From c88bad2d34445fe0a37b06f3f1efe6f1439fc7ca Mon Sep 17 00:00:00 2001 From: Mike Girouard Date: Thu, 5 Nov 2026 13:26:37 -0500 Subject: [PATCH] release: v5.10.0 --- .gitlab-ci.yml | 7 + .release-please-manifest.json | 2 +- .stats.yml | 2 +- CHANGELOG.md | 108 + api.md | 5 +- .../v5.10.0-migration-guide.md | 187 + pyproject.toml | 4 +- requirements-dev.lock | 2 + scripts/mock | 2 +- src/cloudflare/_client.py | 158 +- src/cloudflare/_version.py | 2 +- .../resources/abuse_reports/abuse_reports.py | 384 +- .../resources/abuse_reports/mitigations.py | 10 + src/cloudflare/resources/accounts/__init__.py | 14 - src/cloudflare/resources/accounts/accounts.py | 62 +- src/cloudflare/resources/accounts/api.md | 14 +- .../resources/accounts/pay_bad_debt.py | 196 - .../resources/accounts/subscriptions/bulk.py | 14 +- .../resources/ai_gateway/ai_gateway.py | 24 + .../resources/ai_gateway/billing/billing.py | 6 +- .../ai_gateway/billing/topup/config.py | 245 +- .../ai_gateway/billing/topup/topup.py | 18 +- .../resources/ai_security/custom_topics.py | 8 +- src/cloudflare/resources/aisearch/api.md | 45 +- .../resources/aisearch/instances/instances.py | 154 +- .../resources/aisearch/instances/jobs.py | 40 +- .../namespaces/instances/instances.py | 371 +- .../aisearch/namespaces/instances/items.py | 272 +- .../aisearch/namespaces/instances/jobs.py | 104 +- .../aisearch/namespaces/namespaces.py | 24 +- src/cloudflare/resources/aisearch/tokens.py | 10 +- src/cloudflare/resources/api_gateway/api.md | 3 +- .../api_gateway/discovery/operations.py | 125 +- .../resources/argo/tiered_caching.py | 72 +- src/cloudflare/resources/basin_catalog/api.md | 2 +- .../resources/basin_catalog/basin_catalog.py | 12 +- src/cloudflare/resources/billing/__init__.py | 14 + src/cloudflare/resources/billing/api.md | 46 + src/cloudflare/resources/billing/billing.py | 32 + .../billing/spend_policies/__init__.py | 47 + .../billing/spend_policies/activity.py | 242 + .../resources/billing/spend_policies/audit.py | 248 + .../billing/spend_policies/spend_policies.py | 832 +++ src/cloudflare/resources/billing/usage.py | 20 +- .../bot_management/bot_management.py | 36 + .../resources/brand_protection/api.md | 2 - .../brand_protection/brand_protection.py | 8 +- .../brand_protection/logo_matches.py | 8 +- .../resources/brand_protection/logos.py | 8 +- .../resources/brand_protection/matches.py | 8 +- .../resources/brand_protection/queries.py | 16 +- .../browser_rendering/accessibility_tree.py | 26 +- .../resources/browser_rendering/api.md | 8 - .../resources/browser_rendering/content.py | 30 +- .../devtools/browser/__init__.py | 14 - .../devtools/browser/browser.py | 322 +- .../devtools/browser/page.py | 207 - .../resources/browser_rendering/json.py | 30 +- .../resources/browser_rendering/links.py | 30 +- .../resources/browser_rendering/markdown.py | 28 +- .../resources/browser_rendering/pdf.py | 30 +- .../resources/browser_rendering/scrape.py | 30 +- .../resources/browser_rendering/screenshot.py | 28 +- .../resources/browser_rendering/snapshot.py | 28 +- .../cloudforce_one/threat_events/aggregate.py | 38 +- .../cloudforce_one/threat_events/attackers.py | 6 +- .../threat_events/categories/catalog.py | 14 +- .../threat_events/categories/categories.py | 60 +- .../cloudforce_one/threat_events/countries.py | 6 +- .../threat_events/datasets/datasets.py | 68 +- .../threat_events/datasets/events.py | 4 +- .../threat_events/event_tags.py | 24 +- .../cloudforce_one/threat_events/graph.py | 14 +- .../cloudforce_one/threat_events/graphql.py | 12 +- .../threat_events/indicators/aggregate.py | 18 +- .../indicators/by_dataset/by_dataset.py | 16 +- .../indicators/by_dataset/tags.py | 10 +- .../threat_events/indicators/indicators.py | 40 +- .../threat_events/indicators/types.py | 24 +- .../cloudforce_one/threat_events/queries.py | 88 +- .../cloudforce_one/threat_events/raw.py | 28 +- .../cloudforce_one/threat_events/relate.py | 14 +- .../threat_events/relationships.py | 10 +- .../threat_events/tags/categories.py | 42 +- .../tags/indicators/indicators.py | 38 +- .../cloudforce_one/threat_events/tags/tags.py | 44 +- .../target_industries/by_dataset.py | 12 +- .../target_industries/catalog.py | 14 +- .../target_industries/target_industries.py | 10 +- .../threat_events/threat_events.py | 138 +- .../threat_signals/articles/articles.py | 134 +- .../threat_signals/articles/content.py | 26 +- .../threat_signals/articles/skill_outputs.py | 26 +- .../threat_signals/articles/tags.py | 20 + .../threat_signals/feeds/feeds.py | 126 +- .../threat_signals/feeds/raw.py | 16 +- .../threat_signals/feeds/skills.py | 36 +- .../threat_signals/indicators.py | 32 + .../cloudforce_one/threat_signals/search.py | 16 + .../threat_signals/skills/skills.py | 118 +- .../threat_signals/skills/tag_categories.py | 26 +- .../connectivity/directory/services.py | 16 - .../containers/applications/applications.py | 20 +- .../resources/csam_scanner/csam_scanner.py | 8 + src/cloudflare/resources/d1/api.md | 1 + .../resources/d1/database/database.py | 143 + src/cloudflare/resources/diagnostics/api.md | 2 +- .../diagnostics/endpoint_healthchecks.py | 39 +- .../dls/regional_services/prefix_bindings.py | 38 +- src/cloudflare/resources/dls/regions.py | 8 +- src/cloudflare/resources/dns/api.md | 20 + src/cloudflare/resources/dns/records.py | 18 +- .../dns/settings/account/__init__.py | 14 + .../resources/dns/settings/account/account.py | 32 + .../dns/settings/account/nameserver_sets.py | 616 ++ .../email_security/settings/allow_policies.py | 49 +- .../email_security/settings/block_senders.py | 37 +- .../settings/content_policies.py | 37 +- .../email_sending/subdomains/subdomains.py | 8 +- .../resources/flagship/apps/flags/flags.py | 46 +- .../resources/hyperdrive/configs.py | 30 +- .../resources/iam/resource_groups.py | 8 +- src/cloudflare/resources/intel/api.md | 2 +- src/cloudflare/resources/k2/__init__.py | 33 + src/cloudflare/resources/k2/api.md | 34 + src/cloudflare/resources/k2/k2.py | 102 + .../resources/k2/streams/__init__.py | 33 + .../resources/k2/streams/streams.py | 724 ++ .../streams/subscriptions.py} | 133 +- .../resources/kv/namespaces/namespaces.py | 14 + .../load_balancers/load_balancers.py | 54 + .../load_balancers/monitors/monitors.py | 4 +- .../resources/load_balancers/pools/pools.py | 58 +- .../resources/logpush/datasets/fields.py | 2 + .../resources/logpush/datasets/jobs.py | 2 + src/cloudflare/resources/logpush/jobs.py | 2 + .../magic_cloud_networking/__init__.py | 75 - .../resources/magic_cloud_networking/api.md | 135 - .../catalog_syncs/__init__.py | 33 - .../catalog_syncs/catalog_syncs.py | 881 --- .../cloud_integrations.py | 1111 ---- .../magic_cloud_networking.py | 198 - .../on_ramps/__init__.py | 33 - .../on_ramps/address_spaces.py | 360 - .../on_ramps/on_ramps.py | 1238 ---- .../magic_cloud_networking/resources.py | 839 --- .../resources/magic_network_monitoring/api.md | 2 +- .../rules/advertisements.py | 7 +- .../resources/magic_transit/sites/lans.py | 12 + .../resources/magic_transit/sites/wans.py | 93 +- .../vulnerability_discovery/repositories.py | 6 +- .../vulnerability_discovery/scans.py | 26 +- .../managed_transforms/managed_transforms.py | 122 +- .../resources/monetization/__init__.py | 33 + src/cloudflare/resources/monetization/api.md | 38 + .../resources/monetization/monetization.py | 102 + .../resources/monetization/rules.py | 779 +++ src/cloudflare/resources/moq/relays/relays.py | 6 + .../resources/network_interconnects/cnis.py | 22 +- .../resources/organizations/billing/usage.py | 10 +- .../organizations/organization_profile.py | 64 +- .../resources/organizations/organizations.py | 154 +- src/cloudflare/resources/pipelines/sinks.py | 16 + src/cloudflare/resources/pipelines/streams.py | 17 + src/cloudflare/resources/precursor/api.md | 2 +- .../resources/precursor/precursor.py | 85 +- src/cloudflare/resources/r2/api.md | 14 + .../resources/r2/buckets/__init__.py | 14 + .../resources/r2/buckets/buckets.py | 32 + src/cloudflare/resources/r2/buckets/jobs.py | 797 +++ .../resources/r2_data_catalog/api.md | 2 +- .../r2_data_catalog/r2_data_catalog.py | 12 +- src/cloudflare/resources/realtime_kit/api.md | 2 +- .../resources/realtime_kit/meetings.py | 43 + .../resources/registrar/__init__.py | 14 - src/cloudflare/resources/registrar/api.md | 14 - src/cloudflare/resources/registrar/domains.py | 474 -- .../resources/registrar/registrar.py | 32 - .../resources/resource_sharing/recipients.py | 22 +- .../resource_sharing/resource_sharing.py | 128 +- .../resources/resource_sharing/resources.py | 36 +- .../resource_tagging/account_tags.py | 30 + .../resource_tagging/resource_tagging.py | 26 + .../resources/resource_tagging/values.py | 10 + src/cloudflare/resources/rulesets/api.md | 6 +- .../resources/rulesets/phases/phases.py | 68 +- .../resources/rulesets/phases/versions.py | 141 +- src/cloudflare/resources/rulesets/rulesets.py | 163 +- src/cloudflare/resources/rulesets/versions.py | 141 +- .../resources/secrets_store/stores/secrets.py | 32 +- .../tenant_custom_nameservers/__init__.py | 18 - .../tenant_custom_nameservers/api.md | 17 - .../tenant_custom_nameservers.py | 403 -- src/cloudflare/resources/tenants/__init__.py | 42 - src/cloudflare/resources/tenants/accounts.py | 151 +- src/cloudflare/resources/tenants/api.md | 50 +- .../resources/tenants/entitlements.py | 177 - src/cloudflare/resources/tenants/tenants.py | 203 - .../url_normalization/url_normalization.py | 122 +- src/cloudflare/resources/url_scanner/scans.py | 386 +- src/cloudflare/resources/user/api.md | 8 +- src/cloudflare/resources/user/tenants.py | 28 +- src/cloudflare/resources/vectorize/api.md | 3 +- .../resources/vectorize/indexes/indexes.py | 33 +- src/cloudflare/resources/workers/api.md | 1 + .../workers/beta/workers/versions.py | 189 +- src/cloudflare/resources/workers/domains.py | 48 + .../workers/observability/destinations.py | 8 +- .../resources/workers/scripts/deployments.py | 20 + .../resources/workers/scripts/scripts.py | 50 +- .../resources/workers/scripts/versions.py | 14 +- .../resources/workers_for_platforms/api.md | 3 +- .../dispatch/namespaces/scripts/scripts.py | 48 +- .../dispatch/namespaces/scripts/tags.py | 92 +- .../resources/workflows/workflows.py | 13 + .../resources/zero_trust/__init__.py | 14 + .../resources/zero_trust/access/__init__.py | 28 + .../resources/zero_trust/access/access.py | 64 + .../access/ai_controls/mcp/servers.py | 128 +- .../access/applications/applications.py | 662 +- .../access/applications/policies.py | 28 + .../zero_trust/access/custom_pages.py | 134 +- .../zero_trust/access/logs/__init__.py | 14 + .../zero_trust/access/logs/jit_requests.py | 354 + .../resources/zero_trust/access/logs/logs.py | 32 + .../zero_trust/access/mfa/__init__.py | 33 + .../access/mfa/authenticator_catalog.py} | 106 +- .../resources/zero_trust/access/mfa/mfa.py | 102 + .../resources/zero_trust/access/policies.py | 24 + .../zero_trust/access/service_tokens.py | 78 +- .../access/user_populations/__init__.py | 33 + .../user_populations/user_populations.py | 685 ++ .../access/user_populations/users.py | 976 +++ .../zero_trust/access/users/__init__.py | 28 + .../access/users/last_seen_identity.py | 14 +- .../access/users/mfa_authenticators.py | 212 + .../zero_trust/access/users/passkeys.py | 214 + .../zero_trust/access/users/users.py | 64 + src/cloudflare/resources/zero_trust/api.md | 360 +- .../casb/applications/applications.py | 2 + .../casb/applications/auth_methods.py | 2 + .../resources/zero_trust/casb/integrations.py | 26 +- .../zero_trust/casb/posture/__init__.py | 14 + .../zero_trust/casb/posture/asset_schemas.py | 333 + .../posture/finding_types/finding_types.py | 809 ++- .../casb/posture/findings/findings.py | 4 +- .../zero_trust/casb/posture/posture.py | 32 + .../resources/zero_trust/cws/__init__.py | 145 + .../cws/basic_auth_credentials/__init__.py | 33 + .../basic_auth_credentials.py | 591 ++ .../cws/basic_auth_credentials/secrets.py | 620 ++ .../resources/zero_trust/cws/cws.py | 358 + .../resources/zero_trust/cws/deployments.py | 825 +++ .../resources/zero_trust/cws/domain_acls.py | 723 ++ .../resources/zero_trust/cws/policies.py | 791 +++ .../resources/zero_trust/cws/policy_sets.py | 785 +++ .../resources/zero_trust/cws/rego_metadata.py | 719 ++ .../resources/zero_trust/cws/rego_modules.py | 711 ++ .../cws/tenant_structures/__init__.py | 33 + .../zero_trust/cws/tenant_structures/nodes.py | 1013 +++ .../tenant_structures/tenant_structures.py | 765 +++ .../resources/zero_trust/cws/workloads.py | 737 +++ .../devices/policies/custom/custom.py | 32 +- .../devices/policies/default/default.py | 12 + .../resources/zero_trust/dlp/__init__.py | 14 + .../resources/zero_trust/dlp/dlp.py | 32 + .../zero_trust/dlp/entries/custom.py | 28 +- .../zero_trust/dlp/entries/entries.py | 30 +- .../zero_trust/dlp/validators/__init__.py | 33 + .../dlp/validators/proximity_words.py | 642 ++ .../zero_trust/dlp/validators/validators.py | 328 + .../resources/zero_trust/gateway/__init__.py | 14 + .../zero_trust/gateway/audit_ssh_settings.py | 12 +- .../gateway/dns_destination_ips.py} | 106 +- .../resources/zero_trust/gateway/gateway.py | 32 + .../resources/zero_trust/gateway/locations.py | 20 + .../resources/zero_trust/gateway/rules.py | 4 + .../identity_providers/identity_providers.py | 460 +- .../identity_providers/scim/groups.py | 250 +- .../identity_providers/scim/users.py | 249 +- .../zero_trust/organizations/organizations.py | 72 +- .../resource_library/applications.py | 258 +- .../zero_trust/resource_library/categories.py | 48 +- .../tunnels/warp_connector/configurations.py | 24 +- .../tunnels/warp_connector/connections.py | 4 +- .../tunnels/warp_connector/connectors.py | 4 +- .../tunnels/warp_connector/failover.py | 8 +- .../tunnels/warp_connector/token.py | 6 +- .../tunnels/warp_connector/warp_connector.py | 20 +- .../resources/zero_trust/zero_trust.py | 32 + src/cloudflare/types/__init__.py | 1 - .../abuse_report_create_params.py | 86 +- .../abuse_report_get_response.py | 6 + .../abuse_reports/abuse_report_list_params.py | 15 + .../abuse_report_list_response.py | 6 + .../abuse_reports/mitigation_review_params.py | 6 + src/cloudflare/types/accounts/__init__.py | 2 - src/cloudflare/types/accounts/account.py | 40 +- .../types/accounts/account_create_params.py | 7 +- .../types/accounts/account_update_params.py | 2 +- .../accounts/pay_bad_debt_create_params.py | 15 - .../accounts/pay_bad_debt_create_response.py | 12 - .../subscriptions/bulk_create_response.py | 12 +- .../types/accounts/token_create_response.py | 14 + .../ai_gateway/ai_gateway_create_params.py | 14 + .../ai_gateway/ai_gateway_create_response.py | 24 + .../ai_gateway/ai_gateway_delete_response.py | 24 + .../ai_gateway/ai_gateway_get_response.py | 24 + .../ai_gateway/ai_gateway_list_response.py | 24 + .../ai_gateway/ai_gateway_update_params.py | 14 + .../ai_gateway/ai_gateway_update_response.py | 24 + .../billing/topup/config_create_params.py | 32 +- .../billing/topup/config_create_response.py | 30 +- .../ai_gateway/billing/topup_create_params.py | 4 +- .../billing/topup_create_response.py | 4 +- .../ai_gateway/billing/topup_status_params.py | 2 +- .../billing_usage_history_response.py | 1 + .../provider_config_create_response.py | 10 +- .../provider_config_list_response.py | 10 +- .../ai_security/custom_topic_get_response.py | 4 +- .../ai_security/custom_topic_update_params.py | 4 +- .../custom_topic_update_response.py | 4 +- .../instance_chat_completions_params.py | 20 +- .../instance_chat_completions_response.py | 22 + .../types/aisearch/instance_create_params.py | 68 +- .../aisearch/instance_create_response.py | 78 +- .../aisearch/instance_delete_response.py | 78 +- .../types/aisearch/instance_list_params.py | 7 +- .../types/aisearch/instance_list_response.py | 25 +- .../types/aisearch/instance_read_response.py | 78 +- .../types/aisearch/instance_search_params.py | 20 +- .../aisearch/instance_search_response.py | 22 + .../types/aisearch/instance_stats_response.py | 6 +- .../types/aisearch/instance_update_params.py | 68 +- .../aisearch/instance_update_response.py | 78 +- .../namespace_chat_completions_params.py | 22 +- .../namespace_chat_completions_response.py | 22 + .../types/aisearch/namespace_create_params.py | 11 +- .../aisearch/namespace_create_response.py | 11 +- .../types/aisearch/namespace_list_response.py | 11 +- .../types/aisearch/namespace_read_response.py | 11 +- .../types/aisearch/namespace_search_params.py | 22 +- .../aisearch/namespace_search_response.py | 22 + .../types/aisearch/namespace_update_params.py | 11 +- .../aisearch/namespace_update_response.py | 11 +- .../types/aisearch/namespaces/__init__.py | 1 + .../instance_chat_completions_params.py | 22 +- .../instance_chat_completions_response.py | 22 + .../namespaces/instance_create_params.py | 68 +- .../namespaces/instance_create_response.py | 78 +- .../namespaces/instance_delete_response.py | 78 +- .../namespaces/instance_list_params.py | 8 +- .../namespaces/instance_list_response.py | 25 +- .../namespaces/instance_move_params.py | 17 + .../namespaces/instance_read_response.py | 78 +- .../namespaces/instance_search_params.py | 22 +- .../namespaces/instance_search_response.py | 22 + .../namespaces/instance_stats_response.py | 6 +- .../namespaces/instance_update_params.py | 70 +- .../namespaces/instance_update_response.py | 78 +- .../instances/item_chunks_params.py | 2 +- .../instances/item_chunks_response.py | 20 +- .../instances/item_create_or_update_params.py | 12 +- .../namespaces/instances/item_list_params.py | 19 +- .../namespaces/instances/item_logs_params.py | 2 +- .../namespaces/instances/item_sync_params.py | 12 +- .../instances/item_upload_params.py | 12 +- .../namespaces/instances/job_create_params.py | 2 +- .../namespaces/instances/job_list_params.py | 2 +- .../namespaces/instances/job_logs_params.py | 2 +- .../namespaces/instances/job_update_params.py | 2 +- .../types/api_gateway/discovery/__init__.py | 2 + .../discovery/operation_edit_params.py | 19 + .../discovery/operation_edit_response.py | 18 + .../types/argo/tiered_caching_edit_params.py | 2 +- .../types/basin_catalog/__init__.py | 1 + .../basin_catalog_enable_params.py | 22 + .../basin_catalog_get_response.py | 8 +- .../basin_catalog_list_response.py | 8 +- src/cloudflare/types/billing/__init__.py | 7 + .../types/billing/spend_policies/__init__.py | 8 + .../spend_policies/activity_list_params.py | 27 + .../spend_policies/activity_list_response.py | 260 + .../spend_policies/audit_list_params.py | 21 + .../spend_policies/audit_list_response.py | 57 + .../billing/spend_policy_create_params.py | 52 + .../billing/spend_policy_create_response.py | 116 + .../billing/spend_policy_delete_response.py | 10 + .../billing/spend_policy_get_response.py | 116 + .../billing/spend_policy_list_response.py | 116 + .../billing/spend_policy_update_params.py | 56 + .../billing/spend_policy_update_response.py | 116 + .../usage_get_account_usage_v2_response.py | 12 +- .../types/billing/usage_get_response.py | 12 +- .../bot_fight_mode_configuration.py | 24 +- .../bot_fight_mode_configuration_param.py | 24 +- .../bot_management_update_params.py | 92 + .../subscription_configuration.py | 24 +- .../subscription_configuration_param.py | 24 +- ...bot_fight_mode_definitely_configuration.py | 24 +- ...ght_mode_definitely_configuration_param.py | 24 +- ...per_bot_fight_mode_likely_configuration.py | 24 +- ...t_fight_mode_likely_configuration_param.py | 24 +- .../brand_protection/query_create_params.py | 12 +- .../accessibility_tree_create_params.py | 6 + .../content_create_params.py | 6 + .../browser_rendering/crawl_get_response.py | 55 +- .../browser_rendering/devtools/__init__.py | 2 - .../devtools/browser_connect_params.py | 25 - .../devtools/browser_launch_params.py | 28 - .../browser_rendering/json_create_params.py | 6 + .../browser_rendering/link_create_params.py | 6 + .../markdown_create_params.py | 6 + .../browser_rendering/pdf_create_params.py | 6 + .../browser_rendering/scrape_create_params.py | 6 + .../screenshot_create_params.py | 6 + .../snapshot_create_params.py | 6 + .../threat_event_list_params.py | 122 +- .../threat_events/aggregate_list_params.py | 13 +- .../threat_events/graph_list_params.py | 7 +- .../threat_events/indicator_list_params.py | 8 +- .../indicators/aggregate_list_params.py | 9 +- .../indicators/type_list_params.py | 8 +- .../threat_events/query_create_params.py | 18 +- .../threat_events/query_create_response.py | 12 +- .../threat_events/query_edit_params.py | 8 +- .../threat_events/query_edit_response.py | 12 +- .../threat_events/query_get_response.py | 12 +- .../threat_events/query_list_response.py | 12 +- .../tags/indicator_list_params.py | 8 +- .../article_bulk_edit_params.py | 2 + .../threat_signals/article_edit_params.py | 1 + .../threat_signals/article_edit_response.py | 9 + .../threat_signals/article_get_response.py | 61 +- .../threat_signals/article_list_params.py | 64 +- .../threat_signals/article_list_response.py | 61 +- .../articles/content_get_params.py | 4 + .../articles/skill_output_get_response.py | 32 +- .../articles/tag_create_params.py | 1 + .../threat_signals/feed_create_params.py | 20 + .../threat_signals/feed_edit_params.py | 10 + .../threat_signals/feed_list_params.py | 20 + .../threat_signals/feed_list_response.py | 6 + .../threat_signals/feed_poll_params.py | 4 + .../threat_signals/feeds/raw_get_params.py | 4 + .../feeds/skill_update_params.py | 5 + .../threat_signals/indicator_list_params.py | 15 + .../threat_signals/search_search_params.py | 7 + .../threat_signals/skill_create_params.py | 6 +- .../threat_signals/skill_edit_params.py | 5 + .../threat_signals/skill_list_params.py | 2 + .../threat_signals/skill_list_response.py | 9 +- .../skills/tag_category_update_params.py | 4 + .../directory/service_create_params.py | 38 +- .../directory/service_create_response.py | 38 +- .../directory/service_get_response.py | 38 +- .../directory/service_list_response.py | 38 +- .../directory/service_update_params.py | 38 +- .../directory/service_update_response.py | 38 +- .../containers/application_create_params.py | 18 + .../containers/application_create_response.py | 18 + .../containers/application_edit_response.py | 18 + .../containers/application_get_response.py | 18 + .../containers/application_list_response.py | 18 + src/cloudflare/types/d1/__init__.py | 1 + .../types/d1/database_export_params.py | 8 + .../types/d1/database_undelete_params.py | 18 + .../prefix_binding_delete_response.py | 31 +- .../types/dns/record_list_params.py | 11 +- .../types/dns/settings/account/__init__.py | 6 + .../account/nameserver_set_create_params.py | 50 + .../account/nameserver_set_create_response.py | 112 + .../account/nameserver_set_delete_response.py | 10 + .../account/nameserver_set_get_response.py | 112 + .../account/nameserver_set_list_params.py | 18 + .../account/nameserver_set_list_response.py | 112 + .../investigate/bulk/message_list_response.py | 6 +- .../investigate_get_response.py | 19 +- .../investigate_list_response.py | 19 +- .../settings/allow_policy_batch_params.py | 37 +- .../settings/allow_policy_batch_response.py | 30 +- .../settings/allow_policy_create_params.py | 17 +- .../settings/allow_policy_create_response.py | 10 +- .../settings/allow_policy_edit_params.py | 17 +- .../settings/allow_policy_edit_response.py | 10 +- .../settings/allow_policy_get_response.py | 10 +- .../settings/allow_policy_list_params.py | 6 + .../settings/allow_policy_list_response.py | 10 +- .../settings/block_sender_batch_params.py | 28 +- .../settings/block_sender_batch_response.py | 21 + .../settings/block_sender_create_params.py | 14 +- .../settings/block_sender_create_response.py | 7 + .../settings/block_sender_edit_params.py | 14 +- .../settings/block_sender_edit_response.py | 7 + .../settings/block_sender_get_response.py | 7 + .../settings/block_sender_list_params.py | 6 + .../settings/block_sender_list_response.py | 7 + .../settings/content_policy_batch_params.py | 28 +- .../settings/content_policy_batch_response.py | 21 + .../settings/content_policy_create_params.py | 14 +- .../content_policy_create_response.py | 7 + .../settings/content_policy_edit_params.py | 14 +- .../settings/content_policy_edit_response.py | 7 + .../settings/content_policy_get_response.py | 7 + .../settings/content_policy_list_params.py | 6 + .../settings/content_policy_list_response.py | 7 + .../email_sending/subdomain_create_params.py | 4 +- .../flagship/apps/evaluate_get_response.py | 6 + .../types/flagship/apps/flag_create_params.py | 124 +- .../flagship/apps/flag_create_response.py | 117 +- .../types/flagship/apps/flag_get_response.py | 117 +- .../types/flagship/apps/flag_list_response.py | 117 +- .../types/flagship/apps/flag_update_params.py | 124 +- .../flagship/apps/flag_update_response.py | 117 +- .../apps/flags/changelog_list_response.py | 348 +- .../types/hyperdrive/config_create_params.py | 14 +- .../hyperdrive/config_create_response.py | 14 +- .../types/hyperdrive/config_edit_response.py | 14 +- .../types/hyperdrive/config_get_response.py | 14 +- .../types/hyperdrive/config_list_response.py | 14 +- .../hyperdrive/config_restart_response.py | 14 +- .../hyperdrive/config_update_response.py | 14 +- .../types/iam/resource_group_create_params.py | 4 +- .../iam/resource_group_create_response.py | 4 +- .../types/iam/resource_group_get_response.py | 4 +- .../types/iam/resource_group_list_response.py | 4 +- .../types/iam/resource_group_update_params.py | 4 +- .../iam/resource_group_update_response.py | 4 +- .../types/iam/user_group_create_response.py | 6 +- .../types/iam/user_group_get_response.py | 6 +- .../types/iam/user_group_list_response.py | 6 +- .../types/iam/user_group_update_response.py | 6 +- .../issue_list_response.py | 6 + src/cloudflare/types/intel/whois.py | 28 - src/cloudflare/types/k2/__init__.py | 11 + .../types/k2/stream_create_params.py | 66 + .../types/k2/stream_create_response.py | 72 + .../types/k2/stream_get_response.py | 72 + src/cloudflare/types/k2/stream_list_params.py | 19 + .../types/k2/stream_list_response.py | 72 + .../types/k2/stream_update_params.py | 63 + .../types/k2/stream_update_response.py | 72 + src/cloudflare/types/k2/streams/__init__.py | 5 + .../k2/streams/subscription_list_response.py | 43 + src/cloudflare/types/kv/namespace.py | 8 + .../types/kv/namespace_create_params.py | 8 + .../load_balancer_create_params.py | 169 +- .../load_balancer_edit_params.py | 169 +- .../load_balancer_update_params.py | 169 +- .../load_balancers/pool_create_params.py | 27 +- .../types/load_balancers/pool_edit_params.py | 4 + .../load_balancers/pool_update_params.py | 4 + src/cloudflare/types/load_balancers/rules.py | 37 +- .../types/load_balancers/rules_param.py | 37 +- .../types/logpush/job_create_params.py | 1 + src/cloudflare/types/logpush/logpush_job.py | 1 + .../types/logpush/output_options.py | 3 +- .../types/logpush/output_options_param.py | 3 +- .../types/magic_cloud_networking/__init__.py | 55 - .../catalog_sync_create_params.py | 23 - .../catalog_sync_create_response.py | 220 - .../catalog_sync_delete_params.py | 13 - .../catalog_sync_delete_response.py | 9 - .../catalog_sync_edit_params.py | 19 - .../catalog_sync_edit_response.py | 220 - .../catalog_sync_get_response.py | 220 - .../catalog_sync_list_response.py | 220 - .../catalog_sync_refresh_response.py | 7 - .../catalog_sync_update_params.py | 19 - .../catalog_sync_update_response.py | 220 - .../catalog_syncs/__init__.py | 6 - .../prebuilt_policy_list_params.py | 14 - .../prebuilt_policy_list_response.py | 18 - .../cloud_integration_create_params.py | 19 - .../cloud_integration_create_response.py | 102 - .../cloud_integration_delete_response.py | 9 - ...cloud_integration_discover_all_response.py | 396 -- .../cloud_integration_discover_params.py | 13 - .../cloud_integration_discover_response.py | 396 -- .../cloud_integration_edit_params.py | 25 - .../cloud_integration_edit_response.py | 102 - .../cloud_integration_get_params.py | 13 - .../cloud_integration_get_response.py | 102 - ...loud_integration_initial_setup_response.py | 38 - .../cloud_integration_list_params.py | 20 - .../cloud_integration_list_response.py | 102 - .../cloud_integration_update_params.py | 25 - .../cloud_integration_update_response.py | 102 - .../on_ramp_apply_response.py | 388 -- .../on_ramp_create_params.py | 56 - .../on_ramp_create_response.py | 1675 ----- .../on_ramp_delete_params.py | 15 - .../on_ramp_delete_response.py | 9 - .../on_ramp_edit_params.py | 31 - .../on_ramp_edit_response.py | 1675 ----- .../on_ramp_get_params.py | 19 - .../on_ramp_get_response.py | 1675 ----- .../on_ramp_list_params.py | 20 - .../on_ramp_list_response.py | 1675 ----- .../on_ramp_plan_response.py | 388 -- .../on_ramp_update_params.py | 31 - .../on_ramp_update_response.py | 1675 ----- .../on_ramps/__init__.py | 9 - .../on_ramps/address_space_edit_params.py | 15 - .../on_ramps/address_space_edit_response.py | 11 - .../on_ramps/address_space_list_response.py | 11 - .../on_ramps/address_space_update_params.py | 15 - .../on_ramps/address_space_update_response.py | 11 - .../resource_export_params.py | 93 - .../resource_get_params.py | 13 - .../resource_get_response.py | 632 -- .../resource_list_params.py | 101 - .../resource_list_response.py | 632 -- .../resource_policy_preview_params.py | 13 - .../resource_policy_preview_response.py | 7 - .../rules/__init__.py | 1 - .../rules/advertisement_edit_params.py | 13 - .../cf_interconnect_bulk_update_response.py | 6 +- .../cf_interconnect_get_response.py | 6 +- .../cf_interconnect_list_response.py | 6 +- .../cf_interconnect_update_params.py | 6 +- .../cf_interconnect_update_response.py | 6 +- .../gre_tunnel_bulk_update_response.py | 5 +- .../magic_transit/gre_tunnel_create_params.py | 5 +- .../gre_tunnel_create_response.py | 5 +- .../gre_tunnel_delete_response.py | 5 +- .../magic_transit/gre_tunnel_get_response.py | 5 +- .../magic_transit/gre_tunnel_list_response.py | 5 +- .../gre_tunnel_update_response.py | 5 +- .../ipsec_tunnel_bulk_update_response.py | 5 +- .../ipsec_tunnel_create_params.py | 5 +- .../ipsec_tunnel_create_response.py | 5 +- .../ipsec_tunnel_delete_response.py | 5 +- .../ipsec_tunnel_get_response.py | 5 +- .../ipsec_tunnel_list_response.py | 5 +- .../ipsec_tunnel_update_params.py | 5 +- .../ipsec_tunnel_update_response.py | 5 +- .../types/magic_transit/sites/__init__.py | 1 - .../types/magic_transit/sites/lan.py | 16 +- .../magic_transit/sites/lan_create_params.py | 16 +- .../magic_transit/sites/lan_edit_params.py | 16 +- .../magic_transit/sites/lan_update_params.py | 16 +- .../types/magic_transit/sites/wan.py | 6 + .../magic_transit/sites/wan_create_params.py | 36 +- .../magic_transit/sites/wan_edit_params.py | 44 +- .../sites/wan_static_addressing.py | 3 + .../sites/wan_static_addressing_param.py | 23 - .../magic_transit/sites/wan_update_params.py | 44 +- .../report_get_response.py | 19 + .../repository_create_response.py | 12 + .../repository_get_response.py | 6 + .../repository_list_response.py | 6 + .../scan_create_params.py | 28 +- .../scan_get_report_response.py | 19 + .../managed_transform_edit_response.py | 221 +- .../managed_transform_list_response.py | 221 +- .../memberships/membership_get_response.py | 4 +- .../memberships/membership_update_response.py | 4 +- src/cloudflare/types/monetization/__init__.py | 19 + .../types/monetization/monetization_rule.py | 41 + .../monetization_rule_collection.py | 21 + .../monetization_rule_input_fixed_price.py | 61 + ...netization_rule_input_fixed_price_param.py | 60 + ...netization_rule_input_origin_controlled.py | 49 + ...tion_rule_input_origin_controlled_param.py | 48 + .../monetization_rule_input_param.py | 15 + .../monetization/rule_edit_rule_params.py | 54 + .../types/monetization/rule_update_params.py | 23 + .../types/moq/relay_create_response.py | 11 + .../types/moq/relay_get_response.py | 11 + .../types/moq/relay_update_params.py | 11 + .../types/moq/relay_update_response.py | 11 + .../cni_create_params.py | 6 +- .../cni_create_response.py | 16 +- .../network_interconnects/cni_get_response.py | 16 +- .../cni_list_response.py | 16 +- .../cni_update_params.py | 16 +- .../cni_update_response.py | 16 +- .../types/organizations/__init__.py | 1 - .../billing/usage_get_response.py | 12 +- .../types/organizations/organization.py | 4 + .../organization_create_params.py | 28 +- .../organizations/organization_list_params.py | 26 +- .../organization_profile_param.py | 19 - .../organization_profile_update_params.py | 13 +- .../organization_update_params.py | 20 +- src/cloudflare/types/pages/project.py | 34 +- .../types/pages/project_create_params.py | 12 +- .../types/pages/project_edit_params.py | 12 +- .../types/pipelines/sink_list_params.py | 8 +- .../types/pipelines/stream_list_params.py | 8 +- src/cloudflare/types/precursor/__init__.py | 2 - .../types/precursor/enforcement_rule.py | 28 - .../types/precursor/enforcement_rule_param.py | 24 - .../types/precursor/precursor_config.py | 36 +- .../precursor/precursor_update_params.py | 38 +- .../types/r2/bucket_list_response.py | 4 +- src/cloudflare/types/r2/buckets/__init__.py | 5 + .../types/r2/buckets/job_create_params.py | 51 + .../types/r2/buckets/job_create_response.py | 122 + .../types/r2/buckets/job_get_response.py | 122 + .../types/r2/buckets/job_list_params.py | 33 + .../types/r2/buckets/job_list_response.py | 133 + .../types/r2_data_catalog/__init__.py | 1 + .../r2_data_catalog_enable_params.py | 22 + .../r2_data_catalog_get_response.py | 8 +- .../r2_data_catalog_list_response.py | 8 +- .../types/radar/annotation_list_response.py | 6 + .../radar/annotations/outage_get_response.py | 6 + .../radar/traffic_anomaly_get_response.py | 8 + src/cloudflare/types/realtime_kit/__init__.py | 3 + ..._livestreams_for_livestream_id_response.py | 67 +- ...livestream_get_all_livestreams_response.py | 63 +- ..._livestream_analytics_complete_response.py | 4 +- ...t_livestream_analytics_daywise_response.py | 4 +- ...session_details_for_session_id_response.py | 40 +- ...ream_session_for_livestream_id_response.py | 95 +- ...get_meeting_active_livestreams_response.py | 38 +- ..._start_livestreaming_a_meeting_response.py | 25 +- .../meeting_add_participant_params.py | 35 +- .../meeting_add_participant_response.py | 9 + .../realtime_kit/meeting_create_params.py | 6 +- .../realtime_kit/meeting_create_response.py | 6 +- .../meeting_edit_participant_response.py | 9 + .../meeting_get_meeting_by_id_response.py | 6 +- ...eeting_refresh_participant_token_params.py | 33 + ...ting_refresh_participant_token_response.py | 8 + .../meeting_replace_meeting_by_id_params.py | 6 +- .../meeting_replace_meeting_by_id_response.py | 6 +- .../meeting_update_meeting_by_id_params.py | 6 +- .../meeting_update_meeting_by_id_response.py | 6 +- src/cloudflare/types/registrar/__init__.py | 2 - src/cloudflare/types/registrar/domain.py | 121 - .../types/registrar/domain_update_params.py | 24 - .../recipient_create_params.py | 3 - .../recipient_create_response.py | 17 +- .../recipient_delete_response.py | 17 +- .../recipient_get_response.py | 17 +- .../resource_sharing/recipient_list_params.py | 12 +- .../recipient_list_response.py | 17 +- .../resource_create_params.py | 4 +- .../resource_create_response.py | 6 +- .../resource_delete_response.py | 6 +- .../resource_sharing/resource_get_response.py | 6 +- .../resource_sharing/resource_list_params.py | 12 +- .../resource_list_response.py | 6 +- .../resource_sharing_create_params.py | 27 +- .../resource_sharing_create_response.py | 19 +- .../resource_sharing_delete_response.py | 19 +- .../resource_sharing_get_params.py | 9 +- .../resource_sharing_get_response.py | 19 +- .../resource_sharing_list_params.py | 19 +- .../resource_sharing_list_response.py | 19 +- .../resource_sharing_update_params.py | 4 + .../resource_sharing_update_response.py | 19 +- .../resource_update_response.py | 6 +- .../account_tag_get_params.py | 5 + .../account_tag_get_response.py | 253 +- .../account_tag_update_params.py | 5 + .../account_tag_update_response.py | 253 +- .../resource_tagging_list_params.py | 14 + .../resource_tagging_list_response.py | 253 +- .../resource_tagging/value_list_params.py | 5 + .../resource_tagging/zone_tag_get_response.py | 253 +- .../zone_tag_update_response.py | 253 +- src/cloudflare/types/rulesets/phase.py | 1 + .../types/rulesets/phase_get_response.py | 5848 ++++++++++++++++- .../types/rulesets/phase_update_response.py | 2 +- .../rulesets/phases/version_get_response.py | 5848 ++++++++++++++++- .../rulesets/phases/version_list_response.py | 33 +- .../types/rulesets/rule_create_params.py | 3 +- .../types/rulesets/rule_create_response.py | 2 +- .../types/rulesets/rule_delete_response.py | 2 +- .../types/rulesets/rule_edit_params.py | 3 +- .../types/rulesets/rule_edit_response.py | 2 +- .../types/rulesets/ruleset_create_response.py | 2 +- .../types/rulesets/ruleset_get_response.py | 5848 ++++++++++++++++- .../types/rulesets/ruleset_list_response.py | 33 +- .../types/rulesets/ruleset_update_response.py | 2 +- .../types/rulesets/set_config_rule.py | 3 +- .../types/rulesets/set_config_rule_param.py | 3 +- .../types/rulesets/version_get_response.py | 5848 ++++++++++++++++- .../types/rulesets/version_list_response.py | 33 +- .../stores/secret_create_params.py | 10 +- .../stores/secret_create_response.py | 6 +- .../stores/secret_duplicate_params.py | 10 +- .../stores/secret_duplicate_response.py | 6 +- .../stores/secret_edit_params.py | 10 +- .../stores/secret_edit_response.py | 6 +- .../stores/secret_get_response.py | 6 +- .../stores/secret_list_response.py | 6 +- .../security_center/insight_list_response.py | 6 + src/cloudflare/types/shared/__init__.py | 1 - .../types/shared/load_balancer_preview.py | 14 - src/cloudflare/types/shared/member.py | 4 +- src/cloudflare/types/shared/token.py | 14 + .../types/spectrum/app_create_response.py | 13 + .../types/spectrum/app_get_response.py | 13 + .../types/spectrum/app_list_response.py | 13 + .../types/spectrum/app_update_response.py | 13 + .../tenant_custom_nameservers/__init__.py | 13 - .../tenant_custom_nameserver_create_params.py | 15 - ...enant_custom_nameserver_create_response.py | 35 - ...enant_custom_nameserver_delete_response.py | 7 - .../tenant_custom_nameserver_get_response.py | 35 - src/cloudflare/types/tenants/__init__.py | 7 +- .../types/tenants/account_list_params.py | 101 + .../types/tenants/account_list_response.py | 31 + src/cloudflare/types/tenants/tenant.py | 66 - .../types/tenants/tenant_account.py | 48 - .../types/tenants/tenant_entitlements.py | 100 - .../types/tenants/tenant_membership.py | 13 - .../url_normalization_get_response.py | 55 +- .../url_normalization_update_response.py | 55 +- .../types/url_scanner/scan_create_params.py | 193 +- .../types/url_scanner/scan_get_response.py | 337 + src/cloudflare/types/user/__init__.py | 1 + .../types/user/tenant_list_response.py | 156 + .../types/user/token_create_response.py | 14 + src/cloudflare/types/vectorize/__init__.py | 1 + .../vectorize/index_get_by_ids_response.py | 18 + .../types/workers/beta/workers/__init__.py | 1 + .../types/workers/beta/workers/version.py | 19 +- .../beta/workers/version_create_params.py | 19 +- .../beta/workers/version_profile_params.py | 33 + .../types/workers/domain_get_response.py | 18 + .../types/workers/domain_list_params.py | 6 + .../types/workers/domain_list_response.py | 18 + .../types/workers/domain_update_params.py | 18 + .../types/workers/domain_update_response.py | 18 + .../destination_create_response.py | 18 +- .../destination_delete_response.py | 18 +- .../destination_list_response.py | 6 +- .../destination_update_params.py | 14 +- .../destination_update_response.py | 18 +- .../shared_query_get_response.py | 50 + .../observability/telemetry_query_response.py | 50 + .../types/workers/script_update_params.py | 56 +- .../types/workers/scripts/deployment.py | 39 +- .../scripts/deployment_create_params.py | 45 +- .../script_and_version_setting_edit_params.py | 19 +- ...cript_and_version_setting_edit_response.py | 19 +- ...script_and_version_setting_get_response.py | 19 +- .../workers/scripts/version_create_params.py | 26 +- .../namespaces/script_update_params.py | 56 +- .../dispatch/namespaces/scripts/__init__.py | 1 + .../scripts/binding_get_response.py | 19 +- .../namespaces/scripts/setting_edit_params.py | 19 +- .../scripts/setting_edit_response.py | 19 +- .../scripts/setting_get_response.py | 19 +- .../namespaces/scripts/tag_delete_response.py | 106 + .../types/workflows/workflow_get_response.py | 7 + .../types/workflows/workflow_list_response.py | 7 + .../types/workflows/workflow_update_params.py | 9 +- .../workflows/workflow_update_response.py | 7 + .../types/zero_trust/access/__init__.py | 12 + .../ai_controls/mcp/portal_create_response.py | 11 +- .../ai_controls/mcp/portal_list_response.py | 11 +- .../ai_controls/mcp/portal_read_response.py | 11 +- .../ai_controls/mcp/portal_update_response.py | 11 +- .../ai_controls/mcp/server_create_params.py | 31 +- .../ai_controls/mcp/server_create_response.py | 11 +- .../ai_controls/mcp/server_delete_response.py | 11 +- .../ai_controls/mcp/server_list_response.py | 11 +- .../ai_controls/mcp/server_read_response.py | 11 +- .../ai_controls/mcp/server_update_params.py | 31 +- .../ai_controls/mcp/server_update_response.py | 11 +- .../access/application_create_params.py | 723 +- .../access/application_create_response.py | 795 +-- .../access/application_get_response.py | 795 +-- .../access/application_list_response.py | 795 +-- .../zero_trust/access/application_type.py | 1 + .../access/application_update_params.py | 723 +- .../access/application_update_response.py | 795 +-- .../access/applications/access_rule.py | 28 + .../access/applications/access_rule_param.py | 28 + .../applications/policy_create_params.py | 7 + .../applications/policy_create_response.py | 14 + .../applications/policy_get_response.py | 14 + .../applications/policy_list_response.py | 14 + .../applications/policy_test_create_params.py | 7 + .../applications/policy_update_params.py | 7 + .../applications/policy_update_response.py | 14 + .../access/custom_page_validate_params.py | 21 + .../access/custom_page_validate_response.py | 50 + .../zero_trust/access/destination_override.py | 20 + .../access/destination_override_param.py | 20 + .../types/zero_trust/access/logs/__init__.py | 3 + .../access/logs/jit_request_get_response.py | 62 + .../access/logs/jit_request_list_params.py | 40 + .../access/logs/jit_request_list_response.py | 36 + .../types/zero_trust/access/mfa/__init__.py | 5 + .../authenticator_catalog_list_response.py | 18 + .../zero_trust/access/policy_create_params.py | 7 + .../access/policy_create_response.py | 7 + .../zero_trust/access/policy_get_response.py | 7 + .../zero_trust/access/policy_list_response.py | 7 + .../zero_trust/access/policy_update_params.py | 7 + .../access/policy_update_response.py | 7 + .../types/zero_trust/access/service_token.py | 32 +- .../access/service_token_create_params.py | 19 +- .../access/service_token_create_response.py | 12 +- .../access/service_token_rotate_params.py | 3 +- .../access/service_token_rotate_response.py | 12 +- .../access/service_token_update_params.py | 19 +- .../access/user_population_create_params.py | 20 + .../access/user_population_create_response.py | 18 + .../access/user_population_delete_response.py | 12 + .../access/user_population_get_response.py | 18 + .../access/user_population_list_params.py | 18 + .../access/user_population_list_response.py | 18 + .../access/user_population_update_params.py | 20 + .../access/user_population_update_response.py | 18 + .../access/user_populations/__init__.py | 14 + .../user_populations/user_create_params.py | 68 + .../user_populations/user_create_response.py | 79 + .../user_populations/user_get_params.py | 23 + .../user_populations/user_get_response.py | 79 + .../user_populations/user_list_params.py | 29 + .../user_populations/user_list_response.py | 91 + .../user_populations/user_replace_params.py | 71 + .../user_populations/user_replace_response.py | 79 + .../user_populations/user_update_params.py | 31 + .../user_populations/user_update_response.py | 79 + .../types/zero_trust/access/users/__init__.py | 2 +- ....py => last_seen_identity_get_response.py} | 30 +- .../casb/application_get_response.py | 2 + .../casb/application_list_response.py | 2 + .../casb/integration_create_params.py | 15 +- .../casb/integration_list_response.py | 18 +- .../types/zero_trust/casb/posture/__init__.py | 9 + .../casb/posture/asset_schema_get_response.py | 21 + .../casb/posture/asset_schema_list_params.py | 32 + .../posture/asset_schema_list_response.py | 20 + .../casb/posture/finding_export_params.py | 4 +- .../casb/posture/finding_get_response.py | 68 + .../casb/posture/finding_ignore_response.py | 68 + .../casb/posture/finding_list_response.py | 68 + .../finding_reset_severity_response.py | 68 + .../posture/finding_tune_severity_response.py | 68 + .../posture/finding_type_create_params.py | 72 + .../posture/finding_type_create_response.py | 110 + .../casb/posture/finding_type_get_response.py | 71 +- .../casb/posture/finding_type_list_params.py | 59 +- .../posture/finding_type_list_response.py | 71 +- .../posture/finding_type_update_params.py | 44 + .../posture/finding_type_update_response.py | 110 + .../posture/finding_type_validate_params.py | 72 + .../posture/finding_type_validate_response.py | 53 + .../casb/posture/finding_unignore_response.py | 68 + .../casb/posture/policy_create_response.py | 2 +- .../casb/posture/policy_get_response.py | 2 +- .../casb/posture/policy_list_response.py | 2 +- .../casb/posture/policy_update_response.py | 2 +- .../types/zero_trust/cws/__init__.py | 50 + .../zero_trust/cws/basic_auth_credential.py | 23 + .../basic_auth_credential_create_params.py | 15 + .../basic_auth_credential_delete_response.py | 9 + .../cws/basic_auth_credential_list_params.py | 30 + .../cws/basic_auth_credentials/__init__.py | 8 + .../basic_auth_secret.py | 18 + .../secret_create_params.py | 25 + .../secret_delete_response.py | 9 + .../secret_list_params.py | 24 + .../types/zero_trust/cws/deployment.py | 45 + .../cws/deployment_create_params.py | 48 + .../cws/deployment_delete_response.py | 9 + .../zero_trust/cws/deployment_list_params.py | 27 + .../cws/deployment_update_params.py | 49 + .../types/zero_trust/cws/domain_acl.py | 35 + .../cws/domain_acl_create_params.py | 30 + .../cws/domain_acl_delete_response.py | 9 + .../zero_trust/cws/domain_acl_list_params.py | 30 + .../cws/domain_acl_update_params.py | 30 + src/cloudflare/types/zero_trust/cws/policy.py | 50 + .../zero_trust/cws/policy_create_params.py | 43 + .../zero_trust/cws/policy_delete_response.py | 9 + .../zero_trust/cws/policy_list_params.py | 33 + .../types/zero_trust/cws/policy_set.py | 49 + .../cws/policy_set_create_params.py | 50 + .../cws/policy_set_delete_response.py | 9 + .../zero_trust/cws/policy_set_list_params.py | 30 + .../cws/policy_set_update_params.py | 51 + .../zero_trust/cws/policy_update_params.py | 44 + .../types/zero_trust/cws/rego_metadata.py | 27 + .../cws/rego_metadata_create_params.py | 23 + .../cws/rego_metadata_delete_response.py | 9 + .../cws/rego_metadata_list_params.py | 30 + .../cws/rego_metadata_update_params.py | 23 + .../types/zero_trust/cws/rego_module.py | 31 + .../cws/rego_module_create_params.py | 21 + .../cws/rego_module_delete_response.py | 9 + .../zero_trust/cws/rego_module_list_params.py | 30 + .../cws/rego_module_update_params.py | 21 + .../types/zero_trust/cws/tenant_structure.py | 33 + .../cws/tenant_structure_create_params.py | 24 + .../cws/tenant_structure_delete_response.py | 9 + .../cws/tenant_structure_list_params.py | 30 + .../cws/tenant_structure_update_params.py | 24 + .../cws/tenant_structures/__init__.py | 11 + .../tenant_structures/node_batch_params.py | 68 + .../tenant_structures/node_batch_response.py | 20 + .../tenant_structures/node_create_params.py | 37 + .../tenant_structures/node_delete_response.py | 9 + .../cws/tenant_structures/node_list_params.py | 36 + .../tenant_structures/node_update_params.py | 40 + .../tenant_structure_node.py | 42 + .../types/zero_trust/cws/workload.py | 32 + .../zero_trust/cws/workload_create_params.py | 31 + .../cws/workload_delete_response.py | 9 + .../zero_trust/cws/workload_list_params.py | 30 + .../zero_trust/cws/workload_update_params.py | 32 + .../zero_trust/devices/device_get_response.py | 6 + .../devices/device_list_response.py | 6 + .../devices/policies/custom_create_params.py | 15 +- .../devices/policies/custom_edit_params.py | 15 +- .../devices/policies/default_edit_params.py | 13 + .../devices/policies/default_edit_response.py | 13 + .../devices/policies/default_get_response.py | 13 + .../zero_trust/devices/settings_policy.py | 15 +- .../types/zero_trust/dlp/__init__.py | 4 + .../dlp/entries/custom_create_params.py | 4 + .../dlp/entries/custom_create_response.py | 11 +- .../dlp/entries/custom_get_response.py | 11 +- .../dlp/entries/custom_list_response.py | 13 +- .../dlp/entries/custom_update_params.py | 11 + .../dlp/entries/custom_update_response.py | 11 +- .../dlp/entries/integration_get_response.py | 11 +- .../dlp/entries/integration_list_response.py | 13 +- .../dlp/entries/predefined_get_response.py | 11 +- .../dlp/entries/predefined_list_response.py | 13 +- .../zero_trust/dlp/entry_create_params.py | 4 + .../zero_trust/dlp/entry_create_response.py | 11 +- .../zero_trust/dlp/entry_get_response.py | 11 +- .../zero_trust/dlp/entry_list_response.py | 13 +- .../zero_trust/dlp/entry_update_params.py | 11 + .../zero_trust/dlp/entry_update_response.py | 13 +- .../types/zero_trust/dlp/profile.py | 55 +- .../dlp/profiles/predefined_profile.py | 11 +- .../types/zero_trust/dlp/references.py | 38 + .../types/zero_trust/dlp/validator.py | 74 + .../types/zero_trust/dlp/validator_array.py | 10 + .../zero_trust/dlp/validator_list_params.py | 15 + .../zero_trust/dlp/validators/__init__.py | 11 + .../proximity_word_create_params.py | 27 + .../proximity_word_update_params.py | 27 + .../validators/proximity_word_validator.py | 39 + .../proximity_word_validator_array.py | 10 + .../types/zero_trust/dlp/validators/weight.py | 7 + .../types/zero_trust/dlp/validators/word.py | 23 + .../zero_trust/dlp/validators/word_param.py | 26 + .../types/zero_trust/gateway/__init__.py | 2 + .../gateway/certificate_activate_response.py | 6 + .../gateway/certificate_create_response.py | 6 + .../certificate_deactivate_response.py | 6 + .../gateway/certificate_delete_response.py | 6 + .../gateway/certificate_get_response.py | 6 + .../gateway/certificate_list_response.py | 6 + .../dns_destination_ip_list_response.py | 22 + .../gateway/dns_destination_ips_id.py} | 4 +- .../types/zero_trust/gateway/gateway_rule.py | 1 + .../types/zero_trust/gateway/location.py | 9 +- .../gateway/location_create_params.py | 6 + .../gateway/location_update_params.py | 6 + .../zero_trust/gateway/rule_create_params.py | 1 + .../types/zero_trust/gateway/rule_setting.py | 44 +- .../zero_trust/gateway/rule_setting_param.py | 44 +- .../zero_trust/gateway/rule_update_params.py | 1 + .../types/zero_trust/identity_provider.py | 233 + .../identity_provider_create_params.py | 113 + .../identity_provider_list_response.py | 233 + .../zero_trust/identity_provider_param.py | 101 + .../zero_trust/identity_provider_type.py | 2 + .../identity_provider_update_params.py | 113 + .../identity_providers/scim/__init__.py | 1 + .../scim/group_get_response.py | 57 + .../types/zero_trust/organization.py | 15 +- .../zero_trust/organization_create_params.py | 23 +- .../zero_trust/organization_list_response.py | 15 +- .../zero_trust/organization_update_params.py | 15 +- .../organizations/doh_get_response.py | 32 +- .../organizations/doh_update_response.py | 32 +- .../application_create_params.py | 24 +- .../application_create_response.py | 14 +- .../application_get_response.py | 14 +- .../application_list_params.py | 68 +- .../application_list_response.py | 16 +- .../application_update_params.py | 6 +- .../application_update_response.py | 14 +- .../resource_library/category_get_response.py | 2 +- .../resource_library/category_list_params.py | 16 +- .../category_list_response.py | 2 +- .../risk_scoring/behaviour_get_response.py | 2 +- .../risk_scoring/behaviour_update_params.py | 2 +- .../risk_scoring/behaviour_update_response.py | 2 +- .../risk_scoring/summary_get_response.py | 2 +- .../zero_trust/risk_scoring_get_response.py | 4 +- .../types/zero_trust/tunnel_list_response.py | 2 +- .../configuration_get_response.py | 6 +- .../configuration_update_params.py | 6 +- .../configuration_update_response.py | 6 +- .../warp_connector/connection_get_response.py | 12 +- .../warp_connector/connector_get_response.py | 12 +- .../tunnels/warp_connector_create_response.py | 2 +- .../tunnels/warp_connector_delete_response.py | 2 +- .../tunnels/warp_connector_edit_response.py | 2 +- .../tunnels/warp_connector_get_response.py | 2 +- .../tunnels/warp_connector_list_response.py | 2 +- src/cloudflare/types/zones/__init__.py | 1 - src/cloudflare/types/zones/advanced_ddos.py | 4 +- src/cloudflare/types/zones/always_online.py | 4 +- .../zones/automatic_platform_optimization.py | 38 - src/cloudflare/types/zones/brotli.py | 4 +- src/cloudflare/types/zones/challenge_ttl.py | 4 +- src/cloudflare/types/zones/ciphers.py | 4 +- .../types/zones/development_mode.py | 4 +- src/cloudflare/types/zones/early_hints.py | 4 +- .../types/zones/h2_prioritization.py | 4 +- .../types/zones/hotlink_protection.py | 4 +- src/cloudflare/types/zones/http2.py | 4 +- src/cloudflare/types/zones/http3.py | 4 +- src/cloudflare/types/zones/image_resizing.py | 4 +- src/cloudflare/types/zones/ipv6.py | 4 +- src/cloudflare/types/zones/min_tls_version.py | 4 +- src/cloudflare/types/zones/nel.py | 13 +- .../types/zones/opportunistic_onion.py | 4 +- .../types/zones/orange_to_orange.py | 4 +- .../types/zones/prefetch_preload.py | 4 +- .../types/zones/proxy_read_timeout.py | 6 +- src/cloudflare/types/zones/pseudo_ipv4.py | 4 +- .../types/zones/security_headers.py | 28 +- .../types/zones/server_side_excludes.py | 4 +- .../types/zones/setting_edit_response.py | 351 +- .../types/zones/setting_get_response.py | 351 +- src/cloudflare/types/zones/tls_1_3.py | 4 +- src/cloudflare/types/zones/tls_client_auth.py | 4 +- src/cloudflare/types/zones/webp.py | 4 +- src/cloudflare/types/zones/websocket.py | 4 +- src/cloudflare/types/zones/zero_rtt.py | 4 +- .../abuse_reports/test_mitigations.py | 2 + .../accounts/subscriptions/test_bulk.py | 18 +- .../accounts/test_pay_bad_debt.py | 116 - .../ai_gateway/billing/topup/test_config.py | 168 +- .../namespaces/instances/test_items.py | 300 +- .../namespaces/instances/test_jobs.py | 164 +- .../aisearch/namespaces/test_instances.py | 386 +- .../api_resources/aisearch/test_instances.py | 16 + .../api_gateway/discovery/test_operations.py | 115 + .../spend_policies}/__init__.py | 0 .../billing/spend_policies/test_activity.py | 121 + .../billing/spend_policies/test_audit.py | 141 + .../billing/test_spend_policies.py | 637 ++ .../brand_protection/test_queries.py | 18 +- .../devtools/browser/test_page.py | 172 - .../devtools/test_browser.py | 238 - .../test_accessibility_tree.py | 4 + .../browser_rendering/test_content.py | 4 + .../browser_rendering/test_json.py | 4 + .../browser_rendering/test_links.py | 4 + .../browser_rendering/test_markdown.py | 4 + .../browser_rendering/test_pdf.py | 4 + .../browser_rendering/test_scrape.py | 4 + .../browser_rendering/test_screenshot.py | 4 + .../browser_rendering/test_snapshot.py | 4 + .../cloudforce_one/test_threat_events.py | 18 + .../threat_events/test_queries.py | 32 +- .../threat_signals/test_articles.py | 6 + .../threat_signals/test_skills.py | 26 +- .../connectivity/directory/test_services.py | 48 +- .../containers/test_applications.py | 2 + tests/api_resources/d1/test_database.py | 116 + .../diagnostics/test_endpoint_healthchecks.py | 17 +- .../settings/account/test_nameserver_sets.py | 442 ++ .../settings/test_allow_policies.py | 7 + .../settings/test_block_senders.py | 7 + .../settings/test_content_policies.py | 7 + .../email_sending/test_suppressions.py | 4 +- .../api_resources/flagship/apps/test_flags.py | 4 + .../catalog_syncs => k2}/__init__.py | 0 .../on_ramps => k2/streams}/__init__.py | 0 .../k2/streams/test_subscriptions.py | 121 + tests/api_resources/k2/test_streams.py | 558 ++ tests/api_resources/kv/test_namespaces.py | 2 + .../load_balancers/test_pools.py | 10 + .../catalog_syncs/test_prebuilt_policies.py | 119 - .../on_ramps/test_address_spaces.py | 272 - .../test_catalog_syncs.py | 780 --- .../test_cloud_integrations.py | 995 --- .../magic_cloud_networking/test_on_ramps.py | 1132 ---- .../magic_cloud_networking/test_resources.py | 508 -- .../rules/test_advertisements.py | 10 - .../magic_transit/sites/test_lans.py | 36 + .../magic_transit/sites/test_wans.py | 22 +- .../vulnerability_discovery/test_scans.py | 34 +- tests/api_resources/monetization/__init__.py | 1 + .../api_resources/monetization/test_rules.py | 635 ++ .../network_interconnects/test_cnis.py | 8 +- .../test_organization_profile.py | 44 +- tests/api_resources/pipelines/test_sinks.py | 4 + tests/api_resources/pipelines/test_streams.py | 4 + tests/api_resources/r2/buckets/test_jobs.py | 562 ++ .../radar/robots_txt/top/test_user_agents.py | 4 +- .../radar/test_agent_readiness.py | 4 +- tests/api_resources/radar/test_ranking.py | 8 +- .../realtime_kit/test_meetings.py | 34 + .../realtime_kit/test_webhooks.py | 224 +- tests/api_resources/registrar/test_domains.py | 351 - .../resource_sharing/test_recipients.py | 2 - .../resource_sharing/test_resources.py | 20 +- .../rulesets/phases/test_versions.py | 17 +- tests/api_resources/rulesets/test_versions.py | 17 +- .../secrets_store/stores/test_secrets.py | 26 +- .../tenants/test_account_types.py | 101 - tests/api_resources/tenants/test_accounts.py | 82 +- .../tenants/test_entitlements.py | 100 - tests/api_resources/test_abuse_reports.py | 4 + tests/api_resources/test_ai_gateway.py | 8 + tests/api_resources/test_basin_catalog.py | 18 + tests/api_resources/test_bot_management.py | 56 + tests/api_resources/test_load_balancers.py | 192 +- tests/api_resources/test_organizations.py | 48 +- tests/api_resources/test_precursor.py | 20 +- tests/api_resources/test_r2_data_catalog.py | 22 + tests/api_resources/test_resource_sharing.py | 118 +- tests/api_resources/test_resource_tagging.py | 2 + tests/api_resources/test_rulesets.py | 17 +- .../test_tenant_custom_nameservers.py | 331 - tests/api_resources/test_tenants.py | 100 - tests/api_resources/test_workflows.py | 2 + tests/api_resources/url_scanner/test_scans.py | 4 +- tests/api_resources/user/test_tenants.py | 14 +- tests/api_resources/vectorize/test_indexes.py | 17 +- .../workers/beta/workers/test_versions.py | 216 + .../observability/test_destinations.py | 64 +- .../workers/scripts/test_deployments.py | 2 + tests/api_resources/workers/test_domains.py | 8 + tests/api_resources/workers/test_scripts.py | 2 + .../dispatch/namespaces/scripts/test_tags.py | 59 +- .../dispatch/namespaces/test_scripts.py | 2 + .../access/applications/test_policies.py | 4 + .../access/logs/test_jit_requests.py | 227 + .../zero_trust/access/mfa/__init__.py | 1 + .../access/mfa/test_authenticator_catalog.py | 105 + .../zero_trust/access/test_applications.py | 954 ++- .../zero_trust/access/test_custom_pages.py | 113 + .../zero_trust/access/test_policies.py | 4 + .../zero_trust/access/test_service_tokens.py | 4 + .../access/test_user_populations.py | 511 ++ .../access/user_populations/__init__.py | 1 + .../access/user_populations/test_users.py | 939 +++ .../access/users/test_last_seen_identity.py | 14 +- .../access/users/test_mfa_authenticators.py | 143 + .../zero_trust/access/users/test_passkeys.py | 143 + .../casb/posture/test_asset_schemas.py | 216 + .../casb/posture/test_finding_types.py | 572 ++ .../zero_trust/casb/posture/test_webhooks.py | 100 +- .../zero_trust/casb/test_integrations.py | 12 +- .../api_resources/zero_trust/cws/__init__.py | 1 + .../cws/basic_auth_credentials/__init__.py | 1 + .../basic_auth_credentials/test_secrets.py | 515 ++ .../cws/tenant_structures/__init__.py | 1 + .../cws/tenant_structures/test_nodes.py | 883 +++ .../cws/test_basic_auth_credentials.py | 406 ++ .../zero_trust/cws/test_deployments.py | 630 ++ .../zero_trust/cws/test_domain_acls.py | 638 ++ .../zero_trust/cws/test_policies.py | 622 ++ .../zero_trust/cws/test_policy_sets.py | 604 ++ .../zero_trust/cws/test_rego_metadata.py | 548 ++ .../zero_trust/cws/test_rego_modules.py | 530 ++ .../zero_trust/cws/test_tenant_structures.py | 572 ++ .../zero_trust/cws/test_workloads.py | 576 ++ .../devices/policies/test_custom.py | 8 + .../devices/policies/test_default.py | 4 + .../zero_trust/dlp/entries/test_custom.py | 4 + .../zero_trust/dlp/test_entries.py | 4 + .../zero_trust/dlp/test_validators.py | 213 + .../zero_trust/dlp/validators/__init__.py | 1 + .../dlp/validators/test_proximity_words.py | 593 ++ .../gateway/test_dns_destination_ips.py} | 62 +- .../zero_trust/gateway/test_locations.py | 4 + .../zero_trust/gateway/test_rules.py | 8 +- .../identity_providers/scim/test_groups.py | 243 +- .../identity_providers/scim/test_users.py | 242 +- .../resource_library/test_applications.py | 34 +- .../resource_library/test_categories.py | 20 +- .../risk_scoring/test_behaviours.py | 16 +- .../zero_trust/test_identity_providers.py | 932 ++- .../zero_trust/test_organizations.py | 32 +- uv.lock | 2 +- 1289 files changed, 87344 insertions(+), 37605 deletions(-) create mode 100644 docs/migration-guides/v5.10.0-migration-guide.md delete mode 100644 src/cloudflare/resources/accounts/pay_bad_debt.py create mode 100644 src/cloudflare/resources/billing/spend_policies/__init__.py create mode 100644 src/cloudflare/resources/billing/spend_policies/activity.py create mode 100644 src/cloudflare/resources/billing/spend_policies/audit.py create mode 100644 src/cloudflare/resources/billing/spend_policies/spend_policies.py delete mode 100644 src/cloudflare/resources/browser_rendering/devtools/browser/page.py create mode 100644 src/cloudflare/resources/dns/settings/account/nameserver_sets.py create mode 100644 src/cloudflare/resources/k2/__init__.py create mode 100644 src/cloudflare/resources/k2/api.md create mode 100644 src/cloudflare/resources/k2/k2.py create mode 100644 src/cloudflare/resources/k2/streams/__init__.py create mode 100644 src/cloudflare/resources/k2/streams/streams.py rename src/cloudflare/resources/{magic_cloud_networking/catalog_syncs/prebuilt_policies.py => k2/streams/subscriptions.py} (51%) delete mode 100644 src/cloudflare/resources/magic_cloud_networking/__init__.py delete mode 100644 src/cloudflare/resources/magic_cloud_networking/api.md delete mode 100644 src/cloudflare/resources/magic_cloud_networking/catalog_syncs/__init__.py delete mode 100644 src/cloudflare/resources/magic_cloud_networking/catalog_syncs/catalog_syncs.py delete mode 100644 src/cloudflare/resources/magic_cloud_networking/cloud_integrations.py delete mode 100644 src/cloudflare/resources/magic_cloud_networking/magic_cloud_networking.py delete mode 100644 src/cloudflare/resources/magic_cloud_networking/on_ramps/__init__.py delete mode 100644 src/cloudflare/resources/magic_cloud_networking/on_ramps/address_spaces.py delete mode 100644 src/cloudflare/resources/magic_cloud_networking/on_ramps/on_ramps.py delete mode 100644 src/cloudflare/resources/magic_cloud_networking/resources.py create mode 100644 src/cloudflare/resources/monetization/__init__.py create mode 100644 src/cloudflare/resources/monetization/api.md create mode 100644 src/cloudflare/resources/monetization/monetization.py create mode 100644 src/cloudflare/resources/monetization/rules.py create mode 100644 src/cloudflare/resources/r2/buckets/jobs.py delete mode 100644 src/cloudflare/resources/registrar/domains.py delete mode 100644 src/cloudflare/resources/tenant_custom_nameservers/api.md delete mode 100644 src/cloudflare/resources/tenant_custom_nameservers/tenant_custom_nameservers.py delete mode 100644 src/cloudflare/resources/tenants/entitlements.py create mode 100644 src/cloudflare/resources/zero_trust/access/logs/jit_requests.py create mode 100644 src/cloudflare/resources/zero_trust/access/mfa/__init__.py rename src/cloudflare/resources/{tenants/memberships.py => zero_trust/access/mfa/authenticator_catalog.py} (51%) create mode 100644 src/cloudflare/resources/zero_trust/access/mfa/mfa.py create mode 100644 src/cloudflare/resources/zero_trust/access/user_populations/__init__.py create mode 100644 src/cloudflare/resources/zero_trust/access/user_populations/user_populations.py create mode 100644 src/cloudflare/resources/zero_trust/access/user_populations/users.py create mode 100644 src/cloudflare/resources/zero_trust/access/users/mfa_authenticators.py create mode 100644 src/cloudflare/resources/zero_trust/access/users/passkeys.py create mode 100644 src/cloudflare/resources/zero_trust/casb/posture/asset_schemas.py create mode 100644 src/cloudflare/resources/zero_trust/cws/__init__.py create mode 100644 src/cloudflare/resources/zero_trust/cws/basic_auth_credentials/__init__.py create mode 100644 src/cloudflare/resources/zero_trust/cws/basic_auth_credentials/basic_auth_credentials.py create mode 100644 src/cloudflare/resources/zero_trust/cws/basic_auth_credentials/secrets.py create mode 100644 src/cloudflare/resources/zero_trust/cws/cws.py create mode 100644 src/cloudflare/resources/zero_trust/cws/deployments.py create mode 100644 src/cloudflare/resources/zero_trust/cws/domain_acls.py create mode 100644 src/cloudflare/resources/zero_trust/cws/policies.py create mode 100644 src/cloudflare/resources/zero_trust/cws/policy_sets.py create mode 100644 src/cloudflare/resources/zero_trust/cws/rego_metadata.py create mode 100644 src/cloudflare/resources/zero_trust/cws/rego_modules.py create mode 100644 src/cloudflare/resources/zero_trust/cws/tenant_structures/__init__.py create mode 100644 src/cloudflare/resources/zero_trust/cws/tenant_structures/nodes.py create mode 100644 src/cloudflare/resources/zero_trust/cws/tenant_structures/tenant_structures.py create mode 100644 src/cloudflare/resources/zero_trust/cws/workloads.py create mode 100644 src/cloudflare/resources/zero_trust/dlp/validators/__init__.py create mode 100644 src/cloudflare/resources/zero_trust/dlp/validators/proximity_words.py create mode 100644 src/cloudflare/resources/zero_trust/dlp/validators/validators.py rename src/cloudflare/resources/{tenants/account_types.py => zero_trust/gateway/dns_destination_ips.py} (52%) delete mode 100644 src/cloudflare/types/accounts/pay_bad_debt_create_params.py delete mode 100644 src/cloudflare/types/accounts/pay_bad_debt_create_response.py create mode 100644 src/cloudflare/types/aisearch/namespaces/instance_move_params.py create mode 100644 src/cloudflare/types/api_gateway/discovery/operation_edit_params.py create mode 100644 src/cloudflare/types/api_gateway/discovery/operation_edit_response.py create mode 100644 src/cloudflare/types/basin_catalog/basin_catalog_enable_params.py create mode 100644 src/cloudflare/types/billing/spend_policies/__init__.py create mode 100644 src/cloudflare/types/billing/spend_policies/activity_list_params.py create mode 100644 src/cloudflare/types/billing/spend_policies/activity_list_response.py create mode 100644 src/cloudflare/types/billing/spend_policies/audit_list_params.py create mode 100644 src/cloudflare/types/billing/spend_policies/audit_list_response.py create mode 100644 src/cloudflare/types/billing/spend_policy_create_params.py create mode 100644 src/cloudflare/types/billing/spend_policy_create_response.py create mode 100644 src/cloudflare/types/billing/spend_policy_delete_response.py create mode 100644 src/cloudflare/types/billing/spend_policy_get_response.py create mode 100644 src/cloudflare/types/billing/spend_policy_list_response.py create mode 100644 src/cloudflare/types/billing/spend_policy_update_params.py create mode 100644 src/cloudflare/types/billing/spend_policy_update_response.py delete mode 100644 src/cloudflare/types/browser_rendering/devtools/browser_connect_params.py delete mode 100644 src/cloudflare/types/browser_rendering/devtools/browser_launch_params.py create mode 100644 src/cloudflare/types/d1/database_undelete_params.py create mode 100644 src/cloudflare/types/dns/settings/account/nameserver_set_create_params.py create mode 100644 src/cloudflare/types/dns/settings/account/nameserver_set_create_response.py create mode 100644 src/cloudflare/types/dns/settings/account/nameserver_set_delete_response.py create mode 100644 src/cloudflare/types/dns/settings/account/nameserver_set_get_response.py create mode 100644 src/cloudflare/types/dns/settings/account/nameserver_set_list_params.py create mode 100644 src/cloudflare/types/dns/settings/account/nameserver_set_list_response.py delete mode 100644 src/cloudflare/types/intel/whois.py create mode 100644 src/cloudflare/types/k2/__init__.py create mode 100644 src/cloudflare/types/k2/stream_create_params.py create mode 100644 src/cloudflare/types/k2/stream_create_response.py create mode 100644 src/cloudflare/types/k2/stream_get_response.py create mode 100644 src/cloudflare/types/k2/stream_list_params.py create mode 100644 src/cloudflare/types/k2/stream_list_response.py create mode 100644 src/cloudflare/types/k2/stream_update_params.py create mode 100644 src/cloudflare/types/k2/stream_update_response.py create mode 100644 src/cloudflare/types/k2/streams/__init__.py create mode 100644 src/cloudflare/types/k2/streams/subscription_list_response.py delete mode 100644 src/cloudflare/types/magic_cloud_networking/__init__.py delete mode 100644 src/cloudflare/types/magic_cloud_networking/catalog_sync_create_params.py delete mode 100644 src/cloudflare/types/magic_cloud_networking/catalog_sync_create_response.py delete mode 100644 src/cloudflare/types/magic_cloud_networking/catalog_sync_delete_params.py delete mode 100644 src/cloudflare/types/magic_cloud_networking/catalog_sync_delete_response.py delete mode 100644 src/cloudflare/types/magic_cloud_networking/catalog_sync_edit_params.py delete mode 100644 src/cloudflare/types/magic_cloud_networking/catalog_sync_edit_response.py delete mode 100644 src/cloudflare/types/magic_cloud_networking/catalog_sync_get_response.py delete mode 100644 src/cloudflare/types/magic_cloud_networking/catalog_sync_list_response.py delete mode 100644 src/cloudflare/types/magic_cloud_networking/catalog_sync_refresh_response.py delete mode 100644 src/cloudflare/types/magic_cloud_networking/catalog_sync_update_params.py delete mode 100644 src/cloudflare/types/magic_cloud_networking/catalog_sync_update_response.py delete mode 100644 src/cloudflare/types/magic_cloud_networking/catalog_syncs/__init__.py delete mode 100644 src/cloudflare/types/magic_cloud_networking/catalog_syncs/prebuilt_policy_list_params.py delete mode 100644 src/cloudflare/types/magic_cloud_networking/catalog_syncs/prebuilt_policy_list_response.py delete mode 100644 src/cloudflare/types/magic_cloud_networking/cloud_integration_create_params.py delete mode 100644 src/cloudflare/types/magic_cloud_networking/cloud_integration_create_response.py delete mode 100644 src/cloudflare/types/magic_cloud_networking/cloud_integration_delete_response.py delete mode 100644 src/cloudflare/types/magic_cloud_networking/cloud_integration_discover_all_response.py delete mode 100644 src/cloudflare/types/magic_cloud_networking/cloud_integration_discover_params.py delete mode 100644 src/cloudflare/types/magic_cloud_networking/cloud_integration_discover_response.py delete mode 100644 src/cloudflare/types/magic_cloud_networking/cloud_integration_edit_params.py delete mode 100644 src/cloudflare/types/magic_cloud_networking/cloud_integration_edit_response.py delete mode 100644 src/cloudflare/types/magic_cloud_networking/cloud_integration_get_params.py delete mode 100644 src/cloudflare/types/magic_cloud_networking/cloud_integration_get_response.py delete mode 100644 src/cloudflare/types/magic_cloud_networking/cloud_integration_initial_setup_response.py delete mode 100644 src/cloudflare/types/magic_cloud_networking/cloud_integration_list_params.py delete mode 100644 src/cloudflare/types/magic_cloud_networking/cloud_integration_list_response.py delete mode 100644 src/cloudflare/types/magic_cloud_networking/cloud_integration_update_params.py delete mode 100644 src/cloudflare/types/magic_cloud_networking/cloud_integration_update_response.py delete mode 100644 src/cloudflare/types/magic_cloud_networking/on_ramp_apply_response.py delete mode 100644 src/cloudflare/types/magic_cloud_networking/on_ramp_create_params.py delete mode 100644 src/cloudflare/types/magic_cloud_networking/on_ramp_create_response.py delete mode 100644 src/cloudflare/types/magic_cloud_networking/on_ramp_delete_params.py delete mode 100644 src/cloudflare/types/magic_cloud_networking/on_ramp_delete_response.py delete mode 100644 src/cloudflare/types/magic_cloud_networking/on_ramp_edit_params.py delete mode 100644 src/cloudflare/types/magic_cloud_networking/on_ramp_edit_response.py delete mode 100644 src/cloudflare/types/magic_cloud_networking/on_ramp_get_params.py delete mode 100644 src/cloudflare/types/magic_cloud_networking/on_ramp_get_response.py delete mode 100644 src/cloudflare/types/magic_cloud_networking/on_ramp_list_params.py delete mode 100644 src/cloudflare/types/magic_cloud_networking/on_ramp_list_response.py delete mode 100644 src/cloudflare/types/magic_cloud_networking/on_ramp_plan_response.py delete mode 100644 src/cloudflare/types/magic_cloud_networking/on_ramp_update_params.py delete mode 100644 src/cloudflare/types/magic_cloud_networking/on_ramp_update_response.py delete mode 100644 src/cloudflare/types/magic_cloud_networking/on_ramps/__init__.py delete mode 100644 src/cloudflare/types/magic_cloud_networking/on_ramps/address_space_edit_params.py delete mode 100644 src/cloudflare/types/magic_cloud_networking/on_ramps/address_space_edit_response.py delete mode 100644 src/cloudflare/types/magic_cloud_networking/on_ramps/address_space_list_response.py delete mode 100644 src/cloudflare/types/magic_cloud_networking/on_ramps/address_space_update_params.py delete mode 100644 src/cloudflare/types/magic_cloud_networking/on_ramps/address_space_update_response.py delete mode 100644 src/cloudflare/types/magic_cloud_networking/resource_export_params.py delete mode 100644 src/cloudflare/types/magic_cloud_networking/resource_get_params.py delete mode 100644 src/cloudflare/types/magic_cloud_networking/resource_get_response.py delete mode 100644 src/cloudflare/types/magic_cloud_networking/resource_list_params.py delete mode 100644 src/cloudflare/types/magic_cloud_networking/resource_list_response.py delete mode 100644 src/cloudflare/types/magic_cloud_networking/resource_policy_preview_params.py delete mode 100644 src/cloudflare/types/magic_cloud_networking/resource_policy_preview_response.py delete mode 100644 src/cloudflare/types/magic_network_monitoring/rules/advertisement_edit_params.py delete mode 100644 src/cloudflare/types/magic_transit/sites/wan_static_addressing_param.py create mode 100644 src/cloudflare/types/monetization/__init__.py create mode 100644 src/cloudflare/types/monetization/monetization_rule.py create mode 100644 src/cloudflare/types/monetization/monetization_rule_collection.py create mode 100644 src/cloudflare/types/monetization/monetization_rule_input_fixed_price.py create mode 100644 src/cloudflare/types/monetization/monetization_rule_input_fixed_price_param.py create mode 100644 src/cloudflare/types/monetization/monetization_rule_input_origin_controlled.py create mode 100644 src/cloudflare/types/monetization/monetization_rule_input_origin_controlled_param.py create mode 100644 src/cloudflare/types/monetization/monetization_rule_input_param.py create mode 100644 src/cloudflare/types/monetization/rule_edit_rule_params.py create mode 100644 src/cloudflare/types/monetization/rule_update_params.py delete mode 100644 src/cloudflare/types/organizations/organization_profile_param.py delete mode 100644 src/cloudflare/types/precursor/enforcement_rule.py delete mode 100644 src/cloudflare/types/precursor/enforcement_rule_param.py create mode 100644 src/cloudflare/types/r2/buckets/job_create_params.py create mode 100644 src/cloudflare/types/r2/buckets/job_create_response.py create mode 100644 src/cloudflare/types/r2/buckets/job_get_response.py create mode 100644 src/cloudflare/types/r2/buckets/job_list_params.py create mode 100644 src/cloudflare/types/r2/buckets/job_list_response.py create mode 100644 src/cloudflare/types/r2_data_catalog/r2_data_catalog_enable_params.py create mode 100644 src/cloudflare/types/realtime_kit/meeting_refresh_participant_token_params.py delete mode 100644 src/cloudflare/types/registrar/domain.py delete mode 100644 src/cloudflare/types/registrar/domain_update_params.py delete mode 100644 src/cloudflare/types/shared/load_balancer_preview.py delete mode 100644 src/cloudflare/types/tenant_custom_nameservers/tenant_custom_nameserver_create_params.py delete mode 100644 src/cloudflare/types/tenant_custom_nameservers/tenant_custom_nameserver_create_response.py delete mode 100644 src/cloudflare/types/tenant_custom_nameservers/tenant_custom_nameserver_delete_response.py delete mode 100644 src/cloudflare/types/tenant_custom_nameservers/tenant_custom_nameserver_get_response.py create mode 100644 src/cloudflare/types/tenants/account_list_params.py create mode 100644 src/cloudflare/types/tenants/account_list_response.py delete mode 100644 src/cloudflare/types/tenants/tenant.py delete mode 100644 src/cloudflare/types/tenants/tenant_account.py delete mode 100644 src/cloudflare/types/tenants/tenant_entitlements.py delete mode 100644 src/cloudflare/types/tenants/tenant_membership.py create mode 100644 src/cloudflare/types/user/tenant_list_response.py create mode 100644 src/cloudflare/types/vectorize/index_get_by_ids_response.py create mode 100644 src/cloudflare/types/workers/beta/workers/version_profile_params.py create mode 100644 src/cloudflare/types/workers_for_platforms/dispatch/namespaces/scripts/tag_delete_response.py create mode 100644 src/cloudflare/types/zero_trust/access/custom_page_validate_params.py create mode 100644 src/cloudflare/types/zero_trust/access/custom_page_validate_response.py create mode 100644 src/cloudflare/types/zero_trust/access/destination_override.py create mode 100644 src/cloudflare/types/zero_trust/access/destination_override_param.py create mode 100644 src/cloudflare/types/zero_trust/access/logs/jit_request_get_response.py create mode 100644 src/cloudflare/types/zero_trust/access/logs/jit_request_list_params.py create mode 100644 src/cloudflare/types/zero_trust/access/logs/jit_request_list_response.py create mode 100644 src/cloudflare/types/zero_trust/access/mfa/__init__.py create mode 100644 src/cloudflare/types/zero_trust/access/mfa/authenticator_catalog_list_response.py create mode 100644 src/cloudflare/types/zero_trust/access/user_population_create_params.py create mode 100644 src/cloudflare/types/zero_trust/access/user_population_create_response.py create mode 100644 src/cloudflare/types/zero_trust/access/user_population_delete_response.py create mode 100644 src/cloudflare/types/zero_trust/access/user_population_get_response.py create mode 100644 src/cloudflare/types/zero_trust/access/user_population_list_params.py create mode 100644 src/cloudflare/types/zero_trust/access/user_population_list_response.py create mode 100644 src/cloudflare/types/zero_trust/access/user_population_update_params.py create mode 100644 src/cloudflare/types/zero_trust/access/user_population_update_response.py create mode 100644 src/cloudflare/types/zero_trust/access/user_populations/__init__.py create mode 100644 src/cloudflare/types/zero_trust/access/user_populations/user_create_params.py create mode 100644 src/cloudflare/types/zero_trust/access/user_populations/user_create_response.py create mode 100644 src/cloudflare/types/zero_trust/access/user_populations/user_get_params.py create mode 100644 src/cloudflare/types/zero_trust/access/user_populations/user_get_response.py create mode 100644 src/cloudflare/types/zero_trust/access/user_populations/user_list_params.py create mode 100644 src/cloudflare/types/zero_trust/access/user_populations/user_list_response.py create mode 100644 src/cloudflare/types/zero_trust/access/user_populations/user_replace_params.py create mode 100644 src/cloudflare/types/zero_trust/access/user_populations/user_replace_response.py create mode 100644 src/cloudflare/types/zero_trust/access/user_populations/user_update_params.py create mode 100644 src/cloudflare/types/zero_trust/access/user_populations/user_update_response.py rename src/cloudflare/types/zero_trust/access/users/{identity.py => last_seen_identity_get_response.py} (75%) create mode 100644 src/cloudflare/types/zero_trust/casb/posture/asset_schema_get_response.py create mode 100644 src/cloudflare/types/zero_trust/casb/posture/asset_schema_list_params.py create mode 100644 src/cloudflare/types/zero_trust/casb/posture/asset_schema_list_response.py create mode 100644 src/cloudflare/types/zero_trust/casb/posture/finding_type_create_params.py create mode 100644 src/cloudflare/types/zero_trust/casb/posture/finding_type_create_response.py create mode 100644 src/cloudflare/types/zero_trust/casb/posture/finding_type_update_params.py create mode 100644 src/cloudflare/types/zero_trust/casb/posture/finding_type_update_response.py create mode 100644 src/cloudflare/types/zero_trust/casb/posture/finding_type_validate_params.py create mode 100644 src/cloudflare/types/zero_trust/casb/posture/finding_type_validate_response.py create mode 100644 src/cloudflare/types/zero_trust/cws/__init__.py create mode 100644 src/cloudflare/types/zero_trust/cws/basic_auth_credential.py create mode 100644 src/cloudflare/types/zero_trust/cws/basic_auth_credential_create_params.py create mode 100644 src/cloudflare/types/zero_trust/cws/basic_auth_credential_delete_response.py create mode 100644 src/cloudflare/types/zero_trust/cws/basic_auth_credential_list_params.py create mode 100644 src/cloudflare/types/zero_trust/cws/basic_auth_credentials/__init__.py create mode 100644 src/cloudflare/types/zero_trust/cws/basic_auth_credentials/basic_auth_secret.py create mode 100644 src/cloudflare/types/zero_trust/cws/basic_auth_credentials/secret_create_params.py create mode 100644 src/cloudflare/types/zero_trust/cws/basic_auth_credentials/secret_delete_response.py create mode 100644 src/cloudflare/types/zero_trust/cws/basic_auth_credentials/secret_list_params.py create mode 100644 src/cloudflare/types/zero_trust/cws/deployment.py create mode 100644 src/cloudflare/types/zero_trust/cws/deployment_create_params.py create mode 100644 src/cloudflare/types/zero_trust/cws/deployment_delete_response.py create mode 100644 src/cloudflare/types/zero_trust/cws/deployment_list_params.py create mode 100644 src/cloudflare/types/zero_trust/cws/deployment_update_params.py create mode 100644 src/cloudflare/types/zero_trust/cws/domain_acl.py create mode 100644 src/cloudflare/types/zero_trust/cws/domain_acl_create_params.py create mode 100644 src/cloudflare/types/zero_trust/cws/domain_acl_delete_response.py create mode 100644 src/cloudflare/types/zero_trust/cws/domain_acl_list_params.py create mode 100644 src/cloudflare/types/zero_trust/cws/domain_acl_update_params.py create mode 100644 src/cloudflare/types/zero_trust/cws/policy.py create mode 100644 src/cloudflare/types/zero_trust/cws/policy_create_params.py create mode 100644 src/cloudflare/types/zero_trust/cws/policy_delete_response.py create mode 100644 src/cloudflare/types/zero_trust/cws/policy_list_params.py create mode 100644 src/cloudflare/types/zero_trust/cws/policy_set.py create mode 100644 src/cloudflare/types/zero_trust/cws/policy_set_create_params.py create mode 100644 src/cloudflare/types/zero_trust/cws/policy_set_delete_response.py create mode 100644 src/cloudflare/types/zero_trust/cws/policy_set_list_params.py create mode 100644 src/cloudflare/types/zero_trust/cws/policy_set_update_params.py create mode 100644 src/cloudflare/types/zero_trust/cws/policy_update_params.py create mode 100644 src/cloudflare/types/zero_trust/cws/rego_metadata.py create mode 100644 src/cloudflare/types/zero_trust/cws/rego_metadata_create_params.py create mode 100644 src/cloudflare/types/zero_trust/cws/rego_metadata_delete_response.py create mode 100644 src/cloudflare/types/zero_trust/cws/rego_metadata_list_params.py create mode 100644 src/cloudflare/types/zero_trust/cws/rego_metadata_update_params.py create mode 100644 src/cloudflare/types/zero_trust/cws/rego_module.py create mode 100644 src/cloudflare/types/zero_trust/cws/rego_module_create_params.py create mode 100644 src/cloudflare/types/zero_trust/cws/rego_module_delete_response.py create mode 100644 src/cloudflare/types/zero_trust/cws/rego_module_list_params.py create mode 100644 src/cloudflare/types/zero_trust/cws/rego_module_update_params.py create mode 100644 src/cloudflare/types/zero_trust/cws/tenant_structure.py create mode 100644 src/cloudflare/types/zero_trust/cws/tenant_structure_create_params.py create mode 100644 src/cloudflare/types/zero_trust/cws/tenant_structure_delete_response.py create mode 100644 src/cloudflare/types/zero_trust/cws/tenant_structure_list_params.py create mode 100644 src/cloudflare/types/zero_trust/cws/tenant_structure_update_params.py create mode 100644 src/cloudflare/types/zero_trust/cws/tenant_structures/__init__.py create mode 100644 src/cloudflare/types/zero_trust/cws/tenant_structures/node_batch_params.py create mode 100644 src/cloudflare/types/zero_trust/cws/tenant_structures/node_batch_response.py create mode 100644 src/cloudflare/types/zero_trust/cws/tenant_structures/node_create_params.py create mode 100644 src/cloudflare/types/zero_trust/cws/tenant_structures/node_delete_response.py create mode 100644 src/cloudflare/types/zero_trust/cws/tenant_structures/node_list_params.py create mode 100644 src/cloudflare/types/zero_trust/cws/tenant_structures/node_update_params.py create mode 100644 src/cloudflare/types/zero_trust/cws/tenant_structures/tenant_structure_node.py create mode 100644 src/cloudflare/types/zero_trust/cws/workload.py create mode 100644 src/cloudflare/types/zero_trust/cws/workload_create_params.py create mode 100644 src/cloudflare/types/zero_trust/cws/workload_delete_response.py create mode 100644 src/cloudflare/types/zero_trust/cws/workload_list_params.py create mode 100644 src/cloudflare/types/zero_trust/cws/workload_update_params.py create mode 100644 src/cloudflare/types/zero_trust/dlp/references.py create mode 100644 src/cloudflare/types/zero_trust/dlp/validator.py create mode 100644 src/cloudflare/types/zero_trust/dlp/validator_array.py create mode 100644 src/cloudflare/types/zero_trust/dlp/validator_list_params.py create mode 100644 src/cloudflare/types/zero_trust/dlp/validators/__init__.py create mode 100644 src/cloudflare/types/zero_trust/dlp/validators/proximity_word_create_params.py create mode 100644 src/cloudflare/types/zero_trust/dlp/validators/proximity_word_update_params.py create mode 100644 src/cloudflare/types/zero_trust/dlp/validators/proximity_word_validator.py create mode 100644 src/cloudflare/types/zero_trust/dlp/validators/proximity_word_validator_array.py create mode 100644 src/cloudflare/types/zero_trust/dlp/validators/weight.py create mode 100644 src/cloudflare/types/zero_trust/dlp/validators/word.py create mode 100644 src/cloudflare/types/zero_trust/dlp/validators/word_param.py create mode 100644 src/cloudflare/types/zero_trust/gateway/dns_destination_ip_list_response.py rename src/cloudflare/types/{tenants/account_type_list_response.py => zero_trust/gateway/dns_destination_ips_id.py} (62%) create mode 100644 src/cloudflare/types/zero_trust/identity_providers/scim/group_get_response.py delete mode 100644 src/cloudflare/types/zones/automatic_platform_optimization.py delete mode 100644 tests/api_resources/accounts/test_pay_bad_debt.py rename tests/api_resources/{magic_cloud_networking => billing/spend_policies}/__init__.py (100%) create mode 100644 tests/api_resources/billing/spend_policies/test_activity.py create mode 100644 tests/api_resources/billing/spend_policies/test_audit.py create mode 100644 tests/api_resources/billing/test_spend_policies.py delete mode 100644 tests/api_resources/browser_rendering/devtools/browser/test_page.py create mode 100644 tests/api_resources/dns/settings/account/test_nameserver_sets.py rename tests/api_resources/{magic_cloud_networking/catalog_syncs => k2}/__init__.py (100%) rename tests/api_resources/{magic_cloud_networking/on_ramps => k2/streams}/__init__.py (100%) create mode 100644 tests/api_resources/k2/streams/test_subscriptions.py create mode 100644 tests/api_resources/k2/test_streams.py delete mode 100644 tests/api_resources/magic_cloud_networking/catalog_syncs/test_prebuilt_policies.py delete mode 100644 tests/api_resources/magic_cloud_networking/on_ramps/test_address_spaces.py delete mode 100644 tests/api_resources/magic_cloud_networking/test_catalog_syncs.py delete mode 100644 tests/api_resources/magic_cloud_networking/test_cloud_integrations.py delete mode 100644 tests/api_resources/magic_cloud_networking/test_on_ramps.py delete mode 100644 tests/api_resources/magic_cloud_networking/test_resources.py create mode 100644 tests/api_resources/monetization/__init__.py create mode 100644 tests/api_resources/monetization/test_rules.py create mode 100644 tests/api_resources/r2/buckets/test_jobs.py delete mode 100644 tests/api_resources/registrar/test_domains.py delete mode 100644 tests/api_resources/tenants/test_account_types.py delete mode 100644 tests/api_resources/tenants/test_entitlements.py delete mode 100644 tests/api_resources/test_tenant_custom_nameservers.py delete mode 100644 tests/api_resources/test_tenants.py create mode 100644 tests/api_resources/zero_trust/access/logs/test_jit_requests.py create mode 100644 tests/api_resources/zero_trust/access/mfa/__init__.py create mode 100644 tests/api_resources/zero_trust/access/mfa/test_authenticator_catalog.py create mode 100644 tests/api_resources/zero_trust/access/test_user_populations.py create mode 100644 tests/api_resources/zero_trust/access/user_populations/__init__.py create mode 100644 tests/api_resources/zero_trust/access/user_populations/test_users.py create mode 100644 tests/api_resources/zero_trust/access/users/test_mfa_authenticators.py create mode 100644 tests/api_resources/zero_trust/access/users/test_passkeys.py create mode 100644 tests/api_resources/zero_trust/casb/posture/test_asset_schemas.py create mode 100644 tests/api_resources/zero_trust/cws/__init__.py create mode 100644 tests/api_resources/zero_trust/cws/basic_auth_credentials/__init__.py create mode 100644 tests/api_resources/zero_trust/cws/basic_auth_credentials/test_secrets.py create mode 100644 tests/api_resources/zero_trust/cws/tenant_structures/__init__.py create mode 100644 tests/api_resources/zero_trust/cws/tenant_structures/test_nodes.py create mode 100644 tests/api_resources/zero_trust/cws/test_basic_auth_credentials.py create mode 100644 tests/api_resources/zero_trust/cws/test_deployments.py create mode 100644 tests/api_resources/zero_trust/cws/test_domain_acls.py create mode 100644 tests/api_resources/zero_trust/cws/test_policies.py create mode 100644 tests/api_resources/zero_trust/cws/test_policy_sets.py create mode 100644 tests/api_resources/zero_trust/cws/test_rego_metadata.py create mode 100644 tests/api_resources/zero_trust/cws/test_rego_modules.py create mode 100644 tests/api_resources/zero_trust/cws/test_tenant_structures.py create mode 100644 tests/api_resources/zero_trust/cws/test_workloads.py create mode 100644 tests/api_resources/zero_trust/dlp/test_validators.py create mode 100644 tests/api_resources/zero_trust/dlp/validators/__init__.py create mode 100644 tests/api_resources/zero_trust/dlp/validators/test_proximity_words.py rename tests/api_resources/{tenants/test_memberships.py => zero_trust/gateway/test_dns_destination_ips.py} (50%) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 890a5a1b77e..159cbfa3ad4 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -21,6 +21,13 @@ workflow: lint: stage: lint timeout: 20 minutes + # pyright peaks ~5.3GB RSS; default linux-x86-2cpu-4gb Pod runner OOMs. Bump to + # 8GB per Codex RFC 023 (gitlab-ci-runner-selection): Pod runner, one tag, + # below the 8cpu-16gb evidence threshold. + tags: + - linux-x86-4cpu-8gb + variables: + NODE_OPTIONS: "--max-old-space-size=6144" rules: - if: $CI_COMMIT_TITLE == "codegen metadata" when: never diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 09242e06fa9..028d2d67279 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "5.9.0" + ".": "5.10.0" } diff --git a/.stats.yml b/.stats.yml index 585a53fe6c4..e44abad49fc 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1 +1 @@ -configured_endpoints: 2718 +configured_endpoints: 2790 diff --git a/CHANGELOG.md b/CHANGELOG.md index 236bcfaa933..12766ff6005 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,113 @@ # Changelog +## 5.10.0 (2026-11-05) + +Full Changelog: [v5.9.0...v5.10.0](https://github.com/cloudflare/cloudflare-python/compare/v5.9.0...v5.10.0) + +This release adds the K2 streaming, Monetization, Zero Trust CWS, and Billing +Spend Policies APIs, plus Zero Trust Access user populations and MFA catalog +resources. It also removes the Magic Cloud Networking and Tenant Custom +Nameservers resources and changes several pagination and response types. Review +the breaking changes before upgrading. + +See the [v5.10.0 Migration Guide](./docs/migration-guides/v5.10.0-migration-guide.md) for upgrade examples. + +### Breaking Changes + +* **magic_cloud_networking:** `client.magic_cloud_networking` has been removed entirely, including the `catalog_syncs` + (and `prebuilt_policies`), `on_ramps` (and `address_spaces`), `cloud_integrations`, and `resources` sub-resources + and all `cloudflare.types.magic_cloud_networking` exports. +* **tenant_custom_nameservers:** `client.tenant_custom_nameservers` has been removed, along with its `create()`, + `delete()`, and `get()` methods and the `TenantCustomNameserverCreateResponse`, `TenantCustomNameserverDeleteResponse`, + and `TenantCustomNameserverGetResponse` types. +* **tenants:** `client.tenants.get()` has been removed, along with the `account_types`, `entitlements`, and + `memberships` sub-resources and the `Tenant` and `TenantAccount` types. `client.tenants.accounts.list()` now returns + `SyncV4PagePaginationArray[AccountListResponse]` instead of `SyncSinglePage[TenantAccount]`. +* **user:** `client.user.tenants.list()` now returns `SyncSinglePage[TenantListResponse]` instead of + `SyncSinglePage[Organization]`, and the `Organization` type was removed from `cloudflare.types.user`. +* **accounts:** the `client.accounts.pay_bad_debt` sub-resource has been removed. `client.accounts.subscriptions.bulk.create()` + now returns `BulkCreateResponse` instead of `Optional[BulkCreateResponse]`. +* **registrar:** the `client.registrar.domains` sub-resource has been removed. +* **browser_rendering:** `client.browser_rendering.devtools.browser.connect()` and `launch()` have been removed, along + with the `devtools.browser.page` sub-resource. +* **aisearch:** the instance path identifier was renamed from `name` to `namespace` across every + `client.aisearch.namespaces.instances` method and its `items` and `jobs` sub-resources. Callers passing `name=` must + switch to `namespace=`. +* **rulesets:** `client.rulesets.list()` is no longer paginated and now returns `RulesetListResponse` directly (was + `SyncCursorPagination[RulesetListResponse]`). `client.rulesets.versions.list()` and + `client.rulesets.phases.versions.list()` likewise now return `VersionListResponse` instead of + `SyncSinglePage[VersionListResponse]`. +* **pagination:** `client.zero_trust.resource_library.applications.list()` and `categories.list()` now return + `SyncCursorPaginationAfter` instead of `SyncSinglePage`. `client.diagnostics.endpoint_healthchecks.list()` now returns + `SyncSinglePage[EndpointHealthcheckListResponse]` instead of `Optional[EndpointHealthcheckListResponse]`. +* **vectorize:** `client.vectorize.indexes.get_by_ids()` now uses `GET` and returns + `SyncSinglePage[IndexGetByIDsResponse]` instead of issuing `POST` and returning `object`. +* **response models:** `client.zero_trust.access.users.last_seen_identity.get()` now returns + `Optional[LastSeenIdentityGetResponse]` and the `Identity` type was removed. + `client.workers_for_platforms.dispatch.namespaces.scripts.tags.delete()` now returns `TagDeleteResponse` instead of + `object`. +* **removed types:** the shared `LoadBalancerPreview` type was removed, along with + `magic_transit.WANStaticAddressingParam`, `organizations.OrganizationProfileParam`, and + `precursor.EnforcementRuleParam`. + +### Features + +* **k2:** add top-level `client.k2` with `streams` and `streams.subscriptions` APIs +* **monetization:** add top-level `client.monetization` with zone-level monetization `rules` APIs +* **zero_trust:** add `client.zero_trust.cws` with `basic_auth_credentials` (and `secrets`), `deployments`, + `domain_acls`, `policies`, `policy_sets`, `rego_metadata`, `rego_modules`, `tenant_structures` (and `nodes`), and + `workloads` APIs +* **billing:** add `client.billing.spend_policies` with `create()`, `update()`, `list()`, `delete()`, and `get()`, + plus `activity` and `audit` listing sub-resources +* **zero_trust:** add `client.zero_trust.access.user_populations` (and its `users` sub-resource) with full CRUD +* **zero_trust:** add `client.zero_trust.access.mfa.authenticator_catalog` and `client.zero_trust.access.logs.jit_requests` +* **zero_trust:** add `mfa_authenticators` and `passkeys` delete sub-resources to `client.zero_trust.access.users` +* **zero_trust:** add `client.zero_trust.casb.posture.asset_schemas`; add `create()`, `update()`, `delete()`, and + `validate()` to `client.zero_trust.casb.posture.finding_types` +* **zero_trust:** add `client.zero_trust.dlp.validators` (and its `proximity_words` sub-resource) +* **zero_trust:** add `client.zero_trust.gateway.dns_destination_ips` +* **zero_trust:** add `delete()` and `get()` to `client.zero_trust.identity_providers.scim.groups` and `scim.users` +* **dns:** add `client.dns.settings.account.nameserver_sets` with `create()`, `list()`, `delete()`, and `get()` +* **r2:** add `client.r2.buckets.jobs` with `create()`, `list()`, and `get()` +* **aisearch:** add `client.aisearch.namespaces.instances.move()` +* **api_gateway:** add `client.api_gateway.discovery.operations.edit()` +* **d1:** add `client.d1.database.undelete()` +* **workers:** add `client.workers.beta.workers.versions.profile()` +* **zero_trust:** add `client.zero_trust.access.custom_pages.validate()` + +#### New Resources + +**K2** (`client.k2`) + +- `streams.create()`, `streams.update()`, `streams.list()`, `streams.delete()`, and `streams.get()` +- `streams.subscriptions.list()` + +**Monetization** (`client.monetization`) + +- `rules.update()`, `rules.delete()`, `rules.delete_rule()`, `rules.edit_rule()`, `rules.get()`, and `rules.get_rule()` + +**Zero Trust CWS** (`client.zero_trust.cws`) + +- `basic_auth_credentials.create()`, `list()`, `delete()`, `get()`, and `basic_auth_credentials.secrets.*` +- `deployments.create()`, `update()`, `list()`, `delete()`, and `get()` +- `domain_acls.create()`, `update()`, `list()`, `delete()`, and `get()` +- `policies.create()`, `update()`, `list()`, `delete()`, and `get()` +- `policy_sets.create()`, `update()`, `list()`, `delete()`, and `get()` +- `rego_metadata.create()`, `update()`, `list()`, `delete()`, and `get()` +- `rego_modules.create()`, `update()`, `list()`, `delete()`, and `get()` +- `tenant_structures.create()`, `update()`, `list()`, `delete()`, `get()`, and `tenant_structures.nodes.*` +- `workloads.create()`, `update()`, `list()`, `delete()`, and `get()` + +**Billing Spend Policies** (`client.billing.spend_policies`) + +- `create()`, `update()`, `list()`, `delete()`, and `get()` +- `activity.list()` and `audit.list()` + +**Zero Trust Access User Populations** (`client.zero_trust.access.user_populations`) + +- `create()`, `update()`, `list()`, `delete()`, and `get()` +- `users.create()`, `users.update()`, `users.list()`, `users.delete()`, `users.get()`, and `users.replace()` + ## 5.9.0 (2026-10-02) Full Changelog: [v5.8.0...v5.9.0](https://github.com/cloudflare/cloudflare-python/compare/v5.8.0...v5.9.0) diff --git a/api.md b/api.md index cf1a6ae6e82..dabfbd45513 100644 --- a/api.md +++ b/api.md @@ -9,7 +9,6 @@ from cloudflare.types import ( CloudflareTunnel, ErrorData, Identifier, - LoadBalancerPreview, Member, PaginationInfo, Permission, @@ -195,7 +194,7 @@ Methods: # [MagicNetworkMonitoring](src/cloudflare/resources/magic_network_monitoring/api.md) -# [MagicCloudNetworking](src/cloudflare/resources/magic_cloud_networking/api.md) +# [Monetization](src/cloudflare/resources/monetization/api.md) # [NetworkInterconnects](src/cloudflare/resources/network_interconnects/api.md) @@ -319,6 +318,8 @@ Methods: # [Pipelines](src/cloudflare/resources/pipelines/api.md) +# [K2](src/cloudflare/resources/k2/api.md) + # [SchemaValidation](src/cloudflare/resources/schema_validation/api.md) # [TokenValidation](src/cloudflare/resources/token_validation/api.md) diff --git a/docs/migration-guides/v5.10.0-migration-guide.md b/docs/migration-guides/v5.10.0-migration-guide.md new file mode 100644 index 00000000000..a68e8e4c642 --- /dev/null +++ b/docs/migration-guides/v5.10.0-migration-guide.md @@ -0,0 +1,187 @@ +# Migration Guide: v5.9.0 to v5.10.0 + +This guide covers user-visible breaking changes in Cloudflare Python SDK v5.10.0. + +## Removed Magic Cloud Networking + +`client.magic_cloud_networking` has been removed entirely. Remove all usage of its sub-resources +(`catalog_syncs` and `catalog_syncs.prebuilt_policies`, `on_ramps` and `on_ramps.address_spaces`, +`cloud_integrations`, and `resources`) and drop any imports from `cloudflare.types.magic_cloud_networking`. +There is no drop-in replacement; these endpoints are no longer exposed by the SDK. + +Before: + +```python +syncs = client.magic_cloud_networking.catalog_syncs.list(account_id="account-id") +``` + +After: + +```python +# No equivalent; remove the call and any magic_cloud_networking imports. +``` + +## Removed Tenant Custom Nameservers + +`client.tenant_custom_nameservers` has been removed, along with its `create()`, `delete()`, and `get()` methods +and the `TenantCustomNameserverCreateResponse`, `TenantCustomNameserverDeleteResponse`, and +`TenantCustomNameserverGetResponse` types. + +Before: + +```python +client.tenant_custom_nameservers.get("tenant-tag") +``` + +After: + +```python +# No equivalent; remove the call and any tenant_custom_nameservers imports. +``` + +## Tenants resource + +`client.tenants.get()` has been removed, along with the `account_types`, `entitlements`, and `memberships` +sub-resources and the `Tenant` and `TenantAccount` types. `client.tenants.accounts.list()` now returns +`SyncV4PagePaginationArray[AccountListResponse]` instead of `SyncSinglePage[TenantAccount]`. + +Before: + +```python +from cloudflare.types.tenants import TenantAccount + +accounts: list[TenantAccount] = list(client.tenants.accounts.list()) +``` + +After: + +```python +from cloudflare.types.tenants import AccountListResponse + +accounts: list[AccountListResponse] = list(client.tenants.accounts.list()) +``` + +## User tenants listing + +`client.user.tenants.list()` now returns `SyncSinglePage[TenantListResponse]` instead of +`SyncSinglePage[Organization]`. The `Organization` export was removed from `cloudflare.types.user`. + +Before: + +```python +from cloudflare.types.user import Organization + +orgs: list[Organization] = list(client.user.tenants.list()) +``` + +After: + +```python +from cloudflare.types.user import TenantListResponse + +tenants: list[TenantListResponse] = list(client.user.tenants.list()) +``` + +## Accounts + +The `client.accounts.pay_bad_debt` sub-resource has been removed. Remove any calls to it. + +`client.accounts.subscriptions.bulk.create()` now returns `BulkCreateResponse` directly instead of +`Optional[BulkCreateResponse]`; callers no longer need to handle `None`. + +## Registrar domains + +The `client.registrar.domains` sub-resource has been removed. Use the top-level registrar methods instead. + +## Browser Rendering DevTools + +`client.browser_rendering.devtools.browser.connect()` and `launch()` have been removed, along with the +`devtools.browser.page` sub-resource. Remove these calls; the remaining DevTools endpoints are unaffected. + +## AI Search instance identifier + +The AI Search instance path identifier was renamed from `name` to `namespace` across every +`client.aisearch.namespaces.instances` method and its `items` and `jobs` sub-resources. + +Before: + +```python +client.aisearch.namespaces.instances.list( + name="my-namespace", + account_id="account-id", +) +``` + +After: + +```python +client.aisearch.namespaces.instances.list( + namespace="my-namespace", + account_id="account-id", +) +``` + +A new `move()` method is also available to move an instance between namespaces. + +## Rulesets pagination removed + +`client.rulesets.list()` is no longer paginated and now returns `RulesetListResponse` directly instead of +`SyncCursorPagination[RulesetListResponse]`. `client.rulesets.versions.list()` and +`client.rulesets.phases.versions.list()` now return `VersionListResponse` instead of +`SyncSinglePage[VersionListResponse]`. Stop iterating these as pages and read the returned object directly. + +Before: + +```python +for ruleset in client.rulesets.list(zone_id="zone-id"): + print(ruleset.id) +``` + +After: + +```python +rulesets = client.rulesets.list(zone_id="zone-id") +for ruleset in rulesets.result: + print(ruleset.id) +``` + +## Additional pagination changes + +- `client.zero_trust.resource_library.applications.list()` and `categories.list()` now return + `SyncCursorPaginationAfter` instead of `SyncSinglePage`. +- `client.diagnostics.endpoint_healthchecks.list()` now returns + `SyncSinglePage[EndpointHealthcheckListResponse]` instead of `Optional[EndpointHealthcheckListResponse]`. + +## Vectorize get_by_ids + +`client.vectorize.indexes.get_by_ids()` now issues a `GET` request and returns +`SyncSinglePage[IndexGetByIDsResponse]` instead of issuing `POST` and returning `object`. Iterate the paged +result instead of inspecting a raw object. + +## Response type replacements + +- `client.zero_trust.access.users.last_seen_identity.get()` now returns `Optional[LastSeenIdentityGetResponse]`; + the `Identity` type was removed. +- `client.workers_for_platforms.dispatch.namespaces.scripts.tags.delete()` now returns `TagDeleteResponse` + instead of `object`. + +## Removed exports + +Remove or replace imports of: + +- `cloudflare.types.shared.LoadBalancerPreview` +- `cloudflare.types.magic_transit.WANStaticAddressingParam` +- `cloudflare.types.organizations.OrganizationProfileParam` +- `cloudflare.types.precursor.EnforcementRuleParam` + +## Summary + +1. Remove all `magic_cloud_networking` and `tenant_custom_nameservers` usage and imports. +2. Update Tenants and User tenant listings to the new response types and paginators. +3. Remove the `accounts.pay_bad_debt`, `registrar.domains`, and `browser_rendering.devtools.browser.page` + sub-resources and the removed DevTools methods. +4. Rename AI Search `name=` arguments to `namespace=`. +5. Stop paginating `rulesets.list()`, `rulesets.versions.list()`, and `rulesets.phases.versions.list()`. +6. Update changed pagination, verb, and response annotations for Resource Library, diagnostics, Vectorize, + last-seen identity, and dispatch script tags. +7. Replace renamed or removed exported types. diff --git a/pyproject.toml b/pyproject.toml index 5738f2222c5..dc387453fa9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "cloudflare" -version = "5.9.0" +version = "5.10.0" description = "The official Python library for the cloudflare API" dynamic = ["readme"] license = "Apache-2.0" @@ -56,7 +56,7 @@ conflicts = [ [dependency-groups] # version pins are in uv.lock dev = [ - "pyright==1.1.399", + "pyright[nodejs]==1.1.399", "mypy==1.17", "respx", "pytest", diff --git a/requirements-dev.lock b/requirements-dev.lock index 444b5b6e445..5b7f1e2fe0d 100644 --- a/requirements-dev.lock +++ b/requirements-dev.lock @@ -56,6 +56,8 @@ mypy-extensions==1.1.0 # via mypy nodeenv==1.10.0 # via pyright +nodejs-wheel-binaries==24.19.0 + # via pyright packaging==25.0 # via pytest pathspec==1.0.3 diff --git a/scripts/mock b/scripts/mock index 0ca780cca6d..c147f1d3242 100755 --- a/scripts/mock +++ b/scripts/mock @@ -16,7 +16,7 @@ elif [ -n "$STAINLESS_OPENAPI_SPEC_URL" ]; then URL="$STAINLESS_OPENAPI_SPEC_URL" else # Embedded OpenAPI spec (base64-encoded, gzipped) - EMBEDDED_SPEC="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2WZtzj43w7tthntTm92hVV1qlUuDwqx693R5pT83R1OpXbqrXZfvStXhsFYuXVzUZyprXbAfdv/p+emGlZ+fLKGT716yk8qYf9F4E1jK4vNCFW60R+miOoHvJT1/DtiilLv+zJX6hYx0tTg/nWfO5beni8cHEeQvJjWblTsZe3h3+6K1VEP4NEZycX71zF49XylPY+vy4hS8Czct4TpTF3usPus/3y7errvqqGVd3kt6Z5KtXJpvpVa533jRutNqofN42mO52ac+P78TT1VNa2s3KniYfNgFqN9AbSHOryYcKPavP5v30/b5dUmSTjlhquj1D9SLWefBGutSuWQW7jpFTbCn4kR5mnYL8MmG1cpDqyUMpvVBeQSqz5l2sSlai+4o053U5bvqaPaiPYlvLd6YPyqL68a8LJR1NX/XmwqfF8og/2wVivUO7J23ywvB+ATme/XyKXudm4+f/nrRsJistasRojOJFuA9SvGbCv7wT0j4H1rwc1ktP5Dno44VFvzlu0jBr973DiH472atz9q81XtftHr97AP9rV2tzdzfogT/ff/zxwn+6UfGvDIvJlC2Ly+U8c3V6WB6J1+ZzcJnocRmW8+LxfWEP++cN2qF+lt7ejp6v3/iHu5etOvmotdu313kK5dQqnGa2BvohadsrpufnxujeSV3Xr0stJq2Cib1W003PoTcVT+36MyVFtu6y7RfNK13eaFelHj989kCuadyeXA/GF08qFydbQ7a4mPl+mramD08tMTKXMjcDB5yV713saPVcsP6w5V986INujfZEW9ne+Dh3u42P8vTJzN//wly49Oh9VSaXpUu73mt+3wKu7X6bVXni5Ju3CwKpyO7dtO/Lrxo2XppJpTrt6bB9VRDbdzWFUu27/oXDaN7nTff37lat/EJWEvPiDeWoctXUOHNoviebT2O8+rzi/bRPH14vnwUnu3i6fjzeSQVJ5V7pWCcf6iP9krB35mC6eD0RTMfWkJzdqVcFB+LM26q5rT+fWdJ8JO3o9590Toxgv/+vrV3we/fbQkEf90V/OUn/vmzDB5YuWWWSr28dXv5adw/3H/ezXNXfeFF69fK17bcVB9u1ffSrKc125WHznkBtt8qlXGjJIxgX74Yg095cgsKnc/ZzVhi2z2ufffx2V28W9aLNu19iIJyUc2fFgbF1sdl8bxumpVBz/owzu9M63zUuBAexvKAq12e5+ofT6WSmFU66u3QHNWf5/3Ci2Y/WqXC6EHLDa5ysNmtFi/KslSq9/T+9Kr9zJWb1dvpqDgoZpsaLAAjt2jI2Vyv3zYuOgV4UTZftFp3/pmV5fvOuf7QWZjty1PQKC2ePi66he65ZY0reUN4rJQuPh4n1vvFbaXR+XgvjUwLGk8jWWgWXrRzqfwJ3/q62K68vV3UReu9dH3efZs/31w/nE7a78+zAXySWwXl9r2aFfo24Ka8Jc9WCf4NxX4mWuzjSLxKKXj705jbWouGpaYZZPOIes9kUEgfSiCcWFD+PwNnAj4kwldH8gGKAKbw2uvQf9YeHPJbpVJSc97Bcau1hmzdPD0vs5E3hro5T6fT+zxOhehxvTGUIeIwCYxYmnmgOGQanKmKBlNQQ97bHYehMq1WKiVwVyndlWby57K8qPZK11RetMr1e/bpYTivfqLzhMgJqVV+n0/EcWcqvtUeWuU7cjYNZ+1OQ9VAv61K2t2w+5B9u36rdVolenbNZk30/MV5Y37RK4mknlar3rgXnh64mdjo28+olAf8jv3EF63wefaiRZ1oznlWOO3pefmUf799gOXpuW70M9f34uWsanTvRHgFxpWx/qLNJlnxozpvzu559vOjI+ZLt/2bqyf9vlav39TuzFwvN2yOtaaujkTlIjcWPofP55Xb6UP55v1ZOpVeNO5W52vjafnztFTNmmW5l33/bNyVcm3xYfHcUOV5xxq1r29MDg5uRrL2ULdHTS7Hf4ylgTqcKM0X7aFqzz6ESnFw+vQOL0dtrSjXs6f6bFyQbu7GVeO+0G7LSu9D0QofmY+n0sXFZeeBLwzVy37l+b33/KLNmqDbyUlG+a7QE5/aNVaWTisAZKo3zfdPrnZjXjx89uanGvt5NfiQxOGjIlQv56cVTnybWE+3nRetfPt8XaiW4INdKkDRlu97grCoTQp8o5g7bwylQb6eycxbc8gupNNHkNNn9DwrlbCcf9GiJT37Lhl1SeqO69XxXJ+zbchy/eZH16x+XAyvTx/HF73Hy5kBc9UXbXTZfZ6J05p1c8U2MqeyIdRNjnuw+20r+yFdm/MsKNjvQiNXurpofdqja/My//j8NhzfPTZqlcnTi3YnjCuZRS/zrFcak+ajODtVbjPquFZ7HIK7a7Y3z17X1XP9/Uq8epo1P9rK4urhpvWWf+6cz+YPw/MX7bna6JjZ7NzW4XX18vy5Ux8UxeZpE1T6MvdkDJ6ki6aaaRTypempIRSf7mcfnWqPva/e5+3r4Yf2ovHFxyZ3O7nvtyu3dw2tODmHj7k7PT+dVMHtQuxYJb6Tf7y+ersD9aL++AAr/Y8FN5peAql4V0cXyGL+RuSAOrm41Z/z4welZl/O3sq3ipIDxVaxkWG1vp4pqmWFWy3pI2zPG0io7EqFf4V972jDOdpwjjacow3naMM5vA0nhiMMiW4N6eGq8glfqdbooFpsdgzEgPc6Lx/PgOMZcDwDjmfA8Qz4F58B+egzgGKkBjzVtdaOp8AYGSX0SjqdlkfVau1g95tXoAF18XkAFuT/XtTx8tDtObAzMG9OeE7MooyM5MHwFASKwDTtDfH7h7o+DCB6y8pQQV8j+G7nmQot04HtRqFMJooYHm+ZXxfZ3ygXXHRvTYgi6aHsxsGRcCWGQTRCKEIcWWhxmrWG45MDbjqvFAdBz+UcQjF0aHxwlL7J/I8JKSwEDqkehDiK/v7dpVRDPE9oJ5lhMjXTVM8xdRFiGTj3yxynHQpc5ycMjbwzSV85MzFW8hVrkYSNh+guTJdwAq9SFCxj6PZwtOHy/MqeR9ixo3vtUGh4+2/5+FgPa0UipVYgVOQKYk7MC6m8yEopIZ/NpgoFgU0JMCMWJF4AMhTXcEHFF17xEAkccpRKCS97mpgez/y0YVZxBDJqOOUXJxggSEZGQXkN7iglwDiNE6Z7yov2CyyEyOT7KqJjKOw2lNJMkxiwXAnkNu8zG2Epx94f4/YPxv5yZpuEjqLVsGOVESUijElp+ipDFQ6dhChJN+SIoapW7pmq+x5D38Prj5KYU3qaIBbaPgfNq4A2kyTZhZQw9P6uNeEyyALaOeR+aaqD8fYTQxkDYxEOctwlPJuUuO8I7Sz2MVJggB2KQ0WQofXNp6fchlZdeGkx5E1yjGHMHRFCvByhMvWImqJ1it8rpT9Wrc2gpFoBFL204kmzVp+U3Vrnvl5qXjOqrr+jUG57wlRKVIRPJmn6JtJM4gDdltVc3xgmi9hOvsdoecFKYuWD7yA1f/OPDP3i62SC02DFWrzKYLGXGtyyItMJcL8cyRM6c9xNuOFFY+lUWF6GGqNosjJVZIQL5F/xNKkRrELqiDmel6L/47Ur8ipDXl299G1R+bAVS8fpFdGpLBNEdbM66SiA0YZgu9CP3u6mZWyVfcQLCQkTh1B/9V9DlpvbxReXBU1ZRdCgKGPBgAQsdGIoU9T+d7hwAOZHUJUZVUdX4sX6CVKBSFJkVoy26VPHyR82JaOFmIZXsrHSFc1Y4z9Cgz27cBYqIyFkRUfaKmZSgrMQdH0ggyko/f4MSMOYK0PyzIvVqzMP82JBhiIoZDMFMMjxWcSAlxf5bIZlM4IUsxTwXSKCDq8Xe/7gQ8u9XG1gA7iG1m8mU3PvUlHNSZa4FxATh0vcW2pgVCaaoaywpGCjwbnzDtLJPcDCoKzzSBKTYnpiTD3LjqI69lOvYWpIfHN0M/qSTlitUu2WHhRrRDA149oRh2Hr65+ZAMQWSBhcOgZubqLqQN50XThfoUuzd/M84AL55+zkEyMC76rB+NXrqMPaOaV3OJZ9VUQuIILl78/8wjoeEy5o9axmCjw/GBTZFAR8MSUI8iBVhNlsiucyLCuKRYEriglzZDft4IetW+Bomz6EbXoJKt3BQtutp3jGTvaOxrS0Mo6AKUfAlCNgyn8BMGXJLPx1suWIM/rvxhn1l388UI4HyvFA+U8cKJgl1f/GQY+UCMFCYhiOouUoWo6i5d8lWvwel68WKpmjUDkKlaNQ+dcJFWSOxoGAqG3oBTml4wTp1MRW1S8XM8JRzBzFzFHM/OvEjO8RgQ1GwVFfLFuyR9lylC0/iWzJ/gDZwq0VLD5R4lWYeMR+gBDJfI0QUVBcgbo4yo8Duoh3D0HGlrdY0O8vWShHn84P9ulEWV+/atqPhtefwpm3HL58wCk/msV+2JSvtVx82SI4Gi1+hn3vu1d+2cwfr5T7VQn3fjn4qpXwOqH8N8fF8FMuhlvMLXTI5TDV34NAF8GZ/7JrEDkDXyWwgv6ItFZ+BbuKX19B5IIVyt3baAxjEwWoVYc8DyUyJ8wZcBKFFE2xFATXQt6kWSvOX+7bOMkKxdGjPBby0FLGijZ81W08ZxCnFr/KcKLqizHUrN0z/pPSqe0vh9b3iCS+BhPUdiEGcwtKCXvJL8ZZE0CfrFjUXqbSLnkVpJBw+swuicVuOXtOVS6cLOe97FCqryTHNr+F7vWDVm/uUKs3u5fV6/zri1cwNBSgvlJT7c7si76yfoXtUTzc9shsuT0SGAsIKdguuwJEAYLsybJCEA0Osc/2g0IxttRVrI973F+kwdp+WBlJYQfbrrT4Q2zYfSFlZA63WYXtNuttovvccbset+t/d7vKmCh050ukV1BKiAKc/EnkgplAHBxEucU3KMncdZGhEg4kDjIOAzR+sidl2dyLjElmDsHhJ6972B6Boryioewi7OynAn+BYbOWN4Bk2US2ItTrzcxdZhxVnQuoEEFKtB/QWge6vH/Vuyk9t9+kx/vnzpug31ls98JUOYmbtpZglF+08l1p1o/g66q/lfoO/071vj0SlXJDGtftJ179fOILLgA04eKpvLdHYkMdi5lLGzzU5vVeqUe+1lvVmsuqQ/l4SsP6jF203mrz1ltz/qK13/rZdlUGjVJhQYDNS4ubXo1v997ZNqevbd+LtqqFSdr3ogVbWKmUus3waJUp6PRtCY34nV7BANStjnTTmQ1ftMt6T5Ya53zjqnkq1Z+Um3K7evVWee4/1m6mjw9PAl9+vyjO5kqrV8gVKzenUCtxs+ykaTzqs9x75UVrceadObm4APfjy76qW7XW5XyhX9cHpfPClcXVruoLXbx5s59Nvjtb3C8uebNrTe/s/l1NN/vXzy9apd14rn3oF9lh7nPUup2D+Tj/fG0YZvW5OAbtxv2Hnq89XD9cGM/Z/N15tmX1DHF+d30KH9/648vii3aVee+eZuzarCV/dHLPmbJq9zllCrTJrcRV2nyjPZJv2PNR90l4em/UNPva/LhcVOWM1FTKXGv+otmV8qXwDD5uZH6q3HMP0m1G72fk+f3tWGg9LAZPTVVuPZQ5oQ5GXWl+PXqQO1qr+PR8rhSbden6RVtMHk37M199My5vrdt+pTSrlUqgPW4hUHwEcd9hb8rlp1r9Nnv5ed0Hs3b9VMqUHs2nXu3hYpR/0T556ZMC3MvN2d1TqwxKcW/jd0sCgVCf1crns7vai4Z2U/mt1MVw6R0MQl6rVEuN0t3FeWlYK0eRApSEZrl0V5ZOyzD/orWro0mNLS7yo+vb50bnVuWk7lV5JnSa7GNzmjNUsdurm9kaFCe9xttofj4bteez2vOoXLx4znPci8bdAO5J7RXm781i1RyV84XxW+miclUuXeZzY/2qYL03WPAhP00uhWfpsndfLufVYqEzHUr5z0FPedGU/AMc9xZ5XoZlsQuVmvUIpmOhVmfHD28Xo7tsez7RJixb/tCyQ25eqCx61cVkOLaHGpyczhsv2qlS/2yPe7L5mX9oFnvn+fdq6/GjnG+d128fyjedRbdYuLn8aFfNWeW6XhCbz0+zfrkGT8XORV1HLFfdUesTVDLWVBnnHyoil9P06nu311IHVzfCRJtejSbSvdwdziTDLvXu84vTh9Pr6fiTv+mdN2xFeNEuRx9Q78GZOdfW4nInENcY+jUMrvYj9Jd86IpzYERUoi7p47Guve5B4/eXhAu2NcvYueW0lH0pdge56WGF+5+zk4GiDaExMRTNejVHACE97VZ8RIF7wSBdWvFRF8o9XCO8cv45O0GYdk4+/w5lusX8c3aiG0OgKZ/7KDZQVKhooL7amrLr7S2qxINejzMHuR7TYt+VXQt8VxxL9s5tw2Xs2SzOcSeHhA5N6jpauVWXPcDLLBg9MFx5n2DlQlHKs3IKyMVBSigImZRYLA5SOUli+SzP5vKwiPz9YH4NtaE1OvmWyZ2djBXN/+c+UMeWe3oEAzlmpvy8mSnHrLc9Jqws6+B7T0NYIV+O2Qg/ODg1avr3PPuRBArRI6QbmOHb0hkgyz68U6ZMP13isukh2GOMPYu+AIxpixQUXh8wpqb4qGZMU0UoxgwwCfEIvjUxbURfqAzQbkT1otFdPRkDoJpbHrTBG19I/Pqag6THOmqUlcwke4Ij1bWBMjyQ4HEDTvA78quiTWwS/5jwYhoxgvjBGaJBmSqyR0JQ6XZWD1y/u6cBM6DP3xQ+HBSTUcjSQ+C8+B/Op1ga0K+3w01nUyyfYnM9rvCN477xmXQ2wxWL2TiI38QdiTajR3RlAFRVRIw0xJ2xc4+4YopjU3zB61EmL3Dc7h2KYWnCHZnFwTDv0BOOZSNwl/e62qL4lyInyVJNJOgsJElRt8hcIcB7p4dUwCqmuza3W4+ZFJtPcWwPdZj7lmXTPFfk8ltPnxmD8Oy/b3WVoYY61iEKMfN7pdv5I820bNNCwOSU+zAFNUmXo6dyna+H6dTu+rVuz/P5VOaflUoJFCqlu9KsW13pHemFfSMvGvKOOOS15ZLUK723y63O3aw2xPSx1drMUmGjbkmNuXqNKGqrQX/Ii7bSI3I9h2+WLYinb7dyHdaV3E3fXMBC7+nyrjzOPAwq0+sX7cLO1qbKW+vmXHjme83xrNQVZ/16vmkUbq6HF6fjhnr3DD8W7WlD7960auD5/lF6Gkw63Ei9B++FF01oNO6NU1ZoNgY3lQ9Q1t9Bud6cfUpq41n8vBpfN2bNO0VvzxuDj/o412k8NUoZEfKXkFdMWJZetHahcc/NnsbTpxrb6ZwuHmbwstK75LJ5OF90Pu28eT8HtYdivZD/LN9dL2602aOUE4yB+miqnQ/lRRvm6/lZtgnunm7UwmI6fj9/q91WSiOQH7wr/UFt8ia0Of5Uv+0orakKL+vFgjSav1WF1kWmKGWbL5p9Y6r965HxYGuDUb5R5t5mD+1ScSEIF6ypGYPT+VRf8D3pYjyfjkGxpmoF6g8p5VrVYeNF83khLqtvNaNVeZ9dzrCXpFOulGYXevP6+XE0Eh/L5nM3az8/divVjJyRF1k8yy+aN89hgl+TEvzWSlIZPObkG61Z0KRSx2gWn7t1vnT5eFoYz1+0Se/iiT994ivs/dS4rzZalljuXBQ6xUVL/Hiw1DmE7cbg/Pwatt67V906EN7FiTzn+Zw6sJXC+YsG7E613LtszPkOJ0n9+fj6+XEujBfsQ1Zptua2Zp++w8/TclW182Kvxys6az+2Ohc2FJTch33xoi2krCLOp+Jl662Tlz9ECWj3NY49zwj6xPh8vDMvz+/HXfu5/Wi9iVb3qqqOpcks19PPISxdnl6+aKPHxbvUV0bTi0VDKHFjvpP7mJTa5TetxE4u4Hwwa513h4PP6USc9odsj7PFMTQK5WFvVrlqPpgvmiw9PPWsUSvLXTY/OuVB+2Mh3Ell7fG08cRmF6pVq5mzu2Y2O5OVbqby1uuVcnlTFqW7v2KIVgObP4l3A9u8f06p9ZROp9NJurmdtLZegYoea8NXOEYkkMvDUEO/I50d6eWQ8khR9iim0mNwAegyQOrATJOO7o8i7dNMiRmDuTK2x0hd5ljWV9gYLNDYEf3VNqCcZmpAGjlvMGM6uIDwIzGdeoXJZniegf5WMUCTyavoTiLpGmLXRewB+ngM0phyN04vds9HXODSnAUZVxwemP8dpF4B8ljRAr/9jY2BTVIJR+wRG8yEhuYwgqrFuXw5o45Wo2Iy9P3gqCe4pu64YExb9DVuFSNHzwCaOQGINHThtdz/vaPrmJT3IdSFOFuDu2R3uVgv7wE0694c7KtsWmL41u78nuSGHjP6RyvNT5s7GLdf9m27iVsZJB5yeQydQ0zU5QXec/hFtC39wiVyi/6L9yWQZYX4Hm99HaJ2pG037TKMyNrtucQpt0Nfg2WhIAGKbWMau1MHBcs6TEToSQyJ3A6FLxW3TxbU/cQfrAYg2nt+1ztcqNDE7vHpzsXSwgJrfplvbZdjwldSFE+arirSYp8LJqrEECHbLqU7xfwCuXAHS645+TI+M6eW5MLb+WG95Pa/uQeb+z5liWvHDwoS01R3XRgmQcgBqnozOPn2P3torNf/v2MI6fDT5DNoGbZppUxLN35Y6GLm506goqsED9QrHqj/eE58/lCJSfyXJSZFyz86SO6M+uciEFx7ElivwTYGhibxPsQb4hVoMtIREmzEJS1o+SbTHCBLD37RSxnxe4UUM0x1uk3KiIwSHNSckzJyWbrVWkO2bp6el9mowPZW3ZzHmu5ouT5tnA7HsgUS0R5TLsz4Pibu222neY9Mh1e1J69vtelds1xaMmTX6qVSt1K+kmbDYfetNKyVSjoK1q+cdyvlbLBvy+Vig6QJNVPBOCguIbt/NUZMb2BANlxW5KazPIwlZPTDUC9kBP2LA1kO0RBPgGKYzO8cCmzg6V9AVfUZlP84EBF71I74x2845HEMoWNF3GgsEgVCLo+Gj3/VAsPVq4oXsgUJZkGKlTLZlCDlB6kCL+VTBVgUCnk5Mxjk2OWgyG1sju4dM2JqnTldb6hfa7VYGfSBKapJ4AcOA/idxK784Rpd14YuBG3GvmHJCdHDEhs+0ZvpKRVaFjSYZveGyXC5XIpjgDoZgRTP0M8Y5IVIEEwRWfOK6AiX/7jS7eweDIGJjrlsj2O/ZTZxuMe6mW9rLccDs2pN7Ms7g3zKfRP7lC/e0ul0wubv1+7iV9Le4cJNPY0+TIA6RJfN0ZgQdVs6M4QaNNAgJVrHhgl4Vij4cLC8XyZ8Njfl4uCrUFqCGklfXkGE5brBOG8wceEMXjO6QGPqBtAkxZT0mHUczn0IVnrje5qgQi9m64xpalI6QZ2+pIj4qoGK2K8tvyBBdlckotYwpmtDRYOQ/h7Jlg60CPN5lxTOlFQLGhpAxzMOZkPBr5Jqo52jaBFrYensW+UqC0q72WyWDvnH4tjdI1ZuF/2MlgcOF9MkmGS2gKoMdENTQOTYRKnF7tYJCMANdJBoN/I+jyggYen+aoGI0MwSeeg/xIFp6pKCo4VQQDUJF1q7w/kMZAt5UeaKosTJAgtgMSvmBnwxz+cyEkxKoX48T4/n6Redp4F2LwnbCRWzvp+TLzM0Lehl33JDUcyyBAw5ZrqPp/uXnO7RguXCHgMthRYNziPBwiXxZLcWDL0VVbqdf4NSsb4FRy3ip9MiaLywA8+SwHmPP0Di2LUSBQf9YDdeN/oNWMxYNy0mJzDSCBhACuVpbXaAf9FpvVKiXgWkqaUjgRrsexUOAE5bs3SGSkmUn4Ji0MwJlLCHMqm0lUlZCSXwYcXtwYXc10m0LcRXYIpLFqNCgBIqNch0S21kTHa2fJpBWwSnW5oj3VZlR/KRvARv66ySfr5lz2dzq8MP10pDX8xhlg0bDw8jFpdMunTbOvX5FmpoVQUvCHSedpGTUZevo6Tcm6T8UTr2UUjHCemDK8DHgyDZQXCU74eR70pEDDwStj4LlztJ7qolCQrIkrLe65sXuVxG4PIpTubFlCAVhBTIFECKH4h5wEpyPp/lt8ysiLzCx/ngULM38b0lbHfI97aPTEavW0fkkSPyyBF55D+BPOI54PeOOLJSnhxJMI8S5ShR/tUSxcF4O7BMOZJu/0Kk2yG311esj2Pe5M/AtU1VjC+a7aN28TPM9wE4dkPpLmCi+JVLZJP4dSc+3Dm3Yz9sRXzh5A2AotpJEni82YtTXsJKsOwvVdEsOMRq0VjREHAFVouQJibrko0YOgFJrjbUSA827XDkM1O3DSlBFyY6aoURUcbSeYhb79X697Izw9aUDxtSYyG19HiGx7+/eHnGKxR0YWm2qv59doL+E/TsH2xd0xRvWj/+a6OV7XZqiyWewD7oos9tYiT8aVCLQ/39sHULrN8AKPsCFRdjA3YfO348d4xw+b6h8XazGz+naFZOCN16ovsG5xKE8iowFuzspbdYG60GZgRMxvkOP/baGm7bZqiVI2DIrxKYRI+IA7LjXQZDI+NmtDAiHOgGpKGGzl3eZAC+JqLZCBjOkwwgHzeAyAi/7tK61E46nuoC3WFtE27YmGxkW0Lb2VtftJG+yfYN9RYbGk9ygL77qGv8jNpnSCIdWJP5V/lLfu6lcTCLlQcE8M+ynXUnIjavpK9ahv6VEMqo1YhoJc525z3GgJZtaB5Yb/jcLd02k8d5xp22fp1025796sacX2Jz7QUdK3JT7Xvpj6EFZEBUzuBQ9fG1CMXNn0+BakPGeTUCWxcF+5kQq0gTaLi1ML+TWqDxx0qArGhkqSS7InE/KTulh+AT7KwDoei2HMVJ/H//z/9rMiKEGoJSJPkCC902mGq7izH4EAQ70JjSGVMqlUpnKI6k0i61aggAUjfWRFeQBvGBKJZdbhBOBzVluXelYL8I0LwIGROp5U6vqMSiuNdkoFAPu+0mnvHedZcZAU02R+Adz7hiMhLQ/ACUAdR6B2wRDUtk2bg91GNGBoj57ZvDlYka/DqCQIbGt9+Y2UiRRqTZEkBRbA7qOENecbw59GvUJxGSJA/SgzTTJuCXGEnTdTwxNGjtPAz7TZq4egYRLP++Zi8GWGQlcOTh89H3d7/19+9fpev98FPn6Mk+erJ/bk92AF7qQP7KSPly9Gv/On7tOGStr1wvv/rV6KdYLvsWFweY/eSAhcHc9F265hUUAW8WcRfbfUe5pXkVLF2Cdq8lWORyVdquNJ/L5f1z9gsCSeozDRrmSJm8TqFBStgD52x0obHVvY4sa3KQOknJ+wPM3C9YIQaXDDR3LyI8qsQknKyyNH2VoQqH5Mtf3xfyUxw8ezS92bYi35By9nwAoWlHHOryFGgSlANwdBMgvR+VkV9Kdw3P3iE1VxlOVD0GBxNqU8XQtTG155FXlxjgLP3MMXjhjM+Jocs2tr+sMXRZ6KY+DOR4et/60jy9F32PY4Ao1iH4rqN5cTg2R5C5IojqTLd7jTIPdQ091AeDRKEEe7Bx0bZGpVhXFROIKjJt9jVlCg0TqLiZBhzrUxRzoC18/nwg4QzL4Kv+irFdBltrsWV1YOhjcveXhwStc2LAKVrBuOCBjVBrVxaHChAhah9mIkV5+01sujWINV9DFKZEVgW/9Iy6gZ9d/FXHgETswWfMVDEVSzdM1/Zs40HDHKl4W/jeZnRkHr7o9W676RftRSsvGDl6HM/QYDC2JkPDtFD/sXkb8zjqKJoDU3Z49Ksujw4dqgFErDuQNopaThTNaywZGq+p+AGZANpUW8NLDzVjBKbQGwAQBaiKMk1tQxoBbJnWIscWd/lP5qLb66L/ltQZWJhM34RkRNBvN5OJbli2ppiWIjE1TTIWeMHhZxpKN+7oNuopLkBbMLfIANaxVeyolBUDWV21IWMZYDBQJNQzWvaL1lXGigoMdXGG1xD63f3GfZGho+yQZI4UlUIoeYM9MfT5ws/AFBpk24SrR9hULJ9RjboYAvC0lq++30y8C/DoNQd4QmQdiwg8L+73jicicuwji8SrBfXI1ky0n5QBHhnq4gCiPoXRi8yATt+xb4h+FxhRFAuFjJ+A9pkM6Bkzg6h9iglRYvV0WX74Wa18y/FAxFaOgIvgHG0OvD4SwyjyE+GpxhKFAZ7viUIKSPgV/6hjCGdtgZeMAuVYjxpaNq70O3BfI7hIm5pMxdyMHkKoHSkVTqHKANsaocOfhLLRjTGxVdX07YEDtzmbpM3OZxu1mykxKOCUIZ7gqa7IRGA7GIpBHSK2b8Gg1V36erw1fYWGvB9CKW9L7V0pdlbDzFCi8B32rSzKcGJAGne7/Qp21+OSIk9jKMgb1FcP8TGCfVFIQXMOW2OBT3CdKI347AqTV+8v4OgEhTwQGWxSvRC7mOwJI+kGOsjURZq5ob5zgveE4wJciX6OBPo5EeayZtLCEk0xJllwqB9C6jWBbqTayDLRPEMZGtY4x9lMBvGO82yPz3zjCvvjtg4SmsRgmwZOQkejR2IZ0x6t6sJ69vHcYTi7A/wqyXq2Qzc4nsck6sUel/uWLX4T8vvvRoRqE9kNrNmQ79YtKk4gg884g8+csizLMv1eZe/Nj9BWvmB9HYwT3tezCJ0GWTxkPBn7XmiH6o8jmB03xlF5+dG+RmdGyITs28wbKv1H+BmjiZT2spwcV8fZide/XTxKdAr26/MRDkRQtTyqCTw+A0UbQmNiKJr1ao4An83Fxtv6ovqohWFZrVlz8mRzEi/kiiwvZDLZ4kAsSAMuUwQcnxVlNgvFAScXcwUxz0FBAoNMhs1zBVgcZKUCKBQh2I/IiyIlDYGvYXPAgsaZDZHZaoYNj/iKPzGIVotwu2mY6QiqMsEEVAlepT6xlDE1OUyggcW7JsE0NVJJuqaR+EJs7kYWBjin8Ms4kFmCSKcmZ7ppUcPkwEbFQ2JUQ2YN0aYRs4omIbOUPoaMCizM102U8dCdwgEXR8sMuXtItKoTOuuQDUBGgwCNkJt45mtTmiGgkTQrDdk/LUMRbYwlaOkMimtC/+2nu2n/d+aZ+6iW7i89MtynI2U4QnU7rO2BN11gyGC9ChlGVfWbu9B3bgX+SfFPyFoIURWIMCJd2L+sMSmb42kgf9goF4105NXpSLS/IcEeRf+K1jXefdOrxeADuqqFG1OQCKOUz2a22l3+AIgIvNVQ8okX9I0Tp92Qb/eFqQKIoW21ZAGTSXpFV7J7ERyufSriZtGjYd8kdFzz26DR0iNh4lghJDLTrxe6lnnXA7EWAXF9f3fpX8SVI9C/YI8s1QyaloMRnolav0trA3bCFBn0FLITJtBuEInbzs5WN7AG6JMV1M++J/vz7qZy+6NX94y1+w9k2hPbacKhpke0Q8+4G8ezUxIK1tkXXa7bD/yO/ErX5z8JNPgkQ/DrZ2cEennMyzjmZRzzMv4LeRkJDvV9O2oCkobEth2tYD/cChZ3QB5q7pG32Knki9RGp5Qlprn9WNkykVa2X0RR3Ke9rXgoQviIEU54m/etuaNu87PpNs457QFn4KA4nUb4bHZQ/xsUnOwPUHC4tdqNT5/xKkw8Yl+myQSPlsMpL1640/rl736/pz6aRGiPLdUM3UijtdJ+v1kloXXBKHCXAcQxiFk6lhJjZEb3X2FbQANDiIPKoSZj0yEOD9Z0JqIRyDw8VKZQO3PRGXCrXXubj2/XMUDSgGefOZnUKTOVUtSVeTUc39Zm3/DcmkfV9Cuiyw6yQQ6296mKrGgT+0cor7+GTrnJhgveOX4+K/Lr3tVjXOphdGSvdCLUX3dOLvWV5JV/IMv6r3wzC8b47VKqP+jpYL4B07R3zv2mhaCTBRoKUF+p7rfjTgmUhQpXhhqwKKb1LgW75fxH7ryTWFf2j/MM7+CdiFBcSugOge4hnpqpGy4tJkN+EXVbc7XbYIbVhfvZmDKPkrCPDxux+6GIZZrfRV76vX5XbZt/MCJUdcSbiAOvUfKH6V5YgYRvbczvMD1MnzHffaPxHbXtu2mL/iH6/keaeaDtpQ5dG6d14UswSgY0GcB8/zP9HWeqKXOqyhPbKUOSN5zK/gyXXNVtcjN0Kvj9+5/p0Fs4rwnjqCu+sUOvDnR9+WUa9U2DVQi/rzvgpj1ATXQGEzBjW7WUFA7rcIby91Az0YUBJ2WREJvvf7q/arr1RxplPCHw9vNmte1HaUaZiZIEUWwOycyyLR3hcZKwIEnXptCgd4yJrS1CDK7LHJTeHYJbXuFrwuKDS/7P0BYIzXiIpJJdIqncQM1dcZv2b8owQN0+ABXRv1ayByxLHQ9b0fNg+WtIbxAsE/Z67q1LUfEmFX08BowJkTnFby/yOkQFRESvGJQRblJqY0nXLEAdQgQ6cgLnZ8wYLPCmch6PEfC4NQIak2XJeJ3hNe68J0IGjifWYo+ZHauXcATP6jxloraiiKiUj43OqRZaJ8F3LGgYAIVHpTz4RYXw/iIS1ImNzjydUiSfrJ+sVQ74pvtsDfo/n4Ecmx0IUIKDApCLEshwoJDJ8zJywWdCpgZ+q+MLa0lb5q2gOzj53gEU9j8tOcH761IQeJLXktl3XounRUaoGL6GelkGuLO0R+HjeGUnGqouArWrDLV9Nj0uuGzPjb/5q0b+jRmdz67/8siDz7q9vwKk1WeVv/rd/fSRBiymQje2PSKkIGN9gr1KG5I4gMYJpPVPwyaBNILMFwRB5iWYLxSKnJQRZFbMSWw2kwV8kYPL+3p/o+0GMSkRFBS3NJq5eetEdSNy9i4BwkXK6Op+cWwa/Y/bLobPaeDRCfazOcGOAT7HAJ9DuMWiDoB9G8aXpMoRsernQjEjZ/SXTDq1yx/n/WdFKlujiO3da+bUZ9maRhJ7whdrehXEiUXo0LPRSgpkUlkjQ7eHIwb4/cM9XOD6hKKgMraHkfMViMAkNbgHZ5RTtlNaeBJ8dXpVbjD6vlaGhj88oMy9Ylg2UJk2tGa68c40q6s10nwml83k8yBVyAIhJWSKbKooFNhUNsPBQV6W8iAjbaetYuIxJerWfE2fnCFYiaki+y7H3c7q5nb1McTJhfu5YPklT9zxfSTR3IiwaKzL2PCeHCsDSV8VmBbjfLodRIZwmJT/iAiZf1HiiBabe5gkWTLS1uuX/cE2cwV2b42OMvzcUOMjQxYxIaaJsOimGdQAkt6LHo/sMdAY1DBq0UzU11cJ4HWxnXTE/r0YtKNDDv8WTdWNIdCUzxhhfuN7uoVA93++nw3rby5QX21NibiC3gReQi4qa8fG01L21QcHjyHY7CcPWzDk+3XpTUM0UMvhe5QsanXPHOCL/TuDKXIK3TxJhCraDvMsW2RIYIH/Ej+CDlhVpZTcmpvhC9l8IZvJFFmezxVyBZbn+IJQ5NlsPsPn82w+y2fYQjHDFQX+/2fvzZcTZ7Y90VdR+PaOqto2tsRMdXREY4xtPNvg8VBBJVICsoWENYDxiYo479D9570vd57kxspMzSkhMK7p8xexdxnIYeW0cuUafqtQLK9pTROR46PDVQlkH3LBEmnsMMNOmGhIpkbRAF6Y28licZrP7wEV7MxlllmSnvXkQS6S1247Y5gyaZNHwBUdLRRI79x+CWTRJp8SoIkJyCH3zWLDGfBVdIsHXJJlsSKLxRxG5XyuiEooVysNxFxRqhUKRVStlFAxk9fcAkB/zlaYmNgiUMAketx4wjpLi0ZyNXjMirjsCtCO4JjayhsEGuj1DYUHUB3rex1ztkW7ZAJy/OQTmNXrq5Nwxjt5hOUn8O5wSL65qDtMcG6J4ZUCkvgJPbHpwtsR4683tekjAkq/7uzQJrZtbNmw03e2Z1jTck+6MdN34gcjJ4+QpmF9iHcyJSvPsotAf+t5CbloAh/Ozr+d6o4tzfvkIEjfBB/GoQ/j0O9nHPrnBke9P1BckecovW7n48K6fW+l/Hs535Z48+HJhG/JF0Ta+PEjKkutW/m+gMHTHDQfzP23vOz36OKse0cYmipzRPMgBB8tQ8VlBbjjWAX/5sXofK5sHYTn+ysg+CBzhmyM+3AfwviNgUAuH1PF1pabzcB7SammYM8MQcM2DIgWhPoKFj7DA8D6urOD9e2Z+qROsKKibcMc7sCnnVb7vFeQyuWc1EPaZIRy+f/nHPJyqDCTEJeoDnXIFWUouIc1EpBpfXEf9vLIsCDm0nLkEfiMf2I9fxVaZ5+24Bt4ZZBf6DJ+FZrXbkZtkgLFcl3km9dspSNJYGzDEAZ4FoIIFCxkq9aAgpB7u2dLUP23lolhQ2Nlu6ufGTb+SjzG4SxS922L5pAfqLBtkCVglRzY7gZtqrsBXvPupxCUZHcDXC9czdW2cMU4mxtMHmk4oY30J9tnbxqv21+Aks/+7H1ZTXXLoYL/dGUnMVgwECY/d3kay8FOx6kGipDJYVPS1QlIMnIbHSGW0h78VDgrgoMLwJr25xoOYlenHUXXL3WpGDUkO0ubHZwgb/lsfVkR/LOrx9A/94nNh+rCGGcHVGgTWxZRNkNtttJfu3o3fa27G139TTslJkos3CZmBhxKKBXkcmNHp+ajPrZnsL4BEy9NjOSCIn6yQswylume4yVVFMVqIPkX+xxQ6pZLpcJqat2JqY6RybmaWjEcXFY07BxKtjYonNOt1bjSryq4j6qlQhUNyvlStST2K/18qSCKheKKluoJBM4QR3beapH0NztuGYGmSXLhKYNmzAAcJR0PO230eBJ8U3IiaDu0uInRkwCCmoBk07AskjJLQ5MJ8ONPkFpSnrOMpJ9CoRb0Lk0rQXtANO2U5UywKWMFC58sXeWWT3/lBLbNalakCMhgfJ4hnOKTFWQZ28KZQS0bID5B3iWWm1W2TAZU4Jpstvx1kZGF3X3mMR/KVk0Vg8bUA89vtK9cJTthS/154Lil78Qc/LfbPGidCVftunBx1bqpd5rCcfOe/NLVT1utpjFr7dbrx436ZbM+uzw0sC1rtc2S+nTwelOWT19v7duLo8Pnu05hNuk3n66ua/evFW04VZTxQVdXbPmgP9yRGgcPjvh4dPB0akwmxrVRlAuKbRXU2fPV/XhXfbq+qFRms/v85cF472GW358+HTWOtGO9q6N+68o5mO4ez16b7dbd8PgJUkmgzkV5R6k/Ng/nRrmNjeOq9tSat6+nx+Jgfn6jWWrTaozPJ6rS1W39+G4HbZbEg8fdSq1xdFhsXuW1k5sHfYQv9q92Xq/P5xcvD5eXRR0dDipzZ6dfehydi4PqYGZvTuZdff+ldffYb7aUB029vXq6OrVfzcPzo9bIHB/l69JRRT03VbPfh906e3w8u7m+vRgUWkeFUynfrk2aXR3PDAPh87z6etZpXskHtcPXOpL7N1d6/j7fvm3NOztS9bK1V7+s79aN1m690R917u92H+6Px/cXjX5XP9y9klq7WuOyntdPDgbi85VzdHb0MCypzdc7Y2btlG25ej8fPzxdNiu6oaHJrXW56Uye8vPSnTLZ6eroRXUmZsuqHb0+3R9Xz19Ec1PRZo0D6al9u3ld79+J/cud5+tnzepMr8tj58Y5vahOH+4PX44Ks3G/q286g6vd41f7onO5Y97fovtLedgQr25befGws797+qJ16vOzl/uz29e7ytXx/tPBzc18t3Zl1e2xLFeHXX3zsXiuGFZ/cGYcXbTFQ9wanE3qr/re4PBYedl7yt/Lkn1TvjrcNRvSXJ+fNGubHTTQWnXFyJ/eTLv68cnpyXNJOni+P7aHR/stbffq4vL52JjfKa+FwcH0zuw8DXZu72uXZ8/ikXTzVGpe4YuHUnF8VlUfditdvabN5jv1p8bwvlkv79+9GtaLNUNH+dnlCTbu5YqM0Qzf7bRnnenL4fDu9Wp+1Gp1RHx0O3yRCrdGV9+5rRdar6o6th4H5efmZru1U9XQy8UkX6+Wb05Ryy48FMZHZzuN5/bNwax6cpyvX1r25vlMuZjvnTpdXUVys6o97rT2DxrV8ezsut6vNV4PrgtHk+vixcvLwf5jewef2gf46q5x+3RcPGtuHohVQrN0PKl19bP8kXmjPV+/bg7rd5snF+Nm7bx5Wm/Xbi/bl9agcXhgDFv7ewcH8tmgsunMdk8rB3XUPmpdiNKrbOCuflMf3iqvd41pYf9kZKEH46h8NT85P0Hz0mTUdyQVdczi9dn9uHRr33deT1+fR1VN2jzd39/Tai97u119en3iNFotc6idlk5xe+dZbw8l59Q4zBs3F4+1zo1l76gmpfrFbFVurdqDXNy1K+KZVLc2r7u6Nm8/oubNQ+P06Xl6eFTuNJybh/3BpdEUTXE2Uk6Uq5Pr/IV1sn+x+Vx5Rvjh8nm4i87ax/hG3ru/6uq13U39fufxfHxpXODZxY012Zledhp6c+eqKlkTRxxPxPtWWW6NcEd6qL3W54V83prKcrFwhG5hP4ybffw8Pzm/KD4Un9vn8ng4ethtNxvD+3pjelW7s8S9A31z1rBui9NXvJPHaqVyulc8v5ziyUVr/66rK/sPtrY7L9X35GGz9irKzs1uuaGeVPf6ynHpaXZfmxycmdXD60ZLLKiHT7flB2tTPBHvx+po0LzBXf3iQKpdtF+Paw20p4z2asf7D+3+yfxmf3w7eDm3S+Jh5f6q01EvToeP8/3JQC095p8Lxer8piPazct2Vx+Mrp7R5fHusC7fXhhP46NKs39/eYBP++3KYaOKb893ruZorOntwUBpKG254uDCq3Jz9DKpP11Wb7v6s1MVJ83WftlErctBfVA9vVPVhwpy9s/b+uFl5+66P2pMpnsnx6p4OnsuHFQvNLGibeatsnJ5UO50dW1avutcotP5oKxL88fXk83B6555WHi+O305PD3f6UuFJr64m+ydTu4rh5cT42RP7erksmme7SVcQjSED+uWCvg8K1zVSfFVnMv647r8uC4/rsuP6/Ljuvy4Lv+x1+WiXBCBZj6uz4/r8+P6/Lg+P67Pj+vz4/qk1ycn/WknosnlxnOEDWgEdkvHWGHxHV6+esfCRD1seVZWGq2IXAfSsD7fHgkP2DSEjulYYG7pa4b8RPyEMt/W/Jt6etnare/Vz3aHT8+jJ/WgNhN365fN/Xq93dg9lmfDYfuxPmzWyf1yude823uSW42r68Ld7rSr10aqeqHv3rYeh53LuTEb3+y/7JmSND4/Gz7s7sin94/NnfPp5eNUn8zO5HPUPpbKp+eT+uNZv3lyfNXVX/Lag3pzhE6u9hqy/Nx4uZtd7DRM5aoxkp8PXo3KuH/2ZJ1qsqqYTbMvnmjN3eOT/Ub+8vFqfHX83NV3N+/PrWJnr3prPTj5drlcqecHD+PHKw09n7/sq9KonMdYvNjsnFyX89Xrxo6uFaUjddC2S82pXenqo9O9Q/SEx8rsoa+d3Zv5SblTOLt8VEaP93cd+6J4PT4/ONodHVXUyrEqDwtKodEaKp3T/nDYxgdwCh51xSxqyo2+VyvvnxXkm07J2du39Hzj6K6zP1Tw7q1xrZ+2izf69cPrxe3BoDht7941qs83lRNrs6vPiuV5p9KR6sPT3Xq92RgOm/XLB32yYzw38NnF+VVZK7XzJ5uSPXgRh7ePD5Xq6OjGxteTB1E9bB939cp++ekYn7/Mz1VTqUyv727Ep7GxKR89b4qjiXiMixiNy0VxvzGZHQ/ujfZlceeqMB06jwe3RzpSu/qocVaypyXrFNviHT66cF5Lz81K/cQ4bkxnrTK6Ozm08iKq44fWXufyqHbZP2gf6Ec3r+e3+ubRXqerq0pr+DA5K1WuJneDdn2mH110Lo93Ls6qaulVEqsjC+2dK83hwfjl/qHydP98+vx6lxeP78b2qFQ92evqgwv1xSodHdjtsqiqx42d2bl88Pq0m9+pK5228XhVKRvN60pFrp9d7BRez/Ols4OdndnoWrnXbkVb7OpK5WJ499LCR3jzZXivo/He5dFL4dnQb+Z28bBSGSHxvH9Vf6wB37vcU+UHc/OmM9s/1ZsnFwW02dX37w70Rzy6Up22pFZO7w6OX85muLG3qexrpyfi/kRrX7arV0Ze31SqmlPd3b07eBGfx+WbO6d6NdK7eqVTvz4pP29eNIYDZL6+DFojJPd3Og+N54GKW4fWqXazOxjdlA4bd/rT5pNqibbT2Lm4qpvybWe219UPj66P7p52R9Ona+vMmk0vX9F076JVOZ4RqpWd2+HJ02OlXrgrDYatw4fDnYP+XntXvZu9Hvc3zf2uXnxodPJ3+8ODnfP6bWWKJgP5bme2Od0sabsnc9OQx+f1duHi4KA+Oi11Cocn+nXjcqAfF5+HE0s6ee7qav9JrnXGuqWXxROkXz8616fW/XTntT2riLbx2n8dHYkT1WhObgdXL1cPu6/2ef7KrJ7Z48qovP/U1Sui1Lw7OKvfEaobe9KL9TjPHxWsBjZbivwqOqXnu5P6xRN2Hm43C8VxcceRlVnndiaLw+ZrratrI+v6ZP+xNikeFErS64mjNvXnzcq4fnsi7x1p49Z5YXxpl49G6ol6UrsXO8XJcHf8Mr59Pj6+t+tWVz/aFZvj0/tNaffsrFgc7149n7487HeOHEk+UUadnRfLNs+x0bp4nttP+v0Z0ged0wfttQU0H5onXf0Ol4xn8e70oqrIpzpuyvXrmYWuixOz/HSpFE5qzfH1k1Z61SpHtcbmHnq5rTed2evubEc9cGztpau/Xu1umns7FevVkYqzo3yt+XzX3zs4vno9nWxauLQzH+w+jisvzQdpdHMxq1zMdtujwbNdqtztFI/t565e0WaH+viwfCUfjOTNi8rtrlxSz3fateJ9XWlNqi/nncJkUDuqGwf1pnj59Hx0fb9ZOh2am4Pdc/HmrKvfVPIPxsUUH0xuN/dwqeaMjuvnuiO9ao+XjWv7qVQblzf37gZj0T67P7bRDJX0qnpWkR5Gm1Y5/9LV79p2YXKvSvelRqMxnlbvi7ujWUu+mN0dPxVem9OTYfvwpjNpiH00r9dQ+7zY7z8Mb+5Qabb5IM52uvp0OpjU9m4NqdUuNPXLK/O1fHt6X/9fgfs8ek2tdpM/O4aNFvsjgo8WVOfEs186SLfBOl53ywRuWj/Wmmd+BrN7SoPXVua2MsRfMMt+jx/N1HZxakkwk6Bgi9ivDT0kX3zusrTLOdNC3Q3hs2mhL1uC9y2WZfgWywr5njhRcfBgoAwIOXFfEOtLupji9x4Ipwp96VOyscXrOynwKtvsYaVH8BcTPS98x3kFfBgimUEDU8lCefoMoTLdA71YKQWcGehHNvrKVkHcqolbhXJpq1IQtySxVtqCEquO8yOE4ANf6o34Ugv32NR48hznM6ItsEor4SzkizmxlhPLHan6tVj4Wqxs1/LVaq2wJriFGBB5fJIjYcB0iF4SlMxRwOVKsVCpVsqFQrlaq9QK5VpNKkoVqVgVq/l8pVAq1sQVgfpCg8gCURka0gKoiEIpD1QW87VKrVaqVktSVSxBzHKpWKoWywWxWCgWa9WyVCmVy6XaOyxLkpabuzAsQIUDjrogSLvfrxUHA6lYRHKpXOnXBpUSUsrlYr8sl0qDqlLCxapUza9tfMA8E8cFPzJlwVLAoUNk4xkJBFqJKBJQkJgYCBxm27QMxYjo6gyl2fFEjwnWFctdC9bg166eE77L6mSETev7V1YB3Gx1AbmA7PRnwXJU2J9kZJaHU/4f3Y1mY++wmbtq13P1ZlvKV3MHjdNc+7CeL5W7GyDGcL7+9v3LNul7rOo9wFUBKUU19BANZFjsB9ax8Pl7d0PaFrsb37cE8qfk/5knfwIyO3wqdDfcTsBZPx9s+nt3w9C7G99ZYWMw6G58564fE4bYFFF0nyDBGzRqOb+iABQOC10sGnwEi/35wWJL7oq9jMFdH3vjn7E3gilU4jcBYfaQRQNZIx/XaKmbivLoW9UeXbXra7pUXaK5kPwhS7hXVEDaEBzkR+M0xtxs7LXrQCulemMLyJd84sODWZFJe9QniDvJk86RdX7+5D+pHM2EQ7gIAa3OirFfxYVKCQ2kQrWGxHINiYNaXhpUZbmKJdyX8kqlWuzXiusSNC0ODggJlPHYnr+3w6gfi8FN+o6uaLg3xvbIWIj56OjQqNKjn3smHvSkMpJRqdJXcL5WLuRFSa7gMq7WSsVCWZZkKZJdq+chz7+VN3PbhM5YPERAJRMPwBn49i3eK8kNs8xs02o0rzqt/Vaj3mn6Nq39o71GY7c+H9bBC2XYutwT1cH4cedeLZ1d7OSHyvW83R+8Rm1e1n59b/esq59eWrPG5f3ezeXlQXN2dHP92rw53T09qEvXzcbo9PTqQNPR9Zkm65fD9m3p8bQtz45o+b3mS6m5vb3dfm0fDu4mJU13dgo3YrVVyT9Ll2ev543hvXSHT4oHxzfyY9Ewy3KnbN+VjaPDCr64GA/M3cFza+e8q5/jw+rw9Ghz35nZd/fNC1Qc7Q4K1dMSvi693B5UAgrT+BwEl4OEp/CZRgAV0OMWdG0gGMXP6blwQSp9qVwoSpWcpOT7uaJcLeZQoYpy+UG/gkRZqVRK+YRnByMzMRLHNbOmbpsPh6UPh6UPh6UPh6UPh6UPh6W/zGFJkacEXGVIsflohChH47/XuBH2vHIskpSKpyxVHjFHkV/TMn297QXJOmBkbvzgZUsNpTblvGTUcRAcLyQdsrqCwcXGW2wukCBzFTUXSNLXfGG7VJBqtdJDgmziZaWL5In0TFB+xkeA9ssoobw1uVoc2/LfMbxLgG/hYrRHsAkJsskS2NCZQAOXT6keTCHLEVPJb8tMMYfyPXWowhu4pScF5q/8EqtUkdIvVEoDsSyXlWI5ryi1fL9Ww3ksD0qSyM1pm8Fi8YbRvsWe5II7vVUTZmleS9G8u5zBezqXtw08qrzgDtBT9EVe9uR7FxnCHckn6saQgE7AIQGsHGAp8dlhQFmk6qqtIk19pbW4ZSmWlhL4GU4AwJAEvlLwRDPmANsT+lLDrBH3K8IyPSoI/4SWCR4rtBckqAc8U+kZDrQZ4ObBr11SQl/6xES+puSEvnQJkwFCxYEkFJYNtv3IkNwvPUIVzDBk6cypuvcLYEM7E5YaEawhhhadom8Z9UHMhWZJBlBDtVqhhGqoUhFr5Uq/XxaLCBclVJVwMY8lqgsO5VBf7t4jr3DWwGo3n7jczRdYfB+xLSJwRKUKgZakeoMRmmKKCWRiGasBbODguPxsiJ8b9S9pd2RYdxbIVBG9mmPCDiVrAddoXt3s11sngmYYT2DjcyZCo16niocMUNIc9L3QHAaktp8jd/3Y2nDTKHOUcLriorIEAO2C6yID8guYP91G0mHtBkizuCcqizHBIrD40B/SPuCD14wo+Babk7so68YNhBUPbFkqdn1ABf/k7F/rtHaWN8LsLpsknZ2rsS2i4AGRVgx9/bnFyKYMguAn7MfwJL5rvsVQZoYfnDsmy6AmhsVxxovYsIi9kED6EcO751j0YdLyALh6fRMRuTX5HBsmSacOiKSKEoTK22VVPSMLQXHbFmikGEVGUxQBCZbTZ+KLMRAsXd32+7csjSTUQRTgEHLIGzrNk6EOwJeK4G2aDl7xpg6Z73p0Id86q/EGP6yEv5WVMH0jfBgOPwyHH4bDD8Phh+Hww3D4YTj84wyH72zOeA8bwTuqX/8cbVhwauOvNg8+wi22+FXmBg7ElaU6TVHgWjNZQSI1QdwDTddALcYAGw2AFazI2LFsCHFk0WS7BshOQB/VRK/R2pkS2rGx5cZ1tA+JYy03XzAytXlvpOo8S27k6daEssIhlIUnBtaBqAUSbMi6Qz4Yg0GSly+N01hEBmS5yL8PAdHQEa7kzLJHh2NfnAmgwy8iRtrOB6iRtiFRsLQtkf/Pk/8vpHhA96Qex705MjtAlbRdeI/5yXJAbe6LFUyHeIWkrY11OVhnMmkyoFT2Hmq3T9KJ8wxs7uz5X3h2xJitMmJSzGx5y6Ro5Jyd8AgDgeerjs0d0VoJ52zrRGuza+bkO7nE7My8Mfg/0a96JqbGUPrl2JiGzMsBs3Hc9kyAhkLfjNWhZ1F2vyM7HzgFKQnZKHs+EeSjR1zgUw9N8Iv7ld8R+ThAqka7DTXtlloxjoIuBwfaKbwcbsphlt94+VUJG7MXWP8X2fIDezOrnf1N01NKm56gZLQ4SUZkxB9uEL/aDWL1XVGO74orBh9ACqzgFbM6MZX3vuuyHNUov+UzUne3rfVCqS4af8jNIiPvWmkS0vmVOwk/iXPVlpkWprlGlmXI6h80PevbRZKYGgsp+GSxM+6p+2mG7zjMS9Yb8Q00SxyaYzGOljBGc3ih0skWSC55AjSy5aWucgkzsX9AoKD//dSQXXdqlvlcUPXcxDSGYJETkDXX5ZFp6IZjCbaJiArG0BdwwmTRk0dQ6GuXHvJoIKN523GROAL13oI1tzXLVT78nHWnQDfwPPzwDvqZHiI/zdJOw+/ZY/6NHbBWaJMuohckr1XX45ASaG3tPih8ADcvujuaX40O1XJVM+SY0iIsKZ/FEMoUgyhOVJ3kSBXaZy1Xbwe6FC+Bafpp9jO1bQQQyzZCNAV4WvT7QPXVOBZQxkUvYoHvyz1LfOc2n+TxyCd3jHQ0xIqHEBEewVaoPlKm8BIgD1eXVfkQdRtbkbl4w/AXxP5H5BtIQ0dU2+B6MjJmJI0qsjwQJLgGZyNDoGO1BNVOn7PYGntfMGChHps1IuLAQfC+WI/Q4k/6Yra/VmaSzwSLEUb7iC6TSlTKdtDRO6JkYF7eCkrQsmZy8i7kpMxO3tlBR/g6az6em4YsWxgbCkljvNI4pGJOlHKi1BFLX/PiV1FcE5xbYEBJJwmWZpY0sjesjSSK7z4mLl45Z9utcVhiPp+TpFw+35EqXwv5rwVxu1iu1ArVt285jg6KO5qAOPr20RRyYiUniR1YIelrSdzOSzWpIq08mpSQj8Tz47kp2caCBKC/8CB5A+MDCmbadW8IZ5FqOUnM5as+pytUitIa1mlVxvBbjmV1hvCWSKM1cwQnyQcxEvBMbb8Bz8QFj/C+LOULCh4US+XhSK2sTl1W4Dx3JG8JyYAmsogiXF/88BTe+AFSp6SIYGHwcw8gR1E35dRptF+C5g36CYzc8OUYqdqK0m6Mfh6bCYyAFoJXDWTVYF6fkQfB8sNhA5HZAwB+XNdwCov3y0+Opwi/ZOOdZ3i/pvbA0TNRJPJpdBnfuERr23kslm4BWJyXETwwDlozg2eOi2EY526Ns/pp08sH7obrw84GvucDQqRPVg/JY5yTR0jTsD7EkTjGLJIAIbFnI3OIuc+aCKW0IEM5XZZaRZ4GIh6WIJIseAIKNoRGGAOBFIEwC1DcYhakmh6OSiMzgKHYhgDnDZT1y4FpLIvsoIDrjWWbyDbM/x1erBnuj5Fl4/D335hTUa9vKAl+8LKh26DMzTxi/DIBWD7bEAaqrgisFunFMTVBcUw3QChtLngKBFTIlSrFWr5QK+RRNV+slOR+tVTL50VxIKE8yhcIZIjbFX88QAONMABi+1iQRxg8AlzCliQKOvu6sxOJ8t3ZnmFNyz3pxkzfmTypOb+5HRiGgqQ8kuR8CVf6xao8qIpFsSqXZalSLvSrKL8NnCgz1EAa60h1/IiBq9gvdi+ZqXh8JPNeIHPLLtTOXcc95klTLSzHjrKEVtMxeQCnHOBpn6wlh7XahqlKYr+ilAaiJJWKpXyxXytLfYhVKVWqSJaz6Yo8XTIkk0gQbYDkPcg1sVAw8xOIsHtRKvrJI95wD7oEJqHGR3Ji8NFGvXNKmhTQwGYWDeqo0DN0QQlH4gSG4856oVwS3zYO3wQQH4dbSKCFQI70knxEtpNFJx/uexUJNLlD56Sdthg1ceUlSNzzJ21P6UGKMbR1Hs76dx+5/TuN9GTKf5atQ5ggexRFYQ+CrxMfYQib4oGwq3rM+fcdgdmRi8Ee0GzbCR6r//1f/1cwdKIYXwqw3SPf/TmC4M6jwfUcB8/dnaDrLqGCC/Ue6Ib8SNAvkD4/H2x8/Y/oml97Abqh1QQYeXfNtoV6xjXb3ggJHZkcrAPffUuUb37EBCHOrl9iaNH1J07ovLXezuJzHHVSziCbLUEr3R3bwm3STgjSGPRCjjgqL6Yqy0MsGDm+8KFJIpt75Ep84xMz2BIL1e7B07u3Bt1HpLFIJPha0Aw4DUaBq94S6xIAIP8ZcAmsmyCmgZv8aU2gBLS9aCdrWQpei9GOskQLLdMNaS+qCOHsiSUPYCKAEo2oAYCAIHDSDMMXOskmReSM2UjVsGCbc3LZGa4zHxYQD5nhrU/QM3ZlEpcTuLDq9XrdQ5MEYo2Z7gY4QIYUmVDq+1SZODfEOjaJiRnKmtZInQjBGRFs4wlTcyf4JQwMR1e2l55WdzNnU84Eu4eaIKiERf0E7kiHnvCoIvgLxiCkA0nVmgf8CdzLINhB4O0bUmrRXxPESNZAoo6GqmTWQyWVSYM6h4iKKPhcWzXGJoGdpL2gFy70lmCMVRv2pDoIF2JObgApoZP3fhaXqlXEeR7vCo+JKeKNMIULlCqRhXI/j7GNAM9zRT0ouE/n4OkM5hQooORYAsaJo2VwwIjge6znVs6V1u8oVtzwoFLf0BpMVw8Zk5AM4duioI9AavE3dhZMUp4nNxbSNPZuWM9EM5tWFllz0chT/YuXgZ7NF0tVGZdQTpQLpVxRrgxy1bxcyVVxrVitKIXBoCzGoWczWbsdXcdaj11lXNCTAJqPe+O19tIRWGs1pVYtF/NyqVxU8rhaKuFauSxVa7V+JU9QTYKk5tNJo3rr3gCNVY2j521duKptgRbZErBK3iHfp8XvwufWxbT4hTw/p2X6sfwllfppMcBSyIdpmd7QjKCJmnOdcHPvgNhGe1nJ7zZedTFKVwxYS3c0LYwZ+wYf3VVddLPJ63S8wRrLuKV6s5O8uIA09Zsv7E9eoPXPL9WwvsMM01fginNMK/9U9/RlPaqTZxTiR9mrPeu8+u8gSIGs4I2vFVEsbPlwsxtnhmAajo091fD1VWvjx7cQxLm09ZYj4NPwbel2kj372RwDW/v2M7kbw8Jg3ZNP73J82GIvd4x+xXLHz+OqC05b+iVLngn/5P3WHDLfZkAnTL7MUtvl76HVeqJr5P5uyqMEE70nXSrCeVuAgqqNZQKHTyw2tiFgCyRD1RpRvYts6DqVudKlZk3VnZceGivlYoAUeaDk6J9/rxSXac3kgdKjf/7jpT7envBP2u+8H5Ze5z9IVgwQzgG7DzxLO6QQ1SEz5mAJc8Mx3eiSkDv5J0vAyjADpK/7KAZNUkaG6z+jwUhj6AN12LNMOetK+RVodcbmsm6RQA2IPDUxUV65bVke8EjmnROp5TXkIi8s21SwHjSWPWcya8WvwHEAYiHl2ZsLVOA0l0ExRpth/9BFB92jgmyU+VSz4sCCs2R1DnVJapBTNjZszPZPZv4ZrJM9BzSt7dulbCejOSpEOTM4BQ47cZ7hKqCur1t7rrI7furZpuenufDU+sRwGjKE97Eil0QlV8z3C7lipSDn+pJYzQ0GBUUSZVGp5UtvUql5A+qp+sThGCd+o2GlDcPQjBS3ugDhsI0FGYPpLpiFeQmBbW//NiioebuZE5PiTdJAHToU3IbY4VSdwhOYjoYz4AOy4vFOThgu4MTpa6rsew/6Xt3WtlC3BQ1DyB8YDoM9CzrGigXXTp9VCXiwUdpXzkPHmA3t7cqhyOJjVWfQf9KPrQ16611RH6eMDYbrAGokMic5eAFygd+bxIQgMHW8oGN7ZphPAo19FQamMRZu61cXsBFMMhHRkuRtaW0LblSO6zSkDgKTBCm9iT+WBR4EWKG1eMsauO7Y0UwMio2IMD9iifoIpqiNVB1imHNuy6qh5/zXMSF7oGJNAeLVoW6Y1DIcfM9Yqi5jzykLYuy2JXFb3N4I92A9qZOghTAmDKTgdpLpojOIBM0AoW1OAT+Au2tz74jAS4puPKE1EL6Tot+3WAB0cModEHwFJNzXT0+EAdjfmTMdk6XGSB6pOqbN+KPltsVqPmDTEDom4GYqyBr1DbTIzddvNxxxD1QHI+3Z50Dxb7wZ5Dlx/iFz+MmKcLn1zGnaDIZ3p41NE8GFk/Po6KsagcPYAHbigARlkFlFWox9p6NtukfDs2TDhHOZ+7ZwTd03bWzqZIFsQwAImtCBm6n2KMvsuH6qSdQmOf1G6GVXdSNE6OJeWMlUS1uHMweZHyyZJdewlXYp8dGXG5eW4iFy0rLReMKTui3DMeWswmTohPvTvLzk7jmMuXs1e+f+lolzb7Zw68fs+bMNHcsqMEKHYEUziS+Drv7GSBBgf+UjI6wjSJXPY2OxhD62Z5CnMKgrASk6TVmyirTKPub8vjd+cAcRVFv8YePhyaBLyZEkVsSykWkLJrYdUycyhC7g8cSeU/f2baFjCANsy/SWCw4dHN9dlDJC5JYwgccJplF8ELGGqcCjCFhXJoaq28L3HXZlWDv/6V8eP3b+M/BK9z/BL4Euv4cvtqh+KbJ2Ls8HQj0wAXbTe/p9TELu/DeV3xtfhUfkJ9Bcf98KtgeyHNM0rRTHL9Ygjh+wMApfRYodER1qRAO2xGD7WCaZq1gDwmfdCC0kb6BfUkb6buMMXetZBmhienkHkZZWzlUu5fIlgIXI578WitsFqVItFeMQHj65YeXf0uSy6rF59gqNmMcuyevqll7TpCePipz99xYf1m2c+uWW9/WbIvCLaiXtrtbAw77f8oDmDF2be5sn6N7uIpB9hnsJNhTbS1+EPh4YJqZPUdg328L11Qlxh1+ER+KYWo6Vy6VDrUj5jlj5V6GeF/9VqJfE7VI+eOQHmARpcFZkn/3iqWm81GfR+zjtZg1EHiPmUhsbVkAuGKFED2gQBQ7rrv8yufuIuqnhak0ZDCD3RexGIg0GmqoT7FHQLxEUUgZHmuQ3zOhyXcTTA43dR21EZcVL0zAYqDLOSdvuazxD5z2wsgOuKC+1ifscFwK/RNH2sxDG/hLcvrJR9uxgc55MX4vkbNyiR4TkXwmTZPnPeCrPsJYykfqvvOh2zKGMtJ/BgdsnPQMvjK3Ib2/ZCm7gJQaY0VucN+fMOBa0FaVgOUYZCU+Z5duGA/7/wS9Bf93zrCjsC/LYGqoycKVJz8Lwx5AoxGRdXXDsV9AqFAKbcDXrXkStEJ/VdB5EPbhae8s9WwcVcTCoVUs5VMSDXLFcLOT6/b6cKyIRK8WBXC1KpYy8gNL5ngmuf39Hmwj7+ac72yTtjb/G4Sa+3n+QpKvK4wlktHmZ9wI2s6jzzUBDJCCTFiHktxqnFwKp6AmHbrgIs/mtHFwWU1bHZYqM0HdivoAlsTQoYhkPqkipyaggoWqhklcgtKawVGRK0AYbo+gibDheqLtPFiojLflm9UwZCNhlGoSaWZeFGMAz4uSyAp4Up1oEZYNdRZCpm3wVHtQC/G2nT/oiyRfJmDmzZBq2IRsa0fe5AUGAzoItmyXyIxMGycfbbkI32K+klvVVYGBIW+QPi/zl6OoL+cOW6U+WNSL/msrEK7Bpa7S0Ne5/3dnZFuoasVHBQwJsh0hn6jwBEWQE99ECzzWKLEW/+Pof8M03AaAxhE/BH4pi8dN2l4eQEIZyAjLICwJm9WtVFKUYrw5ierOZDJ79yQYnajqgzha3pW1xWypUgsaWSY+db74s4hr+IQ4LrKoQgCWYSB966j0/ZxzZI/CIFhqtvSt4HmeIApUq+W2pvC1uiztSOV0s8Wntsfcyh5Vc7JDOKYmqDq9w93XNUF4ykvOv/L5UDs4UqLeJKTt5xkD9BDQT9ZNqCVPVtB2keW4TDL+UtRPltCtx2PWYe+OD80v91FEyF3zPaSApJenahu2nKGH7OdWwC5B0qu5goui1TQDnDGp/YagWnmITaYD2Qp7DHmzUXFBUi5X2PWcQfe+P1VcXYUBQx6CRwoKGbKzLc8ITTaypbEzAFz1qIZeJIIRWJKR4B8Wn3y2cVceGbi2bYlsRaAYYh6s9JRMeb8dTVWtzenPReqD6yLigq1pXHF2m6wZDh+EQHS44G0yB5g7B44ovY9AsoxszAWkzAMYyMc04AVRtB3YC9dwABUDO0/vFd8KpVyqkHcQuLgR0NkJT7HpS2caCGAdjaIXcOYYhq+cYW6MemlkBZ7p0MWSgm9xX5b5mULinM3ZEr1zFeGuPAD3ZBG9SNnQFmXOhedaiOk/VEsg0e6Y53VAwweeCsCVILrxAraOrOVHKF4qlcqVaQ31ZwQMxdq0xqqMDjxrhiWDiwUUu0gHxvQ8vqKrXzHnZiCN+KlcuHIM1QmFEshHqjQ0Fbwv7EI2MZhb4+4CLCvAEgOH7TsfxnZXw/ItCZabqxHJL6IaOv5PT/V1RLSKtu+X7mBkODdOFf+D5zYVfokEUrmwvpNDuAtSorNXI4IIVkaKo9JheBBbCO/wh50M6MDIGwjFhHnbcGYAEDDzfTxLRz9Yg+xNw1HOrxGQp9v2iXZfVdrPyjrtg6bkG7raiO4Jun6TZ+G2W/pvneeROWaLL2KmhG7ahq9RDT9VBaUo87cIecqz+Fi0BvBbgeHQBI3kkXFx3+C5aa1bZvmWjvdmRKZyOJUP9QIXYWCLb3ictad38wYdmNds5eV810F/uKZXGf1b0mwrtzNiYD9XhKIemSNVc0RLKeQJ7xCbnOs+ye2uMkW6BGS/g/g3CpW64BlVTUK2g9+0c28JnHc/gXc3sqLRNy3srMAXDl+3AlRju6WWiqbJqgwupY4JTuTEYbDPG6QA+dv22TQQYEFzIUDxRxWOqpJz7amldWMLnm9aF9cV1ziWlqLPqAC3S0KBZUIKDqQGfZ0Y72CTJ79Q0mG6hiHPXxUj76oSHwQtDArw14nfvjsp/xZB15Q1vFWcqQvVUnfSwbptzcj7RC4tmqEZDG4De3sTEU9Xg2YVdwklmYcGZAOkKeBWz9JauA69iqgP7PemOJRWAeY4eK7/ywnViGi3OiL1N6Gm9PgdVLV8WKE8gHkHcjmuK3A7DNHtsc5V581i8i50YCP+P9xKKRY/1ExWdlOCN4cMQM8DUja+SKIpgSDVkBwQCyhsZznoMydV7QHJ+8/2T0xeMONhRVXXUwSGGs0ivSrfXb3FRjSZ4YXsrBlwYmjw/+jCGr0Z+8VL+Bt3lYxZX34XH7eU/A1ZIYzAw0XjSIybW7FYCwjVsg/2b5em/0CYQ02NH9C4huXCCTDTGNgQkuRdUNLwrKGK7igs386r3hA1GHICkzRxNmXY5i5c+9yTDiw5EhpOKC09teepyl8CtSLiDprnY7ZiKt6zmJ0toDHJ10lPuaGbn6pYFFBCUfQp9PcJIyUSuo3QQ51lCGxfQBK5TxHwX4clPgMIYBrNtCCahKzQK34TBfIaEuqOoGIKlbDS0iM68H0BI82C7vVgOwstVRL4koXqMmokBdzvc4Ret7Mig4QMZT9aiz93tSkfo+gIOHG2gaiC2uJNB8fZfo1rrJK0WbGSMxmfM7pPMpl+xaeRsiGfJGeYQ6ayLHHXLiLJuumKBtskbC10YBkcXewHGGbLPUnMHcPDgQY0Y8LRmGkmqJBWskeFooPahsaDE2Udl5YNtqHQqWXxff56a982PigeXToMXVct+IPR6fsU0GkvHM6HTuIh4FQd9xV0DERkIfiGufMGEYQh0dCFAks5Je4ulmqWiqm0aZEeARUOzGDXpAP8SuZmowNcYOfoTVppgb+AGXu7RcpYg05I09/YAm9RTkGhzry08cDQ23eQ8mo5O3cmF2/ZBK86qvGBICm+aP6fOefFDb9ugVaJZYaiW1Dbc2aNRb2Djym8L5yzSjemiAkI8sqiJLbn7Q8OyDwl7ilPQxjZdEWJLg5KMkwk+bwPTqG67m5oK44nG0h+QrhZP6po6xY20cIpT9ELA1/3MD6qiYQEqI6jMjURgQQpwTcSPimJguvtNDMTINtMEQ2IFvxfZ0GXHNGFEgR4WbSkxOK6Fp4WaGOg+RnrywFzWDAYBZIb9Ujlk1EQiFdvyqH3Wsg1YLc6ecuhuovuDrq3nQxkKm6TbNsg+MlkOgnYCHY3ZsZrM7RFVMlGzO6WzB6mObYP4cFDPK904RJPJvDnHfaTxMi2xE0kI/e//+n9HUFrArPh//9f/JyBtCIx0NCZMCYTzHWIE9XLgunyR7lTXCAa3zJgYXtyTE8Cn9gzX2W4Z3eictG8AWJeDoOmxFJZWwMcHjidWBpBri2rU+vPwlr4FaYRc/ALS56FKJB48sJA0MB4EoUlYL50yBFq1TbbAGddRwts1FAgmGIhNLyOW3YlQE2f7CfvKZxPEuaXDdV8MdQYhPBBKTJ1hWOPU2qdbYJKjvMsVKVTdNsi9RCITSCVVH27RG4zOwpbQbh+CzHO1d8F4h7ctINM5pP5hzpO0UzfvDKEFjFwkqw67mwmW+Vehu9Hd8K51Ew8dDZmsOrCr7oZlyE8WK4OE9nnjuF2iBXjeCCDLyJNjl+UkuHjy+A0ZvM9tINEBpiZG4HkA7BDkQBzOGmMRCxLqiBTaN5MMwZKf0cszlDOeLzxsudcuseLJI8OiIoN7XbpYRQbwWdgH7Uw0S2LQDXSChrhHbwieQDcMpieaoCH4vwB4AlElBjkGayJgLZeCb+ZAh9gkncZ7O/M6Ys3D0BTVmmhozutpTG9R+iLndxZDs0lxHvCjxenFFOCWXvi+x324UeExmzVrkCO5eNgA3GD+DC9Zng071S2Bb9a+ZhF9fvizC0WhWzZGShRggsJTRN/OES/QRcYph+fL34nIKu4e8NkKEciAKzJ3o/iO8Pc48SnjbbIGk3/gV6K1UPXAvtYYVgvrfGEXS+zlCTZpp9mazxPOAnPSS50wt3mmOdfooAhj1OHGABTEgLoivUsxxBreJcSBeur+MfENmc1mwdiEgEtWFuQE3+vtLeY6gjpANbie21TmVjgVYzshOQzn3I0RMvEYmU8sVKjvphXLEB3UDEcH+Vodr66P3BJ2rJXEpIx2kXVJjdPPQGLGSIZQAH6UjL/PQf1P9Es3HX35WOuA2EiIZ9Lw2mOlOXgAcRtFEOAuC8f0ygO/pR+WAyhxSxOtWQDFLRPkhlt+GXYaxtiAmgnekS+5ATb1kFySKZKG2x68DSdYXyr2O7IxAgAEaw5Y9x6uzLma4x9NTRAB+10gUNNT3AUemNvZoo7UCfEEyZJ9jrt6P6KGgfh2JxBxXojdx+6P7P6/f1eG/TuW2Jhpmysl5NsKJb5y3UmoboPk3aJp2r674Brfhc/sJiAmG/CrZs6/jv5lS/iu4KGJFPAQcct5Xso0joTo9Qz6QvcUNsQBGoBlBEcfYaTZozmhDEOT7IulWvxCs7Aqxkz368GDllhGQn0jS1BdA1QUNiQSj98kwCHpUSOU2ID7iTtzRHijkwP+XF45oDF4LVtOX8dc8IfI+UcTJBN3+mwAO6TZnleLHOJlXixuA3/dk4UNzLtfORElS7QSr78cDjFrx+WVqxERekqxL5dAFA7WCL5/onuIlznK/TGYLs9TXtAGFlvIyYN/sW6EOlMRBgBeSsykHeuEo/zLl4pwlVs86/RZpH2sLNt6Mc+btRXRJWIdZkKVCL0T3ylSxz843Ksl+LBMHsR7xszHj8Oy8XQUnJg94GlzSwfTieJ2uUiD6fLZ6F0hqi0S30VbioV5QWQORExBgBO4D/QxsYBFaoGKLi0w7CcFggU5IccVCnCQcwNTxbqizYWAE0y2I0MWO3C3t1nszYWVaY2WRmSh9daPxBKihz9XmYkJh1UnTNq/8qI/bf/Ki3Ti/pUXYepidP2zcSqYLPdPx6eI7oW/Ru3nr+8fpPfjr0bP36G/97IsCrr6eCV9vJJ+zSvpz+MBi5HDsohSvia1x3z5AwBinN9Iug9ErhhDm2IF9FcMTCw9Gge8b7PpRj5sseu1xa6cj+iNllz2YfU8Tms0Bfe4j5VouSVI5VYNag7Yfv+HC9Huqf+nS9Gx3fDXiNGBFf6D7lA/6QYn0GShKUkqgilJlDpi6WserN/bBJPjIV37QP/5m9OsLoWZEErEmalGGMPUq/ztH89cgkZinrqN/iJ8tucThhYRMKB/oQ7iY6QSSBUrakdDCVntMsTKsTTHGaaDFPWThL4l9YyXl3NpQzXZ9UHU7wy1veJvso377jxZtg4tvHSGHm9+fiRsnT8GWT+7KMnOxB92OcU25h+zMusUHaMr+MHjtYVOoMwJ5D1sddmTpHq08hLH/RpqkzKK+KQWfhdSF0/sklY1lAlCvq8Zww1uV7xVfGNnaKLmPNkv0qX3RCIYgL87w1tCp0KG80feRBaWTcyRLL3oY0gZMjNMRXA7I1AHju5nEM1RQEg/ZegpCyjyMlwV8kJ/TgA+dcXN8wIOXkjoIwuXiwLdR+kbq37Z2tutXx/szoa79eFpc/fy/rBRbzbqs8v93aHcCvz+v2hYENYtlbh48c+atwnjalYWu9YhUJWqRSP7CcFjLI+QrlpjIj879giQG0joJwmUmmDTCyjNdl7w/GjUejTUs9t99ezguvSwvb0dUy9mGs5CpXEWcn5BuokA/QnekOQnfwTk7TJQAX1a6M+3BAtDBBGL1AV9MQqG/q2CeBTSlcYojTxWkx9n3Ew90TcZisA0/OxHWebXVHTYa3tchdIfZUk74JVf6mUWdLT+1a8y7hb6Y54C2U8Q/6j8kTdl8vb/Y9Zt/U+4xPX9R7/owqikKQERBLUFJCRaY1s4czQCZ0M9+Fk7a08tGfXNSHpCpaY0DyJBuGiDRE4KwQbZDMIhJatwiOr8dgUw+nwSqDEuFzCUrtPGHLX1/X3WZl7s7Bs8Rd7sIpJgXQ0fOPLaZm6PnB59758k3N2kdV02ODiSryF9+7ZtiNQfCjcXDfJgJsKbJRO8t5QY4XwpXTXAt5Un6zMy0Pye3t2ZLPS/3wDW4xyd5HawhJf0UlvOsXLwws5JuelEXnJbfbgwRC+Xf7rcMv07/Rg4y/wHPT8iscd/sY/B6n4C//Bzm7RF/poTnLjsf9g5TlCfcd9XEeUhU0nzoDeD2GygYff1h58sASvDt+LWL0ZB+JE4TLZUPOUoMifx8VFEQ/qtFRqZbaQOLBmDGgLmejZFds6iGmU1GCJDeJmWczrpBWDQXGVrj4adL/GsjNTyGnIj2JdtKljv73nn+lZ0wpd8dPhMfIkVX+4pG7TZAi9aRoftK7Df4sYdOHcAnN0jwNneDpyq9rzngrr/aUrKBNr4WXuzKC7iFQEcJAHgP0OD3Kp/UMCJqUNiQ9wDg31AqByP1ylQup2stkt4td91cpdPHZQyiznIpuOYSx04P9eFm+ujIoqFQKKOjTODJRh29QXXV62NH98IwKiHOrdIll60LIGUG6s0lTUq8D2Xk6Ipv/149A27N1CHIzshMVRrIISLUDxfAsruQgEEDLqqZQF4D9UhIao/0uZdHRCbdYtgkI+QpmF9iAm2hbunoLkxgpwPhmNBj5bwuXnWIcHjX0IoxWnw4DxlkDtQyCRkIl3GPQ1PeSJbayB03NIkv9S4jxWFZpwLGa0t1cYeXPFMVYbYdoGphyYCdHd3iILX6VZXZ6m+yXVFsBAUwAQdqzrDgHWLCoQ+Bq1tYXtBwmiSncbD+vGzT/kD3tjaeLQ8mogWjTi0kJg4v3KiF4M3g0ww4llMbl3oKzYfsJNZ+ZXMO9w4BSlfeOAJUT6JCp5oxhwrvanKSZ3DUhlQGdxNOwarQoneIrl0TeK8wwoQnwXIGIF0paur47FDJofCXs8I6jAFMs8p2FQhPaqHUUw7cIFz/yfAdnR1akDMwS6AdraFc5rR06/mHQjgf5Qubya7eh8PDAKtD+lwCVIwflEBlndRWvEZAItoFC+GbZHAVx6IMqQTn6jQFJqoJF/Rk06AongeO2l7RTHAAyQ1w1Qc892iPkhedpkQyL4LX2biEHI9HatFMEa6urv7ADWd4E4QAH4K82xhgVG15Z5e1YRIU/YtncLgJixAQi2psC1xppY3fP9aiVT2bYnbsjHe2CIui9usOPnqWwRWNTSZeDLCY8gkzbWNXNGk9LB5mm5BSOar6sIOsCqSCGC+bnbq5fThAJe3/N/S9qSYL2BJLA2KWMaDKlJqMipIqFqo5BVRLpQKEQfT/LJ7UNXdlEo9dTzGCuTK0njwUQMAmuOV/R687ILQ4m7iOoH6F5IN19XBxqbqNJETlV9mhjAyHNPaFs7htp+pFt5yMyybFBs/0F1X98lQtliyb5YIheZkUW0vI4CJH0ka74TVXIiWE5oqMNLD7U6SNKUyT2bDGhP0QAyuW8KY3fTCZ8qntphhf0ugb18AxevqbMQmQy/6EuWchEMKyQwS2nD5IfEpIN2ShNQr8sQg1/spTPHd8+55HbkrmfWqdiv8zLuabzs8dMYIxEKkMDh1QiOU3RbODFugGfS2Q/KYMxzSJGtwsc8NBzabTTcEcTiErKGqPoRUSnRUVNp8wnCeIPMwTevBWBrNhuJuNnoMZwTASrVdZ9lFW4vw9zDXFzQDzg/MZtSQWYy+btK3kTEYaKjPE2H3DIo0OWKpWwKT1DcRwdt1cx6wiV3zrWDiIdeh5op8z6YxIHK52R7InLJ8KEiHMfTJS0EHv2uaY8SVx/hT7zsfzAxTC51o9hlyO6DFQu5HMoW/J5lC+HFMRhcY6BZbvjBtYUaaHD5ALrMnPPfB8umOTvdnEF+K9fq+KNbr9fquLl7l84e3Y7FWPbzZfRwp1v21nOja75Gk2vgJc8SYa8IZ/WSLJotq8R+1K1OYo4RFpLH0g0Q76ynYRirXQBKl6xPkfobCWAnngV9oBInrMLLpdCL1CEB1TEmQraloxYDhIYs/NeeJzbU9hF+32doM1SKpc72nWcYGWAUQOCIvkWwNhGr92NrgSpvZmopXBdXeUqvONqa75BFZKaM2MFCJs1DZjCwhQYgq6717PVtNrwZhde7Vm60uKw86So/JZavJykNNnxdlrMoqxBSX7HuPmNDxCS+S5znp7ku2Abwp2IoyhMDUxo94ZFN/4zExuEvTWditq6kJJSqmIN9oMsHIJOpOaAjUFR8s7YOlfbC0d2Rp62dMvxM/4ptqKA8STmkXaRaDqWqpILUF7QV6LmxJCJZyDQYJrycHtBo5pCNtbquyBcbCHjFAZXlB8UbShMoC/LYwOy5RlXrmQ642IedpEwhRAiudLgfvIkVw09FHN4VMZ9jt9VvCFASoWmUSTmn1DNOwzBRkGvwqI+6rmgb5fMj3PXA36U0MlR84Sh33BFZFIFVoOAGp4objg+Flgk3VULZIRm5EQdHHGHIs0+c0WE2hGTK2iWkojmxbIRVBYjDp0IBk7xomobW7EL+d9vatm0ODJLplFVjENzEngZ7Jp5W7Vp4STdXtcjE42SWR/Ae+QGM0xFfYUl9Vfcj2XipNLagguDV8XfHbiZJKlCTNQMou0pAuq/rw0sGmmj5LJwZSBK+CsHfWFp5prXUQxeaJ6Mvpa7dDcqa7CR9SSTuFWkx9KJCpZhnXvdprILHI5g22yIk6Vu3AStYho3J65ocrsBi69fz1RLTmujYb3I+QP9l0xmTbd1jieTOduDarw3a+7ddaA2FV7xRYtonR+FTVHRtbNypeMGVtUtznAWNaUZiSmuvYdXm2pryzeK2rL4KHyCd8xhNDHoFxx9AV64ufGQDy1VHTydtoKdcKpXy5SOgB0yY2reObK4yU1K1/S0sKxzdEsb6OjV5gq8WIyMKtXCrWyKbydNP8WHgdBZ0DI5o8G+kKMoNexcK0SFxyPFN84O4JX1led+TyWuyt6ztChYk4Ybpa+vuWgMcTm2QnZg49qzo4JwtmPyIeUXx6Asl0kOaKDmulxpUofoTcqiLyAnQC5CTJCzzNOtlUJJvKushNFHDe6hO5OOF0sp8XmzPP4YsnmZGfVjsCVGB2q65rg/+zt3OTHG5EN7UpgMsgHHUykDRawjMftv6u2fMwfUdmcz3k7cQ0p5HA5gOEdpIWxy+/wGixpCcJhzQqdizzemGSx+LHy+Jj81vKPL+dyMO75kPLtrZbPrS0H5f8T73kf83lnnT8f7e7fUqiydTXmEf+uoNl/Y5WiW3g114YMvtHBbr6Y1xLrGviyq4zYuVdV/UPCQ1KnejfNqhl8cplDmrJeDi9cbNZh5O5bkEzi8cZ6558WvuqrzeE/KcwTU7OgujTIJoY4sdPXbd3OavU/JZTdQW/5JgkkMWyAub47BNPmw97HxErdWB+lmsrWDWjGTXaBBdCitkc2QBT5yprXKw/WenlFHUM/mkZQsZjk+HXpFHMpiov2warBS6LEAey0G8lWp/Vis5ngDSPsm8xl4fIq2KCZXidUiRh/03E4njoGzYQCUXCW3Sh1T6vlkUpBRV4MfpdPidJOYmi35W+FovbxWJerFXiLtd8i+36NnSqq3nmCXJb+X1m6A0HlXcW3RD8ZRkYKd7hQh9HJpeBILsdCaydOfFsh1a4KhRm/ve+8FxpXb6eYPJ3Wz/jOvGHSVuSJG8RwWPdGHvoBT23Ojf6KursG6RvKzCNXE4ZW52sLNMNfWktdB0KXO6sTo5gu0W2C42YWXm7vG1ZSMjhSJVpcmbStTBmYOcMxuInrdi3TJPyy1bptw1+S5dkMrKQsA+jbUB0hvdy8c5ttoxZiRJATMha5RaPNvKNMwVs89CvrVx/nlOVJfgvz7Ja94IraKsBPTWJOKJd+jG99CSpukKQ9EnYKk09YI9W1V/5o6R/5QJbMhyJWpLyktKvSoVSERVFuYywIhcGWEIyLklyqQaXaU3E/WJNzktipVgto74yUCpVuVzB1VKhWBA3vkX3f9rMZhc3+bEgEDsNP3lwmbT9wOtDm3PYEccvqpgnCDu8FXS1jZwFjHRLgspmmMSZBQiYmAZ8oJGJlJww/u/6ljP75E/zv5QrxuTDBQwn8Js76xnEAhIlplrCeC6wL/1aWXhiEgv6Q949Gd8tKSQsWBU/bs2vE2b/qYeuUq6Sq0sdg2gplSAx0FjV2cdsSzTE9k9l2CbMG57+/SybN7FJNrMIj7RINJ4wRjZEUg4FVUm1EUVX5Y2zE0Q8ixnC4d1lTZAcZHqBF01E7zVFmpMegx0OK6QoZMnGdzq6DcsYu+w4RzCbgyQj3QCVWo74pHufCCWgxHEs2xhjUu9rkdxaLpH/IW5XpfyWuF3OS1vidr4sfQNRifTIGsnUJaxdDvF7zEslKTyL/t/QaoCWWhmoqJTg/8tAC4/VgB1kiXtoXWzVu5GvJx1jD9mYaAWW0kn4uAJwJfVhqxP1hH/Zr08/UcyJlVw+z9NPpOcvSHyQ+6M/ZUNY+WJ3F7XBl9GSLgyXUzCEFuqJkOXSIO6EIveVyN1gFjbtt4ua4WEsFjppv4ukTnIB8pborZLoIlreWeJks/47yJhwm3v32Ju3wVls/5oEUifgSuP1sSAaBRTGjmkZZvNlolK5shPM152AxEHrCBgqYYvLZFbiMaWcWM1J+U5e/FrIfy3lt4vlmlQs1kocNkOyZnRMR6d4rmlWIRML4EAzBtgVd8r8oP0+nhu6kjRvSV4QWxs6frEbZCI4zmF0glwpFIomIxBw3gyWc91Be/eli/1r9WqGb2RZf53bNb1Sspyzi/7d4YU1mjZeHVwaHz7aj5UTbD9OX7VXVMMHj2KtxpstghqQwCCjCBDuLGVmiNT/ilXLwDXIkV8TJyCnC6rSwxeOAwogJjTYh+C28WnmSQb+yyejKttUZVcBJSNNdjREIiMU1bIhZC5NpS0blqqTE+HImqowVCTDzrEooSTNNlepz5ErAykO6V85d1WztOrbrtJmgpZKVMElk/S/5cFOHyF1pz/EOWuMNC2H9dxU2i4FZii1UOhHSGOZ9JuGzGHwR2OCdaTu2PjFzlEIRVUf5pCCcqKYJxZLYCA75Kfc2NFsFbyqIX/BNL8tZl0Vrv4vg3p8jRZD9jVvn0PM0zz7m5XmeuQ9Wz0dPUsHiV+g11AuKg3ChQQdIxNb8K86HPWpzzZwRZ67ordN/nNjhKze1PM3/R96wDuAOMSBv/tEQzZBLfq6oWN7oKkvbCrgjjwNvDgS7guDXadhowOyLENWyduavCspBKZhwSAYC+H6zoVxzTw6brxHXRYq6ItmfTTYxuSYr8n0r4DoCrEsn3pQgosD2ZQCvZW8ncbviyHksCuB6i0ZWJy7WaA/doNGqMngee6+h4OPX3G7tMX+F/PyYLSmHZD3EeBjYhzT3tAJit+7oF+Atx5vA8W0ILRkYpu/ThHCc/GRDTMhaS75KfzCgPBWw1QYPpp30wAuD7tv2ZUc27CraFVi5Ma1LFzZn24d8gr5YK9BxqYb3ni26MphxR8hi5Vekf9ycNZ0Q48ACHiGdiIHIk3b+PbBn/9k/rzUU/+DRa/EopfTXf+NDN2ZfGjzfr42j836r9XmEU3D6m49rGKL3DlpqxG7Df2GlrBhLeuKl9Tr/Jd54i1H0cpuXbFTHxKKYsv2H6G59QceHhk1sOnOGBQ4E+IwFKzlkc2rZdkmv5YvM/Cqwa+s3rfwxn1nJOek48Nl/A4X9xOWG1lzXfbtWTBA+lcg1JHwSgK0a1Fo0ICLmiiKCCGUk6R+P5fPy3KuUFCUXJH8h8l/ETc1XkrW6M4Kje8DbvfvgdsNLSyFgF/Wf3VdfulRJ5nAb+HzFb8uUxw6WWj3DZWbU+0NIWeA3HLOnuUiB38vRUufwSfmbfJDLHk5mUNH03sWoHVj892DUYN9rRRaldTA+8b2Lgov/TnsLvUBuyZ+t7iPtzG81PbfieMt6FP0e53wI+zDCgZSlIzLswPCGaN4F45mC1YIm5szjYTJLpnCLe2YrjWy+O84omue3d83nDjLcmWPKE5q7ZcEFWdAr1lbVHFw4H1DQzlkwbsaJPYnVedI7HXyO9X+IV047HQuBJoslQB9Cqrl8lpEES62BLw93CaJTGhVRpy3+PmXF7ck9SEhaYEEtvO8YsWXl52SW3Q7bhr1Bb1lDioZ88i2Jzk6iBxpfsN7BHLs5uyhC5VYmtgeHXGP1o2tBmlhK0jhN45DZpysvqHMU/xbydR76C9QmKZ1wjOYHUWFsmO47ag+d4wmExgBgHNTsNCs0xOiI0crQ0o+QsVKbZC6Wxs6wAobDmyz1drRDTtHG9jaAIP9qu2QujFdxAY5AT8yhwplJnZhsFCmJXhrK2zQb2uErOQPPivhER3bxbuwbyERF8k+2HcgQxIRbYhFBRGP1evOfq66LVyhGcXu3BLAoaNczGEdeE4GgCpQGMC44gf6x9aGy+iSTjqlnABZB93LIiw6eupJq1t+z8HaWeaLnq/06UIWS9Z21D4/e+dZIPT87Enwz0xc7DYoz4O7052QxVOwaJQ+S4qxcVI1C9GUE2VcObK3BahCNj+kjvppS0oIff8llU1MXuNIy5mGxsvR6z7WqZYXCoH0QN+BNL4eKfSxQ/JkCn6LJLvh0JhiU7eYy6YBafe+GzMdmyT/YShYn3y9JXxHto3kJyiBbBuQzGiqNSqZuKW5FmR38khLYCdmLS0evIV5eHSN8FhMPMAm1mXM8MGF3fOTugBN0qGzxsHiSobW1d2h+j3RqhoeqrY6DiRxtbysv/74u3qwHswBnQ9gw449IkoVhU1MJlxydzoWDbS15+t5WZ3UQATXsZ/O+xKth9c+Qx+RDZ9xoeNCZDyLHHwNT+mo1Mz1w4gYi9BLvMFTGqYmfFZ1WXMgPfWXkDDOTHZRpDnfTOjFuZVLpUIpEOhGcMpVzgV0Sku8S5eRiR+TnJUwcP6Mj7E9Mjg3A5ld+mPaAT5odja2NvaaJ81Oc2Nr46LeaRzCv+dt+P7iupPQreHYssGzVZ3TH2AKkC54DylgRk/fSRJHi5k12C/CBP5UtiA3q6rxiwxIQrEtyPAqG+6UB4u6DEEmCbzh/sBg+oZjH2oplZc9wSmAPGfgAeP3kzADJp4YJhdalDArqIBN1Fc11Z4T+gRaY0uYYhO8k1jU8cCx4YWHp4bmREhMOAV+z8sJrbRebirRRz186NHSPUZSfDQ39AdvR5NaAq2VNplTKS478Lt0SUmd5pzljMfI5CTMO59CkhXNo4yWWzyJU2wqqsxZP7dBVsCz+MfWE/pYbgHcPuM+PPT71BmYSsmrI7lUpm+9DBi2SdPcpj+QY61BBlY8oRcpODuR3N1Lz0ZkZUEC46PPuxintp8floTym87qofoxamyaIyamQ6LEubTxV8jGvMxiV1QhDDPmog1DwcWLMDHxQCOJhpJQaElqHTYVoO6gidRhUQT8guUoH1nD1OR8MFqy9pwdQraEvzqUkDd4w/DpgN43qJUy4QDfBA8upP4Oz/16j6w7Hckbw1cmJukRCUALmTdXyEdDyEFlM5bLXkvZAdxT0RsiqYQ48A0ewVugiNSYj8HMpVAeYfmJByIUeGyFuzwGh0g4B8FreLl1iGhkQQTug2WMF+R2zn6hHqgCSVns4iH5MoU72Vz5LKbKziLvxCSN5YbodpFm995yX57e6H3SUrZg+P218N3gbUaS0XnhduP5tLT23BkJP1MzvW74D+QreBEnNrrcXEdf4xzzOCMjZVa97Ggc5kzn0JBlh+TWURySsRxlvAGWOcA0u0OgCPdg0vQR/BxlZ84YQ4we9hK2eVnUPeciDVmWh3u+JagD3/6ajgXvqLpdgJAx/4nD8zFNdfTgT3/AH4VrE6CKkxBjXTzzoMTiXeW0MfiVDl7nipgxtuHvs95KB2+FCzJy1n9sbYwwUrBJ0jly7m1Q85OlpcVCWElYt9Ou78guo17TWV6jyw2LNQqJA0xOEurmC5JtKotCFo7rqxP2Lic+0yPDsrdI/rJ5wCvgiz/VnqdFOmsyVepPbaqwwD0ZTeDZxpnPG1ZEcIsEfDm8NOMgNKxPMHKpyrEu43Ism0I6g7FtGdkivGGmnsNsxrnAjGdVVPNPY9zmt/yeCpsV33JIOKPJcFCotihhbAFV0vIKK2aN5evfg81DiTAnD+b94BCQFNEQfTPRocU2FVnMlH1EJPvkTC3kdUMs6tnuUE8S4/mUe78FFnIpyXsdTxn/YfDjx1ZixhHvrcemAMx9DiR5hWAjIH6M5q6cLqA+gWyBoAUdCKEQhirW0nGe3vQeXOEezn6HrnQFuhRR35XVmNO7k+iynsjpCWxb/lmJMXvOkXHLgCmDFfNR0WKcM/0cgcmzB5Bp8Y7AOneB7FEs5BL4COuXeb587278j21V6W5854qnOjfuwbtK4We/IdeW0Utqj4+y7g8kYWKTFAp1VxcYU2IT3Zqnv54hE17KsQIKtqk3j2pZDhjuuWpsev4D6pygXpssnokRRW0DxTq8LEC97ZK2SLHNiFuo22ZgymRG4LslYPpDQsUKfCVqJfxBcSjAJY/z7p5gHVzHaHOCggeqrlJjgeE7ljm6Am5mcGEEDYddnVkOVQr1qloyWE8FrCssXRGIk7KhW7bpyLZnOgzZ/vzdC632FrlKwRCpnRmwNuwe1qeqaehjrNu9pKgQWlQIFAVyXeXzchY8frdB4gPTHRUROcyIbZTgSzrrTtEMORuyWaQ/tyOvPkluTP/u8VkICG6u0oDKIwJ54xpPKhZmBAUpok9QLWqKHWGFt9zBAIE6sw17xPBpiDzYoVB6qFZdGas62b8kmz0L4+RvkQDlVN31mbBJVnlLsBhfto0nrH/ZFm5N1cY5Q9fm2139DMOuDwJluZcDd6uHUqtDbLMpNO/qpxcnzV7n/Lh5BmwGmg/D3FkA70fy0XPFRcadvTWNLqk7+gwbEMBkMm/CNa3VBQUigikmnqy+HwH/HkoaRpTXxvQEwOyRoOMZzxRFmNt37yh/F0Kej13dwhDMEbiTiISg02ezatM3KtBJosrAD4cJjWQXpLpRAlvLeH75F0vc5dBnST+WEK7SOuAVpAwxF2CIK4c4Ra8mm6bhS1XKBTfRKcjuE38nBWhKCjdf79Z9AOAH725aii+zaaTLxT/brFXe1meHhSd0BTiby5Dh9qPpHpkrD9OrkgYBxBPOQdCZR/hOmAdxgZp5nI/sej0j78sk7XBv8AtEQm8iflrp6VDDd3hS0HqqIvHtHfyd93N6ipi1XtkZMmWQyY9voq2F92HKKcoFFy4WcZE6lbD/DcceGnCcPHE35VFBF4v4QMJaJUK+JVDKtOHLG5Ya6z5N7y8HZN0N/OVlOQLYjZaYG9cLnHHfnDSXAQtLe6sRj2VqyPj0yDbg2EhJLt20Mbr5fz0NBtanWDMm1CtWQMJ3uCq/u2MWzt1YeaurM18JWCQMKEssXK9PHZIZaFEA7DTLHfCPCqpLiwOLSSgLQmQXKJCXidfLFvS93szjGVhdFmyJqBO7EtQfBLT9Xt4FGq2qGLIDkiG9E5hJLKaT8AINOb9R9dli/kt0IXRioxq2OKasgv11isd2bW1QhIsWHTybsghgRnACJwD/lKBdiEiKk4kGXvMI7HvkYqCwBdsCvEMZBKsxVRVQTJJXDcPK+J+CMVZt2//axGMQxB2d/p7BQPV3Skq/hyYjpKsQfo2qYuGujKgcfp+d+TPUG/zZSX9X/7QZ6updnWhFAj1+p6UFy5mA7ynoQ0xMzZ3Y+trVc8K//83a/fe/vwoaRlPsN0l/pzIG/CxrGJnRHEisUJfu9O4GKcnwn6HoUJ1incHBZxAxllc0COeAdQmgl2Hqt1wq6AC6OtiGYAQk4pjNMriqEtIIXDVdigWn6+/RXUS3M/y72iOlDSL4258mSSEGNyEFIPN8Z7KtIqCBzUQ/8hJwzcAWs4CM0AQ27ATriiUYul8QKNwWLljWD6InIfEJqq5aIyb7c2N03mYOZYOMmlE4xhCGyMb3xE83u/DnN8kJwwVN0dQBluey5jlEsOt3UZ8sUzAxroyw4mjk74lGlVTgWei4f7mzy0JPIHyQT+sbrUbE6YhEAji65Xo5rOsll0Rd2LjEZjsm6cXvi3fQvzIGR6yniqKyAkzZvVblLHdV4ivyOyouHij8b/L2W5tiOKjpStIOB+svipZtaIajDDRIaALWeN9MKlxbRLz4zjGLbHd1dtI1F2OWQC354gFhgt9fDR1/Z6cqg0UEimeaICjIpCWOEcS1f3Cg+DIvQaSH0G8M2y3LC2vfoQFWGpIxbF64JZi4oGlx96KPt9I/8q20JrNufF+mvrHWszd/F2MwG/wyT6jYBLzDm+If8gBYyngZ5K0L5ZVFzkHkzoAu4I+ejYYcodS/4qCQYCNq7qSfWIZ3zfBhwgE33NHtRSdeqeLqQEZ5RRYH1Vp5oFTkflHui2JB6qN8sRZVfiYAO3mEwyhmaJAbIx0NsZIzHQ1bPaRpxgwrvTEE+scHtwfuW+wu992R6bvcxzBwNCwMTcNZ2XU+ThfQE0ncSpiVMRiAJB5D8FwwMvqpZ5vIlTGzjpVU94YqsxfIbX2fDHu9A+ZQuc4p0I0x0jh++ysNXHBVRIDKQVtmDpVw9N1iK3s3J00QG8Map0XB+jz7xnCROSeGZakwTUim/upMqnEHDtKMLqg2wXgx1eEQ/MLXPBkxysOz4qbOIFIxYfVbG5Y6hjRv8GdfM2RwQJVHSNOwTo0DWWaPLkEPPnEtXLo/4K20rUFeeabaB6xFsokEg4X4g/YP2Szpgp/KA9owx6qOiQu458GukpYsVSGu92OkqbJqONa2cG84AtW00DxmVLikSKHQNg2iM7E1MjRw6zUNZ0ijUT+5QpRqzz95OO7BNZ4g+QkNuYFrsfdUOFB0YqqGqRJ89zDz3doYU2MNYaUEk4/0AS92sNuoNhVHE2f0LYDP8XVmv4Shn13iFrTm6HBJKy6khIkHvVIhr1T7tUq5WpRrYiGvKIVyH+EqkhUF9welDe+JvhyZ8P89v2TOJTucNSQwlUv3EGnJXb6l2/Fq/oiu/NJN8Rn7D7aD3shaf/CP/fuCUHOIWsEin95KolneZfCznwFLveT2DlReGUh14WquE6v4r13Jd5393xbLOPtyZgY0Tm9y/ajGa9sUa0U3XrAtaHTlx6FcwvvJR8KNWr7CUwiwsgklXD+adS4rwMHG3Yo+ZLPfUzaLZ1jirWn6oFJfkPGMQi6GG0+NwlMM4XKlgktVqVqrlpS+lK+WFBFXxXy+NBDLuJTNKy4+JvZe7I25YCTBIbCS7O27M2bQishTifjEuq9MV6G26lOUE93HG0GKAtUdAHgA6NSOp06xC0wH9BMkpfBKCIqRALTqjfCAlsOWOtRpJMTENOBp5sWsty7AtgmBuJjFtRN7mPvMJbCn84kK7HDup0ZF4CEi7O0ZbQZBanFM+tFJyrbSHp9YSh+93ImKsKZVDvdCzjE2FPhb6bnlWXqSpV8/8VYCCvHlWiO11srV3jS40Jj4L7s3MS6UoA3hHBSUL6EaquCaLIpoIEuDfh6L+WKpJNWUSr7UX5VvvXO6uATddOpUEQV5kK9bblY4avaLsHuBaM2+G/r3rUANVo7yIeAYrh4L5mPHsSIYT5wswkTf5EWbB5SkGSeWr5Lm6/xcJzZvEK7GmGpDg6l4iWqU4cC6QFZMmRdSKwc6FT4TOr5wFcucvbaWkWfRl5O7j5Vk65g4E75ueJXZyKZkf6e5WE5JTuUCetUlT8AEm3AN0wnwdeSJOwBoyLwBYnLHCsrwzPPDvYSSpyeQXYwcdJaSxj/sZOJG4CXax1gX3B48qBDV9EQwjydE7MGcnFoBziCuKjnwjcShwQVcPLJKtBemAQKIcGjoeC5cGFSLvgp9wRdAMo2GCZ4nahB/EtByp6riIM3fparlgaW6a0RCslNHtRrd60hdFxyh/ZPS2AX7lH9SSruEo/Ru6e3i87r2VHd8wcy1sGXL8LPAUrcol068eoD5Uv6/hnaoNEEb4gtXGXQGqz2vOSZ7Disa1Ao1BRf6uFrE5TKulCpIkRW5X63UxKqY54ScrXjgYZiEifQ8+fPDqvJLrCoclfMbrfPunqXv7KWySi7QJfK2zYem+M1xsr+p5pis9gd7+NvYA73+3m2ffPCDv5kfrPTCZK/LkEom+oLhpURex5PRvQxdM9hy24TUSm03k9KfBKw6fU2VeYkVsomG7csTQdUfmfKF4UG6wIbt5kmz0aGKvzFLPfe2+UpU0ifF64TdzJgvWXDLfPtQ8P/lCv71Opa9zaEsydywzIMuFK3LMvYkp7haM25I5pfsQifYoBoz4P6KHIu6pA5UE8+I46shqOMxVlRkY4BDg2w5elBhQ3LLKt6XwMfDGkChrgufCG2fAqrWUKPwY6hNgrpmCAa5Yl2VJNVQT0wDLivqury6Y2vItJzRz7WTov3/8HT9Q7wp1u3pyouPeIvPa7y9bP4ffN3YuzICZ5LGCkJcIKh/3xbqwicgMYkf0HeD4kYnpbYOmPuOF/RAHT8+g/jDeO+W8IlYUj59+ROYStig9MFT/pk8hRdFE3WFWlYyDtR+G4OKE5fEn1igZw6cSPuOrmj4Z7jsc3pdVT2woKnFSpjYtPwCD+E1u41nX9Rc/mNZfwrc4vsu57oDMX7BQv6d54zEaPzpZ+zvOyvrCZuRREkUg3Ez1/qTbsx0lnmRZIsE8X2iYQSSujmnvr0rhNIssepLxdMsy2b/4qCa5XbOcoeat3fE8N4BGBoQeSmoisDycf1zN8qbGcuv3iCFN26QQi28QQh2r05w0k2S3Ci4QxgO7z9pg/y5nGT9ltZfIXiv1dj5Fwp/dJX/eOHvp63zHyBJyo5lG+Oc50qfYoESaFni1W8MwGXfBO3cDmQXnBmmEsixSFzWx4C1LJxg9IQVIZAUozHC8hMgF2ZN+bDCunvjydF87S6NycPDbrQJoGD6ySIBZNgCp2g6HDcswRszSffqBimkmuI0w3hyJj2S45H+/Hlk25NttzLJdWmi2ZbQ3bCwbGK7u/ElAevSnft0M3/24bjtvdNwoPmkwfxYuDddkOOkbdkAiFTdFtosxZK7T/1hv+NGC9DobbW5ZqB1tOe2lHGOcjxcV45DcGvPz/Kdbe4CkWuFkojEUlFGqFoU5Vofy0q1Jhf6xYEo1Ujk2gqDDmvGl5iZBV74ZCgyGyJ+sU0WjhNNBmsbNHOpV5buEs9baO0HYqBqOPl0p0+AbUxUefENrKE+5gQnXdM9QH4NIvwKpwDPx0LzKKosmAZMGZ75GrbBe1/4jP77v/7P65ctQVGHEP/xWfzv//o/tS9bxMQ1mk9GWF8QjAR4k6qdk5GpWGHfg7wYehfmSSwCG2l0jWNuS6SkICMbDw1zzhvMxFR1MstCvd1otQCjH3ZDOCYhkWABCGa+ZBG6S1G6Ixc0XQd3MItvYlKOo+6N4TV65aLI4GTXh2ZEZfB19ZbQxrIDxiP6eTKxvD3vXZlvwWZbtG1/kLljT7u8mMbZ/n/23oS7cVvJF/8qGN2Z08tIsiTvfWfm/9xb4qS323YnmcT9ZIiEJMYUqZCU3UpOnzPf4b1P+D7J/1QVAIIkuEiWe7u6ZyZtkcRWAAqFWn6VOcJX5Wty72fGlE5q/4j390Z8zPmRGPXdcW/PEQdHu8LpHzmHB/tWhOm7Y2wru/9s2uWnqXdelXx9dxHHllZT/YRFev2aLybrb6+UBN/IxbN0jv/p7LdrcR7bsvgmrcD5dYLy4XaJrHbV+OaMyflV0VSq+rIXwy2lr68TMLBqdmORAFLEP+PE6qF/c3OqUx79s80oDfzbnM+v32iw9ox2Bp88E+6G59Jks7nsiDaNgghAjsAcUjIrGbzimAaiXhVLpS1XfkUoa5uealZ7audaKyFclQaiLPlaBkBFArUbAy2zeNxi6E8V3nu69cOIBWFSbl4BmCxZX5Pls5Ji3tzS1dBfkiR5NXM9KVSkWnUTPo8TCQoknUwgOQ27f3r2mh0d9PoPlIKwoOemzlVrUga9wV6nP+j0Bue940f7h48Gu93+fm+wf/xriea2JB+ShSrhuIools6otbHiVGHSkzoFWm6rbECphB3ygGlEYTgbpgnthojCbNlUmE01hZFR8Dw/Uy3sbRjO2Il7zQNIIBkvRkY60ZM0Xd40jBM0ZIFGes4TUOnPRgC8o6ySCujIi5nsIYMu6pAMjphbLiauiRD5CHRvM3wIH7moCpZwXiJw1QqDxijbTWUfVBocpbTEWBNsxMV0UBQlYvasMnFIdtNAy0XKZvrUnALsfhDqAccPcmNTw6D8tx4Ch7ohJLhtw+yoPyGnGalidcn7HtiOodWzsxcUMcz5mdypXkyLkb0hB0M3RC7nBY6/cIVMbTkVUA0YVx7t7EAT8Gf8aGfnQfUijqfhfNCVv7tOOCvZxTBnRTKeiSTWM20ilcHIgK60Q/FRhq6wRM/zDxWx1aGFJyScI4sR1B8zHrMb4ftddorrC2BSIW3HTZhdHDo/KpBWFm4X+6C20wz6Gs+FAxxTjYR64kzDWARd9rOaclyTfyxEtDQQnLAXMCUyA2HmdLHQfAeJvuPAoRQukgwo405Z8s6cF0aemdx1MEfa1HpCpb38JxUAC7Afa+GonX8i7LQnnwgv7dUnwEg7vxtcNNXqXC3BIo9P54mw2fBTZcIG4TASsl/gwlODdwGmuRVuEe+r9+hmgznuZn+Wu3NWaUZzu/IWN69K4m3y+vwNsLfNrswvOONI/Vyt4NG86rr/VvzcSyZ/0z7Ln5ctmVBNRS/Waq/Vu2BilMp4yBOZ2M7mqqJi6WOV+Dj9Wu+ajBhLn4E4jfoeJ1rOQUKQpeMkjNAjEPwN78Xqqi1PQLMiuKM4U5Cx/1iIhYAchl7SyFEQ5OzYS2xCTDoaaO6Mz8SZlxhjUqK6dUQ/geaAXfJFEl5qkTyJeBD7KAQBjLbPP1zCdecywHTfrpiLAPPFe2P28OGJf8OXMWQTZ9+fn785e/jQUIp12aswURkEAYqBbmDX1CrW15YJxiHCy+g0KCdCvOopNO8Acjdf1iDcL5IwI+vLBwqEWv70+QdYyJTUHapxkjK4aepYPdnz/W9CdKTcJSIfO5jPVeN1F6pTUwPEkAvrTCSdJ7QCKZN3W9GoeY0picmZzlwISHdbyZUWwCamiwgFMwbDs89U/rYm+UC8GI+9DxYF8hzGAJv23vAe+3fDyxwLKCwOqWgxMgybiqF7moGAhuH+cOiMh0YfHuAl+jLTk0ugzUWLjxz3oiXB6dMq9DRf5usaQolLyYEwdzdUpLgl07qNy4LKq27HjBw3MwWlzqEGbSFritCIK9Wci+tbctNjCCExuHYfWQkFJFdLDvzDUHSvVI0qh45iyod39VrSovmjTo42U33hZMMFijex4TSZWZxsb6HLxHUF+kCWiNkceD+DNhh4DBsJYEdwlQsoz6vSRboTgQs9CFm+i1DjnJLOu+1M4iKrUgqcoklnpTvhxSkODuj+uDMV7L7WvKlH3YmXTBejrhfusAdKhwrbNRZoKGHXPPKAKEb6H5nxQbhstCRlfbrLYVCPLoJ+l/311yX09dybiR8hIvny40d2Aj7avncFKYSk8CKPNKzc5L6QQGDKrz2YipAl/ErmJYY6WeLNcITAhfW0tXHeIG0RzBN9jdICoKbA1w8fwpZ8+LB7EQwy/XuOKZUS4UIfn8WJN8PRpU2pBQFySpc9N1GDxpCJaeYFwDG67MTHAElIz+Qv22wp0/guYiDKbqZRaCvVb8ga4E+R7QCZ4rDli2AvU8X34SKKs/VM4VFlLez+5UtQfY/9MIzuq6p2DnoPLh90L4L9QgsvqWv2/vJReE0q1Fyv5Lze14//7aCHDRxgAzgxp/Hzhe9DxU+mPJhQ4gw1SzSBQchmkEp5LsK5j8INarxdV2jYJ6yqexFcBOchu/YEIcSNF76vNVF6EbcZeP2rHXjpjOUWhx1+KaMIJMzmSLhsATuWPsUwAe39KvnaZZpgGfzW8RKVZRryNlVjuPrrr79l9srHj+yvv9STjx+B2jH766+d4kf/O//oHygfw4pXmupiuVWPLYUKpJjL0OfBZGHV2J2jkY/eKkuLYl2ot1N1KM5XWneBBQbsUgSdd2eX7P6zYOJ78fRBlgFWm+PizrOzzMCxMkNm0r/1l52nz1rt1jjqPH+LNpzO6Xmr3fqdd35402q3rsLOj/B8nnQew79/TjtPXtG/5z+DzOV3Xr2A937nDfzruZ3Tp9DHqHMO3/Oo8+w7xDntvH0H7fDOKTwfTTqP4fk06nwPv5248wTsly7vPP0RvvM6z09BFk86L6A//nXnxU9wxYs7L/8b2h11Xr2GesPOW/hX+J3voJ6p6JxCP6Ze5xT6OV10vod246jz+AT+veqcQf2x3zmD+uPrzhmMP/E7b76Hf6edc/h3cdV5B99fe52fXpUnmzGXTwXM7Qkwccn/DXaJaYNclza/KxLu+chsFknhdlCboAVMrGDJ67Cnr9mr1+fs5eunp8//e+VdQNl3hjGJGcNIBIB4t1Fp4im1ETMQ4CHNn8NkM7CZZMtS8I1JSoaeXsIlhHHHEXi9RjaPWwMz8agOuwpjTzHvJGSjKLyRCH5wS+6yk3GCLI8nuOmWRj1JyCZhJtl8RhhBXBHqE2qAoFP6Zp/peWq5VKPE/IE4UpJYQPhYWsK4ynVPeirl77rZlNxxGEbexAsASG7GA9fmMaNPEe2vgkWYKlJl7lW8JRLX4RVmZsqvVDIrywCb8nAOPbzf8tKtPuiHeBC6QyC5qSUC0IYJmgtqaaKrItsFCNfX4jYVAs50A/n7dEw3aRSLoQytEPDViTy3aKK9F7PLfK3GWXwzBeHbS1AuxzHQabPw/UIbXjAVEXxaEy24wSP6GbaOx5vAOYNh7TQ9ufNaxGZzcAc8GCtuzHyJ5LdkwWos2BXruvoKJnC1QVacOrU8cbWWAnFDW30IBlk6I26x61W1ikDDmUimoVs9SREP3FI3j/I2lFz+7dgGmtZeoAPUf/fGAmuz9V4LqP5yh6upgOAGHid8Ni/kJfjYbtl4wHq0K9S0vgatyHI/6uSNto28XofLKgRdG34oAheJt3oTuqSuK054lKxZm1G2IdZvvgYCatDJEDa4fpolUsj3RyVSKGOZ602otTZEHqZT5laTYKvkY7tl4c7rdT5fEVqAsveO9Ssv1AS1TxfjMei7E3OZrbE67fUgD43B1rGa2lvWoYtqR6C8ML0eJSx1FSw4NbS7/ZG+0dtB42v1OpeEkso3eVdIxa/1JHOTS+fE8oApv3immRhJ6TMeXcV5j+YGAvmgN+h3esedwdF5//BRr/eo1ytzjbdy4UrhbbB/uH8wGrhjcSB2D49472DU290dHRz29vq7h/uHKzT0DUp0q+MX2U7Bj59KtrOjVZ0oN3jlmy5BLpbGAmSk//LnUx4sZiICWBMN3tJWsDNoNUf9euyQF0gkmIS3r17Dc32pHN4IcNOPqMuNl1fZqX17dmOr+fa8hmyMcClHZBzlzGBsemi7yJRN60TMuB+HOT/SlFXP+AdvBqqqQX/vcO9o92DvEP3e5ENAAV2Pu5XILisyOsqzHrKRAMWbvnLDVRtHykZiDEqKlIbYXEw2UdUHioHAN2ABgoCFJGO/U9Vc5uXWGlcAk6vup1x1PYpZJLLbL8xcpXesK9O3+PUo8O3x/tX4/Ce+xd9pltZvwHd5G5qxDc24dWjG7VPxlnGJ2/jWZ2r6OtV3X4/abquu+zbUdV+lmu5O1HNbtZxNHdduJYsoiBMvdcZdvd58DZlam2VlK6/TzHFbO6cbuX/ka93kBcRyi93tGbfX/rr3kPKlXCCINPi25XVUCgr64qmDEKhGl9ENCdQk0hOxeONkb+lQl463lxbOcKl8YGF8qSvyIhbjhY+SZewlCwmlgHfoGYhM1Efs0++hkmmQyLrDslsYpI4esKCtAdeAGx5gUIkcCXw1o1j6GGIdxtyLAhHHXfaKJwsAWlm2YW5n/Ep69VJAuwjIvUCH4INzvoAi0nEXiVK4tbqLSCGgU4fh7oLAz2HkCnyn4oQePhx74/DhQ4Q0EL7yccJuw3czviRUh0CAuMSjpfVisLJbkeX4XUOrS0qKjF6XnSREJyjUJiWIa86lmZ4UReSMfiiXa/lcN4LTq9AhtFokDJRWJKcUUbLGSiqR3dUUzRkOnwN1oFcw4aQtRLgPSSHiTBjzJL3i0pUCW2MShOh/DyljIz4GRAVFuSkH9BU3mzs2F4NkEnBza8V+DN2e5VbqA+9UE1mjBf1sukjbsbwBOudqvRvdmvQj9EP45QVjL/ASQVJdqxDruzpBlESxSXJAnXdKjHA8RmJce7E3wizI8q9hEAZDzFVFDRlvZKLadWhWDdbD8mg9JfgxZWA9a+LnaJCfJuBF9Wg7DcB2TJJUIaGf3hn8eV2vrKEaG3XTNvyupd4uVtEouUmXpzDFmbLLE3TRfkSrgBDQdqC7MnI0Eo4AewRnP5y9fsXUGFRgClYHWkgIV8JsCoEOS6oMnwaBKJzPwziNmjHyokM5z2Hfn798gYouyeatXZhCTYFIt3U+hoaWP6FwyTIyr4OS3MYhnNvwC8MxYwoXu/QCs55H7LGMD5NBYTJqVg0Xz3PLQO9TyKuOInpAwV65ULSq2h2pQBXFODBppIScmiqC5eFDPOxBzkRveYW2pNdVF+O+0qivRxDE7Ll0gKKom+tbJlKNndKxaPbT3kkKiTN8+xWhcGHhECz06rKfsQtK0n4pBW3sA11SaGh0s1DSlerxfu+NiBzY5764pPA0/W6wb7yzjLqySYqp3ghhpDhhieYb7P+byoslL1kQwQDq3Yjs2WMeJyJO2P3BfjIF/bYcjoyTs5Phixzqfq/pUPd7uaGyUxXZBvmzwIDP/bG6mmRuIRj/+QHuY8RmfAy5l/xGBk3ciBHEmehLhZWElJ4GmslXORKyVsYxTsVLKKJQ13P4xa+6w8ar7rC46g6NoaZRq4/YGZ6rzPXiuc+Xqlsp12Fj9THQTobPYZewH3Si2QauuZulWWItsk328OEi0FwPg2yPuiwT51nFdXNiJGkhMC8MUtZfUkAnTBCyVzxHoUAgbtTyS6SCAYBsuxfBsWr+pKLt1IVACWhySVtPUWwdzz/1dcUa714E/V4XUEDi5N0ccE7LZypVBHA8ObWGgAQmtd3kQY8oqjAHs3lCG41fW3AMobs1XUTxUZ2npIoJUVnDeECbXjVD++0yEuNIxFPYB9E198+EEwYu3CyhS1o9oUAQqWpS/ug0dSwJQxaHYYCaIUVI83KeIVmKt+FgkDCQFeSFkp48KtujqUkvpk/VkDKNLWCrZaSMSqrcjvg/FzRdBlu6jARIT6TEiGS4u4KCBBUijZ+Yy//7n/97cTFU5JQy0Eiwhw//FFGIu7E/6BbaeYTzr/1pSM1m7DlMtiaD/LNiwyne44SH1Eh1babQ8PAhJF2U4YJSEffwIY2KegSCkRc/P33+GkNnGjMI6BcsKCjJ7j/3ojjpnAYd+uP1InmgY8L7e9jEW+zUeo1QWcmRbnAqiGEg2+ZobNX6XGhyH5t8k459vXYN4snhsB+FmEsZzzWggcwvUwAZKbVlpXi6v8NxKD6AK4BxKAKXNA87BC7yYox1epPGOWW/GQmHy/yUKRgupKCL04sRtjkJmetFwoFVldkNQLEDmiRcGesRi1ZVOu2HXd33E1QBlB8AQaogTBd+CDI+cN4uBXtJyV+yAmJEjOdPLY1YIfXU3NiucxF5IbnqIoMEEIkUcsa81WUxCpRiXhni7YaAtsWCIIGJcmpbdbC5obOAg5IukiAJoHkfup0hMBaPM2RwwiD2JJQJEpeNRHIjiJfFSq8MjYNzMh5tbQWPC/8aWnwzgE5SyBvDsYDLM4apPOpal6FFtstOeFZwW2XyzU5l3As97Vd4EfRBvICxvYMTAxs+g3cVHSvbRaViZVCA20iPp4yb40Uw6Nm700BItA2ikbxYOqxUaKzsUZ38OOgXxvQscFed+bVpC2YG6MXA1ouV6Qo9X4WqmbGUETTTkVpywnEr7XYnSaMVu8JWUiJT0fiJaEIFw6e28uUXMpzYWol8+Yg9m80T9bl6zLw4uJekWHnFGeABwTAlfAIcW1EFGjzXtdx47kQkWvcKsc44c3/99Zdu6uPHj5eqFsKMIYcjCjnXcEupCdTWBOj7BI9wfCgeSAV+xWFnZozRx7cXm0A+ktCqMgMI5yRQAEXMeff2BQZy561ZCx8E1Efw+UXiLCKfdX5h3z07ZxctpV42lMGmP8FFi11cQKmLpPM9u2iVKTUvWlA5rOkS8BxTkkCjXOoHyaaeRG83u40wF2pkOcmm/HpPwqm6vWmGL8+uHCX+ooFdtDJ6zYvWI6beJBetjK4S3qEFIX2fuUlXvIdX/Z7lhak8g49s35gqk7JvDhvUozkIfHDR6vcUR7xoGV8bF3n4jkycudcn9nfGBYuaGPQGvU7vqNPbPR/sPto7eNTrdXu93q+ZBu33O6hg0Ms3rGec6ocJz9RlXDIss5G5H9gGUJTm7V8ZEqz9A4OpVnxgHKi2ryxnan5qq45dIpFxOGQoVThfqqs2D6Dqii0Hjx4cffUR/vn4ZbCMjEbQlBK/Jqax34BpWCvKc42+rabcvO+bqEL9/a+eh9AKqOIilv2fZSMFNnM3XKTQzJfJRDKLqI6LlCygEiYCFDB5yF3gRc34BxMfyZsJ6dmyXuxzkzzc+bgS1w7Hkjo6UnBD5mY/XEQWXJyPBu695V0cLiKnQfjVPEQnC0sdhagE7H3aagqEpasuAGFZkoun9FsnPDWrwfzkUaoNVkWzyFSd2Ci9w6ZWkAzkbEb7TMkNCFmNqpaGfkLqJMdRFxQ04ATne0Fqs0obMhoBUkhjHIT+qCrPQunkMw9j9LnRUNoyOxfzvSTxBcFKhZH66YMeVbnlOeEM79FmzzOueerDOTCNKJDWHy5tbTwKF1I4uAkj313Xz6x+vj4kFY776wa6AsXFh8T0iMpGvn6ScFRjcHczJqz1kwxlzhNnuoXdvgXsdrulUi6sXI0uuA529za124ZTu62S2S03FZEAdOVvMDw7J9XIcUrJqWnTZrFPAdOR62Z2g4DSj2yV5J6CGRoyqxAjdcGTG1SYYcQjjxy6ZbV1a0k6oxodiruuuN6RxXd29/n4yOkPOgfuwVFn76B31Bnx0agz2t/d293n+647HjVYc7jkJbxHfXzqNpj0Cw8m3YZvbsM3t+GbGwrfzJ4huEksO7bAEPLnCLFYybcbM9lV+WuRs+YVBEa99i4aTxpI8bYE1k07WywMUAW2/GiNh18onNaYZlpasTZZ8JYwCvYzryLhQ9OKyytZ/1Td/HladZKWQ8Q33rolVXxs69zfTavC7z+2W6XRLU0rslewxum8qXO59ESWd7/GEjh8r05bSPqzSuG00O3Oa8tJrR9RgM7QWZH/W8vfUgKwnv3rnMwbPJM3fxpv9hxudgLjPi3ZFFYKWU67dPkWAjIzGa108g/fz2hFKZtWbKhRuVSipukQKY6/qBd/FaI2WWtiecAmIsmqYkNIsJVkMupBaBC6/GUjkmR7TjiDIMQ0KqoBCNeqFppa4DytNco7PJe7OWNeKvLoAo22Ur2wcRTO8POHD2U3Hz4sVOvF5FK1XozhWzHhkYtacTPYJq2/DW5Xl3o9XBq+vxgdb1itDY/GHERFUREmM1vqZDJZb13QnsXCDJmQzuaxyDvEynxPsBSlHdbMawPQEKSLu0bns9zgULklIwPBneOSPXx4X5L6wcOHj1jR6zvjok1STd5NWw4awSJUvF7kXQtXRgmS0ffykc3p216j8meDQFBzvrBe7pOzL4UAGm7al48g66eiILwwvKNL8+sEbnkowQl5QYOmqI24aEZ8p+/NPOWHLWdX4mZAcOPUUwAcZvZZNAypeABKuqasQ5BpKE1zJ73r+Mgnj+dsNCZGrF7qM+LyAYtDaT0KuL9MPIe0mMBWIfxVqjFTnAHVrjcm+BFwmAR2BiY4YnuSTwVgQEa4kdEi0TAlkaAktfoz7ZlddHLGAAVA3mPXIoq5DGeUURiZCYNwldlMuB5PBOYt+p1oqblClolk5iYIzc0TCS6DxXPxcVXTUkEX6QdvEoZqmosInE8J+QRsYAHwnDYb+aFzVaROmd86u6/YygMkV7Y4NSVST3FYbYYr/RPpOJ4nP44EeOM1dxywO7peTBclD1XqPJGMlAA/cr2NvUnQWcxlu+T1joEIN14sqIexSRHyvU+IkrGwaOgxqCCNv8GNl8RqYAb8gRdTTDaxqLZmIEibzIbXwT5ebDsnFN9GH0UZVZMNy1BfBFWsvTASZMEPH+qtr4KGMmz44cNqXS8MLmMtkA8UDoP8qVFfjXGj+hov6A3yxJXJydlTHFIlq1B3+IJFAgQzOqmkZ6zEmgjSY9NqATZgIQfG+ND0KwcHf8PbvcFxgxFsoVS3UKpbKNWvCErV1CneCknV9AGwkoHeZXMZIwW07ZvNwEtB1KSKHS2BvaqOD7HnKSu2vW3Ct/K+B9YhGE/UlQQK1qRJL0hqKCX1e91Br7vb6+71Vk0Cl/FwsLGtQOFUIAfS/TQFqVWun81cTPIeE0VuEnmJiDwOGW8JDEWtAeUXhfOvuZjCFKgnsTfvxpEDW+ovg6xNUs1hpz0LFWG6T582n+UNpP7I+ooUevRW6FsbU1/hRQt71yr6E/Jg+XrcevRb3o/SC1zxoVj/G587EjaFFovantxJ0gZTuViqC6Qwobjcf7x5fXZ6fvr61fDVu5ePn739ry57o8rSJ7EMj0S5sd9lzyDQEeW1hZ/yRfwhkvRGYQjk2fpYGNzwyJVRVt44QR85g0YANKWWP4iuN5GXJCJ4YJWIipP0MU/Zj+08RSk6sp6kMooS//6Pt+9ePBuePv2vLlysSC7m0QQdV4k2IORi6Bd+f/pUJRS/aF20HiAEpUjSujm1MwZlQGYCJSWrl6/uzbokQCiBegoQ4sBdEgChIe58/NbTrymM+NbBzu5gtxrStmLdH9sYGzFcUHDESvpsjbT9sd0Cncc6Y1DlCnDCmbfWA0a+bH7K9BseI/H2Ira9iG0vYl/TRcw8QW51ESPaDQWYbcTQifiNL6Ih3Ysq9pZSKV+LiMQsOQdUD5P1YHAb1cW4hNXLuf96MfszDEDn/1NNVaY+Pom4c0V2G1w3dnsUi5dxImbtiwD0hLo8BZfDTObsBVLD3r0I7sDcVg8U/8IbC1Qao5hOTivsfopR+AAlmNGSPfHDhTv2QYTVYAjsZhqi4VEaWkz7Izpic43QhC7QAD+SrYqjncYLjLgQUmZLqEalyk8orQmaNnQgDRUC1FhpM6SGbTKzJtx+BQJ9LTW9YEI74BvzrV5LE3PnztOkPy4GrpnShlJHG+qVrJMnvQvC1D2z1TZLpa4RDVQwUuf9yTJtyva+vQWX67UO2SRcvzU8Re01gOSfhoPezhe1qh7thb3a9SC/nD4ib6qIYG08KeW1wLbV+2q1jn6SiInV0goodeUkNCIRs4Zde76BTGoBOJsmobX4JlIIpFc4C78gtKHWoxbcDDvKG9iIrevvdXr9Tq9/3tt/NIDYum5/sLu3/2sh81KDjjTIYqD9b5LcvUGCKuC5K8UKHUxFDkfgMMAw3BgPdERQO5HvUHdqgp6H4xwiehhIWOqc3dkzBPCyWFhejIZdufsKLjGNiA3ZlCPOt07QkobryPAyHR4L0o/RRFxCoi8wPLY+4cLPNC0W2whnoxCJ5oqEvCsWICOl0EqArBpOCPXqIkByBiHzZnNQ2IZGlliFytdmsTeb+0t2JcQc9zQI3bRabjAzzkUwCqXngm7VC3LeWlqqTmGc6GSQAFyxCFxZERqkcSenvQF+J9rpbEs5NIC4bOkOsgwX0UWgHK4KrUQqL5B2HDM7mBH2NStIDSyUQaIun0TzmbVnjqB5LcBgQbeAKgAZCbuJqIyTFCapf8aZEBfBb1kgrQyqwfv7CqLKFdfChwM/7jpa9EfAKt3FHQfcFedJvEO92Pkb/duB3sQPLgK1r8kwQ9mSSCcVZ3oeQ8+I3Yfj8WXq+YQTeRGkncVdRNciebMGZ7czkSTalxDWRrAEVcZEwmYmUx5cBFQ1Ym+qxBa3nXIzQ8aGcmfUrQ/SRpIybhPqAUo9SRHceUWjaeyslZwPjo/d46ODvYGzf7DnDsTR/r44PjjoHx0fjw4H+4MGknOuvW9ehF5N8MzPxqcQ7LaRQeWRQV9WztZtsNHXFWx0y71/l9FKX0J62buOgKrHl2neQmVN2bZu3US25m0c1zaO64uO48qJE2C/GcYkrMf1AkWdxan5VFbUU93Jb14G/UQ0zsmiVR+/37xYm5VvxWh3yOdeR01t5w5cGaCNtaY3X7DWEPwxP8NVHg9n0tktzqBg35nvQ+1Ize/Xv7BYJnQ2+6In8/PN0aaJ3Blzz19EK/HHFHxSgW8e9nq7BnJm61Uoda9Kg/Tu7Wnr43tUk6qElf0aE2jVrBnwlyvWUs5nJZlhMxZyoH6i+Za2DdkT/LXJGSdT+nZbNWF9OXfVKLz2XOmwCm0qmnYr/avzR3fRWbbkC4UWu/nZ72T0gF/aAti8Ag6aMpLx5unpuXl55ath5qnUs3kh99OJP/XVwX86oHbROoWtuDSEzMGgTwAXz1Ib4mOVdUv6EctC6BdaE0sFscFm9BT+trfuioR7foPrYMPbbdnw6KJX1vxXsQdWG7ci7Be0wr+JUzFDZMgu69kcg/XgzF3D5OfGAFdnaIX2ly370qZ3JXO+RN+OXNcwhSBuVtsU5F3XsfCaXVaPVjSlQGWViuZVLBIlPctZJ9YQElbTodeOieZhvcFg2RLWpybia5QDdL9K9SCFLqc7dXVCQsG8wfWfUlbIbt5S3gJjfwJxrpFmMuQwNta/LZzGIkn8Y/bm1+OJ8+TZ/I8fz8MD/sdBfzIIfvnu3fTlnvfkxa64eXzw4ukvvz5JvPDZY/KuUhqCfQzfKB2D9HygUJr6Jb85frd5HrUBDpFdIfiwrcdctRYqo9v1WROwcC4zslqi3YsHUfWqUPA9s6Wl6CqL4K6iAz678Cflgi+HYX2bop/cPpV8EH3zDMZXLW1ZVrvjucZdin6pnqBJ194/5SrWlMHd9n7V3sQRW5bIQn6QjnRF7r0qz827qASx7wVXzYrKb5u6PUAZpZtIeDQRzba7/LQELFO+1fTaBJdWSpTq1Xqe8ubTN8/P2IQn4oYjQ7ezZYO25Zvo6auzF15wJd3IFUIbbi8cKbTozcc1GC873jyId8JgFPLIBeQ0LJL1b22pfhkSfWXX0u9WI1RvsCv6vf3xnnDE+Ii7xw7f7fOj3cOB23N293ezBNsdWG4G2eNiTS2Z9gEiWbGQHAzbgPvM8svebvqSY09hZk6ZmiBy3cfwBx0IKdeTXLbs2uPsyauTl8+qJ1OtciOzb3b+Bvv7qn+biBBPT29b4MRdxYtnW3U+UfR4ttXiKDcfS26j7sYjy/V6/ZaE0IK2fSt/blD+TKMAq9arxHDMHUb3ZLATerPVQIupAAUlc+oH4MmmoiB8kciC0HMIXrCfT6lMUyEjZ5nuSuconOFmKDFGei2A/co38M9wEXiIPuvnROZPFOinmsvuj3ru/xlVo5sRgT+/+nRlIbxhrK2xIdeU3GFRhNGViOLO1fWQB0tjQSyCK0hX3cp9c8d+a2lLax0c9uKfF4CnYYfX1Ze+r5ygjfqhff2Ts1G6frmuZ/UT1dwBzV5Xc4+XD5044V4Awc4dRL3ryE9rvR9uvQA2645WvRaCsNMUJu+fZrdtcJmsv3FHC/+qA0HBTacHNTwWCr3Vd9grsaRY8jmHDhGoYzIVXkTqIcTeAl0WNmCT6DXV/mpdiWW/9YhaBRi8K7EcqN8DmLI0MvFNuYqjJfNtLAAvMg4dD6/AqmPQ427mIpG7FrT/yt0VjSfa8739V0lfrHeR9x/z8kVuJjrQu85MJNzlCf808wLAEarF2kkqI3yNmffD3GsY7ZOSxiiEezylScMKQHZrW5aEHmzpqgCESCDOBhqrWX/5TUzNGsN9X1hE1iXUdCOnnGt4JZZlqpYUGhCXT1rIXzKJqMsQ0MAXBngbdIRBY/nbrB1Sr91aBNnuWBbyKz4Tse4IagZBwqD8ByNh6Q3kEkIzDqQZUZ1RgkOMZK909clxARu1h9TUurpdozaYA7jhYLUStuiU6uj3COkw3zaMuLLpHFwxj8XBXpGwp4HrOTwxND1hhPg9qKwQEQB0xNNw4buMqmCuwAQUiV7UEuE4TkLMTOIlCO47XvhIbegnPJZcBqfuBuoL7iVmxhKVEumHs9evGFE9bsOSmwIgjTeD86sBehBh096Wy6S/hklSH4lpqwYLfsQz61YLYXV+h1Y7Xc7kYdmpP2Hvzp93jpgIYEJdSXS5oWA2hdtmizk8GOyzl95jOBV8FLOrlT5nkPdMPzf17AeD/t4eqFez3A5opLpZZHQ1u0FaG4Fq8Zw7YjgK3WU9B/x9EXmx6zWzq6atZYqBasFL/FXOh7SbVLLg3IFP31uHGAlcGquO9NN0cRHFocUY93rO/1gIZXogwKMrEaT5a7wAkg7p+32XKrrssjeAN+olbBE4kI+OgKmA61zKTxhmyDXy02EqKBR4yBghPiTa9pBj9zaQlCdXfZ/3fvrwQ8/9feq5s/5L95fB8+XT7z68+PEnIb7/9dfZ67dnw6NfxNli+ufx2e+nP7zlZ3zgB/HzXj/5x+vvo/H5dydvdt/u/9L/8Xrf++nd4uXo1Y/Tn1+d/PL9a/9AvHncO3/34ii4aWWF+pQ6HTl1OK3zRTQPYzw5Icqchj3E5IOtjzbyb8R6lcXq1fOkkbYAqIkMSA0NKn2Ez1DLo+EilAXyx26Wt2c7/gzeSTX7FWS5A/g0R0RAZoQAa7OZ4DFmh/MCw1YVCycEGLzYowyPgr17dfoLE/PQmVaPbP/waG93v8CSisdHmVylml4EiefrngsaSZe9XMSUlzBhvgCQ+4Nel53zK4EpsBzhCugxJDhgl2mjlwQmNgoBTz8y0ihUDma3Z6K3HuSGVGVwT3NmmEC0Dq4vmcjsJqB5+ZlqZD/+xDSbqdmXtzXFl2AblbD0SkuI+WU20d5UZIaEKFmLiI/8JZ2kDC8aZIftsidwt4LcbpiTNIHpTYsis8cGvDrriliYthX4MRZuRKr2RVwKWZURN2xyAZrfQXjjJLYB7CDJeiQWsEVACe0m3rUIcMnO+JJSLIIv0LVw0TaPMiTUJe/YNbqfir0NV6h1t3Ab6EtQiGqDIfoc7TIJgaj4LiYMmcFlgpLzpfcNjWwpy9UwhsOj3YMjZAybEOEa2UmKYqTdA+l9YRGUuGWcwPDvxbgeKG0prgw51zxhM0Cc3O8P2GiZAL86gcSekRfggoO0j0HnZuolamVPOeCrwf4HDoHyPiUCmYvIEUHSQVFUCqEITEfThZsDjv85JJFBYO13b19U742Xy86PIu9v2h/Yh07i9mcZ/+0HkV0st1NVnEQjL4l4tKR7mEqpnNdbcK0fselS78DXCZQE3h8LIa8BRU62qfGrgcIUZUihGTgNfof4IWjT8nTQrLxeBGtggLXJ5VmD7IZuMvFiDolo4+Ei8odqI1o4cQRQsVIRo9UugTTHvNAA8+/evuiQqsDNaQgoFamcXMznLPGEL1owrxetNpHYVjuP2UXr33afX7TSpN50JOGb/++i1UQT30RA2PStCT2DrVcn67xWCFk2GapGhBoPuHO4N9o7PhrtHfUGR87o4Gj36NDZG/TF4PD41iJUfvDF/KWLGQ86UCt6Z0lVgyFnrD6ol0v2+iZgr/Ruy3PJ2l5vs8FUXU2+umwwuatiqdYLzmoWw7wEJKk3Unfl1Fs/SQV9ldlIeygBSDfGvhQ8ztIehyNYIHzk+V6yHJq5oI0cY7kY8IVzhYr3wVM29eIknER8RuJRsJiJCNJOgrKALoiEH/4mEjEmW4MbIggkyTmEQHgxu2e2ea9eXB95gc3W5s1EZ4QdYz4fCT9m90/PXneODnp9pdaFLNoBCn2Q/THyPjAn9BezYBV1fLtFjTwGUG9uD/N9y2+Y7IpwjbQ/uDJQrCN88cBL2nKm5fdxV/78d8hW+E5l6qZwKB8UILHDIf9c4CrZFRCQZ3wOGNsNxqFMiXocL62I0jTDiKANJ450rkfhOMI09GBu0RTosnt+OLkHdxl3ASn4JiKcwYXMofH/nd0DSHceGZ+MvQ/C7dx4bjKlj6xMNwOcTXXgKSapVew4bo9OBHo7uQwKcx6FN+y+6E667N5+7//9z//p93qz+N6D1RYB1WW5tcNm9YJJxwmjiDDNkRnFXdn8b9T1U/fD+99GXgD/wibArFAq0YPB1mUWdC+gxaNW+D1dyz2VmD3BDeAF7B5Ve69qQGXLIleikBsK915Kfk0Hy67ILLByhjP2/EREQ1/wsY1n0msIkyK7L6Rf8j1ai6SGVUeDTOwopMU5cJXlRwRu6szverGDXCnl/siqqETGLi2FRycM4iRaEHA6dSeuZ1JWBcdzGgzxRrrbQad1FizsOSYhnUfi2gsXcXaMTLIC/E4Nq8ueoLcLPfUCx1+4gv2rupd05fHfNh4RZK35JIm8yURE5iN5q2ojYdLH6NtR3KtgcPICS66Ppx78moG8EEbIzGCq1bwGoUvX1xu+jNk9enqPDok5nRh/V9deqR2p4hNUHlebNr1aRJpwNueRF0MQE34VRl12RpKhehA/UqSM4ToNwpr6hXCr8RCEhjbMgvozEhPxQaaYhRP+ERPwZ9xmXjwE/wQCtJ8JTEw79ebQhKqc3UcA4U4sQPIAHkCr8EGXvaIj9RETf7RZAP+ZJPD/os18OD8Su7wqSaL6LXMnGT+NceD3rv4bR4KiB/Qf+AYNADHsdUXwwR/wC/87SfA/IJoguKKPf/5nq936F/gP5Dr9L/jjP+D/4Y/TV09evHv67KzVbj19/exs+Or1+VA+a7VbL0/On3w/fPvsu2e/tNqtZ7+cnp1nvsQnWEur3aKirXbr7Pzk7fnZ8OfT8++h1Kun8u/3Rjh0bnnC7VoFY1JO23SPSj04ZYpOKK34gvuZ7+G+OBIpb6heoPqBFiXVXfF9ub3UWK9SK2p0S3Yp9XFCMwkqDf7f//xf4i3L1OkjxxO77FkAWk3Dqo6Du08d3aFu7shOPlBJ0yWlgI3B53r3OLqnpGlyOGCEiQCSI18L8IyYiA8gS8Ts7bMBi5dBwj9gzmQ/DK/4VHA33oE/R2LqBW784PYOUgXnQrL5puxBTlbtCRVYBaUzqbxgAV22JlG4mMeohAZ++IjdwydWsbYsZzY1+CTNsWOLQtBRGAHc70NYSievnrbarddvcSzypLqtj0g5KT6i0UaZxw3+X9ZTJESrOB8ejqA46HQMFtP8LXqPokbFFciL44UYhg5FsjXRpmHY8odG0dT6Zlo4PuM0rXHhHcA6W32DVJxNbctTHrgSC77gQtiaCbB0e/GsavpICAILSEdmtYGW5d9xwp0r+Tcki+nIGAg4QyAbDM1nuEicUNoBtHO1Zbi5MBiDRt4k4EnWvdt4C52wi+uWYGjVAXP4bU0ns633OmIlu/ffoWaYpSuFnT61SkZecB06+Z1cdrsFDnvm/Sms0rkTlawQW/9ItcXS1rWXQkk/f4+jufNSg7cX3s+45z+PQssyIWtTWTkFSV94QRmQbG8iflNKhIgvT+0NRc48OQ/ti8OZCnfhC/fcm9mrjec8KKmXVvMTeQLI10byLmW8Rg1UxB1RUo+SQYobPLJY698Kl+MNUk0bqblJV5XzQbFcnym6LA7hEvbED2OR6386cv3Zs2th5U5WlfIS0WDUcN/LbxpFgsNBnz2cah18LazP7JKqESU9M3ov5xWU7lX9FWjw3wXeBzLaspnn+5406xZ1fzTBnl91rpad6z5kzyrZO+XM0BaLmL+ul3NtYMmFI1dNnREgR31Le2I9crPDKeXSYYBZHO1nzZyDOvmsYq+Vv7odKaDiRrSQB4TsSDqeIk3ep6rf+kXvevEcmPsri5kuHSNiwKBsbn/9QTioKAW1in0x0Xp/VXqG4utzPqmUDYsMgMr9JKK40TlmSw2GEZGTRvylGBOUjqpAhcygCiWlASydXxKZ9MRlzme1vcvFw7mIUL8eOGQwBlW7Vc3wD+LQ6ecYg+3FkM6QtDyYBo8nHFzcuuxUXs2ZHp30PIkgQWrs8CAASwGoY9DqD/kL3S57GgpKyq1UP4FIoOcMEjMFTgP/Fz4CoVjypqL7C76C6+6Jy+eouH7sJewtTwS7f/L47QPwtEGdJymJlb4aDyjM2oqhQxTE9PitrM6LWd/GXHFkQxhZlYloEYDQH4k4FiYxUqqi6c3KvYXP57EtKS3IBXB/Vh49mXGg09XCElMAay28qe+xOYf13cytYNVns60MqcpXK/a+wcXEnYaOxfY7Nkhww2NwnRcf5r7jJeBgxq+Fm3beYPIyQt3GjS3R82mBx0sr08gFqZebZmnLmZ9nbLPgxG2Bei5hVXbXJGpCASrlepKBdullw0Pp7JPSWqsQJ+Fw31n4yEosZo0nSB/2xPgIliTsAkzYm3oopVuvQv3vmkpZoy9LOjVaSguKoW4l0gz3PW47KnTkge35ed0ZXakf092qqIEu2O3Wk9fvXp0XDwNdRQMB5wsdITgk0Vqjqwccf4hswa9xDQrXQ9+Tea/Xx3/ov/vw334P/jvAvw/xv8f45Jj+Pqb/HuON3nXFNUZHRB6cXoqmw6enZ+enr56co5YWtLMvSff67iXooH76Dp48e3p6Ag/fUB/eyP9CK2+wD2+wD2+wD2+wD2+O6e9j+u8xqnOfPn32U6vd+unk7enJqyfPLNojQ5tnnVUsAYdsbLUXYopZgBKTX2i7Upe9EJDl2EvU+aUMThCEq05uKLKC4TAPo2XV9BU7yNlzn0vfRHg3EphEmRjACJwVU821zlOdZwLraA7zeuhg7E2Utvi5bA5S684h0bOEypLUW0MxumkF5cc26Rwf2wL7npKXp6Qjfif9ZqSprSErnVtuqevufq3/rxaP5ZWlLGwJElDya5VNrWoKv8fPmONzVMlTdCPZP8KAmSeS8mAwzZHNqVLGLjM2ujKS1diYbHQrEaOKmv8KEvrezLPhE+F2xJdqoxV9sHZYJJwwcs0olmVKv8r87/1MNEQPU0UK1+baJlcwD0Aki0h7DGtZejBRAneIme2Aclo+rr8NeDFaaUo0xXCBfcIzeGTGaz0Rt7TZWKS26i0hJxLWVOSK6LHF+J5d+viZ2uTFmKOldfOXUAzrKj9abE1VseXYkd7B1TZBNRoKMDAkQ1gD1KY5tpHlLCij4seibNQi4NgVRHpZwCrS227oUqTOCu90L8lIzuntwrw2pB00W665Fw3VbFhNrhBibR4HXHG/RUA++fNwDiSHCx25kLgCoNAUX0g9MK89cSPtquTP084w17ahoo/bDDWq4LYUMT6Brx80uMLjh8VxnMBz6DGLF7OZdNbKuOKlXB17Cf54VNm9LnvGnakEJY6EdMeI0Z0K+4jgxdwLgM/oQDF4ixUYg2p+UmDJU8tN+vRpemsWPPI90Ifn25HInQrGLwwsnhFwo4Fir6y3u1foGLyphpwwQHg5KGIb1BPjPbOOcOUmUxybghtO4gVOwugDmM8wktgJoOjUJ3xWy9FAL2izPJ2hYsMMvqWwSqlUgcAOtTBLDGbzRXIO8bqWoZzCS4rmjXFZgxO+E4VxDH6lSWE492Jarn9nhrqO++h5w0ag7Q8mKMxbtTuQtNavIih9kCGo0Q3ZsVxXVqNwuEgqyPEa334yesgVWLnGvhPBySnTX5bRZt0VJz3abIBJZPFUH6Rci8L2bjUL2OcqFV8Zna1kLAPtfI2nFNj8gGfjR1V3OEeeU26KuKlMkE9ljuqXNmdpdIQnJq5yWUPPm9i+HPEscG2VPoOjb5wfPeimuGlfa9yMjWOeY5UGuHZDhoIVnoHDm63n+GIzfbfaHuRoct3IULM4aWrFGevdQNbS/hWSP5kb03qfqdYvnkwmkZigLGN8mPrW1okMZu33wCMVBYNYKSgR4CkCu8d91M+1Gb+etNn8+LjNROJ0H5CDmsaZx+t4Z7Rko0jwKxejuNE/F3ycYwFiTJ5D1QoWcoCVVq9GkTfPLG7aeC8Cvkny3SOKQF7M1KJCEwmYFxKQQX2tXpAxZFSqy04TJv5YwPvsxTLzGU0C1XgqK0R7inUrkd6l+aDL7uqbutqtBsGCsgAN0XYBBiwCnAlU1SKlMmTRnsVTCeGBQeHY2N/BWlWgYhAnYFSzhPy4urEUJDFT2LKprkUE8Uu5yVdzT76U6eSjtG3ONPaa24r32Q67r9cVrDvwGda+8bhAvAShAr1ggpeQB4+MGL57MQOHiaEqPsTis4WfeFTDaInBUHOfJyAipO0Y7vfkEEtgCyEEpsDI04h97OZMwJkYwKXAOmp2IyJFIDcty0fhtdDFqQnt0Y+epWmsBArNsgZkCm0ZLM+dRMbYw/8FdDkDsuKGUpbYrrZ+WrdPyfX7LTJGnako5X5dJhlcvJhJLkcK+XYuZoccZG+EN5lKyUjgbQvIci/OT3rtQaNw25T5wyiYW6bWTVZu6jDGZncnEJG3ClPN4Qr+M7DgsRfFyZkQdgJuGfSdMWifV9B9y7233Psb4d6JZ/X1KsCnkYK1DNUz+7XJ99um+KxZvv2agREg1UEslhtGqvrSkW/QXaC4F7qW+4dsR14ZYI2IAHRObpedcUIBJG91uMOZt5PtlWF7ZdheGbaHzvbQ2V4ZvlwWvL0ybK8MW+695d7/DFcGE/5nPa8/G2gR2MKv7U4RAD1/7bkQNk/brrGZg2o0DRx6hcNe8cMJA5AaE0xEA2fU+nA0BPqS+0g3mnbzPgBlQLytcM2TSHs1uQtEnULntYxTiREdUUKyFxLny0tJlwhfzDDTQWmPNuvbqRscYoO4dsjxpry/yjFHor6kZuA8LzYSB4wWno9YoO4y4DPPYe9OV7g1lgC/KMQXhWpS0g+r7VL6lNYCV0AbErihLScfvYgUekO9Axgd3PiNdaumkpsFfMuwy+ngmezw2hLlKudhxyYRDxY+j7xkBVfb1aRC62W+ZCMO80H6qZtmXmLA+HZ/EXvX4qXy2aTnGRfOYYU8ZxVDhqaEVCe2NO1EuWxj7cPIs4b5Fb7MraGhOpHSMbz/2P42xPLUu6pCaZId4Hfk927xn7aiSJWFP29AQv9yhe6tXP2ty9U5HpGRDT+rBJtB57A5NRF1cXfTdBoumfdTPI0H9cKj0Y7yrQXwKPBdMoA5FJYjxtX4vppeqR/nJW61tfxjk3JXASSw3YoWa4ru0g97ESinOFpM61VWFpqtHMBskgv6eWnnaJsQWzuxVHepvzRn+n4C+x0bRHcnL4nJabCtnfDo0qj9F2Gu/esMpFiNnFPm//sMnjOFlI6plxYBwpVp/MipdOtGZGweVIpilk0XhojqUOFXrRzswpA8QNV69hJCeNc9sIrBUOw84kHMETnc3s6LcOI55NqoPkzBnjONW9uQhC+/T+QdTNUEqfN9c36l+Wtfxru03K+0oeundvqUc0Kr8rYeoLSZhHTU26znpwRbKrh+iuLuWsMDVLIB9ANds+/5g0c7febcOFd2A83sLPs+qNfNAIfNMNja0JiFJRj1rcnVIL7MFwZahREjwyegHUk0uvprswUpXBBeRVaFgbk3POKEacXk7KoVahY8jQYRMiRgWcMwismDTp9m8gd5sRH7Y430SAEPcromBUGdwg3ljhFw9Ab5UlZhrd6NLEqFNDuwF2MNnLmyvvvKrA4C3BwgW1BytaQowJuLvn1bGLdmQKbvrcT/tQJ+fO9NoFcSaFLiPbMZ5iISCeXOtLvwplygAm3N5vtdPTcaAiOPLYz4FYWFl57NadBZW6vxaBGGNwFBuJohFA3W4OdE2WgIGW8WyH32fgvUsQXq2AJ1bIE6tkAdW6COLVBHA+XTcgvUsQXq+LKBOnxfCg23tTC0/6oF7SgcClvYji8LtmMzd4QvBfkjq06+DTgnu+/WoGw2wejYwmx+AzCbZYH7Kk9eXmuVkU/sOoqUiWD+kmdPUYJ/+ebFM/hbIVqPI+s1F+lJ+a6ypNQd6bJ7QIl7bCaTehO6CHzLA3YvCe912auQjSNSKHK/TNNZsq7HEhHeFlOfar1y86wG1CUla/pdTtFaeQQP9nf3eoPdXu/wGP6XB2IPLWYQqZv+PH3Ki4chcGGg3vssp15XhQgOHkzWY1WFQR6JEnQduUzhC3YzDXNmmSoNm42lK/Ep1bqai1h3xMAxMLWQpPAs11DnLZI23R4pp3NOaqlZDk3w2mGvjeYVdJaSeevQiwlhuJmQWbnBlC8V2vWb4l8lNpL9fpYqnJ/oz2QPDYUiyfkiiDzMuYOJffxwQjxT6kGXOJDAZa4YLSYT+IX5S1ZwLpHKtX81Mxnn97JK/aH1oEx8SCLKTpCiFsEAEBorTrOqRQJdBj6Ab0ngmmnXAA4I7zBqCMoroJku1SnxKLJo81OdsV15DyXOykx/Rn2kzE5oXiYiEJHcIJ6aPcorKFdtG9OXxja/O/B68F3kkVY/s0YOXU4YV3pUwXtMMhmnqnKr98CK7SrjoWWhgFW3AaDMig2KQGftsLS3hr2xJHWHzqVTYTtvaw9OzYSBi5j2/oCVJ8nDN+diBg5BttOc3nh/AmocQe0rzizMXqQyICpEMFGnN/N8HkmAL2vjY/BhijBPvPVqkogg6YC8C4h2+lOd+5N0L7qdco/VCvMNbZPTp5T5UDqTSXAwckqCQYXjcSxUV1IUMWtjJSL1C2DtKAPTnvTDSZuYZBt5bJvd8AisjEAu+xY1snIU61YTAVf2qtJrzbVvNFA+08qbo6R5OMfsXhIv6YxDxwi9inMHJOylwllobYmySRZbeY3P9fI1+ONYJM60zXRKnjbDRED2WcgnDLFwgFR8oY/Ju8T0lWBTT0SgVrFdp1PsJItkFIwjngYTqw/rjhSdoqj0LHnLlxnIv0tn3In48pJRJptU8UCOYXjkyCydUiazsnKjC2Ji5dFGH3BiITxFRKgKm2ihQ6bBMrtQ0gi+qxmr4d1G4wDjL2jnSZoBEmh3AhPxMJyghXs1Vx3looOPaI0r6ESwRJvHtb3impVmHKU6FgIOWZgx1AjIJOm8whklLnWUyuWrN3yXvLjCbwkyn1k7DS/YDiCT+uFyJuqFIfSBqTht1/KRKTlvs2m1coQ4P38DWrB5GMRC3aWd0BUFdV9BJF9Rush43DR1mAIaRvV+U+t0xTaPTwsehKdP4eZyheeBiTSpXNPKnKBu5T/nxZXcQPInm6tKBfeSh8J3z87ZDtwL4zZ78/rsnO2gNjSWh4M67eyHhDLnWJx3KUjG8Xkck9sINeeMOySmd5AVtI0Hfjixt1KSpS1Nzmbh0oUkfI1u0HD3/Vd5jahkrcrBavOXxzJ3AtgJI1+8xmtZSaKuuiRWuTRzzS6oWKrOao+iRctI9we1+jyatWTyRJV0sN0SkM4QJoP+ieagbsYUiC0jJZ7MEzX2wxvQWwRXQXhDRsC6VFxppzIkk0oP4YuYvPBUVkwbpRANRdzYaNUo3VZ5Jk1/YU3ElT/TiwVxHdZkF7ttlrDKfHj2DGI1meOqkjJGi8DJGUm0XasyC5lekA18VJz5Ak7Vl/boIdfjkyBE68OTKWiv/Wc6ErOZ6dahYquTsyKnniWWQuVQU81VZQyk2N4GOe+2LGXLUv55WEq7dcN9v5QZVHEcNa/mys1U1zb4jM3FSntY2W2Q8qWp0RwJPwwm6D0kBSctfEh5qUTBGYeLyHY/e8tvUL8x50s/hASGL/kSrFKcUVnMe5Did7mMei+TK+AHAXkDSUUJWD6kjr5bY8EuZwZWWlUkkpWipZlD9jZ3oY9ljGrM/VhkV4SawWxSS0luU49vGFCGT8MZt8fz5o4RESVDm/4u1bGcvzhj8Jk39mCNk8iYGqRdbMlm5dT+A4sFGolSd+DjsTs+HjhHnYM9Z9DZ47tuZ9Tn447o7+/29o4P+v098DmEa/HrwF+qKfvQ4QvXSzI+wiK49qIwmFntQlIYN75hPI5Dhwxd6PhdPYS0y9IWQM4KxYjsJl2dhnFi913+Xr5RJJcdYk94gAZcTzr+C/Yn5tuYiw9y2yxG9K0qCe+7TN5RYnL982KmmmY3nu9DlVFId8tQoutJNxW3eLu20ILP5135q+uEcC7ahmtdVbPZgnJFpOurCfXdkej3Rnsjp3/oDI73dw8PBR+5B72e6B8eHY7dhoulVIlkxqvJRVOxUHL0zdCvktJe3Ii+s2VH56q1DQMmuWbT4jox8rWkvdc9rO7D/vGuc+wc77lif3A8Go3GnDuHzv6uI9ze3t6ha+saPIqhRRBMOomIIg48oKPII+25rUcthRM/VBDwLTUs+wYx5+fWQ6tZurcahc04rnhsllml02iO3OAS6XI1GTsap04W4HNXy9utijZQv6EuE9QTSD6epK4AHnk98UUyDSM0VSShcpuSiReccmsiCav9Xm+w+77KoPJS2jog6kXPotkNnztX0JQj4pSJjQUHCaFeoYIDN24qefJhoHnAfbABN8nkvQIhecCkgE+4A+Begxk+pKEOoQlCykrv1hCxN1iLiEYXqEnVHMXToUUDPp4sPBc94eAkp5QtajvhEX97Or/0YtDyvwGXvs1SmaluoBpO+wzC8p1Ro3W0XXmBkgOnbtfWJgVzLyYAHCFD+p2pcK6Qpu/evrg9Ren0OA2uuZ+592yGA8iTT5lvHAV65VF7+fg968bvr07Xpa1xTzcLUGvOFCTuGfeBDwmX/XD2+tWmqPlCOZRvlJbKFwX2O2F0SQWx9BwzvNOVTpf7fnhTyxV2D9dmrZLE5CQPHRsJEaS9s7OHTZEZjnBwh/Y9Z7PUVk5aSkyDIwzEBe6DSAiOkV6clBhpNFX3erelKrYJ56Ns1gsQKMfGEsIQXjDXG48F2q/tMsv6dL5jBqGGKjdoDWn7B7dkCeXN3ZpQb0g5RlEMd8MIcoNIwpCBhgVWwkh6e+DClXq6FNi8hg3099dasUZ3YnvDDNypEQgIkQX39yCHG/r+Wd2M1qb9mbq7fmbqE1aU6kzdYt5dTyjL94WIS+5QB7sphSVzBpFMd2lzVA+T5+EiuDO+oIMmkOXWSWC3PsdAEQitjWFMm6JRBrniTIZgQFTGXfBUHrCMp3MOlqwxi93tHa1FzExzsQ4YGInkBiSDHp5efYqBAV+GTRH5nE/u+IgiBLiET0xNgZJjrfzMvtv31lukfBIrNirbRxUq/qsbZ753hZktZhy1eTNA7uCbW8rnfPIJWGtKafJAMBibEnXhpY89qaP36ldeJStAGwaDz8PNVHbl1lS+a/rWXCBwuTW7PfRXv/jqDiHtKu4OWTE3EjPAIsSlcStav2lqwJQxgkObV9fPyu1V1lYNwVMSLNlExUyedw17cS9mM3DajwR4ZZpee2b32CUgo1wCTJs5ApiEQIBmCadCNdx4NFm4lfzoVlDgyw5VK10Pdkd87Ijj/uHx8d7RwdHR0cHBaDQYDA6OxKjvHDQkrx9O5ot4aiUtGknkB0aGIG2pKvZT2Whh2sYcYMSVAc7WdontxuLBuQphpFZzZ7bsjCIeoOtBBq7mwN6bjOBQ7FYWgSsWCezLuIIWJZtKErGc4FkB5g7IXgRctRuzs7IThhWYXeuy5+B43APe1Gf3++w/Wb/X+7c263Xp73+zQKQbE9U3etsvsXihM53FBC64j7uOneIXK01HfpuuOD1Rvm0Egd3oFH2kfWmDZQ8nt1h6Lh4mpSmMmS9BGs3vIL4hEuT5qCxw4oNMR56EK0HC6JH/9r7M9lxDfOzG5gl+mz0BXfoUW0H7vw7tS0ORyPALvh21ys8MCYhXOU0aNQ8MIusysbIukLDjcieRYItyjZV2iMJv6SsiCUlTMvgySl2QEQCGCBdIV/F47VVVA5r7OTYydekL2MqyI1/WZpbzfffbuXYLUZDC3W6ij4bTYZlU+u7ti07Mx1bg2FXEsY4pjjURTOEOZpk2vJlZPEmKfSks4gy6zmDPFlyqMcvAZSQRHPwZZsuOcvl8n1v4M/7hlGo/yjo5OKHvC7Trd1QjgoC/uecPnTCIFzNrZMJrnHxlwCKd0jRc+BCMjIWMkK+Gw86yjnp3ENW7pp41MKSOKmR1sMldTQM74m6BqTQgp8RqaH5DNW6H/rIc6uEW99VF5Nsk1jDdT1UMvzB7KamnSTKPH+3sFDZUR7s3deUVv0uAhoX1nbuR2nxrkB9oSCHchPmrUXppLKxnOfy2qTrIzJJFD/FUX9JtuhzpIoTyTDzlEYWtgbkaD2jKFAERdXKPmnf+xRwcZJtgG4Nisew4fakQG/goXJDiJm2jvm45WkD2m3nJMJ5a8CGeL3yf0Qfs7PsTu6ucbhPCsBORhY54cmo6ZYJPMOm0DvYId6h6Fx+NDrgY7R7t7e+Lwfh4IPqHPVeM9g52+7uj417/4MBxnL7Yz96kD/bsO0CNuFQnlrvhq0BtK33ZuXIFx9O41+tJICVvjHrJOgb13APkjNECVWYFfLWq7s8Xvj+UkuFQHvIVyEkYPQ3ziCAD0SSN2t3cbA56TWazv3d8cJBTeqwy1sRLbCh85/D4U410vz9oMtQT12WcOWHos0DcKIe27Nj3+4MVBm8NUQSfqC9r4OowmHjJdDECz8udNK5AQ4bG7hWObseyJGrJAh5ssZeE0bKWKOQ7z9ISOQLg0Qtp4RIkwOekx4pEkJEtuZHHIupIJAPXmlHB4F9qIP1eo8173e/2uv0Cr6rppYqYHY5smkuFA2oLr8WD2ojLth5tln7SAT+Up+4wLTbkc6+RqIQxG7ECK26AgDuUX1NqNdeO+/pYvmE8STjmd5Iu5eZ25Agyg7IWjJtO7vgiIIMbJKGRsAdiFgv/Gm6EJ4EUJ8AMyWLAzLkUwfUlC6OL4FL155Lg7TnB/FGgfcxGYTLtsnckjSCMcCqTTsNYXAQSdiNjAdRuJAigSM7SZFEGNyhsvHsB4lUT0mmCYXppZyqki3Vj2mcLIXjSbM4TT2UQlZfsRlUVSxbqG/vy+rd6hVQUazQRxJpVpEtQJMya6+tKLElOlWQnfzR2ElwEZYuINVlDjacbuo73WUSmLo7iqXB8DkzhWqmAYgvzMm2+Tyle8iKgiEnCAxAxu6/OOy9il5Azjk/EJRtx50oE7gMcCQxexcFcBGkcatxlrwMcZdxmSTgbxUkIsBS+NxbO0vERJALzXPBIXAQhhai1WRyyMPCXzDd7f/9SXjkuoc2L4FJ8mMOVMZh0EIthLKLLB1LzR/AXXXYpC2MRdjnzJsQn48uLAL6cLZIF933MCUv+GhA6RzO4wlxQI0PawcMZn7cU6rLVtCEPU/qACUAkANQVngB8IFxE6+8cznwxnNlwD968I+QRsjo3g92QHH8fAUcWIyny2BDm9UtZ/zx1P66uG4RxOA5uFe0Cnl3DWQgRxnZ1n2lJpO+UhwUtIc4uMVT5UqL3RF32Ul8v5V2SRQJdTB2NRC8oIcVoiT/qg2UQzK/7e1wSipQuQstNVL/DzSq3JKMdaVeLZSSRtDiC+5k5GnPympex5acRoU3WO+EQDeNEzIfGaCB8tElxmfvRUgHoDuY+d4TSFTSpThfAhHbDIBxKxExE8+QTAUvGhn/2Du+k+NIm11XOcZzwwOWRa6phzYcpSL5+NFogYBTGs4/Qp/C9LSzSumRwLVsx8F1A5kR+MuNzmQAqRBWjQ2h10mPTxlvq8BKogiFIJwd79h1H7zqQLA8kZbnpZMlKrRtIyhmS/vrL9Ga0+0Pv9Lu3/q+z5/3R9/+YiJtwcvrd8z/Fz/u/n373q+9+9yr88fsffOeXn3xn9x/x6Xc/LVzvZvLfu2/3fjx7fPjEO5mcPnm8/PWXt31ntjcZzX7aPX3+g+/sPr4eBa/8H5+4p7/+/CEeLR//Mtr9If71ybPgx3+Ek9Pvez+O//Gf/6mEChh2IkEPioNWlE2M3NI08togUN8jy93O7/yaU73/LjlaqbuEnbM15EFW1WxukO38VNtUt420tRQENySQh2JEODwuwOhKNmS5VmHQO2F2w/5MX2reJTMD8ICdvDllSXglrFGxTbS6sutWD570/tew82v2oZE7VonL0yY13EqggdQPgeP5XhmYKSYFXaY3y6LMma2CjuMInHgDuIx5sRK22JtwDjD/gGYAop8+s+i9iasr8eXdi4AHhoQ38kPnqps7M7WA6UbQq2xv/n4RXALNHkk42sv065ApR1TCFNMRlZQHdbm6cJhtekjZC8qgQJ82A6MrAgY0mV194g6tuo8cAfXX6JXIXkuo55xnnfZjh5trTmypU4cUuv1R55Sx8kIpXpobgT5vE/Qe5goBrRME9tuk0kZx7yXYHMj/fU8YoK+0A1cSH24Ajt5v3hkY1mI+hC1sFftVygBT2GfxHDNQBzolK9VSJ6jfxgh24vsYvZ8awshpnzKjE1i42klWWhVEknSBR54VLTg16CoN4fHu0aE4PHA7qV23O1t20ngV04b2vpHNTHsApKdE7rCz2cUqTWFk+NoaxLYGsa1BbGsQ2xrEtgaxrUFsaxDbGsS2BrGtQWxrENsaxLYGsa1BbGsQ2xrESsSoUr2KBJrcKla2ipWtYmWrWNkqVraKla1iZatY2SpWtoqVrWJlq1jZKla2ipWtYmWrWNkqVraexltP46/V09iiAYwf81ikTlU1h1pebM0tdnjN5GsJOA2cjS44IIOJGyV241G3ltRbLRPWtFomGK4m1N1CckBGFogbf6mdoE2KrH/8NhuA7Pma+IbVs1lA2tkcmOCG1lK28fxZlu3JG/VK51yiS/qGulJ1KG4SC6d8qX39sDgrcrzGiR5XtUVcU8XNDRHrq+VVU59PJ7+eOk73+yvTxRWn1tJJupisoXGrsrQB5ehLvEp4gU4/0r0ILoLfLoeA5iai+PL9faV6dcW18GHBxd1U9YqaWEUaYDKe06GKd2QNO39zFnESzjry9wO6v/92OYyE60Vws7lFI7qOnQd4P4sVsxqJi0AFpWDSHRKipbIiHR+pBoy+0N0qI+RdJuJDsoNI0lIlV4eQ3cSNvGIOalsASW0454nlhD1HI8bI9xyZVIpyY4y9D2wRuBgi5WEeImwZLoqY2MvtshMGIK3a5nHN/QVoU/A7D2MELncu/w5P5mEAuqEIri8xkmkKGQIh41oMH3UZBB3I5Y3YjpxNIu4uuG/eQrWyMyFYQAFqszDwHO5T6112DolmeDARzEvabOxFscKXNndQPo+eLMITRBCs3l87bujEO5mb3I4Fr3bTWQKnycwfoh7CCqH5FHJyzbxAEAS9Xp64XCNxE3nAj8Oxmi3SGHx//vJF1fXLuIwskhAUZx4034l9jrhiKQns79W91v4WxVFLpVE4Lz4NwgDPXStCdZgMMRvGKgSiRUnCE9eLWMdAzSCfN2boBfZBy5/uywkidGLGQB2Vgw1VU3Cvt9eZwzlrkg1HldJJ/jQ+JeUJ/uoYF8IySkSLYEiMb4hrn+iQxeJMtTcFbkN5zzghkyIniJAJQoAUhNGFFBkkoe6N/KySDppDddl3fjhi9x9Kja+YkG75/r88kFUiI1nMCde0y97iQ9zgGOJEXFW2cG/nHlR971927nXZScJ8wQE5NRAsCIOOrhwq1sk81PnfznaAGp/ya8Gm3gQqB42KcKUGjwfFKlEoKMdYzUiuoNTKxcvibSU26SYjqQAC+EqY5KNyjMNZA3uVp9w17jIKHgVOQrFXcBX6Y+Fdc19QRNblbxetnYcXrfeXwEGRR1KqaTJsKd6HwgTklfSEj+o8vUYzGaJ1Iu/3KCf8fmNLpg3BuprUbDEHp5wFpq8cL3xlIJMjoeMW7wGw3yaAmAqSzowH3jirEtbb50MnFkHswVyYMsstI5Qr5CitcFIRYYZgFYvof2WTqH6amORGYt9e78gZOe7Y3XNdvnfQPxRjMd7rjXp7bv/giBcDNO29NQ2pWzvi3dgRG0WIq916x+Hhq5kCZacsdkBpdLgItnbA29kBt2H7nzlsXypm7iBmf2vi/bwmXkhDJk1OUj66lLf8Syki3RfdSRffrGwbftDQwnIHcA5nIkn3rDo3dHA+MLQc4IP6ZiozCWYSKbEwI9JvGhRiw/bsVJVXY8y20eXLMmVv1GwLWrlzvCUQx47Z16yj0ygdki2Ii+C3M7qYn2CZ9Rt70K1U7n16HeHWzL41s28W0KsJDo9ij5sH4Zlz5wrcalwxFwHoWTxrrp2p0PlwgvmMyVLSoHiDGrcgTrjvy6yLqeUTZUN1izCvTehgvsre0i0YxrliN8UH7iSaYNQ/DtJ2HPrXsndpX0ekeJbjAWUHr7WH7XX7h93BoGbxpVQqSaRuVumHLuhR0/n4IQ6DymEaqvIYtLEBKutBkZyIAAQoWVH397hON/G/aUD9snVv6VK7OBn29W9ZcJt0CVsPQqqRxubT4kf9lgWQWuXAnPs8gRNih+4nO3+jFx1ZFWodHtRJ+58KkUoLhE+V4CpPbMZ9j8dYvM1iD/S9+ERgymJMi04JUKAqXSdnrjdGD8/EMqubRrqS+WFWALpaw2mx0eL8pKGgVWBd1YhctKgb+Io1UbkZ+dU/X4pc6sRaGXKNaJEvIkFuExcccTQ+7I3dkXM06o9HvdGR6476fNw/OOgfHRzuH32C/LiFbm4iPa7pk9TQFYnW9EY91UqHeGdZb29JzH+GpLflk/Epct7eaoJWTHnbdNl9wxlvP9t++NIS3v6Wy3i7igCa2ds7UFpH8OKPv6V144MHa0/F3WbTvU0PvtFkup+ARXwNuXQ/G5v4ylLp3nIPR+GcT4hbzUPfcyyS1BPyc4rZNLxhHl1kZN9QH/chYffxJ4Vo7xABE56IB0zqf+G67QVOOENKK387mHayFblddoFuIWBgxLvRRYtNwyCM4pIWU7Msd9ApIfBItcTB79FTn0OdEkAfWnAcMU8uWmwRgC7AI7OZv2T0oqStLntLdzHyk5OzkhJOYWrAUhnphQylKC4ZXUK11aW8uEeX8/wEw/gWJc6IqTNhSjkw4eBwWm1o+X0DR0yZUlmF06N6dVjmgnsuZqD+EKvFXcjhaL1k1ybVN7NhWyKj8CSQUaelARmRNCpLXUk2TFXeFIHdk1oWlyxYNz1gn5MG/NiL5+AhOYTrTzznjhiGiwTXU7MYEXuHEIdBVUQez0w1xXRTqwWMUO+sl1Z9Va1sY51rq7wYUtv1V8RV258tO6pIRxdpacVIzWgltSnvxl0NX/ak6fX4Fr1J7855VVJKjWx/2tmFUZiroqoZBADUx9nss2gLZfI9cIqAwGwkEkTh0Koz8cGfY+RvNRN5/uKMGV8zvJSmzNQxO1akIQgOYZzYZwghyNRrHV1lVmh6gcHLP9Eht9YSkao5TV/KMrXSU2vTt1+d0Nka4v6ZtXrdpqH6TdCgMZNaNpWpnst0dGbz7fy6si9y8rkYSgicFVl5zk9F+QJ60HHQXqb2sFX3RFNGnuuBLsZGAtYpnNuflrPfukPA6qmODk3KJhh+rld6glC6+Zy8/xYd+0THwB8LYVX8/QOfywBYEKlkvGS87jGADenI25oZxo/T6NeMtHr7+aSuNOjBppqqXzkNmpstO/hVYT3o4WSaa1sobl0BUjRfX8yl5f4bKLU84ATSh34VlZj08+rwuRfvqAp2ZI0d/eBB8+VWPbtqHNDxjdh1GllOVm21nAXo7W2b0o9FI1ORfYAVUomA7er7T/EY1WzjPXnUUkVWf1p6dYc2HKjsoWlWZrpDd2DRUYCAi8gfxovx2PtQ7NmbiC6hPI1RijR+r4xFVfZ9kHIYVQTPwIJpGdFvqvS7ty9W2VYZvrmjVAQ7DzL2YfQFxCBYuDaHAWo45MXfUO61GXoTX6rW/4NG8l8NDP2XXVAlYKQsKBnQmGtoR1h4g2F61jlsQ2wVj1zwCYN9dCOn/VIrPGT/LmG2KZ4sDhlF5joidfiFs3fJDELS6JxFBIovGWfRZSejmFxMzMiBTEeD0N7T6r3cxB/CYpzOj7LCImEObSOLZEXN7qZDhK2orKD25a4bwWqoWcQQe1DPGO5iaa60Io1RACxZZjmCCzSyiXdvX2x6aeZ8e4pYs+ss2I+IsGIznJ3zid3lvV6OzMBTDPaq/ZAABEVwiGaEVHsIBABSBTnvGCaPGf9wSg0cNfQ73SRyzLp3xmr54vOhxeSsSQ2oKb3TGrswGf5D/lL5tm3QoalUwJIL2pRz8v4rqcNOYZVkXL0yo85ovU0nMLmjO0pkqncHk9Qf5nznitHHRXlmEgkRDCX/NQpVAU2ZuD987nUU+IAx2fV9FlEUNo84VZdPjJJSf69RVkZzV0uTkLfZgRBvWHdp/Lf10MsFm0ujDvx4jysKQvPQD7eBUx/MuoVxhgn3pSM7IV5AnakgLS1ygo4/L6Ndtpg20WXaBo/0hE4eBm8VIsucT8D6jMGqZJCWrde3IaKhvZ1XhZFAkB222rD+AcTxJUCWYSXNVP38mntoQ8NhAdoTD8CrjEfOFNBN+QzANOra7KWtztXys7ixpwkTsA/4qYrPAzMfOi5Av+BKVE1GiCjM8yW1gNtqAxn74X35vpzNtnsS9+TmyNkZc8+HbAwrkDWVU2C7u6L16LDX29Vtwu4I0TVc6O397u1p6yPIK16ghaBmptay+Uk78X71imSwsWXMksxWs/WdzrK8rcv28ddK86wHVTrhMJhO+cj/6TbR2stgE7uPglZtTTfKsWDhi2ZLW/i4LXzcFj5uCx+3hY/bwsdt4eO28HFfAXxcVnbpDO7y5Lz7s1mJFvajWXJn5N2cqW8pT8l9FblMqYuUi5XhxYx9Sk/gGoybHQgxH4U8cnceXgS/dJ6DoqDzmqDdHrGnz179N0h7UqSCb05wrjvS57pz4vvhTed15E284BF7CNsjlZQajS89uHIjnIPlIH2L9sXwwxK5VGxsGRww6oWCSd1wx2HIdkY8Yru9/kWwE4AR6CHbGfnhZOdRDG7DmJpsKzttZafNy04bl42+QkFoDbmnRMjZCjVboWY1oabdQl48pM3uWyKJdN/Uai8EBdHmEJR8kjYGwcnIUDXi9ggmI0eP9FGsM7tpiBYkpKesBquqIW4TdVYex+GLFeqk69sQFqctUFAl2sE154c3JjlwS89mi4C86XG76TgamyTmelD5DEw+YUSW9/lcsk3uNcTOHV55gTvk4FPAvSFZWVYsqkoZNaSOaevVZZSHOx/3l4nngFfNxAtWrDJfuN0CbKkxR6FulYp0qTRtxSrFqUi7NYrCmxhQQ1YorMq0W25/pYIuoCACdupw5Iej1YrqUjZ/w9WqKhbPOymuW3NZJe0WAiZPvflK9elC7dZ0ORcRgseuVINRrN3yZmQgWKG8LAKx7VMReclqhWWZdgtgsVYqigXaravBSqWuBlDmes3ZyxQEY4Lr8ZUqoBLKDIGsb6XSqlS7NUv8eGiEqKxWUb5wuzX35sIHOXWlitJSCCTmBUNQxq9WRVpMuv2uVJxKtFvRYDhaOFditcbTUu0WBHkjZNdqNehSIOI4kUiGV2K5UhVGMV3HymQ0y6la4iEgiQv5bo3qchVAvYGrEgmsVJsuRoKgt+LGU2XaLRjg6mdDWqrduhZOEkben6v1IC0FNaAYPFQ43ytWlCvcbl3PnWEgEvh8taqMclTLOrQ1y7VbNzyeaYzoFWoxy5F4OfbDm9WqUIU+aqXd8hU6JZIk+XFV/OG8xNgUeLhEXLxd8aEZh7ZGRSnzX68febFyvVq0TLlecZIp1yqrRMq1Crv9NctpmXK94kU5cr16yqTGtWozJL61yiuhbb3CM+lSskZZFPnWKpkR3NbcfiC5rVc0L22tVYshJ61XXotq61FwsF45GVK4TtFUtFqvuJbt1ipuClRrVqCFnjXL05m8VuFU4FmreCrtrFk8J+PcYgZyMuhaNelb8m1WAsjna5U35Jp1ShuC1XqTYch3a1egxMyP7y3KQyVf1fouqhCTVbqAZbSS3GYThOalbzclhqHcsFMdKqzUq/YMHMoy5NndPOwY3FhLBS20YrKOJIjbHZRiI5zLLGcdZxrGCCROnxNyCHsJpgqEIQKToDIfQkYLBiWpcwjYTP1pgwExacv4FjJsEMY6Q/PEzu/hCE3ZZB6QjVVbmFJPwA7YcksCQW4z9YaypiyvAIFEkNVAUmgkIJkyWJ667ClZQNEMdaHsoRctgAKW+bC6jHBpwJQPGeXcMLhHJlxdPSFfxxRWB8VyRpByEs2j0F1Q4EoJDOCdL261IFdd4+3cCq1f88PMdN0dQ6hZFeauSVdIYduMxDiMhNo6nQ77WeLMS/S5mKHJOM0trSCimfTPZ/ffDhgJGmDvTEQUPKDdZy60tAeeWSMhvJBhHcII0dYN0GgySAusoBEHh40xODBwtAux+0/evnvK/l2FmPw7buoH0kajN4B2jknMPfK1LFRjFa2+ZI2ypcu1YKOpjYLjCYfgwtrcJvJDhPwDomSQM23g8eFMDFXtm+eedz5leUquPl9q8OWzlVrAPiNLOVG9MLYz4KPGefAyZTzX6PQKp5E4z0iwQedgF7ZtxB2IDWubLgs8YCdnT05PGffnUx5AoKfnpB+3lU8QRWpXfRq3mRsmcZv8o2InjIRMhzVdzqcikD/Q4YHgJWXgNJcfECNLR6v9VAJBYx4JnXtVclK1dLw6P52JCBKMANfmlDQO+2A3E5E0+EzMSK+6u2FBOhjkK5aaaQwbk5y1sflrJooaxMaoAkb0JscTOk82S538tM9UicYH1Qf5v47lP+p/JQfYZ+9Ug8wqWb9HVQCgBdL4SUwSqIwTmDsEs4ZEgiKXwIXKmIjLbusLP7zd/prHtVpq5Ws2deK4y70851EDkQzdm3OutJihV7mUMkBvkFDPEo7mUgGOyVt0vAwS/uFSIXDUol/IFHcj73PJ0ukMrJdZKDvpSOjy2bY43HxGSS24HViw6eRhTS8jscssIC0KjPmmYTwC4gNYvPXf8BgUMIQ2gkEPCtflqRpP6oYHj3XL6vE0CheTqUynZwEhuDUcjK61Rj8k9SoKNnBdFBi99DZA9TR7erGyZ/odkFZ6gYYk0IelDVWioIjg2ovCQGXZy7enXyrKrtmMtv5XzdpadRNQxJ0zrCITuRPBu9yTrxZDBSB6K1S1OlsGfphhQ1mo1uot83Ipv36turHpIA07vy4OqMg8bbiz0uvc0LiuAce+xtZBkhe3D32CQ2ssRtZqvjZyWknhvEkdZhklJzfZq7dcGAbt7PSWcy2TxVgwiCFj+NgLIG7CG0N4FUQZfAC9KPc1LmVDBDHM2l2R6u2Wg71zhlbGaDZ2M0ydhutYF5/PayCJn8u6IPzP2DcoDKs8JNAeExDC1gArmc/nnf5gd2//4PAI/8j9B54f9/qDrO6nPzj6+pSgeh5WP7DkxJROsenXXWtNbHTN/l7XqLIvYGrmhpxy/3B02Ds8GO8fjcTeYK9/PDg8GPf2j/jR8cFR/+jwK1RhGyRewz5WMXfKn/5r1mbJMWyMZek4gaZEqb7eyepAAU2t1IhW/z18fPrq6emr78rudr5bcfqFvlvTOjsdMxmbltJZhagpPRFe5i5VU5eoN6K/lL1O3KS5mU/HqHO313olxDwNM8a+jURyA1opFaZcS5HXL57WUOXOF5lcFCVIG8qhqIa/5XI20/0NK850CKjfltHiMpm1WQpORKrH9xIRcZ9dtCCpVQyGXKNKfSOnl0YubcPbQH6slE5mF2xlK2fq6PjgeHe3P+4c9o8Hnb3dPadzfLx71Dnggg/2hLt/NBpnwr2p8sZ37rqdSzE6ddtWfZWdpR/OXr8ilVsSgm3edkc3ZTkeLL+KowNHu/qhQcXKCH1lAdk4YT8OIBpX8FnKa0409CTaAsEDQDoOZJC1fxzUq0RuQ2TqVplsyY2ehzdBmtVGYUuTQ0U2Trd6J/S0+MhHjivG+d+fiYtdDdZYCpJ45Yvh+pMrVW97Tf0UpL7ejJaoUvSWAX5fs/RGQ9iY8GYELn5G9f5L1QtTLbUpRc/dz4gi4Z0oN4uBobVKzboEeoULpJlEryndxfhmMQgO4s4fB8duZ3AVHXf6R3u/d/aO+7viaLp73L86+AqvjgVyrz6p+URzZTNrhOjeqUVVNlNtRngjv2o8/5AuQdX8eTZeSr/V50h3vXx2jPDnOz0wZAtFKmHuY8K2KsjYlgn5Xvh+2AYzkO/+y+eakpRoq88JFSubDxlKfpdT0TT5Gua6W2WjqKCpO6c/NbQ66Y2Rl06AEZFfNwn0XQklU/fqFSgYDTo6sN+2sH9fRF7sejqZRJHAv5mfNIFAjgY7OuPGDtx0O35I/kM7fzPr4oj1nUT0K36gVokeZ805ujDmD3+MhRvx2Tz9qwO4VJANpITTfdknarpuVl+X5kIqX5gp0MOnvE3VCVXQLYb9WkOqhftvmVeAR9/YZsxosywHZgllNAGLlVJ99zWoFubfEJEXuiZEpDUhhX0EMy/xJtivIcQ2hQtLw08VOCgmA3TCwI1TJEsgb1oJ42Tw4ONEYs8ZZEBjpSOECyFBP3Hfc+lIJbi5HrvvejEqVh60Wb/XBk3hbOEn3twn1MKDHlug9ezoYK/XSx2+J+glHRFAXBgB7poyhwpJHQIFBPC4P0UUZqDMvSARkyy1DkqIRXXZZ0a2k5Kou0YTuQ2owE9ku+8/BYfQG/iWF3+9OUp5hQnpUmth9Sdh5CVTG5CaetWJ58IBYZ9diaXpl8V+eyF4FLBZGAnLadOdhX96vs+7YTTZEUHn3Rmhe/4sRjsnb053zhajxBdPouU8CXe8GXih/CiWf9NdemDXtxaXj0pvVdhfoLqll4phXYnlHXWb2qkBlI34TWZNwK/5lRMfwbTOrwAg7vebq7IT8Eosh+DDerBXHOtjfN4RAeRQcXGm4DzvsrdyWYFjwyV1EpPwXUDzF602u6AewJ9hxC6wHxct2zgQ5zSbMiyP00edhDEUevij7BJs5d9Qtf6zGLEfxXJzcwAa6uGNGMHafyBnvooCv99cZUaqV1mjkX7JAonBA0oW0yK2Z2xChGbhMpgGPHriNC/h3e2eK7F8hx2qTGesRcjAgQrQbqT+ir1JQDhH3niJb8A2/qNI/37sITbgTcTn9HgRqL/f5ymZTaBYbM9G1EZZ/ioZvWRkbYMt64mqY/ef8xZPXVjhHv9yKct0m262T7Rh7uRab0c2u8upkqOpv+bLmdPAuWFU62meIqtZJXccY7XTFn6TD21I10OFMRlyje8eHfZ7R2LveCSO9g8OjvsHx4fHu+Jw5A4+k0bIOr/rGNUk6bLzV7GsUmC7ejkPufrQFXECWLZwL5E5g22HwAuZ2lAWY0YxpotVcWqdcVQh6FWxVwh77/8v+QD0Esj1RDTIPCs5x9TIgBoiWmVQVOJLG49lhiySbXE+tCMJ9rAyC6waQ7qxoHe5Dn9tKhhjN2zMcmgEJ9xNbEbCo4lIGrkPvFx+j+AO9qTENU7nr6UDccbz3Bub4d+LxPO9P0EhEKwCuJA67typN3ptmEgaWNRU3Vruof1JViuNZ41TQpUsW7QG2uiXGcSINp+7D2JMPpTJKHc9uekM3H0Qo4EMWw/b5IoPDWTCn1SVDEussqewQKc0aO7LPkFSUq4DOKRpWzFVeQjer9lJpzCajZ26GWjh+ugBsEkkluQcKgXJdzwRN3zJ1JdaUNIeiVJBFDPZ6tBTOCEXLWfcfyQfX7QQecThAXg2A4pIOBtB0JBUkCyCQPhDz81owYuK4EUABoEOiiodxEC5C4tXOpQmdhz5tbnViTHnCeDFzKGk6P7STGTzcpEsuO8vwRDhL2II02hElDTiNm2mjGurqooDevcuvVw+0RZOdo4lMoMq62dKrrqOgrMmRgNhhNBxT4w7k6n3e+fKnwXh/I8oThbXn+ncMTfORndjYzl4AyJewxX705snTMkJTQ+oL1R9YFJ4bXmw0gsrA5D+ZQqFP4vRyf/P3psot40sa4OvUqETf1g+TVLctPacmUsttuW2ZFmL3XbLQxaBIgkLBGgsktgn/Mc8xDzhPMlEZlUBBaAAgotsdzfv6bgWyUIha8vK9UvfZ+O+PRWVlb+DiAjz8oMWXV2Sp5cSIzjXpbLFjzIJ4h9EvzVyxYtkY0i/UodMVTKhoZJvzZNqy9SDE8qaxNlfiskUpQpf8TRhnoMNi2rI2nDJsYrcprjWmqkkzyij4siNpYf2gzaifL3cPPChhJYQreicKjdfxcK9nKRCt6n15HXIa3pPxSreU8/CLBNczrTMN4PSQ94sZ0lS1BSYGmULUX9VVCqV9h7y0Q0xmWsA8wcONUL7bhjEjwF4Z+gR8KAdkPIV7RNxMVs81oN6QZVXZqtKkX3rX/JFRabPeY4ZlmRLGEPlfQIpeyfn77vvO5fSX4LOBFFORLxcBYxX192AyRNp8JrphqqL1CZH0OpDMiooWnk551hDD/pDwD+Y4sqtgwEtNg3ARMpPDa+VSklPmWI6mfTIn1CAMdXprdMhPRjCgbiQegQtgtKv0uMYG36PjOkEV9y9Z55nmQzZxa3DPWdYI5jwwpYkNikmJNI8tu25vh9pmDhd2Wn6MGJYWNLgWzEuHYtVKUcUfOQUe5LmNNHhrcN3jg/YirwGIyi8EzCgcwiLnkjd6tXIacAxhwM6xdqIt87DCC98Zc4HgwrxRRxRFIBI/NC7t+6h8GbogWBw68hn3MEAda8+Ne6I6yRmpKCgYbKsud5qimQXz5WgWs1O0wNCLEEKeDJM0+Jm2gtlbcUTKreURCdOiDue0MDi2BFwqjTrfwwhY3BSIcQT5C60PoMnhCtySQhQnwhVtUYOqXH3QD3T5/Ut8UU2yHGPzJfxYKIxGbjgXuFiHeBq8DKLto1XJh0MAG+jNJxGs95sVOvw33W9foD/fZrBlJMTARgH2YkA1Ah+WzJhJHA9IoLk4NBHAU8SQiJnYgppd1yTfZH0zE20hssh1oVKtkI1prcAvqqg2M9dyxuB/Cq6CCeiYGn0oOsRd4J7Af4K8XhHE8JrOXM8Vcsx7BBlPAcZZWYH9pa9VjRrmfS0Jef4s3LQ/vhcKhwjuQQ2nAZ5S4ra8ZJLlnACeZ7rlR6bwGeE0iYb0d8LPCsKr+ZzMNgFnYtTYgDQ9gP1lVKtZViXkBPhA5ZWZj7O78yMal3h2A7Yk/g8w62yQV5/uE7mtHvMZAzQBjCulCOYQynf1IVUtmhsSsyUc1WRa6VMfZKZotzPvJwas0fyd42sQbOMbQFV64rBbhVzk0Ir4jhdPle4wH2I7DSiOZI1S8KkJadIIUo7IwXCbtwmR9w9ihugDCR0RbWxbqg8SFm5M7JK44LcJbHKKbFVXZ0MuNm3ubkLhlJLniI4jM982MxVsT9mnilZMll3sORvZPMPqGD++YD8d0T9UYX41p/s23MUPN2BqMYMIVpIQo10sDS1GHiF9LagHsbWCPKsqphmVRsFY7tHHnC3wWpBmJdl8jrpEBCo2ed6SaYkbxMDqaJMvJE5w9EkfC47vWsOvhAH53kpGrIwCUMmSgQuGdM7Fm8pXua8UKPUBRDyyBx8lIdJoGwBogWjxigqp85VCf4moccXdIuGRjgGqS6Rl+QlLqWL25c86aUa5dyKcA3ysElCsdTGCMzdRnypRAPOzu6T3H8cHr+ryzPjNe8VUD3qSzj9wqAjEAirIIKmBPzGrkbA9xg1kxGhBbJz6PmuDmB1Qr9iOOod1iCKtR5QOl3fCiKEWn7LYml4J7CckHHpQ+w5+YwDYQtio3rMcD1QhzuCG8YKPOaaI0lSpnH7eM2YMYAO/90nroAf5BPKD2YXAHQBeiQ0QB4v1jE68H/n4ej4fPfqCzWunav3/nHY+vCh8ebeD3bMx9cvr79cftw+HD1e/G4Odt7shNfGxOyevw++jJxG4+3Nx0v//cn07tG9eXhRff3upm06O++m9qer367fvg5f1i3H9Eyne2a/mpxdBv7j8PcvfvXywnz18fT9uOWaJ93w/uRd17x+9/LFeM+17j6duSPHb7WP3xwOvXcTQ70FOWiKDFGaEbEIXlYaGXyKG0vDVwR6nt4Mr8IxhZuAmiheiHbC3IaIyxFpNXLthQ7a4mFPNOr1OulPA1CpBgSM17OU1mNea6cfDkFDrqWQAut5GWNyDIFnDYfMY2a3r/Fqv5Vh+cLaKxvzfRVV/BmkB1VIsbIu6bOHPAQ4kutlYk3zIwvLnN8kkynFN8p0y92Hud2FIQbYlumJW9V1valwkVbZ3gJIARtOtf3J1HLmGcwJYAcXg4rphIWEguQntHNuiVF2+AncqYL7YCUVWZ6Fkl6MW9Yj6FgHwxslvZi43q8k/uBLkyEIJ7xLn/cZuAG14fzUyKmwgxqDHjl6c1ohE1BhMFrVCSywe8NVC5cfWFcxOShKJuhVq3JQvQphFopElgPIBhXkuGI11Ibk2R//vVUQ2G43Dm436s0Wa9S3B9UmbTer7cFev0obRqO62xrs0CZt1Y364Hajcqsswy0e2G+fn/UwOQoZOOX0oWyBsQPqe/8nwq+DXKRCA0gKUz1e+iyuevQbHmyPDsAUAy5QiUtl+RrNOCdbdUwfrTHsN/7Jcvineq3eWArIzk2Ek77PV9TTZ3GmTqoQUEmdkeS1kFLh1DnFwaojKbUdhKI3gz4ess+5hXLQldOa4HaqpJXFtC7pegMlGjb/hfBa+IvUDCiNaB2RmwQHNhlazLrcvaGTbHuiCcBFjvt+4DrsgHgswHArbv4XzhZmKink0sR+63BjB7Ig4C8AzuyLzEaQ8PnPY5GwTPs++COknCXdFoBt7poMe3FcggDNqapXEtZtTKcRhjD2ENFU4c89WD5T7lbwC3gMJgOioM5l51hfEf0qt45INwCIRW73QveJ5zHcHX2blfHv+IHWon8tJ5VLA3yy+cQW7wIJ9sxXpyAD+ox6dz7nMNylBQpK2kzD178EqrQ0dXyey98R5ccgVlH+dmSPE9C6nGE38KjjD5iXuzOv4+B7H9xwCPkXPLjVyQgL+YjnyWYP33pw60SdV+WPveewpga4Bn3pe499/7w9KrMeM5h1D1tBs8XFFo50g15EO3zVk7YudLzdOlCJkdgQtoarUeFeFfVwRb5jCAuw75laVOPW4VzqmVoNDhwDNtfoeBiB4Y7HcMpEVbWIII+ZvVsnelWN9CBjCeQBPFlpwsGpKFfxV9ITMLLdwO3dOon2Hv8WH8DhiANTxu0pTXjFDDO2jW6afMFMefA5h3jm3zo96RavxYbM3nO+sOB3FKcgtfVdh5cXuHWiPeOzILCZL6EY0MzpOvGqWcyfFWQ4nlbjoaWRxr9VctnB7B1ddEizWxxPm1jlsqYtfuS68ingLOrGyDEA8a2nxM0oByfJz/CoRCAVt47MXYRnJBuH/ZW93HhE2WNQIxcew5sCXNsgvPO7tKc542VXjA8gTirJLNlfhL3Gy51et2LGm3P/46bXDidirdJ61KuIexU9eLwe7a0TRWVgAVolNCO5J8CUY3m+xGWtkDEsPejswa3jOsQP+z6YcyLkVlFG0oFbmIxDoIR7gcUVagV8KeAs3TqM+63xTIEoUcVDzZ2hKh9EaUDH8iq3Tpbf5TBNhQfCuDi/v3Vwf/wlmCIPsrl1IvDveJ1UR1VVxDHoGCUf7tNxyjfIjPm5ImcU/VCiqvaviXC+ntyduuMXJ7+JVsqRlN+shoP+/MyD0zqTSXQxLs/R+RU6zjSHVfDRbYoQqyS9vecVYYFAUZvY1oAZU8OGNHM41FxPkBVUCGc6PS6hEx/drD6/wAVlcBxwWeO1f/4rT1yLpG3eNdmM1Bs43+K49ypJkek5HnQOzX6viJZc/Lx1NnXXznPkBKiZ2FiGBsz6Yiyo+Hvc8Axk8PA19kiNAOwyVSRODJCnqHAz6q9SLQEGY1u+DKam8dC5zCbUGTx51Jm+HaA2XWbn6u+Fb5WFnk5plwv2Ipnwcr2ovHu5nvKVlG8Fhyc1Cp2mLbdfUtNGcI0CVfuZUEC4pivVEMtHhzGgCAEPVC4ysQWFpsC1bzrFaD8UxVDRNkNPek08CAcLoUq0Y7oPZJM6WCEQ9qDF7wPG2e7z2q0TXaQVjXYw+7YscznGQ9ELoirSQVwQTYibpjWAkxvpauo03DqbCNnGp+15XKS6D52K+5VG6ttmzFw4e0sKsomI0Rr5AKuIQseBEFkmQoK1HPLy5BqkWBHMOevCPGcP5zzaOl2/KIXDUqBmJK0OfEpTEpncV4WYaHwt/krWh4q6gQrOq4Zf6M6sek8o18umVIcKFLnnB7fOiAJkINQn8LAIlixyqbWpQSiOw81TQs2yHH51qKpTBZ9As3L6CPKjL6wmuLVHFK0aNqhQUyFYwy7n0jewgFyVaqoyEmnmk5yEzM1I0DIScRKiMhKFeRUxkdhQtzJznHxRWlnJrERhMnm8CPygJBZlNhNTU1EiZMccnVnZDvnaM9l0PdJ3IWnSdSITMrDvI5DCNEZlZSISAobK1m4dHV8jpdka35Z5+reOuf1lOE5qxVWuEycJzEqRyM2NiBIOdAkMMv8Agz6ipQmi9IU4M4p5z3wyxDyMW6eXIKYmcwOEzZMGSueYBxCFd0LEBAT/K5H/jugVUgAh32kSoI8w7gFilCuy+hG3qpcyqS8V+q/MTokIrNWH+zPnPkv4YVG2UQXEEs7YZXoY5wk9aTHuwax7oHTHzEGt5kwxVJB7at1B5OvlC0qNkRAhgxEb+8y+Z8LEQh0ZGQarCzFOIoNmLBcNWaF+yaKJ/K+aQAQu9BIZRLmTXFINd+5TiU3JBUj+qLne1UyeOBXIuRdCXccRP41c0MqiOZ/QKUzXrcMnnLeBHJtoodA0LyNXRBE2sbmnFdJnBg19xpm5FOMhxcO2FCmtRq4Yi/rEMfSiAKaIBHfA4+/kloGcwzKH68myFmMUonih5zpg/ERm2G3qcP0IKKUixysLdHksr6gPp1xc8SJfuiLjzkJf5macDqrnrsOqZ+gfHjEKuGcY4xZOTIyKm4HfTve3G62m0djebTXbjabZbBqN9u7OgO61Bs1dmo0aUijnZh9+8ZQ/JYr6o3AuYQ9CPrNJb50en/EYYqunKG2V7MWt/uh6t05PmHp6qYy+Z740AopXcnM0vyN7t45pwRjGIGO5nmpFIoE7qdqQoAkJdXCf9rIXamTcRIEXeO6U8Cuzl7ygKyLetZcyecUdgDw1CD28rzxewlhWKtObvG4djXmrRq4LTFuxaSFlxQbV9XGC4HMgcULEIqi2sQUuxpC9dbgOjHYse/qrXjGwfMVOlvJlxQ42vRWMJI1gm7BSFT6a53LopaxhJN8Yllh2HpE/mYjCUimJbxFDWWwblcdnVjf839giJbnw9JznLeCR/javFS/d6xK2v3hICetWysKtRcZXa7XzduhxYI4J+t1XqHMZ7RiIxx2PIR3VBM0QLi7Hnj6XD+DCQnnSSCXxa6RnsyE1ptW7e+wmwpdAN8QAuAMV/OJh5Pqq/iYVXvZoQQg89clv76v4KvPXJPu6dTBFXqo2Sl4xUKNSEIdrFKIH8XFvVDaiRzey8+oLbtsd04lmbuODKJibn+J+eoZbE78KTxSXvSUf2kxqD88FV0OmllU6QDRJaAG1jIaV6jdt87914HRS23ej3plJsL47+n6xUHS8YrA/HMOyLV4pgnSCW2fs+gFEJ8p3/arcDpyx0oDwRs098PV51EDY+1mCasccWxjTGqVhR6pGQvWUZ/xbZeMINHDusIvORLzWonmKw3yrbLy1TeVJ1bQZ9RgZ8SJrW0F/kT9LRztqJlnilxWyE+LBN1Tc1V4g/DK7v5Pr2cVshgLZom+7xh2IlsnnCD4H+F+gc8buz/s2/wV2OodaICFCxaI3tGaygFq235MgnvIQJTu/dQbUsiF5GPsim2jQatTr7XrzeY10bBvvKRH9w5tK+whH1YJYmyGqoqAkewE/kYpRuowvGFrrBfG4Iz4KpBIYIcTEa9NiykbXs8eJTZ10UZa4n+IqM9f5FsyITI/Z/M6HYmAgx0LNFMuAt8+OOMXoTY45AJoPf7dmkt4qcYJ+OlCQ3wlRsBXuMO5GjIQesslqwxpEUGWDIPkDkseih8++dWR3zxNLm4kcTk0owtowh3qWO9+py5yjqBvMShsOwYyoywHqyHo0uNwjuAgGuCoQcSYNtrhScnlkzV/NftAloG4oQ4r3ne6m03GCrprxl91c8niT6HR7kgFgyNur6+sL0q7XOemwWFAwx4VYzsiREyso8qaCI5zmL5v8PXDyb53o6F8n1ATepCfG2CN0OPTYMJJoIx4R8RMUOEbJEzfxXJ/9KsDVReaQqfCXSJ+H+Au08SCz6/E0sD8+1xKMbXF2EydQlot6h5lRWmvq+fBZiwQg/vFzETPqyAms8CpHVZ4pkJoxPxyPKbergHA2vXXi2Uqtoph3nWCGdJRB8hRTq0n01i2XngBfrsutk78wC2VCF16rmSxCOZbPmaMLqxmvjJibbJT+kvmy+QmsYpM4oW1/rmzAP8kUnDjRNt9iKwywoiv8lBloUR5lRF8JbgXWVZ3YAo6VPJkFnV7Cg3bCHV7IfP2A2kwJz/XJJiWOW3UnXE6JMoC4axol/rgt3p+ws6JaLwkXvx8Agov0yqGjOwL/JFD5q2q6DwgwcutIR92EBnCvPV+tmBIP/y8gqyCZP15WQWWLL6GS2yDAeGDRuaeedMx7y3e96YEwO8E2ZONJME1FP1ncaDIF8wwd4KYjHhu794z8f//P/4sYHpgbEYyYH2er4M5SotOrqPnB6zFy84eLPCuVQ7iyVaCSiAOnC9uZjRySH0ftetbQAqOfCCF4rt4T2lT3HBcy2CeUo7eputE1Rc7Ss4cUYu+lJksy9NTdGN/RD9JJYGqsFykOaWIsqcgfkjgXccQ3DzIVgGb8bES5ktRRJDvkwLVb5zLZPQVTr+vkWCx+TflRY1Ot6nMHr4zpchRJ6gWWYU1owGrkBEQR4WID9mY/0Kl/60jP6+bE9SFlaErwWD4H36lhW7Df0ehvBQzLQoYOVEoUOrkNQcNHopVAjfFDbwBcqvdAEWnNR//R2HIQ2LkCIT2o7wK37REa3DoQGuERYHQcjYn79sCb18Ojj6Y/MdQeSKgw1tsN4A8kcEFyBhWIh05NAdOQa/y3G6g+lIO44wG1BbCk3JDF0/lp0uCHOAUKqy7KzMxubZknVfjutJkQ3igeBElaqwfOR4ZeXjhXpYXofkTrGQoFyj1fUbh48srX3PPPhYuwQHjpPZnsiUPlXCW1uzR8QhVV1LWIBxtJDI77wEUl3L/R9aVuz5gDbDp4sQmYYuUiFi63+RV1aYTLXgz598HS6JzFd9Q3NUMHIB2lQyOZgwzBZ9VGHL4Mx9YXQBjMTBW0Aa/NE1GdIfVbMihKc0Yxnw1OYU68nU82Mbau2iysPrgCopFY9LmWYyZ62RIYC09ZQS1+YiezPEtsQ8n2ZzAT2ayYEYhWS6P9FXcv9dAk0kJCYotyMOQMx4y7opq/lc2i2frK7AiOq2NCJcQaVUJNK/3QFyQpQYQRi7WRgA5FnYrBFBcAr7K0YVl2THj4AJdbpLmN044BUaqqKAWAMcRp9z3qAACE0As51ILl+AGjGJsxoZ6P0ZvSKlXslILLoivw0lwAsJEzwu9wuYNFk7HlQ+cYfSnt/pUN4bES7gDRjTAoiN8ioFh4jYPONwaBb0JQd73JiMJr1Feqie3Cs9KFYQAVGKQKGpfHWDewGNgNeSGQbuR6sRx0MEtfKEi0gmmI9AQxKLw4FZIzzYS9t9ufdqW9N8aPVtvHcnbXNYxwYqX3rNyoOEkDN3TSv3MeLOc590c5fGR9XXh1dBS47qD0kN8m1o8LW4vX8slSFkjfGqucd3ke8gxSzRCVaVys/PdajgZpoXBceU+oczlH0xl0xFCEYWRjjvd7okF8zpIO90SjB8vDoC7QA3x+ThK/y/LvqT58lR/GrSfUA/xVZSFmN+oCDDUuYGJ3608LCmTdqJX6ApEC3BU+966QWnVNDDDlhZMIybUMj44u5nxN3ZglPkTSg2iqrVte2t7lp4VZrqLCna+8XqvLIxk5WAdSbMM2NXIUFfHhOibC9/JhajMdlUI9sl3iApDffS4wKWii0nFoIJK7D+mU3vKeosCVJ3meFc8XdaOVn+hk3iKRF0yuPHs1P+9hWXuoCHTH1ymbhD5Qi0PV5Sb6f6sUGI6SCfjJfAWE7+4zdf/xJPzSS5RJIJ8h681pExePgSefoyIdAM6LFJNunYk7CYURFuQdbl8JXJNCUmmu9AJhQbeOMJVg7hYKVJhDUkqs4XFFkKbjmVw+ex4LYtISgxq3tMdQZxop73g26GTCaE5s9KImdDFbK7efy/QjuRqrNqdLupc1qP8kluMR9bsczTM/BSFOjJCVaDL4n/kurKJ4Yng5rz4019vFI0u/3opgw7JvjyHFii8iid/VZgYb7FFz36CtBt1r7TbNutHabiWTgFrNYopsCzBvdEABiIUDiRSTiT0tKP6Qdy4nYTcPn5aO0T/jDsjRxQ3B8gkqzLXMl7AcMrZs2/JhA5rq7Gsc5ts58JJ+2JegvTkWf4SLQ7T/uGmGHgT7nWC0MbYoJiYP7VLNpLDd4ST0R/nb8A1vgLGePEwjW9alzIYsUw8kB4V6pn8fQIb104rww0rhMy1b9EUBV829DHVY1bpplsPRSDUTn2ZESJToXOU8qvN9yTiNCD4QVhoM5a4RQkYEZ5Ghp4ELTV4u2alIo27mzDj3Hno6+9aMuIRMQEJlI3SsryE75YOXpWEiJMHE3FlDT/D/gE3KBH5wEAOBZK+TbGyJny/A7mNzdMrFFEcvp8WvGSa/nL2eSYl02MOchHKb2w8hlNtoVk0vOkOu3r2xhDdg9bRLA88chCNR+TRzBZFh6Cj2XR52VCoE6aGkyM4pTecu+Oi39AnUTpRqPykxWXGSMdwNxTuSUIHlAF5VcbthbV+UlDFrkv9pipwaCaKbuW6ecn5RleCD/TnX6JuWMQZ02I38zyXAu+Ewa9PbrqFKk4uY68KhjIJ/QKJ3gcG8WEq8b5adKdc288kIRdWke+ZZgymhQxCHg1yaMmIi1IwMRmxKTNd5FnB8hIqCtZXAES0eUKPk+qlr45ogUJcH9LcpjEg89WNg/eOqhZkTkBcVY2m1mY6Ssyz0F7LpDgLmqOUi8eHnYMGbeJafqDkkETg7AbEZTAzY/ESNWonwIiM0gIlEdtsooUCCqME27oE7WehePfDS9PquOQXzadCDMAEgBKN1/o++t/V/XvCAD4a1c5gTVK+nE7bpIzzUAekJzRdGuvWF3lNO6i+id0DRYY+B/hf9o5pnoq8eq5NpMHKdzBdVIWyB4JfuGurcRg9gzm66hWsEYM8KPEbH6d8EquKYTgq9i9FuhOw+b6qTsEuV54hq2Wc2EUB+V5kDkqSpLGdUPiACGoZ15HjFse4cJz/NVhdji0AZ04QoeNME4tVqpHPU7MSQ2mgLahzCCmRgNErURLIlcgUH4XkPkcYC6UF4njDLEgAHRQBib8ACY9SDAGwHMmxPeZEOLMFXXOG5mEXyR2pfcGgZXIxSpaESD0Ev2vKK89ewwycz/UUF/xYriudz4HPucl0g309m9mlTlJfN7EPTZea+msfupiQzxuNMWeMKgwdLxg1yMCvqIGAoXt5R8KCwH4vk0Ad5Y0bnQXIEAPHKDyXMS3LEbEWA8FLJSQcSxq153CAcPM/qhwGPr+PQ03zMfM6XigzCgMxvlY07xia5VspLxmtG8KpNPFYB3fIikXrisXvLDX17Gs9UskzFrxFIgW2xEEMPEPyB84u4VCCv4sMhMx7herAC0uPv7UkJKqB3DEL8mMFMLCcLIDWkp4ygV8JMJMdcurYzgQ5RZ4DnuHYhB94VG6h8bE7Jiyq2VpZZZdEanottbaUeFM0xLTOSWpa7I6AjKT2lLgq+G/nay7sBIM5s5qVvB9HBwrdCJK1rFvgs+i1p9k2eXjTFu4aFbEFkTSQUxAzPmy8Jn/sg0crUVagtm40fefgzHYA1y+3D9Ur5HVJ2NyQe4jLHhBp3EFIja0Eb2vjMa8R04KfGmYyJeEo1XIA2RW0b+abJmYLgstGc3jqCaaCG0g8te0bOQFKwit4gKpPoyeQAEvJFkeddYOlz6mJaBdKGGA/UYKQzq0O1a43dWrMpnWE5tvh4lnJC99Uubdek/JSKZ177rlM4TDlACA8JPApubeoT2LEBFkuTL8cqNsUv/7/5gBoZ67PDUSY1JFWyi6Er5aLTDjHWUQLzlNm00QMioriyEWiLK0uuzkfoK+X4oH2B22dFHB1S6kDS8cMxK1+CMvUUBJeCiRsYNbPLdqI+kjWeRzrR54xyruEua2PPDzH2QAgVm5S8y7Cyt1m8iUtdMUlXyAz7YBzuNnOPRKEMmaOkL+6WwZ6SjDXrXMoxpuLBYTLsM5sfqh9JFS61dXnZGeVlF9pb8RxH07twNVNNX7O3oCjX1S8tHSkhDZnihqXU+vgJzY6OLLiLEpQyAZfaRMojOYdMDeUpddWIEJxstbNSCFM5xdKig93FfNey3SWeQX9TCChgAv6q/B2ceiyHV/C3ValjymqBVSgUBMJGVQ8gKSzTIHJKeU0+gVeOvgxcHDMlcpRq5AoDBGVlqnwSSB/xlTm0pFJ/tSJT6gTcepz6jbhamReWiFYrrV7n1ZL/6IYYjzKAhGYA5xDG2OgxiEcLPWK6hn9ARkEw8Q+2tkzGET88v2bYbmgOINK6ZrhjuZpbCYvWVuyEEDXFpTS09S/5omVv0STCaLKAoaw+HyOfVkoBn37+Oe2easEUjdijLRKrt5Mmt8wL+FoCC6OKDoV8LB//NJiHVqoBowGipwifjDw9Xoi4BTVyI6Q+0UU4MSAhdhg/6HqIPoziE4AOo7owYYYF1Th5LSCeGK+WXqUYWZ2aiaVTpbLTUnI+49214bgm+yK7AgUsWpw/PpdUWlZrc5YWTiiJMo/NOQ0p/Rc0OWMhssVMztFug6p685mcU9T8CuiepU3O5Ikszj/AtPnEtkD9dvw7WgOXM850HbcLYIWhnxEfcs0218D5s5OviQtdiM8GizDW8bQaMArwF+NpdRL2bcuoQp3wzxiQLIIMG/U0QJGm34VtR3qRSl553KwJeQfiIWK7Q6UEaSRxrWoSVfJkQNM33fhLDHZ5A1eBdM7jLqv90L6r5oPIHSMAlhQ4Q/uOx2uKFAghBfPLX5fOVBwpWj4od161KxvRFSNbxJpTYTD3t8oGzxzwdFaSjC+tcK5nza/ITiFUhgBEV5+iCORqPyUC81esomsSO5fXa1evtscmsPI6csoIM3NJq/y6WlvEUhax+Sxf2blfEoVO6RrXZ226XM1CLbRC2oUpTIw6j6uoRq1m+0TqgyY1dtv99v5ev71Xb+4Z/Z291t6u0W42WHN3f740KYluXyIf5ipwPWYea8Pp1PVLaSgjWEV8lGDd2RLLmOFxutzC02Opl6WK1RbO3oDt7tVbA2N7u7+/02b1fXO/vbOzs93eprS/s7dntnbqxk7fpDv7fdpq7xvMbLDtQXPPbA6MprGX5cDfErOZErxToH7qz0nbn1bEXbTQUYKMbLmjwiSrMklVUHCk68OUgqHL05dO49Bo2IQgiBm8PEFZjbwACbUO93+DbDbIfwBO+39VSL3G//5fauY9T2dLyC8KtQ09pZbvh7oIhktGbYxyJqfYYp7FSEu5cy6Ol341WGFXukDfuPasUxzc4eLbTkn3L8zbUNuBncMT6ojMOucWAxT75nK7p8xZGpVt1tQjGSuf7mXOA1D0PY6Bc+/yCOyufmPIGfojbom0fd4sb2lPnO0teFr+VMUP/4r7xi+eL7wU+V5zoM/yNVHPyhYgohHGFC7IHIuSNDxmUiPofg2ZN+2K7ZtLD7aKglR4tQAAXuWADDIpl9xcvkEFlO9ggHz1sOjJojuWP67ZpR76fX4Ai+AU/QRMQhDyU7EJsdpPzyhmnh+k5ClPEN9SdMi51cS1LUMjSUH2jOfaPhm5D8Ry+oCaJWiLqprixwmFlMAtPoG8dhQvl4YORcBTGnMICpEeD8vOQ1TNGrndoGEwAtEc4lRNwDZ1HRfxmHVvjA37ANQ8nlDHkkihCDommkOfMv75doOXKbrdSGO8ivpFOe8CZBQObcYha/iqxBMnnVywVfrRRpaVUXwCMkzsg8h/XCBDpxdYAFEXFUxNzBzUncfhbFS0WO56VporWVebf03ZemYV0WV4RGYvl2EX5FjUjrN80ihkHvVao8yq/S1F7tnVX1clcRcP9EdL4IpPJJYBN76nNP6kJ6isMP4Uh+ZvIaCXWJ0nFtBTFMyW1/WVmbML8vknEOwXwb9ZmaD/ZJxpRYL/annTYkrAk3Kn8jrAE/CnJ9cL5j24azVhrSZINUHPw1V/TBSXUhW1yFWYqRxNIA/PELmLrGnuKa6bYscDfRC1roZ6HiljOkSDuMJenI0i37ls/EY8G/xl2Uh8iwOsc1L1EykeXXga+fOlpy/0qwDVUc2mpVl5Sy3on8MpKie4YHmSq+9H8UmWp6yYePPq1inatZmViknWTkJORbKjTMjlH1dj6gUQeMEfnEeuTIZY+9BRNaIAio5gTO0UkoTZf57h78/wpal3IsY9lmeUx2Br5PoBOFPxj9naO8DcdKlD7emfzOxSzX2FqauA+SLAGRMoOfLJp56RRfB3mtsz8Xe+8drA4fwbTIbpfUuUFk/O7VhABibn8wS5rf+dZyuqng1t9UJeOusRqNckpaZHGbO1dCkPOPeCaSFHRthmAIiRlIIYz5eRPJPH8oA/8Wzm3XAQM7gSoxFUlhiPPEDZEWFVVPlzzpBmkD2xauITrGcZwiNySpKuOcBHnGpUlrCW+SKkm32V8oPtdqtZlvwypOvPynV2y0DDog0ux5WnyPw1tuuY43X+dXZt5XutoH6i/mqn5CeYrp/qVPLfNXYQCVsXv4o39cmmERVwwBQIHhUr6hbwRkvXsoqve0Hgt0QAO4L/xh/Kzr7oKzv/+QKpkhjwNxZNY0EKANO4wn6hbEhhtftnSFlzTMFf404ruszmGOyPvunmks/mHNePvpZKC29Ln8+1ZPe3OAw/gRzztzl8P8Fc/nUO+1pgzBcY9YvwlxcTc6Ssysy9kmu8y6av4/dAy4+RG69ujo5Orq42Khs351c3FxdvL69Pjrudi4s3p0ed69O35xuVjdPzq5sXL06PTk/Or7un5+/f8l+uYPTzoItntqrGCS0KuwUuYETwouUCs8CBmlyrEuFL3dwruqL/BlLpDxJBD1Z6A5aUNVUOhwEiJXxS1KO6clPvoY6RT4TTV+Bv/189PoiRa6N3ynJIz/9q9yorw4hDqqtIFA7a/6qpCIQXg8xAa2SS6L7aG5mJqPan1QQYXF6EeaK+aVePH5d4e2UDXmAVV0cqPfSsBy5LUfxG7TBTYHblBqpHwMsM9UvoWb5pGUHSN5thzQNmenQ8gW9CCO6BIq2fv/dUCUDRBM1Fc8d3HWDqR2w5HR+QDguKhiFiX7InsJrBtyvKmNU7FPEnjsLgB+5kArLYiBExkhp5K+rNYiQFu4fAMBEeBvmkLFEBLo5o4oRpjv5bh3F0HKzbhj3hAZcxZTMPeroWmB2OncI1T9EmKivMnjPPfQBkGKqeUrkSFf6rwKjVNPgmmmjMYRSKqLsPGFbmE6jnd8/ZoQUQuDCc2ZOwANvjteO+pfrUlCfjEyrIF5OVvQ2ylzdf8OwejYrWpUUaUdgKf6+RQ9vty1hDUVmPiuqoKAZCnTkxU7WEdDP3Mar8N7M5oqJ16elRh+O5YVCC+XG2npb/5gdJnNAASrNnZ+6C/wAXJ6K56kK8OEpsjfzxhlHPQUy6xeVmGLjlDPFf5m/9C98K1YT7bETvLagkWyh0KBLH1r9zFO4YCSIfzV1EOwgZ2OJfIlF8IpiGF6l0jKdVGTMsXldC8cM7Ua6Fuh1g9SQCffGOSIJ7pOkroykYXs6VGI3t31utOvk3/1++TUOF75ifjjSrAKLSMzKmfrU4472gqLY6oO2B2TDoYDDY299uN/aNvb5h7LR3B8ZOm/b3BvWNxItnw1kWL5ECMKlhVfGPqXBQiYUJxSDiNhKa0nJGzEPrBjU811eyRsIJhMr4vxIXblcs3ABBcgOL2QCmRmX9cfYQoW1ijPGI3kPXKh7m7MAieajLVlEW7ZSCQtEor73QwWhHDOGt1+u8/CecRdt1ZsLNv7AeIVo0RJQIBehB1OuUhGqxsG985slYMlMFnZArEhF5Rh+hDCjQl6lOqoW1rtVrjQxBKj2eNRwyLwK8TUk0Eybht0GIihojUXj0lXLU8UzCeiP0NjWrGFULlk0AHBc4/lg7fFZgIYIQ6WEd1qCma1DT9M5Zg5quQU3XoKZrUNM1qOka1DRjn16Dmq5BTVcOalqkma0B/5YA/Jup8i4N0KhBRp1h5vj55OEnKW66aqxWJvTdUpc7tF1OLnzmkzFE0kBtSicqL1eR1UJBIE+JNKLePdlUEsZ6AItIh6x36/Spcccc8zlqsKBQmVnJ06+Ra3fc9wMXDLu2NWDG1LBZXNkVbCYudzVUiO9ymcxWR7HZE9PYgxfdOiCIAf9yhtXAo44/QDlWNSBzuWARS6xeShXlH3WXpLRrwSUgm8Xp4NTHUsyx2MpTnPnvi2aKY03KDbCccjskTyUEROT5yjYrT0SIyliYfJ4O5CM5eJdyfqJqZsJ+M1XsuvPbbstYTjGrzmQT250yswsXsJ46w7Z4MFR0MqBQrKCWP59Tc09X3dOjIEx6K5Kac4rDQVYzHeqBRNWicLJuZHJsWNk8yncuObD7xtOVbzK7+efrHLmKOJUVuGdHcKh0fIpYQCuIvNIaG3EllR2V9jCu6tA7yhAWB4eAWnSfi6t1Kg6TzNs0S3o2FbP4NsZhT/v6fhoFJtFFFF03Xz8iks9kUJ0ZM/dzHIcbuii1hVJTS70t95Bb43GITI3ETpQyLJPtDXbrA7Nv7PUbg369v2ea/QYdNHZ2Gns7u9saOOBYByypuvk/V7XQXOFVUXbW2kbJyohrYX8t7K+F/bWwvxb218L+WthfC/s/ibBPbXsOr07qefDmzBTFP+eI/ou+WeLTlH33WhFYUhGA2FWIVMzO4iV+/4TuLB4jmvG8fMtCvS1rj1+XtVraebK6YlbptRGBWWstaq1FrbWotRa11qLWWtRai1prUWstaq1F/YW0KDz8XTz9+qkUiZwYWiwlpjJTaTkme6x98XNQYL0gnHQhZLyrTdJLVIFeIG8p/YbZgvxa11qZriVVo1WpXHPmeS0uWqyEnWcjMtPk6hF2flBg7jrq9ntF3Wp81+s42RWynyeJje1ihYgc5YgjXBGedI6JTNhCZEdZPjm2/Ammb59rEmI1d92empMoKdALtdmk6eL7GOipWn53PJXzVdcj6Gnfr6totxIK1Ncxw9MDI/FfODIAFhTxfQuEu2DkueFwRKhMWNQlypoWdDaGqj4cH2NMJxNRGol33L1j07IJhneWY3aVxyqyD5FROHcnPNcwOuXTc56tiKP4Nm+CS8ELFu8AhpkASeDfV3FnVwUeQXbZXl+9PSdnzBsycoFnYPPyxRHZbe3vPI+QQPquyTOB+qF9J5dZJAFyM1UxM+RP6DKO6ATPI++Rq6MAP6dsJP/g1qmSKw64ReVP/EXwFTerQZYiz+SuKc17wP573AZiM/EboKjAVzaDDO7Q4eMw9ePQ40TlIl1Ez5Xih/wgAQcUZsyuXrx4O+EkRAnoAaaAyhQtgdoEGeoClkGmNpceUJSqnLN34ltvnvWLsvZg63DWDfZZsRvKU1fyeomnM/lVDmfukNf0nl6JGaOehYpojEeGid84jizX0pr4rjgB8wHOKSR2Q8/uMsdwTV1JMcj75WIVUAMqN1Y+i251ZQ0gmf3m8g0RfZW52Ocj2bu3jIK7TtjPoRiU5aQqsBUZR2fdc/q0QN1FxOErIYXfHcTGxPjMzEZqcNhDjuESlsHFvimHhoDMVT9hs6Qz9sp9U5ckqRu7a5v5ZEgD7z3zwBgtkGZyacoYS8kpSgVTYrrOs4ADt1SUxFsOigDTk9hEestqyQFxRmx2hVdGt3p2VCOJO24i9p22mEbwJVyxKG+XzNlnSfpBe2APcxIqbqMfQaj/1bYCtmp6UZUV8FBPQ7vHuP18DsKRqHyaufLJ0JeGfZe3l0sXS3oopfZ24C74aNZorZso6Sf0yk2WbO5rcrjTO5JQYlqDAUM9SbBv8DxwnwQKXvxPkw0sh4M96N0uTzm/8LDU7X/KNUrIHmHfdMfUKhPlPrOMaIxyZKkl/VwOkyBeWTPZPYleu7LSrxOP3Vvswe/OQeYzn1zwx3hlWvBrr5DsGVasgHkeBVjcagSfIW2FGFARYjSDEKozFoi4eG9m5J9168t17hkKkGYz6CWhuGUZ83nUWKVMyAuFr+G5/gmYpWY72cc/0s6pGhRLHNzHCRRFFRUCF0GTWxVCYehp8XPndsggxB50VlEH9zk1M/8QS3DeoJU7KH35egwvUYMJa4WASVx4DnJvjHvLcx3pis4xFyitJESjuEXCwLKtP8H378zA/pt4rhlKTF3dDo4kiQJCTGlfjRqrIJJ9BoB1fhk9MX5ZDnRlWdUU9Whf1CsOONASLu5MEmx3WJWNS/FoQVLiDHmhD3eQ+FzmRo2gvOIpxKrij8yA64yjb91uiJ5vN8iYOg4iT2GFaEV8EE0qxArICHBd0VArrUj+iAJgHgY2xrF3f0IxAkHAEQJTdS5OKygiZrvoCbNhzRj0pKFOrX59KaBRNbSFTkSdoEACOAq6BHqjpImTkHgh9iLE1Bo5nMp4tYo6kTQ1jbcb0ZtvN1YmOUW+fO655mFqax/SjOzHGcZAMd9j+qh+W5/Hj6QeRYyzqGKcxXplyq5McjKWj24JfeZ158NCUx9ZQUR/agxpvFPAYMUf06CzlnPvGhn0V83N4QfUMalnJnAhlS+j8i3xV/0QgvJQIHOwPsOsUi6padSAtkr13WO+G3oG4zV/OJ+X7BGFekkGCeOxzxZLjEnY1RWZAC8sHYOHFu7go4sbWTY7siAgvGno4yUztmzb8gEyL4For/HDbmck/2/ZfA9lfkJddC8cmEs5Hzc3p8ez7beDxm6b7ddpdUAHrNreabeq/X7fqLZpnZntgbHXbmwn1avWTvHSSeAokHWrg9AuoXzoxnLjWF9DVgTJWziuxt5gf7fV2q8azb3dantvt1nd75tmlTUbrW2jvsuMRrOkYiN9P7pxRC/87wYNg5HrddkY9S1kBP+TLK8mWsBoN9r1PaNvmAOzbZq0vdPYZQM2aNf79bbZ2NmjYIRW0xug3Hmz2mhU63vXjd2Dxv5Bc7/W2N1p7uxA1fNEIPCMtnx78LIzihtYQlYnRpEpMwBfSw88jJA8jKTl1Sy/OJq5KbMQyvxlgMDjbbI0dSWWphy6upqdkrnlHJUgvOHEA8XEFa9tGbpG1BcGreLbV5IG7KzPiLAg5fjgMgGXqdD0EsOHBAEiH3vqSZCHQMfeBf9MYmtLgNdZhZyU+y907hz3AWaHfx8lIwAYtDDrwR1KfcgeMQZdw7bE527AxhObYy/jZcFdX1gLxjLuusy0ILQEY6GnQw9v1IgDG1a5UmHfdPH/vJpFFiIX1BInsBTPPW+qTIh4Vg2kLbcY8govARCi4o8vY1tJo3fPFz8eUZGo+rHIe9PTkxgThsBknAS6u4dnrm00WrTVbNfZ3qDfbrS3dxr9emtnZ6/RgsDyQbvZb7EdY0Dr5j7brbP9/b3WtknZXsusm3t0d7+9oaZWycSmz/rcHbGp0wkjf/xX34WERJ8eYeoED+RPKiJa5/Ar6oM1SdhXAMkYDEWFN//yk1COjX7vHDRFaBMZZzm7pyBLTcsYSlgPf0j2Ft9hZRbjp0pbUs5lqaOQqdL3nROdfuS+mid9ikknrqsmtM5KquKTnC1mkTvK2CeqlnQox9QWmgXdPSwCYUWRg+wMXfIftKD6Gh9WnpKrTfFO5TFDUIWI08KSMrI2pB9OsGBkXl2GQ2rcPVDP9Lm5FF9kMzKwHllkXxWNycC1bfchqlgDlHAnA9hL6WCAAZJl2YYiHdbrB/hfWbHw+5WtKHUeH8ucxYXO3QJp65YfpaiTKEP91nniFPVbJ8pRJ6VT1KEShZqjTr5/inqe7epSY64qPrLKdSKNUtv1zKXxI+xVs1jqT5s6XY4ZfE9DqtQZs4bSStxsQa0u55tElUWhf33Os+P5I9crYT9fG/LWhry1IW9tyFsb8v6BhrxveZeHrH21vj/W98f6/ljfH+v7Y31/rB1Ba0fQ2hG0dgStHUFrR9DaEbR2BK0dQWtH0NoRtHYErR1B39MRFJ3/VF13jd7HC8bHwmqWOyS7wKW6dTzq8CRpSGbimjO5cCehjaYYPLAP0ggg7YS3TgS3w/kLiDQOnl14UY/0bde4q6V2SQxhbnpAVpKcX0kP5v9ApGr3Ih5iurcOXC6gUXhWPwwYv5MsSDnBMXOOMA8HSL66K5I09DCkqXMAZzJ1/og/AVHadcgfYmOJbj5vjoJg4h9sbZnsntnABfyaYbuhObCphwY1SdoWGBHAzrDF2c3Wv/gPVdFVFSh6XnzSG5nMpFhfrxQ7EdUU38J87r4xaO/t1Xeq/VZjt9pubTeq+4ztVls7bNfc3t4121hmMZWOkNnVqdf7VUCSWCdFLZYUlQZFWcjOovEmr6J8SbTAHCdpvcTLoFpmM3dWtz4icXS9Pqtan8iptvQa8X/F5aVJKssTz8XFTzaTN+vzmmjKL2QhynPcFPuBTn0uoW/2AHudHUhvR4+rAgb1vClx3FtH6AqgU8WS/8Bitgl6wYgRCXtCephgLcQC4t4zz7NM5t86CRSXoe32o8ay0E1N4KH0YtFRsSiUwIPE3rKTxjPLJSnazslbSWgCbebWmZ9QlKPmEFOiB7NVf3BRsuN5Ewt6NXJGp+AIEprXr9Jyicp8pG7pJN44XVS0UgRe+c3nCJ0oi9Do3fnK0MHMRXO3pVbiFu8SGH2f4egUpmar5wo7A+r+pB79s0snlloIeDx2V1YEmL9gEZaWffKpGVoJYJ+S7Ch3WqsDatmhN9edoVrsDKxOsVuvt6JXgyXYJVhWLVLabi5P0XA3tpwISaj4PBWvU0zC53m7yZfMxA6GvODPmvTgp1ttcSDE+/HT5yWXuk99Vh0bJXx9wNctZ3jtWcNhIVKPbEkC3pScHhda6NMMQrubBdd6gVePzlDG/Tb8auLbyXXtZ4Alktb9Z6LDxuDLafPef9OL802bQh/TexF6E1eHdCsJBugXUCwnvCE5PdbxTJ1BZDZ8muvaBPk0NtRurTz3jUYp5tOJjgCZ9t+fRsEdZam+Z47peufaV7zH32LI3OujFwSOqm1RJ56psWtSu0LknseWR6EfuGNyRh06ZCY5is43ijPi11fXZ2/4pKA1lJLkGgEQmTV09NEO+UO5cG3LmN54GqsUHw9i11n31JgS3haxdP8C4xMnRyOM8h8idwfakAjFd9fIiSWYnIW+IYe5J/dIKp5NjgHLh7YqxObQ4R5H/rnrsUG3sceMZqO112j3W43BdoPt7NLd7ZYx6NeZ0TIHKLBHXeXudjDAeCDdwgvKzls0Ys2pP7m4PDnqXJ8ckyqR/JLOM52ycXYyAX2378LCexgfBJupkmqPXpyA3mEDg5mALLYoQtqisz5h3tjyff3WknOiNCJDjzoB91lzZC1BytJ3iqwckbv8ssH3vTxy8SMzV7Dg1enbUd3ZyiiTU58SAWCzrYWAtRCwFgLWQkCuGjk/K4q5jGFbxh26AJjDvKoX2iV0SX5utd4KabGAbt+IXvMArSyzHItJXgnFpPkMfPmu1pWiBYoW5pS8gTxOaICRp1DTMgfciVrBC9e7pgn6YifR2HKsMfRWL7GW+HQlHkay+4xaiUCuVAJ3RtOkrC/uv+qY785qQrZSgyCwMoYTiHo3UaGG9b2zvnfW98763lkrn2vlc618/jjlc7agIi96Q/FfanxvUQSMcEnyqDFqANsAl5EQFLQzmudZ8A06YSZ3NkkuXuZQcAqu9XUMZkpK8dMVDQkZSemJ9PVKSlaKJS/GA+Sr95YvYmVXJl2Lrt9HPf+8EnYGJl08PL8ki5U+/LAvpn5lkwn9XkXd/rwzWdm4p7Yl489LSG15U690NP8qJIPV8vJLi0M6680Wa9S3B21msMEeNfcN2mrQvdZu06wbre1WKoitqZ8NTg+PnCm1FcovIZZIK9vYnRTtrqO359ed0/OrjcrGybubzhv44+q6c3l91f1wev0Kvj4/jv4+61wfvepenrw8+X2jsnH+9rqb/Obl5Unn+uSye/2qc5762H172cU3bFQ23pxcXck20d9xg5wtjnU4FzrVuGv4pOF8yL7ibaPVP9fK5Vq5XCuXa+VyrVyulcu1cvlTK5fRxv1+elVKnVLDx/IWIZ24aaqD0hjkG/U6JImZrhFGucxdbY21b0p4nOa3GCmjWKbBIExdnkc23B+pj9/6ObshQgT/EdXxopSlKLAumjnf8FzbrppsEoxWpjXxTo+hz++pMk1c34ouibnl1Pjp+RUfUcFbVhCfTaozhyVk1vkTRc+XFtwx8ZU5MAv3OXMkjqzwQ6XleN71j5oF/sXK1ZfiIUP21+oco9jb9zwxyHDuqV3MCbe1vkmRobu8VzMiQvY4//mTW66KeubK1kN2e0YFXMH3Wpe5bAya81Z+e0cPSx19/skXaTA/5tjLjIRyx/7nMlJnX6v2mFmIYk6E/18UO65CeFhWjvwETZKAF7MN+NSh9jSwDI1cqvgLzlwH8LTAzlIkpia7nmWVOEpZI6TKCLJ3/MKVWSg65j11DGaqg/EYT9HGOptzWi58huLqyePkWotAcsV/J1hkV6R+Qxbzpkhf1mcVj+kjZ617O+16XWG1O3pei5olzmP+BHMDHNaInXN39MMgcJ1r9hhcAyqETSP5a05lrWVQxga7ddraoy1q7uzvtBstY9fc3zX3jdZ+e0NiizjTk3GyMHPhqotn5jnU4pGrwGMs6JimJxJDyj2LM3oGVpNTJ/BcMIMs9fAHKxil5zZVYpdjPTyMmMfIHZvy3WpTZxhCGiDoCnPpjKX4mOG6dxaba1rRLnR0dTXfAzgRx5Zv2BSko2PLBzUwgYlafAwFl3kj5qPs2xV2kVaUKxsjy2S4TKWpEDys9PJFPM+ejGjVgUrDlpGyXc9cyTS7VV5bbhLK39T6u0p9ZUZJ/aZMy6K7/Omn6Sc4a3oT+A8hxfXMhIUivpcW2RKyP+3WCIzBkTRH605hjqkJJCJAQHlDpzo35DGAo9jwG0lAVSEQzdxXvMn64fA3NtXY7Ea4KGgv53IXtsXXlJVYRhakck+PRtQZ6uQHRG4gF7DaHcDx4ZA5EazY/PJKngHyJQTqUlsMpLyAR8PAPXXgp6sIgzNlvA8Dd0wDyyAWtgP63YF8ETac32WEGJePwYnjWcZIuwlYQC3bl5g8arALGKKte8ZdGQAS6wtijninopj5Txv4MkunkDf3sTumlobBwb418TcxbjTSA7gV7OQHz0IIO5gcwI6Bv2GKeJ9asCbt3Qr5yUwLH3wif8Js23lXnqGnozOxLiAwOyvvctcUc0ye8A5D8pl3D3A+gDYQeNS4I7yT8ofUZCeP3DFzyQbM0224VxZOFRPtiAcNPeah823eQcIbTy8UwTS1gp41HsPbTi8I5Y0WesW7kHnTC+pRHdzSJRu79/ASGMBXaAnAmXS82KugLnVnqFVRohdFlkmC+FYAoErgOYIPEr5GBW8HS41jBeU3Bt/+8IxgRGV3BOdkpwMPcEaz7zrNZ3SWE7jE4g/OPZFj49J1i8cH6Qo4No3rlp8DMggdg0sHVjDHieYvm3dykc3MN7l4ROd9Dz7E1fmvIfPLHu4Ua83cZoi4kRuAIj1dcF+ScEJCx2SSoISWXYllOHChwo0kY1XSYi0yXrT8pFvO1NtXIPyKERHl29Ic/xHh6C5DW3ck8GsexwGrFOHaycFZPsKYDlJu+oyLL/Z2zoaNiGPDwBc6u70uF6rck4qPoNwD2mDGco/qDOHlnsw6Ass9lxfJ+g3tlzDLiy/6esH/cgueE64l1nSewBV/6gPEf4Htf0KHDFZVb/3Xq5/xhkwxJa0OKmdXs33fy58W4e+y3xIMPmqa5PDkPTRCFSYiEvWZ6YQR7hFGewDwTYkFuljgSImdlPL7ltx/KZ95uafSziaIWjEtWJix5VARLz2mkwlsFQyjRuf4XJRU5Faba9RxXsVc9Ed6o7BR8xVCuz0+8Z5j1+V5c6KYMFlUROi0fLdoPQiz00xd18YgmzhWJz4IiaCc2NCi2EJShOe5qFwTzSb5eabi9d0oh2LtzVp7s9berLU3a+3NWnuz1t6stTdr7c1ae7PW3qy1N2vtzVp7s9berLU3a+3NWnuz1t6stXNj7c1aL/jam7X2Zq29Wf9Ib1ZFOLC0efQLbfDkvkZQC630Aj8k6wnn69er2KpZ4JySl0Ee7itwvR/hDBS2oZVXOftrFwRS69mUsZbKDZrcgnOaj4unXRSb6mhowjLXcCZEedx0aW2YEfG47tIEqYECawPsMayqmaeQapyep8dJTpHVHIoZRjgxlxmWTX3gKebSYwPsolPN+Drpi1WMlhoGFiaG58jDyCWTsG9b/gi8ygWTMctvN7CG5c5H4hDzQtAZUzbmD8f7Rp3saMDRW7P8Z87aSCmK1uxEz05Ws7TLrQ12uU5SXod1rMM61mEd67COdVjHOqxjHdaxDutYh3WswzrWYR3rsI51WMc6rGMd1rEO61iHdazDOtZe/nVYx3rB12Ed67COdVjHOqxjHdbxFwnr8NyHCIp4HVfwj44rWCAoIL2p1kFCs7z6eRLo+uz9o89epVhjPkqMXfmNTDz33jKTpdUyJFn+LJoWiwhKuOVWExYEcs3Adh/y5BT5u25apTzvMWqL1Z547N5iD3nFB3RvXjOvpUOSokVcdku4DqsmK5bOJkFpDx0xz60GXugH1SEN2AOddsXprdrusOpOglQ1opyltt1hl9qamn1XE2ZYgymIrqKIIrHdIYHpl1ZCXojM4rZRK1FATbMQA2r7LAo3iD7rVgaIwqpdmg2RQ5fr2NO44OZiFPKtMpvAb3nzr2dykmLOYXkckwuF3YCPx3Yd6vuuYVEs8ObRwcAyKoSveTCt4JVhMhgDmbh+EEK81SMUt+Ol4Rgvjkf7GK/keoSBHgF3TeCSHlDd03KWqPYttWFfx7yGe58HA9ArxE84uyCgGzhtjiv+8OmA+Yx6WGV1GngMujcCrL1m+a4NBX2hefy3e888z8I6Yna7q3xiQ48fI4/5rn0PX30NKZS9sxyGX5uWB9s4j+/pV+UejDBwLPJduHKRZHPcVOU9ubnBc3nHSLymzIZ0QtuOR5kXA5FpFGNbBczzKNrQottSlOc+2OCMgtp5PMUJrOq95YV+mbmLGs8/c13TfXDA+NSdjITaVsgSs6TmdBSHKnXDyUpekOjmW2VjQC27a9iuCLqas1f1aVhHF3g8j1ToqlM+Z7f6fp5yp0ysSMKoGq5ts3SNq+WEjewbF5I8irvJFUNOHRMmk8XneDl5RLBZ+PA5EkW6ljNwFxiB+vQ8ksnnUis5Hq9XscwqPsnEV4E9hN5cMnu63dhyZM36RmVVy5N+yRLdZowIUadifoFjfU4zru+zzkIGFITgp7lWOin8z1hyHwPWVjC7uhOc9/5JFV6mXVOIYHrr2FO53UsakrVvkdF3s+3JhY93ufU/dzYnXa09h6tOU64LKN3VCIyPuA5TvwXZPFl/vtjck0MJPDuLHMYdUmh/SZN2FtqBNbETpPnEoA7xR+C6gqd9KBEPXdQIBlf5sjh0zzJ7WFOb8GwXZiZGiI8sN75oRWdXu0ytn5iU+XdB9PS3yIjTpbM1+GxfYEXxAzqeZHZ5ZBFcgDpOmPTwziuw0TGrtjdylcv0GShrW32CCSo06V1wwx2hxB9BlK0fjsfUm+JeVPfxgxWM+KZP7UWNctpRHwx9nuEEfC10OJ93IcAHbgfXg48WVI3vh77lQHCfkH5rG8usrbLznnyB/S637nX9gAYhfMo33GXO61owyxOvF1v5WYvSxWhqJ1iN5F3+dWW4rufeAwOYTBZZuOTzy3JcYCJdMNLN4L2OHPeCVKc6ACeIs+xMpHuIPTxPOBf5bCI5loxDBZR5Hj1gmVEIv3wswYOLIsciH5PlBDvtrKTwLWk4iBX+qmTjLMiROfssoCVZAHwxdD0Mm7AcAk+iJdQPeXIPXAOY/VFKii8p2/QtB6LRxckroBQohFWrovHZZBPbnY55sDU8GfkQ4UwOxEXlkDgr+JlPmDlkNfKSv5lcv7niASsG414wEPYgt0DpAicCun1G76mFCtEzson+IDf07SmyTGaSZ2hiZM+eIzX6C1bGiTE+4HgEYPWVvQNjiRrYTCQmWQ7vHyyxaT2h7DyDPbkKQWolbIvYmEBjyE5yw2AOE2OfGndDzw0ds2u4tqvJP1BN9Mqb4gcJPghT3/uX5w2H/X6P8CMSG/AxQwpckhgLY/3JTD7ELvS1dBa2xpDM2/I9xmO7Y9pXY1gGX7MbMK8LqT2lp40/QzAdaPHZicW/apX3WK3m5Ugwas5LJH9mlUTyHnOJFFGGXZF9VWqF6QSOHhGPoG5HvSELuqFnEeqrmSUsYJ5fI9eRGgnxjsCXMoOTThTopHT2hO0O3e5Em1egTvAgtG3MeRFqKDxGBpbNVjLHoyCY+AdbW9CrXzPc8RatTXKPEqTBB26X5iUCJfxy5thyCINHMC8CQgF8rmU4ATVWs0XwJf8jPgP5xYSLS66YcHkT2pbDU9BwDFFoDM8DSm39VYzlENoxk6cYnTog9k7zhuOauuzM7G6XGzOefarcltWR68OIlIG4HqGCeOZVo5CRm8tTHfGRY3dDufs2ZB59avSKsxHOidbhuJjvRB8BnsOlAitY0dmJJzJnmSKptFDioYF0qOPty3UzMEeZ5N6iSORbb+ij8iazIDkfgs3JryrPAyFJhCtoOVD6ZpopYZRfChDRw4A723w39AwmAydmSHoyOCqgw3S8FE6LmAV1dnQr8r2GFk4wOqDLr85S508+Q0zM/2UmAZcSCDkgi+LKM9J3A5A0xAwsw1XyBHUIt45uueKTcnN5qmccZS+9bEwdvFN/QO7zIs0T20TGmTvhuM88OU/ZDRGbXKPRN77T7ng6JzBU1qpCWAikLJWQ6mFqjt9cEMvxJyLpMwUAkCPSxw90i68X1IOTvYPgJOJleiZjkx7cIz1/hHEuM8JkoL1ye4iP4tncPJunmm3PffCZV+WBNaB7z57xI9tiTgBvJof8cXIqH59DpXJcpyuDk7oL6CyO61Tl88R1PDqeRLgMcFFkaFs0yC/0bDlP3WieFqG4aOIWI+7pNoYwm5SCVZTWmDltWPgYGAVt6i9iU+PPZZ0Jc3ajPF1tLWzgX96uv83v3H5y5nM8I7ZNEk2FaARXprB3FVnm5iQvftN0Q4Qyp2yuutWJ7U0leIpq4JKtcUx5dq0aOR2Q0PFZUEEGrQDlQY4+OeqQEXVMG41dymOzr4WCI43ywo0S2q9QjT6lARp4VCpPHD8Ujla1NWjY0jomxSIw5BVZ4WqkQxzL5hRwUcRXxx24aOiDrsQUzLiIGv3WTtvYrjZajUa1vbPDqrSx364O6my/3WL13f39QS5eUkbISATIf14dH1LMliU4UcbuOi9PSnYA3CkmIP884g7sJFZ4MzLrPp9l9alWq4cnL0/PydHJ5fXpi9OjzvUJfnt765ydnh6Pj4+OOu7RsPNwetgZnt78dv228+n8i/H7+0+XX9ruu6B+9cq3G0bj/uzh+N3H17+5n05H98Z5593Jm8N3nYeb65M3Z527l53Gzcnh6Ozo/fuzxxdfOjeHw/P3h53h2fH781HfOnxpjF+EH5v2nx+be48nf3Yu+e/G2dHd+aj/0h73W69D+uHk8cV155r/5p4dn7xvf/zQeOi/vBlefdj+8uZLZ/jioT49+3LyePbl9PH8y832+bFJX3b2pmfXp9Oz68707fVJ8/z6rn7ecL8zbUdHnavT9BwdHr7rHA+HJxcdmOd37tFweHLYObs03l4+DF+/uDaNl1vNl7+d/mK8+Gi9PTw//u3L0aeb30/e3v/+4WO7eXj3av/h0Tq73tvZP3r7C3M6jYftyan3u/uwc3d01vDf+ZNXr+j78esb2w1Ozl4/Tt03Lwadrb3fgsbJby+mbv/tl/CT37x6mL6fvm76V8H9u/Dm3Ynr37z5dHT+8tPJV/fV9nDnz9HZxSN9HO9+euN5/vGn/TE9f/n+q7t78uHNh1fep+3dd1vbZ8G113989+YX9vuXm/Hr/d9ad1e/tMKThzPz6+XOp9ahHd40rHvqTC6MxtF58+X5yHxb3xpdfWx/vHt54oRv/K+vp8dmyzi1Dhtnj+HR4ev2J/r1rdm8t943PhgXLfemZT6+vxi3zz5MBx9PbfPsw2Gj/YKOrozHN6MP5qVztv/x05a1f/rCeDOd/O6Hf+4ef/FeXwQXN0edh5NOh56Pz16+e3j17uPx+8v628PDjycvLrZf//nmhj6cv/jFaHV+9z9en3x4Ndr9s2n8eXa4B/vDPH149/HskHYK23ba2Pb44eRw6+HdCZyZwy+dK9gTry7PDjuDvZOj487LzrtXW53hyeFZp/7y6Orry6vTfuv43cnh0cNNp9M+Pey8OzR+OWS758ejyUl9f7o7enPx6eXlhd0wrn47fGhfntZ/P73f8ez+1fULf/uE9SfXL7+MHrceRuePDyefRof7rz7tNhqNt7Tx0b7ee7w73T/2R4e7e+MvnVdHvx12Xu/ujN3f9oK7l3X61fw4ed3+ZLy+fn94uGvv713eD43dPwfXlrX7gY2vp7tNkx32r5h1EvxO78ftkxf18Ycvr0bvts8fJ86kXj/86mwPG497R9Pr4+lkOA6HDpv88vjyF+vFn+fja9P/c/fD6f711u7d8dnvXw93z7ZeXHw4fHs5vdrfe/v66/mx/3D05sVe//TTx4ebwxP2S//y1Qt37F6Nzv6kR63g3hrvfjjqN3Yc9/ju6vrMHvz2tj1x7n8bTYz35tXwwfDCzvX73ekvH355cz/+s/n2eutlaLVfj74y95o9+I+OOTo+Prm9dZC1nZwf69idzqH7PZzGCBDL/O5CEqTuHeD3sJwh8yaepbMLqTfH1atOc3uHKO11AkbpC+Vk/6Cxf9DeP+h0Do6PD473DhonB0eNg2b9oNmBj83mweGLg872wYu9gxdHB43OwYvdg0b9YP/FwdHuwfbhwc7+QefwoH7QahzsNw72Dg92GgeHbXiocaQJ6svPiZzXSx5yMdpyuqEOrTjj4M31eoY+84U8nDOF5KMbgnMU0Bsg+x4b88x5LlvZ0xq5dqPsQJZ4QSUStSQJyRxMadtEEF7SU4jo5SxkrPVlp3d+253l+yHzuq43nGFrcr0hdaw/RUgfGCHxUXOJ7cf/IqeOUSu7WTi1HtXkNqoHBZR9WAhsTgYWs82lTsrb/6jEVt7854ja1sD1HItWrq7/c0Ud8sKjjmH5hls5+s/NVcnxyOi6eSPmMDD1e0SGwDsgA4WZK+R4OeEmxkBax7WRrKpupSgz0i6eiKHVLOHO/r65v7fTbhrbO22zyfa2t9n+zk5jb3+/v9vcbnI4bxm83mrm0ChNEHmmHMsYxaZ6CHbGuAp+M5GJa1uGXgknvT73cvUIurt8EjqAPC5QNoRPA9R50btfIz0PAPmofcFDJnqkA5ZBsD/j19wfF72zHwbEtHyOTiPxO2qk57j4wh658DjaYpTaWDyhE4+NrXCsWCgHHhP5wuIHMSTcViqlmKKHb50juc5Ao1g18qyVCOqxfGK7IgpZoJyIx6PvV5ZHqqOYh89p9kvHCEJqE9lA8qaLzhE6sAvnXaICkheWY1547uP0hevdXL7ZDD27QsBx+Zz8V0Rik9uN49PLk6Pr241fybfyIddlfFSx0wHNRTJUCEC6lEnlrdQBNOurubl0ZPv3XdDyS8aKfw95EWBlFjFZqiPpYifLyErVJjwedyjvnSzerEwRiNoWMwE+hV1YdIURqN9+5qhKEJ4K9hKMT9UcCDIKx9SpwvyhqQvbERHESix+PiKiyAB9hiKlAhyJ4OWNHHFxOxEdZ/mkxx/R+lwy2T55BYmuMQoPfpNHNp6nmbSMAEUEULQZhBbEQcb2tBRNeSGCQFMyCLDk2k0iZpwKzoOIPB5wxxNOGa9cwynHBf1hIamaczHzmK/M6g9nCPZ0dwmxjZ/EJcz/+eJTYmp4fldhOP86dn9lsfvJi2cF0fkC42xO3wgPzMx1kRx+fFu9+O1UBO5xrciCCIyJx6C1+Ssqq0kl1HL8gFEtXuEsk3qB8BBB5SWIxSdLMa1k/PATxbUs4LmlukWgYTByPfA+I8i5NUSQVWkPEAAcqwqiXdQttXl6zBWGM7CRJJfF9dgMBXlhF1H6LimFP7W8+IjOYLnt86ZXW9IC3jZgnlMVbjnZt9LdynxaGAMfTU3BcTIx3n9AZNB8BSQm6mgFC+2Mzo4FWomAXiqbT2oRs7Ct492HIhDzLGoLrYTzO4yBtfzAAyxSX5/ANu/AujOXLA4SaBafREDqLT9GVJdJn5rkgfV9C5IzAHMSAh6hN8tD1S9C9S2p6CVjGuZJsOSFKSK1TxNNoBnEFdLtMZtDD7mEmSHXw2NtmBsX03i58B4Xma0Sy+CHYG3xyZVhMcdgFXLNjJHj2u5wCnFWJ0rncI1ZQRjlIi0wP+3s/BzL4EUVTi6lzBfPiGyFG/aY3bsTnwSM5oVrF5PYtQRK84yDBc0SJG/KXT2DzXdCP4CFgAuLkdOLDaXmXT2PPACS6gogqeIT8WB5bGDZkNARA07FARMpTCpjxIw7EGa4CEhl+RppLRvTgJeO8aljBdafUMdBgbHqs4Hr8dsNruNgxMZox59wMxi5ltyAJzUR07MGQWzO5y+AbayQGuW/i1MBdEkRfEa8vjPdTE5VDcfn1yYUSqz98e/P0Ol/bzcarfrebnufVQfGoF9ts75R7de3G9UBqzeb/Z1Wc6fdvt349jwdhf49mJ/jV00GW4SHCFoTv2qZqNTPkgcjwDl5fCbUwr9PL+7bsnYKGC6VupMJA1/x9NZZm7aaxk51Z9Dfq7b3tveq+839ner+3mC7sdNqsD22k5iwkg/8uEmF8j+zYlGXn1TyAewYaM/BWkPRLxVuk1H1iBgQDt1kLgGhopJ4r4hbT71+s8xkP8dXhIFbldQK4lB+XIo4j0V9cko9xu+20OEZn1pk1Lk31/fZK11lr3StSRcGVCIeihp34aRrTXQyeDzSxm6zttOutXZqzUKI29XPFVgRqeXlWC4zCpncc2LDUcNzfZ+MI5QT4UMhm7zBc0zvieLssBiBb90zexodCZlCQs4h9pl3C68QDh6eC62mELkPDm51n2yajLM6/p5sEhE26k9dazLj/uXvVSx20RfRK8DtAj3leVYmngUi3BxL3SiNdK30XVG2lLp0OfaO7Ma93xGZHPMotKcX9zsiT6TvueFwFMjkQPEi4rtKYpHkF898/qQs0QXLbeOPalbbIcoJH93QI28fHP7E5uHHt/DHc/FWj4r9R7kA4AfUMalnqh7LmMjixe7X9wa7zVajara396rt/W2jur/HBtXGfn2n3jb2GdtraVS3FaWO5SySAMv0Ipy/7n17Nnvhmy1/DdULQa5lOPEDj9Exka8snq1mDf+XxztcryC5kRJMBhAeLREeK3PIsnSQYy4mYPbPdgsumxDTPuCuVe8KTd7Ndn27lZMT54YB6wYj3LfdiWfdgw/FYQEgAZcxhWIIiiOgCnB/S4oJwJ7CKHmnRHQKsE8+D2pBd8W9w8D1Dl8smgIhuiiYaofIXUbuLQ/doIKc2Csez/SNz+sSoc823d4yYerdsRXkgJcrTtPGbpvt12l1QAes2t5pt6r9ft+otmmdme2BsddubJdic5N5QpbnubY1B2tnJQdrZ9mDVa83Do4P9w4O1mdrfbb+emfLHXVlGcISXrA8k7/W83T89lVc4tCKykTGk10uymRlTovEXIiVXAjYaNKNno4XqRu4d6wAczx3ZsTzPi+sEKXigVsE/vxRU5TjRzXd4Ak3zPXff8PkzCsz/KpIuyw5W1Hs1hhYqWBc5OT4/ArBSJIlUVcevcXGk2C6dqAv6EBPztUKPOLlnbHStWIV1+2duxRDEVkaSPnSLmMFyV5ks4NPR3ZYbo+vUAkse7HmId0vOW7e3U88as699Xh4IgGAB5pG1oyI5fuFjD4vfMkdLRK2pIo94O12F4lrSdyFYN2bcG1/7uvhvp3uZ2exfnaUfmallwKx4l0VnEY+DavLOcVkoCjYNO0aHAAkLE9HiNrxUlwY8ybKrHDx24xKLgKMMtxwGLcNmSX0jvlgozaYCU5Orm+ggRNbPPNJD6bMDG3WS9eCFFEAPOCHmC7jxZsBswstm6+ury/AJCmlfhksXiNXLMBzFOPp9EzH7yFnLYHZIMdTPC+Z0VMxKF6zBMF1x5YTBkBRpE+BA9IzY2USIagh7DJQFqQXy1noIAfNJ7T1ONQxKEpd8Wdu51XPnvANlne1+kkrNB+P5RPxYCnG9lQBTSJ5bWmY5hSPH7kPHF9cNonDX8X4xZu5OzYAJzfuQUgyIOjB5QlVKOgNXEhjIJcvjkir1drHZ0QYAKHk5voI/M+gR/MneW1isM+zSeAj2gdQLxrxvAfDde6ZF+CuG0uTMLCKe2qDW+jm+uiXev2gXieCEA4nBc5cPx6VAJKmELJl2XBffaqRk/hsR6kW1tAB1zLPWCDYAZTh4sPnU0GGtttHT7VI6o9sHCReJXyylrLGNNrVeqNab1zXtzFTr/6pbGXKwvimeGs8gRLOHgPmmMysImIcr48tigLn3KFCWeQoeYkoRihE/gDSasys0A84dcMYpdLyuW9PbA5phudBANhn7H4UvvpILwUNRYnjQFkycAkSTeRIRC9YTBYudsspJEwk3iQQuxIUYu8a4tgjhQxDiHKBfiZxKMcYMCMynQLLn4KLgneE6Y29Gocd+qUHmEToEF5xmSk+NzD2aELcgbKCPtnEo/ML0FGLqXjOgzuwvKYVQAQXTOSLzESuKDbyZ4Kd+xvBzD3RUL4HBtpfDPMsVf5r5rkUTklZoRDRRh3UtpBxQODZT6tp8UCwGYBuE88NXMO1ga/YUL0bFcyoHiHIJPPWN6yRIzCkw3mWXn1KeDoFFw6KAJPmpDTkYWHSmw+YsyBdOT5WK1SLFKouIrihk0C1ZQGf5UPiVZ8x5/WUE99A2Vd+yFuTSZnifC9OL67mAHgLdOXuTwAO0mDEsCawmf0QQ0dh6SA+XZx6kVAFNw6XzfDNjXa92vzZcNLEv1VZOZWvbNWwzBLhOUPmSoNB8S4bMnfo0cnIMmLrqSz4c3R6fIkhK7NXxMAhFb3IQDA90TMfCzm90BRFhsyx0Am8Wf3xRqW6/KZYIuaJKYi71U1FTDCaKwCEvTsbP9eIFoYHivAMcHxXggD+YqbJbhHmkK7cCTOcuVJVX2BkGX+btI+oo1WpqSQ2Xo5htmBjV4GQKoQcr74g9D/Ljr4sMl8R95mr6HjJTWC7w2EalrV42T1mUiPoTiwNDK/OH8/bQ/k0XwAkyHBXFG1UNGE8mGqxXSCNbF6cnvL4UD8yL3DpmZxeVBTlRfx9elyRUgP8eXP5pkI8qIPmMY/LFNiMDpkT6PFaFvA4RMEg/WkXFNFSqaehg2gyXf6567FBl+3tMNbfa/d32X6zabS2jUG/Xm816E6rvj/Y7ed67WYt7Ppgf58M05kH7AkOcZkK1lxbVGW95KKXLSus2bP17W1KB639xl5/0Nwf7DWM+r7Z2m/TvZ12Y6/JcMgpP2PRuFSleL1TF3XlZkRTaR6mw8W3NT69KMBFEjeIw02AkczrLphmn3z+2wrvx4hQrj6sd+JyO/GnZErfB4fweyBwrG7bC+ZQoLeK8PwIF2AWnJcMOoSYQwg5hIjDVMBhCTivIXMAtIEh0EJV2Mlmn8p7alsmoNFPmGe5ZtekU90lybjDKZFMLx8l/FEwd8PTZNODRKMD0qg26pX97Tr/dov871adTBn1/OfJ0NhGZa+5LR7djlr8+9+nY3BfUCf4978PUjgPaNLypV/XDGXaY4I+nuoFmV/kSC0E12eGOwZnyXgc8g7oAPI0ZXtSjX2xWyhrI3oEiMW9LZPF38SxEOg3cADeRyXAtgbMmBozXbV7zR2tAUe/0JAbXfUZ1A10vQLBRnhUMJWaN0fsMEeq1xqPxArcJywyx4IPxBminwFo4Cbb/HcvYbB9QlPX7LLYMexdVBM7Kr+4fEHsOO+xmOloUATjR5dEE5xF2SxwgKekbYGJLAIHSKWacopmZEw2W6xR3x60mcEGe9TcN2irQfdau02zbrS2W2nuPSfFs4yXM/LMI0+w9FP/nZLM5eBqUGxy4tdAwomTyweWQx2D/aD88WxF3tIVZ+Oa3RbMEHTyg0rOxhWACu4ZHgUlHUOP0/mrEulLEc3slxDSqOFms4yDCINIFnHk36sPRUFiDrk+utjcqz+vkQ/gaQEvjMkMbypAL5xK1Jt43Mcnr6QHTnbRbree44m5OeYfgKZmjZhTh451REWeM5MFMVXiJZw66C7zMurwWI5amlYRTg453iTb2ZUGkUmXiotTpabiyi/EQL53hSZdKpgabJdkXVLyNblXQY1WPb0oAgSIYawxgRo0PAhXjHzMmGYvH8Ou4t9Cx0zjspbIPaub/b2DvW3aOqjXMUirXj/Yo012UG/t1g92W63208UgFOY6zFYUcjPMkm6d2JnjwSfw4ZSYF5ySgy1kXzOTqyQlOYqamsBRSCzix0CQKsToAYyltJhHjilUZJRIZynwi2ioGIQGgp0m4I/niN0iWpNyDGMsXCT79vkFjI8FGA/LBgM4r6jSCHDQefNqlnWpKPvgKQ91yfWAPeNzvwjsFwPCZLnaIBIXZxVhz00pRDcmbsz7Hb41yRtrbAX8CyycOqaPEDMLdGw16jxiEx/L/NrcToYzNvabtXqtWWtstZplwxhnBpivOGkLR/KTZm0VzcequZTqTvf459R2aMfbMLXs7WJ+ltoGy3OzePglz0+ae8W+/Oj2SqNGENezhnBpslnsycJtA5HJyPHwfCy8s5bnW8reeErOpeZqrPxIvt/5WY/kkomU9zuzUynVVqs73jup473zYwQRdQIWE0WUKJl/jjCi7IgnPNR6aUELMFgobfwAIP5VoYBzkEWIT4Zg0AX64s9pndcL2xxgXquWMwk1Id8d0xQlGkTiS6pEw4zF+VtPHMK5A11Ronc3fnztni3vnu1CwNXsCcvJSoAMMm6lCNyA2qLGgh+bOiOoW8xt8Rn1jBGZUI+OWZDMZskWHGkgdtxQF8gpE9dkwgYvLm8FI8uBv1G4M6OLRlA1+2XM6854YZytIIcKbg98fckXNQFvFWcrr1pLnJaXmNMY5g4G6oYBGsrmm9JmvR6/fiI3b0GWBichHjU+UzyR9brwQC8YMcXZ2Qqc2MgjStRT0IiRa26xsgA4WIWVLWeJeNToUM0bjYTPJW8ksAfzbMdI9lLuWVHX44DXFuHP49b/S4lFK6hPtLDwy0/6kmVVlqrGxwfww8riSI2izL7GpOSuUkZt3g2erMP2vfZpBiDU7y603YowqrXvSQGRzv+6gv4QmGPU9cM+h9Nf4AXxs5DgZfhdBWNpzq5UhCYsf6JAnczbVfTsUmyhxbNjFlKIo0weZfoLhCSBXZvyhCk2zwgHFoGFo4AHk+i3ZqLKTlRndIYZNIG5u5LyrqkJ6HJU3oJ54A1+kmlormgaxvSxGwT2IjITfazCk8vdLqLq11J2wXYCk++HXTVyQrTBGZ5r+wR2EncJc1mZXF+/8bGgh0EnE50hjFcEAcAXYaGQIU89sXBdnxl+L8rqJm8BlxICamSDHoeOwjo4CAXjg9E9cEnPckbMs4LeohEVUQeyVHQedTXSA2gezzJZTykrrWBM99S2AhHC7BGb0Xum6Lo4XSWh5+UblTgEQe9GRf1Rvi0PFVxSlh3/G0F/VQCUGLCKMNuZJa5A6I3PoGqtXyOXQkrnUDA9mNwe1mGMJklA+vSZhBnNNI2mHuGH5IQVB4a2dup1PPAcxQc+qqg+O/WSsZGKgMQ3RjSxM5BUsPXqMKbEeavqV6cj04HYPbNLroyM4PAY1pDwE+19QEiPtqLHDNcTO9J0ETuKPRpMYkLwdHhyHto2GTPqgI8LiKiRE2qMsN/oiANKvpjBCpF7oAIrK7FR4MByhN4k+mN8xkuhOqxiA6xu9RRtfRFTf2SVRPNaIoU/R72dnbKM5ixZJyqftXSgeha54mW1znlZrfKho+LWKyZErnAJYnjhobe88JDkSXOSo4lhzdTjmk1KP1OIa04yZuStQxtNYCNWqFA+AoHFhL6gBuu77t2c5G0XkxfFac+eqaj+Vs7hwNftlJ8NHtEYufAK371QKS0kaDdL0LlCRLmyXou93hVZEFjANTd2NIkzKUskI5y6z7xnvsxS9tGoLvI8qIOAmzHe5pNkMKgj0OcpaGvG8OxrXi/9sQBLXnmhzNgWzyTyvamP+MBTvTW7mJaxPyNTKZpvFydYBmGrI9dtDW1yN9e1u6GnEadj/Pybyzccjsm0PAyrhWXm6TMQW66MvEZOES6fBZUMUVAV2vEJFZhAYIAvR+cS3uSycd9/j5rt63rt63rt6un+Z9Vr15yj2WckN5JkzAIKLUSVyr5MVQQILIzDSS4VBbYIawqTKzA95MqaDKZJlEklveSh0pgF9IRPqAG3fhm/EVYxXcTIEz36V/P9VNsrMPMuY17bRZemHS4CQYCPfZczUtkQN/28c+TlR/rGwNAaEYJxaFmOluwKYFCO4EzeuA/M4xo85EwJp+/IGoKAFfdaI52AMNDm40uBINZ7JcbZE3oJ3APYOwhF1Dc4d4pfr9oMLgE5B2SYP97KnxlHfIOa7p83AZ/uYGvLBLsGHC+/ZkQZkTXDHW/ZjHqAGV+d0GDkb/nMCD1W5fnjLKiKHJ4tTDlB+NeqzJ/dQoKq7qCqvHHrXzwXuRoPvQrxEbF881xJWFbguCFVN8riK5e1unoBSqZIVaMUqVJCNG8dJVgpxn0LkhmpTfpTMBC5A4llnE2NWoHysAoylsCFfbpwyQwQSSE8JDblCu9m6IeYphWnAc+oDBk3zKflcVqVynNVTZT98RL3klfHneVodtp1xmRAsGHRNEbTotjT5Vc5pvNl7q2d/5+9d2FuI0fyB78KjrMRkrwkxYcoS/7fXKxatru144fOkqdnxuqgQBZIVqtYxSkUJbHn/N0vMhNAoV5kFUmp3W3GxvZYLLyRSCTy8UtyxdmC9ffZHBCSym61oLgGBQrJAsJrEF2tpr8/8uZuvlqzP8UBVWFslY2ecsune2ZvfWGK3O/6RBsQ0EIHugyJ/h5H+Vl2csOloce/C3OdglcEKVKmfDZT3oDxJVwFmyz3Gic3mbWbmSncNPRH/EDuiLgJX+uAGvFxVHv1ZR0ctUwnGzeiJ/y1aAvmA88d9u9EDgaIHafyA5fi+Kgh/GEA6Rx+uvzbG0Z12Z1YkMJV+IgZINnV1U9MKvgNLxhjfhzB4I0ilz5ShlY6cF8cWqG4+t8N7dRxOJeiMeRSyEMpJ/D/DdcfhVxG4XwIGOUAyyikPPwLidYNKDEMplN42ig0yBVuNbOFd3zRjt69fBz97/ztP//+2z+8zz+fzP/xD2/2KMY//eOH3348/+Fv/Ort2V/LGy2q5VTQidlK5VN4zrwJJblnTsp0AyUCjLoBRZcnbGm1mu1O96j3r7x7NncYu8CUbQSmVL4749pPgchsYZ7JrUAw59AJGeB3lPLHppSsY2UffC+fjGi6O6L54xONDpd5GhI52pHIH59EYqv7U5FJb0cmf3wyiWOLnopMjndk8scnEzT8PRmJvNyRyB+fRPhshogMT0cmJzsy+eOTifIwdp+QTk53dPLHp5O0sv2piKXd2lHLcwHBLAUN0QgmOs2uQuYD50wRgsv7mjAwiU7zoGD4k4DBJLotBoTZEAUmZ0X/8Egwf0JUsZ0L5TO4UGZcfbdzY+y43nfJ9Qo8cuEhvBL53+RTt7ApoSIYltXv4FS7IFBJiDXS0ddoQcVXFBpLEcse0kXAOeCRC/PSeW4kxgPFKSbIz1LqJBNoEA2ndr50pkKSZOwqTBEm0NVwIoZ3GdlhGjiA/0CR8cq597PEbw0TR2zcjKldY4qNFJi/ToeBI1vtXModpz8R3MlNDw5wh8O5jIIpU2UQj1iBhMZovhLs/A0cGWJZSBo31UE3TF1IkgF7ymfYEtw66IyqitLkmuwn+0825XH+8Nv/+Y/eE8y38fWW3fOQEpViClHwJFa9cAzpikQ4Czw8epycuIUzVit7+z//859bDLqTQw57wzw3EiH3oJ/bJjuzoZc7LT1Mo+6VbJ87Dvtv2HT238wRECZyAFZ5vUh4CMFbeqEiua1FwYlZgeCd3rFyzwUaEVZpWtpU8SP2tx+IyHH2SN5wAm7BmeJWuY9jKm9CWqCoIEFYDji+XCQHczL/U3u/aHwQj1GDtgO4+igIavXagGPi9H80zpE41PcGObt8qclgKohsCGYS2D13HJccfC8T9GcEjqQvQHy/aMkk1ydpC77GuBD94cT1nP5gMeN50v4VLZqKzHx/dcmwfCjwxFEtm/FQOBTHawBKK5QLiZH7uAMTVzbTrIoSV0FssucptgTcHGMMtpKnas0Fgkb6Uk6KGLDN9eK79QyqobcPUV4upXpHCTq9NX3d6lo5BJqeZ1ouQD+evvLjyQ5a5SWDkamyLOvzU7zKuU7v66zrwJVBnwMyAEYrAd5LdrBxgPIgDB4gKbIrgZnBUR6ICb93g3BtHkBN5QVuZRd1luOUFA8OvlvjuRjpPkIxDSKBsmhdBdsOuQ9MDKuoEThMxWvF4QpU0cxaw+0GQ+5B5MJsEPDQwZ6iRGY+PoBItTo2D7cw5aYxyNFNdqZS4eBSYajivQjRG+2vf2U3tfvOTW2575c1JctxUgdpWPgw9UTRArdKZ5iHIEWLhxRnMR6YU2PGpQLugQnoxD4E95KcSfumdptL0rnjyIsvyR+GEzz4XsCdpxhFHrR6/ijuxAJpgM3hTbH1gag5LiN6XcYifERCX0r6DNJpmaqSDeaRPhGS3wuV1qyQrK21fwLSjol4Y7IuT9Wz0PU3pejVTLpec+alhzSfPRF9a6JdRlZJwk5y1XyiSNX4neiigBKAX+W8XeP5YoGKlwfVyVwaqesBhP8gvmNIPVa8jIqzftPnSh+WpQsKZawFVblu6+xSVbYyKfzOxEEHbdlkqESZU2AO7Td2AFRXS20IkBxHD0khGWTlPS0lAljK3HNIq5E37jjX5H3bGjL+cd8pGufDNDfbbCLZJ49EOOXhHbt4zfY/f754jZG8pF5RIpo5bnoCytlfXY4KSqCuNkdabYYCAoyRPv3cpvLmalzGQXWb2LOjl73uUc8ZNnqd09PG0eBYNE5Gx7zRdbriaHgiTkdtnkqOeozgZvrP9jaFfYSpzVfjWWI06VpiWJk48TrQ/dSlmPEgZPAGinObZtK0r/siwJ5z3wPLH13rwA6pR/P2cYciHo4FQAG5y6n586cLGAedPo35BBwlFAQPlI8YGVNc6JbJ0mMNZ00ow5h4+oWx4OpVSwroFBXlkoPjywQ1KErIksBT5HrKzi4UXOYxyTePMw/0fg8TC1kOq0hbhU9wJTnnR2XDcAFA7DFi++5IXwsHhctSR8VEnTKuJ46NRrZZdWxyrhDE7lUwd3htMcRZgNzIoSvvco7YttYX1VN9UkehSr2MgsuorGwFl3BDpdbakxr8AgVkoxIrUnV9w/ot1MX31S21jDvrqDVS3i/VvoBeK0s9lVWxy5muM4+RvjLbGZ8ORI7VYx+FQk58gbsJ/ww8J87ITTYGIE0feJzn/gb2BlssMaAjS0m922oVATkqmJBC/qXHacGJrMWK1r2nSYNfbBH5JKbBvTDWEHx5ZOwhA4Xo+HuZD7ZnFMi4BZTB4otxVWv/aHz0HG0+AIMBrV/jPcL6bkN9DxE9gGTl3efuV0a2MmXxgRnMI4GChiuMZSpS0oAuadb/s49p7XHx9tRXjChSULv9OER1D2S0RBlC0wEgkj1LTANYX939WEQ0IMdAdyuc+KEXSCFVKmjgwZQtU/Hee+65Cu+Z4/7uydS+6oHsFd14ZgVvM+y4rAA4u7cDWbYRp6XHZOA7+/dH6HgAeR+evq9jcmlYhyYFZgteRoyAdqmxoy8xXl8nW6e6cIb/GczxEhVasnONpRs3zjrKbyg9Me06WQ9HrgdCM6JCAya4wnA36FSkKqHeMHb457NPl5SSMYdGqNzG1FEyJW4U4MsGeqaOy2W8zU93qxI3jLjnQT6G5cPQpVaMJxYEdaoLLA+AgbR+bK/VxP/bK7nopSbYLZ7gCuhfTOSJCTyrLi5mJX39w8nSpKTrHJJREApfusP+KtuSfjJyMhkp9chP19eX+sZlD67nAfg9ghSCh0cUhOh9o7cJXw3I2tch31WPLqnQ2egxO1tYQyj5aF1zDd2xH4SiPwRpQPt6A8w9zjNH4YTFY9hpVRDcIs4/nL1/wwgthTDnDIy9UtwEo5EFUxc7lpOyRuMR8DE0gNleE21mKgir/aLXKUrQy6+np36cuj6h4fWVlg9uCymGfbx0i6TvHFg2hcv/+sPV1ZtzFtdm+zDdM5C7NPs+YF8uPly9Of/86c0vK17u69lC1lyJmR1NUHQULi5xf1UaBJKfDL3Rs53eG3IhIzHVL3mcnKIUFG0tcpnjOMHbKe8q/LapZ9ZXvD8I+yMhnCUevTIPkjtvOU2LDFo0i2q0/MnvUmlD0iucf89/KwvnHZmEKzmPW/DVA9aFPFfJTUpkBqc7D1MoJZIumasc5gZeeWW8UXIeSN5RP865soYYVOzDaIQgnTBcjXiFZNDE/yuQC3TusvweOS6E9hu1xILr88vDz68vTWYRewxLoDjXvcQqQ/XzJBg7sdeZxxcamDiJ3a+EAH1D0aXnrFRJbV1HvkqKKIC93xDvP5e9PJnqPRfyn5wE3d+SSRZAM+s/GeS/IXIA6ydaI/D/QEH/x8j/sWfic+D/r3NC9EHsTwK59EDDd7w+gaTjxEDaJc8wTUvtUMo2kHMK8thgnuGU/gUIXpvB9+auh8JCLFoOjqw/CHHQwQhvU2tlYCUUN3iqFcnoJqoz/zxmX1ELF1fsNPH/tqV8m/EF2NzB13IZw3797pKposbVcoWKcvvsNWcQqXiB59Qz/3vOQ0gi4y+1BxunWnJn12b2uLI2wmx7MQGfv0/x5Uv1CubKhArITSX3nUHwuOwMGBeKR4B3mzkjcFkIhvTfKf3PI7jDRPBlNovov/DToyfpv1P6H/jtNwSwDMklvQQPXnPHtFE4J0oC9yXeq8AYkMttTyFH0c380Q3y6PMR3os+4Mv3wTkbmyo1KEhz6TsqSyqYqX0nM5DYAYwU4xihRJoheBYY+/v360GQb4lYxnrAKzIIH8CLDiZGS65dfFQLeGuqyDl0n5NaC6ZCrITD9sDfte86e0BBrj+bR032IUDxSxkt9hImnD2EtDTV02aUPFMLKQO+JWtIRWWzNiXHvlRGcZlYapOIEnBWmeOORob49z58fPPp08dPaHiK1Z66AuZ/USFUSttC2jnKSkli0d4Zma3Ozs7O9ow0lCfeKQbuBz5ycIKJdXxZ6AJHNLB8ORJTRS9pkxHZYk/FFPikIvhyGix2xwlQOVxkYiTLIpSKcw7gwxVVOUzJbQn1T5OdK29xEeWfn+LDY9sgn/HQrJ9PYr29kiJaZsCfeXwomHh0ydtXm/Lhjksb8s3FHK9pJtDxYgQPL7LKO4GQyiLvSlDFRWjLdxzQN+xiGr+JmMZ/ND5LETYuDF74lxrc2n/9n/9oPGzag287anHuoxFbOAh+uzRuTF8udLwhtbeMQsGnzILNhd11fWIDoA3z2dXVO5WILhgO5+EWfUpK3qG8IPeO/WZWXc1ECEumBQqYo16exCSlECqvmeawqgGwsuNccRJoWsQrttc5XqHewJR+VhY58LRT90NNuTZqBIT8y3Gt+6hCpbJpjwhzbiXqQrwrVQHLqOKzpWPDTIPr9WFVflKYkg45nIHs0p8FEoDp12ox0QD62BlNSMW2dE1UH83c2L2wajtxZbD0kyvKGu3omhvBuSg0mDhHU9XUKSZNwmaoMF3KC2HnmKuM0mUqqxyRJlvAuscIG5p7ImF4WQOuMkbpAAEMVKrKz7gq/I2uCs1MeEicsnozuio0g1ku+8oxeZ3Gkg3AJU9GxzXa0jWfCeHHij2q2IGuCYFBlB2wH2dhrdhWqoGCXDAWddet8Cp1ccSLHjOUAhghpYIspV4ScdhEVnO5vWTe+e1vkGivbnQM/SJByX5bKzkHtWF3ll+U8sLQAcjgboiaiaKk7ErMQZnOyDdFcs0TZQK0uUuxaKhLkXUXUvrySJu+dPbKjVwgCohjtEpnCOeVXnD33JMpFzWX3t33MCD2NnQdvpB1Ew7ng+gk4zygqPlpQRqURucIkqEwEx1plKPo/BkJp57oxBFqSYRj9dRMRQGQnjLKCQIgiqgrzSe+ZTm4D1gASQA/BMmrOZv7VkP46HMx8XqubjSWrVsnMLF251W3VW93X3VbjfbLV61WkeV51REov+7vA7/auu8PQUuNT3HraX1MXcqZ50byoLnm1qjB/JG3RvIl9odqW3PFo3n4TIfC9PWHXvv51o7F1bzisViX5FVHf+RljyZ5YBNrLfv1ZB7K51l409Ufeundqej/FuQZ1jMbAMVMLIV2bo5j1Tn7QiqxuPAQ4jVBYKW02pCyTvjNB/fOnQnH5c0gHB/CX4fvXBn1g1E/+q0PxpcBl6Jvhib/Ap9Rp6qSFTt1Ew/CvQcAxZtLJcloPEkcBHks8CgekhprartdGe+4bti0GE8HYAzDqQu4gsaGqrznYqfJJjsPvMCqpXYtptpMlVgTrgQoNG0xnf9i+X6fTUXoDvnhB/HA/hmEd0UbPS+zxeXO2Fw81xFTPf2RT9jDsrdPtYX/WTj+cy193Ncfd/E3eFWVVQTbiqAVoHDPoMhNpiCtqi+LK6NZUDj99dWIvWdKIVywK5YurFJmUHzdpnOD/s7ZQOFwe8IkCFhNabuUADZk+2bZMTdG6U7t3i4x5hPvn51bbuubt0tQ+bSbZ2d82/rm7VJHPu3m6TxsW9+4XTLHp924bDqjrW/hLtHi025hbE/e/t7tMiA+8fHjQ7AgPsHW9cFBCxMy99MueLuNLLGRv/+DfmvuU5s5BaHv1bqIQVRvM3eg2Fe0ug/JYiZoAs+hjtjCGVaZsJI0//nTu8YodIXvgAN6Evv28uwcfRAIRm2p9mzGh+ACF8yKEOdWO/RkhnZJOvkEtGrEx3p05idQuKgzYxSPeaN9Rs3KfKDRNlYf94GI+Bp0g9XAj9NTuVKq6iOw3lY9KbtrMwPX2dStr1cr1NnNBwS4sVxbDh4pEDuMfsdXGqMDiQs8otx7IVUECEUlNGNL0TwKIDwPbokFGwsfFAVClsZpDDy365/+dvdb77mJlCZJqqPilTEFNToFJ/uVje3hahwuAFEbem4SMHLppJtYqRmH8egRqmj1lSuSP72Ym+bgJZrQP2DcDSiaQttqHzVa7Uarfd3qveqA0aPZ7nSPev8qWMvIk0sSpOU4pLk+xLJETPjDcDEDzoXu7sq5brvOb6X7qhZv/UR+ZZZT5xIEdDcU5H7IxCPEteK1hdZQNM0qNBqNtBBjqybPKpEBxcRI7ruR+5uQVouSDQQApCGMmAqqnDbZdZzeLbZAgVel0InoNCJ4bImyhmlyyKlDQ1YwhcK19NCArbupoZbnoWugw25qzRf8cMbDyOXeIcTYvrip4bQSVQCYAnr9r1a72+qc9tqNo9PRaePo5fC0wY9arUarc/pSHLcGx7zdSiDYb4YaUdbopSWxJZkPgRs00E3QDimBinX2wz8/Ni7/dsH2CWT0AGJoFJNuTLnPx6tsgOa1QIUtV0tqsVbPFPllfQZF8uNSOscklVBw+biv3ny6OHtnDdf88PkT/Pf1x/dnFx9q9dqb92cX8MPFZa1eOz+7fvPjx0//rNVr7z6en11ffIQir9/8/eL8Ta1eOzv78fPF66JY0jyJ3ucz8KMASXiWBwlyriNf0cDsSC3JxRUpxYvS1S4DLzAM3PUjBERMASOlQnOs3Nd6FUVUQIS5QDafffffc2Gwa3TKIVtKXn10wU1lxocFV93h8empc3pyfNQZ9o6PnI446fXE6fFx++T0dPCy0+scJoTsNakO8zNkjxiF+BLR2QeLMOkZ5JhYPr9R++WROG3xxoiPROPo+KjbGAwGw8YRbwnnaDQ8OWr3smkeKgw676gkhq3YKD4qvqVxd/MEECt2zen2eseng6P2UBw57REfjsTxSbfXa416R62T4/LvKRVms71VKk7q8fSr1lsxD3AjYL/r5lJSzeWx9ODVX+IFcPLjm5OXnfanN2/L7/bqfDYwAv2ij9MS6xfyvrlJD3KB5eLkx8/5KMkGuRRMjjNVlCILICmL7gxCx+eeqKM7kJ+bmictu2YnuMZsAl80dIhD4Pf5zG0YXTekuKTN2oqeNNXVWkrSJW0Uakh/fgLFaFXN1uplbgACtArjLLvcMU4XpNkEwMuXrVbX9F17Vfuggeo1jtvnTxe1r7+kcxVtY9/iwfyyfoPF6ma1/HAIMghkT7r7CgpX9Y9/Vdp/M6mVhEAGi7zJV1nOvCOc03MMkFJ4abn5abMs98NOV7RbvdGRGIrRCXdOh7zb5ifdlx2nNez2uqlrqlNwTxTRwxKc/nSKWcdetvg+mLo+hNTUXrUhUzyig80hLwh1pITmDA6DOT4530gIWX1I0XpMa5tqI6MWx9HHvf6SVaPMUZC/oMlnMPpiuvK5t4jcoWzwmfv0rDzR2/rcvLAZwws2PN5PyNtzzvaqPfjG+XypTa3I6lfv8HNy++dm9sUEUczv/wCHssb9xccRkmRaME3O5mu9sIRmib/8cU/4gPvOg+tEORnufwgFvwOtC75gggjiGeB4mipal4qq2GCkEjCtVKNzL0fXA7pi7MN6NRF2EsInUuoh1R9FA4VJ+6ilhBpyCIDO7yPdOtqaHgSmhkA03H3US2OfB5DNKkYnK+iMEvEWqFHPYjQrVCsGI0DROrRQtMBoENK78U4sWChUllBpQEahkk73SwOj9Hz41NSxFlE8N9dPrNwKTKgh0Gyn+/Ko067Xxu6o9gqMLp2jTr02iaYe/tnunLbqtV/5Pae54Y+do1699utMjGuvXp4cdV6efMXVAPihHHTFyguBaQKjh6DhuGM3YqphwiZaNvs03SBqHjcNrFiNsx9hMY46Ryfdeu3Hi9qr0xPIpVqvfb6ilTjqHXW7MFMpc6j4jA3g0DB9ahIjiQ2dZUxNymxUjoqX9WDR6tzfsN28ZtVigONhFAwDL4cFqmXRq2Ini6OkXoC4peuvXpzrd1f37VUTMJ3Yc7h+d8Xu281W/vJgu82NWm4vazlHmVq+5c6ylrubtNzNb9nPjSMt0ewyQpn76zHnkSCs8pg5p4Fv6eewqONlV19/sOgPAy/YXYHrXYHf0qbCPm4/uuqZRdOKjUCQ9VD4Gi7sOSVRQHNXcNYVB4314p3apkzrcDkZBDzMI0g6wyhAgK8KQdPCAq4+tHGFNaZrVQbvRxzGOs1Qxa8Y7B+hEuu1ni2LF3P5snx/50PTw+50JLnFKkkNlsCsHjPtEKb2AKTxhonyAn8fgFKVzHOnrkrl+gbhekNXEnwC4W8v8zFIK0a9IBc8Gy4W7oaYxQmfBEodDDHzSoNkjW2FI8fbjzUFnrGF422Eic2PedzU16xSwpz/s8yuxDtcwAnK6c63rDrPuMMvO+5rprg1sRKQvqFWRssMCYwAcD3nLBQJf6bKFuU802aRrIcJTPPFLyl4OJz0hT/OTalS4uVtlA4mhwE2yahJvC3joU7cKHfm1it6wF1nPghAT9AFLcHA9cf4Z6/7slOvjYNg7An8odvrwC8z1x87wRTLd3tfi4S7FFfMXVnxyIeRlSDj0PikKtxkc1wUdj55MGLmEnARLCkMSLcMjml2ClRPY/U4wiM/9BzuNkVHeyA92P9912dT159HQh6QCI144njk0VbDLGpRYk2sSyJfzHHI/bnHQ8DxUU4JULphiisXyX3RHDep/cF8eCcSbbN040Az7QaNjd1L1m44fIH4PkPuDeeE1D6IHWEADsjR6eqwf0rOq9GAdJ6DJFZD4rkRud4aS0/1vn4tx4r007Y8XzBO6muyhRRLSL2tK77zUo2pl125Nr85jaa1GmW0me1e96irlJmdbvvliaXKPOq0u0lVZrd90gEPJFJltk9POq2jb0eXmdawVFdndl92Tk9Imdk57Z4cHZMy86h90u4eH8FEwU2y0Pnnb6tnhp7tVH+tOSn4fE6i3IopdVotvCZOj09BR9tttWuvOvCvI/xw8vIUNvOo1YE/OifwzyPY+dNuYU4DbZQro9Et1HhtU6lbqpP19LqVNXY71e5Otbupanf5zZZW+lXQ9umWqmtw/zyXdcElVYJvf6M30go2vfS2Wu9qXvsCS95c5QyuG1xgv9MpM2+dLL/Yx2SL0r0XB2wgxq6P3sHa45lGIBzbXEFaIlpYwFwfYFJrMeaIi6iGkn2RxvNSryAT/cglBIt6VD9SWJ1W97B9Uw65gIPQ9OgzPpCBB08W8z7UG4lQhphu7dPbc9btdk+b7EzBy8VPLXcqMMmVwo9XOZy4BoCMxzbGKGmELvUZQIguBA+bN/6N/wnePVKD1wnLzsIexMAOy9GPI6A4z9N/KcsTANLDMs1E6AYO81DngkwOn3A45Fc3foO9g+Ect8wK7iNJNHqnMNdG++AVa6tvBF06h65NxZdsEsxDU+uoTdWOW1CvZxrNqdnuJauenFLVow7U7baW1X3ZSXXb7bSw8mkLO8avqYofPUevd5cB6CXbb/Q6veMW1YQmsKrDF1bNZMLhTqvdU9Go7c6rTvdVq/UvOziv0W61Tlp1y4so7WqZcef8WqCCiiZAIRUemqrCFtVPWiGoEjZg8zoCW139payOxS+mJ38oTTkkNgjmMmZ8ZgKK9ZW/pD7XXp2267XzD7VXPXgzxg4gXy3siuy6VpklrjLTkAVbev9Ogqg54H5z7t/5wYMPGrfOEahih2HQHE685pDPouGEvwlDvITa9rdf5XDi4ZdeF6YM0MbYmjtTcy+4IJKq89SyAM2gnkvqpH+YfFxEHJVXfBDMo4SySam8SGdlWY/xq2T78ZE9IKhbg+OstEwp1dlARA9CJ/2AqwzXGrVB+Rl9VxglEi5zFXVQcV1MIW7pnis2FNdVpiGtq6rYjqkKT72NdZoxJ6tq8FA1v2pn8XUa0TW3oiNM2VtWEX7xC2R3AJY73WyHfu3mvhU6fh4SNDbG1cKDsg2mg9uLMHJ2fO5Pz+eW0VQ1pcrvQFs7FrLW7lqEtwXNF7Vm5b9Q+XBLGa8LR6jmnaNwEI9G4QDZxf98qoaLUTKlA3aSnKadXCHnydrJf7Ju57UKj4I/kStZCv1OhA1M85JydcJwd89TPkwcna9cleReJ4FZJj9VPb+wxpjH5+vOY00tB2m3clQLOTvFKDKNjo5Si5H0/LQ3kzXQpAS0we1kt7lVIeaJLpfcJVguQcTe9JaSi9u7VzdBTU/kW78CjeO01TltVXSrt9XuWG95H6cvX7ZfVnamL63bt3vq9F52y+xfSRcYfSkVbd6zmdisOfbaR0etpXPMT5O2jJvgxRA8WO/sFNsv5TdeSjmQc/1YCoKUYuDGL68ZiMUxoxVIaQS2fY0pvv11E3fYREO0pYVewZSl7ckAIPJSFoFQ0G+FUY5A0Wp8ur5m0oAQyvkUP6nkyAo5EcRUzGdXi916qebfEe8oI0oZCIoikSAIMQMdJfIijEwtkE4DB1Ym1TXbN355C7CoWLaomcd95ol74dmgRZY8EQsQdYo4z/GwywVAe63lWhyBGueKHYNljjH38M9fMAcuzaqfh87kgeCuhHVrQUBU0vWWQnFVBixdBXYE6cnzkazOVcZDerUULI+F6OqXQFch4lTYWWnBDEHG6FMGuSNB3EXYW3+3R6rpvXAnY3TLYDSyNhInAj/9YjqlxN15TBM9lFG/qcqAHD4TIUbhucqzlYdj4Ik6nR0mBkPoTvh842t4TnammoDjEQrHDQG2FVI2+gEeJYAfDEI0goWuY/ZB1tlgHt2g8XcQRJPmjb+EczouTGAKyL1BaGlUFx8QfrlGWMzx82z1llKqTGCNfYQ5xDdciWoai5Vq9UPxELqYHatU9UEYPAAzRhmlH0Ve1XoTMbwrW2cx41KqrgK/PwyCO1eUrEy1BoCVDU7e5MxapaojhmJGgEThNAgr1b0Ti/7IFZ5TdlmpGvLYSjXWW5Uo8mBllA9NuZqOK4GdEchotSrqYHJ6d1SpKcVwDt7qFav9xkP+W8k6whmLytQsptz1+sFgNJdDlZ6sXL1H8OhwI9UhCHxhULbTURA+8NABoD4AfipXCcCH+xPBHRH2NQcrWdWd9cci0CFUJStN3RAAfcoVDmYQvzX3XQn8SLmwlu+L3jp91CegnaCP/CKahPOSLcwCz5WTkoVVNt+qywgaETGM+jIKA3/cFxEfV6iJwUyD+WgkjJ6uRMUAngN9AMsVZRmXPmqVmJAMwkgpfuiCByIl4i7bgizbF4hNfQK5B9Ikmi5Z94GPSJ9pA1GBRFpL3ktGKgNx5OsvSUhKeQduEF9qBprSFlWce2BvTt9xgjyvRPUZHaEJEpme7K9dWLcBoFmy18J3uQfyypUKTNp//Tq4OmA8ivjwThrR/EEMpBuJON6S+2zu6zeBkhxRwexKthf4e1p/PeQSBbUf5tL1IVM1PPrSEZr2G8SMGwbCLs3gdw+SWAJPbn0s0CZ/3z1RVgqm9npt8lbJa2j5oyUx9hv/QxAJ+Yq9ppcKvi3gvAahOTj/jSQoN3zekAAf+F5u2CZmtldagrpN/aj+ioOsh8EMwvGCEfqMwjUoGb/nLm5trBj8cgHn3BcROwuHE/de7En2M18M+PCOveeQsEH8sq/x0jkVaQbh+PBBDA4P4FGFp5DwOICxBKMRDLzJPokRpbz4coYzYh9xRnFrDpxU4BbSAmFH8HW8KQ7RAeaQlqNBy3GAyz2FLBCuyiyuw7g1a7L7Yu8JgnLHlDRTStCWxZQSv++YUslHNq3XRkwpp6EKTGk5p/FLMZpYU7DSVJtLhqOYG3F/wW6hrVeHh7e3qCFxUX99L0IF/HCrT/8teLoG8/GE8Ru/22obHUtCYRLTcJJS40HnpsT4mmEIn6WgSLlaBekt1Vde1oNPYuYtUC3kebEpApjD50/vlA8/JKC5wfiUm5qG+bdnrK3FQDz33ANypeLypgbNoO1/EcwRJIM9cD+isHRVWxkj5gOl+9KjqMPKSxd83jEjGxkQ2I1ekrlekpsa3g9xrja1dP8CUnuDm8tylnHHVZNcNabJZeS6460VFZhbYK/ptrbGYVfKck+LVS3X9oGRz5hiYJ2kArlLR/x3+4tHiUPXWz6q+63naMhfzu63SIt/RHT0/OU9+haX90mXdHuk+S2DyRdvRSX8+AKyz8z3uVOCPMFJULtZjX//DvuZvQjW3FFq6HtI+rJ8wyvdMLsDvJUsD9vczvUz9xQJcMv6eSr5bksCSdZL3soEkfKb/yNlfsjfC3ocf2ub8cQvlfLHOF81VsJ6HsNo5rxotyHcm/3bPZdU6MLz7SlMb3u7WuSStZae9howLAMfXdZGI3amGyd1HvukGs/VdGllVtGACtISFyhb0E2PQHWCJQPJVwMntUlZ1csqbXBBb1W0wgWrkKcdVspTJOeCntlI8GgeimKP34Qatnj8O3WsVscWkWkZSt6pZ9d0FN1ITbu8zQ2s9GryjpgJ35EaXRaq7EmLajc0pJnhzzwewVb3g1nkTt3fyEVuJb/OdUotTLeLsDH2Ef6C9THSGutjrHUZO7sZeEMPvGEP/DAEE77wh4Is8g1qHrO2H2IgibL8ldEq1GvDUYU52cwlDB4XpXujM2I2T3eu6lYYQcxqL9XisI/W4mw6IPDA9Pk0L/jnzGfoKI6o2rqYwgpaNSrg2D8HoXMJIdfoBEYJSBOjzLihG/aku8uch4STXO3h4aGp/gRCiqer/pKTYJYoAIflIQgdCKnOmXHhJoBDG0N8NcgMg+FKZnZrLfvDrD/z5mN3Sa7u7PmyiDG5vtRUfNTMFNFFhr7Kw/jU0alxfRlxbz3CSbFXTdZ4uuwltmdqE1s9n9nEzAzu+FoG2uXPIk4YSb26WKHYKKTZ7U8D9PP9rkWFFH9Y594fhEHkuQU+buiZin692qNBOTBwCY4Oco5e4oSH9gM2xEBoCVVMHffGQehGk2nCSQ5hEtFZjfF0LeGwexFiZbUC2JMtiqsa53E/O8E7Jgu1nbGspH7YCdUlwqAiz91EhE608ET+DfhX4NuXRSbsay3dxDkFvLBJ8MC8wB8j+ibkI5ca8xhyChEvUF0CiuOUuz5shOss9xnLjrK6wiKON5diGMBbIgpocNZgRwEAuF4p8kVajgLWUnKiZDe1TxT1wd48usTPfsJ4BXlTS0whJ3K9e9xqYdQxJX7vtnvwS8vKBd9aofv4gZaBneOor6/fVVB6ZJYwT9uR6QCzk6j1OmAwczjLMt7nmJM1DLi1Xkxk1WqTNee7d6UbBaHcQ6Y9R3i6DHufBD54xPkL5kGsZ0jwOqZ7JCbLabnJjPim7pT0M2kyPBR+Yy4PeRi5Q0/Iw06r1T4+6bw8PkjdDpkF3l0O8eWQOoRLD+j3dmWsEWK74XWR21j5m4PFR7t5478nJkRzRNA3ID5El34bCgGoylQYfrkMg+QPOn4i+WscgWT/rrkrRwYTjFgLX+Kx62wUMCk8CEjyx+y2iOHeYpATvI8BJlsdKrA2YARHLoiIuRcBQ2QVL86uNEaSredi7dMcEAaYOOCe1BchDpyi3sDVGsys3gIk12DoYoolcDi+8eWMT6dQBKY9FCFwfYhPL9Kzp08mjn4TPb9mjhBvMsZUU+fQ5tOo+Qs6W+fCg3rLLrtUF0BS0p26HsfYlx+4w34QE37v4pXkMC8I7sg/nPaKcgzo/eMDTDo2DWQU7+VgwRK75wjfNWhj0AnyffDgbjJ2EdElyD0ZsOEE1AwA6qIvTnJIdwK8ZCYcn0GAosL4GM4OepL7gQ/75juQ29H6uE9t6mHhSAcLGjOSUp0NQ/7gwTiD+K4+WPeCfdlqnRRcsGozd5dr+nJVC1NwfL+3S3Wdd1i8Xlu5X62GniuupwAfY62r5wdsSz10gPlgbm77yZObmBviAjkLxRjSCt744tGoZRBpBbjXmIMalHFGw2OgnmQKcVMHJmssluVXVP50q99VarjMGm0UYJQMBh3CwJFhxOPVCKAWakwc9aiWjh4Dgc/Osd6Nr/a4jH0GAnLkIXD2Bv0zNsjEqXAa8Y9/obWgt1Qj8Bs01obq8uDGjwLmCR76Cl1cB4vmTF2z6hX3M/X41+aL/+/yp8urN1dXF6//2nyRxMdq91ppF73lt3fuylW4vGn+uGR9LsZuno0Ffo7TpziCdP8OE2PU7F9c6tQiFs/Xdy3ROgWj4g8eX4iQvWQ/n73FU3L++oNOI6pybFrNQktA54jQZ2BrvUXcHB9iPgomVQoliP2Ce8r1IZBLCnsUTCM0wF1Msp9O/BKFfDRyh3RGOZNTkG91KgobmDcPq854TOD6lRJTS19cmd1PmO9Vh8ZWj3+vvLvefWt31wr+UxKUx6bi4gtpCelvcvkU5isssKXa7lvarSU2kyrxK1dayluqWRB4uXB+b+gswXfmOuxh4uKVNALBEyIx2TgM5jOVcCr3ZOvQU6qaViANA99XYZkZ3MwcFgjjaKBUkMPVcjdG29jWeApWNmDlrewf/yCVPQIKC2jS6U/5I4DRCD7NuQ0+Eiv9qcPe80d2RcUQh9sdz0NBRqYpf7ST8QX+UMmgJuwXmXXW2uQn0nZLEHQUicFF+wDGLnhVzX3M6gVrTenjUkJVXUPY6V+1BcyNmgzcXhS4yyhxPTiBkGRKp+Iwyenci9yZJx5df1xnvcdHRn6IbMoX8BgKBjr77gxfZCAbeAvW67Rkk53BK9A33cGAnISzjSvZbbvVuk2oVNAnRWI6tFlkg8uQW4MbUbXbJvyHTQX31XKmhovwpYTnlQsgq6+t3B0tdcQqSeVLb7J84rNk99zv3/lNl7soVW++ZY0s3/B8TnCVoYA8bGFbJ9hO6gNzRd4lI4dhY0JLZZEuZFkwSlQhab3o35UJWwplG5+44wnAMGMpbeBOMykeRWI6i/SDBxmQxUUUppQmNZQwZUoynvI7wgY47FgcMUg2sx+/j5RHq6oRBWrpy+PDTIKHRhQcknTRgFqdRhQ0qKvDg3o+VswByeMZlnVT69zUqrOsm1r7plaCEZl9Uvvz+7CiDFllmFGmxI4d5S3LmgypoJlSLClNQTlMKaMb6dTqtXaRKsQaZY7vaXXZ9EpA0rBIaJs9wFiixV6rUJP2C8tXdbmCJ99hbQNTBCkWfliw1zSE6+IhbGiHyOupqh4jgzi71uYokD7SBQAiGKn0TNsGTfBh4nqwWGREUJoEWDt3eOOjQxRy9YHe5tTVcC9CsvEb4fDzp3d7wEUj4UtMxKpVgKThi+Yh4NDfnhO1NGCJbssQRHpZNqeI12YxzqDFpySJVFeVacJCEt7I40Y5RUCc1YI9wJbpPNm4y5jF2RH0RnHE0HWQtcOrGXSeWgmsXWEULSjxYDiXUTBVj3KTcoB60TVufMMdZDAVEWpYA6VE4D77dS4NFZUhCmtdfrE3f4X/vdGQ566SVHoCKiYhAbPgoVZS04b+TSxofKmWUf9Pau28XNlxAlzdOKwMGhJ1jLOuzIJRHQWzAODFaWdUaioXVIbRnHvK/r4cczym4FEQ1NKa2WVu31R+wPGwTfnjBTWp1LvqrzbYtYhuSs5Xlf6dR51NrFivKTTZVYShzbdjmIsC84rJgr155MPIW2CSb0jLcasmfAsasVvUAMMfoCl7BEO/cDYjJT2cPwUpqeUpOV937Afh701JpejfHvS3S/+BzEle8lrzckP/4K9AE7JvjTIMUqFnL1Mmxw1Caz9ZfakOUCrW2YbAfnijD6F6dtoLq3XOufO1MatXnnqAN8QKjCpYOXOznODGz2EFbD1OYB2JGJIgpSfGc4BP2YIhUsP69nxh2bKt3H9FxFs07dQJLCLCdYm6kHhTxwbhF6wzWLhKiq5+j2Wyz/zvuE55pwB8frLU/1bHKaN4hYYWx9FmHqkMyghj6TsNdBvaJ5ftAzwKN/5KXrA0+vHc41LS04Kbw84lu50GA9cTt3V26wh5FwWzW0yzeYvyd3RrSZgoR8LAzsCfKZ8r1GtjkZPZVlGKtKJS9sBAMPejcFFnjgjdRL612Lpa1I3H81hMop+RG8qIQcE5wHMCJo5OBiYc43pwezaEt0TjnSp3q7kjelKo/F405LKM8GviwYJifLxzld8qlDlgrWfK2QzQVekhgQ8GOEiJ/QzoFUUen2JFIIA9nmrPxRfsljwdbl/Zak9jXKHnz40P5bh0h7cQgey59xSokHCWoYf3gwpxIgupHxCvuPGZYhfUlnSnMw9VaHaDxoqkW4bDKO5FuMAcZz5FO+M9yLQSyWZF1DYfoz3UvRcwJ05eOWCvwre+0d7gO37C4dRl26AFxa7x6Xb7il1jlmJsSTcB+B3UKDqfmq5geCPQNpCidSAWge8QKrm9xkpTS+oGqKPaLa8pBludmEXyULWlHGQGyjHz8C+J350GDKphNBbyoJwTTMYnCRm5dIcQEGs2slavxStvwjHjJSypQHiHRLzWUczzZrUaZaO5r1JfqZM2IhLSKh6KmEctOk4vVvmi8RxbQg9Wtekx/e+7TdGss6GUdeZOAe6kjiTxv/yeX+FolHY+Xq5k4yRcZAha6yfwfJBzeCqchJqNFz5vzBbxmyHXWfw6why/Cr45cRTWDyDpJf1bLapP7vLO0VWdNJuDF/D1783JtVIWsU18WrPNbMujNcEQjd+X/WMOH03ztg09XUnUiGXUN4Yjaxlj32aS2qUylkY4aEQzbpSUWTDX27WMrPJ7+7P+Dt6fG7p9prLYrUULlq03VmID/4TAc7osgAGAtRmuHLZ/ff3uICGXonYc8di0lSHtKA02GB2AGAdMxl5s2IgzDwnWIyB/aiXuacVKzKR9ET0E4R0biBFckAPh+mOwtIR3wlHylwddg+/MkIdOMgE1u6IxwgtD+6eSXebGhwgP0/OeNJb8K3Ot6LGb+aemfuPr1Ggy4S2kUGt0dMy+iTlRgj7512rTE8hkFP8St0YtwMkK50pksR898UqD1zUt9bWO2vUDv6GlUrRq1XF3uX3zGtPQjW+xAwhWAxHjEh5lnyBnglkMP2jIKNDXd0NbWcCp4Mb3ggcKiqUGbqf8sQHvtcNb2ZjyR/jngXHxlQkfCprJjR8TjQ4F0qWtZIpl+ErykFTjLWfsf68+fmB0nuzs1DJBRSTKuxDoFBJFoBR1ff0O3sRvIG31nVg06G6bcTeM05EZilqYNinSGnK1wlsED8coMObJhR/xR4gZvKXyfRjD7St2Bj7T6Kij7lA5B24sWafVgl3ptVpNZlWB14VtnhSgrrPntfQY/x1C0ekJlzpOOqd2u9VqnJ6eNtND7WPq7dtXFE2mR0txYuS9DasZNOPGrWpxTIW/WDVWbIBCNGyXRBMajQ3S8HAIeWtIIWRihApgPNCaSxlwDldCRxiab8WJIvagb+QDa/+QSOUrc36g9n4yprPRPqjDd6KE1MdW8okW4yzrm+o/tU6r1eicntZenRxj9Ga31Wocwd813WitXuu1Wo2e/hFHgul3TazFZTI9fYFa8VZXvs2dxK3uMPO5dZDQNloDM8P5xb5+rQIrlZJr7aLZQmCgOtbXXle1mCmnONArZm50daDVVXNOmblKX+06klGDTKRcT5CAFzGwANeOJnaIbypiErGl+CgCVZmBFwV1UwBzU0HGcQjlvuYdnJ2fXV6f/3R20GRnWD1S0wPWJB5nIFXbzi4KlgCiLaNANw+Rl754iDtosp/h3gVPYPAY5qzdYw121GNT1wfMa+N8h+7ESZ+9GPLAlBoE9yKuLdcPwmx3U49UsyJ4Ae5gDpIP1AShWtdu4vfdIzX7SLUXaKNnak5Daz1Uydc/Efh/AsxObWm31aqftlp1/LHzstWqI0TLyw781oIfCSegcwL/7r2Ej8Quj1tHWKd32gEvYQ0fYHM71+d9JdP3C8NtEnbY1LkSDBsxDwMLrZBuSnOaodQHVeqNgZPbHWhzoPP2wj7Yed+/uwNeOdQ6d902O/fFDT51wq+cxVSDcmcTERZgfIJYYtyhqCCeket3V4xONrmsg+4aVBGqyBR84gZGC/BDAMO8unrHiDgy0NG6no10kupid+CtA6+2zDri6pfv7lCXOMW0NBud20QTa53UjLPUMneoN+evf3rT+HR11jh7c9XunDR+PH/fuPrprNM7rtVr6rern85gyObkQz6Yue/+ey6UK0XylIPytD/yQCL3c12HUqcGK7C4AiZOxjBTR8xCgfGqekfzjEMfzt6/YW/j/pIPKd2GG/iNOHnOtTmIBsEJnPB1d/+HzTyMLQcFMaz16w9XWq8lVdod0LQJ7jTZ+1RUDQMb8Upj7GjuOxzwU7knD/nMteAMrCHLw790Wp1eo9VtdNp/Vsb0U/AA7zZFASSvIU04iHMap7Uu0uKlKW7Hm7K8KbVGGzGp/LaWc6vMKS8lY6jyfR71wyCIcnmCJoNsWfOLp1xc/pxsId4Y8gXp6yTTOY5riCasMQiUWlqjiUpMC8B9Rk5U2nXKAhyOxGN0CIYUJ3jw6zd+DlgAdMx+un7/zlg+UMn0XlVScpmyG0DnUaC/7R9onJDmjW9iI9EFxiwYc4LhHNcHJlTG6wUkYBHKBncPtX+emUKDBgzmwMOD/BBJ+3moXHjOzfL+SRnyWpJihvYsBp359t1x6OpPwvSabcSxCxp7NmxkzLlesNXXyoIsIz6dQd/aHTA2KuK+qza2ve1l4mVpEhnQ+xwllCnB3oPVCZTSQchDV0MRScQvAhdFMKszq0mgaxHDHj2IgcSUSARhwXwBenQVWT6cgGkqqb1X8WbIhwcKNMrwij2CSPREiOgvMYSZBEMsMmbTUJ0N5mjvmEsxmnt6AMBxpvwOGVbcPbaEsevawXHfc++E8WhD97YgtL3aSGkfzD2HYVHEKIVzHsh4ZqE7nkSMP/BFk32EKB1cL0DhyCwZzhj5BSxel02CeWhMrj4zeV0wrC8KxmMw/o9GNmdP79uOsS9J9RAf9MynHVtfxdbTS6a5OtDiVPQJ4jv31Vwiz9M1OoBEIrznXhJunCKdyTE0dXzIRifZ/iyQbgQePMpyeQA0jRumzXj7vhjzZBEdTecEMPAmuxhlewBLoA9OvWwgYumzTiRgMCeQkPMsDinU99T+rXMdFmzCUytG4/4Js6fPZ7ONEhiORuini1mNkn7iZ7OZLCMcK/PnIYi9DYfLySDgodOAgVmZeujvgxt/P34LFfmBa9ZgT3GVF/drKoyjrmAH131Y7j6breaN/+VTMLwTEXsXwNOn1ArOhHAOE5nC1E14GGJbDQ/bAgwWDpjdXy4Dz5WTMm3TJXo4wwqHJVfcXo2yC39p1am+/hp0cePFfzPlrsc+DkZzOSz/vuOjwygIPOC0IZ+JhpxAUNYhcFKvoQKPGkHc6OFBHTYawDneAeQnXED7s1Dcu8FcalCguvXsPyg7jPit7okxHy4OA89pgMTV8FRH1PcVDpRd4UA3mSO2BqGX+2DcOGDvgiG+a6u1CbvZ8FTVmE4Bv3PKfT4GVygAbnnKVXrgo4bqTMG7liR3Q3xlaf1KV6hO6L/xkP+2IcP+8i9opMxaYW9ll4GGVnYNcAwVFkAA5F1/4vpRfp5i61JfAqaFrJLNZ+i0isBS8L4D9ohJElD3A76g7Vb31tIeYZTJ7TvXv7s1geLGm2/k+twzhW3I4TcI0/cTjLl8cBQGbh7idBs43dVaIauf3bMhlodtkonJ1f5191hY9ViwVmsT7U+2mWeTdIUzFpsmxMr4M5pkU0ujAMZeMODeja+cIJrsxRtnLOLwghcUaxqhYyIwRddy1ld8ZjnvTU1uleN4BixxWc6UVYEhyblUYeWJQeeFP17DiUu8HtE91lps0jGBTkbOQ1JLxbmpEkon2iflpZ/gmunx7xinZpxJqiomt++NfZbgl4kV2ohl5rW0rkpGHWr0iub33MUlSqfhjmnQbrDJ9q34q7+ybqtuEkSxvzJ0t4QUUvAJtCOYYIr9lYHj5cEy7030zIy9N+vHrTr4cLY72okz338TPmkvzqNux/hyvkTnTfLobL/sxB6d9e5R71gXbtV77ZPY6dNiSvBW61tvtE2EbB9DK0Yj9uJF5kH54sUyR4LsMDbB0ct0/jQYepluqlwG6Qnn3Qdv/GG4mEUMCzOu0iQYPgpBPyjIo0xOqY8IN/FOiJmy8k7NLQsO+vMppBVbPxNSO+mEn7cCu+tEXycZml5K79/bpVJdJk+v2UbXTEFjz5UdSTzOPHfoRuqqG1KI5nrMVyHzkkyngz2thBeDhQl2hYMEFxVeXUrdZG41siSokE4Fbp+ubN2JqvgKST1/nptw97zpPg2Dz+upAo8fBeEDDyHctD8P19zbT8JxQzGMJIYsgsIREK98wiZVIcA+u0XsuW6rfdhtdUCDQ5WUUgZx6L787HoOxFzHIfewz1oluHkqqAfVfkO3X6hAs1DEEgtkOZQlP6yiluQyWpGpS0kJg1MtKAKF72qtXrfVxsA9CGuech+hjOyvHfqqXQ0WcVU7gLLbate7rU7Mi+J3aN6sFKlkh602X/dhpyajoFwl+P7Xf/z59Gsyhp+RiZFC+Pde7Jkg5wCi1rmrmXWSMQM9vDo8fHh4aKofyfASTAWCzx/+V/uQ074e/lfnUJGl/qGbAWBoZYkh//ylcMDiE/nWEAYsR4WzOOn0Z6EbhG6kbEU5zrCUAgDfx5eJsoyMTNIgByDCzwLWMkYVUpm0dE6fOKGAO4X8XiLWuSai5CFVJma0NHlUIBaWDXXM/si4d5hu0ZqMeS9dSNni/6qQkkhf+zN53dliWvHMdvKaRe0ZEokZUvbbTl5bJa9l1mwTea2osSfWp9ZrhLxic5JARn3SUvY1BsgmWD/coJ/bALbLHsu5I6guUUEz6Bqu7kB1JdwCtK229yx/4MR3QgYMdKlcheC5lAGbfdQTqMDLg8hzfQChxmQCucw8aRojxF6sxS5NLY2oRMpUlSuAJCtyABxyn1JWDe/AeIbca8B958F1oglIxoO56zmEqjrWDeBSovsArrDF+MhX8MxfIFeI4UMx24tPlRKF2cSNbF/COnsQCksb/Rhh2CrbFuCAwli1aIjVbf/xiZg22aUIZp5OCBYpXTJXygGwQeP1BHLhvSse9DRQvWCyO5OTor1MD4G/F9ktgR++R8oHmBusCOna3JCBwyOu1gZaiE5SC5Hd2d21Zl1r2dNis5LMx93FtvJiyyzaRjdbUWvPZirEnFX58nDHKBEStJ8WLjsMx7Y7dsm3U8c+afj37nCtPFywThudJ6uB5UeIKHd7Z6ibf4a65c5Qd3eG8s5QN3WGurszVOoMdTc9Q93SZ6i7pTPkmqzCOeQTf1tGMa1OV7RbvdGRGIrRCXdOh7zb5ifdlx2nNez2Uiqpbien7zxDXNz7coKt2v2ymCcUvvuhkO5vuVEJF/hcuA65L413nJVKPvAbjpiSipeaqLM45pIQLC3XaWQQSt5PabISbiXGpycZJZo/mMoRo8rterXrX25/O9YZU2KKeuJzl/qwY6armGlywTbhqrktFSccys1eXzeWOQzu05KF67PbYCZ8OP+Pi1uM/llT4QXN2Ex51h+LwAs28Q6xDgl3HIQufNu4uDynvCWUOEmFvFs4rmSfoCJkqwFNRwzjamwbCt9wlbUpNRPrSCQ/bGKbBIxONfSLS/Zj3KpSdz2NnTK3qwoKteQC5HuioG4n1RF4lACcpO37qT6bXYlDZVVcLV49GCSb3WAsuUEigxRGZHK4u+thjbOwux5WXQ+JBdvoeshr6bn8UdzZ/fGSY39/jLkFQG08H2g/EXJODhPnX6M7srUPce8kfYjvj3dH1z66uB7xgb0/3h3TEsf0/nizw2nqPxt0B6Rpn8/AJJPt8z1FMDDp/oZdcwXkiOeVKtmHCLK2f6am/qRHKX7AVz9S1kLHG2L9+N0dr9XnKV6dTU5VppV1Hf3xGKzl198D53jbs78TO/a3Lb/+dsKtP3bhilGZLbf+Njr09+qQdKb9sleHNjudXr3TA4zmHjr8dzu9erfXqndf9urgmX/U6dWPeq360ctevYfO//Af+Bf673fgX10EaoZ/HcG/juBfvQRms0JUs8ENMrCUy3ZXx2H1QfGShKzMdkIvhaJu0snNE24SViyWCbxqtVpf67WE0ijlOGnlFtXIcTnfyCNr9VN1FiBkR04bX9PUPCT4Fd1rhqLzYTlz1871+5En+0oRl+PN64NTCOLASXwaX1k5WLSDAY8Y4OGREyCg6IL1MBgGno4Pj5NpNNlbUBTQUOqAKQTl2010bdQJK+vqxxY8wH2hstjoaLNQ/KpKUXhBu9mus3azQ2nz2s0u23dHWvQ7MNXAa9KNNHCUjQX8XsflvLtif1cDvt9ZP1K3UopSrKsp9WV3P2Xvp+QSbXRJ5Ta1LSmw3WxZO0t/tZtt/G8H/9u1RUI3THK99bRw77EZcCWeg+tq7NOEXqWDhbYEuD6jvMZsEAYPkuJyLyI8XzGqGTq1Yoa6EVVsTAS/X8RAanC6MVElQJ6pBm0+A1wEfVTbq/Rjav72UQgVQ15bZ0eLsV3NXDF+8ns9g9WYqGqXEkCoCmtOJ0flnhstVOpeiNDGJDL43IaiN/6VEFuHPm23G60u5YSah8iCHRFx11ORIGWVjrRzecrGswRunLJSKac6Q2vQv9YoGlVjoOn1xqcs3tLGpUD3PS8YgzO8Stv76vAQfkkvCI2t05CBB8AYDWq0gTAaB5DyK8c6hZNfte+MDFcfLctbRVLAnHoJglgP7jYHPUlZ32jyh7uruATb+d4u3sp6F1qoza5fq4Xt6l6KEa2TDP5bPJ3x+iyjv7IIr0inT0WR5XFep3MvcmeILUXQ3svel3Heu9Vk2AqjCNPRrS7KnXsIzHH6jhPIknUokTtGxPW5GLtl63HvgS9kP/A91xfV6sylQDcdeISXrKivVarXD8VDCOJZ6QYGIbiqli8MAmMC8KRiTXB0L10rmVm+ZJ1ENrSydfISLZWsm0HjLllPZX4pWTqdlKFctQykbLlqNq5UyRppHJyS1XIQE8rVzAZvlayXdY4vWRF9fcuX7ZYsm7HTl612f1yyqKX0LlkhpYooW0vJ/uWK+6Ls6Qzw7TP3XQl8ThB+RpW1SjYQ+OXnFGDS2n4UqH+VrgYx5n0RhkHYh8CYPvhG9KNJOK/G+9T1o9qbdHAvZRQKPl3nGlPtQCNAohU3mIBTS09gBg/OaDiBf1QgvlkI7lS+U5qRzkL3ng8XuMSlqwSPiz6IMH2QeoJ5WTliJsXcCeDwHZWsoSO7ETmgz90+RmaX5+ChmHl8CKp7hOYU/V/LTtJo/Qfz0UiAyFd66whqt09Qu6Vrqb8asUwy83gEQmbfFnrLtiZ4OJzQqo1F+ZtII5iqYMqqtaoJGwTF1peuI/ricejNS1+xcsLbfaXWKVslCKP+v+cihOTqsJ+4OHS+Sw9YVpic9PomaXDplYSLo93vgPy7qFSl7IUJpSnFDki/k7K1wrnQ1dyZIo7SSwF4uqXLisF0OKsoRapKMz68K0voD2IwK19U4pGWmD9bv8xApsx/XpI3EIMCEGAasi+f3p6zdqvbszy+ecSjkA/vRNh0RTRqBuH40AmGh5No6h2GoyEU/4skIavRaXabRweUMl7h1eLLHoOVlT5pPgOVXqfXhbwVIR9GIgT0KwBAEHw4YVKMEQZ//6bm8YHwbmoHqJsSj0MhUIF4bFddgeSUDHSOPfg7ve6y5yzILUU+VSbXLVz87F0wHsOgQgGHHHXpSiWmbNY/iIgfMMuOllv/z6qz+1ciMVjJYAxYfSuLvdgBN+aL1pso5+Lqa2nmCqxXVqrpLA3pZUUCsnR6+DfZXtQvVkPm4/Jnwpr4W3Zr7I1pTecd0rYzhG4aDsHNBF3eP3+6kMjhwHtLDUI4aBSHZDy+8NDapiP7wfVSRm4Eue7gRKJvAEXjm6gf8D8nuxDTYgqWxXD9B/B4uZ97vgiRBWm3gpWmr6LVsvSlRUU2AvoqWNcnAvsq6K2CSWvJ67PgGiAn+EIC0vEfiBCRiRpVN0lxbVPrz3ovrGPL2Yiav7cLpLK9p2jpNrlkVrS5js/gawVpSJNPOQ5ClT1pUe1mrvV5KqWszdtxMP+nFzWu7oc6GgouDEixJsZu5E55DOmiQFmug7BOt0wcMKXdKjSsD5xF7FSn+JQ6UyoskXh0I+YHjpAZJy3NXrDup2Ae/YkFzM0ZCe1rEQ+hrzv2sYb6dXucw27ud2caq4LhM+rkHNhX+B2OufrX/sfOxwMtdGIryawAUJRytkeBAnCiUog/mCi6PAd8uufyid9zkzs3WcFUAF1zNvOAQyRzSQK/EJ47RlxrNQffsZygFKUAyKc/csfzEEfzf5LHCtROGmjRE5SQmRIjsY+dj+y+zfbfqyxMuGwHbMajyVPnl96xWItrpA+BdWTSn3bMtaqFaiPOmt/WVsMVt+Wes+M8JTmPtbuFRsn1VCSp/BB2wCjqLwk/cSx8lSYZpVtXyjnCkfhRnHaMhqYS22DW02RWU73EUeiOx6B0sTvAFtHBOW5qpTZhyVrY7Ki41BbAzknLiz5bl1xKaPZJIc9z+quiB1lq017mmI6hI2hyZQS8KsLEBiJyzYL1Wp16r3VEnyQRlkUW9gNHTuhxxA2MfS7xKb9qJxBK24bYrFHAep2O7gYOuisZZpSk3EtWJBk8mZJ5lswSSvZxBz6w3RO1u+vXdyvZ7Npf1eyzoVZi7+CrsvpG4hRnsir2UblJqsJf67VhKOA2UhRWwn8mLl94fEq4a9lQZFlCL+FdZVXIGYfyhVuUa8yUhsBKvJbK1VNl4Wrh4VhEJavpwrnUqT/WzY5aszHDS65YYhdt6oFQpxx+5jsuiIYSPKUNDhOSrStJbqOsGxZzff3hyujWmuzsxoeFVud5Krgv4zbwfgOuHoqhgNThxkoD91CcFuDGHwhfjNyUcSZm2Cmzl5kW+l2tJ6MRHDlhYlt5XilptjFFqINsTf8Kk8vy2WyVRKIGF59q9UN1+chEdavBLYI5e+B+ZIR2jTlUTsTzAilBqMnAMVgf4J+rUx1f6imWFZWMo1xO5pdpcC8km4qIg/8Eih9wblQWMJyfRuiGYCwuIxFaWSbQ77/JfuDSHbL9d2oqB6/YJwz7w23U8BGXH36ss/+9fPMjhfT+ePGWjVwwTzXgaeNOZ3wYYRifK+fcY/+eY+CZbvy/sSr1sTh4xd6quLAw2xEWpKatQSdCu5rsHZzzEMtKBJjRDtO4sbMwGMMawPGh+ddNVBhnXvAgwgak5fDm+ESitkduKCOcm/CxpOszzibueJIsrdwcm+wDHVLl0USS1sSFomw2CaJgHPLZZEEI6LbYpygyN85rJwGu4gTfm1xX1pN2E5kt0cJTgtdkuWU8hthTd0WqBotk8TEHkKaiQXUFhAm/xyxIRgdDvp+Uyezsgg1D/uDBs996AsZv/T3J5r5py+Qut4+v6Wx3Xq3zGm+fdWbjH7+7c1v5PRYv1kZHOd3Ks2FRZTz0S2hxqAYqbD5/emfhxbk+uj87OuVMJvk3KWPK61oudV96dLuza5/d5M4lTnDy0+4cV41U2fA057X1fBoUSxGQfWPpr7pjULXUCSAEkgUJTFP3MHGHEyuW2EUEcnBxFM6Nr3wb0dTcZGdK3GaUE5u55qmtBXHTZxKz6MZ3R/jEQ7BZzoaQYLIBjjFxx/swPHb2it3qQOkXtwfoG0nvQsRruPFNqq24JoAI8zuYrxgKB6wiqrEfrMawHveg0bpuZZEdN3IIqsxkwNyI6fxckn4+SzxF81DElvmTJ8KXMpt2SV9RYQ8mJDiUXDufMvEYCR+BlrShyNhBEhWvBZ/aWQuhALYB51w8zkTo4hrBTJHvGfCNwSJ2RZprf1frCai2PRix87PL6/OfziQq5/118H7bAIzWPj3tHPc6DTX+Boz/YLnnQnqN9uOiB6W8GPIWOW4DLrROq9Ntsv0z3w/m/lBgFELDWOny0EbUtjZgW2EAvsND5/AAX6v7Z5cXzBqKxlqxmtwOrstRo9VtdNsHu6vTvjqt82Zfm9bPuyuzStDlZtdlpp3lV+Wyw56Y1jNChfz5+Ye1X5nI2UIYWzwfAxE9CIAneYB7A97uMxFySx2ttLkJwR9MxZ+g8LXqY8e/LP6V2QGbi2U+fne8bJ3w781YWEFr67ijUpHpXGLuTX142njsj1utVrwRJHklxMxOLx6UFaie+xKgJZQiMmnSL7EK4MIfJShRn0rr8586qVnyuilYlMKbxV5461xav+4O5DJYhY1OYqaZLW9unkaNO07f5FWGlyECMOmf4od5MRBEeeU56uB0Q2DWoiNzdsF0Y7GuPArgaAU++Diiqg4gDue+0c+h0l0r6eqUeBgaOLvAREOepDbRO2seTeApzCMwzynAI5s3fNJzw9N7dgFJvGhuf1Iesc7FXUwAMUkVl/nuuEblJ0nh2m3CUlY1+my6+jwcmBUgq6oK01XY//J7foXFmecOQh664BID8AqSj1Cr52jjPfciEfp44E3+QYfNfUzn5fi/kuPkDOzypHOywkyY2l9voXFryVlmFGhNkun9FTh7LEbA1qjtmfqz6QZKq2ZYTInJ7NiNzW6yBGMzmuzXHYtZA4xpM+ZS1NyzmQvQS+Ze9LVKez0vs/MJBVzErvzcccCdx2Tzo9eGTl9AMkhMQqt8uTKjtAk59am641lqyMbvDALqVKvIJVeNMokos9Sl7BONmn2MJ1TWuQxENjGMAAIq8Md9EfHxVsI3BotINEZB2IB/MCDle+4Jf7hgiNkpY03ORNz4FtdDACq8DrKhHPkrFm9dZiabhFV8ovbYFbbH3lzzsXySeIq8jiruYBKYbSsbqH1bbWebSTD3HPbAXXrmIyRJ5AL4BOKp5wfgsIEYBQRQ8cBDcqyL9Em2sdmb7IcFgLIjt0l5+UAULaBZicgwAULfYhylgQXjYQjPCRjDjb8G6aSWcFPKQV+FH3Rzz5Q4INtx+bBbdAoNlYF2vWQCGxHtMgCUINQpbSUzFWCldTOWLzLoz+BO0NFfFhlN+UJVx5IPk8ATbMYX5AoLBmvPxdCgCILmAjBhJmkNPD/nMjZhEh0PhK5JV9FwMvfvwKt2wQwxZ0fGFO4moxcBJPSh2CGQH2mUWVG4pM/L01CILSdsRCQ7oToWRNJ8ZzlT2onUlVFKN5OoC1p7ToF67kWUaW3lrY6JknMupyDinuVaQW1Ko6lXeDGKM7lDOyu4MQuYnWhDeBDPA5vQO4o3CUi4rg//dn00W3qujKzeV/chKHos28+HzExmOqihZPsdSCIXwbL0l66Zbp/fcxeJHKcVzCN0WFRuxTMe8qlIIUTm9dmKe53p/HvLd4qKLVuoVutrDFmXwNndihD4CVtk77BFreqtENejWVliYBuJVvaAnkYat3uoItGkQI6zwTrJtQTHKwpm9xqzeTgLIGWfXPjDSRj4wVzaGinCO5Yqozq4yGqwehB9yNsX+DxedkqhrvLw6agX/ATS9h61TCNL9Ogtmgz2X0GLJseLtgJ3OhWOyyPhLYzzF4cUS0ipe/ZQ8BKSwVRgiBHEuMk5CDRcohUeJJe3GG9zyV3AYL2+fnt5QJFFCDUDhHb74PpO8NAMfJjFLbW5z6WcTxWWVYjSqr1SKq8nH4sDJZWApKC8AmeBdCOKCdLRSrguPwbBOI4TCLl/hzFGaDiJ5qGPokQ9b0WSyA+O0LKlle4MnBCtFTf+ESgrYvdgO1HAtH6QBIXQWBGOnaTqMywyOnFAF4lR/VLCTy6VTLvVOz5guemqasWnYifCaREuwdoKWd5OcKuCEb+RzJbT0LOJa2Ux6zMD+mJsLexS1UhEBuLh+DkInUtQKlqo2YWOWWYIDT2ERiJX1IGOncLjZZomjQy+puMjtycZZGRhKqUNhZmCng50L27oNGY8RM9mP0rEXFSa1I6rxIdmFf3ERLiq5HfHeaokuSpIKLEO28nmlyjvh4EGUanSnIK/wxUJIhCfyLUjvZ7rjY8Ryo8gMIIMedh8EJ7XuPODB/+Quw0lxAjfwdzVJC6eXTAaFR4PTPrQvPHf8/DOCR58S42GspcGHoAMrlDrFfvn2ft3bMhnfOCibmfgBcM7xh2IuHYlKjhRm5vs22YFakro0EHrszvu5rRkiSc+4Nlv392RrixMZNZsE4GiqLFn89VIp6BZFlZpsEIUOnA+KviVLvWT+H7k+T2ZXp1VhzK57PaRTH757g5k5bRJm52/vKZWardgFYcROFj5Eh7Cpp3snK+wKHgZUlGmz0elNBRLDwqNhpnRxKToSi0T5BO/3m5N5xQX3ZfzAWXVyRE0LqgMah7icngeC8dRqnPI9Jarkn3PHxmmtwV76zBAzGMinTIdZvWaJ8dHqC31A+m7o9FqPhTogHG294/GOWnAGteLmWh8JLCiV0y1tZc9/MUTLoxkV8DnRpTUUeV62j9dXV8lNTkl+vuaSk2ylIQN5dH5zqML+mI2DRfVWlP6bKao8p9kzx2y5jU9eQi/NEaMUoLsixfmCnoHrb94Eeex0IbcuMyLF6tVzKnRrtIxF7N9dBzs8yjiw7vMvQxBy37kgrKvrwFNHgBNTDjuHNx0INi3Vk82skrjnFyKCirnTJa5HE+qAPTKsJx8BtsVgvY2Zj6zMADXjThSF1J7uZGoq6jtHB0nd36FcBLMoKXPuG5Op2RGzFVwfBqq/gMF1QkIT9zHsO5715nbKWhUXWMqx3Fh/wOAWBLsHFtYJxIY9JwvW6DnzBWC9LJ/BzJQ2edI4iwVH7Kd3LM88eNWxB67pW29OQy/2gZ7s4acTV+ZJchRbLiRADdgR4GYo6H4EGkvjAslaEkGhMcQCu4ZXAHKcJUsGwVsAq6WeJ/IuZy5QxfManEdEI8MZAS4/wQwpoeQz3SaFLKjgV3GtnlevWERByb3MxQFS7AumhnBQDC1EE7hQLRZNfZn1z28Yv/3/9VoSCkajf8H/nVI/0wgX9hlGPuBO3G7D4G/B/KWYNMFANL5Gl+hznq9XkP9f48lmobAwVc4AgSyRAaMOl9cBrBUGeaO64ZxP1PXB8QMUuoaDRcuhBkDTFFPLGH5YjKYh0NwxxI+cyN8poX3iHgeBvPxJOEABS3gmGQE/9UeR8YDeMgh+ojLpPI6O0jQoUFbSZelYDjETDiNaCIaI7jspAYfojES3KIeGMxAq8S1ZzIt/p5EGMZ5BB5oa19Y3fSFhX5jV0DVb9Tx2t1a1q2V5T721ZX9+t3dX2so0jKrttmdVtTcVpNCLDPQKTSHnNcM9xcfR7VXX8pAELfCqGyaZe7cgw7f6TtOsE6SdS7Gbtl63HvgCwm5kl2/bOZoVWcuBSZxl6UTE8dmFKzXDwWGqpZvYBAGkeeWLwwYRbQ0/Sgqn3fa1IS4g9K1qJ9q6buHE+55AnOeRF7pOq7P++oWqZjlWYkdfQ19Wzan9tCdTURYmhghp3J/5PEoEhUyzSvLNECDANp4WXIUPPQW/YlbPkM7WKbXIAsx5a7XDwajuVTuzmVrTjoaFq1aCvoJkLt/BwgPEeXfK1sximalBxdFs7KpzxG4DFxM3d/K76s7649F4AUVF82d3R+XLAoKq/kMlVIlK7g+pnFXwMyla4V8XD7VPSSHLldySYrXdRqgvIAla6YzXpWttiwZS/U7S7U36eBeqkCH9duBRoCuK26wwU0vWTyNdFm6moa4LVvBggYrWyWDw1OyogUUUq5GMWRA2frZSOCyNXNCgkpWTfnelqtV1lmrZGsZO33ZekljYsVa1SSUvFdQyZoT3u6rB2zZKmCyQF+TPknquDh0vksPWFaYnPT6MRx/2ZWEi6Pd74DQvKhUpewtC6UpfgxE5knZWmD0Ma64ZYkpVauPkWrwuEVGWr6VudBDdmeKMEtvwwMflS8rBtPhrKLYqypBOGjZGT2Iwax8UYnsRNa+Zt6NfZCFcwzISjGAX5f69aUeaKnWgcMjHcbP04wyhfQomapRMB7nqX0qvaNXP5zj53rV57LWG1R/NFeqmXk6V+vX3p91appndLXKBU/pSo3Qc7pqleSjer3a8LCuvklJE0n1B3bFmjnP7GotpB/b1WrTk7tandTDu1Ll9PO7UmXrEV6tXuIpXq1q+jleqXbmSV6tduZhXq06PM8r1+hWqpF8qlermniwV6x6f1ypQvx0r1Yt+YCvWBee8ZWq+BXZTtGDfoNGEmnr13raV6y8MtXjdh75m7aWfupXai+ZB2mtR3/VyqmELZUVABUrFgHNVlUGVKq3EglvXcVAxfpFkf3VVQRrCmdbVQ9UGkOBO+0aqoKKVQvNf5WVBtUqFqsOqrUjq03YVgasUbHanZ5SDFSrm/dEr9TCAx9VK594qq9TFR/sVSvOqlZQj3ddLfuChaeVdpFY5rGQqZnjaa0e/jZChB2rZb2xeRhySEDrRmIqs+bnr5aW4Av50tYS76uUp8cX04B6+NdrpJqoxfNON6Pl8sKmyGSAHsO1V912rwsQ4fXa1PVrr9on6Dts91Gvyfl4jMghtNrQGJaDivWXnVar3m7B3+0j8DyGT6165wR+OerC195LXbBVJ+/k9ssOfO70TuF796h3rAu36senbWyye9KBop3WS+ync/zyBP7udXvH2Nlx62ULftAz+CVvMTZbU1rLO7Hoj1zhOelgti9Z74LUyuWXlsJTvgigt3sznUUL7QcynASQOxhdLXzj3KIdWeq16dyLXCQfVBCZDm0miodow67gMzz3IcUsoBgk+6YGVNeWQntZp2q8Vq8KhNFZ1nYgo02mU3oSwyC4c8Uak3AEQOn0sVK9NhYBeFNyQpYr6AsyIgGVpenMEUNBDw4eToN0uFZlsvVy/J1zaNCay2Ch0tsMIJcvHHx3OvPQ/wnWYaxz7UIt7ELci3ABAEDjZbRZMD5QHQwWfZOqe8XJytmGovYViFyfz2aZhrOlrFzbqwub0IzCkknlyFpMGFlqCSa8ddbbayOLPW4dYZud1ily3qM2lc1htBl9zvpUGwNH9udh8cIRvSYIt9tq17utzhISJCLrD7WDimor7vIz9qgPaOjZA0tqVtafoHicee7QjRR1DCloZv320pgkazaTCQMozzDWjZMpzSnynT3XnaisRFXKWX7kiUfwRod/zj1ogeK1Ss3DEi5tw2oWgh2YG7v66aytIRRtj+BrnFni85/VI/hfCfBJB6hr5K4M4bXX1vIFtn/eOQGv84pfy/s3287zxdAXKxS2ApRHUQJB6BhoWuyMUWdSYYklflNxJxA/x6cYKDsfQgRkHaF1kMwJYk2uQgpfNjmL6peU2gSS7//FSV1hk+wqCKMngeXL9FIlTnKpI8rKLNWg2Y4Q4lqltzB7ltxPFSyCXzB6EbCAoZM6C8WYhw4MNE427xDGI/yRopWKma1/FFFqYf6UN8BaMSGbn4zd9bC5rnat22Jls8+H6ia3HP5+dfXOxLur4b4BfLVzaG6kMl5HfJCHuHr17vD63VWJgHi5Ogo+y9Zj4yam7aKIRqv7OYBERQhS6UPOgiggBlAGbN8QlhKXk9d1oThdrynb4Ax+XhlMf/Wuys0gc8PmYX/USshEBmuM68OZ6yBCSHU0nvPQkWwIhrKIDXnoqEBLSmuEuc0Bo1hCnCFzeMRh3TA9EsSE2gGvTaQN4L2YcHw+g5I9iF2cR7TysDgLxoeRe8+h/Cc6WHbEI30VhjuHQRAxQoUAVv/w8KD+arKPoxEgY2CvVkYOPV8cZNww4bOmitv9+o6ZjYa5Z/sQZ/vT9fUlgICMRu7woMneqs1+VbJj1miYL1IIie1dmQkSZAHEAFcaW5P9M5gzB0NUfUEXLSHF+rQNIkxEJKtq1JMmCwq1jUNSdawrhi9zyHMC1wGNVwO9sLdzz3vFtjl5CmitNPM9z0tOm07ygz156NEbNaQ7BhBc/I1HNFYQWTzBZUTTYfsEo3Ow1T3dxrQ4XHiuY2alOCzB63meJcbYLRF2sFVcZ1FVawGp7BPfdVrDRd0QkXicuQrH16EeKdJ7TnI+zIDM2k4ajF0fV9AbsH3QdsO/DtYPJj5qp4KJkU/uBEUtKEovfXd+b4JfJWv6WhJdyj8/B1QpDDwPs5mrk6KlnU9xNZ2kQCHURJh1EJO3gO+eOlOqNNsfLDB5EGzMTIRu4LhDhqppeYAdTAOpIKnizvROZgUbmaeEyxnjMpiwynEMlnd8Lrlbq0b7CwcwZ1DNNMEnNiNB/Ikvv6RpGMWtUlvcL4RHA8HLKshEPInseY15ghHaCazK7rbym8AkyX4tZphfSmHH/0ZYgTF7qqx5KtYMxyMm49YK1QpmFQZctU9zTyxnYCTyJYamTFOOjRZsSulvBU8EPUp8eA0DX6LPV46CWike4iKrMfPg3zwKchgAzH7KIwSW1qXwfpljcoRIhK68U7lC3ZlAlcuD6zkocsOve0G4Z2qqVEh6OcCsgrho8XKovkC7b33895x78A8/iPr4h/q3KpO7ZJkzsvSVRecU3gCzmbcgfZCebhTkbXTum8fmwGZRDR82uxjxcCzybAtG2ADEPpeSS2BZGIHduGoBl0lTwi9lbox56OnuU8MpoH1MQKZKwAIJmAyITgAsA5BjasjLPGtKeE+ZIdlON0kyj6nUIhO1p7UXVnLGQ/TNlocvoD291spUWP4lmghDyywNXPKUdkyy63dX7WYnYQbCXxCw588q061l/kmsaXzqEz9/d2JeZf1enk/kOuJfTjvPZv7REZuFGQbPQdcTwNli7WY3BqPMhU9W4J+6cCx1UdE/6xlc512lFz59+rq7g1fVp3j9M9fdSDjGQ6am5qwQlddStNdrv4VR6rDaAdNZQeHdFTunjJxn82iicyQlVKCrdNRsDmkLQIVDDdmanH3L2gbbf5C6bO3O4SbK9f/57o+9vYXJ429/2bGBNcME1mUH2aYy81g6/g3saGlMgyyMOGSXIxz2uBilR3HgSeg3HDFVWlMMhKwzCseV2hwTpNMLkXCO36CRoBhcck9qMEcr1xqswJcLaCM9rDI5mNTL4AC7//J37H+NZii27tAsXwNnIg//MqZtgScG5NY9YE4wnIMSJZ7/sqRuucv9nbExdjXhmGhZGRhy9xr3L3f7VrDBzNIaNpj6smOD60VAr8UFV4CklGRLZ1SNfaRqwJNQyydZqoMdH1qHD6XXd8eXnowvZU5AIZ/KlNzxrQ0hmZ6QkRWJd+fBdMobUkDiajszt6qu3kngdbpd9hPzDfUDgWp/g3wprcpfEnO7Ne/h63AuGvSwbFxcqsxcaS8xiyF90Lk4Cx3BrOOeN3D7kOd938QnGCajX8lmMquGuZ5jcG5XFVzAisDO8kMxpEpkQscCLEKuT6YcMFGlxrJ/dsen3NWbeKCt2tSHZA8CjdP6gNG5q+z+W7QA39Nt+RTkv7vZNsEgWO8+K27w2Zx9qWrWVgqWfOoHY18xDQSP2OsPV3BWwUNLOOlcIU12xiA1sst1VXnjR4uZTqWEH30RNlR1LIN2hPMPZ+/fwIzmK7m7cjGIp5hyr1V/qnGAMwJmaOMhGk2BsfjcsxbAstlmluHzp3eWiXj5vbfzGtiy1wAs/gzA4EIf7gQcBuNjGAC5ZA7VMdc2cga1dI0ppzw14FVIbsUjYNrx+uzvvdg7gLVBnJ5J4MEdVcoXwabGAst4GW+FYj8F+sLMdROp1Qh04JXxCbDyuIX2IYC/Su1AnP/unvsQ/IogfMr9K2dsPkP/AxiKzrM4l+qmJFGBfDhVC/HtDmbQGz+JG/IDGCUgSAio0rrz4Tq1tyLj8mAuFe0pSgHk74Q/BgNKp9fNIbXY96Hmy3bT2jggXdlJ/PKLdSi+xMzigY+2IgF/+fnsLZtyn4+Fg04gku3PQnFPmZJIwVsH81MowETjHJR5Fzzw0SHge4WA8XDoiTEfLg4Dz2kARK3qjODHDg+aNz44gw+5D0IQ+a3B4JSjlJ2yLjvUe5fHflorw/VgzWLKhL82EbVLLNzB00jeP5+9rSBnEyxw7mRgCjAYoH2KFFAnWhrbnQmPYBfgHCpngEfGBkE0YT++ucbzcvnx6jquCL+AdxVc1LQs4A4uvBmE5kUg7s4j5nqeGLuROwWrn4pOoJgM63edikzn1SK2agm7MHwzJF2aOw6AYsCVFAKvSvqoEjYGjiGOB3R9Hi4wu1aU7QCqhrRCVg4xQAxhAzHh924QYupEYo5QA2MS9gxk6h5+AA937XSPwgrIIGMV58PhGogmYgpjlfPB1I1AFDm7vD7/6YzJ+XAopKT4k+TrZyLcEINOAt+M33QMzG7EXUwJhokoKXhGpXZkMgpmM4iJ+HnC1etjKriPPDIVfbQn44mpDPT+wuyb8Qpy4BJLbO1AjPCZD1cjRznBNgjbXv9rutd3Win3+p/FgJ0B+al8Y2/dUDxwb5dmcjkf3L25yqO2rfPCiqs/23sqBfGeR+ZWzkCLVl3/V+SoyM/E4P35JRuELoRJ7tP/Nn+VoFKJAszvd+NrhEiZPA51CMMJ0Nvj9cf3FISk8jWeh8IhnBJgzwH+l3H/xnf9hkIKY2cXDAEb8ZL3+b07BsG1CdGRHrbzGEHWRMVMGoBIwgBO5sYfTgDKRzKYjN4pJf8ZT0aphXZvAdqhgYg4jtCF203x9RsfZXdsLcVjYFHe+NrLe8dZNGdJ0pzFZJIfdvxmPdTHtVhPXkvP5gCayBmRda/Gf3APYoQapIS5F2EIRzkYqUCjwdx3IFZQnTpgFwybg6ECx4DpgsFO8yYToyub6EWGEb2SidEIZEDMdppcE9QOgQT1TkD8oABIM61ZhuWglvckU/PG7mF9muyzf+dD4Cb+Au8/eeMjDx37QUjBinELFXjQja+ZEFvKg65hNS5xcXdsKM2GZmpdUkyIft6xoHXQYzdgQHY7pU2j1qFvxGcMpQV1yA2F3vhEoqM4R3Od3dSGnRmvT4ezBr00GqTmvqkd1JmchyM+FMYOpFnJja/kHQUsA8ABDWI5PIpCdzCHB/GZrzgFrfrQEzyk8pqH3fgysI4/YTiggDF3vajh+lmGspTZpnVLx/YSzwokPHwSkpFKvdGBinG6aFZW7y0j7l2q30GUGlKoNP4aAPi3hGdrjM7IMF1MBMVhzpYxjXuqGToOCfmSYvZhNxintrUjoXmS203YXO8Sgeap0rlxQNyxvgTrmyVZ3mzH6irhXa/J4ma/g2Sl82VlyVwMrugbPoKCmfAt/BTUZIHu0HJzstgEHPn4GBoNzYWPTyw8srrxuM36khbgYAGOLSGwDDjqj/B8RRNUhoE6DqQdYEwBC4WQcHzhpEvAtwW3KhKdpiTJPaI8BMWxRWjC9YtGxkYIlZFeklEk/NhiEAruIQWT7nLI9TqBpQc8Au5RsUZTG4PGdNxkb3PcWFioXXe+nHOfXaAQmWB+EfIvtXW/rKf3Oj49Oj5unHO/cdGYS3Bf0ZUa0EEjnmwjrR1Tv+94ZoJnSrMqFufUP+74Z3X4/zW5aLKVZ+OlGD240pzGh8NgnmdVv0btOn6MRzYQXgDohIm48gqGugsTbLuUeFudrmi3eqMjMRSjE+6cDnm3zU+6LztOa9jtdZNCY7eTb/HKT68I80IjqlpxNcflp+kN/YudqQX5AE2jeVeL7PmHCDqLD9IsDIIR9Bs8+CKUE3eGx4kMOcIxVwwuNR40DgI34Sxsctg6163Wq1a72mGjjHFyPhq5j4UObOQpEDuxoZeEtlXzmXhs3vgvroXP/UiS4uI88EfueE5IRi+WL/vQ8VN3BxysIUBoFiy4eR6YNVSlt82rMsuVSVGfSwzoInPPPbaPUgj4zsgDshKiEsdqhTDzEPUJNDD7oHZGJDZoYyzCA7i8kLiojMP2fTHmySIKCerG1xhtF6NsHxMOUQL3aP2z9ef/P3tv3t02juwNfxUe3T86uY+ocNXiu5zjtp0eTyeOx3a673QnLw2SoMQ2RapJyramT777e6oAcBNJkbKcXsbP0hOLQAEoFIBCoepXuPGzTdVPJKXAQoZIV+QWQ5Pvdpx9zU1gSVNSF4SRElSziA16Wk2KlSY/JDdsQFW4EULH3TFAW0NB5xrEyelFvVYgBiyWHa4dqxBCav26juoGcYGTAPvJCVtvZcRH0R9QZwBDrNA6F49i6yqIcJjsObjTi+tOg/Oideiy1IFuXXBMsR30V2O65dusWueWMC8dvNXv5l7ubMFj7ruyTFGgoYWfwPu7JbbxllEtEMKPhpIXkPmc804QaB+WwChKUroqnOo13dLwXGrV7bZ3SdxHnkuv29oVmk/mAlLdSLqksfTz1dsTSVV0s+CjQ1KSxsS5o/HIp6k3iuL5Gzdy3izSZfAm9hwo/h8JuynJ2kgfGa8zGxYRjpeoA3BVn7mwaaYO96GYOCmNkyETPcSJSegcd8tXnwYBsWnwafAarw300aEU8cDGxarth1rZNarqWNWkyDR7jWUKjYAVK8IaJgAwyGyLO5NI1fl9tfl52ZE9Cqt+UpidISA1H+puO8IqBrsBZuHZGh24xMIXgRSJilTkScmDnzJg8zQqOsm2sh7UtpMFJasy402lgzqUdbV9Nj4IO19pSrjPyDK6b+vxk2cEPO9EPzlHCx54dV8+9xl5DCmw05jUuM1eiU8Z9iRfyYeYtu+iU+K6my5KK2rW9WsEPxXvWV2vMB3CSXONpnF3uyjcObAr3W4cH2Kc5HpHchgWfMnuFO00o3hOwizT5Bc8JcFa1G2QvCzUAucxZsPa7tM79IyUCmVyV1vmNckczZYUQY3hElQfMbW1GvKB/AcEK9H4CKa/bknkrp1CUIqOheIrnA5LmiRkjpEvoOxmBzRPMIqPneLSl/c4GSEbAlJzth6zoBpwect+ro5wu38VLZOEFq9v10z7dYoans+EqdQQP9CyW2k3pYI92ToNip9Lw2jph0z/4hIs7nztAvfx+pTtUCwuINhY3Lm05lLgsevGT1z7E16ogIwbMtBrkEwSbroNycOHodox/S164KbS0u3VTyQbHP1q1Z98TMsoTBfBJgfQ7Ls9+Ek+tzWMaJncLUNAy/jZUrNcP2mw73DPSr4kRbnMzRWfD/l89Gqx1j87b6hoeoEF1M5sL6b0ubbUVQy5mGqlYwkm8qpwrMimrKVvX4JVZTSbwb66e7u5BLRrmrlj3DJRefMb/I/lu1/eFGf+Vjq+PP8EzmnrFWI/kyJa0kg6EU8HhRs7vkgy48cbBx42g08hSZLI8fExukgeXiIi6d6nD4XUoxgmUHF++xQCIPnPuEYv4XsXx3my8t9AEkYWnsuGmazt/Cds6c3r7eMYrzvN0KbMVsp918PO2kQGWypsp37og9ceQkGACsAgfgfDvOQy4gkkt/SNFE1b9f1DpPzimUsCaR36KfNEzl8UcqOq9Eo8zhCJUcaQhgIJ5NLzKSlV4yiz3D3JRlozqWxoFvCiwUq2hNxuIOgrgpb9PbmIGeFKvEzWtvwM/KwdJVfZOsQ+Qkl83nj2ICHpzxsjdE9jZtwC69EdrTnYfyiUkO7ohplXiiGTLAayVYy1qaEbhjGbyaoyNTRN1czZtg2j7imIs2HLECxuJcPssYWbJSs3+6Y7Zu0NrObuXLKMly1AlXcKrruW34qyzNSW8H22nCgImBll90MSjeMo7giZy4/BZIAGWv7v3jV5DEnz4y7sYMeX5xIEyKKVK4866WJCjGmC0vdb4yog4eaDh3C/u3uuxGnaMfE4eiA51LVcN0o61mEJyDA4ySIgJV3bCh7IBs2+ftg1MTqvs06ohce/rHWtuE4juAU5rJ4VU8ifTrsTsOMoDfzuhcu5yvs0kyf27lyrkBC5ex0R2IRpfDvW8VcL2Bc6lmbhCRbDtkt5Du0O9XAP8gKI+A1Fvu/d1bZ2v27VKImDjbXww7TruMoZkDszfCuVcOeaC81axT4kZclMKN3qgciGkB88Svlm2rFimq46dy5NV3rHsmXws66VSumJOzPNX92POxZdkkdrvYI8w10r+CGCUAqPya61YjKnnQcQ0q7LMkJfp3XoJ7DB5bnPOjdVJhCF3ccUYZ5vK434vzpXw1RoeHJb+GAGHm1WuojX/TY9fu5wegsN55IBKe1zfnE6QATkuucEr9CftvMAVuDcljoL+EcP4VvFsIQwp0nXCv492EeAxZ2rRI8bCzRPC+zn0bqrArFK6NqNYPEZHWtAtrkYIuQwMSLxLUTS6L49cHup5Ycs/431S9dBZsqmvQZvbEDY6jp1pdTknWvxv+RcGVkFJIULjVUEfO1KjZLYWTCuQWRf12Fn+dA5QlDPWv20jLoE5x1rFrNbd6zSmiC3I42kx+AqKYa61SrlbehTpespW8Wm7lirAuW6V60tYMWuVOrBy7rVZpAMHcuWIyd7VWKRTp2rrLoXFa6xXz5/qd7vxVVzKK65hXtr0y0agoQDOCQwQKV8XXyOhF41NqhqQ5kHapctA4dRcH2tEIdhnwEzrvgG3sdEsE+2HWzslKRksDU9nHDWJSy1szuZMf63bVOVwz34Km428LZYRH0EfKva+sy2vbsPqwg9AmtoVAf5mTk18Xc4C14Ud5PP3n6qTxYVm2uUgsdC5hHFLB95imEuw/BswPLlVT3HVmU+NjQj/LQRJIQHOPAhFcLjeONbTVCmo+5u5mJrHCtImYsRXbXkNfDjSoEHVi+GCfK5TVUEfgCUCNMMwP5IloC3UmlSUWom2A0TzGQXu4mV/7tunoviX/QM+Yzp2JzYxxdbhnDGZWKDFvmjgTA3d7NeFbt0fMX6s2tLLdU5Pt6nGmLW7VHv/f/tUenieo9KHy7PLi6/u/z+7J97VL68udqj1s3/3ezDyv0m4Oxqn8ZOL67348jpPnOAWX73qPfuw8k+YnK837Rdvz9/f7bPHFxf/bBPreu/vb3cp94PJ9/uI5TvrvcZ28erc1ELdr5onc4jUDh2vvgyZRdyt2awZURaxf6SxJuqX1crzCB7/gWXss8YyAEanuW7qwbUzqKzFXv7SzcinUiML+gZrBZLVF3I5AV4XvA0lZUf5jF1EEX2c/Z8XkaV7vK+nv8pRyF9I7r2xndXMuotLNSi9MBeC9tGwciw8svwbYUfyb/WMT0+BdBPsoQXFIeGaex7oMFBzLkdRXeD4WDup4u1Df+IonlAZbJaJdlf4B7qh3fgNAtPWL7rwP/c4WNYFNIgmuOHlR/OWfKzDQld+giNZcNksWtkDs8IlATpgtnpO0wbK46lMShzHQ7R02sjYbhkAejSLWWq8hPpFsvdtvNQ6PrFOC2sV2Cp+FuUbYDrW4dwqrvcWmHF1LPG45nt2bY6dpSZqhNvokwmju6oM8OzPcdVGt7Ss2fqzHeLMA/MljCz5uUyuCexD9E8OAvwHgkv8lbq05i67Jb/dfqROpZoHbvCngJiiraOr9OFcpOf62fNGWuKQvWJY5hTQojuGBodU9OezWa2Y6iz+q6yy7zoJr7nF3qfgBbNAR6uCbkuBvi2S6hfBDBif8CDSFPndYN6CnEnOhnrju5NxtRVJwpxHaJO1ZleI3IfOBhrezf+t9CL/x4MB//9P4Mh/vi/8I//+Z+m/hjqdGq6rjG2Z1TRZoZmGo4x0xWTaBN9PFWb+oNzvElSutzh3EecYrisH7rRQ8L2rPUjujg4PRbsjMxmuklmZDJRZuOJbY8Vg1BDJVOVGhqt6e072OVh1u9J4POIlzTCEIWkGIksvC5G0ilzsy6Uf+Xev5aW6yQV1dqH7N4XRuze9xieZpt0YpqGYhDD9tzJdKZpM9Whs4ljzMbTJwUyt8ICl9adhSAlg4ZVyb82iBOltutMx1OHTrwJoTONarqhTx1Cpgad2Ga9dyB3LU0F/H6QLiR2pvgADxo2nSBL391xfgTRQ+nsWJaWK/vKflv480XTVMWalfir1cYSysa2daFwHGk9ZnwyJa6tT0xPGTtj1xhrrjvT7NmMatTxTLVmO+DiCY/QcRSUxPT05IfX0pKmi8htku5WZoFmVBgI/zN9TPNNrfPA1DFxiDmxXarNxrqmqM6Ejul0Zhr62FGdmpV6LK1t/9e1nwJyKoPzQu9xlAl/voBM2Ks4sontB6AoRp5kU9iGmBsTdSUIuNw8LGgMoIL3NARXZ2Z9TXg+yWidumgaiWJpHa4TwAtOY1jZSRrFAAV2HLIkdSQQfUA8HvQcXkRxivm4FxiHEbpSSB/gB7Q4cQc7pMGijr0odqggw3uZCPRVPxxK9jqV3IgmGPqELtkP4CuGfkYbyd/hHpizqyTipZ8zgO3ij3yALAbNoT1mdTrxyIyaHp15Y3vqjpWJTVXXMye6obgzdVwzq8KzTqSvATvrOhQ+ZfCEHzkA7SggRgpxkO+OLxKMrw2jQkEEhmDr0B0C2co33tComELCAUFeu/Bf31muCugCuYExd05qsrGWs5GDOXOiKPowN3sOLiIpjtYZ3BTAoJ9jnvGlHwpPPrUdKoEQspc3V7Xes/lyoXd6xlsGu9HLuj9sNtt38ng7FId2e6PtooZrRg6ieYL2/ALLd7jC1b4s7Gxt5cvibVeGZQRPqk06sqqZrm46tj3xZjoh9mw6c1x1ZruTsUHdcRdDN7yHpLvYkK7DkAYWSr0l6hQgBUhXCoUKtVgAAe1FrlChMYi+87h8DNLiaf861vRXlqgAs81/7NpuXh78dP04XYMPK6PXnUpNRRC9ip2mTo2bGmPV0Q3dnSieobm66Y7d8dRTiTl1FbPDUxBOJzOWt3WUpaDgDlSiDgQb+QEVDvWd62eVOs1wqWrZlV9AHHSuvuToB4N8H7z25yF1AVq+F6Xt2jBD6MS1+z2zRCmrhH7w3MTQh0BWqZvMuIqmzkyXTlzietpkqqjTienpY8d1PaITfbfM8Ab36aTlUg+jTjAOc6u7QTRfrRPMqAzaMrUyvJi6XlVjYreefH139x5fm52hgXPqVJtOp7Y+hr16MjbdmUNNQj2iK8qMzjqsthynYufWECRyoXgik9CVxf0gKaJkyGMWYoBwKRz14AmUc0Ky2W2F7iAo/mWRaFVC96hGByZrunMj2tEWJwKHPI192FLZM+bTqJZpAXF/HmIyuqcSzuiUIr6eQhGJyLPidvR0mShQkvWO+4wK92VN91xbIdScKmPHnVJlrBkzjRB73EW1YR452ZVph/cGjSMZL4nynKT0gWy4S48sCPRSd2rIoT8iuE2hU2KSkuWqVgcKwRkckFm5w8Iq6aAK1LQHj0YFQrK/SmTflTH2u7ad+7GFCT32bq6FHjqALCCAl8Ve7dFAXhcEyEky97r+pKiTyLlz3oCGLvqT7I6lqSGV1e0W2LxNYb32XVgWwwE7p3pW91es6r1RZH9NfPQiemDRw/zJr1BaOr+8N0S2HIaqhSWJHxczutSLJg+U83wauICd6cog5O1GDXWijcbGSB+P1K01UI4CzrIYycJkwC1DmBZuuVqnTPepMsACaNF1DRByxgdW4A/CBu1AbADfb4iI6S9HS/Ios1iaQReVvIYCVENXRnGH2mc94Txm9fEYcp95z+10HhFCzLFCHOI6tqcSqrrOWJ3ZRKXEnBnTLoiRTK52jaLw1goRbawOnD34Vsue7voRKddEJz30NocgbQuSQvUkt1W7QpIbSHabahrJ5hS2YAs702s/ZItbQg+ixXpwfyV+sMaABpL0pFSp+mWIhniLre5elIr1Op1BpdoVLZrDLPYjISptw6cdZra67EclasI8ENM09nvKoajTWaUu1eZV0EyYACLC7ut8uX5WC8xJzl4CUaiGiQJZBEzf2WBRM52i8ct10Uuy056qaTNHNWfmxLSd8ZTMHE31TKKOVXOszRyvVsdvv7V33yseiA9vqHEULduFj+NKYpgXAOX1IQzPU6m1RaHfBrRNsLIL8eyYFsdHh/AqSHO3B90GQjCZWICGLKKqP+msZkYrSUmc7kmtULfTjrdNgV1JeuxWneWly2a13R+xY4X0AeLD48QCv+2lH65323pqqNVRQegeeIFf0ycxv47Il+EAfwNHRPY03Z9ulQBaYZgguhz2eA9JqVIAqou15wXUImlRnPagXU+nz95fQ7R0AKBvPYPTYRPan2ANDXypiMMk9aH3zn6c3aJQoiqQnPelyULgt0+RxPGXhTNx2wHMKcJkC08ZFpGBET/gH0Cka/RpYvjCcZQkMve3OBf+qe8RRo2Bl16fnL9/zVBN08wbrujDuhMPsTHv4jEi2oKr0nayY2g2e2FuazQ3TWe2Lv56W+MN1PdSibGd6CyIOy3rhcUuZZbIS1bjsRS6HE8ZrtuEDQYnmUNxAVQT4hlmI8t8WSAQ2dlIFDyAmGue9DGh0qdBFnn6aYDIrOJPQMjLEb6A6jdJTheTEK8ZEK2fsnnEW3rhio/dw+4IeC3RZkwhCpE1yDw9YgohsAugzt0bolCax9F6VcRm5KMcVgfJeokgY4grFDkOJID3IBty/jS/3chI+hE6XugQpwnOJkgOvEtEbvku4+P0wogv4AaSNuUZ5xBTkBHiM4juMRvpgTAm4+ZSqriKo+UqZUm1WL/5gGpdlHLnlqxPBe+ObLbZoQuhocNCwfq88k+SdtxrAINTRKtt7zbwFRJLI5h4MUUy8ukHbaSg84UwEtaNetvqs+2jk1ACWh+u/aTWupdvJDEF1LV8HUBdmKmfaBxJN+gF9cBhrDcI1s2AOwvUIQkiw3jMtsPLzF2fWbl4hnabCtB7aY1MxkaLPQUHPhIkYn+rx9V87m0roU5MayDTjnM7nZRGdzSU5jSkLOmc4BGbyUI8AIxIDFrszp4f81wVPDd6IsXUJZicAk6htZ1w10eRGh3KeZAJRwqihKeKgb/Y6qFiyXgxTRawa5FUesMiLbJAhcxNMXlz5Lur89M3vLyFgssG3U3iEhqyHAm5V1hlHjscXTG9j+7Y8ZqJXsJkIARwOwGX9h2zzT1FCr++EDW86WrU0JSZoXn2ZOK4muNqNtEdMrFNT9eo2sEq2OPGSm39YFYtJFa9R4YJxJh0q8rLdrt+QY2K70WPm9fOcXe6cgEVccvqZtjBKrlBJyXxnO6+JmBvWdFuVhCTjtXpVNenik616di1Z5ROnIk+0Sbe1J7WeFteY1TUBhLG8BzaGAMMUUWYqxZf3Trk5GCVO41IoGFBQxY2JH7qZ6I9vBDX9Kwi17+/gHYxojUNpoc9TTFNQjx9pk5tT5t5U9VRZq4+M8h0bKhTrQ4RW0gSxx4V96XdwoMXSkRUiXZaJ2seZkR1cKuURassuBo+xLtXZx3RMPVlrFwiyR6hRQx8T5pYWYbKZZqRu7ESUIPgTN2DbORuZFG/TJlj6PlJFHQyetRRZzTkjEaphR5uRHVeEQXXoRLVrfw7+xBHInJTGwCIDrYRjka3JCwnwj7P9pySjJTkjBI6Ja72ET6oVuos+L9YCQUg0N0ekjUEob4s6pco+yHExe4pG3nlEk3+cAxq4z6j56/HMlZHSyNz1ufZffbrqiAi50Tg8Caha0eP+3iQ8JqwIwfwmIdQc3sQAn+nnHkNuqFqKo5pmlSbeKbu2rahOK5DDXc8NgzPUzp418KV18qUepb0bFdvWTESb2RwU6ilIB6TaTdjfpmiMPeKI39/CruP5XK9hvN5/w50URvLNYX+uKIdTLHlqqwKItwQ7hHYj0ChXkdtgKqm5ujUcEzTnhLFIWNTV83JlBiaY46NDneTP72UQHouSwAfxC/S0iwt+sRUJvrMm0w023Y9xbYVxR2PdcNxHGWsq7ulhXoexVeGj3XYTtUIxKM3bwqo5W/wdN8Jc9UVh6oSpyQKbmebRadxJ1Ozmrt8eTPIwvbbS0JsQvmO2Vz2PLyMo7nw8OkeWMRe9dtpa4qmy4opK/qNOjlSzCPFGE0N/Sf0qeo/Q1htXXKJr2uUUnM8dRXZ9iaKbEy1iWzPNE22J8p06iieYo49FuuS+MLc0sr2tR34ztaEYkfYMDJGD+vC0Xi+vUJzhQnP5nNYlt2GFTKZamNNUyC3pjs1dFOziaoqU3dG3emUmmbdCslG8tvg+OL06sP5KXR/Nhlp0+lsigIp7o0JfGGTNpWV6Y2qHKnmkaL8hP0hruszW9RlOemCWBpV41y4XtLYdyTG1HIiZ1WpS/5UWnRfqqu72M/mBVqb7XALoK08mQXKTZw3bUIniuNpUzq2HerpY8OeTQ3FtXXbpfbuvemAveepq1sJPXUyWliUNd/Aq5miaNrEoO7EsSee7jrmeGJoKtVVU5sRvYPWCU6wzzq4ITQxfuYmvoq8Dhmz+IAaZsQmxJm5E5eomktNnc5mqqF5U+q4+myqUXP7YKOhe+PXpZk5dn9ZI5wgDV3MYwJviYhcvVfqUU2TlZmsTmCv0bQjczIyTfMnfnjF6Y4+YJnD9WJc7UU12Djr0jBjUF36eO5VYKFbAb+k9Xck4/DEFNJDQcgieQhobNkbRKHu4dfQSmdriG2FP3fR4ozxWFNdwzVtuGU6hFDTmanjiT2l2nQ6rj2jygOPGO4LuLXv1LzBSgnw64Ua1SGVPnYawlhTHaJ7Y0pmZDY2tIkzUzRbcVVDm8w8b7p7CPwlyEpAxjqYhxASS851BHkZLi34/+xlyNqi1/E2sItu5qUK0cex1cHstItigRKuhHgFeSV8Z7cL7C7KJVrVSc4S+FT4VBpapT/dZMGdkMmUOI7jORNTJ1M601VbdQw60ewxGW9vnSUFtS73tGkWZq9Z8byhziKMgmi+YZr5CvOhpHQexSJVXxXitjG1Ud0uVXdyz2wyMWwyVjSAJ5tOHKLorkGnquM56rgWzXTbXsSQ2YkLOUv8hHYJ7m+ce0wD3kQUTNUkdB98N11A6gOaLKJg55bR3lYdQXgS6uj+10686AK4e2+rpYV06vPB7d+vzExAEJX/QKzcosbcPz3/kZnNn0i9SCmj/IRthnF2ZWWEOr6atRMUiL3/SpwoBr9m5ubAr537062hl7fS7Z24UwOFd+TtDM71WdQyBg4bt4Mc8bgDRMREGbsmnerjiTk2TMOg2mymEm+qUdtWJl0hIjq9ozJ1opSL7Smvw4xc77dgVg0fYJmT+J0fdqyEJfu9HbOK5ZRze/k3MEKZG/l6aXXCt+HVsuK8LoKs0tDBLBR+kHYwYOaU6iq3Jf5DthX73NyHllR9ncSZzFRPsd2JRqmh656iKpQ6nuvMDMfxtFkH5bIszluYS8xj6Xu6QW+46+t3iLnEK+11PVINWVFlRb1RzCNNQYNQN6fBjtkRduE5ZLkm8EHzidSQxCFQIe4Yh1sAISqLsONMwYOBJKp+3fnqssp3cCV/cWhJNH+cpyou5JoXroxFhojfHJ5/gDsQowcjy5pMJb+MDbplYdkJUFnOb/ofSRKI9PT4b+r6aW0G4S6h/zvYJeL/DwmdoQ0yHKgDiTgn1raD8jSmOJ6CQVys3bJAPHUPtb0Z1YjteKo9mZKxQ+wpHVNtRjVNmxJV3b6UFSA4mkHquNe/z6ATBQqoEMHtTMribaTTbuL6cz8lgUwfVzT2aehQeRmFfhphniV8Tmi8FrbnrGUj63jFczWijt0JpSpxdTKdTl3XnGqqM1Onrql6Ha54Wdrgp+/D3TG0doEJMc+fDKinvA8nyVMXAlCASSBB0CHvRqfO5uP/XDO52ddO62Giu3Rqj3XDto3peDyhGqyKsWOOlanimF1eTuG5qt0ecRGl0ttoHbqjLXlktZsQAs2pOfVUb6aOyUxTp8aYKvZYNWfEMyYKmXSwppGUWPXPjSzqL940f2bBZ9kD+A6TSd5UiXCZTBNe0Jia5swxTKKrrm0aU4VqqmfTmWLY4KXd3wRcSWVUMykfr5t3jVK50AeD+XUK8rg1aoflumYCxwArWWI/kaqotVu5jWvph/4ShFWFHDnD1jRNv1cyJjHYxhd5mFv/1zU9Z/pDC0atTlTDNaczOgFA+Jmi2jPHcaYTRTNVV5nVMA7hnE7gGIk3x8FqQbT2aWNv/qVqFzvn+hJSkc5Z3EmWNmz3e1YLRoyyLTE1I6nrqOhBx9PJUDWDaJoBAHWKqk2ciUc0xzANXVNnE1NrYunx9UW70VXXDD3j5PH1bia+P/vw/PyDblc61ZNh6pQ6mqpPVcPWVc9U6XhCJqbueLZCHd31thnGgtVu6hNuRFHAQySh8U7o7sK72Q/nN7E/n/N9tgKOzxOEiZJSyotK56fJ03R32Ep4zrhym2f3LGHZBpDftr3J0c027tRrVu6Afcadku8valU0ChNUw9qtXvPhd5QX3SGUehOF6FOiE3c8Gxuq7kzc2cSdOfqsg0cehICtUshTuc2wD1hFQmR06Y5uGE52QML5GlK4wc5b69ff5FrSafbxeSheWsuN5Swi8dL0B+hYTIHKH4ZTW2KWzWOpq7UMbdB4pqbuqOaEuPp4pqjKbGZS3bTpWDWoohu6t1ua3h6fvzvE9jocXHy4ODsMpcvj6+tn2PKxg5z6kA286c0RYq9cY2Jo5hgut8pMmXkT1VanmkanU6c7W5/Ru0Xw+xmbEBPxtXycus/Q1NanOij27syzFc3UVM2cUG/mOJOJq8063GmEi9PTxVV4Mh1YXDu4FSmaacwm9oSOdX0yc3R1Bik4xrapTsfUMDvI6SqKgpqpfM8MI9SVoACct9KSrFYsJDldUB9BBFbMXxJTLNVulgXXR2I/BOHK/MX+NTRM6swfXUWnsT1PH9Nfia+4YAm6OH4vQfpZyI2G2uM9nS5mQez4KzM0bXtOZptfl+5Dok3JxnSVAJSMs4/FOi1uktuR+zg2zA9FkiRyfBb0LTA++Mi76WDs/fPepw9dfGYi4so2CQh72CjaSuoArYlrscKQxTWKgt2z2gsnsNKbbaTA7o93ZUqHCvGskOU/y/UIWF1AIpsIFijU9LjjW0qFePHthCXcYzfqvtNSqdztGbN+nNXwiNRP17uReirEsmpCRJMFdd0OnlZVOqW6SCyc79WhrN6XzA6SJXHvR6pau+dzbo9VwA3QffvHamUAZuwvhJ/ZkxLWtcoW8B5kcuSybpiv1eoFqNcw4lZbMEqxVFQ9iW0TqJJlL8lPocspQO5VlBErSSmN+0t/tXZGsC8LM1HtFOgzMwxjopsOGSsTVXNtx5sSz53qGrXNiTru4NFBs+OvvZuYUC6Lk7Syatn+9fyZJjmPV7/y5KfdV3Kl82UPjYqlgnDwFwbjwuvgc/JhX5JHqqYb5k81lusu78sN1rQfMM8e5/YH5Jd0GSWp9I81CdP1UjoLMUwWgFyue01CjufEsdZpMSvfCv07Yvyt+D3yvMFWpil8lmEDGObyNyz+jrE0KbKuMAp5exSFlQtBzwife09jgXLzV5P9rTG+LITuC+E9eZQgV7r0A2NezxUgpgLM82ovqd6W5mpXmryI1SmdzAxtOiHjiW3SqalqY6pA8JQ7I7MOEQBgEGu7+LcJSylpDxL60jEVFVXpZEZdx9Z0w1UNx3BdbTyeThVP81yt5rb+9+sPFzINwVjnSiIzk0TsaM0SjIqkI9KKxClDnvoxiu9oXIaI3I10glAfK44QWu4DPBoIiYESArFquQ5SH3/g3jJSuiAZOh/PM4l0pFd0NB9xELGAQvIBBqEF7nQARibSFd96NHUWt+yB4PVIygEWiXQLKVt9h0oPbIDJJkzJ4y0fb7vxgVUZ/cJBIGDDiNx1ULM+njJYBNdkhKsjpo+w9bNBi0EuCCTTjKvD5AT2HB4IIqTPtYRz9S5Pi1Kp5lBcKGghgGP7oxaL7VRlXb1RzSNzfKSPf2JoHk6wdmme36TGpoydL9zddvb+6U4dBcc68CXfYamow7XSNXdqzybjqeHMFF1zXX1sEzoljutS26tJEnwK2b147lRwg+aommkkPSx8Z1HyRfvx+C0rY1O4/XVALOoCE+3JSwR+dWWgDUkJRCG5/gbdDe25Spbdmb7UXAprs/SNKbWnhj2hM01zdBPeFxVdJWMdLNP2Nh9PRHJVKYjm84IGwXFwibNgvKu8MzZ5gNR5Ee5o4/TiGl7uAD48gBZ6w0OhuxeiQzEQPgapA7mK+3YFDs038J/n6FFQczLt6M8Fu/EevDMNMDTglzSmujpVFNtRNGXiKFOdeB6Eo2qTSQeFoMPettlsmp6nqRfFO577Hx8fG1/N6hwQTU+3XXVqKMZMsR1jOvE86k0NczyZKhO7Luk0oJUy9M46ay9LEcsPpmidwiNgFLNUzbhG4NjjB2+tf9R15ihT2dBAJWFmO5x6kvUjqT22uLp4/O7dYDg4Pre+/XBzzf713fHN2Y/H/xwMB99+dwn/ZV9OPlxcnJ3cnH+4sI4vPrw/fgclTm4Gw8HpxTX7r/X++LuL85uPp2f87+NrVQWF9PQDlDh7f3z+zrr68PHm/OK77O/rs5OPV+c3QO3tj/gf6xK+wjLi/2OdfLi4ufrwLvvz6vjHd2dX1tXZ27Orsyvx84er8+/OsS/n/zgfDAfvzo6/Pzu1Tq7OTs8ubs6P38GnizPo8tUHGJV183/wx/Xl2dnpYDj48cPV92dX19bxOV5cKqbjZpk6QQ9nZ41qyk0UzjFrJw3dU45M1uEWInIV1PtrnGWuGn3m9ruzi7OrY+Dah483x9+xJ68rYIR1efXh72wy4cfzy7N35/gkdnN1/Pbt+Uk2w58x3eF5mKQkTElIo3VL/mfmUAIovBLkRgevb/DWQuUNbmrQc/avagR3wcEWoD6p24DrkjFuHftZ7Hg/Lqdk3nrlyKf12w831sk79ka440GxsDCL81iWoWJ3c/Eojnib113dqSamTulUnUxmrkLNiTqdGZqiTGbEJvaYYcO6PnRlCZnEmCUYXtq4KVHg/PYDTHvcyAJtWs4osNRye5NZFeBAuAvcQMQ6FfXAYsrv/lBvW00+mYgYflP67LE605XZZGK4yoQ645lieCrVTcMcK+5Y0aZtIllebR9DQK/v6LG1JI/c/Ujpokd7qqPYZOoZxlhRPc21NapM7Jk+m9hjx9CVfe/qRZgCDDrkmdI7KfcTxdOcseO4U2Iopm5OiTOh3tRzdHc8MVVnV+OoB9M0sa7WAX3H1CR2r2BLnT1llk1P+Cf0ksb31HICSmJU0DEF+IDl7GWGHYEk9fPnYt74nz8Xs8FjRppE3MtURVa0G1U7Usr2Jbg0DGoaFhvHNgmlSgLCMfBEyrpaxHrKHKl2jxUM2QIuqu9oDziO81Be1aFW9RhJGKWWB97s9eMQTs6qamgFP+bBRwY0jsjokKTrnplIK9QzuyMShrSMVIJ7f/a7G9EEMxTQR/AxtKlD1glF+PWQ3tMY4qLgnKKuRKQTaEC6Yg1IJ9hABmoxwviBep7D4ilwB1HJO7KHOYRR13JibqBt45FZ4tHNOg6lyPMqHU82oQOMW8WRQ4Xu69KAPsswXBqCiRhHw0+z1hHoxRGUO76daUDMF8n6z5IMwF16A3qNkM6DDwueJnpvMxWT8PZCzGzAR/j20XtJNUnIwToVdumTu14uNxY2bokIhh3zDhtLceKvoyWVsJgkfnzyBPJHEAdyc3DHFouLioXLv2ErLWxBZv0WxFxjpJA+SOKVEcHqSm1lTzfbu5AQWNaLA8hq3VBtAGiwcJ1QlqcxJIGVxRu1jlutHzcj1mnM57xBNqlfY4jcAl0Y288DdaaNlJGGmYY1RVGPXHt6dKTiNao//TbJ7rvimnlYicvEk3ksK2A/zpSUnwaFpyxIJ4rXns+cjRSzj/38G29ExgtAkRUCy3KwTmRKklRW0ekudEE0BuQhQQ28WLvIvHJ9cMCLSVCiMHdWoHh32Dqaub7C//aUW6Vebnnmpd1yK/SGryi9bJw1wvvbYM9523/C9uj2y5r4KmvCD+9J4LsWSxPfugbGxTVwzuqBqQeDwMM5XwXS+aXIdv5M4i26zDhg5fi5rergpKTQLqjEqovcdy5q8OE3QoHnIeJ8FZcKFdR8EUmeYMoLyOOOPeW0n2f4h7vndN+2dlx3nmmi+f/gbHP3uy6btVkS1Le4YGHcnE42qWQO76LpV5gyvglbsNiLnd9nr+jXImwOWy3usb90a5UZg/9we3an0k/YvvfcetMospYkhDwXaJ/deWsYG0XBfk8ewakYokJs5t51fikJUpk/Ck8oB4v3mVbpvfbs6vJ2E3tqB7tOb+tJp7f1FAVpHwnK+LJap/Wa3u8+rP6jeJlazhQm7L0ZUT/c/bsh1K0VmcOTUgddq6wp8vpgAMV8WeDnRZY0pfFQWq7RVirZNH2AVI0qutSpivJsW9W/ufIIHFhZSz/J8Dq7TyT4LEqZdOWjQVKQsPbZugx+iz3Xwc+9jv19N4e2JvS6JvbZQcSgMuwW9NMZHGkA7wozoyIWF09GpykC2iYvxqFuGJfU/bcClkFwuWJQp31mo3EQSrdBKJVBKPsP4t/n/nSvNd48niD2ndve8zbw7Mt2X8H5a+jryV4L+MmXNNZhoZjuqRUl+5wEz32/7HfS7Gsf7N3E8+qqCw1jgJI0pmSZWKZy0EkpU89ZbfbY9qshSpZ20C5uRUDlb5talz0mi04rC3h/bd+GgAggAwAzoqdsXpmj7QPblJhTeUnI1is4cVMf0hBEQYTJos6PwUHy7McruJsXaz3QJJW1hlrXZ8eDz7Bbob2p1FpB2upqfrg6hZrNNhSWbpJzHTJs3tFHK4us3/+dQATf88zuOLc1TdVsBo2RY/3GwHtwgCEUpPPrjqDPw7yizEqnIX808HwauNI3fCzfgKsFBGFJcNloOf+efwLLRyp3RcjR79ereUxcGh9CFOu2mSQJCq0tOcJh14HkmxGDJm2Z2MaBPV0+n2NcIX1M0WcQorZczJadVdHaWQHN7mRET5me1r2JXV+/e3Pz7lqieZBzKTyQ3QqGUhQGGwl6BQYDNlESA/ECf74/kMRkayEG0BB/Se/81Dolmwc/oQBAmlyzklcFtiXr5ZLEGwxYwIKQ2ytNpIy1xZhZhPv7Gf9Bs/xdqN4oSq7exNSJYpdFDPvhOsVYqjBZL2EbULXZSDWGg4QySGpxc1SVwm911fSRpsFRV21b6962rk9HqlbT9nhH25PpaDr58rlGJouc/o6mxwiMdM1oXUQpwvbWs5sVlXhZvGSy6+6wIsqDDPjVUEo3lYtIIowI7zwjgBeTJaUpwxiSxran2VObyorhurKhzlTZHiuarKradKapRFfG9m4xqg6uVZT4x0yIsEsY34neT6VObwvYb4M8UAdRlQadhpAjFmGQARMQVVa1G9U40tQj3Rjps+lPzNVflIL7jnD1naq6oWvORNYdk8iGSTV5RhxPRtzGsepMzKmB4QH3FGOCfcdfkRC8yFSWQ92JQh6iWPmuITJNRay0kW7oBvfBbe31dPpTDu1+NHh3/sNZ7m7OZxr1Nrdx+GPYQyZTo153KE70h3sakyDYvV/wgght3LZf/Na+KI3xdDSd6TXLUtuxLHXYE/Rd47nMZwJgRa/zRLv5UJI6eeVNf5NIxcnE4Oy6QaLdfT7g3uWR5yWUWfWYj7X4Qa1YzFQcQVlcfv5tS5R1fmyqypGpHinTkaLPQCg4/nqhPlsxU/1XX/EHCI+1CsjG4pr+exLfDYpZtczRVJlN+ApQFNMzqOLIhqtMZcM1qEz0mSqTydimE9Nxtdl4MBz8EuFVpqVv0LWAemltmfGROR6NVe0nlrIooano3QO1/ZDExeHUyHUNLVwgkKKCjV4hylQ3dFcmM9eRDdNT5JlHbXlMxgbxHMfwpipe19vYrBzp49HU1NvYrK/n83iby3+jYbwpsXk8mmljnbMZ4P69menJ7nSmy8ZEJfJM02x54toT4tqqYZh6O5tZ34zxT58GbZyeHOnayNCMQ3Ca0dLVMqenJp14iufKE0cdw545k2fueCp76oR6ijJxDGo3WCxaFumPfrq4pDTGMDu2Yrsv2Jr1ylzeAUOexcQlLwv4YAuYwh2EMXX3uE04hMY/iaA8MajLs7Mr6+8fzi9YHCoOZWYQT7eJI3u6YsuGYs9kYhumbNgzOqaep85UItrHCpOZC3kTTXlCjYlsmBqRbd0BTWFqaMSdGoA70C7jrIMz7aedm8O4dSjvzo5/6DcU+9BDGedD+fyyzX7FbfYPsx46Dv/PsB4OMJTDroevdRi2XyELBaUsSUyv+yNm9WK3RjwifVfqdAuqvS4mS0BbWoCl8K8dr7lroH+SYM1dw/h3jtTcxZs/Q5hmcQz4b4v/YTw+WnO6y4kvN5/qpW3jI7M8S9dAUrpGkhhkE0LKDIm1BK9HlLNuxE6PfYiReB7xvkM6cUTf25sYe7sjwaE6V5KLJ9BhEM+Iv81tHwef7S7ROoXem3XmcqzBLlrbUywxBEXhKPhNFH4D1vJvIs/75qCjMRWl6zhUfVK/L+EKw9sjet0cItyrpb9ar7WmjnfspbvW104CLWLbsfHapbizboflt5PGMy8VmKx+S6WpxzzisHayevaXIci7PFFSQp11DDnDWeIDeKEPKEtcBFaJQU1qqZQEBW8mxAcR+I157ZF0RdN1HIqD5+T6h8y6gqBGDL1jUJfsKwP28cN0bBTT0SnI7uYux+sQUAZrUHEFhhHo5ACFiQifMcDXQZQQuONy3MucmhT4Sz/tP5AM7EigCNEk/TZyBQLaype5eNjr4E5mtyAG5sdU6zCFzOpYdBVwpPA3vyRMLdhqrRdOS6Fx3i7z1sPmZRFKUE21x7Fmqj2H58gD9rsOYbE8h4DvIp2fMkRgXFcSNgUwj1EbGDAmZS0ieinuzPYmiiPPNKrKhm3r8sxQVVk3iG47jjlTFLgALsnjOxrO08XgSB/XA/CwJF89+M4r9EtdUahfqMUSBHfMJ1EgUcglQR/h6pr060KhEi5HWC+7kw8UCGRVvmTQxJ3rYnk28lWU+D25l1WpwU/exuLauQ7Y+77Mdudeq6DrKi06EFRxyWr6wxY1q7XPqmzOVI8AWCToucWIWvnecgC531tsWBrZOxp2TZ5SJFCqlxFKOZ5fLypYqSqBrIdVSLlys6VWh6Vp+dxVOGKOyHxwUW09UNq7hkfJwaX2LyFouzehAvPkykJ9hjnOVjQewD2n+LlkD4nvJXnzILJJYJWyKzxHD8vtWM4CEDItmyS0fx/3OG6qC+XpvS5vXoVgfZ6qw1r6qT9nP3GdZ/cWBY7CmZ0ta/brjbe+/eZhH2yMCarU/aWvJVOePlWn7lRTZXOmqLKhGhOZGBND9kzPJNRRXdNgYfJbYzgaBBHmELLViTNVDF2ezYgiG5qiyfbEnclTb+K4NqWK5rhNJDDhLR5y3RLpfRAsQQ0/knKaEqOZBc1s7fM1zW8lIqxSY3laCcBoB0H0kBx9Cv9Tug2i+a0kA9Z2loDgYUHD7I/MiAzbbRQvoaNsMqT/lG5xyFDfpeEGXTqTRORcSPyU9qEVRiEFUsmdv5LidRgi9jf7nC826T8luORLsoRmZEhNwVHAoPiKxnImacIQ/ilsTXLApi3HGIZ+wFtlNBdJjAdDDtBazpcCM91XfeapDve4RPa+aOzqCscjZUrMAXUQxLatzdEDX0QODE6tbWKiFQ3Jyrfu9cLsFH78XMggUM0gulgvSSgDRhzakzBVZRaGvLvpFU0TyOIpysKlrwGlHAYWkwdecigBDPqQZcFZ0fD48jz/4qM9hiTM8T+KpX8ev3/X2o//5vKPuT74/CT/y7O7Z1gx+XW4Ctwu+SwDSBRLvsfzCjGKfiIgIWswqyt6esiyu+PEZoyo7cLus4BL3ZO3/bLMdeHG24DMYT/CSdjiAkpHTqYOyXv36mbH9u+gmbYrfyuykWFndGLyEFinJPadk/43j7ZuNbeAParB9WfuZuyh0oOZiUJ8vUwG1QHUW6EaWzzpv5/tNTLeTtv4vHUQbKSYrgLisBQ9JWrstbZs79hn8JeXH5kqEcUnJWLPw4PG5mpYcclrwrtzxCs944g/HtYq1avRvUbPXzmeygTQMqOEBMeo6F3l+DjPy4b6ZrsyYsVrSy51/OQJonAJkc3JgsaXse/Qr8SDtkZ3cGAlqkorqMvV831H/1MU0q+6CJoa3DHq7c3uicIP/UhOSPgtPWNH+CXZQNK65x15bYtdhk4Df+7bfuCnGz7w/Y66rU78Y03jzfOOvb3NmtFDBen8FO+C+NaM52H59Csw5DCMYHL4lTlRbvS5tJ2ic+Ox6xbcFr+F8OEDPnvU+w9vX7DWof/rmhYDBaTz05H0z2jNXFgY1tNGIqLk+Wl2AStUGrKcauzCM5Q+fjw/HUqYe1pgqw4RKSuJJHhh385b03QFfPVhxSwwr6Vq6kXedA214tXrPYk30jUmF61c+4eDle+k67i91WMAigL5JxIvDn/YFDxG3TpW1PanlB6o2D2AZEiO3rzxR/5yvo5HTrR8k4Irzi+reW2Xi/66rckpsSB2fLUKNsya45dCQuoyNOXpillGdIcEgQUJEbduk8WeNDmsN9wji8uA6d/Hq9UBpV9wpzq4pR+KV3G19nLcub/vWazhgVct8a38Kak1cUxxHzkXVzQekclQSCww0aa1CVuvOX5bwowJVMTISskiWgeuhNWkOd/ngCYjSV3Y7/Brzb26IDsc4WBbeAF6JEnBLF3TrXNPIllXWOZk9FErVBpm3+Ev6QG7G1NMrIrpx6QHSu/Q3UXkZRVDWxGnLq9XtddfROT0wfjHyIFzbiIlESbfk5JoSeFohYiLpEhiP75mYaV7iM+VqJtLEQ8fs+4oXVkEZQpKgzd3Qp0aC/gNZE7zwVDrRKGbsMOAZSslWUg2m6aEBz0PJUyoiGMPIGN28QRakESCGJMGzjAXriJjxgq6vDBXq7GiFByvxgyCByIF/H9BnhCL1tk1jwUQAYG7/hySDqPbGgsxgE2V9yOR1ogDksYkZAQScLTCHSORbrJf0VLPTgpummInoENC+E048rnSvU+kH6m9iKK7BIyJosnjy/Nu8pq981YnJQ2y0yCPja7uiVvCJAZm92ZWgSXswaC4NmjoJl3G86VG92J7bkYKoVY6bdOXURAceo8Oo3CzrM026HvSfZTSOIFtkkirKAjYW01WpS6t4MJ3qQX1mikygqHEspwizXs/8W1M/AuZRaE1GieA1BGxC8l2OyJF6nZ+Tt/zKKYT5kUyrQavwdybo8H3rZp+cDjIKm019A/+JVNRIoQc2CZRPJcLfRAj+FwjIvzOjrKB/cf3EGatg+w0vK0uMoN6TW+p6brfMvINFt5iwTPXT5/vgrC3tt2qbP+dhFQ6jb6isr1b1+6nQjdxYD9tuvrQuHvWv/edu8KsJ1/jXtiadXTrnrb0Q564US2He++iVHVqbaX8pZhGs3TtqDSIqG/FAg1DRMy23dvGne/c4Qt0MXLeiwHoKKzgtYyk41QKAJxOAl0u8qTbSqO3cJ7f1nfolt2vYV5BeyU8/GvXHvV+ndLjIHhGESHgVWCtw+U6rVkfvicxLbTMoYcIwKRtKmVu/1gf1s4yocE9TXJ9b4MHGHyuebPspA9szdpyzbOJBeVu+WHNtHVh8V90Cf4hlxyfvN0T93ustyt89aO/u6XuY52dLgNfk+wNB3DH3paKle8RB7C3dblE/DkO+yef8M9kE7sGA0J2Me8gbMV8wWfs35I6KEZssV19uQ5Sf4VZjgUQVWZVAGt1VDAggO9gSAMcLI0phKlArJcD97/jE1T7ABDWAp+WbBTwBw4fPKQ8/7E4VZjBji3pQjOcoeen+oBlhba4FYHf6jP4NoBLmBiG4oyJrBoIl0Bm8syYzWRb0z13QvTpeEoGZVbaa+eOpoX2SiCk4IDju7Q0bD7Gv2kYwLU1SIhB8+eLdHA0AdD3B5LSeAlQNBAIlIV1DJj5IlqBo43/L5wCUU8dDh58lxkhh4M15JNHM/DRmzd8HsEKDNwQxbSpwo7Bfmd47WxX18C3G4mfuMOC+Q0JJAzwETbbjAIGIa5DiaQSkYDJIwlfUPDTgkq3jU3f5nk0cHHFayqagVD2NJL80E99vOjz2nmziDfOIeWCjQjaS2D9CvuQdLPADLhFiqy+lFBoOoVbs0ujJPNdK1TnQebZVbj0wpkMpWQNxqxEAmmIiZ9KgFcJx01AQjdxyIriL90sNtWl1tnUC/VyO932Yts6NVjwJTsaxAyiExpUqz0W6ldp1x6e57XzfpYWdbMxFa1FHHNeANngMZB3vWhjjEk4x+Ggci5xgx/M7VgRpdjpIohGnqQZ0iJax0VLVB69mVkQp2Nj24ZY3Im2TNenFUNbLnzthxbchL7s2LG68r7w72+RRj4DcbpcWdF6H6rvMvN/2UacRjGZ7yMi16xmTgp3wCpHL0mSSESAzK7joLCcSWz7KZhIEyemtM4ruKQV1GzyXfv6A9TLPOAqHvS5PHQ90m9i4txl53pHRbJ4tn9LEt8pnev9z0foKsDK5fuAlG8fGd2AbHicdbZ7/VZ7uq8ouWOrh7o+sZjXMNvhsKl9OtjjpCv2s+yUz9RMCXsiYbHypj6Szj0pWvppCqb5Kz5X3/spF7Okep3kpLj5f0HFubnFyMKSz3rdFErQVRJRdJgkvoOxbPH20FsSB3NqYy0CCkZeiUeIo8Q9Rnhr0jX6ssNNLoVRFPbzV7eimdvX8OTnhxIlcbCB/FqE3dWcVOKpB9CskFCmlnuUwI1h1GKaLsRAa5his/D6W2d9Io/iKsw3/+LNuHXlV040WOoJl5bqiPGVMrvZZrrLx4RKt0yWb5nWhQ8oDOOHZQOF2wnZlrXn5m7rrsb0i5fH8Lr3ln6P3Rxj7fkfvP94D9z/xg/YrW/WHOW6CQ+kOC9+It0en9yc/3DGTGDnF/wv3FniRHrwgwBDtgomWpgb2Ivy0jVdrXnkEcUL0TzZD9m3z3+pV/cnvrJ/9Vf1Wqs5vwz2eUXnXpHP+yJabKTpXRTC7Gia8CfaK/Znr95UIDMg5ZDIgwTLl8f8IJZG1UeSty6xg6pOu2uN3q8J5mLaFpzZhY9Cinhz7YvwuFQTzeibYs3cj2+Qye7gtAwQ4O+EXsn4zjl+7jLzmvshDDbCHrYl6yV+1gbawdQnKVmuYMyZUAs+P8DuCVuqSAbSqrBiqBYQLPFHUxRFZA4pZcWo9J1z5h0095F3udE4Dl2vi0jsM3Hvs2kabKmkvDNglsZbK5fQnpP0QybYO2dKxHj2If891AH9ZkGSnfAS1cqXWEms6O612ZsREsGbj2CV2Al2bBvvSUjm1MVzAgTncIF8zU1cYsLaHR276gsr4fogkEtIbMyAi3hsOfyTBTnv6ui3UArbHYKNPwhoiJBt7bVORElRM1oilFIBH24XBV5DIPhyQq4bJZa7CckSLBs7aJyeRtenrCyvTh+pgw/VO2qesXK8lhfFDtquQgaYBjntOgzhLVQ7yWqdQCVO8ZfE6s7MvydVdkKU+q5a76J5Xtrij0uYjqxL1RMs/xaKcypLJrE9+s1lvNr5mLp+DAfh7mXMCmb1HmK/w9xdsXKiVtRlvq+ifLYTJ4p317iGUqIGAtxy0Ohd9aDsGRTNKqccKRdWdRwFHUikiIB7wspv0RFQG50JXfMKW5RS0oPKDSlT4FezDrWxpKh6h+k9d1S681e8fCp20GxrsRbpcjcTs51XbDB/u3n/Dml+yRS0zQXDOc+h7MqaWxGXLfeF2FLgmN6XmRPx+WhBY5ppAey+ZVMJn+PdOpVRnGDfMgfOS9FytUvMwbNeF2E2PhJGeCHEhsF+gC4AWVcYgZF0HEqYSJfD1yKIdJIXY5cm1l943YMPabRqV2ZcYtIpNZWxM6WT6WTiUWXsuJ7hGCpxXdPYGieeh8/M0WO8lzcyFK/tT+An1t+LnXaUptGynaOm7TiubWvEVA3NcTXTIe7UnKmaadqupsyq4/waDD0PXfrYzFAfPjdcdKAi2K3QlLLFyyHvEyunghkDPnl+nKRYoPaZLmOWWjCZqJXuAl8+l12aOqlxuXYEbO1UpXwcdq9Wpw91rl3VhDpXLCpCnSs1Kj6dKVRVns4VhdbTp0JV1+lct1bB6Vy7pN70qJVrN90rRb3nMNdvulcpqzY96m3rM70rl3SY3rUz3aVXzVxv6V5NaC6da7QoKk0PyaIqs1CchWm8WUV+mO5jCHuxbr1Yt/49rFtPtDH1sBj3NEexqXhZvC+L92Xx/uVM08+4bcTBBYhW4P/rsMBgzS3U9ygJ/dUKlR/2j0pHmPsuidM3sBJkkVa0aRc7pZ4fQggrJ9t5M1vSlAjiFe/BOAKXP0mUkIgdrdklnDfSgTrxQ8hKv94Nol3lx3vih+9ZzS3foQLVggS8F0Npg53t04W3fsDA3suOS7wV5jucFHsgprLbjF/1xj3dMecogp1nvtMSre9zdUIYqW1GSKJ4HTseoviOxgn6QqKjjbVe7UIrIveEcaCNL1fkQcpLCqhQCV9b/ISFM/+IjY+k9zzFFPqtsBQwrF+QQC0lj+2bPXFdTCoMWYbB1eDVN5iW/puh9ArTVr6W/ud/WY7gEbPDuuA0+gpiqcW95dU3H77/5vXr18wXsX7R09CJRBALk7mcRTfcca+WS/+PLZKhlNLHtO73+mpb5fkPj/Jqky6isPKnzKd2SQHDqEjygSRLXngVED8sf42clKYy8wQrf2GwqvKSrNCpsLBFtYw64Xk9um3XQvoylstcsPBltDz8v6Kwta1INpaX5fiyHA+6HNuPo4yTW/cpdEpGPzZkUyK9iryUhtLfyT25ZkKFlV/XyZTEiFXiXhmlLMEghhyCc3oIjqEYvQRPDpk3qFCAEum2oHswN0FwAcPwxFsIIIWOYFjQf9vxm/+9jBKGMHLC+CQDo14lryF4+0i6bZWS26F0Wy8n8KW+ak2d7CchHls/FOWlShokJquAMlMtUZSa6rdcbm7bfMyzqx7mTd7Uef49yglEHAc0SeQ8RZssytG0KphlIQKMcRmXLXXr9Fm201EX/U8TFAMuPeVoh506FUngCtD17GGlWTYrG9DJeXBhl7pZeagrRHB75MXo3GyU6P+egi80j+ROOBY8rqVXgNrO35Dgqc512XoK+K4qchrc4uZ6yzbU15D2EuHVAaVAuq3dvW/FPt+6i7Mqo19waOzFvQC704U35UpfmKMNSTnApiUgYTuR2q65RQ9ALLv3rabqFxEiWwcsRJ0A4i7BmMQLZWHd4tTkskozk/YnaDsG3/NXt8DoIz4Pt68lh8TxhmXtrCDQelH8KUSpyAmNMF8Evq0UDQ1dBso7yz0eLH54iF/BWT10/MDPLuEV7/nce5lFCW1zoUyCyXNMwk8h/oHhACDvI+kyWq0DDAzIg0JK60HsCJ9CP3SCNbrhh9Itb+hWQp+wkXS6jtEm9IE9CwsWu7F/Tz+F5e78l1RmfF46Elk/0ti3Ed4jArYDVh8bM+N5HxaXm7Z4AlCw/6DvfrYnVTEkGIgDfuavyyw7NguKwPQc0ToJNjmnuKRxa8x/MZQBH3Jl0jVGMaHNgO0XPEE7zg0ktWLP/Y9wPPipdMvaveW0pZTc0QTadADJ36FSBFm5bwsjuK3x0S7sGyIuGGsUd9PyqN/xeCteQgKC6O0O9VgcrBg4V4Dbjq79DirMLNp5x+Clv6DL2mqdLDpX5MUxLqtkh9n/jMCgGa49VQ4KJo1s7sXZsCChG9C4ejpwAnufCkt/zoPKt0fzPvuW41CAQJdXbwJyHzk+bgsYto5LMO/J1p7XzQciu0JhNjIrSenKKvR21/tm+VZaRwBiQiIbjlfC8aI7SkOpEs+gSZw7iD926YqGsOpqUzOBVVxEKYarpcRrJUw6HpjvSZLCa7+LqhNuCnyXzXj6KeSbBpr/7bUf8MOlY0JY0cIPudF8u5v0EYLxREOsfwROiiQK7nnv8r5yvBc+Hom5cu4QQ2OkTkaa1v6GUOBSA0ZAkWQQuYStUl7n70kUtg5TDNCJwgSAFODmkkggsXAt8kPR+AguYe2N/39sQGpTnpuaLg23J2M7d2oDaDl4Li25JaGL0GYVLHhUwxgg0rarsxEmIg6TJBKU5wpTaX0fdkdPiR+AppOslzySusvoKrUwYBjWI4BgBF2JFKugq1YYpU1743H+MVMiM2HCqCC+KnLtaeeVh/fjTZa3vNro38ovarxc4fbFezCSsgTeMH+qoiiSvUlZAGUQhTvX5lv/Efq/xtC7QuAyUMqtW29SMt/uJET4yUx7AY0Gkwl5Po2rbBpJ7zkQhiq6196pe3WkjNStDn3ZwjEsvCx8frFBWpzf8iraylzyxzXLbVlaXgxzL4a5F8PcH8EwVz4Wux1pJPBJneTnNwcswe/L4oRo3UCTlMx5HoX8PBjrhePJiZZLP7WSRQ273kK2T1ZAuv7bcc0dJjuohpJLU+rAJ7zUwqeTc4mG934chSBS+VE2NrqcZFN7TKitTw3TpJo306g6UVxqG2Nd1e2Zoo7HjuOo1KyMzSiM7Y+iIzwIGWJgY826wmodBBZPKGhxxIHt+zP+nmEgwhyBvxaN5zRL93qgmdI66RyqMRuPy+PSGkfVJSb/WcdkqlqXQR27LhqVogCxyDm6SnmUpqo1DbMWIAuwM/9AQxR5bOZ+uljbmMbGCaK16wUkpkLhlxP3Dof2pmaaywyIKcZiRfFm5/DZiSDlNUp3g+zKjkP9PUfeNtyvq9iTcCPn5GTghEwfUxqHJJCTTZLSZZ3W/7SXnpfnkMbnED/Jp1KYnPKHDKnLg8incOtFRHruB5E/gbn6z2A8HvIHDD+RxJUSp49bqKSPVd7sMjG/2EZfbKNf1Tb6VNNfm49sm6Vp2wiDvzBjDb87kWCT+k4iU0CLpda3xC3klK1AIRNXaE+AJoz5b+JNAbYYsWgL6PV+Ii39BE0DoH6RAG6d1GULoGD1yW+6gwqgJy9kAZsF3sBvHDhrA5mPuD0Mvkv4XXp1+eH65jXL2w5YnTVl2DsTdszCMZSJvud9rgyvQBLzgnKLNCN5lI0UESekW6x8W2+NydDRWQBuZQreRrHtuy6tWQXZp5F0vE4XoKE4/DwjPoJ5wcomjhOtw1RyI5rgi/SC3OOvNMHz5Vi0KJ1hi0NJYMkLXQofdSv1GUgy339XNMbxRmHCgaWFxTGm6ToOE8lQdHZ5hiRP5b7CdgQ/RTF3o8ferwGp7JXgIvZgKPkh5qoXf8LSwhfkpZ8sAT9mmA02/yWKYbNbe57v+JSpB3DhAeU1ed1D9qCLdTJX4TyMsW4wBXE5Ln3nIthfML4jKX0gGwDji9Y165N/l3iB4hqljw6lOLMLKo0VmQH5SQwdBg8NUefaX64CyGiaispDKSRxHD0wyANAAgRoaSY1xHWlJeAzxAD76DOcTc8PMMsXQpy6a4dW2ukxB2k+1nwC/sGHVOl7geEVTuzDbETqDkmAMb7xmRCDCkolLySxUhIWQ2eIdUgfV+wixbalyEF4dhegu/PNJRsEX0VLAuDtTCMCAHkIhUUhtolzR+EYT5I1BWi/NN4InN3sRovADkSyY596kksDsmFKE5iVQNPps/P6fGh1KyAbdsKGzYrk7L+OYhCbB8rUpHUoIBUplIChbaJ1zFgwki7BRAw4fhuJzEGNBIeeeLTPpKFkXK9xp9ueraLcUBcg66Gctw6CDXAUPGsSzL3D9jCG2BnSh8APqexSdNagrgSGTenVxSn872vQpnjA3kg6I85CgtLAdsIKcqCJmHJ7Nx6GkDEgegDNkjn0JAi2DHP59sPV++MbVtUJADQD0U+T3DLO1ySbeHaUs+aYX0KpVQbaT1IyRAssw3qMIQEAnlIJk4cFJS5/2vw/GZkknzenWNm6Z/vJljAPmmeuqIUp6t/+758/qZpuHH97cnr21hxPpuztqAfmN/wm/KJKUoqMYHZu3kHObOlVgcsFTeG3AbNk/4xQYbYKY77G9bIO01evB0eqqeng5iG+np4Vv06NyZfPzCKONJiizAtnmuK1uKBlBQSBrMjH8zAdGwMgBnM1ONK+dA9+2FoToMO+RS6IZzoWRFVg66McunWsZb/WMpeJf5mvhR3gt09s3J8GR58GH68/DYafxDg/cT5+CkuFTs8qhYCdlTLffVspM1a1L5+qT16VS2zt+t1rrZYGW7rFte9K10w1+hiSe+Lz9DtbTpFcfSoUKp7fv67pmkoPkFiDn3ZwrUZVLM9wGUewnyEOcYBQtg5c4Ev0/IQdRIm0Dl0aSwtK7jcSeunhzRUywAuNKoqleRDZJMhzizgbibms4TaZgJkWDKj8PNp1GPU4fXC8VsvpzxiyffKzr/C7KwGXgGU8MwZWYUxlNjzcWStsOOhxdBNF70m44ReqOhtDFElQQhJFWPfEDABMcklzy5O8cLnA2WCHAZ8rfmkBWzoAla+DgClqaA1AQzDWQQPBwk+lV6xCGkUgNQ9D/NcSsrks6TKCk4YJPP4ekHhO++jQjAbzc6xcsvAL74wYZGEir0rdPZL+mWkM4haSVLsKL0gbKeEKrNCOWJ0o5lqs+DlXZEcDlpU13rQJXEHd5Kzq1tlMFJ/YuzW1YDLLXbssLFe2IrBMc8dA4JYgcNAu2Eyxlpuf5JxayzJAC8I6SK00iiwUiHKfmCLFs5Nzkek6r1jTT/KKjGlZnMK78/fnN0IvKjGtoFDus1I/hnz3hI3yH8IkUNV/CmWkM7hVbth6vf7HOz4Edg2X8NLKs2icRMslGK0YABr3QucmTqY5Q7Ie4QDB/NvCuzB6AENXsF5CdqV1yLMQUBcb4y9kifTq7x/OL5KhFEahfH327uzkBsDnU37ZHTKbh7gaU5bi4BFhtVjaJtAHv7v68PFS+vaf0r0fBewdvccKZwOpuyVAR4vDLAjBebhasy2IX/CPSiUBEk1ADUqqiV54YAASAym3c1McY3mE7U066DkAj+426AGw7ph2hmxhWhi3ymcvhP9PAvMsgsuCYY9NlMUmqtytj6VJzGe4U58STFpREYQjmGZ044dZweYzsbDEo2mlD7Vy094FFCk84LEngkCvZZX8GrTZsVqMV4DuTmPYBKB1YVmBr3nSbdwrsgVDBIu3q6OZKuUeBeCC0E2wG0w2/YYvLskNpgMEk+HX6LKFYNTWwz49eC8Mro0W3ZuCwobWB15hKKxahUliLwq/MJsGf0M4vjyX5tzWwvXQog4YU3h6Y6oL7gZMyd2ahHZkhG7e+eWhH698hsuWXXl2eOeXq3P70TaVz3V8vojScxAb2HSbYHOY1OIRQIpLkb3WcHH1cyoHEwI8zN7BWXsmlKyWDmbaZkFfzK36MiZcwIN7VLYboP4vH9dDh17nyebwBsMlJeY2rJF0yV0Bs/AtodNkgpS1C6wSnfwvkZ4K1ZdMhyioF/wg2+JXDpaZ+cH5eOcuIGYqVUPEE+dgP7PUCVMBmJgUtz+C5zlGvaWLOFrPF9Ltf94Cb1C/AB0vq7NrU5ROAt+5+1u0Tug3SZa2C6/ENLynQbSieBdhliSwSTDNAVQNP4Fh/lce/VW0YOVILcEGKQCvit6A3BxlMZFg9wSLpBZ6jY6kd9FcOntcBVFM40LPoFqxmexJCyMD4HqKpySc5L/lff6SDWaI5zlcD9f5dTvr1RCe3WUmbSiGCW6H+WBHxcbBjnAVPWTvHg32QmZayKveEPuaZ91k77M31z9wGhLFfJkQN2fLSVYIzXai30Rii++/SiyCDdYHcCJ4t6FJ1jge9hAWhc668FaMP4NAg74EJg60B36Fjfn61wDlfc+NORdUMGs9hdK7aC7YViHzuc081mRmqpEIioYSYG7RuLSiMZqdIEEnz1ME+c5K1ls3ctboa1VrY+LxAyXpkNkUd+hhSfBeRTEI3mve1x6C18X8BWwW172zxwVZJzuORyoK5UarbENPDnYidjHHHedPneJhE66ldLmKYhL7EDdbMNQdqmddbqHl+ya8daZJ/kbN9Hauyj+lXytfThawJ1j2OriTWQSRjGBQctJ0kn34vs/20e6ozW7GO63deT+5YzELIhX/3q964wCLucVA94WDFRXj/NBuj2RmLmU8LRj88Tm3p2AY3E6+4IlUZ0lMSSCFmbuyeOoQrpBck8rluS7dWo4cjl45dd7cJ9z8CF9FWr0V+L3jViH8pYSNfGcbNLbq27nYGglsnNhqR/roFp0CW6xWngn6+ZaT7XXhRkooiZ1FYYHtaFPJW10JCazxlMrdyrEPWFQ88MGdi72ocztaOxu562n+SNPkWdZxITCk5apbkVgSQ7EwC4ssa/xz/eZBXT992Tpeto6XreNl6+i+dTBfankOkW5Ni+qK56vMcZnBvQwjixKWo9WpIOHkKyK7NfbZeDoyotSmzFR7Oc6f3+uHypBvm0d7TdM/xWiYrsgH9bLjP8eO36OvN+A6eVKcwi2H4n1XaH4peJnm33uar+rQlPecWJcG9GUFP//UtrNkN8Z/YTzrte8C8s+hTl8uAodc2x1HAv8Uh4s4bCL7l+1zBq8VLzL6u8poJV9Gx4EVa3VKZlEj6IWM4x1rsvKoY9/R0OJmxT4ESvUOttSy6/GLFP+VDlFMUO87sggHeZ7LSyHa5Fk3Yge9mLLBNI3Wahzt2z9KP1/OjD/Kanu+mwnM8suO+keY44PuqOjhnGV7xoPTaraWZI28TPOzT3Nlap5rxuf0ZcL/rSacmURf5vyvPOfw8sN1spcHwpcHwpcHwr/uA2Gtxn/AXeTFyeBlD3nZQ/7ae8hBnQxggllAF2RX4ZrNyzXjD6Ny1s7PoRTP+snveOXA+AxJJCt+EYa/pDAk6MC4w9DEco9LIq+LlFGRA3pPA4mNpBATLAnqezntvMjPlvxUtDzBf+n8FKOp2RqVln7qz/krC2JhSkuyWjFMmipT90kxvXNncRYQ0G/ZJHnmAyzhz/cdNzFW+GUTe86H8nyOfle3jgZxAb34ReN5uTu93J3+2nenJg3qQJsLoFXThxcrzMtO8rKT/El2kqacOmKY1iKqRS47DgIJPgGGIQQ5S/+CQGfEqbQ3+RUoaUE677jkoBUGdgPwk+esNgfW5mgHNUHFuWTkfWEoPrei0q10i1hJt3kfc1yIjHOGUo/p7c/DKO7ZMq/TrWG1qeFwjzGLSt2aNhuaLkxry1lU2aFDF7Mr9JjxrMqX4WDBc8T1FJaAQF4Ybpzp4yK6pElKlivmYbqk6SLqU59XKLJqP31/OMBp6lGTIUZFsZybHxiJL1+2UOqBPBanbtP6/lu+tr2i+HytlY07XkcR57vPjtVUK9OHUn3Y6HhETLsTJHXzZBqYnoepOs+gEmWD//kz4tpk2Wq6Zp+AJFqFBnO2ZiA5kFNruIWdwCaUw1oBEQZFw4rZlGUMufNDFyYSEa1zgDU+zC/DgUDBYMuIZzmqgBVks7P9bbtbySKKU4Z6Amg1xA8F3GJjH5iz926m437FsI+2ehhETmPS1kwXQtyPFUkXBfQ6SFpYYhx2TpCDrzw5S959rhxkQP4CPWMkXVMq/ZzlYopokoQ0HoU0fUPi1HcCmrwBSJVLki7efH7VseBr1Byh7/Bn5rZcTdy3JWY5ztoIxpz8/GnwZp3Q+M1v8F/Yd758GnwerRDadRuforJmUUxzSRhWf9hK01G35VTuA6W187JaXlbLy2qprJbmqwS/uIbrIPg8HMD/lLTI57s3eyRI8osz/rWVH6fTAZ993HXSd30l/Crn/cs29bJNvWxTVQtBdo5XTviX1fKyWl5WS9tq+cP7g6ztwHcsIar7HfTZb41Hfce39JdHjQP6cFwznxlkPXhqZOiqkbB4Q4LButzwFXXzoOadgwec7SPoogMiLU9TZw/txPicfUUj5Ivb5cvT4cvT4Z/n6XBfs39xzR/M94C3Y9HHNCZOmns57NhW4B2z8JTAOfR8d/SXveZlr3nZa56+13TEns+XRLbId+PEF+BrSeI7xarVpNpP3q9ePC9fNqKXjehPvBHtaas4zC7CEWM5oJETU8zNS4IX78vf3ThVmIynhSjFqfUtaU7hdc5yPWSpktAuUk46eATZ8TAvbJbUgqV/HopMEVLm+CQSJr9aroEYla7enui6PnuNOXBEPjpIk5PQ9A1LvPYGHI0k9BbqlEGmnGYcO5B7Xg0qmcbr+1dM2iyk8GdhrVdVRTELZnHg4Yis/FG234x4swOWsFkIYk5BUbQigUtRUfrGi6PlN5jLSPAOOyJ9oymaIauqrJiSohzh//tmJF0vonUASXpxW9qs6JH0DWfpNyzDMxcssFsVpBofL9EpgU2dBfNa5s17PqlRLNHlKt2UROD5GaQUCcBC80PJpik5kljme8mOKbmDDrK4p2TUYbzd01zHqVXJzZYtl5bEg+dhsvY83/HxtIVEWCwTJs+7m2e8Ay+thMaSG1GWNWtB7jEvGU0wkVn59OfrAbPm8QSqfRdCGFmcikWyna2QbzsqdBf1D15650TrdROdPYr4BYZYBYZ87YkfDh7iKJxbnH3lwR/zdHApmWeJPr/SuL+OxH4M80SXNTaKciJGsYlD3jx845J4cCkedwhSCoJ4Rzejg9l3G/puxyR05VUcpRQjKmWy8q3Ts7fHH9/dWGdXVx+utkdzypO4safRQ8PW1/aIpeBs6fLHi8urDydn19fH3747s04+XNycXdxsd72cAfiE9/fr9Zw+9lYFCluSdH56MIHAvtRLBH20AOEl8J2aLpawXyQSQPrBDcvWl2wnof46vW05LhoOha3ktHAiiLOhMACW0fZbSKBGY+nsMaVhwuK/s5RiQIeGIE/bSbhZ2kFell+k/MBPN5CWMHCxrk2lexr7nl+XxPvr8E8kuoW8ajRuSHcrCuF4aMxW/1fq4EWUvo3WYc3OmiUjB1Z6UOYrdalLDrpmudktC19pGL3OLZbl+Sv0bO0HbtJnp+ysqdUrG1rltlC3D/fVK7pqFXywLXxo34zhiyRL7pqNOc+3+GSeGLMiT7KVVt7zfz+29NkUni4fJZ35IqP7u42eG5bP4N5YYyPKEDRym8l+POg6PuEa3Gd4x5fn9YO7iaL3JNzw1V9jIrrK00mLXNJPnmJTLYl7TQu/22Tvdbt4usyXLAzCWMGuJ2BEydQn1i5LK/s7MMkJorXrRbFD5SikMr2HipBA/gfjJIDrYYNGwz5WrjEjME3SJfEDGYZndaHAvh7oVCy0vRsXnxVOqLOO/XTTqbOH1dsqHdjd4zuy9MPIcrAzFu01MwfqM+8CUrcqWdCCnjc0NKkm69UqiuFygTl9D9bRoEE/KndS1nZ2c1jqJLc74eVEmEDRnFxOVvF8w8jwcILWq+ZxbpXz2LUIzK+77pwwKggm/Urdb7l7ih2zYPYr3jKL5sfMqvU1RCfrcp3kwIUZHlwgyTlx7pJi78FOHWISHnBpr16Zn38MJca3qX9Vtj7D7bCNwaJrTfzdnvfcSo1S/ZVYKPTkpCW3+z94XnemAkm+sAIs6TJi6cuzMaC2VM3y/gwcjuardRAUdsCswFbvsb7E1RHJpSnxA1iShVgJPhm9uv2s8Vz8Lbs9LCQPPkhSEqeSeOyzqRfF8FbuNsAGdAmgqQYrtIUKtgUH7ojz+/KlPKHv/CT9nm6SD983T+g77klxRzeJhM8IMJ39j92nzuA2iw7N2HKPYLw1JyQ0gFgKWItxBXjAw4KCaJ6w6BtkFR46Ga86drIYUzKAkBqLr5jkjaZommIqavaPGwX/z09W8QdVV36yZprqmTNvPAqi+Wj+r8HwcKSYR1ez2FXFTGTtehfNW0Xtgj4Efkhll+LGRl0W3wQ87SBq+QL97RPXZ88vPw2OPg3UEf7fT4Oh+MC3MUDswBK87siJltul3iNCCZb77uxm+/vHq3P8+AY/nblzeha6N+L1HT8BS2XFlFX1RpkdmbMjQ/spKy0Y8u0mpcmnwZE+1itfrlOSruGTpij80zVsQh0buSKb81MsMlFmRFV0x3CoR2fq9NPgy6fwD80ulfkFmG3smj6VXeVGquxyHIdONENxZsiuQUm2i4aCZsmuGAwKji4SiWnma5JfD/60h+NHfJgpaKr22rmjaR4lmQUZFpgw+vMcnUsSkjl1ZZd6FLS7+3UQ0pg/LMiunzjRPY031tvmFIbsHntg037PflU0vK61e10BwIGscA1AT86NvKKx7MTkIbAuLz+2Xfy/Ja501fWxoRuTyu2TlV+n7W51cvdrwO/bv5YLcf7pd+1hs9iAXf9tt/eCA3YwpiQA97g7P7WOXfcSQ5T9FanzzeVm/2fAHQdbS91CgkBuGJNEwNtX9KwucLOycSO+hmuRmlH8uKAhMxpwxRUWJ6/AHLmAHxIaFSBsFC+e0vn1B+48ONqKqB4OuFvh0QAdaqE+emIS90MYbLIt1lknabS0CiPh8G4N4f+FggBGjklS0Y3A3uD5weyY2/3JkiJX7HKnIty9npfbowE8OaAGzpk1AkuWtCPFrdNm5Ttp7Znw8eodnpgSL9G7y7Ff2x4IUmrVD+QSP0oowMwbY2eLgDvH8AG7yxiv8Lwyhi8k9ZafwoC+SfD9hL+n4CXNIeCHxzA4waz5S8SucURaUgpAv+zZJZc7KfFdWtfRRzkBj4PUv28Io/Zxi6tdDOWZGhYXconjYqCfs0Teg+LW1ebhLXaxBFVjIV95lE6Nc7fLnM7ag8ILXfmOpTPmLbXsuCc4vMsoqAErzHM0AwYIFGTTsYLSB995dwC6OqxTNRf0Fe9820lUHDIOtuOtuVjvFHEU/lDn0ylJSb6A+aZcI0h7HFLZ/azppJJI+pc5rPiS33Fm1WzSftL7KGvbtZuZLpKAPC/Tq6gs7Tsk20Ub9sdWAJY/0g7ICzY8G/Mr2sH9fJt60NrR9NiBM+2KOlHswqz++TagrjzJx/h7yNGQDXc/ceKzdM0QoGo2LPws8e/S809ZV56X+937fKyOvPmiWeGAXzBNZKGpc/+ehkLzO+/uzpNpC7X9qGOFqPimy2AKM9/Vd2fPpR4E79ngW+T++WRmh4Wv93rmYxkwk8Scb16dVTascQ6h0F0NhR2Wd9aTkg4Pv+ycmoIW+JeYntLV5S8yRaik1MzOGWv/zzQ7OBR4/AW4u7/EBJ2SzYPPXofqHFw5XJrLSkkkJMEm9R084kkoHa9W/Q6EYnPX+dA7Hwc19RtOgqdJSNfJLLEvv8p2P6nFfty4d139UTXI/a6w9Pe4wbbfJ7lus/vSWEM58O+plaQxJUsLMmHBi2rNXDIwTwCRKDUJMKoQdMOcZ+YsjZYENBlJ6kJOCvxaAzXAEDoSAH5xFnV8LzV7AqY9DglCqh3gdFDpI9IDpXf17cV4GzjYSBk5EIBESiII5IP/XVJIAQRWx6RhfrZ6hFkx0Wu0z+LN7jYsmhC3Y6ZlWneUriyCswulLR+ynDl1eCEoshBS5UQhICEACx8WvrOQiMSpSTH4J4eJxNThoUS8lANLQH6ZksEEAAGC/7+9b12O40bSfRUEz4+RI7ooSr6NfX61SVnmmpQ4bEreHY+CRlehu2FWF8p1IdneUMR5iPOE50lO5AUooArVbFKSbc3qx85abBQuCSCRly8z1aIZWbnLMOLUp68gJETeUg7hrzBAxGYU/uqA67+0d6S3sJuka/HL9PDi+PWzX8Dt/svxC/7XvnhVqwqKAOW5DRGzLm3YKHgLutbbbhSnw9ijpnuTPfsVGyogVFv/ruCIqajK0jZmLQE0AAnRrW1JcIw3XGkevBYtBQpUsqAO6n10nepK1eLC/RXTtTUGVsTxkxMhi8xawSuG6WTiWkvxk5qvjLmqMaCSh5yeHcePJj/DwxPT5OpO3gPf8xzn96aGt2ZxQw6IbpNVkdXxCe9qEVN/vEFssif1A2749Nhe7ajj4eM3mTUvr1Ul8/wO+Q3IBEbzdxfg/PEeIsBFvn8nAW7XkxDQ6SEmlY/b3/Ag/fOjM/h5swcKfV+Z9ZlS1XEUmsOaDYKx6ToED3HLQROqEsdHkOAIKpfZJPf450pBJMt7BKXt5oErw4O4884qVfn0oXU/xP/WIzR3dG8KfzSE80xMoPo/lGRoO/iOsy99ZOzjwe5K9tWFyt4H0uNorPfs+vMWgLK6rQX5YGeqk2G207hTAi+hFrKqLn9rZa7dvvbCEWxjQY0FNd6IXF2rvN6Gs3fawsGg7OFbj2n/HKvAtJa3l3VaKVXUK1mpsUyOp6SeeHkV6SOBX9UB6oRUJCEbIdn1wJQcIm/l7SWAZg3r3xG6RAampjQkoIyvda1BkQHlU2QK0mLcef4zVV81ptxlPJygG9UbjPvgIevoAs1cxxSI8VV5/dPH49333l8ea+LWRlVuMh3hHqfw5zBIUxhSpPaFWn4rXuOi+QjeSU0opWmGo0BWpMrktmfUq6fQ1HZ8N/aP9LnLlV6uLue6qbgQas8KTdjsH/RyJf7Bt4bGgRE3pq2cRhlVmniQulGViiyDu5/hzzt1SVKwu1RRygwpj1378ktwxe4k1QLy9V3GKfQ9/CZQsexd3diptdseCeEj4vb6EFuMBCvgs9dLsG7/Rv9vgX9qV9neoCBbd968xcAxxjv4UDLix++Tfl7n9d+o+4h5x1l0Pj/YRtPgpvV7fzBhJ3u1Xrd5KmMIdD7QrsUIxaKpUd1r4pL17bCBvVaWYv4VoV1WN5c04uBJh3jt0OCyhTbPz1++Ors8nJ6c7E32fnr23fGL6fneZG/66uj45eX5y5ene5O9k+PXz2YX58+mp7EJ2onE3qixR9Ny2ze7gWzjog5ZhF0Kwh3AfKkqG7DlLpULgouJtBPb9EZqIF/QeMyuGGKy8IGnXgT3IlwvMcaayuKSRy0rk7UIPLxjlvANJYsMwFJxovS+w6I8ma7LXG4cPDjetBPOxtuQYXr897o0Ta6Xq2akCVv071BpKn3NPOcOkZ1mpBCJOzoltjEOf13oPO7UmuxBDbioFtSDsNn+J8Fc+Hs7Apx+ynC925LqqFX0UII9vshsxDXm7ibjaB49am55I/3A78LLrDxOhZEOsFDelg7GidUjT68h02riDsIbUjEKqsm+9oArdxNT5o2qLrd+3T8wN7pJVw/5pDFwQSH3yrpzgO5AldE53jWhO0YHumUa83EGnMMJp8PVxJp3fH1kSfHPnIQybL7CSKXLcpv1cZTl6k4laIww0AhdF4VpoqdY18y2gvKLXoMrnV715zJstVVv8HnxA1UDEs/v0xHsPT0iMXlaFoJ/FDTiFrfVycnLn54d7U32Xry8uOz+dTh9cXn+7B+vns0uhrfUH/3NXdL9rPvxwywxEL578ueHWe+IAE7C6wdZ4x+wrBGx1B6gvnha6sEljrjz83apY8VNz/CHe9MqzU0s8BoohT8JHrAzh9isRqZUESO+Lyl1hqxh59CA+2Y7wWhfIzgCfDkRK2BpEu3g3g5BssISOUdcgx3h/BkOV+6Gf8OxL7F9M3l+/11DQ+nItuFvgoYboyloIPHP4Ze7PjZjY8MvYFoa+z5GR1qK17M3wzcOvqGqHTQ3h/RA78uWy33+7PDl+dGz80BPw3++ePmCcQYrcxO8wFAaJ34nSTmSfWv/A1mK7Y+hBiMitQ9O2N7U6WPGrEdo+JNVtgwE7ZFeOraI2Y/HZ3uTvZcvLs/Oj18fnzx7/uzo8tXs2fnlsxcX5/+1N8EWly9fXE4PD5+dRZjkmJ54pz43poT1taX+mdkmt+0ipG2TyCICz5CTB+reQD+MbVHH6KPCuuUmVpBiZTAqC44d5Z1UYTiOrd7BiaRqvSwuMc5yB11iTrtTyUy3W68MbAHADyoA9KNPBasuJt2/U12lbS4rnCr3e6OzZrWt28IUeMZXGp6wBQM6UpOHGT/GZi/Tq2Vl4xS2t/3q4GA4kbeTva9H/v73kb9/M/J3KJIR+aF35WAWNCaNQP3x129sqYK7V/P5yCy+GPn7lyN/vx9Veov5HKf+Bf7vl/i/3fJQSYMTHS8OP3TJeliq0EoR/gDwqj6NuhZkv5svoz/eyKoIVb2RdVH/E/94ucU4LT+czMRDRbhJdEMCNRamaC4Xcq3zTXR6S2OWubqEZtHfc7M0sasUBNEDaUuZYvEgWUfS4HiQQygb16zUOp4Qhy9oJqsrSmAC/7UHKFrg7IO3JGQkPQbQm5Qd1l30QW8hFxv8vBURxjZZJ/KFdlbkoj7unqyzHx9+5mMOaIxYDi4zc1PkRmaXbRUJqz8molNT2liBBpS6BhAo/AY5KLBGEndk8T/4jSeRenjHe+ekiIAEts8bJnWzUpXqicXsQbcfv/+pXKrbUlcRN1SHmXBoU/sdkhC/U/XO4M87ZwXm0Mta/x7ztmn0Tv0+1BsmWGAKEqTFANV3jrkdfOJGeUgUgS6uzZWi4nU7UBdPm931G6ogB9/vSN+3kz3TNmXbXCIZ494mJGPhuZzciFGscgfDz9ijGlkHF/S0M29C6LzXrwdAsYD8nUI4HOC+RyONft1dAjzuPAVoDXjgVsm0aRGozZ1wHMBc4Rx5D8WrmhpJsVA3ljjc9Bf/pPzywPu0JSjA1o8Nn6UtW9896scvXr/8ETVe0r+PXzzfm+y9Ojt5OQ3+G5tgSS/8r7Ppq9mzI9aMTVm+wy3g7/fFS/xG5v9bWAAX5OMu8k3HnrovIeDCbcwcLaPcz7tQt2ouKyX5JdzVOIXfndNnTI8H9WLKoJMKDA73N5XN6MttAPrgnYq/FZPYU+wz8OCKRziTO6w9Ntm7ir3j4wlAf24Gg3eVxP7SUc2fZK5PMtcnmeuTzPVJ5vokc/3pMtd7knPA6u4QKQ/JqvLRS0n/BlktOFnQYTQs3gYmyTyHytIdMItClJjQHyA8aVdawrRPOa/4Q0KNePWjkVnPVeOisuTctI0LzAJfiyXAx5z/ir/dnh0IyODjpUXOVT0eRg0/StYbGELGHhIoO9LF20m/8590s4LgvgeH5I709wwK2FF/75Ja5e5gvK2Z7N8lSu8dTk6XH2Ccf2AuSxtY3fns/ypcxFvCeyHEjPIdbOGnHTW8dAx+LoK/HGXsmt6BQCOMBR4XXmltq59+eI19pFWtBuD3B1+0HnN+G4oL2+ehiuzSLBbgHIvV0iC72ZYGDWgzXZThqBfy4AF3/0edXt2ZUA4a4dYG7wZVIfVCS/4qGZkBvaIyH/9Rj1HvgRTbgVwBqf7sm7AtffV7fpGGMsiD3qTTtlF3nktoNDyXyG7/eqdy3TYf7lACJXagFWSYgpJ8UKXuY6DZX/Rwet9vK2cSBCXE0sv+Eqa2puxT0azXv9xPEC/jE3yIbPzHZp49V0tVXMRLOHz4xJnvFYsxUogCV8iZ4YcFKbzCYPj9g8pLcGWIjwGI0+aYJfXy2bqMBfpOC6Hgl7BAuPtqtLDWVCx6idPvJXf3O3OVKGirdwjBd3XWtt4Pt3pq3qtyttOnp/aDoNhZZAFtTvN2hi9sO1wIG1nB0hjLfTF6ovzEetOzYyxjTLZS+mLR5tHgaDuhmTtBPAMMlh7g1So77+7EMbE94gUGvviBO6UqZ6gTgak1sqKp4Eaia/Wnn6d+V9Z4o/xau1szn9znWHn5/PaeWTJTvYtj6o98F7xlP79586ec4d1GGez4H3qcgVAf7DSf039EyUY/fTq4f97B5R3waGa3k7dth8w7XY+RN1IX5C2CFELej86pRsNEXWquWOc0+BLk1PXG/9I9/3veAo68mTi/9U6k46UfD53UEZcvpKC6tCmohu46Tr9JLjuz8FxvTHmXxmptMkjTu7vDraPP04ODg+TgSYK1kLFE7ME/Y3NnypzAcK94yqPJLWDqq3YtiwT6wQwjgSN8l407ddtEtqATVSwhUuRJNxnIoYGYfsh3vAOsqrdJr/mzHXbqSo9rGmPd/wjfgLK3Ypj9fT4+w48sL9z9a2Zk2Evcf3ntVh0cP4eJx6XaWdvxtwrdH+Wb8rI6qjbnbYzxDN6WicBE2t1yRFZtkqotBBYyJr3m00P0F5SgZLF5udj79uedXq9Pb9Wnt+rTW/Xxv1VDQfTtJO7lVBkd1KzaXAI717UAou7fYS/o84q3/37PY/RJsY0+vXV/2ltnV2o/oyz9XnZ+foVM0VV3oGTXqmNnABlVMl0FzC28MvUW2n16Sj89pZ+e0g/5lL7zWxh7A/+EN8pysku40vcRDNq8IfDpB3rlXlX5C7gguf59BGo/xbCLoNGnZ++vqOLtNMpgvz96ga0udFludRaSiAtBEO/PZ2j7zHOkjO3RVWfqymu/L2eiW+f9nYnuU/+Mje76cZEBFRS8t+9p+28TiANofMUhdAL6R/4+DstI1x/qeL1o80gAnTtbMK+/7sEKxwAgcf2emGX/bEWZ5YM441/41IaP+l/40M7oP7acW2766ej+jz26Oy3EHqQPfFAPu5MXPVv2tPIJBWqslMwUHZV0kaiiqTal0dTHbjC2/iROpS5OTdbmipCa3nVYt3mjAdX1GNTKxOLKxm4ELEdqUlp7U+/EX+gkdiFklmkKPjwLrsZ9lvI95tf2zjX/XTChxR37cd5GM4hPO7aBZpRPzOMT87j7MMbt2++Zg2w7rZ8O6v/cgxpnzHYJ70xc9z4OWK2n0O9k/XFdfjjrTwsNElcz9XIuM5uwdkiq72RmC5qIBFILgKcfkM1yrRpOvP9bq6rNDnfKh7D3Bq1tGN7eMQ9hB+2GAuOfzFvlX52f/3svNZna+/bJwcGTA7d8nvg5D/D2jX+soeibPRnw3+7Mcv2enQHwfULipC6r7dRemGqOGW9jd6RuFwudaniavVSMUOaAUjXbZAW1aat0FzbmkzwY2Sd4fNS7yH3wxCf3967zvxKx2wJQ9wZqb8frTPuIfHvF7knW/hgdZU+BksUSroi9OGEQwJ0kDk70yHT/VIJft3lxWaeyKFR1+cV//meE1+Z4sPDre7272+YWDCtLndhpJalZr02RsK2PZ3ljqitV1fEJvioxu9BP2EaQ5N+J59zRvvjJup9aat/WWONR/avIVJrLivx0v6hbKJ9b/yIWWuUZ1lz3o7JAQdGqxm7/VUDukCLVuUYaTDifCI+sKRabOxRh238VJB6o4lrlplTiEf0bjo54cnDwxcHTz8SNblZwo5M0l7UtWSt08a/iFzptP7/ZX6tG7nPahF/2/3Wv/AgdqmjbXlnib92myW59MDEuQ2IMjuabcNufUorme2z7ezuodgo0crd+OkQJsIc88Eh6jGD0Wne1anElTw+ePk0OvkwOvrw4+PLbJ19+++TJ/lcHT5988XdwZapGLve+3fv6668XT7+QX3w+V4svF1998+TrL6T86ptUycWTTMmvvv7mq79nXz45kJ8/yZ5c33yuvvgm+/wLefDk71+nB19lT0DVlkWWo679895CNekKZAxwDkNS8jrR9eV6Yxd6AB/kZlm29YpZD5T+JD9tOO2nBxdPvvn24Om3X361/8UXX33xzdN/Yi55maq11buRIe7Va6hZYUOq2xLTvVyCmAZPPxxhSJRTt2vFjFQV17oyBXWz1+Xnx8QzFVZF/XZvvUlys0zsl8hOkfddwrA5OkJlkckqCwRcDpjpIWCCc4fyNXDtnZ8eeiri7/F7TC3QKR7u3OFpC93MIwJxr7QHbo0b0Obb8pNn4zPWF8AzSNiFKgGpTbIh5lqrCjgf4DW6ZxUEoFJVYHQhCYhiSj180pODg6efYyZ1k7aw38QYOOvdMFjXPqrDdN69sFpqCFw4l7oYzjWX6VXtpDND01so2cCjgQcGRbW79wStVtEc8G8HNUiA5t0iJv0/vBkqngN/5duephcchF042trT+h5mCP8Qvke3DGY5W4PNtqlPk07L4h/fRC73MWxZIfOZqq5p7/oSPf0uqIHAj0QipoVoC3VbYo0MUdOP9IKbNIXUabtIoR/3dZdAg6vC3ADSickUUALyqfnU6K76wdM/8Kp78wx3CIW7sjLXGtO/LVudySJViLKqFAgqNsmnruv2Ezf4t+cGJEtuSxnQCPxJJFbuzIyix07d6rr5t7/zsIGjK/fu99d/8FPOc4IjBVPCZA6f7uu/3X3FLLBpW+lmMwOCcIKSUl+qtdR4vjTMn5yKFlP47d5/JiCvJ8+wUXdtSv2j2gzO2QVVsr7Wpq2dDEtiPu4CPRB4XECMhZSjoKcDrQ5z02aLHEoWTs+OJyBhApYZnIa/tkXKcOZmJaR4npu5JB/EldrgWYV1XKnNXaugOf9Ba2C7SWlqLNiKS8JJU8EaUHYaJTNA74Urqt2SXKINGhkOjJKVXytv1TTl2BIWip7qd1rDz4dUoFDStN88ghHrbx8/zhSZX6p6P3Xf7Kdm/XjRFplE7pXXj2WpHy9Vk3DW0sekvifY2ePPcKWgTFyyUrrLLr6qVZXMqP1OW/qqtlEe0SW/rDTUtTycihS42gKdNTUv/7VWN4+p7JrYmLaCDXp3IsgE9vnx/4KyidR5Ap0nBqeS8O9AHri46pZkxCOTRjiOt2PnMpOVOPIfD2Ch8Hzs3T3lCr5+vOdxCrQkeDwCWKy7aj+/AdOVd0zpD8Pd/PkN2BVuk4WplmT+kkVG7Gfe1iohgTGaymW+1g3Kmk0lIVEbtGcBE7NRi3Kl6xWmJV/L/EZWakJ2R+TBpcl1uhHX2uRIixqKXXbkSsrK3GpQQnSDjBPKeJXMF0slY5lWp/iDULle6rnOdbPBaQQTAwoiwSLfIx+tBSZTjn641o1e0myHX5+6H9kMUItGXuG57oyn4DEJe4UzJFNMyRVbEv0iatVgucKJWCtI1lVPRGVyVU9E3c7dBzUR2ONjsAy8Gd5B5NH6NLUiXZyw7tcuW09NRUwbtTRVLHRk79D91vvIVEtZMNOLUdJcu1nWYq6aG0haHX70FiUdSMk8/B7YAhJijbk3kI9wY9rXGDXgFTdRWAl2hyZw+F3Ia6lR3qC+aqhzhkKbsX11e4RRPJlakFgH2TgREO57s1Be8bbw7uWUOZTr9b8RsmlkuiKDFBui3Kq6QpK93eG3o+u4Tk2pBsenrMyykmsI+EkDg1L/PeKzrJOlbNSNjORVOqvM7WYiUpjrREAyqiTXa90wX5ijmm09rDjK9Jg1WXDp/r//83/Fy1IV0+OJmBbNqjKlTicsJNcC/oyrMZUKDjelNksys5bRes+UokVQM7EydQNvGtdprgxksOvmtKpMu1yB9j09Fs95pXARaBA329FheGuSHHi9HTRYJ/LUldLgRslQgnf3H2vay0bGQwCPVFkpuJHZt3ZPFzpvFEgaqclzxXzJLATvkcjNsiZ5br4RCrx+3QXLNoVc6xQqhNoU7T3QSUgbmVamrgWh0XIVLgpf9IXMc6jJOBHoZpjLXBYpvhCwZg6hUZnIVJmbDbyTsYns+z/HiJCbjeBveP+4a6It1mXu+hArDfnsN7GR7Hdbr48uarCYiVpeq6wbCpMbBtPAx8fROAHB6I5dxBASdLfRZ5DHD76is+ntF9ZGaeveEHf0XqeGa6zgMdCAvOXTRftVq5xMgb3hsdolnaDtpKECARDd0N0WYiuy8JmU7Wx/y/2B0gHUa2UaGKAtqeyvf9BQRmcuv+xuJ6wvCmyAjYPTV2CXdA4zhWmV7RWxiA+kEZwUuiwnainTjTiBni3nq5Ws0ohbxWb0ot8TWScyYTHsW5FW8iaH0i2ZuqUJIHDFQTJxJ6bHSWlu8CZXKlfXaNFDCsNB4FTQDI/oON9ITKiFWeKQtJrpsZjh5FD1gd5xk3818zhoSt3Ci/armYtcL1S6Sfk9HOkHGWop08hrfWKWOpW5wFkDj8N++LWHQUa63PKuZeDCknnH2KJduD2z8vTwqjRwrcvKrEsg1q/EPyfi7Jifmrao5QKkulKneH+aSoKPDJ4uFLumxyIQrSLPEn08HP2lJ+8kcE41dVzqVHRSV7hEWgltRFnW7ghluBJNKaQh7QaDJ4aj/tMUip8muxbXGh/gTNaruZFVxmnHNQih6Mw3uRHzSskrqKthRdFqaUQuG1WkG7FWTQWDBkQwuYkICqpCFHOSKlAKxSNo9llkRm48l+L0d6hHja8kzzMizi6XlVpiKkxo7S0pXKp92CZiLosMC+ECFgK4Gy+vhCcWnpOaAodxnZEBgQoz8BKLc3pYHE26EaG0uC0alDQmWeiqbhKo5iT0Gtib4vcQd7BaRsj2QjVgSBOmbPTaGhXY6cdPRl0qlYm2pIeL+gWOoiVrTJREPjjEpPiG+4Y+77skA9cRC02wPwtZN8BNC55rKZtV3RuKQauQoRVDox21ENmOYEbghAkIkvHhVdamyvaGgIr5RqzkNXTblnBcoQvsT9AZq8nJQ8KpAPFcge6xMBiZRwP5c6R9mMsaTQKNzE1kHsepmqsKnPjrUjZgaeIh6QM8tOdP8bAxw7Nxp8BNQMoGRYOkFsdCiUHO/nHC74Qqlrro6chpxwSjehmOzsK81xZ7thaNsHvxaFbK6moiLipdmIlQTbr/GSrFEgw3BTDVhJ77yJAXqDB5TZ1Ei4tH+qTOBpa1dtF1Ict6hdb4UpMGSZYD3XtXYnBlflg8wuEVQCrBmUcOwBSGR5ZDIvwdCsfYp8Yjy3Od2N31JhfrZn93yjFH9ulnJSsW/1CBCpTs7eNVbezt/IEkYWAC/ljQ2AIdAAxSMNX4Dug8j95Ca7zgBlYHp8kilIVoDYfOUyV7qm2RCZllCRwNkpjCk247HQ7/XTgsw84kyfxr1axMNoGuK1UzO4diTjq19lllJY3WOnL6jhvSrHorgdWy8xwmO/6SwIjMnAWhfMruiZ6bplBNslAxgOh3+CM/RWg3zXO9VOjkVSqjMY/P6AWeveDTgzM0hSCfMZv6Evg/EBMqAxC8RSXrpmpTmFRoIKpjQfiub5ouGr6u4RXBseyLxqyedUAa/vBpf7S3tt57bCupe1hccDzCW0Bs0rCVGFmFv5FI1lbnWWwA+DsL/6g+WqMCVptITVGQHgRmu1o3hsSehszWpP1h1zazNfQE+sJ+QETqO1kZczVuH5hXskhXncT3w8XFmcBP+AUHOzWNRs4INKGM2Y2wXbLWBdYsINMVPfSoSKlFpeqVn5dmf1xdOgf5TV0rXiqtD71fpRlfD7kqO8ptLDnxesONsbT+rlvTmHBvTTURGT/sBSSKcCup30ovl1Ht8tBpqitzE8wWXQA1L3p4RPa9XCeRfr/XRca7BcZCk2p8dvAqsHvXfow9sSd0dOndzBKwpCjuvHcTPLKynwLlmoik3VZLFnoypy6EmvshSkTnCuWjiSDZS7DsxZYbWWmJZqrqmnzc3aG3bhNg8EmlliM2X1qddfdAY3FOjQVLmcQwpc4NYHHC948cI2wj27K3D1iL1/M+TR+lUieARlM7gJc9bfz+UUs0uVlu8Gj6gieLDVK4O79UYHMtV2A4wiF7s8DpR9WmWtcN1bfEOos4A+IbV0qBRkg7DRWAIZYLykFQ4U11rUkAQ46nMnsqAtLuk9i/ffXTtjFoLcaCk6B6VmtdkJ1pDqL/mACOKlyMYsEUeH9iBiIU4DO9QJ7f2LUGBrlC6DVyWVmzJANYgDRVZSPIpSke/aTmZxMxfX38vRNz8QZhxEBS60xtMRpQXEEy05nqFHJ4j9emgGsr/kNeyxl+MPE54YRvnblCf0lBukaJlRKBMHVblvkmSVcQIIb2/qu+Ju36ikiRK11lCYQIh+x3LTMFzJPa9seFaZNzD/dJ3YI1mTlMpesr8gDRlGO3jtYC1sT5xu8XmR+C/7unGqV9uVYJOPxggZWesw6ZXtm6LFbyH7VoOYqfcVM6+1bAuVnpdOUWy2zOEQPdQXlubuhkdBPG80cfDYfu9lOQdEvGln4fvGhyVttFsfcFpgqIBoyS8Gw123ja93il2gK8MJETN1eg7WJGFjq7wH15sSaCCA0VduQBnkie6UqlTY6sC7vq7K1Ozn00/Wk2EdPfW/DzPj88ozgPqHfJajiBKMNDW8Ujua2VhOK4cQvXsvRi7xpQUevIdKzHxF/3wlSpSsAuNGLiw/PcooIKrxAqCNOz43Cqc13IapMwYx12xYEbJFaxoMR+bzjYpVNp27rk/cYutbIGcZlvas3QJ9IXIszVhd87anRqH17YstIGjwD4DuwZQ34vEN/BJ2uM8j0yeDplz19cmesxLzz+JECSWeTmpqeXOkhTxPlOu9Brf6vWY67RZ/a32Ie0ioj6ZK3xkW9AfB+jCvwGJE377uymUjEhoMX8etcWFACtgg8p5E3G1jUDb86r85N6Io7P+Glg9yUbOoeaH2MauytPwcRRWZJ9ZJ7v99C1DgzWISjjb7VYEhqKVbp7YAhOt45DoKru3/udnX7Ma+N35VqLucoNGKzIH79thMrkuWmjNctY0uYG9PyyWaqyUvfWvsfVATt5Xyi5s2+QAesmDrIY0pUEHO+boIf9rabB51wkKuxk4ytcQfaRBA5wbFL2SaOAsrp71SaiRlcl/t3TOXRBmq7zJmNSUOaf4TNZyg12Gpw+dQt10MecteRl99owxlblOaVBoZhN1P0aQwZfNzVnkQWREjyFEPwNGQILoUFmumGbjYUAWPTrNpQBQfbZgZfnCqQCkhM67z8L6fg4WDQM/ApOix47ZkzBTjOIAhCcnBPrah8xl+omGVPLz+h3HzZyxyh1HMHQm6JbbtgNf/12soe/7bTqYS9uMoNOHrLe0f7hZGRPIjz4CQSUBcyVX6wJi0o5WOdB8gZlheTH2T9OdANNwfxfq7WEWD0wK7Y6bxJdiEzX4GCpMC73WlUbejzY0gD/ibcMMD5k/g8tVOR8quS1ijzRgFtzKipKWYkuyEEDjKstkZuhyHv0xE18r4MXqlLnZtlyXD5FHvspkak8+gV0eIFzAEoocTc6Mnvy2Fn6HvtrIOpruSxMHXd4Wp9Z10g0xuSd8qMQulH3ZeK/1aQkA0kdTGcFNQVByld97cw2SagJt4hA30hJdD4Y13Vgu7MR1NpkbCF8DP8z600AZRO3gpiIUmxbYqidg9WCaKQC5x1FEfFBR+HuLregLlKzhicaW0PH16rCCFzICt3ogk8DmeYV5vKw1j1ceeWrB4AnawBUkedO65l4ok0mjl7M8DpUvSfDDRCxncYmRNPtpkWqpQR4Z6ogyn5hqhtZwauGMi4cvW0ygKlEW+QmvcInyJtlF3c73wgSjFkj2iK5nwIV+rTtJiupDCjMzyXvISNpt0D4ZG5uA4pv10LtUtCjgymPw/l6wLXueGwznoAyR1OvfeOJLq5hnuC07zzwLLqiyv54joS0FgIL5CEAB+OQw80fx0BMnU+elDkbMsdWnGaVb/ivBAJAsMLGwz5QRm0U0a1HZA+dD/lVIsdMNNN6U6SryhQg4gDuhvVecNBj5F6u4BlQwNTtDoo1bLrFliLABd2pCMCaWJOTfxsETAK7xxTqHVlj5jTskB1jjvy0O+4IwXgMqGucKQuZCmCU5Y2VomgSgIgWlVqrTAdQacrIrevVso1CNs7gt+fwG4Y3Mywdapny3jrgeW8+4OGl88KgMDyjFVhhtp/sZ+EhDM3rMAgduFoVGUJ98RR6588Kj91fWIED6rQ1TMz9Qa/hUTOFDbonoZsoBmmuMcOBtUUD7n5Mzj1XbFXbCK+dZ8fD2HDcCMDNWZqZhcBYJoGuBX3N7AJBEJm3seElLrIoj58pCgkoatpbeMSIF3lIY/oYJmnV2k7sBUYYkDu4t2PeLseJArnTDvRbaxrJFj8Iki0actsyRUehwZ3nYGTKYFX35m0ZOL3DZLhuyy2aCUiShNDKNd7sxgj7hcp6/NvDs1uoudc7Gnxoiwj1G7Ua5mjs9xQh6z/LCc+40JW6gbeUbW+GeEynl5GNCaQtYYtR4NUq1E3EKWO7i8AzYuNNCJEFV8uiyLiEPf2Kl18ugWJ4/5zX5qfp96KU6RWH2QWqkarrZOTRPD5LyBPgD8Px1XChJzTMpNPSsNjYzUo3irC5bDElu0i+gV/hQbAwNLeSONTOrdQfubLuow5tD7Yg2CRw6tORwDfBsrGR1UVJzEjs4UG438a2coym3yFjhKQ/TrN1hydwu2Cs2BQ3k10vXfjsjVyMrgf2eu3b8OzGT+iftPmIqNXXOmulO1yIkrlWVQW28uGaUIfbfmAQH8mBErAZ/rFB9AefSixJBycITVF0SOhuLo1Z5ipp5HI8UOI5thEXcmlB02OGWFrETj1Q04EJcrtCMsMcMzkc1UC3sMIJqSuBhT9UVeJqUw/CowhDOXRbgX1bBiP3XmJG6JFLHmitG8zK0uXUoUVuSlVllY55TcH7l5PVq7twGP0N/Vk1Fq8fO4oRGaeZKZfGIMwo8CQxaD+j66nlOsJ60KDGQAwe2DO84210cULuTNsce+4P+KLbf0BXs9lL4Rw9PayU6y/xQSkD0AgGTPXH7tSdueKwJwo48uKFiB4dPM/OdnS4I4iN4sgjHgEfePbU2VfO9lMLaQMHwQoOg+KMiHz42tYRXKz3imNiKwGTTwg+xHRCc3GX/Ej1Y7n8wB+nnGu7hdb9ZCNmR9f70qI8+90j2pMJjSBMWYN/3NsFIjnmjMIjjRbasTAJPCj69y6gAYQLiwuG4G38uHu1UGpmx/pE2JA2iKXgHtABaK25waECF8+dQHKqfc3YFPgg9MuC2ZWnJKkSBs6SQI12zqZwUhJeqjUIr5F7hX+33SH7mX2O1YJULFjFopS8JeMGLMkSTgBCfd3ZxOEpRsjPKA6BuwQAZsZrccQl940lCDIsmmiwOtxfcO7EPPlD109uDFrfGPZXqbJtOHUfyapoZZsAFpCz7dUT8dMPL49nFvfIriOCD+4E/AtngAjmG3A/rHQ5AfxKblKeAjk95wDg48FJFWsbU5g1aLv1psZAFTAMI7IhqdtqIVMbfhyZADYT3Gw4F0jIVzucy0RAYkZV0ZvkzAMhABE8zCVLH1GzzRncwGsy1AT4RoofQ6wx6QC1yVtW5UgdgPVaHQMziMB/JjbubASGix3y/rFO2EElbAQIg/wtSA2hUVhNzA0T47r2UPSoBpgOCgojqxrHmEysC9mC14bITXeCEjpB48c2OGk4KgM65xQd3ak5KbzxKkO1piZIsvUAoVPUqc+sJpNFo0ywfcwHRN0dn3GPqPh43lSn53bPGKDfET1AbBe6jyoRTigfkDS4CUhfOJJ1vXYmEYg3ZZgyQRj4klDAeR1udFTnd5YoxurQ7g6+FampKtXZW25WRkf6Q74QHjiHbbaaL5UsJLMLtYPV2P9mgxMC0BnzgRzt6mnkKLaVxAQcpsoQ+UXqMAX28SuxMS0LdMrdKD4qnB2R2DyFLAbB1EHICvU5nMOPT+14E1blKwW2G8e9QB5Ct0nnSkHwBlJAF2VrT5OTPN1ECVSAne/fEec9C3Dv9n3E5Unh5jhhIJFZr3XTqCwhmw2o/3JJdM6VvAJ4nvPZJmPSPUe4QfhFZdYaluBDazF2ZqkLT3/bkBSOJsclnIWGAd1z8pk6cbkHfG5GoWnsm+1un70vfR8tqH03K1Uhn1jogkyBFKpNwVh1fYOHw5sxU6SLNo7jIdA5PvchUBzMzJpNiS4hpDwrI6z6oAFiqUxSN0pVzhxhYaoBFfiTUeHwOQamcCs44ktKV4T4g5WkKO4+3h3tuZ3egFwjGGffw8APNWqwYXQN0NzDOh0Lo848hEFUTEKihzdWLJZkVGnjjS0rM1c9cJgz2xNkFIYJ1El/yP1xvfHDj72NqB9sdKJ6RKnwtW/vqN4ovVyhCZwPdWbPObI2Psnw/NUrk2f8lHrg414gDHa9T5/96dPYtgN/3FRGj6CDCFDu7DZvKCFAYMuwdy1q0wAUEJs0LIQnykCf98HinmhjAet0niyPssLCghz5nb5OPqSoVsnOIOKKYEwMGUKnoT9CcjvnUz0JW9afATehurNVx3osn465Yk7M0mqKk/7TDB4mL5YRRK7D0++YoOCA2ojjI6sg8Sfkrc0oFfrAnAbDbJ1DD/1nu4t6Y2ggmGDf7LaWS50m7EhPutckYrPPzQ1bqa3f3e5d95mVCvgcQbSlzFXloWhh6a/PDlH9Fhq0hYFvZTT+aho4VbxRh24xhLriqJCoazK4S0F8lp/WZMyt3Q3mmcgzsht5AcY8CB9tjPIhCqClHK6tvhUyuwaa1MqlFrku02TEgnGMNOpohvkfKB4swBxbKzltzbWutRdhJQuzlhwG4dkjaffRDqAj6u3RkZlBKhn2YHrbDu2Rzs/Pnz0+PqtVCiDwQsGNQ4AqpxqpJ+IUxhA/TV9QDq2JZ+2y0evpFaCCZYkB4j1sBKaYyJKsqO1McG5DQDI1FEdFLc5cw94lcd01ablbdxdpuaW7MiY/eWmqEom4wT6Pw53q6MLxdEpVruV8A3wXs5ygy35ZJuQqSbYEmj4/s/4UF+K6IK4O/AJvA9kzGWcTBBqAwldosm/R1C54m3lj7TzGfdUwARdP3R+ZS6mj8YeSp1DSHv/l2zp2ukgwNR8fn5gI30GGLJzq2PtCPDp8cfyZyHVxxaYQsiaWq02NRg5TiWtdNeCoKemFwpwwlUrsNIaP3vkznmMH+Xc6Ew6KODR3c4yPa+pOAS+XVXuVjg/o3zVvSEJiVSphAf1KbXwrPppyi7TalCx02NHKVMaO8FlwJUMwbKbm7XLp+ZOQLVG+WLJNj27hGABs5nMM5qy0N8dnlmf2kzg4BOCAA6EEoaMDdXeOwluJJRGOAlAth+evjibiZPriMbTB44aGveB9mYjp4Umfj5VlvxEc8heqgWeTfyKea9/aOw7zmT2VlCqKj6U1AfvfutR0eNR61kT4OnB7xSDzaRGzwBAKastN8l1NHPKBs+MbFnuigguwx+blXaiAAp+NHOJno2oAK+33IGrrRcYLcfJySmZfiob2Y7jGuVgoZPR6Z+ZGShIxtEgEaG6iMTMuY1/Q6UKm9E7jZ86ai9a0VJYyxTe8GQNE0qG6K5Uh5EJL0EcXtPQzUVhst5fbEWlHDMUtvQWgEeC8yIVFnqcoCvyOOaHOH86mH5jshaJ6SbruTFPZD4zh9UTIwl6vaPNkjnhOArGNf/sdwlI419h4fsnk7jSRDFxEr2c7z1HLo5QRPjiZk5b5feOZg22KsVb8+0Ds52jo0tRN8lsri6ZdJ/xAROWhZwUeXL89vjHqlkMJ+bl3/MDyJD/FZZEF2XVILcZXKO5C/L7Nc8iHC1ldO5nKWarxiDzXDXLSJVnVKcJ9Ilgh9jP4cWQrm/nYJ9FL4fHrCBdC15j9fRL22mUhiIxgzbNM9lKXKscsOSNi/qRzyk08MSm0RqOT9vzppMvahGggSmjrAWnZAilzcsUERmhg0TFDrPcxGTntlInp6FrcVGDwJS3r/KmYtyAq1BOyTDuJxJuRDVXsTNCx1c8x8z85tHyrOybbwPXzwmU3Jc4LCio3J5NHU0jaVnUsuPTM/hRKqdIl6/qtVW0UoI6JqSAikfGu0BCOoD3l1hhPryBa3ifWak77SMyEJ9vBVkHwT2Wu+vqvrdI08IrwQAQNCyLcLfqby26E4+BjLHHeaq+XHb9HpLZeBchs/or6bXMUk2UK1vYcIw+alVq7/CQ8b9gHyOgQIyUiicFyUzKUcXSSdzgq2L9Nswuz9aC8C2cmQbBN4TbOhgRQ2YGII2j2uZ8li0KuXBYD5Di/q8oItUQ/20JZ6dHegi4NIWO96Or65gaLZYCjvtbLCLiUe4uIZLGUlt0l9Bxihy/PZ95sJj3Gt2VevGYAkJHOR33vj+Vg5LQzMr2CBRQZgcb5mXJz83sCz0qeWBDH8IjYb9AFk9uKgiEWlxCtqkrqvK3KWHGhUyStzYiE2SQsYCbcZLu7zFYdMSnGQ9XtGu8+MWZVOdR6owDiAcHYu8Uy1itTNUmOprhwBr6zi0F9gL+1so+dUD+5Fp1hzlD4Kffbp9xv/2Nzv2FZghhzgmOkmuQGgLbWgjAAR3z3/GwCkBmWYZpKFWgmJnAP7AXbjFkV/q2VqLDpogY3Ts9iCUDipFIygyMbU1IQaewacP7SjR/Xz+6NXm5zq7ljvthIv8egJ5Abg9dAMBYo08jZ4e41BiUjHkF7YBUJr4lYywrd8YhggyelaISlv5XfHpm2IYB0ipcxbeHJdNdY1k+eRJ7k6ezJk6cIaQKpdWXCHAiU1w5clwSJIo5xbfJ2rWzmeDJLWHAMJQB2IK+YGHxkZmQ290y5udyA4kuHwp6Ra9+Q3chqCdnnvAwa82UZt5Pa2EG86RbyDq6BojBtQUifGqByNoKkwVgzUgcAWcFjrvSvMB8i8B5l7Is+0/5NmJsuYsCupI+zCuyyHb3REhurGd+VRSHLXykrzJUKXMjz1NA9usk3CcZrZn49FRiTooX3tueXNzcFiAR4hugk2saUtHmxQPXAbgS72zgr9hiujgvsdGeI7xBGLZmyk5wQWHeNio3LwHv0YjZ7dihkZkornmxNMOICurxBjk6n54ePZ2ffPz768fjU9TWBA8vaoAszCzcEjTDRtAwnxlxBmt3p7IVN4hHg1TqQC0o7UO4YT6TvmXUJltEa3gHJtvuAbauuz6E3OEikzDcGqxUNXwVgzOCwManJfaJdnMxcEgvm390/55W5AZsXGkdowS9nwcnei+GUoiEs0MaTUzygkMdrEe+JAO9gfwrVjDj32LrKzMU3qAu3D8TLIBSHhgrIZZMij1hvfWSfxRA5Y+wjtb/cF9O1/B1O2XzDG/OZFwTnPLycMxthD50NKKI++haizqLkTrOXuRA9E5Z43WtkWRUp5PjSjvMzz+bknmWeK7mBIc/0xCZupiPwK9gvKlivBVRsbIpSdFLI4irqAL9wTEBwGy+QqGMbpSnbXOLlvvONrQyw66S5jXDUc/xtv7ltQuJhnn5lvVeg8Q9peKPmHY5iFEXRsU77LTII4hVxNoF6T1pCpW4FE9drFU9ec3F45u8NtqdzRZ/4T7hXBtGKWAxPsTH9k70mmi/1wpQ2qyxtzKOLk6PPQjbGQqPsxCJOSAAHOyHHeJR3HrnIXcemuC2Za4u2Rp+MzQKmi07g8W8yOfg5kj+Jv89WHzILxjEujcngna7FI4qhmptmIr7TxRL/A2WmyD21k7FisS1tMx6VZ6MEEShBUS8dyMGLxXMe8XNod2Lb6WKXKD0wQqINMmIPssnVZZtpMxHAm4xnIXGJ3e6RAuoqBmaYHf1oExutleIyVuBE0qkuKeCEwLL0C+jpDo4Ls7lRc8qYCxBi3exvidx/hcI2XhzXi5diH1VupsiPULysl2cp6H3fm0jMifI++9/PpM5jFSjgz+9jLSMprC297tVpFHsx9pWvdne7b72FNullz8AEw2ylPhQgASumTVbLPTNKyvvUu6l2zMgA+/VofPbM+jX7pPHnxz3a9cV8VvFz7+INIXpu4i9lW//7mFQiVkoFHiXbQd1Yi6U3pkWGjPW5X5o8JoadwZ85r1MTjNKjquuvm//Wy+MlL+w7IX1qO9L2h/HpGfMfdb8ix7xvl/tjGaCm/s4NDoelTjA7HqekJzx2hdqanR309TClM+bNmPj142wkkwVM2Aw4drSOs46eyv4ZSSiMpPvSoibpn4Mj1DUcPZhTOjRelyMUi3WK09m+ucMp39X/+I33gq+4EVuiwqsLdZfYaYgfW6+9r7P5A+3DBxH5A8OoA0eMF07mr6B/01zHO75Twwt234Hud9fu3buKOt7OVBcS9TD6dFsSCbnhn0D+u2+/3t5HBOTux3vN2gk7Qw8k/eJhz+i8lZwJh019/YMfOJr6o+yz+SpCmDu69YWytfkthtv9B9rZOZwWgRVkQuF4UGg850SdyNeE99ytzW/79HXUKQy9gkana0OWfBjNDyJPZYVZkqBb6yvmKdhYCxd2WPVGHOX5F8TsrQsYCzerLd1iemIGG6E/F/tH/XDRRmj+/SsQnYK6kz+p+fnFIS/EieZuRb3npV60I+IZ9+2gHD2HkkNvuShC0tXaKgJJuXh1/oLipHGiK5WXgnKjI9KLLMIvphecc4yTj7gO9+Nx2D9ChzaIbhlz3eG4g0SkDJFMKI9d/CamVNRBupTJN6bNM8hjwP56yhKF8MZA1emQ8+FbbIEQYe7EKu6Lmul1m8uuUKaHnKAEbPN2adNPNxB94WFR6g6MQljeVNeeD9KmVwA7WzwZExjgfBuIF6eBaUQnDn72WRfy5kPD8KVYVrIA24pzG1oRIMjlrVJd6jg/eUUQK7QHCq+ht4i4mO8SuAzmzV6zz/gUSqhLApeCcXPsRO5Gersl6bXr3Ea7+RRzZ6BifbuXj2ok2pgylQaYRhfJjOYeV2jWWn7QQkvWJZ6J5sTWfnJbXkhErAb+jEl1xKmSYA1FQx+UMxAupd1nXjIwrF6HWICJOISII2j5WkNVdC6FobHSSLRw35b84dGk+11yW6r4xvB8qmCyEcEkLZA4Afxd9CXs2npIYoo/Vl2YMsVuUS4WL03/XMkUfCuFLkvV2ETcOkLR2eHxqXi6f0C2W6C/ywNIGBhAdtaTIP/KICmIgMR+XSXuWPntrRGhfZiku/Uj9WPtaRYXWCm2l+A8Xam1jHEp+qHfnIxArqxxMpZvaEYNIWSDFn04zDZEuVGiZps+GPQtFbqvwNaJJVdjjq+iqWSOqUGoaT99Dn6I6WkokYmvZveBD5DblvmfhXrJrlY9ZRMKLwCmlBuFwlLGOTLr2TcWl0OzQhsI/Rubs/LAgBiLPt7rqBBDhtqwgiu1SaA+r3J9dhVlYLB9AakrREKUTDSBXEBa2idsoIkjWImo9DNzWZNnXjzDcGB6HxDs4pVkwrXZ4m12b9ENxwU+o4OTnw68Hm3lF+l0GR6DhILc3EIDJpj/ILCHMk8LM4GE5XItrmB8OguGlTqdeL1WRWYtGHSA/GtODkaAOMxmJxNKXTacGFiV92wCsvFZ+MnHBitmMA3CsCFMHxJBwikDA3izmWBIk/Mwg/lA5r29iHpDTrucg4/3b1SeJ2gnf2y/Qj8JgqVdtH7dTc46f+EUuNzqiLDv7wNMBIsL1SsIy4xsAdZPneGvDkE0CbOS8d3G4kFcJcmPjQ9QUtAo4UZJmqsYjiUoFyUOoVGPo9HwowkW/FDwCIcDBF/0KT+rzO3GIkoxR4Os5hpya2zExeHZ41dHZ30za0R8tU4dlIUQWwHOg+UQ97jFpO75CRD14LRYz8kUGpBnvKpYiYTY1Yo0j0bNQwUY64m2qcYgvLMx/QozlrixoNyXc2glEepExXAbl9ayagtxApdpZfA9aDPdcDbbq4g7i5k2g9YEgpwRa4E9hgTuIvnj9YswHJzLE7lZuXjugQbCMYQusMVJFxZRPYLsh4R6KvMrEpFx3F8cpyWaBKv0cinyzCCk3YkUQIC4TAG/ZB5tfJrHwNQtVLeChaO+gYbNa6fs1XUE2DGbnTwGNIIPaOlJAv5PEPVaT8SrAnJt1QBKBcZMbkI/ZRV0CRCuPpcP99VOPmnLZQU5LKPz6xZJXaoCojPd9EBGBRmElKSurV2Z7TuMl+5NK4IJaTj7ADcE+Cv36AEEcELOnT6ME/lbHZCv56x564ILhhN4DR5FGMpkmBiFxZsgJx2lniOkMfn+EpvnJs0hlRiEQro9gdCfjDyVcQQ/+jKTMYvxNMsmQmW6YV2LEPFdRSX8mu0fQAxJQyH0So6h4V/x3K3NgvvmClD2O2sbanRjw4OxbzSVriFKrMyhznWxbG1ZClh/hFMwEh0dvkQJaMgY/qJLXEm/zTcMZ96wT4hTRSlGBHAJtzIG9aBEekwEGyQA+agRnjwjB04YChJsLSK+UJ1lzPkWjLYk6RyleRiCUkFijcIiwwA6W0uGp+OXJKOp4HCMUBuH8Gc+hu307AsBTE43thaPW60HZwNhk6MX8QDGHknebsoUdXrCJxULurGeySEv7kTFzWAzPw/hVnMYJ+DEzMA+2pLmX+ZyA053xFnBraI0VTE1gpJFkFyI/w3tKa2Vb5LF/dmyg/G5+R4ylArVlomCiJolW/YQNNquMi67EG17V97MHkJl/cl002KI4GWllt1crP41wOxSljjlB0PeSEjVI6uoqd7+1uUDwPMMEMtcbroqlFBUApkgjc8gdH+UO90BgX2/4ytePIzFAAPyeTOhykNBYUuEekcTWWL0Kv3cZSwNn1abkzxoBCpNgazOiwDk8M4V5NCLha2OmDOsQh2zZtw7ItWfVewudL/GY1NX0QSAp92PAxkfTN51Ew1APZyeXRz+ME0WUBkOoMG+ECJudLZUTZcxCrUAtAkTaO7suHYVFjMIw0TnLIYaq1uoDYNpdXxCc4+Ra2XnyIP2ZU00pkBZTrKjsLWlMo0nLnXJvlGgCOt+tFWecImtmJTIxe6IjTHSdmKLf008Q4wt5cBpIyFRMFbQY22cmTB5Cyn3KgqpoZW6Lk1Rx6v24i9Dcxv+OQrGv7FFy/hTjh/B7A2ZyFoUeYENUqE/rvg3QoO+pS5aGtB21uWGYJA1rNQnjKNoD43tXipMenmtqkyn1j4Op2c45H+BTOhZxPGMMWeDLOvXurGGjMB3MBFzjTlIJhYPWKOY1SWM7hXYxMYxORIKmdOvVjthSzJhWW24ttOCcIaPMgUxqegf9PB0oUmeu8UwiPFaBd/bDPrhFoVpBffHc+GdwPP0nW24Wy82vd176m1rFsB7dDiSg+7eXeyDHP7+ehtLSnf/nt4L2e9OUXev3t51SoCN68CAY05/rze4aZ2LpceYtkcHv+6ZZr3CeGUui17AMCSNzlx5aOQ/2ySSC/qhX4B1xGHvRe3yZCI8yAv87HgHazXLSq5JFe8K5nWccjsSVVVd+vMu2MKFTkkre8LI4HJzIO2aawt0qfao4COCmSHqSf8eeb2e21TuLsoCS59D+66GIFaogLQJBN2j8oFcOWrSN3QQ1z6fPh9UhLWlwcIUr5bZJrrI1G0c2O0Y8vUT8douRuAHA4GLoOTUW0zmYqg5j4Zroyxc3cJt5NFbFNgROJ1UxsSAUq850w+lImBj9qoyTZN7eeb4jKAwxK97qeSVyICW7HSmgG/9O+pSPCoXg4yJvXfMy2bF4VNq+4PWtsIzCrZjQB5ngmM1gK30FEEN6GJXDyXoOkjUUEuMqM9lWxA+wforyiiqmH3fqAf768dhAQnB1ltOFVJhCa3txe08t/J8A4l+BdaPzKDSVTBvi3+keVtNsV84fG9rIiKvdEHQNycesuZYqG4fCY7HlEdxv6y1pHPmBEqOZPMOMbCWPcrYJLP/QotN3eg1gfckZPci4w2ebC60HbtxNr02mpggSXHp6nJboFFbeHea8/84EyTJi7XL5kQsFNzsfe1iS8Xmn2wlcNumd9fHyyW7L7nJQL36XVby97g7GnIUYPixXDL7r5Dzoq2gWekqSwBAteF6n4+8pC6lvsWMihTtMVL50ypfhH2isf5jtlN1HkiwI/4JU+8Bi7o8Eg1lUeVUltZ5CVUk5taACLYCa+/nsxnjuZQtKzaavY9kaIL6aGQhpDRYmvPXgaHRvUAQaBcryPAM/45TsgXWYiNKquBSYQy5+I/ZyxciM2lrM1ePVkQ4DHqxh8HqApgIBEMOrTKEnn9kMFAuIDITTpWC0L2I+41+cJlSYkuxJRewQtoVp2NB0xmXt7JbY+/bltNNNwuIvW2kR1klF424rvcd6DBjEw7kRkmwrmCEdv7JnU1nz0AOa8CSQOoiWeVIuIEUS4jjYLf7RBydnE26FKNcsapXZ9P6GWu1hJ0c+hejL/iRXgLWSDxz1grhJXvFqW2KZqWwJC9ouhOxyJUNpeZ5MjQpnAeWpfWr/sIFyct9W+O5MuuySRpTRkW3I5AqTkD24uJ8sAdJV5WCijtjH4L6wJ2bHnP4ia386KV8peEpX0gu4yVntw9LhgX61tmFu2KPqqDCjX7GsmBYKDfWRZrfe9HuSzZk2oQlOK1GLuuxwTaJe/R3HpSvcictYI4zNO7awH3g6d5yeoPfe33wzZCqaHeyK+1IDKP4I47Eyt+5nVyZxgVNUyo6snzb7pk3JgtI2FyVlY4KeXeMxZ0IvxPOKIonFFJB2TqytrGbAkbT71th1dbI2XUKXbKkznyMPXDCgLah9GNc8hdMhLYEjxt7RCTcvuiRnj00Jzu+K20qh0DBQYvmXlcEy0B6KmYXn2574o7H4kFH+iWIE1ONcWT8uhG8j2qa2t6daLtz/zLXVAyXfe2DoqA2k3CUmY2nQ76LTs4E6brodcl8+uGcOd5rCZA/SBseceBt77n7ctC7ZQuAn8L37r3zO28ExpmOjn3vWzLs27sapAFhXR7vTvqDYot3GpR6sHjFbUsdU9a2j9WvBtzBJ6BXvgJRk+3Op9jeEK+zQfdwCG/hCm8SrFBz/wPof94bCqpKgXkgHgGAePBzKDw1oyYi6eZu87M0ZPXy6n/1O95nxbodw+/2x7Dlxlkf955Xmaet1Tq2j2nzi44AL8ZH9T90DjTwi3rDoZNa5ttH3WrC3UraYArzTZdZzSt50RuYE1Lddw9tjUxvZV0Q4ltGlY6YOQhHZvHyQaQ/6coaUqPaevJh+kPO/OAuVWDcAih+xJgFf+4p/wsTlWm+N0M7LyfPXT1N1vI2GY155OovPzwVp/KWwSEjXUE/kPgmYTFstDPo6YemKcXriCHCddfkNeb7yzUmWgNPaMxd3BnGBXcPmKxD96E4hQ8tZfdG4z3add80D+C6ZF5JHfMxIvLuO/ixZ0Z5O9m7TRamWnKhVhd3sU4RgYQKe4zR80pOD88Et+HsbSuVWTQmHZtDcAqfhp5hCi+IJ4jm8IqSMR4wguvPw+4jPqxX1hHDLVCjxrX9f3hOZVc7/9IA" + EMBEDDED_SPEC="H4sIAAAAAAAAA+y9iXIbR5Yo+isZ6BtXUg8ALpLaNvv2zKVF280ey2JIcnumTQWYqEoA2SxkwZVVpGA9RsxHzK+8H3ifMl/y4pzMrMpaUQUCJEjmxMxYROVycjv78qUXLpigC9476r0c7g9f9vo9LiZh7+hLz2fSi/gi5qHoHfV+YYEXzhmJQ/ImCBN/EtCIPZPk+OyU+KGXzJmIKbQlksdsSH5hhEaMsM8LFnH4yMWUXPN4RqggycKnMfPJFYskdAknJEyiirEGxJsx75KESUx+9dkVC8IFi+TQS0EYeuF8jy74QLDP8d6n57M4Xsijvb0WjV/AYmImYxw+njEi2LWGmAmPDc/FufgYkimLiYxpBBAnEtaR24FFFPqJF0tChU8ki664xyS54hSHPD477ZOITVgEs/06C6/hv1zELKJerHYkG64N/JNE+BS3KJB7Yyq5N4ipvJR7ZtABDDrIeu296JPrGfdmxAthx/Ui4jAMJAn4JSO/fmRRRCdhNG8DQGwa7/0h+zJIf32BGwFr/zWcTLjHaUA+nPy77Lw2uuB7uHNwGHvSv5TqyOaUi5hyQZZwabLNIxGTYRJ5TOLJ/axWOWN2E7hiEfst4RGThCbxDG6mpy9uSOIZje3mlyK8luR6FhIuyZxewojQnUl93tfQYcGiOZdwkyXARGb0ig3Jm4jRmMF1h0nj8JIJgH4aURET6nlMSryA6pLAPxcsgg0k1AN45JD8Z5gQjwpCAxna0DJ1b36Ffpdsud7WTlk80Nd6DwaBazJWD0EyHBYXQn6V7IpFNCABn3P1Ljc04R+sEV+ovZ/TSwYQzEkA+yOZl0Twg72Lckh+mTEBUJFFKCUfB6xPEsmsJuVHVr4I5n175YPqk0kUzot9fCpn45BGfp9MQ5jh7ZKcReGEB4z8K3b+qCZXmCBgXmxuAX4Yku/DiMzDiBFAstFc3btQEI0WUkh8EkdhMg6YnIVhbK0rwyXnAm4/XgF7p9c6mRe4FQCcDVfEpjTy8coDVHhYFgAknf89fP4RP7eZ3kIakzAaLAIaw6Ry7zqMLlkkC7+af+0pAPb+AAgcIBqoH17oc4xpECwRhedo1L+RXz/ApSMztgZ+te/si2Gv3wu4x4RkQCAFnbPeUe/bDyeDl4M3AU0k6/V7SRT0jnpmGiCvCikNw2i6p3vLvVynm34v5nEAg+VvaK/f0ySyd9R7Ndwf7kNboDEskr2jX4tE+k3AmYh1zzwgdMHL5wCt965e9W4+9XsLGs8kLGtvNGM0iseMxvDnlOF/YKvwWpz6vSP48a9po35PJvM5jZa9o176KyDjRShwS/JA/iyZT8ZL8u/JmEWCxUySiFGfC3jwcPUDfsXwj0UUjpns449vTsk44YHPIujLPjMvQZYC6PeejOmUi+lQzuCIzMy4msP9/TIz8+4S2nmhiJnA1cXADywCygX8Jb0Zm1P8fbmAU5FxxMW0d3Nzc9Pvvd5/WR7xg6L75GdBrygP6Dhgw94NHpaXRDxe4mkdn50iIugd/foJ9jymUzjG3ozRIJ71PvV7nwcTFomB9C8H0yhMFgN9yXwhh34IlM8LhWAe7LrVds7iWeibxrnTASD2qOeFiYhl7YGaBoOAy3iQNreP9kcuY3KcfclvAH6lQUBM35QSkvBasEjO+IKEEbB8fMKZn1FAOIoFjeicxeZW63Xgf4Ah7R31fktYtAR40rPJz/8TnTPgIwFlaxBg4PwB9nvsM50v8KXpf8FLgD1KJ13QaetJz+iUEZHMxyyCuRdwC5GxjZhMglhaEKhWuG0TmgRx7+ig35tzwefJvHd0kIOARaMuULyln2EUCxA9PTAUABRrhONwv9+bqyF6R6/3Lahe21D5PGLIl7QF68R0QFoRwcstb0vFwcAo8IMAEH7tUfwLf/x0A49m9fPO3VQbEVkvni4WgWb89v4pw8K7/18Rm/SOen/Y88L5IhRMxHJPfZV7nM5HZsyRFwaBWuUofTQKTbz6j/9oCxmZUB4k0UYhRCKpxx944XweioGZ5kZBmENNdMFHcYqb+uoHNqc8gB/6+OclWxYxV4oPEHd5k7OAimOFAXmAY3/pjUHeYFL2juIoYXCyMYsWEQcqqn6ZRCz99yIK1T9vUgxHcwP2pkwAPxosBymu7dVjTguX1SJMQHpAWRehrMeNA+TO1APIsKLF5atmJcxYajEkGdOJ3L/6GdlULqDhu2hKBf8dZ+sDGbziPiMXieDxkPsXSBDDOY/JhYyp8GkQCnZhD0tJ9oF8H7F0Emu0rMURgf22h4WZLobA3F5x5ADHYTwjE84CX4IoxMUVDbg/JKcTxPPYy2rTt9lmkGB8QO5zLtSKfSZjwJSK+w2W5HoGwtGMkZ8li2ACEHp8QEQyjmgcIlZjn6kXB0sCa7J3aJibDDdA5jaWCyVc2J3+TMJ4xqJrLlkfG2uxjkQsTiLk4QmLojAapsPAZZGo1UDGk/mA2P70mvz88fvB12S8jJmsp2WnPpsvwpgJbzn4d7Y0SHTGqK/RcY5BwX/QAMQwBTv3QfabcCatm5ReSQP9MHfYJP0MR6DF3tw24inCJH2QfoGXV0yhJHIWJgFIMcInFMFAKQqErmXD9O8ZyGGwnxIIMvaDs41YHC2NPI6fTJccBSlShTn9/CMT03jWOzo4/BpJU/q3JgY4yrehv6wiz+YkyCSMDFtArHes98Q3yGdj6FddQ8NIaZKwmnKZg3tjNvZDotik99skYqAoCdgoD2wl/SrB970iKVuBbydJ2IQGskDD9E+KiOk/kIrhv++QjKlLl+f4977of424f6MONGAxq6dy+L1I5U6wE5CVBfP4hHvmMZUwV21L8hwxfbpWfJIxE6gNA1QvCQXlE5ck5nP2Ykg+wr+BFqCCjcIFISnMCite8yAgvp5SLMnvoWASxAxE7plCkCQC+E9LOKhF1Nl2GRwNknEFrqjjez9mk5DTk4JMAiRjzDTIfokPbsngmmd4os9qq2gi9wwVqhhwvw2WSMF7dFgCJsVB1CO1GpAPLAbFhCS/RDxmKVLJVMTv03v0JRVy/hBarMkR83nc+3Tz0NGRxjTYIoymbKBf0MALxYRrLSNcl4ghEykT0Nbhq1cacGBbRBjDg0mEHwpQqfRX6C8yNBZTHuQ1GNm9NN/y9/YHFucUoHQMhqEKVIa4B0AGZpCSOdOCdz37twZWWXnx0yE1Zxh1Rx+4D9uVkLszF0WwHo14XIE1PkYJ6M2ETz7QCYuXGmv0yx/eMwp35+SnD+TvnF2nDdMfdIMPb07fKsENsI1io38MqU++pQEVHjDDZqPNEDWf9YD/YFFIEJwjcnZ6mgJyEn4g34axYDH5njE/A6j4QXf4RWn3yftD8iEOI1CdmS4Vn+xZzqIw1qqk3CTW74U5PlIeFH/797/Xzmt9KnT6gPdTlnqY33Vzawe5mB6Rt6HgcRgpffYZGlorNruuqR7UnMP3PGLXoFo91kQ+CVg2XnMr69akDeybk/6oG37LgwDENNPG/F0AqUDkKj5gh3WIX4QdWxG/XVUnAYUCbVLSRKiUD8QgY0czOvUzfqpVKOnPoKD4zCVaQYzGezO6ijslVjn5fXvyePrzQP/cWTbPn8quEM0aqB4zzbwfTntXkY3CIw1C/x4dJxKY70UYNVgAwTRxDC3f64Yl2x+OQ/Q4hE4pFzIuyNRVRsFctzn1WdpXWTQtgV3fVUKlDD2OprTUeSPFcR9DAgr7dEjkxm0ZWybjOY9j5iuvEFQ5mp8K4DDhL0KOOmIZM+qvgRSLJvjMgJ8qARpRZ70lbP/wJTvYfz15xTw2+Zr633j05QH9+uVXh/6+9/L1y7yC9OXhKjNmwaMPHCJAN67NltpSh94OuMFIWOzdqlLVgpPNFLH5agNmfv6/htdkDkqb/IkYmyXAgnaZlpPKMIqbJzwG28eCRfES1xlGMRkv+2QSBkF4rXwS4KooU+Vz7veJB0+rr69pn8DsfdigOJEvGvTWN/YhqjHQfmlDy2jkzZrhBVX+ADwTiGoN2nVlmzB7dT0L050DXROencyeDNhc4HGpdmoZ+Mbw1ZkWfWW58ahkAy4kE5LH/IoFyyH5kERRmAg0AV3PeMzkgnoMLUBTEUbwwoBtBVZkvoiXYE9I8HOMqkifUEnoWDJ4tm/C+ZgL+0WrNz/hQZx5JR7/dNLaJHD4+vVNrUnfslzjulfsNQIBV0DvklA2ioBq3gnxi3VR2x5/DUxKVeuPxmwSRiseSvHUdV+i+ir0pjQUzCdIDBqUk3yOb/7992/Iy5cvvyFK20FSv6jr6+thNPEGQBnDCJ2WookH/wfNh7N4HrxoNN8f7u9/Mzg4GBzsfzx8ebS/f7S//4/8ltS0KO0NncRoGltja7Dr49sZhXra3mRcPvYwSmi1Tfn31cT15TiHkWIMPigYbNSLS+4AFLTfJEgfYX4boDmP+RQp2qjDluX4CfRcAuqUjSWVIZmRKTio6a1dF/K36bBmQ+2LAPrPK9bL0VTEwiMRxtxbsdvH4C7MhRckfkZXlWcB+COSn3AMxNwf6SXzw2tB1LhAfXnoF5F1aT81sn73vk/YcDok/1Zq8Re1hP+dh/svwPxU4vdxGAaMitw2ICfdTqNpYWbFHEplEZkkQRcRSAMTjv+pXOw0w8DV1OgPIK12NIoomvJjNpcdz59JCSwS8O1z9e8tjKwcrlavzBIObg+AJUX0tGxteN9f05k+pdCNTMBJM4hKwsiaaUc20LPAais/GD606mMMDsOj+lHV90XhXMz3wqo0t2sxvkYgsqfJDwo7oG9p1TsozGBaftK6gKpXcKq8clI5KIwIIgiSSTR9jReQt9d8pWITg1BMkWZSQQ5fvybejILzPDhI93DCg2pTp/Gb4RJwCEYphBH/nflD8hbkcDEl6FeuQPMihhogGoAouCRjdi4iBgduM4bKNSnyi5EbhYAN7Z9zOjkX9rjQGmfrW8EVEH3hh0wBicg9nrFzcVGpZ78AkMufUM9wYYV7AI9wLmJlsUp9TjeicMk/qZ9Ftq/fwapTS6q5DhU+yaU4rYAukczp7ba9nsbMo0ZWzjYMVvfuOIlnOmqltIHGqcgnpc1q3CWibo7WVSWSSXWYxAvBNe1gf39//2JLe5lty/HZadVmvq56W2DCVpIAuDJxdsVKsvGTpTJrYrFmfaGlEYwlE9OBmh8AAz/9eLCIQhgrjEYoR27KxPZpQ6q7nNJtpe9pS+3d3hf1D/VlsWAQo8ICPuWZyrJSu/cGwiiPscN3VvOcJytGWl7PGErl1HBT4Do4ZkRNhi4r1SKY6Zgx9UASvCSKmAB3QzUAxVgt8DqdWuieTwUg7jGbcQwdpDHxmYcGzKN0YA7xBWAdWpIZlSkzq8btYwiVUiepbVE4asyAU8+Uf1rxyOO+Dt9Lx8YxYxIwCgGhgllMr4KImrmIh66REfhCSogSVbzOIICQonR6dEbNVp+6PaEXFPg+nbx9c0yee+FiGfHpLH5hMImKEjMOTLiR8Kqk8o3KHKCMo2rqUXnxav8VUbAgkp6A5uYiQ7OwwHRE3GODztGOpByy8uETj0IVmj6ZRmiVCPHe6NI6wNnW60JdHuu1pjueqpSeLAnJBJUOckYJnd2Oo3YMrmNwnwSD+2r/Vd1VR+x3TWVGQDSSytbWx+sOejJQ46U7JpMFdo6qiOHzjBIi2TNKKSCGLzptw/0gvrWxygpZQmW3oCXK8Hi35Okw/UN9+ZuYf5t1X0sGQHeKZqP+d/OSI2zJLk/YvNIjFhuqbxAKFBtLmJfIOJyD8Q7iakRurMxMCX5lmR4262QPaFigzE6TH+vE4Bejzy5AMwshFUcYpUx+tI5j01NlXLv4C9jBzrYa5LmOJCYHlTbx9R0EfkrjmfWZp64B6ZSH+30yp5/Jwf7+isnbBw5XvAtnTehkTciQ0u3nR+wF53Ias3nZnKCnctaEzVsTvqV+yj0PUvkmQ6yAdKOCtuEpvw4neTrJ00metzKtBPV8qUMrTs6qkbPSO7IFG4vl/dMoZL212jVLWvNcywr+03Y4gqBHxWzPmc9NwpCchOSEnW0IO845usE5utE/1wRaoLO0St6E/zRpnSYThp5hI/SLplU/6qbKkUw30X+kyaFiHi9H1hz2LzpZlH0zs9834LeYvVCdpEC5MGe8sTGaZkqNeRLEfBEwzG2gs1MqfUb2BY18ueFTj0Ml2xDJ1vaUzBBUyVsy2/0u3sg2lCoXA7wYn8sFjb1Z3j1ZOUw+AgfcbKs6OCcXDcnFjcqclR/NPt3WUdl6YRvzr7WPMUMW67x/1b0AKOHzBfXi2zoEM/87HF2/0jXVVvbjdLqrLrqrAsO3ASDSAeu1WPakTpV1S1WWU6Y4ZYpTplQpU/Ki55MlBU6jskqjkr8o21WraDdWOI3q9Kvv1dN/z644u84pV96nKTvhE+TRb1KumNY0bZ8XtfARoNyiUEw4KVq2+5mdOfWkzDm6YCb6AQSoRxWTpWmkrFn7KsPmhfYVuMhoi8VZnp6o7DARoxLrQrxnC8i/iDEcZia0xNu90mIrAtLgBVcgaShHEwjfNelIYz2y8SWlcY6nVeInFwO9DGDTweUVF9m0FWZh8MIws2xfQ3iB94NFOiLsQhE//eNAh6Hp7F0w/4VPY3oxJBt2snVqs07OrdvP0lLHNSsvT/14WydryfqndyViHuNXELKehUBZzyBii4AuUQItvRi5JRJfXiUKKWqRh/tfldf1AWowzcuLQ50CpNRfIIM6g5IkSGf0J8PXhpGVVM/49N/H6p4Mn17JjBPHiz8pXjwqcSo+g531dabLB+Dv6fjxHD9+n3y3ukXdOW9keG5q7Zg/MDsBVI7ThsyoBWa4VQKo98ZJUGX9V0xdmbHOZ4WiJgdL57RQWWhmLs5prdxQjzc1lH0bGgE+S8YB97L8QsMufGN6f9M9G+TmxxzS3ZM7oJvZjqJLJAw7HC9l52VYB+2m0za5DWohI3tURg7FnXYHdz8Hp3fLKcmdktwx5g5H7TyOejrK9jaJpCv14h/w9tZx7B+0blYUsxYW9EmVzZBFB3emmHtJQCP0fEDl9ntTOzn1QzTrUF4RAZtjmRaRY7qff5emzT0XaYFIxDtQN2xJdDyPLsqV1ZCcJyg0a106XpQXOuPkuchQW0prWqB5rFlmAXcuNLHT8Pv5cmBckjxJo4L89ePHM8i2cJAlVzgXzyWDdBNBeK0K0kLxk6kuBokbdERORZqN2+ORl8yBNHosXy0NiuCqFJ7nQtcQNoFzqhI1bhuTMR0HXM6M1DKYUeFjqvZFFE4jOld5JABVQznndIjcXEC0J2F0DdQ572ioqj2CTl34hItzMUmC4H/+678z1alqqYUzqLJsVc7oE0gPDdhCpdnQscFcTM8Fg+pzwmP/81//DYuEChsR83XBjzAii4jp14t155YWvNrbjoJLosSVZTGF6FF3BXXlpqaEsjobU7M9njEeQS1SsggD7qlCav650JMxnXfDLx6buQ7wR24D9LrPRa5kiPDTteMKgwA0rXqTs1SiKdxcENhaYJyg2jJWvdZOUBcQ24hmkokmQKpE3wUWVC18wMyrj86ssVpGtcLW0T1L1VdKKfuQfKfgOVIXfKQx9drJ7PNUD9EnohU7E+VK0Rf37H4MKwrhK2i7GlVKbFPmWhYst8Pf5cEtsMlb5ey6wljNyXeVs9D5WtNkGyHb8hdgnDoBjLSWv85FnQBGauUvVY9tHsqYqPz/wfJc2NKGIfhl2aKWVzgXFndA1mUOkK0A7gBt9NUCEICuN7GtrWZIvrO4Gl3sQAKyBnu5stMrxplc/GTxEHCMAMCE0TiJ2BHJGWCPz063JQ852fIu86gcflP9vNNcBHDnwiuGORIYsAkeA3YqppeMRMCnID/4Zztpmkm+olNZ9/q6RiyiZdCnLwfH6HteUYPeC4WPwQXXFJ5O5oAvMIt8SqzSpG7aYFyZkdfEkeTLlN9sZavf05j9qFjjexDib4/qH58t6lZ1Rgv2p/SIak1P4Br9wbRqrkJSU8mjTe2RrKt26H9sme5aJvEAX7R0K8zmqJQeSSRWIANNjXtHB3nEsH52jzIsJsytNSj7+7grCphD/KsStE5xcPDOlBxsov9UVNzq2iBNFSxaFAfJbtuqqBSTozP0q/eqIvaxWzUMLeX7ep1aAm8d6FYJVElLWQK2xz4vgtBP6yrJeInbBXL27apoVOECQyZ15eHm8iNK1Id9hOpt0D63u51rV1QAZOLBNgFPt0CslG8ZTChUJzQ1DrZy6l2pbp4yZFFdbS9Ll2gvS6Nw34vPl7hoXmwrc/qHagKK8QIFmX5LjHXVeQK5biPgt8hxv2a+ekUBaXFbSt565+JjTvYRjPmyRvts7I/thE0nEj54kbBt7vgaLnbYc5avNLRkkMkN3UUNO9ykyeOtCheVXd9qzqve3y11QHv0Mke7AIS8K5nhVzecYbuasq3hMnY7Uqbql69JzHI75OiYo2M7lCL6p5DMIWcFSgYFoR31lnbCaAvTdaCL9f64jjRmTiEbo4xt8gdXobi6nMKF5LxFt5JUvqzW1lm5gityDmdKdfROWUVfV2YOzrwqwkilEXY0+T6TBzcq+7aePXjF7LfhP/T8dydfpzlz1+BB+nass5OsHUey0xxJzYsrFq9gRHnSMX8tpqQuQAjf9ZPiS1rm2mzJnyAi3KN8APcpCgO5N/cWe1TQYBlzT+7BlFDg7Iv6B3aKwzAYeDQI5B6qW1mkfa0r+Ze5txjoUXBH1b8H6SADawybmTljkW5L3r45I2l7kmtfne7NpzxYAvachyKeBUurt3ZcUYkQ1Phr8BzrcBP06z/RryevvZcvv3n96pX/1dj3vv7mm8M/+ezg1WT8tZcnsGa715zYHgtQFLgQq2pzOXpdD3dq2OvhZlpZJc3fem/BWTybi06nETpvrjPThAaS2fkrowT+VD/npol/X2f8JM5vsk+XK+wyJ3iR4ohy8OsdXHPhh9dE8t/Zn41PFJptv1JOupLwqQgB60+yy9eQR3BDw5e9RYwd9uCrb+rssIbItCrPbQiByREIvDu8jD+TZzQInplXBeX4liQdsG7Z641Wf65W/IK+OYWIBqCXFBI99vo9GgRwl1pxk4CDfKrQx56NPqgXhVJXV2ERFCHE4t4aoSh/oxzNU0e7ubCWtrn0svdYXedb+FW8dj+HMxoyzJZxQb90sRq6rzwmoOqGutTZ8ZpT8Vlr8mnFWoqxMD5dphnyPvULu4tsBuQfrp4AM+jVfPp99dR5PG1jUkR35QerQFGnmO6UAWO9FH6t4kuhLIVxXL7DQK1ClkgdLbVyW03DytOse0eNm2dRdaRN5QLrOGh/rcCqvvoBuTz4oY9/XrJlkZMFruhM4Ztjw6/VMq5ZY5nyrPZvGbvqTc5SAUW+T1f1JX20XjgfellACF3woeHo595ipHk9vH84WkDFcY77/dIbQzwI7q3iYljqfWx+mUQs/fciCtU/b+rY6TGLaQP/PPcWQwNWA9ucsaQp/3sr3llThr0v6h8b4J3VQO14Z9V2e7yzGn8Xeed0ux3v7HhnxzvvGu+s0QcX04BpLOIYZscwO4bZMcyOYd4dhllzr3fJMN+OOdZTreaOtV14MA3C8Xa0y1o9dDtfs63zyY63dbyt4223oReGh389C4MsGtsxuI7BdQyuY3Adg7szDG4LjXCZpbwNo2smbMvQohtHBmXBz9M6q0pXTmWdhFZ6CMiWNOHTxPAJO86dVrkXbiUmus2gh3Zw80FDcDOjkTern6GYLQJag9csRDPDEH30gsXBioxNl0J0CmVtsMJQCSmuQMWYH2wEPmujOYZKljhctoiYB3G6R5il5SJte4GXU7Brgueg3occkgu4ZxdkThdS+TUviQjFIJxMyBvwjXsL/w/zii3/TC4QC2ets+GPSDiZXGCOnXEYz8iEs8BXOXbAKxlTjS1VXpsx1EQREnxGVWCI7RdoyrVQ8mp/f5idVgVFUA/ET1ecoq6G/SkuKfPU1D5L5ALWcWStnUuSiNSd7M8lz1FcoxYUoPsCqtsVR4DttPP9eAEHj0GCcdIcswpijo+LfwPgAfa/qDs/osIfsc/MS2J2MSQXeoRRWJ5CVM4AMb3hIiaQja44hTqyC5O+pTgiDa6xbIhYtegTS3YyG0CuZ+DQqb0LITELxo9nN8S+mpj7rXC5LzZ3eSpwpoLS4pDDyaTXz37O9hnbqA1CUpvGwcdVWLkiaB3QC/XfiWCZ3VAT3V/J85ea5+5w8Uq/w3/QgFg/mzx7GZlq3o2PJv/VUscOWGQw743/+uDwpt9LsWkJmr/qL3D8OkNPBgReKvOSmiHS/xp6IUS6Q96I0lQ/C/5bwqDQjYB0gSxKyW/bZc+Xg4w5KEYdIC0yfx5AVtrQx6j4W518OkjLo6/e5RMuoaQP0rbOq367rD3dl6/3Dc/MRtdsPAKx6FpJcwWdQpjEDJDKGJ2RUdkX0QnUAItnUZhMZ+QfLAq1m/YHHJH8wsbkBzViM2pHMmPxCYr57/eM8rQ9wUzi2UgxaKOU0SvxC3SCntCSqfSw2MdKFCeTaEK9LMOlT+VsHNLIH5JTFYAjVSdAW+S570X/z5yKhAYv+mRG5Uih4pFkXsTiPsn9OYL1YF5RwIEwuvJ/NyUaJPkX04FrPRQObfzjhuQn0NuYSCCplSEwtEqcaW10nebCgN6of/CUogvmVmiwahXWCFlVVbX9LTQoOuIAOZOR2YAKsbPf41ImKk9Y6RPUt0oir0pchY9XoddifJTpmpqAlFI62mrNT8SmXMaK32pb99YceM0iVOqeURLxxqdQltalFy6qdya/4pG6Eyi0Va7+pgJVYR/VslTnIp+PUQ0MDKqvlJFCQDJg/byShYwjRhUNytxh6hFaYud7RJ1WStThQ6/fGzMaoeRRbPpJw50BZynT8mv4ZcZUkkYfZBR1ohAOn18aJlXWISo6/Y5HF0qAhsS8JsXKUnhYekA9ZvXmgdOULBrMqaBTCMkQPuAPIsIVk06C8Lpyi/Q2iDAepYKlJWPi2xSoN1VKLgyXMI+8gW+5U95HMWI+l8A1VPABf+W+znGkLssziQpkVVhyEYXzRSwt1hjL6bDPi1CyrG6lfUZQ3xHyXeJ0RwTgMDR2Du7IycLHBahJwij9Qc9VQdpuy8O1eQWGhwsFMMTzMLa7lpi4fk8kgQqQMTutNMNtzgRbjnTRoxboDCK9qvg3n0XBEkKuVSyW0R+WRHRA+CODFsoDfYQT+ou1Wi0I4BMyyV+/BxaC/AUsCoEvnoGwQD2dRtZsUfnUQM/mVUqSyG1FYRx6YWDFkmWjZAQQoq2WaqvrkAqAoQaB1FgRFZKbAqbXYRTPMGJrqY6jDKVCWTWAYkp3bfnBaLdJFM4r150rdF448nqO/+f3P5qrmsPchpZU3doUUyQRz13iWRwv5NHensX+g45vPRGgzavRIkDVK6kQAbgcyRmNmD8KFZdIg2BMvcuRxhaVBywQhfQhQHEA+J3kGB0VjIjHgSPbuYzN8AT2mKpWz2zy/8xU8DInoOUsu6OKfTSBwVwSZKaH5AOLybNVC3qGRBneVxxqlNgG1lSrUnkMGcNfYvADKuNRFkc8Ajq5PqlRoyGp3YDEtsNiX5ubrsW+D1U3HcW+UIzGbEaDSTUfq6lbE8NJfZ8rQnZmEQCjp8tZenEwuJVcYBfNEWXIqYoLJKcQ/Io1EtKl65HkjC7YkdqZRZBI0Hkpkoppq/s2ZVWyFo2miS7kgHqxRFwKqKGgNZcLKpE91cJsIrwZFVOVULhkwSqdn2L6WZRemwLFAm+YmM4X5t1i4nEo4ytyuSKQ7dPcoS1HNOJU+yLmiXwFoGvI+qmcHxbf+PZF/9EuUIE6CeGNKteNV1mVEzfHW6S0FSDAySxzbhaQ6TrPx2e/mNaGZ1e8WxXLjlzqZh7txzAMNvFkcZxuD5aLRRJ/QKtKH26i9ZeqmSPC2JSd3/xrLjD47dVPFltQRqgGx5eYXR2kTANOq5060ktjB32r5ln3gsCxchBVft7ulb26FqDYMTQpKLp7a1D0IBWgFAz/uHeVfgY56cyd1M6eVKEZGsK1gday1WY6JYPJMkbEpgnlCcD9QMaUC6g7NPDCIFDZrgdmTSwuwVoDhNE6V3spOc+fp+D54/x9buHvAx439dX+iv45SkFY6aHzBj8Rin4MOSNWgRPDdtJqqAVjbUChU9A6HZ+iolBX30uZg3yqMybXSZ62JTeecl2tDWEG51jiHEucY8n9OpY4L49d8PJwDhc1Dhdl84dJ0UPjGIMJjAFXXwPt0MAj/cMgtbZJFoMew7aUreBEd88KaE0FtfGi5TO50jJoiBdiMERbuuw8ttPV+8pXypJEczrawkORDGwuysSgVIa2E4uaU5l71UwZ/Llzq554h9RvFdqYgnK5cN1UQ4wVirjPOly7VJouKvoQeyIyUHcoc/1O79By5ZoVEtYyeG7Vr/ZX0QMNgk0NukCCEUn1JqvUJpmNkcPqKcqpPeUK7UkhiS1sniZgyIVjgWQ8KGvSOEyPrWIR6yuFmi+Mgsddl6d5XYpqm0Yl05x+PlWX4ev9jamcPlWWLa7ITWxCp3HvlV8NeWckvLsOgHQipBMhnQjpYhOc1OpiE562qOxiE1xsgotNcLEJLjbBxSa42AQXm+BiE1xsgotNcLEJLjahWexzsQkuNsHFJrjYBBeb4GITHp/Hu4tNeCgn9RBjE7YXinAK+I38HUrpKqngO5NC9n6iEry8OlhLhtYF+Gp/H20iddEL9l2pWRw8APDkbgAqG2Mc+ssKb4PCnmsJPFMk4AQdY0pSeousx6f6c92VYIgnHvmgFIrrJzXd+8L9G/UkA6ZySzcHT6h2lcETJ/gJ1E4NkROqkTStTNiEYaN2OLFphxnv01bbLt2o7dijHHoIn4AzxjWVuTrrRB247/x9nL+P8/dx/j7O38f5++yI4vdR+/u0c+PdjEz2qrzkn8KYfA+r3W0x7LCtGJatZ4XY5OSlRy0vaTEHW4TRlA30aQ3QUQuQmlb3ApFIJSEwX86pYCJOGWJZQkNQa6dNeYgJi73ZQCObvAQFsfxEuxagN16jKIWt0SfP6mEKdGb9+to/DnwNeJwrJ2H86GqlrYci8/TvN2K+rbSVnk6YilyTzSJZJ1w54coJV064csKVE66ccOWCKVwwhQumcMEULpjCBVO4YAoXTOGCKVwwhQumcMEULpjCBVO4YAoXTHHfVMAFU7hgCueiv5Mu+i6Y4qGc1BMOpnCOO0/HccdVfSj68gB1ReSXtPC6Udi8Mm7hZ/y0wtlGNSrGLRhfmpSXdm40rvCEc3Rxji7O0cUVnrC8TpzzhSv64Io+lM1Nu6OKc0UfXBZ/V/TBXZcHWvShsqDDirhvfX9dQQcnmjnR7ImKZi4GwcUg7KwzytMRg10MgotBcDEILgbBxSC4GAQXg+BiEFwMgotBcDEILgbBxSA0i30uBsHFILgYBBeD4GIQXAzC4/NsdzEID+WknnAMgivo8PgKOrjYkqcVW/LEA0kUlbWSwqJrQL2PiuZpQRxpEDrsVje3KNCh6So01bh770tKK2722GQCtOAKUtkqXcoA9FBHX9plo63pns9KK8PgKg2Q0dKRkeNUJ/Lz+9OKBLXYUVqWQLs9yFxGtEQhh9pOvnqaMZXK4yKTPJ5J4hnhRGluUnWN9gEeEvBbVc4UWneK5kPlxqEbkWRBKPoQzW27RU4yJaiHVn1B2RRGxNdqi1AEyyPCPnOJg9WOgQl3Yy4SRuDyT7X3sozB2yS3H30iQ4KsPDQrrklZW+b0UpsHFB0mPp9MYPuM2AL7iqYoGpMoESA518clpVfroYUnZbzSNgDftJB933FVXZwCU3yQf6rwIiF5tDJHD+/eWdBWFDdqLuE7YOUau3mmf1iwaJTeO603nnuLw8NeiWLnJk/HdlG8jtNyUbzmo/KfNL1vHdqLnMMA7Th5zqQ7J2X5WbViiQIu44HpZDNCP3IZW2YHWWJ4oAF4mgYWGckl3DdUZofLnC2UrIlzoqNsr2IS9LpGdJDyuQdI9PgcrmuO5CGeXXPQw32krHrU/f26OZR7cf0MBRc5bA1eFNzvE60XKQrjrSgn3giFqeQWaaLzC3R+gc4v0PkFOr/AR+sX6PzpnD+d86dz/nTOn8750+2iP51zmHMOc/fpMOe81J68l1pRiYM+O9cQL1PO2eDybDzRPBsr07LY9wZhcbfG3Zrb++91NFzdyr/uW+qT9ypLxP3ZB2vtfsWlNZr26sy/q6x+OX6hbK7FQft3Zf9L7UHODlhj8susabUmP7C6KTdi2cJGp/RrlVa6N/hJu/bkhJoCfsR20mqo2dgJamuynHaQR6hee7Eb9rvt5c8t2Ikq6Ez6MZ8OOaUylTzq96FSdSA+JedaeX3e6xPGlQaaRPSa4EMiak/IczacDsl5T14O6Ng7OHx53nvRJ9cz7qFa+Tqii0Va1XwggcJTSS6ObY3KEfkWZyL/B4f+14s+Qc+zv31499OACdCB+aY8t6Y9IFqRiy/nvRmjPovkee/oy3nvr/jHAIjUee/ovId2qPNefzgc3tyo/FQ6+wwoL5Mg5ouAoYjCPaJH0iuyFCXHiLBwCdxjavnyqDy7Nxkoa/dAmVEG3EcohsPhea9f8V0Zb7I2NzcXL8qngHqe857i5ylZROAWaGRZbaKDiHLg/yu3DG4d5QJO6yI1uR2da3X7ee+iD6mS4JYMqy1hVoO8teZCiR0XJUvTMDUkXQzJcSBDYBKu4PAr2ubMShckQYd6crFK03WhNK8JG5JUG6/FHG2TTKFWVjtrGRXmOPhahg3tVvXLrDdeXYC+ThtW1WYY4yg3fpOApWIA0jblXag1DMm7OY/1eVlP/QLcLhU3DUhwETF8WUodbfweSxnQG6IsLgfz5UA9dEUhkR5IJiQHg8+Dt7GV7KQlrRdcS0me5Ro+M76v+cemk61iS+2HiqeFXLbnsUUuE1mWuQEdU5Wj67PiiQ7TJ/kMhnmmXuUz1BjYNr18Ktm83y+ihpy3q+1FAFjPeLCCecVckywnLCTyq+uub2Jxf1pcQ9V0SPQea6JeHAgcjkNUEmUOBEoDbt6LJILlbETjJdiC/L7e57610Zrgyqo7dQ1cXqbQqL7nu2/1c4YdZ9i5A8POfRg0Hozq22lCnU7LaULdrdlNTeinyszTBxW41Aoy0d5R95d52jnMOodZ5zDrHGadw6xzmHUOs85h1jnMOr3KI9SrOIdZ5zDrHGadw6xzmHUOs05N7BR+Tk3sbs3OOMy6/JMu/+QOe+g+cXdcpY9bP9vO3hfu36inGbCYrfboVe0qPXpP8JPxQ6px51WNZMFbKeX7djjjzkPJYtc5l5wy7xE+gaKg11RaoloAFYzgwDaY4cxZ/5z1z1n/nPXPWf+c9c9Z/5z1z1n/nPXPWf+c9c9Z/5z1z1n/nPXPWf+c9c/ZcZz1z92ax2P9c7UzHnjtDGeZ62qZ0wa1rFqZPrUB6tSBrdW8ELCbqc0NJOY5FUzEqelFFpBNH1VdUK+Lx4plAivCUsvBio0xPbEWkCphpRhupe2WQ8BPrapsTFjszSrNfZANSdlUlFIM7S+Ntr/3LI44uypa/57JQkYaWIGFCzMu2JkF78gsSAnUQAuYyRfDJ2SyWVztrIDOCuisgM4K6KyAzgrorIDOCuisgM4K6KyAzgrorIDOCuisgM4K6KyAzgro7DnOCuhujbMCOivgw7UCugoaRcMgsAMYB5q0ML8phF9pf/tZpbduNrmpRq0MblZ+71oz20MxdvVdhQ9X4cNV+HAVPlyFj9tU+HCVMlyljMdVKcPZMVyNCFcjwqlwHpYKxyn+3K1ZQ/FXWfNhRTIYfdFczQfn7+n8PZ2/p/P3dP6ezt/T+Xs6f0/n7+n0JM7f0/l7On9P5+/p/D2dv6fz93QKPKf2dbdm527N7vh7upoPj6/mg/PjfZp+vE/caVcRYiubD/rH4gm3U5VorhykmAZZxW51c7uiHntGo7AIZQtHY2idKYcyL+MPIIxk4jR5Y+nGS97G0LjC19hWpwO7HVXYG7XYhWJPXxvHlM/V0pgbkOrjs3AOyrd0UF5lEcZT90IYNQarx5sZ8y6Jou9DrWJVJ4m/5NTkuHFhEnvhHLmYOzYg1yj3nTL/KSrzM1VLnaVtpU7kppmgu+gnxzU5rqmGa0IWpAUbs1jAh8UCf1yEAfc4k3tf8F9L/HFOL9koYok0CKkyekpHWpgRgDm6YlE8SDvanM0b9RGQrQ72sN4dUXODRE6J6a5/LLE9eiTkfKwxBui84TcNpUxWusE1DwJwHQhCMWUROB2wz16QSH7FgiXRg2mXC2uaIfk+iRAdJzrYS7fRw8oZ0A4yDXNqjJoTyTY/4f5NzrRZk3gRT63AuhQIXR5ecnoybGRv/lfEJr2j3h/2gAEJIRem3FNfpb4xoyThfi4LY3pVVkKid2UbQKzByrWYJmNJ23Jvt7nZrclQC8gNpCMvDALFwA++0c5Ir/7jPzYIOJlQHiRRN36zxQoAyZtVDLxwPg/FQE/V2yCNKS82hzuAVNfRHNX1iBwvFoolP9M9bApUheGnTLCIBsFykOo5GxD+7ywKBzGYwYZqa4YWsHKYgtlADACFZ5i4BVXIXKaQbYc4vBGl04T7ePUr09dqCpDrO1B9B7rvIOAyzlGCH7mMSa4LUV3I8fEPP5+elAXdLE8qDAaK3eNc95Ncd5SI3n5/XI7R2lgy263gkZX7QswYd4A4Dr5qwhztQTWo4kFjiqbbtr0nP5/QYf5leTSmQThtevb42la/9nEYXs5pdLnyaZuGAxsBDZ4PfLaIGPqIvsAXXt2w/O6/1c1IoVn5fsnqtvf3jgcvO73kSujv9Am/XvmEm2G8v7eb3a70zDb3mqsX/fwku9FrkP/37Cq8hJ1axSE0tbDzdRhwKg206JNrpAXQBmUbBrHPE3oFSsEJATF1CunFF8zjNOC/M9+wescWq3e8WJCPywXyc77yBUsl2zDoHfUO9w9fDvZfDg6++bi/f4T/+4+ecp3spahk5Fsg14q61tF2QYYZwtog8tv7Yv45WlGXuwM21CW7aWXjygrelTeyvpR3ZfN6tGgtcZN48c7Fsfbot3Fft4WBuZ8i4Sa02w42h3nXErwc1lwHa2qcV1eipAPqm7K4Dd77gcVtkd73UA+FWRUyHO5rxn31e7stxKcOJkV+g4NXTfivBXwO+XVFfo6n3B52BJwILmWVbh0dcKMK62uDHt+ojDwtMWTaGhLWOOy4QlXftLW7gSDbgfjEcaRDZeugMoWCapNhdkBmOk9mC2Rm0ma2Q2Zp/sxUd898h9RWILXGLd4NpNYOxCeO1JzUe5fIULsYr9YWqkCa0YJO2UpriQ66wbbKLGL/UraG6Eyp5muFhr7Q4t4smP3qLhk8phdA2rNdRVikftOQ/ZawCP3+ajyDf0KXOLiQyqNPQnw7rt/yB+YiZlOdf1k7cb/eRx9gPgcnr4P9/f0uthp7l+/URHOw0kRTCdqjsKrmrvYqDKhD0s5wG4pSb+5jJvBuwyhbeM8rTBEr5MYcukgFROvXarnQ2rh6cTDf6H49H9ZL0N1iKgs3p1mXcg/+oEHAsnbojrikEQQ7h0k8msXzwLz8w8MKms3miwCghNcHGagVTJCxTAe7/RndCq9Y5HMvJhh5arIe6yiBDS9FT81aWTka99ghr206irVFUEYY7MT/7H2x/mppM80hudQ4WofkUvtYE5KraVSN5PIQP2iZsFIirEAfVftzB3ZPFFlXWz4dTthVnNDOEph70MrkV/ealbWn6SlnBj77WmCWEChpYGIXeSzJXz++/bFe7/PYn3mtre/u2ZjBweFqE5975Q9RbDHWrgb9cO75p4rgOgyQav6akEBNoyfz0O9PPmpSJzv5aGvyUeMeOyy5C7zQWvrhPXMLerWZIKqwqOmVx6ODWN/yHELV+W6Kl8dqm79qVvsf+W8J99OmVnII5K9UNK8KJ6cR1LKSRD9I0MFKXSqHN4UnPiKEmb7o1phzxdFsC4l2wjxtYXRIaBeQkHUFV6Ehndhm5NFVRirdcuBRZaL68OGvA4+WjVMfPvyVvIHUBRNMBk90PUHMK/P8zfGLmqidVd3uH3u0MgmtWsZdmolWx+K1hvZhv2udCJa8OV75nGFHjhMf042UJK/cx+1KXlxMIirjKPFiiJiWcqYe2+0sR9Ybpr4/oKLqFR/7vvYLrLsey+qHfOz7slXPHXvLFdaetntwV6qTr5uecmdgn/Jr3p0X29qUktHovS9edrotDSnWmzdmlMpnbxTtouuzTyPMGno2KGBzC3oUepm2gWardnpHYs5ag+nQyi6gFWONWYlW1MWNlyNdAFqlpCz8hh0knQcj66GuVFOYYQbp0MZPBYYaWENBos5y8yoHlg/Hb38kTHjRUqWWtgbB1B2nehBTjDeqcXJJWZSG8aBkHRqTpORTtCOZdE3o5gilM8i5wBFK0+qqybbrJPfZfBGiqnFAuMovfeqfERpgOjusRnUuaBkEnJ75/UIR6UIzLI6lkxLqUuSH+/s6L9/wXJyLP/7xlzC6hHpWuFWY8xRGKuzB0R//eC4OhuQNDQJVayFdBdQT094Z6b6QMsR6l079s3NxOCRaYWnWmy94//zs54/kouYa3ly8wLUcnQtCyCAtD67StY4smLEezIVpVryqI8ng0h+R/wM6LExPKGO2IAf/enEuXg7JG+MwrlKLZx2fSbJIxgH3yCVbgg54GSYRYZ9jFkH9guqzPxf37GyZJlgtP+MtkNZW1K540euvOXmePZQXm2aoq+5FgQpWSgJ40EWIdbE16y2opG+n/tk9wP1q/2UN3BZ6E2GsKyapbPxhNKVCF326Y4Jdk2czfU3m0iLMk66ZNzcDYIN7WulGKOpz9kj4IK0E5cXT2EbKojKfMCwyCBuRoDqwOh6f7yG4K732K5gcVIzCEHrFpmpqhQ//hzenb8kP0IrYrSpVoxVNTV2eOLSrnl1xinTsw1LGbI4X800USjnwwznlIiNYb7EWJpSjIs9h+AaVzB3RkjsV07LJvMnI7Kk1YTnaoI0RKD8U5LL+vAgwc6+GN15iAl6onNXLUevFxoAojtUeCl1yZP2pYYDBq4cQ9HGwX4j66KThr3qN21IDenw+Utiolci+GsBHTZsaRPZ3Frsj+2XOXaoaY7htZZerbr23ZBmoIpYenw81tbp9gqu1qOTeF/xvS2VkBc3USskKqlnt4V1xvRuSXlW0zpLUl+7RM01sF+EiCVZEDD9uumgO9Q41pRUiQdXpqfviD3t1SPB75dwVh7qp4ojKIz3sNMR3hAN3CY218zOvQDHgbb4Kvyj34zbIJUsrXNHarooD3lGqODKZM+BUZN+x7Q8WPVXwg403YdPoJeMFW7GCp8JH+Rmg01gIbt207po7bPiUOEJ02N80QwjV5G+nNYERVipNfpZYhamFziTf0uHeHVeZDA53Q2nSCQ64srdWnaSD2PuskN9thlUj3GxcyfP6aSh5CuhjmzoeRJ0dVTw14DkNz6Oj54qw3rmCB6fd+wL/2Yx6J0feG7Q7uZu9SrmTa+x0Oy0IuD7QHVDt5M/uFpqd3EBOlNkpxc5K7HV7vU49YrHUOs1YpSDL52+mkxweKOJZrbTZKuZIebsNqWwcmnuqHF5bhc1iNGG+xp6jaURF3EIjsxhknQaqU039PXBzytoSPUG1CsZ4fZbak/Aa/OXGS1UkVRfR3a2YoDrBsHpBW3PULx/nCA6mvaTYDO+jkBWr7+SdvN3Ss1kppMF3GRdKOK8K26t+odr7rSrXo6jclHqH+Or2yNLknd5LWLtP5vRSGbvORbqh2NMaLg5JiMWPDfYySTUknTObp7K9UtFz/WOGIcg8kTEZM6i8rOrL1nUk7wQbxHzOyIILwOrnIms6mCM7VrEWSTwqwOd0zAzwzB+SY2EgOBceFeknQmMyD2VMJvyqQt6U8J0SAGN4v37h5dwHxbG3jrTUXR1pMLom3ay8nHeJczskr2yE1eHbO8S3KX6swrjrsVLg7ERVu1basCq0rTtVh162QttWwGVVe1WuvoSPSAQnLFLUq9fcPxfjJIYIJy6tuvbtUfk9IzfbJ4BWTVVIoXR6AqaEOt701uXm1866ee84riIqtDpKowJOP2RSRZh8VkzODkRrtNlXh4/vEB+3VfNVIU3oUVLrtUSX71kccXZllwOsvBTjJXps/Xx6cq+y6MNCaDX5Re8dmz0qVLZyRx0eu0M8pnDRWkzlJVuuVMddsuUgFyiNZo54xgZ1DUqYEZCB3lQIXi42Ll0uWewRhbE6BMniGDP6ARdIxcNR1q3ahjvLedyY3Lw1lI/igZfv4hPQ+Os0HhAjzsV0gBjgdpmUywhCp1NujSOstAyt0YSpsffgMMVmFF/azywc/5N5gP4XEZwNJMqDr5dsOTI7MQJftOiKBiOfKmzfAuyGAZSmzID9a9Ncnzoma959BNkFUIcj79H5oyOaa50mGQbaw+u+OutQGTGqjhZSzPuUv8fP1s0qmzLPWDQJ5yA65rDdriG5lU4PpZXuxvtugMs954fznPUDXf2cg3BqpaxF0rxSIKJJPINNUKc+gCFU/ZjazyWBSJ9GvinRTSvEIUrAWAt6leqeFJK/Yf9dwgSZ5ijgcx4XHeyL9V0Z0d7xRKQu9kE4JUyAvkyCpj/SqrNhzj+/3uf+8DUGTtD5AmIl4K8UJBUIqTjLFWB5sygUYRBOuUcDIsMIs56FERgxjEka9r4SKhlHXExtoHCGXr/HBAQC/Gr+pNLrfbLBVR8skCUXXilMoQwuo1HAmYwJuwIXPzD4ypjOF7CB2KsZTggooQgm8vAcAzQyoA73D/cH+18N9g8+7r8+OlR1cXNOdSIuh4mUoYQ07VuF8WC/AsbdDhE5fL0y3qbggMyDmEWgKQaHLYI9huQtjb0ZmYc+AxsaEKsIknCjh9MFtnm3uCDPFxGbsChi/gtiLjGbUs+0GbHP1IsvyCSg0+G5GJATBSZ5LsJsmH6u9V8mNJDsAsZLhGTxiyMik7E6NjJHsP7nv/5bd/nL/9UnNvTC+UVaIwty/eGtUGUbSDyjoAUFWyGC8R1MpAY7wuRnBpa/sN9Kq8oBh4n5EAA2nA4NFLBzNiT/u9zFgBaKYKnggU4aGqD/PC6uswAaHAIYOy/Ic1OLogzaiyH5ZcYEGYeQMzHC1G79qiXE9JJJAkWlmc+Ep3IgxohAYYshTyK01gB6QSIxMWEOIsF+uxiSX2CHq2aAZIscTbr4M9T2SCDlox7sz2lJDR73wT00+f33pbUHaUNlje0eJYZF+ApvQUHY/CJwA5Fw6WVdwDJwX5iv1hJA+kQZM+rDCy2cGxfTStQzDsOAUWG/VrzrNsKGaeu9i6vhzcqnD5G2L2KdD29MvctrGkFRoPmCxlzxUARs45ZVHLhP5p8LzGM4QWwwBK/cbPFqpWscgwG/oq687a8dBOE1898tmpf5DhmpMKOXF7rjhYG6Je1kv1mUE/8Q7DdQNFjxoMDXRMuRF/qsO1x27y0ARxeLEQywxobpnlsCKuHrHKLquAWQIrocrQOR6rcFgDTe7AqPfoYanHNxkVGCBYjyEcryGRJ67lHJBpIJyWN+xV4orKQJQxlRnwtA0lBiskQrasiEBQCg+KkII1ZCD113SonEMGp+07i/6L5l3F9s4fwEaCe18NodJrv3FoDTuHYVXJsnFuQ5Lk/Pf0FSXhgvRyxZMCEZ9n9x23vyqZmYTDgLfNm8B2/C+ZwOJANIYflGMFZ9QX5QCW+YVScPlSvDc4GPKJzzOIYc1sBo6l7AbJmU1c1rzAloFAXIviZlfcCGsJK+piF9nZZ3ROO+wkt93GgdBt/ablivLbjL6j2rq6W2gPNRKNGq1Dar1GiYnp/8CHuxXcMeKiK0KirVaN0+VBsVZf/kcWst2T95bOZXKrLqAB69pX87/Uh062o1mArh0YANrrnP6rqSiHmhUBUKmE6xnn7nE+YtvYBpCfO+1WO7ro7IJ6zYt0mWyuZ/q9wd1nUa6eFyMzAaebMV1AC4JS5SfomoTiS8QgdjdeqnJ33zb6Mk6RML56D6FBgkpcq2v8xCGQM4TbT+5hYqOgNihQLM6FuQpr38058ImFTJmE1CUxwgiSKjPOusLltfY9cW5A2A2IpC1qOBuyONjTalVQA+CppYQuDbJXAWddkKddv7cilC7zJFTzrAohPBq/ERrt6wGrtPasgZSC9cML+qt54BcRc4DBeJHDDCeRMGmi7um/bpyYr73HrKWgzSpRhI9WEQn8WUB1tHIco23eQSXAPfjhWiaLeLDs9tD8+1C8dHNKdSKSnvuVU4TSUzUd58KRM/qPlYy9xjqgjVsIm5r2mtDC5g/gEFE6HI30eou9erIHPqY2YKTEeReiPcR6bF+7eqdxpYjXDTxizeadxslO4G7a7ePV4LZrab4QNHKKgxKww5tzzSRbdyGBuQt9QQnbJJplkokdreZvL8SF0gUJyBwne3BCE31Bq7YKnvNrIXtjqwOzQq+fKtU2hWjdcemu1lX325I9lXW8Gx45qc/ZImp6v2uUSWt5p+FOcZwTytch20gfNRsJ8lVmplaVjocFdqZ5U6SrOWt5fK7Rwqcs8PZ7XsagbPwO6EbplQJ3NQ18APZwMTKVIS1rHC5j9YFJKP0DOX04WchH8lVs/qnG7AXtoNkclsGnb3Pbc7bcxaSKI5tIVFURi1DWOZMynplEnA4Om/u3eVCf5W3oxfZgxzT2A8yNkp8cCmeE0l0T0mSWAh5syHKOcylNpJ4Y9PKl4GsfaqrfACztSNaElf0/Y3/V5mm2zbO+sAIFL/nQiWxoTb840/eUsBwTQH0qqqgLb1DtOtFU3mEZPtl5CqrKG32raymjuLX5csuuIeSJaXTFjnmKqcWie47PcCCkYOxoSGtjgUhu9yEaBgfckX5mp0XVXAKGjTFmEUj5IoaCsHFnrlB+pyS0rdCkNFa4wTwSAKDbbPCY9SjqKe7e4GNL3p60igDiu2OlS9i3A2+ud1PLLfR/nOma8pwfjbLx/BA+OKBhw9PIbkrUo2ZrwalLaTXLzc359LdLi9OJy9ej2/GJK/YydMN5YIUAjTiB0RCN5IJHkeRuT/+3/liz6ZQ/WfPpn3yWxIyE8hhrXRWPuRKkf8FC7lCMOlwewAXJovjap/5wKSFizioU/CXG6fqjeUaQe+3t+fpZm4svhCg3z7BvVbqPzTCp6wO6F62FxizVI3HOTznl2Fl+sHNu9kWHSOCQNWc82Y6DpGU+tJ12NGddTp+vyoHSz9wPjRXLj0hnjIKqTchmkpdsNXizyCeqyjOp4CuIBKrgI2n1xD6pQ4hKACPBA4obyPUSPenBx89Yp9s08HEzphg1d/evVyMB6PvcErus/8VxPv61cHrxWSaZXjsOtlczy+4/Edj+94fMfj35qcbIz3XRuHO/b3/mLcu7CgrfNV5HWoONEoZRMbUsbW8qiqfJL6Usms6jyXddcOezZpTqXJ/5Vv+QBY1dWVPiACs/XGbPIB5g++lU0lK24U3R/cDnF0RRyll7lu/tMmm0rD8/+hy1Wpt5o8usf/8J791D16pyzbJMIxejOIaO2sOWtAOZrbXRPr2LqxB4d17iKZoEpgrFBJHI5oEIwMyzniYhRG05bgtxgI5Dn4zsU0/dYF1+X61ei8avMP+g+QN0s63n2Hpx8Gc2YEvI5mhogtAuo1Ysv3qsn6TBp2d/jyMeLLvPapxfytM7zqa/MQUWzU9cE4HPswcKw+2BZatEUISb5Wx8uYdrk4mYglEtaSfq0NlDEtidWyIVKm1Py+41J22wn6YH9NL+jGI8ryi9xFoPH+ygKbK+E0Kv6HXa63/FRWZuBYLCQiozOzI0XZutxiuz7T1itf4Sq9oh5ninaU/XZARTXuWdYU56zc04pkC6Y8JxHsuqbTY2HxWkytFgxRRV3rR9Zu+daQSSkL9kGL0pGrwXS4JI9L7hVV6PqS7bmZvS/6CrcrH5liGW0DbIdlslqSLbGMVU1yB1GMxbaYvdvkXOBKAm4NnUo13j06sWozDl61KHroMMmDwiTtKiOm+ACT37dCBvkUKKswwfcMsvZaZRIdPlgdm7XrvEU7GB06eEhCSosiYSmy0Oa8dvhCW/baowxjzKNPHlfsjBhUX+5r11FVazAdttoh5qW1a6Q6xEFsspmuVrGYxjaK+hDTKNW66XsBrUqoCRvaYo3V+OlpTbhQ2fZa44y6fd4arsgDKhdpmrZ1gHscGMJaGYtWYocz1foj7MOW8YK1jxpJZE91Q/oSPWCqM4lbpoW0OxtJSaOoqjLJJmOqytUERg5KpvyKVWGNWoGp60C7xRXFHRNBtn/LZuS1xCn7WWuvmy2jHp0FZxXyaQ2mQ0J5Ucr+tl0hai381C6nYyNy2oMEY+2s1jkUNYB+A22UrVPf5G4azEN0hxVaHGiF2Rsl5uhWJlxM0757vNG9IKctWtI3muy9shadugljqJPGeGQOkkH9MOUuo8ZqzgZuCodk8W8TlXMPw+DA6+h2CDyFE+/ittE4zLQ+Fq+G1eHyncPlQ4Vsb5/3TNJ5MPLAoXACE7VI00vnwcDuoPyPrF/AH6rC7+jD8dsfidWM6GbVcTkUriAXubI7wGra7lfPpBqUCS9a4gCl8Yfn4jvqzYq/m7o9efYVtAvP+QSqWEkm4hfwjyseJtLuLlXNnl2gEhXYt1DAG15xVuA221FNCduWtj3o9+ZcaHR904II5MF4Wyq1W+VMtRbhqANsVSnErJhp1bUkP5+emKpXcBW9mjpQP5+erCIuWf2m1+Pxq/HLycA79A8Gr9if6ODryTfjwYH/kr2avKZ/Gn/l9Vum12jvSVb56LaVTtOaB/xfR7BNrfxfW4D6sIPFTUbNemy1xeTuiLGzWXPIexsUZO9L+hNegxaKizJRAdGgQFNK4kHVjakiKFjGG4WCBfOg7SqyAXgBkpn9DNV8FKmAPGRYK9cmFpX0gfAJSQ9qRwSK4oEUpiyYIrKMJVU7PNyE7aiLWqQSQ98RCitir6q6GZXw+SGTWDqDfVa1yHagdMbKzXRI9s6RbDvFSxscu7dg8/XwLHTMudGF1yIIqZ/iOvu+cEHOvnurc0KWHep01zxj3XAkzyRZJOOAe5jSMTd4WhFVo23ml1AR+Qh5IpnwFyEXMSSKTCSbJAF2XWBcCCBuhMXqGocV0SPYByGlUkLjUORgDsWET3X6HIfWb4fW4ZDt+Sccn9uMUV/rEN8o/DM44XIRQr29mri4Kk47jqk3gxIqf8aBYbP+ct4rvqHhgs3Pez1EPzXY7jM8jQEC13LuAfzPt9/9cPoTefPd+4+n35++Of74Hf56Lt6env5w/M83b47/5bfp8fXpt8fT078dn351uZwH33/15pePw+HwXAyHQ3tnNGT4CYf57qeTiqEfDX0q3gxHmu6TNCFp2BB5wnS9bKXzQ5lEqY72b/kYY/xcwmllQQDbyQwB1hwEuebxTGc+XkV51NGkcSrnwm4GEsI8vCoomQp0CD6lYoQMwnhITsF8WiVaqLcq++eCx+SaBwHkaPYZVIa+Qr0EzBgxmBMqS5+LPHVkQiYRkwRviB9eC0zbnGZRHi/TwlcdhJ1z4SeRobFxRIXC1TonMxa+Dq/h+6l/JlWi6CyTgFLb5yirHJLjJA7nSk2lYTsXM7pYMCHJy/1caVJata3PJMFMjopS74q2bpO0GiOF8TrfKdWueWlOFluD1q3aS0fv7pzeaQLVgtwxqr34VmYXwqapH7IydcNvlZ7HykqtPxe1WIqS6DbKgm1nCYBe5HrGhELcF8YJldH4AtH3xZTG7JouzU9RikkmNJD3qKi6BzdiPJWRzybgcGdnQ23rTJyd1J2Wfm4Mf2qA7WEjk8Itr3cVzhoekQ/QcmuugAqOBlzCfKyW+XkwCaMpG8y478OyMYlvC/xi5XkHXrqQ9/1mL2KTiMnZamZa9VQbBeEP2G1A8x8KKXuwDWjL7XTVFRgJ22nuNmO4lPdfKdV1NW4pZbTfcIhCjgPbleyMNTu8tSJ3hTiEw0a2ZAVsDxuTaLYkt7QWZe1084/YfNvuxfkn25xSRiGBjSCUlsJ5AZ8oybwRnSg+dxU2+SEvSJM3WFqAfGBexJQiuHgjlawL+S4VBgoDqADUwMc8SlyzjYolRtA39R0kHsIoXx2hXOcgTwJyeo2L3EgXqOIAeUxp6JnfJzwm2slDGq2IkezTcgRgHQgjH8pjhITP58znNGbBUs3MCqoUnApnKhdCgYoapqYAVJSC4gAABVadmgOjAdBZBbCSOInYn/Hfqq0eHywOPpcejXzm2zBVVXfQJpOjnsoxyrGUbqY6Ptw/eDXYPxjsH3zcf310uH+0vz88OHz56vU/EAnQxOcxYhPNRbTOhlb5ArcmtGOgQyuvjxWAPVpSc89Uo62Ua2pdNNkToY3y/8PWJZ8//WuFt4/+4jKI1bm6vb5NAjHY3TuVTP+00r0rB9KjeNv459ZetH4gt0vWhe9TJ+qK6bQyJRdRH6qzMumPOxQvuiEmp2v5n4OXHcqa2bt3V2Kdrru2IstWDiL3Cm/9ClvHdcJAe19iOsXr1CYFFr5dk/6q9HpNsqPK11v4uAPWL7PwTU6VvctOCay2+SgBpFa8byUw7j3e+j22yyaFT0sFHxbfFYZGVT4q+8sTfFF1YWS7Q+PK4LgHdesH1SLdEr6m1MRZfFCpWarqTRU+Po1ntR47267k5Aicl8IkHtHFYoTb1t22uTMPuhIi96Zv/aZbZy0CS/JoES6SQPlmrVIHqUj+rL1SDRV/LauJ0GKdb1GVih7Ur8WmoKKlgmjgK7T/7bQ8Fo7ZfdXQ7ZLLl3bwDvVEL/PPvWqUdBVmnOwVbvQJlu7c1p5jxf2/nVan9My0hqfwe7W2p7DuhsTrhZZbeGl36/VTwGYjPXXXhOrFbbkjUvnaPZ3mp9NaFVOkantfijejXY7y0jPUypqmZ5jK/aueYZqZvHTf4hlFuyOYKFWoiyodBG8zu3R3SwnLG9jrpJS5ozdlpRJ3r6n5NbVTpJSeAChVmu6/ktFXXf4sjVOh5S7e6hrFiCMTu3mxWyg0SrdaKzeaLnbe+7bhbmdZowstn0kCIO7IFd9NrqxebeGe224+t7V1DZVcWbscg/VqiBrdg9IirHy6Sgvx4c3p24Ze9/9+W3eeYBKkDh0kpB4+FT773KGT1kK2bk/jOOLjBIJ12ndinzGfl39sde6QJSk70m3hDY/P1WFl2pDd50XVntwdImmb1e4W+pFWShGiW9ZpRtL7sqMY4I6jqczdxttoDwdf/uXWY3bSzmRHs/WXXOAF3Ctu/Yo3q6pRTIH+dHvVTSt9TTWGyJQ22TXUoZo7hyO6da4WfSsCsCESIFs8ONqrrfWHPfc4Wj2OW2peVqtbqu9upnN5jHd3R7lPzMjmKNbuP0qjNaoO+G+hN2qlLKp+mZnGaNf5zjVpyt1yqniGlpppoyxrcfBOOiyHCR4AJjAKrY4q5IgtAupV4IL36kNbZKCbO2zwIOXWymwA6vzd438Aj1+/4paSa72i2soQhA1T7l2W2Hfza4lxBBRgEtEr3SWGyTd56NyHQ63tTLvKIQ6ER2hvAshhWeVIant0dbU6DI8d2o8vGY28WdsJPmBrPIfElKYJ4xmL8KCYT3AAkp1KzeQd3Q9bNjfeid1s2HfqH3i40sE/D9LDdga2EhtZmK6pBirkACA/htNtF2K+pR6+hN5aKeAbFO6QEsQ81h2KRV2bO2mOTdU3pxWE2BZy+vS7h7Tu9xSLYhbxq5750zoekds1uCPf0iawrgqkJ4ElRBIE94YOOin0W6rqS0iklY6+QSefVv9Qus08s6Ty+WJSXRrIUKcWIlQsCebXZSr3HKYdUkk20vT0zYjJCDePIdtQF2/OLeEDdQna44MqkBw+2DY+WGHDqBV/aowXdeJP44t+ei+yyRN1R8hzCZ4n8RZ3kYNv8oMtvc9WhowGw0XuoWpH1xIFfq+eRhbn90ymSeCU2E6lShYPedRAP/Rc/exRofO1eTMqpsx/8TQe/+OWRbTiqEkkWeEOvCM4rwqkJ4L27i4jc1u018kf2ZJU9pQUMJJMysZQ6EreRnUepJ1LbI4RMdLvFakt8m1MUlRV5/yJyiB1SUkKW7UlRFC4Eq0ZoDrwnghSuB9eaFh+g7etfLoCRex9EaHwWH3x0xaoooQp9HvPX6FqfCEKrZ4gxrDMUHAUG03qggOujZTuBietiZIcRto1jNSuTGgRIcGeMn8UhFPelWNRXQe6axELqa8k/VpxoYIg1wpC1dkcyqk/PSzUGkXktnVbGMK+FK3xQzVkDj1sEz0Un+Cm2ZWASkjJj8UQVDHcbigC+g+g/yDtX8QT0IRAE2I1Kd+ucjOHJe6bkSjfDsdM7DK2qHyNG+Yn5hM6okk8g/E9GofwMff3ujbd+YQOcgPVG3ifSVJsudLg+/b7Y+IzLMQAdcGplJds2SdcQNgGFCel5Oz071iBPIzI96cn7w7xDyaiMAigknRfIyTEROTYn3OhApvUBYfCqZKkx6cK8cGsqj4I/OYPyYcEtxXqk1t9sxI22XS6uk2cRALdX5Ig0DniHj0atCYr3KxNTlkauyX+NVfR7p4iuOF2bN15WLtkl66E0qDhTUO7W3h4K+ZvhWnnEzrMY8E2pvDOyFajqU2hWD1cI2LN2uTv03HAqTROs/lblSKytMz0JEOxZE4FnTLAaOBgw0j20gEzYsEm1bKI1cnpiYo+xJJLhrRl7GH65BxSfTRI1VyaXUWnRfgcIr0lIjUY7pbo0/cjkDTE1PxzNKeLenUXXwx0u0GGnqyfFjpfkP1LOW3QsfpK3qqvFUllQAOmxyAwBgmvBfMhJACx6F0HaaS7ZAV4dZU+SyvfvPCZgdkif3Bb6NaRPFe4RURRqOJ7Wq5mzqSkU4wq76X/Xq+7VBSvvAG/zBgGm8D9Oj47JR5cQUjBIFMaaQWcjMMwYFTYNQjVhWIC0kr/in9gbfBPyvMiCeIRF5Nw9e6olE/l+JswpgERpazXxpFWe7RgdUUsZ2dBq3rZwB5gPPaUled5o52G4CuBhPhcwL+5oDC2iZnSs6+ew8TNdMjf3Xb8w/2bfi+GbRk17pkZ35IwVZ5/dFBWQUrVYUVVc+5nsy7MPawIxEpXh01xXdJUxATMETENFxSSb95GyFCeXiLr/tAoosBu8pjNuzyHHG6+Sa8s0KpPRT8i81z65tFaD7C/4qsG+NMGye7pmYWjDPnJk5NazZKN25QjTT//4yYVTdl2DwukcM2ooBaEV8cJWb9VhQtZS64vXAchQxb5JYnwNWrcSdJ7F758uZ1qDbPVS/n2MYH6rA5DmB43/R5XnNkt3z9fGBSAABk882vv4JvD4f7wcHjQ+4SEFjCRnOlJW9Na08skcpDda/9Zd3SbTNIkCYIucVFVYDnuaEPcUQvGiIpRprhpuTqr000fh5iHPp8sR92udaEjDIV3wtcVvVsOk5bjRnxI/XciWOqS1GmJkpEUvBOGyXrd9HcDTXXpZ4mdOcze7+F+841ucbdD1yd9W0QoUQB/slzW/XFULQIrq9Ufe1/yt7JRZ9yCMzOFSGs4M60ia+LMUmXzgkYx95KARjkGrVI9Qo5FjmbNQV01ZqlRjYzZJIwY4TFEgeAXk26wlrvL7cvGObwaXLBFfe8mNDvl89sm11LQcBr1TgsdrONfnHbHaXceiHYnvT8249DvwX+QUiqWxjESd8FIrIjIbsEBWH8MfBZTHuTNIjZqPkm/FxIkzcLrjhyAo+Nd6HjFIeyE+qEJLke/nf7B6R+c/sHpHx6Glac5F3YLTsLUiq/RJeh4+SZdwlvEIyRDbsDIQsCj4yZ2z+j0KFBytf2nPgHFHWlSivXoGh1kGkBzPJjjwRwP9jB4sKfMCd0f18N83hwy1dIOY3VX/K1Fn29rpInYPLxiAyoGesxBxkIPwJ0eP9WwXe+xs5WRi2SddSUg0ciUlQeg4GevRkEGrUbxszOeOP3dYQdLd2N3dExdL8qOWZLWBt/xSM7O5OxMzs705NmkoWFh2hmcKlOMtjM41bAycdjEyBz7fg12j8NVPEyhr2NgHjwDU+Gi2+GC7Bjvsg7kjm1xbItjWxzbcq9sy/3yIi2S/rbV3mh96+2VNPMkiPkiYAO+kG11M291H3J6JruoZOblft05mftmKO6dk6hXhaw6lx3jIrpC7TgIx0E4DsJxEE7xwds42Q7GSXB5qzBo0Hzk+IPVCo8cMm+n55gXuzieYFecZjYfJV3EAjBD6zqPqy/YjnE4HQB2zI1jbhxz45ibR6oeWcGxaFdcxbFsRj2y9yWjO5tzaOnkwHJ61tFhJe3QmQWyaOyGOZAc9d4hw84O62Fqj37H2JPW4DrmxDEnjjlxzInTvLTSvGzA26Std8npWXtvEou7iNiEf64MTVpPA+PYjx1yKKm6EzvGebSB1DEdjulwTIdjOhzT0Up5shG9ye+hYJt2LMExO7uW/AN6reVcgvOBy6x2S1zTY/bJMxgt/ExqD2nH2I3ucDvmwzEfjvlwzIdjPhRLcNfeJopp6OBvolB6R48TxyrstPtJyo3e0gEFxskvoYAf1ETr+aHUXLwd44A6geyYH8f8OObHMT+P1BdlJUezaW8UnDDNs6Kp0aZ8UpBVWifBCnI/6yZXUZ1vHZec35JNcy9luu8MSK38V9pcjR1jcNYC3TE6jtFxjI5jdJyWp6WW59aeLSVupYWXSwmlt/R4cTzKg+dR6pxcVl+JHWNPukLtOBPHmTjOxHEmT1sF01L7EjCqKUaHokLwqAa6p81y/AiP7Ufze/6S4TdAUapf19z+d0hNIe90O5nfWu82aaYZepTRy8GrJopZBZejio4qOqq4g1RxXcss4tHeY8gkrylGtUQPy9o4QU1pVy0RhRfSloSGdOSHXgJr6UpJVTQJk5qkhnSQjVSmrO+OyYn1uYbAQrN0FJIsgpD6zCeJ8DVe3Clq243W2juwTZJrn+monZjaAKCjvY72Otr7mGivhR4eBQk+03SoVq3+lk65Rz5GVEgeq/J1/cKP21K2F6niCprdzY0yJcCKTuZIcKGkHXzPIfhybdxkPOdxjgCT5wt/AhhmTuMXu06D2zomKidQGsV7sLCBT2PahXjlXk+Zjtq7F4eagbHet4wjLqb2++79X9NhuPAnveILzM3X2lOx4sC3zXGopbaqxtsEnWM37qwSnPVKb/cA+z2axOFIIcm4U72zQsesIlyHMbJaZTf93oQHTGGh9lWkTZeuRddyjHZ+QyT/nY3Gy7jTzbE63fR7VyzCwm0dBki7WN271X2zez2KSm8dmYN75wPU9V9Het/7UriPN3t+eC0A1a4r2Jv+9ZzFiW7RzFukreSCeXi/8nxGB9aisMZN8xe1T3qXrOMVGobKc2hB8oHlqKKlKZ+iuD+gQVzAkTeQ9WYY1iHs69nl5/NQDMxsu4ZgdlP6wJrarVCOwQ230hWmg5TUhGfZlxoNoem7w0a4TmpBs+I7NsKt1AaW4HKc+eY58/VTK9N59oqeIJ/WgEb7MIMZ7qj6R90999u3P5yRd4KcsDkVfnW3fBMcZPNI20KO29EWgUOm+qPkc3lmfq7yYhPs2mQQeyS6oNsgLyq7lAaH1iDccj/q0AubYznygE1pzJA9RQmBh90Kk1f130SdcxikyJJvhNvOYTDchz5ueadgXXWdt0lZ4f8FrJXWqwIgR1IfpLLLv4JxZTdFV9YpN8RoHvpr6GmqBxil7oiwMdR/J4Kl9kwEcryIwqtuQJsuN/07xXdaB9htSzI1YMXidxuDdrqUigQX7iSPotEVDbiPgI1kTOMuKtBS1+2g9X5vvdveeLShGPnIkI2YgLvfBdJy39yAQehdrjme7grDXQvl9r/pA6ocWDPk7SGuHwSw6+KSbxbsJyCrbMXrq41U0El3bAbc+5IilDVC0zNVscoGVCFXnOCXOtFCf6WCJMKQm6Y8xfWCRrqMTcsZFQh317XB9pbfWUSU4oUbNcSVcDku2HmYOQ+zHfQwe7wxTztiFW5D1LMA7HXMLeofA5/FlAd5e4vGwifppyqDix017ajy7ahyfsN3RCtVA5SjyU4z5TRTTjPlNFNOM+U0U4+Vr33iVnT0egLGNfZmnTlrnSwyZbAztJmPvIBWJOWy7FZ5VuQt4B/FVFsfUPpuLNzlWO87MvhvgJ4WUIr9rdquXSFF1N6oHREoVsPnZAsnWzjZwskWTrZwsoWTLR6rbNEgRtwPt8983jXIwbaN742ni81EP4yni4YICJCOVkdB2K2MEQ0YjSzAKt33Yb4xjRhJJPMhPBnYrygMyPWMezPT1yMyGQsWq6YZyYUOMMWpiFkkWDwkpzHhkixCKTkYvSCrpWmdjjEPI5aNHM+o0AVgNYM4XhJFWMS00NaGemfci/v3I121DyfJnfXdhpSMxtPFyrCSSvicRLBjoSU5FPUYiFcOqzrlmEGrBVK0nXgTJddYdypH9N7gV+uASkRPt6DYRo3QN6QrALoB7wm+pdQHjxxYr0SXdiuQtiH5ZcYE0QJX3xpYE0gueMxhZ5G2+hG9Fn0CB+JRQcY5qggNEAKt+MgWAm/cEa6NaedaQjGeLgwkqT9ku4iR0k28Q43aKtpZD5ujnXenTeuqDIJsvKhDghu5YMLP/MjaD1Loa7KtpChoZFBUl2FrRrjp9+D9SD4VNBiFi7jLORZ77pImrJMmx0Ihd6fH6Qhf1u9RKBfK/Nn9Mjy3dqXPqQv2vuSu1Ab87GuYKe1g3cBMGX97m5RQKUOPo/ttys1UKhKO7V7zRMbAC6UcEhmzCUjwPDZskgLWf+pMUDZt7hpseuoatNUpZOBumJ+KhC0twgY2xPw8hKQyu4YOb+eEPGGxN6tDWd/DxyaM9Z7FEWdY408xzTnU5Xlh5KMQGBIeS2LdfId0dh3pFM9+hwSuWtCcvOXkLSdvOXnrsclbTh/egR/ahOdoDT9UUiOXGCLdAjBzhi+Vnjvr1QdEPYMqmNAuFETd3mod+XNLnx1GmUT3wklu989E3Zf2XF3TUe7CVOvS671Ud5K1q4fN8XaOt3O8nePtnhxv156Nq2LZdoAh24Rzn2KGOrr2+UtB59wb5MjkYMriwi96cJvT+4FB8VWbHftgGuXx9d85u0Zk7enUGWUmjuUChYbn4lz88Y8nbBExD17/0R//iGeokX7OCYsJfxFyEcu+9gOkvs9hZvR/oEEQXqvB9aSgbIOzN4gO/j4Xxt8P2FD070shcfFJq9mluquwVSV8FkzRJq5nJYiOebo75ul2sTiDlxuJxmkXgnN3FNVP0V36grdGY08U2s+/CKdISel2DfHbqEKlmvQW4nIr21QQ40LYYtXx1pHntJGtO0npbBQmjjrvNnW+k3Tht0fZBcxpjbhu8HDDLd8hzmMNoB0v4ngRx4s8ZMG/KwNxawUAF+BG0lX816kwB6a7ivAr/lqO8vugWpBvsxYVwVLwrt8EYeJPAohK0MOCSQfi7hQ+5NKoBYIlGYeJgEC9IRzwBAMedCVSiLvTV0eHC9qMALnmQQAee8itpKF+5bkx4eSMkXkIyzRRFYXVkDmwcSYyQ087BJ7nO4V4gOHRe0MuDr45HO4PD4f7e4evLmBma9b8ZYWLlzY/2Ht5eFEB6JuTn8h1mAS+5rxivRHAJGWds54nP6nIDrsdoNEQMevpWZpUU+9UA4BN7NTTsJe1UnYU7z6hcUy9WXbtUruno91daPdGwwD1ex/pZ9q76UIsP62KAi1dgcfu0FnC93XkuaX8v0XKW0G8NhoXWCKZOj6w8HtVkGBhF2siBaWuVVVo3UeCgFRJo/o4RPxuhc9P+RUT5M3pyXukmSnVixIhoGcoLOT/TBLB4uswukTa9tO7j98BYYPszBMelW+5iTdUJMYOgkdXevaZekDDkXiqSHvT4JlEmIbkQzKWIK5W3Cgyp0ug4GYS9OSnGFOfEWo1ynulalDIlvxaGsnU7sST/PR8FscLebS357MrFsAJy6GXbsLQC+d742XIF3vFg917gSuFV0ljrm4o0ZmIHaksax42jfDUTTAYfKRnax0OCffYXKbyw3OkeX3SvDYJ3gwFrkamjgQ3kOAdIbcbiEozuPmLQQtrhaOVaLgOS2ui4TqKZxUNTwPUyg2fMrmwPBHTg9v0vAWEc3vRzgQA7kwImcN5Dw7nrRV6VsJP4JDThJzAu2EVZlIhQWkUmsNPDw8/AU9bxAFpyHNW4Oj0xHG4D5nDrXjNDtU/TA0TOoasz+/qDLY8FOvlbBxkAyjTTunnCuNOmvvablOTyNEaSDuJKB2UXqTlq+E8NVqmQCxv/x0nQoRQhRUK8AYYne+CK4foyiHuYDnEW2XUtAnGYwgyKSGwbTIMeWq7hSyVNpnX5qjShyqDVHkXapNXgkXKEPVs0BzNd7T+rr0y14ypM3URfAv8DsNUdbe3PYcNcM6aKav9PutTW5au6x1G5TYzRSsBdFzRnXl07kyg6VafWcc41gxlbz+OdUGBI7TSDdwSjT9abuPeFdktGZPb2+2sifa+5O7i2skkbZ5Hm++aeR5tQ1nN8xgTntgAw5Nb66aZj5pHff869F3UrdQd/zZ5CN4uQmQlaI57uDPuYRNU1ZGseydZxuy6PsnSVbCQKq1VN8IMUJUl6+/6W12OrI8Rn05ZZFxBte9+VphriG6a3ox5l6riQ5QIQuVSeLMoFGEiIbhS+IQLL0h8Rk7fv++T92f/fqqCBax6rFhGzAnsRQJyWMZOhTPbkXqldVA5kuGqlLoqpXcp5rsqpZVjuiqlrkqpq1L6mKqUDlPWeFM6o4hNMSXIaBbKGAaQ+qd6rxc/kAM92sB0H6TdlbOLGaPk4fI+/VDj1vJej2jcksC9AbtYVmHQBCWSQQlQDGjW0FTw0lU3Omuy5wfS1hB3cBUxQK3Dim6C2QPI1+Hyiv3uxdHP+Vc4/4qt+lfk7xGSgNXPQj1pJBjAKNExC8pL+msyp2IA7AruX8w+xwSbWtdvqlTbGjgZR8rJO11H7w0V1KeIofMvYGOx0t8rERRCNQMLXW1KYEa8eTc+qyc/fijThFoaffLTB5PmDP65LXpcJnvDbIdXeJm0IssmYUctEV4jqUh9MpEyOf4W7uzgP8MkGry7RnPL82//893p2Yus2mkoxiGNfJV8wUpsYap7mYwi1cHQhdwbOhwamiuenVD78yIK/cSLTcfTM5MbhEnQx/Es25kpIIaFyilo8TA9GhMqA0mG+dKUKLXA6OweM8ajdAWnJ7sUgNwpsgqvKS7p9KQTInC6qdYpMm5h0DARDXnJWt2rzoNgty2SlxzycAES9x4gYWH49anPFCjInM3DaLmHyGJBmyiQ3X6QtkeKUyY01nhVkp9E0S9rlDJTuZAGyD+hGVigCYYVbzChGJ5bI+PfEhbBe82uX1tO3MIWXMRsWuSF+705/czngC4O9vfhTy70n7ZxJYx87NkKmu85C5CAYi/NWyqwxsthI4OJ9EdjL/UHAvDJhsXnkQo6aAvPiekAMMkwinMgcdEMEpWeBZP6C8bPA+UlkQxb79CZugIAkupIIhYnkWA+qAYwa+oVDxNpeGCFP8pwtqSkx+RHLfRlN3W4DUpamDa4pktJ2HwRL7UTTEbGqla1gix5oV8hhb6lkHiNZaKNrvADrVdJZS9BZW6nfhklUYXs9CMXyOFFLGBXFJx77D6QphbeusF8FceUUqeVcpluR1Sjsckoh1sMyXbV4ppvbHrIRIQxmQA7i0xHmEQeW32cyI6yqAzq3z68+4noryaXjtZZkIl68zMKjCzysCnYzcDuaZJfcgKGw8727VOJJbAGAUqZY8nycJ+KSRjN8axo0CciFAO1n6ZLn3DIErx0V9FdxU1cxa78dt7AWFBF8bkqfJZtJcgDukvVgtRlB0IJniRgrMqt8nD/8PVg/5vB4cHHg1dHL/eP9vf/UV/zppCXWPDfEmZVnDXJMVPgmnd4/+BvH354891/HL89O/hu3/4fW2Yo8DbZFaLzFePLZLEIo3iALB4MqVKjd9rZgMqY6H5b297CDcs4nZy1OQd/+dptSC1dZh5TZgS1nZB4dSUnCZpizQOVJni3oHBrNKdjOGQBGkgY+M8knPMYVNNao4EnUJiy82WqV1ufAVKT/Heta1HwcEmQaVvFLyuJrU581xwPHHErhscS4G2JvXA7NDppNjg2Sb3fIcq2598y5/dOYGUAyMSnEK+0qcg1oOZrEFCvo1BMHdV1VPe2VNfcDThSa6+rd8Jxi+7e7si9zXOLlcQEHFNM/lRWQuTFHUld7gwbt4pWoeviyvFLhEp7PK5NqZr1npZm86dMAVerfhyzmDbpGy2F3ypF48BS+N10tpYU7PCZZebY5DY5GTYaVYrXbc7Fj0xM4xnq4z7VBXrXqDS1Q01FFDfNmN4VKYXVoBaPDC5avvJgYbYDy92EL29aRkD9p9nil4fFHc9fb6OLbBeBnAFlCWtO5eYo16OhXI6Jclfx/2fvXZfbRrJ1wVfJ0JwI2R0kdZcvNXsmVL5Uq7dd1pHk7tOny8FKAkky2yDARgKSWQ5H7HeY/f/E/JknmCfaTzCPMLHyAiSABAhSpERKq390WUQikdd1/dZaG3IUW0f6o6kNTW1zTW1o40EbD5L5DSPzaOPBc7uN5xZtPBtk49Gp7nLrx+LAsr3v2b8lXrExHU2NZUY3d+SaabLMqCbCblOPISsOsjWs954MK61wS/nXdVUFtKAgX3hUfAFFFDyKG3IU6y0oC8sbqBujbowXGHVjPLd4blE33hrdWKdEtfXPb91hFI/gjspJdr0oHHJNHWScPBckU3i1liZKln4aRKbmFARLaUDBNI6GPABqIn/g8C+I8RQQGQYJKnhCgEtTHopebS20GvUa2pZrnTUp1r+wpKBVA7zBKLyPVru+LqScKFgUUMdG/vJo+AuKOngUN+QoIkoBUQqIUkBLDJL5R0vm0RKD53Ybzy1aYjbIEgO12y2IwsbFodwdM7Fn7D87rdL06NY1SXqyvtwpeuAamSYyl1ou4HVUjhoV0CLFSXJm2hI6nTIaQ6I1j4E5akwFGTAWyrjhbTUNdR42ydBJfY6hxVLomKDyKEx4mK4gl469omz2l8Pzf0bfPrz5S3r+z4gP/sfXxPvzX27+5yQQ//PqL6+Ki3x4crqUAe4sy5VqTifa3lCieFQSBQq3eBQ35CgumZTnrMlQZCQFMBMNeSz5ixfJ3LI6UXS+1jz02bdV2Y9qjWMXekTzpYZJJlVVCvAWDU9nmHtmcQEBM9Cg3Q9ZzBNiMWj3w3O7jecW7X7z7H4flbnuXrLPZJasR23zg6Kp8l8Lxk8ZK2BT9JSRacsL8pHGUPc0E9nhvMl+oDTq9tvyrPVccpRLaQ6FAR5o296idjDzZQzyQvb6GNkrSnp4FDfkKGKQF5oY8AJv6QVGEwOe2208t2hi2BATgw7wypW35cO7MoxMMbgrGhKeiCykS0Z0mTXpPSmjxh4PR0zl6t2wObdKIqxHb5tYzuVP2XZWRnoRR56sbEkowHJuWCzUuYFDwL4lMfUSQUQSp16SAuQqOyXDOJoQnvTIGQyBqNuQBxXA/fUS0SHsBsrsdQgPVS8QJ6iLXVIB1p00ieDwQtXEGRp11mrUuY9kz/Xyyxv7fJlmsgirOmfFs7WIEJMNvOTyB4+xfmpiXPR3e4V1PCcxg+Mn682ymPg0/komkc8MIsCnYiwL0PZKV9Mhl8RR4BBKztJkDBwsCphjKPVbnAolYulSdmImEjaBmBL1OxWCi4SGKrIEcAgioZOpQ6bTUlDWpPmzbgBDmalGgV1+0yVQTHh4rnbtQDJWGSd87ghKulKPrKik5gF6Ywq1huVL3ePDqoBRGmtZHZ1v4SwcV0Va0c6JMv4jk/FR3cSjuCFHEe2caOfEC7ylFxjtnHhut/Hcop1zQ+yc2ni1gtTOtdY9Y1/YaRW+qP/jjl7MunJFL+aGDJFEsYLFZyAmNHGty8T1WKIk3zjCI4E8TOmIhxDcYUa5dJqWYiRkMRDy8NQeubawWAbveaOvGnLk4Ic8SBiMcVGzjjXS0+P6LZddthyitlXDK4uMDQzalinO/HmjLo9l34ZeqPgKdHbBmFKdZ2/CEurThKK1CSWtRyVpodCPR3FDjuI6Qks1+V5DardFU7mpkSwtIDT7as4rn9ONVUSkXgUuCBUi8rgUWQBtcEePjiWEV4SOcRQnHTIuXg7dfJE1+SxA8JNeQNHoBvxheqlIbwH45IaaT6vUJerLr8kuyAy7HbIrhQb4hyU17EJeE7ILksPuygWRLAld2/O7jgR6zoR5WnAzW2sfPDua2Z4ARjYvdJMxphkN8SjbPBXZBg3xeG638dyiIX5DDPEypjmzbz8p+K+Z9d531Qn0utM20Fn/pynOOVv84hrlJSK1AD6YwSKRSzaJbjR2Wz8B3CwNZ0QRghxFGfDwK1zYSEJyL6XUql7UAbqW9oPeh/V6H7Kzs+TwtHn6vCUS8g52/tYlR6qHCM3SKHc8GrkDRWA8ihtyFFtXG6kLenif5vW6TOyDDrAAEw9E7cCc7GCfYjAE0HuILiCCcjl/R1gEiCFDHqrlCfhonMC/wIoYRWQQww/O84NGdDSioxH9Hozohjy0MqejHRftuCgMbJgwgHZcPLfbeG7RjrshdlydOMJuuGTeiEVsj+2q/ur/uEv+1lhJL1kSc3ZTtZOiSRNNmoubNPMqymjURCb8CJkwyoN4FDfkKKJRE42aaNREoyYaNdGoicLAExYG0KiJ53Ybzy0aNTfEqAlFtnWrJ4VMjRnkR93Z0sS0evS2qfdS/lSfRyO39mbJNDLqqEmDjFKSWlus8a6UiFmYjBmENIGtWtwqSyOah7c6pazK5+BY+iSNadANaDhKgaepA5FEZEITb0zoiILGY5KwmHNUNAz8DTgK3IfJjHw+1woeCz0m/s8WqV5N47c0cbDeazaZRjENCA29sY73i1lAE34DGmMC3M18zSiS5dC75tys+6A+GTOA4QdmxOXh/JXFg0jwJFN7HZeFvGVDKiMfk4jsTpjP08kcnVOAhm2nqNV/q5d3OjuQbVylpx3z8CsPRx/YDXNIQZokAPsP5TD3iGA09sbEZ9NkXBpbEN3OGVg2ADOyILq1xzXmo/FOhTeqw9Y6S6wetOKo6ENAmfdRybyofuFR3JCj2NaHoBiZY5M/fOxWGV5BluyRTzr8Xu64aS3AYC2+8unUbfDMJ/v3KG2TQh58BjT0OYgAjqv1EaQXOBm55EslwmIwM0fUY+TZJJKl6/WRlZXsn7e/bPftM/Ci2HE7LrPpyAZZRgS5HT8R4NAshuWXJkoz2cZrv997+aJdqnnpMTL7UO+bkMZ3qd3zobxxxhMhvGjuibiz66LsqigPeFVOC5cB3p2TQ22lMwfH3LQak+rRthJs/J7fit+bSXuVmqRSo7KuFToA0AGAnHzTODk6APDcbuO5RQfAhjgAtCl5nWmiYzZh8ipvrbVdj79ob1c/1uOrr8BMKm3oPBwFmUDMvoHYwRMszvYILOm1ALtLelvG1yWRspwX7eXnK6mR9oCFwLJqZW0tvBq7rrwIaOFFoeZRCTUoX+NR3JCjiChxRIkjShxR4vWHGFHiaCRGYeDRCwNoJMZzu43nFo3EG2Mk1hbQdZqJtXQh9r7nRdLaZws2gmpTumDdpmKp/Ujjr4LY8GmplWQJOexyg+oygAk6oaORFqTlrRjxGwC5aMn7/K08NnI4Wi9CW+96k2pUa+s5vQhug2jbOZi326beKGpRx/MK8LVKt2HGoLMIow0Vef6j4vkofuJR3JCjWG9DXViWRLsH2j3wAqPdA88tnlu0e2yF3UOn/MztBsvl/Ky3LBRtCBAWk5kPek8rIN9yJW7YpFthBK3QjlL2VWM3ylsUB/wLC6FXiRScUpEo0g+O8mgyTcggiLyv+mX+BxBQdsPiWSKjPnQktrRPaV+h/hzam7YeW3ivmL624L2L4mlG0xOKXY9K7EINAI/ihhzFtvC9WhDWxdLSBEzVEiTqJ2vYgeQB3xJCBQCsDslfaJgC0gtgR73fwv/vf/3n/0ueAS7qObkog7ng8f/6v8kzQEY9J+95yMWYRKHEdcnDVlpIM1/EGqHNDSnXplEutLnhud3Gc4s2tw2xuRn23gQ14t0RTdgtne0NeBDwcLTnxcznSXdAA8h+AmvsLprDR139ChTL6ZZeK1tv1GOSPy4F+emciioKIo1j4KTFdzpkSmdwz4maJeHhMOpII2ASTbvplEgT4iiNs/CJVZm/6FLmr5YQlDeFWULWEbkSi2FR/lvMhjuvd/63PS+aTKOQwUarp2LP2qn+LyxR3/tZfe5SD0/f+WPXAH+mvqEsaxmTlOQqAzmqDuR9FA+477PwHodx7LDYGTp+T8NoJisd9QObUB7ADx3551c2KxOds3Pyi7rqivDQKe/KbhRxKTYhf4u5xP5ZP10y6qtXveEFiydcgQwvs+vwPYvb8KJJz8vuT49OeU/foR7lKuOi7CWg4VmB9H3fGaSCh5K4q9vFgMFNYy6Y+WUYs+zf0zjKuIKblo6kUTgIZt1MJshpJh+FMvmT6qyW3mZEsqd3qYnqlgjhYsSXhzcR91h3zEGFnLWmvuX3yuRXPyf58xr6S0nARQKqJ1jQzXtC+VWmdMRDLWZFUyVNBjMy5EHCYpUFDEjgJpDe3Pqto3Dk11QGzfLn3svxZ2sEL7wmNE2iDpmA9h3I8CUaBL2degv5Qp3US2AqGbGv0olmf5t7Bf3tdPSPqlsQPVrxmfPiEVg/o9Ef/LP6HnIa5DTIaVbKacpEfzlWM43ZDWe3C7Ma814dq8mf17Ia3cREsaZTL5qAkm264KEXpGC5hEKejEhLhBL46bdNYDIL0V0z2fuiuxfqe0h3ke4i3V0L3TUUbjG6K6YsBJrWDfiEaxNZTVSWRXkNfqr4siM2y7QgsgV55rMpJCZLmP/cQYonkba5lF4z2W7Nnm4Lsb0qTmOZsJ6211itt/ngB/ge0lqktQ20dusoa0477k5QexXSNQcrWl+uvSSQNtBEkEcXI4gOM3Spg4KV+bEQyuKk1i6iItVEqvmEJNQHoqNAPX/UYq4tKiqaqejVglT0bfbsdek9AUUCSBgRKLzEYjJgJptYh7AQJHe/o0A2PmBxfaXsA5qfhb50dhOqXLyKwvmCHO8f9chnoUh2yG6JdVrkx82XIXkUo/5rMk6SqXi9t+dDrSdYFGGfEy+a2FL7kEEpLyaU2K4WR+z1yLtvXCSleQ3AewcStU9uOCVv3314d/2OlAT+jeEQ9wG8phN32YUS91HNAC7nAU0izyY8JAf7+3bREAA6jCqYEQ0q5xO48wf7+wAh0VxsvnJgeYob8OxRmIyDmWWE9ymXf98y9lX+wzSRMLoEIhBGrkRuxa+bhnPyofFvkmhkCdH03yLgEtEn0QrU97lyxlxYqy/RDEUog94Oa5TWcrmzzh7MFx3ydIArZ0RXKCpso6hg8TtDi1Dl2mhRQV3iBS1ZSTSFZf/eQsJQ/XfVG7Zs8UY+IFRjeKrczjzXYCAN9TFql8oUpMfZId6YxhAFqPFw+vddQOpKh2oJQtQj+jRAxFiWAdNEDv5Ezi7OiTxhHfLpLIV6SyCPCBbfgEEfRgRBQzQAccRjUDoTpBFk8K93rtU21TH2eZz9pMLY92UIp9y8vtq8vitr7EURIpZE+kgY6S+rVZWKJJqwuP5oNLLl6aR/cHi0swzzbZ3cXS8hD3mi8szmsPtgsWixtrRc3bVruKOby2gP6zfdrDb5r//4TxV4UTwNkPzVZx74Eu+LGaJo8DBWhJ/VGEpSwLY6o3qGb87j3+3C6qdp7I2pYMLWlRV/Ve51RTOF4qGKhLflqMuIEHvK+rigK0y+2tWvupIUpjBmBzK4yQ1W+1LF0EveluUFQaIwmL1eQGqgsnIkMFaTuWCT5Id5DOqsdq3W73aTTOqN/Ojmsiok/BtgPt46DXCNHKSXUctV+d5qibDM2LEABXb43ezXk3HMxDgK/I5mSIqo0nCm43sgFGsjgMd3JJ1rd70h5UTK+WQcbw9LSxfyv9VS0quFKOkb/bQoykrZkmYxZhk1taPnFF1VJjEmEqHTc/u+zKZUUKRlRXddHxu+MwaB1jOyX0J5IHrkWtUzsmgbJOWi4B0DOZnQoYxcVUK36QHMHCwBs4cgIh2omvdPQNZeja2OhrNPQ0UmmqxS7Ux4No9arR0vO34udlM+odk35XFMYj4aQc4L+3TL0Zy0GYw1lpP9/XKkbz6uTmatq0Y6b/jiesA6wqQPdcScXtC/qgfGEhoNhyaflVzUbk5mhJTCPI9NEx3cpYuQzQlh0r2k0+7NwbwkYK2sum/g5idRgVBIhXyYJobUgYnD00s6JyTfWG+BtSbptM99NplGCQu9meKd1cJXHCKuRzq/nE8+fz5/qw7khH5lwtBHTf81CRN0yFSigsRdmysrNJWmksxYbt9TOnx57O13Dw790+6xd3zafXm873cP2fGro2N/+PKEHVjjl+TBuXJXls2YaFsQ893jbZsCTbCEmwXcoqvsOml1J6B6jaqEoLUhv17Yl9xQAl48OOElTmrmsy7P+lZoAisy9wPYA+zB1Ev4TYb6QG3mnrUZGMarGvqeyX08hH6lDVdGzKq0W5DGpKNKFTotz2C0Dkf6OolZ6I3jKIxSYW058bmQGDOb5Dw6Pe4xuj5aKFvLIxj2WMBHPF+X+fqaEm7s18qmL03ui03KKMkE9OiQQcaiZMxkshqjRACcULAARLP4pgJ/UFoOH0JKIUh4NFPaVo5gGEbxLY19UfLZlNi+jPTXOeoGkT/7SScRoiIKSRCNuAfXMboF+jlm8eaY1wra0oqQDEXhwJVbSI24GwBstER8RMcseS4oF4rOt8uplYX9l7/9N31CJBSWF7Z1Pn7BynNk5Cd9j6ESan8YpY70Uh8g+8Mx8fmIJ2p2QD2nAXgKo+lMqt/NYuLx4fFhfS3Zi+JRlGkjyNlAqhxRTNIwZl40CvkfkEYRsg9KkCFkRYTkZVJceuZHTMisWtIE/LxH/j2MbkNyQ4OUidfk4uzvF2cfOuTN5bu359f9N2eXbzvk7OLiw7v+xdnfO+SXT59+Mf8+e/Pn/tvzy3dvrvtv3/18ft0hV+8uzsy/35xd/fns4qJDPpz/+u/Q4d8vrj81z976qKRJlXxZE/rtXJ0CgK22zhr8LqcoYGpRFGS9xmLrk5srJ6KMtQEWY7QPt0Nr2GLBMgKLijnYaZuxQYkr+qWKk06zES2xZK0aHHRa8Vb1F+g39e8giG5ZyZgsyDOj8z/XAAoonb5loXLX9srck4NOot0Fklskt+igWwMB1lRuGdqrcr620xO9MfO+avKr3ytg3+GxoZjZ8+JxlsqkZduaxhEYdFWScZlaNxpm6HlQPYBG6b+KBt2NoLX3gUk3mlyDWfy6vEAKKQ7boVd1OC9VLg/7B3TgLYYBrw5tUTi4Ht56uZBkQVfyS8iCkAWhxH9nhqOp+2IMJ4Xc0gunAi2+VRb35dP5aUCtjVZveJFIOmAs/HxF/CgIaCw6hI5GMRtR7R0eR6nMiu7TWSk+K+ETRmIwz28CI8pTg0pLUV9uLtysWx760W1zrtBfdGOiGsuJqhXyaUKbB7JoT/XMx6fFgGT4C5ZfxgPnVdwTGid9WPzmOV1BO7VJVJDPIf8m/xAJnUD8EZnA6RLMg3j7phSoi/ZTXwzgxX7+v2qFrXyGLPRbzO8dgJzuPLvFemme28vT45q5tdJIP9uXeP0aqfwcpnFFeQBV0nWkEywy7HYigopfhUqLN9xncbMtUDlPu+Du6+r+sjcLAsIHcAiqrknedZmcQithRdHmTTN4C/PL8VLglvdNkvBpJKS+pNO7sDCrK7mgbNC+EmnOO4/YYOAN9vdP/WP/+NR/MRic0pfei+HB8emLU2+wX5AQplDupMRcKh/JAUqZA+/ABuYVOmRxf9lOD/el2yiD+9V9Q5cPae7feAWL7FSf9sVfFYzG3rj+1ZKkIFtLc4XfkZvfISJIR9ViPe0Yojy4yhwgVlcJrFI2bo77dkAFMzWL6rF+MQf3n9wjx5J2NJDB79OksR9f5lNQsg8gZD6FwSyjbF4aB/3syFdE4NKNdjzXJ8E5wDGjhuQ4ShKptQSrFPuWxJT8+fr6guhXFPDPTtDEIIWTji01ZKRH/io9uBIEAVtJwYmQQ7ldorGFMX158OoQqK1gIVCZm9zdrSxBzSjMH52df4rGpQt4+NX9IBpFzgcmm9WdtlTdM0fvhpg6aAcIAnCrXEpQwS4lCat18Ipj1h/XnXXyc14FRRaLM1XpRan8oCmopG/alzlCpQ5NWEetv3Y33Coc1ryg9ZWyGspRNi6excKkYbF9maoWtamWkAnJG8X8LzI5AYXEFvJgRXBr9FKIOQFEWrLT2XUaZbs8kU5RaKvJuCMsNJqGPJVeVMQ8Q5pZWxpnEUSKsAMLuCJANcjnyw9kFqUEKpkHMyvYSJYyZQovnrMC0LV/10v2HajPj987RKhe4U8ySUUCeffSkP8rZTKuRwPalvcyr0moXBtybUViB4oMDpFhWVlgrdy6jhu3dSVdysA9rcJpYN0nc7bWJTuv9/CizIwy85bIzOsTkc/DaZrAQeC+ineQpsGHk5ZNieBaW/iL/f2DYjneeg5bMzkZQAhHuH5QeR8AcneYGJqL3eoPrEzX2VSpHGXwVom1pDCpWJdmR2PpYqjlI6XHRUpZemjoZOlnm1wVHv1Yzlq89537P3bmpNvSuoXOttWoW5iMW3N1C9VQVFtKSzC7YfGMTGPugVs0TgOmmN+AQbpwyfOWyp+9divxHb5Y4qTtzJ22AKcENwgG4okMebTTRJpMXCjXoVyHct1WyHU1/uP34D/ebFHusK0ol89njuiFMteTlLm0VNIymSmLJxTQERm3c/qmVbq4IABiDBBpW8oQPYfpEqhzKljZ/JiHsWQ93/IgICKJpiSOUqgJ0mtMn6flqiFLvHGzWCXDc+bKVAaz55CqOlYFVZg0TKGTGWJVFLF+RXMllK5y6YoSgNkHzLBxPlQoHhSmUJhCYQqFKRSmNkuYQrdyO/HKpKWkiTduFFHSqT/XrfxZtmkhpqiGwhQb9lR9tyFnga9j2Eo99MgbmdFHEC9gFFJkeWPmExaCuCMyfGHW/AlILug93i65YOUMf8W8ehmHsSIK6DDGM4+y8FbJwugwfgQOY1RqnphSgyqMM2RKCiEP7JU3rGjdznoIvV4+wKsLr8+N8irawxtCvgrtpBJWCQIrAnA7ZBLJYgGestFnpb1lEYFN1Nq2MubrDqFbZqXNDlpLPi+OC4QnUweiejKkm6R80FS0/lz5UF/97GxkeJzi7ejK1tlUJpHPgj6MYO5KZJ/OlnqH/SulgbAC67MfZCS96AK8XHNYykNRjLaHe9aXnS/xackGxEoi6uQadEw65P7AJcBsUVCd63S2UTCs+Teu/ISGKQ3kG7CB3BbxtRBjnkVpUv9Q/dpmj1ejfTYpjy2XSJ6UOmXK3KNV35gVaWpyMfua5jjncMv4aJw4qGtZCHTTP7U4nTlaG0bAYQSckerJGymoob9i2VwJZcm3pyTfNUbIVYXjujC5gnhTHzPnQK8KlkiUijoPMpGSEo8khRFkAn4YWRTL5QMpJGJS7hPBtIwFOeto4KUBjFh7B1T/myNWr81vUSMXlAxcb4sF30vBi2WFhsgByZVtU6/HyKhqXLNGEfUepYsmyeCBWH4dt67ZWw6muz5NfR719bxcK6OaSb9gX15wHoUt2/vz2/EJHbG+Z+p3Nbaa21nCviUtWs1rAAeqcUmiNGkzdt1MlXqAJELzu2xokUQJDeobVOylTQLXVgYxoo6COsoG6yjoQEIH0sZqQajzLKjzLFToyu1MWEH8X1VzqgsCbNac6iMC7dfsqsQKx2C0JkkCFfo+FQbnDq+yDVKCHh7LvsGRgig8ofD0+IUnBG1sO2gDBZs1CzYrCfsrSg2wZZmNFLYgg40X5QcZwhdGBPIMsFjG/dlyxNLhfFUpyRnT1ywiNQT4FV4sR/upqcmJausmZNuVRmgUkDY32A/lIZSHUB5CeeixyUPo7r6zhHTXyL2qOFIXvtcskSwcy1cWy1yBfbljvCKfPQVBZR0+cvQ5o8/5yfqctzG4EWV/lP0fv+yPjuRH4EhGJe4pKnGosi2osulIxXbeegYFSeUl6cJxaR/0p1+MYlGN9MueEdkneeazacw8IPHPGwL9yq9JwGw+QJU4AAzlSUSEF8WsWAFES1098s56Baq25l+X9ug0zPYFegrZrQkcvC/z9L5/9OLV/it29NI/Yq9eeYevhvTQ84+Oj6h3fHhAtyQ28MQODTyxPyEL76k4sIXj0iY09KmpS1jpse/zmHny6CzRN5w8S5qi8i/545eFjfeBjFUbmtOmLsIDRaytQuC9S+oQl0AM7C7byjotfY35M9wKQ01hE9nIHnBxPTpWsOviwVlqN/s8HEbzt75em50WJQfrgbnQ9VprXa8VAQOadQzNsSiF3c0dhfLigmD42RaFn1mc9UlZ4XMJol1iiYpUNTegrJWwpv/bXkjTL1QltKynemks37RyfoUe+QxZilW0+O8gQw15kLAYQsF1xzrmftMs6JsrSzXkWVi+zu2Wh+GnUKc50Z9ziWLytJBiO+nOMaeQSrLYI7+y2+zIqwJ+Y3pTeVPxeL9HPkFRQP1Xp9zKo2EYyQqAPhfqhXydc8r9rQuG/UTJTEbbE2ClC5gQ3YTFMQUJp2sKWOfUBqqvpyBeRHKqyno6mEVf+5GUfGoWwiS+YLHRFv3cG2blWZNK0DRmN1DfnQxpEAyo9xWu8edQudV+VhXE72Veyq/Bwxtlq2L9KOxrDdbFECufz7pIksB537JLtd/ZCdMgKI7c0VsUBMxL+kE0cvNk50urEMCDqTz24ezTUJLLsqHeLZrn6szPHz69+fedzs77D2e/SPaoj7Bb+p7G0ZAHrFESmmP7y7rIP9Ux46xKQZ3yjJqHFwXc483DW3SB5MJ09Dp9kU4M5n1t+oJ58/Ldf//87up6p7Nz+e7q4tOvV++sCVryYOOUarSkFWyEJPWVLejYG6Sm6pBNS13lvWQ7UH0J1m7I/JhOpn1ZqbVKlN4z//Ls4wWBSx9wChRVtnxN9IvdCfN5OiFRnP0y5qOxKwra7ELxzZ1sDPJFGGab+23GPdE2W/ewWTiMYo9NWJhIQECP/LYzlRVjf9sBaEEU84T/ATRXzw/C4MOQeWAIIIM0gcoP0W1OX6EDvc6/7RCYmgdAUiU5OXNfmlmrz+biUduJjlIa+zHlgXDx5nIPxbs0jaPJtIX38OJgoft2tWDzw8WaHy3W/Hix5ieLNT9drPmLxZq/XKz5qwW3aX/B9osegwU39mDBnT1YZGttnz2eeDzxT+HEVwU5IPfWPfji5imujCefVSF0LvWLIWexSYBimX3cVdLrtfrJzLJdWEmgT4+lQG/+PKgZpehnWnZLAT6IRn0voELwoaVwrl37gc9OaEhHUtJw6y+WiUD+z7YTqL/nSgMrHWVfJDFN2MgJ/DEn7ur600X//Nerd5fX57/C2Xv77sO763f9Tx/eghzdRoS5+6CnqRjf1zbCt/rTdBBwTxlRq2tjneOD/cPSST5tJ9StxGcSJQVcUgs7TBTzP8q3wjWvw5PTH5nBqAVmS9qQ8lOj/5zGURIN0qEkbVZa+jJnpr7P1SZcFE32+YCO91+duhS1Nun8izPbP35ZJpvQST5Ah8YLHZyrVT1pt79ws/oBn3Co6tYHKhDf0NUYNopdy3+sod+EeWPJEJqow5B/kyqmCDjEjrXVaGKWxLM+aFPRcOhyF8kHxNAnaQqU70C8nrJ2143Ii0KRUOn8CnjIqELvTKNQGc0WG6H8WnV8b+FnMmDJLWOhHhhNEjaZJtLEPgGzm2BeBMUTnu13T4G6P88H7eAJpyWG0HbL5DAn9FvffL862o/qG0S5CoGnl0YMqzukPGB+XsPw2UH3pHnEJzb7ajdaMWWhr07YEqpsvUnGIkTKvdbZUbmoW5PGVn03VqnISaHm7vs7Rb4gk4EXr6oFL/OCVPAb9tGsqFqA/DiYt69rKHF+/IXy605YQn2aOM35deS2zmI5KaLiqoYNGicqb/mXii8VXm1hQpz3CWVekTO7kcVH7mBkmyj0ne7HZRRzYH5rtMgHHLeyOKqKWRs+zkZekt8cw0Ua+AvglXnoR7dOjtfiHpXGml8qcz2zDzSLAYeyKyeVS6KYOVNKXjEvhoyeV9ACAHA+uPdkqnPjcCafJjyBfJ7KdQLOnK+MTXUeyjgGM6b8QI+8yfxXMhaK+eR2zAOmHvvkK5sJsMkK+VEibY8s9JgAGB0LZdJQ7tTeqqT8DhI19Dp1mmOaqf0cYRUkPwBp9JX3qz2ln9JZEFGXAb+sSuuG8y3txaGWBlajf99G8VcWiz7l/YFy0tXYsd9EYRJHgSDj6Jb8Tb0FCjkP9X5CjoJAyPrBzCfJOI7S0bhwqCR2Er4CLtFdyHc7pdzflT8JW5UnCpMXzLJu8g/+RHZT5VXcJT7zUy8R0hcJ2QJuOC0mm4VwvZClcRR2oRaRn8XwgccSUi6MZAygnjkc8vx114nMSYQZvc198p/0COsW/Q/fppTr0iJdLp0abcAty5dcl7ZftNHNuiG5xjEew+2B3Nx4jNXjywzg6EmBy5YuX2SBuFaWrtyFGMsSlOcPa3KRhzY9L9p7pQm4FL4NRImHow4BckYMOeuQIBqN5D+A7pfgN4Il0Ej0yPWYWXAzSKTNqKoFZBKTf778oNAuEvIzYCRVpmq3NXozwGrry16OcCqEU20JnAqhUAiF2iIoFCJtEHeAuANE2uCJxxP/tJA2CJtB2Mw2wGYQ8YKIF0S8IOIFES+IeEHECyJeNnWciHhBxAsiXhDxgoiXdSJetrPiK/pv0X+7Jf5bTIeBPuAn5gPGdBiYDgNdluiyfAQuS3TS44l/Wif+cTvpMR0G+vUfqV8f02EgOADBAQgOQHAAggMQHIDggKWc7ggOQHAAggMQHIDgAAQHNKfDwOwXmP1ik7JfYK4LO9eFurcL1lLa+67/JRvoapt+NJHllNvWWSq8Vq22pB4T02t9zaViQ9AtZRV3IO2F3BodwkMvSH1J9uE9uLjSUsskc7jJr5pIaJIK0FcZ9ca6681Jd5GXOcq3ofWXN9vwvvV1p+TJaV9m05AbHnKwEfE/1M8gJQNX9r0bjcW4gWEPgsj7KrUSSVTdwsYKqmCNI5HYRR4t3rFFtbCKgKriCNk08sYFa5nL4pSd6YMXBy+OT14daudJxRpu3cONv2KdnWx7qyK/oqWmgaomPItSEt2GHSJSb0yoIL9T3tNj6XnR5PfmsVLgnBPZsmzoP2oz2pK7Yq37KETQN5Pvu61trayNigrc130vCF7W3S1wh/LUOjmt2ohUdli3dMPqlmpa8FYLYJhdrn3h+VxoXVmOuXppOcs0VxCEpWulPvvcBZhvhar2Tt5kq94dRnH3itIr01nGCUBCji1k/5tfzz6+IwmNRywBUXsa8TAhb3+9InSDEsM9Zkl5bUnv9BnbDuGAh9cfrpo47UEP3GEHvQP5/4fy/49qzXRR6Lafn781251fFgKt1SrAykvt01JIzTo1L8DRq5OT09PhsfeSngxe+Yf0ZOjt+8cnLwb7+y+842Mn1qjEGjKiYIbfOlbn2orRKZIPuO+ue27skHJa9xzN40nZRY3FaZd/MIm/MhJbxK48vFeJdl2iaGu5M5My7d1b2mCcjRvmVxkESpxPUeJE+fIe7Lp7380N/6GuUsBUfF2t5KqaNEiub2WDsuRakVVVM1GVcONoUkqfrKTUSXTDBAH3oMWsQR52SbYorN6vWdfiE8vMbPOE0HYmUTsqWkVDEz4kPCG3VBBNYIdpEEicIUskp71v8QrtpWgvRXvpXeylKzKPHlc37tcoIe+jNFwhXVgHvOGwLbwhn88cOMKW4BBQdl2d7KplS9kiikesqzdUCZYQXWGsF1xodumAAkhhEITAssBnlD4B9gyJVsvo9y0PAkAxTknMVJ0N2a+ZAuhT87ANQ5Z44wah9xeWzJV4L1kSc3bjkHlboRtg0hrCAGtgm3BQ2kVp9x6lXUoAkBkwDQYAkXe4WiaGwi0KtyjconCLwu0GCrcIBWgj7oJEeRc7LcTaCZa0R97qF6qYW9MTeeazacwAGus/b4DeZu19NuQh8xXowBZLe+QdBGPJsShpNHsHjLL5Z+SzNMwWGQTckN0aDihQcEX07Vz0rS1pz8feNs5fheXO7awpI8gKgLjc7xDoomOSfD0mRG55P9olntAb0zYpi1m31mOsSbyRsSZbPNL4m34hWUW+HeXfc3YtQ6n8HSuM1oT9dlQcdWdH8laR/aMvzQT631EKLfw0NnF/Q8Z8yGlQh2tR/CCKm2bG/qUPhuZX0vU7Suq6lDG2Tcuah3SXARBlKcv6JZN0vjhDXEvyD+yVNTkzKFf4rDO73VYpam4NZG0JXtzolRabUuCKmiLn1Cunqz4ijxEH4lQ33hqB9ikpGrko3E6/yKT+FYKMXYpBBi/WD5t1g6yqddZcWo0Eg6DiPCwcoovJhCa5iT0vcK1phdQlUsEgqw3LdYh7UCges1j/aCpzoxiIYuCKxMClJZ064WYrSyWgboaXcoMuJepmm6ubYUYXzOiySdof6nqrAfybz+x95/6CIH+X5pjB+1tpjjnKXzdH19GW6ph3WM0ng65H+Rrla5SvUb5GoBUCrVD2vavsq+XU1uh8l7SqcPmtRFUbnm9eMMEGQTTKCrKhAIsC7CMBzKO8ivIqyqsor6K8ivIqInVWL8HKGIDOzjRtFl9Vun2n/PpZVe1oLcJOA+rpsFmFMLYk146USHVlIhlKyoCkomkWJdt7yUCIciPKjY8K3KPoNoJ78FLipURl7ikocwjueQTgHtTKn4hWjjo41OtWtezugqCyAlV22kbj2+9UIvKth22D8u1X4jSEYpsYkv8YlPenHpI/jSMgn8yf2989ReVjML6deqTdVy3SUA117WSPEzpyPkdFFhVZVGRRkc0U2YKoYVOPRZML4FauZCs7FptuS2EV51pE+1sFF8iE4DpeZLWAZ3XNan5eybpXeHrefyWtYEYK9aN+4Qw7ekiihAaq0He1l9KVLK6Wc22y0RZ6tjILOoa1VBqQpnG3oC7yiy4SUzsKS87JD2unII9aY8LUJU84dYmlWiMmosEeUzR6rCyBSZ0txSQxsVOJtExkUnhFJTPxolgjJ2QeE0jLnaEuQAwoJTTR70cxgdOLGUwwg4kkZXrX+9xvpLVVwYJ+O1cPT+TC6T8OnBLLIl2vwFtuz8k9nCebGwNNJWgqQVMJ6tdoKsGtRFMJmkrQVCIQbIRgo40zxqDpZWX5hKwvLZFSqM6WY9IKtbflZKmFCq+YiG1NpRAWs6UGIUw3hCYLNFmgyQJNFhuq56LJ4tFsJZos0GSBJgtMdvEkw2rQnHAHc8KiKdrqtH+Zpq296m+lakPlH5V/TNWGuj7q+qjro66Puj5uJer6qOujro+6Pur6GMexXu1fpre8A5LAkIj26AH9dteQrjJ8wGzTB/XcDRiwytUSFoIlobZqrQcnIOb0ngwA+/7Ri1f7r9jRS/+IvXrlHb4a0kPPPzo+ot7x4QF9MgaAKPZZ3B/M2ueYyFJYFNmEU6lzqGTyvw1aXEFla6upuWbU93nMPMNcF50bFZ41KfUXbGrxW7ks3vyBu+nJVclgQWXZNF9Idy5s1J0UaRCSmLm5E5ZQECJ6SuHM/lTqZmeHpskYrolnurkdRwETNFDDmExpwhW5/ag4ox9M+9TscypY3KcjEAe+LKKrh7Uau62eF2/1e7n5RD4V1mVt0N7DNAjye1hBD7bU5pdW3UGU/zYNpOCi2Fh2kgM+4clS2XH29/dLuWzK2WwWMgtyRRkVGyoBglYn7C0uMWEY8RaFEX/QgeSP1Mc0YiGLaRDMupkjpZ24qaW5eV4m2SKKR6yrd1EJh6CnqwN/PeaCTFk8oSELkwynJwi7YfGMiCSKmZ+JfTMSKcHGyIMyDFgKgjoOOKv4oyRHXwUGezQMo4QMGImZF92wmPm9Nh4wmRauVoCV2aMaxVeVC04zzT1DugpS7BCikZUAN7IEOD0REG/B0TWlIx7KIaJYe79i7WKpyd7HjHUT9i0h6j0Ch03udyaeOKD+25BZ7qQ2sdyGCf5rEOGluI4yPMrwT0WGh33o83AYtU7waN+Dpe5aZu3KJJvmyyYSGid9mSe29VecDoLyp+2PsNBf9ycmPOzr+9T8icws3Ngb/bbK3njYt+/2iga46i7zUSqqs9phrq5POU7waWSEc2UjXXmvPOxbxHtF41xtjxZHqektJ7WamuznVNCiqfrhQfXhl+YR5KyzbRbcpt4y9ruKzgzfbiW1Au8MtMbhEqrnfsgIBktS+1JuYSN7LNtbppZmelJVge1m37G+XSNIrWBWdbLY0l0vCJALZKLjYVlbfaiEx+qkO6QILVu6PPCrACh4qUiiSb/0DevrGYWqKkYNsAQttdZhFlhQ/0QdBCcMRID0GTAh4PTCj7COs2SsRqdXdNbPjnbf6lBKhaUQ9PzL2dl3PXRegqaGDQ1ch74eeNEvOcKtlRcJm9Y8qbe/2oqJS9Etyt8/CrpLi/YuDMQ81VXbRSxG6FC/atSpBiurktXnw1PBauK8XJncWPfQcTGKDVxL7WxRXN1yE0uQcTYy0nLdw+ZxFuTZOS1qx1kW41yNpkX7ufXA2GNcD1W3dbt0x+ylxbOCTohH64R4BOCXtbklVBrTO+JfshQa89wHI1bwHnR9lsCul6NorG0mb02TuugZ1QfzCVxj7UeRTgRqMDCebTXPPCf1foOl/QVPxQVw346VhTNfwCarc7FOob5OqEBh/hEJ82PgF44ZVGRl+4U+WOINHrC6D6ap4H/UiPcrVCWylgvMxHpj7lR02/q5oC7TRpdBQPdTBXSjMLsqYVZiueU99MaNcqhsYUuiBRH0Ap7a21ORPj/LeowiwzAoeTNEOfMRyJnrSKifeWYcNDCHd1p4ku6Bg4M5JLHse9T3OQyNBhfFUOg7h7dWhiGLTDTPpABT3a8y12Uy7d+rTI/cGLkx4lsX4b0rKFGcmZL2NBVexqQUZ3baeptSbsutMyoBwYliDhjTwMBVyZTOgoj6yOwfD7NfhAGZYwDpqckwjia2hVHJkEsSdGQXT4RdoPLWqLxlxHtVXERd7+XYiH63mY9kjZoYSRbmgAzkiTMQfQ6QgyAHQQ6yJg6iSfJdWIix7fcVcxBtGIiMjDMvOsLizCPylc3q4uKASBTamXC/CsPoZbxHEDGObgklEyq+Mp9MY3bD2S2QZUa9MXTTISEED8ruv7IZZJdkwRDzQd4ve9rcSLaDpaLK5alWlPUBkbM04FRUT+CPbK76DrtdiNufj+1HZyegIumnIgMPlKZx/QYyxjLy7O9///vfux8/dt++fV4IGYb3iWAB8yA8OIH4Y6ASSUSsYDNGaKYAJ1GBUnXI7ZglY1igmEBUsa0sSy7KfOb3iHKa+AQClCM4O6HHZHniWY/8mgaByU9gxjWmQnYHU8tol+DwlhzkkLPAl2kMeJjEkZ96EMRcXf4CeKLi6S1iERIWxxRe0GQ9jXO+BY7wFBDnq0q8lrEZEaTuTKQxTVhf5Y9wgUbyx/0pi3nku4Ss7M6f7ivhJWa1mVH1U81DnKpE1S1enEalk8pNLCVGKyZBU/fZHicWrX/CQM8LIw290ZLY05F2jWjas4XKlZWjd0uqVyBuEloQQiuyqmwks5anU5HEjE6AJWavnF2cS0pdNXJoTnklr7Yg6mOGzjK/lMqio9I+0JBEU+XZJEDviKR3PXJBhSC/KzLxO7AkoccOOc+l0BvFJJrwBIpfJRFwEZlo/RsXCSSRKI5C9YMi8X2IxGvzst9NFnw4blzds4vyZcrO92J3yLWL37qChYIn/MZy6TdIBSUWUOb2FeauduHLMi5+DbDThevuH7mLygQqE6hMPGplAss6Y1nn+1ZXHHb9Iv9+aliixVSbFZR7Lhv0l6j57FaYTMXnZo0pq/JcaJaJbTpkTfoDCwqTrPak34WSUIqOqZYVKRCVly2p7/R4KjmjvIzyMsrLKC8jEP4R4lJQll2DLLtQFmgj+slyHgoIUpAfTaVQpynb+LGESgkds0DnitYc5pYHAfQ6tRkNGMal1Z0nrdJBq4KobtFYlkNtloutEqiNknEV/XJtw+kAACOcCBjNuBAA85QE5s2pforyMcrHKB+jfIzy8ZORj1Hmrc3KkDbLkiqAtEaYvIwSOt/OesmmAfWKErPxoEfDRiGzR4D6ZZTcoyHxxjQcoVl1y6TEdQBLNgOmUaZzalBLAS1SLe0g0AIFYxSMUTDeXMEYgRaPAGiBGs4j0nDQA3AnbWgFeXLiKE1Y+6BUk9bAn0GmVa+rX69EqOrnJHteF6JabFgSa4uG+sdRm7H+yyfHx8eHhwenc2sWlhQHOmIkIzZ1WlqxlR5EHsyZjaJVVGiJ9MpeQTbWmzhlMdGv1Q2n6Z36wR3utzTfX+W5UlfDC+pS5RVbZcUaXZKVo1qiq9lyxQ3ya9yOV5krk1C32LmKFNI+mwbRbMLCFkpc8/cauq6TY29YDIyiVRhCsbfCu4WVAA7CAgYNG5c6z5NYnGTNUKM0maaFHmsWKWTfWiylHuF5i4nnTb+UH8lvwYRVDw66pbmuLBVYfV+unZmZ7qUqqnRWvUQy0nBta9TZgfN3X1sgv9XRU/ryo/yRORcqClUST0dbKd/N29esAxq0293CCNay1XV5SVex+C4pet4STVnssTCRUvjmnP+glBx21Vegqlus9RbkCko2t0XvgrPmL5jNas0q8sm13v78RkDpIF134UtFJ+7s3PLQj24dHZamlPfe0QVl1UiyHtrQXbD8bMrFxDM4dyD1xS3mlJiQheydhxTkLncdrZowS6u8gHk3/0KbM6fe3pBDt2ncgIWOk9OODcjXip6IykrUVVRZhRlaqXvVt22HRC5Tzz/sUCP8pnGxKrLNogpAXREZLvo3YPB0mb4W0woKWoD8XsdMrKQVuPZcLqmlLpQqfpRM3pY2VrKNmzUvqFOO81lOrmHsLlqntjT5TEl1qqTL2trlAmE6lC1Kh/JWW94u1VF5SlkDB0ze5hb2WNvOaXzpd82aAg3chtSCHfWNpBfgHrVNpBXrm2omyu0q5tM80k9nCWU+0bMihkr1yJuAwz+IR4NAeXFlZ4MZgS0Ykd/1R/a+w6x//E6oMuNKyYDAb0/JTLs2kAhamdDKhFYm1CvQyrQ9Gj5amdDK9NBnEK1Mj50b3NXK1MrUU5bSSraM1jDhlbvhW5dNRvc1uq9RsUDFAhULVCy2XahDxQIVi4c+g6hYPHZugO5rdF8v6b5u4bDGMhvoV35s5a/X4kVeQYJahf1YIi3tfJ90lqK22Sed56gt+qSraWmfkrd4BXkJmvzQj9oYh3YrtFuh3Qo1FbRbbY/NAO1WaLd66DOIdqvHzg0eu91qldYZNMOgGQbNMG3MMNpo0iJt+Yi1AfOrBObNVhM7g3nRbqLTqIsKYL9DlEmXaKtrR+Zx99I4ZmFCcgMsmlnQzIKYJ7Qdoe0IbUdPWltA29F26O1oO0Lb0UOfQbQdPXZu8NhtR4h5QswTGts22NiGuTSay7zQxBs3Wt90oZf5BrhLBl3PtcGpCgUqp4V8QZZ6KbzTI9eRrueS2eMGbExveJTGHeLptB2y3DYQA0JJyG6NhQ4tcRudeKOOreajkFec/Kp4xdyoyQcMlZTnuwXfx0TAaFVEqyJaFdGqiFbFR27RQasiWhUf+gyiVfGxcwO0KqJVcUmr4sKJgJe1MUrlcH5hvBVXw9sgnRTVN1TfUH1Dho3q2/aIzqi+ofr20GcQ1bfHzg0eu/q2PiVlBdrI5rjm0RHPVllhWKYj2ctVV3lCli853LV7aq4+TIpNawsRZ63ImIskimcu3z9677c2jqZdCd/SCa0zDWyj09rFDB+qYnHtHLBmFeLsEGe3SvbeK16uddavsrhyKW2YBsIVGbNt0i6mD4PmolSsSrd2cGUiIpKMaUJ4QgSLIYI2ielwyL0eMZ8OCaNxwFmc9ZNEJI6CgIAaiHx9o1F5TeywbpZ1LpynUbwA3Rvo3kD3Bhq00L2xPaZldG+ge+OhzyC6Nx47N0D3BuZLQ9MS+onWZ0habQr7Pa2739VhlHUzx1tktatzFQl6k9ujBLqJnqCb6KH8Jpl7ZwEq/7RA2FUO5e4JHU0oDaCjaaXygXWz1uplyv1GOSd/o9MutHQxqeaimJvB5VqSJWuKjqhyEtYeuR5nXyJ+xAQJI+2JMo4okoYJD8gsSk1WCI5JWTfb6YQuFHShoAsFjWboQtke8zW6UNCF8tBnEF0oj50b3M2F4h6LQGASStUbIVWgVI1SNUrVKNGgVI1S9eacQZSqHzs3QGASApPQFYnApDU5HteEStr7niMTfuy0gCjV1ot0ujUddSNrfZp2/cgCRMnh1+wQHnpB6oMf01VYEn2Tq+25AF/ZeoxUW4PRAyKP0M6Edia0M6FmgXam7dHx0c6EdqaHPoNoZ3rs3OBh7EzNSPgHSN7eCnW/mrqILtA+WrDQgoVg+jvatGSZxDsYtNI42PtuuM7C1qs0Diq2KrNbny8/NNinAE/PQn8a8TCBpmQYxZCiKd/uevvTElagUonHkP8rZYT7LEyAcMVgHoMRWYftlidjHspfzcnZKQuStkVmMjOrAgSRfjP09vS4SH7lyU99ntBBoE+RbSV6ONuaJXrc9bu3UfyVxaJL+U5+LbK9rJ78bvbtdtasS5akcagOURCNiM8SyoN1WrdyLo4c62lwLP1f5FVuXmW4yRzeJDnEovxJu1F8FjBVK6aWF6kmFuG1Ew7CI0JJ/rB442BXaMjCJJgR1Y8oMqCOdIuoL6Xq+x1Z1Bd+hvTAzAfqc1+OkiM2GHiD/f1T/9g/PvVfDAan9KX3YnhwfPri1BvsL+vG2GzWWM8+DO/g/hJc45MkSYQPIWHkLRVEk5VhGmTHwX8Ab0majGHh1WdcU5C7SIrtpOyklwN2hAnRI7+yW/ObIJNUJGRMbypvshDW2u+RT6HHzF+dciuPhhDOOGDE50K9kG94TsEruwc/iYTyMGBCdBMWxxT02G52pzLC40WTaQr6ZDTVhuwfnZ3BLPraj6R+W7MQgnipSKIJi40I4RMjS0AZbnmKaSDktZ3G7Aa0V2IsQ5D/83OoIjp/5kEAMvd9zMuj3pj1eSitATRh/Sjs6yzrLsbouhSqiySx7VQ8TNhImY54yCfAXPY7O2EaBMWRO3qLgoB5SR+oWfshrKIsdDDdafDC0ZrMCbkl5+cPn978+05n5/2Hs19UTWZ1hN02lmkcDXnAGiWisuBTNdCpLvJPdcw4W9jOmocXBdzjzcNbdIHkwnT0Oknv6pgV7L2VL5g3L9/998/vrq53OjuX764uPv169c5hSZ+34jWmsBVshORwlS3o2Bukpjo/HUTeS7YDLsNfZ2fI/JhOpv2A3SgLcZEovWf+5dnHCwKXPuAUKKps+ZroF7sT5vN0QqI4+2XMR2Mn99S7UHxzJxuDfBGG2eZ+m3GDUbh+2CwcRrEnLXwEWvbIbzvTmA1Z/NsOmcY8innC/wCaq+eXgHAUMi+JYkEGaUJoEES3OX2FDvQ6/7ZDYGoeCFtDHoCg1DRr9dlcbGk70VFKYz+WuqCD15Z7mJaN0ZNpCx59cbDQfbtasPnhYs2PFmt+vFjzk8Wany7W/MVizV8u1vzVgtu0v2D7RY/Bght7sODOHiyytXaUGZ54PPFP4cRXBTkg99Y9+OLmKUqE2XQtmYu+z4a0qGU2C/BBNOp7ARWCDy2Fc+3aD3x2QkM6kpKGW3+h35T+crCv/mepNAfq77nSwEpH2RcJgDhGDnBKfuKurj9d9M9/vXp3eX3+K5y9t+8+vLt+1//04S3I0W1EmLsPepqK8X1tI3yrP00HAff6TuBO4Rwf7B+WTvJpO6FuJZ7xKClgOubpVWkyjmL+R/lWuOZ1eHL6IzMU9eugB9nl3JG2o/zU6D+ncZREg3QoSduYUZ/FThm2DkphDeh4/9WpS1EDU2zT+qUxL81s//hlmWwqj58ZoEPjhQ7O1aqetNtfuFl9Cavi4agPVCC+oasxbBS7LoPIVtVvwryxZAhN1GHIv0kVUwQcIPdtNRrA/Mz6oE1Fw6HLbSQfEEOfpClQvgNGTGWfrxuRF4UioRInF/CQ0Viyo2kUKqPZYiOUX6uO7y38TAYsuWUs1AOjScIm00QQHpIJmN0EAwSrIM/2u6dA3Z/ng3bwhNMSQ2i7ZXKYE/qtb75fHe1H9Q2iwFnA00sjhtUdUh5ACjjlrBPk2UH3pHnEJzb7ajdaMWWhr07YEqpsvUnGIkTKzdbZidM5hpgl+i6ITvWkUHP3/SpCqQbvCQfUC1LBb9hHs6JqAfLjUMaE1h9/oWDzE5bQupSvdeS2zmJpLCy1hg0aJ1wnEi37VOHVFibEeZ9Q5hU5sxsapHcysslvZf3UoOHKeMkGWOUDjdsN3dzIcTbykvzmGC7SwF9cKOecOLW4Rw1Q6DIIulEMOJRdOakcOFH7LgXrinkxSwS5ghYkFcwngxlJxlwYp1aPfJrwhEQhUa4TcOZ8ZWwqFS4vjWMwY8oP9MibzH/lBYyC3/Z2zANmnLhf2UyATVbIjxJpe2ShxwQk6mShDx/hTu2tSsrvIFFDr1OnOaaZ2s8RVkHyA7BGX3m/2lP6KZ0FEW0BETUN51vai0MtDaxG/9Zgoj7l/YFy0tXYsd9EYRJHgSDj6Jb8Tb0FCjkP9X4SjwaBCnRkPknGcZSOxoVDRWjMCHwFXKK7kH92Srm/K38StipPVEboYJZ1k3/wJ7KbKq/iLvGZn3qAIoiZD7CBG05tGwHAN0YkZGkchd0BFdJ9yT34ETyW4IceySS1euZwyIsIuXoSYUZvc5/8Jz3CukX/w7cp5bq0SJdLp0YbcMvyJdel7RdtdLM24JfXiEo+D6dpQv6qhgN+9XeAYHo4uJdX5HSWjKVtUi/29w+kgFQDC7PNVzWTk0nuk3HToPI+BpC+t6q6ltbcU0zTjEp/wAlFW2YjbVgZbORxdSN/jRLyPkrDFSJE1rF3h233Lp/PnLVeyyJvAnZv65B6IxaymAbBzDwI2OqAexp5J1tE8Yh19SYqqg7mInUProF1Th04OuCUowVRdAb+KogA0S2Jipz5lgeB1L0h1zoXRDn8LWhSGvpRyHpAceZB2Ics8cZO1KBKtlAHGSzC1wtzkgkW2sHXERW4iahASkAWCxiJMmjgcLUkHkGACAJEECCCABEEiCBABAEiCBAhUQiJQhAgnng88QgCRBBgPXwCQYAIAkQQIIIAEQSIIEAEASIIEEGACAJEECCCABEEiCBABAEiCBBBgAgCRBAgggDvDAJ8BAn81goLlLlmOzvTtBldp8irE173WUlp9Qg71aANvq4DKdvGhAqFL6TemIejDgEGQQyD6ACycCT/AZy0BGgSLIFGmL9vQ5B60pTyM1B/VRRlFRQVsXSIpWsHZHt4LB3i4BAHt+RGPAQODmFWCDpB0AnCrPDE44lfFcwK0UiIRtoGNBICiRBIhEAiBBIhkAiBRAgkQiDRpo4TgUQIJEIgEQKJniKQ6F4wRJmxY5HiY+pdXxchwwQj6BRFpygmGEHHKjpWMcEIJhhBPyD6AR+LHxA933jin9aJxwQj6NJHl/4WuvQxwQjiAhAXgLgAxAUgLgBxAYgLWMrfjrgAxAUgLgBxAYgL2FxcACYY2bwkFZhgBBOMPIEEI5hOxE4noqkk7MyenqDY+57n3Pixl3e4pxN5ABdQAJZ5Nb5GLOkWXyrX+bK2RzckpmE9dsujYRRyjwbZO9OAJsCMJC+d8JHOV2KvpNToaWhb6NeUcOTHYkWvbFmjvAb3DEpTK1e2v7YxngH9Mcvez8+pG/yiN6tJ9QJpyAOiaGTCaCBAPNC3oqJSZ312CpNwj2qNjP9n6psaeg/HMWo5QUUpbSL2dYemcfEsXqOsTmVAqOq0U8uFT/aPqqv6wb4WhAsCRroopjEPZiQNbbq4UUy6iSsvw3+X2pK553k9PFpRtMed+IuPwii21KO5LLnMDOem+aKJN25ksbJFA5P9qKihi9EmUabKfipQ1zLvPY8BTxsLPghmmrsyANoSFvARHwQ5/6rr0nxzs7iu4RTIfreS/b5yuHUy0Y8LAobA7KtS/EtU0VpFmZBX3JlXILt+8C14KHb9lJlzZlpsU5qbO5mngx0rAgWhOYkM/NE8aRhHE/JB0mPyIRqJWh7bI3+PUhPAI2554o0LuqWJg7H66s1R/AWjsTfe4xI94KmrU6Pz67bdgIukm79giyIfuJAK/5VsSbJGvYrAAS0FYMxdzUkJavdb+Fv4lk1j5gHbeQ0uJDJ3SrCTYko9Jva+Z//+kc+UPFNWeeGx0Af8O0gj4rkcBaP+PaUr9Y5872S4Pzg6pgfHw+FLdjA4Yt7+8ctXJ+xgcHhYSFc6VSZS+c1/pSyuynEXdMQM4uHZQZeHPvvG/OcwmbpUpg2vOByNetwHlnPiwEZEFIbL4v78If9q4TOA+slS9wTeaxp181v1Az/ct0YOf9jwxLqJqBPVPI330pNsneHbcSQAVQpxFeBTEUo2UWeAPPOoYHCLWCh4wm9Y4x6tpPMG2NvpsT3dcSQS+c/GCSsxm0BInz0wnmgvHPtGvcRcbaB8ZyMZsGd6X3AJ1vS5RizgUQnKYq1RRlGWWSRJ3kB8NZ0sPnFnFxV5JhtuFPss7g9m884wC3xgILJ5drMGs+az2fBSvUez4LPLhIn8xy+u4feVp1b5mxsm8kkOJWvcNHxH0/pBw6vWcKn8S/74paVyKjlkNCyyxnUpoRUR2Y2Akma8ChCB97XU1HcjvyrqKeV9RSj7ZRBR/TvSretWYrX3dxwzMY4C5xDMPogUWI2KSetPpEGls+MFkWB9FoJDH5CxAfsGhoz+MOZMOvtoOANQ/6g/ikCMgbFVUJLl6NwcKqa/fbq/nysGmZKRPT542fz8aM77Lw6bnx8ezOng+GhODy9Pj+dM4cXhnEkcnrya85GTg5fOr6gY1jT8WnME4FE/umFxQKcuB2l1s+Qbgv/h9KdWm68g7Nn0MXBi5quflDHufQdO8S63Fbqqhauba5KwbwqApJfDwnrShMn5ycBYIOh9RXnn6chW2441CBeGrLISbDJgvm8gQO3ohQKsuk8LC0c8ZH2piRWwU7nuP0zhUV/pek1LNaHfYK9jDeGfDWLuG+q2TIy0lKqr350DTXUBxL6y2W0U13z9RsbvtjA56IadrLsvZpCwHwrUs0DIghpoM7JNf0mZLvgfBfRmFVobxYk8o0kM+vREji8VrB957ukBUJiKpA+h4zfavtDqPletrPRbP0wnfS3ItKIji6OO26yYoSxgH+hTro/fLf+D1u1/4Q028SnE9ATpiId3O3TzKEtIQaBWBiyFuqrewhoKkigQqmn/JQMJ9v1oQrmzh1XFEWWdtKTdudDvuuNTCtDWGou8CqxioT+NuLIdtPlg+TVpkFjxvTQwTub3QVdaCAENDJcmfZlDgEmakY31bgfOpKapu+uai6oj0jjkJoWuojHZSOdKcMePTBPQ323mBI0PJ970jgtkaxWOwzhvAXMA5t3GMWUxj/x+4Xg4omaOTsuhn/KHH1lBmpr3c3PMHDR9PXJe2c81517/2VT0LabhV/i8c/OzxwsIPhC7xNkNDdbDnAdRJJIiGWwpjjpXiCZ0XsROxkwz2bNjBFSzVF/kOTYKf0Nflh4Opj4wLcMaRklf/5GJta5eGsKzneLunAiJox+ZVKV00f68IBQq1dEoznI53IL/ZaHDod5QxhDnmRMeRGe4tOl6qUZEaezidbVN18KfZHCLz/plJtSCOfFw6VchaQ3/5iSt8WH/n2nMhc9rDiaIMGzQ92J6G7iDlBYiNh4owMte+zLXmBbg29nel4L0S5TXrCP7lrA4pEE/4OFXp2czbyvSQZU7W+0y3jMvahNs+tIlJtdT5cJTMVY6CR7Rg4fGavg/WYZSE7sAQUdsCAFIyZgmxKNTMqEzEjNQNQglkIKJxSaKSH6gA5FF2sWmN5N4AZ1MBaEJidOQAN2yLIYtl1PGrY6cFgorMPb4ZTEytvFCZqQkgGAJAQebToUKBv4qNGGZ0hg0qFUcJBMhL1hQVjnvwDdKwQVOo7xeFDu+1DGIdq9WQp+kGy/rrpnOH+xbp/1uQf4vD14duoL8M/o1gTtQQ9inzIOcH/1s0xu2opQeoEn63dcK9yCObgWL+zELfRbXyDT56ZqnKepR7nQyypaDHBKapC5ybDzM1ag4ex3sJgvwTjELvUKegoqJ99XDmngPjucYaNdmA5YorplI2KSvEuz0MxN/y6W131UmsLqdbNtLnahT/760N7VVuOcd3/hwRzL3rmHuNW4Dd37Dgn0yM2Z2jA1Ek/eyNNUp+WKsKRkHStVbUoyeK656WWC0FZaSqbLO9lk2pTqMhy6dxX1Nq6bgshBcdS5Vtaj6s9rmJDafM+OlKDgYyv6JqpBdNSY6LUG1dp7MppQRR8vUWHUllIlZKTDSclQU7WdFQ1jZkGqbvRowcH0eDqP5PkqFQXPZ5qdOkQgeGBiJ62ESJTTo1/VaYfAqxDDHpRicqN1NM3g1owVwzysoWQeUz16exQNKV+gevgcE5fz4UIcpd+XhoNkWSVdZwx6VUJZ+BjHLEFyrCWXUqJTzDDO3Amilhrnda5zigEkqsyj6MiPDtXBLgBSqpMmiEXqoSFgGPixgD9/IZ7p6eQlRWMUfmtYkZLeOFwywiJERv2FhsUh6j5wPCZw5AD5HE55AgEEUE5ABOtAlxP8HNPxK/nx9ffHs6jlRDF0lLxDEkh9UwfRwRqJEap+FdvHhTyQ+1D/qvO8SygRxGWDYAqzXIPW+sqRHzog8SuEIRqK+rnuDqUSQ0FeNWa2hkHozpMTzSTqFjA/dAsLoiWMu11cpfTFYzepT/TlQOsWbcWan25BtyPlboiJrLUxz9gS+QhMZI5Rdmk9TFp6dkzdgaXmTO4fI2cV5j5yFBBJwzQxaMRVMB/3mppooJtrXoj7ULl/LGjL7O9lLITVWY07/JvSShYUrQpVWCWuqSQlSADWVKCM8Aoh6PCPX1x8AaahzuvXIGeQEN+Yx8Zqc7u+TZwf7Ex4+7xBQhMmzI/3XkXo2ft4hoOGSZ4fwT6mrkmen8G+plpJnB/KBVEHJs8Nj+ENBjsiz45fyHQkvIs9eyIYKSkSenSqIco5Clu90EKG1YoRWzfmpAW21uxs1sK7c75fvqo3QPiplCqzvuwQAczgUwdOzcoLRHtr1MOitxX1d7aBdhSyhrl1ZGOq1+s2ZC/3KyTHAvpxQMPfkatFh5eyZRpgi//Uf/ynlKdvUkslA5K0aiPR5wCckmh3E1EyM+okIlhCp3SjHiJZlFaqrJMi5iuBUNZ1VL7crD5xDzD5/2yMfolsWAzif0GA6pmE6YTH3OmQ8m45ZKDpSRk7B+iztK+5aE3bmbVvlWDz3dgmpV5OWTHmGwFsE4TMQeMUg66mxgkmhpriVanPkZLR7OG9d2eEe+duYAeNNOmQQJWPX25DezFxYa01qBE8LN1ic0jt5YLNen/388fDkeXlmNaWU7nBAcqiiczh6vs8yyrH2Ic1FSK7hkrQAXC4Bqiwu6LV5pDIvwlEzey3MbVTD6BEFuzRVtwSBVl1Z9oboLyjTlBT0L1RjsJpOZNTRKIpU/yFN0hhy99BwlMKWgRWVM/G8RzSeU1cnE8Qb05h6CYv1Z0Q60GqBFHiL/cqEqzRQj5joEDAXdazM/fCFN2MaquQHEB8D3xuBMkPJMA0CEjMV4Va8m2re81LwaUhqW4yq61wL8unNJeHhiInEFHu7ePte1TRTbr7lZiCZQQ2tL+QIdmXvvOMxrkfMzpPoTvaL2ZSdGeMbsLWIl22Fl3UvbHtw6YMBRuuBdyXZSj0BapIQq3NiOs9zQ6hZZw9aXRkn4LQkGMjnRD3Pgg6FApvQgFPh/jz55d21vPxaiMsiyCBbOcT9FTLgsuQnK0nus4vP189Vt1JYl+ZIkP2YN44A7wLh4LdSjkjBZMV8E1itbVsEcjR2lO3xloNAmsisGkBmnoFhE35IIhIwANrouZM09IBAFWOEKzvfZnl65CPYNAcsiFSyGkr+ymJVw/GPKGQwVzuhR68g6an73dM/9LxoMid+czG47+rpZD16uLhYUvRTYT5ytzJpmcOpoN5YnnW505CClpKYjbhIGBjOvMJCw8GCHowt7X+veh//j55eR8ptZ4MXTeQ26WMoyPH+cY9klTppAocCQhlDVvxmVX/pETelUdOZBtSTOZyjgAkq56XPd4eICO4DkyZj19JBW8i8MHOljTZzlrOAsgqgdUlrPbBWnsiurVE2EoJ6Y8ZC6flrYN8LQLttieQ9B5VDBj4HM3ILlGYWpbsxI0EUfdV6RRkM7iacH99crIhW3vGONOPStw57ftcs4vNx64uySC3zr4gxrkGabALPl0dQVx1kQXz9OibRAq7fHpJfwshqiVhxfUnBZGOzt1YIPnlH5WaDMV8jBZXrr9CF9kISMwMrHJ68Nf80BFV+b5cKb1fpespcs2eMkGZQ0OWugt+rhmC/3NMbqRv1yHvVWLo2pVZHdqETkdDJdFc6neCzPMw4W7848iYJpHwzrECCUkZPuXjWnHfh+S75NwMK1nBjOFXmp2esN+qBzYbFJBsxqJ9qZf6NgKPE9WYvX5V/09smbdZaVJSQZmBfanpkN49icL8QyJw/+QufzB4Cu1toyzrz96uhANH8GIy7GnBN/EbTZVD+8exCwA34LFjhUMHc/MhLZWncIfjnACLRUR7OWc0xI7+qNVOZ/EtHHaRrCSIPAjKMUiubBDi8hdeRHu+O8tmLDskX5flPrmVWop3pVbXcy19qtn9mM11VZEvW9T8Kl8hstd4W67vgM2oTDtNoWTU7JMiAedFEZoT2ZeZ/VbgJrJQE7MHSbrVLQ38X6J70lQq7cRJZfelsObIkQxBIs9SMJCyeiJ/IbhTvEo24FvIoZKfEfs0WfOFNeSLgfouM7oK2Evs6/6YcaMwCdiOt8cqum4FGQETPxF2ZGszgOuxABEizN7MUr5+UVheC7KtsxJryD2VNDJMGTK5K453NAo/uajldPf8sxUAhRqFxneoiv9oJTI7gsHLSTSkLE8EnPKCAiJN3D3xOkhcpBi51U0l8mVYbWcmdtd87bg6XmePgvas43TKgrWaV5sW4LRjH5k4MBLgm+D+ItJJrpt+TjEyQCffiSElKoyAaEDELE/rtNfmTMYqbUrVU9STYCEhYh/wpb0G9OBKi8FwogaZD9qg/4eGe1Vr/kgppgw5984NgUpMWe9SXpM1/3iMfgekakJgJz5LanArOIrI+3U+KoHpJxuOSiMRUGaCaJDqLn52AQlcx5+S8aiebyE5nZ28a8xuaMPXXn/7022+QrvS33/70p50vtSE9i+6Tfu++9mkQRKPCNskfpnIDYJPkn4f7h8fytw3bGz142Bo/8sTen/6096feOJkEenvgOWyP+q26R3eJzizm81L/mh+xadVjtgOdsnimH20CN0uZx9QD49nSfZJd8+YuxB+ymJGfVQgWuUxDYh4K8vnyg8gKVkGYHxlGAM8y9aZMPFiPnEugrnKh7eqfd+d7jLNgUXeEJnyyqz5JZFOVxxSYpGDMh/G5aH12DE6sRT1ZPgK1lIxOjUc+VfqRsnJEaSK4rzQrDYs15kppggYBi/wuWeTvIHFC2EW21ir4U4vl6hfoR1qoZ1FKotvQaS0p1klwmAPdsbJNM4pI3taUKdfzATvncsNYMhQXsoWqzXreuNG6yLflAdQb3DZI1j0sDcgl4F/OMYrSi+B5bJqQZ/v/9R//l4qjbR6gBNhZA9R/t43FrRjvY1YIGQZjrLrlcGVfZ1dQgMZCQX9Uf5P/8fGDPGMdsiu3e1ffaCEXXh8B3YAGwS7xI6gmFyXjZpVQBQXnVE/9vZqQ4flhwfXss5tEXdOSTOh0CuKEXCj2LQFUgNSDdHxrtt+Syqi19dWJLFi5ppRLX/nnyw+K82oerQR/St5cXRHz0R65loaT2FifZKEhYLe3PBTqqdlFqY9pP71MkavpgawyIHmwT/58/fEDGcZUsmpd0zIzzUhN1Pgp9VzUQHgU/iTbnV2ck5jBygqtfkg2K9pbuUz4TXHRf7HXIYm0pY2OgIqoEcoDBksGHWgRBpxOPo39uQKMLbtIkQWKbUpLQQSoj+bD+ac/7QGqwwu0dLZArHfJgGBtrJKb5RkqnhtFwbK9VlPPBTkwdwqqQc4ZNEW8Jj91yO8d8t865HuH/OiQ337TfCOh8YhBaAVEXgSMsIDBUvxE+JBM0iDh0/xH/d1OgTioIBqh2WaQo7wyjVOCPkqJjV2XXC0i8flNDyS+rq6/t+oAeNscpE4bbGEu0OUbVDMkWQQ5e1GLf8UXJY7hR0nsk0M3f7lD74sH4vMUjsGJcU9CLA7RjYmAEyEpgtRZFT/T7qAe+VW67qVOC3LA5fs33ReHR/sKA2Wdi45WzhSdgrAXgCQFkQEtesqmZb3RgwC/1O78z9dnP8vG05iHUuEkZ1dvzs81oc8/8OZSNvvw3iW5ZbvyXUH7u/rTwO+irvwJ7I5dScVkGMgasxI4RAxnlgI3Z8gIvmGLStCN5GoBc5CbJc1+n6QLHCImlUHMkqK5cIq6C2dEsLSWcZJMxeu9PQtwsKc/0fsmVRdXC7gZXbtZVZtpm2ahXJO9mnWhuKJ/jm4LtGYo/cWwnL18cbQMArKH2ZufLB0kE0GU9BFDQCRUmg5myvBpAAGWICoNQAsgOuppmpUsIi+Wnf02L6XEGuxH5VwR5Qhe9YQMWHLLWEhomoANAM7yLPREpzGW5pUMhjlpH0sjE0OQZ8dt42qKpjj7wY4jbObpZr1Y/blpSkGRE6BUBjeu/NtO0nClr+psWnFJqDhWIy7nsazqdneymFZJlmWkaiWgNXNiXB7q+FSVp143jw8XCFeVcpArUlXDwZv8Gy2zday/EvYXkxewkB7+oLovdu0yOyBgnVniMVJ1271AGKmKkaoYqfrEgk3vuXSB63WMd93ceNfaSgl1MObm4gmO7ceIWoyoxYhajKjFiFqMqMWI2pUe41WUsnHVO8FA3W0M1L3/WjeO9xtq37R4u7Y2zurvzjKldlwjxuhojI7G6GiMjsboaIyOxuhojI7G6GiMjsboaIyOxuhojI7G6GiMjsbo6I3HxWB0NEZHY3Q0RkdjdDRGR2N0NEZHY3Q0RkdjdDRGR2N0NEZHY3Q0RkdjdDRGR2N09MrsR6pEtUOlrICrMJAaA6kxkBoDqRcOpC6VtLeRsc1l2+cWam8qzX7Gc2C/AZuFirPKE7ldRdqbS67fR611WOYjp+0ij9dR/hIVh4Nru9javnLQKe0CBf1pJNUtAzNVQSwDkFhUEfIM6f0Tqb6ViTTGuWe1dlwTnynHITDsaRyNYiakxmupJZcsiWfds2HiCrW5yu1Wt5QDGHYYySCtJJ6BkLtjV/xe+NV62epgf0cBm+/r5OViQ5szmJ2MFwf7p19WeiI7i4/g1UOP4PB4tSP4spZ7eeKiefmdAadbFNOYBzOShvSGcslZV3xb8oEq7rye23PPl+cRkO0frhBiAfqklI7+AUvIVVDizut/fIFLAj+wCeUB/NCRf35lM/kURkxHAj6XhwifG9aqAC3e8ILFUnaMQnGZDTCT6kEgszHvdMp7Ri/N44G//NB9BTQ8U2dWC3Tfdwap4KFcIzUdBmrdNOYikw2HMbPxAJl++K07ZHHYpYUOdwYsoTvZQ2UbzKVM+aPwv3ZHcZROuyojwI4duWy1UdHIppGSKeW27hkf8N53/a8+93/sZd3sZQLK3nfu/1AXJ2CJPFVwCuUZP/ftT3dVi655FZhWOplQwKTsvJXPNDSnFMzd05hBO+QdWgt3cwVUDQLCEx03zSQcj5Ipiyc0ZGESzHq/hb+FeeT8a2k4mjvrjMuLve/Zv3/ki0GeSegfEx4LfRom0m4snmch+DvSFkMnLJF07B/fd8z+ZJ+DCw1T1GbWekJVT3e8I987Ge4Pjo7pwfFw+JIdDI6Yt3/88tUJOxgcHsIOZ19eyRcLsfE/4N6Vcjw5tAk7x5M6GT7mecI8T5jnCfM8YZ4nzPOEeZ4wzxPmecI8T5jnCfM8YZ4nzPOEeZ4wzxPmecI8T5jnCfM87WCeJ8zzhHmeMM8T5nnCPE+Y5wnzPGGeJ8zzhHmeMM8T5nnCPE+Y5wnzPD1NXAzmecI8T5jnCfM8YZ4nzPOEeZ4wzxPmecI8T5jnCfM8YZ4nzPOEeZ4wzxPmecI8T5jnCfM8YZ4nzPOEeZ4wz5NMknPscKhkyTjCCDAhaYjph1aTfsjkniCKeRCzoSAcalxnMCNTcCrqJCO48JhAZGsSiOgUILJFFI9YV++XIn/Ar3REEQh9WZYQOy2HzgShRMgFUnv04FyOmLwjdelHhizxxu7sI7+A2t4u9cilAnOxggNYzUMa2tXFjoY1/WHakQ1KO4LpRjDdCKYbwXQjmG4E041guhFMN4LpRjDdCKYbwXQjmG4E041guhFMN4LpRlxfw3QjmG4E041guhFMN4LpRjDdCKYbwXQjVdskphvBdCOYbgTTjWC6EUw3gulGMN0IphvBdCOPDReD6UYw3QimG8F0I5huBNONYLoRTDeC6UYw3QimG8F0I5huBNONYLoRTDeC6UYw3QimG8F0I5huBNONYLoRTDeC6UYw68VjzHoBaSckpLkx+4RytLrTT3xWCMKWGShUa+FIQIFZJx4q64RU3n4GFTO3RN2VcmGKiK1xhWOKCEwRgSkiGtI4LH03Hmt+CUzusLnJHdaXegGD9TFYH4P1MVgfg/VbH2OMqt/KqPoHDEnHWHKMJcdYcowlx1hyjCXHWHKMJcdYcowlx1hyjCXHWHKMJcdYcowlx1jyzXOgYyw5xpJjLDnGkmMsOcaSYyw5xpJjLDnGkmMsOcaSYyw5xpJjLDnGkmMsOcaSYyz5yuxHMvJM4y2Xt7bZvdzBRYkR6xixvuxBngFAuD+No8k06WfxassfQ7s7Bdavuyt36LjO2L1Qlw8XrK8Djhcrta18Qz6W3MZ4SoynxHhKjKfEkttYchujMrHkNpbcxpLbGMWLUbwYxYtRvI83ihdLbmNwMJbcxpLbGCaNYdIYJo1h0hgmjWHSGCaNYdIYJo1h0hgmjWHSGCaNYdIYJo1h0oiLwTBpDJPGMGkMk8YwaQyTxjBpDJPGMGkMk8YwaQyTxjBpDJPGMGkMk8YwaQyTxjBpLLmNAcyPIYAZS25jye11l9x2RGbnJbdzsFmoOKs8kVh/e7H621jZfJ0r+8rFUPWxVTyamHsDMriGzwYzMgXfrXROxTNc+EUX/mT/qOlIg08limnMgxlJQ11sPZBU19LRLmHtu2fDxBV3dJUb8W4pB2TwMIr1foHE31ige+Gu6gXPgx0F+sbj0fp4/HBFiApQFyTz+wcsIVcxZzuv//EFhCv4gU0oD+CHjvzzK5vJpzBiOoIi8VYEqLnjGkvkDS9YLEWDKBSX2QAzoQ34rQ1pplPeM2pHHu755YfuK6DhmTqzml9/3xmkgodyjdR0GEjt05iLjPUPY2a7ezPx/1t3yOKwSwsd7gxYQneyh8r0kwsR8kfhf+2O4iiddnWFejsw1Wqjgk1NI4Ugkdu6Z1x8e9/1v/rc/7GXdbOXxYvufYcHEDKxZ4VMyOMYCXno4VDKI3/u2yPpmi668HI3f3nH5ICCyZaBFRodlt/QCxaDoCQkiKAQt5HFJxgTpYJ1lAKBOySVUqEyx/q5Q0DhfNg3BW4dsVDOIhzlwRW938Lfwjy4+rW0LcxduSxASOx9z/79I19Q8kyiw5jwWOjTMJGmRfE8i9Lekeo6nbBE0sJ/fN/R2yfFPoiXMha4tcVAt6WeWxB2DRTE3JFsu0rrWD/d+lF5R753MtwfHB3Tg+Ph8CU7GBwxb//45asTdjA4PNz5AdRJn9CfwaKZOz7uyinyhEDtXS6lzDhNzZpz4Kw01U1jZIQdUWXHVNYgO6nvM+k+saBdQaRdRQbDr8xKGcXKQmB75Ey6AwVJpT34UEO6OtqvKYGfBn8JLiTwWJBLJlh8w2TgPLjssnO62yG7CRVf4b9RzEc83O1o+PQMGpMBG/FQQgWlWrzrDXtOX7tlsU0g8lKfUIDZSPVf/qt7cHjUZK3NTTFlw2VVeqjuwhflZrW7PPzR2ZFYMpOTrIV0U7/NUn3dYvyeBbBTmdpckldNyMJSqyXxsa5LmjmtM0Pofu+4Djhnr7tztDo2Yf5oVxOD8OmGxbHMDWBHs+ngffMJvTNLBxy0QK9jtMETijbAiIFtjhjQAnyffZvSsJSNwJHJoZDWrEQKhzxIWOyUpOqzKLRJ/uRI9oSxDrWxDp1ScIKDFVSC5nrVxZToiXDB6AY3a10dxH3BeZbg9vmUFoLHu7OdzIPwmX0DVK8c/8KjL300H/3BvjV4RxzuSRnil++38TzVbWUlsZLJoCb3Vk2kH4X9IeVBGrdIFKotVtpA1miba59qxVYCGwTzvOesUSllC+QFdKX6K0Kh5i2a7KZivZOtO/phlXiXxyJBHv00biEsFhu5EhQe7r96cXByOAeFBP18aTG/fGh1k7RazJ/pkActtB1o1S/lAHJN9eDo1cuDg+MyD+2oDlz+Xf2sRZ7Hw5OTeaxZ99NmGeW861ZQPawsnqSoORqrJBVbjvMaJ2pp5vISR0HjMFXGbHmPb1gAW7KjtGXg40JwoFGwXUkUOQ6E7D036DtTXhbQZVuvuIokZnRS4yduomn2smX08csyKb4r2XgM85FLoak/xCXwQJkKV2RF88YR95qJeonIgQXZIWE6XS5L5OBCxoCMARnDVjCG8vNGF6qyjCxAZ9y7C63nHzDpGnW83ZSUsFHBzfXvqq+5tArwbbm1zOcU0tH0XaGRZ6nPoz3IAgoplWionhn7EZgoXkN6GYltnPAg4CZmJw8cS2icmLgm+THyTGaGMljI5x3zFBJI2l8R2mhox2MoxU3FywGkEZoOND8tttHoAGnO0b7DzPQgzS86OH9KQ/BF/A4tfnerOwUFTa6XnNXSKybfXs2atVou6cAA/N2DrJjUjV2G71olWBtG+j5LKA9aeMxaG3ZUTm8w79iGHbB/ONEZpkH9FOxh50mKFp+yUofrR6KfL9rxjzzIXR1cwyEWP7TwZik+UR1N4BsqMirREalgnJIZCHUPjSYd+DSkHIWPKybmFIlquZsTcKlZmlquWgkoS1BepcA1zpaOedc5jLYyuJFmM3bThOO0bNtg9SRp+DWMbsPcfYGQpsWghofVNTYaIOUkDRXIcACUWQJM8tTquNJ3hsv+GiXkPYJkl1rPQwdI9mMUJuNgpn0B/0qjhEKAGWM+5BSyzrVHp9QDE7iN6TQtVwzoXA+Ac/+eEZx1Krv7+GSb+mL/9NWXlR6mivo6bwQHBysewZc1gY8dpPiME13BTZ7OqQqltgn0VNnBiOzsXsnI0ifi6OihT8Th/uafCMQbO/DGK4QUl6C9Yilw8T+jgdzwEWuHJw64SLryJRtJLCOD/6J+rcYMWwV04E2lU7jwwgj6RdBv3ahagH7zL0MyBvNNlXjP8RFXvZGC/9vukMX9ZTs9rC1isq+Bym1dNpANTIXg5wcBbt06K7POg9E1pUKXEGO/HzMq6h/X1BSpUebdif9krRrBWFjXVX1eQcMatD0a1slPleXcmWIQbHl1Q3aZLvSXnTqFWuw+D4fR/J2Rd8lx0mSKgYIQYD8x59b5NIkSGvRrO64IEak00+t7YF0Ju587hsAWF6XJkHIeTtMEknUAtAoMpe/uXYC8sx7aydIB1X2ifMKaBTvdH8bPbrdpwBnG+VmV0IPcblEYMk/mfaRmuXGRN1c5UZLxtmgoq4yI7GlNoVaHAXlGksHW8Ywy9QJoIMVQRlWbCaptqkclOK98DAKUqseZayOojKAysl0RiHOKDxXBJj9+LAMLy3cWbghfJQev6BfLzBL1ilyvWF/GGRSwUcB+lLJfje/tahZ6AOLxoijwdcZoXNY16y0/kftOT/PEvZkHLx7cd3WCvitUD1uph0rbW9qxtff9n9EAmu0s4OEasaSiXv4iM0j/JRqQtxrDWNa/LnWshCAa5agUyzxXrq0t5eonKpmPSslUx21JBfPBtdX2bqiC+8ncCdQSH72W6NBH4ACgJoKm/s1dZJTlNkKWA/lL2WO8cTtTvyylCbJYV6d1L1j8oU0ApvuCPFU1/ct2QjXsTuNoFDMh0AeA4tm2iWdrSWdYW4Ivo1Ly/lTDLvWbS4Wdq2SoflGMRPHx0YuPjmMB4qNHQ5AgBzKtkseCAMNzVuQsQOEchfPNXmQUzjdCONdcXraI4hHr6p1TNVKgqI06/NfFFL6eFq6BqcepSqpbFMfvbLrdgzzCi9hvTYRCV77oilIgH9QTV6RCEI1MjmGXWoCWW1QNNks12I6ghzVEPchb/ICRD1YRKIe3s1JurqAPNKavshPHyGfl5It1AH155HKkSuHtQtEqDEbAYATESm3Bljy8fI5KECpBT0UJkgrDMgqLXolF6jJlImuunlyZn4pX7d035qUqeEGwCQ1lBVq1qSpLSGMJJriXUFXYJP1OysWYUI95VHrM4/FMYKElLLSEhZY2KF81FlrCQktYaAkLLWGhpWrSbiy0hIWWsNASFlp6HIWWiiunpMuuJXjqtkRy/h55H8VkkgYJn0Q+VdeLM9EhgiV5IniQ4c2Lu4L8rtXE36XhMFRdyXzUsynzyZTGiXhNfv/Hd/j79S5QwN2OpPevd//rP/6f3R8doh9llSJ2OyT79+vv8H+q5Y8vv/fIOTwhHMz0wiQBloO7PPtlVxA2GTAf7m5fCdpAPpgHVi+iPgA0wnAV5vflTDkQySZBCOuPYP0RrD9SXLytrz8ytzCVcpM7FH3BQRaUREzLIGqoPXIGcllIE34j5e9dQ4x3pTIxjSNIp08Yl0n4lXUntlqpag6DKJGel6K1sKL1LoHXLSqyDwDUxTIuWMalIkxhGRcs44JlXB5lGRdld//Kw8ZjI9/XohosdqaCKNyP8h5l3Lh5fNYXrTIuawt7wCowWJtkk9cTa5NsRzYfrE2CtUmwNslmI+6eJNiuCWenWyyFtEto0iYaSLUrp3DKAFzwmIuEe6KaMMBkciKpsnGHfh73k7+HOQMQUPfwmZiKyXrloX8I65yCHLGaCBefjWLqM4ej8TpOGbmVPjOYyMW5CQWHHtNE3dMU/LdwdTT0Q9qk2Ih6MzVhLY8a+VI+f3sgnzFw43YF/4ORgE948rxHriFSUa+v9PRlvfNQWVbhCFpny8IksXDEQ4ee/k7+3s1SvRlDYY9cxEyAJ1liEoBiTGhIR8wnz26OnmfHX7hAcaWtcIgvl4dkkHpfWUJEEsVAqxTF4iEZzJI2vZqBXvE/2M/winsD1dtvmkJ+ZkFE/cZuSmy58krHMZrip79kBhf+h2MX/moeKXKd7QJ55vMJk+Yy0SGqA7Xnz+evUP6qe+aqO1G7NqVZF5p37N6/SJlEiijuL0nnz//P3tvouI0k64KvktBeoOyBpCrVj7tt37nYatvd43Pb3YbtnjnYsaFOkSmJUxSp4U+V1UYB5x12n+E+2HmSRURkJpNkkqJUkkvlzsFgxiUmk/kbv19EoJtyXJMeu5mhcVnG0u60ZR+YqwJSf1xLoaNK66YxBAsDwgXS9IPlG09Qnvm8kUD8Oxd50zMZVWx/mF4Fy6X9zXaZ8U4Zz5xdwQndD1DoRom4k8xdyKIdJG0MtzfeqAXcl57ZQu6LBsSDBZPD6ktcFkKq5iJImPF6ivIgBrWiewV8bM1S8GFFZZdX4S0wbQlLejQayPicx23WrZZXal4fPe7RXWK+KySwBqJaioTBe22jbn+reeCA+rAHlo9OTpomom9EyzR+JOO7cQBv5nEqCAcbl46bAgPK4AqJpX8EwiIEdQEbB+99667t6XPNB3WZxH4V//Gko4rxs4y5L0Z7aLH2bTJHHTdSC8ivJP+qYt4kmNvcEwRnz0WxJEP2hn9mpxdPmDfnCfeA6rTvyNsk9nNyCIvoOkjiCFSU2h5Vh3/b7zWBe8q7TX2jTJ5PwsADCMEyDojyWd5eu0rVbpC8WuXGaleVcK48m6N07o/ncZq1ijp1wQVK3Y6NUrd6POuPmh+kOsykvMcv6QnsHWmcKmxGdS43PEgZrYJ+YFEPDQqFIpEZ1+XHC7jK9RG8wOeMnjNYFzxaFF/Aw4Cn9s+zn159KNhfodCmEshK4T15koDumYrsOYsjmXSPPXr724fH1C2B/gMJmRfePBY+wV1RJwe0YxgIX3FlGV7GJrG/6pMn+SZIBQsy6AO2nz0CjRp+yGLAS18LObeU5RGl8ywxqdrOd1meIXsD8OOJCGOCWnP2d5EEUxjpHwDPjqUirwS50iWRocDyh6EXL6qX72wNgsrE54/qx96Wd08eDXkQxkbgU3nCCD/G49MvwY1hfRFujecVd+s64IyzRMyCNBOJjtJRiwWHA3pQUV3/s04O/tdQrgUPTBHYixe41PIopez85ByCAFFMSstA+NI3AcVSBL3AzIfMTj1oOsuQe8JniKBJOc5LntE+SwGSnQq0eNqWDtqKazD7yFOdxexKiGVpzjiLeDpFDB2CujE9VYZdG6NsvczNm9ocvlajBSCESL1kzEMIULJs/uvCGJoCnCdO0ZiVQJhpme3U6cErDPBbCB6lgAia40RTidvDGirsFS7X65cKvD8ViYCvQagnRMZQ6i513uQV0p/s6xOFuXiwjzTjK4xBLEvtRymBwQeFtZ10MzTBdb/9OzQTb2cWrvJK6yHQ8T09P/ZAw5mE8QyUT30E/lmK6Bmd2DtaeMsOvKy99Jv+ZO/HAHzf4jP3snDFboCdrOL8KBEsjGPAQgFrQ9vsWu745sXb3THEhGdijOdg/WSXIglihX+sY9l0jNOTE/iPoQbgD7c6Lr3hfTP6IhPePAr+na8BO38WmBM1DEAjlRY7iTLapTwir8uOFv3W7t8omWtQttxzhqjCRFVJAWU8qOeHKh7a00M1wGjrWaFUvqju2aH0zsOKtVi4XK6oTkL8weSKut21zfGXwsD1TRgdWzLoaHlgFzV9ZSlfs89aQV/OzMe2or5mEySVcTLjUfAHMLm6CHFAJsKvVSD2oRo25PmSc1up01Wch42sE84a4awRzhrhrBHOGuGsEc4a4awRzhpxP9YIq+nBXkRoZPEga6IjbRX3gXZ0vkjni3TSv5P+nfTvpH8n/Tvp30n/Tvp30v8efZG7dNO1O+ZUsJ0kjAUKU+VnKPkRHo677v6x/7DkljoioLMYeFgULFz1z20W15KwodCWeQjK1IoVOXDd8jqP8cF4jInYG9UnC81emRrqJ7swgYgbwwzSQ8ezjGArMpxuFPZCIdi39F2IbG1zY1OLBjf2S3zY6samJmnJj70UyYJHIsrCFYWsFo9Q3KUYWeRNmBjMCBMv/knBBTg8sPFgGEEQhiBQL5N4log0ZX4s+4JwyH5NVSs+W9Ropvm2RJzfX6yNlB3u+s2y8Ur5odVcLY7oTgEVBTU2VnDvtkt7NKdSBb+KWFVMHE4Q1qJwHGg3Ga5KK+vq2+1DdFrEPtnzvDiSZsxwxZZgeJLppNySO3HqoMQpKbNsJk7Race85/A2Ve7erBq4IbXIXtKKjwqO5pp44qnIvHmDNAU5fNpEKZ26x5SlMIFPlpreMye73EF2weSvzu/q/K7O7+r8rs7v6vyuzu/q/K7O7+r8rs7v6vyu2yVUc2YsZ1M5cJsKWC22NKjI2n5oUkFtqtX+QcJMgwHkN5J02mwg1CSVUlChuPLIP5a6a4WG6ELQZMWJpyV5wFB0P9g8Q0dpOW+V9hMpw2mfTfIMLTC173JnialaYlxAqDM3OHODMzc4c4MzNzhzgzM3OHODMzc8OHPDdlVmia76ZSyfczI6J6OT+p3U76R+J/U7qd9J/U7qd1K/k/oPUuo/ICejC+504QnfzMq68ATnSv+WXOkkSW/rTae30Ze+VVDnMWjhx4YWjsd2Tapi3cugLHEOoLNB0VnJWf8Gm2pp+wUIRy+M79bqgIkEDEwQCVqxFGiNmM+AYWUk9y5DYctwjPGdPOFhKMI+W4hkBmKYAiEQ2wN1naf0z8/E+GciwrlHM1T3SM9/IO75RrYDWvwGY7qtSPCW43wvDnwejKX4Fy/1mV1jyIRECh2bjbN5ItJ5HFotd4oqpTmk04efvWy84BnqNV4Yp2IsItAdwUAais/BJBTjaRKICI4Gj1aoJY5nMdC/VnXWNGWp6q11avBG1XXlPpb7jeES/MQzccNXLIxnVJpbyeQk0BYxSlkSzGZgPWWXnieWWcryJfRxKmus9WVZvT4UZJMDYyKCy5OCdSIVCVyiK7FKn7EjTSGO+uwo4+kV/H+cBLMgOiIFEaKzr8SKTcQswEqmqMiyI286PLKVn9Xn70svE6m2C+SpSNCyiv8ajE7P4LDag3u/wKL/OsXbWj3fdV5c34VPZHkyuzw1LAvjwG8VAR6gcr0IIqU1UznaZDVOxE0SZB2uUMt57vcWsS9Cy6qwf8TJlUhSOLvYBgwmuqK8Os36CbACnsHNouMDVpBflyK6fF1jK1BGe8guIwq0VpUD81RCwhTWC0xbibZg4YfqDgWUl3AZxsskXiwtThHp50l4dFUu07vVagFVsVIjeVwNtfNkeG4WgjQU7RNz3a2jRVbIw/WjncRxmo0nqxYqhLZttPFhY6VUqwqXk9WQ/XotkiTw5Q5o2SEU1yJk6hNyZ4bsZZAIctz4hpnziKfeEVI2eVeOQQwCF5QcQZ8dUXYXagV8/VjRL2oxZD/SWNGohmvNjrBuasYXyyM8fvDNINJWXk2GqYs2m1rV+CAnUV+5H3CZdIMhO4LnR+yvbB7M5iJh1zzMwcPAoyv1E1V+j8SNSJgecfp4KJflrww0etubw2JV/io3yJvn0ZV0fczBcwCbQtNjR1GcjdteCMFpYbyg3Xdg+t31ftkcfJIZ89STcg8SRugHPGN69MhpsZt1R5eqj+rjC+f1t1SUDgaMz4+9HDyIbAqXE5SLPtGrVcNRYb/QvJGSV+aOHp84AddTCHaBpDgOKXvEU6+P7tC+zFfUZ8XEHj+3LRW5KlSv1PK4eKndVapn2s5KqtojrW5dIzVttaWLoLZLbovx3duS5fbsVirsn2H8S44V4q22xYIYmnbKCimcYtVZq8jYWup9msN3x6S7tQmGC/4ZZOxkiofuSqxu4sQnCXG8kBaAir8tjrIkDiFFTeDN9dlK2UR48QKTzfgBwZjh7P3w5vSCgRwQRDO48pF/BPQVJdHUbAzR67ovad5DhSYMGXJ1lolkkT4HGe1IFpcGg2C0Ks63+ZrpgoI38SwDdUk1fQc9KKEK1TENNBGhuAYCP2ToZkOHEMCgpzwMU3J7gkeozgo0Y1Ji/rC+mOivi4jCRP5RK41AATxOep/srLVCFejM4DoLVEHz6Er5cLg3RxIhpLNO+NXJYRM1n6NUEU2ewJ0PyXM4WRERNZrh14ph9ZnHl0vhw9KjDwjJejyVJDdJ217G3TkZnhtrosWGZkGBfx5H+WIs99OyLvSmqrYdT1GlFr4+AYTwz5OouiQmO7COv/JtubWjE2s1bD2Di5OKU6E4NvRS8029Fl4WQ2fyXPX6vflqkgQ+HhGaxTiOxlMehHkiLEJaxWFZz+de0hI+Faa+VpWhmQ7Vq8oVCnWLklP0rBuV+wHialupEsFXu9C8oNhNza6IrfvyYZ0/VMcSLPhMjPOkgzxablSM2oAVnDz9bnRxetLOu6CfTx3mVwytaZJGi/UznQZhB4UKWo2V7t8y1dHZ0+9Ho/Mqm+5TBzYYknzWhHAqoTMu1nF/2U+XZcR5N60gPawt3qeyXloRvGFtZe+AC/lUh4dUZo4XPA5bh5mu0kws8I5fixC2pEeWBxAV0jSAm001FGPLgcDeC1eDTTAq69kPXjdOs0TwhdWQ1SZblZdN08e+xcxnL4yxBkdZNx4De6HFkbxLcudpEi9QONqH59Obx4HXTvcrdDDyxWeLnGv1F3WQYR3vcLzD8Y4HyTuqz1v9v0TMNqAz9t01JFf7c5jf2gOInmDL26Y/YyM1vLAS1B3plVWCb5PI7QcckEJjq0U+94P4+DrwBcASeUTPFEsAQ8ozQP70wY+4CMIwSIUXA8oLuQUwmDTjSaa0MvwYe4ToSiabPu6rpyGoz8ZXUmnaxDdBJVXMiHnxNbplXuJgJ5Ill9tMxBSV02ilXZfaQIJGInwHfwLX0O/Q4ne7NlXSAXG9cFZbrxi+vZs167Rc6E8CX++9rBhq3jbzfKOeLc03Y5k/rgMl72p+AsMTfrhkfgIrjRV6oho0T8EctvZstLRvmjJp280jkc837RgBKnGeeGJMB1dxkM0PLbypTh11KY8m8JUh+5UsGWiDAykRkfiyh1bDE3y61+/hx4nJWUWmRu5XMyr46mvq6Mkuy1Tbyh02xSytYwOdoUtmR2sQTE2fanBi9dW71jF0VTyUfK4ZaBt60vAZgDFPQya1W8ghzDYD9Z3W11ipvTxgeUSgvgnwEkTvUJ9upXcDTI0z9qODo261nqcWOOqbOMrm4Ur6WP6dxxln4rMnhC/858w41x5fci/IwA+zWMYJTwKIB5MtYTPmgvvSWQXJfFeDy2kmkvoX30v5KovZDQ8yJecg4BW8RD0T5LXxq82+wtGJRCl9rUPTZISwHx+9qd+dPHn6aaeHqaaQrxvBaLTjEXzay4G+sJHiy4DNpJ0RTif+XDrI+ZKMfww7+6pkZOsTcXZ23yfi9OTwT8TO4d+XhJSVf37rEPA24DdhpyuQ6XQNEFxFmql/NaN9ARyeiiKKSYM+7wAWl5O6C0Rcr0sjMvy9atGIB0/FgkdZ4Cl0GTHa7dHgFGWtEOHKkx1EGOScBtEsFIhzoIcOCu6g4A4K7qDgDgq+TnhzUHAHBXdQcAcFd1BwBwV3UHAHBXdQ8J1AwQ8Y1J3mC+1BRXaPacyk8n1UhXizR7g4sP1wTtQBGJ087kvl4+LbRX9XEx+CzDowxFnZlqE8MWQ/xglZNhaxz+nSBiLtQ5q5AloCKpB68Shlv0st+3dM1xZRV7g/KzhKS55k6TP2+z+/wN/PjoCuHvWRizw7+u//+j9Ht30mH2ls2lGf6X8/+wL/Qy1vP/0+ZK/hCQuiZZ6lykmHg3t3+dNRysRiInygCGMS37G6ogcWPUYfAMqjeJXwxzjTAEhvm3jlEI8O8egQj98Y4nEtWh6FFpv5IA1AwkQiJiUbGuqQXQKzjXgWXKNUf6SI8RGqKMskBoAOEwHCesg4lhitCB82ibP5sNduSqlObkdAdsmTK2r0XkHrnfMEO8ypw5w6zKnDnDrMqcOc1lBXDwFzSq6NqyBqPehqxiC3Qo9aH6PEncTktWjSPjjjiwbmtA3AcaeEnw6y6oCUh7yeDkjpgJQOSOmAlA5I6YCUWwEpzXZ7hk82mp8+gHaXxcpGM6UrvIxTaVwwHQUbwy/x37fH2s4Dn4c6vJ1QmFA+YlC8asIvf4bKEhas5LC2OtASE8Y3QSuNchSHCpBUqMV9oCT71hP2eZCC3zQUaTrIRJJwgLEOdJVhfRXA95OD3yOW0IkW1KUxqSXpIjgfOpY15Cx4ZaRv79FogIklZEGgJmGm5ZWaWUIPcWTMf1Tyy5nDFcl4/ZB/0Z5IZedcioTBe22jbn+reeDg8dAjPzUhA6OTk6aJaHrTMo0fSdcq7sjNPIbKTUa1BSQuEov2CHB/cEtFBBTjWrTu0U46b3FjPDk3p6vKQLVPmOzVBDoxBkbIvECWRlGkA2jr5QwhCar3DZdgT59r9e2c1Xw7eo3ixBcJgOLWHAoAF2Uxw+YmHq51s1teaqZCRmmRwopRqjdiGf64gOa0TuRXHEqBV2sZvqVpG+kk8FYd0fXplqDk69wmyNLi6dfxiXT0SFN9sTp+XSoEnQoF3ppZkRqQnJZ3qpB3A1j6lWHufavDsRhHFpZVEfntJycnhZRuALTl49H37c/P1rz/3Wn789PRmg7Oz9b08P2T8zVT+O50zSROL56u+cjF6HvrVz6prDANRwAejcH3E3KLi8u2WfhGGvxhVcvqzTevIlqrh6n6mFgsq7ZP1mMldnBboau1uCJpI9bLYaCFJNazgKCO7WgCK6ByLLlvMQibl7y2EhXQTafVIyi6/bSIaBZEYgyewjL4srA0bomPJPSVom6tcPhG/7EvPte/u0VyNIUJs35dIsfWG+hrELNPapCwHy0RS20Dba/3qnxraFoI/hBJ2/ojzgrGB7E/CV/g+PJUjGPPPr3bfg/cyWPuZcG1tAh0us+1I2bBJK6lI9s58NetmKIs4Cce80Aev5vgD960/6U3xMLn6Xy8DPNZEN3t0K2jLIRdIXcPlYqr38IGCiI9d6o9vHuDVkdZ4NPWAwWLYOaNO5Fu3UlH2l1oubY7vuR52kQWtqm9vFGt5e1P2Vesw9z9wJk1EW13vV5HuWnIu6vk21q218aO2qKm7MU9N1igtsKflTKetgVsr7vZfRzfTE3OXZ3Nptg6Y/ML3Eh3wacWZ7BbImAGzW0mjlpXiGf8wzqWoaMDleypYRtqqT7hOTaC0pr62iyyqtWwtG38UDkUyB5Q0zj8Iujj1gjf3ORw0BtVfIdx5ipBG52kGkL9dBqBxBztgz+JzxjyM64yoQ7MSUYLbfPqMhHT4LOVtCan43/lSZD6QcPBBBFGTMZewm/Ckpi7HbFB8OO2177KNZbZ3Lb3pln55KQauqLWUXxGnHI4DoMyqNZUgGTbNJ/UubPRTvOedQE/YCRH7AKu55D9Im5U0CiGgnImBw+NafjPDZOrETwtcQ8Yz+TxJVvwFVSdx6BGFbWaZjE0xQ/0ZawbxmDTZjIvhChWiHVK8gjjWtsDnmzLCRpG2R1cf/HJyfn3pRdPWi+kJiVhCMwPDjZfAhGknSLCsuQJaFC7OEjSYjlORVhVOe/AN9Dp1U6hT0+qMSDA3WuD6PZqhbpLn5vurp3Oj06M026geLotakkw/X709NQG1df0a1EpzGES9qXwgmngjfWmt2yFVovyJLBlDqjMDhTuSRLfQCKLREBmhwaZpjhd6zRFOcpeX1O2AoSQ8Sy3kWPlEg7+4BWCa66D2WQD3pmuIm8MEmciswvUTLxP79fEOzpfY6Ddmw0YMZ8YPCNTSYy1ib/j0prvkgmsaSe79tIk6jS/j/amrgr3uuObnPaQuQ8Uc29wG9gwyhX7pDZmFuhlIu9Vaapf8cUYU1IOlLq3xPRbVO9PVWA0FZaKqbLJ9lk1pVqMhzadxX5N66bgqhBcdy7Vtajms9rlJLafM+WlKDkYqv6JupBdNyZaLUGNdh5tU9LE0TA11l0JVWLWLztZDUdF2X5WNoRVDamm2cuKuKW5jYNoGq/3USLAxmqbX1pFInigcBm2h1mc8XDc1GuNwSO6wwB60Ivlbtqh7poWwD1vQdhJZ2x5edpg8K8hOJn9nYeQGAHiel59daDlnfHa/aoIt1bTagdAyv6+BtB75yjI1xrS9icGQAK4rxH4qE3pu0se2d8g/SPRQw09LCEPX+Azmdqrgiesow9Va8h2ZHmhyP81C65FpFVSGjZ7TVkPGExGBlVhCqIw7EOXcTSYhJAd6W8fPrx99P6xCsYKoilAsw1hRCevo1iscrvk9DlLTuWPMp8UAo0gVx5YyTDPRe5diWzILhme1GiGGfXw67I3mEqcg8KMY6Y1TFEJjzgEAefLMOb+oAR8cojLvSIu95nDchMMkCVR3x1nbIEUPcikfPtfqSYgVSUTjD2XYgeolQHcK+OqdppqtHV4mWX/X8AjzPW5Yh8+/IxZWijaCbIqQIY5actLn7EnJyfs0ehkEUSP+wy0dvboTP51Rs/mj/sM1HH26BT+iYo1e/QE/o06NHs0wgeoL7NHp+fwB+Gj2KPz7/EdxEKxR99hQ8I9sUdPCKBcYJDxnb6Dk+0YTtZwfhoQZt3uRgMGzZLRbVRK6VYy3rb1XUGrWbyf4JbaOcHojkO7H6jZ5o65bji0wsZ5Yd+VjXFpu9+ctTi1ghxThgMLbs0+uUYoW5muvhTLRHhgLsAUNCBxm3YhlOwE9yG/hJFmLclJMAcxWHtgnmMiMFTFyIsjZWWCoNUFRcslVWPZ13IHlhXYYRLkZol1k6TItt2swgpbUzaCawuCZyCZnYB4YGWyQ6GmvJW0OTgZ6csuWtd2WKbeS0XWxyxEtrc5BhwXxZHaBU8D5Fie0is8sLrXR5C98XF1ZtZTdKcDUuAqrcOR832kKcfeh7QWzrmHS9IBHboFArQSpqgewZmk5CJqr1N1G2kYQ0YYUZUeK2XQSmbllF8gOxoK+m+pMZh4FxhzNItj6j/iWZ7wkIU8muWwZTKB4eMhk+BTRmQSEmTyhHtQSIA+k+YTqRagwFvuF3IYBjyUOXfSPvMwFWjgiygDY2sCX3gx55Es9BCkOtE942yah5BclOLbyneT5t0eqKLxs10BtbZznbJfX7xjQTQTKS4kzOrtyx9TvNjkk9xuBsgMGmi9nAE2ub3d/TFuhveuk+jKGT0bstK3AIEduLcTuNe+sN2RsPeGbm1GCVZkK3pSLf+eMtV5YdykWesHna6MFR1bEQzwOaPnOuRQpkvnYcBT++fZT68+4OWXQpwOd5M5eMkwkicJJGVORfacxRHLlyDys0dvf/vwmLqlHOaBzAAuvHkM4BxIsXuDckQOJitMzyvr36Bti01if9Un2+ZNAAJpBn0Ay2GPwHAKP2QxpH++FnJuKcsjDwhUOUJ4Tf0L+/IM2RuwmU5EGFPmaM7+LhIq//gHZJvGVGxBaoaZF5Ie3e+h/GHoxYs10ZubYZN3Tyeboc6VYpiwZRSTVMqPDXuDSajxrONOXweccZaIWZBScmmvtNBwsKAHZUv7n3VX6f8aynXkgekr8eIFbpM8hik7PzmHwi9IiNJyTvDSN+v6y5DZKQ1NZxlyT/gMc/OlHOclz3efpZCJOhWQOd+6dNBWXEO6IHkjsphdCbEszRlnEU+nqHWhNwBYa5Bh18YoWwlBszGjGZNeoyONGPUNcOimRPJjACoHhj2HK3YDlGYV50eJYGEcX0m9oopctxPONy/e7ohW3vGOtIPoHxxQ/o6r0QFkvymLlDL/jhjjHqTJNqR/dQT2K7lxMMA+JtEhtqB7/MD2RXdecdxsMOZLWCO5FsvFT8jLydQMzLI0W9bhwS5dKR5XiqcIGLmrAdeV8XmoZXxcMRx7MRyQX3kh7lJqaIkbMaMmIJv1ylC8npNWF4HsSzZilYOsVFtng9I4d7Wc7p5/VgK2HEahdZ2awtS6CUyWSLaGqkjBIgg5APq6F0gy1cGNihntfrW6Rt81rNK6gLwNg+7sWYwAMwX/A2FhuGbyPWRkKVsEXhKTpDQL4wlLV1HGPz9jf1FGcTzgoPpTT6mYAQnrs78ULbiXxGlaep6SQNNnx9xfBNGx0Vr+AtU9SKqTP6QCNen0mPtI2vzHQ/YGmK5KdahiyVCbo0gyluQhuC+RoHqZ5nFQcoqTAapNojP42QUodDVzTsGrenoivX7veJkE1zwT9Ndf/vLxI6QO/vjxL3/pfWqMP9p0n+R7X2ufJmE8K20T/rDEDYBNwj9PT07P8bcD2xs5eNgaP/bS47/85fgvw3m2COX2wHPYHvqtvkd3CSW1oQjXh5fqd76UorJ08NVtlyjTahUwYjjSsyX7ZEfqzSMIlhSJYD9QvBh7l0dMPUzZb+9+BpaUABCMQUwim8YAz0IpJfKZCl4bstezCGUJ+NCR/NladbkhstUeTgqfHNAnGTY1im8I4cP4bLReH4MLY1Evtg+XrWTOo/HgU9KPyMoR51kKBX+MygvKXIkmaBCw2O/IIn8HiRNiRPRaU6SqFMvpF+gHLdSrOGfxTWS1luipStZbMwfaA3vbZhSzom2lkgTYObcbxpZxw5ArlDbrcetGj2g/DQ+g3OCuEb32YUlALqMqdAqjiF4ELGnOHp3893/9vxT02z5ABNgZA5R/dw0crhnvZR08BSEHYyzdcriyz/QVTEFj4aA/0t/sP9/8jGesz45wu4/kjU5x4eURkA14GB4xPxapLlLVrBJSBHNB9ejv3cQ3r49hbmafgyweqJZswZdLECdwocTnDFABqAfJYFy930hlaG19OpElK9eSB+gr/+3dz8R5JY8mwZ+zF+/fM/XRIfuAhpNEWZ/gg8hub4IopadqF1Efk356TJAr6YFZA+hvH978zKYJR1ZN9VwK0wxqospPKedCA8G88NDu8u1rlghY2VSqH8hmWysi2sO9y4v+k7kOWSwtbXwGVIRGiAcMlgw6kCIMOJ18nvhrBRhTdkGRRaTSBBInwTq81l/+cgyoDi+U0tkGgekVA4KxsSQ34xkqnxuiYHqvaeqFIAfmzpRLkLOGpqTP2PM++73P/keffemz2z77+FHyjYwnMwGhGxDZEQomQgFL8ZwFUyrguSx+lN/tl4hDgLw5lWwzLFBeWuNE0EclrbHtktMiMj+4HoLENwDf7h6i9U1zEJ022MJCoCs2qGFImPJfvyjFv/KLiGO4rYh91aKAljwB5QPxGxWVVe5JiPVhsjFL4UQgRUCdlfiZdAcNGYaokE4LcsC7H18Mvjs9OyEMlHEu+lI5IzoFydsBkhTGCrTokU3LeGMI0Yi52fnfPlz+gI2XSRChwsku3794/VoS+uIDL95hs59/tEluele+ELR/ID8N/C4e4E9gdxwgFcMwkD2mULCIGNaUCnbOoAm+Yosk6BYxarhZaPb7FV3gEN5JBjFDig5Sq6i7cfoGQ2uZZ9kyfXZ8bAAOjuUnhp9RdbG1gJsxMJvVtZmuOSHqJYirKSLKK/q3+KZEa6boL4blHBaLI2UQkD3U3jw3dBAtgpD0kUA8Zxpci3BFhk8FCDAEUTQAbYDoaKZpRmYLLbwUv63Lf7EH+1E1sUU13JiesInIboSIGM8zsAHAWV5FXtpvjaV5isEwF91jaTCLBXt03jWupmyKMx/0LGEzf94UHbs/N235MgoClGPE5s6/bSUN7+VVXS1rLgmKk1XichErS7e7r2NmkSxjJGwtYFY7Md6dyvhXRmg4ap6cbhAOi3KQLRJWwsHb/BsdU4vsetHrmUrsJYBH9X0xSwCbAQH3UObXRao+GC+Qi1R1kaouUvVPFmz6less2F538a6HG+/aWNahCcbcXunBsv0uotZF1LqIWhdR6yJqXUSti6jd6THeRd0dW3EWF6j7EAN1v35hHsv7LYV6OrzdWMhn93dnm7pAthG76GgXHe2io110tIuOdtHRLjraRUe76GgXHe2io110tIuOdtHRLjraRUe76OiDx8W46GgXHe2io110tIuOdtHRLjraRUe76GgXHe2io110tIuOdtHRLjraRUe76GgXHe2io3dmP6J62haVsgaucoHULpDaBVK7QOqNA6lLcW9lZGx7jfm1VeXb6shfBgWwX4HNIuKseCIfVkX59vrwX6MwPCzzmdV2UcTrkL+E4nDc2m62tk8tdEq6QEF/mqG6pWCmFMQyAYmFipxrpPdzVn9LizTKuWe0tlwTX5DjEBj2MolniUhR4zXUknciS1aDy2lmC7V5X9itbngAYNhpjEFaWbICIbdnVgvf+NVm2Wp00iNg89c6eYXY0OUM6pPx3ejkyaednsj+5iN4et8jOD3f7Qg+7eVeXthoXnFnwOkWJzwJwhXLI37NA+SsO74txUCJO+/n9nzly/MNkG003nl5grLQP2HBAgpB7D375ye4EvCDWPAghB/6+OeVWOFTGB+fpdB5ERD8WjFSgq9407ciQUkxjtJ3ejhahgfxy0S482UwVFpoEf376Vb2FfLokk6oFN++9CZ5GkS4InSyBChxyyRItSQ4TYTp/dfa4OfBVCTRgJc67E1Exnv6YepfDWZJnC8HFOrfM0OSjTYUZqwakbBILeJkJgYFPMEWTv0bgpgBEkO4X8rBUw+yhtO/jFNpIrKHSNXdqP3K135RzU3zDar/cJrxrgx7Lb6Usk4A4r/SKJI4zkCXAN0f7dbogMcIR1RRlA1Iqir9kuNPAG4LdhJd2jZkh81RC7BYAATKXhT8gXHwNvzH+19/YXR3hs2q1EvjfWjxjCWnMCtD7xj26KocK0/98Rf5r3Hg3x7rM3GstyI9/qL/fXuspcvjL4F/S0MIRYaD0Yv+2jeP10C/PqC2A9UJyB75YsEBWtR7ic8kwspyXKqZC6B1am9OeOMwZEEmw9+FT4u7FMmCRyLKwhUeQdgR2K4USYa6GHpBgETC16Thupn0N1Ny78z3LqYnk7NzPjqfTr8Xo8mZ8E7Ov396IUaT01MghfrLO/liKdtAQRz0XNXVVqs1CPyeMYbiDpaH0nT1MNBqo6HaLvbdMnWYcy/GD2S9kjDMopqaCcPofPouaZhLGuaShrmkYS5pmEsa5pKGuaRhLmmYSxrmkoa5pGEuaZhLGuaShrmkYS5pmEsa5pKGuaRhPZc0zCUNc0nDXNIwlzTMJQ1zScNc0jCXNMwlDXNJw1zSMJc0zCUNc0nDXNKwPycuxiUNc0nDXNIwlzTMJQ1zScNc0jCXNMwlDXNJw1zSMJc0zCUNc0nDXNIwlzTMJQ1zScNc0jCXNMwlDXNJw1zSMJc0DDMunVscKjqzSxQDJiSPXC6r3eSyUqlNGDEPpjYUhEOJ6wxXbAlORZmxxi28y0Zz/9loZK6Rrtlo7HF6vX0lmrktxiUPCNFbYJAyhKn0ipmNRKaeIJl1g4wmOJuZwEu5Pv/KVGTe3J5+5SewGHTLvfKOcGSi5HumGaGNn2hKPG3uz+VdcXlXzLwrLt+Ky7fi8q24fCsu34rLt+Lyrbh8Ky7fisu34vKtuHwrLt+Ky7fi8q24fCsu34rtay7fisu34vKtuHwrLt+Ky7fi8q24fCsu30rdNunyrbh8Ky7fisu34vKtuHwrLt+Ky7fi8q24fCvfGi7G5Vtx+VZcvhWXb8XlW3H5Vly+FZdvxeVbcflWXL4Vl2/F5Vtx+VZcvhWXb8XlW3H5Vly+FZdvxeVbcflWXL4Vl2/F5VtxaT8eVNoPyG9xqDk/UPyCSPCWBByL+FrYs268icECHxVjRWnJD6ZTgWBfPeZ6Fg54NS29i8otJAhRUOHInAIKZxL94yudteifIBJyMY6InA8GPoSbRDinQak3mFIZl6oczibs0uj+Rx6EZC5gIEgEZLasDoPxEKSoFZvz8ty0xzYFbEfgs0eBggxNBMsRllcYI4r+AABjvubxiNgNyFaWdU4fH2J+km65QV7Utl0ah82QzuaxbtFZ8/SWSezn5HxpSYVCLNxMHdKSk6UhhVXgbzKtymut4aCgtXVO5PJJI0l/AANHYQe9K9+MxM24QrpKUXrVG2S9nEGUxWvUrIzP6Dc1XRrFqsi9ZCEFNZ5bHq2UNtYng9HbAkPfpdTRnAbGbvzQtor1cgEctBaxoCpwWWZdCFySvEHcBRAqRQWRUjkZbPOcd066vY9sguvTCOL9fs6KvdAUCvOfAcI4iCCMeJaIFJ0GhmUX8o6tBpfTzBat/L5w/d3wAKSCaZzIr4KdsNfMEzq82kw3RyckBH61c1RYXrqcKL3P341Ovv+00/PV33gEp+e7HcGnh6DBaT3iwapwMxGJhIfhSj0IxV01OiAD96nSFdTJgPWWpVvovl30+qWLzEUaYt4xQSOhgO264m8U3tYxSSO1LuNVKQeDS8z4507MuA8lxWVRfDBocZdF0WVRdFkUWzIdbn03vtUUjC7/4eHmP9xfdkKXz87ls3P57Fw+O5fPrvMxdonnHmTiuXvM2ubSrbl0ay7dmku35tKtuXRrLt2aS7fm0q25dGsu3ZpLt+bSrbl0ay7dmku35tKtHZ4D3aVbc+nWXLo1l27NpVtz6dZcujWXbs2lW3Pp1ly6NZduzaVbc+nWXLo1l27NpVtz6dZcurWd2Y8w/k3iLbe3tpm93MFF6ZK6uaRu2x7kFQCEx8skXiyzsY5X2/4Ymt0RWL/prtyh4yZj90Zd3l8+u9uuCUjeScgV0FTyDfmlwNi9pyNx8ZQP1B3k4ildPKWLp/yThUQW2Tm3rlSv+tiyUL2LyjzgqEwCKHeLKMHmsyAS43roi17/2vbvL+5zvpokgT/WMNgmbKtYJsJDOQlQb2AoMCNGUXgS3K9D0+sxns8BT0Pge3J0YFQGl6GPlL3XknXQZLRqLPva0O5padjPAEL0IOMVD5dzLoF/fTZfLedCWalysDggnGONqbaUu6T1SrkoXhfF66J4XRSvi+K94zEOeZqNwRN6LfOpdZLv1gpsLjj4QQYHm7n3t5b1dSdbCvulJHQbv32P8c3djFf1EbswaRcm7cKkXZi0C5N2YdIuTNqFSbswaRcm7cKkXZi0C5N2YdIuTNqFSbsw6YPHxbgwaRcm7cKkXZi0C5N2YdIuTNqFSbswaRcm7cKkXZi0C5N2YdIuTNqFSbswaRcm7cKkd2Y/yniWW3BNFnCVC2B2AczbHLH7i+JVs6sV7pa3erWseS8SgopJyTqKo8EkBE8nEYI+stxH7x8TBQ+iqUjYjZgMFD0CAqL9He9O2ST3rkTGCDhHzZPTIbtkWMg5msEHzQ/gh+McxC+k+SgyLXjEZ8Jn+TKMuU9xLTIKoM0Vkpz20AakBtfrw9Q+7duCXxHAcFuNuLcyMvZTayHu5srbMh5aV5e3RGZbasUHEXFWPJE7jM5eX3y9S8HznZY4332Bc1jm87ZljmKA3uQUkuJWdrOVfWpjqPLYEo9m6t6ADF7UIV+C7xadU8nKLfymC39xctZ2pMGnEic8CcIVyyNdxR7W2dDR3sHaDy6nmS3u6H1hxLvhASCDp3Ei9wsk/taC3xt31Sx4jqiivDse3Y8H2ma8PEFW909YsIAizHrP/vkJRCn4QSx4EMIPffzzSqzwKYyPz1LovIj3VDdaIoe86VuRoCAQR+k7PRwtogF3NQHMfBkMlZJRBHd+upV9hTy6pBMqufOX3iRPgwhXhE6WABl9mQSpZvTTRJjOXS3sy1r3vNRhbyIy3tMPU/9qMEvifDmQFe/NiFOjDUWRqkYEDaEWcTITg8L73D1atlcNbqk7wPqVjn5RzU3FGxU3OKh4DYa9Fit4WZoDwU3JgkkcZyAFgtaGFkd0nUJsWs/mY7e5zACgCNAsKQUqRzTjYPf9j/e//sLomA97dC6Pldfz+Iv81zjwb4/1BhzrxUmPv+h/3x7ryNrjL9AegkuOjeASvLhxiuRBr8pr39zage5toDobQDeDopueypsFR6YKRqnty1uRgHCZIvCiFOuiYzqUWZegMJXj0Gc5StJkwvYLJwpho8RnAgTPRITziWZFQApQTNwXkSEp/+eXnjykKLVCuJcyIO4thLsr8X8QUePy0us1VXden5TARx1U0Qt9dCur3bwozWP3znzvYnoyOTvno/Pp9HsxmpwJ7+T8+6cXYjQ5PQUOob9c0I62bS5IBob2bDQwG0G6W24Ic5eK8QOnkffkB7BFFy6ru/L4IpVTd2dZJadRW7P27EU7TVLUGtNixsKZ0bANmFzu+wIdXwYoL4ylk09FX1T4ig5eHrJLdOSmLEdL/qkE4/WlRxohuwo5C84/8DWxdyIVybXAlAfgbNVX9KjPjjKeXsH/x0kwC6KjvgS+r6Axm4hZECHIEw0aR950aEVJGLb2DGJm5ekGgBQabvBfg9HpWZudvTCiVU3OdbmvvgufyEFudnl62+8hClBlk+sglzZvMxoeHjDy0oBGUo49m8zcEGyy1Wohstl2STXcQNO4k+F5E+TRXHfraGVUyfrR7iZ65NdrkSSY1cGMQ5RpF9Qn5M5sHSrSIe7AxYn8ieJEXKzHQ471kGrEWHxe8qiSR8KSg6OUkK5CCqdBmInEKkk157/okrbLkqbLRak0Rqn0K2ElFlZQC3cc1hcTcS/RhnEpdta6u+CEDedZCZQoprRRYIM9T8068KXaN8Bj4/g3Hn3lo8XoRyfG4C0R1BdVcGax38pn2LSVtZRYKvcd7i1NZBxH4ykPwjzpkOJV2hqlabPVqto9SY6pBLYI5kXPulEl2Q5kdLQlaSyD2NYtGnZTs7ti6758WCfe1bEgPGecJx2ExXIjW2rJ05On340uTtfgx6CfTx3mVwytaZJGi/UznQZhB20HWo0r2ZtsUx2dPf1+NDqv8tA+dWDzzMtnHTJ0nl5crGPNsp8uy4jzblpBelhbPKSoBY6uIhUbkIcG93dl5niJ47B1mJTrHO/xtQhhS3qkLQMfT9MAaBRsVxbHlgOBvReuGGuy0hIu8MErrmmWCL5o8PC30TRz2TR9/LRNcvZaHiXFfHApJPWHiJIgJCvpjqxo3jwOvHaiXiFyYMe2SJhWZ9kW2dMcY3CMwTGGB8EYqs9bnd9kGdmAzth3F1qvP2Do5ra83ZZOslXBLfTvOkqgsgrwbdxa4QccEgmNbX7Vy9wP4mPI3wrJsHhEz5T9CEwUzyAxEKJSF0EYBiraqgj5y3iSqYg0/Bh7hDm9FIr1cV89hdSf5ldSaTQ0I2lIcaNIRwCjQtOJ5KflNhLXgeYc6cHUpgc0v8i0CksegS/id2jxu13dKSlouF44q61XDN/ezZp1Wi50YABy8l5WDHVjm+G7UQmWhpGxLzIehB08Zp0NO5SNHcw7pmEH7B9WXI1q0DwFc9hFeqnNp0zqcPNI5PNNO74toBN0cBWH2PzQwpuVyFI6msA3KKYtk7HEYJzC3JGyh1aTDnwaksXCx4mJWUWiRu5mhcpKlkbL1SgB6dTydQrc4Gzpq3etw+gqgytpVrObNgSuYdsGqyfLo6sovokK94UDo20GEj2tr7HSAHnA8ojgoROgzAhzKZLiu5W+M9D5lzhjPzp481breWqBN7+Jo2werqQv4N95nHEIDRTCh2xQxrn2+JJ7YAI30biq5Y6huPuB3p58Zextk8puPz56U787efL0004PU019XTeC0WjHI/i0J9i4hRRfBkzW3sPTuaQgeJNAL8kOxrCzr0pGtj4RZ2f3fSJOTw7/RDik+D6Q4hVYcXqomPFdIrL1jZ2JTVHYYZBmA3rfBGCj+YtBKPqwNj/4NdXIaXyXYY51C87agaUdWPrBg6WLSUH6ETUfSjVpGaCtwk4JN2B2KJLxtp2eNpbtOTE/oc9a+wfs1vgnpZ7iBKGUla6qYdJgy0t8yLMQJ0QehuyjzBnwscceyQk8ZtBfKglICYUjYxeXSRADd5QADSyVlAoRjXkGPRohwR97zZ2BvUaGQXoSWA04tkcLqurgISQOUh89JugIvKbAI0UIcquc/+1OufnOyRwQhhdD/VAO1TbPj2rR8SSqnv+dixwLCiQ54tJRBkYGj7+iTAUdXQXLJf4S5xkW1a58nmK0Wk8vOX8JjEgLK53eQSqtgOPAJ3zlx94kD8IsiD72cNsp0F45gwlbqSyHRZU1FgZX8K4RYv/Mki7lY6/twB3WKFsIyMXo1NwB5egZk22vfSsggG0gIhDNfTNPP1kFMXrr75Ra6w+hfqbkXEP2isaYPmNfPvamceiL5GPv2cdeIgBemh5/7N324ZF2IH3sPfvysfc/Zpn4CGWbT4r/3FJL3Qk0g9V89s+PPUza9LHXNzv+dHvbtnUPe1atDvDz7829hnNpiB3rrxsC9TKxMM5yjqVGUApTqAwOiBEJ6ITWXa/J9r23zPnJuTlj0M22Ji5YvQbDbx6Rzon/PmbK3/1YJveDX4uxF6nnZKaRNAa4yiSIJFrnd3rwu0q6t5gEsxwL3lJOXSN+NN2W4hzI0NsQCyen57cU87YJ+sdQCJCl7872IjORdDfhzoV3leYLG5esF+tGJ8sYBX+rBNleEa+hAPoOipATo+4yBUSSVKqtayPPNsO3JxKqfdeKULC0M+Wy7dejOXDwB+DZgyDqm6A54gYwrb7MOQaqjvAL96TiJnGi6Z0tcG9/sXh3qy1Zbw0BFLwxf7WSD1//8vLVf/b6vZevfn714VVjxqJ6bjIlKtU34LUShXSEgxFoj1QPmQnldwML/3CtpPWx9wUmcPvsC3VzK9upVM6KlvUpmRQ8CsWMe6uC+lQXYP0MGxO17UC2rn3P5pkmpqglf3NH+wVZ65fMBSUCZhID48qYu1e5jyViZfVVEfkdB9E0Xk+rm+goJh0sGZfNJ0qv31KDv8AUaBkPG8l43YRNqyWtCebLd8yXVV4v57t3qbMe/MpaMzj9hoHNaAOJowjkWMjbqZbbLfKheLcYYXO/cR/XUDllGj1d4Lo5XO9Wf5ucQDJZZUBw6MId9Rv+jhtf90fRQ0gFhHZPTLarsl9apg2lgiklOU+yY/QPAM9ynirnqXrwnqrWtD6WQ78J11JBJOVlocIRdO3o9kKSCjL8UMAxiCkEvGKj0+/NHPCW46cV50kQwdVv1ZIxxZmMMounKr+9VoOvxGpAZQOxFoY1xgxwWeNpnIyNRGR1uCSAt9CzAz5vdJYoJBeYk3wMakf4GFsmMfBCzM5DGOaBdpRr/gVUE1Dn6JRJgAdGlIuMcXZ6kUqwWO5DRQWSRqZBsjDswkE0Eyml3nirP8iCLBXhFLHsQQRZNPIIE28n+RKQypiIHzIE0V5gMgz6yJC9nqqvFO6iFIoFUZEGZTbTRdAxNo6yiZIiDAqewE+AHwk4mqoPAiPTQyrn00ZxomMx7WoMUPd4PmAahTIuhRUoJrHLzKc1g15jYJ8z5DlDnjPkOUPeIRvygC8m0Mku4KG1kVayDY2RR48h149klZR77/NSeECo7GEwlVjgfkFVDC4icxaVUymtdVfbNGd6uzqqzZGqaxcDP4SLUVCJnY2/IdrVrMJykDbc/eX7/1BOuajLuBQapBLbnjOjNgBUostTCDkAWVem4QpSHT3zvJCBSdyCegyyXCTu1XP2WySTXUnCggFnz9lrWW3A5AELwuIcPu774r5x3ydnp/c9gouL+x7Bd/e+Bk92jL7fYheeHD7+3xn4v3ZtDJD0AIXCQxB4VpRm0CTsiugnQspw1QIOh0+Dz+/79o9Od8wF9nT3RhYXEHLzKscGscXdwJ2Eb+INxHTELAGDEVZcBnFJxXVqy1YttlO1kDWsas8tlZsgawapbi7gc5ck5ul9izij0Y7Z+xYjuHcyOzp/EGT2qYUMvAgDsBxjmUr0tAuf+TlliyMfgiO3ztl+UM52OpcH7W7PN67AgyaWQZwMqLxS3e/+AltAkMhv2KLBA0/NUobGUkrkzKNShKgLEHVu9z+p2/0uzEu6sRrU2CLEYsjebOhq39Qp88k5yx+ms5yM9+Zeb5wJlxt0Gw8fJapz7nPnPnfuc+c+d+7zhxAHsz8f6hpXp9PlnVvocFa2s1vILe5OEzY6w/7hG/adWf3BmNXXBLClq8jTYq+jYs6QfkiG9FQkBxu3VtO1io6VdjUPfB/OgyrCttssjsdfZOKcW/o6KCAbmvXppbox/yX+3mDCp4c6iA5rM7SG0ZHmvYivBeiART5IF0t3/0b9Su6lDS36t849sAf3QKcwJbq69x6lZC/U01BR5zCR2Q8DrPftAaa/IlAWb4wzhuzWGHKIWNhvY7Vt1hGL8GHYNtilLDHpMzLpswVfSbciOz85ZwGVJxI8CSFpJ8+g2IUuWAnGEygdkJH7kqeKvezYaNJV0rqbEeUr21C+gTPndNl967JSPbu7LqsE9jqPMzFU+0aQbV49YCayup75k8galMx3smAuSHHpUniQn7oMEyO90wHFnE7pdMq765QOwOMAPA7A4wA8DsDjADwthpT/iCfOjuKSiR7wIjtVdt+qLOh+34oeu4Qy7xtqsoCYqKuy7wFHYddl4dE8iaPgDxntBDODO25TXknJdSqsU2GdCrv/qCkX2PRnCGxyIU3OIuIsIs4i4iwiziJyJ4uIDYwVLfOM/R0yMRIrfAWL9bC09j6Jhi2fqMq37Xq+7M+FQD1kQ4qL0mkEmLgoHRel46J0HgQVc+bgfZuD4Wh+E/bgAwroOSbhFwaxOdIKin2hfXogezHN1D8HKUGu2At8WLdWQ4uU0au4UCYAqy0/V58FkRfmYN0CxTNIGOTbZ5JaOYu2s2g7i7a2aBeTwsS21WrwtRGuKwk7OjFrwo7MVYun01Rs9QWzy5M7V0VXNIXKwVdIwz1VSxeRP56sMrtcYzMXSk61fiT2wKiyua+bSU7edzSxZ3yxtIy1Id5qIfyAj2GONPcKlcv9ID6+DnwRsyzhET1TuxRH4eoZE5EPZJ0tgjAMUqk0IfIW9jfNeJJBPTX4Az/GHt3M41Aw2fRxXz0F24z5lVR45DgAxwB8kXmgBJo0sziQxiFUk8JPbz0tfHs3E2ud00TMgggCXtdPSxqyaHbUdJuZwZtqaNoiDOMH+9mQ/boIMiwjAnw9DFmczUUie7CyKym/AvuJe/0efpzMabgBjXcHS+2sVQiQhciqPHit9lqDmyit9ZGkkdZnWB/b9qihrDa172vCLvv+aqW1nUXyEC2SLgTRQecOfJGdrWTfthKtkD98a8k+rR9+fBNhDvWt7B8q0myg7n4ps4nsWtpACgWkkuNENiM9JuE3lOtE9mg1i2jhsSUTinSJOFuIs4U4W8iGAWqVO9jC3GMvE9kghYD2hZXJN9cQ302SEUlWmKJjKPfphAg2vAehO1x6krvU8Xt63yN4KAlSLII0ymdgDyFUk6L0NyIRzEv4TQg2A0r0tcwnYeCxFCpzwUmW5xXo/eVrFqDyCbaIIfsREExLgAAovhmk0VH1JqhL8hxlDbRbUI8i8pdxEKFMn8hwcOZBETAEEyTLLHUSvtNND2JRXXocZwn4hhbZWQL2ng9GqbjOFtBuCwjj2bY4iHiW1uP0kNf9HM8akQ9FRA6DHjaCQDjF3in2TrHfJcjhoiPIwcuTFGMU2r+g18A4iRej07tjG0JJUe4Jx9AUHqMCwV50DANT8VkfpAO6umy11mCS+d+NUIcGCcfST0F1PwQL8SbtNlYbJqIt/Koq/RTv93s6HqXwGarJlRbRMlZz0fbqwZanvNOCimS8LK++6dNO8sjDAJ71rmjl19Y99ovbVvTj3NvOve1MCE6pPdxFdkrtvpVa1NWcQltWaP8VT+4C5MfXawj+/6BfbfqrTqIAb5L26lTVw1NVnYK5UwVTCqYb65ejJoXSkHbvhsy/uAuKnjMgAgDoLe4A3P17VDVLA7VItgA3TwRPmx83JBBpTNBhu23tuTc0ntp6bSQjzlPcNVgnPw8Fse/6lxDo3DRkG55ZfnmvimCzZrdG7wNscmNSmEbNT+oYxZUw+3Ga359a83OpFpz69xAWeY/qH0rj37r2JxWRZuUvSA+2ViOm+ozTTRUwyiAEKlhJA3uBP7NI3DB6VB4SPQbZDVqY6pjTxpw29g1rY3vL0tmqcpQOx+nFxe3tphkey+48uKfBLkWYrukdnWLVUbFyydychvGgtuT+hd+GZG6YtDyImBfHISDS3LJ+BcXNjPKAKoxxwpMgXFVBwS4L3q5iU0bf3XcOutOLw48McfrxfvVjUiatGnJF8itf0l+l5M2Mn4vkzoZ2OSwEvXtWtnfrPD3+8q94Am/3tg4HrmrwUHeSw7FkLzGZe92XWtSfpHTvNRywuajmHjg9/j71eDopDv97QAaBbeosGDfTKeLfvCLu6swdgFbiFtmJy4ckLu+mypyUB+xIQuWVOcQic96cRzN0PQ102QzDAwVtQqwlVxE+K64obEdF56LBMolniUhT55NysqyTZQ/FubW+spGHt7hXY0zbVjQDw0G+xPo9ZZnbydrfvKxtORYga3s8AnF7IhgdtvAr5x36BgRCp8k4TeZBLrLTZPZs+Cf2bVNmbLVGdPNSsZFNLfv3r/gU85VHcGBWjK1n1POkroIJN6kMYdW9sSe/wl1yjMgQrYEMfauHaWGukYZQrTCeMRGBo8EaqOXcCk4Vc6pYXRV7GFFfewj70nmL7in0y1r+WaMdanVnS/qXEYTUhl2Tz3QFjOrbNhWpQKqV3i5XgHXRWC4ay2ElD39L7l8fckqnUzofvNK5o1Qc969G7lDpW+bJTIw97s1xiN0DwvBFwzeHPZjK3ltooAgvPq774rBNilW3sIWv2hPDbUvVwS5lKJnMGY/vsyuxgizxMxHB+AUUaltgra9MhCsWJ6BlwRbBF5dJECfqu1LlbFYq76ylmCK101C/hob6Dal3nTSlF3gF8GL6TLKYaR6Gqx0y4s3FaCeZ3Ydk9rXDKbrSmbuFV3zl6Ipv4HjsT6b81sXJNkmShB8l8xxoeP/uhES5IBvJh5on69UsRMP36qfyxF59Fl5OWQJSseBRBiVVaMnQ5sj4jEO3dokQVmMaRFBSIhTXHCqryNR4rtr6QYhjzs5/0JCrYEwnQQ4jXf+K1ho7NBtn80Sk8zi04o8Us0hzsODCz142XiBEtN/zwjgVYxHF+Qz+nIbiczAJxXiaBCKCs8SjVTYPotl4FgNbQggUHFR7ImdMGZ1m8WJslh0vH4U38gnjvi98oCyXr9lPPBM3fFVUQJAbkVaIL8uSYDaDut3s0vPEMktZvoQ+ThlNuM9IduizOGFyYFoBZe9EKpJr4YMumz5jR/qKHvXZUcbTK/j/OAlmQXREF55HK1R8sbI2qrdYTv7Imw6PDAqgt0efrS+9TAA9p9MNaC00bOC/BqPTMziI9vrrZuRp1X5cl5Dqu4Chn/yz2eXpbZ9cS+NE3CRB1uFktWxzv7eIfRFaKCv7R5xciSSFLcU27PVLps0MapP1E7idPIMDR6sKrvhflyK6fM1ezHnGXsSwlnhj2OXb10N2GTGxWGYrudnAocmBr26+8OFzkk7Qh+p0GoU7XIbxMokXSys0DhslPLqCP++4WnDZrJdU+7I0jTsZnpsFCKq16NW6W0eLEYSl0uENo53EcQq11Fsu5zQQIakS2LhqO5qshuzXa5EkgS93oIAoiGsRMvUJuTND9jJIZLl6OVfs/Iin3hFeeMlvjwEmCmny5Qj67Eh8BvACtYLa7cfqWlOLIfuRxrrI04zhWrMjnWj/CI8ffDOIQFwpUyfqwjgh63JRqknUV+4HXCbdYMiO4PkR+yubBzMoen/Nw1ykDI6U+umRGM6GYGoTCdMjTh8P5bL8lYUgk1jeHBar8le5QVTql2Vwb+b8mirb0fTYURRn47YXQu5dmS/oGOD//q//b+f7ZZObJI/iqSdFBySl0A/UGtCjRwaE3aw7uihnFMcXzutvqSgdDCoG6OULrLALlxNUoT7Rq1XDUWG/0LyROVTmztJ8uYyTDC2g0zhPiuOQskc89foYU91nNJk+Kyb2+LltqbCuoe6VWh4XL7VLoGatiRbxs6rq0upakhAUXf+zdBHUdsltMb4LAtWCf6Zk5c/OlHXhM4x/yaO0jMG2IBxMgMNZhRROgzATiVWSsrNVVUAkh++OSedsk5cW/DOIqckUD92VWN3EiU+C03ghzRUVG2EcZUkcpuxmHnhzfbZSNhFevECosw/Oa4m++uHN6QUDXQJsM+yIR/4R0FcU0FKzcRYbfcES8kAb2kl5y0QC1VyP4uSIBZEX5kCV4RDr822+lrFQcIB7RALfxLMM1CXV9B30icSH1llMA5WaH3gH/jEXEYsXQYZOgCkPw5RNkILENlagGZOSfof1xezDixFRmMg/aqURKJfGSe+TnbVWqAKdGZYGiyDkYKrBJReMEwEkrpEIDta8GADpCWJihL/xPLHfYizFlE6G58aENM9v5vL88zjKF2O5GZZJ0ZtS1AXYjto3Kl2aJ9HGo698tBj96MQYfHFJ7fmmR6YgUgXV1LbyWngZlnWRBwLMpqtJElB1F5rIOI7GUx6EeSIs0pVBLPB+k2lGGgEtK0fS5cAQPGVbhpx/yH6ME7bIwyxYxD6n6xWItM9SkeGqQeQGiJ2JevEoZb9LNfF39NBH1BXsCgzWZ0ueZOkz9vs/v8Dfz46AAh71kd4/O/rv//o/R7d9Jh8FC0AT5Ul4BM41+e9nX+B/qOXtp9+H7DU8ocq3qSoMjYN7d/nTUcrEYiJ8uLtjErSBfAgPLISMPgA0QnEV4Y9xpkEWlEwa9Ww4jUS1DlwqlOYWRWZtnh1YINvpKXEvNeDmQ4bd1Cy6ErFFD9dn3NGbsV64LjeyJg08efrd6OL0pJ0RQz+fOsyvGFrTJI0W62cKNajWTxJajZV+3zLV0dnT70ej86rMQaWuxraAKfmMrEvty3hxsU6Ukf10WUacd9MK0kNLWiQcgBRwRpXLA2sre4dqWZ+qRbNqaikSvThsHWa6SqnCpA9UG7ak11exYDxNA6DpGUL0YsuBwN4LJ49NyjPmo4wGNkU/DUAWRCImZRAa6pBdhogayIJrlL+PFDE+QmVimcTXgS+YCDLQgMi6kxitUCpmkzhDiFPZUFrTercIRCwrsvcQgUh6V3fXWMMlwUKjaz921VgqrzDPbSQ+2yrgKVtU5bDBtykNmR/wMQRWWrJP9S5zP4iP4UzELEt4RM+UdgoK0DOozN4HnrUIwjBIpZcTy8PjjkKII7LbObBzP+Ds0c08DmGvsenjvnqK3Nv4SipNEvgmiJJgIkCx0Iuv0cr4Egc7kUaOchvpX0VlkRQbphUbOsbwDv4Els7focXvdmGqJP7heuGstl4xfHs3a9ZpudA8CoH+97JiKHnbzGqNIrZUu8Yy2VYHhtdVbQSFET9cUhtBu7L6t1WD5imYw9YWyZb2TVMmYbt5JPL5ph3f6mjlMR1cxWg3P7Twpjp11KU8msB+h+xX0mUItxaGLEYOQj20Kozw6V6/hx8nWcAqWTYKCdYgACkZ0HI1CpLa7n4VRK3HBt+XohostlZBCGBP3iPNjdvHZ3yxr9jNHuO5DcMbsH6WR1dRfBMVtlWHKbkzzP6XOGM/OgjXzhIRv4mjbB6upOj67zzOOBOfPSF84T/XXiweMI8vuQdWIxPqpVq6tLm7TJv75Ol9p80d7XgE+0ibC5jEUwt/DdhMulfhdOLPpYOcL9MsEXzBxFcPm9r6RJyd3feJOD05/BPhYIj7gCGaLQ4PgdhomfkAOlUWKzPHlK76Mk6lSl/YyXeHYMx4tlk6A3qjmiBZLxw8DtIs8NJ6VIvKk8xystpHfpG4oHjPJZlzQMVvHai4XbUhvHr3YfUkKJdoCNH3xSzhvrAQ1g9JLtgN+iJhIm9fq9xhcsUYpatkRMkkpAZtfWLGvRVNWMr5Sm7H5y9H+EyAe3yQBn8IFgaLIHs8ZB8gI4xcX/Sg6t6DiEgx3D7jWhlYLxHNgshi/3iFvw90OndlgB2yt4lIwUOPWA+gWwsecYgyenR99ljf/NQGNqxshUUsfHfKJrl3JTKWZnECFJPoZhCxySrr0qsa6PvgD/EDvGLfQHr7RVvOglUYc7+1m4q4U3ulbxlN+dOftCEr+MOyC39Xj4hp6F1gj/xgIdAMmfYZdUB7/nj9ChWv2mdO3aWNa1OZdal53+z9E3JtFP3sX0KnGrp/xzWpvJt5H5dlLO15W/aByQ0h09S1FO+qdBJIIEcyCdUOwaOAJyjPMEWkfWr/zkXe9Exmb7I/TK+C5dL+Zrssfqd84s5e45SZQ1JmpMB9kLpMN10ED0EXNQNTpMnWtQRp+ndbejRgkaUUtV4ifBFlAQ8l6xdMDg7x6nGO7qs4RZzcXAQJeMgSke0z1H1r+deWZqqSMQAkA4kpezQayBCvx22myZZXai47Pe5RJTOWdiydnGyaJ6ty3mp4uKVIGLzXNof2t5qnAQAeezKulonou9oyjR/Jj0Jnld3M45S0EQXilEExMgbiEQijEBIIYgKgLlo3bBd9tyqTRKwrQJ0nHfOR/SyzkNHw7jPz2HQMnKV7RmdrqrI2iceSv0z1MbFKTVXwUO315hiUCkrSPgP7XPXI8xxJljWbNWpaXb5bG/Mi9oNpcMd1051suXBNWLP6XG2OYHy7b5yY0mEoT3H3WeEKqa6S9s14UM8JVzy0p4RrQPTUM8GpHHHdM8JpqRAWtEUodPnhrJ+oQeAOJT/czgX3DySqfeNS+1BLpM2ptYIUkZnr8gMQ1bGJvi/wCeNMMedK3Ip6LAXgF3ohDQm42aSOqHc8EgxMZWhPIQvC4YjBewvtbhUUiiHy0eTUO/PPxcX0SbHXsquVPhXLgLaPjOaqcyuIs9T7xIOI4n4Pg1oL3rb+Q2ShVtLdxhy9hXlahMIqIbFxzmLG9jIjI4uFGDpnkufeh2nbyYpOVtyDrLhLMapNcCrSWWmKHkTXIEcRv3hYItQ3aMJ0ktD6ktYlIlwRbwpxBtyH+Bll0Cxz2A7vYSw+vlpQsvJr/5gLGdpSEp90qgrpl4QuIbEIkS1tXa3397d8waMBECLMB4zGGlWOu+j/DigPWnfEctDXwU/bJmhSC5ug+RKfNAqa9DgtJE2bqRWsbwseiSgLV0P2omyCBSPyZEX1BSWtKkpJ0bj8w5E6W5KSdv9ilasWI3hyyqcn/uRs4J2PTgbnJ5PTwVMhzgYn4unZ9Invj3xx0muBaBSiZifjHMlZxiLvXc6yuxmRFn8t5uisCoeYdZ6OostreodVtYDiaVULKlvCnrj1dRLg/UuAUjjp6sl+T2KGIVwkAhKbkPi3cckwQzKRfFDGFFc/g+LcGj/1VGTe3CZEARa2SYLS8Nd2EarmnQbDHPmmnXS0X+kI40mdFcpZoZwVygnaTtB2gqATBPchCIJwtSMpEK5t3iqqUfF6m6z2Gz5pEdeWIcAf26U1CmK6JtInVNUcE3wI9j6tjVHKTtDRAifNbSnNOVfww3cFr4l5oku7ex+WE8idQP5nEMidW9hJ2Ie/qk7C3peETfzzQJztm4v1h+egX+OOP+Z5No+T1KgIZbUg31BOlyJqf0AvlvSSS/yJNRSDop9FWivXkaJznd7F/854FPxB9hgVD/8V1I2T0zMxOrmYngtPTL/n/lOPn43492ffnfon3tnFWW/r8vZyjb8qla3TQDM/dVdLUb9DDMsm1LYD8l5OzRhvm7zwA/fZO1Ks7pGJdeZVrUyqScZfx7/UCSaIQjX5rlrXvXKy4koTDysUSeQE5SbsH1gMqG/+9E5wfxfs76vyPSpKHIargS7C2coGh5IQrMfdt5JsKCqT5ZFojks1qDUGphZv1GJTfzQe2cJTsaoIJJHI8kiWwk4V7BnothGe2pdVIFRWnDxFI9MCvIfe14pO3TkVl/PHNboPhX4H+nlpZhb/wfYadENpqMbGd9eZ76bz0ngL3Xc7ffdOGq7jWAfGsTQJdKyrhXWZLGTLoDGDK8moMdWpPW4sEjfF3tjDx1LZrMKhKGysXhcwR1gK1diChNBUmggzIh0Wd9qHp2AdF9iIlncnw+DnmoSB125mRUrQgYqXCPhWFnolu6iz53j6A+LprYepmwjQyPN131o8oJXYoyygqBsdSrB3QNGpneLct7EUdJ+tVtbVKwfDoh1DFkXsUkd98viL+ud4TViOwcplXI6VlevInEY2rltocswuIwCBD6ZhMJtnRUnmRExFIiJPpj1iYZxwdhOAesaDkPFpJq2rkI8uZWDT/bqhOR14ewFXMBZ6B5+eeOcXIy6mg+l3p2eD88npkwF/AmCFkxGf+qfiO/4976r4apokV4/Jqz3Nw3B1D8yyCyNr5CHNjs9dUXWLc02v4P3413Zjj/2aKtefnkxLMrsVmda/D3iaCsqJvVb/ypeQ43RQfrWCMYMWBulml7JN+bBTu7SsTTEaSl0Nq+hpjjKblLmk9DWQFFxYZHGM9rBCWrCED9T+PMaUz6raWlfqouow1tK3UTJF/cVGcjwJIjg/Ki2s3XcJGRpVySWcyiPu82UmkrGs2w5EEStiy59REB+mfCoyEaVxkloywlVJWfH9vi6zuJm2aDI+FkwLMzC7EYla/50K65sT6m9auzhcA+Cfh20NJVfZk5JR5V7wVN7b2y7uLT++idaxspeyzXpmVrjul4kYpMEsEj57d8p+e/cz8jL1NSxorumBQZQdQ5MMzfx8QYfv+vFGftBVuXlbbKvaS9jce1BrSuyxZr3Dp9aazuvY3FhVcN63cgPsGc+903JKfKVCYhynMPUceec684rC2tsJ50DN2+AOb7HFWtQDdRSumF4ErboIX6HWMCLG4xFkgclT4WMAtKHtHCIzwGojaxNyBxHJiz9D6zWZuGtty0jeUrZqcyTxdEosuNtQfsXmHcdSNG4cTHksiS+SH1btg/kVGrEfVuxFHOaLiP0ioYlN42lqX6XnG8NR6HB+HVTKOvS282TdnyerAmbR3qvNEkE7mIuDuTiYS12a0dfpLlBNkhSOi+O9ToyZiWyALw3kO7UcLZGGsxxBcjrIXwAoyzjP4J/0Vl2sUSlcCANRe+0/3v/6C3uP7zJfTIMIM6CZFQ1J5WK/pQJ6SEWpWRZDDhI4FBE+ZnIKqu6YtG1ScW5ChepSZyrSYWNZqTGUQ1VLef2SxDJd/0XjgJKCMHUti7ht/zuS2xStb5FP9NcDDP6YBiIxEbmQjEdX0iFgLrZeX3Fwp59pXo//25seQ2m04zDkCz44G44G30+gDEiW5EiIOwlKb/Br79Xl+drOykgG9bc3s6cYbGMhXWQlczHtF1pHCJXph3HxbtUOtXVeYo0FR8MXymNsyKb4iSqvPay1kqRSCoJfa6Gqgh8eML16Xwen7OS3A5DfvmmxzSKKrcnDUpaSuklhm4Y4KqZbSGCSu2wT4IgRmuBDKN45RANRU82z2oeK2mRFWbWTk3W13zp1Y3aS8fSqU+GyyYp94OnVWrNMQ/Pm5cPi5j+hIiFJdVGDsLR0OiK202ApWLbbSIu21WE2DIUqoXQdyntszV773UZTal42sJljmAe+GIvPS5FAMdmMrxFfdY04Bi8y80V5izpVmGt9ew3+fNOSeXTh24ZVtOi4cSRIi7EvlonwsDJt6xBeTxkSAimBC0VwQHjJl7Ae2TwR8HOUzdMCJRkAIaJPgKwDRq0he0ljQn0OF6Rtavv/8ga7JYWydUuViqzPEjSlquHKCptSYwPjPk+uREYZtKhbTEUiuK8gK3IYWoVds0r7+2iNZklGHi9FlMR5JhKQRbYMWpe3Rm0NS+d8KVigcs/yyOeJz0R0LcJ4KZ5TtfTfafC/Q7s0B0FR1j03JliYBXSXtDrCV5PeyGLIo9WvU2Sef+YY+Zrc269pxsYWyDOmDxN7LwSbZ9kyfXZ8XByfIQ+O/dhLj2d54Iv0GOSuNONJJnzAl0Far+vAF5TaoBJtJJFnXVekMml8vT6pNs/0r9jGuaP/lArEXe2+RO3uaO1NcjxVa9G30GCQ5NEAh4lG5kLFeJdHpsmVnMrKgBrjYbeYd3Og3VE10pGTYXcS+ytVahd+xiZ9Mv70yQy8JNOD+oC01A7Zb1EYXFltuoCJEpG/jAOI/Ef7p/qTZfxKWpqrpkLF+nBI8OUIgztqNqmU5ZGPzZd5NvwYfYzA8ixHNxSfs4T/TXAgPSAyLHmassKAwhRdYnNqM2SXnieWWV01M4ZGdunL1+wnnokbvip6qbXEAQHJhHH/s9anxzMexrNPjxRF9QVxySQ174cXL46LU6G01McoQdXHiavSZ9IopcZ2lDI/9nKUdLXVSkoZVB4RGXAS57O5Mbedap4HYCjfW9CsNuiWJ4nXil4xLxaKRiIUXqZQItrGSheqD6DiOeMpbOBimcF2Kh4+ZC9j5F4lgRozIslLGUQpKDdUyx4/biycnoBeOBSIFssMddgwZAuIs/pXfEVQTe0cr2SGm4tie7KYic/CyzPBHonhbNhnYKSfxfEsFMczsVjwwfng9MlkwM8ngyDrQ9WCiAfHs2U2uBheAG2Bs7cMvGMv5LkvBvEyTwfnw+8et+54uRuw0ynCt55VG6TB4rwoaMS8Qj5QYcG5q7tlWds1xmhDJpzRRVs/YEy8+yGzbMULeMI+fPgZiGYqvDjyUwukRS/b2ZOTk4asZQZVe/0S7yF8FllE5LMwns1oC5q3ZLEaqCmBZHIVLHF4FpX3KlhSNmEWxvFVviyufaLNyTWJ6LYmARYeLzJ0dwTvv5F0hdo9mIxbVmu1ZWYF/yUPwJD9SKL8NU8CgYZGeXVXS1GnDl8/OZeSXAYMJcdoxtQnlDcYs0xTik/l3fiT5qJ0isHBKQZtGgGI+2sVguMveB+LiIbu2kHd/YC6QU02tGsDwMxqUqSkHmhpwRYgxYOABxaAyLfJ4X6QCA9qD5WNVijB93XNH06vHeNLx0pguUn4cikSFJeVBF5RI0iSShgFjkl5n33AD5UQImA1FBHQi8jQLLgcdGFKk3SxJKHvTCwHm1acZAUGWH4/SJSYh2PdJtnZnw/OYosKqSRNbdbW9gFt2dHn7gpx2Y0e02QWzcRni3ABFw6eEKh9FefshoMiHzMv5GkaTFeWiS2C6GcRzaD4zKiGcYDPALsJssKL9oL6kpOwSCfVwYLdEZKAWw5wHGVJHKZsHt8wL4xTEVIyQqLwcEWDBZ8Jls7jPPQZ9+cQtCmlfFKMnrN5MIOkvJjyN2ULLk0d9OYihtsRUrgQmmGKV9ug5d8NL277vbmA/BX2laZnyrRfHXEQsWXwmcxRNS/pgn8OFsBVT0/Ov8ctkH9ePAHZfyHFlIp3DHwyqaBJBIvZabCYMfCsgmUkYigWwWjkZ2RoQwJumlTAMdBrgtHdXgwnlgcRFjpg3w8mQcbySAZWyU7kohZzqAlfFRWFXmATkd0IEbETvFmnFxc2JyNNdDx5YotQapssm/BUPDkfiAhENZ/RWVY7QTScFrEG1Ie1T68sA1cLqNcLeuyyrNCfua5UcGXJA+riAJY5EjMOhTnGypJQO81wremnCYxZhAJsUahO8+s40IJG5ZDbljfKF+M0E0vLqOHS0LBgPf1gOs1B2GTYvHqNISQnWIAWL9i/cw6SH5vkZJVkYRzNTNXegj84PSlds9t+r2n2l0QzjR/1ScJdNemoWoB1dBSke2FR4d/xyI8XDB7iQYFjFPu5F5BsW/7wzIQrVGYKX8gS+b1ux2PEgshHqh3NkOCmWRJHM6C4MQO2RKQ3S3iUkgSErt0c71bpCj5nYXxjobgSXIeEPFFU2nod6/QW1uwm8G3TgXODj3ZOayvsTp6QKsP7ELPX5eE3srqQRzP7BNKlEN6cQYMcxixNcUciOsKT8CqahUE677OjaUK//AiJkuaPy351bB9M0cSo9YBWZAKUzNnm8EPwSrzV4e+8qu9xTTosqxJ3CnGoSfCJmVhMcEXMIdXpVN3KkXl0vqAbebCN3hoI8eYfhvP4mjobnZxUCP5tDSpqlcBewZdAik2ta6faXuZZDLfYkwvN3gkvnhEw1mIWrSB2Yftb+OQaQYNOz6EIGoSkGjffTn0t5eGnchDCp3nY+FzGk5nIunQJdBBoaggJUTWF1dctiLJ4yF7kSULVgeMoXClqoBAYqK2uz5ZCg/1kngEkXOtE9pq/xC6AHryQyR7prr+fBNljy1moIrEX0sL3GSARQRSKNB2AFZZH2S8SzIVCqldeQXOJJWThpciE55a3ZSVpOca+XihzFesAza668BSV7chbjcHhFGaWzEsvoX4111VagisRBvM41rgsZSFZCpKO0AUIUN8Q7JbsWiQTngULWyxyIV4YssXgFIrIxInFPGGmTfo5fnfJHv0c3wze8eiKXUJiDJz948J1pyPWyePOUzlaCzXAwYxleR4rTZKDNaRwam1y98JEWMOo2cRs1FjpeHqieQdeR112IABzAIjD0QwzQmfgdUw3W/ZGJUfLosiwpeu2FB9SWgbeitKrSPsJv2kBV3LmwTXOxGKJTCBIUX7jEloH1wvkrEWeZhUTh7awKnsuYGLRMU0SOpzWLihLoHpLkSHrb96kt/RAaSaiKIJYU8/8IPXiPAFKVPTceaNODC/gWAVlr3MEgbVs3GQqa4vkkf4LfF/3bfaGUpciRGjLBjdd765aXKG/We+QXpmn+j/GEo2khscXLQfLvKeURnUCsE54Cwp7cO8KLJ6JIAx1uJKIovfvX/XZe5FcC6jzFGXs1TWo+90OEpximFaetBn0cGS4TOD4UStCCmL1LNHiSVMdvcTIWWm9+kX2h+ETYxUvKucri5dji6EHM1ykCiUAptF5HIN/IoFs8iCdxUt2dHXEFnGKVGKCiUNu4gSQVD/X9F7tzKbhT2MP7O/VKSrCJieJft6MsFPLOJNlxNKcnGJp+3G5OKkcE5jp0gaT+FeuYFmUPO7aOJyXr49SY/ATwpYlcRgq88CCRyu2jNM00AvAAkTKpAQXtawGbbBci2Ui/MDDBAjV9eBhGN9ImJNaDyKEcqTGwrZSlZG568OTkw7a59uK7bdR6zxUwWKaR14VSLOZU9ww13XKuKsqrUAvVnf4fQkeJjijWZqWrSTcKi3bePF6xNG1SFKyeM0DqLi9GrYIzNXFLbw7LQYK2UwfDTkonmKN76TMyRsNFZdqUijFqD4hWShelIYhNviLjC6sOq7kqJW3VkstwarvP4IP1OFgt7f1W1azePR7SWxLWIru4zgU1QVLBYJKlQEtT0Vy1GdHoJ9BREMGf6SrNBML+FcWx+FRh0yjOIYCtGI95Yck5jqJ00mcTuI8MIkzDq32FBWNhQ3MbHRS+dSkC/MzlzjfGqhhs1WkkjihOqRJEohp1ex/gzQDZeA4ZH5ckr3qMoPFu2cYN6CPIXsTYwkH2fBaWjFEBnFJtr5NvE0NlGpmd5Ccu2iPSPmlUdAQB9CrmNNXmLTBWKpP1Uvfsoy9l0a6nHjKBPfmxQhsMO4mqPFGe2VxzmiibPv6WgY+l+bDzODkbR2tz3zRkLGhABHW8zPChzWKVH+dMDkdLkBNwrC6ZmwTVLB79ihPc6RRR/RDk5jQNjMtG5fzgBjH2BrUV1E0pEBvO3AZD0JNzVRDfbbb+dedaID+1h3pgOpn39fd/I678u7K3+eVbxzhe+myJ3FFjxXYrdJn1DnuorTIbdH0o7Ynbe4Y/RZ5nZ29zNnLihxMqWkxe6N+2+R4gUVgbECYbj/VGV93vzyYntRW0FtkAGmA0ewINdPdyY/jq3v6YYjg4C/GmdI43y95BOO0kvA14N4YdC79Ids81mJ6y1Mz8SWy227IXvSnjTcDI5vONgqKCP7ogKcDC2PYgHczLYzUpo4Uk/EXaGQkQ2WbdXF0cnpuzdo2rgJy3sspNC9ZGYrxIWYf5A60ym73aXxuxiDvH6Nwd7xP1cJ4H9bpi9HpPdgLv5L321kfG62PezHgGQf7fi1h34yUWJ6PRRYsrWUXYZCj8Hj4omADAM7CpyRGt4FZHSIYC9jWLIoTMRaxhdL/Yy6yOeHSqRn2/OrX93TlaQljcArmxUWE7xMvKGrTFq8EaSFhWMhSMx99rXDrFMnCVCRLkUf7ALBd3zQTq0O4HMNwDMMxjHUMQ0dOauj0IcNoHEvYB0v4E6NuSoAbgr30SduFmn19JjJv+LgFiKObNh0AyOWgjNWYjRONxEHKjvSrJctwg/mg9QuvKawW1XM0TOE/n+EHjv+1FLPndAb7x0//dTwcDjtYolXBwvVAo+q04A2rrXsT/BFsh5wKddhvWq82S7qFmDm00iaCm5OhnAzlZKi1MtSi8Kc0SFHrA9LQvZLFZI+2+VZ2JGbU9CRF4Zu4dGv4qwl7ewNV7hexz8PWgNZ7TxrXXDaoSe4wpaBy4KC65lppLdTZZpkh5JOmJI+V3rElwslm0tyuvVCKAb399f3rD6///uoI8jUd/fLqp0v8y+qISr24geZNIamOJxi2MPMKVBhJphFlMIaJgMQNacXYK3wat/Xa1Plxl1Q0yvJvWzJL8oC3v/zEdPJ5XSOSkln11iYDMITGjgHuzeazhqjr8rgptjqI2Ju3Z3Lc/UpKlE5I7I2/Yl+d8ncslEhlES9/rbjzRdC1Sv9lBOF3Dlv9MYzpCFL2YqG6L/QOuiOYr16jhopmOlVlBXXS5FaC+wFdtdHC6nmunt81gfydcz6ZAeW2i3ydWcqhQsKNOPHHmDjMOmHkoW3zq2RqjCwyGIxPRLjClP2UagzA2kP3zIshrVYm6klREY7Mk4Y5y84wxxl2NBGzIDKqMkAAfykfanlebbiixoT2VefvRhkWYEc3p/BSKBE+ZL4TszhZAeFGul9hIkTOgA74kF6PRzxcpUG6AWG/BGFJkXa8fv1qDpl+NYmMJxKQU0x9IWV8AukEs9Lwt6Dx7ckLmoi8yX0p1hwWRBohQPGVoy0npmnYmUn82cYA8WzxDHQUE544gZIF8Mck/sx4An/h75VhrNXePy+45bNwHD4PPP1xRTcncZbFi0GC6ci8OImkracyINtN+LwILPjDpg9l8XIQiummH1k1zma129msGmdj+9BWs4Hzuk4ek2JYnJRwsI1nYC/ylk6yANfRi5Ok9Mkul685rUVx8e6evEGL62tkHpQIimSiSsNVTLtuOorjcOzx0BqQYRAIhF5iOyV+gGboC5X3qhTvYkvItYYn8mSGef0bLLT6MaYvJ5F9Iow/dDQGjLGee7vYtu5BGfIb0GE3QfG238tTqzL5G5m4QLJKs8AzOdJUJHhim4Zcy6BOcgCYjhpN2jEUAqsZs4NIqvGtkTvarbhF9yqjdWvvGbzeufNa8eYqKM32kZo8om+P1Q2zjaxewArbYH26kUI40uFCSKHGRNqP1lY4Q5082SoJKhChD46g1MzfZyrXzWNZD+Frxe43d9yO+Lt7x20QjWY1rIlwfSXFZxOzj6tr6+raHkD2+dwPgJfhnFP/ika8ZbJ5mRC+PeU8ZtncvNStLLNapJrH4qhbFbqFrshHJw2HQEUHhQDULywn6ePDKYG7ZZlEXO8HU2Zkb0UL8Q7nfoAuEHkL7lROxBX4c5R0lwX+1D29S30/sNglV358s0GZvywe6JdM+voCESwZy5dhzNGLFoSUN/ZN0bymzMMrqWyq3+QpW4BkhEgGkNwJnoHBQ6ozmUyh2PYhK2iZRNMUTiZUxjBeFT41ZFB7D90uKqGoLCBqlvwDH7LwrorgWngV+cA21TAOuo5Fa5UGvRVQIXUxUKJzV0qEe2txUajTQXuV9YvyuuXth0Wnk9EaF7tWwavSMBpXZ4/qi+qRKhT88onfo7N1jQxeUWr0UagzssJ31a31IliID6ulNcGLrb09k5a9bWElWN/aHnusR9cvymZrE0JD3d271Q1bVyPMqWNOHfsqQsSGOpfJu7tKBseaR3bRvqCgtvGVQfGyKStgAoSi9JTm6Qbflvy4JjPAq4SKQs4gPmciwp1BA+Kb129eEYsu5cQo9vUotX5NcX0lGQQp6UNaCLiR6GhOn4WKHBOF2sWPiCl4I4gVUE2lb1JIWMcm39OlnuZfBX20zgmvDsd++FyFsBVfMzpynMdxHsd5SBm1cAWldq3hRjdiUhgA16qpwIaosu/gRkykQbDEf8jeR8AbMbGUE7dVoGQcG6fqXXqHE05klkMenz3VI9+fbncXyjBZxVeXYcBt5rh+LwRAtvHEkoxmVE1G07kmduda1IEF29SeEiTwe7XCM+pzn8hxSrW0bf3yz7rfk9PzGlz437kgx107LrgpbxYStfLIqMdi5Tqrs/8oTrJUZ3fHMqomxnVqa6unr9+b8uvAi6PfKIqnuuZa78+TQEeUdWwb8jR7E/uIu30JxZza3vF5JgZZsBAGMMQy2rzLpy0BQ6pPe0ppkfGKdt+w9uCJjrzVG7vzUh/A2rAliXjdgAW0nbnilb7x2drloV035tAmwryWdbNVTd44YfLyaTKrPNOdD2sT3OYwi2nftcR69XhEeRiWZNxW+YnkCiQ0tY2sSU19M3hDyafrfe/49vqTrCCeVgYo5Z+Z5tZeInyKt+kZNLqPbCeJOAXkNWZ+l/28a7kEMMMsWdFS1uV2xOdmubmsujxh9RSoifXVgZCvmp+wjAlmEF9tvm/xldoyy+7oy3jWyiNk1hoRweD8HWsX7izcy1mgnb84OW3debV+bMqDEML+3N5/I3u/I33XUJoOXmm9o8+1TcEtVNQ2VTaEcx3Njq/PjvUnx/hr2mhdjeJMI/4H2HaAFk60tRp/lzTcn0TGLuEZ+yCflW/4TyIzQR8AqMWupPEUrIg388CbMx5pE2OQMhEGMwgp3al6+z8SMe096/1fx4B7jSOAAB/T0/SYcz6WXQ4Cv6sVsjL7rUyRa0eFuzbQhRS8OAxVLT/iqf/5n91Htg15XTvCZaCHN/DixSKOBvIzg7PeDknAL8YJLZ26JgPY/yOSmH1I8jR7xt6+liavfqmfVJvGyr/KppfyTL4XmAevaF17UJjTdkAC5P0d6sYDeXnvgsMwiIIvIIabpnqsLls3yrAQ3hzyqC4G9B7OEGmEL8LgWiQre5Ma2VDNmW7Oys3rJ7pMSCwdfDNUpX1x9kJo5L+3oTQdR/vtEJ83ep6vjCO769tv3tKhvqUtJABu7zYUYMlnIvFzlToEYkPXUAHz9QEE+A2wjwF0MqAezF9SkVwHXkV2eInN2Fto9jLPVlisRraq5qrCcFW89WBMr78CZpuIYr1kBI+S9Q77rjeuwX5kCctlOW273OuH9+3cafNIU7ImPe1GAcMuSTQIDXslD8UVbqEP8mpjiziZiYE86gM0eoLlWIX4BCnTt5/5xvUrjkK6/uqBqrtWoGglJejPW0dIEOZRH1gHEcLwqdXfP3DS0TDrvRCO4ufBlmLCutH+uenI/Sgqd7N+SDchmj9UBvB7pm93ln+OJS3rNfr/u5Mu2ZXxUxnHDkmsTNaK9jtJcekM1nDs+ArYUygnHOS+BF1HvxnNKgfukEjYqE4UPugpWJdhp9oNYKYgadg48MeaRLYQLLk/3Fhn+17tx2CddpmU8osBNSu79DZ70/DVNSRrhVxwb19TRPwNT1mq8Xe2ygAaOKIoCFpk8Q9pM25zJdqgFevmk+d46jbzJbY93aXp+s8mZmJ+PrEbSnz8BdcC3upmn9qQJg8UqS1FGEEjY1/q4ODoKjXIAW6jIfnKoCGKh69Q9fsjyX39JbWkO/uOMUu5oB2FWE1lS3dkGYeBtx8r16bU//9n712UG8eRdOFXQWhno7onRFmS7br1vxvrrkuPZ+s2tqt7Z9q1MkRCErooQk2QdrkqKuI8xHnC8yR/ZALgTSRFybItWYjdmXGJAAgCyC8Tea2bl4V+C/0W+gtGiODzSsB/xYYTIT43NE+a1ko/kPSdUwpkniy0S2Z0AbpbbsM2SZSu0gaYz70V5DSDr0sZMDdZC6drgtM5R76mWzsfvbqBKJpM9qEqU9bpS1KK5BlUXGBNbjfRgiRgrOR+h5pfyvQdlKQP67QbJRB8zwici20oDrwmwDIBzSvoY7GrordQ8c/FKhFsmTqTL5S0Qr+qLrOqRVEWFFCi9ikehY0Q9ItzsdzICvdrZUvLS/IPjKXcQC1kht/7pv8y+qBGzgoJg9KOCeUMStu6qxlU0qD+plDNptK5r41N6SGLCp6NuJIUF3SjXBrWA/ibaYG0ULQIim7oCKEDeucpv5HDQwJH6FhdikXKU6EKiJTLXUS5r3wdKQF1s8/SK/VGSM3tOwO+xm6Vt4tFRhRXu9FI/CyflJU9byp7LqHx2H7J0io81sASxuoqDFnHG8J3PPOq1R0f8WENiBcb7KQIaXUqK+lUSrjb3HG6R51K5VwsX7M6FXuRWSfXUjyoqU5FF3xuZmPVjZWJ1fScs7D+LXlQa2DV/XWNMHVtCXKbB9XiwIE8DdnqkLOkqpgkkITO43Lm02udfg7SqpCLLxeZEh8evZZpOS6gxK8iYGTm04D8AFtI/oPsd9sQba7/GvKv+i94/3+QZ931plZf8cY0Y+FgpqtkwXtMMpTmAycjZIdV6QNXH1T3z820dpaFOsRQQiPdrRkdY3Uor7oSb6YWSy+XxSkzA8kDt/EUsICvLjEEaZzTl8PhKx7TgF0hotOgUD0TqA7OJ4ccwhLKbIKnKJ8yGdHpTNWEAl2CCKc48MnrF/v7+8/KkiOWZP7Jpt7qd/t9p3vo9J6d9bvP+8+eHz7tPH7y7OmzJ/9ayjfgb8mnrV8u0Mu2Ls+A4lSt2HATsWHAg5FoMuFMc6dfUjwqeSXkKML6lb22In/8w+DN8363WZmEhqdqK5wSDBvcrCv6GiWTVABYSwA6elKaLHsLRRHTWskipY/mJZN5z03eKCastN82eH+VTvxW8N4Mvi7Ar5/5wzHMJKfwwcJEhs7W4VqUEH7iWjT/uDSsqtRxe4HLUUmPHXA5wq1DB/7wkjZSWRV6QB5R/CXSGa2b9cfW3ws70tzGku32HeQflTGuwQimKaT85L7a18W9TFMUAnXyh4ZiYNI6U7Gi6WcqDWS5fjCzjukC5KbXvOqIDcPY1evB7mkVF3Lhe425aMJBl/OkMiPufVOEs5TvVMKBE9+pRRw4cbBpwoHrGm+EHs6s2NpepEZcxY3qrrC5IBs3keIbzdHi9D2ocSwe3wEer8GdLCjDv0buZAlCK3eyRfCsFB5NsLnSzczC85wC6a6weWnXMgvI9+lmloDHQ4DhnVBONXYDS2A3cQNbhLyJW0wT8K1rvCPIa7VfVvs1VSxuSR+4DdNiNZqXZcZWi7Vbt6blfNfKtFh7uGZ7cSDjIRy3YcMc5gnvlhNx5eAgTmYQR9968rX8JuKKYFOSaUrSpoUCpRNxJXPXp7QX5IaigR6Mel7IpCSjUEzBELWL7D59jyKCgi9X84qFiS+VGmcu59WqIzetSlt7Rm6FBWXeoxCk5IrYbkXsS7Q3iaZ+Kf9IS9dXcbCGH7YJlnp7vekYIqrRVynQWtIIn4VIBZoAWovvPZkTo86QxrpG96C0s7Sg+RBBs+J43JUMPw+gQBK3gqIrfOn2IOq9AFlW8ruJHBkx2TTnc4KG0KeB1ucM6os2w7pTFnjgRg49cpCmtO/6aESCXLKQj65Lyq6oMAmoUY0ypiTsywxT8z98OJxXGeUX9z3+Qf18gVdcWriVzi16h/w2YQERUx5FzGsTSnQkAjl+9/q9IxlsQnStOqqaZlxFsXTWd4U3bymRyMz7fXbJ/Pxn4Gw65KWaL8YfwJzJD70fCR+ZT8rEIqRFs5Mbdy+5bnfbvXa/vd8+gNu2FHHospLp4O+EY1HEEYc6jvMzmgt+0GUMwVc0DJmPazRQF/WCH1D6nBy/xLGx4yj2My+QHWIKAZIr2Dw1OLtkgd6cujlgs5Ivg4dEjQE9a17+UTKV1rPso8qXO7PEn5oruqoxZTNyrDSYn2FsHfICByQujSWThAeuH3sMRD2uizRjqFjgsC9cwveYkY5ftgniYlkdMIi/4ZLEQcioO6G66NdDdx/eeJUP8tmGjFpynwVu0xAB01qFCCR956ICTtMntQGLZgTFe4MtKSeV+8RbMkCrwdfl+j83WasHv68ssHprtyLeKiHjB6vNyUDYOiIpEnzUkRSlCKndrSsxMh8voYfYLIRcq9F4VRIaqEUe6Om0Ggt2hQ3YDGmualIWqS1SrwGp71VobYKyxtu+iVdQArPaK6gUZrU/QCXMquegvOESi3ptpjC6GVCrFnp5qC1swqYLy1XTtSBsQXgXQHg5ZxEz4t43AxPLxDwlIK5jnkpBXIe86JWtLlkdzMH4xqB4NoWOWaW1vUkPuXygk17RzZB9K+ZkUfe2PedTdLXgeuvguu74Jf3OhgFMCdxCAJNM8DQfslSFs1ptqzNzuRZjF0cr3SbAJgqQGwu8ZTO1sGth16qAlyp5HlD/OuKu3EPvrb1vHo2oZNH3vQReq7xeaBg5SXcHuzumUxad/wFPSNKSpG3y5/sE8y1KQsfjkI3hMqtbornchJjq+XXIsTIES+LGYciCyJmxkAuP0MAjs5BdchFL81skIqq9rKMQnGjgdNOQSxF0zoN57C+jgrTJHg2jQYYvZDBcz64A4AWRUbUh0AVcL3DlOuSVolP5nFxQpBbHF2MeyIs2uYDVuKLXziSKZtl/e+WP5YR64srh0YX6uuaufmlaydwc1qHR0UOrqCocfJA5YulxOcJnBF+cnAC191eMQZ70S+rHeEVLApQAEsBVTqXDPHB6PafbO+t2n+P//6vVbiEB/ay91fA8AQLQKGLTWSTP4HwAeUYiO8TTzBAKo5rxuTAa4KE/1R/VVOWk26sTodOONnBLyK5shntkQhMSBpEsqEb8zGIaTgcLlHKv3yGXowf+Pt1uN3kA2/ThmPCADFlEn2svMjIMGUXHMnCzGENSPC10aOaiKVWtNsJ8bv2fHzztP+tBF0O/1S173f3975+y7BLTLS+3SXq9TwohWmpryjonW4jdf6beidEqQrdes24fAxpHExHyryrM7qC736zjaxEOuedh8ez18MujkzNyZIC5AZ9cwMbgMNTxLfOmjvEUruRaKY/44sio8IaV2Bnm3mWhFuuac7RMvzqmlmtWztegiTOM3c8MMhqnXWGKlcwNOhHpi0i2CXgqgXdiRHlgysdrTGaeYpJtolZ8eE08PmWBBGmljTwxZFL4MV6oYIwQhGyPqPkQyb8y8gPrjDvkYiLiELiIR68vfrTssZw9qjEGPLol1qg+buBR7tfwRzg83L/OnD7lX6gYYzmrTG+2vi+uMCOcmIFz/5+mvdT3A4SKpmxVpfxFkjUDK+zXhw53HwXDlZhvO13xARzQ4qqc4lNyfEbU0zxBNpMYDqs+jc5m72DNih8Er8p+0fA6YlWf8/iGssRZ+j2NvUDTU3GLEkXm7N2LUFG6IwCYmjGqrXveOvWpC9JjZpOe97oHTw+fPG634CMGCgurToTiqnWj9bvPnvQO+3Wj9ZLRbiq7pJtrxZeNE19y4LM2CUbMnGBJ4QW71MotYua8qxZZwD9fzMi7pAZCTk4hw+tUtapFkIzsAupVMJqCu6zqT0Jx1UyQQZGlRJax8ki5PJIdc90iSSRmAzqbycHweoB4l+cFZ2JGel0iEw4MbeFoqLZr474AA7MXNGJjnUg/AABvt0TosfBnpK0UjMu5crIqzbh0Gz9dCTaQzZyWcEL4+kOStIHvVqoLI97cRArTCtpVxDC1PofZ5ckLXHenBjkTs3fNhRYApFuVV/AF9yCqKGkkOcAQtOT7dCgUhqvjvVhW6RbP8PNet3+ghZPM4K+5z8hpJEJVficd+2UoZkPxpTD6Yf+g//Tp/OCHvT58w40kFTF7Z2WUzZNRtGxwM/EEOKhj1mlPk6kz4oEHZo9FMkuut1PsXSK+ANpidFyoDTHDa6K7EdOtgTSTGyKkwWfQhFwrM8HceOsQOdbOj7NfUMqOG6zSKnp0zXPXxiBAujrVB+CFmuJrPUPADeQfy/COwtbeEgMpe8td85LMFJCWev19dnD4+InDnj4bOr2+t+/Qg8PHzkH/8ePeQe/JQbfbRUE36aYZwi9CQNLW30T4Wc4oulBEWsveB5wrvqi/+EW90he95W4opBhFZP/xYfqW3hPLYW7CYYCEiKGhu+YwnRyEd4oQftcMKGE8C63XedaTsJwyAzYusGmaAOgSduzlLNQvjk5/3lzmYyZWbrw9XZe99lYYjOEsepbLMZfXhX2/HeZScrru1UKr5/MhFF7sgjbzhS9iuK3qB2dKI6FZd/p73qTbLhnolNLTuXE+CBkp/63COL1+97DcMnzjGaIp+eYzfPa0bw3SD4mXNeFh67JTV3CxJkbrCkZWYbeu4GUNzNdTFo6ZV7Bibwmvyq9juhq/MfbZr1qGjWNbqclnRc41Z6q7LeZVvo53wL9Sw1/ms1xkCM97h912S1IqW8/7+zooHpA8bZE8P/yujHhYrLnOIFjylqfJKPvd+rc8qXpLTgt9U55Sf5Isq9kWVrMWm6L8E3MTlsZcyD99XAFlOsRiMTpQQbpihiaKajuitqTNs49XX5gbq5wQp/94oxX7akCwpoFOTr8GiD1jCSRgjeugp/svyrgFlybJwksdUWK6QTvl4gQvgPaaZUgCldwFmdLInaj67HwMBd3//tuZ6d0mUmTiQM7oGN7iAQoyyB7199P379R0IV1UICIzuAcmQIBLHiUzUe2w3nv6TpheEmZCjoJr8lUEGLIQhdxVGiRdIt4XYAwVKjtV0kUtdcoz28opLEQAbBMRR7M4IipJJ/h6aQLDjU1cvxQpkZEAcxPOy2dj6hpfUxZ4M8FXioPJb7dxfFefYGhdmXNxeWR2jzvLZAvNmju7vf4+6KCePqND12Oj4r+zRl6jCc/lKC043iYnMxKEqRPbIUckCin3gd28fn/y9uiMSAaBKRJPRRv/+xV1Jyfiqk3O6PCUwdJhMkARkrPTX83eiIDQ4Drx7lvKyJv77NNXb169OCPMGzMD3JB+Lpbk9cn7tyoJneyADViDsyS//e3VySt4NcNT85/kUb/bf+x0QXR5RN4cvz0+I71uqyo6aAEyJ/4G8k/f+DwrVtWYmeSGeEt9OMgsz1ya8IjcMBlu0W4d9PvL9v8YzEIBnwGRGFrYgoGerbQkb/iUR6++uIx5iusdLr8wx1BPJKD+K5Ch1BhNWG5ujHciOoaDNGVBZCay9NKesvCSu+xjkEaq4EBPlh3ohKlcka++TGgscUL1nD1rVEv4zuk/3lTyboNFaesiC489rlPI/d6S3udq7k792aQZe5d/+h3DhZvUESq90+VZMbSxvNjy4q3lxWvMBlN728kD1Z8+7lbCSUyC7plPefZqe6t8tS77edXt3fJcy3Mtz70FnovMtuk9eY9DkAw4t0a6+FrtrTnXuo5bY1bTZCObsO2s/4rxvHVpRH0xjlmSR/s+OfdP5o9BRMdF5gxp5qnmbQk/65DjEZExYD3cl3hUz6qNEy7F2F0/ngbE49IVmNZZzBTnhtT2KsG4S30j0GjWmtueB8hi0+uuTpA9UMsk6y++2lfbrOmURTQJR0Mv7RDPHvOSy2sZR0uTDegU+K3n6Ln6vWxasYzEdECjKOTDWDkIN5ggJS6dgZwKp0CMiBqGJMOge7Zad5iUJGKIh9wjXhwaH/NZyFzmYaYlYOnEo9cgpElyMTeriyRVPGYzFQE4yCZX+AG8DRLow4hw4weqG9FLEcLcLsy3ZofDS/+NVu6mS7autVpykU7YzKeQke6i8ghctMnVhLsTQA4vWdM1LNkVZc3WCpyfWCgzbOtVMOZBgrfSzBAwxiAP81R9lgyMPpJEXAXYqwPJHwCFLnB6F/CnoiYiAj9ZJfhiVaAkMxp4ZnM3Bfnk7ZeCe1KhjS/E53jWfJGU6WB+jXz2pdkavRFjvGaJkIWl6wLZhpmnvu5qwkKWYzATilg43fR1yZ7e+oU5ycw6y5sxBDOCVEjsC3VV5AjcNokiD7SHwVGPMG8o8kc+0kxP8yIyoR4Zslx9kcAjnmCKtyqTJPZJFgMUlipIBZYBOSm2TuaFkoEiMV9cg0T6SGYECQ5WwT+wGoz6hIuDfv/ip0y4Dw6M2eokGcaRYfR6o1CcwW3PjpQwZP8a7/fohHsliEvhDuzSAEYYgmOu7xE6oyHoR8+Do4UkiW+nU429se8rdNJ3tUSsUp06/192W//z4ieVkwpwEFweQUPLI0W7oZa2GMoWMnYnme/PHWdY8IvsuBe5FslmTehl1eoSn39mqBwWmNsnDj4HMAk8MuVHuEw+KLmgVmp0y6Ob0mOQcPw0rZB/vb7iGMUbViqVrWSKbHqTLYhtcTRRxxLFQcgaxbCOiCIo3weEy21f+b2GzFg45RIi0+AIIUQl0XBGeMVtzCxelRLiKKssImgsX6g+0Pfsght0Rvx3Rex7RNOYvmCDvgwzteGZ1LuN9XCyx1dL8pkiK/pwtlXbGnYOjcuEIF1jB8+/iKECTJ589Mi0mvYL5Abj6TsEoaCxk9xj6auvKPsPzWREaAIOJfgOhNQFiT+DbYicGo50SzTjJOuSvMiFHE8hp/qykgFYxMcCxMKYCSsj/+///F/COJL6kGFFG+ifAxmNryJtwSuRFvaREe0yocU6PMJmihlWgKdgAmmjmh7I4wCUmZBhTB+C5/C6kCGzD0TmToUTShg3vi+VI8Ul97LL9kN2D//DADZIj7qAz8WPC8/9erQ5JcgA65nT2hKplC/IsNl0JkIaQsqFOFXGdOqWs+47HprupZNXmawhK9mAId3X+i2k26waw26nTgw53Ys2gICRYQ5aUovIJZ9TVzQzpdAx4EtUL7p0yAcqFZlmepaqSBSQ69SGWP0qYFc+fCKUtJpykCXQKPLDu5fwvz9CoI8WbHXtK1WmUrVSKQ5TRFPv40m4trFyY2PXB+xRNcug8Yf3p2dEbSJqBwBtWYhjcCYN0FwThjpX8vHkDfFZMI4mBGcqq1UtTezzgL3XubWGW0McJEt+LeKw+vamPgMFda3qxwpsU0QeXGZD5Yhz1CQtzW8rTQxFTGnJxiGFk0WGbCRCph0HoDTgikHcem5DXwx7bRVT/MOPygQxvR4YBqEsD4njGPlP8u79bz/8SBxy/O7s1cmvR2/Io94j8vLon+SXk/cfP5Cf/6mGJO9PXr46gX+aoV++On2R8QG4qROAor+b2iT0KEUPs6W05nqMm9gk9BBrMUvosc6EeEuD61REX5qR6YEMLwPDAAuLHG3JwaqsCwcrjKV1zOBfKOJoJeuCIt0bMLklUmvycSDCJDXqQmanvxJ4XhPT/nKO0MWl1B96rJyiK3J+VLM+7LAa7zN3hyEYa2+Z8RWsFfBKYIYoPhGQpDaDC34I2Qj1LVzelAk2t4SXyuUqSZgOLYPKoYpj5lOEpY+1MgpM1MWkYAV2I+PpD56Ihz7r/QhbgBFp50GB+5wHTdjPE2Q/50Ge/5wHCQNSkdbAfs4Dw3+65wjToE8YKA+Ksm9THhj4VWo7sy4XlR9XxUsLDDKz9ZiKmcOKl83iFJ+oYYmRWQqvrnhnK+++vfWCzrq9GqwQYYWIrRIibiwv/Kmjeaqvw+FY7Kl/gr8a3IphCl71lTgcC0dOISVYKGLIFY7+/MonAYdw9BBQz8F4K8zVVFCLJEboJadTSx6FY0FOYWhyooYmeigV9JsMVe3DEMTTIQvTcZFtKi1r/eDl+tWb2vCP05rkYpRVgdZf4+rjbsZC1cYYD9KS501rMLxYatnXHMOVKfqwKHArE3l1eJMYpXStsmc8LJgDSitP4kqpZUoOiq4bvtyyKHV7blEQEevXw4SuPel297Oha+8EAbpLnXM+nhyjGF++egFYr9IF1ObslVYQsDFTSAMKGA1MUYw1FlqYP46VWKuCp9CxiI5YdJ3USJh7oIsq/AtccrN/Z+reuKMPicVFniS0+c2UtWj9GxyGgdRlF56HCOvfdVefBkc5YP/WGsaSB8mxhfIYEQtnIZfJrXAUsuTvWSj0+a5B/3AsOjnsra0duQCSa7lCxEfUjeReYsesroWeNB6kjQdYHnjONy0zWhEq36Bp4siMlWnauJ4OXoSK2r455Rgmj9FqV22n72F0KP3Cp7DTffwXD9S/elkDvhuHEk1n9a9IBNZGmPwu+dKlTKFNi8tU1RjMt1dgU7JIybI863af9J496x8ePDnoPnvWy6yRU3z2vd3yhBvD3UDdJOPQL9NP6qvV81Yc8kxpm1KTtHIvXfzl6H3Hwmqv6LSyDH50+tZP7cLQ3wvVduxS3mgpF9e9LCykcmIZ0Kj2g7HYLSgNUKai3vsAMnhrKP0jDrn0eOJoO6ch1+AeB+m9tNVuxVhQKIbXMC+EGGpA+gSTSlc1ZDOhxIy17r6qPnmTVShsVfoVheXJfUI7u/y5WdTs7YAHI4HQFVy/HyE2F2lj3cujIblsQ2YsHMzyNHDT9xVPveEHyava+hPnF6l9+2ux5o+9lRXUudlugVDUuLMCWK95x/UmZ/Y7+1qz+/mPnD8LucQLJR6EmUpqn4ozSFICLqx8lmi28vLGz9TLeo1bgWODuCR+47FasZ6VPm5V+kheC3dk1LsZoaEBaer02Teizd48bRa8B5MgVEunm3WeLJ3uEJ2W+PIdBzIejbjLwQ0z9dS1N/hNO1CWUHeGUA/LhF1jiUTjNAuV77ul0g07TZZKd4RKm9vbjSGg2tCemApulj3PDNPJGScqrSrasFGWJe+GxmJMLjzyIQLCBMocv1wqrrvGm6/MRqMUfDkrzQv8CSJuM0rCwjSxCZbgUkGHJTabEpPNurK01BPPInVvYvIpKnzXpQdGwHmDjnmt54/3EWTMP/vVmthPpc5NJRfExFhEtHrW8rLNw1zLvu6AfVlb0TbYiqxpyJqGrGnImoasXGHvyJu5rht3R7amoa0+T5ZOd4hOrWloew+UJdQdItRn84T63mhIISnPyOeulXk37ShZEt0ZErXW2609TZZKd4RKb8V6+8rj0Z1ZbxOT55JVzkri4fa+JX9/V8jlswhPSAPTq26cK5+JP9WaXlWTetNrdXhcdtyatOMl1lxMGbpU4qlaI+h8VNzBPPSnhk61Vl6nZbWW24dhljfsCG+wWsutPk+WTneITq3WcnsPlCXUHSLUErnY1NlStRpEHFheumlHyZLoDpGoNSxs41GyJLozJGoNC1t7miyV7giVbr9hIVHolweGNU+cV6wrAslS62wCJvsp5F4vUd3rgbbSKlCXK89i9eZhioVnG/Zkw55s2JMNe7JhTzbsycoV9g64weu6cXdA60Cw1efJ0ukO0al1INjeA2UJdYcI1ToQbONRsiS6MyRqrZNbe5osle4IlW5/0kplVNzQnJWrh13tgTIet36BfRXbVdQkw2c8ElBmuaIqWbYJlJWmWxVu1b55gbTDW6qPlvaUjIbuZKWeIlz8TclKpQlAc7YbY+OqMui0Wz6V0WAWy4n6J778U3YeHg+ZMRItPRk4FJlpUPwX/vipoWX8JHNGraiweSzNSgdbXUdOk+pgGNLAncyT30v1nKjnCsLJW6hCCtdsIEbKA/Ko03mEZUmn5gkLPFWF99HeIyJC8qjzqKTyeYFrzH/EnFjEvdIdy6FY08WYG1whXql9n3oDges2J47h46mIGh6l6k9bu7UfZRz8pvw6z+16tcF/jj/o78kuSfL9toCedRew7gLWXcBKWlYpsy3runFKGesusNXnydLpDtGpdRfY3gNlCXVnCNXaIrf2NFkq3REq3Q5bZEcZ5h5wGT1lUayroJcYDa+rS+iRX3jkuGI6oxEf+iwTwZn23j6D46f2HVX7W6SU/4WXKeSnNHInZO9/f6fO1yPnX13n2af0z85gz/n017/stVMVfVZ5315Be59brf7h49xy9Rbr9jO9e93+wcr695IYt+Z1B0/S82gLD24sr7Js/84jcOcx6LZsdzVUX2lW06JBif/EqhYw/TIztI10taYra7qypivLv+0dfkPXdePu8NZ0tdXnydLpDtGpNV1t74GyhLpDhGrz8G7jUbIkujMkaq3LW3uaLJXuCJVuRx7exdblWyrzp+JN1S8Na/4pO3Fdub8aO3FS7y9rDgYDJMCfF/tMEhcOQDwjYkR4JMmQup95MCYejegWWIrbuSnVziZjgFx2EmURlP15XmR2xHXZzNo3NxItLeO5c/tmqTFy3nxo7YDWDmjtgNYOaPmcvW1t6Lpu3G3L2gG3+jxZOt0hOrV2wO09UJZQd4hQbcbbbTxKlkR3hkStHXBrT5Ol0h2h0odiB7xZVU5luysvyFljtTMVOTM2uymLqDXJLTDJ1SU1vba8YPMwy8L/Vtb7tKlMbSrTtaUytWZfa/a1Zl9r9rUClb1cb+a6btzl2pp9t/o8WTrdITq1Zt/tPVCWUHeIUK3ZdxuPkiXRHSJRG6G9jUfJkujOkKj1zNja02SpdEeo9KHk/37QFYl1hPje0BfDvW8TKicYLd7I3QT6zPmcwAapbOEEnle7nNArMryGkPGRCAkNCJ9O4wjOaNKXqOPbIT/DPxIXDAIL5lJ3wrD1SIQM0H54TWD61m8ljXxN3gMLU/ueg67jTmhI3YiFxBdXLHSpZGTCvlCPuXxKfdwVtSHJOq/ZhQa3Gc8EDD5h1GOK3eJmO8DFQ+GX8P3k5Oj5YXsyEz530RunZomMbOD4en+Kg5/yrwxSFkQTlhxBMhQeJrtPJltZmfp75h1F+UO4EYscGYWMTkvlkHneM+QBkJm1m20li7aiz46IPtZuttXnydLpDtGptZtt74GyhLpDhGrtZtt4lCyJ7g6J9kp46Ym6ixKQe6NrEglBfBqOmSXUDTtQllB3hlCt9WxrT5Ol0h2h0m2ynnXAWmNtaK6YTnm0rBVN9aqzo6kWlZY0j8Hp9pLI7XKDmhokMam9UP+0RrWHblTTG50N66+zrFW/rdqOZSUBG9W+7UvZNKqdxtEkF8hbdcanlJesRXUYd1nJ67YeBjiUejHzjtYcmIzwEN3auPexVAjMZePVnbsZDVkQ1ZLS/DSikLG/lb+tMEnNLJIO6WTM1rayi5bOJ7fz+f2yEe02ot1GtNuIditMWbXKhq7rxqlVrGfOVp8nS6c7RKfWM2d7D5Ql1B0iVOuZs41HyZLozpCoNfhv7WmyVLojVLpVBn+lhrYm/xH38dw2svRD4yo7Pw7UMFYWG4PpXviXzAMbfchGmOAY1sva6kts9SEbmdf8GbOSTPi/oDPEqK1TSbdJRMdtSA2t/SaWtc7nPrmXnYr+zJq5vIbtNVu56gsbOQfgm0ojbm1UrJVwrISz1eu6cRKO1b1v9XmydLpDdGp179t7oCyh7hChWt37Nh4lS6K7Q6I2KnaLD5Ql1J0hVGsk29rTZKl0R6h0q4xkYKaxJrKRCD/jubzvD2q3ZkI2MdPBhLMmutci/FxfRxlaSEKJvndlyinzIBKEkoBdZX61Jrp8DCvKwj8LDwuYFvuuidHmi4rWlEtdUPM1s2q9bv9g5bqsZUFsnwxE5+x2JSrzzJLDabXK8k3knFYIufPo3Pl60XNfsKaSzpVEr2a2zki4dl0FZy38lPg+rFpsWb/MDJ1+kQ03teGmNtzUhpta6cDqKzZ0XTdOX2FdXrb6PFk63SE6tS4v23ugLKHuEKFal5dtPEqWRHeIRG0B5W08SpZEd4ZErbPL1p4mS6U7RKUll9JTFl5yl5E40J4qvnUb3bSzZGl0R2j0VhzSXnk8uuMi59rpqcwXbV2OYHw6EyFu3Na4gukpZ53BjvGnencw1UZCEYa/nZ19OCUqu0DBKSwg6Y5b37Dybbob37DUXWQ+KYR6pmZP3sYyIlMauROy97+/U+frkfOvrvPsU/pnZ7DnfPrrX/baZAptQR0Fk6Q8II86nUdtTNORPGKBR654NCGP9h5BsolHnUewRDW70T98XMj0AEs+iyYr84reIk+1dqsRsyhAKPRZxZ9NkRyREQ0jaxHbRAZsZZld9Gu7Tx8063lmPc+s55n1PLP82yomNnRdN04xYT3Ptvo8WTrdITq1nmfbe6Asoe4QoVrPs208SpZEd4hErefZNh4lS6K7Q6I2H9oWHyhLqLtDqP3+PKF+DGahgJ4wH02ulkg37DBZIt0ZIrV+3Ft7miyV7hCVlrHSmSpyYx25N/gwWSLdISK1wRZbeZYsje4QjZaYYH6hEbui1yTiUyZiq9zdtHNk6XNH6POhBEMlYT+3GQ7li3GraeVYX4zLC8ea6qRclgYimQKyutmURdSjESVX1P/MgzEZUvfzFQ09SUahmGJQU0kJ1L+9Onppw5JSr/Y1V5UlL5X7uySRSNZ6+bqyPp/yqDidygqsGejsdbvdXDxQZlAxGkm21KhmmG7DErQvVCVpy7Q3j7lYPn17fHrBQtI4muSCTqrO+pTykjWpDuQpSzvf1sNA0IB6MfOO1hxEg1Qe3dq497FUAN6l49WdvxkNWRDVktT8NKKQsb+Vv60wSZxTpkM6GbO1reyipfPJ7Xx+v2oOtA3HsuFYNhzLhmNZ0cCqRjZqXTdONWLDsbb6PFk63SE6teFY23ugLKHuEKHacKxtPEqWRHeGRK136taeJkulO0KlW1VS2xdjW1E7pFd730I2+r73Deb6vdXUjSCkV+VuBJSE9IpAvXKVjlIjMcFPqHIqwObD64hB+lIp/EvmkeE12LsxySVMra2Go0QGfDRiXm5gbDUMxZVkoSPpCOpmK2sxmTDqsVBap4N6p4PS11T6HBx0HXdCQ+pGLO+AsNxqVLgf6LlUz+s1HBd40iFv6XWSFVX6VE6YvMkkGvkZvE5PK55JcyJfqBPpnDU+kfpPxeJUZ19PZs57mH9lRIxINMkMNRQepABWkyn19TCs8vv3RChyDEY7M+Fz97pUIEq50vLCVMagmG0v3IhFjgpUqOuXYbxDHgC0oOGSfYn2JtHUX/RKbDjzKV8wOWvk2EKRx4qSOyJKWiPHVp8nS6c7RKfWyLG9B8oS6g4RqjVybONRsiS6OyRqE1pt8YGyhLozhGqtkVt7miyV7giVbpU1MqRXO2+MxEXHI9HABKm2Ug58LvNWyDdc5iok6lGLHw7NpH5IRiLMlWG01sISa6GMaJS8qDJ+N5m9rsSFRzHilywl7MwPX2Y4C5jQpfiMf1Efq/1lzYHjxa9NQTh5b74yYXbANAJn6UH3u/lw5/w7GpkPz/DMWblg8/iXFQXuLUrZDRmNmDegUe0HezRiDiTnaalKo++x0KiWKRSayOZjVNculK6YlaxnCmHw8la7dRXyiGEIr0LHmh41oDcn5CDTVnNoJ7ibWaLct9qgWhtUa4NqbVCtFQqssmBb1nXjlAXW32Srz5Ol0x2iU+tvsr0HyhLqDhGq9TfZxqNkSXSHSNTWONzGo2RJdGdI1HqabO1pslS6I1S6VZ4miT9EpbOJdql46N4mIWN73yBquXnUO/SpCnuHYGl4Xhnk7jE42R748YacaaeTgPDpNI6wBKYZgajD3CFH2dhqEupxogmN9INHkoRCqF4/EUqGvhhCfHZEx/k+B/1+h5zB2Il/AoFdcKk7YfjykQgZsJLhdRLJbT1gCh4wOiVy9XtycfG+uGKhSzHi+wv1mMun1MdNVvu7dMR8U/8S2GZ9yIpB5rDdDggJoVgQSL1C3LcVJqx7ypYs5bLuKdUJ2vMrnD6oyARvJlPtJ6J5CEA5sJnrqc+Dz612a8wj/Rf7wtx5nxENglP19SZ7O7zEOohYBxHrIGIdRCxbtnf8bVnXjbvjWweRrT5Plk53iE6tg8j2HihLqDtEqNZBZBuPkiXR3SHRfn+eRD8Gs1BATzQcqLQklkg37DBZIt0ZIrUuIlt7miyV7giVbpeLSMjYTtZGSDOQ3PtXtFszIWtdUnQCFBUWnvNIeYE/5TKaqEwn8zPFlhLKKkC0uad8UKDpNuZE+aRGYjL6WXiY17448JqYH6xKOdYtnTcgivx6+N7vHe4/7uYyjTzuzgPRTBhxoOAhUqK0xgwkROcTsDLB5vEuKwbcgRhQOLvrSx6CxSegDMVaIKIsNUj6hjRNSDYjiPXvsP4d1r/D+ndYZmwv6Ju5rht3Qbf+HVt9niyd7hCdWv+O7T1QllB3iFCtf8c2HiVLojtEojYByDYeJUuiO0Oi1rtja0+TpdIdodJb8e545fFovd4di1N/JM4EZb4dN3as2PvGve8KzHymsuUvcG5QGfIL6TbgJ0IrPBrUYwmZNdKlLPpBdIgygR+/VGkwQiaFf8k8Ek1CEY8n0JtdsiCKqe9fgxgkuQRcJTzw2Jc2kYLg1HgwNjMhVzya8IDQoYgjcKhgrgg8IkbK0A4teURcGuikHOSge/AT/B1eEzqChBGUyIkII+Ixn26Du0WaGGOBP4xZ7A55G8uITGnkTsje//7edZ5R5+unb73H3/+ydxuZMPC9usqC5Y6bh+KWId65n0Opz8K8j4F1IbAuBNaFYDNdCKyZcmuB2t4Id+RGaM2U232gLKHuEKFaM+U2HiVLojtDotYGsrWnyVLpjlDpg7GBJDaH7YtvjT0eDXwxxo0uz2gOTRxo4oxZ5OjeTvpzztbyC4uSeWITopvkv+oXFkEIKeSNB3tH2tLkONdjdMgLGpAhIyPuRyxkHmQbv5oIMqUeI9GEEXdCgzFrExGQqwl3J+SrCFib0MDDxxB4NYLlh9ek7attJZXbUr3efwnZqPW89W97rpjORMBgldVTuUcpHXAPFC0jzsJWuQlkvpx8frVe88DDiNsZc/mIu7BSsBA8kvowFLGIfaHTGVBza9R7cjBkz544vWfDnnPQ9R47zw4PPOdJ1/UOR0PvsO8Nc9NiX2YijJpO7TjwgFsynWQ+mnBpIlMIR5uaGg+WH/eXB+TF6a9EgWVm6hl0MXNHJMrMDOphi6CDHRqvHBwbCYsFm69GIDBC/apRz2sVXi3CDp+t+N7jD4R6XsikNMfQrBGuWuEwQ69kq7NdQ3JJfe6RF8cvT8iJOcfVX9F70uk9ftrp9592Hu+XfA+bUu6v+EnYt/hVOGzpN5VNNGGYZh6Z9fe5y/5L/7vjimlu9pIHbs0RSM0O+S94w6dAMWr5waDKIIoKuJUkkVDHM2BXDL8gwHZ6G5hHIIwT6itcjGLfd+BfF6auQgAfgkOcvH6xv7//rJP7ln6398zpHjj73WJYaMmaIAfhgc+kdC5pyGkQvVMfDe8dYC9Yidv4siRSdfkvO+v2nvf6z/vdf5WHvi7zodBroAJmP2V3fcig4sTtbLvwvQe67Yu/bMO3Hfh5J1uvY0mgCjLMH8YiVErhckhkAF9YD1HpR1dhkcdDhlyl6fRe4MvUriWdU+kkFIHwxZi7cE0VIXiB1E8MRkf5akRRtjc/mOBw/U8qVQWAZOIZ41WjeZ8yfdSCeDpkIcw4c9a0h8qMhQQGzUxZNc9OuX+YmW4P81SYe1kvn7ail5vwEpN9yUY8YFKLhNCzdL610zzsZqdZNasJ99ggliwcaEF3SbHpasKiCSxniIrDSBAYkcCIxGeXzM8Ix6XiUjJFvI419HMpF9OTUj/LqEQWSb/pFWNghh+4wvc11WiN6v/8z9KTJCPK/Thc22T1xXXxzbStflBSy/PfP7Xxn5/Z9dy9FSf9Bs5F5cVVf98pi4DUJfkNkzi05x+kqZvc0QefBke5m+231jCWcOSluZ8wUBzMQi6Z+WUEdUL037NQJFf98qvymAUsBGc288BndTfn7HWwvk5YnVdgHImQjvdCOlauf3uUO5LR0J0obUhpfiPVCYoUjfjYSXtk76VHx+TU/FrQ28eB8v0zLQgSL6FjygMZ4aM4EidHv1RfGhfc4UM6Jtik+g5Z0aEa9qfXTkgLDnf7/ZzDXS8v8S99r61+ubvvuYej7nD/gPYORqOnrDfcZ2734OmzQ9Yb9vutssxKa1KyKk2AbNX4FyEplmjd1A8lH6ZZJfsTNGFwzMcR/hf8ibosX+deuqR+zPKvLr7lW4GjZH4xoP19TmkGM9bzMy9p4DuUWYpmitEHujANvoAGcO5FOJ8eR49t1rLcTWdKvwyCeDrQEkSpcjkj0mQkmsO8PKPKLfn5lTKT/C93tDdlEd3zfTqlzn5n33nSHToAQ2HsRs5o9tQZUSy1ONe05zzNtmzWavZ0vtGBI10RR07vydDpPWZJa93yzysW4H/tO/vdoUP3h5lhPMZmkrHPDuXp32HP8biMuO870M/Z7w/NW4UI5ERElO995lPufO5n30YD8K2ecXfP9WnsMWffeeJIEQSs9Kl64hyUPROzWJY/2XcOnQnln2OQIljIhiGVe2qaTn//cOjQfn+YnVV1I/Dl/qxOXdIot5HzDw6cKb1kIXc/q+XuP2Wl71q4M0nL8SxyhJROr4/vGwsx9hnyxCj2uNgbMziMTr9z6Ix8VfGrrg2ICe3WOBSf9+C/cA3HofizcEIvWShpxFFCyD1OzhtFfzgxYwHlOMnDwj8deGfxt4AGIkORGSgxJFPyFOhVyd9lUBdS3KSBQF4ry/hNQsjfvs+l8aPB51JzDGbVCtkgmoRMToSf9ZlNrhbJwN3OQfbSk0GIrrbr6Gk2sDkGIJllX1d5NViIPUNK+d5wzBz1fhY6QyrZChugvgHzkQ2KW1EzPRmFjE4btr2WEZsOZqGYzsrSphVQXs2iPN9hyf3oJKmcylDZ7rGIcl+uz1Tc1PnaoxFtzt9pFIV8GEes5Fzny3NWDFCZg66cv6acN/OW3FS/I2dlg4rEd/Cssu4hUtQ8HRW3VjUrlQomVA6m+UFqjlTAvkRFR+dEkJgzkOrXlGKMuUaXfhVeMubIouLc5lpnRq73HZ4bJTHF6nNX58j0TkTkNfgvbYxjxLxu5km3268zsWcvK+n3rGIyX9kOPmf+bmDzXkKzgDdSAv/R99pKDUMMelw61poFo0FIPUlPkkmnqO6KacdNLM8dOuMdY5GFW+en77eoh+DjAElWNahWOOCtv07bkGoCllI5ACbVmcNz2gbVOKtpeK1/KarqZSQJtlYRgcqUbZULKykXmiqFa+5olVrmhWrx6kH7lRe/bs58aRRR9S9IOULaM6JRXKNkrrr9grYT4mdhe/6MWYx/hHEQ6GYAUIBPjXTHWdkoVZoZQrgt+WgBx1CfUMZvy3UepWoGvQ4Nih/XT74qqqk6OGtRlFWDI3a4MKhqnv2pKKVcCJMOVrqZeJFfrzphQ8PpIBDRYPSAhI7579oA4QPcYktCTGK8Qg4iMXBBh+JG8GfKXzd3O3pPmm5H7SduwM6sXyxsKg+20x9yFqYdkA8Vy1pKNvxDDBuLhmDscrBDVjwEQZD8Xf1aJiJCB+MEaUXD3RANlxK7Uq9ZQ+36NN2X5BV4g5BR/ZY58YsFHvNKayRUl0PwqYwGkrGgqt+c+/ycxAv+E3prvNjX+pKIhlHVZMqKJujXbJ5AeFNRby5w3Up9VuqzUt+WS33IB6zYB7vb0XLXGj2RYMS9b3+I4UCnJGsiA0LEzB9iOB8iA5tFXiZWpXJWr61OBXEQRMStFgnVGq4oDt67T1NzOS1Dl5mtvmMD4g6IZ7dnCoOTuh0ySr/XlCnmv2kDuKCVT6x8YuWTknq5q4snewsiekv1VPPBvEZXpVzYy/VV2aBdK6Dcs4CyHcqvtWu/zPm8Jw2YLoubF1wSzgDFOd8H/nWCFzmpKqPRqcsXoZ8NCm5YVeoePG9mvELvdna+VrVlVVtWtbUx22FFRys63ly1BcxwKdlxyQi7kvC6itg69bPOrW+NmTaI7v5jxWwQ3UMIorPxPdsX32MjcuawyEbk3FFEzg2CbmykjY20sZE29Z6Uq4TZyOvAxfMItZ0W3zmgde7GoX4o3DfAhCgJNIZESvyrKm5h3SnvxuSNKQDVvuEekCRe5Y55tFbgLwR63W5dEF+yNEZtxuVgRmPJNhvq95dWB6bftQGQb1WyG7EH/ZIK0QAHAx4MXCF8T1wFG70F/W7TLZj7rI3YAasU3wml+BJRPrski4JgWCOJDqnkgePSiPoC9S+lPhKqFbpG6KYlrhE/QyPyIn2+yGZ90ifD2P2sMmnSiEzoJSNDxgKi1TyESnI0oy7kjHbZkIVjYl5/DllZCzlckyzpr6g7MS2hdm3IJOQ2BKk3eSdRonQcMu88iASRkQjT10AGKFBtYOZ0/APDozrnwfKp0gu5Lk36cy0g6jmvnFI97EMeXmr2ZWAy0nOvqbz6Rm9Hfv8aFAJJoCYFOqDTtELF75+yRRauaMgmIsap/A40AtsACxdQ/zrirnT0T8opoHV42GVPD7pdh/WfDZ2Dnnfg0Ce9x87BwePHh4cHB91uF5IJ/xGHXHrc1V9jtCZwhwBFakADF1JswmYriJ3OqG78DUPIYfOMXhFgJRyzaCD5VzaYDiFteP8p6kwCOoPsXAP2ZcYVacAAoMVNHiEkt56guwEPkt+hGvPgM2Mznd+1+FIgz/wh6vX3ByXLoi8QKvf7pcqBnCwj1iTIr+DjIX0yfNrrOs886jm9ntdznnaHB06363YPRt7Bftd9uuRCeVzew0olby1fqvynJ6vEA7NOuSuNKemxNA9figxn3DGk5+ghCtVbVh4uGSTPk1cez4yRK4myzGj6f50kjKCW+ZdVECuBpZ+pZ+oCLFWUaOVlcMV0KgLH5NFtXi0UeixZK3TdkyyRcF+LcMg9jwX3OLFbqju1zkmuSQrNMU/ylgZ0zKBGUqVI+psIP0Ne9pM+eQnyhelqvDaqnqdOHDdPU5wX/m4QH5QbaO+bguIBdK6ODVJ9ICTIwEdqxMqHB+XX1qsOEwo5u2S6AfMID1QSfqBROhRxlC0akx90eG3EQph05zww0qqRIhVTaZMMr0wkSHyDKrLjhgzlOzjd2GPbJMZMgYl0E2und6rlbzW7VL7GhVzbJNWg6jw2lGtLj836xdo6OTY9DoNEKtG3ESvlNpdyrex267KbFdus2JaZWIndwADpagV9rVxp5cql47pqxMq9lLW2Kj11VX/U7Dlp+7yAeYp6PyPm5VsVzenQkuZBJNNBGdbNUB1yNmGS5RpA2UqwDqLCMTMQI1c8msCWSFToMqiDg+WDQIDlQaL2JMn3WcHy9gTLnItx8S3NhUdN7a1rEYdOakjIEO2EhUq8WWnm5tqUnjBHz73V1I3wReZwIpl4RPN9KLR2vW5hGXzUrDC3pDBXXJSCo58V26zYZsW2TRPbUmC9ucx2G0JZJy/oVApoKjj25jLanrnUL1YGptws8ZerUwfOadzma4ZPmPs5qSyIdSUT02+Z4IdiGpYWbhMeqD/OA5DthqC4AV3hLBRDEMsKwqApkobv0AttxbT70v+9KJ4MKHOJKuLblXK+pRosPDxWgXVjmSe/KCmWLCUup8AC5MsMvMxJUOrnxU5MVrKykpWVrLZZsroHbVhTwSsDTisIXh6D+haLFGOqVUZPl8pZL/FRQdQyTnElptepuNQCgBGoRqGYGmErCoVPZj4NlKILLLH4bhChUoFBoT0otk4ZUFTosv8AdqkKVMMbksHhK+WMuky2SQTLL9vkkrMrqaywGZvYeWBm3SGvYUj9ZhEQLokPJeNV5XNaJhWqKRElcK0iyd2ThHYbMlf6XtyaYuajshNB3An3vdSZcshGoEJN9j4rJ5clT6qJhdSEk2xHcmGh0qUeuHzNiYg1EJ7MUJFEUT58OKx9CV6GTUtiF0xTLkkgAodNZ9F1m0yoJHEw4gGXE+aRKxF+bkOTWSgi5kbMa0NNd/bFZcxTQIGnSGOQIsQt4Z8batq5a9uN5jHYQoQYRo+go2IUtd9N63nrbMKlxu/UnSYF5Tn8x+t3CN4aAZ7YFTmg8hhdyAJVs3IeqJ7lmeAc0plWOd9yKvOGIC5Tyw3xGDo20CjPMc+DYRwR9A4JYanYFygTHFT7ooOBKdVf0IAM2XkQMsc4z/s0YuFu6x+AsXtmg2SW19yNVqIGaY1L84NlNfYWaW+RG3uL3Hbeq7lbM+absh7l0ypGI8RK5CXJfU2HUylI65BXhv0kdy0Q4PCyhepU4NFwz5JtAnwLs9+gEXm2Ms9WjGsRy1atSjn2K3xUwYfnGIduPce4g4qYszlGrowj8jyAdQsYoDgNr5MV5cEopKomfQyOIwFEqGUZv34nrDwY33kwPg8eWADa+tk5C+6Smy+TbS5jJMg7JzV1BLmxJ4g+XlwEy3uC6ENrhMfbNZAs4/k87zM8vTbOwtaychdhXbljpSuuW+uIlWtr5doMcm+AZFuryaI+ZCW/NthnBXArgC8SwLWouqKgm7FP6IxeTTxj5nvNucYk6rWqKLXqqDmQtiq7adfmJHhOv6d9HvDA9WMPXZSTkCMiWQRXB2lD4jbMJeZt5QbflWtMfUTcFgWzWdHzLkTPecyzIqgVQa1qdYMluyyPeZGTPbbHSadMQFsUxtau1VrGM49GbJEM9xFbrSDG6Y5NhLi8NpP6vriS5FrEJBLngdauiTAxm2XEOtRgen/E4OGMLBd1kgT4rgp+gyzzU51m1kp5mx6ftrRY1T98vJxY1TuokasOy1ME3EwDmqUvTXLLakKrZWQ14K1LyJu5LVbWvXtZ14q4VsS1Iu7DF3E3QYZVzG1VjWbqkL1AkYk5ZDOt57LIps8IDypt9/PJZPP98olhc8pm8C+PZzMBpREmnIVQq4G71CeqXBOG9QUemdExD1K5mY1G3OUQ/heF9JKFkvrngRgRH7hxxkciGXHXbfW3JQHni/pq6q31RX8/o3/GLLuh2ElFKFDwuLzkAqMDFXB0zoOPEu5SXILDwYhF7oQoF48vEQzD4Lzpsl1qk+ekobTWTpqP++3pP7+8+/rx8N3Xj713Z+7Bu7Oj7tuzz92//3H05f2Zz+E/b87+/sf7l+Po3dd3/O119+Bfv/ydvzn7x/Xb3z5e/etsMn37h9t7d9UqrgIIg/WL8FaV3yIqpXiBYDDAAggKUo7gF3bOg5fK5R6fgg6U6Ape8I9uxWeXVi7Lli6DvoXiZckC9brd3HeFOkta9Ud9wDYZ6oPtQiomw+sOgTrD+sMk8XiIoRwQkRCyAFYAdzjp3DkPXouQBEyCjJ+NMIklI//eew0+J5IBPUciJD+wzrjTJuetYSiCr+zfe6+TVGbnrR8758H7KY/UKxIIgPkhXkVi5vjskvmZ9yxxktQrs6dAfeUgjrkn69fsNxMHLYiy3WTR6+PH45cJfmboAQJyIkHSaByXcW0zSjqrlxPMcF/xLTXxHMnHqftF8cPSpI/LfRr1PA5PqZ96VP0Q8SmTEZ3OJOzTb5BqB/Ep+WLTXZK0ODQyBX0DxH/Cd1ZtWuMPXSpBd4Zi78pcY9YdWFe2sHer3+0fOr2u031y1us+78L//0s76+AUQejRx/RT5mc8JK3nrW7v2bPhs2fPnMdPHz9znuw/3XeGw97I8fa7rHv4zDvc7z9utVvpehde2TevhKNSM7HeYdnEJPcvWVg3saHTd58+dZ7sD/edp95w6Bz0e6zLno76Tw6fFCYGCVkWTGO/dH3GUDixZhKus+89g9VxD5xnnus6h/v9UW/0bLT/9PHTutXpJaszNzrKrw1Xv+FaNJptdiIwh8zpyOyHWZNPmWJ3RkBXy2wVEbeniEg2SEnpt2loM+xT59cgiRQDYoYPWc8Y/Jhn7z9a3YXVXVjdxc10F+8SYW8rw+dzqoPbyFeeUWXsfUv+/r6nwsybaDd0yznNhvodpOtUClis10h75XUaqdAOIfU8ILRazbFYl0ESVUakrX6+z9AIYdUYt6zGyB6G6jmeZa9ahJsFDdd9a12iduaCK+kWq2f6b8+OD96dfey/++NzP1HP/Pbq65uzz1/eTj9G7/r/mrw97R7+86vvvzkbH749O/ry9pd/fP3n2bj79h9rUc9out9E1cyNlA0KX1ZQNGDHbVQytIkvlISwjL6hnVE2tJNxB8lQKtNJ8s/70EfoI7qpuogUJKG3cdy+BJCu0lR8b7fMigJK7D/f20uCjfYGg7A/wE0wgsPVxOGekgzgD7wHFfZphWHMGHuXvU6SJwHXDKQ4QwSJmoD2nP5T2nWe9FjXoU/2mTPsjtz9vvv04PFTVqcmOGyoRNmvXdFYsvB2FtTpr2lJnX5mUfsNF3XffXLgPHmy33OGo8N9x3vqPn7CqNd98syrW9THWd1LumA5sWnRIWy4tlVakuwXZfQ9Cw9Ko0+3pdRuVQejjuxm6F+s4uVhK17g3pBcKawW5i61MGcoBW+5BqaTaDruXhGz903xuKBhjblIf2M+Xk5dRmoqyqEyBuTZYk6IRNDXkXE8GPv6jvKcqMPVPg9mNIy4CombMVe2iRRhRETosVC2ScoclTAPt50gIsYpk0w4pIW4xguf5OOAefi2NL9EFAoYF1/w8VhXUQ4YqM5Z6OQ+7jwwmRcnwvd04sVMLsrOeXAegJLhIpGOEufQi3bJr44vxhc47/MgfWr+wKf6ToIJvWZhHKhEi+ijLmRkPrfXBbdzuEJISK19kVycnKm86BC4619EIoKAsWRC+rXq3sa87BMo5RyHI/QGgFtjGAeuUSsQBjZckKmsUssqtVZRaqWgs/DDFPlh2hKtoYWNGPNLllEA1+9EzdT0FaLZhf0siwR3dl9f7f6dJJkFV/g4BAugo1YEKOF5r53+apAIft/vHh4+6T97/OTw8MnB4bMnqMzSyg4HQBJbddstVRLUAbU3Lk7/JjdUhSEK4vEtCkhGnPle5k81c5xS5mI34N4gLXooYkiHqT8xCmkgYaYJwf/ee/wJdzv9FvhX/n6FSZg6Mxr+GbOoA+QbMgmf6bjCY27reeurjLy04pCaYnrKYryzZWavp5OfdMmR1UP4Ao7pJzO8+hr8t8FnHFXCHQTcUpW2E1+xeDMTzp1h8oDWsxkL8JuyjKP1vHd4eNjrdp8dHj550lWiF+yZvuU3yj3zfc36HBi059ChO6eBmGdkcF4KmomG+XIKvLL1vNfv93r79tp+m9f2RMS8k1u7vaKv+4pO/t//+b/k77+dEdenfCqJJ/BCPKVgXMqIdht4jW+nh6Cdpuiz13l7nV//df4G9Tqb3+ZXTI+j4LdBkhxFILedIgffsihBjr2GbvI1lPxQet0clV1Nf1z5Jje9Th0v/733WsbD9N83vnreZFZKZbbMDbOaOO7qztkkgRDazJjPxxwW1BjwHjvdZ063l3Etnw+Erk41BG8NLyHdZ6sHe7LG1EOrT9cmKboLW51NUbRFcv6myfBnVli/N2F9+9MUzcnut5e4qJF0bbIQLSlgL5G8KC9e2xxGVjy34rnNCNVMOFsxH9Siq819ZIVa6xVGb+LqV5hFm3qTG4y9wNzDBcbeW+y9xd5bduPespkXk3Vlo1rF1rD3LcfgB8Bmvu/9GbN4YW0qbDR/V8pdkv4BbebvSHOSomqXlTtQsgX3FZ/MhO/zwCRxNeZhTzCJRCkjGkaEkjBG5LBFi6vvGo3F7yay/iqDzR+2FQdtt1gAkXu/Z4XFcjnu0xoyya62PYpCslRXK4/357E9C4BXVBIc0SsjjmXw3sqSN5Qlyzb2gWrBt09QE2HNBXYTpLjS+kxZSueSaL9P/5pQqd3hIwHlGtkX5sbRPQp47dZBv3T+QUx9BVAJj8ZK5yRkEE1wfyt+lyLpxgmXSpS7W9kyjIPmyUOcuZ7lyURyRK3blfuuSBNtUd4vqf6qaUyr163ouNmiY2VyiZrsD9l8D7l0D41Sd1TPaun6U3juVvYLsZLb2iS3Itg8XMHNqgEfqBrw4YozmquvHmDLfV8Fvkg01lRJILlm6E972XMMH1Z9i360R+op+Vn3JR+hGfnhVxVaRXptcuTPJvTHysBa81aCLyBJPG3WUq4T5gSCIA9KkymbuFJxyT3mtZNEz2qsgkBzHsC7wAt3xkIuvFLLftmJTJsUlhI0rYOMHASnbPkBIMnVil0j0dA38zjwgAqZNGuaXW7QoGRZb8qR10bMJXPHvwYZPoMI8z//Uzd5lSlKXaLWDNNlO3tHZXBztKMAxh198GlwlEOYb61hLHmQ2EFB1xexcBZyyXQup3ZrFDJmHs9CkVhM14JZinw6BgrqXIqcy15zSNrjwUjcBJccHKAhOB0HI7EMQk34eKIztSuigZdBAKlxScpAVZtkff0vWUjHEAAAHkcyHiajJ6kDbgGDthsPYG0tKDxUUIDdbYgMe0sJK5d9xIVmwkpBRulrBGiTEwZXWTdiXjUauJC2AusA5OWVJP/HC1/E3sgHwSQBBeqjrlIl4MAD+/trHryfSfL6/YuPp+Sy19n/9MMkimby+d7eSLix7Ix4IGayI8Kx+sExfo/qIF/2nP29H8+DF2Y+H5P5SBaRXGNM7PGKuhPQAIkQLmK63rIkImCpDDYFQneVD2SQzJ+IAP/pYb5FtDYmyQqpjwkPWcj0imQRUC0RZiQZUd+XOgnCeQAH0onAfw/9NkHKVYXCp/Rap+2ExJBfWShwwfED/vrXdyJiz//6V2XwZIE3ExxypYB9X5ILfNuF/kT4MP/6p3S7ZiF3eTA+D1RoOwqOdAhroLKMJpjZIWciQTwSol8XjKIzT1x8eH96dnEeCJ2MF3I7gPoGv41cvMUVfI49LnDaKLpewDswZQkkMrnAt4spjyKQWr1MKk8cEy23WJwkI7xORYBnJxTxeEIiAbtBztBfViX+RAfakAZj1JTv92C/yqPL7kHIvezfRM697DcXdY82haFd9q2MW87OyK/9VTma+mVjGFpeCr3s13jSzzEsvMvWsKx/4F13t5mWYjaKKFRVJ+3MH+OZAJyMBLn45dXZBSkicoccR9CXngcho54DDIEkm6KzbaFiUzEL7H3xb3r/n0OfC1AVTDnmT/npPFDYD2PGEtTVQvM2VW7KBV+qkEN15YAMGZExECrzCCZmNyQ9FN71eRBSlUB4QgOTAVmpNpQu/aEx7BcFLkwyTHgmZrGPXBY34QrZpWKjF+cBl+QCeelPRMCSXXHM+82uaxi4SWOWXXLYNIFkQf0OQZ7M8XQkXFiE+t1nfMo+oIZIvT9pgciM/LUJxyY5hn0eLMGxz4PXeKQkDOnx0YjhgJ95oNfMFdMhB+M3kubRu5cd8iv1Y2Y2DHc/oijt4Nmc7/T+pEPUW8il6orbnkt6gcfhPJiFwotdhmb26SxKNlwytc8nKs+6OfeIpsyDRG7xDFfoSqgfZRtpIbjWc1GEKEbngcenLEBg+8yupaZNnQ8pomP8tUPO6FgPhB9kMuZoCjoPLs7oWF6ow9XR2GJS3iUUCC4DdExCYFqBVBMicRDR8RjADsdvE415NIJXmyOgDpp6i/5yHFKvHYiHMHRaRBJTceg5w791Gve/nZ19IAfdrjpwOPU48FjoX6dEiBitViDj06eqOcCgsmIC6Uqu/a3J0LchVc77ot26XKYMmk1jQKxcaeXKO5ErzbFsqCJJV18JAzUuJrU6k7lh5vxN5vSpikvLZaVSGEwWZRhJkkU0XNVIM+bOC2c1pG4kVerPrEJVAyBoXH06y551lQgVzD3E8CkasvPAY16szjvzkN9gRlbmdcjxSFmaqM9H10qRq95L2BeOegDETiP1yJQvmpIUTS79MEU1sUpp4jyoFCfs/X8hTs+drysWsvuBa7N65ulAT8ki+MNE8FpYXQDsPBjvDanneGwYVSJ5dnAejBHHk06VZjDqkZeqQf6E/cIAjikA0TCas27RoMy4JeJIRjTAv3lwKbi5EGLqSTUSnZo49zvxIITFcIAp4PHNZJ5t6JhWtlbJrXKdhJZOcki9ASxVAgQDpY+pw4PaaRJDobcy3TuChKycAY6FtwkIc0RuKLOjaWsRnSdk14CuIdc6j6oFtDKyNn2qqPpF8ryEqFF+wAZkSH30ZgIaVXHYuIgFEt9KYtVLcMu0ahZAb0gj3l03y4dLqiXxp/p5kifH/DvNi+OOPiSqVnmSnKlvSUBbTjGLacI3FxQM0TbABF3goTEm6PaK5ed/q3WAgdX+W9KuAiuMg5wecAPBIe+gXu2anv/ADyBapnUVdZ1J5iUlIlvtuhqJlT7yLBwsM413yQx4xKYyLedY+/p+pY8+pMqI52oVVr1da3uLezwEowOMk5nFch79NUftjjBZf9NAf9MgLV3bWJKqmPdDROkEB3YErTspPt7IhxrgehYKSBamDpPPIrYYsXUXR7Uv/pwD7ZfYJNmnD0mT/MFVzfKQrYfbQMiex5CSKILyL0/ho4qGF/R7kORrjkUz8l2SXkFwuWN6NWSqj3BtrIMmuu/tZtKSob2stFRGeMAKFlFdeqPSGtky0isk+Ns82isLzSoQz8ukSNCt6j40z15C9bFoopbaN55Zr0UB2wQoTFpTcGRojhM6P6D5We1WSXpTs8ivdIOyZKZ5/oxDQZlwKMekdaWzkI1YCJ44UFpoc5n3elLE1AfpGjjQBFKS2CYtyaaa/pf+BYpc4Vab1Ryo1awfhAXOx9OWolkReDS8HiwxhaRTfhLfmzoTlB2jzcPb2llasF0JXdtbI2ppLFSLWOnXWoWkqpZ8rdD1ApsslLtUM0nottx1bj+jVjll62UZLJvdtnwfNg+OFszTAtIDByQFKQhF8RJIVJDpypCowOiqkKhMrrNYtFYsKt+JzcOiBfO0WPTAsahBctq8xnhvRq+hLKAep1WZRbYIY1qQMt25Ok0lctQH1YIcYwsEpOai1WkU8hnEzagxeDoG9Tztyo7fDH/TpJ36GBN6o6f+SBbREXwvVSQSJa7PscI9c0Om3jAKkUS84qipFWdj4LShKFXYittFL71qA7VnKwhUFbN9iBi2JHZtHOyUg0EDFJJQIduZCZ+7WuFSqj/PN8N0hPN+4KfQiHwwY1UFHbJLDGjDxjjidQEnlM/2hKookyFjAVHqfS/raagL+ADIQHB2xombSBFGKtDoAtbnAr2qA3LBvQt0jQ7REzoQxuBfjiQN3JEBh/NLs3zKjdN0IaDWzl15I5dMXW3GADZ3zotJzbxs0OQLq4blwSX1uZf3FTcZ11YaMQ5ompqN6eH2Vx5uZFKotdJcZisNFIhogMnOWmnxgRWXTNUoGGAuPTXa6t9Hc3nsYPUSnfq64LRA+pXJ0IYsog0U+QVUWmSfh+cyKrylUjNVwDJ9eywRnDIfNe8blYpIWSTrEIzONUAGkY8TeslUCCsEX+rqNTorxWDoC/fzhYFB9PvBoMqoQ46IUiZjN5PA7OKg+6yAYSppsAjIRSCiJEr6IkGU20O2NVSWQlj0YozeHigLAJJR8h0IasnGKE0zxim+VJ3Ie9VJ74LKnSzJX3qdbrfVbmEIK85B10dq5QZvJ9WE9Kz1qSoOTn0WwjHLdjZUUWp2QA4P+wir9bz4heBQNQmZnAjfG0DqXYkpV4EYi2uROSb5pfgZfppbBRWESCPyl8Nu1Qpkh2y6ABMaesSlsxU+7LCrvqzRrpp6JGvdTTOomv+qe3ilRqnZuwV7Zaaxrj0y41XtTc2E1Z40rp9WLy/wANRupYqckqSqEJmWk/0gWFZhMAo4E0Y9prLyvjqj46qp6WZVU8OuMKE7kJduQVRKtGM7ICfp9P6rfWBKJljS2+duZGWvu5K9EsmpTPpa9uq5983Aife9VeNFWZDedLMSZ8la6e1UjCLdV6nt80IcgJSGJy7Tmyb4ZoDEJYIx5M6YzRgNMVMESKFtAhVjQTEWezzVlkg12sXxyHkLPicXREEXmUKdWQbhxCrmF1/3KCllQS4uVfD0xa0IcM3CbWtA/yZj8NEAE4k0vCGXsgytEbijO7F6m70V3xzte/2VB9IEkUP6g/7T1bdAH8NBcnexrOOOWEcC2+UX9yY6SGhTdNWtxXyjf4T79DzcX4DIeJEquTVKg9Sc9+5NcPknImEQHkGN6Qy+Qw4xApmrtGVElRvHD95YKF8dh6tVlVaS3z14t+h5F+ipoK9C51nmAlOATm2kLvF0WQCgMx9qUSAcXk2EX8TRV2jZwTRrRJceBbbaBoAUgb7l/wTdIUdfyJQJJow49TVUKv/niw9HZy/+dqEUnEmeMcjBc1NRmrwPDGK105/JGFKaxTOwGGG6RMhXMWEkYFcqCZ76mjSrnGIWG4vm6xLM78ZJaCXNUlP2pI6V5UdWs7QezZK9v1gOnLp5rV/1tYfao2X8MBzVo84b45ocoU7qVQDiebVnRo55MuB8Kt2TjpNuA0PEJGM8lGChhORzMlJJZY2JwXFDISVGNgVReE1+uEAD5UBXNb34UfFSyF6sUvAZtNbUgcw3cRPDRHhtyKhMTTt9pwLTqk6CTJFRq9claV0hmexEJb0LTJKbDnlpVHmJv4WMuO+bVKjRhPHQfO5PRseUNtbNLg66B5WeJM9VOQD86gtI3QcZrCfiikxhTkxtASS6ZWRI3c8d8jKT5u9CffF/aMkl8UB1r10f/Fgg+a1/aTLO4n4pk88jTLMrAu5Sn9DxOGRjEKfaKEBB1BNEJalcgbJDXug9kjqhr/ruZFcSl2iVh3AIgCrb4LgTED5K28Elt0NOWZTMm/r+BfrumSwSFI8DwflLk1kY00yA+hTqfLGRCBl5c/z2+KxD3olEaMMuieE7n0vxJ5JBE7xem301vaTwYzy7ieX8sLt/odL3usJj5KLX7e1fwJG+ZGE6vBYOH55ohygxwFN5g1FMIg213U0zLyL4mJN//w5OailuQbgyq7NLQtbmyBtm9bdO0OgYDr6Kl9PSwgb4GFxqp9UmMkbSfoGEkTarqjWRLSyfZJICPsan01gVn9Y8PmSXHEMD6uqoFblzx8g3mJiXAttH3rJHR5ls9iBeXLIQvLc9Qt0IDHZRFPIhsosOgZRQUmVMZ9JlKpOlmQ85fqlZKvBCtPaBizL4X0GW4J9IyEYgB+m6FKGMMI8TfoWRUbgyCaqi9VKERsuBFR/ckIEDL/XhG2Q8hfIRE+Z+xopGy4gKzwlTZSLUxB9JEvEpkxGdzpS6ZMhMTQBIPpeRIjT7zZWlU1z1B1x7yS91KuI2YV/MDyzwftTOb5mxsBvKe1ps4YHH4NSwIPL15peLLek2j7LsPdGkZ7d9LQJIxhV4TgqR82IIbOvapJAOeYFHQZIZD9LFUqMo6ct8xwyPJ1bY0LuIJUeSUiyqyomS2yQzYRLJ+GIIhAEinvrqCM6hrgUB6hIeRKqoQzq+PtKKO2+OTHQ78kyaQ00RZzGHWh7a3s/onzGkJf/MgqxEzlymYUOxrEdSJ5TDMoYdNTRAjZRgPooDdVOBJLlphTHhg2rTIEZNfXWs2/6GBeNoAq5o/YOGMSkGse+qXEGNQKZnUiGTFfNeo7Cl/F7bGbrVeIoVWzQF/ICChSK1Xrf7uE163V4PW/S6vf6Pt/19jQuPW/nQyoc18mEqW92OiBgHM8o9RyfsrpQMy/IQ57vO5yP+iM/Jcfq8JHuWGsQkDK9JNb41AX8ln37L4X5qDQdmI5ZNHV412Ycb7bepSYKLFNWEfmtr4uraDQH1ryPuyrnqLkDK5ZVxTRyL0ceaVnM3PCWy5JqR5IVFGk6CfuFK4kiGd7a09qDvpzU69F0iqdWRXgtOo5DRaZu8ZR6n5IfjKQjGP7bJCSiH34BswINxm7wR1CM/o/oX/30UjkXbuOInf5D//rVNcAiII+RfsSkI2acz5kZhPF2lXEph2ZcUe4u9kzIRy3eVPHDZKh3jIMIUP0t3hI0Fn0l0SVi6d2OhvthRXWRkQ7Xkx8IpNT0aCIXZ6CUtOecjPk4TcbpAFFq0pn427APFG6kQbMokNNT/UtcGBX3hWBy5LvMZ1h7++TpiOpKj2+22WxxOrzm8pvxb63nvEJ/6gnoJFUABUQz27amuUyChjwH/M2ZnIQ1kwnxl6/mB6g+vNERlBj+Cio/AVw/VMFLTCs5MDYRp11rPn5pJSiTatzyIIyZ/5Qy79/rqHTjdx8/2D/uPD+DfOn7lv3+FjIWy9XxfjaF/Tj+xj4PDnidbgYjcPL6leI6MKqW8nFoTgXZuRLq86X2eGkHcFyH/uoSsP0ciqZC/Jt6qyOjIvGFhJH2af7JMQPagoKm6zqyn4E4t+xRRwKLBiDFvj8pg7xuVAT7wKNxFwemokqmqvg7YPWnkwBDIVz167eieRWbqUY53a/2wRAwG1gcaBOSFmEwIX0KgythnVHnSiA4peKdSzVXJmINV7uj0HQnZmEtVwDUSoBYKE/4NTVVDD012qpQZ2lG5VE/aoIm4ythCdQr8RAM7A12iiCVWj70zMVytMi5vTc5/tW+38kYqg9yrtN2/IrP+MiMnCtll7hT6RMAg+igpBSm9XkZAr0+5adjRcp+TMK7vWSa2+hgZvppfht8mTBdJZuTowzFYt/2CDitTsmAohM9okM3SaQR7zDQE//j0PeW0ixbH5V5YpoNLc4D2Ovh/e/tY9RvPS0l7xWT1gXLgLOQG6Xd7B06353R7Z93D5/3u82630+vvHxz+CwYVoxGDqx3SWmb0tEpEMlJPhXp+z9LD78nits1mZ/bs04KbYvURvL1LY5Eo76gGnfrSM8R48poxr5K7vXwpToluDw2TtMtzD+r535KJj9N16QBQ1UVcpIxpFY4IiuEVWSJ0reKJ8Gw1lqj2BA/hTdnjznGzxtwGt2ee3i2rsazmTlhNxfmzfGZz+UwW7RsyGuUZIoHhLMNblPMrzibPVOABFNM6On1XYW+gSRsgaGiXZQ+KcyCHMJefudU9+nC8GWyjMZZnV2UlU4RF8pWRXJ/sGujc398/XC92lu63Bcy7B0wNb4uAcwldVQYwEwm9VZMzowQ8ddGxInzq3BkUReaK+mL6qXJ4KRHHs4I3gOhm4OSmidd6LdXNxILxAwbjkp22MJxNqHsvcGsKxtUgbkjBCScUkfKi3MMsgNU5cscs0n4GUv/vsfczjPEhGeJIjZBFXOA6KIWq0SFOWsbDKY/Ax9UTU8qDqoCtRd06rQIQlfrTQa14bZpanztcYenwUL5STlzaiLY/P5PXxjZ1l/MoqTl5wqSIQ5ehWzY6st3hhPrPSiYEhhqV55N9cRnz1umZuWhGzRz4ykZ5+er10cc3Z4NXJyfvT4Ah9BU8rjDU6ccXL16dnq7NaIkvGaQvqcQtyH3uJzKj+tfyFkw+DkSY8K1KFCt8eYcauFiYCWIkwjFzJsqyaxyS1iZ0zfkb8yDxN0Zxp6KaHv68AibqZBQ10AaZGo5fVuKiESSIZtBEhYCkhQoWjWyh00Knhc71QedmoCVLwuzm4XJpOXDP9RlF/fw24ewLnHQJ2KqYOEUHEN4VxVCNVIyUdY155OPJG4w7o1cU3cBuCMErvs8CswVmC8wWmOuAOWSjWKlBtwmZT9SsbwLNHpezUIDe9Y6wufBCC84WnC04W3CuA2fEluttA+df1axvAs6olw6nqi7ZXYBz4YUWnC04W3C24FwKzviDrPMhUL8vQsuf1TglLgXqDathH74bVQCZQSyeWTyzeLZdeDY08NCkMESpTWtVy3sJMCWW92RWlUZ21cIijkUcizhbbE9fDD+bYk8vLVwLv66Ac7qaLeQfrEe6tIVFOot0FukemmyVqde4jtvi3oxGkJ9tbdfGD2a8kuujeRd6l6/lLlk5ogU/C34W/B4a+N3uxbIUuvCCuTRwlXagkOQX809bdLLoZNHJXkI3/xJaiomZy+jaRDqUa0Gkqx3VAqcFTgucD02sW9uddsu8uZf3404jXe7Kk3vRGy0iW0S2iLxdiOxq3LlthxQVjedAJYDWDQKuX+IwxzDK3M18yaDCkub2Vm6hzELZg7iVZ/Fm06/mS8CoL8bCwRqv7EaJK96IsXirh5kDUj0+3rjhheRPlWC+Hk+re+VhtXxVoUdmSeczMes1xHKx0CpiUzm/tnDI2ZeZL7zkyMjoGtMiQtbEbEEwMRpJ3P36F6YDp3PFegaNOzZKH/T+v28XlpINryvFZfnZZvGzJqXpy0b5+O7DyXsA/aOf37wavHj/7uzVu7PWw2aRa+JuiEMIZZvJ13IM4IEytj1PXAVQ4WRNHO6lGS7nh6B/vCG3o5K8OP3VMj3L9CzTs0zPMj3L9JZkeje+xlUEQUgKJaezPKkuIGK+tdWAbSN4Plik2yQN2DbAZS1OJrWFt9YjZR74Mo4o82CmcltjSUUy4n41FlZ0V1Zpb26YatE+ouNVpGw8VQN8vkJvyNotJ8JffKMI4ukwLTeA+P2z8DCNQ3E/K4Dii3N1dQUHaOrEoc8CqMnu3RA5sGLra54UNy7cIHrz4KZ2/ZYBDQ6bvUFsDxO0N4hNv0FsBBdcm6sRvmnvm9bm1FZuaBY+g9wN/uvYK4udKWFQNwudqRpw7g7QLyP2d4K8UIe+07IQuR0QafHs4eHZbUXEVKGRcrpZEovK2lu3GwsmGwkmVumwRnjaBOVsu8r0dodK3zV47zTy3FFTXd53p9iviSGzgQ2zRF3R0BhpKjotb40s68kD1489NlAOYk2sr6ZeVekoXE65lGyZUTbCNPoPmKe1jW4Zp7WajTu/CWickIyGm8p6H6BldJ2eQEt7Aa3COTN+QJaBWgZqGahloJaBWgZ6bwzU+Pzc2Bbxj8R5qMIOsQy3bGiJKBty3bxzRQO9dLFy8eqsyhpQLCPZMUYCQ+2vqkY9+vXVy8E/Pr46+efg5as3r85eDT6+O/r16PgNLOA9Mqm74Eup4+adG33KYF8ZfJaA+/qbkDX0bBvoPWCE2hxDzxbIyw1waSPk5Zul5CmDQJ2UZwnJ19S+1n1QZnwkSUTHbQLCJJEsAtG3TRLV0cAolX7Qyc9+7JDfJiwoPuaSQLU+7jGvTaIJU4OTdHUJDTwyoXJCaMhUgh/mdchRRHxGZUREwLDQlJlL2Ry4JGb9O61VnUXn6V7vnBj+wVw4KbMQdijSVxbuzSPNWfKBxy8h95D6HPKDmQK5giVKshhFdIxf49LgR5h4UaPVVqL83Gt+m7BowkJ4A26PXofMEIl0327l12p+MLX5SdJQNRgU8pJRSHkQSb2x6TaGbOZTl0ncT/aFS3Utyr0nM5e5yMD8Ok7plwEkcAE1W0QDl81P8S39wqfxlLxhlyyQk4jxgEAXYrqgTnMUf/16rabPg3FmAsaRGEkNvrF848wCREKvAR1DypUoM1ImmDE9Vb8nw35qF84MNIRL3Nz7UDMH+98hJ+ZsUEm4x4KIjzgLCyelcnGTGZV4I1t5xcorVl7Z6qtTXWarm8SmlMkNc9EpednhRhlSywbcYm3ZeuSL1ew55XEnVmX3ILiBVdltge1nQ3jD2mJD9Lv2viH8YRvj2/AtsaB/39Nm8Nbd5atNQdrMbNmBzVUKR4Y7ROt5NzvunIPAzQa+Ubyo5skI8sde4hGCySS9l3rxcyYu9Ruh+r4ClyA6z2qv5zj337jHTK8kt6QKHIUrncdGNPYjcsnZFdy9i3qBkMnYh3uhngD14QYuXTFjHtyeYAyX+j5MQJ8Jq0vdRm60aaxjDReKdutg5UHmTUbrGmrXWZmXoNsd8bI4sNzsHrnZx8Ar4WfJr8tztBMmIxECU5uF7JKLWPrXJPHbK3I6zaOyfM4yM8vMLDOzzGwNzCwO1s/OhrH/+Q5Z1TqQ/2eY8hL6RcIDMlR91qtnNAOv0zS4muoOl8Sq7x4uj7HqO8sm7lx9FzKXBZGDtUKk5CK4UdzuCY52mhlszr1OvRAKLBGZa1eK2+WtrQy9jfj2YMFok4zV+JKNL15Sgjqb7mq3FKaOYhWPsh1+gCdqvjerzedxCU5eLLi74nyFV1quYLmC5QrbVZ0vNNBz2+X5wFHHgZw426IIOXUpJiar0oKsnP23cd5fi6UWSy2WbkPmxBTc7kJlgG+b0fFdS7g3gtIPMN/GUAoS5moYCj0teFrwtOC5VeA5U/BwB+CpVM3bgpxqtlWGuEYu/vMtLT5afLT4uEUGKWlg4A7wMVEJq9LWNzBGpWaoY1Uku2CJKhiV6vWWc41tqgcLZxbOHoQ1qog5D8gUpYwmWyNuqtlWiJsNXQZKmpaUebmvUlsfT97or7RJNS2vuG9e8dDNS9IAyu0LrpGIqO9kslKuKraewUCV2ckgogBfRVRiErSMLxFw37S/FWotUG0QUG2SULsF+cvyYPSA5NkopO5n5jlqD26Gs2qol3qk+TyQib+RfhkoCEyypqp8kPN9jJ5A97S4anHV4uoWKwuKCPSAwDUO/RsrXT+Gfrm2teC+WZ9Wt9C2Rtd6L6UxPp68wY+0V3iL4PeN4DsFvglCPSDURYf36ztW0d4gWuBXNd+bRQu4IhjxcMq8u4sWKLzSCuIWxjcIxrdeEL8L+L800LP2aAFxJVnosC8RC8BitIdgoVMvlxcXMiM5c50d1dlJKlfM1RXSXUjSRYHTOFbjz6Gh6qZSZi/oq7LeBEm2mfMAslPLCQ0hkc1sBqCJadWZZCGofSGDOpCymq3XOQ8aidg/L5iGGW59lMi+DNQ6nOjJ5cXvRXTDvgx+pt6JwnKVE6HXsN/HgMbRRIT8K/NaKT436JmAdiuF0wbd3onoNSBrqznCsC8DoMYwoP4pbGyoUapxaRr2ZQAducs+BpqCfbYIUjKgYQ7Eq+RAvFA0VAkMYxawkPr+tZO+b2mEKNBeRxPu4oIyVaVjFtO1EjBTov6FRUtTtJJvVqTotRCoGWG9FKr2fI5CLaXdK6UNWUTvgrTM1UtGhXfP37zKFiltolYpuYG0qt1KFpMr9itxKVmWZFW3m5DsXWQPAhrEiRpK1PyuLG/QCqjhrt1Hpho0toatP2vYDb7T525kwWYdYJPx3CjFm3g1tIijMtXG8vw9U+VmJZE932Qay4hQP2TUu1ZVczqkVLDn02kcwR7fMeiodbod0DF1nSzoWAnnnkFHHcUK0FlewbDHg0sWRKLWZ6wGtDLdHZ8X5Jw3XJZdTLKvrLuWQPUq6vvMK+l7jZjFqDshIRtzGTGoQaXfdR6kHTwGpwCSKMKQBuHIK+ipn4VsJsJIEg7/MeOfBzMWcuFxyJ57/ROJJlwSFngzwYOIhJlp+iCUReRzIK4CIgM6kxMRkRnWXIbxO+fBeXCiks5jlbgZHfMAA3aH18SNQynCDvlApRruQv1yoaJ504zA54E54KBLHjFIMAzt4VthSNYhFzMWDuDPC8CvKBS+xCdE8q/sPPjBZAw+7LbJlH4h/W73R4XS5Yp/NZNidZmCpXNG/4yZ/ozinMmiKTcscmO+q34q7xJ/Qp3iHzcBF6D808venuaS1l1azw+7bSjzphJL97vdTJrpXln96UYMJkMEt3QTPk7fcN/X4e2F/cwi3rEeKY+SlfwAQffmt9ubcY69bwqEFc+AbjflJWUqLkokD8Z+mTibwPYNGUryiiZMZXVFWPrS2yX96/sm/F2TEjceLoCubowWKWMukH3BP2ARGWR7JwbxW/B3qAAwX4zlXgo/UJ0VCKkqP8LdKQyLc3LkfBYElRihBAqxC+SHmReuVR+oo1zTq6gMwFu+vsXDj2wWyfNA/P/svYt32za2L/yv4PjetZz0k+RHns105h7HSdq0SZobO+3MmeZaEAlJqCmCQ5B+NCv/+7f2BsAnSJG2bMs21pmTJiIAgnjs52/vHQbnRKYRSM6QeYazwFfFkKc8gPX4G4npKTn4v+/AJgDuPdU19+9dk1kgu5uvcSnVElzePpCtF1F7c0WEvGH2t9RksNO1W3miK2AHnTKbr4KfWAe4JWaHEVz/UZX4tHGTQlqGlRgj7BQ54QvACmgLxfpQ5cK8ipRZFcduIrGlTnZRtamrmiDBvVTGAxiMTFLvGKTjUMXmacrK/D/CMTZ9eT7W9HlE9hT9xoaSLpih1lC9u0rSdOH0ccykCFKY45hwIP0K1jYgMQ1nTBI5Bx4Qk2ROQ7KzTXx6LkkqGRnvkLlIYznWU1T8QfcS06ytiP8IF1D+SHeCH8cj8noRJed515gR/WYoOq70e3HCYrKzvb29TWQgEqntMuTx9vbNspnDbJdXxWryc3M9rKb4BY7dOHazDuymRDsvxnJiFvoMNAhox6TkaoTDmKlkklbeMIkBegjPgJVUetWsFMUWJIkZGnxZq2ECGmxKS9cR+Qw0EYySMZMAOP41DM7HYE5FCVzTO8kWNEyUqZosGA15OJumAQmFz+TfFF2NhUiwIxaHU2HYMLlEEEr2Dw6GkgXMS0Q8pKE3F2D5kOlETWJfWZOVLTUQ1Adf3ylP5mQ8E4n4Fb9JjpG+j08pT96I+LsxEer35krpjcjy8lJp/r1URWzr1Wxc9qg3Z4eH79qNy/vQihwevsvq7nFJnsgROWAJrOG2zgePns+N5ln1HUfPW8XKl6zSBaP086ePS2bpUllFffTbP++TuRdkAtFloZ9NaHzMEybTeIqHB47SL/oH8gBu3cO2r73ksFWdn4Xwdf/eMH03vqygoj07o4soUCxZ/x051QkNUiQKaRxsvNiYJ0kkX2xtnZ6ejnSzkScWWxvIFWt2CjH5k3lgw4xiICaJll6pivzlCyYUPKC8XqBr610lvvE+0yAQp6Bki7jkzVdjqcgCmE5ighMMSSFzKvG6Mp88kKk3BzEvocewH9KLGQvBVSUHIGzEMFo4I3qxBkTERBmq8OePr97IhyPydqocYSh4Ksg7uMU06n2gfWw6FkJEWuLTlI5iN5EmhAGjsp3u7ETv7IJU922wQX3/ABfokM4sd9wHqwNRPxEWsAXISjzUlS9xEZBOqYKZEo4F5uYRsfnSwjRoHFO4GjxhC7Vbvs/hTTT4WNjFKQ0kq25s4ZBVSM1gg/vWn9UPlgd44OoWr6mIFzQBH3DMkdeVj9o3vVrJecDaFmv8Q8DDYxKz4O9/bEhoLeeMJX9s/GNMEjrruHowDnYmMIu//7GRsLNky5MyGyfr2WGhu6/lJdYGrpGW8z7qKPp64CZwVWxpFCng0DTRFV1xWWJxwuFKxWzGzkxYPdyi2Yhsbv2/0Xd//DF64En5cBM0FXg/idOAKR0GKRBazGLZuiQ1hmU+QEW/HJ5HarEuM38dSAOvMvPHFPybsMObatxLfQQNz3+dIsc3pNsXXgqXFGTM6ubmrfJj2d4OZ9veZMF8TtubTMXS+eBStLeBC4Cx2e3NzubxktkwnZy4uUkUsw6tlECNW9ze8JRNpAA1e8lK0pBPQUlqXyo+C5nPzrw5KPpLvgN+aG3hyeiEiwAZocJpLF+ZgM/mS5qJZM5s2/AF71mazBmK0yrspnzDPqrrA0BUH1rRQJnMfzo8/EgKXUHR2ajSoSrXiKiUpyK28IeygwPVHdCTEn7CsljSVILyt7AwkVrx7oJQ9O+83yCfADhQJkwme0nCFpFFNNEPQNyIYgEMn5yCfWiTgsDP/E1lqJBkSnkA9EMz+8IiTIQIGEXl3BPimNsI2P6cecfk31p1+PLAiF1RlMQjn51s0YhvRWkUsYSxeIQoEskSNd7D7jxGZU+wshh2FvGYFYmwlk++DVAKBBpbeFj4KrMZlU/CuRF4aNFEUDdKUMz4hZ1bJ4RKkfVBzIVS822k9p04bb8F75nP00V7m5/4zEZm4LiAAfEjjZOGxYDHB1xdofrkDpIYgMit735Hz9obfBChjcJ8MRYQ1jAzpIkfgZjY9lg9PgCJvmHyn0O5jFh+gNzlOIXWZo1tvjTJOt8GuWZSlxGK11xfcdX6S5UUQWu2SAG9BueAHjZJowUN/9LXFcbSbR/aqGOm3X79ViWVwPJiFluniM9iFn8UAffsdyjJVa5GlfoR6BwFJeSp1kGAwH0OEx6o79etgYRoSVXpWBsDy1GBR+1HoDZMa+uQJaciPuZ+wLY7t9y1t2wR09Z22l++VSg88GwkzIugfjzR2JCrIOB1MJoNyLsvyPiH+c4/fmJBIMjvIg78//qvH7bmO/8A9wMHGYGMYeAx8LNxGgdjhYOfMCJZYrVQKMvAxouN6sA4bpUxDzYqpj07wYpRAF+mu7wMhHdM0tBoaqtQYHopKGaarRrKBWbZTU1xaohTQ+6SGgIGeysrkyx5DQY70Dh+YtRHo3rd8Gg3XtnurWTJz/SEKjvb6xBMz76dEGmJpHyjwSKUCBLSEz6DUKVEqEs6NsJAwVw6thHNkvGmSEMtA2xtaMVnb2Y1ERXY+cZ78RcPArr1ZLRNHvzOQ1+cSvLhkOxsj7b/Rn7n4dPHfyNnTx8/JHtRFLDf2eQXnmw9efRs9OgpefDLT4fv3w1IwI8Z+ZF5x+Ih2Z/HYsG2dp7sjrbh/8gBndKY6y4omnF2GmnBciWKjRlwibi0MWd43F7sbD/fHmycch8ZzPe72zVBSoFXDzwasDcUHD52RYfKQ5F6c/s5MG+zdOTyHQ196dGoQfrm8r2Y8KDhqZ55beCKbKuaZRP5oqW0NyI+0G6s+g78TnmSGdGNtwv9X1HEaAwxIiqO4iJbBW+fitgMa92u8j6Y1CC1Vcj8HKDmK10m/6Q+gm3dmn7CJZ9Yl77y0spyZzMoLHSjEwPWWRo4dcQ8PgVbobH9T9gUsB4gkfEw5eGsix/gWxM507b4nMGHimhWlloLh+36Eraq60m1fbMP1qSuVW0vsfUdDRO/zJArnXbD2nzpCmsperszhBJRhB+irtTftM2sM6il/YKhl6nI8pa6HXyL9QZBFQSe1Q/qt8GGTgvW1E8/tnqgSwtsxhmoaVjV9QWAHJZ+9pSHNPjcyKhBytaZd9RmqK0baN8hDQFV4POYeUk5eHgqlB/SasOa53JIxSER8xnPk30Q3XBAYKzYg8Sa4GCIVAVL/RSdDH8KHoKREdxIFIpqBDwE4pzZXRXkLaahBAY5RECEGQA/0xeIPJZpfMJP4FONM7oIJrPQ6e6Sk1mp/bk2JpY/Hm3C+WqaFQSeE2Ps4ths1nhAROADxFr5VMivOnkckFHV3whY6BIO1RMv4CxMhhIM0vl7jKsXzguJ2TRmcj4ieyFhCKnDa4AwEVnoJDwvjTHeJUWdmQNDTFiMikuSHxQJOMRApWyawM/U7251bTwmn/Q8LAeFh16QIuJkHAhFCsaX2zWVpq9hu9RDYykw62O9+83SMJw+5fbOrlltnBZqnk0xv1hWgtDlQ7JpAF50zojAC2n9noQngc3jAX5gfGabvSL/Wgptp0xWyNWS7HeQXY7FnAaABtz75wcgjoONMA1U3IyGeNSXprik9feiVKUSO9rOoj6CagVtDoyqeKSHypZC0+ovLfl5i2EVwPAwWbtiWQTvvB9uJkQtYHBOWAh8oehLd1yy4VKsfl/NPu7u2kZVewhuL0i7nyKkTvKEDWMWIFfjUqYsJ8taEpYDcnDwTm854m14aE5q4Hb6hnfalufTutNxlv0TdBmMlvrEkvh8uIfylKLfhIc++pOlcpqiTRp5N8DngZ3G0KcoHo82SlJVYcz6zPLId8k8EfqYbhbUNKNt4ejAQisv6IqlvPALqopdZtt5uo0L3Q2bVzy9/zYHc3d7e6dw3mxpWDHeIzslqCv2wOq5+9L5vjyxcTgDTlfqRpyj/hw9u979WV1W3og3puI1wQQ55LeQltebfmSxKYb4KZtnwcAuFiMvEKk/DWjMRjTiIxOAiq8dxczukFSDBzTcK0UqfN2YpJKHuJqKtDE4jVHMZSY0TlECVX+PYpHBai4Qtd0Y9BCn4eg/KfeOhwoW2xbeUBJTh4C87xfRULhWS+MY9nXbavQC2LyLokclBTh4ezACCd7J/FJzlfwlc9tpnCi0MBbVbOFMZIAyrrfGEKi86eXoAzJhcwoJZmIXWuBCC1xogQstcKEFFadQE5jLhRa40AKLpOpCCxymx2F6XGiBCy1woQUutMCFFrjQAhda0K2lCy1Y29ACFzXgogachnHPNAwXHOCCA1xwgAsOcMEBLjjgNgYH6FR4Dv3mogFcNICLBnDRALc4GqA6jTK0qEY1rgSQ73D4dw3N6HD492mnHQ7f4fDdfXE4/LuwPw6Hfytw+OZa9APfx/QU5f/l0HtsWQTe4y8EHBkAPq7D7g8SCvVpKcGXkD/FJLNUluD2oAeCdc2b88CPWehw93cKd39pOHr+AblJtAcO2QHMHcDcAcwdwNwBzB38w8E/1hP+4QDmVw8wN1GPy0MStdjDpZLcGyIUlRKBLEsqzlONVyRIGk9owPXEx6oPFGQkY1hRK3TGEtOYyYifpeV8gKUgBPJqQI0QPBmwExaoeYLDXqEex6lkY6KjiIcHfAb2BeXUAOca+PjERCRylJwlI/IOhpDkQcCoxAVYCJmQSKuiJ+zhC7KpQLihxzYHZHOaBsHmiOwhx+YSpWctSWZ2uyidBFzOWbwpic880Fd9PS81ZS6VW1FVpsRt4Iqbk3eMxiGBopMviAFw6G+W+C1yJOLZ1oi8UrL5CzOlEoQIfrIic7NvWUItob8dh+qCGFwQgwtiuOkgBqTaH9M4EtJ2F99xibhvZZaJdLsiqWwikLJKIfc0dcPJyBdkU9XgBVpI+ZCHUZrovycx5eHmRUjYv5cN+qWfOKyrP7fun3nP0lY4g4Z9zijuv/OK09nAg1LvBT17q2b8COUI/Y8dHCVSZKK8ie+1ySLMXCuB4lY+Y5HSAWF7WUxOeRAAwuSExZKpbBcIFgTrHDD9z5/etZp3sFBxMQgk+8EYeXa6Bs7oxKn1r3mjM6riGQTTRbb/KCpgxEG/Xa6Au6yydXzsi1Pb7hVaoRFq6f6qt7nQIBcatFbTbgoNgkPdeEr1A1QCfj749UNmqrRrV30MdqlMxOKI8qaX0oAEhjlhW7L3liyED3RN50QxFlnjJEaPuW6ClG4CBYLBUsJDDRVCLUVbYAbK2xASAO0Rqnrm5tJQ2UmVVTVkZwkRIcvGTSXzwZ47pUEAqlJ3sdRUBqfqc2uKXvExQc9Y9qFmBV6Q8UtGYxaTH7ABRGR9EAkJ0Q6MzeEosFgOKdcrYpVL8ZFlDvo9jQv9Xsd5ARFX6zD+QS9r/I+tH7DzEQgn/xgPCBtBsEQ+oa3/9qZbAGraCgK6oMNHo0fDZ9uTIQ9lEqdeMpxGz4dTKhOLRljzheIHWCWfKBZak7aQPeUEPTJ2y2X+YbgkR03OExQjaWGRtIdVDT4i7wHVUMgPTuasKPH4wKvhZbLotoRQkMKSwQSG8LFbna+d8qeU08w2m70r64pPFYFAP0MXoePzp3d4NZWhoF2MWCZCLOjZns1Vbt4KtnExJbRgRQUzq0dDheHUEEGUcNCVBvdcA05K8sQO8el562SNGytnbo+fV/xaeJEwDOCAg8pcx1CG/AwtMjKhi4g8MNAXCc0Ji4Q3f2iAPQh90cXRtViOZhX8wFMWI4lTMQeqe+YSGpE3Ika82IJGajs02DigMlkIsBizAP1EYEiQ6LhCm4OS6oNzNQKa57D/oC49Aj14Ox2+13MY4hcbbBJaNtA2igimbArgdVKzVqa50nV4EIpsgrBLev5AnENB3lGZZG8z75FphEFDGTlWU/SRDLIX5BA+EK4PaimeCP9MQ+UXwwVRp4sMyUQkczLlAbiAVfAqWOR0bAeem6KdXhjCnxNAGE4zF/gEcg6BNmrmieE60zRJ46JdAEw4M41h8oIUzEfvzWFSt7Z0tkQTd97L7n3mFTdESG/ZkqAqhURmr88UuuYdD49zfq0fHqQTZUgpwJ4q4JkzbKidOpZ5vlYNCDi+pHKFGHxX5g055YHv0djPHDpm9TLAwIi8VhCuF2TTFjgXxfyEeudb333XGhK7oGfGMvtEX+OCnbfOITNtbAdFWvuS1a2Q6ouZbqY/vf5JbwEGh/ZE3HhSW3S4pnwWiriE7M+jmrLdNHujR2jeDTM3JDCX3RIzWNYE/FMMTAAIV9WQPn1CslaaMhQ8YxCloRHqeUgVrw5ubrt+4Pc+I5NAzK7ngBSvTdMOqMUHiG9hu2tfhLRM3e/CYSB8SmxnEZrAUepyWL65CHsXYe9crPfPxapcb/UL9PucoeiXe/QyIIqIlVyHuFHuZagSchinDEJxNG1ppzsGP1kJ/72xeH99duoqnSILYEk1NFq7Pze1eCo3ybAooyNDQ3XDNBiQTexsayi9mEZGP0HxHozYQQBtVTOUTIuisOmiJvRAL+nDsjuPNnjzzJzazwwOvcTM3ejuu4bUCS7/gMs/4PIPXFH+gU5B/P0RmQ6ksd4gDecedu7ha3YP333Pr/OpOZ+a86k5n5rzqTmfmvOpOZ+a86k5n5rzqd0jn9r1mte1loIT+OKs2rfNqm3Nl6bP0IpSUr59lRtmQZkH01t2G1walcY0Kk2J4PazLBbWPA5XW5ndpYK7Qwl1XIIwlyDM3Zc+98UlCFvn/XEJwm40QZinM3M1ZwaLITH1BRKDbX39U0yggToykO9ooyFHmHp6tE9DjwWWXGH4ezEXWD1fmGqDHgMRzgSmRspkrsk5KPho1ANPuM4LDNoM9gKGibpFIqIIs2MHAflPylKVPkeueeYvtcytEzhUIr1W7vOFyZagz7w6DVad7pcuGkguJecbo4kFuKTPHX3uonks8aKo07JsV7P117etbnJp+jZ1ExU+ERSFKTc25gt8r57tlxvUkH4WE7Dn0ACo/DnYhjBlvaEiQDg8Gupk8Nm6uaN6I6rR9uM2qgKbNBVp6HbHCeJuf65cEHeCdZtgrUViyPvAGrPnzphOnvtJMaqiWPwjS7T0pbhYXSguWnRVG+WvL8nRt1uyrRpWu06h3SBby8d2x9Ps5t+XlV1p+bo36KsHrQocGzm1afqKpvbVNTdkQale8ANQT/ybyZgLf88xt/DOYx5FqokRvYCcFTYsjaWIl2wXtkGPR0RnPMyyATbuS1OHxg0oLbJC87RO6R3aCrvPqKl984nY7qiUdSIijln31cp6wDQ1WzlQ1u3PktnUN5GgDKUhTZHKq5zlnpaCTKklhTNYudUF6X3GC5mZeAh498ZZVdFpgDiY0xNGJoyFBjXUNkWbvrrUoxYzT8T+Uow6jKCbrii1tL12drEUVMl2ooxM1k8w16eikAIG2IzQZcClEXFlfKLtHGeoZwsYUD3pNaOiGSGhPk1sQsJEwjhw/tI40McmZKAjYOk4MNopDMQlUdCAGTPYtvo0foPwA/M1ZRxcpVLbQLnPMuhOU7mx/OPF7EXpZXUQNgvJjzGN5qTwoLq0kZ1a4fAqGrhtYGzRZ0gAURzZs1oWhoVWmN6yz9AN5dcKw2KLXkNqpG3ziOdR9wG7lJtDB3n7gEsLzh32+kwr5uQNGqkw+3unYdqK8IH5TaSJJ2yb/imTCTDPsJTG0wpXnhRuMZR3jC20tib/FcxzGA90VJL48DuOdGhR5ZGiPUep5UHIEHt6hCLGRh6ml+U2PkrDoo6nIDdHpqZCoWcaauQr84/MG/FT4JEXUCmRPGTtYcHz1wpxFNAYwsBbztM+FKIE/3upFGMrLV2l+NxwpPZbaXnrAbLKRri5lgOVBYHh9+eRD5i+njzZ1iRVIholBQ0/p7ZV3PtlGLl6jYV6qIqup3MhWSFkjZxSqEPDvOOGErH4NfXhDMovRTWuOKDK4I9w8+xotu188fxSvHhwkIFFHilcSOuhKxIxZLYAlFehjKqEp6dPZVzZoOyWI/8LBdFVXzV3hGWJmcf4SWldGgKJ9aKb1bLVcc7Rnk8A7GnOcA/pE5dU9zNYGQ3k3NI42a0MD2qw6SNyoHvgQDQuY2A1YcPqsfAMjM3qeEK521PA8CYwoS0jLlsZwjKKkAutTXo0cBV4T9N6mF2srEsN87p0p9Ayk9kLLEqKmUhBQyhSHH3/c0n9Jr08Dgd3y8zVzp2w3vtzo7iegeXJJ+1LcH6Jdr8EeCN6oX18dpIIEcitQpGQpRUBX+lOex4uf82xQXPTFcON0maeqiMBe8tC82IFMwT7ZN3xUZbYSaknJswZqjB5Houw5CAaWCbCP1eBamaEWUpjP6Y8MPkMsFwBEWkyAZ8ySj1bBxAOP51yb81dK8eMRUc0gPI0rXboXxiLhthOFZHjIVnwIOAmjLPFJN2ha6N1+mk1L8BuLUBV5yHJjep00v4pnyUEQUUs5pBtjQbmyLR9Q1ufpZE9+dwS0PiSJW4VE5FkTrLupGRLRYvbptqxe49Zw9b9xtnp5zh4reqfvA3fL/mIn8QpCYS2AODeQ8IktEPETEVXYU2fQfU4kAcLekaebpMFD9OESVMBCGP8FS7dfFAeXNW0Ftc7i8ZT/Kia3uLR0+oxflo9xkoYVnpdaZ1rEkrzFtarZq5I+slJ4CVdGtoC8QoVrANmMwO8p2fkMWEhJI+QL0BtwWjGKGYQrAmrJckDTywWIhx6figfAn3fErGK6VdKjZiSkJ0GPGRDyYAawwhzIRO0TEJqi1ajf91anWmej02BP/MRNoXavChPawmn68n2iBwoCxLU4qReglOS5EEhDOyhKtoIxrSAke/yOFAanp9C7oIR+YjZfMh3o0I3qBtq1FbT5SERIAl/V2oGWQH5WaENpN06EdzP41Ch1ySGGriBEMcU6ufqKrrshAeF0S64hOCB1EUwm45N39A1WmT3Cq+nAsa1ARBV8RVqA/ptby3Gh5dW8aW2HKdscoDyyCs2SWczFn+2Wd5+N62QhOUp03Do5XpAPk0XQrRWIUT3V+tsMHNdQOk0Loqb1jmdamkUwZFRBFccVlJVNLe+asLWK8rEaJ56H1+pPqV4kwAM+xX90xJyEmBuO8hRdcYlRpdY+qyxDpivXusk6pwMQz3g6/vMaskwVZ9GHvKecr9rAEn1HTA6ijJxht/HF64SAJ6Tsia3jJ4FvBJfvlFP51kgYg0o9uqnFbDsDrp7c3TMoHhXRsey87cEFWzI2M/QvEi9EN6ktdRmSDDNEvtBsJuPwie6H3OzAZgTUOShEzkw6TnArM49ZlLbqfR9KleVIX54r86SdQ+buzD1uxzR60LrrsoEI7X1o6vx40IWlgu8ZAUGlE7swSD/CrejLxNYVkK4Dc51iK8tQrmsKqEhD29inJtv1QhfsZNDaAS5c7BVI8LOGuynZtKgk3YBJakltHe3Qq70KxFu9QCIyQArhgMRDv0j9YMiKgPCEm/00Dp2Y3qd5dO6qKataKPS/cDo1/QGm3fcwIKs6bFbvNEvqV/UMp0W6XzLbn+cb/nWCM5/KqH06nzMdZF5CzJin9CEbX1VJNoYBXrI0Xt6iJI8bX4s+JhzHlAVPVVTSR5MYNpoRkQG/TAvveBVhgHkIjiqFTO2C8y3QlZdC6k+2/v2fBhG/kG3h961PtNpHKA6s05yqR7NjHNlSS8aaX91At3Jfxumzkkx65gOQe+1y4XgBEy3P07AvJ0CpoFh5cCqRlnTMLWVC5xozL+EtIn+I4vjabmcaTxPjSLlg4ROlMlWG1MKQiYxJuBNzQmgBoHyUGwSERrZA30muvwK5LnOrSvQocQ9nMx67TJrb++bvfdlpNX82FyjhFp+qRNRbzmfdSLqGm+NE1HXeX+ciHp3RFTkxyuXT8HB31MkBQepAxM4MIEDEzgwgQMTODCBE9ScIH3X98cJ0ndHkEaR9yrk6EuYeRWvsgS45+5/W2h7Me1mTaJWgenwaMZPWNiKHXDycVf5uKcd9kLm14tbXeftm78ituFkTidzNsicTsRcVxHGmdHXeGuc9L/O++Ok/7sj/V8Fqjhkp3hb0uZ0VmlZ3v/ATkvCPuYappCHpIDSsFSwg3ZSN0zoxCRkNN9fTFWlYB/nhJJ6ZWmnCFxeEVC5a9uz7zTW5l6T9EnXkh3pGs3tb0O10LCfdCLSBGcP2X2gpDxD2LS+V04VcqqQU4Xupzzn5O313h+XquLGxeSVp95RknIUi0R4IuhpHv9oulUN5PvzWCwYyZijaUjUnWy3mJuCB8tGKSBTELqiUvkNoP+Chr4cEHbCwkRDU+CASMiBxqXpr6YwYeq1LEx4zMj+q49k7+NbItN4Sj3mRPKLiuTdqkYvPyirkgibMj0aLIi5A+YgFb5xKUNQB86yjYYkZIeybdQLlniysQCfRXD/Q88mD2+orJek2KhtXnWOpJaocWA4nFbZT13ItnVSLa5plYrZgS0iqK7tgeKmzsvJZSmlsI2Dql8sH3kIIrfPoJ4C/HI9H1nh53rjrGLDCYulVV/KLqVuUZh4UygA/dNWlu49/GwZpZBhlIfWjvBzS8eqkISvN6PVMnYZUuBUgbUVNZ0qsN7740zvt0OnaNMlMqF/1dpEgZH0UCZ+072quoQxvOtRiak6WVcilrV2cvyVyfEvK8vOc4vvCsnzy7xIif31mLEdtL02GcOIM8PfmgSeRq2kbdjPcE/2ZvozK5ZRrG4yU2UBY3sE5GDjt+fNU/rtOfmZntAD/ImwcMZD1jqd39nkF540D6ietw6xCksts1TdaOBnLzOSVduh0uqWFqr2oQ3TdrLe2soSTtZb7/1xst7tl/WMSLZCUQ+cz0fgfN7oUzPsnXasl8S89zxMqrFjU6yhUknKbhH5sMQvmHD5gg2x1oUp8pkINRwFz7hI6lnhyQFLyDivi/OCfCUL4bMXZBOOhQiD803ybYxZF9DuTiiOOIQnJODh8V2VKi8lVHaVKa+iyBErgDVWF6o4Iq8UMuIFeWLwEyPynp69KAAq6vT/IoCKQaVOU0UwzWphFyrajQhUOhs3nl1dBtt+eqvL2aMO1EIzxOpmG9pr5lE3wGFPqBi7sPLUz2/NpxgKtEkeVGTyhwOymdDJJnmgyywB7Ao+Dx5A7r1N8mCRBgkfwgN98x9ajma2RRneo/AJhZ8SLFEHIyvWg4RWL8h5RmZhffGjwBSL7jxbfaE8oQsiMLCAk65yBCgw8nZKxIInCfMHhKaJGMZMiuCEIU3Lq2ljdiTWWBS+awGmd+WbYI5LOZPhKqE5HWA1GhsnIl2QKL+tPMzZQiulAUTXEtSNTekR2Eou/47e95TgqmEZK+VTgDu43lcwK1eVrb9lyZdclsY3X1S9BA+tly3w0jNQeb31rXaw10CBh8yJ6KhCkiHhIfIRUhANnNqyJoEVVXlFZInXslgLt1lrbQNw23O/TABO068hxYAdDzU7vhqsmFG4u/twDlQPexoiPZwlDxE+1pJsRUFf98RBaG1YGmxQVwZ3S5rgbrk0dvEFYjqV7CJvKI7YFaRfhODp5d2Upa1YcYoczJz1iVFpc0+o35GqotBXrAqXxnZKWxjwkJ1Z3DA/pQsaDoEQKEwWpmyNsYPVAZJLma9D/5AvLES8IOkD+B+sUPa5Ze1sCmFhlIZYgLz/QULjZOlkJLRqns6KYxtY0/JootC+NgGVyefIB53Top1SmZBUPcUhZEIXkXWcloq+B31cnljitGmNzUhLFviaoxwKVYItGLBunq+ejhjnF1h3aSE3ml9F0hU9eq2Qaz9x4RVL0IRSRX0Yeu+r53awh36ofQW1hNp3qpLrwYUgH73oXn85wbJLK1LNnHDghAMnHFxcOKgCxRuEhRZDmfmWqy1W7Fj+dbP83pkWDOle6uOvlTMGHv2ntNVf/xEyC8MjIB8LQskpm4Afy/wzisUJ95UnH0y0Px2+fzciH6mUZBzFYhElY/h5rNjJOEu4IPzzEdkXYRKLAB1jJBAUQ8Qw8dZ4JhKhkjHIMQIFx6eUJ29E/N2YaDv/mosLHvXm7PDwXXsugn1oRQ4P3xFtE4DIlSdSQR4SQbbhD59LOGOjlnQDfcdptEg8KVg8nj99vF2xUOTfl7v2Wj4vJwAQu85CP5vQ+JgnDGL30PWdSkZ+0T+QBxOW0IdtX3vJYZscY6YvkNs68qF6QJYIUOyMQnikLPx9B/5+QoMUORKG5m/MkySSL7a2Tk9PR7rZyBOLLRUS1FUKoygvAK8TqUVkgrx2eleJn8Y6wUMQiFPmZ65DI42rsZSrWwd40mnCVCO8qnMq8boynzyQqTcnFHjcMeyH9GLGQjkXEM7JzpIYRgtnRC/WAIiBdlzDzx9fvZEP0Y+uGCVfgAtzwRMVwOUx5oNvXZm6tEgkIokUIc4Soyfqu3PkYfV0Zyd6Z1eDN6jvK4juIZ1Z7rjvY+UfDeINGESRER5qrz4uQpYg0GcSjoWhgPpL+weNWR3HhUNWY3fKZV77Wf1geaBzQSz1wtbdFbBayXnA2hZr/AO4yUnMgr//sSGhtZwzlvyx8Y8xSeis4+rBONgZ44D//scGJKbf8qTMxsl6dljo7mt5ibWBa/RJkYqPNAETTH2NfgUoD7Y0ZhzQy2hCFjTx1OdknDRmM3ZGIjUU3KLZiGxu/b/Rd3/8MXrgSflwE8pLwftJnAZQoipmGWQBASf9YkT1B0iRxh47tIdE9pu/GkpFcuv58wWdsU3Y4U017qU+gobnv06R42eYBuGlcEltcmHeKj+W7e1wtu1NFszntL3JVCydDy5Fexu4AEBGj9ubnc3jJbNhiTdvbxLFrEMrFfmLW9ze8JRNJOpFS1aShnzK5LKl4rOQ+ezMm9Nw2d5E8ENrC09GJ1wEyAhjFol4ydthZQI+my9phmU1LE0QW0PTZA65Czxw9tlid+H6AIDVh1ZUm8t+Ojz8SApdO4X1RlTKUxFb+ANKc+9YOEvmGy92QPuQLJQcvHqZ0pNKMCMvrIClYu+qbTvrN8gnAPihCZPJXpKwRWQRTfQDEDeiWADDJ6dzFpJNCgI/8zd1pDmZUh4gCEQxe3tEtyfEsTWSfn/OvGPyb606fHlgxK4oSmLQyrZoxLeiNIpYwlg8QqieZIka72F3HpMH3NfNKwryWvcHfhugFAg0tvCw8FVmM6p2Iphbcwx/ROMExYxf2Ll1QqgUWR/EXMRad66T2nfitP0WvGc+TxftbX7iMxuZgeMi6YJ9pHHSsBjw+ICrK1Sf3EESc2/JLX1Hz9obfBChjcJ8MVYV1jAzpIkfgZjY9lg9PgCJvmHyn0O5jFh+EOGBmkJrs8Y2X5pkHcgrYDSTdheWvuKqtRXd4qUyEYsjyi2CRKQE36yYkWpL9hSOMZBGbTNaifF6EdRhVJNTHgRkwkgSg7SgTQoi9lmcSSEqlwwPiUex2if2zFUGXXNzoPPbnSVEhCwbN5XMB51mSoMAFMzu1x8ItYj5XzSxxvLtFR8TNKdlH2pW4AUZv2Q0ZjH5ARv8YzwiH0RCQtSFsLku5TSkXK+IPUUDPLLMQb+ncaHfpzKBVQDZV63D+Ae9rPE/tn7AzkdwCP4xHhA2mo3IOJ/Q1n970y2I5d0KArqgw0ejR8Nn25MhD2USp14ynEbPh1Mqk3EHIBV+gPWEsUUa0IQBpaGHTfpOwYZ0aYYAY+m2D238N7OffP1WZcYgVMUqGLY2RXwWs/ijCLhnp9JJrtQ3Gm0eVYIWTIgCsNDPYcL1McgA9GKhdSGlxQOWuUaM4FE7kakN09o6ZAkcE+4HbLtzy117yxZFYG2n/eVbhYiAVIisf2G5pWjOypVck65RVxuevSDjH+Y7//iJBYEgv4s48P/rv37Ymu8AsXjNMRvOGAZWxtc0DsZkoa+1tHkiBsZEtfFiozowjlsV/fCQa4HOcqrhVizTiV8GwjsmaWgsAKtQjHspvmaarZrvBWbZTf116q1Tb++SemsACUfGZrbMZg2G8qNGPITK/JcLJxoWrQYfkfciZsXkFWTOYvaCGC7usxMWwMtk0ZUIdvWCqAITwCCwrc7BPcryX/bZNptcK/IMPlVKRPIaTOOg2//EqM9K2PYlU7C9RbIkTzrxOoS5+XYdpTEfcDnBuSJbY7OcBceERW6rmEmLvMQywNaGNjFkKTiqo+WCynvxFw8CuvVktE0e/M5DX5xK8uGQ7GyPtv9Gfufh08d/I2dPHz8ke1EUMJVhYuvJo2ejR0/Jg1/AGTkgAT9m5EfmHYuHOlPl1s6T3dE2/B85oFMac90FlSDOTiOtwq3EhGAGXCI2bswZXsAXO9vPtwcbp9xHRvv97nZNoPQZFHQ98GjA3lAvEXFdNgS5gspDkXpz+zkwb7N05PIdJED0aNSg53L5Xkx40PBUz7w2cDW8C5tlE/mipdU3Ij5gATNfVQFaUJ5kJEHqZnByaRQxGoO6h6tOLrJV8PapiM2w1u0q78Oc+z4LLauQeRSBPKgLn39SHwG/7rc64ZJPrEtfeWkNd6pnUFjoRnchrHMFrKdhO+Blm7ApEF+QTHmYlnPkNM7825JwyVzkCUVS16uNkNxOYLFVXV+s7Zt9sCbDSNXKaS0NOmiY+GWGXOm0G9bmS9fg4yKa8OeDXz+QCQUrCfiRwYyAlhew44pYPV55Xtg7FwMGVpLlnz3lIQ2aQ69BCUG4t1+SkwbaZU/DcxIzn8fMS2TJyz8Vyv1vNR3Nc6GkYr6L+YyHuTimGw4IjBWDrc0Hv16kSkXop+jb+1PwEGz74L3F+isBD4FSZ+4Olfw5pqEEbqmSH5gB8DN9gRA3mcYnEIOU4Z5weB2G3z1Tgv2+qJXan1uT5qIrJl9Ns4LAgGJGvTkZm80aD4gIfIgxVq5M8quangIHYn8jbSESI1RPvICzMBlK8APl7zEICzgvJGbTmMn5iOyFBPwm5wSvAVkwGspCJ+F5aQz66kQV8eDAHRMWo16X5AdFEk+kgY8rO0EYrd/d2tl4TD7peVgOSp4LfBwIRQrGl9s1FSnZsF3qoTGfmPWx3v1m0RhOnzIdZ9esNk4Lac+mmF8se1Bohw/JpjE511ZvuJDW72moSvIR4Bf4zJqLAnmBFkm77smSZMdXE++aTVRT0rao/8Pcvo1yC5bfUQyF4I30w82EqMMdnBMWImK9ADBxPOzacwLs7tpGVXsIvmDmEz8FXZVInrBhzALkOVzKlOVEUwutckAODt7pLUcQGg8pvo+rpO9up5fsdExP97jZVcvO0FPwYGX03rjSDL0aED4lPFHcBi7bBIzZsUT/HSQAwzwcIDlaBZKrPGffdz1nmJsJ0Ymg9KBD8hNL4vPhHspairYTHvoI8ZAKx4BGfOTrRM6R1cbQp+Ry2yhJXIUx6zP7gJsP/MyUC0sEAX3OqGU4uknpWXhBV3jzhV9Q1QAzI9DTbVzobnDZ4t35t7kWu9vbO4XTvvEp24gMI7oBgN3slKBS2QM+e+du6zqk/3DU1OX/uGfhPf9JuXc8pCbfVWNoD57/XrE9gK1WB31ZcM87bFmN7sFf7cG5OHQhvCfLU+eCa1xwjQuuccE1LrjGBde44BoXXOPQRw59tK7oIxdc44JrXHCNC665+8E1nUIf2Bl4WdnrM2WXe2esBzXMUKaaGpOpC5pwQRPrM+27FjThIiNcZITTTe6ZbuLg/g7u7+D+Nbi/hrKjbNqgnlnkUxcksNz+7oIEWjQsFyRwPUECgfE4OwyIw/87/L/D/zv8/y3F/3cwGDh8/93kUQ7f73baIewdwt4h7K/vvjiE/Trvj0PY3wqEvcLL94LYL2h87IvTbiU03pvGVaC9GaWhlIZ5DOS/UkzDXkrD1chwMH4H43cwfgfjdzB+B+N3MH4H43dQmbsLlXEwfgfjdzB+B+N3MP6Zq2DgwPjrNW0HxndgfKdhOA3jVmsYDozvwPgOjO9y7ztYvYPV30ZYPXoGik5mBwBx8HoHr3fwegevv23w+nJHgyjKfLbkY8ym/Mzc6n/tvX8HQKEwWaBpgTxQtVfxXeOHORYWOYTW843+zxLq04ReV25tB9m/Ob7nIPtupx1k30H2HWT/+u6Lg+yv8/44yP6tgOxn+PteqP3In250Aex/9Kc1rP7HV2/qMP034HthUivAzIdWrQB9tHdmi2KQ98r03YrRR/RwBd1PJmxOT7hIYwfdd9B9B9130H0H3a+4bJrAUg6676D7FinUQfcdsMYBaxx030H3HXTfQfcddN9B9x10v1tLB91fW+h+5E9Xdbkif9r5bvXQbH0uo4CeK4jxGyGsjqvf5wyXCzymc3GKq6w9Zgq0At0sooAlL7Jqe8gWUWAVwMBYSRL9ODOKRDEPk/p7cgJgNMQ6zCFClBM8HZFDeswkMXyVCHB3IMgUP0PBTKEAeMP258QhYKAWFmxW2Q8Bm1HAeiR0Egi0fAbMn+Ejug1/7MAfu/DHI/jjMfzxBP54ilKaWtaLrY/q2wDlMlje2hWSejvx48WURLBkI7JPQ7gJlITaqRgTNZxS/dOQ4xrlxKV+6Su8Fz4vKMKGGw+Z+hwekqw5IFxYmFQF75aDtqDxzAbfMkQDzOWqjRyRz5JN00CJvJIlaBRrO+ANAv9EJIlYlGlut2Vh0+QC3WKzqT37JSLq3QvIMMDrXlLvGHwooW85nAjlMabv0zlPGJqGVXtcSrReyKLxMfKnUpuTEPZHYxZ65902WaQJAAjrM/lRjc+IsUgQ3bTbuMBCPoGGa6HbiqTE+DQ7rAOCKKfNneGTAXk+IDs7w51Hm3aFAOWZ/YMDgGAd8L9sswdk4/7BAflvtNJJ/herUC1UcdUDn3kBVcZkm8vR9nUw47Z91FZ8UETz61jYyFlMozn3Or5OQhSC5SXws9RIBONI0Cw8K+9M9hbo5jGMecKSU8ZCsj3aweO02+pF2SmIe7tFD8oImHNCZzNm+frs7KgG5EEO93lofHHNX62196TRCaCt5DwkCx4EXCM1Wr/jkRFVTdxEAxFXvOxqafg3F5HoIhKd4fT+GU5dRKKLSHQRiS4i0UUkuojE2xiRqCX3BryQxuc1QZ3AWjDhIY3PLTqdix65MxhcFz1yn3baRY+46BF3X1z0yF3YHxc9ciuiR0DO7BU4EjNPxBApv/VVMlxbaAgfP2ONoSQzlhx9Mh1r8STZkMQEWzdLzeW2Wr2a8RN0lOF0QNqhxOf46TQ+BwaiwWLgKEloPGPJW3/N40TytW2dxIH+5n6TKPeqWo7KYL4vffWayg513w1Hoe0UulZYcIlt046r0PEdtr3L9svEgCz1BQGaCzexbTi9zZASAne5fNyWGmiXxEV83QjTQFFEfdprmn/TDxrKgxwKL8Jbq8+x+Y7U7UJmmGxdBvmKf7niQo8uXcQdEptgHx+33SpIiTNFN7nbnHXWOdz23C+VY2B58knrD/dcF4kLkn+jIgLawwoUkS2N6O2jkHzQXap6iR6qs35Sb2+CVLS3TXNicANlEhFg/cj/Ub7fv89prFWan/Y+kZ8Pfv2QAcacvtJNX8mnpP3prZHoJj58TuOxypgHW9m0/s3z6zNK8yKqU9E+40NzcuBFKm0dA4G9mGexz9p2HW+FWuJF7gn6KrLlRHt2fmcuJaheUL1oEdY+1L7PCW1OaHPb44S22yi0jcJMPFqd8Ca9WCOjlmYgOlBNi8KZ+slk4JB1iQwrCkNiWpokMZ+k4ANFBJsCSg0UMnlAAAyKuG1EGkrlawSMD/NLo6+x4OUSCrmEQq0Jhcw5xpObY+g25jvoqXb5hly+IZdvyOUbcvmGXL6hljYubOaOhM24fEMu35DLN+TyDd2DfEOZ4tPVCNcSYdQYCWSBmSx4+Fa9YMelPXJpj1zao5tOe+TyA7j8AE7RuWeKjssP4PIDuPwALj+Ayw+QGfWLc820oy8ub8CtyhugXOdl/7QDrdhNAK6YsStm7IoZu2LG61vMuNspUO2t+ksFgZHhnboPbrfr75mRmk37maW2qSc2WL6By025TemCX2tMhHpu3SK7zQrTFtdd9/m3mQy49vfBU/uBYGc24AvAzNrephPg2l+WiMj6robsm6YbPrZ0rCx+4cRk66xXTa+C/io1S/PaqsBdNQmqJ8v33pzsQZtJ/YoDKF3Z7ZuT0FziJLfTLnGSS5zkEidd331xiZPWeX9c4qRbkThJR7D0jXrRsPSNjpEvpnk1NDkfqR78oqrK0EIbYAUUihgg6LmtKHe1rnaWm7+1Ird2AYzIfioTsYAqEAUEvh7AuGjGAzKepkEASjL83Qt4NC4E4bh4Gxdvc5vjbVxAjQuocQE1LqDGBdS4gBqHM7v7ODMXUOMCalxAjQuouQcBNS6SxUWyuEgWF8niIlmchuE0jOuLZMmMb6tirPmIndlrH+MWjZI0Zi/ZuQj93wqhHhbBPuDRcjNoSxxFVsy59qQpRGKwcWb99dzya0VEOtuAZgNbWAUifmDLSjxflWizcnr9qPVUTKhkTx83sDVw4xyk8ZR6DXKrcbLYn9Zrp1vaRAkHbw7Ei0SsKdrpPyk1brzaohqjZb4kETK++npEy27enxFb0gIcXPY7pC6RaFuP1ugRF0vmYslcLJmLJXOxZK7W7C2NGSvARRyi6zoRXQOlFG79Gc02Wir6/vzx9Y8tJX3NKFHYOsrHD10GQUGpZZTf2eRj6zDovY0CbRJvGuYliq8aDG+LgnN4+ztyxh3e/n7ttMPbO7y9uy8Ob38X9sfh7W8L3t6A4fth7kMadUfcm8ZVvH0xXhhRqm0A/KLmBZaKTdna36HuHereoe4vibpXBm2pqKUaqug423CVLhww3wHzHTDfAfMdMN/BZu4FbMYB8x0w3wHzHTDfAfPxbZmG1GwRzO1NFg0KpPr42BenYKYxrhi0/xyCqchmfcr04CalzMULuHiBtZq2ixdw8QJO8XGKz61WfKzxAq280IH7W8H9DmrfD2rv0PIOLe/Q8g4t79DyDi1/C9HyWrFQrlqwmRAeqr9pY7CDaNntUK7ciiu34sqtuHIra19upRHVU7Vqv/i68b9jNt14sfG/tgCdI0IwSWwpCi+3EDp4dMBiTgP+F/P3/vkBiGMZut2z8khmZa91fa+fZN3Jx5hN+ZkhQv/ae/8OsvuGyQItc+QBG4Gag0szfpiD6xERos1kxnzGEurThFqnVM5b3BbkQ9Cg1bANV1LDw5XuuGuAbBdKdJ922oUSuVAid19cKNFd2B8XSnQ7QolMlE9bIFHKA1+ah1tI7vDAzJglhGjGEh3J8k41rMYP4XDDBQ+hLGLpg+3BQ8C9ECCgkPg49KasDAPKOg09prD7c5qizQpUb+R9PDG6NbOF99j0mryJXoAj/VlvFYlfbkczAT1qwZBdcQa2HH1RwFN2fp2kqVV9098YcSQy2oaF9KN1TBsFMhpmeX74hiO1YfJIb8eRsCh3v8OWYXOim5NTHgRmC8kDNB+BTSUU4TCi3CdRQEP5sM1f5dOEDUEM3hhshGmgLpO5fnMKM4JQJ/+oPE/cPOsU8UyWZ6kkAQhRmTAWEj1il/nmpv3K3L6VDOalZzbLdHVfcgtzFcpjNuoIDLodT8dHOuOhuurQqcw+6k4KI0iZD7FrrfrcFo5bdoYyXXanaYLZLTRT/BwCYFnEYILYWBUX0je5kQ/9LuJjsGTuv9UMaFD86ZNmIyuh8fiVo8CQ1kbCDrR5OU1X/2mj5S+xxcvz31gs8ecGgi7BZqU+mpyotjZ6jhTQ9KBSCo+juopGGxGCyYssQLgvD0XevloJ3c6jDPXARxw/qBRp2KygdLgixXG/deMTaokdf8jOYldrcYf54toaUVaZ3hw5vWlyqg78+lBTfWdXRk+3vioZIk25/20pcX15/jnFgPIyVaXEfDQO1kxMlX42ICJNPLFgA7T1yYQuIjkgScxnMxYDiBZsRXKgIu4VFtQYurX/X8kynz+rAPQVkNpufXARcAl6kEtHLfGE6T2vd63KkYPOxPJXPSQET+E79BE6MqelD+U9VH3f6645ITaDwxXpOGChAxjxYvRCa/2hQ/dCB1hV6quYJ60A+CwKxPnRXIhj29moLmYVpZV1PjLxUh1mVOuG1JmHPEEXGg9n+usuptMshI9onu5LVOxhWaMoZoBwO2p0pYLNzdhjK/IbhtgrAqM+G6AEGNlb9Hlm0iT8AwiRIleoPgnQ7hHjgA1AyYpi4ace6PlEz41A3NmU2ny3HaCLdOLt7D4aLs6Hpzj70eJ8KNOJiqsbqd8kgMoQsZMGwZG2Ovc/Ml4gZLY1F9vfFd+A4vccdQlJt63gjCfzdILYz9yytqVXDrjqFrxma2f3kfZGp2F42XOeO9a7UqUD1QP7iijqs4aFDiAEKvJmcbRqtlsAS6GKg6A6RVVB5lHUbBn4cBLT0JsfsTPAVnSWfKu9gOSqnxRIo+9AWa+MdkMiGtg8lqOQO5Pxat98ULFY0LDnYLrPVbAFyEHSY7hCh5yr9PumSieM3lVOjSN1xI46s0xLxythDDTpfTzLfcwgPY9muQ9KS5E48kQYMmX57jbM50iyOPnEIrGfdS2KKrEQyZHCBIn4vOOglU45tegjIpS6FIboITaVunxzGvDlNGDo+7hz3w8ieYNxLndUc74ShXnLA0cOyh9RatGb1eMm1Xkfny7VnrNm/0lZynwwO2pZRHW4BRqwWgenABsF+MIK7oV10EtJj44O3yM6fG1UV9POixHeQMyW+4LeQaOqsbJEbEmgmjTYK700liIeRurIMWxOIF5Aro0dspBsEydb9RD18gjpIfo4g3AF772JUy9cv1UebOBRapuBJaNBxZYV8jPCIgFJFIwtvUj2dp4+evr42S7mMK2Ct6pjvRMzkuOwcosJ7jMmt1WmppEFzvUFIfBnb9V8dzGjRf6PMt1H5SANAe9piwcuvFpBEh37uUfs58rhCIrgr0YXAPy6Mqk28aF32MIgE1QofJ0nqXEK6ASdUvXtqxbmBAbmhZAAF/MAKa17A2NapEHCo4DpG6uHkytFJdQNNqtFJ9jG78iY3pWW877zJgdWWHsafctpLZ+FIs52exkBVjTz0iQY7Kdy66uOh4uPYF+/Ff5d7PIVja1osBHhlM+OaJqIKQ+CNtKt1mYfO+yZ9lXKjbPgYDYlaugsbXjeowK1DWlw/hcr9kRdIk0EeF+8yjg+S5iBRq+OeJdWrbVAwMH+exNzGBPd+lJ0/WD/vU7iGmPSw2+2aTVWL7jUq23DF1+vT8kqX2mGLFcNAC/VSpmlHrL0MWWj/mXUwqp/oBsX3rfeB4IonvvOkzUZmpbz1VgSBp7GNJwFLB4lYhHYXMo6V8+RkvSOmhIS5yNmkAHbaCw8KY5klRoKQWcK1aD3Oxt4CD+rYPMZvL34yPzWmHnFkkmkNsuIesd0xo4WNKRWn/ZH1YDoBuDbZpiEAFKCFSkv5CaETZB/MzVDMHQvjBYqGCMEnC+XmgrbklR0Qivp+bzX81Wx2SiRt6+vcgi82ID5xGmYOQiU1oE/418vsZpOcFsDwe1HnvyUTghEBM4UvVwfhRlvy0gRrGFBqlmJ+Jb7v2WjEy21uLzLfjTERYBfLI0AfkNoRSzLO1VkG6rVaGtzYo4TKOTK0Ksd1KuLy7pMcZ1eLNyOG1CIsO7JlmyrpLbn/nLytULxXAGQsi4yX0LYtgzYA2Ji71scVO3bxfSQGiSnj7fV2tUM2W+UQscea5O3dyx9HVh6gVjuF5jczbhhcyaeTaSFgSuKfhEerg0tlXvwTbESoFN17q5+b+Hur5iqrdaRp2fNJT3BZOKWTtfqqy1/Wit0ptNpPVC34DXkXNu4zZ6hW3xD9GFefkPwG5qBCgHXvqFD1a547t9x48IgiXlacXNAi1JgVLE5yT6e6IpymIgvTKAiZJxBvFVMgw6F4BB95cUsWVUEa7c+mIO7R3MWqx49UAp6Te6f3clJAjctCagDqG/42qj1GU1pJHJAnFC4tpZfVmpMTrxsGnmBHNVRraoJZmDVDcvl27J+t0vR3q+sS18lu0CuiFYV7w2tsqFmVfBRD0Wo1i2PDs3jmPoPlQVzZrFi+kHn0Ww9oYTEadhPcS10cKre7SXw103OFTHpLLMauG1++juocQ3sINPJ2hhCrrglQuWLzgkhHPks03BRjF1topXafV+hI7hOS5wWeHsuT3eFT3sIkJ21CE466tYmNdGys6FZcjIJM3w25WGeXNRi8BiYGPeEzgZEh2vKAZnyIMFk6BDjykzmDRXJXrh/t8/dsV9c5L4imImIvufilwvl7hzKvaai6lq5plyAuQswX7MAc6c83bzydGgEppuS/cz7V6I66cG2vhZPWgfFySYOVrWmBnEwa2bEQRDeVGwlgVy+aQjSoZwblep6Tfv6w5zb61YdeH1YsYWIZ1CqA8nLEGFgOksQFmnhkmTnmahuspD6qn4mZdOhVGxPVYasAsD8Bo3ps8F7tV8R3SzXe0rqjiououRNnChwUqMa6ThfPfINX51rRIv5l1ef1LY59cmpT059cuqTU5+c+uTUJyeF9pBClQBxcbVLP15min9Pw5SqJF0l4fIgofHy3NamlZJAdVYYJUti3aQFlNmAWjuzQn1w5t83ibIAi7gYIuKeG+NTl0LbpdB2KbRdCm2XQtul0HaGA5dC26noTkVfrqI7Jd35OK/UtbnFwhMei3DBwuTohMYcZtQe8PQ67/Fb1qEh8umk0MAS/ISNUFTIW2b5k5hfcd6QA4xtIic0gHrzNGYkFEkmkq6dX7RSUDlftsLH3r+AppZ0KXsf3x798vpfG5Ww/I3d7d1Hw+2d4fbO4fb2C/zf/8Dr5JGKdjP0EA/Gxgsgk98GGx9+ffX66PWH3y4wHOYtzcYrpsn51pKq5UoTCxRm12m0vP237EOqR/I3+BnS48CK4WVTXQiznVWLjlbPRVOk8fkUSpJevTa443E3z+OK5Ckn6+sT7mYytxSO5rB4NJeHwTWBE0CaXMrTDthylrbnq+IOLAqox+zMDUsiqhDdTMX05jSEpFokDWXEPJTdyTE7v2mkz7UZl22r39fKbGev9w3D4JirY66Oud4ZL+8lmfK6sODOCWl6KalbX20/wzJ2AOxaWE4bePckb2NF70KaSQu/J/mtn5wDS785jl5I/N6waquMlmx8h4uavEsXu3dYZfViR2k8YwUnA2sGe2BTdAjtY8Pibf0Iz3JL0aZxXnq6pfXO4kN0cLLQZ6HHtXiuuhrXpCRUSuFxFCNBYl8bNPF9v0PrAoEamVPWeE3w6PZG42OvIhhfod6VTdR8myoZkJ/I5VdRu3eXoarUC+qoKh29rAEDemLFTOH1eGflpckmDUHMkNKqlBEOcfuZJqDHNQD/tYhfLqhSM54c5XPPnb6QKZvycKMh7WYh94itiT4s+9ZGWjhWHvuNQl7KjYK73vyuRyo+yQEh8mhCJTtSe5Zjk2ruYbUoFTdvLZN1Ha+98Xiywx7729Ph0+kuHT72vveH39NHk+Ez7wnbnT6nO/7Txxt1b+tGGJ0Rky7dIEQ2BlZxBU5v3ZP5743vRgs0PFW8k//e+A5+rToGN7ZKy1L58vw0HplzuLarpZ5ew2Jpz3RCS1nh1ZPeaEJFDloNPTt1vbqZ8txzjGGdKnWYj1rNH3mSZ3NsoxWdR1TIHXNvrNestrFzlsxZTD7qlujg062R6yEq7XdT+2BZ1bnGG3zxbyie/gsjOpxBBuTG7vLqS5ojjm9CWoV+33fuB0VTAu4lK5NytaB3U0KukRZXAUHQY219rV+LIta/PdNqVoWvAXIgSwKyHXaQ14NVXCRmnoh9m6aXS6yrzVRlIQyrtL5YyU7XCV99Ntf7CHtwNP+mPdy9KekV+7SXO60vR1GLqcwaaaoxojRTVTNMB7pqsgVALEDRlmakr7tNYDvRP7PejgI6CnjvKWCnKNK+pFBfSej9basQtNVOB19hw5+wXY0EqlHIXD+1UT4w0qINcKghPF6pVx3Uqhb2Wl0IisJ/QHB6J2L1qvgFjmA5gnXdBEsfQHUt14ZqqYs9NOTgUgn4c7pjTyVbICKNiWRD8tPh4UdsQ5I5TYiEmHZZCWrPIteNARXJ1c0SoGsOX88Xuy+6sEAJ77mV2Xi6egQjXm0A+OViuMtD9QjUqnVb+8g/Z3h2hucr5703w2n7m6AbtYStr9Wb3QFN2MDFMxBhGxe3NSJSYJpFMKRA3kUSChKIEGwryNtvIhNokXl37pQvTI9IuSKz1RHajtk6ZuuY7a1jtrcUWXibWJ+B4A7stq0ZSxqYE2TvaedMn7TFB61b8LqBVhqzciTch3pvU85ilfoHwO8yoYvIeAsKw98DZnX/TGSOXTl25djVrWRX62Ilnakoyii1cC8VvtvAwLLk8e08TAVjGxam2BSNZxCSpdJ83hVOdSuNqfctQNsxTMcw7w7DdMbUO6hRdk7bXTWmJnTWwVbaFFim7aA9Ast0jyrGLPTtmDWMOysUV6rXsCGHeSpcSNwgEmN/vAGR4JDOOqqgLRExNvPp6C7z12oSDUekb6tWs/6BDyuostVydYFSgQ/I0LJBqQhXP+LVYh1sIsdgHuxBi0u2wq5xvdeBB752knvfjYAuDNGFITreuGa88aqNfR24pbHztdWIbGJG2tTXgx/pHoXkGSUiXdILVL8ROUijSABwMoLkLzTQxikJySpmPCmytbz0ZCNzU/xaU5GVprK4CFfLI2NwA47YGZcwoSNDEE14zH9SFp/XU1tGUXCeF+4oEWSCI8IisRMWnxMzdPbtYlqUdagkpywI4L+JUBtEJdP7A8tTY4SZMO+zKUWes4G0FfMdpAs48EAJoAQF/vzl20qzfbQngrDnenhRyGrYLXkDGQ5ZeEIq2RB72WU/F+5QX5tsi0Bzv020Tpxx4sytEWdujz323hgJLmVN3VrwWUwTdpSInFE3Ju7SjdU3H4qPOWfPJan3qg051Xq2IAUBoEw5TFMjJ21KErAZ9c5JKMJhQe4xYb+JyKiMskbo5hWlf8KgYh1y/owoFUQAZcDNe5vROYSgLcTJDRtjVyNU9GXtei/yTb0gf9dHxC/ulWPsjrE7xu4Yu2PshZyJ3Rm8JqnDRAwzVnpBbl9k8Y2R6urLrcxdJTdq4udZoHpGMcQ0N4Kg/T3KzvcN2inWIEtRtkL3z5jviO1NB72vj3HXTgxHBQqz6qwdJTK49dXUMNZBeO0+zI9ZytiyFzNPJdvgsqQEyrsHrGiwNHRxQFRmVFMouaLL8IR4aRyzMAnOSSrZTdp3OxJC9Y1vu8Y3mDW5f5SwPD+aJkIlqu84F3N2Cx1BloV/5QCpvuPk0T4XhI7mN+oSMjnQucsrCE6yv0/y+Toyqe4uSRtv0S7GJvaShSc0M5d2lyOwmySm3jFgfHTcHfwGhEAXKZ8G1Dga68zp1rGiFfnripRa1xrr47dTu3lB55v+pL7WOXM27rerzbFYx2Lvt/HsnuYavwQLZz5frZ6pe7Sa4EwicptUUMxEPjlvlA7yrJGqKUoFFUnh1pnkcn6+HmY8l2z8/hJ9p1fdrPFP91uW/1LTjMY6Y/p1WQUlazbtaqbLEhm9TWTzJuK4cen7KiwvFU7wfmfCREVSpAnAWepdqwWcB12mi+v6qx7yW1YwTNfMXLCE+jTpur84mL4i73XXT3pr88F7hGkXOlxpFLrtbFQXs7wXKwthhw3nIQdbDP8L8NHq66pbOxUQ3gUxYOj65QtWL9i98pjzXLVM46B+Jz9/ekcki0+Mq0I7dk9YLBGlBXAQRSbVZzN/RGB0kI/SOAQr0zkBh4lqNDnH9IPKuiSgnQi9IqJ+TqWGKzM/h4ZnhVNHlpLm2bKlMS+y+415kkTyxdYWnXg7u4+GWWW50eJ8KNOJL6CuYsaDfHaiUoYEwZGml/2PjBcImW3NxfZ3xTeg+D1mi3uvoKoQOfLEYisvN7lVKAW5Ba/Z2tl9pA57nIbhZc+5TGiSdqXIykShemBfEUV91rDQAWRURd7qt8GIBiCr6lBMVKhEqg94sQxjVS6unhVl3ClUT+xhEsp7ZSalQrXFPgNlvTLaXStD2YOMV/t+q5Wv7DOY7nMVbAFjWLsPV+jwrR560YctFD5qvZOR1Ip7drN6lvp8qxUC7T5I8WBiAVpPlfzlnT/vcyRZjKDK/axrUVSpViPtNGilU04t+ogIpS6FIXqITaUuSsJ2CvotssreX+uqIs1D7Vpps7IGx1synWQMuCVKQfcblpoPYYShfl3xic0mcFB6kb0qhiSLNEh4FDBSepEyEYREz4LwMDcYaNHLYjDQy1Eo5r2SYmI8CPBj4TQc5blUVbFG/U7us0WEx6kSoNkUJrmC4MeuGron0kiER57wLfovMpRzrEQ9F4GvWaZuw8OEzRCXnkmYPEyePlb0p3KOLqT+l9a2OOTwZBePcipZfMTlEcLdpeQlAdhQvG/fulpEbGeTmG59jCLdvwruTFY9vviJR9l7NbH95z97TphMKQ/S+IomDsTPvGkIUpYIh+aFesFXQXC1Aa9CL5rI70seBKA6F2ivN/3I4gXHw4ERN+oOfc3Cjv/XRHV6AQLZxiD/N7qlgCHjIAEN90oUHIxHkofIZdWNZGHC4ijmMhMEpjEraq6ZqKeJNZ+FIs4aNNF+Q65HskIzl5P84LiN4ns0COQWjaJmTxk2GUKTIaJBa14y7G1zjElCIUA8iiTQZ7A47GeqrKHc10Wk8SuO8kELRLqTDyr70pUTAz2zKMqu+5EngoCZ6PHGm1+f0qqvu5naZa554SJ/YjQA2wM5ePOZ7MGpabrE+/DizDOi/rVKp0isZzKS03Skz+9F63/l10PfOToM2Sn8Yi0FFuLXq6d2iYeS0kLRKBqRvRD+C8GTNCRcigAN9jBBGUFeXB6S0zn35kTzQInlRigK8gptFkWbUuHQbIiym7l0V+8iyS8XkHI4FUdTztChZRMIdpr4K1hGQ7CK4r5d1b1XAuwR2LeOJPNilnTg/HAu7jQBuIk7v7wSUc45t77CJi4pMFQgE6pJjUCYAkLNBOKVzjhnIRDNNxqntsLb3KDfrBm7NotZuBtXfm/b7qplPp3v6t28YRfMuhixeEFDFahTzMCYXYSmHImFC2iARPCvoc8SyoNyAGYWUqRHJXmj8ra+YYk3Z9I8LwMX3CVdcknzyK18idfjurbO7E4y2RuXstvqRxTuroLWN95cHa2x7N5+1uEZ7t7eCrHcQjte+zxZP7rROKs7STNugkwsz8OkBHOAwoAxcZldC9oNj9l5g23r8POnDwSHaTZwZW2arVxro3F3MnPlH3Q1l8rsTR87V31Ot+VK4cx/gSN043wYFn6kT/OlzF3ZrdF6srXmvdmyFkMXmFTKC3XMztfmslwXH8zuw2psVIV1v4pJXshIZeZ0x2/vjVzYrraqjCVufYV97GSw0rYqc99tBqvGa24xVy2/4mpmd06k7mivql2TK7rD/S1XF7/Ad/XardiAlV0Nsh9w2DsCruUZpqYpVY5X35QwCNvAc0YDuczslVm8MsbdavbKNvtCdi93yZfZu6rru0bXvXmOd5Jh37y4vdzupU1eVh6s7V1LL2yrweveXtj1FPAtlKNhm9eIbiyb4d0kHzdCMTqYwKb+UZKGIQuarV+ZjWqoWqIBbFj72ZKZtGDeOszaWI1joU+mPEgQDV3rhJjd8NotZOqzCkShRIDwP40I3Q7j6v/oKMQC/jeLaGkevryGb6dkDB82HqiwPR2dkdWC1PszItAQEySNB0THgVgbsUWUnA/QZKl/Jqc8CMiEmbH9UWuGaR0skH0TVohh/hFNLrVkhWGKo+uIrktvRWWHTylwhISfsNZ5d4qgy8P2dre3vx/u7Ax3tg93H73Y3n6xvf0/tdfy8AZerLcWkiNN+Vn39+avOIm8neFGeeNXP6YOPrzMhushiqNGLD6KINPIZcbNBimNfOlR6Ywdheli0tM6b6GkqxYD9Ay9qW+YQ4HJdjbZt0z0ItJA1ywDHT4sC2eqJBPo2bVWrrYpC0E2526Lbnj3t3rss0asw89fyjFe9qoCYFnY+/iWgLhETmmxSMRSUp+9Df+BHKZnbJr+pGKPCwWbDXrEpK0o6KB2eJvlwbzlryEjOvBRxAUVs7HFJxVv0NTgBcnlMX/pcOXW9aHVd9iG0U+qSnDqcxZ6DNdD+serknb16b64C6omumbA69oju2eqvrnNLiooVpMwSJsQk0DAPTonCxrSGfPr41RkWrI3TVis8qtwEQ6yFFaqIjCcIxSSIW9lce+gBp8ERZHLOV5hz+wxyUNyb1RivsbYNCjCciRjD/6lT4xucp55QLDRUIo09lhHMpuPC2S2QyCxTcAfbBjRQznCeg2ROc/KFBFH/tIzXs1ypq9TKlhuH+gwz7smFFRKb1q+PJnTxNxoSc5FGhMR8xnASESh+aYkzJ+x0dL8FuaKdijVY7nUg8pl632LctrUdeEKPSBbQ8w88GObsYqKWvfxir2ygYqqV5+hiv0KSTG6j5J3aEmK0Xm4QgfLcMszGdQ1Yzjr3bJRZWddN78U2VRctWOJrUyMLPbpnK+mohwiyT5S96jPzLEHkLcbF8GdBN1dQC7JvCuVXy8LycjUvK2v2XVsB2TUxF4TSLRE7DWxJx3E3o8W57SNZU9jsSgJulAmUr2aLFKZkDk9YeCzVtSzILVeX/Bhu6E3J4ErfFfR4tgrTGndpbcO83TSm5PenPTmpDcnvTnp7ZZLbytE9lk4ZgtWrybhzViyVLyDVK9dZDuD2ctgP5aZOdEsW66GZV0vuWzZJJ1Q5oQyJ5Q5ocwJZU4ouyNO6SuW/dprSdYlNJOPYImQllWRXC6nGag2HHKYFDielasQq0uFBPFyEBrSQ4C7cpnqyjDcN+p9vlm/cE90+NpLqx3m6QRWJ7A6gdUJrE5gdQLrLbciLitpavcAb6mjnSqhsyV7TR0EWeyIlsPSLzWboV6WaiN7OKg0MMS8rY4hzPCRjaDI6zYrNsQWXq0IPNztY1gsL+RVCWnFl3TKJd88tVWH7xnRozl+Dxf06ggR0I/CuXd69AWo30iz4YtGNy8hYVHaRsJMwGk3KhYF1LsUERvoGDmVkgGCF2cx5NaO04CpSEcttWvFlJi67/eM+l0fJnyjGQ9eOk598OA9lO6P6dqS8eapOTJ+m6TLDvS1Tyx4Vcws6undQYce6CjDNKobPIfFMUtxN9CFpJHF+lHuUqXaC3GCDuu8FXlAj232o2y/HmpsojU2x2cRC33loRdTpONeGscsTAiohgzDpENRCLfhPnngYT6eI+4/hPoLUSxOuA/J1oIgb5iHUsc4a39Efoe/w2VgKsInVAVduSS6ICGhGB0Ui4SiORfP7L3BR+avytb3UuG0+Sgd5fBup/KqqDoG43cr8NRvnnfNglqdW9H0Yqth60wx99MUMyqzkmZoPmxsGvVGd8WaG7Xewj7YLnu+lUYmag+pb2WgKgtLIX40r5zYruDk/O/tKzkobaouQy5VPfHCKBAb6wD+3RIhXAeDsXhXunCbHhO+o5xmFUkcSjKJy+Nwx9nePTH1deGuKnPDRbVREcutr9nfTUBcD6x0IzsVcc3/0UjksG2TG4QWmCNwQNQhc/W0nF9xqRXRwlkHhMbenCfMS9KYKTarX8DuN8MtaIyFI7LKt/XWIZeco6vm7Wq6XT07XSZ613h6FX+jlow8SM4jrnK5FK7gQwXGWVAeJpSHsiT1JKJ8oQH/QDys99sBlBMrNGGX2wVNcxyOpgr9sDimk4G+9EfiQNcpo0CCuvbOmvdBoeSv1EiUOA27Q2F042+DjX7LlK2Pg3I4QepmBCm1Ze1+095ilPJeLjTV7po9qyHIbJiPpna4S9QZyTsR06kps5acizgZBvyE+bVuKEDBVdMeReZbXhAzlfFJDuASzglcxiRmdAHiVSBmckQO4W04kM62hS9GgO19EZuuzS2bbUebMt2Fk+fnLh/yW5VO5o8658rqemavWGzLsmqrC9Jq+s+mCiznfghpkEpEb8wh7gaHUhjgcIO7u2DenIZcLlAgS5M5oB0AMYyXPDfXQqiEzkhSEM+yTLRl3CwQYslCyQHmuzYmGicYrIdjwcIHV574Z0svfC9rh41pd+fUdvZcBnwqcoi3LxG1NJXow5ZSeBzuH08I1AQD/hoxj0+5Z4GCOoZ8yfDz9WJQ3Wbp+JXjV45fXRu/WsqklimXcxoELJwxuXXK/RlLmqMQzABYnEgmPGBD3aWpnq5pR37XQ9ud1nk7PZ6yqJfKhXStZmt55TWTIT2BC1IiW+8rvd19nYNmgiX/YBfPardh1Qk40q6lHlTmy9KiwtWjQV7DIKvjquYTLlenqDNpy76nkaTlX3zAwQpjSFP1d20s21O3jRxoMHvWvvZgtaYyPZnRaXZjl+eKvx7J0exoA8y+vSpIBaZNZ4yoAiDA/iM64yGW8VUXRxbkAF0mBGjllOKl2hlsLHjIF8CFd/pVPCnP4kM2AbyWkMUKpsJa3777ZLCxoGf69dvb24XZPCnORsQ+9uw0lTdQFA3kJOyVUf7JuU0iymvJ4N5qeUT9Q/KEqUp5up6TCcHF2JCF8GHj8F9fipP1eaxLm3Sc8CvToTbp9hlT6RWmrP4FI5eno0pnVedSXTJoU1gqgpXlVELWMQw0Vr+ASCqJRyUb8jCTHf8IZTpREyQLSHnBw9nfyFiv31h1YmfUS7LHoz/CN1iS6AUZ48gvTmiQsvEf4R/hQRpFIoYjrOrbvfgjHJpZDIme6+RcT1dlt3jARrPRAMaCp3+H314EYsZDQOctxg9xiGxCxVH0j9UR9M8vts8e7+3twQB/hJ8Y3lzyeHubvKTgC1BBOnyKjFKtEMjtocw+QcRE1V6CBzw8oQH3R3+Ee6EqpKUrmxH8eijsgC8Abmuu7x9hx2JI+M2Lcy06KQ3RbrxvlLfaC7FX2FyLTb4qd1nFruswJk9EcjTls3lytBB+hzBtQ5cr/cADGjAa09BjRwE7URXxug1V7QjB+gKcwz1kF9MBHI3RnC2ACx518Y6aAUq9viHxwtVoiHzSpwFbLUOqVeQrs17dAvpNZxPML6bTgE76LG/WAyW6WSfvbS5pzoz/tlY6Q69Rvll9a2lUrwv5dAFri1McVqE49DrACnvVC5nYpiEsOw33VldoUApuQvjPuJ7B8qMWgKfbEMrKKVd7qGjdt15GkK2vWrJozdLfzKGzrLKWzPxLOfSrLJ9snUNXcvF3sozoNztSd2lSd9NkatlOOjJ182RKX/2m2KBmmqFIQU4warv8qqHeu1F46gkP0NFQJSLdiEbT2x3VuHVUY+lW3luycXstoVnq0nUwhOYmuFW+zIyqTCS2pDLNtFSnSrBmZV0qfxWTsnamp85O4uwkd9FOkqVecsrDLRcDlu3kvZUC1kh5yPjWtdo4tjAtDSsksL4/ckVP14taqaFeqaJ88QmfkAOVvV3FhC4VNX7Eo6SMPSE7NbnfwdOlgiK4NFIGpCsaa9cUbBZfLJgPYMzgfPxHyCUkoQPX5BgRWuMBEq0oZidcpNIMHDMk/wRHwVfskrlIY3Bg/RF+EAhVo4luDj7EMBQJpjrCz/MJnVEeEj+NVYYjRmYx9Rh4krnwlRvseoQh+1L0OHP2/t2TwpU33PHD28YP7fvnuODNc8EykW1jahjhOyzwrTZyPpzwIODhTPvPh5IlaTTkapstzvQDeE7emudNbvSDJOYRIzgaUaMp8u9j6D8lET3HeCP1kYgNLlTTNdY7auKVZc5BpjEeQr86hCeCQIFRrg1HD2s3BAAJnKkyw+6Wga2+pitHtpfnqCPm1XLmOPflpSvaprrqpJrlKV8TkTBX/aW6D+qOe9OPAQ33Spf868YklTxEXmCg4AmLo5jLDBw+jVn29ygWGZFvogTmJo/0bVzu8itf1FZyAJhrEXtsKEK2NaFhyGJMMgKB8m0ZRoC9/MiSl9hD1kJqgN+9g+ueENWE/BjTCfAMhWtvC6sJVD81GZCWJgY0VEocArNGXLn0aFg2OxUTiUgWn3CP6eGkcgiKiIUEkEwXSQ9S9TBNYb8Vh9fH5O2rUSvZ6DpCGRRVyfGhdqjz3FQq2EtMrTRAdWadKJoh3Ps6q2j9ZIyuQhhckrkqX92SENi9V3M2xvKMdkb4f22DtxG+8l0dwukdwtFHOgj/2kAaIiE5R8CkBJIAUwQmf57M1eoZS9+RQaCG7Kjw/xuDDRrPUuCczS0UxTkyDS1twJUnbK/7NWTZ/yzvqjyuv6jU4FsN7m5WuBLhUxGvm8XhLOymEGOjz1GbXLyU4Bke2Ot4X/gsXBNPPPAomEVXI+2WP2gE3yJHmuov8eoMNWXvw+d4iKyqSfyFX49e8vDVy4+iEqcDP4DoOQV9IBHkJQ5FDhIRK1h51YQYCOpDB/XOrF+Zh21K8xwS50woiE0iJgsanEI8FA1pcC65yqSfzDFIFJh7EPAZCz1wusQxC+gF5dtKGqALMbF2xlXPslDu/bK8OBNGUlw4FVkLd8usi21OhSu1SIOERzROtgCdPDRVm7oyDZiAxR08Z6Xt0++Dqalp2vDsCh0NZEcdtirVwVd1dioY1onvBySgycS6yrIBMExW96kZkJ2ws2QrCijHFEoL/0l78yf+88fUZ8+e+rv0+aPnz7znOzvPnkwm296EPX38/S7aT+Z0p32U7+l0+vT5s++f7j71v3/yjNEp9X26/fgxezx9/ux7StkOe7b77LkebffJ0/bxtre3t+mz6e7T73fZ9PGz79kue+Rv7z59uvPk6fPnz3c96jPv8ZMdz3tOnz72H7NnU+rR3e+f72x7/tPdp7X9hHXQH5LNYFBeVcNDbBtcwN1fqxBUbq/5XvvSAcYfxiXCw/zw/qi+GHqcL9XUX23yUi+m3Rwh2yEatsDFkMoviXHNNI1yqGr28yoxDRVGqIjHUGbs5TK5FWxMcOvrnMp5u56HawTKnqJkJRt+IfUj0iZUr5YwxWKnIl3FvqhqlNdXt9GLoIMuFEdcS26Xq2mwtq2vhwYAkkgyFtNjFtbOl9LMauzFkStHrq6EXC2Lsi/TKnYC6k8rkXoNTSBu+UdmiazXA9jD6dXDgUrQogLXJImo1GkqMLaQ5FRmRMYgV0qWvPXHYJZmUSKJ/ol8/vz2lYTwOIGmKRExHQSnsl4EImQvyJgGwZg8EDEZfzd+iGL9OPskGoyJZGCuxptdEvT1W7AULvgaCaS+UGlwx0gTE+5J013ZbbKf7Z1HZK80TU9A/kcCmT6FTMiT7azbiPzOk7lIk+L3K6+pDn2tEu5Dparg1uQrpDOAjMihIBJs9WbJeUgo+fng1w9kIvxzwkOZ4NelkpGxUnvQphnoHSOSQT7Q8ZozAS+Npegc5ruPrZHJ6ZhnUOrI73OwWOrqOoNsyUA7ZIsJ80FVgqrIgMBTI0iB+yzC4JyETGlScKjNc4pekhk74H8x41TJB8n84IZ5bEpSCEQa6UF0PO1naV47BCXNL0wdv8RnLCr+9mDCzkXok53t7cH29jaWAop9+VCHlRIRJXxBA3CSIy8KPdYeM8zOf979n3/+/Bf9/fv07Z/i7N3+z6eTRx8i/8fgZMLfPmXnPx//65+fgrd/Cv7+z73zD/vbp+8Pts/eB//37P0rcYr//0bwd/s/7/i/B8fQ7l+///zn+8O3f70Nd74voyzw2DVvaBPzouH5r1NF332fq6v+scDQEIdQV0lZ4Fs5nAmQThLqHWMotPnrPpxLnBTk0pkJ9VcV5b2H5neFmcFrhN/hA8vWh1T//RDeB5HrScz2cGDzr30aMQjKRqYE/4lnLMnfqf79NvRTqX8IoKBImnIfLXMiavsc9p+UImQ/FDC1mfoDZoL8M1B/5cfGoYTgPKx0HCcSCBSO5Zu/Tnmo3orUzfbiBT17x8JZMt948WRnF0P1zb936ko7bAZ+ghmxLjMM3P62fA4PrdtRuyxt21KjtriLb1XXHZ1vwfxzHfbwmAfB/pzqb7/0BSgtYE5Vygkp4Bsqy1TLQrXua9H1sPRag3U/LHMq9+c88GN2LcclU1kGX7NBQfApfGh2zfIW+GmtTXa+VFOkFB5utz3c2Gl/97bl8Voc7X47d+HDfVd2bOUXEYbMsvCA66o4PgRPnEUBgoIV4qIi0L2EMI05Ov06SeqgqQxZ6AkflJlfP5GJHgBsMjKJU6xR4mstxYjsI52jRaK6iSqP6oey/N6HV5v+IB8Jc+d92tQqnkr5jR5FLlVbpbSOtSb0goz3Prx6oP71EFqQXz89gJ/0O3YeDshoNHo4HpH39Iw8L815Z7izDc4NdSEkYdSbj8gHkZA870tmfCtplFoDzWSLcUlBAUDsOSuOwkPJfZa9fES01gP6CGBo4/hcZYDEqtE0yFoOQK3xBQ4ZM9Qekzlb6FVQKsi4oCrULpMTxp0w7vbXCeNOGHfCuBPGnTDuhPGrFMaLQ5ZGrAhopabPy+9uFtsvmk70wc4Qqt2fQU0ztDZPpxJxZGXL9Yi84wueKMu5aoNSctlmPSJv6gZu5bNosohrx0Y9h2g1VyqY5vtnKjVg6SxXKYj6kH2U7D6Bmbe/FxN1vjxfat22ODqWpDNtlKkaMnxmTqbOCUdLLrhEKM/dIHPGJTT00QFXdHi9IJs0CDa3Nr/bhIabBTfcJp4OcJKBF7TBEfeAyz2jD/0dr/VDfONmpiVVhrH440pjwCF/OCIH+RSNC9Lqk3s7RWUodw1hVtKiU063bdOK6qDmpjuHzr1PbBozudwDUvCGFwcAXFzvU4JYAlAt+Nkuyr1nnJfPi0e9eefrsg+NQUsHmf18RDYBfDKcxTSab2LMAJN51IHBpeDjYSh8Rn75jeD7yCk45lRiU1OLS50/0Hyxif83MqVBIMmEesdwLENYgoCAK5KIEDzLCafB1l8sFmTOE6uny/CNbJbw7b2wHZRAMmggEMp7ehHcxhI8RqYdtQIy3gTnEJjxL5ZwIPxVPaq17/4HS5e9IJrTR0s6/oQ9MxWttfErzPkA4G0RpAYHk5Oj1r662VD/MlQJN1AHbO23u727O9x+PNzeOdzefoH/+x9M+HGiN6gV4WJWhEBOC5kwsDshDVBfov4z8sQChixKRpbLWlRR2z+1NGpZl+3QsdaptLRZWu2s2xNsLyEti4VmDQq6TG2Ub2XVuuVA55MkNqd+USe/xChhuvjEpiwGVmL56EoLaW0R09NlZ/Hxk0ez00ePTx+p7CiWF/aeeT7KW79LnEwuYeRdW/t1noC8wAQCRqWGOtnW7psBWnWZngbnWydZttK07tHng41qhy707PPBXt4vM/+0k4lZzL00SDAORBmKWttTc9LQmNTadGf30eMnT589H8JfKn/A799v00kNE4fDZuYxu2GrvCKDdvubnS1YbGTq6tSpT9k4Zwx25ctavZrG4lYw/lWtenGxd1zqqox6OeVqNQGW7171KpTpepFfWWCNDoi+bshOBMmtL7KzCL8bZWjK5XVHmuOrMsBmCa15oJxl/fGaEiJycgShlsYRSTiCsFoEaYJIJKGuQuaeknZkIcx/jE4tmXL4twhnoNVBLF7AzjKHW+7Vc5jQVWBC1xvJeUXKb3kyv6ZJlCamugaYDvBM4lKNyCZQ3s2sokZxoVWPAdlEHTlvc3D49p9kd7RDDkB0BtXr4NOvyv1MAh4eM5+8NRyLHLz6VQ7IrxNUgX0CJhX9G5yng3342yYq3/kLKDnc++fbt/iO1+EJC+Dk4PD7insMgRGSIv/AEf4/+Ja/6XLzf98d7YxaFPZ7vizNXFAbRi5pJ7lV1pG7b9QpxcquKsJT4dDXBHF+w3Duij3HGZJXY0jOt/DZ00e7dPvRs+HUZ9Ph4+fffz/8frKzO9x5/Pzxs21K2bNnu1bdWXkRuvoLBpnDolVV0HgMlQG6pFfU7Uw7uhF6X1obbm+jeI/RALVDdFBDgGHJW5ROcd3AFPsVXWkDIqKB2qJvRN1eqYIqYPk3ebipa+GKWFeRDvUQSj6DkPk0OB56c+YdkzSCH3a2t/Wmj8h7jIpXkesG3JWhzUgiZv8/e9/a3DiOHfpXUL63SnZCyY92vzyZW+WxPTNO+uHYnp2kprtaEAlJuKZILUHZrentqnzaH5CbX7i/5NY5AEiQBKmHJbfsRlK146ZAEDg4OO8HFqmTIWHFELAxmhQzbXC2V9QF27hgqu/0fF0wlQumcsFULpjKBVO5YKqHzmwoZTBUrScuO8FlJzw1gcsJ1E/7fJ1A7QRqJ1A7gdoJ1E6g3tTshPmbn7gwXBeG68JwXRiuC8N1YbguDNeF4bowXBeGu+4wXBWbsGih1d0vCmtxSMBClqqy+PqvYjyvfP7pDRtQf4oQPJUjzche+UgH2G6HOHinGuKLz2X0gzU0V36sS7a7p2dvzq7PiF60NvcWVy9/7O5kWbfkWIMdWinEk8GQHOwdvGjv77cPXm14AGq+sea+P0b80kLtfkrvle981tMAeYa5MISyJH8NYYXHOuwFcYSo4Cp5oAuBa8Y8tYbCJsNgJel1oexKkPKjLAVbLiVYRsWry+ouTmlJ4Xas5MFYScDGCfMxoExj6rqYSy0bMdZwH+7RkXS4iYkEmpbrFstiEglZhlvq01s5/SwqzWY3Kr1eHkftDBe2gMovQMZJj/XjhBUI9uLMDf87s7sdHhaw8lMT0sU2dzRSUejLs7MBS4GX/XJ2XYaADQDG4g2WttlMS6+4cQmSki/KsIpvlZewWHq8OsoVkkhnh3N2OGeHc3Y4Z4dzdjhnh9scO5zWlQ6drvSkdKVvbIibQ5XCrkcgrKcyY6iUFg+Ppd7x21jRgVzfkI8yOdXSahR+l5aIAb9lkWzOgrGTmZ4CgZAho7rVdgx5P3rcJPKHNBpAMWszmZ0Lok/cKRrztjf9ZhoE0ONQ4rLuK7+ERnEPvSCPLbS8mxkQAVXbKR+xstD/vA05gq+LQv8cqZrnp0SFeAIoALclwmOPVvhac8Lp697LF69fv3jdpgf7++3DFy/89ivqP2v7vdf7By9e0L0XL2iT4jJ7Yw+lzSykrBzcU1up0T7M4RG7I3qgFNNno71u21seZQ/Akje3gvYiniT+jL2ovzQU5pUB7yHTziebnkdiAjHlC0mmJdZcEXgWM2bLWxM4o4gzijijiDOKOKOIM4o4o8h3YBRxDuTHHIu0EVFHUnScp/yfM3M4M4czczgzhzNzODOHM3M4M4czczgzhzNzODOHM3M4M4czczgzx0NEevBBFCdMy9frsYgkbBxSEHOXj1XfTejd7peE3s0ZuE7vECbliPWE3hmF00lvik/OT2dHsGupGcbjuyKNQbaaRAFLCCVdubauR+6G3B8S0Ih0ylYctVKoJ9wQBw/T1sfCW7MBStBxAfGzDDj5EuRZNS7gkt6R5RZRfdNqSVpETcvQdpUqmjyuGaI28O3c3jOD979+udfe268oLnZFH2T4OYSJrTmV/GGajsXR7u6yyn6RuOfAyfeuNoLLztYkv+D4quOrK4ug7ID1bBVRlJf0rt7DsDwn1C6I+3HC6yFLGLgdopgEPIHWPkpMGCk651jYprOwdThDapnFWi29y5hOJzwAr5tpRs0vFbjguOrwtEKyf09WWiK1PGNqjoE9CQa2aaxqfle441WOVzle5XiV41XfC6/aRCPmnGxtJfZMFiIyiiEfi0aDplFX6rLwkskpoTUswTmzIjn3qMpRWJzqBls0TPambR7U7ueJ1JvaANYpxQ2OTS0bSktdg4dfD4VwqDSh0EKT5T0eO+RUdtDAalGtXpwOW/CX7s4Whk29JVf2gTJBzNp6bMELRtFnCIwBaU23QWZRQKWfAQcWenqO6OdTNk4rXWmrexjRz3w0GZEAhpv7KK7++SxYLDJPxf+cC0bGpQEX4awCYhGJxzI0Ku+hZ85B4FP4Ydnig/SmTRtZdr5Kne3Ma/6l4nU3HOom7/xaOL+S+3UZMGRT4Jp1UTS17Lw3i1gGJAvOPSMOwYgOKFZcqxS6Ow/muPV5aGR+12T3mkXo0RxT1RMpHvnhJGAXNNFdNGqX/PsQmy3CB9Rbsis5NCWBWDApkarGqgqsxSsF+2g6wdV9oSQ7GbQKj8sAADbVnNUR23L/sz6bc7+7WFGnUrH1TECATQJMxsznfQ5tkArQcUXZXUCgCwh0AYEuINAFBLqAwCcdEOiKsrvqUOuvr9tJSoarWtMaCKzrq7U7vwVrJaV26WCQsIGS75oDFo+zoaZVL3ua170uXkmkZyIrpguHwwJwkMURNOgkI9iDH4eTUQTtOSdghxGkq8lhF8Z0i0Sw2yHvlQYcTnO9nyhPXDRg6DDAb6EgKeEhh0w33KKXnchP02Y99QRhti12QFfK3oJNtong0SDUYAUI+vFoRNuCwcZBvUKta5t1Bh2PtDSsWx5pFSHdMn71Sj/tdMjv2DYVrnzXy3N7FbTjyGfY7xX6wKKNAnRXOhCeVm17E/+GZePRxxORbhqnNOzKlrAKa0DDjycpvi2HI478Ft1E8V3U/UGtQfo/Z7ebXeTYHJTvA+UGq/F89iOz4UHRyucBwIGGiJRGAQ3xTz8eM4Id5Y5Ii4Zha7f1Ty0Y2MqIGg1buOCE0QBt/sgMQj4AWSRbPNnm4lhv6Udst7eDX2xlGy1NUwVAcQ5As50OucqXKAjumdCUjGKRkud7OezIeR+BPE7iWx6wwAM3v/SUKhOPHttkaHLQmwd69zeGom3qVLLGBmS+gmGSS8Hm5WGANWn7/Oo9efVib5/I/G2PKJpxsHdwKOOVWzsN53zviRscTFEwe2NnUbD41/cP2s+at3XPaes3hZLBT9PZGzMstVKayM3ocmXbAeXhNGMMPI6aNrTkdFUhPttJyEd8hj37rfID5c1P9FfTmCRoh21Y8nxvl81emRl6f29vUYuw5rGBEVC1yqQCQ75q4vZDmpI7CKoyFtSbVtHK2zJOS1jkPu2iMYZlMMS+88E0oiPu6/InPSpYQOKIGCvVAnIDtbLXJPhSqkdgWX4zuFAOqO4qb3ujhAe4oumQC3ObVcdibkuuMCpGtnmfGDcT5Awk+zWWtFyLlWvErsEw/SVoADXfkNrBRCipJSMqW7PgoOmgzeyWk38L1wAIg6xlcWjBY+NiKUgqsa0RjuVcEBMD9fe8Aqq7kCQXkrTeolK5KWFxK4RSfpqjjI7VqDfSAFOKLMrnqMQScZFK4S8bQ3JrJPDe4s3LJFBZvao3NcpQgQoWJ9nIojBJ7oYsKgwGGhaPeJpufM2qfNFzdojLXfEoCmhhXAO4n8SjFWkxa/zksqL/kj7ubK0rJLPlNdcMS2f6NWuYK77wMZMTGn0uMm7GNoGGrWNDm8eGNF19VJyoY9L7Zlv9wuyo2e4+21K+UAxsDbuqhsNklr/elPTjMIzvQBnm5VjY+qKJMpg2C5HseqSroxKVIbBbifbrwpfhJiZxqBJQik4ImjC1mo1ncS5W1sXKulhZFyvrYmVdrKyLlXWxsi5W1sXKMhcr62JlZyzPxcq6WFkXK+vMbd+t12fB2NiF7W3qRimMqLWtnaiLZ/f/qKi4bCrp5AWRSLlzGvxC9ncfyjFEdJiWMKObwLBWCLPrkOtYagDsFhwfmg6hh8OeJG/syKcpDeOBzJTfcEPdanxRxuYfzBl1v28+sDcqX+waNMQVy+jXWHFlFXL6/sEzu6SOuNfEhXAEkPlhnKSzh+fD1i5Z4VdM6cIJAo9AEND87HHJAgazXqMgsPtFszddTTtgIZOmlaJkIJ+rEjQapKdysCkkyEdG/Lwaeo8aNAa1l6uAEjSnZ2/Ors+yHB78T9vYmHIumtt7IrVojC01rkIf0sJetsqLZUKRdb9CurhEFWuzCpk80iBDlBXSxnVyAxdh8RjSI5ej/WvPhTREQkkVm2h8oInsmlIhl6Ck1pxIb1bhMn0Y1n4Ma2IYlk4KjlU8FlZB18EUnMb0TTUmxzafLNv8RoUFFmKmwKIepKjAPdhoYz+HIiud3Td6xfxU1gwGlnpxfH3yq2OqG8NU11HW2vFKg1cuV29b1dh2gowTZJwg80gEmc0SWSaax69JalmckdfJLfWdPTZHanl/5SwBTmj5bviiE1o2+HCc0OKElk2yvqysecpC8o3uobI+AWdRnr+Sko/GJ1RQ2Na8UXcnMSB6SUKS1RfCsBJFV5/ZmkzL0pSKm1MLgl5nMu0nTjB+KhO/MHyKp3ksXByFU/1qOfJPJcT4WeDefKFymxsi5wK9HON0gV4bxEk3iG+uMdCro/nEOgO+ZA9zRJd6dV1D8kQONtmQfFRV1KuaJA4UFpUeKoL5IRWC96dZ9iQUVIA9dmWFhOzqdTFCOyuusLHswmmy69Zki0SjTrdZTNOVt8Fpuk+PYTv+7PjzAwZiK7a6OGfG1MqZKVkyAbMSOIc6YT5FfeZVNiZT2uRWq3Wl894AWQo8MGSZ8pnPs7mMeBHyH8bRALeHpErtDqrABqrYu8wAk4/XoNRVruesehCQgXswg2T8jBUd5kh5liNn0/Hj/mBIIw4lzOvYMM3yieUKrcSoSnEsH4Pzr3wlJzwKYk4fewz0XiWSPy5yb1DTVWth86hemLY8W++aqW7JfhbQZ8KoU+cZabhcZNJvKZu2dADXklOcSQOezqMEy6Cv1qQf2ux+WTKvHLzBBr91aHBqTzMKsUgJN8M3NcW0XQTMefCpB6sz6vU0ExOzLpBXKlC+XJ2gB6j2M0lgke8RnO+U7lBX7CdzKcOAdsqRFX2TCkDfoMCPsCB5pfSaUTBeUYUrmecuyGgSpnyMrUWywWOWKOrQl212xiH7TKCKIE14bLaamcHsKlur1k2DiYpl4lQHn9P3b4/P33nk/MIj/3r8zCO/Hl/9Wq1ObwcPZvXbP5h/CAfpz6nzhLsG3yQ0CBImhEeGVAybPzuiIfd5PBHyREtsVC6lfMxWtl1bhcn82jWcolrtHQX/yQ0LpyZ6wqGNh1wM4dqPJ8k4BkFYljaaTavghtpG2TseSHJbISoiniT+DGRWf+lrMG/dnBJ4cbkfC58sN5nAcqohC7AuAIuo7uGUmSSxSxMWnsiuQMASfguwTOIRoZr5XfFBREOoFpFyPzTr3M0AEzblKUM6YXLNdmJYCpTxsuG1ZELX/pSLk0CZipSNmkYrLi3kzmTpaZ6G1stjgwHB0T8QQAGE6pBD4VHu09CEt+52RQn8CjQUXrMFCJVwqawCyA2VoOGZsPz4rctNrbVsVBX9WbFKkpYLZfkkuPL3MokuXdOwThRytQxdLUNXy9DVMqyu19UynIO5uFqGrpbhOmoZOsPpxhlOH1/pwrW4xvC93d4kvJnfZvoTjLbYTfMKgz05wm49zYwi+Xho2ZoZPWt6fvwgK9vLPpq6XF2jNVQGP5IrlpKuKrgu1xBIO2s37/uIsppsLatK5hRE9A12xa3DolqyUsxymC1gf3V2VWdXdXZVZ1d1dlXqTGkVU5oNve5De21Mv3q/foeCxogSRFvxdH8WkXfaKcgDSlSQUS00CUAUwSzZ/kTaadOE+jeAybLPmJJ0sAeznghevhuyxNbQxYovFo2iZHU8sEoQbIwVl5VvWX3+B5N0/nXCJuoKUjGNfLAtg2zNo8FCOkmpSTFLKQfPgBTZAYggF+pIZVgHdOzCvtF0ksbtlA7IiEZ0wEYKNRrvvJ8Jo3JrSouSmFJ2UyS67jf0EMo3mtPVfMuz82o99e1alDq2Yo3qkV3GnTCWABUd8h4ygMYJEwAhLLRtQ+EfMX5nXnaGnz6PAva5us73CR9waCjF4Xcdo8Cj8UQWcyZ67orxC5duA/Vp3qpJSdJyl4jqRmgEcAEFHVsjcm3yKE4OoLMK6HPkQhdvlAEVTxtC9J6sdKhw4idzdhKvbDAHoPrpmg5mzxaxOwKcwgwmuYqvbdOiLjx7eagxExah5A78t3auJuyW1oAA73lTP3eLbaI66xlOpg0IFpRoQmR8rDFDIhh2vfcpxmLiU/zsrPbjBbyQr1jRQZLM84yGzgT5fOR25vosaFi3GAuOFfDDWaWcVWq9Vilg9+0VmKaqTWsbDFWn769KtioI0qvvY1s0XiGHLraFVfase1RJMeBQqY9ibLO7I/OybFMUl1QzV2GQmtmoreJsWM6G5WxYzoblbFjOhuVsWI/ChrWcHWhG9FmUKSVan8ztMjYJ6B42oMui6afQwTuzAGVC3Jwmn5Ur4cupcbPnLQidM6e2iXj1ernT8des48+jeNfgTxMCOBX8m6ngy9YKW79Svqqap7MLgRmqaBsofdvSD7OuPtizvfbefkmaX1itV7xrqykVW9mQ7c0x5+iBqVbRyjLpRDEKRPbPCjD+Qz3KWiRlb2yitpzXGi3upLm3pOHg0rsVcT9tl7es7f9amuiQM+oPCVAGwyFGuuq947RL+pyFAdk+v3pPXr3Y28caZ5Mw3OmQU5noeEQwO6OpDeWGLK9CXpasUKajk3gEOTAKWdaQ155ts0qbTTUV6dFbbLBZ4cb9PvNTfmuqZqNJKoUyn44VfSK0n0KFArkTfYHBZTeME/6nHE6NuCxIQqEDVpgiYQQ3DZ7I44tz8gtN2R2dEkmdQPEdcSGADuFYweDuYS5uQEYTrMonYijNF98pJEDOyIJcerTlu+Q8qj8JQyMzJ2E0+AQF9zJmrf+FA0Gv4eI4ouE05b6N/RhzK9WLi4tJL+T+XINnVwToJ5xFQTjNwPqgVV6yzRThYEUsVyjgEXgWFE99JL4Fg8mvuECAmnm3vYuLaa4J8wsMsYsh6ktEzTJTGFEDO+RY/gWhrZTAvY77eozQCk1Eekx15qZ46iCp0LwFN6joNUGvarxJUDe+KsBC5WQUm1XgXD1fVaqbja8ubfEubKfRzJ9fNzHpwUs9OKu5GEaO7qVXVanxle7oQZiQCTbPOBhzS475PALm84skko+L93QkKe1kFH4GJ2pszoEQaCw5U+AT9aVnUAwMFA8xWAcWiwGWgVRS/mzhHY0JE4+Rd6zFd/wQ5Nqvodf24l/mku6Vco6YsULi59jl42KXjjs67viw3HHZALCyprb7Bf8Lb+T2ryq7lc8lwz1llRYP8tFshivHicpA0ptiORvJkjaOJ+YWYg2s0hLqP3Nv2jSXLofnklnb1c0Bm9sq60LX0pAZ99sRxydBHDeSDCp69dWbYW6qFCD+haWzyVXmh3DkaqXk6jJPD/9OJOcRG+Gf94qdtZ8Klo6So6/poHn4c/by1XPKXtL9fXboP/NfBf3Dns/2n/X3e6/9vQMjzGa1kvqjk/5z+FupudOE7JpQjulOJ3oabP8R6UQgAoDBcGKzF06UJNDYwneWOID9/qryQEsUWgAZb22mje+bCwjOvjiffVH3s/1OpCTHVZ198Snz0o3kmhLNVmpJ3DXUnWa9/C0OtAeDSFVbTzUzFkQUgwNzmunY73L6uTCcnuoU1hAZ4hTdDVZ0Hdt5Cmxnw1S4Tk7S7x38IfmHJQTkOAhMZoDRGnat7jgIRHlomYuQ84BFKe9PC8GHvSnpZtenC3Hw3Zw+Oc3vwTS/BVjIIq2KVsZqvt47tETx31U2NXBsd1PYruOyjst+Gy67hiASrfrtfpF/LBJYIpm5Jbzkko3i24KBVjU5qrPTwnBRHe+UwxmUKvt2dngbrJmumUO6cJfvmpxvNOHWYS/LEu4v6o85qbNKc2sI/NPh7vURf4X+q4JVc8Nndx1QKVqlfPMNp+I5pBsXYVR4TWMFmwVWU/P6vRPDQFpFpybsRpcJKZ3cCknZZifwOkn9wUg7QPnQQXlTGOhSec4bktE8R4io2p49SLSWteVVKjQteixhoQvzpEUWUXyr1hijCogvWA9k9SzHFaSoFqRwjO5bM7p3cUp+jidR4GC86Wzum9v95gmJpKk/tPjR4LHmfg2BkbUsUA4wCHMpElLTly7U5Eih8wn5KU6HsoSULEqkz9GxzIVY5jr8aCZrK1WJ7KtaYimUFaPRFHoLQkUVwWjiD6VWqPX7876s/6VGc1TfRxw0xjQ2Hai2AmE5zyxhmpCvy6c9Zn4S7QKqjpk28CJIPqc2eI549IZFg3S4dbRfE7iZQWLhqM28UJk8NlVCywkrTlhxjPRR6Is6HrIx+MTxTMczHc90PNPxTMczn4ryyQdRnDBNd9fFXhOZRLca3+WuH4+Rms/ssR6Pp9fxO3Z3elWsFBaPp7qlAQZ+xumQJbW8+yQecyaMF0yKKktLQlBowER6mvdbB7YeMgohKTA+Vv0hMWEBgdEhl/ROVd/HDpFcEB8+FRConyubVnZvGBtf0juYGHu4wzk9LQkAOlEuIwPo92ZJAfnCDFg2l/nOuLgvjz6hd/KI9OEzkfJIlmvOuLmqgw2HhFydbGevcUFgeeMxC3ajOFXHvNNUyvsBl1AhdevM1syvyCrYoG5zETQymXzWly+eHdC9Zy/b/YD124evXr9uv+7tH7T3D18dvtyjlL18eWDB7XLvmMI2jDXct4eMvP1ZN8BV5X3itBZzc7m9i1lCSC2m0gHEOKODQg+vk5lfMRq+LPil57KxFEvSnykPJ4kl99dos6LoNNT/7cu2ydicAF4nPJKisb47i7QBW6STSvnDtoYxCaPqJMvIAc9VuzOGU01qWj2ZWMlVGxY1bY3sU+iiMuvEin10Fjy0Z5W+L/qVCtLYF+bk1c2TV59WV1UUJFcjk6rfvuB/dYRdbewBgrGuPJVuhVZblkr1NZTR0KUwBC0VPR35cHUWInMR+pwal4DHtLCAWnzr3tF4stvlCpOAFu64ulyH1dIrx+F4SJ/NePHXh+rNKoe11ZM2KAr1zVm/SR/WIRUnQx4GCYts9P2bNGqFl2Y09n3e1AP0q7d1w8PwZAgTV2aBimk8Tdgxgmk+gZ5YxSKc5oSOmX+fWaLJ6JL1WcIin1k2XRohrCMSejcLFw+fPxvcPTu8eyZlQssHF155PssMzai0XvPVOTWqGQsQSywgZFQoecAGu2/dJ3UBevbb1fED9Vddt2VZebyKILNDxOjpXeUbdWyhAiR9darUx6R8ed/Y4mUtX03dV9ZoOFukhIWbV7gFCttMylWkUwVyU7575atQpOuW/rMuAtppO2vSdjAsbCXKTuHuiF2VUdpskT8332ls35G30Evl1azp31EeiaWAzGBhpwN9y14fxTW9xz9oSIzHmYmrcuIVjl+RW4uzX1cmAdObxEuyzTqDjkdap+/fHp+/a3mkdX4B//vb5Rv4z6/HV7/Cf8/eHp+/ae3Y/OD0s/aDP99rdosX1zm3Pfi8uHad5Gpa3FZH9wvN0WdJp+q2HO0fPDuSAFxQjchfmot/zAOJZqDnH/IqW53TpLhK23s2TUkLt0zaPJVj641svThUAavyvAL26moXKGpZkMssXiKzxqNCBIWBz+1UIGUJ0MgrltyyhJypHuwOFx0urg0X5xaGM8r8WEqk5G6mDoBtrUVR7OKxEosa0+wzsMrU9p8m4Y0t2d5wnvKI9OQoe9b9ZAzCz8HenvlS0VvQIRdUiJLsBRZrnL2bPTsPRPcH9QP6NSEQFcIH+pCmpMJSwVTNAnwRm91FA3zhyeXor8MNYUJ6RkxK6ZyyjH+P7LfhsMdoWM6MBPOudNF56wh5MezGIsKP6OdzOfhgT0rR6p/7YED/PA6xszqGWC7sI8ljKHSZAuPyr1BylpOj6aq6IGukg3rFgBwQpwEax0Y84iNoor6HNuv86tg2q5u0G5fxjhVuowrsza74+xFP4Q0MJGO3LJniy+SO2pZVZ5qtD4IxYOFc9d86d9RB+duYCDPyuXFpL4YU0iD4gCTRnqNaQrZPKMH9hg2oP60W7y4KKXlswnaIL+xU63nj8w75rVIEyJhKlgHa7v5ydk203JX/3N2BEKuU0aBDzlMiJuNxnKSCjCZhysdhRg8FRuT6k0TECRnTgQoAe1pCysPF0o6lgaUgsFSoSu7WK7x3xf9c6l2d3lAvJP3Mw5QlGAuTiTW3NJwwsg2tI3BbZAQJ0DsNsbeLzTKHcKfsUs0btkyAUXEsOFM+rtkbN25Nb0rU6ypeCM54W+x0yFt9M6QoAdlJPUbGSXzLAxbIF8eMQhYaChTZ9WiKV36wBcwrrtxLpqRIdIqi3CqzkwoK4nysdS3dW8xomapFPciUGJIOuTBuQ4+FcTQAZaFDzmVlNpQ/EWoZmG0UpRqDA6SlrUoOLxWeYt4Sq+hsIKHwiE8hCB5TNgpvvoHUuy7ZDlQQ/cFOh5wMmX9TGvcrFW/jhHWlppQyH8oFqUlh/z+QMejWlsl/bO/jWwlLE86gtmkYqtjhURNql5SQxUKcTPAiCE6Vr66kBl69J69e7O0TTGRVAc2F+9sh7yZhiD4byc5L4cHaVN9j/ThRYWttnC1NqH8Dlxk0DxoEBb3DHmV12N570d5/bqAruPRDKQ/pPDwVd98MB7kOhMLh8xdVy1g1jr8hdLqEA5Zrk0yYVLhKNwbwg0q5aJSBB/W4qIQqXUzJpDwSpMd8ivURbYiqUA7OCdBOmXTmQTupCxYP15phKuJJ4tuC7S+vrghNUu6HjKhB0sJ0N+SY5VrYOxw7+wxYMEPlpEHApZvwwkB5mSNbugUJk9+1H39JbvGy4bV0JQI9/I8ttamtj7D7qUjZqGm0klgFH0BmF76U8jS0OihhJLmSIzPY4egfSKQv1pCLNE64T0Nkhyyikc8wazeeAJmBX+HM4TXbHSpdkbIhWm6oBA3PhKXegPUKzAq7KjEsFWtTx13QFqEITUoHRI/3oKcCQkTdI/kzF2QSqTH8TzsJqVAIPec7a8ZubdTUV28L5T27XGEBjIzSKpMC2u9zn7yBWEhykcRp7Mfo/wYkQN2D/HZxcXZ5cnx11iEXsRC8FzIpaYojcvLm7PjSI79cnp2988jx25/OLtV/2lfXl+cn1x65PDv1yMVvlxdvzhR1RpCBSUiFQDRo4TCTDWabXFa/9ly8Yswf93k8EW0z9tUe11YW0eX09Y1ONUW03o9cq5wtAo6LZpI8YjRTkGw/pnFKw8z8aP/5gg6swaglACgFztDHjMkLU1UcVwXLgrFpbZ/6j/+Az//vhPW3jrb+164fj8ZxhGp7JhqW3CltyQ4/HY/5Xw5PQs6iVDo/v6ILbJwwuMm5OrtO08yC/ipjdfd2U4XartLcIgd/j5MB9EOMhLTYyNj1rYO9Z3vtvf3SBVy1W2v3S/b3nMWkS14uazlpI56rvqK0GfTlUl6W8zXNWkbRJbS8M2np9Jd8Gu3OMeN/NqjcvzPEO0P8igzxi9jg6zIH6+mnkT3o6OeTp5+mazxb9aZ3kna2SGeLdLZIZ4ussUU645MzPn3XxicX/fNklI4NCIm+b/34bOcN1XCbFBJdEBe7zWMNPVXqNu4XlZRyHT0s1afGTiJ/SKOBq4n7uNSXtZTkXYm0/jBS70OJibNEJhpN3/fxspQlkDpxqlaUaZBYzKXLYdXFfryXIHNCBWtDnbVI8JTfMhIDARlPUk87TIGIZIkKVJiiz3EYxncsyCQfP2Q08cggYSzyCJZXUP9pw6b81CMJCzwyniRjuxM2P8jLs9M5xQbF5otCwzLVBNVETu13ar9T+53a79R+p/Y7tf9JqP0utcqlVj0VKL+2k+eK8Eru4kkYkGAi4Yw2BfaZC0wNWIeI+92eynfjZ9edntYbErVbEEy3mmoBG15945U3MtCrLsGuKPhW8+q4SEUuP2cCMqYNi5QmKaHFiAGVgyfbFKGs1pcZPaAZyB5V7POYRkFXFjVHhasooUcph2uh85C1Dva0bHMPl2G3Efa6fDkSM+qz2Ioz/+vV+3eE6pL8X9Be65F47ElR86vCLuGR43enbT8e9XjEgg75GQ27RxKZpiAgkW00+bZZFGBJqB1PVobaNjFb/+LHUZ8HUG2RbO/947/+3/7e3o5HRiylcMydf7lh0//TIWeSMh+RP7582MKlfdg6+oB7/7DlfdiKx/hv9tcJDQU+wUXjQ6VEfeLRB7CTme/nHzdnGaSsMMXzva8f51a0cfIqdA3o/E1C42/m1v9W2rGtGkNs0R6uZI8ySaKAJLSQ14qWbEhzS0MeoPJdnF5Z462iv0qUkKAEyT8GqjaQ/wOEHllSKP/kN0xxclA9AbuAUonfOSI9iwL9J9bg7PMINWZcIuZeZHJ6cVt/wdRNqAcXj8ZQsoQOYH5VIQE3lG90DNtoMoyWg66rjNf7Mp+JtTTTx68lrPhaCbyW6ICHZxUUihmPRrFzpNzz3t2TeDSibcGAaGeEfYp4huVBhtMgkXX1gDN6OQ/xQGneaTIjVRXbuiXLRO15l/xvbApEVmV3q1o344TdgkoG2d4WQ+1iWcnF70FgPBH8T0a29yWZ8UhmtHtugiCv9qF+3zo6eI7FUGTpj31VC0X9a8EALxYMmAC6KrOm9NHkzBhI4gRtjsDCi2nvKxKZ66TTavmxSdHLkkux6rAtQnTV4KY21iSi2zIP5G7q8g5+VXA7Q1RHxBzm9rWqVUrCmcfRWVlfyDdVkQBXt1xTUjwLBmxLCfBzRCw7K8Jj16Q2IHigU9Y+mvNVmrvqWvWfOQsEm+uoLxRcGKa4Q6F4cJx3VYF/0gHZ7sp65CBjdXc6pKCbkR5L7xjYie9is+KBLo6mapA8tbCE70z1WVuoQi6p22SvTIoXPjhplBZjrx9mFyKwmpiS0C3IkfR4mtBkSlBHy0T5rTK99GrSsRUjVvX6LdpJ0ckCo5QIObPHsJ61psiznAtm6JAPOZJ82AJHDVw8qnz529lv//j7/9TYTKq3dafZeaE7DWQ6jfp3Sgdbuexudf2aWmrzR5QxpZ3GM/ovG4AyzkJNvVQfQu08NaH0AGJiI+st914uJ7RnDFjN7pwl39qMX8B3GiaMBlNpsheq3Dt0IsUsak9RB6mb6LuxyecC1DnkGZDnPI35Qe4EypkC5ZoK9Taa73e/JCz8BFLKQqnO5lWYL+25WZ615kAXRFszoY9o2t5VObRHsidwl/B+xTNAgpiJqJXKm+rE1kcsthaqx33KQg7qllKg14uuxvryLHgtZOC6GzIM+K4gbKmI7QPbstSX7ZYWZ4jZDAnlSbm05+eQeSL5fAkc5iWeL5mjmU3NndlRuM/fYZqHY0wbyJge2uDzmwp5ysd0ZCAq5iEIwtOFTD8Wj0m9KUh/O7MB1X95DpuQ5dN2k4j+bMWBP9M+dK+MCGfXcFLD8kGg7+KU/AxtFhyMnWS2pGS2rtBD7AY0Z/dN6RSrdBlSzrU5ugxpr1pWX7+u6D+PSByxrHUMuWIp6dJJGssZ0LNmdGmkkVluXQWbQLhiEDvDxFLy39rkmeIhVhf6Sxj3aEj6IR2gb3WSxiOaQlXbcKqPu3zU0ig1LZw2Aay95cGEFvpBQL34+JYlCccIVC6wQC68zhMS30WkuD5chz25aJk67LM2f94neIz2bVe7ncLOeVoywJHzvrTWZbmAEPY4TOI79FQjfc8ylUrzVUx5Dft2ydIuWXpTkqVlctgK063seVaWw68vb7uUIzVvRqZdqks2kShJoA3T5oDNqv06feFpyLIb4J2b2T9qXU65xRrLzxczNl8/+UIr+Vmi65xM3Qmvj0F4dfKbk9+c/LbB8tt9YttcVRxXFcdVxXFVcVxVHFcVx1XFcVVxnIHDGThmGDjWZdvQJHx2XZBrOqgpBwJzgPyfmSpaomgUrKsKgi/ibQBGFdf58CCIGHAjT5ZRGcRPLRRrlRV3F2s0HOVVMkYcbh0cCB3cx1B8XJwQeXYS34kGQbZiEXfE1ZUce0pQfu5w2QkKK4j1wS3MzHdfiawwim9nuT5Ql3wb37Lr+B27O70qSAjwPNNmIcNdxlSrT1RYIQwXxvjUsDPJMG4wzARMpKdaM+8qU+MoVmHbI5lcD6/KFD9DkKB3KsMeHoEOScM7OhXq9aDyJkzNBblh41SWH0KFqnvD2PiS3sEauvA7cOqnJYs8XFi4Acty4Zsan4gfj6HCW0Lv5DFqPGFQkRGRMz/xU2Wu40K7QrLXIAU0TTiYSXZBqsRpgx2JJSX80B0gS/jRaajOs6HLrVDXtfm4Crd0Ndq+MsE18rV81pcvnh3QvWcv2/2A9duHr16/br/u7R+09w9fHb7co5S9fHlguTNlE2BhG8Ya7hmWIQmOInWrY/x49DyOfqY8nCTZSdgk8yJ1xDS3hBE9AelTHrJgOcNznaoy6xu5wS1hVO28DEx4rrK4SzNNEmajgbUWXfUNq6ySs9sTvGjVleShMIbiaraIVVe0EhZjYP5z/JJgSTrHeeVG4VQBTmrN8DrhETocMpoy97nxKGCfLeQLHmt7rOSZ1g9Xg37mPrt5j0yusPm48DY1nZECXuF85EsNx3NQrqA1GxeKXo8F0eFZRZxWK6xgo31dziC5eXoGisePRMeQl6RJtUB9YDWqxZglIy4EoHCjCfIiG2e3P2r9wJyv3uhI8TDJIKFADkyzpRPgFw6NWkTyQed/3DePaRk6NMvLuIY4iIRJSanOc6l/zyIh8i0q87bUfTMsAo8m3kl5mPWEcO/Vq8MXvdf9dtCjr9uHh/t77R570W/7/VevnvWeM/oqODBXOEdcRKZ46wpS+glUj0ricMb7iWz6rV9W/7yTCU9IX5HUziHwb+WjZy9bwc74cv5E0tKPG+6qtPsbTQCYwFNHUTrZWj+kJZrcyQHOdv50oDy3tHVhCAGPQ+bS6ndHSiadohhzn5qmOSwsQem/gACkpSHgTrU22V/4rQxMVyQXuJf+E3dJtrsGHZP22G5Gy7o7EHVEgy6810VO0bV914lfGxGZ/qhFgEoFg0bueq8g3vyabngUr5NeHwXqfsfSqxNWnRj1rcSolQbWGd/c/YIWpk/zVevMwW0p0XnJbuMbNpeodqm84FJYy+xcuheJk7Tu5anWJ1paVv2H70115zKy5ciT+X1Nt8PqyGYtGXTFJjeEvjtjxNPgopvLL426nhOb3WFimh0shTxPsIamUaAp/241Jx7HSrWrCxJlV1XvLPC2NK7aFxyHe1QcbhPtGGWSsJDBwGDJuvCjY8nfJ7NwLNmx5PWy5JUWdAQ47X5J6UB2mtgtFqerjdFQLOeaDrKw+lnNo0WWYowqLeQHQQW9QvXG7YCNEwZZu8FOhT1eg7GSRcE45hFGzOaDZR/pX86uye5RDgi9cdzjkd6jscWshF/eyzILFxQEo5JJJlZA/FvKaJD3uDCbsAkR+xx3l805TuJbHsjMKpntnO1X8GgQMlv+HBFDmgTCk9MUW2dusISjgdu4hGsFh0UWYL7zCAUsaPFa3961FEi5UGvY+nfLOc3NE9grpWc1A5pD9H+W3dqNi9ArVRJAmG2LnQ55q0u3whNZT7NnXBJ8ccxoCpUh8PpobG8Kun+wBdTx12oka11vYXsr8+J2rtJk4qcTSMeUw6GSDiUz+5pLDiugZhi8BTxJtTE4kkOMfsnX2MkuA4YfR7K2uky3PX532gIKPcAOKB3yln4m+3vmqDFLsvK6DSfzCLcynwxV0x39ulBTCwcBo1N7h2IPqgySfRseAdrRXLJBFyfQGoz+d/nCIxX6OG+7deCcLR61MEwbCuuRMI5vJmM4n8kY9rC/t6eqUhAKaVHQRI11Bh11fEct/LEFx3gEM6mzPPqjxW55COUXWl6rR4NOnAxaH782b9JoxL72Pu4N7dsVmPDXDrnCdcou9DGENSroiQ7JsytwjOw3h/DUg8j2CDFvjyBGYcPHvC6YpW6FJT3iSy3FWaR9e0M10jLdWiyfPM/Qz8I+l6w+2qzvLFM62VXKcpWyXKUsVynLVcpylbJcpayHqpRlO/zcmjGb04+LZso81zDTjG0/pnFKwxOMtKr9+YIOmLD8XNq20twNRdyYvDBVReIqFEMyNu0Cn5wV/olB2VW4eRBfR27pzkyVc3k/rulgreF8xrqyIXwQoYQn1zmnX0Sk9IbFk1T7RNoPWPJG9oM/j4IJIAhrdnxcm4On4OH4aXqaRedVKuXBYBBm1dTFXlXbUh2oejre4HNpmumaLqNM+sWJ28bEAI8u2e6iDyTzexQ31t3JfBib7U3YMHP+grYQbQGpnn5WxCKPy1yVYcReU688LJ1pHagpyYAvfDSaazYEv0s7lG0CTaudILR5jnJJ2IimbA/ONpaoW9CpkMGOpKjrYxxz9YZR9KWhM0xtQHfWFiZjEn2dfQN2ILVv2RqGi4tJL+Q+2iiA4sF/Q5ZCU0PogahcDzz9QTa2vuOCyaJmqi4C0mKfbqZveW2BYhpsFlOeruCVgm1AQRHchAqSJunOeq2o0TwFHjziKr7BgLDdQhQpO0upSbGQr8unPVaoh6eiBwqHByD5bLVfFFsYF2kGftzLIbFwYlzebVPyytVmxXFxHNFwmnLfRgDLXYy9wonOHBxZDVwmWe8nnEVBOM12ia+sPbmqfCheAQ6OZW4ey9Ry/+NKmFpjdpQoKlbMcCw1pkOhzd2SCSUfkaxKUUmMx18F9vtFx2zuHSjlP0kLf17YTAaA8Ih0dXE/F0G+ZIBTVh2xMa4lc5LjSROAPnI5OMCFwDVjnjpKZTJDW/W5e/i+i0UedUKWEtRW0XezOKXrubn5fGGJCnAbUetN5/qskvrvfsH/4pOE3jXa1hBul/QOOGKprPQvLM0L6oJKBA0NVXxi/b2EN4yip7pVHYbW6gk2nPBr6DUuQVPDRRZgvrMyvvPNOlro086Lfa+Q4ilEKARMVGt5goz/NfOHztATXr/ca+/tW+OKmt/88mGrH8cfto7Ih60eTT5sfcXwnxlLA9KF96B58mGajsXR7q56It3BmdO+weRn9aAizuSwy0Gj9pmtSX7B+e2c3+5JQfkJV4ztACtvkCSAxS8vRozj8SSc28x6oUcXa2j0JjwMMhOOCmkG429VkVSD87KlAvOO05T6NyzByEcZTMWEV+qbLDysflbv6lHbbom87Lou0s8T2W3ZNOye6kEQwD5OYkArGSHao6k/lKGhGyeuLMSq1elCrmyi+nyhQCYRBcFJoylRN2llZMjmCJuL4a/Ug1ahRVkssWWRczr1FtqZRurqi4tMYwg5i4KnJtyqFjw5+3jUHk/LzvrxJLKA8LFvrJx+gLs0hb+MR86zhJpZ1RoMkNggnNNth+4O3Z88uhcSHNbNtgrxwO5+fWs0dPdr/fdLyeM8GlzzEXtbi+arxFdbcKK7aO6iPemLJpMrtPa7fmxtSG0rsTnLhSyImZ6hYVX2YaEgqwbmOvH+6d7ozG50H9oqG6Wd1mrzqyexeYmxh/wqIvWDf/B8hri5ps9ePDjLL48qQNt65l4Z9ewgq9vR2ul56RXTIxSYG5N3cG18xgVKbJzjI8PYx+H7mCeCLvNdLOz+kPn2uSyx25u2ebD7RWdmz1la/EQNrw+n05EPWR55bWRdZSQUf4BIZ+kG2Dg/RB63YACtcRUaWgtHzFVeLF/Ze/fPg/d01r+OAdPbWiGVWmdQs6O5m0dzNeJuaHxap6BMzVGWujaaTG/0Utb5LcaSzaaBWT6fo4HfhgbSdVC7Gx6GJ0Oof1SJl4Km0jxN2DEq8E0kJKcM10ADrf2scaoTOmb+fDNBoSHbPLPTVXR2ihjGSTp7eD7soTJacpg7fvBU+MG3jj+aj0tgGBLQ6NQfVpkEPs7YhKV3gXw0B6+QA6XYNuC3LFIVK1X7ghL/gAiXkNFb9QLmZuoXJpGPTRA2PUN/Q3nLOvJFHcswWMbXZVoo6pYIjp87fu74+Uby803j3LrHQWO/Y8e6Het23MGx7idwOI51O9a9Aar4UrX7lufyCRuH1F/WV/YppQMjvXhrzjoT13RgbboLnXShfrKuHqGZ/xJV+nCWYpFvuQKo0Hd69ubs+owUmhMZDZgKr+1+SVgof3g0xfsWyFheVLIovlVewkLWZXVVCe+TDFXkQ6bKrK+qL2ENhSmPqyc35RpGJeqjX/zYSLPmnCSjiI4/bB5/2OS6EqryXmdW3dZla0zYKP581fg00beU4zsOAkmroSPdaum9XBrQ+4v3V9fzUXtH4uci8evQFGc1bMgpSi9OIyzcWF5bOQINZly4sJ5jS44tfQds6Vu7D+dkVsuWwxskdIwOx+ZSR7/gMJMh/Tu2HMXXScT4YNiLk2EcB1IluTzA+gDkhKY0jAdVivt5TCNVxkB2GG2H7JaFBdZUnDfuF8rnCcYCEsUBE2Qb92LUO8BuMykd7FgXAzVpGVhBBfThG42pnxIeEGnqI9uAikfA8nZU67gPkokcPX++x14d7u21O53Ohy3VzK+N61CUXpARS6CFfBSQgAUTeZVZVjxAsOSWJW3BA9Yhv06DBO25epeERSmHuymLDChQqzpSsI/TSYI9Bt9nfQcn43GcQJ0G7C0J1Rl6xZZNWPlBrkeVlxB+PGYbzrQBpjPK9J3EoxFtCwa7QKufOkg8Dh4I8xw75EySsyP8WfxYPU8vw52jFy/2+/T1AT6GDj/QcpPs/+O//t/zPTghMBT8QOIRT7EaBk4IbZeQJx7u7TU1mtzoRdfxjKp1sa5taMAT5uNWG4/uLBgwko1V6HqLJaEZ9Ye4uiMST1KyDX/+4+//rW+I2IFLTrazf//j7/8NQ3Y80ovTYdbXbafpEB7o8/XYPcSLPxNMv+ph0K4RbFRTrNSSUQtJ+7A3FENq+qN8wgX2iSLJwaf/G8Ny9aqOkOJdHpB/fX/+TrWM/mdy+h6KQ4c96t90SBB/gqrbcuQ4pDyC8XqoXLhsaZfBgNxyWqFMDeB/5NuqP1Ysqd18pNDWNf8CtHTFm6+3cgSdNz0yop/xr72dDvmL6mXaA4sfPFO3dhalWf2XSm4PY+Mj+vkTnlHz5q8hpQeKDE1GE9mVDl6CFneE+kksBB6AJE35Op+vCiIP9Pl6MJlsWac5LcDgKlwdTQGS8ZPe1OjZm9LBgAWfQIjwdE/CTzzydDfAT2kMdaImggWfelMPqkclvDeRvyzCvh5wSStgTjpTdkG4B0a9YSFbLMLX/DQnWShSocyJvQxSGgU0xD/hB9VhmLQy0ZqGsoNxwmiA9AUF/pAPWOSzvPjWtlFU/Ucs4L/jkRbVj0pzZM9rJgBw7OAiWzQMW7utf5IT6EaRapq8XD50fAVhwTYxhiCg6A8vCmNM0bSkxO8d6CALkibz06yoqbQeDBIaNTMMdyDf6EDuf+f8SSLipPm+vR/Tv04YyXsPEtTKO+Q9tP+4pSEPpDQgSfOQCsI+Uz8Np2QfRdvpD0B7874hTbi0lo81GB9RgFmM3uiWTNoQR4QUVBHV5YRkW4ksOwaJ7SIL7nbIey3ld+Xobibo8wA0zD5nSRt7q+Abi1y9b7G2ZbFwIRcbqu3BAtaMGRY7ZT6TVrbMTNBWoAmktVJbUgw7Al7Egti7LS0K/yztCTtbRrNUbe7746OnTXDqX7nNjQXy4Resu1s2ZLCD17324X5w2KYv91+0Dw9fvHj+/PBwb29v7x9//2+Ldtnr9Z+1D9nL/fZr//nz9gF9FrxiL/v7vb3Do5yto0WgKOzACZq/6xK/C6woewstUwu9oVagq3DLuhhbR1uL7TCvqAELWOgNtYDse1uAnhEiK7TqlX/Lc9JFOcBccnF98Cov2jHFGdJkIqTuaNTQ2qL7vQP/WXDY3tvb22/D7tuv4H/28v/bl68w2dH3BTTfLtR0Vr2x4btqCSRhAy5SBoXIZdddwm552DFrLnuLIhYgRyyb18Q+DfMbrk9HRhfNd8BAa5cAA35g4cMvNa7X3enr9pMfdranOT+kbvhWBdiwXbMD95YyGFNffgY/ktLB0cuXB7S/779qB/4hbR/Sg9ft3jP2on3Yf+W/Dg7oC/ZyP19pSgf5Gud8Va9R4ujXj5ml/xM0WpLuLuxt/MzTYoBC9YCN0+GnBGwtQAn3PSRSn9TwfW9rSMWnEcb2yK5VknF+gr7Un4D2v3q95ykT4dEfi2Hegmf+URWi+JTvJU1kw/JArc50Y2i3kDJoN5D8KxxBamj+P/7rf0h/EoZTbZpQhm5H/J8I8feWOZF57/WRoWzbD6M4YDNOYxGqlZ/DQm/ku1/yBOTgV6+e9fb6+4ft5/QFax8G+wdtyl6/bO/7h+x58Kz/mh7sHeV2DfsRFH7fjBOYf3fFM1jojcLHcyHosYk9qKifHEBTwYSKNJn46SRh31wYerRi5IbCcxOEy+9RmvQK+FtE3XthrIGdReSak4iNOJYj035uO3LNNVeDxHy4mMT8bLbEvH94sJzEXBaADxcXgMUNhFGqQCarAKy9LR6JtBVpB2Vgq03ICcFOCHZC8EqEYEP8WpbPbYKo8+jW/oBixT2lh+ySPoQYsDoj0sFslrgqjjiXSeirt8IYXhoEXDotL4w3CwKJEX6bs8VVzThvOLZivPMGI8uU0nJxx5QlIx5B5ykfo+ViwaHLMoRw8YBsS3KKfAGI21GZzu9U3XM2ZlDxJpk9CCsuMR0wqgoeqq6dGE1ixO/Zvpzzi9ov1i5IM4nZC1IdvuZZUM5Far9Ys6By9Hu+eGObhTmMr1nOwJM9GPM2i3K71pDyjGkVAPEzkGa5azlWp8cQQxzd6ZB3kzCUTt5JlMVoG57GDJ2brgVQIYztVi5vzY5Wc8lKwMX96k946mJZiGXzfVQEq757s4qz073OOsoBKV3h/5yHkxmYlCfBa/I82+MuR2Zd5yL2OYWf2Q8kyk6GfR7SiQDDtxo5ssRabxvnSkBBqKK45aBKnKMSJpbQW5YIGhIcSNRAsk3DOzoVZB+XY4asW8FhcqN6iONJGhCXJ2uZLudm1fVOmIQZ1ZDlgmR4XQVzI9iy/IsKv7SH08kQShgEuxjxMOSC+XEUWHeh+K2Ngkm6zmUxE6SqOrx/W+wUw6KP5UHQiOAd8zAXDveJET5M5h7NHzZQYOf2bcqo9eyKbAs6YoQK9VyCmAvComAc8yi1YoQhJdSfYdZlkCUYmjgGzBtDygDD8IsRTzEBQkdc2o6uRDzkxorbLOBn+aibs6Bmpj1lmTmG7OFSoR6wX67rSuy6Ej8dKD9zUN6o5El4+/Igi4R7XOVfREpvWDxJOxjoN7se61LJlH8Nt+bI8seEyn9/UyzsMgEpTv1C6GCQsIGUmeNblqjGy9Xq3xOsQG17TYpnxstGyiDCSWUMonQ9BmkR68N5BCvSJVAiToXzq+bR5uQqa0LHIG9kSuFcQaAacllU65hOw5iCYwKCPmHf8r7srJDcwNS2URV9ZTZdqpCG0hxfnfS1mbT0USWiNxJLRfcWJpiZXbqd6l5ZtXnoxR5Rb7hIC8QTHpQ73lfronAwHIB+WRoJmYHYux5bmOi0Clllszcl3Tx7qOuRuyH3Zb7EOBWlfBSthuaJJnJqzD/pkN95OoTU0uKEMuVDTzSNJ8SnEWZygDIvMz9Y4NkyP9I43kjKu3ji1Wk5rweHfUdZPB1yDhaGlIxl/nbgIQigIACkJsr8HG7MJrzm+RoyOxyw1wDsB0lVoVkWTomErZB/P7I2mU6+2Tj5JmPWRKY6Pw5JJ7tRoqPlh1qZB27hPQSe65nyjqzhtoTUs0xZuHznag7YHpSE++UsrwhXktY2vAaco6qOqj4aqhqwccKUe0gh/cbRWWONqyGvqrbZGqnsnBrlDLJap0caRLNkDPNIxO6YSEmfJyLtFNS9ZRTHI9KlYdgl23FCuv/U3UGjVNcQxrtEsBBiHqRuaxPFTbVSWvO6mRirX5e6sUUMN1+u02Jl908M5c1FcKlZbySDeDgVNVNWQHNZiQqFKtB9tCiL/jMRqldI6RDXoUc+fogsq+zlWAfRGGV8q/BKSyEheO+K/7nUu4LRxB82Y/mVzr8JiBwOoQ6U/OvV+3cy5ALEpC/oKvBIPPbkoX5VUVfgY8C3ZPgJOhSO5BCjQiNwKw/7BhsuCYkHcSKOCPvrhIZARuPUIyBfUB4JD/ApScXvWEaIRYH6a5B6BNIHBimDP+B/+A1+zSN9HgVS4IVzbPGolX1GlT1RcSSK5qYx6U3Cm7Y/ZP4NmYzhwf7enknrOXhpZBCNDkZSlSIluH7848uHLdz4h62jDzJb4cOW92ErHuMDHuG/1POjPz7I1Bw/HuHzHg06cTL4sPXx60dVZBJcMxBVw2WxDZowcvzutBWQNB4wKEXSIVDwa3/PHDXGzKtMSKu7we60n+JpzydB47KrKHFdsI/jIACMQo84Miq7NJy0JRgvF8tlCo+3xaLJCORT/e9iGpyne3N7W/HYgrpqQeqE5cHjoQP1h4MlYRzfTMaAwvnh3qoSbimJI5+pw5QYftTCH1uA6Ucwk0L3oz9a+tRaXkudWevj1+ZNakw29ikxHYM5QeIcyP+BnaJ+EMo/+Q1TapV6Pb8JOFeg/8RMIkB6hFGWF2UFE/7aIVe4ThlUGYPKq69hhxzr6y73InBQ8RJtjxDz9ghiFDpEaTR930eRLt/5iIbc5/FEWIKOq4qwEXJsou3Xj2U9SuIrIoPerVVpq+O4qrVQA+/7WRavM+5/b5pJ41g6ddKTyyUj6MlKtt+c/9vZTodI0wqh8HqUFRQVZeLaRIkf4tv1MnD55jWLFpYJVEp7FiUyG8q6VjELVD+D81MxGz41b91fHlMltudad0oHmo7EiZR+oaRadnKjiUjJkN4yIDMho3DRoHi1Cm4dMx/yGlVLh+33lySMB9zfMdgjVpSFz8DkqK5l35wDiTZhiSs5kavFBNaUDsCCQGXRbAmLBeWZ90jrgEEMgPpKlRpicLVOm5tk6YCMOFqXRJypyECOS5cYwJKVtBSgxfMBj2T4MGhLoxgurUdEPB5irgtqQx4ZJzwGG5BHWOp3dlCEAb2bEl2TjVzD6Ugu1yFQry2OSEDFsBfTJCATMGwdkSDhYah6Remvgm4VG+tUfDADeUmukUs+ke+eX71vFnHOL/HJyTsl16j3ND6O6JT0IM5GoIUDXG7jIW0feOqPZx4BDECljoacQol3WYmdJzT6sLWjT6kqPQ7S3UHKdsN0N0wZ2Y4mI5ZwX8a557LlLrDYXTip3Zy17mrGSrYVmVVvcZB43p22oe4wrFfaerKy2n486uEPKGF24b50PUIlkYZp4PjxtgmactGf4sXJhDg1jynBYclZU1aB34ARd8gFS7BQfYQpRykTR6RbPpuuVFx5KshP7TRhKM2xz9JVisDajeJ0F7bV1SjW9I4GIpYrT7iII7gm2FBUAcqPw8koEmS7i8UDdHe4rke6Ere7GoUpBrYL1uaRYJHgyK2AdEwi/CALfiBoqJW9TCHIkAj+JyMjeoPKOGQ3kCiO2lwIkGe6+tS6yqYF+PILmCTf0RET3eKZ4/dDRsGL277jYeDDNRE+BUE7CogI4zsSRySE9CMVjk+kv7g6Mx4wkFcZNgIkps0iPw6AELHPKVzonGkLpA661DAgdS+eRAHFw9/+sEXH6cGrD1uEhiLOplaP9z5syQQBJLkyj1xHq2AyQkoHLT0t2EwbK6A7eunopaOXjl46elmkl/czmuTELbOYKIJqs5jkhXc8UsABj5TglldD53F0Ekd9KIsCdgvj8ftkQCP+pyKDmjzGY8H8N5CjCJShiPNl4qmG5RRU28wv1JMOkaqFNtyxhej9toyZ5ILcsDG41oiYRr6kAPA+kuWr+BqpP+YwD9oAdqqCze/i5KYfxneW1hqmxaW8S4uFyah45G0VIA//LoIenthgX3xuAh+y3hD6aKXQ4Id/VFdmOQD0iUt4o2WleAT3MYS9v0Rgm9ZMxdNN85eVb4EtTDEtbQ0rcazmQ0Ej1cYZwCSdhkTcelNYZv8qm73uw6B9KXTY+LRHFGDxv+8+bElHL9DgCJhYyP9kSFjU9IWGUjWmuPNLqw0uG/C8mqtqWOjyGatTlF77uJD9biG7nWxuFhz3UzajmnzVhqbeBaYD0hFMIbki5LiAxV2k2Bbm/Oo9efVibz/rAwYn45HWwd7BYXtvv73/PC9y12oUrx9yDeVbJ1+ULm3WhpTego1OLeQn1o+ThS2hxV30cI7Ft7F/0H62f33w7Oj566Pnr+8JypUuYkFYFuydb2Y3/8EhMhc/KwBQMGTqjlwsQPk123SHnOp2NAfgbkuBAuxJSTOOmEfasigBxC3rNK+f40SqcFkInCcFIvi+zCMfcshlly94pZwInyYoZnULm/yVirdxwo4IXE8pPsJrWd6USlSQufnBLRdxMiUqugoLusFoaLjDoekdZKVhuBgYqHnIojScdsjV9fl/4MzXx/9xfk4SiDkSLEpltRASxOiiV1/S8GtLQzAIIE3Y5E7goU6gyBoMYeCg6HLAOa5n2t1/H6Lfk6ACLr8L9bFRUQxYSnkofVXYv616ahiYAhBrQo5VfqMaDljZM1RjOFH1F+bbOWiTkxRcO3lJCmhSdvL+t3fX2/+0U1wKhsXggse5BtwhRhUIxAHY4SQKofELElEucBMZZsFHoQs26dOoDaYU1eC3MblkoxfdcDaK4De3q5mk40mqmQosNb+ziP2kBXGvrayxiRk+JN/ySEuk/PNBPgav3EFnP1edyNXpe+GRVko/c54PpOpSwtiz6JaFEFOFStSJjMFtX2O/TyMKF2f4Z1jTD1DYhsfRjwed/cYmOU9ni/VKCQYn52qJ+icuGqtPfeYcgnMN0QnqAM1o5QNDsraGHdICC2IbkyNbUlQXWYUXNC5mXZvaWLbq3/5C8Cuqnk8YavsWC1SAnbQGQUGiH7C9oSDQ4BCujtQPCARPgmw0pknKabj7J0tiMuRph5zQCOh2j5Xtb7JqULexD9Bj31gFD9Sx5/soHfb8jat0OStpLB4n7BbiHjKW3BKkmxe/6ug1kd8BEnmkIcAky7TPw1E9LNnk4RQY8wcWQoNtKhteVRQFM96I5YehVgkigGLgyNSRXo5ApIlUXttULUN9s9vwbc/6YWNQxuMwwLKL2m8XT/nHHPBdjHAegAqbl7CaYiAZodhsq3uCD6UuAEaYkPvpGZiVuh1ynFe9EhMWSDGMBLzfZ2gTxZ7KaM4ik0hIzzULiKIT0mKeRSunQ5pi0y/BwV7cY1iSyQe7zwDdJdTorCZrEhdXeh5hDzG5YLXE2e3IHAo5FJqFQvfMblL4Y/RwM5IxVpfCY8tkqq9HKKW0SOXQ3H+muvea8oPqUnZkMlXFSOVt9SkPWaDi3m11TB9XllftDq+GNAmW398i52dUQ178ABvBZNmdgH09xKdKo/JN5muY7xhrJlTnaGxirVhxR5MIvHJPD+MrBRMVNanc9dLVMGCy6oO0wL+Y07bUCWgzempbpsXaaa79YO/goL13WOz18tUr3t1qGHnmEzxVqnqm/fUY8mySxhCVKCucgF8Q+VPG2pqVODV7G6LE2/sHzwpwshcuLrwue6zoktBZ7KqFj5pGQk9X5oTCMDa5STe0INBn9wRTC6xmvC7oNwFLIW+P6klh/z+gJ8k2+Y/t/a7seQxBELeyab0M2RzN78IuHNpi4EUQnNLU4mbLLO5YPUzFkRbsq6r4MghYqjRzsTuxNu4rsz6+08bZ0oT6NyBe3oH8FARsRn6B9Ji8KHhMrNW14BOz4CDXgVA4fP6ikbLr+WqoTBUHLNcmqwZbujGqfQhW2s3AA9YXGpVQJQ/iID2GbdVrBHyJctIiDXmqF/Oina64Yh6utYywLOhtu1NXVwR0eT/UJdSV7UBGCpT2foedmAEL0ub6vvYy26oHQPEWJKy+HrtBDzEFRWaCN1Roz20KalOyju5UpGzUNFolSAs+iMAvjoyEp6ENL3AkuZIjM9jhaFU7Gy4WhBTECYda6KAbsghDn4xIuDTGwD94zXaHysXjSuV+5YZK0PBMWOoNWK+AzFufN8Pf7E5l4y4Yd55VvR9kQTWe9O7rauL6Z0hGjtQY8KTPsf08XuQdWoYsOSuyxYXlhywaoRrwbgFMaInruE5ov8998oYPhim5SOI09mOoTI7ogtYA8tvFxdnlyfHVWYdcxKpkkYxKOCInb86OLz3yy+XZ2TuPHL/96exS/ad9dX15fnLtkcuzU49c/HZ58ebMLI0P6n0x0dVWWwFmssFsMg5WLmjYwWy+uX/w7PD5i5evgFUdlv4Hnr/eo72Gc/Fs+UttKSPIfmmlu4ArqqasZYFGmbRlAiSniGuV1nN70X1Va1UWfVFZPs89nk8ty/sHlEQV80I0fbBkSyuXvVe8Da3KVLostIFYlUnF+gQ6NhHf0/mUpAsY3s2JiYAfgKyCoYdFaH7LftQRjWold/EkDAj7DA4oFX/YZ+S3yzckZNEAElphUMbudQ15aVbX7l1chzYQwh6k3Y2mJIiZkLdVGqb0Z42GC9t5+vvlARrSdzrFMqGVAiYGYNWVvp/2ZnysaEa3oYLZ7GBJZMhlKJSUAAFAfgDVwoi+wYqMF9K7DQePwaJxvw8KCxhFM1CmQ9HZmgsIjeak2Vsfq3o2675tY5Z8eqhvlforLHmiZ5+hyU0WIi6dwapngnYlwZlply8XmRv4BxKDO/qOC4ZCwTqQvwkoCyG/Aa1PXHxisO17gC13xRdc6DitDswvuMwlLVRQfAikr2lXoYpjZIhabmBhhZNBOzKOsnbTTOmVQtUggw17RYP3yk1/rlrXxtZAfHTVD9dZkWtX15BHVJhdm+s4G24W6MqeljLHZGLNtqjWPszfkJsuvYipz4kUF7LsHBkyWipugfL9TqX8PdHOtjQet9/J8vqQeR1g32tc2kQaSTa4EFZ2Nj9NZ4S6aDhjNHoG2t6UtHV6gYSijninbZ2Cp1yQOh63AN2WR7IKHMVfPPl4Z4FNf8s11oN4xKiYzAq+/h1Eewyfg1ODWFTEpyPjg6JFtnXCVxLfgc9fWp13sBRWwbDaItshj27yMNdCdOuOyhcpvYLJD2k8Nm32U1Vygfopv+XptNUcBviINlHmSWodZmEMs45L4WHhm8VAopQOfpvkV7qmfgGWRitklxIqROxzREWVJAVRjnSwiylLaPnC/FUIeJIjFGL9WDSpWwCA8Q2RzDprPMBvva76S7R0wb6+Lo/xfZc6z6hhVrly/RXmHehXDfo6wbtqb15nYlUpnWkX/gc7Qm5rh6DMMTTymPb2ZeHH/N9mXtNS+UDrWEWe/Ga1WZcN/hXAf1x56lU532nmNjHRydhmJfFpKWCvZRkrhXbmpp4HtUHutzGpIyxooOSXDAz/+Pt/S/kBpBFB7oaxYAU/NjorFah2454y5Fpz/3J47XTIT5DerirwKtGE3HJ2Jx2vPqbntLP58Osd8i5OIR0IJlTBnzqF2lxSK1vQcSrFKDWRtBADiHewIAS+OYkCloRTIDy405YgPahAxoTKsmtCGgfMxYFZL+hkeDwX3XhA2JdJwHzA/25Qc4PBU49s4ewk1rf0Mx9NRkYCpdkSUOeAyEiRSRKR7f32/t5eE5dZfka1kSzJMFPZ9ve8rZGcFv4B/+KR+teikdNaWgvKSVCrs6SaRpcmIwao09gY2lhUb2phjVsGBC2RN1mZTxugUWULphEdcV/V8yU9KiRiGyvVRrKFQ3G+lMIFLMuf0yVd11XdEFiy1tzGVqvNua0uCCxeUA32rvtopkpIOmGCVk6C3ik8PvZZRTtmqRWZxbm0MOXmsASGGOmUqqyN8cUjA1fBqqI8oYr0mSWsIBAPbSoqf7c6umjbmAW6AuLp1Xsls2IJqM514VwXK2/wO58vI3dFLOzQUM3iGn0YGED578BH7Q1GBL3Nitjq+eo7Vqo1tYTtvY30KyzZgamysUWv/YzrbECkYUP5fsDmNJDkmIYsST+xCFDV8vZp1iHnSB5SW7rT8TVpxwlIMgmZkJwgYaP4lgVQHeyOToXMf7fE0Vb7A2VrSeIwnIw3ZElKUv1ELfz5BH7TIqtI6WhssbqDce19FE7zGScijUefpMvuU5+xwHps992lDAupnLitL1Ml2NG2nt8iDsFoUC0shSrKeUCavLtauK5iWKTCTEtyBtSs05WZbTPkwhP+8EnfjeI0WI8kK0GIEeJYb3HIzBg4SUIsUwMANwTTcClAMB4CHQynkH0haL3+pstQAabWm/cGSnvLAYtdvolgySc2otwigZ7BY42SMBAE38xAmGGUTd8shsvIMnwGj1JF+o2PF5C6TIRrCGEJWwu0qQAuizCGgtJzJ4+uXR71tg7/4z9gmv+dsP7W0db/2oUYqThCCSsTHUoSmFRVxKfjMf/L4UnIWSQzubeecvf1Ti4frjgyR028+0XeMR58lWivE6qLYq18bki2p0zlSuayrXwEqSYlOdXin8WhwjYWjGFQXVeKlhsn2+ZWMw23xiWcGRtD2XLeVVReLIsM80nZ5jTyDAOi7iRUuZpipOfh3qEjeZuigi9BozaKGikK8tWbRz9GYmrSkF9YOhcBybVHR0DWSkAujVpfBpBXaQZ3arlTy51a7tRyp5Y7tTz3CjmR9DGLpI9AbQbxFFMvU39YlVPxsSGp/oYoWpBV5aO5xFU5VEpRA37LIu1iB2989X0nuM4WXJEM/BQHUxkbsBpRdF55ElmF9FQuyEzWJE2ufUF2QUgJVvBjs0i1UQLR2oE1nxSyimXUCyGKwi+m4SlG7DQ9p+k5Tc9pek7Tc5re+jU95299AH+r06cftT69UZqzvMSoPMfC4uOBp051dqqzU52d6uxUZ6c6O9XZqc6bTtic6uxUZ6c6O6XOqc5PTXX+5smJS2rZCRuH1F8+RXFXUg/EmnnU9BM53FTT5aO51PQreivbD5uRmFiWgFAykaJFF3bW7ZBuThq7ZBiHqiZCmZ1jyzRi8P+N1O2fnkatqimo3hkbqGHPXKDTuO8BvI3QwIvcQ4lXxml8XEZF15KeU9Gdiu5UdKeiOxXdqehORXfK4+OOY1Zq3sJqYkLvdr+o8lU47Av+oDOBa7P33mAHR4TlJb0DeJxeVXL4EnqHpbF0cWcpcm3L7o/VIv1yTlnKu2vCQdf8hvkGDHpsdn85uyZ6D7r6VnEj6sd8P7DX7g7hkUgZBUKoDwd6AsSTwZAc7B28aO/vtw9ebaSSWSoMOZ8DebEFmO/Ufz4Hc+MCTrP2r4ssofiWVdFeRNwHnJF4t+rCffKsCv0js2qEGe2E9nO58NpMZvdfv9wrlyLWXXab3/zyYasfxx+2jsiHrR5NPmx93cqEx/qlZQ06mycfpulYHO3uqieyG17Ws7D+PWotEmfy5HODd26pfWZrkl9w5tcHNHK7qicPIqdU9b5NkVyMld1LYJEcvpPQuxm5V+3etK14x+d2P04GrC0mkZBSBwaMYU9QxZWLZPFzW4CSGTIh2nrhPI7aGapsgSCxpKCga/iaIsHiwhV2SC6JVPMUV7lkfZZAlwNLgZVLVOQUT0v0QDFbrJIvCvMdrVJh3VeryJV16i69020S08yqoV0U/iKmubAstv1kxCtsebKwgKXfupd0o+gL4X2SYZJ8yFSH9BXR6jqyWB5XTyPLTRXLfaXVix8bCe2ck2Rk3CnfT0L5fjg1W3OtjNbNU+Hm3jxhAQ9txhYsXtrjIFiCJ8xHwzXNJ9vdi/dXOT8tDFL7MDRsR+Qf1lcsT6WJ/ORU5ZX6v/bh4eGh8T/7B/n/W9ZeIgvqiwv74RzrcqzrO2Bd39puvBBDW9qCbGECM5iZZF+KpeVv26KONEsr9iGweH+ZIAFPmA/qTJF5gR9pOmakaz6Gjp1d2YOBgmcSviK/lcbFdrBDHmZNJ1W3BQEeU6VCbiSXWxuLQWhA48XqgnRfEdnyD5Q+E3QdcqWaruLDH8n+0X7hnDwymoQpH4cMfxzRaFo59jrSlLUMm8humxXn8ohH53LwvrKnYv/IeuOz4Vy/GzLs5cM0EtAEmhdCyIvtUxKXbHMDYLRTs4hx2NuFhyHpyQ9JC6gemxSvSJncFjf/tdiQ9Hpq8x3DU5i90M8o1R5W0mPpHWORXiQ4ks2jtKxBN0aVwm3wKY2BM9GJYMEnbFJD0zThvYn67WOZRmdA83IMs2zEPLoFZA5jk9rgYVY/XR0TneN2GIDUzTGzzj7jJIZFmXi1KKp/9QxOXrMEOUB1xTQJJa5E9atJY0BGDa5tbJE1TpiAdfM+EfGIld6WL+40rN0KrOZ7YoKrtDxfh6Uuej9w/xahHSUVJY8Q+VsPAinuhtXGXPLreX8fGyXA79RfwF2wsw7iZKr3KkUl3KWWl2ZGOGgg6l1ZxShDVisu49fJiEbtrKepZe+wrlxCL3cqMqJ3CpS6HvfMe5dhVwGwct1N1N6CRqezKfr5qUHJTbRKmOABs8YkLYyiSj5YFCMl+Vt0EwUe0rCLJTjSkvtYkvNofpPz2AdhMXYOUz4Lr4xhNZqKgf8nubO3FGmXNQyzEF5kAbb7YesMZqg/xU/8PmTpkCUNBCu/zlBuv1oMvBokV6+uaspi6YLu9Fenv95Xfy3L/yvXXVM6aCs2jF0QNEv+BBRtHm/dNR2cqHeaeiGkdED03A1tEMxhuoC5tiJunI5pNLc2oda4jms6IBpeC1tVrS/fOz4I1qx5oO6NYJ7DCmkUgqc5Aujg2eHzFy9fteGP0v/A89d7tFchEDito7guGfRJQXluvmaQ4I1zLMIaOzmDuWfHjAKzSWXwerlpRiOnyftl1HEaj/AI+tNq3U+myOhiSwHr8wibIeMLXYnEXcee1see1sSKsq7iVULxtQQVy+86j6iBwvjQPvZrPbQuaAJtpX8GxDoFtMJm0X98lDiGOUQF1Mt6OWtgYPtiSGIBc1QEN6/BZGDrMCZXVtdfrLQw3HU5OUsletQAcZ3cXh2BY0dPiB19M2VrASY1T7V8AwBNNf8aGVVzub8C8wLvRMiw7gAaK9H6oUZPIn9IowHb9FCUjeNQ63AdLsdUGljIe/yDhoRq63KJaGtbcof8Dk3tx0l8ywMWeEQV1VD9rD5zgQmTiDREfk29Eo94msIbhYFyCOFCekSSYj77OpjP/YrRORnCyRCzZQhnOHCGg6cC5dcOyo9eHt4syVdXu17Cw4DQbjLqvIHWzaaQDA8IvlmJ2+YilcxdfbolcKCK5BaMJv6wC+ERIxDGkfXf0nDChEe6mu39NuEBjgn5iKfKqy904FvOHEG07vZ5CDJzl2yrKlyI4TswWv4E5iPFYMXEH0K9rm6c8AGPTmCByfT86n3XI10K7FyjAjwYxSm/ZV1kwt1xwmNApm6HqNfU9AJ2ysYpoeF4SNsHMFr++Yz4cQAbgyMSOI0fj0ZxRGjIqWCiQ67pQJARTW5YQK7fXBxd/HZ58eYMI7huueAQ9ICRLWlMiji44QrDWDpd8fO6FEaFZGlvcem9K/7nUu9K3Cq/WVz/zwlj7ZR9TomY9FQtGImIUJtH4yI5fneqRLO2FLpzItkhV/gdSDSjgrV5JFgkOGBKOIXMAh4w0oshXe2aDjo4XxcxFQPnWMJpyP9kgfw5n7crkbcXxj2yfcOmwsvuBbxMoyhOpVd8xFKKRQtCfsOgkk0fggF9tpuGY8QcGoZEAgNIz06HXEE4aP5pCYA0oQGL+328D4iQvwBZgmI7okv+8V//k4MIthoRP4mFUKuMJ1FAgSR1tuqRxQF7DcCeraT/ZujotffH8r4iZ80X6CpNJn46SViQk7+s/mGm537Bg/RIPFaA/ZqrulcZsBRVPkIXpxroZeQdYOMR4+seRDSz9/1TLvz4lgEDSMOxZxyKRwo03COSgntEh97wOHqfDGjE/6RyxjIf8DRp9gj7nLIkomGW0wQUfCyY/4bdstAjIh4PQd+Wgpl6SH344OkkUfNrruGRkIr0irFIfSE//g55jzw3TsQRYX+d0BA4Rpx6ukiV8IhIaZKK33k69AiLAvXXIPVImMJ/GfwB/8NvGHhIPNLnUSB5botHLdQse5Pwhry/xFxaHkG5TBnwrM6KdQYdfaY//gEFG+D5h62jD1tlKH3Y8j5sxWP8jUf4Lzy8D1tHf3zYOr/EJyfvPmx9/PqxQ97qsGkWpYDFeG2O3522/28MzpoOeUs/k/297Ocxg7hPFIQ9MsLf9tT1xN9gQx1ywRJFLqI4ZeKIdCcoNUhmLCTbbEl4tvBWIyC2pf0t1iDH0ip35C805AGeGUZZ7uCVRFoFNQQHcAqp9DfRKI64T0MSxncsAaqEsdYQltibpMSnYQiXYkShnpgQhHH8IA7cVlTpliX560JncoPaThMu4mjnB8KjgH1u96gPkkFPxnf6cTgZRS1Bfnt3/u+/nQF+iDShXIVAg8gYBXAx4bDV2jGC7h9//2+ktwkTcYi3oGMRgaCQlUC/2U/tNGFMrgFnk2DcjeJ0l8O7mTDU8E40GbGE+8a2ANURGFkRNtiPINsNohdL/c4OYkyZAeCeJxF+kAU/ENREIjiBlIbxgAj+JyMjeoNWNA40KoqjNhdiwjqkq2+R5BZVkqzv3i7Sffh+yCh4Hdt3PAx8moAhjoKrMgqICOM74GkhTQZMiasE8vg7lpklVgnkgUOGhLPNIpAUAwK8AiiLnRvgVAY7AIlXsh4E+IctOk4PXn3YkqH6NBRayFa/7H3YAjsS8ks6HjOaFPJFUjpo6Y9AcbmdJt7u+IDjA44POD7g+MD3wQfmsx7iRbT79eQdTWO9UsC94xCwHzhIItK2H8I9cbwAecFxiKc/HsdJKkyN+F9u2PT/GMYtCJM3nEiaQG5r9MJThnpB6gdDv2UB+SIBbIArDcdfiRjSMRPkllNy8v74zdnVydmOVI3LK+mAHrxbfZzPaKxV5r+GU1i0oWOLSU+ScIuCa5qdca1gJI7HFoFEoZUi6IvwvOav8shI7pAEEFxTMVhEB/J/wFyFpuhQ/slvmLLgA+kAKSrj2zhXoP/EuYFFY3q+3F/dzvDXDrmSNFMS1p6qrTyKRZrzsg6R6Uzwi2R2mnvitcX7TKPp+z6aDQ2z/sX1wStLgo4x5nk11eNLTgzySatTlF6D/RZoytdKQowkJnjaVi8C+zwO4yDzVBp2EH9YMSCWErJhCLAfoArTDmlBnnV7kNDxsCUZs8iszpiCjXEe8HM7igNG/u0vBL8CyU4RmoCUoKI4rVCcCljvD1DbORQEeDjchQiSkkICRlm4B2OapJyGu3+yJCZDnjYJ3Ru+7LqMqHyV4JpZOMIwvkNXee5P0GlBKMuMkxgwAmSZ1XnNxnTAI1oKDagfyyyGaS+3Zdt+TOOUhshj6n++oAMmrDbvUuLYQOaFZaZzY/LCVHjplL9nPoZe5F3WEIDikE8Zb7FBrhhdUIZkXcHOLLEOK3OqKqH43zYMwpkHCWNATP2QUfh5PEnG6HbDcf+sxhWobHPiqhz2UW4wlx/qQJCPuA8Ecq5px4oNBVBReGnCruqUpZfPIylhLTGJJYrLNFOoMWT7SyZV5jLKfnt/D0VH8nWnQy4mvZD7RyRBKiSzuYFaar+qLEc4ZkmboSPw+s2FEnGAUG1rBRZHpeH4iEhgI3VVZe6lahRH7ZOf3787y2ZeQNa24kreuyFj2a+8rRH9zEeAI/t7WGpC/cMS7TNnzdzV4pxlHTU4aK7kZxr5U/ITzFyDmjahoUbqt19r+9jv74Kb6tecIXEFZ9QKAsS8EuhKkZa3GHAhAwnzW70N19q8Uve9HjMiCouqaPO2D/YODqGW9v7zUi3tGWGJFRX0DdQrXYxcVtXYRsqphxcK930hkyQs6OJzkc756VsjIExI/oVFAQZOwuFA6GycVC8ixComYfNEljriu2q6SoBiEtYpJWXQWsnFjL1vIh2o7NbWDUhx7+M6fvz+LmJJe5zwWwiyF0tx50sDtar6AVopVFi0VILEkCYsaGt7IDDdGJZBMjXEMd31Ml2NFqczaJu2h1l/lHa7hp++P76cmx6tYMl//g5BUzLiVknR+dV74qtIPrC6k+1qAN9Oh7xDuwcGEaUxmYzHytmD1YagS8s7CM9Hg4qsuaaimrggvZBGN7t3Q54yMaY+s9lIKpewvPCnenSVrdcepbaX240s6sfHZ3eoseaY+64Vh3RmicXybyKkzs8dUkGiuJhsYiBjBiYaBFymLF0Y367p/GfxdVipkGXcU8Xp+rNUy6q4xdohwAMNCEMaBaEMkUxuVBvhby4SPEz2z1yih/ROwFiWiKIEUXOVVBZRrWBSGq7i2Q3br0s92sh0jUeUttyUsQG+9eXyNXa/pHSwSAmoGaWfZlR8ejyFnjRYZqYoL5OZvO6KTq6QkyOKLh/zKbGeDWAy81VtaqrWNKNIU01tJnhWTG7f7hr5NztPN/XtcfCgbxBU4WIJXCyBiyVwsQRPxq3hYglcLIGLJXCxBC6WwMUSuFgCF0vwqPmyiyVwsQSP9ehcLIGLJXhqOO1iCTY4lsA5Zx6/c2Zj4wLmrGE+o3b5EiXLQdtJDB+B6RJwTpcHrERe9ZQ0ZVYvpFXWaJIbyu0qVMfqQ3HAMYDj/CfOf/JITDkN/hN3pfMrXXZ/VBkUvES29bgdybBkgwjVX8TLm0OYYRjqFrRvZdmrUo2riN1llXdaQneV2D7c2wOLxYgLrDEDJU9ZiiUiQFkEw0YU8uiGbMOyQibED0Z5GDBsQENdWEn21Z1m/WT9Xh3yHupMp3HWLyMD17IOH7sLp9I0GXsNB3oI2QZD0n/+53/+Z/vt2/bp6ZwLcx6h78Uj5HwijpGu3yfimG/OfItuEQcZAzIWr4iDTw4f09VQgYtRPe1Rw6XZ8VADl3pXxImlkiEU6W/sdpb5yPJmZ+V+amOW9ONkBDHLYkih6iRqjDdsSkYManWC+CUrYJp+t+1JNGIRrI0FBNoEKHkZyvqB1AqCLy6BRlDwlN/yYEJDGJmJw4HKpEmHNIUfOkaJWZJMIIzakLhxMYGq4YYFQKmutKaapWFBWYADbAUF8rYGPH6X96vbgDKSIcf6rIt5auo9M+6i5wg9hz9Gu2EaxHlygo4s0mMEVy3lL8Chh3feLOREuW/nPxdh7iLMXYS5s5A6xW4hC2n1WrsIcxdh7iLMnT3RRZi7CHPHdDfGmlrz0/fHl12EuYswf6xH5yLMXYT5U8NpF2H+CCLMXZElV2TpKUD5SRdZknTn3rX8dsGH6GMLLwB4U8Gm82zkG6giaCYBwAMZ0N8SxJixHA0P46QzJh8k3ZQ+TZKpnMJTxuOsJmaH/DQlAetTdFAyjFpDIIV8gNovNEsXLCXTeIItC0HsBPFStv2DvlITwUhXDTsPRBck1ZCjYwzbYmK3M2gUOGY+73NfTylQ1CXCj8dMd0M7jmg4Tbkv8kFBHLVSKd3KrAYhYp/j4gW6VOErXapf7KoJdeJDFOsWWi7loenz+QE2t1o7Vfgg+4vBsSK405hsJ2wMNjA4D4SzbGWnusTuQCNGEkdgd6FRQEP8Mz/7I9KiYdjabf1TCwa2smtCQ9nyDxAPuwvb0FOQbS4y5PmxT0OhvtjKMKM0Da2iWmEOAOpODUZCb1rCPo9jUYOT5lc1JtKIsNE4nSp8VM5jbOoHO29qFOeAvkagL2K5tncoVB3bCremIkHkYmLhPdXibeF3MyJ/DUNmTWC58AkLQbg+A9bVfOV/lt0+DbbSA3ji6wRZHyLmttgxmkJLVAWO0WNZ5I58ERAWVI0MZ4EgN6H/gy3g/qgg2V0zPA3nhuKO92+1rszWBawwgOHHkVSusy7dLbAoDRj0bc46dRujjGbdc7aNfyxbmU9Qr+t8bIpXTT2Q7dvwsFbwPF1xc91a/7t84VXx3qW754ZxfDMZw/lMxrAHoxs7TUmMrZaxd7w8vqMW/tiCYzyCmdRZHv3RYrc8BHdVy2v1aNCJk0Hr49fmTRq9dDeuFW99A964r1qci7wXrx40b1NeMOf6PJ4Ia2PeOoqzSHPdhgr5Zbq1UJlRqtUGFmAfcQBHTpJXqFQX1aY5XWP1vnFvC2JFaSqFXNZO+YiVneEH7T3wh5ec4VokttMBrRmdn8pG9Dld6LEwBiRJ4w45xxK6LICW7Ag1m9/PckPU7G245mCw2vpaJgGNNoQgHlEebSGW5HzeYsu9NNmogNbs47Hkk93Cm29Ao+uSbaUrkoOdDjkZMv+mNO5XKt7GCUMtMGAp80F5VZPC/n8gY2gLb5n8x/Y+vpUwCGC6Zei5l2XVRws47s1DWwy8CAJI4rK7a1692NvH9vS61ntBAlGWb6ALIRtQXwkowIGGfCyIQlDSY33QZPGdNs6WJtQHkyu5A94ZBGwGg5CxGy+KsRsW6yl+YhYc5DoQCofPX1SsQDk08/lqbE5VHLBcm2TCtHOgcGMAP2gCT8goAw+aL6ISqnSJJv6kx3yKxgcboiqUg3MCtOuQi3nRThpBioebH0hmL1u09bKOSaojJyCvaszCSCI13pO94cteFS7IJFJjwD84l3uvOZSq1qbe7HOoIoPd35DQPlh/3vDBMCUXSZzGfgwB9YIPtC3qt4uLs8uT46uzDrmIhSwaLmWSI3Ly5uz40iO/XJ6dvfPI8dufzi7Vf9pX15fnJ9ceuTw79YisO246okBvFMze0jw3usJM1sCdeifE0pzlQV0XmcTRlkwBRLU6b0VZyNTCZ85eTYBYKcGT7bVeerVginVNhpyr5+lC+bnD5UfsUPumhbE6BTK53t5ZuwWJe5bL7dIcbPe6gZxVnLPe6VaU9tHvhqYJMKYo1xv1k1hoF53NnG762KTJRvvVyl613HrepWHYxbDTrmG9l5VAAPtuaQj20SFL2I4cxj6PaRTghLK/CytqM1HK4XY5Z9w3d8ZVXHF1s57EoxFtCwYQhTMM6vxFzh/0EP4guxOg7vBmGstlcpcg24KOGBjYc70ZLUrycwskb9UYt/HmT0HyJ3+TNYj+ZsbB/42MWErhADr/csOm/8diwJzPFv3/2XvX5baRLF30VTK0d4zl2SQlu2x3lSv6h8pydWu2y1bbrr6cLoeUApIkxiDAQgKS2Q5HzK/zAmeecJ7kxForM5EAEjeKlCgJsWd3WUQikdd1X996hEmy8hHVg0LUIDK6FrqvRgpW4um2ZjKGrYUhNtmO/4qBtmmMsIpAbVXit32kzESXRXNw1fBb1mKq4oRtHe7R06detuMONuP8mBMjWZdG0WnDc4Ykar7y4QHbR+ZuOU5GcLsbT3f3m+lliYyTrkN+N50CFaWXKJ2DQ6r3JWjTYA13BFX38++W42pngsngX5A79j//9f89OTwcMWNvfe5OJVPP914+fV7I+iim3/ez9At/JiSQICL9emty2WBEsetyhBKFFU20OUWgTuauRuRmyq5dkc3VZrcHf4/29MSaFI//nYjp3su9/3UAFz6OUAKl2ciSfDom+fTsz2rdXuNRx4M55UEo/A9znvj1Fox5bj+tWh1pM4I4el1WlfKZK4yJ9yRrufupCMubm7ctWr/2Z2JP6TcNutJgNBkUzespmmVFrUXXHO0tY+nQDuHXsnr4Cq2fBf2QflJAy/anK1oCtQT3qd1McxN4HZJUIxXHElthLmz/POXJTKQgkp0/BueIpfsp0Gdw1BkvzTnkJ9p66IVIrwR4Da5i+BSFTKA9PFtCain5DQZFrPj5rQFBN2WRv8olbemBfn1IIoCT69cw+sNmr7UdRgiukURUTBcsia/YVRCGEDWlUsr2w9gzUON5pDI7fucE+lwE0RsRzdI54f5oqd5xBpKLIE14sqJ4ISP+98U0okvimnDRpwatlNjZYdz51XMdHuwrxcik3+CQ/rYHHjm4WZwCgNh+ymf/8//+d8WGVL2CLXCpQkXoGa3HROypndjLZXynd19vLQ63Oa9HYU4If5zG5SUpsRlrfawtGBVcxvilT+sACml3ub10NyBdNjJaa6VcOYM5u1W9D56gQai5KaGG7suGTegHXxMR0gM6wVh7vCIy0e9loemYWttCE/3URWg6VjB71aZ2gfKJLfoA/dUnRsM0SHZOg/NfMjRHnmtAvUKXfiwk2LXRXDMIRE2f1wei8fMFrtN3HM6Xa+MucCzOPJbuaSw6okiHhJd5TteR9+nTKXJ2ZZBXcwx2rh5kiCBTB/4WTDHqy279flD/7zun3DmeqPhVh9pLNs1pqcPUzLfaizIV7itYT0PBL9UbMd5q9UYWqVoP9Vxu4FQDp7odTnXTxpFfFb5s3mZCMbEIKlFCQm43kzg8APVmCv1tY5+o//J6WCZu1V1/NumiwhcV9esg+A4K9yBGrB96+TZO2c9xFm1S/Hywa/yARLVrIW7oLAjRGvOnUbLrw/2svupj/dS4HsnSKypmj+JxMMCOQndMCtMOS2ttMUvXUli5SRgsLdjmqETxEHSjFC2Aui14kVF3POL6gA8EUvsZJP5jMQ0iFBr++QmiPkgiK6CmYVARZk5Vk4OCKWCL2sLBBhz5pYE5UVdvBqTLna6CW+Cgz6XW1tkYRISdZF+mwMEdss0XWMU2ItvzDxx81Re+szX+DSahWkvbZo/XX2D7lL/6uMoA8XfF5Oz1oNCCfLjKBnnO9s+PX795/fE1s+Y1rp8WxjjIFKPfj/QWAbR2nM3m7Onh0xfjJ0/GT7/fcVZamFSr9UPvz1pmkMrL12LTqAdmga9d5sqgWzgeG6SM2+QNA52/bVVwWOVNc1NfLBPhEXCtIg3b5a+1nNQayUYY6IRYTgdjPraIk5kYyyySpOqh6ojJ1oo/FJOtv4wl2DehcvFYDzyIo7E5GnvA0HoxKo3iYLOkb6N61dPBjFMehAVm/CeRboETzwSAdpz/6fXHgQffGR68JX47qLv3Qt0deO595rk9ddpb4MTA5bbGhrszqhoe3Ojqr/DhNmf/JlkxUQ7gxqdHH1/9eeDHt8qPt+HBXo+FNjDMdzoDz6QHl1hUDqRZqpCciGXIPRVXYkorE2Alfa2xBjM1KRZh3i6rvXbd2UFiGiSmFolpsAUNtqD7sso/DKt8D6X/XZLzMy0bb0nU7yMFO4X96zrVsHB6a8zITPjIpmtiRqjuq+qqLmTEakOJvyC7lA4APmaqTqjSJxB6BANJFqC/qDawP5KwnBQ0jB1rcrHSwoDMCI+divrpcoMTdqQLicdZKgO/MpJEeCK4FATPssSSugacHYIvIYGyUHt3xHxddhgBckdQUsyuoTrSYkpOKkalYY30l1QtVoKWcBT/nZA0lE9P1/e03sxLZ48Yleek7t6dfnj9ilHVM0jDVMLvjutOt1FeIkedry8LkQgxTsUXyGS9oGGrYxpH1kll+x/5bIL9PW4s8rBed/XLpu5G51oMGmapbwUDGJSc8yVCM6EWReDFqijA0enJhAH4TRxBqaSX+p4qcnCxMnVAsTSTGsUf//n1NwLm+W3v5W+Vupy/7Y1+24uX+CyI8C8c1297L//5297Je/zl1dvf9j59+wRfpw8oeP8FX2FNDC5Bt4DpUunRkS48OsKVHlEp0oBLto+FAH7bCxIe/bb32FRZEFGKpg2rxMKIaRx89TV4Bkj5Nt1R2UucAA10bWSqiwyjQ8qj1ik2ORQIqodIS6GMFbkYGyix/XPgFOcjTTVH7NyGO4a/cTJ/Ao4Jv0j4qbyw549/VB+G8wcnjyXC5x7Wc0btWSOJPTs8nDD6Zn50PE8sUxo+IuERQpXC5wuic7umwKlIMDkAMv6jOAWM4+pw4MhITHj8aZwmAqtPiC+o51HfB0E0YecaxUp9qTxRg5l9AGhYuIah4H4QzcZXQeh7PAGrAI+Iq8gwvoKph5DUrYDSAEBZThw94xUVEtrDnRmLCMrZ+gxuMqKwmdtMxVgIA5GO1QVECnM8Qfu/7fFl+vT73/Zod3W36ufD3/YIy/kiTucKLVzjYSAqGpVHo24h5KaR1AyXfrj0w6W/p5e+m5ZaV9+Hz5qq+rBpkMh07IVQS0CLxHAaRrrcj336yjIyT8W76bGWlEcsDZdFIRmpwytjuTOSay7OvktmPAr+xanH8sEZ5SKwFpzfG7kZCJmuyA57VKmLjN8PLsVxlqj+dXnrEQu5TD8IEakv5GcBlgb3G7FMpCXgKxTHXDGJI1fFaKibQ7uOu5zwK1OFKPKZKdXMvtICW8uVhstvRIMluww4e/Xu6M3rD69eP1aodKWRTNJwyQ6qP1sIl/lY/SARXhqukBjQGMDaLrOLcQMsZamG0/q1md69R74QACWSQTTT1bGav4r4lTtXTgntz6BfNBRWMtWUOhZRomrMrgJKps3zUVm72RUAzWsXXfocxVcRQ6OEnLCPFWaq9HeSS6Zg+6ffl0kMQwri6EfFjbX1xKj8wHOUHg4kXGzSkHhvC0P0rQRTJLNOr0ixyXUq1u9oSfoCq6tbgrzFdVagmFdcPRU7ukBFPtt0uqpdll4+URayNTpxOLZt9Um1YftfjQCUs9Mn4yeHKOWwb48n7BTJykslSguUsKDCl6FBVJlaJGOBesvHN6eWUL6vtQ5slYbLl4wWG+XaRCziS0Eo0lEcjV/9/O7ta9NzD7HQeVbyfHLDXb4v5JbbULuu/O6aE5bDrqnTtckz5xhHh1pBP/PIW7GfoOeao+nibzUCqvtau9s+vAveXIvLGSWgX/l1Y+WjmjAX3l1ithTFVuS3eh+utRuLer3r0RJkUdSamqdNpfGeFEvjdYjUqGhLb4Loc0+aW9W4Gimnw7MBVDRLwoLa2Il09qiO2LQQ9kr+VUQ+xpKg6yoRoN05q6MlYXNH8zRdypcHB+oXKD52oLqrxGwkYZ38XF5aJ7lomfsu0oHKbB1LrP1bR3X8+B1I9+NlElxC4KJcizu/t44WQhFdYXSROmGoUCtnGTkw5Zwnwh9rxQOYrlY+quVNB6a7Baarj8VxC23TphvnQzIxNTx6eHw5t5I5lyV//ACXpmRvrJIiqJOrPRtgEmb7ys1AbgV0NDyesLdgAg+hbCnQm2y5FInHJUQcqNpXefFOhUGNg4B41IuQR58PruZBKuSSe040pMolLA/8vm5dZeq1W6lNu24ji3p49+wONdYce9614pAOtnUYqe0DqRO05hzrmRXib68NBeYwyzupkKPdfT3T9XvpLjPMZ2MK8AEDwpxHfkiRJAnU2G6BP78ZkeBmAqI7iR5kSIe2IpFFCaLmKqnA6lrBpIISPxvq494FBJa7hLxioi23jLqiQNXhgDTWitFW6rY6Mdp+01AjppDIouDE8JhjiCdmfVDRjmLeB/htVL5ZxOb8UuxkSOOOJV71ysTpnIrVmJoDW4QRDFaKDgaFyECmFJcDARU/5qYeTj5AlEzw01vPwyqSGDuDZr0SHkNu1pCbNeRm3b40MGQN7ZrMdX9R765Vjqaz2NUsbrVIWSqQ0LZwJzb3iuHQpajrPyxhqhqe0hQt1cuUX2O+31ETQ4WEOANXhsWxFmcIWhmCVu6I/6whaGW40vmVLsecVOPl4SW2r9s9VpXZjL78P//132Q4RyQRqOx+nq8h1rO55GFAMB58BmHIaVFNeiSLiCX8grrRhvhA4hAg27gU+E15I5iegX5rISCTedFsBN5+6IxZm3WDaNxhMZUSLwKsFHlm7j445/7xj3/8Y/zLL+PjY/c4NhVUUxDbmczkUmA6jQQPxRjNCOjXQ+FzMsTg7HwMzhCFMnDR7UehDJw357zFQJRhZayVccShDOuTr48d3FFZFysd6k6vS3OoR8261Ad/WGKBLvTGLsL4wpKSSPw8tyVilF+x0OOosxgLUU5XYMlTHWrhdeQSVckF+PXbOaqJZLlCbTIPPcGadL0CT+oDTYZblJ+WdcJLrMOiU4YpgggER3/EcJzqP2paI4azGlFBwZGyEKg2ako3H7bSK3ykJkLnej7DDTojhoS7IeGufYEG2+Vgu7wjWteQcDck3A0Jd4Oxb0i4GxLuBlPn3TR11jx6eHx5SLgbEu7u6tYNCXdDwt19O9NDwt0OJ9wN4fJDKZP7tMr3NEVxO7HxyUykJ5GfSbTM7jUXrrAar2pqV2AbABdWPQLusA+B8eBSBOzf2oIWwvGysav4gG+t8LBVlL3ukHyl8Pxc/XTiAyRzbIB9fTHlAD2sHpMIYDcGmVTXbWAfY0LFFBjhVhzTagTzKRXlU8OilmNr9Fqxhu7OdzLgP69skK9Gc3GDI52qqBfz5FiC/I+tHTsIhoYJO4FktNSqJYdo1I69aYJYv4FP97EUXgN/VaOuVsa8QfJfHntNM3raRPJrRDh8IQeybbTSEMatqwO9xoMQsovsEU+nJvh3hFUSNZ5UqPE2UvuLzPNA0fueTPSVygqrMlNy3JRIRA3/JG61TATl8/tVxnU1FwjQjO5VsAYT49KFAXLGZ6oOOLg4xFwH08Az3LcXQ9xdRtiPgLv2hUzqernZgi9N4a2BqA9EfSDq2yDqE01yN07cyb5zAKUT8Ng0lQB/Da9Qje+foL2j9HeuulxQixJxgjOvxFIsQ1IoZ4HmdfhfqGKQ9xRHRgkiyP5zKgZO73o8epRCeR5vzqMZUW/49u6S362guGi1pjqiY6NF6Ko2YGO06i7hssOSTpBSwSzht2VCfBML0Iy1c3UR+8AXcZQtlTx+uPjDix9+ePHDmD998mT87MULb/w9974bexc/PHn64gU/fPGCY0ADfAYUssrQ3yj9gQYCyXHWaCm44/BxgzrT0wxZLYqR90DGxPGTPTJ6jp/qf3wHdGHBv5zQR58ckrNX/2lMqI7pqWKM+YygYkoYauEDAi+IHkBArIErirwwg0pEUPVDBrN5+gjDylQZGdD8xBesqvQI+nzEruaBN2fq/Ep0hvtsEczoeru8AKUI0DTl3meRtPiFwxWM6R8iDVxOLd2Jcms19/XqrR1A1Nz2OF7wIGLvhYzDTGO1NETpjPawhlRKpgAxToOFKIflPB8/eTp+8kMxLAe3opWB6nmyRMwAlgjvEujgNEz6D8SV7KFX3IebFLcsLb30tPLWx1bZhd6kl/CoNDf/CDH3dNfURxDxYRkDhQp4yMCPM0d0Hr5Y8mCGXSf8qht9crXq6XDKEq9lylboTpM3qORGQcGCuG6nE/rrhz3zghExGt84iWSWQOmyfqMqSUeGVI4sip9TmPXixpGux1NFhDTRUTWkVmzKgzBLNmqzgS6FX1NtxloHoJ768y3cQVW7o54tkoohuCTWKuFVdo71wdeaNwpFItQzp1CbzWJnm3CLuXdfi8RuKVztYvviPq94y+w3R4VNGjSc3dNw8OhtqET6pjWYJj0FhPOxKpDeXV1RYjPtvBPaqITkpl4Yh07/zXvdndvKVFo9nFoYzDAWUY/ELj+K4YeAn2CwWtdQP+pVjB4Adnp0Z1RtfBogH6nqHeWPdb6264ylsBddeRTuk1ls3X4rJGadORluAuGH+t8b6MsiJMX1+JuyawLPPjo9YR6oClcci7nDG9PMBqPQ1Mcif7TRKl4E/vjkImnXQU90bvgYeqqCY1aon7WMmt38/e/VZVAwZfo8aPGk17lYZ0pAY/VHxx6WJx6rb+/V0W2x4EEIdHuEf34WqzIRV3QIk4FOIlJNIJJ+//3PJ493gbgnOaFstjzh8ziZifE88H1gVzqorx+BP/iq/gWNaPvRa9CV3qvmNsU/xp8Y11S/QvSpAeg6HQg/CcaQ0SBl7AUoMus84t2h+LnHO1/OrX4dY606OhjUhugFXYu2b+gO7zWQmpphDiTn9kmOueVOojNy+yVrKAa0tcnFn0TaQCveC7DIQ4lYX6Q8CKVCFzAeww4kZCAVnUkFbMa16MQgA/aQAa8j6ykxbzNSnmvbB7p7G/7JLtSYKGgNKV5m3UmxMgs4HIv1BBkboAKeS2igk5N1U/+kQiRL6/Z7JqDcOhq+4T4t+ApciRgFktsQwQqqU8GFxIA2q2c+TdWNRLR4HkL570UgIUR9wt5BkIly3aCFchVnzJvHsRTWFyJBH7wQjPsmr1F/4SL2VwPL8HfHjiH8oLsdQx3ggYk9OCZWs/MDH7t9/cEwmi0YLQ64lKR+9DJU41vN5mp2JBtSC7ADSS7ouQJeGLSRO8ZarFOwjqFcH4KBy9xFczlt/mbt5U2nY+BEN8OJJlzT7bbMti0ypIOv+J81zep0NDsY14lHOcxmgHoGUSV0CCmMfOBPnflT/l29jTtjoyvZyWl/74hRvzjYgSDuDEHcpIWfiFejnb+WbGlrvyFcg3x93+iXbWy+BvEaxOd7KD7Xn42BV9ymO6IDB9mYV4LOVQffRA0ToWYWCwmigXPcCc6xK/ag6zgcBo62+26HAufaivNh4F07quds3xNxEImrNb0R8KazRvBbcdXK9MKY+xBTGYkrdfwGjWlrHGiRhWmw5El6ANdhrPPtbo0JmTDtgQk9YCbUeAoGJnSTTEjR8ttxQFjZeb24kHqvxSv+S57Y6fKL65PaWe0CnATAGN3BRK47wYu2pw0VzsNa/nFzGAZedBdNfPoAbNFHXjkhA5+6IT6lucR6Nr3NsKiDr+ofa/rJ9QHt4in/xcy3xleuz2IPZzlVwfEHrlW0HOab2vm7inzp2i7r+cL1Bt4Rb3h5uAPp2x3S1+YQ7+PR0FSqi0+jjkoZr4Y5NZ3l64FGbZVG7Y6cfh2/xbVI5yCo35DRqCSQb8V3MXCl3eVKW3VfaJl8HQeGPpidXBh1PO7I920G19V/MRiQdt2AdB1fxsCYHixjajkJA2PaHca0aX+GF0cy5VFaXzuohhHlL5aDj/V6n6oShiP2IeVpJkcIMQQl4ex36wKTdRuNoq1LGJT2RU9kZCEIX/Iw8JnEjwpC/IS7KneLZfWO4TWrNpDonSbR+eneRrRu9RQM5HlXAURsOrcher2OztBFV5hUSDG2KgGQ+H4ZfkRhergASAhBKuLhSgZywk4ipmGxNRKIOq0jwJmax0nK0iANxQip9YgtDf8ACp6IUHCpNg+aZ6EPwCK6MhiWCoOaCoEsVQzjplTYVRCGCEYiZTCLxI6Z6nZEl7iODjEwpl1mTNvRGQYmtCvoH5vWDewC5Z0Yjn6hJrBJKwTsxDYuqeIsC+HSByjUSfdbg1hd0QoGum6NpbgpvaKL1KvBEFd0x+KKzJ5vIaDIcSjuOPFvp0ts//Tk/U7xgYkhzjeGYK2/ePBV/6tnMJE5lU1RRK2b0QBz3cgnKNpolxlF7sSwFnhn0snVDpk13vHYn8o4ByK1m0RqE4gYhrK4wTD60xQLICOHwB7Iy5bRKq5HWwZp8y7aEZz7PtDqHbFud6Lg10akMOS7KXCzPxHPQzmbKfeO2w9ul27vgOFinXDLgZU8PFZSt/UDN9lNyX/TQZbGQNHHSWqoTKOXtD/zodc1UMSdZkB3kg+o7Rv4wE7zgbKheqO+ySojGDjBbnKCbXkuD37PYkKM6WVForfKdqTW1Wd/Ue/V2ZKwX5ZR7muclKNmrPOq1m732EAvMw7Nd6C8u0h56YxvxYpT3PaB5t4lW44mfRsixL3or1YK3eRXh+hck8hCQKbPE/+uE1mtOww09iHRWPeu33ESe48jwDdMTjGNpS85pZfqyOlH9dRZeksvSg5xAK1dZNUZmXfHSStNdiCtu0hai4d7GyS2uPsDid1VEqvJ2zVJbBYK2SOWjZqNeRiO6VVXMFsYMv3QGaNkGiDGTMTU+Bxk03WS8ialyZxZ1LUb1TsyA6F5+Vs65mc08aMwfK/GpCO5Dp84/DkRz9J5nAT/2t6AXgN9qAzmh+pgfsrCz2p12EUYe58FpB95PJOC4f1TC6jIEAsiP7gM/IyHjC8hGYmHNzcHF5HAu410YdSZauDh3dLVVhejJS7sKAz3OgaBQbSr4zISCqLzGr4XaZZE0rqHlLKmLyK7CtI5i7E5D9k0gALcQTTb6AXN3fvwH7nkntAy0e+ZSFaVUX8QofBSyUxzOWHvxVLwFDm0+Spk2UlsywhGOxTWO2wf5qpY9Ch/8MdpHP9b/tcFTx7DdPODuQODMYLFP/dWPOEHV3HyWSCXxz/9COQDL06QLfFo9W6Ke6QEFJnCHuLCmyD78qO9Bf9yQg+fH46KsfnfPhViMkhu7bBf0FLSkRJfuJeOFzz15kyKBY/SwJMT9m4ROJYtwVOqDyhCJoYh9TZhp1xiBRaxWEJaJI6f7cPDPz62Xo6hXjv1gAMwb8QJyyKPp2JGdBb71d1S7n1pc7BvWGfsn+aAJeBxUup95xGo6eff8F/iyzLBHt+9Vwtjzom1cB/+8oadn7xl+5PJ5PG5vXYf54KdJ0D0ZHApztk05DPGp1Ncepy+l8k0XohkrG+3OVjqZCpUm7ajPuzj3djHOiqxfZpght9MGH6OEzMZzXLkiIHgykQE7BTkMemJyAcgDFxNOBaw/Da9PcV15eEVXyFOhtpB3b7pTN/gEIrLaW3PHnxtz+iH+s8pD6XYK6yrFDzxKtS2onU7PrHgYeAFcSYL8XSBPFtmF2HgNe/Tm2ARAN4CXjuVuq6CwuGiYQ/sMpABSUZN671GVxtYtxC+2rpsUba4EIn9BTjmKnee/ljwL8ECvvbkEP4KIvWX/bF4OqXCKX2/Zn/M7v1wtBdlIYmXSqvrpNSg4BdPabG3JXujiHyaiMtAXMEHd1evuQ86AaWwjrpFdlFQAWoE7sAu9cQZO0JhW75IiZ9g283r5YWgqm0cA5oN7Jk7cMpxOqExo7Xz2X4UR2NSbx1sIk6YDEKIfLjiSRREs/E0ESJvaenFj7d5AdXcnh4+rZnOUkSIDKU1cbYP9uoElLp8NqjVQyvX+AmExPWEBBoYaBCKRK/E9iZ8pOZwSnOqEBwHJfwrAGKRwQ/toTdrTBko4AYpoIqU6mnYPPjaL1NXWTcrpNNk6TpJp34aMfElkIgdtHGyaQlvZddRcTCgR2RR8HsmWO4FQrkVAYzUuOrdTev0VhbVyM4Okc4ZjjYX3Z4/PxTfPzs8HIunP1yMnz3xn435H568GD979uLF8+fPnh0eHh52dVkhhVN220aCvTWS9IHcLaWb7yTHeEaAEHUgybUkd5dpK9sXk9kE+MEiSLV/jYkvnhC+ZAv+hYUimqXzrc1hx4kwDOZZzSEG3K5pnEW3b+0/imJ0eZrTGYB2C/D+K3Ny6fYH0lz/bZ7IV3E0DQMvvXcMTXGkjjb+mUirXImSvJ0siR7JIJqFRKbZxYqdHA8s6UZYUsqDcKuat1K8Byr3ACRfIA8d84kpsaxKKEwusZNWWPXsB/l1g8Ri60YO2rh6I0cdgaJjcleMHEVa5xSudQLsA7J2DBR/kGt3kl2p5Oa+hhq9MZ2jfE3Uyzh/1Rn+wuzn7jiYYrNS9ItUIP5AhmQQR/QvcSWSsfRiAGwGmrHIUhwqBmZuPWKGxtQt/MIceV0YoD5QxbiuTQ2Bosubfv6jujD/pv5MBAT7Cv/xhP0qhW4EPn4eAjB1GjM/kBhOTc+Ky9MWdrDr47fc7apjlE+oT7iFxrlnPc8d8dqLaT3DCQvf7ma05/HIE2GI/+ZhCB3nYkn+coNff8tfssIEnqEXU/3xpDFkIATRMz2DAIfm4/y3uYjQPz9SMSGEyB6JKwLgpssJAaWCe/P81HhzHjSGt1y741ZHdX4AyEf9IF3XdpQIkc8zJJ+dQhBy2lyJHdC9MeytQwxCr77q95bYcL6Veh1G5kkWJULGIdyvwtZ6cx7NxBl2fc3Ja66DQfvXm3ulq/qpm6x1PXfzg0E2UdatYnRQFtrVMGtig5C0WgO9oLgvZbyqjedpfq1ZwesZV2E+sk2tR8uJ0hlc4RjdSUTlfwx9IiZ1s5L3d9VxvUpiKU3ImhkdR88JiOGJgG3xthh8vzW7kNmkbQrbE1t+bYkQWVfoNn7SPrZoI3hXjNIFeVrbQzvYqM0rpGxnSQLmB3zk85TvokHKznHYjFHK7rGeBj/pSrWOSttwE0TrGD+1FtWiUepktIF69TC5mJ2+u4b2HSKoaHa/Fj09IEVqrysiGzVvIK2vsAHAepYMndVgvnLLAnmdsHcQTw4CYZwEswCsHOrCiYQt+IrRUFiw2ZS8B0dybU365uJPnITsbZyy3DwM4r/aY7R4Wgdpx0jYrRuOLYNxFLMwjmYiYbkVZCCv65FXRRs3kr5cpruQYX8B5pPuBQPphQba+x7sQEJV5KPWWCCQrGYNlNgOqzbUWBuVKBsq78ZFpoFA1ZBpMxJoQ5Y00/dAuR2Ue+su2fdqR/RNU/gDbv+sw5MJmKtGyjTHhPrcooxZHfauB1d3YnHW/bCY3O4I6pi86IskXBkZbXdcpupMSDyB6rZKi1iNWBbJbCkSKXyLAg46x/pM0TCuvgxQfIFs2CCO+kB5JGIRXwqt3I6tPoqMD1pBDiuEUqgEXtO2FmAAX0rETHwpvbq0ElhL3UzYL3Dcohn7LFaShYJfCkrNRadqFqVx5s2F/yPDwBWIVQL7kOmfJ0KFrIQrJj8Hy6Wz1O2WMUV+zsLQmhm4DAXj01QBCcnsIk24SdbdSowBDfl1vqE7S8Z3KozFwVN+jpMLFEzvHFnbehDIpEAwNhjnXEOIwFxcIhgl2BK3hblwG5HH5gRJS5H0/ojhpAHgZmXcYDdLPF6XJugY0EAxBopxrymGDnjuorlz328TYI58P7/xadwqu0D7kuCSxk1iC9vPIuT0GszjcXdBxs/oVIiS9OILP9uK9LJ1DfiUJ2nAwzqKcm35Cdd6oIMDHbz3dFCnPPfK/WghhipSvkYgcuhxyxDwhUxeSP6iIY7oqwfrJoItyQl7DWFyn8WKLfgSaSdIaBD6B8EzX+PQP1PvjuA1/cc3JiKAMu+sBU7Yz+DPZsGU8WjF4tCQebLVKzsKQxFxRfZX9VxHfuO0XGi9u05kaRsr1Ao/uSk6S1lBA6UdKG1nw+apul+7Y8R823jrB7a0BltaM8FjwSM+A3dP9yAz9YoD2xQUe/W0RoqHFsc/nxZasYVIOQSSsX2YCzrzrLcek4HyH0fvj3LsrJtV/3+x52SGu0EEdt1le8upSIHLnvF0z4UJmMYpD88MenQxQrwMS243Htk9Ix56qQ/KEhjleQvFcRUWzDEwOqWVB6URYavimfk0Kq3It/JLegJmET/tHIu4M7RGk4MNR2AppMSORIZaO+jLB3xQQ1rshyxDSXW+ukgCf8QuhZfGyQgk16s48TGJlhAhE6rTw8MRu+AEor1iRydMdUagpggPOuVhCE0GsOUBbHkAW76vIL1tR33Yx7uxjwPY8gC2PIAt3/OMVd1/w/a95WmW8HAc8miWAfJdnGgpkNGJYvhin9DHPn3Wb2B8Mc2kh4AvyyT+smJEovZwod8gJh+sOy2G/ruw2IvYbyEy77V0C0wF+MMK7qdvHOxmmHVT7dxB/TxJBi+kW5uf9OlFgrE3yh+QwL432lPrihqp0kgMLxoXKMMYl6OQwk7b0+1+Y/UvV+4xGCh0V11ud+eO6pcMOJa1OurP/8RaYZ3sFX/GdURDiuau9H11PNUgtwpCThrULlttn7ustrnul0VGix4MBWVDQZOBQHHq3jaClKedYWZMsiu9VTZC+lzOL2Ioq6ufV82Q8ATcZ55k/CLOUit2CW6u6eLmzY3HhdHTGLeGlQvrs7u39K7ch4k+Z5s1m6VJ5qVZ0t0+j/BLuB51pccs8LRa4KX8u3bzLVm+egqoW5dJ+8uh/VSTXSoX8hp2Fy9HVzyL2/P53hlSoIFmNlo2JL/TzuIhkXVR65PdnPd6V+Ismv1eXhz5gfYurXPCX+kO/oTlZL+Nml1WBTXsyeHh4TcQyOE4+FbjvLiwoRpIHMgZ1eQ96zGFX0TKT6Jllr6O0mRVNkbV+tYKM3j6/HlJkRxptLqq+BHIZSxxrVAaMoYfPDNgpQskE6jtKOA148BF+x7qPWiMEz5ZH13qTq4OUnSlpfCYHzQoKKp/9GYPl6RVbbtle59+X1kcnDSBQTlezgefii/20NWfc/EFDQoz8QXHvoh9HEjj6HUfUexxhCO7ClDB59ILAjDuZGF4pRwbFfukGRHQwr26cZsVxh/OcJI4QNymDregao4oepQVeFa+8rrrqhu3MObSmXa7hXMa8Klr9aDXhsyZGkLBYiH8gKciXLErAJkzaZzg++O5SRQPs8LaVQcdNOooruLN3jLQ7nWKCrkAdncSWnenhJFBSdqKZLRmOaFcrlmzslCNdGVVEKqXrhxlhrYvZz1A3PbWHK2c1G+5avxQX+jBk9wBXv3hwau3s681kmrdjAczZBu5jkJpdDGaoabQfa4ptHM0eYfI4P2hJP2rC9VQEl1jqJGYuEoNDTLsFojKw7OMDqbQdlPoYPd8WHbPoqlzrRph99CIeb1qYYMZc9CpB536HkrCa+a1lkzCBwDCutcVeBYa1wnUHwHNtVmcpiY1yjmf8SCSKZMoP6on//Hh3dtBtt492Zo26Uy/1iQkvPjDH/7w9MmLZjnB7s/tw3Swh4+EHwwhuxtMOUZOU52UFgHrhPnWtOBysFNpBXTnuqdPO8sXd4gV3R9qnoo16uFYtLxaGqeHiUSxZ4uyu0HFTV1mzc9rKHkduLg6t2Kkxc6RAign1B5MqEviZQyZFO6u48hRTqIdeJzmOdSHqKCMF5JmiGU3Je3me0L4FPhOY3po7RtNlerCgkZNf5uUmEVo0j0entVoiKcb4ukGu9Jtx9M5RLLTsnVGGaS2Jgv5/aoflAnxZS5CQrYzsmP6c8qDcAdQwqrVERQT39HaCDtkiCmUAEqNuBQn+peCCv76lzdbNcfcZ6mdjqS6+0e52LuJIkG1wv016gW1CfgtVYPWFPdVABeJ/IC8Af/E2EBnhyNg7JEKS0bfa7CAar8XViyvKTUTTxllF5cKGw2C/iDoD4L+IOgPgv4g6K8v6N/timf3QOYfKqJtUBEwQlIM7v7cO5tXRRt0ALcO0LMc2sYVgHzR+8dPj9XLldpEuQRvWlRDqYH1TgMR+szjKQ9j8uHfAA5C39SWwiA36A5EptpDRsAZuASEb6M9HGOPvmqwgbtyY5TxUzFDpjkNY44SkBIwP9WwROzSgS08Io2nFalY6UV6GcyknV3OBfeLMkwduvPDWTm9Xt9G6pbHXRZID66HA1rPrNcrell6vaT+ub5zvNOugHLKQ94sEhdXrWZjtnNM1P7WHxMlQ2+S4qx1Z+sGl3lpj2E9wCvbisiuD2i+nCPNYMrbnxNHmw7sZlTIHRPmjLjTmGWycSFOqV+is9lWv1AXcaftqy1Rd7kZ1m2/laso5V/QRmtXcBigbzZtwdMpRFhZApbGUU5TJRnhxpwcU/0/L8x8QeDYpv4enlTmzYX3WVKgu9buwQkZKWfZNoIKB0vkYIkcLJE7EHJg8fs1gmDXoZf5F3c7e+NuySNNgoiRGfrKHWkiRB97EVqK8KWynWgahz7UakiE5a+ttxW5WiOppaSjiF8GMxzJLVS6d41tW6fyYyLE7qYU3Zkboo7kRtFj1xfE60VwFNhURl2kOGWdGG5J3VTWR3n4IyGlVedndDdFct2NzUsdTF2JtXCCTnwXdy7KqeuLgnlFjiYBpamTVpHEbSxoFidyvo8Ltntcv4HZD2Rsg6jwa7B46fFIHnhxNA1mtUx+JtKzV9jkZyhgWAW8/uDxiFGLKuI1tJAMPsToOxl1TTjwr8x42LtIPJIsEimU6cAXIswMEcll4LlwMdS0LXLUFFF1LKZBBGVh5oKpGrwKw6drBFV9D2XbXjd4GwUFDmWq7BXcdAZaT016vIyTdAzLP4ZDvhBS8pmQpK6rf2+qQ0kwb9W1+dtcYAowLvXpCfNgkcDTrN6YZnakWm4oMSYI2kmlycEfn4gmIqndhMGhNCv8h7pHVWOtmuZIb4i1lNoO+/e/V1ehcrkwvGJ7omZpTnwZjPUxHnvxYhFHYzWATdJMmKCimfBF7IEIITwtEgj2tyRIgWaWfn4vuL8lsoskcqK2dm3IcfhVEVHCCndijGOtdmvDa3DGpWpZJar3naZuQ9KcYreRt7rWZcl7Ad/m8nrUBN7Ho5Sk1+uIeijTI+i+s5io2RTskAZ4pjM3MKrtM6oNMaTN8KM6MjWwJWJLt8uAeiM728L/wVf671kLuDP9fkaIzLRELjjnRiZGjYCJuRgYOKfuJwfLMyfMWncem7po6w+t0MFa+oprb7fCArqHA9l0vvtbFTUgd7ZYdL5EsutpqOrOGo2hq03E1LWcAyHdBUKaYwwv0fXXJMwTkEUdHqh2wjdRQycyaJUuBtFAFW+DKg4ax3oaxzrqhYZeHNSLB6le5ITztYNwDrxxF3ij8IM+blJSMVQx5LKOUets+JNI3y1FdIqkpBxFAFfhDXBMZRp9r8UvZ11tRedDegH5qq4fDaYyXmKqDs47YkEEDkY4jn4gvfhSQNhjvBQRQ2I3cNub00E0t3iVJQng7cIxYad6F+6NJlIe0ZMJ/r+teC7grz2s/S5THkShkBIuu0qzWK7SOa2eGtHqTBd9jcSZ9f8x/nyWLUSU1rcgWnKmGzraQGGP2PW5d5Ew/+f4Vulx9UOFBt8qLhq9wp9uVgmsJ2gDu7stV4/iD5uLFbp8enCR8MgfL5M4FR7unR8veBAdEFanbOSGx9j0F2gJDsGq+13yS+EzxN9gukNXVN2SA6IhCNihqnxMo9AvIUeMI8A+ZIs4EQxHzfJR4zcCISfsbxAnvsjCNACEXfz0WeBLxhMEXrwMfOGzfThIfCwFcMdU+I9H5kvQzhcmBt1n3EtiKfUHMF5JcG9OLygOjCZDCjlWVWEYkkGKllqKZEyt1UrocGvoK4j84DLwMx4CD18EkoAhVWB7T+5dz/pawnb6Fsx2RFIfFnh4t8Lejm6eF/vRG1juqiuT/wuu+MmxQgOwN92cNd2mcnpOjovn5vZOieNodOfl4ssyjH1du9wC+qFRndFdcyxyl/2a8hADlRzd6jF3L46ed6LG1FZdvRT8GoSEhkqbdLHSZAQDEPdldkFfohaPG4XQOPFF8tOq66dfxWG2iCCXRcZJyi5WE/YOn8mX7BGN4tGIPZoGiUzPpBDwV5ywR4mYBTJNePKooTYIvY9JePp1Sk+gVzH1rzjwrsP+AIPFN+zxcuk9YvtceoRE9RhHCi8+YvvwH/Vzw4i59BShN/hGbQL0B2M3CFcsUTpSlXlsSJK22Fu3bJT8NDeaQtR9l/mNVci9y0RI0AsQWiCIZqEY09SUIU9O2M/A3YD2lJ6MWCYJOTgnAwQFEEQWlTFERUCekcP4AjGddJLcifvmbNUCg+tPVNfg1FAvasJo3VUFjn58r7hgVw0MXSMg+00EsfM+ntQOKS/qIJfCC6aBR0vuXmRaqsCO+NVpu99GOUdreJryWXV4H/mMcSljL0COY3K18JURC6YoIaGlXroytqIsJKnTJHnaCoPFaPMxWHMZWSvnzibOLsLAQ/ObM5e/+PkK2D6gikjAGSouTU1ScrE5WQ41NXSwq9LUMYs+OssT6CqnnZ7XjCnPwa72G2eJ54zgbl59N4UvLGlx0M4hmu8XmINrs9I45aFzSosgChZAxCtZXDkNpreL2qNLwTNEv6ziiUt4fna0DP767FUYiCjFuOe9Fm3O0td+QgXg1CgAO6S6lTWqSb5wN6a2HVxk4eexurF7tTkg6C78KQs/H1PLX8xIc0UOHmt6qLCg1B91Gt2xs7Gm4Fo6CwDmnjihpuMTMBGKZSqZCAxHhYgeypNg++rdl+yfXzW9GjEjvn779BgJNUjSxHFAWEjiEEUtNLaKGfdWxe6Ambxk/4yyxYVIPj1mV/MAuJgidsoYG4ZGtJdzjjJkzngfSTbncj5h2gYIAwD2o30hB2hv0ebdG9TrtuYn5F5d+riRWdXZG+2ZM0CptHrNm0QvTJyRwaX4RVMjmndOnEYO3pmnoD5Ria76T1PYpI/AZ7QiF5lsH2Ezq+/UQz2LzgfXXGOushClLtU+dg65tInBQX65c8NU5/PFo9W7KR7+4rJ3NTzrT25kP7+NGkriNAts3U2yzu3LO2hHVtFTvqYl2HFibmwTWgoPbWCVLYF1B1b2DstItygNFYSXjYhFinm3+XbJoP0X1bjs3/3d/O4oxx6GytpdZ5omQSLShSxvw7jb3cJnv7XkswqUdp09iWxIPASLvmAkU5FMVrTw50aPY7IkSjCdPSFlP0b1XyRn2Ako3RmwEjSlAE4q/oyLrNukMZkLkktRkPOyMByr79Ets/TiDpyYf6E/ETlDcdKcN+cLpIbRe5HU+sRTc0aWIqHpdV+zw0N71Sor9gtNAtrd4vIVl+669sBgk5bAdp96Of3bF0UBpszLzC+0v8AFjPe13bShGzr19i7O/B0abi5H5J+vGycl8DhlA5tQfnWAJp5pnvKpzcy04F/O0qAGhG8RRPUPS1/qA78IFYydZNrKx29D5tHduGWZigbQw8jotH25pJ+RKgXSwTxXY0zEngvbOTL7nvfu0mgKa12VV4fDMxyeusOTh5WeBdE0drgulKMhjqocVzEp4rDIK8m+VBVN9sofrsKGZFHqWNKSzWBZpLo9LQ5GFFm7B7TtnnUabGnfcrEWRSFLKrL7vHYYU1vk7p1Ssm7WEJ3LTs2G6MZU8ZNIisTSlFYFPYmeMnfJnUKWZoO2pCIibGc9UzRM3gPj6TX4SC11RW9Qlb/YLTCU4iyM488X3PvscH9OGS4Qo5YsER6QRRVCod9D77JWZy2XUDnOvwwMurMssMVu7GR0LSiKxK9K0kVXEytFIwV4j8D/bKlBGwx/qBXvN2fvzGm30RHuLqFejyQHsyhOjDTZNdYz5Z9FnKUTunnjDlS7d4J1u6nswHjYumdd1zEFlVCqKImbN5ik0xq+YL9MqdhYHE5NUdtPsIKegrg1A2VXQQh1jBaxsm+UOvGzBAvv0V1hEKJywaXI/XnPDp9BeEX+6skx82Mho0cpxVvcSqhmOTRyE+yuNdPa3gXa+9sgUQMR2kEi1J6cjK4ZyqWrIxUq066RVOhsvE6kYhckye3e2UFEHUTUmxVRC1xAp0YPgurAI1p5BB2WzQiqaRJQDGODsYJO6kdsabOZo4iHq39pPkOUgvhIsIBCgXGEHVVZDxgDj04wzh8y4sDtq/sIInKeaSpE1ZyxT8LTX7FlDHciAP/oPJBzXbHc/iQDKrCAGDg+g24pC28WXIpIjZAuwH2IIsP5XJdsUid9aReHAyCDtUKX2lhnT/aB6c6+iApxw8oXZ3tRS4bahlD+5tC1Qi9NUf8WPjUigyPPx0XmsrV2zPPDioHYBDnb4U+FgGdrKcxn6uOXzzjdYr+6bqZJdTesFkkWeSWfRGNYUR78nH+6/CG7W1PJylEHlqi8qlrK2b8gdv9ChHE0A6qQxqoarAoW+Tbae+6q1Pv/YFLkVSQSOQ+WVCtHVbpl+9lSpongCypN8Zg6cQzF2YkamQYcEP6Oc7B263equMB2rSihACnugMbahL+P/OkNtv6TblyMOKIfGXBZP76KGHXtCD9SDXm5KZk4OAOGEmJmjbZo/PUZ+48P795SXov4kuqQaASeOD3+mV0EEU9WFIbiT9Xj+8BzaJPfxmlQoLcOrQAzG10VTWt61hAcq2O17zV0uQPhHKmzDjOs7e0/sySQflAbiV3pU+eEROlryofv8U5bDaZS6z4fkHGYwRx+ql84KaAA9at4seTRqlO39Eb3YVD7t+3lF+zmH4M07NY+TbgvFjz53PkL+RvEr3q98w6IeRcG/S3n8dXGbVWylv4U3bkRXqZTIAxdrkmXS/D0+XeVIheo7p1cIxy/Lt+rUMysWMrMT/gUcQ3oZzysl4JKyi2RrlXKbqr5YRkvRXfdxT8a9fP8TatabkcRl5gK0yyoqJqrHHfa9T/CTo4guq7AFdBm9lWJxi/ZV8VOXmo72jf2rdjN0p/mvSjWgZ28IqI9/rhaipfMpttLf7pBYBzFGl20gx5d59xEZWbRyFr8I+dlqqQKNsjvgVuiRRHzxPHM0Tu2/YitqmPRpzuMZ7ERx6vxT847V//J+uvV5zaZUJ5Oy1iGD8+TK/bywZuh5UtoL9DI2jj765WbrQ4Z/l46ys6zWlWj6GrsDdalPtYlLdSOaf1bwleUJL0RIV5T4ea8ASK3H1VbNxCOksfzDl21aCDNPxn7CEvmV2R58+6EfVhJyC5UUIr5E8yJN+vPLgOOxqN8HgfqFcAI8JdxEN24SN/Guz6auUAE3tbMyoWd7Wim4amYxYlD/Pw26kv6myvwVto7M+LrioU1ZqGbAqJ4goDcSaRo16e6JvNcF/3Sy1Wcbi2xbc3RyrfsDlvnNxnvdz2qSlRlbFOk6xSQKRLB+kIyJWLWHCLYiR7eA5vEhequ8fOjBgpUrvNbebV3ze+1ChHWlP/LKQFOtLMeo0+TKe6yHV7gXv3G9R4ofh+KjwvcIGXfVWK+62R7k/bsXIT8qv/ZMTSwyBkozM8VHdjGGUyAYCeuYITkXDiGUgRxyi6EDly7lag9a/VuQ64egvYGKlEXttdRw/2TSCup8W2XF1Pkc/C0TlcY8BtPju+qtrs7Nz7PnR7kp0F+2iHKeDeVYZ0hl7lU4axMLOurMLWRTBPlfH15ZxH7wTS4XwLPQ9DDHYRtPb28t8a93aDegWMMHONeytIbCW+uaNxajO3hhXqtX6l4orQY3c0jRWd4bAonVIXwdM5TYDXAZzIATIYSYClPsEgWCt0KPQEPI/zoZTKNF7Y/6+NcSOHkXNijHyTCS0OKRgsLwQ0Q17djHqzXlSXaNU/WQH5vlfwOnq7dJeCG1F6ThMezuFMFnTfxLG6onwP99CycY7+iCskZs0slUxIb6yTLodZM71ozXWcKGlsY87XgFzdZiITOhX+UQi2SvCqJDBZByIEifPDiRPQpTWJ6tAOvSv09mFolpet6iwlF8N2z1Bn+1xiH3syXrezKYMFn4gygEpxfUMfizB1Y7A4zrM3k7FnawRy+M4mnzxVKmSUhllVwFpvoJAxYxMLuzPH9wmpYt2Qo0bA7yFhwc8c3UqcBRYOOcMQgHdSBERvWvQYisf1uCZZYk1ZYSiU4rFjgAz+ZkQ+HKjbg8Z+wDwKy74m5/RHuCjRUBcAYgKi8eDYWEWCQQmYtYOYBybgVO2SVr9eg8hqIlzQ2tN2WogpCUyvGb6/e6qWAOgmiBh+hdQt0trK+/w1TuVan5Rldm72uj//bk2sWh/TLyS+vGTwCGRvmSLPejyulqgrXwVFjritPLaWL1q75WkNInp7hxXKq1jkDS+eJkPM4rMmwrcEAzZbw8a7c38VcCZ5CD7JmSMUPudTqgfd15X0bwYTU7MqJCFmgc/1hIfPXkWFdBhLKtOXngsRuOmB3PRy0nQ4wB09lr3hkSDRShl/fnwBdmAZf2L6YzCag8/GUv8SXDpbR7Eei5KPJZPIIFaf/zBTeBD2woCZaXGK9kXvmgUzjJPAQRiPSMylA9jB+oQHbrH22738pjMiB6FNDykq0neRp+ysoubP9w/GTx0yfD/vgVVCF2vEanDX9fo2C3zOhAUICVSyBYERq5YIu0D7WGapZhu7phPnVG1Apd4tR3BpL2ExoqaUKrQM36eY3Opy0nt+0QU3mrw4QkI3kYIglfSj3XQeJXv++q4rezbAoH7ARnLQPhnUVLjk1KAkPlYv+AaqjpmDdIDkJln4aRD7VlWReGEsh09xbogFhSzJJEPniC+azx1ma+7F5pKROgCGME1/m1KIsSVBBeFP/GHh8Xj7yViiHnMdXf1YyWItNQYmUpUXRy6GwF83c9o1kB38+NsWKXjLEU1HqKnze7kl187jJDHHD46h3G1VL3t8r68yg0pBKAxd3LbXBvFPQZkCZGDFfn8LDxw7lwZyxwyZFIl6eOTSst6aYWJmukeUxSyK2/2QMUYn5KJ7Yw8g9DGYcTwoDKdTxqige1h531i0+FC+zUg6BFW9VsujrUbMIsTM05sZMh02gITdnPWxx13WzLdY7565tgASgQpnyxbK/7+/baO9SeGmcdCtDX55Oe3BPCWx3kELzQTTIn1jn/rqut6qqacqlf82LiB90q5puV0wv6p+qJjIn+luRAn7hyWfbAaQEFy5NzXFfxe0Q6KtSRFW3PKS8p7zG+f/813/rN1Eq1R0GUBJSa6ugqhLS5HQKNQ5iLK+uFuROqa49C2hbIlqOObrFD3ZSofHQWNu9HS7XtYizGYdLm24Gk23hBd0KYOffv2755YGkrlHxazN1ljvSVlMyvoW6/qrbVemreVRLYd/nlV6sO4YQYBoRtUx9HQTXfMdNcs1MBqJ7l4iu2baB7A5k9zbJbk4Jr0d4DToeoVQ2x5R9VI0J/tgdc24yTHWHzsQgiC4rtzS+Sx1LtmOZOR/L491qYo61Hx0DkAb40HsFH9pqCtAn5A4T0N3J8qnQwevh2RUpZT2eXYkGNsc2lRorqVOJjjIDoRToEZgJNZI3C6IpnF2xEDdPULfhCVgb/rtKvnrCOK9D024KdlyTtk3gjnfN9S8dxu2C7A3M7X4xN13Z5ofqwTqq0DkeJoL7KwqU0WJiIBXl23Fp/+bY0kaCqsofPPhK/+gYWVXke/VofW18z8RYVc5C5KPywKWMvYBSVwnXewKFZxSqVyhjVbDXJ5MN+PL5TNyK1cQs4A5YMcpUewjBuhMmg5sjIh3g/Ip33AXn13a7S3B+5TtOwH3DVS2uyrZx+AYR616KWHeQRt5Nq0AbsF+RbNYD+7URTwPsVyabGNHGvDmPZkL7qwDHQURYo4lO64iJ1Js8vvfU9R7ZHm6SPl5zXJshot3xBks3YLuwgwODvJcM8ho2CCDWyUykgyViCziGTZaIA13Lq4u3kqANW7yVeXGwGm+lalDGxCqdk3vPVzuTZL1eW3WSWsdgG07SGkJNX3VTXwwrtgU9F3Vtqe1Zg2lQ6nVUrPJpDcqmeO1uRL2Gg8Jww8UGe7gRiYR1cCOuUeMb6ZllXV2KRAYq6SXBOsWAGy6+pAi0itW9A2lVhw35v4JwxeI88v/eE8FtKBdDmfChTPg9LhN+S7WsS+LITnmpm6ULqJHuOqS7L3xYEyhIIndXvth1SWLrnl+tbx18pX/09AaT+NLBG1wjvuSIGxW1S91r2N0glbZbGASVh+L7tcCM9f7sni44OJsHurW2s5lISKOzuVb3cTub1aFEZ7OGP4BknKreMxCOWyYcu+X6HuS2u0L/7qZd6Pog0X1FuYOlP+1hSj/1p2VCfKxMPxXyenr8c1WcM42VPUnZ1NM4qZaom7CTKYtibKecLyuRjliQFs1QOfoSdWMKFH1JUTr0OGCo46emWZolwpirbieXciDwxVNitqMzlVeHtn7pp3GyAAzhvYsggmM6ELIbJ2Rj2KQNEzNAic0Qm6VzAs4beqXg/sOfqkmIFyvlza36An/Kws+Mvo5JNrWvMlgAC88N8PHBLwVvfVVtRkz5r0fa+P6NiShFTP199UsgGUgfhKsTqdogigo+nrAP2XIZJ6lkcQEt/sQH4Cr1TwoB8uKlUCOXYOA3SepSSHb67sNHaMUv48Bnv75/w0IkWAwL46jya/AySMfZki0AuU6tEfgEgrxAMowY/ORjgAWasGNqhDHZEVzGMPiX8Nl+mgSLBcQihfGVSDwuhf8YibQv/Iwu+I1WG91yxFCjf7IpdMiBnbTgX07oVQ2npf/cRK6RPjRNA+4SGFRNOC+M2517tI5ZV10UdSkpo3yDtXN6J+E2RP2ocD7HN4saxhB2dM/DjvrM352kZw9CHasHkS6863FPSjK5prwDpZfGXUr8fISWdQV+sJvGCj8Yv4atIoP9WANprYv97Cv55v8gyPXjUvGfHcNrqCkDky/Miulhb7gWDH7izNrCCjeur8FVfHcoS7IFNMAsCcdBNI37XVQvDkPqu/lWvjLt3CGHdj9V6Ck6pRJDDq2WpZtGYMOqeifNtufNK8W7qm5PjhsvZcNLFWOkGcISnCiNwManACdqOGDd54qtSmJMWznPEugxXFvUg9TgatGRyw3Ln+1EiF5Z+7htU7Z1JtqjJ3GlXDLhsuhIsyzQpaqC+foXiJhaLb0VuprgqIpu1S1es6YUFKia76JwZYRF3fzCXYO6BrEVvn1GrMApICtMcNeCct8PSPc+tcatRlNffbpGps3F1G4Tdsmpqri0kU2tyY3s5SwsVuG7znKS9R5UI4jDkCqwEhW4r5F9RG9VFrWu5V21xhV5yXUiTfPFqI8yJRSa/Js1aDWArJg3IlY1jTOgoWAyhLK7RM3QSsT2xWKZrqw3Ho9YEl9J9TSIpiIBgz6983ik/vF/oA3bv+RhQEk/iNOPpYenQQi5QOhi2H/14a8H//Hh3Vv8nzePd49TXsP4xKPVuylOolyLEIo49zFbaCSZ8shV1QN2ycNMmKwX6p/tQ+fMF0sR+RICgNXv8LMF/F1j56glkIX4wRfPKtl0+ao7aJGZCVZZ+KYHUW89SMnfaQQLqyu4BhWCpugrdlellC0GusLidgi13DDraVvZZRJD53XI5kQ4689U+WS7V04fTsfiVY/lXV4uIFBNy1U/orZjVTlXm9kZHHCHbRnIy0BehvuSU7Lam4O7u8jCNFjyJD0Af/RYr3dnF1JxT2vKRNs/O7xGIBFV3/4Z5KQ0tkWlEQMxCaUoIy+1utWLB6lmhF4m03iRF1jiEr/AaNqmHM/X3/Y+i9Vvey9/20Oi8Nvet0fOIiL6CNap2uiDZfs8XM55lC0ElHJCUTSD0D4qq+XsuHhKa2ajGjkluvx41bwMj838yTGsp//P3+DlJ7/tjfAfT3/b++Savvs84i67fWhPGpdqu1kRXRGt12UrZ3hQOnnHXJTHOtBZFvh7TYr7MpZBibo6bbqNXGQLXMPW/FPyPpnHo9I6WbNwavrNJhezVjCQMVTKWcMO08inum+T025Tsx/1W9rMlNrdj4gLQIcZLo8aKw9C5Xjsy2vabEBddqDheBSsPsZKlLOyenuRbSLapEXIADE4TKcnESr4TGnIbMyUwg9kSy1yHYjDq5INAjEjkSsUwRywgyff1fLHmIWA8sD2F/wLe3L4y09YGA5+x0gYskPAs+8OD0eHh4ePb8IGtcPWpnWykayuD77mf3TMM8pXsT7HqMFsRS1KZisNNAkRUHhXVagTVyyTR1Ca40KAPAGrhMnRx1kCC87ekVCjMo8gKkrnvnC5irx5EkdxJsPVGjFON+e4KWxD4yism/brr72GUn3TaR7r7mHZcpKRABtzF3JuMVSVSNTzreuTVzVWawCG0j5rlpzjFAy2kf/ACVmH9KR82q7UpAaaY3l6GcgMoU2hKCmJuBbQHzqdhSLAA+HYNOHYtmd222qQq+dOClBPhSd3jK6j4/TTXK6jqQzO4W04hy37/VZ0gB3iTHfOzasRSLGqXdXNCz9bDKsegbSBbVELafMq0qgi/wCKVavbMGEfiGXtq9Py2BKYF7EfTIO1AvwfJA/bRmJCE9nqYX8uyN2NFugmq+ppJ2NqZ1t9V+OwY7275h9YPW0Xc7Sz0DCwwpuPk7rvDHCHWd06CKMNNqYDS+huDpLKFtGR7xe45pHvG9d03MQ8j3xf5kFUqj2PyAwJyXUWVyUCMWGv9TOkd+wqCEM255eCvf31zRvjMbe6zKJQYHFbv+BbDyT4rC4Dfwf5LiTq8MUS1JS9J4f+H37wD3/4w/c/POfiD8L/ww/PnvKnF999/93TJ9+/8HaOSduDf/78UHz/7PBwLJ7+cDF+9sR/NuZ/ePJi/OzZixfPnz97dnh4eLhNrt5HE7zzwRE9eDXcC+53zyzfFpfegvvxetr4tjyOud6+mdrA3blivS8IDkGLH+jeslTl27spl41mp/h7tujhxskWzS6cbFHnviHvDWyyQQJxsNNjCD1BXiikSC7RIcPiBGJEhI8Enn0WK8n2p3EiIhl4TPKpSFeUnj4NwhRhofATR6cnzJCfLWard+V4a/ZH+9PGPWFh+3NO6611zbPQxXZ9Oteh3nfCdlp+r4Pf/RVZa2jhWbAAnAmhxdy9DiQ5TvR1fAgqSxt9zT1Jbca5bNFsmHMRQPUUvjXC6NgR09uNkXz6JECCr6aSA71ah15tQ2h326re5hodBTIuMqnCDYLfM+GOXLQIjpuOBnIZAgxN4ruSKItUqdjD3+YinQtzqRHnxZCaegLmHAY8fInIXCOV0Dli6l08r+r4ry+q9lQNdsOE95DYSzmsa9+K6sKwhcdr85gaBaB8n7w4moaBB/BGoBPYJhjkcA+WVW3asia+gOyw1y1j/jU2fq3QpAoskB7ZMn0aMxOx/gYJxy88+QxYHRWG8CFNBF8U3FYYhB5ECu4VjyHBAy54akFrvfrwV7avDBuPXd9ilwFnR54nlimbC+4DYqHC5FA2uyBiF8DehQQGDOkIOdrWQiziZHUAUZxxlirErQ0a6Nj+XHxRs3q8lrWu3MOuu8zy8RCkL0AsyhY4AGqI28VOjnHH6NiarX/J0Kb1uAkroFcvVUuIvcliaRAM6Ew54oeKR5b46YEnL+3javOtL+PIB941opaL/K7UzWiT31hL/aNrC2RZLaR+pZ476xEUOXSxW7zEqktnboWeZlMnQBjaujDzb+jH0JEUI0dru1zDDvai2vjXSBJlM5uaE78hpsLBDtV+bIwdGrd1LTeENLW/KDqVs7+/KLwis9fUUX1YIfEeNFRV0/HBxiVSC0AGzVsGRpLEhPEFADMqo5fcNafRLnMeL0tknDQznXdL/nsm7C2gt/SWLRNxGcSZNDRvwt4tgtS4/KZBInEHsbBF3ag3+5X6Gd8o6E7+2d+bP/mKSzEOIgmW3DS4FExmFzR4JgVPvDnjXhJLg7YEsvGE/aKENUjuUCoDMBseRLo8QCqSxYS9jVkiQnHJI6jOziPAR23ai9sZTYN/77lKjLUdfIoQmquu6SAu8JjGudeNe9M+7hLgEZ39DkXWvCxJROQILcFc2kS6n0RO7H+H7xVuXYeGJb2aPjwyg1P9qO+Cp+2GAZ1GZkFvANpprciiGpvKtYOHVAR+bXrczSMoNVlZFDvatfCi3ZEFtSxVKwUSe2lGUAJyV4+dBJ/Yx4RzF2QSiyMBRoVFnIjcamDLbZZJQqWLoJ65j2YMrIqHWYkXAFGOxxK2k57iPXw8YTBAZfaQLMdN4jPAXk5rPKZ3yU2wBSQlN6jBB2sHcEER9tcZweXAKWmgWGW4X/h6F5wc5yiPNOQ8HSiITaPDphJZIVN1VEusN4a20W1OnWELTugiXRuzoG7HtxRxe6fY10YDW9uPb9clb0++dF+LXmuOH3EuexD54ku7qETNdEejugP/zYAEuMQyUBPASNPlc6rllnetSdD4a8l7cwOiBhszojA773NpFS42HXyFHzz4igHt3QKvYCW7ZM4jJ6mNv6LHDpPTxYqy6H0RpZD5k9wpqcJyKNCKXk8+6aI164Cnm3dC6w+3x2rqljcT4RkndLjufTBRK7XokJQOR6g5Hd19kbXxOE9JHy70hi60sYLtfGrY/RFU7zTtuUPGkS5px3AJuiQcuwmTaqYljJJpRBdDSNIAkBAh/fgBk6Ot5BX1pwlOrb9rXB6STHXPB4K5gwRzQzrgINVtK+pOOeqa01nhmn2ghjZRpp+U1XCf++hS1HEAQTSrGrHVG+XoBCLM1Q4KlSthVHEi2b74fcQi+J9ZOmJhCv8V8A8x0g5POWKBPMNyAfivKE7pL8rOOXp7fPDuPVSmCjx0YEMZiVB80dWrdi7vdfdCGLbGQZQLyu1PhWNRHe17IANQZ1IdHKYil8DMrrY6EhS0G0/hiBC5lRP2ikcQKS8CjFjnLBTcasD20V1yEC8PMDUa/Sacjg0PGd5ntq8ATUzZ1kgFwlEwzOOJy65vLMrFibyBz6s5mFFUVggH5dwzE7OcxrobN8ZGvHS9v1jyJJBAbdVdawitF7+jOxn+dwZTQm/jDIW2MNVRd6o2rr6K9E9zF5HHGETeCo/IBCXJw6iE8T1BwVsWCeGrCt2674PCLS+scbloZnk1qkZVRyT8V8vfYXpes6ceDpNP30p+l97vV0ID4PDgCehgb+eR46AdYdCJvkQM002o3vD+0dtjuh6PJ+w1V6wBAH1You9ouNJEmnyY6p5MGhxM5fh8636xfY+ucOXuYhW0GO+1ogF4X6vlAL41OqFgBTosVOwgS0cpjEmm6LLNB2avl2ZC92a54sTpEKgGnOTgywYL4OkhugcJiVnXLFB/QSlUB8na+TipPEyKjsvKHSU12pMq9aGZOXYj/dAXQwyaKuHHfC6HxmB2YY9Lz6Lz9Bd8rpq+Q6PpkUVFcV7GBa72yANhOwn4EOnVoeEQ6XVXFerdivTSkvIqSvkXzI+7qdCve+SP1eS7ly6eCHSG8HC8iKMgjZMDXdS+Kdb/GNu468SqfqCyneqprAliM2CCqgFLxCyQCqECNt8MSnemeN3OasFbrRWbCyfiixdmIIf9okURGn2hKnM+KJGctQ/s2uHtHYbnFqMOOzqi8LjEU+fB2paJdcOcAcfrJPQF+t9zpx1Unz5UoPtOUk8TPsNq0u2yRi10Yi3TNmevlqPXAjKW5pVXaMdDZx1qu5trGoiLC9LEsX7iPlP5hZObhOcvw6AiMr7r8OWobkfKos1iDwUyf1JZCN1PwxmpDr7XUpsFruD7f1KCejeWfZpdhIHHxuxVzhx+IYKwQ9XcS7y7yl0nOem6TtVb4r/1UdtlUukImSCOC3iL2OJOMd7tOQwNoS6FitEapbFeFyp8xharMZoEo9XEixftBc9U/52DhtV3LfnodrE+bpqRbdHvNxDyjRLyGviSYZXvOLvcJca4VsBxrYJ78LVbkDHR4Pow4w68dhFjcKLmtBCXeFdYrRXl0/xpxap6fdl+Zy3O0Ul/VF/ZDTDG+kDlko3tNrTGG4iNHhjCwBA2xhB0TPk1GcKCXHCNFk9007kNnjYpVz2ViSNGsVeaGbQKNeJHsmrj2mmWYAhHg33xZzLtX6w0+9sXX7infM5NuFStL9aPK5MiUQCAnUam27N9HY3bY3QNLw8G4+sbjK9jMXbezFsyGW+Fm8NSwbzclmjwI+qb4ArgbpAErBtkfWHzpmQ926ot2X5SNSZbT93WZNNgMCcP4tD9NSfnZK3FnNxHRBKXAlrNEr6c/46hFw2m6NfQ+E/Q9C9v/vq0IB29zyDhRT1jfDZLxIwi7eNLkTD6DNsPxYx7q2p09hv8fcJ+lYKdp3NQ/sdwrUP9phrgOds/P3334SMrDfz8MYMgTcH9CfspTiHOe7HgkS9ZkhF+qgS2jVxug2LWZC05ywVT1onX6eXVLdmSr8KY+xpEJfLp2lLs75YTaypxRL3rTldDjAbquXPUE+/8LqiNNlWY0O2fEDlpTPxThK0XUVwmQQwrQx8Lg5mIPNGoMp4GiVth1F0xuyuNS79A0jbFCFitGDojaAAkU4gxoKGyU93jid3j+3KPlq45Ye/xMEgG8ezSi5fCB/8WNsnSOfAZj3CW1Avby00sgfm1qEmVXhzBu08K0bodVJwunTZGBPdTTE5P3ksMbvv736HR/07EdO/l3v86AGdiHCETM52VzuKYjvnZ0TL467NXYSCi9DXlrXUXflpPy+7KQO5r2Cb+wHOZ5kO4EClvcbGfBkm9f5233+EaxDRdSPH05H31Sn4EKLOpPc0zu/szq/szDHRlcE3TEH9hUqSSzeMrtoBYcjhiTMfXexCP/iPzEz5NJfNjjJrEj47YRZbao8B35nHoMw6xfDJlU4hlB6R3ydI5/Gi6R5d4ysMJO4rUR3Biapww13Wlq3Vpx1ZziaVIz5BUVm/2uSIT5y9BOk1WJKMy9VZlgSFE7CUrXRt7r0f6VcnknINBUNWAM/2MULYrmg8Bj1u/NwJPxxzqhH1ELsk+BLOIh3LCznUTGOwXWJIgH+nJsYTt5OEqDTyZjwLYBJwaZQ4obzlMykOxXh+b54fm5QkWGpCSyq94c+F9hgnNRQRrhXOAPgJpei+kTLkDqBGSvrxLtIcOQUwlEGhiXolhxhecqTU9vq7PCCD3N4iPxcKJjryIHJbueQmUrr0gol7zmimOCoN0Z8f4wUzIFElPcsnDs3mcJY5cnj/Dz+xCpFdCQI0eeEm+ZC9G7MlTLDXx9Bkqbz6Lo3CF283OoxiQV+gOni1iX5zDtp/T2+cTl5UwZ8DPzDRfjJ48HT199gkhx9JiIkRL4L1z57yQZ1I07lqP3riXtmgQVpbO02qWTsOBeApGP56m3PssErJWJUHzwK/3LRACZ/GWv3G5zd4/i9VVnDRfybW/8BwrvScg79/AZqgvBZGfyW1/SnhzLNm1tW+Ucxvp0jhPt2ONXYtROK2FKagzZh0GB623hvd9mewGkQ9Ua6vXOsuLXJxB0t9NrbwmfoVZuoaDGVz8QoRdR4ZaUmUshqD/81OR18E4Y1+ELv7WNF+wGpX5ikNEi+JInANjMuyGvbVeIxknXoI9YcLOg8VC+AFPiUPldVcjBKaG/LZwxRIBZ4cElvKI8yRG+LDFotWf5gN7muXiAmvRv1kZPSz5gUiR7cemLhIeacd3canQwMNQWz2ntKKfVNvzlzrpFwVShDSifnD1jt4eQ/FG3TP+9u59YX0q58WRyt5jEiYJtU4g0uTEoiyvkIqscnqxylMmjlJdkG+0hzK8fS3sf38kcWoRpIk4wo71X6/4Unh7St/WdCr/Jv19QmQLfwiXcN1AGPxk4BDqpiN+z3gI3UZxquEONNKBgTsIg88l1AOZ8iSVfwtQuRKRr/85DSK/CH3QcPGeP3lasdXU5fPrHq8rUz+0/VVRz+XtaKKylW1ppP9PWoCub2MPPwdh+GquI76vfQEKC1gByKjCYehlasKn2Mm16HpYeq3Brh+WOZev5kHoJ+JGjouNlWJKuSaFiVqQK7oFTq2xyZP8obUb6uFh08O9J83fPnQ83omj3W/n1j7c92XHNn4Ry10WeqxA+zSpQ5cikc6KzSeY4+5PVGlRiLeOGVdWYe5T8DsY/I5OT7R5WoKwecG9zyyLvDmPZgV5sS6Sx0ivLk0OxeEzGWeJ12gtI18EwTUKP9DBz7Ydv1kkenboUEZkytPMIVafowH+/CUZUnWo54SdkyH1/GX+44hlUQgm0/MlKGdnieAyjlAVkQIKvYoUIcT0qwxq4eEyE3hd+T1w/S6wvN6E/RJfwqvUHNc9jZkaG+o32CfH/oOUwK4YCZA5XAqfJkLO9de+Oxz7fIWdTYMwbFaH8Eu2yVL9TVPBDUCvxhpqIIhajrcsPBlnkrG9353RPtHs7arm0YZ2cXryPjfO84IZHZYTCuoqxwl19V194AgcJOUD8q1KKca/+NSRk3WUf+73LE45aMToxsGflF/pi4eoZrfoVdwR/6GnnYAuD+K1AwgOvuaevk7ZSKdBUp+KtI5b8kM8TcfUuSSSQH5IOo1hyKKYhXE0QxBAOHIa+w7Pzu1EBeRLtnbfRR9MR/c9rIkzjagu2wVeWAeg5p7eJV+fXLc3vimSxlUXoMNxhwB9TGKoVAzIEjD46YIBPUJpcrf97oTJ3O6FSHkQyp2/AzsdpTITDUEqmStGJcNrUY9Nvw4voFeRDVzzFrBXIMdrBEOUZVgQeToYDapwKBXiRwZyt25pX10tC0muxFXqBoqTS6tbmfJQgL5hZFZOgS4IzAqTgcvNZBinGLAyF7bAhVzsR5Cpa8RpaE9RCZDHkoE7O5elzRhh0+/Vzd8KmHIcTYNkcWZ8FcXTh9d0DLECE3YOgz5n6o3idoNQMoUTVDowI+aFgiPe5rnS/+BonJtN8qpnEpHczVmc6BNeiFyqWBWGWKAhFmiIBbqVWKCNhf+UYbiHcKAhHGgIBxrCgYZwoBsPB9pEBJAj9WwHI4I2EAC0RtBPM6sbgoDuYJDIEAR0v/d3CAIagoCGIKAhCGgIAhqCgIYgoNsIAnIoFENQ0OaDgjYdAuTYNmdIUPcqUbAcqnBOvygfeskK9LEdVJuI9VEdWtE+HdyvNTjNOB4O+IN+MA2ED54Xo9N2jyQawoZKhXFvJGyoE4DlaZCoUnNuUJIO/uJHxiejEJhq4yqAtiuQJv3GxUr7dh5JOvBQNvdKmPKDWDzMrjw459SRZYcgRxqyOcmWYSZz96z6dcKg8kruqnI521gUX6FRIoi8MPOBrgKB05E9auDQIBTTlMVZOiIGBsghOT7CVFyJRFUMTuc8YucaXeScXc2DULBzCwZuQiWtiFijDxNJ9rmmjucGFdQDVCrDIr8D19kKfCtTqLio/WNXOUUBpwq5McmnqbgnEW3w1KFjjcxhyFh8EQaXUE0g/+aVsJaDCtWTRYogH+Crtj2Ngekr8HBpkcH/yK7mUKDQE8ElecZ9sQQLA7Cgol+y0M8yBo+jBYWK8WfGCwu/KI/la9oVC/Di3jjcrWrKVPasEX/TeajMcYGCe0GcSTyrE/YOgjn12trXjcpK1+GSbfIbzaak/vijumCmBhZtmoerbcWkaoKDnzcC/OTjTJOAzwREF6QtY0VapO8YBp8EktHrDF9vGnynl2tNzOIKzyRWDE1J8z0zf37qGN91RCQPim8VCX+b8GOiK1oK+Q3BYWrsnZEca6PE4H1HnBj8bDH/j3h+CuyfftqMAPABeO65fUEAnTESV+cj4IZ0/M4xIuDcPpHnj4FRZEuQa58cHhr6YcrjIhtSwEXiSyBT7IOYeD23z2OXge+PsH2CMgpxORwDnr1zS3uC4VIskZkLwN+SGmR+uFidPzhOtbXQMEuCLYcklo4ElhRWUVQ2MWRx1ORfWitypzqcj1rcfCRN6NSJf+6ixKW1U46G1l5JxD2Hl7p0Wy4wlY/d+mCzc7tiVRoVOVyD5aSVy7RE4RRCkopcVZ+Izuk4ZhE1tUCZVqvuFB8XS1FWhhuY2AWc8V3nXDvGo25D7z3Q0MKteJzITY50a1mE9qPslk1wQexKWvquPpegBPPZiGkfZf4vSq4BpZg8h0zFsaxGMCAYIjNOSWR95i8Gl/Ml0cN4ydDsK0ckjKMNGsQ3P5BpEHmpeazjRY0CaIxR2GLCXkEAp8xhknVDLgvvhciKm3iw1rgn7COfkVqNJw+MTFyKcRBJEckALEnhCscl5xC7qmNcg4RiSAG9GTTPJWxKNPsRMueIWNKBYjHsE+ghAkwI8RRVYrh2ELqhVwv1bxgimhusVcSXqD/QrXViH4xiwn4G24JaO5yBFy8DFbaaj0OtyY9mcUjPvxAgVag3SAKhMBqUQLSkA9pyEM1IyDDwjNo2YbYJSVg+TB7C8q7YLI4EjQYmrQwkSADVd+1PLQIJaS/nsMm4cp+FWOKiqMb6kIDRQ09OW0dCjpW6U7BJqCE+ODEo791QnrOLVbMq+ArAx8dSwALAOqo9gpxNmPpLPKkuynBWogxnOWWwKIL55xkMvnLi89P9SLoISn4j4CAFjjvQA9X8Hky1V9qxdR4we7b5IHw0RDpXRcA+gavUZA9ofbHesvGko2VDBmTW7mrSoHXU3JCnqJNNU4zjDyQ7+fCOff/i8Amix3Y2dfTttPa2giQyhlZ79856Y5XlI6PtmbYjtxTvodb5WteYmbWzCnJijukU4QWGi9806031X5/Ajz78UdGlP9J++45mLRQDtdiwROsAKrWaVm2ulgCRPtfpEMAZk5Xr8xP2M9hHgEqejxhX/o02KQfZdcpnuiHIXtz3lVFlQc4DbokBinvbWmbNLEx0Xet8LzLvMyScNBCvEYlzhdv+I4MO0O8gPRKEqDWLE18kTYp95/pCNbGNZQ2amo1UT85aDFqYPqMJVSd7XJS2GV/E0UxLSw7buDVKJYefmdE6NAvhF8R2sHLRYpERPpC1LKESPqG2qzqn8kg+VfNMVsNxeNDHIQ+YHc7BcA60PD4chgd9GMjMORyBB30ECrr7cBoe8Gn49m1k+/aaz4Gaa30YB1k/lTmJzLA0swsRxlfutVHGzrZO+5tUf1SBVdoI6vy6sur2mFLVZvyjbQ5mK5G6P4UQbvUfCsgSD24g21bPU7bkUpvEMadvxCBzjH4Rwn8kmVUatcP5oIGMzHbmq5DvRiUTIXctKZW5qWpqIcpk5z10dyK2JHeh3azrTgqdt97qt/sgVCL3Jnx2aHfxedVCZoewFp138MavH1/BW2B3QdKARphCz0RDfJ9itIF0qNs2oqqnm3SovUZ0GRiPAjZKIPITjODQC/iOyDoItAStb5rym/Caj+Yl37bCzQULuUyN1Q5cUIE0cC4/0M8jdiE8SCjI55II9lksKRxQtZqw49b4VYynRWQQXAr4BsSSqowQMGvmQ36wvqYOxvkPkI8Bh9McBnUEoIz4CEKs+p7aibG3/1g4IiV77nkWpUF43mQa3oWx9XQV4IvNK/468ktzMmXb64ZHvnD7tpbuVdMqbut7gxNlcKKs4UQRNiPdWKXFlRuNIlnl/PdSJCFfLg1uIN2FOPQFVqxMiIk2Mr/++mFHBcJBqlT8Kl+5ZXdfxS6VYh9psiP2j3/84x/jX34ZHzvLhFciAFs0UY3l1RTYBxsKujzxnH60vCs56aKymP5/JMEpW8BXz2E///mJPFguoDBEzwHa3Yt+dh631nJV1MAZbzgdRRUrTufosSfwFCi9OueXEJMI8k6c+EawpMCn0qEiF99crAiXBuOb4UwBaA0Bd+dFnHF2HbQ1cxpGRsDQbA8v4sjoc45ZD0rajSppUmtA29HQvDiSKY/SVnXslWlYhmRG+Ef9lO3T8OWI+cECgvziSIUefnxzquxcjx0amFW2XEXrYcg/UHILqPnkPaP+J3gIEoAczNsvRQLfBFh7mSaZl2aJ8HG+CSYo4ZsjJmAUnILxKGWNYJyQ59ol2W+6hnGn6gNmH4Za4hu7h551uNfAa77+NVTc4UDDEqBA0lio/Gd840+6ffFS0o8mdZY4Dx5vTEOvxqclPJKhLlXO0yzh4Tjk0SwDqbsdGDqI0rikl5fhw0gU+1ucfIaxHJ1M2EdBKL8cTRzAEC7wEidCAmgol6XxVxJ5sigRMg4vNTgdIbkhKAEm3AJ8AgSSiS/Cy5S59q6XJC8BUhS38W3vnXPqUl/4YglgCnAsvM/sbZykc/Z/40TwCJbzfSZlQCVM4kSy5TyQuOYXPPpsBLhfIxRMPqQq5r4ZKaNPzshadVv0lfD1adqc6iKAejaiIZY1C9/2LhnMmD0vk2m8OAP7+1mN+gEavYJoUJU54imj99Bun+dUW6UJKiGiBTxB+6sUyVrzVfMRVS6m95eAP3vK11NGxNlbCCkhSdH1DO9iw/q6lCOudrFO2UmRWJ1JwsS2pz/aA3njTK2LBFQueeYHEviMr5/iz2dJFlWepIFIzkCwj7wgDAiJMojOlkk8A8LW1GzKA+oo4Vdn6nSeiS9LPPmwU3iCzy4DGRADOlNp/w7XilpOpzKoHg5ndjizd+bMEjiBixrvaPFj9nqxTBXqOQLjc7LDEv7sAIs6wKIOsKgDLGrNpAdY1AEWdYBFHWBRB1jUHYVFBSVECXVVYfIcwCJNISgwTTFtqJoAHGeSBhyey3gh8DGJjbk5a6KkRMAHVdInqE4hBD0yg1za5AeHEZC1C76Ftz3Skfup03b0wRjMGTVh4kuacA9tJtoZXai8pTzSHk95GM9oihl6ph3JZT2uzVCIZyjEMxTiGQrxDIV42grxmLI5paKKxsnCsAXDCpZTBJCxKXuRVOfjK/tVql+wfT+p5cZBHtXqyekehdNuE8uiz1F8FZn01JH5JcgVTtMo136j+EwjWNs/BxTAcKaO5t5I2YzOcpAHvStnEFpmdqXUJYkfmBkjkkWdwc+Kn4dWxgbosIDVYaAbhu7YNktG0WcF43sI0doalBYQzbKCdFiRkJUJLu9gpH0flkm5S3SI7cGpg5l+D/7Lcl360d7zw6fVtuQK1YIRQMwqqyS+4EDXrr4QSJVwEU2DGQhBDwTdK/eGNbi9jYt5O75vHZ/RGoKiIz5qwKxVuLzpDikehEy8w31nTytub3hPWqEidX04N1j3CkhReJwuVkxEaFdX6IQQ9LLksyCCP+j2bDakxI0Zj7XPO4evO7B3K55PF7pMHZxMHaBvl06fdoSsUcvc+omqB2WdoFd97DDBYoi62RzxyS9+GwAuONQao2H0Hr1Co3YxXwh/YhiwULzd7QSC3oWgmAYiQeLVxaqFTuiwMwiIs6PXQPVvjEgrhr9tLT5tbWKytVgXE0DY6O7wyE9R8TLYrg4jHFY9ImVvRdG/kRufC74OEKM0EXKJUYaiqXokXZxJT58/b3Ym5cthLFpdw18MCVNOn1YYVH22a4uHmB516ixGa8oHIjZ1oly01huVkA6+6n/C+7QrANFYJYz0u00aj6mlTRrpp/VII73bRhplrMAju9NGC8BbpehAraKdoHR28pDZhjU/ay7Qr786v+yE4e58zxVyZ20Ivmm4C3H4O3dz1aXqgLCv1/FXDYGcXy76ab3LRe9uQ+54BdE3OoOKwCASMVaGA4qjN/1jvS9JsOsmgous/cN93JrUUy9XrC9I9JYTFIR6L/oxSArr0hsFoL5RSQHSWlNtVemmPP2kXnEoUfqRJkJ5Ug2F8zFfpAItylVaJgEEHY4IGKGzMBzLJY8At3z8FgL//UDROijHxYNwRcbiMVJPhTsDCABoPlEIMBHUouJYiC7hmF6HMJcAXP2FeymbBxD9H3g8BODtkFIwb59ebY1mcHkWT11kwZ3LqM/GmU67rTfJfGebZH4oWmRAx1Lbl4fhVuNp6ww6I6tyRbN7pbMDsFLUQixEAuzubBFEZ4qH5YHKjWM9rAxXgPUzDORc+Ngfv0CPtzjzRZi6TVv9OsQ7vbHhJSLEK1IZnorHqN2aQ0dFzasg8uOrDgfmD1a335UseF3Z0KsYElDSXObJyY0+uq0abJxgwviYfAj6NWYRgQfGgCY5R7hhpdV8+OCroTxKfe1i7te8508ireSecoAikAh803BW6vB+uClrF66g1kTboQNh++SYgDXMb4sMHghQWSkPG8A28vyC2+c6uZRsrf6anzVywCa11lOzhbmqUit5vjZNdkJ33SErercLDjduo7fbUi+7i5r5LjqETfVQaDyoXB70lbhJfrmKt85VgGPJNW5UmvAAqsjY8iWxNVN3BuiBJxA+hJ4UBU94GoAFdjzjCnZBe/wqY5mwN/CBAEaLpxVgvAg5C9IoQ19oqAco67xcCp5QDVayl+WrigAQynvIaHoXwqxDEBWWp4iFZonGJBdzHwr88GQ1RhwZuAdpsAiiHdHnd0U+HsTaQay9WbG2zPgaBNu86UMWZm2uc8PirPXpg6/5H31E2pz99RZqrZPSU6yFAuBN/dnSrfXrHZJvC5ux5oct+XKQcXdPxu147zck5fYuNnkUhu31JkuotNxLYlmAfKUiZs3otlVhV19/RNNE+a6AZqtqBI1yYRchaTUMdeTnQCvoeAqiWag7MPPPi0jW1pmEn3AI2LOeHQ9DhcG2GNFjcj5piGsocWRqE4KsDQcfFk6YLk5P3suXVgVIHqmJSUi04SE2mLDjhE9VH6GYpizO0h/xkQW5C5Xh0XtGxaTRy+xP2BHB1CK2nwZizKFp9FADqxYbruU5hsFSFUf9SYSs8+LFRRBBuaVdRrAd6hkO9QyHeoZDPcOWKQ1QvDsFxfu6kcuTN7VcXcQIGovNwV9pHtfeMq+L2GKs6Vx5sH99lVzUIrR8LWcFUG4GqW5RIHmbhaGq+JyLZHMuqbZieYHR0gZyyYVgYKFxVghxWCFK8zhLkyzyeOoOAqlEhZbrsdT3tl5Bv2GV+69yjzp5w/JeY3k7lp8b1rj/Gner6jas7Dor27NY2rDIfRf527cc/KKqhCSZqEy2kLusFkdjr1cWIBSA4A5qPuD9V4sL1E0ix+MwFa9Ge/nWNEt5eqiPJIuvImPOicQVBrboiaDqUTSlYM0yMqZ0z71Go0Z1RB9EqtHqA2mPyRhMHAv5I+ioUKLIso5owbFJh8ii3IQIS7V5EXKoQ+ikH/ehDuFQvHo4DkPx6uEcDMWrh8MwFK8ejsBQvHo4DZ2KVwdO0M5S2MdQ43qoce2qcQ12h0yKs3rosopZBN3/HVqWq7jBEOjd0kfb8cMsm8Mod+H0KO32gIOR+lTWHnP0Zm4HOGuZxNMgVPSzDQbilBrXo0BgqcJkxqPgXyq6VHVfh/xQDFhyvTphHwAqDmp86AKHJlAejItRbFruWKW1d47ZFEAV7gUE1E3emvw0tcEuuK/LqDHuTp1uVzRt53NtV4FvPtcjdjUPwDBLQW3AR9u3hsk58ME0Zv+Z+TPB5vEV0+EQxSi/wBRktz8+YeeUBYIRQpEx2N+dS/WxZidGEB0DE7o/N+v2uVSH+1Zf0HC0t8xcWVyZfdlOs9QFtBYnlHPv9WApGmctf7fLNXwJUmb1I4EcMZnB9ZR4NWG2VKEHq5LGC0A1GTEpPIylS8SMapR+FismVxJULgyfAWzXMAC8WnZkoletIXW+8kE6YUdR4ZLqauwgi5tbAB8NUubHQuaicQGFBcJTf8/ilN+HUoYF8aWAX+ze1Zeb2s0PsCuInMOd+4qxwmuT6ebIy2sWP9Rr1hn5zSnISH7ZAQPOnEt9mS5CHn2GO6rgudAN/Gx0eHgI6YhYK+DBZCJ1IK+ZxoTajvSPdGCvNeP2L9jMVbMZO6BEWkOcOgpFOR1i5/hfCn4/TwRcxyCanWviZQIUZYGQWTHvhPL8I1vEl2AbwAK1cLF8iOOH04ZiIRZ1TRELk6i6DON0ws5JhbfHQL9URkLFOE5P3o+oZ2ni/kdmZFMYKwTb6tCJBZHuKFBps0xB1WDWABmE8NbumqSVb681zPsjXd3kRf9d3Z+2FMPrX3PFZeXB12USA8dE91RzTuF7eseNiP3+5xNnllASiEsEl9Pg1D5GCQEnhFfI3EpGM7yRwD3jBK9gjN2sAzxbl97XJymj+FbFwp1jUFvr1ziM9z+fMNWYqcZdx+J4tRLFYgopU+XOwsGq1PUsPw0iLwAY4LG+mPBbMsbUbxF5K/t3yJAW4xSLHS1FpEBPggT+Vr3PsyilYXmrC5HoizvmUgopF1RCIBHcS8fqFkE1MDHjof0hGXtjHopEpZ8t4mIgfyfgb10OqvTeh+Bfa70LiQiZbE4Z+IBt1JmesFPaN3XSoeJ5ksRXAvDH5Pwi5onPLmOPX2Qh0HzueWIJonq4ArYQJKqwrEjGU+4ZJ45syim4sQHUXwoqa9oVM91+UyUW/dSSHZbD4OMLUHh9wYNwwt6++/j6JftZ1d49Lx6q88ItIscO9p9nt4Ok/e//noj/xFK8tGZ//vjxlD07PPz3f2f/81//TemMIgG/hS+SQENZqtpZJoODZ+kcRA8MEwT8zOSRZP/xt4/wIAYu6QHzoOQJrYWp1efMQ943VoqET4tOmX0I5J3G1blZnqvAxy/hnQZeSOXsHXN60nSQhkXe4CLXH3kuocqyaCdIjncVH/9oMZ8+r///7L3pcttKli76Khm6P2zHJSlSk6e4g0rerlK1t+1j2bW7u+ygkkCSwjEIoDBIYjkc0X/P7z6vcF+snuTGWiszkQASIEhREiWjO7q3RSQSOa71rVnBkHXepcqqK7/mtS6lUJwnmd1O13pbYZU1XpUYY4Xvavimj7tCb3R4+zotgrtjfGguUg42xWa699ezD+8ZfYmRqgOQlHpXFz1iZ1QrKGHpVcgIlSev2OgZO/MAJigzOghklK2HArqeQlTcFbAEAOs89Sa+ePaK/fgqOd/XnVfsK0DD4OvOT7b3jH1AlAj57ybEZFDEcy954Ag3x3XYBV2UKehFoJ8fXyXGDGPqVlVMHvteIL7u9NhXch2gpxOfXwyccP515+fPATtWkJupPpJX7In4xxP21JhPj8k4uGc99kR1/4Q9TbKJXENsZj7Fjz9hT1WAGyW0YPArmH8DcQX/NIJ1U3GdPhuwN6CONEzQRfoTwA743j8pj9N//Md//Ef/99/7b97IrWkiwt2OP9Ydryc66KKzDAKdhXEq3VLY2YcTBlHkWSAVpAmT1cJy+JbwqcCEX0k61hm58EsyJ1ctntz0h5ZMvD2ZbqWfMDLVWEXQwebiU+UHilVE6tvavJFk6nMp3JQkkV4uvFQ1qah9jjDdhP3dGueWz/AzI++vurc+Yr21mlcjfFh5tRKOMiPfES19KR8X4wvfSM+Mkcv1yczKRVcVh14lsc9Psyh9dTHPPpBuLuXzqOHdPy0sW2hiZdu7heY2Ud/8xfK+Z5kpvGZNIZTH/CzG1hf5FYP81cJVmUIKejP17oD9jfjH0UGPjfZekAFp9HJPkb4LaIa50l5LXJ1AJBPkw0Zza4/t7/UYpIvHN40ak9qlL2FfqHZiuwAvKWV8lm7VJaVkk7YEdIkkyFvXUQv5lbe081T1JeUbVXlHZrdf45TZXLBMOGouQO6cVTw8ei6mXJ0ffHN4VsfMav1Gm8YJcgqUh5sXbtS1HA3yqLy/7kVF/Ont6fZa2JVm9oZ1yqQQW1ujDPhhIK6AAzZUIsMW1BPivNNcw2+kdoqEAyDPLQr+KHOLlHt+p8LtVLiGCvf2aritwFjZUzIvcP9ZMaMK5PyaR+lCyVzo9xTOvTStCR/Vu/YHRL9CBp6A+4vEw+Rk5DPAIp6mAkBoOEGllkuuxJhxWC2tTNEG9xr/ZQM0H+SYGSYmVWnd7IkL84FR0t6DwyMbG9V6h/qPGcImSjvywjvKJQH5X+FM6w2yOxtoDi61TzW3RUGPt2EW931xKXx1hRJQ9bFzP7w677HzOMxSLxDwzwtvdgH/zeDQp+evqQAM7KN+MwaaFDA4q86C+uj/37ILLQQjKR+w87lwvWwOPTrgwuxw/5wAzLms83zOyPortYogW1DH3Pd4IpLi4dJDbT5JspVx5/0QExzp32GewL1xmnnVaayODCNGLk8DlqAaL5wOQqs9VkTrkYBPpX5X/mgZceUwJdkE2jQeXdlm2aGVzfqjvf1GP/YaKFa4338Yd7hnqpZVvWFMQkgcMtctFxYD9lz7/tsYijn20+ASEnHPpDdRkIYsyZLIcyBPqqIJSjRGYOlHFukq5lO4Ze+82UUKZpw0dEKf4UUYsBMehAFWnVH4ORbs3PEFj+G4zmIhAvgHB2lM/6MPo3VSvDXChf9EWRz54nzAzq8uvFRIxwZs/H/KxoTx1fn2gihL1fF+zTROY9y/goxVcDOxipceYBIBo7LJ/uaicZlRWR15nMpObwdnAqREPjfngTwIsTDOAmJsLgiwmRMgtGnxYRrVawtwBjLJ3ae3pxtUEijvl+UNc1+QemxjNmqV2s1c8r3h3kF/tNffH34ePX+1P3o1PBi8HB0MR0f/WSdoqu/W5Ks1tnNyNBntTZ9Ppy/3Jvw5P3CHQ2d/eCT48/2jEUfHT8JfdZ/Ap02f+OvH30/sYpJ81VwcjNFXlpbqN+WTGqnd/Or/zHxPpKn4fwm4+zwWoKW0ESmdD9kWdoaPgD7Ui4A1G1j9jqy0atdFrPWNwiE57A9f9of7n4fDV/uHr0ajwejlwdHey9pDUquNMPs9cPaeT1/yF/2j4eGwfzDiz/sT5wXvTw5Gz48ORuLo4Aj9Bj2TmFp1GO+84Ltw2QlPBPjJQR7VROAAZLIZwLI+ep4hNAM3sOA70HxsKFGMJPfNROr5IX++7w5f9g9f7r/oHxweHPS5mPA+nzx/OXIdd3JwcGjbIS8ZgzvZWPFSix+qkAUUvATMoxzdz6q816jPNxdJApkZUYKt1c7JVky2sukU62GY5ICGmbB+aSQkydOpKERSxi4aoZRBTAGxPFKtlcIQ1mn9JZvzoG/AjMYF//T2tE+Xczgcjg52flIGTJ6IseHyaFNyUStWaNUC3cUC5m7fEHy0/NIP5f/0Lf9P/c9OjldbxLuqytu1h9eozV0/LnmKPgnpudLiev1euFhYILVyu4xP7NXyu08mzlzK9BQqPFZSZp+dfjhJdkyQXzNi/aF2Iz4yAFNDn9Sgbaf7BQ1/KQHVdUTOE9RguZ7kVCXXQFkbWGoczr0E66okYRY7Dastny/TuhqnR26NVmfqHkrrXl21ymH61koFrX23+lrizn22kiyeYuzKnC9kfmPTuavitaVdvJagcAnzDUqOLsyoQpyQCEV6aNUMi66Es5iUvfyKeyBvj9UAzN/ENWhBUFWklwhUJthPDpZ6oBNNZAI7rbi0rpN27GgkkywM2P+M5hg6Ae4XIkn+PvgGoK1W9nr3kTk+4MWpxPnNAnthweokl1jl5Gtk2C0v0svctmBBRFzX1d0Q9Bu9fHVw+Org+eBgtLc/Auhnw90KiOZDK+5r7vlfcHoqAbwqXKpcoJ7pumTy1BoeaDKvnLsY9hHjJKFfk76o9VHqf+KuUo5vUDzEVHiNtZyK7eXCNFtojgOG/bLQwQpO7qCyf6ofqxmoYpNVz2wWorqEhDnh1KYhOVm5yofdKt/6Kt+ekez+zGHrFF6qCYDY/aGY+bIKS/JMoiWwUlQpQJ041jhqDIrQfF02h2AjwNBkXFNKftC9P1YTGoponhKnXjGLcQsqWJRsWz1mNW1BHQxp2eoxadiCplGPFc1aPVZn1YKoTsOo1WNFmxZkaVUmLfA1m4c3sAE+hrn/qkbMigv2svtn6MRWOS92p57VPN+UjU5a4+3EpdNud9rtTrvdabc77Xan3e602512u9Nud9rtTrvdabc77Xan3e70rhvQblurb3er/EC029sWAoJFxxtSJ8pD9UXlBcsV1PST1FFX1FT0NEE3eOU6DTxGR3tEcXjpubpK8YBh4dbSr+yKEnBLKu122uvt1eB22utOe30f2uv7jgCyBWtuIPBmA3EtPK8BiOEp5PK/BbEsthtzJwEqphJhwH7nC0pQBUX/Lngwg3w7F5Bs1Azb8BJZBwKSV7ymhjKzYywc7jsZ5igw38EyDd8F1Du0qUpvHuCyrsTXKuAFdwmjdnQoCzDjZ9beVg84uaf4kLuLBlliQZNQposG6exlnb2ss5d19rLOXtbZyzp7WWcv6+xlnb2ss5d19rLOXtZZcjp72YNa5ccYDSJL4Ww8GmQX9O7YFfwXf3HDq8APOZLc2kCRN4pJH8N7b9QrhaqY8keGXbOnJ5JbPqvWw9QtGVZXohcwZc2nPRSC+EwMmOoAlGykKlVD1eltvJiFV7oWT2eg214jVWeg6wx0d2ygKxQnEMsvP1KhFT9feGmt+BbqAemgAgK1kCB0UpGCnUDwuRUaVFHwxAs4lp+uRSM0AKgpMQ2zwMXSomGqaS2coFeqki+c/svwO/yDap5jvUa3hzF/YezNPKg7yMIsTTyXLCRGgRYvkXY8FoW+5yywjOlTVU8tTblzAeftGfYWccwhrXR9XsKyIMomvpdcCFdXOUNA0ts5GNVUT8Wdf6LqSl55gRteYT1JcR15Gs60gw+aBzJcsi0ucKqQwIC4fWMJYcXKbw1qYJ7X9tjCXpmL+qKEk6TsaMAX9IbvG+hCZvjXGnELuPCN73T44qHx2A5fdPhiG8NXiVUgcRGg4UQBdpr5/mKDFRsKfy2xwBNHqLyllQSb+1TJj8n2apPqoUZ7jS9UdQ16MVUq/dv+nImPqt8rzb3+s7mRVDA+Q8TDDUEXbackH2eBK9s5qr4Goij29M3x2V/+9OH405vxmw9/vH/34fjN8Z/e/Tb+8On0z6fvz56hRnjp/OuUL5KbmBOyLQfhqYQqBBTXIje6VTQ9xgBUStwbbZRh4bMNEvDAe2mwuu3zAd9SRU5W/VZN9ZHab5H58rZn5CXj3D9knEoZZBPnHs/3FZcwHQuNw+8n+msMvsaezj1U++HDXDAoj4pNfT579hrEqQTIbpCS4zfJJ3dyG8x85CX6a80lvoyU3nAzf/Y2fQkLKt7K8lgnueRuyt25g3MMBpI7IQHSDFdS0yP4qlfS559TNreqNfemRBLHYBtxFgHXUYVebnt91NeoANGahOQ38G4DW7nsLWZPUZxLLkByA6lP243V96SU16NCmu7cC+TLSUte2by6zcTBZmPUfMlgG0VAU9gaZdCjg6yvjpVCl4CKyagLG1CuuaMp2LcN0ANja9t1R7eipje6KnYIKL1Qb5fhllppJQt9fuMLdo9Fhh6lyosKD92WuovuFB7C+sJGRZXXl6hiTKOfJDJKwzZaL/WKaVNLQ8Oihv5+PElCxwMnCi9VxbQblGI0G+lP2mnDHopGqNOGddqwbQqHm2d+6kU8TnfBMNVXotFGIuJ0yJLxM+BBLVnaQoeARtotRkg901BRvqdACrmfhBjy84QcJJ9Uw5EsJrdWZakKlZGn7LtY9PHysYh7ccKeisFs0GNPfnzd+S4Wo687r2R14dHXnZ+WYTR4iS6fHDxtN7XWsUdkXNTA+/71n7+qlrBTAnZKwE4J2CkBOyVgpwTcIiXgNmnDbk/l9WA1OPeuq5HalM1rayTnwENd65kk4+HsLkmqByYd2EA2yqMwKiH4Ml0+Zh9SbmyggQ760pEt7xAd5XwdxUuAr/qVHnG0vCD5GhqZesFvLc3KOt3VSqtrjQ0iEWQ3/8gERr/Ue0m6VNV259XOqNiLiMdr9zRs6xryu9rvWJ6O25KPzLNex3FKAEU7Y67wUkm0qgimZVmohEBK0NwqsissLR+qoGSNfisv2eFq9cs58KgQfB0Bp7qBgyD8qY54tPMJ+RoWyM05DYVqoQst6mzW435rsDor6zXOV2XljAQM1VV1azah5Wp7yVjTQHsL2+P6KG6Jseq3rnXalW/FEMQq6qrGB+ZO25ZIwXweCqZYt6qwIL3C9WsIqxp7wTRcfv0veDKeh3HNnYuKMWDGbmoqaH2aQmTnuJz3RTcoLZWkpgZhNd/v5WOsXApNvIqzboqvM3hk7te+U1ebCdIsxJjyiMppixURFnxNkfIHYB8z1vOuLWTq07s/VOjrsvpEcl0r9YngB6g85AUzP9cCtANiOheSqiRCnuE6Hl31NhF+SMm20rDUbQe0dvIdXLuzVUDSrWOkDvF0iKdDPNuBeBpYuyIHHVtfg60vS7csp1ubbnlX7hjjq7BcWzJm+XoPnA4gPZa/ACabd4/5WcACkIiUkoXSo/8Ljv+A/RHG36d+eNUXASyXS4+J8jN5XhN26op5FKZopf83sSD3lzScyw/GwgljN9FTQboFwYnYLlBBiiyNeZB4nX5lU2w/76y0QarHCwFunJVzRPpPSAg7hx36LhYDzKIBX2VXFyJQhwTOS+mEsqvKiaFFfs3S2JvPwSc0cJnvzT3QxKUhJEiDbKsxd2CvBzv1PhH3Pa4lvOL28hTnNHusAqwbsVOVtZgeIl7wTgSz9GLn1ciWjZiW0M46N8cMVbLVClDJeZ4aCX32W1tHCMW4VC55ZsvKqs7GU7Lin8u/z5+RphfCosV8Ilz0Yc455t+/9cCzIxWxUK56edj1k1yfTOAp2WDOmWoOmQ5ed/C6g9dbDq9rEjg1JAY7DS7RMVSp1Sahu+jJtA1iHqXkVIbJ2cKYzUPXmy5MEgXp6tDXDBKbLfp5IgeNBCHHVCDfhkymFuaCKU49OZKnIAJAGmDwfdIWMZ2nArgrfUx2JdxnlCqiSawIY2ZVHiK3Ji8r5fyMXb2sdvVZGfgkHDVwAXq3xALS4GGHrjedCvTR8nDLWUiuMCmPZyKVIBjeUTPRyzZYTexZJcvF+nLPFkg4t5Y2S6suA3G10+zbLxfvhOq5m1IU/QQ5mpWf/TT0AfyFgWb9dE+a5CnqJTG7yXOs1HYz0JtKiYIpjb2RUCVgiQhcm2yV12lAmtFOrlpFrGJv4eDjCZt4vvFN9ElPelCMIEl5AIyvumQJ+nhlc1HKC00fjAW8TZ2F7B8Zj1MR+wv2jyxMORMBHgUgM51w18ljv7o8RunDxzXQVz4N6vD0JqQ5w5Niyv2kAYvlHhftMtWuI+2tLN1JxIaHJGfWBVlPNVHnbkslu05g6wS2TmDbFoFtRbls7iVgGt9VslKNPHIXQhcZz0N085ckr0EOu0fhi0avi4XplcD3nDCQ4TR+49Q6ucwul9HF2IxcBmgfhIFm112ZX/tENzYFsT+LVB8zx2hh9xXRi6OKsHgok2CadfgXHDBIro8lxsidRHWu4GSyuVjptUKlNxMp/dGQylYYRum1Ohr90ONvW7mzfCqfult3bFklODLP1r5+H2bppbVSzKVW9LhKmNPyHtbML6ILOCHZHSdZDKLfzBJHdFsRXnX+lSvMfY2orboAqmz9RIJbvMvWiK2HPq2yP25eakTXCyF0WnvGNx0VZTtTeUmIVZe1MVZz6XLkhSUkCXxMIWCS50BZLR0N9gA8mkxg1uzStAlUaQbrLs9U/bts/RZq09aFh1ETVUze8JSS56OIDACTkkK/8moOQKfSQiSdlUua8g5kPnqQWdX8mwuq4tSKS/MWFYjqMKEWMYQC3QQqdaBhLtHLVEBv6QVQUIZZWngI5exQaeKFQcGg5AWOn7lgoKzfqvsaT/3hxBMcL5qX8bdr7EqNW31RmPoJP7rg/T0m+2NO6IqGhVi/x/LxnvNrpW/f65na973WbvZFknPbUokitS31yg2aSGkHwKqoOKpg8WGKxK/cVP+i68RW9Y7ffpa23fZFqqb6IQar2Ktqrzu4hu/4RPg1amzhuw1KbuG7tRr0GiV3iKNd0dojSXLtt0iRZtfO5mTZ9jQReBNP31j7lU/rF6he/drbQT0kL+1NnXcav7buj3FbbE8LVoDC7w1vReAIE9sPjFqsPy6EJX+VtE3Sfcfdp9R7aKrEcPFYYE1QweY8dS5EwsDogxUwMU2bQdv0QtTJnze7HT1DDrr5PSuc1J9oC8lLxFTX6SQM0jj0E3Z14TkXBfJPtn6ikR4G2eul9JI8E6xtoUp5OYgij3VX1WH8hQrb6A9ISAYMzEKrkwE7nTI+SaR7D/hKgeMUkE6BzA/qlOjPGSOsXOB6Gm/LDiIZ39iECZbZnF2EV5WTl0+psMitplJ8o2E65SHr7feF/Z5Yh/rrXZKfVhuUSctNDlNgRiZzMfrQlL7E2mz2LKsk3b6SYy5ny0Qr0rI1qm73l0AWM/+ncB+/sKvFzzuJykXnpzbmk/+BDetMJ7ia5EnVGGgrB/kkMd/QsqzKU8eDwLsUccLjhfLTesUwSpzNYh6ggRGsd5ATdM69ABOHAt2HTuQLu2YnEzAeckVWH2Oq2htkev2FE6W2Eojw5DNINQCpL+G3Opu1qXlgbigStFxnqn48A5dGPKugAJInohC+eLC3V392oFYdD7QB3jzf2tX1UVNGRV5uXwWoIdJy/Z9cS+CkiV39pzyzijCVnAzVPXyqXbmq2bwV/SzBXK0JTEPD6/epqkL/jIEPLjgiok+toVEoeNRSWtlSMuVnPYJUSLHBx1bXrJpAZkZUx8CYSJnyUFxlV7LK0uLcaq2uuoLYFrNtPvk6obIA7FuqUngqZmG8sBk2Kl5VyzQhNdqIUmH7qqMYii/eHNjJENJS1ulC9BxbdqR2epUXirtRvxZ5WuWqsFWB4wFh72JJDb30vbyieWmG1SlUVlOPxArFES9ZFBSViurm4VGv9Yqn7tua0F6b0Dqb16rMTu3HHcgAWSLiXbp3tfzuSyLiP4v0DHxdy0KAgu3QD3AXzKhuM2qZGB8aP0lUcyjnaiTeMSDqBgH7PZqybhOut+RsX4zduX2lPmkPdISAZSiyCZMEsoajlDUB3j8yQQfNsjUFXdjIQo6b8ongoAw0vkZe1T6DTh5CjhBYwdtB0kUkCe+LJOk7F8L53khg3sF7n+Rrx/jWCb5UCJuDX5g3LZIcNI7lKBWQNfbGPuXinx1SXxlZx//6x+c+6JlEkKL20FUkSmBZMS8hb2dRwsr5pwfsM6gkReBGoRcgTI6yWPgLU3bkPo7vyymbcZBqX0NUXMZ9RgtlhqFhByKGVykH+rlvrtHvnuv64orH4pxhrhPul4emhpIM8FD1EdT/67/+NwtC9iaLUXr4QBFxV3AWyV6qv7lB0sueam/rv/7xmeWmGxQ0nq1FmZf3uRadpLPHXOF4CXSmlFPwDXltNkQk0fHbook/JoM1atUxGlPjqfYWPTPR6+Z7byu64N0QFkL+Oc4E3GNzYVe4avlg6zCo+nIzctWaLDhzlRCcCo7tqS0z1rdJcf0n7rJPeZ7AjR+bdnJeNTOHRc93HFAcAgsdpK3uoLKkOjlAfRrS6uBXEhz0MucrLyerrB2PGvJXdJa17LnAVVfi04ngsYN2a3vcOj3/jJrX06JaN2fDZ9hIlu5iJe1vyVSHTWW2cx6nnuNjoISThnECZcFmSY+RkEcqfC9A4x2U9ViEGZafizHFZ+BKrVOCgUpABrC20yIS8AROTtJj8zABq4QvLjlkSvdi4MtfEsHOga+DLyvIVeegNMPQXcqygMoemvqGdVrtzQBl8HprwcHmQlSH+Bs+lUuShnJVBuwDLpb6e8WtbLL+6uBI6hGMsdAj2gaQRl2Shl/3ZhCgiu/Pyh3N+fUpjeQQN0D+MTLs5jzg/iL1nGQMZjksU1BZNV2+JlR+Zuy3SzJluexUfVAbpKdxOGe6X6b6HbA3NA1ceYx6ZhPhcLQgoBVetcR7kfLvgkFmWvqw2imwmbNw7qWAYcOY+ulJ1zo1Agrlg+OEoNRfMOnwQDeNFEsQNBdBQF8AiMgJwdyQa4Yn3PkuAvDbu+ApuxIx2N5E7BVc7BqiufH+VZfyd34NWjlG+iq44vJyU/FLoADFddobGt/LtXv6e3tD3GZS9eEfSu8Hu0weflUXA0nixHXao+0awbdGw+HQCPJnfAr+i5gQwAtmg6L/HTTuNQfAlxggDaZ1rPnnKgFW91Ou2T3CDvRPtPlHkWvzeCqEmycNrwZvKhGPKGY4VS7R8F6iUblRgbRZv2t+tebk0Vf1RySDWPlL4joSTp3TWi0YI8exi6b1tZ0dntRU1ipYaMeJNwu4n5jT7+1MYyHGcl2S757vJ2PXSzDZhXqKP4/jLKg8ST0RjyHBS+B4vodHauwF4ygOZzFBt9pmU+5RRzG/GsvTOc5D4p0sBvF7nHuAjZ0LHsxsUfKNmHT1Yhfdme3O7P2e2baSdV21hdK+lvehsj+5W1pJcicQZU0AY1QBzTIPHRdwj1q21ckNxtxqb9MvgFdDP/XmwprmwUt9q0xbbWm1m/YqwLOyUVLbbixFPlE1gNJ0LKFslZUFUNp2rZbUT6zMtcF+igp/7o8TRxYAKalE+RW7WExizCAh2ypBCmAFvDVgf/FmAHPJkVIBfAFVawmG5i9AbIZHWpyEzwkaLl5TP1LPGIeXniviPiLOeegKv++KSASuAs7JRZj5LirlJwRGsRwkd+IwSSTYTEg0UYpfh6fcD2fMF9eQhIxUnhL0GmQwp+xLTwfKELVnQ22m1dDb4jSsusEpn7U9O8tmBlLRN/Kjz1pYs5XtiQagXlt9wiTBtJ0ECm2tZ2ynCS3WgmTDul3Wg+iZw1ff2/yktYS6+gu1TiKkG1vVN6Q+xRd+us3YWh4vbK5a2x0aluyhIdevfKoLK17a5dLi5icfl7Q6VDxFUOHcK/hfmEExKF2vsB11HidVJtZC6VGI2C8HVhjyviycrtLfaXFfR6SJXFU0YKd1yoSykoO5IVL0OWgvkD2QrsEVsxgrg0vsqrX+ciltGjOd1EmOG8kRdQOe6kGuja0q92lJ9VpYjlzZfox709tRharUFuf7eXfGhob8T1oBIO0OdcYJpYv0yEs1d7E3tHwWDS91uGfNuFSvjQCQQKKJuHaEcHXe2v2V+vESBjmGw5jHnr9gxgavkj9JfqCg3t6CNEqmM3WT8l+q8KFFkubfnoiUr2YLkB+UctauUunWmunjJDmmNnZHV7muZ9SfVhFXbALQOH9M2rVicECpJxSf78jV1MniBOlnQ/zvh4iDGwo1lcpcCDu69MIs0YTrScLOA3GdjqndudTMStjr9oxyreAR7ooYfcPRAU9q0OUaycSPoIKdi3y9qN8BOxOBC+FN56qm3nmPnSdhnMJ/lRYbuz0n1/NgUeqZcVAjJxDP5qXazMLZwXDIzk/wMxSqfRIGU99zyAnvvCm0u1ujfI2WeCmtUGy2uMbvtYpcX6ZIxGrNI0ymXtBd30BxPhoWNefGsHOZuNWo34Ke6suX0zdyYXPbkjKdFEmDuBTxQsdLwMdsa1rCncbwCvJ7qxF+EpHgGJmiz0BhvIWCHQF6nExJyMREwjTSfngVCH08k9cUBwK4CW2PSSonZqeaLBaYk9Ah1x+M+5AI7kkiIVOjWa24HhaLmbb9/33n8HAoXhwMh32x93LSPxi5B33+fHTUPzg4Ojo8PDgYDofDnd7O0VGLZgWb2sth2agmriMflawkzxo5LHj7A0T3cbIgyzAmQB0w8NuJ4GADqVdGrxFe5uFrtIeZR0zblLOA/im3yWK6Ms+Sln5XPUcpnxXP0HGgt1rb5AKocuWjIhZeuNPt/dawOTBrLRGuO/2+6mG1dVBvvZYBvrgB5PKXhMBQEszYScUSZhT9rT6EaIuUTcfv3xToxo0W9DYvAoltrdb3HSUovcjmPOjDKdZLjRKqXuLTWRDqjOf5AiYZxmu7r2EVp2DGxEc24uqKKBYOZWKg1OX2w7HiyNVriGzBIZjPJ94sQ1M5Spl8NmCnFPkWhExMp+iqKLO+pHxWGLpxQledQwEAtJ0EIhXoSXmrobeJZLvErHKeoDha7sZCVfA4ViNIuW+x/b82ObmWm2ESvpP5IFIRDmpjbjcmq+WHdhjj7Uk/gLvhg2zY08nvfS8FUYcKMsASK5gU5hca9WPJa3Z8dnJ6yhyeiL4XJAKLPVwWsMlhwaxuxUy5Xf2wbFYvYKhcHQ+2+bbTPC1Dj7weBsccB9LSD/z79OwDe3E0HDFtoKDU7f9JeYODbC5iz2FfPp+wcDpNRPqa5SsIs/3y+aQRwuSGD/vMJmIaxq1R4tKpUXf3OrepANJ/0z2TvWzNjqlZ3XC/itPait0CM/iKNP83pHXwao4ElGRV9KKpyAMElNVbzRH0BI2tudCW40lpxoXVM43q1Gd1XJMwvVDqy7SU5aSqo6S+d5RZv5jDDRgY5U9xx5PWa3qcgPIGgwVAZBYBmt4U30cG5YTziQeCCB4Myf3DCsckBJXzq7zjeZYAB76URy7/TtNkuQeaaND9kqJokaSiNOPIi1fAkn8SKQeMj4V/PsrEpAUVnqrsgoNGV7EojFNVNKMn3dri1LBRThb5noJ0Jnju2fgkKfmScvnt00+5AEjSPzlOZ4EPWnNYxo+nnxCh4hurCatzLxjrAa62ODQo8s/L8QaRwkmo9s+YPZcJ9WknUFKaKtWHnqysk4NN0DOfjK0DJlPWGYo89APEk0IWWxGQudcKx9RJ8cMr1HC7XgbFDy682UXxnCRw+yk/7UqLoWUPDxIqBYnnMNWVnHpLCQQa96THI6I3OFdAjhMs1qI6ta2IgqrcaPXOU3YPNRpMxdPL/8Zdkh+RqY0gZs9QkapcELzlfXjNsDbBlZfA3uTjw/m2cc4tRDBBeg3LrkGSIA9ip3yrh64hP1maN/jh1klKcJnbHoozuPiTBdM4I+0x03GjR1gV70B+Q56CTv3ZgH2MxdS7lhgfEk4hLe1T8QiROFK3iPrJ18w1cHw//+CA9fOefVSBI8ktEhnN80GW6MGQ5dULkUG1pFA9GmEW0P3Lu/V5ktqFI1VCyRhx24ipkgZLvbCNIS+34otlGk7aja/oD2BdTXQf11ZThgl1IM9vnDv3aU2h68UQKc3eZ76f50EzNaZ5R3MeRXBYvaRoPltarazoi9E0ZmxnjpgnSeh4iKwIhWA+U6VdR6j65dQ6D5D6sTcgeMhRfC/4bucolfEiTC1HIrd7q7Xbm74rbZNiWHqBKbUa2jLPucoLqFWtydrJV+hF4ZEaZvs5P41PTIQhy5Tldr22/CqpnGV5WEgTVAAXjM+4FyQYyTPvSWwOJ7xyEaQaKSeTCdL7JX0qSzpkzkFSbMsfWFyzMoEA3FC3dn8Jr3IKbk6VDAV8+WK9YsBPe4y4MU7JD68G7ERXlmJzvmDkj0rIg5zwJuLCC1ziKQhteFLy+JOEwuG+N0HpZXUk11NAv+HsSBaXL3RuEpaLAfySalRpHFM8WXWc0MifTF21gOM4ZIt3DA34N2mO0l8wxwkVoopHqCYk7Q1W9IVFlyWz8Dyiqlr5zjThsu582c7XUjGrWPhCCaC4fMv9f7BZL38NDwm6/CgJpWYLTrUAota+IIhIPWgxSUAaMgWPgablfrFg7A0WLIxnPPASGe8eL9/FOnRQIopLKXNPb5yim8r5SlZ9YxdekoaxMVvVENL74c0IwNsohLk6gBbhtLArL3DDq6b9X10GqWZuUg4rlcx9Ik4oe4QIYk+We5Ot5cpBFkLffBzFoZs5WH5ZtWyDSlZzxDR0Qk3efzXqljzT1GmLC2IZ7K16eRZG1zOnavf/bOnxby2kqV0UqqAwd+VHIFaCWT1lmlaISe5gAfzlJ6tn6ivq/IZzQGWd6AVPxnPppF9Fboa7TDuPcbARjcvxItIBvrn92EvGaKKyjaSccCH39jJHaMymOJSaD93EhXJJ+oD7SkBWFI+3Nw9B0R1wYGzokhxkGAVGSQXqHAb/lPnff+fx9090l3LHQXjAKKV0vSeMdPLIqq6E0GfCsohsiHUeiAQ8OCpRyN/jVp0Jb6+st/ZksuV1AUZi+IKhmwVivDmPv7Ono/7h8NmNPCAMHV3FnUFJmpY0L2oE0EQ65ujf8t1oR15w6vJrq4ZJPzr9VBff2sW3Ptb4VllloA63VHBlofntgAhLHMaDwxNbgxwmmf+9DywAHdc2Erew+yNnEj9bBDH8WRRjGCBDqR1A2PIHYvpMkP1qUAsqutE+SB9QCXK0G6+ENNIjrFZl2kJXejeBEVU36hWTH9UsFMCUFibyzhLVgmpOMt8X6ZiSPtqaN+upvXlUFPZyPnh1wdPxBY8iEdRw0auLcMzRQ9PaoDTdYn+lt3tqJKjBkMwo3ht/F+2SlT8Uw08eWSquU/B9BE5cF5v5UXJxFZeZG1xykpJ3Q4mnPpwwXL5rSDHq/ZO0hXEWDLTSDtsR80flcyriuRdw/zXLgu8BVMuaCx6gijDOgtwMB/AhtlZTNBV2JvQwYjQ12JDfwH1ubQUz67OWz7e9jhOd9c6c1pnTHpW5ozOndea0zpzWmdPuz5yGmgjICtk2fY30zq6T6rfDQifbroI4wZt69dXoTIG/jCmwJMVUDlmvJLsZMLd0a5rFhoJxsbOlPSBbGpbcaGFKs5rRvtzQglarxrpby9l2aZtuw4TXwk5W9O29gc2ss5J1urNOd9bpzh6R7qyTDTvZsJMNO9mwkw3XkA07eXA7fSFu0Q1i14DuS9whTqhle68Ipvqu945A7XWK+nvZGJlqTYc9lgXSqwiy4UQqrDZgF+FVxS7g8CjNYmXdQE8LvAoUqq0+5yXsL59/f9djIOe64RWmEWSRzyE3ubhOyWJCdIppuZZholpd6UanopVr1Idq768hDaAbCsWZg0sRp+a3fw1J2cgKQk9aJwezrOkr3BP2FFZRhiQ/I5OTuE53adfAxJjO/fxn+GvA3gsv1anp1XYkhf2g9zyo7ahSQcmsfHAQGuAQPAfYk859IHcbdEXRE7DK0QZ3zBegueXDJMXbr5rrq03bPImORRSHiinbq/LlVPqTbmwSaf1rLW2tFuZbBM5FHAZhlviQSLEfZ0EiM+3IzoD4JqmIZIi2veNXLAJ8LZenxxwAE/mfEoWAOJ2oXCzyD+0Yd/K336RznCF09/IsYvgIZG0qqYa4i1RQmOfD506xvuATw+nu+NR4Py9I99qsMxiEqooaln5GWT4W8/AS+NAJTNp09KNByLwcVn+KQLym5G5eAiV+5RuQZxuWV0Y7uAP2mX8XCYOqaoVOZHG4BRS4yMBNQu/GQImHMJyIe255TyAZm9pjnDH0a7txkCd27iUgjfwabGqDCl27nkSm2XuoutYuMqCLDOiqtXVntjuzt5ghaJ2iR9UDlKOcAiI5faMzXgqwN6CgG2hFtJdqdAIPQF5GgIJaZ6dYZyuYevEcEMrxUhRDWbgNiNJGiRpmKWTpr07vXCu4z2nUhEcRhKLiSWBRgHPaX9mGp8wXHKpBB0LiVXyMC3CeZJGIE3hPNQ/Q6TEfNUvD8HsVhrkZqt4paV4WtCk/45r2mfzD5FZH2owxFFezqLDRAlzBk5QpmFJ1KnWIgnUQZU1UJAphkz3fx8ptC+alNuMwVLoRkc04JuI+LhudZrCBsMiLhO/hUXFF3N510tjZNosVhGFUWLPvXhTJBYMhNfUDYgfcZaW8JEEDekMho6BsdS5RwPNCZyzFi1w/W1P6Cz+fH9Xl/owFgKteU4teyAVQPApdsNrWK2hjQ+i+paI7RZUA8co2SlvkrWfYfJWiPAqFyA/VVOghQ2WhqQJNkGMUc8QScSpK30iVgE5dybLo6LOMOSuVOjjM0ihLB+wD/lerazFJK3yIuNAso1lLkZzUylDiCgTWVPiLAXsbi6rfk9wLqJJOKdO5y2ipGK3VLyT0PjxZtIuO7+SJTp5oulE1hzCvB6WBY4F498BoFlEm+ZriT7re096wdEhyntTuNinfsVKFSXVHjHExaGrJ6o4wKsrSccIvtaNRyYr09mR/f/8lw9T3PIVMyVi2UBT5DIvDKzQaQv5bdhVDCuvgtSEdBaFqCYVR0rqk1e1KU6tR1zij/SGZYokXYsZwBWcqcVZU2MZYtMbs6wYqCsIx9Y9AUw4NK0XyRpe5v+kmzPGB1U8l+dfkpcTJz6VD2jlzRRCSytyXFWqkmxL3Wf5lqtu0xiaoWWJXyFfxX2NkS4qVjuWvpqNcrZeSTdLGIkXKXbAKhFpldS8KFOpTulR08ZxUT3vDdllqDhvpefaG5Y8r9xB5iTuZY4stkQMNypfk3bolsWP3hzqqP3cl6VguiCCsJjC/ggcJkX/5kVZuJJJAoBcJvd1knCTvDgkY5KuUwR0qWXBQz7C/nn14n2teKiSZiupCo14pWjbmV4zu/q8hTRiZ93NSts4wTEmMisHhFv7OAz4TrqqDJZ+fvmFPTz+c9KXe5pXyC+l7oaN+7OOAnlnqwnQSUCcBdRLQI5SAihaVciZEo2YrFqWJhSM80BwhiTeYTqv0BQX+YUGKQRpn6H0+D12hen7VyF+kEhxgMHq81TIaYDLkp3gSBgnU80qoIlPCpwIddwIXRL6YicThkZDKfx4sPkyREZVPbPVyW2IyflSCnardNIWLlLHpj/xCbNfIAAgXri7+UtjwMe7jUmmuCDJA1pT7r5Nv2Le+ScKhHsoiTnWELcS592HQn/ih8x1MSJeNsl1mPc+mgIcFilKOZcXQEQpeM4S8OLxqLIW2suSWz7gSSNEALWQrIgEy3oNIgJpSHqdjjF45169TIkWJcDXIB253XwTAZjXGpLY1YyFadZMR1Uu4VRhWu1C2inv1xi8DHhZJZ+PNWn6oaw5BedU74fZhC7fgbSsPzF2IuHEWtHG8xWvyKQuKfrcZuVlGFIBWgBaNgmlV2MWelKapcDWb7WxUsgzeZnMpQEkJSSqqbsVnlB37V3yRqIkncs6vWSziLAgwbONSxKBplfJ7FItLL8wS6WUwYG9U6IS4jsIEyj/zWRAmEKhIfAcpHqwhFnZniYgvRdzHfsQV84Io+1VyX25M8lZKzZqThvQfdM7LT1zNaWOnb7b2wL0PzTMGCVjrTlSOURViUUqHlM9mXjAjhUNeN6+qjDCeSXIhf7eURlyaev1b57/caS46zcV2ay46bVt3Zh/amc21bTnLy//1+PPjRCpxxHJBsShJ1x2mGp6/PB9GMb1F8/wMEJhPwHR3LacLKH7bYjsu7/WtrUsRP31rlx3DyIZRJEdvIdsOu1i4eB3MovWJSF9jGtWJYGIepQvtYSBByUQGFqJnoSr13d7Pucu3YXeCrjma0tW6utctzuKKsRMVZf0K8LcCQnW6mEauvkKPyvv8ZuOSvYyTANzl7UR1SZat5vxNeTaeFVdfvkXIRZ4i24t1yX9WySNmvlKXqGzuBe9EMAPUMMpfyWK/BZWtLEBllJYxFL5RyRFTyAVT3sVvmNVsGvMkjTMHcluMeZKIJJmL4KYnRrG/ceKEkR1bievI5wFP60jwLOZB5nOVfauO5mEZv7GOrka+NHHDOWQu6Cl9xTTz/bH+0VTzh1eBiJMLrzH0gzuQ4AaaujI5WhzOPTKV8EmWwDxFfOk5otR7xAEwyy+PfTHzUm/OU1ulxWX5gvKBFpemV17r4srCKOLQF+Oi4eWm2wsRL/CFSzGG3hvJlQ7E2QMlRRxGESL06MJLLiAs5SJEbuWH3MUH4nrq+ahkcgoU27g36KzvClnToG7bZNownUYMsop9w3A3ereRnkWxRzmRQnt2p5vNyjwm5bzm5ocLU7WMPMdDq2fas+5sHlk3Ji1509x9fz6OxRTscsZI6mijTvZW0V21wKv566PBaDC0xE/l3y531rPMiqBgPBMG7WjLCCrv0RtWGFlq2RIf2UZW21vdgDTF37GTgCbqXzlVVnGODDZpA1MnC+sKu7oeECifheJnSwO1faJXwF5N9t9an/E6tf4tSn22m9QOIBemXmM0XWL1tPk2NGPpzmum85rpvGZ+Sa+Z+6SazbximzxJzElb6WvnZ3L/gdstPErAxWPzriQpn7VxHPnMZ3+WcKcUFkE/1sVGyMxlNk8RMnArwzs1nGG2NmLS5EpiBI7FKksapP04Pu1LnR5+4NdwoegCATrTZGeafJCmyeYb1dmPHpP9qN5QtAmwpelgl8Z8XbAlN6jBeVdCnVvBW61S5H7ms2O3WB7r2EWsA/6MLf1xj/HUggsjvJcXUNUVUuFnh6fcD2dU+LMmAvXXQVe3US4LCEFTdH7t9phbE0WQx73gyrp6+L4cib2c1qjDkh2W7LDkQ8eSvygq6/RYDwJacfc2CsTAV3d/EHf7SaQQK801A6xPmB6/VIMAfsr5cdvAJ3ytALR+bSyVD0RCjhuG+ixBSJ3urMM7Hd7p8E6Hdzq8s114h0rwbAbyxMIXlzxwxC6fzWIxkz6fS5KafVJvHeuXTMRzggTazu0TSowv38fisxXoQyVrTyhVcZE513XqBZRLudhzD2k1PmhbXBbNgtyJQ6gZBTZDzHQ4H7AviUq4xueCfTz9BOHARkJ6+d1X+kunnxJIGe/4mUv58kOZH20OlexFzCIOHrmvmRvzKWSVDiBmGDPAy+5jwcQ1vI8lB9RUITQc69W6jM+4FyQp4/ACtqeSe1kAnUyxnIFM9RbOJ+hgIRNAo9lTroycQhhAjUCPHItg9WDuYBediER+sccS1BYt9LdwQbK5SggZibgPQ6GvDCjBtPwkunbgD2FMf1DBdr2JEMvsq9aU2JpDqPVMpgWVFajQkfqOIK/hpj6l3Pmtavid4q6L/HjqfiAXK0SJy4IUXsJOzz6wF0fDEdOpU9mVl16w/6Ro8gCctDyHffl8wsLpFO0vAfAB3/snBaJ/+XzSMiWrfWYTMQ1jsbGpUXf3OjdZcbbVfN5S5bWJPJqYe3XAjjG1QsLwpDByQGYjDPAfvmYhoMA0lJdbnlM4nuUDbak28WsLDe3zOBO5agHVVJmCmsLneernCq8gDoH/VCSzBQ1UzMHIfwvUGtIoLCGHr0zvE4cHYEOVfAOPE1Y+5r7srpHeBwvj22XCbxy7mkXDgIN8aWvEFghDWNpIBi0saVc6I/aAB7vDG3k5R8S3vfqN/s3k8qefTNaL3LTKeXtUxIVq9UB+jjdtGHF7U/bNTqY8Q16sjp3ceySsH08/NZ8QL30sp6K3Y3XKbgvnTt+sbtLyDM9zW0ppSySMOpy9nHR1VcW3LcdWoxJZSTJ9DeVvsaiNKnK/ktR1Jl9aU+hS39y4zOUFcK0Szyl+Aquk5RmSkKZ51DcUJItFFMbkXURFyuW7PVm3PKA7io73wB0duGEO9w26B1gyzED80R8uEz127Ceh5L9rSIM90zaeVInsgM29YJwLnaaoo9+SkH8CVgBeklBfYXYm7vs0uCJjfw0AgpgZ6Rx5Sn9pMTTOwJE1KYCN8mgGLPIgMEsNborilwlecLwrCmuIkiZhemHMExK+aVI4YO+876JQtU3vEqYa7+V/YwSAPA6ygLDnC/MYUpGkYIWNy9k/TNYmd+dhMVRNjz7kJeyfIg5Ls4Gf0d+tE1I7IfXxC6nGFnixcUqXDZS4SGtwlkrSDDRpkO9WCi6lVlJaIcC9EgHm0j0NJp4mSmtVuss+JcqDnoGEf8KaQGBpPRgOGeIslgW+kEIeEEhPFX1rBSb14hXGttoaEjuvZyRUfrPES7zAoM9lfrKcZPJCtXhcpidJaYHd0GC8dDheayQg13hR5FcD9hsJT4m5xRxo+qWQxVVFUJVxDQ7VFP4FYoIhNaAU8a3Ts6ySLX4dGbWA9Xq5wsTEdcUcmeqNlRAcXV4bg86LwhoQARzRW573ZLlErDDncoG3nexcALX3KWoXB9Kz3qFePv3t0sAYcgWq0Wj30/CKx25BiabMFYnQpyriMZD+qY39bV6fUyJpSnVjv0MD9gfAjgK57ZU4wBUakXJqjM67qtMyg+CpksNWEJi6O7HCndh6zZSh+TDub6eZepiaKXVpN6+Yki4h8orX6aHeCuGeSOeRVkWV0WnK6NteTlkmpXYpQY/RnmiYtJSYubfR4+tWpesOPbax0hVOTbsRFlawvKAffe4FfZ8Hs4zPIJA7z4cuLWrKd8laFdVGjv/wYsHQ80nmyyewAX3h6TxXPY4995wUU62yuNiruP4lm/OgD/I1BkK6XhL5fMF8PhGWyphW6i4zQ5n9Lqfzxk50xH1biHuB8N1eyUokhsvIdmty3USka00CeJPM8gV3lTwhAhrWUq8y6k84ZNCBdxg5Hw/Y7wQH2ei1ShuBuqOR1alXtth5NTJw5KgwHhGPVxlTLjOQE3OEotFMSCPICMcyHA5U7UccXE2Faj06rFCtylWPhsO6wSqv31Yj/RBJU8zoX//136PhkHHf42RMUJMesD9AJI/iELL/uT3pLp3y76CBhaRZmBOwubx2w3iTMG493LMwToHOO3BOMZ1aj6Ve6oueZiGoKM1if8A+Qm7Aa+IJWAQV9b99nBx0KwKyI4CsWjwn/bx/G9fQW7JjNCwcYJ0LtuW8fgO7Ah6WvnqVTVE73GNZJI8Lcy54zB24eQP2oaQHBqfGnDLZRj3n1zo37HBY3AHMR4cvrKy6ll7csOqmTz31WR0n2pboIYMPNqaAkn3r/EXoTaKHLQLlqL7ikOWL6ync1cuozJC+8jlybVC561xMK5wImQ0sCn0f04hjF/pkJBloZpQOG9O7AQuuLjrp2ehtG175pWFxF/HSRbw81oiXmkNYxidYNBJLhM9sfHzbT3YsktCHxJ0bOOIadrckBbmYaeE4hp5kwSB1cupNPcCnefHLLEiEFWRUwof0p+wy6hsplMJTJVabippF5asIlAJavNb1NQ3AY7mbICJ/CPxF3lyeeCPRfbkqJ8EHlcACh4yHsVA3DVJlyk8jhpaTmRZRhxVMVKYgxffaRNGVFxTQqMrdWjuxVLHg8wQqlPh+7dpVPgutx3BM40vuj81DaVxME7tVFvec1uZc1mbEteWuS7qSL5/e9di53CDVxLFshxWhXXNIUApQl5AZDKUmq+hHQi/sQnA/vXjFzgmvnCPCOkemfy69UjgjCoqIp/m71AkVksGDMmm/sigytGqZRe4qx71VpQXK75nfo8JXqA81xNJh7RXoTZkk9EpAvnz3egZiLh3H6mHr5Xi1uL5WfhQVGb9xPrXobH2ahin3c4ZSblBaOKXIoPY9pSYwpHOzPxv7sDGyu4qPPBzuWwRaqtvAUjGPwpjHHrrkaSUVewqVG1IRSKvhpYghoz/eHFfMYu5iRcoI8jsHjieSZ11Nwg4W/7KwuBPlujP70M5snSjXjiuhtuoXC9u/R9uPQiBLzD69+qSNaGxH7FcM88CfbAaYiuHmTMGxgvWGkjJKwoBSEQF5S48Dduyi5psXCEnF8Y48j8Dflpr1DXoTS+fag+E+qdUJxyd/H34b0H0/Z+e11/qc3P+MdyqE77ypBY7vnM28SwoBoDHBCwV6PGBKuiRyrJyikgyvmHazwtdv3+/gNhJGNuof4G6okNXcEaPZmeM1S4Rgf/7tM9t9lU+80bekSYM/Ge3x4dQ96k+fT172D/df7vdfiul+f/rixQv3cHjkHB4O4YQfTp4PBef9o72jaf/w+dGoPzk8nPSP3JeHL4fu9ODldLLT29mfHD7fc/cm/Rcvh27/cO/FUf/lwf5+fzp64bw4HD5/OdyH3kbPpy+H7v6kv//c3e8f7h2M+i+4e9B/7h7xycTZGw6PHCDhRy+mey/Ey/5z8WLaP3QPJv0Xh/uT/nR/+Pzoxct9/lLAJZ1MhuKAvzzo77/gk/6hMzrovxjy5/29F44QL6cHk9H+S2g2EtOjI/dlnz/fd/qHL1ynP9k7etnf23P3D9ypOxpND7Be23CPv3x+1B/yvWH/0Hl+1OeHh/v959Oj/b1DPuXOFBlFVfGyTJOSZ8ByjFOPEciKYrA0BLMYGvIolsVfYBxNOAWTmUE31GcozYSiCFhTBt276dTAgQDtDCi2Uj9PtAGXTFw7Qo2B+354xYtGwnpVSVk/UzrUlyKOYfxKwfUk0Q4Z8IbUDDm+4DGEoOUWnO9CRExce0lKZj/mihjr/aAfyRKT2d7hYbNmyF7wJVWOy/4CdRp61Nr2i2Yni+nIMDPW64PsihbVBhxSE0A1bsKeHg37L44OhsNn+Zf3h8OEPT0E39QslbJjvf15f2gaoLEvA1MeDU29yvItw6Z3uldSN1Py7Pn8+eMZ+3R2Rgf1y6d323xBYq800eHBi58/uxS9ndTXSX2PQ+pbCd919qXOvtTZlzr70uOyL91VukqbOeYYX4OzOvFcVwSdNaXDKL8sRulwdXdmH9qZvW9rSmfk7654d8U7ttSd2e7MbhFbkkb+kmoELfcyM9IWaIO7a9pd0461dGe2O7MPh7U8njotS127SKN685j+3R9SYbqs/ByYd97QY9NVjH5q5Sr2JUjszmL2unOkv9dJuiiBr5lR6w5C/3Nl8k2qwMFc7Qu0xJDShcJ2/K/jf4+B/3WW9M6S3lnSO0t6Z0nvCj9up0DhKmx/3Z+G8QxKlOAG9J0wmHoyZykiFi8BPtAA5TULwZToIp5zWH9/UUDyMpmMWeohr2IIFYnEdYr5hVzmBS4g1zBOelBPOaF4DcQJLMzSKIM0ywRmnIta4eULXpaC8EI/tRNesGlSI6aYPOdXEk26IJIuiGT9IJJfJLTigzksJWKWh2Igw6WRFe/FlUrCtTS6otXHLSnyHlpEhT3uoNOWdNqSTlvSaUs6bUmnLem0JZ22pNOWdNqSjWhL6Cxt0vy6G3MsOtOUYP0Tv/qzKKZY/7OwF8T499/fVXQYn0Qae+JSqmywmRs6GcYBTwXUTNJlC+ZhAmk1HHiE4gwU2hLX6W4E1ROglYzExlpABli+nkvmR7QZ0nZcz/1fRCdijISetEyv/EleNbloA/YlEbBsxC6KqytlKAP3qp0w9seUauqA5/Xcv8USdtC7TWYyqHU+3uaWD5NObXNeoJlI+0BuNkm+SD5ZRsHOsFVbIib7rKdjMtd4EAb90w8nfTyL1yn7nQd8JlydWoK+yqYhJDYgIiffPCFYKxuY5X8UiexRRiEspSaCNF5AkUGZTv5tLCqkQi0nUk9MhA7F1VKsqWYf1y9CHDtflk4702lnHqF2xtA6LBXQcy7R9hYEU29WPWt/Pfvwvi8CuCTKEkhNM+I5UEH9ii8SFigFhkJJiaa5m9bC2JYAfk7GUoquVgsiqEyPe2xIf3pBpQy0oYqw61N+9nbIEjquI+CFFYM/2Bm2xMtp2lIpbVDCUy+ZWkqg2VQocTiPLGukFScWnYncDtKIlJDSXLJJ2ir2FFa6D2z0GapSDGWLtDrX76m6xypvlFG7RTW2XH6t/lAQZVUdxWq6CKlXkAoFuZo9dfbLO2ueKL3Ay6u35exf3sFOxbCt0H2gcW8TgkeWly2D2mclqH22KtSOfO5IjYGqoyyZfFIFzVbviIGqSAveExH3Kvb6zntic94ThDg816Ih/iC3D1kuDN8UfhjMKYHg72u2B4bjws5Lo6658XLfqcg5SUJa9HF4ADnlqEXxuAy0EFRkyJgONQv4dIrgr6lidnEtLSU65/z6lBpDlbos8P6RCfmDjTrnS/atMyJ3YkonpnRiyqpiShQmXmqtNvyfIg5VTVAvEr4XCKZa2wG+IkfLr7Ju2csH0AHBB2lragH5NmZyAnuOPLT16BHMyQXg+Dn2ZjMRW8FjRI1LeWZSHkPEXsC8+Vy4HnjaoikpnFIS2xjLhNrKA98PCFxmpclTWieRcLyp5+ic1jAvNLR/3eG+/3VH/YYzpCmRJx5UsuVJottN5SroafNg8WGKM14Gc35o6s9937j3qsHt2XYeBpZpyxcqo8sxzHS18nt4nhrdWFbiQdrRo47rX4Xx96kfXo2lakERX6To+mEbTpLfBPM1PQbr+qZEEApTVUtXUyorf8Wo+d5Vkt867wak5zdhNHnERpNB8JhiP05V41b142XAiBEUUlNMPm+AYkU4B8WalwgjsERHq9QWnb/fePOlRaQxSzywJSrCXK21bCwCTpZqL+tonRq/s3q/BrkeK4xRbvJaw6RXVxthInjsXLQd3fu3J/0A+vK9f8qApTRGvAI13BPR94JEBICtL6GwSwp3EPVVOBBGH4PzpWdAHuyJofTa/9d//ffhcMi+BB5Iywz/XxR6QZq8xtOXRZGI8ec+/swmYRa44DpDg50Il12IWLCJcHiWCPYhEsHxx1MmR+GjX7zSukSxcLwE4hDEdQRCGviKgA07zFLmzUFSCGbsy+e3/dERS8ScB6nnWAtx54tqFDVst6y6pK+xszjJLE4QA82guDls9UjWk9eFILDm/d6wufzDnln9YVSIVBgVi8nHrb1wzsI4BdcAKKMADjieS/AscUTgyjCFvvwR3tS/uiJ+rdRZOHrPeqv04HdKR1begjHWi2w72j+wQFKcCaqXLNjUi5NUrqys/wDxcBQkojcBTjiVSwJkjkUlGH63uP6YieW1uV0Jc0OsFBELh/tO5gOexzdtpeaN2WJX5nSp0/I8S7rKiP8jE+r7mk5Hsbj0wixHqU8Sdh7xmReQ1Y/anw8Yrk5EpTPcHk6AJd4/IaElbJcXzCiIkAhSAuxB5J+hbgbsTG7xuTr/5z12DkcK/lvYNfhBEm/4Z04mpf8tEYpzxv0wmCUQK2OUreLsYDhk5yf41bc4opMwmPqeQ9jjfNBwDrqVKq9UJXLIC1Tk0KiTiVrJREX81m6EBjRoI96o5u29xF2e8kSk1gAHuWG/IXhnsqURDIJEO+CX3oxjxJk8wJ4BE83IjUJIM2qiVZdzHkVIUhMzaW4rMzme+pXDIlYRGVs2s9u9f/Z2ELosP2K5OkK90isCwxzGVudc3vnCvtaVc5ZUa/nBrSveXDETIAtqs/4XPBnPw9hcFjNWU97JiqXNC7hPJkIvMdnoa+ShnDhnn+4jCCjTYoCSZdyj5vrVDXhoWWVrc3FscRz5y2MvGSNmsK1G6ZRIvKjLY9fVxbZ238tRgt6AivxfEAGNU9LpFLbFnaGwQ0vKlN5A3SBlvjpVAz2mJVQrWPSJQCmuRvRnGQpMx6fsTImW5YTq8HMxEUa9JkF2910srsKYJE4lhAHMAcdmflfxEgp7F4B4WyeIf7PNQM6yLwVj8MYuyXlD5lxw1L/EVo8tI84bWpfhWz74Ob8eS/rZVmb6nSikEttRPhIo70hnjB6aK4gsGsM+rEinBBMgEgP0SGHMxDxKF6/ZPPNTL/KF7hs7AXOH0ls5HOG2mzngVnElYglujVwoRTuA0vZaVPy9yuZ+u4E26QP+g/uy+CDoa9ILDuAbenfQpT1RS6CPs0RSvL02qUPgbUKe7S4TuWKF3FrMY+V6lKJGnycvIPihF4/99o+M+3TecScHpDpa7u2gLtptSQNFbN/c3BY7DAx23ZdXMso4RSiY24qA1C0/GzUwWY+/sBLqc7Lz5aZ9BanUbnVAaEuAUBP6keDlRvhnaewV+vi1sq/UOIKSTUVGTdXEVwESKARULYmQStBnEHucF50CE4yakqFXRd8lvRevSEl5R1BpFe33R9ChEWVgT//1v/4/Nuppb8fRkrrGozpN9qoq+E+SV4PWHZV6T0f/+q//BtFQjwX8PG+gZf+l+XjnKdl5Sj5WT8ml2FO6bIcSXwJ5sfsy1pBuqzUL06iV4nFjwfLCZDIoV5079hbIPx7HJi7TY1cXnnOhw3Hndvdz4Dc16djs+rZmbVwX6taFunWhbncV6rZMwW11nE5M5TQBq1oddR0d61ynt0/WauFKTQrnXr0HNPKfEyqxYgpM9JNVZKpITNQWbNaFOKsyfGoWkaRPD12oknB1m4LPrcWn2dPqFVYIc+spacXQFj9bri4uaYtbcQrFHBIRe8oNDHZNOldhRNzB8OXRCiOB5pWh5Kyj5CB3yugRzfmgqCJ/xjDJsUyLTUftCVitkzTOHOhimRb9oKpFz/lBjQbY5xPhv2ZuKBKyV2JYHhPXwskIc5jq8K/qhnzdac4mpy6S6QuV/6YYWP4LEqIK4ZQ8RDOP4h7bY/hGnWTaSaadZPrwJdNORupkpE5GWiojdXLJfQbYLJdANlC+kT6y+0NFAS8r4IjgunUFR7tM80YWcCnKNAP22YCmsrCLLMwCSkLtKwD6PBqhS6YdLx3UGZOk5DPRb7STlKjxHUpKRqxBHo69TlKRSjYOjJC1Lw87fWOJ1+gMMh3s7WBvB3s72NvB3g72drB3+2DvSkUGbZUD05wD4td6LBbz8BJrCpqhw8gePUw/b+Sn6xXqiWNKO4lSvVTj1sDww/3Za/aoapHI2g6kjRTWNQgvjEsYWzVTRUNIL4waYATWcPkwFqkVTobWHUruUHKHkjuU3KHkDiV3KLlDyb88St5qpxWV8rm2yDVintZVru24NC9zbQeftUpaeUjbgU9q/AvDz1upm13D/rRTh4X1sadS6plkKTp6SLTmL6iwcBSD5t3q7iLPqRzDom+ub1+OpZmj6dLJmql4OsIE5DThezMPHH+BfFNVRZ1y2u6q2zkXbYFzUVeJuZOxOhmrk7E6GauTsToZq5OxttMSsYFs6hUHnN2Uz/qyWrSkl43Wg898dqJbtzUlsJTPmPGR5iK/n/mM5d+g0r6lALiUz2aYyxR7n/MFS4QP3t6w27IMPNpjFEFv008PpYkHKOD9DsR2oovq9uWs+tjt65XWYDn5K/Z+i9V4HwZwbg1CVEF2yMrROMolOfQbq2202K3achylEXZ5OLZLzTYoEer1C61V6bism1Wg5fK3Nem5UYerI+cPkJzfirKvQgLLelyZbk3liTJO2ULWesOkXWseoc2UZ0Ol2tL6bBVi+ovrlzo2+Wuwye1kiC0Ep8CD/6uXfyD8eowtKsmoxLWXYILmk/enjM51bS4q3ydFBXsvUihbw07BZOGEQQBvsacn70+TZzmJd8vqyR5LLsIr+Jh8xwuDrwGVvEEDRM7e6pld4oeVAgPF0Z5OVb0oyK8OahP8LswQndNCB0pjyYAIVP6o1kx2XscnK6ofg2+mWRAI35L9sd3gYHeWDI6+wGSeutVHaC8DUOkp1xxrKuUF6f5eY99Kbdu264b8x2bxk9WBjY3c0NNkN0ic8TF1+Zm39kzDaxJO8+IOxZvSmrMtG9lJ4L2jvLxIPW1D+RN3VeLUHWxzYDFASZUg4McplDWBloe23vD2op1SxJciZqINqe3RD2LOPR9+6OGf38WiTIjhttWS39/5zHPYH8fvtYCS/4Kyifrhc8yhGIz9x41S7YBoWt8zadpAEs01E1uQxhMory2pBWeBuDJOU0NCC2xYS3qR8j5DahvF3iX0LWejCe2lly7YRKRXQgRfA+J+PmZ7Cly2CLOYecE05mSGzGIxIGpJtdWYKzCrNFCsC2920Y9EjLQhcPIv+V7wfbMyyupXuQD8yx1v8qKeqGjCdsAY9viKQ91thErTzPcXLK8ht8mRrUQ+XlbbvAdzvSrx8ZBIxxYRhRaxphKx7f5wAq8xjpR+r5AQGUPKDXjQQEg+Go79yn2fLycoJYPiZ6xyU6AvX4McybErEF4ngqUinkNlAEpObScHNB+TDlRvDKTDDlWKdihZRngEPsUnYZauoOBorLC2DSAD5nvBEzYRIiiSCRmMu3MTTAC9P0g8sEWXWl7QugCVmUgrlxQsSpVTCxev/qbmxqSi25grUu755FpilMNddoV7suCfF8wKV3VFmau7rZX5PilIa5BD/D4Z+WO68w9OBmiyWJDypkIZfg9db7pQEXAr0gjlMoyheQUqAbWyA0OlsyZ1yIkAVS8Ms5Rqb6bw345O3L28sZKkYccRczhy3v3KG4+JTG0RAWqnIS702awqLjat1xmX29VpjZWOoNC+UVGsCROLLhaJ53AfSdGlF6cZ901q1aQqpv1aQxtbHKgfovKDSevdzLuEy0Wdr6UqJj+3G48Lq92p8chOO8Xw/SmGzd25DQ2xycFXVBXfA1UtGIcePgos07qbqYTN3up1w6VWTdphG4lFsqoopcKDqPZ9kugX0pCJa3kO5G/J4GtQNO3JcsW5IphNeOBeeW56IQtcQ3k1l0GN6sBZED2P+RRkVHFNHvK/hG7YXLYVlcSnFSkAiLvlGNzKYB8zLdlGKtFOR1zobveH54RBG21xLXVRauPAxqtaqo2tlMamKlbALYwVbivY/VdRF8PEGyXLgnCLIYebEjK3DnacWbTDRRJxE3msuJD3LJg9vmvfQotce3lr1Mnt7nKdYhmLyZI2uEbHbLvv3U1dn6PnFrst4+uPnR48XJECNcyrI4VdP+S1ip4yqRlD4yK5gRmmAg/tO5GmVIrsOEsvwtj7p0xn8O7D8TNJMUgP0SizvAmvAj/kbtK6Uxv16TF1i6HR10AjDScOk6SvTisKLYkXQrj91hMsGQLZoBOSwQBqBFkiqN6wYO8+HGMKAcgwJ3VCKjCUsi/sDYfsRCUhoNDxZ2vqiraCsKqj6cqps49v3jKplOqI3QMndkCH1iR2u7rKzQpEbyxfGssrWARccJlUmAZFTouYbhXQJzh+tDh4JJpDQ+3dYFCIkoWyRFURl7d6yoKQ2nlaC+PKwoxfg/M11uicicCNQi/oQFwrWvPGtmubRGvyA+B490mOpgNtj4OO9VWEDv60DlEj0aw9PZPtbVRM5ayR0h75CrQRHf8s0qTQgx4DHJm8txqslpvywEUYX0C346+B0hDPgXA4DYa8jh6ZMJA2obBzets3RpXOsEeQYDti9AiIkTwgS0iQ8vBppDe6USORkY0Myz6lmXNUhdda9VS5h6K+SvWXa1FiQSlgQM8MZ8Zz1jE12YNoIIjXpCTmtFYv77k8fra8TvkHL7mfic3ecLWPjyTgSM/nwd9q44bdxOnQelFlbtKb3FXlf1i8mJVe7vSGygSnN7ufd2MiVuf0k7pXraPrO+pwD9Rhy+59O18/iGNe4uNHTYpJUySX48yXrk3gvIcNcyen4tU27nC9+59ekVKQoey6Nkqc++h5VwxY+Bo4POKOly4aaIjrQp5HzN/IvSBZz9mORqcDsaWbnbhOpYbGi5n8EJt6wl83LHt9L0Ua4Ka9E5NIiDWD2GlAqNFKsigK48KQZL/rjCl0nCzybjYs3EjDrqn63M0C9U8STm1jzHNidG6Ut+1GqSjT5niZHz4Af8kznPbDB69y95b4R7bgX7s/4D8/m4VRmbBjiZOENcuHRctli8TRBMPCvAwW1S5jyYqJue49wuWmLg5y7hu9yptQSkE/949Jf5Ebv8x9wchRset6sXDSMF7sSkmxHsaa7/VV6z6Sl0rIyh9h/B3i2f728aSYE0N/xQ5f4TQvfVdZ7Iws7Hfi6IwEqXhpm4NM2kKvXovPntHkP0NH5ncjSKO2xJGB9A7QUi2dojQrAiZt7x0ZkGdUGI6Ix8uH9Du/ZnyukvmLIMVsj7FIsxgKGUYiZrKT9UZHRRv4tRygquGgx7u646dSSbrLj+et5N9bfkB05uxShYbV3jTS09UXMzn+eMockDSLSVYsNUuM3OZ00Asp7lSqvzHggOWrUVcgIkwhlgJrSsBxoj5zOVfyJuCOuTKsWInCGCYWG5E5DBvuEUg3HoTuzsiXWovw8uvLv6EuSjUlTGUm6j607X8PSk+ksCy1RTVwzVT/ucIApkVernCeeexclBIWNHxzmH81UoevqlLL9wmb4rw0RRdB6mGlzwQrJ4i0eRmHQ6XLk04oy8/6iXFjJUk9xmyRlSyOrXPTF+f4FgtaFKwYm6UYy+cI4EaRt74Tzudh0Ic6G1lMng6bCuM1p3Km+Hot9JkIzNlQh3WuaJH6l5EzMEDCumFfVqyCbS3RX8s2aEks2LLXtwiv3FjvLi8fXu6LNI36QDGU3wX+mq/uXz5//qjXANVBul1vB1Xo2IvcQPivWofIG8gPDZxwjguQhP6liMcSEiOz0BkgX+0MRy9HriMO+i/55KD/fOqI/uToaNh/IQ5d4RyOnu+55OWmTpuY9EnGyAkMTAfb5PPKx9Q8L91uE/PSv3kR3rPRcAD/O9rpqX/uYd7cdaYPU0vGoCnceXVwsK/XA0jGjKfiCvPm1i+IF10eLFuM04+XB7gittWgDsw53XRHYXByRi+GL4bFOb4wJ9m46akjp0gvmlP8fFKaobiGi+GlDNveySwVvA6TFGoq9d3JDo5ZzvPwYH9Pzyl1ylOKwzR0Qn/JtHgUMd3UmBWPonHehR7DP6CR5ZS7k1u+vCssws/VaKXkYieyul9LS+GZJc3gUqbQgudXaK18ta9SGRa20zoK83aaW6oEC2DvubDw928mmDKrUe3sDfcO+sNRf3T4efjy1f7w1XD4n/btv2PiLSdHPR0eDsWLg+GwL/ZeTvoHI/egz5+PjvoHB0dHh4cHUMxvWLr7xUJL9nmacpFK4A6Xa/X9MO7cbW7HHdGfVdd+1Hxd19uKnxYlwa8tTq9H6zYt/jjtsHUn+6wu+7QIZm/W8e7+yK9uY4C7XY6SrS2R7itLUp90nHviBTN/eQ9ssmBemrDTNwN2HCxk+6/BxAtc9M2JxVTEInDIecJLDIwD3hVpGDFY78Ygtc1WeMmp5KasUusHri+/jstvtttur7ubvfrN1jfruj8N45noyzNCBael5Q81aV6SxwWAglBnjqAu4Ea12usVTD0zSwW/lS/8W5E6F2te+F/ovra3N3TmhoeJj1qrhzs6ujodbXLXrtENZ6nNcXtl+qa8tc3EsL8MiduUZrlTxnXKuE0o46Q+oeOhj5SHZu2IdMdBV+egLQIfyNtfxMmusaLNYRDHZsOK15j5tFKcDasm1cVI5cEPaGg1+0H3eCy91NBhPd9t7dAEzkWGd0NxDKF0btKuHAMm8xDgQw4VaMMY65leXYiAnUMbOjTnDHUYOMQmD3Tl7XRYdnYq+orJk9g4mw8Rx5Kq0BLLoTLOolhcemGWlxktYFhKnXlNzjHWka6Vg+et50MGncJaThYYcV78SNOldZyxcbDey9QAebD7fOnu1gwD31xpHKf4rdZZd1IK58k/u/QM3ykTc5zx72twsNJrt8u+WjMsxwHfIEnQ3pVJVdVVbUlffzv4qFzDPuGL0ou6PQfUAy9++tsST2wZ5khkTwVkmW71TgglQAN46FI9OpWIkA6D4VeOg9oY88RV+RNPBNaYreReGVXn8yXgMlEZJSu9/WFYvdKPZd4OcEzHJcGSDxDEFMd3M7ANIYrCkV7PR106PHo0MRmC9QrmhcduUGAxwBHGZhtZoNo4zwNsU3hLeiVa3oBrWFsFWF/eAS+CjOUuZEXGb9ujvAmyEyK4p+4OrG5T4nFjxevTjvNCI5unGRSo0fMz2w++Bl+DL4lg53CK3Mz3gtk4Cn3PWbxiX5VH9Nedc5VllFqJuD/hzneIYjT6gjTCXwPjQ7o1m3NPUpKiR62HtMSBwjjgzA3UhIqtJ18DV0R+uJiLoJSuuMcinzsCHvRY4nAYc49dihhyByY9WQPH98MsTZbNL4vheI6JcuXTfEO/sw/4e1/Wf/8aFGb7G3cuSi2l0TIxJ4Iz9r2pcBaOjy64XppgRQxaJr0GA3aWRZG/YOdwvs57ljGf0+zOi+NOznuQnjm9YCFuO/fZeWHFzvEt/TANo74vLoXPzsMJYHl5d8/zkkFfgze1q6+XHDlBDDub1K0/c0MM24GFWwy+Bjt3E7dfYMYn5ZvUGMlvYSPHcMsMJwzzFHSYaVOYqbBBmnetgXeaEM5JmPkunkjpXlAS99hEOBxSdcI1DaIs3cVIXpBaeIKnex7GQiMe5XaOTB3w0C8Fdg6G+9VhfDaymXqQpBpzYKh08R0Cu3cEtgnk08qBxKbc2f1h/LXMeYR+r4NAeUldsgMXbvGCoWminBpSWbbrXmkwnxSGvRH3+qJe4fRN+wyXNHFj8BrnduxoU+zoTfnwqeuMwOVmjGlLqLclzlq1YZPQXZAqkQemXhVouo7D7ij6bVB0S2y5MlAYstVGA8XXYAEb9DQqYzCqcRFGCRq1jbE11eGoYxOoBW3PIz6hmv3B84hjy/A75rDFskrHEjqWsBmW0LM9wlwj98cslDvVDRWlkHGqSvyxUvKijv7L0t08aFST/k7Vlhvpfo1WsNBSZ3jksfgaRNnE95IL6a+XBak3F5A9m0P9eR0rj8IUuHnlCs8EjLlah8k+K4Xd16CssZNJCpKS0Vqmc0soq9q5H86SgQhg9O754GsAQrpsAkVZIBseiOqRADWh1GlI57OC0vOJ1uliqV/USQ7YW8gT2qAYTnqMSkqSMf1rEAvU4Oba33pVb56NHAaFFlNdToZxtUakWbx3rnzHis3fywf/kzGCtv5O6n500uTDAgyNyk0iiZ1y87EpNzuA9ggA2v3BMOF6yzK7tVLa7irG3eysp2d+qptXXPaqZtCEPXVFFAvMkvvMosRVz15hTbVz/V7/cu9c1VUbMPLos3U/EX4YzBBShCVceP84Yo1MaCXHwXyiLbwG2zoFVlOgba1XoMoJvNQfLzHPxMIw0WMPA3ZO2dvPJQYVSaFCYQ8APf1D6asiOFO6z9fsPAjTfqUTbAkAOXDZlDyR9TsD9geQ73DupSnkRAaAkg+SY2orynFHJ7U+vEI6Xe/Q58GXRo8FMETRiXIcxWLqXbdyYiysGWcOT0Q/EZC7EjLdYy0f6q3HptxHOQEkAlkDDTLihzE7fUN8yiiW9j0Ir4IB+zchIspJmvdEbbMEc4xTIjM8RM1rsGI6Ywul6PDvRh0iLezgYbhFnlSOBiwf3UfAVVKwlrK4V3CwYsUkgrjcXnDJfe/OIOOWwOkOud4QueaoSKOMzUSJyMOdX8u70Dkas9FNvFkQxjpuaEXgO/AMlNnos9m/HN1YG7lJEN2/3FsRR48v91pB6Zo4lw4VN6Di0XDYoeIOFXeouEPF94OK/7bX4eIOF3e4+C41uveFgh9VrFR7BL5V8Hv3h/qnckiu8zGr0GqLp1mVYzb4mFUbPxQcbizZpj5WWd327m4WTiStmB1a2RRa0Wf+FuzWHY64FRxhWdgONTx21LBZbr0Jz70NMGvlCwd7fjfh1p/oi/VR13JIFDHc7F2Yl/tQL+W5h0o+Ok/Kdbq5E4eJoZSRkb6odOI+c8MrdCscsE8q5BZjbcnxLw2bHfNkZ8uCvwfsbzK6tz64l6VhwVVQFnBtGXd9/9DmPhz4qpHJtLIrByibznvyhKlg5cTIZ9aBoRuCIQt92Dwa4sGTtIY66N1Vnnxeirxzwl3y6NtcKaiHAXo6H70Om9mxmWKHt42iNDK5k3DpXZVmo9FgaJwrxbir5sJyarDLvGWNusL3daMW6WCQ/38NOmyxisnFtiEd117GtWVTjoUYezteKuZtRlu9Jjs/uyi+jgFtg5P4vWkFDDawBSp8DPjqR7GAflLF+G5FA0AfEbm+U+b1zNnmR2pR1NvLVqU69K6YR2FKYe5JymOK6KPYPXSZ0BPCSragwJThgTxOvSl3MCqHyJAMHmRhIJjrzUSS9iMvgDrXKgKxNBwI4Tvxw8yd+jwWTxImU3UPmGLle8M9dnXh+YJJblkYEXTnBZlMY7ancsrqADwgFbHg7gLmZL4INzUWHLgy4ywV8dzT1/hOk399tO3lOtFxIEyUV7du9rUz7/j3pkwQsP4f8yW/kfC9N9xr1JjjXpv7C2mUUw99j8DnCZLWd9hsO/d2WXbbTkliKEncUBD0u+DSu1BzHodHEl/kxjfNNTuQuFEL0pzqFrRCbN5cHvtaiCbRTEudQyxmHjgILgnok2xUty17P1CmU+05iFYM4bK891Il8wpuWqeTwU5bRq56NbrKk/u7LrqclnvuiPstCN4nWZKGcw3LcDcWj0L2ftzUCveLGQRgq8Xa2CRU95nEu3jMCwZlRd/Q6R+tFExcy6NCCDTO3ytrdOABrJ8TC1cEqcd9rZfVuV2W9MqSsJCx2+EBizJfNksoIMFLIbW3lzARuFHomZDBURZx1eHXIIxZFvkhB19+WeKCfYREOA57EzrfRcz+kk1U/yBgyn9K2psLrl8DJd/q0UqlsMr/gnikYC7HfN+foIIrSM1/pwNL3UB2mW9PoWZ38mp314V0OrBZycDRX4QSVyZbjHyeQp2yvnQmk+qIvL/dZ18DWPF8vQ3egnODDNmZk2qdeZKG4IefT8nYvHvNj104pEtFZQux/XxRf8qKLg3Acojf6vCHjt9uRJiq4asbFqROi5uLhmeQjufch9sCITqJEEbymHV8MTcv7+gBI+jzIOQNY2cI+RE9474fXt2dZPbSPtLS7eE+6ZswJZcN/na45r5xzX2hl5Usy3mXuz/cEEpytEi/XQ9edAJufVARLTTJd8tf6RFTx1rrEAYJKeGM1cbmAFAwqNDAKKlxwesztNKsW5t5qzeTOsiLmBv0e7UAO8s1R2cVrLLeMcINp/EugZuNJfKu4TRl9MMD4C0Tsdb+btYObBmeBvPIX7aL9VWWzvR80wr5GAC/CBx4vCgmwgw7Ztkxy5ulLDfTlNslmoE5R2RdQcggjEvEcHTRwJqGVsH6bszoFs6/awiet2ZTpw0t0d8T48NFDTI1Zpz99Y/PsGB4YbiTkrsXxr9TFULhlgjFwKJKpt4s6hGk8BQ2byiYy2beO0UTM5GWx1mFFgZD3NGjK2ov7tSRvW5XT8y70Vp/YHRA+504IWSEgIoBXpKoOri0exW818GlzeSppUutNvUzsofbtMQ+vDqjtdoFVdOQUrmYx1YFMkrtghHIeJew5EHiQT0qOP8GteYJw+zqTo8lYYF0ggpbYkbFfjrjz63hvluCcQOnABIawhNphxs1IKgVHTf4zMvWlGO/T+3xC+iuFyd9zBqmWlWfWyrRS98K0siy94W2Nr/vQNECCACkl4wPNNSc0RPdiPO6GySW+Y093IupJ+KVvNnrV0FnttrU+a8ZOHeCZKy+NXZC3xeOgUoO/v3f1x865qnK4pWmsAn0UTPV+RqIpEVXt4tSdEou/GPK/UR8qyY/al41UjVWuUeYct/IACdTnaiKGQbDhml7jqnLo7fMwY5QTpsJC24FQh5QNjYEruAeqJIxGT4n+PXl31D57SrfeV+Zicpf17b/veHP3k4KyzJuXDPVv6beulQJDxYsETx2LlhOjpZ8c5h/NVJnssrn833CpjivvARBkHqY5Q3GBTVWmpdxOFQixw3cVGquBtGD92dwNeTRDTLf/7YaRm6PoDcVjCB51zss+2zhSnVKHEUHz1RhG+XHUXmQe3E40485+P2kF+WHTr/3f4TxjAfeP5FKvorxxZ/yTZ8HxwU48WNnAknukAYpkpGKOIq9RBORaSzEziskH0gd5L9/bgih2Bj+0owJVoXIUqTBXbceaBRwxrHr1nOpCso4dl1MOFSGFiUTPFJHUK+CiZ5d8gBcP43WYcD+GQZiCwHJ7Ws8llCEUzCDtw4saNy9+0FHVPiqCRm1G3SHi24ZF1k2Rlctk7tTuefGJ2sW2cWz4ISxa5nUMSpgjo+Pj5lsw3iShI6HIEerZ63fq7Dd4nepVaXI8fsz+SUGDZqVocdGalf4N4xTcrTM9VIk70opdsn9rPl78tAm7CkP2OnHywMI9Dn9eHkEriIQ9PGseTSjAf7vju37P8u7gCwqAQHYF0nSzyWUvvoAsZMgGROBXevgqrepo0QsVQrW9yPHA9mAM8tB+ZuIQXtHlhNqpCLcrIfDsn6X2AXmBVebOg8v8W8oUEfNdaNvtsToto0HvjVO+ezGHKe/V9GImncn3yu9SsbHAZN5Kc5TUdCznV8aSq4DGbGQ0eOBjC28eJQOa/eH/qfKVlnnv7MUa9KLLeGmdN1pjzg/Cbi1dtBZ9vqph5PmbG8TUGoKaeS43Fbd2rKtuCv4KOZRutD4sQk4th5xhx07nVqnU3sIOrWmK5AFcPLdMf09jsV0fDR6uT98+fz5gTt8Lpyjl8OD6UjsHx4cHg3do+HeixWNzFuKeh4DGJFwogmMXCW7E554Th/C6/olRyKrhc25kka0mvcqBrS8XdV/J6j1L84za1epRU2PVW/6FfVaJcql3XG0LH76hj3d3+s7Fxx8mUTMLsQ1d4WD+TtJ/nm2guPQ+l8oi1xzfv1OBLP0YufV/h7Wscn/NHGQzCrfWAflo85Vz6i5dNUuV7LZqZ/YCl2UXK6BUEV+6Ap9b1asF5TzAVRS5Fzg6ag/Gg57TOYrY3vDZw0zWLGbSmEhiJ7hKf10dICjxPZA8otlhwpVhxqmH8auWLJzb6H6O6iBsa1mVJMF1GHFz79SyUTHPG2a/uo9lU+knu9O3s5QA2QJ+FGgZF14Tsky8Y9vTavherE0/zauyFkYp0y3NQbPE6dp/sveq58tTxyzOhH+BX03T8dYjuUViiYLptqzp1ifyAvyCkVJNqFhsTlPnYvmXV6vv/Z31hWRHy4gvtKgto2TS4suQDxNKRUPGjcwrkL1uHxiK/VV3lJ9g7PMcy2TbCXfffi3jXkFXSXjj+ikKUMegAceZ+lF7mzZJLahL9Emx2L1mrqnL28qg8cfZwyXlcG6MtO5udZBaiJS3oDX/inisJ/GWZIOnKtkUAuZmmPapWK5+NFawyQANKKpdohmz4NuxVQN6c+t7W3e3Yq0dHhM47G78uu+Ssa0YRZigTbOlaLCqSt3k1e5I2a/FDGTynE7OVtHSN39kf+xTIcOZFGqyZeTRR3d2o4svjHiigxqiGkj0oQlwokFhHtPZawbepAbaIQbUKSjkza51dzmxtmfvlFGSmMjdJDvCpNc2tESwHgfAFEREjqPsn5kR0kfHyVtG/8o6RhKO1ZS9v/Ugsta5d9M1Oj+LCX07ChxsmCnb2o1fnDlWqPL0zcdvbwVeqlqVG+AYhpdbTHN7DDoL0E5gazdHgDdlVBvJeuJeqdiOVG4kTLBtYOiTXYT1V+hMGnxvnbUdEPUFFK2Bmlxp1YnpLZeltHQztrTWXu2zNpj/Pj4rTrbYhg4Q2pfjs7usMzDwjKDHB3cvpGAvlWJTeISOZCqqh0OkVFKEU+SK3DFz3voAMcjAxz3Z84gErd1Vgwr5T20pRs5I99K9iXIvQn/9V//G0XmRaEaOp+m0pvUC1wPQyRAFckxZc6F4K4g19hP8Gb/GFpbPpfNZuTUia+Cx1QinDBwQSaYhuhEmMYLL5gNCmy0nBfx5y3zio5LPUIudevWHyV87/6gf6xnEbLwQJs1SDertwTlWkrJ/HSsRMf+HhH7y8etj13LMeeY6AbWKUsnW6xl7SxTvwi1v6GFir5wc+uUhZpXLFPyBi23SpUJ+pOEzUXKXZ5yHQMirqMQM1KC4V9LP5Qr7KKj9h21v6ltzdrNFlP8Th/1y9H+dW1suRNUCwOa2bhiOSs+bG8hM97rwom6cKLOwPRADExdKJGeziphRDm5Y5uMJlqr22U3957Nam/yWKEOudwYubwx+POG4EqR5d+SrawYfVaNognEVTGqrC58xrgiFq/GKPQ9B3IJpElPlRY4PnnXQ49ye/Rzh0/uL7wmP81bFVXTkazHQbJuYDgxvrD7oxCM29YyUkPxtEmkgdqZthCD3qn6D84FpDBJC+kHY5GEWeyIBMrUivxPXXfBKLvVUbuSNGYNtl6ilDL25WZmiJqOtlgx1ZkiHg2FXMfYkHe9ppWhhjKSecG4DsvtCs1gsAtxuSVqdyM1fG1XW03xOkD4GMhdvX69twOZy60ki9RhdVTrCz5txnOfRORzpwLowAqaYYLeUnF4AHoKwclwZ5xaR85uhZzRBm+AmOmOtsjxk85na0G7I6kdSV2JpOozv4aMjfq5PnfaJE00G1etllrTt6LVkt6T9TRhq+PQx6edFbOzYnZWzM6K+bitmJpsbtaKuU63t5wa0eAQN06N2L6vB5Ya8Q1O7PjkXQfJNgDJDEyyKUhWwEC3ZanVH2mw1Oq5NVlqa8EVKevAgqH4Hne04CsCqn7bAa77M8sqOrBdVtmOOj0G6nQTo2z+hd0f9MeYO6skMKwhbrlRtp6wFYyyOcLpUhOurbgzN7Ct4i5f+BtaXe0dbbUNorO6PhISuJbVVY92XaurnfRJq2t+HVpYXZcAu84KeyfU72ZW2LqutpkCdgDwMVC/Gxlh7UQsN8Lmx5qMqGh4RVFTypVLjLO1pO1JgsqsXklk7XUy660TupvYZ+0dbZ99tqXE3dHajtauQmtvYJ3FUApZCrPZNKtbVuyyxpP2Rln1UmeB7SywnQW2s8A+ZgusjFfbpPV15S5XuLHY9TgRq1heNTk3laNP5wLuY8LC6TPSb+SRe61ssOv0uqo11pg4d77zmRhLvtJua+kdBu/Ijci34f9n782X20aSvdFXqdA/Xj6CWiyvc86JTy3Zbs140Vjy9JwZd9BFoEiiDQIcLJLZDkfch7hPeJ/kRmZVAYWVAAmSIFURE9OWVFWo9Zd7pmOHULx2yRNecuSOBwpf4VlpfnN1fvNKsl0tMZsKG7cmozN/p+UG5/jvZcZm8dCRLbFdx3YZ+cTGHuFO1CClo5A+n3m2G3KhnZIRf1Ls+8xnQWB7ruYxt2d05s+/UxbnFCLpNLQ6De3eovcKRnk5/OEPwR7Wt8YXoH5siS9BfNUKLzAfsNykgUktERbNf28ELCSCIZzYM+J7dyI4WkkSQXw4E437RbqF+Djrphbk27qaXb5gkC5bpLRNfvexbxlrPL+mS1riC2CPW+HF5V9sgRcNtbV9/Vi2kpW9cJgO45kWwXcZyFYxrBdgUmxUL2HFUoZz3uZBkI5k7pOPUzsksDGQyTkKGPnxE56D6TCK0tBUw1WrcLWCrbxgkM7ZyWspCbYDl1o/oPUDe0taVvUjQGm8riuBaFzsTcDl9uYOBULe1z4F2qdA+xRon4L99ykA9eca/AqaDbvmqG4V2VeN6q4/1o5FdXMu9ZppBWVbzNecXLP2Eu2keZ61GtiNgFXk3045yywwtAMMwIlR24UHX5CFG51zXIvcef43x6MWCak/ZjqJ2fZt7NesW+m2NUDtBUCtakPmX4jNyEGjOqQl+JYxJxdiW4FJGdAtZ1ZWM3HHORmxmWKIjtGu0PLssxHzmWuigiZOr9aLAbOXGkNbpxerSIMmheSU023FSp0dqMOWHW2p3hucXd5eDRd2JZt1Dl9TduugVi1QpbG2X28O7dqwY+eH6jDiaa5yL9BudaN2DrQyhu1CprDAuA3ttIG7K3i2uqE7O1BHjd2LpXUNqRpSm0DqCsZcn409Q5ZuX2zOTTfPGXQxQicuBG95ZtS88HDJGNrQqw292tCrDb37bOj1U9DXpq132ZHrv197OvP8sFFANe+yhnjqJQfueDg1EMb3kvRqfm1lfg0ZjXhDW+LYsgzSmqy/5XxYygDsF/JSFcbgv15//BC3I+GECp7OpHEOtXDie9GYZ/tWHppmyLZhBVYxoSvWX41T+4RTKxiBU984/AE/DuSPDSzB5VgXG4Nr4pxqGE4sFMUCp8azAgEze4Q1FX3Fx7OiybbGoB02Zmjz7V6h5DIm3GLcWdKcWw6S3KJb8loWW3eLZ6ktvdvDzJUMv7WG7TBuauZyn2BzFVtwOeLF5uCabGHKNJxrHucJV4Rd7tbHhWUaUo17m8C9FQzENQbtkLG4nlCvIVdD7hKQu7Kt2LMip04S8VTrEktx/Nf65mHHHvrUn6cG0LZhbRvWtmFtG95n27CCd61ahpcbt8Hb1Zm2N2QaxjPUDFpbDJrgTVrlz2J+Z61mYX4RSo3CyouvsAQX8Fko9FrMt29lXlb1NSGdR40gZujWTNj2ooITOOhUWHAOpXSGLZ1ha+8RfWUDOv+EtJ/jT42t53mSENvOq8iBajAXNMAeETfOreL5MZ2II6E5afBhzpoGlOpF5THW1IqqVHg1s3nZSB22+Whb+R7B4fKWchx7JfN4HgW5cVx9E4st4kWcsTaHbxL+VrKAl4/VYQjUAv6+4N/qJu88isUG7ypeLm3lTgT6W+rYFgr9qSxfHOVsbE9DyG7DXIt4LrG1fWVduLaChbtspA6Ztfktra2b2B62arWEVkvsPR1awQ8gZC51QyMI/cgMI7+OM0C+S84jgDchSRMy8nzC447g8428BPKDaRcB7SKgXQS0i8AeuwhkQa9VP4EVBtdB5N3xFLjBY7yWp6i5uNW5OL6l5DrhbVpi5YqYpjU5DmQ/Vew9kMWAcvcBl7DpLIxRY2Izn/rmZI48HepJmcNM4NhMYHOIcryaNdue40AGHTrlPaCRa0+RawUDee47hz/ifzewkVeiX2woX4h+qrU8xy6BTpU6DnE9i0ujYCWPcVGDXoE8qh5lTYVqbttXM5ZXDtdhc5G2mO8lUi5jO89e4SUN6JUQya3oucey2JSe66Lt6BsGx5VM6QsG7DBAamZyTyFyFfN6JcbFNvaFbCBvWQxwIpgcuUFFwfQX5AaVwxWFYiDD2jQKwdioQXB9ILiC3b1yuM4Z35vJ9xqNNRqvhsZtGpkzov0hCtK1Lc+8dc7ozKVxNDQvBvYqg3Ms1heBgsbudrB7Rn1M25E/qCVqRpSOtQi1tcFcG8y1wbyzBnPPYoNvtluv5PRwTth3anJCQES3xbbhfJ/6Dw9e8q0KevUmiHYyg3cmtsXcENQjfoPplo/QZPL13RFwe9p0QWg4YJMcBT7PC9bgPAT9ENuJeq66B1HQdbe8Bj7AzDSTvkNMel/yv+v1H4CvpJjsM8uCrAPwcEOvDo99ZlnAYMugBCuNWnIghcnWJrS9ZLI3qBrhrxAwraOuDhpu9w9u1+j0wDUjhz+QE27sBJGD8Kz/g2hQ7PpAiTmxHcuBQiEI1nFWGA3X+wzXGfmr9uwlQV/BRyM3RIfNjtovY48hfQXvDBh7NceMHGynfDLwjdR2x8DW2hNDg/YCxF3Jd6RgkA4Dt+bI9x6+W/AcyYFw1mmkkHdW/UWgwYOAWHYwg6hvVHZ6vnzjdxPbYWD3CSAY3R2LGnzCQ0TodMM5GYG9QWff0mCt4OwKPi65IXZMeaOphKYSbVGJtXu0HA7BfgV7Xq50xyblni1ns5kzJ5RgMyUbAr5jIBYwWL7qwlnoTW2TOs5cyQmEYStwNVhAjgEEnh4dkchFQzaz+JDxBIM+kRGAU6qkhMS0wxz6AjKMQign63oh8VkUYFZiaRIVQrwlHWkCoH+4jD55z638ZOhZcxLYf7JX5Ji8t3/RZG6fyNwGSccvcK8S+hF0yxsSSRrMMKUs0qmJdGqie0dzOUVcqFfjZC+rVuPko0y5Vk2x7zz/m+NRq4abadI052Oq/qm+Q2ncS2cu0pmLtCOmdsTcOUfMBq6CEuxadRdcYtAGrxYT4A8CFtb15Aw9BdNpGFJzwizuzGQHMqF+gErIBWtrMNICdrtrfoa/iWVpDm51Du63mO1oiXNT+Zg1uRHKT5QXL1JalKQeQq0CykAxAPBkQ5JcUzLi74h9B1V6oHMObTXnkLynnUo2pIFo14FoBQe7ePzDH/KfDfzoCjEsdqIrxS81eVAMXDbw6cQGX7qQhNQfo3J0CMrdhMxr8CqQCJWDq6n/jDd9NXe0wmE67NmgXdL2Au6WcT6TAy/peVYIdNztLH4Ei33O4qba4Wwz2LaS11bJQB3GN83J7Tq0reKYVYhRsVdWKTOWqpUjWz0ICILpOOLf6pOPUxvYsnEAPlpgyv7xEx6G6TCKVraphq/W4WsFP6bCYTpkkOb3sqY8rAFUA2hNAF3SZ8k6PrRoSIc0YKX2T+uYmz9lwwLz58UxuVD+mj4+2SLuD9bOuRf5K5g7y4Gh6uyt44EY0VByI/xcYNAoAx0ar4hbH0KPBAzi3iDXUD9vaUglI8jbAisMkoy4sU0vsSILy5byJd5Ktescp0x0NSySTY2K1V8/OspYDNM2w6OaXGP+BilW2NqoIKbpDf9gJnAbMx/ueWjzDzPAhKDGDZqyIKBjFgBrEv+7WbcgMk0WBPmF/jZh4UR475xdXRLw1CN3NCCixyhykv0eep7DKFgS2Xc6nTlMPgZhxYMffudEBU8j3gHq+xTOGk+yxtTltht+Aply2IHtjrzFu8urO+XWe+OF1FEutzTWygoCgiozUO+j/1PBbYsXDyZovNJ5/ify0VcNreAgg9pugTeG+PjCT8iXU/FG5Dpi03u94U+OfvYOQtiTQeWGyeETVzBYlBeFhLpzCUIKolZ+8uhI8h4SUv8dX9CefBbKVY8v1O8VzEL5iyUjajvcT7AVeg6YPrPjq2mY3nTquYb8SovE/eKYU3T4HHbnVJv/iXxiKGNcHJPffDtk5cR/zFyoK+PMjfj4KngB67iWJY7rg9jMdrxxBH+5AeUP7AU695phQHjCUS9kKWrdL7fZWcfSZBezCAUmO2WwEnudsOopt6FzDECLAkA1Dv4R+XZg2dwFZPFkU81/9sSu1AdsbA8H7NtwagPH4/MeTGy+lgUDiX6G7GdgPwQLag18Fm9EjbGgi6F0MSwWUtsJ4O4aYvcPskCEC/i9rnCk6hyFe4567R4EZMpCCj9qvqEJ31D3uskTzfAJLdIVCTVEfGrvycoGiYliTV2FnNQSNg9/yH8tsrpax9LoWkiFhK2jigrFdlkFCrZOcRSXwGQj2vpi/CDzRG4RhCb7GRNrLWutIGvFOyAaupHj/N47gP/gY8Vh2ofJ8lPUQLkyUObssEsB5UIzLg41Y/6Uwo47c+FqwNkb9Whl2SlUzgT4+36pZdc6RsNuIZiCYbcKSeHvkvDyfNrCjmvuEbZSd/5xhLNeBmV7TZnz39X58qD+alfjc7hcRsBgi1X1Be8LWkjbNZ3IYjKoRD7NPvltwlziTe0wZFbviwt3RvSiPKIr8l1m9b+4RTFdOa2RdBZHI0qv0C3+lvkBd3ZPSTKAf9MBJjSAxY5shw0g2hPOJXJd2x0PbHfgszFvnBM2fi/QrWa8nHsHQTh3cE89f3pQk/iVcZea9GlxYSeo4Fa0UNJ4v6ISSsbE5+iVsPPPqB/a1CkmXcLer4xKRHunKExM/EWYiNOyQc4HYLfp2fKywvot4ur3M6csPm8Mm1jHNYDvGYAnz1oLMu0DN7PssNTDKgHemoBbkvRKg2t3wFWDqgZVDarrBVXFE2vDavRD9h2qTR6U5pWyjg3epBjSX+PfUjw0Dcj139/lkF20hJdy/fd3RFyVANQQNKea4noFQsnnT+/I3YRBAcUJm0OCKDJkxPLuXHBvY1affPBC9kqEOPse3HJMMhXSb+yLG3jgZGVPGeqeHIiU8snFL0GPWBGGeN9NbHPCDcsXx+TOdhwYP1Iy5qCLln/LCKhWbBb0yY1H6K1nW1/coeOZ32AYPsAvJHJdBlOgvu3Me4S6xHaNme+NIaCU8I0k0ygI4SuwBbYboVAx8xyHWeAvjHOgUeiBUo+n3TKpazKH61g04VuTmd3kDj+Doed9m1L/W5EjDR5T8an24Pbd2hbjlmThPSQHIw+lpgxCX/C2jGw/CHFAuEAS7YocqL8bNLLsUNH99w6saDobeDizoI4r1XRGQ1tiV45aR9MZ4Q7OffLVOv5KHsIihE/eIzK2bzGCGj5KwgnF9w5PkZeq7ZOvwX8cO2RPBqZjDzzXmX/luROE4tmLwlkUSndr2Zj0YbyvEtt6QgcJu3Fr+2FEHcLVfUBMJwArb26un8IT+fT4xmdM/LWnZo4bMjEn2GhqfiO2G3rk4jjvWqkmskBwlqpJ/CG7HkEncsfgenht81sq0A768hTaiCUWG9mujYfW47GbE2b7MRYWsQolXy3zuVS/y6g54R/mHDR+g38Xdf7xZOp+V2hfS/NPTJiEuNAjfwDKeS7mqZ1C9i/eu0+uaBDAIVOXsOksnBPUEkM0a5zaj/LI1lnccg7+d2MkDVNG3eCV/BDwW2LgZBU5tfPiF4U8Bb+nA+nqn8uUIgLQAv4G5l7EwRpBAQkQc62ZZ7shidzQdtQNgReIlpiCiyhvnsCC4ruWYejSU63t7XLFyUzCnQKVCmnwjbgecTwXyKNQp5OHyCpyoiSn/0jz76sYdNM7QCuJjUJFgIExQp/eMiehKMDQCL6lB0FGGL6CVxH+wjnKoE9+gxsKj8mcUHfMYjdZSwjTEpXlw6XBtyKwLIIDPMH8zD8C9mAyakxNzVwShDSMAvLf5AF2edAn554bYh1z/DT8kojzqvtx9SZk/Ei9cUACG/KLwugODfgO4oPlfNZqUKGecP2lyyf0IPl4yb0A25b02stfCi53AIEDNlq2rbttgT12mTWIfKd4dOC3IUJdMNjK1eAf7JOzmDOGqwQAP/GiwtgF+Bwuv2hfJejJbZGiaRmlVZ5wPVqFjcq/K+SeYqxdRXw+OTppgrsg3PFn7swl9GqQ1SDbCZxb/HypCTnTdv7RFuq8rvCcqQ0v9yFcXBynEQvULT1XYzWWPXY9P36BSxoM+JltQ7fFRcFK3RZvUqzbusS/IZlFMVJqiSp8nThpxsIe0Jn6c6SoHCyAoArBR5JuEno9eL2gUeCpb6WnFvjk8O/b4RcX9gdhxw5xMMFWxADEpxoQVEjJIQQK2X6MQ1qFtKIKKXH0ylCZODojE2Qu0mkHCMoTeisjW5QLIG5GEUGQuAdyehnGspCO8x/+JFbIuVA+PeA1HsBQD0Cke2C7kK77QZ+cuWRqPSUTGkwkocKpzb3ogc+Si9snnwUFNCcMdCuYhYo64GsFNaztANQLcFVlnQDUM8SaXpEFnH9XpAGvyW4nqE6lOxiuG0DODtFnC/coy1rDdVvipB7cwha4dgAJNJOHC6k0meMoTzQIKQr3bhBNeeGdylOEhTc7x26fTW+BrCL/mtx+lQMWs2eFV7/hRVBmkroTuOOdvhUA62V3ooZOGihojHaBqnx25oZU5XBK0uN3QxaI4jRktb3PTVDZfFxYbutrq6qu45si4EtSOYAxZqNEwW+33PEeiVxI33xH5z1AuPisHuKtYxbXZXGO7lFfS1l7KmVJqwRqY2K7iz0iscUithQWSd9wR3xm8t/JO7RVnRjXN0M6eeaCHiZZJM9cK653K7B9wXz7lllJgebYLnt5gfQD4LaHbAsPykVTKDdhzXj4JIfGIHsAuGx5ZoIPES97F2Thdev8XOoseEOFb8ce4RpdxrN7hEDFpaACijxM7A5ln5ISL/zmxJhYf/fDOjw4RiAYU5GIC5z2heG8ZFGZdA6iMb/yd2D4Z9+ZGWFZGW6yV554QZaCIsVAl/WQQkYt+Rp/SuXq2k8nePVQqSt1t/AuUwLnKg9R60LvI5VeM2XeBbjvmuqzCie06rObqk9xZttQffI4wCrNJ6fThYrPv8OfKjWdrzlNJhQVWTgUoWPgXsNyb744BVFAOEAtU4pYayNrf5+XA+U3oa7UzY9ee2tvMFUaf4h8GNWDu21MTx/tvnptbyWaUUZdbx7nfXpXifI+vYsx3ogTNsZI/4nepXy3i8PHV0B74nt3iPj4KgLiU/ECqRsTAcKVmFjvkPno0uaazADv1qn9J7OICAmXXCQnbrGznSYiXSMicKv+ownJpgkJvHVNRnaYjACYb4OIgOg84IrFQ1VBUJYMRlFEYmKYuE9BYpiYNCiNchn4sF5EYeAEGnLgDy6joN5MVBM0hD8JuyWV0RcW6gGCkE5n/S/uL6JxIAOHUIURVxSR+tLYbRurV9wyEaYUTz308AOimitvColS7Cm7nx4VySfj3a5OQHPmEh6sQh1yef2RvHh2dKycFLkcxQfYEwxEkDr2JB6r+ALw8s6pAWXSmtR42fuVLkW+YDPUe58svGaWNHkX4/ooaRWoppDt6TlVDGtwpHG3NSjU3nBdmlIeRwVETTrrkM6+clgLcsuoJGm79FTQmEohTb2Esn1KShN0SpXUkCbFWOj5abJUQGT5EGlxrYKwSReLW5tmPkRTJPZeUz/lllURv2T78P3zk8hwGH0Su+zZI/I13uKvssyjpI9LUywF3pah33myXX818tPtLaYx+Y0fjpixpr5rS0tRAGdrzEwhkS1GVWG32l2yuklamZCbDSQm5bJVPhlplXyFXyF3PvDyruLFEkOqzNngeEG4JL0Gt0GZSbqUSMtGJamNxF8rrWYJEeaNU5nmQQ2qYChul0CqWGBFX1o7JBMqvDjsEJ+1GK73xY1cB/zavrrsbgCtEXFjtMVPxMPG3+K7Fat04Uti4x4ExLGndhj0v7hiiRjBoJwd+OkIVJerEq5FQVxihLsFBOCgmZ2eZY9GzA+4vxm6JAsJDdfK03NwZOh/cc+UOYMCGdxaMF2H/LIo1PKcWKBsfvicPCYnpxigGDyKc93iKjAY4ov7EXwIaGrb49F65AYYoRvucfUQ76Vhu0h7wEPQu2X+/JFMPSApoR3meLMvbkIzM1JrPHleOBAWBJ4HkG4hvupJC6nGkEd4P/mvvPK7Jdotb2U5kUmxOeJZwuXHd+kGIaOWtFIseKtpDom6HhJstdqJ8gxjR/4okK5xMui3Webgn70Dalk218RcKYvHBLjL1MxI3p6umrFXCb8UgraHKb/WntHL3VDG9zMkE1FMm9NEK0ObihmvlNhfRZ8quSsaQoZxfkKHwEVFPjukQcBCkawmKDUpQOWvM2h5LRrmikXiOCSI/1xRw4eG1PHGmFYMO5kO/DdV+AxD4qJw4qE/sRkFoTf94o5sF7xlgx7Bc+apmm6Za3l+n3wU2msMCeDZbmDvID2Nw0QrJAhfXMxxxH/zVZhBYwpdYKsuehdJE7mToGsbnPH9vqHjA4Xu8k9Vy+9Av3xbRJcKy3x+AX3y2f3mencuBIlFWIANTfmnR0f9ovTuOSfFsw83v376eHV5ftA7OPvt+qB38MvlzS+fz//2+gb+/fGfB72D848f3rz7/PrD+WtQEn76eMV//fby5tfPv8A/Pn58++714Pzdx88Xg6t3ZzdvPn56n/z+t4+f/nZ9dYa9/3r56eygd/D+8vzTx+uPb+AbH69efzi7POgdXJ+9e3395uMnbHj9+tM/Ls9ff/j4G/zw7uwcKuLCSBdn/3vQO/jXx4/vD37/qcB0/mt1a5W/Ikrg0q83N1eyIGFbWJm6EMmjgWeSKYx7WmiGoBZyHiwIX5FLF6MB5f2Nr9065op0KGWYxikeF5Ee8Tj/ZNYrchZBfHQoJkBiIre5KT4pUOd7/tC2LObCHgbRaGSbNlaLZP7UDgLMyraxCZ68LBsjvrCpUSBE3UCxjlkHCwirQjrTWF5mAPgX8z1yA4WIpSFA+U2rBgG15DENhn2cn5HQiLoVECd4kInn9/IE7vAH/xFJzs9ScveWqdQuZzRXaR2QIIWMVVI+WZYDXbAcjMSiYejbwwjFSUHniCBzBDAcM2X6bMR85prsiyv99iHhn6t+mDz86/XHD4TP+JEINh7OhUk1N25AhpHtWOuhd8oeV9aJP1Omn8iP5OEVDUzqnNOAPeoR1h9DAHw48b2ZbZ7N7L+xeb9SZM3Ex6hEIzNO52lGjl5oMF59gqf5CX7wQvLGi1zYQOVSAmc+gl9rUtFVUpEuU7ISpVBOuFQIOudt8JIUSEEX765kxgYJt3mSUNWyNShu0PMCI1B5MdpEV+jMBjPfwypOibqwWHYR2UWBErq4MNGRXF5UCiUyjScvNvWz4bQv3ZCN4+Np2Pk9/X42Gjm8dNUFpPZuOoDtFgwgNs/zLbZA3vsN9ebIEciQUJR6sSsKveJy4EsI6kl3/FWLml3qCfLC4zCheM9kM+BDgnBA48UMMNP5702P4wqqpzftw/xlul1jLfSmvf7BpfBOkvwrWbdexRfAicaCopikWig+ISvZbNkeeQ+15cUgwSv5L9SXYp4sQVn65D0kABYl6OgX9yv4hM4N1G19JRNGBSvJ/4X7qrQo2F+hremTJIHLxLsjU17r3vRcXvXujtqh1HWBX9ZcpFAo5fZgt1o/ngLVZw2Vp0Ju5Yy6R2jlzBZJY8tS04XlC3g5eXHvX8tUdLmK9DQGxDhdXVFZehCjzq//IfM4jjw/AVLU5JpsBspc6erKVYWBtObM6Fxm+mqHEq9gCat7OVNb9ykuuV7PULRhnBOFKv7whnm2vBWEWzvjzFfQRZa5xksWT6fxW5aLruKM+f37qzcsMg44jnyRf/AGBRxxppGoRcsVHeLMPf9BQDx/TF37TyoSXG2DY16V1xHHITIY1OGtPVfZmwcyNVht37wU94RdXwPLWNMzb1vMUHyl2ueE7jFOyJm1TvHFwIc/bKtStRofa16xKq1dyV0vDUYKilqDDAoeRJFr/ydiilJxDVrOnBNNVi2XmUKccyW1uNpqzE4+1TXS8wVqutfJmSdaOv2+671veJmNn7fQUg3QfFDJCrzhLW+wYSEzkDJFlLMDiUdA2naBfl0zTiZAyx1EM5m2aBfZgQbdlK3l+oxAhSS5nYv5iYwtCCqYhWzs+XP8TZ9c8x0NyDRyQnvmMO4Mk1So7xET3f7cgLmBDXmWhEtCoXTeKFC6YL3nYnawbsG5LKoNr2rj7LHtLrkvvHPnNgQ24iNOrfF2BODjbaPP3lI7IvrPO7kn12Jy9XdlucenqCDjDCPUp1AukC3Qlv8Gal4k9tJ7B72klf7pPf+LSAeI8091cT3XKO3WJx+ntgiYxi5DL5wU7rt0glRdhae2O+DJ46wBDRe5LiVTSt8WMYJwWZP+0nZAPr05J0+ePHmphCo9RO1iYN+yR9XK7thqgMVvMZYuNXP6vfWZqyHMa5x6DbPBG2kwCID7Gc7Jw+wLe9QnF7xuHipQH5ioF7Me9L+4H7Bymxt7E8EYmGs6yL3Tv8g26M888m3mWphFFeMUfHRuRn//wGR833Dyr7jTglBJ8boJV/wF/UVAqfRGwL8F8yBk0798cSWokHfeXY+8Z5YdTXvkV3s86ZFzQCuTOvVsIGK9Bz1RsxX+haUOYyOIMHzEXnk4Uk+QCfiGmIuwgUiDWGwlqzygaziXuG3M8898G3ggbvDJnBAMAMdzA1lVKSq6A8+55f4bOQCF6YiKFJcXPXzVhMan4LMx9S0M4fBGyTzqmo9MsR5YehfljZlUDRjiuRqwFsNpUT+wwH8B4nPS4MhrHqZQJ1Yrw2mCeJIwsqhotiHIYOZ48ylX2O2Xb0FaUOiegKRenRpqkF6l4ULhCUrMFnnnqxLbhSg8UuQFxgUez7HNuVIVdJ1mirVkq1I/z3E6/Y79KutFgesT3zfrFXmjbpagAEuHD9deAR5UegVcI9WqMkR7+u6Sc1mBnf3cc9G3InNNM8Fp6UowGyQKBQnAP7ui/AKSrNduaIfzV5mo0yKYQlrBA2OpOQH5T7A/aTDzIsci7DtEoHLmiPmG4pkihpHFK0VQqNJgZzy3ewdPi14+eC75YH2+hrL1PnmN6ew3s6b1UfFu0GwO/m25BKY24fCH+uNAWDmSwPQ0e3CBvy9jD/hfa7IHsrHLwSEJiUp1w2jpx4+vxRoeP37Fo5ULvb8fAlfKpS9jSl06ZtYjGbss41+3pE1Vtgz8+vJiSKFhQMqcGZBNVbMSCzvQFHljFPmchzeKSNX0hctZAbpHo5GUieALFMeRIPlkCuog5MdRZnctGceZPB+kfeBHN/UssP9Z4IgUF8/QFExTsBIKlgtLTlGwXqlZvYzUgGFdvrThnPtkl+T3pCSYMdMe2WaaYyuzqneWRGxfU5WRazdqG09B2Fas43ujAkJLee9gFhW8uc+o7yt7dvyvNTk82bgWh3c5nUahsIpDQCFwetzzn6u0e0QJwOuBu4nPUA7uCUolLL0JyeLZfyxhoUEWWqbfaYOhFIrRLqHFZnVdfAMa6LpK8Cv1sKWJSqu57ilTjYzlvCtM9VIkqSM8/z9E+YqpHaCpkDzkpS2C0DYJFGy33XFrpbXaVMndAS/GSy7aQeroH6Q0ZiQwvaU0b6jzG42YCUijVXBagKnBM3HCtCEV3KHPpsyyeUhjtWviWxZ+Shqjd+Ibzy/j39AJURlc8Dk8KqGSmYvdF8t685iGDGeHGafiOgeBdK1C+74Z+QH0dCF33Qji0xPnR/DrgKxUmHPuK2/5FZt+ndEx+4o26GkURpgaiX0XniqdYMauoE3TEfJxv1L1i2tflOlZ7OUIs+nEm1gZUrhBb9AuirJxPEbm9bQZlaEl2jbRua8gT103h9VwGQ+XViXo/YdoUYa38u91XSYmzPwGbalr8X5lfhOY3hZFWnB1C3sk8MCPbeiwKVad+eKCBOz5PmdyhK/fLBo6djDB4sw8Jy+/t0PPmoNaGBijAOy2wYTOGKHBF/drziPkK5e4edY7OU/wtoPJg7yt5PPFwfzIgSS8gffFpUQ+GMwFN2VUZBFK/D9AKcecEYwYwHvok8s40y+Fjsy/xQN4BcNxyxjK5EEoUjL77A++ak6YfEYDoFVASiyP8ZGGzPFgPz34+hc3+XwPRE9wPitMhDrxHEsWA5/S7/Y0mipFxDMp/YTLKigczpStwolAjsmAiAuGqw7EAih5/Pjk6OjxY5HX7yvfqz62fcU9ZjkpBG6WuaEPMexENuN5N78CEywvBPn//p//VyZM5nkCqRvcSa/VmDpzGz1sCZDyPvl6+v37V5EQGvjJZD/x0sBINIQkzo4ltpQIbp67mFLHSTaT8jvGy6vLss0z6gct0uxd8PcpIXz/SC6CKSrCWz1wkcasr56P25V7cXgl1kEcC2CtcZK/Tyq2pG8JHPsmxeSd142UuQDBY5VEals6Ei3J7pgkG3M17cqytaLnCiLnxDALMkuB5Cm/HDfl5GRCoaoVg1Tn0oZnAckZMngNggbS0Db7RAikSIBEAAklwCkC9Y5HVdzNbVQWzdVvYIF2S2DyOhINriLxkY/DkPKwGZ+HI0jGYGC7I68vJWmeogmSFScFMOQjaFNsTGfhaiIP821eXYzefvqsBgN8HMbc7ZIqiI8YbdPdUM8r37MiM9xMciwZN9e0H4pxSybiWkFxFHRTU5IPT1kqMkVbxXbT+XuzqqgOa6HWp25SLAALsowIvCjIMZJho3Icw1sWYnIRyUPFykfOQgX1OKjt6tcvrV/mYUf1yRIbl/YekOIburJpfNwZfKyp5N/frMs7jtyrpI1JA/chqL2pa9ZLJHMZN86JxPE4XEIrg/R3qK8tkoyVEVTjbLbZtuD8zDcn9m1z6S5DBrTI3DHxNXOzuy6LLidUKvZinnSQBSvuE0p+DV8Q+MLukMQo8ajdpAZNKa8miipR7NsKBdqEYJPQx8Mf8p81BR75VAoEnyzJI1GAtWLd5DcF0SFl4lDcB6JDtu3crRC6VdClmyCRg4YtxZPEJ65xYhWcWAcbfUg5o1jufyM4ySqUEE0q+GjZQg2DzDHSHYGCDaRez2zmL5Hz7QxZwo6nYe8KoHQeRzqEGvKBt44ckbsQOz7LJlXo8YlNvVtekVa0JlBdHc4ZxcU8/1EQiFo9hIYdDTsadjYKOwk6tAQ84CIZyqswiHMtlmLPJ2gvTi62UqdxB6txygSS6QCNITW/CddVcJyFpIs51LkERZX4ApRWkCPFph4RHttD986QQEUiMawYkme17X9xL4TT7ASRaURcj3i3zPdtiwmn0S6hVEfhYQ9QoYmv3ivy2WXfZ8IPm9pOxFOAshA91uVNDpK730XXvu7gWhWa4bYa8Va2BGlh5LIGiHaOcFIFaSIdAIYFFOJaWQKBVA9PwbW+6s8XJY2/ytYDiVOx+p5XxJKvQ1TGklnrGKaqjD/F8a9D0LZZ3/abyM2e546wYhprRSIFDbUtQy2AYitIC2W/6JhhvdJgRrkiXJFf6xUYzJqSef2Y8+t/FGftzVuHm5YdzCpNg0YFCCES6pJ7GM1TGTRpQL7+l1rG1bb+x/ivTFT0/3x9Rf7wxJBfldZ928KAqC/uV2nYht+IQH/5jYexebfQ7Ty25T7i1ICSyXw2YRCJvCUKcM2vyAd5Q4rTvKxbDudXipfN6Dj8b69u01Zl8O4WbWomlC9bxzEG1UaYWQmVwAbGwCDgL7m4NbEyHmBfa7SmdvK+I4R+7DXYp5WfOI++Kn/iPGyoyEv6PfW/KSwQDWQkV941AH3l8nFhPVTbKz37JKsZi9mjII4Yl213OcpZLGvnVPI7+sZ3SiISL3L5Jx25ix71Z7f8WQvjGh8CHyhUd0tZ5vL2fr49oOqOXEN0pcnjhdT8D4LYy9OZpyI/869e1SiJRBX61etXv8+vPn60jd+9zC9e6vQH0vmVbFQQLY7lgkzPHdnjKEnbV1QCL1CIuKIuMDBtoFU8VFzbjHvMi/VAtpzCRGbCpXxIIeeJ6lT+y1ya0Xoi2Y2sggYzw7SDWKkOI8mh9hwfAvJ/8EI/Axq2rHpo4Ct/viVP+doGPHlBYD8xy/fyGWPFHLwhJA0quEl8OiQI/cjkGqNkVzD/veNwf31uBfXhNofigvNkPE1AbArJMMfoUn4Q/3vJ/srZNBmCdzOwG6AX39f8OfwmstPAPTi7uiQmRKJAbYDkJPqyEGFSjxOKl1LIcBOnfuffO2ihZCreirmaqUYtRf7veCk9eTDKHqe363ed+/d+RfFtiMjH1K8V+X0hKZ8ldHSleoD8YRUbFUBXVkRKKxRlZV1EjjbIxQbtotCb8nq1HF+BYR+CywkzI/j1FxdrCOfTwgChtViIBrE+OYu/hTEBphNZLCnurKYz/eJS1zqECidsOPG8b8mH47RlQ0ZC3x6PGeSAETOEMq7OvE1qvQVuXz3oZRj9K7HHK5YprKbG5950ivhVSJSB/gAhkmxa5wjyBknp0iSzPsXUNPKe0cgFRjAl91IvlyWaF44SsMpBf49D4puQ+bUQdVEwcGnp/PAHp5n16gEWsAdxKcBarAFvHZQ0354Jni+sUQTdlaxnjDk8NR3cETqoXmRNDTU1XJkaChzQNG5tNE7QpIrigfwMfplj/Hc+YVaBAFpdSlCmKg8xeTcqOOPSgkXD9YS4yXO0B19cGgSeaaOApDJI4CCSETnXo/uNibpU/85oOMktFzLDf/58eSE96IpFdS/WvfYPejn5tEzH2zsYef6UhmBDiHAeMXYfnL58PnrGTGo8O3n+zDh9+fKJMRyxofH0iTkcDof02ejoRWMl8XztKmJNjLVQqslwt8mwljg3r1heXGW0QG6MC4zWkht56yBVYrSQWgGF9dnMoeCyDlV/O0Bmr4omitzHssT05zYUx+pRrqA4XrXwp6bRmkZrGr3DNLqn+uhoBfKWhWtR7nI5BfJ84HgL6oHwM3/njV+7IJ2Ve3rZ7q0nXhYOutjVq7hjsWMXVCWLfFO6NJ07tvntVy8KGLm1KTJKc3LmUmce2mbQJ6+pORElt3wGBcjh5HkdLjRKw8e43xOfgyyFlg+9U1UDvNAYtzQ/VO/9H94wUJUDwSNI02DZwQzq+TIeUPdJ8S4Tnm0iNYSATXR358t9EJDzs+tfUjVveSW4r+nou68EHcMSxMViVC46vjk2ZI2weSleP+Bhp2rRt+RjahVe6jjeHZzRX3hgdUC8KAwghwT2kX/l67Ad5obOnFi+N5uJhV7FnmjwcV4y1EC3OVnMThD3uMibNPZTEnohdYjv3RGc2l+I6dh4dsEEK1OFYC/h5eUg8wVGAI4Yr5FGXfJ1xvwBLzzK+H2VBeIYVi/Ff8Ls18NPBjbPK1ThsffOg8kOAQxlkLvjjcVdDe0pC0I6nfXJmYhDurz+SF48Ozomh+TTm/MnT568BHxlM8+cgEOF51pBn1xwD0Z0vHhOLDoPZCHBr5Eb2s5XvvF3tmt5d2TIwjvwk/6K0xXVWnk7cL2AAxFFmo9fHOFoVc6ACm+LZeZhDcAKJeqik6OTZ8bRqXF0fHN09Ar/9y911/DT1bv2eTZb765hybbI94H0wnh98h4ge8jIGC104n7BIP+JqANdxPa1tDcvivcm/doXOIN60ykgPVxZeOoSZ7NIQi4vcM08so0M531yBvXcg5AcHx2JR98jDDCUyj+cvIBEND414Sn0oQ5eDhliNAmZS11A1WKsiP3zfwOk8qZ2GIr0NiX4CDJGMlilZ2pzNWVOGsSfltpoQUwA9x06Jxgy3nSjT54+VTe67lrPotAzJEkS9UNNZw71QcEBamQ7zbMfb6aUsBArkfRrJ2HtJJwRXN954634CWfYKi3I7pQgu3pOl5Pie/KWhuyOztOwBfnYgL98mIglj4D1jVw1rGczS39aJMOLWZMbe8q8KEzPnt90YE0soOddSzvTrsJchjByHWtTQbwvJNuWk7AromRwCLJkpUSu1DX4K7TNCeRZybS8UGdOhg1tznUp9vJzx4uskQNc2ZkMsvrgyfLYX2UsEQoRXPKCptMojMDZGiQJJwrs23bzc7VQTqTFSiDbKYUh9mBquwOhkx/QsHoveO4HLEZsszv1+INYr++hlENHoWAGprYb/w3+n0tH59QF4YiSWK6BQLlY7OJiDw7kCrErkdIaC0zqaun3NaxWCMuiWHyHlhtg4ZLllxnnyxN1hXC49IzqYngadnhFldduNE3NNw65GAznA2qGix6nmHtqzsM5uQNo+WZzlQ0OowRzhBM27ZNrGdkZB4iYGamMi1eF2780T5rehDOYGZQElfuQcMP/PogCBouX6M9p2+/QZOZ4Fjt4NaJOADbDcI4SHNyE1avoinPAUNUFuOgmOW5weLhBEOkqVJJcGB/OleuD8aLV95nBTrz690ESHAt7EBcrGoh61qpaQ8jb8VV3aBCm3ziFIjqyXSrZGP7u9xUqN3UxE+2VFEfTt+1dixV5NmQdUd91BzPhqNPrC05ppfC7KtZMRtUt5M5EwJ6abX5JPm2XclRltk7uZ6cTWRQd+qesqNwt23mtKb/MT/nccxHDX5EPXmxcKshTCddP6NGB+XfssT10uJZNucS7oghYG9B1B9aWDUDKyaw1s/pl3vmCRKg54GuaB7XQSruPOf4K91Xn+tvI6+9urr9GULBs0j/p9FCptfpNNsqpq9K+QlWpgkRsB1omCjvFviM00ZBjWgLOD4EPhnBCcQnKgCBflgyF6i2Ty/1RwNmtALS8oySHLDBeNLEWtYcVHXuiYouwKKi2V+wumxK/1O4h1V2CDyuJYAJnylOgFD73BTlQCvsg2AAiqMn7U6AAkMG+i0IAaZ/l3c4+IjZ5GcbiN7mVOv/ITrmRy3el/cc1GSsnYwVW88/uzPfgigBBIK/d0A7nCgykEBUpGvHBIQq0C8jMQYpmjnn3mhxvnfguqyiQYx/+EP+ql6qkiI7HuUrq0fBrbxSK/B5BWScsHx6Cq4b9n4gRmxc9sZmPJatY3EnmFMPExRY4FcvEIej2DX91PeJ47hgc/RiJTwFvcRRsrTyV2MdGqVHk41Rps1zvOh4h3Hw5M8NE0t1YAyAPCqLhlbxwIrm7nPxi9absCbCTJAFAO6qqkZceIXj8wml6yNa5SRqp6iLV4nwT4oKfIxIUpp0oBYvKrBOKOaYh2uwQOmxB77C0XjBBBc1I7hIjuSAQURKo/Y0r3HFNzeKUAkX8ncwpoCQJqMfpFaUXKAZgJOS8eCgWuN1aReQs8m4jF0ALahydDUCrcbQaR1Pf+0t9t05rl80AUKiYOWTgNkvDiipPr0WL14LSFlHyG3j+zen4NXMtkKJCptiF2S08hCjA8PhFQ8pK4xgtCmVfgtCbgmsHuEczX9SztRMNQVwqxg5IENoYFEHNCapuQLbn9MSZky+u/BAofdA9HlViMjGAHNBnPFMBhsKDCinkUMgLmItI9+DVF9fgK0NH1lfki7x0fWj/5QD+HvuQvyLnIjb588158mtoI1D6FcEtFz8RsEaZcm6QASCQeRNiJ0GICoYB4HK8Ih+RAAt/cQRzIDFby+e7itYK9xs+wfVzD80JM2Ndlqh5w12DgHg+agJeK3MnWXZHcyuV05NQ84HdxbzqJvIYabWBZlw047JuxkWyGoYk6SvwMPXZlgRLCjiWMrUtjw+L6b2dF1UrWBeRxUKohiGuDJP98KE/f3qX5k3ynMkX1w7KuJKEJxGl7woZHwA1iiGbKuuTcDTFqxTpjiDdiWZuuuaIU0Qal1fjaJ5J80xa6XOveSfNoZRzKCswJjKdQw2f1ZKQwZj4VkQLBqlGsat6Pp0h/En1Y1B0GnLK++OfChu6ClXEvUw5wQiv1fVF5qVm3ulIQo3EW5ZiIaVJ9nVryXZjdKONyEp2a5sVFdbF33nYjWyci58SfyAPLch0ixFPj4pT/vx29ulKNsckPrI+OqA/5GL8NybTMCB1BZl6Fvv94SQMZ8GrQ5gqc2B2Qd+Mxay+6U0Pkx8Nz2WHpue6IoOe/Lec+uEd9WeHFps53nzK3PBwak0N5UeenjQwcBIwh0PMosVcOCErie2Ko7m+uI8fX8SLfvz4FZk5jAYYr8WpHE/4OvJAKIaHEgsW+GQYtVBUffv6hlQf0eFsMg+gfKxcS81uPhvbQShCyooETnFXkr6ZSgTlFQaqXm3I6DSQUx0kbmZ1i/Kk7pVaEb4VTEnPTv43iyv//GfNeZERtZ3IX9f8CpxTDfFFmcgseXjxMZVjWo//gk2p7cAvevjjNzbPIt6FePClOKZ8dvn8ZhIObo9Xymsm7vsP/g/p4l2Javy/hqjSlfPA5H+uRrU3DNJro9+l7Y4dpiKcBriVAE49ymXA7vCH+iMfpRT+4k+tAf0y00ilq+oY7CrXXtau2wj41sLeislpBF4/AqNHZSMAPvRume/bFhuYnlWXy6TW1HYN2dOAnsbI88VZ5EBaNiT4iRRYf8m7dyRw7bkiix4AGX4zPRTXBsdIjpYNnzkQcCHSvz9+fIbdPopujx9Ll04yZBwJOaraLpl7kS/vbtpbZA9ohEohXj1+rFKI1TE7c4ckUSmsnqCxPAuXkGViwd1eN8Cnz6820DeZ+b1A/5Y98IsIRx0akQLm1TIRCwDg9VWMW+ZzLVcZlUDqkG2c00XwBkRpkBfgAiU4Evn1TCdxy+JIqpD6YxYS5t7avucCSIoqgRzoQp+a3wSJUJ35bJf8wkJaoM1eHjAK0gTLxKc4yYEyyersm2g7zy9Mwnt6S8hD1h/3e6J+S9AjU2p6waMm5XzVuYqdG+DOLZ5maqPJwzHFWb7lSjRyplzsHpSW4X+GrZc9m800ySE6pge9AxhRZPiUZTogbfLCWUMr4kbTIU+N62Pin8LcpZiLFLOlWrwgzMGr4x6kVbanMI/j1LdFeaHF35/S79BfTsEbJfc7ng6ol3Gided1ctQ7EAMfvDo+OkpPs75qJ/viliJCde3yy+TcTZOA29OYcEnrO0Kbar1f31dWq2iR/gbf+IHYeGX4WnU90mMlucwHC6t7XHKXGbATLuWYkPUcEHuSnn2vlkNBEctxzu8jdlo3R3R7yg0ZaV6oth1CTPUfksKVkngErkbEPU9d26buh5zkGArJqUfxi/rliH9C1vOUrTKfW1xACe5i5ShxQnPbT5dZ2hIDUB9yixajYXdDsJvnzgRkbgUzNUq2iJL9YmhaGTkTlQyf0QKczDcvsNPKJiRuUigdOU6+LReK4nKoffIZ6mfmWkFK8CCwx67Em0IBC9yDpHQVm4O3LEDtKldfeAZLsvdP22Hvg9ykNKXZFKVJdn7AFUWaxd854nWRvJ63HKhbJF9FhGLJhKfcwShHeopcSLOAsCDfabZ5XxaMg8qxU1EYVyQxoqbvBSVUa5tc+fr9Tqtf/oAfz8Bv6IAqT0Jj+HIYvgpWa2lgk4BKI8sO0fsybSzfLMbWdtPMiwSHP/hLX5DQkv++GqdFasuFOH0Rp7PMY/RZkq8wTk+YJKWEuzBHy4l0oAtCD1DFZPYtGMylsYFLDtuXCOTerlc5IzdUw+1KLHPJim0rv+MgR0GWzhFeYh5wmLvMCYAmZqG42PnTp0fsxenRkcFOXg6N02Pr1KDPj58Zp6fPnj19enp6dHR0dFCAMD+1vuc+IvyCfKCgParEZu75tgCYc66oOUARuT8vL+4Jsr5lWhOhudi9x7gtAJrMrklDc5LHM54PrBrSRKbNhagWJ9YsYDdlLaXTo5fEHhHqzkF3ADymZUkWlGsMZBbuIQNeFJXUroe3Lz/qXkDj1nUP/A401j3I49aorVF7v1G7G5xpjdSNQvdgz4yZ741sp8KRHw2RasOcCfLyiih/LLIcob2Qe76qrbURUPl+YvxTdmj7Zr+CY9O4vSm7nz0biE3fnMVvuRxD95kYXF6RK4l/nUqsL6lHGr1XswsmYxVZBBOUqLAFFlODvkzY5sx7xHOdObm8uj2V7YJo6ILkL0qnJkV09s/klzz61Yx9+S3WwN02w60CtMbU7WFqRxC0vtVPGfDwh3zu9Sx+JQgsbH0VCBwXuisB4A1x4/FiN2GC0yC4ORMcN78BxkkDXOEdK7fAjZ4fjUYvXzw16CkbGafPTp8Yw+HQNE7pEbNOR+aL0+OnzS1wGnzvB/jWMMiVQCeY4ipwszgfzL7jJ2yKBk/NQd4TEOusVF7LLFcCbMIgV4FtiSlud6Ty9rFwiyL+SjY1DdAaoO8LQHcEjusb11wW3nn+t0UpsowpdemYWYZsryZmzf0xb31T01CJ1kRpXcbKyuDobJdsSOBOJRet2ot1v4akgSEaxAmGBqbnODxz18I8pLWWsP3kSO2lQiLvxSo/yEu7vjeuvIslrSBlbzaOmir6c5GlhJYc8sIYqqJOnXml7TBS1ewIz7UH/xJnKP48lycoNsUQDXsNViRfLu+acGU9sZ/Ns2DmrkoRUODgPyV3sCLq4CBZxgK/ID7Qk1v4e0ODUtmd3Qa2clVMrdRztWd/D2B1uzxWHfytb0ORox3+EP9abEApBu84lGoheMcmlJrgrQZWFXXAyKlRjikLMUHalNouhFCVXdu6nFqyO2ugAVHU7YyZC06s+1xh3QVo8OoAeC2wQZQDUNHvFyWxz96EpHmx0CcTbItMmNyWUZuTvNcosnjXu80CNZj/PcCRrcGD1OVHDbAhDrxZyJwInXBt5iTR/Sv12poKmHsNC1qc7Yw429Aw0iF+rwFM1538PcDo7vN69S0B+ZIZlS7WqXTsGeYP1gU3xIVESVCfz3HA9BdyOSKdWD8H+LJ7oIiNxh0096TO2YhT+C0ef51G3iIvr62YalNnt6xD9sdUvQNtom3ZRJs6I22lbdVKG1/dc8SuJmGOK6Nw/boU9ZWG2YpkpdbZWuUxq+Id5SrW7AqzoIpycVlEWFz8A7YemJEfeP5Bm0MGnh8OhvP2x/R8i7U7VYcG4SBgzB1AdSTBvLQ6bxibjsKW543DDtkIioO1OW4ct9ruZKlvTlodkpqhfctSJZyCVj8woZkCUVweafELIOK2OFwINdLX8jJS28ATcbQ9eds1nQhoeC2tnMwVkhhOLhLM3RXOSgmAAOFpE2xW9pNthixL+ioOdrW4ZU6TBmp/zd21yd1didMiC4tSrsrMtZE9v6qabLXdV7HvFifIFH8ps96qFYBbrFFY7tm8qSoiQgeTfiTOXEZw7RKQdlpEZdNZOB8MQW+xfgS7t8C1VaXhyskic+iUWO2a1SjfFYRalnGEqjtiKauxjRfxfmmQawHkcryf5tX2jlerDkfDXxdBWZwashDNpCU6eUw8kfMugtpWrBSZl7dsVJlERniUfAhLY+S9wsijl/lp3EzkwyWAReSO+Qxq2IOrhAW+I6YMEcX0rf5c+K/i3dsolu4ryK8rr2Q75u0qsfzQZ7feN1Zu8+Z/LyIZn/AvSV14VcObL/sJbXm9ICQaqeZKYHJc6lPWqotdnvrkymcj5pMvglv/ckDiqRKwhTNq9cgXMeMvB8TysBRGGNeyvrX9MKIOubzaVGrL1WlfTY659Ci0NVurCrYFqRab+QxSGCf3fFvKA2UqcRN77IJZLg3ZK6KygNM6qCyK9ZQauEXDVLhxwMLQdseBEfcusXwT2bI89W8+1jhMGIlc9w7GHefzTIjwuYpMvm9sJ4REvXJVw7mskwp9++S3CXOJN7XDkFkioQbSq7gD9ZnI+Mu1r0tJA+p0m8RPlx7Oml+4IGPyuwmWNgicXjj3fXKaXKcje5yd24yC0Ju2YrhBY/FCJOJqUMxfXQxI85x6lEMKdim7AaXAVKNvB1GpdrxKneWt/V3j50vf96KQlSZL0M+74fOWmeKXVvbJZxtHqNR+uUIbuMzjlarCHX68m4gqoY7j3Q2m4LMc3Nni+Brc9lz3nz0xJj/thvJRuqsci1mD0Bs4jN42DBPJ9YYRo9AbmJ7rwnY0G03t+bN3YNIZOpXNPD+kTkOPlXRfEFLsAB4p/8qIOs6Qmt8awmjhEDC2GwinukEQjUb296bnUjQAuAe5+D0B26bP8A5TB2YwgX/yW9lQrq05KLoncXtes/F5JzXKSf7KG41QTTJruD0F/cGE63hDmLZpMkfgYbNhiwb4CcizxKpFJ3XVDnXlA7bdqPFbzXdPjclz/g0C+8+GMy0eAvURoE9i/gCqmPgjijs9AEUd3M9mH1kwFlBp05wObmfuYOhFrkX9+SCIZvBcm32ofBjkBHy85AigtycNR850RiUQDj2I/IZwpHaEcRDLB45nfmNWw5FSXSG4L3Jd5oCsGXqm13Be2c4/ewdxvNEgiTdqNmjhCD97B0ItO1ATsjXQPmV7N45F3HFGfIlV7CEvvt14xCZMuzTcVKcwy6Ysq2LXswmUFjLpSc6yspsSepgwFi4Es+Ank/khtd24jPgUZA7IfgP3zoTt9e12yzVqFn5/Wfih791hHM/3kLlQf36QhNnXH7V0lPaFBFm1bQlQ5/2V59eMjeFB6uoAynQOCuo15ANztZCzlJCDTQvqaKiWPVHv9s52nAxgxgApaUTe2KfEeXBkis9VmqTyJ6lFr/skek1pY7oiEYN3VVKJFJS0pFO2wO5XXRDmDOYMVlrmAGVE6zT9/o6543AiiloW3WEwxcLDMxtuk9IPR1GsaCvY37SAqwXcHRNwC3LHLp0rdvOibnMRt/actWC7PWNzgxwPyDQd/ohjlGtkhc1mga2Sh7MpORfKw7k0sLkLVicPbGNXmSRGu32ZWLIB207R1jT/a1fgaMnsrxqZOohMtbK+SveWInQxhnMD30thntfcmQ/n5PKiwt+usp+Gi5qJXou3r4vsS/1J7yFKbPvxN/SRqesbU5+5qErjWiRu39/Hr7X2Wmu/t1p7rYXfFS28VrtrtbtWu5ep3bWyXCvLd0pZvmxm+pyodsWpTAcFzKZT30Mxc2eUUQ3i9nNq8kOFDampLg9mjh0a/AUbojsPKR15vkHrSLyfWMBCcg0DkRsciIiBUBFeEOwfQNFxIG+lnYA3Uz0Wb6kT8YAQjP1noHpNxOT7Lh0n3/Rhb6WMElTHul7EMc9ovuDhzlafoM5auu7hYVDnjs4xEjP0/HTwTpAOcs3xzimXlYKY77oJDAIRTlZ+Y3hZrC2ZCfAZSULY0EbQ3uLuM263kdR+2Yj/LL73xdmtXmuOWx1aAOm3q12xyiBcae70PRC+5KgWGfneFBtgiDyPo38QEL4OWcZO1ivRGs8V4oT3EBXbWtoeYmK3cW1xkbwAkKoNULtuGdSuJV+qEW0nbDgrZHxSoemgtg5gxQvXZbxta2l7iLfr0x1sFJhX0ixIW9LA8sCfLWigYnA8TC6I/Qw5zlI6hnceZv3Ckcgbad0q0C/kxNTiruq9zsL2fUfre6RTWHg3tgTnmTe3vF5h5QXeZ1DvlGIhhk8Jw+0oGNqA6LcrXrZaKgaxbIw/ns9oEJC3NGR3dE4uPlzDdfWcCBO+IqdOc1li89w4uZmwgMUDo49AFLBMjlmHL0p+45b5MqXsvSUQjRQUewqxrS1vDwF2N0CyrraiDYS8bhshc/qKuvC4OuqRm4kt+mEWVLipc2m1W4y69xo0u6IDyYBfczXInqJ6a8vbQ1TfAV1IE/hfSSeiuD82M+GJjm2Y8MRQLZvwxKgWsV2t7t64Aa/+mW5UoZw47q5uyFtiiXsIptvDSLH/7RvyloO2QuPDCtBWZsjTuLZnLGwRQK1oztsv9G1riXuIvjvAytaB6cYsbItOwtvxA+5CGsl7ZB4rP5wOuzM0mf59xrZuWLfEld2Y32wz19j2nV+7gGAtOZh2GAPqT34PEaDjr3hlL9FmjqAtu3p25v12UQ5r052yw+hSf/J7iC5dlp2awFBj4WktfpAbdXUsKASxUKWl5aqW5aq5F/lVB9VtA2mzNdxn+OuWeLVx78GcnLXgztQoQrw5F5cOoGFtGW238aTJCvYQTXYEEVZ3lcvJbE3hYIsOb11Bg65IfCs5j+02XDVZwR7C1S7Ifmv1AWvF76uZa1fbzludgbPVHaR2wAhffxF7CBdbRIGNeDk1c2Rq1VWpM6+4K0zJut2BdgBr6i9iD7FmF1iTtn16ghB2tJoXMUQzw48cFnDnzKK/pLDsHVwW8Wci/1zMhUg9stpYOJYp+7+w4E3HeA/cgMKlrRkHGj75xfPcp6eeuZJrTNrJv9OXV7/0tSJdX1CvOfMC08Wb1b8VVW5WV1xRrNlld0XXoDPvbRP1G5bOyZ/Jxc++z+xlMqUr/TBBuuArm6RHhy7LJRnPJRev3xV7/OQnbcE1a+yWjr1+yrzkjfJHY53NoqqFYrSmxQsLHsHaWTfbHTusSbXCqknuO15vORtzXWBvUrIQhzz8AWPWq1iYoQjp8oWlFEEUlKukCLlyhfWogZj6GkjBtqNVmhYZ3CRw2FYt0Kg1RQ0bnYCNWqbz3PMv/GVIbSfIqYorX39iMuc0SYNA49KBqcclDqFDDETdme47HGz3lS9WHGdec7qGYCmFF8U6Kt94UjNQP24tWmrRcgOiZbaGTkeFy1rT3HfCsCN8YmMt/yHUQRsn2FGHvVS6FCv+1Qbl+v9MqxqZGtOno/bnlgF3N+0B6PhTtbh1Y4HIALGMjaD23PcKIK7ESi/VK7z+5595Me1YD1KvudiIoGJEhS0h3axQQ1loUVD6debhboL7S0oZi5MUf57Lc1Q2xhCNe03KE2MXtSoqFr28bVrmOO61FK+WNDAk0Ej2rTnzJUdYyIQpa+3JjW6q889xPMp5bAqTmxsBas36nqBxN7i2urDd3DagjHz4Q/mhobkgRQKKrQZlJCBjPKgiAbG+mT/HyFeqLTahBOl17qHmYVnbwhbgaUVTg4amHYGmZvaHDJ6U/W2hMaIKTRI/Ma6hFin2Cu0TGlaWtFao73NTRovmjE/Did8TgOkEbkiLhtQO14eNYtNGGRuSsXBUAUdi6NB8iJaBd18GXtXa0G2htsms7wmw7xbnWN8i4bOxHYRyyErpFSXUdPsCoTTboMylTdoXMB4q1alVdaQAwiD0bXecwvVkkOJcNGdJJJcyO3J5gVHqfDv6db6di4PKzQlMyY5nsSb5Z2LprmiWSzKM1VSD+b7nB1ULq/+sb0+T4IgpCwI65rdV/HvNX/FZgAmAGlntp7NwPhgCYY5HGNjuyGtIlCI/8PyB2h8gLDJNFuS9Ew5+m7Bwwniyp7OrS2JSxyF3NCCixyjC4MFMjqOsjlasN/lOTx6msuO/V2k5MV6RYKd106vb0wF+J02pqnFeQfKryTywMZyfj9cF+M5iYiluDyPnm7FA7EfbbzkMv+OhgVUgDE2CLQBv0R1IvpdztuH/heUOUtMcYJ9BFDAfJtT+yAFj7oCOQmDK1zP4kI0gCnENo4c0jII1DKz+TnjjtP6NGfMHM8ToNew69dHvqfWBPT8cDOfrGtnzrbXcQk6G1jDwWh4kb7CesZMqH2vYDBm5Xt8tZRVGjn2n0xn3y5O8Gog8CU/1798T3uffP4TpyxrQ8ODVwcnRyVPj6MQ4Pr05fvLq+Pmro6N/IeUAYsTbuJHj9IT+CNUIyBUMbpkf8BUc94/6R0AhgE49OaH06PTo1Hj+YnRsnL6kp8bLl+zIePl89PT506MXx0+ePjuQcv3B+7kg2KgtgP7Hx6PR8MWzkfFkdGQap0+OnhnDU3pisGcnoxfPT4bHz57Rg94BCnMHn//P32+unh59Cn4bsXdvf31zGjpvL9zpWxbdhcGfp8/+dv6r//TjfPLbf46OPgXWyDl9Oh27fz+LXv/12fnHo//1v81vnJdvPo+e2r8cDe/+99OT8enr129e/zoJo2d/vKH/Gb33f3n/y/Wfz+zw9uWvf//nN/rp5Ueb/e3v//3ffBIDSfCYOTt5+sw/PugdODQIBTWp2OI8tL46uKP+DP90631L7b5IKiCaTWnwnwiYES7wVR8lEEy8G1waPqCObbL/Ky5N3/PH8ckdPTl5Yh6PjCfHLyzjlJkvjZcn5nPjKX1hnlonT83TkZmc3JmDpwavp/hCPb05Pnp1crTshTqW0zp9MhwePz1+arx4eXRiPD0aPjUoPTo26IsXz148O355cvrseTKtX7zhg4C8o7PQm8V36uSEMct8To1TemwZT0+Pnxvm0+ETY/T8CX354ol58vz5ML5T/zj8dH317Pg6/Od4NH3361/fPo2mv7723F9Ht9/DP58+f3dxGTy7+tP+p398fB2y8fTpM3fif/rl9s3fnl9cHf8rePfn5+nR23+Mn/1xfmx+/9f16eTpmzdv3/zV/iN6/u3t0B9/CM4/nN88f/5HdHd0+el/neujv8/+GL/7tMyd4rv8tOJODX3vDngm9j1kbsC1tCtesPRHsxds6A3j62V60/gcj0+fnFon1Dg9ecmMpyPryKBPrBfGs+FL6yl78sx6Sq3UOca2FFXkQob04NVJ70DQslcH1A5ePLNG4ahPA2v0fEhfAEMrmYpXx0e9g9ALqTMQfWHBqvAl8sHeZ3l49W+oN08ZXIvK3ROVP6WkxA6Iv9yFsqHS8vBHCuwWOuHk1JiLtJgVSsycDF0Rs5OeZAsKzBaE8pqZrhX1pyDfWr+4Xv3imlHufoLbjigBF+j/IBtlKXyBV0YlduWiincdwpYV2scsLbMvJbJ/YmHku7CbnzI7qDGxBUxM85Ka99tn3g+dllZm/Q69W+b7tgXhVBa/0rVA1JD9DN4vi6nyz0T+uRhVPZcZoT1lmJKcWlPbzfQUHpMpvCU3Exv0fI6NI+Alfvz4DHt/FL0fP5YlXcmQwf8zF84Cs4qq0WDSu6r9uJ5yEG+LLNT2l6y5sZpHbRuPM49LI3KbiAwqX0MdEfjVgQe7WId9/cRQa7YthrafA9B2kZ4rKuFAiuMr+d8r7OKfsMECyzhvtMA9iVz5bMR88kVw6l8OSDwXWWaiR76IKX05IJbHAuJ6wJk7jAaM3Np+GFGHXF7thrMTX8kWnZ2KDk/Du3Zx2jdKkS1Fty1lhzKP1TNn1xYBBMY3pg2Ru4g6yBYV9OGzaLKAQshme+DCKjdli7hevOka2TWya2TfJ2SPEboWtgc2nJjJDi07MD3Xhfe8qEZT0svwWejb7JYZY8cbUsdAwUqKJznNzltsRC6STxUqd/ASi7aI98ncCDhddic7ex0NStVC1v1E+KkM4FQShULdiNPKie9RJFJAPsUXup70L1sXKAKUP3J06G1XccCmzB8z15wblvrqFsazViRWSgEAlHla+Pava739uKrTTjz9dmJHV37KIuqzQbWmncSj2hPXwKRgT3dgJairh6yWLRMAQglT/FikexR/Ig8TJuxRDRWkXB/54IUkiGYzzwcPnLsJc8m/p5ET2gZ4XpKpZ7HfH07CcBa8OoTpMwdmGvRNx4uskUN9dMM8TH40PJcdip1CSVr8Wy7iEB7FocVmjjefMjc8nFpTQ/nxznYt7y4wcBIwh8NHxA6kbar/xf3iPn58ES/28eNXZMY1oGAfu/p4fUOWUALHpXy/uPcVePlGDJIfm0Fu5j6uGWBT+MS9TqpgtWRy2wfRRiLcFuretSra3R63o6kTVuvK0PLk84YcLJMQTY5ijDzfyDfPgG2QpKaJP5+H2UCydmbk+6AgyHTZ/bp3fCeSB+T5jda4hleWP7rcCdfhvPjCxPNMFrjlxW2ID8uvpxPujcpLW9azsQgHwFFnCRB4WwMCLvCnIdtzFCjYitJFrZsVaOn9L7Wk7TMQa339W3vU1dnGit40Ni181eGELXrZIjfRosctE47B0965J71pcWLxs6wtWhQfz64DzrKr2nPM6T7HIRNhldR3KkKndA7EduCpWuWTaEheoWLky8HV2c35r4t0I3LwLwdSI6LxS+PXnuHXepQu60G0lhUwjQBusSZmsZeU1GTH3lJFuuzYZaeWNrvIXUrrs7OOa1qjPZBbsbROO3cvu6XVLp3evkLsTuq16/kpfT80PccrDy6z2HeDudbMs4GfxHx9vEMuT995DF1EtijICZVtRcIJjQnXgyC+UncMWyDkMQuzlEbgnUkowaC0GfNtz+qRgAPucE4i8J4Da7WPoWUj35uixDz1ghAwzcIP9sk5fvbODideFJLQp6ORbRKYEHUCiA+AMFhmEepacnTqzCZ0yELIxejMlxCts+/H/k/E1K2QvMrlRbUDa9VbseyxHVLHYN9hb9B5ZOq5dujBtg2SqSnomHjfwm5V+99ew8byvQdWK6FM4iggeu/y+iN5+OnN+ZMnT14SA3988ezo+BH0mNKwlnOucMLtJRnAIEXPE+PohXFydHNy9OqUp+hRZx961XN/7Vpbnvlpyczhgv0yr579zXzGgNfgFxzfC386wcSLHIsMWfIK+uRyRCI3mDETDtnqifscEPBXzT2+0vtdsTg3mgLmjRzGQoPnaDRwagc9FemNkAWh/MvvTaoZ8qmt1W96+XcUe+lmfKTbGbFl92PlKvI7Kw4Pfvi9tvt19fTxtFQfo3aycyg3IWsba427WICYa1RI9X5ggrFBwHwgd4U8x+t/kuu5G07gWZKzZJHkfTzHUoZEeegwjvSUzPy6yLsSBJgCn8p1aL6+9yWfsEISJeBfplPqWtXx8XGjHNsiSa/SIpcXA12wQeyb0bHtAvcWC4CyG7GDIBKMimBhItcSLzaGY/m1HvFweNg4MrKdkPmciUEq5VN3zHpinB7xfIKRs0RhOvaPA5lxClJBB6+A/LnRdMh82PnkLDiMBbWINO+vIuMxfGdEEQiPewdT27WngJLHqdnJzHuVM/wQT05MCTgMmGi9uKSCuR1BYfTvfEJPj8pm15h7g0uJDWvyPuXsAG8DggIomuEDa2TdNj/tMr6Nv83BoqA18c6SKy/UlLx71RTVjyGp4JSkeq+gCQltDkOJtbDudwSWDeL6p6Vf+phFL8K+MzMKUcgSgDicy38TGLAeVzkzKeSKDWaMWchBHvR4MgHLplh/VWGdeXrwNubJh6o3w6vXHy4uP7wdvP7n6/ODXvzj56t3H88uDnoH15/Pz19fXx/0Dt6cXb57fVGb9wVHgHhSmvvdFPcbhw4uKjMV8SPIyGaQg1UhShL3JVoJzR+ziGD1lHkWwD36HoxZ/jvnwqMH/oq6C9stYEYUQlj9jTiPbPY75RSs7vgnRz8zqWmL90yOH7ONsUqGunPCc9wrHM+Cbx4lX53JS5n56kRlHrAprisAWgJHBRDNpYzICcGuVL2NR0dSmbuyCAXp2+TLb1+SSuHK/ZWlPrGpFzJyLtn8nRedYnFlgfRUFmwGvy2Wi2Qd8EWS0aVrhza0TK6X55NoBtzH8VEsBwGCLO+V1FHBZYP1DRPxtrjGgjCiO2BUTI4i9CSvk8BYLoI//Snqjws+I14Mof44Asti0CdnjuPdMYuMbOZYoLOfMdeCdG9f4UNfFeCMF0Xd+ccRf9uWZXOu7Er5+og6AcuuHRhAgzqO4XtRWAjqDCR4l1xeEWpZPgsCrvcH/kBkv7RAfmbfxb9RtA765HUQwGEiZ4gSOp0yQgPiR64L1oMH+EUyZiH5L3v2Pw/QGmB6jgOaY3csaDunhjznHRfoyZSCcALFAwKGrVB4Cek35sKRiCHwLzFfW8i7xDKpNAvRyLJDBAmelAIInh2iuBKPRPAIs7uPAFp/16f0uzGyHbAE/smM6TC/7e+5SAo8NSPQijy0XfL+l0cx32PSGRYfhBaok1Z/CRaaETVDOBbGrCCjI5nS78nIPWKH5M52HPLh4w2ouqOZ41GLWUXUOd6zp6qkXLR5AEPmN1BgwxqH88LbJZeZsA3YEM4xoLdcJGUU2RQYq2pCx8+OFk8Jrorh2FM7NKa2W/Tgp3YIz0xupCWSI+L2T20XHsmjlfZFuVQgirVyn7Dy6YiaRVssMSxpgzm6IlfeCZBl4ZFj+t8yGJOymVynrPwAtDcrxxWsWVl0IniWLP33nz1F+C8wjRcJ/LCWmazlxnsfZGf2s5dLPtlgdOENlc7F+UlQJGylOKNIwgxKAuoDxuHr9HwfoAmbBCwIRNbN3DRlwdliK1Us88f0R+YBLVl4beG/+NEoypHcnMoUIvlVZXhtVb2T0r5gt9/zDwJA85Jfx5Oj7GgxCf+9rgOI4MC0OkCrA7Q64L6pA0AwW6M+IIstWiWwlEpge2I9r0xW1yx6+EOq9fEv3p0L/HNw+ANYbBjxZy3DqfyHYVtGPIghx0iXnRF/jlkBLwpnUYg8fT5eQI4VSwXCldvNqer75JfI+UYspQfDVLSx3+3eaBfyNpl6M89whnLj1jR1ZW4pa2RyKconjPgLQrfHZUMU+EIPJDx5wOC9xIV4KXF/7f9pz76SuOhbE7es5lYY5Uaq2Dhh1GKcczozTTYLjU+oVMiPdelagJxMODnGyxT3NUBx0kCVhOQMFhmhYgslF1kBA845VhsXdjDzApt/u/ZUYheykNc7BCUIdQkNQ2pOQN3DQ+3FkfBZ1JlfMsBfiLwQj/9bVtD7056l5v7aNT0cPJ+YSKgFAkGUebvUrRHEqkfsETALdXdwnJ3EO+aOw0kxq4BKDvWjtsuVAYVfA2l2zB9yPPpNodSUXt6UWTZFa6n6rboLUim1XNvrG1qwqTeCvwnnJKTpzUTYoOaEkVvq2FZce6HOBJ6cjl4On7KX5gv6DL/+jgah8d6zUK9TPA0oAQnREfZIujdhdE/t5RcY8pF3KOFgYF+KhKT8eEPbBXK2KHI7xirNUO2tjaUvhJOVCgEoHJkMRarFdzHHHttDpziACdVnUp0jW+Ib9vlRCE1hiTN+7GxvhxOe941XrZUUqmgkcjexzQmZgAJ0yJirOOkLyQmf9DGZeJG/P/Ye7ajWhqOaKF1fObc33FFH3s3hXPCJPkFwqnZmalScPH4wMqBGa9e0dk1r1/ZbuxYr1pLgzHWELmSxRXOFe8cVFnBmrQQyHP4n8kJajzvkTdMpA0W8V8Z7h4eP9Qj26KE/g4+p54Tzc1nQg5pPDPuKODQYAG3VgZqML/6agE0q7fpmEvqQ1umgfwTGy3PvbvgC2vtxdnvDPzZ3AeZboS1/mjfRvMk94U1SjsD4/tfsDswxRrMm+8aaSLZgFXWVTPPyI3aG+XmoBn0fOvYtK+VSZP4daGTEoTrppKZcWYTOVrwFPEg1OCp/cyu7kLF9y1wSzzfJASF+xUsZoP/QPmqmckFphRO/EDm3JF92edETG0cD8vnz+mafTC+lErJdkw2E82JdrZVoToZs5PkJfwq85Lpmn55nKoTRnrKB691VT/5cmaMMXyyKVFx+hvE8CvPgfIdXaLsOCyChDv8rpGmQ5diAMNpBQmghWVQyCrL7yJYPGWqEbxN97ygKMedPymrtLIjrjJ3XaUiJycD9Ex0SRZiewmC0Y6l2vCZM+EJk2gB5FK6KC0h5NSC2nY+p8wR93zMm1FA1tEHaoXYQN6ZW5YWS2Rt5DpikTxGdl5fzFqQ3Gc9NE3/cgpsN3vDDCDzrQWri/aeglzBltseYhiUPU9P0DtD0uvkIhJU/SXoBFAA79MmNPWVBSKczYlIXqM7M925ti8XpmiDYH50F5HWa0hCsRFPbceyAmR4IOEi1CZt55mRdWxDKiTbOa7DHy8d4jlu6IGHBDeeFeFP+psdjn42RS4e/BY5X01yaCybgnBr4a3mRn84csMvcyYVIe5uFU60n3I10WYokGgVYo4/z7WLstrQ8Zdfk/qp67gln2FfZsLZ5RDuYNcoUKhhE7FbitkQur69KvJMur68I6OSBssFZeUM4YhHOlmP+ZH7Q0Kcm49G7oXSo1UzhRpnCKMrwgy24TJH3URhhuDbGcgf2LbcTEF7HvdINd90+VBiHGttH6nArRTOr50HFl7tQ1RR4IgIA/2kMKeS/FbuKsaFl2yl9wOrki4LsoYPhouyl6MbLHAzBhB6xwWe4wFU7PiiuYcPMvgqDp/zy99ysPN9iC3YJJobNshOrO6uL19fnynzO8Cf85e/tJmdDVn/JrGbt5VpbbRaNHPOAJqThPp3MTDO42hCuDeF7bAiXDE4wW5d/nsJ9aqFob4UiIXms5JYnBSGLfR+gRLHA5m2AIISZiywWUtspEH2EdA5bxEfM+cCz0JxgFqO4zT7KMe2EUnQpdKJmqEQymXpcP9yAD0pIbWXkBKSRBnsg9K3Lyn+z3QWpbDOD10/pCkWPgG7EcnntjKiZZ0LEe9o0TsN7lp8cyBxgnltlmc3OfG0FcrZHYe4ZJZE4vWSyxSxp4DkcjMyvi7IwZq5SXtgXyRrjFvtDKDZUvKsOK5qcnOhlIKw1rMR4wb6n8WCDCMbLeqnc9KIKi7nZavTaZmqYhQhULy9Mjp0FDT//J7ThtwFL29fgb6FdJYhdYJOFICaa0WxDyGHHw1m46mBKbUzPKVX+4oYm2oW9yzOrKv3jU1oiFUyaPqxR61+Tsyu6FtuARXGHFZypx9/x+Wv+bqcQUgDbz149+R0i7arADbzUFiGbkOQJJ797yKTtDkBJzg3PtglWdUYKbcDDaQn03kmg6NTRO5hFNaCNl9quRLdYCqgGONFsH+XP3YE2lffSArMWmHcMbLcEmBwEFwnMqcCIRam74OKkKuNWZO3ibERcwAMyNIBsC3m48sGP9frsG+7ecy96HUex9mxrK6TphpltLvXaChOV82rsu3dhT3mi3YW+eytIZWIizQI0MpXMCbV9TFhoehZra2YiLKNx0c9afrfrC76aetaCKwiOP9BKVCjmCR0BQNQUkDYWQ2prqjipnzEtjumUkdpaQzRrVOPzAwvvPP9bYRHPFa4l/3LqfTs0BHhcVHIU+QF3TIJ5ELJpWxOKv65O6Zb58DyrZ6SequjQ1qTk9ytOFgu4JO0UAIp8c8FFvcY2r764hDwmXyGQy5l/JUai/ufsUBw0ZhHepieK0D0nFp0HZObbni8GgeSkg4AxNz+O7PXsKM4vgD05DSV3tmt5d4EoWgUHrDRMQuP/4LlQMfXEXyOXkeMg7JGTo5NnfXLlYFmwKGDkAZ/pA6C0D3x694DYbhAyyt1dHc8dx5FdvGSZmL9P78pnnl5vawCNB9XEhVcypxuW2pDxlqFVBen96ngEBvsovGlvwLrB83UcApskwclIg9g6a0KAXyqBrxlwG86JJdmwwjh52RBxA4Z6mIWxR/dEWtzVVDK105JkrsZDOO5HW0VZmEEtiF08fY23e4q3/Rjbgr4AwFUCU5dIVJLC4PI8JUmYtIrGCboqKcmrIbm6ewLCab5tHyFZK/DuuwJP63Ia63Jq8wOA8hJVEswRcVFb5QtSiS1qMQfFa9GhWfeIOWgrdQVYmg3h26r6tdZIWxF3LQzeUsUtLBAX39NUXjKXwDDF7hKY2Ux1I0qPM2M+AjiAddmYwqeAwxBiPlxhD6q4hXdQkYfX3sGR95izWMEdI4bzDfhkZEnO5QKK8xH/gakZUtmmUL+NSahyqU8eBo/65Jy6UAtziOpF5A1MbzoU+R5EqgygrngPCiO3cmXV62xmQWlz8hAI46N+qjacOTx9aZ48HxnPRy+fG6cvzafG8NnoiTF6bh4dM2odjaznhWW52feZA1YBUe97+bQK+ccq+Kdp0wxj8aKOn714+fTk6PQYwq2XT7Wwppk9O3r2Ij+zHc/MVud5ZBjKWm9DPs6i99GMXS0/lOu/ntd2On39T/Lrzc1VCy6nOgfGxpO8AakeiENrP39B8d3QnPK+csrIjkpnFhFN3TZ7fDhjPuS5tJ0Fzm1FrLLaN8suK3+rxxxXddCcr+Z8Nee7ekKxh5/enD958uQlMWIF4iMltdcyDOfJ0ckT4+ilcXJ0c/z81dHRq6Ojf7WYfGwbM9bMaCHDoQK0Zkh3kCFVDnDdzGmKmGsG9b4wqP00R7gKs+pHVRypyDL83eDN8om2YHvEnwpcvuI/7yObqOuUr1CnvGYO2WugtZbt84wByLoIf3YiqFrtHLdntZLJ1nLb/w0duuUEVsi76/KUY3JS4keeZ8QaUEAYHkOFP6Qm6tbNVpbMisAjrpG1rBbPcr2KEVRzKDptrE4bu3tpY+H4BsgKrClrbMww3GNulvNTO86ySn5xyXR+cfo+znkW5e2j8WWpTtkHLfaH/exEBgJ+OggEgyFMo27WAc007JZaI35/bYG8zLkp3qVG+e1ncViI1PXSHuIwhz8QExamORRpDQvAPUlUWAbuuRb7A+6JdCe2saEJSng5+2JTtp2EUKP9NtA+19GNHA4J3M7VEpLLlDwayXcHyRekZ+TpGAtAWbqPF+JxNkRSA7MGZg3M3WbDU7oWDd17rmqReStpaE7yqB9nqiwA/lTuyUL0z7XQoL8l0N+2Ugivl9YJaWKkJYn9lyTqZfbkPtAQdXhrs7uabs/ocoI9jbhnod8JOkBRlzrz0DYrHFB4AQv0+5MDyjigfSRW98GrsmnhtrIVB0vVctPe1m16W/tsbAchh4OF6QLKD7JoP4k6NpTkDqr3Na4iIU+46g6Xb2PBx+VWko8umUZOaBtAD2Q8fo+EEzsgEY7ozJMxA0Jhtv6DID2a52YKNpc/GHo8PDGfWKcGezp6Zjx/8fLIoEPTMtjo+OTJ6dNn8JuW3dq2WDIyVym+psta03qRnSznqDnp3eKkkTFp35Hmzb3ln/fdD1yyr3WLZdbhzjnRidPo1+PROXue6Zq1GHA+WEmlH1J/zEJm5bBS1qDjAxZ0nNCQTOgtKFNcEsSnrFxlktxEwfALZ7kZDcI9j1XU/O/u8b+148LEm8i+IU3kd4TI8/MrypbcXjxY2R25v5q0+8UJ9HOUeJWIsETyMNTAM5HLQMYiWD8PXV4YwEBaWZNxKBzbSI1UlhAsG2AfDyVqQkUluULJ0Gf0m+XducBTTLwZzwlWmgls0Sf2kYVIjnXFrAfpHeuCswOqgLMHyTkRce0IrFUT1B0hqMlZDtSbK84SzJCT9VDZOpdIU9x9pbipGOzkKvQzpKtFwts8uWaWuq6QYjN721vLs5l7RjrlkE45tAklgM58qTNfds4svlTofREzojNY7iwXu9Y8lovuieZY7xvHujYmtQ19UKUiKCVpJUqd+vxqRhUkSeJwDlohHMd2LfvWtiLqFCl/NOu5Q6wnrywCZFtQc+VABWGHIyWh14TXWKb4jOYTO88nLs13aRXibjNfiH6b1x1qpeG9YcGCzagIl0gwnmW+GqUZr8VwLeyltX/7zILdD+1fJ3Jp6+zfW1bI3WSATWfx3mm+cGO5vKvujWYM95kxLLImt5fX+476M8OcQK1bg93C6ZdyhRhxWdA+F3UJJZUJb0N4m35x2CVv6LkjexyJkCXg4JgLuzTF8u/eGAKtUoNh3ec4pGnfmDydLnz5dOGaJ9vQjKFrnbC25MFCF/KAv/UHUBX7AX/aD+pFu/GOQO6xV9pmK363xIQEvNxSJ2J9SUMgdXPoYYP/lrOUHT3XWZC1Xc4YS9J7o1HWvAzrGNTOyp7MtwArYRQBjRaBuw/7GnrFC5FbX38h8X14f3b998+vUzdAgtgSC5EIuyiUJDWDueenleqNKgPEVszhnE+ExDXS2ygLoKMuO8nk60T4OhH+lhPhA7c84NC3pkz4eV77noqDuBHnfCNec8Fkx4W/QlFr+VBem45dL4AcOIdSt29MGHXCiTlh5rcKa0DS0yjqial48lLga9GU/IpNyTn/SqEgWNx2CfFuOYFtSse2CXYON7CLEukvou3F0+eadz7T1t5geqryOAb8OAZ4HjHSDEzPcXhJpIMKHCmcfc7za00rWCdqKOhQchnLEOI9zBF0bjBHNYWWObpyqHuWeuU/DoZRYLvI34yoEyA/EjJ/5ttBzKGMfMbiP898T/z7ZzvIoTzRfvHjXrrExsLXL/K+q++/cLfLym8UNu7M019/usQaL7o4SeJx06e8HRDiuZI0AGkAWqFyxCLm5fDHomISi2BMdCwoMlEPzaoadwHNFL+6dXyrSahtCbu0ZpgqeOjNQWnvsWgf8WVBPYOF0AC9so5O9UCBe5OLbIEaGroKDWviYPYeLO474yIz5kfLoIrIjVyQR78etsiU+q4Glm7LaRrmdhzm9hG6amRmV2QuJSzw1Y8aiqJUGGGCbzfqrzO5HSNXcfoOuDk747XZHYVwO2izyC7peAtNsOmJ8i4/ewcebmvD3rIT2NswNVzD/rJT1r4lf/97XXS8SUXgrRMRFU/OhkrzgjnuBxBeJM94L5k8BWRW1Ek5s0MzCkJvOpj53nQWDkJvBrtWakdzZgbvYPAOBu9QYj/jTQlvSsTYRdazgIDTxMW7q6IuYPz2bW4Lp65qjmoNSJfyhS9d4hYdZJzZcm4wmX7bLumZC2pZNPlzPIYrPIUbOISDn636KBQe8/q8FJzZxrDy3RXhm0f47pEb/kzLgDPrOJByJVhbpR5n1i/CnRVsgmVIVmALFFa+gjtQYhCEYhZVYDZfP3il2Lv0HM+Iy+4K5xZ6hC+/yO22tZv9gd0VPtdajFX5WWjUXU8cUQm6tgOuFcd539G1S1gag+J3Iwip7TosCIzgm41zDpnvU3DXRz/xprzm4Q9ExMEi42cZXpcbPevgNW+6XbxOVIxyJ5YcqnfAgyZAN9IkbXDpdmlIXRukvp7Ownl74ZXlR6hhtDswGmPVIhgtM/OWgWCRebcO/L1hoTlZDH8QdMKjCfcWBEt2TCPgDjKVZWd536Gw2/J6pSW6DPjKLdB14I833W/ur0IRIHYq9CCHCN5+ZmG05aRw+9aqFMihwWdp3aunFyg/dQ3hOwjhFcd531G8S5gdw+9qegGLhnRgOjQIqjK6OTMDGhqiYd7m9AkSerJbhsYkaEpE07TlqMQCleogo9QhKl1Ey3bG7nQRT5TH1uYfvEa5NlEO9vsctvsMrVKtyeyZYwSYYdauohmu5lw84c7xoipurGYzSiFQqa0IWEowsiSYUmEpShoh1kQBJANGjnTmeyNIkLRdc1EY+vYQPZogNh0i1VMrW7etKH5+tXlB5WXxE7IUqOA5QzRCrgUh1wGOeISQK+Z+AWQX4LCeB5HKvR3+SH6qY9JJwWm5KScOQKkA1MSUowIq+GBuintTksaqm7Bha06yeL6fmj/cLVNO7vw07m0a9xZF22WBy+fMbJEkqmR9LoeutwyS/ILWLZUcjae9TnNa9wa8YE81dO0y44YneL/Aq5tS7SLLSgrLyi0qyEalhME6bJm0sdwHeGskRStcaugRvu1rlaXjx97QtKI8aT5LDcu7DMviDO8XMHcBhmvEK0ppOqTjgUlDNvZ8u45JJKRjI2lfxzIS0jFJetQ3kGT6dd5Oosx3rnnKTYHXDR2fi01fg9Ekf6Z7AGY3dEzOkyffTWYzjTMtWFIywFXPoKKef74sQ8awojbuEU8ptAOqQUpCNp05gvXqoo0lu9h1m1qUp9uMQ0y9Sm132QLUrhFl98kI0xxpO4SrDUwyaSby8Ic8zNp2mQw41zXPVMNzxkyTumVQOccGVSgdb0oboGzKFlSdqdVrc82ummuKjlED5XaBsq4NJwNy9U051TCHJh2NcVoC32u2UAvfncS+WgafDPAtb/epBsIkxma/sbC57Se1FZszASnIsIwhKDVrbQ/aM0DfH+PQTjOvS5uK0lJ+3KKeCamu4Yibi/IgtsBuJLqppGKXAb8uWmpXpk1i5HrMTfvjzHQDv+gsf9uSSamBIamW/WivcGtpM9SGrE9LsKPa2LQ5gF0D87lftqXO8JqbsCMlHObhD2jXwLTUyKBUy44kLPp7ANRKYXjc1C2pbbVFapctUntliNoNVG1gdGpoalpsYdLo1zL6abF9l7lKLbBvHQ3rmqFWND7Vsjntiwi/Xmxczoi1UdvVsjYrbarabTzfK8vUbnCzy1mh5gPpUt8scGluxP0aBjDNYyf+eoFM8X5VjdTF+CU5Oc2absHqfiM2f90BTelD3g+8k5b4ObmJsaGzPG0BIC00S7WSAbMYRA9/yH9K7eoSkLqkX2sqOqpI/eDWAtMN8dvKPm3bz1UjdQeQWoO0BmlFFdEGRgeipGwlBEMjBFyDOk4KdLHeRszD4mDV5TBls4pA+x6xXdOJLNsdy3zZd55vYVLZAF1sX1+8jwfqBluLS8Kno2326wbGgIXts6zJAe4+9uEz7CTQCYBY0SMK4ai8rGXiDxWwvMSc9pqCLXuI9OKdFwTkyme3UFf8/2fvTZfbRrJ10VfJ0P3Rdl+SGuyaXHEjjstDtep40JHsql27XSElgSSJNpjJxiCZ7XDEeYjzhOdJbqyVAxIjAQocJOWPvbssYkjk8K35W4I/1g9AdIoTEVlw5LNEdqMmC5okLOLxyEw88SgHcANcJuwL9RIypwCS8LyBhWQDIiJEskev8CocxVu49HGeV2q3bMnqu4j1123kTcHSdXGJwhBd2tQWIfiFSnLqG4XvU/ZUWyDeNey2z52CJ0lK5JglbZOjEK+bcqPqsPrDLNCksVKDvGZRDIhoR2xitk0SZPnZ27fGJQTDTBTxbdV5ujdZM3flNLXMmTFGVZVBlXdhVZ0NK1sGVllXHqLhmJB0EQowRhKapNvkodzl8XDm17Zkf+8y3xleO8asNpktCFj1iS0+S2gQxoSORZo0CPV6/lzIhQGbKYgTMLYsd9EANviM0BgxDsY8sA0SNKUyoyxmCTzgruPeHhll6n1rpKrAKOWecdh8N7H53uSp3BX9sX2WSskaO5R6H0x+axfaUBlVOUw/i9iCRkxmwqEqKf1l6lqZttjOxZa7JYfpNAzFDSD9UqTwpjihU0a8GeVTFpMxm4gIggJJcI0fMCIfYxUtkAmTQ0+E6ZyjEw3031Kw4I4LgLb4qmfY+b+2iLPv2M3v6uD0jbi59XSesG1i70Li3lDh6C0w+PCrWsZvLdFY3laJxh87QzB6zoIYei/WIOb1MWKmatr7B2AmRmpH5MOMIaRKTPrEIaAheLiEptoaYgKO5+9FKFJ/EoKk8Gk8Gwsa+SPyWkRE4Bn1wgB23oAksyD+xM3XE/uZZoxc8GHMvIgldcMaC39J5mmcfOLQ4Zt8/PB6+CNh3BM+8wcwPWHAGXn07g1YBC/O3715TGJYURw0diUVExQQseoSjrEZebbupqTIHp7tnE5PDnjCpiyyHx3w5PunAMLqnJiZGea/w2zWtgaL3BuWnJYxfdgdOmYWq0XVkTVr/cZLs8LejEbUg7XqYPcIL2HJME4iRueVgq88yeOA04680TaCyzPtRPIdNX3yy+jE8BZNoPXFr44RdRbAPpsEXIvIOCeAL7J+dig/Ay4RIuv6NE/DJNDiVQ1/pVDO3QQy+SRLa9Ji+PpECWJbZn7irQTxBzPiWF+oNxuhiwWjEQn4Jw5/j+mcERH5LEIvm74YId0Jx80KRwrZTKCYgHqn1ysRStlS6XFBbGI96sG38vip78NXw6QkbN5KHmTpGS9woBqlOmRpqA901uo2szVw0vtNm3uN4tDaqH5+hZ2gbBaUwZSLyKxwrwHonCDrSYoeMp5Ivhz4D9N0ob1lq3FRjqulgZsTka2t3Q0LVicPbyUPs1HonbT1wJnCpb00HnNKpBOQ2xSQG5CNynbMy0YnGnckGpUo8rLVbpKMwkvnjCeXk4BPWbSIAr6qWEbdMbTvqK6cMeWKWGWokiagjkY9gtiPKFcrZlU1lTcUy2tg8WKPcg7hNiXa9qevZcUXuDrDrYCfmvnX2cT3XFpTu7R33Jmmv+u1DQ37l/pVhUe3LMCphLjV9MQVG6GJqrjunhKajUjVHotVOph5BrjvaEJAj4+TKPWSFCeVxME8CGkEkhoOYaZ04QHbxx6aNRO50YKcMky012qrFtH5fnaE7psF9vuSsLAuuO8VlLcs6qnScQ+/Vv25VblPpXRow4vcSj6cs7m4ljx4lbIBGENhBXN5xZmEiGW4H3RgdKjb994EYUi4IKGAv0FqgJQg28sNqJ7yLaeUVU1rDWtyJ2i4H1VI9wIY2tQn1dqxq21Yq3Sp1ZnWhUxVu2Yfqpr29lg6C/k+6lDOON5b4NRFUh1t4/W4gFthp66lmrOEIgZjMopVQ1X1mHIxlSyfypUS3Rdk7UYAXHUgt0MGLFeyd0PbyQgnI+6XjNgriaBLtZoqZ2tkgsoQLOZAFKumZHZhW2lgP8HckyXoiEhX89HckzAlwlyv/aMMUioop+HyPzKUybikxTSFtmJi/KfGz/pAhMfrILQqF6rWB3zTzRIDs1QWNEoO4e2YH9MFfSdByNrlH+ShCO/7q61YkR/qchF2JEg+ZpnQG8lLgM3gZMhuZUibXHecEf375ZwuFnDYm3IR8I4hhslYNJyyZKjuHuq7benzKwOeOv33otdVunlkCjw+lywicR1Atri6qUDloKN08mITq9t5qgF85isc04WcGPJcvpm8Vd+hn+HQrW90e+77AVfTrWa7N1xbva4Kg9Zb3z0CPfzK/XOm4OBHZYRZ35mSxy/FVdAEYYr+sw7FstwCDVljltwwBn2UrCxf9QZ0PYMnJY921bhGMC1WRZt2mjKgBq++cAsei+pD3U61fMduHBjfQzBeva4PDoz3CnrbZQZIjTNKwxVtj/I4DQlkkOs6lDfa+Awpq5ixaoEni4i+sC6/teJq7ebemwzWpk9zILbBPsM0CM/TsOcWRo2r+eCgaxd6pMaE1XmqkM/TBpek3xNRabiIAhEFeJYqgnLlRSe5G4q2MRZNx1Vaodww46V0usqsIxZE+nFLck3DlMUj8o9gCsfI/F3eCNoog0swVXISRBuuxF6lXJ7np2ILyqU532fZArRVLtVq5vWQwic4aN48NPeGyq0W9MGh8x5g8TgNPw+ZH6xjz8PDq4z4Mgi3aORRAb8y618WRMfkBv6htkNGMJQIXSwQaHtfb0j0AuBdFCNeeHFCP++2MAA3/baoX+U028d5XeMeh+0Q9+4gbs0SOozdPsZ2NtkPv8L/tEnZz+OyvLKMyypfvwUuZzn6NZgs0w0QnctJ97h7VLpBDoq3lFegZm3L6b1ych1c3mm4rF9Fh5jbR8wWVQ7lCHkJ9n7F1iptYA/LGGQPBOZXRMOtuogaXLT7XpY7zMmAlNRC7zMWliO5DgjvGBDWLOGDQ8G99Jyu6vRS6zZt5yutLVGoVwfvMJjddSO93qfm8Pbu4G39Kj44yN0DgG3XvkWRKTZH1uU1WUxd31QdVTc/NvVfV1eBq3M/A+hqfA5/1sWfdZl9XwEX4x9BMpMp5xdYZH3wrf+gulrhe4NN6tztn0JoAOEWdE8ag1S8Bgk7qwI2qqeD/r0uVIPkHNalu82WxMgRjiMrkto0lxIes9YKmppdJAa3ps3B48bUM9l5Rq9SP9hXt4oPEAJ3DHgt4yiVTNeNQRQFkyp8UoZJ5RxuhMmXutP5dmFy03TMLaMfDt+2ZH4ukh75PSvWzqHatlGtTaxDARREOfS/l6VQh/7sMjZhX/rMjYcLPV6S05f3GppgThwgbRiQtN15MaMR888iATXJca/RiAcLTHtnca4MPyicUoGHMkzpyEMlShWCDXdedWowXjWFlChkzWCJtv7wjRmyeGg7toO3V87h6WbxtO/YwoMF0B3DZadgwqFUw4sNmlpCrby5HnEbTdc88N4b03Vv8dfyUjkU3kcU3oQb0WHxljsKKYQcSTzrD6ctuoiDxhZ6heiLdV99JMa6qAasTwtXQDTOo/xvidXhXbZslwnamjPO4hUtvWT0iesufJwxX/GiiTQiclmghDFhUUQBZ+FE7jTyg0Nl3F8IQ/3e6iPJaYJfKBKyEHEcAB1eRq8H/v3iPZsulHzHbs4iJguc/LViS6WvdFJhY1LBOnkbiTDdL9Fg49RtxETqB4x7DJ9rMGgXcsTG/d6CVNZD1w9YNUsW5eVfLVm0CKCEi6FYyFbiuZuCyBY28u0+GafJnkiOXXuc66bagfLdiog5JL4PSJwF1tp6UZqBVFlwq4H0ATmyX0lWaWBRDmL8zzL4BZyIG6wYWMjw0EZ16oJCvZ6DxSH4PVCr76XHpS8w3zOs7uaCWZgz3skDk91W74DJrqkB97P8BWu4X4qvuI/el9I3rna+LEoTu+e+l+I3OhmxMRlRXinneakVERZC3Qt130L73vwu2TPXd7s0ihNlSa4UJxVOl/w9zufSyufiwNi5XBwE7xaCuztcGiFU2W8rIfQBuVsuWALqdWw19LJcLyUMvIOeF4fjd16pvpd+l7vga2mH0u1cLWEwD5JmhgN5CRSl5GAbi02I/JHQOBZegCrpTZDMEKGRUEu+rqFblZdGETC9wh0pbDrzSO6Tf6ciobKTALbhlU+zOLg+8Tn9EszTOVStixsk9YIPxbv1o+Vj4SFWzmPA4gG2RI9ZQjwWhvHgE4e7qtoEbpbMqyX5As5KpCbOdfnbLGjK6e6xWwGu3pQld7wlrNZM9q+uRSHZSiKFZjzUTH6H1zQMEEAbPc/q8qG52kbI39UflcYasSn7oqkCS4ioLwYCbL31g1hfLl0H+BZ4TgrdXNmXRcRiaEA7IucMDjM0CyfB5BOHU1O+DB6SCEFgF4XsC6iUHuVkDu0ZwKub8rFIuc/8Ycj4NJl94hKiFBcsDh8dwWP4F7yQ+SSYwEvTmMXk6u9X8Myr//dqRH6BJ+HpVQD9ifN0PmYR9KP1ZjSiHiCppP6GUYyZHAjzSQrt1QklEeVTNiBsNB2Rq6/Hg+Ojo29XayBxdfstWRXZn8NcLSDM879TtuHU8nNYjOyN/wte2FoFt0bqtO5NCZDCCp3LG/tvEauR5yEIlE2KDw38TQLEoPxKIbIEdqbLUDR3f1XXDUMxLanXUBGrfiehmJJYz1Mlpy3scq3uWndNa5u+Dkg8EzfwsxY3Gn1164UgJmMGF8BzpMKyWw34rGI2HG717i2Qs/xGTNXJ3ABmTWv29rYxzGeLiHlgtZotehfUZGvYt3MoWPhzq3pwG8fgIhvHLtrimEwxiy1HZ1yCMt3ZVWJVPCJ/zBhXHlJ/UAVhcSIiFTmL2HXAbnaaVAHNOuo2/ub8tcUTLR13b9iUeu2VRoe+9wV9Y4e+e4y17dy2C03A0qheqosyblpzWyU5rfVrEzutvqw1PW0YakBFw7jKGZxGPDcEu81CMhOx6hGmVVzd/9sXTOaazeg1uodZDC4OGEsJePRhtQN7W2fONXPnDO/NhbtwijfUbdYs4H0JeBkqp71z6FpwdDuXrnrO4Vf1XzoHbDVwaiI29YdKKrYz81sTGZt6wlbp2LLP3T4hm/5eh3MbxrleKdj0qjlw2wdwQ7O7JbYp9otu6qBiE2rWClXMvKVyWLh6b1sYFMfpcGqzJDtOK7sjwLWecauG24KEZ3U3A4NTqpyrCaXyjQ0WNapYZWsDK1Vyx80NtNTdWnuD3JHs1Cw6P3cONe+MdlexeA8RK7eh0rUAwXZFTAXlrmS/NtUwGRBVRUx5EG3oelCHoZV9D7aBobu3ZysnyGHf3So8cuC3L+DXohFCzgHXAF3gs1iBW5kbTl1Y8MYFm81s2T16vXCwdTdVthcOse6WabsyTUajWp7MuwrY8nTeddhWSeh9P3SyRmYSpqhIfJJ9oSkS2kYJZM6AXq8A0mmTdxSWq9fvIaLznuiT3TJm8lSst7CobRLBBrPapphrZ1tX3EFuMAfG/oULEgooUJRkTPGInE5s/IOK8PgTN6WOVxHskDi4Zv/f8RVkRuqzANU9UF0UxkLRjsSmPwKwXkFNZMTmAoo14ehGbMIipCsgicBSo/kA6EzAsQuMJUsiq4/MVZpEql4imaE15wlBKmkiyNXxFfyPNeDceMUNz4ahJyP7iFt+AzlX0waFT8XpJpQvDanVJ/6STWgaJljFf3V0VZmVhEvKIlsMBjx5cgJoJAunDp4dDw7mAZf/fdRz+tLu7ZP6c+KE4t1ysVQtoZOL27RRujHmwhVxQgMesjgexp+DRYGA5rYi9TBD0A6ZCRWCdWg9qJSkUI0c1vVV+QoWdEsRB1QAxAtpHDNVlWqekRcvk3oxPfjEoaoqJjNxQxj1ZtZTyY1IQx9KX/mUFYVHEBvGL6RPyAnrAYzvE4/YQkSJXR6cP3E45jnlcFpzD48TqNlVWsLdtgpbpXc07wcnVLbB8Kvg8jw7hr3mfKxY4ocodPbJVWYtzyiHxM1ZIb3Jo7a8wcVME4umrMqiK/PBtks4Kd8wIu95uCRxupCYjhVsAZ8eyso3qHqwuHF3lp5yVho4UlRixUVGg6wMyDxXsIDvayYMNo/cShVcjge4a+pL7co7aXJn/Hb1a/gQxcX+cVAa6dEnD3CFSLiV02+FhCiT1NZJiGY+YBtt958QeMeeI4fKd91x5DD5fmBy18yeFWgqK5JWQmmW4WNd/NCyfMqqugPBO6OaVizeQ8S/fXJhtAO8rhk/KwCvzI3dLvNnbx0M+50nVJq07bCm3yptyCm7dxjn69fwIcL9VtKH+uRKX+VMOJRMi+1CndX671A9YrUaTMyV1Y6FOJgHQP8LuSdTllxmT7hCJwI6aCNk3olNcBNjiDRimlKtvmVdzs/wiTsd3Ongu+pqoTDnhTwPTifftk6+j16KkUHHlbr7LaKDVWjdPkhYhdRSEG0YrO9IdHKnxsN9Cn3WQGVHA8TFQO+fkHMx0fso2XRo9FaOqSrZVm+/djBGtiLinH/szvvH1hJSzkt2/4SU85rdRyHVzuUWMx4HSXAdJMtLHENzIYF1uRyyLCnICTHdehALwawbiLwhz1hYUz1QcZvusqJkktWucPeshxfF4ZKIUb8CIxww9gmM1rT/CrPeL/lhzaLe9faC2Uf9Ks/73lG3lkHmdnyHFaClNPiyXwkTBtlNGYBGDTnopYsHROBVMANkEok5oSRh80WouAd3x4eYJFEwThNZZwXntvZjN5koXjy4rdXP8plUjiLXrXWrSLtBkMUFxUZqDxBo9wdW26V/l9XHw6+lv7XJA6/AaFNEW0r/pgQamELl5WqUzqgfShdjWSp0DQ7ZNQu35Yiomp7thlHLZ06xPDh99S7ldtcuowPOXQJnixztCrCLpIZdZUWTeMG8YBJ4beAOm5U6rHOW+YPRF51RvocguCpvuwIBlb+yIhyGrr6c4dpFAcwiVQ8GFDs5AMqzkggVttqoG6AIER0DUWUgUBkhDtrvDbSrFX2I4L4/UL5uHKnGEXCIWHspIp9FXUNNkNKNtw/l7ZX6MpwL/Jn5SDcIOIc3kdOXMvheIQlqFGl4lm6Jis+Eh9k3S8GBIa3sQfdChqxkgsIplZPiVOrt4i7O/Xs8Ar2xPhWX8yGC7p5r1Dns66hdL9J66ETaV42akJmlETNGsjwEtw6KtnnUwwHLBoX7JYuRzbZWJG1Lyc6BRjsd2wYFp13fM5R3yvUeoLrKDs4Be6+Kdvt0Lnl5h3QuG85L4qFFXlfj/fdGNHTxY6gZcer0DoB2c7lj9qreH7R9I9Flr7VqhYC9JY8piOyUPIb3tE0ek0rhw1KQV6ekmSncUkoabu21HNFy/VxK2i4AfHPYfR9T0trD9/6Adc8paUpBzv8qvdMdE9aUXOiYsFYjGaoT1uRGVKnE90Y2VL9Gr8GOFXGXFXfXs+Jyy+iwe5fY3TErTiFq56y4GkytyIpzgLp9QHWOjfulFzuXxh4ibZfUOwWzt069q4Hd6tS7++jk2Cburp3dJyd+69l9eKxukd0nh+3ij/dNety7AORd1MvXzu7T5cwd+SKG5r6uxBGmgLodg4SZuaYn7SNzhB6c05Z3kc38Qc3+pqkk8qt8fzAQJ5F8MOCw18p0AZE23j+xCUYPv+r/1N7nNUB1zTLCHDdFleeEt4LTLSny1jztupbQYfU+YLWDaQfTlvPj9igtKYNXRwDldQ1xv0cRi1nyGDky1WukTm54icEcD3iQBDQk1zRMpU5aExHMPQGeaZ4ChYya21P2LS8+crdqbm6wOCkOHvuGx5fh4kJv3b4Q8TUiHmxSFUWzF/LuAqGapZ1b6moct42bKRyS4Jfva1KPPA0lb/VAs19I4jDkbmHIVG3IhwQg21abVkOKDhDRxJutQBTmB3lIOaMR6BVZ/4Uu+PI2iCF2RCYBC/2YfGZsARs9iLIWDtvSV5oKtmxVRQ11OzET6/B1DJc4ULy7oGgdpIeEi7tGQYS25ji5AsH66HiDWfcIsr5JxBYh9dic8eTxSjykkmgdinEzm/BRyjPi68f7gI/v2E1pszpIdJDoIPGuQ2K7WPA1DQOfJuoU1Fql2WUY6LX+nUNSCNaS3G9VwVzY5tlFDa0ABpD3wq5ZtCSfA97QDxN+1RD575RFy9Kb32f9cux3Y15NEMvHk/fzAOFaXZd/c7YheRrK9VLnbtUG/V2/73/CMO3gx7bM7MK6uO4uG4NSs9b9hpyLC3hfWrn8nmHF3lnfORxbUXPaFmQPv5r/XhkYtjAX6GLMP0teQUrs3wpi2HQaNtdg3ieXwAaNhk9fbinUa3/6dmO9MEvZ9zv02zj69QZ8+ZVzsLcvsIdux9aot4jEl2AOiTI3IvK7qZrm3iHe26h6mmsJXNtOE70qDO6qnW66+9hJ8xc7lNtgBz8153+IyN+kwle/uA4ItwmEowIG3Y6DxAI40yq9BuKqWqXT2m3RQEsSsTTGfD9NWHfDgukMaC3wjbJzrM8S5iEzgm4oCy28aZJQbya9mIpsLBGfeIStC1XEZ05RyxyR5yaRm8zpkogbuJ/MRZyQ46MjewdTLxJxjMnhoIju1gtazVpiRrvhTq5VaCI3dudm49Ubw8mCLcuC/juO1yzsw5QD+4f67chM6jXiCr9AU7KiJULkZS1FiCEwaS1CMv6SBj15RMDbL/llydXTo5+uyM0MOg6DmyEvVZbY3zwJwvATl5JFBgmC5Ge4EiRNkMhC/mQmYmZE0SSI4s0q3fvgqFAL5ID8jvOWrFpHh9v7gdstEjILbth2QCvdsq1RNvPSNqDsA/LVOvy7b4ps46o+TDS8C96MVfQjFjgq8ut2+KhSrjpA5LlMvpI+WxgdVsngTdqnsUJHfY7qJmRvxbIEQumln7jWMSFnS9xwcPZKBZQpnTUOfPk+uIKLhNDJhHkJa0hJuCNo3Mkpkp3Y7aTQ9uEaUTvNSZT7JlFWLezDFCr7J0K65qEd3ojo84puYsUYobylMTQoL2kZEpQX361IYOkDHbRtDNr+wLneZOivvJoPE892piQrFOo50lcEquoAX3HxK5ThaRAD2hBKvDROxJxFRG5KQnPJXt1Dcp+4i8kVzvdawbjiIjo43hYc9x19K63kw4TivQHezsE2+chbx9gawduE1laCtxVSK+mZa0XSiBVI+8RdJM2OwDgUvtsRNIe9+4W93QNmjagp42QrIdOKj5Ug8wGFxRyY3XmVsnIZHyam7bFp3z3s1YhyJtrVwrAvRLkGRP5MEjrFCNSEhuGYep/JNYv8wNOBrwpNMh/v+sTL6b0u3rVf8a5buR3UJnMy4s7LiLqVfJhiYm+EwpqBrILb4TBOaJK2LoGr0qCH6hGrFWliriyJGRElMbmxTpC56W+xdiVD+ceYkTRm/oicK0JSJWouuUguJyLl/hUJJFzKuz5xj3KQGWNG8PcBShJ9Gx6Fwi3EFyxGOTOjSG6NY9EjMg6PhQh48omLCDwfkqMBCHcC7okoYl5iDsZmHdf7YA38Ub3QDuy3BfYX8mD1Bfl16/kwIX/HlsHIoOb65c/xYcSmgeA0vIxZdB14DGo+2CT4cjkOuK8ZqStFwCIdh4EHYeAzvOMXfUMpqeHlmwsin0r0UzE7YUU/FTxEv/z5/vSsdHchzSF7UK+Q2rwz48vskYwnwSRgUQ53vTSK0XhqIvxZ0H+njOAmw0+RNw3HNGY+WdBpwHHGFeuPzulA5zj8zEbkjMaGrChlurvkImLXgbCwFoyDCTioVJDyi7r/oJ0QWbDoEq4vfk7p3oAnbMqkzTihCFsn3w0O5vRLMAdQOz46GhzMA67+1SV3REzMDugRYeLL3P49k3POfHjluRqYMm+eVg3tFwo06Gix9TqqMfUvo+L7jyv0cE7TZCai4D+9tgmoGcCT8gBei2gc+D7jm377d1XTf8oTFnEKNIjRNYsISrTNjqQniSO3HTG4WSdyXr65eKaFDf53r2LGD+ORFgJDLQRGEnCH4wzT10wwkVJChqhz56w6p6QsKkqQCfcTSl6cvjzXYJcTEonASnL4otEn/ol/mKEejiAvgfLvfz89I3IwLJaz+fe/kwWL5kCOKTj2+vL9AHX6RJC//x2Gpa4bkDHzaBrLPpVqkKDqy3ivT+iUBjxOisMKOHnu+xFD+s3di6mym2lD/qL4smLxTzk4LSt9RhUIp27SM7w57Hdwv09w//Top4pkF8EnYeBtfO4fsqyR8mVwYKHkvgmdNsk1LYybw6/qv1al2kgxJqP99WLMZNe0EGPm2ioLBwXXm+Azk5gH4Ef1bwPJBWokWrU0axJhu5c+mV2RzX/rNxbxMAALKnu8MZIKU5q5XYxTy3hdDujx+MR74j8dsu8m3w9/+PGnoyEde/6QTY5Pnjz97nv4S1uvlxZXci/5lusnXPYKFlMhnMwovv1p+e3vRCJ9vE5oPGihsSIrSGL8ryypB3gZv2iB7nYLTNm6vgrmN5AU5OC4Do77R4Bm28HhsMNh5yhq3QNKou8Z/FiPvyZFqQUEq2sBeuSwJaN01vfJKd53DOm3466S+6atu6pB4MhMDOeuciLPibyHbnrIzl9tvFVtAu7n6srKSLt6TOsIu33PoznldApBDO6rkt3HxEwQhlZcqP3uhtqzd+ATGqfrdRAmLDI7Y7wkcE+p+xDFjnN4TdP3mZSmA7XDAIRwf0HCUacUAOttvcGYPFBnSgV1CQB7KmLvmZDTML5re+6WnYOM5Dr8Kv+jsWeQ8bLJr69xr0X6x1VuteziTHghtkvZhQ42IjSOkc9suU9yy8zXujbYR/i6iW3kPpKfDt+s5uNx9v2wC2Upjp4rlShxexsN5c4bxqfJDMTQdy1RXe6CDejIWIwpEV2+wznonLXykIF8VTIwjy8nQcRuaBjWgrfP46G+SHKa5f7ihSny/VQYJu8uyGt1GXmRXVah4uUu1U8sWzPbgXDr6+owvFlVz3/gGZ0ywtP5mGF/u4VWNYnM8I8zGJYX2ar9cZ0uv9peKJxy834zuwsWEfWI2vefHPWTxVu5FYzt1Ntxt1fO3tsGAC49EYay1FRjYi3PWfOYdf3DRsa+rfIH6wvrccyeBu11yf0RQQ5v9yZnJqEyPjen76sxBP8fWJWIecDM+CzC+76pG0PKn+cQ8evBOI0DjiU3ExrGWCKTsGgRBbEpmplEjJmfF5FQ//2tJ5S1FuUWfGs5uJRsa1UQWpUdW7UJa5opgRZdAaO7h81t+fELp780v0Ncno5caVULsEXgkhZPSZFroARrHPBDRq01EAo9uPcCoVrkTlrb7vBrbhOuoiSzz5oiJFuJbyoVshW+ZSmWXfCt8Alb0w23i6stycZ6g7FeKnLtT1qrNLfuATur0W2elsBff5V7Zi1z4sGJh+7caTmEr1KtgNYxCPNOgMqt9tJcmN+eFzNxY3l4K4C+rTvA4T5fMfn7qb+2GvFDRihndndKLszhlOJCW6mWqgTCVmrpW+EHkyWqFJqbQFLCYLDF6ar76QPAzdKRuezuOAHaDPghY+iD1vJWJqQ1ugDwZ8ppuEwCD+L/QNTVLmpk7hom6lMyxP2g/lId9AdiXd1ETd4TxFhvP43YFHb6HC70YiIgekjJNLhmnCTBnEF8IxA+JndfMEb++VwPAg3AzED769EsSRbxs8NDn12zEP4cj7xQpP4kpBEbeWIOn34YsQmLGPfYYfY5sOmyJx0+Rh1V6sLMJwGXDFogE+hYpDL3Lkutw6ANySRCfZbCpuSD+ZItCoiV71RLWh/aav8G/Sj78X4wZzxWkdNbv8F6mv2SOOBeQ3Cu/fPlg+xHpzwJwj4eLR9kPzqExll9PFo+KDchABZ9zAc8x37wBHMWe1lL/aiWJhYi106daPZGX8+LVv2E/aS6yw1XiZ++vGP5tVxHQ2q7pmYq/vn1wBM+O3j2w9HREzNMzMghkUgTZtKRP56fHsCWnAdcJ1sdD3rYHNlQ/lr3cfUeULXGPA3DvwYH8D8o6HEHbHSLGSUM34//+qvLNjEf9ZfSV322iJgHKRtG2PWswRKjm/TiD6jSKK2PMJcEUy4icyjbaJcjswtG8gCuzD6Cn+OEBjxkMbSrkaMIBB9mGx7Zmhj3kUUVaJWywY4I6m56M1j3Aylr4LE22tsk5T4FtnEaxod0EViqnPXA+PD/OTk6+W54fDI8+unxqGdF+XC8BK20q748Xg7xNltj/mVJPsi/rdaZy4oyri3zMbkf1GQoKIiuaegUZacoO0XZKcrdFGWruiiYs0ufhQnt4w3W09pSPkhUdPr4LvXxSyXl+lLLi4vqFHOnmDvFvJViPpJH0SnoFQp6xK5ZFDOIsrRTyOOZuKlOfFCPgh9zSjrmM1SGYc7lHfBjdRZElF1QCCw+OvtwTlRcQqrQLs64Rm5Eq7XpoEgYhMvECeBLhuj//MsG5EUSyaE9GR2Njo+fjI5Bl/8yUo+BE4F72yCxRuZbF0GYXd8qlthtmh5yVPFBZmaM8tC34SyNWqBting3Qa26z4HtHU7qsPZEj4kdTgjcYqIeshi498klbSG/TaKJmoHDVNoYDVq4unI4EdGQ8qF6EPafkzcX6SRgac7xJvIRLkDwfl7DiQQ3YApfGkWMJ2oz4834dKRF+ncqElpsO0Te0iW0eAtTX7nRoZAd7i/cuD32iWy21lCLK6eu//Ze1hhtEDK0GXJNVzQqrh2nxp+NjHeL+CM/ztTA691bh0bqd5yXC5Yk2DFLK6eVP25BSdXOxWrAkv+NeKVkW09wNcIdNMrqBG5DjxCr+WpEKH1REaIMW4J5SqWL4CL7tcYC0/fvkBJBD+E29rbZfJvInTUDzKGKzJ1tZeaWRteHt7m9c7Od63P94ISZn3VjE5UP2GJoYqBcxu3r7hjElT2p7AoeLjt9Zenmb4OD/wgOYSlkx+g2ZzmY0PhgKeD5nZJ/z195p/23bz3LmosCujhh00HY6EVtLW8aXSF1ksTyjFTKEstMq5Um1jX7LU+241IwA9AfZ/7QzZXgpJuTbk66PQjptlkHz12QYG08O/p5h3CP5PWDv93ChJL0lsPseUN8Xolx7oWkwXxnroMFrKaciy2x97e45s4ReW3SFOMBwag08CD/07oORtI2MzL7gPiw9E32z/h9h4+36jiqFshtOe9aP30hvTt9UNkpAj3DZGchbkaTbRD3O5tX76hAbLcOs905smHb2bY1u2gjekD+cHVluDNj55Jyk9zMGK8ZP/Eo5yIhY4Yf2idLak4N245zreYb98H08cTcRg26CDQkjzRa4HyNkG/ur1oRMGaYhNkF80dlbG1mu1NpQ/l3NlLg1SG8YsSrxPgqSrzKBazhxIPDCU/0q+8akfc8VBX8+DsymUwCzny8DXY+bHtvRjkQJ4c0YdGIfBDqL8RCbyBcprLZM4sHqm8xvJ7dgIwYkLkADmu+JKD+EBrHwZRDzlM8wEiBpGDBsYjQh1uc9NmJOZifh6FhTmtnDWpgxT2luoNX772tSoXVhmK1RIDPqBy+JRR6b9G931KhPxhXW2tnQK7eXw3l6+n4h18LO7AFd2CdYFBUgqsFg6I2aycY5MW4z1MuUbhePDx4AM7U9NK69v/mAvIGftsAkw26Vm861SRB92TeHQzLEbTKt1kfhtVnOhjuCsMKm3YGw+r9dRp1Z5cJJMasBk3IomiHmL/CEtCa/SduuCwmtRNjHGzeOdhUavb911YjVSX9YIByb70YVnB3B6hr1T6VnRhrB2hX466KwraD3nOGT1qNvlgvr+EXnRrov5jTJez5OIXNzfyfSTCfp8jBhT6HlH/m4oaTScBCPyY0guMBsSbmEwZEWsGEpFx5P0bkOSdsvkiWRAakiKqCNM2V8ZUBjDaLghEuhmIxIue6g7I10mHsCaAikG2XBSeAoEnI0CtiiizN42O2xf6Tew7tu/WJdAuQ51wiApzxQEcB5JnB/Rc3vTeEvk/CpmeBIud6dyIFg6O38qZcB+ymOU6KV1QGSXUG+tBcVg6QntpZ6r+ra2p6H5lr8briau8ZDrcNHr76Qr1EtfJV7gH4VpguFF8jgrXOKMQ8wa8ZD6AMmdAwoHIOrvAyBs+5Gn3ijU0U50t8cmm08vbexrzuKACQaNBE71LIJUrH8vFrDaN6DHFCoyS+CXCPtOunJtuErzcTFUvB/U6vv0gn676+8P2YBpOdk1Uvfi4DR6cvSTKjiVSLYhJIMQQ/xTIOrfUmGNaqEVF28tOY0SdH7IQ9PflhTH/y/B/9H34cf3/y4/EPP4zL4+1y2NSIUS3sb8w3NzfFKrmMEQkVk9snKcyVgrMP2Q/tn60fZT9fRD4rNUlf4+HyOXl6qEjlGdz+6dmzunQVLEuzzadewg5dq51gw2A3yWrz4PImL4FMbvUMSS2mzAMqEhpa3Tp1ipEGqMxNBjph4Nk5R6Z9phnsMfoSZHljIT1BVRvCrwTET8CtzqChaXuPb1/9Dn3yOyRLtX3+ydG3wUEC03LZOGf6+RlrH3wWcPlBzkPMaOTNChR+De88yt660Dux8NaZ3VUVL8XvMuIFdEV0aMC4tPOgfhqPjrQ5m0++pVFEAdWChM27J8UCXFiJsMVU1/4zqHtOnm02Appqo+GGHD0G/qEfPyIYaqgqWIlQ+1s+XbYptXV2i4ailXagSqVaYQmqPKqSQKrrK1q60FWN2Kd7na6i5SndsuKy2uW1cqROa9lwtYctGvAIKdsL7SaYdZl3dakIgrVHVf878Mv1NLlbukxT7sZvxZd1mvDcnd/UV3V14+pylW6LLe/4NmjZkLHG8fQgZXh/MjuX9XavpHa7Jrt5Z+/hVwTmFmlylRJf5ciVJH5Vftxqga8b7fIs6FZ10954ftXU7QPHQd0cb4CPuN+us9XfrIvwmjihtqkabOObC8A+2AU38ErFphM18Ja1nN4Jfu+pBMwlHN4rCdiij3ClGIOUxRUyrLiMtZ2ENT1U7montRopv/Izu3e2qHOgO1PUmaLOFN20O/lOEDCvIZZX8w5VSmWV09osmOuMgTr6IWdc7pHreh3O5Dvgu96BgeoUBqcwOIVhPxWG/hSEXIbxvVIRVhE74XIN9bJmnR0P54Ins3B5uaIfPN5/qe+/nLLksnBnsThR/UzMz7Up+abJpW9uwtcR/Tr1DEXWDZqHzxKZtxUPiB/ECxEH6l9QF7MQYeAtCfWS4Bpu1z69JKJBCLcfn8g3YRrLasn5NvcpKx63VYGUX9a1RFLDI3bWt655asZLuffK43pO5nQB+UT4O3n0559//jl8+/YxlK9iKXm2VYg8JYornvlqVanauNbwzSio7+OtNDzLO611alF+mNbLrG9SGbE6Pcr6RXNewSnOvzr7g8xm+qZVvnU69FXtBXMEirvhRRgwnryCRx70JRde4dm+0Gd7VYs2EHVrFoTkP8bqsaZgZmiwac0yw5ypUzWx2SXFmbUsom9/tcbtgF+zOAkALNtCtX1Ljr5cpvRJpLU0gWqYtlv8wklh1NwrDw2YIqo8cBGJ68DHHMuKrMFqAxHrCIqZyOWMwTGbBpxbJQzqFbIXENQ5jshLxUwJh/6KixsyJE+OiE+X8dWIvE3jhKjaLpVoOEkT1XCghM0mfV1+PEhnsKi1+pgltZ8cnZwMj74fnnz34fjpsydHz46O/vvAMkYZL9UJlD+Ocb/DZ131MeIfakesh9kw5osF9RiEsKEJLvNJwqK52gg+8WgMrocYmgYnwTULl4ROoVol0ZsNWlpTnyaU/N///X9IzLjPIqAb8IIFgM6AxCnC34DQJKHeDMpKiaqn5T6Z0XjGlMDXTzx92TQpue8fizH5l9LJs5x4o1ZIUtXGzzdCUJguInCTpZvADlMraaXqloaXyUdDcIgUobnmv5yGl7ZEaRzaS0slgvHJhr9kvGzeM1qVfvv8zemL0/cfoevWxceLs+wfZ+/fv8b/ff72YHDwy8c3//NgcPDu/btXIGSKna2bx/gWr4HRZU3OZYq2TERuHmz+bbj6l7SynKH4VrlTqLfu5Jydv/r99NUfB4OD//Xx+fnzdx9O3726PH/15tXzi1cvDwYHb9///uplfjrMnm4e22s9kOwQQJMaCazgd0O4VSR1yFdHfDGnAW+96efsf+RKb6y21Xj82o5PXt3z4KBn6iJc1o5wniwuZywUl8FixRqrUWmhRm5mImbk4u2HM/KPV2/eE1UFe3pmxsv+ndIQpFcQy0q91qM+/ulkdDQ6GR3bY6Uhi5KK2rC6+cTrV6GXjVM4s62frlaCTETKfZNfjwuWQa+6yEJg8xdrNeFuIEzln1vPUM166lPbfpZg1OevX5DvnpycEHWQh6cvyYxR2I0t505JlRWiTaI2aDpmF6lyS1A+Au4H14Gf0pB8Zssb7PQDE8OXBAutdEkIinL5vtZLy8LgmkXLyzihSVqq7SxlLeHFRF7cgGYdLEA1s/rZF3Ic9hi9NIrFCrA4k9UwaGnh5WQSibnSD9l1INIs/vu3mFxZ1T+Nmg16WWjqB4nd9rqr9p3V2jWXCBanW7dNfkY+xkx/2CL7VNBvGPVH5JXU5cJgwp6Rd+KaYaXL8YCcHJ18X/l9GeVxRnNssxpX9PouN9Be3Qu6edzS1kk5sJ6gjvj98Ph4eHT84QgURKkjtusZlFN7jMvEmAY4wc5d0qu7pFOpU92hl0k538r1eB0e9gL31znefwq3r5VFlh+BcmKcHJ2U5/dDZjEFMUnoZ8DoUPApzjlGLBfIijPCYwvL8EaoLudSeAByLkQY4ka1dHX5K06mvqMiXHX+Jnd/C5XfAP83dwL6OAEFN2B4Q5exJjvigLk/k4kIQ3FTt/iaVqyiprJ0rEoCaU6/nMofj/b13Oyn8682AvQCAjkkf/Ezkz9S/WuWTHJ7V2HeabYmlfpO3YOHX61/6PqE1qEdpS6UYjrKevZrcjfP1SmKkSgqYjPw/lyb61UX7njBvGASeHnfoxXdUahrmSLxQFspliNS+n5049d/pzSiPAk4U9pwBvb5mZCKaB6kUXNmCbjccKjMt1/ULkr0Kvc16pOditMPwN9WlVkng92h5mZQcysxlcyuy5/+XvLBCu89zd5w6ktLudvA43SsUhv6QvtD6eC8DMV0DeC/tO4ukZBBwfRQuymMI1VCeyY46jkENTtG9XMeQZ+NeGDDecRCRrErB3oO2E08ICzxRo9l6GlGryEwxDihkiYTfco1UqYiAtXRc6C9Bus6HFqZz89xNkgophmPJjzQiZPbixPHMHNPGGZuz/dS2Jry1L3iSbQ86JRh4fSGvvSGkZQDQyl5dmx47VKH6EkNyILR66gB1t0NpqC8pMkoRNlfuhLAfEYoaAWQ4kvAkz0VUaAC/GWDLx+PAfSAuJR+7JpWWn5MTsDu0F6TS+EMt50CcO7MP1wbrif8BWsGU0PvxZzUMZoVRAhcZGQIzoAtPd5iI8VaUxF+xh4EWCZkkNq26SBRnAbhWHwBrz4IiUenfCy+DMhvKf+MB2VAJKOHj475ATlnnrhmEaid+Bf8VWaMi6j061kaTVn82Gp7gLnk4ElM2DSynIL9lH41CxIfFoGb4FMXaJWz9NJ6AKZmyGjYZSFDuWAYCD5JuScTnmWLiUJY+yXzSmHtYtZUOUSdj2K3CVkjpTcOAMJ73B4XvLLDfFh5cW/omIUlGWNP9V9tC+twQ5sDYdtMTpPYj+C2uGbnahnhfDvjzq6sWq0+BFPIzcsObGedQsmAvjtZdhHEynW4jhWkby2aQOrvyvVp9Kb6Uidzh8ry1rJtLPwl2EGUjGnMvn86ZBxYinxy9u5XEszhElk5tzS3lIwfbNqWs43Qs5JdMSCpCodxwYeZ4aPHxLi/EAFP7FygtuaUeoaDvF0ZT2dqizpc24nNlCGEM5huidMRXQuj4bYiPkf0RgV/NCg1haXg6ldv3+hrAaMbAbcVPJ4Xh+AgclcQeU4dPO4IHuXhdNB4W2hkXggdzyfLh+lRsr4/x4eP/S01zMorFKaW6zog0QLbISvXjcz91M81hUx/i+1acZlJJlODoWAYctSQ8oHIK8BhBQUO+CcOpWzwpxF5v5BeinCpE98rJY18MFYnx0EMLcxYNib1JeD5WEQC0Ir5hMZL7s0iwUUah0uoDdVelp+Nli9tKpKllsQ1Kv7m2YsKm+DczPe5fHk1hVFFovd5cVb0KlLPY4uufRqdeG1JwLBrsVl2Iu6JIK2VldaI+/Oi5PBvl76UJKJea/4BW0uXNxb1dEUjoH6ryyjOMsWA4UVCIQAx3leKEpuKVJ33RS5m4kZq+uZJINkGmPovsw7ILIgTES1VUXnOrYt5MfAO5kNJgeW+QekArZLhvT4bp9OppKhRbwniOGUtmWZeZVPhoGxXlsIH3Im7Br09gbht2woaBpy10A2kx2n4uQskw/WX/xLjii7D8JPKxyXqilqHdikjsXizSYzUVGY7T8C1yvRlljNCS5sadPweVYiuPjGZsaWWDC3JNd7//upgcKAYI/JEEW1qvstjCSJbHqril3Wrv39Jw8+/ibGp+m6VrvwbDEaX0PkWcoeuxnd/wqBqaWV+1f6W+Drh2Ul4AuAO6eqMrS3VKrZ06EgrxUihqgaHtChLahocghzi7KZ4NXh2pAof6QqSLD6acZatYiwjH8qPkRXlYeAFiZF7n7m44dkLlIcFowjqqVkAtvg87ZeJd+SQAWCQue+NDpnjMurBnTjZiqTXof3WjZYqVH/wVsuWsbV/nwu8+fDrv8R4VWu5Aq7Ky6pxVbeHW4mr8kLpLPmXGIOLZC6ukfgokdXTsN0R+cBRIlPnLRQj74EHDzVUpIsCYkAgsEPdlJFHVy/evz178+rDq5dXA3L14vm7F6/evMF/iIhcvX5+Cv94TDzKgaZRfpKPSBwnYgHwG/DhIhJT5O4C+NH5LtZAM7j1KPdYuGaCy29ibEbgwG0L7L6SH72WzjJNA7+EcsA3f1+Rb3sopiAGrxDRlA3VdA49wSeB8q7qfNws33XBojmFyULuyww5YBLx3AzUCQzhPzFOhgQLRX2tBbDU6q9dvR4lH3RxMKuKmZDZTZKuZSONlbqnK48LD+0COPJxxqR20OP0qn3Qq/bJoN2yI1jqYgUHcH73nppeHTrDtxIBevAZq815S3+xUTAPJUBvKK2kj5kDa14OcjNz2NZtgUOocVtINbOF2wIvtNTrOY0+K+2axpmwlFWwiVgs4EdIRlwwjgRJOikxc/vKrBGYKNnQADRhYNsm10EcQK19wJvlajvBZMbmBJITSPsgkLZt6Euc3JShf2hv5a467aW13oWInnFLylKVVQBlK7kW1bF5Co1j4QUY9lNp0YUnDiwyt4YA1b7EATuE3RRm/81iF99QEE46ZFVKQrdw3Ft7uY0wVfqHQ+29CcblltiF5e6tFTOypnhvKG160cplZ4UsrCZQydwjM6d3/oVOGesomqsJEGo7Lkn+A8ExQjgXUX5694wDgbzHOcABV4ZF9dh/NuFYgGLzRRiCRevGBEm9mujvJpLWHe/CrngXoA9qheB+k9825PRlrDdOEyP3+tl2Nnn38dHREXZc0P+ubDWBx38SfLms/ICsEkPGn64CP77q0Baihy88k+OTX1fVIqLwSW27RuQ/pZE6Q65uawINzCKYOxaN/dZYHYvGZn0QLdmTDZdGTw4IixhjN0pSNb0GR72iwLGRZ66oY5DSN9uMGxaLRkYpBUlgcMagH+QkpNMpltblaTU+WDwdAUTkgJSQ+Vk3I08slrqnluGrB/+A1AEGJBayr1hk9CheoUqhYxb7B96I6DP0LAtClmMJCWISJ0EYVr0sANUPVDWdmF1BJBJ7EWM8nolEa/OyQgbYRyroQ6q5Q9ryhmxDP1vdSX1Fpn1VEkE7ieVoT/aiUsfRnmxYELVjNpFw26dQUpmxuxNKegC2UDovZhGjDMiI6uva8+Wt+ex6P2fZSx8ySAQOiG23PgGxBf10QSqwyCJPxNMXcE9EEfMg/8Z6eEfb3OQ239Y8V+Xr8uTozrhW+abKmjFNpLNep2XBUW7zZc+YGvKABNpP5WfOeGs3gRVZ5ZLqTQxVYOVp/vUFxi97+Buza5vt2JLw62Cv6YPgrLX9tdbUGmmDzRlrOzHWMjFyK9G4mAXxbJrSyD+UDCSdAsTZ3Zf67lKE+Ayu+RWuIdk1daX41sX6RaqFsbo33+iL+blG9ufqGt00XZoU0LYFaeDjgU29ohq8I6h8SSAKbfflMrwsZhhzwYNERDJhRj+SGG6VctA5CwFHq3oCwyUayJNgrj6IPDp//eLJkyc/PR6RD/QzA54W5jGfcY8R8KijmnAJM9BcIGpSnOHSIbwg30f55OjkaHj0Y6EbaxbQYXxFJ2XlfOw6/ET0Nvifagdv5qhtB17lXsV1sxyscpFwuwWc/Pnnn38O374dvnxJ5AA7fESd97SVq7QwrDZtdbO5UBPecSYY9wuO5p3PQm5ILedgH7sx6ahEGSSdwuP6Mbl+TJvqx5SdN6kzOCV2iwksmdY4yjTCXVeXt9aYY5YATV98SKHr8+VCgOujfV4lfM5l4daSzizd53gVsa5qz5VS9QD0nyCzoPw3YV+gj3XmisGbYt3EVqm9lqceH6cSL+fgZxgvFzTO8RnqZosjcpEulMKO6Y1w2xh5sRIWcQJHWNJtwWCWhCZJFIzThO1H9mbHHpsIaLaeJSIfUawx6xOyHxJBYhElZLxsR/Gi5g90A1kWf0kTRfTSbcx+EClOeZuRKL6Ue+LSuM7apa4KEs/EjQwyme0lPYoFR2TmlNO7B+R91hmochq01P+WH2sSpSB+L2U7r/5GagJwqk9Y5UBx94YB/6zav0OlRIexS1pJkI0bHz6NmDrqOrh4saDzAblYCDGRRjCmSdi2MXkEkcu3FN4gUuQgvUjjhfzX49Yfes2iYLK8/RdiPJWBee4x8vLt8/MXA3Jx9hqzy17+z9O3hKbJDDy1nmmg02p86ji152kqQNjaadhn8iEf4L0VA2o7FvaFeokZ0TUN00Zj2n4T+7JAVaflokQobOSyqFuz5Xl0BXr31WNYjoqFk7FlsGCW5NEVctlePR6R9/MgsR49FslsxcJ1MqkKws+ZU86ccuZUlTnVpY0tnKkzVNngmHWKju+1rUQulFa/t0YTwtnQMgZ2bTB1o+OyLJ5lFSVXyWApC6M8J5d9qdIPUMeJ29ozsfTxY0KSR1NpvcQyoUpqfGAi4bDMzbFHOcea2DMt4YBKRtJ9Ca41LiWQpY4o5R7oNZq8wVIiIZhR0n93wNMl59Y63q15uuSdfm49nLDdetpSfukcKvcXj20PvP1wddX4lw6/yrO1HmtXLfxq5i7eBoHPgQNLpZnax508n4CZ4Kuqn4FGXoPECKraTLkBa2CM/SPgyAM0cggMVeCs5BSocC+1ohVQNUoOmnYLTWoZHELtHqHW5OGyubdyehccz4hBZwMWdz7EaPkVlLXb83DVIh1wcbWFuawzhGTLyiWdePk5yPgIoP2PArl8ponUT20/nHS73ahDCuwsAESqELNCIVwFdc/tEalRO6hzWtjuMW6/bOMtM3sZlW0T3R2szWaYpgBNV8JkuvAbTfKP+HtLsJQXxzINPIixg1leOUTKVsODjVW/sVEC58LHPL4Rkc3WYpLQz4ywyQRUQ8BdMPbL+iTTSLsjg1l+9kqDuQKq5Z1OK3VQvW9QvXU0Zn7QAMfpaoUvYouQeg1Qdi4vaK344dX1YAY5j9B7ZEQ+8jD4zMjZ8w8v/jEgDOtPDKEBQBjP4rC6lSCUQ2LRpljYHAyWeijmQYLYEGGhC3YaVgeGchKySUJSnojUmwFifsTKyQADwOCE5BTbg5ngmw9d3SJsGSm7peyvY7GyFAQXwwGlA8qNA+U2QU9qX5vyEo61Brj1QA++uSmz7ReMkuTgNOuBWC4p+MI8yAcj8zRMgkXI6u4kNBHzAA7I8pnyVAwgGpoE2B5XTvfgE1eyQlV9qFrDXI6AbCkALHuhAe0ReR5C/8U0svwhmHkaf+KPlGME3pd4M/yPFMpMYMLixwrG5XHB1zL5UT68CXPERp/4BYMf5guodMHnotab8hTa8WafOfrEt0hPhJ9VhiWr3rAwdYlQc99UdHjLIvuiwVMush8UPqxEwvNN2UhVH3cm94zaMdIVg7G7//u//48sKGU8iZbEo1EUKG+Y3I1/i8npy4xmAX7Qkl0QD+2apmkpuHKqVBW4fR7wM2sCj4sfW87DmM9hOivzCU35zAdIosvX5kIUU2kvLE7+h7p25In5Ac7nG8anyQwm9ORpkf3pWy4zEbco9cEC1Fu0w3pDrU+c0PlCUVwBxYV6aiFNQl9IgHZjFujeSxIq1J06SoEaEzx6UFCDiWyjay+sLDnGvCoyh3kKA6ZJMiZpkkbQ/RVm6wpm4QqXO2RUym18r8lHa1HWVKhq+mF4VKhiqaLaKrNIyXN1i3kvnLNBdb5imblCx98LiYhBrOPixeTDmtxDOEQ/W8mHcFWWfZi/1sota1aIMO2sZsIq0l7LTFI6JaCQBjqx2U0SQ8hiVZ6vO6aGwWQlWpCyICbktzRcKrKv76RhcFXxVXV0Ydbd37caca/cX03jPNBTMWVfKlICW89l3Z5tOZH5TOPbT6OcoJ5nsW6Qag5jOHFrz0Dp/O/rXmoYqJqIQtp465NeTvjOH/4i3LXZAlXbNaRxcqn9ok0Lpsoz9aWXtPaAV/EBlue9KDJaTnrl+7uxOOYkvfW8PhUInVpdSf6RS6FGXkjQEqX4l5Ka+Ax6JCDlyZWdN371jFC4L/C13ub72D0MNsert89P35BHbDQdkas0ZpGtTV09HphbfQFNFQjYiHjjy/dvn5++03cWbsJo5CKEG07Prp/Cv0/Prr83bxYReXH68pyMQ+F9xsednulHHY9ORk9GT6E9mvzPo8MT/NfJ90ffP3v6w9GR/H/Pjo+Pj1XftOJPh09/vHr8s3FORAz0TyjvDq7BqkLzJfh3yoah8Gg4IKEQizH1Pg/w/Oi/ptxU8UujDL9lHAnqexR0Uvk1YFUVOd/hyuGcLhbMl18OdsA1DRn2iPugxkXDWJjB0SxxH5MF/53SEAnZ5MQLPhY0ggCFqlNRJvBAaoXwai9PqVKhS7dRl+cBN3+oYQG1ixJuUVYwKJRflBW2UkFFXT0F+QM8jJDZU1CZ0d6ZCS6iuJD0L0tmSmUZ3QGxbOblTIwiXg4k21qV4QdGeWPoXBmy8uk9sedUOECrxpZWDe11GkL2N/ot0JRbyya1ndNiglkKEFMz1SK3NEu7L44zXJ3h6gxXZ7g6w9UZrs5wdYarM1yd4eoMV2e43jfDtWzolRpbyDhrFpRUlqA2Vtv3uZAViI41dRd95a1weQ8Og5pyGStsfZuCbcsNcsvHpLd/SifSrbuUT7TviZcyS6hrGdCcLlWSh6KXCSW7aiEVxCoK2mhNUPdcKVQrlFTpRtiFdxrVu4KxS11gCsb1Ze0pu6qeYCrJDXeXriwH9nxgubBr3M28qdfLv44Z/EmRpEPaaEtmLskrgWvlRSKOs7E4hq6dMXTddcKinVEV6XNTpirSv+yQqkgffXVundbmuIocV9FtuYp+kYfqAs+UYyvaco9imPxhpgbdLbKivLZXRVdUpaytICzKg7wpX5TLsIorQ9+MGp1ueDMiZ1p4AQvRmOX9eOB/kk4i2Yb39Mz+BVU8qQmSiE3TkEYgLeHnnfMQ5Y5uZyai/EQ7Ybr1iqHi8jnU7c/Gbw2sPZMR5Uznw6/aDlmLjKgBXjUdUTuANXxEteBaQ0xUCvAjznJBQsGnYKkw8AALcIRgYZF5PjS/hCoPFS1PQ9aNishh036QETmI2gOI6oGNqPrcS+UmEYu46hiDklXkiKw+17djImqAOeQiaotxK8iIaqagkpYIfUAD6X2RKuCcJdSnCW0HY7/k3+WIhpyKtUf4tVeG7baZhoxCtgmqodx2W4tsqAEMNd1QOzys4huq0/5aMg/ZeTT4K4BZwFOWyQslJlKeBKESQL22I+/MPNTCRG7gHnJqqMPv/cPvbUN0b/RDDeBmCIjaansVDES1Gt7+cxEVIlt7REm0HoAaUiKHoA5B7wQxUWs07JmXKO8w3DUtUVP+jsydLIBsJ2ai2ntvw01UjfqtSYo+ccUm9JBJiurmcBtsRWWbaR/4iuQM9EtYVGd/bYyzCKc2c90nM6VU3fGqT6XXrVf2qW3eh1j3WTpq+dq7ah1G18JcgZZMK2LguiQIm8mRMEhYRMNS2XS3ij5XIuVKpFyJ1PolUneoiqlC3HdgpfilXnPZAD1FwZjaNEFFUQnpiaGiQQ+xV8JKWdZCYlBKrO6NpsLpKk5XcbqK01WcruJ0lf3VVVyp8n1xoe+gVLnsil+vWLmiYmO9cuXqB3UvWK4qIbmvkYY9j9X2W7Fc5xfWeYNrpA2KmGHeYI/lygoOs24KXSqWSzeXSpbVFcS6on21cvFmU6Csq8BlT2w6hfKTRM6+6vcqIow+w1N0Wk2MZcaZYVBdooxKiYgI4yAEYaVokupSlmK1Ml4Mv2iVSjq4XfFypbmqipfx+ZupXFaL1rZQOL/GK4pts7eoD2j3ii/USzTXIty4zXpkfUzK9cg5Mprd1COXDrfTzVxBsitIvmVB8gt5gnIEOE6X3FLetoKvVuw4e1mTnNPnllU1yTSP22WRlK9Hzl9s6pBvUJMt6mpzadDlfL86kVpfq/jnUCOfpphN4mkH7c7S/HKHrnMpcWGOnBjcdpZfcfkcXvZne3eBxJ6riYvG6eFX0yl7jXriBmg09cQroDGrJC7CYk0FcblgmIHPXtIRG6M3Y3LoVibscGc/yoQd/OwH/PRQKZw/UlaFsDq3lldPn1+rcPb21cANICWrgVci1Io64MIHVtb/DkhCoylL4nWKf1/kX+CKf51StEeotG9G5Lbrf7X+tIny39yGW6v8twH9TPnvCgCsKvwtKmvtCn53Wbfbwh5tqNt1eqGD3v2D3h2ga0Ppbg/W6K6r1RpjtzJ/pqDtdSpXq733NuVqxZhR2zo1VU/2iT/kOrXS5G2jQK0s1fehQK3QvLCX+rTChs/1U9Ge7RWZClS1P1yrqG0zWdsqoN4oLrUxGKMv/npFMnB92rNrYri1BPHSsdxYJrKUpcXl/Ec6p3wI78BoqUy6mdjL0pjYKusdFrMgxmycz2x5IyI/zue3nnz3fZv0Vi4qgfO9pqyA34n8bayScskijRYQweo65JhAPYfg2dA1CoQBZ4XxPz366fuK8oza1O7zcsK+dUQKENQ82DSaQnvGv8sWSaO/Ky2jML9HT39sM8HKG1QN3UY6qYIVK/QXqPyuzNndVzmSvfk/4OhkhYr6/H8eXHz85bdXLz6AaJoHXEuido2DuxRgvagQyRuovCoYFHezNXDfAtZeNpXRlRVt6T07sFPK2pRrOSnspLCTwk4KOym8VSnsSovui590B6VFZX/reqVFFbmX65UWVT+oe2lRVTKocyfvyp3cb3VRyZtnyorqcw1kPandYq8f37ZqANM9qUrfmAvV8UUkoK145kuWUim7uDqtSt0GkyY7FVbePiJZTfnPWFOOHF4I6oz7CxHwxC7sbp9PpV/gBEGfgqAHfH+JC3OwK+grcw/cGTC0hm4ukcZbZhe1wsns7NbDYxp+Hq6Zg7Vg0ZzCsoRLk49lw4EqYDHgWUAElZWuLouZ/qUiAXMRCdgzUN65LMzm7dK3sJ6yCg+xXkp9THHonaopc3daTyx/CDnFvC5IA5NMDTrdnsr0VN0bDLIddJsvaGYuouA/ckFURV1NjWXufrw74AmbqsU8fenqJw8a6iflmmyoghLbLDP/Ui8RcLOsKHZ8mVvNRKi1Ln1PN+DGR76Fl9tVkebbm8aTsYvEDcOpky+lkkzwiIUwEGVKZ3OFfrYuU6Uq38Kl8tEVTsJm5846Y1YKV/VAT3PncfUslr1taRr4uddLSGhTzxoTLVsxRG2wOFHeRp16VVW222Wi8MEXclgdi1edrudqVl3Nak81q/IgumLV7eYZt1DJ97JGtUpHfu77quDUVnJL4uVM6rxxxbWgllJflTKA2CmqxM89jy3w1klIk7xGTCRmEU9cSx0X4DGvJI+IVs0BlTi7CZcq0utXKtk7rWfNDOZOhazyO5xM3H4hmV4vB579uXZb4GPPBavqjYdf5X+sV6dqoK/Ko6rzH+oAUrtS5UX60SXPKtVHvbb1rVDhfwVt3fwoBL07sq4fmo5zkcAtKfcF79gK10HSbmtbHTLtBpk260e1MaTgPV33zN+69LUC97DkdSXi5SteMdNfOjH0F1vlr9Vu2EIZrFH8Cl7Ti7PXhy/fPj9/keOUK/tN20KcfLerkHVa1z5g256YrFuuiDWa2iYqYuUGW6sUtkoLVCWwKwBRV8DmDVyJg9Xw17oF7gusqYkJnUxAGc0ZyINM29T6sMTHiE1lBqCSHgGf7rS2tsk2biiqdYqoQ+k9QOntAXFvfW8roMz0u12p3OlGt2FI5ilmjGp4wh4WtfpcVlUqq1UzHbnYCZeilsuHsDuwUFQ9364k3RFgqc/viFim+6yDLAdZ+9lutgX89NxotsI1d4hp+eosHLRkTc8s1cvc7UWzVQGRfY229GpzfmDnvnx3QT781wcSMU9EeVMWe2bDNerZ4oazKJ4FCxLE/G/JJy5fxnySzCKRTmcEBckkBCT7j+DMugN6rjy/+MVO29HV7ivNVjXCqk9zWLMjrPndWoxTCMffV+zZX6N2VMCDB2fhrg/Ku2ZSqYpIyyohDbVdiFNK9ziSkw4kJzpbDPsWQDCrGLzaINeJtZv3gOREzsQtSU6aF6QyWbRi+LkMUXyz4GNBI9/WR5TW0VN1YT4LMt/ezxNhKHfEUKcvytpDPxKLSz+IFyIO5HEtf4r1K2YnRmJh90VUUxHw6YDIHnT//HTw9vmb0xen7z9efDoYkE8HF2fP3346+Ouqr0/NhvSGjlnY+nMnIoQU5coegfCKsfhC5DWYo+xRPkAQeH52OoR/cYh4WJmQ9ksTFkUUlM+hcSQaaaVN5Uuhqnu79U+8gFeDKf9ajh8qsfOprWWA8BlPQLmNNE4U1VdJI6CDMXiETChLFqfbF9MwFqp7TIwanJ4OibFD49qUQWzlypQJ1yJaknjJvcZadcyebVmFvriMGDzBq9myFyKNPAZdESPpf0VlBiPskNIELgvARfKcL4lAvTSWdwSx6nYoPRjtEqbrSAVMVe/xTyejo9EJtmI8GICRcPzMH//47NnhkxOpU7XYuqEQn6HJ4uVMLCo+OcuihN+xaUAEDiO4xZg3EfNYcM18MmMUOoNJCwksJx4nUeolus5cRAEkeoZEqbzk0fHw5OixNSe4NzAlck6/BHNQy0+OsGpZ/qOqaPk25wXly7R6uc/lD3JDK6e5HnkpSmuB1K9v3v/y/A3gErbB/OenA8Cr3lBKDqs1NinxeZmE8WXAxyLlFcf6XF5EPry5INieFq+D0AWXD40rzaj+lyIbq0iTdoPVF259tElEeQxFOfXAT8w1ZCbixPRpfftfh6ccOBKy2A0oIHBG3v6X9jlYXgN1lc4nSoTuyzr/Msp1ea3CwnrGjb5Usg5EPS8ztZL6fiEnoleuHu382zBJT1E77Iek51zaAZJvB3aMHBemxPJC0BA225X8x5V6cRCjlOVys4bLT5yOY8i617vMbhwMF8+1U59iHhrm4xlf1L3RXe2NUKLCeFBqbX4mnJLrlNw7quTmsP3e6rwrV/bB6sC3hfRNqsebX7VNqsubHv1dUZ/bE9j1oU7XaFNl4K7SRrKDPKjRyx2Z190MRO6AzMtKnliPxcuuRl2PvqvwhO68XQ0FsW22vgvdbjXTbX1er3K5xdqsNaJv1pru4dhgvmBRLLi0UADS4yRats2MQf6bmkeU6HBy1xF9Hbo5JAlbe1acLAUwQPspUW0lYOarX4OWUsz024jPJiDTrdvRoYKzTH0fWECl40BX4WENXf7ZNEmo9zkekReUY9I05Sm2w6A+pFRD9nWaCNhL2DgDbStl01gWl2W9xY5Dp8ps0xw6ivBZQtJmmHQgH55xyr0SJ8xaqRJn2eM6cpU0Hxan6jgKE0dhclsKk1P7jJ2rI+YYTbabSZcDuqGlPdwtgpMWSpAMFTUhewX3GN5juE8wItSo59gqi+lWa19pVFAglJ0vpO9QWNcw6WZTmtHSlIRNQjqdQkWYoQeM2JR9Mcy0CH2TkH0Jxoa+FUnId1f8JWev8ph35klpWjYnjreeAl23qA63+zOju0Nzz9wq1aB6+LX67+tRr7QAbumkgmB4J+zWvCwQREfgRsOvyUQtErNUAHHRQ6DM4LJ12o1yxaHbXqGbWhYHcvsIcmvStGhqlgbdTcKE7gmQsbio8K5BgurTfjsqlhY4qKhZOoJgnqolLrKzNE5FxtGiOGTzXr+l4q7SOqhMZgA32ywS3NCzqJyBSeZ0G0pXXDuMPG0aoSuCcxrgHoLjflruW66Cq1UTN1EVV7kd16KBaYHEGS1MJzDWNDGgkX4JYhQsjZpfW5KYlwVgNWEWj/K/SR5ASamyUxaYDo6ABlIYpyo7MXBXxMDOkL6BSKa7GyBmHHRAzcFQzCltHahuek4pWq0u1snixXyo1qHqhufomLT9N8KA/cGTKXRqB8sCAdCbmcoeAP3faNAmt+AtbAEdTIH78Tr99KzZlQFwyOpaMJ+kmFan++9qPh0TUWdfsLEMfpLl/oXYrSwS8FXYRnl6XQR7i11gOkWVmzajE10upOxCyrcMKV/IAyZzAc+z4+Wiytu1TRXQDSXQDQvS+26FluvVlqrwMm0A+RXh5fobQdA1KiYZubyKLpfUkBLL9Jr6xy4jyXWnu3MwuX6mnRjeugXZsKoOr/szIteE5J5Dyg024OHX+h/Xiy23RG4dX+6C3Ca43IQlpYAyoHE5jKyQ3S+ZmHalaadwssO3PcI3tSgO5vYZ5noIKjeob5KTXSIGYIA68aC/rTr0t4sqt0RAjCx3g78VYeWGycgHlc0FMN3wR5gf7PHBl1rz9DO1NAbevfkiyZJ5CvpwO6C8qB+eiyg7RXA/EXKPDfctR5YbFcVNRJfrtuZaAeaWoKyDzF1wuSrC3KSgrteE5GYWGJ7WWIOvAW75q4XYUJavkXynAehu/oOGGLTTr53YuDNiY7eSYVuR6J0TWreNbkv2jAb9uBvxtfRdWMTXkHFZH2ZUrVmgHlrSYVt34vmQhdMTyZ0ylYecgp8D+VmokhsqhhUuJUNyrGPSY8ngrRwe0L+52ugpObDRgJLGQxYo71NY3J4lu2lWgf0NH7FBpuxGHWQd7uwalgzHA7MfIvDWPDA73m8N+8vJ5fZyOZhyEVmMVJsU1uuxsuSdYIp3pVEGrXCH1QqDfrSIJEohjcO0oOiSw1a8t5S3pi7I8850yljTT1Azp+t7R+RD7gcoT2HXOGU0jBmR1GDXiqoPOAtRPstsQRZZ98H0Ay8ixZZsvmmJqxniyJkuKfYoJylmyE3TkEaEfVkAMwsuYq7c2C40dulndelnaik3xJ0SxJdy1VcNPUwUb+tM3Ej9rWm3SPrTiJl9iRXucuclUTCdIsMtuUjjReAFIo1Bf3xLQ/UPm7Sucpa0YPyW/5Q4mAchRbzu/DmLSHwJ5gDQ+iMeLWiUcMiGioDmGWhh7HTMZEbU+wB3wlAV5SvaxOzSx5ocU37+xUIAze86X5hthRqWm/we6shek4cQp5G53EKXW3jr3EIlfht4Bh+oIruNuIRCtGELasG9TCLM641ViYNViuOKhMFqTXFEPsaSO1cLPS3obOEH+jnQ5KJAi2ciDYHncEHjWGkDmeaO5SbUBLIzyUy8GZMEfIoGmAE1NkJwYKRk8XkCZGyV3NxZWmHuYHfOJcwvghO1W/f/F5fPYXJ/Tv8OsNtzomDB0D78mv/DegmBDShskgBb4XCW/leHwcXUv5oUHxNsjVNEATA7OPR6CAuwWY28nbICHVLtRyagA6y9AKweUv6qD7/yb8aJiFjc4TSjzqY9aQowbp8C2IB5Mu2vJeCtSPirmYos2Q+6Y+m/Yoesga0spkD3LAkN9QwMrGwS450kcE5juEPmorSEwLzr1OX4OWVtn7BvzwzoLSfzlRS7TSTw5fbdWll7DThqMvVaQWlVjl6dFtkxPy+hnxlhMkkP8BlJa6XiaeQKMnmp5+8yGa+F1d2Qged0WQfk+wfk28fqhvQ67HGzEt1UE9QmeDuXl7RXFfHyRoALOJmkYTgiHzkGoc+ef3jxj0GuoWog4YxnlR6R1Sh1QGJBdIsxDYwmVCnmQQJvg/+OWMwSElF1cCgnIZskJOWJSL0ZoCe4S9Ekx75+c8ohYFIcMii+XkhhIq9ZuNx3h2UFdKp1cdjpsHMr2LlVHJRK2sa8j7tOLm5KO5JpmAWA7ZREXHuvlS38TDk+BhhVCrChkpz0wSeuhIi02L18PKuQxgTQT0kc8GloEF1mIk9EGmXv/sQxnzEmj5TDBV6MzdsGBHq3yX668WOF8fL4yCZS8vt8gsEmn0WjTxxyGQnUDS6JeiyoxylPob1X9r2yB/b+pBzXzeE20o3LFtM6Oca5hoL57zyT+0jtonYd2NUMZC3YMd8HftEqgCAeGkPt+68/r1Rr4P55wM+sSTxe1R7dE3PMaK/MAdNixPii8tFZ2RL4DePTZAZzd/K02I70Wy5tDDcm9cFA1Buzw+ImwZzFCZ0vDkxH01s8rbRVBlYyWkXtbagCHTqPqin9TGp/WZ4ZbZNp1kaQV/Z2hVFP2Zd67eFK7cArbJNdkRhpN4CnJAwSFlF7T9UPC9M4a8dl5cPVzagd8heR6thdynZDJXlGr1llytsSQLiU9zYiZzqYD9kVzctTDO6v/dUhjZNL7eSoCmstIubBeRhgkuqVvvSSJld6GUbkFce1CIMJe0beiWuGmUvHA3JydPL9CKWjfo7eGsWjYPc+1lcDE6dSy8AtUfv+bh3sc+fSel6fx12nHla2Yi6477Ehehonut233UG5qoFyhnLWlVXQNg+4+UPV6lcIm0rhojvNNrr7bbkpIbSn3uSV5ljVMNOqUb5OQ4gLoeokK6HWEoG20QydC5MY/X4YY+lDCtrrYKWtaqgc5BOPi5m7FVqCE5tObDqx6cSmE5v9i83WVZ5NvdBd+ece+BNvXf7ZR2KSZbzfLlPeUtVu/aC0j+eUylPvi9t170NW6xWZzulSkx3k6kzrXGRWDtaGUrC6e5XTKLyU5byXepwHXYpPq+4vFaB+PH9D5EXEuqh9+SncH7Eb2BzF55hyJfWxI7g4n1oQW1crpkvsPyOfmDC++wrRTpV0FbNpZsHkZejpcJLPldm5MruqMrsedJSPUXiKB1FVp5cJJh6oBN9G9mAahYqIYmgJlbtVgleWntX8/WXIX1GGVy8xywIyyJKga8XjzvJKqo5Yp1q48tQ5mbj17JKKVXQ42Z+l0xEKey6LqzABDr+q/1qvJm4FLJq6uBawmFXFNUFisTJuFUTa8EjotDMZvgOlPQAltRgOm/YJm3qogKs/6DIXjGJhlzndeNYTUXOmb1fotgLIZLFbKxTTzhGVpdbwjeMlxltlP/RJwKJ20OQgaQ8gyWHRnbEnt1yRlulTmyhFK+67tarRVoCdqUhrgXdV9WhN+lu7mrRdlpa1s2MbqsscPjt83lt83g0E98rjXmXF7rrEYlVwTaY7lJGhW6lFZW1FVf2DqlP4xB9y/UNV9G0btQ+VIvqelj8Y8d8g9H/Wcj3O3ljQAKwXtkjzzA/hva7j5CKBlgbw21jXqkeMxoKbEF5ZLK9OGQ04XItRLsmcq8N/q7NHq1PsanPBzisSG6VtuLTNX7uHmZxxxZ1c/y2zJFnEzw4P1V8+fYIUscPR39fJEhv0diKo7wdy7exCGZWcWC6fuUVKdw0UbCCdu6x33M2M7ixIVSG0MJ1VbsOie6Z2V7pz7c51zGoLAirPs8s+vZt22g6yTyvtPUt92kwOiSVwNvaCdJPPX+OEtTejzZZw9nTP9nS/WbBNSZsmDnObMEx7Gz8dzwPZIqRtbqt9SymdNQLWlTgOJtBlzL6uOmgD6YNq9lC1sO4hc+oz+GrrkSrDl1zMxI1qYJPQJI0HRKSJJ+aK0sAqy1H2lemyIp+kZIxOMFTvGi+hwibCgiu5XGq/JozOkXdmkoZSA4qo9xlWJt/L5ZCzKRLOgFIJDdYqsmd1S9SERis6f0ChyphNA87hTaarGab2obs4QsuRvGQTismAiSBXXNyQIXlyRHy6jK+a+5zIqYfAIk3YEKpnQIZlus7J0cnJ8Oj74cl3H46fPnty9Ozo6L9tvzvj/uovYLIwqeXYexnxD7Ujxue16U8yXpKbmTZXfDl6szXROLj68Or52yu5ae19QuZYeoWb6OrjxatzeQ1MA26udq1n4OEHgwO4X3Wc0fvGjMIKd6z6FLvRd/YVpy+bxvIt12EngGTZ8NI6WPWtULr0LDOjeWk92X61SQHewbsVpuzgzRLV2i5vxK4DdqOgUG5OFns0hK17NSBX8nf8b9iUKTd/aLsB9AgahnMhD3fCornsNYXDw4bGGaY3b/5CIbCNNPpzLsFWu4SD1DyaP4AaDHVmEqGo0Y0vM/GCJvUNg2bH+ul4Vrg5q+TRdTyCv5WEweMRwTdIC6vFKyBvtO416lmKBG1AuFCTh8W3YBHJ+FyrRkW9N8PyJULnjiJNLKgqIpJiRj8Y1MFG3ZGuPm65t96++dY+F68UDoqzi11tiqtN2URtSiaA71FVSo0xDUK1p47iOXvubhWT1NmsqooE3PVN5ipuGDAT1U6otiZFJM1VMP0IPAvqXLM+nT2Gav0ARjcHkBCRFUBdvrPsHPAL8+X7Cc50HvNsSO/hPJ0XZiJ3vvTprjd2ihNZ9nkpuy07iOVQ7oY/8S0u50u9mh2/UG6GS7MZ1vnCalf7SRmFs7FBpStbJFJ9dOrEpt3sSvD1LqTO5ftLokq/7x66iPvy8raUWbep+jlUTbuVo7HZi6oJF8zVJQeqnAdJfUGyq6rdpxE0RuGGTmGYuXkSEGva94kuZQE7HDgfsJU3DUki5uM4EZwpktckojymiE/DmE4g+Yn+O2UqKYmAMy8Ri2HIrllIFiFNwBtnsX/PGPGUMhvPKKQ3TTGplftknsZYN+mJ+RjHiz18Mb4uR/63WA55RC4kBQT7klx6aRRD1xosQFpEAvY08jxgvF3vTsViK3gS8JSRYD5nfkATFoILLwgZmdH4cg4PhUFGKRuRD0K2XqCSRmIhAp4MDF95kvfh41ANSVEccA+cAcjsZX8yOCMHZCLCUNxkr1QXMe7LYcbASCUTgDDQnn3mz9AkB3MRlrH6Qrl8MGmaHx1nQt4eqdbBMxEbYyQekVMeYJrSWIgE2kAuZIYCHFVycvTj96C1CHx6xQygtYGPh8SIgAMXloiWA/gbV4PL+N3hW/zc/bEwWw4d6n4a6fQB8zBMgAN3SCiASRizk2m2FzFPiWlueNN1jcaqA70/Is+NXSGTm9Q66J6WPnm/YPz5KVkEoUg02QMZs1nAfXikdGgMxWSCG/RntU3gIbhhYfUnk4HM9cg9Y8qSmHx39ERtXzWpPx3hHEPLpeUQq+UGKrFPZWebRu4RIymXjZCQyJ7H6QKUReYTiUexdiU9Pfqu8JLjEXmewjokWt2c0CBMI5xrDFyYL7ihS3Uf49csFAtWH4ewdOrecucvs/qafBNtbZw2uqfe0i/BPJ2bnYQqNU4KJEjCDqEyX85Sh9d7gBLSkJYyRbPThBcCnnz/NG+HWp4w+MdcvgTTJjDTQ/0LwxGLUPia9M36fnnQm7/+vcRcBX1y3NJjKJP42DWyACpowC8h7+dBAuihXRMSHFZNU/9vaqBJW/52cvovsXzz4rcjb/469U5e/8v/Nbwehz8t/vvF6ffvXp7Gp/N34s8/vuP//bv625Ojg6bZzEPyqllVmU3nr1+QJ0+e/ERCcQPOc5Fyv/A1WgwAuIzI75DEFUN4MQ58pjw/SujOghgRTe2uDGRH5LnM/iLpArYfbLp5wFOQhjPFmih9ytE1i4gXCu8zwA5w3xEal+TKz8CxSAH75VMjJf6fHh01r/B9/uoWscFCaPD74fHR8Oj4w/HJsyMdGizur1YO25yOlstpwhtXG1tqWNL/mOmNVciqL1XQOl4K/1Lfgrp3B1yW/1817pIPufREGEqj9NKMX1kGVZ9+yq9pGPh6v3SxKzuODzdWeUxPKlKzWaQNXuAGBZE91CLbZzygYbcVmYhoHPg+413WJLvpVqtS89VPy1+tth+oUhM40N2+kYvkUt7W4RuzmzbxjT9VHLQvC6yT0JqwlFWPAG0ew1oH3BM8Bq7WjChOmj5wzdPH296e31UfGZX2qhS27Q+q4sxcsCRdEJ8toK8895YwYT88BbrYH48e6wQYcKEESczCCfz809FjkrD5QkQ0CqCdCDce/oPBASA8k44hSxOuerEnuB+TMZsILIVJomWWY4ygMpCdnUA5ro19ZkqbpXvB13Y554wmacQu7Q/pcuIrbkdnSJIu1n1m+ea+T1qzu6bkkAEt4UzZ+ipfz5tkgBufGzPhq/F2emI+8iCDbxLSiI3oIhhpyj0c3UjxRGOkABxszc6cNs3MLYHYwlfT1kmjQhkNHpoGrkb57mHsiUXGdylzNEbk5bsLtMQjP851QEuRfjkLLv5M2BfqJWQm4gS+1UqrAKtP6WAx+AtoSDzK/QDLg35W+hoeKxywEhenL2U6kixtiEQYQjGAM6rvnVHdgJglM3efLNstmLS92LJf3rz47V/e/PeZ/+vvn//rye8p/a/ZZPxH+C9v/tN/4Pd3/5nevH35PPd/b178hrbt6b8+f3n/65//+fPD69mbD8+P/vuP/5W8e/n26dvl0Xd/nvwWvvnjfP7uj4/H7/71+vPbf83m71/89lOjMazxoXkJXlVhiY5lglcQue05ofNxME3R+pfxUS1Bmia/l4cXUtAavlh2Kl/xwafyIoRboKqPUhmLJYJLCAxlzjIERJq+retz6uKAPseGEQD7KPh2bnyihOugn4SK1Bv5jQFLL33eyXTN33g7A9ZZrs5y3QPL1Rl9zuhzRt/2jb7Q6lSxMtyuA/xlAmGeM+gauIONdYWGCNJ/FPWBETlnkBoSGz0o1vFjCAZDN+vj70lIxyzEApEbjN5C7tMUFFVpOw7PKNgoXzzG/JicHB2T5xcvTk/BCRZRD2yNn40F88MPRL4FTpLRvaIUTS+aIPqAVYRfIYusIEAtne5DNPVUJwXtnMegriKLiMg45X4oP3iRjsMgnkHHsS9emMJGGJF/mM8MOIYKQMHzsAQKY8gvzI7AufqP4GxApOoG5/8/mH2QcngVJWcXb8giCq5hiuN0Mgm+QN7ODGIDNyL6DLmiPrvGIoYZJB1gGr3s/5SZsiYbHw03xlkUeNnMgEEbBl6ShS2eQPp9gN9IGI3CIPc0OS2BMeflasqJmlszLiCeAUkxlxGbsIhBkkAAeIemqiyYHWQKr3QRmDE8lY+1INTOMGBfFrJqUKVwwDJCeGNE3glI4h3qXhp60WCmsbYwJsLz0mhEXqRxIubqJzGGCIxitYmYvJdxX+rnPsHTIP8OyyqXEwxr0OEh4mb5GdBMxmwPQs1sjMhFiiQKuBmkGyTlAZpmxUmSwdlomc2pNfmQhRIuwZcBljjOESV+MMGbLVujNKE/QSwKN6Cam3+nIqHl647lUY6YZkpBGWS7FtTa4QJnX83QL40JD2BExqjL4HcAfP8sfSdqseH/hcEcsztUAOvkp7wf4scfi84OABJVmhghooAZK4UnPNs6VnCE5BkmvsBxyI2aiBsaycq1bAgj8hrzTvAse8OX7y4GEj8W1MPUC5WfKNuxpBy2GUJFwMEtBe+LGfg8EukUiZ3j6I45jv7aIs9fwVyTIrgtR32/MVZZx9kpxqpuuZUqthG71P6wQN58afw/Hb6wdO8mzD9n9N5Po7cyXPuPkpoFYdgnjwdluZ+74qfHA0MwT6QmMwXeHhnFHZS0I7RVy+Idrj5+vIZZCoIuRGFUMYYgzjQwYLBSebTkkaW+geh7vDGTVQ/rUmlpXfZA6d5vA+MshjWFXJxOm6p8M7IIcTpl/iUoI10elrvv2+AA1/FSmj7dhlW4E0WM2muXeq91eV7F3Rs4RCcVh+i5gsKy/gj7+8d19vceuF3U6y7hcy7xc7qtb+X9zpfnfHnOl7c7X55S6ftJ4dDmQbsMjsOvuXlq00rHOANNH41y25wVzkA1WZJ8Hel5x8Jfgu3ohTSYY49unjnKLI+BpP3FCoZciYoq6YD1g6MUREzlY3iKIhhUZPPAiMUijTymK3+UxgIkG4l2TOJItE4Dh9JoNdKJRqj3mYubkPmQHI+FPhG7FsqMhScUR/Mse4TWfmKrFgUamBOaJjMRBf+RT3n9x8tz6RpKgGh+JkIfamKU3wRmCTOE6Riqwp8cqzRh+6EKSWBq1XfwvI9TfmpRq6RcdWiTXiSomUGaLHLOFpLKx1A+ST+DmUBYoMAHdExwAWxnnKpuytRAcIvICf711QcrMfnpz7oCCK5/oydVQqv6usBl29w1p4lFRJMHndYvrE1WT9PA126ZVYW9q10ilgzXm6/8mHMWSpKyj+ensPUWIgxNFoxOwNdIo8rymnmC2ikMiSA3NEi04gCvha2lB7ph82kds0l93X65f5yHxnloevTQYBa93IJ41F3KvLO4nMW1rxaXMl16sbjUsxpb9hmbSbb0KrTnW2ktSb04l/uOemWARFpplKU+WAnxQO+K9AEmoD1jNExmslZQKZsqp9ejC0XXINErBn+ZZAChnPip3M1gRqlEzew9I6Kri1JtveUMNpszwRhAlnb71KnxTo1fqcZvOoFXZmd0wUt1B7BDgToe8GnXHN7cfSA/zCG8jNMYxWO3UGvV/d8ATaYR7fgscw/cz+PLgAPpUoRUWZ2mqXyzeqIMmsrdxbtPf90jvg0OxA1nUTwLFjo02+W55ZtzT9S5O5cL2ceo65qveJIzk5yZdDfNJGd/OPvD2R9t7Y8Imwr3YX2AQbF+sOcQpRDmr7VJ/1ZX2wbM7/intSM+F96M+Wmo+/AuoN+mZsNStgMNWQyhmn+nLJWBnJBR4ASFOMyInAJjAZOpo5KnkUjRanpTILvfgIyXCwrJl6AnyJ8w9RLzoBcsQhY2z07wVRnd8ZJ7s0hwkcbA6fJ6VWAin35sZ8bY4xrJ9GHk4wZ2ckZlrwPqX1MOnztmS8Fl4qnkbcEq5AAy2U+MkvuztgZlFTNKlJTLMm5IVzep9hgxWtohFkjtjTCao+mSnxyZ8ZYyfE+yjG35GgAuT4jQFzeY55NLulVsZBkTHE1InK20Wl65X+0MWy31s2SNgZXc6wxFZyi6eM/W4j0S7C8l7HaR5PkbnUnjTJq7adLckchPZfbjWVbPlNOGjMiGJMgTNHf0vsxrTfcjXdL+prVzJusf4sxoZ0Y7M3p3ZrRsIt+PIa1s25W2dCRSUO0Pqe9DXcNKpnJ1/dBnYBLgr0NzL1JjVf9UJsyyLiP2ZeUuSHH1tbalBMsiF+hcDhDJy02h6X6YDc2ETAWJBy14sj5DWe+fhp48hrDpOI8CXWihqkmTyw2PdJugxnHkiKO+s3mjvrNHlfXiajmsC+iiaYaiVjr2VLWyiLBLufkX8NQ3cjfR2Mu1NJP/1qdX/xp7+Z6LOuLRdtBZZz5TMV25rdu0ojBjLXWmGCBn0F8tg471B7FD4LHLybDedWneZQDZIu9pMkcK7gPpIRARNtfBTgAIBAqp9CdJMqaFQepRzz0qNO5Uw1pdS+P8vc/N7MumxoPa38/R49qP9FETNVKjtbk4vMlZSPnzXK+NrwfjNMbK72z7JSxaREFs9ifUzuv/XkTCdLavbt6BfAw0DJdDW4FqFoGFQbNbc4I0CzZZhzCkVT9X8odU7YMaFpHqi8FRMhEROhOXkBSDw4Q/Q3/cqhPLmaxFHLMMYTJ2gCWkscBvaSxVyAdRa64afVXAzqXVpaey+rwCLhvXa2uAmcEloF2YGc5VzkLldT364RnRnqVTvkiTuwB/G8K3XH3SPUG4tnVSJXX/8GvVDssObIsCqmbklPeuxE1VatUGNeWlsd2/uuK2eohr/uAeYW/Fi2xlckuwuwrg6ldh9/BW5aLV8Hb83TONHpm/9gFDXC4h+J5AnKnP/DKciGjKhupoDNENAIE01W4236gLNH4KWy9cKtqmuFqAj1bkPDfD3JQlLbRDzI9uBXK/MrRsZYRQUrRFdYgn7R0aQhrGUjEENKh4Dv9q8a92fRz83SMD10pXuifYiGlTcN4Tb7Yefknf80oA+4iXtUIweamskVZpPWLilLb9tZXlFujLVq7fKQ5L75IqmQtK3RO4VN/U2loG5tz4cBFSviq1VIOs+V+4cwh36oSZ/E85cIW5zZIG1TIja29dx98XYr5INcjmt4d9n0xZvBEp0OMydBRKVyHUvHEPeW7JHxGFMxINFf0WbE4shMOBsgR6/QLrGfexr6vu0SfpgiFN0OStSg0U6Dx8/N//n713UW4b19KFXwXlOXV2srckS45zc6Znxte0u+PEbTtJJ+2UBJGQhA5FKiRlW8mkat7hP084T/LXWgBI8CpKlm3Jxq6a6VgEQBCXdV/fQocMKpY41IMxPqrPwa9uwyFQgFWVqeh2zmkIoMzyLJlh155zPhHNS2KTRPTZxhZ57wKgjJs6ltLVTbaj46W4AmLphtagDtXZQ+r3mRYKDYGIzgUCA9PUkHXmAoWIiimpwOLI9TuvGym6iXCTst6jAoursrLiHnEwtdYivOohdUChgyhZ+FLmB+uisnZQi7NS5beLSG7qEsyxaguUnnZI++Iy564MESv+USD6iFndFOtKnMgCluWOHWc12IYixoUsA4n/VIYRCKfzOkZUTQulkI3RdKD+LTumbQbyMYke56dU66G7NoWYJNVRQGGq8F51sikUIMfYIipbIFHHA2XX9Kb/CKKBxwGEJiCAUhAibtEfqivstxgPTuYElGm1E69kv0QryMkWP3nRa+VEPD/uUBBkded8pIo1IblzN0S05UtEIF+x1Du3K119BNbkvTkX+qkEI12QJCtnvRrqvppsdMOvlyKlCNGQBXCLgvUf8l8KE68iXRK/yL4JsnTAQmBqyvoYNykmTT69xKLTT59sbJCjw6N91SsiTH1+wVydPEUt+GJ91sXBQK2NJ5tPE2p+vHILGP7f6c6Tq99fDo//S/7WsLzhf1SlKGdlq9hIEhX567rfs14IQaVCIkqXu7C9JXqykkiBSMi90dTkRZI1dRDbSB22Rxyly7LI4m1IF4vw+CQxs5Bx3d7cHhRJxGizG6aJCyOGPhuNwygdqiIF1DplPDlKQdCbFJM/CYYZirSrxP5qQ2iYnbJkDoOESenM8hxuTQAHVGYbQmodoGUCHY6bQX7er4iOMxHJdyhyaQ0AqjII6XB098p4JZdMZqFvWJCKX2SEqRUWphIXczE0BP47zQioyEdU7Jm5dr075o6NnoqYiMAeRSJUhnYknkYiknSfgOFE3opxoPJFRMkxDIiXr2uQYwGXJZ5DcosPtbAsPgKQ3ABsE12oJCQyfWmI2eghgfJBUOSKXSGnH4RD5xWhYUitAWD/yvLUOFPqzEFDUjaTiCqogmNa3H4xuZlhkHSy6m3aAZOywo48B1UtgPspohFF/1eeoPx2D/d5De+ccuYABQAqFWjtqO9TiGPnIRvi78n2Flam/ZEK+odqD1IDyE0Njlf3LzFC3P5LLTXDn/FgSzcvsf5zbDtc5pMo70gN1IYIj+l7hMc49+Nkie3st9VEtklenygJJO9h6IXUaRe9MLViWjqJ6JHsD2wiGFsWcoMfOUkNcdrCl/TQql9NHdBo7bXD8aV6HnWNRIyEdJlFAWZAkgmh/KzL+6R+jZl1jDr+1pM/XwJ+eRcJaqhMWTwgA0C+cJfvdtbWQAAUuXeS2RbeijjxJcn4cSYNVR1KFd6Q31HLbSx+U8BjZW1cry0XrO0wt48sorh16HntLu+XtolYXBvSJtElaK9lTtmiSFEeYVGEIr3BcnlhR77kbEyFC6NSfIpuTDTj7OX5UiK+JjkND4jNA/Ss1CLhIfbgqPKGqRy8hIiLHgyWHjUC85Mije6qubf3JvFbWy1s6QkWwhpCAsSLXNpDSVsxXKI58F9KwA+SKjimGuMBxeoUWrEvWfaBODRk/itwVkguQAPkAA/m3MJZxCBTc7Cig1VSrGsdq7BChZNg7ANaF9Mqr0JAxoBbAygVC5lZKGngctfICCHBCJw59LOJk2fkD78RDnwvDB1D2uITWNkSLtDBRr4HQyuTgRFz88VcAVHSRlA73xw2cdhWwUC5wOy+u3ZuoK1xJstk26eXc1knfXqZ6+UVNkj0OaKrscxSmfRMPoL2j6cZL5P2SSzemnAMj5yxcJ6cHp0dRyiA5FHP94aiHHlkynxszJDV7FFoiqKXJzOGIhpD5DLNyxgijSHyYUtoxhC58vKkMUQaQ+SDO/DGEGkMkcYQuern0RgijSHSGCKNIfLBGCLBRDiDMVLqOrCKa0XB1n0WtkfjrsMtwCGV23Cq98yABquYx5TElOyThyDMLhgwMSsn9lrrjcmWURlR+bItpTQoCHr9daTHfVDqw0GcuFK/BINmotUj7lrOWGSCsT61JsT3LkX4NlF3nCCXHjIgIVBTL3jcIPtQnRQ3DfUcdgkFaPCVCw3cTmWVR8c7Wu/DvXIIXcyaefb8xdpi0YYTa4j56lhUJgd8OMY/jybVajZ1TOSmDkbcajabRSDJ0pRVcdLvRvTbmCmAZixKgP3lXMHUHZCOZmVruOwqbItGHSz4ZFHf5zKJv4cowTJjf+R79thiUBm3fPnZ5Lfm4d9e883ub5d09/DZ4fDkovvxYNTlh8Ghu83f/b0/OZpc8k8TeHb0/fPro9bnv3f40feTwdHZyfDz3wPn6OPh988fjy7f7vWfvv34/urT34eTQ7e5hqv2RhhDtjaamy8ylXCqLtX+FbVCwdEVuIz83ryvi3KS1Dvizx0HzNfzpxKnLmDUtwZV57QdlfONEtG5rN4Fk8U87VeEyqJVynjgks5/dWQSt9wrmBNW0qCW7wWK4Kh092Of9fgVEXNjqsAVHuZg4PmhIAJDZnMQyeFsB1o1py4kV2kR3wHI6aq0VvnJ6HKsr/NfyW18siFOv/o7cf59RoPqWNwS1jr0kpdV1tcSIBGBqOtTPMsB9e02fKXFNIFoSN2xLC0zHDmUo1032TTwemH8l0iPScJ0B5Y3Ym189cxA3dh3i3TkuneiQmIC86KI2tdIJzKw4P53RIcSNtIg76A4SegJoIGuFw5q09lO+aIm56AjmlvKSJ5qkrNweO5nu+CpacsbTqKaeZ14S35JrVP5B6F4pV/7xJluNTc2K+YUqaysYiniVlWKa0nsuT6hisqLQAps0zC7RB9lfn5COgI7kwYvWEixEUoMcswS27fR3HhWb7bqzY2z5sbWRnOr2fyMUgm1ocJeJNpKuT0v9zU2oSvQwxg37Fr8A55C2feg+mLIDg3ydiwrp9EYbFJvOd9SPcelap01YZ3kUmVULVEMOgW85XIQSOJMu9i8XXVSWI5On8+Tl8/o080nz+r2ZrdZ39ygz+rdJz2rvvmCvejRpxsbTzZasIiuJ2CCUzzWvuCB50/ATs9yZ1MjvEeoOym//4dDWWMQvf+7J0d5SwLHqe3hecrZRkCcIJaDAQPIhIdjTLfMLI8AOwLfg6z1HasFQhUX2enjIETvQxcKWvaY76vZdQTb0ylaTjUHVOzEpIO8In0fB1ITiUWT+ApskY7gkJ0a6UQsEv7QeCT8qTHJDrpCOoJRTiG3OqfFojveKGdzPyKGR/pyIMFkgc470SuDQlHKgZMMkxATTPNP6AzaURQBcrR9+IYcnLw7UiKWPvXYnJFmgYKd5bASKHzvTt71UJFKkkkxVvq7dxwPyqmKMk3SxVf1G6eUI4nYc5phZywmOEjW5lO7xiegpALfIQxvAy/IXfUxAM91cDmnHKNCMSQjfETbk0v6Ewu6hbOWiwsl5yNveWaqNeJ4l8y3aMBqcb40CX3KHTHglP2oInbkbIv6muz2ZLYxdkqv1WLxW2PPCfak07iS2JAopCNTWEgpqkMWUpuGVPv82MYX3yUZg9GqrWmaqwJ3imM4Ws3mz8J4keQc3uYr+Aq5q4Jq/zM1mQKtXKriKvwMuojRyTEUT4YypBQqM4tL0JFKOUE5l0TWFVm52Q25O2ay+DFHALwOLEIH0MyUiuYAeFc9oahpuh4t0vYaSgrNFfbBEgN6QVzQI3qB1uwVYaXWorsyH2RYtB73M5MFSDoGmF3dApS1lwvSqtmm9IM0NVJIr8OUHjsyVWvm69imHUUN6dezSuCQgJ6LTH1L4O1Ib5o14C7gsVMbq1kLLw80luhiwLljiUCF7mgKZoc8Ko7swNaPa0pv5EOQ2boOdMJfwGuJESAIdinLliPx5J77WMoT8bvacssC1EA75FEnMREAxyzVUR+X36Wcr9N4Xv7T1IdFv+TMF09omTMpmohmSNdq2KbP7KIcR2VqaCSWVLtaQiiucLeiG6WGvTHfUNLD8OUmsCpSPow5a1nBr9KnIooVZb0queWqprlVCkpXYREW7ZxVlH/JI2mWx8qqSrZPdZH3sgEHhfxCMreQ4BQQqNONS9RLD48+KWW0A/y9WCtukENAI5dXTnllwAVTd7j7VbO2+t5lVFwB3xPUJPsf+d7QA3akxEokQWghTr5rWX012fjzRXGWYhtOwnCj241v2IizD89S8EdxYoKu+qMp1vMhEAvm506x7wj7vwvnPjIK3ZzJZ14TC0RThIRBRRHwKHm+4KtUCJUTz7WJiHid3QaT0IZQC5jHViDXHebe+UHOcQ7na1vkXF2S8zXys1OTwUrda6rfxlbwYGwFOo2B2c5gO0D3LA9iC4KNuqBuOxDamc+G3gWzG0QWNxfASPx7BEsdCFshRPtjJfHT3cND8mg0dicgJz/G2P8GeQdYz+D7j6KaB8z6ymzwQKqP0dhoBAKNYVN4IwUZkp7Ju7ZrCKL9pWqGkS6xDhXQm3LPzgbguLQumYIZ5Rnyz5J08h9piWLx5ntj4jVke2nI9r0z8d68bamKNUm/wlxUgjX2JGNPMvakIntSQZLaWUq/StTDMXfK3Clzp8rvVA62fO5ymLtk7pK5S+V3KSf1T18OSNt1uBXqYbmR38DcL3O/zP16sP5EmaY2V2bX+g/tL1VZSNZpz7gmxe/SObmHf0xxTopGczgn92Sd95TJqoZuOfCQCLR7YcaRnr+iLKwaoY7jXcIre2PA1odallxkk4VQmSxEJ5YWpbm03j4ttj+xbXNO5rbtk9Vi+40R2RiRjRHZGJGNEdkYkY0SYZSI5VAijBHZ3Clzp4wR2dwlc5eW9S4ZI7K5X+Z+GSPyHEZkafPFFh4kQMpVqiNgLFiUNHk3IhoyahbhdoohuTDPnk6EGVZmD0QmWMSECsbDuIR8ZIT9WZuGOvaa5YCOFVZ5rm5+fs3CKd+UBzNmzMZ3aTZWkDBzbdu9tSgbhBiDEGMQYgxCTMFyG4QY4/kxnp8lR4i5PYeRMcYZY4ExFhhjwRRjAWjlWBYstAZZ9Rx/lgr6+5E9HcJCNJpDTRcdAyGmT+CS0aQYypljB1lshykBY0GDnOqXusvkvbaNhn+TGv6NwFiUqHxv2aU8OgK8S4KBgUlqSL9mBd5I83tFPIX1y+gFAyyRsasdkRvSBPM1rxM2cqjFhiDYJY6//CjAVhmOwgkR04FZWw6jPuEzf0c85d1xEHpDBhjpykIIkBSjsI7iX2U8CUS0sDmyHHXrOGAjXwEmS55KziPzxCvQJiWst0KI2Ww2hXMDOH+WWzeIikgVhUcFdk76FbBCgo8nUNvzkPUUR5LC+8+fP6umyitzFbx8PBIoHoWUz5iojInKmKiMicqYqIyJypiojInqAZuockSpt56QoNDwI3U+oAIOh4KzAAOHcqX6yRivjPHKGK9MpLO5U+ZOmUhnc5fMXVqtu3TPnStgDp0zmb87dr7ipZ6GLL4zdr4WoYsna7ZCS8LR4jFP6VZhKwnIeARW1Vat2WyWdIf6IUBKovLRWDwVTqKiLjDKzPDkoZeDTr60rpwbc4VEN7qQB+Hyis0G3Fw2jDIFGAmgMmYS+RtMT4JAUwRVsMdicnGRk7hCuPb5U3jQooDHDc64wRk3OOPGnGdwxlcHZzx75uJZ/BWxhjyCHj/0wLnyX8nZ6tS+kH4iucwlWxGRmp0AADsf0qtDweuQ6KWtrvioMsS6LpAJ+fheO4d1qSLH8htVGcNXEdv3RiNkUxaVF4j7hVKLz0Zo2sYQCeo74KREYVOVsYvk0F24RMALXUvEDrAryxnbkZcN365TrIKKd/H6ln8Hygk9yh1mxyIZsccM/qIuGbvsasQsmBIOWf5m4LNSL53+ahT4KICCCKCQ5OKhrJMWo8u/uUDsPGZ+HRdbnASoyOPGgqbn2+DbVGwEt4F0PXuyEDkyGHeHPAzT7vtYGoIhF+HMh73JTuHX8ZC6aWuKvEZYaD4AlomGlU4Q0nAcdLBUodwS8KViH+lFDb5yOPRTGOahvp9rBU57WBzp74Gho+pIhbFgJbOVsn/BxK7v5Oeuza6yn/CZ+V69iwwYWwiWLfdUnbGCE1Vwd4zL2cioSyOjrrjLubYmaET2U9+NQ8sbsulEOJ5fRGK0tdV/U0xPUeLamqSV2fMkqEk0u1xraTz0VC4qDZa9seNM8ihqOdHZ+BnPdPqrRENd5omL6aX8dagoyNDN+pC6tM9s8gjvrnh3jdDYqUdEfI4+yOPp1DL0QprHd+FnrSysmHwOPQZBAIQrPKFK9gvK35s5h/opSIiQtdjQHJ8OtdZq8rVIKL+tsIaNHOiOE4gIc/iQ3zbqpfEJGZ+Q8Qktk09IKIClXiE35KGDWQC40rnAGXqjep+Fqsp5PdE7DZ+xrdw+yUbF4exY7trrEX1U8qjHKIAvCwVcKOYACCKoWPBY2s37/IK5kbQoHEDaOES8tYt1a0e+Z4+tkMiREwYvqO0KAbOo5YUemtPki7XXyuyBR/JA1ogUxH0gKjUCF1gEkOFNeyz08r53wVQ12i4b0Avujf3GuTu7QynlK4tDpbNCc7Hv6f/4rLe2tfZv6xB764HLIVgXT4PEqWjHaltVSI03eRsZwbRURs+QlxzfoxGD+JSpE5Z4DxoihpgIom0YUJBgTZOXFTuDWx2Trr++xCQJyEE0QB75VKqR9BkCzVJBj+D1ECbDzZTJsNHE/+EuIjC1agtUzealnVtxZ3l2YVryn+2Aoe+HjRxvAkuxJnT1ly9ra0iytEcNyxsAYaipo7YXPSK74pHU9HM6IVnMWxg8/foaD+nV2taLZ5vNZm1tCAe4hVbM7CK16s2X9dbzs43WVnNjq7kx0yIlO7eaFRbJpyFro4gkdhK+9MkTtU6Jpw3wo3ljEYFuB/GSlbZSq1fe6IvG5IQo+HOuG5r4Q13PNcHeNvLih06k3GxR12JOnBsgUguUF1akGAWhz+gQKJwDuU8wuA2uPqJeJKwh5+5aUZztDrUjSf1//+f/RSbCiOZqBMwnQgDACzuT9Fp5tYCHq7m3wVgKR0QFW7VyPJ/jcAADWAq6SlDUO5hcTnTloRuMez1u4b4h5xJSwR3MLuecKQIdiZSwwWP3q+tdusT3xuFdbPHTHMvq2dkxEaITzhURx+5gi5/mQ2/LdGOZuRNZ7m95ajmn772iDgkODPPkFiNjN5JsMZyGY67njJDh15/7gmT8XHEWpXs64nUcUIjseuMTRm1NBciI9Uoob6Qk6fIU+hJx/oK5Ydv1gJxKCXnd31j/0R1bX1nYhkF+rmPibX/sR/w7V+j3N1DUxxHr+ogicbefFPhR5NuHthAFErUlJ2OHZaV+aB0QHJroQxMfmguR3iUnG0TMu0Zw0WI+pUVK/TFm4N4CAdtnFuOAKojOadDEJC/BF5VUZ9FWp3LoVtm59Dfa+pB6mv0cQWJT3hSPqInptfxu8edDT6tX9zfqf499Htjcwq2pCplHbbKrn6JIGLgRg9OUFZANUzaIKZ2ipqVO5Uq7LC9EymaRn7yJoRnHh8SijoMJybHFNz/XUtiC4ExkbM+xVbDE4FEWRv7WS+3iAfLoGfZScyBFCpUy/bVazdZTzf60dun5X5kfNOiINwQTc722JCZtFA/aPc+Xi4pHUVPMIplVuLcba5qmBiFs2tqrtNTKV+his1Ba+PPPSsdf9loYZyuZVDk70xjWyQbZEUtZxKU+ig0BQnsaej7tM/LR5wjnmvMoxcuuZc7yNxpim4NGlsGUMkAwEi2WA65/AxYSrP/A/04rZuZv5LFE0VoRgpxSZpVZY6KC2YhZQNHt6qwSjVVp9gjudu+C2ww7Hdq5/hMMYmMO8EscukEOe8T1xDMwi4khbCyLpr0dWa/2clxFGdkbVd7K57tqwRfFCtV4SUZomPxcTF4e3AWw+eqELgOaUkKFc+d3z+jwnVPbmeC9bUm6SomVcN05IggtSba+CVr1MYo4SLp3ZyY7RTjg0zSbjCejiHhL3wPS2HwscHSqT12OiMxPI+NnSLOl2U24uyWrwM//R0ASnA1H4RhA7NMJWOQFZTcEeRUJstG69FMVGK3LaF33i9svsdalkDvH+ex0NK7KTkX2aHV1SLQPJMdEpo+pKImZy+hLafQ72Uja/VSR5pjNZhmrYOcWdUmPOxASJEYIwOD4lU3IyGc9fiVyAMDfctUggAIpZoUJm7YtAgYAWzAKo0vyeaRbkGgDP4tvgZAAh46w+kSil0DJ+BvFJMOvl5JfJ3Jt0xNbEDfGA5TjV0vIc3DsbJ9fsOStKEt5mLJaMCxydu6qDKQ0GxQzq5x+JO/90mqTufO7Z/zlzrmIwCudbr0Lxt1ob4L1xF+F7qpEqzpaCQv8U6eJ8YoC0igZ0T53MQBbBaYJX5PQ5xLvE0FH3kgkZZLA85GQA7sQ/ERmsi8MOKDslA2/FVHwEe1HpPvbmPmTzNcfw2mRwdbAtuQaSOTtNNGKI6pVCNRWC4kGH4L83Eq8m/nt6e9PB6mPGM6BVXz7RhMzDeTrZdhRzmQwTax8JgeAB4c2UUih607yZhBFgkUTWJPcUYXwJkDwomdwwTB+3Bv7FsOkgmhqNveZJRe8ZHqnmNinta0yORpYeo4M/gXDwgxmC+zLXoHb1kCH38DjX7/YrIscjRn00Lir0pLKdMhD1xapBADyWqJIQoiDm8iMydcnkWqPJXa1hvuaUoZnYtnDb21BivUt0eKr29ztedNXXuRMTc0c4S6xxr6PEUfibqZuJGL893Oi/3e1bpLM5PdWxCK7G2mykO2MuRjtgm/JTScpGWakDlT5MCOp/qeHSQlNKk1Nn2JNkWWNQurv/qKwwXPllgMhQxBN5lmIqBLfkRsIpREG0yL5BZ8GkU4s/0Q9ONaQT3ENgozmrH5fpNos7E2NNLmb4qKsFcApJQUVwSCKVWRdWClUjkF5zFBk3Th9Z7LHrSlKNgPdOYpoqkQs9T4/Y75cakVMrDAPCLVCfsHyaH4elRcGiWl8FWPVFbyO9roBdW1HJzNF+TWS9ScVuPwZiWOQofiYS9/LfHFOMlPeoFKuqcy0RPPqNRBO87IkszfAiCQLEknmET1KcJcVpEAi+iCGi8LqBMq0foPMrMA8L5S8CPgGrXIwO5+Jc6oHM7tEnt0bn2hO0PLR2An5yGEpVRQmBdc3MV9IGEN4mvsnH+RLBHfE+iU7v46FY/2H/ue0cKSkNBG56wvij0qlCRV5pJuiiyweS2DMSK3SzYkvhhvdG270MDWopaKQkkQVxeYk6Rk0yQ/GKaVkWkl3Q8lmoGR7LKTcCQjtYvxVnlZpqNjdU7E8qXU/q/8nRVhD1m6UrJWXNk1SNdEop5JpBdKmSpca0mZsTA/YxmRMRfeQrRlTkeHD1+XDMsQkTlhABihupk57pUscYljFshWYa7AsXJtdhT61Qs8P1n9E/y61y4jfMYhgX3XIs8uIMAO9SYFRxnEkAh+RE8jkgEUTi7AzrgUrVFiN4sbLWawhT4ngInV5gmkLVTz1/cxKVJ1ztmfxZB1n2AZcxhFm7CdnXC2gH3dPpqskoB8XFnGGx7ceH9+2OE8nSYyYXOL2XsJ0ZI/VzcxsH+h4YmILImapK1YCyUad0YCWEKP0nK9h5+izsIQ4gJ1jGmU4YaHP2YXM/ymiDSofCCDHNaA0QytWjFbsltB+lOJv65pKgXp+CiIkzczxNISlImEpS8UQ0k8JYZGGhum0ZeRQay6xA2vsAD+LcyOm5oEbKnNLVCZhJUkLmgFMpx5gQXlfHAAEBPR6mdTb69GbiikP1WCGE1+RDX7VcMc3my+f/ayJuzbDC9iVglqtMH5q1WPbR6Zf8jglogRVnHD84rwCN3puBvTvTZnes83yt8II0erkvlArR7PI1BAhBssTd1tycBEby5nfh5St4TY5lZHNb4KFTs9D6Tm0D1Wy1uloVJxzolq1IeKzjU0zOSfy1zz8M6CqB3IIbEeS1bcaRDkyhb07nGBGCZrfVL16wNt/RWAixGY97nIRBAQsDoxPEiPghnivzGG8lPjN+rdcmy1PGTtlhZ4tfQHW+g6R8QsR2ReOt34T771epkJ0ZbZHIxyuGOW9OPE+wnLPZuB/KSHkGg7t4kil+p59YccvhpF979JxOPB8KNl306/Pgeo88Pwut23m3vS7cxEP5ilRPvu786phnHkeGUJSttz5xSHj5s7hDhBcc+axKMhT4F1FXoCIIsvMjOhvzf5v9Y5jSOKT6C7/iPPjvGHDisg/YlQo5qc+q+FjKsdPOZ5D3e2EZPBjrTsOuBuBaIO/KmT+yOcBU7/0fBb9e+R7kd8qX9TosrBU0lATk6x9zjyQaNuEVxLEh7w0EPFzYd4HsEMJCwSiArNJh9tYSG0sSpmhlAHuEzj+UHDLof2aLH/ieP2aKEsIkO0xvLW6JvdfYriNsIHp7m99quRR63//5/97tkkcFsLK12SWWVAjg8lowNygJkC0beYHluezILfGzBTFj9o2SorUOdbmihAuObpoviqXB5U+Giknu5Gvri1fVZejjBhlxCgjRq22GLVosUmmoqyi4DQ9iyZhn1n/QUejaYky0faKBhlxS8Zj5IlbWmIMMGi0wTgOAiviqPhLJFGRAQ9Cz5/E1pvN5kuIvoLbI2JlSBBysKizHvOZa6lAPBj8glNCY4Ggy0XBr/sujGnQT7iVpR+TEJcO92LRF+sHogFtNML4Nk0Wqfo1cw0+lzUKhCXNNWaEpZsXlsRN3h6NTkQ/IzgZwWmR784RnABRzOGWqHwFpIMHBOt/AbaQYgcictKIdUasmyrWAQOVMs4qinZVAcWlOIZykc6SBQw4AvdI6asWCWQZEew/CeKSy6gVWfm3C4WpbM9lxQDh0ZnpszAjKEJsXp6UqCUd0tHoHwGBL8447Br4NQ/bV/dwhT1MrzTCnrGMGQFvJQU8I0LdRwcjsKmVdTKWhQNHGycCnjKijIwGzpNmtDxjdDG+c50J6cA70bk4HGMCoBFVVlBUMT7PjM+zaqiquBW2Oi1GijNSnJHijBRnpLg7MoTJQO5VlNtmjEGPfJzrmulobWpgOhiw9A5pQ1Y6cHy6VSsOFatD7Hk29BwyhE73fpfFemRzRhwPUCcmDXIK5XvCRMTa/hntdyBWrXPYq7/1XFY/AoicDtbTufC4TWzv0nU8Cr5QMnaFoc/WX2sk0dWSROPPSWy5+qoBozbL5iUe++yCe+PAmcRvhcOD4mHnn53GWvG0q/Sdy7S3P+VGwMDie3AMeGd2kNPQ99w+kWkeIe1HVaMU1L5+x0Z0ArehUVL3Aan7YhkHbPyeRisEB3mSx8q1ZmRARWUiaZ+372w9Fi5yVRDrcyZSJsxGYDuolkyrPRiLsQuT5Jbnk3JOFRjR3bmExGX5rFy5T78ss8t8y/NpeYcQaCH44hgJ2XDk+dTnzoSM3Qj7ZwW/dUFis05KjQ10mizdSEqp5fbQmYVqJaZOl6hVyzb8kpCn95WoiwJAz/eGBGs3ETzeV2EWFEB2gGJj2If2KXeDENncyPcuONSUlL0b5JgGgfqL0DD0eXeMnQP5nlj+fQUAaWMJv2B5zLdEcUppVgOJR16AAKQ2H1zidNjl/bE3Bhe15xPHu6w7NGSuNSHcrctIlVj6r2FNTIlYmI5XxLqWEifAtUced0MjoK+qgA5H83c2Ka9HBilIeIahWmroRXrfLPMuG6N4eiH1+wxwUKfOcVfenagHvugRFJN6N2LuAaMhAIFDndjHr0T+FNbAg+vjhlCyyvccB6CRRf1DGZhbeKhu5nVz6SjIhxNZXmAavQHbUvQKFWFZbGc9ApYFtMInXMI8yqN2k/MyBthi+RpPCaD6zC1nX2MzckXjuOmNWUMLJnPzwuzc01uQ/BkPPa/4qf2gZJkFi6SRXLa0Ymk0wwo++vI84IRk2cbGxeIlFpz97fTd28VIlzUyogFwIArNcdwE5O6jdwcn+8f1YEBHzH5MfCrBqqmbkT3jvBdEdpaliJA/EewP74BHr/fPyAX1OTXC4aoJh7cWR6AOdxlj0FShr2zCbNKdYOxtg3wQStCQTiDqF7x7eLJRN3oljIlSRpP1sQIyHoHk2Wo2wfTocwaxCEzA7NtsBEWee6TVrMH/NZtNqWaJEOQnG+T3HW21ok+K0IZ/FEYhVOQGvwWeix+FKq4SzDOL8zubqDALvPmaLI2Eg0cbfZOp42p6lYHAVktIRb/BkDo9zx9qaroRXY3oakRXI7qugOiKf5XJrdEnzG5QFWNXA85T80gh56mfc6HzVDiCSMD2fJv5gvN/ZRNpKu1YYz/w/I4wxXa0SugYWIA1yHuef0l9+xWhBEoBENGF8KhqBvBJhwaiZLkRU1dLTI0/x+FDHpZbB4/olaxvH3rydSIudaPZfFxm55vaMUwWhUcJiw+Bmmw0BZKq+CuBKyxOYvmUj2lf1hZSBxePOgXTPMY6RJpXaWDETKPMZX6Ur2A2cSQEI95bE0N7OzG0eJmOZakgjQ5WHkDIyYfQ5bqxuPrrTWTuikjXJjJ3NSNz8eKb4IIFiMKzYTlmYgMkmKP8vQDNER9nYINA1gHHIXVgCSeiyljQIB2gvZiMRZ1LOgHw6B7zsdALsG+0rCJTFzaqV8RhfWpF16gecJvpYQK873pQh4O8GwnzDukMWUhtGtIO5M6jCS0MqTUAM3Eo5K75qkwaofgh2G6l2bMdncTsB32IDqkqTYgENog/CO2XPCBer4cGN3zAw38A8jnpjkNVSoYMIXxYFUNSITNH4wABHyjeIAgwjyYT5AT8Zqo3JGabnnx0TwQt8Px6j1rCUBw1a5DDMC4QSHs9Zsmg+9jOOcUG+7S1UVsD5TRZ5bOkkKhLhDU2XsDuBN07gVbIQ4BmIOGQa97JbJi+RJGIV1v7mmdzfu/yb2NG4sqsUcBu5K8CMFqZTvpeA6fVLL4wqdO937FAZTCrbRqESEGvci3idaR1RLUhNAg8i6NSgs40NdUG6cBqd4gsbzMchRMijjixHEb9IK68qwZ7RTzJI0nAhtQNuQWF3UZMVH6EoVUcFHl0/P5MDcTDGjnePtv9FXQtuQ081JXG6G4V+Q2oO3nXQ6qb2ahsIGT0iwgEW/v5RdT10Id8knfcoqIsKdksCm0Rh0oZjMTeBhYT0WCdkc89kGU6wuvS434Qihur+pJL7gYNsq0WHNUoMsQItegQzXJe50Olh1okqMWIUbKRuiOfWfiBMAoNuRA3BLiLqH1EePgqImeCqUp8P3EA4YwjqxYfhiWxkGOrz/xHEDPv3EugRK84hjV6JPe1tobE+gtQMDVjRd2voMQPdx0WBPWQ+T4FB0ZdFeKK5Sf4wHHI7LYn6Rxc/XhieXaQEWj2seCBADihJ767QbYdR8kbwQA4cuQfxjV4JD+nRsTXqCRgJPvotxN3YR139rEErqbWAM4Dpw6oZXKJgxCOiSQ5rWa+V25hjrhZfGJf2SR2CGqcMbGy6rrFVL4yADPa+Q0C861bV0yKsjGEGEPIyhtCHmCO8nTTx7xozOLn9R8YzvaVTWaCZ85YUCQgYK4FJQJoFmLiiPlDCicL0o23eyHzBc4uyCTAL2gf7C01YnMfhPpY/wiU+yaKIHiFsokd5TVQJNyeL4KKZGtUOanjML8OcUQOF6nJwOIbZDeDOmjMJatkLknmQbS/xkkG+btDA1YPmBvwkF8Iw51UiSdwftL6sBaGVXmP5n7D/JkDBqb6DmCqYeUNTrWRLo10aaTL+ytdzgMI3ZOpczD4f0oJD/hcrpSXU9sM3VmuRxzP7TMfwls854IRHjYWARidEV0V0E4huA7ybAg/S0GHSEjoyL5a0wyDtcj4XMuCTBsZ08iYqydjGnRsY7U0cqWRK41cacK3FixlqgxcxJgrFt/weVaAO6Z+yAG9kAhxO1+a20bTH1ghR6K9ah16xOH9QXjJ4P9LeBgU1LZIR7r4OjXwZ0fDwZ9R9JUQ8PLc3QKWW4wlQghcqCMi4RW1/F2QtoaeDYEZNgYrhODDlh3hoYo/sBvxi7fItEAI1bKRNzsyhOgbjJVQc1LYbYkwHHIa+mMrHPtUlXDBSHq9jVgAlIE7gJRBjt+fNci2VvEFsjUnRBTRY66tC2C43vKmg2g/xp2UbzKishGVl0lUNoF5JjBv7sA8E/92M/Fviy0egItstFyj5Rot12i5Rss13pNr6LVCoa1a/ymj2L4vUWdP2MihlhTcQKCVDhfNPyECnlOaJLJ2ZtdQsIrUSix/C0YE0mU9gKG49DkiGhJAfQTZXRedOdOjvqG6euSK8Rl8Oqb6owqnhGxUcztf2aSzGMXwlZyLFenxqlJn3RsZtdGojUZtNGrj/VAbTT7XA9NnTT5XFFRi8rlMPtey5HMZm5GxGRmbkbEZGZuRsRndoM1o7sqT6Xyu9cjKslapECV2jPvkAj6mLDecFZekRJ0Yo14HHKBNJ6ihiBwwQG2+hOgHFE0bZB/kCmkKwphaZde6ANsPyisgfsRBuEGIldGj0GIxrVekI1avo2anhoP3gsxYd9gFc4jNez3I/RqNBFjORgwoDelpET83NiRjQ1oCG5IBylw6oMwkMTSy/+3I/rtqwQ1aplEqjFLxsJSK6PKbkOuKakZDl+anYGcWqxuQqHdJJ4VKxHfme/XQHwdhXQ1Q77Ownv29DoRS5QymU/A+M98jZ9A8EmmTzTNqhs8ZpAXGjQjtQj0+PZQ5O+occn2xxFd2E7Tvl0vYjt01VSWO8lVJSDQLub45k1b/le9X5O3PP+eeLelR7oz9hRcXnmpQzvm6iFenpKBrDKOJFGnKK+oWgF4jK3QJvwU44FC/kV17YyfHF1hbY1d0OHJYTFGQZOEfskCyLlKVr5iaeSjqu895KEJhjOX2HGNYvbZ25X7iBKHsmd8WF3LmAZP9f/6MVggcbNOKRycEt9qUp3KRF1lvOnt3ii1oWlvJ6rRfNGaXx0b6zGU+hNLUo+IyJVwlXuWG4gNzwzDnMQqh0Ofwijx85uwSFaA1E5rHTnrSxazcyVkjymrxhsJVWTa2MH2ihiMYjmA4wmI4wh3S/+lYdHIQcF204TQWF6HK7mZdIwd16tqJv2Gw+pCORtztB3VgRNWbZ30dWlMRuqX9je4IrWvyRovujlN9iOVgOvUnVdnObAt0K7xIvaNteY7DEB6m/ryMI835DYZN3TibqmTLzT8CUe88njdTgFrO+HQ0qguCtbJM5LX4lBmI2zLqH414J65v1BIudPAPscs2OJXHlRiStmJBXfSui97IeUr5CVAT6EBEh3wPujBtYcSebAWxfhNv7CeGWnXWkVqLW+EV+uvbiZ2P2MgsnCP9CZJDzPcpaVZxVccIijg22HCP6yo5dAQ6AbPhHMzJB7T+P2tS5rXbdKobM5drUbvtuc6kHfIhC0I6HOEdpTZAh0QOAe6qkzrnrFMD/Kytjd3rrkR6BBhUxMPe4FqsLPMtJhlzskoR6x6HmU/ln+gXEm9uyDdXMeXlZS5WY4Uyki0no3Emdij7rBwzvI2kr4VTs9WgNKlbn3yafWPms2YM8F9xkWX6RxihxQgtRmgxQsuqCy3TY+cjvR9IVDsIBu2AhSEaO6oYolkoiFs9CAb1qGdJKMvp6a9Ea1eg6EMrzIrdxr1GT+Wh2/NpILH3WDSI8mIulceyvlHVAlCyPLfCSgPu9h0Wsc36szLGWWWyxiS8BPzxNtjZaNx1uNWW2fiz+iHjzkilmd2ey0E6HnO7/tRwrVKuBff0VNHcxduhRZGpBk/Q50YuW5gKeDtFuRabPI3lSPm+KteRze8Pz7kNRXthtz91i7RHsyqlK8NGK87XcFLDSQ0nNZx0Nk56HZVv3fcgj7gNpwiJ/LSwVdEe56ZSGrCvzo1PsE2a2qmAR9k8pQeKLnDv021FTq9Y4VBmRQ+8INTSScOJyJO1PNeF2BfMLfW9cV+ALGlRrjD4se9dTZaNg0/jeNPXdPm43gxzNpzPcD7D+Qznm43zKWYEHKUC+4OL1vd8PlvIbdxLxNRqo2SCnBLPCqJi4zZLwoNmi12Kp39nca0vpkYn5UzScJgHG7iq3cqVpcYqclX7lqUMTU1QwGvHplpw2Xp4fivRbL29oNYFD7OkW1ujVMMCOl7QYckthVVofFD4bXdE8afR++kTNtT/4VJ//TavLP1PfMUNku8k6bt+mnOCImdTnbXHU9Kdky0LUp5ddlnQZ9nocMJjc2MJytJohstcly9dq+pkEataRFvvwtw0PcN66mwNI1gCQ1OXI0y7lm404yenBoBwPo08ZEHrRA60MAZvJ87FIzDX1MGIowP8xcjn6qvX6vC/nf3Xh2/J7v7J2eHB4e722T7+en7uHh0e7g33dne3vd3+9uXhznb/8P3vZ++2P7/92/rzw+eTvze9P8Lm6a+B07JaF0eXe398+u137/Ph4MJ6u/3H/pudP7Yv35/tvzna/vp6u/V+f2dwtPvhw9HVwd/b73f6bz/sbPeP9j68HXT5zmtreDD+tOF8/7Tx4mr/+/aJeG4d7X59O+i+dobdJ7+N6cf9q4Oz7TPxzDva2/+w+elj67L7+n3/9OPTv9/8vd0/uGxOjv7evzr6+/Dq7d/vn77ds+nr7ReTo7PDydHZ9uTd2f7G27Ovzbct75bntru7fXqYXqOdnT+29/r9/eNtWOc/vN1+f39n++jEendy2f/t4My2Xq9vvP798F/WwSf+buft3u9/735+/+f+u4s/P37a3Nj5+uvLyyt+dPbi2cvdd/9i7nbr8uno0P/Tu3z2dfeoFfwRjH79lX4Y/vbe8cL9o9+uJt6bg972+ovfw9b+7wcTr/vu7/HnYOP0cvJh8ttGcBpe/DF+/8e+F7x/83n37evP+9+8X5/2n30fHB1f0avh889vfD/Y+/xySN++/vDNe77/8c3HX/3PT5//sf70KDzzu1d/vPkX+/Pv98PfXv7+5Ovpv56M9y+P7G8nzz4/2XHG71v8grqjY6u1+3bj9duB/a65Pjj9tPnp6+t9d/wm+PbbZM9+Yh3yndbR1Xh357fNz/TbO3vjgn9ofbSOn3jvn9hXH46Hm0cfJ71Ph4599HGntXlAB6fW1ZvBR/vEPXr56fM6f3l4YL2ZjP4Mxt+f7/3t/3YcHr/f3b7c396mb4dHr/+4/PWPT3sfTprvdnY+7R8cP/3t+5v39PLtwb+sJ9t/Bp/O9j/+Onj+fcP6frTzAs6HfXj5x6ejHbpd2nZ7E9vuXe7vrF/+sQ93Zufv7VM4E7+eHO1s917s7+5tv97+49f17f7+ztF28/Xu6bfXp4fdJ3t/7O/sXr7f3t483Nn+Y8f61w57/nZvMNpvvpw8H7w5/vz65NhpWae/71xunhw2/zy8eOY73dOzg+DpPuuOzl7/Pbhavxy8vbrc/zzYefnr5+etVusdbX1yzl5cfT18uRcMdp6/GP69/evu7zvbvz1/NvR+fxF+fd2k3+xPo982P1u/nX3Y2XnuvHxxctG3nn/vnXH+/CMbnk2eb9hsp3vK+H74J70Ybu4fNIcf//518MfTt1cjd9Rs7nxzn/ZbVy92J2d7k1F/OO67bPSvq9f/4gff3w7P7OD784+HL8/Wn3/dO/rz287zo/WD4487704mpy9fvPvt29u94HL3zcGL7uHnT5fvd/bZv7onvx54Q+90cPSd7j4JL/jw+cfdbuuZ6+19PT07cnq/v9scuRe/D0bWB/u0f2n54+2zD88n//r4rzcXw+8b787WX4/55m+Db8w7Y5fBlWsP9vb2z89dJG37b/fyyF2eZf82vAfsasR9FrQFg17AO37W1nrc7SMqnZAEijnH6a/bG0+fEa09JOEg1No8DGX/5Vbr5dbmy63t7a29va29F1ut/a3d1tZGc2tjG/7c2NjaOdjafrp18GLrYHertb118Hyr1dx6ebC1+3zr6c7Ws5db2ztbza0nra2Xra0XO1vPWls7m9CptZtZvZyshHkxSsB9IjNlxkEOu83IGsp4dfbmlAB2rm8xbEswkwlLlRQtIfnkjVVxtYCFel0Tm/vMCp1Jg5x5RJUTYYkX1LAWN2xRZD9TZUdCUTsHnQxEVGzraJPoFGxkLBBll3e2Mie4gkEwZn7b8/slqwjT9/w+dfl3VbqKhgS72tc4fuJf5NC1GlUPi5itTy/LL4qsxSeaC9Txa92Ud7/ok629+WWXOrzn+S6ntdOzX06pSw586lo8sLza7i/vTyt+j8/6fE5Kgh21qj0zDoDdbsX9CO9wPGpDWZ2FEU1jRVmMFaU6WJA+4voP7S9oJW6jw4TqU80UI9pXMcXsYcuqphjZmhLlPh1Sl/aZXWSWQfo+hF9tRq2QXyiKp1OKqFoVs/uMPOIutmSPValO/Big47zE3p5ctJuy9QjeqFcWWEozv9imVbHtVJytse0Y246x7RjbjrHtGNuOse0Y246x7RjbjrHtGNuOse0Y286t23akQeZnbbagxfzf6zYLKXdKcTb06xc3z8I5UCI075kDZYwBJbmShfYIufrLZkWZZcrGlGJMKcaUYkwpxpRiTCnGlGJMKcaUYkwpxpRiTCnGlGJMKbduSkGouGvGyKyr4JK1Kig3CZOM6lklWGZbhbDQqgEzOxzqz5TbZEjoReEvxj6Ttc9sZAmt2ohVM9LMPG9jqTGWGmOpMZYaY6kxlhpjqTGWGmOpMZYaY6kxlhpjqTGWmlu31ERGlmuba+JsoNkNNnHfavlNdGajzXu3W8Vsk8hbMoabrOGmlZfrE23HalluZp+4Md0Y040x3RjTjTHdGNONMd0Y040x3RjTjTHdGNONMd0Y080d5CvNZLzRSddaBWR2NRwWEM7+Xk8OWJLmpMoHpTsU1BXGiz72feZOH2U5MIKrZiBN+5pbsY9E5dXlAokZlJlJKk/bWEfuxDqSnMzpiFm8N9GKdomqPI3M2upFxMuWZeyigNMWf7d91ms3nz6ltPfkZetFt7fxsveiZTVf2k9ebtIXzzZbLzaQO92GRG+KQRUyK0W+b5JR6VSgUulgGlqDakwHm87Gdo6hy+yMR1Z6fXS8fbb76+PYQxCMu3E9C5BAo+KvwdgaEBqQDnVDfsH9cdCpkU7oBG2bWf5kFMKfyJt5OGk7Xh/+7jqe9bU9on2Gf/neZcD8Ng88B6cFP/b4CEfqevakHYDawl3sq2sWNeL5pDOkV+0wdNoBs4IOlkT2xiHB6yBqKUZydJJUC6LRIGegCDHXHnmgiPosHPtuAEVQ8KAS3iPUncRfrC2EQ62vARGUZJmZ8WIKLM/HXLVCm5LEVkXwNyKCERGMiGBEhIcnIjCbCxlhXFEtFRs7VURoJGSEbFn3mYSE1dVNDTs07NCwQ8MODTtcDXYo9mlmw+66NQ5Cb9hOBbTMa+vVAa0q23t1L831bL6FIy0Xb10JLiYORmJHU+z4DlhZPiEWU03sfmSJgFqtO5/e1Y9/P5RWDOEh5AGx2chn0Np+hY7bpEOWu0HIqK1xk8rhZSWeVXQXu9RJThZ7lnslR0y8xWYjx5sMYbUquB3n8xMzF0awixc84sIeEW0JzdsEOg4HHhBc3IWA98E+FfnGQ5/2etyqwq6BMSQ/qii2IH++sPLv3x/u5fqFD/dEFO8RxAskt8Xz2RRnsd3qPnm2aT2tt560WvXNZ89YnbZebtZ7TfZy8wlrPn/5sreWP+EkZ02/ArYJnqyh0gLsc0FBALG8lz7WQ+6+YW4/HKxttWqLkgbTL7nGsMXymS4/pE/L7YiVKERGE5Ei5U/gX4rGFJ1lXdZRF6+qXFMkd2hvrX5IPFwV6qxJaSk79VuXn1LfMafY1MiysgVgUdgumO+DkLv4ljYfVapfbruQvRB1q/ORLGOe86C0hLkio3tvT4nWjxweX2wSats+CwIyotwvKHCeM1S261KWOp+l0Pl8K3ZXVdAxh6K0Dvo1v8fYDx5skfQsvWrD2VjdeukzEEBkMHTE6/hGwT5gtF3HG9s9h/oJC+8pzJPhuG88cSsC8tHnyDa0dieM2slfRKObMwfk84gpJdynszLWh7VqW9z222LBZjUBiBHqMEJd8Zykvi/fRURLsnu4d6KIEw1ANYDoUk8E3Mqhy9V/+DiQ5xMDUsfxUF6IxsrKGyvIxJKfKZbtFizYkR0+vb1CYqmSMlc4fcOS7sSkfV0uUnIyVpeTJBWRHD5xY0Sf913P18walTlBHsG9Nh+AdpVoPzYURCD9a6nOolokb8IBgzgsOPXppkupfqCQHudY48WSL/02Zj7crrnfAoPB+Hna91QVWZtUjzsh89PTSi07tkGyI+K5mC1XvTshngtZIGQItTc7aDHdwjSYjmQ+5+4JGzEaYvdoT4DrAuGekOHYCTnkUIiZBK+g4YRQDDAbdjm8DKLQzl3H63OLOmT77R55RAVbx2qhAQ150JsQdsH8iRwHXtCN5/u4ce6eu6fj0cjzgenjRCEsDTNVuE+GEOIHRscuG9AL7o39rXOXkH+SDixUh/zv//w/YtGA1bkbMDfgUHMUAvmEGU50J5gDIwUO6NaQQ3BbDFDW/nCPPALL4+Mafi6sqQq+s2kwYIEaDHZeDMeuqBXmDAUtGuR0PGJ+wGzMZGLEYX1qTVR33GgYkGh7cjlgLul64QBXPxgDY2V2gxzBIneZ2GphF72gDrfxRSLpKZodsIs2XjF9jmDM7jM/OVd3POwyH0ZEHkN4/Am4W/vUGkCsoT8R26w6R5MYMb8ubPQjGoK1PCBd5niXW/hUPBmKuZ+7sp/YzhruSU2uhgh81Gb+SjZbx52jFmRtYdgifmvt3JWryFE4CX1uRYKkWppoI+T61PCsJZYnmholrufWXdaneKrkYjUS5KGIK1N38q6HBC5pF4YrPscvX9Im7J8iu9Hx7Ij5BOEELdpgHdRJScCobw3KScnurFcItkYbokE+Dph77iZIA9AduPOdmji92ml5pBGNx7krGn9n9CGebzO/3Z1Mo4pwvkKPBJ4f5hNHMVviDXkYMrtGhHAS4PXClzCbdCfnbif2z4M7idDAEk4c0Yo84g3WINgIQ23hx8fI8rrU+npJfTvAJRnRkAt6j9df0jpxALPkDOdNndGAdlkIi+RMgKBnqJc+uahfdxLPB3wOr4jNehS/LvRwx+QXjNGeTDoiKxLikeHaBCxUw8fejeTwDg3C+tCzgZXa13xHmiqpd5SRoJLDEomv4sQk4isS7hpxUcWbQSaNz1g01fJDdgoTjdo2yDbS5EDRGkHjRJYod0lHndzOK0HM4x/OXR6og0h4iMxXG0gubHKzsTN3++rSpdZXjab3V17TeoAONW5tEaAe3OKhMyHWwPMgBj514oH66qegYJcfueySBSHpcT8IHysafe5mCKuaDMgYqvcrxetzP/XcVd8K/l07vXj614LVIZ5S2R18rE4fDSxx7KKO6gl8nXgUf2e1g0cDSx4WOFdzWbkFlborA/aTWQzYyakaQ8CDtU0LvXBl7Qdi+jdn9lVq8xQFvzYdRE0o7oJEplX3hOa+i03SlzUr+GGzgFDisst06yVS1xcY0lxOcRLLM7uPRuv9c/7rhP3q3IXQ+J81uegzj4Ldrgc6IEwliVssRSsc9EvVsO7803gX8HBt0EyQXolVLmN3U2Zt+N0SYMPdRgj1YmnCvBA6wqx4LZJy98TExKMvsxgiLlNlT8P6D0FH7Z+CSGA15enSi2hYKr3sYZOp0otoFiRBYcslFznjm0RwTfkXlgDDNYcj56/wrXBkNhyFk4p4raWTNAz4ThhwabCuIbZViW316vOCbKZ+qFJvHm9LUaF56bXNwcc2FLRiefmitb4VMor7MFtt+anzXQhFzUliMUT2mloOeirmyAGTYXh6CoFLh2CzhneqZAL4Q75QSvrymov+eKaMomUULaNoLYj3V4bHEqw/g42VUZgyUFiKh6dKV44gDTEA157Pht4FQwgoOLIihY7GwLi2kQjuwv5McYeubzMW25vvwguUZ13GIJCJNyaX1EXXrOiocbTr+obwHSInrZqxOPcsL6VIVT5TI0wZYcoIU0aYMsLUzQpTVYHEhCyVRRHLCFNZzLBc67NoFpQLTeT0Kx8FMVAncggZ1dYjUKaAu5YztkWkmAjGngACe4NsQ/wpQWup3u2SOw7xLph/CXkLAvnzigfR6EZOM3ECcxDJPDd/Zf9+/o1ZSpltylSN0GaENiO0GaHNCG03K7RVh7tLhRqsR8dyPreZ6D7NaaZaFSU6RnkJxn9WmlwJ8PflqRTHtK/nnI1oH8ARmK2ycnLj7mUuFg6GaQOIeDXkLh/CbWwlpsD89vRpvE2lnADYPfSq+vqnzdrakF7J9zebzeR05vYoitncmiCF+Ro5eQGzOhaT0zaBGreXGVBRjErlMw28S5GPGnohdaKMuCh1rksh/8ZzwVTsE5FSGKeo6tCH4irrc2+hp6OfY4yG1yagQKEZ5g5yV6MECilEowjlL1M3vviFMcFRn6oufNUXbTRBRIHVapcsas6aRhw1SiQWlTdmWdKNZjN+/Ugd4RLYSjGFBJllUxay2VTKnxTQiyv4xVe+zG+wwoG7SBfhqgtnxvxOkDQW6c+kZqIlYqkMM5YOuTJCZkLIbChRbTHoGeui/iGe1+sk49TBn1q3gosKWTnC97p7+qEgPSc/OwcSZcVkwfJHoT+ALDBAyUXYBqZS2UknZFfhuhVciKRO/GvkUO52MP1S1ktlVxZjNtkgRztijOjDIbty5HtwkJhNaDBxrYHvud44gHKq72XN1IhZxP0O98ClOPIcRyDIRji5q5hWJCAxqB+uIwCnTUM6i8QCO5Ilo7DOaufAjgykIGknjoEeZt/GHOjbCJe2y104lGlygtO8bmKPOtC3A3QdXLSjIzeLKbDq5I34ugwGwNuQF+SVvtYBxEGub32LB1R2sCzhQCATrxcT3HKsa7GEbenMUinr+q+wIZLQA1Y5ntLsq7fJYDykbh3WDwVZUUNOninwa4UJ7gHXBwBrYK3JyGcBiPqYy59sJ9gDMJuO6NLJ+54MOnSRhHqGPAmeKWSaeJ2mzmVAoQgeLBxoIPE5dyaV5lSEJQ9zkp+ZmVMV+Hht3+JfsPIgyE5i1ZBKiZnjhhoz6I1IqHNDv1WwjaIIWkVkVfCmVeyhCvov6pQBgMu0qARgrbeuBngc9VgFfLi5odiij7xTODY5iyWFZFOzmwWWTfWpDM3GATgZ7bRiYCXOcATG0cFn4DjC3+o8Xg/vTLw+A3pGcjHPEOssnugrfU3zAc9e5XweUGrZMCAduBJCV0Bxq/MKO3v48ThEVAi2s9lsdm4e2awAxwyZnFKSQubvTA6DPWVZ/6GRIOTaarN0uiPtMn+txYuBBAEZoBr0LR2ybdcuGHsvPSy5HHgBE3BnUjMLyDnIR/b5mv5OaLEFP8M6Zd5/R0htiZslAM8UpTh3lxOeTSOYaYg2lJQQdM3rnbvKlMoDMnYlpBUImPODq+XRoVUGWFsEStoigNHwwob0KwsI6/WYFeZheFEn8MC+BPZk+xXhIaKiCfnKFuTqkgfqFJfAnYlX8At27kaN8rDPEluLOGU5OGck9M7dqThnia3JAIktEcRYUC6I3RXe2NNpeGMV521sNA8XfCySA1ZWD82qUvel4oUupF0f/iyrwma9L+k2eQ4YWkZUKnth0h2XSH29tThoy+HMDdt2LFHPajzFAepqALDCZgtztecypuaV6uJ2HePm5Yuebba1Yomzj/9ss676A/GxgnYgZNA5hmNWUFe9kZLZI4+74TwkMe77E8OS2mHozMOB6FUdel4vllPYs10WXnr+17kCSkcXm+2o//Ui1WPAw5KLfBfAdOXIq7NN2whDt+KwmrEieKv75PnTjSc9u9uk7OmL5jPLfsGazzY2X25Q2n32LHOyjbyyFNLJDKhoarj1H+qfM6CjZYWbLFJaqXAj4bJmE26iTvlJbNVlHO2LbzS2+ckSZJhVQ1dbBi4zK9iaYTFLxWLuJ/bag2If1XHesgyg5GEV/LfM7S3CgoN+eZkshvrPiQxXarW8VZi4mdSMmWdu2IDRNO4Fq1hSy6gCCpsCbZHlHFmYi1LVQWbFz6Y6RJ2M6mCMssYoa4yy14MPWQZ1eSZpabZpG1HJiEr3QlRaCsFoBvwIr9+XcC/TFHA1UL3PwrrsVw9YCNhaQb3n+fVwkJCpZIeMDi77EtU3CizNFi3PSFUnLPQ5u2CJxOgZBlwOL3RVXflN+sN88fkiYfrG6b0SiuXSZDe9iuW0wjcY4r8EKWQ+s6kVtkecV5koQOFCe4jvDjwXQ0XV+casJwhoglxKTHFC9GSIPeSA1icPxKPjw0MVQC9h/kjgjX2LkcPjGtQ09QmSePnvw70asdkFh+d7NfL+5A0UJ+4x32e+qFSNzWifueHjKssVaQC4VjnAZMiFxKltdydtf+ywKN9sRk7KXjxjrPtis/ucvdzYsJ48tXrdZvNJiz570nzZe95dW900IcUXbpTpCS51fVtAxMSkCWBePpYFypOtMsyoyDBQyLQUV1t25rUYXX3BLGmtqlaVYUviQKwwX019gGGqhqkapmqY6nWYanU9MmK4MyXbxr0Ks221gauk2yaa5+TbAg0o7bacSbdPKmuMU9flzpJZNqcls1Sct2FsDzaZJToNq5/MohGqIkPkjTlg5wZnSFDXa0OKxaOt/4gBXWRI6BwspOxpbkBQ2bbMURkyO0Z3QngYkMO9Yjaif/h9Rb2tzL2qbMideLo2ynjXTLM23GsJ1LIlhssyUFkGKushQ2UlfzFS3tJKeWhwny7kjagFoJkzmQVUn2zxKVQTj7d3iRhzFhU/6rWcGr6pDIDA3XMUBjiRKE00gkKPt/qubB2tZpnAWGXGRk5c8qoApQjyCoNJ+fSktwwkAOaDtX3OmgCJl+bVBaA3Uhkg8dri6gDXLAmQs6IrXxbgHsL9gyH3OlrJk+sG5z5HAuKM+/Mo9tDtVmTZ2trYnyeCGXrllkJYbUk4FtpuXRCuIvNGYuoigXgiOVbi8Mi/8zF31ALNDLCjOi6RIHt7uRximHmkkajr4mnjwohbKnDo5E2953Pm2s6EXDA/APuC1P7VIZCIloeieq6CDawBmiuWxu0yQsehVxcXJkQlv8RYQK22zS68UZBXtzM3raEW70nlDIdYHpaMMP6cuzD2Pq8muxfO1Yjuy2DiXQxlMJKZkczSktkDEsSWQeyqjjCkRlv/If81B75QJLPJPrkQQoWyWkW8oOkiW/wB9z7nt7p0ILbklqWD6hhBFSZqRAMDDPTwKPjsID8aFc7H8SmhwdPgegzxnYv4roJKZujtctBbo4oZVcyoYg/BJj4jBFPE12VmSVWUpUJmXxFlyfB8Y5i/PkHNt3frc5zH+l3l3C+f0DXTrI0YZsQwI4YZMeweiGHLIHRVT8sd+d6Vjq03SxAudK1HXUWCburHbGwuNiB6g+oRuqm+qxCnO2/52/Sn3mERXDeaxnJWwY1mN0MV3KhP5Sq4X7krh2RXgMCQPxy0ahDIvRAFYlXN2g4fiUqy4qCEk2nFZK9ZOzcum3vuTq2bi5/2qrRYbu3cvRyAwCbXIVkoN/NxucHdd1QL93fuIndPlcFVc02QoqgmLXzllmqSVwU3O+rhsXZd56l9K945urOat8l7tBI1b3X6eMs1b3Opjql5a2re3o+at9kMlLREcleZMy9nS5wpmraxODxYkJC0jrLy+mlap7pB5TOj3i0wGD6lT6qY+MTP+aHxyQWYOUA+2X2J9MgFWuOTpOqrFF+zOePJtRAKTU4IeJSfucZHGqfBPzS5GUx1HF4xhJQzkeI/pKORRJSOWs57eetqBHla4O2ja4w2UuP8jIg7SvxrW2LJMmk3NU2LuRYZSrz72mOlVuXnNSLtUwfiLvwMpVXuK8/YcPxlrCCw+fzpE8ZetJ4/f2k32dPnrRcvNzeazecvaZd2n7XYClYQWEp2PEOQdNIkvP4j+cM8IdMpzi4Ls5Zw9ihMegpnrxhOXZXBZ7703rv6Z4+tvgN+cJ0Ia8MMlsnhfL/irJeS0M8RS50izylhsjjCegpxnhZnbajy9any6kjnhhAbqdwQ64LoWPChzUWrZZWSElE6isObQq0rBsoaon2XUbN8NF+xyeC6YWrPkMjPaENyZcmRFTIiTZ2y4VeGXz1cfsVsXgnUE4q2zBRMiB0Ka3yI4aqU91AtqxWPwNb3OYxQfGCF4EESxw6eu4ngQRkCpKIGRZicFu1TEOoH70lEmnWoiMCokY4sLw3/FKWH2nJpO7Vzt8ODdjCgvngu39oRpYY67AqQlAOM5Hg0pFek1dzYJN1JyILHIu4uPeK5K6LreCAilZhNKKgjLtRJcvh3ZhOI/4uDouQw6sVaIN+5G0fR4SqPo2BKjAISAY7iLfCKIVPAgKr1P4J44HMX/djydfqHySFHzIdwL/RspEO4HB7CnT9307Fc1PK9ICChT3s9btWiMDexfrKQE7hkoVZt/NJ8NNjFRuzd3C8FsYC3EUEnESblsuOJwKg/sdrRILcWEacufDayTb+S564ez1RLBDPJmzbymcVs5losP5pz1tAwEHrUiAuJE/uYjQrTYv94gIGXvucEuEBRx3NX3kd2xQMoMkbieYl4QaQBp0iB5HL6wMBdEcZFuEsYBwlIixhrkG2MhU0tNsZy4Wpi7NaNBWuVs7e7CtR6Nk85p+SUjbD9YIO0hCC38qFZ4jNuTnZX8u70MKzKJiYhimP7usoZqSaUH6MIEuWZVBbPpekpYEA6lATp9aaPRBDQWnoYpAUGBCqOgd6WNxxiosI4YLYonikCwiOpGPkT8ACRlaJxAkHGVTSySqYIophjVBoY5GcgzwdyL5ndEukPizdLTYGpXlxa5oa4+qgnzOMxlj2vldt57YzwJyKMLBJ75glVjTqnaR+3175kQKCrmugq3tTllB1mnbyRIowU8XCliLmr/EwVLbpj52tdWARnCPMW4oUM7i54nh/lXbAwM4d7Q6d7zaULiJYwwM0xYdlxobgLG2I4sEe1pT1qrhETAyxKZmBXIy7ryM4xTtw5yhudh3apnj+1iPp5D1s4WS5ZpraGZd1Vnfc5KXs96v9TXEcbyMEcrkLVFcL7heV0jlFUzwIUIHmJKkfiTyN7d+JELS3RXXnGRiBbArSfBXCD20H6wTje+d6hdb5RECHDzGZiZtdSyO8jL1RX4TrXaJmZKvhzRaD37MOorjBMwrU7z2DJARbD7m8Hf0uW85njBarnz9raJfVdKLccFw2ecazUAAWijna6YxoWSUDxoscE5ctD1tAXooxXz+/CodZ/IK2YPZdLqO8yg6uK+h6laFVV36d1KFbd5SfdaKTp5hJEmk5THaat4JIlbVWertEbTNLW6lPq2RO0BM0teFCYn1V0m2T7xsz5Wob4ViG+FZZ++Uw3s0zaUGFjvTHWG2O9MdYbY70x1htjvTHWm+vrBDPnAetBmlWsMCJmqroRpigkE9DAVeB8kYpQHDTJXZmtgOEOpOvZk0TopAjdjHIuA5HCIOA8hxzC6yHzgiGwpxz7UZRlpH0A/KklMGgpR5Al5Mn3SfRtOVAwhgUK9DwledJFCpOEtsYX6ZwefklQbkxrkuRTImzHfLhTg2hUUZH9/Vn8qZiDRnpjx1Emj5FDLTZkZQlpD0Xluo3gmGUMXV0eKWfGwNIVClqoOmGj9Rqt12i9Rus1Wq/Reo3Wa7TeB6713lxWQZRQULFirNCEJQ5WFVW4rDBlmS48DRnLuMdMIoORo0wiw5LIL0uTyDCN3i6fTaDyjI1RwBgFjFHg4TIzYxQwRgFjFDBGAWMUWJz+X712eSqRYd1nAQvbSS4xIywBDlGPh6hkUDiBThJTTnVEX3me/HiSZ2HAEYJZhiC8R3gYEHssGzOHjgDmCODmeEgGVBRBEXVJVSsBNlk0JJbzHdALhX5E0CuNlX41D3YD/8mCuBKq9ky9qGMMIdNRsmc4NcupJ83/CUZxMoqTUZyM4mQUJ6M4GcXJKE5Gcbq+4pTWXaqrUCFzqbhNCyzXUJejVq7aQLg7YD5G+fZ8b4ii0Yj6zA1VaYY56jpkB5FRzOovGZJ8dHocuXeFKrNkAHEGA9yoCga903CGeTgD0mlJjkuYwmAyYr7t8wu2LkhhcQUfHDFunyXyv0bPsnDfcU1IGAbosdZ6DrqbHB0sXLuON7Z7DqSWKDp/uNeYm0THH6qR5oSJaUT7rLx8xTHtM+KOVUWYEe1zF+uMiTOYX4CFuyHrY90faclb22rV1obc5UO4EK3EFJjfnj6NI3oFfbWZyPdDuRmYFas6kY1mbW0oRlvbajWbyXlV51na3pOTedjUImi9tsPz0PiC7oW0XdwApOhCjlZFgiL6LrvOSNhnJOnatBdKyrVx43/WBU2p64gws1BynVaXCRT6eToQosN856riF9IRj76pLkoO1KXIsrZAvhJ/luAk8FocRrCHZBPyEeTotZr+0wmjtuhq9Y6ZP+Si8NNJtAE/ohI0ljdsWBEJbTC7zxrxFzdsGtIuDVgDa0vAmVsEY0twk+nlLHL9OhJVuoAxSXzSX/WneQimoo6XH3EpgJHWFjKpJpADzNw7dqjLwlOLgmsGiKV4XMNbncOO0NdCHVDyJ6QLBb3cr6JIRXIk7K+93KbBoOtRf54yE3fGJxcYGDo32Ynw0WZC303cH8ObFsObFsU+Fsw9slv+wNnHYpmFvIC3yy7kS7GF5/dZHUkmnvph6ASNIHCGWCTwx5o18LjFcLHksVpDmyvvTeoWjf8NOdprtbWT/T/eH57s763V1j7snxwefGrvbsf/Ptzbf3t2ePZJHbjKGtf6jwQRLUVnlCCMBdxOouqVcDvRQoQdBCNmAbm2tQ6rxGJiPSjRYur0xi7/BtVBo7EUtStk+DfDHStCOhp+dEP8KL0w10E5rMBrstt5MIeV07CYJIuRhPJ2WYx8acxi5EERAos/pBG1gQqlioATWxJfHVClmOYUgUX2WaEZDiD9Soi/MsIVEf9re0MMK7ghVpDcWMMH7rtektrvh8kobtqU5eOQt8o4yjG/BLRXAW2XCWol5F20SFqykqQ+xvQqpXFkdxyE3pBY1BqIguciNghxu1wvJF/ZKIRoZNWAB8TmAUZ8SOOYq1vE6l1qgaUr8RZhJtNaERoEnsXFvzkgiLGA+RfMJt1xSCzqwpu7jFgD6vaZ/QpLf2cGwU80rOv2WNcd2/jEVZoxL9Ww0ofDSrNbbkx8C2SiMnXndtmofOndmvgK4EokKkkBFz8RGI/lWho2KePjxZz7TIPaRH8Tdy1nbAv0SVg9HBXOLhojPJ/3uQuDuCJ6K6oUQN4NeQixCrlCgC+yQDxZRF0GCAQ1cjngDkPODH2HZ29OtY6unfNCRPkUo0YcX3xHiWyAeKCAOGqPfZgc2nyxHXzdLKICYRfMhXgrV+JvwnAVxJcGeS8xPRWwaKTmhx4ZejbvTcQUBZ5qJH0Z2eShyCaVpZIsUTBiyX0XS3L23Mglqy6XSATnFfY9QkJ1SH08cPnxNrJBsYCDj8sFHGwihBpNEhh5nhMF8E8XdsglDwcemAaAy6MZIgzSTHpf2dnj9whZw/Ypd2XutAj3wdcDFHkQ0q7DgwE8lamudt94RpfIHJ49ZIZh3n+GmdlzwzBvk7UJvlCNu2jaU/BOsY9gfRTHOa6LMJ09ya9Ped+lKoO6YqBnXTH7ehD1zon9VK8gp1qrouyEYOD5Yd3hYHaGUYEHjMOB5/PvUmn0fKltgp5I1BRIOKAhcI8udxwI6hz43rg/0Ai+0GnhhmLQfRCIKJwgQt4Q2nRCQx1RP3SZ/4+AeJcu2X1ziAq2NSAoG3AVx6O+i3RZz/NZPD94GklERIpTopNiP6EHijJmSDsiGDWecl1+jBoiTq/TJrlKfLEScyk8NobH3DGPyd73mw8NzTkGhu1cX08TnCAATjBDuGiXhXRB8aH5zEOpbdThFGnEXz+uO5WGTiu1zy6bYjyln19KGC6nw/VRtA1tnEBx/p7sWY97yCljfkUmm29b0uF4n8lr8YLcjGygCph4HR8LIiYk6hxF2de3lmTN6bAdD5mrHcVvUplz8dCpzNw9RQPjDxTfJzloj4UAfaFRxCAE07ROENee2c97G72nvafdlr1Jm+xl80WrZ1svX9ibTzZ6dmsN0+veMLcfDta2nmxgfl38pz51CbpQafJvwe6/gOnDOO96ZwMWnwk8Eok1dWiXOVVn9gYaL2Jq+Napc8vLlSyaWpXkTTkf0epaGZtFs6iWu1k4j0TC5lM9X/PpLPmaGRoQZeovivXBZY0xBNoZqlapqPyUuSpUgUXO+Zb4dDExLmLbIh0drFuntMfCSRRTlXmAkVW1tb23p+QDZ5dRw+gH2eB09/CIHENZP3i/uIBvPGqTHepQ12J+EPEMNUTBYzlgnDa/RY4PD6OJ7HmnZMcLXRaSA8bseELpB7LDR8//CsOfbJDT0PPh3qouOY/0txz7XiiNj4mXaL+n3nFGuZP+7fcPhe/VHqU6neK5DTI91O+yubaC3O1vkSPP5aHnC2fqsec5Qd5iFzWVg6p9OOA+uwTGvY2yMiJCxuOVt9JOTdRAPznRj7LhDnccUElVG/V3akqnylmcnkX0YP5AQDriDU6HjbQApOe0Wj3IxdxOyHo/1rrjgLuoKimdJmT+yOdBpOX0fBb9e+R7EYDTIgw0eXOeiv1QZqjJlRvXf6R/UrlIs0mTMoAgWYk0RbbIXtQoG/cK+egyhJ7QLhj4qfIGWFkZgbtLKlvmrObCXp0z9qxWjqItuRHOLhFG5+PqU2dq+Lrh64avG76e4etagP+94OuYPVDO1n0m0S4rGoNU+1JT0IlsVMkApEa8n9af5NdlLRTTppTcn6KZzWvcmTa7CqYdtdfKeFLdSJA6JXMJEuiFUgMKY0fiMElwFO0wLcK9Ahszj18l3a/QofJx4XB+uZnMMwE2ZU/jbOhMU0GZis7DPRDX0gSxSFjLE61ukyMmqfsq6LnJGVfQcotgoQoYXAQOkgkTSO5pAUyUDBVLtiVj12bpqLWl4Xe3FAgtyAm+py0WOYe6VIqG3rbt9ALPxUoMY5iDASyG/pdsoaH+edR/kVQ+4UW/B3Q+QnGbRfFZ/5GRtEtxlQrYRQT0oQc4D72LqexCtqJpkRxRzpdTHcos2MJeXKb0VIz3zVnzG7FUJkiJMFvWuV1eEAnndsTQQWvI3G2RuQTwzz0gc1UxhbZ9RibemARjn/0nQYQhUWJDy3scu7bnsmIIoUJql3XdpO7c3I6bFB1cWrfNUlPBvK0wwvGKCcdTttFwjrsyj6yAu2AGfqKghvIwCgrofwSrkEEdmiLtHol0dx3XLknvDYW/AzOM2M55zTC5O2+YzYoxm/JdNLzmprWURBr6PeAq0yt1gzFmHDC/qgca2pZ6n98HzK/keYaRVtHrXORrjr8n68mtPp14LxbtbS6bXwVPM+xrNkS/N/7+ffJ2hhltE/ESmI6N+x4w6gvMIvhLPxVA5Ch3RWokDUkw7orO5VM+8LyHnUYgSj3FeQTNonnZ3Geq3meliUHyZ+D5IfF8W00Mkg+Zndi47kSAVz2igcVcGzbQA9gp9dfj8g2Ehvr3rFH8W5FyKp8GFvDS6hEPMWUyctGNFaySwlF+parqxC9btvZawQ05W38PhCmd1S6j0q7Y+RCN7asQzxBLNwuIZdBEpeI4hngPy2MYNO5t4hdkApqIW9Akpi68cpbABcMSbl5VjvdnoQELhqTfpG6cIt0rEaRQkXhXC1DQRJH1HwmlrFJggkb7i4MSSmh/FJCg0f0lDkZILNDCXlqkC88ShHBNCn9jAQiGfN0i+VqJ4IOK5OsuAg8S1CwbdKCd5bkDDjQ6t7TBBktI5bJLbwTZFRJkS7bPcIPbtk+sQEBBRR5RJZhAo+nFgQQlEmpOEEFMwx841b4d+4cMGJjX/pHZYsM5VolzFO6eYRw3pUasRHRARRYxc2RA2gqyLhZlpogB0WVq4ICMzp8SPyDfT2gYUvBjg1ebGh5kXN+VXN8YuLCPFGnuyIUed0KGP6mz2J0gCDSnDkFqR4ZQ767c2w27+F9rN++W1yeJk8ub1g363ONLPTe+wLQrbwAGFuGlnxeeQCNHYqMWh1DwUPTk6JIYdXnBslBjGJGfxbn1pTyT491PeSiLBBpopoga0rK4z8MVXxaoQheRsiRX4PZc5C21WglCx/GeJZnRzzkjE+ThMer5bePt3CBDm7LFhqmZgIaZ2ZcKbKhu+JWDVjIAF/IwVRoRA9JYiZxueNtCeVtyF05ZuK52IiFRJA0iy8UQa5GGV3zc5jdnG755//jmAzF73wTLvA8sbmFW6/UfEcmaNZ5PKn1VwvrkNhZH94mxRGRfwtf6MLlj/N5od27inXncqpJJcw/3PLvBhsXcvOc0ZiWL4STZvTScxIRjzs2Z7jgsUzIlaK5zJAi7nM6OoJWM6wTtTYvKlPwJIjKNZ3UFGFTufhvudGvcqS2uEbMXxqbKd9SwKuP8WhADm1atYghHdf2iVRjvEy9YXTTGOB/572y4T/R7TtSAgKhoNZuyFbnk4YB4LpRMQONZA44NXnsPO1KHxAyJdJnjXcIIfZYENaRuH+EwxKi3x8bwdVMrUK1crM7baAJoGqocoaOH6MCfiSCdpj4jNGl7fuXCH3DJ4DCgrHK4h/ZoODuyEIUcjvQ4c+yGIg1wUthwFE5UgM/52vkaueSOI8NoolM4YH5qEKghD1JbgIJXOprGHTvipoq7PUPcjHzjwlPWxEmU/4H7Wb1SZ2pK87Ae6k7e9fCizT3JWrWrVsbDvkguZrORzyy4NtF1XgBf243IIDkUJK6InYnHqvSS/EvTtPLYgDbnqAnvu54fsZJCliBo3kVr/giILIUfjxyP2nXqih/qF5zWx76T8iRBG0gUwDYZip96Drdx90CuXUP+N+II5Ij1aXcSsgD0JVSWsDtGusHdpeeuSMMkv56dHZPjd6dn5NFw7IQcAvPWIQMNa4k/VqwEwuECCVITzaHHHUY8/9wd0UAMS96fvIGcNBYEvOvgLKXU2Th3l4GRzORZylmQ+YhIu0sDbrXFJszgq0lu+U2SuYh2yLKGZXSuaF63Q+uyM10gsbsT0jaFmM0o0yqB8TqZ/UqKXf8hlnyK+T9L8UTLuiJlMZmT9sR8GicfRgfLc0lmMRvknasU1xpGuVveiLNA4beJntBezMHGioKjsd+HcGTwIFjgbC+WatUXL5IUqTFzJdrbpn4Vzfc3SnPk3lQSq3Lnc+O0JjtDQ2ZmIjNVTb1o3I3oiVAoRF8SwiN8U7GVN0t7hIyVl4GPC0HsguT7AwB6jCy8iLUZi1hqGoZqFFCNxNoujaiSPysjqNyCDrZoeqKytSFVqJrSBUEQOSKIDI4pUrNsgSaXuvn/CMiQhRRUgJqybdQArlMoOwjC6nsOSifJn4g1AINauaxi5JNbTQvXvxoPlIKXnzWObtkUs5xJGWK3EuISs3k1z4Kmk613Ha87g6ehS4Ncncy7dFGjL9DK1OPY7gNkSrM+HXg+GXqx8RPlNhTkutL94HMwvTvOJDZEgfFIdHWo3wf3uSS3obJZAaQn9euOFwQOENQL5oMvSlFPNegDJpXTqNQODdLkoEFO0FofxDshGgBraySJBD5Y/2euyzuy3gu0KnAccxfOUwl9ypnObVMnvDErT5vuWhCri2WsQq1ElrYyfUIMfUWjuTBT1ek4HMCxR2t+XYymDOpj36lf1Ft5gMGJbkR0kycebdQfWlk6pzcKQFzzBKAwpgjIvpqnFaDZIJziK5sEDbJNxAmBHueuBScd9vOSdQkdjYIasRzO3LAecJsR7XwHKEUOvS7Y0m12wa3IhYbvPnflm+X1kN/iTNADkLWOoTotNkzIqSwgFJzC9ZAPWTTa+5M3sXf4wwZhrj3yuBsKvde2ufQX9xgNxz7DWJEBoQGxxkHoDcnhXgCGtXNXScVLa99fvESWONJRYaKLVmXhsfIZvVnJMv0dkkRGH5JLw2ef+y2R+JKvuX/e0Jv3fzYSpHZhDgUgljNIrNBcBMgEvA+xTPhLNkzmVDwlv4unOX75iTf2NaVeDieI99IQrkpBD/q33iyB+Mom8UWyPMeReCvTYiByZ3hLZKBwzssu84mze9eCX0PerymxD1Wv+voPedFwX2CIGR2JSACkN1EjAXk+Re3UFXoW8ymACJyLy0TAPGM9Cex2MA0SrWLj3P04YCJYyqFBiGNwOOqQsGTXZDEKGcyVepPQisXehMwuk5vSa7dIIqSPvSLabHafl478lUzR0L/K9O/WiNmifJTaDZcaGDbh7gV1uHAouBOQiwNRog2+GvowW5AeHAQ6F8ISFFBGatuFZDFRGKeMOCYaLoZAGpJWjaQBwMky07Oi+RlitnzEbBY1LAhpOIsepnyqkIlTh86AZW3lRFcEBNuQRJu8OAthBo6bJQIvcu1aLIZrzHQjQej5MCC+vUa4azljW5TEZMQa+z6YzsQ7RcLLhXRTyPX5hzT4UdcqoV7LRj4KlvyGA+Lx8FQK3Zo2v9uKjk/PeNnJx52rgWV0RtCOSmTmgvqcujNRGtVFWH2iATIWH+1JjgUiAtuPxRnVYXVud+I7b1Y0kG+ZMdclM7dbEgsKZrvst5p8UGf2rq93Q7s9C8tyiW6u8typX/K1kvhhgTaSubpSdwI2HSA6QOjByePfmXLLgexg816PIbsfB4yAI26Jrvwtxzapi2KzHne5JuxX91FFi38r9CfgkHFeiQIVTvCWiVBmyveGDN0V4ZlFkVHjrf9Q+zFzrkpEt6SZOZ9uRRbkIrqVY2KWTXWTEAZ6CqUEwjyFux1MRaIHDQLP4uhTlYYhFo1SSMTiL198oFM89krYU9K7tET5K3dAqFYvh2XpadOiLMbRpa6e1xLRKfmP3BQXuX5zJrkYUlOd1KRWeunko6L5GfHoXmlps6bFRFRE5sfkSztRGkyRtJOTJ2OknXuiLV4rI2Z5FcbCCRqKuOJCWfXcmVx1cb3n0HAeE3VKEKvjOCXSGHkELR5XEsokPIs6q0gfY3RBQkOklqE3Ig67YI5KihHIVoZ6ziHAwd7cDtGCN80lwyWmeMtkKzXp1YupvhnBbhGh1hFBkQTkuuiDGzMQMw19sH6xUQRASD5sTMEgjFEIk9mBNUG64nbZSpULQSk8d48FvB+o2xCSNR6NPB9EywtOMXmGu2N8Kg5T49w9d//5zyOZvkIOoiqVj97JaTze+uc/odUnb4wpiWp6zkTWtFRf3J2otBiVDSNg7wKJtgXf1oFHjX/H3//jr38X2+L5//Hll3+/oM6Y/UeHBBM3pFdyYqfR/N/JpgFOp0467FuHrMN/tkQSnvpLoAiqvySOa4fUyf4VtUJRZBMH6IfYqB9GXerkNRpdASSWuuSRAk10nclj2YXJPqyok+cT9m1MnZzejniho7/wDaR0FrzNkW9zEm+Le5S8irvYk7v64nBXG+YI1gED8nDhAbYZLgF5NOIjVg8YHL6Q2Y9zDwjZ9dwg9Cl3Q7UfqhbrU333HTy8IwShRTk62RJ5NuIAuEw4qh+xRr9Rk8ekx/0gbATM8ly7EQ64bzd63tgPB40e74WDzmN9tFaTMIcNgfyi7IAfo85XQB7BkmAHeaQCCeBYk9CYNURIksdFrgkkeQbQ50RcM220ftipifNQw42tie16jHuA2AejEEZmPrfEaIFYSW0BeRAy15rgAh7ItQJCbXnDLo+iIrff7hHH63NLRP8EkyBkQ2J7TIBJRrGVlxLfWF5KMYhIrsNRcQy8tpZ6dygyjyXCsVr2kc89YDt/RZfpyy9P/2/yUXwkv/zypJPAv/zOfC+ibl1mUXBAup5cUqAgAUTA9Cak64UDmIxIs4NQS4Caoy7zxoEzaZDDEEiY0Jsdh/n/iMw3XDAeBON0AR0996uH9CtUmYJ0X7H2++JDxZHtdDrn7r+RqEy0oGLnbsw/oNO/qRPfncQH+y/27Yve8D9xcSAiZBz8FRGkL78AWPsFKx6Gu8XDcPfLLyMBNfjf0oL93z2H9vvMLhtQ7Up2XOB/bj/Q2vyy+d9PC8cSnOWvmNLlDBkdB63VL630kF1v7EKCNY5YdZCS85aZMxAPZkdTz/l01uee2wDxAbbuFzauXyIxgnF2xW3Lki28fRLkpGS31Tb/X9n0F0hYbW08EaMfIXiikzP8o+hiP64yevHVlEd5Gbz7GhhvRtQoxuWdEd81Z+ibACZeGC4xFNtuY7HtqlM69XzkhqJCd1fBRRDIXS6tw401t4sKcd9bpGS90EK+dJn+0uT3KUk3fUcfBY8b8QVW91bCchQxacFp8qTVmi6s1nRZtVZBVK3NLqnWriGo1maUU2vziqk1XUqtTRdSk+Ipink5zL0uZZkMHe3Ez3KJqfacuXDI7L/irfnyCxy4vCESvEtrEFiez/6KVvLLL61m8/9n712XHLexdNFXQeREHFc5JOWlLraro2N2usp257Zdzsmsau+ZSYeSIiEJnRSpJsjMkmvXiXmI+XNeb57kxMKFBEnwKkqiJMRMtCtFAARx+dZ9LeUxJ0yM1kd0iC0a/t+IMtr0fwWNuucf994P8Zuvv5ZEz064R3lVJB/ojIC3DAPLIXboB6uE3qisdXMe73khk8dj94pSo3yBChpL13diTQANV6yMI6RMOel1mvPx44XUS+nzyjhSrqmejGCyeclMHhE1lgDFJptEEPCnCRrFzQYn7BqcKEVV/hNSO8DavnrJSBAvEwJ6fi+R/TO4Fg/4Bn3l+eEQ//Mrtg9JyZX//COpbAJoq5RVmVouBcw9CX1/vLC81VgcsPRHfPB9BE9zfE+jjygc5Q16DXrgR+JAoOkiliiZWyRUVGn4OV+acj8VdU82nBu/gxkepdN+3bDtiy0k7LlolbAnr4DsLmEP6i5fD+oiXY8TWFNQ9Nt+4Ah70DSCPDwiDS0oCAIZfempywSqnDhPWyKhjNAHH/KnkekKETX5JAkpdqdoboHGAntxUrABy/afDJV4kfByAM/iY/QmLw8pBrc3ya/PuaLJnmP7gbtyM70o+9Y3iPEX0sIV0/ZlgCku8wboq0m+u9IBBdmGLjrPNnSxm2xDF11kG7rYtlWs5Gv6bs7vWeLLFIWoR6IkT9Q0mxCzdcnOBZmEONzFXNdDUUIhKhgy+P50c6ADDugulKAUy5OBpv2Bsirc+FX5KG5U2BA+yNWD01svrrR4aoanbHlzG9ms46R/XWULujilfhTYxJs9kPB0QWb8Hje53MoA4qIno+RuuWyMHkiIUg01YouaCpwZ0HpxhxPdnz+dcnVhK61v6CP6QJZogqd+IGPsYWnyRfKIF+JZWh+sKn9Tul+XLEjtOUlTppefG59P+SQuXqVV0unKffX1LAWnYlO4p5zYcfy2hiG4VVPeODtU6yP6zhKhW7mMP5Nw53L8iMNMl7G5KjgKOT3eLH14rv5gFUfrCottDiy5OxDzwJmSWRRA9g4YukdZNrbmZq2/K3w/Gvtbi5XX79N2ISv+gtpRuxWz3hFq5b7joHBrN0hVP5i3iAc8/ZzsUOPgXhX4RHyvHvjiKM2awBe3h3PBnFQG7NTCf0Hgm3ADRBYOe4F6itlYWdlOU7Ep96t1FO92oa1FSO+uUWwP43v7D1jd1a1j7E98LJqE+qqoBeUW9JD1Ey7i/3NoBU2Zw4rgwvicQR3P/QRA5LIMWLUBq+Jd2C4TxgOGasFXjSnviAPLfcRBAVofJMe6IST1mLFTl0yxvbJd3FJTl0K34TLwZwF4J2RhLjmgSpP8oZYPGbL5k3+AmYh/paaep0G4uoaA3OJvF9nkW+uZBoonuyNM00zfoFrHqBajwiag7ZQJc8wVpm6WBRXiWO8CFu4SniGrhHOTLYLI83T6tRG6dANsOSvxN1ZcXpjX4sIinoG5Orm4Jyl+vbfcW9E8D8z0uQeiIseFjUAODa01IIf1LoCcW3hWCjmyRZFK36BJDTThi9h/NCmap0GTbaMJv/Jdook/68aBYshGyjlRJIdGPNfYp11/hrAXBgQbEUyPJsaPo3M/jvTB3LL7hj9r6MJRMNtdeW7k52+k1a69NwAuGwM9d5tYC9HlEOX+cEmrIocjTFV/DlaxxfjI7TO2JnNSi3JVTUnEZMojAQkJrAVGzyDugUBUMcguz0e5QObWPnnyTVtAdP6qdbzxspPdKqDrp2+QvAWSjxI83KQ/Hn9LDWe8uGHGs0oCMgQb3L4QzXoMzrvzvROXo0PHO7HY28OlNV3uMvPdBTQZZ7vNwVFbpzsx9OlnsUdduNtpcE3va1eAa+nGuJrx5PuEkzgsnv9CPoc0JhBaOsHCXcfpBRqqWXPE2vdHmanzd9ss5K3rjbdtgDOueBuEs45d8mT8QXt/PA2m5XyqCuAM2slgeuZ0VxfWDEg1dcTbOlO2jgteDzgy43y3LUBrWrRDxR9Rt0MDQXGBgzo4dIOZrsbgT2382aWoyje9bU2O3aJiPPfaJTr6Boy5LzgoYNwtFPK17URUPbV9z8Mg7LGZt/ZH5iMOU6NpWT2GmnEbEUqRV8yxhEcySXUCuJAPOgQW1WIZ2SAVE+jtJpH9gPtmFe8hu3dbuAPbwDb1tWOW0qqet031pLcKcKWfcVAo1yf2jy10e8hTN20I1UfYcA0y9amAJ/tXot61aKiDvgLMu30BOe3YzbbcJAcftR5h06xYEO8B1O2Ow0tdQbkbzY0SKqLIUXoMhOXzNRh4gJzeEhR2lcjnTQOLhkFkQ7rL09AKZjgs9nlhzYeiFfNxyfu2QIkLOY4+kxuLg2W2gSRP21dUdhohtURJXKOIZdoMMCRAh8IUoT9jDN720Aw+fXzJB/1gzVL82tynoc6TI/31fxOtuCKSf25JQuuy/PPyhaxGgUVYKq2SN1+rHiLgwgLByfPupvNIgjCy3LGHwyc/eFDWvGA+AXkEyVP0Q6KfkkFVFtirMS3I+AkFBU+iiL23eJpkOX58WT6zq+vHl8hyHBbJVn8O5e98XfnO152+k9sjnTH3nyp/+Tumw/J4zQeoc/g0J/ZcmQN6sqjIletIj6xnxLPdiJJH/Lze1jAdmqgqUT1vaxrma1isM2024KZmvfAdOLJdLrcccsPrHc+8swWPJ77RFSfLCryTFARUq4Ks8BTIc+sRszIP4ppNfchiDfT86lpeQcgTfcvq3q3uvHuypPdoIWtzwNQoVIdg700K5wGmTiLiOqIc2BT0DQ6rk8BUublPt4LAgnkzp8L8knzJVjNQvp5/0Jg43S/Cx49X71Jfn7yrzSLceU1XIYvl9VeFLMcueai4fboleZr7FKe2H7m+/4BgNLY8ogYiZFJj0xjdeXFpt/uv75EFKcSfiOvYVgD5tq3Asvl1akcvHl+OeWxK+X3EU+JhxkIxmiUqLrDaV19BzTmLl/bh9UyUizhCN5wBoux0P74cY8+5Z3unfqtF0RN2Xe221f0M7FXwARUfIQLianwC+9xNfMTr5nvxuv1evN7UXrxuuhe5j6i7F683tBehNatzt8EBKbRmkKn4DZ/r0iIBVcor3YfW7J6DFpUSxVfO6M77kWHPG9bgr3H/+7ieDfyMvUcS+B5Uf3yzDHwnsuHt989Hd97PeMXoI3/rIqIhrzs4gaKE3pBVqPoLH0WODM3jt93Lkjcvz866Jhm6MmUZBUEUBFA/YcmqFHiyuLVUZ+Qmk7i8x5BNvPDFRap4WZHTe1HltJwHPrIWIG4BoZJRbXyRsKOWT2s3u3xptaL5amuqpScLFTN5RTEIXgC3l8mq/KjL2mmK7Bjzv2G6jBrP2c5jhyvmQEVFt7hLehLVEq4oCfcufmVd+wAvdDONoPBngGGzHuHWJ9oAeayUzOy1tU1i8XiOGRD549LsJ0p5nzrfFxfr+aIW7mnaMy7rk12G34XdCT4Uip9AQVHGGdN4fZQADVHuC04Dr9okdRLicMAff3yRNYXGxJv61avBVjc/sw9+CJJ2HM4iK6cyXojddqYCBTYHB1BnZaQpTBhP85z5U8ywRtWoIoko3rfktaJxwh7nI3kK3iGhoiRoKFvhuu74F2esulRouePSNZPjx2q6WLUOTDTFVmDPlRraFe88S966lIcvf4+TfWJN2XfFNwiUJCwuCuYFtQvLl/HsTGq1GfDVOesf2JW9ZBSH95U6s/+Mz/5A3jvlIv1RooP+kaXrFAFUDB66Qofq79lSHPxVSp2KLrml+YPQhnakCYaSeMMwiGg44qbsUaJubRkxk9brsjaawBgPPyV6KV3QAwhC0CitVZYGd6EmyO/zrvS3HRqhyhE5JvH55DKMN4w88s8o5h9ARA/wVNTVkprZEXoLRbOIB3WmCXjYx+Xo7jwXe7NwDmhx8epVIoLSAaJSUoU1h9Jb/pTz5JartEOORed3HvCjSxwQ3xkkdb/FCIguLRtTXlSKcbeU5y3xHJANeHVSy7vzLHc5t2RB8vgV+ahEBaHE+ePnZBgfsU9DK3JIqMgDgxOyrLfRV9dXQCy/yLuZXfi4FCs8ZutMqW8TVt8cviTRa43Qz1BlJmbtmdBw50H1saHDZCapGFCRPz4JlsOrjlvudepM5IpXpkUf+HoKmn2XLQkOAotVtoozisbgAUsQAdcoTSU5wFatE0sJ0Q05OqlJVdbF8G8N+bcmpHcDVJdvYdsdNDS2ksbWCAPTmltPP8dq1tL4rzSVjqM0coFeBTT6Bi/8R0ajued5OZmGglohRVfv+mFhjVeow1fxM3PltBJxRQRS6jpV38E4PMbcwc3cQXErimKN0ldIWFhTnqYFl+dHHNpzc3k6ujyJfsjwE3vLT8RSvEGzTaGZDFyKqmX2KNQFJxWgGX/KbD34E6FMY2wALQ1oRjFgFANGMVBJynlAkSHke0zII0ErDBnfEBmvEXSnVwxMZMRyE5XAkPcqVAxQ9OwdhhgAuLfPC9UEvoehstoC/A+la/aulfVrSui0lYhOt38dnHh/4nXb3QVRJtOwfHWryzKJ3IdhIsbX4301Zz5ntMqHI1w6Tj/Peae8Z85vyPCghgftKw+aneOXjqxVzUDccKU98RTJ2ax2QIz3nzcdAU2twaCm7zWkYIa5x/ebOSW24WDHCftax/9EZWPzzihpXnav2NdtqJSU6BB90mRwKeNKvat3lIdsuA8otiYWMQ2NFGgZHFDm1E7JsMes/BGgh2TWW4KD5IHquqYJYGDdVGC4wUvXsjFnmnxFs10MFawD5T3AD1YFjVqK8ePAlGzEQQtw+B72TCw4P7gfrBm9CvEiDxd82HZIEfBXpKDiK7bBhgHcRwYwkJd6re00SF4PycVqS2xdhxsMsXtqUe/0s0U95tWk9cewqDdkbV0yw56NWUIw+NF/hCAE/JTzz7i8fY9+Ew9HunSvzKopu8sQ18so9D1/4UcU3a5oiBdIhA88u7x9/5wnl4hjE2g08bCIjCBlHsrU6wjaQ+yOYTTVxtk5/YCXtEvzqq55HBXW4QUUnz9OHg7Fw2Gd5DaFU5R5bTYC/fW0azYLx9MEpiWRZjwixPHtCMIKeVmoKHC1ehiBntpnIvNo5ScsfZhFoBkjR4nZ7JO3DrI/5NQ1gxOuLrziqyH0YjGxAahMUUGziC0XsXuGoIgDyC16TvMZdwYt4R9NeIBBxVMxiy5TOgFQXCkUpziJEzQSOZwG4i+W1a6rhE4w4ojTkHIHoNpk9lRQrubkVnbUUdvb+JkedsVzQyfV1WhHJssxB768/hINkkDQ6h68KTNh8H+PWdih5v4rcZ/Vw7KWmSjOGr1ka4Zz8YmuGQavIuXJ+XcXo7PRxejs9AISP12cnZ2/eff9t2/enL64ELBSxVVkN7QVU2E2crMbOVAYs6SX5By+OTt7oZD9k/c+CvwoxHHs88ebqxO45gvi/cKslSx5QfUHFgn3Cq1uOkyO8MZgoBLZXKaMTaoIppZLIRdHbkb1yfxREPJRQkXXJOhhaEGK2CiYgjQeYLBxnxJKIzyEPSgm8CyftljcoY2BRR2q/dL6Uu6/TdGt6IHesh7oCnpQ9EF00eZwhETacTw8ewVir4D43sx4A8RHmIA2FRxJZj5L5QGitmzJRtieNjWzRi3o/YckZYLmMm1V0Zj9mDYqx7IxdqZ8rJv4piOt4yWyXQKpK1g35Ns2pLJwOlN0ZNd4SzrH3O32KJnNpbpxd4CpA7lRGqw2BqMtELQZeJbAZrYDHz3mRcR3DBCd86R8op5eDJXLwJ+4UIqYn3nWJITTKbL97B5A1cxFdEEoxbncY+3ekgyXym8GCzi2XYvmMiK2/BgY8C2Mh6nmTQx+unsRJ7Op/Fg8s1g37xCDUU2BiW5eIHNRp8bHjzjgmeq7eIMY7d9glGs43umXRZJ6dvEuPphu39kJ+389/M+tnbKOX1Z40rp7j/60if3r7jX1TkSH79OdCl0Ku2R4NQ1eoxVkAnONbHmaV0HV+UbvwsE1f53hefvF81bldmvyXYlOKGZ92jhyaCGFcWF1NEL6Y15fo1R8dA+Y/d9MHMgWBAJdzEhzOaBGRrN1ZIDTz5zSQmvBWTJdrS7iBHL8kUecFw342g1TH5yICZe8m0ZK4P00WXjlOBC4wKyMTDLg7wdePyc+iN0boY+U+8l4+AnLHoUzToYnHg2xtb2y3DVFB7k3td+Z1QpszT1OOTs52I9Js4ybyEaN1A5w6Ij4tkYonvekzA/DAOgu8VCewqRsN89xnTmh8YEEAwJfpPYAymXu5spo/rrhZDWUUnttzQp6y/pCRoq3om/Wq7eoP9dS83cjazYL8IwXNVkhNg0yFeeS/9k3QDS6FKNLMboUo0s5IF3KNrUOTabIYmk5obmp4YBqGJ+9khw5dVuP84lBeR3mR0H2NvzPbdK9AxZITga5+BG7hvkxzI9hfgzzY5gfw/wY5ueAmJ8YUNfjf7iicw3eR9C+NnzPB961A54n8Vs0/I7hdwy/Y/gdw+8YfsfwOwfE7zCaU8nrOF6xGWsJpqFHPHQ8xriQJYuazP2ai5285i3Qu/e3wGtcXRdkK4jzDrBqeHOMHH9hEU8t1h1g6ruPPCOGJWvq2krR6i2mocmFRyroAUkXodLwWJgeW0EIf0VurGx16eLBc3Vxa3vspRlKWQ+zi0qWDf35MnVwIchdU7ozLtlZVeayfghr7tBuKt+DJtcD9zAY1035UDxVk/ehjykLTN6Hvcn7EFcaroHT4vKqHds4tJYV3o1rfk8sih3I7bbyo6Bh5d2DqVgcAAtPASdtP9ClebzhDRgwur7/MIyWFPkTKOuMHeRELGSIJdQiCyxyKo9KUj+md2xKAhqOKcZe/s0/wjMEzxArKSCyL8FE+Gyr3x4nYI4rt4vUpElC5ouzi/Ph2cvh2XlBHubilNZ/E084bwWzuLpmtyReHs5qsTn6umnp3udahSvyi7XFBXlxpp1gLnKbQdUe5WzJc9K7DV0EaWFtz2TO5RdKHfxxPluL+N3BoUXcfMKWd+wxehc/1kgccSShGISlP6NAPGlIbIqsCattLuSQfogWYrVa8PyQuG7MdyzVN5NE8oEsxbWkvhsxL0DAToBO8L+eWhRkYJUZzr1cEtXc2wPLe+B3uGoGifiHRCcxC90k6Ai9496ckMf3zrtniRru0TPZlUA0vu1GDnaej9AtVDf00T3syT38y1+GCHb6f/7rv9EyIAsrIO6KJY/nPpGW60L6fZc8YPTW9SNn6loBRjeWYwUcQD0sZNJHnzjIuvNsEtiRawXIwUvsOdizV+hpjj00iYjrSKATXyiPH1DA0Z333g/xG/acZSSO/dOf3aduzCk8vX8O9QIo8pdLn5IQ33mOXAn4GooxuhefLlf/HoYO4EVle6d4bIu0F7VFp/TV25Tc1FBIKpiUkZD6yNwbCWlvJKTqdUhqazChCHg34tfN+6Tv+2Wg3tCaQykdvsSXfZykYamrrsn1Y6dK8jDVI/C2Y0YXIRbRm4MhAju6oetNKW4/BqFtTCMQvcSvK8g2PxYnY4wXS7B4q2+dBv6iJkeS7pMaJSD0YRyn5NnMnJf+EkgqCVeMlNV7UbYTP7igRKbj0B8HeFpzxrleMBJ8NbVZBahaYyTtZe+Nrtl+STeCRPcol5UwQKydgEXIKnNCQz8odpVNN1OlHNmzQMr5W/xYI+XwvsS23ETgCedQT4bJOwJ11HxUNtcDuSvWYBngR+JHFP6klMw8aX7ZX7FI1RmIf41sgLTGTK5Y+U0xuQ252+xsNsrdts8KuGYiwIZVFxKaG18jTSGvFE72UL2cUis3wnGxfrsDdIlOfcByBUm7gHQmgzdWXS0iNyRLF1fpsH4V7aqUWTfMLFBXnyXfHpvXiQcaCy5PS1Pq6M67877++ns8tx6JH0CJQG+GmU4ho5YhFE2w7S/g3/4yHBJv9PXX6MOc0FhzcecpNEQqYrLjOFZowVRAZ68gGKtIYNt4GWLnzrPQvapI+itX4TC4T8wfikpnhD6AeiZ5ROidN8HsfUmCAXiHnMYTcV3k+cj1vRkO0AQrRhdYWKYTGd15b4VSiKl/niwvTH8Iq70IrhE59QufM0wM33mpr7lX5smmMcGIEpdTYl5oFGw+ogiI2BE6J0vKdTl9pcIZtyG2mTQ5hqJeI9Ou3f8rH+KvdqxmA8L8/4hfFVp9r9U8VmZIBMq/dJmyQHx1uGJsAKvkoXpWpHet/JtiouDL4110ukPm1iV4Bb3WEu5YWufJilki/GkJRUUfMbJCrhmktuXyG7LwaXjnSUWl47OaoFwpOceLApUn8Ub8nsYH584L4lJQoJ5MrkjmoD4DxeIEu/7T88Z6xDY64a+/TvKBALxcJ3gCfE3gu1Am50mhzekVvPMYiX4gyyV20DMxJc7IinUfoAW2POgiuwaW91zcU4lkX1EJAWgioZEBILSfunx4dQMJlGd9uvM4MqJHYhUAAusFWxmmdkQCAeBzGglGiFf4QyREII9zU7A8AjBSRAFhctpfmeakfN803nT1meMCwrU5FxrXxTZT6NVlmKtmeCScs9HUGU1dnzV1/devZRwKjGB51JpCVlhufX0h8RwAQD8YTjF2ij2y7YiG/mKYac5kzOwQWdkyfo7Yc+Q/CRGH8R9iSiXBZVLEZDnZIAc+OwIEkuDzWUkdY+ZFW1MX6temZUGb7GrFbEZHfEzRZOXfY/i7NnNTNFvJ1Bhbd4/MtMbW3Utbd2GW2gETF+vVZ1j/yhNWGHh3ZrxqWvyWo/1VjDk/MnqzW3Kcp34VToqDgqrbBRTWBtKGS4nsW9YEcpBm8DhHVHlLCICCxmXUk1FbOreEp6xokTBBTM3UPwrbTe7RFlPh28RuUoxEVeRe7Ftm4bdE8JUJt6b2gsi3mrKh9oba938Rd0ztM/vDrqwz9jVBDxDEzcIdmGIXohqYD3DIf7YQ9sJgxSYoRqmKdhjCIPrSswG2nN88dxWvWWoqrdBIHQF0SE5risCT7o+tMAzIJBLzbjdWZhQ+sOM/ea5vOesNnBqFD7yMJi6x2w8p+sPF8x0giuseFAixQXKsLo+LjBNq8Z1cQaqpi7ifXOsOmFB+/Rsrhk4/cyHB+bK+ighmZMFhq1AVIaVdLeVQEqZfxtr2imtNTJRifTf5ZvmK1uoodUe2qI2SbzVqqUPksQyjahhVw6geI6PKgrijJYw/jhmBVsPqRmIvCHHygGF1/kT+LVpY3hDOCiuszHNMicuollF+mq/YMeWDIj7onQckBXxkrplROWSOc64IwbxPTwAcJCN6D6469z/Aa+5Hd550qfQ9FqtuIbqAKzoln7CDKGaJEKRleMgSRcvJ0TvvGfEeLZfELo6nEFx/ij7e/MIuEsF0gBaWCxcGVEv+E/IDNMeWg4PBnSc7s/8dR15IXHYlaWgtlgOEQ3v0HIkaqYwtJfadd/+RfQzi333POK/Ie/D8Jw/aEm8aWDQMIjuMAiwmzKkkBJyCzyXC9tzHFAXWk1jtEH8SrkXwqshzcOCuuE8VTHV053H1rWRYIZIfg38aNH/EwcQKyUI0PgWUS4ZlawR+STBczB/60yn22E/cJ/C59FUS6QLAn6lg0bk3U7GXP7D3zFWMebyyXQ3Qwg9A0ZfaK7FBI/R2ju0H7lQVq16fiOvYVgDm0gD5DMGF9yJzAwUvPXC84wNCEDVwkczkqc+WkD+G+Ytwy36XCRPEMaeetaRzX553LR4L4nDyK4Fl57999Mh0xf/5i285/F/Xgf9IKPE9/udbH9aMqefZdRCq/Nz0D16gZdzEI3FYctKWI6kjqAOuMbn0GIcjdu+DsYh5bwz0lfEKJO1o6eRNRXph+yNr2kDefiTUSNtrSds7M03xYyHYrvGUYBcsPmw6tU1VIFTzcRAfB7FxtmWs0n9CPV1A2bSNPqCHoqzRBxh9gNEHHKM+4OD5/IPhoHfAEHM6vobh6pSxtutbr+pYriqsVjxs7Ck5uJALAYJjDSu9VcMVKIhObfqo5fBSBHsrpqYWKwN3V75yzFPVjzOp6o9QeGY7vQ5SCCrXFC1kv0rIeCca1sIN2ZjjhsyiwnTFBi722s4t5NqdhVwYwGkAOCN5uzuPulKQR6rbmRC1tu6vpt6vVOfXkleBrB4yAcPED+do6YLRA5j32Z88ev32w9X/uTh9e/PuRzTxHWYK+elPsmSZMxwcYluUDLv58S06/+7VBVpYM2KjyQpc2J/dn306n6KzT99O7p/DsKdMJ3k/mv15f+dNIYQdkk7TaDoln9Az26KwOhTyGoTkET9nUfCYMFkYUk1ZLrJcsNbA21kvm5WcCX0UBmQ2EyIzzB0BZv0FEW4nmfjOigffC3PMnQeNBtyUldjKKMslO0L8qLPIeUi14Nl+FFgzniAAOt55rhXA63hfnl0VxoJ7AGXUnqwVenV2hn79nr/btpaIXXPMsztAW98bhnM8fCIBRs/gckPFEuw8R5T8iQeI8lchl1dD4QlZ7jwxW9sKAlGc1nLRT+R7oDUOToZhO7fFTCA9JjDJa99Oh5d05dlDbh+Vr+fG1nzqYZ4mgxnaSMgWmtn30P05y5qBvX9GOMLqIWK5Y4Td07rz7i/OLu4T9Ic4YmShpe+6YNb8ePPLCF16K9V2yPP3slfimWWv7jyY7zzwPT9SMiboszXkjH3nIFs20mzzPCxWEJ6CBD6U4lhd1WqiessrBuC+w7LxpRqhH/jFtgTqpJFmdecxrJA4BLf+GeSGn3lEJGJWwIWjzp3HYScBGZTBmOdVhuH/dfqR4oCeLvApWFZHNCSfLkazPznZrK2G7x2ncnF2kZ+pcBKQ+ZS4xUg9bsvAZ2G8bJE2OXNxk6TxO8tmnb/IT/6dinXi9uFPNmO34PosRHkgy3X9J/DSIH9ikb6FlTSA5ChLmdhGGYrBNVjvgYmfklkUsGIXCwJeCjLby2tA3OfIouKEDif+YgK5YCDs6i88aDq+9UCskqxReApuBpa34kcD7PwyexOFJC40mixIKF1MIAnPMz9Anu8NASR9159B7kZ3NVQpBkyaH+1dspWGId648m0kec8Nq+EEX3P6WdzIlj7lvPdQOLNU6OPEJY4bp0/Rte+yFHYphIIkpBK9JFl563sh8SIck1lrGnLGEK4hbD5k4HfQPTwfs4djim3fc+g9crBrrRD3suITYY5g4ChDwJHKD+486Ram/EyUYjzMsyx+JxQyYS5r3PEJTYlH6BxvM0fbXnBm8Tmr/eKcITE2GRAvfP2yrmJBVjnKnr7NEmrFx6uWUuGjOru49oUxjPfOpmsM4/tvGK8oYBCGkO+Jlu/Zmd5LUlrZrTC/uGsYPQu8pm8tj4TkT9Bb4GBBQH/CWv4F+QsSSpYfeEvui8uYUVq3vJeE8TWJwOBECmm6JdG9OE+4859+o1B6TtQF5w1HxwNXZhjlL+iM5Xmk8QIpH6/sKpclTt68OKveYhpqq9wle5HhCFj7ATeUx3yhbg+kUM9EJaCTbuyzu0z77AY4DFZSaovdd3GZ+26Rv/G99BG+R09zEOCf/OAB+B0+CyZr26CsG0ASUZbxDxzrmaKDXxRI9+vPQFL5S4qRku71wkVArn+FgC6ng56J4dHF6YvnBQeF88Gd37aEV6nBhhRUnlMxVOV9EvYrvhXx5gwS7NFegj/21VOhN9YDIfZ0bjtYwummcEHpqeU4TQ0HluMMkyHSclQAyaaThzzpcGmCGdaFihRtSlfpMlyacgaSBXO1nfj8Xlkwd+vEqyxlK+fd3WgN07M2sbsHx00bkWT/RZKMlaXOZIRPPWuLHc6qeX6om0uN2rj7ylpsilNQUHMTmTxUhoGPcS3ivJryDiI3nQwT0yWly9AdpWlZZrqCXpyJ8CR/MEK/MX2oXGhgINJxooaByOZ7i0P6mjIRYj/jrdhumjpl2tVcRNFUDQfRQ+JnOIhD4yAUaNX6anjRAjIJSJBGV+/Y9OLrqsT6AOCP0DsoKuXZPEMA928CsEb3yZuUgkag7iL2nHkxEeHvIhreeQkgI75DiJXeBroS+FFIvFlKSZScrXhBzi9evHylVwlJPaPmk8FNRMTVKySwWBW1WI2VdlpFZTpgPP9OfmqQ8sVTkcpBLm5+JrrvraFkShFToVdS56c504bjS3F8YrE2zu8FrJBPUz6P9ypSE93gR/8BN9MT8T4tFUWGqzNqIcPU9ZkfMUzdoTF1Ri20eyahnlrIwcIm+2k49YMZHopVGzKf07jS2gmrxxiTf0h0xpJ2kUfsQlFUoPigjlHIOouwHq3HgDwS/HTS0NsP+gzTX59wH78QmiNj6bbp8wrt47rjRfzHwdcV2j6lH0P1C1ZkxJD8Q6RWhuTvP8kv2reOLr6pLrQtHoBXGqqk08tCSkyW+VryZDn0H3HAKHjW3f7qGv2WPMtBORUpRH3X5wg9QJe37weZZKEIzp9Uk7HnrCS7t0rKzQuKnNTPZGHwHrzfchxwBBuhr7/+lZVE5zoVRJbZqu0U6jr/6AdI3I4Buo9X5F/J8vHlX89H7P+4K1nq2eu/Xpydnb9xJt++eXN+vzVWoLQWOkw5W9S6OJtFqt/r+v1qcxrKWdhUGWbx17AuJ6Gb0pHUXa6/mGRpispup6js1XWfCsqSZQdOicsh0Jzi+rGigSQkvHGWilzGlvyra/SLaJLLocSyZVsIhmDor3ZiPyrU4RkezUZAR3xvtSB/gnVo4oceDm2bJcZ+sgI8QKEfDNDj0gM/Y+yB5eUTwfQ5hHQSirDnML5QUhQaC0/ImvhRKOxN4u08rD+ZFOEpyuiKhnixS3pRG7/zu7ApGE8eDJsieskkDbDL7ef3zKD61lAdDuLO0TwG1/UgfUGoBNI/LZkhU1+6NNdUeoblx9C4iP2qaZQ+hZcQZ08hQz6YFkUUuzB3Qc4TEeOOLJFa/3/+6/+jcc0ElonmJm48Zwo9KAiA4ybo/vz1d/fo2Xv8hHjBd8rqHijPv/mGP3dX6BZj7zkUT2CiiT9F9wJlxpbj0PtB8rfQosJP8oDJNiBYxL/JdnfeE3FdNIGKmv/g6W9EWo/7l2dn6HvLQeJD7lm6AYpVWsfoThT6oOFlYfx33sLyWGoZkKOmcHX96RS9OEOOtaJJHPGKd2UpZJwtBg8XEanNW1MF3uYOXkNnuNzJ3RShBDSRQw95tp4aDnDF09soiTTaP6NCPSQVqo6V0a2DylNlOa5tqjpbsC55EtwpT5ID2k78nCjxHua+i4uFTtmCmz5nXAJNuuXMiPEj5D95PBEUS7cj3l1gS9T2in0OuW8hdkiAbfAvBKmT2ARSIIWBBWnmNEKhjiIkTfj3Jx8yVuhyPTHvNj7yG6JYyuTkv8a277qwBr5XywLIIng3P73NpO+5FeNDxpgpme1YJlCPfIXNYFDA4mevkmDw5c86vp6HcsgW7B6wGldFt0nbbYR+8WdMy8+yIkquXySMRJJfDoOI1etyBmgShez+TSPXVZtDokSP89a2H4B3CvHQzcUIXU2ZZPFE6BxkCf5Y/zrWYxDLD/Camwv0gFfo6t2A/ZdiO8Aht1xMIvsBh9z5V6iB1Pls4N5viXPW3m4RqAGzpXpG+lwDRPJ0CJ9kWBOeMZH1+UWYi/IdP95cSUuRdGeOj0ypGePLpheCs+cG4nQQt31Ua8xMnH6Od1IkJhMOVZWQyNvpIfEde8ZTrcqn2ZyDrAXTFfO6WuqRBmk/gdIF2Dch3+zceuT5/nieDEQ8lgwDBZHLqnVNiQelKS/Ry7PvEuEP2GzpXCMLCjI+B1I9ECYoiny2Cxx2i1KDxr2V3eghc5O6WuLmQxaNlbz2Z99pxHPfm7rEDtFwyPdb7usckj7qdpJtEdv1CaSUhJPioCkJaLgz0DCQtitIE3j0ZVBP6AGLmxaTwIxSAkjwWI9GIOGQkOYjjAxWGA5hv4Wgsqqb2YslUu5r75bIs19yvW7w0rVsEZ/I4wMDECZkZmCusBUsrp4jICyBqCUlHTYeKPlG6JIVkMauQ6WwApqH4GIsxRNJSwI8pJFQ/KPfIHFbqiECh68n2Bg+Txr6kLKYZxPnpgkPMXonwin7hwD9Fon6zr4YTNoJia+bZFko8rV8QBS4eR/O7I85hgAqx1+lG2i8OWN/TDDQi5AS4QxjwRAq6sh6RaqlEioZEPrAHD4pF27gxRKVhKONw5OgZ7w3++FzCSufcZ3Mh2DDN4U+S6mLouWoTsrhxOCSBIPPw3BJ35yeil9Gtr84ZV9W36cnu62bMlRGgTtWz1cTXqd0nsZi2Udjm7FY7rXFMrs13GslAWqt6iIH5pT6NrFiZxWmSYLyM8nUWviu5YBE+uKM4SVjsbeptfzMqu+ev3olM3GcfMD23IOyFsyznXVh6TLOYdGXOEgGhV8vXn+B5QJuWp43TaEZ4LUZroNKhlWb9f0HViJAm1e3GsT16T3mPg2L84nIp1I+SC+35u3KWwteCPR4zAfIcaSS2ic0uz+7DlsG3dhaaheL5YqJX1l7yYp3JwMK8YFRdk2Zk7q0A90l22Fq3RauAjkGcbdSfRS467s6Ps19UuxFwJ4OuVmQMdHqDzkG+ve//XZ1i27kw6IKwLxZgGeEhjICGzzKefYT7saYkt1FS4hZ9hymMBClhhQWfHuRya4fOVM/sPHQ9zBfkCJOmX/LBuKM1JXunp/VfqL0Um/I1Wpn2oqjbTzjlOcgl6KHVVJ0C1RInfrdIgK/zOtAwqNPbMEaWqE9zyOCaD6cEFYFaBj6s5mLh0tnOox7q7jwgT1H1+9+RFfJ8wylYm0oayQGQfzzGThkMl9u66LDFw5pNKGwnxtz1S3nS/nqlrDHUC2RhYL4AXIIZf/UL6OGXa5ffE+zi51nwUyvd0O337IJdl0MrWSim0OZS+FS9z2/dxw37Om1a3mXKeD4fDKJKPGYVCUDXkIcLANC4xCYaYDjfy8DP2aEi9Alzikrbn0ZxOgAoQRyHi5OaRhga1HMhMxw+PeX4vvp96vLuPfPF7eia86d8ecLRONnec9FuC5T4kIQQNKSVfbdPs5w2uVaAR4+XIyhDggO6PDhYiihNlPSSzDZJfq3H9mXUfXTJituaIGjMYMcc5mawBBZkpgxiiugLqxPv2BvBvLG+cW3THUR/61Ocsl1BOV8T6IBEQUgmXiaaENSA+Jg3HbQi1dKrZnzs7P0O2oxXVexy0iigHBXLOoRO8pCd8zRyFMhTzqc3ZsanFcyXTBSMaMF8dhsYfvV6X4ZnLyqGAEJbpuNw3MgdYFo4qSPHy7GrPRFF5DGEntoMS3DXU0wy/9TBHgPF6MEPlq6jcKvTXBL+IDGm1PuJBo3G6G/ffhwDdZQQf8dXvnnHrQurISiKEo1Qj94/DnrIMCKQtzUHHgbW5gyIO8EDzpjUVMBmREPHB5c8Mm5T7fmWSJsP6D3iFqi4vIToXiELkPkYgugFgqLe8so8eLhLMsWc1nWQthtZbNMTYbvqTwQNw3TWKYuqYpL0i80OSWbxaX2mMRmymmSMlmDSu1RqdrtM+G5Tj/zf1T5e/LfK9Ds+9WtHEznAFoMbLGHaNwkw4oh1oKfEtGA6aAdH3NnTfwJmDrLpb7MwLjFVHUN+TeqLNIG385fo0BbazCRTpftwKSL7AKFH9km4UCtwYoMR2mbVavXCBlRDlOs847D+fPq7T8a46yT3CCDs53gbIUvarXUWoSXoDYtBsvUU+Tg0CKuAbvOwC4QZop94J3EXM2t7vBWSy9Yvfab/dzyWgu/2OKbHTvOKrLdb6KgsJDmKGZeqnQAh3YOPmI5gQzkNy6RQVQeXoLFlwRx1l/mv0pZYRFrAro8Lg1CS+bnuhggKpTK8UNrZrHTxlxgeati+S6AU+L1VMbbPTBtW8Dkh6pzAVOUAN4DkGQzNRDZIURWe+jqBcxT0DHLtV5H3a8g7G1qyHxWA/Ux99axfY9CFSbkWrOCrAb4Ebxu1b6I/T8Wx2eAfBdyxoswNPSLxWopQRDhQuD10qcsmpAOmHwacI8FsIBbykMITwRbERQAtoiL/Ak043q4pehD0xNJ8u+BI7HICBh5SdI919JFIhw36FbB3A/aDQdXqRgyBvz08B3CTrLVQ7mbcuU3goK/+h5hASjqga9rDfgV0iZ7MykzMFykEeTfIMAS/HwhjmWcYNngYxU+jmgGeFrno2Y16ieWa3k2RPUs+EaP2XuLQVJeMOg9lL2HojOfNOU5X9K/5SFSnCz0k3yusZbKwCwoniCa8+G2hjTKdxJvpsue2Tzhp+bzO3dqyMw7tRmq24BMD1N2jcvm27WPQ2beW3Zy+MW3HPS9ONXZE9qRx1Tq5tBR7pq0tPrVupgyRaT6qzY9pPrl5fbA1L3s9bXcvARUduka5zlUt2C78MC9nnJpgc8v8pO9Bo9cmcDiR85RDtENnuIAHJUT2E5bTHaEFhWpG7UrbgBuawBXbUAs5VlOP6f+rjIt1gJMkV+mGDCFCbEcMGM7YxE/U4yb2U/aBHpqIXPQJ+iuwkzdLuwZZv6qngfwngEVEmV5P0AB4Ado4QcYLX2fBV/0CD5LF9/A59bgs8IuWAvv0odaGPlSgJfe5ndxi4wnKA7BTID4tTC4tyHc025GL4BPqw4qna1Biq0hRbmtsRZQsL4lfNE1PK9giy6XS3AZZHUEWEkBMJ98Er7CKZwYxElx4BHLiiMy6KDErceAyUHIv5qT0wtEO1jxt2zBDShvDZSxQ4rzoNXCZJEcrRiUhaNHOSr/6jtkujLC6qHjrO4wGKDdJNCWrrhB2q0hbbUfSVM942kgT2LnltOhMnS5DTW5Dnl5XCaWlQUcA8zzuog0x/E7WKM4FVyPYL+/cN/c2qtsVPc5NCoMv/LFtQT2elPvPKnGkUPXKHXjO/bvaIlPaWQqRqLafhx0V9k1Nn3Ft3el1/DiOK7LSwuz4yjNiTd7kywPODleg6klTp1To2mXeXX0CLEp/5CsZ0iJT0ixN0j+kvf6Uu9MTMMys11Lj5Ct40v94peZGRpwqQUuu4OMth4Xigy0jpdF1r+ixLOiiU9FtaRiZJRSE/6mEYY4tdL4FczKoErPUWUdR4TEBaHM+aC920FdqcMgRbnHQdZ63yNmpGiKBjcORtRZw4Eh47pQ7LTQyl2hI0eFY0Od/ZHF0sbyHqKffoIG+3rOM7W3/mft/iUW/ya2fgNS+wtSGUNzD1GqYIYGpnoOU21N52mF0ekywI8EP52wSkAttNWiv56J488KMU8+Z5EUIi9xut6jlBVZ4H3OGC4zX7EKajwRAuPu2Khj4siS9xHl5e65RZ2/E3sOq3zEa97zhE+iRj2kXDOc4R6DbubcbRx15Ymro0krmtsR4e3G4HIkNmILiva13YwyDkZ1XIs25VRkoG4tR6IduBCt4zx0pG5DB6SO24xXEg9nbYZlrA8HMhkNm8Gua/FzuScS69xXF4VBFg6L60/kq+9dvZMV9+T9C30WTAzWD3uO7QfJ9M6x5UJ2qWmcbx+YXsa1EspWKF+wrwlc8eO5aYSSK6iUrq7tEZWe4UGDEr8We49I8tJXO0I1MQ9wVOG2gTyscK2qHlfydgHkRYsJDuBaxQYCNmY984BYQiuAsH8HA1ZNVsiiNvZYXcJ7+M77EboRWfhUHsyaTrEdxuiGbqPl0g9C3oiGludYgYOW1ox4PN1fptI3HSBMWImve5csSHh/eu9PpxSHvOKGrIZzf3rP/tNX+NxaoTTPh3fyzvJiNhPj4GSN2W6NNYPVL5WmHNG+Aq5uigZxd6Xvq8TRSeQ+DGPDRAM9HcdS4VIKf+j8Sa/57yWpxST7cdQAw9i1MZSiFblrm3xEqu+XzGK3uvHqCFATmmfbbjiY7AU1txkDKqpMN/2+TOcvgxPXCkkY8XL3DQaKu8EQIKHQOXaA1jYdJ9WXDebNWk0o7vclLho3Fix6U/E90xsGFCJFKz0AXLhkjLFAs1YjxQFjX2T5+EbDsC7QFYeQvLXpwsTdYIh1ybiOdGeG5XUf1xlXjPBlcMI3c0xDjIPmxzTbOx6w6RLGZypTS0b+Lrb1j4ae7kAatsbDNKgrrZue4V96y780VrqzEU8/w3/a+bVzxkc4tecYH+HPrGV8dO7s5fyPmOVx5lio6dC+VSBp5tVuQGQ/QKSVM7tQJvm+q3VjZ3vf3Ifd4EFrPFBXvI+chXZ+BhUOQBndxlU9q4suUEU381CHgdZ0Tz9qiDHKHlnne2yFbQdURoA1tZzfPHcV10Yx2iSjTTLaJKNNamHz6iVTl5+dYel6K+i1iMDhfJoIv8kxaiLGQcup6QJvjHhneC/Dexney/Behvfae0ueQvz6yJrppmd4s97yZo3DDjOWvFNOX07aOJozLT7vX6zM/xv3oy7X6TM/TahhGzJeTzpf09AKI5EPU2r9DS+4nqo/vR8bRyDBvsjjUaXoL5idAaA90fePBJxUqf1bw1XL+GgBWCI4Om85EFGgWolUDYuWyMSDo3sSAX3UoLd/YdBb4fzaxEAfJc+3Mxxc1werfchzJkywNNiZnYnOI50NE9eaidPtyubRhJ2YNmHORTM9FnjZf45uM9HNnOScfk54oy8NUSyX8obzSVq+7kY+0oMX78mCBDk75kc05sviuSgZcRIgi6dfAmdxm00imvKWPUO09CZtkzOK3LARg5SZ4UFj2OHkaaiThaaZUKqYwrSAlQYq0ZozXLJrjtG6iR9oqKjlAmMODdDCWi6JN9uD9Aw0mjjkkVDQ6tu+g4vzNDSBu8ygY+ui9KXwfBvvZUserKrfmclJ8eQPXRyGOECWu5xbwwskRkIwEpr6rus/cWXB1e1v6MX569fD83zmicEJ/mQtli789PG2ES8pDt7GcZefX935aZOcIjvrA8HiNAZLTNh7CE5QrysGUox4+lkcqzL+UQ/HMyzROAXGwBPeyJ/z7GJsh0jDcTEax/PbBBjHd8rB+8b1Jeu8ceTRzLeBQVQzUQM2ew42zdg9iq3Abmoi5Z3kf2K1WAprbtlDECvih+mzJxqAATS9pomerf98oOSBajFE4ot57p0QB4tyXmcZELaWsHBTC2T8Nyepl6e0F7XThMELuTYzVlyFPiKe7UYOHqG7k6/vTpRf0MQP57xxYLnslPM/cKAMAf14N6jCLLta3krRkhJv6gcLdrbKP/zr9CeDl1q0gGt6MmDP5GTif+IAXFSShYEkRcVLIl7MszWdxO5ZJ2/OU2OInEf1x4mnfPFqcLKwPolBz87O0u+oRUKy16cdIcn6Pqo+PjSybUzh6OAg4AmgF5hSa8aOk1A4/ZH1lxRtG5qV5LhflHe0H0LOPLdov88xS2IFaqzL6ytkg2z5ZFEkekwjNbHdxPddbHnq0eOYIY4b/PHHF7kUYzi+jVmYpGc8UFPhjAO09I7XkvHCw3IgxFyvxeFfvf80ne9wpyroCO5KM6IudDhpQs/Hyelz0vvwUTTKs5Z2FATYCxEMiuSgMXlHbHSuEziswsD55dm4HJDaN91nsMWuJRSUTf+QAeUAxAN5e+S9XQNPZsuIzk/DwPIosG24pIY4aBvkMMNklKEYZJgaJAcmmad5fRhlKmI7oqG/QK4/S/XYHW6wbxu3NHKnPmED2MAnp7xl3EYRqZ3lBiCAz3ZrmgH2uvS5K775s5QTtD29xsGCUNCV05v45HyORZR/cf0ZfcOiyoB3ZD1cy7tMXfLPJxOwtzIedmq5lPGcIQ6WAaExFzoNMI4fLwNf/PtLV8DBVmGUuX0ty4zDr+0gQCTXUp4XZIekIj2kHgf6BwPb8N3L33LueDUWr9e7753nb3t+F7YMSrWLjeumaBDpGBGpjo9hnok5/ayev4p0byKlW11gG6aH1mWBK8M53gRwTo9xServl2ffobe+N3WJHSIyZXo2yw7JI0ZiXugf/oRmPBTVoXaKj4mSLbdg3b0xPXTLTHJbB0R+4nJi2tl3GkCUB+B//uu/UxMlysbzHPL5o7F1qCxPi2dQ3aB6rcR7TUTNMjhm3pElWPwTBrEzzsan5zknK3T1zkBpDWN4nxnLovkZ/DlG/JGJ+3TpYJZRN+AjwtDL8Ic3oalUfkVc4e9z7KF78JO5B9ov/bcHjOm7/bdfhMGZUPRouQTGdZg2ksvTjziATYbHnKN2ciP6CxKGMKDvuSs2KiwWG0OZNatcw0O2nRH6DfqwsjVKk3tku9gKeFma+LuUBkcPprvRGvBdK9caFGd76DO4l0zR4Psx4nudnBI1tAanyonpmlEdyrFLGFaUtEkfeLU6WIL9orXINpGmHiSc+1GoVgSjAxHfTdXkFYJQ8B7oXvw5Js59unlSUVv2OGJQT96erFfWoyjjy8GXz44J89U7NWpeEOeYJOc3iMv/PDx/pHNYIl6IZ4zn4P5Y/KfXL9sy9PJwbQX7xcC1vVvLJmoowKFSgFECj+39ZOuQAXHnurGNZ+lAPHiZzRwprfSkQOLCAoeWY4VWngoMQBIACJmSgIYj9INlz+Nuth/ws+yIMpcJWeHE1OA7N5AuSFgO7b9yn1ClTqjcO4HwUeBVIHbsY3p+lvIxbeFhWniQtgPkkh6u6ZeQn7VB9YNFdQXqOvVsqs681MjBQcara8P1y7Q+P3zCdsRNgACy6jG3ZhbxqBKjRbxlBKyM7QeO8MpPePCkp4P8KFxGIaRtIhR4Q4ulnsMupjTJywQ2JM+HGuAzpkOChaYhLon8P3BHiiSSvplORLPN28HTNkmRjFrkmOCzDDUlYpUDJz21Ivj0QsdyeAqQSIePF0OF9R0mT3JaDdEEsSag3abo2d8F73nxvMgyF1c+T3pt0AUsH0UVeeSfEUbE4bmgYtji+KvMoTjMyXr9DT5/6VjWq+m3jo3x5LvzKX718uV3E+vld6/xVBv1yv6sGe31I0s3TMFOqUyKKe+VmVlBYLEQthAvqMJ0ihnDicCfli6E4Yqs4cqkQsHC8Qw0TWf1pMTr8LEy0TpQfd7zw7LZypuZhDNJUPkju/g1PoV1aLu87ANghDrzFe5LA2nxHpwIlkFoKP9Qj0rcuNEH+UJd8qnN3ohP8oXa5FM4uvOG6N5akvs3LAWksmFLHAhmI5wHfjSbywgsniySSpWWHWB2TyyXRyFCX4gX5FwMduJXALDnX2NF4Ry628yE9QRqSAu9df3ImbpgfPrJ9SeWyyK/fsarZDAG+vWG81hv1oH3dyw6r/vBylSg28S3AvFJPryr7gx+u4zCuToHke7btuovi4d+Y53Q20v0wNaixpG0luQkoasDhQIPTuCDTgYn7ENO4vzlfErps5r0b3pYOXFf46h+RREbA1mOE2BKS+9hMmGX2Ph/ib9Htr9QNaNyTk2/Ja/mbXTnrt4Jhl0kVcUkCWwUMH71DtDxI8WB8EKp/tJz5+LMfmFN8fk3L6fn305ev7z45vzMxvbri+++tb5z2nznciwWu0kM8tW13CKgAQHOUgDikZBYQv6o8V3fjM5ffzu6uPh29PpFi49gh7z9lsWQAXvyBOr5HHgywctD8Y2CrWN3qeYHvnxpO5ML/OI7+9UrfHH2wp5eXLxyvnW+vTj79vXLb1p/8xrsRPLVzBtgI9/9AZSSHwQENf7CtWi5H9Qm5YKxAoEppgBjy1kQT5D3GRzlMcXBI7FZOOWKhhhgJqIQup5Cz3isBp8LPPDY9WeNjjDoc62ENoNbyWSFSEhrw8n0/JuXE/zdN8Pz7ybnw5dnzuvhd69eOsNvzmzn1XTivLpwJvkPgSVZBphRq6QOTcGn7cMHlUw/sJ7G9nQcWKv26BIL5m9/RDfWqvbHfIu/dZyL81ev8fTi25fnLxtPnEuITWD9bx8+XCPejUljahx+vUn/9MOHxvPklRQq0rDlJxuvq6jEwHKSMWEOKJBqQa2c9gWkeMjo6qtmHQWk9YFgKin08eaqGzFOBmSvdUZ5SHf54WwxpWXgO5HdWIBR1AJiigpzLsZEFqW+TRKuGZrxMrpO/EX1ju1tGGBr0ezkyi9sQ6bUz7Mg377Paa/QSiQpXsS2yK9Kiar1Pu3vxMF+uy+jtt+aAsdTZ4MMBKyvQD+tag3iZsBnZLbTgqy2YNxMlEIDZKE/fQ8PEDOBLjAY4uicLBuQeSrp9uAEhuJ5U+Q4VEvNaaP1E8dzDBRy5tdPL6Q/+76H4WMXPjv42MFTwus28DsgXgIFoLnZN/NghfCnpQWklXjM+mtHAVtiilM50eVFBR/TCPNwd0LhQPpesiFsNJfYJMx35MWxRuhXqJ+JoZwExUPiUexRAvEr7uovKPIePP/J08xeADZ6eXYGcVJLbLECBiMQkPiZl6ui66zWp3AItaFeNu8lda3iu+rdmT9x4IdBRJuxcXCa2kMw9O4MftlU1pAN2GS4k3AhxtZbyrRY3kQESPSlI89vTEDAJS5PRDasQu1mov3Uqna5Cf1VtHb6lUb3anSvW9W9dnx6e6WO7fpm7qGGtoMl6KnitrvN3XNd7iYWosfq3a4v9T5qfDtbAwIwVROkt6L63aMvq6sD7u7A7lgt3N2H7FxpvIE92ZlKuctv2ZyWudMV36ziubup9loB3cVn9lwRvYFDd3y6aaGj7G4tN6O27Hh+O9VkUuLZOT1sNihmAWbuUC3MLCorg0abfQ9EeMG5tLxMlC4L4UqJshb7DfG5oYuz8++GZy+HL87QM8LdmHHIqzZ9/PD2ORJetxPquxGE2pMFpqG1WHLCZ/ss6z+bx82Pb1+8ePHdqNTVNusvG4v+DlfMJQt6cXbxcnh+NnxxlvKUneCpH3SwYL7rHOqCnacWzCGBiLuqXccipIj6AcveAcrDoNzRGXqnSjqIHyR4iT8taqfLOGhD6spM+iKwzk12l1c+UOPrmAbPjgIK2xCGAZnAJiysVVy7HGpfhODWjlFsB/JA2J2AZQrImRyVTOFhgFnqE2Zhi48Lm4OyLHGViITDe5UK5zsrrRmhFGNjU2+yKuJjuajuLy1GmJm0Lj93ac2Ix/JkCI2qawUzDCY+yqk3qIjpCF1BaQ+HKTv58i59sM35HpoG/gI9zYkNylOmHSBeJLQGgpOU9UXZUsbWQzHyJc9NI+fKjG3ydvmT0GI2S/aSMPkivg2y1rxSbAFuYmSHUYAzdU/VSJzi8/pv55Pob8Px+N2//fOfZPbN7d///f98GN7SX3/78NO/X/zHi3//9uz34fSn2aP1zcp65yyuf37Ekf23V47zm/03+r9v5u8nw08ff/7Wmv3Hv/3z4X/f/nr5w/uffvv2/cfXs7/+tUmQvSYyQjHixIE+HcXpWJY1TgdwKNE6dUIzC6YMhiMOr91PtzikaHjRab549jkQLVQYSiSVvreY5T1KMsLnHiT536uCh2Q5En3sEP83Cx0SqpQuIockWziCzRvxeJ/1wi1F1NDpZ/h7TmgIPg1rhBAN5RjZSKKMlIFEO44bCaOtuAJgVo2yLNxIzadizwPf811/RmzLzb3Ez3L9MiQolnZm5BF72beP7rw7D2A69kFgQfjI9ROYFSNm5z1ZoXvi3KNnvHjzvbS2kgW+Z6WYrCDwnzg58v2HaImeiOf4T88HyMEBecRUTpLJLlPBCAuYtUL+mgHz5Qg5kvPFWAAhhC7KNQeeWCDxPWNZ70/vOSt2L14bf+m9AtUjsX5CIXOPpgS7TobM/DOy4CwDmGuX2JY1rLHzhlnt8CfLDu/fxBVxuG0ityHxQKDkECbLZeB/IgsrxCXdn0TOHP0YkRffM2EwLNg/hzjMBAt4aBEPYY8RX6VOFuNFxBal3vYXlhlusQxXssC3mvWFWRw3H/wGmWm2Evy21mTBCjfNuACFPppiYObi3VOusW7iMVMdRWwyDfXFXzQ+ESTvXZOBHs79KwKC+A79cfqKxp4RZMEdn5wMCvCOQ376UpAwQtc8bSC/wEIvw5GEM2Mx85W8Nn2hAIrWkFSGYkF08t2H81dvzs7enJ39R7oespGMjWRsJGMjGRvJ+Egl4xz53qp8LF5aJiefvcx/wGWGDQQWcOpHnrP5mXp+OOSvqinH5/kjI80fsDQvJet6An0mUEFUiK0h1rNKk1KuF6MMlVFy+e7ykrvGib9MjOd15NIe/aWDCZk3uQCiDUUYoiTAKiQDI0I/jjKgMk4gMRFlozmEmC0NpRqFmVQEHEQGk/qp6Grt8VbxPX8ym6pE63+YwdVDxlUNxlVBLGx/4Lun9mIC/56S2UnrSlV0KEYb2ovJUIymqU719tfvUfxUX5wqabLN1HBi+u0LOSXTbnXFsnXU29VEjz+jXT10bfed1ELXLYlo6EWu+8fgBP7DrhC/dF/ql57/o7palGYzZda6DpPWydXeXt468Ub1+9I5zTaYx04HiYqzbmmmOZ5uOfDdkb2YjGIAqarxxFr4wQwPxdngyCRU34xLgeIjEueQIyCIOdMpMNSiVlQlIIIMVIKGLAndvkFh+ps6ZzWUudmLyZi/pWkhJnO1S672gP+R4ozqXPMAOgxO/sXyLHcVElv8sv2LL4srNU6xW3lfRZ2XkisrKyr17dZuJb1t/mI2LfLTZ+AonqLBjj1iC2oV9KWnzOOkSM/E8t66Ltcwga/IlLg6hRJI4fKRTlN0cxGbMoR1HpT0TD0TOz8I7Q4rtqaWz2FwogEX3cFKmpyKqY8V8IFjUr8XpvRnvLpy/oYtB/ClfmeK7QCHl3KIFgOEVhBew+9NemHPadxnEtkPuPmrlgGekk+NuzFblehVwGPpRorbxQPBqfoZr+hvP9/E+bnBPNBgiO8t54ZTi/QQ5/WH+OhBbKYfkD+xkwzSZeJt123FyHSS8JqOGDSsVfIFVo0XWqqEGNkwn9X6RjxB4oneo4z7c4Z+wA3gNxdcD8vgxWDLvmLLWighDw7cDoMUm0SK+Ja3R4uFNSP2qeU8WlBnfex4FGIGQ24UECpbepr5OYhcTKsVue88eh13uoE+P/rBZRwonlPcgm7v3ftblHRC7E2jAj1uYYf1k+iXOuAlo7aTpORqDx3HhzIrcvLtFcOFC9F50Y7CuWskiTJpp3IHO67f0WTem5CA4K1T138KA8t+cAAvxj5otgvh4907P7UsigC0PnqwW8+r/ZBwlKyNpy6NEHboyPHoSPmZ3/4SyJlE7sNQQEORWhOYnNr4wA2QtdGhtPlBYIOSZtGaVfhCwgShlfSeg+8XDmGsEOo77qPGfOjOm5XaZEcXrIaKkUQJARWlYJK5QoGfWvNNasuxEFTIlsW+YYR+jWgITmMTHD5h7KHzM+bkAB516U+5eLXRb2FukdUfwuMAQp+7UaLJKj3JrzjX9ZV2qrGrQqOJFXp75icXN2U+jzBBUAg8u7x9Cz6s7364ffs8M93L27frz7WBM8XuyVoaEofweq6WqVOhqgKIDInTkbhB7vcu+ebNUj4eR1ZkG+CqwRzVS5G6t6yN7sDk6Zxoa+laHwSZy5sWNKQCP2m/H9L8Oo5uhpu9bO/xU36H65opind/x5BXB+1KJm+gbn+5+WqDRnsdwuln+A8M0kKboFMh1MJNKXtqj2oSB5SKd/34kad32T8QVTIJ8bWunCJ8q5xkAbTyLdnA1FlkYjPlx27Rsp3ew4DkYYFkhbZjhvPKjpynVi3sYmEtBrhaAdeO4apgj/eAsyuauUGsg5NgpXMb2G/zOMaLDZRDmfBjqoVmoq0BtPacGN+SDUNbhQweCa9EkLmXS3cF/2iAwZvFjtxp5YeuqevgfiJ3yeQNeO8vuxnJI1xXJg/tpU4mt1zXf5KuiOXi96Vses1MFnVs+fHoaCn6lFry880PR4nZwI6vWYa+S7NFu2cQZvsIE9pLHcIkN70Dw31dLIjtX3WQoKTxQeCAsdkfj83+mAz0O6VXxJsG1pC/uIVd3hCtXus01qFldUzxMR3DDqdkOlN89owU2+G9XNuDIFx1rfC5j4dMYWxpdmKFvwJoENva0P6e+5IdAVoDq3v+5Bkc2y/mu7GdvUqmP/3Mj0I983qGpy+Q6SuQUDRk4FQOhTKN9EGoc+N1bqTQ1eFln+zqO0TB1moIg4G9x8DRUgLMGtb0MrRiJvJKqGKtNBzbAVuduoGpHljR94k/087XANP+CJk18KqO0bwMsaQZvBK0ZEODW+3Yqz4by+vg7GbBQpGY29nI9wmXi6ZsoHk/ecauTOJSEVwtMdc3hNcyfx+Usaup0XuvTN3GVtBDrIjvbQf27bpm7RrG7IO61caEfTwm7CMPO98BQTJW7KNSMNQhWHWM2MWW6yp79TEaqXthmm5nld66TN3cCm1k6L3ki7syPct3NbM8Fxuca5iZjXFZr/3sp0l5TwzJBsb2EsaqzcYF1uJSG7ExsJRCTA/MwX1mjJT5GTg5CJmsjrG32MZbZdk1aFPJ0PTZiLsr0+06Vts+w2d6igZB94sh69omewoGHNhUvT4Mnr5VdGKZkilCR7GI3JAsXVxivSlqeTSaMqZM9qeKxoxjXQc6M6G5t4LAAvMAM7R0pEtrokzL721/Ff3Fx9HgYe/wcMQwagvKNrry1J95Qe4abiu3Ky9ZsR95r2oXltt/f68utHhbqUOLvsvhYGgD95aCpei7HqxsFw309AZ66MpTs8dIJOjAEaYBVsTW6LpIUdHhIHAiEXoX4IlQ6RoBreQU5TqEPprhcIR+Yw0td4T+brnEQY+WG2H6Bn2FPThNzlcD9JVDaPzvhe+R0Af/iLV9J+KTFO+APEh8kkP2dcY9yLgHHYt70M4JOv60DDArgToUd7C535Ah7fuqp25O8et4EmmovTYhhv7glPgZadsfBIGv63YkPnm3bkc/xJghNrehzkS/jbvEvAbak4IzaLBuj8WYzapSTj/zf9TzYqoCTyFS14TOuESF/tgesHUwXvNG1sEEX/vk7rRrwGyn9TFIeXhIWe0aVYVf4MhSE7y425RBrobIJas598CjatfA1Y7TK565Aa8DFGnrOGJVoZrwL6kJbLGTlsG2htjWZ5+tZLe3K5FnxfF23lv7CdWlkzdovc+sZldOXxmhnNfEaCaGl9WULzZxF1SVr+hwOOrM9n4N2y7O3ZlXgynI3XPcqayI08qjoQwfiqxkBehQ2vwgsMFY9411/zit+9sma3Tl5Yq9rW3dNyRuPxUhlZSvsWU/V7FTbyHVV+wssunzkoIHQObqWvR13w+aBcfZiW0/v8PrGfe3XN9SB3ntjfumvuWec/MbMuyz955+FtV3mxr1c7ipt5fqcbPIoG8qHefVxgXQ2mPL/pbRshO7vgHJPQfJhjb9HHxpzKV67NLa8w1w1QKu/hnz94SzK5q5QayDk2AbG/JzUKY3J+rRrMiIbwCtNifWB2s+03LSZDbI95pg8GaxI3daO7Ht7wlyl0zegPf+sptd2fXhZ1izVskLPtjLH13/qUUCgw9vrxF0bZrFoKTf4eg7G5j8y9aj7xJw5X4aeOoNPIX2cgRz31Bmg4ZAElvVGsFInV4HASImz4HxhDCeEAfoCdEPat9FsgND9/dap9SSHajjHFHACuhTHxQfoxJfieJOB0H9jyoJQsle9j3oovoLDBDuvQDUletEiZqmWWKEOvAq5PMm4Bo7VJQc5wPW5h9SmoReQGo7jZLB0kPG0moPizrgBpbsJsjG3S0MrO15DoVeoFr7RAoG2Y5QXK7jiVEH8oQJuAnqxW4ZBvhMgoU+JVjYYxyv/gID5XvPpG7SL6Nm0oUcSaiZeEF3MKuzLxT2Ohxl6pr+GPuTh6FkLw0y9RqZOsvI0Ag8Ss15VakZDhs4jFeC8Uo4Yq+EbdM8gErAxA4yNRgieGCalk5yNmjpos4poej4NHRIOLoMDmXrtnW3BP1ud+CbsOWgkUJYXNNBwYSPHIJMsEnnhMbJHaoBtsTIW5HlofAIH7AKu02AYeE67YGLwl4kfTBYeqhY2sI5QZsCoj66FTsmGGirD209dU3YJz6x9BsMsB2mzNzKN6EoU0R90Cv1SzC414yl67OXQn/UAdpT3J3zwj4hfdVnGLDfcy62S+8FNXdJaIURux1FzHGyZre8bZYvTkZDfDQ9QwzQkWuqAey1yYBoijhV2bkLgnaJtggrCprwd9fmHPOzNiiyFyyj8jOVd3YtdrEUAwTpqQEDouWhIkEtfirHTmnXbbt81Ef9JjdkofYP5AonbnCuX9xSI0CrzSktl8WMD5+j6DSEptxfgXXKOVpd8l/zbguUPUIWpb5NrBA76ImE8/Usx+1wjH1QC/Yl/r74Nnd1KfiMYEHHtu+64kbUdghJzUne2K7ntpXb+Su8DAkvPn6Wiu4lb/r75fuY80h+YTyH/OEDv136H5XbbE+vXcu7TF3nzyeTiBIPUxqn+8FeiINlQCiWp24a4CQb0DLwY2eqTUAEv14tvUQ0V9lyAASX+swV4PJwyR7qjO40aZFxAtn1TU6xHxthIOIbO7YcZ0yJN3PxWLxYzy2cF/ouKMd9c8iSzLG2T4VuXseOLoeKG7W9LJZL5Xc4VxV+ExrI4U1zqCOsz8r2FPhKUKk+T+3lLtmHQe5dfGV2yq7I9ewLqmjmY9DkMNEk8TMo0KVoUIG1zIGCNKV5Wjz4KOwy8DgFG0cFBNvkdrhEWc7pFOtFeoNFmvkcJBb1A03IzPODeOhuIAY7hAs6UT05hx9cgy8GXwy+GF6nQ16nro51MluKZHigop8SESVfonKdzJZc0yrSN8TdckrX73+6RjxfBWiqZSOdDhZix6C1yOUgh1w/iGcHqljNV2/o9vP/ncyW48wOjmF/6itqy2Z8APigO4b7c9HhuuVvWrmmFZ7TMHn/BIdWlfoV3sPVLZnX6XSw+SWtUMbmL3ff7va22Am+xppb25i7KNyLLcNNE+VtyWQN0uwX0gjdrB5rWrAdp5/leaqlu4XZCpVtCV4J7V4NvJJKXEuDVf1Q4ibL0wcF7n7ATvVkDezsF+wIVChicSoElxnOyi05b9kaWPETBpklsff0mrvpHYDoF7mP6FExUwMd+wUdgA2FolGxwhbeIvS0JdAhdGs10CNW3+o4DfTbgoTghrYMYC4hgYYBRi6ehijy7LnlzbAzQh98ZLvYYiCDPxEaQnIj5T2IYs9B98ovb9Ddyd3J/VFB0baEOqEf7kCoKzxGfcTH6skaiNwviBRq4/ZCHcUhQFEdJTLwYnFzHRd2mzzU8F/gmg+t5BAZlmuAiGe7kQO4CE0dnukNXd6+Zzn1AuwQyOs2iRhccmfmiE9058qouiyUXKGNg4Nc5EZsU252B4IG8bncLxhQ7toGWSTtjVYIReGl/tV34A4c9sXeAUOiXN3WrEg/caZsggZq+g41a7Ea9nQMuW4D2/c8bIdV7EaqLbdep7vnbNfZxzqrdapNT0OIEpHr05CvhYefhnN7GFoBB3v22jm2eMbf9HdeTRF7PwPaObbccI7sObYfEO+OiMcexbdu4jsr9ERcF7IYQ6EHOIsOghPK0RqMgf7kH9gOEU9RnM7By46lNgfvxPddbHmNTPHpDdoMdiUPhuLBMIw8D7vtgqb0Uz4ANLtKXSgTPqVCpj3NwVF1KFUxN5ZGO8GXLSI3JEsXlwCfoKeyZQUGSjWWvnkZHKKPFKP7f320XMK4FN9zV3+FVb9HFvNq9Nk7LBex7N4oxk6WatxzVyiIPCS6A48HL/CjEBKpU6EK44oyegzQy7g6wfomMAyc9DaAuBuOVozNJ5TahP88Ic7JHw151oIzuTUKsOCyjDNuSQrqfcbRU4VjwHtWfKSuN2eWLT79nPlF+la055WHDg4t4lawzOhd3ErHOYsxuGSf2FHVEYqRO/9J2/Nr339q0XtGXR6dbfPrTRzpqyd99NhsOPZs/qaGDLv6o45NzzwvsjFrwbX33LnB+GOXCGosrXpABIavF6iVuiLbJj+xzNBAQNBO+OhJzzEQlfoSwfmYkrAyqsueng9ZO87xx3/m2fy3P56jW/FIx9vHz0uJzGXcDgVYoBGQq+V8RYltuciOaOgvcIA8HD75wQNyfTuhJwkRmmF/FljLObGR7fuBA5X/dqv3qc/2Jku1IbCRm99KFZ2f3QEgS3J6t8nQ4mBBWM1rehOfss8n2IsW8MZ/8YOZ5ZE/2RK+CVhm0i97hFoJVKyVACyBIBGHpgchEUlUDEMy8gz4meQMZxyy0Q+WPUcwOlpA0c259QipxSKP/DPCCGbNcEawVD0w5HWvbLWCwILSmawIaTNAga1cEO+K9zxvGLHWW9grnN9RA9/6kMayYhwapNXNTRafRlDG8n/Wi3BL8FDEuckfdBFucntL4tpiTUDMefUxSEVZoz6EuSlc6iahqkXGstzMDEgZkGpYWi0LNOCSrUUZcOkthJhsOJzBl5ou3D0EF+20jhpZjNy3Bv6U167Iwo+wfGgRSGg8C0Ho2gpCAp8Sl8WqgUjoN7BXgIQ3Jdh1qHAtx05Wl87MpRCHJ7W0f0G+CNQTPQMwALJOJEgi8h4tN+qLF9K2kG9rmVTk98S60EbK/h6Cb9HMjhp/DWfXjQEgLX6eBtaisrpGgVFgyPsWWgbQjXiuMw+wvuiZ1OoLWwds5PO8wSAecsTHTGwF6KebH5Dwrhugq2uK7eTPlBVlgPwA/fr2t/fvkUu8hyMD40Z2iHiRNwqI7ASsZZHIzPOA4FFcHeNso8XDkQSezdgZNLiW0QgXIJu0OJRhG3d1jPHsqECoL2YLBj1j4OW7MWD0GC/LZ3qgiHloaLamiYHzeKef2alfz+TAoLHM7sC2oY7xAQZC08BfHCMaKvXI+Z70ysQBW7gNMFvH2JGa44HC2FG4utUGwTVMGHnUSqm3tZCVNWZwvDpO5q1fcJXbu75hVfEEDVAZCVW1iFQydFxy9IMSDR20GSYNhyLze1Ynl4yk18cl25M03R7AwfzHyqAq5jj4kdh4zMQ+8TIWcZL7EJGdLVkLNFkh3htBb23QAqQI8mYng1hn/Ovl+8uffnh3Mjj55ertD+9vf3gHYce1kOm3nzu72GxBpO/zOPkkfUkH3WS+txx0I+IfOp3VxMrHJujqh370rCic+wH5EztbmMGL/Ax+9IMJcRzsbfz1r3Q7wKIXwDf9FgePOEA/BIEfbHgq3WJ9Ahqtcb7P4G2roNhWl5jF3zgffl57KBuVFMnQwPAuUXhbhtxCuBNlMpoGcm0DieOpGSzuFRa/PHuZf/17P0Q/+pG3ja//TqOG9b2pS+zN774hRHsgNNSjO7W1vvFop5/jf1fqebNkK66nkFftFpKtRK3bM7KlaEeUBenwbVGUkMc+0CK+e4YWGVpkqMFhUoMq9XcWz3keiYzGuxDJhbbbwPhuYXyGjW7HYLjB8GNRLVWERWQxnTkwq6D+g0PKUB0eU7WCkD8tAHn0q7WCfEARxQ4k+QkwlAl5JOBZjSzkEhuD+eoBr46GHuxS6wUb3Uudl5iYoVCGQhkKdYBSBqMwhUkKs/QoLt2QD88rpEkyI6GhSntHlVom1dsGXYqnZiiToUyGMh0gZaod51hkDTll0YBBtCyrEpSmcMOkS4Fb1VUyZkltINZAOI8aFdsWKUXySfE2GAcqQygMoTgwJZsC1J15cqngX+zTFROAYp8uLyEChgZsTYCJ13x3coqO+hinMUN/jNPYTqjfgRCxtd3CTkPs4gUOg9UpfoRdqS0OxR2HvGOBUPQDH7V2nAn6IMdNum6PFiZf1SlVTIeXqMNB0HM2kKVyHC9aTDKxeKHfxSguWZAwO1CdjnYUUAYI5T01C/BQK4xnskLslKEHwgC4cOT4rsRnRl4V1nMnoqdyqGJ1Jb8zXP6kkW0D6OyA/CtTw94jdv3lbpiAsnlsjRUomcSFhiJ/8H30q+Wt5MbQLU1mRwS6aEJGSG1F37Pks1pU7Y7Gn35m/x2HX0biX15JAcgquq9zLmSkW+9YWIPmHzbJF2vfdCQN1RV713qknhFDcHg0tLD3tHB7wrEhyIYg95IgN8zXUEmPXVAOh2uI3qy/lhLzR0ViOKPIosmxCuM9o4J8NwwxNMTQEENDDJsSQzLz/CBu3pzqCVKyFeJHPWtJ534rnXPct0DtfBuP3UbzrPY+OHp39MrnvhD8+AwbNfCeUHtDaA2h3ZTUSRWaswVNcPy608/yn+OwjRY4ocQ68VNS0ja6YKXvARPhZPX3Xo+bEDQjve4FPTPSqyGqhqh2L9C2V+gqcm2lTrdYxq2v1j1oSbd/dNEodw15NOTRkMdtK3ezZGVtcjgL8FiUViymciwd/izAQ9GSV4xUfsjrbZUKjgWaW6VFvjZkz+qKfxryNfDw03BuD0Mr4OScvXaOLQfncyJcTRF7Pys1PMeWG86RPcf2A+LdkyrEoowEK0P8RFwXsiOISpjYQXDeZqylh5+QP/kHtlnI0cIKR+gdnlqRG1JIpMAOmTYd/sT3XWx5jcpGqtuzmVIcYvRWxSJ1szuAOhzqrTFFONQiHGmwWatEpApkokhkEZSJeEBL2ZiSNO9wP5OGI/SRYnT/r4+WS1geC99zV3+FlbtHFosg9NkQlouYqQPFMAeXGRqjIPKQ6A7JUQAa/ShESxxQUYLcnlverC81yDeLkrxWu+U5KcSEVDPbwMyt1T3noYQJWW6cmUWc2c3jt26qtWtXGgA/mHJvNaFZhrgV5aHKYTNPDjJcRG5Ilm4xSIvsVLJdKespE1XpGhvANoCdhRcxNp9QahP+84Q4UEOqHiiXnNENofPCd2DDnbZsdp0ZG8A+ZMCeRO7DsG6GJkWPcPpZYQlqVSZWUV/UJk5+0lWvgF37oGfH3xEKi0EF8Cz8x3SJYhpaYWrf+wH7qSXbPPIfDpXpm/Ikd0I3qj0RNULyqSdKyi1rpmaA/JCBvFaR5RL17tDBoUWKtLziKL2L2+gz5sGlY+jIsyXFeKwAsQHHQwfHgkOzWYhsUOS5an5HjpNGxayUd2ikxChgZ4WQVcLOSoWFHjEN67rP6HwICpLqpVWOR8tc47lbsll6EWtOGqhJDE99ZDx1Xb0IWVJs1/SwYG3TTHjqJ02m6muK7Qo/i1Qb42nRP344vUGbgTbxlzxJrXwu9PM8AJhL3yLDFKtwmAWgtTwv0gAnfC+KIU56X3ipHapwwFCblqFdL1jnw0HW4+BlVWo+thynrXPGNiFfuGmkpt7AUcOg/kGxt7XxvJa7RhrQsw4bxcieNS6X87GlrQ3GG4zvgUPHNhG9a9cOA/HHCfGNHDxSiozTzyl2opaTR5pWCDcP9UedowffwfVcPdQxek8tMutq1On7q9zRHOGtaHfa+IRoJ2kowKFTgFqeIRVq6WLvkJQqxin1DxFPs84h6ggGM48AMwvPzXaQs6mrSOlMjx4+jWa8psOIVo1SyBoL8a2UNda4jeyVYtxA+lFraVpo4mPobuVbsn0mvY2XieHSj5JL70hFc7qkD2M+Ya6lqW+qlb2GywAP6dwKsDN8wKvhs+GSPjwfTqHOYaGy/yfRGV0HeHjLOqOf8Qo9u779+Tnj+MvV/7I/ULPMECXiAooodiQqXv38A6KYUuJ7W6Vv6HIKHS10ffszIhTJdXQ4jotfyWKBHSDG7koOgh1421vXj5ypawX4K4qwM8MM1m3L8/wQgDzAYUDwI3ZYjrBghG5DP8DJ0B4sjjXFaOlaNj4qaltL2mh4MjdEGJRrWVeD33bihlYcOq1Y0ocYrZtSjCV9aEYWKA4zFIFW0IJbHGbOLK1NB24hGWK2M3Trt2FY0IDr258psgKM2G0TFGDFftkQ/tP6BGCb0k9q0cuLxl5N0T3blUELwbKPkgplYN9URmlwaTZEonTfUE2l2szbUKhjoFC0TmrCADuR51ievRqz91a5zyft+TyFrSL3c95QcRM3QT/JJjorRTIU4kOV0JgBIp7tRg6g0jRyXbTAkOU9VhZbobVLPK6vjc8tzoYwJrfdrZzUi2d7AMiSP6f7gw+6a7iWM3n+uguH8uwDfUa/7FpWuJVnr/4gZhHdFb/64mLza75Tf8BdJKzL3t5yJkeTnFpsTHZbtgQ2TSx/VTM1QLM/QCO9nBvzIqefc0eolhdcHrWEJ1wpagkvnRqoxVsCamURa4R+VTkQLoyCICnchdD//Nd/g+hIAqT5NNBT2i4GRr4fYqRmjjvllcQWbQm/+J7pULe2y5fBrwPAr1oOXHnMmeG8XJSrTpI7IEUpfliVkgIPrjzf1GuxqL/4ot2RLTFHwN+OBWNb0z5RMlmDL/uDL9W+S3lwEf5LpfgiHBpqMDQ3mOmuKfdSsRZ4gJQGA6YRZ0BCcYj8qZS/OA55CH8SmuEcO3SUKNNrqbDYPWcPpMKqmRrU2x/Uq+twE/hRyA9vudDHA5GGvLkU+BaWtxI/6WQ9XhZKPtZy8LHdk2+PCHfiQ+5c/1RTXlI+c1OJsMUqjdnCJJJTbUFJN8UDuM23/LiII9aNmQoHC8K8rOhNfJg+n2AvWsBY/+IHM8sjf7IFeoMdEp788WV/EETexULYwItluKqQxdJQwA1UeQzgpgz95WfPLNfdy1uvfNimaDgbvJ3tyNzxI4rfqL7PdaxQ6fssLVD5G53YneBZhbEpf7PX81jK+M0wX5p+prLYiZDC+IKWmXw2imWZCdY3TRkgM8xKBbjVyu+TRjeZ36dAcBEScJngks08omNhtol06DdoMCXYdaTmms0ChXMrRB7mbpgTLDo4/CcWQuU/Eme3trCtYiXHIJHAF05AW1XO1gW+NoFWRuQzKFoLRRul0OHDnX7m57KWu4BWcxQIFjKnM9LzliJNjpIlRzXQaXjNQkyTEz+aACF1XTcpr7ZJ2ZKelEEng07tvAPSEMP+o03pws9biQ+AQZWaqJJayY3CSgP7lX5SRw8r6+jAmoBPAMMdFPhUuw5opcs8cyMtq1rmJnYkKIOeXijPDg7mdiJ6tnUg2DgH10bMNCycYeEqULSubEmJ8EQo4/RIbHPkzXMmx1tSZHGk/FllULXtex62Qz8gjgqmDEhxGAUeYq9GT3McpFsvrNCeY4owCec4YM1Gb+Xzq3fIF7/dYtv3HCtYKQ/74cylfE02rnkLVlW+PxvKXUTa2lTTszoEiCPGlJqFMYkm61lSiWJBpSTDBMb2U7CP3pJKE6pochS6eX4710iCJhYX1myDANIixi41o6MFj4OFhbrRd2yg08/sENVTmxNFXZ7DEqFA1aLITU5BDs2K+Qsxp4MR6mpqxDcNFS304QYrjlOGqkSZelpwhhjwv1rlNztcNXXfRwMYx5qkXD0MPeGXtFM6WhA0SvuWUCl19qCKKUdK1iTPWl3Dz3rOij86RpzcujDYVlme7N4mYa2RplwzpaOFNcPb5UNu4IMqrIxEsS7mAEtYYrSIlbctGsjqG2Qp+9cbzNLNyYCWAa1WNr1E7XVq2W4dE98Q2nEzH+uhtfKhy7e/lFn62PMya18vLG4bRtxmxje+ZJsBIdjI1va39MQOBIn4ATZ2uBzyjMSlX9sYx3FEGOQs2y23x8F+1LDJQbPjwY5tcVAMHjoyAF6+/WVzINbWBqhO6qgB7LChqaVBkHFG0K5mKeoE3YSJMItuqklJh2t6K2E5th2QdKi+a5MFgxpbJDeLXW2Nkga8jlsWrIS92hZKDlqWrS+6HB+2BoZKg1m7wKzsTvWD4Sqc1VGDljEmrgNtdS2KHNm4VTHLjSk2IB0zpjUsGlzbc3m2AxvmZrnBtmZMww0abrALmyZHTGHXzEKmaoLSYabetGlA80hBM3Nc+oKaRdMysGlgszur6nI5tn1vSmb1jKvL5VA0FzbW5Ie8qfVyuURv44c6Y6vSIm9u5RGPR2MuqWVqVRdsQziVnIhWNlfdDA8GspQDbYyvGpSK0SDi+NGNJVYBHctxlL+LjbLJTlWYZZOGsnjPbmMnD9REG4NKbUNtcZXEzFXcOA62Ntvmp2iA8KggrrVFN6HBp5+Vg9jAvqtgpjTz6mFT2OpKAFNWVYylZeVgHzHTpojR6g71wRzcU3Asnp3BxaPCxcTkW8M0oiCZsJDogUxq9bwyLOONaLrVkXF+uwCuHTCaXWgD+4mjFVM8WDDtBxySmecH8dAbw8jahhAFH6U9xACkAUgDkMcHkIbb7NI24lpeLaMItOPWENZDH3H2y+X70ogzeG4izhpFnLEl2wzswEa2jzhLTexQwIYdYGP0yGORuPTr2zkYjoiIM9fyKiLOfrl8Xyfi7JfL9yME2YbmmPFviFDILTQnszlSlwItfAcPROZwUNIHmLLcQgSOMr/gyHJ9b8ahicpEtKyyyiMJwshykeh3PGi1LbaNAVJHMW6/XL7vEWwWzeyocfOwEbGtWQTGPf3sWl4DQwgDVWEByYKqGqakg9OCQDeA1OPyE+RL3gfLxuYBrHWgmwGvI/fRq4K9+oFuXKK0vOJANzhsTQLdDGbtKtBN2akNglbTQDfdrI4atEyg2zrQVjvQjSEbN+NmuTElSkjHjOkD3Qyu7bdQ20Gg22a5wbaBboYbNNxgJ4FuDDGFYTcLmaqdS4eZBYFuBjSPEzQzx6UvqFk0LQObBjY7M+Z6OJy6/pNwJqipPBSdhKlZqhHTv+o0iu9x+KPrPwnjfGKi1qoXZeOUPVvxuDkeY0pNHaB2dTcEZulj08LZuXyyhwJx6a88MnNHDg860ADmkCevB9SfrDKloEGaukijrla/YaZ6pgZjjsYVpT4S1VbYZYCIq+5KOCDBzNfjgKSzsQGmbUuRGcBpKUnuB0TWmqxByaPCv1j7VuWUl8E/4Z5XAoDCn6keACYOewYC+wyBxckI9gMCa032kCHwIEFM+tFVGxEyKCbMCdtm49CzpRWExHIRn8BzA2qGrzN8neHruoPEtuaBp5qxXk9xrNdTcazX7xWxXr+bWK+msV6/by7W62mtWK/fDzHW63cT66UHoqeuYr2elFivp8pYr9/rxXr9XubXcWjYsS2O6qnDyKvfN+Z00QbEimZ21Ch22PjUNvLqiUVePTWKvHpSIq+yEKfGzejArSDyqhTgDtJx7Wn3UQyZvdocgLWOvDLgdeROY1WwV9/vgoHWU1nk1e8NI68MZu0q8ur3jUdePbWIvNLN6qhBy0RerQNttR05npLIqyw3poSt6JgxfeSVwbX9Fmo7iLzaLDfYNvLKcIOGG+wk8upJibzKQqYas6LDzILIKwOaxwmamePSF9QsmpaBTQObrUyrnjXDztDBU+xRfPoYuTApPsehQ6jtP+JgdRrgpV9sbQUbyiUf9e/qAO9k/xvoTkI/IFhjgQ3ST3VGWLUJipeLOaqkpoziKUPKvFIDre70J02yKzMsWJnxL2TBaFNnA76NAuoHJ/Wk5nhhV2hpzZjLYUfXv95kk/fDPt1kAOzsZdF74i+r/ab3fvijH3nOSYKM3Qz8o8SzwcmrjYzbEUimbhaKrxaHuyLMSE11VDDVUeYCVttKN3KTBIJcOezs6+2x3BpSD2tWOhNtoD4tMM96KFq6vuUojZEfAKnFwSNvYNGVZ88D3/Mjihy8dP0VdtDvfvCAA0QWSz8I0WSFYN1G6Z/j3JzoysGLpR9iz14Nf8arEbqO6Fy+mvpRYGMU+uh+YRHvHibAGdMVSwx6Pwksz57fQwtqWx7AHUsYCv8WvM7mQO83tmaWq3zCz3h1sj3mriaUsh1NDsRNQ4fhj7ljwM+fs3WczX9JCmkvzi7ys0+fRnF6HZb8dRn4Nk8W27cvMTTjwGhGHft1Ax709DP8R9q0tdzoDNdkRtMEAixBJdThJ6yyoSu0wKHlWKE1kFANymomIgzYFbMjGvoLHHBEnhMKvTaHyLe25XXOisKgLdnRHXKiBlEOG1Fi+8mGmdDu7lFyNhlz2zkUngLGgPOPzd192PMgrIGQycyKsTIINTj5SPATdjLCdyBba6ATmFMFPpeB/w/u+IZ8nureskPyiBGfqR8M43cIlhaGHqF78Y33kOUeuqVw9isK6fBBMyDYUHT1bnRSB7ku+dvjl/L3oWU0kbglp4wd4LnTn7N9LgqCJrDDt2drgHf2XX7hPkihg8DaE9cFSWQZ+DOoKoCe3fOFHHt+OAYKubofINt3MDo/Ozt/+XzrCyfwMLtk55oj8SEjTqEnCzgAcQaAxnu+PCdP8OETDB/uRDZ20h8uf1W+/eKsN99uyFjnZCwID5qCdcthbogmilPxeX+XuRst2Ae2DhpVmNA0heJ5UayC7+Hh3I8C9ATWFd6cR4h6CH8iNISSMzmFmdR6Dbn6ATsZFX6AEV3REC+GYm240GR5ng/shY2BGqszpPXo+Eely860NZnFNwLJ/iJ5fRUHN1Z2oehg3Hx7Y9utrY1zpOJnnXlNMtFDweoIrpsiyw58SgVbzK4o/oTtiPHDLplie2X//+y9C3PbuLYu+FdQOqeqk3sk+Zlnz9w7jpN05+wk9rGd7rlnOyVDJCRhhyLUBGlHnUrV/Ij5hfNLptYCQIJv6mXLNnfV3tsRQQDE41vvtTyGJahYUQmpbbexrZeQnYc0jORm6MF77oWsqRoGJnM39kClhmotgfcV8gxI3G8TIJzCIo5Hqt8zlyUaTnlat8vxxiCTY9QRGgL75GLCJWG+OxPcD4krmCTAsvDplLkQG+7NAQ6DMAHKGlZoGskQREeUjn8l7DvcUW7roslEIH6LmdWcRuFEBPxvzTnFrym7IJFMxxXqN5BTI0M2EgHTygsl1HJJZiyQXGpGqTUYMjw+hTbCAivbWYpigr8Jm8G/REC4+djQQ92YR+d3wIzC19yphujEZ7AaUzh5OSFAsfvUneNtgyX0QZ5Q6hN1/It1R6+2Rn+yX3AqjvzSiwxAqi4zrIq+rlji85p63O2SyE/udhdXjqu6nk+udBvjzHj19FfQQaWUVNn7vA0r1BLp2yXS67O5ZgwLS9tccxQZrAiF5BiNBcJnZTKJEUkUya4SS5opDGBmDxuT29t3u7fv/ml316iFXdoSWYwbx8KXwuNuYuxaly2ymbnxLO/wAdpJEbjSmH5ivw/CrplPbibMB6JsWw655bO8nDnSmhTCncVTSNQ63L4F0tqZ1hrZWiNbXvHeUquexsqHR7TYdIifUkJ9dNuebqeyBJqXcgr0T/GDgsxy1POIfhMcWu4gNSCn00HSZWFknwhcFpjB/oqY8oCMe09/1nvOPHR1wbfAfzjyQkmG6OwSzmcY/xgG3Ifsjuw7nc489RMqwbtxoFUkWdAf8UCGA5xGV/3i0cwP6pp0TQdfU9nJTKeNZn6kd0J5A4WRNM7x1paUf4DR4FifYP00Y76r3jDYm54paN2bzvOUjhnxI5gqnJkZHXOfKv0grrU1T9UKj96IRl7Yeb3X7Uy5z6cww73UDFgwWGQWn+h36MWaiNnqGQtiK0LpPPZ3u52p6qLz+tmuNatn9qxcHih9ZNNpvTUv5I5g9fZBL/bW4b/wx6+LpLDUl33tYZ9wS62kb+qgxpGfA8grOpgJUBwxWZvOMjvJdQeBIqTcTgioJhExyJaFgJ4ff/hETgNxzSGyU22+efecheCMIOPo0NwDzE+y4UwkCrPLwkPV3xgdCn+uKTjUkL9+QryWTHiZJYnUdfXfKYJ45Lp6q3LkEB5RApBu/CRhRMAVQx9B0xuCGWVrSOQazRDUn5+MSpmnFAwotwG1Kj24+b1AeKzcgFzzcgIbX5sGuSfbuBGg04mWlga5gum1EGdD3IZD3bcdyhrouVUnOz/0GazJhZlFvwCTWhYBoE53WYKBcTJM9SYZBWLaSCaIp7k2vNOfMuGzQdKip1v0bifdSDXu1gcVWUu9EZxKAYACrR53q5CpeE4tOLXglM1giS1EMGY9fXdUSYRgSg2RCxiZi4jISP9xQ/0QWCcFPopTQnYKUcSSY/9XaXrMLI5pNqEoQ6Y+wlX5Mbk/Enq+hA5FlMqYqRGuoc6jxbcCATy1A1vJiJVMscW7Vt6sxUFjDi1K3ZbFKZ26rYDf0nmvSvitT5BCa24hkIalFojuUsBN7eaiAm7By0sIuKljs5XQWjzDFllbTnKRNG7+dEdX2qqt9OCz8EYE33pT4aMjpj/upar/mQIQBpudTCHBXEkIA7nZhoXZ/+2gMT0Tkswk3cftVsbpwUHUVsapvwpDV7Uum8kjmZ07/Hfx6nyN5r0MMmlrjRiCxayDl2nGgpCrNWRBIJSRdvHvZFLSMVKUTvz3qh0pM1NdN5EPZ9EdqH8PAjYaPN/fc+jB6Dmjr+ir54f7L5xXu/vDXXfvcP/Fq9HoJXQuI8dB0Mlla5qwcAI68wkjR6cfiAMWZfDx0G+MIi+xew2F8Bg6T8aGLwNiiIX4D8w++VXRSXMr/hlPoGvW3Vq5+Nu7zZp9LSMbTVN+ftYI8ClBgHTd0upMoAWvH7lT7luOE2vIuZkHzL66GouJ/xPuukBLNRGpKGtRi9Dop1CPz8oxoRE6qzBAbdQlEs4U98ddEogoZAH5cCrRxeiGBjPismvuMGXGuZP6h+tD6vIV2macbjDrFqVblN56lO7W9Z9J81zeLtGz3C3oA6iXIn5lwY9azNfycCHq90bgqyWLFCbFMBG3L5RF1VOdQPnec+vr0XpUg6MmnANDOFclBrn+fnb1Yq7WL/YBUINkfcBnS+Jw0qPV089uB/iDgeYPVu051dfPnwtqfKrO/TbT9kWm3xL5lsg/GCK/BdQbVYbl5LuiQHQt9dbuWvUym6kk3UhqS5WdbulzS5/vkD6noU079ufWqbHhpuoebDP9bjTvlnC3hHvrCfcWEGTt31lOksvLwTWWp/0eEKSgCW02vLlP1CsNqbT1WlNZumuKhKhYZT1cGkxCASGe6jNcQkMifIe1RL4l8veHyDe7UNtM7hf8gpbwt4R/6wn/PZLYtWdMCYPQxF9mZxR5XqcsQHwRe2wQeUz2qO82tcziC2hWXZeNtpsy0Ko6NGqUh2KrrVmzbSYVC82/JRQtoXgwhGK77Ld9RPzljLjVFAUv9+K0RBGOhIaUUIoSelAgSj5EyL81YMfh7BQNC2L7Y0RwPW8aBBRSevCQTZeXPGEZUdSOPHXV06ALP3+9E4g3XzyAeLilPs9+/75RjDPEoMdBKQzeVufQWJelUOG/thDmKYApXFxIA/TDRkSAHEdBoJJRCx/SlEczVZAYh4Z3KFH8LL6M6X/gApVXE94KInIb2cMroGoQJyFYyLB1J1RtcTvW46VpC0olr14N6YvDIX2+u//COXBevnDo7oF7yF7uOSNn77nbSiWbpjF3ThTWa61SVEFbqfJUQSuei6mCfnifRYN7hur2dmwxqhdOs0X1FtW3FtW3xRhRi/6rmCKw850fCDw1Gapq6IWO3UUZuiBUV/9eHPZZRi+akQs9+c3RCj3AbaRR2Ew8MK7l9tKGolm2pKElDVtLGu4c8tcb4qsAHNOxZ9Eby1wUQbeKBDVamxa/N4PfZvm3GLxzU2yRu0XurUXuh2YOWGvYb07xU6b3KXU0bgnBo1M6bTFpKpplS51a6nTvqdOdk52qeNWFFE471L2GqyTZVF/FlYhWqjeYXCkZS7VE8lRJ2Apbt5RsCZGmckVvl5gMUpNYJvii+iMeE62pnjeNQgFpvJ1B7r6vsHslnf4scOGySUjZe1+3wNOrpXZ3RO36qbOwUeI3jLxvSOlWddbqYU9lHluQRUk3KHSwmUZeyGflyruUsR5TMsU+Wtoti5wbP65oBkGhe7u7+s0ZJhTWrY48L5lRthMyjWQI4aRihLdJQo16uDgP2z1g7X6rsQSHNfE+qP72dlVVPPPPpTzF9DHacj/oyik/QkLcekS3HtF3aLzqa8pzZy5redqY8kAqo426UUsbW9rYxN/uftDGyim3tLGljS1t3EqRtI6GruL4dz1zeiNP3MgdXWhlYXk07qGnPhrUr1E4AZqggEOtfcadRLUk6ZYEWyJN/eP0mECvxBNjSdh3oKH9gtpwy/azjWSz3gtkma+NEb6/cap0PXMGeBQWcxxZ6qs0uVroo+4rvcrUJC5aJ52LSzI3XrL3sBNmudKLW1TA/ntPMl/ykF9vDwm7ZzTHrDoe1G2Vy2K87uO8VggoqqAs4q+dgHl0XpGMQPzVU016OpY1m3JAvV+ccwAO2CfxX7qRrufOkkDTMxZGgS9VmOmUhdSlIe1f+op6d4kMaRjp/DRqGQgNGBFTHobM7V/6l/4ZnhP1uxMFUgS9GR1zH5PdPfnG5pJBxjsc90otlHtFQj5lMqTT2dP+pf9FJo8GQzYSAbsiO8lPdBSy4IpApbZMN9fUi4y8dwnFWmW441EZEuBVlYw4o2MG137EQke9Tt1/UQcsUPCoT64s9u3q0g+YkkOhJb57hWt1pdYARg9FSL0rMgXLK5xH+FF9ORlxD2hl/9LP084ikEuawFmwaF5p5b3MG+lVW/QtXNimL81YMIAFadqeSqfTtG60R+fEU6c5DDi7Zq6Fid58I9SrTLpJt3eEy6zW3A/ZGNfMYKX1UNMIuPDpSfzM0LtbHtoiSNXEZXXpT/w1QKwZwG4O4B0tETWXsLCL5QQqnc/wsOiQvYPWoFfaffaafPCvqcddfW27RCMWJvQUAZHACsTHeX0MIdwKu7YjfoFm+p6VT3p/b3f3+WvyxWffZ8wBXJUsuGYBwfdvY3rVFSdtmi/+i5wpilRKoIcspBUUOWDUA/LQn4q/+jF1q8/wIMPMEOUJHhKaGlPufGJ3RTRzhDUuhCl1OveYvhLuy5BCbldyFIVC9w3NZtHQ43LyHzIaQldDdukrdhTzi5H45x7SYXzUJxfYAimcoq7cd7zIZS7QNaR3sU7qiZyIGx/zyj7tG9GbA/m/AbIPFDgUJiGdJE+imQwDRqfy0hej0VOchkN9X6D6FNJNeJy5ZMICRv6//+f/JZL5rko74Qu/x6azcA5kEYa5IlzCTP6lDuaT/b3dvcOnv5Ir4Iav4DJd/fh5hZNxHDbDDLiS0KFkwH8A5T/9ckFCcemb/GoMCapaUSRQhIcqIe9a6OqtZbk1GWjTx+f3aEr9HlSNBsaUQKOYLcNvLpI5YpCG0+dGqMokH/k1I+e4jx1UzX5k/jicoG62IP1rca7XvTJqrFmElgzfNRluRm7VdtmKhPVQzTfUTawvp0JKDqdW9fH60u8hbdp/Tc60CWYoXAAwQeSUep5pcPiavKfcY66CIVhR1fIJ14T4P89PPj/Vzff2EgKtYABvyRM072iMQgyKXzh8bUDPQjEldqiFIU/gnzwk15wi4ChgSYBG4ctTxJfN0/rD3VdVtP7la2JY4ilin8OYqzUW4URBqQkNuIXJ7h1UTXavYPM9GozXqEdr2ab1s02WyiLPODXRWOz8UMhTFwaf8FpxFGa+MHUJr3UuRqF+DdiomNPqk4v45n54S8ZCGergOn85+0hAGQ18y6V/9fbdx3cX78giX3OFLA+giGayksP9K/wEnJgkviCJWbHnsWvmETVTwnx3Jrgf3p4WwMx9IXlbzbal8HdO4bPrmLaQrlf+BUw8MOTlw1siJyLyXKCXB/tkwr4TZ0ID6qAS65ZI4WHVXF+YucJ9HInId1uyss1kJRdpr4+uSrEeTKmdw0IpT7nUSB6wa/GNScKuWaClYMKljDTnw8MukcLI0ixQ2blj2TmQwPwBLnvCH7MA8nX7zAmBVnBpMYaR7wofuZNinUGdGl7FkKZj/ssI2JlWZ8rEWclWF4A8n5SUUd+DGvf+pX+RqNs/n1zEwv+WE5VWf7s1ZKWR4Lhm9WpLXlrysknyYuL3C3W9hS6wCW7H7j/54MYS9FaPpXn+i1SKCOq7OyLI1OwslEgu/axIQq5A+7CwOHLpa3mELCCOqA+2xRGkhKgXlgJ7Q33zDQVqiwqT5Es1SXriZPQqlz62C41iBTbvaZ+c0iDk1IwpXxsTsamEDGRsFjA8yu6vRtkL1LungA6YgJlHHQbq4ZuJ8BgxD24mzFcv36FMdRsaY7Uo8Je+APrxPLktHp3rajWdblPVoGpu1UTL0pymvrwKKk0hu5bAPyoC30gT3JD21+qFASlt1bClGf4MEJxTBZsGB4nq2Bi5EH+hQxMeQH2wPwkvgsgF8Vf4emcH7FSTMJxJ+Bvao68JJRMhw1vTCbecygPiVCxn45X1qzvaA62Bj5hqWeIqFjuy5YRUdAIz/l8obdtCuGWPRRuu7JNz5gRMe3350BYUpdANc1FKp/GrNCQTKsmQMZ94QoaWJB4wR1yzQFuakYUK2KWv2Bn2fcaDufaoek3gYMBgjIIXF/T9iyRX2IjJK8AP7YYFhROQKwEbOwkZuFhOuDMhwmeSTOg1Ix6dyS2WpJXhP96NJz7wZrjcT1s6u4V0Vl2rAfOvmSdm67O9tiJ1S6jWQ6gauDCv5kalyU6VN5WJbklv0Cfuh8aRSkk30hEzpr2NlX+U60ow3WuINwKqcSfCKBqgPmMuw0CbBsPEdwpM/wCeT0HwTfykjL0wjvogR6rrS39K52QiPDcORdWE81er/o5P9vbCCUHdtXJ9etCSqaaz+Qt2gn9Qz5DrJ2fvj8nBwcGrp33y1vibwSKSOaMBGQViqldR+L9afmN8RKYCXb9gaVVjvUOjKIQAFlzerGPUSIBJAewOEE8Fpz7lLbW/u/+it3vQ239xsffs9e7u693d/4bz7NEh88o/pkucSIZiyoIeKDuwdbVb1izgcN57zAdahaQpvisFq/Y59qID8wU4qqiI5T/2SCA8XUveGEDAiV/c4JW49GcsgG/uk3M+9tEVUF8L5TRoL1KOqOrAkY62oOA11cYTAJsMAbU+r/SVVDxwmuhZn9/Y80wxPtrzTF1kdXfTV7dlgh4RE1SpdlDMEXkSNGCOnnaVyoE8GRWpHLopfYNqvLebOKgl51k/2ydPNCrmkUtE4WKs+kNjxmoc3F691t7NysEtAKEOnIe1+pnEFJiGZAoyY0yDb2lZW2ZyJWZync5lWvmx8+NfIW/qaabZ0QKHszP0MShlR8+0C4JRXwzBoj0V18Dz8VCxL5hahIVFWhG12Je+A+dZ6T4kU24L4NxgIlEpejmMRswJUdHIfaBzwnclCaiOEKX+pa/iCUJvrgLwtEODCj3wwIV8TiCITvlDuEl8nOadQTUjwkvf8QSoOwh+nOZeI/+bD/RUNUVwZq7EmaIeBQIHwVbksulMhHdkeGnW/l8hX0ixotxMNgiEjphOhd+5JaJmCJRmF28N4LeS7rS4vRJuN/XeipEEvbc0VHrC+SZRkLeBCkFQG28Jh0RPTMoUhOnWBsB4CD5QYGYsc9GqIiDXSBiK9RVH+p0BNDP/SFGHT+I6Do4G/lAEY+rzv9Vn51QX2Ni30lqFoPd2mQx1LGHq/S5hHLGdSsnHvq7iG1LfpZ7w42FRa03Tr4J1KiFCQxbegDLdbhG7P2POqwlnAQ2cybxPjqxTc+m7bMaAyuhwbLsHMPnTmWrJmVwi90cGaycMsEsLttaawuL3K1OFZIWYvJYjP1TZqsMcOLoQ6LiyeLekzgUB83GLJrQmEdOa2cCeGSxg4ackq5b6EL106Y/wQ1Gco4JGLg/LnYirJlUsrheRU8sdZWKyWECgyq0K6BkB185ZtttQ0K7C89QtgzQVgz8OP2mB+2djCTnfy6cEg1QGhU6daJ6k/Vgu4YeRsouSy9hbqcVjN8K0CZQ4HgfsXi+ZLFpWpNNn6VQ4zxad7UaIerPZLpclJSZExXlQIBhgPZlOaELxShkAJKBVBDb05MCB6zmClWQVNule6Mme1bQ3pT4dq0oDYGzo5VrIvMV6evHxnGSalOU5ybUl0cwT1FWqnrmI4gyUXYCqCTiavcGEMv8bnp3c+OT4iDx5879PesdHT9EIDl1CILbKTZHqWzumD+cIyMeeiNyRByKX+kyXHB91Ic8QPv4nfsyxukjHdjfGOe/rkx064zsBkyIKHCZ31K1LrfWO2iu5A7PZeXpr6bmy29SjvtsDzxgYTpaVVUAA08P/FbEg7175XiVLIYHOIDOc20usMneSTya1KPxTufgPGXgDTGlPMvj+UBGc+oSYRv+tlPudbmdMQ3ZD5wO9ZZ0urByTMv6hRiuuO/qKv848VNBiRqZuR4ZzNAyAsr6hdFp84NeflqxmO61HcTixlUGz96wqSVnNN9xZNrKab14mL9kCXa6SEKy/pqSWdZ6nkV+QQu0CMh0RP5oOWQBMqbmpScICJMJalubKNKNHUm/Zk93DGmvjgqQIx9ptB/MtaY1YkkQKwTcZvX4Mk6gob3fLfQlkF8ZRG/b/DHhKTAA1qFwz039MmPGzRBQS6s+JZCCeJRlm6r9JDTkzB7NoSHxoDdh4xX6unPanOaSc4PnrHSCS2mnzFuJoV8tcl+hcuk2ZNIQ0i3CTTzEzU5q/TjN2r8n5+UfU36YIP9ZD7NY0srKnOqNTFky50p2cxSuVULV/k9J7HWCVxZ/6BY/6RymO8UdnGEnuIxYZ6AhZMAu4jMFkFLD471kgYlPgOlhQKb3+tIDrq/ZKKXdAqeIxFfOX5zIzASDQKEexCiJBsB1NMyig2pqLiNxQpdoAdg91WNBfj/mwGq7NG2qUlIszoDraYgUWVDvi5JnQ5XhQNaEt5UJvL2JjZW4L/auyEtV6sFb29u2ojxU6hf9Vnc0Cfg2cIWLkSn1aPfUOc+4CGYBwaHO1VMmd3g5GWif8RTyrTEFf/Q0tI33bjPTDwALtsTJQR2OFrpOOVMdKmb3KNmc0SylA73aQ1gWr0gjsZAOoKFnAqTfQzPVqvab60t3zsU/BCXLVruN+YsewlfqDLhQrr2MCB7RWE17TZdJR7xBZBeqe+N485kKNSm/1E2z1pOnPo5ZHFhY1sKzfAxI14pLezZXfOz8KUKvaR6lKYlEv1UgsOmNWrcTyVmfNAoqYYyMi32NSPbN/5mhGBolhOIdwKWV3DliRCFPO9xesyW0IAJUEZHPlfhcWS+rY15IN3ib2tVoHXPcBLe/a8q4t79ryrtvDu7YsZctSboKl1FxgaU65KmZwzAo8JHJ552rZwPdQ9cROP5fnBUucJFDtPMacQGkecSGlc17b/JaFlHtLej6MWaXjQ8t6rsR6Fp2o+8N3Vs6+ZTpbprNlOlums2U6HzjT2fpVNOFMgR9dXdO5Q6UUDk+yHKzLE7iX6rjWK5hkmpd5CFMHqnamWsfRNFldKJ6ZVu15a7xn/cbeOidqDV7kCbuwH2zx17ScaesTe799YvfvwCd2f3d3t9YtdsKsfQotJ1kdLAkYFTA9L4jUr17G3d3Nu8paEHESR7S1DF3L0IVM9jNsTo3XbDl7JyBl2kDp2cr5NmzV061KMoqeQJF17VNazHkh46Wa6a4QKZO46VtzIOV0amWjWIo/SX1uTMHXxY7ABBP2YmDvkl3Yr5rpKJ6iYTLWOdWCnBc9M8waESV9xMowxG6lIKMZGDhi2ndiNr9PZ7xvzqV9/vt4/LcXLzidpua7glN9+tqXZ3S0Vzx38+Osj5AOwr7923n51+MqXjd+6kLHBTtx7E5T5+aCxd8IDmk/5eIp10NR1TQfFxYtwpk0BSN9KR8IHNU73qX4lZ0fqUNZ43CXRrPyCpSVaGaqVPopKLt77Eq0O5klWduwmX6X9GXbOFqlrr+2FUICsVontRagNgJQ+p49EIBqmhXrKGAYDiijgP0vVXWQqlLt+eKDZT4habzKlhpMbZx2pMihFdjBXe1kIUbg+TFjDsiQLXothl5Fq31rzFYTLqtygo8LxTYg8m25imghCEN7H1z40JnUgU55nbxKJsnU0vMJ+84lZslP4Q2BOB5TxtSUhUtFT2MHLS7dhTSq1n5habTgXGwVQFbN73Hh4ya4PA0UDwQi9dcsL4buBCKES6RKFiwqlPbU225Pv14go56pFunjfG6aZxNZQyo3FeIFidS19k2XU6CjEBKREhwTc5N+Y2wGkI0FQeElUNwBp0q+oC8v8LL4EiA2FtEyZSDRZ1h3nyqJajJimN7U2Kqsw9WEyoH+Yr1gV4ommNykukfuu9rEc5PYhVXJU0iS6rnmkzCbPyxTS0CaiuUV52m7pPQmE23hvBXa80J7HlXXK8M3MaGoKRThujrXjfBcKdQxjgMrBWQAXWLsBmZH1FWfy2F5yEYQ04sLpHJ4KxKBaL8QON9wz4MFkQp/r2Cvr1r8ra+jXLrvG8HdNNtsMymNmOgGs23Bt+WlbfBNQ14VSz0EJzk9p50IHJN2sCZQuVeK/UYf3xjgG/2sshT0oPhcVxmSIQ2jvLrU+Bv+KYJvkI32xB4A+EzDGo/YjfYkSzKw/yKhUK4fSoh5i2AxyZA5FNheDq57UkKNtlASl3JvriaiirncQPI4zCCnZsdln7xNGqEeDzj1kGDZOvLl4vhXMqPcNUOr2rvDQETjSUiG1PkGbm0yRAc3KKuriucJKB4H05+IKFg9rT9mqrP8ok0m+g9vq3P6L9JLYf7/Okw9j71DjQfm3VWJqyzIZjvvmYZf11MirnTc2IWwaJlyLoWVs2qW7/5GXaZe6rYOrNu6Srb7av/GTLb7ojqDX3wAMhHwvzHp8x2dEmWjKTgkFRX9ko1MfcNiW7jGg7XQuA32W3tqZ3qN9zbZ7nztwIP8Pr8XwZC7Ltb5upebnHxAu8OH+wUlBS+EgMDzuQEzeV93Ov8h7Y4XFvP6AFwvFhzGulr3dLszX/HY9/qnJY/ZHMPS5c8KpISe4juWD4oUPtuxTli54zz41w7sloPr/bzrfKqrvPo+jAKokRYH+iRBM/aLKt00iBsOlaAe8l0I3zES6crsfgGPnqg7FqniZRfL3t0/YHu7z0aHzGGjl9R95dCDPfry4MW+u+scPDtIqXCYf80D4U+Vybm2mggkJpHRbCYCUBhbL5MnqtZa4HbJiLkBnc6eFpYNSW5GPAcMnKoc/EgFTOloIx2tBfJXErGVjjLKDRvXc86MO5D875rB8xFcIdQbhRMUx3LVjNk8BAKOonUAG0Qt6o3Hfs/xz0QIUecccTq+He9Ue3sYdQss3dg19SJmwzZoeBJc/OfXRFAB1RDov3QKGfzB5XIGRUb1Oivtzn5/lxy5U+6TYxhFnbdYnbs/MOcHy7mATWoscL6ngXAjiCwGZMoXCfR5KAJy4rO3Ab9mXXI+oQE7hcw3XXLB6FQqfcBJFHpCfIP1zMzuE3cCIcUIlcLebKDzypsbh1P89OH47OT85P3F4MPni3dnn48+drodT4xF53VnEoYz+Xpnx6VyYuuiHDHdud7fAbUId3amZpQB17SpL6/h3lpwUrR24HiDMT6RZIH8hYwizyOzQIy4pyQ0R+BZ+yJZ0IfG/SPPg9/ZNVO6u86EjydY7LWs62xf7+HfS3UGihfQ3hHUCyY9fqLcww6Vbi/VoxPwkDvUw32PsWVgYQsSrvh4dDsaX4B6RRAyTPFW5dcO0ZUc4WUAlSoqM8mbQHzDyEPcWYfKYdH3qHffwXfEr8bvQIjt15/xJYgDXnV45l6347PvoSkupuJC9+wg0b1d4I/YNReRNM1SEZ57Nj+gKgz+bKpBFz4bnBpcPEpuOeDLR54kRi9m/1S1W1M9t7MuPfCRTY5L2Y7FdKZ/s0D0wiCSYR+2sZ8h+dUBOovWPs2yJzs/rH8ZN/lCfmXMUuxKllsBPaqNxW6J36nhWRABCl7Qvl9Y+BTwVgNyN2Ffug+Qf0lvQuVkrSO4c818VwTLT1bLGUefL34/Ozn9cAwRtH+ed7qdNx8u3nw5/se7C/j75P/udDvHJ5/ff/zy7vPxu0638/bs5FT9/NuHi9+/vIE/Tk5++/hucPzx5MvbwenHo4v3J2efkt//PDn7x/npEb79nx/OjjrdYmp0cvru89GHTrdzfvTx3fn7kzN84/zd2R8fjt99PvkT/vHx6PgfnW7nv09OPoFg0IgrOcqftFtiStRoS7Ila+JK4F9y4LIRxV71uViISN0Xdob7MgwiR8teYEP4xfOIzxjU5Yl7JQfPnxGKC2ZuPMpIv3liSD29lCIg9rFRPwbCQzZ5PWxTmvAPKSSxA2bjHjFRX3NxUFw6aFmCHUaiy8g5pec5WXYhNmfEMMWWXpj03Y5CAa4ZDlrWAjZlLgdbtCH4KhtlwZDwIjnT7VXxbjxYNArFIEj9XrcrMctYvYjIOOZX0mIeYT0tlu7rihyUdYCV63+mcu7h7mE1WII3y0hEvvswmagx2wAPtYMW8Bi0GzJUNtIXclcWO1SuCkoUQFbzOO2MDvJhLlGsQ9dit5yAIR9BPaJOEDxMwFQhtqaIZEbnkFBOWp6f4MjpuyxA6qEs10mXyg5tWBPjXQQ3FoY+PTm/IICXqGsIEqVBy9Y9WrauVazlyVxyoZN7rq42eCAmJ2iTrK09i6V1bVlCfPqB/IPB0k6iKfUVl6Q8KgfJuddFkxWJ1qQly/D96Exp8M0VN7Bi//Zv5DcWovsiOjrqYS79S3+vTz6KMaZ4Mgmtkb1zhC+Fxy79/T75TK/5GEs4CnKu+pHkf0Ivl/5Bn/yGBCrOXwGdw4wwgArBcRCjxo+EFHbkt973gv/Y7yUnJW2giTsp9JQxE8i7xqTtLKaXvPUG2rk8YE44iAJPaXTuiX4oCief8FAqLielIHr4HE4/xXDcus5oR7IwmvVGnrhpzu7gOwN8p06XhE2J6r6U8QF1UgyK1hsx72P12MW6RQDOFpy1/EbLb6hVTBjxpsZE6xgR7gJtCK3TyIEDD8SU/PZOsblZ21gT8+ISJk7rlapRkh002p5uogJqObFyE6eFMhvkuJJRVrRtqgAPo1QEp0CFFEjrY02WJ8bc78caK+F73Ff6LOVev4OMkhOrGZO4idcdOnT29g96LhsdPnueYIgczL45LGbgYl1KPOY4oLNJMiaO1jfqSrCPBd5g5lGHTYTnKnAGxUhGoZlBY+H7zMGQk0TtB87xJuI8pzPtG/1PXl03iPWoWf0keVLS21O8RWymKEnMwKiF0ksJnQ0smVfpaSPJ3AH3dSatWOWZPNBhAMaH36JZmsdSpzoeU2n8MrSKO9/wYg6jMFRhmEMQ0BX/pwq9wGNNG0CkHwcQg0/xzKLKdu7TKXcG8blXoy/yBfpEhDz0tEJOOavaiteEoVUhKmaOS1ha7wczew4X/r0nbpbiYkFt7QvN+8Q0aKt4Wz72RRAfi6UYXpvj3AS/ayuiql247JaFLlyprspduPJZm+0XEy526ZSIW8ysNmaz8kzrE9Yf97skyx92SZ4vbOzJpfCldl5vTTPAShG4LLATYddzW1Q6us80l2XbuxouzNuPp0S/oiOYyBPYth0E2OIPN26ZqVBI+Iq6QSHEM/vFZDhv+NGpXVcEwjV0FflOCL9akOs83SaesyGnmYykcppXD3Ou8p6nIGE4J9ADAH5G99fkkMeBbo0OmDWwPmDNtvt3Rr1wAj1/8DkYAvjfqsHJaASMZafb+eJPdKPUriem0cbSjjr/iZ+rxgagHl3iMPm0Tz5RVekutZDMDyChsgvqQPCu19F7lrEEmG3ZJ8fUx0jm+ME08kIOTHrIp6xGlFtItMgaQjYkW9jbuqL3pHWvsWpXqatAWvX7mxBQcBDiKuWMOmxR0/oY3x/cmPf7M+Vebwvxr3MKZz3qWzGl3O/9yV2oOOixsVqJc1WSgehs8kYs0EO5+NLghrts4MYvDXQdBxNsjjXHNLq97uzv7j/r7e719p5d7EGg5uvd3f823e7uvXL32XPac1+9etZ7sffyWY+Ohm7vcMQYdV+xw33mKMFgBiGjiSLciCJzUrCI+nq/tm6gzsUST+ewt7d7sfvy9YGZju2NoOzP94Rj/pAc4z/24Qp9CNn0zpwEP9gM34a0vxmmchkGuCwvhU7gbI2QZWt13ua04FqWiQJsIzbM5E3RNvEi1uIRnAn8gb45Ss7mEkWdxHt/OEfLB8ZJMzIVqO0i70VABEZs570Ir4rUcHmldmK87o0j7rIrYHokY3H9FrRk21ZztEOBu0uRpRw/nFFnokXqe8vBr5x9Lk+sznSQcS2NUmfTit2OiVSK/hSpi1MEoZNFawRr46uA/YEux1x29a//yxHBDMgP3B1g0mPfK4heerVH9w+e7/Zc+myvdzhyR71XL/b2ekPHZY57+Hz/+d4hgEElaKe96GMKeHNz01fEh864RAIIX7PjgnMdZqCEhFxZR3KF4F308/66ILKmAFXd5bM461+3E7Lv4c7Mo9z/1ZnQQLLw//xy8b73stM4d0ftIAWpBQtitHNoAfJPzPl481tineJjuaSP573inWJ9Z8rH1LyXqJU97n9T/ILZffxXWl2sDfjUd5jp34DRz25HdRF/jX6S/aA4xL2Y59rdu9i1eC7rnqtyq3PV9nlB22UvuRJoBsYHHrd7NV7PozIcTOZuUM3BbZQlzOVda+joubrrJnliLAnay9ICyqcVXptcZh2Hyz0/ayKYVIUq5XpruXbWQTQSjr5SKIkAgkxRvxJvBerUmZtz/KyYe42jbM13oEM2eYJeq5Br9+kCH5OhN0WfkXct/g2Dj5YbcAzvFg6Inwho9TVv2zgNRAiWHzqmgC0EiXgPnKtdEk4AHzKn8qsVEZVe+LSkVRJNlV7xryv77FpEzVDFjM/uY5Vm4jpDqyn0d37U1ANRv1eJQDrnZJUIlNQDsVkFiDwWo7AXJ9bjD0GXXzNBm02rywG1lNrMHkBtXpYPfNT3xqpNUaQHKPXXqrgA4OHCU6veIN6v4AXLAf0hJyjYrguy6fi3/D63slErG7WyUSsbtbJRKxutSTZqHs9oE78NePtvE6dXHs9YWtdHV3Wp4PV0gZQqYUc1kRlp5xeJHgpdG5O66KxiKEcqr4MI7IjBluur5fpSVpgFeDm1W8dpi0eejbPDN3XC+ALLS9Zwgpfb3KOOz24GqZ9g3qOAyUmqSfo3vMpqkuhuVDK/KHcum8xv44adL7rmyYfUfdka284pusC4apYpG8z6TTxNxmpWRMq+K6aozB1YeuJr0EozrTTTSjOtNNNKM600sw5pRpHI1tKTrrO3FkvPDiIsLGSxwxs+rpJ/TlWpjgrxB1tkpZ8ukaGYYVUQiE52AnrjsTVU13j4cs0izKAin3fBC+LILSvYsoJrZwXVJWk5wZYTbDnBR8cJIi/RMoJxGF4k18UHAvGdVjCC6nkVJ3iGLSpZQdVERfQiZ5LiCAMmQxqEKt9eyw9ugB9Um3gnDKEauuUIW46wVQ62LGHLErYs4ZpYQsVTtDyhfk/zcQszhcGY+poslSd10UHfcgChs/ofJ6k380W6NNclMs1ynrABZ9fMKteFRdXtl1St30tkVij3Lzs6tWs8AKRRvvSngELaeRyymV5gRCowKSZ9jCm6jmnsIU8H5p+77ARChNCrIJcdj9HRZadLbiYsUFGt5rdL37yfnaGa4IBPNUR78wHRk5XpsN5Lf/lUNWtmDy8mseMCmVCpWEPmMrcBX7i+yoC5ZKtT+v2DerjbsF5fJWTY5wiqkw/+OPykC/WlS/Kup3f7TjQt/FdYqLegOq9VuzdTqLeo9Ly9vVD7nbnEjTBrLyWKz1QFFBfa7UWX+h2MkEHoZ4vOFqKSWXAns11XdjCNnopE0BnvYScK960GSUJl4AjWRVAM7vezSFydH6GCZkAmC7kzCwRc2nKigc16ullvzMJe/EqOWlji+imWYbeaFiSDAVAtfUVlrFkhKVg50lYdKfzcQaJkqK2DWFbi3U7cVJS20yr0bjInWUqKvdSwJu9Iw6GbJgutGH63If2BWJl4x0zzjdCe+k2LoTVDchZ708L69Kf+OWGYdQNOLaTlAImO3Biai9oUa1EtAmEWVR3DFL3IZaCpXg2dXCZfBDqkXsFZM/lINCaD5kjlhrDmqd5KHz2T8iaXWTMKAiA5mAdXJyPL5/azEsVVjxFn06k/v+bUNu1/H9iOVEKe4jUz/ScJjeGzRBRisiyVvYwkuFMz5m4y6swcvjyFTPYJm+J3IdrBVgHsYDURO6lb+TLu7v5cnQFSd0Df4s7PtTMxhRiBDEIULIYV9V8BZNkM0VOpaHt6pHXyAopUneolK2MIVCvkArr6H6q85pp4gpnegxoWoCwbUpqyK7Wi+WdRUiRaSqxLciRVvIHYpLI2RwG6kfgucdnME3P8F5GgBMun/7srHmDlzEBNCd4w4p5r5bPOZX4e8XGC7GY18S34l0lg3GgQ6kxA1MyN8g6VQ7pT3So7ZBNS971HI5eHeIqVmqgbf990Sn236APxAUHzEiRuNh+WGbPArOPPpiSIfPVKp3h0l8kQyBVo710e5Mc/icJZFJJYnWlUGdhp9fhV44JuonjAt/FIwKNFigro5akeb6dkrBs2HFCfevOQO3IQ0oINBjLkeFRKPsLrFlK1v/Fr1SM7jO05Lw5Gz9nhi8MDd3f4jD0fDvfo7tChdOiAfh9S4iWzajRRhcJFU8U8Z/h8kVnu7u+Bme+Fs/fy2eEL5tAXwxevRvvP9p6Pdp+LF98LZymZL3nIr5ml11SwBMnX9L0sIOz2xUzaKyGm4PiW3EtMKchuqrvXjfQwuAj1YJb7hoFK/DkwUSU/cS6uqjZUNwHTbt1zgNVWkJ5jCSEbrIGgFCXpk0+RDMmQjbnOpkeJJ25YAEYd4rEQcqjCrvAxD5HMaKUeAY17rqnsqpa6KNxkPpswv+akTec9RUvpbFZyKZM1GwwD6qtgtZxS3yyramKwJ/7QLxoUNWWa53cCD13NZCn3SyYpRRQ4RXx/CdVR7XE9A+HVH++EqlW3s74lMVSUimNCp8cFmFCmttQNvJkwn8wiiURMZ/7XEw/YTEiOVqtL/09o53KJw3Uhz7zdyxNrqZM7+DRWRocBH48ZZE2ktsGvf+kX0UmXzQLmKLtkCT5qCwD3PSZlz7zAhd/TzLeqhkqurJNVsG5XeIqv9HztKyiVluoKd3UKJQvBxBV5NEg29Ge3I258VkC2AJbxkTmk1lrW3RURjEsOIPaIlvPy8T68XXTIvf2Dw2fPX7wsu5o0nAzYd0jVUSSyHcWCLTTUZgw5EZEHtR6JftFVVgh9DBQLmwZqlbzzT+65Dg1cIud+SL+TJ1f/4+opZP6Ms35a31KmZ4+/Mf855ntU6pElvudGhbXhTVEfc4dfEiCjuCgOnJ4R81ohl1qMz+qCKORtdBxUU5ZeQYjBXnndDEVTXDDStMobLBnWgrlyIhmK6dUa1j21GE3OUuFiPJiFyI9VSCQBNJHg4IGEM8iV7tV8frJKVStTBGamxACWV/YFZpdXX6m1D8twHBeKlhdzHY0BvZyfqCZNlVfZXqACHodAZtJkfcOiD2l89+FLS4nO2skNjlbM5KJ2EMseLExToWnxKf5p3iwaLc3BETS+M1zgWSCuuaucLMtHHvNwEg2tAxr/MOahR4fFhzOjYMTuu4Y7zBlRdfmM/Hn+2jTAWmujDNvamimWNVMsqklesyK5ZB8fjyr5drXHOiVlYxPyzg/9F8JbZRbKtOpZtSpUPZtMk81Vz6csmFLYT2+u8yVWqaFBOgIikhGfi9XM9uetUdGc6jZVRup21Np18Kn3oIXPdcBndiHSKsi1Q2bJ3rWQuRnI1HhXlni01JcmXyO6OeDFzpfKcqBMasqjMTGqIU8njWMSatFLR2gBsNyA3aLffWUeizbx8cDgHTohABKWp+hLQ6KK1ilERZ2pbwFg1G/E5tuuhYVdLfpiZj6rvm5jjCQXImYv/VQP1zTgsGZdVEcBc/mNoXX3Cmj91aND19ZrovWaaL0mWq+J1mui9ZpovSZar4nWa6L1mmi9JlqvidZrovWaaL0mWq+J1mtiPV4TTb0htFqsVWjfc4V2yT4+Hp327aqxmcsXCKfP+ELsWEjeqY60T1qigdB+MRdvr9Yh3aQkzr5QEksJa61RMB/wz/zrpkH3bxMya1sDknh/8gemL1LaG0h2Y0uhaYnzqpp+GIVXQkAsJVTMf6EnXZu6oNKqa5//lhC22Qva7AX3NHtBcpE3lMCgCCkeAquVkK279SDop7mYlVIaWCyUzmpgHY/CxAZZRmqBhAaWeI3KTEp+42GsFQiIMlWSLzNPUBdkRT6C7IXYKhZVOZNkClob6kEuyDlob+Kkr5BnOTfuY+LHFnIjmEZeyGc0CHdGIpj2XBrikMx3hKtVUIMJoy4LjHUF3rxQyJOUhoMzNgiYMmk3aCmikMm+ue7ptjlAgDcgJzEL+sPIdz2Wf6foM6zX/lUwpdQw9Jqq8/sfU+FG4I2CMy74vfi1XHsYfRT5yGTKHiQMhm3uwYdzf9xTeogFFsDchCatfxbkSSxhMuy9TV/h39WDjIskfEjMalSrE2EjaAjcEfcBP3InJOuXqR+tecT0ScuMiQ+LBnTZiPtgYdEbRoLIY4VGz6JBc4c1w1ziY6Ieq/G4TwqOMFGdg4o6jDAjMtoMJGTsVYrq5IBf9S/9Y+qDbUBl3pyTocg0UVJTenpXhhuRdBpzj/1L/xP9zqfRlEj+N3tN9p+RT/xNytLYZAX+VcRaq6//T3pNz/FnXIEG36jnu+bvbPZBZdpti3iFxpiLNnSVA1U9+kWSq9/fHb29+hXOFTVymmXl/kVWqpYLhFoZYt7XEv2vUluDM1A4rxZuqJTC4cjTw7fAkqENO2AMM6RGvuoLGjgT6gMtBYUT6G3JFQx3BWT7ChMj1wji2MYSw+FtWG78+Wsy7QmVJUutGpDz34/sieMxqYeHZCJ0b7jvHLiH7NnoeScZNzZ6Vwyt26w0vFZFTsSUoUy0EKlIz+y9eS8GqjyYNUQtm8KkB/nP85PPPeQImEsUISFTquqZ2fwcAJm29+Lp5gGJkI9jyh8GGsHeMtm/9M80T4LYnub6bDcTYnBof7e7u7sLMhOwf8UXN1niH5cd7rvse38STr3LzmtyCcUF9vYPIM3xZUeGcygbIKV65LLR4bPnl52fHS0Oy4FyIRToqVfsVHdhPPaIyPrzwSJUHwFX8+U3AfXHHguMs1Lx0f+dythk9qd+o4hqoQVT0UouK49jc/uHZuWtfW41P5s1gaSE883EhBbs5qOSzu9OIF8xStS2jOz8sFwGuNsggtSS9HUQaYmkH8eR1kr6Z2wqMJN9XrBf3DaS+p41isfpflMK9wcn/SdjjUTgNLYkHHmeuFEhGkBO0KGREl/4vWLfCOANMd80+DET6nFa7AeVgsWf8cWI9z9O2A3j97AfrH6yQKRtS5rudbBtS4vuihY1Cr8tNbD30IyVj8RtQDKsCFxVwEeH3mJ1LGB0KxXHLf3YihBf697CSWix9x6LBVX7+ajAeEvMdhgEvAERYWfCJWgodjwxXtqzqocvZ4E/Z97TrSqwX2lPoF2ZN1UL+tsL+rhvLejfFugPPDHeOPCn9rQF/s0Af1+DcF8j5O1TgYCFAdqFGrqFYPsyXRFA+rwp3z830Sgiki3cbzXcq+1qlSsPgsEv3cxHBfJ3x9ArxN0MmAvPG1Ln2yJ4rl8phXQBAefU+dYI1uPGlqYYi1jGQJ9coRbztxvz9cFoYf+BwH7FfrbIfzvIb+AZ24hgzHp6i5VnD/jhGIcSLkmM3ARelApYMxFp1mYCzvqE0cDjLEhh6UZoDSroFyA02p8cXivyJLc/RDVJH9/zkAZgUoCHKug/YA7j10wqSRWsBuy7w2ZqWWhIWxqyNZ7lqxCIEffCQq/k9+oBnvvZzJsbP0o8IZJJqQsfloXGUNfl0BX1Tq0B1dzTU0KkilHemtI/f3REFDoC1vyfnfj4db7+/LqCUxV+QEtqN0tqEWRuwacqtZktnW1IZ/nYF4GVmaqpOk0RpbvxuVIUcecH/N+yPlg56ph3jCikjqqZNPRRe101l6r0nDfviNSS3tstPdCSlQflFdVSk62iJsZramlqIiCbVa31XbVSpnf9RklCE5WiiyStSnKapNvlIljaZCaLWcL1Mrbg2ubBaPNg3Nc8GHiJN5UDI4MQD4J0ayJzx84UMalbLfGFprHUdfXfKRJ75LqxPJWinTkSexSG1AEKmmqmjGAtUb1FvaFJedn05seLkS+h2bhcJhwTveEtL7BhU5mB6zWjdcEWPh6wvht8Xlknp4bY+WFd5CbaNw35Jvwxj/qZ0Mdq4I+jH9PAv3wApIVKa9STpbHuoROaplqyFrPvrXKsxerbxOpmcYI5hVVpbGAdplYW6LyGtLDqnzp2EOMF0wBMkSFXFSZaHN5SHE5k5BaE7ynjXLCFjweMt0DL0aRYqAFmbFQEzco3PA2gCcqWhHFYMKxi91oAvncAfAonooXg+w3BhZv4eEB4c7jbT2HgpiI7ZlEwZoOkVi5qLqqU1vhCD1/oqRdsLD+Fp1b9yqS8LitTXjgKqFVLGoR8RCELqxRERkMJaltf1/6VWDvWGIvS6SvZdy4x/6A14qNTcdcCLu6OtUIt6t4n7UN++x4AzL7BzzlGhLh1qE3DWCnGIuYtHECBb0kr04TeM2RXM3zo0vhtl7OtUjzrt3oul47wffjT/KS7SCmh41Y6QX5SpS3vBpq0hU9Nt65TRQN/LkMxg9d6Q8i9li3y2wJ48Vpn6hO3QH5P68LVb+lDQPm7KhHXj8GtXLscb0Cdv4YBzAYAetwUPVMNf4+GkMz8Nx5+pEMbRSu1GFZV4BZF1+fpUT+y2veBPg4DPXCncRBWi+QPCslr9rOF8Y3CeIzhy3LSqlRAT69NpXO8AX6wNaZey1oc1UNiHuaNFxTKiAdhz+PXzCX/+ecFigdaAZUqSkAlFP6OZ/P4UL2+UHKy1i2IbhpE8X/V8VZwMjBLvonSydbOtii65uCjDIAtnw1u3uP+teBOhQpZv9Abcs+D2jL2Syk1Mp2TD/HvWYPDHFO/iyiUIfWhShzRfSjdCmSFx2H65AxL0UKI6nkY8BkjjsdBnSyZE7BQZZk/DwPhj8kx2g9ZQI6icALYo04TeXJ+fPSUcEnMkQZ2G84RegKhEprWBLquGSBh8XqgG4ezc0eOznrB4ZMK4y2SWZm6MWaLQgELVlARBlZPBdOqc1fat25GVDPoMJKsTz6MiFCForq6GhKWuso25xLL1BROQFtc2CA9kwoAFsYQnToKZqwhG4kArRQAgNwfF6By80o41qWI6du6UDB9ptQtGahbEgP7AL7AY51KY2B+igaxNzPVWwLuI3WFyRsFXKXQrZ/b4O2MTj3qH6XQ+0dnGEnuI3E3tDhkwSzgMkbtUcDiv2eByFawyKG5geW+BtdKhbaFuzWYPmNBzwnojbeD/8uCHYlQWq1ytt7r6/eU76TC4WN0qyvwe5Y6Kb8Ca2xl/DtUL6VZCGreWwKd0+PoZgSblQN3DlPy5fEacbMn/1gfg2NtBtyXz+IMea6zhGHDC100jTfUJWdar7Gp+bwDrjA1mTVd2tnMGejDWnZfzb0+ZyFYj/NcVwHTVHC2+3qYVZxYC7r9jYWl9+U3Fi5+WZq81N4UdTLH6cVvb8s/OxcBFr32XXJORyyc69vSzT/QvolvP5+TPzi7iRvGP+gG58cfPqlynpA5S1GtjyDsvaEe9R1ItWWuqOmi5LHu8L9ZIAhO5zU5/fAhnshbcU7eiNBnIXnPmJtMKPtAv6CqxEpytk/OQxFAGLR5peCRPcppIEKmEuWlBrF+z4xxAQk2Mr/944/Sca1HmZdUPVuZe8P8rptbK8j98WvySfhgZlD57E6F8GTRYpc11Z2afXjPA3YD+ogjlPrJGRQujvurbmWdmriBfXLiH3XDNLeV/DszpQy4FzzAFzYA+sY/tsSoVNCpSuZVivrq8eLA3/C9FvsVzjq5XWjh/zaZpSbRmQWiSVVSG3siEJx/bF7JZbVJtSVO0i6f10ZdKNOEfPPFja81HNZw7aXC02uv+qO4TvHRWfSGNMgs0fRmzKKhx+VkCbE9fnNFwT3uZ2HRPX6zvUGt8L4BepScrzWL73HHSwvw5Zem2WvtjWmF+FaIb4X4VohfB/gvIMbH3a4oyJcTgMZvtjSgFea3g3laVJyXfOzTMArYwOP+t4ZC/ZiFFyyYynPz8kd4N+uRB10zNyPjh/Ae8VT7AnaLElfc+OiEBI3iHJ/6C36RFd22tzDmxPLb8yguIh6Dlh1r2bGWHSsnJ+qSVPNgvZgu9BCrG9MT1fliZCRHOQqwvVw4L6IvsL2O8FUBIAl/hgGtSkLyOAlESxNamtDShJYmNKMJCxKBRLRYVqpoQhdIPIrOEVhOKBIRokk/W0QrkvifgE1FGEca/RWxgjDXMzYKmJwopUXmo1SOgA+B8B2PomN2biKxs3R8GOJVSPLg4Aid7SBi8XFpqVlLzVpq1lKzRSWcpvpmyXw3jTjvrnPl1JkjgmKdF3VCfg0IkAdseEeqqrdJSBVxuZx5dM5cSFRAxwFTAVElMs9W0isGCzTAVyppFsQapVcJvjTAhekvMJ040LKj1gsGMqsIcY/JzK6T1SiekiGSsfBIrlkAGEg+vF1kSg1Dals/htugj6tq4muBBTDC0p3g+W/ON/8tfCYHDvUHQzZQeUYwIq406WsansL/hvePqf+GvdMv29h0zkKS7hsKMGEmP+ETHDtf7sbzxI20UYm6U1XvBmLk0SWvtEsa18zCzvvkyDdxg9m3rqkXMeIxes00EMIrJPKdCfXHKoZwS9AtH/hZdPqTJpxl70Bum77MIKzxlM7B7tFpFKHY4sWaHAeVvXhTgGFuVQVghD2H+r0h65kLvxJc7ChqVpFZ1J4eNq5GjVh8ztxYvJ/6sucDx0FgcJlrQUDG1Vcn+9cdwQhcmljeG+5B6TqIJ4e4cZN/YQ5TMOmXTk+PgS3yxdYpddcLDf8FO7QVyFB8VlqQaKXuVupupe4mtA4RZAlqF0m2o5vHBZLrVMqQpwJIj4apt3GBhUwEiiFnkE7hlAXki2Sl5ZVNipPYH6e0wLJVlRYW3u5cTRe9WgIRjSeat2YzeHkWQDoHlF0xzwn5yB0GiR3Y9xnXuW65IseMBh7k/PCF34NkyGQoIt+lJg+sStmd6g0PZzJ3JOAeHzFn7njInZNRhLpia7CA6Q8EsZxhDxwygM+ETLQR5pP65GgUssB6X6UH8fRHmM5gX4A3kKolc9HLB6bjUI/BR5Cp8MOJSerBQxhUSw6/qgVT04k/zbgJSTqNa0aF9BtmbmQOc5nvsD65SG+LIfxTQOkhszou2rCV+YyjmM+IE7aYac8gGbvDZxTVSWtSvjhRIEVQreU4mdG/ItY1S9HDQ0TUm5oFg4Txc32e2DUXkcSSvn1yjK3MJhKKew+7OBFR8CskJQlpEJoKynCa4uLDZgT1DuwQv8YdIYe7u1Y6E5VjyJwS9VKh1SJWtliVPkz95coF+ES/82k0taoWmzuNCihYgKLxuB+ysfYYxdw3WKy425mq7sy/uK//1VALpNHKqiesdyDJNubNN8NDpYGyCVv3wceEPGYvhS5hLfnfa0tA04DNg8ntlU9OBIT7MhqNuAOJdrw5kY6YMReTuZlEXLc514P8XGNgkCDP1MDQrU73WZND6ojIc3HmQ4BXVdLNvY+cfmSk24FrVySpZn6A08hyJ2uIKQSmx+z5Tqo2XnNz+unplxPdxXGqhzLDemQzKE7mlRr/q/J3M7niuoT7jhepbHIhgBx1e8L35sjLQEollPAdj0rJRyY5XMinQFCmswI6XHR+kiaZI6Rv24e3d2y/LtucEuXbQbk6QX9Bvv/3Ihhy12VozT/cPVyii88ifA88QWedtyx9shreMQsAK+166c6rSqalfOyhUaP7opS1y1wZ9aZEHkkAjxswMuIMqu1AYUs/qaxT3zkkXFQylOKbXC4VKsf3J35Ps5MyTqXomhSNwh8KGsBF7JKbCfdY+gaaHiRxBeC7Yr09uK9zI78lwxjqNRoxJ1RMo0eBvdODaQ8UpdBHcSPJst67ZgFwxEl3v0gCe4oSR5xeEOUZh/qa1pTbBlYChJUUeGVHSO393WrwKhCngNlbECjeUNfo+LYDr6CHV0v0AEvjcZ3eeusRL8JzVQB6UYP4uWYMwvlyDIIJnhMBiTTwLcUu9An2hDDnx/qa9BuIci0c3h84bIFwESB8+DAm84xbMxEJciULSb1F8hGdnn45jV8rzUkEAKWu2MxqXJSYiBodl3J/AGbOzpid6jBWv2a6NqCX6FI/al4wVsGa3OMam2zNK6BNDHnwz1DjBaRg9mM0kcIaEIypKLD/CwFqjbDRXfBV2A9Q1C31IgvUu3cty8UnaltBZGukPzj5cWLneviwb1+NVqVh3gCRgoC3zEEraybTksNdhje7DA2K9PsMzInIY2DdE8XwsAIYSPWUWASQTcCHA+4SsGEkFgsyFO68T9QoYOVNOBmLL4oRAe1QlMR3Hxaqa7dMW4K6yFpMQQrG0q7aZJhWwshf9ZelTEMxLgGEORA8EK1dSbMuJsRs+pGj6H18xe4YO7hTEr5w33Fjq9iXTSCPi0jRlF2JoBZLD8rNBaGs99KCWchoOOXhF3jxDN9LC2f4FIEqNiESHIUEpnX6HP+hqygoZwXVO/Aw9kuJCJazQ1jjKINqXKBDv4r1OxRPQTioteaEh2wKv3NllLknltSVKnx4aTjIKAIv3vdekv88P/lMPkJpAuIKJ0I7NqI2+04dsFShnhCLgpAZCyAfhhIAKdFmRsL8MJijxQ2YzoN98g/+pkvYd1u9/vE9UKTjs4/vVQ/gwwzMKvCY76gzMUPE1ARqdgxoSJ5Qn5y9PyYHBwevEvU7UUvWxY39cnFMxGgkWdglQxbeMKZI1heffydsJpwJTtgXN0+R9tChFF4UMvL7xcUpTAv+/9yUb/ty9tGQrYmQoaFYruKLwVBNuKu8gzmcWF/4bDoL53pKGCahDbl9grEZ5MNbSaCKI5UymjKXRD6HbmAU7mduDY4UMBTbmT8SgWNM3+Dy4LszweHMfxZEoEuiCIgbqV2P9bg4lvbmKKh70rD8yJGvj7ZDvfS9hMpTWuUAxXyDWzENW9ijlDpZr7/9IgvsF3ve2zPXQlP2J+qNRAAHBC9lcOvOig/Pis08PubAFUKogCJSZSRK3u7k9womr5kmgE7GXMW47+3ukk/8DfLdxOPwBYgwcEQ+aui12yv41Q+w/S1/17P8dx2r4XsX8xmLVZI5UnWr09zfL+CtLYtYCu+Ac5BY1kgFiQDnomS1zWLHH/FQuem/yk//QggyBXroCN+JgoBlDri6ABKkzNs964X+G2cJJMMUYd1ZSF0aUjLiPvX431oNj6t+P/04cPUHBl4a8vtp5rxKW4l41pTnXzWq6/T0S31gl61dQM9Ohb+qCFaWfz4H3w37DauxTm1owjaMj+TqEVzkjF2Lb8Cn2aNpraVCUHyDT6fMBV9ab641nbFZPPaT1R6lUishjJwS+SH3dLZGcD3U9fB89j1EVhW9SrdNNZHb262I9qiNA7tbxcRd2zTWH9cF4p/uo9yWkS3qCbe0l305Z9E41aUSP8UNCq0YnpcpqiizltgtKLtp+fcW+PaWCdxgIrBcfBNzjSqJKy1RrcizN+3JW+9iXDaNz/EMFF8DUj36UlcOv7+MJ3HRxm+4lGWmpmhcy9IRnqd0xlX1LCsn/KAKW2avY7MCl5kwHlPvEpQ5irE8i6/ajzgLwr9poHgd4Ds/77JIZj+PU0uac7IoqHLeZnCwIAV0ZuVLPVYo8dlNtsDs9kHhGisQL3vJG2u0CjfgjvCovrZu9WxbMFoKfbrJv5nLw3uERo1yatud7fzI1df+2amoBpQFNNWuCtBUPZ86QDNVf2gOzCBEcLvQzGbssrXJq2xBp5ma43Gf1Ul6VsHcOrAr3JwNg10KNlIIt68suItMkTzxBdGTfNopQ8maPlqUXBAl7xkq1pRpymIahGZUABpEIdWgma4PIGfMAY+U7WfQHhCk5bdna5m3iqm2mPS4xEhTTKgoFiKLTzqQogKidOBXDUqZIK88z9Xi04MXcwuPyNYiZfVsW7B8ZGJupEMUVxJzd8DwQWUv1l6XuThm8Rfe0y9VgTDYOt/qAKgaJD5nYQEMU2VqNEFULSpvkGss36ztkoYbzLOZSNykoxZWHxesWsBWia0OnZUbfqd0zJ0etOkl5jRj/nW+obF5himHNa9UGNgGDYluSKyG5ebgwjfuCjTVIkBORLXXuB5yCVyqWo74ovbXdUNLpq3+N9nNmHOrtZLWzdxADHnieOAuShi4Wj3d9AfVYU+382wNnyRZcA055rbik9YEp59gdHJ6fHRKLGN5GZiq1nHSx1O1dMdq6STpKZTF7iQ4CHe69a+AMsB642sTcB1RT1agq36M8Ip/J/hKU312xsxnAfW8eS+OJeuUY7HaqjCgvuRhX8FmnSkZn4tgzHoT5UBkAL+YNy1GW2Nmhp8TD/G8kRm2MXleaFkE+7LdTiHqtsLp5oXvSojUE8B/LWxwthf5dpFdsZ2NUL1qsvcLzJt9SYvhC2P4A0JkbU4vweQaDnnnB/yfMagvwCuj/akMutFmUIXb0IBDTNjUSlGTPubDOakKbdTTvjXk7t452WhkU7oX+Fw60/sFzg0+o0XmlrteBMsBgFcF8h1X3PgY8bAYopvXepJDBDo+TztJ6QbkHBvgDuR9pEwjPCA2xnM/FARiojwGwSv6qmDk8ZD7kGkdX8HnLew3944q2JUm0H/tu/3QmbnRdIbnEnWF3yn00Xn9owK9Kwe8Xwje8FNaFG9RPIvi/RhlNw3nMhR4OQvdLoqhHF7pQVaAPIifh2JG4FExfKcftzhcgsNFRq/UylkIXGrcKn7hfiFo7Ue02PmYdROIXcUImPyqL65KWKm5RSxiC1VqDNqRCfVCTM3G/d4sEOMACjrhyUsbOyCoek4iX9JrjKpWFhAMx8dCeENGPCHDfq3xcEfc+CyQEz5byozo0N5M9oYRWhOTrvLRpLjvb7AdObHaFZh14PyoHqVd8g+0JxB2jsl+4nO0fYrvZkGWhetxy8qMeL8Wirasnvn9AvbFvqhF+ZZDznHINugtwyIvZk6krqvRVkJnmv1NOXOknTiOXDcGU0DQAlpSUMDZdZEIHf15Dplefjs+1X1AXqYYg4u62j44vmM7ZIKxxkrQOJ9bg527M4KxgB58oe+4X+RjyU9r6chDlxaaUYXVbJrxEDs/kntZEzNcohNXkcML0RUdx7kwaTHRxeZF6rpJTdDs1ank7+2PbjU02QDbBShHTajuA8Xu5b+uhe8Wvq1Y5pXhW2eoRLheRBYw7y0G3CaT9+LQneQAXx28H700YDZvYbGg8f7dB9lg8Y+5X0Rmle9ryUxLZuDFmDwsTmj4jEH2/vIIoTEL/zjUcVnyzfwofvnUvDpw2SxgkK0+HVL5z7fvTs/eHR9dvHv7lSg1ajxalnDk2nbB/yVkgUrUbxIrkni+UMTGruUHJSRUTtYbknzVzvVe8o841z7kPA8ZXaZexHK0x0kq8MWzGdyI4BsLZPJLz4SucjclRkhGA2fSNBfkuUpjYqoiBmzEv2NuSj2Mqt8FydOx26JiAsvlwkwGvplwZ6KKtqti91i5Oz+SlYuys9dZJQFm+qOthJzx3hekxCyYxf6zpiaa3IHV620GVCey7CRaB7AxZOtZq6oaHYSfGQtCriapEo4OwM+svjEes/w3ffBdLDqRXUWVVFT4xOQgzyykatnpJm5Te1geeczqxrA7NBU2qvrdhX7N2Vhw/gUnoGDiMEIoQuoNGi0SNs0OVbM0P20Y+afejK65a9bRt+fxVXF+kFTW2l8aBBTuBQ67JhQyf6lkyKqwxgpdWz1rpsH0mV0I83vyod3Usf5awSWmdwUZIhIGc4gNDoVKOp5czfXdOhyockOyF89lVmt9On52O1MmpT7TOTTOnBYXjoZp/7WbmeFP66j9s/jQxN/iR6oCbeKHIEPKfY9J2cMCOD3d1JihrNMQD6KZoTs5HXr5v2r20+JDDHleA0Oqb8ggmTqW6SllSWMmJ86MlPySyo20QoS5zYGmQ8xXYkBnFn9WHvjIxtSZ92oqIwq5FrbRxH0ZTKrkG3VjnWZXv/IAWcO8mmJNcOYyqIeg/Y7qGg9NmYnqZlP6fTCch/EAhVxbIKLxJK4+ZuqOgQd8XQr1Xf2fbke/nf4tTm++uwuUHSbj6pT8g8oZmVZAPm4oR7M2HY8DNkZZHb6dydwMY3IfT/AgNbWD1KR2+/vP9KQCcbPAAiX8BryHnI2JFqhfqoKVSi8UYikcVfAsa3QU1NNqptxlEm4HsTom1BuLgIeTKQp5KkKiiEGPiU1n/Ld2CTMcu/7BJPeA0m2drtUMaqMjgeiCLQ2Vfbqoc/UnUaQ2QA/gptd829m+8Q06wtfIP9icfCgo1GZ/yv+hhiDfGAT4/U+k3BqFGoz3ztSNqxxjEoYz+XpnZ2//YPSSvtx/9nL3+SFzX77apweHL0Z7Lw4OXuwfPHvVD/b7CRLpCj59R0w7SqsTsHCQrEjz5TjHV61VqVkSNRQsyf/MMQDx4nQzm1M0Q+B81Hmqm6xqBXcJXSNDQVzm8euUIJJMVR8zBNavKOSEhRiYBJB0lF6v89r8AScNhHL4hUpMdJoBVv1C00UGWR7K4OXQqGCFdd+wOtxjiqTVCNOgLpjRMGQBguEIa8a5/Jq7EfWILu+kB04G+vcf0ovGP//9B/seMh9u+8+8pkHNwqxh41nAFFweMCcUQc2J+vcfoBf7ufPvPyYiCn6qxVarXz0gbE0yiCnsiE9wCWuWGTc2c4D12sOxaQKY0AaPZUKUq45ksA8wlx4R28YXoatJdhrcu4Z/seER5lh8ON6yETJM8aboWkgxu1W5LhL/iFnpDtKij8wfwwnY23+JhCj+N2APVvCsErBcDtPTlUcVwzGbwbhwkziWyF6G97LYfd3LQM+li6i6Yp/QhekwAYD5Z8Vj4rf+7HaoPz8ZlVaSWmnItXSZWZmfcGym3P+g9ian6cATFe9pN8Vufm1q3Epx/InYT1M1QInym3EzUsBtq+PWrpG5W4VMQw0M1IJHBQz31T5gibUUQrTql1b9ckvql4ehbWlQKiSGth/mzwH0Uensp36vUdS8mZ/aHTbS25gaDo30Nroxfcg6G8u2ZS9m4/ncIRe2hEGslC6rA2fR5VLXwmJ6gu9n6UkLPpsFn5qKHPUeAssgCCaVaQQf0DJVbBPry7Zg8lDA5C0+GhqTccVOt/x7M/69yCnctqDSMHUAyA1VFd5HIvLXKSW1/HvLvz9S82lVCZlZtAmCaqpyNKKpujGwXqZIektPt5eetsbg1hjcGoNbY3BrDG6Nwa0xuDUGr2gMbs2/rfn3Xpt/Vck5t9UMbciyi+ubEgpbpVCrFGrtKovpgHRhzCRoExUkWeG7j4S6nxGdtcgDx+1nt6R5Vrht8k4ie5a3tjiGfsK82O1/NjJU2wqjzvLxp3/s2XGl2ayS1qN8Yr+d9xhkmrQCG+PRLddLWlFjVRkmWaqK2Fss3DIDrta7tqLMvJdeaLXG0grGHM4V8/jEoZL1uC9BKAj5NSNQcBJBGsPZc+PHPOUabEylzANEtjA3ORMbYR4a0jblxjagYdEiQAHLE9+bxwBWpJywPzPy+V8Rs0q4ovQUQn7ZZgz87t7+weGz5y9evlJ/vXhu/lK/IdkVLvTdeNLFgkYmltMSNU4bzXQ6X0TM+MurEsDO/+ujXqhkdDILBBwZYIJGnripng0c8SBUlR8k978RySCzAfkfZBSIKVEs8a/IBYY0jAq0f8Vxs6p1/cpkCT8il7651hlLb55al3hKebYo5oTasOOHHHZ8p4LJMiHAtsOQp61XFpqvK1NJa9ksqIi5SkRoGSNXFwSaivu0QXBr2beNGe0aK3EfATEtUT/95TXXNtXGF9jrtykesYyatrzhozrOW80b3jWbsFJkSrI228Ia3HNOYJFoBVsJZIUu1GQpbhS4YPETlsMUd4uyFJcyF5nn91BBlPrwW5uN+ctieJamtiZq4Bap7f0DtLuSdO4vTK0c19AIYOxABvKWhZR7eWV0qpGrGrX4clv4YlIU3id+XqdeHQSM6glVMYWqVcypmgyy9cxhKzi0gkP52QgBhgs6RtObGBEZBoxOJXp0whQllAZywf5Tdj5qDCJFh/FLyQHEWCFfJRAmT9RUoFYRTORp9dLuOa/2d3fdZy9f7Du7ey+Hw4ND9uqA7TvuS3p48BJpBjiTygJN7Uf8ncRUilyzQOpYpfSkCl1040k8Kz3Gn62DW9hb8dENNc2sObfF7mgX2gFtkTHVkltuafEPsAUoNOq1yY93rA9j6eLVnqSCJT0slHXNHOIt7RpfOVz+ArvHGiTm+O7cQ9FZk8tWrX4rXCpGCjWUpBFjV3KlOMcecm4U5udyFwps8SCk41Lvh4IE2c29HxT527TnQzIzEbgsGAzn1bM7F0FozQ2xdMSZ5/bJW+UqIsHP+yqBtavq6cWxFzk4/GrPTjlTK9StmR6J21aPnISBUOlYM1H/gn7TU7gbx5kFBZUixxS8aXfplIIR2PlZ277huShtHaUAc4epr+DaHOxfAKyeRkOPO8u5Mgf7AwhVGDg0pJ4Yp/r7+rNbI4qZUJIOVtYJOR70vHwWB5wsPD1YpPfq9dXkL6lXe6OyV7PlWCyc4Lx24tP5AJnIejFseSJyHDOb56qTBYM16pc/2E8HbXQ7maOJcRqS+/G/c2EdDZlPnEPrwtO68NxfFx5N91o5Y3k5oy81H79JJ568CKEddM4VYFc47xjc31rBYWOOO+tgqvSmmmgys6Ww5z3d/zo4r/XxXIrbWhun1PIYG+IxNHuheIi1+U6ZDbhtO0t807bvKrSCRyt43BdQWEjwuGsedCX/MHUotoXvfBBs5oIeYtjfzg/4vzV5hiGT+mZ+rnos8ggr5FatZ/dP1y3jj721mSDvuUYPsFviGe4fXN2FkHzfQWgN/l8VMAIuXYgTVT5fdoMWRdaOIpjKFNcYUpjGbl53KnW0RpNWdmlll1Z2eWDMwKPVmC/kn6P8IVfz0NF95H104gcVXjraIfPeyS6N/HTW7la+lKOPXuItdfVJZtc6+2yZs0+Znhy3bGuz0DRjZcqz2WZKt5u84V/OPirGhptDW8QVxINHAS9MdlvHq/W5P2YytBLeQnqrnWtk4lZgRxNWVKWLrE0xHIUT4EWdOOF2pUyTbk44CDcKlGPn998vLk7j5bTWbiiEx6hvrxYSUczzHFQmnoZuj0/OzonAZ7J2rIIUuLkMtyLgY+5XJvzLxR1M6XedZfIZ8kbMB3peyfPHVS1Sc4WV0y9XLxEe41wSYjVqN7t7X1eUQEqP+9bIIOWRNOcNJg9yiAkFuF1JpDTeoNi7KBV9ULQzBUEGBz+7mlMexAloa3NeLnB+Vd9E972WA1wpHyXhERWSEoJc7rtbf7PW3+we+5spVrmVn1eTn2OpdKM+ZwVCsfE6M5Smyu8sxvWtFYU35nm2USY3lqTyHK4+eTHp06evZYsfNFu8aIKy7WYn6/k86wJUn/RtYwFV7Ov6nP02rsRYKq1Cq7xolRctSrfKi3tBbVrlxa0qL+5ajl3NZ1Vv9rbIrg9EVF3Ub1X1uPND/bEu31XV65v5uem10H+1WO5NPb1/dmBpffLt+Z/hoGv1Y70tdvj+gdjdqN/uPzStw5u1GljQYVXhRqVPa6pJiyu3gStJBsNW0G4F7VbQbgXtVtBuBe1W0N58BsRtE7QfqpF4rCqVz7Bqdd5IDD+vyt9+wXqcZYKzfkrvg7F42/jaTditW47pUXJM949ormxDNdXMW9GuFe1aoLovQNWKdq1od4+oVCva3a0N9f5LaIpNaWwbvaYehxcGulDKCt6/f9hd2RKdeQDVVnICnXloXa1EdIbyLFwSRwQQj7jVwt7GJKwGFWxCQcw+bqRo65LVWmFqel6A3hoW7oBzHgd0Nllq081R/A17qKi1Y1EIbEG4fy08MAVxHw91UlSoiDGjrsuhJ+qdpmZeVHcnx4YZ3iD3wGR8yD2w6G82WrayNAs2blyRZdtqq+zvL3BaoTjXWnPUuJyOfSFD7lQy2emXpkxKHbuU20Q5o37RsH7kKYqiMS/L47j1c3WEF03tzhMGa8p9PoUwb4h8gv2oa5XZHU+V7dIjfFV1sYJGuXtubU7ZA4UTROE5/9DsUGGUHfIzC2y3I1xWcCm7FecgFx3mYnWpqlmVw2b66KTvbZ6nVdH+yPTk1yy+hHoNuqkLsCBrWHI3t0Xbfw9YxyqW0fAOPaDzVYxjIEYctQfFzi2GPxyMWaj/PtWvZB1YdLdkFj9Pb/2Z9qRQcqBZRNOcPIGZdwnubJfMJsJnXUJdN2BSdrHOHfsessCnHpmykEJaoqeXPpVSOByVeDc8nChZUs/kF0mcSIZiygISMEcEbp/oyUviUJ8MGZETCpod6gRCxi9iWb1LXwRj6vO/cTFkn4DsbhWfCwWZMrjLWNCP+sRurhhfoDKU++qD6dLegJl6cRNGPrw1OgGz6DcTIQsWNRSxA0u/knXOIlAjp5kLrH+JDDKZUF1Th7lrJbH1cJtzy0tUWLsJzFZ2UcW/pE4BIMfgj8NPGorTyLtYL+YaNUNk2K8mgBx/bSM0tjdQATBxIzw1lDgeBz0N9rzQfi66mO9ghDN92Dpqts8Wna1kwTUL7mS2ayJYBmlLKZRuQM5ZCGoU2wi9OlExyNdP0LvWYBxV0QtUYs0rSIax+tZQjVMahJwmxprbpB4ziqrKFLBnKEo3UWtpiRCnw0eXPg+JK5gkvggJ+85l2CfHEwo2EQJHcg4Hl12zYB6vAUwzNRhQJ9U1jVeof+mfTHkYMhc+dxbOu1B6Fbg8lXJKEhow4rFRSCLfwQHdPnlHnUk8O2wHShiPTzl8fCjIXnd3d/fS/3LxvveSDOchu78UTx2UJehdStWTfXdDiPIJ74m+IGdqCp1CvcxhISIGDDbSF0TPDxZAMt9NbB76u7pkGCld3IRRFzZxSufAAkWSjSKv32mJxEMkEpY0c7tUol5p/VfEIlaeslE97mEOi1xKxv9S7xbIGFGg4Ue9T8SNr8oZU38FRFpO6Tz9a5BYIZty1abEN/U8/ZkKW4fME0ALRIpMbYLTrvkkOHbXhz1s38lw2M1eNaqMNO9bpingCviPTj8QBxblhtrlO5H6iRIzvMU844WJXB6mlCH1GftqvghP2drSL11kcgn9ZY75EmmWju3ESsDecB/+5j7yO54+ZQ1HKE249Dkz1zjHUlWX+7UpltRC6C4TFgQ+Q0TAKc2JZDQApia5yJUj7iZjzsxpLRoTH65jyL3d3Z8/jZNSIWV9T7kXBUCvNKVYE0lKLtpIjbBOEoSQVEp/NGAZj1n9T5RUup0/lU6OnOMaJK2yv6e8a1kw5RJsFfIsxuAfcVpSR0xtByPmjllfqf76eHj6SD6+rkn1Fl+WJTMuaZKmY10LUiqpxS3OqASuLfjcmJ+2gpptwjz6ryjg0uWO8deqmVSq+c+uWuWBsaA1wW+1e1n1itVPY0vpsc7KYjaypc3roM0NafCjhtpicF0TimrEuj0crU8HoPrY+aFuaU38vwZe/bggpr8YeNXDGHjLkdZMYiM4290q8eQ8ud3xcq75KiVeAO193sx91jt3e/e5JoZe3094ljUrFt9MI+i7Khae0CHy6EQqJyqnvbAWiKkl0vpTzbK1PErLozxCcTDAvm4N9qpjKzXqKU1pb6YsXUVGsmIM/KINYvAiKgxVO3B7sOudPQoQXE4MbXxnm+DsFx1M1sLqBtSy8eK0MHvHrKO269wehjKXl/sbpCC0OXSesZlHnUSyy2KmcQeAklJwIJibwVRyMcHwIB3rFhv6oTlUW9JgbpwWWgxuMbjF4BaDtwKD+dgXQeyrvDwwN7XwWzq6HUf4MpqyoJHZv5e0LnYAIMdWg3JPgLibGMR1MHer10sW7MjzrIWiYUidiXINQ3eDFlG3wNnA7E8vSPkWPWKYvXuNwgYMzH0b99Zhao6BtMjmTDNYWmF+Nt08OvDcCGtr3eYKt89SI3Nm2+JLvpHgi0eJ0kui8aMF4/tngm6GtEsYoxNGd+eH+XMhI3UxZNvW6nLATszWCWBDLoBaxLZmumHQfkC0YQGDebwdreX8vsLQRiznzWCosQ29GDtiY3o5cBih2bCE8Xkdzq10Wi1+3Cp+5PetZfW2nNWr2DKi0XFt8Ufbg7t3L4tvwLrfDJqrQmLTVv5CaLZtVVXonDZaxfCMEaCOltJ5CFcmH3zagvbGFAIbCRVdRUFQeJ5aqrHlVKN61x4w4dhiW9lKVGEZA5l9MSo1u7NITuJLYROT00hOyKf4QSadQiQnSEH0myowulXkru6jkABUQ5C29AJmM1TGbO2z10L0JnwXsrn4VC6QRi0Dneav4WlQ7X/G/2n1MXl4t3ZOZ0tbB+QDNK4b8K3ESqV4j+MuhfY71PlWi/jU+dazppEg/pHzzRc3HiwE+Q8Cedbmmov4lDTPWPuTV2S6JoJOamqcqAw2YU40nUxMJj9iZoIbyEICkkbyrt1lS1iWhG7qfFsg0aTHqMTFrJ8+NtUFbQqTSeIuNx/aZR6dDyRzhO82gUgYYN7Dt4BYrGvmjQuCWCExR8f/SB3tlvDeCuGlzrfjkswPUPUgTipRADRqqgqsaAJjdpL+fDKGZ/pYz9cxqjoq9QPe0MCHJDz54T7RGYyDp5l8eCuBDdetk8GZj7DFAsxhhInArO+dsuJ6IGVpp7MZr1qu5Ja5EiDxd8CUwLDL8SRDE7XUWA6VpYIoeYOdlYqjOFb66rWC6ZoEU7WPS4ilalNaobQVSlv4v7dC6TDyvvVWkEwhb6qqL1BJBlSzYkLwDp/FpOAjcD15kVS1imVLxRzJOP8W950AmR6Ta9UM9Qu5omEIqVDlFdEck9QZT01fAXMYv0ZK47MbzXc18Wh49BSmBsfjw3HbMuo1l1xdngHUVxNROGjkQp+819PvdZrLjZ/js/PhbSsp3g41VEdsEbHNIEex8Kb6uxPpDYdGCtIKbveKcnveXVBuTVLVaV6Ses8Yq1csQ6MSEY6xb3WqZGwTH3vb0Tim3fAJmmxPM5SZ+44XuUiZAzbSWcRVbY4ZRVUyRqAxMouCcVLEtqt1dlPMNp5k64TAFBkNJVA7yH0KcxMBgS0k8bdLEvkh99BVRqqO3ZYFWJJ4oZA4kPzvJtkWsXEPGzenukeJdgD2k7mZ0wanow1PvE35tPE3KrET8SXRQrTU61apF1CAuzCGwrhLEq2AXXN2U0+3VLsS0qUe1lIv3WwRAoa5P1w2C5iD2SYCEYVMVQqH6hc6uByOIQ21sPErlFlQdAxIUpw4BBqCRIol7TR1aknRvSBF6uC01OjeUaPI87aUGiWYEt+w++bEv31EbJF0J80omyZPKxG3xh4/lUROx4OexlhUQ+10+xixAgz4UvVR4CZ7bEyducG2mEytg+SBvJaW4WQx9SM4yZQuBTOQ3NB5EtOgC2bBnDyuimj5bvKYjkZQA1vbOx4fQV06IqF1SLoTh6QzJHaYxDP28IAbkGcyWq7iVriK1nXnXnEt98mZZ+38iMUlLMuTgIa73tHH88ocfUypsgo5O/K8YkeflMCNiYV88vvFxalS2ppAm8dHw+9aKL4jG+tRwRHRBY9asfrWxerBkDrfPDEurdOWMsBGvu2Qm9u/v4w3X6XddSWBvtt6Tz1IentXNlgcd1miGqiCiTVUNRizMrIK0vKpMnktKNiniOpwTiJUXwdslJf5UwrpPoFRU7xsK3PfqcwNe9Zc8MUvaCDujnLV7uC3rwUibK6VbF4NLxFrZ/pUZQy4LTG/HR+qeHEyLpf4e0pavZlAFfVZBgSs+dUcQLM4BWJrkWanVs5GyGooYiOWPiDB+uGT9TuKiVGkGRsIIL8a4XqYHjyY0pi55TLxGoLKxlMKW+fNdQI/lV5cMo85YbkhsL8oAxGzpXV53kzT4jRvn+KnxVnehkyGPTYaQb0K3VMqsS/5g3pwOqZ0Du5YdDYLxHc+hRwlbsSMX5bL4foMI1gAn4ZwQcRIFy5/FExAHRE0YdQxW9RSvNuqt5YS2bqdkH0Pd9g188OeDANGpwthdFGPjejEA8zYs6qVeI1obzCuOjfbIgAcC25V8KvkttKClUQJb+chDaPq4hQSm1j127SVNB61BdG2iOV2iBHwOcD2uA0m6lEZZk8yiTvI5QdJc+IwJeqe+N48MZPkpy1DGoTMHdAivSSfMhnS6YzcTJhfPiPdx3JTeOziwsNM+GkJB8UERSF2bekN009WoVdcke4cDiIYyNQJxTgII2TAfS/U7D0K0rAJo5ha2YFZ1IEl2uUv8rGSCnVAWWozbrjnYahKTjR0i7HYGDoqIaWtdLct9K+tdHfH2Ts3oCBqgu9BuLB2yA3ETBKGdpEkuM22e1YIIcF+z6Eh9cS4VO5QBfFUo4J6eGf7xHpYltYfOgEe+myfDCPnGws1qE3oNSNDxnzCfFhFF8w8RzMoAUc+OGzIgnHc/aUPSiIUXWbMAah2if4WHdunW5IAHIMkHFvw6YjHtKrwXfqhIDIUQTKMsd8q4xL8MeIek/1Lv5TYlVKhDJgY0qIELzPnpalVsN+D+ZlNGegOlTNgI6nmY7IdZnUbKAtiIpLANdzlBIH/+dXGtBsasImIcB7//NFRewCr5lNvHnJH9vRP3Q54PHaePdtlLw93d3ts/9Wwd7jnHvboi73nvcPD58+fPTs83N3d3e10O/+KAi5d7uhPcdmIwoDdDoRkhsynvsMGaqeN7EB14x/IQmGIqzptANs0GLMQ/VQG02HndWdv/yWSBp/O5ESEA/Z9xgNqOpjS74P4EdobOi+gmyn349/lIBSDb4zNOq//f/befLltJFsTf5UM3rjRdg9BcdHecSN+Ki/VqrZstyR33a6ig0wCSRElEMkCQMm0wxHz1zzAxDzhfZJfnJMLEitBipIoCzd6piwCSCRyOefLs3yn0243My+F/ZhcQZ1ub5AzLBLwwW2RewMayxhGmLTUCO6P6MHosNO2jhzqWJ2O07EO26Ndq92227tjZ7fXtg9XHCjHDR9hpPRb84cq+el6lFxfjdNnU7erU9tGkUhmD85czbZtySZWQCelzelGkohl7fZ0sZ6qZs10a/K/lqgEmPLUqtabaiSNUZAO3N08mfQTdZR5ZWOGy9JhsPl0yv0EjIGudbJdO5lHExDhog9IiC5w9qN1spcD+Hgwch2HrUaXtdmO7eVN7Ck4S33qkZAFNywguCwerZP3Fjd83iWvJP44oz4V0daFWFaB1/MueQ1YQz2aBrfp6+WmbOPLiuFoasSWlvqE6yEk23gshCpx4hUu9/VJ6rjxKWRk+PObS1KAM0eQxqreOCSuH0aMOhWh6c43IesH0KvvhUAVC1BJyeQIs23GRh4DHhLfkgGtgctumLyBOcQF4CngN6EjSMulCoLaZoujhQKa0NFW31f4V90gNFWTGApYY1JsXrBL2AFDxAhbBp94ahg0ttMYE1favQuJ6EXvYsSOA7mxTopGxeKuiJSzC2bzQLkMGcdrYaBxjjzc1Li5Om6u0eC9o8EaCNZA0OjYbo49WwpSCNod87n/mCNXI9UfC6mKgIgNA9Uk8LwbbN2JNXmjMDYfLZJWfGcSwF6gvVLBkeRdaace3EmT0sp4QIbbyaYgy56FLHEDDRik0QtDqdGQoKaByYa+gq0Z/dwzFgBGhmBY1b+Y9ayGr/cGX++SCGCgVClEGgs+D6zYL2KIgwkLBI5aq+fqWBavsJVLC74yFiduk2wsxyZRuT/3vBo1roga04MCg2j6mGt8WOPDGh9uPT6MRe3d8eFGAWAriXkKwaAoSVwdD378cLEOIDQg3caw4Y6yXZQZOWMtGqo436SZM4sRSZgfEfxqwuxrwHDRhAnneuwkz4OaCAxvqOc6TeL64h99H9DkCGxSYAOdBXyExCNJYUivgDI3Eu+Q81kDw8eya75KrwxZXOrmnnHVt9g4h4unts3dGWUlByWWHysB9FikwPZlSrBkMJv4+XON5WosV2O5Z4blHtLWVxXqaVhzr6a/LEC7I+ATsdrFhkBx3TB8Zqg3DcekZp7JurKn/EZiD3WzThGGdR5wj8w86seE047iwIyxilA0YMW7YEgcbbP/ggUKibgBvkE3Dh8XzqjNwibBUOewSYAeLBSObcPT2PdVr1vkLTQp38x9IPf03KkbiRIMNA+Qii4JYpC1QOQjgcP7gHvxe3Fq1Bv/nLNgUbAiiD1xPSeOeB2xMdiL9dybEL2Rg8fiGHflRRa5+XG8tJ4OfSSjoU0dCM3LoNMS7aF7KHMbUtD0x0EVK6hRvPWo+FYXWHF8C+qSLZpkQqHoyNj13XACLBs8uG5i8ZGAR0ge0IQUBvbFZswRggJXkSUGXGzEJ6K6n4bD7ME8YlLFVEsnCKSmSKuUVlYPoAVAsS+37t/IIr7jrvpWBBSXKFxxQ77GFdcMlZulwZK3JNINaJj0sSXTNhgGp9AoqZ/7/mgO9ewZru2QsC9uKDmp89MTwHcXG2qwgFHfD5il8ik8GrHgeRtaAEY4aoJCU7M9jPmlRK6rQPcfVrHVx+X6uPyEjstPU9NL5bZq5qAITuZjkeGKOkWfEmWmnRBtLfJGqSF9wgPYiEc8tB8zVRKvSUB/3cIAoJ9+9hAIQXz/HSGCUJjFCEFczwUIb3yFD3I0f7besJ8PFfyCxMcMdBDurbDvwwz5DPQGDRZ67lx/HNAwCuY2kmIBXkhCDflOLFkYcWCd6Ps/WBbk5gEE8x8SP6zCPWD4X5IxZlWjeu4c1iOXF2zplcN65KJVcPV+fU+rxMtnI82nCxViXjutHiK9MLGsJItB7XiqkXQpkjYk9xZg6VJLHfWARmihZF8N+WvIXxXyS7B679BavOeOyNpw+4gTyVV5fFP2/sIAp8JMyuK0ToB3hY/JwHid3Snf0+z7ol44BrjrzDgSsghORWGdtrll4U1nhRP8UGFO5YmbTyjnssa6D4F1szKvxrw15q2tx08KSppa51UCjTyBgKs8lPa4CZd5wNGEokU8qHOkqFwGIwWR5RpIUj5YBUcmLbjU8/htSBZ8TiLe96VFkQfaOWkgS7TaOn/MIWAetT7aYQmofpG9yWeRO3W/CqbuGmhueYLlysiuu7e/GrLr7JZAu718Mo27WX3N/SW33KrW32KYPpc0s/cM0rdzWmq4/fBwu0bZNcquUfZzRNmPCqOFnrt/Q+4SKL2GVTeO9S805iJ1tHFfhjw6vgaU1UUBE1ka6eRzSUroOEoTMhbmsxmH+gYTlwU0sCeuTT2A0hHDyn0As2f0yvVj1M7GY9d2IZc1CugNC0Lq9X0+Jh5gASP+Rbf43KMj7gt/x72cQUFoISlKsxs+zOifUMconlB8SJWuwFr1HFNdZYGsvg+bKoLDWcTJmEH9bxFU8yWCZpioBAlIQ05yBoupGo5GjYXG2cW/v7z/+mnv/ddPnfeX9u77y5P22eV1+5c/Tr58uPRc+H/vLn/548Prq+j91/fu2aK9+9vPv7jvLv+5OPv10+1vl5Pp2R925/1tIz0KWCK9dBDO6Bd3Op8a1bGN3YIpO7CbgLEHv7DV91+LJA68CkZgMpVNdNrtdsFngzS5whraOgUE7cfyUfyrjcBX/mkOUKfdTnxXINkMiz/qI95j7D6YLtzFZLRoESiXIz8sJI4bYHIQ5LgEzBelmyArQj3c6vtvoW6DKORk5izNQ0b+s/MWonxCBvs54gF5wVpXrSbpN0YB97+y/+y81ZSD/cbLVt//MHUj8QotAqB/KKwiPrM8dsM84z0rrCTxSnMViK8czOeuE5aP2a8qqZ8T4bwypdenT6evtfA09gOkeEGBRZ3fZTNXOs30w+LlBAuyFnxLSYZQohRJ9sNiWtbVPi0utRrHsL2IVDWmEObpV6zIBPJJf7F6PJRBdVDUCZWCPH/in/CdRZNW+UNX4uU3duxD+avUuIPqiscCjrzt7p7VaVvtg8tO+7gN//tNhkdhFwFgyWX62fgZF0njuNHuHB2Njo6OrP3D/SProHfYs0ajzthyem3W3jty9nrd/UazEY936pVd9UpYKiUd6+zldSx0vRsWlHVsZHXtw0ProDfqWYfOaGTtdjuszQ7H3YO9g1THgM9oSTd6ueNzxT2nrBO21XOOYHTsXevIsW1rr9cdd8ZH497h/mHZ6HT06GRaR6xccfQrjkWl3podgT4Yq8OYDzUmcDf7Eg0MFS+HuTaD3J8ZRE8QUvjfq6dRqU9JFkM0igGY4QFpIIMfk+r9ZW05qS0nteVk05aT9xr+PS0uiIQJ4YGLFRRaPTZmPtn5pv/9fUewJpRbVOQ9GWuK+B1AfQw+lttS4qeSdpT4rADcEK4vE1ZybCvLDShE208i6ej0oHR9TQ57/7YTcykU9/HSPN+RuBbmpo/KpZ+70jn4CduEumeXp7vvLz913/9x3dU2oV/ffH13ef3lbPopet/9bXJ20d7791fPe3d5tXd2efLl7Od/fv335VX77J8bsQnJXb+N9qA7WTiEfFnDuoEPPkXLRpN4XKi4VYwcTcPC0dTtDnRTgrBH//kYRhC5RLfVAGIUDD7WU81uQEgXmUe+NxtqREFK9I53dnRO2c5gEHQHOAkKMNxOLNcRiAD+gYev1Dyt0YxqY+em09I0HzhmABTVJtC2Cdqxuoe0bR10WNuiBz1mjdpju9e1D3f3D1mZbWKvouWmVzqi85AF9zOgVndDQ2p1jUHtVhzUnn2wax0c9DrWaLzXs5xDe/+AUad9cOSUDeq+afCJBywBm5YtwopjW2SaMb/IMDItXSiVPr2u3Hivhh+xZLfD6FNbe35saw+cG/SRojb9PK7p5xJx8VM1+7S0yWNbrD85Rpv7NAjtfBM6119aATOSiaHJfElxLCopeYlGIUDWaRISfeSQmZGuf+XJ09IxEcu82fdnNIhckRI5Y3bYJCEPIsIDhwVhk8RqWhwr4NzlR0RFxJKJCzwkCzx6hu6Vzxx8W0xoEgUc2sUXfDqVteN9Bp4DFliJj+v7isp0wj1HMpkaZLKtvt/3wdwx1DhNR+YOmzm/WlCxFPvd9+Or6h94VZ6OkBlvFsx9wVyKCQI8jNTndtoQ8w+HmRBo8of6CGdNw2GL4LqMeAQJg7pD8rXiBMkc8woUsJ8HYwyGgPNrMPdtZeAgDFzYgO5q81ptXlvHvBaLm6UfJrYf8uRISzFMxJV7wwxDdPlMlHRNHmaqmQ4uTUnwYJaD9SwBmrUZ8hDmAThALTEisBOOO834VyWJ4Pdee2/voHu0f7C3d7C7d3SAZjVpdrFASOJd7WZD1Cy2wACPg9O9y1lZyBAh4vEtQpCMXeY5xj9Fz7FLxhFz4DqDuDYrnwO/rPzEKKB+CD3VG/73zv5nnO34W+Cv5EkP+cVaMxr8OWdRC7ZvwEL4TMvmDrMbx42vYeTE9cpEF+NVNsfTo9F72Z1kp3OWrGzC47BMP6vmxdfg30o+Y6shnIYg4lbYXfEVyydTa25DvYO0ns2Yj99kKo7GcWdvb6/Tbh/t7R0ctAXkgzmT9oZKZEffN2xZgkY7Fh3ZGVtIVpHBeknZSCoSNKV0ZeO40+12Or3agHCfBgQNMR/EflAbCzZtLCD/87//H/nl10tie9SdhsTheDSfUnBzGdBuCw0KzXgRNGP2ydqwUBsW7tWw8BCJ7tXP/g9mZFiZtUlohQrcTWLf3jdzE75lGW9TfTre5tMxeZF7Ch7nnZhfrn3AnC7icNj/7LwN56P47zufiO/SK2HJW+XgW7w5HuooXIXXCp2KzHOvXBhQ5eHct9pHVrtjBPxnk+OLGbDgrcEN0N42OjAnG2TEWr+7NXfWQzgza+asJ3T82LajxWV9htiiM8QTZs/KHCm2kU/rbuh/BeqtSmcBxaO14nFgBfqt5GGgZuGqDxP1YaLmNKsGJddkNFt2EHsMXrONHrjkJK5/4Fo2qXc5b9XHrUc4btWnrPqUVZ+ynuspa8uOUQ/Fp7a5o9SDe3F2viUgyQAU4/edP+dsXlL9Di9nz3WJA90/4Z7seS6DasV9JkZCFA7xSh6Zcc9zfUWZrOIBHM5CFCBhRIOIUBLMUcrVZd+Lz0WVjwpVziXrNJZdZms22mwwH5JGfzeBbT7m/LwB3ub1pkfsEHO/lZ4dulk9ZIrmWxoSbNHJ2xyr6KYa994R9+ZN7A/qX3h6oJIHJYftbUCcuRXgzJ3uhkQG+noLQkOZ/xBx4NtgX5g9jx4RjDYbu93c/vtz6gkBpXW05wIPYsAgfeTxRvxx4fP2AGGB57YcB5dA0ceByMHcr0K+Y2WeySfjScgmeV9+cFOosoTyn9MFuaWokB6NGgFvNwIupGcp4U8xGVMShCmVyG+Ke7Vy3Txcd2sHDtUAdGMANC1sflz8WVtef1DL67NAZVLBb3GKejnwqQq5dsQLi4FS0BUUI+q+DDj6SV/IUj8BN6GiWdMhBprMS/YEIzNCBiSCzCF/zAM3dFy0C4lEasH7JXLNADOFPJBcZ3EouSZ0e0AYNYhb1DmjaSQDgbOwQDJMYfFLUtI7jsII84jx1RBCdq7kqZ8EFHnBYCDcQCXveh4ZxeMGw5KxwxkxBXJ6E/1H8+yAjiOEMqv2HnPa0cAbMiytARU6oK2WWjGYYo+0AswhHvvi2vwqoDMs6yFgyao9nrEAGY6qdjdLpaeGN+bSA7JMxZQAHTP6JTNBDaa0bilLntFT/Oyq3XwLua3QJXxK93GUP0bSuoov+my+U9RSEObWSu99rR7IvLt8cqAVoycU/8IfE/0RW7lqZz7GpI9SBkjGP4c4c6z/AnLAo2FETLEk5swUPkjsIBpjQKyA6STYYqhkJqwEFFtihnM+F78jTzzEsgckhD22gq5lirSKOQCJT9Ckhw+P1Afr4PGBibpjmFzeI0MPyRuRiAOWR8SmVd6qBUIKSKuWPyfPAAVcjRNGTj6e4rJBw318VDJWQUySKBc5aI7P+msHrj/mFXps3r0K/NejmnyhOhX8939XXFBEwroNQsnBze5ANT9IocYSjGigwPOu7GcVJ/ZFxAPYqDlRwupSeYDwFfNZAPpGXfBYKYZsxTioHBsWhtWCmQsJFJUGMxHVK7yiBiANqcTVULI3y4DNqmCqKTAD9THQFSlIFT8AmbjySanJSCgHz/ZoGG4DprqDrN2M+7BceqmR/LvrVzAJSFEV8zMkDxI+nYKOgZeyIKCCUuObeqOISkXiCvk0bi7xY9U3C7MbhN3hPL+Caa7wtLx9gMsiI7IU5KgWXZlY6j+qjquosu5bMa2jW8q0Sf7c/Wjq5EGVhtAJ1Q7rSTOBmB6PRSxX2YhLecrmNV4pUjbiKiobNp1FC0PlgKZwAVub5hmI8mHqjimkWUzoDdiriNgNYRP+7frWLOBXQPFDpnMvcoGKiMxnHqeOZJTzOUHCJTB1QcaHzHqdeyz8G+GwGW5dbRYQ7kpYGSVqavO+jKQcNQ41T0IjLhPNiYWxnmiuvq0bJXImvyO1nLmDnJGSAu/gwZWIbHID6cYFmjGVrgK2JRZMqS/CGRwpD2DfVRMIoNeKbIrAMpEjkoBTokAe/Qwnl1jDwxkdoyrcMJLMkKK9bUCrDyh37lEMxJNRw7MnBc9yJu4pyEx7/JEFUxfJ/8JzPSDfzIjRlu3xuTP2aMBazLliLS31WgEe9L8/pDC9EqtjBoxbuWIOr+QJuo9I0lV0zp9Q/0qK2twTuUx1vPUWEjoxR6EsIqo75chF8kb9pm4NgFxT+Q0SLxBIzPUd98Z1IDxMIjRig/3ghgWB6wgIJjWA7GYtfCsIX8MEjlflyFviVC37OmFUuAiKe2vaDPCtaJ82T+hLJVz6QF9JL5hrt9YMtWbYes1wK2D2g6oG5rhCN8wr2ICt0cKSgqrAFkxejBboV31ZbBUGjWCAcuHaUtW+RZE0+OvT+TsCkrBFLtyp61H0pg/TXRqSFxBH+rJJRvPIlPTYmM3BP62bhOZQY8Af2rycVFkurHxYVMwhNy7FW4c5AnBIhOhDe0KAMdU+1yf9EXcWLfLJ99xroX8w2PWGBi71o6bwiDPfmXGwaOtMI2rbbAapRkmLN/BnGl8GBx6P2sxRNvXzLgnYleKgwJBN6nks+EtIYIVB6UMexyiYPSHuGFkpkNcePOFwSCJD00w8rHXlxnXl4+vG2qr9dJVjbdW+J6u2Vm9rWLd3bLncq5q4LXjAmnHPtRfF5m7y6sP5Bfmo7so1O8LixNtEY5KIaJmVqTY2r2ZluhDblpzfs5m5mRJjJYLgDciP++7QRjb+JvdxyxZCczOm44BN+U2aXeovobmhWuSngN+GLFDoThYDchhURyAcQVjIiB3wMLR44F65WNtWHQTIlC5QOle0NBdKBuNUVCYWkPC4lgnbLhO2Hz8le4SezTvEveGqhkakSHtaoKuWtaWW5QLrwWy+VKhdVBNq5wzPvEJQv0JJ+0FI2nMm6vuQiwnFANsX0M5L4YkXgs83zcvn+LvgaVyQ24lrT4gQ2iFWpZ5w5eEX5zURiosUjpIZYZRRB9w0a8dH9VrSblPw22YFWMXwsRo2PhVRZtA4VYGNhjhaETcGDI2LAjeSWcBuXD4PpbwysOIah1CHQ4JVuGPPw4hjNGZpspS4zZJPZXOmXuF18lpch1CGsqAHSqBRDHjwPCLaJrJtNFCGEebQqPjeOibinhMzUtP3PK18sCYHYjEO5GI0YrqeGgwtm9enYAHcztiJllwYLSk375I0QR0nKVcTYvUkiqg9Sc4gueRFcvVcSk3pNEvIVAVtazH62LBz2RA5TlIADVZleD5xnNSSeZ6yPG8kn6okL57TZyDH7yvSYQVBvn4iQwpl73wTf1dMcCjWDedoik4tircQu1CU+uCGNvd9tDvQtHKA5xIJeGDRUNbunKyIE3FOjSYBn19NRAIDkTTnaTAvowz0oSfothx2o17thmTu0/EYc/uemQlEuSDU7G7kZVLWPcjBQfoUa20Dac+wWX4YhVM6s09B5zxq9MAKmmUl/6NjyHBBtpeR4gkT0xJBHZtbxH/1Ry71PSb0kqWqlWb8j8nlcxHflu+DzCuRlPxEXhQH/rwOMU9ecWQXx6tUOdDnqEOgkM2PokCqzvCPpksekK5jBS2zxPMKcd1VZLqawjQwKJTsbxy3Fu0/lmh/ECsYLMg7msFw6dU6ptLIPlUlU3mOn4KWefpWMukUv4uVbEp9eiU+u0Ls42w+8ly7KPpRGprkwljij0675mVHUtYqMIvdyp0gXo5pOCITSB6rBGdIxsoVQMw4liBgjkxEjZjvyCghh90wj8+mQBEyD7eJ8XPLnTJVThpnci4v5iPnOduo5Jp++nK/fFKfgbC/b9e2EsNVfNvLozmLxbSslV1VUr9BCRsaxbDDlBiOeKr0s7J8gRMjV6a3FIBQIl7Lc8MvUYv0H83Pjjg4IxBXO2LI1Vurlx9MvSyd12egYe79OFFBxawUZGtLfpkV9EFSD6x1bvmDj6qWGbDw3oJSA+QXcTGv3MCI2tcwmr5DoIlMlkKTuL7tzR0wm80CNna/yPAB8gKUknw70pu5/tXLvo+tIKeumXhOpu6VPDbDDS3sEihjdsOCBYEtiMkNumzBHDPRyfAPPrpczNiw77tIZnbjOsxp9f1a4a1CBSBHMU0dnw7xA652QXMEYgwX+B9ynmChi0wViBiH+WqVFFyKuezFmnmtHJEmfe6ZWhJJlnsobD/PlH+o2lVZ5sHsrGiwFa8lImvruhgDPmG+rAuhBpSYS62xwrzFU/cHHw3kh5jfNqVf/sEWSz4uW2QBv0xXWMgd+PwSWmY5hXaqOm3k+nMc/su8UlqFtQRQPcSlBGhIhlBL5FW6waFKQIrTCgzgUrRwKpJGpIXbKqBIll2QiTi+7/pXID1Rn8bRsWnJBnOAjCwRFAqRzzWajRvqicrRCkNBuZ4YHP3+2cQ8QqD//q3hggQ/GHd39/cOR1av4xxYu6OjjnVEO13LHu3Rrn10NOoe7Taaeu8ep/dS4k8d8eV8EPlfjeNOb6/dbLihGKdXHqOBkkTi0cZxQ1Ba0yC6dHFddNvdfat9YHXbl53ucbt93G7/htsWl/Jx4/zT+/en739GMJ077UDks/ile/oH//Lu1S9fnZ/fLpw3b6fOz/9anP7B3Xfu7vzUb/9XArdBnwQW+XHwakIUhLJwwdNDq4Ub7Rmg1Puyg0iotqFqCCi7ilmwfsGrRfxXSfSXk6IKpolYb46xro4oliCs2n/w0XHf7/sW+etfh6ZAGv71r8eaAVeAPLF1yO2Eh4xcswUZMUh1FSpbPjxskRPic1/I3b5PJOgU/NgMzSBkuAO3KZZtecOLYb/Rbwxf4q+uot31IzfQObCym7kYBPsrQGq6w4lEWjJi0S1jvoK30EVEuAwQhsj/vTBeMEQsPHQYeJ7xTcmr+F0jpvEGifgVygFoGB7FGxx3PGbB3wifuugMJyMeTeLuYnDW8NQfo5HBj0Rg1hBpyi4i6js0cIYtmKeP3POS9cGGrjOMUZNB7PALH2lisBa5mII4Sp4AEJbY1O/7Y9d3wwkJF749CbjP5yGUc8YwX6wJNXz14ezjuzeXb14PW0QqqJiIE6tcZVZj30fFJJKekZNMGszIaCHSF//gI/yotzzI6dkxoSMeAJVZ5N6wLHc6GbExDxgJ5yM1qgZDerPvhy5U1KOprwLRhXoWd0xMmIbviiZsKjK26Q13HQIHXZM/lAfyq+DHbI9uJ67HNDtGBnsAmYekgm+RN5C9Izvb9229pR2McbBxdJqaYi7GknI4cmbSDYmyN85g/Yle/I3cUjfKpPhAl7DaGk68HEqoMIcdppp+LmB/iEmDJdb3/355+ZHsdo9gm8sNZVMfBnDE5M515DBkKe3FUlDRHswhL0Rz7aO+v0NQwxGbO4x02u3D3ssWpDPNAh7BJlaDKpb6eZe8phElr0QVQeVda5KQiQHr+5Jpz6yAaNkTZl8rur2/QZQJ98eea0fiRCF3FL5B9YyYHev70LOO2InZCZCa22BsgSGWd8gl9LfSc3Xfz28DDS7KXqGlYX2GXp1OL7seMpx6meqoOZutiQSHeOwUz4njHeobs04Dnk7TqzV2B2uaxTicacnJ6i72b/PkJHNI1EHiW5Y2LKFD576DIl7eb5yblhxvsGzPVbgDB5MdtKKhVFQM0YkXv0E8kNH7q70N3yE1qxVxy9Va1aIaucfvFAAi9bURJ7EylmHSZi8K0EDjuJHW4YnzX77xpNnIog6ge5B6v5E6WUGYd+BO4fU8gB+mdDaT1ZOSJ8pi+glUNgNx90CsBLR4KB9HkZ1naZMJBsmBlm2Jxr/r0+DifdK69b3ZoP7iwxhF2TIKjWXfUCQy1ux05SpPgLhFw4gwVjRomJvD0lAlbdsIEcyBRvfgkLOQSFopZI1w3OmUOS6NmLdY1dTBfKfcpIAmkP2j8dHufnffor0xs3YPRrZ1tN/Zs9jBUWe06+z17L3eXUwgG7d/aBybY8BIiiZL4sr06AshJTE2oKj4vhWH+EGMSBsfwTfv//npzaeCAdSbp2j0LorBzx0Hsmd3xkd0r2u1R4fM2h3vOdaR02bWLu2MunbP2WV742rSODMYR1Z7d8lgFErMFZWFVFyJ+VumHp6TJW67LXDto2ynkucEdeBokTcFFb/wjCSs1OZJKX0I6b1squTZBLZESIsfLVWXjD4px6B937CQvEidxDovW0RmFKtoffgELCOcCKhNnSLFCWUV5QdDYiVOjJY47qZEcNHQKWOMyLd0yNgNwihXmnxrwOehj+Wwp6c0Tp2GlVNUk02Ya/RgiQ+QWuOlGgR99ncj8kKVKm13e6zT3hvvMpuND6lzZNNehx72DrpO2+7t9V620DBvyLnGuVHwDbxZhuDz555n7IYx9cL05l/TYNts7HZzlvIl5xAmtci3QfAgz+4RtsivS+0PQGOPTqkoWKwImCLOLeiTpZzt8TIBJDZjgaWy1kWn4cVoJpGbhNqTAo1jrJG9Q3ON6HGwuW/PgwCWibRimuYAcbZzQ22M/egxKFyv7THmYKB/UCG37VkGy1nDwcyYcSqIkDijggGykY0Ycf0b6rlO07TIwiWwIOFwaKkmCg/oiyNG6Dya8MD9Kpy62+q0eNzc4mW+CclVUS1qRtlv024GNN4yVwS65xTMy7EcwIxeuTfM1+b+EhO9khWGe+AlLIs1zPvatr92AM/ONzgHus73imkHaXdO0iJfnF+gBInAlmjpTY87FgCUwTZZV490Dbhh39f1QLRfAC3Q2nYX2zpHC5LdznM/coWXQXYG2jRcAE0yfHty+g7/xQMyfHXy/tWbd/D3szNKxvE52e9KTvRpzujL2BWWnmiBWeVpqFXa4bSR8MEKJJpyf0WdrQ0UVrEtMD+AY0LD2LyxKZNGZ/e419Emjfs+kHd3DzsPadWoD4NbFI5RsH+SuElqMh7gkl8dHQGSVIkK0TZDpSca34H58mugCc8dM3the6wiktD3W4ljdgZdCNFC3qnbBS95LpGKhEy6ZZPavGYar2s6bJQtN7l6n56wfqbs5rGY2ki1hipS7KK6FEtUbygTZzmVGqZYxlU8ZEEAmwBcTOQ72GiemoHfWcZqNGVUkOsrzJmN+REaOaB+6KKFUEUK5bmQ1aG0FrE/UjGHeIHXFR1+aJm3mbIOBTJLSSAYMWfuadmGx0cULIGURhkRtJ5tCyqzepZsoioiNZ9Zgkrfwb3kk4yMfJW6t8AIlnwohxcqIdV/BfOJDv1TAwZeLjfEkLmI+cRnVB6ZPBdEsfTPjBjGOaZjQ2euOD8lSGlngQsfJkvjtlK9dEPCfW+BtX55EMXFdFUhe1OuPSfRX4Pk5SAZVtJAbqhBckPVePmJGh5GLKIV1U5CBm8GblcU0Rcriug8do3k82n5XCoGH012v8bOw/PJ3mNVtjB2yYL+Vl5/7ad+dtL7IfC3XAQlQo7LhYLF7D2dbZH2r+cJvC8WnTtuhEhQR6mZUk+9vXJ8Zw3at5d34h4k7x1o6zxuX8ceoFzBnazjDQ+UiOxkOe933L4usJHIGwETQJO1kXdbjbzPXRxs9gzP7evNV/NOb6IMjX5T3CrTD91AZawBcKBXwGYTZc7ycNjnNyyQ6YVVq3kvkQ+Gc7FEOMBdtVTYZqnw5E+15nKFVVZ7gH4wSbrScbRMZF1UElkJn09adiUsgm9kSLu4Dsw1cGxEv4+Zxi0CuPEUqcQwHDeRl1FkTgmx6Mg+N2VIHIUTKkOXj+s7DA6FkFul/EuwIhZ4XFGnSBD0Prv1FnGyvOxDLWt/JB9QWuLVXqAfUu5txgMUSzCZV4NyKCDhBNwHvrA+wWgDVASfENqmTM/yiBXIrfVcQVzFJlY5q6qbc06mH/SlvPOoFN8upiQlJHEqjlkwqRBKfrn48J7gVoTQ5w58OXCiyYf7/jVbhMrKaCYbID/DqQiWBjd/zFChxPsLkX6BIalNMmI2nYcMUnU0HwiKcBT0YsKY87IpiCVEQSyYJXx/nK4lG2+S0VyRAMjwPjcUfBLddluy5UhockwwXWPY7PtDgUeOCeRzCNYZ7mMmfLBA0hyBYYYQcS/TQKADImQQ7gLOHPM+h8OH9H0pihdAy2FPcEBkFgkM06UmqCjJ9xdBDlxG5FN98hHZBISSJHWQYH/RsefZAHMdnw6nI0YlhbKiECLIYWfQ+XFJ8KceQy5Jh80CZkOu5N9g4hSBCkat0ykT9CkwE1oCwxfAnTQI4COGr2ULwB4kWRz6PnK/EAkTCb4Oj3Y8+xmau2bKgemBB9cyIuQWpt7m0ymQkcxDUbHmLyH5/aKHOd00csGaefLx9POLSRTNwuOdHUkIzYLQtH/ZfArbls7cnbCH/8FECEp+FzklYjXJ/eP6wPK5QpO3Ii9F/RdTVwI2ZgHzbbbzUs/OcwvqvyvTiCbJKGFkfK2Xb0utrLxtRFbZRX0fvSqzgIXMj5oZuYgcRFc+D2ROKM0Sm8Atir1A2df7vpIC7Au1IdGHhjndAdH5tzhvB0PzE2ReBicZSNFYNqoEFTVCPGjKhZ27SWXfnfiK2q99HwSgOuPJbJTCXAmYEjUJ0jlwZ7aYi1JWGK1TN88LU7Eaq+Lu0pkb0hGHsh9UA0pWqcekShpCIEYkikCS4Te87ftQaKa+j5oUuKyUbhUaRDasVDBonLCp9R5SuA6l7ovfAz+i+hNyWKsySPuIlWFSAf5NjCwaD/IVcov8KjdR349nPFY3emsnexIZRB6ZfbJybjP1PPl4mk9CDz1YO9QtK6W2/P6tcc0WUhLuRFwCOou2oi+CCCX38khc/pzD4wDhRS71LAXREz3+4Av6P8d1YqiUmoalH2Mk17YPEsm1Ce5ffE8Ck2VyY1dLhY0JZh7frJYljknuodCweK16IoXCboIUR7SlGUy30wjXbERuBD7axonniX0cr57UuXU5sU/uKbP5LSPvt8G2uuShDMHRllpR4wnMEONpKfoiHv+X2WmtUHE6rb1y86ZSCVMmCEonoT/BVHMxBI+Zah4bAArtJKO5d22t5G7LSyM3zAXnXS0StTInpbocD/Nl+eg00odbxJMpOtoc4FrmpcNSDnmmESRgLjKMiBIOyhaCJeQSWQuYJ6xDhqcsoiJCSld0uGaLJgndr6xJWESvmsSjsMy5I7SnsFaj6UE9LL5WVldVP9Yn2fokm3+SZcFgBrgsdZY16AiXlD4wrJaSSxjg+0xmwWSKH8hgwcZxt11cCaHzfelhu6iDuYUnMHw7Qlpr1V1Nch0Kluu8uhTizcZnmEn4ccwBUvIGVTt4QmCXeQxK1gTUBkk2D0VcIwpi7FOLaJSEgkyez6RUlG/UVBiyiANINUUnjMRIhNuCdMJmqkJI/LDgdDYfDZjoARZ3EdZB2VUxlIR5DOqZlQ+IPQ9CXnk0jLoV4sG4cIWwHMfVKUxBixq9RT7JgQNeIZdJ+iqoeoDrD75ZLoLyLmMm/gAHpPoyMyW3pEg352vKjBFOHndcn3jsi2vzq4DOJq5NeOCwIK+L1UttZI79P0Q8whpnIu37Us0NXH/Mqz0LOl42oApCiKe3E5EvqwpRCKa3GPFuGWNABSgsikGs75Tb+SbP79ds8X0VD12xg67QP0dV+mqOW65GiD8mQpSvihdZ5TdlrVegvV5Agy8Vnoj5tMXabJEzutBwJfRoOJFxPPA6y3OvBehq9f0LefHFcGf4EudeAhx4y9mni0s4p4Ofg3gAWGDbIrzBS+8/4OUZC2yglGQ+GBudvv/CbbEWGf5n9+3w5d+ktRK8JQEgCo24QnDFzz0npwlwfczDOfXEQsl4FNBVfy5bVGMm7cCGBXa6kLtUW2jvMRgxsfl/MAiwAm9Qvjn0qanu/Ml8Crp7a61VGzFUxRjeVKGJ0J+lYd45ijvm98mJihSnmnK9rY1IhjhGXzD1uH8ldKo2LAmnZVgr+1rZ30nZqwN3re43q+7jKTwdW++5z6wzCG3OxCQsM0sYs4W2L3eMJY/fXNKr2Nsq2HJi4lb04ZZbSk7H1pm0PVsXUH1rMz1D//8ITFnasi1qe6WK2rpT1ur7Z5IEfMxBdEdiEqmPZnALa3e/OH/7ihx0e52XTcJaVy0yvJyzJunskV+oT7rt7i7ptI97QLNIfj67HOZOfnXCzDTwKhTJ+cK40ZTDh295JbS79Y75V9Ekf2uCQyC1KV2fjBYRC0trz4JqV+0Lcsu81s9Oz94IDtrEK8pjVJoNWFz5DYI4hLo/9EqHvYgmm+Q2oLOZYNRw+HzkMevPOQeVC0ZkOYvdZt8Xs9hvOLsd59B2jg7H7fao295lR4ft9tHRIbPHh7vdA9ZvLAsK+t5svKNhpNdxgZ8e47V8sebMcQZ4mPDBNKutQ/UJVRZiWd+F1EiUGCtYIyY/ctlMLtExieI5olZRAQDldgRVVaKA0WkSiGZ7Z+yKrMRpNsSQgtJ0fcBJApX22rvZ1t7ziKi5VDtPMe/a3HeQtYt62kUstxrkd0DHE5MLYggko6gm7yCeK6T5fIII/elZ1yokIuWAasH5UISrNSOEbyCabFVVU3Ab9cZhk2fi0bXE18KdjrgMEk8lBomg7Akj0vklrwuZrhkP4tDPkPTabXL2U4vUgL0G7BUBOyzoMHSvfEWXomI2a7h+P3A9gaqqYuISsCWTF5XsKEflKci4yutzkKQQeAaczILIVBB1Eo0siZ9OwBIt79T6/HDDgsB1EnE5imDoTrBl7UzDNVENbDwxe9XxzfLTRkKxPV9L72wePXUzb/5MPgMQuYzi5z5QJMDHdVy0oTubLar5ZFVNSXhC0SEkHLSCU41cYJMZB61iXMPLhPuWw6ZYXF4XUMzhPBbyDI4sBGy9kDXBwKSDk5POhkdTChYa1EdDCWmDuOK7Kjcac62dd4nIh0yW4amz2zfsvBMTn6Do+1HleyE7XJEExjSPz9+3NLNhuS+vbG63VeJvT8WzUErMzbj3nGqSNunXW0c+VmN8KtQXYGHKWTf5zMpZHmXxaLomo+GpfFan7HsumPWMZPeyUxfu1Scnp5dN4lMQ0ltm260svatTTRXKSkEKVQCt1YxKCn7mrw60RaKzUW9Z+dxCDbURYp93m7JdNEBBda4Yexu1ngtguEjcAc2CT6JyqQX1w7JIxdnDy2QsriMh8Ab0NqyStZp45spe/Zmwt/Ij9CsKlursx7U+q/XZD6DPNm5mqqzQKhFKTyGAyl5alkU+ZXngX7PUQ+lzwom86x3cRc70XTmLQqicHWl2fIVF6+UDhNoBDwUhrvxYONMs+Dwgsh8t8p6jx5wWvFSnWLvTKXNcCuSJJGBjTxGkeMDhJOoAPLpqq4zv8z/1eUpENZK4IgdqRT5JCVk+rdsqI2WvS4WkoEnZsOCLpc9dcqEiNp1ZonitZQcM9yP1cNnMeJgvCQW9hFX0qCkOJWvVJZvOeABlQWRhvleJ+1MnBMUspx+SxXWNlwBFnaLFkyme1EeaxpmIL4L6UDafCaOQLjvIg+V0sE+v3MeS18M4DsQQDmAIIZcSX1zZzSlnsXRCnqf4zRtbSf/65GTwKrO8rdJ441S1ejRSIq5Q5grhWCp1GfUgjHXn2o12vtHZDH+lPvUWkWuHOw5d3LphcdFqzFwJriz9RELivkWXo0MXFjRCQobKCG0ZEJkWOIImWz4qKkBJE8vJbJaX9IKBdKs1yMeyPW28T0aNkwACOolI9MfQXKw55OC/W+R0bF4SZiJH/hEwBLQq/K+ZKHlltO2GJGTS3tNrQ/9DQq+4CsASRAyIfEvKw25aF8iZv3ajZdYdsSw2/1bRbCXjjvEYzsZrXNerPch8RzxWCdx/+MfmlAesw+V36RUMnxjlSOpzvcThBvDb2KGxvJ15IAuRqCWt1nmGbyvbwUXRS19TyE0ImbHBxJ3F7HSZtht5/JsRj6g3iD966vrziOVFrMONxuvljZKmX36kDbsqJyAt857CF8S0NfG91d7xPcuu3jRmU2DyVd5aZSaNL8yMIRSTDOfT3ASGgsGs8krR14bUgih6i1bNhZTMj7FQQ+Pdm1qm6nOXLFL16ipLVI1m6hUV1qe68w6rUzVRdXHqV664NPV7qq7M9Aiuti5TYSApzKrKMkjEmac6tF5IaI6fAam5NlZGaCzBgE3xA/j9PUFQCn8iB2sSIZ4YkOlDcEV99ytql7AwsOJcdomcOFMXILj6oRhjLiuKJxtoXbtRS+Om1jwUtF/ljrn1UaXn3jARNVsNYcb3x0DTUg+WAM4caIkmS+P9y0FmfLPRXhmUfKYQLkGYhauylAP9AkduIUYRnhEjCGly5JPvfsE/w4hOZ2BpDhnkayFhmzwJCoLI7NSUJjka0dWuH+3vJnoOuH61fjOVBPiIvR67Hi6z0k5/kJYoIu/G9Vu5H6tlvVYBziY59hvxb9KBPzRXtIDMyBSNCmq32UDXyXGj2+72rPaB1dm7bENy5HG7/VtDKVHXv2JhNJAD3zje63XUpRuX3bIgvtTp7OfQX3/P+f5qqH4JvihQtMLNAlkWqP6MOVGqMy/NQg1GhkDQFHg5+drNBph/jYK4ReOWr5xxrTtmLJkoKwKr2vVnc5ECKzLGpYCcMobhZWhQwg9LZKykQVB6kvL7AXeJziT7IJ4OyS1krzNHyhZ4ac4r83HREwEP79wb9Wmw9d/pZROjikdHEYaWbTnU9ZaH+mwGUUB1JOp5qyMKmEoZLpqGFOrSnSBFjSRqJFEjicdBEiaQWAsqbBApFNy1KkIoQAbPV6HX+vu+9PfGNbfZdpGexoS1AfW8QbInad2MVbqrnOhZBIWIYCsZt0MyPLddrCSgeb7Figdb5enrFjmNJOs+CxNPqtIWo4XAAHA/OIjUhPzDjdR2kdzP4DGKW0g+iq6mBZ8L7qNbCg6h/B4XvRd8UXnvbmKzEJQAhQ7h+4bsC37PQN2SqbtXDD3Sj5brizfibpE0U3lccpVH7HrWRPGyyM9yzvoUL4xhdBdE8CYvfRlFUvwiSCD3efl7IO8b2calIRUdgEK6wYzgHOMM4k0ho4E9MbnpoWilG848uigYkryegdl7vmRWLiTYDBVoiuYxD5DahGUaXLv/G+9O//Wm0Wycvn4H/3lzfv7h/M1r+OH9vz78481r8PJvDNJJb6pPTi8+SGqlHERkaIji7msc5GD4kJtKH70Dgnu4ToY8iAZIEL/SbPMgEkVnIa9AHT8MMvzlc35y8arRbLy+eAWzey9QTv7bwqZSEa2eR0z1ST6MyYlPPgRX5CKCkgFX5EKHn+TYk4TwHOC4mrakg+P24XF3v7Xf2wV7kkwGdKSQAaqQiAU+QCtQTgcO26e9MbPb4yO7vTcad5xxZ7d9tNd2erTbO4AZgftG+2027jnUGo9GI2t3tzOyjjr7h9Zht7c3ard7e93dQ5w9CdeCGxaASo6mSJ4DSyVFm3O8u9vD33cgqob6c432dFelcBU9HY1GhwdHu3uWM+7Y1u6Rc2QddvaOrO5+lx5Qtm+PHVjmck1BCC6Ifo8uRtS+HswDDwg7JJePKB3DAis85H+07Y6/x64P6aRj9lEubCD4WTZIO1Pqu2MWRjsQP8Fb094cBkNKsGMlW0SLAkY1xt39vf397uHemNp0fzxiXXZwRA96dH8/CAPxv57tsG6PdkejA2dk79tdu3Ow3xkdHY532W6jKcOwi9bAbrt10N3/DeMEZrigcEX6zoCPxyEglU5TSjLjBwF3JYbvbPK4sFqlAwO5xqiyIer6qW+p2gBW4Lg6zZY5yGDrovAv/BT96s9bC8EfCWxXhNgidvb52YI+3+FYsfMt/gOulZoDb7qmRVBa3s2f8CvTBw/D7KGQuqBZMy6cvq5yHqHmI3gKSfj44yNJomWklgugIk7aGnT6WvYEwf4FIqj4MgbJKQQ+hKDP521o3F4s/2DHmcReqTzmD2LVU1Aw36oXdxxNaDW4q8FdNXAXxyZVOBbAU7vd30Q8+0DXKxa5NDgR9nhvjx7utS27N3as3f3RnjXac7pWd2/UGx1R2tk/3DeXgjSH7kNtO9e/4ddMHjhL121ym1ZegAhWS17QO/oN7+LAt5x/V0fdVTK8HXOgMjb0bruNCn0bIHXBXUlhsg7MNlfVJgG8jKdsfE9DbaPLxrs/13D/CcP9u1rU09B3h9qRe8NyIO4yUFz4oCXBa545Hp/JiWQh8TPLAbHnZRuqwfADgOEaCdZI8JkiweXr5hniQPFtd0J9Twu53RWgLcdnCM/Whlc1qipGVS2NgJdYUyWyuRvMUi8z8ZYGSCuZHMM8iLXM5piCVVnbo7qhxAZZ0lwh1oqbFZhLV9ceGmJJJUy5ztAAXxW/gRrvqCFZo2htPBloVivVhzCubELL3kHx1Srt8VTaWhYDHcBVoqYw/M6I9MqLvdOhXBWoGzL3Z6LtnqekX4HGAPw67/mq5AczFnwEsboO2cIlBh6tTLawzmPCb9ZYMZztLcaixwtrtJAxbRXDmV5dyiC29/KfxWFNqwin6MTzztTe2Rr5pnv0SLLNkCbLAx5yab8EnFBiKY/jSxv0Cgi94htqIaRiLTIcYPnrVN3iptaqGFi5uLCJLJ1XZ+UdJNurd88qu2dd2ifV9s632LJYeojN3YISGCQ22DJUoG9W50DXT5M2if2p7ivboyYLtdIXxceheIcZ5tTkLkt2+vS1ipSWD7SI+GQzOybhc7DTMkeeaKue2YxA4Pk83qx3VE7G1tpb/XFza9V7s/reVJT2z0y7rIYCjZ0ognChznlGAInDcq4M+jRzymGAuMGUPHeROE9NctxBzYuBK1fztSx6GrJIsZEXVdhgM4/a+RvsXFwr2WHyDnHkF7yIeXblenutjKLvtL3q3VF1d8jlvyEYnY3BWeYdUs2of5w62XCcKuE3iiaueKOuF31znzv3PsDx4zk46miTOtrEjDZ5BC9N7Z65D/XRSkjiagEH9dlvhbPfPaneHfDGwrfUU7HKMTzXGA9DOUiE0yZAyUXEZ0XRttlE9YjPRJJ6NogYs+QU5ijm7DBQSTIgOPcAMEy7A5ZEmzwXPKODMHBKoHKJwVlgFIbwFptRaOV36d5krbdPlfLn8eMKyhQWisdqNZO1MICSlUWbt0X+JYmcPC4ZaEYBp45Nw0Q5sNaGD1vLshzARYt3qiCWHC5h41Tkqy8L9e3Lj1I+4f4VR6GVeHiV09TqMvvUKSxzsJoHOzE8sJfau3dr5D2P3vK572yORzs5J48NCSXOq10A2woD5ULZuXbt60ZhabF/uPb1RxpEtjujfpQMfYJrwJQVufKqSAZfLh/gQSgXxoBMb8oDVqUVCVfmIQsAvPCAiAOz+ewzjVlYa0lp0XgHM61aHWrqNmOpTbe6lrw1GqhFLe7xe8EUKD4sSTNcLEJOPC8xoxkxAqbWWfKOPJmRvq1IVqxuoq2lw+aBU97Mb8055EluYtxpq55IHDe0ue9DiU3CbhhWEcRvNzXn/R8/dqZzwdWfLybO5hErlBFwMbnxKx1EzrB2Tg00tkOU3AFopBfHZoBGZsnVwmld4YR7+/7ERjnCgHksQxgoPZYiDCEsMggjT9DU+GJbhEJq2jcnF2rcsknRgPv3fsTDjJeJBuHY+MgRNuXkR8zElfxq55T47BZvkWGRtRTYPikQz/Bmsi2MFYN2hxwn008UyO1VvfYfeFu3YO0/XI7FToWosJU4mJak9S8PBqvMC3C//taamfMHdDnncLqDb/RCLLe3MHvi36dOMZN7zftUR+LVDKBPj6TiTgygDxBrUhOFrkgUmnpNmgG0Djt9tLDTOs7gceIMUrXN6vHfQIwpDcyardkg0xJO15woUxpEYR1bmp+vlm7rzjGl6sAUONPpzPoyWdih11hJc4sWsh+TqWWNMHOATsGr5c1OmHs1ySm4+Xf8XY1yclXhG8AoNnO/MDx6Zwtw3rpONMk2+yv8vG6r31Usa56NJ8+I52wyHPhBjjr1oabkUPMAyBcGPr2WYmFjBPPmVJVPiZXMKshUfYU6dHiNfDp/B0aYuObr+eXZR8J8m0N5upBh1WMsBQt7BMpc0rnjciy/ne3K9+RCKv4eJbJHLEmayZwmccHztcj7zozEUaIpZfahU1Zt4DINJhdx3rjdshGhjhOIaoI00kVydYFPLurlLn3993jZpl90kSgJWf4NVStBNhtnby7PT19dDM7fnLz+tzgcGNsk3YdPvvvnnJFrthBGS1z+MFuMJkycLfJmOosWMG0p5nc3JMrOk9fxL1bI/NBFP47cVckDiWBgVQRkklcmpafNdZ74ntRc1kehR0lkoMEdmBGTuD7hRK/AijSYFfnlY+7EjMd9qWU+85Swy9c+uUckVHyiPBV3ZzdMRwrU5C2bNfSkJMiafInUcUxZlBBFJ44D0QCJq8nleuI4YfIWQBi1qEmzdD+13X+H0IMTxzF2/mbCD5JtGiEI6wuTO0qj5ypMNhvaYL5155vxlyKXdJjHRHx0UmqJ3/PAVEKAvcbblsgwcVNajOVDJjhiVo14Xn/P/5vP8cA2fui9b5Y9Neei4gcYD+V9RHLgjA+haT2z6pdsALOIVZCSMjVkeRwpI7f9qjkdAZvyGxZmFhsG/ZjbCLZxwMCtjje7AaHzaAIYQZhBCY5PC2ZwlYNcLtWtcf0v6kBWQnZr9rs8qqqWRT+qLPqZRbUg2gpBVLvJN8bIyxw0p+QLyzeOG1WVlTE9b97ttbR8itLyDudNWDrLD5wris/sgbOWwI8jgSvyEBcJlpiLuCIOU8TEtXCphUs0kOuhli8/rHzZMJNzqUVrRw5osV1LHErlwCflGFxICaW8Q2uOSBPnXEpmAbtx+Tz0FsQNwzlLyqy8xjDIjc/hJOoJWZLZzx+iCQvE3aFqVroAzNYDWDo+uaGe69SugFr+P5WjuNg9l7izNuF22G33ar/FPYn5lpBC5dIeprPYGxqwKxguKB2TJ4PHAQsn6wlh1W5Y4fENoMxaktaSNC1JHxtK4+4xYC9K1c3gadxfm5PStZC9m5DFmV4dUs8CFrLy+DlL3VMQMqevporAwh1GvSF5Hxkxj/tXuE24LPH1TGXq/ZcLNkLpVASmKOhbmiV/IVLy9YQtCDxcVrt3cwFscjFtzeFadeiR5EG8udaMNYNfczdwzDyDF0u4Z8QNyX2LqnoeBAzUGlYSfW77d0N0MTi2GyvPm2yu3kHVdtC6AVay6Z1v4h/VAqjUZrT0QwXhU/nb0oicEtsyRpyzgENSjqOunL5+htvSQPvG+FYC+mLUIi7Q/aOHc9d7eZ29vGYY04wFUwrD6S2E4VWFNOEbS6OSlmzobNmKoq2tAHPOvfUur3d5vctzYoRyw17w5yXbUlekLtiMqetwCKp33/btvjtXzi4F4PV2fpjtvCTgZDZfpmSNkJP87axv8LxMXEkFFftMDVR33uXK0//4Jbzrfb4F+3ztwI+A2Txw0DBfluhNPW9g3Jpvr45vEDQGvjRgFad35z7RIqditQ9jn9iQaCEBXAczGobAXxEUt1WnbS73MOYbqYW4obGD8QNeoV6L/Op6HvHcqRuZtLLc9wDDuaEeancsp6jMtJ3rUHyMbHb2ZYaDXT4qY73q8HvDCb8NiXx0x+e+Jf9tLkTuEyUK/uGCg3w0t69RiWYGxeDHWOl7pNthxad0Hy94EP20WPXxkAfRh8BBFqjVHgSaikuQjCs+yHxnncfi7xTcJhs5WZ7HgnBrVJTRp0fSUgn1sKZPRdCi6pZyqO/0teW0dzm3tsilER4B8QYjIHhBxlg4iAoFRCgMEHHcgNmRt2gSJBI34w2QLg8sW65gFwUpiM0QGr+2SUY0ZA4IAVBGsM9RsM6jCQ/cr8I8NpdC8rmppbtiT5xjveg3gjwTrdW7epVdLdiHkGcqSr3nDoh055v+t/IAFQJU7rMCuZFjJjZvXF7X2BAkSWAZ//7coaU5TxWPsuYcPK6huN73a+/7K1a064sMTnQewkYN51M2ABL2gk37Ee7bOcf7di4iPivZs9l7ab1Bt2qD3oV2tyr1J5SzEU8UsTbCcsNFMA+F3QwWDBAOJgkJZUOfc1loa+nygNIFVkbAvc3jCllfTP+SyHoqt4Phk6VIQ1YQW44xMJY5dfPy2kPPWow9AHP4hgIucV6Te3/V+uY//N6vUFkQ3dF32OlRQO3rRmHtQGGOgnv0uLzlwcmZXjXF5odktiHwNOO7stHa0hqBV1NHCdMukbosQ0C9hfwtJCGDfZ8skpx4M6Eh+ZWNzsjY9VgIJOtIMh3bH6X1sUX+hQzT6R65+IzDbpjHZ1MGWRlvVVFl1xeK3eU+WN3HmCVJfk/1+vOLeEaMlRxPiHU1dx0mZsUQvy+fo1TbiAUkuXbLnHCrVzRblXQ9FU5JIyr9M8K2BotR776Yo7qg0Vh9rjC2hrxNgbq4uRQ7dWqvigskTJCC5/RaWeths4/p3IvyabXVi0AAuxGQnzekVJdvOpcz1dgm2uut0hFaqm6a+tqsSpWL935m0YW6J9/hqZqQFaTLvJ2mQSn3yecoAh/a37eih+sH9oslCCVW7yu60tZKfRIoW5RzmFIRlqs3g/aXqPMOCs2mcfxpYt6wKtSKMYLFQN5YyLrSUUXvt5lFi33VfQwnfO454DdKlU9aydO9iTOGFk5bozh0jx5JbYSxuF7igFxXWex8k/8qtRTEk/O6sHBxwsOgakIXag8AU3JZCotAvAWI69veHBF8xozwTJWKfJMYGDYYBYxe83k0CDjHKhol2/+dG0aoodVDRD1UGLFhYEAsW/s9IRnVaqlosIhXwuM6RVLrtxYxK4iYtYwWuRJmx57QqIKYeQW35WNUGzWtqOJbUdpQVarK4be+x6mT35CxXIUYIq8u/kXEYmz1/Wctep76vscFVW/61KZv2WKfFe589mXG73IWTW7+uPSTtfSwCulyN12jcqh8Qj1pSTR76ljS+5Esk5ySHEZpMbXFFWAR0fw0CcLzBUlJK0n/RtxWqt6oIV+MeqNlJ/AltUefg/CZsQAPy+VI5/18OmIBDJwK5Z2xgMBzuUG7Pt6eYv25YgOfl7/mEql8rhgRDQj6elEDccHn5Bas2As+F28m4iRpBhePGFS2gwJzBdHEOR0rlL4bl62rW1Wr1yIV//39m8yizy1D3zbL0LMgGEgF3TiGeotNUc/UHu/t0cO9tmX3xo61uz/as0Z7Ttfq7o16oyNKO/uH+2aFP1nFfr/dhh+BY8wZoDDNeXt3v7Xf24W3x5t9sEoVVRl9WfiC3tFveBefzYru6qi7RLZT7kB1zIESdSTjL+10221B9q3qwzPfGfDxGBKejjuyk+YPEY+oN8D93jjufH+AoqWpu2gQUNhsbsRE8e2q8uKdniapVVFbxV9etZ2P+MSpP+YZYzt2VbdZl4O8FyhSsS7kBs8ilapCxhDyY5KzNo0wEpUdwShT9Wyi7k00UAgnnjUQqGKXFQWKUeviDdJCGzPyyYsCfiVJ+ZpElJzO/MwDpbQrEFzdlXjrXuCOqkduGHe6e83GlH5xpxBO1gXlOHV98Vdn5ayddR0F5qo3cndSFq8ZY8GA3TCx9UpGBSoJw3ojSoxKa6LJLsdYQERb6W2XO3JVzGKggJeY4f2kBU4j/aaskc1ujZRAlckhcmOHAb0dokhQgiCcMdsduzZx5pKWBK4mS9IGZGhzP+SeiyBiiCR6tj2fzj2Iukj2RrWTPwQaReoRaAT01ghFFH+Zr8M4xB/GfJCulrod+ntrzAirFTvdvPbOrU5YpM6NuazozSirT5jjD4/1dorytdhG8ClksWwKGBhdCPOdGXd9mR0fBS67YcRGI0FEIzeMXLv2hzygdlhbOdyVTHhDnMZPVgbnbNhaBK8rgjd4ftIyc+nR6ULemZWz8m9ccgH1xUKU5AkVzk6y4Yx/B5bvRdz0ZarplCWWhmTmQQGMiH2JnrdIfThL4zowLJ5HtaJqQZAWBGJHgZGtgl+nlAtYNWnFi8IKc3byz7J4grmZS3Zc9sQeuFdXLNAbVhZjgM25dO/Wu/Ux/AIX2qi54ZDr8ruMz13+JWjkhri+HAvNEgvuNtlon5ZcUXVUNgUxYkxQAWXEkiIHaCANOQfvVMQMqFEZaeQhjFQzpfEjtZx66KNH/Hp5pdxsbMyl6zE5bZp/sqpZ7NXFvwyz2MX5ZaPZ+Ncl/P+/XHx432jiDZ/vCRTVaCgjtYxDxb3GuYDZwBKGm51vaI9YwQpFI/o24NOPjAWnSyihoelCKbW8Oj1aN+DEAwUaBOtPbVEyJYXr4WeXioq3eBOa02czYIrjadtdubSQURJIQX7j2mwAyYiG1Ej+6s4GRrIiYiIGczbwWXTLg+vUVW0G+3NOYeNgdkOYtMY/FbuZ2EZVDWZiZ2yPqSq5q2vRnLFYMbHTNmuqumWjCefXpYGFJ573q7otP8hYtaLEaNU0OP2cwf75DAVqteAyXVJBnsXGc2+VE2XVXqmphkyIgixVUT8n7bDFcrhQZhAHkXoVzrtmMJwWbDoUrvGt7xMVcn5M+o1PviLPY06/0fe/9+Pj5yb2ul7lj7TXb+NdtiaBInUc+RGJnXqCJRNv9ZXk1J04DhzZfHarbnneBeQ2yFm04qY7F69t5HIP5Ww6+RgJ2JUbRgzYZ2Ph4C3uUTwUSYYcwYX6mFhkSj3AEMiQKz7zjvLhG0S88gD+YXOHNY53MShHRcA2fjp5PTh/889Pby4uQXrA6uk3gOZCT6dp2JJ46vs6Swc/sZaS2yMl1y08ptre+Sb/Va30WJ7M1fXGisTuOZvyGyw4pqRu8vCpfn3uVvt4JioebeIBv+94/4eFZE9Q5rpOv0Gm8zDChHkihN/Pn05f/0Cit68+v9+oxe+dasWZ9eHka1rkDRhJ4JJ7A+HJEScuEHCjFY4jPs3nHy06zebJ6pwgtmKpLU6ySjrnGw5r2V3L7lp2b7/srmFzdT7n/JKAzHFzReobx41KxChcTgj6WpBuqSC9iyFkiTxaU2x8hJVYxWKyMbG/TK6qeJzyTN04V5b5dOTFoyh9Sse/K4LblsyKhZ0vk2lZe+x0epZzMN61djvdrnVEnT3r4Ohod9Tbc7q7I0imlYvlbEHiLVmSFJvo0zzwGseNSRTNwuOdHfnFLZtP1aG4sSTLtdaIP4JGrE8zRUU0Vyp0IAvy5WnGuKRm8RmjuKZmrRZ/eLVYrg9yZfxy2X0nWV1r2VrL1lq2Pnfel4aNqxlvotKHduJQz2tUimt5o4K6clme5zMIUgOaV6l1dQxYcWEPxVKReATJEEKjwdHC5Od/jqp8G211YjVsM0P7tuzplt4Jm8lhp7PZkjrUcEP+NpWXUrGnicsIopFsTPagcMNtB7VZDglJJ8M68tAsKFnek82wgOMEjZYTxiAJyzvmX0UTYO7aS3SBA00X8qqUdwMIA/A+EXkoX43AEsQMLvSKKQyv31y8MqKRT/Av/LE4b+FutHFvxL9JHm1cDl3cntXuWO3OZfvwuLMPLGj7uwhFEfJ2dmnvaJ8dWDbd3bV2j3oH1mjcGVvtvTbdP+p0Dvd2ezHknS6ssRuEkUVns8adGNM2SJiWoUJL3m0OR8nZDuC7hRISpow6H3xvIfsmhqpCBp0YpRyGo9QHJRnXyj/WHNcM52F6nHNuSIx7ljTxCaX2nYCAfySFJ5XL8qjMrYBvn4vCQ8VeAC2aUKKv8Ofc+iXyEsSG0tksT4HeqYiRaB5evLGyRVUlJT6dZ07YrLz02a2Qlg/AESk/qPymLZCHtdjZkNhZMcwRmtPH5GU4Ow9mz2aFGR7JEBqZzwEPuH5CYtSH3AeRbQ8GAu9fqj26wGo2gEwZbMnmN9bi687iCzPWCiNLhEk9I4o+4c9SumTEkLwKJjh4ieSF/zHl0NbU3lbbJmsegYHHAz15xyhWJoL6XVFAXQ/+uJ24EQtn4OvEtAwIiHdEjS89g+gJgI4C4xSNiMcomFZ9RnzuW0YL9oQG1I5Y0IrrNObaDPbasLmo47jQU+p9ND4G3QpJSmr8upJy4PdfWXOJfBzrdRXRqwriq/mQItUNBzy4GnB/cH2TJyw3JHS1AQbuzdR0L2AVz5s/5fKp7Pu6R/eT6Rp6uI7sZjtyAtuYA23L3H+gnjwD9SfjSkrRu82Ai2Pnm/yXoHJ1xoXgXT5tjVzPw4LLLLLksxY8lyQii8i5uEY+vn6b0aWvJXkPpCjJNoD7j8LNxOH2HItEP5QehS+ywvkohJks0qDxMJXGg6ivjltp3W+/HG6jwEpZpeM3ZFWnGmACD4K7QJFFZdVbxROGMde69eLNLFdZBbgxcn3kFjRRb/LNqZUW82KMqevNA7YpkZKcC9jx6k2WzadT7lvqhZsUMWKdk5/ElhOywx5/9Kh/khAe3xojYNHXZyXQWRELZoEbMvXLOGD637OAa21bJHCU3GjJDb8EbidkQanggYTigAZWSH1nxL/sOHxKXd+yJ8y+RiN7roFR3m3Fz8vnHDe0OSTwyBYS5kf4hYgbSULepvftRxbAqgOoSD1EJk0iVSQw8tywxOMEXxUSxw2YHXkLQq+o64eRfFXfl710Wagopd0wwSN9wwJ3vCBUdc4N1Qs8RkZszANGaBSx6QziiXSDwol041Iy/Pjh4pLsmL+Hw1bf7/t//evpFKIAqB8d//Wv5JPvudfi3CJ9ZKofSHgfMu2wo/DO5Df7Drx67DE7IvY8CEBqyFcuZC3zFjnxbukiFGOSHCZ3OmUOFLL1FvKjUl9CQzUAsjA68O3bE+pfMRLQmet4C/lN73nE4HMuEyM5D1lIcCQEpz4DRaJDJETTIRzQ4PMl8Or7I+4sWuQ0wlGHGXcs7nsLI1/sf/73/4NkMIezEOGJgLVNMuWOO15gGYqAhSy4YX2f+gv1Juzrf/zHf5A3XyLmiwIBIiQDLgDI1X3iPmHqJjNwA8sHBPwqoFNIZrNJYryw2r0bQiWyvi9rE8Qp+i1yOkYHsZwKNbYw0D6Z+/Fb9KubcmSELOv7mP4mOYXIUL175LFjggeYoeCqonCNhtwfkrHLPGgQiXvF0WtxDJ9rkaF+zcDn0UC/fnDjUpChQxznVx6fO2MPVt+52txqQEK5c1Q7EOEkZ9Oh4WTEaeA0yWgewWy5Yq4WLDL2Uvl43rgUmlRj2pI9YIHYYyqaDt7VsnU/MaouIdXkrKa2IwGZwKjTKhsMMQiXic9Un5KI54nHCbqshyrduOOG1PP4bTgwO6PewuKX/CWMt/KEhgSEDQ9o4HoLeAGMGwumFPSgt4AQhK/MR3dN4iNb5D3Xv4h6GWpBGmtdD3L8icDpB78gqMVvELcPZgGbuvNp3ONYRMpLZBa4Niz3j/LvxJyKsYM3SonlLZIDqWfbfOvc12sm783UAzGxMDZbU0kAB8UBjyYsuHVDnByYu+QSTPQQvp7kbEYUH/De1OaCVFaQHTN4ox+R2wnzE5tzCLcMxQbVMugnNqE3Lg/gK89EdRnSbetJmSFJmpSIFvkYuDbsXvWuAEPOpEBSz9xOWJAWCwAjhtDCuaFGUGZSe8KcvxFGMTgF34SVgFyZiKtWn+rwrzy4Hnv8tu93WuSV4DMzhT1KHtUVaGAesgCDYUJRmkFMTavvd1vkLQ/Em+UcFna9qYd1JodA0shB662+30OpOoxcFhyrBThswhcyEWYyK16E8QqEVZG/CtEm5XC8fRZwmzEHS80U6PddWPXld4kJxCo1+oVg0VIdjZXV6ieslA83Ft3yCVloUxx3hLPG8wy5Dh+s1Wy4/tkohoGAxSU4zPiqU0bKnILcfEyQ0IYgS9/YZY5aMCKi8sXbf75+H76EsUal2iJvjEWFFkSlLSNTuJIXrHXVapJ+w4jE7jdw3cQ/9hsv84ZgBV/NaO5dDzR0Ts0OogBkcQVzJ9o8qR3wMCTTuRe54OPJkUKi8pDG0D/NvWsFKMTD8uPjB6DwoXYTicWFwfALestCPmWjgPoODACYS5M/+pgXmvqRB1fZH4VNPvWjw26QUbGhPmig3/8tcw7QH63uye+2MWExR6TuKKxF6i/iN0P1Mv3evNeKG+RLK7zz80qx53nbQKo0nLRBsGKGxYVB8xRrgQSslwcGuRfkC+KdQ2czRgMNu6WGDYcE46mEGIccXXWgSLQtzwEgFJU8fuGOY22KG2aFDQIEnfrhPEOo++ecyc0+pfBt5mHRY4WLPrlLTiChSqqm+HXNVKJCKI77qta5+EuMZnJBaEH85c+D6dcjcwPJUUH7PA6gjb6ri9coSGI9MLDxHN04bO0d4CWf3WK8Vvzr9/gJbQ1vNkDToTWG+g4NHLMKnNkbsSFW7c1R62gv2xv8tWJvPmcdw02cZQPBZef5DVJ8ZJaqGxLjseIpjSgYb+4+nUnZIlAeGvHSGLSRGgyRlNLMNCRmYQMNCZm7ckO5szF1v4ALKGWiyhoisyS2Iw6Hy3jv+Y5C3hZOgcYuiZk6g/fliqgNTFny2He3wZ4urDkKHAujK6Wxzeq2u7tbsLvLegfqbvXeddqtTifbPfHzXfa7hLKG1k2Z84yDIqgQkOxQxnEejKlt4O/YFAY2hEpIvuAsmViQHxNI23jtPMLGzO/ewArl4zFjrS+LrzmrU35T7srUo61uyh9sdU4bCBtA/l6uYlZI2xRk7W1puIN5ypoXUgnORsNFFokNiunZwhzRZTaWFSSkYYsb6GaXDOwSo5BxyKIRnLqSQxdbJCu1scFBnPAgZPnjmDCErTl80paYP3it+XVyAJcPXtq8qDftinbFAtGQsQwzB16ZfR00cfLxdAMTMV0IxDa/rjALejyXqrLHBaU562Kzp6blac2pgI64ajCYVl6hV5DYFF0UEuAcg53szXQWLdKnIrRFnoHXJ5pQv8BOJ25KJ1ETdGfApd9YwGVWsz6LjNGYTbEYsDAxrphnLBoaxDaKvH2WPuMVh1YZ1pXYqJKkN1VdFy25IdYHB3MeDFzuflDp3512e9/M/3aSTS3pFOYd5e8riBjKpog3Gz4f4NiaZodUXhy0ryojBPzGdZgxOwGT8yXmyQfHt+d+lc4x3zFnLjFI71MTvWxYDs1hqdgnHpAJvcm3Ea0xVhHngyn1F8VjdRk76Qj7AjZOYeeVtdGJ505dNNkVbA9yMfPAD+RHPDb2yIspJHHJOZkanrtl43dQvKxUT1UvE/1beZzuKMQeKDJB7FHyWvnei8OaRGyJ5y0s85RUHOWUig5opaFdccaC9P4rYlCUxmFCJWJsgQzN1EpjjVAFmY9aFClVIVRBZ7TGK1I659FkrlFGvDrzsl1ZaHhnhEgN51dXLMTBIiMaMkc4m67Z4paDq3Q2CWjI0GOFlWGoZz7e6vtxoTXlRZ/xSDBUQJxDumfCmqeOWUYFnLxQhKSHyLcywQZxl4XziEBQpQ4wmIva3H1/mIgZGeYFVugwjqRZIBNZkYBt2OcLYwSho6HNZ8LZsrq/vu+bQJC8yHXXvGwRpfJ4gZc+RFravo9+RbSuAmaUNo4mUkAQF+X5QkRxxBaUKOFqIx67YZ52EUJoik1DFgJ6+AnwnFhFeqHGbgxqT6FuXzDrN8j//J//S+Bv+BMAYDP+y2E3L6Gxf4gFZ4kJNVelblEcW0k44apN8Qv8IFoFa7v+xWcRtnwCNZ98sWRiaJ/T44TjBds3fmnqP+hsFv/xZfH15UruSL21SHIjCifkR+lZNL8/413EptNLGhtX9/0Fgmt4GJu/EDkJwuOilW4Y0DfqNURHpnCmQveEi0Mb8gIpPXL8rKk4HiHBXFX87A/AZjRjZTdXC8wiD0i/AVPWb7zMnIfxGwHMlM3KD+3yjI9nfy4nmJC0ERELplhd0fWd2GCl12uLnKB1JlRDGiolEqIWAT9RwmWKJ5GP4o7jzDZXC2TZVm8SFtnY1Guj7ePMtlbtGb9K3By4VApx4cCJhWl/tXKWZoJHW3BU6L+/m0XkjC+NgYpebAqniAlJWOANP2rJnL0D9BuaNB/hjNnu2LWzzinBGIKuX72ZQxZhKAPuGfEkc5oQkCeGUIcBivFKEhQZfq84uE3sP2kw0ff2/RAsJaA6XU8Y+twrn0N8Go58ZqQzNAupGGScglNxsds2h/z3hjA/CC8IuDA+w9WZh7Bd2jjDaIHTA9DEHHc8TZQPuQqb8TW5SXaDiNATGMIWeS24O/C3bhtUcmKwC76/iAtFvLxxvJckRjG+v9teqUx0yqerviVBH7OiexWNQIMYEOfBVBDyorov3g1SQ3rRY0qWONwgRiGyY1YSfWzAIGZil0f2uZjA6ZEcLDmdEbEWK3em02q3czqDP9/F2xObKkVZUFZlxSGsiMXWf4Ga8VkkjAgJMRoBtlrm4JfHMyMGzUApolsbWJkjFkYz9+tXugVLM+7LY7n6c/qiEMO22JybDQmLKstAhUwFiCKx9vXYDdYLzkKwxEKUJytTOiYg1sYcio861M2cznDfc322BV1Kg9VH3hzRhBn9kfBza4S3zwcqGCNbZRACmX1u+sP1ERfZ22QNeljpGft31halkkjXXP+lkQaF33DBU2Y3GWuQOjcLzTFxryZAiycP5mUB7KtFHCjTmnA0gbRJvX8TYiFYzCK+5v7rtOH/ctfYnrxQusp0iEIz1Z8owPT/7RALYoS2KDRuMz5RsQPv0yl6Jt186lhOhn8O42fREPBPOKJpb0un3Y55GQSow7vU+w1whibplR2frmhoIE6Gub4qvATbVd4rrGdCL48YfqXMS4o4Jx73r5qp6AsaktPX73dmc38Bria0qIyYzSEaFd2d0jEYUt+NpF8wufHV98rXqnNsqTOrazqzPqpBJn9mXFke2jng3JsY7nW8f9KPWzac+XNPbmmokiOEpzKZzpcOBRTraJXh6JjDkVmIuiPH5M/am/dQ3jyJplfyzhmGtOquOf2QhUyL5lrCBJGEdS6flXvKIgqOKjQ8/nLx4T25wFnVqfBQnR4eHAlqWvBbzJgtIn9m86jvh1Ewt6N5kJMrJllt/HAMBihtRsb8UYi+N8xuhtX88t3rlzKbLJMua8+DkAfSM4NkoUKsJNxzSGGLgMNsF80yowWRdqoWueRkzBROgxuR8bdJZjQUrvuheNuw7+MWjO2SQ7FxBuAyHBJBQBPvbOlOoOlGhMSNZYOiXsJX6zCAE18KT/WgpAXu+67vgMwXCWhgwkdPJJmCUxB6HkoXoEw+/fvl5UdwtCg+H/Lzm0uRGfrmkl4NW+TUyP0RvxH8zr6PH0oBhd24fB6asc6QjDs8HVsQhmGdAcwdkgmjwBmMtkSboTu07w977V3ynkfkDNKOXcgVxdQ/EZ8WUQyDRKiIGdPOWu6NB3BG4H9KDa1v0YBiGrBHoOqpHUmqJhilVt/HrD6hpJtkCJfArjPUp2j0YYklAz+bmZUlpMspK74AmXlfHw9twQCI9TaId5X8ZZMtaj7uDbYpiAxgLtKc16NF+cy94t586qM3AqivlVlttEhaw3Gu5PLlUzeKCq3hOUTYcv0oImz5p0E1laiSUpUcO98onrT/iW0pWBEvBQVWuoAAhfyheOHrckoqu+mGBSg7ZbyV6leLXDAkI3NDITJ0ulS+ZMCA0VEIIs7Xog6HVhSjSYupMpJxBA4bYlrKW1+xTjXAi+epFYav7+WxQZmyDpOwbc+Fz8VoEMDRclBBV8n50gJRHTh0LkmxlEVponSxmieY31ajiGcmhQUUvUwFb8kTwH/aoXd/wC8Bo+5Q0qEY8+180/8uZqAtw3+iRGmSxCqOzd828Ee19zcf+NUYZrMYxlwJxdEhyYQNhC4yggUBCf6nNb8e5qZ9V4cnm9BvtXrboHoTOd5PU7Ul5Fyt2O5FsSEf8Sp6LWkoWTnS2Hy8wLBxnjLF5Ks3qiwEzEnRaiWT7gi/9ZV/QkfGbcgCkQqpRRrmtYwQJGmD6PvrGCFI1gbR91cwQpASG0TfV0aI+wlTvGdVWR+ZN3lkTiBBXPQvVFjtYhAffocvk6fqimfqnJaMI3b+Vf0r+zJzAxaKXxWLdSVQokh3ksJDgQqDQX0FTw1uM8VU3UgwsCgGTXS++vwuicLxv1FcoFtPvLDdbMglewzRF3qxiWDFLDtCKVVNosdljDUVevytQecRuN99dqu5hfLKN3T2Ljvt4zb8D0o3SK9fLmeFMfX4/H7O8x63r2MJMwvcG2ovBlP0tzQC5lCxb7DGVDQPUapBPD/uJLPLMoIzp889q9u+7Owe9/L7rLJTRVRdTp8zz6/f58J10V1tXYD6kDdk+XWlLsKdjspOYTyt70AlgsYzwF/IZenAnDNcS5ABooaSt5qKCZyast4oDaO4jl8cgKHfa5T8e6Fvfnk/S3UXK40cFS1V8FB6riIzyZn2zPP3MO2d1aZd46ukHHgLhVDEAAtRAC4KHaK9HsNQpVHelRu6fVS0uVLhs0USwWxgYxKhsM9duaELVsYocK8m0S29UZQ5Ob3ONHH/ve5Z7b3LTue4s5e/ngHFzRi9Ll7RmRYeotPdLpT72c3vdMg9Gsyoz7yWywulb7KF0k7z8Xh9XbELm77TvuzsFy2Nq4Ax32N0XKwtMi3c/yCDjgOlWrAHw1t3HAVz32eBjNbO6XamjftWzNjvzuFlp1c02D4P4NTjY6GWlp23PvZyGlm946JVp/qA76NqODju5nd85n5hHmYWS6KdnPHONKG6LYfrPtbJvtXdu+zsFW1GbjPqO4E7joqldaaJ+1/dB1anW6LHA+hA5NG5b0+K5XWmkXuVIodW+/Cy0y3akCNvzmaB60ceHRXKvUwb9z/SR7AmO4dFIz2lM4/dcu4Ua5hMCw8gRY5QFbeL9GI0mfsOC0bciwqE9l5OG+W7MbU+VpUfnTYq4t1Creh6NyyAU4k9KZTY2UbufYF0OlYHi/cVCWzATfy2QFbv5zx//13u4orsFG1FO3CnIfevoKJJkdDLtvEAh9aO1T4AGFGgYsYBB27KGSQ55Au9g5w27nm4sdtdRPN7+d3GMlIyNyNfNR7ktHH/3e5and0SJGID91xwA73OFdcHOS1sQMEUdrdntbsAHnYLAF8ER9sIjL0Fovogp437sGqY5i62+KV9+gd3z/44Wby/aN++d9tf3v/rn1/O/uC3Z6/57dmr3duz1ye3Z69/oqfurTtyT/dPp78s/v3fv928m+55zqtfjpaeke8YRJvwhRQHpBSHfaRslZUdZHnR5GrkvuWEcMtrS6KVMQVdhyurZ2PDtGrmxwxVjmkVTP/VFgQs6zrtq1UvSixOWXQ5p4B64mMzZEDA1hrG7BkJx8GtZDHRnC8fA4Y+oBDKW0LGxGVseBcUacgyI+tdjDSFjMoJiJMX5OtU7gUhhJwotnPdIF2Aa5DMZ+DS2GvHxF3gZuMR9RTfQGKkRWtSSpJoEvD51YQwF86OKXpGdB0YBT2Muh34NSNWWG+jnLwHWwOGHEmXkiRoyZY2IjbFQlnZYk+SqkV8VCW+FjFVyhuEdUoWwKk+PFZuT00kYxKvSpaA5AqYscDlDnnRIdAEfLPoyJQnQtoEBS7wZrAQAxTGiVjbFnWHyMSux/GlypGApafeDORn+J7wpSivEuu+VN9VuRJywSJkYnJxrIZIFoMlV3ysKuTabiQ6zGeRBZFHsnIlPGO4OZFMkAZXzPQk/SVU7yQzuoBwLPntuHflquy1iQP8UnIadXb3zA0WwhEHHLMGjZJaHtDSuUjXSjANywJWkEuB5W1iWivNwxRPtUWGpl5Oj5JW0kNzBycZeVJ0w+skE/Z9KHKSt9A1pU+6AoqsWWIrZqS+r9e88OdRlcyse679GCNdm+Yn7chvymTPAIZtwj1J/mdz3xeKWpFIQJYnVN0Rt1oOG7s+5D/QKYociESCQb+duB7LTBtST3gsgspsZzyr3V3fDSdQByuaYCCAC5mbvsNvcYeKwSDDbrtDhGh2dEUs1bCjZa6qkAaffzrOdgX4aCMouIV1X4TrRuR74XvDhW9PAu6D2+aWupHsSLPvGwOlp6fb7kqqHuYMW+Qjx2lh5NP5O5C1Q8/1r8NWyLzxEEVHQO1rIfxYKLp4yUl47c7wKXyf+GIZyufHIg9fNoQJ8B0y/BiwMawMof0di0K/h2tU73ySREvi69WXiCisHLq+SG5mc4gSkZLp4Y3nEtcXh0hRmBRFJACTFNerQyUjlh95cf72FTno7rZf6npSOjgMFbrNpyMXA8xg4WLhKtjWYwY5qgx49jCDTqaV9n1Ac9QKGUwnEgkt/Ih+WZJScfca4Qn4zAfQ2UHAPTZACle7MBc7Vu9yQnVhQF2XW38ckW0RaBho/ewJxPsMI2ZPfNemHoRsUqjhK3YtD4aiiPhQVsUctsivMkwPyBywFViyOllRqTBv0TS11UwWDws1d5IHgYHQgKVpnVTnME5W1pLDACwWuDdSZaJ/d6iGRONVPxrmUadDOqXgRRG9whcSPaDG0SPPomGMe2JMRBAGQvfGNYX15Prs/1NxA3i6nk24D8vjf3Vae/h/7U672xBwmXr6jEkdJ5BluG0B4C+oT96C1QySE/HMNfcxMEWcYT9dxI3In452O+2ePNLC369O8I+AQQRd4+DwSCQbc59cRHGV8MY/VMfJL3zih4izeXBFfZl2i9zd+EWiqDPETWNMn6qPagyCwwMeTRbLh6B3f0OwVzgEnXaH/J3fwvJPjMBr0WvyLzq/mtCS75f1aPUIxIvOHATq0CUDAP9XZQBO5mHk+pW+/ODwoN0xvvzyvxNf3u2RM4BIie8+cSh5x2+YR21W/NHqY7VoML/1KqB2hRXfeYzp3t3bJ2c0uGZR8rN/hj6Tv6MZrPizL9XnygH4ng21sTDWxkp8PR4BgK3su+QuE+OVw0LoopBP4jAd8YzhoiAhxxzqLcCiU+i4ZZyK1j8URYsZfJy3IOJ4lD215B5asrC9BLVbGqP4kZbpY+p5QNELFdp4wZFFrg0y4vyaMFgEUuka6e44tMlvg8Nbkk9TZsylKo8ZM+izW1X0BU3mOk5tAIOSF5AktYl+BWCSnjj5FSgeuEMHtIn1Udgl4EoAYkprFnAIypVeHrmqelgD4lpAAjmgg2T2d7K7UAYiifNFnVLEIyQWX6IiusliDHUk+765N4zbw2ai+J8mtRNsgSp8v+97gPASUySQSXyAdqP0zBojDL1XVSxBeaf6W01rp8ZH9nUg+ipE4+7e/sFhwxTnAwnq3l2+bnxPAoDlMh8zXUxBuLvb6rYP5IuqSMJ33Hd4jtz/+aeMCLz4tXNCOicnhhTUT8finyipdiF+WlUHfPoHeRc5laQgfropBedh9fWaxLFheqUushDRqJCMiwHtawrwKgmjUW+QkUcYDmhmksWEyvpUDzaZBGO3OocoYN/3r9kilFW7PH7LHBFxH5Yu7jCxuDMfVBGVpsbTOFAMZvNgxkM8rPWQLPTLPBxAoOMVFzZWwZW46uqe/iCQpsJaDlNr2VzI2dWrWJizq0ydZMBXKAnL9eFe11qHmhN9n5ZoQaTJiTga2AJ4k6tMTm6YttENjaloiSR0N9TiGg/MqnP/P3vvvty2seULv0qPTtXEypAUdfNFqZwzip2LZ9uOJ5KTPXszRYJEU0IMAgwASmZcrjp/nQf4zkN87/E9yjzJV+vSjW6gAYIUJVMWZ6p2LAJoNLpXr+tvrYXpetguXVLj5U4vwpPIQ4JjVJ3E3N0DqkSKRiU83zIqcHm9aOxNuO8VImPxDVQ8mwl0CM5VcLzqIvFqHXoRm63K8BZjgIS2qY1r5OOI9BdOtvqQFSy+0q5UHbDcSt8eixIOPj8OawxPcrpFfc/W/Sp1rODghLL7Rgao9mjKKsdih5xFBe8lth6gRjADXOsTGlf64JtCX4h+Y17q3U4ufau9S+1T8nSUv+H70WVsJj1qRzCWjhaecjSqVMebZoCa7iX9AXZgtmJZ1UoGExnPMvEIAykU8lwS9m692XCKfTBK8LnJz+o75z63JYjBfrd98OQGiR7l51eHF3xqNkF0WhPnSeNZMoJx8xxKbzjKD5WdMrlnfwy4vVd51LrS5q/4lDMdfRLsEiSu7zn8x87aoQ3qqPLMKvKRD7oHC1iGIxABCmGQingEcIL8VOYuZz/wqSGJFoSLOQwKbhyrImoAPu4U4grZChEMm+e8ikf6dBR6Pv/ySqWrF3mdIjPxCFumgyvYeOtuPc9pNeJzFbGAKr5HPbrUsOtkerjj/XzHa3gfEUcQ6dW+AZsz1PaFfO4L4RLYhlUvXD2f2O9+Nj7hREAxAMXyXqwGgVJxP95uhI30qeJkVVtBZRsoNEp8HaUVYJRiiwZgCKqt0rI4EoFv7UUZOcnxVCI7oOm0r8HmULAXu2c4TxiKmiSSelhlOSBFtZxYAuD1wnhSDXkCRe/AhZX3Eobonu4eacBskGHwmYD2Z9BrAtw9e+ah+7R8OU/j8QWtIfOqnsYzA7JZSrU93cU8K7yYixfPeKMItPHm39KaKIyfqYs5m2Wa3mVaB4VUAnRDHEoP23lNqXuUu95rPgb5WJZbmNfF91UtifEtK6yIKvpa6SowOz76gc/9ZMil6jlMVQq+Gm6DXkT1g2q8BdjcCJAC7GzviO8Djnkj0UGAuxQ9LRSZFVjYNwPAUMkx0YuMd3mZGFxm2TQ92dsD3tKx28fbZT/4jBYacRV5ypvY5UnBLil1n70cQbhfoqPYC99GtddzL4zO5F+eaCyD2O4QvWyD7FJBLSUBDNwTqrm6so7hdEUAE8TqzZZ8XOAEoSbQWoxUYL5uOUOLqCMO+xAU09XVnG4sf4BZeWqJHS0q+OWBCaeoR98Chu+2XymBfVevCrT30ZBXy5S8c0GPXcXvakHHqkCQWWcK9V1QwZxQ5LwakHLAelFMoWXQ7oSFHtQjgKYTX0cd8TJTWDfCv2HjuULQmI233AWrZ0YYU4pNoGdDTem3vMiWcyjU4/x5Swzj7FIMjLor5PvK3SSDXqSRPVGpjNB9renDUzRVo7o5Gt36uDFaEsgrue5ZljS1xZVnLH7oy8wLwmWbnbHzqlCvBUNh3EF8SbP43pVnuZPUnMVGKXCnNVikaiHjrE+tY6ydVaQcZzWNZRbZbfnTq9sT1n67EodWto9cA2zVgDtVAy4IhjCFuo2rCm/yKFny+x3+VC/C6R5OtAjSzDC1S3L7LmD69BklgP6Mp0nQfGEg8wGm74Dmd8XPf1sOlc9vXhGPTyCfTcfjl2sxlnJCUloI+GzLRwFV9R+m/kKEcbvay73JJaitLJhXDjSmpcsCrisPwA9SYMUFF5shs+k6esfa3EmrFj+E7UWj2jG/jxoPuXalqE8EWA8IcCi772xWuoUC3BQKUFrQ+woC2CRz4r6E9+gQ3iz8f7BZ4f93lRpPk8A/4dO2gf8vMfDPlFEK+StNmBjeFgDQjEPc59A/U8LDcbRUaYC3FHM1Yry3EX7dOmZu5Jhhp8q64jNOjNCNYzZqoLrQjThT9zSL4MzSyhCOXU0GaqOUap1MQXiDUckcH59SIg7rSyii6kW6KU3RWXKuhH9a6vpqiuVeROiJapmuQi+9iJUKqxdFlAWh/SQBbKCgCWSfBZwqDkGtBOD89G8MDOvUrVkKeSwZsELlLPv663Pr6fTk66/FoGgqwWHCPwC2o+6n3Jlrb54CsuFKOi0qeMObOGpnpbdQ8iIq3BqWM0A0kjkOJTHiu9CiIxhRGodXWCsnyLD+DkbdLCsQtgOaGvtiKiOMr+HHI7e60t/fFoMh2QS1b7baYFjvYNcEzgEq92SXQYJ9eLO5ztC3kjzzsiqQaBFz/14+Olin5XkcZUE0k0iecJm8jpTppyqm48cwLfky9OaayoMItBAcF0Ak8XgshjK7ljLCAVMuAqCMYvX5LRgS6AbSGQFwwi+nBePd5jIqeG6CCL2kAVQVwpefisgDl456MozjKdEfdrrEEi3mCg8osXEWWUP1omtzekX66IjvEum9N0oVwLqXyOgEJjQYDP5Ie1EoFa/4phf5sfgIi+yhwg/S8W0ST4JUPkrEt/8TYq/npDQ+SlrioNvt7u5+A/fzMf2WHzSQMuzuePTRrNZzIr768fvzr1r0G3jvwIi46JAU7OR8Ae/4BO/4xPv8CH75F/b78v25Kf+v/5rPRl2lk/4v334rviqsw1e9CIbuRcFYPHI99K3roV1aor09cTZLxpB4zfpvh+5EUlA/cb0o8gCBetAHqyfWRNrhoV7EfHTb6WwI+EBHHJu60fSiT7h3t+XE3biyLNX+3k0KQxdDEsuHow0aK7/LkhGQZAbUgv0EAzS0K5i7F/kgmy35NlKuYTQbpY/9jUA7nSCy1uRPvYjQjMhTYq6hREcDMtPRJ+AUOihxoHOh84DY9G8Hu4wpGhjP9Rmo7MI6MVOjUbXtW0eVpSLtYukEwxn7+uuvC6ly99/2XQB+L1JpvRW8j1/l6pMxVH7GOiov0DRDpCfee5n7MfwZhnY8gBHligW3aSwWjzA1C491CzgcvCy7HfEuCoP3sihUWwCXNI8Ouc5lOO30opI2AucC3ozfiGWa1MnQqrMxV3g/upBKKZ/f0RpxZTd1/9ZXswy9Kjqrp9PjSjoltd4BVbWUdSLUAkR0FhICemgEGoAhSilw3zrgWSAIG/7JG2jk4Xsp1KwgvaAXccgKyJfjfkSS0AtI1sNQ+SvuJJDRkHBwAvQWX5odzBL5BzbU3XHAX+Ek0dVq5QgmsOlUqfdjQZjhqZsoTTdkBQjflQ44lMCd2FMMQr/IuZCH5iY1NBO2QgAQBbIAI2i2gLqf9iILJyIKsBAuxkkuAkQkAMaBOSVAP9h6AHsR7CHAiaaSGabiqwq8ASVsyQTp2H0vAUGidRF0dwSWwmJaUd/Yhuqll/YicOKBMQfn2peej4UN6K3Xl8HoEouaosKVEaY8ziOmLSgPALuKwRFmO7WHcpuAdxcJeM5IXcuI9TVi7ew9AwfIEPwEKk0LTtE5w5dzRaIEOuaEBHR7KUW4WOQJcg/MoobQ2Fu3Ck5FhLOtJSg3PmCTw9fbHPaHmcNeCQNmMbBaXEq9uyoy9SbO+f0KoanS42ZN7Y7q5L6N6dwl2LbtPA3rCvLYceCbh3fs8YpRHg7Q3iy+w9jXm0Z2Ts+f//QAQjtLRAMKb6dUdFbzelExssGxArFiqODLxOZ+Zl/tO/torOalzf0BJYzNF2pkzxRuZIPM60qATkPD+ui4kWFd2uK7N9laO1QOjqHDPghkQ7P+HbotoZu6r/fW9Fbzp90T1XYtuKtuxd5aFl8NFPhz2E71e3zvt6+5TXK4YaC5H6XKWNqaJlvTZDnTpHAcGhglVq8ewg662o+VDA1d3ZeftFqOwS/KOrCWo6g0vpUJ4GfSvKdVq1Ah2GpxxWgVP0jkCEAm3gWoxKpJkHaGBZD557RArmQSjOe56QJ1RtSuKIcxqOuTaWaF6dBUuQo81eCoVG8FAFUvJ5AC50UZgLU4qAfazJn0ktGlnkdLtfrAw0DNPgrfTOHzMbQX1IaXjiOyDilOEeRFa2IvU7mzWOFLPF0xmTkMYH6451TiTQOfwUMAEsskfI6d94dF9XElIAzKvVEENLAzymcVCuBAkRt/jlUYYNWxKEIbnfl5YgBH93UhXxJBLQgCBGMq2stdT8BxPjcKdVF3qO/zxi2UjwgXfoZ3qDnFkVmgxa5mUtnHzexz1YtgrYbScse+HFM9LdoKtbaIybFqv+hXt6zKDhxDUGWLBurdw1BqwBsnow4oQqeqPgHgygsiwqPNEV/VhooS/Bq7+E3/KvCAS1IMxLDXcpam0zjtyi6AFuLd1OXOqOhwkKnKMHOZGWepfj2vAg+G1DV0hK40jGfshuWPVKObTt1i0CKcW59ZLnIznBvrBFPWS1UcHPIKoWJ5amXfqbdUQALAtw/MJk68JACUnQASn8pk4kWUVztO4r9khJA46yM7wqi3lHAzAl7DnNb1Iuef6HGhaOC19A2sJKq2bHrGOYvkS9hyDshddYsrhvwwZCwadIrL3zqLNM243qzK9uWHraU4AAW9sPfUdZDi5mDbSYsErRlWNXHUTa4KhwtymIB3qHosBIE0DicWAs8behAP+k43pmuL11xk8CBvWjnF6DlzxLZ4y03/1Lu012sc5xtJ9b5ttoBIXuoMkosR6qYHBf6+EeCs0sGcP2cSi48bEey5mvBvrMX1ov2OeO6VPGHIedRUNMr1GrpXUM4wbU2nFx1gswt6s6rIXzX1ll5W1ffQhmcdIlcttQyMYuVjm1YTYU6BiPR0UqHlDiNEGuZWVcj3I6D6+rtoA2HfjJqScdSe2s0Wb83VducIStsbV87SdjRCjseCEoj/nHkhPGlVDknFox/+88WbdJdaccrR+4743iAmRAWa/VJytsbgq55p5PZ2kF7yH3s7u65PX8KmGs7C932tKhd2BaW/LvVJVfapM61uWuPgPoVmN9/NwvdKkaCHdTdRVzsLJiowTCZz71qm8URi6wU2rAs/UlP4wo/UDLzwozedln+EHjq/684+01D29fs/lvR//dHqHve0i/FW+ktNlLvM5G8m+5nf63ottw8ul1OqeOfvqxqeyh+Mm7V0fv2ZmU6vub6lxrOBwGeAX5CfGG86hQ4COvbB3wfpIIlHeC3ExCoDwhqb9X6jZzC25tXSc3dZJHEY9nP7tuwHj4I/Z5IPOaETTeMwlJXEbp+O0zDUosg0p5fymOWEoBnvhz+fTP56Zh4cXhX0sOECjtBzd/aiADvoj9Be3nnaOX6Cl7C8g/WrUZESF4e4Dkg2zMCljjo7RjjDnA0dhGVn86zz7Lg8G/y14Wx+d/kzYZcNja28z99jv58SqQapMB6r3tLMA3fMzbeziBLxkGJ3yjrnTmExyBPVKg1Eu7CGgYjXLj2QczcmwQdwalruJjcyj3sm6xqlWInQOHuYMoaadhu3wKr9bBRT/lDBotawZbaZd7PFnszbM2Q4qiMdusjaB92Dow043XWzoyZ1y85uv9vZ3y9Pj36+yXln1dWQtsU+TblhqFqXD0HLwfyLXN/OXV/gM2ikuVfYjhZBFrqW56/lRBXzu9dAofF4LGXnw/wvB3XyNzkpU6+2usm92DqYRja/+yw3cSMUfQhpBh06fXbUwT6V3QkuhB8NXOWBWCObns7NFV3kU1mCQxq+t7y724KFXeAEMowqKO4chvbS5R7IRmOscREv4ySV7nW0S2CvtnzsO3QvHvSXtBZw8eIV3Yn60C7pR6xgDSVPMIGEyq+DIU7fvlzDRkzmpLFh38ZFu6DXc6Eo+7xKqYMu1mMtkUqi4qAuC0nVzFA+rNxlgglQEN8TIw9DEazYnIA/7PvJNJsXrSH0Ob7W7S3c/ji6yQshIiXz92LYAi79QyaxMMudqoo2+JuqdLlKXZN0QQeMom2HjhAsCB+gRzeU0BsQug4a3pTciWKdDNXShEfiBhngtoOFWxQDflxujpE2nNQKZVWiuG8WsHVknryB8Rnip9GA+bwk7xftUwRNeUPVhRe0XmPnih0TrI1etCxP7ch4oznFCRXCc/mEVlirLI77E2jIW7lWZqsM6ppjt8KhDjHxuOp4iLNpCPGeKItz5w5fLGgQ53EsJkaEbtH6PakmKzVTNUtrfneEMbgrbAFXInqhYutrRxUs0VyAo/of2uM4uZBt5L6pJfoQK8CpI1o4LAE5SDEuXolxroEc8JMmxXGQHV3fWnvIqa9YSA1uhorAOspCLDOdXVzIlDKthh6ksmPQ6L2cX8cQ8pxeJl4qMfIEmNvAC83HO71IQabzaPg0RvQvdogvzYy8dMp8MtuGOyAFdqQnapdAA/mUKQiEzXI1UGCGgAjZiwYW5mPgAkhoOIZt7pcQEuUyz2fGCsJE01E8paDJ8nH3XmQqeOKRM+yyC9mqOrjvjLZT2VFqtEJeU4FliXA5W0JeyYh7Cc8JjZF7RqyKGHMRyisZ6lAfQExGXipT0A6+S7DFDVBR3vlahyW80QQAf8m0tyP++//8PwL+hj9BsWvlf/nyahcG+xsRXJs21KRKPSKZoyK9jNWY9Av8QKOC91z/EskMRz4NMdkQScbVq9sdSMHxjV9a+g9vOs3/+DD/a3epsKI+WsI+iBRMfMsRQvP7S1FCHLpI0ji4uu8rAMnEae7WogLFiFitonTDMb7W6B8GJCkoCtOjkIV20OnS3+V4aQGPQxwMcR/wqX+A7uWVvOcmtcAuxono7cCW9XZ2S3YufiO23a7ZlS8ydJmbW3+qyUPAvAxXO8c0ZBQ0kAKCfcGCyM8dUJpOO5yxkqqlTJXwSFF6YO8ZM/SJFsZbuuOkdLwVYSw64i0hsxEOZZQhx/Hs46zGM35lfTgJPGbeFJDJmWgvql37YjnviffhlYwusktU8MBbHem/P+lAn/ar4ZfmCokmMqWP0IZYHnUjHlqzZ69Aq0012g7yp6dyFIyDUTnYBM6uCYVw9SFOZYZQBDwr9CRmXqsl1DA+Wi8gXmeUNwenpdykzn4R1P+nbmFpEJLjLrjAQq4VhdNRPYZvzyQpZoWarrgFL+niQddc8n/ukDuBohoQkvgdM11DVMfZZ5lmc9weUEnMdVcdKGuWXMFeih01i4yclrAjXlBfCPztoAui2Frsiu+HxKYLLm+Pz8Nn4kfDy3dOjono6A+L5A66zbJ33DFa9S3EB1SQdjmzH506/VwBdqmnqra+J/BuwXlzYFUhM7ZhA7n2wRNr21rHGhxcps7ymWMopsL0mQImjskQZmLpyex3ul3HZPDnm0RvctfjOAgRPNeA4lCdyNnWtyBmIpmRc8BioxnoVIsC9myWGRgyQzuhaa2BMocyzabBX395G0Ca+Vw+V+jeMRelMWyKD7m1w2pRYx6oNFJSokQufUN5BQ1HHSqYRYhsUZnc0VKx1hYg/KxL3XJMJo6gpswGTKmorH7mw5FdSmM+rH5uDPOOIBWPwBWls4HJ4VFsxre1aTuBNmBcLwkoveTXLvugqpO/GtF/LXKg8hvO4oK7jbEDBXuZJMdlcEHtlskgrwOgL4cgUC61vN9n4f3rYAvJfJrFK54/TLvrOmnsmC/UUpmGHLQK88kSD753M9gCrdAGQd1uFuOkk3ebQU7V1163ih78OcifRQfAf4JppqMn+90uJHgl3ggCYajM4V3q/YZShi7opQOZqgMCWYTO2BNeotJU9FL0lpE8Hkr8Ss4nyuIYy1i0CigKLxUvX7zZm86i+QjrwkHZMzmKAVWK4UsO9KVeFGQc57MPvPpefq2yX2uDUwdmcOqtWmTxZyk0FaJ/A+xda7lXieapvvc1y+nee3HtpSqpwaqNoosp2JA+oqNllmPfaklRJEQ9kRPx5zY6d1vROdaal4m2YRHBsUxukOlbGKIy5VfdJ2QYXAQrp/4aT1dm/lKJOkV+EyCSTkX1oQa5v73ICG15+XdUZf7unRgVFvb08gRR0V1/P9JnXalr+2tJXVNLs67cNfGvlPmn9n82TbNEepOUPsVIBD7LE4EBaT7ozCDimbtiH+EvLTHojGL6l8xGuyozjEUPEqYADgiO/RR7SLR6kRHMoARe9NdSNgY80YcnBiLlrrYICcF28PRhsE40H3MjkFQm0sNkO4AYWvcIX0LxFYx1TmfDELzYXuYBIcVDRN4o6s5jya1elMZAGJPg4pIbCI3ltZgE0Qy6Z8SzDOtjdNaUEag2uzYj0EERDVICGw1GCZn5aITFs0KHTUJ61Yc7j/XhVjs+ZZvsR7zMXBqdFj+ESk+pBU+7SUPXOOvP3ldC1N/EkwADY1xNlwiWjpTiJq2cZToOvEPOeSrLzDya7lyz6iI8ABT9tOZsOiyBSnxn52Tnv/7+a9f74dkfw4NfwucX3367oFlA1VRhni175HcHH8J//P2745ffX16Nojfh6DquHp2QyZ/Wlr5nT+XszM9e/vj9xejg1z9Gk1+7L1/Efy3+2Btn/SnKXmv6n0tx0hGmXrQwD3DAbWQ0XPS9nJP7g37pRRg5Eqd5ay64P08MGsB1kIbmwR20qN0U89HB0rYhpI2ZAzbOG8t9ORMpgWWo9ZkmEllGGmTFE2rlk5kvXdWT89GinJOKJLN6t4UjzNTayUmo6D7BdaYJ2evGldUUKjwi3FwBK97Ej2JP6KBz3HVM6Fnn2bMmE/rkrmunWyKqs+qyYnVQKEizFFH5KioOPVBzPpyz6KmXctWb1G3b62duecvzZdHFDssf/am0ZIat687oM60mt9/UBBNbIpaaVaFqTGXDcrCDa8Uooy8fYT1JfR+LyXwni7L8rDVkBgsePn135TKq6ttt94Y5Lta9kyt5V79sEl/JNiZKFs+efeFOj5+ux6gNdAyL55NzXnaug85BUxXElqFeRsT2lTHWVz6YEhH/HGHR3AlYSzoKgWU082YIahRl+lukfQ1qvwTy9Ir1EwspgozSVXFrAgbG0zYiOQXT9VKF716qGYKezZ9oAonHofd+XiA5Z2tW/vK9/brOrNa5SjPYhApad1y8U7HkpAkzhSxO+oo/Vmnr5GLjzcmTM9QyE8fLqyWkbNu5NPV3LiQwUJ3yPqvtQjN5DaKC1NyysLAT86zjVpWiV82AePL//u/5CvLrilfq+JyxK8sc8TVrzMtHRzgVa3FcxJX+1SQxzPB2YQE3aeeG2aOjYQHVxoySb2jbEgBzRkqxlZNV9Oqh0w9vfxfJD1OqgDxNwHrPgvzuqTcPY89fObuMowkVcYQYlSp8g11ixyutljN4oDk4VM1ajpfSegHMHmcBnq9SQEGvxolh+9Yx1OUbXbd2fLVbVpXvMn9ybypxJVXAOhbvpZzmqO73ErIvMOW/kIrnGm3J3uUVQ6wucO4gv8ztU77N/DJ70SixzMt02kA6MKOO4hHP+ETsd3fXTmy3FORq7Rx3Dx2bokxmVqNYzVJew6LJrZsbKj2sF2lFjBZ2JetfMSJXKfvcYC/MUb14verZEopZl3IDVnyRbY6v+0BuQ6UNQ6WFoGWjkKmRW7A4O1Hf3AZhbrEpdINbiQruBisTmXkYxgE/23+c/fxGnOHuCT8ezTCoKejBoeo0rpWFIJrOMmg+ksxGmaJAu9hvZDgW87gAlsIFh6KRgWAkDp2/erGbx6Ps0OVolqRxwslpU+8iiAhpYcXz4sQHyLEYzs1xEaEO/kiC7HfEeSzGUkHW4EYYULbIy4OuenrboBchE8hTNNjZ2YdI14A1r1y9YtnrFQchEEoOlwgiKN2b0Ku1JDqNGE+iHhSUVdGLrKbzEJPB0CWZsjDzlLMguY7uT+fnbyHXzGqxhuHk78+9iwG0O8zLGdJvAr+zF+GHeuDqvApio2MNKpyRGLwctyHTvP0aEH8DcSk9H1oVAixwJDEjtBcNDrtH4k2cidcQAg6g7K1uuIMEd8loESr+7K8Ur7rFfCyzo4s71+QHxJCbEd0hoJ68UUa0hnjITi/6IS9O3yI3N0DbBxpIjCE9IhX42SwO60o+yZNszEQmiqK4vjpf0sKHE33181PEv6xjpKnEP+U6xiLkBay5sT1pnGT94bx+h57H4WyC3bfhdu2JGc7txB8KPRB5xpMgyyoTf3SKmc77UXQiI8j1+af60+hgYTWB+L1h9x53kMZOdaBjh2PA6XX4uqYelD7MCVwHjlVhxiuZpBofkPOujjiTwLqB/xLrU5Ue3Scfa90MU2BhkWZluLQyQudwgQ116ugaWxPW63irHPNcVhpKSBgqysLXHnaPXGHcnIchzmUUQgd6QoyA8s6LCTKI90kzOt3RUkW5qrkncgslY9X+wL5iDyJnu46CjF+iWccG628aP7N+xc1Shyq1NlSlltTV9j7qf39aSm+7kLbaBh1Y8nJhm6a0eTqm41bYtrrHenQPkwKq4Tl27ThUOTjpHhUJ/A+ARJyVp5urFeuQV1txtQZxZfVvumeiyuJrW0G1FkEFsqORnLIdFo2LHpmPVTgYfim4QtziylOWuvQLUGO7rqeIryOVMqUhh2vyBBSq+2CPs5WcAcL2BfSiVZwBouwL6EVLOANEjS+gFylnwCb3VS2Jvq3puorpamluSNSPVAWfeT83Qge7tnXb0LZ1jGSYuu6r+lejf32LPr2p8asgvDZzUMqA4gvLhQLwGPX52UIUgGkbARpRfJNaw/m/kR0g9oFe2G3tMImeQMK3JjKqj1KGY9Xicq0Z18FzG8z4o9l8U2GgS/03u/vt/WOr/2Y1whULuqitx+cfO55nwBO/cZoEV95o3p8oMJDv0bmhtprQj3wHfrmSChCsp6z6y5bnfNg+6J7vH50cuuesoiQESXLMufT86nOupIuD5egCxAPfUDw1vyhZgycdhZnS0bQ8A5EHEs1Q3lIoCVVhc1HHc5JAfKspeCCfkuRa6KX0gkLOt34vnmZiYY/0zbu3Q6pH7e7+efdZFalCcmQYqH4Ijm0vPX8L276/3LZr/cnmAz8ECS8ls4I4MZo7rtakpNEqH/GB7j6rOlyFij1VHMEcYG0coXLOB3ygKyhjmECW0rV3pbpuOGZdGuL2Z33Y7h6f7++f7B+76Rm0tKn03ldTdGmEu5j0wcF59+nJkXvSaRx6ydSLZNgJ4krua49QO+l4PF5dVhzBod/vnu8/riKNi0TKKJTeuFpalEa4/UUGGQdCteIMptfBOEtmUSQTLhDlmHZpjNsWzDjv/afn+4dVix3FCVg1UZZ4QdgZuejj2DHI8hOnUf3mC/4YRcOTkwP3xKfBBxli0WLu1eFY79IQatq8XLdBJ4/bB8fn+8dVhzEeSS/yk2CcVXPr0hC3T91P2vsHNXI8gQlkoTeLRpfV/Lo0yK1ykaft7tPz/YOqAzkMZ3KaBFEWesNKvlca4/ZX+hnQ5P7TqpWeeNNQXsexXy1hSiPcARd5hqK4WyUXs8tZ5MtkGENWmpNpHzvGqD+NBfpYln/sd1EQH1VKxSC8kglYJaPLSo5dHuTWCWR/v72/D7K4imGD3hRfV/Dqx47nb3/KB0iR+1VHcZQEkzSOLrys2mgtj3EHRut+u/sE1IgKETNOYsBMTqGumpvpPXGMccvLjdM+QG3+2D1tqK3xF5eDc4vGJ44xbn/aB+39oxpNZATtq5IrmLWTXT9xjLAGAVM53cN29wCUh6MKhS8D0zYDZ24Fq37iGOM2vBqmu0vO/6P78o84eP3H6fzNWff6TdD98ObX//zw+o/4+vWL+Pr186Pr1y9Or1+/+M57GVwHw+Dl45eT/5j/19//cfVqchz6z//j2UIbeUVQqhXjqAaGVMMvCj7KxoEtVwErtWIfHZmlfG1JPDI9mzuk1TBfFuQ3rz9hxqM+I/CXICStpmWOLCKkU29XfsCf7I8r9RWBho5png5kBQauuapKh6oBYRWfYRBS/SG7iE+ezwh1xo0xwG12wbVw2I3+VariZ5DEA7gTQesAjT9CayhnuE91E0nkeBb5OBmYQhyNCBiipo3Fp0MJTkdwc/WiAXAieUJvgCo8gxa5M3GOYuRhv40h+MIAMmDUl3lrZu9D8tN5/jmUgYSNkWh5qChjPIbsT+4Zwfl77q+GDgtnMiPP6GyKaR6XWTZNT/b2oP1bx85BtsO1/MI9HrON4cSOc4rYTISapmJJnczKdclzD3nRVck9IU5VjQs9nDeHoCtMNovFcdfKQcvizAtVcXlr52Aslk4iu0zi2cWlkAFWRbI762HIhqtfqk9ROQrwJUPJsCJHvmRtfxZKXEulKp/DJ4l7cASTifQDL5Ohbhwz8mg/S7W5uBsHfFKjhhxER2eOOvs6UA1ZGamCQlW3EFSJMM7uNIBdt9cSIFxJIKORbOVNRsYxdKmED4O0J2QG6QlMZHARXAXRBaCAJgQGCqIR/CeMQ/hPeol/BBFWoBrhpUheD+BZZ9dE/UFH3e6/mXMutlM02w30ImCFkC87jK/wYNKphEExMO9lvaj5GVFJK3b/E70p33+AukspFB2TsBVSVQdT9YogSxC4n5VFiS0WBtg9bpRROhaHSYmppPM0k5NehKgDN/fzfB9fPIzj90JGUCXMs6qGeZHq5KCeAQAd1p3A4vmx4PfD21X5xJaFywG5mXaQvwBrKb4birTlL49Uy1U9BC6AB25M5FhrXXcVkIYzOZhDRZjBiZqfrn1lto/l3gj2cQDqjn3xaF/AEHA64ExOYgvjSm18oVeITFFYjC1wfccLBthNXh+kXfX1IPPUe6GRG74l3UVGMsiV78LMB1TRC9cdS/MFyDQGVGorQJQUtK8IRkEG042nwLlVNcG/4AnjNGHdKRRRtVIUvxtFCjPmw67woY8W8zKdTjYNkjmhAKBHrklvzCOF+IUy7a0+yYR6FJAeJZDd6eZdushdzu/aYmCaBMX10fbBwJSxdt+hQrPkVUon9yI4pC5erxsXQXHdE1VEedBSdfRGqohcL9Jsn6AEnirdrmeuQ6hDXY7wO40RYm4ANQwTcRmHnGI6iqOIq+xxywyoaQ2nl25t+3IcRJDi5E1Q5gJ4ERadqkoUNy3XdTridVw2MIIoSC97EQgAZLwB6ESRH1/joafFEIOD7r4grdEfKNVFDeznehUZdPj5L8flqUA33QyqC06hXB1FjanKLb43nUejyySOIGJ87QUZT6RFgosXSm/PQfeAGxNJf9ARb2PcFine/fIK60eBKEo7qQzHA67kN3pPwlOmXJ4wFun7YEqqIbyPvphRv1Eu9fFlA9gAqB31NpFjoAwyRPy2B/MefKnl8XKYEX23+gKCbjraEWZ8jM3FseDUxYXNdxEpKwY4OWyHapgA25PbFKhhEeGJR7/88Fw8OTjqqvQ+mSNKUZMdxZNhgKhUIFkqsznFzwC1B/oIYsVgLp/di8Ck9NqphG3EYizzKPM+LMibclQQvEENwCDuw2T7SRzKvlIiKmon5botb6SuwOpruLH6OK0QwMBU9hN0ikEmR5dRMPJQifN8kGh4XuNE1UpjQ2LQEb8xtheaVuAoQKq6OLMSW+G8ZcqoKddpTe1qWDBAO6/oxJNDMD1Uw5Wej6hOmaDaCWISQSVar+rkmtDA1fIdqnhS/xeaFb5Q6AU1/B4uN6qx7taaEPIL/Qc77z2gpyCS/67ASujSm17GEZDHv+13jvH/uvvdgx2y3b1QO7ZYzUIfF3kRzrxI/ACuesg0RofPLEI0HNcpPMsH4Z+eHe13D9mPBn8/P8U/Eglw3J0nT59RmQ8oHYvuAz7If1MTF/8RX0YpGv9xcuFFXGYce47jF4lT+HhIrkBgMFOCuQh+nMTZ5XzxEhze3hIcVy7Bfndf/BRfA/lbK/CCZi1+9WYXl17N93/HVrtagZzozEXwfG/BAsD/NVmA01maBVGjL3/y9El33/jy879bX35wKF6DcmR996nviVfxlQy9kaz+aPWxmjWY33qReKMGFL//Obb76PixeO0l72Vmf/aPMGfxE/reqz/7XH0uL8CnMr6vjQC/tvX1qPZDV7ZP3KON1svRbTFAJm9rYNoc09ZgboErvbhj2EGrm0HZfAofF84FGURlS8VpqJQV9hp9va11kyjTPH3shSG0IB69V3NuYvCy0DUq9ODS2t8GBpvdL7RYdqa0g5G8bkNYI5sRlEyDY/uwKC4UJEsTz6iyJQ7J2qsQPHCHRtESfVROCaq0QAPO9jSJseAShZaZqg6x8Nh7Ugl4Qft2SQd7up3Z+4KGDz4S1kcM74EAJcbq0gwFqXuReTaM29OWrqRENgo376OuiCrnB7wzVwWdnzST3GgOsuLOGisMs1flsEF4F+bbTGoX1ofn2qe5Ems8On785OmOyc77rNS9On+x88lWABbzfCqAbDDCo6POQfcJv6gJJ3wVR37s4Ps/fldigWe/7Z+K/dNTgwvqp3P2LxRXO6OflpUB7/4mXmV+Iy6In25ywVnanF5tPTYtUuq8rCLqm7mKBjoMlcKrOIzWepMSP0IMsplumjeM1vY8+GGs/g3KDlGKfS/CSljoFwN2LX1K40lriTu1iLv0QQ210sJ6GgZFfzpLpnGKxtohNkX9MEv7gK6+iCnwQz0hl6XuyRei0jSg5bRAyyYhl6lXdZkuU5myZACgwA3ZtVGvy/9CaKgXlVyvhhTERhfQEOFKJgm8KVDOpiAt+uYGxlZ0uJ5fqtk1Gsxqcpjby1UB0Ynd6UV4EnlIcIaqk5g7ekCVSNGohOdbRqcxrxeNvUkAHTwSwu7jG6ilARPoEByqVBSZQxpqHXoRm63K8BZjwKFj8BOPGIxIf+Fkqw9ZweIr7UrVAcut9O2xKCXf5MdhDZgIzu2qLzK/X6WGFVyadrVcoX2YssqV2CEnUcFfSR1PME5bDgSTD0S/MW9hb2egv9VepfYpeTjK3/D96DI2M6S16xdbY0OJShpF5UXfNE3cdCvpD7DRIBXLqlYymMh4lolHGDQhvMWSOTbWmw1n2Aej9Kyb7EyqqTivJTzTfrd98OQGWWXl51fHMn1qNkF0UxPHUXX1jARsbziqyrveK1T/k+F4lUetK21VKztnNvok2HWHXN9z+I+dteGo1BHlGVUULTjoHixgFY6QA4NW4hFgl/LTmLuY/cDvIeBDC77FnAUFNY5VER8An3YKEYRshViFzWtexSN9KuxPh/G4lkWRxynyEo9SFKup9dbdel7TasTfKnz/VfwOqwHrYdfJ7HDH+/mO1/A8Io4g0qt9A/ZmqOkL+dsXwh2CqG8sXD1/2O/eOX9wwiwZ/WZDZ1bCWaq4nmq5ALioPpULdp0PE3el4FbxdWRXFs7D1excydvodXrRC0ZTLQuWEvjWXpSRMxxPI7IBmk77GmwLheuye9DwhC+pQj00taPXGFiwJes8G0+qIU+gcqXC2Sk4D6WfYjFzA0nWqa9AS4dtlbLZ+eP9PH5X363UKp5OaKBiz9K6OuMrFMk23igCbaT5t7QmRg8YrXu5VsTyItM6KDge4BfiUELUd6za2FX2uuExyJey3MK8Lr6vakmMb1lhRVQz20qXgFk53A98pIW8CH3ZJKUgq+Ee6EVUTKwODJbF6FVXTvWO+D7g2DYSHQSyS1HSYrl+bFjcBPu1DOi0EthVbN3u8JgwcK36s5cjCPdLdLR64duol3zubdFlQpYnGssAtttjOOkn900GaaFtdKm6npIABrKJMNmq7JbhXKUmnIkURtMMVR0JoSRQ8JtUX9U80IL7FXBFHN4J0a52OGT4xvIHmOXoltjRomJfHpjAuHr0bVbCrWYlcGbB8iXD9j4acqlJfUtXXoOr0mVtRoOqHmYWmUM9FlQsZ55DXipMOVK9KKYQMWhvwsL/6RFAk4mvI+xvzGg1QrCBl6oY/GWjLHel6pkRPpRiDOipUFP6La+w5xwK9TR/3hLDOLsUA6NoE/mycrfHoBdphE5UqjF23wp+8dRMladubi9yFYzgaeD2vpLrml1J81pcpsrib77MEKC9rEWCzqdCcScMYZXbkDYxb+9dLadbzeNbbFwCF1qDZakWMM76qIbYO6pIN85ISVnJ/sqfXt0uKDQYKuv0K9s5rgG24vxWxfkFwQSmUIx1WWFMnh+7aR3+VC+S6R5OegjSzDCNS3L4LoDz9BklyPyMp0lgeWFg5QE47wDLd8XPf1sOJ89vXhEhT+CbzUfIFwuvlrI0UloI7Exn+hQg7+ph6SNEELejjdwbTH9tWdG8bKgxLV0TdF14fD9IgdUWXGCGLKbr6L1qcxvSWhwPyA8qC1455vdR4yHXpuT0ieCW7v7+zmaZ25D8TUPypQW9r8H4TTIL7ku4jQ7hzcLwB5sRhn9XqdE0CcATLmwbgP8SA/BMGaXQu9J0idFtA/HNOMN9DMEzBTwcR0mVpndLsU8j1nobYdCtY2Upxwo7R24aJ3FicVaOnagB6kIo4kzd0yySMksrQyl5ySjwAkChnVLhnCkIZTAOmZPjU0p0YaUGRTxQSYrbDRWdHOdKqOdlT3TzJkPc9iJCKVTLahUC6UWsLFgNY6IsCO0nCcgCRUEgmyvg1GsILiUAj6d/YwBWp0LNUsgLyYDVKSfX11+fW0+nJ19/LQZF04eaSg8wlKvfRrko1948BQTBlXRaSPCGN3HUzkpvoWRAVKA1/GWAqB9zHEoKxHehhUZwnTQOr7DwUpBhKSeMfllWHWyHN8POOjLCOBd+PHKjK/39bTEYko5f+2arV431DnYx4BygDFR2GSRQri7J5jrj3UqazAuUQOJCjP62/ITDOM/jKAuimUTyhMvkLaTMOdX2AD+GacmXoTfXVB5EoF3guADWiMdjMZTZtZQRDphyUr0yctXnt2BIoBtIDwRgB7+cFox3mwuS4LkJIvRuBlCiCl9+KiIPXDPqyTCOp0R/WMOI25PnKzygRMFZZA3Vi67N6RXpoyO+S6T33kj9h3UvkREVkBoM/oD6TVLxim+gipv4CIvsoSIP0u9tEk+CVD5KxLf/E2Kg56QMPkpa4qDb7e7ufgP38zH9lh80ECnsvniEw6qqNyfiqx+/P/+qRb+B9w2Mg4sOSblOzhfwjk/wjk+8z4/gl39hfy3fn5vm//qv+WzUVTrp//Ltt+Krwjp81Ytg6F4UjMUj10Pfuh7apSXa2xNns2QMicys13boTiQF9RMXHyOPDoj/PlgzsSbSDg/1Iuaj205nQ8DhOeLJ1DKqF33Cvfviy5tU+2k3IRxcDB0sHxY2aKr8LksmQJIWUAc27QzQYK5g5l7kgyy25NlIuXTR/JM+Nh0DbXOCiFWTH/UiQgkiD4m5+hAdBcjsRtveKWRQwkB7UOeBsOndDkoZUzSwk+szNNkFdWKmFqPK2reOJktB2sXSiYUz9fXXXxdSze6/DbsATF6k0nprdh+/ytXcZqj8hHVUXqBphh5PvPcy90f4MwzFeADfyRUJ7olaLL5gahIe6xJ5ydNktyPeRWHwXhaFaAtgiObRIde3DKedXlTSPuBcwJvxG7HMkToZWlU25grvR1dQKWXyO1ojromm7t/6XJahV0Vn9XR6XEmnpMY7IKCWck6EWoBezkJCFg+NQAEwRCkF7lsHPAUEHcM/eQONPHYvhZoPpAf0Ig41AflyvI5IEhp4yXp4J3/FnQQiGhIOToDe4hs2+7yfyD+wa/WOA1YKJ4muVitDMIFNp0q9HwvCBE/dRGm6EyvA7a70uqHk4sYwGgj9IudCHpqb0NCx23LlQxTHAnagmQLqfdqLLDyHKMA3uIgluQQQOQBYBOaUANFgawHsQ7B/AJ+ZSmaYiq8qkAXUPiaTo2M3owWkh9ZF0L0RWAqLaTV9Yxuml17ai8ApB8YbnGtfej4WBqC3Xl8Go0ssBIoKV0ZY7TiPeLYgvR52FYMczHZqD+U2oe0uEtqckbaWEatrxNrZWwYOjyH4BVT6E5yic4YNF2qnm2BfBvqjm0spwsUiSYDpN4sC/vj9ed6fOxURzraWoNzx/U0OP29zwR9WLnglHJfZ/2rxJfXuqgjTmzjn8yuEmEqPm/Wnia9uYzO3DHptO6n+psEalOVjmbSDiCJvjTp3GE+5Gne8jIIMMXbnfN/Cth3GgI6uHXlNwLx/Ry+qauChB0sbVh2npW5xKwE79Ytab4i/ZBLrcXVRcTSxxbu/GWW60t1iE5DiJ7r6f+hK3D/F18aNsBIqmdr4eRJjqw5V5w+bGEdUNVjvFChmuScT0Gv68Xw1M3Aj7Lf3ucw6+xFePj9986Y9gcpk2MJgChEqL2QAS1rfU8TscqGSx7m1yF9QxomDXA4n6yPP9wH1LIxcwUKaOI5w+vblrm6qgb/k/UtevDk7kyPBYEgfb/sBdFHV9CVfxEdBR3ZK+wzb4tzrXQYvi/vQNaXQamQWsReFO6aoWKgZQWqz+xPL95Oc+f7tW4H2OVKY80EztxuDEsYRevc3c3XxiEopTmdYUs4He0iFWYGY9O+9qDgRuv2RF6YxVrWXvlBTa+X79F5SFTJ4FJcDb9jtRcYUqeJlsbOCbiqiW4mAzWZNvyN+HmZeELF1iAsyj2dJeUW+SlG7TeJQUJtfVfHb0x9eSHAexv5cbxV0JHh81JYR3AlRyEQA0Pjo8dFT8f/9v0cYj+Ei4F44vfSGMkPHHJpp6KBOd+vK+p+VuaQIiFuTwu7G5P8KhEy3wCjGEyx8U5VVQDUXRjOgSoh7H/397wMdp04J0taLBqDZr0tusSysSg5o0pqhyJsXN2YQb0Pppei9p6zJf2pO9fujumO8i0QYGaTPxZuZTBa0mIITR1INmmRAZZjyjmpAYhBHLTj94CS248lgxS0l02Bu+l7Ph1yWgDIA8iobX6V5ekyeCtpDOeIu7PtgY3W1ORVqnTc8q0LhG4RnwDNpyQ2PWS8ycoSaZk2sOTmist51Xq2ZeDGKAqzUbCT0EWRFsW9yGULRCuAVPeikeoktnbSUzI8wBs0uZnC1uoBDL3qk2O5RtwuQuAgVJfNxVipJx6Pikoi8yC5lkPQiNbi7tqv6SH18Ve6Enatxqeo4Difh0fDw9b+9/eP4cjR5E7/67cN0GP16tKMLjcbUcMvhN1KvoHK4c3RZwsSn7NFxF8bUj9mFMdVrlp1na1s00yyaWekBWtkKV5TUD5oVynTA7s8L2ofyIprR+yi+thIMDa6C6CFEvN2uKoHci3QJUW1B/ff//r9sQ62Gwdcn8wFi8A1aYkKwPVdlQlmXa/dLDBuUadl0jOZwjgVu0f3NcIsW9/4GJfCU3OhzZazyy6rtX8OCVIagsO3AXtTEELQL1uX2YFqP8an0ysZDCASDVZ/EMUZI+ONyg3eagLKbBTI9EbnsrMba8w0rVBzLVziKoz7Zse7IbG4J21avYKu3eqVQiENdQXDTKPsXzSFvBBYE2P8UaoqTRI7AepuiV2m5dT0tTdArTFHo7N71L6QrVaS8iKyfWhALvL0jvo/SWSLN6odg7ZH/DWz3KgecKvBmqr6oheJaFndlzTkrt1MYUJuw5XJmRhqztoqtSl3LfdD5qxfijVXoKy9YdksfN/E+9AEmxgU9LwNHmT9eZ6gLx87YCJqMmpU8YQjBNSfUpBUSBfAAvlZPEu5wdo1EdxlkIvUC312PM1fp8WYErLnyLagMKUwGJ7ISFdmF5uBz6KX52PCht7QLUdzP7YnqeouqPqnVVMEoaajK1EGtQz6IBFnFAo3qoboKjY2qF97b2oRaTWQ67tcCgE5zlVobFOoAcP9hPSndC9VNv+qxRVCVammyeApKW+xga28waNgQwMa5cvQewcTaEvlig606XPj5Aq1mPHSdwdWlE+H0szVJcJpIb5YAVzorC5LfDJ+xlRGttHSw1Q1nNDp1uIfxmlZzwOU4GqTQCSuDzvCBGalz4IXXawl+bQinpHUx09ziXzZq+puZIQEv+ezZdAYnHZzk66CBXpR6g4DT2NIOKMstJVAlRP9qcJV22txJydejqu7EtIPFHDeR15OdY4gYJBNFYHKV1QAMXErx9ddGBRL65K+/Jp6rthXDufQN4L9PZDgXEXSaC1Vix0R6fH5wf40QiL2/IsDBoDv5eCy5e1f5K2BNqbX5MREPwPZxJElf+Adp2q58PjhFnGan0utSBfKX2BfssPvf//v/Pu5Cf8VZJnWP92KWG04NYdMAqKMOjZ4G/Jt5Az/8fCqQf8OM9M1Dyf170S8NWO4B+1AGuLxcElJgXqxnI/egSSM5IUxSy9MbuF68Su2ZEy4K9WmjMIcO6/HaXMwC34tGEDv20XuPsdlSMqJu927yQytjSZ5YU4Q9KRwP9Dmq5RapHHHWQom48/CqRdx2sievtcrCEAapKALb7djvtLa4aofPsniqT5591jQ82POvYM0oSZhgF0wWQA0pk0NHPEcFZKktNlgXrCBzrhOh2RyiAcw5PuBQ4GdK2ysfvttJ2bPOgiM3byhHHoeybKbUiwyuVEuGd549V4fQHcdev7il2njJEbfMEvrj2PtCnMtLpMUdqI9aKi2uhqsuVhkaKAwldUH4swT5smfIfae6QDy2QkXQxTcvAtVevjTXaqUAvAB/OPxvv+VfXxztzmi9hq7Vx38hxL0oh+7p+f7RyWE1US+TQ6cJqCJ/TjxHGgXCgOy41Gp5XKIsoh5VASK3ykAcQgKOLuzD8IYqP8g9yJ/T5OjMnzvPTT++uglZcvVkV58kd9hdwEoXJsllzY09i1cqCKAqHqPS0mQJZMLmOZuFVcSl39oSioMYVqZiJdtQb3PKaZ4gVp34e8MEMR02IGKy0Og/yGxEoNuabhNXgbcGqGiprc95zl8/X7LYl0FlCzOtDrvn3acn+1U09nkyrYpwm1tLuSrbPdvcq/sVDgDnuz4C68q5smtkrl4azx6nGBzg4pU3Cw1wvf+bVsU7PX/+0wMoi7dEJbXC26ldJlsZvajoKOQ6a2LFMmtfVj+Cz+Qwe2cfhdXcZbkdWKozfA8MrFUKlMxUDd0NKk1SWaS4YVGSo+NG9lZpi+++3EVrhxD33DbBBwFrgON/bylMaF/vrVnpiz/tnuiqa6k93a3YW8sYqmmD8DnqTtTv8b3fvub1HA43yMqYqfLx27IOm2dabFBZhwLZ1xkXgCyFrO8g8mfAq2tsB761rW519iH1Iq3P6SGLut+PMiMrQd0hRqGXpsGY6ZYCq1GO7Vta16zW5yq10OlsGAYjQxkVjw4P2hoILi7lB8+XI0x7I6g2tKApdWYiQt852ekeHMr97vH4SI7k+KnnPxt5h/ve08MnB353dHh8uINo21cyusgud04OD6DBdpT/2VCDPC2stW7mWehGpPMBv5pF76P4OvqKsgIRHbq7mIOUUnMoUQB2RqcDmAxC3+cliQcUEGRyki4+wdgJrf89KokAXCccKB1Jg2vcbPjXzK1KL8jFZpNheO1f8tKfIQtXCfKWzNDTzRu0cwsvIM/fKb1NUew/9XN6Qr+zXHBRgO6joCght32W2NUVvhc3Kf/c9bFU9T5MTSVOCswcRyL2CHf9D77tBPCvBr918FBmXB2DIa3cCrLEBKv7PzZhhaoN5JYbNuGGVvL2Wmn7Lex3gcDxRU2bwZUYMaDuC4r7lsfelMfiNn02FmuVV4G8MLXXCoSfUgYsugZVM5u7ZcGtnaODQ9cX8EyDVKjCPVA7n0o/D5VLxWc/JlX36QNs+TN8wbF7D7iCKGcRkx/pYUg46QfZ+iRck548yiqYxlA2QdZFFJRAVLe2wyC1zYJXQQo+br5R6DGLsvAVZrB4GLst3rwVgo1NAlzueJwvndskWPfZecuvg9cXWZJrmt95vlE1ZP1T2ZjT21w/NU5G5enF07XU2d37iP+aw+VlzrHTui8ezQrjvnwfpIHmpkn1+dVzXfH4vouCP2fSeJUu/M7zePTu3csX8OPEy1zHla4An5wFvhU+2rIWOlh3yVBKVjUzFEcdAJ6cmf+95SoNuQpavU2YCr++AR/hOyvUAXKDgsapRqzWBkr3bpWBpZUBtXJ3c3R/of9uVYGVD21+KtagCfBgex/pHw0VAXWA3XpA8VBW6QHF+5rqAV/00c11Cr0jN1N3eG0t3+8ixaZhJzYc+C7ZRnOJz5PbSvzlmcdCgY/cGHCKI5ns4X92Kmu585Nt+yn7z0J/DXKknfOVUhrhCHFzaTCZhcg7fjo/f6vdb6qWd37CoUqsf0EdyyIvnP8lxSVg4GahTFvglYNlSVuqXyRWwKRIKpd14XQCs4gyFs6AEriUFTicXVyANTMOEnmNPgoafAq9pfjfMLyqmc5TRZxnzNCXVHeYSrkVrDfKZlRGczwORh1xRqV+UjGapVk8EVz1ryVGcfw+gHeg75GpnN54IeOQKwLqLijrZKv1J8Xc8X4+uoG/W1fZVfjnkEdQtcB2RgfPsn/8+mz+j7//sP+Pv7/p/v3gP67+8dP7b3c+WUgXWqOdvJzmqzjyoVxlayd9H0z7o0soAh4BgkGhk2jBKdAA/0SYTH8f3kl/o4O3v7/Tsm44KN5wAC8xqjfSP/PR+O98NPOGg+INOBodZTB53p1TdCCLRzEUHIVzsrffgWFmCfygykan8UR2oFoX/quPm/7JUXGxIuSg1n3BXRUV2r6zC52ZbvRaOVu5ucgqZ36QIXxCbZmil0JgJhkGgKCYC7gOhS/d7+dvgthfCKgoDZIqiBwjBOClAu8VeG/5S8qT/GSTZWGmeZciNUXjEBcnWt6irJ+O4kQ61h/C/HBJYHo0AnKAnKiuCpxdVeAP36mLIuTvBFTwBWoVroXPT1dRBYx9L/NUgQzzLQs/h85psRKoSR18hN1TGmGtC2Yqi/eltROkfTnrc3FdZzjJ/VTMVXebvSX0siCbWfdHs8mwcmUBnL3UA1Yl4GZzAmRRHC31SDob+sFVgFXwDvrLLgKElf7CMshN7v/k4NFFQvvtUqLYhc5x74Op8CJo8823py76ozIZJ2LkTbPRpWfo+0b8UJEaSSnnp1wCCrLq3J3j1Vs8ep9sQVUwgOiCwGqVqvpw/RE0JO0ahF7ede2tdbTL1YUN8Wh/w090YcVvWIOobf4NSiiXPgFU19fUaAGSS6o+wMHhSLw7j7kW+c7XveXLy77QUB+cxx6OobIZy68+g6OnNFuzHQmn/f6cBBdBpAK4lN+rNWl9LJClN2K+qOG4SmBnMTeWnMoElO+l1qBOY3KeQRtYAJPSxPB7U/SIZRDpZKPbgIwsoc1rKEgBFrLiEAZUo4J7U2lTbMgjrr3U8DV0GvBnC+5h4kwc1qWgq9xUCTrQEGkSsJoLGtcvKd2rBZ/jFJ7lo8FBxL5SxtY2Uq205b3EotMzivRcmBcmB2Nbf69BnruJU8HP1+d0sU3Ju4FvK9iW9Y3VzpjTEHDt9s3iF+2YGY3fhl50aiG+P+4MZynU/ktzQs1kMk2CVJPuOJH639Mk1ru/Hgi5ua5pB/9b6xvi7nu17iFK52iHwRBMqz1j26tjQxcSogH44Ct67tR8rBQj8uyrjsAGtkYx7hJ6QcgVpFy+4DbhhlzW7bkHCautIxJTlaxmD4x1v9GKBWsScIljTNT8BTkKdXuaehdBRA0o3oJ/iMpVjmZJGicDkcaU9mnPHDUcrC8Evfj8XqRSPHkDU5WNiXWPlZuJ3pnIKSiacSIuYlWw/RsxiMfjVGYDms4FoL0gT1bdCvfpEXReLUQVQHdGxbk4BSomOxgHYSYTrCHZiwap9JLRJfa3iLwkgW6DPE5LDOIEFKrhHC+n6KNmt9WAMowGVHfRn42kgIRZnhFWV8I+2NQmQnFebGEN5bw6lBo7COP4/WyKo4wDdO9RvpO5ulh3PBUTSqul/F8P1Q5QVzJoP9HqRcFFFCe0TqnsiFc4cF4nmWuW47JNJSbLph3xMhOJF71PxQSQibBkc1jjUFIhPPjQWcr4Xmy8QWuXtrhtDa0F00tA/omQ+l11epH+uhyoN4onQyyrTTTFi48UqGCK785/aD/FLGPx5t2rvJa9ePTu3yBdZxe/P5qLP2dQ/0/7GKg8e5wQdFGlVKdicNTtDqymc7CQI48qKAbRKJh6odm7cES+1Ng6L9on6OMaDXJ+MlhDOvGpju3U5xAX9PalojpG2IZ2Uc0I17E0pR/wHvuUzzCJe/Bezk9wkQcMRNGeX7AR6bn3cp5S6Uh45+CkRNDikZFZ1aLbTn76ZcA1OgO/8AyEvewnAv/k6NlT9cDlbOJFfXwM/9mGgAPy0vKT6l7jfZdxmvFM1T+Blrh4vUr+L47Dd57APV7YMfLE1LgkMArfwtVcXMtAl07yFnl6Qab9dDaMZDY4Ec9fvvhFtX4AtvCNblNobdc1tOGCQESGHWvo8bxlBDW1gQNIR6a0vuqNJ/vdTrez3zneOzwYaFYxwF+7ne7e/mM1SThVF3Eyp31Qfzl2wLjxZP+g9DjvhB7AtVLWzcZO6n4DgxOj94AZT01ifwYFaX/F5mAnYvDj6fn3v53+16AlBqfPn39/dgb/en569h01EB0k8iqQ11zTDfaSI0bU0ysYiR+9TF57AC2CG1UifP4CLl7nw7izyPwrgPqA8BBdon9LxVQanXz+fvOAYwOC+vP9Bv1wBK4gIYqSDMioI14Q5h1/Ozj+htuooXIwCr3JlLwZUPP54Ljr7H2U2wUaP39wbIaOSbqvMEcw4+0Zdr8RkbzwoGN7xUy7HfHygvo2oaqglRmjrEbTz+iaX0Hj1H/Fz1MPgtx0xrBBzoA+B/ulddRUuHTHFEggNmt2CKMyCYg1XgnQwcYxavQBcGDJmh/KaaXktLSMbWllo8WaT67cqEVLbb8HFffgwiRB9g1UHJkE2cBWgCbevBeRytWBlrlyMs3m/LWBoTp4oIgI+tqOOBWT2Cd5Sj9hq1qwMcHTyCXS/WCM/bVUH7+WKAr1+r5fObHxpy7YKLhLkxoJO/zKEz8A5YmzmUoCD5sPYptUbyJbIvBbQkmYVi8yWF3L5M99mK79CwZ3fVDoyCerIqRR3wvolw40rFVv1rOit3vpiMqeyHRUoHdm8wa1f6O/E80H0AKp2Umu/QVRmknPh0aLaSwCczyiJOv0LMmvvHRkMiya4AKNZPbXX3P1Kd4oidO0rFXAAiixnMLRyc0axzd2xGvVcIlthQMc4aDbNZoodcRzLyprr6zp5IpfXRM4C1NzgEnnOajmwFqf1/M38vp0OrUYOi74Io3NMCBaaAe0gyiFTj7IGktrxRZFSgbF9DKBWrBYX9W0LTriNdsM0mdTRJty2egyZ0/4J8ICDCXESVpVyw7p+Ma6t1QHctU3DPmM7mzFXjcvEpk3xOeNns9o6+XcB+ojNbZcNM90GC7MmWg/FtJXC6xlg9FCuUg6R9CuIRbvpZxSkUj5IRMArYA+27+8QtgH1NWlloTYKaLT6ViOij1lXalzWnsCLfrb79YSIBZdMuygH+P4IpTi+aWX2VYELGQ9TRJt5KYwLLHVhA2q9aLhbHxaS2B3LnCbee1UwgGDh+DZjlFsK+P10/5pkU7Q9wocCgxtfCtY21gyCpa2/KYx0Dt/upjGU0DsULuOaTB6rxqwsrD7NvBbqJqqNYcx/fg6CmMPwwZYkr4XaQsCaOzlW9a80Qb9eRJwg/vccEXFayThjOr6j+ZhJRdui6vaYv3lAheepezGAbuJeltBBwwtvfHamQzlCP2zVhM8eITtr4FhG8G/r2QCQdKBYeqkgxY4TUgGcdGodGBaC/gXXlVhHvwlV8tbYmCKNBywTgrCA3m5FtSTdckT+MvWzqnsGFUJAJWC1BH+4DkzMG7N3kSLMA8Gb/9OM/AhFla0fXa5Urcuv7MXyg9e5CeB17+QWd9kEHmsS4EQHamVdT6RQmcuyy/CSqL0TRj7ur8IvN7qI/rkRe+bXnRItnR00j21FtywyGRqV5DWuNDPNXnHhtRN/hrs+XzloScIqp3Qu0K5jlvkOiOlmuJQ2NTjMgil+tUQe0FqP/55VqKyZJDr7CxROWjtU11X3MaMDVRFa/4hk1icJ6ApYYymZf7yWxJg2QYVkhAck1C3ln6nB9ZU2EfFVTqFIMcCtH+rAoFL3L06umIFV57jzSZllKsz8i2OKEgh+YbscY8tN2WqMRZWtWiPZAZFodjzRXr+5rt7bwxcXfrwcONzU5bXNkHfd6B+Spt7lyKzJDFdbKlmig+QM1Xyoc/Lb24YBN77yElGvgRjusyx6PeGHOuFLIb0ShxB3eLiWNTRDtFQ0PSSlfIUfKBcVhgbZnKFUbQMdHwVpwdXuU99USG9H6wstzkXzcYKGK1ej9c6dzl7aJ54VN7yW+VjRI61rKz7rEL5N6YYGJSCjowiHdlVV+itt6I8Oz4IzMIwGGXFL1toAvjqmFi6f+qNoVtRXqZUtd3y8l7xGJCmQUCRnkWbqCbXkNpWHm2KPGI5gnfEyYVsM4217drCO9hRRosaPmFpBaKnWjKcU29povq8ShJkHEgsOL08wum7+Uu/nEhbI9J+YeMatW1z0ibIyYRYQGptlopoNpEJ5LuWePlWUK1fUH1mJ1UjjbvoCMAc7IfM5O69O6C+TCW5dxsq16paZS0nmoYe677ghg4h6lw06skxUMVlR8qjEMlrxWc74mduDMZjYIQi5d4VYsZBcf8biuV4KjSOGEXoYx9K6GqrnwbOs2Vzq7G5O/VzEH0293NUt87YZK5bM8UHyHI3VK9sUg2xzs/BuILK2gh0vTHuPY7fQ+NWC4VYRivXIxeWhT4LG/nci5pBn18zjLEKGUKAYaunEzYBx+CXOQHVjsnMy24RSp7j+mkGsdh4lvUiDu+jTFEPhPEFQ9ODzAwsU48nDvIXwc7U4rcXoTDRU9Q4eHzvxJsrtKfIYSB8YClczCCuloJ2aXA7QeRRQmoEFyAcvVR3F7bejKYIIImmHvS1hPsKUy6gcbAzk3ch/RON9G9pXJ4JvW/lIH2eXcWaFMK6QgWBrbq3BvLAC9NYwcTVMzcFofciC4VewqttQeirgNAV5JggeTnI0QSiE7xHYRgt4qzDZVnT1xiFE0YEL4mpfe19CCaziYg0blXN/G6xtZ8JmUNt6wzIp3nYXPsiquEqq+NkVsZz3KkOSTysiNdYTok05bAtI0tCquWUcVsQyhaEcisglA1yj7M2aKmkD9iOuX3X0VBm3lqhI2SiLGPiMI6jrvJ72df9PH+oLpdXjMz7KrJ683sMdzf2gqXeKPMiTBpQW75MiEHDh3cqUnLhus6MjROtMd8//W+bo/TF5igZ5F9MU1IpRGibon/UkaZtZxH1olXSiHTi0nAOzZt1JhFmdpezg2sTiRpHUryCRmosxG279/JXlQPkLgn/JSJEHcv9BYh4FkzzzRDvKzo0Lal5g6LQlZJeQ7aWE/fzRXFtDQptHODWWcuFgPYXHcQ2cr3XEuYxsiaXYsBV++DfFQOerxTSrpjrlnvdJ+61qCp1HNYYJLoKNdyFbSfon2Vj5Bf+uUL90PYGPn6bzSbqCC3wJu56yjl3Ae9/USutKhSPdYhyt2puDrHSbVRY0wVGtTa8j7mO4JndOdm3ZiCT/jKzMHR9XNsppv9eyNq3H3Qx95Jef9w15nK8TBcM3PWVaust2qZRHIaUR96Hz2rEvxxTWndFNaSgxWXUfDlN5MgzWsSvtbAanrUq1nX2/OVrqFZJtWQpzVY9ecZl2zULK12wCq/JBAtfxVH6iz5vH1VRwJ3/EScXXhT8hevIpfQrC6wZK9KAtSkmU6+TwfUUAomhTNO2ekMQR+28dzpEMCtYX+BN9qb6E/s4k1QnLi9kmnsfkTDrFDybfcL/tn2ZeUFoM1DYT/FCXyizUDB3GY4pvCFkZHtCl3mBYRszVJ7y2rgpjpdfa/O1dgV3vSt+3qwPh7Hst8LDUuy60Zx/OSe05WBfJgejFkDrZ2B7H4s/wb3N2BoUDd5DvGAlS8Or0L+oTfcVjVT1ayFkLhnXEoaMR+R44F1rgPhyg2csY8YpIOWaLTaaEq2rcSiV+rPIYLNntZJtVl+UNy/6u0rv6vzr0OKngxfNwhAOWrMSyjTEKpWTy09WFkx+gWVHsTzdmgsnt8ZemNZ1yy5XDtaVllvNbvt9jaYx9gisLtbL3JYxMNRQkM1e57XvdZ/ljSzkCxyvo3jWionidHQJjN32ys0ZdeI3X3Fl7qaM4g65tyBGFkjDk754H0T+Z2eR60Gi1PMaa2maTNN84FNrBxaq2YN456cWr2GTJwiUUzjF+CO/t3FleosgblOgLCtP3BO7VZlS9yEzxC36ffq7n8hxXz7pPvaP5dPDx0+OHx8dHx3Jg2fP9r3x0wM5HHafeDtbqfKlSJUvQnI0SPnPle69j/Cf/oIsfxI3dNUlbnTWvlPcvODkTcOBgIddZW1CbAgVu2p5w5Nco7BRI96iq2BVxd9azVvl1byjS7Js9/zuwgyouC9oKICNPbc4WIDG+9ZQ2LL0DWXp68ua14wXKzQi24VsG1ULvTonPnfCOPg/9ZJ2Mn/lhoE5sCMajA26e8vw85Dlxmnmjllt1fItD/9czp77zsNVqv+skrlSDquLv6oUZDeLpauKxeorD47Nbr636NOyafEbJxTcE9vKha1c2Or2q8mFBpULXO6aPR0Ka+S0wbNOjzgcN3iY1dUiuBf62KWYSgDd5qAHMt6pKsZyzisXCciND8hmTefR6DKJoxiaAJ3H4oKLLI1mCeYg5HdTVh2Udr+K31Na6wAU0OEsfF+6bWAk+gfcEFCnOQz03ZwOjqnmCfZggdlCPm08Fvtiyi1uC68ALJsKEYuXY2wrOsvSzHPeHWBYeZrEF4lM05ZVAOE6CENKbKSSlFsxvDbpYBB/MX82p2VIJiLyb9kVA2CXgkTMogByfV6+MFGTpUiz0Yga/Ew7h0fD/YOjo6fPjo7H+/vS8/aHT/ZHR/6T7r43fPpY7nxyu6fcbB/oRc9DReHIKie0wivW36o7HS+ckNXy4vDAangBfy5shkz+MXtHPuEwL2mV9ptrNiWOc7voBmRB7SZIqOqJraTdrEmbOXr8+GDfP/KPh48fHx2NPE8ej57tP34yfCoPnj59fPwQtZkia9hqN59Xu+kozeE2/ZcpNm3B/mta+Sj4NZs4Lyv0IIVqqlCCTCyZYtAaT/YwLOxFabRVqQIgko0kSp2vGomYUm1Jogk8EZQlG0Q+Vr9QjTsz6nsVRDNJGcGsY6gaOJH8kO3pVNxUZpSEPIoTH0vAGs3OOX84VemdnIE8i6DhnSPTNx10xH/FM5FeYqUK7NkcxcJL09lkSjUUFDiaHvgqVXWlQFsOUcrWi++//vpr5ya5GKcTZB123jV1SMKSXFi6xsoT4UzlUxHFUVsnYx8eiCHW3cIk6o6rs72RvdGtSiVxN7CrnLxqY0flo7D7M7JAo90iBIbFywwqu3iAzBW+BNXdrr8Fcz2BFlOe74MmDsXSIG8qzaDjlbYSVP44U10rb5GHQRFU7hNJ/QR5BFU4DJkQPwX3np694TuwtpFxHXqzjrJwXr/v+x34/2XBoLerM+Hg7VWDBbetOq2OBYVbHVhQ47wvNjmYIaygwx0eDYeP5eH+0253OOoedJ+Muk8PvfHY2z/wD548Od7BZd1qcV+uFlcBVL03cY3FGt4ScNUKFYyBgDVa2OmU+D6AVrWBrzWwrQtq64K6uyrIprzkuB2/tiwwG6NzN88pUj2xrVNkK063TpGbiEyF022ECQjDKrmpIrKc5rYgjAO3yQ/U37noSslBub6f2ubSVtxuxe2XI26dR2ZTRG795LZidyt2t2L3JmL3RniLvY/wn9oCHEWgNIrsCrS04GsV0Yb8nmaxBp7bGnm9GvGTVa/0CxJdS0CzcR9u0fGau1ypiEdDbLY1rbWKB9Nb2trxovnPY6S2phuKtDPtQ3l6LKa3zHPKL7/a08qFv9rTXhrxgw8xD+ghSbQv3y+7qBSfIerAzulrWZbufTTNqibyDgZo64ttstxKks9p37lKUKWW4Uj3IaY9ssxMYywoVWVap1IMlPnIPG4OXUCpgwICGglvRWWZwdajePCJGLCpCA14klkU8T91k9wBllceALeV/gCtRor/4SSDVF8i+3CA58CYBRqKKrLoCT4djN4fqsA2PlUt7s39WaOQtIbdUJHsJKLbEs4Ful5STNdPdUMEtn32+0z9/TjpM/U3FKKFcfR5We1xOkNbMbwVwxsuhm0OcTOBPNlLg0xqUII7oHoth20v8sJ5Fox0YDWl6nSOKkC/yaE4VbcLvq+uJlD5gTurBZTMJo7CirfvYoT3Ggup/ItLxvD8iqVb2xR5bo1F0A8kX9YvG2EyDYo6roOvWEu6kL8UyjVuMAOZdHA38agvDhTl6NnLwPdhDRVWvwkv2ftI/6wv9GLzFc4dKvEVXQCkAV/RxV+iPO60SdzFQC7S+twiE2uWG+FiIXn+SrJ+bpJ5F1uO8qA4SgmPb3GUChC9zRvA4C8xBnJLNuAKqmVI6rx9yw3glVtFYlOO/aYbIg1PvSr/7DzyTgyKfeQ58F469bomQIODr2pVbNWBu7JpjF1b2qah3draNJvDir4UDYSj8De0aRB1XhWYsJkXhuLhSUcjoTJ5u1uaEnzOcbcKS9xxZfka7rU4i2zRwHqE5q2KFg5ZHA57vfaH89WH1CMs00IoHrs2ce0sbena+g+Yr30hKlaoegTdgKnhvzLvYiXu1sZ9aMDhBN9YssuwGyzwOX1XodMPdJ6FvyAND46Suo+zHzHlNkhzwG5ijKlSVAHEC2mzeWbwSn2b1842vTCs7w/8G+Qf48tUjq0SAZi6DK2M/SAFcvIFto+dpRXdih3xIIz+3JiR4Z7djpfIygzdcrIvnZNZHOVGPO3KCwNQ+PY+KmBXNaDE5mzqSZqLetricL/yLU4LVBiP2DSqHuOja+U7qIcAynEtwxC+fSL9lvBjSW2gFXjjOgj9kZf4KWWFXwJzFDhpcf7qRd4P3FOtvIkFAlaF47ObwfmMZapudAuQGr00WSzU5ohHsnPREczIOqN4skuFFwZTL8tkEg3EUELn8ytjzfOhvkpBdsxGGbCMR6E3lKFI51HmfdgVcRTOO+JlBEkpAUyjZT1KGfgy8gUCaWjhp7NhGIxEOhuPgw/i0fmrF7sd8UOc5Fku8ZhvpXs4/f8Se7PDngPXbolUUl7KWxrvjMYDznsiLrNsmp7s7V0H74POJP4rCEOvEycXe3Rzn27uw81771LZf+6lMsWdbtqt2CwWYKysXc7p4PiwocD4ySBp/Pa18mSk7a1oeBCiQbNkg2fcSDr8FUerabzwYCONF25crPHqu6DASzwK0PeF+WYum7/Q/xL4XSoRXziUyECMciZxIuQHKskCL9G1g/CNVNoIc8ui6Sy7f/rzUgqrXuS1HnxFCVsV9eHwoRILWIEJXR3sfUQkl8wB0UvCrvCRBrArvq8OdgW3kCJTfjSVG+FYzBdrbW/Kh/ysqC+YxppQXzDUWvkJz+2hR0huxq7QvXI7/ApJ+LYwXC4eRb+sBOcq8asKOJeTX7ngXMi1uBr0g+db9hvX/bq1gcpI0twOqAyZVeBv+dU95leLEGLN4SIldlMBF3GyGw0X2apGn5HFbL4a5gaqbNWwLVtbH+zEpYaly3ir1OwKnir8GVibk7HVAFGw8pB6eMsXbxI31cuo15SWbq2cY4sH2Wyn00LuUYfuqCp9avOBSewH47mDE7BS5KDKEgN4DWMEhZY8i/gAubE9QTJLFSx7cNzhbjQZc5eXVmUUg5rQNrt0mvW6zres6TNBcD+nIoQZy6s6pdJRgOrQj/DaahUIbqOppeWWlkjmZ89fvhY8ilvPye8AUotnyYgjbyCodehNBfGGcXYp0nkKJZHoxeLR0Bu9p65Pz8N45o9DwGhNZTIJ0hRibnRfS0wTCUgAXwxG+r721X57sIvYAO4zMktlwo90xNlsOo2TLOUoHxaLnIuBH6TT0Ju/8SZyIIAWLugzOBZIyIY7jNcF3sQos+FOdoA2CS8jX35Ypq/HfnvoQZwzgAd1MZUgoc6QgHJhjUoXcaHeHKp3JIQyO+JX6sERyhSROJHYRxhdxp51LxX7tFilfhS+HHtY+mK/qhsFfnTTTzqbyhFJVu6kCkstuOmFiGaTIURyx9yrQoVioXooAJsr5qjn1TXnRaTQeGIG9cgPU6g7CpT76Jcfnosnj4+OxBnHjw87R52DzsFuR/wchTYlCvmn6O1gfZvezgBAIClRr/StmTvAJ6VRXs/pSPZ2ltK6jdOu5Ua12ADu8W/LyQ4gdHisjweUKno1CQVXzk5VZ7mdWWJVDnuC9ZLNkF0m56ySXHjPW4C0AbnQrlZIM8cFK0is2WX6i2ZBut7MziiedHKm2fGmQUex5omEU4NlMnZ+/7Sp2j9sR+dCyaEVmxyY4k5L1lJUON+4BbFgQ/I9yqXObln4Ic7OkjmIiQOQ4lAy6BAkmPHrBQIXs0sxeP7DQDxKZCqTK+nj2Jb43N0EMbWy5n5zFkL72K/V4ferosIF5eW2+V2DOv6OCT0YFrcuVsZHuxkzYxW/iQVA4P875WeqAn1TTX/vI52KBVFnkxHqOFIp3FzDCHWQ2WKCZQ0cwcG7HXFmafzNFH4A6jGL9DlCehXQC3N74qB7JN7E4rnq6PY5MNsNtHe1K2t7n8EBF3hYj6oCzk5e8yiKVXu83Z0FjVi3vOrmvIpP35fAq5q2ED1NpJhDx8ZZIv8XIWk9Mo7yAz+L/DiS1e1CTQZGRRPsEic1rMssbMK+VocLA5gTji9evrgzH+xmM5KKQp+bo0JVzObB8KStidiETWF5RzjQ2eiynrHQLSZreYt9RGuYy1svyQKYsZhpXIxBkqC/vD09f/5TXm42dTqJjtFFpL2Xnu+3RIINgiiJLZHT0BtJc5g4EgPaqBQKIZvmJj0zkB8g0csLX0I95B+KhqR4VO1fbaEeJ2h4MfEi70JOrGZBKXoECw6rh8k0b2wHs18P2a7n+23eVWROmhRPfZ/3A7s+XTA5ovsQ7vw5r3UKax9PYeV9H3cF0tJ21Kj6mX9+VP/a6R4cyv3u8fhIjuT4qec/G3mH+97TwycHfnd0eHwIBX9/VwuGrGyWRCeBzMYnuOfpCXzQiTcNTlQ925ODTvcEz8/P053fyUgHeuavsz+OemEpekPgaqMPpCFL3/hPfIg8o4s+rbfz+846vg3Pp3vrfuHDCwiR0i5UfRg+0mz3wP7CTJt9LOpc+vlgLdvH4EHmM3TSPpbj5aREcQ7act9osLD82Z038pq5KV646Yd8WvHco3Dox9N6z5NDZyrKkM+tNVXO58HoTevSjxi69iXYchKKfleBiC0daWYbX4q31RpgeAvF8CazDGYsvCxLguFMVWqy3EpO/Wh/V9X3oD6JqVCl7JXYAICY+HkS4F5b2o8YhdJLUhFkpBnF+ialQCkFiyepB2SQjqoUgJ0sVlKlCsMGqXrjVnW68xACr/zSnLxM65+bl9fMaMvNHy43X9xQT0URfmH31/l8WoOcRgGgPGVtgCXUwofUoIJGrcrvN0t/4HPaF4dvyI1L8M3BzUbwAO+HEGkwklpgHGqB8bglSkLkaLcjnocB0DNELEQGjsgshuJQo/gKGs6qDcgnMvIyeREnAECheirvUpmkLaZegiFllzJIzPIEfFg64j8RlZJzdjSZweGZf1kc0TxUaYFNEAZLwkfs3b5ljqh2pg8ksgqcpGK2G84tXzCNzrduw/XwUJuZLUaYLMlJ9z7ahFrXrc3FXCtDHBb5VldOsQIdFlsFXvryhYtl7iLuL/DFyxfEqQbA7AbkSkSGN9gE7mTA1AtL3Pi9ZdikvUR2Em41Cg/WZ0d3i1J/khH0+7IRFWtn75KLNoqwuGe35ZpbrrlSTy3FNM+UI6+ONzJh1GmcapzGqiaPeRMd88kSOmYQZUmcTuWIihrazg/pjS5tDvRQVEfetlvmdvTDKspicX5bfvew+F2q2cqN1UMmpb2PTI0LNULF9SpVQRqxoQ5Iowkf+mRizU7gd/zju19eulXCJ2WV0Blu4amejOJEYrjFUBybPbCJ6qXeqBvolcYKN1Uqm6/w0qAdopg74baNlMrCfLbcdctdV1QjSUl7S7Wik+eAP7xYwF7pkTbXl04ItHhRw25ZEVQvEfyWOpUTHzzodMsP09tm3IG6zHqPdzvipf/W0CJ18dEsFt4si9tqCMkeSHwZZrnxqBi6yvXZlvZ0QuTr+jIYXYoYZ+2FYiw9KPUMkSwID7ewR3aLM9xaQmajzu7mIX6WZH/uHbxtfkhv7StC69O+NWOQC2a85ZgPjGO6mdYaOCjGNeo5JsCJao1wGqOiOA7vnUKweWn+TJ5GbiAgc85kJXLDJCij7hFWE9jlbG7Nba2Mbg7a6KcIEQZ//btRvr23M9jtiLe6bjME5+E4JVB2gXJQBnk2Nuu1+DkDTjw27HTIPa5IAj7aBJa5TTD/whPMbVpfKbt80XFZ3tGDrOGWBS3McxUnjz23DRepxGO34nQt4nTGAusm2eUkFRckl3NkqIDDVPuk0sttGWnkPmI6eS75xoEMOXd8KHWHFRSHkDgArCLPLp8g2pM66QQwNb4xiMQA/5UO6AX67WrcSHyvt0RfRZsCvwlkShZiVgAYJ9hfaxME3GfBlSHvWUNmulKHbplNNs1Lt6bzUDjjg8tKX8gGmyel4ybsfcTj0CQlnbjngox0J/d8Iacm/8zJdTinxCm2CoJE2RyXwZQySzLKQKXNdylUj3e54YtuLUYzRDZ6EcZDLzTjhPARm8D5clWT13+9GF4edNnc83xn/HzLpN8o13zLfx5CpvlC/rNKojn+49ojfymlidHBx2IVzAe0XvO/6hPPiU1VuoadDMqRdl5Q8DybcZmZ6DjJzLvYpEz0z8ZU6ny6G6AwuefyULjVbduRCQ52z+3IBinoxGJqM9DdVmRVAjpS46r55zgWJkhps7MlBvA1nYvgSkbWL2NvEoRW4jmU97iSg46iCfXLiUDhMTBVAfK8IcN7RHwaf5mUeDQ3DH3pv8XMLy8LaM9aypD9J4I30Wd1HSfvezu/d9D9hc4vL0xjGElO2cEIfQLDwKPSpflnPlxFbq1p7DBT8hTvWEnCb/XvIs3m4fI5wkRI+WOkjdw4uRlHa8fDP+Qos2f8q3GF5ow1k2A6u81nr2/j+RuNxe82mXkdacwbIHSrZvNQxO6DS3pbKGMXZzCziK1LYK7Q5Dk12KmtV2Urd8QPMxDLyeLsZyUAGwnggZZ3RWm7lVx36e1dSxLxBnDS6vlseelD5aUN8oflKI58L5n3/Sjd80ZhDXhE3dr2o7T9qO2Nwl3qvuSN2qGj+9Lp81duGAleuTOXiDXvm6Y7wMzX35nDnqIavp/3C2kfLoyBWzNTR36pGTKQgJVnJNqpTLKA1gTPebrclyh1F+S5/vfKI3CB2PL3/3Yps0tJtbtP374UIyjQdI1ZQfjEeBYaWO1hHIfSi0ykhPI4IIfAP/Cs/k6CYBZmfWyYvXCNCLJSxtvEmRcaIBQFP1H1xln0gC1FwDBjtvSUOdl99EBcSEfIj6E6cBUjvEGk2thLX+dNKfDOwnfIpO9+z5vSlyggTdPxD7qfWjsZLEu/ds3U+HlKP3xWPMuEF81FKr1kdGmgtha8s5u/dapIsYyMyvcJb8Xv0g3MgGlQbx6ASHErs+pl7HaVNoFYJ00/XpJ4gBoKMjlZ8kR4oxAOAxNrNAtDLlymeOM/9UFpqUNrnL7Wgqs81d/X2AzoTM1fvHhzJh6dPn+1u2xLoEXeyU0U0X6Udv6KI9nOEi9Kx0CeKF9Xx6m4BDC39gSqcKBWTp+/quiFAJc2TgSvp4dYPY8Opv3Ei4itNZ+zfupTa0eVzGv+NDzRPtopnlMurqfH/r2p7ZFv4W3rIhTx0ipJvR7imNZWEVmvItKAvv0lKVufQtjc1iadD+Q+pUPy0GTfFybjGoCQSjYpXA8XApFc4pFuLolHBqe4xGN+qU48hrcjGu3DaLjhNtQmzhfrtgVR4DcUQo4pbYXQ/RJCD868+cJYPHPoSiiWi1F7o7DtywziIRanhnP8Qv9eRuxs+XQTPm2s4kZZDK55bbn1/eLWW5Nh4+TJA3GXKTieEyngEjLc+qBoDXDHA5c18Br7zW+lzBrdc0u6uhu6xPI93CgB55jWVr5t5dtWvm3tpdVhGlNZW+SjIPngbgZq0IMloMZbWVXwgy5tXJyoEVQDp/45sBoHC7Ea9tS2AmEL1tiCNb5IsAYw3PuN1gBW9VDtTyUu14TXIEHMgA2kDAdi4610INeNaxsni+8Cs7Gi+nzoRlwsC7OAZb9ro7JWh3DNa6tE3D+rcll7Ep/6ME76VKZnyceNB1e3SA+J3SXZknIQngB5ngYX/WUXTj1UbQvfawN4JQn7pUnSZVEhOODeR/jPsrgQEsMMDCmJYYYPOMWwca1aDPOUHoA7uCE45C7E57LokK3ovMei8+HZU18at18SIEIcG/7XCRHBw1yHEdky7GYM21zIjTJ4nBPbsu37xba3Fs/W4tn6FBfKxmVALSQYGdVSMmUYe+A0ZRjXspWMnwfZQnGB5aAtG+eGdM1rK5S3QnkrlB+MUP7ShO+ySBygieZIHLibkThZGrQvHFCc87OXP1ZAcfDSxoX/GkFxcOqfAYqzEIhjT2wrvLZAnC0Q54sE4gDrvd9AHGBVD9VoJjG7NiAOyWEG4iBlOIA4sN5VQBy4tnGS+K5tWDpSy0FpYOHu2IZtAKSxZrVVAu7agvXCi3jJQwBPgBW6uu17cAPrE59N5SiRS9qf/ExdUgff0qJVudcW5UoS60uTTMsCW3DAvY/sbFgK2EJijYEtJbHGyAenWDOuVYs15f+4VW/wwSZ4gxsCW+5CmJnAllpnrGtOW1F2j5yxB/cc2LLl9ssDW4hjw/86gS14mOuALVuG3Yxhmwu5QeaHc1pbpr21P7b2x9ZjdsuSahmYCYkphpmUDAuGATgNC4aZbOXUPXDRGfu4QTLSNautiNyKyK2I3BptaxKFjUAficzSfprFidz7cxZnXh3oA+5t471tutcUl78G8lrQTWIGO+1Ee1CbsTyoyqNCezFfRVVV26KyYHWRe37LnjVFQ1ztNLOm3sGssWUZft06ZYQxLRy7kYjAFcXbbyYhms8Nzop2y43iySSO2qrJVtVhbXQ2cY/P4B3VDbHMu7TSav/aXGNdT6/doUQir2xWZS5eRx2JWtUULqdZ4Q2NTyj+by0uyziiGDsuAbFUj28eyn1GQRLDSaSb4FxCN9r1H8vWks/6QaIAUMs+itiV5Z9SqJeln6T/jRMftOTmiDJ7e25FXy1OcjWEWcVEtwxqcxmUPvL1cBM3i6rBoBg8h6OCDtiJR5RSgTxJ1fXb1gHuxFI1JkALgsTxM5kgTc1WIih2n9/m+V8GUUJ79EAP+2c718FFBHPlp9d12PVZvblGsveRdmxxYN/gFRzQH87baISWIvpVHIMuI8dAdwvd1hHfzYUvx94szFqam2SXHoioIAwFEKgXRKkyOXrRyIuiOBNDOGUwpI+6fyKzWRKl4qfz87fiqPtMPHoeR+MwGGW7CDdF9tTboQ+O4qwvJ9Ns3tvpRWjqdsRbL03FYBwnI/kt7NhAZLEYeenI89VHo4KlTB/mePQVveh7GE6JVS+Be6+9earnmMgLL/FDmerWzPiqHPfq7LN8ZyqaIoTln8TPaKgrKeaIS3JL7IdGL3HH7rOq6QSpAHpCeuhA+1+RE0E9DXwmBloPuaATtGXx95jFMyOu0ugaGJEXMuN/lfk0ROoVox3OxcsXjs70xEtZiwGGVeDaG8GplmI5m6GPwdo/aGXsC7O81uUbMjQxdX15jWwWvncpZGq8KoUsjqSIEzGB7TAE2yae7wPH+WZywkUIYvR3yemdqxd1Apln+EBP/MYebn0sKk83nKi2IYzHcXIh2+x+aI/iaBwkE09nnQWp0McUkukmHuxTOGeFl2Io6VSOIJ7oa7oA6yW3aWaRH0dIGysLf/WX25NM4qeKKeSOZOu+zWAIX7LfGbMgl3+OPdVLv24UT2Xa/3Mmk/kyfm6LKG7dzc2CchU/t3uiD4z13i9lazE/vrGfm/6qd3crNEWlv5ti5bfn8L6hwrTWAujLpjiXXej4m/Kh894FEfjB2un7AEk3k0nijeNk0rwUOg3LZt1msR/lcqcZPlDOc4+ZzO3419X1vY/0j+V87sy3Grje3dyr7HvH+zaDay2vKvECLmUhbryBuOUQ94VDrMc9W+mYJWpYwTP7pZ7pzyr/m7t1H7TA/9JMjWrHLhyvbHS56IjjTY5D/hZ+r5bUlF/whUrqu0bx4B7YFsjG2ReN+AsRzcPmMPeYmUg/uLUwkWlQ7Pkz2ns0KJo4RPQDLqNCXRNni3wiehiFbaG3tMR7KadBdIG/XXnhbEMix/eNken1/RKYWU5XW4Z2TxlazmdW4Gq4wu0RftNeEKXBxSXcFaTpjDgb7v0H3HunLYXgFnucNo/TVs+ajOwXmSWBvJIpMDJ8SjzHp8RLeko810+5zS2E680YjSg/QHHOeRh7Phb/9CLBb+8IDALKyJ/GQZQBsgwTpOAu9aEERgy95EKqUVLCOwJoEIKAQTQKZz7mVYVBpKHVWPnTjLjcVbU/c53tJOI8gVltXuN3sn85zZIgumhcNyMvs+rIOL3r1FtrXVZMvq0c4w7Tb+sTbz3fD+DVXvjWWCbkNkuklv5eIw9OxSgMoOItPibi0Qgq4K7VPWct8ypyYLXUVhevSYnv3zy1VH+W4iydnPfVl1lozp2nXpJF1NmQ/gW3UPLtUtyZn27rh93s+S3dJl5GmbxgHMVZ/oibN18bB0JlN116wIVhAX1WRyFwI33BExGB8QYv8lsiGKsHWpUjDqWMxARMMennmHIesiNOI2tY5OnwGAE7ZCQQMHIxS4C1pwxYB/R6KvwgxXevpB3bxE3z/f/ZexfltnE1XfRVsL1rptOrJFl2nOtMT5fbSXe7OxeP7XSvWZMcGyIhCW2K1BCkHa1UqvZDnAc4z3Ie5TzJqf8HQIJ3UJYlxeaeXb1iEQBBXL7//v/HtkxuprP6FEsd3IrQuM3VVRPUZ+IXFp1aMJwPBGDU7akBmGY2MIco+v4PjIvbmMKlVOxU2VpaAYPWhbWChdd4iwV4NKpbJZohQOdw19Z8gqNowbWs5ZiHIiIRn0FAgAgInAU3hpelIbdEOFT3oFECFNt0x9ciyNZdYWshdvNocxKIDm62B26s0mQ0cjNT6gY3fUjRsSRHYw6Q97VMoKv/igsnuGZA+s+wB/mH6lHmfukGMwx5c9Neo0U5iuUkxyyK/UQFQxFSrw8JmcP4NcNmsjCCRKrA9xb/RuYhm/F4Vmye1p9ARyB0WZ3RRXIhj87+IEEczePlDBV3gG5Ldz0UgkVHcSiCW49ywsITdAa9LTtlrC9wjmkdjSgo7tnNlPlGMRLkUy8P0efhJQH5YNcR15ewT1NGXSZF3b/3jxLnpj5W7ahCIdWp8OGpc5Ts/rWXGzSMfdAYVeZfshg4GQIHf8c+R321Uy3H9NnnZI+/3hEsS2TAa25Qjd6O3oJSnUSiD2lLXXpKbQQ8C56APOPCUykDeKPsiYr99EzleCEslhJ5bMakl2NHwixJWJYwNJQKWRkR2/0iicfX3WkgolvTtL4cpUjYfoXfMcNMA42rIHE4bobAMZ/RCC3j6esVJSzRq6bnFUhXKRACkRLxHIrsCfLb2ft3+MtWkiqtVsevzelQi1SiZIFa6FoNVaD+18AJZlKde29pZqJt6cjjNpFHhJEtI4+9DPnzqHMlEnAxiGGPKEIpv4So68hUNoHPXHT0cjl6mRCdlRFNESmfCGtaqEbry57l6uokH6VqU66f1iN57Jp5BQskjv8yUTmDxkimD9Hq6zw7BjSsTEEN8AfiGgYchow6Eb9GiW0cBjNw0QggHjGSL9wO82Fn89sSm18r6JEHBM98Brg7U+AWmQI1bC2Vb71CV18NiVpRXw+IiWtrMyAOiKqC6i1SFp5pnXyi2oc/JGIWFPim54b68TshByd0HKnLJL90i9Bw/fp4uQSHmVuNs1i3Zr5D6A6hO4RuZ9+QVpJdmVw8ULkoqpU+CYKrjqr2e653IWPE8QwSbJ8ywf8JiKvdGGRz6QInB67mgZO61fVjUScMhEw/gdqsAq5/9Ms87Maxhy1DyZpru23uw8gjDi8HH1V8+feSHHz08QuSV46YF/gTHCMw8yeXpee7IzIxZ8xdtrZ9/QIvlbFhJciM37QUHhd63jUKf+7T2OURXmntV3vL4t/4DXC+LuSGXEC3na+rQuUWO796J2v8tjXhdL4ERKXDNaiei7WUsr9mYtRYOONCwFKdJhvyRRPknf+Ne6dx82WIPVdUI0KD+6AIxLdQgCjSEEf9EfeAU7anCqAPSfvp3wuhqh98/j8xI+c5lFXdSNqtQBOU/gSuacMgmUOsva1TRP4TVHmJ357u5NKISoVeKI3lUYDvyr9kzudoHv8GoN1+vTuIvz3EN881ji7UupshL6sB8yX2ugP1rQV1A4At1DHlkcUFhHam1J+wJpA+wlbL4rRW12wRSr8LQFeuD38SUwg9P+4E4/HHHZ3MGbLv8QhGDXwnUaZvAdCvNDtTBVzjorTGMdkrD2LyV+u8TK2OXEeqvnVStdx2P2BqtRRhwvDxDREmfHedoDGltaWt8HFTTSs5RnUq0mzDtanrQyaCOHQYOESB30Em+NzCz6XQH/RNsbBxkSl0veK+lZdRoWMEkabRBaLMMv31DzjCcnO3zlFa6NkqgWuht20m1mLHFmlcC51V+G6ycMutWTqKw+egcL+Qt+9WgwGEXYA/wJInabJUSTS8tKvPFVu8XfCi2xVFy0515XSqCChzbk4YSNZFttLHk29v0iuis6fqveBMil5fVXQ237CVCOgEs4HjBbE79mjIBnTOB1pwwYUdKNLV3NAQH7e0GG1+J5sVjJVZdeGLy9Lonod8MmGh9OINGcEmcGhr8uliQ4xjmdEr/ElPNBvpoDKnO6mHr4p3Acaahd9BzN+E+vyf+EbpnidFyptpAI7CxtMt4SHWZPMvTELuXIKYNfb+vSL6nKU7u0LDbxOcy3RoNol3cXobR8EK6N6uSS6X8sYSmaH++D1BQ4V0jXLQ7hd5apuS+yJ8JmlEq+FT56wtT+ir/JYx8m82Yy6nEeuB6k26DrhqEKkpkZ7ulPhQ7hvlEHID9fVGLPGN3xJQTOMh9GLezUuT0S1tMGfplmwV7ukswtsBKRW4t12T7HDPDvdsa98chowsgpiIOGQ/ymAtiqJXSWGbygzJUlVUkxrZFHgq8iP/zCA7izDbPFxUu7fKC2uTefbIrF0F0Yzd1ZPcPEhWIPk2T/l+qR7ul0ahLuJAMsTK47WOIU6aVNuqseF3GM439+iCwOsxagp2d0Deg10YtuoS/r4kHqPKF+mjj0F7aFqmEwiKl2Z2F6IJFJAJVWtaoSNGas2oTyfMJdecwjA8/OiLeJToMLSvqlij9XnrSNGmFB3yvNgoOioZfiVMbRHRkKd9W3jpCjKxXZNcJcN/D7DYIrYgr8/YZZ9lWtp+wtU1mH37JT2qalLiKdHtSdoeWHj5sITZlwZiIzxApEPIqFc/o/TtS1uoVoykQWLUl9XfZZSCEdCQ67FFpudvQJZYgfm1RWHKyhO0Lq5fv9uQepYqXNn4IZtH0zqz5Lcw/079ky7WoAzXb2kYLA5ZaytME2ZiR4FOpDJrAY5XzPEpxzeq5OgBrGD/XEsJmM6d+zHw/wGRzZCegNdmyHL2xFGsHuqzrV/KBYFSlnPmEjcOpaebE/gO9/g2GRsfENufsW+WAvMyJs8iqK3LClpHW1oaRks+YuN4bGMr3cZ5d3RkeTqiTaq1GqEyCaJGS5Q018icxWECyd4rSMqpapm6pHwnSrmYKJAp4JEUTPg181FqGJD3kIfumnpc5uxRblkyv5jhhPmDSVQuO9KwUY1QEVdFPW04KKLUa5QcR4G7QNtWs8am7FRtHMpstDhbOfEHqNlpC7UJYjZZcbUWJVCxU8hNJ7WHZJZpAtkRDKyVCcnAk8TMLS057VsrmHa/lHA+Vs41JSJInb9NKoLEft9SCjlls+C6WggpUJF0KopinBvp20bMCWZMEObxCVcOj4UFJXRCOZIx+AmyNOYpnLNwvPXlM9o6opK+svTc3M37y1/VyqmohLldk5/R7SSLjFfPNnLoNt5I2zjvTrJYntzZOi0hfutA4hTzpRO6gbnzuUwwHUm3Jmmhr3djKhVcqj2bKs9huZPTL1BJMqE6Jd1kVXjtAsXBUz4JRAbbdkcgvh0CUXs+tsG2Yefk1PgJm8fcGn+nb2D2HcVYnmI0VUUsiCrWJnBLy3cLg3dtj9Sk/be/Uc/729+Mdh/9kE1o6HpMCFWmm4fkkgoROFJ6UPHJl+RR8qM/6RH9B3N7H31IvGo+NP5m7vcDcoSxWKqi7Q1VpYXIxx1MSM0+7sA0kqnPYrC3cw9SLsq8kn3BXaYlnNLJjTnz1pnJYxtp2Gbcetdq0M+7mK7dnn87M37j9DdPMayDi7dz+h3BMwje6mz3diZ7gwXSBaIxXWqFquzQdQ2JJe2bybCa2ukT31kcrUcmIQU7/eSjH00ZVvgBGqaCe7GN4ZMr9WrG/NRRRlojk7t+9HVf8A02DTJQjDcV/YIbqNf50f/on4M2bu5Rh5n+AVmFHkHVnAxH7kFa2o/+5cmHc7IEV3EJ5eIjRh80nduUhSgP/7M4khzIcl4Da3cWuL2PwBYpwmxcA7Zouh1Rak2UrBwB7Oz/plxub/hHWJewP46lHctE9Ww6wzJnso++YOE1iDDBbB7rOBSXj8dkxKIbpspNObKkBRrMXCZ4mLGkvvzoQ2h2Wr0OVI+uCxkTk99S65vKfJHY5WY0vJLFgrIiGvitwfuSWJbsCzw2jggVfS6Qypn+0Jjen48Naii/XOTd6z76j6r9G76XkTd6qhit7vfR2frfYJRkOT/6ymHCZaGyefHQZDzdhU9nHGjrQhrYgnBCZmw2YqGY8jm856OfRpvOAhfUnfDuMIgnU6m91bE4HVndeCjO+vwttslbwcbNYpvm+xC9K9buVJHRoaXPl/GhMF0nWnpM2DlKZGjsLLimXr2TxAkLISMoSH9/+5sIxtqw/be/YSJfSSqTMb8TH/1LRRsvypR/UUAuM8t12SM3U+5MieATn3oqkHNEnSvYZIzVzHACN0F4NfaCG/LonM3mQUi976WrBfhyGPIkqCl1kGeyIwWhMi9rwstCeKes3859lFgx1fGICllbGbO5knkczgPBZDwpOJBH0oVGVSkdLT76l7+8XlJ4RKdDDirfJBMMrp8i8jq5lhSjVQYZYH0Wah2AX4i4J3Nn6QUDOIGdE5LUXip2pnybIBMsagVEyZYppqmwbDwSzBvjhBiwU/PpQiiKr70hHjDdTl959xbL5T1Z1u7Acnu/lS0SH23cVbZoup2025ptWHtGnTYeKBaOJ+UtO4eSDaDyauyAS+fSWbcPytKuJ00T3zyOtsi0s32T74hAayKwhL+Jvq9N7iaqXYO3iZZsrJ1NSjo8aMxfOov+LUoAJGMsnct/ow4c+gitMQubXK5VuG/kJ7952G3jvbF9s++IRoZoaHS/te+GGrnBdUMrgOw9N5I+0mMjSZSmHDRm9Ar+4lEuY3tOn/1wScZWJEIwEHE5RwZ1BtaX+j0H4K3dGNSENw53dl4M2zLbDpzbgvMS+eFTnl7/mJx3S3ONmmiDtUZtis4kX2+taZNWPhm6yy/fQktU2Oq7UhWlL2ipvzcPzHaCfE4dvi2waae835bZdiDfFuQ3obrX6pxmzb3al2bFvdmwQ+RtRuTSTOty9zanRFkyp3122puHvzbJ7bdt7h10t4Xu5tzzybi1SeiTwzBjEcUC5rI5+ONW8dRmbnrd/ztBLmGIS5U2LFXRyXxhkoH+QcZMXgLdQKKRZiLvQHtToL15z1kbJU4zf7++tPatCUjOG3ZbOGY7391tme3D9Ny1oAUWue+9OJyzcPevYFRjcJWN0NDax5YFa6v6taqq+ek+OYvnLCRncigy4xP5AuyJzqJGcntJGmRchHLnXCUhQKPiyx0R4babWOvxGY/0OP8Ts3CxU9KR+xGbsHCntzOjn/kMatw8GZrDBOOxYPbjWPLIh9KNOhjr1ba+bep9Unu1g8dzzsKIy5dh/ItovJX7fXUO4D72rw/62A94jRkTgk7YEkOonjCIiNFHt/jZx74LX8aEDtE5PDnGwFNyQwVR3caxB0Vw/SCCk6K+dxQEHqPgRqsKEcFBkKwgOCbjlcPDIYlK7EXGYtEwpLBrPGKzNl/2WzA6VVspwakS+3+WEJZw2yvDz8Iy30XdqNyNlui5AqDbHwgYV3/CQJ31emNhqqiYcteFb1HbWmFCVIAmddkAaRlEU7YKSuSDqmrOoP6tBzaM2wb/8DELle5YJFpppZuInSsWkUdsMBmQs8c98svRWY+c7qOr/un+neLeupi89DzKxcMr0s4s91sw0ra4DvjuFvgqFou7ZUcoAbjhi+IHvJXUkfgxhC4C4YL4FBUainR/SgUZQdBoyKgzbbe3y0Ngh8d3iMeJP0YpIttxortf/gpGjbZBBeLyeQHElS2iHMTlQwBxHeoDscejIMR/BKGMCWZuA74PyCGqLeRhTlXehkFpDUyrXKvbUYEm3hPwV31Vh793i78ZbK1AVtiOJJJOqs466PzmobNgdcsxs7XCOZjN8hgIKv6/8OZGlHtFAf2URSFn15iKAFok0ZMYqom2vkms4A7jOYmYM4ePudMEjPcN+fT6dch3F8i3tGjdwdEdwtGEVQrWLdm4XWStYHXLzVIKwrBVAcQO4dcqYZz6DvNEC2Aih/4iEcVVapkZd12PyVTSibiOHl1j7nMxlfXQ/AAlft0Xn4uIhlHSBxWz9wv5FE/cId96eb4O1O4K1CQSlcNao7sTOjgl2EVEFMwxYiD2fYgJyLFArVHSCybNRhjF5/WxcRmzpx6U5NH3ggmkcww5EzrVVz1a9oiYBjfZT1MMosyxJXpSUob/jZxvA/u+EWvPb+lWdtC7nXaeN8GkM/WsGLsH6swvZe9pC7hzGgvWyJZiqwJbegK/VrCl+MykDE1MKaRWAuxW3k9wSGfMJR6FbPFRkBTvvc+sJi5zx2luj3YRlNntN6XTLW4l3yuhblW4GQaTUJ1qK2Y16VDGsBoPq9ST2miom4JTasgdSzb2nuFkulwdUm5WG3mitqLTSq4RyNLjvxIsk7xWIxMomxW4wFP8uYINlA+BD5RktFHaVmyeLtSX6CLRZehmykIGeQdA7TC/d9ZlxfN2qNZpGu8HUClguR1Mobry0PMsbSfU84oO2sqA4nnlXtqJDQWS8lrJqwV/7W/bqmLnfK2Wr7OIdDh1v3AqQY6VWkUgq/XiFpYR6R696wS+D3nMrnm06M9D5kyZc9UIhtiqrxNEGUNk3byhlfbDzrXKQSS2vJmyaIr6uCvmy6Ii19TjrixVLyKZUt10675fzttn+Gm/BaMz2dM6Gq+4wgR3qEPRTcuwR8aedELs6jC3HLZqQFjCxvLMoqwtdCu4lEM0waVstTK4VMPdR7g83T/Hj2uJlufFBe7QskPLDi0NtJSosQRaiuBCvUwd/1LrBcAgSNJCBH2jed52Aefx7Ow9yTSpioDONkx8q2Uhu4wsva6UF5zOjCwXUOZ1zO3dU8oXYOUHHSaZ2TUjs3GSE6AxQ0/1PHXyglXOF26kHr8v0xW0uJ7GBTw7e1+RuQafkSP9PeSUUdcuf4E8IVXpC+S/MXuBAslVXHhOZwMhguVT/nKfR32f3WRvZOZCHvs84tTj/2SoT8psd0MMb6YtXkcvmEwwyS8UTz7ygtgde1gWUhVYpD6RNyZagDnumrss3JJ7m2FxVsQtjNiE+xfXLAQHayX15+/ZT9AGccxsB6uDlbfoGDxZMDYQ2pfR688UIvH0WrhsTJE6axWEiCj3PSZEP2JhSKHSWj+JUEkOpipL6l4EODHqwaFCUnfhBlCprDjz1/CUyKegrYRvKDtCWY7SmLD+18AJZvC6WLCLMXNDOptfeNSfxMDuWGxqaT/JNOpz8t/Zb/lky1TW3Y41YLYNUFtN8Z7A9Z8hj9g3jdcWWYAzvNbul+yJaIjtVTG91XCvonvrYT6J8vXzGK+rHG4Nz2Wk+8qt08remx+4LcdXtuR3gh2ZCylTaPUxKVlTltwOM7YaM9aZVBZEuGr0wByxeLAaECQfICvyYbCZ7h2MWAqO28h/VM/rngDINy8j6symNHKmxRsvc91lLz0IDbkEpyqFYXandbPqbKbYAtSN2aB4cG7wOxBYixTKfDhCbol9MXPMVbNkT+sFzdWLa7YiWfVB3BJAtJjgPUHGb5+1skj02SSO7ZZrecoVctg2h7WZnibkStVQ9hzlGmdP3h9gJkygNxYsxERh1HWZiz+9endGzv9+ntaglziGzNm17Azqu+DGZ6GY8rlW6yglTzRlC7RHRuECfW0DIlhE4jnmgzIUgR2WWwBZ0/YmOsA1yYp1mNZ6rh3CbQnCScTJwEYd2kVBSCds9+p6F/qLOa0rKHsThFcsFP2r637SWiY7NjoXUh5nnpWZ/f6Uw5Lf/zDaIii5UJIE2UopRzI39aT9IBi5hAKkl5iE6VLXI72UMAW2LwwomKBrrbRhi55sG4QuC1U/l4fSTHapA0jDwCMiCKNV+9PWnfd0aatwDWutVsbO5+NqJ8zIJjmnE+5jmS61DIYjgGy1YxgS9no7M+7LAP69zAx0xVfLWRTTWqrXEzCWw0i189gfGpkE9obDYdW8cDdtJ/VOnzAy5sxz8bCA2/doQR5dcvcSZJfLiEceu/x+UGvNwJ1X3hPyD+wGxoZ0bsnpsp3fGUzGuAZQRUI4zHeBAD+6pMK5/B7mCL2SX+EP/FnZ16onTYVjzFr+Bb1h1vZ1fN+l81uq6swqnG6MG5M42bRwuKnoXulq86f20qr2sil3r8ma60xvm8S15oL746DFhM1et07VYIybHLudr3lzml6Xnt4dY6U/NVVOLjkuKy+GYHzG7fgGa7cfg2wlH1jJZhiNzyTNVbxGr+xRqoK6Pc9wdT3IUOAlXQtKab/KC07Tn8rzg5uPqzwMyrgAHSJTIP9J4QMy4dfMJ4i8A3KKVSUFuTwYDi+1T5zuQr2QUXcBjIUw56THopEc5t8y1YzTZrNYoEqdfYYzyiNvoTO9khEbBzLmMElMMfeow1wI+CHaxE7+ikMuXC519CEDeMZYHgxYxNJBXBAXzPTeAsIDQFTDBJPUJwHUBBoxFMBolHgIkIjP2Ma5lDU5jRqvV0WMk925GMGLbXVKycFMuYGOjt2eji1JalZDaWr2tCM2pmC7RpJi4f1QJoDufknvdYMDRClZCtksuK4mS0nG82qypD0issSnlEQBQPNIaLy+Yov+NfViRuaUh6KFC4X5zatGa3PsUulynYSiCZ1Pcftuj863uMF+0FeQVoM4NfPsEGdDiGPrO5GLxXTN+466o7rrDiQzGOOtz133akeLUqBCB/oKlEKH7BqI0rwuTLl0ptpfvsg8wzek7epK/naYZLrHd+zi/WEXqza0Q+6tU0zUVeqt4P/g35XIeoqP69USMmuvDL0EpYC2jFowg6EBzKqiatpCprA0wRf7VDCPYHuNfZlCuCaP0YNB6U2oGORhWlbTkJy1jnR8U6QjeVEdDanZ3I6MbEgAsPDwsVA57I5i76q13kFFY8xiL+Jzj/UTOO8jnPddBkG7qjZjQR+hu+WpQAnnj3Jn0v73P/K6BoPcAFpCdvrYAzU1qLbROgT0LJ6D9XNv2BsOh/BSAX+i8hrG7+iNdahH1c51UL8iqM8viR97XpqiIBv1yGbzaNFXTdVzy2+FS5/qfVYjZ9gekaUIRndUvsmj8hUQPSEFGq62n2Rn6Jdqwid+EBqrW0m+ccXKRqhU4rWS+W5g6pWkN0Nv8SvtyS02FwVqmbnFUL+6WTpUFa1/O3v/TlLhnrQ9JwbiGYso2oFBJmSf51ynimMRGKNlVBVUAMbXDshrbaXGuYhcNyk/BtcshMWJmD8gx2PiM44X8DJteEn8IPPDRRR5l1g4U39QD78v+9kyCSUEmmFPhsOPgmiK7xUs6hXHjOgVEwQOAXOZr+VhoLuY/QUFvMTSvjcckhmb0NECNgDyDTAhZA959cDOHoSRlLVTNzMj8c2N3DzU2voLxeWAqX8syzii8J1wRyGGsXWcz5olbYCGC9wpa7m6/g53jNcDoqYVjJflCen4rodzUu6pYgR1FXWVAOJoJfqQ3VQZ0sJHsEEpcitNiHbTqOXNEq1IPXc2IGcMuASDPdNK/yu2kO3gLfJ72nEh2EdyZB0jsu2MiJY+LDmRTgfUEZhOB9QdlY4XseFFVuGflZBxJKJAOKMp46FWgiT0vpTKr4YTUi5eLdggcPWy4oHAMaWFKUjn3UFPBfY56o8oVFBSa2FYeZSJx5obMvibGYVCBaB2UvRYrj2MCz5w+C5gnyJyCVcPAykvAanwX3MaCia5KjUryGrNqCsjAsFZAlRYMlhNRWhClMMl6MbeKo2YHBOuJ/6L+44XuyxVmKEeDaeoZvMT92m4SBRjIUNFlYjncyxLIgNLzTPW8Vor4rXqCRIcwiJFONTstjZDhupgk0cqBBQe7g2HZkzmsmFuV2yB644AjnSOfj6WY+wNh1/1+EVrPxzV5EQJfWLl2buEy3fZAy2lPPDKpcc897IhXoyyKM0k8nUHxjLCNNWfuNRA6cyLUUNdS66JiqcyedIClU2mMaaeYHnChvtnnU+zDsw6znhL2B3qL96PEfDaMD5A0DTz01u2ax+Ocl8fz52vn1bp3nk3/PZ9dNJZh69nE2eIXp635M00cWmZvcJwFP2uL/o4SiGNBVImiMavcRuV+SxSdVEhfLWM1VJGQMPcBzGdkrFN+Zspg6QrTLA090XIxvwzskNj7kHaaPlSzGrhxKEIwktJSqVVTeZr/hzJzAvkjyxnpEjFA1c5pS/0+IxHy2e6MPgYYBogY7Zv0F1yQoUgl0Yg/0DvWMKgJyhFhcV+1mb0kMkzqnJpDDNJPvBU2X74z3jwhPpMLZKNFuqWEDkaGKqpA3JE5Eyz1litVwVNKKauSSO7ZV9pZJYqUXxFfX6Lt4v+ifwC86Pk6tl+1Ps5/R+kFZg1BS8k4KjcmdI9U/d8HrJrHsQiv888Sr24K3dQn5r673t6dLXn0eEfn38bun9NuTvbe+v+ff/nxatfPr/5/Q/Gfv3HP2bvT88unv+dncXTf744++v4t1N6Rvc9X/w83Iv+8/2v4fj8l8OTx6dP/r73+/UT/seH+O3o3e/TP98d/v3X995TdvLT8PzDm+f+zU6WdUjXo6+YLpQT5nE4DwQePPY5upBLcoEQAoTOPqmI4Ub7nSC/w0HqOMSVcoi3EJh2vrY8DPIdX5fOcaLOUSbVySpzktScto4tXCNbqJithqwkt+QLNRu1+0XL/l/bsYmQOaQfTVkiqoD2sk+BVSwJ2rxii+9EwrvVRm6ieiB1+xIicDhGDCVkMKPu1JSmmo8M4kgrT7AyS6qfA6bxw+mbPvOdAPNGgTMZjk494kxpSB2k5Y/QyUwiS49cvrzskcv/Bf/5l8vv9fs15ZZ8qRP4IgpjJ9IF2TWB+3D6ppqf1FuxaoYuGdfkAB4C82oZXE9lbtDk0MlM7bCjHblda2QSQNtFqvtYEXWz2eCOwq2Rwhl04E6VH1LJnCNxy8QvZa1T5alTsio1y/wpcAR1uhTZud5W15GsjmSlhy7nfL6VKWHqp9rB7sr9DZrEh1Xmg8ntapOfQZtEMChf1OCuKVdgk1qhQk5SGSBj32X5RDANkgRoHEN6QzDuYmMoDNEkJUEnMtZEyICUTBBLcs2mjMI3wxWDCtpIb3LqdZiPYE7guwIqHDkMh/vw7vjvhM0DZ9rRgO2iAcjVtqcAgRNBgasoZHS2FKzKy9bEbnd4v3k2u4kStM4iIyMKs6Ccs1cXowrznHFFgF9VkCFV2L0EaPdUTliFpLlpYJkuyEmrlUIsEzrYM/Cxl7E8Krf4lKxQrBN5WXXLLhMMhzwp6A8Tg7VSGuNpGO1iRVrp04WLQ8kljnwJjjORMg6lS4YasstZ4gcGjTZKk7YsgLIjVOs3DqebUm1TtHyDMVT5G2DbV/gWHO4W/n6roqhZcxJktwYKMo2iObq4lcAFqhPVdYd/zwwPODXZc2XnyhNYpIaWGktzWGulo9bh9Xbk57VnMLLKP/mrtZudpD1llCdRAm6luNxi3h0vtXbZuTFuUGNAqZwrH/evucsCIf2s5L+LrlXJ72XeVIn/+lC102kUVGFaBWMD8nO24mwI7hY9ErKx9IUF8pswFSnFXFvufLkejdXLIhrFYjm8V2+YMZfTC1nWMeMEA+xhnReMxdh6DHNchNPbDIoDZOg5lqVZfkDob46H5ybDCy01rDFMZssYDZ3prUZWQ+QOQljjf2YzKI6QYSp891YjQn9zPOUzeCHR4VZD54bKvKUw6TIfNHA6ww0ix68eie8H5EhW4khw4vgVQYAAfKd9weDSg1YPkAl8r45fIRYU2IQSJyxGXzzZe7zv7D159nj/YG/f3d939g6ePR3T54/H+89ogTNu9wHQY/dDxWegoFL5IXVfkPVuvGYX3J/HJrw1zQ46EewEi4lup76rQTnvumAgMfaT+2w7P1lQpX5ihx6nMiPOd8x3v0urv6gZyfydSXEWjPaB3IC7qP97dPrzEXn8+PELGGFGo+/rN182AoUyFLyBEbKINY6KJcgqp4s3s3rCONjdzrfUu7XJp1VNM/VqfaQ8TJE698iMfsZ/lU+N+xGb4CLVFHWz9xZUk1k5W5vBej36hRN4nqrj1uRYlpvYyvlWTePWw7Oe4dvIH5JDqyyiKVtpZZ/6c5UKPgUfCae4ZBWrLFPKfR4BZMm/+/HcC6gr+lDic9KXbFjKqR6rxgqkVWOCjcn5h7PCBdIdUKtn9FFdgB89/3AGlVSjwAm8AXnvaweUnjI8hddMa5NdkeAqsojECVxG9od75JHCje+lbV0SUnjppRc4Sj2lLCIYEubCuWOq6hS8Rx1LI/2EnCiUrzrV7DNI5uLl7m4UiwEPEMf0zInLIsq9Glb6PBb9UybimdplhB05p9vy01Es0ElUDm1i3Af8iP5Rlu1N3nprvleN/4b5k2i62o+S63/hyaFLXvo21SPf4qvUa0wXpM1KP7JaJlSMv52YYo5TRlT2itjddL0Nn35NtilevyNFtdW1xEv6Rl08fe/gtsAYalS4KPIJzke3Lk4KYrA/nL4x7qqCkPSqYkBQPVel8Lj/FgTD/vGr8vfEPoeoh3RnkgIickVGDFYiQYaGV2ZvfOkLTfCD4tJCBWHbcOB7g+FgWEeKrbfz4dHndVNkmyJgMNTul/Ts1fquZYm4clrDv8p81fSDcgc1TZq1W5oTzLnOIXHkBbE79sAWc5ZIL+UEzsCzFaLleswdddDcxj9LLmTKkDf4SGWbd9fwrq+hrSfUCQtnFNYyqW8qRVF8w4+Vbk3ZS6nTNyjOWjGIuSosKsODPAhpk5z6gcmYQfVcOTMrZQh27W5lhcdM2fquS2CWG1TvOFM7v4cHCJuVm7V7jIXYLEts1Fzt1y6PGq41Nunu9NqTHWZua1Irxc7KXNzW7UGTmrndPyRZIywwl1sYgTOs+y6NXR5U2oVlxg1o0o9C6lyV2IOp63JlqMWGRDYkga/59QpbcXPHAXkXaI4GQr8SD6wkUYPUnIPwjrCEw9Aoos5UBu+nErEUKrfMgLwGfLRW0lttyIpvJRyvQ3jVObzpVM2zSWtvM9N7Bii4SORcXsEtYVAGOVy4RVR4BSztfsH/ubBUNSjlQiVc6Xi49oCVKCAsIAvbguKKEm1xM9qCmykgGPW84AZ09v8VxLKEBhWCT3xC/QAdVs0+VCRDzUMehElm69pMiPcV0QyOL3c6Vvqd+bFb6Vc2Aaby+LsJI9Yc+rYVQFo67U2j50bx8rbKH2MnUQU0h0xORbgEbrEaLJFHXwIqoZ8dUEJLbVvV8KbsMsEYax8aEJgmlEUmcEbDK1nZPQ+W+I6U7csNDMNgpszLDjfXi5trk5bhWKc8ZSt5eROoTV23HQdsO9EHzwFvFMOXFsV3nWAus3OVKveo65qYnYHsQ9fNHoYoqITpQ9fF0LDyc2T0NBxg5mEAP2VeUp+C4b5C6XoRDU7EEohWcxw2DmI1c7v3uLUpSEJgaQlJDsUdq87Tq4wNIh5FPPKY2O3rLjKKJPkrCNNGRSWibgbO0mazMuUPQFGySuU9tZFCOzXffzNF+rL+fhutX8X63ZWpwKP+JKYTtpSzbv1U7wdcnCUX6UhfvW1R9yVYsGJVnx5394s+HTYORWWIoxSAzZijNIF2qHPKZoEu2lKBNjLGrQFl9Net8tonY25OltwaOKvb1M1lS0zi/NpnSizpuumkxCXenQgHwINEaRmLFddi64B/zVKuXvCBgVm3VldKHJUqSvWCRg+1MpSHgiTqDxPhMcmvMV8bDlPxiYlga3Sv4jyrxymM0pGCLeZsq7b+7jneZv+YLZr+twGCa+R+rSCxLn1VDbJJHxUL/lUGFlnyrx9UOIWBXmYHqEfDtK8M8915wP0oL0D/dHRy8Cw9ZOS9XzPWnIVJU7B3a1t3B4d3BIe2msiKPD3tlJFy1y9GVHBHBaVZqyTrzu0adQ7NCGw10Y7x3CzKJofvtuqGXTllqW2odaou50dl53ZM6S+qVzvGlFxzSg6PCxhvMVrVWB0sb4pLbdi0b4FT3bJP2A7k3DDrqaBsBbB4HUXLGH5AQL+OSoX0fFAZeHH/yUZ/nJ+nJ8hWJm/XvYO5TcFc6T5lpIYKzg8qKeszaBNn/t2fr3/64/z8o0+Gw5f4/weQiK7f/w/9w/7g4Pnwo08wgTwXOtdsMoHvPtZaoey/5GGzhpsQxwdwUG5TtKUIiW5w46PobGGOms0P+kl7bYhKBygxPpkPS7Xe6BepGylYU66TWFI2nd/uF/1PTM/3FWpcighynWNWiMWc9RNJPuk0IIeJER2ayOqyl8ph8lJWpkXfghpfyQcKafktvDPZtb1Pd8mk7gcYvT05IK+SO3M7EdVlkJMbMsFYA455uWWl3hWbRLSnsn7Rj+Q4UhFvTAazYV1dzd/Juz2OozhkkLS9uoZJKUKhc045PqH2uRqdUlNIetJ0MjwTpDrMKFHqrwEx9BusMKNiUg8WMSw5l7vGD6u8eNkLLa9gxZWWaa9qLrVsABl2dBvzLstaC/oPDueEuguApGvObjp2ZNPQkt/eLQGXymndW3jZBFYslbGr+rJayDoFOSdzpe2kniqhJwEGGBPiwHQHmTJ+RJ2rGxoC3gWzOY24XOYeefX6zevz1zq/PPqTp98o2SjXEKtyvNZDQhQjgaO58at8Y3bgTqb6liBsI2Y/EzJWK1TdQpiqZb4KjJcNBuYIYlsuLBgbBcbgfQ2YePL+7LwWEZkv2a0OEbcSEXPHpbj/28rnVU/03sLmRhBxOdaPzUZwiq0qAUFqSIa5IbFXH/KY96fRzMvxdprFfUmSTIEem1BnQbCfzH/+6/nbN5UpIwGEVBdoJ3sIn8/nLALskuMkMiiIozdsRObgyOAyqFoB9XOjaRjEk6mRDTabqT3U2aB9+ZZxSCczpvzdoPRh4CfDImS6XMw9ukhV7+99fYaN0WTdw+SQQzHFew2gK0h0KffzSJ+LWhsgHjhLI+C/yykS7v7wsbH2y8ed//h39U3/8e9ymlDFg/adMRUL3/nh4w5mi/i4AwSSSeXFDx/lrP6i11T2+bhDRAiNdd59/LiBkxxCdbedYCYf7d6wg8lg7NEXAw8ofjT4S8i54Hj/YZWKs2oF7wfG3kEyzvaSeG2EP8JoS+xV69HgZabAV3GWkBaKuf049OQiCHQqKynPpuiwbI+p6GV7BLeKsm0py5nvlrU4Ho8JRVzTCawSBwtVl1XxmT1CVXeemgUwzb7mMLF4YE35iXsNj2vLGSB3U96/C/Veazddi4N0Z6xnbuLW3KfVZO8fNK6a75SzauY5m5NTAT5AlQgSsdk8CGm4kBvzIwqtwGvRiAiHQqlnKOPMofZGUhVb4hH8S1bSRvvBwAJuHY/P7QC2D03nUD0I/qFBd8Kvmd+nfSz71ae+22e+K2tyZbDW43N9urCLrPWjSmJjEW7ZJXdYPT5P6xiMqGCuzleVSkzFcUQGbgVzoMTQVqRd2UAmZFjDs4j6Lg3tIw/s9uvOUA1OmM6LctboVdtysvcI1ciRupPbWZYBwcUCg2pTOGWZPBXzpf6CTAJ9CrxeWbxXtqTuh9OiNK1jvTTCRIGqhqI7JTiyfXmb7qYE2CZStcP+t2a6qvZ4e9K2N87wHgHRltaFsczhpEuqyQCppZDomtO+HEY/iMO+VxqGqg4EhBPJHrrw2YfTN7WuJpnGSehpNKUqPzLq6YD9gtpwgGWqaeKWwqNpEANVxJwXV6xG69ZB2rK2APMs3RLVyo/I3ZkxclNvFiZbTbeDu9WYOkyUWYm544otmjPWSfGyD22lN6z5S9Eh1hBH63xir1VVc+TUpTQb+FgZGn9Bvl1505kCLmTqUdqydUPY0r6s5orc2RW+YoulcsWVTu5+XNgz9Wm/w0nceDyOug+3c2XNXEZD7V16HQ2FX+WFTJgMn5yeHULVhGvoI3VJ5OT1W7yNv/35uyrQLgawnJi+QjqeBj4kVZfGP9TROEyVeteXGnvIxurm9kCr5fZwaOVkBBWc2Zz5rszSntRll43YNQsXOCmH+kSVf1g0+c9vDwyU7MSdAoFy14H0Ey01wx0U3AkFb7r8rSh225KyGdBQnqiVoKHdS+tAQxfFyBwYuKchuw6uGCayMewMgqTuY2jhAvpfK4PctWkr5820PUBRsvrb5N7ZIcTGEOIWtU6MXfuRHHqetvtlrM7oBYocNjg8jpgTzKB6Oo2jaRDyfzL3f1mgE3gXXXB/HkeNYgU07cumUqowfigKFfCQJA+rZAqjVTbSzidqsgNyHpAJOEpNkRvBK0o9gd6u0t9VucVgnvXEyT4duacN+Gltz/ThhnkRI4OC73ixC4IA7JV+5f/ELFy0Vafkhmoj+Jj7cWdJq5Ijt5T4UzbF+wFob+DLjuWV2bjwk73ct5OBTORQIhA1fiwTgaixzzV6VvOWS3ZGui2aQIFK10UQQzaLRRCjgT4UKJeAqT4FEBwsMS6lfpbKzrQ1UHHsgttBxHxn0f+dLQq61+xinYTsGoYnbixvQxZ10dYxYkBtEuoCShxwj13I8igYFYkIOiDnUyVqCiKcYJ6WIlVr0CMzugCnh4hyn8RzeLz/5AkZLSKmRcPPcx4iL/qZTIM4FEr6zNIDw8lqQE6ZLNVC8d3SeysVQ6H1iI2DkMmxF4b36sHwBTkK/LHHnSiDaNUOlzP6+Q3zJ9F05+X+kydrr4iC35zg41LeTea9WCuMNxva6mb4QFF8I7htLb4aDOLuF2PP2wm0JgXQtUyrKICuZVpHAUp45iwxmNErAAweEe5T9JDnEA8E+DPyAgcfOnEYgoM8/KgCpEZhQF2HqqAiHg3I689coNtWyJwgdLk/EZrhBpih3K9N/1q2YCvNxlX6gq0WlZdFp8QR/kuz2HtLfHmgoHDb6pzpmmNQokN9cKfGi5JYgBpSuZhAEapwgGqoSAIGasFCt4JENBHlni7CyfTVthEHu5tcFqixxZxG/RwfKK+xBRKjRQJ5EwTiuVsrL36Yu43yomwjUvUQJM/s7vxymdZvfUXkji4p4ZRs95bhTt0MHyjqbARn5DFbjYSz63IhS0A1+Btm5BzZp0bQkQ0aJB2tvskcKENrI98sFTHoh8PCGfeVi8CCUCeCboZgE/sR90jI+jJHQie9WEovJbu1ZdBTO8V7ij1rl5EUEjQKSXozCpLRYeFGan1CcnVdUyfhBL4vbSNpS9RhMFfdZR7JzHXpjV4N6snhWoGe7FKNea/9Zsg7VA7SRK21yaxJdT3EC4XMYfwaENBYSTqh3O8AzQrQSrZiy/CsboYdnK0EztQVXw1eBHG0lCMB9by+6tunQgQOBwzsg5cDhKtqma0KU9AsDA5MagySjiE9Jcrlvho9UfvBOsyxdzJov7p3hktyGkv5IdziK+4pdm2J8mmgYehO3BZ8dqOwqtdXnBlz+1Fg4dHgsxt1Ynok6SrdlqycHdL+0qcBPBhGmNRPukHxWewBGwSODjoxT86pIcBKyqfnb0+g0dnpOXEZ6MDx28WAvNcHOmSEejd0Aayrf6WnWeJdRf6///N//7//T+BnbPcwsym9ZmQGIqjajw4iN+JJkEDckq4EVqd2bQDdwsOg3cTvKSZvCmBX6V+g+crdL+o03N73wFcYXup44JPkYbkXfdJC+ZxBUlYBUjiq5dAbKmUIbHjEwnetEoSKg5vA96Cw19ZDIdnfu3JPKLyg802wBBZbH4VXhl+CHPZHcliiD5f+i1yQiIbgZl7UxQ2WMVeWAow2DVUCjDZUYtKkCNpKTwXZvMOPTePHum2kS/Ju+XO2RdxZ5dTuKf+11Vi6UhNpGABgXegEBdaStewnQx0h+2e1sxc2lJFs0gW8TpeHjUUhaijfMUm04kypP5Euo4Kk3zUg7z03MwKIxjJq0u1lzKpCWmOpxwrtaRwFQJkc2FAwa6TyiJgGIfjRSR94XAwe+NJTXiYfVfdD+7SHbBwyMWWZWXWytZ3fWs0R2jLbh9VU7ylortsIYkCQRQ2O3MYsZd8dkHfsxmyifGWlaRN1yEEcuShAZq55M1aLKAjphPVjAUWa7XLhZ/uYoHsmn4CSsaJKtSDcl5kmIB0MHamsVWpm3wki0iG2LIeVk01etVSwZS53lV3F6DZrdnfpiOU7LmLBrCLKbzH1+4FTd5C3fRlUq0Oy7EVuBosbCphEw6tGo23Ssj8PA0gmI023hZ9LQsGTNsRoUxYRDia1YuN8QPg2YIi9sbPke+7qQievWsqeWTPR+3F9/0w+8ER+4MZv8sC4frc1VhbvpzJZFm8oJsAcUcGdNDNdwVxZchwgZyB2I0m3clNlSV8dv6sSMFz+en5+Iqt4zWIv4nMaRrtAVvpQo+QyiTfemru+Gs2PCjUORn8xB2TWeQh7GXEJIvLTrCaKTb/2doI5dfD82alrVGs4S9SFWEbLjrq1PIRcbrddT90c7jJkxLdlTrDt194O5IsuapFO34BmFOTj9KzxGbAdUUAgkyycnHxgt2RbQO8RcgWHJYfvFrCLl0Onpm1paLW4b+skHNZ21jbzftB0ZBOUw9oKmw7XNlVZke4oG2sDZ6jsMxa8YWJ1LTZedz6y9KJsSdEdS4PmqpjQevrFwjAIheU3zZgAGUUAxif/bt9Vlb8rfvmfU4a+TkAjIIO2I4ULoQvmjWPPoBGjIPAY9c1ya3KfmB/Pdl7+N/zxScI51KyuLdOGFxLKuUfSex76SlKgj8B/J9Pu6UUzFuFTs/2449W3B2OXqd1b2L8fUR+YkEtV1zaEwnzMd5I0PKq1VCjC6jfG0xfhuQywMSo+A89/5mdI0lZN0fVSXa04/Q6z22J25dJvF//XPM0HDUWbVxtgoH0z58dG0yC4suH0ZMuEv5N/lnN16bNyXg6ocuD3XTYDO6cqeSE7bY/Mb8tcqY/dprSvhTndk7uoDusmmIH0SK/UN02N+yOUIU3S5PSkBxj8qTzS0D2BNZN7dUevObspv6F/cHajX1pJy5PUWOkdVV1M68+3c1PNj75DMipf0IaIlk/sAV7WOyWXFlfXIiuNvltar152u5RS7I/3r6ppYBKgoK8U8Mt+ACdabq5QZtU8gZTiwUMsjpnerKWCWLbx5ldN7QHe/fXfduX42EioS69qei0TmBA/kj+BSods7lGHkXnIrnkQCw9T4Y75JA5ZQkIH0uFJuR/q/Qc3wSn1XUh3AAr0dxlAOGPhNXdYvf9PPEoOmNj9Yv5pGzGjhutnhkoKUBg/ljH9Z9nnlaEzhquI0aMa1So+ZCUQN+Kehx8Gh/RC/dpfj6Ig++6lxQ9z2RMUWbdSN/sty+h2q0co6FwrZpo7JyvY+lvql9uql1voiJNVsVAWlx4QTWZWRWWyq7kmYnMoL2TmC6v9s37ingeaVIPoOGNIZcoFFHMXp8naf9H7svO/R7LTS+ZyWOzVUCqN34MMzlpIllXSXzluT1hUDdq/sKgesX9hkQnXGbAmo4XpI99Bd0vozi/+Urjd4jqqr89sRwWvOjwoTjczVXBTHgex724GOiqwrnJFHzzQ9ZK/U9G6GffMo/IyxI5fVU+P+ocZ9PuyMwL3LiSTmqxFLJyHXCSEbhyy5N/zMFBW0VVCJKDdaJEBgAp5vhwtVeRmJWCqyLVazEwSzZbDZgeU69cg5L7eWOf+9X7biMotxeyaQMsOE1fA/CH+9UqZwTvCwzWzlxaBoHbKhV2Kzua7dA6VYXcq40DLIVh27svO1Uh8iM+zR/vQKQXksxmV0ZVwtpXdkftOMMNYTXMA7qtCRh4fM2fheEx7mHYIfh8QvPrQbDmQW0y8w/Ntx3M+8YMwabA64FY4uwLgdqjvMK8fMqqOSktFQ7Z/XtNwhE9BAhFVqgaM1MdmHlWnGxrnor86NL614iGzF3cMfnJDL+RWtkG96oned7Dbbgk7e80rg9LKcUJZzquhQtnb6tHiFAuxQTxABxffGPOWh4OlrPnfBH7VzvW+Q9iq+LWMEvLumbQVQGQpwllzZ6qbG9z4k5C6NZUXKvBV9WceXTDXGCeDsfJIvpKNyCujUe4IY0NBgMOErVPDkmRYnf+EGdmuMxNam6fSenCulfm5xGSMYfbBOKd3SCaLJUflFubW2AhUomFIseJzxGZipxCH9PXrV2s0rTgHdy0Om+iUwdH9MtNT4yzJIz8gap7f71TCceMwHSTfV0iuAsUaWJYLWu0nBc/7ibd3wRMKHstcwCkn2vfYNQMPMRHEoVOWTElmEQY3EqN/mnK9fJy1Qax+YT+iE8iTZ7iFSg62rHM6s2J/Pr6Y0ciZ7pRIriVAcA5rkvrWJJVn3QwAoIP8wd5+sf8J1G/2XUxGgJcdknCdywR7ODEypYKMGPPJLHAVMeO+w5DAzcMAfHBd8vqcTtDNJxiltZ9XghjFBV7OEm6ewTtzKl1isk++ncmWwXEz+p7qg3QuX2Mnzo+pJ2qQUT1GaMR/V9qIRiyiNUYhmOVAY4heEdtoFhHl3lPliITACE/yCkAJaRnZvBkRdWBp2vnbgUOdWlC1M96r08zl8G3KyPErbXNKQCkKiC6DnSzDYHWzNqdXOm1kLxsnDq3yU1/hLPXaZmdlzvcmCK9Y2LjIf2KzTHpXzeXg+VLDXLNQKPuKvCYD66yAhbmnM2uhok0OvAqiTo7DygMYCvOF/5WxhnKpW+psG2e+eXSvIEXfyOw72qTDtaoIU6nPFxImkSNMZ8sRJp3mLAhJrBP221MociqDRCSrzz5zqL80SUfIY+h2kLNbcvd3r2guzECwCMBMaDVz8km4H9ZK5+SMbA30PmjpprAdm0fkCnqyhTPtaEcu+K9IPup1Qru6ukG18INZcVUm8Vwe3IhOiHpSlf3WRWrgpG1ldT/qhIEQKT9KuL+JjLgrpxJOHArInW2fTjdZl7XAMVazWCqbbmGem7/9FTi1rdO9t2CVlhmoSfe7FDql8NcIUaXoNGEuMSG0CqXyTa0zdHPf8WKXXfj0mk+o8titkddhNz0jHQkMI+YQYa0k+XQgDEmbzWJMukecKfdcmOeAvMfBKHDg1O0Hvrcwe0F1sBmPIqUA0DplYO39UL7dlaOFzB+QN0FwFc9ltLbHZ1xVlJTJ2eiE9QiNyCwQERlDjLcT+Grq3qKXlAaeUtA3RDdBXyDXRkaxO2HRAM6s0k1Eix4yYz0y5h6sItaDmdOJKtWKE4h9mRXG/TdcGNVUVqGBaPRYJKXEgtDYL2w9IK/YmMZehGZHPNVZLUchdNWV7fUVuDuvFVvdWrNu6mdcETgaqUJtMWcD8MuAghwhm2O+HVyCpK1MCuzJtoI8en9KvGDCne8H5LUM331JfoRnP/wz8Nm/4r+kmqdsAQsW2+UUdFrltcM+z73ATRBKRAvMOglZeXaMxcH/abs48mCcsBBGkx5WAgqoCOZDGudr6QyPpmaC4p25ItD5h9miD4tSthBJqswZ/fyG+ZNouvNy/8lTc0eb9HclUz5+VdzNeA4b+mRIIj5jomJzj18Jc/bc/YGOnH/l7g8uG9/hPsIZxiU4luM8GdrvKezGhbEb9Yv1FjaIXEZ0cilpO2aSoV7MRGFfvcWAnEmUcCimaucixZfMuaeTH5h/zcPAnzE/+mEeBm6MPNG/5qf3A3xNa0xpy0NGdLKzNt4zS/Y2qBJox4qWT3vzPF4DS7qt0763rKmV/Lw8f5pwnDYCdF+3rpKjSdrAXpxWZfV4mD5TkNjJ2BXruz5R+0K98TYSd2HWm4cLC8F7C2d9b0EuhY0lzEsNCCexZPeLOtBfLaBOdilHueRZI8ApEJMmqAm/Zr4+Wj0SKAnYWyg+mLlFkWhr8C3dKjxf2XeWuB6oC2Q6SqSLUe+EUJ3D3+Bwl0NdKa6tDa7VF68HqeXLlgbp3Fw3j3RN+Lx1E7630Jzg3YqZT0ZnPot2wyCO6pSjse9D1Aa0kths/lIG0fiYJI9LUdp3Ex3ePOTXEBXkswj0RarjhhhNOfkq+IVTBwd7qdKoamj8vAs9UkbPI3RS8+oXZBfzeEwu4esuewRVuEqTnChs5VIOIIv2JZ7Dyx5hnyvbsNkcVKxAQtUm6Bq9amC3pDiM+QVqCzGqn9UsU+ErBIvUJ8AJ02+PpjRCnS4AClreUVvMfalaPj4hocz/3bNZeD6/UPOrmPOchSubtZrxKieKTjHMvaC3O3/GMBnOQr275uxZDJ6OkvGbxCN/y6GTQXKzRqZCrGLWciBz+GseRjH19Hbc9hNKhjPfNmfhxVyWml7+HckgmZFvPSqURPbj2ahlndcMLVh5DJXeN0nIlmO9Sie4TNzTKhLGqg9aJlNsSddCitiqMLlkzvaLDeP7seelxbyStK3w86e1JontIW1LK5FdQDkGW1gxeiyVa7bXIiXtiiLazuWhPQ3iKOFYS0LZjrwgdsceEND3PiPvJOqIJANi1fNTmQjGeKxeWNJRT2WF9QkUOg4UY+JwN1y+DnCGe1VxyDTDwZalWqAZXCga4CVa0ALrGk3DIJ6AObuwRBvlYNcW7qvZ2qVY4Z7eesvuJp/UMxiY1qxKr4zQL0vS4XvmMXBYWsNUwBU9a3PSn1rme8ge0bsirXKH2md4qJjdfaOrdR1jH+63q3KbXIRsfOHs7T9xHz9xRqNn4xePKR29eP7CcfdejNxnTw+Y+/S2pTuXo5oPluhlqNpmiFdzKeKslmb3ixaDaitWZKieKlRRQ/VUvGkD1UsrDpdqbPKh3YOPfiXJywuEqyB4pfLhumirZVWKLQXt+tl1oN2BdgfaSxQ0PAfdXwLMZA7VSX30elXK10osra5omEF2SD1XCeoYuVmH59CgCsu3Ufl+x0TDOgx5S0G8ZmodgncIvkoEXzvi6jqUGDtbj4mqYEUNt6tqADRwu0bRiiQa2QYrMb50zJnnGvarGaN+BM4YI6aCo10ipkHsufBLEmiK9iJGRoG7SPNGoNqmGoLvHSvdqak2p6ZqWfhjSylh/ew6YtgRw06cMYgr5iu010Dx+e4XPq/x4ayTULAW1bxWTgEnzOOTYpATi5wpmGhLnSyY8u48PiHUdUMmarKs4vtXRsD4fN1UclPuCSoqqdBsTD1vRJ2rhiRTUyY3qvgWkuwTxFdBJb2EIzJYIB2thi5Jai5EMBo604K/kDoTupV6ZcK36YQyCc92PNbBqsZEBIuSINCejBiVb8MZaFcr89VugLOf0mugPrm32saRYqrPFkmxCldnbW4Wlrmvqid430jxnTKd0lSAflt2IxgdYJLUfe97iySVrHL/sx/O6FAynDUnmsoWt+ajpTt5axevW3Ph6g8Ji226Y4+7Z+OLL2gx1dKuGGG9ae+eB8sjbq9zTh1bqfJEtOAs1djAXibHj/lO4LLbWjv74DbcV4xwg92TPDo6fnVKXvvuPOCQPf22dlDUCOGY3CeXxW+7JLNYRKAIugkh5wZU3SMfTt/01XNgV2ZUcil+UMY/AeeS6JAizSHJHMJTZk4rwxX5LBlUo2npUGNgvbErNkkGSkAREoPwseSBuCCYKh2C5VV/KkQ8Y0WXKEKFnoxkwZLx2nwQ1SxGjwQAPDdcsOpOIwqZowLFivqgM4fYV/X5dTbr4satVowojP5AxIqEkK/Ig/uOvdo7c/83xpR3+jE73sdl85A5IDEkWLKV3FCFxsyuluTyln4BmiaPCahwIRcKSq2q5dTGfqaYBiQqPIKAAg+NPYcnxzI9VrrKQOXH9DoItakH9veaepDRy1g1Rh4B8xLEEfIQ3+NQg1tZwyq4oXK1eRM3dCs72Qq4ogdLr60IUWeo6QhRR4i+fUKENpotJUNLxt1UUKHyAIImKrRURE5Hgh6Iv8a2+FwUAoG68J+OoncU/UFSdBX5s400vVlhn4O2xuQxqn1ftVcpvrI/lmSSyVnQbZLJ5LtspSf73SpUy3Ic32p8bQLMJqqR7gq3TFRT46VRnrWmqYORwqZwFGyS2ZSBVfMN/SDkzNKF0YtHFL2CTxYRo/hSc0ATXEqXODF637elvtPMR/kZ1edAKm196++zT5NSGP+O+LnrZdOkVE7wvrF0K8yUkqNvXcaUzTtl/KGOsWIC76tzRglndbv0KXn+LVHo5M94qSYnBx4FLu7QdUF147ObgqdmFGwL97aluo48r2ZoPQwurY58ouNrft25yJD/vMOsBdiUsVE0dnlk4t8aOasyjspSz1bomPG1W4VvXSY5DPzYXh2U38G1cBAtFEJV87unDMRdX+574g1cJsqu9KrexQ1FKqOl7DI5LU0Ta6z6py1g9x48t3aX4VZtuC77vD95Vdvul+KdsfGOzbNwiWtLiTtsE8OWeMAaPh8l0S7lvFq1d+EqeLYG3di2+GVULfW2kO3G+XVkuyPbHdnuyPbDItsrzfxUoJgNOZ/yFFyW48kGUjfT7tJWW2IX2wBrYEWtD7eVTFdPrKPPHX3u6HNHn23p82boqVVerzzdkzEN5aELTdSvLFqho4VX376JY9t0+q0zaW0ph9E4v47R6BiNjtHoGI2HpQhozJkGX1jtFquapouhqt6qbgVH2HP9e4lr1qEci7y/8aU3MJGjEHV2lfGeizT08oh6HjjLgvfvR//SCWYDJ1njAZ3zgW6KQw1gbheCeeNLVGVAeofAl353IXMYv2YfffXSaMoW+s0DcopnSyTeedSJ+DXrQYFe2BS3B767H30YBJQjffZ5Dmdbf8EN5Ay7VJ0v1MNLIzcX3I218WuczgxmjfkRH3Msh2ZbZy27eSd0wogsqQZu2nM64T7ul7yQwnCyUIXXjCRhe72dGff5DBBir10Nuews3tLPMIoxEfV62GmYFKudx/6wtzOTQ+y8fDI0ZvUkkzqOh8rR0HJar3QH2OUgdFlYsiwlFYphlJ0EOnco/oU/frIpWAxbnDtubWoOy2u6ctYNZpX6akpATgsNN/pu5ma1DMPWeC2WKM2b0hWDchTBTEFfFe3QHdKmCdkoeZQ62znjkwTJxGmCB1+So2MFipJXsATPnU9fbUoLa+JfXllY/hsLCytebRUkUBOxQUKAlvQXLCFsyldQbneJf+C5elDhNwRegRUkbvPIv0KJuREAcEEu5nThBdTdaekfhot8J8AkRUh5m/UkbaCpdGIPBJtWhEDKieRewIqFQwyOsftFnrQGp5cSHFKJ4Yo4pHwdynHoFRNRGCxAYbi1KGSku1Jrs7L36QHzmGfp33J3sJO51RKD+ty1cGnpAGd5wFG37V4Ajq0p/zBkZBHERMQh+5GcSzkaJROH+pDtGUp6+G7g1xRtKkEjuXMuiyj3sgK/PKCvkidF8z1E3qgJEjqC8F1KxJw5fMydDqVaoFRmqe+eO7Jhi8qn9EBg6s5lthDHug/wpS2nsR3cqDxwReZH2XfKmR9t/DGMpQ8XTNYj5sm3QwUoaxHP3MLtALHSGT0QDFsRUiknh3uBVepb2sh2u9fUi1Gus0W4MPC8Enw7DTyvAt3wEZroylkmIpgTsvVFnW4T2DVhTrqsd4I4OQeFC3kaahCnZD4d3jxUvAEoaBbs4MggRwMinbzwqrDPNfU4EjAABycOQ8ibJMEAcw3JiSfaaRD9yKEPccgRm0iUEiQWcvDCCPgSEQVzAlZm7k/qMy5JZEzNrhe4Ku1Ny+kIfTVCwcqcniHyi26SK8LFfRcToiQ7ZhqE5bhob64634OP/mvqTAu9CPdduJYMjb6J84SDhmqQtIlgYP/CxP5T5n/0UWEIS0wVT6quv/xdOt2DmCwD2WkcTYOQRxTsz8bbP/rOlDnr8/mzwPiy9E35XcBCWKMFfhq013m+8ss6+OhDjkuEzySZpZHBsrQmVYlZVW3nv+wPz1gEqy7+ZX8o8cecunCCYh7/urljh7uefA32/TPwWatEPRXnunh17oQspiskJAwslcun/Tc8EFLaqR8yJHZQRjIa7MKNhOyahXy8aEO9ZI8S1v4PfFDB3J9DxUBNSqim75jba+NYbwU35tfdCZhI1l+uboHhFmwiPVWrsaR0gt8wUnwDN7Lu/qmLVXcDQz6ZgJfTF7mN6Bxba0W9CUJtNpVd+nqMMgOqbEKMJhVZAzyPsGvgiFVT4jLHo5pxDnB3RgtCyZ9BeMVCNXD1vTU+x/ri5tmFGf38hvmTaLrzcv/JE/Rj03/v3TKBQPZVltf/XeKPp3MUli3W4C687qtS4OU94V1mtFaugakXftmXZ72XcYS0/adeboZfcVeO5euHOf/+rZlki+ABneIybYgSI3pUJk6UL4bDZ3svXuw/OXh2MHzxwnT0HOYnpwcsyePXFMYQ+1HpwjhxKIKwZF160rm1rE/ic1r2MAoi6l1Uv1A+n+f2VT/PfbDh3SpHzI6fc8ovOtinHvU2vvSJA31y8FRaroOyG3ss9QbJPUV1wySWN/V+X1TLu1n2lqqbY4Za5PNm2u1yU8iEEQKR3/Fkmw9KDLQ0nIAWJwivxl5wgwWfx0Hsu90Wf3NbvKJwlz/VWRDLy4k3yOmIwY0SRGua3L0QaZfvXt8AMTA4viZ3myoPGeA0JyyqZTPB9aWJxzxlURzKMJSOx2ziMc8yi9kxlts1yRaMpXk4yzi35LpYf58sp1D25jSl7NfeDnVdLqOmTzLdqb94P8brY5z5veH+QT52B059fg0LeP8VIT5CwtviG2pXpeE26nmW6JUViGv4QyjWfyz3snxRIFkMN4s42TfUH+m9oQzE0n/WfI3FPPS6N76zQIczH5CcwU5Y6YSVjpPthJVuizthZUuFlfq0RCCrUNetlVUOXbdRVsGyBzVCiq7NFbJZcA2eDokTbrksIw3q90+MWWlGoo7v7fjelfO9dn7ar8djhvkvcsjQCd7bNclO8O4A6BsDoE7w7gTvrQf/eymVdYL3vd/iTvBem+BNXbcyqhXE7pDNPerUe6OdyjYWpkJs1/mjdUJ2x+N+AzxuJ2R3QnYnZHcA1AnZnZDdCdkPSgLrhOx7v8WdkL02IVsJ0bWhYphmHze81F03XY++KtKDOQYopGBRXQvZBQ4hQ0fysBiXLDC3gmTNpFAOZ01ACJTqRrgPuaiMIvRbUKenLFy/Kqv5IYkFC/vjkDPf9RYydF+m52dEvqY+vfnICyaZt2P5ChkEZDmH4zG5hK+/7MkE/jo1fxJmJtd6QKAh3urLHmGfqxux2Txa9OSGqX3CFBcjpsd2B43VLsxvQjcHXZqk4pss9ssYxhw9jnnNWlmMq0uVZI/BDRUXsrpB7bzzWysTOYJ/PKZn43iW0v3eHw5f9Pf2+nvD8/3HL4fDl8PhPwqv5f4GXqyz5M9DNuaf7d+bvuJ67uz1d7Ibv/oxo9i/QBxZxZ7LgTIZLyIaxbcbWw3RroiDxbjJIPYFKmxGpRN2kYgELUojKGi4o7JWigoZYeLW6TDyM7unBa2q+MNkzqlWw6Ya1dhVa75TVVYj1+OGhvMLJ/B95kRBmHQG7inLb25BmaWCCG/xfWaPb6VOU6Gwkm2JpiO9j6VFmnItMINKdYOXJOUm3cbhsq2LQ2cKRJU9SfO53D49Q8rrLp0WJQ49AYmkWbirAWj3S5KNQ2W5L+XB054YOZdAX8Q+F+tCh/TGhN7qoLm5R7mRzkOlZkqL/qGdqJr1Nmae473zr1QvmFIxHdSy5g0dC2JusxiQY8pVVpDjV23mke1ValJroot/YnWrKQ0HXjAZMD8KORP//Wmgew4unPFAkaBDfRqx+pVm4GPByGWmOazKpUqZFQVkzCJnijtoHoCcegQOzC7ue5ao5WbLRjBAEIcOI9iFz7LVoZKvb9TL4dnZpBWmUhljMpNnkHbu+BUsOGiWKJGT//AB9jwP8bdW11hOsNV7Gymnus85okmCEL64SDsrXp6hWPqddYo7XNlt0NbZnwNjtt3W22w9FiWdhwySOqZougKm5cPpG3ImCR959Cp5xfeVvIvZQfMF5m+ZDG9rSAFlLEtLPV8cen1F8wcGNa+NY0nzoIrYF5KRwFSvIOQ/HvaHe/3h3jlK+FLIhw4iotz3mICqOXKykAQuOZk7HwQj//3H/qdH0yiai5e7uy67Zh6cYmHqSp1gtkvnfFfTDQHszoXmd0Q8Sh8k5HJXfoLYnbBo93vCfREx6tbmSDV4KPhfG45JMBo6U1zMrKryDB9AmkmiH+awSzbAh+AVpDLku+SGjdB09p2+WqKnFGAQsjOOPQ9HfUTHEV4/WRNRfN8j00BEsGNYDZMAkzIg/z4Kd/+DHJpXE14pVWt0Pmc0BHWo/I6kZiMlY3ZDZtyPMdEWvmnMfS6mMIdRHJEZXZCIXkFCTWdKvMAH+xiXXJ5YiIjNYNjYh4qLUGhsQH5aEGUVVxrDdEregoBAJHWCckVq59cjMZ4q9TPOaUEuoeexezkgJx6jgsn5cT8KtKqXRFMakcBz0fkKXgOfMWIyNApKnIbBTH6CfB/3XfaZUEjXS2Jf1UYBvSWfLVMv9O4ZRjOHKjUzfJdnUUWSJBmR6jdmGlXq/1Afak7A4zNeUCTm9SYzHknBIElTJmkP6uiR3zR4zaoJthxGfUKaMysh0dI8n6rk2efoQlnPa7/jRNZcxWI+2Bx4ZjApSpnnc4R1ZtOaqHUfs8xY1acAUAU0g2HDTqh0uvJSKNxhrrr5CE2PEIMEv2bf102/9UAWCuXCBzG/4VxXzGLExkHIVvE9NSO1/KA49Fp8y2iB4B+MyQX1FxcJ9zWjLtOxm4qA2H5UuyGr2VtNwtUvSLR/nDLPCzLfq4lUu4/Wvaymab2fywxcvQDGh+d05Qj+Lb42Dj0k3yv/2tYDV3/trsB/CZP96svM9Txa7GaNPPN23398QqjrhkDhHx2fXB+ANHF8cv30+5UvyO3fVL1CewP8v+zpp6LlWYAeMBnqL8g0mnm7f4ldR4iVnf/lhq+mOGjYaQ1qIh7NeATIGshfwVf+w+mbFl9SM0TDbJeDpBkoOKF/iiGP3AB/DcaEJf7DH07f2FOYJcZt+Lj26MM+Uwc2HlR++TdK9HhEPREQEc/nQRiB2D8e88+KZ271rSt4VcPnU1GoFW+7/IdxFPjBLIgFOZMSjUqm++jw7N2SW9o8ZsP3tIVS492VWNfmU2zHa1ana7G45mOkQUFJizgDWd5XhtGk7jvVSn67/kUdlekYM6Med3hQNM83bbrqRq5Z6HKndqZWnQvTtMvOlxGdt1xH+hoG3Zhm1JzJ+9/bTcM2CiGi4qqVH2jsR+GiRA/gzae0v09UA6LcPQsu3o0KXKkOstTe9nZQgCm3QRkjaVL86MP50feWQlEPZaFy9QMwrgWNl5U4cnNzMzBFEnwP6CrKX4QakwYlR2/nmgueKnZzwyQfn7Yi0jmnnl+cxyOPO0bwRPJD7Hvog7ZTcIxVXmiS30rt/soPSx+ezIRLTm8+pAGPqJXLRKKXuzMjQNGDuzMIdlahzip0t1Yh+N/BhEWD1NZRZyDSvNw3YSLCySbmIUDWjH2otzMPRL3VR3KRuFgZo88R/k709hfV7UgaCMUWUYAEc0D+K4ixMp2UdCA5dQD6KOwkesTjV7KCoEFOPFgDtPI4sYiCGZky6sKKkCMoQ0dQ9y7AcNG8avrW9B08ervcv2Yi4hMaMVyqvhxsdyvtHcWY8xUBfyXfdaT4LdTKB4RNUAACw1EZcVeU/PA1FAUDVcThW/jPe/jPKfznHP7zAf7zj53ezk8/wX9ewX+gx08/w39+gf/8Cv95B/+Bvj9B35+g709/wn/+C1zUDuE/0PcIGh8dw3/glUfwyiPodgTdjqDHEfaAV76CF736Df7zO/wH2r2CB6+P4D/w9DXM4PUZ/Ade+TOM/DP0+BnG+wXm/Au89xdo/Au8/Bd8AI1/gW/7Bd72Kwz/K3zCr/D0V3j6Kzw9hr7H0PcYpnsMTY7/E/4DrzyGdr/BJ/wGU/vtZKe38zs0/h1m9Tu87XcY73f4rN9h4m9gId7ArN7AK9/A0zcwyht425s/dno7b6HJW3jvWxjlLbR7C+94Cy9/Cy96Cz3eQo+32AOGf/t3+A98zFt40TsY5R0s0zsY5R3M/h30fQeTfAdN3sOgJ9DuBOZ8Aht6AnM+gVeeQI8TmN8JfOoJvPIEhv9P6HEKPU5hvFN4egpzOYVpnMHTM3h6Bu89g/04g/HOYPZnMN45vOMc9ugcfjvH32D4cxjgHKb2AUb5AAN8gOE/wG9/QON/wIN/wMT/8SdygRJjfpUQUyZgRnkY2skzDdVB0EUuRDghY76YBpE4ZSLwYgTC4nvPpfnZi/jcwzB93YvIYFzMcMnHY4ZVU112zcHjDFzvjfkV2KUkchvedhUF85L6UzhSmM5tYFz1tNcsGHFPxgaPPBYZnFQqnSVvSzt+SgWh1tJNk2wCdTAlYSGXJyhdXJIZA50DjwrRNmA79WSmUCGpUMgcLECLWgqgPlmz/IBcflCSSn5Y4HNzQ2M5VbCiQYE4HoC2Vr8NPRJD5QTgMzC4B2RKr5nKTUr97wQw0NKyD/jLowE5JNTwbRhhsdYAyvSCPzeoVMIrsEQKosUp8FfgEfrpg48F/gHkg3JfkHkAZIRTj5wcHwPjGiiBxxccVZQzGrGQ09JIq/QQneSFuuSHD9VCXehpacem+AL1E3YbVmOOThSGb8XWi0PAFcl6obFvuNxvgxbImNuyM7NWDJUqVs75jGGlYlSBZJUrY23owOLPt1KyHFE/8OGiwKAz0MWnr/lw+mZAgA3HCtd8TBZBTG4ouNMExKNRqgaQpuQSPq1W5WLlWLJFOhdjIr2sAgaXuD5jQaf66FQft/eFftFAB1zmc+a+TC2IMBlJvZUpxGfb7y+9ZXRhK8wBHmd+9CaQ+1QNhOB0qdrUwd/JOSaIwUHPsVV1Kp8zVdpaM1Xw7zlHuEvsth/KaIvyLsKooJCDqkSf057yC4N4u1/Pz09S3X6jaj/naASfsbJD2A4P5GX6GRQAFloFLyiB8MPzQ7TfwDIZkWYujahUytQux9vDVyXJP7xAUiIZFVyzr/8ZsxiVhcf+SRigOkP+EYjoJAzg1skOP6MDsCoTWpvKIxORn5qMqj9hf7j/uD980h8+Pt979nL45OXwYPD84PE/tMHpte+2HGDvxeDxs4N/VFuVTPam5Wlr5Gdqx9tn7MnT5+6wPxo/G/YPnu8/649e7O/3R8+Gz587w/HwydNxkd+p2j0bcSJjI9KB5iVBospqpBe8l+V0ctCTgY0cBGRvxZIGp4ZjdRs+at+WfoagzkX9Z0cu18VVrW7fO0vRmixFdaYhaSv5Nm1Dcu7LRQ/tflERGNaR1wVzEgRc6wCighbSfIiuvRLlqzIJZ4JBSs0zmTAPW+vMkrEhWxEhA8qxepeuJDFEQELpSobhVyEDZ0TyCJdebReqQ3V4uxdMap3qbjvuko5gMOyUChXJxdwBOZaBXEGI/wMSOWpZR4yZ+q5tp3z332lMhyPWt6KizEzyimP+GjhLwbjSAVWAkjFk5PDs3XeCgPQB8toVW4gSW07htSWXEMdBbbojKYzVIDXe9E/2Hj+WJhPjPbXH4tUvr48Oz1DE1dLwBQW3uf36jh/OoEtVktryFwThpDKtrdHDnTCHiogc+05R3yV9lZUnuvmZxvDFT/mEPI4DSzmGa9nmUHMhYlaeGlbEuFHvGr8pvJoF7gB8FlITFCj1chKxyvVkRts9fb7/9PnBwXCou5wHDR1ePH364vmwmERXfUd21uY80heU3kPpX1+aziiHX4YU2Czt04hNgjBr6KzUDCT4muxVXbag2Ifj4F7Ivy9CNr546j6jz55Tx3HGzrMnj+lz9uLx3mjPOWDP9kdP6dOdrzmr51cgflMGrKi7tTMcZ49RU9xVbyfkDRq1lU9ayrMbeG3uEiR7CZK067fAAeXHX7/OLx4P9p4fDPb3ng4eH+zIVwjmXODNKjN12GBobvOiKiVk0uGwAJsKF/U3qEFy0yu99q2nF1L/qvmmjGLnikX1Az8ZDpdaID2DXKAD9a+0Tf0XLxhRj5xSl4YEHqBpW7BoQM4YIzOIWzUcwyAVaF5YCqFvX4JiH94IRvndYuh0xU6o7/9kt59z9pnIV1WNp/bTgFN5vNVqSAI4YVZJ0v2I49Wruxt5QSs4PiFJT1Oxnn7FuyCMpuRwxkLu0DKpIyHbS7xZOpyVvhddd/Ivy61i+uaeuQCwPXxuQZr43Ir1tGTfqPBfLcPBUeFr3eOhNQ9Hhd/MwOTe8j6cWPTJMnLGwtb3y54TeWzhlB836Lef7j/ZHw73kGTP65vuPx0+fbn/fDh8ub8/fLn3cv/g+cu95y8ev9x/4jx/uffi4Kkc5Q8WisYdgHgu5J9pxKPYbViVxy8Gz56a7Lb9TukezUv/wQcaR84iZHWxqz+xmFz/xfPBE8XZuhxU24G/V/66bKP9ikZ58ouRecmyFhYh940l8yh5q7Hy5oea5808Qz0lQ+hznznQhbtXdqkkmHrcv7JABmjW3GqKjE8e3N7H0SQAFz0YhLgsYk6UOoa9QsfJeqOM9n/j1KeDIJzsKi5em2qQn4AkhrXH4i3QQ8i2CboqKOswKApm+AVqMLlAMxZZaDvm0nyW1Xh8u8JCI4uboxsmppVlW3lmxQC9YzfeAlgXn7xSYhreT8hLrBZtcdH0rsf7hevq7pSNombUbLPSe6CXBcjpfCozJNWtUfphRyFzpYvhrzQEn/sSO+/XjulcgulkztT+mJZevIY+aA2pbV8y6aYz+vSx1d4cHx4ixZyHPAiz1uGSQZ/DXfHiSf2YnFJRJGh4Q6BvT39wop1KXl4qV2GdHJf5DmtAAFT91Cr0wK/jujBWFac6m3ucuT8tLHbGuGBzCh4zbeTldh+o8tHbnBdjVvJjWnbCVAoNrOtRRr2ZvdPSyR8MAkdBcMWZLC2B/qeCRbUkWbDwWpaoCdmEfa6fxP+lZtEsH6qQAqVWjJv48qMz8sh1RrvPXr9+/T12qmJzKwp5ycnrl+kVTQ6+sfPp2OlmGZvdTEKSc9czTi6KZU4TX344o/8MfPL66Gwgrid2oJ722bECBYrt+8zBxb9hIwE26/rNUvhOb8RAdkdoZ47YrcJtBTAZ4T6zyLgY6fsNPLBwLGG4d5nBkZgZtLrgL2NwbZ+KNdJWIQAvJci2s0c4gS8Cj7WANMUE1b9CWSLtWOufKfdk7AZkgEyyPr9UGRYBLlRiPggJueHRFCI40EEJTFUHwwPy6F0QkZ8hX+73dnDBpC3QMoQm50U4ptdw2gbcKebeV/CgsqInq1VB/wA7W9ATpf9qa2dhn+c8LCuyZ/TrQ2FD+Nb3vmdubist7UgWC4waSMtuBV9SJnYxl8f4EYLO2AkNo4rJoasOq3omcthe7YQo+D9LCqoZ7fahER7QkyAsKWxoND04eJw0PgOZqsk1S36DHQkbVSGlpkjqsPS0z4Q+Beobjd1OVi9dKnO9c5+Q+fyKc50ExbbQz6he7UHP5lbkJJVpGqRod/Oaz/6RFPT6qgKo3SY+PXhev42l67sa1d5fFhqEaxpyiEpc6Uo5EHv+M/gf2WF1BSNmav2bSXz6JZ+MaiZ/8MBrVrcvQwEdMbejfv99Kt154CZ+IqdsHAuDGCIJjBYeE1PGIvKd5px8Frk+HYyCIBJRSOeOK1mo5Ifdx4PhYAg5+tLfBjPuDxwhviMj5lCo5sAjco1LwGQ5jnHgecENqNvUcSZnaqXISeBxZ0Gk4z2/Zi/JYDAgy5LQIt3MEUw5bLkTaN5XvQSkUaBqrcGtrPm8kk+UntUJLKdZd8qRr1Hzq3MRzk19rp+ocAvDaXYjhT/Dz/svxVAjN1h6QT7Jer+oAc1KtM1SMBTTyTrnF/fs+f7gyQv5/w6Gj188OZDsKXQ9w8zEdZ2f7Q+eqc7Phnsvnj1DhQEES7iQ8eGsiarv7T95KknJkcowXtv88TBpjdfkTUBd5r6+Zn7jZz4ePhk8V1PdGz558bhqoOaPrhjqGBx+ZY2+ZbpT7r8Jgqt43vQlpWtu9G/+gP3Bnuz//Pnw2YvhM+BBXVU32WL9mW+/wU8PnmOPKFxURjCl4gu9hsQmWM6tt4NVbZo/ZphdzOHjx+g4wyNOoyBs+1JAf8vz9NRsbnNqnlox8xXhU5Bb/NdgfhIGUeAEFrC4i8ltAQol7TiqLAiuW5R+svG84hu/Jklemhfh+f7gaeboGUH0TSu+/2xYuDe6r8WZf/qk+GrJf6uqYzzwq78Qk7SfZyOljJLqIfXFmIWN1+EFXodm3ksdShkR7tcfymyT6k+Q5YyrnpdzeenFNZfAQIv8VSse1OyL86cpe/oyl74M1YpImSNWPZPsVW1w7sDmj1H2SOZ2twh/RYpXsiGFbSyQjFpyVEP0stSzAEk5SEvcdbKwUMrwQdxXs6zSxbx2Ma9dzGsX8/pNxbxKyxNkbrbQxgTXWCzU4i4tYavm9UzPnqUbxlvq3VCpxKzzvShhS2/vegFWOJ2DuxhpEhEo9xSRwEcwCeIQktfIIlRCp31CfQuHEltGaifPTLRNZYkdOAkaujE/Y3PN+eUdP0id50cekY005BmDVrUlS5+rwgMkvMqLqaeLeYMHbS6QJKsYMI50YUSMULJKGbzGXMH7w/0KvOJYGWqusF+nzXTiEHPFKRsU97EqauxFMh8qrNpAPoMiY4EQfASZ5/AXJl6SS0lXLnuXKV2Rf2ToymXvUtOVy22MrduGSLpjnySUeYMhdZpDbeld9/jZk+Gzxy/Gz57tj0bueDgaDYfu06ePDxzHGT59vFfUksJ7vo1L1WWh2q58CV1F3q4ib5d7/Z5l1GiZe/3bTK+xdGXeNLfG7pRi+LJtfo0+tK/KsfGdIL9iVu5ipg2aa0TG3GPStxn+gsqw2r9ZRSWIYByBwMTFlIautOF6wQQm3N/b70OPmpTqXcKOBBqtclvISk/CzA88peG205/7n7hCXc/6Rl4waW6EuXgCi9GcYDZrjMPTiDbh0TQeyToIPGJizpjLg11nGgYzhmBhpRzJtq90OTa7DAd7jwdFQUA7CSWexfpzPikrZyvdz4W0nXgnVj55f7Bw8SufTHeyxMGnM6XamC+iqfwuGk5imNaFLpMm33OROP+hcmEauBe6ZXkjNd1F5TjIblwkJqCLZssW5ule+hOSd1R/gNGkfPpJAzl5O4fIWyx+7aLXLHZukRXf2BSK+urV0bNnL34eHv30+NnB058Of95//vj10d7hk72fhj/v//x8iQ9Qb5bUpfgJmcf5jzAeZj6j3JSaUXwe7D1+Mnj8eG/4fG/5OSsFcvWsVYOqeauC0HLmkk9qdilwA0e+Zpl5y5dUn/J8i+LMzecy+wx1piVO8qmjTyMcSt940ESqaNHqplgHc8/wCmimCaNKT5K78Rn9MJ+E1GX9Y1/ah/uncqa2YSzVdKHaeVR9RrNH1ItnyiPcKgLc9PSQZ6W+/S+vz1fmWKfep+045hf20j013d7Mz/pkuG80H5ELaxeLveGzJfBCD3+hnLSL9y7fIn/vss/x3lWf64KHlMEHF/ileVhwpC+LTxzCODM+swAo8PrchXrSOzau9+ikl997/R7Vv3jm79Tb+zX4YCgnUYsLO/knn9/hnT3Yf7zsndXuBWDyLXWTtXa6xYbnjX7PJaKEOfHsjEzjbDp+z4iutrj02asr3cAhuOj45NAmr5GdVz06JzH3FY3YeXvbPvD6L54mtv365X76fPD0oODdgCS2OI8M49YrcvwmA5oS2JR2JibwPJOdZ0gMMM2Q9eJq55iw0pM/byfE8gaqk/IE8K9zDnhsY3j3DZen2k0Bn9oDBMDAt2q89/RFwRwre/Zyr/20mtP1RJ2uyGvobkN5pYm+cNTk6NlFLt1eKxF4b7BfeLEh+CqBX5+VVPwt2MlAgVD4EYTxLa1h29mlO7t0Z5fu7NKdXbqzS3d26c4u/Q3ZpaX9tNIYPWHRt2mLntLw1rbotATtThuTtNEtb5nOPCpapZWlM20FhSDSurTkkaopuytL0e7KQrTfd2bnVnUi0gWtrxZxjlWHzULDdTUgylvnl6asGrFFpeHlreYKpKGEbHKqcuSSz+iE7c6lwrPq807e/UKOoWHZ2nYyUCcDdTJQJwN1MlAnA3UyUCcDfWMyUIYrv3+iUPp57SWi6/3dUewhWZ4Hol4AktX1pAwEnfrX+xkB6KfYuyKyEdEnRxTFEQxqhQYCkivhBimWEQt3CjPvcPVK6TvSl8HHu9yHuDxMkYDL05eD7WI9toheQc7wKCBqGfC1cKN1gC33CXySLKfmBTcsJNoKhyNAuTUcBXK6y0pwsipbtWy2aRdcBC7IQLCTzUBeTzmyr3nDIU5zTOAU6N0ij+I5/JuSveHQLG/XVLNmwvwIUETBRP5dr30Qhgg2I6FuRzBJmSirotfbcWIRBbNfU6+C3FFjEZFNiDI+G8MktJG6LseCa95Jll0tkBU5Fk6wjBbO6GeVc+7lwfDFUyQFYxaW1esqa5xeY3GaSLAlX3UOx3AWexGfg8CU9iIRiqiQNMzlY3izn5FXRd1elQmuubp0cqRUusbxLITbwvk0xOS04ydbJyRdRiAX7J4NRc8t2ZSRAP8glzIY/ZLMGCAAj8gN9zwyAnzARMCIBRCmDsZS4vEr+GSHJZgBaJBYIIGXFwNyqQPb88MCP5QbGmR3Og5CBl5EPPCZm7ytR2KBlf2wK5PZ5xCRDIH/+BWROAaXg0cDcghJWOFe6g+hOvuFCpjGeGoqSKwmCZneeUTGlHuip/7Awn/cN2KtycnxMfA5gbK5+oJD6DyZ0YiFnHr12o8k5L9NDoDyPHMqsNqqWiZiuObZYI3mqBlJGDdvsQwb3QRsc16cDhBA2Kc5V2VCS3C6tyMPpYXjAxyMCuD5mpXUS6dRM4UlMk80pZaw0BnW39f09WkrpRoqG9twK8kfu+SHuCn1hFpBZKjzaSXqTmatCM/9eZxXx61TcnNZhIJCrR9Zbu2lvg5SvRhrXeJeKOtAWviv6MWAVSzoapSDippoMq06KfHuPqdCdDSc3tQGbEth+sZSDCs6L5l4gndnBAOhSJ8cBbHnIpVDtuCaqcpwA0tPReszZPnSuz9dNS6fBf+xhvPzdeWS/jcj3E+Yj5lOFvqBx3bsBXpRJ8ajZKqK2FvLwG4wW67+O9S/ycvBuRBVWRqr3JBDydyjwBSyzxHRPE5PptY3eL5X798ShRjAyIXMd1nIXLAeHmEkW2chXHVg6ip3xgD7/5+9N1FuG9nSBl8lh90RruqfpCjZriqr/+gYWbJduteLSpKr7mKHnASSZJZBJC8SkMTrcMQ8xETMA82bzJNMnFyABJAAAYqUKDI7brtsIvflLN9ZUvjZi5br1O5fL9+JdHQ3ZDirMck50WOHRY/FFgPQ3kzD7OadBXOrVIq/1azns2bHQ5uvxZIpKzKak3h1kkTL/VlqqKtbsUbpPWuyNVo2055XsQrrMTTL0ocFuQaLOmBthkEVQpHeLaPtkn5YfRW7qanZCXPrEeZ8wPaaCnHgEracEAc5PuqFOJdn5HGLc2vLM+JyYbhcGC4XhsuF4XJhuFwYLhcGcbkwXC4MlwvD5cJwuTBcLgyXC8PlwnC5MBrmwnD2HGfPcfYcZ89x9hxnz9lee44AmZvac1J0f++b/msby46uY7PsRPgGGRJhtc3ALKhfmQpJDA9Yah+/PnpNQ/lg1RdjnF+0s/cXeCKvrwrzvi7Sn2A++VJt6TGaqjWtnOvRQXttrCulikUDy+Ox8sCWlnZrOEcQTaRn19oJ5w8yRFqJEKS9LjreiW67Kro5RrEEo8iu9IKAzDbMIgniJe3/NbZ/q9VffwQao+QQZ65fBSEX05pgnorEfXQai+BLFon/gLgsIqKGhIRGYM8qfepx3KCUx0LOcjSvdcB6lUcBxLzaqZvgRdZPsRXarBTLi7kxZMNd1bdqTsW9tAqo9xj72srKL133rUMntzMa5doy7F5xPPsQBqbqYMSF2qFyAbBBwKXtQ6WdG9YdT8kZjuKK3qSZrOpb0Thhfqyy6sn9OGNVT8+Lzxdwnu3TrAD9azF+/ZB6p6tpgl5/NVBj0dM5ZxPsmsb6bMEKg81NzXqAxgEb4qDFAYJ/2a+E1dBTXANRXRW2Diig4dcWw5lYTcDVN7RobZAAtyhsx56N912bX7IkwgUzdnaaAJmc261idVdJAKx2R4WKc5Z1ZNbuZqOryEGkrM+NZ9vYsq49EarMSyNg6TaXEiBAmH/kJHpDeFx5+VOjxOKhTBi30++KU9yQsCtjiDJBQx8A2AcMrE8VE5tFFMSg89IiGhPTVrBfMX91G0f4NByx+pLnjW3Z3gRHKvNGedFLNtPMnlpt2xWTYjHzmJ2tRmTKYlJjcEvLVFNkpQH8uhqj7pIk3J7iRg0NVKB2wW0L7KZNz2DxTXfTVGoYyvW+l/cjt/rGXhbnVt6Gz238bOoO10JXRCjDL/CUXNC4ghpUOaCIs3tLfGVWqzzDIplERKIzFlDPPoQW+5G6p5T6Ls+21HdussYiV5CUShp2g4OgGQsxzcQm2TZtwWlrJuWtIFZdTRoLdPzzUhxngxhJM6lHijuLWEEbMn/XS1YsWEEYbeTv83Zf0MxX5PFd1fR4ZXegeH+NW2u4dZizk9e4cE8qTmeJBead3eCbxBt6CSc9ca17PBmN6K3Culr53WHeIO1lvlC2ogIsieznZFFcP7WrPJXSBIvGi88dBUUIRpuNLT+SrhY3oLnPmV/eUYr+We8VACo615FV/wBYFjw16kqNCctNukp6rLr8dautvl1VLt+YsLCaggfmnS5xCttlGdv3teg1lW6CqtGV0xM9FkZtjvGz5CoLSDbYRSrIWB2BaH45HrUgfyIsEQ34lAd/HQHWmD8eWZNGiUvw9ZvhiITe/JhNZwEt6PHGmaSziS1zmLww0RwSGx0HlITxryQIKvaYcp5UNPKVzF/dehMcVlhSjO9vpP2h7W5wHEL6uAZ3wzj/0h3vgo5DDGT+KBgDX5tM7ZuViD15X6NDUf91xOy1xddLVnVHcxCRVjjMVbOsUbpt3cK5yI81W5t0i8zBZkNrcnhq1qziqHx2CuumKaya3NhV2EqcuJmwX2awOZ7czUlsSvIynCMmeb1JYcFSTpBcuWQiyAS5tB1b+ixrJd7JrAjd1MyicdgMIM5DoUKXoXmlrVoeqz3v5cU0LmEbt99q4ntPhCulLXniY6M0FcacMKYiP3vL9RKSyQIzULmatD+0rARiTNuO6KxlBTh7J8uMTpLmlpXAQt2mRkmM5x1zD3L72JXHP1vsbIyq4/xsC4c/Xe/PUl9uYCidyacaWBOlv5widpGICblhF5cbsvhIWIpBeY5y8kq1eRc0G8FUm4iBfpW8+D2zb7yzsyxyTX3SypyDG8QkjkjsTQT2RENfBXjVT4ElsccWue/PmEwDKqmYcpioq/BaeMZK15+IDVnM+/FtXCJVuvOsVUHR8dBmCi+E7KE9s+EVIb6rDhfkhaiFmrXI4T/tAgEhxOgsIteU3FgZiyXmTjtBLdDKNNpC8pynRiizeFfdORjLJpSVpA+sY3vk8WntRKa+necMuZV0wrf5hYvUx10kYrsCLP6FVLNFJzTLxAVZ68sTcnkb98Xtke4L8CKIZX9KyIFPdGjOQt/uGbY8C6Md8OBnPY4jep4ExBFDRwwdMXTEcDeJ4Q0ZvmTxUZJDqR0ZdGTQkUFHBreHDMLbENVksAjcFQXEblF9ztFNaTicTknel7kKEvAaWP0cpXWU1lFaR2m3jtJCuNiBo3+O/jn65+jfTtK/6czJf47+Ofrn6N9u0r/E6b+O/jn65+jfjtK/22cDpwA7AugIoCOAu0gAi2fTgyADQROlatwVBhIJE5oRWcLbsZxesWIZ4Y1wn92E78mYQcBdnrw5mutorqO5jubuKM21EUfoyKfcY9ckwk2prB/yo1wuXEdYHWF1hNUR1l0hrDK0qBxy6uigo4OODjo6uDt0MB2Ho4KOCjoq6KjgVlLBRcE08Gr1FDv7tqOBjgY6GriLNLAqkqaTEce80tzVKKKJQDbAHvEBPoLkGsc4cgiko7eO3jp6u530dmE8DVDBi680cFl9HB10dNDRwV2lgzN6jGMMr087MujIoCODjgzuJBl06rCjf47+Ofq3q/QviSfvHAl0JNCRQEcCd5METr3ZhUiB7mwjjhI6Sugo4c5SQgbS4Elzo7IjhY4UOlLoSOG2ksKziMVi988JZ0mjdLWOJDqS6EiiI4lbSBJnJOIsxIHwIzwrv/zpKKKjiI4iOoq4OxTxhgzfufSMjgQ6EuhI4JaSwJAkcYSbJ8sx3ApLeGKlVp2aoYvGmG4+biXvvZ3SX+nFUyWgloZYzNtTkTStW3411oy4Md6wMR+0KT8Y2+Q9Yn5cfg9nyFhAcAg7G5DrHKWzXR5dzP6mtLmlL1ncO7rBkSDTIbmN3xaarzjN9pffzZbFwvfg/V44051s3aeL3pAu3Bs44vVd2ZIyATc1b1pd/YtkNmNRjNTWozBrB93QeIJg52fxIYrJbbynexPXLGLT2QLidOT7SNexdsFl94I0wmn+2JRLiAsQEezP+17AEn8U4EjyjP4NCYLe15DdhHuiTZ4OuxfmV4nPiPdxwSPT5a51ayMWiVHwPovGJVJVeo5abmZ+a4whpAtqrISVKMc4GpO4/hY8LXauKnXl4S2cxxJlkPfMvEhd/cS08JXhTbIi4tyj2IuENW45p+kL6hbpadEZF6+bW3+2X9/iEtCZfCK8k42huHWiIcsWFcksLISIUgwtTOmOy+b7Uf6BcGN5Qs6JdyXZopWcVqyEntGiJVJHSY9BVSt03GZ9xFPrxzgmYxapCa5ysWg4IRGNicW3QfCes4gWJPXFa2VfkqytrtFri6UYE0ab6FOt5t+wUS+fw6/ZXVTfriqPVBDUDbSg7ollGdvvdUmI05dT1ejKCYgeC+P6XEUUbHdfrlaLPZtNKJ800iEXbdsCRlLq8eq6SWbwFXUaYR9H5zj8uurjOUy8r8QiT4DKxXhcebKi/FhyZygbf9pEV3fUYmvbZClqNecJ5hP7pKoeGMe+T4H/4OAs11KBLwQBu2mz24WXKhfPE9MeDWfJAvkvZDAZTHtxhOkCSXROuJDJCI48y6KUiopBR/gmOCEBnltOgNBSWq9EUY8T9Y2mrDKZylHQSt0ppjxQL4amTbU4n0kUrI9tqoMhOGgFY/Wtq195Y3kyI9GVJ0c8v7JWL5JkP5Ndy9XLS9XNT+57t477l+GKrZjxKGJTO3Gh/GsLLXQDJ1usL6aa0rCOnuLnumFu3yqoqsVVWFIGvcGzGV58WVoqLDO7UubZyNeCtiqXfhZRFuWl2IoVVyuWVrASd4+Fo7bGB2udBqdmhuOYRHZ9Vn27bKScGQPIWs23Ua3BmnO+ZHFOHsgmQb0KxfuGDIGLtRxkscuuOCyqm6zR3FlpfJwLv0rhXiv48qRbFFCps5syryHmlxqdRQxAUhYpN4E8cl4lR83I7Yno17qUVbgI5mHlGVpKgfOrx1CBo0zplFScxW6HexEhIZ+wJiJzpRQ8nT79Nf+tyRWqaK64W6JYV/We9aVvhRBFAYC3z6+ByeBgMBBsmcZBBcwS8KMxOcFzu8kzDvgp50nFCOKA/w4IS111UeB1lRhgtciV5F9xQ/RxS5VrAxOTB6crtWa1ZF1tntNnpGse9G5moZKLY861MPDcKhVmLfbIw2GYW6JKoS6wm+Sqb0Ul1CDa0pajBgL36dn1T2dg1gjjPFEwVBWxNBeF9hZymSSMrc3JsS5gp+Xp1lABEoK9zC/YRQ1uEPrktuILBcydRS0HQ9vpU5n11X4fuH3ktk3uyM6Nwy0q5xfBXGQ9/dxkzQFZmSydtdzvRsD7w0Pp3Q4YRFYGscvmPusprP68t6y06CY4nLWeHNjPEp1d/2R8MKD3+mut/FjucufTJrIDodlZ42sPozeH2s3JmHbvChxQj7LEPvSZsts/NEtYSPfbUulZ2WPWkKtaEWnr9kjKbW5S2qN1GyLlfdF6oaczsHvlb09huTd7I+olkoqtaGodbLlH5nLmhqb6s8OuxEsiskCykoXOa8mEkFq37qbV6S/ruGeqP7vXQsC3bn01XWmgAVy+vUD7/adoDx29urjaP/jl6s3xu8UbYK/2WZ9qGs9hUStU8HWSUrnd5hDsuw5IzlsafrXfuySk/zq6eF/98diy0xUTKehYeY0qk7VNtltkskVeUKIdxjHOEw0LKcpNvjgbY+qfhUsPb2BOXQAV+Wz68fxt1aeqWlUevCDECym8weH2Eh6zqfGcVd7P81h8RspvFnESG46dmfkig4w4OEQGSbH3xRY1cSTAn6xqIbI+KksU4xtNRF84QdqF1JhWCOR2lKXbSRJqX/ZranmvtoLJikY02CKGkKufTifdZ0OlzQEy2bIVFyk9WNmByJYCDu81iXzqNYFBhLNp0MC43MwaUF6aCea/l0dj7JJN5DY3EY/vYsI1KYs5lBxkrXopocd6ccpuuoBgKzgZcuBLQjQl4lcNf2koStESY1c+y3vxbDAo38zTUIYcCEt+3zAdSUtNQD3hKrn3J5dCLvcmZNrAJkSiaAHaY4sLsV+6FGgtOY/HCS+6iVtcIZ8Jb/oKENaEa/ViwGUquU8qmFINNB1Wa6/5lUyneOxUfwasqjYg3ftnlh49HKKQxWgkYk9YhGiIZhEbgxS+gWfB3KrfEpIQf0Xr+azZ8RDrRblcMhpSPiE+mgMvW9Vhabk/Sw11dSvWSGRpYibJNvN+eGguUCsZBtRrxFbTu2W0XX4iufIqqhUTN9IQ3zuH/4TrRa9i9pWEncN/fv7elT+QqbgG//wsUlRffSVz8fWz5lL/7Hw8f4suFP3/3O3c9vCM9kQ7vXHEklmhDPojkvZT8zeIUZCVvdFZgMOja0wD4yHnYcJpKISeOEoI6AcxiWYRhTAr+csoIunfZxGTf/0OLY5IFPZwrsHOmISCzc31B3FTVFnuf5Uj70l4EzagpzhcH/7L82WlTKMLg387LO0e9oTGwve+qb9dUf/7XhIFqqm964M9+KugPUyGwMGhFfTt1Jf9qrI9LyI4JmIUvesDI/LusHMsPiG9nAXwGkIrhlMaIyxKxAxBG310DH70KKBTGnOEY6SjCnzwtYdh8GJAgz4rPU+s/h4NrwmP6RjHRMyjJxvb63dU7BOJhRz+T+0i0cnWQUCW4jWeeFIa8JEshk5P+h3zXMvNzQh+Xa2iiPQ5RWhfMn/eyXtX3YWviNALOL7qfBaH9SoU8WSiGIp0OSTDGIyRGuKfAbwXNBj5ATZxTBgiggYj5XRUoi5hMoWrd/Sq0+0cgdx89A7++AB/nMMfl/DHR/jjH51u5+VL+OME/oAaL1/DH2/gj1/hj/fwB9R9CXVfQt2Xf8Aff+90O8dH8AfUPYbCx6fwB3R5DF0eQ7VjqHYMNY5FDejyBDo6+Qv88Vf4A8qdwIdXx/AHfH0FI3h1AX9Al6+h5ddQ4zW09wbG/Ab6fQOF30Dnb8QHKPwG5vYGevsVmv8VpvArfP0Vvv4KX0+h7inUPYXhnkKR09/gD+jyFMr9BabwFxjaX8463c5fofBfYVR/hd7+Cu39Fab1Vxj4W1iItzCqt9DlW/j6Flp5C729/b3T7byDIu+g33fQyjso9w76eAedv4OO3kGNd1DjnagBzb/7G/wBk3kHHb2HVt7DMr2HVt7D6N9D3fcwyPdQ5AM0egblzmDMZ7ChZzDmM+jyDGqcwfjOYKpn0OUZNP8b1DiHGufQ3jl8PYexnMMwLuDrBXy9gH4vYD8uoL0LGP0FtHcJfVzCHl3Cb5fiN2j+Ehq4hKF9hFY+QgMfofmP8NvvUPgf8OEfMPB//CFNbfU6/QWJkZfT68s6fbWzcllzk22Jy2rj2FN8+5aE43gC4seLnwTXHZHIBm7aCldDC/lZXeKvBE2TIKazgCCjFpLxUzQcI5+OoOcwRj65ph5B0L05+5J865MRToK4cwi9fY3ZrER4T2RLUTa2vkFIslpTNqTSXQJom+nCbppyVW9Zxc9twq9vbm76Rgh2WZoqLNmEIIkLoC9nQpr6gqYEhxzRGN3QIEBDgmjoBYlPQNFEoMDScMxRQL/ClIGpCdbIEQ59JN2/YSmSIOZ99OVjCDWIX2wWhNtC0/GEIDxiMqyNspD4aW9dlHAAn2RVQnyg5RN8TUQl6P4JR6cn8CsW0AaicR8dISy+pRPBCZzSmHogwojIRuIjzFGiBonoCAYI+RJ4V/0D+B3YFNGMAd+jOEBnp6cg0LN4QiLESSizBaApjklEcWCT7rNDJFfZOB/pD3qpynIp7P5nDZDJMHlxNA9sqIBQHxTTFqsxg5kpyGeUBMF8heohntHyCJTAhGcUSWDKIlnU6Nn5+NbhlAqzkjGDVugmHJwKwqQXVGxMcRJyW7TwVzMPdTULIgcOWQjnDI1YNEVshLgQJ2ErPp6/7aOPHM4u5XDK5ixBNziMoaMADpG+RsO5KGw5T7c9nPhU0JFUZNfqlOU42IS7bgeGhuFMKoXJ1mgd8bhIp5SVQlJzqtdwZ8U7kP6QVN6BTDdTo1UbJ/SrIm5qXBiHnO0ycvZiAX30SUiJf4h0fBm6wVxxtWCOpBbpr/CANA/sbz1K4eW3BrTu5P0FegXtoh46ZkngC94thJ1rgqQ9ogBN5U19y5zJhp2u5bSWtmEWkWvQ3X3U7zef6Yv2x/Wg6XGNALkQuMH9nU53vNZADKunctD2/DhYch2wpAQQ2yCTqda59w1+hzL9mYwrV4k/KtHKMYklVJm1UkQt35DY0GxLqqj8LNShrBTIkZlyin5QiuWe1Ef3pDb6YzX+qKZRCz4KMvXxYzvsMVepXjr9Dif44fHQbBDZgupB/CshJR9oACUAejDRhn6nund76WptMgMXGsANCs5dpECekziJQm6q1or/gB6ZnqoC36EA/+ypg141vbP3b9ApFLStrZPWd11ad3ZuZ+d2dm5n595mgdIQ3poLlWlSlUUSpCwpRsOLouOFBBVhXfUoC7gtJ4CYJ0NOYoAsXwWYx9RT9X4D8QbxeRjjW0AqRzQQUCU01UcXbEqQOrEIJCFK+OH/HkZ7/4PEnz30BIS0w0+dvWES+gHhe38Kgan/J//UeXKIZC+EA2CqDAo3E2ZIHtq5l8vEhiCdjOk1CRG02886GZM+5uHh0cXBsxfPBujo/QmCGOHD29vbJ4foDxmHzgWWIu0OuuTNhESwALqjYj/QikBeIHtgwLBP/Hy3Um88nFIvYpyN4v8SnWtXvn7qXyjOnvj2/sMlslYF282TQ5RWyVaEkwwG4jGOYrUenzpp5U+ddFx4Rr+S+eFUdufjmBz+82Bw8Lw32EeXH5D868Fn6Gqu+gC7uPiA/oLDBEu7ufj3azKM4IeN9FTIJHPlC18jk78F5ETsrFS84bBL1sC1IUqLyXXCestmqnnVvpCW0gn8q370r42LVzO6QrES81EUKt1ITaBkp81UhYucuW910phusLE4dmXjsCYLffHTwU+jn39+2nsxGg17z7zRsPfLC/9p7+lguH8wGHm/DPb3O83TPtiCdHOZUy/2n+8/fVobD2qW/3hRFVuZm8TT/v4vz/oH+8/7+88qJY4FWblrYkNFwKMUJ0TYY848trgTkWdDuD8Z3k8eDveaLn7DeHxwqdYuAjUQ2sHz/YPaCNNC3uEFESvmfVWlT88WlStKbKpSOaDEmJMx5ObRJXahNJ/P4uBZb/Ci93RwefD08Pmzw8FB/5df9v+x/DmqkmyXuXd3FIVz1j8lChvicbtAh9owg8qggZKUrVz5tWe/igC4zsIKrkw75uJcOJooOsPmjkMlTjFbh2IGjgd1Ktk18WIW0X+TPZE1QCfltehjacneDz2fzCIC8UP+jz3ooZd91M2YOtpbymP0uy6CTmUR9MNJ1kxJHtR4LRbuUiCElhpoL7BXC+X/GcGbEZ3/2IOYbxZCCvI9+ZVna3QFqcBiOqIi1LORLGmbOjrXr4KsgZI1m4i6i9xwWVqydkmUKtHQZm0qn3ZxfHrpsynf8yGO+bX9Y0KEsxqoJEdnpwgc4IQqazhVlVyqDRqlL68wMcA/SsxOd20gSencMx6nONff/tZw+19jGiQRWeoYNFtMoHl6DXvw+gULeyPZa0fR2uwKp5dhBdQ3m+pLEuP8Da+ixlkdTYuzX0xKrNtSdvyiyyfliIT+jNEwBvw1mx9orSN8zYQmC2cFHh76spAeXh9okvglbbgvk+7ORG5fuWo0RxuvgFhdiXpXvjHe74qZkEg5/vHz9Jh9S61cHpuacRbEH5N+2nRftNoXBP1zJSsxtjUtQschi9LzXsVWso6yNgxqXs9hxHcWjUmPJyGX7MMXSQA6B4Ong95gvzfYvxwMDsX//iEzFVjDXKrYjKIPBUZji30pXrdaNiPrSDffKGU5IbkpNrMEPLR6bpOLWSk2v2IaUiDI8mGupu66FVux1YwvHWGYBEHmbtq9GwN83Pyv4hw4DljLAVfN8M4+XKyP48lzu1aep9yVNonrqSG153stVLG9b3JRocvv8gQERCbWacYzZflannkiirTjmbKOcqWZEQ9YlL9p/DIzPGSLuOr+BKkWDTfUBitWezfYIg7nH0biIBSwqG4JgPpcZKKPnA1W7Ltig477rZX7nbx6++ryVSv+l6O8bZihpLhrZYaKCWwSM1RDWkYJbAU1gidxHTMDP+FWnCznFOo4WQtOZlvq3WBjTrurPQSOpz0KTHNpDjcm68U3I7E6G8Tc5BO1S8CbSQvOlsz8RejmR1GkHX+TdfLopuN1RV53n6iq2ujlUNWKI+D47o7x3Ypz4FDVFeuVE8zRkJDQZLxASkXmFc5YCOlXIjJl1zJguZ5zyqu/VuYpu9go9qmGdH9A6Z5CPYfzHvWlE1crQ2MONOWymWrIlKOXc3SasrAmwClEI8hQBNWHdE6HsCFxjYdzoD00Up9RxiC5Y89rZs+yd9sRaM2sc8fEOCLc8etlN2A7uHf1wXAMfLPNojY+czWEh3BbWUxzFcuSwP3x7X7KKvvAKjfJ3LkHWO+yLDzDiW38O0OtWjFvqOY494Zz7tLOt2bb1adjO9n2XVd3O3hy9a47nvywwPYdmTTA1e05dFbrQdmz5IGbx5tpyEkUt+fLsp4iITmefCq+pFewlhHLsjzlwTSMWQHVluy4iHrLQGt1rnRtM4UskgOUYI7j1g249W0v9Mt0L79fsgRkViA67zDkrNYbEDO17LXpsoY0xCKaNwuE+z/3YCn2YqZmxftqLE1ZfeHQbSd/X6Varu7vtjD9wv47Tv+YtG95FtswdVlju5D3vmLFGyUeyFwbraUDUc0mHMgcPY1kg9c09DPJwAsYhwSzkLZdpbvRmnmYau2O19+LZi53t602nt96x6GbrvJ2MOj87jv+/Kg1cXE02/BrUWGbvMz6OvPVBvHqZLacKi/r2bj1x1lzVV6WXazKd5FYGVAb4wmZwvMi8YTMkc9Enk1yC2H2ler+NQ4S5QRHfafxb4LGL4+P0/g3XZ5Q13xbBAqn8T9ijV+exTYShKzxoBC+4q8PxfOztewszuu0dCYnl7xpW5iGS970KJI3rZRD3FnDXH9Wo3YJ8tLGFyfGW5yFaOm8Qy7VkEs1tKGy/VYGxWxyqqGHoderI88LE/CsgUAvfqNsocrQaZQzZ+ksOS4xjkuM4xLjbFtinMdOqxfmh1kDrVZ9Ls7nskQGF5e0xSVtcXLy9iZt2TosY4FteQ3kF4juXeTkfChbE2PwnYKkXVz0I/XhcnHRmxgXfX2wNbxpw0OjnWqwrGqgQ3nvxKWyqKwmLGrJIGAX9/sYOZOL+3Vxv1sY97tJutH96TIrYRY0HLEGPi86sG3EFmYSPpWFygcIaoPTImUhwkOWAL9Ie9jhIJNl4ChY5C2luKuNxByxLSTChXPgaPB24FOCvN6RmjcNU2iaY2A1aQUwmiaxpPzURx6L5GHyRaQCyyUaIOG/EpIQH41E/CF0Rlm4a4wh6y8JZzjicLx6QzLB11RsV+6F+Kr4gpeqvFhKFWwAjRGk7i63RRboOyKolPQd9nAEV+GhoyFc/oPHwnUlbdkewG0TAyIeEGW7N34ouNmdOKLwX23l01/pyV/nvz/DYxqKaA7tyV/GuCQaZmGVu8vcxOyasrN3+JZOkykKk+mQRCbMGDMladS+tf58APs3woLi7Q8G3c5Utij+Bf+kofpnboxJxJvz3GNRWnBcdSZA6IkZGpNY7H1IbmP4RGACkvRwGxdO+RdPPl7ik78/P3v9kZ7fkN89L/z3PH4R/vycJ+/Phn/79YxPro//nZDn01//jP/8+S2J/7z+d/Bv/IK8+XPw4sUSURyOyS0+yybF2Bo+lzsDO8zltkqtzPG2OzHTKYmxj2Msr8Cecj1uoG0qDyFdvzo45J0qUeHT9iqEBUG6HVAWYgIUEw0xJz5iYfZNkZ95H72lUwqsOWZof4AysrRrfPehAlby275s5Er+aDgOtcS6bweTsp+HHeZWmx/A0i9R/nXGsxT5VBbb0tBfr4ZPKdebBXzqKAiYGa8YMySbLqh/KbPaST3w3vmRdXuX9cxz/KgxP6pa9+3gR/bzsHu+4pvvgNeCDZXealZHpuexcESVG4NO7JKyE0XlhcErR9qRT3gcJV5Mr0kw76+UvbWBOPMLYMtakj/GlqQl1lIC8HKRRm1dOyxr6RhJTduWM7w1bMR2FnZYqVm7d10LZiCToNyFZDfO9dwsu7NL6PwItA0z1bCwhbuczuvP6bxFTgcbmNZ5S1lBHe2XlPtOxL958uCm6YLvL0Pwsp57cibOc8957j1gHuNCjm3HQxvmMd4iJlo4AjvMRe+TaSqOV8c1kyC84h4OQxKBI4Eg2Ti44iSuzsEr1P+scE8ULiFYWQGkClR47QVBsWwKY6mhWpiX7RRkRcS8empeV+DmJdJTtaqUVmwEIV2kVw3pwv17J3Dm+JeicVUN3IX09NvSHk1QrnRQXP3aSOfFcqpvFuPAcFJUPn7p0VJ8mPiIk+iaesQYp6xlDnMfcq/CabB5GkYkVL6ENzSe0NDihqp6X9yHPnWlft6XZjIjUdGDsbb9g8H3bieGZbmqXTPdfkqGxLREoGA4R5zgyJug7Nos6HOQ9TrTZ7CYlJ0Y+ySKinmB+Cy2CihDRNS4gEDUL+NgoOWSu2SLNq9CntZ1vrdhj3muaOsyJS75TqHGqtjUcUZfL4AWVzKhIYlxDdcB/qbH04fRkkjV1cPul/nC4qTGy5N2Q3mB+doVO+WHU9hFi9tbng1Vp0QWaZDzhfude8K1CueyPLHWCJdjXStnXXeiLgv5XyGnpiNGqyBGDRyeamTlvW/5H6BCpyafr3LFqCFJyp1hAUk6SQ3d+YICPIIDzUaIxtz4yiWlWjdRaHz6yXQWm28AugO6WleIGYmmGJYumKduEeK9sfJ5IdeAdBsfaKyBJN6vTJcKKTBqzjGEyy84xFn8FqfhOCiNbThHpyf3c2wdL3O87PGTijFZpVzdEjgpMUIpmePYm5SJB/FpLfV45dOF5OOjeMzawgNBbUUsDES+Mwg4uaY+2EUoCXz+34hNaRyn/0YR7HaIktCb4HAs31i8d4leLJMT6B0RdETwrkQQSIuggolFaEkEzaijPJKqLBZdZgH2LMSnj46CQJOWacJjNMxI0IOQFuuUHW1xtMXRlta0Rd6lVYIFRpnGhrdao1tTgxvXRosSBXNGtx0kRs7o5oxum2Z0e9QGt/tkWf08+b8vw9tqAIJmprt6s11zk10N09sAM56Tyh+cES5Nq3ZHIt9E0rZ6M54pmee+tzXx1Zv3Gpn2nO3ucZ/O9dnw0qSGRX7WzGxXY7JrZa5zpjrHsxzPakkVNs1ct3wLrYx9dYa+Zka+bTDwOVHfkU1HNpchm+0MfPXGvWaGvcdg1HP0xNETR0+WoSctjXrw3wWmOlmkZKTTP1eb50QJFwXniIkzyDmD3KYY5OC/j9AUdyGo7RrZjSbnmxLnJvbJYiZTv1cYyEIf8RhD8hJpK8vNVdTto0tBMeSOoSmeIxp6QeITFIroejiyNziCrBPpqf2iD8MXJE7eQxrY4J8rkY/R8YR4X63zk6lC9HJ8CtP1iCc4RjhinCA/EbnyYTgqDwwL+59CxyjvT+qWtGzb5e2HJ30tzXGivb1v8J+G5rUSsVOGNSuxy0xq4u7pGDnMOfOokFQgEWEffQBIUcrgwkcghly6IVhUYiCkP3wZ0ZDyCfG/dNEXyCpC/C8/CoI4JMpA4/fRURyDgUylaFKJx1XXghpQjnhMgwANCRSSa+UjFiFyS7wE/v7DF/Ur9AQn2U8C+Y9ZgEOgLPD3KJF//THNF/Xl2WDwxdlhHgMpMg5yLt2PI03rJU2rtsUyOBbq/kqaUEllxO+C1NSaZ0u0DQyzVsJWMsmKHpwx9tEQASeP3M+lf1BTqxJrOt8/NxSHYhyNSXxFwmsasXAKjdcDjrJCL1ehBD/KQqhQqBqMtJR30KSjcA6adNDkpkCTZbr3CIHKS0lnX5l0eY280s4rNgXEtOyoBdIss6YFEQDlCjZW9lAAZXnSzpz/8GzuzpRo28X6zSZcLSFIi8y99638Y0N4cgEZU2BlAzJ2TqbsWpCxcmEXFfC4T+iKkSgbj4PogN9zFr0LNdZaBGrB8QU8qtHZLaBTlhE6rMqxOMfiliQgD4pqWXnjwjCABZRFhAM0IC1ZWICFpjza8ACnBzgi6Yjkiolkk3CBBVRJhQ00EnnS8AGLvL6pYQSO7ji64+jOiunO4rCCGxzNrjwWhvK9uSoLX/Zcdy9OwpAE8i1pqN1La6tP1hel+QSFzK94S1q6gI5oABKeUVi9VVpt6FvPM3JyGjm51HjTzXw9btEjbkco4STqjSJKQj+YI6ibgr6yG+srbun7Z8OAjfMv2HHltOM3HcPpCH2B2X/pSnlU+82qZtQweB9BwREOOJQkt9WFBMbSleZZ+TO6kZ5kum1/Mb0x5ySeHCT+FY6r59Rgv4xmcm/wJbRmrRq0q/5TOAY3mF9h8Zh77bgrH7uTTI+Ks5Tt98Fg8KK3v9/bH1wePD0cDA4Hg3+UuqXhA3SstvZqFpERvW3eb9bF9czb73XyG7/6NsFNMuF32nDVhNlqanq9S7uZ14DZ8p1bxWNypSyd7d6cT8lsipeuSL5TIytwB+NJvCAgnhjL4sfQS4PU71/et2SnJrWMTGeputgAXRxzwwXPmLkiXNBb8UFIJevBz5/v9XXHrmAwFjeOBrMzayz1SGS3WbHPK3yj8TiVm9Cl3I2qtxqNkh9Cgo71LvL0BeTqEuJF5OoCh+iPo/Ozhe2oYqt8XnlK+KSv5b7F5n27Ub4keiqLNbaLnzZbPc4IyQIjfVpug2TPFT5bX08IJzbxMfShOaKiiDLBNRX6dOxAzOBfEzqeBPPMP0iIjAru7CKfjLDwH4oZEqTAKimqUp1DUQTol1jrNtKafoo5RyXEj5+bwgnls3PfjFKarOqYZM0Yt41PFjWrbMbiYKrl42jOkgixiI7BQYyhjNo94Yj4Y/PEVcxTX74Yj5e4rmK5QynfNJ2xUePKJ7OIwI1L2zIVjebtmbXShkzVoU1TZj1oTF75Fq1kFWBPsQ9hTkoT7CojdIvmjAqW5qjfXrODQxpjiItofEhV8TuQp67WVtrpJd1OnIRX8gy36VTUAFLy4OKfk97swtm9il2LnZPy+sTet/S+1LoflQU25ZDURGA70aGK1QJbFkmZsQDhZLIh4lqm22f0ZYV95YiW2tx0rnpvYVF6yhS+WNIpL/rmSTo1Y3SSjpN0nKTjJB0n6ThJZ91Orgb/qXZfLUtAYLRtIv6AV2ud7POaxN6EGO6sxmicyNNC5Cks9ObJO1UDdMKOE3acsOOEHSfsbLSw8+iNcqlfv9WPvizhKDfOJkKOcmWtk3NS3/oQCbceyFHlRB27qHMflsHlSaEmcsSLSFM+kK/z/XtTi135YG2eXFczRifaOdHOiXZOtHOi3UaLdg+HY8kwomXsdXsC6RonUoSrzuRlcbYyKwocq8D7cgVKYFZG8389QsWiJcRDBpGDC1FuOfMVhQM9fjhxkIoHHUZU+NvelzjYO2jq3Fu/6usSiOAAX+V6utI9XTUDuxqMeRkBqYksMKOmc/J0KlJoi57Esq+POgFRMW7Ejqqh/QJxaqCV2uIoF9EupaE2Jl9KUm9BwY58n0MK1kRpr46YLSJm6481raNPoverIXTfUsV8bAS2+bAdjd0sebAFcWwb7VkUEE0V+M5RoD2zweqAUJQvZosNzUogn8SYBvyhieaGA4Ltwr/MHVgX8bLHJ5kYij1lV+txbxuEtsLgsIo9CKiK03cxYluMWTwaPcDgBQvixe7C5VjE975ll0A5NLfw5alleSyq8+lBZim7d09aQuRFcPyvOf/LBmPu7irHIwmmEZjX1tMo29z7ZbZy3E347OIRbxubrbZUZXMXNitI0xZjKhJKGvcyZggbdivxvgrySBhDksuFxqtIWtibXDwoqk1DLUyVdqELWhoRHCdR4+VLi3/vdib4qpUxJCvfxuJj3LduJ0rC5iYnVfh7t3NNIk7leWxQT5d2dhcnwywtw8hFr8cxl5JggPKyayJSNTWEQac4THDQ0zUbeOhcRnQ8JiBjyLpI1y1KHiURRtXklVX5jHh0RL2sjS682iCfqpsQ/Z34SN58hLlKkQ/W7IweyxdB5djTRHYaK4HMmiwS2CvKYa8//Hr0oxCqxLNZsgNdOaDhVxnGns/O5CSre3U1ygj+4bd0WLLEvFcU7npiSdqwkSsawrUpEtas18b5Ad4VzveaxDmRbquR3FY1oG2T1opjM5l0KaGgY9o76iyRMsq2YT9xJQvrIpGfWbOqIksqq+XLsXi1la0AiQq/W7mRtXCELlHhjCE+QxpDwRnThyQRlhvrE3geS6a7tjF3x0DvFJYkV3+9QEFqRpQnoQUwkB/dtrGZ8kNkyqB4KaZNubwVWBAKApSB8qm4JEk8Aau6JxI2T4hBW9gIsjKnomUxsWHeMRIOFSchp0BmNgaWd8zNYG4ZMfZtpdWBWZdpWJPupdVMFn2FNxXUbz2lh1UbgGWFXrF8bwTAda/ia477CIgb/SE7RkeyKLrIitoRcV1Bta01RoWE33/eD7VyefeZRhS+fgEeLnG5ntEyZNRWdyPTleuBlo7oUlTtcw2rbLjNmmeu7DWsdIbV/jar9LapvMhVxPYyArQFEJgLPCLxPKWapQ8K7Dt5f4F+p+QmLZj+oApcHJ++Q2fwggGgtpKPvmXYRy9xgEPPHJ1uouKzavAfJGJIDOcQnZ2epgM5YRfoJYtDEqPXxKD3pQ+qgl6b8wN0EbMIHmPVVSyfzF7OIhYry0KuE+P3Qh+XmAbF3/76e2W/xqdCpQtxhnmphv5dFTdWkIbjQ/SOhVSwTNjAM8YCblvsqqKqUb0Pr2lEboAqHIlLiM6TgGTt1ZcyTk1awDw56Y+q4EsaBKDP6TL634UhpRe3OIr0QxFOTnxKQo+IW8L9r6vi/up+9y1Mdimn2SqOrnKsNmHp2r+ONGfr5Sqbz9jX76paw51aZSx1wsWWCxdN93nnpIsKcr2ZZLmBu67WzzgnMd9LZgHDwixiz5StibUo3VOl8xEN8JM6N+hIlLOE3puFZGMITwj2Ab0QfAEYJNYllLm8jy4ZCgiOQjRlEUF4CI/Cwz30aUS8GMnxcAGBiEbB7kfQJI5n/HBvzyfXJID58H6mVPc9Nk1XAZwHqKemtydbVbPce1j+kOGMQ8zJT8+K7zlUd1VNvUY0ENAyXFqOAEyQbfdI6DF4YgW9U3ZL+bqLnayZdKwdG5smQUxnOIr34OWQno6zFb2DkH34rfNfwlwnq1zKrv9r77/k00qV7AP7PoXp4uAsx0jyK/ESc9L76RlSk80Wgo3S1ZEWYPUFQT/mV8QnLAl881UawOZIyEHswOgaB9RHn0AUgfo9mMCnDoJzTiIA99JakAgezlxKVnkZurOnKNgvT0zdLnn3Vv8Ysj6e8EkEXKsLoolCwYx4MDh4sCHWDqwiiMU2sM1hcmJcV3/exHY+pnSo++RGYkT9lBPcJRWwIsI+5SIlzB7U5DPskWq0MC2i1QjhuFuKBdFcHiT+swDHQG84OlEdofdZR1Z0EGEE7cLdt7ekh4yyIW+AOtEMJ1w0t/yUVnr8s90TQT5NLuhreTuAzsKjeA829HsWT3PzqpRN66CaRqjLaokDmMR7Mz3qvr4kvdC8bks+2VK6+Iq+WF5maXr5K55tUa+2NL34G3Dv7zNbU9mCKR4gVFKSfXmq31qbznvlUyIOCfCx2HzEsylgsUFETsbQOjK3KjKXJ2mbRLvuJOzsfdM/Zmen9jWEEi1UjyGYN6j0/MHSVDHNkv84KGKmOJdXdaW9lpvXL0S1eyBhwR1f7xUHn4+eggebkSe/7jjd06gdYWpKmFqlKRevr5UzlAvO3vzyV2UwL1Et8DG0kyxwCluaXkmPMkesVkms6tZ0fXd+FZKUo1PbpifWZxEuUZmycpHRmTNsetS0pjSyegtagz7IRyvRiJLAlxB8QEYxSkLhBS5fOXfkaBcU2m4nBn8g4l+pRWm6dsVqzVXj+vO6uXR8VnNNd5SSV0qc64X/70a5Za7RCq+hMuFOqsRDlXlsabqd5st2QqKjyg9OlRecxs0ly0ndNXR0+fHQ5eZeQ03Ryz15ZPgyKKau2hjDvEgrWBE26XUC3htqb+TDro2Jv3CS8RFEWs2klwmK8RgcQoAZ7DxrMAIisXBOy7kpFYiHWLN0I4ZzWEmOhmQE7l1i/4Xb12sGyNQhgtuNe5zAAoPapM0iMR4f4iBgN8RHM0wjjm4mBFxw1G+Uoydzwp9A4twnIXvSr51/Nd+YRcxPhHP84ZzwLo8xBOoehiw374BOaVw/8bdQRLCuMJkOSQST0KuQYqowytKoaBiTsYg4Toe1PxgM2oHMuisaGsd6bV44Bl8R/eqLPUyCr414TJNRb46LjmMvYIjMqHYlmxH7vxJAegq9g8eocUTWBFILRxUbS6rxM6piSEXTtB69dKZS0fBOKbk/zrMeTnNXztI84e7q6LqLyGiQIXcp5mcyvBXHbCw+A7vJJR+NmaMJ11yYmXZJ1Wzvm/yL+NTO3SQv1skf26pr1W4m8se2Whp47lMuScEEcxSy7BLAawygv2GDQBgyt2OiYgjGcVhp32a7Zn8jFmWztHPt0xESPZqOCOp4kGsSAi8OERO8QJ8THoPMGJERiUAgRjTuowsSiYxCQxr6IoRLiIuMZyd0iuciXR/Y4oYRUJU+OkkiuOfog+CJhtMdosBFppCK1ReSxETprsTXo8NR9pMYKR0VxpmNMJ6QqVVs0IyrJhOQvoI0nvTSFnnDxEC5W7o+dXAZfyP70HaTmz2sc1ETFrVmJyM5ghY6m+JPKawoEpw3dDCSq42ySjYVDt4CUNNSQYkp23K63KNgQ40IpCI/JypD/rkmQz9Yt/XH9QNpLd4ELoxdm23ua+gbTVG3Sj+oy8RRRRlVnKT6ccr8JCha2I2A7YYCfD7IG2Js9VMTxpNgDajip9AQ6l+zCL26QHKIoj0pRskfetI0o9rrQvK8T+EXS5jxF51N8i8XH96jL/rZ3i8IiqEbIQt+gUT8V7LhL59C4aIlKbTgTSSMo/mM0TBWkcJqvgR7k3R8kLdPg0ii2KcQevhv9Bd8jRVryaYDn0TGP9HBl9ytw9dYLu7/SkdkhiX3P4WfwnN8U1Xri1irLzG5jXO/Kis+qESUiBQpZBZ/ClkYzFFAxtibIy6lZXU6EJ+HMb5FCZAc9AX7/qtrEsYAPcCZ/yIipufIZyhk8adQNmjMUVXnCSCfHH0htzMWAX8d4SSIv4gQf3kcIeWhqPMplBvaTZcm3dF0/JL/IhrymGBfrMbbYqKArJbeb40T/9NnXgICvFi2zz80TxiQO817aQ/6RumO9n7sfwodT38o1VIrelc0nJBokXHuD9AiIRg/ZuiTAGu9+FOnK06KOppCaAX+JemIwOvQ/mDw/GfQ7HA4R19UV19k1oBU1fRwGDKRUyEinAXXkN1zDK99SHNgAI96GlKjynyhHV3kMLvoZkKByuA5Uo1JnXMWsHlWqY/+oPFEpsigQA1D2aXQYtXwsoGBisppoGTwiM1m0vu0Br2WeKlaoY41+4Nt17IilFiEGxW136lwlrG3qMqlrUHhTBRqVgcKb6hq9xjMeevzGslDk3u55DM9Trh+eKVhpHAq9Ii3elUWMnujjaOJVcIIJQNcpNXzlOUiBu4j+5AJbjwWBCrdXpq0RjQNrA6ygtTqwC4xzk4ytnvOFVd3Q3rKQtgyfZz1uqwxVU3dDJp4oDQa9hbDkZvFhdomnUnJ+fp5kxanOo0T1kDUo+JIaeVW0OTLrJYNm0wFPGVAc7jkoyP1zVJcqI1N93sV0J5zA2mZmDO9wmvK9l3c5JHDcR8xjts3KP5dH1i4I+MyTklrvqXrtmJbx2kl2znX2KZjWtvKtOCAqG1Vm10gVgpnsvEjiwNlHkdG3z6FCGE+Dz0kHg75QSlMXUTC6y7y4tsfZRmEIhInUShyfGmL3g+fOr+SIGBddMOiwP8/PnV+/G8o/P1T+P2/Py18vyg/rS1WC9ZMizdG38gI3GrMbhDKWkM7z8ksAK/NpeinrpyePvkkqiOgj4iAZv0dv+798eH8r6/Oey8/nPy9d3Z0fqn7lWmEy6/j5uxjoYqSLZwAaeeEI4JpmAVOpIeGhtrsh5TZTxrY+ugI/OZDLF4ljJnKYAwtCLAyNaxB+3XWA/sc3x2dvu+9+3Dy8e2r+5wq4do6ufJZrjofNtiQ5RO2uZzYtabiLiqYfdPf7dVK5dUPt73ZPJ6wsPBP7d0F9tN8kzeYT1XhWYBpmP/KvBhEyDgieJr/wlkSeaQ3xTOpK8rVXjBrrvCdpsprupL5M3UUIuHnDydJLhNHP7BRTELTZi8q/whRIrOI8lyueuWdho5iQOQhaiQk+njpZ6BnEeHi3enQzxw/fW2NTo8X2MdNJwQIKvkCzstXcEi+gK8pDAQOfv9/D6O9/zljnFOw7pkZx3/gP4Jx73CRQ0G35B5gfKnwKijXSX/Sx6P0g3leik3DiUkriDNTLGGemuK37NyYqepLYRvykkuzMBb238KtFY8iArkICOe9zETT0+UkrzcPZh2NT4QDi38l/30VkdEVIfvk5xfE94YHT5/5+8+8Z75/8NNPv/wyGB2M/INnJfgg7avx09FnSUkQvS+QoL13mmWwDtl4TIbhJiLyvRmIOfEiErdMGq8Fcl25VWwnukhr2UKy5Ec0ZEmoRG8njz8mebxtBKbecYe1P0TIpVz89cZXpnfagTuPAmjPqPri9wbaQjg2jnHk+8L1F77UEXdu951uVx0UAePRLEAytd+gcE+MJ1gfWOEZKxwcRYJJqCA8huIJDoWmovrEEMIS0ynpgrIyUjf9k0oZqFPofArzt+FTRxAD5YUr3vJKewGnSH1pwOpxTf0ENtw5xm67/1BGj1s82OCs2RtgzU537g6M9OBFeW6XjEmCoI6h9D72kiiS7sdT5tPRHMhG5vR87xzW2eEfd4RqE55/3yqpyHklXJVbZavOCxqykXLe6jSxXa2swCs0Veni2FVZHLuANfrFhHmKfbOFfskCJpewD0pnqGKGRMjVOxKNCZLj/uH89TH6+emLnyBIRsQEZ1WkAx/PWssJNkASZaLs7C3F/qfwTEsslC8lj3wKPwIxO4S/9cC1Wo4CliTRyTll1a6IE6Exh7ceE6J0eylCSTbTV034aTqLqopfIBb+iyiv0AQR3GG+EQnUUEc8WXKFO0lqJyQpRRRUx4J4mU1P4WrJMv9rpd20SSpe0JKBYmnBxYlyDyfKpXuaurw7ya7Byd096W5D5TUh+dybtLb3Tf5liZRYudzFSnBrnhIrdwYtHj5Tdp2JEvWZsRohRDJaDMefQocSOdmm3F92C1bbn9Gu2V8SBVfqVfZipPbSHVyZjS6TLVmfeaXyPwwvaJcuKz/w3WNiWwFR3EsyLW0daPdYX439Y6H7/4Wdt8mH5cb0WqRgyF84qSkz+WTWjyqBo7OjO5byiFiKER6gjrfThh+pYWNB9IfjujviN3A/8XmcxPHSgeVp5ZYsOq1lOeXqo4sveYR8uH1Uud5ux5bWyZayO6wuLg79ngJq0kvcA2e4VqyrcVh5dqmdV9vj4E4phV7t88h1fKPukeRFnEMBgzrAZQW8o5umktS+GI6bbLIRtEGMmynqrDDgy2x25cR4SeuoY6pbyVStu5wyVSQsK7AkkpYlXKYU/hT6xAsgVzCEnarMuPyLfBxe5joOhROKsMVA/mFI2Qutfgoj4rHQowEVx6arPEVUXjKqMhbLBlG+7KdQZi8locwBiH6Q/xYJm/cHg2eDgx+lt82MRD0vwJyrbPiIhp/CL3Jl/vm5D1S9r/Lkf5H2msaHGofzDyNBqu8sRXSbtaEW4yq/GFdiNleZffzzg0slG4NULxY15Hvea1eF5XouoQarZ+HaxHVd4srEauKpUpef5rEKLK3UX/E4oOPSDxDMFWMRkJ129c/OKCJwOLyEx2xKImDEa1CF5e12avBjUIMVXV99ZFeJYTTKzGPlGbqmPFcOM32cTOP+XH3F0VsqZMrxqs3hVdM50JB2LKp9NtDd5VUbohwtYkD3FmYEA9n7FuPxXbxV4cS2fL0VeF71C64xHq9GUQK31A8hJP2hGsH5gnwRIAQPKEQIj+BV7y8Hg4OfevuD3mBfJBPC4y8oZV8QS/SVzAWeAkQkizWSiSAlVgIXQoxebp0v5jDFsz4Ss5JutFPKRUQTNCduNPF5H73CUUBJpB1sAW+BXELyeRf1pJJINAQLjYZkgq8pDF3kghKpKDECPz8kyYDzfH1ANyV5FZr1k2FYtym8KM5j57CTHcjLweBQ/O8fnW4zpjKfER9Yi6CaMLas+SEZsYjcsX1gWp+/V+Fm2cEzOcKVGsGVysy3jD9tjMfArGQLXDKr9FqXK19OjCeTBOdn0xmOqSTyggoAkipICuQuJDL+T8ls9Vn6vi8FVa52m/GY975eG6E5K9/pak/iOkmjtGlO0thgSaO9t7DhIZzy6UZv7y5lUS7KFh9lPG1r2QISpGThuGAXgcF/JfM95SV8Z+fgNDAmEpq7SP4Jsc9S+wAdC6SRQriyWm2OcFFKqZJPHHvfKPZe4DnyTPXRcfoqFlAo4C6+iHiit0RGOEKktnzrUr6ad7fxFnj+KnjzvSIXV5I2NIUvLusE7kcoIizH76tZsCKSO8GCNyyt5SJ+K02ey0HLzV8XXMAI0+QYcDRcesmtYkh3ZCR43NTeaaTgVZrZg4cx5oe0xUTvUWf+XUQiZfKcRuAng2zn1b4dqlxflesLu16FPwc6UY3ZMvJykTlIFVStSaNciNTANoUI/puFxOiqHLSWn93piX4qGiqazx6I12DFVNGE8Ria75dSn5sv6jx/8dR74b145pPnBy+Gw+EIY+9n7/lTj/iDZ89+9svDNMnkooG+V681rGSo6m/wYm0hylC8YbHMmNThwJwzjwqBVKXS1EOrH9F0rnh+bjx6Nk0H9KsqrwfVpGc8m/Wr1oOE1zRi4VQm6m40BLUORs2l12QWMT8RifRBYvLJLCIetCLvizHMWUSuKbnhVyQEatX48GvboK4vNLOIJbF48Rzut3WoFiPhCAec5FduqZFIU0I4ouMkIn56msEjc6lxiYVqkY5a07alXtZ1dmFlib2i4YgtXhHBFixaKYtxgMJkOiQRXGTZJk/3XamfxNdP7hjjlLXMYe4L5G1Myv0cyyRLCL6Ki0lD+DsNxU0FXmn0vrgPEl3Z+3lfmskM7hz02rD9g8H3bieGZbmqXTPdfiq3pJicTBODI2+CMia9oM9B1utMH78yfpDtkygq5sV17j3g0BFR4wLH7vplHAw0ALIC5wIpz6wrq3kqBD1uGVsLfe2k6od+iU4LtEv7sBUFY+VvkEtIHsc4DdtSwnEZTBCFhIlcyV8idTiwKghRiPBoRD0TTHhYKfmegc100czrZ4h0Wtr83C0wiqY4qNojtfSOZ99HdFBKVldMVfN7uZNkdaPoZwsXLNnY3jf5F/hW50xVpL2pBdZ0oGpAe2Uhk/bm8vr10UumdC2tmoa+gDHYSBgmc0pPyFDAwjGJMjVDJl8WBo9M09gEhCNd5sadVUEeTZRQf0j2B8NnQ2//Z+/gxfOnP/9M8ND/aTAg+z//8vOoRW64O9PqJS94feI3R3U2ieq0d8fgMZuJSytuq5K4WGheXBDAMjpQnbOtSJnGpOqJ9iqa9Eam4ZQPJoJ/Ax4K7SsPnTpCchdCArvgJL4tkPiMjdxJwvsYtOimubqSCPq8kpeKG874lbYpVaWnqmSGMvm4pNFCyWB1IquiD6Iqem8WLQaRZR7qhVpZB4jdhMSHjM+bZ80SiGIBQ69GMa0eOTSMyVg9Bj7C4t7vdztTGtIpEIX9XHcaxKzt8hRgOJHdoE2nB4NuZ4pvVa+DwSA/iOYYfbbfjgE4mN7B9I8bps98lVoh9QsBeguVWErM2HFq0RWWXUczHM3YTJqRHlZwkWsZNtxcg1mVnpATQXlGo1ajOWQ/H/lTgU7of7/yacwi44djSf5Evd6HMJgb397pbIPmx9P0bRFU7MTyKe3P8s3WtaWYZRQrUn8Kmkc/p2ossCfeRRXa+wbl1O/L6kW6ekkp0mdKvCRYpeu0UJBUS/Jlgar2NkVNWnEv6t89mvfZC+iUNvYDyxNQtW2ARMqY5T4SQRxJxMGLMo4jOkzg6Ug8R8Ms6ILGcDQIYteKqYfkNkZD4X5utEoFChcRYcrIHh4SAdQwZhtpzpRBqYqZmllONRuYSyAH3HQNPszwv8RbjV9JKF4n8uSDSiKVH+NUQKTCanMzoZAhjAmvRhomBN1Azj8lD+g6YvbwDqRgrh6LIHz8CF6EpL56F1JLEmplPRzCerIhuEoSP4vWk9+5WsLsrchUxoGY88SLlbhYDWsewf+9TyYn73+++BN7l+HF7/wkefrHH/tvr3n8k3/7lzeXf57//fnLye3Z3/zRT29/Si69mX/1/vf4z0m4v//h49/P+e+v5l9v2ceb172//PbxmR/+9Ns8+MfFXy8//CV5M6ChH/nh1bvg19m785jfjv/2J++dn/m//v309+lT5r+6Sq5f/XblX/725vX0F0a//uMdm4T86bOTty/H0W8zrymymqMjTrV+aNVai3ySYABChYEssBDNWRJJKbahxOck5UclKXc1nW143FXpFUrYmSPOClXyImlx+vhm6OOO0DhC89CExunxTo9fmR7fz7TktevzQgfauz6AAz9jvJVGn+pPqSr/G/xSUuBLavurW+IlMotXluD84re3CFoUKbvGYNmNSy3tgsK+Qi/ndmnWxXb2hnMxjIZp1dM6MrT5c1PXZ3lQiDgHMpGKU9fW7wojdysNxF6NbFzcysfuDLMi5rh+P5jlgGBJtBtwDjYEI5Ya3B4ey00hXCQ5rMR/Zbm+LlcRs30EpVDamD1mW38G+VABbBOC+Ix4QJB9JLoCCTWmHp2BHN5FLPJJJL1hpoxDMidPhLB6Mb2m8RzgNtUsxGSm1F1UGJPwCtO+x0LIOCOm1KfyIQ4aekHiA2NK4gmL6L+he9WmBOXIteB8Ykg6jsZsCflJpHHAzEwIb6mjCIdj0ldrQsNr5inny9CHl9JjxGc45Jl0nm/39ETApikGC4pPMJf4YzwhNAKvUk+EoBYDeckt9uDRYMGFhyrNUW76ley2ItLaGkusygrY3RpMnG2hyLMJ61CfU2ml3RSx0Sm+fUvCcTzpHD7fPxBQsv53ztlINFC/AHJLxYAiAu+PEDhK+qDJEYhod3SZHQvYKQF7Swzd3I/cVaA8nbIIDSjdhjZr+PAjXXYb4PbV78JFjKNYu/ra7l4XnhP7GNJbRGYM3iujQUA5PBQDAP3vAMxzRFSa19Q08XPPx3MAHYCGsBANWRL6GIhARJAX4Oms3RY88DBLnm+pCSVnQYlZ/WK/gmeLlp3Du4THYO8IcKynANvbZhXX1X/D5bEbmKxmJWXiEdzDAMP6yrTTl7kDFTYion1YkrdrLLBb3b2Dmjt5MHj2S/WlbOaI+U4a7QxUSGAvppXxRJr5xG8HA8kScQjZ98gt5F+GF6vqlmKFXZRPgGFzXMIZ9CKV+/VJXYfuUwVu5csrQb9jSYSXVxJ0QUvMa15vumO/qaJjW6YSvlY7qpUAfb2cNHwlWNiVkiSNXu4GZ78vHNIU0NbxQNpfuY4YaUyULx6GSmO8gHwww3QPAwAhWyYs1zKmstyHTAI5ZZA63VSoJrQaldkkv41yPJ9r8fGqC50RezngRqu1XxyBQbfkHmWr+Tmv3Jf1dFMxt5/PCrBXHdD8GdIat41yvMQ+On9okiFf/rNQjG6TW21Ood11XiGRadVvg71Xtq1Cq+k+Z1tfwlUG++Vd/hhmyuZj3ebcHNw+Pxs8Le/zaxYNqe+TVg9obtImZxNwO/zs4IXN3srQFIyqiknxx7rT5Ym4HX9u49CnYUyiEAdINPBYt7swC7fXzwfPynv9BsfkBs8FyMCSRyuRFaex67v9PTMJCXB0cXj0B1NFLLlI5L/WP6A5JDGuMfzkdNF+weKy0GkgS06BA4oFQiEet6noa3+/fRffxcx4XJjR99bG+/xN+zu4c2VPM+hgZ3R6Uo8QFs/X5zsav/a+mVD3qf99L0pamMSgcBO7GBKt2m1j4vmWSIQHFk0dWNdvYA0DMN8KzatNQlNARJWZTAaYixLCvGUi+BpGzFmP0LlyMVPmM20ky2xo0jRlpAJOezDsYEuZ0yotV/mtqz1vH2YkvCQBmZI4qjQPSr99MUDjzTlhqZTb0Aa9Xl2Py5pTnGHPGfacYc8Z9pxhzxn2nGHPGfZ22bB3FSXOuOeMe86454x7zrjnjHvOuLfrO+yMezu24864t0t77Yx7u7Lb22jcU9aidRr3RBfSuCc7ESYWpfXmzCoymlhkSMKBhvbyUB9swjYZCX2R6UmC5JW2QKNQ2QQIGcVPzFZstj+Z1MJ+8DLTkdlMtS3MhuSVVsSScqsm//LZck3msis/N1G352YHwqC5sPmU/KXNi3U06CEW/xI/fi61/3K+TA/qHXujE/kQLvyiv312COIjQxCL0J582lM947FoqScE+8SO1WHfV8TxLFclj6EVMTYY859seBHjOGkAAYqtvqrewG4nwDy+AnBUv3VkLyFFxIUnIN9arm63MBigrgEbzxI+OcEx5pJWZvkK9BazGQljTdV60uPB2Mt0nFU1AjZuVR7+pJ6tCoxY/lR9INWMxOySyCatFVZMfC2thKzcTc+PuemfRaoZ+ThtWS763lWUzLKT6v3uutNeHiwPkvHiaYhSquuu8XZu/r5kQ1hW2lsef3VY3A5J97DPFl3uPYvRCIzkj3WTswm4HXbIzK7staGr55Sj+9PY26VlySvwfl6fW7lrbqv2hRCzGdp1tyrbmKEgSwUqpyIfi59M9bb8opAsglFIbtroyXoCRuKtFZGP9asN5YvrhOuGwvUdBOqvdHYWkVFAx5P4eEK8r7YGCoNaICPbE6hZhNZzwlkSgfN0ijI4gKB4ZEqLdEd44MHut4MFHOXaAVjg3lAA53e17VqDw3p2Z5+d39V277DDenZlr1eJ9TwonJNCF2sDdFQP38UiL+2osPcNhLTv8iBrab8SkeF9VciEZE7ET7WQjCqC28IxFblnpVjZLP26BXhy9vcVqdert787Bdsp2E7BfnQKttO4dkhGc9b1XdhhS6TLMQtHAfUeLTyWjt/tr9Ood2Wvt0ajTjXPtWnUqgczvkEtdU8IVNEU65g/iEBPtWQkK8oUTKb/wubEMsA4Ym9Sq9z3pZd6Trf/KH6q1e1VERwickvlW9cbouU/TleOxZpoRGYB9sivpbYNbWRdGlMr34kirVIlGz8S52AYB8M4GMbBMA6GcX4Ozs/B+Tns+j471G3bd9ihbtu8vw5125W93hrULcWE1oa6qR6W8GOhnCfyOFhTbcjPFYn2fRITT+TClo1YM20UCt0xj0ZFisrWyTOa5KldOmPGyhNk6AYF0pkll49pLE6r0gC51O70Xz6muTR0os4RjXj8Qb1RrXRr45/WVBtmUnsceZPmgzbTIT//qUF6/Gok0kiwLafafghP69L164Vru7/wBASRGiML5CLSccgil6Vk8+G5BWPSz3u0qJHEbGqkbipJAFmB91X4SlbknFxTnkcIVcKf79lNtX2j9s5pqGd0IfO5lyuXkg9DLRqLdyJezmsvghq2J+5cmOBAwDOC4h/rTM7lkcLnirUC0vTKjhhahjljAfXmFU1xj9UjbopJGqRVYEtFgLRUb0ZCX/4iJBjiCwIwwlTi891OTKIpDXFwZJm/ZRbxJCJ8wgLLvtpKR3Q8JtHlAjiReV4SRST0yFXWPlyH9GeRU/oqOx+dJihlyODFFC+Nt7RCkoJdpXuTbXjuZJjzth3T/CE0uFx2REzWZay5lQ54lcex7lKNaDgm0SyiubrZGctz1hbXMseCbfWmBP7WgpguGmrdrZMCxULyn+2j2ZmubtcS1M2yXtCFN62e0RYFHtsyVs2s6qR/z4SgcnPF5bBLZasXx7oZV6rhcW0z7JfWapbnxcYHI+d8eYVZjIOr6lbl91lBMqhYUqULWJLNm93kG32o9PMOON5+KMIFyO3CDjvTwHbvsIOOd2WvDej4VGKTG5qaOkVOV57TqmHLG5TNajnoeu+bUkdE/GUdiD0m5UzROJS4dGlW5+DEQ65JWqIauDbU2iX8LIuwpEMNNxk1rFgzeYYWFnOgogMVHajoQEUHKjpQcRNBReue3KOnrYPStl81c1DaLuywg9K2e4cdlLYre71FUJoEgNaApEHDGwSkVQYqKyBMfjWhsHfMp6N5NRpW+I6k9AnPnIvlQkI8vVeELBeXvORgiwNYEbm6u+pRoVjkHBr3D34pLowLCX6c6KGDDxx88FjhAxeG68JwXRiug4AcBOQgIAcB7dIOOwhoV/Z6NRDQfaE8y0fbNm576TjbzFlpzzR296JEPne/MfiR9VlBBR+ZIz9PQm57YvA9lJkjPGRJjZPVBQl9kfBPAjUxQywk6Oj9BZIG/i6ANuSaRHM0BcwK8uKdExz0LumUIHEWVUl0MyEhCpn+5+kJohzNInZNfeI/HDK1Joip2jclH3erQprNqNeKtGGCNDgA6XECSFHSIJOccyVzrmRb4kpmA7se0CWsOB64jg4Xc7iYw8UcLuZwMYeLOVxsl3bY4WK7stePCxcTsM18PbiYatt89UHgLWLVDT1qxrjCHjQgkgdIYEnbPRvBSejzzNfHxKb6nbujdJl6IqZSF15oFK3IlyeHaDZpzZgHgFgE9zQkvrxpZh3pxAT59MKYpRPvopDcEB4jYcBvi3cVaJUY5ukJDCKJYBDDeYbScXR0dloPKC7VXD2yliVr85KIs1IyvnyXH2b4XwlBsmjWLw2RkcGjLz/zvlAw+53qGSzZXA0w93y/Jh2dkfXk7kkMXTjpJuN5pTH9Z0RGncPOf+zBEwgsJEC35EpzTbJ6OZJ1JW7RVUYg7p4JyJJjcwCgnjzfDYBGuAANcLHCyslqn+15hiryfuaTBpWzBekxP1RuIIfNbLsM6LCZ3dlnh81s+w47bGbLd/jA8jjEJWNoisO5Fur4Y93p8kTcjjs0bpf22kK/3+CY3OA5iumUsOTRytzFaez6bm9RWGoeEFwDOmt2sAKIdmPiXJdEdzMnpoWYrlG0FtM1m7RiunqOOPSR8uIpV615x7fdixmLAkUdKLjJoOBC/70WE8AhP6tzPqvz1FPfXs4/chLZfU1LXl+1z4qu1PWv8o3SqM4zcVlnu6pQUcvAVNkqx7cNdquriy9Nv7U4DjY3vXR3LE+9modVb1V+PXMxrcZKLHbuKx7m8nys0a3lC1tErY1b6RJlOcTRIY4OcXSIo0McHf60a3v9yBCJfl5nXVP++Va9bFYKrboQSFNpt0Q/HoufMq+0rHhpxFlRPVYWVSIEehLrDzAU2sFpjWJm8T16uv/86U+DnAMS/BvCxqC1D3lXuup2XgwGP++/eHHw/NnPzwYvXuznfD4WqJh2rXBBUGRdgNbCqjWqYT0IUxuJWfBs0cP77CI0Hzt406Csw2wcZuMwm6Uxm2qIxiE0DqFxCI1DaBxC4xAah9Ds3F5vXrxeU3gkxRjWDMOofpbPb2X0s/fNzDjzXZ7mgMSkEaqiipqoyon4qRGqUl0U3UxoQNAsIkIqDceIxhxNKI9ZRD0cIEjFVe2IkUui4x78c/q80+edPu/0eafPP1IJ0enzTp/fsR12+vx277DT53dlrx+vPp9qt2vW51U/ZtBHs7Q6siI3kjObXgjfu42jJuSba5kS/4bEjTT4cxJHlFxbdXinnjv13KnnTj136rlTz516vjPinlPPd2GHnXq+3Tvs1PNd2estDYi40yvibTrZrHCIpJm+n76+lan88pXZhlr/LMCe3XAvAItxEj0QBOCiLlzUhYOBHAzkYCAHAzkYyMFADgZyMJCDgRwM5GAgBwM5GGgrvTTu+pJ4y36Wj7oQA5BHY1PgorrsGXK4TRJnyKNRHOcb+BXFNwxyZUxZlD4llIQ+iRCGt5CQl/CYTUnU88lIvKREfRLGcAjuLYmGyqpae5dNdKL4ZNB3AWacyqL6ZR/1zwO4VjQOloJAzPsrG+lmg3VoxyNFO4rv+DR7j3tEwzGJZhHN1c1OoHhQTFLkihYqwAp4N7m23pTA31os9qKh1j3YXXFXSpp3+j6a2ZmubuecVYhHo0e6hf5NpCrLgmuho9JxyCL1Rrds4WMN2lA1Mz1Wy4dq8MIGRBhAgqIV6dvY+dFl7y7lD03hLNjhA/dctnuSyT3J5IAgBwQ5IMgBQbu0w5YnmY5ZOAqo92jZcTp+t78O6NuVvd48oK/Ww0pBS2t4b0c2fVc4b++b+G+z1CkKUrNlTaFcKJaLQLWKcuLFmohAehQiUqUorR1hjniMQx8HLNQAXLVXlpqKi8naXXhKnk2bw0u9eq/rOS8Cpzw65dEpj055dMqjUy52ba8fl3KRhGtUL3Tj9qc8taS9E095FjWlPcOmuBkTa+YKoYbdx76fU96OfD+njOnpFYcL5UAN0/4Q6ogQX3tGxAz0OnJLeSxyXmZt3qvO9ti9LkreE85r4rGrpc5rwnlNOK8J5zWx6wK2A752Z58d8LXtO+yAr23fYec1sc3764DNXdnrxwVsSoBqDaAmNLwKQHPFQOLeN6XbtnDC0GBeRKbsOu+McS5+KrpYyAqWZDj5wqOITRGWdbrIl/4agOZBkl7Z0s2EhGhEbkiE4gkORYyUdtiIyBTTmsQ5q4X7umm7GTjgXD92BmPL57dwmJvD3Bzm5jA3h7k5zG1X99lhbtu+ww5z2/YddpjbNu+vw9x2Za8fF+aW4khrgN1U23dH3nI67fY7HqaQ3rfal7B0MRMDvBB/o/8myCcx8eLUSa/mDazxOCJjyIwkkUA5XDRikcD+1Kirob1MLxYr+q+EyDHVuS06lG3zUbZCBmMB0CiCZsNfZAF7RvCsFCAgopHyV0uWXQ0GVXZbmGnWejc/YNvwSs27GDCnlju13KnlTi13arlT23Ztrx/Zg0J1elemGKxBqdONb9ADQm3VrCmoPh4ntzMWxZValir1SpTqB5Tn3xp+S3mM3skySBYqK1miEIiZSeQRnr4yRHyhXtmPiuoXyeHJpXDa0oZqS6Ux1T4AVHBUkObfI7sV3ycQTafyO9d0uCjazAgvkxoPHMWKZ5HyzyDpwoseOVGXDA7/PpzWA3X2MA3hZ+NBE+tUC+uf6zU34sKadI0FNHtYlm84vc7pdU4mdDKhXSbMc/p1yobS7UmLPc1kQiUz9JRIUyO+KTmmtWDYsocNkg6rguTz8l0y4yTKS3gfxU8LZTz1rACLUKQemFyBwJeLZV8RKVGtkshWtIXckrbTUIpQpZuKEaVrmm+hm+v/syGn1BKeFvPbIslrWdnKQmfbPG6ZnTRzd+xZDCwy07mqgjIHSafLFPe+tEhOk3GajHMPdu7Bzj3Y6atOX93JvV6tvnpfKmmqeq1RKVV9LJE2G/yZ1PZbzQTqe4WBQNe2GgY4via+LlLtYDWDk7TIuyp1ovHJCAvJbl+IQXQKByoXMzkj0dlyTR4MRPoy2ebzgdHBc7MDFvmiXiN/MKN5sUZmUJj4l/jxc6n9l/NlekjSGC3difW1aeei9qiMLv8ZkVHnsPMfex6bzlhI4GrLleb6Vvdyt/pKnhlnGXCSlvMHcv5ATpZ2snSNLH0h5LTflCh3f25BYxKSCAfBXH8ISGMvoUzwXLkpqGnTj8AGpGVv8TUXR4GvCdKCZX5QZyTiWrSfC7NOgGMSoYQTi+2mIDLOiEdHcxFYId6RloSCIzYSv4k2bXNbEUXJjcZCCm7xdAb+953fxOTM4vmHnweQurjkry93tzhp2Zb4VoR1c40eKI3CRG7N41OkIB4OvCTIcGWrWe7YKASJqkFCTOAVcI5mOIpLC19FvHwKjU8Bs2WRMZb5e3UzxLliMhQinH8YieNeiKGAG2Ylz1/JvOr3RZh1+kOqrmkKCNcvHVZNCzpbxfGHj+8vy3Q/baJMgLuPZIZJSP8lz5q0DcirDlbPa3EGiU8Fx5gNBvviP/LP5/Dn/gD+PBB//1n8+UL88kL+/YX884XIAuL75LrT7VzjiOJQhESJNb06Ob24PH1/fNnpdt4d/Q3+PH3f6XYuPr7rdDtHv7+BX16dnB7Bj2dyDGfqT+jlTIzhTIzhTIzhTIzh7IX8+wv5J/zn4vLk5NXvnW7n96Pz06P3x6/K+wk70a3bVVHDxzHmJLZcrAsSiytzokrArZLXB70lQDZpjMh0Fs/TDwgHgaiiG627aKUTkhKlf34WeXiCmETHbDpU5hP7ADF6HeAxjEB+GxI0YTeKAAxpSMR4ZGMcsdBKBMpZaoQQL0S8o/cnnW7nw3knG5SNCGn7v2j/teoO8uXPZoFYoKxfdJHMhIcBCsF26susWxxdU4y+0tA/RE/EL0/qVq+9JizHfhUynwiJSvTxcm6ZzAkZwcKpdZQ5wWD4Utct87BmcmB8p9t/jYOkgQwZSxOcLG0VJCcYsp0t3MJfRTHkBTjh8PLBBMfqFMEhMjkSosahUmvUfFWqyGUqvtQtGQFiF4o/x7H4AyYfxOIPYl23ioA6k1ZIIaBmCQM6pXHVdRQf9UWTvcGB0WdnD0XEY5EPmeTiJAqJj4bzbP2ydaNhTMbiGKRApH5GQf5rAHIIIX5gkUTUCRaPVcwiwjmFATHECY68CUo47O0oCYJeTG5j9bOxaZWPQpyTMbm1KCHiuYfYmxxjTuyf043IhIbippc2qVtu6LNFPKu/Emoj4UwpOHXB0RfF9CXX+2bdrcUrJhHiStZi66qOLJs4sbGkVbO5mVBvYkqGcAZkn+bchhZeULWK3+3AZVYwL0orYdiQbt0THxuLOi+NLjtw2YHLLkOQyxDkoGUHLa8NWn4o9FjazdeEH6vGl3fX2PsmePCC1Noa/rW9bC5+qoCA1UdseHDMq/031EiWzFHtnBGcWOjEQicWOp+DXd1hJxjuyl5vhWCYClPrEAxV42ZKSbXCPRFrGU0VOt65nFCOUnEPyYpcAHw5qQ1MHnV+vfDRFAzfkLhCKswyKjq50MmFTi50cqGTC51c6ORCJxdulFy4kb6oUspah8QILW+WJyo4BFTLm/JzPg8JxCVVCJ3q4/0JnM671Xm3Ou/WTZqh82513q3Ou9V5tzrvVufd6rxbnXer8251cLWDqzcd4nJwtYOrd2qHHVy9K3u9FW4MxKfrgqRF00v4tvIJjoi/J/kvnIpNQbStuRXkaPtSZi4lWFAAJkZQDPYOBTT8KsCDnFJZGveFaFZnTUM8ZkqCNxR1jGYRuaYs4cEcRUkoW+wCUsNuQAuas0RoRtBWrvINjSeIxRMS8YXJHJpOYY2ItzfBkUUp/WNCQiQ6QjT0gsQHZZ5OSY/LRQOkSmvwWiY3tAFDgRMdaAizpHHEEQukS83Fb29hGWagfvppm2iG5wHDfvqY6BMTQ3iCrim56aMPUxoDIsQi9ARGKQd5hUP/Kn2b9Mkhki83xmhIAM2A0/v//V//NxqyeCKaNucHY8ieNdWWFbP1J4e5CiwM5n30xOwuq68++hTO/DCBscN3NEy8rwQGfnCCJpTHbBzhKfoB2kX/7/+DhPKkCvEfM12ShoW2EA15TLAPJze/QMVeEeUoZLGA+XFM4ciJA/tE/BCRJ2JJJAYIxzyekKnqmCOMng0Gdfhf1dpDlfQTwMrGB3N4Qj1VI2l2JrGcSUQ5eGhJ+BSNIjYVO6rvsNgpNCMRZWKNyL8SHKBAoAH2U2uO6sLDNrDkd9idHr6lXG2RAEdYhNITX1j7/DkN2PjJIRoTJlNQ6m3uoiHhsWhnQvD1vAdSBfFFhpjQg1MU0JDg6MkhGtFb4vduqB9PstpeQHBEItFAiKOI3UBvMhP3NUERDsdwkE9FPk55rQSxykbN++jSuNWIeBOm3d6AqBDIUyMOoTm7vhzBO+aTuhMSMPiXnILYbT+y0EVjp8kt8RLtdidpIhxYlsSwn5BGRx1TTYD76CMnoNbC1K5xQH0JYbBIHgcC5Nuy6UaOR5WhXHFfbcjSvFe1Itz+IhwmAY6EOFFSPVIQz6QTaqP66EMYzOVK3sBsoUm4nMXrC0cGGEKgoB8+5zGZIpzErCcfaAa4Ds9glBEFYmMMyphm9oCuTMV6keYkrVx6NqWxheqntys9IZJgSxoBpC6jfL6kYbyPzomfwHsWaSUOT0yLqWuSGxFBmgCcJH6DHaqGVN9J6NPAUcm1MCPHTA20sOjy85M+Ogo4E1bnlC9lbUhJbThHEbvhtbtWWnZj6M/NDKgHgwHgsWw04sQyj+Mk4kze5RkeK4MO3Dwx3i6KI+wJanjNJPvvKsYFXA7GxvvoDHM5kf+ckhjDDvapr7FDeO44bQxYIDQIfJKzqAtX5giaOk9CqBMzNCKxN1HW+dsYBmW57emEbJjp+2RKgNzJErmphWO5xMTfm+EY9KFUqPohZrPeewRJwfiP4oajmI2JIFyCf4mD0EegLYs7NZyrWfSGGP6dLZ/1TsjRnNCIeHab2Vm2/L4udYiewCo8EZMYsegGR34XPQH6IH8bYu8r/Ghdorzl3uYRkJVAPgDzsEA3YFAR11AeZekuDDxb2di6OSNLNz20XB4NgeICAUSnIZpF8Ka1B/Ir5YhPWBL4CAc3eM7RELgnu6a+YhLY702Yl0lCgnwBhZAXQZJpGGFOcjacSmBLlPuI2sAJQV/JXMpakkwgEvozRtVNBZcCdk0ilGpnaERJ4MPgRiCzDxMa+ILryrn3y9JtrQvEkSJTtGiaMvwgfiD9cV++aN9F+HrcRbMXL37so1fYm5iVYLUkhcvEPjUpse6iTxyUyOm9+VQUKQuP2RQFeEgCJVtTnptPJtyXuKovuW5C+QRWf5oEMZ0FJLeG1jOvrHaF96xhT4X7i1h31QZBsPV99C4BCnUL6fLUiMSqod9JBI5C4vKnJ0kfn754o4FqAYdcw/nTq4XIrUdmMfoiNvVLV5k70m0D0s4CIqk87N0Uq5NO46pZ2fWbE3FPQRBU5PYrmRtDExfnK5kDA0nvWswQCTlYYTwWRYK9Z6e0TrJq7gVSfQnSJdIW+D56Jb0L+GHuDvBk2kVTGnbRFN92kXQQgasxgD+ei0vSReBW0kXS7aOLtNdH3STW4WrjDr47+Bt/8J0H1go9sCo9ryxuV5lscT/OV2/ZmHo4yE6cQAwyvIXNegG5BtokZZpD9ASH/hP0Awx2CjRBOEz8KDAEFsGHcG5+6KMTqWqI6YvKK3XZMpy0FL5gIpV8bbJdc/cvlKp/RKIDPpnFEyA2z2qlrYIbQWtns+wlxApZzHo87rAxa3JyKz6UBvOtG6k0wpRvMRUzKE86m4OVjS89+oDgkaIN1U56r+UpSx30TM5vOLZI/UYB6wIlFbhIikFVwTVnWguYkUiadkr6QHvXvwXMNcUlxA1anlVW+AXlxRQ5p2yllIKUgQuwMRRQCeOnGMcJP2Y++XGxx9AdXBHPGI97htSQ+q+KfZQyhmW/NZ6gHRXVVccj+IfZnJyqQLhUmZsJEQILmL3+B+0PBj82312rTGg6XQkJFui8KZ1kzpSl8dmRGNMh0g7FGAi67ukQkX91UQh/jGP4f9JFQQz/XyvFtHGszI/lchIRPmGB4hZaA9fGtfKuITzGYPWwwDlr8NEsA4p5MDDDFWloP2JHamJshPYHQDkw4iTkwgKjsEEhCkwZFxAW8sBYbMzO4th5MGjs2fm64LRpOnjq24G9iHEupCIBCSqODPw09ibAwSWIqt6z1Lg7FzE74nqR29jGDyu9QSuh5xgMoxK2lMuGYcEiMgZg2xz7D+evDhCfhzG+/dFuycn5l1Z2OCPRiEVTYVDCHBCakEuLiXJyzUlVoggN00L2niuPOhErJSwSCufMfGxHLOrnRIiN8Xb9oKBDcUwVUGs/64J3ktEIYNJrxTpxdmOE1kc4CRsclipHWBbFOSAWc09irph7JATBsYueQB35K/xN/lwrCzfykz2SZHlUIkypk6wpR7xLJXNRXtL0Hwyi/qN0N7AgEBXhFs1dbLtpvF7Za8onYQy3Nkot60pTEpfCgJ6BBDNpt+xKsOT0BLZQwOxgmALrfBXo+4QbTem2hcYPB8nohYZgE+yiGVgrQKOh2QAl2wUrl8SgT09sYoQ0MY8ia4jdpf6Un63yaP8Y0lsBzPIYT2ciMmFKg4By4rEQCOATsHk9kVrWkCCCo4AKZ2gcoicxe9JH74UqBL/pnrhGhNEIw0PWqeVLYSug5CjS6aVXZ+F9gIFYrkMMoXrpDAqTTIfUL8y0ONF6ZvP86bPBwdPB4OcX8H8FvhOz8qhehf4DjqkoVjLQO2D1xNUGA269P4r0Rcl87KWLS2oqPEQ09Ok19YUnARuD5w7h8qZrzqhuVF5HODSto+r5SfRDwcDQRST2+j8qZyJtO0gp6DAi+KvPbkJ5lgybQh89yayB0Jni2Zpeg8AiPZLATQs9EQY/KJfa8uFWCyug9LSSbQqLohw7CeNeem6LJS3ENXs5MWeMMZxGxBDgBzFU8ODMFzQmlDlUSTcSUaGkeWZRyhlJcPEDGxs/sEBctHAvM0z89ERfUp759TVgm9QXlMA9hu4eQ3ePobs4kxb7fGDJon7JGJqC3Gqwp0e52eWJuB13cSe7stdm3ImQJjpd6Yy1OYEnUsrprTW/eus+7hiKsveNyjTr1jyauTCQYjLN38EQo6MlRLqBCQYjIviV6h18wPAPe4DNgsCaZuJtdYDNSoTldLBCV1bDtWeQuiAB+GsItBa2w0x0oeH6FCHvarhbIKlS54MBVA5/FY1XGiy0ypnXMXMK6GeXJ3VDFcclA8+vdMYEp/459c+pf079a7nPT8v7/JpFQ+r7JHysm5xNwO2wU/d2Za9Xq+7df1rc5nraktlx23WwQUly22qjMQkIGOPme+C22tn41AjpePsw3j4ExuXU4rcQNyCmUhya+KITTgofXRqCOhuhtE1DcapNX/Cahn59E5k9FGfGbu3CFiHprbTOfL6VPuLSIVz4M6Re4YnyXNb+WGntFg7hqbnzn7Ve1Eciv+Wo5EsNURHaN7pNykvn8/z/s/cm3G0j2/3gV6m//pljO4+kFstrJzmjtt0vfnF3O5L9OknLQxaBIolnEGCjAC3t8TnzNebrzSeZc28tKACFhYskiqokJ20RQO117+/uD9vnuXLwpJ9I2VcMvCF/qfERfC80KxlnCeHZdAraf0LhSPbk1QjMowr+ByKIGChKPBGUQCWpgBP5FVwDEka0Cx6cR2TVGGdzEQc+utIR5UgH3DLgvOgk7dwI76MbYY0j7Yl/AXFHPskAhr0mEAOOr/4rNP+XQlQz3IWEzWB1LpBVSU8YrjNAAP9A5oLpLdBHRtyLoqNffvrr3GPP9KqZjIpnYzFP4G9gE5O6R601dCf0Hp9Q4bJW6uO7cxPaVm1vtzHVJYaGTBdnjEUnqZUtih/q56F/yEVP+XFN9CI2VOh2VdnW6Z+d/tnpn53+2emfH8oOOwezB7bjzuLwkPbakqb8rzRll1SExcTZvUVk5Wk89N027Ev/Abr4rXEi1Hr6JpOONB8sbTTq3vgKboO5oSYMLlhfndb7Yq3Rg67ms/6YMIx3h1cIzqs8TvXGJRvzGNKIQurMCxnCqT/rmnW6Wys3YJTpXKJsssESZXkYmjAyrJz/pmK52XCFMmeS2VGTjNjW95Y5OK3j1msda9bskn9Owuo2/cbGZ4K0fj79QLwwUHkzInRljsGeIOtpxYSDDWCeU94Gt2XQ3FOgYVkSVJZZjOX2Yhqdumn3AaxTN+3+Djvlw0PZa0Mc/QDc5hMs7XoyqSgmoASEDQqfuXR3UxJo3sNmxND9GaNJOmY0vZ8CqR5+Jcbug4Ym+RTLQ/4lTiHILEcxGIuHvkSQWz4NIKtYGEwx4Rl6eXgM3sUPOvob/gdjC+FnmHcjQZXMl3dxk86EDsDffwDv0LFDxw47Oey009jJ5NI3g53yHtbCTvekDmWOllT8e46NTrNIpR+oDEw8S9l8EScUCjEkZm7EVrgjqgAh3iksoIRLPW1BF6V9RB41wFaYO51cBDyjYfCnrGkDr8ikitdQLzCYznLI5QpLusKSrrCkKyzpCku6wpKusKQrLOkKS7rCkq6wpCss6QpLuvp6O1FfzxWWdAf/QR58V1jSFZZ0hSVdYUnn0esKS7rCkq6wpCss6QpLusKSLt/O7efbcYUlXWFJV1jSFZZ0hSVdYUlXWNK5ft+867erD+Lys22J+7ALCXg4++wCZnd8h11+tge24y7M5yHttcvP9lB22wjqEp6RSRbdsyRtKvLoZuK8ROtrxXgJ2+TePQryktZUe00dOR1rVR3wtcm0d+YkziJfV8bpGOJ+qjxvVSPgE99YnWcHquZ0T7cmfThCGZ2hYgCcB4fz4FgpJ1tttQBlrW2ItljRKJrG0mrTxehpmPKc/fOe2z8LVqRuxpjygGpqljQZJJSrT6vnTnthi3wCvWKRC03xnS58a3XhHcULsZNWmlhHK9c5YcZdXvNi2p1zCj5f+qC6UiybFiydqt+p+h/iPjtV/47vsFP1P7Add6r+h7TXTtX/UHbbUPX/Xahw75eeX+udb0bRL5tfQdOfqW2fMotWHZ9WEsr+lcnkIETFZZccPPNnwhERcrpwMk5gp0Th6fG1zsqEL6jgIJ35Cl+47qF7aLYARdCrA/hFZiHK4yGlHg5jEkATjFq4bI7e02GYu0TK8WAuCKslA3Uu0oZhTwjX7JGqPVk5et0qD1FIrNRs49hgJ2VyMg8ire36DoK3nCsqmdafKYv8m56nrYvOs/yzeZbvT345wSH8GUdMO67TMJhCzrAgvCbjQGT9CGOIzZ0HfgR596Tn+aMTjJOi+29mgUen8aNSjO3nT29gtHULcDu9VxiMCkzeK32/V9CNPj8uL+sXpxjcYsVgzZpp6lfdqhoibTiEdyHQ3cMax4FlEJ8/vbGEAhRom+hwQH7E/5IxmGXRqZxM4jCEilLoh4+rCFfoT2sMiGBUVfPkj6d96v8jw08NlpZnAJHd25JDGdpWa54BERsrb6vkvo965NEfGcsYf2QPVsFBnAV/2gKMzMGmcUpVPB6mTAuAqaaMdxq63M5qHwI9YapT8YoM8IX0UjJuxRd0uabKTfkYjzFnhVqqvOeezumSz9h61KX3v0WMhwVo2UCd3BEyYVlRAdDY9lhRHYKQX6jbq9TjdM67Lt04nfPD2Wenc97xHXY65we2407n/JD22umcH8puGzrnz6r/pVXOvZqnp4z66xUTadIHC63u8trm9jbRC3M7XMHbVd2LkHpszqJ0P2FTlevXqugWX/T1B33wUe6rrypu5GpPz+agqfioviKn+oOKX7islADtohSq89vpPonsjsTJlEYAmDFdNayUSoeZoPabM/2qRyPIPKG0h14cTYIpJMssjwzkYTnqehV47Q7W70oHn95hnrNjr6MeERe5sqyFiiIbJ7FdZqIJRIngLfutQbQqrreYvBxUFycf30P6l5BcUk64VhlaM+Brta7Yn4LyYcmY+mF+CeQp66t1r1Bmi/bC0G2UFBn/9V9LbzSZ0CDMkuU2vMscgYqrTvpePJ/HUV/2tSdpP2deJio4/A49BkOk+sLzXPzA5shtf//Swz/Rw/L3L3DCFd+ooROtnATKUwkWkfOPM1w2XuEr6vcSR6GZH7DIQ6K/x/2vmzJ+yhUc6FMyyKlkQ7FOLrh1C8EWR6OVTIvXBI2Wn9bRaLU8FZL8E5YsyAlytoCMRcxX38mh3C2xNGxZcKIarVkiAasaN7AO+GZAfsKq45CueD6nfc5gNqAtVRNP6fQ1BU06lkMIEpW9UP0G2SyvGX+EmWWj+FHRplVvXxLqYszDdc14j6dQKmH6OoqXYgLqlK9E+rustzxLBjEIQ1ntoY1ulce2G9RK3pibo1H5zye+SGmt/n7nBykKy+qHN2IV8bs+pI8znv0s04gWHr7Pky+VO7E80v1Zntm6trxmGcUqNNhni4R5cC87kN6QTal3PeCasm2K7vZFsE1H8itethLgMxG000KCz3RoT4nogjEL8rqJkW4LCY5E7EyBBNcZ9+V8VHZcI4iJ/Ah15dgV9YRldUGTNADzvkymCSKRqujWbMCfX8u1L4wyX4uOY3z/FpKIc0yBCxXFUjp9Uh6zyNyIY15+nGN/8vTZ8xcvj16+PDoevzim1PefPTs4ODj2JsevDp8Who+ZEofj666T+ChLn+CIIfujmWTxVP4bxgoPRXkynQpSpGVsHrwHEXfMH8aFOlPqLOj6FOZb89jHEEDxVySzjOVTXAjZvIGVv5EFCVUdpQq7zXPe6SEdGlnuCl4wC5YM27vEqFCwli7XqVm06rCQdbazy4hJKrSc4yS8VSS8YRBN4vYVqXGGEBb1PJWxuknKlJ47WUgjvq2emR7mIeqJprbynsbpxkyGQaTqcBmwtJr6sqYPdbwbCu2pmajj3bX9I5HCMqXhsHHNVPu5UkfVIgRTiSSkRsLT5j4P8l4X6vhVQ2XzfRKuIPiqShEL/CtRtWoIt3mBmMt4cKACP5cKNzSoXscbUqCTCaM+AiY80uDqEV0ESRyBUDkM+FBTmaYrZHyjvD9VJgPjUfuNKnUfWdPFQn0t5Zdkb71RDsIqi/4qKKTIVLqSowIfqqy2mJieaXdZSXySexF1WKwqwbDjGeUdVNYzIagxe+/Vs1yLlWDTWqsSz3JinxP7rjetX+sg3Ulprbt8t//NuEPfxbkOWcraJD3xlpI2TEHvLT6Ry1IBlfIpJsARH4P9QtRVC8mMQs3pXHsyjv1rLGBhQCEiut4WEbBIgjbXXYGwGv1N4sRrA+4TmapDrBSSW3mjwWtRZNkXpZw1xk6DEEDLhCWgnYAybuRMunuOAxSNJJKIOdNfQdW3MSMhm6QylGNA3mYJwp1fkdKiuMsXWMc+AKIOzFFYsQRfDtFzWI4OhDL1E440mJTGmY8Qyo1bZRIjrYgqy6yOibol6vAG6ayvW+R73aSTwvm+OSVkgdJHkH5GcqEGJmQf2sNiRnWMp4H4i0dbpKOTJDg31ktS0kdjLujuFegPOLmEm7tgyZzCLoXXllsvuhxgHfJ2JR74MoPhw0rc5bOiHq/GkpLQSyIPnCi4URoP1GCWucckTo+TAIS+UL6hvu5hte+/nf36C2GRF8ua3w+H+neiS2ptNaOEoyC3i/mg+RIOB8WlFemiRHlSMEhCaqeeKCYQxUTV5UKVJOomo9jYByziLEoCNREXekFFp1YdjQX2s6sFVm2RUtu384gQyq8jT1QVfyzVDj2QuHrES6+eiHeIKq0UsUvQ9OGKPT7f+3cWhnEP8Ebo/6/zvSc/wMvfz6PvP5xHwlNJzX8f5t+HKTfrk6jvB6LUwseSu1WhFlTsZyHjus54fiWhErsXZriCf6MXVNwjyIoni37wOEs8RuZ0gbqBCVrsgLsFEU2uLTEWDVyhdGcfJl+4KyHlJuWQLWJZwFdA9Za1shdhVZfMpT/HK1LgMZ8XxmmtxqGaTwkwA7wvys1JlLcDCzd5d0ZE66KsOuJI8UN/TDnzzyO5sj3MeDmyEIGRoIRU0LyRIocjQQ8vAQyfR6M5DaKhaHkko44R9iq9W3KN1Uzxdg+InACDqvBqfJzQ80jZ4fE97OEHkzbk04FHXGXpPI9GdmL7FzUiRemBYgzOo/PolF6Smo9GuFYjSLpX+FVVghnHPsTZUQ/KQ59HWOBQHBKl0JEbKzMNyrJJI+r7GF0IRnKQfUfotQYMClj7eSQaNOYoP+cZeGRwMiqyBPg8lv4ZwL7wG7WfPZ3ANGdravyCjhIoB8ioj6vxgdEkEkWW6BgUtPlXmv1JHervfuxlIMHgsn15PEvTBX+9v+9D2DmceT7wtBfjwIvnWtouHM993YO6DKqj/SeD8+hBQZu8PyVmDoNoxpIgbZZxMSElRFSmMTlHLuil53s93CZ5LhAYA98RlxgVe1B489kLkCtBDT+SXY1EkVQt6Ho0AsA5RnV5HEKNMllDEtuH0uuQHFi5B12wBDNsSs2mOoWiZjrIyLIxIfEuwvg6/2hAfpN2AcDBUA9cdIkytBxePjC0WgahxPlJvFgI5NUAqoycfR6qML9UEhbbdi1/JWCVvRMz3+uUGLJIr2/NZ0deLKA+yF40uMytfwAtcnve719Ma4dpx9g7Ojg66h886x88+3Tw7PXhs9eHh4PnB0eHxy//B1pO6XTv9d6LFy8mR8f0+OmYTZ5Nnr86BKv281ceo5NDn9HnL149f+k/OzygTw/9w4vLp+z4lf/0mB4cvnzhHTz3oUD6jEZ+KO78HgJd4OIBprKeBbwf8OH8Wk0UK6qH8XSR8dnea3RnL1kE9LCPDj4dvnp9cPT62fPB8fHz41dHMGztrId+95AL+PUeB59EVONDuHW2GILf/xBTA0NaVBqA0SviUAxWECbD4lE0axjxxKDED+NpX32Jahb0HAeeyUI8rRQiuP2ClVTaJCqK+zqYaz9oGuSKioIGeci44NDnkc+8EDgv5LCVjIYrRo7QIQLJVLAIYOcYaU6D8DxKIDWFF4QBHt1eoQCckmllg6T47nkk6BGLBOsgj8XfCGgODw6OD45kTTcoD+2FUOxQxHKQIDqPRuIQ//5lAKxjIJ7wkeAenS9WnqFzbVjfLZfzUC7GsLgYQ5zNMPcp/rK16qMuQL0d328RcM8WPk3ZyhaDfcohUbCmtyLZNBqGrUn5y7IAdN4X1LZvb8oUDd7gi+qOn+D7ClCf6fdtFS9Fo6iwILk/J4ZdiFYwqxDHpAlaT6V59KeYhGWYiNwc68rKxnneWo9wxkh3eAhlzwNPLsC+aFWuw/4DVHUV0MnKJRG6ex/YT16/wHPakY48nNZTeXPAp3EGRpRGLd/sNOyVdEUP3AmrJ4MMl8jNg+lZarx7VHi1qDfwFZ1IlQSMe9e93sUn9L9IDeqXxlIhiQQQdRNKZL6cgTpC089Bc7Oou5hRPis1aU8/U845rgd+1edQQyFknBvu9331mVA2dXrpH5e2JD/kb799UqVOQPuSpTMgeuIoywxzmmGUV1cLV1d58QOJV7/rEwAmu0qAabObSXcnlC2ARrcXViTXXwqdDVBGkkIFHFaGNAaB66DPXGRpX31hYpVThiJW0VKmlLiWcNDC2yUjjfIdTONM1IwW+iSUSqTq6GHBhLy/Nz/1f/v19D/enfZ//PXtf/c/npx+Uv3OGPUtGuRPBc1gJH3SqFpzSVPxoVHKpbQjQaTTYUmFp1AtDshJiAkSUJrUNBBaQGRZsKg1qW7sc/z55P0v/Z9/ffv5w7vbnCqUKxd62Y3PcinAV2OnU8bIPVF3Sbk042efJGNp0pH3SEnhrX+3f1Z5X/5w1V9cpzNUBJh/KvP9HE3ZZpOXlM/ly4uQBlHxaeylLO1zqPAzLz4R1sH+nC4EHhKr3TJrLmliV4CmV7LEOyOCXBpO0lwaOB/Hk5RFFUvmE4gwXCQBF3JXyfp/koJQBa7dEVPHa55xVJVC1SK0Tkd+7vPjKz28Pl5gGShYX+KEjMBpbAiHZAQ2VxgIHPzBv4yT/X/7GHMegGpV0uE+LNRj/gQ0q6/rjCLKktKrGEaMJzX2lOo3+id1PCo/mOel3DScGP0BnpnyG+apKT/Lz82oCS22Wps7Yi/zYBYPEdjT+tKXw9hOLVhr3bqwdcEx0BY/09DXWkJLH4Zmb2TdH+JXzG0oCSKvOtLIBI6pgrvgDIAHPJTWLaCI8HSEWtyRyEL4ZEBAIQQaHHC5GJXYhzB4jWRPzW7R0nHyH0Iays//enOEhtQ9LM1QqO3EJNWkpLa6PK2C/W7p6VQcs/UR6lyJ6mOWljjYjRsbpJWhQciuDupheV/spFp1kMP+G1Ovyi72L472uoXgTpldHIEM7d1EEeG8ZxdEwOD/sCSNTr53YskaqY6ke9vpAVdLt2wTe1iUy/mN3QqdRP+xVYmkcKqYq6zQTVTSeFUkizG/rUsY87bwTm3aD2K0JWpSTIKEp8bPSoDBiFZpH5beJMZL1AOxOpQuVVBGNqGTSeA9LMJr9BdEbSEvZ2Z+eGMpUSWIRXqDuSwXIV1vuSxGW0+NtRSENkpooDCqLEqDsHlU7/JKFbczJpdHoHI1jbvrksW5VAIulcDWpBKoOT8lZl6no+pyZfKmqhHfZjdL2um6JjG0kZ4dAc8mItpWBP3QwsOLSLYlAViv2T/LhMnSrGpcpnqXrLfmS+Xg1Pw25ElpZ/El+V1+/HfhbsW7ONbTRbCvR65uQV86bElor/56IgOLpec1KGcloCYnBWBGoSRcxCWPEMamkCk3MOHfZWg0HyIW7xZ+Lh3zRRR6Cf6iW/6YEelirQO9I4C2ELQ4DmPvqwiY4zGcXbRJQiBIEoch/DGm3lesjBaROPRzRz0R2U4JZ17CUswm4M0AX9ud5DtEio+vF5Rz4+z3vRnzvqpY8dtzVCuysmX80fJ75/DvrSRLLmzVhnFF/Z4+QGBx60aFW+TSgjpuRCW2/y3/A77ca0/yYrJ/mSyjhv0XU040sn98kVZfFaqyihpMBVAFvFYh1jMitWTeEPBMCWWwp28iDpEVX731QLl34SA0lmR4rwdcDGsz922J2gyG5irLAr+rXUUemnVZ2IpkrkOqFUeI18q5sn10d9OpV3zjurSkXzGJLlhxayiuYchtILfwFujr5Iila42N+jpSeC9IIWyog/I7BOVrNvQBsg+nINwqBeFapng4degT3GaI9xJwF02C6ZQlwmnJ+IG3uC6dqV7I4zdJHJFP8rMnVj6I6WbrvrBmJntQPLEz+yksnONAa3Og5sUo3KR1rGCqIUvWY93F5i1g9QdmRzicObmVJaSHys5uOGRQOZ7lB3y91GUFZqWTFtTxq8/4wsosS37uuNZtJQrYFHHtZpaR2+uYqWOmnZlp45lx/HSb4klugWGtG1MiI0U4SyGkq2tpTfU6Cmv62xY5LX+tig4LzKsfgqsHUe0KS75IHnnj7iEQwYaJKjj5IDKqYcAhqiXeqHxnD5C7LhX1onbupoLt9PHrktPGOrIdoZNbHreyk1LIOsEvBqlsFUGgkGJnOoxv2ynxR5qWa23W0+LCy9tDjdHRK0sxeWoYzINUuO45Cn0nidLKhw9Ac2dPNHHCtpFRWEdmyRmKd82lDHUpQ++VLHLTbIv5wTqmIvTSbRU/kDvouy0+qQRqygdkHGcRsomSbswetgl3TWTqjyetTTxA9tIpwE4TT1w+p8BaU4G1mlYKF3+5spat4UvFjXXSk5OebqCkpSbo7fFKDfYZyMFYYBEFDnHi+3lQSAfe0PI+BKaIGG7MhwSZNnT8CaAvzKwkvsYCIwgiMQ4FPkBImM4gdCViqhMKrnkQzd2DzGcTSWXOJTxVgUjnUfFKnu8hIZLFTICH5b2I0FBxcwO9s+H1Q6svcttikibEy+aqkidBlvpwRe9vw71P79byXPPoVXVKn+JYXDydqhniDj0RkB5eEyzPcY3xC2jbVajyVtlpe4Ky0kl8UHz/XoYUdWCia5uMRBf9cRZ+hQ1u1lRKzWRBZhOfVpWUOsq2yGPzOdkC4HpETKgHShbpdK8bUmwvjiqcG5PTimx9RI9cKjaxxNvPLJkyIkb2+PSnN+TF01fPoSgX+vvnn4jwLJ63VkAAQMpE4ClXOdCh1thHxdoDvhLjPo8+AxF6Df/qQ00KMQqC2crRQKxQSw8jcIOUkwsaZkyAGHmvBXsYyCZ8FZZV++EIMpmP8P0zOS5Qyap5qaQQKl08kDwsCJ1FKvbWQY6bhxzyzsmO8aKbTc/hXIt3/rLRblZSAEtFSxZ+dTjn9nCO3jutFnewp/5gOtizA7AHMce6oGf/m/iH+HWvS/Q0RkzXKySKQdOF02cpDDGPL3IGTSZJPF9SIyGSatMUSsw6rcQ2QASjv/xobbY/o91C1sIkHMq86+UsLit3MDQbXS6y2ypy3izNBTjbl/yzPcC7OEDHFHaAKWw6xLtwRFqjvNF7spYzgF8kLV0Hq/MkJdPgAksgF5Q1j4XYFs+DNGX+E4sM/LDMmI7QwmFZn8o6kev2VMt10XQPmBU5c+zWmGPXiw5fLuRgiUgDcLqTLqlLRB0YpYciX2al7Ilcg5QrQslRwQp3lGDB8ofFQZeJBLhhz04a+cpNeKVwABcH4EjnHcYB1B/iTYUGLBkR0IlmWqIDcqoZJ45orm0C6lDU0uSbG6zwaDa7Lh3WAQFLWYS2lWMUh9caEECMeADwtO8eEFDy8e+dR90DAkgxHuA8cgEBLiBg2/jXmjEC2diPoTBlB7OLHKCyvugv6y0vKjLOeLWkBA44FtxABYJcFp9dEN04d4k4llL3q3VzCS9uRwulT/bGU1LU7ujDEq92lNYbFHGDdhS/Gzmt2FZajSqmvshK9y2pKWqJPrx7KS9vxYHQLMMUCyhonYnjAXYdtmMAu8IA7Nv5sKi/U65ti3KtC8NSqrSmwldKkxbzOlZiz+5Xy03eRYJXJDn3K/EUx0ZuLqdfHafATfGbabbapVmchT4UD+nO+dto+hVeixStcvgTHMuEXQTskg+XGNwjTj6Kz8jn0w98w2Od0JDbBgs/8ZQGUcg476csSShqLlVVt/xKw85nKfOHMc6BhhU2pCb7pbPiMOYORuwQjKjZz4eFIx6wFLluoStUWrf5E8BL/TCeylxT4pu6au+f5FOb052qH4wtGDEOurik4XD3AHl3p4QhuL6OcN8K4YZzunmabdnGHaHXKNB9iKebLVriZLz13NLwFK9b0jjnATyliWACBR5wBj+bTKDCA/ANCPpFGyrm+UiYx4ILxgm0jJZeduUx/IAXY3UcO6jQEbHin4QZ3LGD+8oOLNvo2MFWo/qbIcNIV9dE8vvfulWozam5tPdXyHnR1G+l5+IVTdAfMLnO+7vJWS3jKrA6V7i5aq+OxD10Erfp2EGkO5xxcKcarE460dG2j462baoQaeCYgEt83/yu2VyOmWfIz/JNi3u9dIQ0XH6da9QSsRPG+t4c1TO2e4m4CdvQdoT4OTPv/TLzFunVOhXdJBmUtdzq6OApW4TUKxt7m2ih/KIbMSSngthw/YSTjzTwwR6iG32AJPM2TMC4N0PNMjuTT/nJ995exlkyxMoUnRUF5ifdYyWkx8FWsoiGsT0sHrG9SPgWCO666SVV8Zc28GovGVO15P09f2KxXMQTRYfVewPyacbIJEh4qjMnybyGaPGTYTgh5HzUbzwgwtw/KvQorJ1SpCqktiiuNmAEkrA0SyK1aFyozT0agZdKxkUCSUry2uQD8n4axcAUF3QaRFTxwAphz1WkPptQ1IKix4o50gWdtozxjbDhQmfM2k0QpQxKEhrdHBa6YMmwvZv3kM4f47BaO1rGlqoO8M0xhOKV68IS7ANbiRs8cAV/D8/zMnVOddWIdapJqPAu+KjPZ3EiK0vIkUECrdVKnPaWsDVslolrhuBEvXsi6hnMfT27ryZg2SKMqQ5eLPn0wiN1SiwVufExLcEGnVxRMC/McBqTN7r23SNOIpbCMAbkv+MMmd4kiHwRBUzHIi+jylwNNrQ8sD4icZYQP/b4a9JeYE+hK+2BKZL+qnbV1FXz+w8Xuqj0BMMgmrEkSJu5NoZ7c1EF5HyPp0ngped7omibWFOh5MVIboy0FhHYhwcHz16QYEIg4eVIdjUiQJTzBAkejSCR9hjDvePwgvmETiEIKjXBpuiG+RqXgveZViD3yOUsgGSc9JrIxkQ4unRHU1CV/KbzgAa8R7JIdIkOwnJ4+cAgfS8PQqmzTuLFgvlWxAILgvnpJGeQKwQEvCrH2/YtfyVgVf6D17qjhGze31sAQ/JCdZOQrWOz5BSQJ8pVGTSSCjgEuCwCtAQOfI6CPzJGciKswywNUbZyp9Wg9g5fTl69ePr0Vd87evmif/zyxVH/1dj3++zo8Okz7+AF8w6PkGRTH6FCQ5CD4kC2eegOv+3RLJ3FiYJ3qGn7P+Vj4Hd7PfUGzHbv+OClN/b8iX/s+/T4+eELNmGT44PxwbF/+PwlPYSTh17G/hCX4+jg6Kh/eNg/ePnp8MXrw1evj14NDl88P3r+/H8Aj0K68qDbuzzOEk+kYQkQiBS2ojiL8qa8g58VNYcZksuZKungd98cy9p02Qhj/coDe58fk7VH12FruozW3D7LpYvMAeGFkx80D655b7uMa0a5jL9pJgZqaFLtIUN9CuPLqUGx4++lE9lp+iHlKVGf3fQiqEtQqQsA2f7xmTpHaoiC0TWPC25UDiyy6GsUX8LqiN8vEwplV0DK0fFHgN4oB/DoTYZeGMi/hymbLwBMIdRL2VSg473e3h9Z4H0dMiUuLUJ6DZJJBNBX0n0v2PvSZRW+W7YtyuZjlljc5QD0RGlAQ70g4lVjQeS3xoIcdtsMwHWw5LydUyi8t666QLYzFBmgens0DJfICKRHASB9rX7Ly1OY0/cvmBcLVfnNvIeldApM7yl9enR8wF5OxseHx8+eH44Pnj5//vLw6fhg/HJyfDR+yp57E3rgv2IvDtirVy+fPvMpe/nUP/Bf0hevjveAOkR+KOSrPfS3gLMEV3Oo8PkQXM70YQcRxR8aX32zNyFFmZ+v3wD6ElMr4SKcQ/ng/TvlM+arsFMFxho5//qL0I2MqlnaaIiu0Ktek8gV5CVQEiepoi9SQSufG9epcq7zKYpVrT09clG+G6ti7ER1cnlcpBeHIfNgHn3VljBL206Abd5eGICqZg4BcuBmjuIYaszTWEp4opZU7rDYRk67bEb5FJaH9gs8V8JDnvfvLcR9hoz8ileKCMEggN5BqU+FQzwILZH4PkqT60UcRKJkcOs+dbwK5YuwqZMVGZPe1nMl1qJunmomeoZih1DSU1vRfITUIldYXT3tlfS1MMuuRG2lVbDxYakMSrIIaplUV+hUPCAF5VkpEY2xMjXcFBgVTQOh+xyiObTqRgqmcuBanijVktJkymAveLaAXVE2R6WGlUMekB+p9/WSJj6Wk5MdhWCwvAJVQSzEezmNSRyG8aUotxRwguZ5VFKBfohOJnA7O5MNAx0eHLzG/+sKC4sLMgnp1HILf4KfhUmQVRIleCyB/SYTRtMswVp61uXpdB+vutzFle6dJIU2r+FcfaOULeJYBVxBv54spBdE0/PIRkMZJ49lWWEWJGTE0zihUzY6j8bU+8oi/4lBVaV+2iSu5FM8H/M0jph/HoXBhHnXXpiri0DXJ6tF9AiPSQwm29AY8Xn0eCSlqRH2BIooWIdo2k8TGvEJS0ZPsB1h6VUF/8pruUxqR3EVh3O6QIapfWzKvlZSvBAvdLiyBjvxFtkQzsizgwrTUI9spJTOQT0OxPTNx89YHMm8TCjgZaBii8g8CMOAg27NN1lcbk7Wg3l20E5SQQwMpOgytKI7GF1Kp4rOl86S/lhcNhASi8ACFXLMzw9oF/Jw0VWAL3lbldRTJTc5wz86iC5ioSXkzSPhKY18mviGzDjOgM3AL1k0lmKdfm1Fqc62L/Z8pBa5T5ibcrBapQ6l/K6iaFeCVbnEpkjJmXyMF1mIqhi8sJdFFTJcdW1K0oU6aWQokcdh7H0dlE7JeaTIgp/AsIrD+YGMYP1fy1QiI01D/PgcLRkgUSTBOEuZ4EkBKD5xzoIirJHcVdVr6okgo2wxhKtnv6VwJ0v3j/AFQOk4Ir8rD0zRzJfH3Y1roEQAPcO+IDf7/1u5koqm+jCiJ803/fCgbDfP5XVTdv9ym8b2rU+729l4v5s+eF0s4etm0VB97H+T/xrKMLxO3niQd1EZ7YTFpyWapM7QfsqAokA4tWgGvcPgzgl6KEzmFG6zF0wCz7SJPtxAk5KFO9/AjXaYN7tsQB9sv7J+vhWWwps30Iqy3J0MtA3jc05rzmTpTJbOZOlMls5k6UyWzmTpTJbOZOlMls5k6UyWzmTpTJbOZOlMls5k6UyWzmR5v0yWtSaoWzU7PbwYz5sM49xGo1TXUvEsuQg8BiYp8S9pk2LRRZDE0RzJ7jfjL/ncUMg3WamMD0WBMJH5J5clrYaqd/lXymj1Rn/RVlVeti1y/kTEGMHWmKWMld6sXUo0XOisvHUb7dBofKlCZIWdKtl3JLG2WXUsdFwgAC3JfzuPCKH8OvIISgqPZZBjD85Bj3jp1RPxDlGpMSJ2SU7lqB+f7/07C8O4B14Wof+/zvee/AAvfz+Pvv9w3piksjqtHcnAY9zFh07b2wl4gMlTcoDQTNUV7R2YxHaQ08Z1UqyZhHeRNRLeUp61JYhv6UtHgO+YAOedvvmp/9uvp//x7rT/469v/7v/8eT0k+p3xqgvM+qUxYE8F4LSAFG1qTI8Gh/CBtMgApVBacsDCNjHJZB+akT4jwzISZiyJBKybRrnQqxIQKT95aD9pmh3+xx/Pnn/S//nX99+/vDuNqfKQCbyM1CsbHqWS2Xi03PZx0pgyl7OIi/2JSudBKFSO+Fnn6T+w2RG9IKKOf5FzKpHUnaV2n63f1Z5X/5w1V9cpzMMhDf/VNl74ewWm7ykfC5fXoQ0iIpPYy8FIJkmjM6LT4Qk1ZdaANN1oGHWPBZ1tbq6kOiVLJ6pk4igMglOklgmTh7Hk5RF5G/0gkpCih8/IXChkwC8ZKpZKU9SEjIwx0J+AXm85hlPpR2Yw9kDtUrCJiwBUcNXai59vCgnI6j8NBSfj0BHNhrH/vUQDsmIjK9xIHDwB/8yTvb/7WPMOSoIJaHvw0I95qileU1Gjadk1CMj+zmBJ/ZPLd/on9TxqPxgnpdy03Bi9Ad4ZspvmKem/Cw/N6Mm3aC45CKNCcV8JRV9YCf9n3kwm2h8FgnTivh7mLDJkLFD9uIV873x0dNj//DYO/b9o+fPX748mBxN/KPjSnkJ3Vf3En9ZCz5fH8BKLKIxrHAXa0LX1UE9QHR96w62W4N3l8hwuaI6g7M0Vb4NHRK4V9Qa6vMuCo383TZVhmrWQent1GWIFO2lzbopcqnaXyJ5fOUYPTia6TIKtmcUvB0yb5DIVr0GBRv/EiQYP7AT4Y/waCkyXPhC3iANrauEOPdoUZ5pjjTfAmneTJb6DZDfDoiabiuXsI7MkhsP75dLjWemxlubLW594J8TTTrxLHAH7ySZ6Hrc7fX19Luqvp5ZzLumyB4nZ8ZLdaX21Lt5zXfJ0eSQ75Z3VUH3scUdXg9dLI5vREuF14O9ljJyZztb7V5v/3K39fbqu+lD13ihNlzlzTjreDYapXt971Cot146UYq+/c6donn5Pt65GqN99eK4wMybLBecH8ajzVcNtm/oA6eENaqAbSOQXQqs6bMjXHFraNkbfNiJnIlX7wk5u0XhsHBJu8mDctUdPd0helq7pw+cpG4b7exuSZL/rTUIQfkTOedqCbT8gaU6E5x9tVrbRDpvvHAXhCREwRzu8M0W8TI7PejtzemV7PXgoG4MceKzZDi+bh7DR0Fkr8G5h4PfqSANnIyvm2t06PHs6UBODClXsQfFX8UplX8YuQxk1NuXysCbR32GHrJBIrwRug+Ue8YIKf6FP35ZpkhaDheQxDoetwqPG0IipvYVQRpRHdmnOKWhzBkA/knq0KrYGQmYQJMi1GDNiQXQQjO1hCuaRAFVsUGkyggyX9RyzHtv70NRhWpEcWUmC5aIXju2fwRBXCksy7BxzVT7mhHpqlNQW4gzmngzklPslj4P8l4X6vhZgm/17PBVnJcOZQRyjZFzMC5Q2Tcv48GBwqTFXEAr5W0QN3nv+1rg6eCwrjtNT3SH76C5kyydwb17JijMEl++j9AZMzxjyYVgcBtERNsb6HR/Tc8rAb/VS9QJxipPtUUs1k+sUJ9i5Ege9LhNIm+JMQkIj9OFgM4ivbpR8VgvoUkvBIapxPwvJz0r+7xDFTcvOWvCvw7dt2zlj9Qnp+Lkkj55H13QMABv5gVUdaQpvZFdzRNLfEFZ4AOLpukMpZM65lgGWT6zyhy5YCE4vR97mc5lMsySsIq381NjfZZnymqeHYbui9RR5UCC8qbh6PNeK9cQgp8h+d97MXlxepYzeyPzFWcGcr/Ife1s8TY+X+PTT3QqdvYDxPqv0gKMXas91mzrE52uMZdfx4DLJZ88g+MbRNNTmq6ztDA7mYquMDeMOzcpWeG+LEvW6pNQmqHukPosDIs54m6MHmKCTN2/TJe5Wqy9fLg2tD0+eGrx4IyTceD7LCJ9coLDIT6LIONCnIgEFoRdeYz5ImGfo5P3mU6uQ1jcxV374r6ywMw4moSBB8BEp42hIeTyuCbsKuDpzWDOW7p1FZkGnOjMRFOQ80WHpsl0QgEXsZLVZZB7gl54X9a/0eXR/SxeBMfAUAZj4gCNvC84sIDrsQUirQ44I/JsOmU8lQXCvVkcwwPiBxMMoBMBoIPbISO9VeiKu9grXux7pzK6I9vZZmobqP9+E/9QNQzqXB3F7xbtS8GrscaVMadNcMPhwEE+L8p57AWobNZplchjlSynJ3Ngomtnj7DUGzzZFoObXrLOndWm4C4mxFIl6mUi6fdvAT0KglcJXzXGM4mBEDab4yYEx1T1uCPsgkWiKk6MlEGbgFLw1tOByyRIB+RMpgtQwRNC0Q0kWn01p9cw9JBNUjJO4OKUK+eIvJwLCtutM4gyH+KcRZZX4SaqTkyS/4QjDSalceYjTGdsbrWXKTL2XV8dfYyKfox9YJ593aJKVNmm5SpcgpW0XCv6EOx11tf8HHCMYI8x6xqqboqaxR0HR+puks+nH/KZAwiZi5UpIqODp7eDjMR914OzDcwKi5j3FW/L59MPDgztIBhaRz1xvOSXUsUUpz9hGsX7D8WqJrlaQ9rtQbMNO8ojVSjBKIWd8JkBn+o96acstWC6PLTdGvUuo7GqJaa2wby2bSits8O+M5HtmonMQS4HuRzkukeQ6wECJ+f2dOduT81pNCBg2QLRYNJ1GO0jSyD5GRGZC6EQlfBQhpq+1MAwLC8OQHKShRoXVN9kkTej0RSyxifxXFYo8KTX6AUNM7Y1yTO2COu1u3aVduUuHLzKzly9QuNzBvIJHsi/bLijrjk4cIXCa/JZrJEDx7sGjp3/2C75RUhR5yOQslX9m+6r59l63mKb9Fur8xK7CR8258CyhZ5n7yOeTSaBh5UFQX0I1xIUgnFC/sjilDontB0gts4JbQvu8Pq6gjZHNtNXyvmyOV82p0u8P/Th3ukBbz0l4N35yIkUgDUZeYROxqJwKygiGlRusNNoqk1EtR3MXov1Sjop3jhLZcXXINFlsqSujaBpWKfdpF5KOFJF8Usx1I5FPhKLHhlnKRGThGrIESbEBfoJZElabMmnGOCiXWsYRDxl1O8hWYOODN2j7sYpAldQBN6hAnBzEZ5OQ+c0dPcAdz50odFp6JyGzqF3p6FzxNZp6B7GHXYaOqehcxo6Rx+chu6+aeiWTvtqRrHuLwS+bisOyAfqxQEmHqtkhf2o2qlNC6veEHlhXfhDY5Cqy1K7rVlqeZhNtyhZrVESTQysae2Eqro/x5JXkwAKeoOOW15tAi10LVBu1kFbrTd1Cep7656IV9MWp1F1mXhdJt77nIlXXuU1U/Ha6hgUKcU9r12g8daNxaysAm7HLKUd6hkscrC4Yn7bCiqVuVwsqW7VgWrMdStfcti0AzYV1QeHEqDwMgqoHYZKqqIAgGpgf0w5IxjYPdXBM0DvgMpLrQSY8rFb38LdLIODJoeiyZXHt/6w2izb6tTdRfri/FpsPH+xmpYDY7dg3s755c2U/dGUcZf45d2xtbVyjmltzf43+a+2TGQVPqkTa1SSktXxSZ2VTL7g2GJB916XIutSup0YSha9ZZsbsdyTypB7KMz3YOSfTz/0WQTacn/5WeB/1k+epojIlmZPU8O7T+nT1mGya+ZPa6hAvJPcYpWslksxkC6MY6mMSJoJWNIicfNGtpUNNjgHvFXOe1THMxoTHzk+0qz631o20T09k5MAdkECMHfyoRD0+6oua86LUiHmGNZRSZFSR86bc6QYxKVzkhRH/O8n8e+gzLq7hC358b3pjC31PXVTlJm3zTHJe80kC1u5U1zy7phZY9BhhZdJByhL/GE7P6sPQOzG1WQEojJlOLZ279ias2vdnF3rLiHAxmM2HbveBXZd2sydYtg3Wn1ng+x9Mx7LBRvYvpHAfa+zK7OZ9b3RrZm8NZqv9XA2mpOOJE7Vef9hwYNxxV7a3da8FY4tOs9b53m7C563+aW+YR/cAvnYDSBWwAn32dRgQqMNeumagKvVY9dYzGbn3bxVB7t2BnZtWhtTp+oALd4mdB3GIbxDd978ysjURChlzbMwDcAusw9qzz5kJ0KABZsB6/76294kCBXGwFF9kozEHBi9oGLmf5nHfhayHknZVWr73f5Z5X35w1V/cZ3O4qj0p/JwgdkUm7ykfC5fxjj24tPYS1na52nC6Lz4RISl9+d0IVCiqGPRMmuOjk8WgF0D0vRKVhMD9IgYwZwueA9D6oV3mewdAu19QlOSZFEazNmAvKPe7DyCnXvEIYSOqeh8OMdiscVVIme6YWjlPBrZ5z0anEf5Ka/ABDgeFGIOx0FE8Z5ZPAV5SoMoZJz3vTgMRSxjX70nzNDm0q50et8IFWcZf+h2v6zokp734ASWW9TjFTDlzfqpGzusMCX5DTxOYRmyRRhTH24IXqHzyGdeSAGxXDAyYleLOEn5iEwCFvrifkYMWNc8ThCbJ2D3gWbPo4R5ceQFYYBnpScFLXEc87ST2CApvnse4UwJiy5YGC8YeSz+Bs5IMPPH0RORKQTkey+knEtnOhJE59FIrNPvXwZwGwbSzU5e7M4nebk8PY0oumPKHrkYw+JiDHE2Q9U4JvG5eVS+HeD5BmIBTD3o/rf8jxXiBHKk3hoz0ITUdfjAogKUHD6/x/i8cLY2N8682dJQKfn8GYYr/gunaRJckcdSgUlCTO9EXj7BqUBLYZBCohVyvhdCMt/0fA8s9TK3L3iuCQzFIYWEJxykZaKH0hFdyQu29oJsqcO+hW0+IFXMrZvHurKIjdVBtlHfzq7/JjNoCANoYgONEQGONTjWsBOswVBfRV6Y+RUrXt10tawWE/kljmEkZHw+Un5n12g3KCyGMh0o0qoXJ45AUOdCrsD8fUpHoBUO8CtE0VEfbEMXuChzNqXja4wTiotSDQ/+tOx8nplIDhaktaUjRZxgvnOCec32PkB4sQuWHgwwuSlJVZBh2OmuASwmJMFvPogmTGjyETOPiQddMAqUMiYjy8BGoNDh2QIUGMwfyOIhXJqfqugF4ovhQF9jdXTyt7NffyE/Q9ABEUN6fPrTG/Li6avnTxSNFf2Y3EW8KhrQQMno4v1bGFQUp+bAfpVeyqjAEh7KQTRjcMTyusTWziy+oQEXCmnFfydBUvzKYbT7i9Hui3mtcnfSWFyt0s2xiBDkJCJsvgDMJJIBeIVra9wlVLZGkNIYgtM2L5o3GuduJDLJ1lXXatKwyg6W7Swsq93gqrkED6KzljhryTYAUBEUthoCvWAJFg6pdQ0HPybBsf6uXq34gkuOZrxQ4weuenPZBJ179Sru1fr8OJbrfKqdT/V99qmWzOKmPKlzTnO/lWqap96YJq1DCRD1wxupHIfv+qATMp79LB3QCg9Xqh1ifWbr2vKaZRSbrTcyuMhBzoq+30LYLmAqm693EVQ1+3nLQTlY1dkGt7RahxbVImEIfSrbF5aK4izyOQhe/weS24RCgT6ljDF2aSVtjzwGd+JBbZDqZTxL1aF0WO0W1CP5Ht2ME6mmMG2eo8RQhYCSobsupKTe6J1H3XUhpKgKOY+cLuSGdCGdAcmOFRrrxPjX81tVPex/k/9q800Vv9cjCenJ1oIktB+qfM9gUw4/VPFDvjebG5Bs8w69d6rYZCWvznV4/s25cpaZ167Lgm2kd11Ke1vkdGM+nmXKVuffOWVpPTUFr50WUtroy+nIqyOvd+oZqcjgvXaLdFLlLkiV5k4+FK58Vxram1TC3gEoWMPd0ipg7S+SGALI0cfSqrCVL9Qjg4/ihVaVLV2kWYJuVm8+fgauMmN0QWTzwk+M5ryDeuhOEvAY2A2Evsuy9ExhCuaXQQVBKMQiH+vHE3lnuQmCRHfQ0oRRGA+Q7TGoYmCTcqdGuag7h1MKizG+vgNgwgvceHwt8Ac4Kho4BJVVlJTQSDwhLJjOUnDIS6iH6l/ymbMSJuEMsg+04xHF+oGlg8PsWIVPgMus2Wxf/SzaV0eWljGFPLOmr6Gij+jwCNo+H17GmtCmnpzP4DmkdwhRQzijcE9AtQgfiDvQLfm67ZDlrwQsP2riEMjbq90B7UjE3qp8z94iNHW88tc/Ut8Y0vHBYfd23gFTPsnSmfjy6cpfHtuNygrg06i64T1Nwgi7Yl6G2tkw9qR7GxqoiruKoAZO3yTOIv/WYUBv7/jolX2eOamU54cg0g+DeZDiqNmVx5gvHHhnjPpM4MdTlibX/ZNJyhIrAM09ZLQbzAEM5L/6pzRlH6D5Pv7/lb8+BdwSyQw2K7bA2TL9f7/1bXu2zNXCg/0+SlkS0RAKqGEFur1ny1yOwvX8HOXAZlNQUjKlj+rY1cMrGi5mXVwJuwAqhX/WBVV5qEqdbkUEnDRrWGRQytKKlnpe5/QunWoXO+VDu/JBhlQ4HcSu6CBKG+pUEd3DLpeQ90WYkzoNXXnWIFSBiyvW9jKiHxtkdzMUsoXryDDIEsdrjoEscp+V4x+1gG8LflSNrx/56JjkDvqOdY0U1GesOTxQnbabjg3Mb+FNFy2r72mZyECHCnYBFRT3si3yz3m7OW+3nfZ26wDCuoQfTsL4srH8TB985vv5q5UYQ6AxvxmPqzEfHN/RTchkDVmyjE2jLgiuQql1eEzHGLfmsL4uzde1J+KGmqP2TkJckUkQpgxATb5KI416KmPQEvOcXn1A88Pe6+fHOAz1Z2EgK0DDlVzNPsjQr8KJIGMWxtEUDWQxoeZOb5wJ14U9lcPnfFbd0Zwn2+Zf5GXYQv5+tUwbbs170f1BidtvzSA7RYyVRgUcayiOVaX/nvSy9Ydi/8qnVWfqhlJafcgWjkeQ+miwxiP4vbcX+I3fZlngQ1dBxFMqyGz1fFDfD+Ao0fBjYfilxfze2/tHlgTcDzxxgiv43Hgqi2rqfoX6DNzb5EkHO7DQj6UAKSDYaUDOWAofCoSi3wy4FjLgA49G0sZnlJqu046xDJaD+QmdL/Z6exlywCgLBf9QqziPfTRDr7UV9n1uJjuCiAgFXvdjldiGCSNgVxAUK5a8w5FPUFYofmU9+GKXh8IT0W9G0mOwfil1AaBp+VWPhIxeCMt/wDXFI0EkbG82kVD3XHuH0iSYTlmy3NaV9r+0LNgX3qzCFS2ekuLIeuZVLw3KvHwNVGXZYOYKpfOyhMeJdZEWRQqYf2NGE1celiKBa54vSoTaoBbmohqARLRYbP9LUU6rilymjNUuKklCbXASJSrZGPH7aJGl5O80DHwhlqCRbbdZbkcua+ulxAP1nOUeweWy0dgO2zuhIW/aX0MCLm/1JoWlHJ7frP7Zm3xkyTzgKKCc6hl/08zLi+cDL4wzfxLShA3oIhgoueZStt7wSoIdfZc9hTQ6KQhU3/bGGQ8i3BKlyEhZskgCrlUbk4Tpfy+SWO/lpiQ0JQS1RCB3kMmEKRf+iUS4LRV+XzzTgpol3IjLSCL52BaQYb4iXdbiSHvs5w5ayOcAuvgxE3pt6dOPChU/mFxj5gSVUI3z2AuETjUuMcs4EfxVPAsaJMDCcqwoyGydyGRZ9p2m0vdWMKpZYp7SNLMwlhyvx19bsUAzesu5hexs9XwxDmJtDGL9SH0ivQB3+8buJK6qcaHUXGk1p0e3t9uwt7eOmS2VOBwQbgXCS4WQarhriSMtotLGEiH9KctNGX1pXrOGkiIVyF8okgnwIg7YBcstGWJs6Aan8hyJjD/aE+TSgHcPCN/a1nO3aequIVyn8ncqf6fydyr/XOXvxM+7Fz/1yZthiJYODtTpNXebye6k4OKE0t3dW2fI2TX5VUU4ZDWipuC6/TjpC4OI3TIjQhL2pc2k1jpTjFy4NIwn2cIXTyLCrgKemj5kUOkmiBAW75jYWfCpXznF6uqCT2HCR8+eVRAx+MFimnTvur2nUEUUFzf9Z+GzaGQKb5BEMFgBgiZAJNG9p+H1gJxo0choAKJN/shYJuURntIEZROu01nk74LnL8DfAfk54ynyIRFfbbpuEmPKIhDbAMNGZLJyxHx1cPDi8NWro2fHL44PXr0qeVF+1w6Ww4TBblqFtbfiFaJfweiJQNoSK4ul4yOkdHZN/FgE5TAMUw0SEl9GeWuDStyBlX02jfBM5gORPulKUxREZB6EYcDBYdrnGHwPt1scLxIGXxl59AxyTGQp449gILlX9yo9WPYCrqV2/N/TnVXDbAygu/tTvQ0NwRsaCbP6mOHRW15bQCikMLikic9/IDEkPQhSOPNfGVvI8ATJC8y5LKlj+N4TlMmqbymbQdnCfG2V+74xJUKJOD+vsKOqAqFZjXeEFR0apfgWhlDGjXVi95flMnkr3JB7D2A1RIht0aFtUO4DP5SJawycMFJfvYvS5BoTE40IjkZSesg6A2EyeNpkeyrTkRcnYpg+/CK62G3BxGl2b0yzy021XGV1nMb2BjS2LSpJEP8imgK6EXjQrk/bgOayZybwaj8tpQtRSP61ea1nfjCta+J0oVugC3WuOPdZMwabasnypQGNSfztRNht+L3acOefswH9ZvfELa2KTKFBXMknfb9gku8WQdzPv6mEEscTA34Zr9WFFBdwHs2/RUlHKHTyVIfCe3ZLFKHt9TzfskXCPIAwryGpARkJgDBCxyJZblFoP3jKqG8NFDaClVVjagbLlRrtEAb9rGOUtcQ5jXP/dUH/yCD97VcmSqeJj/pCuM0nD2JqmoFeHxSSYcYh4yVu/ghmMWqKni5kjwkSJqSLli2ZwK0V2if1SeP4GqO3Fa2h3JNdAYE04seFu3fbVlTaE2pdOLUSpcKJzzj+hBS5gGbxD6Xh3evtXdIAlAM/xclH+Cj/BRqMQ8h++CP1vhaHChRkiDrklnB3z2NAit+f/UpePj841KlqQDT4EzNyTCacwfWOMBvt509vmhfRImHkVFJf9H6+pEm6Vx44i/ztHjYM8A7j+as0ebdh171V9LSqS9fX6DAI1VpL2rdL+QbfVMzD1FdsRFUijVxrjb494Oe2yK9WVgxFQs6mMWXR1yi+BPZGF8Feb28coNoW3rhgKM0LNfiyyphejppWUd60KmryDTNOXrHTXlEFpGKk7jYuvRnK1aAFE8q1AbgllT/146kbC5iSF0nsZx4kfUUHRy/DJNuiXLVO4tJhpDujaXJx9Tuig2hztfuFzpnzt7vHG+z87e6jv93AVPqsWMTd8L2L2GVV7WSr6F5yqzNebXLDU68VlU894UuFHlQpz/VPW6J4uk8eeGqBJbaslgHh1zxlc8jNCXUjOHn/lktHuDjiUnjF5PfeZDhS9XtARGdX1IMIwufHJIwvWeJRzsiMXVGfecEc4E1excdi5q3Vc+VxEkVPKedF9j1Pg6kKEGjtBkx/7wE5mdWuhOJvyL9UaZ7hLCgIIhXh7jKicxCKWJbgr/gXE3/RBfXkf/oRU/9CuTKGBxxfphN01WLII5BI8erSQ7LqPosAT/gExUayoNdYYn5BOcfqUUZebHURbHm7l/NyqhLmAQHKAx4aMlP7giYcmIzacCQCQfqINw4Nzgg6y5mT2W2wd29VW3UsYhVlktPhbFqH00Eh4zxl7l5/8TGJLwJfVl5CipoXprgArcZuE7+dlHSdKmPHN9j5y9wz/YTQPhiZbXJEnf8L6vv8JIsbawaLV1Du+eq+OPvfDMF52byRdj2JSFNoutjU6kjyjIaVd4V1POXC+RqDzkTp2C3Qi5i6hmJXZROAnEteGAkL8iqlk284Jc2xIsno//qd9v886f/PQf/V8Ev+7/7wyz//04g8ntMrKA1iqBye/EAAyvW1M7IZi0cjtCFBrdZoCvWShBKkL440DsAnPkuCC7OKFLQHNUsSxlW1opWW8OjF4d0nFdJ7IH2zd5up7ZzIJnfvvUXYALAdzBlPIW6isu+ruuF0cb4pSzX5IM0hOSnmtqUYlxDDoVqHarcA1UoM2ZRdUVzTcRuYxPKu8ZSrxANpxgVQqcWUecJF/V3Zr7su32JBD+1w5k7gTB6gkaXRZVeUBcQinxAfDzIHW+SVySMf0jxkSSQT3Ou0nQgp4N2h9nCqH7B2ft9Dcmgoa6FnQBr4c8FVOk581uL+fgZDxfeCaPqanIOH+PkeeSy765E49KEs6CRIePoEjF3n2AK8E7HL/FHX0QsP9DZ/9NvMGQrRHVYaAYfMvNK7y/Z3DfeDE/vKbrfCRmzpo/hmuc/6idYFTtckUtQr8L23F2epzPqU25DLrVcWvWhZrWy1NDh1W5/vwow0BhvS0kuyZSvpxfbwdQOCKbMaVCVl/l4FdKpW1Cn5YiQT6SCh1SUiVU34n4K57RrZE5EWv/qivM5XP/nbZKzM+aIxnuVyvfTLz2SzjWQtv2fFvaNpCuWwlyCJO0OEljlV65UfkVFdIkiqJLzbOYLIit5+9RKE9RaCWH4RKF08mTTTCQQF8G0YRIyiK8yVKFgc0BDXzGchtVRhL3n8wEva7weKIDGwjWaMPPrdv47oPPC+PCJzRiPpa0YBJyd9nsnUY5MsksHq8XyRpWazRb+jTjxD54Zrpj7iNTVFPCAs4gHkJLYoUAAbY86zmDwS3OxRTwBk8RfYhBPmg5QgsX0YTyUUy1/SSK4pE4pkll+kZi/OLPEIxQ2Qr+VbsOyilZZGnbJ8AF9EHNPqhKA2bUoODcoN2+j6DV1gtRn1lwV2cc8AEZU1kwSnePc1tdU3XE/YJAzYqQXOrk6Kt4z0Qk5NPiugNSPZd+3ZWHLDW/cwZGzRcef0iGWz9dS7sktSN9BOo+scmCr8RLz3pcMUFWQJ0K2p1I6ciBrfLh849O8a2ldr9fNYR6s2f1QBUP4UJ+/QTW3TJxbbW446rnukV/DJq78E0lnOZg1rc72T8mQ+I7O1Xi4XlCBcDuIV9K7iul6efUCTeINdOCvYnfvyuaxX99n8VWPa1Fp/Z9q8v3vrYg931wqKWf836J23jziB73/LMR567NXHNnIW+X18u8XMesYiFadjZEOvGpsYBExBWmD1KtUp4KsefBBFI8CG8N4jaUJRzyBLzjgL605YWA2JYwO7VY3BuScBqV3j1PCqFa5Q5IyU2zNI55zoxDInljno7kqwPeS9dR6nWyhrDYT80yRyccx+uUmZK3epWACut8tZIsF4X7zblkYG31V+akahrmoGGXxTph0ou7AWkxhrmesxG0wHPYI+HT2wumZz1iPan+OJk7t2Ru7aLmGozu2m3SUJz6rF7FGXnLFiq2vvQtyDdfowfehK/uZZRNRTMmYTKBWjjZHRtKbKc+uQ9ZVdZ9RwIC0SKPhlpDFQBzD24LFtL19X78ql02n/rBy3ZNrwDi5eB92q0lQrc7VbEv0Y6C5avntdzIpfOu2LXLQldqV7na46zkD6ULINaNGYCdLuK9rug0d37q6321Bz1xQI2+SuuR3aCm1IdpoKp6lw0qwzILu9Xa0kVmFvA6jwKYGLzHwnk2m4zb5Xm+3UUhtQS3VSNWkgUqtqYj460au8PTQMKIL737/dha/BQgK8ahohJQPOAt+HgyIXwxRoS49yWJpHfar2C6+iNuIOJivF+Zubre5gK6abqwKWmLFtWmZDxZnlDUvC1EevfcDrKoNywIlWfOYSp9BOKh+Q36qB9Hd3RKQja3XFlj8MsqnSafiyYUUzQ9mrNmPClFm8ePoyPKOYMWGShWEh/KZrygTYTPi4R7IoTbIIa3PoRopZE0T7kU0NPSCnMmCekklIU6nT6PMZXTBfpOEdQ1ZeHUFPRuKVEXn8SJ6mR+T/Jo+kwIr/VpIt/iGl30dPemSE/x6Rx4olP+mhJDoS4x6RxzAt7AWDs3qgM4F3yeUsCPXp3Zd97cumnwzIb6rQM34skgBAiWf0iIOeztKE0blYXnhn4Mc9cSOktgeiozDhuA8JhB+ZICv2Upb2ObbwSJchJAm9JONrzIom9gMXSpZ7Aa0QrN6AnKgV+1e9XqO8VymhR32cplogcDj39KXFOUHh6ixJWAQZziH6CWu2ixrulCySAPZcxPIQEVPrLAg7Y0Ew98meXeId5L4XJwVerqZVEIkX1LnrkSDywswXabUZyeeIlBEcAbPJJLhacjo1wzddzhqSY8BroO72A07n42CagSuivKxIJ0zdMGERRgCKcE0+o6DNh8uCmVHpnC039FIQXUULnRtzxB1rmY4ivepGCsFJ6PIFCVe0Ok4IXnog2tbMHptS399Rzg/FqAoMzmBO+nziRu+0pLtrWnEdTVciRXicVVKeSwxLlgxQYYEfBFeP0xlLLgPObEatOw/Jq1YmkZ6gSKYMvizhCImjHkABHTOexuJQm8RkQKB4IVQt4dAWrg40+K+PzLceWeormLF9JXNUHKU0iHJQWECUcVKkm6q8AyAPiMiW6BHD4j9zxsmj30/fvT158+nd2y+PEErqoHPZJB8Q3SWVYfSFbdb4b0B+ptdQtwVerqIx+ZEg8HnmJvZDEZnJOjACgKkxYCmQGpBGEgonC1hDJFBY5XxtVQ6OOttKnvnE2VVux67S26s7U0XeUxLLtCQgSxOVzrmWR0zxo9HwNg4iEBK7GXqELxF5JMHGI6JRf06LhNRSJTRPdpvl7qRyucZKhBhaW4hA4E9BF6QAFgrT0okIhFyJTEFblGFNrQScGtxxuI/H4chiWDorJHXBbecEpCSs94qpZXbdDWVHt/uZNVoJtluhD5+MId9PnpQ/zwDkxUmSLRAWom0ompLHCLCSPg98RiBfZh9lTjBeoSopS5hjE/fvoLiI5XvuRS91UbcXtsyzscj1vC/PSYORQ1Zjtdg5RCNIl8RJsRdnrbrEC/Ha/J6o7+sqtvJZnKT9EFWy+C4KrF4cRcxDmVwWCKzr7Dc2Pou9ryx1yvKdUZbflnbzhEyCC9YXFUEtx3a3WeauKTM1xatoRi7ZmCON+JyE7WNSFKvwlVPhbIFrrPZ5qPIZTmRPqKtM4pAsQhoxcnG025d4J3Gvc6Ld3b11Ms3tyjTBNIoT/cKGXL60mCHFgzVlmLEK961Pr4Sv1IosBfnkR0TL4lWsK15xleO18sg8C9NgEVrEDS5cu0HdEjKCw8md9LZE9tiuMNVudNSUl6wmWyGWgC1RGBHfv5UeI5BaPOCpstiMvMlwBGbZSXAlSxFRD1ytnh+TML5kiUc5IzN2RX3mBXMaGoKSzZKjfTJUmiT51/dePuaEwVIEhUoFTfyl+EFjunOZZRtO3TwIw4AzL4aMYOAkhnIzjpOEwVdGHj0jQobhj4pZuVfpwVgL5bgCR4xdUazu83pPd1a1cH/RNENO/lq7cKMhNGcxD3clFKtEVhjG4voMZ0EBvFdz9UZ0jjJJhn5E4i8m/qIL6sn/9COm/oX26hgecHyZTrAWhPCTyD10iwsDpvY+iwCaqCR1yttgQTlHDYJUyABlNZNpVWFIg7yp7pT6s2vcboG2V2n0gPyIHpxwLNDzNQQCoaiFcGEIQzUlGUTpq4IBCWucpHISLSzLbiPQe6siaGM61qzOjanxtsnbRGeWHm4wFbZOUj20r04p53Uvhzad3i/nSoPJmy0Uuu/Vh/g7Pczd62E+JvFFABxCI+v3b4Hoglx+QcNgx6niTsrlbSnWfkGvbKd4ubcb7AJat9FCLFQfDaoWgXU3omHZl7WCOyhaxJtVRQu3aFrEu4aipJAvraJqeYuvO1XLzaVHrkue20jMOlinVXKazLRSgzrmcbNpukekLqVsnhaly8pmZ5uCh0r1TpyQUX8dLU8Txrc47DdJrPbkvxo5tQuzKnBTXCDTOE8xb/U1WbCkn/s7IFXfbc57bwXOmiWWW7ueZGqRnayD2th+WgexxAoGQrJtW8bSV2qt9ESczX0LZL33Ebid/h2kOqEkxeCw3aZCO4n/nYC34xvsBLy7NJe3S3JS+tqIJJenl+kgzOmXu8lz+vXOIt1HloC2F6wu40ITwC/iSZOo58S5JSznGxReljG3tR6IHrkIKKGE8uvII/+Ixx3scJjZwtfxlnnLYHlTHe42F9o1YUfv4afcwmUbXLshLf4K9qoQyP31UBnT6qOsbR074WELhAdnKNo9mOnkiB3fYCdHbLcckWP/NUWJghBRGyYo8wl2FiIgZVReVwGw3T/isUoFE0BK5IlZRwEdsroKGn+FzPcicU9emWechV9tJVENGQQg6W4JGl0Sd21oF3abhO8aCO9QVkU7p0Vx2oquHY7eAhztlPA7gq0ceN7xDXbhbTuHsyELhmSGKwFu6dfMG1E2KEhzZK0/MYH1B9Ch+mwRxtemRsV4t0hU4H2OwE5/pN6tArwtgMYGAy4k5q00LIlRL08c/+ygIV7L7GK15g/r2rstNF/c+svy1u82n7i3CL1tVCHlfFiT6hY3VKSL967btw2TwVXPzc/S704mrzbqHEqxEHLfqtMkzDM0giT9RPeehtcDcuL7ATRJTSER4qVExIvw44PKDSL3vqpRYWSbkWEuA/JzxlNEOOzKY5DzZ8aIvEbEmLJIb2eJwOuWLPsQObH0URzGlrQg1hp5sInUh/y+ms9IIrDRUM+3ok2ZNly/2CH+sNvs++Vn3eIu1bDkq7cyMNimGeVDn04tsKzGF80SjBTSaJrJq1yNIV4k8TSh8znGico3lV4k1xzBEZ2zKNV+xnUS9D/oBRVdwN5fpzMZQIVnlrcfEEgLZr62ytmexz645a53uNcK4TJuV3E4PVt0l0Ht8h039s1Fem2j4sEVo3TCqBNGbzk6yJDoaoVTkBfXE0f3v+UBt98bZVNBEsasRT4Fk0NZKlVFJBrqYKkyE6WSV7XSzpZIq4Vo5dV6qrDXu7ESqRUvbdlu0/t7K1TWgR8nTDph0gmTTph0wqQsBeVkRyc7Otlx05bqv0uQ6GzU93drnVpgZ9UCKxeUsGoF9iWQWkEz0BccuU07gC81Vcj2g4R5KAl4114YeGSa0MWMPH578tcnJGGyCqOONKNOXXAL1WAXNIEsiW9P/lrW2thWf3e5w0NTImxCAi6IZjWlYrtLavdacIG1cJLKbUsqDtQ6UOtA7a07XnZBr0AQN4heESquil/Fx60IVr3WhGEFZL0IeEbD4E+HVe8Cq4o9cGjVodVlkKGmIFa8YBqnxfkyksI3I9zyXOQBtC6ujoa01K+Tp1sPg0Vpcr2IgygV9cJFAVm2EOOzjWupNZ1kkZcqX/ZyS1Tb9T4W2iz2UNt2FPsqZ16hMsssCH2CD8njBDg8Dy5ENdsW4GIcKfFL9RQoZqvmNfTZpBoJh1/19iTpFeO0nlw9hbqR5fUoSmkCZQWK6vTfqtoUlBerXzwWB+QJpMScZXMa9RNZsl4WxCjWvyifqsoGAFio3ZuE8Ti8sMJ8TOeRpPZHbesOR3PIQ8YWbauuV8hC16pkKpoEU8tRwt/VgkpeAJfjcYL8WuTdBFoQZ+mT9ssiv6p2BOz/miziMPCujX7aWxxT72s8mVRb/FE8gK2lKZuKVnHschBNFkbIo5pSFLnCIGIUK4hcLeIIDLJU1Db0WUiv7/j4ab+DZklSvKaG3NOLhnURxObd6URKw1WnJB9c41W7STJ4o9fYj9vusLyX9SS0cpNrVyleaDZUXKdfZTVIceuggMZPcfJOlIusuYLNnBmrZAztK7CdB84YcfHMSXRSHevZjC4YUb/FCa4e5u1SlXKKYyrVXW05HaoCif10dDgFk4CFvmWvf2EcLAN/43EkZiBeNO4HrGjmpVnCrOS8DrEsDyDkq3UXQM6gOtcvN30r4QYMJ3EyFNVeWm6oulbrXM2VpxPMGU/pfGG/Z52RxDCL0iBsm2neW5e53iE0DeO4ARx1JaRfg8hy7z9SsEOykLAr5mVIrRTAaMITNAwFOcAkbeGQszQNRd0j6gnnm7tcsYWcVe2q4WIssXgeRAoPx2HsfW23XZT5x12uhBhyy+EBsS6IwB69y1NMk92eXks7aXJd20q+NL3CUS+fiy0nlJ2Wqn0K44RG3mw5rVgkYIRtdBVTyM0tUUXVpobVqLNoW9agXiGil8ota2VZ/QCGAfkjbHU9uwCaywDyU9StfaH95bbC6fg2ouO7gSk4AW0rBbR22YMm9U0XXD7yy7UJLchNSY76qngA9RvvyjrDv+/UoKOU9WPC6FciYnOyJCKTJJ4TSkCwa5KyxvAZGqXgq04oT3zSKPbYTrijPNtJecrIo4WQlN9XNkXDgvjlgXjWCbut861zvnXOt8751t0737rbDBhBStnJ6a4UQ96cytB4uf+VXVsyGZrx2fINW/5CI6S7z714wfzKl/Vuc2ukFDx8CCkF44l1MXeXPN9bH7i2UW3A2S2wwf8UDdN5FWAV6F46NjZBphpW3zWvBIa0ixQSc3pdSB9BZnHoi1wTxW7zsHd25YUZQPyf1QUTF6ZLOPyB4ZpRHOXnKPgjY+TxgiWKHj0h8GrdipBTNmHwJ/PJ+Dp30ROTg4JZ6L8jnCJs62d46x49e1Zx161WXJXgV/nHGGfCJVe7c2jsAuR3DBTDpj61aK9K/BQz22CKmghG6Iu6G0C/JBVxW3/vtt7JQ3cqD41ZSjsJQKbE0ppLr9dQR1Ww0rJQU5Bp3uArhJZxQEWsES+Cr3GLXDMgHzAFEBH5rARu4GmAlXrIJAyms1QpkxcJuwjijIfXRJZRhxYUNOFYVYLOWb2ktJUFUNfNT+Zw5LI4sgAhv3QtEwtZsSTatAkGu8vd7q04WYfynRj5oK9/mxjppEYnNTrRwUmNbutX3PpX1a0/KZN8EbmLm42MQdZBJ+wKDCJu4+/dxruCytuvAxAoZ2lD6P63r+xaJdAXkrddgyCeNWoQ3uIrHTQI4kVefXNAfsJU+pezIGSERjlc/P/+n/+XkxD0DqlOXZIoYCmMrPj9J/EP4gecLhaMJpwE8znzA5qy8LpHxplSRCiqBEAa03On5CtjC2gqSAgP45QTjMSCX67JJIgCPpO5vUGFIZQadEohrzeh2GvC+kqMlDSwk+5CbEFJb1EqoNpF8rhP6U1KgEFpfXabO+yauN1eqzn+2ipslDhaLZdy9ZydDOfwnJPh3NZvPit6mRs7Z9f7vcUWMb28xQHPATRqZh9qed6dPAROZN9+kV2K25Cmr84VecoqnsiVlJ5l7Vt7xbqK3C3yhhnlf0AEjzlrkLhFOSonz9bLs64I3XYM0pmPnfm4znwM+yeaD6LpUFO/6rh/sxNGjZmsOkm5uuRHyOzBhYoLXhLqzSiO+my+SM3lb7ktRmLjdiLYKyVdbr1J5RzNRm+WW7Wc5b1uoZ02x2lzHNR32hy39U6b47Z4GwR556p/kzI/1rcDQAK5sawif7bw21z1P+MrHQzt4kVhHkdQJsp2VDD2CRACeC82qlSj4IBJeAidpCwR8HxGo+kDM2W7kAAp1FnzmC/lZC8Ot3Oyd1oSpyW5P1oS52TvRPptJa47CfqdSP+gt96J9Du9xc42v/1yOvODjoXooXhEEE3xxDTa8XWJTv1F2ZIvOyDGC7UmfBl5H7ILFpLcOqU+7RGeeTOo3YNF6EXWLi3cQyZXANlNFTtvy3B+Upr0bhO0XZMF5cka6gPVcVeKH5TDQ8RpxRfzowpJI8xCVFZ5rIvc1S8/y8l+l2HJV29lYFq34qQpJ005vHVP8JYzoWwi+6uBgtY3pzSDL2VQacNfyp4SR+F1IbFrHQxTadsXCeNQwjGI8DNpUyDj2L/ejZRGVhxg558538QOmV80O6GGM+Dao+pyxiIRgunHKPZyURg9SEh8GRWR7JrA40zUVZcGM1Wxt8zeoRIC5VgSF1aZhMFXRh49I/MgylLGHxXrCazSgwVAAJliV3S+ANK5pzuraHK/f+kGZnZjqvJ/uogZn6XlqXzHd5ufO3HDiRtO3HDixpaSJyduOPXuncsQbareP1kSp0nGU8ibEjEvDS6C9HrYqveF7/r4YV81rOK5dCv1uuD/YUlMPsHX5I3xATmrk03+ymSxibYvpZWQkWlwwSLTVLgxMeSfEjbZe733v/e9eL6IIwZrKp7y/TSLIhYOjVY7Koq7rApRzSxDNjuMFvZyiHs5tB6Coe5XkvX/+q81J0AmNAizZNMTATKiuuh78XweR33V0waJV+vpraNpxoenbBEnQNILv6FSxfjFIHrrE478yg7qbumKqggbMcBXO5AD04tzabKwzMfbShluQ4ERePPFcJHEV9dD6U3RcbiWD7/39uLJJKHzxfCSJoslG7R+uqyge78p5bJzcMRya8hgdzSVxKDW2Z/FPFVekG04KmIpYDvex2/76lOs2FUt0KUeE9FTTX0uCH2fBCHQtvIXIGnT7aCDuVd73km1WleHVtUUhzjFcuN6M0pdlDz4J6A+6wk1eGhZauFOC1eRwhISno2lBlH6rwoGc0HDjPXwB7EDkJTEo5z1g4iziAdpcIGxBivNsDAxRawri7fSzBZxEKWgtqaECzWnR0QPS49WD6z/tDBgIDcM1RIb2Gv8eqiaNLvBnKzMH9L1ejKaKZxVPpR5/epbr2zACO7KSO6BLDmsakKUdmNA4H0U2Ec9gr7YPqt9OdeTGTK/UjSLC6rL22GbhTJ5rZX4OiyTbqR7Ab4urdIpG2o1V/fieeWjfUOIoERxVC9DLw5DhjWAm6CAdaQrsPuuurEOE9IKoJL6aslP20vklce89GJjkfKCCqyoICsqxEoZD2Ysncmor5OP7wmUUieXlCuF9CQLO1woQ0/ak4q1ioK5w7TMLzqoWw0Vnda8dnptkwo8A539uzq/p7grdXjujda2kV8jRn6RaEf7DNQ9l1Kx8fgTLpvtQ/kkdzdYHy5KVDaQZNbAECtWLOqA+GS6Y0sBoyKtqKleRGjpvYch5CoEsCTh1sCht2ei9aWwWM+AYKsgo67ir/UU3DZr40E0DRsl3OZh7iiDu7FTqaLPaNdGjA8swYkSQHZvzvjA0twad6bzZbGIdXjjhmLpbbG48ATlMS24lIMCcy8Mb+LL+2jkdi78iNoqqS2IE/kDGqKngQeUczHkDP4xFcc6CiQbzPwgLZjo1qIT+vMlFtz4on+E8OLOMZKDOCUMc3dQpb2wQq1Ka/9b5Vo21lnogHvkp5ayCy24Rxdn2CLcU9U75eRrg33aVF6dpGTrym4flmgepsMSDks4LOGwhMMSd48lNPe+6k/iZMr6cmP6mJgDMpioKxVworEBWbBkTiORksTXtZPKjLwuj3QHVAHflR2QWvAExqs6MLGc+9K2I4mGMToY4WCEgxEORjxoGHHPrS6dXRTrcIIIprSFTragBeWF6BCDs/hs2uJjPYHbh62ah+nglYNXDl45ePWg4dWWaGm6uzDzbByxtFMImIZU8psan+Uz2WK7r7JsZyt9lFdxIVbz0YWzhY+wbGqpUYmmpNdrxRV4E561hR5sfrVyu5dwey0tB5YOx15kxSHZImFX1ANF4BxQvAzsEUv15v3b00E3N8FgMZTtDVkEYbr+LXoFU99PIPh9QudBeL3EOQki4eBrHH0jWkm0SkSrpE9GF8cjSGAxung+WnbkpSFWfJpFFoLlN7ng26ym4+tIf5xWnVNz4aXCyzIrSo8AM8rvURiSMVO9+Bb35826aufTEe7XLdOpvrSJafA4SYdx4mMShE7TOIuTlOAXKjhBsE0+ICPKvRGZMxpxEoc+ZOxJYxKxS8bTHhlBO+qx+BEeixeLE8L0NTgT+AlnQ2h0TRY0SQMvC2kiRmCFZBJ7Ue7J2wEM3ZixIEXwGV+W3KQSFGLWHbXimI0HF7tHOANukoqs4kDnaNMQ82jxIY+zxBM8IEgDih68cXjB/GGwUFDxy47716sFvSFRVG78Kv705ZHtqPS5CYd6sVTOkX47ZA4Fj29El7thiYNrKN/iBr+EpLFfIbH734pY5fsKwohIS6Fb7mviXbQIG4t3hm/I7bClKc6SiJsZ8h5xjWCqzUicW4o+L+C5LRFs7NB1Ix2WEWdno3LdttwW3+lmVm4d5Y7yoDoNKF1QTybL6b7m+qvvvSV1qKqB+6JB7awLlBMT6k+LbLZcK9XvjRo93dtRytzVBrEwOzfg/XLN4BdOtbk+zNg4IhjYWO0GjbaSqatCgo18XVqlOrN2M51MLSMvBPkX+fjDZOPbZ+mt8oM7pHLLmnr5luEb+7AcoHGAxgEaB2i2DtAsrTfZBhi0tFF236J53piyRLbdV233UatdVJe8F++QU/kOef9xNYVJfUNOZbKayqRhRbcGVHQcp0MZDmU4lOFQxv1HGXdinRnYOXmrNiZbDjNIXUwbbJCC5BLIoaCPef/2VCOCpWCETWFzHkkYQcB1NGKXov05bDR4MUDIYhh4qXDYQlcfSPC4SIILmEOeQdMYzeA8epigxCmANqoAug/4rftQHYRzEM5BOAfhtg7C3TnaWl7pg46FUMqoc2JJidDEHe/LGJZKVsnfTk4/Aunmdhims0qq9yjnwTQCiiM/GZA3WHY8Da+lv+z7jxfH2hPPoxH4hUpKMziPzqN//mcJgAFq8TShQZTy1//8z+dRX0Iy8RQR2ZghDgsiEkdM4blJHIbxpYnK3n8kCY2mjL8+jwj4SB8eDPB/91+OyOPTn96Qw1eHL5+ohy+OBofP8fHhke35K3j+Urzw3PbCwcHg+bF4fiCfP3/26iXpkzd//eXk0xM1F2k6wanM6AWs5CJhk+CKhCyapjOY0Wj/SDh0hzSZsoQ8ZoPpoEdG0DX85+hA/Od4RECCuKBh4P8APzwTv78Uv0dx+uRuYei9QYQ7x1RK9FjGlqjHX5bMMbptZkj7sBy6dOjSoUuHLrcOXW6LGVJCvo0kADVh6P43fYeWzvopQan4pApKZcbHFlCqU342gNJSprGAk8Bn80UMfIL0RZgWAEgIMQ2Bmlz3VehWnJAojvoiyE83KcKcZNkOVbsWVYSUwFWR0VVbYpzMqdwG+zJI51J5Ru8CTwx1VEt7gtEHBizK8T4OaDig4YCGAxo3BjQ2mh20iA2Wyw5qODpVoAe4pbTgDpEatB50ONZfXKtt0yNYxrTrvN7xdsfbHW9/CLz9bryM2lj/ukFeFTYtvQ9aOHWelrOeWwtTlGzPbokayVGNyCRgoQ/GLJnnZB77wSRgProlYR9qRQhQFDKC+YN5RtK+UQ9zXI2qd32kTGRixmAi64MJ7blpQpO9yle2xdnodpCGMyjdA8elbYN6LnLNoT2H9hza21W0d0dwrtVvKR0mAf865F4MKdT2v2WcJcpOZFXT+OGiD5/04RPWl0APVTSTOOnD9xU1DbxP2AWL0n38ikDWJ6lGQkBmVK+XDVTC0pKAXUj3cp+lNAiZL9oVLY4TRr/68aW1vZ7MIwf2I+AjSTDO0Jg0oZAxmG9UEVTMSWfCL7m2K7bU2xNrBg1l3fU6p3rtcZq3ykb9cLESDy1/tw55sqRpbKJPlmRmbUg0E8tZynIdpzQkIlcf+IzJVI46KkLCZEg8yZKLwGPGOGWGP2OYhyiSTS3ZtKUvH4GnyvFuQadBhLkSMYFr3nt7HyptYaWfXyozWbBE9Nqx/aMDyJANyzJsXDPVviaHOK04SzFRJWc08WYkv60tfR7kvS7U0avmI8/3CV/FeemQERalQaKScUK6yuZlPDhQSFyCvraTDjf0HV7QpRLhfWlA0z8J+pjGZFogv8uRgLaBAxNUBKgPKDKO+gqw3wwPRmJ2JnhVLSPO339NPr5/v1F1Sq4AGWgmKIhzs0ZlBQ68nzAuGLDdhbjEiPHtPr5a8BoOGZUUJ2eWgkUaOV9rmC7H1Jz6O0G9JGdlPn7Fe8SDLoCbpjMWJBBhlc2zEOkPfjsLeBonm40C3zIm+5amlLNUeU0b7EdEvzuu25Xrdhnku/kivd4YrSzsHQJSJJ4Pi1JuVkpZgUoKYresxfkygJTRZh85tVmC5o7ZjF4E8mp1kXr0B9aClRQThcs3UI1MOY+9AEkDTmiaibYbBB31XknM0c2mM5pCRG0QQSmfSyTGhGLWZU7oZMK8VBLk+AK3zmjmRklxd6lEbZmelCOVmyaVP+qTfYPQcr19vP+0U9bfu2VqOpDLnSWNmZ2b8gTUUjV422LEK9AuBIO4/zn5rDPrWShYsTHeE7QMjtElC6YzWWMmnSWMz+LQ53l3Hg0BtcJnKxCy4gBPxGvk/dvB8kSuYOgqtvujeRVWtoG1XQ2xvOYd72YDcnD1NmlwdZcccL1fwLUjqZVFSZcAnkGUsqmkgI3Y88/UJNTGZzXVu4p4j5j9lBOzDOpKfIWhCUKNJV+i4btFmbgU6jVH2DZN2OCqwk1l7/NTcIKVTjZF4nADJb1ZbSO3m8CR9yYB2F6oWaBTrWVEeg0ay3pCJqPbLCkPIOWTneZUaZf4BBzJ4KtWotUjsm4obAa7SlkSUUU5g2lEQ6xClZt2H/GiyMOvecrmN0/pNuNT1XYZxOIZZxJ7XDIY3dHb26S3GyO1cvccsd1S0toh+LcBXO5/M/5qiwNuptM6OKgSBUw7U+lTNo8vkEp3oNB+wA0ijRZZC6EmInPzLVmZiqt5y8YmsdqOzt4T+5LYLkdYt5SwSnpWF5bYTAxt5h87HYO6pYFfJYV/BRt7BzoI3wst5Y6Tt78yJ7PfUwwJW+fo3L2R1ttMQ/VkT2o6LSai7hjw1wuWXMJySH/ICUtY5LFh4PdIyiIapcMsCUUYFti1LzCTXsZkEhf4KI4YJ4skvghkPe57ThpvR8oXO7WqlC/32VHoe0mh5e45Ir2lJHk9E9K+SUX3v5l/NQd0NALc/vi6r5vqI83rCnj1Z1bomzs7dcG/GQQRkiDlhvivm781ZGyu6c0arxwOvrdU1uHgrcPBA31x2yFxd+Kr6eDSwXLNRHQSCx/9MBRO9qXqJTVKhIjQ6TRhUxFIjY1jcI7hwE+9JOaF8m5mbJwfcBkbF0fC/SphkX+z4XHLuYuyxnVxZNIFuLkAt60McDuTxO6G3ZDZA/M9vrUIt4HiVp2YZ0TD6zTw+D7/I6xljvyPECf3R8YsPPE/4VeiWyK+8Has+hi/u2JeJlw+zv7zA/lDfDelQcRTwRwqbRhXL43xHaCrLBlgC4uQegx8joHByFw/4ziLfKF4Eh3k95PA7H0ywl+G/wJ//duoBwR6RihXv/OUphn/1+OD4xGSyNE/iV9GA3JCIJFRCAx49NOvpz+ffCJ/O/v1F0hGZPz5jnqz0/jS+PUTHZ8xaD1l/qgHWZD1k7O/jyCDMs8WizhJZdYjYB1qBQbkN0lzxCc9wqg3I2PqfWWRD1mTYf2ktCULqqnybTCaHNY25DbClVLAQP1R3Lx8x9KYMLGThRWRM+IsZF7Kse+euR69wjLgKnw6+zuJs3SRpQRhzLWatRhrZ2hi0Ly9s3cf3r35RJg/Zady5me4f+Sn019/VsG1szRdnAq+x8lv//7u9J1CJp/olPwreXRwePT0+NnzFy9f0bHns0n570fk5Je3MFyWBnNG/o08Ojo4et4/OOwfHD4iH97//P4TOTzYqwNNNnKm38tvZZ//EQ7xfp1J6gtUdvkmfqYhqDGZL+csmnm6bDM/xck48H0W4fdHR8t+/zlaJDFMAy40Tks09GqlJfkQzIP03ZXHmM8wf8yz5RcG5CNQULwDlibaOFy2jV/i9D0cPkjNoway9NKeCej1OcopPzb0YtmGoGgcuFe8u5rRjOOAmnmfwd1ONP09+88PtTxNRWLkb5e5WuYHQn4D2OB/3RTD0xMdALPqYC6x+jYWmVklDPuOuBnQchagBJHQS2wRQ7+RhAu8jwlRqIi8gW9lj5FPYhwTgMWYB/KfkGof2V1O8XsEaRVWc1LWGrGVcUL+hCJQ3IsXbEBO5Qgq/JWGPF6Fye4E67wNq0+JKPwR4nHUVBsECHaV7i9CGmCr28r3mvQIddYrxxMdT9xdnrgO42thdwqwq4h8JL14s8QTkZhEMgaZo+97VfwDA1USQ9IQweFahMHi29W4Js3qOvDSU6z9wu1sk3g0pWE8zdiA/HitKHRP6q5k+knJG/OPYG2Q46Uh/NejKZvGScAwflX3zXvkaxD5XLDDGV5kMgnplANPTslIqFzZ0IvDbB7xETBu+ZvgJrK/R5AHAF5RHRc7gbcIEEJrT580EjDKGdqPFKbuDzgHvW9cUKlCFZ4oFflextdkpDS+KZ2OBuRtcVmKo4MRyQlivUNoldO5UOGyC4QZWTqLk+BPpkHDgPw2Y5GxQhlP4/mQpkIxzTgWXtSPzd+Ba7PyDiK2kG9zol8XIxY6blg/4WR8wSDSbZLEc5FeIS9dDonlYLV75HIWeDMSsmmQBnOaMqh1EEwmgFFAYaig16g0MkoShsAHMxqjBsAyNewV6xYhZ83gLgMyStBf2v+BZFEahDDDqAeTVeAOdpwEkc8WLPJFAYY0JgnzGLjNICSME7EmqOjH7MgDMhIHZkTmFDIV6hsBGkE41IQSLwwwBfMszkKf+KzP5osZ5QFnA/IezhQnUUyYyDcB4jYyz9fqKOYYtXQYRF0m5pMZSxg+TUBPFhEMQhb4D+45Zn0WJ1kNLsTwREwEqFpPIS2IzxZhfI3rCwsu8bA4k2Omdi7gWDSekklwJRXIA3IWz43WYHzqMzz1eHIF2xBbFF8KsjIXeDcRg4JSVJBL+hLnhC+qrwIDpfcIj/PLoO7ZnILuFxyoxHGCaeRz/v/Ze9flNJbkX/RVKjgRZ9kTgAAhCXn9Z++NEZYZS8AAspdnaQUqugvU29DNdDe6jMMR5yH2C+yP5zn2m5wnOZFZ1TegmwYhGeH8Ygvorntm5eWXmYYZ+lqYd4ZtYW5sRWb+0KEVPp1CzifLhkOtPvgWZqbdgqAuNQXDAadCntVwkx1vl5VBJrLoNld+CG6yW27rOc3SpT9ejkC9CkvrQqQCzMPnYXzgoJeeI1oLa8Jylxku0y0htwMlZdzrL5b9DYgpYFB1cwRJTiLbI9UBtTXeEkrqAc+i3BxvoR/ljqaj8MhM8cHoUelhe3JVwbynRGD/fpGjzf+XGm5fqipyl3AHkU343K7qXy2G4x0i1DgcNrag3JmDFixriAoFDtBwlJIB9i7gbqF1DHZczTG8hxNhC+QnGp85wlspvBYc15pOhZ5nVdNfTlUrDRk1VroNeREiB87jM5y59szUfMfM3GV3z8XfMfsrXnfWxECFdoK7fmGNWP1hOrZsYUd3ehlhBVsO/Ce61YuL7NMoLBAkPfOqEoMF1tDCgkBkvGPxEDPelf5Ql4+S7Z7eNXx/a8EllSDVRLjlWkkqwvbLVQpYJoJwjAgnyRNpKKlFiSkT4XI8pHjHgyTjM3rPCLtMiwscl0oOy7zDlf+xbFjz12a6AXKmAWXoeG1aQyabSZAIrAEwbxj4zMtuB6WgNYF8zwG6Zzp/BA7sLLvM86wjdwqDUS1TQFQJC7OFPDsT0CISDFx9/M5C6lom3shj96SVe+qSbWut1lykjhScnCShMHS76/6abmHJ7rlIt1Yrry1vhMuvIrHkJpLsyLXYTcCFVDlL5IY+hwhkFb+1edbm935nGbpKHja2rG+zafpFkhre4hqNxUO6NVrK5MPrko7X7/q6hE9v8sJ0QqMOybMewN0ACyLXpHqFV7MkD4TBw1F3Vf4e7jBDXmn+tcRuuc4GQph4caFrDEUQT1AYGmNX4UpC918Vu5LLMIESMPh0IKKY85L2b2GtAQUTsCkLZcW9KZdKN78HoqBsGGU9hw1mrieMq43CGxC3PdySVEBBr3r0JWf33mIad0S41oprjXXG4X5HiaK6kiSxd5QjldqRXUOg+x3HgXxwyjUIRUABDWjXVmYHqeKiHziYf+Q4w4LfhNu9iTzhbxaKaMtXl42Nb0KKiCi2zsxvJgwCj8zyI7xMPlhiyI31MsZkIQpUBe/G3zitVHpbdiNsLvIs1F6dka1ab+fktxno4K6agsq8xCyPoNDoEt2+1IaXIL+upyTgNoYWL85YX1XWFDkmxNOsNJkr2/IiYkj5JZjm63UDuNPRqAyKAmbilKqI3O17sNtE1DGwSQDI6I6PDVwcdTiz8tnNbTwhdTZKPqplHk/7c+SmPD1jXG5QuBxDF0tVFpmxTloDtVtucw39UjxiGvTYkXoSPUv+uvgdaaB42QaXLDbMYJE/zhszwEXmXWXs//t//pdn9PH0ONOKMhnFX63gCSOW00oroUJcKbEOj7A3xNBVgKfgFrBAaQ9kwwQQBsAV1SF4B92BvQe1MRYYe3FAIaXS1W4DOVLGdwVjehPew797DBukR1UB/ObtynO/HQ/GEs4A68kjhBiyAblQ0dzmtjF+ZLPAAZFPWs6keeyTv8E346MPYWCMwa17wHXdFo6Tw+PDPRfCch+8esd7VuTUyxE3wmf1I3svn2ZV/6HoRnoPAo2rlplqUNkr5TXv9ab7vzqz0Ug4EnbO5m4KRYcCCqBoEsCoXM2gMOUgl8Vs6rcUzJoNx9a9gwKQZgsUiSA5ERASmFyn0D9IVNC4ZyHIv5B7GVYHygA6cKb6auz9YOx92/c0p4sxjNujrZcrSzHy1BXMVg56k2Jmawz+ZaCqHotQk5S8QRu2x9ysRpjD98wAIrYQ1e6B0F1hT23D8WHpQ1uEi9r7hb7iOIgiw7zaqORQDo8uo/wEIB/96ZhDSpzpbDA2NJhlfHScx1MgDg7ezcG7C8EbHdh3WAMwSbexWfZJLCp8KtkDNAQwGPM3RxUzcjA9BIDO5cvfxCN7I/KjfJb95go+cfqwVr9l2W/asD+1rX6p0C8VfnsbyGHce1UJ4kyY+tQyIMDDsfBGSuBC6J1Zh60sN38GC5qYdBeuyNA8fQ+jHQQPeAu0jsEzrM8Ea7ZOuF2wjc/LaPxD2HcMGLDPZlYVw14c4F4wFX9azs/hJz5hp4sN0yA4ZgjrK+Kztlq2MTLMnMYxQ2su8s4CrKEW/XVJEkxAoPlwsha2zWpVFm5WlXUZGWBtBeBdnn21Zqg+gBLAzdB7n8CJ5bBHa2azK6gcoFAx+AM0Y2K4Ee6l1GBAqZUiOZilFG9hb/5En+XAuhN/vfm/1D3vvH0bzyNgYKF4Mc8wtmEJ2rETWdkcN/XcreW4qMn0A84SieHFAKC5/oP+oovf5hG/VxB5lBAR5FsGi9nMxDCNCQRfFSMj8MKQUo4iHJykWbYeBCcl9l8qZDMT/iAHcFQIjeYoPJoxwLvSDgWxYB7Q1FwYV9hTpcaFYZjzMUTh/q3hUBb/SDWAFj7toTzm9iCmr/TZgsOUuP3Y3RXnNfRTIHlq1ngs7Vu5UtL9ED9874548fDIFdPdqLxu+iZfMKjSq2pKoZUUWrnV0Er1KMes2tmM4YrJU0kkIonMlwJeqyzvFqvxYtU2dZqXSYi+5PKsAuLTzFvOOB8IfXPy3oYZs0Ptoasv3OyyTNm1yM9LE/xGxMBQcz9ZWNyWnWoFw3Xsp1KPg6Zf/4snNhe088Nfg3R1vZPbjTQVNC10adxKU2Q+VQfhBueZRzC3uallcR/+WjOveOhs74ZgJk2CyUJZwthJKntpqSwFfwjxz62dmFwZ5r011iMepoCX6suj8YT2goZyh8/G0wz9ia3JK7Cv8QgRhjX7vWacsOlLRzE3679IkPu5glw4P3/4nYPv0XObmHk/6NYWd9a3eHmvgz8nynvqEW6usBt6ngcHfOue2rmTpsPoQqbOOPWszCdl/qqF7frJIgwMJ5XXIWHkGwkw0fs27b38QrcITFXv85VJjVayeL+hH/MKdjYkpPmSy59gCtJF5t1JoXDo816wnFjMtgBw7Zl+rjoNxOVNDPNCmCP3Fo3MzyDtBWP7a2vtP5/oh4Kev9JK7PuRXThV6a9EuvTSXHoraicEDYL7PO4uA8dm0kWGJbXpFvv5t9jcRr0eLTxu4KSCkwpOKjip4KSC74U0EgB07p2DIDXHAZ8a8Tgd7d5RCB35wmMOH1+A6Hg/A2OMTzWio4yiuV7FEuCiKlhSZl5WeS+CG0bi9E3BIdjaVAFf4d8xkidempjZDoZ5JISZtaVPFxqTj8t4uKktoKZ1BFWbAINJ28SSKKPpGLUbGWW5GgUT5z1G72fgO35TzBULhayfXKtUeJsKQpOqmQU8iV+wxTDd43IsygaaCoN+EqYf2uTkFajjmYB4t5wjTEi5A8H280eEtRQwR7m5F05aPmF1ttjFPCgzrKomLcfqcMkaDM8wgwECTtGVdXjlgCCoNqC5pAlv0lb6k33HbYObbso4a8R0WDNUbuStCsIQJIyxhYOprkC7wWh6bzwQOo7HD+sTY/dJs91+T3My4OJipNIoWp+2pTpo904fsHpeDGBNsesmbEiCalBXUXJbGwQ2OBeJePSTet4SPLf2pctq/nUaHw40EC4P7mdjZFq2LyGkSDet3Tv54NZeBZrwrumHnOPODWG5DOAv7XqyQOi1eJlg7rHlsoESCcLPyhQKt8KwITId8ErfxGNCvQW67V/tbb+1623+Vt7GNbe0zVVbuyMcvhoSo4jR7yWjjzDXDRj+wffQJ4z3OrgTtrP5XZDzX1/MUBkipdBTi1hthxmTyUxyff8iGcxMfSz8F2VIhzkvYtPlsGeXw9zxTIye68ojEz5n38RjcqBc2hYWdDf+4OlupaOjOV1uVy6Az5JYggozdAe8tjsgH+KUyVDpbfP/g+/qL8jZFx8GDLcB+jATLoMFp2aUcbPgsRj9gE0NEzKprLwXEgqyvUpGEjKcBJuROPaGv0RLVjgUUbzObNZp87kY5a3gupD+wxrXbkWuZkGOlHGUOczL+DJZytQaG9qjgooYYfEidGwWKptm6j0+Smq+NeX/nkFdCMuNnE1vYVScvWVnoVCEYwwgeZtMHXov+Lec/zuICEPjYdkofmyRM8ZcD37elyU5WzzffygnPCbasYWrEuF62ZD40MuaZpi6ITM36mLM8dCHNg9K2z7mqvD0ku5kfhDvVYgVcoRmmbrDBmJoyXyf9iNEJifnsXnmm4zu0L27Q2WVtS1foWNwzLkr70752HpXKFCafG+tqzT0WvxlimmrZe4dSLNv6l6RG1vWpeZjyccaw1zTMkXuErJS7e/VG5mmN3rJ0hbVSKXsjf3kz7q3qnCdQF5DmdvMS5J0WCiHkrb5+JuBpT8mma+23c9GxWc3vpj91LYax0yamKfUS0sj72jvbCra8O5UxJYtkzTWv7DnWn5dt/VhobxEfbdcdmnpMkdiLppaL3KI/RSmMVxEnqT8it1dFLZEsI1ys0DuSr6qg11bHoJtRfZsmfy5ycatSoFHohCJQr+yKKREkvQSkS/YrGM3Dr0U70GMPJQOW+S/sgxhNJV4opCEEyoPswRlBI+Cy59DhUXgIjJBNPki99zc/ETkkX9cXgCCtEFfm2KR+NTYYGEi9JMwSKi5s+5CrNn2TwdhzTGnLfiol7S4A4Cs6KieH5aVqj8CZ5GA9XN99hFxJkm4kmJGLljIRBNS9Ol5Y5GqaYHF7eLFKEcV/vXs5SD53Fv2t7HFdfmul0LVkQqWX9MInrxqsFvDVMm4BjNjrOrpYc/iAQgWJU9py9miaeEllPAPOI2ufI/o8sl0KdeTqQV9TtKcJ4wNDcCGSnF/4MwGkBMyNtU6fOvlw+/KZ8PU6P0Ujl4WMnrzqnPBsHVnOTQm/asLJFZeRmLvue6ZLLYWpziwIaBoaluuSswIZ0CVBVClR5aYVvyazi85jiX2M69usawDBDXXX3BAsgL13ICAG2MSUiZUkemXG1GqQhBLWzmrf6heXfT69U6n1QEhqyQ51gZNda9qtXq3u6qAdGrmg530g062VcLB4w95x6P5VflQgvrRsiKsXy4rc2BME6woY2umD8fcFjlj6uQiH3MqZXo0AZ7/xME/zhh+Yo02O/MfXYwIbrQdiAvXvcI7y5owhQuyQRZLs0J1JOfdwcH9/X0+GFFesyYwF2RVQRvYvGX7L+niToxhks78u+C95znV04EtsMqrJg4Mc2hzx7VnmjuzxQG2H5pbgmlGtbVC2+kGhYYcdvM/dRwWVlPD1J/+8gweg25RDtIwGNBJtsimUjEiy+Vt1kbJ17cRlS1z0ueM6UYB2MvffsFY62iUNTcfW0M8FOkGDdQIDCb10311YjI/1gp1/SspW17icdgk1T0di6Uh+OE45ezOHpUnREVHJPEIT97aVThNB1aMufzGxp2Ivf1Gwr2A3yMZv2Ymg5cgKJtpt0L7FqfiMu4dFr+wl/TV2TPTBDl6rhmSo0mOJjn6ReXosaTulVp6DPOYCPAoObdJEjRkgfgt5+RUNcZc6B3pnww3suCXvIz8uKTQQOhtLA0te5FQC+gasy5x5EIJkClV4HKZ1yHdsTT4pB/c6XL59qXUR3iJt1nuw7IlpCvVcD6gQdS1GL4VGdNgKdwsqMEEtZZneHdLaSOD2a7m9lw99FekgLJhK3JLOcgz74WlA00eJbQUGiPHT/hlZEzPd0T9ZUo11S4+jdUGED/mTzN5ll4xr/BMg68AFiDf8CoMw+TTF00JcYuNlLd0AigsZFAMpR9MPZTIcoVUurqJPpj8++gaACXhR5K6Ejv3bRflgmG/UCkuyIX3m+NXKw7fA3FVQ8Mr8AVqtGayke+2WUMUrpZ89OZaUVph7r48+B7a9BXZeJOuUPlO6KvIHXqGv4ZWb4moPrHuVH17x7E0A28a2ZxEuMj7E3ll7AUamctWUgnCUQu1GjyhfAtObv28gQur8dMsPHJ26yvx8+/9NKvOU9Pkrrm92zLsxJ+AX51V/gS+qNhdoF+oHc5pljk0AGsmN61qC8iPypyZLf67rDPKpZSlqpwPBJuZOhQajM0Am8RCg7+XWvRDhyXJis+ZI+3Y2pww9Jo55uLct16RFIYtc6emEYPiSTthqL86bW9NDEoHCViHByD4WYy49ojFp2Zrku5sivXVY6SfK/w1Sfqpou4B7jGpcEhlRvXEDPPOcFcku9gNOn6JmlVKP4wXNSxVqjndcm6qI4Y1wzmhwFfh09VzWjgeO8vb4kf6q7O2nyC2SJ4jFToL6pkfOJo1TarADA/l5EM55Y+ZM3O2qjP3lnVlO7F1l4NIKPm8bFKVXvczwdtetN9crXUon37LoeA6/mLZxn/kD7Y1Ft5bEzgN6TCDCwN/FvIJWUlwHfty0qlqhsSP8BWTjZxPbWzAAHY3c7LBJ/nwwU9nILHsETfVuYwnqFboqT683Iq8tkBdkVYDzwAQg/QMMNda5sOE4GvBuF+BNtoOhwKurqHNxtxe0mCeVV02seBNE+rLXps3cNS4Aa7PvLoTb7Is/C20cpOF+zP8bbjbGzbhj6DwTG3rzlCOtTnJZNlBDR6JrjF6q8LLBwsm4aJOQ4+1Y27SnATZb7nBrstt1/liuLdbb7pu6s/TcE1ubTx2YZOGa/55URfqM7UOt/YzNR1+YKtdtDnENqvjHJHb85LfJsLTFHh6jolA3XnLEVCSxZbm0xGgGZARZDFKBlrOMpB/TS9SUplVgRm4t9wLfwy3rC5z3RIOuvMNFZlzawgbQpAec7qwMf1A4NNMiPaO+tr6g8dVU4042bwq1oPHPFMB4uNHL5BT6BAKPhPOO3YDndzkr80vUJ8Ghu14kL5sUArbFrJZieTzJ5Q0g0ABwGn8lRRZFeusm/NbWbbL/Gf9elY33gLdyNCLaEDTDXe0G1l9J/Sg4Vyb/kTTTSPi1Vs2mbWPPDiLeyBFtOEpx/+4GQEtaa1r/Edk0lmLeqGo/FvP1rw2+iOtfT2uJHn0/R/oim7IHwtzpvZNqpovLtrn8qUqlPb0munJPC3UQd8wh9b6rfkb3MFWGtBI1I+w6BII+wDWQs2ppYgOOck8Hz5AIDpDOoaZQMsC01DiZdjP1tBEyzYzdQxQ0mih7AkEYv2E0W5Lz4jI1HEaOZYs8+ytaFnMRr/bqpoeVQ82rmYfmVpfBgjAoCOktqSqvRX9fQ4zrMraM1PcR56UuXNRMMiz7myQi/yIvWNUeWhhmMyQ4DDLBEkh2vNvkMdnKp80pPoPORhcmTPqZmpbQ2MsbphkgMom50hlhY+Z+v3aVL6O37FcHaROuTP0GR+rsEW8r+Eq98g9z8LL46V6sBXQT6DYcHx0bV71PuQqbPDowtDqECqselQxjYYTfqOYLRQKLPROFqMbOTMtMycmUxeyZEk99trEQ8smMwddPphoBrWsseC+muU/jiPMMq7rEAqZZdNbyxSoW0WauTaDnlwL8E0Omlu8Uecz27Ovrkfb8kCFF70jx5FJa+Ck+zhyHz/l3n3mK5Iuxb29FH/OBRiuAh556eB7+OMq5FH0pvQd9gsAo8SbUT3DzTlNt+FKJgy3jDJ3eYqyM3dNYgSbh+2FbHu2ZbnXZuQmxbb42LHYLb8TaOZWWjc3+UjoeAM7S65gnNb8FXxtBncwW3UFX5vX5t/+VpWmPxU1/+5vf2Mdy3KD5g20P7u2oanLL7DIRq0L8d7Gub1LzO0IlNg4kwjNaAfQt9zL5EyPmzPMxllahAHdUU+4oyRlRUUEbInuqz28rza6nl7wzkmL51L3gaxfjYJ3uItNEV7Rq0qlzl0s8J14U/k+H+CYSj/CqBKs8A33U+QGewE27c2DGPWrZtSkTBBz/rnMGWsSxyDsoqxzAimNH5cB6RJ5p3pmTsr/zVH54bqQGRny57KbKbrj+oZ+A0mFwXsinfKaykEsf/8dL4hr08e1qKsAwxUWdIk0tqmwmekleLdcyOfn3BHj1OIAI0ujjHuuxWbenspNWDrOZ6IpTJr9SJYtuozoMvolL6MIhDLZOnXgWX1SocGc/ki4Ve+NRCCYb05K1gL8gHJjMhE6RMeNHxl3XUiQqKvN9+I+oleSN4xrM/z4omXLc7QoqIeeZ1eOgFtyJKSJ8gZdIvILx/iPuEGPkkxCfW1O/bzU6NxQuDD5uPemCv2GnEojCdaGFiTunlnDoSNcFrSDYI+5tpnLvwkHsl1rQoesUBINoegBBt1DlUkmkPZhljNHBAhfeff8fm3eSNj9OzZPG7+rMf0d+M2N17qUDi7wF68tPyXtCk1M9rSiioi6fdjNivF4YJFVQ0kHyNm2ihgCKvqHdmitqDz2RPkjO59CoT+dDVbnbn4TTSr91ktQifUx5ufgWiGQ1Vw3YFMV/wavpWtdmxFEplzzxO2AYcGJhpBXHyUbm4o72nPeCZCHKeYaSiv9hNnKPjEb7AvPVnhgyBebK9ref8JMNQ+d+WIz9Xp85ok+J1nO0yLjcHnMT2UOEa1wg1n5f4ig/K+8U3eTBV+P+tJbLh8K7RfdmSJm0U8NlbBsiYv0IqQ9T8/LV+wps3h+ko3SaQQQf21uYQbPT4oR+tvqBJZnU1mKLPaHNnhkY2MotEdtjGfDnTnzOFT0aN6kBJviw9grGNz1ZPzs8yKEPZ4nkcIphx+88pzQX2/iHvD3M+CKQiN3NOBH0BRAnGNgwX4jhsO2jQn2c96iftBHFS5V+QhPQoU3ZC4PWTdLpYtz+YhNDFRZVQ0PcLz4cjTCoUCytZUqJB4Mmf86kHyVmO/c8qlYOtv40g9LJma5fAUWPxRrqvExEKor6yfKuntqmACqD0FO89gwqk4xmlOUyuAezTPEsuNQsyzUgOEwa2K4qPL4GhkM4dqMzAMvJ+2WmyPBBsK9F8LE553fmSke3H6g3jEb1HUVmKQi80CXuBPXJrAmw5xJWd8xRpDy+NqU+gc2d+DpdoGyxMf3/NEJrY8cvZ/BJXaPQhm8VCDYFvDpcqxB8aQAWL4ZQj2mPWFv3iRB6HfWsBnXerpEXYv9rIqNin8zovP7+WOfgMRXTYFdirD4ZJx9WeNsPmT8XDcsd4mNdmCMsfuDGdJwnKXWeyyHj+XuSlhLJ9ya/GUBtBFxYV1hJuE3qkArK2VZdTy95VnW8cF1b2OL7migfoLAgB3JNPKIz4fwek8OB20GsIhRJ2P22uRjY2QKXao7cF3/+cEwW1OHfWjVrrrsrpg//OuNl2h/aGkzKIhiWlMHYnjlFznPWiwP3V0xd3jw9tqseeO68scFRtnIwwgzRES9LTTL1gPLo4Matbe8UCjINjScF3zv5d+wTPyo88f8tYkgGyWxODh9vNGEWpms+g3EPblUGLA45OOxtz7XJsSP51xD4PJZ91gWDicBso/kM1BIFUrE4MJLI7F3CfoCk6N6gPGq6nlqxAMxtswRjAHjLUUgWkexnwqA2bRcAbDLaD4EJH+H3WAnN2rtYMXGj78H52FqG5phjq7NUPgDH8DiSsnZv7rzrIMp8uBN9ZiflmEq7GvTG/ydwdlNu9XtMd+HcfDdU2oWqeZGGbtuLnH33mEHNzgzFEVvYBjKoO9aNzKeUkqifuVGx18nMCx4BmPlV782J5aJ59a2ZqNb5lpwEnBLVLJWhh5hG2VWw2GHRTgrEt1ajdKCpACE2MqZoe9hjmDAZo2nxotmvTZRhcj6VbJ5KB1doE1IY4KpsGHqHAE12ByEf4ydReqUHP3aXDsEfo4RARuet8enkP2WtHJX6sM2bf62a6UUFCMsMcTMojn+sF65dA9sMQX30pHjh1RpORqqTLMTKeMsb+3nHOQLJeh477Fhyco/l3Y3SUdUJoAlk1ko5B2cjCVKIxdgxifh5zrta5YuMN4gBQzplkNR9IjHCVuLCAcf8aEo1zG8x1ak+uJmKCNVkicX+B9wSc0WmHiL+8FjcDt5LFd2q6s4v6YFkWeGK4PyIAOn1PWnwlZlwzB83A+ue244Uii3qy+8RPNxvYCPMHQKVs4jtDXw/LLsYsmjXloHaAVUKtSpxB8rX7zsGUsS/U/LWIwHwYwtclA3MrhCGxumSLHKz6SLfIwhHsJZ/SSclVx+mb+MMFf7qNZvJ5pw23e6uoG3BcaCYrQHfKbLkpxLlXz8NQcPLlXwg58TQzMYPsew+G2g6i/q9ecClLDAyxe8NVxUSDa9ZeMvmcXTOjONf88EM3Sp+vipOp2FS2NFEszjE1Es65wfDSu6JsTgtDgUR+Xy6YCXT4/FcA58gwP3bXwpK2pgciTwOt6HsoWrwJuoHgEXnGm5oSEvcFjPnRVwKE+2/muhQHrYtSDF2fmp4AvrTyQ0AWghzXj9+pB++NKdIe4zWY8u/grviv/wWhOyQOYxXfGwyd6oKYHfSraRvzZzAFUzbt6h8h7asKmwh5Y9AaShp+TL/O9SzffF25AkCxPBd2WuB7CNCN3vArjWYjehxJKePMnDFSfPx9ZASb2fxGPQmEQzpmrODGRm+b7Ondu0Ew4NBV4bWNxWU8KMhGlHIDMthsZg2cbIMPsaT78sJmvhS6xWZd9wLVIcST41MsGlkQ1dL9kMTCiTlTlF4f/wkKJnNXh/3cO6NCnaOkf1N0cl2VDZNxLpMBjw2NDE/1CfoSIp8BAL4gYz7zLemNadS8DMN5wIZnZsnKWbQlEvFbRDPhTFk/KwWBkcl0snxYImtOPSaYWf6ptMYNpXq5h2IqgGtr21jwDP/LNqmIaL6mDKeZ3ki8eVfKlUyR8fbjAJPL2b70WgPzfOJN5igSt6ifY8UoEbC4kk5QTLZU0flMThqXZ0JEqFQ21YKh3pFb1SKlSOyycbzzm5XlPKWSNM6Vnm3QPJuqd4y9ozfNIlDfCbtHe0z9D7XJ8YmJzp0XEFcAigzyjjw2/Wmc065xLQbiFD0dgawZQghVJaHjEsnpQH4vQkVzwdFHPlgn6cOz0q67mTgqYfDQf6UUkfrDV8m9/3tWHf5o+bU5hvfK99YB3+mHoyFVHR9VLx6FgMS5Vysbz2wKUusg5r+9jrtZl8zcdweSVu0g36vN5be5wSjhexXaUZbACRkvXSpC0LNAPgwtIPkpIJlwoF/ymofz7C9P/Jo57ZxsYHQmrdV51G0ujWWEQFO3vSGZXAteTDucGQpralz7S1pfOQtqmGGJI8VZtLLa8SF6b7M0p3bLuuLfhkvZPrzXATVh2eHg/Vp1cqLmoO1jDYFm9WET0s3dQ+G7qwNpsZphd/6onCRrKKrWOUclgl9h+Du3ZuO5eYGFbdZta82SdYh/kIurX1ZmkCyJvW2ofZmrlzB3o3rQLbmduuGwq2OkuyHZDt4EVtB1s+vTtlTtj+3HbHwrCFue2o4WF7u/bKbRHPsRA7bJ7Y9j26MxaLrU3MAN6TkqU+r+lie3v1k60Z25vIT7d1PMOe/DRLyDbn8nzGka2u+PPaS7Y31J22m2xjmjtuP3mGQ/f6TSqOYWorMiZcQH45D8csOZgfE+1acmFMcY+T5mY0hAHR9qrek8ZNyGTAJQJfjo2VCsXTXKGcOyywN4bEBUMYN4RUXPVqbxXing8cazyDME9jIhyXT6aSq0LSVcue4Dg6H2qHh4en6wAmQ7qSLi0ZwZKWCqVyrljIHRYiKJSBGFr2FhbMGuv7umDFyILFxq3HkV4X0E6OZWMUNoacJ4OIMKg8FNbrfeGRjfrIMfQ8NDBMm7iOm8OcYWGzcbC7EqzpqARFM9uUZiQZew0JtGxjAJugcnjMHJkey3ABSyaYdacYBQRLswF3tVuswKhaNRDiDLE3tmATC9VMdVxwDKFlkUMLL0vpKLQkRZAlVPwLfoKPhqk+hhdFDn2dVVGTlSqQNeXI9VEL8qarQtCFb4Iac3skINjFkVcDxiphqnwjEjUxtRwEl8vgpPtbQ7vFoHgZLx7NzoXxU95SQhxNuOWqrKPijRXTHnjUZQ0gL4bQg9wB6ilVWkYhoUMRpUCJM82d2UKmTZ7a4s6wZkHh1eTz+s/iYPYx1++f/fPf/zZGJ93PX//o5brOZat3/rX0r8OvlcKX3PB8dMdPHvmZPml/uhMz7eORrre0j84/OrfNQe7h6lOFj/71z39/+0f3slpvnrcqzavj0d//njbPcRIScUm00raAp5zzfhQ6admjcLiKVwY3KbImaewKPvss444PrMmVtgmYreJ0LgA8+kpiamDp8xIwu42AmgB/e/AdPt8ajmvZj08G4+a8huYxuXPCKVPPSY4wH+/nnzaobGE/JgJ3vYBcKdbblmmNrZGh8fFCT9a8xOhBan1JWVbejMwMpU99fkR+KI8fHDo0bAceCDir6mV+LoNHdgMZi9/A4RrJTDzgkTImmFaRmdy2rXt5A1nWt9mU3Rumbt2/heBMqNjpeANHWXiohGjFWaEWKHQjq1+5knnLBZrA3QevhGhZBShj4UqUUm8ObqT0daO69Wd6E06EotZUKfg3XkWuyM0CGbygBJmKIlpYds0LORT6O/RsYL6Vm3cQfi2fRDPvwib5DYHSrNw6U9t6MCbcFQmvw1xB1Vjexsz0aVI5VWL2Tzf0SKEZYeJ9a5hSalMhYN4WRXr7fSEY1QgZLJaFnz4XqtwLqH0ZVPmTRhzEoQU74VpsKFyMX1e7FCLyZQP3JerZDAezpiVyCUQe6DVZQ1Gif0g7UPNYfrB+80tVwAsYL6bP8QP5Yk6ewwhzyLO2SteKpKw0fslTpCTmS15Bt1HSAqb0BDUlpxZkmXLXKx69KxTeFQr/iqwkqcWkFpNaTGoxqcW/tFq8cIe/uHKsOk5SkgvlxZlU5yRDkAqH1szUn2+03khNy83JrtZR4helJVLld1aV9xTpVOq8TIgQX9pAxos7fczElVzNwGtqUbJwXO/HW2Pqx8W2njUudmspI9ZIoxvO9hue8OAx9DExrW4WSiWYkPPqRiriKqeD0G9+Z1PuOOxGgyRXY6HfMPAaGZoB+W7hglYpV73fwyNYmnQzHsDnZe1VQ8F1lqMAQlftp4DPZjOO+yiVJcuWKYm8iG9IUbI0yG+thZV1zX1gqET+bZguORhSyqzPG4zNl2e9bM/ObPC0JM+hUafNGb7xuCO5wrc69HSJwjceeDhB+ObDpqyu+5NGZTute8lUnpqI1d9aSsP6K+VrWS89i5LEnidJSyC7rcjFms1MLSdBTvSjTgJJsYZfLZMVFzi8epSHxSXk4CObQ45RLuubRzOl7bQcuZjz64Xyb8mllNtCObdeMOcWZdgijr0bHFvx4nXsAH6eTEP/IXcKAw1j2b0fiBiwe1VbPQ27V49G2b0VKYKz29x9IbHks3UtF5xqpb8IC5fncpGUpXhOrJ1Y+89m7T7ffcgNLXskcuqQ5cBXaig4ScBhsazSMmPtrTH97zL/On5m98Z4zMaWI0Ki9uLLYJgEd+JCJdk80EaiHdnLBZ6cejHmvugEdUYBAjUW4YvDw4PRhUEXBsn8dDH8mhdDahyvausdIjiksQDWMNm6E344zMDfIwxEizX0LDoFI29MZmPXmEbYuROy+5DZJ/1I3gc7pDaNjD+75SmgG4JuiOe+IfLIqLdlG5ra1tAYxxdVi1ZNGQm3rV5IlPGn/kPLhXwJp/PgN97j7A1MICu9u1k2vbVMkfXyvUjIhHhwhQ01TybC5VCR6O21uRjKPafT/OYwbea41gRLCgMED5HR0KWPaXVuOVQn45ptOY5fZUvWG4tuA2uZ48dQVS7X8q62ZaVRnr30ioR6eqqTt5IK8f68d+DL3DZrulvlAsxxIeKZu8szn4lbBiwoWZ7OpqkWNbF0Y/i4jPVd4i9LuV9+gYzbYPqG+TCZ1O9ns8GsFNI9qLLXvzFkxkJZvTyrYeScw+BIISotWk1xnlMiS5VNc9dfEywFDkUFr02MecLKfuZsPGahyohjMXTZzFQZK/IMq1L6rE1GlTkScy4R3cVsoVBgV70Pucq1OXh0xUux6f1TMi7DRz1Rv1gCfu5heIAB54ap8cHCO8L0EgxhbBs2mmUDFXd3K7gO+xJEJQxnYzQ3Et8mvv20kkIo18VDoKNRvfhsLgUcWrW6DA0tq90uefplWYyH6s8pLrxYgTQFUHGhEYWX3uRVDJza6M0gYGuTt6eo9m/yorDVy6mE3bhDEgnC2QqBL+4KdOTXRu2nS+awcrxMBWY837iByYRGDdEg/XDF1BiO+gpGvhl39WPUu7KbdKEriGGOj11RP2PwioI7PwPX9hliinLvQFTOAXcg3u5AuxXatxwWLTVH8UZqfCcn38lF34nAEeEXpn5h8vFFICI+JKP3lCg4lXHSOkMJ85Y7t0JKol5TfiwewHkdFLahfrpr2SLPOn69aR+6rl5TLaEEbAopq4KEMx1bXCazxoBuSBcdqqiNfbAzZHvsCp9l95b9bThWmReqoXTOQfq6f3zpLQkelH3lZASkl5ji3bV5Xo+tHC43aGpbGPZ58F39hQlefxyEG8TsBE+TU/04xO8ZuVoYpXJarpwWysPSsDAsn5wOKsPTw+NBhRe0I/20UillsplBoXR8WCprx6eF8qDET7VBeVCp6Mf6cVGrFPVi5q8fae9KnG9f/ivPTB+PWF9tY99e08wePYZrXAChxfDM6MAvAov4n38F9us/U6xByCStIte2tiSrDSzRZdg2U1aDW7PqtnxLnuFQYGGIC0vqq0resZmIa4xMiMlXBBDHQXEoebm6eXX2k6y6sJpLOKicS0rWqR4O80zFYPCBBV6pfrRMUJdlzLc0m6qy1HKxItwQlXVpR3CuzWg6CQCWeHohzFiiTRyfITKZ/gYTEEDW5390W0243acCWO58Ls9Pn9lgNv7G7m3DVbUEVrHTa/OX4ad/fs9AXtDjsvciShyreQawG2lUguZUbz3pzYKc2wfTMTdAFs9g2DokSDj/7AzOK07jg36nTR6+Nf4Jgd9/PYHXKPpcl++Gj/L25e5YhpPEAyNDIhaYwAKTNX5kW8uYnyNsN+dJDil5YPidKCuEX9Rm+b/Pu7BGhuOFKi6XG0ET0YTpop1XMbYwv5wTH9cVAZljseEM0j1cm7qYjq3HCZwK9GTxO8uA0H3F6FUuME8EBabJx7bg+iMkiXCE6e4v/9speVKeub4c0QZ8Dc+lOl/bliefIiGuzQ3DEyF2+DSJUB4qxRUxr3kCzAu+/VRqq8fCXE9952WnWeB4XbDeK/7lYLLz3xx245E+pDW4dd2p8+7g4L/kz31D/2/5b6V8UKUCOB0fYZmcmzyrTqdCFrr0UwypvqPdyORF8hnDQTHPFSbjrjWBVI7jxyywQmFg2m/pjJLtwNPIXHVZQ8zElEWgqCPdKSdT4D46YpfvswxOFLjYgBubOtNF8IXyunFMLoc9gNOJXb7Ps/P/GFM2sHRDWQwAzzZFJxwkA7qpyYOdq5uahakfYGw3o/8Y0xs5HgMsV+GiUpIBfyqpVPUCKkmhDgVpEc0xguXCO4FFHAxzOnNlBqObULEnwzIxfSQafvIM3QBYEYhxdqPo/kbmokD+cAMzeWSG6bgCxH55Gcnf4EEASuWfzKLTUXNwenLfSn3/6K4LeWuEMjhBuoDIMZGplOQJw+JzeGi2xpBip7Badw6GzU1mmDJdlO85475WLY8BHPPgHKBPVfma4DBYtuflZE3LJ7V7cNW9zITx3CWZdEOzjTrFwLZmP0qSGHDtmzUcBqWA8BGVLdN+BIb7chNJzlMUujxAagN47bdS3wJGtY18RGGbbmJCooFw+bqX0LdSHpS//NS/KmIvIO/GwMWAXZNurUUHqM+svFsjy/jYsYJshDx8o3iVLNQtADWN7DEkP1LXzHf/mvkRe81A/URuG3AokDf4r8jD56XmKxwdimLhaFgWmhhWuH6q8cMirxyelPSCdnh0uHgZqryIKiHcbDA2tBA061PJH/WPYFfk4nirJh/I/ACB8sDmOrcP+EiYbh8Ec9z/A3U5H3zXjYkwgfX/iHVhYguYfBlbyfmt5Lwrfh6qh88x/zkWPLc8iTL3noBZVhuL72sWXmKInWOOxk3YUt2aQCKcLMPTFWTqDWWW9CaXZ2fc5XhrowNEqRv3QnwbP0obD7QKifPGY5ktT162Nr9X/TCpeMQ7Wf3OEoF20e2dnyjQRTBqWcRU5QDESYYS8znJ8Lvn7HUh059K/VT7WK99iqacVDkzV+blcfx0oYubCOlBU9RzWdnAmok9C6e54mk0sScehBp3xUjmGl9vWt45Uu+vOaclb8ehyyf84UKYI/dW5cFckp7IM+FlmuLeYf83uxS6wVEDjasmg/8lTrkK4wAKhkcdPxnmmA/EWG6JsOEIBvklfS0zbh2e0OTqokOwnn3ZwFp1ddS5Sd5+fAbGJUnJ20gMkRyISL2w2EOwRhtxJAn27Uw2U+t+BrpMhTPoLubB3GLwxkJsRMxzYCJe/ZSuAo/mMgNgIJGX/10JAMDf2ZuvX79+zV1e5s7O3ubZJYe86sOhsAPrk5KAFdsApKJpyXcRpOgolBkI+pA3fjPmcpwrHOZKZSDFCE/xZhWlAR9hqFgABM5q/gu+Oc2w5TjVPQVWP5B6ZKZ+ZmFzjl+OIMrLmH+lJZFOdO0lNSyeHn9wj0i1yalhI+wnsPjPt9qUiYitYShL6/hxXhKQbMBwwisUZpThWnvh4BjF2mTfQWJCL3zoRzYz5o57haAwfQkAbz7TOjyNlyrYYCWWbOURkYnMf2QzJnw7VvrUkpUI/+yVVkSCDGzA3lXNOgLOtmuxP5e95vz1xhN4dXEnxrC5TkjYBSlXiY+aZYLRwTmIjO7gbRLradc7tXqzVz2vZ7KZy0az0L+s/iH/VH91ql/6n6sXV/VuJht6vF/7WG3iW53WxUWjed6vfq53ZDutz/XORbXdrp/1I+13qr1GS1pQ/QNyJk/FEv6gjsvSs/RGPGAqTEdqf87bZQcom3Etl8f30INf/WPJXRegyMK3B0Bfy5udmYa7pL1LwZ2ZLcAMz/CRcFmRObEsJdnG0+TfIoQY/5xilc7a9DT3uOKQkRVdto/ztBElS2/tlrBUeSxQwegXll0qISv2hNvfdOvebIqRBYWe5fqXjwqFAsjb1sBynd4DUG2pUoAvf2QzXNcxazcft6O3U1TZmVMlgDlzSLEubENjQVrJ0E0he1iUTRaC+7y5SddqmA4ySyMFvS5QsplrzU/x57XghQUuExbec99o9KIRnvPCggy+XFoNNDw378GlTD5ONEm7mBL8tmo1/QjMv7aYjboDXJpVUa/reHqdNASBtwJblEYYePoKCrafCZcbY4d9AWxDJhv9EtrY3bzWeCfl54wRSWYkz/7wI2QQMQ6AlDc1hBg5eDvWAFJtMPhdmkw9Psl0w5H1EZSWHbYYxIUxgst1NLLFCONuomaSJV2kMIVs14DhV3x4LltF+g7iBJGrbr3Tr57Xm1BJutapfrnot6867VYXBIdG8+yq2+t8zWQzn+udXqNWvYCnWs1evdnr9762Ubqod9utZrfe7/aqvavu4jf9WrVXP291vkatH6Qzh+1AHQi2WttqYosxh4ziUh+zsbaazCzOuOtVr7AxDsiAoDZUh9CRJoteSCszPs4cASff9ZZA6kg3/2X+N/0GBSqdPzrszQzzyN0cHpf1G6wuA0/cyyfAYhg8clS6v3nruRvZDdx+tjW+kSGzMiIH3Qj/nhl3fAxj9CtnTIVtqKLo4B3gtuFY5js5H/+zKrOEdstbYwgcAHwUHnV7E5dP/eawMVp9mA0lGgDrphLi3d9aY7+YizWUk0DXpuGyb0JMnQAQB7/p/JHxsTEyUd5EV6UK1cMCLmM+XdI9eyPyozy7OdH9ZdDgaUeuaq5YhsHkTrLspliIeaYknymW3+bZB8tm6txlVfL6E125EkN9YHUUWC+VpwrGHyBM/OWGr6VxV53+ycyR1QHHd8J3CsMC6DNb5amSqyJVbnzp9+Aw2jJS8Y3Mm48V9bwhvWUOdw0Hi7BBjZiZa0FGLfQnyxOH3/s8GE4YgnW83CSYKV36g01phnDYmxv4vwu/qDWAz3VTvwkakqrKGiZFIi0iLSKt9KS1+no80de+FbHj5FsRH/GMSwGtwqJjlDYuGxCNf8tCvQ+vMp81kmXrcef8ueXZl7laUiHakHuSVViGJ2yrAmuHVvggWF3DYcOxhSAa1Zwp0MfKikdsYpgz2B1ZfY4J4DjYCxKXpAsHyM8JBqCKjTILArPViwGxqeBfrxhJEq+kBX+mBY+joKU1Hdejo7qpJ1NR3dQXt1SxGce4E2833l650LTBCRRFi/96qYs7C5UsV4qW1ZlrmdYE5IPuo+OKSZ5Jvf4xEuqz8BiTnh6Hval2m85baSMFjC3PeRKmjkGQkGBJDI0HdRJyKK4o0z2Dd6VLz3eFRGSem1zxpJxlh4dHxzfMt/d7w8cXq118BDJIqNpYCw/A62tK3L/SsqxIzpfi4GFZ8yV1VFcus/disLrLVwurWY6ntzxXYpqlA4EnLJ/X6oo1vOpm27249QO2cNVNWsB2b80z9fon+/STIgukgudh3aPiv7nd5fObXbF+9atssxq3fvWrpLVrVtc8KK99qls4Jja/H7dn9tRy1jdEDiyXYQNsKltYc/mXvr8hhCthjlAYDx1Ba08Q3pTYwDVnFn1x+1O6A0+fxlNVe4wMzHtxzfmEX0sxm1JhvekYpj5z3A0AhN6La04n/NozTCccwLsJ90X74uNUBNBGKcs7ws36zwKwScnBbDizUQeQyCbp7PKuq2zAjjBIYVHgWp9nvvwAV9VY/di7BC9V47J6jtgZhfL7R/VztVvrNNro6Ooiquai2mj2e/U/4KsPrWYPvvwD3/5axf8+N87qrUw2U706a8D/l9XOp7PWF2jvrFW7uqzLd943mlX0knXrnUb1ovEvANzAQ63ex3onRTnX0InxXE7d1MVxI3uiPJ4qFY/MGIX3lLKTlgqFLCsXDuEfMHdinr4/G9VmNWer2Fqhy4stQEDd39/nDW7yvGWPIPZXqVnOATyQk53k8J3Fb/IPt+5k/DYSnbXmOXs1c3r6JRzd/Y3R1PErtiHAOl2Dq0iz0fzQ6lwicaAnuXtVq9W70mV81ujUa4psahcNcDDXO51WR1LV53pHfVyLmDDKsC3sc0R3JK7iBTwqjRqBx0KCXNBr4rnVpfXCtaYMp4dSn4dc8wEFYEbwzKLIDuFZhWwSD5CG11HFdieGm4WEojZX7fHpVHDbxyqARwVrel9nMIDpOhPitHjQndl0atkgnlomuzVGtzmN27phcoCPBNAG53eGDdwb6AkI0iJiBJeyk7BLwzQms4nyYRkOKyUdFFqz+DWbgy+GoFDFwg8CzP8cwPw8cFRmWknAi8a0h7WgdGFqoqHKEic/z03TclXezg0rH8xMODB6X37u22LYHxwNDwd6sVIulE8LA61cORkOxbBSPjo+qRROBkWJzgb08uLc29JorAJcdbUBQL+31j2bzKCEiD/JcNofSCWuaBcDFVcjyOUIspFFABBmAHvZ4pJwrp3qJzovlnRxdChOT4vl0rAiNP3wtFISRwRYf12A9V8V8u3BweYYTTqU9zqQ7uqE/8cyBxac3GIhXzopH56WQaWBNN5TA7LGvstU8oeV4kkZ4nGHXBMDy/rm5UC/NeDN48N8uVAqn6YHfFcTwd1FAnYTsDstsLvB3lvu3gO6jTzcKdLVKh94KqobLJN9tEyuD+rODR5z8L6Mel8G8Q7snokh7qGCNBEEOFy+Nh8CLglcg405O+pykDZBiglSTLhHwj0SpJhIi0jr1ZMWQYr3DINHkOL9AD0SpHhXNpggxftHXQQpJkgxQYoJUkyQ4h3E2RKkmOA3BL/Z/TUj+A3Bbwh+Q/Abgt8Q/IbgNwS/IfhNBH6ji6ktNMmCVca5XxiQE1qNNct1+OAcAMfkA5xLfNWoMGjmAaJKDKwqlPPGYFhmzj9asCzsz8iysq5Kc/j+kZ15knKay4dPDb+UtqOuImc2CL7iRvQzgoXU7eaBhvp3pYO3XoWi/DJ0UYBSWgNVFHopXbZI1Fb8N+JQRcveZXfWeDYR6P7FZuLhRHw0asDJulsVXVlVSShBHDDUG0GOdSnoo085C7JbyDxt2azIbq2Z7b/mvA1LGssa3kTS4EE7Ob+dg7dK07MmUNpLz+J4/fErh2/OEWPUtGLTwKPS+DsbGqYIzQODo9CU7oPcUEpwbkHzs5XbOc8aw7k2wwNwLUhnyc3ZmNtBdna/02ysVpiE16LN2r3NihfrirchMbh4BKWF8Ksi8OriPeUUJQAgoZQIpUQAQCItIq09Iy0CAO4ZYoYAgPsBUSIA4K5sMAEA94+6CABIAEACABIAkACAO4iKIwAg5RTd95yie5aEc89SpFJOUcopSjlFKaco5RSlnKKvF6BPQQ0U1PDKghrioLVrguRPjgZcnBS0YakijgeaGB4elwenlXJBHxwOdDEA7Ofzxk+EgW37g49KOGQfGh969Xqzf9loXvVQgms16/2PrauO+vOs+lX99aVe/6T+vGw1ex8R10wBJxRwQgEnFHCymwEn2QhD/2sx/oCiM15XdMavHIuxYXJUwPknxV2EIgwSgxb6MrXqwXdfYP+xURyDWuL5aIZQ3MJCvtPlkQ6DkO6QXzODarQl6S6UnWR9xUbh7wKdye8tTYiE/7CnbEy5e7uIp1KNy1FyVw5SQN9ScXAtT62LsvSAbFSQUhx+aNMO4q6/q26906+e15to2etUv1z021eddqsL11WjeXbV7aFx7nO902vU0PBQazV7YGHofW3jnVbvtlvNbr3f7VV7V93Fb/q1aq9+3up8jULYKejkNccxUNDJK9osCjqhoBNCxhMy/hUi4ynohEiLSIuCTigGgoJOdm7BKehkzzeYgk72j7oo6ISCTijohIJOKOhkByMxKOiEgk4o6ISCTijohIJOKOhktwI0KOiEgk4o6OR1BFBQ0MnzBZ3MI1UTjuiOwaDZzQJ8+YYp6JkDyo3mjqXpZsHcqBg3D/kuA8tnoqf2V1qDeKBNBAauiyFHuG3061WQ9EXs+V8UDPXKK7xQhBJFKFGEEkUoUYTSXkYoQYiLbQhZHmfd8NlK6bhUKohi4UivlA+PSgNeLBYq+qnQKxVxdLQwWa8rqlNDkVAUCZWZj1FKGRAF5v++LFyzeTxUbvCYi1TAWaj1EngZ0hZ5WRb45Np8CEhAcMaH26SqL/se00EBOK9osygAhwJwKEqAogReYZQABeAQaRFpUQAOxYNQAM7OLTgF4Oz5BlMAzv5RFwXgUAAOBeBQAA4F4OxgVAoF4BBYlcCqu79mlCGdQIGvzMFHoEACBRIokECBBAokUCCBAtOAAnUxtYUm+aLKC/0LwwRDq+E/YoxMy/bbWAkZXIQEJuAHI/i9BwgnNcyxcJycNxAQcPzzBWvD/oysLev53TFUER32/pGdeeJ/mguCT40DMCrPbE046rpwZoPgK25EPyOoUd1AS8CNb5lhOq7gen4ODGmYQ2EDXztQSMX1E8P7TeQ8sOM87PGLZX8DI0K1wfyHo5DGcBL4BCgkN5knZQqdqU48ASHQFf1OHGbPIKA9NII0ieF/vXTwl62zOsT59qrdT4Q9I+wZAWQIIEPYMyItIq09Iy3Cnu0ZWIOwZ/uBjiHs2a5sMGHP9o+6CHtG2DPCnhH2jLBnOwjIIuwZYc8Ie7b7a0bYsz3GnhGUiqBUBKUiKNVuQqkkfAnd/RI+Nc+c/DF/z/wPbQhICH4wHvMJzx3mKoMcoB/smQaHuZI/rBRPyoeZbPDkpDQpFgq5Yr40yLzLlEr500JZ/e64CokCiAsXUsjkdGM4nMFlmnsY5wbcEblivgA5XQr50kn58LQMq8t13YAJ8XE7sjlzjm6QMoSNZn1Y/Xw0SUxhiZFjHuflrwohvV4f0muruK6GB3t5ReCuDXPA+QifJCCXIo3cXWkl6Gli6VKk2ADuBDnf5PsJuCd8wGEBQmqtbG9x6KbBo2w4HrBE8B2C7xDGgDAGBN8h0iLSevWkRfCdPfN3E3xnPwAGBN/ZlQ0m+M7+URc5PcnpSU5PcnqS05OcnuT0JKcnOT3J6UlOz9fq9Hzm9Bav0Q26hRwXvlswHzgZY12jnr9y3fQW/tqyrkq+8OyZLQJnrZfewqP+u9I6eS1c7nx7gocXX09w8MLvz+HfhXbJvUvuXfJBkQ9qN3xQ5N4l0iLSIvcueRvJvbtzC07u3T3fYHLv7h91kXuX3Lvk3iX3Lrl3yb1L7l1y75J7d96964oHl8lYObW2gd81i7/mXCtnTKTPRvlyySFLDllyyL4Oh6xyL/4C/tjF4gRPqDgwX9hhwUOL6opSyOfdrkvLEoQrEeS35cfdqAoB2utxAlSPIJTJMVRSJ9nx/VrrpUm12poYriv0LI7XH7/ySeQcMUa1NkhSp65AoYfMX7+zoWGK0DwYqAZo7fGj7VEkc25BzbaVZyTPGsO5NsMDcC3YTG7Oxtz2Bbqg02ysCp4EKaDN2r3Nipehi7chWi0eTTJZ+VURbsviPVUQIYwKOdLJkU4YFSItIq09Iy3CqOyZU5cwKvvhRSeMyq5sMGFU9o+6qIIIVRChCiJUQYQqiOxgWQ2qIEJoS0Jb7v6apUVbzsNnEo7o7mGz4g7G7o003sETwXnpYsgRlhL9Ohlz9hehZ185ejbsad8fh23Czn9ofOjV683+ZaN51UN8ZKtZ739sXXXUn2fVr+qvL/X6J/XnZavZ+4h4N4IbE9yY4MYEN95NuHE2wtARnwvmPAk9XpOgTiql41KpIIqFI71SPjwqDXixWKjop0KvVMTR0cJkva4IHfz60MG/PBb4OWvUzANYnaRqNYvQ2Y3q1sz3uU4BmxCedttFbNLgXQn9+ZoBhYT+fEWbRehPQn8SRI0gaq8QokboTyItIi1CfxIYkdCfO7fghP7c8w0m9Of+URdhZggzs+OYGcJYEMZiR8yihLEgjAVhLAhjQRgLwlgQxoIysP38DGwLMIuXKZLV87tlqDk6PyM92wJqZONEbZuU0FoGNklXS+t5oCbQNiFN9h28QEiTV7RZhDQhpAm5w8kd/grd4YQ0IdIi0iKkCQEfCGmycwtOSJM932BCmuwfdRHShJAmhDQhpAkhTQhpQkgTQpoQ0oSQJoQ0IaQJIU32GGny5Op/rxBoMuH2N926N/tDy+7zkWRSHiIkDcbEayA3tOycbCAXrHUUXAIJTNTjeI3Ix5kt9JmGFyx2woLXk+AmYOnn4zGbCN3gJvvYu7yA6qt+B/OtQofVhuzTY1+OwqDcCjYy7oQZNnzGYlLIw00ebnLDkRuOPNxEWkRar560yMO9Zy4h8nDvhw+OPNy7ssHk4d4/6iL34St0H5I3jLxh5A0jb9huesOkBwptt9IDNs+c/DF/9+aVKRbyxzDP6OL4s54zgoJOLmxU+WAZmHvLXaYhK5EFwHShGROMpjIhMmpomIDLweacpccsCHIq5BddbGrpFjxv/iTJ9/b6fG/b87Rdhp0ZVXRmvCKH24YJ9Zc4fJKcap4zZ7XbKXBcbe55CrWxofMpfbxzWseTH+a83AVFwc/7GU9Lwc+vaLMo+Jlcw+S/Iv/VK/RfkWuYSItIi1zD5Kkk1/DOLTi5hvd8g8k1vH/URa7hZ3ENc103oEk+bkfeWDdO6GjAxUlBG5Yq4nigieHhcXlwWikX9MHhQBeDRW8KBbFSECu57cltT257ctunCGJdcOGSg5sc3OTgXl07PuLjjl7hq7zZoafn/dZjMFqBDSv8SJJfevGFeBcz5sR5Qn4jT0Rfx1+1cYNLMuMobVJl0vGOxsT7GEmYYw2HjlhleftmeBZcP7/Q4iCVbjYUrnYrYUiRmyTWyrSNxuPTAxXiJr65L46v6TLYjhcgyzzz9w05BCIOgcM4h0DBdwik8BmUKjHPHB3jM6VKVtrFUzkXLmfuDJgs86lxwVgTGE3WdFjR+aPzt/XzFy+Sn+iZeb65ubdmK8bOVTTzEn2nUF3Di1gqlA5zhdNcodgrFt+Vi+8OD/MnldK/Fpb25xvwf6b9+vkWlncxN8jalz0aA2VekTXZ9Nyb8QRWvbgIGQnkp2qj/77V68q/zqu9+hc0pr0/b8O/8pdaq9ms13qNVrNfbbYuqxfwRK2XyWbOml35b/+yet5s9K7O6upztVssluDvFjxRv6w2Lvqd1lWv0Tz3P3frtatOowetffiC//Tb8OvHXq+t/uvXWs1ep3Xhf+xUv1zUO/1O/UO9U+94X7c6jfMGjqXxz0Ymm7moVz/Vz/q1Tv2s3uw1qhfwU7PeQ8MGzKrf+wM+dNv1+lkmm/nS6nyqd7r9aiOKKBN3wnR7sKDrbie+yWAv8qz+ud7sIUiPjcWIa3gFcGkGOa83653qxZpbvkHr8ceidaUsOd7JwBYz2Yx6G2w/3iPtageWs9/utP4hjwR82WjXLxpN+L3XqX740Kj55ySymtbM5SOx0XLKV+WM11uquTfjTGZNsGI1vzTwAHfq541WE2ferPfgcMAsL6q9D63O5bI51fjM2XhSGry82az8V+Om9f6iVfskaa5WfX9R79euYGdrX9/XO9Ver1r75FPxh0YH5n4Odr7mZb3Z6581OvVaDwnkstpo9urNarOGJsU62AkbNVyhy8ZFo1ftfO1XvfNw2ejWWs0PjfMrtA3CV81q76pTveifNbrVbg8JV60sHKX3F/VLWOHWl3qn75+1butD70sVB9Wr1z5if6Gnr5qfmq0v0PiXerX3sd6JbgyaUtbWuHytnbl8lGeX4BFEu7uvzTON2/ajkoDHAuzNlim820rmMYK+15W1t9tznJ0tOg4/ORa8B86F0CikYRtwvfnwpXF2WYS74uwSmHu13egriodPHfwX75Iu7Is8YPj5qvexBZv+vto8+9I4632Evxu9TrVXl/eM/Ldfq/bq563OV+/jRbXbVX9/ajTP1J+tNpxe2WCn9aVbD/3V/1C9bOAN9f6r9BbVqvhP7WO9/7GBp7/ab31p4ku1j/Xap36n3r26wF8uGnDwe1/bdbz3Ltud1mWjiyQAN1H4R7iJ+u2rTrvVDT7jvdSXJvFs5qz+uVGre2+cfWrAuT27lAvl353des3/o19VJ159rJfwQwvoL7w4ZwFp1WVD9Wat87UtqbXe7HW+et3W/2g35MP9bq/au4KHP1a7/Ubb++uy2qt9RGN/s/tFXqrVbv9L4+KsVu2cdb1L9rLe+9g68z61O61eqxbczJ/rna4cUKN5dtXt4TAb4e//0ehJyv9U/9qvnnfq9Ut5z1xUe/VmDZ6/aNW8aXl/9sO/nst/+9V2Q/0VOgqX1YtGrdHCCV5Wm9Xz+lm/c3WBZ+Cy0Wucy/bandbZFUovl62zOvL46mW9W+98rndCnUmRwv+jj+da/R0apvqmV+2c13v+D/12tYHeyZB7pXGBF2ir2+v/86ra7F0hy+vUPzT+wD+8UYUWtt1pfW6c4Zq1r95fNGp9XLqL81an0fsI7//zqh7sdCAUyQsM/+i2W81uvV9rqZtNffaPwtw34UPm/9TrwWi6jXNk4/XICLrtqvzvA/7bauH/V7VavdvtK/qeWx38pgs3T+9jp16NUH3v4kz+25+XKnsX3dBhumqfVXs+aV0B4VfP5XH6XL1onKmzU/+MO/y5XpNn5HO908N76691IBne/bGu+Q4M5jlXPLg+tARZdYjLhhrJMkPPgnlkbJjfBEAmXQMcIuzN2NIUeKXabcIjxsgw10Ufv8Bo4kVMyNo+G2Eg1YQ/XKAtBTKqRwyl3DHXXuPqzLVMawJmn+6j44pJnnXRugsTdgxzNBaLz7CmtNe8qXabbxm6yNGcu+aKbr3vhNzzJ+XwSnlbsPZyeS+GRmoyPp7e8lzJ/5Fplr6uPLpew/EHBVlS6IiU0KrufwovwkhYjRUmjCUDHQkrGGvgpD8XVhPid0J+eeveHFtcz4+EhaE9ecseHYgHOMoH+mwyPbAF1yci7z6469Li8w0ifmUPi6eFo8JpIgVKWl5fj8HX1tVg/Jfix8wn/D+WmZs5OZB2c8XEwbvj9U+Da01ziHhhugXAwzXnsOz1+Nlo1iQ6gePD+NOt8bUno4EDfQg+egFY/VsLvNBrzii2jflpxe/D2Bo9aehja/SEQau30w93YK3CWi52OLDcNYeo3og/HKOpK0cSP1IChr5AzqCU4L+5l5zkp4N7vHK6FIEHDSicxlq9JmOcipVTALv40sL6CL3isTg6OtXKR/ywqA+OypWCKBWHA3FaKA9KolxC1NxKTNbF1WW9mbuon1drX3MXhzk0IipFwJyNJTRkKXZJioQKkuXPYynaJ2R6TxwMmL1/zJFN0vPeXwtDhcOun3F3RX+lQqmEfoNKr1h4Vyi8K1X+tbwxKWCn33984/EitLtzWGAlfoHU5VmJsC6TLX2c8n02EGPLHIGhh705r7c8JQ19gNVuIPgDLn6FjNHuxc7ssbnymJy3e++RBca0gIbjxBbAjuQ//nk1CFAx3flTF+ou2lhkLtn5DVh6LAMPQuJIlNHzR1aKtem4SaZUOj4pHJ0sDS8w9OQej44KyBxQvbuyx8lPg0D67uBAfZGXoszCPnkUmnL4KOwvjtxvJQVH3Do/+5FVUnDKOSwRURdnpFpcm8OvZq1+v6yKA2FfxIB1hX1naJgyYGGLlIif2OjCnOYJxNcTcIBLz710UCy7b6NDmr9/w/6UxEEG7gy/t9VkFvLyLMwp4sgJNYjgW81a1XTNGhsTnmWXhnZrce3//G8zyy7/z//7YGjWsn3A0Ng1bo/j0O3xwwOKxp+j+TM4N1kDVKWIszp8dXjzDY8yuO2ktJKJCi1h2vd5WOhSW0LVAaEtEEg24nhVnpyAU/mnazU8ez6MgVDUvxyKuho+AvuNno6AlGMh02PDcWPA0gffDf3HWojp3OAxh9wkCpsOGZUHj6xxlgCa9m2l8+/E46YN39Iz5e7tYpafoCHZSnD0VLWnuFw+8y+uEJ9IOf9ZynmKZ0knJ5088v5SgB/p4aSHkx5Oejjp4aSHpwwTJ90blcV4Vfu5NO3y4t3atFw2hJictaTRdXN+HOqiMjg+LA8G5crx8YkoVfixdqwdHRcqBe0I6JJ01ufVWUEfjVFZ5XlcM843570VE++LAfmmcBXQWma056YF4fwrU1OnaoOiggVFBVNUMEVl7kRUJkUF0/mjqGCKCqaoYIoKpqjgFVHBFMdKcawUx0pxrBTHSnGsFMdKcawUx0pxrBTHSnGsFMdKcawUx0pxrBTHSnGsuwOVpThWwswSZpYws4SZJcwsYWYJM0uYWYpXpXhVilfdKexvPsDjPgEDfBC5xNdHA+dca7qACJ7DxCosb8hWuAINnPguoYAJDEtgxB0DIxIYls4fgWEJDEtg2GdYWLL+7471f00LVOWQF8v6UeVUnJyeDrTTQnFwqmla5aRQOirqhVNSZ0mdJXU2rTob6KphpdYpFksHSgE9+K57wNY0SZl008nh+zlPgZ1XZRF+z9R3GCTgtb9Ch9UNOLuDmavKzsuGgHkbUp+NBlD6zcart+Ge4zM5dVWTchTclYMQ0KPk6q7FcCfmIzLTZnzauIO4K8PHwSo4awQ5GoJEzgEew+jGCPxb+QwTLssqsCHYFATWsJkjq9GP+UCM5b7IXVrDDvCEJld7HQBg0lclm9cBL25uJFhPRctKUUhw7ZZhFXiQlfSZho8zR8B5dr0l2I4+R0pcRIlLoaGlUrw+WDZT5y7LptxxUGOWmluoD9dS6yWYe2s4OH55BmCI/nLD1yBTj73TP5k5Lhwzayzla38B9JmtYg/kqsCJVy/9HhxGPIeOktjxMPq7/5Y53DWc4aMcEJ+51oS7hgYXkjxx+L3PWeGEOcL1OLDG0A+CE4VTBcfeYW9Cwr1cA0+HChpy1kUAEmkRaRFppSet1dfjib72rbi5Cehpphf25VaYHi3BKodoQ+5JFiqV2o9P2dY8qwO7WGosA9Ibji3LlvIJ+i0Et4Gyi0dsYpgz2B2VvEMAx1GIf8dSdOEA+TnBABw/pmD86L0YENuEP0rTAahgyeYHWvBnWvA4Clpqm1qPjn6+vY82+CcaPGnxn426thnoA9sy4TlPWtQZ5LOGk8FDmFEnz9q2GBoPaptzKIugA0YXfqsOG9rWxFfro1LNTe6qm233bry3gnHhS7A7V90sG8zAyLzsiXbv6cFHr2yyaeFd8ScF5DQDLNHrx154b253+fxmV6xf/SrbrMatX/0qae2a1XUDRV75VJ9+TPBUbJSB46zZRcPl4yZJOBZfjhXovUQDkDWgWsX/juGfD92z9/B/8ysmHsBsK71L/P2PDxjKjw/XzprdT3VMqYKR67V6BwP7IcYbXVJfmxht/7GGyfXPLj5jsL381X/3rAVtYQN1fK5+1ShX5P/HZciS0cbQ7nP88WOj+aGF/3uJVqQFs1uvyeYa3TMMjJcDld99gqjvi0NIo3CBTV60YGAXbZlt46Kq/odJX+I/mIcDoqsvzzGiXXZ6iaHvf2AYe7uHiTXe4z8Qzw1/4BCbjUvZflO9hkbWZrfaxv/Q8gr/HXr/t6sdjOtuXmFimyYmeGm16832eVtOoIXIf9llG/rvyO870GSn023AKHHx5Z/dRhNCvruXjct6FdN7VIO48Q5sQ7f78QO83P1ce48x4vjPhXyvJ1vvXXTxa9mmzDtzpeZ0hVO9anbbOJ+rDiQJ+IIJKP4oHWWymX+1mvXLM/CHzAOS01PQ1LZcS7PGGxGQa3PTgeBN5jWzASEtb2QVQV2dwdL2auEj2rvorhcI71msa/DjJgvgNbBJjPHS91dNu9mqdzoY+g+5e+od+AtyPXyoNuS5lrk14M9Wr3HZlmkUrmTKj6/Br1//6HS6mPKoGfzV6kFiE/kXnC1McHImj+b76pk8se+rZ73GpfrtUqZheF/1WM776ln1Qj3f61whc3pfPau1Wp8a9fU2B5GPbWGfo3twcwTkVNie70YK0641ZbiwePsp50XgtQKp1tPSURWAZ2XUEdx1QugqvSt0mmXiwbW5ao9Pp4Kr3sC0Z+rChsjx64wFusZ1hkFQ58iyH/OsBbK4M5vCyRc6ZC+4NUa3OY3bumFy8D8G/jPnd4YN3BtomBK+4dJwArGdKYylMqkaDittDPL8xdcsIXMBhbC+NIhlItwlS3IpXI657cA4v9wpG9OeZplDQxemJhrm0PpZIJrB0fBwoBcr5UL5tDDQypWT4VAMK+Wj45NK4WQgA5YwGH9x7m1pw4BsWswwdbUBQL+31j2bzLRbFkyS1cbWTB+Owfh+y31nLazdkqM+DxGRI8guIHgCL+wWl4Rz7VQ/0XmxpIujQ3F6WiyXhhWh6YenlZI4kkvCHfdqCt3riwvTMybCcflk6lmI4GmcKtjuZ/haSkAbRALDt2PjPzGxqc3wz0yCOlSaMd9u46tOQVaMZa+FU2TAgsPxc/Kav3EQrKiQIZplamLqOgeR0R0sj2pVpK8yNsk0dJeNZqF/Wf1D/qn+6lS/9D9XL67qoQRP1fN6H/Li4Vud1sUFptT6XO/IdiCv3kW13a6f9SPty2RhcEZmpuEuydJ2KbgzswWanvCRBBJ+cnDh32Aj71aH0arLwVkgAAW8kE2sDtwKoxPmGM38gYqeZW+5JDwOkTn9wjLm5I/5e6bRvitDGGwhXzyunBweopZ2dwwQzKN8oVI+PD6G6XNdN6BHPm5HVm9FsF0wiqzkwYTc+zWRe5isdc8xe45MSBuL0lPEkLsrxcP0dNNxhLYWQg+uGukQgAKKqoHlcD3P5qSQdhJgxgKI3zq4vXBbrqU6CBp9A7931QFi9QdXSdRvPdk7Hs9HODXCqRGYhsA0hFMj0iLSevWkRTi1PQN2EE5tP5A0hFPblQ0mnNr+URfh1AinRjg1wqkRTo1waoRTI5wa4dQIpxa7OQQCIhAQgYAIBEQgIAIBvRQIKLoCzVav371qt1sdqJe46B4Hb42w0RkAc07OLVjEnPpbbW5ueYK2s3ND/4swSPuEQdLF1Baa5NIq/9Ivi0oKrYX/iDEyLdtvIwVCKR/AfWKRSj6I6CHnuNwwx8Jxcl7vhmXm/CMFC8L+DC0n66qUYO8fmV9LN82txKfGARiWISm/o+4oZzYIvpJAKXXPeYCp/l3p4C0zTMcVXM/H46qEniqRdxyqCl9PhamCXF1bRlRhk298CBW7FNotNw1nIi+8s2aXQFUEqiLkByE/dgz5QaAqIi0iLQJVEcaHQFU7t+AEqtrzDSZQ1f5RF4GqCFRFoCoCVRGoikBVBKoiUBWBqghURaAqAlURqIpAVQSqIlAVgaoIVEWgKgJV7SKoSmGI9gZSZUz74NRVt++GwCpjmvMaSQWvarSZen7LIKugYcJQEYaKgB4E9NgNoAdhqIi0iLQIQ0WQHsJQ7dyCE4ZqzzeYMFT7R12EoSIMFWGoCENFGCrCUBGGijBUhKEiDBVhqAhDRRgqwlARhoowVC+OoVqTiCqDw8qhOC2U9dPhoFA6KhVLRydieKppJyd66fRkYYKEVSKsEmGV1sIqRWA5e4NY8tWszfFKIU0tXYE9X5/aMl4prKYRWonQSgSpIEjFz4dUEFqJSItIi9BKBJ4htNLOLTihlfZ8gwmttH/URWglQisRWonQSoRWIrQSoZV2Aq1EgB0C7BBghwA7BNghwA4Bdn5BwE4yc5LS31aSHQGyeDsNXWxpRIB43n7iJYWjvuiGcdS1NqVdIigTQZmeCGUKIXb2BsiEYn1fns+NoUzYSM6VlpAUYCZ4cssgJs8UQgAmAjARyoJQFj8fZUEAJiItIi0CMBGehgBMO7fgBGDa8w0mANP+URcBmAjARAAmAjBtDcBEyWIIe7Kb2JOxMTHctrDP0e2QuDsX8KiUEAL1X3ph0ATB0OTviQKuNWW4sEi7yvSq1FIQGIyJr2OgIAPPMs2amS5QqhC67AnHl2XiwbW5ao9Pp4Kr3sAwYerCBgzDdcYCSek6w8BHMbLsxzxrgSThzKZw8oXOLJPdGqPbnMZt3TA5+DWY7vkInN8ZNnBvoFotfLOL4QRCB7s0TGMymyiDkOGwUtKJpDWLX7M5zEjIV1cs/CB4FMGjCB5F8CiCRxE86ifAo/wxf89UAf9z6gH732WKCj/+LnNSVoDwd5kjBQeHn39kM1zXDeiej9uRpVyNQYpgjhYFOcIWEbaIsEVPwRZFIDR7gy7yJMc+mk2egDDyGsrJhlKhjCL69YZwo6Bh75Jg2pg7jtR85jshABIBkAglQSiJ3UBJEACJSItIiwBIhIchANLOLTgBkPZ8gwmAtH/URQAkAiARAIkASJRBiTIoUQalncig9EtD+AglRigxQokRSoxQYoQSI5QYocQIJTaPEvNCBt5lTgpBXIAEhvnxAgrU5cUKKNiYF1gAHwk7Rtgxwo7tKnZsARz16vFjAfhrQ8xYCoQYKiT+00mgsMV3wZ+ODcQjvvho1IADdMdX6ObV0cgWI3nXG+oNTzjxpHh0+2dBMAt5ECybFdmtNbP915y3YTFiWcObiBE8aCfnt3PwVqlx1sRwXaFncbz++JVPPueIMapRgf1ZMVihh9w/v7OhYYrQPBiIoujtUDQ1FigCOLeg1tkKGZBnjeFcm+EBuJbFRjY3Z2Nu+wJE0Gk2VuVLgtTRZu3eZiUkyLwNybjFo0kmK78qAksu3mNWTMJoEkaTgGQEJCOMJpEWkdb+kBZhNPcM1EQYzf1AkRFGc1c2mDCa+0ddhNEkjCZhNAmjSRhNwmgSRpMwmj8bo0lpFnc4zSKhE58FnRiHlVkT7XZyNODipKANSxVxPNDE8PC4PDitlAv64HCgiwGAOZ4XCBl2Yu+PLzThkH1ofOjV683+ZaN51UOoW6tZ739sXXXUn2fVr+qvL/X6J/XnZavZ+4hAJUKOEnKUkKOEHN1N5Gg2wtAXSoIS3PK1wS1/XXDlSJjCBk9izgcdZVIBKpOAlCH8YAIksY9NOwff/UCiH5tmthupwLVlWMUQPtEPfRqEopc2ymTnARiXNZgG1RjuHXWGKXdvF12gKupLjoS7ciACepPyv2t5sWNRzhycfgUejnP5bdpB3C121uxKi0b9rCktMf3P9U63gSpHu9PqtWotUP7+eVXvfO33vrbxNqp3261mt96vgYoWwZIR+vM1AwoJ/fmKNovQn4T+JIgaQdReIUSN0J9EWkRahP4kMCKhP3duwQn9uecbTOjP/aMuQn8S+pPQn4T+JPQnoT8J/UnoT0J/EvqT0qdS+tRdWzNKn7rH6VMJNUyoYUINE2qYUMN7iRoG2KltCJl7dt2QlkrpuFQqiGLhSK+UD49KA14sFir6qdArFXF0tDBZrytKBkvoZEInR3DDTu6ulAanrJuOI7QnQZShBLdqJlXpbQmn9RSJNVKtxtffXmz9DXzdVWeM1R9cpZa89fulNK17jv0koO4r2iwC6hJQl9CEhCZ8hWhCAuoSaRFpEVCXcKME1N25BSeg7p5vMAF194+6CKhLQF0C6hJQl4C6BNQloC4BdQmoS0BdStNKKMhdd1ASCpJQkISCJBQkoSDDKMhkRtVs9frdq3a71enVz5Locu6OABeYsNHDAuuSj2ImCkvtTS/Tz9ziBp1m5ya7kGOW8JyvF88ZKmjv5ef8ZRGeobXwHzFGpmX7baRAe+YXIJ1J+E8fgPmQc1xumGPhODlvHCCn+YcLlob9GVpY1vM7Yhjt57D3j+zMi+RKc8vxqXEAlv2ZrQlH3XnObBB8JeGn6t5chKH270oHb5lhOq7gej4NblXoUrB7EmoVG0mFWYXMrz5y1Ht+C2hVbPeND09ll0K75abhTOT9etbsEmD1l8FAEmD1FW0WAVYJsEqoOkLVvUJUHQFWibSItAiwSvhJAqzu3IITYHXPN5gAq/tHXQRYJcAqAVYJsEqAVQKsEmCVAKsEWCXAKgFWCbC66w5KAqwSYJUAqwRYJcAqAVYJsEqAVQKsvhhgVWEvfxG4qjHtg6dd3fBPAq0a05zXVCroaqPN1PPbTrUaapmwqXsOdyRs6ivaLMKmEjaVAHQEoHuFADrCphJpEWkRNpWgkoRN3bkFJ2zqnm8wYVP3j7oIm0rYVMKmEjaVsKmETSVsKmFTCZtK2FTCphI2ddcdlIRNJWwqYVMJm0rY1PTY1Eb7rvzMkNRG++74JdGoOCXVLeFPCX9K+NPt4E8jMMpfBIXq691PxaCGFPgUCFT46L2xFQyqd1UxbcwdxxiCuDF4DPogNOqeAxwJjfqKNovQqIRGJcgcQeZeIWSO0KhEWkRahEYlcCShUXduwQmNuucbTGjU/aMuQqMSGpXQqIRGJTQqoVEJjboTaFQCZBIgkwCZBMgkQCYBMgmQSYBMAmRuD5ApRefnRWRCPM4z93Dx3HOAyKIXBJWqQKaLbjiQqdYmgCkBTAlguiWAaQgj+YvAS1E768tz/ESAKTaVc6VZKwXEFJ7cdnpTbJOgpHuOTiQo6SvaLIKSEpSU8G6Ed3uFeDeCkhJpEWkRlJSQjQQl3bkFJyjpnm8wQUn3j7oISkpQUoKSEpR0a1BSSstIKMDdRAGOjYnhtoWNrrDk3bmAR6WEEKj/0uGKJgiGPiZPFHCtKcOFRdpVplelloLAAB4lpWOgIAPPMs2amS5QqhC67AnHl2XiwbW5ao9Pp4Kr3sAwYerCBnDUdcYCSek6w8AdObLsxzxrgSThzKZw8oXOLJPdGqPbnMZt3TA5uDCZ7rn+nN8ZNnBvoFq93FTOLg3TmMwmyiBkOKyUdCJpzeLXbA6MFvI5FAs/CKhKQNXd8wASUJWAqgRUJaAqAVXDQNU1CeqkUjoulQqiWDjSK+XDo9KAF4uFin4q9EpFHB0tTJagkgSVJKjkRlDJCNrvFwFLelJ0H01ITwZMes3lZHOpQJMRi8NzJuaMdkSQyj1H6RGk8hVtFkEqCVJJuC/Cfb1C3BdBKom0iLQIUkkIP4JU7tyCE6RyzzeYIJX7R10EqSRIJUEqCVJJ2TkpOydl59yJ7Jy/NCiZcK+EeyXcK+FeCfdKuFfCvRLulXCvhHsl3CvhXgn3uhe41wXQ5n5iX63pgW/cXQ/oak1zwZvzmFbQxwKj8eBxEeS6Ase6uoF4hCpqcU/QyD11ZR2428YNLtHllDNK6X7eCZ94HwuE7SNsHwGQCIBE2D4iLSKtvSItwvbtGRiGsH37gT4ibN+ubDBh+/aPugjbR9g+wvYRtm9r2D5CPrxC5MNqR/48VI0c++TYJ8c+OfZ/hmMfFs61ppFKq08lrMohL5b1o8qpODk9HWinheLgVNO0ykmhdFTUC6eL05AjeF7/fnkZSblsCIbKta6ddeEOh7qoDI4Py4NBuXJ8fCJKFX6sHWtHx4VKQTsCzosj/HX94iNhChtMkzk/Q0kmpS/cmiZ5vwPPbrLL+EA3HUdoB9/l/z82dyFDoiTZyAbOZCmunjW73XrNA+Cu5WC2hpHmXEv1EW73DTzRVWeN1R9cBeR96/UY75H2J4bi6JS7twujW92Jy90ZstyAahUuJEY4XaPJeH7bvWq3W50eJqb2rqnwd81Wrx98juSdIT88+eHJD0/OQnIWkh+eSItI6xWRFvnh98xxRX74/fAUkh9+VzaY/PD7R13khyc/PPnhyQ9Pfnjyw5Mfnvzw5IcnPzz54ckPT374n+SHV47jFU54oZvOwXf494kOeGhiY/d7Hb7ZuvMdW33je63ZpdBuuWk4E8kFz5rdFP53Na9473uqXtZ2wK/XKvngyQdPPnhyFJKj8BU5CskHT6RFpEU+eHIJkw9+5xacfPB7vsHkg98/6iIfPPngyQdPPnjywZMPnnzw5IMnHzz54MkHTz548sH/JB88Oo9XeOCNaR+sv7DV34O/n+iNN6Y51dAmPnngT9xkjTYLGnm6T36h1Xine7AOia73aFNpXevRt+LukEb7rozlB++OyS1ObnFyi5Pvjnx35BYn0iLSerWkRW7xPfMjkVt8Pxx35BbflQ0mt/j+URe5xcktTm5xcouTW5zc4uQWJ7c4ucXJLU5ucXKLk1v8J7nFQ97psHPcdbn2zTkY80dhHx4or/XBd92rep7GJ64ayclGcp7re94Jjj+zQ6YeZ+pXEG/97lY4vXUD+Mdg5t25800qQ7wy3Qo9aDgh2Xuo73i3d1c1KcfBXTkMAT1KOdG1GG7NPDdN6yHfuIPYm6fT6rVqrQt0qPc/1zvdBkqln+u1XquTyWbOrvC+gO/eN3qdaq+Ov3Z6jVoV32qeXXV7na9RVzy5p8k9TT408qGRe5pIi0jr1ZMWuaf3zJ9D7un9cKCRe3pXNpjc0/tHXeSeJvc0uafJPb0197Qx/RwNnkl9TILQGPamMb0rszsnzyAEZl3VN7mhWEF/WezNOqx0aluupVnjdBMPGS+Rw0gD7kGZec2kmXSqRlZN+OqsnclmejX4t1G7hP/OO/X15q4bttBW3yOBbff+Vt71MIMbjxHesCFOTHkwHf/qtma2JkDhc7k9Agu6x4+T5Pxn6GvexKyLIUc8QabVaZw3miGrs/9Fr9o5r/eWhHG1hX2O/pfNw7mmwvZs4ZYfDIcbjGxEWYEDLwCIB566gzIVPMs0a2a6wDSE0GVPOL4sEw+uzVV7fDoVXPUGNhJTFxhRd52xYHGvM0zjrhhZ9mOetUCoUclthc4sk90ao9ucxm3dMDk4eAJ/hPM7wwb+f/bedjlxZcv7vBWFv5yqacC8G9eZmQgKU1V02eABXPtUn7ODEijBegpLtCRc271jR/Q9zHx5bq+vZGJlpl6RhMC4CuR/9O5TGPI9lanMtX5rrR86v+EzTwKk2/75R5EGY1I2pdtKdW+LtVc+ZjFGeVLAUQlZ3wEzyiVmBKwIWBGwImBFvworkqxDCC3yNievzX/y4+i7s0a5VGm2Lmo1olGu6Jtqo1Ru1WvNJnVe1TSd6lOXt6Gxi55bIx3x2/CycFHMa+e9qrkv6wO+bphlmVbqDh597di2uoh5bKJ9cxPGPByFxJdc1sGcq0t7+2gW3N79fnAk6lpCM20BzeQdjhK9LAk4KY2Qkuuj+FjNQEhNdYekGnvTUeQwxC1jGyg1fVJkUsVnq56JSckCk7EocD7gfAAjAEYA54OlhaV18ksLnE/OFOPgfPJBIoDzOZYJBueTv9UFzgecDzgfcD7gfMD5gPP5WZwPIApAFIAoAFEAogBE8bMgivAITCqTj+9vR5PxYFIp848xykaSfTOLi1ap47GPijcSlTLXHduOqhtLZtukNaY0NPhPzr1YCaq1WNMETuSL0DTYZDFd2RPHnDjM4J8FfXFvahM3dXJC2amn1PL+KpwtzLjaBwajno/NMTP4EMTVHJMoWutGEj697sCKMf6Fg+wOBA0KDdD92tAspiUP9pYM0e6nJk8cfDlWY3NgsE8iR+IcJKeNtiUppZiRRrk8uXGn5NdNyFx/9EfpITByiTOyLUd0GNLTJ87JB/3RHbUbdxQTJyUlcbQ5iUn5tNAb4ZAr5K/C2V3/qjv0pvsQZUb260gF0U4U4jbY+AcwYaP4HXRanug0ja0sNhOnT+nnCLxacFS8JPrCMC2vjF3YtZIPfyUybD5SFty03XboplH0HjMaGuWf0kuaBMPcoR5J11zvn5Qr1/oiy1lcXennpJcgGYMtT+b2eup/5dJ0oS8lWifP/C5iN3msnr9VdMN2mKqVMiB5ru7hWUyeV0gGKM/TthyMynNLBJYHLA/sENih42CHgOVhaWFpAcsDJQYs7+gGHFhezicYWF7+VhewPGB5wPKA5QHLA5YHLA9YHrA8YHnA8oDlAcvLPZb3aXA3JBKkxj/9Oizv3lxbHKO7t5j4K5nMi08bB+fFpUzj8z6Za2tsjin1p8QmxKeLofQ2Unmg3k2vz/mbqvj4yzi9B90Q8OIPZjhP/M9ERC8+bRydF5cyDcy70Q17bI556pukJsSniwHyNlKJUa/6o17/laPujwkN0dy0Usc9JfXGyCemTR57b5DG5gdKnzz6CSk3xj82nZiBuj8DYt/5NTSkNy4eQGqurXgMMinpBv8YnzAZfHRHRoCjSfXHJtuAHTcT+Zjj4XZ1j3KsHGzxxEOObvnxG2WkX4W4V1j8Yo99AIE9AnsE9nhw7DFA7b0+7lE3tLXtWE/P4h69QjJwj0JExTTFzXQ4AHKjaJCQICGBawHXOg5cCyQklhaWFkhIgHkgIY9uwEFC5nyCQULmb3WBhAQJCRISJCRISJCQICERiPSkgmoiECkCkQLWBawLWBewLmDd04d1A4FIO+bDak3Hs5E5d36ohG6cNRtp0Ue3w1kRkC56ugUZBTIKZNSByagA1/MKyajVRAoinsdGrYqPnkxlKx0VkH4cDIvyywQPBR4K0AagjeOANsBDYWlhaYGHAp4DHuroBhw8VM4nGDxU/lYXeCjwUOChwEMdjIcCFQQqCP7RgFwAuQByAeQCyMUvRi52XEStaa1VY5flunY5n5arjWql2rhg88vZ7OJCq15ebHQQ1ASoCVATz6Ymghr/18dNeHem51ATgYvXVmbCTXs4YiJ41QIvAV4CSl0odX+9Uhe8BJYWlhZ4CajvwUsc3YCDl8j5BIOXyN/qAi8BXgK8BHgJ+I95tv8Y0BKgJUBLgJYALQFaArTEUdAS6ZsT8ZAHCTTE+cqDlES85mFiH10dpKDIDAmcVKClNHqy64hKBIoEFMnBKZIAAfH6GJJHNnNM61kEiSwiAz8iUh6OHhHlgR0BOwIFNxTcx6HgBjuCpYWlBXYEKAPYkaMbcLAjOZ9gsCP5W11gR8COgB0BOwJ2BLGH4GUEsYdOKo4OYg8h9hDQLqBdQLuAdgHtOn20KxB7qN35rHxYmqbGYw6Vms1qpd46K5yNvva97yvNUqtZL1cQkQhUFKioU6KiPKrnNTJRFldqPpOKkoVk4KLENZZpipvpcIjURtGgpUBLAekA0nEcSAdoKSwtLC3QUoB3QEsd3YCDlsr5BIOWyt/qAi0FWgq0FGgp0FKgpUBLgZY6KfIHtBRoKdBSoKVAS4GWAi2VK1qqRwSIwYQ8f8yWbGY+nL07a5QalctyC4AUACkAUicGSHmAz+tBpOh1K4GaneEoPy/xUdMnh1M5W+EonlBcWjyUJwmKimYnnTLPmkw9qYsF35of1S1yjvZiYbGFOAnoMod7dHHP+Fz1XaBjW0CKblpKRbk315aXzX4bPGTEFbzPIUP1yyl65Zy/lZc880F3HKYVeHu99ku9dNGmFxJd0zwZrNylmRZQgfxdmesGC/RDoYMql/jL5bhk/IBg39Olz5La8ZLSm0fKDDbAMU1lYanGeqla3vHCr7SQeCFMw8owWcc3WSk+MO8DJ+BK4+GsIL6q0G5e+RGWNYFTBKcImAowFThFLC0srZNfWuAUcwb2gFPMB0kFTvFYJhicYv5Wl2rvDhS1145pmA90Phg92Q578KEs0+CIxwN1ZyOZ0udHKVt50x717bc0B/EQVyqzRXnTaa3KRb2g1GqNZhKx1R7xJMnQVntE2Xc8cb+mYXk+zwZAFoAsAFkAsgBkAcg+A5CN8hEpA3Bk8I3ybQOa+aZIHbxNa2vmLMXJYeO0K2VGakB05h+8Ux/a1zQGyXqeAM+0yTv5AJOXLKT3eSA17yz9UdvglQoKW5SEDjlterblS6K13n8dcwyL/zsZXF+FmwyKHLFqfz2im8SV7Yh8XjSmKrsoz+bVFmtOZ2xea9anl616WZvWphqbEvj0sjRwkNXIj8o/5SH70Psw7nb7k5te/05sNIN+d/JpcDeUH6/aX+Wn37rdz/LjzaA//sShPuDTwKeBTwOfPk58uhDa0Dei2wJNPjU0GSDyu7MFM5hFqvOiR9md7QYfp0HHAf42C6Q74ZXZ5396lnZ/PYvbXUjzznRoN8DqeqaC04C13zO9GsYVmYX0DdbPLxgr1blPuYtRW1RHNIVRbeKy4JiutWV4G/eXiqTyt17Adqwg8ZU3HIwHncE1F2FNvnSHox6/mnzpdsYDOihe3fEXFX33vjcetsdd/utw3Ou0ea7+1d1oPPwavowBjD5l1hZg9AlNFsBogNGgN0FvniC9CTAaSwtLC2A0OF2A0Uc34ACjcz7BAKPzt7rAp4JPBZ8KPhV8KvjUV8mnng5Fmiq6DpESPhEY+jqd2gBKCYe8cMh7cmMGh7w5dsgLBBcILhBcILhAcHOJ4BLDaelMeDPe1T6kVW1Wq2VWKTe0Vr3WqE7VSqXc0i6Z1mqxRmOjs25V8EIM1BeobzLqK8qxi4/VnaDfqe6QdO/5wC931ysLy+KwVyTN6LI3C/EbKBQefXPOQgJcPaHJArgKcBV0Hei6E6TrAK5iaWFpAVwFRwlw9egGHOBqzicY4Gr+VhfAVYCrAFcBrgJcBbgKcPXYWwpw9TjBVVCBoAKPRHMHKhBUIKhAUIGgAoNUYPpGNalMPr6/HU3Gg0mlzD+mLc7Ii4IURMzi+gcanFKYKChvSmPCodcN9YG+pRl6cu7FclGtxZpmeSKPF6bBJovpyp445sRhBv8sAMR7U5u4qZMTyt4+pZb3V+FsYcbVPjAYDcnYHDODj01czTGJorVuJOHPgDviYvCPcfTdEaLRopG7XxuaxbTkWdiSITouqckTZ0UO4tgcGOyTyJE4Oclpo21JSimmqlEuT27cuTrCmZrrj/7wPQSGNHGqtuWIjk96+sTJ+qA/usN54w5v4mylJI42JzEpny960fyUNfVX4eyuf9Udeg/IC1fmuKeV1HNlJsl45C0UKHmjT9EBLcS9N+JXScI2t+E9GnD56cLlGltZbCaO19KZLnDz4Kh4SfSFYVpeGbug56UNvjwNRvfx7+CLxG0RXZy9B44GSfmnGGw5yN6gj706FW6YbCvvn5Qr1+g0ywVEXennpI0kSZQtryP2eup/5WLxoS8lIy8vOpus/OSxev5W0Q3bYapW2omyd7WQh8HsvdIycPaeAvagoL1XKkj7nMPbIO1PaLJA2oO0Bw4MHPgEcWCQ9lhaWFog7QF+g7Q/ugEHaZ/zCQZpn7/VBdIepD1Ie5D2IO1B2oO0P/aWgrQHaQ/SHqQ9SHuQ9iDtQdqDtD8UaU+7IFGQNf7pyAhizl+ba4uT8fcWE38lw/bxaeN4+7iUacj9J3Ntjc0xpf6U2IT4dDHg/UYqj72/6fU5lFoVH49rOgiNf9ANYajwgxnOE/8zkbqPTxsH3MelTGPtb3TDHptjnvomqQnx6WIY+41UYjqq/nTUj3I6/MGisZubVuqEpKTemJLEtMmT4o3e2PxA6ZOnJSHlxsTEphNTU/enRmxhxzUz/oB5ViTm2oo3eUhKumHrEJ8w2cjBHTJhPZJUf2yyDcOGzUS+ScNPeHN4Fg2Vl1+HP9ugwe1S/P4fGeNC3Cs7fquKXSUwcYCJA0wcXszEIYDew8YhbOOgG9radqynw9g4eKVlsHGQ4k+ZhUtID2nsIIrnmLZoE6we8g7Sw+rhhCYLVg+wegCaDTT7BNFsWD1gaWFpweoBED6sHo5uwGH1kPMJhtVD/lYXrB5g9QCrB1g9wOoBVg+wejj2lsLq4TitHpb6g+7cMovrZtOH7JqSipXrS5YEHsClWwpXabqtd8yVwhcsfy1Iqb6UeNBDSHpLeX3lZ2RKq8zMteHQS4AxTdTE21dQ2B+Opcry1NWKqbI2knkZGo2dofzrzKTB/deZQirzhWk9lZQBHVLt9WpFGhpNMQ3lXl/cF2eqpemGSmp2RXN10fbfFV7AD51LbOK1MMqNbugP6wcpa9RtpZo29Riz5DGLwPeBPaFShmEODHOOULkMwxwY5sAwB4Y5MMwJGubsuKAuWtVmtVpmlXJDa9VrjepUrVTKLe2Saa0WazQ2OguwF2AvwN5Dgb0B3hRgbwTsXU2k+O1AaO+q+OiJFLfCvQHh30Gp3kC5wHlzTogC5z2hyQLOC5wXzCGYwxNkDoHzYmlhaQHnBV0KnPfoBhw4b84nGDhv/lYXcF7gvMB5gfMeDOcF1AqoFVDrq4RaQQyCGDwS/RWIQRCDIAZBDIIYfAYxeFkuV6sXdaZdzKYX85o2azQv6tUKq1Ua1Uu1poIYBDEIYvDliMEgxgZmMMwMemKGgxCDAaHFVl7QTXtYWtArFaxgzvEzsIInNFlgBcEKAmgC0HSCQBNYQSwtLC2wgkDXwAoe3YCDFcz5BIMVzN/qAisIVhCsIFhBuP58tutPkIIgBUEKghQEKfirtVcgBUEKghQEKQhSMEgKpm9UZBjzsvHTuQXOy1ZBpj4vHHD+6qVr+Elh5oVVlLCQormX84NQ8OA/wX++GP8ZgBJBf4bpz0c2c0zrMOynLCsD+SlSHpb7lGWC+sw5SAjq84QmC9QnqE+gaUDTThBNA/WJpYWlBeoTECKoz6MbcFCfOZ9gUJ/5W12gPkF9gvoE9QnqEwHf4Rvz2FsK4vU4iVcEfEfAdwR8B5QNKBtQNqBsQNmAsgFlI+A78F3gu3nFdz2uFPBuFN61uNL+UPiuLC0TwCvSHhbhFVIDpvnFg+bNOSAKmveEJgs0L2heIIdADk8QOQTNi6WFpQWaF3ApaN6jG3DQvDmfYNC8+VtdoHlB84LmBc0Lmhc0L2jeY28paF7QvDkmU0HzguYFzQuaFzQvaF7QvKB5QfOC5gXNC5r3KGleDzN95TyvuXK/2gPgNVfuVxu8Ll3jwnStslJ1y1bemJa+0A2uzo/c6e23W/DdzUKl+FOWSa/2iJhA+UKvB4EtqnTbnDHDURdMMdeeGtkxHXW5UfAbLsqd6sul0FmtDcd6eltSvpprZaYaisnbSHyDuGxGLrgBpFi07jzSNOXN2mZ049FJlrz0OuhmpBbLzoWUYG7+t8k4Mm/PMwQZ7i1vF7Zx7wJjrsBS8yivzO528OD+WQbICZATtBloM4CcWFpYWrlaWgA5c0Y+AeTMB2oGkPNYJhggZ/5WF0BOgJwAOQFyAuQEyPkMkJMLfq+eR/9JGO7aI/NeEv97VmXJOmMP93suEnid6b0cK/t25fgrfkcOagDeWC5y8C08YYHb8NtMw/riFT9TOP+gLgzdWWtbRNIDSwvtHaotmDupOPJKKSgaI38UGhchca3Ng+7oC76dT58kHRX9wVUUpozjT2tA8iN70xv3PrbH3avJ+6+CnXIf1M1f/G/a43G783kU8W0BnPt0ce5Nmhvs5wmyn9tRRmO95O5zAsQE0EagjUAbgTb+dLSRBs4xVwJlzDYK4mTZEVhMm67Q1fTOfhjSqISy9beO5AdLNWYs43DWS7VqrVqpbwxnXFvjmpJ9xMVgvSyMWY9b/Y4yJ/XoTm/IXdnUmsZa02atPp3WW83mBau21OasOWs0y63yrEEvCd5CQIzvzhbMYBapRoueO7yzXcFFc5WGKrqAXTrDpxva2nasp/0gPplbAEebHJ//s+8d0xdzKD4CGHkvkp6YGdrK1A1uDOUTnyVlbEpp2popC+ZwdQJXLNN7s6DYP3QSy7tSANEkqtTtqFcwKDhQcKDggOoA1QEFh6WFpZWLpQUKLmfYCCi4fHA6oOCOZYJBweVvdYGCAwUHCg4UHCg4UHDPoOAATACYADABYALABICJ4wEmto9Cx3xYrUmYODLnzg/Vyso9NDfdRe04HsAZ4KXp53hpSocdPIzhmX6ZRhIY+CXemCStsJMPJu/2fS6opP04DpG36BUWS3NIX0n+fX8zDuoWN0wZSgCVASoDVAZUx1Adg8rA0sLSysXSApWRMzUmqIx86I1BZRzLBIPKyN/qApUBKgNUBqgMUBmgMkBlgMoAlQEqA1QGqIxcUBk/242FpRrfA2njAn/+ZGcXsk2ARODz4mf6vCgFKYVEIETSEFnhCeGeYj94QuTdAk9EI1btDk9kKAHwBOAJwBPQ8ELDC3gCSwtLKxdLC/BEzrSNgCfyod4FPHEsEwx4In+rC/AE4AnAE4AnAE8AngA8AXgC8ATgCcATgCdyAU9kgxmExnNnxCKU7WdFColra1xTAE8Anjh6eELSEOnwxCMt55m63A+acHPH0xLer78+bojbFMQNAWQByAKaYGiCAVlgaWFp5WtpAbLImVYSkEU+1MCALI5lggFZ5G91AbIAZAHIApAFIAtAFoAsAFkAsgBkAcgCkEUuIIvto9AjnbTBhNhwzJZsZj4gdAhCh7yq0CEex/B6QodcuOnP/9Tcpv61K8dxUXS5jSjBIQ7iFy6nEaQpvOq2OLvQdNpzpmv3ABMtUuqypPaDaX7ByXhGsG5+UF+pzv2mRkIWKdqhOqIZjGoUh27HVPgzF301+TuSXMlJEvh9K0h6jX8aj28nN93xp8HVWUH89aU7HPX4Ob8X/OOm3W9/7F5NhnfX/I1+0xv3PtJ7uT+5HQ6u7jrjs8LZl+5w3Ou0rylz/+puNB5+pQ0V6AfQD+inoZ8G+oGlhaWVo6UF9CNnulKgH/lQTgP9OJYJBvqRv9Wl2rvraNtrxzTMBzofjJ5shz34em7ToPCmygN1ZyOZ0udHKVt50x717bc0B/F68VQ1OOVNV4BXLuoFpVZrNJOU4O0RT5KsB2+PKPuOJ+7XNCzPRwTAHIE5AnME5gjM0bOZI1Ku7Nt3kpO7jd6xt9Gs2/pH6R8rUjb/WHU/1Hbv7A1X9+zXV6Eq2qerfs5tPf3YJQ3C7WBE/1x1r7tjUv3f3tGfn7rtK/7HUHACt6R34FzBcHD7odenH28+dwakeLhtjzufzgpn7Q799b4zuP1K/3olvr8ZfOH/BvLyz27Gzqdu53Ov734a8BZ0Bv1+tyM+8QKv2++7VMH1oPOZau+Kpt18bnfGvS+98Vf+x2+D4efRbbvDfxL19gfj3gf6dTC86g7dSm8H19eyP+5Xw+7tYEg1jrrtIf9mdPd+1Bn23lMx46Eo9a4faOVdXzbnrh9Me3d71eZ9l+qczqA/HvLBet8eda97/a7/zT9uRt3+3U17PKbxHd52JoO78eSqPW7LP3t99y8XBxsMPssGfd7tsXzQHX3BX6q3XHCa8WUVy+5dKH5pUg7r7A0CJhW27Rm+uhrQqP3W/kBjOxhPhNbsptsf8yey0x2NPA1a73Yy7N7ejbkSjX6+7U1Gn3rda3oiaYgn14PRaHI77H7p9nmanQaXW5TfMusjV9bvb1m+YparUxSXODKy5z3nLz+pNPO1qXSbcqVD/ApKaZUZ+bGgVx1jmqiJt6+gsD8cS5XlqasVU2VtJFI2NGYRkPavM5PuuP86U0izvzCtp5IyoDugvV6tTIve0qah3OuL++JMtTTdUIkG8PW69t8VXsAPnQtEmScw123/uqhI23Upytdtpbq38fwrH7MU1ywhRwBgX3PJvoJ1BesK1hWs669iXV2grRy3OXlt/pPfON6dNcqlSrN1Uau5t493Z9VGqdyq15pN6r2qaTpVqC5vQ4MXPYlFeuI34mUx1Zj3zntVc9/WB3zfMMsyrdQtPPrekeBjnDwi2Dc3YczTUUh8y2UdzLm6tLePZsHt3e8v5DXs4gRR2md7DbtIQ2fl+ig+VjOgprS7T0T+vVHT4vSpSOXIdmwlT8MSDMUHVp/JnkbEIvG8KThJcJKAuQBzgZPE0sLSOvmlBU4yZ2AROMl8kFzgJI9lgsFJ5m91gZMEJwlOEpwkOMkjhAfBSYKTBCcJIA1A2mnBVQDSAKQBSAOQBiANQBqAtBwCaZeXpUq5XG1c+EBaudS6vLyo19J4tAjLQYcAZnHNFQ1OKTQ6lXKMHA8AW44Atpf3DnmKSNtBvUNelHwmLBFzCxNnz3ASefErnERePNtJJCf35D3++ejeoyeIyMbuuQKTw8J7AbEE6D3Qe0CMgBj9esQI9B6WFpYW6D3AZKD3jm7AQe/lfIJB7+VvdYHeA70Heg/0Hui9I0TaQO+B3oPjPzj+g+M/cJaIKAyIDRAbIDZAbIDYfj3ERqe/80rpD/KjVildVKu1ZkOaY5xXSVdyUSo3mo2G92WNgLRStVopt2hcwoPpl7Zx4PfLTPqptp3dkkUU/Iq8vL+DiAMRByLuRYg4H+R6fUicbmhr27GenoXDeYVkQOEc1VowEvK4mQ7Hw20UDSgOUBzIHZA7x0HuAIrD0sLSAhQHRgtQ3NENOKC4nE8woLj8rS5AcYDiAMUBigMUd4SkGKA4QHFwaQcCEAQgCMDXTADC0yI8LcLTIiBVQKqAVAGpAlIFpBqFVDvmw2pNStGROXd+qES7nTUbcK8ImBQw6SnBpAEM8hWCpIfxrKjv5Fex9wJeFXvwqQh8FIwbGLcjY9yAj2JpYWkBHwXNCHz06AYc+GjOJxj4aP5WF/BR4KPAR4GPAh89QqYS+CggSkCUgCgBUQKiBKEGQg2EGgg1EGog1H4Jocatm3gw4Mta46JWcy2dKBhwuVmvNi82nSWKPDHeEEXObaBVyKAKvBp4NfBqB+fVXrfrwwfVUBdMm1jrpVhUe0NrsqSiKCkDtyYzKDzD4dC1ULGg10CvAbEBYnMciA3oNSwtLC3Qa4CpQK8d3YCDXsv5BINey9/qAr0Geg30Gug10GtHiHSBXoPzQ3B74PbA7YHbe83cHpwfwvkhnB8CLQVaCrQUaCnQUqClcRG6lbZhPqhLAqZajdJFpV5tNekUPBpx/4Wl6kW9dlmHQ0QApgBMTwkwjXKRr5Ax9W6wE3mDfR5o6hVXXHmX9e206cY1+oDIaewVHdwpuFPAcYDjfj0cB+4USwtLC9wpMEhwp0c34OBOcz7B4E7zt7rAnYI7BXcK7hTc6RHCmOBOwZ2COwV3Cu706LlToJFAI4FGAo0EGgk0Emgk0EigkVE0khuyvDur1kv1aqVxWZdGLe/OGrVStVKrNVtAIoFEAok8KSQyjuB7fVzkIy2rmbp8Fg3pFZKBgXRUa8HoUuFmOhwCuVE0CEgQkMC0gGkdB6YFAhJLC0sLBCSAPBCQRzfgICBzPsEgIPO3ukBAgoAEAQkCEgTkEWKBICBBQIKABAEJAvLoCUh43oTnzWNHJYGXAi8FXgq8FHgp8FLgpbnCS3sEzxlMqD/HbMlm5gPBpaVG5bLcqoAtBVsKtvSU2NIAD/l6iFJ63Ur+cGeWNJB3G0LKryhe2iRiNJqLgBueNRkJVRcLvhE/8nlLI0MXC4vJO7kuc7gHFfdEz7mgAh3SAipG01Iqyr25trxs9tvgkSKu4H2OFKpfTtEr5/ytvNKZD7rjMK3A2+u1X0I7RZteP3Qp8/QEck9mWkA//Hdlrhss0A+FjqVcHSoX35Lx44B9T1c8S6JDJaU3j5QZbIBjmsrCUo31UrW8w4RfaSHx+pfG3GKyjm+yks9vlfvAebfSeDgriK8qtHdXftCbrgCIGxA3SFOQpoC4sbSwtPKztABx54x6BMSdD8wUEPexTDAg7vytLkDcgLgBcQPiBsR9hGQzIO4dHpOoXjzlUTky6EL5tgFLfFOk7tWmUZ45S/EO2Tj3SOmBGhCi+EewVJHRaxqDZIl/gGPZ5Fx8cMVLFtIAwGwAZgMwG4DZAMwGcmc2ACb7BJnsIEOTHxQjZeY/9D6Mu93+5KbXvxvzZTHodyefBndD+fGq/VV++q3b/Sw/3gz6408crQTEDogdEDsg9uOE2AuhDZ2j4HTfE0D7jgvqojFV2UV5Nq+2WHM6Y/Nasz69bNXL2rQ21dh0o7NuVQDRTw9EB3b+7mzBDGYROlH0KMuz3VDzNMQ8QExnQbInvDL7/E/PrvKv51Dactx3YLU9w9BpwLbzmS5/44rMQnoH6+e3i5Xq3G9iIdIqVrRFdURTGNUmbgqO6drWhl8X/lKRNhhJGMS+FSS9WkliMbnpjj8NrqSgZSJvzOK65v8h7nVX3l3upjfufeQXucntcHB1xyUFX7rDca/Tplt1r391NxoPv4albyDmTxnCBjF/QpMFYh7EPLBeYL0niPWCmMfSwtICMQ+AG8T80Q04iPmcTzCI+fytLhDzIOZBzIOYBzF/hBg5iHm4PQe/DH4Z/DL45dfML5+uMdTpmCylKkZDIKDG5ioHocJfp0OJIdUp3NjDjT3c2MNkAiYTMJmAyQRMJmAyAZOJlzaZaFWb1WqZVcoNrVWvNapTtVIpt7RLprVarNGAyQRMJmAysYfJhCjHLj5WdzKeoD1+Isp8vvFEcfpUpAJlI7faUoQlehnd4GexoogUDE/5OUfJwf2f0GSB+wf3DzgZcPIJwsng/rG0sLTA/QNDB/d/dAMO7j/nEwzuP3+rC9w/uH9w/+D+wf0fIQwP7h/cP7h/ANYArAFYA7AGYH1KYwbAGoD1iUEPAKwBWAOwBmANwBqANQDrLIC1xlYWm4l9UTrmBnIdHBUvib4wTMsrYxf8urTBWKcB2WH8+Y+i7ai6sWS2XXRbRace76GjgVL+KQZcDrQ38GOvXoXfH23l/ZNy5d4Nsrw91JV+Tlq4tTVjtnyX2Oup/5WLh4e+lKy4fEttMuOTx+r5W0U3bIepWml32lyKrA6Imz96wrdsvLkrJDw8cO6WDOI85xAziPMTmiwQ5yDOgcUCiz1BLBbEOZYWlhaIcwDQIM6PbsBBnOd8gkGc5291gTgHcQ7iHMQ5iPMjxLBBnIM4h/N1OF+H83XYBsA24Ch4upeyDQB4DfD6SHT/AK8BXgO8BngN8DoIXkc3Kq/9f3LD2fNK6Q9qRKNcqtVaF7U6NZj/UKWv661Ss1mpNpve1zXOGJWq1Uq5xTvnrh8O3VbL1VqxUi6WK+Ny+R3/7z94i8KT4NecvBNE3kqkz2YWV5fSTJTCAFQ5Vnjs9uPlK6m9cCXBUU6uKJNMPfL0BUou+PPijZ3Xv99B3IO4B3H/osS9T4ADuQ8j97qhrW3HejoMbu+VlgG1d1RrwejiybPQmB6UtxfFc0pYtAnQfd45bkD3JzRZgO4B3YMMBhl8gmQwoHssLSwtQPdgwAHdH92AA7rP+QQDus/f6gJ0D+ge0D2ge0D3R0iiA7oHdA8377AwgIUBLAxgYQALg7xYGCD6AKIPIPoAjGBgBAMjGBjBwAgGRjAwgkH0AdhCwBYir7YQATwfdhARO4gDBx7Qdwo70HuhoAOBcjmkDBOInFP1MIE4ocmCCQRMIMBpg9M+QU4bJhBYWlhaMIEAkQ8TiKMbcJhA5HyCYQKRv9UFEwiYQMAEAiYQMIE4QrsAmEDAEACGADAEgCEADAFgCJA3QwBQ1qCsj0TdD8oalDUoa1DWoKyfQVlflsvV6kWdaRez6cW8ps0azYt6tcJqlUb1Uq2poKxBWYOyfjnKGv7mkznrB9VQF0ybWOulWHzPR61lkUVRZAbaWmZQeIbDAtfhooFb55zgBW59QpMF3Bq4NZhQMKEnyIQCt8bSwtICbg36F7j10Q04cOucTzBw6/ytLuDWwK2BWwO3Bm59hAwycGt4nAdoDtAcoDlAc4DmAM3zAprD4zw8zsPjPGwhYAsBWwjYQsAWArYQsIWAx3nYQsAWIq+2EFE2H+YQEXMIT0YzkTKaA9lEeOUWV55carthxIbE6MDWEZvlw0Qi59Q9TCROaLJgIgETCXDc4LhPkOOGiQSWFpYWTCRA7MNE4ugGHCYSOZ9gmEjkb3XBRAImEjCRgIkETCSO0G4AJhIwkYCJBEwkYCJx9CYSoPhB8YNIB8UPih8UPyh+UPyg+EHxg+IHxQ+KHxQ/KP6ToPjjaHKg/GGU/5GW30ycXZ8P8HulZcD23bSHhfUd1Vowus15xYPVzzn+DVb/hCYLrD5YfQDFAIpPECgGq4+lhaUFVh/oOFj9oxtwsPo5n2Cw+vlbXWD1weqD1QerD1b/CAF2sPpg9cHqg9UHq3/0rD7CGSCcAQwhYAgBQ4jjHjMYQsAQ4sRYHBhCwBAChhAwhIAhBAwhYAgBQ4hTNIQIUPmv3PzBXJ2rNrPPTUtf6MYeNg/mqijyFlV7w8iBLnPiV6U9orPrhoXCFvuGQAGqr6i0uaIyrriS8oVeB4LqXjFrxgxHXYiaRXmOuoxmKvikWXJdGrFZD7pB8J7k9pY6vSh7t4qqaRaz7WRzCn4bfYZkwb127cJm711gzJ1UkhPyDuuuzwf3zzJAdIDooGVBywJEx9LC0srV0gKInjNyEyB6PlBZgOjHMsEA0fO3usADgwcGDwweGDwweGDwwOCBwQODB04aXMB5JwjnbWfNjPWSu4MKqLTBnoE9A3sG9uyns2c0cI65EqxZtlEQKEPbNtK72Gi0ak0aDi99f+vwDbvXvXa/0/333qDY6ytDttRV2lP+XTcV6hRd7BTOHzCNirZU43ugxDjaPdt81Eu1aq1aqW/MR7jxgc54kyRbsX2uxDC/LGdXj9s3HGVOirad3q27Yoc1jbWmzVp9Oq23ms0LVm2pzVlz1miWW+VZg14vvIXg096dLZjBLFKyFT3HkGe7MmnmqkR0VRqKJsGrLYiWHL298CyftNqEs8IklLJSdXL84FJQhia9x/oiubcZgC3X+SyXn8iy6M0XLmovVEt5w8VAU325FPLuteFYT29LyvieuZ14UBeG7nDxkGrQuVhj8yC35Suu5dWDeYQrt67YSPZfpkHNnM+lKc9Xc82LNvkQ0CMizI0i2QI+eMUgnEdGQHmzthkdq3WSeS03xo8GRo5hSFjv5n8L4AzAGYAzUDGgYgCcYWlhaeViaQE4yxmhAeAsH0gMgLNjmWAAZ/lbXfB8Cs+n8HwK0hGk4xHifyAdwRodB2vEBftXusVm2/fskfSaRkcecaCjYfnmuru7lpvPN4kn2N4BjXsZ4FqHiMom7Tb3EpUla4IHw95HTg767v+8r9x5874Yt4fEPMY6/bvO9PqL1W24epoVl4EENTxvLBfs+BaesIC0422mYX3xip+rfIEvzNP1hbnpChMoI1BGoIxAGU9lGwTK+HpQxo6Afdp0Z6qmd/Zu5BONMtt2qvHOIF5RGTmksKL84ky1Q7UfhhvZtlf7wSJ2MuMsbgEgw22NG4H4XsU1OvsjAWISxOThiMk0WNJFGdNpSd3Q1rZjPe2HS8rcgr3aJCb9n+WFVYCF29zajUllzgxtZeoG9wzuuz8sKWNTynfWTFkwh2tWuI6dXuwFxf6hk4bCvTCLJlGlbke9ggEEAggEEAhqCdQSgEAsLSytXCwtAIE5I2gABOYDWQIQeCwTDCAwf6sLQCCAQACBAAIBBB4hJQcgEK4P4foQrg/h+hCuD18zjgxeELwgeEHwguAFwQseDy+4fRQ65sNqTaqqkTl3fqhWVv6uuRmZd8fxACyHgLg/JyBuOkrnQXLPDIE7kjjaLwl8K1m4ncLdeiK2Q8S8DchKEyPf+jK954S/TSvlQFFvPb+EiHUL0hCkIXAo4FBHiEOBNMTSwtICaQjwDaTh0Q04SMOcTzBIw/ytLpCGIA1/CWkIfgz8GPgx8GPgx8CPgR8DPwZ+DPwY+DHwY+DHwI+dlL854fhtR39zvuO3nxUfN4t7OETLhe+3Xxct16Ocnh0y18e8hJu2/TAvkTcd84qGyN0P84orhZSVm77lQrSXGuC9FHPtpCJfIkxuNAotd0YXBb5EDqbx4Ld/s6MRdwvk5d1QvLkGDgYcDDgYmBUwK8DBsLSwtHKxtICD5YyfAA6WD2AFONixTDBwsPytLlA5oHKgF4deHHpx6MWhF4deHHpx6MXlxppJT31KYdN2DYYGvTj04kerF5eK7nS9+CMt55m63E8f7uaOj43m/frrQ6O5TUFoNGiooaGGGg1qNGiosbSwtPK1tKChzplKBxrqfOjQoKE+lgmGhjp/qwsOS+CwBKHREBoNodGOkCwBRAPXNnBtA9c2cG0D1zZA+IDwAeEDwgeEDwgfEL5jQPi2j0KPiCeDCaXUmC3ZzHxAdDRER3tV0dE8Si7X0dGmi9X5vf6/eEHskZ7fDFTgdLEqykxFmSnKAr7/eKuIJIqXIs3/zUb6ZFhvpW4jtjqSVKCUkoMoCDU7KWG49KaSdp7Omv+ZJN6KWZPtnel7HAczHK4lWjGLNy2tC+m5ntlwPkO9LYIM8jO0NvT/XDOF3mqOPtdFg1Qxw2mtz5J38yTqy1r4g8Ss9jYlEdWzMmmr19Wl4mZT2iNRV/Sh3NbkHYtK6cGjPnP0hx3bLzIdoPUZCkppu248kv5S23f0TetwPdmx0Ay9kiYB23sm3WRxYbV7v3iR3h60ouST3S3JTx7UP645dHb2rsp3B++v0MbGBfPRIfL74BdaKdH/lc+r9Tjtb0BKZXS803E2CZV4i5A8Se5hwTuuPSON5ptKsa4szR8FpVEkcZNWUFr/ptzri/tMAvTn15DyuD2ofzyjx+ofL93jPWtI6fH+NLa6IzR6GA60oLgA5DcgoSEktJaEhJY9JDQDNVptJaRpNHmaaqsgyMhMeOnN2lkTkal4J50NXMfHZnbUsuD5w/N38Ocv+UV8oW3sm/vzugfB3batmZ9RdwYZbXAQq+VqrVi+LJYr40rlXb3yrlYrXbSq/7ExtL8e4fyVBOMLDaxtWs77LWfokWk5oW2WbxACmmeaMtfZMp2Xzpg/eaGNezfdgFi8R0pB+V1n0P/Qu+r2O10SKoY7NrA0fqfe0jfFpHTbeuCnSpLWt0cdrq0fdcJNgfLxJygfVduY6GE14RbpO4Grm/bzf1HL+TVuMuOa5A2CiFy1Lybxsvuo4FvAsV76SNkxIvjCmS/7y9YN/+A/4Qf/+D651HD8r7zOifg+7ndxN5082At7wnuQloxZk8Sh9VLIcYgdXl2Lz6zbE9tRl8E2uvqHv/iFeCLb6cSBXyLFg71I/Fk3thRgGpOFqRuLtDFYMdH/1BmM0d3yfPoqtWh+mWdZSg48jkLn8DyVFOl+kp6teB2TSB77gAvZxz5jJHOKZ0ffbSCi6j53PYQe/rgnPfJYxzzD4S7FNJM/0oHnN/qwRp+90KO68dgFn7HocxN4SAqbO4N8GGJnhfuonzyYhu6YVtIERLY2seF6W9ZGIb/zLLR/R7fmROIj+eFXFwmbkye8j/1VNCmx4Ein3FEM5iq4eg6vosPoQoMjE6MZjXnTvlc19y55wDcss6zwjG/ZIjxd27aXn5sw9nlLeq9nHdq5urS365kLbu9+P7gblPcfb09IY7uP65PpYlWSysWSt8QTtbSEhkf1mfrKPqd7iXQJkU2fqa/sYiBTVJ9JQNPamDGNYGlV0yxm24q9UmeMi3QUL1uiktNPpYTAtFDJokS+AxQUi1TNNs2B5tp9+RIUoq6V82rd5kIIgq+V83rLLvByVWWhPzKDjGuS9ahwBAJHIK9NNAhvBXAEgqWFpZXDpQVHIDmznIcjkHy4KjgOLRImGI5A8ri64AgEjkDy7wjEi9QqXB+8vDOOzQrh6WB/TwfyabxiS3UL9dBzn1suI9QoAxn9qQoJ7Gmj3OLvIGv+qCYT4MBpWy2riwW32ntUYwyA24uFxaQpvS5TuQced9T5Lb5AsxE4EJiWUlHuzbXlZbPfBo1T4wrexzhV9cspeuWkG6l+6H0Yd7v9yU2vfzfmdqiDfnfyaXA3lB+v2l/lp9+63c/y482gP/7ENWnbzbxh1n28Zt18Y8uG51AXt6fkBY7YLDi5QnB25lY3cqxYRuGeqUvnPtiaAB+yJClOhv1AWmltqIz9NqxUsrOIqd9xrdhjskVta72ksrxCpOLfN4gFb1wCo+D32evg7wGC6TRGPHmk9xzQA4xgascM88c4brCiKAxPFqzAWwWRKfod/hHgHyHn/hEKoZMRR2hIWBLyl5CwQeirx3raey1yxiI9C7O4GJ+GoxQaj0o5Vqihrx6bL1yFt0OlHlsyCWGS9j6Omq341Yh3aGMLdIf8ZZ06AF0CuvTr0SV9lR6gyUeM4qglc3Wu2rsxS+aqyLPERWNqj5iwUNtgjOJIpbVlCKEyldnnCkwp57O5nC+hKFcd7wqUW0V+Yxz23itTUkiT8wuVDBlcMbF4N/FVyYSes6SQIbNtqKsVqbrdXHogEJJqK99UY3ZvWhPH/pZMNVFxO8uXwqYhVATHtd70RgOl1SxXdhUzZSpvd8OaOhnWVC7H5fI7/l/YqObUg1jJjjao0XOV73UNziQLDxSNcsAdRSVkK02Q3Sy950PV+E6KF5H2nYfPCdaOHk4XoRPfpHV6n7KSj0qP9Um1bgeOl94Xj81JvWWHrXpmWdwPDPgHdanQ81arNJvFSsB3rvAWMOdPbUkZPOgOPzEuluZUXYq1n9b7gxSePBx3o8xuBiCo/BkWTnzPDV08d9ixmsVyvVhpjStNb8fi99EdTk/xVj2Bei7ql3QpEasmNWXrotEUicXKSk1cjreq2lidcWe1RDujjSc97Evyr4K7maXmlG3YaKA7VQV/S/T3Cz7qOHrj6J3no/c2p278pBw5eC+ZuqvzM8tcO6xIGdP8n/FUCqXK7gNtIw/8oMEP2r5+0OgxyuSFixLSlLqeoaJP4bY2Zsmf0s7MHsPao77i3Ks8RPBMpW1nQcdtdT7nmJF0xrJD4/cuMENvMnkK60Scd5GiXmQnIIbOnLt1aN/ykg8bO/j9ggunvMD8uXChAxdOeP7gwgkunH49fA8XTkfkwum62/4s9PLdoQhg1P3Q+4dAyIa9jz0e1YhnhGun1yz4fL2unfZwdEOPn8PvTElujOa6odv3LOhlKQA3JXlfoltKsmMn/muK+xb+u80WGXoSRB95NvF9XKnkJifFm1OSGydLX+jGVidOWz0xZfYqE5yQwPBLt0DewIZGMTBkwWHw+uz1MNKfUOMjLS0EnqjtxM+mgx/484E/H0jmT1oyz0Xse3rz4dIqexcsRuQoSldlvlz+mmycOBLDRddSJ02p6ZbvUG/SRPTqcilyS5zBvbnGliPO4e53NkHztqPPUsT5h7QnM+LtuJ5vN5ZS8EFU+qfOsOyiPTiNG5QEO93j/Mw0+Ets/keU+iycWavv+uRRXfLzBf9DN0J/ro3vhvnDwL3qld+rnk1/CPstNtL/i8XpdP5mK7O17ZgPjOSiBlNs/b/iVmyY1IiUEog17hH1vGiLLXTbsdzdj+ffugEK2LvecU+QSVpKzpJJ/3LcAI8O2apURYkmxHeE1mCW0pvZS4/pSaVUrbBqnZtzyPtqpC4S/0p5Vlxhf4m9Y2tL+dGZEFPXs+gOQ0F7TU/uPClVDG8/9xS5Q+1bzZ3c0bZVI3e+fav5kqkve/YkVsLgSRfkKguSRP6DHHzsghMbbHV4PsLDFnumd01jt5iPqY5K9knxCmknaLn0g5xvuNaOpAYRx1gnYYONELfNYrk2rtQFv0YTwt8LGaumWnn6vWrii+CWMSvGGGTMF4h/YBFK3Zm5XLKZY1oK3cd9/4puj4ULqoxWn94QB/scatWGpYc8c8PMAzfafN9oxR1zV9RM3mUfTDXrXXY1/6Oq2kWeI8qY3ayXjl4c8G2e0Js3N4P26K0S8MWddpXdktu98MTebpNvseKls+UGZ5rf1yuF6ot9TYV81ybe2nYpJIXWOXisOnmimJBjpEzjwD0ohQ4jolMZep+WNSpjxz3n13j42NH9wazRarTmlfllpaleViutepOVp81K41Kd1y/K6gXXMsj9I9t7SayNnTPsp6PwZQDRwB8JL0NvwwgpEKLFxL4q5dLdWoW3xN2R2K6FkPstzjE4x7z2cwxfCvHnGHIhYp//qdrGX7uJ5nnGTYtVnVnFikI/KjZbPPBgo9ydPb3It8DzvEiRkm49tsDnyCEit2gVRc+WxFIXFI1ZOiGxXA8wpDZ90dkPm9uskhWqfW86rj9FxnlanZfNJYscpS0GW6m84QW5lz2dp1Ac84dqaYoqK3/reycOipltZlFL3OZr4uImuDTB8ckbnS1AZS+H7pQopry0lfQHjDz8PDBrQTazM8u0xWlPnXF8yC/t78K38r/OvK/+dUZjZs/MFceMTEOa5brvUEVdEuznOhhTDeVfdN8jZwz/OlMe1JXy5jt7Eiew9qgf7C8JhahDnn0gOfbj/i4llCxE61LU7nVltVzbkVHtK2+mzHaKbD43LefvCtlPiQv+2vCe/LfJ59OAu0jpACdydtCNxTLZxyF3ccg9HMp3XuksuEOJ1ZoonN6j7GT7tMpF/a/dneu1ZeiKufqgL59cEUX4MSwpV+Kh4ouIJJKpCP3eJSbLQ6SjPc8O2P0i1hFf2DxWPsxblAnuQ64qtpiUwCbgy1AEjPqvM2Hu80i/1v519lbatTqmWGepy0x5Iww3ZuoysrHROtWYthYvdqYV5JgF5Mq2Qhsk/cSdgvMFwzlVfbqWbmTdppLmlGmpduq57nTysxTsR1gPWSmXcSv6+dqfJH973pT9eVap1WoNT/3D/wqoaqTlrJg1368dP6SomqYL+/TbUL2xWqVNWyDxZt5bVeTb3sRN3oatb7wKpT3iL8wMJaRL7kVrNw/nMQ3xl27aNWHzNvBsUX1UVk4mB9byiZY5ncUigup0gHmjV4xbcemPrOO9FWLMqjeypcn3vfZ6OgWeWvmh2gr7g83WCUqFbA1OjDOZTTAf01+3zN+lA8GdMND9ngleTSedckz7Xb4rMlTqi/M2/E2JIkKNCdUceuS3iwPc+0ogU8HbyiAmgJjgdYgJSu462AfgE5qMndQeGxICIckrOmaRXtYP6molttdUwUBcnhQCMMXg/tCqgh2UJSla/V3UJVmLSVGYkGh25KjO2t7icYkfY4WKwj/iOvcibgSNN5XE0ci1/U7ACwVPj2FaLjOR6onpgHWk3Eb7X9rX3HTIPX67f/u/3PU/9we/9cO30aVJwaIcEfTghpq055Bx36uiMDmFMvqGCyaJyRM/ReIm2J7P//Na1c1NIRfFE8Ev664SsO+K24IY0l4T8MtbDPVXbtVf0rrkp+q1EnVNB1N5eW+XDLqvWAWXNyA4kOJA+joOpGlHUXmEjD+MWuQcXV7xs6utvFzRcyn9wG/1vg8nqblSvGWddEbdmregCL80q/V0qc8C6TnOGJS6BuS5JDsd9m67yrA3SlGHHPxIi3frT3y3bhW17mzAPNlOdW+4BY6FvBMkrFkErJ6Z9GGBfGlmHcdRD6yFarghBHpXiXnjByeUO15yGy+pdYc70nOvnYFKE7xMZpHQJUj1NvtxK/eXCEicMB4iasXE3RIncaEJrnmawI5lOxZTHwKItJhHPaB/Sq1Mn6bVwyXG64eVcjMckwtatndFIrSFnVYZbdYy2TPq4yJJ/9yZjnjHwt2SPEioKSp3nTzWD10b7yq/fbnChdT6my9VfzO1/g0LbV9CHvMkxz0I0acwPHkb47vR4dglTK/wiZNoS/Bg8uUzI8aEv+3DD5hHnQRWmLm2ZqEhCDxsz743RTc+9xKeMOPenSmcz7PqEa8U3U4ykYi/XEWjYHHxnhQI+HYwPHlU5FNIFvh4Rv6rbPYWPFl8v0U5j7qtT5dxExtXkmIzxmWQPES4kIrEFs6L9Y7jUcfkjm6mFcnj6GzpSEJYIf/SmnRPDQ9gdBhCLY9dC/whSFkMEcOalMcmabFLrY3rLGHj2uyvxlBruAMKcd/Y5SjlBuyKnoGKPJqaACO81wQvvyBWtL+1EYbFWxfoZBYHJtvf8sH3e6QVsWuD4oVSRB0veFfo/v/xVnETPCk8ts+OIUMPsVWEwnbFvrNDT9Dsnnva2tr31Ihf/lvEWxbuzIfHbLsQx7vRQngD4c1rF954kpZ48Q0pdHb0BiKyJLnp9tR/XFdkKxk9dUeyZcJODxGl3CP4dmJJDxMKfL+6M3OscIMCKdrJa6i8/WkLGEc+gYyZE3MlC5z4o6kmkcCEW5I2tyT1zEWzJctSezBtQvViV/YcxGRIk1LxZsL0WvnNZHuK7TV6ydLrW/teIral2V5nIGF6rdtHNuO4po9qlE2MPtNJD3DS0xr3aCY+h4kP3cYTFv84xT87kQcl7qmIewQ25jt+cuNnMjJtcXMUNyGbsTblOQe3CNwiXvstQqyF+CvEeiWUEdJ+8TwQmHOne4VXTjFQQvSa4SbiXvlNm1soKEJeyzNktnK078mChuJ6UOL/+e//bUdNCGeqxU3lpk8Kt37UdIvNAi0g7/a86oxWkEFDn6CuWcYYmOpksbeyTG09c95Kk0mvMm7dFw7iSa72yBOS7Lg5F32ylTfl//nv/7fy9u8CHWOq7RRtfWHoc32mGn4HbGXKnkxpHOlHEeWOA7l5EX9auMM+MnUiI8XB+FN3+K8zWWVJGYmqxViqXHJlUoOEf3svqjGMCF+pESHCMSAcw6mFY8jgONX3Fhfcn6WhPMd4VdIZ0ZbnuC+mAg3Adx8Sn+uW7SjT9ew7c0rKkA4kBgnB/N052xYcXMmNtPk46kYn76sNSHOOkomCKeJRmCLyFTUp7yF9u2hVm9VqmVXKDa1VrzWqU7VSKbe0S6a1WqzR2GigWxVuxLgRv44bccl7r6XdjQO31egFefVdP1ftlXouVOSZL8Sr73qR8hXdfNFrcHt025Z6d9u/iKZceXmGN5t3nVtxzLLoGnRvWhK+fLtZNr3u6aVHPk/pYqEuFhZbcLM3N61waMPj/EnfAXSAYA/mo7qUfngeTI1fQ/mP9H7g7ZIu4pOvibhH4B5xaveIjIrqwOqh6LIeZsYdNKkB9+uEb8rFmuqc5pnFpkg4yHlI2D8nd2DV9qz3UzrbE2l5/XR84AzmGyqo4ILmb+m8nSXMxD5lwYjxaL3VhBN6Dmu2lhdHBL6o35nd/cxk8ysTTSWGgM7XgWNDRqMEuazttqaxVD/3BvsRevkqM4tFHLkHR84td0iv8/SSQ6VqbMkSS6XddbOkK9rl5Y7v72JKbzRQWs1yRRHrNeO2/Rc/Q26LwRc/iO24Z2zM4xXJzZMeODfCeRK5LfbW1OqjHLZ7JCPxjBd03I2VxEckAcwXX21eh93to+P2jD8dBe9vd1YLXuW2m8T7wk2z8bjyygqhUQv2O8HhbKialKfJS0mHSuGCn/3BNdWL4LkxZeQzPLJ+JZZILDQ52SrieuuEMBzDtcEFZAIVJ22T8PAWWiPqnF7YMp7AU8LURkQFwRH35mpjlW4MdMywhDrgr5aXCSiRIhraQSz08+Q5mYQ0GyvCv7XBsxFkJq9GZrL6rpdIapEmLHGXRqKkxFWX7ywq8TLGykrcvTaQKklU4kYjNC3lXrcd0+LeN3cVoLivjOhxaK4bTF4A+Puda85lVqb5uhn/lSQs2INnjmRBSfglvP3yOX0KH2beCFPgvjCRt+/FvTH0vspy+dy32B0un+747NDTVeBgpbwh9Dhl3BVuj+dPXcZuP7+OzIiBPAXsxnaHoxZSERyeeeOerjN0c/fydhev1Em8Urkc8wBO78rlsGgFggcIHiB4eEnBA71RB2JTeql7c/Kr4GA36ba/9wb35Xiz9ugZfpfr7Ou7F6Vfe6OG2VEtz/b7bWK4PFFjTLg8/4HFtQvXLly7wvy2e+1JvHftTm17N68UXFvoqWnJBiHtA+qpxTMpqwgoq0fr1YpH7J7zMyttpNMnZdgb0rXOMzV8E3zvvg2F93ygoH6rpQi5onnkWm+uGOZGOaISArS9s3BBHqtsKfvjNUHDDQ13fjTc8jiZhrfTe4prm9QH5sfQXapTthRXR2FA4MUt2n4He0aRSS9Pv9vEs068PWrz3cn+WC25SzWxk/uenPUtYXJ8AcGQLXhQDaVH7wuDOfwbmzahN8Pe8G1JhBOlnWfYG9oxG5LcijKJIw5ZW+LwySsiOUmc9Duds8JZe9ij22L7tt+jP6/bHfGh/WHYo0+/7zK4h7Rj5yYqatHFnDUe+IbrZeKs0DMM8gtUmDTO2UcMgoUTx6SP886XTRf2LCa5MVXZRXk2r7ZYczpj81qzPr1s1cvatDbV2BRMMi56uOg9A0a2TNXe86pHWdOuetxh4HDQVjS2WppPPJpntjufl1O4XVZcb4jhm57vH0/hDY1lk8UBcMmBHBLRW/qMzJrUYEuSLocklEy5HP7Pf/9//qlIeGZzd26bnPrKOyAtE2nFyyjyp3seXTFL5HLvkNHqEi6PfuB4j7jGLRK3yPzcIsUqTR/X3/jx0tsnAluBXOOeEWNJ/Hg7/8MWPjz/L7Fb0NBQ/qIIWONF73lDtsv/xp3eujb4bwNlfKmLUs4DXzXdgm2u+LNXS92h/aN3qzwKm29ZQG+V2gYZYkWxV+qMiYYo59W6rfybcMJ7Xm/Zb/2iIk2hbzK0JOWBwaA+Y1CTjeXDQxUym9/4yb0EbfwQHavQV83QV+6ABP6OZPJ7FbbOP4grPektwb/y0jvPtJQH02JC2eaLGORb0xMyRF6PWwJv/ZrWPP82DvnFriMGwSIkOZDkQJIDSQ4kObmV5JA8ZT9Jzs7ymxSpDflfzialCYZpCUhefqPdSK4f4QpGJJF+2DZiHBVEiMtQaXMhNVENw1wbM8ZFR8RFB986Cf7DFguu2XrkziXTDgxSeMIlLTKHu127L7s3rLQoUYQLpdJQHnSDxw8zLaWi3Jtry8tG94chmzMeVOCfcQXbv7+5d5yV/e78XKMIBTQ3dmm2NNfafKlarDQzH+R8zkxjxlaOfa765RS9cs7fygE2H3THIbkQtddrv27z8S16Eq9AGBPXnZsvC/i7Qux5oB98jPlseI8vnzb73rRIlMVzCeYhXGawAY5pKgtLNdZL1fKCSfmVFoJZhQe7/+WZyyUexTBZxzdZyTfeyn3gFFhpPJwVxFcVkpZVfoQvnTjbByWKXPq288XQYkshxAsI+pghPG84wkpU2rAI95RclMd9WPI7rxRP8+RRj18l5c5myrf/0/i/tW/8CdHUJ1t5Q8GCTeVbrVnXvr2lZUYpfogUPxj77idpVH98I1HjasUMTflGxynLXH4TwiTxYFED6XzxqC6pjSuLPer0glgxSzc1XiYdMlVLtynwkPSPKf9WfuiGZv7g4vJ7fc7Dbquz764tgttxkepvtrLkXuEpxoChcRsMaomq/Lg3ie3yCFXeiYJim4ruKN8ZW9m+ZJ9+09QnRV3qC0O8nAxN0UxmK4YpqLOluoqpXmxSyrcLzRuGGaW2xagWK3VqTPGioHyrlBPSVEWaSv1tJLbzSrVtKvobb02wDseU48WEUSm1348l7Q03fU0y4aX79D+seYwsm+yNeXwjdwC0tQwJqIpRoSdeZvq7/zCKHUhKnPnD6M3+W8VWHd2eP4kG0T74oDpkV7V8Ek+cCK3kvuPpCSMvolIhMqOgEJYYdnqqxLHhTUA4LcbA1QH4BWUx28HSwtLC0tpzaW1/PV5oO78V91dhPk91uHGZCawN1yEmeyShyzOmVXp2DozwuT+6uq3Ml6ZpifMJ5TQY+XR2gqfcKZuTOJvRjsNr4YtLrAublp/tN8BWHlRndi9OjjKjv9ge1Cch3dt+JseAv9CAJ62gWN3qbuvo1+urMcG/UGGPwX+x1RUf7X3r6ZKkXgZzfpjW90Bo0h2Op/EFPF/jJkRxY+HJZ/c+iexcirdHhyK5t3Hm7X5/cNfvdG+6/fFZ4ey33vjT1bD9W/t6N6z8wIHkQormBLW0zWMK2G8FkhanWS0pIgqvXMzFb8LfkWd2bgupkWxS5Nj6rVi5qBeUWq3R/OZm8pvPM7ZHPMl07UhvnZsJKPvhYtzlblhA5+dIpxtUH6S4TYuVafIuzXWNGTOWzcMA6Tcc8RpLUwzuqGmdNua1qVZp1cv1y/J0Vm9dzOds3qo3mhet8sW0wp9FHih5c66kVaVNmhrd0OSk0Knk3vyhPKxn94rfSaXjycSVe9UTlkY03Ek23aIFhdAg/C59AAop6AGHRFVnl9qFplaqGmvU2OVlpV6dt9hMq122qky4Nl+qtnPH3zxa3NxnUJtH5r8QkuiGNVPByn6yYp2vBL9GKNahWM+rYn1Pdbq5Olft7Mp0c1XkyaOqdMdcKe0Rixxr01TqtH1Srg0lebQM8iTl68Ztfv15m6wVzxDC5pqSiBb4klrXS5kXZWwHFdveBcb4u5IX4Bvd0B/oDSwemwf3zzL0idAnQukBpQf0iVhaWFq5WlrQJ+ZMAA99Yj40HtAnHssEQ5+Yv9UFZRSUUb9EGQVF9skrsqFPPBp94i9SZsWEBxKt+J37aV4JRVM2fUl71JeuxpMNPtqr1ZIVu8ZCNxhzPZRLx+gx4lyZ7aJS/4t7JFjHmLfeMmvGDEddMBGhXNwbp09u1ELFXHu3BeFQNZBGXS5jZOjpRivl0kXt8rKZ4CldjoLb3BidULyWTQw2dGzQseVVx1ZyzFVJ6r8SlW2kRkvQsp27XmJ2UrcZdnH6VPSypqneRCLhb3mL7m2+Xi59hxabSjjTCPrfopjQPFoBt70zLY3RPYS2H6mbC3jAEd6elbHkI+gcyeTpjcc9mPHzws1wLH5Wrdm9/sg5DM3b2MRVqsrtGVNiI7vRHNJ1YAlxJhIVXJniUgT3037Yq1MGFeSN+gfp80JhAmhiPK9DKe3Lkjf5TVQpIwzLzw/DssMLJf4sEQ6kEnnT+CFSNn5Yzf+wJzM3UsUWTkm8//1FJfXLgTJSI4DseLibNVqN1rwyv6w01ctqpVVvsvK0WWlcqvP6RVm9iGue/cI+Muqbz1DfdJQ5qWV2enJ2JZtqGmtNm7X6dFpvNZsXrNpSm7PmrNEst8qzBoFseGG/0Avbe7PGvLX3eGGnvqi9l+TOnExYYLBRAoAYADEAYqC1h9YeQAyWFpZWLpYWgJicaZABxORDZQ8g5lgmGEBM/lYXgBgAMb8EiAFAAgUIAJJnACSSKEsFSKqtcv3dxcVs9q5VLpffvTuv1c6S2ZA23XWZxa9SVNQWb6TlDaWJB7mB5gDNAeVQRDm0s17IdDLpgihZUP9zTaCF/DZJ06N6OAYlhEKHL5z53GbbpDXfdVfq58aQi2mkPM/PmTO75ySL7087VTJxiMKTaYxyUsenptNRHbYwt9EtMaepqekoM5l5x4NYNGvSUWTUbQ87nybd/sdevzvpDNu/XXeHZ4XI94Pbce+m9x/tcY8fXG4G/d54MOz1P07a/atJu9++/jrudUbEHF596Q7HvZH72017+Lk77vU/UpmDTq99PbnpXvXaoR9u2x+7k9th90uv+xuV0WlfdW96ncmwK5rB29O5G/bGX/nPne5o1HvfuxZ//9Z9/2kw+Ey1f+h2ryYfuuPOJ96Jdi/Qo/bHj8Pux/Z4IH9pj0a90bjND53t3sSrif7pfekOwx6/p6Yz4HuEmSlI9sZcmDLzHtMYzBqdxgf1j2suXyceKPTcfde3iXUSqqOMJeWKrSxGD5Am5P9fmCXWzHvTUc6Vkb6gfaK9oAu1ppPgYObIAJBTRivHYg/m45aj9M9qQNLD3/4o7hzvB2Phxserc+N6MTUd0QJxfhk5qrO29xrfx0AxJFZ31rtGuEopJamnX7rD3ode9yr8UOPO9BPuTO5JI9u51d2zN3tDGKb7qysRnJpO+j0isAP+FZnZzQuKPOV4MRXoOZMRKlZra2Xa7G16bYMVM9q988696ny8Hf+NNFxTZWapP5YCfON7UmzH6JfsnZLLdnO5evjcZg30S+YaPt6O35v8mO9uvvGFmtZCNWRwX8W5Vx3F/GEIAFZklNzP1grFyPF7xXK9iJuc72yqTosz1WYKuetyaDO0FI1Z+mMwDAfNGXU1vbrFypmK/q1tZvFN9FZ1SIqc+qiG28SvCirfgFcysxgD2b4nr0G08NlUcSx1Ptdnpbih3hT1RENr0bh4JGOwJQX3XWf6L+iZf+Ta7OH2qzNfs7gyv84rM5/7fN+Zxf018cJM19foZfn8z6npTGgV/pXt3lzUxIhs4JO0I/i/peGSfvwfsYuI84oMXht/p3Yb6R5qVqpzv1ELHSEpERXjP2ZixJPOMME8WzfWtIM5Dl0/59C1PRHOWq/8rOVWeGfFuJWlOpe68d3VSfNty5ytSYfsbULJtbjh2FZL1aElXzJXzFB1HohNM2e2kEDSm0tfGKqzthg/pCQ25W547Q4pP3P9zVb++Rub8utwe+3c+wHgpktzEQ399oNN+Z6srp3787dce7+2Zqyk9Ml6jB5Cag6n6R7di/ajrnrEoNfIbJ2W3/CqvaxF3m46w62X4j3lPkk483rnLK9t+zVKlCTZddfwWDbn03h8606o/TMO4cHlFX8kt+PP5zHHcdgJ4Vz77HNt1KKXjrXylWmfyzfy+Z+a/sAMWzeNLAddN3vRPeNGT7syQWj1cYGlpU/X/F02fVK8KtO0SobiRuxkmnd+MOfhdS12RbdVBYWPkrsXBHUfXpXJZ+lgq5IP0yNZpHj7qo7oGKMaxcHTMUUrosqUrCfvvStIOtV2rnvd/ngy/nrbpad81B1O3GPOsPuhO+TqAn6Um/C/J0NSfJwVzrhqo9O+Piuc9fpXd6Px8CvPM7od9EfdyWjcHt+NNr+ZdNrj7sfB8CuCiMLGCYYYMMSAjROWFpZWzpYWbJxyZhQAG6d8WGHAxulYJhg2TvlbXRxivWXWRy5K2h9mXTHLvcWbnq8U3kg+nfI+6ssvqKHuxstnl9IKV19kgcOYJmri7Sso7A/HUmV56mrFVMsTjdCZzSLxyr/OTHp8/nXmk5PKgIbXXq9WpkWnQNNQ7vXFfXGmWppuqCSr8iUp9t8VXsAPnZ81PP0lTb43E4rEZeUpWbeV6t687isfs6y+0Y6L3dxYgGFV8S5r75F0mTMem2+3XrkZd+xRMFuG3lTLu3VHN7S1vdULYEy73Iw7dieY7QW6M1vqzHD2MsITypw97O/CGbOpj0i7SCndV7BodykgMP10d9MmDqA/6E/avQnhspyZFh9uev/oXk1u74a3g1F3N6M9V7y4J04rJd+iDEnBci+P8k5cLZcLSr1co/+hqy3fmP7Za/fbRYstdNvhzi8pg+2rT3/8+FHSVUMtmdbiXLVt+Uq1zylBUVRS5Hk2vyn9ce88LN8qdCtWZzO22nLwOeU+Pd9KNTz7e1tJJI/YnrYT2QrcZtfa638YDG+4yQTXGIzuuN0CVw9c9YbdjjSmkNqI7nA4EIYXwy/dofwTFrDHBha5FrART67MUbkPXBfn2dRCJTFICL+cn/DLkfcqBWt11IeV+2Kl1LyrJHUUVvJxayQuaHPhzKBvl5J/ioMWAj8rQu2t8AXh3zg93wVDNmcWffvPuGyB94ZGA06Pnx0FioQGfWYa9EKwz0OtO49H1+TSv+0OO93+uP2xy88O/fLkpv0P8VF+GrZ/m3xpX991abP0k086n9p9nms4uL7mBmZfukNRzuBLd3jdvr2lg0iwfKG5pWdkbehOzOHnhqn22uIRaRWeJGUJb+Gn4133BjGb/yNkH56czlXmbywAYzd//kG96kac7/ADFX6W3eES0A0nDULW897m5LX5z7POUl3TW+msWSvVy9X65Vnh7Go9+07//9HkNu2l6kW9dlk/K5x9NM0F72qrVGtVLurccl7VNJ0aoy5vw/4EUg3pBX8147uP8NahsZn+oC4FG6gbc92gKycftAj3VCmXGhmoJ28EXtZnMSwDjtsygHDLjiRrXgFJVSJo1CWJ0rAqF3hKRKv8sOUTXpe9L2TlFyQHfMM1M0m4pAzXnB8OvuKHlGC+53NXXKXLGwwC6xcRWOpi0aPF9bhNhNaW4B03MJY53FOde/2R9L5uBCX6pqVUeOwLL5v9Nnj+iit4n/OX6pdT9Mo5fyvFvOaD7jhMK/D2eu2XOvKizZZczOoD1b7dja+O+bsy1w0W6AcXCHDtg7et8LOTfU9iX0tq6ktKbx4pM9gAx6QnRzXWS9XyTl5+pYVEkXAa4obJOr7JSnF1dB/YGCqNh7OC+KpCx9DKDzCTYCYBdgHsAjOJpYWllbOlBWYyZ5ARmMl8UF1gJo9lgsFM5m91gZkEM3nkzGRUO5jyiB6Z6ln5tqEy/qZISbdNp/SZsxRBAzY2NHktUAO3I39vTb0LvqYxSBblhVTvGpurXN8X/nobBrCp7z9iP6xgecHyguUFy3vqfQLLC5YXLO9zWd4gTpAfrXTKzH/ofRh3u/3JTa9/N+a05qDfnXwa3A3lx6v2V/npt273s/x4M+iPP3GGDvAz4GfAz4CfjxN+LoQ2dM780g05Mwj9T5+E/j2MQv8zwEL/7sPQ//RpaOqeu4I4gVotV2vFcqtYbo0r5XeVxrty+T94m5Kg6YQLwsvT05En5q/oJh7sV/KGlUnCGpnxQMkbLiTdqQPBDYIbBHeU4I5y1Ruh0vb0jklZEz1jco/DYYj6oH4xY8qHN8zNI4kQ/LwfjCefe/0r+XFw2x3KUFn0JxxYAsYEMQZi7NcTY4AxsbSwtABjgg0EjHl0Aw4YM+cTDBgzf6tLtbfwbTFHy/baMQ3zgc4HoyfbYQ8lRdzLBVRlWsoDdWcjmdLnRylbedMe9e23NAcqTeWDWnRPmBoPHl9SbnnQevkkFPlxhUdc15hCeYX9p6fUCJ15vhUrF/WCUqs1mt/cTH7zecb2iCeZrh1X7ruRgLLveOJ+TcPyfGRiac4y0JUxw+xm9Ec3frRoS1KXq3u1WBUQSerwuaVuGcO7UeF2nDR+tC3cjdIG8Ha84zN1+p19/pNCFwTdEMHTdntUvJyHHT6v2C3j170r9NtJ49e9Sxu7fnvHB+XUu3qADQVmBTArOG6zAhEcd3ds2w3vuCOyHYkKeUBcO7cc+tR09qY3qXV7cprRrNlx54Q4va56a9RtDzufJt3+x16/6wXoLUS+H9yOeze9/2hLjvNm0O+NB0OO2fSvJu1++/rruNchJKd9xX0QjdzfbtrDz91xr/+Ryhx0eu3ryU33qtcO/XBLBM/tsPul1/2Nyui0r7o3vc5k2BXN4O3p3A1746/8Z4JLe+971+Lv37rvPw0Gn6n2D93u1eRDd9z5xDsRCDlcOGt//DjsfpRau3Zv0h6NeqNxuy8Bb68m+qf3pbsjkTo1nc/6NiFEwsRSaNCScuWFEBbS6i9uoFkKYXuujPSFwTSFhwLlimDdmAmoke6VdOe12IP5uDOE/TIN2EYMu+6sSLsaO87RgMqpIy9aKo6se/L1Uy+0r2QUJQv9xhuFR1JrGG743121LXuVf7BV/qU77H3oda9AWeeesgY0DGgY0DCg4eOEhnfxmPxBnbGpaX6P+kYWwdhDjpQFIiy+fr7L5CjGCxfIAGgRRD5jEPkkb8c+Q5sVjA3kyMDGBlwbp9CwGxmVR3O5fmBZvA3DHe4pe1iFO9wTmiy4wwWBDUwUmOgJYqIgsLG0sLRAYAMIBoF9dAMOAjvnEwwCO3+rCwQ2CGwQ2CCwQWAfIZYMAns3SA54K/BW4K3AW4G3Am8F3ppHvDWJudoRl7xoTFV2UZ7Nqy3WnM7YvNasTy9b9bI2rU01Nt30nAh/xfBXDPQY6DHQY6DHGfwVb4CpwHaB7b5abDcA2yaTuxPh/XYfL7dRF7obSG+A3w37uY13VRv0fltKAX75GzlSXLgkLuGiGgoZ/N9m4YThCTfqCRfk9CnDuCCnT2iyQE6DnAbeCbzzBPFOkNNYWlhaIKcB8oKcProBBzmd8wkGOZ2/1QVyGuQ0yGmQ0yCnjxAnBjkN39XwXX38Ywbf1YD7AfcD7gfcD7gfcP8rh/tB3IO4B3EP4h7EPYj7nYl7QrYtnQnH37uag7WqzWq1zCrlhtaq1xrVqVqplFvaJdNaLdZobHTWrQoOuUH2g+wPkPchwH/mnKtr5960dCebZ+4ZPWL8IsCKwZxBnP+aJLGBhEo4YRKqr3oi3IS8ycg9F6U9QyzqntJ3oVX3LjBGoCZ1yVIA5z4vD+6fITmbOZ/bbBt38113+S1PLLnZSKmZnTNndk934Mh7K5ExOUThyVLFclLHcaX7CVe6wNJrhzeGbO+dQP4hm5mWNubZ0o1TqOjoupcLx7GIdpjdq7qRNt7DARmfkPTuQ49sUM4KZ73+uDvk8rpxN/STuDitDcd6ihdIOD/M4pI5hOH1RgNFpuUKJeXHPbOECL3TVkxroRru8ZdESaq9jcK/HZ/51fflmW+zCfP1culVTM+/MjMt8VhwsFCeyYNN21KvaTnrhbrkl4H0anl18tIRtxM/KW867fhDulfdzd31uEeDrrS1R9WYMU3peEXRaLW9wsrlBjXK/GEwK75VoWF27lVHMX8YNicexWtKPkaddsZGcd8BKnGqyTMQHAWR9twyzfj32pNolW7ba7ovEcnJBQAPTNMpXSBP1mEbUl2JQ1bxezC6V6uN5gfdWPCTh9gpNrsz+tQuVhtNsldxE4Z7l72R1Xr36qrebZRr7dZV7cPV+8aHD+/r7Q/NZqfVuqg1Li/Llc77brN10W60yxfN8lWl3C63ut2ry8v2RYcH5rHYoxmSecZLBiVM7Kd2RY+k5w0MDwsMDj2cWzsjt43+YDwZdr8MPnfJns3/dNsedvtiQ/F+5zeIZw/2fs/F84c8ejva6EjBvR6KhRhaIMnPWiFhw/d32PBmFzPz2y+iCe8kXOle5ZUuuOrHlmrY/NmcPeX8mjdzSuFrVOKFj25RyXe88z9n6sRerhdZTLfjbntPRU0M24YJd/yr0U+dZqPtW0J22opuiLO+tO2Ov/PJbqQaWXdiWzT61I7szrvYVe9S5svu6LgZ/eKb0VMGjctqtWRpZxwJkmc/2oQuRrZjWqknnF6/c313xQ81dNj52h1PIl9F/nzf/TAYcuF392bwhX991Ru131/zj++vBx33MOQ9/J/ZU09jBjU46Qgfn1aSRpyAChtbB7eS2+7NFsvm8feZ8cF5fP/5P/Xl3X899vrllfZ5/GH4jy6/bJ3IlfTeMh9y+qi86uv2gz6zTNucO/mc2wfzv/TlUs1n5yAqgajkGaKSZrl+VatelWvN1mWj3b2qvf/Q/dDuvr+oXnTK5ctup/yh+r7WufrQrlfblc5F5aJW7jbbF9VO7X338qouRCXLeEKg0w5YK3ADMP5gZFc5n8iL8SjXIARYRyvA2piapCNggnwEE/tTJ5akCHz4M1wj4lIe6BLxZfqf/3jo3A3vbx70G+fqwvjwtal3rPp/SepG1z5Y5kNCs7jVPTcP3tyI/ue//7et8ALoGZAuPt7QSVdc22O3phDFFR7wcuWyWKkWy5dew8ZmfLNcTxE/o1G1arHcLJZbRyRpDl2oCqGb+OahPHqOjd1G/MfAH/nEe3DCc+2/0DdckMZKGF5Iyl2PgwAdZU5eYnYSruzKcdU01po2a/XptN5qNi9YtaU2Z81Zo1lulWcNYkUhL/658mKSAYfFxUtzsSsLxLOkQkAyxW70D2UC9gPsB8LtnybcvpaLP9sdUl3p8YeP9m2PzkWGplqauPNHj2RLc6HMzeXS/JHqdnb4odO8bFbJjm7cHvc6gtkP1rdhKaJMLZ3NlcC3cRfEpblIPxJ+NM3Fkil/a1sL06iWq/W/UR46djFD67qrd8vZi0Qv3CKYe4ojc2AO85sL8WDZZEyszoiD575f/PbFDkqsQ5TgOazaKJYrxXJlXC6/4//9B5cYufas24VG8iHUXc+lcvOXS3mP8eMnfFLUxczT3fC6OLd0ZmjLp4LynU3VaXGm2kzR/eO9S9TvVLXqThmvnY7nPSN1vgJH+OQZ44nsg05XPW666CqZ0E734smTJD3Vyg3twVLxqqhTc+247ScB4Ew1aEPjZz2FBOzvFNdkY8GnTJycSwvduV9PS7p5HjhDBY9QdFCYiEJL987DMmUV33HxKrfI6F8Jy9n/5659LSz76ILbvpoM+tdf+edxbyi//fduZ+zecKkezypmi8FMdNocpvxQbWFDI2xnYvfxTMuryuer9a5Re1cV87W2YiybaLbuhtf7Pb/ufMyckpgSdaXb3HSGTkTna7ty7j3i55t3LqEXD7YnsAfw8/KZ+5RtDOzGeolsd6K7O1E7/JUCXAe4zqu6fskLzy6cDl/cf/JddQ9CZ2kuMrE5tCfuSuVE82dCdNyOZGZ0+G69XC/25XGC+bMcDgoRbxq4d/zSe0cWnOaXXDfUx8X43jLXi/vVOkGyrj4yS10Qq+Cmc09nnTHVXVAehLEoFw4ED47cwRC3T39DX9vn9DkogBW37DNce3a99vhGqVuOi9xbpsndas64LS/P5GIfYgJzdB1bMYu33JjFDMy1uVACCcis29JndkHx3VrLZ11wBStmFZmhrUzSJcnXSpyrB2O9FK9O/70bPF3JEnY4YLlZEi5KkaXvNTEQXEI34nqatjuomlbkCm7ljcF+vBXhLt1vzKXmfrOyWEy6wLcyLb3CmeHIqBT0F5ET7mfbuefbj7tB0zMbGB9/X1ivnPifIgc/b8giZXolJJ1BD1N9fJ2FwOT/ngY80DUiSjxkcJgVfmqwhe60VUFyA8nN8yQ3WWQTAVFEiuQhdnPCA4oHNMeiRXs9pThldHCikeoQ4RCjuvf0cKGLBb8HkbMkttQX3hHSp3H5+Va3eU/Ih+29+sh4RJcpI7elwqOtpjwxp6S8J9iavIyGarCFYz2KPUPwH9MUTn4Smhjwjbo0F39zn+1Q/LQtXH9549jojwjTdh8PdWkxVXvye8bbp9spJ/xtrXmFot/w/SF6OY6doITnOHRDywbGkJQASAxksi8kk91kYaQYdceYtzOn6Mpf0ySxoci0wZC2aaCMobieBpmmyLI3trrtoWyTxbb7BLANkdcvHcx2z8qSDhCdNslO25PBb33ubffqbuh6C+72x8Ovk/HXWzpfdP9x2xO/TEg2eEcO5j61R5Perfvpt971Vac9vKK/rwcfxf9O2rc9+SkQLff27v11rzP53P06aV9/HAx74083JHTsfey3x3fDbujb8TWdWb60r3tXov7r7pfuNUJ2ImQn4goiriBCdmJpYWnlbGltfz0iZOdJxbhDyM58BBVEyM5jmWCE7Mzf6kKgMwQ6O/JAZzN191iNcX4JdrxAJZaRtBKzL7qZOpCmuAfolu+F4rmd2+7PYoe3ttznntVHt5BndC5YROIRX8olr8fdSY0Efx/Hk9rVhP68kH9eiD8rZfl3pSy+qLsJ6l4KP4lMU/W+4p92CqtErNKTtLvebRx5TuE95E1wQCh0FOei/O/elpSewV+pDldaetfAb86Sbvi88POQIHuH2XjZhmyb09thN+z6JOTtZKep+GOlW88JG+YX4AX04l/JeF7cwH1XKU/mMreNE5e1dz2p925Dc6/avdWuA+Lqt3/ci1NfRNFgc0X6lIMNjunf8nu3iqppFrNtlmo++1L1bdkaXa3oluH6TV9q9EI9+KCRNIXOtD9kBYpm0hn3wEOVVssBBojYvee8Nzg484Jb2rPrShqj/WONLs1Fm6MGzxo1jvW/kUg+30FoV9FnL/uGeLlGbNv1No0PdhzzvQPXRvvsgbU/c6D3r/TwD/BqPV3qs8/sqb1c0Gn0/mHnMRVFKN8ZieFlITuOUFIR2x6kqxHptLsd8e9w1N7tSSKsS3XWFtu/814Re/c9oYQMXZ+MPrUnFdLky8/VRtMdDu83/6/or7VWPfR3o0Ir8nY0CqR2/xJp3b9EyuGoPbm58j815Ce35mGo3mGo1mGgzp2mzFnuHsDXMVdFHhVRvi8T193SXHwr8H/aK11+creabwWhyPCuBu4Ktf0lutvr/mc3bLuqZcZdPgU2k2aNuytx/6zuMlP8EMzPyNcyIuVus+bnV/gY7Ti2cdm3rqnBTbtHPMxg+LHd94Npd/8x7vavdo3Nuzb0/1yzrmf2kqaN8rgf7+xnyllUCD3W1gLEix6dyS4pfJezS8qIOVyyZa0FCCvaoUj7Gy76TFXU/IK2bJsYyk9wMVl57zYJ0QCOKZNwfNFBk6bo+FqazPmG4pRqbK5yg9nw1965MD6maRgAg8HyCYa8RgRnBxGct1qKIIIzIjj/igjOwtKCE+YiarNqPA3mwgBB03TKqS5vk+1rz9qkZmQWp6Gom6VNk5rIkSXw+59nV/pCJ2MFnrZUvajXLumS9NG8UjWNgPpWqdaqXNRr5EOcLAoM5igjaSehDJnNVGt2rwhl8ruzZq1UL1fr3HNu1J1OdDat+YyLYja1TMJsRp9t9+zjluHl2JyyjXoXzqSmTZYOm1SaWmztC4d+4klqlcQktYpIcpmc5FImqVST0yT+xquP+ykyBpGm+IV6RWy2ZaOPhciwZBjHoF4lrv0RRczWfoS1NpHcGdrjKjTi2iJUHFubIJIVvKIy1NrvfmyPe18ShmAw6iX8GKnZS1nwS8xQO0mf4ioWcqm4X4ax30daMwwJt65Cwq3EtghBQmyl7A+HEWgb+2PQG0dsgrXx3TB/xP0W3Y1FCyJF+gUEGrLZn007am9bRoR7+Fd7hbZ8aWZ8rsVd2JSPjtLSnCiTBV8gfYoRny04KC9hkt1eiDUwl2vyXvJIx3D9gSXb4qmLBT/YPKpbBIVtaRPIY2PJHO7Fw72hc7SfHPkEKUHTUirC/ZSbzX4bvCLEFbzPFUH1yyl65Zy/leiYKUyGC34oCmq/5O6LNluycGwH3zOdj3j+ncJasEA/uAqdE43eg8WP9/Y9oWSWpP9LSm8eKTPYAMckc0LVWC9V32OEX2khETNLM5vDZB3fZKWY/t8H7q+VBukC+Ff8ZFr5ATtM2GHCWAzGYrDDxNLC0srZ0oIdZs4Ml2CHmQ9LMdhhHssEww4zf6sLRm4wcoORG4zcYOQGIzcYucHIDUZuMHKDkRuM3GDkBiM3GLnByA1GbjByO34jN5hEvYhJVBL7v2vgg8ZUZRfl2bzaYs3pjM1rzfr0slUva9PaVGNTHqruRa2vgnRdfiCtlIfsQ+/DuNvtT256/bsxt68Z9LuTT4O7ofx41f4qP/3W7X6WH28G/fEnDhjDXA3majBXg7nacZqrFUIb+obJBMwkYCYBM4mAmUTAwCHJUmLCC7V3D3/kFyHHNGpCEbCaiEQv2issEn8vB/PtHhEpiz0GYiOdYmwkWNGcsmEGrGhOaLJgRQMrGqD+QP1PEPWHFQ2WFpYWrGhg1AErmqMbcFjR5HyCYUWTv9WFaGaIZoZoZjD0gqEXDL1g6AVDLxh6wdALhl4w9IKhFwy9YOgFQy8YesF8CJZup23phkBaeQukBdM9mO7l1XQP9nSwp4M9HezpYE8He7qd7enIIMvSWTQU3K5m361qs1ots0q5obXqtUZ1qlYq5ZZ2ybRWizUamYKxZVCebURp25rnBcO3ZWhvYly3bHnjA75ly5sQCS5jo3fOtBE7bteZOa6gchl6nBhtbteeHz4MXYbWR+PT7drowwSuyzLMmxHtdm3rQULdZWhqNAZehizD3TK8SNS8TNDCRji9DLkS4uxlyLkZgG/XoTlwZD75jkRcPhicw+A8weBc5A3ZncurUZbgfBYjfM4uelmCxuXXun/PSgvIpypLSmnOvcTJZt8c+nsGwOlKkXaxRty7wBj0T7LCEhV0H4EH988QEWjO5zbbZlfxXXftczyAcrORkrydM2d2T2Bx5F6VKMg8ROHJ/GM5qePyMdgLCHPv9VTtjtqRaNY0SXf/M1183991PnfHEWl35Cdf4h35Ydi9HQzHYYk3Xft2VzeFvShIccYuaqHYAlLlIaHhqJar9WL5sli5PPsLkuOfKzkObtbZzgWhXqSJP8ZkiOYuCslCBXdremzMlVItl8tlF41SFktzSq8qOiDowaNnzAZQ+6vgSb43ThfiLZ7cKb+dospYewBHd5ZbhDxjc6VM17PvzAn3xI9Nn5Y7sqqjBx2dG9PxRoSffFm27KZ7Qs0iSRKzjcPsqzzMXnnzn+vDa+DQmHiEpV0o7tR6/qe61FU7i3ekyOm1qJk/jKWpahsuktxNsDP6otiOxf5/9t59OXFs29d8FYX/6cwOsAEbX6r6dAdpk5mcsoENOGvlXlVBCiRjdYHEloQzvSsqoh/iPOF5ko45deWOADuF/MVaUQlYmpLG1Jiac4zvN6SO1hRAEhv6niJGSlUZGE+6GbbTkwpqVWbUaje+zGWgu24wfwr2DTf08hauHstcGNHkM6dY8jyEmf1Mc1Rgyd8tKkOiuvETWvXOa3HolfWV/Ptx6moSVExasvuKiLxq/mWYg65rjYXyoHC0t2e1q/9wT/rO08JBLIpXMEoySh7SKClGwEWDZDjUiXvIcpYOk+JvS8fJ/MQeLh0rg42U+9btqsW/KTYQSdBwB1VxDHMw1IOmlg9QB77CkMPFB0uTd9SehgzfZrV1U2/pGRPNcOWttnCaGDXlzw8PbE20fkNx/66c3gcJeP8XmXIPXWfWXqK1uSB0cC5zf/Avhqk3D5VDe6hMeUDwZDGdE/9BkLBGqWY6+eARMvswuam3Ff+XXeqPimbE00EQk8vLju632OimNT8VWZNATPx7z8q3zu1N96be7t5VPtVrnfub6reoupIvVlecSS+vqYYoLbgIuPtV+VYsj/w6QMXHb1LxZ6uGX0TvW1H7tn1V07Rf1bKnb6Uty6def652P9dE9PWm3m5Xr8MP3crvlVY1+lotiS+1ZvdLtdX29AO3jetASnBX6Vx/luRTvf27LMfabDU6jeuGmOn8x301KsfaqrabjXq72r1u3Ex973Ruw5qpc+ahBCMlGKkTR504SjDiWrhWxlxr/eOREowHVbOMEozZKBJHCca0dDAlGLPnXaqTvEpaZeJapjUS84P2s+Pqo2PFC0c8K5api+fySFzO3GZKXU6lHOVdpV133os+UEVXjtR8MMPUJMZyrDRt/cH44d8JeTldkZSepitiX++tD2FUY2rO8y1fvDjLKaen5fNvwU7R6csdK225SW8ikgeLNxC7J5xxvyWzJMHdl9Wv6W9Xoy/YMbLuYmvJDP9w/KjmS0rf0oSDrzBf0OoaG963c83OMvuJYeG+vcqAzU7Ce+rwL3b3O0UsEAwhm0te5yjYc7/mC5tdY7/qfa5eWWa/6v0q29UrSasrHfil7uE2UfuP+ud1GPrScnNyd7+O4Vb16mYbWHNFm5SiMy2R90lcYiMW+I1sro/G7rNMuYT5YuVdvXFT6VRWhpb21f4ezDG2LdfqW8nLHYmzcqXIRKQ0gmYSetjyRpaGDvwsx/1NU6QTrsV/P3c68pVvndt2soIf8mK3Yu+DNNvzNvT9/M7rrlbI5yqVivxHlLyqfGzffBD/1kWph0pTJFgqnTv59399bMkEkHyL3k29/Vv1q/zU9mulin/qlTtZOrX9tS4TQ5+vpVjy5vaLzAt5fw33vWl48j2h5fNElfe1s0vv33NRc+tTsyH++En+8XOt/rEh/433Ta3Zrl57zdXaNyKzVPNO1PvtN6HCvz0Vwudb2eRtQ5zYbVOmoGq3Ff9fcdF38j/iUHcfxX8+eVJ+edA70eSdaKxeaXbEl/oH+R9RDlB8kKdYr9157df93ept+Z9KU/4jk2Xin9Pg32alVREv/qvf3wpT1/8l2mo0q/Xmp6Z3AY2m+Mk7ZFOWFPB+b4kmW612TZylNL73sV2ri9Ic7bvaXVVcXFvauN0UV9RuiW5otz9/FDu3v1yLS+hU5H9uvf06XuudW6ms7HhtduRp3fvXdC8v9b7ebsrruW+Jtx7+/pu40n+VREW1/2zUq3dSGWtOhsMIjkniQcG4dC3+uI0ThYOeeG5u4Udz+69zpXqj2mrJVz5+bLTuqi3xqV1tfflYqXldGxZVqzc6tTvZfdWP921ZSvdr9Nev/2q12lLdUo8+NTqV+85n75Mw71Hu6EPlxuudD5Ubr9M+VG46tTv/b3desvRDJfC6D5Wbyq2/fad1L/3zQ+XmutH4rZawwHFgm4673fAe2rbTud2la/zd1/WMrLZ959favpOVtsv+17L3tRh8LwY/fPa/f/a+BpW6/dLdv/tff09mN810HL2/5ZzHy6or74QF2j6So1SFlldWi3sfUABbzYeSNL7O3LV6oJGviTHuXjIB4YdG53O1tY3ZKt9VO+lQsPHl9YeGTAOJYwh86GWMuOgo66zZvm8KjZscJeqNTjf6voUNq6XdLJj3i0nqmqKaznexpazbruVdKy8SOQErtsvcfPtD7WHaaoy/6LazTaij1lSevF2Vd7Xx05msR1xrPp0nTQavbmit9zWfzuS06Ok8YY1i3u/C+13S/X4XGYU3zEFFDgh7KIgfAI2P6pOuqErQvj/i7FwJf33zexixXrS6bjgcigK2wTJafA6fJ9EX+YAWX2PTw6DQbRDvWVTn9lePFRAJGtvoy4RPiGIISPvZ4x8molZuXszGlc7tjaO8K+WHuuvqdk7xoIzJX9+SDrWZtsN6SGKvtYMPXEhyGLKMfRc5pWYnNTtX1aigZic1O39ezU6vQoOUrnh1OmcHp/Cc//bWPb8clQvHxfPLi9PTYA30y1GpfFy4PDs9PxeXr2qa4cm8m1PWW1NVLToLKqG9aQVbvZ118Zq5UrfmO0L+qbRMuSanuN1Hw02mW8v3nvNy1/yj4ead4MV581q2mAgtnsVVIv3bDrK22bzwYi0baiLUREgekDygJsK1cK2Ddy3URBnD71ETZUPvgJooLR2Mmih73oWaCDURaiLURKiJUiixQU2U4DYBgQGBSQMCg+wH2Q+yn11kP29aNYjmKcWaJ+S90J7QntCe0J7QntCeP4X2XP5W5RlSSiTudVvmhcXlrn4fTrFwNPO25V1b2+QtzACmWQJMNX1s631vZPZLwb9R5DRmiXATY2BadtjGWvz0OCI5l2KoISkqN3LEaxWHuuPkg8MblpkP7yhhEeXfoTWVtv82hA/Pyk0QetrkMaSOjRORWZzYfd3xH0rOpBf9JDBY/7EW4LDdp9LJe8UwHVdXteNlzKxfGCAxMBsWFFiJyfq69OgtAduCstFqImp1o5IBYLRgtLB+sH4/n/UDo8W1cC0wWqhOMNrUGRyMNuMdDEabPe8CowWjBaMFowWjTSFbCkYLRgtGC0YLRgtGC0YLRgtGC0YLRgtGC0YLRgtGC0YLRhu+o2UvGG3w7pe9NOa9KmYvTe3vGme6a9ErbqIX4PgvuwH2BfYF9t0a9g0p18yQvl35Cqhted98+AKpDcnfcPv9FMnd6j1XIMAgwHCKcIo/n1MEAca1cC0QYIhUEODUGRwEOOMdDAKcPe8CAQYBBgEGAQYBTiEXCwIMAgwCDAIMAgwCDAIMAgwCDAIMAgwCDAIMAgwCDAIMAlxvdLrt+2az0epU94Tu7rW5GfNMn278WIC2gLaAtruCth5emincVi9tD9vqJT3/5MXrNsRtdVPLu1ZeADRb87bt6nX+SR0acmBXVNP5LlaZveepxgP21nFVdwJlC2ULCggKmBIUEMoW18K1oGyBPqFsU2dwKNuMdzCUbfa8C8oWyhbKFsoWyjaF6CmULZQtlC2ULZQtlC2ULZQtlC2ULZQtlC2ULZQtlC2ULZRtvfqp0ql92VOh3WajXdtXa7N8bXCisaNA1kLWQtbuTNYKDjUTXK0x7gZMbGKu1hhvytPWmoq/5X4K10btwcrCygL0AfSlA+iDlcW1cC1YWdBNWNnUGRxWNuMdDCubPe+ClYWVhZWFlYWVTSFACisLKwsrCysLKwsrCysLKwsrCysLKwsrCysLKwsrCyv7FljZhE502Tu9PNWvCmfa1UOvUCqXiqXyhf5w1e9fXGilq4u5C4RPhU+FT92YT51iMjPAp8osnGEOul7l1OSQatBA3msg75VYXQesBnv5BVv3Q63ONEqdV9hVADsAu5QAdrCruBauBbsKSgm7mjqDw65mvINhV7PnXbCrsKuwq7CrsKspBDphV2FXYVdhV2FXYVdhV2FXYVdhV2FXYVdhV2FXYVdhV98Cu5qROq9h07nonKnzCkcLR7s9RzuDjWYDpg0Xv4kp2tiyeSU3G2y3H2B2+XIZbBZsFrYPtu/ns31gs7gWrgU2C8UJNps6g4PNZryDwWaz511gs2CzYLNgs2CzKWRJwWbBZsFmwWbBZsFm3xA2CzkKOQo5CjkKOQo5CjkKOQo5umpw8ibDe8FGheJnPw3d7umMhBJp/wyrr2+6bcf1TddNOFY4VjjWHTjWGLiZAYBVTua73l2ZFGGV++ZdLwq0EmIV2+wHYA3iPuCq4KowdTB1P5+pA1fFtXAtcFXoSXDV1BkcXDXjHQyumj3vAlcFVwVXBVcFV00hwwmuCq4KrnpguCo1KiENIQ0PgDQcGiPDber2J5lmXmmVW7Gpt2KMwsFezl2GpBWZ4g2Whq41VuQJyYHTT8X5YUqxgDRGYcxJLmzFtt6AJh6guq55R5Lnl1P0H66t+u2p47Gu+kcTgWpT021BrP1xZAlb/nGkiJz0wLKfj5WGWFk6k7EYCHRNsUzl0Rg85vuqrRmmKvLYSnzMlQ18N2SYVQ/D8HIc9hehyp1hGqPJyE8QGI5SWtXT2Gy5zWYIwRiZUSz8AwwLDAsMCwwLDAsM+xNg2PCc/z6qHP1yVCoEqjb/s4/Hel/q4SchqpIf/8kdqZpmiFNQh80pc66nTqco0/m5LTQpNCk06bY06RRDmQGeNJgzdvtyeZcUKQ12lzGkdVTpVFxhP3jpXKgCzhTOFBgOGO7nw3BwprgWrgVnCvYIZ5o6g8OZZryD4Uyz511wpnCmcKZwpnCmKYQv4UzhTOFMD4wzpSwqZVEpi7pLWdQ3TWoDAwMDAwOnwWbAwMDAwMDAwMDAwMAphoEDodwvRxeFSA33y1E5rpLzud1AIef9NZTTia/gweDB4MFpxINnedgsEcKuO9wBEBZ7b8oHdzq3+8GDR/5iId4ylDCUMCgjKGM6UEYoYVwL14ISBlqFEk6dwaGEM97BUMLZ8y4oYShhKGEoYSjhFKKzUMJQwlDCUMJQwlDCUMJvgxKmnjP1nA8F4YaPhY+Fj4WPhY+Fj30tPnbaAgO3W9S6Q1fvFr9vBrQut0FRVtIVLT56LS7wsG1bHMkWy6P9tbi/yy17J1fc59kFbT7up0nZ1l5Ob3Z89xqe6aRZs8xe08xdkpu+DYP++RM6GjoaOnp3OtqDgQ8YjhYzKp+r3QyJju2wioKWssxwu2Xkc/DY1TU/QPhkDSejMC9ePJb/C1aKImVuS15NNr+cf1YHg5q4kZ7UNYGaymBg6wNvvmf4ewQT1GAlJyG4nJicx/Lplq0UlUdrYoe7Oe/jU8lFDW8zlVSjdvJhOyfvfezAGhmuq2s5eb7h+fuEWt7RhzJFHyXF/GFW12IwxK/Kg2HqsetQxHJE5v593xrqchroPArpq+1zcsdK7WGmzfgJuJalDGzVnAxVO5xERgfNLZXFrgLM6az0ddaKKc1jbJ3jTVXkT3JW4s9BUCygWACrBqtGsYBr4VrZcS0UCxlDfFEsZIOpRrGQlg5GsZA970KxgGIBxQKKBRQLKcT4USwkuU18CD7hXaI6Xm1MubtYQ7oTJ5HtlzWwByIQQBKSGSEEQgiEEPsQQqAFSLEWIKZq261v/Cpz23aNv/u6nrntVLtF4WWfOt3iXVd8Lftfy97XYvC9GPzw2f/+2ft643+98b7+7n/9PZndPHHglnOem3q7Xb1W3km+x8evlOoP15cOvg+qh281H0rS+Dpz1+pfKrdyjKiJMe6+VZWe4H9odD5XW9uYTWoqX8p2/aEh00DiGIIXexkjLjrKOmu275vNRqsjR4l6o9ONvm9hw2ppNwvmn9ShIallRTWd72LL3rPI4ORdKy8SOQEXuMvcfPtD7WHaGqp8Ew9staby5O2qvKuNn86UJ8HFNJ/OkyaDVze01vuaT2dyWvR0nuwOkSFOwxxUpLW3vE3iy44A1XtUn3RFVYL2/e7c6tZI1vwebgeU9Sjr06CsR274InLDZcXhE8rXLso9Vb8o9B9Kl/p5r68/nJ6f9a4uzwpa77Sn6T3B57+ssjFOJGcHbF1xk32sfexUq/XuXa1+35HatUa92v3cuG/5H28qX/1Pv1erv/kf7xr1zmepPUEKihQUKShS0HRKQXNTA/qcmg4F3aEp6N6qXm6gm7otoNB8qB852kAjt0obFxOILdWadWWzzsnf4QLgn8TyM9+si0RoMfFZ+Ha/XuwFfTu8i2NRc5tI0uLHlmuEseo+rsg/ivNQXe80dHE0b77vWsHLEePPLfmeSrG27j0r3zq3N92bert7V/lUr3Xub6rfopWUHyVUnEkvr6mGkA0tmiL+qnwrlkc+41t8/CZVRrZq+AKZb0Xtm7jSyMV80enarOchXNWy53NF5tEq15+r3c+1jpcm8zJG3odu5fdKqxp9rZaqMs7T/VJttWtyyXXbuBbP3brMaXWuP8tndb39e1Umj1qNTuO6IXIR/3FfbX3tdr425aO62m426u1q99rLGITfO51bmQm68f47bZ5peRWCyEPW2CGIPKDOQhCJIBLVFqqtA1RtIYjEtXAtBJHo8xBEps7gCCIz3sEIIrPnXQgiEUQiiEQQiSAyhSpBBJEIIhFEIohEEIkgEkEkgkgEkQgiEUQiiEQQiSDyEASRQ2NkuE3d/uRzoCuu/lZs6sVko4SrRxbLpG+AH3rBV9caK/I05aLVh138RKAI0Qq61M/qyNCx2NbTpoklqq5r3pHk+eUU/Ydrq3576nisq3YIkYqEsC30IX8cWWLx88eRIt5dMbDs52OlIWK3/ijm3WePxuAx31dtzTBVwe8qcfmcbOC7IROZi+Ek5c4wjdFk5KfgDUcprepobLbcZjN6nBjlVSz8g2YXzS6a3fRrdmeFPivuyJSpyJRvrUr9N5k3lBm+ka6ahjkQ8tzoDlhEzAddlxNeb+uCNLJV8y/H65ipgMxIHZiGK6K0quuRW26g2/tVAlJy8IwNp6IxIV00LUV/eND7K+f1GHRLgy7Hi6f0fZr+oEod1fTP67SGwgrTHDLC9gN8jy5qc9TmqM1Rm6M2z6TaXMiVbUP3XkKctBTKZem8VCroxUJZuzw7LZd6arFYuNSudO3yUi+X5y42OBTvhUXVjqo91J07+afSen27XD13Hw13S3V7vvecl23kHw0378WNV752VbA6MVJkw9ewrhO9z7bKK1gzLmJFcXxAnYXiGMUxskhkkQcoi0RxjGvhWiiOEcCiOE6dwVEcZ7yDURxnz7tQHKM4RnGM4hjFcQpluCiOE9wmYLJgsmnAZJEGIw1GGryLNPhNVxZAF51iXTQlQHiLG7B7GoEVYHdgd2B3YHdg9zjsvnqgqlc/VTq1L9VVLjnzeBA0hG7LZLswyfE0PldYmHpoNtq1Fz/MjFnDY+aiq5x77Ryo/uGi+po+tvW+N6r7b9N6o/B+zBLhJsbAtOywjbUg//Ecrb8K7Q8Be7mR46qGOdQdJx+ciJiahfeWsI3y79CuSic8kve+Mkf58KzcBLG/TR5r6tg4Eandid3XHf8h50x60U9CWuA/JuclBt2n0sl7xTAdV1e14/WKBL+i0/ZyhLAk1EoRgl9ZKHgz224yhGi9F7W8tvATIoWsc++IFA6osxApIFKApIakPkCSGpECroVrIVKAmUekkDqDI1LIeAcjUsiedyFSQKSASAGRAiKFFJL7iBQQKSBSQKSASAGRAiIFRAqIFBApIFJApIBIAZECIgVECogUECnsIFIIXzH6siKF4J2mL3sU792oL3uMVzDXzO2x6C2w0Tti/ffBIr5AfIH4YmfxRSgneCPKi658l/LO+ot8+ErmDZUY4fb7eyVE4rdHI8nIOuWPJOOAOgtJBpIMuHG48QPkxpFk4Fq4FpIMFAJIMlJncCQZGe9gJBnZ8y4kGUgykGQgyUCSkUKdApIMJBlIMpBkIMlAkoEkA0kGkgwkGUgykGQgyUCSgSQDSQaSDCQZu7w3otHptu+bzUarU31pxcTrHGfGuNMXGD8JZAzIGJAx7EvG4FH5b0jMoJf2IGXQS3r+yYumbihm0E0t71p5gTftpGZoV6/zT+rQkE8SRTWd7yIO0HuOHyBwIYFVuRM0DJnH4tEwHFBnoWFAwwBoDWh9gKA1GgZcC9dCwwBSj4YhdQZHw5DxDkbDkD3vQsOAhgENAxoGNAwpBPvRMKBhQMOAhgENAxoGNAxoGNAwoGFAw4CGAQ0DGgY0DGgY0DCgYdhFw1D9VOnUvrz0ayWajXbtxQ8zq14ILi12eHQL6BbQLexNtyA4/jegWjDG3UBosL1qwRhvqlaoNRV/y/29dCHWJkqEjMPtKBEOqLNQIqBEAJcGlz5AXBolAq6Fa6FEAIxHiZA6g6NEyHgHo0TInnehRECJgBIBJQJKhBTi+SgRUCKgRECJgBIBJQJKBJQIKBFQIqBEQImAEgElAkoElAgoEVAi7KBEqDWfzl5YhVBrPp2/pgJBXpJ/WJQHKA9QHuyuPJjC6DOvPJBpWcMcdL2XDOwgPwhaynst5b3XEqyTIgR7+S852J8eYaZh3o+QedAdVcIBdRaqBFQJoNOg0weITqNKwLVwLVQJQPKoElJncFQJGe9gVAnZ8y5UCagSUCWgSkCVkEJUH1UCqgRUCagSUCWgSkCVgCoBVQKqBFQJqBJQJaBKQJWAKgFVAqoE3o+wSJ0QHjMXXSUqBVQKqBR2VynM0PZvQaoQRiS21yjEghorVQnBdvuTIywOaCBKyDrnjijhgDoLUQKiBMhpyOkDJKcRJeBauBaiBBh5RAmpMziihIx3MKKE7HkXogRECYgSECUgSkghqY8oAVECogRECYgSECW8IVECXD5cPlw+XD5cPlw+XD5cPlw+XP4LcfneSuJloXyhUn3hI9y+9DUIve0ragp8ee9tOy7vvW6iK0BXgK5gD7qCGCGfeUGBXJN1vbt3a0mBbCTvelG9laICsc3+BAWyNeQDGSfSkQ8cUGchH0A+AOMM43yAjDPyAVwL10I+AM2OfCB1Bkc+kPEORj6QPe9CPoB8APkA8gHkAylk6pEPIB9APnBg8gEqskN+Q34fAPk9NEaG29RtCUGstsqt2NRbMUbhYA+ykSFpRXIGwdLQtcaKPCE5cPqpOD9MKRaQgi3wY05yYSu29QY08QDVdc07kjy/nKL/cG3Vb08dj3XVP5oIVJuabgsg9o8jS9jyjyNFQCgDy34+VhpiZelMxmIg0DXFMpVHY/CY76u2ZpiqAFeU+JgrG/huyDDr4tSpcmeYxmgy8hMEhqOUVvU0NltusxkAOZaDLhb+QZyAOCF9RAjiBMQJiBMQJyBOiIsTEjrUxWXpvFQq6MVCWbs8Oy2XemqxWLjUrnTt8lIvl+cuFjwePB48PjEeP0V7Zx6QD+bO3b5c5m7NyAftyKDaOkx+KtCyP15+ulnA+Yyz2IDzB9RZgPOA89C90L0HSPcCzuNauBbgPBw34HzqDA44n/EOBpzPnncBzgPOA84DzgPOp5AmB5wHnAecPzBwnrr71N2n7v4udffftPQEdQPqBtQNabAZ6gbUDQeG7aBuQN2AugF1A+oG1A2oG1A3pFrdMMvpvx2Bg+sO96FvEM1sKm/odG73p24Y+esl1XS+67ZsG4lDxql5JA4H1FlIHJA4wGHDYR8gh43EAdfCtZA4QNwjcUidwZE4ZLyDkThkz7uQOCBxQOKAxAGJQwq5fyQOSByQOCBxQOKAxAGJw9uQOPB2Dd6ucSj6E+B+4P6UACvA/cD9wP3A/cD9cbh/9UA1cLtFrTt09W7x+yq3nHlECCJCt2XCXZjleBqhKyxMP4hDPXqH0l7hUCN5qPLoFQ71CpYre5dTfJXrCQ72+MLHkgd52QuafTR5R5y5Q2YtPGuFmXs3N+01wT3wJ7IXZC/IXvYne/HkG1lTvVjjE9VfcW6ib7HGebn5rI5FlBqotPWpuO963YrYS42Sz45MPs+2oYxUiWIoxWP5vyCAIEgKe7l8RVYt2KECRbCCT8LCb93ggtoFPqni1zoIbu5R8LUA+A/4D50MnQz4j2vhWplyLcD/jJGygP/ZQJMB/9PSwYD/2fMuwH/Af8B/wH/A/xTS8ID/SeaJEllPfI94u8l4qj/PcHQ3p5iWVxRXBr49OD14Ksug6//+//6X9+yWMx5vAzEzeReb2uRkEGTRfOK9rJ4zHFrf/abE0nRm/tSX7IxfFFg5Lcq1fsK74vAubv0yfGBZg6FM0kzD+qXyNK1fTDINCoQICW8f1fGKK8vdRQDCnSTromUN7IHKBFKFJkeMghgFMco+xCjoMVKsx4gpC3frm07ndpeu8Xdf1zO3nWq3KLzsU6dbvOuKr2X/a9n7Wgy+F4MfPvvfP3tfb/yvN97X3/2vvyezmyfQ3HLOc1Nvt6vXyjthgbYPRinVH64v33wfvH5iq/lQksbXmbtW/1K5lWNETYxx962q9AT/Q6PzudraxmxS1/pStusPDZlDFMcQJNfLGHHRUdZZs33fbDZaHTlK1BudbvR9CxtWS7tZMP+kDg0JQvt1dqVP6qaWd628yAIGxN4uc/PtD7WHaWuotE48sNWaypO3q/KuNn46U55ENdXm03lSkmB1Q2u9r/l0JqdFT+fJ7hAZHzfMQUVae8vbJL7sCNC2R/VJV1QlaN/vzq1ujWTNI7V7m1K79cqx2XkpSjKUZCjJUJL9DCWZMJxrjaeUY7s61lmxdKaWSmen5w9XhWLpon/xoJb6Z+Wz01Lx6qJcmr8M7wxeVjZztsilXOVBYICJHjtJX55zqumXvfPTs17v7PL8/EIvXarn/fN++bxwWeiXxcgrz/Ctyk0GuqnbAvvLh68GONpIYmKNV4lKpIZigRQjzIYm0GNE+ywSZUT51cTKjGW7IshAkIEgA2ocajxV1DiCDFwL10KQgT4AQUbqDI4gI+MdjCAje96FIANBBoIMBBkIMlKoUkCQgSADQQaCDAQZCDIQZCDIQJCBIANBBoIMBBkIMhBkIMhAkPHWBBm8bpLXTabhdZMIgxAGIQxCGIQwCGHQAQmDLk/V4plWvrzSL66uev2rQrF31e/3Ly8KpXJRK1whDEIY9OLCoEjME1MHSQue2NZE8E0nvsbn5O9wwvjPBmoh2UbebyMf6IRmFUNyK8XfSvH/JpOFwbHW6IY0QwwbvUnwqJ1ucCS27TsBa+3TuboWNb9cPhQ/AzmxHKvu44qklTiA6nono4sjepNE11Jkz8wOpZE3+u9XWpu1SniAZY+dWrP7pdpq1+Q8tFq/bn1tegGUSktmJX6riXDfzZ33VcTG/0RphNIIOQRyCJRGuBaulSnXQmmUMTQfpVE2tBAojdLSwSiNsuddqp2UNHlWKq1r5V1l4j7qpng+i+lVS+/rxpOuKdePqmG+V/y0vB9XSCLXSdr2ukx3s9KWdJ2HQ0nMKhkS8ZcxSo4v/Va7U97dyITmb/qzo9Q0cT0y4nKnGsP4RWwDQWx9hBe31mibG0rGWIKryXt5/Dvvtc5K7F6QHtXSBWHkpfA15doypQOYfX0PNn3B03hpwzvjh8Rmbzc/Ku/auqnpttK0hkb/Wfko5sTfLfuv3a25ResvbaS3i+3oZt9+HnuJnGRX7u8ZdZTyLmxMnrxpufnwl6Tm2KL1dTaKR3IFChd9T2QxWTSrqdvy1fE7FM8a63YQlrbCAl/ypOU8xw/URgF58QQPViRy2iO29ZgTX5jjHUmeX07Rf7i26renjse66h9NhDGk66mm8seR1BX9caSIB+rAsp+PlYaYd/i4pkdNPRqDx3xftTXDVEWqRYljMbKB74ZchOthkEaiMv4URfHLc/nhI8NRSlvXB3vjNltQAs2PQRSnap2B+2QS9wHvAe8B7wHv+Vl4jw8fTCE+4eAUnvPf3vz7l6NS+bhweXZ6LoSBcoL+y1G5cFw8v7w4PRWXr2qaIY6oDptT1pudis1cSnQWL4v5LHjwfFC14HG9xweObtuWvXIMn33wyJXnYrl9/NqCDRfcHrmlj7lNjfmgDp311swFV/fn3uGkquRYWh7HknFMSdrk2Gd2VsFKvnPkn0rraSURkNmSUsr3nvNePGcRrCSCJfFlfEg2JcaUtov8LaaVwHLAcmAHYAfAcnAtXOvgXQssJ2N5bLCcbIADYDlp6WCwnAx6F9QJ1AnUCdQJ1Mmbok5I6ZPSJ6VPSp+UPin9l0rpJ63OUT7tF8sXqnZ6flUoFq6uyvppuaefF8/0wunZ6cPcBZK5P+TMvaaPbb3vjYZ+QYY3n8uP2STcxBiYlh22kSCvfxwlype/pVguZ3/kHVc1zKHuOPngFAzLzIf3l7CK8u8FtlXafgGRD8/KTYCkbvJIUMfGiQjQTOy+7vgPCGfSi37yGIOpnwLgwH/yBOBB96l08l4xTMfVVe14PacgQx47gAp+yGQRqSDDFntEFZKEQSAVIBVIp5JOTUc6FVIB18K1IBVInEMqpM7gkAoZ72BIhex5FwVEgBOAE4ATgBOAE4ATgBOAE4ATgBOAE4ATgBOAE7IIJ/iJ9jdGJ4x2rKMQhAEW8gl3e66lsPdlOxQDFAOpVlKt6Ui1QjHgWrgWFANJdSiG1BkciiHjHQzFkD3vgmKgIAXoAegB6AHoAegB6AHoAegB6AHoAegB6AHoQXrQg9FbrIwQLRd24A/ia45FDML83H9XCGGL1QSIAYgBeVDyoD8/DwpigGvhWiAGZLxBDFJncBCDjHcwiEH2vAvEAMSAshKUlYDtyDTbAakAqQCpAKkAqQCp8FKkwurBKULs5pNaIsaq2zKEJ6534R0SGqBYEJaapvb20OSMeVYQghAUEBQQFHslKOIYwNuiKIxx118P7IJRGOP8U7iyWcRRxJYduwIUUVOwEbARJHBJ4KYjgQsbgWvhWrARpOphI1JncNiIjHcwbET2vAs2AjYCNgI24k2wEVR/oPoDTAVMBUwFTAVMRVqYiqTVH3qnl6f6VeFMu3roFUrlUrFUvtAfrvr9iwutdHVB9QfYBdiF/bILU7n3twUviIXVDtSCty5bhCuI9dEeXzyx6XILoAGggawrWdd0ZF0BGnAtXAuggfw6QEPqDA7QkPEOBmjInncBNAA0ADQcPtDwdusYQClAKUApQClAKUApQCkcKqXAOyqgFKAUXpVS8HLtbwNPEA9HL8zTlaZzTv7WglP+JzGwELXm31CLkQV/c5lgCyJTcnuRj3pWwhPYBmIIGx+JbfuLG5ZpJ3n45RhD/CzkemCsuo/zWQovyeKfkep6J6SLo3lze9fyzmD2iRiNC76fL4vKb3uAZbOHWrP7pdpq1+TyIb5wqrSuj3JHIn4i/rnzvrabH2UVnyguNhjUhEM/qcM1kMdgYOsDb1pk+HsE87hgwSNTfDkxh41FCy1bKSqP1sQOd3Pex2dcixreZsalRu3kw3ZO3vtBVWtkuK6u5eT5hufv59/yjj6UAUjlwbZG/iXJB5+uxUK9vyoPhqnHrkMRs3YZ2fTHuKEuZ0vOo2WLzJ2XBTxWag8zbcZPwLVEj6vmZKja4VwrOmguvqvYfpNINZ2Vws5aUYTrMebQxbKIw8qfiuIRWfw+7bHwWPBYQCNAI/BYuBaudfCuBY+VMYABHisbxAg8Vlo6GB4re94FjwWPBY91+DwWBWaA1oDW9gitDY2R4TZ1+5OfcFthtVuxqTefiIIFXmJbBiyCRJI3cXCtsSJPWs5z/ECtv4gV0wuRvPNXJHLaI7ZV+tbEdBX9R1/XNe9I8vxyiv7DtVW/PXU81lU7zMxNpOuppvLHkSXmVX8cKeKBOrDs52OlIeYdzmQsRjFdUyxTeTQGj/m+amuGqYoUcZTWc35VZAPfDbkIXxxYV+4M0xhNRn74yHCU0qp7AZstt9kMbBbLUBQL/8BVHjZXGU/0ZidfuKLnP9Y+dqrVeveuVr/vSHKuUa92PzfuW/7Hm8pX/9Pv1epv/se7Rr3zWUJWgKiAqICogKjpBFFzUwO6hEJFNGkrKPXisnReKhX0YqGsXZ6dlks9tVgsXGpXunZ5qZfL81CqfyiQ1MNDUgFQB7qp2yK7lw9BoKNE0Okq2HQWmXTyT6UkuKYIY+2KaYoCU144bBGtKWJNsShIDNrcushUouDpJrAmVOIhg25QiQfUWVCJUImgU6BTB4hOQSXiWrgWVCKQHFRi6gwOlZjxDoZKzKB3Ad0B3QHdAd0B3b0p6A6iCaIpJbkGiCaIJogmiCaIph2IpvOL/sWpdnZxViqfn/fVXuGqcPVwUewVL0sl/fKyD9GUIaKJInsvXWRvDmpaRUB5MYEdyu11wqMpUgTj/JTCe3No1vYl+GRUaR9Qlx+eWkR1yRDRnrGuRGEnqK6Mg0JQXQfUWVBdUF2gJ6AnB4ieQHXhWrgWVBeQEVRX6gwO1ZXxDobqyp53UWsOkAuQC5ALkAuQC5ALkAuQC5ALkAuQC5ALkAuQC5ALkGshyOXTRpBcMZJrtK/6XEHIZSHLdfcCNbr2HyaB+Mo4RATxdUCdBfEF8QWWApZygFgKxBeuhWtBfAEgQXylzuAQXxnvYIiv7HkXxBeFzsC0wLTAtMC0wLTAtMC0wLTAtMC0wLTAtMC0wLQyhWmNqLg1y2lFK7J9sFrx9d0iXmt+nbUPYCvh6g0cK+uEDzjWAXUWOBY4FswIzMgBMiPgWLgWrgWOBR0EjpU6g4NjZbyDwbGy513gWOBYlCujXBkcXKY5OKguqK6UpBaguqC6oLqguqC64lTX6oEqYrlX+OTM80EErnVbxkWFTY6nM52FhavEaW78JY81Y9wV8Dp8GnwafNqL8GlxegpGLWLUjHHXX6TtBVIzxvmncN25iFKLLQr3gafFmoM8yzjMBHl2QJ0FeQZ5Bh4DHnOAeAzkGa6Fa0GeAUJBnqXO4JBnGe9gyLPseRfkGeQZ5Bnk2Zsgz6hDRh0yiLUDTUlArEGsQaxBrEGsbU6sSVL9ZWE1ScG/IqM2Bd9DpUGlQaW9CJU2hUuBpUVYmlhp74NH81bsi0A0sXLe88stN16Mg6plnH4CVTugzgJVA1WDp4GnOUCeBlQN18K1QNUgp0DVUmdwULWMdzCoWva8C1QNVA1U7fBRtbdb/wv+DP4M/uxA8wzwZ/Bn8GfwZ/BnvAcTogui6+CILg84ensoV3DTnfis1cnfWnDO/2xMcgWN5ANgazG6FWym+H8Uq6vwaNvQW1GLI7Fx3wkyg34uSQAsQfvLka34KciV1Fh1H+fzO36T3umornc2ujiitypyBcliTcazj8ZoWPDdfFk+Y9sDLJtGtJuVOzFrqNzWrmuNezFVaDcbjY9HuaPO51a10uleVzrVT42WmH5XWtdHuSMRjRL/3Hlf20258W27+6XaatcadcgZyBnS+6T3IWdwLVwrY64FOZOxVDPkTDZy+5AzaelgyJnseRfkDOQM5MzhkzMUedrASO7Q2ZYv6ty2Ay4ooR1m9lx3jZ3b9lNRZrW8T8XwUyn8dJrssofGyHCbui0j86uv/FZs6j0ao3WvlxKSa+8gBus9A11rrMgLkI9sP+YYRZ+lOtmfXMsnuNhW6VsT01X0H31d17wjyfPLKfoP11b99tTxWFf9o4kVubyLVFP548gSU4Q/jhTxbBhY9vOx0hCPUGcyFg6pa4plKo/G4DHfV23NMFWRXIni4M6vimzguyHXk4vVlcqdYRqjyciPhBiOUlrV59hsuc1mgI1Y4rBY+AeY67BhLtgk2CTYJNikdLJJHg8kU+2L62GF5/y3N5X85ahUPi5cnp2en4u+E3PNX47KhePi+eXF6am4fFXTDHFEddicst6aulTRWYAqHR6qtG8wqR20dzhk0kA3dVvkYfJhsZOjzWik0Hir4CPPPfJPpQ0AHRFe2BbMEaWVvPDEIj5HrP3jq9IQ5tmurFLiQNZiPAfKBMqEVDipcCgTXAvXOnjXgjLJWFoWyiQbeXAok7R0MJRJBr0LiAKIAogCiOJwIQoy1GSoyVCToSZDTYb6pTLUCZ3osnzaL5YvVO30/KpQLFxdlfXTck8/L57phdOz04f5ihkkog84Ef3yNTMOMDW9n6IZgSGPo6zv0nS1tzbbolZGYF2l7ReAeI0SGWECPaiREYwBSStjyCX8Lpl3PwawKPUu1+F7zL0nWdeTeif1Tn6Q/GA68oOk3nEtXIvUO5lgUu+pMzip94x3MKn37HkXBR7ItpNtJ9tOtp1sO9l2su1k28m2k20n2062nWz7AWTb/azx20u3j3ZVugfr2oUJ97s9q933vg4lLU9antwhucN05A5Jy+NauBZpebLEpOVTZ3DS8hnvYNLy2fMu0vKUDCCXTi6dXDq5dHLp5NLJpZNLJ5dOLp1cOrn0F8ulj96odl2MZ30RV98poR61sjipHv5d6Q9VxxGx8f0k15c1TI6cHDmJPBJ56UjkkSPHtXAtcuSkbMmRp87g5Mgz3sHkyLPnXeTIyZEj9EfoD5wAnACcAJwAnACcAJwAnLDri9+nLXBXua1d1xr37QUZLRFg1W0ZvxPXu/AOCQ1QLAhL1Rud7l6bnDFP1Pbssf4EmgCaAJrYMzQRz/q/OXDCGau7Ff2XDSzGJcSftiMlhJOLBe4sJ7GoxXfyxyfnWDEtU57Oe7AJsAlyu+R205HbBZvAtXAtsAmy+GATqTM42ETGOxhsInveBTYBNgE2ATYBNgE2ATYBNgE2ATYBNgE2sV9sQrAH7Wblbj/UxL5amjGKbDYXnSuIBIgEiMS+EQk/yf8G6YiHHeGIhyVshFho7fHtDJuu2yAjICNI35K+TUf6FjIC18K1ICNI1ENGpM7gkBEZ72DIiOx5F2QEZARkxOGTEST9SfqT9CfpT9KfpD9Jf17kQMKdhPvbSrg/vM18u2XtmnEXLSyrR2BZD/suSLCgyXfer1FJAst6oCYBmXfSg6QHU5IeJPOOa+FaZN5JBJN5T53BybxnvIPJvGfPu8i8k3kn8374mXdqEoAngCeAJ4AngCeAJ4AnpLEmQaPxcV9FCfbU1FxVAtFuLna61CUAkwCT2D8m4WX73xwo4T7auup2hbEHlv28EzLhtZUP21oMT3hbKcFWO1csmG5PhM0AJAAkyOKSxU1FFhdAAtfCtQAkyNcDSKTO4AASGe9gAInseReABIAEgASABIAEgASABIAEgASABIAEgMR+AYkPtmpqtZG4XyxzyY26DSlxbety2qsOP6v2k+64ur2fhr3ZtPt8o4vbeG/ne2uYf70A2DF/tv6hcossv9hsoCCgIKAg+0ZB5imGtweFDJ2uv/7ZDQgZOvmncPW2CAaJrbR2BkFmVm0gICAg5KnJU//8PDUICK6Fa4GAQCSAgKTO4CAgGe9gEJDseRcICAgICAgIyJtAQGAhYCFgIWAhYCFgIX4OCyEyS8XjBWP3NkCB11hxn42V9tnY6QvQDoEBo6uPTj06LjwDPAM8w955hqkk/JthGcT8wgsRdaUZnZO/teCk/0lONUTN+XfXkjeDBLYS2wdxLbmDyGY9K+EpbEM5RK2PxMb9xS3LrJU8/nIKIn4aclU1Vt3H+SSHl6PxT0l1vTPSxdG8FZJreWcwO6+Ixgnf75cF9bc9wLI5WLtZuRNTrspt7brWuBfzrKCCUudzq1rpdK8rneqnRuvrUe6o0ro+yh2JkIz458772m5+9J5I3S/VVrvWqMunUhR4GwxqYgR4UodrKJLBwNYH3vTT8PcI5svBwlLmEHNirRALR1q2UlQerYkd7ua8j89sFzW8zcxWjdrJh+2cvPejttbIcF1dy8nzDc/fT/DlHX0oI5zKg22N/EuSj0pdi8WSf1UeDFOPXYciVkcydOoPikNdzkqdR8sWqUEvzXis1B5m2oyfgGuJe0I1J0PVDue00UFz8V3F9puEwumsFHbWignmY8zli2UR6JU/FcUztfh92mMBvgC+oFKgUgC+cC1c6+BdC+ArY4QEwFc2kBSAr7R0MMBX9rwL4AvgC+AL4OtNAF9vtObP0BgZblO3P/n5pRVXfis29R6N0brXy+rKtXeQNfGega41VuQFyEe2H3P012PiSSlSVf7kWj7BxbZK35qYrqL/6Ou65h1Jnl9O0X+4tuq3p47HumqHaaiJvItUU/njyBJThD+OwjLvx0pDPEKdyVg4pK4plqk8GoPHfF+1NcNURXo0ymE5vyqyge+GXE8ujhErd4ZpjCYjPxJiOEppVZ9js+U2m+HTYsH2YuEfUMzDRjHjOcvspL5W9PzH2sdOtVrv3tXq9x0J2zXq1e7nxn3L/3hT+ep/+r1a/c3/eNeodz5Lwgh2FXYVdhV2NZ3sam5qQJdEpAiMeBxrQoe6uCydl0oFvVgoa5dnp+VSTy0WC5fala5dXurl8tzFBoeCxzw8HhP68migm7otMlX5EGo5SkZcriQtZxhBJ/9USkQoiqDMzmSiKLzkRXcWAYoidBJb1Mcwxa3rLiWKBW5CJwLZHTK3BWR3QJ0FZAdkBwkECXSAJBCQHa6FawHZwXwB2aXO4EB2Ge9gILsMehcMGQwZDBkM2eEyZAA6ADopCZsD6ADoAOgA6ADo7ADonF/0L061s4uzUvn8vK/2CleFq4eLYq94WSrpl5d9AJ0MAToUTHv5gmlzjM4qoMdb4O5SMq0THk6Rsg7n5xRPm0ONdiijJqMke6GU/HjLIkxJxjz2zCkliqOAKWWcfAFTOqDOAlMCU4KlgKU4QJYCTAnXwrXAlKBmwJRSZ3AwpYx3MJhS9ryLWmCQSZBJkEmQSZBJkEmQSZBJkEmQSZBJkEmQSZBJb4NM8tEZ0KRpNGm0twpKQQxhIZx09wJVlPa/7gdhyjgVA8J0QJ0FwgTCBGcBZ3GAnAUIE66Fa4EwQdSAMKXO4CBMGe9gEKbseRcIE6Wo4I7gjuCO4I7gjuCO4I7gjuCO4I7gjuCO4I7SzB2NqIm0ADwSI2BfpC72Ax9FzS0GkMK/K/2h6jgiD7E/EGlp4/BEGUdU4IkOqLPgieCJgB6AHg4QeoAnwrVwLXgi8BZ4otQZHJ4o4x0MT5Q974IngieigBQFpAC5ALkAuQC5ALkAuQC5ALkAuV4R5Fo9UN1VbmvXtcZ9e5VPzjwfRNRat2VQVNjkeDrNWVi4RKw3Ot3XOdaMcaODzp7EnyBpIGkgaS+EpMVhKbC0KSzNGat7elWfbGkxjCb+9BIc2qJ238kfn5xjxbRMeVLvwdKyTjqBpR1QZ4GlgaXBzsDOHCA7A5aGa+FaYGlQUmBpqTM4WFrGOxgsLXveBZYGlgaWBpYGlgaWBpYGlgaWBpYGlgaWBpaWGixNkFrtZuXuham0Fz/EjEnl8XLR1YGggaCBoL0UgubTUdBnM/TZw77gs4cl7JlYBu/5PYwbr6zhzjKOMsGdHVBnwZ3BnQHHAMccIBwDd4Zr4VpwZ2BQcGepMzjcWcY7GO4se94FdwZ3Bnd2+NwZSBVIFUgVSBVIFUgVSBVIVVqQKl7ZCJwEnHQwcNIDbNI8m2RZe6OTRFPLamNZ1sPLFMda0PA779eoPJZlPVAfK/PoC5zSAXUWnBKcEjAFMMUBwhRwSrgWrgWnBDYDp5Q6g8MpZbyD4ZSy511wSnBKcEqHzylRHwuYC5gLmCvleQVgLmAuYC5gLmCupPWxGo2PL14g66WPMVchSxwwF7tAamSBoYGhvRyG5mFSgGhTIJr7aOuq2xWdMrDs5/0gaV6j+bDRxXCat5USbLUXLm22TeCzjPNMwGcH1FnAZ8BnEDIQMgdIyACf4Vq4FvAZLBTwWeoMDnyW8Q4GPsuedwGfAZ8BnwGfAZ8BnwGfAZ8BnwGfAZ8BnwGfpQY++2CrplYbiXvHMsOb9gUptGtbl4sJdfhZtZ9E8tV+4SN6ixf3+UYXTvDyV3hrmH+9JmY3f33+OeQW9e7iHgDMA8wDzHspMG8eFgPRm0b0hk7XX8buCc8bOvmncDW+CM2LrZz3guXF2wPJyzjlBZJ3QJ0FkgeSBzcEN3SA3BBIHq6Fa4HkQYiB5KXO4CB5Ge9gkLzseRdIHkgeSB5I3ptA8mDTYNNSEmCHTYNNg02DTYNN25xNEyn14nFhlUfuAdfyjlJ8laOUXuUop69JnwWdFBkyutjohODL4Mvgy16ML5uind42W2aNT9yh5myBkVnjvNhT4GO+qZw5dsy1xkrn9kYueD2OzN9UebKGE/lkXYWPxXeP8oxTDTnLmbGhMTLWrGZvxSbesaL2vVHBCZehSQCUrRucmYeLUccPD98ZpjESEznPLUbB1wK0DbQNSABIALQNroVrZcq1oG0ylp6GtskGDwBtk5YOhrbJnndB20DbQNtA27wJ2uaNFsByh9p1JOxOet034Ys8El/49K7LU8HXt5V2u3Ydy59Hv1w37uud1tdppSPY1AFiU+spIHMylOrbWE4LKggqCCoIKujVqSBhONcad1fCPUmt0LdGx1OGWM+6rKgNUNjVSN71vSzgcrbIYV3lQcTaEz3UEg5iF6eaftk7Pz3r9c4uz88v9NKlet4/75fPC5eFflmM6/IMAUOOBrqp2yLMng/rXxwlhUGs8bGEGlYwIAJ2WI9FnAjP7Ivkw8nf4cd/doQlgnY2oSWCbZX+UHUckVkIholNuQm/5E6wv66JaFPUrmWLlNByiCJ+tnJ+O1bdx7nD3y05T9Fu5Jk+/LRkeruqjeXjzl3ltnZda9y3Y0+2+G/iZarR96l5O3wIfAh8CElsktjwIbgWrnVArgUfkrGEKnxINjLY8CFp6WD4kOx5F3wIfAh8CHwIfAh8CHwIfAh8CHwIfAh8CHwIfAh8CHxIQj7kOA437EqKOGN1dPK3+O+OfIhoYgM0RGy2ZypENrkOCPFPbzkL0p4/sSQYyJLdl48s7WblLvbY8r8K7kN+BPkA+QD5IC9NXhrkA9fCtQ7VtUA+MpYjBfnIRlIa5CMtHQzykT3vAvkA+QD5APkA+QD5APkA+QD5APkA+QD5APkA+QD5APlIinz4+MLutIdlPQjcw7IeduY9LOthI+DDsh72TnyINtcjH94ZrmI+5s8tGfSxeP9V1Eej8XEK+/C+e9yH+Az4AfgB+EF2muw04AeuhWsdqmsBfmQsUwr4kY3UNOBHWjoY8CN73gX4AfgB+AH4AfgB+AH4AfgB+AH4AfgB+AH4AfgB+AH4kRz88CCGjckP0zWE/5yojvdYX0d4+NvnVcfMDw3HnUI6bg3HlZkD0xqJ9IXz7EhXXc5vqIpoRDym5ndbjmq8Jc7Benhw9HVJjL+MIBnmZWN0bcFJ+mGuB93tP4qV88yjZmnAfh+NLzCCP5wVll246iRfJlaim6gtb6JjpS1P+lmxTF2krEbiLOc2U+ryghzlXaVdd96L8KQqopwjNR8kXzV5pyYNp73G+ax4RF2c5S6uSqWjKUjICqmqZMYNdoyuQTUVdTh+VPOl8I9K39JW+tHODS+/XPkqpJH641bmk49+KclbK/w25VW2ptsf1qzH2/797seqxaDVF3NXubP8TfSO0lu5Mk/UyOy1afqDKheLR5V2PTaT9b41G837WzHNrLM8f/XlefDA3Gxuqv6lzk9N/8nJQS76fcHweFE8+0dc28R07efVs9tPH46iTetrJ8P3piFGkd8Mc6BZI7GryO6MxNAipkPOehPMbz+zDLVcdaiEWwlczl7zNLg8L1xdyYnh+tl8ZTwe6krN7Ms5vWUPFl/zP7mj73rPERO9lc0FK8/v378fixvIW206k7GINJ/4cxIZKz1ZNvH3HllBZ033xZx5168P5C32QuuCBX71QdWCJN8e/Um3bctO4CkjL+K/oB9nri3YcIEdc0u9eFNjPqhDZ701c8HV/bn31czclMDJ+orGX1kcy7t+xQpGrjqWLWFO/lYdcyNUPb6Q6T3nDW0OTq+0Fc03oJjKyUfuKg7d9x3BnM+uZRTDS1B5s5x3lXhcUoYWlZ4+tL4r38rfgkimtziyvvt/F+B4tI+/zHBt9UGgVzIgnFe8uMrQJ7geVcH3iZl5X504c/FPVXHExoo6EoOUDBT6rT3Y1uhEBu4MR6m03x8rTWs8GXqzsGAQc8R0VJfbKpVmvXatvLOD2F4wkg7VnnOsjk2jf2zq7sn/M/4f5dL5++XLutiMfzF/b5iD4fLZspwsy7my/2BJxOZv0fbyx1jx4owJ2etPyDbYaNd5WOCCt0FKYvku5bc3ccuFq8sET/x1Z1OdPg/BIEdLxtVueH5RLMROqiLWlKU11m0fxfbYuDfarhgU5/NG8XbmTmT9FDAy5597nhNLJthLHr3wEkYMhovu0Z3vufPy6Vl5I7NcWwPddPPFi7NVU/eFM0nHmtj9BcmClj4wLFMdKjUxWTJ1VxG/OO66ZHur1qy+5ppk2WpkdiiL7ojwmoMFTXCq0Q01v5hZsHYhpcEi4KUWAavSGN4a4ER1uo63BlizFBD75FUn74XZp9cAtVZLqbTz7WpHzPFVoW8Q6wIhkFBGuh8EX7EuiAYHayJxtWCQWN/q9vPkWHplOJw+kFg1DIwnfcnxNp0tb3+E5aP5KTPmV58xCw9JEsV0ul5nOl35MFnwFJ9Kj1XafueHuI13qyzgbXL+2SQ9gGgu+UEmY8e1dXW04WFsMaKLjJ0S7Bjc80sOYnb7lql3HeO/F8wcptuemMZ/TfwkwNT5O7HDatZ30zvwwgM+Grqt2v1Hodbq+vOx+WNW2sFhH6zh0PouhqP4noE1/YnD/GEM80G3bV1bfohgi9ixfAJpRZ8Ytt31ZhyLpoWPuhyE/Q2WNTd3487HDoNZ4oLOENKEJQ1H89yxrouPWm8TC0t1gTBw09vr5oPoTcvW1qNm4YR0xhWWeMi0/WZvvqV3/MK5rniaLOiDpvjZC/VEJvJGe09IqE+P+q5QaDqhr8Ru5OHzii5b1nczeywIk3vDWHD+RMyJmDNZjk2W/bntmvmy7cWzNpks23K9OBstz3uRak9sbJnOo+BG1kbOF+4nUUhvPDF1V0gWVtBASafDdceTuPnCNzvfnziuNfIkzf4oP3MVoTI7GOPqu8yW93YCG06mVccsrZ5KTycyKu3pzpATrXrJOwkxX9X7bkD2Tp3PegPs1Pz8g5P1ws9QJCSMm/TLl+XLh+LDVfFcvSoVL8/O9ULvvFi+Uh/OLgrqhR+NTLQOMYsLYo7e1LvYXRp0DzZYHDD0/lpa2nBpXcOl5Q3bU8mCJc9neVkz1xA/41zgyVMnEz+0d6D1YWVp7pcFj5kuMV06zOmScKGlc6We5Zq623UfbV11uw+6l0FZO2nKe/vlvf3ycr8FvIGtmn8Z5kBOm7w9FG8PReyhqH3XeBIWWAVUizZ8OlQ+Wuf6WfGktZYMNhi2qDbjxKmCGCjwwTuHjncOH3VdO1ZawTn2VVM88hzLlhV+RF20B910RCUgSRTYsRBAT9WUWtM5VhrylCWlEBbAEcV+wpI3soSBaymOLisZ/KX0H2XRGmhw/S3T4B44u/rC70K4Vt44G8C5y/dYTuLW7+8+VFvdxsdu4+PHav1GyMFqzXZsgid/b1e7UjsrBNNL9piCdsV9v/ryOkGBD1mny3N45d3Xr1+/5u/u8jc3ijcJfn+s1B5k1auwh3L+LekzyJasztGXVbKC4dMTQip1y9V/UTqC/DGcqKSI138i6ah8Vx3FG35FZQylE/3FiP3BixbFqCelbw2HsppGFEiK+fyzV4crJ38vFUrn+UIpXzpVdDHFEeSTqxqm44FOcv9wm9LKymzYbLnNVqo/p9LQwY6Fs6lFlz+A32xWf7K1oCKeWObHBvl4YRn/2v44Kmp/HIl/L/x/TwvaH0crO33/R1qeob/QEFfMiivSqdxRmrb+YPzwyxvlZQ0++fDV/OyL9JFQqTxVyO+bQEdyyulp+fxbsFN0+h4E2Zab9CZhUHxuA7F76gRE6THL5qmcpVVYLNttCF3NmgmSGHml/mblTGdqq2XBnEpbVMm4qbav0eD8hAS2nixqtBpUOyuebiy2ua4fbUaefa7VK/VqJ/+hcv3bB1E5R6z5VfOvNcycv9X140xxiQXb5kuL4KvcPAAmD7swmhFE9labO/a8X33R3nyhmC9ddgqFX+T///PIr5axyZ5ipjG9pyvowNVmKBcWFSE4CvZdQKjpxMCIgREDWxQDWxCuWhoSM8YbhMDm9DbjNXqbWlNRNc327oA9yG6iqFfU8qspW+TVrpgJxE4pQV5xeq9oEL08lv+T5YqeGw/yRMLFnTF+OluAt0xvcT6/BbObbApa0KegT3mD+pSfoUhBehLmqH2hyXJ9SShBQWiC0OQnToSN8cKJb7I574LJbjR3Cya9q1Qk0cZxITnTTaab+5tuerd0kinpoopT5eL5lf/UvQ1yIRvMZ1Rng6nMp0bj023V37yxbO4wtYdlCVX/7e21FBqMV28d3Mhy06BS9co9as2ns/h0bJN5dOKpWziRnnlweV4+jkpqx5JPM/M67zkbGHm6d6asOfd4NcY8XXd9utaab+Rpuo1ic2pBtukDNdpprvxk/E/rq06GW4MXvWm8aJ95+4V5VlnidFHWPel7HfZzwFXP49x1ZYppsOVyc4uXiw6Sv60h2mn5Gd4ZmjbUlaoqq8/GkIRiYapPnUlvy1MP90x49lP7Lb+AtiXeZmKbSnUiZlcrL0I8BQ3xTEt8EeGe21Aj8zsvv5zqfTwfLl5PXBGsiPy5XhEl0kWKvF0hQf7qc/otop3qBjHIykcvIBzcmqs39gKWqmu4E20vVdfF9NYc7LG5DeKWD4NH1TQcVzW94ORg7Ww/PkzJGXRvk73CsaHiGOqywFo4rMWHuPhIEVo7bqpc0LdJw7pkxt9cZvw2ugHexMrlOL5sSF56Mtz75O/gY6IilMFOIjPuO+lswDCcw60PF05nxcMdD7YGZXAFKxLss/P3hULg4KYO58XB3GbTCOjSBvaCzTIjesUZ0QaxziQToaRVIZk5HeTMab6v5wKm4Q1G2JQ5yAvMQWbiqAPdShJBndp8Lnb6afqv68On8eaO47vLmkqhRFT8OjT+21OJOrqpeS9uVb5V+uIlbvlb1RxM1IH+Tfnc6TSVR13VgvdQq8qH66ZydqEM/W0UVx0Ekp3Z/X9Rxm6+2fn23tNYPUyGQ+W/Jqrom7x8KZdQ/ximUF35IIOuhW3JXXNj99f/+h+F46ucbsoPl99WzToIDWc/NDzQrZqWOPoW84xNIrWfdKsuPaZ2kzQgvOORlj9QT4tXhXLhKnd6Xji/vHoxmVvWwuVM419hGj/72NssuNO3tDWz1WYnXyyKSafn9au1KqXzi0L5/CXm6H11uKCt4Eko/yxvTsEkauF7Qwczz1+xmjadYeCpyw8rH30/ZXVwazg9Sy4MhLLI3KDn6UP6kD58uT70tllUR0H8JSiTGp90rHi+XDfqnVq9KqtgBG+Szx1Vbu6K8wvnYJ4VLz+7ZD3+54GcZ+gRh3fCa1NEU09gskRvMks0FS/IdpBmJnCycYoovt/J3wPd6hraJqmh2H75KOMznRKKx1uSZoXi+04lht5cEMfrk5WJo7hNajfHSivQg/47WE3/+S7Qy4hS7UNL1cQdI+13bNmDE/2HlM1ok9H4xNZVbaQfuz/c9wlyTy95DmtjACsRJRa8r7vgZX59yPNr1kj0IX348/vwEJZjh7dsPLwTXr6sJYPP+nDv68OZ9L2YsZ/4q7qTvzVjpJvOhvCg2DUfLAhnl4ZyCeav9sQ6Sf5NLNzCQ6xZKWqinoDRm8jB3XqYabD3PJOIDZtdvs6KH3nFO579Jr2zkEdVXe9MdHFYb+rvWorsg9n07sZve97pKMsGKzks5Y4qzVq306p8/Fi7DrQQHxqd7vVtpS0/txq/t6ut6FP3Y+WudvtVjnD1TrXe6Xa+NquyquCX2nU1+CbOsttsNTqN68Zt8P1LtdWuySVNLf7ltnFd6XgfG+KYzUa70/2P+0q9c393lDvq3LbDjadEGf7QuWIhVxGBMXFDeLEBOR9wLWWo9vShd0/otrBrAqJhhyaXReuiB/5INcyu18C8yHxFKUlts6K2CyVM89Vng2iJ93rE/sQWDx/FNUZ6zouQ6Gr/UfGiG2Pb0iZ9ubkS5Kh9Exwr946ufPu/zP9b+yZnYZr67CjvxB1qKd9Oz8+0b+9FTVCxxXdvi++6/le0Sbn0XcRVKoLK1ZRv4kljW8NvXnVk6dvyBIUXPalDcY5hveGxbhuWN/eLauf+4l1PVEv3u2Fq1ncZm3k0HmRdeLX/VzBeBBfubfV/OMpQRhQUWzz6RIWVsVcM/vujNYzjLfIicooj3ium/KXrAQci5pzib6IWsjo0BuZI1mc2NUWzdEfWc7aedHuojhcc3osZKd8utNAMfbG141k1XzwTJ5O/yCnfioUl25S8bYpn72cqo45VxxFNf5NnEz+Ga0WF7wXcLM4/er1PaG7x87FSGQ6Du380kRWoHWv4pAdvx5EG0Ca2DyX7papFcMzb6dfoZpT3oaO884qwirsr7P33iqO6hvPgM9uiipoIBvbFE9C74+Tv4agu7jBHD0tliwm6antmF3eVJrnxd9/Ev23xF98G4nvV1L5FDTkrqzjjWrgWrrWTa61/PF5oiZ+K8sBrOEB51v5KL/JVYXRRsMozm3Ca8Cn77dfgbWiKaw10AXL7FamDaztWfn/UzcCXhJVjvuH1SU7Rn3T7eZduPVaqYriIWfgksq7hKA9Dy7K9+YkkMHXVFp5dLCsjw5yI3vEBRF2MOPIo0rk8v3CE+znRCTjee0IVyxw+BztGzjZSn72w9v8r3wGwko3E4C9j8GUeNPWuhLx42iT2o6q5hiqtmtp8l/rDjMB232/dvZ6h6eAVHoXxD9e7eP8E75/4Ke+feFUs3oPTV5kvDEiutuF9O9fsLLOfGBbu26sM2Oy8ApKfrovd/U7ZQ1mX/ZovbHaN/ar3uXplmf2q96tsV69sW4TmQC9199tkO+3Rpx0UQasMJ89mjdH8JLUvGlrlaP6WyjsvJ/t+lT3LxdLl+eml8q6uf1e+WvZfSSNHb8Uku99y6tjoeEUYks+hmrWwgEN/qDqOCGH4No//TbwoTxOqV5k66j0rgsoSc4l/3d2G4X3FT4PKrLEj3tugPZvqyOgr70zLzPfV/qMuMnPvp1NTx6K4uJhJu4Z4Q18Y/fnWs63vjm5/VEfG8PlbTvmm6U9GX+88j3XxTWTTmrblWn1rGHz3K2uKr0b8i+V8y3mBF3foBL8rD55BTsI8l+PP8R3dzYVmEjClPz9WHia2XBt4e3qmCO7SXDRM5YRp5idiCSdy9M3r9s3S2FuQLGzWRH20Rr0rPv2ZZH3Ts9xr0YWJHbRnuV7nx/HRD8GPUwSpKG4gMs/OcT+s2SIrwHt5675lCmhXvg857+99knRQfo3TWdcNt7Xfqrdfu5X7TuOu0qneiOSp99Pn+7tKPVnH+G7R8ciT5PO6wKUUUXtnYNnPaRpBfs4Jruu/z507kQyv3VU+VUWm2wd8/2flS6V93ao1JTgk8+7N20qt3u1U/yV++tiod8SP/5J7f63If77UbqoNkbK/v6mJf+8qrd9uGr+L9m4a1/d3VW+fD7V6RWJI7WqrVrmt/WeYau98rraS3THRQJf4hvF2ld2RsCdn9lxn4ptq+7dOoykM0vhQu61ud6XxQTzxtcrHyNjfW3knvz45x/L3dtJhZ31j62+6TtMnMNrJrRAV7N7CCE/ezttccmzXTS7wqehf4lMp+HCa7GKNrS+1Fp6t8q42fjqT/VNrPp0n7evVDa0zgyzvLtCap/NkV24lfzb7mJc58N9dlvBCF+2+7vJ+r9VvGr+35Uh33Wj/S1yqxIUq9ZtWoyaehdefW427qvzxtla/F5u07yqtTrfzJZlFotlYYst0bttb3vYze66zR+e2/VTsFjxA6qnYLYafSuGnU//Tf9zXrpNZQBaLaer2Jwk+bl80RrxeysfSvKi9a40VeS1yRu1TUhGaJ8LnQTpQPqzFtop8I49Yiuq65h1Jnl9O0X+4tuq3J6r3qf7RBENgCkWXaip/HFniqf7HUWwe0BBP/EiQZZnKozF4zPdVWzNMqd6KIEHnV0U28N1wgveke4SE4UT5AcUvS+OzG4ajlLaui/PGbba86k0RJddrK7mCd+1On9ud7qqyhGYgrpjnTZeKTIKKdDXzwVp/fNU0LXd95ZSEcHmv/HDa04qXZ4Wzq0Kvf3Z58fCgP1yelc8vLgsXvaIcGodBecTpa296yVJHuIlfedSnjh+t78po0n+M1x2dqSHq+66w3YJbfa46nzyD3JQR/vTfTNyaedXyziZR1f6VdqGpxZKml0/1q6viWenhUu9rp1eXJb3smUR13PuxFrzqbkY0YYx0x1VH4yAVLbaWlyogoYncbZGPLMifCnWMLM1q/HcoIpzVIMT+rHjUuiIdIkoQhyHOaL2+aLdtVu5TZze1dp9z/Wa1dV2tdyqfxFLkrlYvdO8q//I++p9ald+7Xyq393JJGG3evf5cqcu9Wo3b21r9U7fypdry2ml8qbZuK81m9aY71X5LrO7kPTIxDXfBawLvdNWZ2LrMcctNVrjwmrIC6/VL/6foSDm4r94uCLktq4PpNbG+ykMcg54ZaGZvqOl7OTCXp6GR8oNuYdHgFJ7z30fXj7Yln0PlwnHx/PLiVEy2Phq2/mD9EPq38nHh8uz0XCrgVE0zXPkWxOaUCWfnYzPXE50Kb/5+y5Ur5Ao+24okMQKvUiL5rpB/Ki0VJPUstyujqQnlSKKMeRiJXaNNiseBlUjOlESbJA7lWUjMoqebFxoe3ZwYpq48TkaqGSQ6cgJJCRIhXlwymlgcK18Mx3CVncLP8jEg6ZiN3tmI9AbpDfoA9AFIb3AtXOvgXQvpTcZYdaQ32RAHIL1JSwcjvcmedyG9QXqD9AbpDdKbFOpRkN4gvUF6k17pDTAwMDAwMDAwMHDmYeApxVtyHZe3t/Igd0+quprbeZ0pvH4/yh1VbyQS9bHWqn5syO6vfKy0EqrXgEyBTIFMgUyBTIFMXwsynbZAz3IXoFBbvG9AEmX7aGrGIF67OXmicxXqQVgPGWHV9LGt972R2K9R/lah1pgpwk2MgWnZYRvrAdfjiBhdCrrGSdQfecdVDXOoO04+OL54xVp4TwmTKP+O7Km0/dr5H56Vm0CLtcmTRx0bJyJlOLH7uuM/h5xJL/pJkrb+oywgbrtPpZP3imE6rq5qx0u5XC9m0w3etJGQzPX2zvvvx1jD5sbCQ1vSudNNRpxu71kZWT1DBOo03fnLtcZe4Q6pcgsqizz4J+AAzgLOQvdB96WD7gOcxbVwLcBZOE7A2dQZHHA24x0MOJs97wKcBZwFnAWcBZxNIU0KOAs4CzibXnCWgtgpLYgN5wvnC+cL5wvnC+cL5wvnC+cL5wvnC+f7Opyvj5Xth/X1WLX9tCURtxfghoMLDs82OBQQMRAxEPEuEPE0NJsNjFh86QYxkS1AYvl9HIV31qDE4ocTGT7ZC0m8UVAHZBhkGK4RrvHnc40gw7gWrgUyDMEKMpw6g4MMZ7yDQYaz510gwyDDIMMgwyDDKeRoQYZBhkGGQYZBhhMiw2+rCDJYMFgwWDBYMFgwWDBYMFgwWDBYMFjwy2LB4rbZD8crb8AX4HjlGQbNw+7C7sLu7sLuznKqGaJ3/RXNtvDuU7gM24DdDVfP+6R3Y0syWF1YXYBCgMKfDxTC6uJauBasLugorG7qDA6rm/EOhtXNnnfB6sLqwurC6sLqphBghdWF1YXVhdWF1YXVpZAxEC8QLxAvEC8QLxAvEC8QLxAvEG/6IF5ZTLJ4/GM/IK9srbTHtk5fgAoOLzk83/BgMMIwwjDCOzPCEQ6bDUTY2AUQNhLgwbW9w8E10GDQYPhF+MWU8YugwbgWrgUaDKkKGpw6g4MGZ7yDQYOz512gwaDBoMGgwaDBKeRlQYNBg0GDQYNBg0GDQYMpZgwNDA0MDQwNDA0MDQwNDA0MDfxKNHBCJ7rsnV6e6leFM+3qoVcolUvFUvlCf7jq9y8utNLVxdwFAswCzALMJgBmjezhspazBSYbrszy3spsPSzbaO8Lkp1dFSrvfvdSnTllpPYb7ZxSMTXbMrScYohvAr+xRILXA26gaqFqQf9A/34++gdVi2vhWlC1QJ5QtakzOFRtxjsYqjZ73gVVC1ULVQtVC1WbQtQUqhaqFqoWqhaqFqoWqhaq9q1XF4aehZ6FnoWehZ6FnoWehZ595Vq6gR5oL+VvhcRo/7VvI8mSaJ9yt9C70Lu70LtSwZgNandsOW73vyaq6YoHVWJ+V+yeD3Zfy+7Gt1acyXhs2e6+aN5FbYPpgunCEsISpoMlBNPFtXAtMF2oUTDd1BkcTDfjHQymmz3vAtMF0wXTBdMF000huwqmC6YLpgumC6YLpgumC6b71jFdyv4CLgMuAy4DLgMuAy4DLgMu/2Rwud7odNv3zWajJVZse8GX99rcjHmitnMzpw7QDNAM0LwL0DyD8WYDbXaHTjcospycbHaHTqxE8xqwObao2hfPPLNOA2MGY4a1hLX8+awlGDOuhWuBMUPVgjGnzuBgzBnvYDDm7HkXGDMYMxgzGDMYcwrZXjBmMGYwZjBmMGYwZjBmMGYwZjBmIF4gXiBeIF4gXiBeIN6fCvEKTKx4vGDs3gbf9Ror7rOx0j4bO91fY1KrtH9IOeiOyJaRIaKriJ0C7DLsMuzyLuzyNKh72OiymHn48OuGxHJsj9WUsthQCbdchSZP7ycYL7nzcgpZHQxq4mZ5UteEfyqDga0PvImP4e8RzNSCJY1E0XJilhrLalu2UlQerYkd7ua8j8+pFjW8zZxKjdrJh+2cvPeT/9bIcF1dy8nzDc/f58Tyjj6UifIoPOzbUNdiSMKvyoNh6rHrUMS8XGbgff8Z6nI+5DxatiDMPFrtWKk9zLQZPwHXspSBrZqToWqHs6nooLn4rmL7TYgKOiuFnbViMvIYm/AXy0LGIX8qiuG3+F1ONNANoBsAbgZuRjeAa+Fa2XEtdAMZA23RDWSDbEY3kJYORjeQPe9CN4BuAN0AugF0AymE6dENoBtAN5Be3cAsi7Li1ksZ6KR8mwOUvil+mt4RHdJ3h960ZW6q7Qes1FjcLpr1r7zX3pINlieZYuzYPFsWwWLhZlNJJ3VsdGz14cHoJ5+1N2uK6+3r6UFE0Mz38vjfDEcRwJVrPIhu6T0rAnoVs9d/3d2GCSXFB1ukSsJRLFPRnk11ZPSVd6Zl5vtq/1EXmb3305nwY6VmSmO6hkj7hfHGb1P887ec8i1SfohvcXVE8N2H58VXI/7Fcr7lvFBfVBv6m/LgGeREC/AEx19VOrqbC83UV81gRaY8TGy5GvX29EwRjIu56MGYE6aZn/onXDrQN6/bN+sQ90qzJktk1rviUzKUHzFZOsVkvltspSaLu5QigKyBZT+naQT5OSe4Xih1dytkM3eVT5KK9vUT/7PypdK+btWaHSmmkLz0baVW73aq/xI/fWzUO+LHf8m9v1bkP19qN9WGUN/c39QaUpTT+u2m8bto76ZxfX9X9fb5UKtXWl+FFqXaqlVua/8pUOr6dqI85IfID5EfIj/MvPyQt6ggwESAuV8BpqpphmhSHTan9kgo6Lso91T9otB/KF3q572+/nB6fta7ujwraL3Tnqb3hBrjZbWecTQ9O4TzipvsY+1jp1qtd+9q9fuOnLc26tXu58Z9y/94U/nqf/q9Wv3N/3jXqHc+S6UR4ljEsYhjEcemUxybmxrQ57ST6CUPTS/5ZtWRA93UbYEH50Ml0dEmisiVSshIC7hcWNiVDTsnf4cR63+Saw19y26sOFTk9l6QLjzuTm9IWdTgcoVi/JhypTBW3cd5nNmjseMySNX1zkEXB/Km/q7lHXx2UI5ufF/4u4zh3ekoy55ilZs7saisNGvdTqvy8WPtWnyTQcVGp3t9W5GRyg+txu/taiv61P1YuavdihnhdaPeqdY73c7XpnhQ3VS/1K6rwTdxlt1mq9FpXDdug+9fqq22F56sxb/cNq7DsKV8YDbane5/3Ffqnfs7b4kbbjydHkRFesDCRFSkB9RZqEhRkSJ1Q+p2gFI3VKS4Fq6FihRRIyrS1BkcFWnGOxgVafa8CxUpKlJUpKhIUZGmUFqJihQVKSrS9KpI0fQdjm4MTV96+wZNXypOB00fmr4Ua/qGxshwm7r9yaevVtwzt2JTL8ITpW88pk+mkAK6yAvluNZYkcaSw6yfOvfTCiLgI0guP0Yse1Bsq/StiemK+Ymua96R5PnlFP2Ha6t+e+p4rKt2iGuJ9JItyOw/jizR1X8cxW6OhrgNnMl4LDAITTwoHo3BY76v2pphqgKci1gv51dFNvDdkGmRxaiDcmeYxmgy8hN6hqOUVt3G2Gy5zWZI+BgzUiz8g+wU2elbkJ0ebs2cw6lssxJPm9JSaPqDKpn16Z9X6zqmADZkxMiIkRGjpT3gl5kicEXgisAVgSsC10wKXIVC0jZ0702wSasvXJbOS6WCXiyUtcuz03KppxaLhUvtStcuL/Vyee5ig0Px4lGEtAhpY0JXJ/9U2kBS27PcrkwnbCuozfee82FOYo26Np4RSfByz9Wq2iDXp2uSwfIAdBFWtJXHyUhE6sO3gSpfDMdwlZ1yLnLol0iYYXoP4ZUqXhSihyw6RCF6QJ2FQhSFKDI2ZGwHKGNDIYpr4VooRBEsohBNncFRiGa8g1GIZs+7UIiiEEUhikIUhWgKZZMoRFGIohBNr0IUQQCCgMwKAgDIAcgByHkPFew87HxasBTYedh52HnYedj5ODu/eqDqWe4qb5x5MgjcQbdlNl1Y43iajysszC1IfPaFj+EGPrxytN0oGTLTN7GWg0vJSaPNvYILDcHhagg0fWzrfe/54L/D6K2qCmKmCDcxBqZlh22sVxgcz8kIVmkO4tz/j7zjqoY51B0nH5yJmOaFd5cwjvLvyLJKJzyUIovDOMqHZ+UmKPyxyTNSHRsnIhs8sfu64z8xnUkv+kmKHvyH7rz4oftUOnmvGKbj6qp2vIlYwlux7SSV8JrYQCkxEfeSOghIvn1IJaZbjXQRqBcyCcSjXjigzkK9gHoBxBrE+gARa9QLuBauhXoBmB71QuoMjnoh4x2MeiF73oV6AfUC6gXUC6gXUoj0o15AvYB6Ib3qBV6ek9KX5yArQVaCrARZCbISZCXZlZXwwi9e+JXyF36hfEL5lBKkDeUTyieUTyifUD7x1hAUPyh+0q748RUwb0rv0/WW0nuQ/eRlSx7Jvrn8xzv8C6mA/MYRA2VcX4IY6IA6CzEQYiAUCygWDlCxgBgI18K1EAOhTUEMlDqDIwbKeAcjBsqedyEGQgyEGAgxEGKgFCpkEAMhBkIMhBgIMRBiIMRAiIEQAyEGQgyEIgZFTCpshiIGRcyBcV0oYlDEoIhBEYMiBkUMihgUMYehiMk/BKUe3oIwxosjdr07eXtVjNdM3vWCoGsEMbHY5T6lMPFmEcFkXFeBCOaAOgsRDCIYSH1I/QMk9RHB4Fq4FiIYNBmIYFJncEQwGe9gRDDZ8y5EMIhgEMEggkEEk0JlCCIYRDCIYBDBIIJJKIJBGoI0BGkI0pA3Kw15w++JQXKA5CAlFA2SAyQHSA6QHCA5iEsOVg9Umu785VrjVR4583QQhIZuSwBAWOR4GukrLEyHjKyeMVzp9ns4iFRXvvAx3GCwWDmsb5QkmrkJYi3nwl4JLRdc3Z8IPhB8IPjYg+BjWrTwFtQe4uduEBvbRe8h/zCO4n1rFB/ihxMZT9un4GN1pA8NSNZlBWhADqiz0ICgAQFUB1Q/QFAdDQiuhWuhAUGSgAYkdQZHA5LxDkYDkj3vQgOCBgQNCBoQNCApFEagAUEDggYEDQgaEF6Egs4DnQc6D3Qe6DzQeaDzSA8pg84DnQc6D3Qe6Dw213mIW+iFtRHyLs2G/kJaK7giNBdoLtBc7ENzMSsceDOqC38Bu7Po4ilcfm+guQijJvtWXQTtorHIOLaPxuKAOguNBRoLQHBA8AMEwdFY4Fq4FhoLkH80FqkzOBqLjHcwGovseRcaCzQWaCzQWKCxSKHwAI0FGgs0Fmgs0FigseCNIogvEF8gvkB8gfgC8cUBIDSILxBfIL5AfIH4YnPxhayAXjz+8cLiCHmY0msc5DQbMo+wX0LbhdeH6APRB6KPvYk+IuHCW9B8GHtRfBgJ9B61F1F71NB6vBn5AFqPA+ostB5oPQDSAdIPEEhH64Fr4VpoPZAeoPVIncHRemS8g9F6ZM+70Hqg9UDrgdYDrUcKBRBoPdB6oPVA64HWA60HWg/eKoK8A3kH8g7kHcg70knNIO9A3oG8A3kH8o64vCOhQ10VCqXSxZmuXfR7Fw+nWr98fnFWKuqnxXLpSj1V5y4WcQHiAsQFW4gLjLcmLbCcXSQF4So4762C1wsLGu19CgpmV+HICrJOqiMrOKDOQlaArAD2Gfb5ANlnZAW4Fq6FrADKHVlB6gyOrCDjHYysIHvehawAWQGyAmQFyApSyNojK0BWgKwAWQGyAmQFyAqQFbz192UgH0A+gHwA+cDPpmOQDyAfQD6AfAD5wA7ygYvL0nmpVNCLhbJ2eXZaLvXUYrFwqV3p2uWlXi4jH0A+gHxgH/IBy3kjsoGx5bjd/5qopiseLdsLCEQ7+aCdteKB+NaKMxmPLdvdp5xgYftICjJOqSMpOKDOQlKApADuGe75ALlnJAW4Fq6FpADCHUlB6gyOpCDjHYykIHvehaQASQGSAiQFSApSyNkjKUBSgKQASQGSAiQFSAqQFLx1SQHvaEBkgcgCkQUii7TxQogsEFkgskBkgcgiLrJYPVDVG51u+77ZbLTEcneFX848IwSRotsSeBB2OZ5GGAsL0z+vdRw38OiVY+9GOauZnoq1HL+c3IwZ/0SIghAFIcoehCgzuoq3IElxh043eHfHDooUd+jEXgGyRpASW0zvU4cSbxb5ScYVDchPDqizkJ8gP4GRh5E/QEYe+QmuhWshP0ENgfwkdQZHfpLxDkZ+kj3vQn6C/AT5CfIT5Ccp1GQgP0F+gvwE+QnyE+QnyE+QnyA/QX6C+ALxBeKLdNEyiC8QXyC+QHyB+GJz8YXgY4vHhVUeuQc5hHeU4qscpfQqRzl9haNIEXAmdCrBXRbdCVFvRRaNXTXyFeQryFf2IV+ZFmFkUL1ijU9UfwW3kVDFGufF9kKgIn8In+KzEhXXGiuVth6FmGJbrtKkiP3UKLvsRSzmW1kuQhkaI2PNivpWbOIdLgIjPW92wqVwEqJ96wZn1gJitPB5kzvDNEZiMund2KPgawF8H3wfxhjGGHwf18K1MuVa4PsZ413B97MBGIPvp6WDwfez513g++D74Pvg++D7KWTawffB98H3wffB98H3wffB98H3wfd5ewQCBgQMhytgWM/jm5OhLGoZY7Pg8+Hz4fPh81+dzxeGc61xdyVmn9CxzoqlM7VUOjs9f7gqFEsX/YsHtdQ/K5+dlopXF+XSAiJbnsHLAtRni1zKVR4EE5LosZPQGhenmn7ZOz896/XOLs/PL/TSpXreP++XzwuXhX5ZjLzyDN8seDzQTd0WEEg+LPd8tBFsLNnaFXyxYG6XMbkiftGV8YuTv8OP/2xD6oaBkM0pXTkCqVFUZitqNzfXbC6SQgYVsaPAz1KkN7z6YJ45Vt3HuTP68AoRpMiPfRR/yXT1Nc5l2bNtbRQrThBDS0NLQ0uDdIJ0QkvjWrjWAbkWtHTG8EJo6WzwnNDSaelgaOnseRe0NLQ0tDS0NLR0ChFiaGloaWjp9NLSQLlAuUC5QLlAuUC5QLlAuUC5QLlAuUC5QLlAuUC5bwjKPY4zsVviud4sr+vN8k7+nv6+HajrNZF/CCatCWndqXnnCyK7c/PbJdzulEVWw7tzTW6M2i6bbM89X9ZPsiFjIWMhY8H3wPcgY3EtXOtAXQsyNmMoGWRsNtg9yNi0dDBkbPa8CzIWMhYyFjIWMjaFuChkLGQsZGx6yVjqCFNHGGQZZBlkGWQZZPnnIMtwu3C7cLtwu3C7cLtwu3C7cLsLuN1ZRHY7eNdb4HbFzXbyd+zLVtiut3/e9dboyZjd2Er75YDdmeX8Ylo3ZoWVqO7NdGObcro3C0MKcw+T5aEE4FzgXOBcCEIIQuBcXAvXOlDXAs7NGM0GnJsNfBA4Ny0dDJybPe8CzgXOBc4FzgXOTSGxCpwLnAucC5wLnJsQzgVZBVkFWQVZfbPIKlV2oXWhdaF1oXWhdaF1oXWhdaF1Y7TuNBm7HaorvnWDle3J31Nft8J15Q/jaNWeCNg1p1faL8fsTh1mObU7ZY6V3O76CMGmKO/GsYa5h890jAGiF6IXohfsEOwQohfXwrUO1LUgejOGwEH0ZoM5hOhNSwdD9GbPuyB6IXoheiF6IXpTiLlC9EL0QvRC9EL0Um4XahdqF2oXahdqF2oXahdqF2oXahdqF2oXahdqdyG1OwvI7sDt+lNeH9v1v21P7T6F8/ZtoN1o75dkdmOz/BXI7tP0CmQ5sRtrLhGfO7/YWEjjLl5aQ+ZC5kLmgg+CD0Lm4lq41oG6FmRuxlA2yNxssIOQuWnpYMjc7HkXZC5kLmQuZC5kbgpxVchcyFzIXMhcyFzIXKoKg+yC7ILsguyC7ILsguyC7ILsguyC7ILsguxugex6w9rWwK4Rw3WN3WBdYwdUt/YKoG5tA0zX2AzSrW2F6NY2AnSnVpAwuTC5MLmAg4CDMLm4Fq51oK4Fk5sxiA0mNxvUIExuWjoYJjd73gWTC5MLkwuTC5ObQlAVJhcmFyYXJhcmFyYXJpeawWC4YLhguGC4YLhguGC4YLhguGC4YLhguGsx3CnudTsK13JO/racrajbcPmQ95YPydlbuUZ4IeZ20eJmMXkbLbwWEreNBQ1tyt0u2nfZk2PXlRXALsAuwC5UIVQhwC6uhWsdqGsB7GaMcAPYzQZSCLCblg4G2M2edwHsAuwC7ALsAuymkGIF2AXYBdgF2AXYBdgF2AXYfesVgwFzAXMBcwFzAXMBcwFzAXMBcwFzAXNjYK5ESrcDct2hE9XFjX3ZCtF1h862lXHj8+2Xo3TFQcK16toauTFzrER2Z5YKm9K6i1cYc0+S5CsL0FzQXNBc+EH4QdBcXAvXOlDXAs3NGMsGmpsNeBA0Ny0dDJqbPe8CzQXNBc0FzQXNTSGvCpoLmguaC5oLmguaC5oLmvvW0VyqCIPqguqC6oLqguqC6oLqguqC6oLqrkB1pxHZxMyuP8VLAuf6uzgLidyJsKQ6kOHEWX52Awx31e7LuVqYVJhUmFTAOcA5mFRcC9c6INeCSc0YxAWTmg1qDiY1LR0Mk5o974JJhUmFSYVJhUlNIagJkwqTCpMKkwqTCpMKkwqTCpMKk0oBXahcqFyoXKhcqFyoXKjcFFC5Sa3Qf7Qt755eYoodrxqIV8wCxrbe98Ylv1jpW8V6Y6YINzEGpmWHbWyA+LrWeBXVG9C7YhPHVQ1zqDtOPjiyYZn5ke44qnhACWMo/44sqbQ9dlf58KzcGCPdFPPqTUZgdWyciBznxO7rjj8eO5Ne9JNki/0h/cQnhLtPpZP3imE6rq5qx6tI5K43rd0CSM7LPT2KdBWYrATb7Qgo5xR1MLD1gQxLGmbY7HzhYMhlyGXIZfBK8ErIZVwL18qEa0EuZwz1g1zOBlsJuZyWDoZczp53QS5DLkMuQy5DLqcQ54VchlyGXIZchlyGXIZchlyGXIZchlwG3wXfBd8F3wXfBd8F3wXfBd9NF76bfwhUZIdP8YaR8iQAb7hTvvfs/RojcudR3igavwXAu3xnKF0oXShdUEJQQihdXAvXyoRrQelmDGuD0s0GRwilm5YOhtLNnndB6ULpQulC6ULpphBdhdKF0oXShdKF0oXShdKF0oXShdKF0qW+MIAygDKAMoAygDKAcgoA5YSOdXmqFs+08uWVfnF19f+z9y7MaSPb2vBf6fKp+iapAszF2Djz3hibJHzj2N6AZ87eO1O4kRrQGyGxJRHHk8p/f2t1t6TWFQljB/A6+9TEQN8vq9flWWtNtPN6Y3KuaVrnrN5sN/T6OSKO0xDHrxZfPGMWcwAE4v9gsqNCmOIQYZuDLAbkbS48FzQZY67JOP4e/PljY9BuoBcpCdjlVImGmpoyAN5knN2K/yLJLwAgFeiAMtG9wfR9lnNJvXliIL+9gDIpvNISfJ/Bub7EWLKeubUKLRVMjMBpBE4jcBrRnYjuROA0Xi28Wnt0tRA4fWBIQwROHwa0E4HTu7LBCJw+vNuFwGkETiNwGoHTCJzeQTQxAqcROI3A6d0FTiM+F/G5iM9FfC7icxGfi/hcxOciPhfxuYjPRXwu4nMRn4v43NeGz62poNinIHUFvzcW/N7x9+jnJ2B249GHNwHuRnjR7aN3E6xuBoQ3siT5ON5Ek4VRt1l8d+KpWc9vI0gWQbIIkkUkHyL5ECSLVwuv1p5eLQTJHhiqDEGyhwHjQ5DsrmwwgmQP73YhSBZBsgiSRZAsgmR3EDmKIFkEySJIdndBshhdGKMLI3oZ0cuIXkb0MqKXfw56GSG8COFFCC9CeBHCixBehPAihBchvFkQ3jhG9gk4XiHqjuHYHX9XPmyO4BWNVD0hsm8A31Wk761jd2OSfTpwV1mGXNTuZbSxopDdy1TtQuJdydYqIE4XcbqI00UwIYIJEaeLVwuv1p5eLcTpHhiwDXG6h4EkRJzurmww4nQP73YhThdxuojTRZwu4nR3ELyKOF3E6SJOF3G6iNMtidNF9CqiVxG9iujVV4texdi7CNxF4C4CdxG4i8BdBO4icBeBuwjcjQN3o9DYJ6B24auxL+Mef4983By5y79dhkJ8eeyuFZW+tw7fjbSeDeCNrEcuhHe9sqAoqrew2iHxDkXVDQjuRXAvgnsRgYgIRAT34tXCq7WnVwvBvQeGhkNw72HADxHcuysbjODew7tdCO5FcC+CexHci+DeHUS8IrgXwb0I7kVwL4J7MQgvAngRwIsAXgTwIoAXAbwI4EUALwJ4EcCLAF4E8CKAFwG82QDeOEL2qRBeyfxKBK/89EQA79eAjd8Yvxs28QzwXYXhz0Hvfo0KI9ngXaW5UlDdpNyRCsxNl7IRpIsgXQTpIpIQkYQI0sWrhVdrT68WgnQPDNWGIN3DgBEiSHdXNhhBuod3uxCkiyBdBOkiSBdBujuIXEWQLoJ0EaSLIF0E6SJIF2MNI3oX0buI3kX0LqJ3Eb2L6F1E7yJ6F9G7iN5F9C6idzdF7wra9jTsrqEgd40t4HaNp6J2+8+H2e0XQOwaxfC6/Y3Quv1CWN2IMInwXITnIjwXMYSIIUR4Ll4tvFp7erUQnntgeDaE5x4GgBDhubuywQjPPbzbhfBchOciPBfhuQjP3UHMKsJzEZ6L8FyE5yI8F+G5CM/FSMKIyEVELiJyEZGLiFxE5CIiFxG5iMhFRC4ichGRWwyRGwG+PgGQa7vH3213cwBuIE1UhTSxIQyXyw3bhd+myTnpINxQBksF396kNFQUgptWN+sReaqQhdhdxO4idhcBhggwROwuXi28Wnt6tRC7e2BgN8TuHga6ELG7u7LBiN09vNuF2F3E7iJ2F7G7iN3dQUArYncRu4vYXcTuInYXsbuI3UXs7muPI4wYXcToIkYXMbqI0UWMLmJ0EaOLGF3E6CJGN47R5bjSJ2BzPdMNo+UqHzZH63qm+6R4uSoPvnXALrQdiK1rI+cq65GL3o1JDUWBu+nCRuJRKS9kIEoXUbqI0kUoIUIJEaWLVwuv1p5eLUTpHhisDVG6h4EjRJTurmwwonQP73YhShdRuojSRZQuonR3ELqKKF1E6SJKF1G6iNJFlC6idBGl+9pRuhhbGFG7iNpF1C6idhG1i6hdRO0iahdRu4jaXYfajWJki8J3TUa/MH2sOUxnlmdQc6zNmfbFPZYg2+PvurFgVlH4rmiuGjZXFc1VfcxuHL3LZSu68uZQXD6qAXZXN4BsTFb8WxC9/aHkYHipRehs5rAZ117JzuBtyu2JLy/ghwR0SIJNmB52mY3oVUeVjecdyiaFQZJ6YmIMehQMp2eLUcTJclHk78YdZD1hFzefbgc3n/pDrqX57WY0vrjqDodRKDDCYxEeixg+xPAhPBavFl6tvb9aCI89MDwZwmMPA8CH8Nhd2WCExx7e7UJ4LMJjER6L8FiEx+4gZhThsYhV3H+sIjBrjr0wXFYevazUJaFpBUR9b+WSNxoYBTk2SylYdsE37mMtHOiq1+WoGMWcUGrleLSRW+Z84Oa7zaOOLJnjG0DsINQLHy6/9NJYEJp+gIv0pWLOekNZotkry4MrzpgueuLjqxD2zXOobI8ul4w6gVUJFGo8XeTnIxt4+89HRKMem9nOY43cAO/rrpZL2+HpHy0yN2bzqkYd3bAo2AdDI5T7K+ENPBhcERREoQHOPGCTiYxrIlWYhkuaGwdWeeVrlhI7RurBGpEgMQhSO0iQGoLSEJSGoDQEpf0sUJpEr0SAaQFxCsb8XbJY74467Vqj2Tppn8bYrXdHjZNa5+y0fXICy0B13YCeqXkbWcUYyALYAeZwkxIsUy2yTo16ioIttgbh8J8X1ZbyYv1Gdf+d3+JLxRzHdnKJf/zFcl06Szlx8bn5BVPOVSXzfSy6mFNquutXs+LP7q+tY/GuOCiMXIRSxQUHhR04Pi+BhcsNqykvS/VrsxQ8b2J7Yy7UbgGcB5E2AyG5HFJPldhJiPXLC7QZAfetw+dFNAKZSDwEoyEYDREziJhBMBpeLbxae3+1EIx2YOgNBKMdBlwGwWi7ssEIRju824WW4k0txWiGQzMcmuHQDIdmODTDvZQZLroCE9srZknLnnqjDms0Xy1oyiEv31RsQUS7FT7Qv9Bgd0gGO50tHaYJSixDBaAJLzThKcsTFDFmlu0EbZQ159VCQ1emWU+1p32ruh41LJO5btUfjWFb1eDUwQKRf2esuEuGMpjFb4/k0ke3FXmp6NI4Bslr5WjMle+Wu5qEXyWsjO6xfAh9O+P4a/P4LTEs12NUr5WyUKrizHZslFEBqZyVMl94eR7LZW6faM1EayaaXNDkshsmF7Rm4tXCq4XWTDSuoTVz5xYcrZkHvsFozTy824UOyTvqkIzGUjSWorEUjaVoLEVj6c8xlkq3xW2YSyPejls3mkYjYYtho/EUjadoPH1e42nU0Pe6zKfwkAu5cczX091WJoawYXng4iZUHsNFyrllTZ2RdAnbsqFWCqRn4ApwPnRM1JCaqIHOZn0gAl/pmgSSXZk9AxbVkDV8ltSX3bhJoQLsuKKdsB3SIHN75QTV3Lcq85jW8CbMIw3bqQbtHL+VShx7YXge0yt8vMH4pb6/6jKTKzzC6H3ykDFdUS39SqaGxZR5EBBAuCYlcP/mjJ87hwBEjrQ61Eh/GmtTHYBnw75Sa2VSJ2Abw04rmcGJ8sz1uFm7t1k5vOVcubaN9uKoIr5qwPvWeMDUKoj/QCM1GqkR/4FXC6/WgV0txH8cmMEU8R+HYaFG/MeubDDiPw7vdmFqFUytgqlVMLUKplbZwXwjmFoFkYz7j2TEgDmbBszhJuGBD44o+UwKC7syId6aLFL2GVrbWNG1uBv2BtfdT73xVa/7Oz9YwTe33eHwz5vB5XjY/9S/6g7U37rXl+HvQdX4N5i3BvPW7MOaFc1bEwf15RzRHUOMkvsE0vOeSASGC4yD5plCLEqI8lIhThW7QKhVyKXtr2kNso3YCgg3CdINUbdBsb8wU9Keex2o2KHDgaDk7Pz7/vtRr3c9/tS/vhtxXPnNdW/88eZuIP+87P5T/vVnr/e7/PPTzfXoI4f9opsGummgmwa6aeymm0YlQtC5mwIwBcJlo+SFOus0T5vNOmvU23rnpNVuTmijUe/o50zvdFi7nZis3xU6SeyfkwS6RLxoSqg4Ut8tmhwq6TuwlTRR8fFsK1+U4nDwXDmjirgHIEJ+n0HXiJDfo81ChDwi5BHGizDePYTxIkIerxZeLUTII2AbEfI7t+CIkD/wDUaE/OHdLoSvYb43BBPsubYOwQQIJkAwAYIJEEygggkKJcvLWrr1QRwjQRvTGIcgi94z9uH5dziX2hbiEWN7o7RcWZO4D0EVewuqwMiTLx15MoGreKkEfqOgY8KdQtwXjUWZQIVsJSrlltL7pWFLni/P3/MhTvL7RRTKgQMbEIWyR5uFKBREoaCpHE3le2gqRxQKXi28WohCQVAEolB2bsERhXLgG4wolMO7XRjdakejWyHIBUEuO6IMRJALglwQ5IIgFwS5FAe5BElOnxGCEst+uv9gl1RkMIJeEPSCoJcXAb1sN/Hq3sBeLOZNTfshSNtaANDiV6nKKtXI1kUxKxbzHmznC/EcOuV66iADbhkESryVN9fMew9DeAviL8enfHVF6FDQqHi2ZptuNt4ErddovUYTG5rY0HqNVwuv1t5fLbReH5i5B63Xh2FfQ+v1rmwwWq8P73ZhlkHMMohZBjHLIGYZ3MHUe5hlsMQxmTG7Xz4O0Adml7ljH5h9zTWv/cv8heOjWbNozebpWb19Wmmd1k8753kXTZYkb64Md2Jbb/PWs91odk5bHVBvP5B/2s6Xspqj17IkTz9yiDDbQ4QZAqYQMIWAKQRM7SZgSoBxuHm7CEgKrNbFEEo5Ptt1WKSb0cfeYBtNxVaEj9BvPgFF4sRdnTGCkRCMxOEwPjjjFYGPfEhMHsAohL4UBBcBfuZaIl9GEvlyqSJjtg4pCsBAPpDIv92F4UPH34Nkvj82gBKtxQ9FkEETJXXwVhFFXiRRctBHNqJIHQaXKJbUmycNhrJJMSS/R0I9MTQGXQsxwbP9VM7RxzW85PLSZlnKntxTFkfSvfzUOKocdYHduLq5AJYBhJPbwc3l3cUIo4QgzgrBIAgGQZwVXi28Wgd2tRBndWDABMRZHQYSBHFWu7LBiLM6vNuFOCvEWSHOCnFWiLPaQfAR4qwQZ4U4q93FWQkdWUG6pAaDmjwmbDSyLQK9u0V2rGx762KcSYN49+qqXDgz01gY3i1zeCSA/KW4gqJi5KFWTZiEuWbPN9YIDtuzl4SPkp8madEIDVc85YMU3bl8AGWJZq8sD44NY7roiY+vQtg3z6GyPbpcMip7A32fpTMHQEufj7iX/ecjAtbSme081sgNMOjuarmEGPY6sS0yN2bzqkYd3bAoWFhDE5r7q3DTfzC4tio9Tj35ZFjGYrWQelbDJc287cY1y16zGEhMAQ406j8QD4l4SMRDIh4S8ZCIh/wJeMhgzN+PPjBnQS0A/TTbtXrnpHV6CpAwy4DHceiBoero3VG7Xmucds5aLVgKqusG9E7N28hKrom5Fo4IY6jtH2zxVYMUZ8xiDth6q0HyqKMtAhOrX5upyL4wmFgZQJ9Sax2mr1hmuhzEHqaYO/CsZZhibo82C1PMIXgUEW6IcNtDhBuCR/Fq4dVC8ChiGRE8unMLjuDRA99gBI8e3u1C/AMiaBFBiwhaRNAignY3YaWIoEUELSJodxdBG4da5By9HcPxkPsE/uaeSHu/CxuieaZgWxLyhtTaUUV5GYo+uWftNa1BtqVNgUYloVMhFioo9hdiQfccC4rZlzH7MoJnETyL4NmDAM/mZl8ueaHO2hPKzuratNlhpxONTVunJ5Pzzkldn7QmOpskJotZhhEhiwhZBSGrgFnzEbIy3e6mUTDjCYsT0FkFKrs2pOUTomMGASNlW5XAqS07OGYRFC6GyUwLk4nY5H2GuyI2eY82C7HJiE1GACUCKPcQQInYZLxaeLUQm4xQWcQm79yCIzb5wDcYscmHd7sQlouwXITlIiwXYbk7iFVFWC7CchGWu7uwXIzpijFddzymKyLHETleGjkeAfHpbEo5iCn69TpAYRI5GLGeok8sguwRZL87gA8E2SPIHkH2CLJHkP1TQPad5mmzWWeNelvvnLTazQltNOod/ZzpnQ5rtxFkjyB7BNkXA9mLFjKw9vbymLolY1Hbyyqvk4DT20vSHbI0SWANYh5q0tCa43JrTqpEEcapzsbFc8XDE5RIPhNfBk66cYMp6gdp7JXqCv8oLfyPdcTOInYWAX4I8EPsLF4tvFoHdbUQO3tgYDPEzh4Gug+xs7uywYidPbzbhdhZxM4idhaxs4id3UFAKWJnETuL2Nndxc4i9mkPsU/roTzWyhTWwNCUiNAehPYgtAehPT8l+bxnLyOJ59esgmYazPK6w2ulijBiRCD2p+36OSAb/dJr1677qfuvm+tqvRlZw5h9GswlzOHaeGhgTayqemJ9w8HHhlZ8zcVyPS8c6STt/ntkChakUm9kWXRWS2edyWnrZDI56ZyenrFmh55qp1r7tN6pa214JhDY8xRgT82zl3ngHg6/ycLzBHJ1WVBPWDEN2ROK6xvBe/KqI6oHUT2I6kHoAUIPENWDVwuv1qFdLUT1HJgZHFE9h4E7QFTPrmwwonoO73YhqgdRPYjqQVQPonp2EOqCqB5E9SCqB1E9iOpBVA+iehDVg6geRPUURfVcQKxP57ELrF4zf7J3w6MA3iOrrcf43FkGcAFDD/Tsz4/zUcdVSZ0iwn4Q9rMDsJ8QoKNgf2zHmBmFwD5+SRXdcwWc9k3wQxaKhwYsuWwksOcZDnHYDAaF0B1OGKZTl62zy30xfPtuEFU5OUipuZ0yT5uDYjr2bGXaoLbReHZQ5HrWxFFgeQGBRbnsxR5seTfLVkjhd/kBgd+4aif/qV25VUZdr9pIvLiy+dTwc665mqV3LKZNoEB+x3RB/7atZHRAaLkSLMb6Z9xfZ4wj+CrjCPoP4mGzHSE/kM1xGK6Xwmwcf4cb9aMwz1HVxbIkgMVioUn4cx6MOExgLemBYYlHx+CwLG9ODP62r+FGJDHgz9SSevNErzdRahMeQrEZWQ/TzRoi5eey5w4MR5WjDzc3H66EmHwxuBnevB+BqDvoXlzFIrzjy/piL2uR9vBBTT6o6e8nCsD4EG3pIYJnJuUdkq/J8fcgFUzxR8mt+m9R/FWSt2MBr4/mEt2AizFZ8XdmoqSdyROYLeInCGA6kc2H8nPQtp8KR8KHQ5Et6CT7IVPHkf2aDWWT4g2V3VNPzIhBx4Lae7afBUhVJt/fDPof+tf34jeXUM2xXZdQ0/SxVY4bhSNTDZTGsAD3orN7jtcWpOK+Ru4HvQ/9m2sl+4pStEbuh3cXF73hcDzojnoSVyuVvv2rMGcLmdjePNIJlKRBP/yjZluu51Ap5N+LNb8nb2J9yCRDrgBM3Q96/7jrDUfD+1+jPQfFqPUo94/nO1p6Sh3INBNJZsXxXXYilxEfkL8Skb0uym7gvu7XvmZxTGIjwJrBax1VjtRZhDaSfpwtRCcxdBJDTxb0ZEEnMbxaeLX2/mqhk9iBeVWgk9hhuLGgk9iubDA6iR3e7cLM35j5e8czf0tjRlndgqgGeFyh0OMyg6ASwfADRZNUx/0qKAdw7BPGuUtfp+Tr64KqFanfy1HglZTYdmPAWXQmzdjKK5QzrCZok7LtQRt/5RAsoSFcw1NHdLNSp8iFS2Ef4BKN/cD00MbAuCgqF89lJj+5yrq/cZk44PfBdyBCePNQjni7ufr4RYeYbW301a3Krl7cXF/3Lkb9m+vx+27/6m7AceNKwUFveHtzPeyNP/a6l73BeNC76PX/6I0v7zg8HA7E6OJ2/LF7fTn82P098cNgBMdjdDVMKxJRuEpT62Z0QNp6g9vlhhpuz/bvDgiIhgtkyuBQbUJn1LCAmnkb3eVtdJp1Hxf02xVXWwC5rOdfq9B8nXezEOdwkC5P6OKELk7o4oQuTj/LxUmCLyJuTgFxCsb8/Yitqg+MP1LvjtrNWuMEWgkerndHJ+1asyW+4+WaR++OWp3a6RksCtV1A8ZBzdvImq53WIo4KCUl5zjwKpgMZjpHhDICwwLkVgo4LEyBXgITplRaAwvj2pCgaG7847BkCgTMp9ehnkUK4pnALzqb9WE3vlJzDQBEQtDgbTRkDf8x97lebv6rACOjaBJthzTI3F45QTX3rfrspjW8ybNLw3aqQTvHb6V6yV4Ynsf0Ch9vMH5pm6sGEmgQtyEEiIdq4F/J1LCYMg8CrBvXegbnkG+BOwd1kyMthDXSn8baVAfg2YCqotbKpE6wgWGnlUxVVB60Bjdr9zYrx514rvCEjfbiqCK+agD30XhArBZitRBQgoASxGrh1cKrdWBXC7FaBwZuQKzWYaBJEKu1KxuMWK3Du11PA8KUACfkNvI6ACJ/Gt7cXnmK61sl7sfG2eYUfMQ915oECpNfJdfzqLrReTboA6RVz2OW5ru+udsFkfzUaSDQBIEmCDR5MaBJlg20bJSF9oSys7o2bXbY6URj09bpyeS8c1LXJ62Jziaw5c+LaVHtK4ejps85ZO/770e93vX4U//6bsTp3s11b/zx5m4g/7zs/lP+9Wev97v889PN9egjv2gIAkIQEIKAEAS0myCgSoSgJ2IVIYwGYTSvHkajwF5ykTRj4b2xYcClsB25xMUhNmqkpCIBmPiDrAZu2iT2EjfF8FFgFKbXFa0HozAd5r5uPQoTYvH2Gd6FWLw92izE4iEWDwFDCBjaQ8AQYvHwauHVQiweQsMQi7dzC45YvAPfYMTiHd7twrhpGDcN46Zh3DSMm4Zx0xDO+qrhrHEMTM4y7x7AKmtvdm+k2dcvAtbS2ZRyUEz063zgGOb72/c4eIgZRswwYoYRM4yY4YPEDAPo1DGYCCJY1qGl0zxtNuusUW/rnZNWuzmhjUa9o58zvdNh7XYyu6rsCkP8ITYZsclHcdRwBKK8tF1v/J8VtbzVQuKVn5QVtgoNVmWDmRliZa7vWyj7D1GWXALfOAwqJIDJK8dywSafyAWr9shfyZ+VFTY5kFBJkY9kfSpi9kk9Z723v/f+Oe5+GPR6n3rXI8SAIQYMgSoIVEEMGF4tvFoHdrUQA3ZgoAnEgB0GSgUxYLuywYgBO7zbhYbCPTQUot0L7V5o90K7127avcokzLpYOV/ZbbN9evTu6Py81mi2IGWW+LbVOTl6d9Rp14CgBN+2mzKR1nm90TyqHP13s91unEP1Tq110j4Nvvp09Xvv09lpB3x7m7Wzznkdk2yhBe6lLXCqeefAzXCqAaYWALfLZN1KM8RtJ25Q1CSXtAYWNs7dQDSfkeCys8xzYfNooUMLHVro0IyAZoTXYkZACx1eLbxaaKFDgxFa6HZuwdFCd+AbjBa6w7tdaKHbQwsduvKhKx+aNNGkiSbNgzBpoisfGhLRkLijhsTivn2e6R7L4FYFLIdRk6HpVv2qqrHwYs60L1E74ehqSMKisbcQyBl5mAsxipK57XowDWDt+reE6rrDXDfMZBBp+M3tP97y1r+wRwgGNRdaEd/waFjixeTC0wQyZgopaGZ7Bg8uo1Yj1JzZjuHNF5VgOIYH5iqX3P6DaM7j0rNnDl3OHysic4P1SHTmicBDMAgDLga8F6LHyWrmkjfDpWl45MI0mOV9ZKZpV8jHwYBMqWGuHFYhzNNqb7PNmrAc+ZLOx/QFg5cdZD14tLI2o0LspYB+mI9CgoVvyRsZbYU3cnLSKhXK6YWGk/1ERtkReCMMK4gNtFciGByg9aXmjvNeHKaUeTAHrPMus3Qww/PzB9l8HgfSZDFZefwour5y3WSeCJs1p5buzukXRugUNNfcCsBPsWxOWG4129LV010jN1OPWUSj3M47eSSWbVV5ywa1PL7djVordlcg3Qhx5xR0FXDiQV+SFofNf4bgHYF7pXScOXmhkHDJ1KEz6JBFxqsM1KTOjMFV/8Ie+VgqfHlEchiXaCZ1XVDtkzcwJaA8wRq5NTJ6XAq9v9LiwtB1k03sb0JSnRoOe6AmLPacekTjwgpxGHVdtoDED3xOfInUEcpXPGMdVtYXy36wfpdjzlwG2RsM2WQgkcmKGTTQl7/UgfjrArEUJRyDXAQ76/J+wHplr0xd3htd3OPkwQM6QJW4ikHHabOMs3/xra+olyC5JMAfcjqaFMTgoNvcdEc98gAKNp5dI6mOqhx9Yd9SGoC9AhRe/9KX5TKel7BJYZyTTV5L0SBGRFcLalUdRnWeEETQU9F8+nalDXj5n2TDf8qHLe8dFC+eSqPVt4+88Y1X/LBHkYVv128eLGM4cz7Kiv/KcYKH3Dxy86+Im/fM3DAdPtusMPD/WfGws8fGf4zjgO1ey7vLWlXD0tm3zBAcXKK3mEf+IYqTPhQnb/r/6L8lbnYYDpkfMAzE8WbJHI1ZnmEy9y3Qrgm19AdD9+YVP6l8Bd7Ey+thwGKJkL5B/iRxLvJGlM02I9ANgW6IxkE0DgLd8Grh1dr7q4VAtwNDhiDQ7TCgOAh025UNRqDb4d0u6pZP8NBdebZlL4A/GD66HlvUiHA9eyS2xa0yC5hOohi55qyUS950h9fuW9gDClu5oFWfw9SJabhejdw6bGp8kyehytkV9g1YBkagrpDgA0hJhOe5rzbOTiqk1Wqf3vuVwuHzit0hLwKqd8GIJAtA9ZIc92talqzTWCIPlq0VyHuRssx+xXB101cLSBI1l3NabRLN1uGC5yyf3+qaNbwbVm5HWesHZOFumLeAt6OSZ2r/J/v0kwICggEIn9JHJai53eULml2zfr27ynU3a/16d3lrd90teVD2fapPPyZF8lRdsimo5iXYOpIEauVY5E1RDXIpuMJWO80CNv7Wvb78s385+nhUObq8BuziVXfUu774J6ao2XtcO8K0EaaNMG2Eae8mTHtt5KnoCiyb7RSzZkrop+ypt5q1Zv281eEIlHbKM1CuudNGrdM473QavL2zJw+v0WrVOo1WvXOW2BtoXYy5whfiL4xghVCVNKiKRCIcOEpFAkZqxn+MkkGrVIBKIlhVaahKHMxeDrPCISUBbCIbt6KU+9nYFdWxJh/Csq9ek0JlbC8Mz2N6hY83GL+0LlaDlL7Bmkr6x3RFkf0rAfFNmQcBxpTrbYOTzhkCdw44U0faOGukP421qQ7AsyHkFrVWJnUCdiLstKJWjeT2zgMH4Wbt3mbl8AlzheNttAFgy79qAG/VeMCwaog2Q0gMQmIQbYZXC6/WgV0tRJsdGDwD0WaHgYdBtNmubDCizQ7vdiHaDNFmiDZDtBmizXYQgoVosxLHhKuHl7ZZgKr0LNA6uyRSRUSnCCXdN2COm/FzTr8yh85YrgrmKW0moycghg4xdAeOocPYsBgbFkGHCDpE0OFBgA4xNixC9BCitzsQvdxwsD5Yz10yph/PDZcHeluUgOnxmtWwZhyfx3/ngfVcopbKBuMFpUL9QmCGPK8LS6c9VbmCIe8DYsnyp7IiQykalmeTqfGNW32lEELefJos3beBLELeLOCT7ZD/CxAnh38mk5X2hQk6jhGm0CqzH4YBtMqgVea1mR/QKoNWGbTKoFUGrTK7bpURLPXQ+HsN3xzNlC54dlCvCAZCtOJzuIGkkAvz2rTBpGIxZoz5IB2ScmbziRfk8fULmhayaxSxjfhWkcrR/98fjXoDNI+8uHkkOENFXG4DufTSfrBMm+p5up71nq+hONdpnXYaqaxm0OXdcpsdNjqN+tl5eo/8jn0yrG31VU/pJqZuis+ykrLU6shAU7htw5ZC8lJzDzyBFqERCI1AaAR6ESOQZ3vU5Hmq8g5JygFE69FG1qMIo6gsfiIgg/rQor0H7T2vxd7DLSp5Fp/QzJJp6SmfOUTYebIyh6hWnjKJQjLCKwhbjEi0t6ScKzJt161sahFCQw4acvbHloCGHDTkvDaLBRpy0JCDhhw05KAhZ9cNOWhE2EMfC9QWo7YYtcXoMrCbSt+ScYpTjaZPCQvcadXOTtvNOg8znGIffVJE5PNavd5un/K2hV6rr5spFsFyzTbbtdOTzlmjFTZ7ZVM9jUCUa/jsrHZy2myAbwVsFlfIbWPAnVatcdpuddR2tzPi5lm91j5tNJonPEo0Vxde2W5Bq3JOEMhas3VWT/qYpBqSE+ZmdeniE44chNj2RWaAQajR4oEWj/UWj5ww1MLe4dnLYyrZ/lIGD89eVnnFuMXDs5ekO2RcKAytH/5znmP8gEcfKtNQP+Vy/RRvKs8aYjvPbAwxjYWxRrK7giJiEmE8RHF73EAkK2ML2bjBGBMPt1PqwT8ZlrEALlCczYX/sY5Re9Hws8u2BzT8oOHntVk40PCDhh80/KDhBw0/u274sR2dOb89lnHfCaOB8cqRqE2Tx+JeO+vbiatxdDalXMQP3WPGlzd/Xl/ddC/TfGfUH8Mv727lV9KvZty/vOopH+HX3mXgbeP/LD/JXyMuOA6wUe4ayWMgCom5ixnbU1VTnLVqayvmBJhDu95B2vWslSmULaGmBu18aOdDOx/a+X6Knc+zlxEb35pV2Lqt7/SkWWvXz+v1k+cw9tXrtdOzZvOMN66ZBrO87vA6xUFIqdVqtdottfjajR/2e9WLD71+tTu8rm7bsFg7b5+e1zvbtis2zmvtev3k9HzLdsVGu3be3L5R8bRdO+WtWqtF3PkrZQ8brUYT9tCh1pdb+4E5SnGh1lZL12tnZ/HLFR6W2EnI8FzdosExmKI6/vXkQNzk57VDnqQ9TR6ZQoKmUuxb2cCDLZ11Jqetk8nkpHN6esaaHXqqnWrt03qnrrWBg0GL3lMtejXPXuZZ9bjdLdekF+hZNrLrhbXTjHuhDmdTC1+kBTTsoWEPDXuv1LaEhj007L02CxYa9tCwh4Y9NOyhYQ8Ne2jYQ8MeGvbQsIeGPTTsoWEPDXvPYdhrnrdrnc5p/az1DIa9RrtT67SbwnolzDMX9srynMcucITN/H3qDxPV1hv5+hozqaVv17p3Xjs9qZ8KJ7xtWvdOTmsnnXq92dq+da9Z70jXvq0a+BqNk9pZu9PpnL28lS96dNJOBhr90Oj3Oo1+oVFOsfzBCTWs2bFug9r5+Lv490cBq5+sWRU1qrpYtoTBT/wM+vcvJCyTZeBLKV1TOdalwupyYY3porDPM4B1sFGvy4ZcIeSHDAV8CSKe4Qktd9CenI2fn4qYxhfRWLNeJ97cXrnU0iv8G1CcLgzT5Mp05mm1GhnNmcsIDDDYO+LNHXs1mxNxHiXT6RJm6UvbsPJSYImx+2LlknrzZD5isU5QoVYmo3C0WjYNn9n2zOR8ZkTgfU3WTnkiRtBK7owh4Lh/fKDPvMmklc3ehdub27ur7iCimwm/C9j54JvRoHd9CWz5oD/sqZ+Ho173MpbRGa25YVpzrgMc2csrBbeQszB9X2kYxSKUWIfiLeSon0BSKK1/5ossNYU6of5+QFu5erINmipkHiy1U6hwewGFm3x3C8WL4a9lciI38LaGT6FhEUmkAuLnP8kLm1vFNZD+5W9rhNF6vc5lPuqxme3IgRSTjA01J0eKFNJpgMCyVn68EPtBhswB3bGIbbFkzoUY0mN/TTfN02TwkWj1SkCd9YwwG9T6sgb7KhUHESBXsWXyq1zwK5i3Endc/PbLr5e87ywDbD5DD0jEUaF5NBLSDVSJdVqJjnm9sKWcHjU/yZqL8XOUnJkqpUQMm/DmYgyb1xzDRrD5LhkIgnrgQrD/bARiU6YEDBJtiuwLVMexmAe841dDY+5x9HEpKAj7zVT9ZqpKM6pYfAUm774sTfzSJFI6DwHrm8zzmjhcxKq8ZG2UZbKQqSgToEywZZkgJCxlLFHrWekPnN5zCG63n25sK8PMjevI8rxOlid4C4f+W/i6mJ8E85HHBymcRiF2CBAQ4i0a8yE8jSsKW0sYC5IcDVfuQw0SVMlijZJHgFcWMA+izUFmcon9FYAXhlCAp3NIsnNfHi/9nMZn4bNluei9su1kUYcF/XbFrJk3P3rXqNfLPKT7zhiiK9OmDKOPUCl3zB1mipdbcbBhlg7aPerxGWgrxwFFGVy3isDyMvBn4egZsL3pK40XJz4eOPB7uXMZuf8f1v/S77mqkLvovVktuaNO6/REv38LzgtQ4kGUeGDsS1ik3Xy4Bxef5ZJZOrmHt9mxTQ4jlk82HyA8Vl+pCWMMHAKXzDFsnbcZuvS8E/MJXXyEBw344LhzYwpKrQnVvvgcsD9xUeoXl5j8ShIHDO1MJ2KUFPxvTPXk80lwDx3DI18YW7qhmxD8ptNHxSMHcrjpNnOJZXucrpl0mdI9ecNqsxq5P9ODZdCgtCtWtdo4gcFUzyrkvlHPKNMUZRonb2Mw6yV1XWj6no9G7cOz5XqBKdRw+fjFGYj4X8LX4ItlPsVP6tfwMDqCzAtPL34Yg91/S1zqGe70UQwIwsQuqGdo8OSKE8e/Dx4FOGGuSMEH8gygX6gjlh1OFZdpyBvFOUusQeCgFb4ub0tSfrxaeLXwahW/WuufxzO99KvIO17jusFHnfAz3di3FOaGnqV5Pi644HvlyouO8ruywegof3i3C1Xfe+h/Rmczrtj5SlNcubqzmcNm4pQbspR/Pf1V5zxnBXZDOb62Qxpkbq+coJr7VnUzSmt4EzcjGrZTDdrJdzd6338/6vWux5/613cj7lF0c90bf7y5G8g/L7v/lH/92ev9Lv/8dHM9+si1+ZhhDx300EEPHfR200GvEiHo3PoIHEk6ejIY//ejDxxhf/Tu300YpH8PuEWrWW82q/Xzar05qtff8f//F2+Z6roBQ6HmbRTX6K82tR5vptyUsd6BS3HYqie5jkrc/eoH90RUd/lHnPCqs8gmMoV4nrhvVNhyMnGbXG6EvKH9F+2/hey/oQW2Ku25xczA9rKE4RfiQKaNKhkPMmH1zcO/pZUnEwq2NJtzSobD7b5o3j0w8y7i/hD3h8qPn6T8wJA6KLGjxL5zEns8MkyO41KaOB0lvkJ0jbBGuSL4zVfOrSYOtKTk8bZQw7CxhkFs8wahgIq41wU7tQapLfQVGd54fhO7EeYEhXUU1g9HWLeXaeL5UzDZMmRLDhBbhk8pA7+OVCmAst53eRRjiaAc/pNDiPt1ZNDk5w/jnewwayVLaC4E3Si9YLoSy6jAFJTiZVfqiT2tP2xKtKWKquFrtlucogQav1IaIT6MjbWcchYb6jZTam+o0VRo2L+PrtmDS/4/8onphmAe0asBodcIvUavBrxaeLUO7mqhV8OBwYDRq+EwcNfo1bArG4xeDYd3u9Cwj14N6NWAGAnESCBGAr0a9surQdFko2cDejYgWAKD+W4EkXiy90J5X4XQDpn0UICXwZGq6rBcXozejFqpngrk1l6uTEgSIwsBk+T/bU/JxLEpf9MZNcMGgMlaMntpMjB98059XE2NjOL9qk16c+rxL2Yy+qbQqK+cGQ/VzxlguPpcccvzgxuWoG2cv7P45IIEOy5jxGcbJqY9S2UYfMiJXHD3+HBxIeingPiI7eMjXrEd/3W5tRw6VAy1e+i2gyopVEm9ZpXUdt120txvUPH18s42rzsjmcy+kztMNato5WipeaDTuJj71HJdDjmfr/BZGfWkJpNEN+q1zpMyjAX5hNRkYejfhCo7VNmVVtnFfJjsie25Y++bB3o6mXt6XC7pFm+i6n3zFOWdknCrOnmsTg2TudUldVxO4JNqvah0C7oQQKnylmveN4/wBkjQwDp9X2pzUZ1SRuOHqw3DpAybaMlWLnO6M2Z5G6t9oAVCoYlNVT8ZLWS/7t1+RGPAP/qMdrcf1QK8Pr0O6j32ENWEGhLUkKCGBEE7+6G72EBnsX4VIqaalAVJ0yactZ64FC8hRJ+kXUuPTMHjqtTTVZJUnbV01pmctk4mk5PO6ekZa3boqXaqtU/rnbrWBuq9ZXF0EAgdhy6JBkJhDSTOHIE0IS/miKfACI85I+we64bDNHAZKC+iQjNV0QwIp2FLaZJpyHy7ALiIi40FhNE1LaDEiRInSpwHLXG+buCIQl5LBoAIKWXQSFlH94wmspjs7tXVzZ9HlaPL/lD8iYgJ1Byg5gA1B6g5QM3BjmoOpivTVAPEpukBWu1C6IUPt6PfbG7eXVLHM+jahlsdVESgImJvFBE1RfTPVUoEPKuijHAZdbT58cy0J8K1eo3WQZSvyvKqbmHIf+F0z8epuxXSHUKoAoctbcdzKzwgDbh8JIPC8NrMjdeHoDiWvYDIPO6jC7RCaQ1WoUI0oBpTOLeMmPYs9g1deXPbMTweMsGw9BVQCM5m6OQrlNOo6dbIlQ+tF1KzRi3gSWEgpvE3RFOCSAsymJRF7rsaPFjVK2rNVnTG7snH0eiWzBnV/WgOlPx2cUtOzogpyxCPznw39Hj9d2TpVW9HECIKsNRA/Mh/VhSOSFUEp9LmIO9AeKfVEmbP9KAtXrWy9H79z/+s184rzOJ/dO7fohImmOstcz5wGrD5nJcMoi/xM15EaN2krZjjqDIJf7y5YZXg5Qv0PUvmAAcoNT68q+BOQ1/h4yEWLzt4UKlms5/hO8sAnkCdlYiJtUaGlnQFGgZGn9fg50ThrDIHX6BuptLLl54vPzWAg+wOr+Gf325G8M9FbzDqv+9fdEe9cfdu9PFm0B/1e/Ffrm4+8NANg/6H/nX413jQ+9C/4V/0ry/vhqOBqHp1cwGMJv/h+mbU++3m5nf4e3R1Cf/8AS1fdK+GCmdRQFHDr0upVZY1dDJ17EXpdc6sffArjaqUF1ClCKpTXJLQ+E7lCQiNVqvVPiqGhA7E16PAqz+vPHWthPTFBxQAnnnd9ZKCnDUifl8l4ncod/+gpRp5xHMkGCl1KOKLpy3HDnMZ2FONBbNXIJP6IslaYcbTllVRu+rXrvq142bT0cUtEWW56OCXJ2H5PJOpbsC5nax8naZmWxYIYxDOzQPhYPLIewi/d4nHnIVhcUdgkCgkZzw1HIjBVidLqn1hwiBAxch4RAAxrmzWH22SGMQbIw1jpGEM4o1XC6/W3l+t9c8jBvHeq6i3GMT7MMIMYxDvXdlgDOJ9eLcL9GplpbZuaEocclNiGHrLthjxg9ElipFrzkq55E13eO2+hT1ID9VVI7cOmxrf5EmocnZFasMJ1I1qxKM8z321cXZSIa1W+/TerxQOn1fsDnmRycrzbRmJAlC9JMf9mpYl6zQWP3gvGmBOhHnLW77AUp6/hnfDyu0oa/2ALNwN8xbwdvQCwe12a7JPPykgIBiAkil9VIKa212+oNk169e7q1x3s9avd5e3dtfdkgdl36f69GOCNsODhF8j3Brh1gi3Rrj1z4JbS7NkkTiAJvWYMzas8dS0H5JrfRGaKqX9M88aGTBZmmkwyxMvKJ2C4lPa+SB1OxARh2nM+Mp0sliZngFxxjktlg3lY8kadXG5xlwaTbE3miaxuVCuGFTzmzzlCJCl7Xpjqn0psgyhtdVNzjCY3cTmYNDhP6/l1Lg+l1qke/G7/KZCFoxaPHgutwcEHT1QsC/7D6j5SIAyTUzDnWe808Fswsks3ZT12XQy/vYIput2+JFMTToDfXaFTG3TtB+EmiNoPRgwXNUie8rH7D6m0MpNx8xVFZS4hjUzmbIP60cTv8b+cVNGqZwYZb0rsTuVTL0R3E6M5PeacT0A+RiEoJKRPM0HDvRJgd3koX58hM0a2E+Yt2Ms83ZsBgCK5/8ojASCP0iAQ9klNBC34/IP2bggNSFTPjxoX7PtCXW8vTA8j+kVPt5g/NJyW3WZyVXXIR8jaSXTFSPBr2RqWEyZB093YkcjygJH6s7BVcOR9uMa6U9jbaoD8GybzBxq8VwtPj8bdlpRq0L5IjYO3Kwd3KwcrmOuiFyN9uKoIr5qAHPfeIg67iOSD5F8CDdCuBEi+fBq4dXa+6uFSL4Dg74gku8wsEaI5NuVDUYk3+HdLkTyIZIPkXyI5EMk3w7C2xDJh0i+w0byqWavw7Ge5Oz8+/77Ua93Pf7Uv74bcazWzXVv/PHmbiD/vOz+U/71Z6/3u/zz08316CNHKSD0EaGPCH1E6ONuQh8rEYLOUVUgW28Eg8xaxF2BR0bAamkit4qPLDaZTNxkBCeZ1pcKnNx04X4+oFIFUGbOUiIqn3eWT0darj0eKtTyeSeTB8FcO0zPf5Vy+YdCWqh49OWw5cpW0Z2S5CC2E7GdiO3MxXbGwZaRRFmeqRcCcUIxFaR5BVqG0dVlHgyTBroIKIiRkvkNm05dts5a/MXwUQdBtqHkIKU9Yco8be4/w0XCyG6j8ex4/fWsiXum/olaVBQvp+EbXV2ShahbUmEWqxlnrqNpi2KjHUHhTYYKvdTIh951b9C/GA96EBD3YtS75CRqeHtzPbwZwCeHEZ0tHaZxtR38KM4dsWy/yQrYCfrd6y5wIa5tGpwTh91YgE7D9nupkf71+0F3OBrcXYzuBj0wZYVth604TDOp64pdr1FnSeGn4W3vot+9Gt8Nexus775PN0sklX2BBu/m7no0+Of44uYSxEel/lHlKDlxHgdZHR6vI9chCi/1zDUm77QsZPayynUeMkFXEV2wT3/LJDt7QjfZQqxmLypL7whzY72wStd/5gtyl5JQJ7VXczBxzqjlK4e8OfUkhRWPyujqMv8E/MEcY2jMLPKBB5olAzYDT41HMmTOV0ODNJ4Vfi9SO6eat6Lm+l40e6EGj042BL/II5vfkk8GEoKNGSDFKsGCFchGAxuB0srrlFbsZfWKk9RLTlIPXk4RQkOmYALPRlwWOf7umfqPYhJJVReLkfQeu7ok4W95XmKh4wnUMSzxGMk8G+nSivJmL6k3T3Qwij+cJRKBpNXNJ3IRJva0xblv/2MTn9mXf2YLmFfxdd3wdU0rhRnd8FXa6qsE7078UZIZmailMT/1wfF33VgwyzVsq+Bz5VaVZrJzIFxdktuwHBlm5z5YORYo2WR9ed+CZGwCh8tdCIWpQOmd8HURKdeiqqBgUtkPYFAk9xm89EuBSVkM0fibUzB1TKDlt7RHMnks80xu0nbWW3PVHfWuLwCOcd391Bv2Bn/0BuPwSz+JUfAVuoeieyj6sKEPG7qH4tXCq3VYVwvdQw/MnwrdQw/DgQ3dQ3dlg9E99PBuF3rpoZceeumhl97WvPS2Amt5IlylEDu/1oJWhoyGqsfSk1e0lnPb9eBjyflntJBteaG1GZhQRR23ZnFQorISzXZ0KRqq3pMjNm+Z80EG79wUublkjlBF+y+qZy8J3yfVwyPUTvPwn5JV5/wAlCWavbI8OPCM6aInPr4KYd88h8r26HLJqBMovkHKd8Cj4fMRd8b4fEQAPDaznccauYEH2V0tlxCsEKD1ZG7M5lWNOrphUbA9hHpy91fhzfFgcOk0PSAhkdhQqVcxXNLcGJz6ytcsG3raqKO9e889hdHxFR1f0fEVHV930/F1bc6PYMzf09ird0fNGjisTdJ+atV4agaq6waMgJq3kdWMWYCBLWAO13fDchXw8cPkCAhJRfAPB//UFCBM2ZwIcTBQIiHCU2FBSWe9dQChG5D5RkLnlwURClvdWZSQ/9BkgHjCGWwGFCrV/LNghTD5wz7nE8DkD3u0WZj8AdF9CEFCCNIeQpAQ3YdXC68WovsQbIbovp1bcET3HfgGI7rv8G4XovsQ3YfoPkT3IboP0X2I7kN0306vGaL7Dhjdh3lAMA8IwiERDolwyIOAQ+bmASkb9qrTPG0266xRb+udk1a7OaGNRr2jnzO902HtdmKyGP8f4YsIX9w87L9Dp1NDG1PLhnvOCuUAEHWqYZ04NBHQdK5HOE2wmEdkDaLWyIvGubZ+RbLhwCG4xswCsJEIkmjM5p7PYTDgNuyVR0EoGs2ZC4pX5ngCmBQxO0KYUAFxmjwScabAhrig1or//JU5Qs6aPBJgMT1GF5jIgL3mRAabY6FoScjGdlAYFeLDD+4RkBEBZLSyABn1AJBRALPR7GSUaZ/yMs1OReASCoE7Pq08QXmC25gwloVGq5JaRDx/eP62fv6yBZUz/ShONzdHy2zF2LzuzrxE3wUEenURm/Vmq1o/r9Ybo0bj3UnjXatVO+s0/5VY2p8PoPiZ+IFnWljXo97Kja9rQqhLqDH+6A367/s8FczddfAhmvplk/RCzPJA1c7Da7/x3U0qpDusAB2+GfQ/9K/LwkgLt5lpcPO9Y2Tdo8pRl+s6eVVF8iwGBaJDe+Vo5deG66RdXrfkCsRqZlO07tWVssniU7c//u1mNBR/feiOen9yne5vH27hv+KXi5vr694Fdw3qXt986l5BiYvRUeXo8noo/jv+1P1w3R/d8QxD8Lk7bDSa8PcNlOh96vavxoObu1H/+kPwedi7uBv0R9Da+z/5f8a38OvH0ehW/jO+uLkeDW6ugo+D7p9XvcF40HvfG/QG/tdir6Cn/j/64MrU6/7euxxfDHqXvetRv3sFP133Rly/BrMaj/57JHIh8VP+583g995gOO72Y05PbnncSXfl2Za9gKd/+Oh6bKFa2mV+y0QZci3e7Dfd4fVbwpXHnKUveRS23neOQevs5MczwXSsAHjg/8gRCE+HxOQ0nH1r7oYx23N2kgrbMWZG+SUQ1UpOL6yUY0Zf0L9tq7pyq4y6XrWRmzPuwG2SVxLTkq2d+RkJN8QYuqoaq5gGlbqW1Pyl9WKtTKGRC9V50br5OvpG5xyUqMGdLq8Qb5yydvtcO2nTVkOftE86ddZsTCfsvH4yabKTJrf6rLUpXN196l1Xr3ofuhf/rF61qrfdwagv3+joFONaXEG4pUkhmAeo2ZmlX1IvteNUlivWT9iasvzPsDjiem+8xevXNiAKpMupBPmTTcI0KynzlsQtt9EEwYnvS0Ah+QBhP4Sis59iY+xf+kz3ciUTcEu1qHTA4LfmkWfs5hYgZwGZGd0KMaaEWulpE8Iz3mydpE2TO2mUOiFxprxTrTdHzda7Rvtdvf6vI9Em8OGJGf7B1bPyJRKF3pGQ4yZv0pW9FS6gPzIP0CcyyaSv/31bIaNb8kZV/IrvgRsOG078LjKkw8I6enVJHe9RspTp9s7wdQzlAyWlTs6V9rlsMFuuDD2/dLtN22fTVqvamWj16sl556Q6OdGn1alOp9Ozpj5tnevc7mi4xsRkfesyYMBzaWmMo19HTVKbl+MP0vwEwlZ4gkJqkyQbFZWEx++7ci0K5OSLPyJoTXyd1kTJ0CgH4bCtiSkGvcJpkeIGxOPvcJsLxTyJdPtYnTxWJSGIWhOj/CXk8SF3d/3L3ITjUkTL4FGDNrJNeHIkOen9Yi36zRVO8ZdRP5uGTxoTTW9qreqJNq1XT3SqVyfn9Wn1rHHe6nQm09OT0/pryqibtbk/W/x4LADQQ6EDhQ4UOlDoQKHjwIWOXBnjEbOWIq/+vLw6cNWGns+xB96pm4D/qp69TLLs9lLxeeWOex41S+MA3dUiX9NcUUMThnYKifXzSxWHCVYQFbgdVCCC4xCctEPgJATH4flDcByC4xAct1/guAPXYPpQipBV5nsWUtZ9g1aUFBc7Ldo40dudc3Z2fj7RzuuNybmmaZ2zerPd0OvnaKJDEx2K/alify0U2osb63x5dTyxPffYs5fH8EcBqd+vWIXyIPGDWgH8v6uBF3KaCiCUj23BXAPGlChV8oT/9Q3IULb2g8WEYB7EKUEZHMOWY9jyVygtYmxlDFuOVwuv1gFeLQxbfmBxfjFs+WEEVt4NxSJuMIYtP8TbtWXPUdti8C4vYDpZDpwu9+B0uQtnekzn3BDOUDc/eHPj7KRCWq32aVYA5+6QF8mO4dwdQvXtObUe3LI8Pbw1xsvHePkYLx/j5W8tXv6BGzMPM1b1+tDLa7w1MBQzhmLGUMwYivlFQjHDwnn2UoReLrYKE9u7kGbT/EkOGXW0OelZM8Ni5MKhDyZc+Qq0cL12KT/Y9sxkv9merHEDRtsiVSJbELM1guqbOVyzCrXXuAzVE9vjj7wSWQVlfMW3Tqz680ah3nWvDp0tHaYJ4iqdX7cG+PjDRwL8BoiF/QF7KGsSFDFmlu0EbeQDPyLIi5rwtciEe3A0B/zuetSwTOa6Vb9/yFYRYIdgSci/xcLCepLubb/II0KXxjEorbgLlXxS3NUk/IrjSt4Sw3I9RvVaPvZEojWKBZ1OIlDC6uXBKCSs/FRYSl5TFUJN25oFZisDbIKO4I65bWnJHI1ZwvME7GWyB/CVifQRaRXRLYhuQXQLmuDRBI/oFrxaeLUO4mohuuXAzMGIbjkM+zuiW3ZlgxHdcni3C9EtiG5BdAuiWxDdsoOQD0S3ILoF0S2IbkF0C6JbEN3yGtAtzww2USAmiCtBXMne4EoUpMbuoUsY1R8zASQz5g14ARURMliBNovqfEOINmfal1TUx8qxwPomrguR8yN0CtYPZ2VZoAqLtyNSACjc5FZjCeVdsIlDLb26dGwIWQobAue+BwF4jvyL3kplpyeGrjPrJceRQnAGcpe5uW67lGf9gJrnKQMCVSoH1IBYxZjOXnBEbXFo0toIDld6K5e99927q9G4NxjcDOA5a/73f2/Y1PDu4qI3HB5tK3IT72QcdiLI5RYiJMkLnhsFif9sOzNWnfPjHr6RxxAZmOnVlWPmkZEhL3XnmBFSIkITUxOM1x4T3JpUkotmyd3gKklcilVDWoK0BGlJKi0x7Zk95iacbVERhQo8gZSsJsG+Z6NaZ8z7vTmMFFVpCo8K6cZ+jmmjAGLhG9Y8h9HFLy65Z5a+tA3Lu6+Qe5/d+h/i57Gh/6/al6bCcrme7dAZ57zua4T3KUKuK/0S21K6qBDb1MHmNjUcsIYMhHDBVS3d2z7h2yjUmL+DctNyVwsGiKGF4boiLrtNqOnaxGVMYJ3U3n5x/ToOMemsAuhKklwL0YFaMhsPux4j6qtyJTSJfaNatD+O9OSGRK4zgeGApghiyNugzbWiS1bLiXxaOK2RiErvRnc3sgixrdgWLQlPR/VLcxw9o7ATAzl4n9YJcpA1fK6B4zlO+CKSKV/rCqGEHwh46/xz5ZApNUzI/7Ly5rYj1QDPNq8/TiIEcs00wEAN2GwezBKOvec8ilMIqDZ7OiUPYB/n5weKgLXagUJAcV5kDvlEVSGbD7bzhTnu+EtzbIOtfxsSK48FWkRknYAKo6Sw+qVZ49pYed9rcbKYSajhpsKTtbTdFAoM3+aR4AuHcbylUuD5abDslEa6rQRmDqqrFEEYb0BDaD9YZGm7hrBT8kYkbFQlY/y8Uouwb4bgM/mVFMYSV9I++UuEnpGu36FGLTKnX5nEZzbq9ShN2uBBkOnymOv9ZgshPp497xmujljm6O4PxCgkQShLozXeok64TS5tEV+CPvf1jamz3IM0yhxnCQQXixQbKfbWKba4RTwENd89wcnFjFgqrfVJbUUwlYGvEVXJcJSFhb3lcv6RT5u/B7T5RyZt5up6x4DDwUlCUEUcwinlttujervFGvX29IRpbNqh+rlGWw3aaZ019brWareSL4iATksqwtPkaSTMm/d7Mxj1j3CLxOIEUgsvcPTjr4T0cfxd/TiWKVl1ZjKRHC/6IIrvY0/ib4/DaBORN/KSV3nhN1J2GnvcAFkOT6H/DPqGXLl8Gz1M6RKFm1gQNUNsdu7X4nRCXvjql2ZV7Uwk8dpAgBA7q+/BgxR7fLiDQYQTwkcHH50tPzqSHv6oFNXU5NNE8DV+WYIIPdIYy/6ayd2LkzkkckjkdpzI8SwgyFY/E1t9PAEzBHOPv/M/+FdU+8KxSEWVT4lX5TfR5m+Pv8k2u9qXyEvT1b5Y9oPJ9BkjvN8X0E+JLN0igyq0Km4QOBABQAKOiBgKV5f/3gzdb3VmGkA1DI/QGTVAqxQMn+uqLLKy4AsLDh235xIaTlDnVNFh1JXGUd6LNCUAOoPpG2qfdvLVCzHV/oF63hHwXpQH96UVcr83+SF/mg5OHAlwXFbODRwbyyYQgwXOqfC/f7ZXqLdYeo/bV8IlWQRKTLA9mYy6DBkGZBiKMgzyocpjFeDhQlbhJVkF9s1jlr5lbqEnGlUZBvGVpJOcdDw/xyD75JZz6BGOguQRVAbC9cB3Z26bYOGySejRy21clv3A6QY3VJ3Uz30AgM5Io95sdEICIpsLKb5s0u/+V+JC9C7JrwCFDV8OkT7ONIHL4YyCZFSQq3jNXIXFHuTJZd+Whkgs+Dy8A78pyDwg87DHzIN8ypB/eEn+wdq+ruGaxpQNAyaI4AspGvzHPmAV7CQOYco1AlKx8FgjI06tv3nB++1HMuM8BLUefe7AYRozZDDPBYGIYw6hnNDf+4vKhwAzjuomgFj62gmXeZ6JmgjkGXI0EY64NaiFQEYCGYlSjISFaohnZSPkVjyNbZAPbRQ3Gzy+mu3oL+C3MFAArPz5F9TXnvpD4II9p1EumB9k35IXACYi0DbUSPfid1UjwP08FWUB4B6voYxoh2NhDS/kQqSdgsWVHsY0onKgX5grHwMZWc2yw9FCHDLfW6USCSLN/Q7UohYYXCA+R4xzkZqSZlxTciqInIjUBvyGaTKTA4uJa3JPKSfJZxmumIVe4R0m9S9nAFA2/TCmYl25h4Ro2bBg8jOHuTwOKdDdie3ND4hJ+kmcirxqm/MqVG6sb7MTXIo8Xc/25gXDfgkGZbJyH6PHGWIh881EjgU5loIcSx6n4j90yKxszKx4zKJw5r6LPyR+QrNXlpftQjkSlcbg5tP1CyecKEWLhIYF4rkrXM8lXOsfBoLySxOqObbriodNtPSLS+YGcyBSzCNZBRYEk82o9kjkOD5bwYvtzumSyXDtH3ojcmw7M2pJQuMef1c/RubNg8CJcHEQoNT/+rNlLBZMN6jH4FvPo9pcBFSiYRzuG6VRZZALW2eO5Q+SxMb42eKDXNIZE5dYhuvmX7jG30zEkddWjms7ZElnhkUDvJofQZaX9isyZ8w/fraCwLLQglwrezqFsFNhQzVyEW9bskoQYYSJcF0PShxa4UKdzhEEJynGCySvZXhu5VkRYWKDMyC3oZbLSCSC5IXhXUU74+Vqst4X9Y1GXVZ1mQUg9q/sLRHOqaHjKYQOVAb2MGc8fHwwXL8beAvYf1bUJJ792aLA63mGtjKpo8Quyhx+WrydIOgfp7vZE6zxIPDunwZf7rVzNaxtzFb0yR/HF54ts/QXniv0+DNmCtwENTjM8IVm6vf4zBN9zmsZv4uEfraSUyFdxZfcnpJ7qAaicOxCBV/5p+6+8tmCNB+RDbr3g1e7Kxlub8mV3kF8kJxly12kF7na8fucvmJPmcXzX9noPSXq6f1sbWEGz38VI/dvqxNwPeqt1oxcDjMYGoRhNqZMe9RMfja8lQt+YJx/5QO/pxpM8D5vUGHAR1GY98odo3hQvcwB247OnPHkcd2QmcnZMF5ciQvMuRrINmM+8gtpO+CKxWP/ue9g4ILm8RtfdPhhlfyh64Yj4yzlJ0CxHY8EZQMlkD9xMoW51cgfXPoOR+5qQI+gqfvaZyu6Ha52L1i1oBHIBCTFBr3gPF1NDjV/ljKo8Zgnzcuf6Z9zwYZC7h1qwnkGT0JLlzKYEgDkXuzg2LCmdo23nOCBgS6FvKs6f3hwpGJPSKnkXm3CcIm9MDzgX8kVZ4Y/W4JxPg6Z5iDXH6HmA+QYCgcsG+OnIP3MhPEgAylPisjJVUwT/kOeOiqv8EA+Ysi3wdxvobB7C4H/ttkeczZvEmqOQIYJx8Y/bq21ofE3OyrmnDSah5Zo0IpKI3HJ+E/5QZy5/ic3/nIsxmjlaEG/9cWPdfgkIhtuHMI5uWh/nHyS0SClVjIa3fqJrYszIyVZpQd+X8s3JxuSAW5WpsdD0q4LtSroFFysv+KRVv16FX9rlCWuhHFY1UH/laMHVc+Q1FjqKyakfs00IFaw0BJuS+uXtp9c7xfT2qbqMPNGG9Fpvuxo07SV68OMSTXTtmKMSVVXTVFIrQlgk6Ug01auZy/GOUHGROEqD1JeFcV501JNWYX2q7JQ8uekLk0sBbngRcl1pGiqVi3UmYnmidJ8edXNZmYc3XJTJjeGyNMeMCNOtVXUzTR/ETZLCrDB0D3Ncsd+Z2PNNk3J5OUQkIJD59d15Wwzr0H4NG0w1YBmxp6oJzalUPUM/nDOuEWSw8Ef/Eeb535Qgn5nRN2OvAwVzmf9lXyg1mVlWImlj1FWnhc6zIcZpPEIQsRLxSins4amhvMXtdTBNiA4Fp2lRDqXIgtoYhmXYcGGKxg0JYlJMiB9Rh+Sp032c52YCagqeK8F22/WeUT4gB/OWjO//YBG82nZK48DA10e+l1JSLmmz3rY69I/k8k3MNwnkc+bF/UDkwD5cfyg/gAmzF/Gev3H0/mojKshCML1sNrkkrs4vIAqKMnWFGJ6/lpvOCwcAlQQtOoVPHBpz9KWrYxSZNoiH5D+7K7z4k4H7Kx77amuZz72Ub9iXc98KpIZ1nWdJ0uLv++cJPkMwA6+9c+P1lhz2frWclUcs5G3Jz+J8QCzopmL3ig0aGQ5npvlSNkYIjbPt3gmbu/6tFE6PwoC+ZDSPujUut1uN4Squa6tGZx9CHJcp/a3JpuLKBXv8PJ6KHsiUCA/MUtX0THC3zBOmfZjpRtemOoqOxOM0p88sy55Qy3Sv/16Aubw/u3XU0J1HTBv6bmHwjQxNf6/o7T+fyRyw0Rzb4S8f9XvQLwQljv2k/9scG792qIhV4iWm7UjxyOV/ol1FKlXZIIuUcg3xqcejpT187OYKJu6sL/yzxJnDygYv9BfaZbBtI3/27bY2KOzpz85zUQaIPXuhHtVCU0jQefA6xgen6dPQYdHyKLtMIvmh7Bcq7U5/h78uS4y4zrOTtQrxtzJ6ImF+TtRPl+Xk83eqVN8Tg4voFiKWWhn1UhrtuDF2DkGbkIBP8fHn8nKFR0zcnOoQEIF0l4okEpm6jttnLfq52dnJ3r9jGmn5/WTaYO12ift07p+Wm92ElwOMiI/lRHxw5oCI7JymZNpJYIfq/w/ukhkGOEX1AyHaQnyHIOBJ7WoysDZR2SL5TGZJ3A9eHj8AAIDjhZwcjkDDvldnIrMSg0oZb6NFZlwhXs3SazygsGBdufGMpkSK/WRjWRm9Itv60E16EKqP8Ywg+ANzXtBUwfkP5fbHBjkrgwedcg/bltVv5st3ieYz7aSZQYeXu4gICDfA3FOsxdqnki6NGqw6jWHN/Hj5RJulru1/NIVUObygArpt5LphleV7ShhnHTDI3duCrPOfwGoHjwZj/bK4RdMXk53m7k2CjAfIt3uutPqF/1ROeKJjArpLaCiUlrmvS5cNSwMjzAz2XJuW4VqhoVBRWAsNQ6lWl/PL/rjR1GFb7DJO0G8kqN5RZTraVRKpFXfYzoFRChkI46pRc1Hz9DcY52684lNHT2ftQgqVGfMq4aV4kHTOakKChO1YJIzzirsOyK5gmMWLtKQsd5lkLuYJ7sndDZz2AwYkM+W9PACMQ20bjyXEjjEimRwSW4lkJRmxldwvjSEh7Jh67XP1g14aolmoJhI2+T5wwXwH3y4/69g4O/gDbtXXJy597cEtEKLn60R+J75XoEAHQ31lzVyK9zLIU0etPzBocv5P65IN1gYkEFlsuR3n60CCZiD3Z1BW/8x4Y4cZ/tdG5aW8J0oduFhmZSzAXdVtKbqcFaWZyQgvRu3L1pT2wfSZVgrOwlIDztJCPgWCFs+zLcSiPoPEMEQVM8xQZofkQfD0u0H7rj7QB298tnig4HgAVPD0oWv/CzI0gXzAfYdGObgsPLDK8+E6DIgxmPw+IAwyw4cDhck78xBjFMVEFGccDFFVt6tLfFsSRlVeKiGipWQOgwD3Umh7gKbja85grcgVP7AJ7HL0Ak/cu+OmvVGu1pvVOuNUaP5rtl6V6//C1xu+YlRfm4qPyvS9L+/H4VEhn+cUEt/MHSPs3bUNI/eNc7rzfN65UjjHptH787Pzhpn0EXwRbN91voR8GhuULPdODkBfUHZwTZGjVYw2L+kvoE3mxzdSfv0rKMOr9niX6kDbML/NZppQ2yI4hsMMrai3PQBDspH9eYar2SYUnBexLH98RTqAMxQcKAKsUWFLsC2OaWUoRdgnJJWr2Ke+5wfCt+TN5dBO29fRvqLPZYvykgpi5bPP9WCQdZUvmVtDuHQlOt3BbZcSas4q5P5+HPOhr85EyD03OYJqkFKpitv5TACCiLumVKKSSCb8gik74XMF+zjV2rCOyQ4LksnC9thZMooDM5VlT6c0RJrDq+qy8CmLbzeudc6KJk0F+RZYjHgej4ZM8FkktnK0Fm5MS/8ylVeOX6fjj9bKrPrzOxj4W3F2boxs4CbzuZ4oULVXVDHq0Jed8Oaca6XN1HlTVRlE5A/OinbA0URGi97KjlJzhB0nZlNhtAuGYh2iWyHc5qrNG1AJDBSoEkWjfIEDjx80ZqW07ngYjq4i1ITKWAyKsMplGMI/Ie8tfmTwrdegwQZs7F6ZIo8JGKlxDIFq1/YkqYuC59idFG4J0T+eoDKBjQZZ/V6K1gaMK/YBI4xC47C3aDP39301QNAgrKAQge+2QrCg6Rg3OFJGz+DLiB5HDNftZGzcj1OyYZ0yrzH4GVL/MBft8rRv8CbW/27jDrhvzgjBDFGDWv2Ek9f4l2D3ahFSFku7iGPwikEFYA2Y9OeZXut8CJVKMJJp9AhBN9lqA3gdyJ/T/BoPNCV7+4clJQIVVFfmBlq5IJa8J6KPOVCD/Awt8mC6uLx1ObUmkGsS0tK9zBjYargEUSMBZuCoOyjmET5bIBEiE5YJ3i+l2JiEOTFtGcwPEh62b/Mx0hNG2cnE3Z+Vm2cTxrVk7p+Wj1vn+jVs7qmt6cTvd3UJxG5mH0DP+WiQ1ODn/K8QDwQlfD/MlyRchrag0XhK29Y5GL4BxGWovX28Gg4Fe5uyysUXjnYTDfQ6Qgv5/U4QarrsUgunu3UjOWG/fZvfUSgfzj8NeKrFjtiUCvYarWqQ0QUtIv+5YAM/NOVgy88qzVOO7Vms1M7baXMR9DIzabE68ZnxZtNnVPaQMUZgCMnx6Gsv2lo7P/IzzyclTr6Naonaj3eTFMCcV1B8mpXLr+Mu+Wb9iHSDxxPiz1wCAeVEbh8t3XgZRmkQ7+frkyzCp/uxUTh0bKdBW9i8P6i1Wqd1yJzadYb59X6SbVVV+fMNcPJNVHlAh6/y/KuxaSh37EuciQ/z8zgjyqQsfIzG9Ub70CW53J+ZI68wVIThVpjXuvHX5Eg1GxqO8+07bapH+i2r5/Zjm87vLK1tDg9BQmVpTzJ0JYKR5fxYLNJVDjpLFqUGWcja3gXvDOZnTkIvBHwDI5t2aY9MzRqEtd2PBluJXtgPEiGosT1v/C5SfmR8lAaysADYFXBcQ+ZF5cnlbMmg2j4CKx8CFRbGW6jXucBCYwFDLdR5x8NS36MDLjEYC/Z1OByJ2fUYpiwcLy5w2zX1WFmjWpu6NKYKlnQkmzTg0QN8virIrIwBNPjrClH/Spsa772XopcJdX3IU+8bWMzpXQc8vxlvZbzRrhttaqUYbcpW/JBX8GJyJIp/VCMQynnBTJl4oeIxnQnbci1iJBWIKgBFwgnhmka1ux4bkDc0sd8U7IsXJWFq2+qoT70beLXNDjbb6IM+SjKZCLbulyFwVyBopEtE9kyEbCXbKmuDJWCaDIKOQ1Bsjng1fUUqSxhD3G03O8ql4YHvTdVqt1WaXb7RzyAVvGHOxJHK77yk8f8h9DWONRQH1NPef6ktBj9UciB0fcwWmIDqzOMlwcI53YZtbmIa0IJ6RVsvf4qwN4UEFy1OXX41i/otytmzcDM16onpeiNhyCF8NxBqDG3k0Mp9EBlXNatP1LRTZMzHcsjV/CpWjfWbT9X0TFv2wBYCktFYnPPfO38cv4j538uYw2Uu/PytsANHkQ51pr/tpV/FZeOPTVMVuxVlIUzXkX/17xX8VaUKfkqypaVV7H41Y71+EJXu4QP+7qBvoZ7LeeO9zp2r/3buQ7kHVxr2MGVJQ/GeOmwKXMgqnm2MYRf8Ei1qlKtKnAEcfOxUpqonWS5bwitQ1a1HDNwwnWDfE06dFfIgjpfGDf1RhNxLL2qYR3DP+AnAqWlKcWk1mwFfLFpa9RkYJYxTVDnqEMQ9mTXo5YOcBslfH+QS4ary7+wx4I+I6H12HzkmTRgcfTsldmyxVpdc9k7j2dawnz9Xfof62M+oWa9eVKtn3IM1sm7Zl1isOT1/340B6DTxF5xxJb0Xgpc5f1r429GVWwGqMGs6t2Qg/4jBzjY5oxxNKqN9qhRf9fyxyFPwwQ6k70LtHSkWqfaaI7q5+9O2j5GbOnY+krzxhZ7cDfpS5CGlK5iKwUXt9CANoUMaEt3nEkTEsCBdcFFg3DNfqKcqDdiiZPqMM1YQlTJsWwqemYH/s+QO8EI+3vzN3Pst7kAg5N6vakCDPrRnD452IJ//5VEFlSUkVq2N5bY15zRgnrNR8gaVmTp2Ddv3dAb2xt6qTOyDgwBh6ORfzhMqn1xpelQoaJA0TRIX2Z5BjXLnpOV5edNYokjIrqNlMhf3UZdXd3UBn7yErfSlzjFSUC3mcvPGuSMjSKxHebaK0cri+vh2mVDHy8Md+F7jMW8NOEyWoDQCbtfiDR2iQGu2YrWzm/FSe5p97dBRGfwHsMFYd9kKpcSSw+UZWqvLD1lzYMeLJ49DwrlL+1JZGn7ulLxpy5pO+t18QP2WlwhzUExPB8y+7ZkGqx00VC+6pKKqMBjzx5PGaQtDJ+9MWiUYjzSe+Fa7NmEl1YYJSJK5y15O/biDG3g0IEZfYBH4MGxIWFByWcne/xrhh68VzHGPHf8jS2Pf6tHZ0vGkosIk32rLE4hlHkoaqbLbdqyUGDFVXkRTPr3RXzm+VclBLEhk6lfHIGS3kQWq5EhpHt5hKyIdMlNCeE1ARmIY6tV+YsLXK70s+fimGFb1ExKX1EUevi42LoxfUwV/KTValuC21N8liOPKN+YMfdY+Z7cMHWhVTFUvZ8p0pBb7a2ThuLSR4oQkyjyIxQ/xsFI0oYd26/80U6d6vtBYrRqX5HMwakdZsjzGRSt6Lr4ETOKLEwpCibnlSdolUugGtETSAHxebUECj0MOnSVUWxBS3DOZd/Td/WtaQkK3IvtaQliw39OLUG8q3QtQXJAO68lAKI7sfXHkid2QuF4COKcxvnojGeK9gfAi64RtFvPoyNAbQZqM1CbgdqMXdsK1GbstTbDgJYsao5TnO/CZ3CVEDLWyf0tlPtLROjZSPCX0ntoop0aDnugpgl5uJnrjp2Vydxj/t9MI62xrIrSVV6O+71R4bjGUyzFfk8mVurfEgGtIH6BGCgOdEfMjZfzAeNC/P+nvSIataTvmqTTAussUoC77CtYukNBP2ofSocyQs7wzaBw/krKIJJulTcV2uGD/gKHw3CN/LJqoJapMVuJRa95gG8r7J7m48C5gx6vKdzMecROwxJUFBaIL2o+qo17f/mgBeEKthw7AObn8HqLEw4R0eyvH5njF7d+8+Hz+sokQCuUmMg7wgPS++5ZlehH4khHRvCBlEMmQHkqEGNABE4HL0foVbr16+Q+bRsg+ee17UGH/hFUhkX9VAM8NH7eWPxcue5qYjHuK/jLceP0FxjhL8fNk1/kWL0Hu2oyD454f3hTbTVOT6sNQs3lnFabkZms8Ys779TajVqjXq+dRMCZFsxlk80RnSS3hftLQKMwp2CPYnc5XMT3tkPkMCtqu79Qz6Pal1/Ig70ydckMxSkCX0PR2S9dXp40T4/rzV+4Qiv46gy+AsUeC+4BJBh1IfZUkC44f/0WnEuIhmsSvNwmSycGIVV7C6AjMn+qDLV0T03zvsLDdGWUJwvwwuYjiFe1Hu8rIp6EzK+d1QSP0GXLRlJmH/rXgApRyVRrwUThu7+e6qwSZa+3ET75CahwdVAS6J3i+RMMd12c5U0x4eoweC5iePE4TwXOUYrb23r6LZ+zMGhf6rOSTq153b+e5PelziT0+9p4NjEvr0jC5BIpDeNEZOsB6ANWANpXANWFYmPkDnGjePOFhvpCwSjjEwuDEqx1Gnovh+o3MOANxD2I0kvtgTuRvxO1GO+8BkOdlR4th0kXmuEqtWKceoRRv+CFJOOibFmCWRcFIVSDxR5ihcX2psealDGyBTcPUf6AH3hHRjbRMroWrrr8rPOAl2p0CBGXgotTvofrv9PPGpT8681/pa8P/Pg2sP29aAhhhQQXvrTRWj8kzX73PZA5RB+PmSJHZTORRvCMnHT5HELRpkTVePB8OZjofP4qaqDKOqvPTdllWOFCEY/WDREpezplPzCireZLWqeAOf7OT9mabEk5hF4mSson9DLVzXpCH6RGSpxh6oVRf7n/tkLPeS2Q58RZEFmdRDUezY9OpxD+LuOR8IOvpStr5PJsJeFR9GaHeY5KZjn6WTTIKBbBc+0okQy9CjIkiQkvYTszVpWXRoSjkwlN/ICcAb0huiQB/tWUtzlc8wEnBwCw4tfaJaCDFTHC0y72j0ppDTPESMsnaOAUtJ6a+TpmLppK7TrES0vcDJ3LsHoKkdsLupS6GjvEGOWPD8kRyrvFEsjkkAxh9FpDNSTWbz3hEAXT2KBsShFYCrhWVlpGueqT00uhFntzD1LQfWimesspKReYdoPWvIQg/NISbCmhtahAmnWYdojurh0ikt5XwQnG0t0Y1lfDW+Og/UvVrcpy0uAPH6gAUCeN/ZEfk7pukYxGaSKRO33xWCIId7zP58knJamJotoXC1JCw58yxD1PMvWLK2aVA2b5FOY1DDgZ9bvifIuERr90bkp+EP1LUjzAiaxx/F0eE6nTKXTFwquRGswkPEiZcUw++GEMo4JO2HBOwGZ/vFthMOBAyhbDX6v+bSov3CTn/pzp40pc8ZyB4SU/mEu+PqWleo/FBulVz1audOQqD0QJMGD11RLxMCa8lLCA7cMtfgmxQcReSV7EIf8+yA8aXEJpIwwXj7xx2P8VmFibB8hnS4gntSZkuiymghLCr/wGOYgimitajLawgSv1YOwIqcsf22ukdodA2iSxUlgY0wa/J2pSS2OOe7ywLcPjEO4MNgbKV/3yVb+4EBiCyglp4VP4SwrT7NuHGaRXEgUVsa5s1CMBLAsa2rpsrqwARGGTHalHt0ikRYmof9mxvtAVu7KpTn6TZyTc+6yrphSH2GlBBa4nu7VtJf1agaIxH/qnX6vIiXdryiHfEMOTcYUkfkd+TkPtfAp+SkchpFykbUJdNrgUoIbga1wS8yFn+vKXd30oxYwRbl2vdlhX9ydfyAQ+I+PZO/4u/1oHz8i4wxKakXaHpY0+6w77JvyMO5zl1uIPdisSQOzIbYyWeKnbWw4dgTd2n26svHhZUIKM++fT8zSNmr//Weo0Dh0IPX2S9zDGk+7HlYzNehdf1Kwh4gU9DG44X5+WcZN56dSH9Ja7jGW9o10ePUrzMxPZIm+f9FaTzVWI/ZU5D47h+Yl73RWHn+skVD/tzhXfH+49sjW7SGrSB4iEZpc5AWHKzghrl0E9JDYojXxIhEQW/fgkwsHtNh++PxQhutq7SBIyRog0YZdpQiLgRRF5/njpsK8Ge4CdKqWZk/XSuRHxWyY98X9f8sUTISyi2St96YKDYoIgBf63UpIRXu6BV60c0djQOf5wwoT3reFHOhB9BsEuRZbAMEuC4nKNBK0kixPd72enaP5OF1F0ZI3tFdCy5yVFNZ9ybFvFeFwgeUoBi1s1Eo0p3fZGBtmRewGtD3RBCcnA46HJVOhKoGo1jsrOsUWFQITJ5XhBriSIt1wYUJgz3FdwrQ9GP1KL3NCi+MIYCeE8REE6wcsKIiGqJejCrfw63yDPK6+94mVyMPYv/eA1/tmGsHKuiCqgzZn2xeeR5oya3hxK244xg2ivMoiMB/5rMLIkjqcMKRBH4Llvv4+gKpk1OGWEB3nhxTE8jNvu37T1wIAiulBxhYUiNHmHhSor/RInlaBKwKNAG8rbLKYLlesH0e15zCPh8UldTYZYu4f53dfIgAsoboSZED6jASnhAf5tx/Ojjcn4+TIuFIDMOBFRwvpVCDN4YvF701gY3v3xvT2dusy7B0jfvR8N6v74nv/zcsE9LNsLkgWMgzjjZXh7yrNuwLKMUxor7piknIVdJWdpQ0R69lMULOIeguS7nmCJAgWhTIJgSRwTfEgDMd2K7zMQTJZUlbxgiB7gOMYOm/mJIkocsGjdH7FZbXSt1BZ+AJAUNlgv2Zhf60flSPBQYynPlWwnVpknSPAMbyV8OUs0FFSDJoCpdedM12X6hDLtROryxqzZRgMK6v0IEr6PJZdZVrqL1ebxmgRXvJGYCOJy2MZYko6NWuJ1ZXviQpdqhleBqsx7sJ0vZRcmqCYcc5/2Vqa9j7FmRcjgp7QrW/hRORKbOXY9xpzyxzReO2iw7BIGZyrmaeB/L7e1bEgtoMEvxiiUD6cVGR4yCT+PSXiKvpM3cPwd/ikHphRchERSJrgICeZL5SLSMJQ+M5GuvpCjew715Obuj8oUX+ySloNS4gXdgwtaCkEpdQ22baZiJ/mGlwdO7uHlU2e6i09k6vjwCu67YrAMRjKuF8xQC5aDRkJDT8RF/pT7jCoC3XC5tD+m3qYNKi3AmlL9xjIfgyg2qINAHQTqIFAHsYE5Yic5qOTokH/aC0NEQRS44I8kBDzBIEm8byqHlAb+3kEZBnke5HmQ50GeB3mefbG7KI/OLrJEacNDnmg31brrXF9idpdj8ZYclUGNcjWwqJetDf4owJn5SmGOA4O42h7no3xEpwiUFs2suYN8ViFdcXQdnv12S9bA35Z1muKM0eHl3geFcU3e3XV646KkoKT/myQG0vktqWmW3kapkpTq9ubfeuH8tiMebnssuL2km9uLcCyb+Li9Kl7lOWnMFlzb4nSmtFNbzFkl152Nb/zWfdn2kPtIW43nv6p8pzZxZMsa6aHf3QNhRbbivyZIzfH38HHPjpe/xhdfPPCpDMnA/ymdMIia3DNF8BH2yg0YijApWuiqHxKJYNg5pCIo8xzUQmm9qIwSWZSXfMpXplfqRY+N8CDpwoF5txbgHXIFFMW8kJkzoxolBLKKYBb8+gkmYRD8kPISQWIaUZMs6HJpWDPXlyt4ci9+2r552XfcXU1046vhgupSE9mqMrxfyzACsUbHtAkLF3TKUxg5j2s6jLnbPthVk3keg3TdyzmtNolshkAzhLpBdjPDIv3hDWk1Tk+rjfzw+HfDUiyK3ItnJz1iS9NyF2zieRsf9UGSI/+aHAY1CqnBBvwJ3wOLmo+eobnH7CvsVUHeRKg3uNGzKioK6pT8PkmoPoZlSM8vk3IcheHB16RIDF82hVpZnmFuhSyJllRCxIUh/vc22g9bU/uQhhwx3cetdBRrMjGjkGF7GhlPk+fCrlzD0gqT76FHHY/IhH468YwFExIt1yMBe6pTj5Ilcww7UI31hzed03oDlOsL6qVRcvELIMQBIAGtRsh7s944rTYa1UZj1Gi+q9ff1ev/Stuc/COQjPsA5bnKH0Ypz7NnE2H7y39xlo4Bl6aqa9VGcufWnpJYEqcp4Ry47JmIq0ke5syRSgGQVKWJwnDlnXuskf6UiPwdRWuuLL9uOLuJbZuMWur0hDygsykFsUUgEEq8r0kS8uxP7Zbe2JyRH+Rzm0Ls9//lNaxZNXg4a8E7V/QJXoR5do6/hx/WptKrKhUhe3giVzjk+SFhFp9UdQD1w/BpJGwuoFHaynGY5ZmPhK68OZBzjWevXBMAXJ3D1hJzKa1uJcVeygo9Z+IpZfgBoYBYPuOlbRqawXINmXlj3f9EVH5yWiXh1HZS8DFnYbggTrqD4Nh9DxKaafaippn2Sp+a1GE1ujRq/FyHO1VzeGs/djoxrkIFimshbGdGLeNvmb12XcLOSGnB2UcbSDD1N7Gf07LjRpoIdQ9GIk9uNqXZnAdXk90meG+IolOUl7qlM6aEFpJBfJiu2l8l4yNKHSmMTiNAAB69a0RGIEP6FB3FdTCA6KoumQNDYrmjaNYrRwv6TQyjXVfG1I4yvTorHObsvcFMnjqP14qNavKYz+zKLIJh7kH+jMjNDlMMhkPTDUcyXAWHd+lXyBhi/vigLTUzIv/Ev4yMasFd2QqO6M854xGePJvwelxH5zLqaHMiH80F5w8BMeQRk1GQiS1G3lDrMTWbY7C/R9Q01eFaMA74LjLaYNHLDVe9tpKF8IPbqSsKw55TV+T1NIJsiksRPSt/uUWrygyCL0S+P56Hsri0EKFNz/LkK9mz1TUonkM7fYg/6aXX2dJhnO8LmLbtvf3Rh2Ibr/6lHK5E2selcMMNITMgHhhc5DI5ye7e9kWEt3DKoFOY0q92cKjvj6lgV9x7AtfyKzWZ5fGqFfIwN7Q5mdOvEIJh4tgUCIsDmiqoPmXUWzlMiCXQzYRqXx6oo7sEdod6xsRkIgi2N2cug0bhZuiGuzTpY8Bj2CbXUTTr1XqzWj8ZcQUF11FUgFICpZ6NdWUZCjEwW8vbqZyXNaxLnIkoKjFF6h1/j9yxNYE2MlgaRr+yyHdRlgZ+jhzVlNzFC/srC1kX+bRQK0IFszmZ2By2JjWJK70diSm5DBtRz3yvG2Otx0mJaeXR2ezJvBI6i6TyEEmlJHy8hO3MWFXSjip36AO1twyF4DDIHE7clcP+N+GbTQVHrFHLsj2ON7V022K1zAAq6cRU/ZQKno9cuiz0/Afmuap2KsJMbiQs7gOJTVua59RKlWZPcweIhBMJ594SzqiCDOiO56wWikX8b9tiANiB0M2ZKjO/XmgQANV8ldetyrpxPT3/kUyopT8YugfiviwWZzEFuh/Iog/t9WyPmkrVySNvjUexIZTMjK/MElZTYSLNQfTkm2XzrmlyzmPRmqpeeII9PqX9pE1e062x59Dp1NAKm0EtzVzpjFxcXhNZ1TchhytKZzOHzQLuPWHD3MRomb3p27dbpiwe73osOixE9AuMd+vWypRxv5BVYih7Jl2/50y9BLfJ+K+gr5iIfLlNu6O/JLXQ2Mh3pRYQjFziFrKEc0PXYVXEkQ1I3moSbPoaQOL/Y+9Nl9tGsnXRV8lQ3xO2+5IUJVuedty4oZJdVdpdLqstV9c+3XLQSSBJZhtEopCAZFaFIvod9v5zXq+f5MRamQkkRgKcRMmIPZQF5jys9eUa7aJI3wpfZbk28jJXpEwvAIJPNE2OFQfONKuiYjfW7WX62ziQGnPPw1nD2RjBcEf2YEctLQKWjHrT6Co7+h2q/DLzq7xb33HPAwMfc63M3y00fH8aqzqvLT3ehrRu+bO+NKxdqbdh8TLp0PGFH8riyBfXsjyovNR3KXOTNhlevvkpy8z1+rixM17VjO/uSi9Pq7l0zN/0hV7lBvfSvzEl7lY183zqizApsBliUHAjzNQ8/CMVGCwVYmfJho4VXU82dOji5WRDFZTlLLj6CWGJOzYhW8lRjpVlKlXT3oLwOkMqlkuyG8xweSTqjr5sgr5Y9GTXCCGNUl0a2a142XVct/rLrgPaLL/sqmDFZa8xsL+j235fEEvV+u8zYlk65o6i7DNi2SHNKoRgiphP6/yFYNFHILWEf3zUhQtmg/hKiZJfy6QDIJ07S6w2TWGQ2ynBOPxeNFZG2yNlJWbbOScezle+x6bUWRA1tPTAyxkN2ACuBPn8w9uPJGt78Bl0/F7RYid1pKT+lU8dh0nZIxzljarHUMTTGZlxFoKF16JnOVvPhctCv0I1rcbTSAiigskgvcTpy9hxGHOZ20pGVw94WBiCL29ajoYhRT+UiM1lsf4tWhqeqx+H8BeTkk5ZbRN1FCSreoQb/7dn71SbOnQdesJvrPWf8JioU4Id4KpKe/yWf4uiCXBLP+Xj6Jl6PbOG1lokw/5UQ6zt7QUqyVzixkylunQ8DgojbHljEtmypX4LPXzIipBP2o5WshDUFXcx2jKW0oyD7IlMGMl2SjGbWlDhmJcIeZO5aZNvXadAtD+a7xWO5or8EVUdbQ7UM9gd6IAHUlNGhhYI16xHTGjaHqoxQ+agE0qffQ3g+pimbmbMN1VH5jcuiWQYDQuuXU2Uintn4/1OmWhbA9Hdb9TKexOm1MVlWcGIuuxyp1uJtgG5vT9oYQSsDu22rX/VQW1u95sb1f659uRh9OnFubn/VfQwLZJQQ+vTev462NUAadueI+uEeC5PjF2tKbAostYTqJ0p0Q181D/UJJm16fKutAF4P3AQo4AuwIeyrQoAJ7ZNkyhcDzPIFikbswN7mFd3zYuqxd/3/qoWxPiqyuEf6uw0MEG3r7KW3Revshbwll/lN0xGoYBMDckFLgc6Zkwbs3c0Da4oh9/eBc7cD3Wb+9ytu7qlQ+qubsnV1Yf53l/dXZtH2xddbVGZRbQ6gDWm0IT7KmYJjICORZzx3L8vFCAzze3z8CbMu3xID5MEbBx43wf3+OUkwVjoVCrfrCusVW9FXq1VJ+W8Wv9oJ5vclyu7G8iveh9DNy31ZzuC+y1ShHRgYSld0Nqhe08ZilquPM4/vKZejBi/EfkIheeVEI8PwvMqSAf+BFohrEUkc0JWE5dzb1h9OqWtXN6cUnuktqHm8paMp7u6D/jqwk1bjvLhVCi1K9eCMHLDPY9w/5p6HMm9FQZL3z7USahBJ7I0eAeQU39BuB+xaajVwKlON9cCdiIjERBIU4YBMApEJkh2UCVTq9bWpCXVUpk8AvnPFaobkp4V8oMpmI/mAt5koMsxO0TS1olqHYOGpcexXdCefHcYXHC8wLXDqInaMy7f6+DKB80iXn8yjyW+y3758FOf+RDeF1XdBV12iTJCh6D6X8fDSxYBQJP/63ioLlQmRoojglZjxwrbHnzJZdb+g+gf0ipUccWJ2AoRT9dD6nyBq4RQXDbih0nmv+G33KCMsLVTfB9es5BPFo3136p4CXL7G/5Qgd0+grHDjQ6URA1/gbyUzQx47Ma3cgEVuFOTK0AqyaYQcKru/pUO8P7dtz0/73WnW59jPN/XR9axLtciwle1adn3hzbMccWcch+i//tgKKcxUJnR8N80PAKz4Teq1pmuJfnUR9MI1abCQG9+viQf/+sjCeKxxx3yhS3krlSOalJ9PanRhZDRGxrRxoKI919Qwvus7LfvqEv04ulCT4uFvhfhGB0udZFnxSI/i4h8L2LfVUWOXhSLvP0K3p9KAPw9GlBh2ZPhcfmwfqARu6ELBSwzl+P04vxj2d2gAa/iP5+qD6rry4FaYr3C9SnMk/Onjuzx4R+q8u2h1MCrkihPWaSOmoFoudQ3mKKGmGYIn5jzjCZB4TVzAZWltqNF7TiEJZYWxU7rc5/8NebOF8k99KxHqyTI0ycxuIPptBr0qqZyz/KcMkr1BhUGtW/2LBJsGlnky1pmn9R1ORSl3oVlAKociG8bHOvtXOZZFAVo1GdMD8tmfg6E26ceuVR2hm83amdYO6I9unrF22NuoGriI5sHmKf2UCd7CiGfnf4n3M7wmjtMHv6h/1Udm3rKIn0ZQ9No5qbiNmDmKVWIRGmpfF4kPRKMZAJPKPZV72VA8QiqjHbwK77sp7EyD8RneEidSEU6Se98XdYq1VftFTUDWuGSWo9ItYC1HV2qMmv148bzoP6t+iaeBySkN8kO1L04Ozqzn7e6cNfMvYYTDbfCvsbJ7T38Q4sIGt3jM325iqERC5fZyRUtvUCSXEYh5ojA+8m+RiEtUXHn8Kjp47F8sql7fP5mF7d49V70JtX2YsKnt+1lG9e5xZ3y0Rflu4U+CeaduRRm7wZJLEPyuxpFR+3KqV2WIiHJA8kKoJZxzD1XHros8MRiNBPiizz8w/prFMfaQq/8kRyFfDpl4Rus8aMQX7KmOupXohokM/V7TvCjy1CCY9FvYGrXGZBsmDhXMEnArkjfX9uHDQhiH+FPfhZgkwQRENGJBjULVXYFS6zp1ZqN0jn/EvOm9vTf4Rz1qjGXaM+mSex5i116mtU6mqr5nQbcHOxmrmcFymw5lGXHRz2QoC5GaOEhi6v0MYwZvEmpiXmuz4aupyxDpM68wiUZh9TH6PHVWZNMiDxsCM9Dw2WwKtz2tDWrO1L70aC6VQHWg7rvfW+RSL90HPlmTeHZuYw0A+hBbPr3E8XOY0/JyDQfy/sR/lHjYpjZzdtPya6NAGI0HNmFcvIBogCVlnn62Zms1nL1UxS/bIDJTTRD/FlEyAdQZnT8qnG9j0K8o/5Cc1RZlBDlHattMq9IBAEasbHU7GpcA0Xd+kix69iAJjWK6mMEtEoMq+Iu5pMjod7o71ix1Mm4pxMvMPiXCOEDSHxUzjN0YQtVPLwB+Unbc6nweNQJhZRkLvC5Sn1yMhwSE8vzyufSyqgExJ56nrhh7uDKXzHFSQ4JGsSMz0byPlAvKZOsTS0N5MVyqA+6xiStcyTwZY1SLUiGqnSXuAavr3xC/kw+s99i6n0mj7U/2RP92RfRSP2kP0jI2CcxtZH5xHw3+wFYAuW+LKkzciioIJgvObgCFpqo+N20WPy5xAdtTr/+xPxpNDt4fXzy9Da5vXiMvqOSO+SvuNIY0SV56XAoo3/pHWjDH1N34Ig53MMzPZCyFnK/pW2Y0b+GaKXQylvfleRXeBqVNJP/0RqLWaXXNAwoNIT5E6ubKv6cNmZtymuXXQMWXDVZyCUaKoOvAgYn1ekBk8yHVflgTPIXn0ecevx39VmzT5AVoLcobKi4VklA0gFiYw2HB5SAQIXcmMi72Is4bLr6Ud8abXbNXAW8QB1F+5LB9QWfUAwH8JgNpoMe+f+h4v8HSKiHAivq9SRzhO/ScPFkQH4FB1bk9sndB2EzUAZzNXuasqiIvYuAkasDrgWaVwco+WJf0QvSJZNQzK387rb/ZQHYmMWFsSnaA6M7QEagxoerpzoCOl9EQuxr4EEmZhO2V0YLNEeAV/xB8Q07qEsvWmVDQX1DPvXzdulTedCKYKbN/9yRzF2RzDfs2uR8W59kgpI9S5vun2d3mr1LXfZ9ydqlY/62zdaVTdTVyxKA3DUNPOrDDxtP56Xw2beSxqu5gRfC3tXCTDd9oNe9rlTs6eT5k3uGt6tpPciqk5OBsYcDm3BjQuCgaGJ5PuJ2r0YTUzutsHbwGdWktuBr8aSsCxpTcgQ2HrlbjXtHwbxgLpVWcwjs8P9tMuTK7/rhuKInv3qS4m8lfvs4n+owvmBrjBj6sXrpPQHLBHyPWjGxDIm98pWBKVaAt6eS20CVVAoFVFolVzcWqAirseB4QdAeHMphJ6rTR/LKh6mquD0ImpUQMxLWMHpA4sYLTDvhschYQqOJkpFqBqHAGAQg9dIQ9Mp/fPbz6bu3T8CoIg6kehtvylConoQZbcsGklSpS5AN5alTWDaqqXKSGhrVpAaWzNMJzWXNxD61DLaAd6fjFc15RSuavhmSXrZV3wRNfwsBFXvqA9gX4t+7ovF2CAiVGOYP+M+y2A+K+A/7iRt6IdpDKQNIAjJbHqS/o+95ldhQD2YjfmAltKxNwIfViUjLE9km5MM3dV1axS+Fse97sNKl1zONqVyjFhgWFAOKllSEYUjzL6kQDoikaqIyKNhlbg2iKbAVxc/nbxCdfdA2pPgtYznT01LSHrGQllJDWAnv5iyiLo1onQJhHyiBva4dnthvPFG6Vw+YQn4M4d0DF+uSTli0SBysCj98UBGd/85CQfDH1+Ti/Dz5TEP6ewJK8I/ML6fuHA3AT3FbXpPTIFBZ+i6Exx2wZf3ArsUXVlskcf6qaQT7bNHLuziKqUc+/nRJzuBK4euspK9MiOMeOUcqEC1IYqWryJN2vzO18TgZm+OKr2adkpd67wAAnf7nr8quh1ziIU3byH+3W8mX+SBie0q5z7rmZRQyOk8K6T/Nj5c/4fRKl6j0R13xJ2HNG//QP5xRZ8bIRRyioBgl0R9iz2rV+pS0RV3yHfWo78Dw01Yzn3Xh73nIboD6aDPEtHzxF2vVk20PrF1MUqEtP18Nj2gbNLLnvolL0YiJMIOC5EowEmg5s6XpdXlU/iCAX6TWpw4I2N+gEBlxhGaNC6OycmaQHNQFcTPFXJB3+2rYhSAnoLFkDWU0uqwla8kbVYCOVKO5eeAlXgdwWbgkMyFN7mHb0YCcphItI4CLFgEHPACacPjRZ2FfV1dZO8FkEKVfSviljASv/Ix2WMBmp374kSBvk9NOnFhGYg5EQIRgbcYx9PuVP2YMno6wohyMT5iP8ZUJ4FZ1iErVfqmuROuJW6qNb0Fh5/NogfKskYaxzfalrOLtrTWmdJuNe0Aj0VZyqTogut9AtLhRDxiFlrzT7x+fQ6lBmUjskDrzQ0WbRhEg55GMMLlahdmeKtoXIZ9yv481+lhDRTYpC6GImq0zrEfeYz2F0ckl1KuNrVhda4IU+e87k7RFnuw7FobsU99FDoFCgCwzfRgGDyFzBCQn36TJg8fnPGo6lJ+gMKYLmLFMaH01LuXlq2Kx6HFhiB8cWEIqj4YZk4vJRLLGA3iPpSvstir6aiR0WXoZNi+UXXJ+ixSgbcSX6jmtxSM2wdSXzH0Vbt+iye3CgEwqmx7a+5VY1devYqJazQdghQz2xZwWyhEiSRoDfiXqsVpGIdLLgc+saQmMP9MRuOBXBOvct6gfGm2mvS/vwxC8WtKWzc7RtP1jyIsUwbKMatfMtJ++BWBaKIT2F8bmKOVZS/ocpr0G5mwWU/ik+4RFcV4YHQGds/2Ih4aKwQumfhmHw9vbtY1kGlEcG0HAZdGHGVxMWuZlau7KsSHQWEnwKpHkioKqhvIYKb19F8dQZz4o2feVDXaqwahWAmfjAENSi2pIWRIbGCtQEgoRkbNTYp1mA0saAVQlBSppRUVPgGwfQaSAzH4B2Z1JhawBrUtW0p/6TwsPXrufxhY3yw7OXoG1JqlEG06nw2u7xmt3eFHQaYSHTDZwNl3SctpQ/xgaXm6S1/6822Sqd8CljFm4LuVTjcAJ4FOfRnG47hKn7TR2vl3WIjbSfwENqnjA7ogulQAuaTRtqH9c5jYcI8Fo5Ia8tKe0pTxpRvaWOq+pzbD3opc5/Jnzmh1jZmk+fbuYsi1u7Kl/77mBUXsMWWMQWCH9PPxDf1PIMkd5as0IqyFptWFhc0j6gYFDpazApImXoRoEUYMgOAiCgxjoTkwA7AwW1eEhMT4yl9A4BsP2BfGED0Ezxky1VQdV6xZuF/h1Ca+wZIF3CqobGmjeD8zJgex6iwa2nVsCnTl5knUl0pUnEZ1a8CzBV5b/5NPnee6HRDd2eWTHu6iCtAnO+weI1MD99sVw+DRhGRgfiIRg15KI0H75cI6hXObcN4M46m0DG6dj+7Sx9qsxq81xe7l4IVtF2NrfWfev0fXKMT86pr6/TH2JGXEdGy5qKNsrJ/MWx7JoZFzGobU4tpI/93TSbODNiG+1AbMPsZvwdtmGzR0X3jIXvl96uuWin+bz6WQ/neynk/10sp9O9nM/YWKnT6yx964SBCkde+RVB63DEn046em/TIaBivTBkXbgSFwq6uzdSorvs6Fbw9TCVUuwc/SUbPDIbFrDTMRLZ9Dhpb3GSyOI2StCTbQ2g5zSNjWGUob76wIo1YpqEtP8gKl9wEIu1m0639rt/bK3SW5hxw/r+GHCmJq4PZVH2U5YmzqMfRH2XS7xn3brdtxLNHITIXmjyqWMrCTyfimbEyHRfSDNmDAEfvvP/XZsHXMvCVmOrpj2Gxvg1Byv+wIhmkyhwxAdhugwxP5iiIeremmEGepcyDAsHeTDdiBRH0wqiMuSXMZRX/lU67r9QtVs8sswVgqT06QYOdPFSvN6JJH40nYJtquBxMXbn9+c//yDNsvFPB/KFfvKT7NksGsWLsgJmXNfh79bTMUheCgkPrw9XWgGofegzPcf3r698v9uIpu2ASolMT7O36zl222vavv3+mVCXcmHFTLbbsoL157Eqv64VW3skOW0YTbNYhdW7u7GwtZ5HA67SseyQXdee+D76Ni7ITfcQTrNvqFplUTVRPSsIKyuGzIJer3DkE0x/Pko4cWVQkrXU/S1b+qk/BuddIvOuR90QfJj0nhZ9g2MmFwsa3y2aFXguyUZjlxPuaePGuc1wsEkk1opAfcmyBQMfBXSlK93J+So8w3sfAPvzDcQbkCBomUe0pthZd8rlgLeWl6GZmwsP5+3syAVb366TImvCQ9VydysKF1p6KgNsbmULQ2KLGZ1b746vlXiz6ej6xb4UUWMbv0wKBSH8x8uBnaUbjR7xmA+sWQEojgSBx9lVlLjYLaQOmKQJxxq4gwZA6+ZkMwnaiJw+lzmhItAxazTFJH8+PHjxSWJQjqZcGdAfmI09FWCKmVL9o/Cbn96DAkg5evDQ5ddMw+WTw6cNLKRI+aHMNw+DMnTAeES6NBPMkVPGahKaRgx97AsYWtrhp2Rgm6IB5vNb3IFk7JIN2C66gY1pUJYGuqKGGR6jSrqonlSNUuPodV22/DeppUO26z61FqL/Wyc+zjZbf0m2M9+8Jxa75+699XhH+aftQ4/dVyr2uVnOdfSBRWYRjaSiUKsBVqJtXGhwTXJeq9R8ZTutvFqWYu4rXAd6hQz1h11s6Pr7ujO7ugSY/66KzZh+dCc38OXBhdMlUO01upi9TYq79jKPVNT6zDEw8IQk8yufhPkae9esPXxgusIVTGG8C9oqdyAUumC7UmVjjyTYgjYFRAD0ZQ4cEnmMfo33gUl28bDcfUHYO7OrvJ+03vV0d6HRXvj7LZ+E8R3PyhujdkBV77Zh6EYi6haH2bKQU6Zvi5r02EwvFefB9HXiIQQ1r8cLTIVLj+gocRQ48yuN+GesVdMQ4YntFnGY50B3hITqhjxJtUMNuuCzDHs0yloPXAoPaKPGgZooJ5O5iBB0E6DNc0NzlP/eNAOmDHVmh9UJ3pOJpmPsJqLq2pSOaeLksAbe0FFOCDnEyLmPIog3/ZE70G2TDJqQgP2VSdCHBzUjbitHURioYeh5PU+5Y/MVsz2VlGumPMOlMXQcmQB9Ou5qj/MMYTN9ZLlGBuKYJ50pZZ8pG7oKlS+bJ+/o65RV5LH3EcLN+tkipCguZc/tbRyTzZmbmovYy0bgNEfleANX5sQ/s5c8tiMFFIM6JnAz3DH1ejuaOBPS5irCMfcdZkPiy5j0IGg2UmQmtfBNDCTjYeZme9o7M9K5FjqaPgCCFDsuzBQixwk3+9iwCdlZ/xc530gKl0DwRtyN6MrOQq/BFIl9Mme1URRFvsJwtj9mDcEv07PyWmcpMGsskZqko3pUw3I0pMaJChnBUfILKo6HMeeMugs1dkm2AqKVQGs72LvC5muiLJyCEuZmMxjL+KBxzS3z5kgqTTKKhyCIe0D8pY6M13eJFSGuFYmkqtGajrhC6AybacRMvKFLVRgrFm1cH3HoGuDzie5pDoAAmBceqlSM6tKjFZYWebrrDsJNFPSiHcqQwA5Pkk2DsxszBalz8UCEslN30IS/zD/BO33Qe9g7InpwP70yUY+xydNH/Jt4V/5IekA4VYBIVCdHaJCfWh7hH11GHMlOT7p63OPmS0wsbqbggPu4+nv0GKHFv27RYXPhi+LA/ugzzdkngODo8dwnTSNVyecuWTqiTH1TJk7WdUO0naQtgGkNRC0EteaSR+amCEi4E6t3NDU6GdqFJJT/6CzBJ2ek0tdA2EqJtjUwd5UVaV8MXCvGADEig6HFQiYFk5FyDHS3IRDgFZb5jUgv85A7ljaM5cmm2AP0g1KR4CDlPJc4r4j5ijUCMUcDBOnwNlwAJKZwQIMv4FtU8JO3YAGzJ+dycDz5gPVwMAEaoKao3TUn8mEM8/tpfBIzcujY+YNyEfVkcmHqbVbYEyJ04J+XBap7EMwH+0j7vbIOIaHthk+l2p0Lon9iHtkIWI9d8Kj3biO39BJPwiFGzsRXoZx7LseS/VjzaSOcAgaHKONuz1XjD4lI5krU6M0aTgBTY/uLtNjxYRX0Zk1aKqpC1hKkkoj9xVoAq5u6WprnUFye+peVytMzj4P2bfE8bDgFFyjRnyDRE2Sm605e68S/vUOXJPLdnFjyreUkw2yF7mBqUOZI281a4TiJUYO63NH2wjCvgzGB8hwxB4R1ywErgXcjUfav8VbpBIJ3ZlWwulXXo9IoaOvsitfMUnVA/CSG+pjKsIvjAUDcoZ5mxXbiugXRuIAfqTgMhyr5EBwremURpC+98pHCQk6GkDSX0LJZ+R/n3ug7XOhfMgmLGS+w9IRwgDhUQuRYFF3Co8cYMnUpPxWmkBKPmP5z1e+tWQ9YKHGwM2jUiqBk+bhim3KhO3fNEER4DENKk7PEzfcn175SvABtHrxGqbZJ6dK3AMLMxMeZraeCxmR46Fe9QGU0rM3Yjhy/O9//ffxENJhh9SJ0L9axadHJwxP3LDQoZIRj0XohfGY/vtf//37kx5x+RSybT8e/vtf//3qiVqO2SKYMV93pBYm09HJkPzy8fv+SzJeREwOyEf2FV/q4H7lUX8ag9MX4Ik4CESIisc0KK8MqAMqWeUYJXtXPiFB7DtRTNWio2p2MR8LD5qmY9kjHvcZGYeMfpG95KEdsa+RKs39ay75WCmP5xRxsbUUKICEtyOFZWcuzusnWD+ZTCv2+W8xy2uW9WCEKqaOlHVAWmuOtwmLNiPJXJOPyYOWVj73Gqg1n0OH1Tqs1mG1fcZqyjxNlRDhFAxQcRX7+KLW4eLRGZhLkkC5BCnp930TUpDYNw2Wi1lMhKxGEpYkjGor4YoKGpwZVrVYRbmSL2snL1pJRCiWh6h0qJ+CKMkUOGS+GwjuR1JJN5gLMpK+580/qzgyLJRg9uQtkrQkSkCRRvTvkdiXdGIgquLgRsTh/1PLQWgUMeh4nxj4ynINvfI755PJ4VxFlmGOy7fKGHMq47IlUtdmjnaLZZd0yfTTQGjlZsdLnipE+BnF+hLFY8cE95YJbkJEkfCWttKJBuylRRPpwwxPqVa9KpE2/JGRdqvHdir8Di17FPY1ECA3oDIvhf+zlrerDiF8AfcNC9evdd8lIYwYNdbQLX7/D3hyNhdq7BHnubOnY46DrPdq3Gc22GDcHSfsOGHHCe+OE674AIzEdApMofQMLX/rGTn0oSM8Uf3MU8H/TOH+477LgpBh0JwnaDOa/jZe9B2B4WtQRFl4CCYlQZN8li2Zj3vFJbnm7Aa41jV3MTQoSmFdceOjpiFpC0P8jBf4XxXpZ0B+FhF7rUKEcjtaVyTI2yRAaxoRFEXVu2GLueWEQ1mRXA114XlfnJU7Ua1l/H2477Dq9ouByB6jJF3ya/aEjNmU+z6CoEkuZhwYG5FJiDajah+pFzNjJQCBnKY04tcAbiI2RQtS0JDAGmgYlUY8U+gl0fYEVEYkZJ6qD6YM0JfVPTrEUpehLZ/p0Sd0LIWHMIjPmYzoPFCxoOB+iXCOVhEfvj8jT58+fTUgp5HKoYviAOyaQ+AAHkGLIMxX5lWEqu7tsU0xXglQU+oT0KUsGA1RifRB4TPsForbEavYmFg8Nj3yGMpK/6UC6xvtDVERnImHeUfxsjPQUuGQXyslg4zI82Gygo8xv3D/5BXMtX/05DU5MtgwZLg6XPhJxRcYHDep9exIVXs+hHonSaMlNY9OslVfvlJVnx1D3afDurovjnPdPkXNE+m/GmLHKmJvtuJ7zzXr/ZS4dCHJ4/7J8cnzoaoJTWBVly6smgObgx0cD49O+sOj/vDo49Hx6+Onr4fDvyNJmlAECv2j4fDlsHdA/cX7CRKGvEVz8kWf6YPbT/ZVAzDF/VioDFlN7tuvMwb2ZiiZQvKSMGg8FJBIuuza3XDfFTdkTJ0vNzR0e9qghoP5ve9i6mkVjgbVqUA5IHaHtyB0Og3hXjIX6Sge2Y+6x8SCejSnC9RmJTe2egyjUtSQLKmCK42FT5WcY+NRaEpIJ/DHRnkCmo3UwO0tjriBDWHKxRP+taGQveQ0WYLHb1KsUGlomBa3E7qYmlwtRXahLzwGGmV4ISO/YDfkh5AGs7/+ZHUORxfU44y6r8ny0HspHppCU795MNbDATmPUoIMHP+aeqjuAdQBz3GM+acznkhb2wwj08ARbrFkHmSAFSamwxyS0DoSDRR8Bvr5d3yqkd005i5rN+i5qdzHyvljcYiyDy4DjybZsZnwkPgdH/WHT4H4DYev8X+B+HGD/UZJGyPX2hMTEn9JPP2kcpvsO0ki6PJQ+vpnjKWP/64Mpm8d8hqQboY4gIu+mttVsswulbOxoKG7Op5Om8jjZ/uXIjxLfs0B57EAyxkIHavkR4iBmDJKhUNshFtTfs187YutixmYQZ1QSGkHnLXgi8+iGxF+6eBzB587+NzB5w4+7x98TlnDDuBy0lljzFwcXoeRO4zcYeTtZ5tqCZBtALoOSvZoxHxnUW1aFE6FdV0nIlSR+Uq+U/wlA5VPw6mwzngqCS/A5g9wvtg1SJcNASdY+3JOw4h8UFHCrTd92pZ9ivV0CJ/DLUBlkeyRMfXdG+5GMyLpNWjplEGQDj2O2iQucVl3gpyza1eFmsfcr2GyK4ViqtyOjTOj3BRN8yMVTKKOCy0f4yocaROq0dycVlGJ1jRRbS1r6xF7B/Af1HUZcrJOZMGHrU4snqTaPFblnH2PWUZLDWjCOwzNX8I5UiXoDEMGpJrt5fxkiSazhHtMmTAC2mrm0qdR3+UTdPGJ+oHoB7IZvwEHmqQiuRAXRUVnyoFq+c44hFNDUPk5XpApEwjAuEO0zaqYEPWmcBh5DD09GZDLmbiRpcwpw4iYjsfgLDCei1mPu+dKa3KXwuLfC35TPeqOA3UcaEUO9ENK5toyov3nKANF9TfIVwI+gqfADQWOYoXsruYsAe/LGZhuptaqoabsfctDoI+5ofomrmw/03rfupx5yb9UHqQkpY8ksf0rYSkYkRbf1tkAJlb1xEdRvUHs6A1ZP4ofGXVZCHFsxReuJMP/+etH8ErlcyWblqbdBZjDRtx3Irx4etBSxUYrEvIyipGUO0zXdKTGhsoRc5tSwtq4FTxm3LGEPBu6bxfn5BK7SAKjVF8yB9ML4vL8oI7YQa/saxI8X4UfypYvfsxHYlnvhgWWF5PexH56dJqF2G8Tid7aJDsgvW7Sh9vj8d8LypbssX/ryzi0VQTZaPtcYjCUiGFQWHM5wYGXJB24ZELlDJorefQaToG4pNxovYQKSBY1u+XaTLfdRQ88cGhOLusj2eLCG9/1Jnc3Y6VdfuFMEV56dbWFY4WhdVtCoFp7mLSg5MLvwbU2+7eMXbpcOuCXWCPaSy8J/DOpkPJL84m5/aSq7APz1K8xCd99GvDMBXr7FRz+SVob1zBtAfwt3gfMx9OtcGkt6wR0IaN8I1bzqGRDzK6zQPZIyHwXfyv2VcUEy5+Ddj9W78JPpI81XW3+nZNeHPUpfeqkG17z2tnsrO7sHZSuwkpvoPLqO0zRYd4xzZ3kzT1ZNahoOmVzY+GMJFYELeondfrHhSihaXu9ZMSfcp4Q9+XtlvIP+Oeb5Hbda0B5w8Z9KiWL5CClF7sAkZ8a86vDlB5tj3Vl+NVPEPrIIohoxuLnuVYTFlVes5ZVtc8WZS1voCIQt6picre3qwbBmEfJTy0rqzO1cnUTD2DlBlweKu/PlVsQoYvrtmr/k8nKldGQwxzwkQj5lK8+j2xjoPhkdluN5LxNMcSd5ey69/AgBQYjEFktXxfkMSW2jmBqahkhGt9nI1ZK7Z10PF1rnKqWPcwjZARTVuznTIcEgV9N9KyATrmPZlgmspzufXkfhkIV+vm5MBNQk2CvDds/hgjtaIE7ql2zxEs88VeDaUFwZwhvJhkNnZmVx2ZJn8O018CcwKJVarpPWBTnlRiMamNfNS4QRNQv43BofKmz6HJV0GgRIHPTD25XgnJ1ieJaU5ZNG6dlKeVOgj9/MzBzkIFSlYgTqMWGIGdlftEcfMRS5YgxK9dw+So4UckTdehn4LhwxXVmOzTHW9pkiehvKwEaKoECrtDIZIsZ6bE0DthwAdUrLvUWJSRq1KZbzmQjM9gmg+3oztZlpGuQEAxgX5Pvcsmr8/CP9OBz93bDj1BwzedFhyKapwIQPcAmApXPz6U10SPfDI6cv9mA/LOD9h2076B9B+03BO07vvpw8fwmzRDaSNxSDr6Rl0DxIdCeY5c+BJY2s0nwv0THBGNa+Y1ghImwzre36z8NdvcyWKz5LujI1714FjR7EaRJIvoQHRgUO4cT6nnRLBTxFEnIZkQT5XlgU3pUMhDZt0eSfULAIkbglW4VIb+efm9lvSCmnZLYzqo6vCYq6ihrrjlViWXtTrQiK4GekPDB49rqA/RGUrvPpxcGMlAl/m4qvcJMxJ6LPrljpiyioD3wlURP5LuThOjuRumajJL9GNn70ZTkJXvVYKe6h9b6D61We62NaRps9oYBcqtTcad8Zju+2BbngVm/TWf90WzAFplQM+9b22yvhDwPstS5khE5GFsDS8iIct9jUvYtb+W+yfr7+uAX7TPuTAYWk7I7GqnQxkAvcfGycYq1PwuKmdVnNK71xBRyasyY86UqJqXFEjEKfyNjDFUSzcN1pYKdRcoEkhIVci2IDkF9OtUcIpYs7Jvcjaqu9YaHeVZYX/Bs4NZ7YGyRszYAQ6sd2ztIEYcOW7n6hHvRGvYSIJAZzWkQMCTJaix4xeXq1gpwnvSx6ZhqJ73spJcPQno5iT1vhNd6m0LLEtrxoN76Kg/eg5FRJshiF1YGzdDToYYyh3/ACBopFS0wpSurTyW6Q4OTcuCqRmdoamA5FWVwxqoQFJVSOBxpJobbKk0FfcfsPTuhjsPv8tmMRFhvQEKMt0WLyze6I8f7To4HeuP2T1mE4xvBEDLkZyXCfmgImkwtSjYjM97ElJa7y2qmEyqHVtt3gkYRdWbM7Ueihh9pT9gM99AVdRYk+/rWO9KaqI4YPlJMKrmT1T6GqrN7uBOBMc4hVafLkRniKBJ6a9qa0Jl1BQKfNvxYPqlb3o4NPkA2uMo5+OaZ404Uklk+11Ar2dSfW3MbkIKqUwGUsQkpVyX7KD4tEcq+wZ+z0tWlMlpVSWasmEvlsxDcikGMX6ToPEyeEki58TFRZ/K8jCpag+9ke51sr5PtPSjZ3rbEejVUo+OUu+SUyMyWGfJrTtc2JZ+rWRRapGAwa1ahQ8zyqLly0bZFXhUMamNOSsssgTQjV2rjSkZ+hj+3ZOSq0nJGDsTb8aiUfLKASJXb91PaBO3IvLIaPbOsRewARQcoOkDRAYoGgKKGanSAYu8AhTa/avPitrR2DR7ehRd32YOb1nLqyhc3LWHPGQjDI7ntR3bHEncqVtySJFFva6dG219ytYGnz1Jq0ea508JioYL4KXOFVpQvtVmomMs9N1zo6Opdqmu2ba1Qsrsdjd17U4VlhHmv7BSaOLcqx9YKoqzdWVtRZePLmiSIS7y+0A1BB2sqUuw70McrZ8/V1O7K6bOjzg8G9ZZtaEeQ9wn0Kjfd5ZZKQVyJMnUE/9ZAU9sewYGHUSjHor0jZ3G0IjHTy9JRswdDzUp3tCNn+0TOVrDv+aZMSStI+FI70iIt3oox6V6Q/Du1KO3kEw9SPtF68zuusmOusmED0mxahQZqLBN2X1v7Q7pSo9oykWCrIuVq3UJZOKtqY1LTaHk1Jac2YyLpmEC3rGJCI/1rpdNKutxNQNqSg14XcarBIB/UrXxrNvddsrn7eEVbBKHdpO1a6a1opJYpu8g1OTGp5zXMmdIwADaUlVWAKwqp8yWX6rJHuO94sYs5kakzS8s/kkQtc49AsuMetjhhNIrDXJrBOw31oc8AxvHI50pML2J2lb7HOxAJgrXIeDEgv86Yb+gaZqE2U+3hUpl5f2ELSWjIcuFQsB2sBovveT3CBtNBj3yOZiGTM+G5ciDj6RRtp0bJx88WtpERNGBDmwO1/GlS4PQDhPrC7+q0QStpR/8PXH1I/rTbOCb3Om1NcupHeqdXVzJat5zgLc8hvzWztjRF3wXYkHKYxNKuUfq6FebTscp7ooO7izwRS4MxlrBQ6mZyi0WijE9q08BmSLjMGruc7ZMfIa5iTzNDqfggcETFCNI8uv9BqE/YV64YCIZvhH9kQjGGaGGBGXhlxKgL4hE3VveCuXtk1D2mkjvZMNXNZB2nbiaNAz5t75DY1ZG4pUPt6NheQ/6m1qV2vomU0et8E+u9zqlfEbc6MT1tFK46NTktzSpR+R6XAo1QS1E5kBtfEE/4UxCwKezf6slO/d2EiF7trV46uu7G7uuN3cD7vDxk+xZe5VWXWplUtkwZU1bcfnXDBVbHjVxTj7tq3lInUtcmpMbtxtx0l0Z0rWd37YOnfQRJfV82+mraEfWR3J+2hg5tx93RpQf1Irobo0QbuzQImlQJe6woww3Qj/Xu0qBHa5sBlVQQyg9o8554tKLZe1O6qazl7XfZ8maa5tlKRwX6N7iy9mXlfinI6lSxu1TFpicVGYva+xHYvm5DNbvWgXhQRH1/9bSWLGZ5tNEVYaYVlSBVA9l0pxZ/3i0faCBTs2g4lDUUPBIV9PsULRPMAqBgpBH1VvXKyXdlK3dh2Am6ioS0WAva1rLHXqiOpXQsZd0D0bGU/WMpRsy43AzTJrPxciprLMM0gUQ9WkOQXGZtqWzH0OayqqW7tKFfk9JmFqsjtR2pXftEdLR2/2htewvLvGxD7cYoFaUeNIj/ryr100qpeDiVC3rsmnl9I5jNUXItDsyVrhHslkmMsQ3ZohE48knCJfImyaz1H2BNTD4XlrCwOIempeoV/Wx01c2ELO+bD36LQl2RoUWFaY+SXaihL/sxkwakZOtZ4i7VzP+Wzvx4MLxzkS+f+iJMOFejTHKFez7w2JQ6i4HZyRby36Y55f5RXL3Ti/NPj2dRFMjXh4cuHC7oVg4cT8TuxKMhGzhiDqfAckwq3t0n6c3cByHEEnBcpLGK2DejsNr9bg36mrjR7zN13Sk0b0okR3Ph8sliVSfYFgu+5xxh9Qk98DSim2AQtWD0Dmm9hqT7Re5b4GOw/DvYXSrtZdab9cabDQUgtvVmqZyDQHxMsEjvJU4Mxmxzr60217DObGyc6VsUbDf2mSuZWDQZ64N6wj8oc68VbDNXtUqw3L/KRK75l3rBMqGZwbgxTLBrLnGjXMVb8rvY+6K1kRnBVtIs/N2JOrcp6lzTcr5WBLppGegmjsuDIqIPRA66jktrI1uGjK/rnaZcyFPyKgMFWW+h0IyKJwYKacUViPhusV7sfdmcwQISDFpUUnf8peMvVfxlzePS8Zc95S8rGTYoGl1u3ZCH2nnzhqZIu9a6AVu6H0R7Q6YPGuQVtd0d0e6IdvWjYL3z0lHtPaXaK5hIlNpEbAbdLw2HXan2K3HaXq7/KwZoWl0RuEJbW9EI3g8VoF6sVZWAqyx2x7p2arq3xlHYTqzddc5Mp3C9twpX5HIYmvx+6Vz1UWlib1jrkG49tqjv9rV/tuxTCT/5uMGmr0xuia+BCKsixUFksvcB8+FrWrncZ93EiatqSSUC4mFF3ImQ+S4LmVvSZYnLut50HdGsUfi2D8xh/JoZMoB5MUxMuym/Zj5qfh/LJxbZLAD3NMzazc3NQP8FZ6IQku22dxD7/LeYnau6cCVugfwGnnCZ+XuTzvd6TVSMAGZo8Rfuu/klyi6MvgZQEEWbugGE+ng4mFu2I8uDBpkAdB6joAcHOtF+jXoHMlrgioPLfNsAAbkDaG5FySHbqiZb0biE/MNrrp/G3msUMmCFmTyox9hDDh+QktZdRFNbypHMY2PTRvHQWyN7eLTWWMMUvlF94qh0wt7CeD9t5o3W0vL9743GumUTR5zWataN7cbfAewHYvL+7dm5ryi3UondlpE+/XZdjfAZ0VQzsrctQrdzCdQSoqXSyrWVODVbw/0lxytNo6PK+yf2WJqBbe8o7KqePB1tvAPaGLeWxXeUsaOMe08Z76XbDeQSMrEw13xilycLKZP7LonUb2RJSZj+iqQhUDYvf4oDT1BXZaiyDltVAhElFbZvYUSjWIm5rPzwls57NdKsRpehzHeWf6SF1Bf+b86jkTprtqTXIoDMB2lTQdC7Eo0tafZ2I9ksCmeq09Wur6sdwVovXxek3MWRfRQR9Ygfz8csBP801aZM7moaQ1iy8Jo7zBqnqmUP8wgf2lNW7OdMydoI/EpA/M19kiQUISDctHpf3oe5SoV+fi7MJGCh6rVh+8fD295BBMsyql0z036a0gempUL5gkSRhs6MpFd6SZ/DtNfAnMBcrzNm7RMWxXmh2SJsFfMjHjI9LkAy9cs4HBr4tyFbNYzaNPa4o1nZFkzUVqYvHYy772LHhhqS/QJ+u3KGKZE6gjuMPsvZtzRAM0KJWleSFMm/laAYQLAcuCPRjEZEpduVoB5W7kCaTRB1KxX7gErGYmGDkK35Y1oZAtEwOoRh9SH4fRskMeFeCYPR5wZ+JONFhJQrn4tNrQJwcu7Dst/2DlAL346YYpXbngZ7BUZH58jS0CvLbGJ1UriARTKCsKqGNvfK0GMx5Z1Hp+RGoxd9Argkujxus3VXy0agTQBgc2BlqCcZZpnLMAZcar1In5qLJfRR1uPqsOSu7f70hVXPvZHlnb9xw77ynd4iVy9O7z7y9N2JZpazZ+02tF8Muo1k5vAP3VbzFFB6vUzWpzKGnGR8quDEFyycU1+ZKRgXXeqnIpYce0ZPXesUFUScA/I+NSSKpZK/8CSXzA33POIJyYpSmTD22Hp83F7BllYSuWXaWeg8FYOkSV6pHRKnh/Lk2CfytKLXfGBdTzvplIbXyTXVh0OlZVK3GDI4WdfLEdcspFMUsOwTiVyeJ6uVOFoGzOET7pTRwrrnPTEVU/vdKsH0D+Dt6bKIcg+DL9W0VUFG84m29AVWIunMntn5rLdCGldP1ZWXG68twa3egg577xx750VtO5S0Fc5BJ2r7xkRtD9PAr7VaLiHZKxsHKkGK/WUiwvKHwlssanMfkL5UvhtOnYhfo+VL0coBK1a+IQbkgxKxqTg3JrRhIspTb4RxMhRw2ZlS2ApLGKVEhHx9dW3Nm2GjGa8r2NA2hWQpf/jap7HLI3QYKOMRjdNo1x+Sjk0/NDbdcL87nnyv3qKSRVbFPeO0q4rMrNAFq9k4sa/gYRrZjq6YS7TuIQkX33Kc07lAK1hm6j9UVi3lbRkRGurDqBcy6i5UQGCij1G131rCQZMIwVSSSZzpdGNMsypkxB7kgAZ/25UrqyuzcnUDZ1ZuYF0LMH3XrdgJaPVW76r7PfciFia2J+NFgjus49r0FIqQ+CIakM8+u/mszuQ/YxnpU1lzAbQSWED1pr0NyGcTLnuFvlpesFL35BKtqM9uLB2l/kuPEvhuO5FJHbHpoFdn6dZZuu25pRv1F+8nldywDOGnofQrGEFJpUIU/k9bNJRrRJO658HDENk1jJTzsAzlcoK4VoCseUyEzKsGcOu6jhrQoPldtVf6gNE3FUsA+Vvqi6HiqegKExH7oAGrEvXJjE/GgPwi2ST28GMM0XhkRH1Ugt3MuDMjLh5qSWY0HVmitlzrvYLDbWkSsGSNOsTVIa4Oce054mohSTXXeWST4pEina0AVCPctISmdIjpgSAmw3q/EbC0mq5zLVFXObQKp+JQzmkYjUIRo7ilEk6FU9HHon1dtD9lUb/ks/YPzgCpH1hETsOpIJdQlHxQRUlatEoEDFTvmnox0vaSFpR2D+VourHqKIVm1bVoD9LJHfQKGsuGlALmreyORtwFujzhILtsJquqWI7iZBJKN9gYibMGDhQooefLTSybj1oTyu0PWhHmvFH4RshwYaKVhBdDb12akAW/hhwNGLNfUxrqTMCWmEsJ78MPyeFLwzT+SQVX0DVfh1jzVlf1qH+aiXb3x8EYzIcRkxoIGbEwCLlMaPQkZMm/g1AkAR43ET4PtmaQIQDLLFZuq200isREhW1qSGUuoHAbOnOmDQfzhAZB/H0hNjsIamL13y6aU+WO7DmpazPujtitTtd6+a8YUumhUDucTLmmHoBXxCHQ8sihaNlVibxUsb4uhqgr96kKcX3EYuQMkqbVYCyju7SL5y2nqBZNZcqEzI0h1Y8I+RReqCGdgDnqeKEkCf6UeOKGhThc4mAVOCBMC8DjIDA/glMocXAvJRmziQgTuQQ0o++VqrYQcai73A35xZEnMbFWhHvWwlkcaTWitwnxWG5Sq4jIapq460w/VUuTWPe1mllS7bZ3wEssD0Fuk54KAyCc7FaXueVWGxwe5IgDzHIuXOjAHanz0GZrrJoFmTUFi1E+Z9oBTR9M2BNTrWzoiXM1xo6D+hmV/vHw6Fl/eNQfHn0cnrw+Hr4eDgdHx0+fnfz9oHfgx55nzxlYwXvIppTIFHLLotyk4xJh4N9syJYhTigoarf2LptQPEcHYjKxLBJw1eBTwWMaKYwaWi89XT37O7BZHuGiZOjxpmRlDYjLxiFK7njtKAp5dpYJ6thPkJBl0au/iXKsXr2HGvB/HWavFgIos1Xg38TlUv07c4c6zr+E82//7ZUbwirPrw56dNCjgx4d9Ng49GhEXjrwsc/go0ZEYTobBR6tcRbAsNEh3EQo1wdFXTrQvqprAxOwkSGniUb9QhcoNaRJSmEziYUMcahPZDyGGmNGIrEbNDDmEMM1HkuQi60gBiib+Z2Zx2QnswoPrm5hucFBfgbN+0mPVnLmMDpXhq6vCQPWttNpPh274sbNT2sP3KZtJ3LbtBuqjNLoD/DQgclVCq2/454HPMno5szfbbRyY1Vn3/VxSMYHhuwuyWPVgO4f/gH/sajdbVNOkGUCfRUJJMsLsmeTvEmK5GP74HeDtbJsQXmmrMAacvPaNovo7SVPKt+BB86V1uY2u2Qum2YKS3a8YwvfMltAWWQ9V4CLsNaTIPmh9l2Q7F7l48DzCDT1IN8G6ew3HmIvO1JkgpaFgecxR7lDNYaVJWPtiMgDJiKZ+9uekoxFNEoTZ1fSkLHI5NdW8XiQsIABhDKPKRg84JZ9JzLu1WemaJVrHpKNR7Ky3g6IR2auK1CP3NDV6myecmSHmd3IlIiMQR1SQz7qB7tx0pEd9I5oB8zRGElVU47sQiQEJPs5Q0f2jiRkl7eJmrMsPV31Zde56Uruu1ZwtrjyJgcdQIXSQ6gjSNpqzyv/ysdYo4DmOYTqVfmU1LheX/l98uc/Q2Pf8+ksIu+Ey/78Z/X1Mga/pPLfct1Dh2+TfYNCV/4lY+QfUA5ZaxPnhbEAPwB8tD/BJuegTLUjB+q8ei6fTJjy1YLSV/7V1ZV/PgH9KgmZo8KoxsE0RF9F0A6LG1//hTpYqNYjIZvAU0dgmxPheeIGTSTVYwbDljnwwCFxQITnZhdZDq78MxEsMJZnQGXElIeTqkyAiEADKkorVlfoLtMGGVPYD+GrYTnGA82j/uDK/9Of/vQncmZGUNzi7NZgrSv/8+fPQGCu/D+ufEKuDuR4Mh95/AvzFiMaR2IO/j5XB6/J1QGFGV8d9KyCOtxas8LXLFSqMdi4ylIQj4Q7I+OVMgpCESmMBlUwkr8uLoKIz/nvbHQjQjcImZT5EjIO8PtIMkQjI+mIkCWlrvxbXIDlS3f53ffvyEUo1l20CSw/6AhXHsR3/PeKQazV9nfvrAtJLtV7AgmJ7u08AnIgo1D4U4wJDsyE+ZhuDQRScJeYL+OQ4T/RV/cfTiwjMVchvJvc6Bs6OVR1+lgH/Y9gAA68bIg+Curw4/XQBhTKmkMndVPrpMOG/6odGKMZk4ykZ0n2rFa4JNexB2wA8H0kCI0i6nyBK/ugr0ftidkPJLh9g5PcELQhesZkvnGu0hyb21NAWj/Ybx2QPgDoqbORNniOHk4Yc8fU+dL0XYog1VTqay/VnFALaaopQ0IWiDAqSrU+YAguJdfKFyZByK65iKW3ANnWnEcRSxN56jjQzNWWet/na8+YFxA+D0KAUi7T9BGt9WY0RKMNDdlAw6Jt+ZCL3bAQLfccj0qp+qCSAEEGWDiL5xSB3H7QxkYyNjEp24olN9tAWrzlWlT/hx0UWKNWDHJgUTltOfSPP3TaFXeEdkvHw+OT/tEQLJSOjl8PwULp70UpJ5vyiAOLJM6MOV+Qa+u9AY3C2BPOl3Q/UIuAXE1VR3SBftWE/UYeyZkIBnoaAC0eIe7GMpqpDOKQD2CDIO9rGMkRxDogjw5N54+eYBVnMshemQFiSOJF5ARss3gogfRikyPJmG9Nefiq/3T4cfgynbJHl5Z+lZbWBeXB66Pj4TD9ezRejGgUhXwcq0wwkQjOL9RBnIOcx8E2nw6Gg6Ojp4OjYbatl0Ogo2UFj7IFT4ZIUkVwQaNZrvlknbJVIOrDp9vsUHHBYJhHGBaid3B88Pop/Pfpwetn8N9n+HdZrZEMHag5Y3EI8fEcqZuYo6kPG3mMhj56Ex2pgBMyHmt102VA53NlDqS/IMIZBULyiF+jj/htScC+VtEicpfUXLWRumqGo5Wy4YRs4S16EFzXTKkpx02W4AMuV5VIKF9Mx3PYrTxJAWfF1fHfW2Hrg4QhLzVmqErQWMuxk3RYKTG/RAZLaJ5PFCh0VcFKxgyxKT7DrfoMjyruu3CWWeJ/p4LxYAtcQrOwqsRcT/J4KoSbsICJR6fThPw/ISiyUjV8NqWqxlikPAPt790nA/J9HEJ3IBzCRx9qzKgnhQoXlXKRz9A45KIK2UQFPIVRK7a7UJYYk4lKPGk6UcxxYORXKICijsMCKAQitAmEpVAJXNKOCKyJJDQiDYVcjvChTXmYIi8hgsM/wQ2zeliztXSAutEe8nZAT9fMW+wN7lnnTWgjG8UOzOkZJUYJNtL5PnvCTJlKI+lT88wn0glpAFhTHURAnwkULaCXLHi5ublZDbsEoXBjJ5KPaqHLNCLHTbDL8auPCEWaYRco/bwMu0AkqJWxy8lJpq1nQwNJ/vP06Y9UzliuJh0fHTvu02dscvJ8MBhkKr+qwyZPhwevXyIYGR68fgH/OBkevD5pC0s8xFc5IKJPQh6ImFOFD7UsNqk7jAmBXHoYLUgN0atkjohK4sah8l2acr/+SNJgRTiNbdefx+ZQ+qj5cYTSR2XH8aT1aTx69XJwcjQ4Gg4Hx08zbT03p/EXycLTKZCxbNV34nfuefTwZDAkj99Rh/uRkLP/IOd+xDzyjjrk/SX5L3I0HB2djF48IadB4LFf2fgvPDo8efpi8PQ5efyXHz+++6lHQOhIfgDM/YSczUIxZ4dHx68GQ/gfckknNOS6Svb2HdcD8qNjBciPThQgP3qqAPlR85N/og/+s5Psuf8Jtp6cjmN8G1Zg8CwEXxNqF17FRzWwW0MP/VI9WArTsSDKyzuo3kH1hlBd4+1SURw69qj/D8JbFl6zehOzrCeQMgzBT7p2ZWAM5ab1QZWqjA507sNoJdMOrB6fMHA2w3j/Wn3BwcBzQSCnNzAOkN1hYVScQDptiFoYCXKWwM5HGK5ScolurcpYFutD/Mpx7HxhkKVdWwnJ/EgtPdSA/Cwi9lonj834nyGrydbkksz4dJbXVAntyZuUs4JUOxCTb0AAxwPW/0eCookrnEbqK7WhmK7uMLMx5erpPfHpbRLNo/QAtfGotXE3uPdVDNoUy486c0lG0ECp6KZz070zN92llRMSl41q6dO5DgYUsTCkcDngDz3Kxci+Ebp7jCR523npLvfSzV7bPXTTzQxwoyFC6ilWCyddm3K9hWG0pV1uPJ8vRjiDREd70Bz23o37L5qZqTVcqkZtHA9Sf7T/vW5Atf01HsZ9G5jRDmzqt1JglDIE6MyoP2UNQOAZFuxwYIcDtx3bZWle07gt1shiP9VCnlNoxtLUXKfuOqyMaisxSENQ63eY9t5i2g6MdmC0Aow2ojUr4tE3zOes8qg2ozsutjECy3Vc+m8Ema4BPPc8Zm974FkdFKdERKlOypqCStVGvZjyTJfJXqf/rRX4oLsvKW+cMEJl3p0p0SPjWBmqzyEHKOqbTCDAbMkBOffJHHRfDpVM9hTxNelzqQOXweNyxlyT+Of4GZmJOJQDogcIOUpD1lcxhXMjvZlxTxP0IBRAVQCnCn8qgBiSvzAWgN37nPuWcb1uM/ZdAcYPDvUd5qlGkh3YEyTZXqKo9m5F5HUGu8GidQkhHpuRkzR22zs49/tBKKahBjnrts39UdJch/VWxHodOWhFDkrBTUJbs+dsOeqNfaAnSebDkE1Gx+MT9uLk5NnwGX02nrgvXr46Pn515LBXL5xnr56/dEuw8b2EuMx3R1HbG1RGBXRDcKfAUmIzjSZNqWaj9R7ZSZtREQcjE1E/WTNoFbelnexWXWSNJFflET+LSKWl3AQd90U0Uo19I2C5E+O2QNNwN2JZbZ9bhpDxHi3FyJdQqkPJ3whKrtztVWlgh2Y7NHvPr22HZjs0e5/QbDUNXxPPfmD/RE+UTRDyULc1csKiFurBYtpOAGxZqWoC+hVCEU0BguIaqDBEWkuNyRdsegz6/Dn1VfQcbCGvtld+YVwqZQ+6ACg6P2ZI6n02qBM7q8wnI1Suj0I2RceZKrmzKtzHwn1duMI/XSdxwaJEFSVzGgR4kurc1M8v+pHIdJHUS0KqWH7qygnuLXVmphiJmOdJyyoCuKUz00O5Zr4Lbm1+MiqVBxza0mPGyL80IucXPZWuzsQ8Ye4UI5dAlj5GrjnFrz6jIZPZxHh2MhpH9D2BGb2V7QS2rQYDzvPcZSHYZOgV8AmbB9GCoIMsePH5xBfpCrCvXEb3BFsvPQer0mVcobZEueygj1RLt72D6EaMkuO5iZaTWNgdYm+A2FuMt3K1ddj7jemUlx/fu09CYtLVW3d7A8z/vZo0UlDyQfMEzcTf6B55GS4HX2TMeXxMmO8GgvuRBCbEQvK5wH/U0h5mNvIz4b6MGHUH5KNqB05bDDm+uMvmgUDDtotfPhLJ5tQH1yjkBMoD5P9VMVl6hq6iv7NHrbA7ckYD1kPqzxXNh+hlIgTijH510NhHYyON5S7f/IU4HoeN0oM6ajC5aub6OXkFqjB0GGnueHj8XAXvgMPkchl4NHlaMOEpnztdJOMwypEvB044uj4audbm7BA5WadwGWAqQxDLvPD710c1JpulmCQOJAuzqOQMjwg8fNUpAVZbc7sLGOXUdWVaG46WCl9VA1hyIOUXH90LL95ffuzlnt1wGq0D/u9//Q/hE0ILDZ1fEOrB03OhkIAkHP36xTULb0KI4OOnWAKTdmlNqx62q+JgiAlCrZSQZcZp6j8bPiWPHYhieHT0/NkTBUaSkNgzCvwbNtXFjx6HuAViQp72ToZDGKlpfk/gyqY82qdOsAGEkHjVQnMrvwZrGm4cVq1wMWpuxaqIDe9u+4d0h6weJLJqdeJWM9rj/jX1uDtSzz09m01c2/KG4QUh4AXhLzb5jBgVG92m4KhDkx2afNBoEmSKBk2Wqo1LwWRJOCdNwVaBkO1x40cF/FDlBMojghSInF9cPwMaen5x/ZxQ1wUdoTmLPmg6PP67csNxqC988CYieA51PF/jF/T4w/dn5OTVyTF2C609sTHgMMGAz06elKFSlJTlYSkgWFCwXZx+PPsxjW2O8i0ogTG9/Shc6FtQkMqB3A7niaiVTilcZQ00pU7d/PmHtx9Ji8tymFzP5Po8MGxKbzbCdgw2heb2A5tuHJGaiCQbWK0kjHEHSXcASfVybw2TbhqJasI4UoRxE+ct1yJ4UmlQyjfyMrVas9reFZLu8G2Hbzt8uxq+VRuLCLedxvfwD/2VB7fqoILQsCE+1oVtfPwGP7XFxx9wi7XgspQCY0BSjZ91y4A9FfhNkDKezQTV5fCwRr+eEF/iICssVRNxFTCFg6aZiQ2Hn6Ui0acIh1PtrMG+xUit5xcD8quRnkJMvVKkDwM1pxy+4W3xFghyYo+hc32IVxEDq+rR3j2CTZPQJoco12d2m9/nN47czIRkyZrImYg92Ch7itXDzlt5pQZdR6+OB8PB8eCoqcZaH9stwE09kw5udnCz6UlbDW6mbhMbOGq78cHoYFkHy/YTlvGpj0FcjYnvJrGa4ghaGtnc2g5K5l26W8MsSz+8E5i1TMaYgqpnxwiqMlpm2/5NhOZnG13lij0ESBQJXDsCGBUlvXCNlag3tC78zqARnLMt4KKNsaoOFT0AVLTskHWQqINEHSR6sJAIQtisILsaG8PAVlIrrFUmu/oOftCih7ZuDEp+FQfAvo/QCq7amQE8DQzIMvkdlCPD+QVmS020n9x3WQBBFdELBFSrKRPwFonYCnNpITwIEVlhTbwMn7E8c5n7WTsWKDQhtTMCylu0zwgSN8z8gwEUla65tFGgWUmLd4+5miW1b7q5OT7bgt3gwRptUOBjN1gV3LZDOttCOmr1Nwx0mh/DO/Yx6B2crDd+DjzIpx7BBWptxacqq8DOG79LueY7QNcBug7QbRLQjWPvSz8j6GrjxKEQWokrh6I+Tgsr4iJWy7tzrIvZAHwtQ20KS6UwDckfWLfBKffzvy7BWxV2c3Av2DULF2pEnRndKmZ0ikskZ3UzTCfQQMJYwK2bFbeNuR3k8v16rlqFpGMNze9WuGjr4ubNeYrklr2DzQ8FNrc7j6vJDO+7N0ctbm+3gHuJ4NWtzgN4OGVYSLM8+OfGOq5quns2dM+G7tmw8WdD4qvTUhpcAKcHraLZJNWtgeZC26RHyg4pIy0UXh3hJtW5l9RS0tgEshNMnqAuQB2F1i8Q/ZX7jhe72oqyOiYNhqSB8qB41z2bgxtLHWAHlxnD3WB4NbBgTL1/IhpOWaRi4+AdnGpHdoq5zK08Q4k2PxJkRq9zw1IB7vbAjrF5UJsGJ2BVhbhuqi3DSk99NpJTB3c3D3cr1nor8WeanLQuDE0HUzqYsnuYUoAKzeAKeB6PfoupH8XzEfOdcBGYY9wq2YseLjTX18310+Yq01TrW3UB1f6qqpG3SbWafIUyCmMnygTWA79ecPK123p88dcn5AtbEDoNmUo5Tr2pCHk0m0uFIRzh+8xR0EGoMLtqMgNyEbIJC0OUepZ3KHDRYx+ciHWCROa7hGZH8YUt5ExpsPF+qVC9mu5CM1a8v8dw2yZURhDFz4wNCGsS8EYX1BuuqG+AI5Xk4q9Petb1nTNqgNzFX+2Zo8DXvQZ2C/AKAgkL31sosIU9aWkd/LiwulV0Qkwm9W2D+j5t/56gqeYHsg2e6gDPmoCnJGbzq2fPnr14euLQ58MXR8fu2Jm8pBP35dNjNj55cfScbtQGsOWReOgIyF6H7WeWqIVWekQ20yHM3hlPEU9lDX5DZtR3PdA8ZVLajhfkNI5EX7f28adL8pe3/0UeFwGM2YNDaMCI5SJPjr6wr5+fQHizMfdNZFWrOUxXxSHCOXmHD9y6tq1mnaQeZIxk8vOTATnVNDcUnifiSEVcZy4GdQevNT+mHvlcz90/J4d2DClyMXUvm0wYPpWRwGOAWQ3oKrHZ8EX/6FU9NsMiJdhMD+83VgrP9jubSCOX2Xo81CQndNwQfemM0CsAMJ2nssNgHQa7F0rxbaacrieYG81B3UHMDmKufSo6lNki10MHIjsQuWf5PbYMIpXQt07+p6SE1BtFqP5SaWJai/1MK33VSrZIQdr3QZfOqtzaAkxnxpwvhBLTN5nFY+LSiBIHdwWOFhy9G7pI0CRqGwkMEuTVXGLOrRnzAsLnIBhnkNoEMzLB/QL4J+eQxwczmMQyEnOiZqi1kJEIhCemnO1LPOkmsq3a5e/wxpbzvuWWJknP1WpmSbXbXoNsZ+V3vJjPrM3SWjXzF/aeJEJLngfZ0f8NPkPI+AjzGZVdFTQb0NMqm0mhN1ihCcUDcSAmk4PkuBzg8sGnQuIxpBhqjL30mPTs75/StHilA92o+LMZ1dgDPLpHmcb2JHvuhHqyBqvonxGs4L+3lY2sBCM0kYCVe2fUyMCaoxH96OoAyTcn6CnliRuV73Qwq4NZHczqYFZrEWCHtPY1p+s9BVI4wxoZUIYFIr4YaRyxGClD6IOaQCZYIQu1tHdtyS9lIEyHnbxEYNMIgZUUdRc+nSd6P5DVahtG5RfreEKCFi/FW8opFWzUxURhsRs2ljxi//7X/5FawyaV9NUXSZJXZZ5uLnuPwNGYEqjN/f5MgNLTBmxoEast1QEJDmzI6AhPjdOjEfOdhcKKybA0dgKomMTSUyo/tPlUUXutihFE343g6EOIOnFDbpjnEeovbBt7G45yaZSaRsyc9IOiYUCywF57mUFTIwtX0Ymt9nQiWYivdwMDN6OLBAh8o6yxP4bzS7rbD6zaMBJv9UHtUN39RHXZSYEhc3o4DEaBRjAQdCtAYnhOAxL76dtGimW4LIvHLBxWvIKbDoLc4JI/EARWspZ7C8A2o3RbC30VQc3ygLqV0XRLEBKo0xoCJxDLdqipQ037jZrqT2kHmTrI1EGmbQrXSu7eHkrWtojoGhKgDs7tn+by3uG9ep1lCa7Dkk0B3wVGyukgXwf5HoJSt010A8X+bUSgrlhTneyym9PB0A6GdjC0g6FbhKGNSVAHRDcjVwwVXP2GpI1K0ds7AE+BRuhT52ZtCD91Oup9wZ+POvTZoc97gT6XXpwOfnbws4OfHfzcIvxsToM6/Nnhz9Xwp4KTdaaG1zTk1I+s9ONFnFrm2WHydejqdXaEpkwlKP2bKmBic+hYrzIh1EkDYkL4HC6WwkwOCyPKfTLhHiPsa8R8PAmYf8N1OULOTAAR6mmnDoznoRJrlAQPYeE1CzFYiYKLj/5Gw8Vrcuo4LIgepddyxqgLfiLnk8rquaoQS8QVTGIMECyoQlDqBUjiiih/76Qj9NHWmddwH1w9D+O8zX2Xo9OyWpjv/vfF6eWl9kCREY1iacKr5Aa/L14pDS398kepg2n3E6a1jPnx/Pmr8WQ8PnruDF8dPaWTF8MXL5ynztGrZ5PxxHGH37hPRytLvb+ZK3SmqOum7fQqr+gDQTH3yj+iHrDY7hHbQywJwljdKq8qykUt+gArgw56dNBjE+ZyHe7ocEeHO1YT9FRIdZKtLpHqZHefXvNJsQ9MfCAmRM1dplL0d+fv3hLoBIk2nFOLzun4WnKGyazHTFFClccE+rEGWEizt1QcdWut9T8OkF0c3rBxAI3gH/8M2BR4fuzz32KmM+3pmuN5sItJjufB3c1xupuNnN7lPv4zON7FHP8ZHG93jnjrKufIpruZJJve5Sx3NMm7neOOjuv0Ds9r4O9kJwP/Dncy2g1tjbZNW5fMcVeTvMNZYsEdzBL62fgskTUsn+Xtemq5rQmxah97nQTr3nkk7I+Ia+XgabVCLh2hppNzdXKu+xr4zRy9jcZ66wR2ncCuE9h1ArtOYNcJ7DqBXSew6wR2ncCuE9h1ArtOYPfABHbL3nudzK6zOlshDC88ZiYo7xnROJpB+kbO5OFMyAgqj6iUwuF4fvDqlZqtOR5nftS3GutPRNinfZT2eVxGfdNgP9OgLeFDMvKjLkZOs8VKKE5p0d2IoCJP2pOVfeq7yQxzIqleMoI5JkOzFjwdzW8xC4HCpd0X/bt++eX8DYgg5+jNTacU0pGq5yGxWlVkFZ7jceAJ6jLXyC3nmMTNKvmO+nSq8qGaLGkogPQFKRkruINO+TXzE4Fi7EWp2BC+JUtAzC6r3tF3lqq8bJarqOrfJWenZRKDVDgwPj56+uzZ0+f945OTk/4z6kz6Y3Yy7h8/d569PHr6/OTFCVyYOf36E/On0ezg9dPnvYM599M/G5rAVR8s8mEVudoah6j0Bo7MFA5qOEWDSZDvN8wslkxmR8wD5H+XM848l5whSbKPu9R3BfhDJUu5vPwJPagz9QxnKf0RFUGf1ucW23GqktIb2GTZovGDKpK8UmLoehYQxE04wAcWeNRhDZlAben94wM7ciBfgao0diavXfF7RCCbzaOjke1p5LdBB2tzm+Ka2tBpLdhcLFICmkv2sRwywxPchDKBLX4kiXUcFD4sORPjBblUil/qu4ci1EFNLiiowaH9/aO2KepWKuumQNuefsQnCJP13CMBxgEQx8RA3/GiHrdSz7M89dVfCgXDejHf5f50FDL8pCix/flaOOYj/PGFuejjn0wsoFPWdFoXdMqIH8/HKjhEoHaOuWYq1jxUqQMr4sARYmk+h2kcZUbAwlGbUfycDCBkjghdCaFwYDCstv/jIWJ7NYCToTWaE3s0Hp/zqOlQfoLC5mHkF8YVsigO/Ywmk/sRm+LAkg0+Gtr9i8lEssYDeI+l7ZfU8r6aP2HKbvGu+XOREibMeaQjG6Xgo/ohUzeVjkVv5xmzRF4mpbfvoXSR35fyzkquDvy2OoRZPa/W0cyKhcqimBX3tMCtdUlKfHbTgEXvH//dmSGWI8N16ZQM+8cHymSEuzxajFy6WGqqtKTRTFvQfE4LAMPO99jc9KvqHO0VjVdh9ero+/J5rETgN2HMtmTeqxi3tWhyh8ZuPdRStDF5s6nbmqfHIqYvYN5l2ojF5jpJ2+w/w+6Qg48UqVyvE6slbDj2o3DtketWoMHNUTn2NeAhkw2MApe0qBpCG8Hb3sGE+1Pk7340kjN6fPJ8zeZLGmxkLNmeYtmMq3fApYwb2UwuY4dJO7e9A8+85dZrM2nmtncgwin1+e+baDbTVK5p6o1in0cb7MG0iGA55NQb6Sffel1k2uo/xeb51KcRgPM1mzbt6Ga/8HUb/MKxoWh9Gqra0I3F6zIh1Uj/6GgXeEhzIbDuLQQvrLOS6C35VTOyT/flRdbi1bXnIfxWeHXVBu4rylIP/ygl4LcHNVH96p9uOr7fkqfbB5TANXm6XbKI0AZvNhA+FYV9xsMGjfZCAaccRK2RIFoGqAvs34svFYSV7tAuxrOEtzeTn1Xu9D17XC2fRyc962h1K1q9JHjZEhFZ8VeXRZR7WYVWyXl9kxQrujDr3/Su6kj+SHFrj0FHPrdFPqv3757RzwYT6Qhop37YGHGtd5uvp63AapYjWK1nboRizyfNQCxXHvJVSJb1wNiAzOmChGn/PDI+AlymlqcdSV6RJO9CzZLunlW2Qr58e9vcoKzmTN4zftFsLh3L6DB3K7ZQ47oBhvQjnaBJhIdh7NXYmmkMLmK3n1TpqyoZLqG/5M92FHJ2rZNKoQU/OTOtEGwlSYBlXNbRu35AsEHisolJOhWFdDLhDnAOSHylHARwYOgBxh22qzgi2cVYCeuWLURigbrr+Bu5+awUgKOmjTuLwNFmwOpEb8znLr/BOV+7jbna5WaxjGr3Dk7u03A36hqYm6OiLz+8/VjJWQo1VOSu/Oc9N2DOrfnAkO7l5kxl3hpZbsD8lBuAq0Y283cckXKu8AuaQcsKfpAygR4J0eAeBdkziK7FpXJdjSHtop04cV8o/0YhdcF9uS1BO2gMqDuO1HGkjiPtA0e6+KU5R3porKfWP0Ztd185J/elQ/1Dl0sTQ63c+PaGTvqmItTwuT/tm1qZRGzqG6wtFCaXurD9JCnwsSaVCHhgf3Ymgxs6GeihjGAogz9/JhN4+EoCLs2+IJ4AwyUSiCCGBLduj0ihCTG6ZodswkIGyX+jGZsTGYlA+XTrKGTb53+wnEEo3NiJ8HiOY9/1VhH2V67cSkEIVxhy2T0/rpPSVO+1og53OnI9Bj2DDdGo/Ezro2n8evp9Iqg/ddAC0fr2Kbn0fOqLMKE4lZTDurO1ikV9lRtTDJ1/th3B0JVsevHWb08ultfBG4933Qp2wH0ZYDJvPS6ioFUxTANGJQRRmDNjzhepqAQ0PqfeDQ3ZALtMnNAMncG69RSqR25m3JmhSF41YSgR94kTy0jMNaHCtOTQKDpVGay+I8HMxshT1U7tLXWqPFodcbo74qTJRmPaFNAF/FEtii0lTsrbF+8gfuyzr0HIlLi76PGLYtj8KdE32KqIYbcqyFirdnLCXUOmeoRRZ6aUeRxiat/4VhryATkttkUi5nlKjoxzZ6GSCgtUEM4K1BG1i/pBDopDqCMiEtBQMiJ8020PnnYzQiUG8JbkOyrZ82d95jsCSCv3JXfBn+o/L9//TMbCXdwzUoa7lQhOmmzZrmhFSiesw9vCv7PVpNYihJsQaVQswiqSjQZNFVxyqiLhJXNaoUNr36DPfLDljJX2nbgmtTIN10t2Bzbiq/Oy5IMWTRd5W/Zbaiyzgce9xYgGWZ6zoqdsKXujrtuIuxmXwCa0oAaj62ZgXQE4i7BRkz1I46AMWRTq1og8IVGejnSZ8j8EyhgsAD8qyYeLBQfkLTA0i/Uhh2PFF4DNDDV/m3DfJTSOxJxGHK7SoocT1reFfPaE+BIHI6ByIxV64vEsioKBZpUD5HEhvemRqwNgiVcHTz7vGc/LCNmz+3cKdA5WuslBAP0x7vegZMxrC+uzXEKDuxXXwL4BpqU8eTPfP+Xj0TdXAjS/Q/cAJLShCB066NDBg0MHdS/dnbP+Wnetmsfw4R9pB8v8tcql/dpNqwGGeINFCW1AM8gkFPNqxYBqqNkjOQ17jUFSrXdwHiRkeJfSCMwp9wdJJwYXKLzgqgxT4wVWVuvg2h1n9Q4KSLj7w+tTM9rMEdhm//Yp4W5jbYba7gZbfQ/YZvPJdFyz45od19wq19ScDkuIcMr6eu37KFeFxFgmzDfkEzTMUNN62YiTDWqcR0oZqnqqVjDUDD9Vdl4N+WnNo1y3s2l2ar+54clo7UnHBAtMsObR3WBTIqGXexNP7QqmscMndtMXtT65DwMZNJ9Mhww6ZNAhg60ig7amcibtSzvl8pRF/SQOcsrYf2AVGmArCEkVMzd1nTgM0d+rpo1UXB6JqTq3CXdPIIEuD2fYgxSjdjLR/eDhjR6RsC5Va7Fz5qDDOdXanNQNuLM72Vtd3ap5OureAglxKUH/q9KJBtXHiySZmUUIMLMaAM7PygDH/QyqvM/aVND9rLOWgwf5bzG/ph40Daog6nmmKZeZVOaqDXw66BYSx/M9eiW0Ruhmx3YCzCtSKn/M7xkch/xI6wPl6x22guWnX8yGHxSgScuE6VW4N1nDvSTPS0fd0ei7QXgNUF1beU8kplMwXqs1Ry6HitEh9eCmqnSy5eGZor4powBhPE4PWh4Wnn0kp7owucwWLHcNVxTeinjwMaS+DCjYFy+I6ZjYnVpn2HYYR8mOJDf6hXP2kcyFzyMBVAPJvSINSMuh00TuAyeKUNcF3J06WzgMss7hAGSP8Amh/oLM6DUjY8Z8y7JxcOXvXQiS5pCzYr82TxaWBdGIRmazR/Zmtwml0WhCK+U77UKDbzg0eA6frH//i5syx+BvmzuVukEMQKuQxQbb1i3moYr5/uleRb217uC3lTAx5ZRrROyy2K15X1VxXAPymjJdY94YatC/CvO1ea7yO5HQoIbbUrNTX+g20VrhZgYc095M9GzCSOcZSc8jSVwBRg1ycOWj62TyiENXJIz+og8+WPGzaxYuEjN/dH4SfhQKL8UB+DS0J8ClTimrnTPVvbY6EFiOetBeT409CMU1d8EnU4Uk0BFtZCRCTIbl8ACjFyGmsCc0IL9C/aQTaH7OI3TvrG6BSwJSQJXYHGaFlhxoA6JBDAZJg3IK+7ngM6FzXQGmORoOC7gGgqmNme2SAVm0cJBX/ge1hBr9wBCtpaf4TADKzVwlgUNCQsBHArp6Objy9bkbq7dy7Mvkb/soqEGp7cc5SZjzBD289QrAzgnJCJtMmMr8m6X9OHEHk5rLATl32TwQiHpDM4XHvsgUewK9uGDqUhzK3oK3O8/4WQnIEtFzu+fzQwKaTefUYc0Oa3ZYc5+x5kPAk7W6QFQbN0wrq1XM0iukk4VvmYBLJb6lsMpn+TJFx70ekYyGzkz5wOjMqHaCWW1PAM3Zw1ZobcanQECCkGM+JnLDPY+MQ0a/ELiMhDqhkJKIaxZ6NAjgOj/y2JQ6C61Bf5RptEfGcVRbQvUAHvQLIFMBCx3mMvJI+ry0/D6Ho73PmV/xYG807yvGTmk6kIRzCRVzBU+sOsjmQTJH8ApcIiIeA1U0yJcfU3/xpEyLkQw3n+7Xh3HAt0+rpyPWqYctl7NH0rpYS9IPm1TDyZCSDyp1F44ezcnTxMM4Mh5x6vHfkRa3cVAuko7dw8Ky6L0t3JFrptChwF2jwBH3J2L5KqK2p0QxKSLqZZI7q4gp5l2vH2csCTxbRo3SBMwo6pmWKEDPtAkM/IrPau5bdNaoJ2robbYPQ1pr02fr2C+ajDZt/3h42zuIYFlGtWtm2k8ADk5LxBEqTzS5TLnjkj6Haa+BOZtFFXK6T1gU54XhH5S4JOKhyZQNWL5+GYdD86hdYtC3DqFRKMsOt3+/cpqdpfisQXzuUxzda/IujmLqEUwHUCbyXVZOm83cowwRSJP0wwD/vcmXQeEQrZOiuhT369TUBeRf5nZfYH4l5jxgi6gTU+egff5pvVfoeWeZEhLDYti4NWeQbSubIHdzOAkb1u9LCdFwN0IZTVu3cIQCT6ybDVc3gsmnBEC7KOSOep6u13ChObxgHnfWHbFuBJoLMTGEosLrtWm1dGtY4FotYhOF9OTW6WiblrxARPbjDdA4HXn1+LsHwD6IgXdJbrdJFTeciFvqVNM7oI7w67rtqjY2ktG7IBoty+i9bnpp3cht7+ALW3hMYsLp67Wb1Y3lnxHG+WH9w2G3BLeKuu99b5GIuBWP2uSBKWtRsUARauS9Hv9TzWwjvfeG02hDcya46/obabd020tw9CYFzBkIgBjd9HLPdElbednuWYaqPXqW1gaFKSquDv8oJdn1ObxL37Y6KEz921ZHwlj+tv3A5gJMhYvv2myQmPKHbemcdpIjsJ7/WbqHvbZirtqm/Xg9cKC73qJBxJXu+XCfng/bRp+dSLhjnKsnVC9legVuV5pHvUiGqtKop8kd3Wwy9YA5MIkKQ44e4b7jxRgs1WaWcxZRl0YUTDLgOU3UlHtkysQ0pMGMO8R+HCj7ESqlcDgqzPSTiKj3VdP8YB37XY/9Vp6X/eC/y6V3yyfQ8d/947+d+K4T33Xiu05814nvOvFdZ5hybx8yS1whS98x8KBbIrp76/ISi8x6oxStIYdnBOzVoQjJxdt3h2cfPiaGf7mXzID8LCL2mlycfjz7EZ4zNPvowHqpnXiJWbm2S8NcRTCGkEkRh5BXzSVjplKOQVQD8BY0YQuCkF1zAca9PtOFtDFu98jp7Hs6+57Ovue2ccaPcjp5X17uS0bfPdu7Z3v3bO+e7d2zvXu2d8/2b+3Z3ikPK/MSw5wa29zoK8x/V1nTy0LDlj/TQ9ZP66r3enaA6XP9g11UIbps0SyQOTfJicmMSjKPvYhDasO8w3gvyVcudcxpEboshNe2SmcezdiCyJmIPXhtk1gyl7hxqF7yJh/iNrzOv2Evl8wZqE7fiDvF3MKqNUu2uH2QsnH+eFvI2mgB73+oKR2c0BcvhyfD50fOi+fUpUevjpg7fD559fKV4zx1qXNgD+wYKDBWewXVnkO1ly+XVju6LfCLzJ419uqov9T78cZs5t/dcCbde7Nz8+7cvDs3787Nu4PlFbB8YKHp9QI6JQftYEk0J1OwENIp93tJQCd9An60StSFc5IijJYFdUp62z8InKqiTIGmwXa+jz1vQX6LqYeyGx3BlEATVrygKUQ1jXT2iWTqJm+7eX8k+W0ecfdRjzwyYxmwr9SJMl8AY1DuP+pBzKH0s4xoGMlfeTR7VE6DyyL+BMFA/zVwxPwA4yf9xPxpNDt4fXxyUrY6akT7tEZ7tTppR42XCG+NTO8IJDihoO+d8K96hYTid6aISpyxkfUy5yuzWmYR2yxVs+XRLa+5NhCpEQdxN8uzymFqepBSCrhsbQx9Judvqq7S+RsE3oqHRTqmsDEtMDIPWAIdwovkuAxBTy2wo268lrWruJVrOnRfvnJeDN0+dV9N+s9ePnvaH796Nek/d5zh8cnx8PkL9iq75E+fY2y49M+HEiwvvSbtA+YdDYeVIfNQLNP8zkI87UhosZt9des3UkovEx9P/W0AoPpLSs/I7TNh8lwe6gd9w1G+MRVKRlo/TGjHDpKHf+HHbOC+dKStiB1QuLxDoWqnZfS+TFi+JF7f6Jp63E3tonLh/FCDRn2HWZ+UpQWEOcx89JhuxHxCDadpOQ0ZmAzMHtAo4nPQksTQZjqkzGczlMzHdDC5z2o4mY9mYA5IGGLgUDKCK5qbkvmYDNRl+E8amfiGyS9j6nyJA6VmhLnNhJdfok9lfG/lk2CztUc6gL0yd2hyJjB8PTypMrmyktmkIRzVp1HI1ETUR/Budcu3vHhuxp5wvmS+zPk0OQ3mW3ZAEZPRKB0E/pkMzvprRAP21XxKO8I/Qfimus00bUpldsOWBdI4minR50p7Yt/OpCkVRF+nNygzHKzdrKkQU8++wMkHj0VyxHwnXASRpoEAIzJzu+Ge69CwMXpIp2MnTMg91zBnAjFNJ5/rxXfqPW0vuwIVIuRT7huFfOth6qGpVoyzV240Jauqyh9ngHyOTK8QC1a/dC3eRqXKTMEnSr+EGaNg/3V4bWuU3I/YNMuJh8muD3tHrUKo5h/ruxewZyHjSkFUKydx32TrOYWlPxE6eRv1iCmXAnBDS3KX7vTivE7nlZ/e1z6NXR7ZWaHzcnCXWRXT45fCTyWMdYUTAw9TrDgOPauWvlrpfEt/U2bMyzcBE2kqs5xcG7cFLRSMPu31U+8g9vlvMTtX66EtZFKd2R2lwd6NWDkRUeVlygXVyBp92S3dD2F18hRuILG+Rw4b28kwUCIAXi+AaJmoWUcRzR/bkhiiuS0sCJtPXeOpkaeTSpihUkAh8qJ+4eU0zqSb4tGAvPeZio8eMhQU6ZeHdjuX//7X/8yiKOiR6GvUU7mC/v2v/8lai/SUvOMRFHwEGYzEfM58l7ma+5Ozn0/fvUXw5MFhWIC+CtNHkcci1FYkjEgh/CcDcol+8ws0HsH+HqkSmLyI6nxFADqg5V9/fH9+icmuqANR532AIizRXQIMMTLWwIuV4GxOZcTCHgmsf9+wsfkndefc1//hMgppJMIBOZ8QmB5MAiU8xg1FN84lJFVK5of0HIVJapjvqE+nzNULAYNQaa/QZUYvNZnHMpUgCR/cXzAF1mPIyiyA3kb2Dj0ZEJ14TEUKgO7EJOtdAxdrajFVVP9ri2GV6EsZ9iQNBKEAimVi+av0XhPheeIGAxUI3+V4PODY2AdLayBNzAKYSizhTJIPl6ep145AdmP//PbszeXp/qlBdmcJpDbGhH3YDPpMWkvNwbPPjY30km2y2JXPN9uPz40dtzoca5tyI0BHWn6Lz8h1DWilpxrLgYRkxG1DwebZ+d68ZRoHg62aQfeQ6R4y9+8hU3ewYh/22B2pv0chm4zcY3r03H3B2BF1n9KXL1+67snL4yPn1dFL9+RoUkw99qBfE3dh13L3L4YGsR2TdpLAjgnBbRbVsezBoUM75ks8RnpH/UVfPQMKBulPymI/5g/CYww55S/MWyJvcv6k8GqBXadwYbyFdtMGSWr5C+ZafIFf/YLeR2dlvWFh4RWD6liqFFiWLtZ3m8SctJZ7h87gVq/75wneMNpk64OxGoTZTQzC8g1ZHrFy9UVYCQXtcPI9C1TZVvgKeLwYDp9aqOHgZ0FCEUfp6/uXD+cHcJws24Kj3jbQmQUSNtZ+tSuvLWjsHcB/Uoi2VYyirTR1/xqfFDwm2kCKDjTsJWhoFteyVM6Y+6kstGV+h5oGtgR5XvrwIXSMlu6FOJembzvAZbkBR4+IG5+FcsYDcs1C9SMXvhIXac1mu/iVHStvzcorjsO9EjYsmUInbeikDZ204ZuSNnS6y5VizJVhCgw0V6e5xABEy/SW7yCkh37SF6LDFUQBA/LrjIFZkx8p5WJaTwkB0LybScK+chlp1dSET3tKexYJwn1XYQ0snlBFrbkMqJRGdwccIRSerfx8/Obsb08G5Iz6hHpSJFo50MTNqD/NaErhmvcIG0wHPZXqQitCI2EUmAPyndKLgfoyGbCFh3CK1FfasYy+dmHp8K4Oilq8q4NaPZ6Mg0CEkQQF4pj7uX4loZJ4Ahz9qzV9XIKCclDQ+CVKPKj44fKUUG8KZn+zeaW6Dz6hvi8t2yG6Ti35f9l7F+W2jWxt9FW6mKo/sYukKMl2Eu1/73MUy56oxnb0S/LO7EQuqgU0SUQgwEEDkhiXq85DnCc8T3Jqrb6gcQd4EylhKjUWge5GX7+1el2fhFpylerDRnHrdlhJWNr/lmlvmfaWaX9WTPvzlPZVBqIqVxDumW4cM2rd7n1NP0kX48kiy2oZJdInYstQz4b9MnS8IU2TiNz0ctiEuSnIsWeTf7I5ee8HlbcL2QoloisKV01+VWahMx/B3Ij7gfS/5CS896URWyrqEjmR7j7AEPMIsU2Z9yXYZjAZdLyQ98n/iLhboIy0Vf8SNnMjaeGHrLLnzkkAJy7NpSvbOuhtnxyHxGUUgqXk8eOigUSN3WSwc7bwlvZuqzq2PZLmg0J9ac5Rp/Kon0IE+JUwtNutMl50ClqFcaswbhXGdVjIrecI+8a26iGhrhu4NNYOl4UhrZLkmp8vE+6eM+GpIZcpDVnysUSuKjZNNVbGp8nQcEtwapcYtQ6/BFdawRlRewJ2Y7U4NsWMyc6iD0OxvDb9Evav9GsorpR53fJpLZ+2U/Lj1cSVVRfFTq7MM4eJNGWGJhitjnV8fFlo7XG1MtJWRtrKSJ+ljPQJM7hN4n7ujajrQhgiqY5rJMiUVXuiao77RF6J0oCh8n7/XtYjvwkjxlFWhJlnbwkRhqQiXjWQZwWJzaUjiYLvs0gH0Fefit+puMTaVlM0K9PveT4aAUAAF4jSQvXXt9Qtt6ZzQp1F2DiHkNqumkMoYw0WGc+ucQa7H4W9hk0F+oLZQ1pJBavYTN1Q7yAvP9JKVko28q3biZF1ieZkI6tNVtR7JdIV2auZV6OhzKzuZNRyzXPkYUerp81hWlIUf5VeGsXcxpiFzVmNf7BwUT5D+XWI25VIy7Acx3GZw7NMKAjnOAkDOgKe4x4tOgu8RTRHQgPw29Rrt6MsSN3F2Qn+o/FgWuajZT5a5qNlPtbCfDxPz44mjIny9KilHSzmSsSGbM6YfMZ6i/Emou4qZCAXLBTNyKCyqUi5OdUVo7KlLMcmrP5XCrYpkJKPa8fAarCNdoKLWmQ8LSPVMlItI9UyUq0UZ23MUiNl078jX/jCNY3LARKe9GvRWFqkk17z/yNLZWQ4UeDxDAuDbZII9qTcHbF8hrqub2E6HlEKkxlwfxQS15k64X/I7EZgE5Xmq+gIwvuLZtmDxZgNvJXDRU2RXDrEIL1wRJhNIi+EIL2QrQMyJVgUI+cGjFoTZvfJZ+kMKtqS4XSh5BBKokMrR1OtAHY7Co7Ex6HPN/6dqB33HetjsbzAyCprk440HDBAdpGEYAs5vTrCpdxtovmGRzJ3wX1VW6RUPgTF+jzSUACRtfWO6srWGgXUuRNvP2orQCy/2JYAtVecBpRamMq357I75iooxs/ifZD3EF/SkK1qZcr3AuYClIqi2q85DebHor7a6p90fXIu6uOKk49x/ewxUY2LLWIOQwGdMQzjBnzlXXknbBYwgfnALtA7H/Oi/Xkx8e/JyacLuCUD4vMvP0DMAn60t2dDyzB3vG+5fmSPXBpgmpg9OnP29KTyPdvjPS6rZ7Kqmi9f9K+8jQAtfDS7sgbA9g6aQGzDxVs5+BYMZ8zC2hC76BAWAd9VXDsLhrzIdbNGU23K9jZl+26mbJdJtIp3LsAqhFzhlRSjzkbOmNB+63Y8PuQsb56TI4ZfGHdHwA5n6DRLOXfGnnLG+FsG6S0edipNqMrR+dq00c3v5oJeWeuTC9iaJGvitgJ2UgJ97wOucgbuOflsXAlLuczLAL1lPJtc0BEL55rDzLxA7rLb+YMFPsGXR+Ts9FQ/pgH9m4BVu/6ReHMM+VU6Xeg54/yIHM9mHFs/813HcpB7hUjQpUVU38oawW82+MrHKIyoSy4/XORz2qrcb8GYes7fghvqklPkMsI5OYPEizYLuAiD9A+Y2Lg20lvFdRU8VfMED+XfwKvJP3/3g1tY0Qs8dHEb6edmK+ky5+B2ma0qH8uaF2HA6DS+YYif6uVil5Fu54NvjBt/yBdvQTZAzqIAM/1iKuHzyDVaNR7ptqhNfqEuZEUNzFYTj2Xh907A7oGQXwiaGJfPvjFmXS/7zFjFY4+689Cxauyvmlu0pjAOoHJ1qkvpH4oXO5GmsuhmZ6BW8YUOb2X9LNNVdaXD134wZj0eeYqogFDuqHMwOBz0Bvu9wf7lYHCE//2BV8Bc5WbzSx5f8pJ3sYJL3sWSl7zTEZn7EbnHwHauc8tQCIaLobgM2SIQXEy7JH/mNH0zVwpTDKVHzj5fkj1Znu8dxXcpaAupudG8vPFBxaF8NtRX8+HNfKh0sSjai8rvqFJftqZbqlRub/s9df2uegWdwfHG8dpq6mwXOA6bujaz6Syc64szznDh1XmZYbRX5/bq3F6dt/fqvLAb4pv9nw8HP//44yt78COz3vw8eDXaZ4evX71+M7DfDA5+Wqcb4rZfGo1LRhNGdmVq5S1gZKUeuTkvm6fPsK27IbgXjAXFiCIRtSdXs2Fbd724bA/K9gRXbQbxECb/eG5O3v43BjMTFYhwFyYx99Ev9BhIMHtwh0Exkzbpz7QkU6VygIVQiYNEDtSQBmMW4t5K9mdHdbKNZnjj9mrJ/VRLfbDYgFqDte0zWFPosYxJFTSxY8ZTyT37bLTqnLv9JElYSKNuM5SE7c1ASjVPBA8tpkSiDmrORb3Enspox0X5ZJwnEJ4C1wBiBGlimKZG75kI/V9RfUOEhNEp78mRL2jL8/vx+RmxXAfvC2oEyTj9UuEjp2QN9CMxDPWvWEQzriuvEclmsSEtQjjqjwgOvr77Q3563+utwarnRHxuLWDTGBqcsecHhg6vgNdlgd8LQX3Tl5PVnwX+yHEZ70txXe3AHeUpRhQ8SNFbFUJI+d+CIPEOdxeJlVPkLe5GNCuMd2QiylxXBZeDdil5eD34WUX67crcpCMWMM8SsYmERF91EEL3RwH8K8X6aI6IHrbiGMAXQ04+gmJpFvghWiDKHCRcZjAdUQuWFlc+1a6+bIuzxRlerrYD5DYQUKwuPtUWVcrtJeToKJD2xxCRcKYvrng5kZ9K7poEjm01Fp/BUVzBIJ87Ou8KApdZs9seH1KluNwLGCQGKublPLgDyMK9UI4rRudL+aQotADVMk5Rx0FJwHgcAFPKQN8VgPrUB4E6JWPnDsDSmeLWdHwbNUMXjJE/Y1Ur3J/im00dXZDtwTglZu/Fw4G1j1vaeyEPQWGSSxR7aLHnvyMWzFOSzs0ojfQIisJKymlVH8Sedhb7gmrKbN52psxDmd4qvmC0Zn6EO57FVtG+aMhsGr0SVtG0aMhsGt0QVtG0aCgxIXBOVzEf0I7Z8MhxQyHVXLpt1VTNWw+ix0Kav1WpysyNvpiGLL+FDUqC6gdVTHZXIn8T8c2XEhYjuZbrVH9uJKJ8vc1RO4B8cXM7FC9+4fjw69FbgUmIZgsKubmUjVZNvZReK9PKqq4iqR6/Z3u8rz/TF6exlo0Uh7upyzgwzuLjoPCJdz9eIZlnY/RYcJWL+wjxEBj5U+0Moz7x/NCxWB12ahR5NsUAuC5HO5uYtzIa5HvfHQwOXvf2D3qDn1/06/Oiezdz4ABrsqQ38x6WNpnSX+bk0skNO59lS7O8KC6SDDsMnCiG4L2jbsuLtrxoy4vuIi8aNw8HGjSgaH659BeM1moyvBKZWpb3MVneoSQwq+J804va8r4t79vyvs153744l8+RBw6Y5Qd2iUrd4z1ZJtfHWtU3ueAPwOEKhyH1MnlWoEBXWmx2CZBiod4ShFNqC/j32Ib8wOb4SvnBIq7SE2mlCkh4Sgf4QK2Q3FE3Ysr4LB4Sej1ItRtGQrF87455Diwloa5DhU3wNRZj0NK18A9IJuQwEKRzf3/fl79gr2T6LZpZZe8/YegIwe9g5FyLctZzPA7MbOjcsaW7rNJt1e31RXQjPrPGPuseZ7vLQxqEHHSldTt8FrCR87CRGc7ZEJ7dqLMX0WitnS3cC1hlYc5ZnWlsJZGfS7JJKzkSsrEaZ1qVrHes9w9+7A/6g/5+XtdXeab1AN6KP5ZayvJer/JYr7TbotO5fV7h2V7DTOdvjlWd75V2OLMrZoH/4DB7+QOuGkrIgdAaaOmmRTPJSZ5OVwge2Fgt8BAl64HHr8x1/S659wPXzut9fxYw3mAUpyMReE0zY9BX2UZX5a3EGSMvYee9xIHgp3CvqORqef3O6x69WWfv/ChctoMrxV+5B97K/ixzyCoXfrUQvMKexx3P7fdKYXgNE56/S1YHxCvscu7+COm4bi/f+p7t4AXW99IdDekYFRdn+ijitucYrPFGb39QL5Dr/x3SMd60/+sI/8Si/3UtfLzRsW8kstriaROXoiMsdE1m1Am6kPT2L7CyNJpKV1cnX+TBjd2GQjoWMWJAHxNAyhAOvQNjSfwEDiMflvnED8IJ3l2l0Gvqow3mPQtGkUuuYRb+9yxgNppO/de1qSq58t6JleBHV14Py/6nMwWJBPXCa/gYXGLvqMuE5zw2JsHMKKjrgk3b0cmni6KqOHdxqYq9ocql90ZTgoF3AtB34TzfTxxrIhIi3zCFzNnd0yeXdLzU1tbzk+l/M4pS2P2Xnh++fLRBNKI6x9h32KW4n7u1zp6I2QqCKoxaKmkn0EZTLiNyYsu0feog2clTeD/xOZNEz+HyXfyVJedoHDAG4ROOCgkezFdTYrdFU6YTjq9r4groLUxbc1q7RRMnOi/gft2bLntAGxL8LZo36Pp6Zy33mApKvfxFTbaTWpDhiq6BcVOJCywdr0A8ha0kmlVhF5ZvWrVkNu8HNsYoWLJt0UzSNiJglnT9W7LxuCn8QF61mKVKCvA9y41sNuQTavv3RiwZY8vhK2ZDaKAmgv338hCIgB1S+Rr6+sBRyPZCbpjr34tA4YLVZDb5dEFix0glNb3okpMLoQL5dPHurdmMSCCTqIBHjz3g4GxywywaiWjmc3zj+SFR4xIZzGloNAGQAUddcenzGROHWU6XLVBEOQ/NCXtwkFlTY0k2pTBDcXSUeL7XozP2AJ5LwrlIQZmIBC81f5xcFyzQf4LG5loqyy7USOSc1LV0mlIPIm0Z+8FQlKnpUa9eVAEXj24KJdOiMccbN9pBKn5+GqVFazhdwicBGlW6MnQLC+OYlk7ImTvCfQOB7dWlBcLO8dAPRFwtFfxFrUBX7h1oTD0jsGD5y5m7iv+RrAlcHWw7allsFis6t2PtQP+RXb9aRjNpReZaQkVpoENtrAz4bvmuq2Gv0P6jsH+rjl1v9nNTvlLGsGoEgDHiU8ZBE2uaHRh68G3PygbmC7HKvdBYAdTzRiQYJJC4zZWyPLOVMIDO6YkIBwMun7VNAUQWIeO0JmwB3uJbY5NmjAFkCYpBAw35kZE9BOQvn/xQykmO946Pj481bFrUA+wRZErewTmgo6CVXMZ7UXYE0IIBupW1IbaUj5Y9BsXEVk4ELAqQBQpK3Xs6h0MoJQIioOBZ5M3BYKpLGOC5MyKfPQceXHmEWBMaUAt5iXsWMBGvBmmvzoUieAyUJ2wwPGCRFcQq+K8NBhY0wFX+3cPNXddJN7N9N0cCqn1rizv3PPF/YdDf8uxSNUFfAHGlqdfe1/gHvBP7CjOJ14V8UbwI8k/wbRnkw9pQ2GEorpj6wjHCxP7AnyYis+eDXmIgmzIA2wjS1mJPMxO9BuvuujGeqiM8FY7127cSjCse4+qNnTcw1lQAq+5jGFhrg4ZVmFfnNbZDNtItpXoMSiXJzbduI5tjg4cT7mlJq2MDIk706yI3PNmAXC+tCTZIkCExeY4EaJWsfiUdy6zcNnHZJb17nmx2K2apGW4sH8awdBHvbOQcKOCdVdgoT8gsQEJgWBy0kpJKSUmL2dstnpG61XryGRFebDvFM4V9e55k45nzvDiKorxBBaTCyBGTQyt+u2PBPUxqGbmIC7UUo6UYT5NiNBHoZxisbaIYxZ1rScYzJBlVsTSVQP9G3T8a6W1vUveQpDTllxTzkhWmXDDPJpSIgv7I3LVKtocBXW/AWIlZEUB26I9RApimOi544own5K02BhEGjbIi4jT2F8yTdG41oACUiGNFAIluKBhCBdTjFG0nukaD33NiO2AecoM9+ed/EzCRkZYukFkyFDY0ys1iQr2xIFLqC7dsLkwh0eNAOmpNGfWk6Q50EgTFVNpq+SPZCtf2MaE/dSwjDIDtWxH68kOFJcxjJv59L/TFRlCwKL+9R66MxZQVrjoizBM6KxghnpD2ghWQMcmQ2k8IyOamKZH4mEpXRW58e24Sar3ksvjId120kiJoLXgEG4AQQnpESPi5+olcs/EzCuO/fQ4/Wh34MiQTvykPv9Rv1KWdGUzYHO28MW6F+aFwCvu2Cj3RMyalYuZ3npaqDVRBStlDZVDqHFIqahXS0nf4upSY/o8foV+caAkwNyB//nL66QS8P0bOOKYNzOvfO7fOjNkO7fvBeA9+7cH6Q9wxRq6EKRf8DSgfTgKkrKEZliYOKLgGIiR8ljB/jxgNUKBTfCgsVcUQqyjR46J8Lb1Fdl0LADFkD+HezKVOCmbymmM2wXX/W61iv0n8lD45HAzI6SdCjokOwHBVakRaMorneeto9RtaZvWgAzWXoqY48o1vIBIpimBTYkYd2IxmLqRcXzdsktOQUM4jEEohy299Pv8AzD1cdpg0W6LE9WVUL/ShunE8eyi60w8fQvLDHXUdecjF4xfKhbTF5Vq4XJdtnkZu6EDmxz3ofg8Z7wbmQLAXchjNeN3gditmFRfu5ctLZ3b08iX5HWSMcL7HuEG6hOK+Uo7vYrMyWxa57vXQx+97KPOf/3dqu3zfNOhXLgVAwbMMjVJolQMOIz5my3pwZEh1gZt8gpndA2YxR+ZjnLEAtwSGJvEgV7GAanLDPDYCJxR/ZFy+pQe9dswUDYJkwMFPX6PLD/TgGo16rsuJHpRGLMDcJBC8FSplwmriAn6pe7vJws3mrjdiFw25RUtJdUkXnyepfuYCQkl3K+kz7qum1BkqFdLmC8CyUukgFIBVFPsl4Y7se4JSS78ywA8ahT4QGCCkc0JtG1BmCgCLJYXn4GfOIKaGM0KZFPgze9+HREhJJfH3jOTRc5GQ+7GpVRXupKdy61CnsIOPjDnri2/bolATFML9s2RoXBATj+idH4hQK+AKRvncsyaB7/kRJ3Cg0eP4zGUg5Jcez+RPxLa9MHDGYxbUYZJFyFzuRwFklwWWmUc38QMFmWKIPNH8C4Qq+cmA3Tnsfl1fFK2/0LMFug4eMop66lp4L5toKsoStRD35bqm4voCGnjMLgX/2M4W1kglvDBJgO1wC1KvARc8w7yAGLUNNwb6rLPk+kNf0D+Zx2wpaBtCBhhGgznBLARwiYHsl+BYopyRCUZ++ktku7xzKLk+++3ikpiTdN0nx7YIZEVd3f6UAjtrdlX2DGoSl4aox9oBCvNBLoAxEmMttsSXGamMWI7nycu2YieToGCE8U5TX2TYI3MNXj3h7JHkXM/FFqsDY8eIIDF+JBBs5EeeRgTzhYCqY4U+6jHqs29E5lPl+0ZtG5XiRmyG+4mDN2+JV2W1hRfF43sFP7IqU1IsXPCGCs2YoYUmIBW49kNy52vHRfHVSvb7/BljYstZe3J/12T6JKfa+LIv6+XzfZfipWnhcyHKpMRTnhM6mLOYeln2rZ40oE/ALEgZ1DicvHxp+wzNZ16+zBETqFaSkoJLxaUFkTATEgZE1i2sgmerZOpIHZRYVoMAcnZSOAv1rhOsYsySP1WBRHa5Oa43Od+UYELuxkpoLOzplkgoWtR8NNRUQFgJm5EQTjS7JY9Z2BMVTZz8BzNl8+SzLJDcs1AIUMWKggCixhoup9iiEfemK2OyKSDyoukNQwmJvgJ7KCgl/478EDJLTp2dQJi8idJntr92eMGJEMtXAi6lnVTAspbObieyoH4c6lywEJwnuMSZbs4b4y77TK61uJ36sLMqHUaLEInL2SsFI1UoNxmXbiGhqpn494nVyepqVAlV38CgjaGJ+vYiGpT0CNeiQtEdzHHq6B2UirYK+7cK29T6sS/qRcZYPL+nnqFF03vmNrDB7J5dGVGkLD9kykbEpWHIvCF13aGFvH6jceZU/9btoGgJlx/2WrMGk1W/wekMWeBRVzWVduIwTjzet1R5HfmiKmaODMw5LAwtCJex0xMzfCjc1kbUdeFGRkI/a+zx7VtSnxSyIKBoxCMsY6IgxmqYEvA0GPozIcDHXQemP5AN6M6xxXW4/t5LVv3W7Xh8GIZuo0ZkFUGpfc+mwXwIovfAsRtukbz60Kyfm45DtWXO9vecXPymfDqrV5Q9zJwgx/DpUqQkJ6JD+IUbBqxp5KG1UOjLZODCD8YB8kPE1ZfQEVypRfIEPSCi7sXSHIiH/gyfmZFpjf4K9tc8wG8Gr34aDLqdKX1wpnCKD17t/3yATxxPPPnpzSv4/dCjke2EiVSuU8dT65rdsJiAPfSJCxZPP1xefhDmcB6GPr4DWy4RjtdgxlNxdkt7vp/st+yl7vWboi4L4pvXYTXjscChq7JVCD0Wur/CGPwovEHhtTiK4C41ArUlOR0RCEsF9mqx6VaPcu6MQVQubLeUJBqaK7fSug3Q25j2vbRKtJNOrJs/2oCNAsYn1Vux1vYKWM+aMACcCTMOhMgRw0CIo+FpQjm5YWDEJ0Q55Us5GFSsZcFiBiwM5isbXBjM8fw5TFXJOYdAHSNPch8QsL9sYAevFhxX8SbFSwnI7QKZYycOI21DwzwMaOjDzgXLWfQbcwIeEpfeMDd2/lYAAYa2LmTUCVVbiQ+Ub0/8YiIqdP5wmkCE7IWxu0SI7tJ5PnxTOs+H+fO8LIVEcj3FOHMNqFFcC+hiLNts3EjPrJwx3MyyRRmuKEPj80mtoJSahpvjTvFGyfF8SUXq+7bii/dF8qrV3rwXvnmrbVXv8l0arSnvcm3E4Mi9Xhs++4UXbKPMll6xN6O+Na/Q8WTHUbFqK27bG397429v/O2Nv73xtzf+9sbf3vjbG397429v/O2N/+nf+J+6fU/t27yIp1mgS+fM6pSnNeHMMtKYwK88N8c4+4SRljFzvU+U2pj9DWfWUjlDzEST67C9gf6JGR7KX02Crpd2cx3WN9DBzRneXLx7uzoTPtxY6uDswiGXJ3SpDBF4gNU5zs0GATunKBOEiuRPb/woVNuMhzSMhFGdJqkbjXmx4JFODHV9Z7n5Ic7v2NM/vYtK3pMHeQdk79UHuVLoDgcYIEsdZnEIk/HTbEef0Qv1OhXESkgk/ACcHPHPraDGqxGrl0tv5McFb4wX9zrSL+NEJ2qCX714DDcvFAM0ay2uFjcVcTb0OLMOmzUVV4OjKxY+K88UoC38iy/eve0SiAILWaxBYBH0bMZh0hHcRawacaW0GNTxGMiN4b6sYpiX3yAtEAV19E0hfiC3nS0zS9XSYmT39RaBd0nnnj6AP3f2q+pytfc3v+2UmCkDkCurZPj7b37Ls6EE5O764+KfWUDHAiBZwavwhTP2QAT0Tzbn5Aeo8EK4iMkmIs64zopXnrJrK1i29PDXfe7/5reL5hbPdPHpn/5C9m2LT3M/Tvmdf6TxCOYeaZyzPRqFkz17SgOQhEBcoGI/hDELh1hyKEsOc5g2dJ/5eHz+lpxjoSLOLRkrRHtFYU3RfPIyJsLNCYKUSBF+zsIo8EQz55+PgcyPnIcuYcgaqjpdQmcgQIQHIgCLcAY1PFJzHeorYn7jHPZgDrVWtOblzRwoV3RWTMni/ugV+r5a+n1jSIto9wuqb1C3n9Tq1+zrCexrsWO1u2uTDKNfEpCa91G9J8zPvnUd5oXvoLnOqpDuHWpGjqNwIgBsebiJO9xPIsXCF0B1tFkSUBJI8laVSeBJkZWVAIAS/EiAxnFIIKAUpCfC+8C1RAsRi5LfOrPhvfM3DexrkSjiBlM8gPoB4m5goE+s4XjjLn54Qj3bBb0bpq/wOHQ77hDgklQTYVYk9E0/+XSxUshZvy2XuXHV4hgHB9lk1iApT8lqKWf6FglbJNxxJCy+VBkcGJ+N9hwP8q0UZyGQ74d8NkoGzBbPycXZ+6J0cLIIN5MeQ/HLf10qYBKhMQQvRUHVDtKUMGCM8DCIrDAK2JUnrV74bIRO5717P7hlARFhonW0X9ni6UkGPDEQGwbXcOxraUWksQ3rn+suBLADOEYexl5MMI8MJg46E72L95Q2I3AC8u+Iungrk37y8xmklemRT4yLiIOYmoXH7bsgBeK+C5yXNO2JW8bPsaCnn4hG/ZC6xPX922hGLD+SBYXIm9kEj4UZP1t0EOHrIVwR6lenpDFqxYnsajrXnr2PU2Lj5mnR+BHQ+GI2uoSLZIvAWQQWOFgcJVnCaQn0Bn4E0rtCxBUfk6Viy3UIA5L/KnMVFhNwLooRXuQpAEVNtBD6SYRa03wEQwslm9yc1AtHvGDUj/xpWLn1vuii+H9thFQg/B4cZrsKGxWGJ/M4CBSHbAggB5aTLS3PguxYqI1x+oTMuL/iM5TZQqU2RPkeQ0lvoXpibkgtYNh00pnTpxZSPDTV6WP/+3I2+jKBwZarMBNnt28cygVvswUwIV2IaiCFdBSqCRay9G6gw4ZupUMx2fLsy8mOMcBgOBpmjH0GyCWmbluxa40wJROtPiWgUrljCxKOFyBVwGYutWpB1TGE2q2LVKKwTJAqLoB616nIjTmARX6bOmFoFg7gYuXJC55SFqCbAsjx5fXv7Pjy7a8t2i2EdmXL2oJdC3ZbCXYY9rvG/W5PWul0CsPjFuCirJfExaS9qTQ7S6x91uxUlioEvGOX+yRgUx8UojTOSfDxX9oIegaBaP2Io7RK7Ank+pLNhT4Bmdx23whzJ+05oMx6Ute0uJPCHWOadRFn7PmB4YRYA4NKDdUlomARPxiznjxCwitLynFU8hsNNkQIt/3RKLVzDO1kLUBTLt75ji5N4KwnXKJaSGsh7QkwTtvN1awDUWQ9ntp6Qp0nTh/k5TQNnQr9awpwI4MX+VfDZAd6ibg3+cFn0zlUPMZkZhRtILJ1Uq2u/hCPbkTyAvUp1Gfm+BwpatQXKWJ5BADAbGE5ou0r+YTOIO3UCHz0RU5hMx0ws4lMfIpr62BuBAL+ra7Ioyb2JZS7OPkn75MTH0sEoN8EyoOZtrSutdNsChKYM8QJyOFnauZPL9kna4JMM85ymUVsqxRolQLYZ8EUrVgf4Lm+dVvBfX3GQinAS6ZtS8mpRYWP/9JB3Q22Cl6JBHaJBrdISLYuvkgG78JvDW/gY7UF/3krEHOtLS/XXka3BIUEoBRnyyti57wat0DpWVl+CZSFiu+AtrArwwOFqUy0393Hf+Gb2MyIt6BUxjPlLEd7vWwhaZtusAJX6oivZMmm4vg84FoGtHYds1rQaMXsT1vMXh9SgsgVJ6EOouh/oVLPChjYaZkPk45I+F7vPvk+5c4ILYHUisuk2xR2CPxhwcoHDkXJ9hQujNAI9oeTH3hkTcCAgXpyj4tImxD7DsRghrm+FfHQnybj3r0gMzfi8bcoCjPQtiKkt0yIfdTp+cF1bjHN3D0NMLeck/6EzTCMo7BAlV/ok/eihm5cYhhhD9QKUbbEyB0LAJnsvCa2iK9bo0WG2ERD2ByL2F/k7LE1ITX2sAif84gIAvLB4PWrI3KSXV0liFQ7oE+O1R6TOyZvT2jHEL1xbtjIDxjsSZmXFaOYOh44gkQuQ5n1q4OD4v4Nfjwip94ddR2bnHqzKMzuXPwoTCXYEpnbN3fXrof9NFe4mHgk6whwWR8JwQkWG3hX+NC+mL8S0iHHU5d07H3FgxEDyLf6CtYkOZHhBQvJiYxxV0pORBn0gjIRgfsxBXE8y5/CH8rvg9CAEc8nru+NhU8WbH4h/SvLD5oa9wrRON2yqTzZBv44ZyUeA3RfFYPaPoDaCQIsRkV9dqgkD+CTQSU5nqZKXrjhUNhY7pzYChu89M1O0ckaut0kZIFDUyFegf9OKVilnZeELYvmKhPHi7qgBpoTgc52i0rZs5+e7xaSFoKkbu67tSk58fDtlIqzEquUkrPakSCJJtLvqRBQpGdNKabIMopzB7Ebcj5g7+8HMriPsuvNxxq+zqvr04WnDbswLHphztlE7YW5vTBvkDXdLcVNNdwr17G6F2YL8BgyN3Tquc9nWU5soUddN5/p1K/rsZ1S2KmM5IzaCf54mxU22VGvCdP02pWj26LqmhQqb8QGruUXNwEgfb0918g5luCCJPsV0JANC56PBshLWhPqjRWriQnrJBWsVI60upFGrF4KdBZn+rYJIlsGsGUAnxx+12cFpQliU0uePFPoSjPoEtPnHI+yItNnEvtjkB6cGRE3gFR73EEgtJDREqFla6iYbz3d2hy1Nkc7Y3OkrKqLwY8zDwxo9rQDWHHMdPFVWaEXVxBpErLPs9kSZBmSKJON2c8J8EOqQR38XFd6hDQJi96CC4a9JhSRHxrGH1q1g5gAEjWgNV+HL7LbZWkEEIdfDmA3Lq2qs4lTU3jkMYlChRtFzhmWhoOZN3nWgzS7ozPnWBQFqw+P3WfLw54KmDzbXL/H3AgirniyOGZKmVBITavuwTbmfsa0rC67Yy5JbhpIhwxXE0yJrDBkzsJunL535NIx3GBoFPogeIO4qHO0P7wH31Y0N/RCJ3QZOK1CSZnKF645LhuFU5+HECbdtuCioewfr1+aCXqv8QuWxWYhpnRy50KpLPajDPek20iOQXa7T37X32CeLTIoUxmVHVJFETFL33Ny8s/Tj4TLVDMCrsI5qpyurVEPMmhbrP+/oc5/XcsQyQSAcYv4wPUbNmZgcgkrx5yzsClwb8Ilqnvymx+P4s2U3GzyKq+OiqCxYu8icu4cuO+IFWAzeK82BcxydHtf4z3j2DWMAXPog7QELKcP0gitDn04UaEeTOg3zlBZzAfAfXWXcTjhISSqEGnslOZEN9QVkMvjTa7JRyHkmbO1QtzLHuAtttwpXso1wVsid1Z9E57Dw6OcLq7Nomf9qLUjVoLNUGtBU0E7DRImKiSO+fc8Rc0axIjJQTvQ6JZDHag36+DcPxhmyCm0KMy00MJSlVZ5G1mu54RQT/DSXCcGSg5MSB1vOVIo878aYGGm/0J+xgnnPdcfC10Au8eEgCzAzL8SR1r4eEQt8EouksX7o0W1DaLajmhAm+FatfKz8rao4nOugIHKBGYBap7dRGURoswMqexBpnIyw+61sLggV1W6Do8dyu45AdGOsld1w8w1U0uMnIcaOPLeeWiII6c2m878UHihBayHO1ldKrNXSPKDJfUZShEmX3TTlaWdvZROof2A7+lm7ic+Z+Ip6CdQN2G5jAbMftEn52yEWeBRJUDJq8HPxBkBojFn7JGP/+qSaeSGzsxlELfF+IXJR9EAMH4EigD1WVSoEBrKIJ0uu6MeZkYnsDic/H//z/9LQuyaMvqbUi+iLvbNi2YtepahZ+Xu2xgfh3iKCbg1mtYx7jv46YiYM61UAZQIg7rPn09PhAlemWrh1eGRUKuBzsCeOl5Pmi2B0MainlDGkWkUCm/J5YEdGvg5RzPjeyPXsULc1nIjw2rIzazjc/cJfoqD+eBP5If4nL3owqS8IT+Yx008/NF4iKfuBR47Kg5eD08dKs13j+7srLqkivKMnIelOeA9caxWyAj3ZIv1+GFduJgdthnHqPM1uGFCIbCCojMu6E0gVjOhY+hzCLIHdWjgw6xPPnMmtIGhT2wWQopeSQm7RBgZQQxoeYRiStSTaVcteSS5svS1meVgn+5VblJfpCWFkYycB8I8e+Y7nrDjNXTsyvLEv+ddwqg1EdWoiNBvTZh1K6Zj7N+xANXgfjCmnvM3LhZ1e2pWMWH3zHcday7lypj+WD2yA2cUCrsDmAcAeQliAZtRJ2hp4mI3CrGTnxBJbO8mO08hJLouRSQCNgPOBnYubE+XOl64MnoRN94zGq8mHbqwSOxdSj+ET7qdrlNIQ9A7Y0LdUc+fgbWUM2Xk3vFs/x7Ct0UzgHTO7phHbDov8Q564nBp5FgIaRAOaZhOsVD8KZmRm4eBsPMVWkTQp4LaAWY88QHm2atvvl6G9aqdt0FRtjopw/ikbCX0V3g07e8fEUd6NBlnCyu+HpRUfPX6yJh9m4YURhB5GkBbsrMpshNvxgrJmInqzaiQ1Ax2KryWciiNrFmhvTyTmsdcZq6Unpj3EGSj7/3IBVc/FTCpiLJ00TAXhGWONdFNgL2rvnKY/Dr15sb9Au802oA4YTWGxiUOBqJj1O6hXZgdzHtB5KGowPMTH1O9hLuMb0v3RrgHySsMdH4UskAUROsU02DZJ3gZMXjefKthCc+8yAY49GHKklaZTBll4kTIheRoCtzjlj+DWyBIIsQ0wZL0gKxtR6TnXTT2LT0FG6NtcqGz1Kw1+N1lMlFGGxS85xOF2Dmh5KZhFMLbBXpMJKqm7xHoevcuWaIY510ZJdpskvwwYjSMAibCXYlc19R1fXEe+AuJ/WMH7gciWP07EOaY/hbikzfoRDILfDuyQiKbjX04wCkDtg/m2A59dIKVnzQ+KPJrkx9ufB+EwF3BlHZJAOESugR2GgqtBCv8QtArIUES5sc3bELBGzfoX3kN0TOjeJJ4CHNmOrEtiLLGrC/qn5ZevLR7XQWoSWcX/AiPLAsP2FdjT+F+SnwBqfTUeQDtQLxIcB+BvYaLhS2jfF5giwoNK34FjEduKEBJN2Dcaab0YaiuvLK5w29daT1vD9Eq4qhzMDjY7w1+7u3/eHkwODo8PDp80x/g/3DdwGZVl+10O8x2iiu/Ohrsx5XlPoUeyT9B0Y2bYiwChcFAHbtztN/tIGQm38gddUbHTAQAALYfipvFEIHzRg/bPB64hLDysf98NDhYeOw/H+3XGTsNxr4c9eFPatjwsA+juB+GDguYPbQoRgWOZ+E4GPvkEl+St9SaMD0ZxZUL5wbO+tCLpjcY6U5O0Z/7g+4b+G/QPXwzGHypmq5XPy6xVV79ePTqsMZ0QQLEoetMHenli/N2oOYt8bbP4QgCtzBjgePbQ84sYxvVKKtmtE7RL934nOPmQkahOVwlfqSYmoO8y/W5YB5BEG9hqsibOQKV5TpAMCRjDk+iGQ8DRqcA9K4tOTS7Tz75cZJKiAUAcF4kEPiFCu4cvgj3A3UbF3THwPGA+Dd/gUoEtlgNwIynSkJnAusgEoLNOkcHg8FrDXugxqKOK2jciIVJUsljUYHRE1yofNj0Itc1FnFEXQ4QUXvlgNHT9jrQMdjAihvdz05lyq1Ya2BXxjHX7lwOq3zq8Wg0cizcQ7E3M3+E3uXseSSeWm4Emy3ybj3/3kMXqJVut1f1t1uiD4+10V5nZ+vXy8szIlhoIbQD2tBwo1XM0n79Wcp25HGm6nUevJ3C5QeymHMW3LFAmS2sbqIGTdArpy+PNVc5EPFZkZMEFwuddSxmylbhfIK01iZ+FK5yMg/rTyZ8349C4ltWFASPs+dWJDnI3kRLw8XEEQ7zb+B4ge6n7r7lFov59+47J/C98ns3VnpnlISrVjYkigjPYzaYHxFFJxG3E6XlPTq+Q1ZqasRajyIIdQBXd2Zn+7AyyndLp47nD822M9Krf/2rqBU9GtWO4POGEh1Wu8eMFSjdY//NAuAOQJKVyD1tPE9twyZCo3rxf9Q+Tuya6oggSaFF3ozHRdSUK5kGzFiBe1Rmp7+zneROP6NB6GBwDRlxqnrXH0ub2pmoKiui/VHudt2EXDl/N+N3a0uSE+dPDKo9gMsdwO05aXDrLzZyz5wTEUIkL8JO9flQ8XVKicEOHgmldWuPxNM4EipeSUEE5cyZEN6QKQdazoI6nNI5m7nUko4YsJ3M4pqDMt3wd/qoRDgv7Vl5Mmel1FvTaGPvq/GrKqJP5oSdqFgcmbg96X1UksovXRQksbFveiwcXeBSIoXpmU+0m3onN7Xcl0vfP7p1ayTPRufbl8bHaU8K00Wgd9A3FVpXSWW6rt6LqyZO2Kl+LDRYNnkrtjIGdS45ch9pcMuJRaVprqhDIegVdUUQiPRJNNXK+iuyAVOz+z0nPrpemHPRhVycboSGGlLn7vheV9tAjkboct0nv0HVe0e5hdz70E3Mynx99tvFZTYEdXpOr49kRvqHUGtZoHtxuXi8U3rLOHmrbUBIwPR0OqHQJs/9CFQxzhgMyJQFgGoYVD2YRlp6eNIpeJkw1+b9K+/KMw8a2n7BrRMm8k95sMhH6tExioy+/DAJwxk/2tuzIeokbAdumqdY/nTvTtTqTXWtvRd9culLbBM6Kzk2GYi7i5YLBXNXvltnUTBWk4rD0ZsNVvFmTj6ffyA/XI8cl/HrF8T2mVhMWDOc8sQdAk0fOAMPbDV9HBo5PVPB8aX1RDDvkuOLT2g3EU6AzSPc8gMmZn+EOcGFNR6aIl3v7x++uRYWdNcAc9ddcj3xeYh/QGAT54HB31BWDIndsWAegjr3Wu5ccFFNMDow3O+++46Ylj74fVRhcnh9DrtE/NT7Quh/YYWdkE05bB7MPADGOWDYjolf5N6x2Qye+p7YYjOXen1ywRj58wx6KY7WEaH5PaizXbCFvYl/3wt9sZo98eg7s9Ee9eyeaPTFslYol8p8BkyZFzU9wT72xFIVmLynsLiqSyaMnZ50ySjwpyR7BNfQ5aUtE00jGER4Iki5aQejwBhPRThhXBKD3iUdCwulhPWL4gUkDvf2Dw5fdbqdiT9lYATS+QLMxjt9RpLfOnbdFNUwm06fL6XH73Z+9XmITuH5XU/SEc7IRJc3msdjDV2/v783Y+HCBpiCFiLxEMdxJgEg/7MRRL2VXwQ0U3CRGJNuIfPdvRvXH+/lfn2P3tGQBnxPdOPz+YdUFy5UpDZ8ZXwP8RQ+pg54+qMWB7fROWaq4FC1qOBffM/xbPbQ/4vHvRC7BOeb3LI5mTBq40k3O4cF5ZpgeQVasjRxRDhM3UzeAL52jLaPMVJx7wP1xpFQNv096b391Ol23r7vnTDQd/UuhSWNzfht6M/Eq9Ozt4IoQK8ugN2LArdzVDw5NBzOHAvMXfp/zYS9Tmk3mNf7fJHXjal/4yATm+rFybvqXtj+ONmLLylbFurNfxsVsqt5sPLeZQ9IGH6ZX8IBLmJcK+rG53DBBvSBalLfQJMm1S4wbNR7WIbFqv3uhJPPgXvs2b/KPYArUS8Qc8wW6jDbBu+H0WKNMsIgCJlZLE24P2WKaUZuoEuupUYUY3dfo1b0WgTRFqrZa9ScIS85Ba9nodsHLknxOoP9N9eCSNejG/WsHb8KG63BwSHbH7wevWIWG/1E7Z8terhPfzr88cAeWIevD2HfJw20FqGPOQFZe3CfMi/IhSsRsL9EbKbESujpYw/o7QI+HvOGFqYqy5PJ2idBMU3cgKuTRFdceATnT35AY5FXg8GLXJtTpXzfH/x8YCrfDSM02EUqo9RV5rtXHdwz4J/ij8iVwNurTpdcIWkXfyGpvOoA13ulSdhVp6nO/lu3E/O5wnw+npD4DXi+ILGQYz/4uWLs+4cJo6DPIhld6BMcLBhQp5vukzOXQUz6e+oI/xTL97gj6HfghyHYEwpWWi0hn7HmVgpJnJbGncL6rYO2+8rHwxhX/c2vO/LN7NRi9ePTm+4lDAwlMLHHgdFrx16cAzfY1z+hoS8mJGQtgWw4cfJyfHx2ijEVvudE1oDNKY074LAaRsaMAsRpDNN70fy6+mxXLYMxo92Kt3LqvqzYpGQjwrSM3EyIkkpEZbHoo5eUwjaLmjxFkZGIZOUKFI6FDTKrhW79e8k/aplSfwH5symCaCArw1pJQwG8UTeTkCmhdEpGtkOiMVOAUyAVwyLGOoIMXqzb9cfTi4vr7RV53TI20/2Wcw19ndA7VizSW14qlpE34rBhg7VSsVYq1krFWqlYKxVrpWKtVKyVirVSsVYq1krFWqlYKxVrpWKtVCxHKiY4d6SgNUO2fIdrMMQ1OEKr+C8rCqJSKUQTN8Vl5Ge2FCjlStDw8lUgQ1tIdBb4rntDrVtk1h/JQq62x8K56qwptIOHBJ5WG5BC0XzzUage+hhrBWPe+BEnUqa0gA0pTCqwHnmdau1Id9KOVJ+T3DM2ctxQXpKKDKFlEZXJVNXIsYOOX+VLmmGmMCpcwOJQc7LSZmKrjZyA3VO3MNRo/JnaUUBpEFAoiMx+7e/LUQ/jMj1ZRnDFQAZnLnJNyHI3yT0q2155eLVU59WG0Fx9Nv9MHltf0EnFEqy8s4mLh+VPp77XS3lc22wWMGBZ4lVeAYS8l6ehCDjeyx6SC+EOz03o2EwcNmPgDTFITW8/PvOFCHQTube92Jw91+tbgQzchHMhBp2+iwDmPXjzM643FYZYFtqq/5GyePFKXiCBDeQk4uI6dweATPyZiHNPYhTaDkya0YizDC4tdGRz8Ua2nxC0P8xANSPirxZ8NuV2TCwIoul4nHncwYzSIiYcBltwhB5EJh+TTRvMv46krHn/zmwyS3TJ/Nyq+2RUK+/UDaRPQHmS0TOY/po9upwo4AOnH/IDJXziB6HhARRSiKIHAcBpYE1AMt4nHyOOGWCoR9gDhQwS4E9e3tP3px96+4NBaiOh1rhWTzGAWqzXmtGx46FrgTw8xtd1TDCbjSheTSHSi+M5U7jT7Cd6wIJhk1580h1QJ3vGAugMK/3+AcR/og+yAxhPRXXndTm1L1u4yHP+HSUDWI1k2g3oW/l6HP54wN78+PPrV4OD12xwQ99QSt/Yr396c/MzG9y82e9gjz8wbxxORLSyqePFP5tEJdwU+W9I93P71lJ9rqNhZN/E8TCeEjugw2rkXp0VIyD8n3NZAenrX8QMKA9/87axBZeMFcZwXsHNQx2CGgqRxGxvG6oU9K7FlSd7m6gIjKDwQ6YYz8MPmTi6CD9UMvFtlVZsF5D0IKSumm0zLEOTHN5bCi4FvWvB5cmCC4oqysJJyDb2voo/qoJIpGSnVOJRnvCUEv2uIHiEl4ahYhTSvVstDlVKLTcNgzUlojS+dW9WJCoMHWqIQzM9bEHmyYJMTVEo5JzIBQxINVGIFkoUKuRaIdpN+yNdvoWMOhk4N4YXDYAit18tSjw/+QmG1613+8mFD8nVFiKIuv+0/MZj5ODKk9M0uEltI3IVda0FryfL4pRfoUQ7e5D93PbvvfJY4D1VTOiGk49U2p+Unhhtcj7IQkQVymeUcso+Da3xYyv7amlsaw1RYb7R4lAoSBNDVtkmh0t/0GwpoTCcLdmwM8vr+CxwfISe1UyTbs78RhQ46tPLfcVoKDk1Q0wKt5qPpFtbRol8iTm6URtsbHJ1nLVCWZ95zG/KWYinXuS/C31yvX+Nrqk+oWQauaEzc9HP4zWYNU/AC/z6Nbie7g/w/19L19ODwXW5qnqQVFUPik6TSqtV3/wBxg0pLXhIpzPo6v2ECXsHADlyT7kKGp2nus7JaW3qsw8G+696g/3eYP9y8ProYHA0GPTBo/D1H0VWG5UbI228EdtqxMYQORYbmIVP8akCvks18cyzZ75KGGxu38b9Q8bH8GTOdrVJv/b7B/3D/qtGCQhzaNf6GD+gXorwxslLGij/y3r7mLzgyuyF1di26vKKXhSrT8qqucGYi1tY55/k6aTmn+awenlmADRnXxXaBFDisfucCk9Ln1fgt5QI5F5fz5eq9i01tzVbMetgTGM0OmzM2khbxW7MMy3OHaE7b/15wMJpdyR82E1PbX1v0+I9vGkgr77H1+ns88bxpwLXysai3vV97yv8OcS/60TVjzFdq0UroF4ryWpAfZ66tAngJ8ayWtjXM7Y9As3aCtQVAVQ5hSr2bW3qy9pgzr99q6OebTHviWOerdJ7LO70mrNHtNuryJhTpPNN4p/Q/FZgotAH1gDEQo1wi4rL6Yh3gWer7OnzBq8nf/EuUxYnAUarjCtwR2vzakBPniq5RZ0nIQN49KtzyT7cPhiu09nnjcRPBXBrab6FRrrUbliUFAruOPSC+TQ/AoOc3Xyd98uXyL0qFQiZUE5uGAMuVlkFYIylgIVR4HHyan9A/oFu1DIKU8RFEqY/z6F9FnKI71MnKGkgyveYN3Y8tvdCBartv3wJUVXVpd0wODIH0jxA6WNdlJP9Xr8VDm6PHLcG7W9fIxBDbo+fonFO4mw8bRsddf6XDMqQQCEZm6EQg6SH724iUBxCInEcVhVJ4lEBbMuiKEydZKeo1aQ/YNYgaqwiTsINEPUtM5xaJkpCYvNuZ7AEo4tLxUwYpGMmNAmakuzx72gZA+eMOEb0QhpmuwwxXK0oCJgXunMiPlMrjGGTAA7bwUPUiObQsg6PLWXaJp5CW3kA7layE1LgpPTxPX9UxlzIG7QqnUW73WE1lFQM2jbHs72Xn01IpoROb3WUJDdsbTPZUvFm205Qrt/tFqKfwe0O4weXBNpJoLGOt1OIwDrUym6irux+MirQM8RZeduqfaAtZbInHdIa+68lYVg7HcqGm5rK7QIOl3e1xd6njb2VAYryuOBqzndXcbcinNIzROAt5HR3AVXLu9qi6tNG1RqRmUzl6t5X+Kc6PFOempUm0bgoWJOxOruDxvnBpEx4KcFgOaWrjvFgrsH2WOM0CC1lioc3A50ygZbGpdra3qLutvD5tOGzmaZXhZ4qQkEVi2gnIbAkQlaLg4vHy3p0EKwTPKuFvlZdlbGNXlRbVYaQOaL4nQXMIn1Vy0NujzShphV3zryU53lcXGH2ODRheY1ZSyaeJ4estWX1hbY1CMDOg34L8tsA8ptW2nXXSla6i2sB84/V9l04KvrZEpOnTUxqCaojOtSOQLlSmYizoEfHzAt7aKfseGPTFL/wddYq/zNnATmGouQXWbQiLGZhjaeWXPGxrb1XFyazIjzm84ybCIdkiIdkNZEHoT2C7Ykx8qbxBy/oiAZOowyfTYzVN2SjXgwPayTF4o+IItotFIKwutu77oVbjPS7KAZc0FM3or1KEl0ekrCY9OrwhEVF8oMUFq1LRajComoGFX4OJjOJIAG1+xrRZOCCFcUunGJa9q9qa8meztXGopbFOBd50bBot1mAQqyzfIjE1LVL9iQ5H83jFBbux83DfoOAhZW9blH/ES5iawT3WgEM1f1r76v8q8pcqJgoaMuhWkRB22LUJgp5ZjtFlYsJQjzM1dIEQwAkF2dLddWVE78QjK09hmHB/KbRvCmlWAltTMNzjjCwgHwuKltcFX381u2wIPCD+mGMpoxzOmYY/0j/vUhlHiGPkLdBRwCxEKo/nEiJyvHZKbEAqSFiv6w5itzyC51CaLgP/wk/vsB40zvSZBBUn/SsGGPsql39pY6FWUttnxm1XUHozMI9UzOAZjFpFrZsteiysBKqTZQLDclayrygFdlO3S5qdrkFu2ciUCoLtVkMT9qUoBZCabVibZDK0+O3+LRDQqx1SLBWp9zfUWkYbqjlRGKVR3EriVb9Xrd062kx6bVMEu7paM+/Y0Hg2CV2Cfd01NOlhC1C4lHW/uD34/fEfL0jRnBnAbtz/Ii7czJCZt8Wl5Xz094N5cxOjms7dDKL2TaAsn+2FdHsoCdxJ5ITXCug3etBWUC79G3k1X4OtuN2BLlLzk7srxcQDeuktdprJU9kESRiTOcLFgLbGLPxyaf1WXgZoLlO/GZhkLBGE657OuqbiLSgnjgJhVo3bD7O1web87+TgChzhwIrkQuHaDTz+HC4Me5+RQHx8/jPFqOaYtTThaNams0EG7f3Vf9ZpeBMoplWahaimRb57zyaibHaSTFJLq4Vg5k5zatFtHhNHl1622JRi0U1gwok0UToYQqhREjTdx5HzGtiUifUgkkLJu3lqyHClOlUkvAi9SiF+CIFnzsPMGKcLaOyEw73SU1JwO7hDA8bOnOmqkFDymusXn0svZKUbbiAMm+bEjinutfeX1uecSVqiBm1bpWBXSF7qQrFSghdLVcHYbzNt+UxC5kSLEDhly8/+SE7evmSHMOGxJim7hzcxBDzZxKkyR0LONg3SfH1lHp0DFJ0ODB1iAGPZjM/COPpkC1Ii4F7dtMzTkQcgwBmLfJsFvCQejbYD8CE1Ku896LVWaxKZ6H3zwrUFXGf/MDGirU7NHKYawNLYqMnox+EknFhtu5iuasifllbkYqfXxK+q07AGidv0pWW6hu0a/SN4i98mOghpoBq5FmJHqw+uaaue90loA6G0y0dQeWmn8KeJlPINyVyTJFkVW8ObqwADhj1eFTYBNC+0C9OVKV3SYe6rjlcD8YBzxKjlQtWf8/Sqe6egXzlM//54t15XbO+DPCuzyhCfmEht9DcHj69GA0JCrhN1nu1M7euiFMx2IAKvV9tNmXvq9qAUsZezbPEEjH5qEAgFr+taX9sHuXnzLjEK7Ja3sVod2tNqY09sEHMrWs1nde7Fm+fNd6WR+NMAKe2mS7CTm3lWAaf2jI6gZc6nIn4iOTcROZTiBAI8r8wTkEqwmBSz59S1CKGkrVtIfgpQ/DmQr4NG3lLmnXQjFbv2/qG00adb98aG0MvS3bK5+Sx/DVjn956yyDgQG3Sx/T4XKmHZ+kqt+R71Ubj20ilRZTUxW5Fe/jpcoEu+omIcrFM13iYL9ZFxwVdoPiWlCorDLZbUr0WUp3pVJHId5U0O/vRPKclUz4ofIAWCLuX/ZQiu8oTSs2yOjtYQ5RZSN6tSEW4NXJvs0dGiEDjhD2eCNzsW5ko3OhtudxTbhUlgpU/VTDiyAuXlI2bHa6Skdfu9DrE5GZHLd+zHewoKMtyRNxp0fgTl6onToQhXY8XrHy9zgIfOF/yq++xOTnzwwRamZtt6SPKVUhLGSoyv4/6tOo+7g+MGRzUjrwTd8PNIduajVyZ6j+Lz+jBjJ9rqiSo3XvFBDcaxSruPDnUaIHLT3krj3CH6SIP/EVfwYaON/IXWHmjcuI6J7tCg4DCIXJCNl1gkhSPIS4F3/QIvMh1F7uFdRtc1tZ6/zE56ycjwax3DerrC8VadETyNrT3VSBSldbIvBjFiqP4aYHuKF6/ZuojgxY85zuRWpvN3oie0U2soUYr3paPxTA00XDl9LZlENbLIORNl0mNux34B+MqCLrRUucnS52rNYomUU0oFQvoakIAXkJak6pFg5bmahdD+OuHaxAoXMcJMl4IYtwS4pYQb4wQb0KvWREvSgtJy+NEFUlfF9NY7gJbUdXhlrNoOYvt4CyeDAOxlLJTO2mVXulTWs4S/Wa5z4oW6Lb6zGdIvOvqM4ul2sJyaA+qK6ZT++VJvy4b0k75oNEb+cG0XI3x9tcPhl7l5PSi05XPfvnwz063c3H6sfOloao0zQIuq66tTFv55JW0u6Kezddxys2lcjd3uuYOMT+2WbXsIytkn6YKtlaSxJKDGN24jkWMAqbXkwp9XJKz7/98II73l1x7oJiAE1LpffHuw7u3l+Iaj4NPYke8PRt3Gw8UEPX7iWNN8BFk/Ltz7Ii68T0AQhY8MCsCZLl3wonjESfkpSrnpu5bQSJH3rrvRou6cCV72V6InqMuFoOgPzkV7PMT71bGM15K9xqIvF+BkfSr4pqW1LmWaFsX0LO21zbj2rbKPAOtoHc1GteNE/7GWtaW6LdS0Jb0boj01lOs5qhUy5WpNdSoqWzzhhYVpEV7sVOmsrltSWlLSp+OzrRYVFCw/YEieCQMnPGYBcwWxwfFOxCqkJI76kZGjj2QDfn3zEZlKr8meBdT7Zlm4uXiEhTSKImOkvR0O7bDZUIT7kwjlyJUYgYbINYT6rrMQ7Em1vdHIwGY5WriZTS+C7E1LbNQ4nFaxiZQb/7bCOGp2aCUN6282TetHgZUeKhQSIPlraQdPCayoTW72bbc7VZxt+0mfjp8+lNhx0vMFAIa2UMdlWSPyyijhfIurNDTFXrQEoq+dM204Os91CAnOvDJRVwweYrPWRg47I5laqimN58wBmenuXCkcAArj7OEHRT/rz4Sy0hugOcsISOV3Vx5xAbs6IbS+6VGV3z4U7OAF/Fu5rGBCCvIyweNLxrWPPcIypt07imU7ELtg1hQPu8YwuUZrs5wYSbXkKEWBjBkD7OAcbgq82tywyb0zvGDoyuvR05HxJ86IWgi0R0Y1cZAOrvEqERowIjnh3BrgZNn92XdWeDfOTZENxcJa6cziLiEl5DrP79IrbXZ0L3juuSGEctlNMB2HhU5lrkLSi5FZIqF4ZjTjIcwtgtj9A6DzQfDWeCPHNB6Rp41od6Y2V0xGYlpAnFHp9vB2x40lbeSeMC+xelQ2ZBG4WQIau0o9f23qgiBIjAJYixEFCaWL4JA6+8liw1NMiShYWjBAQwcnPpbx7PxZgmtDS1h0mT8gr6+Gux3Xw0Ov8SMY+MmDgaD7sFgX7LizINTPUzManLY77AEzjvR8w7xwHCf3/tETSthD2EgL+PmDKdWwPiM/DqGV89fmw6In/pyi/UB+/tghvXnla5w1fny5+BLp9txff82mg1hYw3F7fyHbOWA3neJWfkFWlzA4Qkd6g4F4hTvAYkiKEiTCyDWvUtc3J5yYcXDeHvW3BZLrKliNxensZ1mIgW7GEu3iyOoRP5nyA9slvCXRb+fMOqGE2vCrNtiBl0U6olSwnY48ShrP/wrviZv1esc2xkN+TYRjRHR2GbYcHPcGeFuXsW4S8m6MxFrrWElZU3ZwCIqMaUrP+OJ7i1iCpXfvYVkR7X7uaFTntzMRWc8OQFKKZd8unGFXDMkSYDBwtlpk2ghs9OaD/Ny05rzlMELnb/WY/cJsHhsrFihLqZ2B9CWc2g8qs045Ez16o0sEn0VFhUaT8pApKxzzxxFdh8wyvLHmm3sfTV+VeWNTeKMzBtbiDMya2wpzujMsvUwJtnX9bMlm4e26gBbmUldM6I4di00KetYiyY7jiYVGWCTuGD+6klL2AQwJPbIiS6QY05LKBEEreju0kJFMVTkTfP2cB+lvXvmgPFELzHl9oRJEMFCxbzFGbwuZy1EEdoixw7fn7LLvD0AVtK3Zw5fu49UwtSiQHObBCqpsi1EKimML4UqbQnWYtXuYlXOQm8PWJV1rkWrHUerutqmPfSAYPcwtAaCZFmrUqB8Jso1ECzLllsB87IC5ryp3x7wqdPJFoR2AIT68sCuRvIsG1teAl0JUFI2WQugWon0YhLpR4CgZpLpFn6eBfwsLqpWMFIpslY7aTnRteJ+WmypKcJOTfv28De1evnMEWaHRdq1YAdl27ksj+/aZRwNlu8NelBOMjQJ5DlnU/+OkT8gENuv0FYabS5Cf0aYN/IDC+OSiaAz0CyBNsGkHzzp4EEXAgFOKewjCO0WkJBNZ35AA8edo9G9f+94Yyh+5SEbB5aTYPkMRs53VHkdY5cxBBkJJw7H399zMvF5CLPRv/LePTgcbE3jbnD05r8BH0cYjy2ckd+efOqhabFsEryYr6H4kI5CFlxDzDNwIFAOA/0r7xi6otqkwjbdn1KwLnYhNbNwPrZFW3IewoBitluwkQ/9+KvgWdz0vpmcfFyW05OF8RHHbQBj7yABxfFUpOPKJbtxOspMm5qyLq4+7gTlRWGsup6v7pUX4owlZjNgPWmxTm7mIgjgnIdsSmiIv0JnygifMQvdO648zDTmcHL+/u3h4eHPPTBdp+gmAiV5SKezPvkNvDvvHc6yXbvy9Po5ng3+oE7I3Hk/OTqLerApbljsSALOLMnN1E8E30uFxTO92A8GB4e9wX7vcP9y//XR6zdHh2/+qGkleqEdUsn5IyVBFhtoES/dbM166Y/xWCCqlTnz/l7txPvYaY7fug7A5TuovSqiLCa1hBrjAV8ZPdZUoZgYY5GVWr+L44UAvAQjnqB7UCLtcVpM8bSLqekpjkDvwP7C4wQ4b1DBLpKxKQupTUNK6I0fhRp9tpAEtPDTws+TgJ/LAKLQwOG7oCMWzvV1IPNCeuz+wQKf4MsjcnZ6qh/TgP5N3oFeVv1IvDm2pw6s4DGuyhFEgBJOe2e+61gOhua6829ZaRHVt7JG8JsNvvIxCiGK7+WHC/IWTtcIVjbnW78FY+o5f+Oq8y45RTwI5+RMsDgBFxD2D5GIVNXGFVAuwAVP1TzBQ/n3yacL9efvfnDLAk4ucGvGbaSfm62ky5z7kTmk1GNZ8yIMGJ3qQvKnennxAYeXO0W5L2XFD74xbvwhX7yl1oSRsyjAUENnEKL9HOMGq8LGI90Wtckv1KWeBd2PW008Vp7lTaPCiVnXyz4zVvHYo+48dKwa+6vmFt0sqS837EpQ+pkMeJ4xkCgm95/j6G+JawD17D0/INeOZ7mRzYY8urH9KXXAWx19T9GdHfzLM7fR/pV3qa4eEFZb3nGcUfYraN2B9xwRRMvR+ZRnlIeL33Vv5sohM/k9iL8OnvTX/SsPb0rGVT6SgfLiC9CU2uCcm777PItr8sbCshm38AwVL7l547EcRSGQXfQf3r6r+DFuYtG75DjEZsduTugdu/I8n7DRCDjr5KHq6tODB0vSK9jWOrKDuHWLxsCHHqLWY/tXnozNqGLOQdfMJsRJEDXl9MRzmJAQlAaqy73im8kJOpl4prCb07CSv/pQ/Lob30Hi9WUPIfMwfQRGvyPUAx962ZoKtzd27pgnpXOUk3vmulce5eTi4sOrC0ovyNuIh/6U/Cqla7xP3vsQ9gEH102L+uRPKZxjWih35X0vq0AIy+9xb2ZH+J8wGLk5scuJSt0r73seQnaTcT/xnHxPZ04//xULrTrRuvRaoEC3frS/9g7U3oG2/Q70aCIYJq5LDwD+YybSL+VSNHn2AANLkM8s9a3QGTnJ7kGRHFuxYm7vndBkFKswEJikmoIspaX4I8GwSY5KUbMsU7V9HFCsKMhZsiqFQVJB0JKuQtKVoRYKK7+lwLKV2rUUq6VYS1GsUuNBBSM6vuXeV/lXaXKXGQt6qm4vdLkOr4dxdbKRdEBUp67moFfU382PqoMxuMU9lNmZyiaQQXgsG7e3JEebsXWGIVuG6KxHPVtPSKEVUDyzm+iE8bUmOcvMpTWnfg3GQRUDgPhC6ldOyK4GYX2qx/Ro4aEr5mARgtKgyWXIxqpyoJXPouVHYimS/bv0Q+qaOTlFWlCNDzF6cCExzkvTqTu7j5LWcU6igLdSioL5SGWGwDgZKYCd8fXqb6iIWZnvfMqMROUXrdv+68G3bieEaRmWzplqX1MYHBbobpEhFQkpYwStHJP45ExtzLxP4kvjg7Vn7FutLHepDYPkzh7SSgaq4pzEDfVeIUZT+zcIBqqEWarkkp/RZPQQD6SOF7kM8mMjvf0DaFEIuFcwH3FDvdd586FjUy7xDdEGLHsSFZbKStgo0voquMEzFvR+NcmNDihcxBwuqKtTxp4smDoi3Om5npWvOo3Id5y7RwGW/7a8daj4e9XGoYqXVbdaRaD7obuojWgpZ7v3VRUo9Y0p5nNzzEqlU0QRr1vkFoOaBpfrOjKxTIrRbfnaXL7WtOvU07z2LpiY3cijp2hvbBtvrQzNKj2AKgfUMtabZqxr8NQti/QUWKTnyhE14HpQW/P0uJ4KO+BiriXPKLg2vwKF60vmWoZlpxmWsp2xZdxKVa7jlkdpeZSWR2l5lOV4lF3jH3oyEfyCubSKeQgobvIQ4EBQn4kwLI9boceO8xCbMBReLRyZ8COefqlrFVm6zXeII6o3jpYlalmiliVqWaJWbLNCsU1ZUElnCsu4d7e/N3L9++IsZmMWDt9DiX/kiHLQ20h4pYDFrmipSIyjHURyKukAS/LZwumFcyx2Y36qX8qqVFZNO6c89GhkO6HhcVJf1GGOenUkry6ys5COO3khNfReKLJ9iJOqp1qUSTGzFrZ584T9QZfYbC80YHVGlIfuXB79TAuiVnFt/QU413cs4I6Yy6T5RxoQ4+SeWM7oaNzIl6y1wLLToahf9RbrdpLnp3S1kp1CwM1ZdE1uUm9SUwPVVeHsFGDHnPFYLGnRNpFFSjudscSYOt6peLlfY92pZ3cydE4upv58jSXcQFf9YCU9Beir001jXSsPD6BpUd/E9+qcAvBA4FWbtHnvdLuFXTS+XGsClVPNlhykivGjP4hwBSpZJBxTtv0vNT5godNHtu0MOkpZgDr5WXDK//6UPqhjMihDZ92jg9iEXS7FXJubIw3tqTYyt275XNG2L8lbV9odpJA/ruFXkKbriyTprXGlzQWeRYYkWqvBvxsc+imyjavyKBBMaF/xjaWCQ3jNw/hLXFDFQnliJPlWIQDMC1dQi3s9ZzOXWkKACMxgkF/vSTGwCTnbqrZuy3K2LGfLcrYsZ8tytiznc2M5m6UfamVDLaFuCXVLqFtC3RLqllA/DdlQDmlvxUOrEg9FSsSTLyHKVX96IXP3uOPdTnwX3qg/5dtxwLhk1fJDJKnyPbnHZKI9WTMvXhL1iHxLgsjNWqol0uqZJbWZmg4NSNTX+wRiYL49PTmXEXOmEJH3Blp56/qRPXIhbuQv//Pb6RmhnPuWg37kGJ9n7kcBoRY6b4t25OwYjSSj+ciphZBCYrjkYsasMIimGMNUNKK6plpxfYjzJGIEctDry09CuCEVtShHSJZn+hAXEevX0+s3VMI0APCGVY2V72wqdWC6D3K5paXMUAJ07r1hPwsup3KzSDsbmM0Jo7ZkUD74oos5oHR+quJAyapq35VmXoBOrXUWGuTtwSA+q7eGS/cMAM8IBAKBfYZVuXmqzV0u1FF5K+56RUYup9Cb1cbywQH29QD7MeItGNmnJqDufVWLXJElMI2vMk9gHr6qdH8V+Gq4P8dAatZ4CvjVvHq8Hs0zpmz23ElYwIC0LSZsCSZUuAamj/GYhblnGHSnVQdYGZLln94Mf0NTXFJ7sLfoYLekvvpYd+WvVWYDWOiMl/ntpA+4uIvlnnF5B6465lLjzltKXXWgt/qe0nIOOwAxj4kqpdbp3h11HXg/tCAJTLEcBqr04uIJwDnVjwmmkrFhanA505jzkQa3EEEaC8k1B9jgIXUZJAthdyyYmzIVzEFmoR8AOiBgXRI6LOjKyMbg6yQy2JwzCAooUUu1zkM6xzwkWFO889hDqMIdoNTHCcmU3jJufjlgelROaIhy/MAZO16XgKuCiKx9/e6SjjHJCrn+AEkiPvo2gqlOrgINUD1waOvoyrvyeuR0ZDZKqMfvIXHO9eHgFfnkh0S31DW7hsMUYKvncjbXAf9s/95zfYoz44SEjin0F7v39n0P56p3gR43mITj+vzdfx9/OD05vnx3AqlUMr3izIPMKGQUuTGi5HVIL5DoGwjY5DKUff7dv85Oz8Wnr7zfYZ4vHQYpoLFolzBqTXDFjSXhsbQM39AbyPzqhF3CIZndncOd0A8wuQxnLP4GbDBPZHLJzjsk9jgcvBId+eyFjqt3kcONj9tdUfkat23vfuK4rBe/ljtBvHRGPRTwXhPbCRhmmoHtDrG3AejmXYK0U2W+0elJ5n5E4uNmEydMRQR3kms0wgzKdoTpQ3RfHN9LrBPMxy1jMxE9U25fcfhwBykJaKbz945n+/c4Md999x0xTrwfkBlkjvq/xIZ++TJ+9/KlmGk1iVM6xxS1kCWFWBPqjWEqR/GoCMbZJ5TYbOb68z757Mliug3L5yFPrp1YNOJ4PGTUFjl9E1sVDj0NCac4ZI8x2M2eqh/iO9zi8iBDpqTUOcaY+fJwWr5nY+ofjLqJIMITqVoFiJmLoI+kOBjJ3olpw/RbL192xca+Pvvt4pJk8BpnWkD1dTc1ucCcycD8eBxtdfDNCValYXvplEt+QFw2pi4MXBFEEjDKfY/jkuslxS2DQKmZPwWjN74NKbUox+2A2W7ETOuSM+0hJtAANz4XvZTBoUWLsK1cZ+rAtB7LHXETQGoxfSKwER5B7nhOrsW04LRDJNfxdZewBxCZk6kfsNwFAwbW3EV4iBVucD0q6JR5DDXNgk7r4/B24vsccmxSTKYZV4ACF5AdAOT7QgQMPrgOg0QKMjeWMYFzSRWuR47L+PWRYsst8vn8A+9rXBZE8JbNVXD/uMNSIN3FHS2g8/P5ByNTAL4vpku4G6+B17k+gjTXesT3ExjitYBvPCbap1i2CSVhKY3BEmhINAludek25Xczwb9FjVnARs4Dy+8IDIqHNAglJTC+qerJVtJ7Q7aW5EGcOG2GsaqQpF4sESge4fkxuT4YDIyxi9MqtXlHBDMckSmjXoKXoJbFZphQKl7wPrn0CaZN7+rVwztbvNtgkOKkeCMnmAqoQnzOENL0YqTpOoJagtLCEE3/S/ySOHbw+jw+hfgGCbqOZoxaeUQRQWIxzwQughqKzWZi44stO3Op1ycXjJE/EenEAhwRmt+DLz9MwnDGj/b2bHbHXOBFed/SEwpZJ/awhb2Jf98LfYGMPfHoO7NR9NcVjb7oX3lLmYkr5R05PSk3ES+7pWAfe2JbJmJQLH3XlCCPF0PBEYs7y1dTSapOkQQELnl2ONISFTqmFYW89MwC346ssLd/cAiu5RN/yjDgNZonvNOHK/mt48w5M5tOH0xlGt/t6CQo+V1PogZniawDunnEG+j6/f29mawEFljou82HOI4zCRz5n1UJCZhEHwUziTHpFjLf3btx/fFe7tf36B0NacD3RDcA65NduDDJgPk9pBPwMXVa0h+1ON/j4RwuixaKiYoK/gXXZ5s99P/icS/ELompjaHtNMRNUNCgIGlSpLBVN5M3gK+mJvUY0bL3gXrjCKOqd/6e9N5+gkyl73snDMK+9y6FrtRm/Db0Z+LV6dlbYClEry4wlEDgQjSVosmh4XDmWJB1sP/XbIyyotJuMK/3+SKvG1P/xsGbe6oXJ++qe2H742QvvgjJhAaT2JCvLqy8d9kDouwv80s4wEVCsIq68TlcsAF9oJrUN9CkSbULlD29d9BXaZFqcPP8HLjHnv2r3APfalsUV5L601HiGuZHro3MuihNuD/V7AuS1q7mKcQdGYOKyIulCBJxjVkKkL2eAo/vuv69SHiJ78n1/mD/zbWgePXoRscI5gLyrzgOy59fzGgmDsiDBgeHbH/wevSKWWz0E7V/tujhPv3p8McDe2Advj5MWENJq9nm9DGR6EdIF3sYKqkk6ZAhwAGzrPRK6OljDzMX2dX7ybyGCNIkrvI+lGDdk6CYJm7AIkmi62PAGXkH+OHXy8sz8moweGGiol4FcAuzIWXC4OcDvSAouxcflrnYJOdNrjLfverIq+sctteVwNurTpdcIWkXfyGpvOoAi3ilSdhVB6Xf+ZsAgpwY6ysTUXY7MdMoDK/jCYnfwM0SiYUc+8HPFWPfP3xljv2zJ3Kb+kLu0DXui6rpPjlzGQXunDqh4qC5I+h34IehC0uCfKlaQj5jzG484m855jtLhUkyN/8iMZGK6hd7JSSTuaZ77dgLs7NJe0fHTpt9pm2rbBlVxgzF9L0OxASb04hdlbHo1xim9+IWx98Bn9FV6QSE3L5E/p8Q2qv8lnJyevJmSfUFx+FEC/7JFMX1KJhhrsDSnAvz95L904L8fr6y4ZYBH8qHZjSlTlE8HFm4x7kLXe7RHmoggOb1zHcJf2CezVD2T1EWEi1KhY1RNielFMgGzDrJ9qXDcZzNcfsiGdbPCFY8NRsPe6e2xiJJwGoMo41612YB2+0sYAePkAXsYDAYVCYCS0gFQyMtmCQQMpaD6BfEpiyfxsGgZnKw5cHGLLJjiahMyBMUKeYotj0LFQJFcWQ/+RpD+wlWbjVsEuduP2fhSy0nMOdpYfLuAg5FOqgU8ih5LiuFJKzAeQWU8YVMitASUBddoC4uPuxBgMcQFtET7xUisIeZjzYMswBygaNsDvVi8R26D58BOipyWUtZvuONAsrDIBJCq+1kgTYRxPgm8mwXLlqwa5YcQbItcP0w4GnJuLDxqx5GWJ3IDb1kENiO4TW9RFMY6/ge4QgPW7Bs37AJoFyR5zF3RaypbCxNGXAeZK+Ta1ZfeFgBAo/PjcuQ82Vit7pjaFnxxwhAXTaKyIPu2kPxexiw0ZD+vD8a3Ng/HjD26vBwNNgfMGaNbOvnV5Y1Ovj5pypv1qfDH60nuPEO8UBlvmh5Ap29rzlPq5zQClgp6YtWj5WSbmf1WalzNH8qZaX66pEnZBGgEHVd4vkEbOBZQCIuHN1kF4XhVYB7zgrms9AfB3Q2caxYpsaL2aX8idsE95T/5dz0GFst1qraA9tCSYflOqzaw2iJ6fZlc6jWmCx9GJ+nqOLZk+IKF9ACIgqeoPUoKPh91iefUNpmIZqdw8KCWVwxIW2J3tqIXumybQvFq8rl2NK67aR17cWxjFpdBhEX9iUXdMTCuRaqZ16gQL3b+YMFPsGXR+Ts9FQ/pgH9m0AGL/0j8ebYnjqwdsfSyhyiAGHrZ77rWA4K7O/8W1ZaRPWtrBH8ZoOvfIzCiLqYQihXuaDK/RaMqef8LW5AXXKKIBfOyZmM7MiFR8g/YGLj2hhaW6UmKniq5gkeyr9PPl2oP3/3g1swQb3AgxO3kX5utpIuc+5H5pBSj2XNizBgdBorVcRP9XIx/Uu388E3xo0/5Ath3Y1Wlp1u5wwUieeRa7RqPNJtUZv8Ql3qWdD9uNXEY1n4vROwewCUC6Ffjctn3xizrpd9ZqzisUfdeehYNfZXzS367BVTKlAADa1JbUYQmOKanCDmEqzPCqLVEEpGIhl6IAwD5wbPB3rjGU31oS2Olqv+SHjtBMJLS5q/CktWxxsfETTs78KYuyBfb5nI7daGGQF3l+i7bCVWCLXKqiWUVY2yoO70LaLmCNprRHuN2LZrRCv0KmZ1cFS52ieX0Vtmg70NUjvq9tCZttik+J6OesqPEVYh0wBHYZlMaJvJwTlh5APWIG91DeEjjGbPYcRT6YjK03PWaUu7JJPf0T1d0sZk6A0LfI0dz/KnIvSD9G+H+hFnAWIBbq8Z5fzeD9Aln4YEAl4IGyCM+kRuPf/eE/FWboQfRYmuapXMTHpdpCXMYpKwqmldOSUr6H3stSS2U4X8q3I3CKq1WPdXQb4KhrkI2arRVEw50pqxEUAYHgz/DqHHPC9Fs2hQsGreNf1FYToHEWckqfQDdN0rXDI4lbK9OqQzJztYSsNTQr7VhNyvjYw3orRy3R6B5BatRiHRFbKe4/dJuRI8iMUUGNXOLGM+W2W4wEJaVkMIkGucWoPW8Xxap5L2LUnuGjajKF1XnBygZH5AbIfLH/DeZqEww8iQw8RbMvNnkatdya6tUf+ejvrx0Ic4t/2X19IJEwLpONZER7MI2IgFzLMwIJlIw4DREAUVjb0NkdzicwjUPqGuy7wxyjNEjHhNii0aBHMoDWAY+FMHKK6xFFtGZtcf7rCgKwlSWTuN0w5S/Jo9b4l+S/Rbor9Wop8l8o9I0Y38Kk28dEN/PAYqVLg3TTrd6Cq9p4nqUrdqdNo1mso46Yp7MRLamIy7Mp+G1CHksxm6Olx1ezYeDDu3EaXtkJGDiiZLhpvESA0Q+gruxEZ2X3Jc3FESMtcVMAXb6X4CF+zQJyNHhs9S1/HEbRyYjExQOgPat4w5qOVZXLgTSxZ542Ra9CXel70GPseLDPDZUvN6mfu6i3wwvYao5EkFtGipanuVBnYwQYAW9PmsQeyk/2e8JfNSlJUQkbJLta5eUM/oRxwr0mYjir7XcLeN4cj2iQgddAehtEUwa2Ew4sqAZyAchvDiWFzHWnV9/zaaDQGihiJTFYZq7KsASxALqR/QewgsBATvqvPiuk9+89x5kgbGjYvgyuJcCDugQnhVGdMkp018I2zndtHJR7tEZyGxmRtic9L2+KS7hmfiAsN6tgQ7ny5q0OIMw2Kok7ynOVkTL0KfTME8qXjiBWu7rDNFwcBirg5zgHRUH4uHxyCuCOAfC01sCn108nI8MRwlizS5d6qDy8XjidO5Kq6g0wQ4ObMCFl51XhTkn1ZzXy4sqT8cjcrrGY6kA7mDaeUez0LuUZP9KnM3rSGl2Puq/67yOa3Bykn/03xWTmVDLCMgkNGhiJfT9SskF91Y/IDRPUEoEZc6PemT04zuH4SRISQHAJ4PmhXsna+YsAKWUIX5zru9Ijsp4oBsD6cVG1eay77OzyfpSiOv1C1mrBJhVkWipBr+qZtmqVYzsF5VBqgWj7M+h01F0qIa8IzNN0m/0MOxpgFXPl5j5suSrVkiZFamW/nyW5PrxUaErerSuN6ibCOULbWienyIXejuuuCY2otre3FtL67txfUpXlx3WLVQlt63BmsjM/7mczcq5+9iDI5hrFePx/EIe3A4WsAtcmP9xQ8niTbhwgqKCHCsCpmHWRz9qROGGdgyIMFyGYX0MiWOgc+TVdo93UOVQdyO8m+LD6tl4VoWrmXhWhbuKbJw2yrrKkuU7vrjWcQne8wes72//Jtie0iQQGHtnqzck3V7ULeHdTMGkKceDyk4BUKMD1kka3bGs+VS5iLr54LkYBa1DMwOYOUEXPdQfGro+mM+/Mu/WSi5SHF/H82RXI1vEVKcV3c7oilmrAPTZnxNrAWLtsCOpXkoO+2FcBuHCarpOw6TswNxcuSa9gFFF3aLg6eN0FlaD6VXoiQvg8fuM8W3CKU3EQhGuNXV7aMs/a0LyQlDFtSvB6VFQgOuE1jWqSlL14+OUrALHoN21Q7FX9jZlnCtJwxweSJFm4G4DKd3CLrTugNO1xP7fVdOGNBBJD3D6tu0rhvX2LFYxy29XoBel1p8+WO+BxgV+O5ewACqAJ5GLh03u3/xnmylp1vpYStpCwHXBzMqWYTIIhmlLM8pJ7zKYNCuC6izMUIvR7ZgvJScgaiKKyRqqo/6S0P4UtMgwSV9VURtDX3elA2RwAGLOXfMLkeLbETQxtDR7XxHVVzORwETm80CBtGf7HIM4X25Dn298ivm/mthg5Tk14AHUXJHEGL9mqLCw99UN7QrQFXd3WeIVU3w6THi2K0JjSp5m4DOHZvvfQ3oXNmrN2FqRPWeqJ3Hy3ByTuenJ1lxMuRtvZafvyZ05pAA4lmrtJFCwcJBe89nzIJAfQQL9wnUFPVkFQz8G7AwCjzyNwv8LsE4Piqsb8AsjDn3Q0DnBGqBrh88DyPP+XfEXmwMBfmEBmwoG83V2et5XOH3RJu5n5PXMvm5f0csAAFow/bV3c5oN3SmjId0Olu2baOhZhyl2nbrQGjRNRSMaFRGRaALoFCDhcx0bg14LDq5rWicxzlu6RWS9xFrKlm+YoRV89IUWlW9XFQ13ubiqnydg6zCjgFC7Yc+oGbgsDu0vHICAldl8uvl5Rl+REDtDeWORShKMsiMhiEL0GH6qjN27hiZYsMo6cKOAYsJ4yB/4J9Tx4Nvf7zqdFU8kgnTT0WkM+wJPIbjruEao4OqcRAaGiFHv+fEYl4YUFdEC7VwX/TJNQ9pEF5D7xzPciPu3DHhz33NPBufswf5vE9+YRYFcwAM+07DLvRizDBxMTbbhY+KnrpzYlEbIrJ1CX4DTAdoSPYHxx9F8DchayN31I0YUpgj2Zv/PBjs/9QbvO4dDC73B0cD+O+P/8U8O/1iH15cd4XbVH7d/aK6B1gXRwp2a95/6FBVLp0J+njDyISCdYgt++rOt4jw4XCXJBaiDbNV5tnpNpccA7S4CQoqxZdLTojSMsTtot3Dks2KNraN3muk2E6Kn+leS/OfkqCZ9w2CvCSjsBfrVhbhF3oak1ImPvp5nl0PED1RgOghy6uW2rAOJ7AlidA3iQBlt2zeQ5pHZtQJuKLxt2wurlnYJMEI4IIQxwSSGN3YUADSElJU34BIztLaYEa0r4Gm0kAo1Z8WV3YBJfr6MDYHiyn16JjZwwmjNgukbjc/xIB4/lFUuAyox0d+MOV5YQRkIZIolbJAxWDITIBFtvxmzrA06+VDsOo8zXfOfFXUiC4XN/NuOgvnnfiE1az2Xu/81Wz7nOkv2vvn6qS/hWDO0rRZnQWRcyabs+5k7tGpY5HP5x/IObOdgFlGNjqRzS1T6a0weX+Hymv99LfAGTvxF1XP5XZM+knp4aSyw32knBf05SMdOxbRWd70IX9FTk78C73vzqV5t3qPt9bSEhfUc0Ln7zi/XlHnLhgYZ6bS96iXv/ih/MIUkmhkvMKKbYzjZ7JnKQTL+VELz5StSD6caVMQbT6/CjCTGNQLTbRYNG8wRLwrxygkdDUQ6j0LIWsIoQTaREexLYeqQQPMyc7Rk4Gt3Jcq1WQBpKWfqzSQpUiX/zaR1DL7oeRjVTgXHJNPZdEUYsqf8mURfqafmxlCi5Ar96X+TgnkZl7pSrlgnHqsEnxWQHTRe1m9GsGLS6g8p2mI1w9kgaKJK5izUkqQ+1JWLKASqceJpK/LuhjnkJei58Vkpzzt6xMhRzrCan72UuGFU06QpI69BklS1hggkJU5A1JpR7eMPCUsMvLJiiriVFKnltq1THrLpO8EKpY5H059j4Uye7o4XmVSB7O0CmEoz2RuAEPXJTM6x5USbacx9JxN/TvwUr5jwZycybJKZIyVRKjDOF3hsTdXqZEAeEWqcGL7jKPpByRVABkkHE0WgECGYG9Qryf0lyjf9Pxk10AISonn9/xZn5yjyYn0NkZjbqj+AwOJwgvRq9jRLwfT81AsLpKYdJRYojd3LUHlue6N2XujN7G4kI5CFohwabKXKxEbJjqf2BDQEyPTQa+OoPP9uqL2JbpZJeHsdl7ndU4Dhc1mzAMt8XwhD5eV9XNV1M74ZrGD9A0LaRkGGY301emuEBT0qOsuHPBPYITZd/IPGrJ7Opc4YWY1xa/wMDWaIjlFYhtjShk1oJSkogrNYtiQuVjdOWwe158zOx/eEm7W5DiJUPk1WCht4jh5NXi1Ufg5qwCdLUAZISPOms7gxE4oL5vXx0KfFhqfMTTipbUIrnIjeqXYMICXAjYMXiVBC4ukYWvmUksyVHBMvufFyIPQhJxXdANRtDAAKccicAlmfXKBLzCQF/BLKr8lOOFjNksIrZVlDVcKY+v3PSjHJ8h/6niwdnU9EU4Ukahi67YBYQ/zEVbOOyQ6BU78hpFR5I4cFyzT7Ajzlc1817HmMJgwcCxtINBibou5G8VcIx1iFnXr3ZP3vsI/VakAim7M+fH+zcNfeFfWUaDzr8vZAIkQFvEdMs8++q6LYty8IudfeNd00e02q4dw9CwuyHms66eknCKmv2CjDSEvRbhMsItO3H5aSG0h9RFu+Avf7oUwD04Gs4sv+cvc68G6MgO9InR/Be4KbFwEd3cBMRN3+k2zmS0EthD4ZCBwzEou8vkq6cSJwDJZjNIBuEth6hhWB9nDGbgxUZdEMvS2XwFdRgpNaXKMnKEXqgOlLnYQ+xSVK9aEemNm/4cIpA1pr0W9W8Zm0uFMyj+lWXiSwxxF6Na7zWzmY0sQxF5oGMiglR5sDudbQtUSqp0lVBgHo77ww78BOYEsuRcG1HK8cbW1AG7vRN2+rCt62NdXhowoBJU1UJgVqNpkOaETRHdIzEJ4x4LAsZmZHvH7/5+9d9FtG0kThV+loAFOJw1Jlh27p5PBjwO3k3R7N50YsTOzZ8aBXCZLEicUS80ibasDA/sQ+4T7JD++ry4sXkXqZtkmMOiJxbpXffebIMpdwoozBs8Y0Hhbdp8mblnptZxjGou5AWnF+Jf7btXqnk5RXjOO6dxkIdT4dBOZGMvy6qbbq4R4Vgezl3SqPd3wazYT730mi+OK85qEf0XHlEsAWLmq8lSN6bVYMJKid8nLBlrAgEmSwi4PXRZa15/bK3VdD1pS/8yaKQltsianMg91xTkIFg0RyoZCOZ9hPKbsOLQhIr/RBgvR8DlE5FBC/uETOFCaSqMyyNmVdn2JN7oSsAfADOxbpxTE02sWQhJGeudNYW/73c7UC+S/B7ncjun1wJZTC8of2JTefWDBOJp03uwPBgPMHYll4q3GOtknfDSVCfKbPVbubj4NxjEdp6rVYyVUqQUR5iCK6hVY6zkcvP4JN2sWmN0u1TV98veaWmr6FJIt5iEAF3AqnySeR2ZG+ewzRQ/yOVGTJKhl0FeSa9NOsAm8WAEm/IW6KOU8KAp0WYTUP4cBu3WwlL2FZuhpjUiz0bw1bru4IoW52eSyzR7MLe8XyD0BjaMJD70/MT77UV5zag/tPRcKiO95eO25Lgse6yUnG2hv+KgIX5+CA3VAfYIDPNZrzuziud/1fSLlfrLlwOqCPqmmi8r4LJCLK8TPRsYs6nsUBa9/fS+fa3+/+RT3X8uMVwvF53HG3evvHrtdLDl/thKDSXEDXLeyErTtltpK0K0E3UrQrQTdStCtBP242LFWgm4l6Od4z60E/bRvuJWgn8tdr0+C7hZ9SpJ/bE+21l5SmxKsMb3e17LYqYVStQkNSARrFSBVR7aWDSG6qUCkxirUtSVqxeXCFyXeMFd7jogYvb3cRNp5FMJ3yquq+OhsrUT6qDdUUbIVMFsB8xkLmDUdDFu1WKsWa7FWi7V2BGu1arFWLdaqxVq1WKsWa9VirVrs+d31o3UssRJPbEr/pdM9fm0Qy2G49OXCOXT3ooiOz5g2yKjOQCNmZsvrz6Ct1iT1fHbD/AINme6vqst5kMRhRGM/EuR24vkm+SPMhdoyrYoryzS0m9qyVibfdZm8gajqMhF5AV5Ggdz+ZYaS52BAPs1YcMF8NmVRCLkDTa8kwQCUVQR5TpWckWpSUSXbW1LdwVFGqMs9vowMlhZJ08v+x4RhRpk8iEJBRtkrl5cxL9WOeHhLQ3eIb/cuKp9HKoRVM5gDo5TZnaSN/hwyb1Mn5ELoXK/XPA5cGs6LJ56xUHhi0YRSB6/aSh18suGSgUM+o2MZRiijVgvnCIgX4AozO5vSOQTAwp9eEEOCnuMYqkdGniPDfJPh4RQgXhYsAjyEj3PpjVcGDlDvc4aP1x4SURi+ahSud0yvoh9gcmO5NXbTEFZ4BfmX1moSWk1Cq0loNQmtJqHVJLSahOd417uqSbBk5A1GqTSYZalAFaMYqI5VWaAUsAJWaukFWgm/lfBbCb+V8FsJv5XwWwm/lfBbCb+V8FsJv5XwWwn/Od714wuhqSOVrxhFU3cKGUhTnLu4jtxfEE2j0hnXE/5V46cn+leEwiw4oA3FwbTiayu+tuJrA/G1UjU09QL71/02zqbV+LUos0WZzxtlthq/RyA+thq/VuP3HO+51fg97RtuNX7P5a4fs0/P6gFCDWYpixEKvbEX7DnAEA9DNtbyTaH3j2zcw8Y91bh3c9BTZc0Tvd8HT0REtibYmsjWZEpnszLPH1l50ffJ6Vkv4qlZTD+CFSbHcZgRTGT9pRkda2lL8dN98o46E92dRMz3hS3u3E48Z6KWeMMCFwSQwKx2woEvlmlqcC80kqLb6VlXykc67Ii5YyxbFfI4YuTGo/hrwCgUsCIXHua4OaHOhJF4NmNhL/JYSBze87kUCVT9KBqpxcxCfuNBGgdTTc0UWZfl1W9B/Ah4cjJYb6qpTrRc3VlVOsmBjfT04xsmki0Au5lxBuhATfdHzMJ57tLPIHWBlCVAElHXB6XqkPtGmTiHhb0gYmMUPlQkWFr42E8tgYXDxcv4aFaASBBERVgLqzv9wcAWhAaD9GpqeX8tBJgmdbrYHUpykjjBkym7T90we6FyIUMbKQxvDoYA5kM5IKDdWz404Ly+CSS9aEx6GzxXQ0AyBHHJISzaVqKEmDByfHZKHMBtt1QQYTRaBdqHrr4+DZIpGbZAm5Uj4A32UXIPLIjCuaU7G3rBiK9naHvAXEqVvBhuCelq4+k1aY6+qIjcYpiqX1LOBikvuKG+5w4TarOm518wcBoYGhz/lgrafZLHixSVfFbsA3JSzujMp8FxipX63rmOhRcgtOjHHbFwFnrCPPdRyMy/ZyGX/7wv483GLGAhqA71B59VsGp4Rv0iLqaKgTJYqRbztPdd3a43u+9UhFiX8VLlhfJoUPWaCziqKb9R1baLOqis/6parBr59IxQ14VkPn0CWsLTMwKcAjE8hdRXhlPqgzKBXLMRDxnxOf8Wz9KVX+VGXBgC+TGE7aTJ4eCQeCOLg9EFMzVbJ9DC6uEIfYLaVvjZpyJKbcGwgB4QSdizi7/FgctCf26qzobM4aELragvuF7eLjFM5uFUGq4/ZW+K3E64YOZMxITHPtyMvcXyZefkTE19OvuvD/qD/kF/v64Lu3qnFY90WS5G7WRNeFZHObSMRj1GY3WqL09cEf9GdL+KwNd4b8tR+IBHwxHYddb04JLxWnr+8PQ8F0ql3mIPdQvhlOokeyEjcx4TEat/3NIgAiFfDkCiiSdIwYEZHQUO9H87ZbFUZRxANn7qVxY1p/0JHd4O7ScvPr8/IUevjw5w7NOzm59e5oi9IdUTKlK6Cx7qzzbVzzR7CqQ64nheBJil07ObQ9Q2wWGhjdoYgbdGsuFtbYBerxN5ykfaUuvtUWtb/F+dSi96Yi2Jbkl0oTtySVb/MrIZzwQL05TzJGQUGUQS6mz9zeioHAC8kQJ2W2GXsKaQRBdlWfiQlVTTUu3Zlwsgqp7LpjMOT5/873//D2IE6OOBj9gMVuD6c20hwBRn4BjlzsFI4MZ6SvxZooF69DvixKEBDzyH+rC+aREN11ReRDwElTiOnLeUAPVC5RWq7+mYeoGQ2d1AeyK9iK5+fXdB6ulQDCHUv1zZvMRAMwtXhgxf6WoJeC4uZ9Kragre7Pj7l88fMqdhj/iKvHC4y8j+/k+HL6VpJcWrhAyesas2NPUiMBa86h4NBnDKmo15IgyKk4WatXEjKUf4hr7tNvKnt+uyOKg1DWHEpRF/9diduv7AeWy1Ac5MYsm1qVJa5uxxM2fN3txq9hJJNdRW1mwySY993+14s+HUE1MdzbSOqawRwfzJwfwZzNdtA82P2zKkD8+Qaiea2laga/3ymtp/sGORFegX5GXchTrPIt8aaQmKTZRClYcNVq5SmiFFwpQXzekZcJAJm+cFLpuxABgQf46ca4Il/bkxAEmnCuAQQ2S4ktJWV9ieucy9Ul4tUh2iAiQcNGQAH3fNCApnGCAQMqLAvnhQeOJmxIfnyWrpYWpfboYQNUDD+LCG67Wk2GMO9S5bbmB73IC8gDXbVeo/xvoMQUvANk/A+tex/207lg8m2GLTh/i/jZU4kvoVqHLkm8yJps0I4RccdyVCiIF1mtSoX6XSAWiRXJ9rLdD9WzIgUDIvcPzYTahVbgiVz565JA6cCQ2gcOQLNDWB5wKZsnDMiDnMLg5KCVBc4nAfqj7BJtTsUxZELxX1BjK8iH5LqpoQbKpKTwJZ1jS3gpynKW+JqghUS+yGhXO5os1rjnaDA1iX7kNifAVUayPhsziy9BUF5HsDXoZmvmzEak19yTIoYVX2ac3qE/vwW+bpCTFPDV/lcoqVVgXx7Di4xnqIHD3sNA3uMSNYepJMpE8SvG5H0giL6pcH/CQuKgW9pB7AsAjw35hJF9EqeFIcj/pVsVxyqvJQHIzEkTysbEwjcuv5PigfYqHijfDqMMoH9KFoKKJJdBENxyySIUGY32GsAvyhZuYN62OotReqlcicP5xM6E1mWSpcfkcYl1qhKzVewLIWCzVUU9yWPPx0bFtLX9dPX0vOet2ktfZLa9USO0XUasZYJJSmir4NI18MHd9jQTSErAal9CzJIddLpUrpqTXOYt8XGLracwDkR/i5gLqdpL/m36SMWpVrIvZY2WhVK61dakmamOGStoP2I1+ktt2jgduDeFeYa2kyYB9VE3y/ljVbn4w4NUx0Ir1XnUW4pXD5S2GTddCVBdtdhs40GHKLdKerYv9z4YbVp+jwOCjI/XTBI+pbUcUqlth4YCm1A3MJ1o107BRQJq+RWew+5sSUCRAypvM4DAHg4Ss6ZwEAmwhmVF4lsy+eQ0cq5+b5mNuJjk+uO/7BAO3VEfWHlWemxzfoHrfFY3A/nxPBaOhY/lOL5hwks87028ynoUruCZvivox+FXBQqJ3aIC9m9TGi6mjVCNkFIIIovJSedO7Nww5i38+ls6iOcK0V//p1jRwG5MLofUB6lE5QpliPM6BHpZk0zs8/INeVwpo6e27hxyR/rjM6Y+HUEwIYg8/mhL6bNCd/EcJ/E2L7+11leYTwNcODrwYZAHwcfXwmGbZiQYBptzPjYmk+Jp75nLr2lJlEvPDZvo0C4wg2mfM4JPw2sBmZxAZkpc6IOIjFUp3vjhnYUbRMzqfTOFDEEdrxGxaGnitz+4oJBX7IGr5PznxGBQNbBpOys4fpAb0p8IPK9vSNsRnhAWQJDFhqdVq8PvYF75Ip/cak5SriSpSux3iR6zl0BvmdomcuUraIJzWIWeDOuCeXI5jcjjz49IYAf8WS8dlBTm4VS0RdDsd+h2vj6npHMjejdwMsHuKzlYa2Ruod5KTUNCjZs36ta6HIQ91uMMXSqFnNEFesveWIt80RPyjAWeljVxhWjdI7RO/MVUdDBEr5LPW+bVS3WTxBff/TCBH6eg76k0qV9rVlH00qtnosInO96BmwiNKe2EQvtvc9DRqVyUjq8ZiydymPqcLxq3hM7YlKC7RliZFlRTVZet/b4LEWYiMrMGenlXj5K3w8DEvF2luGpWVYWoalZVg2zrA8Wf5Dp0yqKAu9mH8Ys5SprScTIYtcshMbhb81bYorRQuiRtEpTWR8tVPKYHhBy188GH9RcruPh8lYtIGW02g5jZbTaDmNB7WsPVkuBNPCNFCBmAdV6iQE/p+6VTnrIr2EknZCcMczlYoy7kK/qWbkON2swN/EZk5O35Ie0VMQewrjuTD2bpjkXvrkfMJvhUpfb7YpY3ZUV5nhRSW4t98KMkqPyP2oOqN8WYHOOrnls64EyyeUL1tF4ryRulE7w3zpIo4yaeUHZYsSEY1iUXdJ7z0fcgGl1nM9J3KQPvkiGBpwaU8weAdwZMrtOuJkJDuDpTT2I2/mM9WRiS5EO1wC/r/sQFPldq1ivfTwb+XucLDLjrTcXnZkJuBIVz1wCwugmbwysleqJpr6AaLZoKaYy2Y+n0P0W+pHn+EZdE0+WfiXbjmMvClzhzyOdAMIh7B/pL4PRKK+O1whKtg6s6v/NcQrL3KNW+gYV72Rlul9jB5y2tvLRHFeU5CPeSBdQJq5ez0FN7mjB3CT21/oI2d5xSUT1j6xjfvDZZCLrvn0qJj1M4sJLGfXW2590i9jgRe7thUlAajJfEvxuMfDnusJ/CdNuo14aK9QjSCpfMKYv5NuYDwkb+UQhCY0DfjhE6ktPM4OkQZGTf2gu3kwEQdzpu2OFrjK76xL1IoxwXGgw9yRMFgn2CenI93S7RZpLjEOTSXCwZq5EcdBzCIYSAbeSLrCyUj6KIkyQ11nHxMeKIYyzf5xK9NBaicgTvg+v4USth95xN4ge0gJQLXkCvH0kgyTPypdxo+SAyzd8c4JGdvzjMOQEPiXAhr1ea5Bxjxt1bK7kiJFjpHzbZM/13ZkWw5+HpDT5bOmfO6KW2x54MfIA7dRIm2UyCa54icTKbI5Fvkxs8Erpows11fvfdf/vF9VdQ1G92jCkqZSE1eTcQZ7J8CYoYTn2LsBz5wY6mWmhxxvm55dKQqz1ny9+i6Ut7pVuReQwFTEcwD7ujCXgh55GxynuYODx2Wyb/QCHpbrk1KMnU6p0pa/3M5aZm83rfzDlY3nqbdUbkDHyZTZZbUJFTZ+bUaVZMMd0oVJOBaMnAwELi1mdBmtNizPwF17eDNSMv763Sx+wqFlWsXVzyQZqPcKUSx1PwX+3PAN6/XnkC4idzNI+bP6gScDyYEN4VofTep2PCFiFq5KZOQgyHqGHvWHigtfEVJSY8Hg3jigESRdWXFgMw4Mum6g3gw8595uK048bY37Zvxi9lKeN+twktlWKh17TVUyAE8q+eyo0vnxJ9Y5bBPrPA4uulWZtirTXVWZ5lx+JUPaMjVPmKlZU4acmvyJSpFjOQ+oNS1ImmPZAZVaqEYanbRLQMTTWWTlMBnNJ1rh9drAWp+Y91OcEGApNOvb5vnd5G0eb6qZnzYXJ/Fqg6lmKt/qbjCOKsyqkmlstJuWj3wIbWzVLuIAlusO5d/DkI2G7v7PBz///PP1q59Gr1/Rv/505L522BFlI/pqMHjNXjdKEvykiPuzIOBL5C8pVlI0SmtSkzFQeU3qsgUq0UQTpqBe3pNqNUaBNbR/GUivvF9kkWYZtYD551M8QxcT+E1jqKfjhSLKeuaZh13OnECEiIyjUMnxdOEiLEt9pVTeVyBLALcD/HqfHI+w6rSeTK/McgTsZpcKJanRy5GOWFJDsH8Z7FA4di0j0WOx7y5+zY+HbWiwl5ZpaJmGlmnYbaZhQdKRZR2gFpD3nFtIDfqu+9iE7HoOMb1LSP4tpduSJ9NjJnVNNtPSupbWPWJa9+y1303N+zpfealBv366LinXQXi8Ln+EjsMwQI5ovjNtyblsiyTvn7JtHn1pD956ydk9oX15IUYn4FiLF35F0ANqqxIn7KgqvA51qjjBrVMmddi1PWnrrL0lRLvnN7v2FFaPy2jbJmqqSbUMUVlEqEqCvevRHJGmOYW05jyNbUppTBLRqaOw6yV+JD+o1/wDBJvEviujriMCB02YhyB7jRrXPYoazqzo54mkLIhVKiTV5LlXCNkE3rHxjB6/tgW15FntNOFdtOaW4LYE97kQ3KdKVKviSMGpbygmHvPdUmEP2vRkGxTprDnT8ptamIBCXfqmidW6qn53Qc9ZyN3YiUhCznVspyzVC6W9QEq4ZhN64/FwS5kHrbX29Fph7CYZjOUQ57Dd8+xBGdy7bZRbuLGlilEvGmgV9LpKRersKQG6Q9hTHRtvCsABeUJ9eT2L6BZj0ar61PXfhqbLaytQXbS7LZWpLtpxKf7GrJznEmF1O2/5lALKT36U8lHRl063U9AOuZ1zfbxa8kr/ui6RCyn9BgpnF9zdytKWjfQlASnG+1/wW0PULzuJ4l4Wui/B8yZgYHtBOQuQ/g7JO4Ur1X0hnBBCb0wRzqE53qGuTbnUBItH1VPzIJBRP8M4hPgDWYB9uQkLxrq/r+/wii+3pcW7QYubvwCJldZIfhu9iJYCl1DgEqL6BOlnTcFqL8FTFSGyFr2VcbBWp1wYrMsi5oDMm25VFA7L4+iax0GqKZlSFy1et+w6Fda1CwQ1cQZhd5gAHJB77eTk72Qfkdru7YQLRr58/gC/RtTDjJUYpAeb/vL5Q48FDgdl65fPHwRJ8pZfz2UqcyH9R8szil/7fNxPCGDf4dPu7e1tX7ewt9VkO6dBne3I3YRkCj68294OqJRW2w8W7J7SyJmUbiSpUFC8m8vgH57vOjR0ZdYmEc+AA0nSmIqIhpHKrOrCzTNqFT5AJbvsIlsKdEvuQmP5z8uAShjC54MJVwMOaVWtScFJq2tiNTHl6jVTGe/letkdddRWV7uBH7s/pj8uXeYAQj0dO2DWivucsIKyB3jYjFDX9WAIQLPm7JSLOdW5XVU2/z75x4QFJrc/WDfwqDRrgUcl04hj+D6qhJIHchmgjzh6fgN9BVc4PFTEWybxLNZDIBcTMOkzzMcBM10zEfXYaMTV9Xtw/nNZB/6Wh99MwVBzz8Tnt9YppBZSeWfppFxNKz2kY26zEcWL4mvTlR7KCj3w0GXh8HreZE0jFJfRARGgBM7RZHy3zqa64gJGDQwFYwHkMUkKL2R/96n151d76a4XqhysDdZuOq26fiocu1wE/gXTpdc4Cz0eepH3JxtOqe85Hq9fVQMhBCkoMX1TWJLOZoyGJv5CRcxXbqSEKy+isY4bDJ2xt8RqWRHFhSuUwHm157hBzxl7VwQYBjIK+bR87QRvTfrhKBziCZyo2baWqWgiSpdFgEGFuJVsXROdSyBpa6qZ9Mmx47BZUv3kDbmSZUauuuTKC0aoNQiiqy6ipSsvUF9LzkB3rlPZpKsHy1EF4KU2QauRciC38aKAQL8EV60QbdjAc4aMAJzjI1madOsZd490q38BVUYxoPvjnjNhzjceR137G9Bw9fuPGb4XdlOf48W9w0nln6MgFILGRh7kkve9qaeqOh0NBoMBZHEIPbYA9TnixkJ98FejEjaF0rS9wGVULI0lCxSpZKmwZOpeHQt5s020WoFHrpfHf29SsZCW2BckrGigWdj7bqlDVVhrLXNu0i1n0KVFioZSQy7V6gSbHJoBrDxakjCYJqdvd0flkDrDXTEX00X4Zzs41Bg7k4lrYdBmW2gxaItB14JBS4Me0giUf/OqMhfm1bKyQ5VKVrcoUseqr4V4cXfQ4LI6Pbm3Vp/X6vMK9Hn4OB5al6cW0erxMnowPJdHqsOTa/9hHQq8VkXybFQkklZtRj2SLDSwKoMsqYbMEVW8cZnKh7lE5fFp9EIaPwjWH/eJYEJ4PPhxweWqZpJfmdK7DywYg5fP/uDgMKWjBeZjjYeD+2YqodC5Hry+zngSRbMh0JINLem3KJp9ksM3UGRD8gQhefcNPiIzDaFRFHrXccSq7zgKPccmAj69g0XpnwOIp0oBAo610T3ADDWXL0nWjIbRPEfI9K9x8C3gt0GWQCDnvcFdoJGk3i72quHLRUFxs6uVc9Rcr4XZi1a+sk5ZrnXr+mScdmVdcnrxrRak1YIs0oJoNcPKOmQcCPTH8I+GumPoUq03Vi3KdMayQYWeGD/vlo5YndPO64fx6LatG4ZJV9cLp5beYsMWG66MDWvpg2ccXG+aKIRNj5xGWD3VJLIljP0KvXBR42zRml3RFK/Iqukz2zavpuddkVnLLb/FT48cP206msBCEsuWqLDwjsyFLV/zPIV3TvALclUF6CSHemRz4MLgs1JZoFY+yTSdic6jUhV7C/p/D2r3oNhI2N0slGofKSay3QjGXk9cXuMFqJupG4lmbq0c28y3zMbJSWvhyUarbzHlk46aqoPnqjL5F7Fie9/lG1qYq9/CkCohfwGGVBm+62LIMxZOKTw5k0pelPWV+XofGu1Zqkp9alvnBQ/zSMIcey0UtyA9e4tqWlRTC9UoVIEteDgGtQS+/R6KVeGUGjOzJ4jBJmCrzwG9CkkqAHsT0CAFs9Jk4xnVWQFukgqReojJVqC1yGhtOrNdZ7bqL71Ff61MujICbZghpgCnqZwKddGazgwTYQiU+dJVcmfXEjS7Jp0zhFwxGUalgEB6q2FJpOKJnylm3EaeGnlTK8jNPTXCfeZxLD+gPQwmO1w+k44a0Uqok7zIlQZMRrnvdvD9rjKcHKBxMpxHShUbrb4ljM9eLqibuEW+sQbGIN2hPDogaVFkBVJfU9bwohwtXelRJpWvGJoMtE+6dns82B3qtlIKF30aTyB9S+lWHmHqFr2XNsyjDfPIhXmox/GwYR5mEW2YRypUQp3LowzzqLX2B0rTojFiZYqW/Aa2m55FL7JJaha95lXSssANYMfy3bmxZL7ZMtdgNmhGSZb9D1TaAocCmgD5s9WOjwgNOGa59BBveiH5N72hsuFloFUHyqSNyAgDdMSEylgddJwncegjTcIG6LloajGS0wASZk6IQwWwbfpwsfOUi+gyCJmD+gm5Ou3mAzxC8ZhAPq81p2fjuOYXsIY0OfpZLUqRY57f08uPs4AhagO/dinwy+DqXcyLoxe3Zb84Ne2KbnHZxbeKltYCUZ1j1+hCVgxhUAPtfZf/aBTCILtUhTCYFmUWWM1XlIQwqM+7ZI4157Tj5lh1dNtVPMtJVzXHZpbeIsMWGa6KDCsjGGRwQSXWwyYqasH8nddV46F/LoxVeM+kIJQ0kZLk9mIScOtWxcHegbTBaa5scPCK7Q+ORofMYaOfqfvaoa/26c+v/nrgDpxXR686WfXKunQryZFUs41G5DJCmdZH2KHIppX5tnkNS90doELFXr/6YZHaBeWDRgI+1szk5Ir6PoiBWsXIaOhMiHo/UChGkGkslACilJamazC/6krVoWUzKBpiQgX0kIMUHECyX+r79nYD2Af89nV50fpCynJQ3Ewt0dxGHYE2fR2yWKlrr9G00t8aySoWuD9UQRQJ97pwiYT6ujVQivpuscJjYd0TGoYU9boRm9bcAHK86DVz36REY1XFk7LbXTe3IjdQwZ7ApayPQbEoWBlbggyDzVJoTsI6jYKfEs5idTYgRYNXCQuSdF1FBdGEtheHBpndVIQDBew2jYAeA2HfsodTTajVje8tWl4P3HVrAApJTGr1U23vARzCMYtqdtONs6hF/941265dEDn/5FrysSr5aEYm1kMlKu7xmRCKUuKwVVKwKHIKB9j7rv9ZK2BK0g4VL1VGO0zcTTnteKuDowLC7jyBBRtrUBBrrTtCRbq7TN0WYdz8Ra1dd1YAodKZo+e5CjgXRW+1aORB0YjCB5WBShItgEq0DCdI1Wc5QtCqIunJH1HPR9GWtlhh61ghc1UtE/YYmbCyS3z6qPMijJUbzDkdsWhu0Gjug5bnWcgJfnxDzk5Pzc80pH+Sd64XmT9SX47dKaZLPMYLekOOZzPp8nOm8718Zjf8G6tsotdWNQjO2WCW3+Mopj65+HBOTgDmRtJXKjfXp3BMA+9PvHXRJaeIV6I5OQv5DbhACelK8yscbJnppMKg0k0pTd5+PNf//AcPv4Ff0LlyANBjZH8vUrfoNp95bG8p87PqeR6FjE5NI/Wn/nj+AbdXeESFH1XHD9zaN/6hPpxQBxSxcTiuqRiC7tQlv1CfBg4sPxk19bNq/N4L2S2gpnMW3niONXD+i3Xq5tpn1i0eB9SfR55T433VfKJb5Ul0oCGaCKpYEuZ65TwJwHYlU6LDC233LDTqSN6klV1azdwua+bqKt6ycNByfI+R4yu9xafP8u2QtAwEpzoGXhImFQJfRppMiGo5cfrMZj51klwjmPhRZiQpJU7oC51rCwPI9VhWfem5i666/txK5u3SiJIZFeAToGIWAIIUwm7JX0v+doX8rc0wlQfGlkI+RgpZcY8tjdwijVwUTy8NU0JpEzplTopmQZZ7Yk/3kn6LlU3yroymue3kYjUv8+g2wSJaAfJChX55oVZmv5ThPta4Dg0w2HVu3MiAVivMv6V8qFvSKC8+3Bahbh6hmoe8Vnewetf6gPjVZbOQgQYvgY01YNzjSlSxVTcya4N1MHPfQmjVbmRJIkQRB0KiYMTcbzoHg1eD3mC/N9i/GAze4P/+Kf0MCzD6vDdjYc8J6a2/59BgeM2GVk6lEqui1ak/ZhGc1gkNfmHvAu2tmjYupnrIYBrme2NPHVMWef/KML2GhMl0X0DM18ykC5NpwZZxWU/PiEvCNuW4Ou24i/EDNHa9CMmujCmohXA//ee6AC11NMOCi/iciXspWs4vFOIxkLBtZl105r0D1JVazJp4q9nMGUqRuRqsaweZlAGo/eIRiBZowHsODXrXLEkuVgP6bNG/PvCdyO1nQU5mDkmBjm5YAGxlrS0AIx7GSAMfBK2veZRWVrQAaC6jBbtNgJ15v0tbnuzRsFEB7JxMaAAZuhZAQ97hWvWrAUm7AykpRVbR00qaQPb29AN7S0PPUSdYS1XTwt0Dwd0aQcyo0EtCGFKjoY9rEYyp4ITGMKb6PUsYO1Eewy2kPQ9Iq/YQl2PFgi0ttJ2dfaktt8WCLSm1Qc9SmU0nYTLZ7zBm32c3zCfjkDoMcrB53C0A5qJXkjTJPBTY5+nbmvqwTcFOwXnnoOhVOY5Qy84P+p6H157rsqCzvrcfD9PCSI1nHQu2fsEI3/dyYpE+7lTvhe/byTRfICrh67a7dMuesHTXCxl1exjAHPCgd+35Ukvl+FQI6coGVt/ImzIR0emsmp49XhCwT+wzKkmfJySkRm4kuCx83cqc1vCBS7wkwJ9ORZeno4Cqh+uTT1MPyaHB9T6jN4phw/Zx4KCc5PYJziXzzOlIdmIgAhsr3gsqZ4KWHTwgZvG17wkgMOdR6M0Y4cE1pyFoJbrkduL5LA1ZMrOoy0nAo7/BVqgPMGiSvivNhoDvhI5GMunP9Zz4NEomUdH8cumiT97iemHtKhObtQUJ7sSbTpnr0YhBnlNclzlEqnPl+Z7D4CWTkMnK6xjZT+Ig8nwrI5xyAgnYXUS+XJyQKQ+iyd9IqHAoDHnNRuD+yO5mXjgnjs+oSu0HcOiCLVViHxHxEK8DMhfr6deKWlbidote9Rdlj9xBvFXAATfEWL9QV3PI68B6MMThEkN85NF7HgeuHOH1EiPA0fieEz0CzKucuzLIdxEXIjGyslnW4EDARnN29uWT6ZazZ9u4lFvNinLJUysJNGRDgeSQCoEVDiNTyt+wEAzHLsG03d3Ejg3oEf4/zXd0SWIYn4Xoqb5+/qPbsN/Z2RewtS3XkYWy70MzPfoVnOGpPk3MsUa4h8cHOpWaEK+bL7CY9hIgqw/te9/1P2UbuMBOZRy2jQRkK3iJmm3BF5DCBZ9mEeFxJOMpi4BZwmIOMXzCxKeSf4H+mJwQib220Gih2vAb5aODlwsyDyydjLaQ9eiTL0ImTAYs44b0VlcSluhixgK0EoHHBxfUf0DUoQHvwSUfOvM+8hJRpwX/TYM/n0U9HicYoCdBqqYaG9rkYPjYyYlc5xjV2QCEzxBAZM1upWaWLbsGskQBPHUVRKNopqf4QZg02vYK1HA8xJzPUynOJQgBYV8JDx7WrJHigqtEiT5Ra9RzDtUkWp0BY+rFo6SouBKzc2REaJoV6dotE4lOFsOBcRcwKmuTWNaBUVYVeIqelQXaD8q34JKeJr7aKUFn/RhPsDy2K2R6QtiC4GG5WKNbgLdZj8q0uon2KqdSRavIme5EjPUv554beuyGKQ7mB2F1SUlmb3TSCZXu8mrKXXbVvQy0oQESQ4oJvx16kPhVRF7kUf/KyDIEE4NatQuu0M/uShZb2LwTrzk+y5G3bjLl7JEYh83+2iDerC75l5xrqOcaXgNuq3A0LV2lditttNp1uA0nezGesg0ch4t7b9F1uIupigszTZYcC8DEMleN/WAenW+46QCyIxxPFgLrj5bvCk9t6gVn1h73u53Ii9DtvQC3qMMLYt//2sR/urvgqzr/r+sMBjEIV+e0ZuHUw2Kh4rNZ9vekFgWf2jXI6MzrU8fhcRChpqtvzrGvAje6DbqE6H91v3pybfnvxbm1r1lEq/ygzeEscPJKnJ8nkiPQ0xYj9BNzGr2/s1BYuZYnjMq80WmgPmc+c5StT8x8L7LIEwC5fMX9Bv4hdlLf/f7AyucLf+FbEFC3xWdCAGkVkR7R/hAL9jZd/+drWTRrEdlOqT6LzEX1iLdd2LmEbNuaQyh9I8k2FqcJuZ+4CSTdExLvQQKHUReUDV7EQzTt8PAyoOEU7EYF1D4ZVxualAXWkKJbyCMtB7gMFAuAZa8KOAR+w8LQc5X6Mx/8A/vBMneeVMyGsAYVo/tGpqeOJiYXBZQCBi2MKSGGoxCgqrAlRrRBDIbtkXMl7IGENJ1Fc4LJhcmLq399vXqpLTtAYmS4AHQ5jsDMBmuXSbEVi1TMFvFQc0Ayz/Y1uwyIXuTfkmlhfeTF1ff7q5ewz5D9W5rGUJ67OhwMrnBujNO78twr2Uhbt1+AuDYOpCktgb6XsgTgOOChLK3hBbM4sgYquFocVwnHur6RueqE1YAHQswd2eWb8J9YJzyZJ6nQjBNYRYMOoWaQM6EhdWAVMigbv6vih5BYHKbC4kwwLPEC17vx3BgC8bpoSIy4ivuG2l6gsvf+lAXKrHt7cO5zlSBmxbwo5gPBFNk4g09+lz8mUC1NEqColFZWlO45VEoDi2THKpMtmRkzLBBePhqlh5cGWFBvaPShS60pv8HsaDDCveZ08I2mB1Tx+vJ2lMEWbNewTAufmNApY8e251Js1L+yLOL5hN8CZNkPWxeW8fnYC4i6ZOPDpaitVY28M4miWV8H8seh18cyf+wPctnZw0EuO51CPkx6IsLm4QZ6htdLNn8cTi30q4AMcTnLL1shx4IzpuG0093pQyj8hNy25O9WlJk6DWPWE+K3k4Jd6Spbwa4V7FrBbtuC3WOT04w8WiiqFSojITvf0IFMfbCpYtsMUuOZyuOX0DDM7Ecwy58L7weRUllia0c20yVhvYCwGxbanKrMpOPgOUqKiPkDI4+FXSsQTmYV/MwEC29UAh+0lWouH7gSXKs1GQgNcrSr30/Pz6/e2NOOrEy7o9i3JBgs6DvncUh46AG5NKsSUFSbjqkX9FM74Ey6teHissvA4eQysGsXjiCA0rn2HFAmPDBB5FLy4eQbYzMzkDpLWM2E3jB7BSG7ob6HRMSLpOSQGjwQEaNuF0oYkauzT+cXJPckvEAPId/FFa7hL3/5CzmZcI6CHUV+G7cH386xeKopDySMIFYggL2RMtcVlA4VV29k5fSR52CFVyygiuuVx/SNzdXNM2FGkfoD0SUCpkWZAGq1moLp8ruqiounQM3zg0Yok1wBDrl6g+KBPtZbdNG7wgfWu6Djq+QlqDF1oVe7FhIMJIeEAsPZMdW8mlXWNYhVj1nIRt4dK14IbMqqOmvPqfupURCGEZwiEJv1aDmI08y6daHM+aalutiP4PdjcnUwGFh7l+KnQu5vsGr0FZkyGgj74RkDp3XhfXIaJTCBvFA4lcIhDebJdpP7QY5nym9A6XDBCdaw7Zqbpxqi4GgMz6yHhImvTt735P2do/9o/gqh1DHiAHMINmLHUVH0FPD5M8CR/NMYN5Ki9Vh7CJ4rRlvga/QCor1oYcEum0nQkI965tOgT84ZI/+SuBN3/YbQ4hV8fQG8t3izt+eCJAQ4Wdj0Cwr94gh7E37bi7hE5j3501/sQXs0cHty0JfN5eB8qS30gJEFOZcseYl3JB/u5sRkSSokt2ALXyf64SmUIRQVA6BXeMOWtYzZMORu7ES9/YNXh51uZ8KnDLJIYN2yzjsDfhlBLweJ9tBZ0E0o9W8aUxQvPY1XhIVZ7OERI8HSb29v+1Z9aLjgKfBlqR9xH2cKtRRPGwcu0zMCEGpElNqTGSE37961z8d7hbPv0Rsa0VDsyWUANUgv4dwmFPZ8SElgMg0t2UkdIfZENAcdkIPsaVnDf4s9L3DZXf/fIlmFfCUJPVLkJ704bGjRmCyx0tjXDFO0ge8da2xZ3b33gQbjGB7Zm86fk97JR0ir/L73lkFW496FFGRcJr5FfCY/nZ6dAEMrV3UO4gSUZH9Tfjg0Gs48JwLZ8t+zMTpoVC6DBb0v50XLmPJrD5NhZVbx9t3iVbh8nF7F14x2gAbzT6NSr5MitPLeZ3eIZX+ZXwAAl3meLOibwOGSAxiAatLfwiZNup1jJZH3cA3LdfuHF02+hP5x4P6m3sB9/XJVC5mBkc0wODz2XRkDgq2J4FPD4CBp7RquAzXGVyjKXyGBvJIS5hUaEJB1n3bJiPs+v5UKcPxOrvYH+z8pv4N6dMNWjIDkmSg6/vXV1iF4br2UmomuQwl/zeljca2YKi1SSh5QRoTUTZjjY3czHxna28m8hmrJJq6nUkxIMfdppJglbkQYostRzaOkhBe/XVycgRXgpY0VzS187zioktkfvD4wF4L6YzmxQwPFXgJvTi5z81528M0Ay8lH5FLi28tOl1wiaZf/QlJ52QEO9NKQsMsOepwVPwLQkFj3q3Sa3U7CNErtg6XxNl/AboPEQu394PWCve+/OrT3/gUVtkYI65IwN3SfnIGJipFb6kWaW4aayUC/Qx5F6OWHfKm+QjFjEB3acMf3BRbYlVSO9uNfRulY1r9cAwgbS3IIZFftuUuzs2n1mSct/6Xqz9PAVaUVbAXoD0b9CY/T0gOXq0HNW9xh5R3YvUvj/O3SEfV0e3/BOxjiHbzBjBlf11VuHJVjFVo3rRnTSjd16D0lnVIjOIGVXSvWiKsUY7Kesi+xdEpVpMX1HxRr2S/2JwTQHyLoD6muYlHqWgiNpSTYM43RtRB1fEn/rIshoq4P0A+wxrHVrjgHaIKPpGVdV9ewEhGAWUt5eyBnD0TKm5r8A2DwZ/YvBE2+WDIdjL3wQbCxLD6NkRxjD9RpPgvGEDDxDhRDqsFlYDQ3EY+or4MnUPcrRfv0L9chvEfi8tsAuAmH+3y17CanBitoFkdHeNX3ZmmQhrTbmdK7D3gSnTevDlKFtb0A/eJTdbULq2knwSjQLHs/5AL+UA4NJAQXX2nOj9S1XQbq9Mk1fKSh1G2MOIAEPHYqyOf3J+TVq1evmx2EHAIkH3jNMFfqdA4GB4cFuRiTI8Bo38VHwO4cPxYQHoxKnOWO4jKwX+qDHcVByVFAj6HLfLQ9VJyHfEvkhQeKLocHrniJEZEAZKkNIpDqcCh48yHLgPWxFg6UhhbY1J8G5MXUC+KIveySVz8NBuTFhMfhyy75+adD+Mul85fSwfjg6PUBOIy8wMCol7WOCyxiY/Q5M0cDkxhj10+DLv6Nk3XVDHVLvJ8b2+T6bcqhb1DnsBDPL8gFlMheilsH7yqgophYQCOzjSy3IhetWfV+gQU8oHE04aH3J7Cwv6u18pAoswSBz/CuVOIOJ2SIWqn/cNt4ld+GCZyAoxfxaASVoYIIoEBzMcYooC6JYXAPj0NnM+9n8U6Oip7RKdjjAupLm1YoJesHWeDGcheXMTdl3GmmWNhqiYiLOLKFCRer+cA67J+wnVQxVtf6lo+cT/i5PM/3449vzUZ//PENQUaXBe6MewGIo5IjPNwfkF+B59FyaawiWjGlM2T5AYFHGSi3k+19pMrEZWS2VImWLFlMRs7auUfgDqBSFY1tO1GSR0CKUcIS3mQr21V5H/01vCkQpv3Ualg4XHZFU3oHI1qLUksBhITr7ZP/pwxZ6E0qVDpbpNEY8LN/BVg44oSSaexH3sxHbd0RCKcTYGCujsABdn+A/z1Sfq8Hg6vK3R4MkFVV2x0ATbZ3nyXAh/sFGArfGzyeCRXkmgHfbt7j2hCVeSspLGVB+OYxlDJEWskayxBU48qIX7fn51KEFKV7cuJ9vwhTLk7VXhpnXIIBZea/HrWwYEH6TIgaNjfx1PHglssu1QdAR+fumurcXbX6ydbwMFASqd1PNYe6S5OQiQn36/dNemS1cXI19phmYboiU2FBphYDroQBnxKiq8pWajGDe98tydFz7zsVuVRKsKNsXo4dpZPfDmHH1I7XiyPTQ9sM2pZQcosMWmSQRwYKou+7jQQ/0PyXQvWvmFylBekWpB8PSD8LCUfX3CgKQi4BdFNetwTWTSnIFtxboaoVqlqk+1z5KFlspUikklc2VMExcNXqEku17fJ7L+khFe2qW8/ohQsKr/qQ3cDnFAzJepqSPLW+Tz7NWJDkyBBJ14jjCz5Xb6V5Ejd4BWICfnpS91wjf5vdRausm3XjgJqlJWwotdwWjk5O09TfqLRcv/d8CCiD563z3yUHWqY7f+/TsUmYIRsRJHZJOY1kHQW+WKWm4+rUZ9YZqDUO4cUMtXNW4vBZexz0dfKcYWJIWw/qOJeH8ndzCuXWMhliiQ/xVxqxWwqXVPCrLgT6lmNq9nT7/I8LjG/NnLzwxDSU5OC2n7yYxWrnZeFLMx+YX6ZQd53HJ0ptrZ5xmqEDFEAoMd+ykebwHXNTprGHDKZylfGI3c2kZ5oVXjmlilxAJ7NCoT0xGuVmzL34oVNZc6kh/KjRVgGg9EC7BkYFsLIzEFGlnywlpnvf1acFmso8LCglZQEsGPVkCSyAaymFJ+DPVfghwoWhohkAQefMFFklnwwUkFhI7ydP6Pa3nu8Tn0sxyLMph8pM01nPW5cH8BSJxS6/cvVAm7r/zqw3Z7sCZ7g+lfNXvklg063H44AHLZjuS7V+eSABhV8BhICqz2UR9XzlS1sCKaYakxJ+pO/slEUUg/dlVx2olwGbjTClBaziejgvqLv3FEHpyfFdpgDtqmxXIxHFEKkhKomQZyuuJJWHQRAxi4AQkpkrWLGgHAoh5fOYF1WNsjqhMF9OwXReMEyopZ111TeXOzF48q6JndPFS9cBkjDWU4TJXSZvkNU66bECM7eXSAoNFCbsLoK0gL2kcw/YryLwSfJb+74lliSxNCU0TfcTCzqmuDyZxEIWNpNlxoi6wXN8a+Sd1ov/TgM6ZlMZ+uj7GCGAqnLp9o8ZZ9JC1PLEUA8zHDEKsdRD064heoNoyKU7ywe0dHdtUVh6gFUVVaaChT5NWYuulppJu1Vez436yHpR5qH8g12TYwFOltbz4CGEQ/fJVcBur+Rj+TfElMjnUvEylciOFffUHBhge+sJBsG+qgreEmOmXni/Uy86KWC3Vq5d9ZdaQ6c8qqKxakzhhuTZi5Zp2yGmrW8h/K3ozVZj4JoRNpVZZRnFf0/2zen88Wcp1MkcBg0MAHHg/REzNcQIYswAy5SwfyKVufXhbAJrEtRw0y3k7xLk6xe+DWV5TbhVWYQbgCyqSnS3rLJk7PNriInKi2tJjzI20y4Ut3CcTD3IlQBGTjbUQz8amCHn+lCfNPAkL2fzyo7m+ooiSHjnesuAwpnM3+/PVQZ/0QgMlIb97Pji5Dci2JRCMOjK1qcsbKxFb1E06JOGuIfTZNQAHn2lhX5z+WevXOYKH75yl2v+9N/Hyz57SIMJCfOx1Luua56uBb9mEIgry4AvDQRy2BYMHgoM9LU2Y5yWU9+h2AM19EzDYniS1bntdk2ASspBdbsnlRbcJyIIwUiWtkoD2qNxHXpe/N3W9SJNeL3r2P8mGb4aUPtL7H8j0Hh50NV1rRaQQBNxnnY5AiUHJTInYpLr5J3JtoHUczbz54pWCk9geq2sBwahTshF4sy+MjdZApFwuuvhLBdN8KTh/sHJa00QNsC0ArHd+55c87IuUYWgXOQhVROMC3Qb0kHFiUXEp4v5WeMikgJn4HBvIIIBDNLcrgGl0kWs7ilVAjaPyHPqqcPMku5UtguV9dT1Oyt9kbqmegQl0QwrqB9cU8+qxYAGusPloczWINZncMvgbTPQ1GoVHzPX+TDeVDaJ65TWVy1V0SwGO6WvWRby0lqbJcnbRnjKdSlpqgZ/0tD8WOhipdYGM3LScD50A7E34uAMS+9GWB+0JJJE9+i5gei96CV/w6AvezhGD8ewweg9/EyO/+v954LyzYEr8JOkoFFIAzFiSXJxyFUeejAQwXoKmE3whXi5nRRHqQ1XR+AXJvlMdr7+JJ/ptcnr05NUpfkvWNODlYlM72GZrO3lIzxwucjcnOheq0AM8wHPk1yqECWIufM4FsrqpksmYyE64cHkRDpOWesznlR3PRq7XmQnpH9ERRnP9T2Stx/PyYvkT0j4/rIUO2MZdI3DTTIH/FX/AeM1CDjGqyyPOFafMeRY5stfD9p3A4HVJHsaA4p+CpsuFy6VwvBe4PCpqjRVqgxYgOF1tFTq517KnlSkIUhfp6oamrQvqv1IzBySMuSL1uv9pClHkS/sDlKGGgezaZLhubXoRZOVtoRk23WHF1cZqXipLYV43BTCYPTlM3wtQvhVmL6nYv8y4UgVeOKt6ZALEHzi+L7OsWwa4UuLV1JW3jyfCuzfaN0t+l8/+q9adBzASzcuzSEbDfePBs7R0RE7+Ovo6JV7fX04cFyHHbo//XR4OBoNaC750ZPH8uZXrW39eK7/+XyogFbQLqXW0elC6jL9Kut1I6Zf9XncRGA9GdrqrwCuK/klfT+d2gU4F9/WLhKmJstu6VJLl3aOLj0LupOkZSq2zS2gPMaZuiblUQa7RpRH9Wkpz9YpT43b2kXK02TZLeVpKU9LeR6C8tS3fPM4GvOGdhFlk05bRewfF9tEzpRZu75FRBvCSwiU3sdOEqia9pDyQ9kta0iNdbaov7WFbIkm2K/xeVIEg8PXZwlJo/hy3F5oBanAD1U2kKeM4RcfybaZffNoKvB9g1W3CP/Bef0B2z86cF6xQ+fo6PpnOnDoT0ev9o/++jM9PHCOfjp8ZLz+ynj9yds+6uD9RraPNNZXlo+ajL1SSTdg7FWPx4z2t615MkgcJ87i8NrmjocTNJahQvUX3RKhlgjtGBF6FkSmoaEjTWZ0QFI9MqP0zw3IjI5jasnM1sjMwkvaRTJTf9EtmWnJTEtmtk9mmls19lSi/07tqL6MbUN27+nxeulVpy0bsi35pCkJXsyF1TajTFftSygPUqUU0YKwe8dnNBTkFALYrqnzzedjqCBit9sNkrXQ5FF9WpsmEOpih/q465k/aq65pQ/bpQ8agnTS+Rb3Pz3crxF50yQnssAyH40q8Sy8XRuHdsntxHMmZMpoIDLeUUKWBBARn5GQOcy7gUFVooN+I+oka2MuS5xk71q0SZa+qU2aVPO6lOlxUJzqM9g0wZGX1Yze1FxxS25actOSm/WSG4WZmyBzmeAg4JE3mi+L0mXUO3xR4+QzicCxf/x0cfr+/+XQ9keOGFHlujLXnkod8rSkiOyRbDfRSO9gcaqRgrW1+HqLCUckHLUpR1qqsAaqINGzQs1NaIPiFEqTgFcSBciSWMzk90yVtXS2xGKOkZzr1gt8r0weKjn84yAFC/e9ixx+/UW3RKNl8lvfqfWj+75BodUuVCXIHi+u5+CGIFFnFECazu/qX/d7YkJdfturLn0HCB6Xlxmwp4bppUbJ1oAQ5Ew1e+sJXQrvHHuQ31RxO8iwCfdWVgZCDeAmA8iyeNcsYDSaJEl+ZYXLkGHZTC/AD1QmiWxeCyKzXUyEelorD2q2p9rACl2xsuhJHAq+8ihnLDyrqlGRvoGLiUnDn8Vw5OT876CEm8UR8qT6pUOZ1EB3Yi6WpiZXx47DZtEbErG7aM8RN1dwIRNGXSaR/H/1TrjvMwfdti94RP0yHKg65TbpmP6y+303M2gYBw6NWGkkQo2BzRA4+Ed2F/XUrTQcM2B35j7v10fwU3NIuEQg+5xQ+25HX0EhNVYCRAVXcEwcH2sxIPEg3MHKd24XonD92AVeAV8AAJ8XRGysdN2e0IXN3W7m7cRB8nq0wlvBLQFOK/Kxnm4XCuqqt0xcGtFUtRficiaSgrnr5KNSxwqkysjYDp9OedBLkuGuk2biGOQEp9VotDwbbm16WZoN95pFtIJOmYPwAuGNJ5Hoa5LSz5CABSVQ6lAr/Xd0pyTo4uC/JOmh7A3N8wF9aCSRaXtlg+JiB0oxZRqSkecXeWOp4o0EkONe/5b5fu9bwG+DvVRnXXpEGmQCTnwejFkI5cJR3+VuTXJJPd/msksFDdgKjEl3qSVQ0mNHAalH2wTs15TvOgNVy0ZvybKrJQCalEBYAKJFtVbrA2uXxEIVT9CdyE3sw2nIw4FafBwrlTwzsFyTFJ7azJJyeOkYW5TE68vgOXZL/X1xFzWSx7+2iG1D/MxmsJ2OWSryJU+S4hRjO1McrQrX6UbN2BHtFDIL+Y3nWnOAko7R0JmAVR6FsRLER7xgxJWryq4gwa34lleAcT2P8pZDemyIZMs4o9o3eEEhe6V8k63Q3kJ9v5f6NWdjATqIQnFpncZjI3Gnat3MeRwCrwRJtUjIfOWnxq2K9ZvHC3hES1pZYOf/tHdujBTreutydbhfU2/OxHIkyqJFlpXyhWprynoXXAGSvVcaKF02C5nSkqkbWwOYpiBwTQTfGZ2xcOoJAXV2Pptn9l0zc52/pG7oTYg97+vYATRTWGwGkP9GKwD8s9QIYB1lOQLBq6lV5BlVJ4l/qYgDIZEFYpY3nYPBq0FvsN8b7F8MBm/wf//s4OJERL3AZ0L09JJAHar4T+2TarQVoKYzK+9nXqiY8Nh3iReIiFEXVBlTGtAxg59c78ZzY0CdfVlwrLBAbRqZYV3a9E/AhKS9Q6EcrSkXW43UsG1BqfWHRVubZ2LkzPqQzKOvzcDguaWOFpnBXUSdi5baIs80k9MUT2J120eMJ5MSvY8GWVZxhXvfdek+VSu4JosoRYLSiqU2AOWLI7LImSRluO225Fp6bD4UPu2aiZJjWeNcelCcowHTmTqiZZDmOrRwiggsoXvL91xF47ZQ4VZbxZa6lLUp1Uov7AFJR8tlb8nZpj4hMYVz6/KxFSg3x7SUKv1KsS6a0xNU+Hzw77a45zRXmk4ysTwj3VKDHacGOyxPPELp4Qnhf5QhqnlzysaeqHJPkemCqDOxaIVyWcG+hcRC5THGBqX04hi/GmOPy1wPhRDCxiETgpyeCfJiFPIpOfF57I58cIuMuNTv8tAbe8HLROHr0zkLyV/JP47fYwjWyduP6KTiOUxIPxdrWBgplDFbLmF3jh8L74b582Q47bsluHTJnPOYODQAD7GQUcHsVSR2qus54YE/B8UovwXUGYV0BEXXcRuUiClgF9CDQTjY6RmhrguLYluKAUjf4/KJtFMXu5zf/zoIRGY7y1CKiiEezGS/4GhMTFSjnZlu912VyjpvAEzeAzxPdFOhzgSuWA3TLEyrI5ELbG7KXRjXHcpn0ORGrJ4552oKNdy9KbhNW+8RrkJ3K1qxNBGD3gYs3dDfvpzOwWD/UGtWjt4cgGalv3/w6vDon51uB0LP7K0CtfgU+HP9d+407rudG+rHTa8Lj24oe2b5BEQG5j7xOoFcgo+pRqtr4y0qAX6pmJkmh7AdE+zKUud2dJUPFNsh2Q0Jyst70BWxEWgHLuUh0MDYMhBPjIHI3WrLPbTcQ8s91OEe0qv/O/ysD9oW/q01mzdQcMqZZ4GxtQUXa7/WEaNRHGL4vmoP0SwBjwrfa9FeZpz7w6L3806iVvhOPFf5AYYM0/Cg5w6SJLgePipG9NEk5PF4orpaCB9jFxweBMzBfAQS5RbdbHKJsI6e5xbu4r6QHZO3tDW2rByNtjxZcYAt/piPsN20imi3mbYaBoIMz+ZMaDCuUv2cYIOWc3t0nNt6jBTV3Me6JWH569fa1RkK3mbLf7b8Z8t/tvxny3824T8rMWnLgrZqwSYmyDjiQwkVw8gXw2/srtRLUAgfKiIyJ+JhDzr2ZMde5IveN3aHOkUWhNz3Id1CTqF4DF0+Sdbt4sM5+c93/0WS5iofl8nJMPZuWIDILYe8MQOewkJdG9xhURCABmR1TgQDf2Ch8h8DPoHcLzDzNzbvsTtHwZE/5qEXTaaAIGKhEpAwAaDsCaRhMAL0U5hEhbRo5PuDUHilS2ae8w06IN+JaSj04ILM4BFGgLmUO47qe2UdP8Cf79HAYUC9mLgyiJ3gppMMGDCAy0Y09qP0dnjoshDD8QQGLW+Rw11SJVnvXTRgFRUux1lVWvvSrC26rdpBATzodPp2FeGuSl+8yrDqAdup1JqddtGgdfOy1YTF2rTEPvJ3QM1WORjov95jURtJH8+aSFVyivXShK3H7b1hoKHw+wUYe3n1xEJagP3KqMEZfFwfPdAZ3UONHwuHluRARz0bzvkaCEWAeYeuvl9qZviy8waTp95fwbCZD5KUXymcXESIwjgAX8wZCz3ueg4RoMOw+HVDMpDDhYMMpx5mILNJVQmZAjXLLbA3QupIZAcWOExTJeaOGahQvEjmgg0g+DsUJqkZHMkJBvT+xnyf624Jd/xwBGPz7prlWEK+9boKjSaPuCVe6yJejVBHS76eLfmqKfugtDCc+TQC1c6QzyJv6v2pyq3UD6jXI/X0SD17pFIXi2Pdj5ypfuST1a9chb+g34vjs09SR/8PHrpnqCfxFEFCFRbQCq3RQRqCOnmB2vXLIOkkvIiRjC3gByHpS8CiWx5+65KQubED9NPn1EWlmqTaN57wIh6K/mXwGSiUJjPHZ5+Iy50YQDVJQzLloF2yUohcBttJIjJjzF1Bcqlxfw+n5pabWyqfUq7nppXaRTrDmqmUcK0LwDmNkddlB276AtaunlN7fyRauV0NEVsjrVK6uWqKsK7AMW0RXoL+KC1yS4J2lwTtjFW4HoJdp5m4pazPmbIu+QieK3F92EQdu0pHa0iA114A1WyorGVWU9iTnXpURKVy3S/YhByfX5TST6sJksWA3RI5MmGBw1EfCTTpP+gNPcd+kkpKxQvoNgSk9Z7RUCjLuBwdSF2pWlLW9gQ6S6iarYezMZfcsBCeDoxkz8kJwAWNPFCrXof8VjAkpzsvm+XvoCUW2yAWCUxtRuKquNfniv93ULjajB5Q0oQEAa9ZjFqA2RVX0iL3ZyX1WPhsnQJOS56eHnlafLXPlUI9jlSCmyNGNWQRR9DpEPwEAhYOo4kXulh3a14qmUCHnuogc/aVSCMn58e/k3PZsJRk6QoZqQIZqZ6lhWwug8sAfMCxdKh6xgRfE1C/KRXfpM+bdlfDzNAKTRYSmwXlyXDjcjU9FWoy1ISpnnxQdCJrT1ZatMzUJZscUWmrd9GCf6GuyRDfI1PqgyTMXOnBcvoWjvTL5w+bXDmgBCvVKqCYoY1iYOH7+YV/CWgcTXjo/Yn5OR90ea/yy3vPw2vPdVnw0Gs7zK8N8SjUIxvxOHjgwzsqepSngG4DqpjOUNYGeMh1ronMpbBDQ3K3zooiNoJfXtJJkQlTYCRPKWQGwXrEQrUFUlGPRJBjiMxToSMo0oSXgXRNgr9wEFyjF4y7BFep/a7zVKULHnCXgZ4Mg4xUXyJ4HDpIVoAmedrmRMPIo74cmL0hI4/5riBc+WOjdekK+fgr8o2xGUzshZdBUigKzwEnJldqjiukbiyEjLwzOCz8mby4gkCfK+L4jIbiMgA2V/V42SfnLHAJhY3Mojm5wv1coSAGzXMbvgxUpCJuCEU/KU0a8qriON2u+umGhclxeYJEoTceQ9HTyyDlHS9jM6+UIHklj0SeVsTHY5/9TRWQQdCe0jks5d8x+BBG5JpCNSwegKu8YeqLyb9cD3NxA59ZFIeBIIeDV8Szopd4EvjpCeJzR3EMFyFM+H/IOR2xaL4ZXmELDoeLGAGL2xvKJ9o4cWQhRyPH2ijpWA9Dc0N9z1VIQ+JzeBIJm6NbXsM1tUzOskwO6ZWD20Ovu2WAngYDtNb6SHU5oBri9YgHFUXK81Y+bF8uUidq1/fQsJRTehdM0NMF0xbcsmvwZvkBfFOCiLjM925YOJdV1bJD9slb+Z38yjlkdIZKzFiDEuZDlkXmQrgNiMun1Au6l8E15yKyXWwky8LUKrAw0yz0bqgz75OUR0xuR7vvHlPHClh2Ua2ydRvKVsec/lDC3zoNgQuv9rkqW5+ZOVC+rPVaAsuxv9LxtwRgBwjAjlkKs9hurfbClpA9SUJW93afKy17uobDhWSrhlAzRsLQi+i4N6YRu6XzPSkxNhB08mMoqTMn9CgydEHH5FfZMq3wzdG+X5nKvrGo59ZLLeY3vaR8sXBnD4aeC7a4DK5eMMyDZTpruObyV75OkaT2a1g7Oi/Y8pZwe37P5QiehvRP8k4WV5R/6KSg+MexO/WC2igfuuy6hJK/lr5BrgvllXgh/lbSSj0Urox2jbG4Li32eBH55k08DTFOPc6/5oW1JOa5kJimD6KlMssTlh2XIZYiLNIevECmmBwMZ6EHqYaa58GYHPTSfUsNKL9dXJztHZCzVOtSJVpxa3jSIfeFyl3kshD84GQOUCoECB8gUCstG3NB02U5uafCiYtn4DcsDDFLtp1uT41BZpnGsILuZeBN0SdDua9AQDL82w575iPQBJIZAPxD69DqCDmVl9UqoLahgMpB5WaCq+rd9HNVRu2gYWWjwbc5dL5mK0s9cqFUpC3F2BGKsWNWlzxmXKfZpSV9z4H0Nbrs50r9nnCWiUaEroZdxpvSMfrBen8CcaovQGHHnu5YKj2dQjNyEdJAGGN8uQuCMcNUdku76zsOm4GzAWJNSRWv+Gh01SVXPMD/zhj8PzrE+6AfjK4emjDVEWXkEXxWB9wi8m0i8jRUbEaAWXC/zxV376DksknbehqNrllqqYGjFT/RDE2fPxM0vWPyQwYrrVN4aInN0yU29a74udKbp+u2VZ+01JATAuaXCgcB81OyQU4I+PjuQyktec8iZ6KUUB9lklSCee3JBz4ewwt98fHdh5eFRAXGpTJcV+u+QA8WshkPI51yVcY6qfps2voIRdkCd8a9IJLhpXp4q2iclQcCJoULQ+o0CznOLySx0mULsu31E1Bezfr+ZVcSBz58w12/+wBjurETFdSua04DM5FfuXKH2uVhOVoJly1PUUenNhVurNfQIJOFXfcgYL6pFoEIybw2GNtcyIvMqevredmxyhVqegTIJaEx//pq4/CkGqWS7T317DuZoo+dwQBrKmJZRaip+GYw+GdqNl3OQhZmsamTrNrXxc1ZdQ7Te9Nv8wW8xj39EtewMfkESvd1MDjAcpH7Rxf7gzevyveld5HZVu3KEtbzgoNQ7yQfqFsQ23ocRxN4i452LVDPu9HTiu0A2dTx/w7kAfMBEC/AMGAo4mbNWHj43zuQ1qzzZn8weG3uofOmA137AY+G1nT3pTcFcfrWmarHs8yhpuIya0TkngYihvrEUIFH1oWTRLLZqY5M8pLCI83LbdZUC451f5A71mS2Bz7RdYbi2sfpqSFkAZf0mb6lEYWkB/BO45mIQkanmrdb9EJTR5mZ5EGPck1cImDQpbKklMvdKd6HSU+e5DLAtaeS+7E9FptyP4pPLWciwCTIDMmwS4mleR5ja9Q5MgwzVcpJpeyLkjApburRsSurCPk2UCq2Y6g4ZQsiVaW3j+8+2ABYyhPcd9VP+aFU+biFIyUVgFeius2qjMm37JL18Hc6I0iOBcqkDLGEdX/+fPifQsIiuZJmKUjSdAVHGKouQ6n5sC/gsxr7RLboXcxnKKxA7ovc6AuozX6a2hRM3ZTmdM0wRlVhVq5P5z/OP33UR9N8eTDuEHs3X9tUcjtDM2ueEcJPOsFRkL3J+stNT/XgfGXLrD8ssw7HAKhTMwYArRpjbY6PB+RqraJ6ES2L37L4D8TiKz1wtf6TT6Joph3Y5Y37LGJ5gSDVsKeYwpRQoPnBT+DEY2IEChjh6YzDc/HnWqUlyKdr37vxeCyd+kxQRZq3N4KBFghEfG2Gxgx+1PcLgp4WJKhL7Qy56V7tNLapvaKNxWjp7LV34UnDV+qDFsBs3G1YGNULqBN5NxnueCFDKC8P+BkzwPKcXPq44BWqkXpNmLkIbKs+Mro6ERoPpdIvEWXWZrPJr9nYbmqQH5ApNcuieUJDMNU9e8IkdoPVRz6DxB3b30Ah3gYjoMtmLHBZ4MzXbhGrf7pFZrz3Kt3gUjbZ9ZxZ0bJ248zWVWE4hZLXkkbumkW0wlSX2l9f8kOqCH2puU6RHmzBQ7TxIcKXNFa5YSA8eoIY6mQRkXLagYOKKLP8+26x4S9N68ArMLWBtBEwPWuqYS6/O6ZexaSuEYQR8lGW8CXdd5/2AVos27zaYPYOGpC6FQldGZnrtjS0paEtDW1p6FZoaHUu+g2QUOmlUkzqCrNZpEmdnCRt6glqCHXvgoUUmLzTiedpoMWgnrbhSJwlAG0p4RC9S0JFMXHUg8EAqUosCEj9f0sy2UvDkZlu5IUiwgrE2QH2d5KO5mVILSUWmrh2goyun9IdFGlT80fznI6kJf4t8W+J/6Ml/tsXoJ2QUSVA5xmAajVw6I29AAI9p/RuKFXvC3K1O9SZZGLn5CgQVD6lsAQcpTSE7hO2Jr8dkN/pHTmXrfXx5ViM4tbG71WK1VN6R4J4ei29LBxuysco7CNkkc98yc7AxQzAXiClczpl0DtgDrIFt1D1BZy84wAfazCW+YJlDDuuS1pEurqmiv41noGjiSBe1CcfORbsoRE0knmDZSuXM4kUVXPY5DT2I2/mszssenN0d6edVKZ0Dt4v/BpndLuyso4T+zT05+ToYCCg1I/gMKCazo6Dl5ZYT5Cr/cHgSvrd+D6Z+TQgYJsWhN1BRAt5l/iY3k4YuO5GsttVH/5DpowG6jgzy4Vmtn5783Eu6ae4ZFxi8QNbImLE5jUK4Wp4NCjbke6b3VLpOPXZjlojGhOWDsKpDPWrd2QNUL99dO+0gbDJObnxdDqXZr90wMlSZ7TzQR6FQYXqR/vfK4SEPIpow0LCs2LQYYa+qdDD+iROhSe1VK6lcluicjsT1lmL1KwzzLOl3Y1od+WptWR7W2R7O4GaKrSrTlYX6f/0oIS5Rsimev3w9EFGHt6wUCxMklkurcLCUNZW4yySVwFWUBvwd9l+ES037VU700/obAMTbzwB1Ri2UqvIUW8aRVCxFFTUMVAroMwWeYXIBy9BeSp61Bok4mRKv5kMSwmrwNPDvDAlaf6lVP+qR8TVCXx9Accl3uztueyG+XDYop+U5+g7fCohcm/Cb3sR35PKCzzkg17E1cHvvewWl7R5KaM4crT8snNw2WlOyy87+5edHaHQDeTQ3DNbkZplwWV4sCQdKxgojanXkSchM/UyCRMqhtjJfNZlaG2duXnqvq2W9rci+3ZE9iz13aTQXovSp3njlti3xP6JiuM5Or4BgbxlYlomZq1MzILn1fIvT0t38ajYk/qqi8gXUDt+5nuQWnw45a4KtS+JvSpibWRbzdpEvuglI/ZwxEL25i120wB08eGcnJhu5HfoVprTQXUFtFKjeyb+KWRTmV+dBnM7W1WyaPhVRCHF1FXHo4iFBPfo8aCbzstgcrqzCb3xgEUAuGaCvAi4PeDI8yMWYristFd8Y/Meu5NMIaH+GNINT6bE90QE1pFIF+KVh/pyR/iIRSS3/pU+XN7DJ0oKFxyNycLQaGem271M3FDkTefl0onAIFb+Q2tbIgp1nrxMQkezs04VYoItp7JGNLsnq2cWo3yg2lE3suUZuCDdrWgfUnqAgCEasR70t68MPEkPda6yozcHkNOiv3/w6vAIMltAxK99ACArfwr8eXnSywznglBvrghvCOgqOCwmYmAREK6NB1oC3tfuffcwXEuyZcN57Db7UESWa0TAlcWlLbBk1GYCLFVgIw6gqo+h3irAjUWAmaBpMdVN6SvA3B9LUT4gDHwXfU9MdDkWGMTyU1BEGg7jB2FpRFiiPaCSpvMRgYNNcRl4KuSFcpnw5+Rq5M3ElczPPPtjcvWyT35Xdn7VGFbo8Om1F4CztdwfphgQakUSBXuhzAoRoU92irsAb4WAgEpnLlf2gock4CSMfWZxQy+Vv0GajUn4Itwa8jq74nLQwKDRMiYtY9IyJmtkTKyMKJnVK9wn8WYG86Evk0EpFWLRuhH0icG4ygEskzRfouEX70/Pznt0BuW4AHHH4Q0TLxPsTF7MuIh6f8Q0iOIpmcyvQ8992SfvY0y+o7A764/75MoJBD24eqmdyajrMvdvxPEhjZAgYsJjH+JoGI1IHHwL+G1gFgTx5fSPGAK14W7FJmjC34hgvmwNKQq5yIwAuZKRYlAM7gBIZm6WkDg+o6Gc3pKfk7dJwxDj9QpAzIvYVGtVP7BgHE06b346rAGd99aj/lcH7g0wzB8TYMqm9O5Ujnsw6HbiwPsjZuqHUm5aPuMsV61/3zJ33ZRitaz142CtVzUe1mau0yrqRvy1qi6d4Z9zKDwdV3t2fHHymy5VCKwvZIyEDKc+lWUL0WUYOwLG6MrwOzJl4ZiR//3v/8HvdkY+QDyIFRPMhksAoTNgt2oUwMigy5Mjw5izkKESzQvAGCeR1hSweJ+8uODqD0IJpFRTeJSMQj6FgGB25wmdszUpo92VPsuwAp0VE5Ee2EN5HIG/8UtykV3+NIZ/ma3DsZCr75cSnVx23pB/XSLSuux0ySXgrcvO1/urYgKVIPusmPA3XPYiRLx5uqTjQfE4LXqqCYY0HlNyeHeX4rJ3QHjYcQNpEc+5CSNpKxi1glErGLWCUSsYtYLRDgtGSxCtVjZ6HLKR9FwoyRBUJBop6aKxbPRZSSXLCEe6L0A0kNKwvpCUxDEiasBS7y7DVORZ4adPzr5clElTedmpVALKCVUpeaiVWVqZ5ZHJLA1AtxVaWqGlFVpaoaUVWlqh5YGFlmWoViu1PA6pRZoEFnhch0B4SgLDb9l1jwbUn0eeIx2pwnjakzlGc/5Sn7/8rtOPJsXqinJ8hx67YaK4/XaY2DCeLuGq8zmeknNc8NoePiwEj9SLWPLkpf3nQTIawoK2BH7/YNfkWD+u1SNEdxyEAcyWNr6m4TDi47HPenLEBAYv8GcEKx7s8dGoCgxlY5FrbRkaHxoc1yNILpo3OcyemrJ22UPAB7K7u+gMW2TxYMjiceOFGiFTYsaYO7wGTriUkKOKMuURjb162KvUA9oSiM6hOfkFZagy/aPdxodobngyNPIgatoUlhUzBknKoLZHQNQrJLcTz5kQhwYgt8xCNmKRMwGoCuEvn1MXMpxN6TeUStk1QMBlENAbbywrnIyoiFgIyctVtDYICCXLd7kTQ55Y1bMo5rpxKdvl8J68ueV8hqvv5uEUTHJPy+iV8j03rU4qkvTqRfHKtSZR/kMLCNMxruvyuKt532sXzeTGHkvQbTFL+PRyg1jYe0WXvqwz3yK6oIycLWl4GNKwVetKOdLVpVy9pN4ED1PZPrNaNaPghvPjo5Esu7mKi1hLAJ8NAayFdJ49DXy6uSZqkrs6wpLwoZY3B2zuoF2tVGYSwu+5LGJOxMOe6YNaV1XxMOS+X1jx8Fi3JufnH/ZAp540tnWeAL5j74YFxUqaU2lRFHMRsamFa7vKeUI9d0yI5QWOH7vgf34XDeHhurHP3KFwaAC5JZTjhbZgQSvL4KdcQHwfiCx0QSuPcixXdi0h/L3IhzU44VwWg0LvBE8QWZDKg0sl8WwcAk0m13Nr8X2S24smFt2iJcvFgMeIpPpppxG1b/RG2Z7Tw5KCWv4tvMu9hSWTPal60m7Z8tMJeVQenuT1q6sKh+pZWXi7qwqWrTy0vuWlE/+k0a5UdmHlsGpxqc6pbzwF0loyH22L7uRObB1JG8/PPyAeOQEuagTHypIehR+frOAmhN9PqIgGkOWltyryhF3KCNQZfKwHIDysIk/g/2ImzlMp6TyB9IUF7oyr8PyJJ8OTdC6CAk9A6YICstplByYAnz54KKZyvBo5080kNzCdnVhEfLrVfIcPYsiQM6u/hvLB1JWj6j+HJanUmihJnkhtnJA0gJSWlKyRlFRQjeUpQ/eRST7N6YWG+yr5B4tiGm2WGGJmXHAKRA+TBQXtUgakzEg9NZLyeC9Pq3M6pWNGLtK9ybHsrdyQyn3cf2euRxf2DhnonRzI55tpCSTNgxUIfGHg5c5l0R4QdkIejyeXQSqXXsCiWx5+A4JisgTLPcoKQBigC6pLdJMkLp9Cip+0vvEyKN41LOHvuITsl93XRNaRfRrddauy24bKbgEC2Izxarl38Fz1eI/RvWkBNVizkWoZ2qN0yC35eRrkZ2fCjOqh1XVmRWipaktVV3oKz5WwPl0aWsPylX2izsGMriDuQfeGMt7JwdlxKWXFjy9OOPU9Q3NOlA/IGQRHBRiQAiTrOI4mQA4cL5q/JMIbB5g23XUFQdMUH4d0NvEcMmURdWlEL4OIa7I7CzkAXEJvbaty4bq7UqEJc9ywUOojVMQTjnkZUGtBuMKZWfBDk8nlpTT7tloi8hBEBEBsm/JY4Y0/V1rxFIQwRPGblbxKyUAlg9JSglZgKkJ2m5eSWqr2NKla80t/roTtidGwZSQfzKC6iuwjB8hKPdlnl8rUWhQIHYeByR4rMytUDmHFc3aVv5/258usEMgcxCV2iZIhlcpQSD8KCQ+KWuqdgieGST1rMOMjEF+qz6zF8Q+B4/EKNiO71Lvu54rdn4TYotHrRgWXPA5XPEQzNC4zkgsCp67NJCOP+a4wCaGaIvf+ZfBJpdBRI4FE4rMR5O2R2zEZ8tRrp/4tnYPhKaEpmJZPFfFBNyV2GfARFguOJiFjRMTX5pQeGs/vunAi8dk6xZOWaj0bqtXoxp8r4XpyNKqGYPInDemfewvEERBAcISeGkDjzh52LxNG/gkfF9CuXyESFwJuRWF7mySR08gKwr3x2C1G4MaYFw/rx6WqUmDULrthIYI15pWFFIOqRkWfnDMnZFDMPvTg+IVORGeH/aiIpi0VcsPDXFICKTq7tSdbkQu077xnYapKlrlqfWvHN3Kd28I3MFk5nsF9vwNA7Ko/VFyK/OPYnXqB7L0GPAFD9uvzrkWZpGdxY1hXFXHqgLtmVReA+oOC2+ZjJQrgCKJHasdLlB/4zsB8jSU+M7B/EEivlX5R8gCqYPvSTIDun+UCdCH42txARYedwRH1SbLezW6Cad11PjNY3TSJTmClmkbXAFt2B4mdl4Za1d0G2nf4Uy14lU1FWtGTcOTVEAyF4zIs+NPhtycMQqVwDOU40HvriRkXnhzku5WknEYRdSbg6/w3MvJ8Blv9/+T1HAwOXvX293v7g97Bq95g0Eco6+Y1LirJDYLM5hAKqPZaTn9n0IgB3pWxyMQTEQ/nS6MR3d/GI5gTX+5dfvYc6ucehsNDV+SrAUC2dkJVxznosavRihpoFxiErpmIj0aCRXqeP2KGJ5Te6afQ9QLqkyCeXstoCRHRMMJU89q0KjWKAmPW++StotQm1nzQL8IIkNh+jNGaUy/wphCVOrDTyA+shfre1Fuwzt/pHQxC6JTHAdY60KuKOC62YGH7tVe2b69s316a4GH0HkwQ1csDUwRaKvAEgX5dz5MVeULrfYY0KlxTLkkYvo9YsFC+FHu2bseRlVeHFA4tGRlDeRO8bn3IbOhTKONoKzZ0zkO8fw5NUzt5++78pN4eoGWn2zk+P8msDD/UI3YNoHizXK1CBbXY2iaLbknSOklSQghKaRIgi6XVT0WE5jOD39iiC7+ek9O3BT4w2DkhNtizmtjgSLtAataor8qk/XqrTcdF+8dAQDw2y0aWYPUEkUOlnRSWr13Hqv6N7ows3WjRzwvrPAyiaaD8UqMpQ1h5Dop6lrBCLJXIRmVPQ8i38UK8LFaM1WeHk5F2AUslvI+HrH4F13PCp1NKBIN1mkryfFSIhU7fYhGU8mVm6jGZ4ksZhHWfKq4kcRb856ev8PvMxwSNI+oLGDyaIwMFZtiaDFSTe98KLmvCSDVa/PPCaVvipPoaJa1Bylc4A84dSroVcF9Q6K0Kv+kRUsnc5G/qnWjTfLXiUPfROsOKvruAwfJ81pJ8VREes1oUZq02UtsJdpOZ63SCOwYQwUIH/a+db0oH2NyKCAkeRj6/fTi3L3nsy7h95Xs+rNvXwhucUEGuGQssIp7M788beX2Ziavcv6qv+ukjbgs910jcBl3eaEz3dV0+XIjUE/xZisylbqkWPtc3uTS7agYoZlStzwXsaOY17Qqars+PrYbz6nJdepaG/NYzhNKtslfW296In1QhaBXi4QVOUjsHYCk+KKO0Ziphu1k0rAuK9c58LH0MOd9fXIWM+pD5/QocOK8U13f1sousDY8j8h/nnz6SP2IesUIRz3r+MOIeDp62qeopOs12m7m7B2ClNoJWnjv937Qyqg4yqdRGTWkYDcUE7VylxSCgUU82kvXztJN7lnqfQ0tyji0TV/iyMrjFzbeDY3BPcktLkPLChS+bI/o8kRlMmI6WXOD5JdLIv77a3L5Mawz1IcIb2Slb9BsuL93K1JHHMkT36C7iRxNnwpxvEAQSw5IHMMvY4wH1h5HHQih2A6OUzlHcOjeXfGwhjzH1Rdlg6VYlg9RaVkHTbmfKXcwWOMSLPBgcHPUGr3v7g4uDgzdHr94cHPRfH/40eP3zP+2pA5ltWl+UrG5+X6DyWy3+yHqTS0UhlfRPngwN5p9GCFLp9QLSy2opzae0OhOaZlx/vma3m3uZC07HXF6V1KxzGEBKfdVhscR8L59Cdlww2nuutjSdwHLJZ7lcPU+1RiS9w/tuWd2wc5WcUsaBSN0J5k6Xrgp8lJ68elKAgOJiYvcVELvbZ/9ZLZtc4LLVcdS6g+Id78Jd5BDdbt+BpGaf5XLrnX16h6uc+XE45ukVrHzwjwsC5N6bP/+Cvd5nyFvRxBiLpqpfJdsCTaTuWj1tNcWEagOfAn9u9r/0u7APZMGLCMofRBF7U3QqEY8SVzg+IrIfkR0JFYI7HtoFUQeuK4NVOyEc5bSpRfxIlt0p46WyfFzBzr5uQQGtzhn+yBWxrKUt7jZSKh+VKdKqOfAla5KcBjfU91xiHm2eHwcDDJhl9/df/dWsGwRdfMLgoKJSq+mM1X1yCiG7QOJwkD7yS8U8fRD7vnWFaPrN8Jl1+b9FMjAc7cEWj/Yjj8iIx4G74FgH+z8VH2uohcY8FPWRKa09QAqSGvZNQWvDvoWQ3XCMPNTvzHuqqCL04MA6eHWYOlhZUCa9roiTOPC5823hC2s0GA3HfFjxbBoNVuMJNRqvAhQajbOzz3JNqr5ivdYaagTij/a/V630tMM1nSwt4gqV/2xdpCz1V6iNrEA8eY/3MqK3C6rIzQeF2/Pb+mDzsmRRvWGjSPGnoyFtVaGtKrRVhbaq0OelCi1cTKsSbVWirUr0UatEN6eSbLWPrfZxRe3jbmoepf9MsVZoNw5zt1VvR/axprqiZ2HBuZK/49dpLDAZ4g88+AEc9n7go9EPO3Lou6ZYenYVwmtqk+o6v+2liNnQ8RnF6vSLHeJS1RJwlJ4apSdHyTrJpWWsE9UmDbz/j8eYcjQWWZkM2wNawsHJnMdhukWXXMcR/C7hZ+SFIiKuJxCdpUUschqQKReQ3VQw0SXRxFNpSK8ZoQ6AiIoSAbOnF5CDQzLhcSj6RC0Q0pWGrCe5lcxKbyceIFAYU1MlD3KFjzkwcuQ/GZtB3YWph667VK5ZjRkHLgeQd6B6kC8HMXewC2q5Os7+RRe3pAbsBK6CRayEiFXowFjgDiMhudRXkM5pcHCxf/BmMHgzGPQx5hSY1LwibGgeb4T4OTvEIDsEplmXkbRqqXk9UbdzGvRmIR+Hy6jz1rhIexmtOqu+OkvKblVLjQOARXco/x6GbDQ8uD5ifz06Ohwc0sPrkfvXn18fHLzed9jrvzqHr3/62V0opH2wBDRP1JbQZMrqzpsOkICecsq3xbb9w95gvzfYvxgcvTlIPxRgJWwtalqKKw7E06BW/y4LHvNQjXJvP+rVRjTj3BsAWHlARVMjL5LxhYU0zRbPECvLjtbOHoXQuKgqSxGeV7zisvi+rtCyf3jQxNtB3p8BIBxYVtMAyml+dzkTmImc3XnIgjsUGBGgzwEmNp+xEICLuYQW7t4i1U+JWy965a0ReFm2vV/MLJey8oA8YkRixTkEirlyRDUL+fJzTH3XcubPgDMvveplcXXL0rYsbcvStiztU2FpyxHkikztZwZAWqbDSHjaoxRPexGHUGV6lPVNmAeOMXhox3yX+axlO9evIn5EyuCmXKXVgIdj6IinIXOWqZJXaCe2+RwQgKYUHoY/l+yeyDxPsGwgZkfBCgrPKv7pmiELBcEji5XStl9tPW005K3ryW491S+XGvs3Gdxyoj8XpLDViaKYmw6FeWAGr1vcL1lRqusMEEjTPixU/eonKU6dp0GO23BxhH9XMXp1D1mveehw32cObm5RluPiXS9pUXwHW11kSRwMbLpwHEiTNuEOJnNznxbSTwNpGbpPX4JG9+lf11UGV2Wi3CjyzmKuxbmcF6sCZF6rFFJMl77F76n3nE8PKttQErDbFEbcBYl3uy7imD91aFGm2j7hBQe9bY9w6rpSTu/c3t721Yh9h0+1DWxw8IrtD45Gh8xho5+p+9qhr/bpz6/+euAOnFdHr0COUu8W6HzY218kbNd2vcfq88OJYxdhLa+rWnGWLQ5+cBz81NBtZW7AMo5177v1FzSVzxiMwwtQtmxUjrLf4vdqlK3a0JroOr3UjbOxO6cWLTjSbSPnegh47ejWc2th3KoDajFui3HXjHEVnrzv1hD67UF7Louo56fF/tSjfWsapB/4ewYOo5RIyChTAbQYtAyDFh1yy98uyd9WHmaLbh8c3T4LJUPjUPRShlU641fyq7IJbfHuY1Vv5O+4xf5LYv+Ko2xx/4Pj/qeG5tG6WZZuPYXlZTRJOZpX6a4r8bxq0yL6h051UoaRamddb1H9GlB91Vm2uL7F9WvG9ZXxgIE3m7Go3NMCjI7gSnOuG+ZcK6QbffK5QMMCFV993zQi18znwRgrbvNUZtEtmBXVGoawqVM3hfbRCSJTMrHhqGfoR2GPqZ0rVhyXhWroEr1M0SimXTKOucYEN9Xs+V6DaLdztFzHddWgQHcvvY8ywNYNjOxufliX2L4hv64EkBY4AlSB89539a8hdKk0QsnfLRAvsjrRFJSX2J2gaKpqUQLh5DOL4jCAhof/9V8JzfNGpg342etBAk5gFBbKoJxteWJVYAj7VNc7mTr8jzDwqkD+Mfb95wbgjxqgFxg+xiwqg0+IxVsAnIYCLwDOFriaUNDnBl9PioBW1ZqT3HIZvBlNRiXISU8lAbQsVvXlWuizoS+l9igGA93EKwG+FoSfFYmsI8RmuN49S39Sg66eqNbV5JU4plkxmQWIVm0ggV0L9+ukuvqOnhnkPjri20+gZBER1kFIoAmkgYtvw9ZKZcMwxpPolsF/yX/QG3qO3xLNEoZuh3FAeKDzAYK6acRDRv7Bw28sFOR///t/MFbpj9iTefxdFqoIVKlhFRi8FDLXC5mDaAk3KZMbJzglU+GR3qZWxGMoFA+qVxsdeIHr3XhuTBNtGBKzWOlxM2PCz3JPLiCIqRdgJLszSTYXhd4YRGQhc2k6lpaNCubCQXz5/IHMaARJEYVWsZYjUY0QrDXV1BzgcovUBykEGqpWJSqERE8oW+4W3lwLFpPn9Mxw2O7jLP0wlxXTM6ryPDTk1OUlsFCgM29h4SnBwuOj5wthwwSn1ZKp87ChBOsa0KErtj8G6FhRzjXA0cLZc6U5lXLvjDlRGE/3aED9eeQ5Yo+OxyEb04jtoU2/QvjVnXumS88MI/O6ygGS727SICckq8YkaUzsxsXF0EXSxu44CvkUwReT1E+9II4wF3wMfgnAz56rpRPLK0JAigEWBoxG4FE69m5YsE34N6epd1TmW0Rns9O3S1qD85PQ2ez/Z+/dm9tGsjzRr5KhiVhX9ZLUw5Zd9t7euyrZrtaMq8oj2V0z03bQSSBJog0CbCQgme3Qjf0Q95/79faT3DgnM4HEGyBBChSzoyPKAvP9+J2T5wnOPDjBVDeW7/qpN32+q4zM0h+6vlhLkgy9Oub++9f/AaFW6Ld3zJuF86NXT1uEiq06Mm1Mi9ZeO1yRxBQlHkeV6U7jgbew49lg83cTsFtdt4v4Rpfhb1xC42s6QEs5gFE89VG89nwkt6NW4J+IGuaObcMiqAC9TYCV3eJuTFYYgKoeVGMo/WE4WWHUqh8RVZMf5Oe8vDFew8mKyBKl+EmA70I5o1oQsoBfLU5wCZmtWiGQrje4pW7fANF2FszDqDydoaLWZErU6QdhZ31gY3rrkRc6bmfNi9b09uW+dtaDak/vY+q4eCi66kO1l9oFx7PWNYcq2AZsTW8fDvvYZm5Is52Un+TMCwPkZqFPOIPAMOL2cBZAnpqAcd+NVNzHcsoouBYtI81KhFz6R0SDEHNmL3wPr9cdY2gwTWGEEM8Sr/tXGrcg//G5BWnNQchD0FNhE1tHTMuHaijoVimoIGgjQdB2QzxjOteGespKWeqp2iqnnkmJeuopyjpw7/OE1Ifwz+pJgUd0yQLHtw0hNYT08RHSNYiMvGn7QGSyQzVEZhdERsLrlsjMclkRKDLeDk1UJCJGFv6U19cUCpsaERX5MHVXwnwZ5NLFkivH446tjMp2TFWER95Ytl1IV6rdF7JerDNGvGgxYQEswZLOHA8lJMKRiEPmBQjBriYIQdjVDCD+uh+AMh4y0HFGfIwbLNvAEKTxuozIFSjTLTeyRUWQF+LgBuSL6GvseFP/SxxBfgnhUb1QldWxSrLxYtg6G3+K3LezABb+tJ1XRy7durAMWtBv0Jy2RHJhgKeAqRYOyGZTim5YZycobpMjQn+uwvEJywUH02C2G2BcE/hxZWogRkgDJvanLjkoNK2P+oji3+opROWv3IJHTTJobLvpgC+SC0SmmEpu/fEuAz/0Ld9NjdnGW67GrBURIlegF2jlibHO05HPB1i56YOtHGW2SFDltYe5yH+2CINaPdjtkdR40Dumpzrwb5z7pHNiC+Rv/aihhfRRhg8t+nEIerPZkGLzQKuH4ZwN/cCZOV5RiNGis0KwDYgsShcqbDRcVdlGsS21iENa2BwqjBLn8to++kJid+UBnhmIUClqd79tNNO2e7pTHKt/EWw6CwNwKf36DrGsMiSn/h44/i6odHX4zULsk3E4i34sMm0sOkUV/pHLgN06fsT1R4FWsxyZYq6je2ASTW8/EEYzPGwYtLPw9u4AZ5ys7GHo2A1CaFYO1wDKQwFKXcTJQoQAQXQha5RiQHKS6cIjkK2Sk12JV1lpFeliomy/9XINpQoGWDRBYf0e9YyXaTlogzS9eptV+aEWY4+MxlUPP43fadLwtsEhavNqi4106zieJzzTC3q7RFy8+Nq83Q4GyPbpxdjJ6eoZ5nY7JwPJD8X8NTKtVoLfzlRMw6TFRromopevVzpVN0HiBcTj2C+N02bScm2SW4cL1dWmQvOCMRs42CmHpl+udeJtLRnDiIbH2nBkkt0ysGC2MGVKV8i+Fv8R+SFFP+TURMshQFTAW+26ZOlSjw8I5eSOuS78F+MSSMt19LLCCru5+/4EAm7S0A9Wa1x51CmHjIeppejsguiDS29KfE+qLvfb9gli1xjXbi7t70mXHV3VXjpfwR0c5e7fRtd/qfJ/V9x6ZAmWMilxhvLD8YaMvmyiCuRJiHB5VEWksntObxmZMLBMxCb24UK/k7wKzmMr9wVb1m9MEzJtbvJ+3mR1Yza/wMffo8C9P4abVBn5QtxnqSkSpYuCZgIdVrSrOuIFlpAseSzMlTddqbfj7wGbgaqIiAZsWRmsXXgIxk6WH3nolIZ2VnjThHXUw9N7zcg3cDvvCtrU+xALtZ6FrN5u3E5iHRTxocW8MKDuac60qCEK/habgNn6Rm4FdfBIGHamjSCi53g3UqCygW5L8STQ1HDucFyoHGsSQxhJiqTPzAftR/KDkkTgAH8sAbWDwqFqS1EJHuCeOUtbe7Y0OS1vKGU2eq5bjZ7vD16+085VfNrE6VInait8pLgehpc8HF6yHltrjSpZnIMd2kqB6k0ITFmMqjk0xd9BpIsHvRg+B2DGnmcJHz+o5hVgjW+VBB1/8ndmwaovA9g1Ja2TmLVNlGueVE0RXJnXdFfQVq/6MrD2WLjDGlPKslfx8Xf4j7KsrBFx56BPhNNNGEqZXahcqC09dSI3zBg6QfUDgDstqoFY9sb9rMVivc/sjAGePgHPI+an0BCqBRQFzLObStuHonTuXWtBTOA7NiG3Tkjd2NtflS6Sv4vY3uXVRKgADBGQ4dsO7s1b/JbcvB/ZbsrZkd06FvsAgNd5d6LtMaJpyvcemPTuu8NYHCFdLFOdiQO54aO8uOnwn9mWM6KdOcPzLFIzCUEyzh1V03Dk43aRTW1MkHT/y4sFCxyLHl/OHYvO/KP6WA0ZX1CCwcOHnMH1AkmqkkHFt9NXzsKa/y/6I7cYc8pllAVTP1hQz2I3gAiDMJxOBlNrOeDOwLWWgzB0BuEkHFgub0d9AUe2Qt2wZSMDfuzEtorMCtpWQ2hhs+zIZYLWtlKDDVXdInWY+s2ukH1oieTi0poYxFDRXklkjQarr+jVc6DSYGIz9RW6YimkqJc3aP1WSRxSZTXoOVSh677g0fvcRm/l7qvGjfzi8bNUTZBKeXHV64IqoEoGJWjCJCURMQyT9JCgBEeCh9TxXMb5MGRBQOFNmPjhxScPOo4wVBDuIXX1J+4UFVqetap/icdF46d46gCASRiOHB+8f7x582/v/hMPBdwTZRL++uJKfl1SxxZfR2utl+p8nMxgszXpE8hnbqzhPA+H86xUjXFXxLX9J76HizFfFhhaoF7GpHIyt0b6Wwr/L8Tv5DL1e45LxezpePMZCrjmPg9h2Hwgvjozj4ZwBqk78wMnnC8GKKmDH9m3pSMdE9GBUWKINqLdkI3Q5foy8CH17GE8ka05vFbr/yeRZ7tsLE7ChjNIt3U/ONI3fbOm9ZaaWxQUHK7uQar5yMfyMoybgGrV2Ndylqs+BywI/IBvONcF4xxlcfeDo/jf3TXJI8tCHM2u1R9zhiEz4VpfvL8iFjqMUAh7izWmkatFQpz4vsuop8u1FTBj0EP8Y0pdzj6LU4Y8UX4BZXEvct3PgyP4D0JxHLo1ubF/i4c+UAutLdCg5lc5gs8dUrki1C0Nmotje0V+jUJI3/nh3Y1eLXnk1JXDZ8/g6ObmHSJzYRuFP6beS5AMlGNk7ut4eb/H4Sr/hXP3VYDl73tLkLk7UqR0A2qs48qSWl/LvbB0cowlhY449zmvKtax570skmH9/CCVdWogVFBw/6gVOrcpMkuwm/4R2y2F/K0KaNtZhN1EFp1b6DVC65bbSPOQhlFFXPf0qK6k0jF3gNCcCRIYYnPAvnl+SP4ewZkR5wWOenXYWuq6elRd102H07XZ0vVzj8qykd6gVHMlYgBjzQV4CjPv1gl8D/+tAlgUnuTcMOWweAjnYSborB0Jw+lWoXHza/eQrAtMOOZb2vj/l0/DcDG75mIwNHj9KqLOKT++Dz4Y/uQjeKv7IR8szIakQWA+Uh1jHESHAHT5OKXSWx8lgXdOOHc8DV2ViUMFyqb7UIBaAZ3ZWORN2z87uR8chbAs48o1iyNzx1FIYFp+BNYkK8IZDay5HuS9us+TpNfY/TovM0v2CYsKp2NlBQLEL4hNTDkLq5fx5EQ9uNKsMA0CTN/khGyx6RXJgg2aymgcds856jyrVJqr1TDA7qiI+VzHj7mIET7+niNcNRFx8xyyNO6g9i2YOtkpZnlBPTpjQY6BLjL+uJANpMjgr6KBHGlswF3b0sXaI2poObaknL8uWJZd8NoF3W49pFxrWVvD8Lut9nPnDJs4HWN1NCoYuHrN7UYTNqzdQwioqmaRvnOPnpK2pZYD8W9mO+Fjopw1xkR5uocJ0KvoGpgWrUG3ZmiRZEjVLkhV0Rb1SHbQLLizIS29Ii05x4PMTcYHLUr2HHhHx8urdV0mbND1Y1E49wMJtV3p3FSbw7OMSrJgMS/gQZsRpspHM2ZvE5C1g9dvRuE5OLJcP7KnLg3YeBJQzwbZ4oZdFrR4PziyrVvkI2d4l8YBs/zALliq15d/xUhMMxVpHcuhMMj2F9TxyC11HTtO77GFRUs6kMM8wjNL7d89dxUTXii/aU/YhjhAzqZa8koaA7fDAVKbOgCbdShbRBQRUvzN2hONDM+hQbGrGzUHTYil1fYzgeTMqcseLSJKivDpSVDAgFnMuWWYHS8ru48RgfxwefFj1dlMI5WE4yI4zJ14MaxqPcbNm+u/vr24ekdc3/8KAbOjJbm8uBDmjMvlSJYcWf4CeTwa2U6YVjGnofU+vYad2HTk20t3UooPOlP+RF8ZWWN3mKAG7ISrsU1XnfQQt5V9TCFTGAqfTIE8GZoTX8LPRr5p5JspQ2oaWvMmj7SAoSvqMDnrmOhifWHltWiQ/DW5pX5AZLz/rkWYcvQ6JEAZ2yYJR0IURyLAsEraSQhaCPvBQmTV9T13RWiqdbWc0lA897RA9xYNOMC11x6DekZcVfNM7av14o644sYGhwUXCc5cv6XGnYiLO525eeObN75545s3vnnjmze+eeObN7554+/PG99oXkXsKphPC5slP7BZcFTqWpcXAmCFDd78v0P9zh/3OKo1zZMe/2t1x2zwrtjJjrmvDviN+EkrAtjtkmTuhAJliE9+NNnBDEoO3+emko014GI/BRmbTNTILYzcwsgtjNzCyC2M3MLILYzcwsgtjNxiz+QWrcMOHGN+xaPmwQeKTMyH2Eg+G3SO0/53Va5RGIIcJyi66akIYi27brEgD2/ejSvbKLBNk2mYh1QfAtykF1C9rjecr4CLe+Pde0jWbyOx62tlQuHuMXBLiwXzBPNUSmug6BCO38K3IXKhXmkY/5hpLJWi7ubdMcQtus4WKY6ajNcxV4cFTzhJdyINz2BOu6E9FrXmbA0SU7wA3VMXMb5USEchmRs6dhXtqBnfWmSj5TiLQ0/abBkwOO/JRnUAO2q6v/o2yx7KjSMQm1BciFXpm1prp5sO9Kq2HQAmfoLnTykLyJxy8fq38aNYOGaD/G5Kb30M1HERhf6Cho6lQKUcESPPuWUBp+4xl5taiopxUYDAoSouLIaH0OiwpITMwphCyI+qKAwxOVCv46J5Xq+kioDE/9oZJHbOjlcvxc45cs7dcbyRY7WJjTjyhjMxTHn/mHLmAcRtypPLVkDSuV98eS22GD69ivbFeDGKqcjabir1ZAZEZSW0JkVj3thOGdXIEZj3MJi9JTHdGJ1sMKR4N46a2gFUbM4+kbwm0zD0ztC7Q6B3j1fz0Y6+VZts3rJArFuNBGqoFxzmPhQ9qmBv/qoVqnxO5QpfeVO/16ROz1gTBo0j814tFsx2aMjcFcGKuam3RJum0XfLtuNB6Jt+eNrG362dyFoULg3IW40JmrpzWaQeaNQ03vS/QfRamx29enFy8nSQmEUc/eaTwI9CFker/Xh9hZl3Fo73jnmzcI5BubdAlpOxfe6s/e3RaKTI8UpL+pyz5mhDJLdABrMH2+Qu2CFRTV3KdTU6eiPl8VpLnpo5ooovS/iasyvQQiTEltGZlybsW04frbkx/6rqFbwgoK5mPiS6kMQ4H6nggry/+HD5FxUom9w5rhv/QT3iKIqnt2nNmfWV+B6GitbaFPmNAkyNhNc9wnANtopZQK6m6TAIcnAOmsDeOjazRe4krQgOaMKSgUAohTBkiyU0DCdvJozZRFu9jIsg+osiVCQ9qlAIXVrKDZ+2e/E3uyQPwyFl59aWTVpngkY20D/ZQJcGxM934jQ0ttnU8Rx5QPdKEvHIWbD9kXE0ZccqpBvRRLvK5VHyUYivF1ZR8nM/FEXCFxYI6UJFEce5NJR5AtiRlN6NWGPiuC7OBE7y+lHic3ON6cauyUV6QutQh/IWGuOythDjeheVdIfy6zC1FxtSotZio3Wfu9Wh9ctPieIuuuKi0ku6o0y6+QtfRiJ+dlwXnhatxNETUanvEI1gO9KvwCYB2/MQXATKeQlz/qiViZghZxdHAE7BL5Gt7gcMl053LRxuPlJcgxTctXA8rh/0QcPCIP67DUOnUKLncrWWKKEsMQpDheQRQeZ0r2bTLrFQAzZNFqR5kBgQ5iDtXbpUBfUc+l5PQGP7QpgM56Jvwe1ZY3lL2Ub0Gbtqx3zQ0LUOVg0eK4ejHAwHR8uoEXoJuXYNeslYxfXoJQoWcDjcoFcX6FW2EX1Gr9oxG/Qy6CWKCzCql6PxbgRpfBuSNHIN7wpwPkFFJURuGLr+jFj+LQsgXTj5yIVvG1ydyKUB+VI52S8EoI84Hg8ZrdAK9umJaCR1RlJnJHWPTFLnzDw/iAt0KpIbTiL3awdcK98Z23oQMG/YYsMW7wX47Z4t3goYSlgTYFjEBItlLed94XeBirJEAYMLZcg08BeSgR267JaBpRz3o8BiBfEYFv4tsLuum6rLl8wC3XhRI7uBL9XbMKSzmePNxqpxNE0rqpmMKV/ZmY4XaBFZwOI+y9/fD7AUCS/lrmT2eJv84PlE3tgfR0DUnp2e5eu/B9d4z0bzFLzqzB5hsiU1sMSpfeHbAMs2kBJLEBVlZEjefKAzZOv8iaBHnRmH5RaoDjKquTw8OlsLJbHGYM/3Z7BFYFyPvdfqIH0Q3cSgWomHsYl6MSDKnxER8d+lkoIJy8akSUEjjHKE0KGWo4nqVgaISHdSps9N0FDElkhHPxNYFoeOqYdBEZaG6xX7joGxZ5AopHWq/IMyoDZn5Oo1RMsIdSQKffQRElF55OxH3Q1ZH17hsGVUxZqBQ6ns0DscJS5sekj6YClSgrGGCrWrLYzyiFYFFj9hw+GRIYYujlu+h6XvOtYqni1K09fFoMLxtwieF18Lwfsmp6dzs+Xc2OG/zE42p2U29NqRPzwFKCFXezJ6Q7/06EY54lUo9EiIF88Qr5v2xEtokDkIMCIp62hKxcg1W7rUkg8A9s3hITqqqOpZtH1okrch2799kUduBJyFgGAQWgF7F/PBbWgsAYnPRG/A9qDfPLnteHgMLqEgPRypoRZKEVpMMAoFQyBM01xgji3fmzqYKKL4aYTCN81/U5QfQmDnFLEBi1WCpVNuk1g6CuKofkVmrnBn//WPD+X1CDroSO4WSpeE8KyBdDhPfO4w1x4vwR29ARXQq7BAVivhdIuaisvpLcHayXXkQ6UcSxCicTuoYnescXInQC0XssCj7mvfKtD1vWM0AMgMGKETyKz9rze//0b+YBPyAXaOa652sLxR4B69OpqH4ZK/Oj62gdDA6eCjJDEIpB7QxnSsLuTx3+/0zOjHRx3JiXGcukeg+HCpn5cqJyg/8kJUc/5CQ3aHIRIKvio3J5lLIl0+/1Gzhd3cFAIXU67UKHv9RrkLVQoNeEPvN7gjMbf0uczGtQwcpHFZgV0rrYGIUoaUViJEDhgy/FnxlVJFnPS1kna6EhhLuKrGlzTVmrntD37bC650zy5uVe6HEvJ9/F38V0VsKFX7lFzYciVQ6wubGD1VX1jQDaVv7AaXTBoHmEtmLlnDS6apCaZ+MAN2G5/w4gwFCxrLix1O4kskVXeCZa2+GOq9KsKKOPBuAmMviDU9JUHkMj5I2oV/B3hhIPMUiHWlmDeR8XLCQxGoZMoCBk9dJxyVazRKLnqRfqP1Fb/GaCe1V3yyIlevN77amKfG3Ot+3OtHyirHIXU35ZRbPShjki047OIgS2UXGQ1XckGUWl9lZdDme67IgscjkN/AUxvGyDHiUeU135TbxqBRHfHaWlsGLB4cLPrPBJQH42jAZx9bAUPqTF2RCXKP0EMbegmS5HFEm20ZimAaTX31n3ACE8GXxFe2IpyF5G7uuAx0RP4d6If8hROGKbyJVUdf2YpLkwI4SDz0QcN9S92I8RH5XVaEdgWbBPbzhAbAdYElmt0hNOkrtjFMSeu9gr0woGVAC0BrlL5tNQBWphhucPlj/UFy/aUatx0CxLrfJhAwIjerxQLshCxxxxcRPJE8y41s1OA5ARZd0JAFDnU3vcel983cZHOTe3KTqzwac8wIig+aq+yweFONnWi7RFFXWDglfB+QOyeck6njAsOCP6UWZECoJf4LIf7YgFy9FiFUIT7fZiq9WD/XTq2nqigFLC529tVUYZx3wyC4pVwKEZwVYsQK+0KucDRzKlLmd+uE7NZBKHLiHArCKU/kIo/c0Fm67Oo1f/Nt6fq2cIlA9gluzfTk5fOnzH42nD6lp8Nn5y9fDn+iz0+HL9n58/OfrJ+en7OTo8HRU0rt588nk+HJ+Ut7+Gzy1B7+9IKdDi17+sx+dvJ8CgYcn0Xn2ItygNAMHosWsZlNgDZNqiKIJi2rNBSbNq3a0duus8lMbTueebHdV69bGFcW7mJi1hq59Za4OxgHXM32g3A43mlIrfdF0vYva40Iu8+OB//54GPqxBJAwLNhGLpgGK6Rej1ioaYiz71S+4sT3ErrD1UqlP2F5beh5cdxdKTjh7bMPX6we/xQDH/tlWyl0MfWjr9L2t9Omy/uYStlfuE9THT4JfdwG8p7c3vM7dmVpr7oFDdWpYtb1lCTXni/EgV68ci605ybS2VYy85u4sOoydUruI2aS1zRxjrywkvaTDVe2FYniqdOONO4JQMChrJuoP4WXCnGG+lE1d36LkPXTVXVxSJsdZ9Fvi4/sEE+rYSkZaJtxyMQmEbeVMzU5clsXzyV7guLb3rv40mKSW98+zPtGQwwGJDFgORelUYyr7qR5TKfhrdSiXzqLqIu+sncyk5unSbC6eje6S2am2duXuHNW0M0tAzYrcPuuqPDbS696ly/8O/Ft9avX7zKiQk8oZ7nh0hMKVfWIDbYxbNv8t+hT+QARDSByGVoXiIiKZIJm8KZxzUtzlW1c20yKrnL9ZMban45qrj8YBiv4lB0WKYLLlQEq6XGoK7yn5UK3Xp94FtU/+ubO1nFGv7Opq8Ug5UDrVcU9mSwcWLctkNNssB2Nlg5lqrhMs9e+o63zkFQVUfkAqxARVzsMADLCYyw4XizTmcTDzU/n3woj1asg0SjjtiGVGuGZThQqV2zgKEbMh+KjhcyHlHgjj0/WFDX+aeUrpcrocT3j4H7W6pGgfbp4/U7kioEtqBg6J1/FbzWhPfl1XYURQjWkoV8DCFqr4ojnT2rv55xM28Wy3DV+FbH1d5qd7mL+5Jb1tJLcq0Cvlz6i2XAMMpunA1MWGiSG7kl8ffXK48uHAt375rZTsCsMPn1klpzlq90GfHQX5A3GCU+/vp74MycpMdfqUdnzCZzRlGEo75jBOEPAfX41A8W4uJrlTgvGcuvdOZY5K0TsDsIXKU+v3tGXr/2b4jq7lpsRPz7Xz58eF9d4oZCTuF/svhD2eCkpVLK2DVJt+aHsocF88L0bP+4eKsn7kXQKvomR5b0+M6fFf7RKBTOQ+QHiQJ36GUAZt3sjTMWVsIVaPJaYNVbFlpzZfkeBQHs0j5gVgPeJG4mt16PBb4Kf5S0vgzast8Va1CJeMW/qp5K4DD9WRUuBMn0V1k0g5zyT/ljGY5mv8vilfBa+GPcTwX05n6KKxWCcuazLFwH1WW/y+r1SF5eQqVDz0J9/EEWKFu4kjWrpAiFP8qKJdQi81nfUp1exB9kgSqaUlAsJjNl38vJj9rJ4h8eB1lS6vMiXy2hRqokSzIPRAvKpLtl9pQitXx6VxIkQ98Me27Y8/7jYJWr2x11Qoz07vtCxFesnZDFhlBMKdr0b0UKSfk7kb+XWZ577C5VdDfwKHuEDh8kvZLeP0pyx9qXtjmT9eXrPLOSPlIRSDgOLNwgNXLh0NZJoNRFrkF9KutkGiyrX55n0ItccZUTHNBGTW0RcZm648CPwnYDyFe+h+X0vzpsTMMwcCZtW8xXTlrk0XTqfFujNVkRWsITYY/FzjZtJnQWjId0scSrTu3fPXcVQ6mFBBKVgON5uHBbjS9b9x4wakojNxyHbLF0acjGLvVmEagYWzRc3sh9BgXbtJlUg1YcDqdqzAX3MQ6YB9S6VYslTYDmQnhnjn1kNMYQCJp6dqujVNbE/UAoM1s0JfR4g6P6vJx6LZ2uCRPYI8CUJCa6ckFt0WZxA4AfMiR6l0db0LzmjWF5qMfuxhFnAUeN+sLxorBdO0X1sd1v4ZjdMi8Etdk/IhaxMQ9pEOI02vVQ2VK6r427SLeMPEOLhrD8/eBIjJK6ra5YUkm1ACdSqnrbtqNV1VsD84OIjy3UsK7RpF4fX1ICDWzlid+GOcjWxSS4fMk8u909SyrdD45CP6Qu+qLfMnEwW12xfG1oE8xhQsdlyse9TYvZuqn2Fi33IVMT9cYihSJwDp/TaYRzKYFb5xUe6XmE4wj72B/+tV4m4UGLhMMdvdb/kGzlNXDLZQ91vVCHL7rmqQfaven099Ta7o2p99zx9wwZrPRuTL3xpI9g6RtPqpgr33iJV2Oz912WZnf9zsvxBJp1ze7elg0ztO/sTZdZlUaPu6oxmsed6GtDftVQAkMJailBB666qTvc0EM3RSkyZCOkjptO9v6H3kNSoFipT1WyPBW/idmGerSgHkWL3ReRYOXYDNkwMkEjEzQyQSMTNDJBIxM0MkEjEzQywa2/BKUV3GN9HsbxYwoDP6QeblimXNz3Hn6ulvZhEXzBmafbXhuV5Pe6Lw/IipGZ56N5Pprno3k+muejeT6a56N5Pprno3k+GkVi45diZV6r1ENRZmAqfSlKr6nKp2IcGdA8Fff7qViw2X15K1YNzTwWzWPRPBbNY9E8Fs1j0TwWzWPRPBbNY9E8Fhs/Fhv7k+f9D44RFMtTqaaempisT1bI5VGNvxflTRU/Ygxr43wgH5b1YXXThKdZKN5UnTiEbyNTVW0bt/poFHQ45pss34XwEiK1aenzsWhwj+3ZqEH7WkieowcxtCsAQ2THPyS8KzAeO97Ur18fDNeRH98HoKrEixYTCHU7JaLNJGa9FKAwm3AW3DoW00YraumDPUW+TLyxMjEMZHQ5+BUzmjoe/NvxMGg2wJPWe30f6nrk+vktN5MlC0SvDds/O4lZlco1U+3H9ACnBfFnIYUyZzSw5iS53jV9niS9LtVBzPQ6Z9o+YVGcFyb6gK0CgAqYHBfmqq9cxpMTJZlKCzxaRSouBAdoL8v9tGJG9oEH2dTeKWbZHpAzGcWUvz4la+NYNthmURAb9UP6WMNLWbtDCnf0dSUX9i31LMCgaBLXHZE48I0n2i5iUsiF+jGkXxknS5dajNgRRuymhC+Zhe99gAnHt/FqOQs2ICDy8QMaOO6KWHPqzaACjGzC5vTW8fEWZjv7Y+5AGpC5nCxxOBEPlgHh/oLJxOokQeb47kJxzAegB2pa0BVhDtIPyBMQODaDnAKON2eBEyYuRvogso2MyG8+pDSZ05gIW5itAJt06VLkl2bUmhMfuoKhisRhEAdKzMOiHpkwORdCMRGZs2AHzAI+mG5B3KKWUY3ELu6OM2wQzSg9pMfGDyZUtap25MGRtcfi73HApuOzs5fW6fnL8xfnE+v5T/SldXY6Paenz0/Pn5+9tKbPj4wcoTENfyQkeIMYBVJGcPxdXM81ohbkqbl0WC+m5nGcggqSXEo01CA7R+64YZ1MHAaJahgiYVcEol1QhEOhEduMhqCffSOQfniB9J4QnQ7CIUgCUPRIaRgPAVsoDITwBtteJwKCIUv7QJZS+9uTh0vxmB4vVTIvl/4SnAORPrb2usw/V4SjW/FrpdDP0hCIPhCI/ovWtIPVEwJVNCJDngx5Mu+hzSlRa6+OPCWSZvTFpKjQj8OQIkOKWviO9IkWFQ7JECNDjAwx2pwYbW41qmmEjpUUrZEhqcrzLUwBKiR070VBZTPAKgV2snCiN8qZQlBOnClxQjzXos0RuRKGEMwmU8jTzYuFjeTOcV0wX7AdvnTpChwkweQhnDMniNOe3lI3YhUJ5Qxl3b0UsOoM7YDOyZ6avb2aDPXx0r92GqyeuQ+md7vYmXAtVz/VcNcOf+kBV7n/YUHm2a3drjI147bWc+Iq8t9aV43ZDx89MZ6uPPXSG1rmt7ehs16ln94GPm3pwRd4uG3iiZZuvNAvbR5Np+DDlXITXON0FrezruebbKM7/7f0ShR5wxkFv9G31D8sRgkTXq13Wed1gTmFm70k0CUt9UVUzrmnpUzBr2WZIlc1rG881Vqz2SWrvFUOG/dqLU+yioE+Nv7aeJUZr7J99yprKRmdnlonE/rT9Nmz5yen0zN7csZOXkxePn35YvLcevb05Mh4kvWSt1C0u9aUY62c6MgaFPmU5YjBVvzLkLMwjMUDa8bEuUDOoa3/U+6Y9I+3qR2pYW4Mc2OYG8Pc9Iq5eRy8ifKwa2LeEzB0Ia+TXFyLYk2EFxtwKLIXTgAijfijD1yK0M0LHqAxm1J+WvrHqDQYq2FVDKtiWBXDqvSKVXl0dmK1bM0mZmLY+PF3+M86YQOqhTfSvbteeBOHE2gvgZEj75y/UO0aa60Sp/09kLXUjtQwMIaBMQyMYWAMA/OgDEwHQSgE31Aag2K9fK55jka4XtYzNInHsWFoHpyh2a1gCI9RO+1VyanqH0NVN1DDTxl+yvBThp8y/NSD8lPCiX0dcZDILXPUyLB3xjJ2vbKyzi/9wsK0j15cpjiSFxx4UUSEXS5LdkiuY4ojPAIdz3Ijm7365J2OyBfRxJdX5CbEANCOZyMBkqGdkx5yzCKB+7j0OXfg6suCNICGP4VD8qc/eX4Y+z786U+qZRw6DbE9bczhPGB87sMA5/SWEQjHPGHMIwsGeGKjPg+t+qEPMvPFCAM/ms1J6GNzIh/XSPVf3Xe2w1RnGJo66W3OXFuBTGoNVFdpR5LCPuP4n3EEbOzJ4crf0l0RrQHZ+4RN/YCBlyf6XvC4x9iNonh2eIIcILKy2OiTdzYiX5TTULLhcmuV06fyNf3i2F/AvzQ/7IEIin3ncIa/LpbhinBsbPTJewqd8NBZoDsbzsYW3hhfXpErL2QzCd+A16qcButi2smSqOWWq48Njj55z1Ld5F0/1utM7ovvpY/T+Yh8WdBvY61DZ8GkG1JBVwv6zVlEC61LKJ/eZw7AaKuTiwM5dK10He9fgpDbzQkqMog18XetG95j4/jXdXUtRoc2oyhpAZy9KiBhvR6Kc6zFvpftj1LKbbMUVFptSnkrwCnGfEq7gRrnuR4buPcgh9tIHJMGJu713LUMoQFzbG4NT4fCLz3NWcODUIXkKDKPp0TUSkM1Po+TWkV2yDwjlkzVGZGPS9endlXzIFCIi/+nH4kgHAGzGPKC6jfy8fqd4namfrAgX+ZhuHx1rF9R8Fi8Vat2/H9FkWP/zy+iUchLEnEmq7uufwejwBBK2lsc+A5M4cJiLl9LxYLNyvfB1A8sJnD2yyvys7ju+isBeMSYNVdxRQQuF7HMyPR6PmZSUaVdFhLHSzHx5I5NuBMy8gN1uU++ev4dRjzBhi9c90fJzwrHbYePp5Hrlg6wICMMVkxz39CEHF5IqGWxJVbw2J16CgjeeuEvmBdKXjfj3P3lFT6LYi5efNU6iTizyWRV/pSYOlM/xdNT8vbq7e8x5ytKBdSz/UWm3DV+zJRcUs7lOylT/H3yi6xD/o2xJezawvHs5DGRP8u4c5gRJxVExpmmDsyfAZS+QH4e8e74s/a++UL+z//+f/FO4GuCWJQr/YQQuIk+YPQlzzzyFipH8aUakBCUHupQUTKlX3PHKWCQlBQm8+nTp6M/mGv5Cwb/HJF4aRmwMdmlxY/p5wdM6csr8pELPl7d3wxMYLFR8ib2WKppz0/eV74F50S8o+TmNX1R6i/HHyYsvIPX7JeCyAZf8IR/yYaf+PJj8rKEj0Xvyri/OdBxUUrrLNek3pMKm4H9wHuqOLZA5Q0WneP+ytryXkqYUbMld3PmaU9mgsowAEZ1YjkLYcf+9Cc4oDDRoncu+UFuMXwCSFC7h0vlwemT7MuArCTyLuDI0fgIh35T9P6/9WuDNPu/paBN/5agzZ8FDPw3cbvklvy34qUVl/GT93xEvsBgPsBuvCK/+d7wnyzwByDKcXDejnzNZkRByWsWqosnrYAKYDWFOEhmhxeho2DdTk/iAltYNDWPP5+ffEGSpuRJpQOmnJwnQyp9cD9WjZsIpagYnZYuY/Ws01af4rKPNhm1WozYvM5FX2qVo6BV/CW9mnk4GgWMeiSijrLigZhAUe0jkbMQ/mqhcoGGhnG1rLIFf3XZLXPTanqtQl7AV1epDySlDs4/aOL+BovQOZDjSqgOGsF5mxEfAKI3qC1E+XJN9iZ27l5B8aOQ4SXXvLuMI+WwK4yiWgNvs2p9gN7dcvMpIG3MzQOYCj8Ye4/g38C+gf1ewP4jRPjWmTzKEV4mOWgN8cqF2oC8AXkD8gbkDch3DfKVrs9s8vR47vMQylYIWNjk6VAVk9Fq9U9FkWrZ5Cn5i/b7DsCbTZ6uHfI1NdwYbkadQSSMLXEgaQSMRQPDm5Og4Q/P/uM/fmw1yE7AECazFgpmK+aE1TQI6ApOQ8gWzZpLHUQMQJ8Rc5dLpNPLfbNkFhwcDmrEXXmu1E5PL7918fbg6LzpQcwSZHMIzSHsl45FP6/l1D99qgX5H2Q/o8SvA6Yg1rvFuTY6YQnY5OlIJ8WlrABQbs2FeO7YNiyrHEuJBV6K9quAtKnzXhSMNrX6D0j9d/BmQ9IuA7KK/lrHZNVXa0vMB3e8mcvaKNHTozKchwH9nXMelffjUbEebbNmsmdnJy+fnU0nL15Y9plln03oU4u+mJxPn56xU1bpmf0g5y2bI86/dWxp+Ak966CX3SPqrX6fCrqRuWHpkui8VFxCuKkd3e+Picj67MsjYFRkFNoSVqVeknH8PeEEqgO2pbgbFbGtlLtR0bIacTcaM7IdBmdLvnrriVGKlmZLrAxcBNXyUPA1Q3RerI1yZjgaw9E8LEdTeU0eFUfTzvy0gUtlHv9SO+jgE71PJ9SwGnvAauQCq2WkIg0UIlkmIp8BPH3dX8clDONQsjYPLwQpHpbhGQzPsHOeofqGPCqmwYhBjBjEaHHqYyuUK3FKrLVTLArY/VVIOd7YTniQMo4dKYsWvu1MV62VRflteXguqWBMhkUyLNLOWaSKu2H4I8MfGf7oUcpu0H+hGyXRsbOc8nHkObcs4BiKOJwfS7gYo91MM+NYaGYYNwOOcfPhjIbsjq6GsjlhQFskJrp6//aGfFSVyXsazskvojK5FJUJGuMZCZKOEm2XbWvmvclpGcvtbcREtR7/Y2exSsZFRfD91ntBVdD+nnNah0L7Sni4ta/xo+LwzBU4hCvw8OzfBuKxhwowk+ILRwWcFh/pLNYGQrRCf9gUnycdYpuye0W+sk3x7kC4vF1ZauuwqDJUt5TEtdzAvvGbbYdv2E1Da/eY1pawm+teYsNtmhuwZzfg4bnNg+Erpbf9joSSx8wLA6ed535jCaVqO+fb3xgy38QtHAID2yjQQNu12wXvCBu9Wis6QevZHAwrqbTDBdrezJCTG9x+16Bi76nsXiiQN7ucj5onNEe5p0f54dm6AxAijhI2aPtxFVrxZquiwAutIGx1IJzZQ4gWJVO1UVyIdpu5O1axfSyJljN5tGxiS/utc/b89Kefnj796eQpO/vpuT15ydgL68XTF2cvpj9Nfnpu7Ld6JlTc7OI+KjbSHPVHctS3x2YeEo/YaUiLxoLB4+8F5HuT2BgbcKjS9b0jDrVyXltnWh8Xf9wwtkcv2NG1g38YFtTEZdhNXIbq0B+GNzRncJ+ZtoNU+Tbh8DqIJNKOu9rMh0TAS50niWGzeujHktq6Xor91pzKo2W6jDDkkQhDNvVdKb66j4q5M2f9kZz1h+chjX65E2cVjPeygeQOoysYuV3vGMq902uvcZB6yd6uMw/D2xp63296XxVbx0gtzUF/NAf94Rnbg2Nh1/CL8YOvLODHgR+FVR4uWGwoSgkGVtbI56TEouRa/ZzNRBxGgcdVKdEImfoBoZifdkcZiMWs13UvEXNbj2fqBHbl8NdC3oK6pfjYMKFtC1T8XKShahfsT04Aj87R/Vow9rnO5Sazw2sR2CaTSOnZLX+x8L2hSr7cJYam7mQphopBqcnHwoH050Q4IEAwsh3mWQz74fZX/aeN8FH0OophptouvNwCPIVc0gJcnJ2ijHraQuWwS5ThhArYIuGchmRBl/Dl4/U7sqRhyAKPhD6hsqWHhrMdvF2z17GN6TWus8HRjXG0zQZ1DJeFO3nAeNknZJTWkA0Yv+Pv+F/45ajKWDEFptJYMQ+mKv1OFZiKMjxGSoGp5Xipxrc9wNySUHFtVlOuosHITnnNksVoYP1UtJGdw2nhphs47QWc5kyP5M6DYmfqBAsq9/DD3OHkznFdsmTBgsLSuysiauPxTiNeqdFSCmxnLCxA2l9YWA2z6r0Nwic5QkInfhRmgHdAHM9yI9vxZilelnp2LSt7eNAMy25wee951/w2HjDS9v+hDyhZqopPgaWMG5nHy2u2dKlVw5rKQkIkr4OhH6iKlHPfcmjIbHLnhPMD5mL7KmGQgecMSu89Shfu5AEDdZ8gWSqcUMLwnVqWH3khH/vBGMUN9/E39QlFDxQPxDFdLnWFU0aNdIGFiLaheWUSFOQETnpBaeIA90rkAAC7q/VLudFngDMHDEqTmsdU6rr+3ZvFMlz9lboRixWH2b60VekEpcXCltEDmWIMu/lHxIT1WdxuemU/zBnB/D7+FCGFLpcafKiZa43b/oI6XpvmRY3GHdDIbtM6jezGTYc0mLFwTMMwcCbyxDfrCCuSS7iWgUNJ0gIcvq9s9edb2H8inl7Vg2DfqIgD1ajjQLRKfM9dEaxKRJtkAanpQK42o47HQ7KknDMbN/NYLjm2TpJbUEAY9JFxRgNr3nRoN1haaHSXS04mK+IjZQI1DbOrOtdXpeiYJ5XUSV/SGTtqUZwFskpzXW8RssTGax3RHjk81awWJHD4U210wKoBKirZ8UB3QyPLiKKY8CtyAccL5BPvfdexHHyx3PpfYbLlRdRbp6qR9LNnE0L6Txb4wzCIeDgSSzfK0LP6YFc8TDqfsJDqms6EZF7YNhC7/FnI0cwL2wahu8fu9GKgsxSVD45A7ugVE1+dZbU972n+mpdu7lpA1MWzRk5mnVdNQdVePmpS+xXbKjd/2lS9aOo39MCAO/eweRjQ1aLH5GF33SfO8Xc4QznFak5b2gy+Y7Wplzo308Bf9AvAcc5dgrZs8f4BqUQKqM9KlXfdYXWjUTbypWg0NIM6D4E6EhMSNWBavdcMF94y8ewr0PMV1TcgsRuQKNEd7hQhMh5Xw5dVOFE/uoMEif4/GJX3auF7McrgihSpN4MWUZgbIDnYN2m5es08Sx/Rs7TRnh4k/D84umuOXVt4mR5btO5xSvjcD8AT7ZbZxIKLOYVxM3J5UWHaW17psdKNKOoT+1nxRq3Ymx08VYdnTR6rTcZo8GhbeDTSVn+orf5Gj9k2OKLetJXnAFbHCTlZRhPXsUDpaqDlIV+2D4Ar2Qfu89oHrgGWXr9z10IeZR2a041KD7VW0PMLzkYwMaAqrQEgAz4PDj4NdrkX+NNmnAcJQf1FGN2dcrP31lJO+aiF+SOJKxWbQcoaqhRBp6RZFDBbGGOlFIYjohyDJn44J+yb5UbcuWXuinDLXzIbdyZgEYdlThqNwJZsslJ2dXsgBSwwDdTW9Or1aJ+Rsb2hnBxjbAnX0Krvt2gxYQFYVAoxFQfXNgItaJIuxwvZDGP+2WxKUZh1dnIyOFrQb84CZF2nJycnbeKsVFyCXdrgVSpMGg/0IMF8fX7SZsuAASTb64O8hpiNo4fk+cZCcSg2vaoIESIKYJ0V2OXGECvCgwieIW2CB+FEbDaFuFQIsBEH238/IDhniFHmE4uCKJZac+KEI/IHOETApjPPJkieoCuaAe4VAUtgRgWo82jCQdiPTqkBm7KAeRZUg1f01WuwXM6g+xNOnqilfEIwWI8B/ENRDIkTNL6D69zacrHBFeo+8mgJV3560oQtbzLSzn2P9gLKWyG1M/P8INZ0bRG+u+fJj7/LI7+myV4ZadAs93RWfUW4CEJpIWHIcOkffBU3IAfqA6APCNXHGR8nHs9afclMMHLse8I8e+k7XmigXOeL1dbXjkRu3mOgJxuZNW4ZxbswbzTw3Vv4Xsf2sQxgNXWRYK7TMLuuPMS/84w4xEDqNo1Ae8UJVw7tMLGz/1KMdGiUZoaeZTiat/dsxqhGsi/DqBpU7Z/gQxpfIiRPHds/A3wYg/988Y1JkA+6EWK1t1evfz8DLe/R4OhWHA9AT8vhYrnx8OASQCg1hkeU3bJg5XtQFGexmNKxYEVwpFCD2WMahXOYrUVDtHP92xHn83E8ziMwEJWLfgFVyM3NX6R8UMYfSsYGYLl0bsfUs7UWKieJwxBzfH/1V2gFLuQupwsDFj21nXjhgNUatNtf2dQOp9t4eiLQ+Rald21tvHvFs7QZ6WGyMP18/m0aPiiR3gUY+kEsKJ7ovD5HRIfIRD3A4vkAcFBSRBYSRYjDeVT8cuwvV7LvDjB1cqnSDd2WcpjBDjS0Ya4f3IEphBsHZ3lwZwuBJcMYHJqE+42jURLHu6WuI55QyB4QzoJbx2Ji/xFC4rBUHSAfZyFofQXoQfCnQn6ngC7GFcsegBV1DOr18pHTeq5qP6t5wwLsrT9WO7K2HMc8RB132GSs+4/JrYGzE2ZPw5JSWIX8uFVCKgNRBqIMRB0ARPXXKLwBinX3ZAUxjxLQWHNmfS02B//AEgPTUhNwKMSJMwXlp5LSQ/tkTtFUd+FwLsP8UXnGzCu2H6rAov3dFjDpp62RXUXl4A4SiXriIQeXeyi2cyjBo9bIeW3IEuEBih1Vyt2YyhxVKmrgcoZz5gSaS11fODnj1hG7dZxu5NZRdQB26NZxXuvW0WSgBgT3y014fShM9VCKh4sP725IZjBlWQuwbOD7YaqCgbu+wd35JmiXOxC7xLhKV+Sa4T1qZPs1CiPqEpj8pT75LL6Vldsuyi1Cl7dEtIqo8NktrooJXwhJJjp8F/Ku6gh3SUax8dznIcy0adC6wqr3gyN9ywuTpOhbLKeRT8ehxa07GsL/fn7zy9Vv5PLN9Yert1eXFx/e4NdP3q9XV79c/P3y8uK//2N2cXf188Xs6l8vrl58XS3cty8u//gwGo1+e3Z99eLf/u3nF57z1Yk+Tn+6nX9892+r86v/OD355L0OPoaL6PjnTx62+Oa317lejmJ7mUYrA0WHL3IB8mQmHH19PrcMxp+9U7uKLfGiCtDrxnbAiN4PqN7EW03v4/i79lczR7VaIqD5p2XL9gP101M+qOA25du4i1h9T5t5XhnY6Svs1HtZ1aJDzrnKYETPMKJkJ3vBmNSN7YARYq+emvVuRrVAEnsX6Q6ZBkzMi7bJi3bzp19hy8WPv0qPiF7CbIPhHTDS9gNCN7EfST0BdbvfYlVErGJQJ73cnq6mvDRadvjBp1NuKffPr+TuhP86dDZRApSP9YBBo3fsWSMjtfZ82hPeACU0z/Am9Q8THHbBWunYL0tiWD6YWcgWTdmsuJn7XAoZ9Usxa1RubVtwNApORu9QsN3oDxcOe4ZzmzBTIqhmOfckrR5lsXIjjlS5g4O8pFOpVGtkiAHKR7xS/hR94XDx8qpHvXnOaGDNm3Zwg6WRbZXBUycr4mPWLlCXM5tgCyTZq5LeWxqmNCyu7Fbax0KWs9mhCUmll2vF0B41Sv4ezKjn/FPYoQ3IFV6JcEXeB/6tY7OAD9Ao7hexJFlWsl3t7TKYQeSyYQxyXYRJFotVHhkZzEz0ogeHmTtjEzGMnd1UYqZK32shTppNzksq8nFsNdesblJhDfnec22rG0OcKF1iE6Lm0tgepPj470oc+KxVTOP00AxAZwD6oTF2E+sQ0frxd/xvq9DFxXCdj1bcI6xWk3xUKpnWUXi3CjTrxt01ENNriGkcb7cYFcpC7Bps6IXtR+84kKpxGWx4TO/DxgFoi4Gl0CrEgIt5iZqX6BrGKb2jAzVDM6SgZ2ziJnoVR05wvFQTrNWxqCokqVKub9EIRL5eP8jEg+hfuOUsxsyDI2E3VZNcebZU78UefvAviJpMAhYGDrtlBassUtXN6a0I636z4iFboLLlMvA5H772F9TxkqP+K/XojC2YF5Ifbi6vfv2RyHF2o3TZsTdwJzktCxZ1dzqdphqdikEayO439662bqhD6vouxGUHosqVOFfYuBHvKGxewea3dG8t2+9dcZOVLmdNx2gwautsZTuY2UTBkWcrj7/nvrVSfNSDmaYEyZ+yaeAvegVnRavxqAQVrTUkO4OvdbUlBrv2Brsaa07qYSXRolS9ZQ2o9FC10k+GqOkYDag8pkdbY5VLPSIVql8MIplnYmNdQz+BscUwDTb2jOHaRAfh6/MtVD8AyVz5UUD+iwU++QDjI3qtgpxgIj80CLwVSIoI/SD3rmqqH7DZR76qatW2hR8zFjZ6qzUenwEOjS3KpPh6BDxZBhRqubEy/4hWYHPDQk6iJaGlpy8GHeOQv6twJjBpPZUrG986dHxHg2XTK13Rwv3gCH4Y26g6bdqgVkM04I8DZjsBs8Jx6McMXvPmSurfwwH1VuPIW0CGOWarZDxNPY3Lapc3PGbfIN0is8UJahM9pk2LMAAHs5WPmWePMScLJA1BUbXjN92J6jaEOVLkjANG7TgncTObpFSt+8GR688cb2wz7syaDi5V5T6bpLhBA34wG2uVZBMyh7GyYwL1ftMdKq0um1ZXeDz1A7g2sJxt2i6u396s6wipLGZvFMR17HjUCp3b5peqtDo2jVl5xrZkJRs3makGTYWBY4WZ3gAfmrZZWv9+cKSfwXHoz8QDjPLGI65oAJqHC8MZDcfs29IRc1Irxcah03jLGjR0PzgCvBXQ6fneeBL4d1DtmdCGNuilvH6q8TU3t6KB+/uWTmkPwV9n3ucN/NMMl92P53lTTldpcctFj614XSV7NA9rw+v2hNe1Ih76CzQmbMp1pKoYdtmwy4ZdNuyyYZd7yC6Xa7N6zi63GaVhl3vDLnemxzoOULyO1xb2Ky9qFvJ3PSoZrqAI30oxIXCBXgvqcPnzEx7nB7bAlQPbSuXcOzSeO+nUZoD1POtekl7OP+YMc3aDrfsX6PvLANdQViZJ/Gly54RzfPVgouY7x3XJBAI1w36gZ0xuxSa+7zKKRCDOyQR97O5hoNYgB05dzjsz2+xkB0cSQYqiyuFPKqwcdhD6su3q1FYh4+H/kn+OLH8RU1owBynsCgxF1unp+cuX9sufnj87s86fP7PP2E/n5+zl8+enP718OXlxdn4W00VF0QKmOJP6NS9YV3EQxOiG+osMPv1xcf1ewIPrkl9oyO7oKsn0jH5ezJv6gcUIFYUt1wFHLjk4osjtiOBwvuBV1Qbyf/73/8dFRVUDRxYwdBETvEb9nmdcZMUBaOwZ2wAXt0Xf4Qm1akTe2wzSkPddOczCsleaqQRK5/1tOPWDGRvKczrE11+woDFiOJwAlCpGTZJdoK9l220zHgYRXhF3NVqPhUg9USpccWU5OYoK/9t0wQPmBzYJeJpaxC0FPk1v1N4HQM1MZ4cRUCtDG1SN7VHD9I2c8wcx56zxTubn7Qapkes/jMFrgzim6c3MAeEvONQkkmn6JpM//ek3P2Sv/vQngoDvCL0GOtSDQAVe78SiHpkB2zZn5FJwUzfMClg4IldTLOH6nOV/HuBvyD4J33ufBH6IjFy2KJgDWWpC+WEeGmjv7H0kmOMxx00Y37KANxdlFdcFiXs7kZgu51TxIBoyq7L0GvFv8NWyDNit40fZqaB0kfExbRqKp76dewVTjdrDooVhdlqHeU1fpG1RIXF12yjRywZ2eCSoB0RmEz/nNL9+/D2jEKn3b66hX7FPcx9JQnayj8qvp2mS391ATNaPpjLMf83QDMg8AMjUOSTX4EAulKuBg37BQcEm9gILqsZ1eEDQ+wdvnZdwDUwUegYbqDAvV/Ny3eHLta1bdg/JRs3QDo9y9IA2rGWaIi1dLV4V2PUSC5HLm+uKXMOWLKSlqb5xZp7jzci1NEIlP0ATPwqlmHdQzo7ZhIhD6tnDOJllmVKqTQDU93TGiBdHQV3SmeOhhYaMh6pphEQpPQrq6eBo4XgyBmpqBGuHYbWSQ1MUijU/hnM9ECv+oUZ0ro/ID0TMk8aauqnDXDSY4H4gxPQBev8zOzXGyarI0CMenRQD2YD6QM9gXHF0b3VoQgp1tJKfUyZHaJ4uDMwajz6uFM+gbqCUW9oIxV/QLgymuYJOu/MxrI+6wvOa25CA0po5DIsGr2hSq0nUxMEPAj+oJf41k10wzpWfQfzv7prkEdKRQnsjVCDDhbh4f0UsAPE7yomsMY3cevOt+JzhH4ilnwVvE7nh2PGmfgNeFa5OweH3Q+pqgKbCOovk9cIUiqHuW5LIInCJB3sKbCHgWF7kHgUBqNrgV7RmczwNPEHDqPVe34fCyxYBqpu2f3YC7CYsy7hyzVT7McOB0/IjCCu2IsICodhUoKjPk6TX2IWmwBwinh0WxXlx4ni4VUDbAibHBTZu1csIIbjjQ3S0ZlLsxhAjngzyGHuR637Opc+WV2igLrx2UQc1v8pJfN4JewqH4hW5uXmHJlX5vPaDmkIaK2tN37Ng4aCNH7+OF+N7TFf+hXP3VYBikXtZwaXeRYr5/X40ibjjIfwotAhZsAwcHuPHNGCKC0NgiDmyTvhpsc1DZG83sSNICEqpCYFUzdezwcgFlzLB5NL1I3vq0oCRWWKd4AHMWVHA3BXhoR9IF8tl4NxCF1/ZqtAo9/Lm2rDVuw3H1py3ifXCOKiYrWmsvk4OZS84NCFAqObOykdu2LNds2f5Pi8ao5fWdZnTsfYkynckQS+5nwXo5XAFX+XW92dP2clPLyb26cuJdWo/O6Hs5fnk+fTs5Yuz508tNkFgofbv6HUqVuTbkEa2EyLhUC4IQpY0VsLGPHsjCgijzx+E3/KPMSdaO0rdEQHfuO+YNwMfgOfPysYTeWGwKhjLnT90WRiygFzd/E6enj5/Pjwl1F3O6fCMyGrE8u0ar4WPN0clPSdv12IPBTlhPIqycFFXUx+MpeHRS0M2RO/D1L6dnD0bnpwOT88/nJ68enry6uTkv5ruFQ+K9+j9m1+HzIO521UHuHphhvC/n9/8cvUbuXxz/eHq7dXlxYc35PrNv398c/MBf/3k/Xp1dfmf/7y8vPjILy/+/eLuL38fjUYNh58ad3Yav+M/KDjaxJ+bHzPYFiisHTewL7QtGtgl2+3UiuSbEwKd2A6OwLtZDLVor5BfcWd+4ITzBZjHo4BG8TvNphtwenby7CdN1pF8WZ6dP789Faxsftaub1HFoWboE7gm+AFRJfDGVw/jhnrkbUA9y+GWX7LMxcDyl2hBvSEcGnykIbg03uxfV2mmtKjblFNj/rDprqb180z40gG58qxRgz6pO448pwBJfk8VIlCowQjeeDPHY0x+L+qcU6+AlN5ESKLIhRuywKPggEF+g9NLZFY+Wz1U06uee2/m2OB4bH/LYPzd3d1I/1JyEDnY+xYMGM2A/UDEtfUs1mR7qOtM/cBzaOHaZJ60yH7HVzQtsnz8j+HW71xmO+FjeOeuZcqoqYiOv6fwvs56seLVHNugNX4vwy46Ycr3VHv99uOVm1qdXTxwS8hvDx/eDe0le/amdVTsmVprSvOk7cmTtnoBt8XwHoAI+WCpZoVtrnbrX7OQOm7eQOJaZV61RQHpEsyXzIKlbSVyMRRujylc/qz0gsQ1EtuWD90QOSO3NXJbI7c1clsjtzVyWyO3NXJbI7c1RkwP8UxF37B1JLuxWV+x9b/kLZfyMJRFktKKpSO/8/2290/P9yrhfGXwJ81eS7Y1WvvNKXcal3qNF2Zuuzr3FUoNUDs+Y2nxKwzpaqyzC0fYtctQaqQP6ziUhPd9Rd5fXWVgTLED73E5ND/U/I+ZijcsDB1vlq8U/5C4rdZDoc4AbAcTJfHsEBJxd0fy2g31j/XWnmsj5fH35GbeF8KmcKrWjnnL/JOpugQwrh9YqSFSFxK21BVFvkNgCQ60lYRvjzA6dzZ2jdH10QCKBmfgedvw/MhAtjZSQRU8VmcRMvC4v/C4i+AH8eu88ThFDYgRHritKkL57EsbvikRQeOg1kXXok+UoXJ8j5g4NKICGaR/pIi+SXwBwThTzllYL2mQxYpFDakyRrKwOSxXRxtoH2Mgt4SOF7LZhuEGaoIMyNOghxloMowzPeLA2clJelStRS5yFLtAbexqHaFLZoyPFrlBBr5fMByj3ibRrvVdzl0bUYpnihkM3SPWNqOFbn4VES/02g1jaxW0onIDtuWVRe0ijllGUdGHJ5pvzD7LC5A617vG4QZ+r4XjMxi8Rxi8iQeFzgQff08uU30Q6EpYT2JAp2E9gH/2FdcTJOlcVKKj1J6SkhTcPcvDSeHBSACvNvCzwaF9x6HaeNGVkKHUT/vECRrE6Ezt1D/+qGJ4Bpb2CJaaan2KYUkLT21g6VHA0t69ibt71G7wmi28Lb3C6+oRGsjeI8jeXK2DYdLZnZaUtEJCKQuXJChIRJTcmUGE3n/94wPiv6wG/iB5UjB02S1LW6BO2NQPGHFCSNq3jCauw+fC46UHNOPgALzxANRRkh0XR8Qrl/+lDtd2ATN16JtLAItH+GgBszfWVW2MX7fit75LLf5InrJtJbfDw3Ac+BEs9HEQuVXuAxmsJrIaEdWKlfzsm8NFIb0woVbgc+FtgMNT7j/9fBlsxy0d1/7x5Av4VajfC+J8N8oZcNYsZ4BKKNNwUG8d8DiDHNuyYvocrum/3cKgoPLOdE7XxJFS5xX7KIq7r6jbydP8qC+icA4nUvRP0FoRRo+gCzxbdkKRy0Rs9WWMzKOjPeDdxb+7RnSc0lDu8kghY6UhwFAu6UbQzaPlMmBcJYdqBuDYBNGqlqJ4rmDsJiujnzD70WF3uafn+bNnz87OTp+3QOxmFlQn7QC4otETHU5PT1IWUSctkrC0zKIibjSsVZxYa6MsKuXdYx6UjZKjKNWJOtbMFuecdxgARSWQyO1UfJhOMqkmykueYv6G+lwKmZwcqXASjYJEpIMogJO1wOmK6sm+qzsScRb8L90B+z51KpqOBbC+IF5CaV2RExDnILeq/BrPaWCPJ37kWah+E1BUsbA5NIpP499yTtqIM2pV5GAGmTuTrMbnbCyXe5Wpo+ZIZLuVeKFBh2gl7fkNpL/gQvxMbZWLZSsxgBquazomTzl7JqC+zjleubrbbBkw8CtPkL4j/gRJuzPz/CDmKiq5g1GG4G5gJVhHzyukcpDhIlfeUHVB1fMCs64uQ2+QNHNvRLeN9RpZ2olMf2eQ0S4EZA0tyANzDqwNNu4dNnYg7dK6Ov6u/dEgHHJ74I1N+zyDuvVvqfRudNDL05fP6fmzp8+H9rPJyfDZGX0+nDydWsNnP7GfpvT87Ozp2Wm7+Mbbwr7y6112nWPYKjAvvNFOmeeDAUbk2V0DWOHp6gym9hml6mz7WsOICkEr9KoQ7tPAyZ7DST9YKSMm2AcxQR3jaihA3yhA+1BugknlzLONXL8PxMPI9Y1c38j1DcE2cn0juzJy/f2m6kauvxePUSPXP1hs3ECuX/BkMnL9PqDungjijFzfSHWMXN/AiZHrGzGBkesbCtCxXH/qBOyOuu4xxUUQ3hl1LldX78kFFi9xsnrLQmvOeLYceN8UxFkgH+aMM+WCtVy6K8j5BU5YQFYqHbHIf/oRsahHpsKjBsoo/54IHUM4uwU/CeKrDGoJJdp7ulTlc6P2NXa7KfHoWvh2hci/UQ/ywxCbShxW4qUdJjNlnA9hn1XZJO2rHoR9FNJghuE7GnlTvWZTcK3BzRc14fxwRgNrDgcncfbLOFcVoK+z1KT8+IezHAfUQ+Em5QiXMgdjSrmQHv8tbvX6w8f62iSAxcpN5BXcpav3hNo2QMMg/SfBQQ+ICGev5X8cEJstxZuU+OJWYTYxyHb2pWgbvow+eb/5IXSobps2rJgxvHp/+6xyLCJ9JyU8mngsBCx4cnz6/AmM8Mnx2bMncqxhKpPlcO1Mlqcvfxqdn45OT05Gz1In3oO5rLM5opP8tsBv2CjMKd6jDPYli/g2ycQ40Nt9QsOQWl+fkDs/cm2yoKE1zyEorqHo7MkFlidnz49Pzp5gnrL40wv4hMAa3wNOLMoZcTzOPO5Arrvq9VussJ80WMCY1lo6MQgJZQvAkRHBtKFc3NYv1HW/DGLQLyhPFhEPxapkq3qrLwPie+6KwLNGxjAoamJOOdQQjRTMPtH3UdfV1X0eTBS+fV7XG1ZfDSnZY7YIJQF76niagyz6LSaeqkUOqimdzNrOsfqgFqWOsvFwKwdy1kbPWz6MqcNcO078yf0Aor7AkwWcZOvxW5IztXElZKUYrbFuW5Vx+UziyuvPZnOtcxG71n1W8JgVqPDqLQ0cXja6tRJ/N2OJepHx4a0cjpr9Nc4+G22iuFSb0BN3dNpdurXtuCernRlpLOKGukovc65qdJPpwmUR4ZCgYoE7x3XTb5XKd8onT5D/V+SDL7Nj54dIwjkNsVGHIZ2KeStoY0ACNoUnjo89/C17bQQzBiU///AvznKoL+Vw6gdDOoQffyTMs5e+44WH/P7ZWey4FKVpPOZ0rXtJml59j59Woo9V6ctqsN7LTbDGCNOKEWralKiaFa3IwaTn0zboev6i7ICAiZvXIOBS+egOmYC1oE2dRUPqCW1aS1dcIYY7/g7/aaImrqV5ulq4+J1KbORgbZ1izR1OAG9E6BVB+aZTSJy+H4GS5PJ1S1Zko4UytYcjac2UyTtF1BRWCVQdoqFMKbDWDtIA60ECq4Q+LOEHMzaU12iI7AWo2sT5yQCWLUFPwycZzzM5XrDCKEETwMYJaA1WQk2ehrZRuXq9Fn6VWgSlAywE42+pEikBYQOf/YLPwm3uBzdaPbRDRkwjS2mWSBll+4VB9WuBLY6rX4pkhp3cRzzcfnDmnCgCz1fbOPb9hOTa0R0yKh8wH4vzWVM8sKQr16f22PVnM7Aqx02plAqggl/UIrIWgVplsoGi8hjf3oJqSrvaS2TuL+NYvRdbhKvMeYFL3AbCGo77UQBZHbbIYOtNYrHLg1kCLxMW0iZ4Ild8KFd8A8vvphigP1C1O496qWz9iAslFfOsYLWUlhlo0oDlEpd9AxWt35h7hxNNBm1A4oFBoix32k0LhFBacz8gAVu61No2WpCrlEq8VC4Xe7Vg92Do5fniw1e2GhHJXIK6f+lST5RyPMuNbMZzo/3hTbx/P/4P4odzFtw5HLP9BNJ/4tnJ00NHsh2+DgvgqfEjseJ49xdQmwzaAOoDA+pamc0groZ7zB3v69xH7a76p/x1hsFhKpwv4iKJ/TXWL0/C67qqknKy4Ny3HLQ1RYPitPueavCB8a3opCbDEes4jNdRw6mjNWprm3DUjE+7EV5D08jtHkWyo5O7p1lVxlhSBSJvMEvK1kcHt1sz/AS0GNehxdqypSvoPJbsi78SCf7m0hyc3Cie3Ci5kLXmiK1gAInDhLrUs1jQIrvVO6AGP8f1igKoEWVulXfFHXLLX4KFObQS9/6oGRkEczFVoMNJiaESObd/ozXYme6vXWYi2p8sKJrWOrbYDefUOeeRmdvDiq8zk1bSbIU5JT93CUKpvY1T8HUavCk1i5JnnrSNboIhBkJ2/jiqwoMh6BjkIdPtcWUecWneO176vgv7MaWuO6HWV/xQFB6unb1u1VF7eFwUj69GDFSrCR0wKD4Y7K1la5tmvY6/p/5eIxxTNZSqSm25MoOoRbYQ2b3axmhqEWR9u9sHRcbCmTTCwVbDNzi4exys0P9Vb9prYYZarAlMHNAMdh0udjU6QHvF1rWb0QHjWU8fu+UWq+8xaEY7Bu0CvXitOcQoEW63mndUE7QbEP+WBXeBgzVQlh6hxtImiTOogcQ9gsS+PN6bPrwbHPu9Aug28zlgeH4wABYWrAWmJMrkuRUAq0qGyzSQ+qjkoU1uw17hcqsJGWDePTCvZZHi+rNlxOfHNg0pZyE//i7/JV0PmGtXKKjl78WZvMD0RBQg8YSl2YrsQ8bUUWdGxBwjDh8BGy7um7BR+cpWQxEXcUmdgA/I3ZwFaN3HCQ1U4DBYBww/aIsgiuI3bWg9YcSTFe4In3ELx7JZEdZYRRGb0ZDd0dXY9vjRLgiXGMqaWnV5WraAimJY6r/Yz1rxyjIj3ALMiRE+NL7N2rnGuv6Mt/GN7cywry2m4uoqMB0q0BvFONZhcOVqZP27P6nA1XeiLoFSacgswdp8hVwAswz0GiTsMxKWH4Dto+Pf/cla2NhgzI8ZL1u5tiJgtvBt7RtgInxtBS6bA+P6UNgP8NsD5NkPrDHo8jjQpQ5Uau0ctVNRE/JVK2kwYtdxURV71p6bsxlo5rBXjJPauIlsPeAMPTiedtMmVPH7wZHIN9K0oiwd1xuLUP/jMKDTqWO1ayZb+R7v6D8i5lmrxi3FFe4HR18dr/ESYNn7gbi3rjsWaVV4K8zXqt1j2vBxtBRS65UMP9ukqVy9dFvgxxHcUnfMmeV79jrN5ppI9xAwyw/WaljVhIi7eMebtYBl7wdHfhQuo7Dt0mdqQTt3Hgv43FmOrTl1XebNGg+lqGo29m/uwrWN+6sD9G65kMbBf4uGaFiQx82CrGlznDxtjr/DYau3M65iZeJIvnqpfvArYnId8yi7CIi2/qspv2HrAVbT9M2N6A3jnM4kXVT/XqOullcvPek/5gwCI6DB08X7K2KBsueOQmpJ5RmrZTcpSMangnUhXMAfnwV1aJGMu/HhqU1OrS3S53pLaIP7h4f7HYQfTmF1WbAm/WzZJebZv7AwH0bYkIIekIKSHewdA1s3ToNmjxvNyoJBSROfKt4zjvZrAOexSOOMTM3I1IxMrY8ytZa2pn2WmVUM0XAbj5vb2MguNb4YMPW84g842bgISe5O4ZtJqP4KihPOPEwnvPKjgGiErR+MjWE7KtmOzlQPJYdpe1g6Y6GG/E2M8OuGaLB0v7E0gbttKSHiHo5vqesgMhci61/lr43gVRXmhYdTpg0wuLpfuLp7JXFxj43xu+rIbg/E1TVqieSNBmvg/JHA+SgG223huurgWLtVNciulyxHdAPb+wXbnbHDRedkBzDaCjyLhmZAc79BU52EURqfauNfdQabxxgBhhej5+WcWV9T506WzhkcQ0FOHGR+A0acdOptkIChbys1CHuoCFt2lraHsvpYRV/NYqHWDdRg7uPA3Gqcjbd/KLZ/2A30+oEzc+qYVVmonE+VqjBZUGBrRj1m0HVr6NqV/jKDrdnf15AFiOPQM741MyoDn48DPkcxSnX+yOfH7NvS9QMWxBEFjhonDolrVKUJeufPyBvZR1xDj8tVlqYN8nu/p5yTLzKpmpjLn2EnvmBQRZf7KuGaCOnlslvmJp1ARrZP3oS5PgRR9EkIZpS5bHA4tfjqE3/hiDxZX0T4hi8q4uLqf3zyIi4ylwrNtHJcJsyzl74jlH0BCwOH3aroMWqigg//5PU6AZLLvo1l2KGr13o4g9QOqIH9I2JBPp0fphnzCYwE/pvaHxlyLd4gsTVOfndGRRNW9t4NzSYhCJB2FPIxpiCjX3IOuwNJ9m38WvR7I+4PnLDrDI6LERe1E88MW/qZ2teC1A7PjrDi02YV3/rBxLFt5ql6z5rV+80P3/qRZ0O1ahxvhdSDbPiXTuCSjzQM2iCTST6sSVlglFQakyJsq8QzAaNx2KoyQIXrwJmAGtUsXAKOUahktKCVH33yLOpBIkxs/EMRaBG0HIfBU3dErqbE88MkMdsAIVqLo4W1P3l3juuSCSPSlA6bf+trc0Rss9nU8RxkoQYw3ldkHoZL/ur42AYghgHwkeX6kT11acBGlr8QNEfx6vK/YOuRBLTZL4zcVSRC9m0sjp6EFgkKxYEDT/NoKKsRwSjYmkeNu9oG9ImQ13uJelDtZbNql743dR0r7BQqdw2PHfKOqWhURzU5T5qDbso1sTniEnXocRQgX1pEPAQEBK4QIDJkVojwtk+Q06yCnHuMUSmAOCsHiHitqGWxZbgdxsigQwU67PDqb+iA1uw+lvultYCAa/WsihOIFHY9WZGr16WAcGC3vMitOL7l6Js1kO8zlWVABVa1QudWhPZzIIWB0iEZGNjG02jXl77GT6vFpVRuW3B05FOB8FA0Yh/7QZEMBP1KS7s4gCu6m8eC2Jomj4Vq0Qmh01B65AuLe4MDjwUH1vWgKOL7k4GVS49rxR6VcuS0HAREu4XyXAISEfGiGZE31JoT5oXB6pMnBZE8JVQRZxGlKqGzYDyki6UArViiIovwuX8nBrL0OXcSYUk29vhf/Dt2Cxl8QNBCXfeTJ8st6ApEKumg5egaknu3/DFnchJAmP1AXD1MHvTJkz0NiO+5q3wodOVvUrQumkQHREEoQZKARKgEa1xZh4vhq1YHUJagVChgFgPmAKxOIM7Fnj2emoes9KdZ2Zu+xvKIdQmGF6r914lK3IiOH1Z0nDS2CUyipuSY/8MtRMfryCMUjApIsUZF/H7z7+/E74TOqOPl1XEZ7ZfIgpDUcjhZUs4hEY7AwC/4/Yv8Ob4xI/Izs6hSdMkel0tGA04cDz9+vH43IA6iBI9EPoXQJzISNoLpMvC/raDcECzPwWTCWTihEF9LHBTetcyGRinKIgnuCsG3ZqxRc8BUeBkwC6WWjkem9BbgTXp/vP/95gO5pYFDvZDczR1rDl53NtcGLwetcG7i26t94zLl4NTxqNK+xfsd+oR9Y1YkQKrc+CM9D3Sdfod7dvTq2cnL5w2Vbf+OfYpIS7xTVMSWN4fA9QBwLfiDSucnL5pVumbcjwKL8Tff5jTiIcPYEEfJmY93bFtoSiOVyEgZNkg0dGaeH8SmD1VQWoWgeBqH6s2Z08BtCfyQe0tzdCJvy/Xby6dPn74k4rzzEXmL0RrQsOvVJ4+QP/7y5voN+R6zgyKtxz35n38mnn/3w49kSK5++/Dm+q8X78iTpydPyOuL/6yp9+Ts5Oz58OTZ8OT0w8nJK/z/fz2pqvTzmw9/vHnzW0lNcvHb6+Snpycfzp6+On/56vwlNCqVjOWJz3JaRvVyr13S/yqwsUCeEHlFpBEEjJJHrRSdjgfqSLS5cALJbvMilpzHasiFD5bP3tSXEkpCJ34U6py9TNgDXxaMeshGTwmD9wC2NSAWGp9CNaO0rJRDhOxbeLx0qZMB7maEJ0texJ6BNYfjAQI0FUkYAtMtgdk9OdmYYa+lMliAh0kfExbSloz7gtkOPY4gbGMhs45qiwya/Qp1iKhTqrfQChHqUXcVOlZpJokME8znNJCSC04XjEAiQebZZE4922WB4uhvwoDRhewjrgw4GEhBirDitairyi5geBYnP3D8+1fHi0LG/+qwO2b/KJ4Qiq8PGOQjxmHgWyKcC6stJoZny37lmPouFsDBDuONGKuzALG52teWy7hOVe54FlunYuSFjrtORSCrY5u5cDfa18aX3DoVRVgs3lAE8zFzUVpYWstosFxc3DjUbHKHb2LbF3lmpc0mdY8GR7fiHCWxcQEFk2i3f/ucBJT92/ejgmtz9Or07Pzk5GRwBLa0p89fPj0/e/7s5ASWrLD4y5/SpZ+enJycwCrFg4ezLqyqG1G13BHDXsf4OWdQ3oTSZRucYHQsjeydtm8j8mgUzv3A+acI1daIdubOVEJHt2tzfrWA7a+RQWmPtnJKhgRmpIhFh6mOFr7HQuefsYt2I9KlVyLMdWaOnE2ZKL5Arf6EExfUgCHhoQ+EoKxRyb71W/qiD15RhSFQhUawdSNWILvMxYvQCQubGq/+x1DrdJi79c/yY//NbzBu6aK3neHX+ZWU+L+8FUW698ZpObjz4sTzqwU0OmT2DDzLl8yzIaRj5845rQbbIVoWISEy3hUYqA019nZJo08lMBbz+YUG3vjKXxv1pLd1kfcAcO6/6u38Ivlk/c6keO+QE9h8x5sNQFoS+LdggO1Deuu/ox0isZnl8If3194IIbdv3lCOeAVHaYhynqHjgblLU2FDFQzqe/Rg02niFWhQ8YBQEY9FF/KPJV0NlywYRpxJbhsMuoqdAoGh1MrLxxSUh2gUVrk9R8CWfhDGIgMlqQVnBDILfM5FpnVCLfwDrC7e0xV5zwLykQtfMlRGUrKMJq7DIWdI9s76tywQoTHg6Dgh+fjhkgRURo6jIVn4PCRPT4lNV3xExHtzGvgLAuYbK2L7CwpdeDbhHl3yuR/CiJeBYzGh+VwsmA0Gp5NoBWrTa2ibk2iJvomerZlWvsBOwFGHzP0ocFcopiYon+H/g4ATHAvE4EQpmzrpQolWVkjzxG9g/jKbBWyGylHR9IBM/HCu1J0wQhAZCuVHAP8EOuPfebHwhrmC+MD6qFjK8ZYEjPvubaYV3EWhjZVlBMCguCiuIdYaLe7hJuNihsRlFGwrwCDFh1d6yOJORwSpEVmywPFlX+CNCTbo5GdYZK7G5QT64mDJJZ2BzQSQ1Lu5g0YaIXXBww8OgthT3Kl42DC+EUHiJydG7+SJFHcFe/t485osHCvwLYabhc2O8RiMI26Pk99gO+JjLA7whE1BVQFfk5MasFvmRVJs1m9Sr263FdA7t1gpLeRXlUrp6/gs4pXgYD40YTPHU3oZPIcxbMiTg0qgWF8X64JG5LrpKW6n+I41E2AVN4T+UlH6hbit4TzZNzVPENNucYbyyql+bWVki0CGWwOGX6CfY98sxuwY8DpZmlan5/37j+9B6LFWRRaIui1kh/pyK8TSvd664jByg8Xub4BqrqNVyjW3hoop10ZK33TeaM0sP3Jt1OxOYgEpCra2sGh06bwBaWtqvbpmxnL8lsa6jHRWp/rxqbjylnxVELmsXXSFuEYWZt6y0JozwRapQo86Bo2aZEyA0vlTrCjgfpCF5pZNX4pG9HaXLBgvhZh2k5Zj7CoDr+q7HLdzrc5D8uBrWPNt/MTZqoz8VwjW8fH6HblmthMwK0x0xAU/oSgdfpk5FnnrBOwOznNSIfVZFn73jLx+7d+QX6lHZ8wmckkSVXTJ77L6h4B6HGiZ+CGulv0ui98gxSWXKe8VVafwR1lRHlPyx8XbuLz+LVNMbWzp95SmvUTtXhfSRmVGLI5oI/6NAW1Q19SN0l5DsE5jM8h2K5KxyxIHiYo1vFVc7XWwuo68IqldMayoIo4OLWLJ5Uk9KhGutQO43wM1sn3EuUI0q8OtMmCqRKAqlKmCjr2Gi7ViFaiGj7/Lf60XnaAMduLoBPDsZwGGIZNejnFc1pK2+gFQyap0C0zyFF6hfl9uaTxbtaPS4GaPsDIFcA1M9+JWcA8MrBlYKw023TxOQhkYqcchiIykVYbEpBLHa4NED49EnTwM9xNYzLvQvAu7CVJRhohxbuHSKoPE11rE9ZOIeTCYuGcM2LqPVXESzGPVcHW7wbC1AmwUPlbF16Pi1CF1cjL8bw4WL2xb5S6F34XRQil3KPSMUE6FBqU2aCilclLTcsZPXlcGUcAmYqW7HNIEDKmm9OGtgQ3IdgyyMGODrQZbO8DWkUC9nYgDxVfxaSPxYDHaxjJCTSaIcIqGGvvwLN8KNGZw0aBwpazRYKjB0O4xNJE9LmlozVs+t4vhTntzp+EOLWoN2BmwMyyngcu9hMsOH/VKWVxhE1iKlU94rGuu1AFlFNK9R16j/TFmgUb985jUP83CyMUArKFajdFghwicfJVfNnj/yxYaiQD2UDWfTK97hP6rbHvHbHIfiYIxTjJ8715g8dqmS6VAGfu3qDx1lsFJg5PGdMrwzoZ33hyv2wcWa8s6H09W45DOpC4tpLP7dQQcCvOfcGlBMFmRkM4qhR2iIBAJspDntaZ1mb1j5twyD5rvDw0Zi8l2jOSXNGQzP1hVgTl0bAiaIWiGoBmC1hOCNpqshgIPt0HXlnPKmUbI8O/7Y0wchRFmCulXyesGa4nANGs6aRRFmytoNUW6cMj9IV7xKm4Fut9jyxXovZQFDIAbADcAviPNqQaXnfp1NAHUCh+Pgur74e9xqPj5MF4hb+LTa/xDjGB957C4mVVJLQO7nqlJAXR2ZHZS0LIB3z6Ar7FFMdzrI+ZeW4ofEgDdullKcwgvtlXZQDzRnSK297D+UDJsQ06MLMRQE0NN2lCT9gJtddSHFk772PG4M5uXxJxViQk5uZHVyCVWI1eqWpYewDtBhDnLVlE9oUy6QH49IHzu34HARY2RTB1MhcJljhTIxsA8G4/V445mm9mlscjJOHVYOvqs7fCFA/na1ws/m+0laU7vxOE8YmPLpZx30w02eAntMV7QE25Kdx19WC0z3SwD346ssJs+ZGPpHkT+hW46kJlZ0+1DqgKR7aOLHmRrmOT2PVypdGfRBFIPddSXaKxo3/GE/T8e+8fOTlnHnZWetO76KT5tcv+666bZieiwv6JTUR1WW0YGOXp1Omi3giLMdpsI3nFXZ+ct+6qL6p0mnVqaBnJHuZaIoFWmI0nUfHVrlwHkKw8d0bPKWNpug+Lcpvd6ntP129BSrqbX4I85CyH/CfAHF++viAWcRH4x5Bwnvu8yCk81mc81YemixdGrv8Efn++TZKx1i4O0vO28RKX7gQAWrvVCg4AiRods0Xq5sDVk7pYyz3T7Yz5ITnfb+vHRvU+xRX+Lt26gjpJ2Ij5XpBq7IJbrMC8kWI34lhUFAbM7S+KVncED5/FqpwmIB+8kfHWXIqQyrv/4u6CGUAaTsg9df1bzFLiCGuQCSpN3ft7YUr4A8HfXn6HAx2EyjXkiJSp5HiSvAGsucl2FPqZFhLwbkXgJIKcAjYgHJiZvgoQz5kmguJsWfWYm3EC1mrtpsNXv/FmcxGL9JlSGjfVbeOsw177Eo9MoS3vpSEQTP682aeSmad72sgZ+xtxgm7Twe2DDCdklA9IKpeUws1mQDAXZlIKMYjzfkQRJpyVphIaFL40bUypbIpfpRsrseYBVjDgLsmRB0JsSMoM5/RxbpOATmf2eIJCPlz53QueWPQG51BNqWWwZjgOHf30yIh98SF0IxkEgQM30F/rEi1x3RC5FMjVBv4gQ7borMmHhHWNetpocwVBkQcTmVVNk6gS8J9qRPadqO0o7nJ0OnMv0Mf6ojDiaZRl+CEjWYY873sw1qLwTvl4Cw2oLeCwluwjEWavKi8CaOxUy/nxUWFWhFF0F9uZ0vwMSsIV/C8y9E4qohkIPAHib6AcwKKzIz7oEPAywxtzhoR84FnUxratBxX6hYrVgRTt/OdFNLF5TKjJkXPBiCb3bvQFLA5a5kALyRGERP5gxYdWQPW3x4QJ+Sky4A2RtKirJ2r6sKTSpUqbKmNmlulRdiiLBuVSSctCYaoQeRuhhhB57TjEaCj26lKALw4i1rGfIJXYNUQsupXlFNll8WQsKy8XgCZ3NAjajkN59sspKGPDPg8Z2Yy5jzGWMuYwxl3l85jJ9ZXFQqi3Im+FyOudyhMlJBYMzWQ0FBeqIyVnSIPRYMIwNZKoeveS9KF3N9lQwO6jR8Sy6XDKbyHftVIoJB8TzvWFMegdQULI7YNvu8K/XzPK9Wmtjww+V0d2m4sPYyuoItGNgne2BAVBfEUkeYXkG8QgaZMoh04SFtHMokkvfFRhxi5Y4Kf+Cbi1QPid6u8FKBZgTBZ5AnIWP+lesDRDDFiAhw87KXRaiJSbFIwv6zVlEC8Cp8xF5Q6051iSOZ7mRDbntQk6uXg9A+BaEaK00EBI4OE6eEspBDj2HJ7UmfjjPdjq8c2yGdfEvbvkAkzjOEblwOeioxaz+EfkhJY4HXjziKaikgnP/DqLfreT05vSWkQkopyMO8fA8OykRwGHylJxRDffs2XDuRwG5czzbvztcMDWGvT0x7G3FP8OhB4m7RgCMkesD8LFcgnKNoG5QkNH0BnH0d2/4WuB0Ed7n4P7Kc0JHBQHSMF7xqQjZCuvhlgdFmhWLeh7GBXJd/MQJ5dy3HBS/3TnhvJDfJNcQu8h1Fk4ocqKeS/BdsiA3evhmIFaD2N2b7njsDs7Qteh61wY7Bus7wvp4Gw3S9xrpkS/u7IWgBL6bqmVuEslxJ5oZNTDislvmkh+swAnBpGlA5s5sPiALZjvRYkBc/+7Hw0V8o7ExGhujsTEaG6OxMRqbR8L/NBGTxqDXERckiP+GHNAHQaw64X7UjzAww90Y7sZwN4a7MdyN4W4Md3MA3A3ShZacTRgwujiOuAxgUhy/NCv4x0pEVCpjXFKlCPWouwodi5f4rY1IrCd2FmzIGbpmgBcaVpBtTRwXV44sHC8CHcOtw+4wu1jgc65pC4pdNkD1ywjwSncUtK53ENIQNNMOJ8CMkAmaxUOPdzSAsHigRICGJtT6yjxbTmZOPdtlweiT97AcVo3pPg52GK/8WO2/08iBIVt7Aftq8XWq8qbuCtmKkRc67joV4RCNbeaGdJ3aqEFap+LUcfEgNMPoj5mboWo0gEApxufirsY6Ak13F+N9+h4G4nZS92hwdCuOU6LrAPRKtBZ/+5woBP72/Uggxa/i4v0V793Rq9Oz85OTk8ERBLc8ff7y6fnZ82cnJ7ByhcVf/pQu/fTk5OQEFiueg/RGbEomcycNex3j53GQoUJNgt5mG5xQexwo/RS0cdq+jcijUTj3A+ef6Dp09OzkaftGpn4wcWybeduOpiuPSxLhtYia2WwZMAsenVVEDFsaKTLRZXyMaBJfpIpcCjepYuVhVAujaD8Bpkmr/6hf00BYhzBdOBFrmN/klztGs674ufQQ1TroWxRf+LHluxAlWYQBL+VAKwZNFGe4ncHvjhUtuOA/O64LrI0K6Kz+TsV0ZgHIOWBNruMD9T22Rv2XiajzKsA69z0JBJ1DIHUzRzyDBLV5sXLGMJeQqoqljksOUUSZwvRX+gAOGkm2b2WSHoG+8MPbs8ZGJgX7/aCQVh/4oGrEh4Nn6wDYIPmb2U74qAANU+y1lQrcUQfS8o0D319U8FeyGMFi4mGfhr0Snqu23qNGSDl7mHzbCAl61WXDkAipOnHY2uZcXe1mdQ6L+ojXYemaj3gdWOzCbFCf4Tomg2X1d2guOMDbkhgNjsEHon59Yu+2jLjaD6lLvGgxYQE8x0SbiVOI5BvACQNiVVlMG62opQ/2VIvonKGR0rcCfkU7YseDfzse6k8xKlbSe30fWuTndD+/5WYC5sbYa8P2z07+f/bedbttJEkXfZVs/tiWe5EySZG6uKdmbZWlqlK3bWkkud0XeUFJIEmiBAIsAJTE6uWz+iHmxzmv109yVkRkAgkgcSFF2a5uzt4zZRF5ibxFRsbli8/tVgzTYlXOmWo/uT1wWMECsk6BMxwP7SlL2UFNn92017naiEXDQrpOWBTHlehcpU830cVk6qnyaex2lUCWhQ9fCdhbPw/av+FIyC0L2ESfVnFMbdd8lQR/en75JsngI9naJbK1TWXgwWMsBRV5AW5EUpHL0EEmvCsZcCfzawP4kM/AmNVytxDjNJUK/gE3tIgyiu3X/8jc0LmbHG/w9W5t2VX2wk4IiOPQHYGmMyFAmfsUBWmJbN6DDHcKZjPeiQQMEvjR1ZuzdyytCcYIijvTjlQKKq2ISdiFiQ5lRiojAY63CrQrsmMTAa4fiwke6pnrQ73W665GjXjEODvnuHaKDCWfNFWyvRQEUdevl84eqfDLaJRfy+k6JkqoHBOPgK6oclqX9qnuEFOPMm9GWX8AjFVcKOPypOk89K61K8zYfZq6o4yE8ruuhgy0BcjNRn9qhKGz+pnviMcy0rQS1fu51xlxiLl0oSzeWlNBuL/qlqre13oelGSP65MIELTlzEd9reI8RaJxGyHmcspyKjcRdjMP5gsPJdcaerIFn8gUFwvXIVKUuaIj/InrCy0JYfEEe8HCGXtci//KjnR9Pl4IolfSRqvb3xO97nA8ELYYH3LnyOZ7PX64d9B3uvbecI9GMXc70RTw3kCzAT5fNuQ/WFpB6E5c30ruoOKgfqBzr/HLwPeWKtiYJU0lJch3ySEmxUFQi1174fFQK0tzeeMz9nt2++7tLeuwE/lROAyka0rXxuIpj9mDCEXSLAgBE/buLQr9qtJSNnVFrOksmfXVW5ZNsLSNfE959xe5kjSVjd1hapaketkg7ltsdNVcP7tW2MMuu4pJ/QtbGt4uoGCI5GSHAnwVamYYagKuecTvkV/FAU7nFY6KnfoO5XSlNJMz4ceycSzfoG3ugb5ruXL7lGGxroc0xH3Gwztwy4iYrFm6D3Dmnr4NqJncLrAxR6ZkhPm3053wc0k0z04yrGLAD4Q4dPY6jrO/1xnYYtQ5cobjjt0/ONzrHQ4Htjgwc6m037X5ajoI4K2dfn5ojjseZ3e0aXKhVMXd+HEqfHYLdN22acfTJZg9wumxWGuHFrUKhaGEpNdpMh5ZtGJQJ6oMHmMAqTQIRYabAVrR8FY4/oU/fioQrHadaWel83Z2goblhH3oJ8a8cTItP9veEXKR6udblayY7hrWqVqIGOjXuItB3crfKhaml4y+KDCYV/e9/AhIum7A0UF95PGR8CL2MIXbCyQ/GBxoArUabMYpxTbdaqBcR2Lo9xLWZXgLlI/ECwzX1DSIGqwClFp/BWDEMiGUAMiRKHMQClqWlGI+d3ftREbbtYNZUfpstxa++8tCnFF1aegQj3MvcETytzZiXAwLBla1eiD/YklcK/NZkV+efEZSivKrQwqJ+vWhcptaoZ+ury8YNdlwoX48vd7AygTwvzM3lt70xVGcz9yYaMUCnbELKauDMZOTipA26hYhD9B4KtwQBsM7Kp+AURbUujWcJgOMPSmqigOguka+rEmoSqlMpTu5e3/cOxiIoy7vjPlYdAb7g73OaDSyOwPeFc5gbB8OekPzlkx7X+VxQshB8C5bYM0Zf3wr/Ek8bb3e24eGuHPue0vlGpcdczpzFk3qb2/Z1JVojQWPF2ElYzh2HCaL7UQvlXOuut/Ru1d+Ji6PIosbsYl7L3yGN4AdhKQHcqJsfWD3qjIZL3bZTyDRcuYFwR3jNI1xMO9QZDkVylwjsLNm4EHsiJi7XsQCXz/eNpsJDldg2ZTK/k3TWWQAUlKJp6GIpoHnRLrRVB6FVIVG9pk2CaeO8G1hgYYjvOdeBHrk9ABkGiywlaRcpudPq/ObZN0bnlZddtrEac0QsCFhK3+FoPxZf4NgscoLBITrRJ4dLSuFpuQ+UjtEChDa74lYF4d8PHZtfD9Fu9LKFhU+eDyKrQWmVXIK8nBukJ3+lxmmXjcdqxQLsh/JB8KxOAw5MxZgtwCBCXZmiiLbTV+1hZGabX05FWxqTtTeHY00u6soHjWiSo2Q70r1+LqCtrHWt5y8vq7HHXY1Yoc5YsOFJyoe5Jgwjl7jlwtPbO5Jrvp9tkdVcvdb2LFRpCUOqWk5lS5a0rBBoWK1sRSFkEqpQwocqz2/ALPLHPSZjwhdU4SX9XO0Qr9W7oxb0oWoYgBnUja/zbOHWxyUAPBJ7LZkMBXdVstKOYeLStEJO5HzUTUY1PNgeynq5flc+KC4UVLgDsJgLuZewB0JT+kJHvrCeVm8gZWpPzGosZOFUNKUHfj3IoxU1uCp4E5bPfkliSCSocgZLebzIAReCcCZ6OHYSXtJYlXK2JQ+AU8QQZVzl9lckrp+PZl1pCdfMZAwzhmvfws2kuwbpQ8DUYF5HRm2ormzVop3BAtbHObTxlbnuZqjNGfTN5QA60xxFISPCIJEckQoyAq3Kds5uzpnh/vd3kt6mczD4N6FwwXBaSzEzKWYkDSjCNC9d6VTKrOXtgeBYvYU1FZ82WYBeHM9uBEoY2WnGCvpRlKHK5xd9iGiNkHyTzRx0taZvPSyPaZ9lD5RQlQENXjPOqTZTzdWv9sfdrrDTrdXNs9BOOG++2uDd0Fh4+hVS3ZPvvUvuoXioDiaU99ptH1KliIOnrgQe6ULcd9/+p5XftfMHbPbOLiFzQnuYAzvI9AeAOPnXuBPSDyAQm0mWXXyOic0ZykpKWzkWeDH011GcgaCqNhTHk4Q1dMNHLbzAH3YgR8tZrSzp3AZw3XWRvuFOlpUng6o8nvB0dH5dCO214PjUCrFP+t5uO8/ad9klwAobbAIWCy3DAEwhG9htje55cEPLZoL3+nMA8+1XZF3JFvxzmI76h8xn7x83hvMQLuBBZlGCMm7ZIBzgwcjZUtUmRJTNxl2om2PYRdTfWOS71FwL1iv20VDoUwvwWP8JeTSBZmDaAe6M0J7MK0zEVj5+kzWFh6ciXyXeX32KiaCct0uLdqSBkYnwN08xY433MsdupdlS2BSUv/U8AiwTLkOgHqv2tPJ0FqSFkt2b2HTmu6j7Dv3PFJllO2csTVTqeOLr1YstmS3Uqi/JT48VQeWXKsCvw3WfiV7wAPh9vSaT2532f8sAmAxO7c3rb2b1u1LfFuMYHvs3O7dvtTTwysofjGHrcE+Cn7HoJWI7dx+fKXXv/39rTJFJ1MLLw3cGXJuz8add9J8t44YjN1VHSWamCa8AivKiSzhC2ljG2YLacM4lFA8ruiUdXay2YfGzPXV24HO58L1nChL1DMxTupJh8FI+/8e/vNhUfoMxGJWoh55Qv9aS1r/J2LuBcufguBOEZHzK8DvbAqmiA8fUDFm8iDAUhaU2githfY0ii9qtaEgnkh1qObzsEE1qKJEJoitcE1Fs0mi99yM2nOoqz373eLNI6kj1y/TcbtG5R/8DTKDEnJlhTYkaLenwGQ5+xiEd4j9h1lOggefhTJxvImZUAMbOCviEZw0uGcRlbkzcynmwZvA98nhpuLwhGIegDuWLLmRrWlsUyPuCil+jwTk5/2nxYz7HVByYsQMeYTQ5D/gRJewPDkLT/I9kOTpTRWovuYT82aR20DbMztqidSPZycvK4mP+eR5d8V16E4mIqzYDjGV2Mg2yLSF8SJ21QV3/MXUaCrkpdcnr2LypQnABg8axRXVfpu+hVd0ibYjPuuQX2NHRuDpatNa460K6n0G/WoFaZkHkeN9mUAh6MfQNRhhfcmMDB0nn5/SbdKI6vR5NdumkfpRB9LUhU5kSbWmFU25EzyAOxUHHWWZdbiseKX/Kr0og0SFSpWZqqwMFbfwwy0bo4E5GJP9hugs2jKuhGB/v8KG0IiLo/m0M43jefT61SsHnD/ASBHl3ONeOX70aoaOrx1tHl6FYixCcLh4FclG1aeXhCC3uhEIYwk7gCplUVNmV9T3V2qQZydsJxQ2MP+XNF/gkhJnGIEYjkaD/YPuAT/s9vcPDw97fWfo9Oyj8cHRwYEzKBGaVmI8OeJLWcjfIEq7lkc/dQNrlOT2MX1RQZ2VzLp4o8C9/Hzqnxxp1YSnHtNm2TMI0e8pKVampzB7Xpclq8w7T+eI2lBo9nqPiTTyuOphkae41MciGw5d8K9gSqWGWg4Q5SHM7WluF1q4dpkPhgytqxoSRYab9F4YMR6LcIa3N3k5I5wCMa1d9r2Y8nsXXN34UmqCykYke2nCEFLKFiMJ3VJpypah7dKEpcBe0AwGSjiBFmap50bGCQo6qfDWa9/4oZhQxFW2atmQUvIqTM4wrqngXjy1p8K+i76Q71ASYF++tbNUPcV5iL0D6+UIPCRn4EA59wQl51xjexcJ7w/LNzS6Fbl8lsgY4nGuIH7qfR8oAam37MhaDAPuo4IkUHbh5fpc0fEADrLXiVz/bhp4NTYHs9eQEqq/pNk8T3Xu2il89ichhcuvOihZk4HHVslwtMbXe/I4Yq/PxbDf3TvoD4TTPXRsu78vjg56fOD0+2PjkNS/1hiTqlqmVdBaXm9AR3uwz/bFUfdIDPYH4tA+POKHw8Ph0Xhv39mzjQMqFb4a77pnfNXV7Lc7PnP9wBL+vRsGPsSZGUdyqURv00C0yiWDyDW/mpgrSWzySpaqpydOZ5EET1P2n3wFNYOi4QQuVmGk4W0wYafgJR4KeQGLCipkgfWogDdFzTQgOFRp72suQjCZLzzPolj5P4nlmfMTWarUQzhvuLrsd46xcOdPYtk5W/8Qqa6P067zJK2mg2I7e/0O2P65DW58U/HIaKTPaO7WBiGVevoQRgv7TsSUgKF4/PuMvqOGt+w+pyJPpu97akYnTvhOCWXgwYFuYK7PLn94s7e3d8TIeaGMSuE/fQqv3ZmIYj6byy4zxKLJvYTccmEwg5zRzJLfhNK3hMCukTcPxdh9rF1oKsa8YEImZZTnHbbwHU2LkJdLsc7KNF5QNZ3ISNihiJPjVn/Or7CCdtyfvMZXWRKy5IErVckUkmPXanuSEoo+y64kPZrTccRYAKro/cID9CkCo+qkgdIZVf9KPqybvOSaUvtmEUZBaRiQTV8rjeep422v2x8UrelNKXmrPIDW9L4xG0F7RbVDU4LOcSNy78wRs3kQC99ewvYtxjPKcrvsajGfe0tyLaejBdwo4mMhgxmXjCvgQM0VDn3VbsnMp1vhyDUO2nQ1v6SCU0lKnjyuzRarf7j+WoGZNXLBseiHSnAqsIg2c49LjGWrk1DqoIH22CfFvq5CECScrj5NkA7Z+pJHCkgqnR2k5ovOTuUJR3K+xjEHygAmZ2GAlrwUc8FjLUwE3EfIaZ7ZObw38hrbbeViTMtBZhbZCBHuL8/HCNaolNYJxGiLILXm9M9w4fu0HHCFeYJ+BdxY+iwdGeE7923hwc+finGz/ygG7j5vh9m44c8A1BrFS4qZDUKExpwFvoiVP7wyVz+nabSkw8zLPlMGlECdGhUFwazA+3nOl/BUr1IdPTUOMENdFeXwViyfy6dqR0xd5Wj55WsFFlXTrZNVpDiyDYJpAO7/MiKY3cpY3lup2SfVbgKCi8Cz0gc18BwRxR0E+rvxd3hkCx9yer38gx4+Ix6SQmwHeqZCbdxRkv1JO60R1xNNXSspgGGkSUTy2BixRzdbzn8uTZEWCo8vIyYbwSe4HXtLhq2hQHTjX/7whqEIHyvxmu3Ey7kLyM9LMoqrqZTGKXmKID4a3eVufIleYGuWuTbIWGMRS8uLLx7p94opyo61sft+BwjP+/Dvd7p7nf7BdW/4utt93e3+rZWfUUrhtrEplRnhnjintL2aTiq67wWLqOnEyiE/18z+HLsGBozx2ppWdefn2GX/+uf/sr0+6oUSLVFUphuCdtdTd4/3eG/Ut/ecgRiO9w8Oj7rZvxPSVzNv4Q5IFBqanSsT3BBrsSs8FDe+7fHZHK1IzI3NUQ6lS7iixTcT6mDATy1IZcEvFo6rRDvu8aVB07/TeAmTttd0katcxaMurmMAjjcdmbRRv1eLEgGqb8udL55662Ypyd1fenAhZUV5KybcXl4kzAYVL5HZUZnKsmA8Bv33PLUKp0bWJHyUwrTUzrlNtudIeMED6+ElGEs+xqMbv7fLJPNLGR+L+Z2IgNPYAsFg6FmciKQZwVpChK/jb7HSzJR5cRsmJ3J/FeVTk5kWDERKjyhaeMFl4cbvdXrd7nNOToPDbZ6gc+0XSGkhI+/eJBh6Uu1VnCuJvIAXuXSZyTSvpgCzpCI8kgTmS0L0Jabpja/ZlJuMNgX4U2jvNW4fawxbL/CsY89HE684AXr1zc/Ch6gCc2MToweE6N0b/8Y/e3dxfnl9/P76NfsjnTWbLyIIRc+0zW7U4KObFuMStjrC0E8O/jWAgi78mApjtsUlUzkx5Y/w1HfvXU9MEEmC9AlYMMHeuPHhahWuv8uOywhw/UlKQuTOQEMIoFuRjJMlwqS2go2W0CaPC9HjK643tLupdTZ5rZ9r4KzZRUWOl0UQPDuJICpgl7nOd+Mg+D+u892Ihy/BsdV3Uk8d4SE+a3Tjj6BtUL0QOKcKJEYJtqGGxTW6wayUw6N6gs5OKO9pToXReFbNcSA7No8g2bQfubF7L16yJocohyTqRkz8suAefOI3fgYVOpRYb022k/T+3sgegtFKfmHQs9GoXf9p41YnPoOEfeOvPuhd1dImR3/qO9FH14TEtJnRC8APxMP35OELReoGh4/WvGedALT9qSl44rbfjVJyNzQJFxxe1yZeuvo9iVoycDLt6AVvfIXelXDezC0C9+dNC/IO3bQohu8e0M2kYiAOEtU2+SPp+Ei77CyWt9ZNC+f9xs9fuVMO9yvUAS3CjrsrduH5iR29CIMgfpEp/3L3ptVYpocmd3MsPVWYP42Jt1MFOMyNQXX9ybzQ8DZArUP6jrpyfy1xyeYzyvemAj9LkAt63VUeOha8Oqpf6mWv8W7jMV1T3qhClIHPgjn/BXfOHT5GpJYzyW6Dejvc0Ul2O8raMBX+ja89kTwvCwCU6PBwy14kCZZAWsIn0zg9MaqidMhH+KIQ/LcREwxAEuCRBHkDFJZkyiQnkvaVppzSaFUzhTlfduYi7Nghf/CqHN5SVfcm7f+YtgtwMjAjloI6zRJ1cfHhHHHNgtBE2BXWZaoOiNiBLF6vl1clVw7E10G8MmbPvX7TQdXGgD8H+GWRijLNweXz4F328oq3agrLHA9/pSCnjTkblqxZEAGmMPIbeTaM4cVmh78UYUhAvMedeiIov4osPud+b3DYP+w5h/xoz+l2+2LcH/Sdw1HXGY6Pxvsb9rrJjCy0p+69KQIg+VJiwEk/VwZzZDqLwJvVMYjWCvjSRSMShNnFYKRFzCTICg4PInwAR+TnGpEbSwCiVPIyK7d1my1Q5BFrFJ8LL7A80KchGieH2awP/KQ8nKw678bmY8p0sn6g6T5zvl/GJQLBrevcUjoOuTYFvBqMCYV5UkYbzCUru1G1ojQ65MY/k+IWQODsDzrCtwO4YWsZtmxrbXeQ0VLmujHNgdxxxth3BosOp1qSuEyycfyQ27ClkRf0+emeLJWkP+Fg5QusfsY0gHN70Nsf2XuHnYOhM+oM+sNxh4v+sGPvHYyGznho7x1Afp3RcDisLfapLImI3AvpzH6Jg5yb8vPQMQPHAv7IWMFyg1iCmnA83uomkE29iNJF2b3xP2bKjZbsRShmwnHpbUQOOS9k1iG0qAUoSUJgFvMDvxPF3INbJqnDfg5GcNwAZc51IJsO5tvyBHyI2I6y3CYGW5HQ8yJifDz2XMIJAQvoy5yRBFJXAZ1+wIg0vPcS8ueLcB5E5Sy4CGxeysWydIDnD7Dv3ST0Pz9HpczuKUummNnTxyNbUvQnu1jp/1F4IjhfVcaDHGmxVZyJSNwLTKFbNuTr5byErwEgktQ75HhbMlgGQ6hhyFDkWVgbUV7ief1bId/AlY+Jj7KUjyqVCgwpqhzMTlQKbJobUJVicIURXJVEPOeuFmgfrxVf5omCsJe8yiyfIqp0KI0CoEsI/rPwHZlMvhnF91hhheuOnYLQQxopCOYeCSbcJFE8NcfgrLOdH8/Pf3x7an08v/zT1cXxm9OXTL4MxqErfMeT85VIVKOlfCdwh4UB5uTd+TEIJh6BGEVzbouXTVUB93ImnmpjqJ7oU2BqJiuDXu2MEhqWLwpcHOpWk9kPU4bLrgQiMFNAusoEFQnBblrchp0FykIcSomhRXa/wmvlLOXBFfpQkqM0fs1SjLlCAHRSyDIbfhoeznf88Ti5Bk64SXZX2tqAAaJZKoaT1c5GLypEjw9C/epPbxfEl91lb7hPkeqJAxTI/AoqV8a5QCPcZ2IegCeW8vEqO9oz/mi6xVbxwSpMiOtvckKUP+AXmg/X3/R8nI8A0ana3D9asiAthswwdbvDySmTcrTGm8g6x3A+QT5pt878SKLvnUXRQhQlFrM66lj37FEYJ+S5nMV9QIjmNTVnBVLqwRELwXwbUZgVCEEk0goBLi8tbAAwdTV+dBEGzsIu96oZLcFoA0WYzWMxQdTfJltN1mq0zVAP12q3rjg3SP+X6QuBwijEio9l/aGVf17Rk2MF+eHGhxwDL/zAFy80S0HaISr//SDfUwScRSuVmBZ16uSDD1+Cuzf++yAWr5/65Esu5AyyjXrftdloEcuwUTCTSKSPBCNMf8NGL6TSgTLbAFnfwe7LqRDmQu0LPZoDJoySrtXLPlqfVqSWvIkglJjZoLO2Rsk8DCA6lP64lymXyiJOiva5GgGpTMw+TjB3RDjbmLh8pR6NFWc2eViW9Zl8bnA6QzcGf+9Wu/WTOwFK3wnHXUAKgLfBQ/G8XsVByCcCbPIo8prYXw4tWh3bh2kQCe2UxAETj3Au22o/wvSz2//KymP/3fmv3Pvpv293b/xrfgdaUO09DhpRxNJWj3j4ITEnpsyjgTIUzNMO+zmgwjNl85su51Nl70sic+X/dAz/R/5Pr9OgUL8ES4XmGyM6ccLXsKGMReh30nx22UdpJ2kZ3JBzq32NjZXvxObCCZLVaEMGfkxpti+IkOIepOdNFV30viohJfnYzEu62HP6sNK/fRQjgJVeQR54oBrM1tO2l4gHsuzT5YOwb9njTtjv/LwI3chxS8wff9S+yvuM8oNKWClAyieEArheJgsecj8WZF8fKZiC0qhjAwXNUgaof6X7Rftl0Wq3MCxyLJyQz+bpvzpT4G24kUKAC3Nn4s6NAc/C/CgRKiGJ67O//vWvf+28e9c5OZGviPT4S1FFEvePFkoRFH7S73SPOv3+NcaeJOEnJUAY9W+LTGiLue3cwACFwGw6En4mZROIDgTMvQwW7IEbUirNhIjpuQ/1se5MuqqnzkLyuVWL+mHJaJ2VH1L6ACVFa8A9yZpZJj4cdsXhoNvtiP7RqDPoOYMOP+jtdwaD/f3hcDAABm0+lxohqxl7DaMx3qVJNKgs9IxkwAPoPabn4Z4XPJzO5vHyz7SlFXBrIZmGjo4PV21uJy2DRSgjHEhY0p5mI8EcN5p7fFmeNwV9ZnwjCkCCsJd1SsoOCJz43DmHNIUpnkbZse297nVLj2mmrWZHNWmvjCYIBf0eRT2jHBeEsTVqJsaBqCKcY+BNjrxIiuxunr6cGy1w8UH9hHwDDZaLADldf7K5eXH9++BOEDMszEfaX0kAv6aR8VF1jrmwk2osicNv8u4xBO3XvXTO3v/5/E+noLa8PH1zfnly9v7HVrv14eLt+XHm31jk9PLy/BL/dXH84er0xPTSyU1AGWYqQunSeSXXeekCy/4aLJjNffVxESlRRvIfDF4PWezG3tMgVDNUbmw3zFwfFPdvMLEXQQ7Qk/s4Lu4OaDgxSpb23Ny0eHz1ptVunZxevTH0Bf7CZlEkShPUPU0Y6fYaCCPY2zriSKH1wvDKBZIohWr6CiIJDXkTQkmUsJHVzn9hq7w9+/MpnOj3cLLlZpm4URzysIPpV7nvjIJHiQZjpZF+Ch/GgDKk+driRc3TsGz16n0RsVvi9Bak2NylxuCxfcGjiIT+xNvbEDOv41mz85kbs50gBFd6SB3mMwHXjcLXS+QxCiWX7rplgeErod70h/urTFkFpDhCNSTfkeRkfLrbdQLFQG4J5QNp5iKWPnfISazMZazpCMujxvP5hDarMG+UUb1XGMl2Wzfe1v++2/k3uo0psrMTTTkMvmoxMv6lEWLCkH7lae6lzSc7R6pCAQ+F7c5dQAiW6d2LT1KZmyQpyajkqnjjhZ4qcWcyOURqRiDja6tIl0VWp1m1vSFiYz6JSlITn6U5YEKEgShSy2753L1Fp5SISiT6bsilJdMH/YHdztwwDEJVkjMvsLnXZuJe+PEC0V7QDzGKyYw291yb77KzcdKUFwR3izkDI0rUzhCBOQgidgvd39bNXzrcRt6FcxcfjEB7yba9c/1yHxCcObQSQrEy2rCJptrgAgHYB5FhJDAw+zXiy0IjUGYNlQs8ce/hQgOvx/V9GrVEq/TK0WZW+i6qD+a5rU3xkL02bnu30jeTklJsIKdJvyxspt1SplwI4jMz3yb3hdJpm1ByMmPrdxsOboMpT1YdsPpBe4iUHwuNB4JJkSzl5U+k/NNlpTOSJ6ya+rjK6GSgPVOxbAjZ1p8+EmymfhwrLUK2ZqORPN2FsMEQ8473RR7YYL99gW1GrLhqj8WmQLEClYC4pHuSAiICeZHe3onld/jjLdtBR1kRqYpk3sZLOAUi4TG7E8tX1M6cuyG6mUIzt5ikXhSawTpTfk9YIVSRHhXU1kvIwYSerYRxIZw/pG4tcAnfpnHXBBZ0/P4E7XITzC6XpnDqd4vl5xjmpIXC1SJlUPrNBjrNNC+bf/+ddCAiaTaLK9wzYH/O+OMZNdTvGtw1DOscTkTcgJPI9U5Kl21NvcEn7k+9qcwmjflkgmnOSx67ZsS/9d+W2oos/zj9a//9vfNx2P1L37s7+zl4fPfzu+7767/unZ/cPYz/x0xpeaJ1yHKubd5gHrszN4pdG84GQQXaKHPGYeBJ6EsV0k3iJciu6FToeTc+OLSMlxmcQUUMJlRn6hBJ1ykOSNqJmT10wUNUIiPe+INeH1IS24HvuPgA+wE9g5g7VnItNQyIBCMhfDYLHNInRi5EYEEh7PQB0MiCERx1iN5B1YCO3g0jX/hJP9wjUiLtQV2R473Jwt207nuvL79/fx/0Pv76t0FweflL9+NRZ3oHqEHmNatigZnbCKR+G+gNXQ5aVh3QAY0AGgtKORB61bbJYeb4/QkkLnBtNhLxA8xkymkwNl/65cHMLv2YP76+8Tvs97+HLCHgR/77379GDvXdf92J5X/fsg67VGuDul7kkuqBcieWbEfsTnbbVCflMLcv02ZxS2bb/e6/8Me69sktjlTLttzaen+Kq6ne3qkZkZL9zvnly0LHvf9u/9d9v7Rr1S3cBNIKrFoz9NyOYmALE0XBewHQfjAx2dn8Xcl0ArpV5ZT+TsUWG3owTOzvyme20FXd7IJuKPB/990i6iC+bQ9IuPGTSYY2cteeHcxGcDBze5EO3wYvtsJlpXtL6tecWiftn2rJWu3W77TA7cJocw+05CzXuGclrKzyalvrTlMkGATihSciEUfWSbi8XBg0X38mD03pHSilDVylYBGDBAJ6CGDelIoxondXRIEmt7Bgt8DNSfsgBSYfrDNeCirW73bVP6Xu9zUDeJbbP4D7yzxwQV9VUnOA95Lrk0I4/blUMRcurXBRmT2xAJtc7pYn/VcFnlnYTpSDJeqgS9WKmVufK8f20eGwLh1JBo3jc2EcX1MzilrQctVollDMcF4kUgPrtnlkc0d0HAGuxhHjnsdkG0qfQ1k4pXCC5ZRwQl/cOBLeePfGz2b1SEpyjCFWloYgFLvsozwvWaSlNuNxDOWw/eDGJ6KKDch9HbFB96hcwU+D38zGltNU3NLVGjI5kV9PRRbMZuSPmhZRAiG0rUU1Z4dVrz3biH4sdacxqIhyFD1NIbY5jVeJkqt+BJEdzEVkEQVmVEm1YRIgSdooVJPQokZpWGfTgE2qvpLzDmXkgTrctSTIMm65R5kfI4pwe6GqgAo+iJH0jmkUpZCbm+oEyGpeyGeHq9AWar6tBY9wOwyiiKJfwQteHoAnufPkKYW/jFcYZfuqv8HSJta7wPbGzuFwfDAY7fUPBv1xbzQe7w/44bDbPXIc3j2ov8Do/xrHQCy9dgiqgfVG0CAjWKMRVHNfKPIN2Cc0lqs4LebW7kBglQiVVFSarWgDqT7yXebg0gsUAW7V22DyfUn6BimkCx98miIp6jp6egY9KYNK1FAalr9eyoQqwt8QRd9XRiJhKK4dK/XkjDv0pKtOoi4HW+21V0lbtTuIbU6N8SESSoMEn6V2CuylmndIknsn70WytqKtaiA/wAmSM103zxIDBSEQebJjyiEnhOdYslAjY2uifQdoNMv2eBTBY1zzJS4bRQl0i5boJuNqgiGWPLJfkGoQs9pIf5kgZC+gEfpEuWzo0ybYTL3cbxzeCgHHm3Y3qUgZ36si+QoUlY2ZjgyMT5LtrMR5UCe6CcYDjvG+aR9RnAF+zOA51N6wqsWVLliVzMyN7lBHbN4bsmkEzmvIjZRjRmP/NFIoGxzKNsmJ9IE02OjzUMzcxSxZD8L9K2x/lasiSHPH9BL/XJ5qi4MxG36tswKAlKUCw1NTq9RJCzPAh54ij659J+K85wAVSnUhteEX5TCkGaJWSjSUX/13m1vpIt1VCz2EccSCz6KOI8D1KbLUf8HmRv+2UDWhPLAMdrYcNoCCgOJOYseBcwpMDZVUcCNH02DhgfhWiLGnPjWXrdTocZ8kdHnNblqAd2xFQviWcoREsYVwIW5a5UoaNZDqg18+K3p3X3Zu9J4bzNDzTgUMJfmDpoEQjDITVOFUCNBSj/RP2Yy03mArmcHKsAW5p8HB4KYF+t6bFuskeTFAm1HfUEMFhnEozSKo1JSiQhp6ox8+rTSVjTy4IYLc5ppuFGLlAM8CcvXKQOQkb5EqhX7acAshK4LQrGiXHWelfGmuVLba9DIu3rtSzjb4hTbKodLkDm48aVMeZU9nncEHzWkyJt+wW+C6DmwXT26iH6Mumw7QTFLTazE78mI7K82OSfeigX9lYvYkFwbw1I0mgDEE2DWnf3sBGefFTIeVAiTVHIA0ZFoOPRIxxoqBh8nY9QQcA3fip/nTkinSht3wPFROWj7nRPFdU0vrbgEKNw/qkIk47o3Ho8P9cWdv3LU7g73ufmc04P2O2O+PDw/6o97+Pl93MVAtAKkRvLoFwMwNUAdR1l9EDGutPqOYtot63NDWKhdrr7UsmKloq67f1Bri+pA6xfUn3uqXQ7MXTbq6rh/vD1YbYI0RYKQkCuaIGFz5G9s/mmj5V6BS+GWpgotbCYtrOolOYrvMiEjprjNpMpoPNCFtk4Mty+K7gdEaVcYrDbdWebzaeGVAtvGIyd2X4DlngPXZaNmY7hWivhWWM8Z7exhwdA9OJugvUMJt0p8xxLpEek4yQccrSsNa6HhNlN5KE7ICbndO99mY8ir3wRxOglxrFbh0J5avE49QiMdmJ3Ivo2IIPTjRdyJJ7QM1N+yFXOWsJfx7Nwx8MHa+zjhujT0h4tcPPBTTYBEh0F3qkNzr1sxfZtNsX0OrMBbT1EkdTrUY+PH48iKV+ZuSK19ClRDAa1BcTWrmfZaj9Qs/T4zE/6dqgkyT8W8oPhqH+XwvrXWeWL/ht5RpdldS6GTOBQkviTNvM7DVr6SqMY287HFSMtwv/EQxU7zBh0qmg2/ouVI68I09WspG/vWfLsaxVz1gMjv0iz5jkD3hI0U+aKoeLCu8TEqn4DfyPjHSXwvolllHhROuR3y/oDffi8YDbA7vRC3Ds9Lz0MKMGHVrDRSVctUXNWY6bCxY4qZaX7pcRHwiOtzn3jJ27agyXOEq5r7DQ4dpmRqn4pHxYhgDWsuOL86Y9KNlccj9yJNBJC6h1lC2jxAkT38xE6Frg0ggecw4CB84ofZJUWTE7TuAQpUgGZoouXHfwfys5LwB8p/JF7d8+4rHeQh45zK5MwY7qlHhcu6yH1CseU0c6jsKWQa7vLTGyx7US1CFSlUEAkiSmvmmGkfluTPXkIqg6E/g8JgzFaKT5jm+Jl/DBS1vzvfAEXPMYB74EjY/FiGnIBIVexgrnDjCmNtBx6VXCz92vZfo6AwfLUd4MWeTkPuQ+9uNlxhqhH1QirWFb+N7B+fbjRgOK4leEgBVoiJJtd5InwC6DtSM6CME5xhK3g0NITBnVL4QNIvNXO3Ru748yWvRRSa/ZDNA3LMNG7Hs8ScrwOTIB1gRsub4nrsepgdWpWnx1Nqp+Kxd9r3reXBgkSwWySQOr8FnXfDZOwJz/LMrHiBmGAh5C5Pj+pNLmav5GCYTPnoBd77nHvdt15/8z0KA+1ub8XASHNu28ASOApJtQugq+e2rNpIf/vTnSwDPaTN3xifiUkTur1pXbYxejMPFDJu5Bv40FpC7ps0w38EHRCSm39WrGFJT4FheYZEmAy3fGWqxmh1RQ9PGUxuZPQmvELIxKOxz5a1GsKE7uAki91683E1z8aSSXubC3WfTYBFGevYLFesNNcoHvpYHYg7Dcs+IYZmfjJRDGIRDmISF72KUIp9MQoqNpSXVUvOALjQOdtkJ8IBQAOASOjNGwMfD4NGd8Vh4S9Y7ZLPAj6fSVUSMx4IM+mZGmeQpy3FCbW2Ax2mMjUXCEzZA2cBtweR0tHWFIiyIt8xUCiAoP6ENkL88R3E3tpjD4P+f3l672+3q5P0BEzemXC4NJI8DZvN5wseBRnAce0BmCzqjMAn0lAndEhZcviO0dWp2GmCgGVdh+YOS2NR3lH8ehLjDiAQfxYRfFjyk99dScAlTld84eMsU98wpcL1NnqHmh4Yo2tCh2a86NMqVsrH8J9OIlwt/EHPs3WuiHww7ePApeomER7zQUyFRHstnEhGf6i1aIx/eLzy/E9nc99NQly8SAFxFc4aoKoLtUOBX7hlpfpN8ric729TT8mCU0RiVRKZpdEZNItSKTW6Q3i/jM2zwsi44DWfJahBg+lyhEqXInMMCmfBfM0eC91B94J6svsH1lJhAmgXSnNkCizGtWD215qafRvsDRzE7DILZt+O+niHqN+y+Lp8bFoDgSj8FS8IEFUYjXx/CwfsRuDSP3ZHrgaSmIONvU8z4v++GwhM8Ep9uVUbMnQ/Xb17SFRvMpd1OFmLRYjx2HxWaWcTgMRVC5mDmiRjUAX9AWSWRHG/73f5+p9ftdHu7mGPzFlF+IImUg0lyQd7jExbMhdIFy10o83Zm0nxqrd1WICYB9HXqztEQsj5DJWmu5L0GVTnn6prtlCWYSZVUBqPS+lG6CCjvQCC7OpePHQzqggdzAsCHBHoijDsJxqAkgcL3KSfeXISxa0AgrL7XoW29+Od2S2ZpsWjGG1TXy39uS+WRRfurFpAQWsjV+KymuL6mtE3pk2SNAsegzX8nInybwdeCPdoP4iT4kUUy/L18ma+u3jIbphvrEHSYeJwjf82QguLnPTe8Bc7V6VMoSNR3MGbT4IEF41j4pA3rYEup00bEMdetjTdBG6GVpAYBjhM41FCFBFSyIiq+C7i8lTuuxGJ5KcagT4wDmbcBgYUJbSEO3ckEQsXYe31SYZOAy0+aVEQ9EZUCCFqD644nCiNtILKfGFxgsBsIScd0ETzRRs2DKHJHCQRX9dgXvgtsBMS1yLOQfmUwTfT2o0UETmAwtzQbCZKDZS+iOJhZ2iawcANkLK/cuYfUh47lOEFk8Tjm9p3lDdK2jN8Pit+ncTyX64Eax1a7NZrMran7M9TQNy98ITWaha+MpK2RF+SKWvRTKGYBwVAZivjigYqZP0Noo3iwQvEzahagUBBbccjHY9e2Rjxy7ZSAkPuONQ+DmCxJ5R8cdyKimLz37Dv0wZKDHz9Y3A9mHANTTF9hFfUS8NAETBsLXmxS05GfL9t3rRmHk+rDbBc+00onr7X0JxirI/LDkR9hV2V2h77DHIGuXsKpK4a+T3bg+0Imb1ajS7rL7Kzc3wdkA3IJjZIetRY6myXVAeAbvnrBZL6IptbPwQj4ORw/Jy00mll8EQcWd+6B1khIiBz44ASRI3uUv9wH3oK0k+nvU8ibMrXsqbDvpLkuP9HTIIrhCrF4MG92vvRj4UxEcja034PQnbh+8gV1ufmO6cdQangLXyWrTWYDlMvWSGmXLTmykq/zIPAs4cN8zrKNTAIC00x+mvGJa1vxwveFZ2XmCzdFUuKB+9lS+CXdv7SFcqOYxV6UmU1CA6meX5ByI9meojLkDg/zrUNWHDXVs8B340DyW7oz5E9ySYCn2IEjJFpBeoSiigqwOaq+z7jn2hBmvUJJKtGs7CL0Kss9Wh4KdSlAXnWNTGIBxCbl4dJy/MjinmfNQ3fGwWhhyfNZKFVf4oGHvul3VF5FC7zGxgvPW1qLuSNRVwwlVX7lwM+2iOHOlkuJ5KNke4Ds5MLWTH5Aw4PlgT+1vmtw4Es/nooYdj3wZVDd+XbK2vKfgwdLygb44knKqfuGWCPMSfIlc5jUMZK/0rCTXysEggcxsgpWMlm/1SZ1YEOm9alG3oo6SgFu2YHnpZh51QI/8rdGovaMxOCos4dAy/Kv1WvKHVQUDT9OhUQBIC2uDSIpIJikey4VzEpSaCQyGPzxiaAwZZqz/Dwk9f7ROkcGxN6lDOj13/PUQdJr5ol74UX4yH98ZD9dX1+QITcCaAxMYUm8DCTI7GNI9XGKdt9LkP2P1SWZe/X8/R+txPRJ8Ait1wBJ2QZr6pyHbhT45/gyBs/w1nfftdqtP4mlVC/D8bgE9gieiR14lhma+/s/Wie5sB+84ztvYYDsHOcI5ORgzI6OdkEcODsBOEf4N7S4Su1DrfZh6/OnknH8dzqOyAu0UXQ7PawlF7Dsjv4My506FV9ktnkjhPv8azl5TUqPFpkWUanD/p5s5bY6Rtq5+KQO59xNTmZnezLzJxNjCJqQqhXv9FsbWInZ7HlWYd01+NIrsJkZ7PT/03fyhuYRpLEFOdE2nc00JOkfLRvd9Q663b2kP7CmBCwMFnFqKv5weYa8dOb6SSaF9m97a0tXS7km+NemF2W1TZ4ztSZaJnL5Uv1qSqaCv2S25WQ5i03HEMSl/UhOAm6keqnWZJl3R27qVO/pBZxMAOVOl+FtKoGZvj9WHp/BJbu2Tz0071PVRjujMDnCCTdvuTEmeNj8dmuyx/a+6aNf5MjarK/azG+LF1AUlml1aoVJ432p+oC3XMcLJh1egm9+QfGtUSY+jo8IzBt9XOGHuQjhKyE8rmTdyXOTaIoe+3l2UtmTga0cOw57J9CcmXmAmWIk4Fu2l7YezirXCmx98phUd63WFhiHMYv0sRZ7ovWDAbLaSGHLecFkYh5qvcPToNMddPr7172D13u9192Dv+mWKfO0U+vkykYlRjLxgaQpAfRsuAwU2aGZuPT9FoSdEY9M9ni152RQVXa/YbrtIKVAo69+94F5WDyWbAX5EcxqicFGXw3Xd2NXOvN1KJvla+XprcroZIXBYjJVfITM1knWkNTjhjCQoC5YwygMWuvCgvRbhW74AoxJMenhJeCW7pr2oxeMuIf8609imTaG+vNmzflYGytQfYdH06YD1kiBaqOAh3JIAfTVlILz4wUAP6U0yNe2zZtPi8+k2uPNMYT1k3W+fMsCuYWsnnId5L+QHvSwxKI4IvivThuy8RIAGnSRhU8a12m2q4vHX4VUpQMAra/4v/LvXTtA9PUyz4A0DLWGBkivyik8x/S9TSKfQqyPp8INATtXBfOUz/d4fzR0RHevvz8aDXuH/dEhHxwOukJ0e8I+OBgg9XOLO05ovK5xFBdMflejUYlakGE1nVQtnPbocHfQ2+31j3Z7+/vIONHwVDaNyUmBCdUZeRCmXAUTcCf7B+4T3DlFSpLulA9DVYcIff/0LoscOuQPFaw55A8lIoGaenBq1aPGaxjz2Aq5OYz7OstPLvkSZlmJlFoCwPL1PBRHo5693xXjI9GzjzjJkfE0KOkOtapUILejqvu5OL+6RuGSbIQkFZd2kCQlpuIMiqe+8TJiFa6OtE9jjgrIMrgIXXNPHy7PVhrCK+ksFL0ajEZ7e4PxgX00sAe8f8S7g+G4u3c0GIy7B30xfDVDAQslHQzt4xMwRpivVowGfxERB8GCStqIyPlCAvw1ovFd8KvrefzVcLfLdt5xG4IUoukf2JkfC4+94zY7v2J/Yb2u1RtaBy/ZFR/z0H213x3u9nZ7Q8Nub+CWxBvqTMuEzWMmHwvElNzkJehmBFyZEgeur8ybY7dWJ/QVxDuygUroAjmtdkxgMTXPyIZXI+6Xlbh4xdU4c+2p8Ly1b8dyOr7y9fj1rkXjhrvOInsGYTtRd3Acdltn6MfOzPXb6Evps+NFHMxQertaRrGY1fhBRUKPfJF/cmiw1W6lfUCgS8k6H2eOBal2vGXqqiwPCDAKeI5V0+MMR93xHnhs9vf6ncFg2O8cHg4PO73u4dHIOejtH4oxrhh41o25KVgNXwmUCE8uGlpza567F2fySuMQyGQYpS+TJcmXDbiweRAtgiGeSl6QkSRJLCpMi3yCUk5NECjY2BOPqaca3vP3aM1PolcddzwWGNdDTUWm+1+zfaZ5csgwjybOtMrYDcUDhZ9jl2CAcydTZbyWtTNn+nO75YuHP1Np0xT74kHSH+QyqSZMUGVxqZ56L3iAqQ88p6I3c08ylMddpTscOPT3INMPVLNZ2vF1OqJMRIyWu7Fp+4W9ljaoyWn5+eUYJZhKOk04UK2L8hMuwc1QCFuSZhGEchMdH67fsMsf3kCiCk0TRJhTpB5QaSRLDiMLbHsRrqkX6h0U9UJFcagjBY8vZjbut55kjq3U6DZQuj/B9Facu/sGphopZRtCt1QAg3LaD4WH96H22qp/TplvOrrdTKdTdla9teseBLAI5idr9pLN361yoFC1moBT+heToYOJwNkwUqCg7dbF1a0KcquC3KogtyrIrQrya6kgG78mV3oTqotWBVQAQ7DUCxESDk8olIHcB9FxF96dErIs83BsLkZLcYY0qM2vJaiQE7+bX0tKVlW11xMSYLIrxISKTtJllHjEtZpcWc6Y6KO8g4xCJ9VAyuNWlLxoQlGINX7EbLkl73D4lH+2Fee10c6tHhTuMnw6rLLmCD5R+0hZSUSskNMk1IVxydcQ+7C5epkv+6w3i9udqQsRIcuOH8SdcbDwDUO7VHr1hFHJ116i2sFUgwDYgboLm2b01nVuQVsCgtEIHFkWPu1SGXt5S9ONaDu37MH1neCB5KxMmjxJoAweukW26D3wZYT4DHHAbhd+Ejp4K8+bG61gQHnam8v0YAF/74yf/4rPM/MSUSOdL/hoW9MhRx/tp8pd9xXeyFWebSuti/S1+00u7FqOsHL+VlzfZGSrOkhl3YvkJdWWIdzAGlE6aUvM+zZqUxWjlMHHvyw4RAw1eVkaNQqo7tQQJBBnP7UzGuDyy42Nvc/tVlk+gOs0XTHJeosI8PqziY2r1dhXvzh/cg6cP00epx3+t8PRrDv7WxD1vo8/Dr53Tn9xx29+fX93Kn68/NW1hlfvrc7efv+vh9EPnTe960t/v2vth87er33njP88Pjo9vlj+j/V+diaO391xe8b/ePEXd/7L/cXBxdsPg/ig/7D85Xvxx/HPs5+d0+9gz2a5dJOjoLaIrJHff0r0zDVs3m5BOFnFCrnVdmy1HVttx1bbsdV2bLUdyekx6Dg2p88Iwgn33V+5uoFKDBd6sS9jvdB7rLEf9o7swXh/KA72uwfOoX003ofzcMj5Hh+Ph11p/9wqbp5ZcaOv2L+H+sasmAjCyb/FMxGF0+1TsfSpCOu8NZWvjoSwkV1pPnqSSXVgOJMA/JN+2ycwN54lHsdvyOehSKDhDp/DK2yMifzUJaKKEwqy7ocjSyAgsnicc0AKj4P669HjI2F4BRyz6WLG/Q6AFiJCG5ZLrsg8PdUX2N9EGLDrcBHF2sVZIi0XB4RSsqlT8zg3vHM60A7hupa7rBUo06QKVOwkN74saSUlCUykxk1KhEFM09dsNxHRhkXNz67SzvOqFX2OnVM94B8JD7xVPesJAJOinTwHV9wvhu4nqnvzbG/vri99d+XvLQCxg9R1Rvwk7i/Pxxho/TWRQTY5A/nbqya0oRCFDwBAa4Q+S4QezkvzxWFaFnkPSQ25Al2OAyYl2ESLHngOxSdIk6L033QQIVg6Tc8ShOact6cd4KMYG5YOoeuF+vY73WGn373ud1/3j14PD3f3D44OjyjiF8aazk9Hzk+nMgxbQ1ZSb58MxiwluWQ77hgudAjgeVnNfT4oeDL2RgOeTdHZZARUm7lRtAAcQMjs4YPTN1lEUiAyJMSm/VgytHIlDqpu5IAexGgaBHfgAxwr4wStl9KpFdO+kooLMXhRAQQIrqGwBeBM8aRFfapqkHg9bt+xj1SvAszWMMgt0NqzsGgAjQydRbwm0JZhoUpUC1KtoPZMkkeqGlrAIzxSpe2DWA8nmBDQGzAk4BbCjaaLVrs1saeYXXEifMgdAvryeTQRvotOTrKlaO4t/LsqYD8tOaMxjRDxMxiKUokaThaurGxpPRbXBRB08Fo/fN0fvu4Odod7/b3e/t9azUHIG7C8JB4uwW6uXpCVAPkqDngetDwnfibUNPCXKcf4K+tceO5E4vA3YCFY2GsEb56U/UyLtGwm7UHBFUDUMwctkal0OvMrHYtw5vqanBiEaArUndHdiKkmEjnfEQAEGi7ZTEDkoxvp0WmlPKp02hFX16DJ/Vik6r3h9gUKqYkmVCQpHaqJKqLfZ2mjVI251Okgx7iThbygZV22I9MwvkyV0OmpooxiSrmqMjw6C/QWkwNEfuEG/mt2DGwcCtJ+r8StKuh2dZiiLaZlAdMys/CGFU+g/tUioeiKmR9R/okDlG1haSEyCTIoB5g3fjEC1zbAHIP4xUjuAqybsDPAf8FcilEwE8wO3ViELk+DDbG5FFIfmqBEcJk0AexK6JuLOYG9ALxqmfcYAM8wkWWaoruJj4VhLj5gDgYtaV3iXZD2Xr81E6ZdPISwGNJSY/HITIL0qVGHDg6MEdZ6M1SkTLchLQXE8c3Q4QUKefmrTYkbYi4FM6iDkYhaYPOnEUQpLihjhTVP/Fa/1sYtI8cq0Xd9CaJKL1njejWEvy+jaOb6EhSwV5TQSshLEl01JNGEar9Beu6/KUqsMnN6k9XLpTZ42jZKAdW/yjaehMFibo0MJpUv0XsmnYPJ98C4HA2SZjyJquSicWdzbnJaeNr1pN7YZ+/fnJ2cvr+2zt5dHL+5tt6fvz8FwSv387uz9+eXpt+P/2j8/c3l2fXZm+O3GqZp3XDnC3OiPeM4qzIXPHHaMWmCZXvcpNcxE1OaceFJpJQkaTeSYM4rtDl+hSlRYj5pzKsKGVSeNBUzMeEjN44wmSAlwmhISV2apyeRhclPKM3LV+fhQEvq2N2AlpL8G0+hYQ45er+5VUI5x8xZnv9ymQdzVHt9Jam11OXtq3CReRjAi7Q5m39eIQzSmgV2YLCIf/lNinlMyzjs8+8TafzZ2NE92MyskDbECPr+JWZFRk035aj1Se82t3dB1/V15mSVO+YJQvLqUyKzK6tUdd/C/pUkmRDsvjyLkcRooGLfwASVhkEcEyy5PIJJNAR6E0jTtcx4XJ5DcZedk7eDGzGpA13q9cEoay9CgnLzHTZexItQZPus1MZngf7rR9zObmtTpgWVME082t4iWkElWJFpreYNmLxfSJUNb7YZf1z19JE42fhqfwbxUzZZtrefnzd+PQ3Kw1SYvH2+RNdkPfoKXevGr3/Qhfh3MBYdtT4pM6n0Z6q3+2aTUzfKYEalU83wivZcrRak9c4a7+saqfF4ahwCtVi4DnnASItvMxcYVViv2XgCcjU0dI2mU6dymZMh1Wo2VCrcofFGUg9c26PwNQ/eXDR0hYcmmINlXHsBFjMX/o7OxnHAHBGC7ROKyn4oQlU8cju+fc0uVX2MHFbOygksStL8h8szFZ47D4NHF9BmK6qDN7EWzJ9rQ0ftoODYElQRx3XQmm9TlBwTPobu6qABcO9Sv1mK/6BABMDiP5vHtRG1OCOam5D6WxswZjFKSE/8l1Sc+tbh7AvkDyyaoTVuLbEcepTHmP4BZjX8o9/9vBFvN8X91/J1cx2rPDDvP3Mj1M/DKrfOmquSQPkW2W/6rTJGtg5jF6VfJdbv9fMeeAVKKHXdCmCkWd75RETghtQC1gl5MHUIbsAcDoqvLK0wI5SCcvoO7YOe2N8/GB70RoPxfm90NHCOxGDU6/eGh929w4b0eTyKLS0/Y4UjJkwhFEd3c4xHp5QCeIm60RysDoxnPboR+Rt8n6XvJiWh+2qumjja0hNcMVotSBnhKcBrKA60o+0tS+dgERFUWToNX238GXGzuAuTzzC2FDklM5opBzx2BGOn4dYhi0Oa8gyKRQPySkzieuD0urSSDxjg1I8keMerxDn7ldqmif9YnJkV9YyuG3KC5aEEJfl36gWO6dPRO/9TfuyGjflWZtlELQyCiMtQAgqYm2ojRMVRNlQAq6HGBqFKcAI1fA/5s8TdaAAIp7BQyqSDZpgCmV4Ns1nxzk+cMD/rU7oiRQ3vSlOfcumiL9bl52SP1OcfreokkbVVzFs2u2guom4zSU7XzrdaSd1ec+qUX50snYKPzVzfncEB7XUx1dGXG0azSKJkayu9aE3yoiW7gBonUOMqgZ0t47Wmg7MB4bK5UoGUCWprp4+Q/LS8TyDmcIEBBAinRpsNQqFrad7o/SGKP+n6ass9VF2CYsLNnKZKJRUmV7nnXnNFVVJjZWVVVkklI1yaVExCAddQbpVotDRfx9rIDFn0c7ulOX7X1VJFG2vPMiql7MXZWAlGEasyN8rKM7ue5uxzbudt9SFfLgBPHfa1Xr/phmuIjwSBLKbY1uonp8P7o+GRGPd6h4O9I+ewe3Qwcsajfm/Y7+7ZR8UnXRlzT6KisrR+L2JIs8QnuwjpRmIwMReANaDwGIlBqMnXCLKsUA25s2yz0SJmD0LhF08WPOR+LIS2xmlQUzDOTET0lNimnF7sGRBT0RxJaKNfHhjVBGDX+jdGRv1cXNZOgxw3ZdMexNzLTDyF1+cyegqHpaD8eQEiA0hrlkfeSLs1fFWYIHK6hcM8+VSTndd20UDsUeNQgk/D5vtdNPPH3LMqJ0w1n4ZDKdME90H05KE9ZXMe8pnAW7qyy243WVSDva00XDmrMwJ+s7KaYaGgAKwo8izNsT5HTmW0bhKUpv2c7B9DsGRNGH4AqV6BtVBzI9IDCa1yGaOrxhx4r78SmhBy9TZL/SlMD7tQV1IdFVuZZCXVfBrCepF9RzUVVvTI6VQdQDLPWvKLWkjQRHpia18xLGIdlYnS5ynzb+aCWuS40m5WhoQ/VeNYceCFHQrDTZHwRSqQVULOeRSlYs2tPe7InjqIEA2+iABmU1BTSgAJI74JoL0ykuJiKdJEiznESQIGTgoAgUG6QFLEQDdPImoqZ8ENBnslyYgNriOmmXyAEOGsBj0SfuRCWHRuhuSvWzvl89kpyVC2nqEyMucKNyKKZMQOmIJU2IDdc3Z1zg73uz25Edez2vTAatM9hLSYw/7r3sHu8KC3t7efYChFrgfRrA2k3grAlI9J7hlqrQ4XJY/y1Ot0e9fd7mv8/38zSQQG86HwHVSKNCAHXNE2Q0djHZHsWiqJnuCxFHMQX5uNEwtvbqSLubPakjfL9bv2mn/O7lmjPuRKknN2Uo0Wf3hwKI66dn9vPBj0+vtc7Nlje+/oaLw/2D86OGiu65DEbHVpGxd5FGtaiw2rVUEmZJXCcBdm/ysxld8ig8gdR4vYxbc/1+sw8G9mlrdK+y+ntE8Z0FocaPvWXZPxa8aS1ec9tZMZognq08gP1KEcvu7Dodzt9fcGw1WcnErc7JSLHUrz8Az48KFGRuF7vb0RP3D2xGB/YHcFH3QPu4djPh7Ze4e9fW6SUcyvxrL4FEFuYQTGjM8SAicDJx7fYcjQix49jXR+0zieSzOyzGeES1ah7Vv4gK2FaIVWScKjS/0dnShGfzy9ZtE0eOhoLXRUQpIEgZIdewD2JTyH3urzYL7wcg+U6qT2DW9nWVpeHHl3pbLMS+sZn9eNoEj2aNHtKb+DPpctjzUPIsPDwLxGF+dX10xrQlsX9DlBkHw8IXk9ym93eapnbntBrH9BlOzFda6LYlPbddncuqy3JGFJrjtkIopxgN8tDa/G/7T2mopev3qFuvVdhA8GJ+FXCgHg1Um0N3a+/2H051eD4f5gf/Cj4yjVGXqcFW/Vumt93DsYiKMuH/MxXOx7o9HIHvCucAZj+3DQGzZXPSg994p+IQ8JMHc5kaNeb+gMhd0b2vuDnhCHo4P9o749GByNhv3+wWhlIhu4uWU1jLWhkGlpg3KwGbPWJhCwjnKxCHW1M+VVfe1oNqqvyq9wmZdhw2N8ozKg1Ec4YskVAInLQMBBURg28kqEYsmtqPbF9j37xd6zmg1xVbY8WkSiEwqwgEXWMfx1iX80ONXw1DK4sUgUZMwoQS4l0N4uA1MJPJMuf3jDIHWEtH6wHcWqHx4edsOx3RGOC2kkg3DyKhzb8L+YaWIaz7yXNaqX7lGnB4aR6/6eUr2Au2oAwKYG+yj+TkZHyvsYUWCRUESbkg5OOYDq+ODaZVFyh+p9Qk2BoxsaDlkwFz56TdgkHV/zO+EEDypTBLjjuIHzmvkBm7mxO6HZBMALj9vCYUsRk6Nc4Mt4i5jfCSYQeTa1QVEzeQWb2pMlGV8vFiPPtdmYA5qZzP2KW0SOos34HadfrJD7BnvA53br50WkAcIU+vij/llzoiqd8HQWrGgxm/GwPqQ/s6vfJfWvZPXPKhcv96yHILwzGKblZwaf2St2jVArEJ0dYsZzmUzV88REODQhRtobZubO0EsH8Epm6AZuNJq5cUwRks2buVLVTujF3PhKMBBznd4HlUEi+fiGHDdyIeED8Y3kVEqikqkyrreBVc3ngnunq6QC4FilzGkt9YujcsDTaQIdxieQKDbWj3MUsDHXXTlV/MfntuyIG9H8DZwBnWXJ+c9bIjg51hcOW/iOLCp9aPl87rkEL+DG5mMN7CklwEons+Y6k8SAfxyPmScgRBE4jMaDMFUwtAwurR7kGQLPOFFOB7A6SUyjzrmHfsBEhOSUOzAJgIHqvJS9l/e3Nlt246ieJe+y93mWrNajyJNpGfEjj9ktNWQ5gjue64tbtvA9QEPKUgIICt49+KW4YVSyvjP+KKfUsKDvKDRFc1ZVmxkB8CGLoQiLvFbbuzlCK4wimbnBeybJiGicpF12QbmXCCUfL6rb4qrdQhUQjZ5PYqhVFpvEiBwr08545ZkrHgTjVm1nuVN2mcu436XgkemGpd/Zw5RwOexFFAczEcq1EBwgIatfzzM3QrxcCmJJ3b9CMQvu8ZdsiTIKr2vDbSVDGQnE3VUct5o6nCMRpnOXZBPPf8A8535sKboNdC7iKeaeudTUQkVyUTJmdBlG0vUL1JgRKdoxic6g22PgmRaEKpk4ytyMj2MRggIen+twGMGzDYvCD1IQAu4xxjha6VIOO40yduK5uuJjES/huM3cCGDEGILwsSBsoxCl7iWYQvzezuSHgZ5iwoWnirvsKima+SofviqwgN203gdJfbx6YCrGggO02uvMzMDE3LR22Smswjx0o6T/iE25BMPR+xotmQyt+wMLkDUn5TELnUphxvEV0yCGOAxL8h2846BDEmlKTFobKFzn/33nBw9o5UC9MlQr6eOtmHC4pD2Xy8BoSc5KPcwiA2ToT9l8nrobufTXNuy8Z1ziygGt1Fg2UWPx5KVYQi9wUC9wZrk6XM2iXchElQMYSzdLZgmya5z7hIuz4gDT8Sk6sldJkrYbGm+nZGUIKXKu77lzbMfIu0xXQCLNuT7mLczhs6VPlGKrFDtf0rKMhnKkcVHvIXJ/bdjDRPgxBBs8Yx9v3Hj5nM0HMzhKZbMkPzMZK8w8VKjCWYVYFmZPechtTE8kHm0hHLxTm/S6AISZZxzXKWj369onjIWHtP1GTZ9dlLR7Jok8u1A+33HA+Nxt1CqoE8rohVcM5iAGsiH2ME2rRO7eeSbq+mPoSF5OIn6ASKEe3r/D7Lo1oq1ii78Dtow2jeSuRxt2o3Yv4B8XEuy6ZlIv8GHlO0yVX2OOQRfxnGf1Q+iVHSQ1jA+Xb0nuf/3qlQb68uol00tcgQ5DUEHw9MeHwkumJlshCcOjYhF6rGwR2Bt834K12lExFEz4doDxnJgATniOAdXOMDilUP0BPRQaaCnsejV/Uc+Dd3xWV2NLDlWc02N/mU2HRwW1mNbMOYBpIC4Fo8/xr132JqkeCnYn5jHCTYXQchzoAEewCaGtaMpDPR87rAosVvJO4SAhhzLccbLweAhnGCRAeLiwH4IQ4ljEBAMj5TS002HMOGpRZDfgmLPwPJN8oBm6+grKIUH/pRmcc98Q73wtHvPT0svNCqIB0WaS9IQC2RECPGqzQkhWoYNDdgWaEqYwBTA1byEvHOYeBOSg9OHrwe+O/BnfvcaExtoAe4bxlTjjHFOiY8nllXipaYFF+E2MT43AgNZ2NcUDjAlLsCNiTnPFq1yf3WLdW1OrJTAqxUXvD4ff9KL3h8PCossldEjTEJbtbon7iaOsuvay/WV66+u9LSIRWnxiDqKpm9nVRxkLk/LV1NG3fWz7xVOLz44vMolK259nDyoWPbl3AdUdIrljmqZ//fP/vbnx//XP/4/t+OKBgR4xpePlLsLOqjZguqiFaXLn0ghYf9jFT+ThpxdKdAkRXObqVt9lp9yeohwgy42Uq8Q3sbAFFSJhqKoIS2JlkvvIyS+++t5cHb9raqE1Zhm7TjXOqIOjEEhl6ZDdGF/TUslG1j976npOKHwkcStqbEWNraixFTW2osZW1NiKGt/AwuKNUnXmvjXmYswQULNnYDGyyaeKTh0Z/J9MBvf0poHfS6/61ED/r3/+r47p5cfcjrOQYIDwJSWDf/3zf5UbwDgIH3jokMYta48leQEkDx466A+A21RF7uyy9+fXp6/Zm2C+DCEPKds5effm+CX5KITcETMe3ilaFWoaeB74gb+cBYuoJPNCkibIB30j/KcDVVCWq/HeOm6sP9Uh0AAvwxcgVvFwKa15Kr994jWAaR9YFIt5xHzUicOM3bvigaaNbLnt3N7N6WVrd9LQJH759kzYm9tLX2HZggdfhNvTsMlpBWcYX1DuoRXfbSbmlD9axl1nXMhPyU3ceiOfXRkrY1HtnLLo44uzGveGtOwL8mzw+FKEYNOUzg1RzH2Hh460uAr/XniBfDmqNJPkRIv+Czm/BjDWZkzTIzEGM0w8FUuAfZRSc8HBgu5uqerHMMBIs9mzWwDf7d62U1geIGcmFfpBmBghdL+LHeWnQZsGDckyOi0I2Tn4grAJQE7ScCBoRLloNfDHUK3vvWzkqGBMgqndrbAUNGDJKKvy1jU3F+BueCeRpjMo0grSGmdWg61uHWdXVBqxP+Vc7PN2m4QVcI+pcpsZgpH6TxV+BMfeA19GzAf2Qg7HblTuP5AsGZTPhL00igtQPitYGG6xamDSMfciUfRMwN2x8pLoK/L3T+mEwEg08qnP5pECSUNFfdTJ9yWGux9ISHiYup5AeFc4l+MwmDEl+rFMEUDKQhxDuhaSQiiLqgSOtGbk9B66k4lATxDKPwcLqx0f4U9cX4CFHfND3gO2F9xmdOlwUjGguyW40jax5cFt84Y8zN6XOJjKzx3pG6kkHAkxRpJQ0Yu1LMAi69Wsi/aJssgs9icucKZgR+MTwazuaBY/C7d2Aj1viAYI3chxMdbHsoEWX1ddap6tcxH+vAiXkJEUAv1zwUF6wSlmPCWYUFOfkTvx0RvH/DWWgSuGL6EQsaWSR5iK1HnAJ9OzCA22dciu6M6tXOqAEv1wOq8Fytq0OdRY0qXU2s/NUyqxSAnFNN0ly6XPqIEFvHtz/C2opJ2Zzbfq6K06equO3qqjt+rorTp6q47+htTRUnLp/dteKXjCG2ZgshMV1jTwHLxUipOw/23Pwb5pCkJhehRRTrzb7i1Kdvj4BKnntkc/ULDXO1CsjOR99ZohOC4D0VLJOcVwtUQA7KHUJ59L/5Z319aas9VfN9Fff6oPbf+32TFbk8fGtkxGYZKPJFKe8Tl+3NZkDZRGeMTeozBy7DM+HrtJnnjQpQNQij5XSbIiFfsMtwCOi9v2AgQqqRfES0VTDCoMSZipjOlCf6cZwzMSvc9v4DysehrWMVElIllGeFHXeKJiSlVLJptWltkYD6W+vdQqaCYt3FNlhqwT4SzmZaEnfw0WJBAr3IBUaYRnCORhuc8w4/IBc/iyQeTOiTseN4+DAnR/kt7x0V3ffFXTUiUOKaAFchM/PUdqOZs0D5l9IVuoSQUm1RsYip/nSDK2Uj9L9YpqAIQsdvQ9wERKo70SfLFn4/vAiLhmgjmrbiYUtjt3jW/tUz0xcJquTZY3o7fAqagEyU8j4aDs1wQ5iha0OEWNEH2gx2jNBJrwWlTDbVpnfY7TGSpqhZNteLkG3uKmzZw5U+UGTZAr5CghbrGh4WUOeQFoR3aV2kST1IarIP9AxTOZ0VkzfeYNMqWGxFKjIS7OG6MRpN3i/vJ8jLbP5rTqsdCf26vW1OOdV6+djWVeuX4ap7x6VT0aeOXahiDSldvQAkNXq/uOP55drDXlmyA7G7y9cnXtAl+5rgqCXrliGue8ctUn7M40Mne1qsotYMVamrS3Ys2syLZa5bUrnklz33p1UYmMD9S1jjAozNav/T44BjF/vaoKHe9jEN6t18KVO1mn4gdfPM6FHYt12f0HQvNYq2rovQ/i85D7k7Wmjerjop+mHlQVUkuDfLV0g6Y3Zl6CTX6RTgC601a9A4IqWKTzR0ixBwBUX9/qPyFStob/reF/a/jfGv63hv+t4X9r+P+GDP9aUl3LnVdO7tmFUs+JJ0yv1iE7uzDN8l4305WcxCBVj2UICRZgeIkDbWqNsOBb++U2Gm0z0Whbw+az7CV6usyl6sjIiWCQXGM9iqcQGUBcUp2J3ckuO+y+un5z0Wb9/qsPJxfEiOIghozm7q8JPyEmbGD3+YcFMiLXd9x711lwD/t9pbo0NFAUwSUf1IrizTGjkCvuA/OT6WMMgzJbQYJFaIsvw7ypry/Ht58rtK86ik8+n0utnlm9UoWRMA65H0HiiqbGQYPWqRRyjx4Q8CzPJgkMxViEmD+ztjtdzbt55MDGipINaDxkEgnhnALu67Ie2BrxYZcsThJHLAGAMkEGr1JsLELPmkNYRghbSSIiQ2gHhKO2W8RlLfE4h53uSu5WlvPiOIHfr54jkwGWEoDkEN0RNzIXwaQbYBUmeXPNWAbN3GiDlK3Wj/MyzVFcsILO3FhLYUDBn9LEzeReZMIlFOqEIWlY7unI20yayakpXHLU7UAeAS3YS8oUlBoAb7Agnu4ysh5DJTdiN7mQrZtWWwoYxlAykNfV9OyyY6yewTi/aSVk8Tsh8yhItZd4nHvcVw44USy4g/wfgOFtW8xjFCAQnB9cb9ZLk8B2jKj+UjARacaOJPby5W4S+Kt8hYIHxhkl7FPD2bnVMPFvYW16L5kPKSikE0iODOlLhNo5youDZW9ToP401UB9KsqyjAtvq/bJhsJd82cZjgi8vFZrphi+iEGnyY4oju3ctG/o3JRvu3byepwGGVEZvSRkaUilEad7DtqU8O/piTLqfnOi81opbbTUBJizLNGeF/M7RHhrZ3YGKNX1gvi1WKoJq2roNrBBr4iv5BCxkc2veTsUvBrq7CSLTMypMoa0W/OsVKB9EKFV+hEFfKu8Vfo+z02u+p6737AXrUPpcNfKdpNt9NOTHDJo1qo2qO49VrM5MeuYey8scza4E3LklN5SmhQh35B2AI6j2MLXdJ4iYU0mGi6q3Onr6pzGJDSW+LqRqBWKmXDcEgFxzXRiWvqzJKXY2kNxAz9hnAUpDVtt5/eEltlLn0h90qv24lUy5KKsTQ1T8tN0b1VI1lIoQakaU2G3W65vhQLUOnDyuG8LzxMkcpaljCnmkzM8i2XmsqL8HMlUg1JpglmfmrlZqusS0m2WZTH7KXhgM9BvJf6NZIwgXfKDCIXyKYXEVOQ0DWfPnMeMVrGuK31saPSk42xsUjzSy9bSHtHCcBxKMpONAI8/o3aCRCCyTdSKg9gtbV56djY976Fa8JUHRunYqLJ5eEroXbVlWQ+G64YsOUCYQ9PUU0FtUdgZeVpyq1mchtK1qToA9c9gPX1cmryOpxuTuIA5ZrDS36U03YMLWZF8gdaMJfSGQ1kmtv7kyNX3+f7N1enZt+Dl4NuRcLc+Dlsfh62Pw9bHYevjsPVx2Po4fEM+Dtvo7K1Feh2LNEp1lgywskIxpwS5JRN8RscqSQeO2msQtdHEBMNBcVWFPOLJMlzz5lfR1ufg28ePrdwudTZn2htlFudMOEAxWR2CntrgOu8JZyLITLMMFvg4GAULH5nVsNffGb9sp1+lXWYSBA5gw8ZTNhKeK8bak2TGYxG6YDYgxxu9ppbWlB5yNHN1bzZDeELRtCGLMCjDIoF4d5RzdiSSzH/9LlJVeBvJlyZtYBihwflIBUYzCIwmYxTeYXLbJp8T6wgoSedBFLkjz+xhVhpDUZSTVbw1jYjk5WWwCJncZDVtX0zdaOr6k2/h5TuXtGwfv9vH7/bxu338bh+/28fv9vH7DT1+t0/DreP7Bhzf+90tdNn20Dzl0HwdX271Vip9WjdJ1v5kV+hLHou37swFXxNzF3CTWR4VeV1UJAX3lEtBwKawUZwE/1GGSGxYDR9w4AEqHZLheaM70QIrCmbc9ekylE8/cPqDlbVDAZsTPD1j4D3jWFr3yS0Kff+FHfhOpPRXWLBzjAWVpyibCg6G/SbpGvJTshIOUQLRvwJeTn4JPstUGhtqaxZNzI9sSooh3flkfhP5q9lDO3GRbvSqf2omesOxbJCr5QXS/6I2YkONJmmQJqqdLmJmFYrODJdi4kZxyMOP0+As+gFuDoOAeHly0ZlBGiR0V8VCMv+RrM0+/nR+doVpS5jjRrYXRIswSQYT1Xv3hGJiPUwDK5MsyUK0vJnxhZF452bTKyU14HzOgwc6WzyOg9AXmK+IXZ5csF53t7/b291r5mSriANNnoWaPEtDeDQsYh7+UU+M44I6w0FPP00zmCFskOIB5/yzNZW1IsrjD+OFZ6XqFAsRDM2zdqw+wY0mq9CqUTNeboqGK1EiJtyzRjxyTZ7i8JHhXUjCViizI6VnVs1QhoI94JkaBicgadJmM2yuBmsoayXujOW+O9qWzlOGM+csQoOmMr2j03OA/kZ4nwEJrkImyxAkHPAX5JbwRImOD13+5sKGe1gnTtVgIwQKTdrLzmN/lXkseCyrMakDn8Jlar8E4YT78iBmvygxRPsJs7Nkf0rTuxR/tFIcTsPHeRCRszAyPO7MXD+B88Q/cqTRj4oq+ksRRH+ltMTCnqrG8N+5tvC3JP4M/lAt4R+qoU+Gu2jGH89ohnsHKCSrv4rbIwgrdqzUdidOj7JGntv1q3brBEQgf0a4hnYQzoNQjTCNyCyKmcZjVb+5zUyjltM243rVt5wbfQt6/eTm1DjCVr2/Ve9v1ftb9f5Wvb9V72/V+9/Awm5Vlc/qGFQQE1fUEplUF2upQatVnJepkgNEtVJNJ/1eFrAFwPP+YibvNdQKJC5MtFW1cK4Ugt4OQqdKmJShL5lILpP8myikjAKtLiswKcKXdXnx09nVT61268fT96126/qny9Pj61Yb8xi02q3Td6eX8PO7Vrt1efqj9fGn81abvK/gv6fXH88v/2SkMIHb/s8MaG2gS9zUW8TcW/xF1MQp9vkT9MOZRv5DFMO01vBNuyulmlguPBo0xwsvsRc8v/qYdg4NSwcfcYH0GeDQkTFmxudzIACmD9+/9tT1nFD4zWbwzdXxu0sVtKalu22M/JCrrFBzG9XPov22MyFpzfCetTC6dt6vrxnqe9YjsV2iRFj52kx0IarFeAqGqmYNXWPZfANKYGjYhiqeXqrysC3f45sOz8Xn9dIiaAu/GlZ1kapVamf3y4rw/tmFXq2ydkpWHK++kqtVNe6mFeHQteNhAA7Jspimt5M8INw3RFcDK9Wy6qibIb05S+IFfuN3hbwgNnpbaNNctnKAVg8/03hOhO8mYFclMFWA+xTxMYwBiklUpIJkg8Z1R/iucCrhxHwAO7LiwJKh/ygrw0J4IgYeKvmXH8QWJH1PHpatdstZzD14EWjFcsA/LaUxsaQjkTVzI5UJyw8smqAxxAjA5eqSrjqfNsxxQ4hpgPj1ZMLbrYcw8CeyZwuomAThUiNh4fN77iKWU6vd8viDJd0XZkTgWIQhz7RIHgqW40bzRSyU9jwt0XQNY6mGrJHTzaAoiHMSZ30kkrU1rSQ9fluvAfVJdGJ3JghZF3aSFa60lchjgzZNgn72Hp7HGICgzaiJEH/h0Wy/BmNoe9VjXXUUPqvFMYDI4O8px3Ky2QMb5xO7WIw811azDgLdxkBWTMNL4VYST5v1Gg1pv62J3KKz0eo0xcfSkQAugAmaUUBXBXh2iNuQWD8qpr3CgmOw3qzY9CIsYfVUiN20Av+mRRuZMyxPVhjSLRL+RKT0Q9TVHwh47MGFnMRlJ7AJjPVJBnZax0LNDJIzX8QUEmS+YwuW5+KV5ETcAnjIqCxSUEdPSb28ElMC/HziTlyAqb0S4b1ri4gd2zHTGjU7OjTw9b3S+lNAoSmI6FKinFRhtaSTXuMEewo1ofmV9pFvz4T99EG8f/Pu9E1JB6tEdV5mvqdDkZkYKWyvMnKz2mf2PBOHBpJegkgKUstqc9dEGdxwAySZIaFJY2fzOrzmCwMq8+ZP2zOoaJuYtGRyN8ajKLBd1JbnVgjYNGD6lMHnNDJkfYjAeo3cfv2eqhCirxSi87OyxGgxgh+r7x1q3vZ4FCX7t9El1ICAMhMX/LzaGVs44XyFa+7DyeXFxm45s/mM7FgbmaZFWArlZhrb5dWGhmaCq7MlPJ0UOxP8ugSuLitgJ8aS/PW7ypvhPygZ6lPfBvjE2nTmUVNXzdEut++57Xvum3rPbYCtNT8j/0G8q85VH+tuhoBKjlRI7Ky6/lYzO1ecmyJDI3P/vYuQF+pWV9FFqPNMNZ5V7EFztVDlKW+C8gwg9lhBbnIiDckwNM+TxNk0fVRncFbrozw0/0yzZ6Dxi1LXFD6Azxg5WxukrcJoM1aOr+r8K61sW5/frc/v1ud36/O79fnd+vxufX6/HZ/fLaTHFtJjm8vy291LXwfpgp4Ppd7feZ+xr/vASLzwtm+M7Rtj+8bYvjG2b4ztG2P7xti+Mf695MLtu2K7f566fxJZ2ZIRfQ2FvG5jjtozrWDabTAeQzraL91ttJyNAoPQ9wzdfsEHm2E9DXNtmAf9pZfsrrLH3gefJ87ChbDJ7HTC0frp+vqCDbq9JNQiajM4fJCmjRhRpMIVoymH3L/aPfQiYscXZ8zjS0QChLdklGA20dtJhhXA00nhJtqhQP8C7gEu1DgI8ZqEpNNcCsJookwyT0MXiMol4kXoJwHJvsNDR78UoRxRKvx74QVzQbd4sTXVEmImZjDatJGSm0aR5DE8OICG6xCTL/gOu+JjESM8mQyQYfZU2OTTqWyS9Dvm1COkISoDN/A6AWTpuI8vzrLrvFqIE7iW5+oXrbEffPE4FzZYj+24BMaSJhgRMmHQGCFiDtg2NA8JLPySho/BWUb1L1cosO1FSIEjdW2H3vsgPg+5PylLonGM4ph8TETgtENuMGjodgklk3I0wgX1Ro/CadQ57qGSvv+qUmoI0EeodKDYsySIzeiEcJ/1pKSoSZPHKhe7VM2A3IiJ4lUKjEIdtuPuijaDjL0y/e6uHcxA4g1UI0iDlgyV+5QDPNPELrn3ZRqBVBYvPA9FDqg4hmT1PBG8q9yISJCxOJ8sTB5FeJAX8RQOkA2hu+w4dfRjP344O2E7x8fw35dywDAH5MeEns2c/XB2ct7H8542Mgsc4VX5gS0W6LqjJSoe293hwdG4c9jr7XUGB4J3Rr3efmc0GvJDZ3TU7/a5Ph78T0cxxUa6NykyVZ5h1ToWhu48L3igfK1N6snSUHE+t1J3sCZ10wqyulywhnWhNOqtfF+sMlatAlQn1FqL13s0UnXw5YtiPpujkwx3zn1vSc514MM2T8DwmrXmztGPm6vM1A2qyMLwZAU1Q6LXalAVy3b2pOeIvrGsSRgs5la4ML2234FmScCjgB3TMwFL1/vCYLH6rVp2TiljNocog3s3WETeUoEMl9GRisDJOeO8ywecjzr7B/1RZzByRp2RvbfX4cOjca+31+W93tjkZlfQwdNgNBlKpyEqHFUrEtyk/gkXgrkyz5ege0Hpf6lBQwyINp4x9yLRbj12+MJx49Sz09h9x6At1AmADYQXrcbMlLJaF4ia0qUTYX6wIWjFvVDeX+r6bSeKB868YOL6GKg0m5tdwZK1xaKtbK+QlFxAwFNZiubrDCS1vI+pSiTRfvECla85mCONikTgTqjoF/qPBAppVriGO2WDU5y4R+ZcJVesqnkFlseWgZRrA44qeTyrgOrqvUCexvIVCn98WsH1UnoHSn5Yvva9/t5guH9weNRtlRyHRTy1Us/g8pben78/LWkDnvuBb5m98/Q2yLsbt10d4VpRuVGarh41Zt2JpTXjcyvbSNrsRRABVqppqlND2EVm0ht0LnubU+N4U3T6yDhLvBr1MYOE9X/TsHOQ8YDeiaj3a5XXk0BPVpcb4Iu0jnr7R4ODo95Rd4gO5Y3vnqLbpXTaNnhcuvO6jXmw24X/hwRHFiicHrjuEFrBPt3IeuDhvFnhWexFiCbe4FRVHQbY6CKMLTeKFiK0HL+2SHTnlpeR0Y7CMYxClYkwJWDJDEcUsWrFwZ3wG52nbI3COCvmEGWoxaKuk+GBPT60x/3OeDjkncHw8LBzxO2jzngoBj1xNO4ejQZAyL0II3nxVV4YbnSMd0U1kciFCh7iqZO2vDa0a+BT2WUUbW+j4m2UeNbXuXSbBQmAN9NECWozymO9C4fJ7VkpRvQ0bLdcnCiISH7M4CvKZq4P/4ZQdOEktiXZe30fGkxcTpleGAmAa2OvDdvHDD85qDnTnKn2k8glHBb4Y4BRIhI8tKcgFfOZQPtBdZ/dbhHArkrkw6I4riQTCci+YQooI+Lqaex2PxujSQpBIrlz9Th3w8SSIeuA/8ikeIsd9vaG3X08UzEHY1sDHj+fG/UCZZd+trbSydRf5Lqmpjx2IfMGm88pL2npzaqXjoQ3toAcUizU8mbb7vPD3mDY6fb6h53BoH/UOTwY73UOD/r2wNk77NoDiv7JTgyKLrAimUCjuuXISiAlpRMRxA98u2a0f+nxv/zc8374s/3LL8vgLz/gHMVedSf93r7cgyWBI4bRrnmLgIYH/q9FiXlMNnIoEmG2BbQCqEwSskI9dzb1NhPxNDDlaSnrTVYwIygUmidIhermZZkmLWrPZ+ve5YkMV7jKfGAu+LSEWwkfl2jYy7zA2b3L2cfjywsJEbGkuGhp5nR9SvSr52jYZcdaiUjEgLwBlhPPY5jkaR4KWxCUBuaB0oyQpuVxxJgja2ugbiifAZP6ofEckGtClBn6IpLYEm5I8yOFm13G9HaR6GJtnA1OyYfkSWCESsXOnAu9d2wSnSjkVKpqMHeh64hIZnhOVyApCUuGtOXaW/kUaLai6mm8hdq3yrQvooyVaccOgjsXrHFZA5U8nG2wLV3//+y9C3fjOJIm+ldwPHu2MutIst6W3D2947Yzq9ybD990Vtf0dOalIRKS2KZINknZqZ7jn7V/YH/ZvREASJAEKUiW88nZPTOVFvEGAoGIL754dU1sz0VfElwI6Glk8XNuCNLkTqk6B/gStKjnUk2XXyBJWSwW8RJ7mGyISIwWCQQeFgZD0PX1r7g10D2hm7yte9KdR1psm+yIF9CMdEDsEclZAhYon7gvo6rW65aOVdgzhXohQYa5/cGtYgaHsdSWZXtuOAto5FheYFMPaOCAuS0BTjbwPmjW4lwWIeITIirjzko7CNHXMY+CFcFKyYraS4A2JeDcgcox64o8fzUMESYWbSdUBiFcJg/KHP/9KGGfQJUBP1DpdspNgRh5EojJOMgUlEcM85CbmC8+BfXXM3O23c0G1B6FFl1HxwaTMU+CJ1sc7phfWZmoj5kHcldMNXfIgGgvC/0OueD7H1lB4F6+dK5igkSHi7UAPWPtwnJYNyajrvK+SYImpSc5vW08nTrTyXjYt0fjodNnk9GITcfj3mQ6nZ30R30tQ0lhBuuVnOKalTWcyhxWv7wAvvKrt9fwf359cXYB//oNOcxfvHrxHsyd52/fvHlxDn96e/X+8u2ba6A0f3d2Dr9dnb0//1WbzknZj9CGZh/Wa1aAzSqpVdu2Xq5ZiUJUHyFqN/yNxdOQ5W1C2zxbG4HQEE4dQZpG3kPhrX6uika1EATwamwIr4jcL117yZHbLAZQAOxvUQfBOrR5BdPp+O8HuAdjcO8DvKyNlbfFd8J8VAAmVXRV9Wv5G/JXnIz8LCiTHLptaU5q24HnZQ7YxrLUWJYay9LjLEt7vtTzhxIcV82BPNxctgGvV+FWq5rT7NqCow4pIE663UHaJAKYSRSskyx3w2/vLo8ePubBpVtYm+oXJ+vDx53rqfbZijkGdqmPRZKpJ11iYZAQ7eO/dlrkPLONZrU5DE43ZiNcUvkMqu2EVdLrjQJIQAVE0TtjYnM57W1SCwigRgLPtVW2Rp2dsP6ZLPujM9QoPQrDWAG2c7kNSnocuwsfkRLaXpRazusq8S14Uss9quIUe8+DZ+Tz+aw0T/VYkaLl+hiToBZWh5uaDXG0AsGVsuxvB8zyEuhtfPiYb9mja99essjygkUALOkVz5UVTL4yDfA5RADd+/LGOQtD8krUJrOp186M1KgByZn30R+7q8UxtNC+Z7P2jDoLFh/b8zb+KfDb90s3Ye3ZohPfLY4qxgOy0QSuWHhUmoMPeREO+ADLhyCaTwJLvu1M66sqDziH1hHf/ZbD/I1cHxO0YaFUVpEPPNOihT1r1VeRNRHucEOrRfiAd0Jz5rno9F6gdbLknynbjBfHV5wGTym9GwYdgE/bk9oOqCdDtasVfyh1QwK6nHXmvjPB6xSK8WmVDjBNijLFEIlBS7WjUd1kasxP/q88GBXYBSiF2y+OIWvDnW8fccytlw0bnRato5kbB/B/guAWw+tbRw6Nl1aMf4VgMhon0dpOeNLvyIEyK1v8bwtw2dTjx/vTxmK+EwauTFhcJecMEb/lsg+to9nCsgMv2E7UyOtJP38AcHaQQG2uf2t6SnJFIMYR5au1YyeKpR4gtYUPxmg8f5bD4GY1rExXEvbsLYCRC7MGOcDFC81k/9ZVUVS6cKNWXWp4CXAt41u/BvaQiu1BIxfN5aIJBn8TMpzUx8rQnATcaUcLTsuyIL9w49ADX2FS6I1GPTN5zaarUdaUi53RqfGH7s6W5wR/lKB81Fg/yV+u377hyG+UoISSiK1jtNPwkjxKqEKrN0IM76qyHxkXA72db9XMm25YVCmQi73IZsw43daj2sY7OAruqGeJsAXj2zdXSq0oOzK7VZWWywXxoKHeWGctFkNkZeDxJC47dkxTEEwpc8qTai1MLV1ZAdgp6ygMYmblwnrhOlyFpgFHtVVUNrHj4LdUckBZP6g+AcaJ75o93OzhL7yHW4+9dh53h2CgprmRClgx1HNWMj9lvwmD7042MN0pNjSG4YPSpGv3kYs5CtNrcv8e8ir26+A/S/2L2D8ttpoxx2EO/85lBgYv9cuyGit/5cqSauvMsqMoSlILAUuxzfApSILI4abbbM90CNDNc/BFlrSJfXJFki7ZHlDTYYwlATaj9M/sk+2tY4iUKzfeIe+kEgckBq6PHEhpUYggXK2TNfW8TVZPnft/35VFrROWtah2Ct0SgrsBt+P6t1qkieapsItaWF7xkvNfaa0d20HIHNk30Iw75JIbdcXfnIBx0oANS/hStYibEEk8I2JhOxUxTZ9Po220yuZG/vI38sPDx4eiapmTzbHtrpRZrxfPhY9N+qSU0PSjfG1JvM0L3yGYpE3BcGsevSbx/cLcK5wuKJJEI9fMm5Nf0S68pR2NQa4a4G5qn6sEiEvKCQWta1ynKJKxVjzKbFhh3dnVNi2LfgaHVBDFKuzTSLQpRQo+rRSUsLNfS5b8IZ1kWVJY80hqpciefjbARNIFi7LtwXH+lghDMKytvg5ohGcWn7ncx8A/MK1cWxacJkkSWkAuJBukSRK5s3ViWnNNBeBK2c2zpDqTHnkv726WB55DjM2WeOZdbkFdSagQFU5U0eYe0Apas01IjSlpKosjjBAb3GvR9GUfuFshj0aNLYDdC0FlWP22WkDZoCtmxfCM3HMINRVA9Y9TGVqq71acc2NmCE1JJSwe98mw20tPunG1VeUP7fxBVyNSqceJmwhqAFMXZa4ceJLownTi4NO93E81rng/wPmVHvnUB6/D05f+ANT2PBbLyz8fckqGuXQzrw/zMTc2iaeySWT2ukNZJ3aAm8EW/5jvRSE8uGw1+WqtFeXYZrOJ0NkAP+KjUeP3TdWyj7lXFKXXuz+ffriHySEU60docXupYYCPggnTmQZ2OvwxXXlWWpvh3gxcx1YKfTyEOvH5r0EOMSvdac210lwrP+K1ot4cf46Ce7DxQVh7Y3/7Pq65xv7W2N8a+1tjf2vsb439rbG/Hcj+dnirmilM/FsIoWnMg807rnnHfa3mQfnI++ub8+aR1zzymkde88hrHnnNI6955DWPvOaR1zzymkde88hrHnnf+iMvx6/0ubEgDcVRQ3H07VB5NBRHDcXRt0xx1GhDjTbUaEMZE1KmBF1gNkjywo8Cz8Ms9Fdp0vq40YoarWgHrehY3MpPrBr9TqOQvMLkwmdhmFOOSj99VUxnzT3U3EPNPaS/h6TH9VLatJp7qLmH9r2HZnwzPf1VdJ4aY8nvbJZt3tylVPNRcz0111NzPX0D19MvPPd7Ltvhpw15IUxGzQX1I15QGgGJu0IaEgn/UjL08mSAp6TXJdQLl9Rfr1jk2sRe0oja4JQl80DkVpttSAcrUy649oJvQmGArrkeZ7bT6w+Go3F9HQe/DuUpwcORuwPzvzQXXXPRNRfdV3nR/Vm4UtQZ2X6jHR4NujV5UCSlq8ifI31AZilyVpv0eyEJP3eY+mcP6lacZE1gdyMNG2lYCOy+zLmLt8g/DcQkodGCJZYN9MaRSwHqlh/vznBZzlh8ANCsTtkqH/MV/eSu1isiv8KUcSQjUdVtzp9iwscdd8h5+iU/ZwkY8HgG0gDOt5sQ5tEwZnGHvF7HCWyOnGpMbgbd1Q2c+pv+cjha3aAkuV8GHiMxswPfiTsioW3irhhZ+26CTZ2SuEVWLbKsF/6TZU4n7Q+Xj5WpJYhBGdxY2BUZKck+2cULtYkdgkwjh5bij8yDXmbb1tMoQCr2+sdz7qgVZrNVxHcVH2XngQ95CnnWFLFTYS9hvvHZRjfo/KF92vVTkchyFZsYoiaGqIkhamKImhiiJoaoiSFqYoi++xiifRTvhqi1Mbw0hpfvw/Dy+vyKXLPobp8onM/wTvpmPLXNc+ILPSe+Xu36u1ePv34F85Bu7s+tZfFQqcZb1CgtjdJi4DtXFJkrDC1s9JlGn/kG9Zk9zaONGtSoQd+rGpTFijfaUKMNNdpQlTZUSqkdh/qc2ofEJxgk5n6Ez16bE72cF1YdqBamUR71HuCE+hF/PrDJTsNXjfXf+iSUERuaqcA98pgUwYWXwdo4e/ZapAEXgsOipo4npYAmLG0ncYNOldDZrX2lgKb9Azxc9tCL0yzMB1KQP7Mamna/Qh89uPPzx2UL4rm6g3DtZRusPAux6y88RuBjkn1MaBwHtos4yXs3WdYpMftIMHkkV/TTJS/Wax2tXF/+o4IxTbdpNAPNZ9XbNzd5I+Aa0F8D+musWl+hVasB/TWgvwb014D+GtBfA/p7AtDf4Q1TT5gDu1HTf0gFuMkC3mQBr3B4PYVd/QC5lhtB1dgTvlpx2tgTGntCY09o7AmNPaGxJzT2hCYR2Y+UiOwLmjv2zunbPCaax0TzmGgeE81jonlMNI+J5jHRPCaax0TzmPixHxP7545tXhPfVBDqj6HANtlzm+y5TfbcXPEme25F9tzPcus+VY7S5vZtbt8f/PZtsrRuwUB9cXl3wFyYjbxr5N2PLu+abKDfphg8aM7FRhA2gvD7EIRN1snvI+vkF9Ar98rt10jOJrvhzg7trza74dMGrOyUQ645Z/n2m/x4TX68Rx5R8/x4h0ttF4eVnuNSSsj9MuA1giLffpOTr0HANgjYr+ol2yBgGwRsg4BtELANAvb7QMDuo+w39Dx7GOm2JbQ+RKK0H/7B0KRWabTcr0PL/XqVvu9ea/v69Z5vPEfK5ze9P3FCrubebO7N5t78Ku7NJiVZc9021+0+Kck+061bSPwkjKdxmjRKQ8OpS3/5KP/HAc0nD5XDybL7fMPjWbuaTEzg41777j/XjPC7YO6yCFzP6IJWE3JVJVdTd6gzP2H9+9G83e3PTtpDZ+q06bw/bk+c3nQymdt0POge5XoVBXfUsxZRsA7LnTsj+AP43NmKuh6hjhOxOJb5wiAdHq+DEUoStgqDiEYboqge4KIX23F7FinZn9jyGXN0iatguvz1asYT9KXfE/49gAGCGWS2InyESpO8lDpbPCMLoAuOTrvgcIAhWukQddPhuXGSzoZmEjBvFl+z8qBL0qAkQtKu/f0oYXHyHxmYTwIBWZz0i3/+mPYdusfVUj3ICRL3wbTBkrRF0kG+sFBSk7evIHZK6/Oxai/pZs+B2Y6TiCZBFAOCYv/9s6dgVTd7brp1W6+n2RF8XXrmC6OreKBZrqPR9KQ3PKG99vRkPGsP2bzfntJ5tz3pOSOn2z2Z24Ph0cPH1tGndgwbHEyqbTvwPA5uacuFY0nl+YYbsFmVp1gVzYxnx6Y44+/4Lzz3HqalSgI5mVJ4gPcIjilVV4fQBMvECY24FKL2kgjdSFmGWRB4jPqqqJNPy4pO6jbGl+qmAoaaUy/OdzvWqQDlhH9fc0osAInFCV1pQ/B2tj08SiPnI9jZfFE7ggZR0yBqcqX2jrpoDxqoyddkBnkaq4XwwT+x3eIHBSM8ARXKl8UJfON5dn6Eu/9Hu7i/jxw7OBYzQa5m2YFiHw8paYBF6dtJR/MjnOdGl290+UaXb3T5Rpf/PnT5ePnN6PBfc/KI5upvrv7m6m+u/ubqb67+b+TqB1bib+Xq/6qp3n+Eu/+rRgfvdw015OnbIZW7oSNxUh8rlnI06d8bL3UjKn40UdEwPX8GmYFz/L1xOjey4oeTFQ1L8hcTIZiH5Rum7/zepUWF6a8EHk23ryj4/bN8HsgckJJ3bnuWq/DmOA5sF5cZ8EDQKQ3SH/qS/iynWemcCJy4dz0PkMWcv9GG4zPHaNU6SHkxImO+9rxN+59r6kHkjCPXFpomz17+PxdvnnfyEhmgyh3x7wp65U9tunbchM5S6HT9DOjg09/2HKgDXldEkyjqEzlbOy4DOs1nZ79dPCcJXXQEg/zcFRBydXNmk0ju3WSJv5+f1W/Xk8HJeDimozGd9Zz5mNnTmePYJ2xk08mQ0flg1j0ZTyaj7nwwn89Gzslw3hsNhtNeb84GkylcGSv66RXzF8ny6HQ8LMoc3bKrk6ANnpDDhgF/0d7nuzr4IVZMHTOPs03Yp8SK1p5GPr6mib1kMUQrnP0LaILP8tEs57x054OfBj6kn0otETjf71yHRQaRbEqPdEitwte2VRWzdXaexmwVeixqr18DRiejca9P2/2pPWkPx3a/PaP2rD0eT53xqDcYT096R6nCUG7+UY1T2qVDSmft8Ul/1h7OnFl7Zg8GbTqaznu9QZf2enPeuAiCl/NbORu8O5tgHRkszd7TUbgPXWDW0vaxJVbuYylQTl1+IN+SZm3tpjsq7OQ6FUbEisbrmZDyNIaUdDz2ESfmv1gUkPcRcBkH0YL67r944Ci5nJNg5Sac+pigwukGfovQcqXAp7xOgvaC+SzCU1/gRKYObGT3jrX9YO23l+zT8IY8Y51Fh9zMoyBONu1VEPjtEzqYaZ8+N8/rVwpCt6pMsbWCOp2/qlv5ETN4VpgT7YTuO678ILJdYq1YsgycCrn2wp8Hkc2I487nLAJz6OuXZ0S46czEFK/fQErlPy7PLBRHcZHf5bwIkRq0QxOaRNS+ZVHHZcm8E0SLYyewj5fJyjuO5vakdzL+t1jENfbrp3M1p+UoVaWf+pMpf6w8mOID7ZIEkeUw7kekC22s7Rl5eXnxtk9yhQgvRM7OfoEwXOYn0Wb7+qQtmLwl+cd7vCt6w/Ik8spEXR+rZmL3kHbYnnwqth+Udq6xtuu0e/1BflWq7UH5Tv2+ZD6JWQKH/AZkxk0LoxpjAj5X7FnpLiExE+G1JE5YCBz0rr8gmKVTG8iYj1zcJqgqTVFP33nyt2BNViDg4pDZ7nxDAKBAAl9XEYhIxRBnMHJlmHBL89heU8UMPz6YHgYFzy62C7ftCpDSuR9b6ynLVDHJqjzNZuuosBv0q5EveHZRWqDMOFWeoBzFDgkpQNBEkqVIfzo65H1A7lx2jz/LwRSLUnE8XDst2CIRm/NgaFiPvzvsjnnQT+IE9hr8kdiJj8/S605+EHfygejHSqqmwGfHso/HrhO2AQOy4OM5fr59m3P8hXYD/Q26+RbuN8Ltu+Tyona3/BE3Gq+RuM6f0DrJ64+ZHbHEpI1r/qVxO7zmP6FyFzM/dkG3TGWm7VFXZ/o4R4waET/vR7TBg/7vWIS2E5xZWOCIcepcvP5SDB22ZPErUS/eeXXKd/oNC79zAw3sM87BIVRs1+Ec0kTS3tQf7nLP9B2DTCUudIF6Vg7zptkz18tg7TnkPN2gJIk2sOW9gDpF9U48cwQbAC4qte1g7Se6i0LXNX4JBtGmegNzsZB+SNZcOdm2u6im2J8qehFGwSrUbO5L30GLHDeKSB0XGREQqUVFHhow57lxKks6hFf473jjEtTS82QKDErDX9wIHg94/IHLRlYmyBZaxGcLChhHErv+wmNteK4QeI+IFny8t3nlQRgGAKDrkMuEMD9eR5KsJ23ajf2fEhJGLIYeCIMO9TfZcO6YqBofjVJCAvGDTaHsDEQuTDQUj10PvEYbSGS3jsvdbHG1z7WjIA7miSKLPZrAe5JELFlHPl70yoym7BSERVEQpaPleo0l9hgvEa3DJBbtEmi3DfcAimzokPw2U4nYp5BF3AAGfB/4kedJ/h74OCbMTZZc/RFeK/AdwDxFbMWATIg5ac34i3h2wdrayyAAq26Axl2qPM9kCeolwYJBC9rzLRi8cfMcIT+7Mmhk+vYrZVC8DoGmrJKJp/5481L7nuaHfbxPu75X8A2ArPsBWgPrjqzY+Rq1NibuarXGzhPqO7C3/QA3t3Bloa+I8V1+51LOyHV12fng6+aiwGJS9phCvKVi4Qfksv52uD57/Yow3442fD8phfAV4LAE6KcgEZXtrXGH2+uI7y7fgZN95wbrnDsh7nzwoTfy2OO1g+2UJiYWAqHUrLST8PEXreemEafFGaiYmUplWHBYJQbzpBp20L+iJrXlauCus6K2JpROnJBzdN9qJg32zdXb6/f4dDsu6dPx8X+7zsNxcQZucnsslQrc+nZ0eiSuP0ULGHanbD4cttlJ324Pe/akPbG7s3b/ZGJP6Hg+nDuTHf28BerGHXz0rhOK5JuFh4JQT4SDUdT9sfQ+4E/g5oXQvBC0L4R7yNuQd9xpngxfg7r7BXTbRpFtFNlvUJH9jFrrZ1RRH3/bVjtZ9BeWw3iCU05Feke9NftK7ymNXAt8BpiwEDeK3Di5P0oDItcZQYcAP4o7B2vPnNoMME1HraOFmyzXM/iPIIADjMyB8l9HrSPP9W+ZgzUCnQnYr9cB/OM2gWxAgc/kdg1dfwEbtHW0ob7DPkGT6WDLltBtCs6Mxixjd/7ndrO0w2w3NodXpp+jjQseB8bxj/xrDuXj7wpjdc9Xiu56TqZHkjob+a4Db81jx/jptYzPaW0V2SoZ1ia+hiHpVzid6GyyKpc51nL1FNSzg8I/v9Cu2UWmNhutuNEOi6B9yO1G18ZoTGlRhuennku1Scay4yTq36oNHPzJNjPE5ntBpFeOZtS+BU0QrHnwlbQU5cKJIUlKvSLyb/N5t9tVmfIhWsD41Hz1gS4/XjKcPTLZNHE9nzuupzIcp3wKjcTuV38Om4Czb2NjPn3AWbrDRVCO8V1zeIak7z+A6nPnjUojrXRhNrWBhlUbw0j8NRF0X0kEnWaRz2oX+fMf/Cd5vO1zvSmWhF1QxbrTo8lntPde28/m0NvvJWT6JF0nSeDv8xzyggV4A3gF3E3DiEeR+my/5xHvCsZf1fQn1wn4WGLeDt4hmx74Wb6TgUuat8L1zHNt65aZ6otKAXWlbXp4M8Ng1xENDjoiabevcfSfZ7b9xtH/Izr6GyjwE0GBxcFKvbD6VZSfpZ5euDZNNDw6s3v9QWe16cgqcJNv7U0YVm/brDNhSLbgI8R/USQ/aiCKDUSxgSg2EMUDQRSlHKrHKDaqyw+uuphhFL/QPfzUl26DsPoqTtkPibBS7+htAccbWD7XkadXz75UJauyj3UXQTrl//2QT9nMVmGyaYvvUnKp7PNCxcXhq78qdsW/8nEoP+pnBLQWzG8sHxTbrQqIWTW1l4usA+g7S/9796LxGv9WXrvflwg0lWousQHrek9jIkrM155JhmGx8+EfH3GC47WXWK4/DwyQWnpJ/T5IqKekpud1Zne3wB0DzJiz0NenpgdTi0j8UHznci0afkV9zwVVYeH6+BqQ+elF69vbYJGlb+dNaSShgE6Y1t/vgpSFabFq50zWT++o6+FLB4YVrBM8oTGjkb1UVJotbXazVlPIQFnEZ+uEn+K4YvnqBtEaMdEv0JDrp7HbfXhIN5Gyf/bJhq57ZiAIsSAG5AFpyeOpHLcKYQhHvzn1pVP/2IV57LqYuHoqSBdNDL26ood39LBPITB1WMZe+Qzr9dA6mrv+gkVh5PqmvVFLbCUvK1LZGfMu1vBB7q6tnjylJ0jdTyaegqoJu2WbdNL2m5a8f6DcAv8dGzJqpXKUg89+bp4CmPldH5x9HKaTJ4SO2nNEba8jm23jrcqCjBS6t0snteqdX74mv0DEEZE1/oFQLw7IrR/cA6Mcfvbh6NL5cNT54F/RGKLh7PSlyOO7vCC4XYfk2c3/ynft389unoNhN2IhE7bhVP/54Gs+/5+FP/z55jkPjApuyTokq7WXuKHHZJAUIDf8VCVtffDXIXw+6vLnbNwhr9fJmnrehiDAP4Y4OrQt3oDdTGnppkVuYOFuWh/8G66qIe0hdf34poWmXvnnOKFREltQzU0duW2dg4b26YzNRt32aGpP20O722tP7JHdno4HzmA2H510u3N4Fq3op0te36hbtf5b6AFNdsBvEIT4TW0AThp22PWXrjH4b/Re4WaQf3n6TTFzpidsPnHaJ9PJuD0csEF7yli3bfdHjkMHAzacdY03RQVz7g6bQtbWIblF/+B/tlWfux7E48422brLr+IPfn7xn3bSlWmuNu3C/KY23fS9LF7JBP2fHXKG1fDbx14y+1Z86MbCBCfebjfnL9v82zavs315cZMG/fIsi/UmsslkNh/Mxs5k3Bv3huPhfDzqTucn/d60O52y0UlHoGlV+uzSOKtMzMpYuW358OPl9e425pnjDHr2zB46zJ5Ou9PRgA2mvfFgPpvNetOhPR0MegObTuddOmbDfncwHNP51Bn0x7Oe06ejCl+9bk7AvS5D04qsmeIn+ToXMK8NOA9hrNKBeJOr8EbLTV2YzkvfhlhnH+Oj3YQkkbtYgCikJAq4FfYP/MBJxySvnC9AnMD/nmFENQuhnbWfuDzIGlQP4gpnrgOH7kbWURi41PVocpNGo+e6iU/aiEEQNARkx8Rj9JY5LZMawVUMnmH5GG2RFd0Q4SuW3L3rZB0xLoB1Y3Vj4rixTSMHuG1XK+bApHobnfkjxYz2alkuFUtunbcs+6rxl+3gL0sDCwSesXjAS8+NiMFvPBJBRi1yBgC91cUngjOjxflBufpwvwwIhN+Lkik3pRKZLz1VNvVV/gx4NUTBerHkkkyzPtio48aiVbAAItWD8PcbNNECZmeYrpTOWchSDNx0mRF/aQMRaSAiDUSkgYjsBxHJJHw9SKS59ppr7we99hrcRoPbqBCahSO6BcVReTaVdS0fnxy9vPr7HhTzlT038FDsSj6SRT6BZ6SIDansyEfdpQMCAkXJa/6RshbBahX4eFq3YWiySeaFEMhuMGdZCyaIi9zHuhsxbRrO7Ao6V3+e/gEOnf/ImXCKk6k0WtrMuR+VueX9eAN/VmfT9zlZW4WzxbmCXYz6nSrR60eAp1zXCK5YBewBf+KvCYfNQRYug3txhMBeIGpBTZNGC5agbQCUQzBscFo1bXxd1U3thKb+5UL/LSiqhseepx+QdzjA6rEDkCeij58BuFIOMQtxvNx3FqDovrMgJr88B+8urtrpsS1PiO254SygkUNmbEnv3IBHWb67uCJZG/H2YUsuhbQ+ywts6lnIiLAKEmbxh8Cu3Azb61OSDWcfi2+SQBR7bONV9anLBXO2y5KJnaJ5S1//WrdkT7+HcfwWj2iinkt3mrdcOfDvCo+RaSXZ90VBnP2iiOHr61+3zDqkn6qxRJ+LL1KDtHipA0rsp5i8cv+5dh2SsBUQf4KjR7y7n/3p30nvOcEIbrgaqe8m7r9Y9ukfCJ3hl0FEuul3HltQe8OxdWAQBjsNi2Y0cVfKwqC2iLbXOntrEMUWt/ibEhXBEqlFjBdVLSdPHP6RJ8/avTJZLldZELkL19+9MlkurUwhpt2pMrWcIlj2mDGllFLRHrOllFIq2mOmlFIP6CC1BBbUBLknvs4hLECfjDa7KI1rozxoC2aKzI02lh04lYoifkHgCy5AY04qO2Nca2ROvdb127VGUVRaLWmK0PGchsjHq0wZmtwaZKYemblDvJCJepV+rwsGMq9AlHkCwozduI3Sz8E3n5Gbm/B2iq+NMGB5X+ohYF79PWh4ngA/uSd4N39iTfCWzZn9ls9sPdXufkeWH4Fv6tD2Tj7Xqa2Fcz7m0Mo+lJHMWYAWZNTcwRuYA+TKxpCHoc25KNqC197kaDTUFo+jtngorgFnEhUboqKTfHZx9xDxJaiF95j+gAo/DPhnkiXboJXZYb7LUyaAg0U8s7cRT2n6JfxXlX0CsjUqU10Q6fbilsLdesQ/n1PXQwCUJKEEnnKH2xN26HMVcvbgvTboUyXz7GefVD/w26n3wHRKZezddq63NITOkOANvxchCxqDh5kxMl/s8PqumAVI/F0p9tAs8uv716/qBcQfoZI//XEWOJs//XHZ+5Pwfl7gGv7xeNn70x+P+Y+YZ7wqCeTOl2JvHzpRTgv3hbnNtf45dUVaJXZSZddaGDotop+LQE5p74JDI79LozrBTSoy1bjJdsujrEt/qAu2OLVB05ClvRbP3HaoTgFdAAY++QMJVm4G/YWO55DYNaY++NOcRX5bTNKmzXdsesjb6WnVc1Km01mxrGKV0jP5g0qmH0cOtI7uaeS7/kKjeZ45d24MucXEDob9PHeRlTEWya4AdA3XIE4nnOkg4sBDzESlGMnfrtwkkV8jC0Jd7IHJDIqqrTtX0kaXXgcq6kC/4Q3M5PMgmrmOwyr8tyB/xKPLVq4skTELh5vpG3mdgs4hUENqELSsQ9TfeePp1JlOxsO+PRoPnT6bjEZsOh73JtPp7KQ/ElSqmXLk6pLfPW4Ij+1gWWOXrP11OhwP18/iEWeQBy8OPbqRG0yoaQCKTQMnVGLl6p23pVGev4w5HDuU11V3GLiOCVqaCOgmtjDAwPKBT1UGKOg7lzEZQDklMAHKYpytLF/PYlCGwta4mdT8QhoSZe53U0NYEnrLiDuXu2glPAG4LDyhDsRozCMaJ9HahjCFnKItMWyIepOQPG7AAjeGaLF+L6LDQ0FPyX/Do4GnocvI/VtHs01I45wFQY65amvuN+on7jKgvi0FVBJEjafBzGrprz1PtSzsZXUSCwCr38z7Z513MAT4wqVniVA4zeguJCgUIIRioAAV9TeYRVMWhD8qsZ9hFCT8EkjjKvll5FH7FtJnKhFpQh6oNwUEf6UA402wJqt1nEAiTxBykH80xeRDXeUKeHgEyg80UaEITCI6B4+qRP/Wd7dDXqYs/jH24Z76iBiZpRwNFPKcxjgP8Xomvm0R6vDoMZECQJhFbiqm3GKfQNdjjvWvwGeoK8c3BC9d7bapvXSMW9A/y3Cs8BGaJHFReVmeNbRuGDdkzihcSx3yTtkTNJsZsGtSn8jO8Ha4cuIF9i1Z+yq2z0nXa7YhAoQNNwXsQMyAS5XAjG1bAHZedrc8OrRXRUVWmH/TFYFnPHbICu5YFLmObu7fZXgl+RUilsSwltR34AP1sOEVqVTfIS+ovUSVGHWAFdyslI+aU8QnS7FvW4RfhPBnOXG5DM4d8lb2Fc18wj4vVDqx+ZW2Y5zs34PoFgDgyt9z0S2lKc7LdAml0+sOKdAO9lQYepsUxgqjkBNTl16XdxtlIMyFFdIkYVGFgiZDg/ms8S8z4Cz53fUciAKNybObn2+e5yepBST9hFHk5EqWJGYLAMQj8GxJ7xiBzRgACxnf/1hTh/zme+4tV9lu1pF7A8dFM9WtbIeonYuJE2Awq7tShOQdi+D8wYfxH1BuB7jLWiJVcdq6NgopU7OOl4x6yfL45yPEwLxi/iJZHp2Oev3i9ZOb2la2qB+LRqwHlW6gP9IeGc1JeSXo23K7T8Ht8f3cIe/heMRrsKQx2MY3MfPmyFTDHJFII77J7gbY16sgYmTusU/uzPXgeen6HD0IOyxL6gzDQPi8qAUvqxu1Pze4HwQ83sGc2H5FB+TbzF34QcSc+vNC/c3b+dHp38vWRLFPJBEPlySqns1nqEOuNGdXbFzYKG0hqVF20kTZ6eSnn39CuTJjHIotnFR8glBoYN/zZzon8kx8v1pxqZiNDA73OnL1Z/q3d5fyCZ+Tm5o5+Qk+5m8pkVEV8nrn54ZHHv1dHqF4j1gX+WgTwz+mYdjGs3r8XHciVdxsudMlM/FDqyhibdepEK/nlxfvSER9zl1YmqJrTstxeRWnOxYWcS2i8I8Hfa0nR+5HfZvpbtW1mCHhOAHp9ZtLifycbUCN+PX9+6trwrF5+jQ2Qwi+TAI7qPB2vRoS+YG2CxhxFnCbXIvMgmRJfru4wvV/f36Vqic4IdUBFWKDJja46tdOyC8gyOKO063vGp7H6uU45+cwpUvBzzFQKy0Df4qLYwBFFX9QO63baAYHLnLvpI38zq8J4/3rmxfvAXQhL89t8wx9hDJx7cTmjgLvytazUBSar8+v+JYCHg1VmYRD7rbRhB54cUcjSHEQavm5MPaB2ioCGSl+ANNNPZ1sXNmhxYtXzp1pD/dZwDuXWkoXeD85OjOlzHX5GK55F67wk52nWRdjJlTFymvqTH1ZRsE6kbHdTFbHpL6pBse7wMEKQfHsnjgs9IINKF5xKxVa6TsPFAQmWEPYvXWPVd1w4iV+l9yoAxWXPlirsAUbAM82RJTiWxIvCu4tITGDoOEkZ51DhT1V2xAnL8110sPFB/NT2v8YznMWdgmXwhe9YPkM4XHn/1m5aTOAlWbBA7kE/PY8q7CQV3jmspYVwHD52fHYbXm/DGKm20javYq8AhWbVVeHRJ8V9nH1Hq3Yjk+1G7+iTZc/no/dfNXL+hTb8kq0s9f2vOK94aal0khimf5NRrornVbFYbJkbqQbcIecKU9QdWNJxlHcYDZaa+DBBYHdMi6Y70ohMVslGdoiNxBckv9rSmpXL1ufcDOLmWvlJwVe01/VjoepE1NWjpTgPtpsi8EtKXfEnvurRkjtvPWedlc128dw+xROntk2ykurLdvpY84amvZGvMHFC/wIETuKpfSYOivXx81YU4D6AVp4lXJxQudzLMffr0e9bmfU6Xa6x/3hUf4tdTTptqfdrMfylVIuPDge9MuF9SWzZ6z8czv23Ry9obZcQcOHf7f5v9u9rIReEYfyyrb5u2ofzSYub8hUzHQPmb1NXJ65q/No3DuZ95zucNCj08mgO57Pxz02GIydk+ncZpNxbpnyt/D+FanCrfDn4qaF/qfMK3/P+a0As2+FQQy+BguJHw38hSBvVLN+vTsFplUPgq+BUxd6pg/we+HPA3SGUcK/J+J7brhfAr3h2lc8h972yL98wwaItBylRi21tRDy3DFx78fi8Z7ruMLRAhrTjhQdrSOlvLWu71Np0gpt1+AEaJcOKZ21xyf9WXs4c2btmT0YtOloOu/1Bl3a681L6l2xZyVJWph5RaZe8H5eiV9qd4lJeFS6z41uD80RgTgcmmhS/sIP6nSb7HrhW9a6yfgKmtQBYy/ym9QWUDzwRsc4CzwxbKDqejU59zGL4/wEViylR+PEynk6lTIp7EjTZC4Hkq6W3ngwmQz648mJ2j0E71cikexlFPgBMBbZ1CNBBISJkmolBrOiyD29BcYGFatkWfIPUjER/6SxnQMhcDovi/k8xoaDXxEmqeuvBFrIL0AkMN/h0KGcUsd5WhE/kIHbgmhBffdfRWmhAWQg1VeR+qvezxssrX/cJ5Ya61aebPkrTupF8Cv5y+/vCecrdrGjQCse5whpkTKD3Ay63VV8A9rmTX85HK1uOoQntEJy3bUPli8asVMCDsJ1TJ4FEfm//yd+3iKruEXiFlm1yLJDyJsgYRlX5op+clfrVdavdK5ilnD4ORf5MZjpBWO7CpgDFd4NnMKjoEMuhL8e6Xf5l25M+sNlPa90t7vcAnBAF0yFzTxyVzTaZG6F1FFT5R4UDp0yPtJNMzvg6rixCyhJsSRnYUhe0bVvL7dxRldqwPnhVMHlRPfEXfznILgFOoz66B9NukGhn26d1Spi96Lbq8poe4ipqKNFQOwIzzvFw+R4ke3hETwSL9s6W7Spmi2mtmtIo1VHoCWaKqkVuQ4rSsULpXl16tZa5odUFUF2uoY88xA5VnnIZkrELzFRF+uA/ALZDlybvL28OCfvmIec7Fc0SjZkxRIKylf9Trm4PPvzea8/GJ9Mpt1efzAcjU8MUrIqXRIk5Yft1g6J5904XrOoOryQ/47hhYfoY0aSG7na5K5xHLQhwavD5v1OHAcdZx2gsHITnuYV+BuPtfPeJEVvGK8bxuuG8fpgjNfOOqinum6u6eaabq7pHa/pho77qzihPyQdt6GpB1YMoPxeIHI0FRIaCeMDmoDMzT/oeExhJNQT2+NmHkTsDpBM0CzEyqIFBsEA0Fy8n9noPQf68hCMmPTIhtEI+rgM1lFMnk1Oxt3llg0x7q5yBkIss8UukTFBNXO8/xxnE8roAsPsRHIIOwhuXVRJwdZXnuOriEGojnvHPMgyLuACwvQj7N2EVwIWQJgUxfwGNiOeXq+d/g0w8G2Ogc/F6jjrSKYwQzQ55jznvST2krp+i0RUBNlRP7NOQjzZv1xvQzDqPooTNNZlBkgeKROtWYdcMwzeQlMuRkJw+zBPZw7zorTIhyQdribBe+mc53cwWnLqbEnUcSKYzcqcmVtI2oOl34lXbrLMM7XnO1B1fngXRNNgRK+9vvlYcq07Aattt8KiqB26GoHkL/bpDhSp647luXGyjXjVL/QONSBKoKippRG+3W5n3ObplE9diOPhPByiZ4WuHMzZqfFvKuMpmSHxr8UZNma1xc8NJ9TAvb/tmO2/x8FwXZsFgRfRT11p1nITFiabHUKeS/HAJoHELRR3H7f4TreXf6jqt4nv2jiS+ZC9xOBha8aZWMRNp4NjwGf8XhPfCunfIvdL116CHSpiNGYiyAyUdEFRhBEwUbBywVsK0iuIhHNR6AFosTq/fveS0CSh9q1RfqHCCDRCQg03z+s5biyDpjvkLHOA5j9STIGajBp/4HEuoLNo7W7FxKJxEoRkxpCbRWT+5OGPSKvPe5XArQ+dQ1MUhvAImyT0ImJtpdP5vpYzfeY8u3SdBCsKHYc8zHk7Z1atIPxwEzWLJzowmfMHWBrUcVB7g/DIOBC0PSCvht1pXpeQdd4rMSugfHARvWu8dub3LkOgVBDg9jP2NSIMK8b59Y9v93HVx6xeFaIzs2DpeFscq1E0qBExrugphw7mJh+geLtUIeB/j6kiv4MeVVXVltqnnroj+PDxQbPwAQhPK2eLLa//zz//mSX09OefyVv8E/UK1luMPqY+XaAc9cnbszW4KXJ3yhzClEXEl5cHM2AAXcySVs4tDwx7ArKhq0/Elemon0RMC0waTRD6gA4CXgu/AIT7SYYO//3dy3MyOemeKBYmmlCgoLtlUcdlybwTRItjJ7CRW/I4mtvw+XPy7J146BDh2QqEHZq31u90nwu0hqCXAOktriYPQ7RnLKE5n0KVY3/j05VrS7briC3cOKlasmv+wlS7IspLG6ta3jQ5DPU3VuDzbDggDcrtIllTjNkNRTs49enTFMOSA5+kVWiunCw5iGwuCGeUwwf3a63XPwG8dadX0xrQJEduBT8YVoQ7BjPM8e8JjQtNwWSLacYrnc8xA5Eotl0H435RgvIAYMTcI7UCIMFcn9wc/3yTBZsKahYeVd0hnDC1jTJA9GolrEE6chmuqPCa2CdqJ96mPkK/hIZUSEPkwVBRMDBMXBowMK5SgAwNw9NjFC3ZFx/zZOh6nbBmj6raoWYVH+qqfw2yiTniILhx5jxC0motBC+vjkmdrV4F1hIhLSLqa06K5oTilzqzTTUQGlkSQde0PHeOxmn9Bpa/KshozngM1PGPBO3VGwZrX/ojNHIIU5ypRVoMgc+ZKPsFxwCowIeHB93tWqMmfD0a4xMGKeKTowpetz0YUTujQahjMfW1p5jTLAlykSrbLUgnro8IEYnhXyrYth3cA1QBaw+DcO1JwiKt4ODMNDb1Ax8xyXhbtNG4DBULSicQL4LxRiohkoRSBHC1uDU1p2m1yOuXZ8U/AaVRmUIgNtEp5M3nOuGuWaWwCAff554Ou+isubJQV4pdNNnwKY5wV38owi0qNN9duq+rAsVZiSjHsGZdyVoHrLqP4astCUWz6pXzX/wrHxy6NSl4KiFjIXBkIP49DC1PYIePkFYYWEFmbgwey5lA+MKNSOOlFeNf3RznJ6CTHCizssX/lgFjuDU/bWB2w8D1E86Fg2c+PXIV2plgESmcT5WiD9XC0jPhceTE0hufsUD1Wkcr15f/qJBvuk2jGahqefUd7lM5U9htdbKx/DT+im4ZA4KjIgsUyMhAvjg5dtv8OoFWdDfIV30XH4yl4iCXrriytnhF5GcG3hDxpf7+Brs84SWF7VoyHsJZ9jye/lTXShZW9JBP9IN1tsV3WrbRtEvqeZN/U6biE5JolTvOiQ8ZeNYzQUPJm7fvSRqTFLIIzAKIiRGvOqEFtCRvsHhorBhAI/2NXNoXvNlSrpF9xBUu4kNpSDrf6n6DSoPPv8CwcsG2+T1gg7kJA8ja8iiwpLy0Ol/vtzcP6rAgppp6lui+zEBcHqXAx3Ka7f//+fNnJDNNaQT4UZSTkLohCU8sBK4DkbsqchMWudRADJS7ZuAiFR2ohv0BdbFUHtDQSDnzIQILZ+sYKIBjvnD1alJq6LijXqfgj79lwNy+axdk2JkaerSOOT8tJuzaZGh46ZkkNibVAvc9jgDQ7Xt1+xj6XHb7qvOpjKvsCNasliosxc/kRfZzeRdeVt1izlV7AbBMPF+XTg5HYgYhAbs3pIkINiyXAzqF4NVgll9mML0GuFwDXDaQPwsOrm2jetvOwKNNwEkTcNIEnDQBJzsHnEj5XR910kjwJ5Xg7f7nk+FNgEIToFCQAK7HHAtrb3KrlHOrWK4/10bOFyXhWud/fB8AGW6WW4rXmclAwQia4e/qk0sh65SODvpcaCOYbgzuTUgLAEgR1Ko8QYcvWt/eBtg5te28KY0ETie2alh/vwuyBKbFqp0zWT+9oy7CP9O8l/C2jxmNMHOCvBq2tNnNWk2T1dXlAMNPRaYy4esUrBK8X6Bp1E9jtyuS6BVgrVvyW2RcKEoZmccSjw+PodPtSIX4B1wIgozuPWSoOAvBEUDXQMY2mI6nPbs3nHRpfzDq096E2Ww0PnHYzO7PBv3RqD+ejO2ZM5gwZncnkxNKexNn5Azm3a7dHaLnIRFu8KN+t99vd+H/v+/3TkfD08GwM+0N/wsUVroR9G/OyZhO6LDPqDPsDQbSFC8Q2Rw+nRfg8hO87E6PRie9k15v0G+z4WjQHjI2ac/6dNSe2DNKncFg0O+KOL/8pOyb5lzAiJBqKPWGPrmXD6CqWeBNEmRZyQzrqyovsoSWU2ab5PcslMoqqswZbV6rvoqsiXCHq6KQ9/Azezp18AojZ2S+GO/4Dqq/Vu0vQlBL29kEkf/1b+g91pdrwd/cCkO3t62x6y9YFEau9k6FPAEXI6J8lCYqzR7B9bowlH+Zlf/33ovTSfe0+/L05Oz05cXpoHc6Gp1Ox6cXL04vRqfnfz590T992T2d9k5fjk+nPdVqGAQJiyzQeStuYvxJx6VFeNk6O35+F9dkFtnAZ5DdM0UzQdXYdv1MZM7An2KCiSXsDblCbwSmFdZZrhPZIlS/c4vywXN/f1986YS8fe4MOa6yAKDVWZNdSWXoFQpD3ejE4Hbpj7JFFzRh93RjxYzq9mi0ZpJUDb7AYBAa4Ub9hZc0IuSrCaVQO6CNd1S6gP4XoFr1gsUCs2kIuv7fz95dCeykQX+UxnXG2+0Pi2oCi7/BI5kD9M4lj4U5/YPr/MmAkaLcxjX/8iA0Ew/1s2PEefr9zM89OPfymYNrJ8z0WRptdGiIbdyhadGj366Pcu0mjZ3ALAerFt2vxNFZwOqN8K4d1KuKGri2tbR20onUEk+pruFB4vHJFhf9Jvp8VkDj3HnkA4GjGSqz2xrBj/SlqyuuyrC6f2PaGqED2yhzTZqsrQMZgqy1a+WcgiauikIpyMGGtkeHge/IsJZcEZAWc2po1RYVBNHCUgqJKkL3zrplG0soUJjlwlQAVRUXVUudzJoHPIwMLcDmdevL7/6W4S8ZtDWKmAbXh5Trd+bHvLL44R5JWFUSuXZSaA0klmmdleVBR1f2oJUEi4XH4A+xcY9rKoDquT/bXNgpBTTCDs8fKK1WZh+UE88sGZBi0sz2ih444pjfDWCfmUXBPRQbdnuGrVSXz1W+516pqQAe1tEakd2CZbrifZnmLKAL5BZRAxFiIuqAaIUSJzhPbqyEF+RzDcRLCvrVvjmju/0B63VH8yGz2XxCnalNBz06GZz0na49GA3gDVfYHfuaOFU9zkTRbjS5TJN7jKIlbLG7akNZmgKNfPh+NZmDKBl8yg+gZuxqN+yNfriLrHaffsZ7TJhZm9vA8Dbg+IQaENAvbvIrIhgaCFAD4mxAnA2IswFxfiUgTi676yGcjfRuAJwNgPN7BHDyjlmqVrqVYfMXLJPPdfbBf8dbVT4ob4itcWdCGKlVb39QlwT8lohc9J8Z9FGXaolORuNen7b7U3vSHo7tfntG7Vl7PJ4641FvMJ6e9NTDqUEJ0ozhpSJbnKZdZYnhLDK62l47flUblhW6bfyoYtNo57W0w3RL9jF3dRQ3i4LlEAeg7uqRR6S5eg6RtuJb82rrkkvYHnVXmsf4uYhy5T/v92jmHMMY8Oki2UaICwyuE7AaiJMhfIHYEveLfKzIYYrVKd9VJO2g7oqfXSS7Qj5hAfJxHUsSlXJr6xZBUepZk2aqeTA2D8bmwXi4ByNXYesfjM2t3TwYmwfj9/hgVPqzVQAg21EcUrsRBY0C3yjwh1PgkeavOlc5LiBya/vAD/T+Vf0WWW34txtJoQM5J0LNxjiX2hTn/OafpWy4OHZx8NVUO9uMGzED9ifpZVUEp8/llg2zhj8UvqxYs3XMhO99qQ1nSeEfgSACVfLgqPBYR/IAiXQ9aNriw8PqCVTP0zSotKT8a0mMhph/KQXL+cQrXybNo615tDWPtubRdthHG9waJi+3RnH74RU3g3iiRgtZZyTI37rK0eQ5/ioEy49pVICsGhZCJSHwCwNUBObScn3wTlcfKYp5iPjH8s2VA1kC67JEYYrzx2nGeaGfYmJHQRy3JY5TnEBJbalPqbdL2HAUrENLaJbbvdmOG4ce3bypfGyKD3K+XiTj/AUaMqTkPHv1irx4ffXq7d9evLjmT2iVBtSEYj8rsIvgEITsDChvKgC1Il2P+MZsiFvi+HnHKtIGyRZ4g7UTuDXRvErqCrLr+K5/DMTw8fHMmZ6w+cRpn0wn4/ZwwAbtKWPdtt0fOQ4dDNhw1hXRd7C85mtv0G2TbL7VojXH9JoK2qzp+hZ/45kKpNwS/8SFRBGAwljf8Np3/7lW2dO1RLQ7jd9sFQrii3exTIAgGJWMQ1MSym8//LN+yJJsC/NGyfSg/MnNkwIlSeTO1vAAF+TFgvQaU2FXcfLuZEFbR/4pZFM7RSU8PoVtfCo6fWoHETvtd7qncgEfCoKukXBSwjUbI78xjPgYDhvmreQEMFpv/vU+ejC3Fxk/4/2sJQhqErz4ZizyXDDto3yPjzLBtntrB41KLe+OwRPsjtpwom9gc+wcMfaZV7hmftUFjtduwoQevA1cil+BHl80RBUgpoVf9wKbYr+2bzvT1O+lPuFY6m8ph93FRfLChwro5VZI6y5zsje4VZuE3hgsyqf8Y7W9kU+aAhFdMgq1zSDDuhdE+lmABHFQEHwN8JVckhz5F6+pfg7+bT7vdrtdtf0kCXl4I8/abqU3bbkraq73X5MkFDluoVh2QRukff/P6+vahO4Fh0guuWXW86otY6ZW75DfwfRpk/ZLy56Vz5h0Vt/kCXMcyobj3nQ26tJZbzDuzeiEsunMOen3x1M6HPTnjHaHvVF/ypzpESYBe8X8BQTODidlL0vNC951dKlnvmyH1d41jEr7xOHveI3vGxurLE9DlPA0C4QC5SALZKCENgv0JU/QsFmgp1qgQ52hUbNETyTkBo9ZIFDP5y7TKNCX6W/1KsxWQomcyjLob9GpZKP8VjSagXQMarfG06kznYyHfXs0Hjp9NhmN2HQ87k2m09lJf9QvJ9jUdUKV/JqxGzRiNtjhI9spVppstu8x4dkSD4Lqxnv9wXA0PplMu1XDQd6shCZrjbFQrenN2zcvKuqwg9Uq8FMwZXUdnEEISWu2dVz5VLB6GadzxsqQd29FwUunVpJVe8UpWXRTTR3HTTD/7ZXG5bSFzQhbE3wvaBpBIdzKTA7VY9alPXhoHQliV6PQggBNDVSVUppcFOPp8GTam3ZHaJcITUVa6cxJB1PhB4QdhNs25kmnC/9PWEwFE7NSqIZA2Y1TltTtH68SL07ZlQx4vKoOA2x0FiWWG8drSGXsb/0kvnWrvxEoOuZoRiG/iSG1p2bT4AwXWBcNzlO+RGmcNXOopN6oa2R0Ys8n9rzfno9GtD0cTSbtKbWn7fmIDXtsOu9OZ0PoyB2L4nwcuCZHi2pvTGn+pSnKwLLcgNpyxO4NzrjBGTc44wZnvDPOuCR7jby+jfT9AtK3QWE2KMz6s6vF8lB/83aOGV9MmGvFlDy0zNAccsIMv09n1fB7MfWmX/MV2enrtiBWNyOIlStt+D1uB8NvYc+YVnuL+COzb+XuM/xeblHDz/HgGH4r9rx5x+VJNd2MKueS2WBpHN+yTZxLW1Q+VfxK3OccYeT/TifJvISSzHmn07TD95I4YvcTZV5IninzEnCqzL921sEOVd8mdIevxdkyLyFOl3kBOF/mX/MTtsOmy27afuEMhNacOUxQLSPc/7ODAXXPEeUpculckayPBPvY0bySSjZNo4eTYrvmZjTt60jpTvm1O2PwTBRdZE49PL34uqAnU4cNB9N2l53M20M2m7UntNtv95X/qUrrpOoQWK3ofo6Hfstqi7WRjO0mRsQ9pigJ0vnpkNfrGE0BFGKl3DiB2dPYEPxcNEiHvPVZG24KEgJy1ndUnMyK+hSzuZXflpnp4YuvUMihV/Xr0aBGHuOvq9yT0thUJU12FBX7u/s0Sw4Q8mbRmyTtTZL2z5yk3dDgVtKQDnr6m4Ovlfb7r83eS7MFl5tBcOESQfcHJJJFPC5DgLGzbwSPMz9h/fvRvN3tz07aQ2fqtOm8P25PnN50MpnbdDwA13+3Nx1S1rfbbG7P2yf2fNaeTCbDdnc0mvdob9yb01FxUBIpXA1Ud66qccb5wK4/EOrFAbn1g3sfYuDhsw9p/Ba5dD4cdT74VzSOSeDbqQ3R9XmcfHC7Dsmzm/9V6Na/n908B39QxEImXEqpcPng677/n8W//PnmOeiY0ARZh2S19hI39ARmHcUIROMLid/64K9D+HzU5bbOGHTSZE09b0MwnCR277jMIzf2XG3opkVuwFp30/rg33BBaImorvimhVqp/HOc0CiJLajlZt9tAfHWbBV6wYbBbkUYzyUvOOpWLnMliLtuoSH889tdZ/BsH3iZJSkZ/DeiPnDN5V+efu0hINjCgGCr2zNf+yo8fN3ap8EERL+kH/zPsKZz14Ok6bNNuqof/DTUv7C0BzpPyiyu6IJZ2gzvPBb9Vfq2hS9JvISTEXDtxKM+OopBZdk737u7Whx7wSJo37NZe0adBYuP7Xkb/xT47fulm7D2bNGJ73I4uSyALd/rd2sId2Gw73HFud/ZJ2/fIV+JTT0CmgVNgqhDznhWdJ8xJ4alWDGWEHD/45zLO483RQAMFdctgEloG8SaPZSGoRNc38JAlECfvyP1XQxCwWNx3LYDDzhp3MBvy23BHfPpyOcRxRy8EfunBQHzjsMcC3OPCa2vXidUvyxvXPkr11YEgQYNQw//xhPf4z9LRDx76co4GJ43DcYjnsmaocahfqyHHIHBhB1urHGoG2w+f3ElWRIKvPac2gkI3Rw1Enn2+uXZc3jygJmMP16x7jiJ1jZmo1NGH28fPiYbB8tg1kyg4/t45cYJv/hfvzwjK5YsA0csAr9sbernGJLwZHbIy/oOtki8DsMgQtwPXspIA3MjcizfiGs0Xlpz1wn6+Le6XSn9vaI8uHjVsgo3hPZCqCwm0juLbNkazTnDQd1nFFLic5wybmZwY+V2fY95BjnExVWf1+LmVCaKo414BkIPPOgGZDcVeZrz/b5gc9cXkZDyK5CM1MdeiwoyI63rk5XrI33BsxVe9ctgHcXk2fJ5h7x2fXe1Xp2S7qpDXtNP/B8n/e6SPBt0iUM38fMOecF7GZ+Sm9HqBqq46Q9zipHmquwPl3hD1IG3i+LGBM/ic2mMkts4w3yhGG/5aJ8E5SW5gDLD88w9jjMas5yM/Vg5I7EBJvj7mxIQxeU5iQI9A4pqKhAAjIRGkEXZBp69yKVqUPRlXrKdZQe2NLEHmIfd8UMciLZVCMDFuuLHNS8ESLauKbJPkUo/xYRPTtwh5+mXXIRzBBHHdsIDwk0I82gY82dXKkxA7nBfC7kZdKU4WA5HqxsAXZL7ZeABvM8OfCfukL9Sz3UIun3WvptgU6ckbpFViyzrJchkeaQoZlyg7IS1E9shqzF/r+nCV4pb53E6RqG2TIMq6BphxZvvilDHiUBhEqqvqlv4C7zI6+ewN510hr1Orz/t9MZjVW8NhdeinjXCVzsxj4IVoWgR366niAb28/tkEeA5QkfhFYU+FTqhS8JFu3RI6aw9PunP2sOZM2vP7MGgTUfTea836NJeb14yNuqoFeRIVDHCO5Cfz12mcuYF9q3JJBrMn2b3nEFjd0M4m5dXd2NyfnnxrtSm9tLudk/tWbd72u+d9rr09PR4PCxPUqibpML8RNQXFmg5Qzk+nipbNCDPhXLDPxa0FRrlqU6zKKcnL2jHgX2LBIepYk5j8o5Rp42YZyHnLmi8nAU0cgA0uaCR44mziK/UEASm0LZ+Q1R8TFZ0w9+rMxDQDlOx8bAa71kUURCfmXop2RE592jJDJ2NN5297cyI5UTr38EMqMMLPJFRMd2CJbsD/6V0BcK1OGPoMgS8ASjqhNcHucSj4B4GBl3jrySkfgVZi/VwHaVDfhIkwL+zGbmUnfmJrMQ1KRKQJ0oOc7B/RU5GVIvVzRmFi8jsaVA5dq3V5QlHb8Lamd+rWe//4SYSqWKxO2YCVsJXtVUZt5fiPvgX2BQUyAfUqQGq8GtVEFUeRYKGIdtFZSxYJ3agi6wEQUg32sgvjS5nCc1I+Rih0hy+pDjryps/44TalUNqN7WptEYyYKFmGS19DGKG5z5/9+Ls/QuAcJ9dXb17+9cX76yLF+eX15dv3xy1js7fvn59+Z7/fn725vzFK/zPV29/uXxjXf92fv7i+vqodfTuxcXluxfn7633b62z8/eXf32h2oDVTnnBwmBnhaFF1xrZcbZ2XAY6sCQ7UqxWVYzXnLPbWgZxoo/A5R9EwR31gBvMZu6dTm5lKAHhtcQNC1aKgPDyELSz1JnSlY0kvhTnRmMe+m3Xykv6b+HglebjoXVwWrkQOMr2qe2hdXTrB/Ztuj+0YCM+JRlKKBXif7l8r5mRbF3DdRQGMbP+sY5FlFI+rFKRFAKzspNAy0JEdzy9omDVyfWChWBPbs5Kc1aas4JnpXWEF9pj3QtlReeh6hhmXc7PsTKThH/TITfXVy/evL+BN5LDwojx1AZga4YNHYURYiRpTG7ENXuhN9OKW/nqxZuLyze/ZLcy3LoXL95cFm9ibFa9bIHXIbOO1csOMCNbaz9xPctnnxIrCpJ01U0CA6qKw05lm/TfFk7BHfWwhGHlNRU8tI48Gif5T4wPlLaougXqu14HsINvyIwl94z55JZtiKymHsk36CIGAYyGR6eD8ah1tOLm/6PTfq/2OSkc5Aj/sxwGkcP6PvLftByRqpNduN/5UwhFKsPn5gZcwsQ1cALO1kkS+BlxpYmRWS3y0JJVJLCl9qhHKQdxByr+wMRWnH6foft2A/fxF0HiGRtD8Vt1A1Ztbk3wqbwc5MqmYfTq7qtF5YNxANH/eXtTtzdsd3vtbu99d3Ta7552ux3kyvmvevsOdj1mSLghosYbFOYemPuGv6jhL2r4ixr+ou+ZvwjCPkT0cPnxakPSNSI+IMyPAs8DDoQsyqTgY9uSDif/ijO6DY3CKc9UtA+4xtYx527hYVECt4mj0L668MKEMuY9U7zX5ddq/gA87B1OxS/y9Krjqd6qlRAA2nCOb7k0BGpQLksPdUgMJdxPIel3290TVSH5L8Xx4DEK72LAP+nBpr8vWcRXAz5lDrnJJRa8wat9DnTqLeLOZZSjA6hZbkpAaFXUIW9XbgJPOZcrXDzRMUQr8FhIzHosYFg0Fo3tlVeJx5ojhFX8eAw1H8+8YHYMCe6O+TOvs+HUG1Vk2crUpLusNDeQMYXPBIkhrpM/CKLER+y6GA/6GoSQ4QP/KS7NYzZocibnOlcGn8gC/YUPZOmcQXUVppzNgwhhDoCEgx9YWzqfyLnHaCSRELAAotcAB+Pln2CJ9tCRTVajgtm/ah0QIqgsBt/KhxtuNrKUr6VyFO7KrXiSSPRL9irmxGRw+hFXGrEkctkd09j8cqFmiq+q31WbBrYDRLvye67eu89Tg/Y7XcLL8+kBX3a8zo63IOPJklG+vbw4J9eUXufspURkN1iFNHFl9B7xg+y1gxt6tgGJT6SHygA7WhyUmdl3vQWh4deO5vAYDdmnEgahNDwFkfAKf0OTxHv8rbjUrnY28sUvyyixhmErN19GrwufRa7dDkBNbmdQuYYZsWFGbJgRG2bEnZkRFWKiRoJ/KQmOXEYNv+IXX8cfkl+RJ4jPHFNbfEdpSrPdEp/5PBkcTxe/PVb03+wRc3rAiXg0DwJwY4PLqGL3sU+JDCKaBUkSrNLcc6bNvRfQWSRlwj8SpZ0OdEMkfDPrRhKET9EHiIe1QsrNqLWBuvDlzpOuyxYNFXVCYWrOefsqZuCR6/1Q3Jg8+G5rgsZUlGi0Tsfgcae0ZWqKr3nT7Zji8GBo+9ww1AccLsNr/vfcDAfVcd882Bs2lbywcVdx97OAOOe81I7EO3/mOHA5jCrqh698ILXO2hX9ZGkJkfR2HAGQFfoTJzKSgSBzz10skxQVIwx3NrWXOVtT2Q3Q7inYh8l42O0q6Id2T+msHVpgxQKyo6qQM01ArhqOy6w7l6aeJRMO0uoauFolY35dJzT1IOaKcAdtYEXMcSNmJ1YS5JLcmNRXVZ730F7HSbCyHOZvrN3gDLqShQrNYRXFUllFqvVsz1r1VWRNhDtgA9QifAYdBkSKHMZj7CVWikAVAdjrTQvzj0EtqM3DalBVTQXyxjef7PTzfaMn8VVi5V5uhnXoSkKFKK9iK5U/Fre8mtZaVZzbMJgVQw7nPae+poLdHkqyvvx7SReJalJLoRjf4QldmAdOLsSxeEy4ZybLtYjbUuSwom28Pr8i1xAkE5ErrCEXKly4Lpp7orknvqV7ohH4jcD/XgX+YyR9hYjPxJTm+cJ/3JdP7BXCncmMecE9d1pTe8nNDirpDpmxpetLr3Gn3LnaaIWiudtRMT2ZTzx9DvU442vOXCnPcwlYpMxOOfYRaXO234xhgPB3LUCtsHrY+6zVj2WjCI8EEkR7aTSMJAz6qE5dQqsWNaEOTaieY2+rIUZgwKpRTCmUWuLe8y0gRkhUsh+EaSTxIgAWkRAmAEq9DhzEHzyubwi5WomqHtPDvtpDxWx2cNqtL06rZcCAlQQJSK+ZG6wAumKDaT1m9joCNcKACmt7+YYT6wk4sQ5LiQXrIzjNZHz/SkajVZ6Dq8u/8kAMpQAuFQx+DRSgZEkj5x5YfuSOgAIGxyJ0fUHMVD3r9xzXd3X5BuFx0uWZEh0wcn39K7Qn2YA4b9wpufHZHYtuyDM/wNKy6PMWuQHg3Q15pv6Zg/HAkyYWFL6j3j3dxMUvYfB4la5jtsU7xitQPGPYKXRX2SC2xO8fs4vImruhhOiXZ0UwL/DNKFdGsC4kAR8GoeTl5dU16Q277T55BUeB9HAbugs4dXcwTYgl4a1sjwB54AR4sG1i91+abl0L6Bnvl5B2cmEIlEGO1pmbpKRN/I8OC5mPncaBbELWIS+c/mjUmyL6j5K5+4k5aTV4yJ2AcVwgbOswEfQR0gduIA37o3FrMBm2Rv1eq98dTlqD7km/NexOx5kUVEJ4MzEIBaHAR2VG9F7f+hmBMnF+w3KiQ2Y7MUVOYT4Jkjk4iqkR0SGWh+XjxQETE9Ntsl0Wwk+RjX9tL80OZrjcxMiyimUecUJ5efWMpmcv/1P+9LXIDbfPp9/xf+JXvZE09+97StMfeK3cn7RFwMqOWvMgAgOIhY5szTQKp392HS68YEY9calI2pww9PCE5zX2jSQwgiuSkSBaUN/9F7+aEIq8pHf8UhWgYwGgSgA6CyknfFbUabi2gduNShmY3XcKsoi8CRJ2Sn7SKzU/ScyaIL/mdD2IZsmz48GmyBclz34St9NP2I2fcqybPz2X4ODcaFFK+BsAsLbNqE9NeWVqV1raEjSRtHTFUt/2f7EoIO8jWBG11x2CcPVAgJ5hfkEjdwO/JRc2pa9NUfxoTuCG9T/w0zcLYE0jJisqFwaDmcLsHa9nvAISe+sFecY6iw4Qr8XJpr0KAr99QgezLYfld9dZsIScB1EYk0tfkL4rr9u43mGHppUKR6ScO46JV/D29V06vzw+v+AfGrRdwYGutl1yT7eKQcXyMW7ovs9P2sXVUaFPQ32fHDcOPbrJ9U2TeKG+7bNXr6wXr69evf3bixfXxYZH2yejnACgvr2/BEufXAM1fbGx8fbGBNgbadm2DAvED6gwJvvtZHvLCtTxgA1PtjdcS2aSa9hZuT65drk1Tm1lajyxJZat+gEW2ul1tze0nTbyL9Rn5CIojaLX0zxE0ETN4/rhI13N29agZyBt/hwEtysa3ZqvxusNELSBsdSkCwZCJ6GL2gaZv3B9Bul9i5VXSI/lekX9NoCi8cmstvXy8uJtP3/91rb9t/XM/d9sQ0bkzcvzUvtbhMhXfRM++rIrTsZTCbliOwYibc8rtNiSgQzbR3jmm2koFvahWNjVpdUb7J+c0EebRW1s9X/26H/+o+e9/Kv9z39ugv98qaxxhR8tP5k///xnltDTn38mb0NOblAAycOzDrN5gtkJ8nxgZBxUHUTyRTCHHQavDwi35uFxwrXBZU3MkpY8gveu5wH1lkxjpKsv5v6bjFB0azAdr4XHlArzrchrQP7+7uU5mZx0TxSINk1oElH7lkUdlyXzThAtjp3APl4mK+84mtvw+XPy7J20kgtDaiDg/ml04HNhLxXEn/AaFzE4nHJ1xhKaC+KoYlTa+HTl2pYIio3Ywo2TqiW7VnNP8K6I8mICiFre0FRuUX9jBb7lBTb1gMit3C4KEv70E+3g1EtwAPnt3SVq6WkVFZyv+eaCEJDZ+7cmGSN6Na0xx1pHbgUPE1aEOwZuM2k3onGhKZhsMc2YsIrPMQP7iNh2HfLr+/dX+I6G/7gmAIvmBLoMCb3IzfHPN5gGBzDCnKx3PWvjZx3C9a42yhDRKxnizD7B/ncT3PjSKsCDoLEm9onaibfJ7bSd8jDpYNYwTFwaZHLpyJ9oGJ4eo2jJvgCRJawe1eK6Zo/CuanhCX4wqT6TJXn5lVVdIU+khMLYLDRD3OSFFZhWltR3PNmAvp4LRf25gVvlBqwnQjuqiBZMzR9CgU3zfW898fgl+JHpnRtEBodcuNgx9tlz5xgtoj8Q8tf0taREQNekDuiuYjV5gD5VAIGMM+uYPAsi8n//T/y8RVaQgsYkfcBoVQVo0LziFadRtjF0fqPPOwbuMVJdoxhYUxPm9guPzeIjaGLd6mPdCpPDL1NdZMTfoJt8Uwjm78uL2oX7I76ohOhynT8h/EtlsDBp45p/adwOr/lP+NiNmR+7QG6T0Wt51F3pHIn8/S5+3u8+QFYq645FHF0AMwsLDDZ2mYbxKMW/YUvcPPtR/y7n1Snf6Tcs/M7fOOhxgELyiLoOF11Evlnqz1m5ZzU0Z5XRJjml1GK+g8AWGdOEK3XpXBnFYwhitrjDg+twqwf8Gu0fIwuVIHeKq7vzj/tb+NUlaU+UXqDDAl96Mh8uOIThr8jgmDJ8xEbdhfAR3lMaujHvLe/r3eAYu4nUr7c2syov5hf4AwRZB3MClgxY1PPAYeTFJ3sJ2STIs6v/ff7iuVZvi+0g1KWgE5Kc/7rf5g5C5vPAaUHeG0bB3PWY8MTBBVm5Bvznp9sKwhzw0PAnNPwJDX9Cw5+wD38CqJT13AmNUtkola2je0hjpgofnZbZaEiP0ZCqdHRAnULfbFVX59csmhxmjIRrNKVijjYcQqoCI14EMvVC3/EnIaCF0eIvv78v+R92UpAW7h3zpdqM1jyuGzU6WcOH8qXF8g/JhwKticfs1qSESNqH33Y++Cl4Vf5QxwJRceNVWaiK92L94151XSpdrOeTxEyBUoxauC31tWc1is2bBMQLglvYxPVtgF9UQ65dUjErNWmuSKO02TrDOogBnYzGvT5t96f2pD0c2/32jNqz9ng8dcaj3mA8PemVNMCcXUOdnIqOlzYcrqkSNJXN31Fh18WUxpjh1IR7fl8LMzYvbq/3/I6bJyxKgQnSDpuZYFetZWbGXeCzAZlOISsfYf9cIz6W9FZ4WWKOw9KP/aGRwZm7q9DUAW+XYJ1YW3S0y3le1wIg29pzOCVtCn1XSFfTq4sj73M6FQRIYcPYBWH2d2PkizaCkQN7pidYRKrvULg07wXXcd6xEZPE9VjqDIs5Gm8f0h7OToAKpf6eusyyD2ny48J7IwqSwA48zpYtnxywRaHHHfJORSzDptpycXAhLq8McTfws5Gp4lUHXw2ESXX4re0pn27X9iua4Z+3OM43Ysk68vmWwidyZbKmqq7E8gWhtTLvmsZKKaAx36iG2R2CHM3uFYMrZU5XrrfhojMnEzWHOK0yB7Ln4Ke16zkSEAHCq6hv14R1gJqsHwv+tMNgpI6cbWG8MWNFfc4UaqFhf9whjtNs1uElZdBZZIaX847wo9lGJvUseP7JioagQfHHD9R/CUApxUGg01rSpv5b/uelc3V50QOXCBR8Q1esl32HP/bVHznlQkWSj3Igq4Y1XzhwUbxVoA1wt8wR2iAAKpJOOi92DSJPyhfFUUvzx+z2wAM5j1i8tNKX7nIzi1BsuSuOMdgWuqJp9SMOPFiH1tz1gBgvYgv2Sbew+AMsJf+QnKeKF4fmxZk4c32+6vLFC9eO68+D9Las3W3/7y/v3v52Zb28fPX+xbv2z/8DaRJwqBb1HUsOVsb2bz8LvF9WTsmB7WnpTSBagZIxa3MlR9ULxKhxx2cqUQ4VVR644i8R/ZNGgn36dnlx8H49YILAmefaGLGqPRESJo2f5Sy/OXuITJCBTsmNNIlwZXeLii2oC0VOyUz2C1KTamgQ5sNGlOxv7179xC2VypblrPTryC9MCByKGDctH9ux3Mj7Wkc0CpUIYFROs/lerlbOfw3uiRfAvUZE3eIEylXASEZuGtiuobecTEeHWqWK3ttyVQy6jshlU2Fw4gFxWc4QkAtg00fs4BITPXDvC05/i3w4CuZzz/WZOL8fjsRdK4cFUGUoz6FdEi/kzvOzwAcmHZ7bBXRq1Eqv5ZJ1q17WGlQAWXi4n81cRVMKlFS0h8KjEOn/z8Kw6l2odzQ0L8PmZdi8DJuXoXmC4+Zh2DwM934YppxZxcfhlt0DLnYDhMSlc2WkYYr3ZjqRhuZwGEcWaCWHsiWoR37GX7WVKdyaF+oXfKHWL2HzRG2eqM0TtXmiNk/U3XRFkxfqLacCrMK/veUO+wb29iPC3ppYiqeLpchuch7CW71h4Ijqo363PJXpOp4Gk/t/3S7t2/vp+1e0uzz5F7L83ibUEkCu2kb5JwQsHia2CofdtenM7vUHHSiPuHB2jxecbiIa6H4D3W+g+w10fz/o/m1C66H7jeryA6suRoj9L3APNtjor+IA/JjYaNju3La3HRsN+55zQBWw0fDDPtjoiodm0cy8D5h4W5f2BhO3DO33ymxthVBX3XSGcGSYxo/5S46k6G+50HIL1d2OPnslt1lzQ/6AN2TzuH+ax708fFsUC3n+dlYuVhtk9PI3HdlS88BuHtjNA7t5YB/4gS2ky5ZHdqNG/NhqhNlD+8vcic1j+6s4BD/mYzsbTL34JO8BxHvViNDdRKgC+NCk5yu7whtVuFGFG1W4UYX3VIWFLN+qDDfS/PuS5o1e1+h1eVnAcZnaDNlaWnZRgKQFZHAJEmrxwhI2WwjVgVtzAWlI4WjwTGs8xZgLLxxyzhUDxKwCffec2EEUW0tG8WJwY5D0ZvFN9WPTZcT6VkZXTJymjDZaHD7dLj+qfj6NjFlegadLwYtp+G5E+robnrQxl77uRs3zmIUyYGwUDMgsd93++X3hlN6J/8p17CCZf+kqspD93/UXpXztlTubcjQykN7duiFOOChNZ/nVf80TE74DOcwgSeuzs9fvnhPZXJZL+uz1O+GNSANYZps0qCUFP0tgfG4RRbbCmHyALMYfjg6ZzrdWnPf6SzXEy6J0sXYdzcbMMopSFVMvyftS/UST2kkkeiVnZ7/8dnkR6zpUrV/253Z3dDKdtye93qA9PGG0Pev1xu3ZbEQnzmza7/apGRf+95NIWRU9BvEDIsmIst+sO5da9zQKDbWluhpksCrPZ2VaoVKCVxBYqYaYBJbUTsyrqyj/ZKw94Q6ZnHJFHuC+8jfW2kcRwhxL3qeGtVWVrq7YYp/YKoQh/SvweSTeIxvT1ggd4PnUIXYJfb4QFW/JoBPTJmvrgHdBbK1dK2eFMXkbFko9AJ0nWKwdBo91w1pyRUTOebPHg14nEVVUpUU3SRNWVVxUXZkQ2LBuffndX1tcSGNGOBEA5frUTtw782NeWbxC/htVWSgGVYGekRRaQ9Zdwzory0P0j7IHrSRYLDzIPUdj4x7XVHBo/ovWEZ6/mNHEYp9Cl0+RnHhmyaA0k2a2V/TQOoILhd8NfuBbsyi4h2LDbs+wleryucr33Cs1FeSy2Ki3sxElyGOuz3Z/rzuuln/g+72fDnJ18Ck/wOWxc/rE0Q8nnmr36WeUTrDmyhkHowcwptfZiq/kN42deAc7MT8joCpzrT6MglWocVdhpjoR29tS09pmOdELYcK8pjh7iRcf4cL7JNZWa3jKW5r0j7Sv1tLd+C0bv2Xjt/yu/JaQLtWyg+DWZVbKllPeBjz9WEz4lyIXK9g9kVUBLMqZvfcnmTSDU4spvFpQrEMu50S80IXcha+RmIHXJgpCzltEZc82Mhn6Iyz5IYvAiwRvzyi401FRCf4P+ApEfzAnz8IogMLMeS5s57I0mdGYU4GFgefaG8LAOM4HyVNfq0ZKvMBYpHa2P6q1z8nezrzAvt23s6Lw5+or5t7et6+i8OfqKzZqpb0w6TPvZ1qExAGZ04g8E4IRhEwk1AIYxPP6fo66SqeE97FOE3T9xVt0UDaK4I+IoG0CcZ4mEAeOnsX8u+pNIk4eYf6dGwX+iq+/5M+sZzUa9mej8bjb7tqDfns4HYzbdESHbZv1e3PKRiezLm1ichqFvlHoG4X+gAo91ybqUYiNPvFj6xNGETlf/nJsQJxfxXn4IUGc+ADNp6up8r6hUYB6liBtNPTA5Utxl1D6R5Uxe5fKZLmncerZbrwDCkN8zrvCPoGaZXouxdf8aO4sALhKZ3zTiq/RuRd43HWz4/yXC/JR7yqKplAojJjNHEAKGhbNCvBWw3UUBjGz/rGOhTIEPcv8ICZV1lVR2cSOs1ZfCR+L+JdhjeJrvm8OSpNaEAwby14y+9aSz9HtUgItXMawGRbHEuuV/vfuReM1/k3r+0qWLJKvMQL+LXJPgaMcS8zXnglsWgh++AdnJ47R9GogMK04oYnBrMGn650FAF07Or9Zdn2dDE7GwzEdjems58zHzJ7OHMc+YSObToaMzgez7sl4Mhl154P5fDZyTobz3mgwnPZ6czaY4CmV5un6hhLIECGyoG7/+j2LE0m+q7l/qkw4ko9eNeH8tyKuOX7zSBHCf/+oSMm///eRSBSSsg3z/8u7Dwaf/1jAH/hAPuYlVE85o1AtLOw6Bryv2HwPmAtB/LVu9GmBB+mZV0GcW/YJjwYXqmp1G8Mes+ez2WDYm3cHAzbqz4bjk2H/ZDSmdDabzDjGBGENAqKjVQCy7HgPD+lsbdsHxYlsHS1YsH1oOLBoU1//b9dCWabq+ZOG5/QSrYFx98bD4XDaH/QmvVG31+1PTobTkUC8LGjC7qnaBY1IkA4XN06Bwds/NjwTv8V8FLgr1rsLhDsWSc2lODUitYOqGkqx2ZJCWxHCRQ2xeBGYwLWaq6C5Cr7Hq6DbXAXNVfAjXwWu7ybwBtm+kiZHmvqbt3M8kyZvKd4DaPyhpbX5K0b/iK0RfyG97JtgTe5dzHpBYHvmc3n16GQ2sKfOkI3m45PJlHZnPbvvDNhwPhqfTOh01rV7Tp8N5kM6msEX6b9nIzou2ZEePj5o3lNi7uJw++Q196dChmr61uazDKtr8YOQyWEjyC9+/NgDYnQ2DmJPO6g1DW1pge8zm1so1p555Fax2GHNTHtFEOWjh74Pa9EBI3jAesQTkpqLX4D85GSwbu/HgbfGTudVFE0uSsFtdnmRBvti6btUYsM/ISkezzqVOhjAf2BHQRy3ZRW/n727KoSj81hv+cFKBKsm0TpOsohj+TM6/4N7SE8K3l/efNk3oButgSRvjnpz1L/tox6HurMur1k9+kLRxMRxTrYmkj2AFrain14xfwFhPuNhPUySj4Ib0Bul7DMqZTqYsklFxWJKVQqGeIeaZCmlIgXgu0NFspRSkQZ9u0OFxdK7qrJiV0uNtgUEIdTj1Zo6ipQS4ika77pkhUJpNbstV75MWsluS5Uv81gdP53ILfJCWkpM3MHwLfcHPjkapNfdfUfFmAMXhYPmZcunt5GiJSmab+1KAO0ziD1OXB15kLmIFWd1750dVcBM4ZcMIJvQaMGSGDqeouLsZRAzQDquVms/DYSJgiSwA69DzngVGW5WBVwipxRkspXfb4t+6Ct9zqEIyj0PIgDwBnPCPjEbnyWiy5mWnxLZiES6iMqm9lJqLYDmBCZmjP7JoS0Va6MOo/BEHdJMTq4DiOi1cjA7Hq7LYgESKPcqC+dNVTYJDb7J1XQDzyqX02vNGFkFDmLnCQVA8YZgwmSRQ5eSKEjEU+wlDIGvXwvtcCu6IexTwuBZl5D5OsIj6PoiKmq+RnotF/PaEJ8xh6wCSE0MnJJJIGDXRMRmC8QtFPTZvQAA/gEw2avgjkEDacUhjROowF2tmOPShHkb4vqY/penZlZGzqH4rk9sGuOZhfMXBSs3Zh3yDseGKYVFL8T3PLszhZzfgjyMxsRjFGKUHDe2aeTE+XZ4f0VsjbdpQdCNH5BFRG0Mz3EDR853nuitjPaFQbQxoDtHldTtDdvdXrvbe98dnfa7p91up9cfDEf/VZWWU24mfh4tZD2DW1y/e/SnnqckUgPjkI+MaYmtFKfI9a8K2A7+VRFuUexkzLy5BU4qAMN8lq6+u7hSugr/2trVT5s0Xzn8MzSlpWIOYKWNTQdqkafkjRIAPB6HwjkmIlN1p1gqqwhISVL8+3616qt4PC0VH/BOJCTi45buXoUNkSaaJ/xLGQzED/Up6XUJ9cIl9dcrFkEq+SWNqC2A5XyhwZzVwcoUIGxbOLFEUpzqbUxntoPiYFxfxx5q5qS24V945RBj8WmjsgYUfjmgJaS/Y4CCNjgB/6gqTuuZ59rIsqhXn/B3csuQ2pM6qPWgyLm+/lWmMM4FHmxJ2WY7MW3HS9pv+26chP3RmHw66P8c7/DX0v/8O4EE7+04XrZt+h/ZZuKz1QkiDbuDMpf1xrsCQyXhh5MIfVbcvhBlTcOQ0QiCbPGy5dWSXLUktiPGtkz2lcfg+mc+12nyFaBqBr+AJsB1uChImA3XPj/NnaNtY1OthvnRiWyDIig3CSo6IZk1N8DpgdKjFJO+C/ftVrzqF+1ndex7RDeVxkihSWdRG+nDRTAhQV8yus4tXKCTE2c6HNrj3nTYtU9O8kbH3ljpkhOCIh7OAhohMdxKp4Cfyy+EyMe+vbu4IpmpXa+ISFJZ9gm0hrnrVYamKv1JtY6cRMMnnWVDwEzk0ixiQFxeH4u317kkYlUfhFxpypwr2nWt0HKKPahBDJiI7XxtJd1QmMOfju7z/2PvXZAbR5IE0avEcscmq3pIJn/65Vi/Nyqlqko9mUpNSuqa7lYaFQSCZLRAAIWPlOoaPdtjvD3IXmCPsidZc48IIAAEQICkspRVGBurThHxD3cP/7sMdMAGfB7UfzYzXdQQW3J/vj91aOxaSxZM73nIZ07t1Zi6fgGGUstvXdsspXXJ8aTycdiAL1U9f5dMLgsj7qbJc2sFw2hdNuSTwb2MLlDVKMFD5m2RicXrKlMrx4BJMNfLdMZdCIuWDeoObuwLPpJR5IuUbqZkMzVGrhhA5NLzGoBJ0nx7m2pzxh+KnWH+xQxjW3MMU08YsKLkQJ1Ry7qD1aYsQ1Ad7auxr0o8kEkgGE7ngbeShKrm8OtGEXHxbBryiG26hYoBmoWNqvGy0aP6+yvwvLZLlqGnliEX4WQyGCaYXnvYsv67FjYhZ/4UFLVBGPGI07rIW+wHkitd1GeBFuFm4q7O62rH3+l2XA/PVzGeKvO0sTZB4Yc4ZFIr7WRdPzJMRn3qVn884PZUToBL5szJj7ghcDxXDKompdVAWmOZhKTSgUyweCnVwlc4BKZLZDb58erqAmQfSkLuLhxGxKhKg81DTA3Tv3FRzf7gBXchKJDB+uBEkJMGgteV5PTNyfc9MVtPBMv3zuwuKfwoIui/JT7laHqQbBJOkixAhGaj6IxJ/SMW+AGT+mtK/h6CbQB5dxLyFXcoBGq/uXEJ+QX+Q8hNx5r3xBn2xL30uH3TeUNuOoeHs/l4tm8f7g/3h5P9yXx/b3A0PxgNjwZHR2zvoC9VAxLuQNt00+mWDisU5mLomW2Ph9bMmtjMOjoaHO2N2fhouD+ez2az4dHEOhqPh2OLHs0HdJ9NRoPxZJ/Oj+zxaH82tEd076YD0zwZk2ikaAD5CLxAJivOwApKj1NRgMQseyoJU7RJMpKcnL1Xn+pUDnl7+u706rTT7VwcX52AhhxShcD/XF+tKw2S6/opu3wZdpqT6MGzS6UlY7bM8+KS4/O3mDjUog4oeQIoW4Fh/gj8kBQUTVRdVTME3e5WDDKsOI7aulIXoPvYloZPGKPzVNiRUUux2Z5S/6UvvStN1fE3lOtDELkdRATPcYRmoKduXiTIKUQIf/3HoO9KuIMKj8iKHFs2D32HPoosWzrC/QAdE7fSPoHcw8SDajUyJwXS5BvX8by72Cff3P6/hjn/eHyLZU4C5jNpEk+Svdy4ZX3+2fTrd7ffAi2fc6DtoDdRtvAbF1vhDkJ4LzyX1SEXVXTg+N276en7i3cf/nJ6epklA3Jl5Uk+VJMk28cmNOz68vRjp9v54eOH64t1RCvb1rBWdEdJ3GsMJm1MrEZtO4DHWF8xxNZsBgPpnPVhQO/zz6ZfK2AAGzS5/sQQrOLaqo74797S7YcrHi3/TXt4c4eN4Z7TlN60zj2Jcw+YxeuGsxlgFLzriBuvZsIfRCb+zCumIQenYCS1dYpe+jKHKMIuDNh7IvO9YaZv6cvi0wWoaZhNnKQuVT7taMkcLJia5zkv7AQy9/jS3anO+KNB4qZYeWZqfHpPuYMBXrAtLxYuKCGjAfjKJOm31sw5SGdN9GVFapLeEzbFfYXKUiuzoop15Xw0DMc4GEgPrZyf7XahcSoTEcTF1dH3qTxFNdsnyYxqtpcZj+q2FomQGrXuyQI79VRhKsFSzfaYhalmW0jVVHdYyOdUt61K+lSzvcoMVbM55quq2Vammqq/cJUgqy4wphms6m5WFY3AMMuN3B0Nj1ub1qB93trn7Us9b3UofZI1bodIPm6RvEXyFslfDJKjLOx7fuxoReJ2hOuTFtdbXG9x/cXguoSNnrCr7RTV91pUb1G9RfUXg+oW3Sl677fo3aJ3i94vB721kjE7RfSDFtFbRG8R/UUi+o41cYctqreo3qL6i0F18JxNaj3sEtGPWkRvEb1F9BeF6GlyvySj046wfTho0b1F9xbdXwy6q0zo2YSeu8T4YYvxLca3GP9iMF4L557KU5guI/D42yXWt+5yxoS5G3FkIsJNYvduNarD1uOppc4tdX451PnvooAOho463mK3yN66PLXI3iL7y0H2kNFdv+etq1OL4i2KvxwUh8C4FQ3udozmrctTi+Ytmr8cNI/ojln11tWpRfAWwV8OgmupXL1gKssiU7qQRXbS3Bm/dOSvbzqjuTXYOzia9w6Hw3FvcsBobzYc7vdmsz16aM+ORoMR5NMVyWo6f4ln/N/ZI9kj59+fYLBzMtDcmg1n1mzSm48PBr3BwaHV2z86Gvdm1mhiDygbz2csHegdsxcsIOfU9ch/ku/P3n4YkWN9+RgZvTtS1bpqtaSqJVUvOPEH5npslPqjfg+V/KN+D5H+o0F7kdKjaXtIAVK/k0oCUr8HpAGp39qOvQZD30W0QWuZDKR+D5kOpH4HSAhSv7VICdJoAzIpSANATeuQjHac6GPYeiS271n7nr0c1ltm+hjvVMAetY6ILZa3WP5ysDwb/r/jaKJR64TYYnuL7S8H2y26awxvHQ5bDG8x/AVhuB4bvGPevXVabXG9xfWXg+si3fIuMbz1VG0xvMXwl4PhGB3Id5zOZ9Q6q74ELIeCXovnRvOySXaG56YJBs+O6SXb+mrxHOt071Y0xxqBWKyoxfYXgO3tm96+6UrjjhWPd/qmp8jeFsxo0b1F9xeI7rt43UUhvBbBM3fTPLp3arMIivFteR01GCtrnpZH5CXVaGOX/xwzcpK6Vi2YC9U+mU3O8tVpZYnE9LwMpXFn9tEBmx/avYOjw/3eZMzGvSPGBj1rtGfbdDxmk9kAnadhk9PMgkzrw2ZEHgR5WHJrSXhI0kU+LJnAsjCiURwSQy1K6PDq++Ozd9cfT19Vr/7MvacOt8mfLj+ck5lnQz20Drf9deeXHtWZfUGiJY3IkoZiFcwFImRXT2zPD9joYW/eG4xmB72JfWT36Hy03zu0h0eHh3OL7o8Hai1rL/XMvtj2GqnjTNnKd7xHJjDM8RYLZk9pXagH774woiu/I+EcwB9P1LhkOPAecy3PhhcN14Pnb7rP6pX/8vSkT7mzUsyGqWQlZUEQdlqKlvA54RFhn3mYeRVNtagzZVz1tYg+5o3XL99qmFJUYdWn2lH11bXbLhQ0TRdVUr4UHgekDOaFlVON6iOQ5ES8qlVptdZSaer7gXdPHenyVl/7nukFq1A/pa9Ks6GSfk/djuW5ruTusXRzXQNgvhuQrNATlXyaLszQEbiEOYVp5nxRl09IOwCHGge+F7Lp3+NQmiphAj/wVn5d0lY5ROkUDTe/ZhAAaxaG8JsdB1Q9oLVYwmw3sNMiCANPLZ+UOpdjA1s75yyQsJcy5TUTTor2SEUE3mi4ojFiOucFMzlO/ViIGQ1zSe50Tio2c7PNoi00d1VVp71eR/dxiryGcoKbohNcszHiaAmgHbHPUeOOMjIMQEG8f81GgCiTDbateQg06+etVp6LD2vDfrEbBY+N+shAP98LI9hko67eivJml4gv2RQE7Q26Nepxz4JHz222IfY5YoFLnSm7p05ME8reLPBn6gUL6vJ/bNA/jHm0CaBheMwmkM395pfBm60NYn022BJE5GzQDYKWppZD+arZbBuTpWzPiC6aXRxGZeEL0Xxq5EMDHt5NQ8triLtpeNFUvYYrBtoZOYr2dISUhvDg+zWkcOo43gOzp9yuz9zpXeTr6tDYtZYsmN7zkMvHsuZDW+gKQ8aRNw2YzQNmRdPIk+959Fh33LL+GM7V0fJNbpCiUsTwgcjpTePAqTlA0vxJRUXX6gZNe4fIUMGtUt/IszdiChBRk9GaoGnaCaAttPiqGa+r9wC9JV00SGYhj12JjXU6QVNdLIL1F+QmYNsiHmGDS0ovybHvO5L36JiQqo4Z4XeJVr8NjGgWb5vp9kmDz6IwT1O4Qs1GtQiPsFobNlegAI/A7OXdcTalURTwWRwZVnLJolBoE+iKXfKIEdGHSGV8V6oxQermNpoJrIDREE05Vhzw6JHQBeVuGJGTy4/fExpF1LpbowaCn6wou2THdG9qtz+AgpBb5PL4/TuDUUoRneIpi29SetQMKYlpSsGs2mHQJ1ceuefsIbFcgQyb70pJ6DMLhIOkY5cEbA7ae494cUD+ZrN75sA6ie1Z8Yq5ES7i0zfLKPLDN69fJw3Cfvqcgx7otRY87LnstVrja277PXToEPt5/a12zGWkR929Qad0nJjM4FxJ0hQVfqHQDD9wxyEzBuowZsPeHmFzIV+4zCZ/+umKIN9DqGsTi7rQMgbg4K4YU8izBPUr2mIL5qEcEdbzlXSQi+x0OzbzaRDBQU5B9Qq/8Hseei6aHISMkeyhQq2Z3Sdep1D5SRMYLlyZLqoB+VRq9j73aGzzSCgGQPyHBaEqfcpcK3gsMRqcYhN5+mEIt+a5JO3RJz+BxUAq5btSZy8B9kLCnbgi2YncuNnRQhKDLQy7avIsmQfeCn+kobxM/SvY/W7cG/fKk5Nri3pz4w775CRg0JDmu5F7TsnFh0sADHKbgO5UYUn4+hduP71GGqt1vb1xR31yySISLXlI5pw5CG23cJi3CF7ctZzYZuQ23xcMh1Nu36r7u7i+UnrRG3fcJyeSBjD86sczh1uZZXNXQLWSH4tnDGdx7kXsDfkoCEJYsYzIAzSAs0B7j9hC/8Y1me5sNqdonZtTJ2RmQJp7oLUGNYgBhI7DuzC15XgkYJq+ROwY5AwB5dRaSmDL6FQMWuRmK1wyarNgWklrbJvQhN5UkpqARXHgCiIiaLBARSKmSUH3GB8PNJPOqHVXRV9KiGIJlchTCDXh2duLIsOYbN88lly0gZh6ru4cAZcHf3oBX3DXzJdmKP2TtLAJgEZINJz7f+4NjjLAHnnknkEKFWGI5AuXguYoQ/wK4CHLatWm36hJD2MWKAYwuyiA1VOBYWdviReQM2xMrj++qyS36uV8WHp0xdFkYgbIFf08DUPkJ6cOcxfR0vwUrOhnvopXMDER7RJcAs7E13xYLi8/EMXsQvv+jfuTMudanhtGQWyBBRPawXAPXuzYhH22GLybQNTEBIKKf2QOfbyMaMRuXB6SMPIC6R3Dgl7IbYYkj5Jw6QURcT0X7E0h8YGu2wpUYJnAeTFq92/chHjyuSBn8Jm5SD1CQvU9OnzFowxFMriJHg6PRniScELo6jEYDLqdFXfFD3vDkfnwAaaUE4GB4+SLKkgTuABOMAl6BwzJMXVCwZsZoLcLRE4n73fssUgnAEMIc23f427GZFdG7WAzoTeNaLBgkRmU4VQjj4TMtdftKiSRVwu8IT2aYIz7XrAArg/fy9eoJjRCvKAFdV1oZUq4plLWWNg/qD31XMdgGj9zbRFNJ4idkbsGIOarVYyLV1yj60XIOPo2+gB4AbGZw+CfwExIb5iSBzTn+wLL+4CrU8BoeKXNtABvLmVzCoyNcIUJu5IRAabKkv5osA8/YPfci0O9X9i/cWE18DGEhkBMcJ7CwYQC5ov8lOLPxP6z++vWFmfzJ1ByMqVeGtdAp+cphFecU8JQIpXiYZGbanwq+myKmYMD2TUTmoGxoh0fEUdHWGsyOGLzyaTHDkZWbzK0DnuH1mDWGx0cWod0fz6Z20I1UV83lleK1ddvAS+AzfPOWojncqiukpY/ZYVvsxarFb9b8fvli98vTERq5aFWHvr15KFW+PlSws9XLem8SMnmC4ox23NkRXxS/qlmnsYG7mXFXXF54KDCXigrY7i/NANq6uWW/VFm8u0IuQL4TJmpFxhomYK30+0IFxv4R5oEN/mr0+2oNLedbgfsafC4xgBa4IUC/yNTyQKfJXLEdrodkc4Vpkw22ynkD6/DBOuygIldE0EllQIQovOKRdSmuOBq7pCDJwGKkFXS9EMSFgL0TbAyspvzSKgV8fuMbn+tmAxI40VTOo9YYAiy0rbDPvtcMu8gm/eJ9jEkNGBAELwVBYLgOI8k8CIU4ccDYtPHkMzY3Av0YSr9pGGKHoBUBvZGg9FBb7DXGxxcDY/eDIdvBoO/Cs/V5J0vvbOL0/eJo/5/9vNPP3gjUu4q80hKUEG01IwGPKw2FyBAFO0ykcF4YpYw08324P++O/3h7JycnH68Ovv+7OT46hR/vXHfn52d+v84OTme/Mvi+OHsu+PF2fXVcvTny7dv/zTwvnu9oDPu7f99+O7oPx5+8q4f3v7HX/70795fz5b31vnxf5y+u3H7/f6Ni6Odnr81zADnGpt0ANcidCR1pE1YAyPg1ZCd58ODCTsa0N6czllvsj8Z92azmdWb0AGzJ3PrcDLcK4iyYhDDzesQ3dXxqgLF63huNMXQrJFNF8ngvIApyYjE68O5NsbVTRFt3BsNr4ajN4NBE0S7KrWsXZy+J3LibQD/h+O/n5wc/8vPCvD/dHx2cPe4cr4/OPnpCsG63+/nkZu50ReH+JcE4WZl5/FaFZ5GGHUVp4etkdAbtZ1Cgk6HBdYUX4QspJdFAKIyT0Vt5cBLBWilIXT5NUOcpBxiI9Df196Y/TfDo/7haDjcH/21oHRFj0E8lPUoUfVMp2RBHZm7yLkCAGu0gYYXkVZeUA20NVxll4BrOMAAs4kdY4SbuknxroXwNAKccDfm0WOfnMeOA9KX66UtIazQs/AQ7D55zzFWVAZAgsQIY3jzoin91gQtbuw4GTvT5mgLAPMsil5pwtgGhh0aRokp5BvWX/S7+Rv49pkB3EiSNPTM7HMN+anzyFZh/k/Phe8T9dQN3ozFU7cDRDdz4xugsHCh3A6JyTcVSOyzgHv2t33ynj4CjwLYJQDzK0ZgLSR4bzabzMbznjWyh70J26e9w/nRrDe0x2wy36P7swNrHcJWgp6Ops8Ff7vEwyQWfz06tjkR6hhQN8uIkA+LKez3PY2sJaoskRXApv0bN3E7oyWW0vX8VZmPbTNTACYQ0ePBM6arai2SsCTBYSSToB6swh6fWh6ExizyiON5d0AT1uQoYPfhv2WVYSIlQc4UXJ6XAA3eKOivPXHD/Iwe7u0PR7Q3OrIOe5N9a9SbUWvW298/svf3huP9o4NhAYhyh188qJINFKvlwV1/0rzFE1jKOV1Pq7zmc5ABAZxm7ecHKRjoVJsL6VgpV3KKYz/wIs/ynJQJxkeF0hAc4/vKzVJ8+nD29qRP3gorG/CYsQtkmIfkBnd601njO48KSaW2lH+ievGTiB4P4xULklAwozYc4+9FgwQCXqU6dmHP4qGyDUGMBa49YBbj93AK6CRCA/TGpTlGvxqWEu15NlVAlm2qE7WkPx0GXgdjmrJGy3r2w3nAmWs7jxU0A/f7vWx3rhGQmrTjHby30E9X+VeTppojz+mKq6XLsafq+S6KzgvHm6EELJOpJDZs6qYkwgsKsFK9hjhw33g05OEbtP++iaw3cGBvRv3BG9gGGi7Eot7MaMgtDZ6b9I1daWxApmWTWRvNFvDOpwxlKqjQcjclMEiiPnKjs5g79hqUKVediUwd62lbPYBCy2g9oAL2MAtSs0fw0DGB1Ir6YMwQVjyY4+wtvHNZo3t9Y35VBiDNjevMvljzgol/ndkXZ2+HneQwa/IFsA8J+3bdQztWzQDPh0YT/5PZ7i89MKYBWJankCelZIlo1FTeiej1kXpZCPO2sDCjng1scwmXSdDwJNS4b8H0zCMu0s7B72sCnkooOFyVfM7X5GzKiUOCLYEQMC2MrOESEt5IGmSVN3UIEqPDwrAXsSCggMu9RGk94w4GCHbglYnhMVFKwQTQua2Rz6pXKXahvT0Vf08DNp9a+6PBgI0PrMneIaV0bE1GbJ/tzY6OjmbWZHikTxIF1A1hpunfQ88Fc5sBt/4GuZpoRFNbqWyM9udvQWkeiBwjEizUoCEQdO1wX4UCXCSN5xgKB4CCj9LZW82iy6MwT6vIFRiRtMnCpfCQEIkKkK+laF+MHRrInFLQixEvjvw4EmiVHQOsC949CwLwmAB4vs2e/60K4ltndPqnMJ6Jn79De9036I/VJa/+7dW35J/Jq38JqWvPvM//9or8M0kbHwOO6G01Y8EdK8mdJT0UDLaCjEdQLD09pAsEwrt6XmuRLf193gCsEwfZlANvBm/k2QAueRa0GC+j6xyCTw5ekukIt7tE3h2cURf5U5GgScBy2CdnEXaiTuhpPTE4K0TftdQpLXtYIbBAGBArG8tXoegPri5ad8lbB/irOESHcSpS34l3YC2Qk//v//kvtcH/Ir+8SrOfvXqDR/BE/guvvZImPxcHaAJb6aSjZAwzQiUSyMOSBcz8Mgi0Qk8e8Yopv53tn4zXlu32rAWXMsbrMPSES89sPN87pKPZZDhhg9ne0J7sWYfWCBIFzi3LogM2OrD2xwf7QOT353RvND86tK35YDaejWdze9u3KKvZq+NPlHYwaeIyorSKvi6TpmslBWjl6a9cnk7TRrbidCtOt+L01ylOJ3tIpvslJ/sWJNNupsEo3wBtd9S2uaDiF5mzyXuGl0i0rWjYioataPhiRcNWRvhdyggVHF8dESEbdJBz5cyESgKsIFAAOiPPL4Np9RuDKFfIAi1pCLgpJ/5m3CWW4wGqzFhEawQqZuQJ/KVRzqx0a7L2Qi5va+18jNpAq9iJeGGcT6jvRUcbMMZDdmCMFjeyQyJpCRylTxfooyjyoOuRK0ggRSRM5ngxLFnPQg8akTlBhwKgnyF5Jdx9XsEgOJOKYcsmrycidcylt1LzhMT2CIS9h7HvQ5CTXBXcCE5eErMjMwGVu0ngxBnAgYABET4ot5QHI/NMwH8Y/XOKZgTYPQQlUekZJLKjF08P2iVLMwF0kdJgNBuyc5Xxs6oNvpW+7zzCP3KTy1CELFIt2UoosHILgec1ZDmNmReQOXcipmraaNuaaQNnqidsVAdFRwGxM+kpsPIiEKe5+VYggTS5/niWiP9ZHgXOowez0gilacipYAyr1B0JtDlTmPhkJGlC5/G7Imr1kwOuI2sqX2BTwvbAUtq2K9L2AGTMeURXt1tB4W7XUTh1V3HIwFY2YxYFkhC2JK8leb9dkpfPTW/KKW24xNRKAstWvCrcjhSBLqVYcCWSO2RVvXh0GrDlKWpWOK0Rd+Fw5pozv5zgJ5KCvlyfEltE8gmTCUcEQgqggeM0FH5L4V2uIGRWYIpXkasQn59xJShMMDfkQPFSnRcetxn8zDcjaQPq21b0DsM6tFotYT06kGokjVBVdPkT6+xq95k/Wc0h0ARoZkklD+Mg8E2F+rIJZP94dXVBvoNuzw3PkCbgwQsM4Hwhv9SDE1zMVwcscD3idoBkgV7K4GIP2ipUSezgIErhEOfuptehQV8KDPVgzkNb2YzRgAUbUNUPx3G0JN9h9y9DU399OMAjEyemCAaUhjQe3VV94tkcKcrAQ64qBYriLW0KHCZJpAWPXx88vhAsbHL7o+e+chjeC1RVmdKEK+qUVUXExNZPIImB+CxDuQTLIxuWiRK1mDvz1S610dFgKCZELbZ2Vu6iKRSsZfguBae302Xdf60PugRpUWLD88uK+mbgi4iWItmZzDOUOzdUDNRE7PKzq5H3StTFaQbwDbj5DSlOOZPcNaCqvosClRqVkCYlxxavS4nXQu2BjixCypZAIbZdkOOjJXvEnCua3J3mhKs6jbJAv3WqFS9AjQ2CqzKrg6GxUCRW06KInRgNrrg6qU9IjZVaGiMa0Sig1h0L+pxFczTE2p71ehmtnNfB3DrYn0z+eyhqNvbG/Ul/1B99K6yDKxk3p+ko4GdpTM0qK2qjYGLlwhsnPp4I8LVXkOqJ/UxuOmcuJIG56cDWU1VWsyMVl47oKnyQwq4MLQ27aTbcsIYoj723nJx8A5lTv12rmCtTTtacrKb6T5zDxrOI7uSbi+Orkx9fX1yv3deTIvoGn4GfsBRKRskmkn6VzL7eSQmg/A3mNg3fAO14I/Vib6AgGDoBgawm6sJCyRTXGCML9N+BFGCYStIGG6+LOhHwEJh5sWun65UTiPfAqIyX++iT//M//v9LnPX//I//Kd+BkMTunes9uNJFGMvDOAyagpwXLQMvXiyhPSbryzfPaqSrXj1ZIUaIj3JYwaM+s2uHruc0KlB5pGhuberxTysWLNg3f/unLvnlFZCPc+F0XHCu+Ke++qp5WEQsjIzuFfnWT5++NT94tEx9aTSwFkOSoRX4HRgZnrCCG9iN4bj+2k2C36+7erDrmNdv3uw2JqpyRd0GRqr1GpgdDbqRCa2O3v2pBOjL7unrOfrNzI6/7uEn9dbXKG8DvqLBY6dYXVlLvVmQJ5MsAgXnyuwiZOKFNhPGhpkwxPnJQggbp8BIbiJsr6J4FVPuzr3155EUMM/r6iLqEDeGUrDADYox00TOUh0g0y1npUTRS1/mELw26cLAfp/IfEfwFWVyDun9F9wVIbHSSC1nXz8HC6bmec4LO4E0uDhrzfFHA1RCRNSZVp6ZGp/eU45pinBbXgyp78AXggZQBjEpQ7BmzkE6a1JX1uANn+wOm+K+kmA+ILEBk+vCimyVxzgYPD1l8HkLtkZgZ+dpGwyHJLg1wFhm8CrQbmMKJagqSsPovWeLmIv6vbyUvyrP+hZwUeFGcP9Xpa8NC0LjWIX3RsVBVJ+BiJg5z7ZNpxPrMx7SEyRUvmduad+l53oBeFFfBGzOP1e3uYznZW1W3LYdVjJNftc+qGL0tOjV2/+Q0ZrUi5DyfNNNJgZz2+4I35F7hv/wHWoxhFCfimz45SxEygNm85UV1di/5LBR+yVlWn5JtvCUkzTgmzlIJDOdigkpGPw9H3WRhcgRictVh2m4QH1k7UbyWC30KVCst32828e7fbxf4OOt0HLL99vsOnIs1J/oQZJ6fx4nZEx8hszoLqrXtIwAYLmQvp8Z20GZwdQShjiTIGjz0Hdo+ZOJwmYlBawr8gqx9QkrIols72fmd5gbuZFCVLDiiurOj+2bFblIOY/sY2AIIkZrkVQIoyI08SRFTXBywY0Mfkopaf5a/uIZ4G9qeY4jzD3ta7N5/srkOIG0pwe5LXXIDbf2Xj4q09wuEBPJEwbKQs8LFlzIJ0gOrGr6bMYQgb2FBtEZFhYxDoo0/6N4dkwtjHp41DbrHTPz5PbS1Q7MePwtRmyKEXB82+mv8AKkJrm9h60p09Z30UojrTTSSiMvUBpRpHZD/Ga0hgYp17jGqvQeoESjEXuAxJH1R8h0AQRnNFLRY3Uon2peOBj1Ibeq7JHkjqg8bE2mCgDKYsio/1cWeOQqgHRqMMyaxD51ytlgzcR3sujkeN9cID63cpPVfgdrz04UfgEw2m0CqV8TKHecGiF3FVObzTF/akaJvpEoIDe6JQY58+nSg6dsantQM8NAY9/Jd0hmJ5HthNQsg6lkAg0rDlRALCY/BI9Jm/kBs6jMlzin9x6S6lubhRE8dKBrvUVHUJXlJNGUkNiNuEP+8Idz754hjR8Nu2Q0GO31//AHCNrNDxIk6URsLLfqklvDDm+TmfjC9QJVX77sLvJaIDFK6fZNyKiVlAaXpr6Wfe01tVeixi98oK4HLJH+PYzofA7q7qTU8t/wD3WqRdKSbhiQvA72O473oPs2sOk9p9MHGvh1qUH5CKKci2jA50F9ZU6mixqC2ZD7qi6OZLrAEL4/dWjsWksWTMGvbebUXo2p6xN6THtTlUB5GnlTleOm7rhl/cW5WV4QTkXd6LqbznRJs/HZzH1UfHndkQw9cwNK5/aGg0GvdCDXc5NdbziqeYh0Cr+B7KJ3EZegU5mag2S6wBBINOp2Fo2BcNAFajskeFied8exCEsk3etrjFY9RpJmYDqDNJvuQjaoO7ixL5hWwQ8McimoCRN1eM2RKwZAq/bCawAmSXMQZee0ZvljJcymHTaouYzF0YQjW6b+Zc0xTD3R3x5Ba+oHbO7wxTKazh7BX7juqGXdpZ1400sz930SbFHWTy6cQpZCSahq23eqRxGZq9k05BHbdAsVAzQrnm3IfIV8qZHjqsXwFXvigOI4EE4mg2GC6bWHLeuPg6Or+NRuBrT5boKMhnfcn4KWOAghVyCti7zFfqAVoIu6BwdNxQqUF2WdTo9+tm6ZdvyiICnq06TbBXNtocz7ZOD+Cj/EIZuKyCvI3TbloedIf1KdyahP3eqPlxe55S7lg6NXTWLOnPyIu4VMbk7ikV7OZ9ZK/NyygS0bqPeSDFZz7qg3bvmj5+GPNmNwnocfkQ/HM7/pv9MXVD6GhoBqLV0atKpWjuoP42/nccMr7Qkes4YdSc81UIcKJu13X8yuIaTZmlShRUXXpm22UHD5UKJzE5Vp4kBUVocy0sol4H2YwLEOIEn1LiZUDxlzpxkDi54LIUmrC4ij7IxNd+UwejcNGKgym1DiXK/sQE2gpNAtN1RdoSvbZ4MHYrQBv76RHr6yjEkZcteq0v1F0bvSNLIhdotL+F3id4u3G+Lt8OBLIW5dA1oFn5aFro8MsqBCyejJYEigKCLUh4c0Qg+qsrnKDsNDMnM86w4y6z5CbRAJipjgxPccbj2u90IpLlJkTeEu+vJKOdCcIBj8g+PIg5QoFmHu3AsstgKvEKyaIAbIYUjYJ8e5/I+Qg1a15XOoZC/WTgI2F0kRQsIjUeqMR1jdXmSkVa42zmMm24wt0s1QV9m4dKZQpWFCzHVE5ch0q+Bcwj1bGgKlIKVnpmD3LHjMr98Vufk12za10NWknr+0KXofeVn8pieXgToExlNdU1Wbh2jJT2Nt0l9kPpBPdXL2Nr7r6rQzRUBML2IaLQMWLj3Hntr0ca33DLSBehuZe1EF55LFpRl5klxiUOZUHDNP0vhoS1WOodpSxwP0luArOMnx/h6EWbnyr0Gej1dHWrW1rgKCT2v8LnTsXFeGXlY4soy5addnusunwq1uLglG5VNJs0uoBlhKB3RC6ay3fzCa9SYze9abWeNxj+4dzYfD8YAOh/OizKRWUUyyms3BqktTJYlUM2cd0cW683bNmW2TtFdJwSkS0QW5g4xQri3Sq/QJPBlEy3eMvXSzILGZhZlMaiQTKix9/fWVlnZRa408kaipT/6dPYqQEIuGLE28hrtZUdiFCwIIuXY5PlkOi0SCLNcmNl/wCHIkuaDXg1Q5YVfS21AQ9+Wjv2TrivIy954HngukJ+u3NNrbR1xUfw/1+EDz5kSJn3R7fxb5boobhFoUDI4WXmEesdCnliy+iVQG3iO19/Prd8Ra0oBaOTdBw2b8wLNjgf1r9pIDabgztb1qeEcYKIN5ckWzLldFjY/hXVrB24b8L1/JMj8JvQ9jWa5Qe3TDxGvlnjrc7pP3CWVG7BCxsuR2PBiswltIDnU7Wk72Vrd4I9wW88Qu1GGiAXtDXACjkHzjBeR//6/w2y5ZhV0SdsmqS5bVBz6aLCv2W+bTVm/HhaIIL2rXmhfOulMYb3cK7CUfQjY8WD8E5PXqKMyW3KVTl0UPXnBn4t8Fcy4Eab0gVphCCegcMZUzd8kJjNcnJ1D8C14CcCNjEYZzBTFyxNjlH56LlQFxeiKnr8ddiaoTRuZCivvaKqHW2AMNbGMSRJl99ESr8vV90hxZKDJnNIoDBR70jonsXNpxpBXmZ4/C0fmRQd0tlWeM2QtJW+VSgP1XH72AQ5krqJAqspMLOxFyx2ArgzJYC1iMrHgh2tdxxjcdj7onM0Ikt6hq04dMyQxhEpS3htMBFzrdqa5jWkhpBJ68WZ34J0vu5iB13WXrmb7Vxi4VVhQRpZby6etElRYvMlLZr4AELwviuWsZNo8pEZX2R2kDGQ1AVRCpFJaOtzDt3ZDvJPNUDUZ7vcGwNxheDQZv8P//ml1QG8G2TQSbFyyoK1MFbx5RmL2FOvSwvQej+VnZKnd0EeP2IppeROKyo0qa7uwyJu1lbJSvL5Q5SHdwBXvtFWwSaj71PT920my2O7iJ/fYmmt6ERXd1+Aft4Tc+fE0i29U1HLbXsM017O5ZOGovoulFgN/e1ol4ctcwHLT3sMk9CB+Bqey3q8sYtpfR9DICFqMzgXYj/s7uoxWqm78WaRDozq6hFakbX8Mde0xi53Z0C60s3fgWZp53t6LB3c7Y12ErTTe+BPBA2NXxtyL0dtru3ckPw1ag3oGedYf30UrWm6paxzu7g1ao3tIItDt8GLWC9Qba1h2efytLb6fp2xlVGrVS9CYqpt15BrTic+PzR2US35nZYZpWpG3voamqVblz7Vr3PZUJdqdQKbq9mi0UfdmT3O522iz122ep34KLgnwXmfwQjrfgbkl27LeQinrFXSZLQ0cegQHE/n2fvJODEIdiFhdMMF3nBJJYAeUQqy8vn8Yju6ZT9LPVI0NzNXxlYWhiOV5szx0a1IwOVEsIl2120DYt1EtNC9Vps4OuyX/VZr9qs4O22UFzNvQ2O2ibHXT77KC7z/nZrZlkTQ2dnTeZCOAXC2mFIURh3rtWJ8u1dLodZMu6nRkPPfgfabmFFdBwOQ3xV+7OAxpGQWxBMBXkXLGhz8qS/51CzhjqCE7w8+OUubbvcVdUDvht5HdT7G+btLTlThtzp23S0hfHtrVJS38nD/uukpaGmLzht/GYYXoz86nI1GcysFamBINSMyr/2ZpjSvVtijWRv6zJs4TTlmUCyS4KS/EWV1Oow6NW8P3x2bvrj6edbufy+uTk9PLSyIBpJXcMHfSVBtyKcsmKACnKdXIueyAztqT33AtEjL1cfUhW1Japh0ypjMI+uXZhbC/g/2B22o2teETwMCHWWSbyCTCHnUxh5wVkMhhnMtlxlcdOKJkJd8OIUVtU9BO4jEnaRGg7KkCF5pJcJnrcdAmuRxzPXWBta4thOiJy8v30WK5W4JUgRPmZ+3rStoyfFJG5LyFeHrLZzCMWkA9W5EHGsT0s5bQvcpss6T0TeQdUvjiZaQDC+KUeVRyLRV1IFCSTrxEe1dHEVoIqgAx6mq6oP7UZwoEkZSbm0BxSX1Pvkxlcy20oc0zla03Bz2uz3/l+aU3GTH63TDIhTDSQnnpmIkPCtqHhDMtS5e4+pXHjzJXj3eePzZJrXNGnzP0l5qOKC6l3o7/H0zO9XxSSX4ShZ/E0IWUhW2wX0nXcsceeyEPmUx6EkA5OJo/okoD5DoX0l2DGYp95KMgiXRgTwSUQ/0smSVomy1hpXo1fCunHCu/Sin7We+zlkylV0iqpqyhLxRZCCk3yQN0Ijo0v3CThpYb6fSLONWAkDkWDOXeAMGfog6TxGfsXqBBmHg3sqmfanCQuf425NeWS0y24yxha9wrnl6mCp9Mfy3MgEymwnaoTizr62QULFqVMtGGxJyL5HGR/WVGRjQQ7kaQTABqmMC18QOhbB1FpEhhRCLCH2fACQQAkdKnfPlVAWa6eYOUw5aXec3f4VFVVUJ6eFfCIBZxOZzQ0WlLnaEYVrYFPuWdBmoonA4XXISOMJ4Zmhy0osKae33PYPXNI4b5UmjNVgzl2VOazLpnFIn3gzIuWkHc285lI0gNAbTmxzf5V/YIMBfuMPyJGCJGOOqZ7zFnsRS8T1ULIgKStooktrMqi/jGAKKZ6Fc8urnIlEmCa5qylv8RzwtyamP21el1ysi+6JlAnavCXshe1XJgCvczp2n1hSivcnMoy/OzbM1KWzYfVxsm/m3gYCImRZ3mOLibKYziRCAp8qvv4Yd5587dflOI6/UEfUwHMp/xRPHWzDdUNrG2oUKPY0NA1KwQXTsA4mdxP45419/2pnOyh5hwYvJb2tbSvpX3PSvs0Omeo0lLn+GR3DWu3IKjlREE3vbakoSUNLWn4ekhDHnd3SSDM6e4v5cmHKAhDtlFXIWBXIWAXsFkhIAzTJ8cRcRgFBavLUslUpwNAAECyVxUbXM/tsZUfPa7HWrP+5X1GBpZ57FH6lcKuSvWuNiJy8geMfPj4ym6iXPmbrl2pEnwTUVZP627WspyJpnsDzAEv/xoWZd68Qka0138a7h6Y4U7zjH5lqtb8kgpg+FFiXfU8hTtOUrYmBAE0H6IayRqYDGWBFx6CMj7irhURcLfCZyjVJFS/XZw5Nj43SKDC2AeEE0l9k5y4d6wGCOv5dctUUw2AZpAFm6enUj3OA5v1/lABtOoCs2A2NEKZujy28h3hJS3thyZNsog0ECnhhXlmLgz2onIAUaOsPzvNsyIHHfGKuj3Q5aKtRfuojHdySpMV0aTHRATJz/JBchcEnYxEumW0VtIgUvOozeiTitJGYUlmZNP0ERfOhEUdpXaK0EiYRwRRAhDWJv2G9Rd9AiEiXeLwn2Nuf1tv+rysy/GtV2evC51JNSzD47Y26fFwopIe770ZQdLj/nA0nuz9teRIkjkj02OF6lv4RMKl9+CqvNclgRAGA/JPzLG8FSMzat39t0z5BPnlv+lEy4uoI2I/SpYCDTSLFjZVqmr4g4Besrr00GhQfRBgxTQEa7UhPHoIT/VRLALqRvIkIw882aayllc45S6k0qi51xoDAVbDd7Dhqm91PT8L/fI4WmP+Yt2YeiFKxkXn/A0+g1zIk0Jo5OxtSLCfMNvEoTTeyu+vwN7uhWFPtZc+CAELvTiw4ME+jsjKCyMyHAygHsjPsaR8mSmAg4NV+hGz++TDikcwIT7tCh2koJRnLwsvbpVbxmA0ZsPB3nzCLDY/pPaRRcdDejg+GNkDa7w3XuNisjNPoJyv7cv3wNUOwGQMPEFnRaTN5duX29SjYjhude4FM27bWN8MfUZwtZoT1vpbKS19s/N72cVlaCcacxFDgA6KkbcQYbY0NPNfBm5INCYPS6HYuT6DXyRvK1hdqDbJhFsODG9Xn8EVW/leQAMO9R/AGcibz4sjQ/VKUX/rDrx2rCV1F4zccyqb5moaRywIKLARvSRuZMYd9PrtALGMQRZWGp+OfjoltekkIYF3RsDTHDgoVcYI8Ka4S21YN+KGAEhjYQigXT3wT3J3VRtiZKwNIcbezLGu+kbhgLFWZArSsvqowHWYXvWxGAM1mVx80rMaAbNuG0WudDe1rRu7O1YF3XLFyFngFSDerEIZMABnStLJyCzwHoDjSyYl1x/f9W9clEnReT6Uw4ILhBjVD/g9AI0MkCHSYweqzrmpu9wPNGIP9FEoTAUiJLrSG/ckXcJ3cglnyRIiT5XTiX3h6KBSMAiJQlSREcvy5oVd9m/cSq5MypJlccUYdF6GpdfXabllPZbYXZSgqIZEWFpZB+P5wd6BtWeNe9ZwNurtDeYHvaPhaL833BvQwdHRbH9+wDq5hWmZ4NfXPNqtB1Ttwt2qhnQDl6nc3tCF6rn9p/A2VLUefefaGJ9Kj39aXocI9S0SSFCeSnv1yTtGUeoDdU0UUO7AH2klR3jbooCvVmDZEEViU6m6T47R+RMbcHfRxSlwOtRXqrqPVFdzggZTGz+pB5ktGSkIJRmODsn11fe9QzJ7jFiYQSUDIT5d+Y73yFiYrRk5HB0W6l+WnKJ0nV0PzFsDU5M6TnnXOpWIQgpu2Su/EM8WA30ulXQOWgoNEuilbX7P7Zg6pTRCK0DlQz6+DLem/ZS+cigWrXvFcNU8vJtijdO1lXqh/auQQA+CPdYrvXJTrL9GQ4c8S+jwEDVW6ToIaj7DYnlUeOtmwL48dMmK2TyG2ot8sUQ1a+xi50o/O3XGjveAIiYM0el2YAwgBHKEdb7xmd6fCjpPHbLy+y9IvoUGqZL6GmjJRziVS/yUu+mQ0WjKPvtcxI2osukMmY4SYSJbR1OAAIGBMqXQJSHiQCZ8eMD75CdVAT7tIUhIKJ1LIzGkN9dqmnfTHmAsYysAaywU55Kkajc88K6tudILyZ7QBXAbkShwfsXoKhSNRXlzQt6L2teykm5StE95wvOQDMnKc6Ml+eZgPFh+u30B0Fs3vO2S2zi8xSKgt//7f4W333bJ7Qp/xv+s4D/L22qch+VUKxbX32/NerFf8w2/mOsaDZY53CvnBdTXTJwOIrJSKFVP9idv6ZLLFY9MU1Z536LU6vLPyQok8wy1sWfSaxnVTxrbDh4V5PLyx/rKKDPUaqQx8DxkqWaxG8X5J7VO3hwEmkrJJzIHQ5UdcnlWH5uHvkMfz2sxdttdJFtR7ujbL5xz9hj8gK9oYCiOfubaskwpl2UfYWRCbTsA4YqL45Hd5ccZA7zTwpo2PC+z8jBdEWofHv3kyDJLqz4tLJpZXTU9u9FGt5KIZDhGZuK/e0u3H8I1/Vu+CmjOwRHhPALccs5KpMUz+6K3YC4L0IR7ZueC9eqADaxnGiqwqS2CCQFsxSJa2yASUZF8A38270dxZtcfz0B3za0lMreWMilqNmkpishIBfRrKNt1I313HLhvOIvmb3wa0FX4BlJ/vJGLfgNc0ZtRf/DmGjNKPD3lyE2tPAUqCre2yKn1kIm4xLMs49SSIKZaQxV7bhIIlqqZDHK8APqaQezQVuxqIRQ6TU5G7yIGaaxDcCgYEhN7m0hBV3MMc99NYrkGIp6bRkp/WyuOWzQXG6/fT268seaj4s7zeDBNRMo1wY7fSGUqs7+V+jbVE23EGJLql4i/YbUFeW8twxtOlbjbeJWy4xdZJErimyxSdtx+kdqKjOYFUFpWvzLz4cGEHQ1ob07nrDfZn4x7s9nM6k3ogNmTuXU4Ge5lVTzjfWMsa4HYaAsrE1F0nao4gp2vNV2IVKa1Jas3Tyua6iO3LHlWHMgIH1Kb5s0TTSioTxNnpleC2WButF5dlV5ldprvgF6g05fwTwr/ldDU9VPwPStGpViVuFHJKPoZI348c3i4rFY21SHiRae1J8wXt2CJrb7OMMKqDQw0C1QIfvFk4dxAGUxkq+zuAKoUuthKODeSIhONfKCBi9Xrixo++56HXvCYHLYQTG1PeNmjIVaeZ9YpbmcHmndPTk43PS8NdJOd6KDrWm3m1za31kvNrdVmfm0zv7aZX9vMr23m1zbza5v59UX5nf4mkuUl7G+b+bXlTtvMr18/29Zmfv2dPOw7iveAt/O38pjBky/uEQRd6RENd2rUvroqp2YXHMzSHKA/HX+8yJcXSvKCimxtqFH88er9O4wp8iMiKHU2R2nzTKTNnZ0rrRrpcZjAeK2HEeryhPRAeBjGEPTk5dLiYbLSmfRsrXDsWdVx6wGXv2pgHU3WuFfhlpuo87ZkRZ6Zb/jdaZA2UP9U+uDG0VI066eFwUR3cAZ5LWWErVOEHlYH/dLAJ+8QzY99Pxv1m/9UWMpOX6CGhgczbf5kQrfa4sOLRrjNONkWAp8NAvF0t2Vx8IzXgfIjdW322QTEiv/4i2hRiM1JtFxGs1yqjyTo6ATejmESDajAD3Ir3HObBX1y5ZF7zh5kAKVYcL4rJaHPLCjqnHTsivQPwFWA0+3fbHC0h3US27NiyCuDi/j0DUge4ZvXr5MGoQaZCJPpnz3PZa/VGl9z2++hqVDs5/W3JjNtHWcicKTjVg91tr1U5/ecYUmIJONExeohgFc5PALvY7ogdLZerWJkP/QM7OCKKzx9gNWxGQQn2knY6fHF2bpothK/i5CuHL2GN8i2Zmi7PH7/jjDXCh5FkJ7WCZ28bRaBr2pX5rIBHtSKgwCiR2EffsDuuQfp9LWC4f0bF1YDH0NoCNCH8xQOJuGN89Oq3Mti/9n91YIX4wmUnEx5vF/qmrLunPRk0Rh5cKb2eqGwtOmp6LNJmoAHcoL+gIZDA7i5+HB5BWu4TVBwmgz7+hduP73On8CtOcyrPHDRmgyO2Hwy6bGDkdWbDK3D3qE1mPVGB4fWId2fT+b2YUN9fk6R34Dgc9s3sx0ytE9KhnLsAu02syAt9f4C1HtDl9CN6Pf2oGhIpCN9280XaqsIBbzVNCrp5d2jgfnxXAZyto+SkjKrZH6k/4gDdvy2IwgqIBhzo4DPwUFnTi0GppNOt7Pg0TKewT88b+GwHvX9MPkLsmNw947ZOKLHbTDI2DHYWLy7CNIvey5T+TN87i48F/o8KqRMN1uMoyvHfhExoGWNmaYJFwyve5qMAap/kJNkTpXuZY3yYe/QZvP9iXUwsimb7M3HbGId7g332Wg4HM5HOVfFUYmiomrRJsfKL73s3BrFP3srWkelYlF3KjiftWidTqF1Aj0Cdacrz+bzxymvISZmh9E6NnO2T4epdLiXYtM0dHmDIfVeTzlxpsEgSS9BbaXyssEQqkc9Ul2AAawHpCEY+IjAefMdHvFTOfT1uF8DAHd+5Xy9b186Evc7lVtYMXAiD5e1trIdLkkN4u7PI0Nh655LBmruuNsE/LB5zWPt1c5C8LL2kcetda+AS45luNx76lfT/8He3uHwYDYcDg8PJ2wwGh2w4YwN9+lgxvYZGzR/tux7OMbQFClxEbA5/0ySJsDxqJBOae84A0OWyyKZLjXJA4W5m0CQfgUVgF5BFKTnEputQDaFPNmCetXxic/XbalRVCibC0gNAMQ2sbbj5qTD/t++++GCiM2yEIT7Ohwd9fnrJPmcBhmvw3iW/u7LUbO/zhb+NPnyrTIpdWXsnszvg0ypPHqQ7lexE3HfYQRWG3gYzpcE8cl8qWdqH/1O2TWbuJKXcdG1akUZt2TIyXZs2ouKZhFHRM7m5BbGvRXh8cm5JiKhaAjbSCcrHsjZnNy4t2jBK4zExR3ZAX1YmwCp4a6n2ns9Tc8ufxDvIOGMNAEy8xVDRIFIrGZvf707Seba4vxOcX73UVXpLBtFVpm7v9CMr9knsjabrVEnvBcT3jY5KBO2G1jupjFf2pJ93lOAolWca2GmADNQdMWrwfSXFC7NJXqW0aTJqyO5XmarWpDaOkWvTPFSGYdWnOdEmgMwWaqkGj5dQIQGs9N0ToVY1pI5IHmXcZ7zwk5ARYaz1hx/NACFHibIrjwzNT69pxwRIElyKKqa0MBaavrZNXMO0lkTR4eqUGGRoBubKp8YYOODJBQyZFH1MQ4Gu0TQ1apFTg05d3quvTnlTlwnc1p6vmk6DEB9qMdzMBiM0yz4bzrnXo7BvP54hoXjssUbtryodB2fNhqr/F2U5w3Pz6c8S/as1y3d4+T8+FejC082VXXzgp8y7bvum2/Az/x8ZQkejvELdZAnZ1lJhXxzQf5IfIZ+y13yZ/JHmbRrjbXgosy9TltQaEr/HEee663Aenz5GEZsRSSJ/+b48vxbfWHKY1ATj2LXziRTNNXbHo/HZSkcMkszyapfaHFNhdHQBe4e7qjsCUufSVTJgRwpe+CiNUvA8eW5kjKB7z++7F1QMMYnjtKVJSA0f6ABaoMg/V7nzRipjPh3WZUIbT/gWpUc3FTJsMVdZVMd6+YM1RlSWH73lw9nF7gZeTfsnrkizxkQBpSTXZlFEuQeraV8ad/TBbeQeooC1zOoGyVy4cH96DPjvcMGVhRcfh0oDibXn5ypApF0BdAzvwQhcXXRoQJHBSqyYhkRLbuJTIrX4lj19F01fIJzN5Vks6qmve8+HJMlhSztUAgujjwtDVZO5+E9uFBx5FE72DqLX7NYEILBiwz1B88veY2+oOQFRlG5sWlza06hr1h7+nOacqfxiKIrDPhUvA1x3TLFdA2RhttNVOzYPP9Q44+fSpdSX3GeqnDWZIYcDI5mdAxWU7p3sD84ODq02GwyHrD9wXh2MGmsNNdWK7PpZ/RqNQDb9FzUhe9CX+VKa6bXdYctGUGHwqYYm6MWT08mCAT3LOpA2FENm3RzzEqnyFlNNyMG2eH0MdaZP80LKaXXmATGc9BAlFHaZlnDnDZa08nKfP0+C0ATK70XAWXEIurw2zXQwHwWFVrodAXosih3CcKAqhqSU0EDyQXeItsRnjEXyn2Kx+yZ9NANucCslTdHuuYiN69HxOHCtQnWRjP+ae6nus8p+Jsm9QhhWnyt05e5t6IuXTAb6huGdZ7pvN9m7X0Za/KIO8SySQmrkVpxVTZwgxMt+Na6XvRMK846ntS9jbOLUFWCM1+MgvOMN/CvejvyTc7tUL2NwEGfODQMsawHEoreWwxiIB8lOy1QpPoRHR6N+oP+qD94PZqslythTUb/p+dcVW4JyNIk4b61fQk2YnHSyNVGzjhpp9QVwcQtZYb/ZNqnmexeFYsM4RsC/xTbF8Y/MURN6pmdPudFVUCzRy8mS3qfVPu+encpK92oXLUyw1ioJGFoAdtlgcjsLHPZeoHEUhgRaIrw13xEUUuuglyenynsXVEfbbOaZAjVlfg9SqQwyZK6driEwlJY/01V4NGUyjBeF9KvK+nP91yROlcWgs3N6oVIQER1Hf2rpIGgphY16f6BpY4DEsYzEVGEEldaNr2OM+Af+nou5MavFRBkSAU7dTwqoMgYTKoYEu0cVREiwWQoGTIRMZV3LJzJjC2pM88xLShcPoMsrHZk13IhPZZlAQ11vVTFwMiTMJp6AogKZ8lM1Tc0Gx5N9ql1NJocjezReHJg7Y/Ge7OJPdoHF57mkoeclyeBm/W8Y98m3arXax+Nx7Ph3ngws/b2raOjvbE1P7TYcH/fpoeDgWG9Dd+qnLtkXpdUKDrn1xDvBO9LHaxQJnvkCt9gyeP6SzPqHV2i6sZlquMJPlVAiZ7EP/JksxlLMq6jBwoyGAESgFCnVZV7fP9ITkGjzAKLia7N8X2tyJHneTRZQjJqGhF4FZK355eCMAL5zhDHswuVAV7sMeviRrAsntp4Y3ewLEloeAhz7jBzWYhzWUVAp2B98p5+JtCHhPwfjAwH778T6kBZzRsUZ9xhGHLAQ+Lb8zWFH7mkt7Zn9X17vp6TmseO0/pvbOO/0fqxt37sW/uNN7l0edOpCNwModJeW3kL8Nbtayuy0QgazXzZlvdXzt9dJfGKGbZVU7p8wxZ9QhMxI2Fo6WKN0Xht5eqmLKsIjygwU2cX9xNY2dnF/X694jNK1h+ufzS5r+jDrzE3XfVmC7+nvD1rmQOaGQCkZeursiIYdP2Nde6iJ7yimylpniOCpuFGilau53myMkabButL++UNGAjYKaGrE0H4Um7JpBhoTt3NeoWmQFDyVDwLEPgUPEBTmGswrgFOTfDQgMhtcvLm897SL2AnXgHrAjFMRVc076/aLmWyiyD3zQj8iyKUpdrGhjiY7b8LyaUxBhtJOA8CvXIKuvE1GLPQFROHop4ANRHN0CbX80s9NbtwfNmx2wsOB+pm4Ip3fUHGgTHJYpMVlw8CwoN/x3e77AIVL3F8B/uoUlcW7KEbl38pCPBJOPhTNoLLpSuZN9hFX+pfAHKZI+u7g0Q+FTPnN6QCecsTg2RFpWrG/x8it4XKtSH/lM9SaaFvDRMZrSN/ywqDYIdqZsXD8TNGvOqkQWVOEKOBcoIAD4g3g8Ff1ethqmZ79vYj+DpG1FqmEZFiq1vDhTQdZ+tLJvLXYPB6DFku0h+G8MOnTd8srdO23D3uX5X43NbT0EhngVI0fAhwTUlHYAnjwPdCY+leYa2QpWlFMwVxiTa/GlsufWZFQbwil5AaxwLiUcDP5JiqrFZKo5GDKcOUh3PGJrP9uT3eH44Ox/RgND4cWtbcpuO9vcnBsGOaXT/JHGgXErKQNNeY+sV7cNELWS2w+lDG9MAe22xoD/YPR6PJwJoPJvvWwXxvcLi/b1l7+RVqb/eX5aoLnsRNhP60Y4qKGzEYT92ObqSp2T/p0hhry1klMPlMZ49RI82m1knUeUOMbvJiqy5a92ZkRO9VwD59u22QZxvk2QZ5PkeQp8HMsCk/lHkPtjEolFG6Ou9w7DsetZmdtY7v2JekoSkf9iPW1Rq6tspv0LIQLQtRzUJsTnRSOVt54Brg/6/oCwVuNdInT7mGJiGcKolvoo3gYUYdQY6FqVOzgGLfCLw7/YB7ASQC9cCnlLoJH29UAuxEn2FIYpYRaLMpy+oYXYVaQyggnkoP+Xd2uJ2n/EGkBLpsxjz7ZuuvRhpQmwTLDgUPkUn5qkptZF+/Jy3W3/BNZAJaT4+xKJ14l3NjFBARV5/OmpbsS4aOXf5zzM7E5uUbqiUIyB1fVQhPTV9yNcZGzuS/4ZRWDZkbo07dzDU0CQ+THqr2I6hXRWy05uJp83CLtHxtSq61KblMYb4v7F5rw2VqmqmzfFMGPsA2MUqXrBhFnRqPtFArhcH1Smm18LgFPCZB4pXCyRe+03WwWGl+y+sW7pirMrtL7/yV54YRRq4kIzWJOwDSTvdm+z34R29IZ1ZvOKLjnvr94PDIWu8u1jjqnbr6fVYmC6fz8dHB+MiyJmw82zsaDqyj4eFk/3A2Ozw6HB02duXD44M6QNIyl13mZQIOlFwKpRb5TkTfvQqJzXzHexQcg5fPeOKy6MHDer7VrFFi/TTU/6NEhvqlKS7EnOK6KVnRv0tONRMUZtOIQpJ8FoQie6caRvLHlgcZP9A+pyrEJEEeGOyAJe/C0LM41fV5RjtcejmZs0wNjLmfxbx4UQtuTaOAuiGPpojn0xXHazFbIXOcsdKQtDrfmsqSTSWVrFfUNqKz4crqFGb73V1aq6hvFfUvQVFf8I/dNfKPW+Rvkb9F/heJ/LqCcueIP2kRv0X8FvFfJOILD7UdYzxE4rQ4/2ziWSY6b5urU1l5pMqgBjnaLBxjo6RCKvNR1iKd1+HUjnnQuu0y3VE6VENzfaZbXt1RcQZrk6XkdFdrwmUno6PZ5Gi2T/eGe3ujo4PZwSE72KOTyWxwxIbNM7wYzqj2iqWfflGx1ifHCbmWEwiTcLRkPCBnb0NlQZh7MZjBcKAb9w9/eAdPlBw//MMfCHNttE+uU2+N7Nn+4YSxA4sOJmy4d3Q02Z/bg73Z0REbzix743OpTt5B1fZIELuofC49k+p8K5hu+Eqo29YrcYWevXVDqibdG2rQNqfO2VtplWc7uJesfmNnV9OqNra6mpz0uatradnQneBMjt3c4nZ0Z8Lsfr9PclRJC+Y6j11D6YDJZLL2pUudLAvuSdv5x6yZ1xQCWTQ/4u7BVQ285eDfaTdhOEfbaR3jrqy2UWNhmntmzcz7qks2vT6Y0+fzHbho5Dw+63txwSLRhYsGd8wmNFTH18AbqqGbE/gVNmJ1oUP1zR1S63ByeHQ0BhZ0PDoYjyfW0Wzf3jvcm0ysOavLed5T12J2z7a9sOcHXiQl87dueJH89TF2ajB7M3CImFL3cfpzzAJuQt8EVjyCrTG33vH5X4js0SdvRb4uUZAziM3VGEw7mcVBGE1DBpwsv+fRo1nHgs2I1qxP3schumxgDqE5eeV4D6+65NWK2Txewb+WfLF8ZboN0zpUpKUp8yMsQMX0kygPonAW6ZmTIHaMIGCER4MTUEmUZ3FFwndSi/+ruRDT7lfSz7Q4C3xB4pQdvXj80qELDl45dOF1eC6PPJi69lUkbpZld+GAh6VoZf1Kl2KW81AbKGW9slWQP1MnxnSMAXMo+m1Ij5NXoeX57BUoCSHDdJ987wXk1cLxZtR5RfBjVwwfLr3YseH01WfRmPGEpL8K2IJ77itwsHuVOpGUjSPiR6MY1M7aBsQg6KSXDNElrL/od8mrB5euxPgO/Vz7dv3Ag1CG9SgvG2aR/iPDPKOujbpvPCc4SkT+uiShi2u+Z8HjtBGJAF+s9ctGj61nJFR4f+ap8VNiJDACX34tEny6Cbx08wBTb13i3eQiA+2F9r5IXzmdp+SgXhHbkIgkCZAZOAwHb3o2uoaHLEPWs4TlU6NX9BrrqOzkLUUawR6AeZG5+B/Wvq4fZGrfXb+qsA7Dy5pMt2PQLX9lYCGlL035cnb05sBPcxa4PXmZjz2ZxiMFiR6uvQn5gi0ZSVi6nZdPzGATRYL2PPBRTUKq0PX0s48cu+d+z51sbEqZoWNjbo8lc0Fq5SiTKH57tiId3bwuMaW2iGphg/t9O4xAX/4L0WtRkOHRYX9vCPlKxN9PQt1u+f0wsCBztOhzOCCTyZhAjNGg39/f2xvvkacSgKrNptY6wWbkQ4zzCsN7DI/cy2JNnxOCGj/DGsAlj/Bmb2YeCes+metAHkhQEexNT+KvjAA1X7cogddf82UTK5Cv2uaU98ydB1Q4+9dxdlmprDHlxQtkI1WdQCWywfASdEgpV4/tVqyvM+PmdH5tsQNPRkgZ10K4Cw3mc2ZFWd0L3lhtNrE2zd70+HdBL5/1IvwEdotrM5w6gdxiFaWfdiAYJRVCFLqk0LIpadawtC5VLsfV2hhaSaJNwLJTpGgoMm1OAs/Zw6+ldE2fj69e/fpyFJBNhMFWC9hqAVst4GaP3c4VgJVP4Dl7aK4l+Iql8V9bVt6F4JGFl6Kkuu7Cdyac7Fgm2SWfU/edb8TnQjyybT87u1vB6a672u1vtexSG17lZ8uJ7XV3KRrpaQiwome6pZ1cY9PLa1A8d9tbVae07lovH93GjPRLYWB5xGXdDNG8KsV32ri4DGtJHYe5CyaYqoBhVP2KR6/KGH6tyw7Z7cu/nH+d7HZ24S27/RUyrcYrfLlM607Y0yvL/97xHr5a+reeomD17JMLAtv8OkmLYfUtffkK6UvpPX41BOOlMMCb21eew6ryhbnx2uaTL280+cKmktoGkmcSOkotJwoiNjWd7MxqAjZghXGKDG1sKNkRnH85I0lKZ0Uathq6t1RJsvXKcoqkOjqGr1gS3Zwkm9juX8WTveZCdiiH1xJ5K0Tzr07u3tE789wg04r8vxOW/MWK/BXe6nlaU9tTfTNepPAm1fZKf5ne4HUoNbrOpVQaGlat6DkpdMaLL0+lX5SP+m/Jt/srV4ttzow10VE8P0e2ncakFuPzJVWDO+J+vsgdtarJ3xMfVH6PL5wZelbWx/gKfOXsTz1Gw0gVW27jmbgNAVJbaauyWz/FD6FW5iRsrmneuXaL+ryXJDd6jpT7JfNullqnxmBtjtc2x+vXleO1cZ6leqi8WrVoXBONn/EGenPKnTholGlRr74oyv4dDAZjrWZf59wTFZQSEnH98azz9AmLAaqEQcPubq9UK8a3g5HLa77Km4H8TJ/yaZqeFTDkEyrnx78agUayqcYwkhDhjVGn7BmvWont6n/2QLTowSPQ23120N809WiZgJYJeAGJ3mungdsdx2GiIC3x2Ih47PR+d3S9aZxNT8bqtM9D+zy0z8Nv6XkohELu7nUoko+WcnzZt8FwuTu623qZcNdUpBiN2XCwN58wi80PqX1k0fGQHo4PRvbAGu+Nt8x/yyHmU6azbh+u9uFqH67f1MOlh3Tv7s3KEI2WXnzZ5yp7pTu6Uf08ywAwT8hs/crT+gMr7vIVbHgosEkVKxCea3HgaL3ke/ekaW0N30IvDqwa8IWVjDJ5KtQYBdC3pEOinPVTtzC08Og5E5tP4ggS5W7VYbavafuatq/pb/A13flD2j6hv8oTuuvXU9PuhugA097oF7/RnAfSzu42fHRb+1/7srcv+2/6ZS+Gr+7ukTdRkJZ4fNn3wXS/O7reyPJ7c8d7aF+J9pVoX4nf9Cthjq3b3UtRSkpaKvJln4uyi97RPcexKY7w+vrsbbUtcD48mLCjAe3N6Zz1JvuTcW82m1m9CR0wezK3DifDvZw9cL/EHsjFj9u6Q2+EXtrcCkYQ3uhnqW4d5KBvd7NkIbEaqBpfd8WZbuLgvMuz3c5ZWl7L8DmvpdzVucq5+fn8lPM3mix2zQaTYtvIweiDzGLnbhp4My8Kp0DVDcTwPcVQ2aUXRhjlGXnw2IbMJqJfP/ocYXSj/vImB2WOeap5H5mFCWzURxnt6VuxPDdibjQN+cKljoExEt+J+E5sHgDlu2ehSKmUbsa0jSw+UN7jrh8bOBb1chyfEWxBYrgfCNz1WbDiUUmdYwkRnUd0Rnc9ddNRQLkhslmbBVvI1PnNpxDMU/kEkrnirs0+bzjJk35H1ZB2YQYrUVabiMLxxPZWlLvr7ygE1Ida9YVp3kkeWLYg1x/fwRyxiwmXjXBQICd5W163EyZRhtnZfry6uiDiI7EwIBSgbc4ia6my9Wkbhrz52rzKgvnU7cQhC44XgCelKApNenSBQI4LA1zlwJnLg30WJIVZpzirQtQ8SdOWnqFghZ6lEKGDgc8siObXdlsDYSE7ejkk4GdmE59GIElEEQvcsNn1S+pzicSl/uHliBYmm6APzlvmUEMM7gl8IzZ8BFANmeW5tkHgAQs3D9dsWrXYZt+5ixYzapOL6170ZtxxoBb7CQaOX3l+7H/cQHzYyAsgPZNye35DS/xTTabj11hXTSmj9FKgc1OVx5KG05WX4SQV96PpKQr71pULhY85xUDue+5gkgXI2bSxsyN9Wseq1QoulGdczqJVHe76VAcBdQ2i2AkNbILfyDf3PKRdsqJhxAKLBnaXsMjqf1t8koGgOBwpDLMCZuBYTvAzEZ+BqNrwagDIOCxixKePmO6SxtES9B4ii4rp7S+wxJB7ZWKgP5CSZUJsvoCnyZsT2IBx5Z4782hgw1+VIjq8BCieUwcSrzwS2THDo2QAEvc05YL2GvPneH4v9pPd8wrH2DyYaKs2TZW/kDzAvGVw7pc+c2GId3zFo5ZUvhRSab6clmTulGSWH3LhVI09kdieeO6cL1rMeVmYk72aFm+eAW+KR7wOa05h5OfDFJpPS1PQFoAQRK1oGsY+FErrdJNfZtS9gz+X1F2wqXpMVyxaevCSxpjpJ/ndZhHlDpyRxq1gWisWBY/TLAsjzjaiQTQFBmQasij2O93OA+VR0sWh4Lv7CeW7xniFaeDC6q273tQWVYBwFRrHYDPL4S5mPedhGLMg84sbxvM5t5CRmMeuHYoy4AA/aiDuWl4AOq6pdW9l/va9UIApInr6O7XtQECd1hfOJjFqcfeeOtye4lSYCQw+O0Cip+yzxZhM046dvORGxY9omLQeCx/8gPmU21Njr+ylTRMkKXwBZXZ28rEdTi3qI08qf8ZLnlpgAdEai1/9wAOcE/ej/Q5nIZjh7O+4UoAfpl9bxFa+F9CAO4/T2E1Mlp0Cijcjs9vpn6v0zQmBKSie8/TlBxadBMzm0XfUgRNsH9eX8rgabqZ9W3f6tpac8HpZXjQ3Hs2cQ0rDCN7raflmnrp4LOqVyL2BJTdV0qaEfJQqIAoPWiLSGxSBYiMWch7rD4auzCBhIG0qB+LH0te00AUvtFZL2NH3+HQc11tNtAxYuPQcu0brHOSlXbtq/wXoVABTeeuFK86dvgF6z9x7j1vsRx5GXvDYku4XRLoLV9PS7l3TbuMRrz1TLno1kXUQq6d2bD5Q+Rm43arvAVsJo665UQQ8ZlR6L0kLY+GdJ2Scvan0AzLeQIHmyXy/xslULuDZo/HFUFy/8WNG51qDWHPDq2RqJu5t6gV8wQ0ja018e15ryDCfQ7asad4ipt14VwcPw2Vrh2UkLtKLs1aO16+JHOR6JliX2XE5Ul8E7J6zh/ZJe3lPWno17ZP2TE9a9ohrst3P+0BVknwTCdfoMSi4Gr+3zVfR9OHxWcDNklQ+hbj53FBPtB7gRLMuDvNJVGuM6OephZLnVGx2R6cjhpTSxhQr7JQrak0iWR6HyhuLButokVysbG5+AANuZYGu5BpiNzku0JryFTUkeFj3dJsGgUv5OaZuJFPkV1+nDmXddIMSmDQQTbemDW8+Auw7LYMz+bkM3Kr4GKWRtgM6h1V6PnOR8CHnErsqNa3Qpt573DY83WVMTpb/MbI8ucVntpqsO08oDHSxtZy/VKagNZs/N09Qy2ZejFfbvcYuDvJySpVoBSVFFoaHup5w1dHm00aD4ymvP5sfSrXsdspVaK1fwcukK61TwfNSlRoeBa12v0S7bz7MU4cv+Iw7PGo18S+OkmQvpyUnz0JOioe8nqZYlpQldNMXiAuRITz9WLTuOeyeOcqPtyf6YDgOIzYL+D2zRUAO+BH7gXfPbRklXx31enl9cfHh49Xp2+nFx9PL0/MrTYI6/3B+2ul2rs/TRh/O3/2l0zX2uj7/9/MPP52rk5pacRh5KxaUbuyM/EAj9kAfiTxUWDfEDUFAuufEERZfjCPLWxlrWKab+Hh6+eHdn0/famvXfsJ/Xl+dfTiffn989u70bbJEs1WybMFasFp+4Uvw2SZyuMTZWgxXvfT3Z5eXZ+c/aCtPT1R9+yReF9+hjwazucG5PvJIwOYM5FGmYv2vz0TpSnIDYUzoq04Ek02Go/HkpmMKPtrIvK5vD/z7K+ztelNYRYEAiH7IAiOiOaYqhUEMlfqcR/KwZC4Rvmrkj3/8Izl9d/bD2XfvTmsU3ck4ueWP1PVcblGHsBTZFWBiMJe8HAIhDdLni0QBp4s1cHt8cvLh+vxqenH8l/en51fT96dXP354Oz3/cDV9d3b+76dvp1cfpsdnOnSoLXW6nfMPU/MAOZwtbVQx/dvT74+v311VN8qv8eTD+dXH45Or6Xdn796dnf+AjS5P330/vTz9+GdY8vHZD9OT68urD+9PP06LeNntXJyev4We47eX0+Prqx9Pz6/OTo6hDXyUS8h+0JE6YBARzlyb2dNUC5iPMYSARUj7QG1MwuGyzxBnyPzqy7q+PJ2e/ufZ5RWs7+T449sipTx++3aqkcbCpRhGuDy9wn9Ojy+1Q4eThIOUgwkidv3+tHgmH0+vPv4l2fs9C6gRR/QoE0WYiUVdQWqhCu+Sh/B1FTIHQom/uYcoT3ReVSD97fpUEQVpVCFtgl3ZdRpvrFv9Qhpflxr0vJSGlj3tqHwIW772pfG1yb20LO2zsLSZ812vddPMU7kiDJcfyGQ0PCCqCYaNryOyb2V+hKnFsjYiLYR8xd30c466iwTZSSR0JOLfhBwLvBD2M0SmZxMdDfInmk6pr073dCie5jWcc+uo9vLISO5iWjqyazpiOOD1Jyqa1wcwulgEbIE+W/fUiatFTJG+xPLCSAlED9y1vYcu/Hl9SWzPcagp5xpq3+1pxFfmSyvxAxABOSW9jNbG/G60eTPDGdAgDxryJPMXc9kaFV8oTTLcTEuUdkqUSk64cKTFbq217GUiTGste150MVrLqPv4YY6J7syplmRiuNruWxVmqjpmqQIwdXe1sPX+RcK+HsPqPm29k2TCZ9xSIX9KkWmRcaJaNhETY7PmYORWQ6XP2eHpFJdYyEJSOL88aCNci0IGLT1/KfQ8eyktMd8pMS8e7trTNGYW2oAWqIhzDPUT7FfR2zJB7uKsuBWHfaauHXCaT/4qHDmbJdWthMh0po1yNZu7l2ZnPnNtTOwQguHqhWZ7/8iiOHDRNGDI+Y6iNA+JupM1+cOFN3voGSq2qnmoSzyf/hyDmQJaJhlz0UojcsGDlQ8wTUs9D9q+PrlkkPoyIlSs91YMcUt+jlnwmGZW75MPIvMn8YQqAKyMOLYxe5c5bbx+MP9ggdebUczwKHKpe/N5yKIucb2IULFscSB9ojoOxEa0lPkiaRmVO688y0FlSnt9bWw+F+lhyS2mt7iVJ1r31jA3bWVy+2oQWVE9Qajc6IzN4f7SsKitc92bFyGy3dPIfBKg+7GcGG3g6W0EjNCAEdcTS2fVefgPB8X6h2szH5cStKYZwn83xGyrE54maaPFCU83yBe+XY5vlTF+2N32yrQqmRuNVZ6JRZ43uHx8qs7L8mwXv21a8WR7BRjwHZUtab17VtpYpCGwwY1mGlqSuax56JXDwPK07/jjFMcLuVrlBvMUx8lPlBR73WR00Tk3pDjMjQbErobhprmotg2HzgwDrAf403vBo+Rma46q99KixOl68aYEFtIB0CnC/uA6jwmWLZg7pXwrYMsMAUlXZL77JhRfHy/tD4PFK+o2O8DMWKp7YjjZYBDZHXLNzFwWbbovbYCnbgd2uOFA2BX4MS+IsFqlZ3k1MmebB8sNgoQXvW+mIl/8puPmR0kHZpveQ9r/SWWw2wIvtAEMeHHPgnBzaqB6F+JuitTNQNyylGMNucqhcLf6OcnQE/1GdLTVsK4rbIUa6ErILUBfEW4yd5SeaPlTaXz9CqUoZAuCLRLeRxsmlXh6Q8Fku55szbVaWCYue+4FKwCoztzxcNGp/NM/GlUsPEOkywUFrQ/BPvAPMLJWO6mMBqO93mDYGwyvBoM3+P9/7ZSvJk/Ts+v5gbnHZ1/49Ib9vfLlZt6LXAkI9UmKRjaZPRYWXD/rvl45R/2zb3krXLuH//oEFZbCiHLXYWGoqXx6aiwWVRy9/lzltgJfUh/QNC+28RIqweHHjxUrMM19Hq9YwK36k6Y+Ssmdcjfan+jLmBwdomcSeD913kxGR5Oj/YPR0R7KH+LHQcUyM69pjsG/IPJbqjrIQOgJ+mIWsYmhQ7SgOkr0Dwm1LOZH5OzifkJEiW7ioHgUkteHJFoGXrxYktfjEfY+u7jfLzQbj9J2w9HhpiA3PBr1h/uH/WF/8HoEhzkaDIZv7NnhmzevJ4fbwh7EXkxhHcUTfYt/zVhIPDdLhbhLqKhtmChnyBUqTsRfJJDUgN2jSktILo9kxhzvgcS4UnI758yxw1vi0iDwHkLCoz65ghsBtziSijsEUp36Ebnl9i0ozTxfWJlq1CFphaRWSGqFpFZIeiFCkkgeNC2rXQUkVAYV9JK6S8o1UPSVpa365DidKMQCrcBx0RAKG6F+X2uMimJBkUFxH5Lb2BUNmH1bVVaM+hCix0RCEu0PDomhoT9+UENJi2ErBj6TGGiyM+Ygt+haqj3a0GILFrGIErnaYV4QVXHc6MJ6qwZ4DcPdEi8Qxo0Q7R3JR/Qj7THXRjPQikbkG+Dp5Eq75Day/NeTyRgHuI1t/zU4ww96YIIZ3H7bJ1cnF8iXXb+9IL5YWIwGHTJj0QNjLhng9/29vfHepoyZXAQgQXYF2/JkSVTkejWwsZgOxNbGMyfLu0NtZWTRxNhgTYKoKuADdlBxViO7hurOUMdy4/mPwWpKLn0v4vPHjpbgqjiRGpBAky4o9JdA76ByL0DKhQjc7ZPjxFMJWwLYAnOaEMk1cbymQsCo8ZBKDuxagatGHrFc/hdytNaczAJG72zvwV0jkaVWE7X4XxTrhPDzN5mOxhbANuiDICbusXPJrDiAxFhgHPIdCquaBwyfx4LZpZrNrK3dqAMOluPF9tyhkvWu94AUVnAp419lg69FU5B5BfOFxdS5gOhkx1YE50ujNNQ3LxFXbExxAD8cX53+dPwXEWB7enkJQZ/Hl99p/lTGvRe6bbltM8aXQRG0XvPQAe9KPkpqEa6ZOS/D1F8F0ZquIXI6O6eqwq2oCy4ZbOU73iMDFwHXJg9ecDf3kMh5nhP2KxafZXPqLVvqQXauXtR4onoLkR12uYg1DhmOKk+q9ahCkg14u1Tb8pRdpU6V66wxbb+DFSq5uGRRj+vZkI1E6UQcr5ajN9MgJIPnNAfbKAwaCpZJbyFV5j1U9U1nbTMpL/HJfCG1TQeqw47tBsbDrbeQ2hTxxNCjbBkN1NfUzWqA5RAN1djD0Tot9rBkqWYu2XhU6wW2E71p/nAQRHJyBSq3TZreOeT3RKe+vJK8T44j4jDwPQQ1cFKX3gtIonIn6KYnYLt/4+aZK3i24IfXSsAjPuVBSGwPPQ9DGvFw/qi8/XAYcLDt37jH5Pz6HbGWNKBWxALyzfW/gID1LWqg3UdVdxtDEROl8+1kMLjt37hr1cM70SK+WJ3c70Wp9kwqJ8CmJIwo58T/pWyPWa+83ckX+ZiAZD/GuJ6cxqG1wW1og8trDNKDNIQDZdtKxYLmYaFToRyXYGNhyoLVyuFWlPiYNnEq3ShmJ31F0ydROEiXxvCUyEPicZEaMcQnD/03A118W7GIrt9TMkyJ8j0pw63Y7GQOFY4v1fNCsk6zlzXA8A1oU6oPFFlFzsRYw2JtwWR76+ofyhMz4DvwNWqC7Gxbe2Xvwqu3LA5pd264BvTZBGt+N07vG9/rDu5qwaL2oja5qOZUqFg9o350Q+6awvae2pC4NiSuDYn71UPitiOJ4bY0MdXithSxpYgtRWwp4tdIETXb1W7o4WNLDXfMx2csfBtekON5d7Gf5+MTi0L1NYnOBlgH15yQQSYNtGiTkNHAWiJiJ9oYXV2Ieso+eccowjoo/qKAcsggcuM+LHnEQp9aGHYSBXy1Ao2RwFCkjqgXhI/Wkll3zO6TE8+NAs9JjQyh0C/duNGSuiSiM5wECqAJv5tQGhoMdgaDImvmeNYdajLDEPb3g+ctHEZOlmj3W9HPiXp3MBhk9L0jVEFX5VTKpKAXB5y7s61T75Sr8WzPisFKI10NAkPJv8qEPd1O6h20JsuLB6swVKAp5jRYl/YH/FX5zzGTOi1V4CaNVs8en1BI17OhXUvHCXzfI/DSkEQ3CM0RU6BwDFlwzy3w2GHwTwi1EM/5jSs7oyoy/FfAERs4Cqg0/UjwEgGcLIfRQAZjJDEYsRMhbmhoA+6PNy6mSgfT2VqLXp/UNOLduL+2FW+nBrgdW82+MpMX2ryo8xhxK+wxd8FdNv1T6LnfoyFcz0OW51hk3E8YBbEVxYHkbL//8PH98RX50+WHc6C50qed2UqbjsysIMEIY8lviveEuKAusTwnXrlQqITaNKJdhEUKHwnycXWgBDoa/KMRjxIWD+frk1NqLXF0Lph4HFE42d+xR6g4EAgGBZ+gyBNemgxsPsyWqw0ziyoQXTNdF499TiOvWTfyYa2ZY5GOEjPFoCJO4/sInmjenDDYljxLrrh13HbIourlZs/S7MMgl2P2Wih125W9cANmx708jc842RrzunkPJvsOsNw6U48hZ4VjKPqBFMrMAiTJO5GTfcogTvizMz32+SkwVPVz96mHd00ZEGTT8inqK1xWMmGV2HlqLSk3uOtoTtGCFxRGLosKd0Qg6/j7xsat6gN6ynILlXGw4hBkazPE1Gac8ixD8SqjKOCzOKpxhwAaJc6qJw637n70oKiRwkfkCNTg4vVbUwUrwaWSaI9ksBIkbHIuEs3SLRVPJt0TPBL/AYS7PrwrgrxbCtlsNGNuUnW2pQRsR+SpIe5Ct6kQZaYo809pNEUurhLY/ID1sLl4KrvA5SHpwwc6dk2x+XWXBOFlPARwaIb7lz87CCyXaf9GoClJryTEeJ6V55NZqQGM0SmlRfMyNH9LIxqy6FhACtYVW39GoeWZzkev8GSLcYHLkvWAE0HpYek5qbOFVJ1SEnIXhOd/eK75CFXcoujX6XagJe4I/1FYzV9B/onook8uQACDqZICbbe4g1tY3S30NkdKJpc2GI3ZcLA3nzCLzQ+pfWTR8ZAejg9G9sAa742b3Yo4veJVyGDQ5tzFem+e3TzdzzlFuZtB1VuxnTNJ/Rur7b2Q2egZKJ9ALoJJBC+8Ff25/I93KS+tqI/g+esSnUqf7hwjpn1cNxl4t3LbZoZBM2XfpHwSEpv12Mpf0pCHQmKUn0DVwd0FxEALvYnUQZEllwj8hlAi5tKGCyPuOGkYNCjHu+nvQnrDPc2EO/X/Ze9dlNtGkrTRV6nQmYi155A0SV0suf/dWFmWpzXdvowlT+/O2EEWgSKJFghwcNGlJxxxHuI84XmSE5lZVSgAhRtF2Va3/j922iJQhbpkZeX1S9Iy9QtkXqf4s+n56c+nJxfsz3n7hAHk3KghkX/ECxhsGKi8+UwOa94bAIh/IPPTe54sN+PzuUSDjJD05jSQqLwLmmlU33i2VGHJbInPypWdZC2mZL1NpfpqXBXSZBFnF2oMXqi1zyFGb0rR62ZPPXa99Jwl0dM6EmAId3+AH2Gnw2TJxI0XJz38SnIdMgIlgcKj0a3MHYCamjCALSk+Ws74YgBZNJ80uQI6O0CX0XV4wv1wkQptCWhIfru4eM8uIj6few7CYJC9ou02ydf1Hm1nVWx8ENenuKOth1kihWaiUskPBm290kQDh3XOr0I0HkyNfrezAEUh9MvdObGc38as2JDPyrxYE10ndmx0aeHHiuP+Crn6PCZTIM4OChcHMvC3iudeekFz3kQjZ/sJeqnk4PKlDVm4uMKqfsskWUs+jtbcxEtsxVALG4xvNW5t6aBnH9rgtqCRGVyqeIHgmne8O36S+1QkPJ4w6A6mqMgEjU4eHsNERCvKUZIVyIDEotSXWbExTBosnzOx5FdeGA3Y6Q13Ev8WfRxwZGn1pz02xUqr8C9Aj/DDBfEGSbxtjMm8oAoVZDAQ3uMaFacH9BwJyuRWCSLKFYRGt/A6IDys41nG28yvQo8YkEH2fCSQsII07sCVbKofEBKtpcUREF731yLq43Om+9KDYsfZ7sXKYC1kvd9V6nOMaaDoBqL1MBZMnhvrxnQw7CgauQOTOFddlPzo6gGcASCp6rXxw0VGF+D4dqXiC0WGIwi7SSJPXNnxzb7H6dJxspyDgK/jZZg8wxcyGoDsXja94r7nTozTHE8xWAV/N0+5kUukuviuKKG3U56Kjb+BGGoyr3kaOFlIA85dlYMtTXjDtCVlBlnxG0s9EzUD6wSatd8VvzF/pWSR3C/110E3U3FsTTiT/ClmV17sIROUyV4Yb6PZD9zQx+/P7kFUVfrQl07Xq55Qw415btBpKzkN9xSiWqZpIP89ZSvBNRSj9GoSq8EXucvXwHXVe8fyb/bSS9gHOLhPjl9+eJrdsCqnT7jSEatKgmYgS9fCWyzhbgNLXAReUv+2IlBGmuz0cPEg0wgsq/NzuDi9WfthJKIN3Q35Zfw5XDDVofI8g3H8UtzSzVzw6srwo605du2uyrclJ2VBq2tnoO9KkdXeTGWwPybD6rmy7TZISfT2BbfQ77HKo+MLDXfC02QZRt5vpAegCdSMEngjiYuz3XE/CyYBjhk5PBZsKW5kKElTUNZwNN7d2z94fnjEZ44r5sW/dyCfcy6ioK+gS/sSFUmZljstrrEQ1Wv7oW0oHcb+WgHYYuW/pfAgdDXQ7Tn90wgE3z+Np3RmY2/l+TxiaDiBKnYiilEchmm6KuLB6MB8UeNqTf9EAIPSDJalS2enQf+UN8OWNdJyXbNygbTPXwrnrrrqoPXAQXskJrvdlM5/EjJxI5w0AZwwHVuoQlmIH8QY0tLD/4VgkQ9QofmCz84FbE4CnDGM2MX531mYJusU1GDUX23yixEPp47VBp40bIq65EpMIh6QE72CiGW15u6fufBW4gN2/sUUNEyaVNiWe8O9bLV3pMFUuAuhWDZVemOvP7x7wyyKMfvlx9MPp7YW/8kk2bGfz96cXbDRcMdYO5PpNJ/z0ooJ0E0BAuUAIVDGBgSKLG9tPs4hpHThCLQudczgbvfa34pBVNmNZolV+la32hQGP31Ajue8x7nWqZw/mZX3XxihN1PedlKuUqq8vPjOyKQJ8JfaoCFvR3BdvqL4S2n4NJ2m2HMiAh44AMItVFC6jHrKeJ7MF/BiMn+XrCEZG+++1jmZARh29y7ATSvb1yx0jibqD83sNsGUK27HDZJkKrEk8WUGL0u3AV0PKsyONmmDWCyfr2PhTmxX+UvuXEK8r/yShG2CfVtBscxYOGHgxht8FIMkWs4bT+mWp93lsBkLZA68Z+5eNTlkV1U5EhDWchamgRsXT5y8oP8jxgWPE75aK4dm8ZxlL9zlZDV47W2W0jMNmJuu1yKimejIiZoZNKF+2a68CgkiDRLPl7VVI0sAUjZGFM+3PcZRmzHGHiJmdHLi42yqiSpjRI0sBnivVfNRMSffQu2RMSrjubu7d3R4dOQ+P9jd4+O9/fmhw4c1ag+Gz3RaSjV/XMy114+XQP8TxM4t34bsIrwUAfs72KEy074KQA2YCAjyMpagtGwd+p4DtSFSiAlif/3lgrqIbUbTolqqHGq1N1E2ZtmgW8WArLmm8f74rvCGWadGq/4YrX7kXujQhWqBkjwwpVaY5Ub7rFE7XMWsaZp6Lg0b0lUVTumGa4oV4UGepVzclj3oJqYDrvXXE1/Al4s14aW7LO8jk+STbVFuvY3BF44K0jOWrlqkEVf00RBEfg8E6kQCwyB4iwSWrFOz1Tao/JvT2EZEQuXZL4WCwu6ygvl2uiMV99WpF2xkhSy302z+27lP5wmiUBout9QFes74blEVIgk3ZAm/FGAq0QBwyP8xEY4BlUt3kA7FAhVSnZ4p3p5QMpdNs+PVELTph6YNmv7ChE1CdOOp6yV5nHNjOnOZk1hI2AivhLy8QpV5in9i+tDZqxb3U4uO8R2jX5Qwc53r2WpxHA5EXhxwj2bz50OnfzQWo/7ebLbbP9objfq7e3x35jj7R8Phbj5HdffAtixfCguTLxatoPC6xKi2pO2NUrntzStTuX/5buEsSglNGkEiMgEKhKtCC+oRLSrRIU7SKAJvPgFWeMnSCxTagXBNpDz4evM3KpEe3pZmAtoNfrVl/+NhE74DrZnqX+c+4LTCNKFsVMpA1xAbTd9sBnS4yAE54KsSzkHqi8BNo4o0NBv4yCbV3CsP6FaruT/8w7nVde1/tzXcmzeqfQ13e1/br+F+5+3ebuX2ip2nJBXbvNvqm5bz2fi9fjj79fEUtwClvNsBn7he7IQQSjEJI29hy6P9M5u++XnK+uyVfBUcqkp6pXmhXO1K28UbjE3Rb9+yP7PpOYmvZxq7vkN/si3LGpf7/5nPhK9/qe1c4+ejsWrJr8AUpavT+dBRbWTHm593ejul+ez0dvJjaCNx55Z/DWrBZAVYF2tf1CHRGH7K3cPRoXs4HvX3j4aj/t5o73mf7z3f68/35/tcOCN3f08oLyZatRdBGJGNZDZ67hwO93b7R0d82N8bD8f92XP3qH84f+64MyGGY8c1m8oKedVGs/b2pxbznoggUQU8NmppyTxfryGuG+NxLcQRsycAhvAUqIKWOi4gEHgRo8Vo0njkkm24INiaJrdj0UWKb1p8/xieGM4NwveC/Jn5FDA4NrSncFzeZa/GEv7kCjXSJMSW5/h9dhq4iF7D3mApH8BDkV3h+6WeuvYi6bPUz4pHl1TrUb5Re0R1MUf8PPh9Jdl3PZPmVlgIKrokgui41tgwe5/HMloWnpfXofx2pyXoMPU0WU48d6Jt8uh9tNg3UlT8AfLJfK8q7dyiOhjl8/IfI6dSj3kDMaAUpqXgLqgZABERXnpVKcKmGUD5H7i0/ZiYVOND+zLYkw9hsCrvMD/Q+hHQoI3d0D/QJOybUTS+knGKyuZYYM0bd27y63UycXzuWUph2/eQiZsE/3QpG0t7IdgJdBM3Mr6KNEFozPxQQjdJa5Ys3fqnJ2SLw7p9i4nnPn3xpye/xgATxJPlU0x4g1SaaeG1KfsUeJSUcPZKURO+wxzTxqyzWq6kL0b6e//6ywWFjk31xzBrgrMPr0/Y0f7uPvsUQDwUpCayJxDKE7949mwRijgORDQIRPKMR4nn+CJ+BnAR8N6zHlMvXl9fD6K50xeul4TRIIwWz6K5A/8HfQ+Wycp/OvgUAInpr2R2PlXAEUIlQ4x9mEXgQ0+AN8vyo/AKpneT8HLLfC8REfcR0+dTAAnmGDbnBa64ETHNFiNaJd6byj9PwoBC41Ry4TVkMuHXExGtI5HQXvGWbjkxdMWI7/L+oTN2+nvzo2H/6NA97Dszdz7ku/OxM9t/8acBlPiY8eifw8+DGf/tmxzUX68N9Q3/6nwy25zE2iTylrEojXy6MRSlA7/AsBSjbsLQjjNn6RJPYIXJKCkY+KBN33NjFkMBW+5EIUAKguXX4b6DyTM59NEsJCPv02m82WY89pyJvkNbqJVSQOnkfZRNZAmlDk3xdcJ8WYZdPDqyQZE+5c9yHL1sNgViJWt+R8t8G4t/q45LvoTvyeY/S/1LVTgDVcJ4EgYZBbXHCaWSl27zi/QVS0S/tEfLjkhBbQ5wbElB2Juq5/dlM89ztipe3g2dxjmQyw0nDr3c76yLBpQK/zXSxDqMkz8MRRSK8/wRyaO4BJ1oJd0eqRRVT2PrEYY3IswIwhXyfcYx5TRn32hk25sQHNQgv/IkdHEOzPWa0uHRAwS4qL6f7yBmM0FF01fhldI4Goe+nSNfgBqmeX++J/ouwOpqev1q+1Y6Ip02LTUG/N3tWNVxlKvf00eocD6zKvETVHKuuB9PKITWsmUYloqg2YXgz7WIHLAAQzRxnHirNsZB7MOyWV26trltB/t2ORiDaqsmtfH3doeDvUpVqRBwVVz39uFfNerUnVSdMrB/1Xs2ulHjV56qrYP7/77cVW0D7HKksQ0vpjS2lYFIAEdElbuQL9Wa85JkPZDvD+j9+J+f0Iam7Yyfdj7/c/h5p1EVpegyTTkpkk8FAvuWo4i3GdlZZnItdxlnbByK0uqYoZn1hwnMXHWGle6Bnf2//nLR/0ncZic6ZwY52KutVonjKZKgpfPTk/7p+Xj/oLzhiCseiRzqENhJAoYNwLDXeL1c2mqH/yRu2dkrC5HbqPXShgEDPVyQ3avK5XB6UuVkuCn39z/s9ATOHiTT564a+9AwtOFLb8cysv/drCfu27K4faj7kixXddPEvauYqRNdWQPOruoW7n2/ssciiaH1AzYIFhWWgyZCH25Le7uHe91ob/dw75H2vg/ag73bLu1V9ngPtNc2OO+PQAbF5TUWtsVifjg/7nKGP5wfwwluNt3e/QhvTNwfkLH2dj4gkcN/90eQwPFe/v5e/v4ef6/YZ1sxj/Nj8KyhBNB2kzclQNiWipFZIqtgZKvQTf003oxmjCNJRxGFtzb00/ok3pEeLCNuMbrQSfoYdVEtHFfROotvVytAHHOA4FG1fX98cfKjTsL4rs/Aj5LWf5S0/mMdrV9aQn9ykwclPvK4P2Dv1hSvla3HC6zMBCYoVauJkGNBb4iFE4kE39UlAqf/5v6id+m5X6aqeJOqcwRmLPBKiwGbXr5gEP+KrnQvQJ+7zaGz1UMXOu38tsXj0pIQt0GCpPY9e//x4o9Nhx/kdhiLgoY1WBhKs7Ktz/dFNjDh1qRTVWGqBe1ciQhCUukZLKMMLFOdxuyJPKhqfQkJzcUInqe/I/r6/vjCppfTX3/56bxwLxnd1/KGznEiVWJjh0CRWvPFNvqB3b9jP2VZ4UuLDbzj1hVY1+O+bbZv3XasMy9VW2bbFiOIHrmYtOtINVraZHrEI3d2D4ej3flot++MDw76e0I4ff58zCHoxDkaP39+NB+PJAt5AUoo6ps7P73d3/3rh+u3u9cnv67G4e7R7OofH/9n/Hc3in/87fxwffPu+C+/rg5Xz0//hmrfix0/uLz87eyGX4nF4rf+j6+XzptffhntBzdX734d/mOS/i3+n9n6p+FfXjv/i5bTR9JqvnrraKuBjUvsNrbmt37IXTvTVt5U4VIxRVfMobQu1f6QBX/jBGKwkXtg6XEERtG/6SKp5FFVX+OYQYmu1gF7HUZU73BtfEzmsiS37Ikhnj/tZQOm4g8Qhn4debKaqzEYGYN1lTkYYGR6NNTaC5Yi8pKsQEPWwYD9lI3CMwBTKVqwhQhyfzb8wp2wRUN+J3op3BTmbZ95y7vTUGnlcxTwPe3DtnYAa7tgHGNjRjIWDKJXKfxb5ZUmy0jEgPrJ4nSxAD93GGw72HTLUYPfLBqwKoDl68XlFZY1B7hS7a39OQwWueohsPklR2oehyYXILoPdcsbN9mEK7J4bpfV1UzQfbvwoDj2CrivKxLu+QgOErApemYbYD7aTRGhqbrPLMsHNeOl8/Q5FxyKIndCf6ECPZhSFX9z8JuqXFfQr/UKMKoY/QRyAmHPjKxBjFXOFujOlG/NxP2iahFs3BG1/tJ74AHtqJ/nNl4tjN7JXk3Ue33yFCToVMVj3Bvw2u8EJO1b4ZRBIXoCB+/QWjcpXi3GKhbRVRZQnhODbkCnBOFi3iYWqoHHmqexLMeopzIZCwJ9HCoozyBLLQNyYYlYrX2F0+mkkX+LaWKQ64W6gsrjkkGmUr/wxRzt/hHUNKDUi39f8ejtlx5DvEgw6etfR196zE3RzO8FMdB+GAzYBbA/7H2eRhg8NhPsxA9Td+7zSPQDyNfwvd8gh3+NKbG66bkQL3SSnCuuhA9HKh44uvXACVfPsBLSM9UPctlny/C67yX96zC6jJ/Vp4lEXl8tTu7mBHp4djV6BsJL/IwmmL8j94ZH1gSR/Abmjk5BCUgRW1a9MNAVq+gSQUSvJJQoYFSFPEv7UzsWp4RYn4RsSlwDMOk/BaAGKnkhS6UEFaIHWVQo5P4z2wj2KnTiz0+alzub2zMVTPbs1+ukn2mGz542pf15MWaQYZMnn3b2x0fPd8dHu31nNtzr7/Gj5/3D+f5+Xzx3x9wdjYbPXffTzlM4VYWWeweCzw7dUf9g9/lBf29f7PaPDg7n/bFzsHfkPn/u7o13P+08bQ62m6e+T0JlMzP/fqAwSQouQAVuR+xRBRU7j0Y3NCrJbZRNQdAenZvLZqhDrtfCnUSiOwChnEqxg4qC5/nQSL0AegolicSgoM8WOpQq2yM9/o7osY4dKh3+gdLswg9n3J/EIgGBAOLig4WATNoWYe7ZrTFxxZwDMuDKSzwqxVWJmwmyj3ydZa8zeh3tOJ+CN8XfZZ0xgNCAWmPxC7glGeuz6SfAv/y0AxAaUKFOxXsjgLn6ww0FoZ1A8HkYreC+pU3QnSB8JnXjiuAWyhGIOFb46jEYVbt2GYSBoB7jS2/NojQIMOoC3zKMsQ33LQF7Zu5O6Han1wb109gf0BMjzxVtNugXmCfar0n9lU1jqjuMxRl8kDDIiKwRS+i30o7GA2Or2i6JRBb0b4uokLInij3pM8cXPKIaqzqqRY23FjeFFtGK5NYibTh/aFrEsN/fSel0VvxwcbdzguS2vTMCu/BAzwdMC+imdEiINjY9K6RygS5IsVoIx/Gv1HMu2TXHIk+uF6OpsXxm1FG5Xoa+wG/bjh6qHhufvi0eqfzN1uqEFO4uCbdTn/gjkYWeKFeJLkDwtH0yEPUByUAwj2TZNgtI2dMKmuPrk92jw4M+unw8HiQM3qtVdOEFefdnQwToGfkXKHd5/Xa8X5EnaAxPQ+RZ1jCDvKu3UavaDHvCEfND7h45fHfED3efj92hs7tfBGUYdxgUWdxbClDGXMqunFYxTkZfgKTTzNT1azXoF8gctEXK4nXKMjuNgjOjFgeGvl44EY9Kx+9H6bh/2b+8+BUiSOaBkgBcRGd1fOHY97WFU5rEXMF9sjj64cLD3PGGg1ihFZVLSJJXPWYIn43Qj9fwRd0EJSLfCy5VySQvLs7BFjFk5Lm/GB99sQ7OoLICH5BP9CXa4oPzMASJhkdFREyDsBqx9po3B9e/7fK39pNskQN867NrO3rWw5Md8RKYLtieUdpG3znIiNdBVsoQnn4K/sym0n5gfzMz39ZXIS6AIDTurJljXuXSLIL5u6ZFILvAskuLEOXd0ElXKj5vkkbmdZTVDNWg4JZn2ZrW0xvylhy2jOqjBCSBo8++aslrtuGeGUjixeVTDs/ySUThk17ISmVJRcnw+tRLVX85vTC2l/56/+4c/vPj6TGEbb97f3H27u05/P4Rfn51+vPpxelOb+fk3du3pyfYAELYdno7Fx+OT07bEIVE2O1rtvcIedAKoXvTaIAssKBTWYQqHISa/evrwhePO/lYzuSxnMn2ypl8v+yAyLgPa2pwBK8FBzChruzLmEHxWoKjqtXs1vAhKg6ssAy5gRWn67uTS89WePQnD2xvc2nnqr13w7UIILTqatfML8p+bL5EwxxUWHdrOxV2Batf2eKrNBfdf96wu4FZV3KpfJ+mpfeOdt7q/sn0mxkjjdlWt6GM00BVrUWtMgjr7KqYnsowLIYiJ7CM6c/42jkN0QilPJcGfUqJLa8/fE+FbsgKvB2N06ZVutfVZFpDaLTcE8OK2t45YSXStjyrgdwhBrPATbqygM2mPVmFrje/7RCLfZ+rsPEk7qdMiGWuSJkdyoXYuiCy3kLlkI3Xx15O5K7dlXh2VrPi7BUGeZVYxUpWIWnMyPjaZLdOZz6EZ9Nd+E0sxeqW7jBLbGKYdAoiq2H8anHJr0WCSTbZuzZWK8lkw/D1KrvQOdWobz/Y/6MuUkBsxAry/1UxYIOgu8cLwyJbOijJoXpResoejVtTZ2WGrpUeOgFLlSS+GN1jLe6n+6BB/emC5xB+JkVN1o+grntMDBbkUkVfHbnbquT9ojXqwdBt827TujVtt2yYriE9biIDWSekukycyEs8h7dyU2Vv5lfulccXQYi1TNRLDLtn4kpoh0PoOKA0uyqyeR2FIMhCaYu7p3KU5+mHiwl+HhcyM6NUDv27GrHlrrBv4zWPArwtQzxQTZuoXq9dCflS27VgF0sRC/U2+HaCMOjnKQGEeAC9laaS7Ix9+5V8LK753RfXBDxlk+rvRBxVDHArVp4aUmxh0nRtlsbQleCzOqhC+i6g1/zhtGbSZla5iuo+qkaUZTt1kST1DqTl5c6vLBSVmCzgGn4RAZobIXFvwCABhf2zZTmnz23rPj3F06XHqMpJFpOKS3ylYY4PZ4KZNDKAJCUIicIkm2f/hv8FIeHLp53Pg3XaCMGnYloMT2Dl9SDfUWEE8NbMpMl6Z1oaxOl6HUZgJ18J1+NYQ+oFWXBoas9CJxFJP04iwVdtAO7w5DQexfbus0wf68Bl8rrc/fCs/G1vlxBtC3FfEa9keUzwhGAJS8t7BKvgsjDIm6i7RMv++a7Rsn/eZrTsp+CYziL3qYQblqKcl82o3WM677ag9xSZuwExVZXvvG+SeiSorRLUp0Ca+XEIWLY5CJnAyiNNmYkt6O0Oxna7fSVPbK99voD5o0QqlwwyP+l9XKmsG6tY2m0g30Vax91Jpsm/I4dqenO2GYq+2QpXMZzvep0/BRchZc2gk10NrgeMkNhIjilMZbaBXobp3U6oPJGFA1r8yP1vHaJkPbCt2+CI3Hm3IWubvvnNNxZW/05uzrYS6WYW8+ouuyQabfbtmj5txqiGlcz42ne5nnJ433JV1RA2Wdu0hVnmj0ipkiVvIy1MxuuU2fsxe7cWARgJdwfDwZBlCVgly7DNu67DBAnOZkd1hrikRrxLOS/rSkQEIrIzGgxlTAQNcQdHAhQA1hTofTAYsNcSbQV/ZIPBYOfFv7/07KgmL/69sxBIVFmoHJqJyee0A2+BKQq+Dv3lKkQR9y05g7Xn6rOsBhpdqV4xoLuUevblc/Es0AQp+kzD8VlsYY978jX35HdaGHtrcHF3C1XqbQKYl31TN25d6Lsw4sIylNli/kMIIgc+I6CrZhS0/MtlPL0P9JCpuw6Bi8rZDpXFTe+2gehcAv+XxQLEo4VIyDtWbylWRnK+9syjhGdcRm/bjcNfvuS4UmGt8nPbGQ9He/3hqD8cXQz3X4yHL4bDwWi8u7f/jx09h1ZDaarCWd5xWz3UNm6iTVptY0clfKtwJ/oOua/hro+GHUZZV1gWwuuP9rfZ2dG2OiOHC7dYh87VSmfgufUB9/v2QrRfSoehaju6nIoKOqjqWu6lLME73h2MdH3c8e7gKNsg9cY4e743GGVrrp4PB9kbu8NsFce7g/0v3Y+hlgpUKFQL8uzeZBsH0PrZtkCMxbYTNPtqcMbSsuVvvfKnu95vKn6pVXpPp5dB8bgSRhRl4TCR4ElvdbsH7xbsZgt121CUsYesnRvRiPBG/X0KHesk8P7hwdHe4XhvNt93hnvucHQkXGc23z06coa7zmi424fXNaiteesZGsTg1zi028nxVDabwY9lLD8HGOVQe0tiRGwE+cVqoN/Yu9UGW6gz/8grVPUE1eVdVR07wWLCHcim0BDSgPMw7m2Rb41WW5DqkYPtd7nX4W1k/50aHQ2739PwNiXieSHA5TqhLErftn2+oVQZRNxpvXWTalmrLd6vpXULHp+fhH0QtIe0KbTKxlx7RaLNk17HK8N6RjqXX6k9sB1qnrQRHO7Unamn3KkjqyB2px7N6xiiGNsxSM8Anq7N2oAgb/le043sBY6fui1ieMxhbKPKRnYX15TQyH/0cxkliAZfSfhynecRX6yELVf3ONAWuszjRSvAVCsFXG24tLyAwKtUQh8PsuYD9oZDmTscmoFznYmHcU9HE8xC9zYfhxZTYR3O9PKpj4qbRARx/uZukqctNkk132xk1EmsYs8wHJknyx77Vyqi254EGeuBu8wJw0tPFPKW9dbbE6NyKFUZen2OfjIG/zJ07TlJAZUNNNZN7pMxbIyZu1kLqB2o35WFbGCkHQb4xRKmW0NjNQttWGvjErX0JKXA6NEPC6bWPoWpCRdJwYAkB2cnRJbI3loYnqjBRha74uHRIXjb6q+1ZAh29qwWTZu4/EcT76aFSWCRt8DeCaaplOq/HWOvlHrLoXDr/SH7V8qDBDQ4BHSQ6s8TCBvIiWNPrcHdHcskSUnaMpCjrz2Qo6qBHH3dgdSZRWzXb3btymtOcnXj0uW6Wuzdbr7jgCE5m30jpJjkqtmNaPBXMzelaFSEWkAe3NB6VTFgaCZA+Z6hE8vNEv6NkhehqoDHlt5iyTIBk2Llcy9nnkLTo5b3tTX61wxEK36jEK1MeKsvIIYWc/yyy7oCc9K4vGU5X+uqi9U6udWbKHdYosFifT6q+SurKichu8UfZehQiURgLYqWh4oBGre5YbQt+C1/79tqbA4sW8O1i+EfuvySJ+IOgf5/OHSlLlakXFErWuUSAsI2kqbyG3j7uH2tYM6qDOfbKF22FcQj2tYHjVpZCNkAmC5DPSDPevOc7hl2SFasilMoMSRcbCZhz8sBrXLQ7FfA37ZB+2yljkM1aNA2SzvUfSUrbdAa1OiuyEEVyTN3BdypwdyyeViKh9BGst3qinwt1Kw/IMlVVc8oLdvXxLUqM72CS8SitOE7GNEuuRHONCv868VM+xK2orUZhQjzw/mIGrisHhhBrQG+gsKtmC6A9e1sOhmGu5rf7+xlIAD4DkZ2qgLepQWfA75usbL6OoyTB1/3OG9U/8ZFkAsW/sJyFxGbigG0klFgKqMXlK/ge445qAd5Kh/dSwnH2BL1pgUkY5ujbA9nKBVwRhx1lXrTYnRlTJ42g1HOLTOYbXuomb3SJAncOoNzIABUYJh62FlNzRTv+dKGViFawZZG/NoEShr0cPmUdV8/8VBL4THZ+8OI/e/xm5/bo1+BTQqm/l8tV7lNwuZxoJKpoD5lblGMxM12iZqtsbJ0pYZqFKXcoZ9IZWjSViX7Q2qpbeMm8qAJ21A70+T3pXSm3+J6Z+9WHmmKZAakHm+BTaw5wj6BV5DspGSjRqFXgjV7AQNyynUcs5mAZpFYhVeqKnIFZvE2bvHuUsRW5pz1+tUnXCAcWX86I5l4wpOEO0sI5wm7npENio7bA0FKZ1w9+FwcvgT91NWWJ7ry9mTOfT9ZRmG6aJEaWYEuqOgAH4OKNxMsweQEktykb16VnG4LMGi//TKvzM6/QRX5MnDDFfeC0SDBmCr6a4x/fa7GbJXoWOb60ezsi1ehrok48VYIVG8C5UvXAVoCdWWUWMDN4KQ+UdA2dDeNPnn3na2rCP7L8Wt2mtX4BinS7LtOznnizAcgzy54Iq757cBoB0g8GK1RVQhbpr6Vlh1+1qKsjaws43idfbc4lX8i+iVRDRCNvfxd4ajR2HrmshXpJvVFvxCx2hh63enWzJJbN7t1jVYUAdAdXVXDqfYKBNS2fdYIU/86M8aMFxr00lrRS3xhQeKmV7MSI5ZUz0cptasvpZTbcYdiEtYE3C9IASo+utVdshXfjNRk/iCQv3exSdwZFfj3aYHYBjaxahTHqZgEYaJDSltQpBUqU0+MoHwdjZyZBylUJi/8MJVAtO1udVG1SpDEYxYvwyhhibhJ4JL3jaCdhq+1KbhWtN0XQierYTyPdUUitPVA7IYhgwCmZ26ZKMjIQPyU9J9NQYrHMnrE1aUdB98X0Ocd8DG/NJets1Kzlm61U/3x6v0ert7yVbtJxGpJoM4y/dSIS0H/G93PlWkT5/gksyEUFDaIS0t9KjX+OoQgfgQOZej6pz5jKr0D+/rPLFSbvQqdODuQLoBowUfiQVb1UqW8y1E+i4WTRl5y++zX66Sf2XefPc0Bj1XqbjqRo1DrehHABWrMkCr9AIJhCCR57cVC5SvgtKfyj+kWHEFqlfpqfLa4eiMJxbo7ZPxKnCUw/2wi2xyeGkJ5eEXFoDih7pkz+Tme3siVzyJQzl5tY25ZVLdhLZkfOfsHo33Rn4vRfn/v0BH9mXAO+s7cGR3tHcxHM+Hs9Hb2Dw7Hh4KL/nB3n/f3do8O+jM+fN7fHzkHB+7B4ZAP93Y+V65N66wiew35M0WMqjL8NpZDBekbi3E1KsLmjHM/VE9Q71VfB4gV8J0lo1iG12yqmgG2XSIijukpKLqYqSAvZACDOopT88wCS8md0axPjnUAqG5X3trELiBr0KwB9iH1hfyMpN/yZ9SDqs9AJEe3T3nIgspfgp6aJtXpa7W6hPqS4Wk1f7rR/5TDbQHfC0bsx5Ky2xJSHpN2vikuU8+UEjfM7toivNM2xL6EBy6PHsHB7p0I7yXNqyJnv+yAicvwPuBx0j4YF4LV5M0RgwFKZtWjKzIXj7cNh0ytAVLbgWDGfXg1d0fV4gS1/W5/vAkdWCbaxhNXtKXbJp3N75T+Vb6/TyBXZpFqR+6K36i6PvvDdl+maXcJgULVrlZmqBwvyBvdhwm9TMi0U6uLdw6XpBTtLtGPlMlN4Y+GSAwK60AenAH1CmYemFiy/LTz+Z9DcI3l3qKe4K3jNFmGkfcbhePSy59xkWT4314xMLG0OLQidST0118uDAkO/mqW05KIQ1IX5mO0QZXp9vp2OHCHwGCIg6TXpE8ZBupBMRlZSwc+nAI/BKm5tojR7sFw2I7D1fvA+ZWIoIiNxQMeQ96cLHNGkSA4Cwv+mmaOcz/kOSzU0dHh88HwoM1IC1dRCYTFAFexSRzViXFouS8HSH88e1XPQ+aj53viaMj7cz4X/b2Dvd3+bDZz+nt8KNy9uXO4N9rPs5Ldg0aKlhcv5hMEZrvtujuAMHm0CPs84P4tEBhkOGVuUSdcrVpJVe20nfyXNtJ4qrvQasgdNaCuCtDGgmzjuve/21p77Tayfb29FrtaBlK+v5p73Uvu3QcRkPXhgR0+Q7Yp+t+KWeeVbyif0ueHeZIzP7HF9Jk9q7tThuNdMRruz/eEI+aH3D1y+O6IH+4+H7tDZ3d/t3CfjG03W8Vmbegi0o46ArUyhUrLEui3H2nYAo30YGgaEQ4WhLSmdpSupu+3DKwx7u3cS5bOtn8pvdIhFxyxPIXLCA+rBIzyVW4k28bfw1Fu2Ke7bU3b1tRi0uJ4mpuUncgOG3VP5xMLq2L1lnsA87j3fSorm5mSiXMiV9pxtAjZ+YpHiQbrl5Gp9WV8d42ApOFD3F2h1buS+5wCe0RMyV9CwxVA8pds1b5On/HJOgkm+yh8EfOEeRyHjse119O8vup1523JOUUCu0chR30qdGEV3IktmD6/RmAI0nUl9R7BtQ4GCqZ6sq2U1ZzctHsVpf2UCVbVHsbDgwCY4dxyupqxuLDuWpfzr/AUqKGlWlIqStSf587NTM04LG2Hpdu0wxu3TIgMKQWSaM0VjWYW+t7yKqNXhh71stUqrroxsQbiLgbFChujlt3ZKLyJmPOzaRiMQdO6LmwtZdtStgMzVRv+COfzSht0lEyO35+dAjdvJk4Vhlt9WY1Gw+F+PmS2eqQ8SiDvZqBBxwZegGFlMtuBxvam1NXmoyvF81YPDvi/F7CZSPgLidnKZpHgl0APBKgSD7KBnqBW8bdUBoAWb2YouCux5GR8G2hGiF+L9dBjFi8h4q6RZ8093w4e+JoeQGIb4LHcMgKcYHyxiASAi2BqIvCizYOVomRCnylfLZDtWOH8TIB05dmSM4YLJYIlBJhHx09j70o8HbAPr092d3ePGN0a8i72VgIvaROC7wnkubPpeDje649G/eH+xRBckS+Gw39Mn7a+h0y3ZrkjmOMiCtP1S8uO5o+tE/rpKqC0UtgAbKZWm81uB+wDjTyWiIHUINZqIuUhMkgIjkVStz+l8HHDN4ZidASvc6h9LR3W2klUNwN4KRu/AodGHzWRTHEG2GvF+NX28ATy/JL4Iky4P+2x6ew2EfKvp5tOMtcpTjAJm9mqW02AGFilCFBNso4S70JfByZ9FW42PEI4nYzw1Pb19MH/LBnOK57wcxmQe0LYDK8BTCFYxBfh+m0FJ/ogkjQKpFgXrtlbjPhbqKC3OaZRYGdsLnvbIk8asKns9eJ2Ldh/qm9NmUaRciH2IQTochC+qRDvyfH5S6Str8e4zjszrbtQxSjPdSwC+RuCzzQ0y9y+JSGLcGetqqQehhckB3v5C9HMdgERYS6iQGWE3vYl3KfvrTzCRLcctdPWh+vuC3XY8vgEDQdGnZTzdLXi0W3FYcGfCRFdXqJCnwoWU9Ntno4/BnU/FBpqQz8XECKBILSNJKQJJ9FtHmnnkXaADj5sYPLcdLO1slfa7rvangrq2pcOtuwWCwT95I2f9XbMasulHJTNhNl6u6yW3zciAvQblFawLsarU9uplyJ18+GHJEs/tcMeHvvX/DZm4J/JkCYtde40hZc9OX5oUwtOCHqeBtyfpc6loFolCHoThdfxgJ1ywJ/1s+QIsDhPdbjYlK39NGZTLdzBYkwBtzCNxJSt+FpaxKeYaiafx5zHU3YpbuNcNllnEqTd+TtYT+I8kWPFykSW2cFP77wYQVQkfBqqSUKQG43SeEM/388nFFbojGWTOa6zoiw8e9/mvN/3Ea/PXm57dtH518XtoFZW3mKWCFtixplhROLA4mXRfAorKjFW6f/Qu/wglFrSCiXPaf4NirNU5EFllpo8/nO9PnPt5o3sqlI2AAyZr5IbZJ5TGA0Y2a3I2hi/YFPxL/hUQP/xAvwjTCb0r0UC/+sn9G9Bf4jpoDGxaUfZgS0ch44qrBumUDK+AP4D5RdAR3TFWkAcaRgYK10n7WShD0UrQonsjJ+UsmT8JKM+iwHIH893ejsnxzu9nb+8LGeBSDCEcL2jJ6wIFEVBqXC0OWimRdHsIruIHg2Nj4bGR0Pjo6Gx0dDYq5UlgaEwkvRY7P1GwUtIWeZRhgyYJAp9mugi4kHqcxCQ1YTJAAU5TtAfij1NF8MyTMsAge3MoLkp5VgsWD8fOeMjZ3zkjI+csQVnbGVsV3T0tezsWMmgmeg1ySAVxGFkshggHWgs0AJBxREsCgn20XgIbN77HBVsysUxPkHOVrHxnApv2Z21qsqmTwuJ2gP2k7gFFgVIV1iYNjtSYGPAcfRntzlmMWBSASFNQyka+hzRzOOepIa4x6T6EFfA3hh13PJL9AISZXuaRbwAVaIS+dWIz5A6w6OV0FiJr2oOzH+2OQ4ljSIRJHLTS/YI5UoqMnCZ96cEKGSNdxET6gxhBcLcOxwfjVDRXUfiygvTuOvgYWmvuA+Hbh0JRyDLyebRoxcjOGAwXB55cRjcn6GvOL/RcHe3bJrLbVRx7mrzH830RsNvZ5K3md83N59j2Qz9nIq3IIVmqlBjnB0pL5WG9Is29nNHWdul/XxCDabyfkM7ep430LHL3Waut6K66/doOW++ycg4LifQ1Txu1eZAkfsDnLntbNdXOYgzz/f7cTqL+5BYwx3K24BfIcJ16QEUbgv8y6qycnAqZWcMlkEWQ6s/hjAcsyIHX8Gg7J3TM0u4vxfnPmx8Uef+6y+Oh4OjI/0hKK2w5hZJ3fheJFYKGDZka35b2z0EqNLF5FT0qp4qfapi5Ja1+nj+yoLE3rAJxuP63uta0plKAITVn3jBVeg5whqcjfUK5ItMvmjEaJdHIDGNhKu7TSOL5PLxw8/K8UOvq86tPdpG9lJOTZI5TbFuZLmKfQdH/Gi+u3c0Pth9/vxwfHh0sLs/djkX49GReI7h903LYpBty4UJHaQVheRtKeJo0o+4wlwK2WYjFRvAgXYhamM0fjEevdg/Guzu7R9IC6QjvHXSZnby1abZ1dXEomftTojuqpEwZa8tVx+u6rQCjoSetR4f/dB4VOG1BvfgEjR8Cltvxc0nTugD5mE7bLJWGXn5726Sk1fdQ/O1WpxB++9U3Xc2xNivmSGtZk1JX52Wzmy4ca6ffZWcCJJztp/P+VWppzLTJJh70Uq4kxn3eeCIiQNfqLiu1cuMloTJNmCfw2YdbYn7lMRSLSOcFOSD/GfbSQj8FnZOii0WbwpHO5sSa9Ig8XzjWzEkzHg5X0orK+khTEz43sKzpouaZ0eSGWaKygZknXWEd6XH0ZzvCuIDh7k6YWTh+uqTXK0ivcjEjRcb5g85mlafCyNv4YEYJAXIGtJRr6qPS3lyQ8KB7KchAXlB84kTBnG6slWKe09vAF6WpKGKkagubBJtJiyE6cwXeRJGU1P4K5ZWmrhi7QuEXHStWMXv1ZsMa/3qTFRFbApcmPrZUHQZ7/WHz0sBp2gjn9g9a78UxzETTrgSZFffeAzloFcag83FUhpB6dh1+PZ++dtfHgjWh/0GMjVDE/7jUZ6h7xQ150chpiUJbRdI5OuQz+Zk8RAZwH3Zl/JoDi2BKQuDc12owzMx6iO3Lsop21r8MvSA+V4g2MiqQsq2Ngxas/HY2tjxEpug6SW39teVYbgcXY4PsFRTpc5sC7eFnxENGSoQWaXYL72d37y1vVDU+zBOuA/tf/PWVR+3qMS2rXrAPKB+pHKWYC2ieduc76qIqn6ZyZcVxvVd6p7k51Aajyx5+wD50VcxSW/EjPKYnb9nyehRwKnZ+G2C5H6VTX+YfOABIeS228XWQISbXE+/C3zcGgp4iCLEHxAct7CDV9zDWfUjMKSsfd6mfCkPlFo1a4TCyn8v37Rg9+3QjWpl+GH928mKB3zRXBQg35elPUafgxbTeWDy137WvBWIWb4TA+4PWsfZinXtKNcUiteIBXduW9ScyfeTNTMKDXdfFGyJplLP2bALampRbmYcDK+zTB5pUD19kC5vJ2tuc44eSymWXmLwEkvCax5RBQgGH2qMetAjqnOcypg9NuMu9lrwpJYN8bbIZSfxroThcq9RdMI0wSpNKIfLtzFsK/JmhA2XhHow21F8Kv2MGGifcJ9WqVKrCFHXNcaN60Svt4hsqSGVB639tm+fPxoP8pqStNPfICarC6GWg646tKY2W7nSChFN7TsphCh15fPZC33FcPN3USECp33PZkMjAKR9B9gCjGJhsOHVgS2t8JvYd0/RTH7583PWpGHsshxTJdE+hp6UOVLhOD8aM2x0s47CuecL055eRL/DB2wWugTK5ESC0jLDiGGdJfg314Y32WFzSmilYf48iYRItJG0yj5vSiej8S57w72AUdt6272t/zF7wtdJj8Wpl4geE4kzaACNOF4nbLQj1xVWEiI7LEGU7yMPEmGyiEF4TX28IQCSmvy3Wb4YPpjewvdAl5ooXaqwZ2D5h0dsJnBP0shZcgjYj7zFMmF8DoAWcqcAqDdd230SfJ04Sz5xltz3RbAQk1+vLSRyQq8x/Rr76y8XzIvjFMIPqEhYGMxCHrnWDAH40nyCIIsJ0WIW/lT4UlaL/UK9bgNqb+OFUVlr1YRr2/XgNgmvA3LYrNY8sDps8AElGW7yEVWg8Cxwaj1DZ+fv2O7o4KA/YtxfL3l/zJxaZ1E+agk1UC+Kk4kdr+U1PNt8Fn8Nl7hOy4kio+p9XSoSqt1LLO1mH+vP/C5DfRVKlVHMBd7CfuhwWzTVe/UGozeQIarQVsjUEkjsT16evGd7zxs4iAj6tAlUx45Ht5MGXnKuXrRzEwL+PIElUGpXg59W9VdkMU0uxUgsIAdok7U+OUbZjN9MIEDHHqMLIDagnPIbdvaK/JeuLUQJOhK+WC+lvGaB5XISho9lKmr92P7vUX9/f1/93z4FElkY3t+PL5oCmSv9qv84e49OWXKvNp/TI0jEsxojJK08aAWzScEirV6RSfUqKcndECo2lhba3PkUF1r/9pCu0MidYIjZ7WQVBsnSaGNDWx8X2twKHtU3GQ8xtQYbSftE7bD2xvn/b96SXS++mmMuX8rfX7X9GzBcKGPqogpbS6mwVFpwxRVkL0Dqev0AY/wHvdjbuY68ROQ6gmDC7Y8YOg4SEa0jLxbl66F6uL+Gy8ANxX8v4FVk63bfttH7miTVbfaeFy+aZYWt2xK8eLLmURLkDkUlhF5BxGgUGAJxQyZHHYS7zY1f81uoajHZlKcV2rflbapZJ56gG3U/66rpRmRntO9Ka6odpOZf84Yhq5dsJ1911I12VKsgbLxI+MwZjXdrv60FthoGhq8YbQwRpZau9valP2Xb3KHFoI+D23M17oLM2CwM5GTDhikePD88OtKR4xS41mJ1RqORISVWv/iXl/orBemwcekfZvzWLPUv60OCf0+CquN7eAqFE4mk4/cKbXG3s+XaOH++LkD5gdJUKSSgYA4JXM/hCdQOlDO4DVPm8IDpRpTODOXqfW7GMFfOwhVzjhQgA1yawwMdUAz8SSR43MYGX5U2S90w6qYxZxlma/Ewa5Qk2Z2PfI25IuGeb7EN4DbBByd23TUbmOxJDg/ero1gLYYNI42vvCSxZVJlGTq5NSAKlK1apusUDlN1krLxUv1il/Xw3Ia3j0t/cHvWPPMHbIfoFFxknO+HyUfNG8dmZPcQCA4f63DI3BGR+rkRd11gqPZSf0rLqhnOwyajDlKC/aSeJ5G3FswpbcE8Qhx+l0npXaVIc3s2zkO94Uty1N1Fn/yq27zAFTaFqvKTx0y/IitOYrmj3Alpdn9qycJGBvKhkengLQJ7ynCWIGyXTlwvXvv8tsJvcsyW6YoHfbCLQTN2JaIYTfsyD17PFNrXW6rfQ+7zh9SnQ3HpBRWXbSLN+4VVHLBPSFKfdnA9XS+GDRMSp1Ii7mJslqRIFgbPwvmcJeFi4ZPUFwk2/E/4DcC+Rv8ZBk977NNOrDtFdQTn+a+UB4kHmwFvpECZ8h2sqilc7dXICKwp6W2VBWDTf3vyR+weyd2+C1j/Gp1XxVWnlan97povxCTCZbdTgI6ELH80DTwAHwTvleLz1d9uTXIV58ZI3bHPsx2dj4e2r1qkk/w5trBBVRwZCaIwlth68W0nWLHIYWrGbrVrVsIsFeCVWMIb8PgaIZYaSnG3UojKc6k+BWng/Ss1NmNQTerqpGG5eGCv5kNXkC7oThxguXNSDCsfTJw0TsKVteKvReCuCKqzzmgVBiIBly2eNS9g10vPWeKho/hYUltQ8YiZ5NZ2BScPObLRXlAk8GQtIi90J6KKRRvI0yp4mJogY+V+HGaIEmAEz9LuYubaGVZLS/guWcIJTGELU0QY9zodU8VGKx82TRObCXfA3vBbWWPFC7zE436uY+bNSfz1KGYbbdCyj40XYb8/uusidBIufIhlSDaTLqojQ78WSF6OQ4339zdarpSKglasl3yqTgQGVlXcCuWFG7UZgD29pMm8pRUvID/ZjmVd1du3pEGru4Erl7SSH+KP4TUL54k8WnmjCmAfBeK6WKy2fufRY+7fGtz+WohL/CF79K8UzmqE/wZ3uX9bVbm9YiI1gUkbzqhMgjFg1voijvuJiCIOjEBWuwf5w/PR2Yau9RSMYvexKL2dIEz6WDLYwWVptUp1csdZ9qxuwMPxrhgN9+d7whHzQ+4eOXx3xA93n4/dobO7v7sNKQPKX3Hft1r4+HrN5HNmRxlyAf4emWCHLxZTptpYoyFyUV45/m1ml3Y7GKY3Pri5vKwym6PHpvioiyRGKp60BxceDxpO7TwSYqNr666Ywdp2pJJQ8pDE+Y9VC6FuCCBtTNYlqwngM4LmCtfQ7ibT7wY9ijchGG2kMW6r4KNthqv8yB4WiHw03LU03K1Esgyxlo5M1LCj6dKiVgRIGlYU+WF6v5oWHqhBUNEYLVqLiMGqpAKlIjdlFdRmDlg7saP/zHiQ+b/tu/iSB5cakzGxwtCqjuyuHeygEhZINqyIHZdt8Wl1czuPxLa6hA682J9hdkGexO3OKuwXkBYgkC2LV7R8Qb5UGbmLQY/xkq/XE/jvJOEW1M0THi/Z8XrN4BW7QaQyS0Btt9MZs0m3rFngSh3tF1O891QyMOls+RW2CArlkMYCCik+xFI9kj3x1IX6IwBkXaGJWYIdITiVgmTs8JMnHAE/1VsIQmnruhSPWZeQoFZ1rhMTWgORv88z33oI8tKgMLJrDrUr7IkH8Ii53gLgJJXZBBagTcw5huBWfbN+HXxetwyB51Qd4GMGD/UJRqW2irCyDnU8oeRqFUkKp5SSUAJnyr5RmXBuiwa072NDFpU9vK98iaoRyZewqEm7E1AK37OPEx/TIoeXIvB+y7ik1Z1Q/lBFKoaiAXzcEf+8IInYr55cMPeH01dnF5OT4w+vDK0z/+v74/99f/wz1vk9//H4/fud3s756fvjyavTl2cXO72dn8/e/rTT2zk++XHy6uzD6cmFfPK5LllCzbITBF1eZnhEMS1/pyBVPWbGtiGfh6jW3IUkHqCy4PPA5r5v7YjvgoFAjTaCqqnyiH3p7YCTaLIBdI3RzsYRYWFy+cIN+q7+XMcoUzmbkut1O4AVhpW+w06pVt8Yb0lDXzUnrdwV/KiKAB4vwqp1y3DJHu/CHN1Uh45Q1IjUdnKOEawTruoLQH/C7YHj++M5c0Pf55Ep+drjO7rbTtser7Kkjv6zDjETG1u3awAbsLaiBm1AF43yCVQGoNRWUm2sg1b4Rvbxiq9VBiFY4iW6ersm4ZpCnquR9mosJNnQrV5QMMCuWAYc0cq5su1JVflczl6pE6Rn0Yr4LONTWpl8w/cSQbRB/zuBupg7AB4Se4HkBDr1E6NnMEsynsj2+m/Zg/rTaK9/Mzr6TDmXCPbGnRrjFs/vW9aFNCU+CSMWiGv/lnE3XGOFXxGtmOr46TfZxnU68z2nxnM0T30/F8nXcltfylVlwI3u4VDFTlhlDMBHxLMLx4lYBNQKrx88IlPdw5hFVYkfX+IMwhs1g2YfsOx8zFBgwAY4+A5ZDxU50yaCb9s5ZlMri2f6ZpjEHmaZ/y5z5HJKRQkkycnH2hJFrvilYOm6sMkDc8OqS8GX8XXzu96pIFhGYTJyr1VNsCq+n66hoBSPc/0ic2GXosG7fnF6/OZ88vrD6WkjS/oxH9ttPOzIn0zcJcFXMXsNt8QD9SkWBOwmqq0BDCXhFdaS+rQVpo9FBB6X2hCxLxS9WkWF4PZZCLSjewH82wvQsK74oPx44ydENLF/5m1pHmvAB5O1zFp0Px5qnNXaBVPda0RonFSYJhBUwmLBIwiN5RHHIPyGTw6HFlZaaYIoO0HUrZANxmA/hSDwwhG5Q/C31UhVPY+aaDsUONRjBjoXRhZDmFFe+8oCeZpP+h0i7rprRG30s3N7amaznrY/PBC7o8N9ceQcHo7d0fN9DvFms+HwaNc9mo+3EXXWHNCOrL05dwb4qRL+jFEdbqQL53Gs6/IwOtCKBX+6y1hqkd87np5Mka783G951IcK5l4F1tG85JYDa/fTqcLFWsQuR5F6DUfyPUcAWXUeLyKPw835HmDRIFcLw0XlS8fX3IOgCel/BHcc5f7iS6+5R/84xZqH7oan1sQS2Fo1vf7V2LKdhRear+s7W5ntKRJd+8q1L/eqsxI27pd62NymfSdbtt1svYHbQnosejs521g3o7rmBPoEdpgIYctYTvNmiCV/cPL7TrMB2ga+Px6D4jGojiHJRSE3R5A4Sx4txDZqQeY9pLUprcUs06Y8nU0GA2U7Jgpt9WEHC9SPtLnsBy2GDXr2Xgp7PEzjQxqL6LHKcsdyuo8e2Tb08xB5zjZro1nsvQ+PP5QruG6e8/D3UsHZjbIeKrrpUvU466J7LL3RdsNKyFkPcauayBYIyLKckb0krZrVw6oMb80Gtt6s2vJvVuDzY0ZuJAaPGVENZbIv+RUgofs+y0gIUvqCMGGcXu8WbXC3qnPdA52qApxg6L8jtrjZVZkpqg+I9WFdSATIIXmvvt5rfiofIG03Rns9Z3M0buGULFUkGjfdUjvAC2KGLyj0PelBm4Hic728NT098vN3EXoLK6FK0+Yczqp67Wh0mKteexYgP9KjyXwoL9h7X4CnUQRxGgmAe2Bqs4zXMDOZIJYEoXw4YRQJB9KUKYsU0wplQdwzmtOoQPYVa2hgnIDTLEywICCfgd+HlrC0XVtcvJLwmB2zivGaY4JkCT/kLnvC/Wt+GxP3DAMmifKpjcbay6s2UIfKY9kq5mV7JXgLS+qEcTLhgTvBnyrSy+DqAXbL4G0kI3ybRcIJI1cCpSmErXUUuqmTKMcmZ/FaOADJw8hcIIFUeoz7CAuVZRK99oJ365i9fnfy8ZxdjQa7umkRD6/i3L9EZ8dJaKt4daw+j65bSPckkpjx2IuNii9esOjRkYm9K7Q20NlyUwcqLeGuwgoAkhlILrDHUK9I3Cggs4Q8MVHi/aYRRtI1ZgzLMcTsSRhQ5jbVXQE7nBcsnjZ5ZkokKFNpjkmfPrPlyFEAguFjkwYUw/uv0lWf6LxVvng6YO8IlZVAgdQjL0a5AsLEdLiBdosvojBd4woSohCerVB2A2tMdLMSHLiWC+5NFfvFfHEl/B6DlEX6ouqMzW7V11+Qv4V6QXMjxAJBRzHDNL3rQBElUlUQtquD2ohlUVrqt1bf4CsCesoFi5XX+e4r22Yp62f85pbJmRhzO2kOnMH15+osASeTHkYvYE+gdNXeeNRUIolCTKto+T2yh1MbiNXpjTqWBpSVRvS7dXzpj3Mynu/FOV61EZzCeL8/PAA4hSFgN0n4pvrhn9sBqs40XyGgqa86hf3GKZzgrp7wRCxCm9L2o7dYijjpI30xxwdkP8WdkVMquqBoT1lIKuAJiCjhnC3Da+YlbAERfkQ2A3aicVPCwL9ln3Y+StRGDy7J9TqMKlAwDHpCoSDzH3zUwIxyQjDQtrd0FF6zyJRApcSEMfAhQ90rYqsQIF8kM5e2UTwDHLOuvTCNC+Bj1imonEv9CXBiVGzLqzoYrnPhz/uSZkAjTldYnlDZyrGD/4ihZOA6jAXyELSm1y/sL2F0CVLkOdRPhtRnWTYS9Roa1etqT1G2vkvtM9IUgqgocdX2918CAXUnAmpXJAX5a0YQXVkMXtSAxRFdcV/VPqS4HHhMpxNBW8IgTlcborbIMzo2zmhhxN24ylcd9agwatnl3wiQ1UIdb9TFReOQoStSaMyIVp0e9kHMwY4OAaPXWtakkZP3cSbmcCgVBGMS8SDWGkp9cspofwhxZ9mwPwaeZZ3hV1hceeca4KrUSsHP3rInYrAYAATtX15+2oH/qoNDf12dvP/Y/zFMo/jTTsNdmTtx8n6vEnHhV9AwnNRH89Pslq1SP/HWPpQWZVlzmMh7dKYBI6ApRKQboQQrA3fV5tVLpYPn+zaeVf5YRczSIhLC7afrMCgC13KldsjxqPVHATtDIlBaDVBF5DkF6T0QizChF7XIjoBXksX3SvI7BC0ijn/WoGEFgHqGtlU4nc+Br18J+4ZdZJoCEnOc5Dm2LOkKPm7cwZIm0jPnpPYyc4kzYJzybo6EL644zHcdCXTpqfqxldqIkkSu8Kxlw+qspfwYxsl7qvcY2QXnt4bALOgMUYFIpVClUIWTVsEL5hGPkyh1SK6IIKgtgaPeNtwZDtMZXdpnUM+2/aCkAcGb5aqEInyJAhamyOB6rlo1KHC6bnS2oeFXONW5z9iiOhcLUldkdc+oj5Hs8RL4/HYOt7gxVfPg9u6HtLAuFoN+6KdECZwtPNBP5SYjsggSoCrF3MuLvsbcWlxA1WOz30fqSPWlmUS46mpCIBBc8DnZOUW08gIggmwXgAuShAa/g4iGIdGyT2npWBVu6Tw/Unct4jMz37sUbOaHzmW7bAp9tVnm/QFL0VrtGWrSCla8iG2IqWchnZKFCBcRXy89ByyhXILJc71/EBBbWYfWHOvp6ccP1eOsZx/3MyAeQy4kO03BAmYb2jl12ZnvyhQdV+TZWRZPPzcIvgtzO09nNXaqj4QRbmym3uAkhIOnrEGYIkaDGrDXUBtZf6WXQ9fKxaZhmQBpHjl71RDWdDRzn++P3f6Rww/7e6OR258dDvf6M7G3x5/vHw73n8/zE6pZ3HubhWvYmhptPeeF2IsLvrCl4fFFMUUis0BN/wJjf3k7hWSmuGDDyh4qK5aiYvbGi4HTYyv0R0h7IAksl+K2j5pfwhf02LTpqZoQU6Dp6YAdg5WeVPVsqNConAOoTcR6Hf69kwi+gnRbUIqcpfSPW/LMzAiGot/33zknWRmpDa3zN5OX8t56g9eWjeANYPwSOqso3ntMKkWGMdHhCffDxcD8DRKkA4ge/wFsGD6Hg0vm9PPL9KyBpVyTtg9xg6jtq6pXqHsUZ2SneMRZtdhAC7NpP+Y3cHXdwUhxM3lP7ghl1Koet/JbOPJNUw6fCT8MFpB/mql2r8AIBjRDOp0xo3eBAL2u5SSJC6jx1c9VfzM3t9d85fm33WlMzXiO7e9OYjSTlmRmmUHz3siRNuzMhzFtiaSMznvxtpGj/mLO4R9hIKoW37LqxkgwNOMJ/q/F44K/fxt3C3zavmZ39KNY5BRawG78pLCGd1y4Vt6UDVYjjyRdmHjBh2uT1mxKqkWZttkIy5ZO66VUMvmXzbo283PBUFbhWq7L/8vFeBgrG4k4TCNHdMoJ7IpEbx+uDruoG2uAXnwKdgBpzAwkaYHiYo0X03j7JPBRlwCUQV8phOGD7LKgC6ByxLRXM3uHthC0PC2qfiv2lSIFIPyjpsRCboOzYIcsAkM6KxDtMpdEEszD5pXsGOHj5RjAvUb1lPhbi1AaMGPkw2lUI8K5kdEj31MkjXTBt9osaUFs64Ez/OGyZX2IjI7GKdRXtucz5F7Tl3I5SqC0wvk5qcwFdNlOeOAsw2gCJtQ44au1/SbL0Xne50sdMN3BZq4YwPwvuWJE4HYaGPi9snHomxVNK2jLzi/hD8qQTg48XUAq1+cSdDkhAlWzdlNf025/NIZiUuPdF/tHL/aP/lEHx1Eve7VHxNp9vXvyau/kbwdvn7/+n3fPz346ePv31399+e5/j2V0cpR0WmBy0m1/qwtcHDOHi6PrNRFuOd6+2K86zcUT9/krRcTdb6QqXW4UadF0q5H9Wuu2uSCNT8Gn4ALMOMSEATk8ght+dKSk0fEIqkWkq0BpHxDwtuLRZQyWjxUos5ATBSHe8p/6fYwlImlfe7HSmHxXgM/ue46XUEyjPo9UixFiSYLLILwOeiwOlY8iirGguuvFYAtOvXgJ1TPpPaifCXfQpx3TrPNpB2f4E7zBFnzNRi/YtKDKTtmTbGKxDKHYHYwG+/tPlXh+KxKGUe1gsZYhqm4o6CFfrwWPSC/VK2kK4v8Rm1o7qKpZY+gZA+M5HLhLsQx9tBqvYQpgKedr1HZwckX9Ekx1VvWclhHXjhwssCEwGaV1AcuJhH8L9nMic0DfW3r0sTTQ3yfj1YCdZaiK3HXRdeAIZYSlVuLGi5O4sODjF2xajJiqXPG9Oyx4j82Ew9NYYDRdmizDyEs4XQQkq6MjLJHDZEno8tsBeyUi74pySUGjdLgvwDzDeOQly5VIPIe5kTeX6Dq22zBmWGLglo2P+rujzL+p42qkEvQfcbGcIVxhrpaBybxYKnqIm+ihmHEdhdKDN+POJeVu0DmOB4VVRvVqSrKJiqSmZaC1hGVLPPTTUtQKfkZ2hlzglnFrXUIdsZj32sFc0iABXPygsPw4TUh98QzzPJLJexGxMiXsASUMRj2DdCUiFzAUU1umtk/Uic7MM9Mem56kK3JCFhxnuWf5WAV4RGYS9S/sDFdsatqmz9zpU3Ydpr7LArgDAepRLlrApjeTKTC8uXczYBdLcYvjvhRr8HXR78Jl6FGBE3wVei6sdST4JdLWkgcLolYkVYImkwzwbsHFBviKDgbTkCvSac7e89u/hLBXMmLS9ST9zG5z1v9YFg0T/0q5H7P8SjZ6bVsFBRfEI+V2VdG/mXktGy0Y2HLhwV8loLbOoIz3nYqofZu77PBVR5JRArwVDAv+VaNXjf6lQ2OrwzyrQ2XPpTM2zod2qgBasAF0ipRtHVqqJKxkWRFeqkKpLvCI4IVgu0Nw6iICXvADiwX5AS/VxaPTZZSXO7uZNw0fG5fDxxoCUfMGjizA1IhRYcckIGUBpfpAisBdh54M/XGWdEFEElZShZahNPeV407llRIbUaRol5ccpbiPx0buSuXk9OVOEzTCWa2lSjYJPi2Vm7eGn3b04hQMsl7ATqqOZGNQZ/5smGWQczGGd6DfTYI2K8/r1kbVOSgzz7t0OKMOcJRBpMa1Vh7lxuGVx3lOr3T2NB91SaEtsb5gM+fQE7rZ8aMUe9lHABkZdPmXl/1YOGHgkkMIEmdngonVOjGsFlTOO0YRGZUo6RRT8RnNznb91TYRm/n1xgDAgtigREQvsF4nbcSBCpmscTSqmTmu4mWy0bjGg3FuXI0BWPmBGUGNxCRQhAUZ2ElSlBjjFEU40uOyiCeLFd0Y1R5S6fDuUZtK0gOjVxBmqV/hauUlWCNqCzJec0jlhRnNhUu0DFE/W4qaEMoctUdpAOpT2yCfHjsLnEHL4MqLQsSRB++q0WHrkgTdeRjV4ZQX6rjxhGUhigi9qoLjZDy5GWJY2NlsR80w3DtvbdfjIIPwNLe2c5B64tcsujbgUCMx4Y4VxomA7zdgj4rxvh6wjwGGBJpcX4c2BeJKRMR9fwAtfM59P0b1G07tpx287D/tGPZkSZNy7bWVK83HVtooQ2W5lbTZRl9cwS5kMyNTn63DBYwQg8avb/gZLUPttI0CzLEKyct0SGu7b9uOX16x/2ZGeovEuL2Qja2HQ9w9GOL7iEkoGSGsCn/+QFSGI5AmVRGK0Cr4waJCl3V5i4hcEFrL3DnPMmukGuM6KgmGRZmjZ1qbqiW4Bh/GNnzzVu9GC2vZ78tB/xCxLnR9jMYtvOtQcz6zWgC/B+MGvBrnMArh6YRiV5shh155K4oO+0ncmkBfDVVJYPg1AA7KwVU22xaDa21gVfYbpVBJohhzXFmEuBBTWzfHjqR0NZ5ImWui4nBxYXJxovfzPZLxyv5uvLrk9ZQfRnkheoXN70xdcQ3bPq/n1LLHPsCHW3azE8/+ylz3q7LM7VFOFYcosMBvyMPmnp+IaDKzKJForGb0AqSg0D+Ap7jefC7QUXrpBS5FGzjhauZpsJ7jt69Qz+UKbGWVxuCuTpwlBBRHt7JfHRqUhOSDocyOdr42M1DVcpV8EMCPnERXH0lCsKHDzQIIB9NytOuURogeYSU8x5ZMCzemUHI2rcyImD4dsL9T9glOfabC7OtuVSMGdTQ+tLDVDBCsJhejt7NMkvWE0ttFFAl3MrtNRAyROyt+IzG8oNwijUj+oPMJcxkDLde1yEpk1D2agkO5jDlV2YPIBusCsY8fz17VCh/auJ2mGMJUt0y789HsyBmJPlgv+nvwP4fwP0Pj/+UXZlSxMPaEqNJizG6zEGXIWMoODiZaZidHJTtZDg7lm8vkJQl4ABQpz0y51bsPAwbXSXEpMegf0zRi0Y/h2gEFYouC3dV4kvCF5CIYcdywjpUZVQhcVsmmMBzfyqWOmSvmXoA9ktU/CVm89j21JXjmB+zi+C8U1I9bxAtLovesD2ljUIuLvTp7c/r2/Ozd21wzkpBddYfDq+z/+3/+X3W3Tjy3hzr2xKNojwjTP3ETQBJzQyeVcTVAADItw4ATMPuliDDM5M4CagF/jUzZjlir+BydEYdJ8GR8i8EAkK8qVsFLfxI2PKf69SFfysXxX56ysDhufKSX72mPIa+E1LqeXI+esV4IfkorVm+YoKb5UP3x/gECE2q2CQcVeyjOB9MPdepWQxKVGrtZfuX4LyC86SefG0g5f0vjmHq40tV3cUmubVQkSBuolOXrg/gzsbV5SPOiWP2tBmRwGxusLmZ7qpMBZAhss3S27+VE1JMUJpY2ku7fK2qWGWm3SUhCir49bbcBMoWC3MGOA+nLpOFpWYfnUmzbyifD8V79zatyaEtSh4Ej2v2GyFMM7JNetRqi8VZCVjCxbGvOi5qE7F+piG57zBuIATkXTAyhJURABhC0BxET+NhLDJS7AZu+jsLVlAo8KSAKjGK7CKfkAZG/6lf1U7VjAGglqzQv0AjyA/2EkApA0ap6HlwLdHN4mHqEKsCA/QLDmoXJ0symlnUfIcDNFXOuJLdybIGMgUQfNUuWUZguljJms/HgwIQseqnZPw0B45sOD4ajpwNMx0VYWm+uVykWVp/NhmBTF2F5UKdZkEfDkPSGwqDYG7lJhHRhbGEQEugbBvTujiAwNZZv2R1QLSezW4zh30SAIgscknZ5KUhCZU7kJSLyuERfIXkDmwzYqVTahI8RrKqq7Q9IdchViCIY+TW9K4jmRbUOyU+B9MxC91ZHQIP/j6LGsF+V3A/dtFEBadQvWxVdqlN8v/R2JDZBhdQAg8+EzLhOyjyGcxMnLLkOlQyOgv6KYknUwd6uBK6F45z8PbarMW+0jbJwxdyuUeUFn/eznB0Y9WZoJZBn4bOpjoZLgwhDQBS1oC8DtbspdJW9aL6G15SGClb+aaKCH2TIdQYngldTGLDp+3fnF1MdhCoBZ+AY5/KKDCAoQ2RWWaMxO/E95/LHEOLVnxDzpGcKLDYjabm1sUgkSxCxqlAsb1w1SZxQBnERAmOQ5DkAxVEtA/vx4uI92xsOgfYjQdEzSWi8XTJsTCFSPuPXav1xupK114seqQxClFzf+EXJtupvR7mMLryV9I1tqBMaF+7dONbmxs4g829gsHpfoUlbIaofHVYPyWHVuIV3HaoN9PyB+q28YAHwX4HbX4cQECPiP3KxBctqGGT5XZY4qB9ypnF9fqxxsO1DUTm3qgCJ7RwMGbYv5epAfeBrEdEDpPvvny/XUN73DoNSsxGPUChFKBTLYuE/rK4LfJHR8+YVyWzmNjoHsEc4i5Cs6Dns7FU5aY8nUP9CxcjjR9mFCrcNk/zbfEGKrozfX/NkaY0Q1lYML0gO9nIhw+Pdvf2D5yD/6/KWGxx6GulE9mFUNW5d8ba603xXiIUBl5tlgc3yWdQYTR1gleVJSwCSdlXTqkfruWb1tObCIiXCqgkJdvgaOw8TXbBhIlbc8y2WM/hZFwVEsoqEI7wryiPT7eOyzRm11kCib1XY+LKxydX4bzMkFSstk1Ni8+XMOvjS20mWkYgh+X/iQGN7WC2dVP1qhuwuraX5pBcAzmUfzxl22PXUYJT9lYhiayrdu3XirSA32YFqDjppVL6PaAFozo0hcWGEStICEvzSNfgRMa4hkCEY6dqVZRFd4YtESGagcSC4j4np0rXoBWx6esEX067zQbHaW8G1ObJCkBh8TVJ3bo+zQ1neK81arJSbLWMjd55kLMqSyyOLe/BLBYWH1RM0MWCdIe4s0fxvjmPKYoEBMnAM4NCAAac80Kkyq00QHHlKGMkxm6cR8hzSctWhlmEUlPJfSFcsJoB+4F6sbK/ZePksvBJ58uU+4O4gWjyf+aoJrU1Pk4hEa/ARlQG/h2DOWG69/iibkzYsT4WfjUVouWVXXnI7AYjCFqWsebHIcqnMihMJYOYwEjwbeeKjtaF/4oGhiiHcSUKbN1JEhLiNzw05racAVmRxpxnBswBDiVIEH/TUZY5NrQGWUlluMem59JVufO3A5yjVyRJ6GnmEODz3FmmE2/iDViNxNSUosTc3C9/AfzFcANFmMmSKRn2zuZp0zTS+6Cu4tJxYbAYipXhiow+LpwbuIX0rb+FWl38YfL+Zxxp8tXgr1gutyFWzz5e+XuC/mscSqeeXK6PFDie2e+rBo2b9h9KstxGP2/rm+FIu9t6km6aBxcr2FhM24S4WQYJgXgooybJr2bnWx3hIyk1su07erTl4EwNxk/TXmNMcXoqggGsbhAxBrPT3rwHHQ8V784S8uYgs16zZ0iQ3s7Pl17MFY0hdL5kIeyXwY1m/GyNaKdCPLP5q2oZOBmSnlTLGF3Cmcortf8RK2GmjcG9TbZWfrdMySmMsQRjwRE0PJVJvJe6ma+xlWyMddhPRubCiip0BTTC3AZtFPRz0R2WQysIg443KJ25/oMPSQKUMKSWJkhEhUJU0IiJWRcl3GMFo72I0frG792L/4B948rj7LoBoPWl2KIsWluReOj5T+dK0fo3a0NYY+QaPW+HBQLI2D3SZSFRXIm+xaIL2V8dEql9oZbxxhHBVOSopmQpDd0dMTjSe2jYIfPucIjxgn/RZG7DpJZ9f8inAjADCoj6ipCoM2FSusxJuszclrpiMtmpjlcFPGYqJ+rvwCeSsrewXcn8NHXDLjATuLrll9hHIhxnrLo9gwN6Ka+NHdTrY1PdWXjKRuzzNuH5+/+Ns/+PK7R+wUx75nnFJRiC/Yn+eMbxW9JcbV+kGtfIsK7+1SOBqMQ3xWx6n4lViM4tIAs+xo7bX8KNw/iictxbOC1sIBKQOVo8F4hrd9l4UJ4YxmOI41CEGCBVElwy2vW4W4bKUvHlXt7HVkWA5ONylEGsSZcMAoWSeLUSiiSbuGZKrRnWHELEY/TYS0RSOVBixOODreBmiRKjCIxQXdwWMURbNneuth1omngP4uKa9hkkD1zPJep6BkZe5IXqE5M1FhiqJvRqFAMQCGM8DRvu99GJEH47AmokxgdTOqO0kccE4tsbQvPUighJiGKPPVmnCpWAvF+MH5vgechqMik6AjbGV7I0WkeeNR+wlcUWJfhzfBs4yCgOwN4k48VZUDhNRbJn5UMUQ8RYxpyUZvvmOLAVM2MXtVrJfU19aKt6sNwHszUEANYuDKY1QVHNFjJHRDl8TNrDwPXQnzMLw8lKIdVbrEmrVZRZkNAt6c1RSr8GjIBDRQoEXs3Ox5hAkqmhfSSqZPPCCAV17weKZLwB45hmEpd4iMrXPyWIdiOuSERwjBVEkxDBNhF1iCxGISEoZJKfpiQCDQfOupJaAnf5yggQC6ENtjJQFNZKCfifZJ9tQDhp5aUTIVVILIkAmIMqF2ent0NIg70ow4TxW00c2Jrdvk8FQQ83hqoZCNQCAdQfyn5/x4lp7EYTZbEyfBcadH095saxT7dk2Izc4HKtiw1Yl7jQvtP6gXecaI18xXcm7icGgqamllkdVA+SWF0Xp8rnoqYJ64VyWkxTuArI+1wP2NtROHlmcQSrBtxRzH4T67pIPECSR7gSmrrkfVOQfXywisYBTCuchpl5MNmxtPmCvpO9E/yThr5lyqoDs76GkUh5RAOWXjE8g9iJmLv0molArAYDOLfzwuo9SOV0SA/ZuDfsMYOEQhC8/p9akTzcJzgX1H4JEheRQlrvSDQR3q0Ygad9wEZWmAV6lbBIgxcNgJzhYOLc5VUKa3UxNviC3KCrvomQU9YYcoef5f7PIQz6wR23hUVvobMqv2OpteNLKnq6tR4rm/H5W/MNCOUV5HVREe5UvAolrkJkZDuYjZzw7FP1dd4/39+b7s/6Rc+D2n4vD+REfzkbO2N1pHnCwTq2ouubAQKqWxXrIgatSbNg8paIFUA8RWEQ5fQsiZCLuofD11/N3b/MJXeydKrOA+iAbsTfeS22hhcQwiqNoIYZv1zB/rzFfnaO12DGmDMZpFIUpVXi4XnqJiNec8peSyFutQDj1Ep0xOgLj4ng4ZIj0wQB7A1Hcs2Ae0NCoZK6sBhPIftqHh5XSlbccLKaTLqlgMG0QJl7mg2pkgmssktwagEU2EvpTT6ZpLCIzdmz69AcFj9hXANIrZG1LWJcpVmP+P8VW/zWtykssH1wVdvS7C2HTWa8LZAmyag1IX90NxcV4sNbZ3huGhjVzcjDFPMoxj3LMplbPvOvWuE1R9flGZs97M3U+HpTHg9L6oNyFfLdMvbkr1wpvjREWhrBHtiJIu36hod4oudslY+iESBhytE+5s1R9GPEb3GAFjHC6yco5YC8BoEO2iBEaAOwhhfhhxAbJxQbr3vICuvRC1wpzqrB6Zq/IfinMiFYyTPorHvAFyvsT7k34Av9RESt9LOOkQ1w5rJIHAedyamD8EVGMZ+P4jGFXDd59DAS2WlfUI/CpTMJgwt3JOsuzso/bfnTJQUyRzIhnLJb8CqJaQT6qGXqLjHEeAHzK2nPo+43noX65v/R2FmG4gJqc2+kNQqO8wNlCT6s0bk7EaewlXItA/XzX3prkyps+egVNo/0NGAO9wBdx3E9EFHFg5n0d2zzzfKy1sAOjScFmpkBQdqwkNwuTeLLyFmRkhpcnoU39vhCrdRhBMST9MpujOyPiRJGAjoaQKxDgkmJQ0/EZ4PtgEVC+EG4/Sn0ViBLX82s5fw0G8XXXYx2FiajgHqcoyjOcCkBKYmrB8Rk7dyIOpw/Z3EnEr/18Nb4WjEP9bTCQMuP4GosQCx45yzo+FIWwUIPkJlG3EPCh4zNGTXHb74Frfo3Jg20IvNgbTX8VusJnqosWywDT9v3w2r4SxtNvuyhgbthoQXgcewD+SkAYyP1arEppkt8dnZTT8JsNx5nK0OHO0NJjQbjfsItKYfuX7yDxvHGNTfyPtmudKRsqW/v5cLhrpFrvvAXE5TTJwpg/fjjb+fI5b0hsyOlpt2mG4rNxf9VuCrn24JD+3AUC485bv13gixoqoFLltrl3kcIsZ9fy3TQJJySrTJCr28LIkhD0aAeLtck8VRk+K2PKZmECUAKycDH2E0t9yM3XywXbbqJqAUeC4iMG7J8/Cx4FCNk3+PwEILPjF8+eueJK+EDu8cDRPYDVFuYaP4sEwjc74tmKO0svEH0fegF1k4bwf+F/+jKWKu7zwO3Lb/aDMBHx0xZH/Z5Z7IzHYkJNccO9BK+G8yUH4ztdPWVdxlSiNpDM8YTVisXdOq3ox/hIXtbcoHejA+o2k9669SbbUSemFNStG92SOlKSQ7dOsBXRxGStyXkCAXETwxHWodO6niAfYj4hGWZyxSOPd1btyu2h0zBI5LfvsNFVvWAWB+oZd+i73IF2NU5+7XqKsnagt8dqRZKbZCJVwI4d2vv40tv5NXaBj08knv2GNFHVyxfI8YawFAqNyvh/h74tHcCVmL+3LFxvNXHC8NITk0p/r1lxlyfSL52wrBNGPWDE4UwwdIWjb1wgFh0guIsrMvrinazy6GMPDH4mjCNw9e/gJlhNzAJ6lkvh5Rt2irW+Iy8WzKzX93hDPN4QjzfE4w3xQG6I3o5V7+hyNErt4ZDYbpUuR6PUnmJ/fTHBohg5aA1b7FakM0sInJtqfyypzhHEsqYBT5NlGGEt6lggFresGkCBH/6tigwOKakOa4RC9FAssgbJ7VqqYxIVGaP0ZRYHJt654XVAfzV7RubeYklb03G9soYTwiWaKN8BwCL9JibXYeRiieGOHZc7yH8gns1XE4kCLvxbpIYVQsR0+05lP5bPQXHku36q2IflMxBK7DkTBSm4OUdr6M3y6SsJkoMMdpOv5TowP2AJn1YyTeXxQlPOmjY/BvEtDCaxI4FvuozM3kkrKTXM0bhFIAsT9hpeYG/g9DwKYY9C2KMQ9iiEPRQhbAsX/x9DQnoUaB4FmuKO3Z9soj80n28oOrWUbYw/ladoArkfjz7e2jBKHty+m6OjteONX5Ylv/TudLzv0Is8uZv1UGGq/HJXX3iDgGUNUQIZ/L1uw85vAyfLeKe7ATNUZD890xkJpuNYRFe5yA4p4TBXRN6Vif4Anf1HjFFQKJz24J8fYwARhaiP4zN2oSJiskk0RIARqX3lADCreFko6LMWTobs/gHfZse4meCUTKLQZz97joDKFbITsKSncUPUqwxbBwnAiHYBTtfLPbv/2BZqNan2tT8e8+pjblvNKuWiRWChOnJ4BgvHVcIvaxEDws7mc88h/Ag/vEa3EF6cANoC0HiYpxfzuWDqAsd3ZClXzAM5vYG6pAg4ES/D1HfBhSRFenblcRZfemscZYvINhmoVRng+BWI2ap61a78Og28eFkZ04mLwJnvBZdsxX9rONZZ5pdaBAtS8/0vQ05VzM/+YyyYDwfzWsD/QkadguL8K7/i5/hqFsSCfkFvtY4AnBuumDf6K7loFZlQYnTxSnexQSDLr/yK06j72VCePW1zh9zz0s6FQMSVCUFFNIuIeejFVhgjJbDE3BZakKLFDYrPVnL/xYuErNGevWbWsyJcQ+IlMwG/0NRsaaWoLEeYmIjoTpNYiKATPrXP79JaNmyFcmS8PpndTniSRN4sbVGcI7/h9j4KnW+i9JTb2zqdxJFz146xD9QUZrRoFhJSD7pYP9RRwLZFkRd/zJNujlCrKKmCRIy9ty191cpV0YDl6s5Pp7IWqXpNnpL6+wDl2Mk6pPLcxrVQekA/BABjo9CJqo1N1apeKAUGljfJfw+M0+YkaxPtItWN/IQQc4BqgISBdXbKOmAs273Psa5oli4S1YDe2bUelmVSloFVmX2tolF2N2tRMNMLB+yM0JwAIQ1vi0xl9GIpOYDAmoD4Wm7Prj3fx0CliBABXRVEa+nxe0wbqrFyVx5KqOtrk42kVRZMMjNdEV0WN5dWm7wO/+3PsWmxqsoXthdNq8aYHw0RqtcNnRS+QW65NPKtN5VRNK30LINQrhfK1iGWM7H0UUpQd4hz6JJqZRu5raJ1Pue5tIRQRnliEWYqhrvS9bFLM+4kEZXKxGG3RieWwdpt/pWUrl5n5+laREWunellMRL2L6rP74Cwa30THS4q3VythUyfDCN2/vL1m/Y3l2Xl730RKiXmgjAUrpl+HKPdAv+N+gRxcy0nxQQyw36CmvMeYOG7oHivj8/fxj34x0mYKmzeJFz/GMYJ/evsPf33r8e7P/J4KdRfe/SP9zxZ0r/A9nhcmf5sT7n9d0t0g/qTmzkYiAd+qV9RrSbkV/MNR3TGzH7Dnoz6R0dPqcg9wegikAcAkqYrAhcixNCp6n7aZeolKJwC52gzDaWYWKeCb6jy9t/RLGr9i8VS7hb+9QRO8FNdey3E8msM9WnVp2GhU7OqF/iKCaHFFFApQk2cJfd9EdAddM9soI3/tANLrF0ddGqT4QGnTBUT9Gyt4Fba9Ve5n63E4goDs5l/BBz7fRSy9z5/jC5/DGx6DGx6DGx6OIFN9xCv81WidL560Mw9hcr8MaLCth43/1XCsu4roKhy8HcRL6m/349oWbMxHcTKylW5s0hZ2r/24mQ+0qAoSr70fnsUJR9FyUdR8lGUfBQlv6ooeR/yxKOc+geWU+9VgKwnqPaiZBYQQD0y1aPhihl8CqTj15sXX0NE19swjQh3lhBgWSBkKGGuk7dhIl6w88rvYJgx9+NQ7aYXMF8sPCqDVohBknLb4FPw7T1D7TMuOgiv1ftR5SGyi6o1lNJeaC2xk7soK2awabwVTeUraSVVaS4ddjUXaFutjjTuan5D7n/6lVk8lY5eVbRKI8LCKiy9xVIBoZEPCNyenMluqfR8MZBUAti0ivX4JutgJiJ1OeFy0rQQep0gSEbVF6tz/1bsyb2vgV2AbCUCeFYId1gO496HgjppECiSkfXo3vxMeHntGH7x4r2HJQlE0gcfdh/k7PsFAM19asPssMo+vnMI0KZl/p4xQFvtWxcQ0MoO/wAooHlCiG0VQC0vflcRl/bte4yT6xInl1tDXby0depEtqvj4WivPxz1h6OL4f6L8fDFcDgYjXf39v9RJRdHgIuaic84glOg2xZJHtaobGzMnHz8tUHMVUVlsF2nWKaCTpnffdug5GNrhkdVlVdqCQWvLM2+VK3g2YovxGvPnltYKLW4stKrsdUzL+CqYLr1az+Hi7DFh1w7d0n4wnpc0rUfItx4srQehZrBvOGJs2we0Qpeq2cWLfe+ZGCAX8KE+7YpVw79b6mIWuS/r/gNHtLW57N0Qa284I49xA43Lwt1VSEhQ0eTFmtbnpVwvWTiIph9jlEG6WpGxLLmSSIiW0JWgTOqF0ss8UslydXvy8vUv2zem3+lIvLuiaTqx/dAaf6cXwkXJ/AKqwh/NAojd5A+q+ZSJ/tp2Amo1mXy7y32WJIhS/2VVnXFb+R1PczLkmWxcDtioG1bPn74+Qzm0LgFzRPcPr1//PDzOaZuNA8PMqnXwgV57b5oXmeR3N9H5ErAcRGRx32w8B//z1ur/EM4CR6p2iyJBFQWdEWjoR78K0DScAit97GzFGBF28mBkJT4/7+1NXHl3VDedaGnz9iX57uRCDY9aBWL8aVF2q7OCLfeXuJmzSE9yv50HjppXPVwyeN1uE4tYjNW2Lrifk4Cyp5ditt4GUaJk+YySrIXfMjgtl6Hq9DN8VtjOKvUT6AAs6h5HAtfOEmB1xovqZLFpREBkIFUhazP0Ya2JVoBsxPCcliHmLE869PQt08AHjRRCq1OVddYT9k6Qd1DacM+q3YrfmPdT3roBdUPE3FjSd0uMn+cNzF3cTM5XntvSnppg1JVltOrVdsv6kMvo/A6FtHpTSICsJ6eZPE49UKJF0yEajSRJTPKrO0NqeRMzZTN6HtMt2WyrVXFSgRfTdxwxT1L3xeCrxg91PapUvfWbvNYAwVryP/P3ps2t20sjcJ/ZUpVt2I/l6RJarHl3OfWq8h2ohMvOpac3HOOXNQQGJKIQADBAJKYp/zf3+qeBQNgsJGULDv6kFgkZ+3p6em9zz6QFwfDEdFCNQRqqMKvJGenREWQHKy2tnRt1gKRlrjLaoQ+GONEzNVUl5Fss5BiXLoB+hzEcgv+XI9HP1HeAoG/YVyqAVoDaE6CKG3BDd0jbOzV7mUSJ2ghdBpYmh6yYHkOk0mvOLk0dn6JBdn/jx7z/xpJTERpBSzo3hKauCoNSwG7j0YV47sUN4qkuMTqbyp9lCZoX3+3hni3k0Gslgg5ea/ZJIGngVRBnQkacds8V+qFue3PWBz05c+rvkDAHYm60gbVVMWq6YaV9a84qt6DkGH/JhhV3FqdHeQO8eYVFloBD5gWAJfF2a21n81CYaIZQUU81Po9edX57f9dvfKiEgz6nkCuv5vtPPRQsxdcq92Mom92zidqQI35eN7hFJMUNuyx/EIkYXiFP3nBNQuSMF4RHtCIL0Jr+hZ76qFoseLgjDYRMLQe26lso+B88kpmTYxTDv7p8mthtEpWtslLmBuzuccT6YZtm/Sn0n7NLlXoUsec1aMLMmiy+5Z4MuMqlDdcgV95dGjByaH54mvSQy+Q9HD0TdBDuy6vG0HU9/c1XLw34CliU/Qr2Tuz94na74AC73AK6P6eIipR5dwGrvavl9TzC0hz4qoe+JdIp4l/gqm0J/XO7is/Oo3DmeejFlKTBr3kE9f6tVxF+YffJA9buXk/b0mt9FKVQGo8fRtw0VN7rd6wug8Ri2kSxhVKBcMKPh7uvSh6S5R1DqUIfW3JHlrsoUZKho4zGbzGeJi7acX8DOYk3VbXfo7SnRFHiiej4FqLJPoYaq4K+xOuNf4fBdkgTE5QoA0DcHvi4qvj7JPMvMFVW/1pngA++0nlot6G84/hTRuGplrTmV1mmzpJXVYLHwTKvf6cBQAR5hJsCW8aJBwmHibbnbHEWRCaJa38gaO3nd26nZGSCuVomQy0a9hhzN8ycdeCyiXq1GyyMQRNTe7s2YJyZNKaCLDa5+KLoKDW7zUtrtHJ5dGKi+zRreUrvEWbvZcVFDO72aNx8Z0WqTO3Oy0+BAWKAlPF4dJ25a0MlUEhD/a+6Ot9XrB6Zq96PksaqPK9vNkq8zfSTfeHOJEgiuPh0HRFQgv43O6wpAcYFXok4ZobLFJUABUOV0GzNHL9ncTfTTFTEvpsbGE8bjPQKZ2zUzr3AkFa0Oa8BanbXMZaLCc/B3KGjhAdCM29X/lCuEVC40Tpw8GNY0ViGswZeYK3nHvX7GlryatIKOZxmEY/rcqzIjnEfM/YhDDqLMg0da5YQqarAXkNn2VIA5QDQLdvcOZmOlgFnmcQrv0wGVwERwFhyyiBGucxXcl2EFAEKaES6hMIKhET5Ly+S9DWPE9ZCijb6QzqY/b4nIO93RkRYmj81B5k9ZMABPf+Yj3UpEtPQ3I52idLL4A8aJc9cjkiizCN4c8whk8uXfHLXJndi0A3woHwaDH9epygQy4NyGiIHTETuRqEhOCwe+NxNiBHOqMWZtEKwuQiiOLQTR0m0nGLUfb2hhLAPAdhixOsXFLR11W6A9ZehtzxcPECtTmXrKnxABffX/FiFNOUutbbgUnvxe1AZb74WkEIcuJD3NqugO2aF6jzQ2QSoL/FY9SRNuYBBGPcm7q2aSFtPI7aEAxI/+pq8xuibL1HurqMAAk/rL9964P7zA+TnZIft7EnNXszwHCoDgJiQW0aMw5iHRqjL0WrS3havIBcyvfKZlYrCHN1g+qGHcblRWba4pE/LEpMNS85tFPvXUu1c9FwaOjHciRUHZBFcd5MbBrzF2NuZqVc9riqSWKJDwHfo5AnpyxeelzbAZr01dAFmAHVhzz59PEtkW6z3GR1Wsi/7VTkFVpxqWk+x++Lo/wS3hRgAepwrZy2Xmn5NMrCFxC0gfqXeEl9dOdfovKGey4DD3PQEQHI8UDtZuvyVlyPRz5dVTnm93aibqcB0UBGl27QrzTkl+eRTYno3Ww1R1NAILg/NU3PqK9inl1+02WkNC6M0M38fZ7ntUc0jZtriogPQDxUB776mxx3t2O9L87Loi5o4V+RBjZ9VbUiStC+SfWvKIZOKgcuxXHMJWWZyD9FT3NX3XaUxjy0BC5+iOifKYZM8zDWfGPAbhMCEw/I+xSCNaWVFnwEYvCsFpKfTAnUyrZsQie/hPeomwfORVUo0GI+SO1RPnasEmIGqMReNaw+oYX223WxST3f5ZOj05N7oyNyxsgTMYltg0Rsj2q5gmceNcpJav6nNGApREBbv7o9DWJbHR8HMwR9/WiTAkTXdUg21jMaiwjdSgdlU8p7HyZkFqaBaynMIINos1X+BP+8Decd2JSMvLQ4ANkY7QJBPUZlQSQafQo15gLvlrAodBYkJ7FoKB3sHuw9H+8NMzurtgUWx3obzlWwag54CA/IIXETxlcsHgwsDOTnLwWlX6ZaGlsS9ydxGjjU7mVfDHwXRi3jaD6kiRPawxizRRuoKQWD7JuZcGSQUUJAMSHy0Be8bQK8a4BrK+JEe3zAXpDFsWqhRSLQAm1ye1crmySxN5+zGMolUJcmtCUO4mDnou872VVvTw+epl6zf4QY0OhgeMi1SMom70TWwVqUL/LD1WQRhtZgzCIw82dhdNb+yS1WVOqGeAhJ7zD6CKJdbWbl1sG4oSuyDrUGkdnDAqMoZtceu1E5Cgpk4uNb4W8tM8H8jjdZy4VY9AinIWLbzB0QGD1jRaYr8jNYJ7DRdEU+fTp5JYoQY2aaEAoho0sgNlhQTqSS3CWUyLURGifejDr1Opk09nI3WVW0pFNnNN7tL1d9SYeWqz5Pp8JhfCC+4wOXXSMzmvq+KqTRHWUcP+T6aNY73y3fAHM/9jQULSA495JFOsUioJk7/TMJuT53r57BNM9G412pqxS5gzaCQ5bhoC1VOhM9sG+IYZytYWh0wEcGyVv5Nki6R4Bpgj2gfslLFlBWVVLV8IoFgpo1RVBCrKqzmIgqwC3yB0lyWeglg16dxUQ7D3UaSPfStNuhzgIOr23WU5OMF/tmg4bLJQ06Dib73MWzAH73HYYzOmSvSrc9FTph8KjwFp8IFJu0fjItHe/kYaBJZ/TM91GDdETNfB/ku6MQsnQGLfO1imE+RZzFyUcWhce6q8mqxGEI6SNi5oCuqeWghU4ZtejCIuS6GEN0YJtyXb58KfG6Z4y5sPWWoV6CGpQpHgzBPXTHF03A94AzoUlvTWV2hJOWYqvyHg0+Q4cG6mIC+JhFPnVYVlIRBxqQd8LFiYzrdN2tXwoTOJj3Ji+FgIfuTWB7AQx4YAsis+3wyOrLaD6m2cup7oXFIEaTBb4oMgljnE1nwL16jmcimjq89lzb6s9EGlMsBRf6RDXU6iuYwJizzloiWAJwTfUSn053PstrKnrWAs5uBDG3YXAWZX2V2p06o9y8RcmrfNJtFFiQEX3HzAuHNg3y3+RiR3ORFzsXAYZswrc8dp55gctuB39w+MFelNtn9gj53NbBIcJn8SAJl5jm0OMQyHqwV237kwsGq59o2mcBqEHsqStLPobyxpXHf61qvUIQuUoLmtB4zhICmxFF48R1BZxVC2k2E2lQ6Cz25YPT7F81rCSbaWDlnylLpaEpE7d2ekZLyemV5qsSaZsN5phEu36h0rTI4v8vIwLATWfcWyembWtslcmzdni+St0KQ3WW/o1uJf1Elgavo3ZCEDvkHsPl0ksmC8rbwtnskQ3QSmN45LokYDdkxmiSClq/LX4xuPbiMMAEsFgHYpp3PG+bgc50RJfEdKKiuzpggb2vOWgiTfQtBjs7fncqu6FxWDF9HdaTtd8Wb1fkqfKIVYsFUcoXBl2SH3PKBSztkwofg8grEST+00qGIHTUHnZCibZ3KuObTagco/qTuZsqOddWYq6tZ9xIQ2BCAM1NR2kCYSB+B70/9pvM8hxJIz9g0ZPI93wiuJJJM4ehORjbaCy4Nkey4pIeCnPyuamUybKBweTn4lsLFqN57if13ZfWZMpmE6XOFZ0zWbPFwuieigaytD0qbFgMqSkw1NfgqiHVO0omPxI3c/8lQbQUttsAPKEhGzjGLdnZ71amM1zPO7lezIgIq22CL3YH9jNaQkJuIQyhrQG0k/g1/rkBNE1kRqWJvMwtzb1VguPPXqIkRuSdn+jsIN6MGM8rev3KF8N92lWoLLzs5SWIBgRnyi1Bra377AXeAGQmfHtsPgLiQEyEA8U3Ms/hNYtjD0qkoOepFO9MmbfdcizSPhxpZvfLW8eztX8GQ575owTr5y+frShxDkxae7y4G9aSMydmloxWeQteBIQGW/axG6KK5rzlUK1fDlvPokRTWrd12fZV1IK725v60Fj5LQNdivxdGEujQ5nUvUIe+5cwvFqD3nUiVNuzJebxrtSgl13jwmYl99pxp4/2ia6C9IZX5mEaFx6sLaALuK1dH5AhoHC3LSdhwbTCvEWELiFUabvlC9or3f3i2RURouJYSjRIuA9IlkUUkNMGimJoDrgDALck1p8VnEO+HO17oJukyiVB+A/kS7k1mmCrCIpd0Sq2QmKWckagF6YLiljgssDxmAgFFOtQDgvcqoMtlGfRKllV5eA7JUlV+qsWo73O+v6muqqX7GGRpxIt0ae786wdR19SQ9lYzZr7XTrCimv4s5dkVpk3aTCDG1ZxHX/2kl/SKVi7fvaSt3RqijQedEEb0pZuZbNImYTkBnJw4KxS61VnUJKZRM2UNfsH+Yw1Nm1o61tj63lv6tXqbWsjXZPVrv1OVevNFLSlwAQxqDlmcaP246mCcTUbbMH9n2MaJFWID7/1pxQLlH+PSD+HDVqT1uHWIT+e1pvAxHMTIAr49QsRXcA77G9x5Xw6nahMkPm7V/gljL25TNb7fV9CA8va3MfsKnqAj+hVLUysSxpFsm68JGX1u2353Gl6uNXRsqNec1iDLmlk2XyoL5r0rERUduGMc8rDFhjVEiqgbdxkNHMHFUhkqDaKziciEcc0dFftaXZzteq5l0zyTi+b7NA4HvR65pMp5ao69RqDW8Qsc/BGcedUtsTQNdk688v6XdmQmqIweoaVaKKkuK1tR8rGskTTmvqNYnRSNmaveMb23VjAWnGMBuqa2sfWat711I93F1axmTYzP1QHMbXU7cH7034xDz6hns/cRwR40AggyytLG2znUJBtQvzLneJjnXKlXO2BYhkQQ5nTV8oc4QkLcgoOjKEdBHOp8gF5j79hoqcpm3sicIJQ4jNIIQKahTQASQILcYMiTWZJFWFCohXvERGEyEUEUdbDWonTMKQfnZ5Mfn39L/jT49qKKM5NZtHdkRbDK4ba3PcfXr2evH7/W6GLLKmr+hgOEF9qjPCF0pbcsGO2OMesvZnzN38sv8HXZEldRnRFPDgJHVqVuVD7KH+BV8P+cDgkzoLG1AHo1jvlGlvNCZUwSCkPCM9MnjKZrq0WWi3+VVNE+7maF25nPBzvqsqyUFb25XAINWWrzh6ucuHMOw63DbzYMpG+OzTzOAGIITMoupj0gGTK3cb8BjV4Y2yuFnnuNWW8mHPTAP9iTeVtJYUvhD9vFnP/M0uOhDT/FrLQdnVFkPkWJzGbxYwvJraEQ1jEQEhesjm58Xzwl8E+5AnSfsCyIAz6EfVcEvk04E/b5gUsgW9BYUVoupnk16lT7dbYfvQqsTEGq04Zg2IOwhjUYr3ZaVX7Yb1FxkN4gT5c58+3Hk/QSaXrGh+9VNp6qbzz5pBS/TxUonh7DccSu5oqjh848dmcOiuBnPqBItJ+DNyCmqdZ9VG2CeYXJGQbIn/XEUZiWcxVM2mz7oB8gCslssUv6DWTadxkCMoPyg9WhZ5zIgp+/6CniNlNDIVVoZaM0V5K4T8QqFgKMbsO9f1Vj9wsPFClU8/nghXdGw6zUnt6YjW6QwPwFZyybJ56dimIbklxEbnDLfiE1mqVg2hpaJLFpxWNgYxE4tM0xXIb1yYF31b2JmMl4/26nOJZ9pD6tE5Gy/1hY44nc1yjeVR4dC3Nd3PwFmdgEqtCtTnCPTgujZvhTF+ensCRLFGBdkcAJ9M0jlmQ+Ctw5WxxdwATM7GylWFCpGgwOgJTCZ9EZPI648ie64cgqdE2FLM7qgQtysAdyzGfpcsltQUiNp8yRPN7CS8c9OOxdtKoZgdSDO1pG5VaT14bTdtlK0zO4CYXJ50i19HEUR8krtUEnwpLZPN5DJISIBd4CMFbIl2DRD/xxHAj0FnZypoV6oKJeShJdtbP1PGldBBdFaGP7qnfbpznY1KPx6Qej0k96pJ6aOooMnFqDratEIglFoUMKPsOyFFCfAblISGyTRQIkUp5HQgl03MtQcqRRUSEEdhns4SkgbOAog3ut8wRVTtZwVOsWEOoUHZV79skw7z7+vVucLfqyO2Kg682gIualaZaZ1TEmse4j79T3McDou8PhBKXyGj7IIRTcOOnflHkL5DWuwhAeMTs9uEDxcJDZUOULIXMB+SMJajE0b+wIBHJldCglYREvBbES2zPW5Umvd4V4Fuy927HsPudUaEWr2xXD8RW9KMVt7aOm2KZ/TFc2zWdS0J5cSwzFOHR1p/9Pbsh87v1af+ymQtlE8vVxoXyNf4ATi2ux/FP7UxZcKAcEGwLmCDvGSe2xWOKPFNzBIODpw1kbQt0ei4OuRZkhpnm0LONfDM3ZE1tYlxLDvUbDRrYIA3S9xYZ8LkJE1rn0XlQOqQ7yM39d8P0LUd2f43Lk+G2zVbVIdIZngrNHogupp/Vo3TxoIOTM53kw+GGAT8wQ31H9w3Vr+BaYvAxOe+RQgmAMLCyNEYVgJsF5hPNCgzwBPzAwMGKNnutSKeSQs2lzIfDzW/G4spRdA4B92T0D3Eo104rkyRUikVOAsZAKRoQdhv5nuMlJA/SNZxDLO5q205jaIk6ahQHXIxWAJ+34EokqirSpLU0Hw8v3vVEGopFiCsEvs6yeHdlRcY/5mKTLfxb/45P+Nd+b6s9fKolbSKoJFCLeR79Ae3pnPWIQXvUCy0oWNGV7W7CBm1XdzNB1+pJ840FCFbsYTtRgRli5e9uwaFI/EY8lwUJMPMNnityLIyHz2ZomUexfmikgMUxc5xHseArDqyq+EJF+qxaPeFYGFmM1aHCbNG5vcKu024xDg22sQ4BGXM1VazxfWX+kfEipWzsVo65tK5jycqoUCuDdWpiPMxEosX58h4i1aO8WxEhtZyr7IpVDHq5oNSnk1eq2LZcOrQWSTCRdRN8VL7gVH3dJzNveM7XqULWgjV0GbHCP7ym1MNM5J0s3PEu2UrrSQhWtHLZbG//wBw/pwxpESBhdK0oc5q5EJulTv0QtJVJ7LFr6tcjHFv9g9Pf9/2TP8Lbd6+O+EnwMZr+/ttf7s9vEuf45ODd+b/+ev/HP3ff/fHPm3e/DI0l5XUx64V72MW9uuskZYX298lg5EXfndK8uTBZq5wFLWSe3FF//4Vho3laP/9pxpTIocCJsWDHeVFigi3rs18Yc31dr41NpJ5AdGU7m90VsxcgyWpzqmg9Y0qr91XB3XTFE7bsz1nARChCQueKIimd/DkwMBDlFiamVNr8Arvu89HBcDo9dOByvhge7u7vP3++ezDbmx6y5/vT2rVaHkXEzD5nERVr9VHzPyO8uImbnESW0DknT5b0loyHDRjUtOLe3ng2He3N2IuRO9t7Pto9dHen7ODFHttzDnaf04PebPbcmR3S5/svxrM9Z+geDune9HDfmY6euwf7hyaZyVlC7U8thH94LpNWWjBy0hkECHtY4ITTaygxeCaCDkVsMYkZFmLJ2UHliz1NE0KjiNGYUE4ugUBcimdmFaYCmlrb8yOqGLht6GuPe1OftXjSs70WlMGdyHE+gKj68FIusolblUb26kJ3x+zt/NdgmUvwU1JZNS5nW+zef4FZWvNW+NlYVtnJrBIboXCDCGkHfDQMl4rtyrzFBsQglrxHRHUHuREhKYo3kyMHFrM5jV2fcS6IDyC3kGBa2e1se8lc5Oybwd8VY2Xshfpc+T3w/JY6rcSq5ygcuWzU5xFzvJnnGFKTosGyf66ylsCO8AbxhDWVqKoouVWrAykt9Zd0SYM+WGR0aoM7WOGxbYVVhpDKilpZ286PtKGxaToqM/tdS1k3V8grP2crqMdrVw3LJrMk5KwAo26V6X+nReOM5CHxDreoxSYXIZ/4zpjWhgXN6nkY8+XKm2zEOxf971qvXVJI0b0jF7tTnt9+CVRF1q5oL6NIuzFdquoxTNaWvRqNd9ne/sHzPntxOO2Pxu5un+7tH/T3xgcHo73R873hcNgbNzcaYcQEaB76URrP2eT1NYtXUChw3sJhAnuwXI8CU8ww8PYSzv4SnztR5436vtJ36DJzwrryVxiwHpBA+dlMAKGifc3vWOBGoRckfEDeSQ8maCIi5tGxSdc8FN4r5Iwx8p9TWDrJlv75iSpKrIuq8UG+qtozXPCzRXjTT8JnuPe++Er8nQ327GnzC9fbue3T1PWSfNaKxEsE6hbWVzymNz67xTY/rX4JeVJZVCd/YIvQGlKmR+gRnsLDzcnlzc3NQC4YNn85IOd4dFycnTw0eYbyYDgjCzVUDs7YDKp0q5+3AO7pqq9Gy8G7gaGzwT3H4xU2DiMtISQ49+Xn8lkZu+M1p3Uas5l32+awIqNluXq6+rVHIEkEoXpyMgt9P7wRJdIpMMKL6mN9NvXD+bOKw71ZhJwRLNUOvLOMZwePQUGKOdOrGJBXIfL7ki0nlKAmnPXInykD5z+EPl7sWUzncHXtGCJG3Bw/JtPVRIx1l9gh4GfFkWf0miY05s8qkEUfbzWunNN5CzxJqM394xgBCr/VHe4lNuuf0/kliaV9iywYdWX9T+oFnFDTWVQfvRjadoRiN/D7dq45jLTVQ5R2IVCj7u30dhbhkmFGAftBIXwLh3SGsd7tCr9WVSgGp4JPH9+aRFdBq4hlDufPeLLyGR84nBvXFR42Cy1GkvDp49sBOZmBRiKWh3PFVuqGcvUgyuOGZTDwm8BNyLt+mcb+JbKpl7LVJfECnjDq5o5+upLR733Y7HZO3Rhwq4ffDsaAFhUN/+C6Jq8NY8RxV+LL716y+BT7R4H7i4Do2ggEuJOljyicZvHUMYME+QT3FgRx4F+1vqoddkjeC1RWSQhZX1x27YGAuopYj6DkGq+wmU+DeUrn7KXAKOglSYrUfin0JDeUK7SFjRg34fhN/xWO3wcfgMsefnNyeiymucR5Lo8ch0VJ/62c73JwEVwEvystnJ788gPG51/KVfT0I4WezfhMIY6rF3RATowGURhDcCJqVISyEL6VSqCsxDUO85K8GOJXeJMve2Rvbzf7zMUC7/XemDWjSzenwBxm+GgPMlCoRSVc5WmaNKhwoA3ZE/OHjAWN+VUSRju9HfO0AdfPdlrXIqzgrNPYrybCSrisLDVtyl6VFIQmk8hzIG5z8EdUuZBCWItJnHKHUMDunZc7fy36x+8FcDrBDbfeetmQUbt2GSzofzqzLWMZTuFFLK3i1evmVbjhPL+KKtIqSB6cGd5ZudACvaWR11f8TB90K2HQh5xMUDm5Qy4/82Sg9PnOy+fD4a5OcAfGopDEYZowTQg+fTzZ+fI5bxmrL89irltnziskADRcH9YbbL1UgEVHNtdzaCKv/NHpCQG3xh84kT2QuRdAbmPRWDePYOU5S8qXs6I3HvGmJ3OXh1EK+Gv0gDNnzJSppcgLWTDh7k/aloyz7qCL52vsodZgNRzvstFwf7bHHDZ7Qd1Dh+6O6Ivd52N36Ozu7+Yt17vjwjRtcm3WgV2h4MSDhGglVyUxlXJBm1A29yxAP4KvVfgdsFfiDFzC5jHA/OSUkydYaDjT7oNKDTk4kYLoKZIh/MKnKxaT5+T3ozdIKI9fvSecxUCuQSIELVo2LIwUM/gZpgNDH/eumcw5icMp2wQPhUUCGCywqnkBeIdwZq4CcremsZesgL9BRRwFjQRaiGI6A50/boMSvgSRVOlBT04JdV1YlD3bmXoMEFClK211vdU+QaBWtBjCqlmGnF+MnFDlhBKfP5cjc/KzvwWZGZNVm2Y45JFUv1rdsqlGzxYzHo72VM7g/ZdjyBk8AEF2/98W+pGP/LHLRjoSuJmw5FF4InpWEBdrD31R9KT1dDqjlF0XJ/wsa5ZdEfpcjy9Vz0mTox8MKVN6gAShnFoxo6s9oNJ2UlEY+laj2mtxleF34rnSxhSzGXDr6Fg/j8MUKtzA9qyEJVnEYTpfyK4GgcHEudIQCGOJK96Q0jsM/T6G6VkYYMuplJm17b7geqb1H3HrEJXvp3ns6vXEey97zFK/jYVA0hv48Hm9V7QOxuswxA06GLtMc8ecc+PprrHoVly2deJq3k6eJpDoz13Y7o2RSfoEy/nxUyd0snDfeusQHtCMQNa3ueSh0fmN/i4e4FavJ36cSBbNxq9LLkwo8nxvxmDZHE1AZgga4UkYY3oIZYBF+7oQrL0gCQ3S/wMnoIHyOGp2xMlifwqaq9S5YmB0/aiyCwiDw0exRMLTqV7ggLwPE/aSpCCgkXOPQc0/0Rxl+XxPj5OFN19goB8QKnCGRxfamLmpk7UD/BLhUsQBs6ZQSAMe/Uerz4gbOh2MEHQapom83BLWgqNeQvEQ4O0BMSpKeCnuNLeb++RS8ziScav5778PrrX7pZk4PqMWT/R/SUEGIjDyiHgMHQDxsKcQcHIteugGCpIQujvOvJgnOjFHriVolMky5AkGfvKeAC2yVlPh97WMfI8rtakXkPEeWYRpzAdELhCMqzHrC86xsFIV5irERxTQPU7CYB4CHpFfGYvAC2LpoeI2k95gzDRwgamDjw7zxSD6arXGcwGsCmyve0nTADTu7kR8hqoOk/F0nz3f398b7tG96cx9/uJwPD4cOezwubN3ePDClr/yb4TBExa4E2teYDD3ik1T4V0uCk1ZsVqfMEHUg4CItUAy3u2Phv3h+Hw0FuVrMpDYXusW21tfQiy2e7zn3e75473ejj4lu6AdRIiamy5SYcfJdgbVQ8kM2101PxVjJlY9kJrC2MFnmwagdqHbonQ44MZ0brglOqdhX96brPtAsIliDWv3Vq+OOcEEF6jrMdjC/LfH6hmACIfOW7orov0o13wFueZRjnno2vf85avUwutUms0kt41KPI/OTUeso6R2wtnMOEXM4QJftaMzTP9epxZThwuqddmhtVK9MGHe4lilsqonuF2tke0wpUrpeC82y9qrph9knSPJvG0+XMTOV64FBIQpQoTRT2I2h8CLKWT2mQAAJtkjU3Rn4spzi6qiPdABWGdKcIB6CdiiHLeYZOBrIg8JszlRL0CQLEQYOE45w4LNAwiMw3SbaC0NA/k9trGk0/2iSs70vch+GtIQm1lUs/wpMGZDbMnheDAcjAcjoc+ee7Yzx/eUXLPADWMiGpnhW8aOhJ6auWo/uJQoD+aGGrEp74MDch9XJOZsWNGdLYXe8BKtzQ7DcnOqsbQGQYUjdmxiqkRMcbA4mgJ7F2TtRE5BXp4yfXfRGdrgTyFK2EJmoURsQyILCZMonfqekwON+VJUN6p4O+qJlGAFILl1hKZQzhILfTKSvQWhxJIbFjPD2gIODVHkd6FmRc7AwgCVknS25KUFqbA8Vrh0Ef4cpr5LZHI6uXRZeQ6pl8rFNmj7dqxFiDPXR/FOKZsXXMfa5deC/x7XazOZ4eJ76hBKZjXkwvSlyxiyVlSCCffJykpzmsj3k7CPPfuSIkgUb6YHbW6Mx/WV2eJzbkH4zm/ak5PT6z1Qap2cXh/0gFyFAciD3l/MbYqf1G+cnZSs+ey1fMUqRIE2Dxs4qatY+za+GPBeGZ5L+In+BWb/3s7cAZfh0PHsBLXyldNL1XBqidFx6zz2mHMIHVbMnPaB9f1rje02zPpQj1VPQciPlwKnUEmskEzEUEzZDGRopT548vHNMdk/3B/jJsQAXwMPdSwsBS99T4NKhyuI4Humh6A8y6sqn3meRhD7wNTpcR1r+3XQXO8pC0PL1ij7tWDetnMZNrkFgnx3ZP/yNH89/H/k/tg9PWXraHWqWYCtchXX47+ZkDz5JoXkJ7D9gN3IZFWitguUNOjJ+DPU1hu/im8anps7E6TvZrnVwvakvbCtEf4ryNtbFs7W0fOtSxK+bEc+u98ltxHR2iKNwNCOWCPLfGUoQrTSmOduQutHuzMRE5H95jsn59yEE93CJfx7irMdDq6T4PFQJI3vX+KdbMLrX4/XFHpjFvnU2YbUW4OHzcLvGyUwijt6+ulcS4HkySV8fCbGf2Zumz/7Hz3rl8un0g/KqDO3xMcVw+tFtsaYLhmk45TTqewDynUqZrA16TZFKNkbDsXrmK1QvNfmAnPTehkZFjEuighgNTrgVB4F9e9RUN/WHYY3XphK65JZL1lCXZpQkc4a4hqVmdUa0VgoOgYRluXh36fLqQiSEKy2Pn5MbOZxPYUxA1YTwSoJGqZjLPYztwj/x1Kih19JgLPVDwWpniMWT+zDFdcL/irQsmF5Q9C3hwn1JxVwOIcf5fpgdHmBua64kSUiQ++EZnCI6SJlRa+fDps1waWAfAggA1Y9ecb5neYX0g4p+QSwqyNzqgJta56TFmj6qEXqZkPUeIqFo+7VZLhtqUupozbURy3GkyW9nfAkZnRpuXqSLfllDLWGyZloll1zLo/g1ridThgolJK8gxROi6GsmBVIOl/ryqZGols8NfDPS4HZFk4sKseSDm+PrzGN0Cz3rXjhQHckHAPF/N4sFxrvhkykf5fNYZPL1E+8yGe3mCFv//ZWsDYgp6zwGZ2KyPwe8EmJ56Q+jf0V2R8P+YAcQZLlQE9n5iYSyhaPk8vRcHgpaIDvk8inAWZtAoyE3C7kNRShimKPowcPuAQmotvlAP5HloyqTNqF5UIz6QlvLRisnAmtJ9rKqbBNVHY7v0I78pVoReH3v7OfoRUinaL+7SN0dRf+28V699ZLfGDH4A0jx+uQoP622sn4Wen6Wjip/SG6SEKd+Z2XI8hlDGHh8mMX50BYM7hJq8zMlY8NLPGX8/NTtT7ym8zKzFWeRfDeBpkUW6mczcXnBcoOLCPMlACRRvh0GPRflgBRRALzovBCPpclvWI4ybOx8ZaF+WGefITsDvD1f2RRcNkjCSXcO2eTEyFHfeg1BhWclOuf9uyu4k9FFpnSY3OxM77Y6f7YXOyMLnZaPCH6nOT5fJ1HpIRWpWek1OLxISnBZJ2npDTGvaSUqTpUm2d9/WZbkcwikluIZiYRSbwb7/R2Ri296pVYFPJk8mdKgyRdTljgxCu5qHJ+AZ7EKaSFzZMqIHGnIU/6/xSDkCen/3yKeUTpPGYME7RTfx7GXrIAP0rBWwteW6jeckTtFFPWxKjasE8YItOcBlCBVwb+AD9P86u4Yiu+oEivROYdjNhUZmZZdEUy5E9mmMuMYwBZJgfwzJe9yN+LwsUiuc7pP5/2DN2WwSif/tPcOSyGuteAhVCQDuJJ0YqdlaeTlD6TkMW0spjxbFY/NkgU2fgtyGgOXq+zo/8q1DT6k1lk9j+/lyCfLuSt4kreYYTd483+1m72403+Jrmfqqu9Xvxeq0FbMRuAQKSMQHU8Rxbcp2+IceyRuuwQ92383j7qT24u8bG4aeR7kLQAYtBsinq5jfO3Z+RYNybvoDFce57EWMVAKqVh89D0iq367NZZ0GDOzDtnUCVQv6VcRrUxDiv2+EIZu2AQQ28oaQ9coh+4Ie2xTDLKFPCYG4FkWyO4NfJEqjD9FbmceRGXqfejPxeXT8GqJvRusjGs0AmXUw9MQVTsD6vJc7kiccpeDAaYpZcAAdL7xJXUJtmsgep9BgPXYUKJ0FhbfR+UpwsPYQPDnTEQj7dvo9v3eNse4m3b6J23Xr+NHvmaEcvwlUguLkgBxaXDqbyViC/3cxOP9dUyHEFE+QiYQd63J29OTs/6NIIc2HBD0/ia8afZNSRPgN3pS3aHLFbT2HPBSSnFxLryGrPBfEAunYDT8eVTZUOjrsvcH4nje3CChC/Q6xZU0pAa6SoIbwK9IEiMRP9MmSxaxe/i8v9IOPMzgQQ8NnMjQCaDZZSsZGpu4f00IEeB/BppGWaS0QU4xKGaBuaS+dfIOnCw1y7BplE5Bw4JqNGfC2DjlvT2RIw7HvZ20sD7M2Xyi9Y5DDD0uozDnyDgCx21hGkll1rFSJ8svBoKvh4V79k6F9p+aSut28JITv1JgusVKTbaK9OcBXOuCCVqGLJIpwSdiRwWoG+cuLE3dKXl6zQC75rE08XFwd1iwfyIeEu8RYCBSDuBCAC8+BLKIMOVclKehEsiFisz7CRhFPrh3KtPwP5RrdA8mPt8pxJHA9t4l8xvv493qBXXZ0W7e1cYPUDsfcTWb4FrsqPvevxS3Vj1uhArktxXkiNx9/ryxjW7QxgOeB0Arbtp57oOneUfE8+WprGLS4XRc0txk2ppjShj+KhZyahxCP2s5v3f9CxqXfws4DMWZQ138Urp3mEA6UPZJeN77elbp742L/qGsy0xKWWBv6vik87wtfpqz45JA+XCxQO5mggO2nyNmht/H49UK5aqfMz1ooqUSNAqFs5I+dw7yCeFCGnh3ANhoDLhMOBF7QQ2X+mg9ePUVtixgGh7LOfjBXq4F2jNR7qMLuuxeJUD1fN3ZUy6L+Yui87KhR9Ux8FmGrJcgIaIfOM8dDws3pTbC0pSfYAKcUI/dEqZ7CquIKjC7yrkE0p+wrLwsCawLFuZ8kyIbN4QcaRZoY/fqHBAvCwmrET2XvSbxEJzcNJchQ5i6KEIskSduw4GVqGGUJTI1QWxRLFzXH37ItR5vdnJ0aud3s7r3z+W84Mh/C1wshFcKx7xyhAg8xB1zV4vNtBLRQuCYL1ZSFA4hUrxsDS7iVb5SBunTb0Y4x/EkT45OTo/QigbiMafWlILxIyH/rUR6nVZBN6ljPgMA1FoWuEEFoa+xPJHl72qrniwOvJC6FohC0ag6iTYg5UkmMs7f0cjIEHyLsFxg/ZDWaJKZ2EDdVXV43WCeiqIUTnVXZENkPvrFY/agqhtueMH8KznPSgLP3wfz3UrfveO2bjHk364jNkWWLLOzNjXYMNq5StuCFj8buQqy4Jijwa2+ha/iV90iCCTa1QKE9UTQ6yXELcjeBuHxUCbseoBYbcJCzi+75CyS74heRdJ6ku9uyjSi0l7LO6RGO6I7pjC1vjDbzRevSSiMPwPOvxc1mIfkJNZZfdCV/CWzCIiMa98ggobAQDtOdmTSSHkRMiqyYxJCFVX7kPxcF6gSpwiYH761+nR2Zk0EkBVjZQrB9LC4mvNXr8puB9rgnJvpExjS4Zv+qvvg3y1eqjUnu/MvPV4977y3Xu8aw+WVdCXbz02odB9m/W36bU3q3aFkm48WRz/u5N3r2VQYjjDMEUD86WXlPQQmjJxN6SzybU3a68FaHSoQQLy7IZNITmN+PBHxObAQJT8ab70dqZLSwqn7W9yuoy+3h7n93OQ8695jn9E4/vY4x/R+G73iLeuco9sfj+bZPOvuct72uTX3eM9oev8K+JrFNzLSUbBVzzJ5H5oa3LXtLVhj/e1ya+4S2x4D7uEeba+S3wamndp4SCBKVQWVvVdlqVXyIPCiNbCcecxp0xL9zyLW9SGKWVs5/h4gPdxgOud3IRGXl8dUB+So4VBH/JpQ0LODgeVkQJIdumynZfPh8NdPSPkjgyF/VVb9z59PNn58hmz/6jIhVGvefuVB20UOew6TAfoGyWkKlHkROpJeA5JftAoQjB6HWFcjypo0exyrnorFQcsbmA/l4Bx80u4/t37Jk7BpsPseghpEpohX1fsdiLn1uSxy5Fs687c3QHZdvzNXR3LHro4Cx6lSdg34j9/ff3/stiwFtlYRSzU+vC2K/PUsPX7XAcrH/Hw3ohHtdGjEofsbEwtjhYj8sz8y0VV9EYo2pwT2NLZFmXw0BT4bVzv5RHlF19//BV69uMwSOLQ513oUFVi7SpcVsvKV9OuPriuFbP1BPdRBbv9PWqRGdtAKZkaG8sbMheIRRAmVuCWMLjpInDuI0pArkYHA8a/wXvQ2wnYbTKBo3JTn7kT7lDLQt+zW3OhaDlSxkjoYVRKOFIgIWdnb5+dvz27X1OcaXezp+BXUJZWMNpmvXnyZ5ZNEB9FpCQoWVrQmXxMUHXc1EReoM6sTtV2Ng7b1itqFbVdaN2FSG7tQHAtvs8n1MFCAAVqWQ5kku3MWKqE2pNCrk1Zq3yXcJ1lNcD2OD+YYD3Or9jzXrUynfUpFYB8wPqUupPpoE8pDlP9qkoAAzH9XKSpd3q+KA/q+fFTpxMu8OWlo67WbTaDznb5jFmiZsTB8lJtREUYUTU22ISWN1G1hvdbhpc098KWEDHSJhoWOhi0snhCKb5kMrRC7cPYhnk4kQ7FnWDUAG8GY9dNfclNpxlOJ/Qlc/23p6EWWtCxcom6A/YKkC3ocXR3Bojv4FDaAn9LsJ+A5XLCmROzNlLX4znkziEHvfXPpNMZfAtPS7aX5j4KenfwIMmhG14mA6BlOQBFK4zoU/WosE42IJrst4lcOz4fjoVc+++MwagTTY6MuL7+nAVQ+pa5RJj0TWFF5Otqrq09pof7o92xM9p/vjveG43d8dgZ7T0/mNEXu7Pxc1qWWQx2tl6EaaMvKlblc83HICtWkhUkGQ6heJ0bOinIiRiqOkljv6yi+WLw5pbfeJjGTouXB2s72lRqX0rvnyNUP2rWz2V52+ZfUlSC5S5fV5Rcr8JuW8S0RzAfgT9LnBDjW3R9IR8Z9XGJZ28+gdd9T7i/LyD/XxJC4UwsSddQnjKKQzdF3q0fywEhbWEuWqkyoYhBX0rr/onRGMu6XLGgdgUHB1NndrBH6YvD4fPp4ezQPRxSZ/T8+d4Bff7cYbuHe87u4e70cDzdPRwdHOzuus5w/GLvgB0MX1B3L3+FIBmgcYXg422fQwxD4l0X1w7VJydXzFLK+Vta/SP/vW3+W0NWu5qsxXvoYe5QMNNzFCW0/A/tycr5p4/vIZXqeuRkuerDxH24VK1JSBHc3wWPdr/ivwbho+y3icxRvvgb3ftHGXBb54EgBKKy4Ynoce6MxsjB2+/tvghT4aW4AwoliH4VnXImR8Loc/LK9hzZZSxAPXh2fuDKZFR+f+TgEHcqkuuUh3+Fn6aQ8DoQEaoyDY9MJgPlaOmSQdZq4UM+D69ZHJBFeANF/SKfOgzK4XIs+gM5XFukkslsYY1gNmHzpbdDHWD3JnHo+2HacoCPorEYQBUY1uBo6PyJs/gVi/xwBWLfca63GE6m5G4mL7mTODY6ftGoMaHN19+ZnJx9eHEwHEGhap7QZWSzqrtpjHyVOIGOi3slOn8QfUubXoA4tOg25C+iT7tUmLme4tw0dll8A3SBaFcfFBbTFEC1FCH9gqLFpGbMd6IuqVF8WjcWRnvzpmCBTxkh7XESM59dQ3g1qkKyhvICgYG4zx3qV6ysFd3KQei9JFuihjSder6XWCS38zDq+1AmlOQaKn8ErsmKsebBRYDbEtmWPE6WaZJi5S526/gp965l/dPcvRrkJhhcBE3Gr9x2PuS2AWRV3nZ5+ecxddgkYrEXdkQlSQmOcJyfYZhTMQq89cIDBdKMRqHvOc1vlTM5031ORRdMh+Zu9yYbRW2LyGJz7jAoSW4xPZPq6ocpK21a3r956YqE83PpaTnOU8L6B+CPNPa46zktibAxzT/Mnrj/OVyttaVaZ/JRpscSEmJrOlh+SUVjIracvxCEJyGkm5HvasyA5QBXSshcR4Vq1VlQpDXm7Wu+NzVLBLLAI+qwE7fMCfyiafhWmG7L2K9FzyLt7jrMie6MDPlySWMLbfvFmy8kcROvE2RRZJzDWzAgcJ9IFEapj0proHMXOwG7yV6Aix2IqKMJmwO5+olyeViEI8OOvlo0nrOkr4pCZ+9BTKUsABwUgQx2RPBjF0GfXOxELHC9YH6x85L8m8Vh9TjsFmL7Vkx1FBtZQcfX1yxeybW4VSOQmIkSh3EaBCL5IREkUw7osnlMXebCiGfhkukBjb2wJWQ44QmNEzlERhjkMGlgrOxDgIlrsXJ0ebgFvWboHc1c8QqU9CPSa0qOiJoRsUjUWmdfSyiWsyuaNEoia5k4GRjZAuWvWdCGeJ8C7wsI9ho7GIjeji9VmA0MTsWmBK0WC6rd1SYEsAJOZXJYvJClW3i2gErnVKA/Ks0MNkmjKSSIaSclCNVuNb+XIZqorhOnAer91UWQRXMwmWEMRXzUzXiiv53IdDX/TS525K8XO08zZo4Snk5lUTMUh9ShS25OXpg0egkClN4j/gbdfXjPV2QapiBPhYQS9U4Iko3vAfA7WGopprOZ50BHBCEa2FwG1Ipy7s0DuLsENumjyFXahQOOmoyTNIK5jB31CA9tzQMyjT0281fEp/PS0pKEOgt0ixTLcBZpDCXXQqgQ5S3BHCRn6Km+fdG3LzasDwjKrC5hG3imFzvkf+f3ZNJQgBhAw2hNfXBJNymIwTCrYdphSvVJyNyxCkf0SUvkKkFPHD0nU7bwAteENlalwy5wD8A85l2znj5mvZgfayCCFbJuEcgCkeshrV4cC4QKtEVeKwNuZcpiVUQExGhBTl7BNYsZx7tAg0Ly/7w2oXUm/mper7SejwyGgiI12UklIZajEdVodA4qEeHAXGKynQNyvAjhXC92WAoX5GJnxtyYLiP4gBxCyuEofxdlj2UlMEQSyXT2yOtPWWHh168/fcTb/Dv8cbOAJGFvmPvx6N0pfv3pTCcce/3+6J1o+v7oXQu1zXuroeK8IIcCS78eoD/UC45npoBozliQI1NngcgezufALZAznflWWHdAPmeBexHIMkHGUBBPpfkMIgSQQeGC9pc0oHMos2bI1BcBxVxnIsXapR/O+UDG0VzmrkPFIwMdWryROQi9hT4WcUGKlzZU1RclyTKkAQIsWUKxgBJamKSgS6I4xNAyhHdQkMffIG5CU6Q1mm99CQmM/RQyLfOERarSdTiPYSjEW/08IbXgerAqVvhlPoVbuIRHpzz4gHziWMYJ7h2ds95FIHnTiesBGk5TWLsohi1YuoHk5EXBJ4RHm9PauppMlgOddFULvgMF7qpJOSgHNyR4e0SIeacUVz9lM+Cp8QAEWtjVRbkRLf4m96CsyylYr7zA8hL/6mEddHM7CssHFwEBsQIEJ4xnArEC8FKiuGoPPASIJVzjHRaWQWxMozDQ4yKSIIWHUXK4bYxF3WvxVYa3UrDiWUgOarroLMEgjJzQJaVMyO04FclUcvtY0iClPuzko3h6Id14IDRn5vIxeTnsQedLlJtIuaq9KaJsJIxR2494gnp5mrBYzVvQ+GpQvhKm5iztZI4pBw731YcCiakR1PQpgU9PttOdksZZNALWAnyDJnm1WOEhUzdUYcgSqpXHzEHOUwQZJaEkEz0JenyjNQVqVpSUqAEkhNJHX303xbnra2lgy5NhfzQcPlXqBUHhm5UL1lusNrKWPvNUdQYNCVyRRjhrXFDoJru19NwS8ySprdaDCnITb1z+yls9JFRBeSngZ7AQn1ROfhfJ9zWL1Z/I9QnmFYnAJipAsbyzhAkHZ3Vadp4rg5k+0775Ir8kMFB/ikok1RjfX0k05ij/EqGGxnIHyoyW2RhCEIOcRUYgfuAKFTMUhBoY8m2uefvl+goo+ZKcZqjsiEg4ArY9jerm2z0gv8lv+SpwpFqpculYfkNJ3/gmMje37By1J8B0c12MY+bd5lpnVLklHbYAxeBNSFvWpJ4OytMGTboJV0RHscS74Snk2JUsxbnAERtHIeFnYDDqGcT1QgCIDMVCOgYtprzLNsuuQbtsAC0v7LcyAc0jWDcqWsUFg5TNMtS3rQ33w6jbiuHMs3CTuhfDuE85jYOUdhQ0n4S++1Qdih2i+UPeZFJJMp4E7KZ2zoKOoHoBJa7W/LGsnC1ZpIrMQJ6BleyjQYHLXHTpDlRx8RUXUb9dmjcu6z8qDYUl+OOPRBgjhbyGffL0kCd0RSgogRRbP2VOuEQG0PfmHsi4KAgt0sQFt0JQzFCfuCkTmip5YXsE8307YeACVZecHU4xtHIWhqPhEG3ewpn9YLj3Yjg0vNuHVRA4NfiSAuIpydJlCfV8Xlb6WF79hlsGb1cdS8EiMmUItVvmYAWnAtesRApyEniJR33vL0HNhhX3LEyoX+cGcA4NKp0A1Kx0NgOOt24OzaHUjy8e7/ym7MOqK9TKLyJbtspDUQG3Dej769tIKNlypDY3eZQxFz0yVTY2kzYajwOPfA8UmqfabOem8AarC6YkuQHBnOKAhzF8jyZVTH1ZfnBumDdfJPwiyJnsHPBo0Grfso6k8yNRcyYaSjacEgplNLvVPBktIWc3epYfTPuZd3n3gCeOcs9QwG5MjTteWZ3ho7hyta0no+GQ9Enl0/N0cBF0NeS2eV3XPa1sQ8pvxvbY3stpdeAXRIoJvEFrnFleGC6zYT2RniVmM9C4K20niybc+4sN8hOa8JArgqZVSknb0OD/CEkwTdnCbgIpMTgGVe7l3x8bbS0/FWWe4bcqlvwo/yrqjL15DxHArYRbeLQqonMX0kUecyqfgha+SEWeK8dCqmEkEI/D5ZLatIbnCCX8UVpb08Con5KZdoVisEci8PpwVREWFiTxCuPoBhfBv8IU7Z0g4saeKxMJiTFRq4F1VVZhmrVAk0KSraF3EXgJQVk0P5FksowJCY+Ygy6+6qnFVMg57OyqpXh9y5w3Ybw8Bc1fofzkciVC0/p9uZZ+GCU5EEtQncAyTmMG6sN6P6YoayRM9jK0M4O62FKzHT9OvBl1konrzRm36KVe4ffawo7zgupEWvNVf3HwqrwMRzvxymo9w4W1sRBgO8Rcym2w+CVdUgz/cwVIhI4KNI8Ji5dQ4Iegz4lkgq2LyTRlDaupPKMzMUJJuFqK2yQnaDrpswaNnbv2udfo8vCMlGdOeYmSnNpvPoiKfeHKwVy5FDST+eEcVPPmiuRALZAxo8Qt3c+LnshdCW9ptyWq22odpWGkX/Sy8pnHnzRzop7aDGjabN4TNwtyqgFJvKYe5uJp5berr5Cq37vOVt6qvob7s+UlwJRaLO5HcXjtuYajGZq+5S6y5ZOThJNP52/6LwgLnBBvbsoZEn20MIx6w/Eema5AG2tR9jVp04EfQvoElMlTCs9qMCsluwFudPlb13qxBmGR8KoiKK6pHCncFIVqVXcYfCYf7/HjPX68xw/qHldd1wZn9nPh94G5KjhGuIhyf5LhXefGuh6/svF+/KrN+Kj6dJnjLalP3v1kkYPNZB0Y9bkMbZ7i7/D71lO+81rMde1EaZ3+7dqLUcd0fPqpKzCF5gFDR2W8zTs1s4ghNXS4xWyYsCoNiJ44gCp8sIcelpcGfn9PDvb6zoLG1AGD0oLdlhxHnSSMycmrpzYmsS6pQ8Xi3ho0yfK+hI4WoVHSkr1+4HW3uBlhWwZiqcUJOi6LrXcIO8kfmozLkcNUnVYVLy+e2wSkqasADQnaDE/XurTs1ksmKjuORe0nHdWgGYFmPcO1oOCMnU8qbSgVkCNYn/ydYfftR14Vw6lxmtws9adzprZlewEFWvrejDkrx2cmV1R7TGVRC95QUKZIeUtoscFtA6Mu8CEIo0h8h3+WQiu8QLsEpwGiTWlnXAbhAtLyJF6dY/aXsigZM3QCpj43YpykE2OaLOA3QfpiOZDpIIDxNtmUlrDmrYcTgxrnJowrVE/qVyDUKZTFRb4k2wd6aIWZdkfvyqoHUD9OFqFNCYIJlkIMJlB0LDcmfAUu5QaIhTbWOhloRqs5MPXrNjZW8i43ggzzWzZWZUC+WEhdlOsoop9hmDTKUViOLJ36nmNiEaRnELhYDHGHzdBg9WGGuXXbhXoy14ym/9Jr7JeLz8v1Ld2xY7ST57aK5Zmt9wxTceVuS86D74wl5LIU0nkJp3opNYSX4mZeBErLH/en1LnK+1cLbXUWV51XWveK1rLeRWBExGtfGy78azKTHSzPS8Rqcm6DelHNrt+AtTETDlIF/kN4HEgPa+zJLwLA5ozgSnW7hdii12hpWbJUNgayRJG/ugguAZMvezYwi+0WxuCXPQFNoZmlPrnMAfPyIkA9t47Svsy511/qOG0h47TG3CKC2TBZYVoLhC4OV4XgesgWeC7wohLd5Q9kGrqrLK6fULRZKRO2UFLW4XILESXvS23LlBGZnGa1+TyjxN39oYnp15HzlHt0lV7fVZoJV2kLK5Xl4jKdm5scnovvlqoxW2N7lU4pbVyKO3tbDi4CCT5X2UmExRjgXraRA6UBzBS/5s5BRjx17i/wsYdRIkneg1MiI03IaPi/iFRk8SX1fbjWJlaBkU+jVkJ8BnklUaGlyfOnIOVlC3mF+5N2eRrl/Z3sh4em6vbedgoBkxA8TcGGBOs0EBUP4kK4J1/soFJuyjEiXVI/eLOwOAV/SfZ7ZDTskTH8t98j+0P4PMQEHJLxw3hLeSvFUzIeik77PbLXI+MeGclbDjE7TKKN8pu4pr5X41lgB6C8Bvu90bA3HvbG+739YW80HFagf4Wf0xkuymUz4d5ioXo9gqdqQMw4iBzsLoIztK2uhH0WkCOcWfvgThXwcWRB78CJSHtXXQRZG8zkQuYxDVKfxnmvaH2qa4BzA390/YzWuqWfqcuqr4bpQPb1/NMfnuc5CAl573MkY/qJ25oX+nre4/ZbdXcO5Xa/37LDrPbGNfGugrNr4girxZkKpr9CyiGvy6z/RWDh/Ulr1v8MeXsiWfuLYGu8PXS6CFrw9thRCVADM2D5UsYx43YuAvMnXUoqF1AbxR6GWMor1o98Guj0NDRj/tD6ge7EbaU8KLnlYyx6iH6UmWnElP50FGhB/CNuiBlUYbWrVv6V9baKHEpLOaBZfOyaWyef6miTLHA1w5op4SwZ3GpsaeEN6NoKcnCgMgAJxiq8wRxkHi8l+ivl71s/61C97Q+1TuJ9yi+jbeB6KcfZmsAuJRmz5v8qrWBtnCmnCoPMFa7rCXpxaiC8LFBksQrYcnQV0aSCKKN9V6lvJSX+KXQtvET5OjlhEAAzGcxNUoyBCVyH+Eexd43V4G4TUPL5QnN4EWjVITljjPwH1yEJM1CMz08WSRLxl8+euUAYAQp84OhSAwMnXD7TlJo/i3yaQEBiX0YdPMNZ+tl4z55eBBhKYSwMrcyxeBIy/SnQ3DRCtI9FnvdWzt6gJu1irOA5yB+lIq5aaHotDmchT/COaGc4AVUFRfHMYNAB6jqWmH1JKGkjmiyMpAsXwUIOxgmNGbl0Q+eKxQMvvOyRo9/PyOvjj0Q3EST65zCc+4wcKY87teyL4PK/+rJ/dDUfuOz6Mutbwevo1Nd64oo77fGJ0NuW4fFhCWrCLAMhnGymO8Sbcjkgp0Lr+wrnIb+kUwER/dLIq5QhY8H3FhGDBtB0ygh1XZXoA2dmgaucSK05fc1CYvYN2nVACrgaQ2XWoWUKtRSQkb0UeHL5klyKzf2SToWK1DzNi+Dy9fFH8b08WIyOvvz5SH5bda6tXENeyxutOoHuqsQ5SoTuifsht1xBi+o0kNXMYUm1V8UWwjtj/Kb7XQSwxARz9oi8Fjil6X8iE/boUEherfq+CAy/G80PVSi8N2dyXoHsLFnZqjXhUTNMFWc0QW2ZVzQQNB/7PWW+bWRzPkiWGtSLnIeOJzMiebxW26vSOVWxRJtzOXVxY+iGILR9Qef0tM2KqobstWdMBkgsa9PYgq6tkA8CPOTj1BYi2ryo++T6HjPbbpjZtjtna6Pad8bVmqE3eWSvyESbEfxXDOLZLRZjO7v7EZPui+BLmfSSgqZpEYdBmMID4DNDsKx4dBrJe3VJqMJDqqs42fdV4OPb7UzsAXYWFL0KVAbaNdwuMh52DTFJ9K3gIkp7L/PQtb4neFQldwZaIaMQQ0RJZM6li0C1NQQGLyD/OcNiFVy0bCO8iOoWvI8ZgEE6kRHgYDBTuvCj0xPIWjHDukr3JyOhmjTbnjoIKKQu1LpahopLrGoLjkZCcJJNYXMxjGHbDHNmhlaRp3ACuQMQzJ4ewr0IBLgFD43ZZ2HIyww6l4Q7YQSZU+gNkY2FBQaFJNRLYUI5pcJtoopiObiaj2yGTkUojdRuGx/FMOjLBUQ01uFPlm1jalFg7ClW9IAaROCGCUcIrP5FQDOPHvgyk4NQDKAi8aST1RaHOGO/hWBQLdLJv/owb+kWlwHQsyFDK8+ftx431SgVvFaD2w/xPV7MR2ta67vaZ+odk77Y9lByErRFYpU00hCI64fBXFGwqqSaFTcwxyJuulcdrFUKpi1FxTZt/bfxNje/jR0Vli0sJ5Uq3zIZM1novEgmMl+uZPSps6DBnGkljsUe2UoBFcaQ2QJq1mxytCDhnZ39IrQnv8oSQjcxhdJM8YTzNnqu32Xzs7NfBIx0YswaaNbqH3PePjPMLQ7dBZTs7JeGpzAKYhqHnEa7jT8Z1+lZRdyvXaYYmBlGhXFeGkHkSaNVA5O+1AinvCe916pE+YtAYArXWVXxEe/poAwVRoD2GRWfjEoHFlx7cRjgmNc09mClPFOBVeRoWUdD0ZpKNlynLWoTNirrAsVZ0A82lPqcrYnGreXXmuy62kJ4VodYoPWFaDs/pK50GdZSMHXikMs6A7k81ANyFGRfy6tyEdT4Xgoeiduy7orcc0BT+EIorIw1gA1URwbo5LclcmhqSqR7W6ZHe9jytqJ+0jCXk1ysuSEKApnQPnvgC6+Me+1Fsu2XkdIyXkuBrkrZjVF2q0j4TWUu7SJLvsg2knlsdPLMtqunW3hmC7e/3AGJvp8zJt5aAleaG/SwNaw7F56V6grJFp5SYHqQvxpTxBzs9TG4kbmKmb1iqx+FRldJq7neyOovaSKTasNVFD7O9bJahdZBq+8NDJLMXCWcSqqMzL9FuVTqIdR17pJp3Hgb6xON332S71cV5rojIraepcLXkWhURXNgWnY0fn58c9wfDXf3iJbnb25uBh5LZoMwnj+LZw78By0GyW3ydADcDocTzHS1vgcGseLwqL70ArIrvV5uyXh/lxydHZ+cEB2o11CfNjPSyS1XBS6UsyS188Bv7YVzh/E+XVmYr+sB8gCKArYvL9U6z3jV5jetELjFunl36lOyNQeSu454XKOcXAcHlXZXq07S7t9Akqacjaet49e3LmHXGlka4WtSqjKXVnQsbAPTBm9DGZCGLE/eD7tglPsRPDsyTwwhA7vC5/aGxpj19EO1y6FW4Waa6+kqZyo2qou0kHiLZQqr2B0GcfayegyGOYpMuK0NYbl5Gu5HVrivcDHm85jN0WJhJtUDfknp+mVkuHJRNmAYzoTGX7/BF8FHKaTxgEZ8ESaczJjwiPZC13MIyJ7zGGsP8RvGIg7sCniHgjo+ZnwhPaVhXIgKlGmmsS3kZ5UeF74QOjFemIrAHg98fDAFFWjvY8b6yzAA73QPbCgrYbuA8OY0xhzSDviOtzrPGs2AXHs4y8ADCnqd5qtTdeNN65YZBfxU9HaD2kHlOAG83GBiNUbTbFUlpfQaPtcVazyVSb4p1xnVRE0zlGq8mBu4i/iis5TzH3V4kaYJbRKR1VQNbLhuDQJL6TmSMskaz5LQJZpKliolCgYcCTTJ6VEGIgAOgjxAElwSN2Qc6aGOmDRlqriL8k+JUB23b7sttWSxkH5C6JQM2pv53emwPfHofdnoVSxxVxbRVDjftzpLW2iCKROBK1rH0ATFF+VQBIF+EVR4vYCGGaJJq9z6tdeafghahW9X+++X9QA53s9615rK6p6J2osZXqDrVAaM4nHY435ba5NaCzybjHSG+zsK3GOfQtmWZriYc3erPCyiY6kRC3Dyql3uG2wthWy7T5caTynA3PxCjPADkWeirQtYppUY7T3ffzEb0Zm7t+cMD6fPDw/Hw+e7jjMbDqd7u2U/1NzCm+FaOIl1QCuaCx9iGERsu4WuFhpPatKk6cHs4LUnG8VBakaVq8VhhQnKcnBiak9GbNrKApWy4xjz9sytySN4rTPj2peFmXOJSJ2rXVMUFezJbLorJTGI9P+4YmFOqM4J3Cnzrxv2cvl8Ve5hnVNe6OpBcTsPoKC3EYw6DZOFmQAY8UH2N+YS1EtwM1kUozG4nJvfWargZ1MveDalfJGdjTYY/ibthVZDhc2wqLxs0YUGXp6tpdWyrErpa3Cy9YbAWgFVSbfEuNVQsZfhrIKMvRxn5eC/qU21Gx3X2ug+a3A+WKTavoP3Bo3BWtNC3ywaTSWTgmGyxq8LGkUsELkcSD8zSmJVbPclOYEEDBlDb/TUfJA1LRs5UWMbmb4Ns79iem8oRIRLCsDAKnKdM6cb2QsDVxAD4GckFUEv+WSBVlDgt+JYqClgK+9ZchPGV14wPzk9kjVy5X64KAdcvaoljcSuT05L6f3k8L+9OxP5I9uOKbMnwK+/vRMebxngllDRQlehVlm9CJXaFhW4AhOLhNCp77efOkp9nxvEiafogQbh06viqFg1vO3AHtaGF+Dn4HwHMynyLvJL40alNyyeoSo0g259WHDeC4QNDDVV8AgYeClNSNNU2IgU7N9gWrTzEM+g7WoB19JAYds0DBN1GtmRCjHdOqL2BIFtK4HeOkLFyfz2jsy8QDqne/g2mLupmxTVCDM9CrZXCVR0GrpQi6AwrNT8IIRqJlDAWXiy/nMgzZSY61uRhbNf6rA9w+M5huUE4urpiENUAcDZh0gPoMvZ2S8ElBUD86DQDYEzLBMAEVvXehZoDkpc4d4gV3W8YM6VSBbzkpzlwWYkTJRR/SAoY0ly8L10oKtUTHIVsIXVnXgoCwHhOLJvvgxiRuXEOnKM6bHYM0AqWxItsmZGqBI2F+RNQE/nUpgVwoRwOiIWK2DjZTATDFdhGsMBAymyJ09O6PQ0CVPwVCfR7qwlQZNarnoJsvCu7PR2bOR5p7ej17TT2zEonfkJKRQ2zVEB65iw9TcqheJv7z7qvIrZXc8+yEa6ffkG7fR2sqsAH4RHrlDmCkyE0AYDMXd6O3b0gGYFeGueBc72HCFZraw+CWYQiKmA8TuNAf5gqVBfna14wpavzZT9eYbSVme4yhOj1hOk6NpQ7xJSLSa+Pv5o7FB80gGTO72dn48+qp2UzGClBX46P8aUCKJUqjTwewE5OftAoKt0vKhf0Xg4HvWHe/3h6Hw0frk7frk3Guy9ePFvCaoTe7pv4fmfxvZKEqqfgq8R8tCkRJHVSLil8IwStwp+SIbXfRarRo511IHyKORC8pHejzOrs4twgrH4sfTMAYVMlRtPKJ6sXi3ADqByXhVjU/lGDeebH8BcsfQ4KrFwKFC1ocjXIvNt5AkITZZekCZVYX6ZK6FsZm6pAIqcZ5CoCohZhAZE5+6yA1D4UaRcc3pRyD3QuQ9sAMQ3UEhkFf5DzSmtDcBVuNwbkIVZWu66caub76irsJy7U6fGvr8o95/KFjUXDZlRE0j5aBtOHBrbEqoaxovUx8iJlENANRjKNA2rS9od5HJ1a8ckwaPh7DNPICwNcuyEQROQCmfR0hREC5fFPspOthTatdGbxorV42QLl5UrwbdBE35Oro9PP/WIyGIu6AEkMoe8XZhcyvcSBjmlRs9GB7LteP8A8rbrPmPy80/YSfSYUu45osue7DEiPxvt9/LtYV0ujd3+SHQay057uU4vKjqNsZPscpDrMhpX9NmFPmqaF/k+BxV99qCP3s8412k8zDrVvloAzFxGRPmFQkn5ESEozH0SMuaHsflh1/ywpxDYyJlefn4D78/UyOoOTpEirxmYvQQCr/TPXKSNVqVE0Iu66vF8J4TJWoeOosu7a6uEZtLK4XCIfrJOulTuf5M09q08UnUQaG9HaCuMn6qi6kIUtGyBpOUabC7byWb9XH7yUoT1idi8vK2ZqlAeVnMasfIZYmE+XQItY/3zZEaJUV/bI8fJCtA1xjSIlgCnnEq7URWpG2NXrdGb6BCNupAoa0zHBk+eTeX7ZZ3CaYpqTxJJ2Js6mu/AOq53FZ7E6qUuu/CW80nkjKVtDNbr2qRtr6Fc56l6Q1Fks6t9hRLDAy0loeQ0c9YBh4J/hNM2+YxRY2YjKnZLuUrIY3HubiBfbbX6WgutC98cIxHovEbg4tfxevyigNZurQJRbZ6RuAA5mHaAVCDqadgXtilpqqjLx/LF+mrD4o6IKJ/Yj7wAxBzFORfK8sEjKSsoaskO02QLlUSLmNFuJKCLm1uugNhHXSilGP6XMawEHMwizGBAEwqZOMGNnRwvQnBe0plfj958hMTDFztHp0fH4q/Xrz/J716/P3on/vpd//Xutfj3g2x9Jn7AVK6/Y8+m+GcYS3IVMhSoihfPOG6ZoVy8ik4u8yrc8Krw1ibW2kgWa5FHMPGunKI+ZXll1J8wVq7rZfwlnzO0S1p1zLZrre9ZoVbicIGEziKMXSHkFAfsFVOWSxVilv4Drb2jQoXypEWl9voy6lU1Rj/i9/qyyly6ji56D8SjqrBovNG58IoqQmc5pXX9adiKfhpZ29HJ/JoJp8Behkz6e6m81EWiWzDArfNzZ96OQjGvLB9ohQEv1HdegBnJQah8R28h3/b/sh1eMb9BtoKyY6EouaN2k0f+YlU2S57nNVJn311dg8oL+N0cV9VJyQPKSQo28o7WKB2vVyV4WovHVBzElBXr1GgdqK5jIIOV5+DREpBFeANu8yoddjGV613FUskYWhVS22qA7K1cIxjrnhLSPYCoK2NxDTnoWkddbTHQqsaL/n3nXHebxuznPaYxgb8yy2KJcJ9dU2nizOV6ENH+aRL2wQu2YmVbDCl7TFi3YcI6mytjIaTHdDNtZqeLscrFi4pvwJYj7Ho70qXaolTcQvidGrw5p14pw3+p/efqp6uLs3xtQSbyiTOjHpnFBceoTkb4Ikx9V5slCjlcbeQhiz426BH6uJtu8GvmcW0Kem+G0n0hsSVNWdnyrORU5D50LhCZoGwbme8U/coSvmXhKeK8QQBPI5W5JJedrU2Iimhf4fts+jjKgQ2pGJdYb9A/Oj2Z/Pr6X/kCtuP9/VwF2xHyxmFsd5s/yVnf0JnJhKkCg2LzxTI39I/PLXd3nFvt7rjMDsu193LQlEh0ByaAR9X/o+p/Y9V/jZaxdOZ2PNWV6CvluQZndnvKarJIl5A1ilFXu4RnQTBVAmM+9UxT/skiQlsSMcJINckWf9v7iXKG7l5mcdUGKwg0l44yyl6o7KXPh8Ndw1qw8z4kcZgmmUL608eTnS+f85SzkS3V1tvMElGY/3OnMWJMj2vbqXxUg9T3P/d24J98jTPhBF0+9t8XDGPTZUpXTPGKvsOZ27Rx4MpqVKLBcviegrGxXb3qz+bRrXNqawK7Q7ctg8l49azluWugpoF1SudeACy0SI2MnpBl0pvGPIxJJNpiOTLpeC4U+Nd7uGpMKRpLyLcgFOw2mUR0ziaJvXY2ukXCT4oBNOMahBXnFjLFytKDuAG7XrhplkiYiWAqrgsEaFbaPiSLcfFNLnD4CIHXk5hEc+dWLZ04lXJ6i4aKNEYkaKE4DUq/QMEx2XPGcYg4PTXRliy8Is21tQRoGJtkJXMa0X3HY6My5cH+/u6+6VFSaTb2PRYkfcgIBYmD09hLVhMaeX2oRKcwse+EPsheeRlzM3Jgm3e5DoFoGmgTktFIMTRdhw+fax+AAsmvIDWf684EyMPjoax7KBNPkubOKzf7V78RZqvaYzROcLl8PL3601vnnhQA3Jd5Xe6PAZXOb038Z5cDa8+RNo36VXjU2mOXbh25oleNvFg7DIBX2t8eE/tdXrFqlOh8+xTj1IaqYVJaqQQvKqNENAxkkKQJ60uvqGIgzIv+6MX5aPhyf/RyNBwMDw9G+//O6uBNRP4h5k6W1PccL0xNPU8VFn7p7WBssWCrrT635kKmfjgvqigjqcsQ43DGgi1tcigifaBEXudVtbTM2c7UQ/WUT7ewmcP+cHw+PHy5//zl/t6/hZ1Ons1EnpoDRYHD2Kv3qC4JE0YugnfUv6Gx0NZkw6exv+WxFYasPVgV8oDje9VvY2FBasJLpUh33OCPkg6d/kFvn/nelD9LbiDvVdyH6GMwV0fP9gYHg+GzP/gz/dVg6QWDP5AoIQyFBMQnjhtMnLk3gQqR7S4WdF/vUtqsWACDXkZEivetgLHy2tTtoYaohVdeizdEYjBNRJ1xe8CkPqLy/cToMMbrB2hzz0bD0j17cMQIMHQC4cLW7VYpaB4qEbudADGw7SST1PU4uwcY3qHUvNWg4wzDvOTivyK9gfvRFq+fIftCl2zCvcQOE9tWk9gzedAdn96KIvHi6yAMBNXFE7UPW400yppQPb969ONkZSwi/20aXAXhTVDhn5f32ZbUppYmVROceBUl4RKtdhPuhHFVNiejHcF2ygb4D3pNRRoqVFnl4+qMiCOlLzo8zCuLSry/dZ3gQD3zw5u6Nao2jesjhiPKgkKwNgMtaRQzeLbRbW9Gr8MUdYJ/8AnuApeBI9/F/gydXYkJDwhy0sQLXDClq1ofx2KcM0gJdSbHIVjvVxR3acGbW12ybcubsQQM/ZKWWTS/Ot48nJk5PBDsIDIANhI5is0k3A5KoCn8KwxA2lbMv5a/HgWv7agL1xD5DVGsSWdVTYmMswUe6PFcH8K5Ije6hTMVvkGPZ/r1z1SeBNia+l45/+QaZyug8Xi2Wz/be9Jh2VnA7sSiPAwoyCx8m+Kz1sbhwqBb0MPl2JvO6zG6fwtKPdqiboNtm9jxq2kFy3z4WoNZhrlLaX3OHBonG6y3MMS3rcdcir83Aoc5ArrhzVIuHIy3SmPK4z7qYe9TD6ujAdZ3mbUdqwoxyB3L/1jfwPEw/zDYCaqipztsdzp09vbGhy9mzsgZ7R3S2XS257w4PDyYTQ/He+PnlO2N2N7B3uH0cHfPoXuH+4eHo+nzF/vj6d4YEs3YSNy4TEVGw9JN2v9StqLekyZ7CwykjBrqwkJm6pLOKKD6dguPsY2UC2gphcqknE2yayivAeAXC9x2ztfWORtHVVNroRwJubqz601oGat48AqshTif5vVWL7cSdRQLY9FThssoBR0eNFEqQBpQf/UXxMhja5v+yYgyONjLefbCx3baqfqYido4iOF4l42G+7M95rDZC+oeOnR3RF/sPh+7Q2d3f7ccB5FHtw6qPDsfZUtoJht9DXUvup8VNH2d6MOjiLktJzSLxLr5M5zTGG7m5maiCqirHtHke0ITqYBshSLNLEeGK6gGe0SW7wlZSprNrSONAPIjznw/OCNAsD1cKSt8yoyVavM1+KqSAsa2PGzyVVbXIsFp3RGre6kxppALtJ2exwoVo9m36F6Q5aFoSqfTKplNDfmVI5TTpq07oDkMBiCvL/nLEQ0FALuNYuH5tNGA2SityzvVDHdtLfKUT8QlwZzbQc+QwY1aUM2HZcV48RtWAaJXjHiyvpKejiwp6MZ4rVyLCW0MLyf12Q/nQg9lKARcL8aaKRDx2EGetaCJLfmkkSVMRVHozCLV68eCFpirDOIBj89Os05dF1jn4aOfXplDI/Pi2aYTTxlb7bXssiO+WXjOQiTux9MugA6rCckkP8ztyUBFzICS5cB/48XsBriJOPVzg/NVkKDnXTX4WeDyCTB0mK5joEI809gbgIIIcl8+c+QRXew8XeNUru1ly86zPQoY3Hi+b+y1dtXSIM5jh/wAzoQ//LjGwhQb+/J/NqYCaHizZM9+JP0PlfRvZCqtjLUtsOP16IDZmSwXo5BHVAZya8KQJTTiokRQdlNEJ/OmjKRJrTzNsUwfimRXJrqJVPS7iF3PJm+cojL6+31pHzr2u93wY/Cuxtyqk1qAqeHpNfV8XXgSHhYaQNo0GjsLIz9i/ZTDbNJIscv1pxTJ7AvVYBqWiqJHIg+0Bl5PokR+v/mFVPIbUs76eoFaj04uj04uj04uj04uj04uj04uD8fJ5esGGwo7/aMPxqMPxjo+GPlzaxMSZA1Y0sFBcrzGspRjiDkdjc9Hz1/uH7zcHw+GL3b3X4z/93D0cjjsImi3wo3KYCzQBYkuXCsHMB1VEhJNpXjU18MWqZXjBn1n7j0T40+WYeAlYfxMtN+m2qcGESt3J9K1JwsO9SVCx0OxS2VnVv4Y5NPHt3LzWD54mnnabDX4zMg5XEYz+WOzq0+VnPsdCAZb5ew35pzvlIe9K2bzG+bYKvU98LBP1MM+0caxxzw1d5enJkxd5bEWxnebgSs/1XoQrx7jbrNftku8VZkLsxnM95+Hq20i2Jbn1iEHV/WADyVF7Kb5tyozyBb2nhUrq3PErecwu3vi2vmYilN5LN3avnRrAYaqcrrFWgAtyamqrC7TY9RYpW/4hO+aZmn1hSkPQB3guRNNIKm8UIDTvyAfSPY5dDz9qdJknd8EGEGbIV2wn1Xv5CPYVPM2Qdsq6jLCtuDK86ayeu3MQPhsEvYnudih/z292KlYk61IpznY4b6ze7DPRs/ZaLp3sH946LiHh2x/Ot4dzaizxyqGNYwo5XpdWQGqcCZs1FCrQxwNAViWTkKpgfMD/RJyFPQiFoPSND+U8Jqot2uLv6apc8WSAd8dsLQfhHGy6I8GdEn/CgN6w1GhbE2mW7xNX3DV+nJ0eS50P8lGlrHVAse30v5WhKBovmZqf9tFsa0Judo8pe8yrtHzi3nf+1fjyTFWq/l1fJbEjC6Nknb1txXQXgBJ5kc2dGNKR9i4RL0INf0vSRKdBFGKx2vP038my1OIQlKBUSLk1zHhOEr9Y7dcTa7GE9Ey/7CNxi9KlUFiBu5tKHkwJwxcC2acQTUQYQd2wtglugsRRZZkcUqyAO+3J5CdisixnsJ92h0Sl644eTLePwQ7p/4Rkt/IIlFW9zgN+oPh3ovh0PCXkyMZ76bMiXUTxlcsnkw9Ufax4vwkVel+fL/j8D+J0eU5NhWbDcKkzAgo7GqtjC1T+DpmS3X8bAXJnU9a+KGwghLfUGieVXex3+N0qpGz9W3uetW4McmA4NTgBUVzPwjdmVmZCIeIWZLGAZeedapmkTlg7fXFIrF8IutohkjRsKpq3sDXUJBaIl8eCiqNWamyKug7aYIrDn2XYREBzFPvqjsPVQZEAxa4GkrV1EjyYIzGvse4sHAk8EcJO7Dr5041m2WONA2VMrL8Ov4JXNta44dE0TZmXnMa0Y33r8Z98afKvtJ6K9nEtk1AFch0yVpvAxIJigOrI+PLUvFC2UeWd0jjwEqPTccSgxiDyGKS4lFGdL4mPHs5aNRCd9uBHxVbWlud0zRYtUogv/4p3In6iFaBIS7zvWsWM5dMtYfo0fGvPfIe/w/l59htwgJ3QN6noCxQyeGUxkYVuoBSagq7WmWI8xkUuJ5AYXh/srRh8SK84dmE2F7VwxaLlWlQgbsgLArB19XzfU9yHQPYCJAz2IrRa8pmEACQLFiw5qZsF+X5/uHz3eeHQ3FFSrs17ura7HUZod2POGw5AEaffxnO2Vo+51VFayGn1NepYRrTCdQqBas32MLfEYM37EYm+bJFdAXV/XqEBaDgcAkovhIauDR2sdz6wd4gL+et/nHtLD/6jn8Y/fv45ODd+dHNu/83/G/T2Wa6SsraClEa17VKsSB9SerMEgrWIGGui0M3dRg8vgkFew667uvFD8iHJThFuCay4q4cGoPrCwFXZZu9zE5Qyzqg3o42+TZdx1/HMDnzrplrrKTqGra5Nwd4b0oMg7mgnj7jGnyJ39IWjG/lw/mKOd6S+n0BFOJ6omacEHuK3OIPHNIVyFOJQu7pgAsMOAIHWuYa1XEFD0WgmBOCStEVcgKykQvFs4P+zPfmi0Q/06KE6EqITy6TFM/Vv4PUrpo6kHPWZ+4ciDlbhYGLHCvyZTGZ00hSuzTwGUfMT1IsU6y9WlvRbVlDvlzJLuBpJLxoyJJRyRbnuOgw1kAIo9AP5yvi0ABKcE7hNlCexsz9kaRB5mcrRqJEoYWqWCwiQajnM+RYQYftQWVV7vFCeFuJU9WDoxpTLxo/Zb9ZarXjvvPks4iGr5dRsvp+2YwH/GC8Ri7l+wV9cf0t2SdRuu1Gck9IPlYbEOoXYyuhLi7mIXMW74SnDnNN9UILBiMrhd3W97bkzmbTmaNj73xN/g+fO8DA0MU6txutzp5lvkEnYVc7bEVJUHKtLCoDCvXJTSAIoLY+fuDJvkPSsZGIYb8nXx7wzT4VLDSWkm15im0EiwpDrqEjGY9GdTZaU6T4dQwcV8KWURjT2PNXJrcjDjGJV4LhKonuOoH8jbTjr8IUOCis1LkyRFxUV0LF+3A2GwhrApwkygiiUCa3iLVVJWEL1mBzjQVC302NXHAUqDvT+xYDCTJyKiUAHNk19T23tXjYXhx8p4RAOoV4MlOcwnWhIAKlx1EWwABDbhPz9LL+Z4ddgyeWagBK5oEklDuVCjabzwG9NVuIcu2t1XN1wpo+1JbKzi0rT/I49SVXh6/THuskAT1J21elxTVqUefQZsu6H+am2u36xCh8wfCGkV/Oz0+J6oFKR6H/QNNL4MLF4+kSPtWoFPW60tizhpkM9+udgQZXY8OtW7qCmGWHumKWxfS7gWJcyMp9EVq2VRav7nwehB1ayy6OLL6c2afuyyatt7eJTXprhucqZrgMTOMmSiQuLayGca6mIsdhzD/gAfFmghLG3twLLCd7BBlEOJnG4Q1nsYo351rDpmhDGOO/Z0SONCCfOCMUwhVcBx5qKAgGLyQqmUKfyYYDchQQho83hplP/dC54sSJQ877oklp8gF5JVwH0Cx2+Z8f/uuHz5dC04lrydJ56LBvyU+pxdU4zdieVfnY7Nvc6Orfn8rTyWhOZf1yeb9zpHdAXnmcTn2gtPjDFWMRJ5c0BfNI4glX9UukyZdOGPPLHuGhAAf08RJC5xSVmQgSnGLZHLaRH78Nq1taulIJAmOEzqyipjyyvr+OlT4diMTSQ+e3AcEIGfGOKwO3GIo6DosSDrx4trBMzZpHEDimeuygCj+QXbNx2KDM7ipC2i5i3jmwOwzVxuuFgdYMkemNYl/8o6RddaySzK+T4yOfF8LIylH+wcilUfqxkAij8HtJKBT5I8p5Jsxhvo4iMJ/0r53yQDkNfj+ouQ4KPlzlTiV31MXNrYlAiuE5kYwSR+WKekkM1xmrS9T2KeZXUlCvJ6wYi70LkeV70Eo3HfLJ38h+tU1UKx/LQzZAPRoeGt6ib8XekPdP/n4Ocf3Derhn9dteF7PQgz6e4vrrwj+7GWQ0TFuF8OoVf8LUH2vH3WyoYH3AYS1fVWNYy4IuvcD8dvQYvPKfCl1pOYalhP/GjaUOyr19m+d1PgYlSqe+55CTVzr1iejaEN48Gu92C282lO+747qlo+W4xcLFimnRc7yXOUlK5xTtTd2QE2j2wt1zDqYjusv2ZvvuC+f59JAO2cgdO7vTPVqO86t+LlrqwNZOfFC3lK3FiNeGexdwtjJCuxZLM8NSVyRtaRBqMrxtgKZF5r8VtpYCvWpX/9wZscPpmO65B7M99oIeTofOyB2z3dke3Z8eOLUYmUWzNIVeONKHi8gAsAF5TcF3Awcgi9B3MVRrCcHK4LchXDsoqJdBWK7fg1zGKA/p8f5ByRxn7CTyIuZ7AeOTLBb6DN+e8mZesRm0FKDFNgrQ6H4A7rgiwAR8G0o4U0HUsejCNuz82U7OMDvCGxgYL4UXzFgcVzwcxRKMVeCRfuKvwYEk/1qVlAs6Wa/+BSIGSmxUNjYu9VzF73kA8yUkThbMq4TX6j2qRcSs8NgHqw8zTH3STfXhBcnuuErdAREBCWLTCTYrR3OuMd3BXqvpDva2MN3MD2mr/b2RDbc0ZZs9vpENN58S0Ld5vp+g1eaTyS8apztTHTfenRfQeNVif6KdbULV5FyFkzTSoTTwukjC2eXVU3yCEXSmh+rt6RCXSp1jZ4j9wcOgGV7/4JhupBpaZ0mcOslDINl2FbBF8G2BvLClEmzkHnoGyBUUQEHXCIMtbbV5A+DSYFFD4/R69dUvi1S41z3l+FwLzXz+PYfHu/trVItt5bQ5+KpOmPGsdoZo8WnOxbXNNATWv9kSil8weAgRKrWzEy3Os+6qmlh4SuM/U9aMiLCZ1lUxLJuU8xwbw8DawpvJPA7TaCJYF5s3tDbmePLt1poOWzRsE1wiud8q0FSiOODZcR4IddKBAS9VGgYUPv84+/CecC+4ImGaRKlVJtfZRnbSQA2DQWRqD4Wv5395UTXTB+vOruff65pUctlAewVpbLYmbe2xKRPWykOz3JYanC7gAw9oFK0UYvR2/uIJRmv/tdc4YVtE+TaoQeXxn8q/XrvzFmYVyGUyyQVY2ZeDXH62HHCgcudsYqdIX3o7V2xV/SOPnfXmRMewqnGLNg8xSU9v0VhUbiRzK9U4JP/6OaaRJYl03hdYaibA0w9SFgNt9EDBsMRM2QtGzv75tlmqh1Vtl0PMoQayiKF7R1O8ByVdKb+CmK8nt9YI7Pd5Td86aQPlJtdDN5hF8WylYSHlnu8z3+PLzkNbwCIwVM+YryaWn60SbmdecNWGWxXPc5Fppfh2WxnWJY0i+WQi79XppfCCK+Od7mkupesgeTL+pdfMRnd/1fJrBV5yrTEKS609sAIP8/fm/Dd9e4uM7MbCRPW5lbmKR6mjEwwNDrKDyraQz0uGAU6u2Mq2xtJmKv3isoXb8JL/6U8qulqT8z2qlh9Vy4+q5UrVMvX9dZ/o7FmR2r+uy29UHZcWbOwp04Xfu4J5A5gJnfS6AKtS/zZDS+rCN1x9ps/ovna75rd55ai/ruHbDIA2yicPR9Vv199X7rJw1Ro3ui3zT6Vqo8hS1hx8PHN2d3cPRcr924lI2NNiq5/kHiovA/qwIcukUwDhJwiVVJ8CGqgPlTPG43OVrqIeqtLByZqV0ig4fiSageeGqtMhEq1blLAKy7M+wOPI5qVJPo7JT/gT6DFuYi9h9kTvmu6LcbD8LEPfDZqrqrhOYl6KzkbA5W0TDpoPvqYxePfkQQPZ3n5lKwkdzpyYJZNsIfe/CsiKz1kAGfOuK650Hk62VRtE7uMYEjfrE8K6tD4DPlenBi8ExCZx6HMCrTDcPYrZzLt9xtPZzLvFYFeoMZmw+ap9RkXrcYuBy0vAAvX4G+Biyhm4y8ByMPx+QLyB+r3/f9LUc//vICoKYyV0faN2cyomxRgZsYvyAnTjOQtAUwMWEMueLWQj9ihwe7Aq+c/k+jn85csy9cXlnKlFoGvyrAIenixFF16zWN5NTE+LVhYBGtFZAEfBo4fAE6XtaCp1TI0QOhPLEEkvs9/Ie4ExUAUtjT3ueo49PPkfxq8k+f/ZexfttnFkUfRXcLX2Pp3MFRVJfsaZ2Xu7bafbPYnjtp3umR7nKhAJSWxTJJsPO+pZWev8w71feL7krioAJEiCL0l+JNGcs2diEQQLhUKh3gWw80MBycDQcoJZxK4CRH1fmOAiJCktvR7TiBoOXUBqsToSTySYurQFYdpUC7fnDJoKRiwoadMnHkqXMMR7kzAnh2ui0BaMBn/7z3++mHtuNPvbf85fWHTxt/+0XkCg9d/+88dOVh4l53Jx5FwAo+7Qubp0mdROUxTqeiJexmN4IHvQp+yr4RVwjm06wRjhQL77yPcc29Qcpwv+nPDnuDGcZGF3yDPMFv9f5G62gO+ajoe1DHAEMBvPZy6hWKfPc9nzFXcTeV9o/8lSw0nx7KddL2FpUARpEmFJBGrOYCFI1GnZcD6TJsQ9rcGiM8FkDtel/ScaPmyXmpF9i30ByyL2z5IviyFYtSp5EXeP2pGs5Sy2B5kHPOO4BES0hHmgWgqSr10KMBH4CMqPOm1AfxBgOVgpqHnWJin0nFNwqyRVRXJLpKusUJS9jMGq2KmRF88xtFgrpMHrMvTYVM95g7oSX66MuRFZNiLLRmTZiCwbkWUjsmxElvsQWYpCChFSSLmsgu26RyaNqONNr/R1WS+GBPgdOeKjuPizdkmlrgBihVAC7FARTGY0QpYf8iMjFldT4c8YJ5IK3EehT00NKhBDJB1QzqbOkjEbXrXhVV8dr+p2sOXnSF9xMz0mFSeED8KoASzOdcM0ks5hppAer4HXzDSbHu7rDg2tyc3vw9nW9s3vs5vfRdNXjYl2RZUxAS/FTYYpAxsVXBSY6JUsit2YOVdolQUW/VAq5oZxbxj3hnF/o4x7DTyzBa+sEWdFUnjyw+OWT8jDFSqAPXodjeagyn8VAf3X8cn5xcnR4dXJ8QdyjI/GLFvWmt/aGLMs5+GVjmXfHp45H75Ahvki+Sruge2GEaNW/ZUFiQMQj9iojiCWGagfBi03S/houkGBF09nSRdS4L2wVjjS+m5DSVIVdhoV3UYz3UfzHUj7WEYHgLEENkeVEMlRCfMBRjOdBmwK9iFcOwsLECZJ/AmAWxnQtjJA9XvDHQEUVJpujiClTSsUyfYZvy2boUqDqSyiCrVDJHxdZTMLuPxQDGauJgwZyVR1aC0WYjO3TP6dM/UCO5rN8ern7L36EIvMqTQTT/yQlF7wXJYmWFlsAtUdK6J7JyUZB1nY0zwD3rvRk5VwqmzQImQutfnlcai075DCYHoFSJN8B3onFGOHy6THLNwZzwTWpy6QuQbH44x/onFzbWl8jTyU+aCW0q1txdQRuRryw+mH/uPfoRNPP//Hv7HdLFDEZ10fFXizxG5aDgWAYNkBMyMv0LsKFDDAUPz5xX/8Gwy+nzmy9Q6R7AexrUXykaL1tgbNuLH5Jq7CbKWErldBAGOQLFNuX0WSQVnwcnIQuuIuyDIAQcMfWrT8SMqNv794g9QHncWjgE4mtlmNF9nJYzDcmuzT/eHOfn93m1n7L4d0a3tvMtjb2tobbu287CU3o9LQQ3byaCBEiLeJLUv06E9zAlcdPJ3SZhtq+pLaaiO5/iu/G+I/RonMUdtsI8QAy6qYzaocqaQaW4sYSCEhjdJfxCwjAYtsrbLSnDCFnPBeMqjqPrmWKXOYwThdtRlRt3PLAn0ie/aEiWGKBOHQMCIhvcVbVm/gSKSahL6wxZPF/IBh/wMutWvSQhK66mZkyy6viCxhVhhEafRouTy9jOzf7BD1t9dYnaxqKSC0N12GpZYqE+mLFUsYrrEOYOUSli4V16hO3NZ97kT5QatW1XhBTVkEnvB3cqdIp6S1U8raSpsCDJCfGkma+oyC+gOelQHqDm4Jf6xGMPYguSe01nWWSdErTRrZNyAeImk2ncgqHjf8JXLCrU1xFdW9XaohLe2RlIJIoVtS2mcIlVX4iRxBPyPyjvczQnReyGZGKUT1vYiSk/ivzl/AuqT0JsLkhS+NRr3AZIbnMoPXLOK19FDispsZPwTCf8E2i1VSUxUqHe8OCyZbdgzt0Gb2FGXowAYacxBc7HqO9LZqQgGeH4u5GSFPLUHk+LoHeRwX2lLS4CZEWzxzsEOm2pQd9Ck4oLwbJbmbgSE1YBG1Xd4UKoQoKIF0HD2zQeOE5RdbWCrAphClO5CF68SN5/K7OpAwQAZimyIBEMY1kcy+5iGy7NB36KLFyYH95lUwNHZuhsFUOdIjfNCY+xAYYbKIhlDaqEvwoxzhPTzOyILQRXJjuxYwpu9wzHc9cslY4QvPAmbGARSjbuEp4WerXpStO1moDeIoiZWyw897vXY7dzQAEdGbTHLGl7IXQTGHoL0AYvmkhQqV09iNMI8TC6Nop0gkjgmd2w6a+QGn1WPLMlS7iuTs4hEXoEmyETj/gL29x8yp/sxhFFETBI4zLlrXaHTKY01GPPskCpK/lZY/vsOZciAcfCjTHAXUdrWlhFqwIPl1Lf+Z00/Kg7TZ1Nx2Nb9/Lhi38mzJh9Mi1T1ojAuXYv4owAHnK+HnKSw9UHzUOk9UE8Ww9jTV5PG38SrBkRDUXn5R/riwIOLVOnEjO9L4ceVzXgywiwY9EwwGXejUGNEpYfhmO8ZTCs4Fc/jlOLP9ZuWfstegpgEiPiOhCXbP/v/53//voN9H2CGztLp4/yBr3NfUYhANfw51hrDLd2R/tz8gOAYdDzJDsyghfUZOQkMWnWqu5GP+SDQySBFExszxoFlV5Gmn5Dujm/H9+1Rdwxlhg3E0eeahbMxc63nFpEmZ4qyTVNxpxWmrhELcerhzJWmh73OKRCurY2jiX4KxHQU0WPCifXKgbmsb3YSFvVUx/T7W6cEqsRJE6TMI8AYedH54dfTji+OTNydXJxo8ql7s2M5UAK34BAzR7kmMfTiqyRDMQgYfWEmJhc4gOSwoZJUhhq6UzZUDqeyfSuDquVGB13Ap3wsiIzSpa1DfHlHfNmRvAeHCrmcQbfq6lHx3+d4uDSYs9cH/ug7Pe7MW4tXtXprvhjGhthMHrZohpfqTbIww6G9vbSm9EDqiXy/hEiRUOfjWtlJc75X9TVbazAni2NWFcmUcF4mZGRvjjFl0x5hLIEiKwFzkWZ/8jbxzmeFNJvjL80q7854SlJNAUAer7WtQLKGkvP2zNyGn54RaFtbdDOFWODo9vpBtocG+Y1K3RyDQruiFx06m2QmkRcYOyU6/36/SGZ8KYFobxaCH/6/T7Qx3+7sH23v9Pv+vg8FgMMhUTDonvIhIzXasrf9JMbzD8swY1EoekwAKoM4CU940ReMGK+FH6K1gujqJhRKQCH23vAOLrrm3ugW1ZxH+qodYHKaCKqV8ar+/3+d6VeQVV6aqopHpi9aaUayxe6hDITazICZkItjgfHY7KUdRaOocltZk/Y0OEg5Mj8wvFLwpwkZEA3ZwLUNErjtdcg02PviHFxAKAShzaoQMqlKCmJqd0gtIQN0pS395xnrTHvnXdWdg7Pf5dNvbW9edD897RPkMQsJZ5aDf5y1c+NXoLHhUK063Cvf4Ghat5UwynCdHLs2YEP6DuxQaGHszkdzlpE7HpjUYbm2X/S/GpagX59JSxES9/HS6hnoJ83xCcnpc7WOTmoW4LpeGDd4HLiJP5dIT8Rm0vXQr+Yf8tkIYHAUaqhCiYviAukLyyTXIltq5viANoQr9yygHG3migTxRNImVoCN5BzWsqpWqfCSnfX1+8tR9H+QchiyC+yXSun4O4TFPX4ESCb7jZTzWGqT+z4v3IQvCF3P2QvzYszzzUxVHS0PUNGaehuFr/WG7uIsKcNDBodm2N0Ko4M+X9Uofe5edbufolxOV67/hn4QUNRpbdpS1xVbTWvnmHfEHALMYW43DI+qShRcT5tCxB4IU8dxMHOaxd8lTtjzTjKHl3H8vB/KGAy6vUSW49AMbosv13kEZEevFEQ+qFC77OJgCqahpN4IJnsvp2u2ohMJglt1At0vP1jLcVbyNml+6+CzRy3VoPSDpPaFfpdg7vRv8In1YfY7gmFB0gUJGYxBADx4oGzJekKNfTsqOuQhrWAYv8Gqe9BzJUvx0Y9Xl8Q+qKokYR04EZOQwigJ7HEf8OqulADjBDdxa3EJevnFZvxJgeimU2DzJmKscy8wgtYwNyd4bySY+kgpqwKhfMWwNFKHT0SRJpuB0Vzg+wMsbnRcsgFx/24jrKoceOlVt1rzNvS4DDQiPBSP9LGf5CTBBy88KClopO49HnF/5lA4xKD+d04DOWcSCSp7yR+xx12iNucN1IU0ppMFihAErRfk1HcHrJdkhD5egrgu5O/gh4thzO+JhkpOAhTNmZTN5hv3h0OhvG/3BVb9/gP//txX50h8xDSIWjOqX8DMfSWjZUsrWwJ0X4kMPsCBP582+gvoIYVKTToGmgryG/TJeN+cBeaXfSUa0++Lutu6DSmL1z7i6CooV/zC4PtVMGEoFzmUQn9XcVGClSMeVt5bXeXYhK97pqnEPJyxe7nmiHKyTKHP9p3S6rfJb9RUp/qW+UHItYlkGfdiDqk9rgx7UL6LerP+EzpLK584YT1NS102iT+fi02AFxCb46JVCqbtqC0n/GVKtuzqztPmN3J9ZFLW4RCW2TIiKpG7UIIBfo1Mu0RGhQlfN2kJK1VOdx24tgEiciNmz4KADEE32zOdSYMDAQI//pL4feLf4T/iew/jPFjMhfYJHImYj09cCsJCTFShNh1GgpmnAOLjCOYr/C9lNNm5sgDBpboWjhBya0Y7etiRnEwOqWcWvYDMK2BTCrcgdCxh3pbHJhJkg1o8XIrLOBHPVsXf5301ga3bJKitYhWCSe7aJIofCB3Wps/hTRseLearxlJ6HMk0P+mXKm2WV5eAcaKOez6ET0KrHSUyzHjNGnmITCaYd32souySHeVmohayxfkJTxKrHNYEI++UIi51pLOM5IV/6VaS1dym7hnrKVll9wKiF9YaWR4PcGjmVwbEifl7bUUwuvPVcbE/vaItqeY0JqIZudvWEo5iU7t9MJE9rwU4EhJHuQcFaJFlbU4m3mayb8LIR1njT3dpRYLPbBMMhSV4RZeEwKfRBdLMUWF4trR20osJaObjb6waX734LzPIXHh6vAtAWWBWQPjhOn6hudk+ilhdEo7G2CwAkpELcGwSFSWjHNWV9JDeSM3uBpaPLS5gTn5FnNDQhFg4GaFM3pNeQhqZocp3TxNZxMbVXfJdQeYFdLiP/lek4OKTUanVPrKYCoDoj2lotu09dfiyRA1YVIFWbxUaI/LqEyBq5UX/qtJ7Iezx5TWXQ5SRP5KpNxU8ZavQgJpd8XJPOJPCWj1nWuSE/0eyKgHIqnuZuPcTfG4dXxSEL/sfywEGFddxKAm3WjLyK60T1zoj3Htg/o3NjyK1t4ciww9HEg2yhkeeOFI5aHnYpl2tjRRB81/BcDc9Ioy9b8QwdahvxjzWiV8c/dJqrIO8SNGpYR7JDLblHMyW2TsGas5CQKatUsFahyVq9SYolG72poDd9oTpOe51EHoEldBNVANQQGX9IEgNRTS7MxetTg3MO+M+gUwQ1mVK0KW4e25kTB0sFo0t8XoXt1TxrxTXxLy67nFSmza7n+8BmE9W/n5Z8aOC8SUPoloSrrFACPsWiT7y2ApaDCbx5M7B+sc3Im3uON20b2qvCVemI1VMFFE/QEoUOBsW/eSqrZWAniCOo0+vN7RBOpLoWDVXgF6uOIPJPTbh0UrMCLkcDR5VJ9jsHQ8nB2+BSaD3FXihHp5eHvLQYs8gVLyBM3tjTGURke5Fneg55dvXmvJKZSZdwiStYeoqD7GG6enPechWxtloIFAippsHJYG+bvexTY0InzNje3d4yxuOxaWzTPrO2J+b+9mAnl6CxWwTjbubZD5n+xr8nHhpryIErn7A0VeiCRXHggpAqBNFEvRWvvBC5Z5JVyXyiB06PK92b9RTO2Ov3M3UzzjzoMxCxBBvvL06xfIZaWayVjMUXULbJmZy0lWbloo8OG2I3oFzPB03VnocmkVULcyRLbUYtoe1OHS2VtEa3jkOUwcDV8aQ1ToUoWqjBrp2vKpUNC8F6hGf8OAtZmX2B+elswgKs58XlDR4aut6UN27GfOc6izJGnyPXJUOZJO5HILB06vKZSpjiJkFs2QSxLEL5uRrJPdlclWu4KlUu3npN+N8F48xS1y2fqt6gYsFRwL7i9i0bmdqcQay/mB0nipA2GApB9/rjlBs4yZTOrBo2Yp80pVOLQ3WVLoqj9Py9OM4Lpk2G+TPPbTQfDmy6FN8LI+qMcgytfHjg3drZIsmlY/F6CahTyvZy46FOOdMDPbZ5f8RSMkoGVNCPHFNOOHJEGcUoz0vxK8eU0Ih8XEocckAZVcjn5eSQGVELZx0BJOOqdl4Oqt1yObBir2UoiUxMaq03918a/aEx2LsaDg/6ewc727/lpx0F9K5a8iqbxXLDkJnKu+Ut+riUtxS7VgVEvHl9WzQSWxopW1u65eRmboKXsolEt6kagZZLsRMvdnUFeYtIrKspNNjZHr58ub+/vzc6fvf28PRsdPTurfHLxeVZRzZqZQEksFXJdgUSVAxDbriVb4XU7bjhtu7HHd2Pu7of9/I/Yk+z2F3oj2G1TgAx7sBEdfXCM4/L2ac6poKDKsPKmagyqIyPZoeUsihlWAk3VUaUMlRlTBlPVYaUs9X8oCZg1zFXdWgVf1XG1bJYZWwFl5WjNApDpjpHQm1dcuqavcyr9fQUNCKnoAE1BbXEFDSipaCOlIJ6SgpqCSloQEdBQzIKGlNR0IyIguY0FFSRUH2yVBVjNR2buZHFwPPiB97MHtvCR4wPgIDDCQs0j7g7OfOAM3nNZPyBdjL+qDAZplQxc+ZCT4tyCleGVFB4OqqcwtMxZRSeGVFKL+moEgpPB5RSeDqkjMLTEeUUnhvTAOI6CldGVlF4OqyWwtOhFRQuAheWl7qEE/7l1WD3YHvnYLj/W37aJiKXfhZhrUAqrp4BRxYaOuaMAVwmS8TWRNRVZbusRKVILOp9khFIimaE0SEvTnjyic390s49ueKs8FWfVjdgrGI2/08EPsXeX/6DH286Hc1z7ZnbTRdGdGq702RG3sUrf67azWmxuScmzG1NunwV9uxXdYhGFzd1oLqjY5vRRWNzHBVvZjlJsSIuVO3cwfCxOqk1mdFnvBWmEhSRf4QtUbE6XuWUhy6Rr2JElQOG5gURswg7HJSmiKH1cx6nsn2OIF91xRWoPOeT3wMmm5YPvIgdJV5OLlZ+plhJWPm+YvGtWGHg+V7IrKMZFK/VWDyhvhuFJmphFMRmFEMvGF+8hLgmJn816R2BWxG74F9woI+mD30tMbhANjjL+p3UfqOlMZ6lZoNM86ME0UUnhExY0V/cuRoOxYPrArzapjJ6pZUHDPLujvq3Si/l5Pi3kbWKPbITYsq3tk32cVTwNSTvFD2DC9ccVfotYEDZhKU965TwAtyg0t7KaWEHsdDsnmWwpqI+3boMDWTop+AQgTa1zSlxNdrZEEkLIuGSVFkv+vptLDmppVi+9wVxFaYB1RcXp2HqEMdkOyz4lQaygFH1dVUqgJueE89VclbCOieeF9VY2HL1GNmtrpkbSuVaVSFfZRDfF6M1u5zUPueuyrSWXjPwAAkj3iq0EZVX4aZ8qdh3XPtO6NMm0UUZC6r6ekQzDQ+SR3nvH47D5tJC6W2DexVJYjEJJsQSmm9QKSpKYErCyeqgFdIdHy3h0ZwT5P0gWjWQ6My80rJCyZURfPPQTJrVQeCIHakcJtc/Lp5TNwnmJb/HIcR9iI67icTLBTClVx88wegAlzqGKA5Pwng8t0PQ68JXxPN5Jy8casZh5M2h+hsfGhLqWtDf15tj6DkwueookUPLIlw74SJh5BETlBYy9seGT10G/UsDGwrC9HKtGnnchHK/KpVKYCpZEevfUAWGNyA7IHASyedOPhSr7mquRK4uJBdUCXIYR57BPkUBxToyGBX7z8OLQ+yaRmxoq8jC+uKXLGJmFJI5dWzT9uIQpOhPC4G2UIsVRXIoyzIRCg9qRCa4VXFHLZu3iA7jOQt0TWMLsQfJCU2zXVK5pMHHb+3QHvOd5y3wJP0lRNUoEiwBQ/ytCxwFtBehOrSsUNkW5kIiRchbUPOd/C7kj7BXEJI4tLLl+TNz6HYLg0Y4hGJnQNtisvRQ0iGPt9q+xbYh+LU0GItnBd6wRfiKYD9Ri5Hv4PL+rku+E1v5XRc//J0C+3c98k8vJnO6IAHzGY1wiqrK3y34zVsW0VPXj6MTtFl+zvSq7peKPirhIrqMhGwNLcEOd3byh7GsGFwqtWY38J1kSb9OzonFfMdb8Fa/dBqSZwmPgk0KCTRHed4jp5LI+K8Oo7eMgJ2psitxNdwVRpsPmZusJCO4RMBOEbqgAX2hYLEGaxrjUKoDSb6pueSOUbQ8dJzm1gsujdZYLgpl5eRbpTDApfe9Zy3qAVjDfQiMnOfRP+aFiGabMAbTB7N48TF1219EEHzPAn439hY00F2Ln4sIhVRUabppb5VqMBKIb+R40yYGLJNCBt+tze6qLgkGiJsBk8QO5QQyVJHbiZQcHpmKTYfxRpE2LiHV1N5dHBCTOU5iDcplQNhzRmgE/dbNmZpqwwKSvMkBFXiqbLo32N17uTN8uYu5UEVbljbVIYFPl7Z2kUBzN/NyEOUNfjWl3eRM/yPrZooAhCYwIrpHlcYM9VvvRY4pNwEqicB8nlLFN5d3V7QASX8JWnhQO4b4VGlN5Fymhk1cZfY4jH3fQVkAyGtWxULu7IhTiBSpT/NMYx7z2N6QCBZI7OhVCcMANmFwnQlRJQylSPweFlKukRmvkEtAxvCUfQJRJmBWbDKCwhHxvdAGiQ9uQ+KwqR2Ro1MpTxbNrHlDZYl5v6zOBbf4jszUTtxCDCmzNuNNAkffxmRgGurkdL6bwGYE48ANXRBK+Bu8QLWYR1RCLDAPDXbPaBB4dzh85oURXKwEXS2AaXrr2VYe0TrbdUURxVLrdBkvqZ5LZ7oupP5nD75+QkRlW9iarVtMXQeqYP3L8ClJCaPQ9HxtKiM8J77n2ObigEyZywLqkDNv7oXyyhGiupDlXiWD0sfQhHpmh7NpTAMuPqBDv6ZYMfr8VeMelxW7yZMcH4O1gPwxSrtRFhcDA2TGNfAn2+WMLHGGyUo25gyKPujzp00nDu1b9lamK3D8pt3ZAZjY0Uc659ttq0ve2emz/e1+32DDl2Nje2BtG3RvsGtsb+/u7uxsbwPtlNEhfK9e/Qjj0OeaB4+pAGEpzZMYZZsR5lxXOa4s2grduWEOg4KBQGh/WiiWTqcBm/Iu7PBh8kfM4rL89Ab4bdIdtOgtTX9RMpg5r+M+DSku8CpaicQ5Gi9GOWdkLgUf2alCRILSIl5G13eoiTKIgqdqsWi4tb2rTSkTIIXV8FzlaBoBCIW4JvKWrCK8tTBt6yy40FcKYuuEBTDPd1oa9M6FEKwthiGPlUrw3aycnWPyuftDK5pl5SzN/ZzQW5YrZ9m/5vbNCas52bp0O6tIr8jnChJcga1nlIuCdyTRZzQq5wmcVTSzgtp/JG2GTXRPMbSF6wD+DVnkVS6ev/2t0+38X/Bf/wX/B//4K/zf34T6Ds51VP4icyYSccJ4PIFaFlpHnaIkDvcLjjtsZYuaXOJTzxs08ne+8kviedRkYQqQuumi5dd0Fv/UzAR9Nua2K/4aYOuC+rUNd3YLa/sjpkreY/7lxDIDS1fjTfAv6nBqqXPI8Q0v88dJFCi0UkWCGeqzbDi+c9AFOMHMqe8LLx3/ajOOU0bgkILvxX7bWZIJfsC3u50Zo1gApd00P+JbKjShSR3aep5LfCud53NyTBdnKCvwrfisBo20YNcV31luntwmLDtNHn3LzpPbTZ2TuGysRkLAoJ2E1gnSV4jqFxTDiX1QlAZ9gj5CLKRhMT+aKVfySqx2pfXnTd15HtSEc1MMkPSCRoyDH74yxqHwzIa8I08RtfcXP7elEnUNb8Xrp9xqU+ClwAsDLAIIFcdwWbGwQ9/TpVgHm+BbH5a8BMt2TkVrBk26i7BiP/MMp3Y/l70lHwn9gt0vi/4mMkjuEm6F/l/AY4eWu+Zmc5OH01gjMN3rQ7v0YascB7Y25Cu3Jj6uCvIQyn81Bxo9YWuMVlCVm8iLMk4EnXeo4B7iAMmXdSsFJKoLrIIwduEkWiJrH+L+R3tbFtsf725tj8fb+7u7e2y4T3fNXXNnt7/fN3cGHc0nZTA6t2Kf5BI6ysLS2d3IpxFYhKvV+DT8vHg6HWvFOXLoVSfsZkDUoDrnDi460XMe9EWPgPWVZwAQYbsKiR2FBI8c7y+GY76zMMABHNrgwCa8DFtI3h6+OT06fff+sksu31+eJ/8+P3yLEcOX5+/eva4XGW6Y1qTYXhvKOdn6RYfvUrwJ4KvgQ+c0iGzq3FcuRD3ZFJbZNC9iuakbJkgsMzkWEuCXKHcoSFyhsV6Dem5BO9z4QDc+0I0PdOMD3fhANz7QjQ904wPd+EA3PtBv1ge68VTek6eyTP1A4zSuuLjtUiIQfRt4aXnRC4reUTvKSL+obfMYe5Q70RwWivSFMa/tKRzcDioYjs0sAhw9SyprygVf7p5f7VKvMkemb0kJOpc82M0k3eWv2/JkakG/OYrPrEKz/RcMw4yVoN2kcUjbUOgq2weKJznjh5JT0y5NpuZDdSmtjTwQOwVwl8to1cRIF1G+luz9mrqtgnBSZqNBjqbEZ0H4WfJiLb1hcovIMf6UrZXwyDzzLDLI4sJ1x6BRrt2yWWCFzaguDtBY9WhZR2AJRaSxqaEufewhs8VK6/Tdi4z8SJlozTPPLtPCGJnUs6RHHAD2zKdwnnj2oEwq850YrCQLqb4YwkzDJ3oOCSxCHrddwoV93oJmTdlhcCrBJSCSw1ZMB6tP+GrI1DN1cjLZUuvKudJOwgW1agn99BjCHKhLoNmMojx5wc3EAUMKDaZMWGAETaZ1UewJcT0XiVR8TCe5F7QHCZiZiI8ttrgofpZVd8hl43GTnUN+unx3Rny6cDzKjQA81U62pbq1KS9/nR4CPuDw/LRHzmQ5mBl1LeMusCM05cEAnRmhsHRZOWv9fFzOvBY+rtOmGtcqSXukVVctQXFTQUiunomyID0tFwip5JoW6ekNE+NHpudO7KnGlYiPjdBnJtiWCR8XB6KQUdLNSqeR6P07q8YTdP9dwXEyrAmGlsFQ9mZalgMcVBw39UoKdVgQjabmjCrdOXK/3rHxzPOg4ZPjTadiBmFM822fiWIMAZszy6aCxKJZ4EW8CkKi7lTJ7fkM8HzErbKgbm7ry+hI0N4xiyCSYZOsuHHUbRx1G0ddY0ediL4KRne8mtG6gpryRZI+32NCyMbduHE3Poi7ceMK/NZdgRvP2saz1sCz9uX40nK3cqskQFX/aBk/LadtkQW40UM2eshGD/la9ZCNBL+R4DcS/EaC30jwGwl+I8G3ioYrOEca5hCWifqVaYRZZ3atnK9NKGuS5yp/AMkadAKR9dwm6VV1SeX8VpWJZQK6ksWfp2rFJsxmE2azCbPZhNlswmw2YTabMJsGLYEeKrjmktHAnEGEstMoBnxzUW8u6s1FvbmoNxf15qL+ci5qKP7nBVpbpsNuwTBBcAAc43/1u4MPPXLOe+hgYw9umz48Jfy2JL53ByZMQOsfMQsWlTadfm9/D3ONuCFwkE+UMT1Y08jCqERNG5L0s7PFOLAtyIkNbMZtSsB9QulxC4yE3IiYlowDRm8s765Bot0kRtPKnEUzT9+W7oYt7rzAGgXUvSnutzIgwXZhRMDgZVhw+ZhbZkZeUP4V8bxsgs9fg1wWCuPJ115rC9eaCKENlzmhjjOm5o3GKAsSZ+603tGQxC69pTbyLnTqcSst/x6we7z1KZETEyCTBlLIZzS3QV932aYml0jLZQqXRnFAHcOh7jSmU0aSl7jDUnT3Ql7S5eAn4DY4t7Yj2x9mv/6aP0hSbq0YWULKP55Jf+jh0Rsu6wA3TYWcCTVZFD5vExGfdzAV7a3J50u8ywUSyo4HGpqLLpF5Xi7XBb2/IzaFml9RTB1nAeuyQOD0Aw99rwEqPNo7Lr1aOL/lXAuHr/FkZfQu3fFSfUuJdyBzdxTwxGGUUwk0ac7cZUSjsPlpy7OxsJIJ7AjHUwjWe12tsOQrySv/5tKf5YajgJleYPGlZkTCg61+aZ0tXU4p4mCU54dFcLeHhaKOypvapRQZu7Zw6mVsmixsgeeQv6AMLFPvCqWw+YsaIK4Cxs6yPVXLVPuZ7VgBc9dE48mHeVfJ2K0REHca6TaKMt1SpajrWha73CUmkFCCyuabGQWsstDccqjMkyp8RAMqj+op1PZr1vKsUX2/NqWQdaUtG1f7W8eHGtb+W/1TbSsB8rebpqJ/HZ1ZL1oFP20asz6xxqxfgr1v03n1i+u8Wra+pTujtjJL5pW2aCYYJZl6SBSBF09nRWti9Tlu21a1eD8sUyO8pAK4CtipqxBtuHAj+qmqQniN9KkUDPchlsceScV6BHeW544m1HbioCnsy2tZ+c/Lu/JzWinnfiYPEvdZlpJOoPGv0DXhhhOIqDrQOX1ZJWkeL5foCOWR+ofnp8SkjoOWD/HGJHYacVkRVYR/aXru8K935U5pd71YlKhUpNGp8Vh9HUzyYh4Cw7RBl4kuLC7BprKRGFc8vfn1IoDpvHK1QNaxK2SrkZ9E+2m2BaKewabyXUgybxHlrQbtSYSJURtXbc9ZGNG5L0WRuRdCPKTJy61JN0D6PR3TSvyCII8akY26Ucowhv3httHfNfqDq8H2wbB/0O//1tHY7HkQruYYQKXGWxakAimPIkw8cICiejTMaGCNxl7s6vwhqeXPYo59y4IFgbLzcyj5jje/HYqSkdSyAhaGeBrBaj6nLuKqmb2PL0MnaqUQyCWJNXO5wg6y328gawE9Spuh4XgmdUrSJASJ8U0GsT6xNPK3uOyuEmCN6Yu5xvtLJcgw+Ts0Ti7Rfm4cnwDhBMbrC+RfxulVp9v5nRo/nXe6nRvP+Dv87kfG9/C/f86MozP+v1e/4kGqPDbnyUOUgAh0puIGvDAep8I3UBELe+TvMCYOWT4tJHRiaNXOetMeue5w2180ctldeN3pkuvOnAY36Ay87miNnIqFKhmaP4/icAyMwc7VoH+wJQ+HAHQMlCJ4q3QOKK/tG4PhVf/lwfYOvsZzNBIol/kWN7tqPpU7vuXKav1FKLVAhffhfOpXW/Ip8eo6+FQepzmmnlQqUQiweMy6KuIzK6u9BZKb8FsQeGpJpfSuvFdppspMmkgvCpKSJSW7qyFxTXeS0HanmDmnv9s17Gq12/5Xfr3YofoRbHwF2gmjAbOWPjcFtlK431U+U7VlePclg9P7N4smALKRwaGKrWgRAh3AhAa3PDo0/DLXf1LiQtIMh7OSMSS1VrXJo2TsWQu8q3EqzJ8tlRrJoSsECiy4S2wud8hIEDsk9tT1Ama9EsMKAhhaZ+bUpVOw3DEogRUxZ9ElIbeUiHlDacIQFi3ENj/j9cR8b+ILOZ1g+mXErC5Cm3/HAtXd9aJGWYRfkrwDP3NS6xE4nnzb0+mJzF+bU18s/hW3vEG665zaLond4umolXoKEo1GWslLIlVSRt771YC3eClXAQ0xdtM/U9JsxGWqjnPRa422mZDODV5hzID+UzYUun9Ea0cdOMl9rdoQpNK91+9vKQpz58wjgRdHLNHI3l+c8madK8sRjeHMyBV51GnS9O7VEtJGePjQhDoU40QVupLxtjvxOk0m5iLI0yG3p0IzT0q+LCMR+G0UmtR1IWORRZLX5npmXB6+JZd8VK5uJZxXSv703AaCJUsMzlX4mDCIVmJCQjCpS8YsEaYIyltcn8XR8OVr10vbeYDzYoyX8A1v23EVxGFE/he5pBMWLXrXbvPw9aKkIIFLXS3V97qKX7VIhfqziChCq06VjAltB3GDkFJQxpSv9chR2uDAuaOLkAcUU7T8XLuiX2EikvieHzuAXrywUM7KIKZaUi22CMjJ6UnqZ9tDliFHPkvp3ZclXWRCD6f5fnHcqKZkX1PW8OUxtWhmB9AQNIgWUkFaQg0q54CZc1NCbA/NTdZz/jSYa3MkS18vEk7A74UsliVysvcNThE2QXqJM+DMU+JScgZ5L+AgwBKSEE1+5YgLqHvtapRZOyRRYE+nDHRHEYxiA/kv9Fy1Mnsg43LebhJbkcAM5TtRX+ZvpGE3ufu5/N7D+BBrVIK7SxahLQUcDfi/uGYSMCMUFabg7BcR1Lt2YY/BqewsXhGX3fJKGowGqC1KThaSZ0Kl5n4MvOefN7yyeaKKhi+9pWjzTRAkBso4bPCLCHyVGsgUlZS/PUg+WxMSmup7jQ5NyQkBZtH8cJAj0bGcX/6uhuIh4kTig69+jlkbnM0/7Pl6S8MbzGC7dlNCiF0HXmGffAj2QAu9O+cDIaOIWnPbJcy1fM92o7pT9pfkP9rzBUCOcO81oi+Xq3TGK+FHKKK3DhwesZDyb/l3WromdhM334cH5gBP/Rh1O7CUke/QkiJf8BiMeQ6FkL5bVlfSyY2Kpuays4qfTm/rIgCnybPEkpHDvAaE/nCLDfo7k21mssk+tV6adGtA97f2hlbf3NrZyhLt1rDY2AqdBYbtWkCHXmBMGLPQfWLIE2Vw61AbwbhSeNB/UYpmxrCTE3xXnux+xc5cI6q2QmgD/JebSZZAjW5nK+FYh5VwaStePvZsBVrIk5USnbTyvOWqk6AN0Hs/rNkUuP6YqFKvoh4D3Ns3gj+KRvFcVPISCFZnUGI8l5gJX/38OXOLZNEtA7BhvBokLbMvkxG42tFA06ykCZqWsjJ8w8y0sbteD3nyN0c+mEw03pOlGLTYVIiqtS0WqIaBfGuf8obCIHO4EL1um4kR8vQY9CM+vXCP8U8AZ+yRYzuMbNeMpNOIXbsQCkw+pt/5mHYE6oqawyYNAhHLlXwolUWuXS5Z8FRDzMP3YhDmM9KoNqtPX68VfpqwwDUEKhaGOETi26cQC2ct1FOtQQyUQxWCssRBpSw0X4yUcbUlb5SNEWAUvWcttn9zrh/uXGuwL3NR7+VoS1BXP9nqeQYcyhjX4tm+dnlIxDJn+9pNDzdZ89l+2DOLp4dvQxmaY9f+I1YNoYkImQYQ5yHRrXcplpGFrwUDqUzagmVpMrWkkBLBRVPEqraouv7rzMXm86PYh4Cbeqble44zigONzUZkahoBcyhmZsFQoDcsQwClSMA0QT6+kAlTL/6dYvHzx2s3DqXxLwTiKd5OaCUAxgM1soVbinDAweqD1y5v5I2HBayA2YsuZFO0UI2ZSSHSlrvDUCu/dhO/1ozeMrLw4kAHggxLwTyqT7VGoxdAX86LHNZfDIYvONzwz63tnbJ6Lw2KF/8M22eVTMA/ki3XnFJ84pez3Wh3u8lNmc6n1NBNSKKCk2bJbHNJPuglmTvja7ocuSCtq14lB3Id6vS45nZpxa/a8347A44Ollafb2K2W7OhLmtXbAevRu8piC+VmTlwAYECghZaaF+SJIdA+ijmpS5UAaap/79J+ay1Ww449SyjP2IFFTsc0SgK7HGchKAsM1duFj4xlLeC47naxJlZ8mnOy00p3q+LL2lOKJmgk3WSy5rtQvmklS2jvwNZGYPhwXBwsLPb29vb293Z+i1XiavShAQEONAQkjDSFegg/V1uo/glsxcCul1jsH/V3zoYbB1sbfcGw62t4eC3dditclxE5o5vOMmGkyzHSYAFSFkwjOdzynsLLDGtbib8AKhG8kGSTl6ZUYujkoRdPnSMkXKzhQjOh0kTjQO8HxA1dy7i4CylzOLHLABcVv4ITtWPmBr8sXftXojCh1CsE8p9knAOsuLE/oSZDBH8CH3Kpl6wMNAJKYELr91ntsh/tzwMhn9BTs/JC/L+4o0sFdGF2htwYKBYpncHoeYzRi0WdK9d+TL+9yh2I9vBI4m5bV3CIrP3nAj5Cbve2Oa1+/G9z8tz4ro/8tgm98b17lyCBVgmAU0KdAqAuUTZu3bPMFyDmTPQsgJ6J7ANOlRiwCSxa7HAWQDO4Uss6F270PYqLbKBuXagXMLwWxaMaWTPxeAXIG6n0yKOIOUD/cyyYbo3mYgoEx7n8JzYbhgxagnVOmTXbgnS63S918DuTRk1gbsakDkvyJnZK7FBPXI0Y+YNVzXxrgCM3tmOZdLAwuZCvNQIh5T3iKEBBguIih3HZ5doacFEWJ1YqCNDTUgOT2QWxgVB5qFL/XDmSXrX8mMZfPDWBrTz39679mTB//nGoyIW4RxsI1CLh/8J3YJFPzU8DmW1Lb56iaNg1VpiJnUGdcIVgMvO8SXJRSU3C3TjsUNZ3hKPYTiiFlD1wbCb/BKwOTZ7Qlj8ZESf/5U87Xc7ceCoj/HP9DkYCG5sSH9C87DjeHcOfn4kvoRfYJ980MFT8Srkn+LcIvtzYszJLKFzsIWgJTCIkor6Y68eu6cgP27MQMubgdZxHnmGK78ZsyeSDNZ7Ju+BGgH4UQI8MqrRIGeFB/Bz7LCDoAhxAnZwdWdyog6tybCWm35zSJY+JEslSrQIIMglJd7vOVzbGYH+aFpYh4Or4eBge+tgZ9jb393bGe4UYX1fDutQwDosg3W4fzXYP9jePRjs9/Z2t7f5/BWwDjWd25Y9VEWFu5wWsyZjmT4m3+c5zVTjTEwptI2Jtqixt4VMvq8Kt8vCUl8VsQAFJtdji0UMWBFFJ8IVYSmR5HKaC38AqksKlFAVE7USxf+UpQiFRhZ0uHbhe6oaP+bqvoArmsFZ4UAJTRNaeKMb1kW1kVFzdu0qH4BRPXI4xt4LMhvhOVdPXE9+f0YxzRvvQEt931lI3VuMREoHwNgE1El0W4qFQ7cL1rt2L+Nggq07Q9thbmSI0Ez0hIZQCwEuChQmkWhClmpLdgAGASlrkjsWMGIFHibvP+NJfoEdQU6gEGO7REiuqv0AklrQbADNZ70YquKg8idR5njNMgKyknqueWoEdbGgnqWo7R55ggJT8HHz7FCgrkcuhRp77QqPK2HQ73rsRTPyFy7BowL5Fym+v+LfMKhl4dAQzTrXrhgsH/PRyoh0hibLzOkgGu+stpFTXk9p+J6iy7R4o+1XVJ2ozSvtvvM5q1zlMi340VfZgTCcIFlLFYqM44hYtoWmlICf359j27y5tJ1bCKgZB94NVGED29Z4Ibp7N9lXra6Xh/KYPyC86UHKcaaON6YO0Z05YDk/X167vmJIQaOHZFyBsC6F5BkYLSEPrEtcessC/Kc8nWA/8gMvYmlx3yKfI8zF+p0QLFESHaTbTJ0+W+ocDmWtF8Hj7maeLEQrDJJQ49cBLrLAtB4eBCUiPEKWWML4EY488vPlKxEc49sil8kMPPfahbZA2E0ILqHYb7EinSpezPfExGhuvZvEmFEVh0yTTd0n/+d//3/C0CnCLenYC0SQCjiPExKFQptUFmYaU4XDNYb+c95kUOKkz9+WHDYLiJNfNYKBC8ur1ZS1afg3707uTaQh1C4hhsbb41d+5fR85S9wm0r5J8Devto3cJ9aiEWrJoIXanNka7PWK3QV39VXRq0teWp5ZgyshteaEsFluaKmmcKohWdpf7G66DUs262Zo9CWIF82tUj1POREFJ9OWGADZDaLmiyLW1kmyg8KhPJa+CO4TEriQDZO0iflJF1HOENTC62OQDaWpydhedKe3ZzpKReJ6xJ77ntBRCF2NWEj8PY6zbrCcJNaxhA8bl8qAMRumSucodWgDTWgcWQ3gIwP1AO2RmNSuiVhfbpPRDXFkDAXH+vkOyDHykDjiE4l+09+8mQZf+WrxKt2Re8PtybbO5PB7sQaTvbYcMAGrL+zTad02xru77wsuT1KQzoBXN6UlBdXEiYwy3oh1OAy2FqE17dnVcsVqd1wqGXjiFXM82Is63J5aGbW1FZsgCn+MscRA70QuuJ6UTNTZBsiXD4XZfkclHpoyiXLJNfoHqRLUZhHn/0LaqQWSxguY2u1pDo0wJz6pZ4pAjQqsFKbtV0CYTbhIoTrs4p3yriXEbzfE++XpSRtsmEeIxtGX10lzEQxCTuKsNTPPVwq75jK63MFout579q9gjXYITl7d0UoiYAZudiBk0bsIKUlsCon5OTYLuuiHRFTb604wCBCYSwB2z4ahalpMh9MbXaUlCQWoEEB4sh2HIisEzFTH8Ga5zjkoySsj0QE582YXB+aK6FkSgLotYsRYuQZzmNDbJ4XyEDD53WbosRr1aYQldYpySI98O66yO8k0SsWeRQcrt0skrEcT7roEhtXIV+pPkWxBUtXuNhGrnhQuUK9P9YkUIgpuV4wwtqU5ZJ6bQamy+50WZglN2d6tCRfoW6SsZkNe9MaNes81RKi3EAeJqqHrXQbSwCodkgrAKgD1wlAmRda+TQfsraPVhjl2F3GMFe77VnFc1VRU0/KG/70VRQPKQRm13gXRTOoarN6v0R6FzE/VLVQrR4DXZJccUldO7L/BEuBvOpx5CvZ8AAFBNdzDR6yL9ogNdREFEvFEhsq386pEk0+jDIKnURYzhZatGo9glAfi7kWBkg5WEs6CdxwIeMBZnlF+mTOKBRYFAjS94ejn/iubvXrtziMtK3j0r3Iiak4vssjQegttbEklbbOnAj0/0NmmztJaL+fDe2HTvdCnDTTAE9WFeVfJtinYjEUuHAYtqyE+5RDQbBgNyhX3aS/L+Tf2NFMdk1Df/kU6ka+IjrhWMTASPw3lJTJMzE9Gb7Yel4qN1v3cdruM6NfHgvlVChp/gnv0R6Cpjxuc3U9sGit3i9LXlo+/JAvF+g4zJQS8xr3kX+rrFLfUhM8yn5x93qD7qGxq6khfuVF1IGyQSLMQJS5TWyIQpXBPEE02Chw8rcy2jF2CdZdDNJ0Ak+Rcdou/Nt2MQ4S447Sr9d/AzqNab9zVliJzwL+1YbzDyFQIAK0jCpxJudPbrMkHpG6CxIyGpiztHJS3Tf76Vd9SYPa8k5idTgU15XEgoiwHtE/N2RRNRr7/WIowirH9B7qtX7pR3TN2DWeeBXU6u1qW/u0ONujVDy9hzbQNSVPNfu/UjXe8tNa+GYYsqi6TNghCWdeEOmMVHwqgpNUV5A+4iN3+n2RRe2LzlsaaMqtJcLxpRpMMiCQI+py07hIlSYOi4AVk2eHxm9dQo0/n3cFSw3Js77x8nkXXR2YHB6aXgAV/kfPq9cyX4jmlzz3n19L9e3rtWvV+neu8Ei+AQVCKHY4mHtCwEkSkgmLzJkIsq1s4BgHdgb4WRT54cGLF0pLhxe4jN4smjuFHRELxe/XM6H2QV5lVJjWcUBNp9VsSbGBloFOBRoEPmL/yUbjRVR2PcPzJKoiu0kQ3J21OuickP3htk4T42TREmh4i1eGL9vCUTlD/YYv7ZZ6kOZkrHTvazaIG3c3u7TRfjbaz1q1nzXFUWpZwBp4gJ8NQm/U/3qJe7G+iFW59PM9DW2THM2o4zB3qjUtJtHZ5bOMYZaRWTNLrkTLelbqB+zWZnejiAZTpjWgKmBCl8YDBNYImWmY1I/MGS0BV+7+KIIEr8osikKWQaordQ4Ojg7Pr45+PBx9/+4fBwdVlu12og1/YwnxolKwgD82csW65Qo/7Ze4OkvZSBUbqWIjVXxZUoVgAKtwgNQ8MeJQFckJjSe4r1G2DbzmMgxoxBx7bkcjvBYVzy3k2o0SgHbUP4oXPZJDsMj8ZvvJnHPq0imzMo+LX0aDDYQoUfzzjk6SR/Dv9OWSyzODp2aFl9fdIq0WrCbZmJusSG1WJEeglPSU4LyaEBhTx6cwwh1nwpAAz+VnhVwI2Hm/CxH569MAg6sheBdCnLEhBrAWzPnHepe84yi5Wvi8BSvW44w8ci1F0+tONa2JYVglLRFii0DzZ9JCmhxy+JRczzPWm/bItZBz7+jkuvO8R05c2ApLxn1fd2Qby+sOMR1qzyWv5FwPlvvTr1fVMCdfUORPvdUza9hFsKVNLYVcAyQ2Wm8L4NJ20kLPDswD4bvBF1hKjkgKDUQN5o9+v9Ps7SEJ7anLLFiToKtY1MehcTQDfmWmbZ34RsuY/epOk4uf+uwfh/Y7+6e//zL42X5z9NNs/IMJf5++//N0cGb/9LLHFj/tjoc7zunvnk1/vOibP77dfbN46bAfXkfmD5+cN/Oz2/HlS8d0f7o17R3P+mEQntp39m+/7tyYP7z0x+7PMKE9/uHl7/RPf+ufv/4TPuSwHw/td7+fbL29+ufi7Z83d29/h48J2AqsQuCmGscbrWRtWkmWdleSSkr62F7lzny+R6uGXi02obCQVBBJf+FTQVxaIxEgtRg0DahKwRj2B9tGf2D0B1f9nYNh/6Df72HSwG/VqU6pbl3KC2kYeqaNwj2GnuUYY2uOdvDixd3dXU9hamUg3oUjtPQcxtHsKGAoBVGnAddqHwhasNDo8kEuoQ5KYNBQ8L7379XeH5rVxxhspolxax06V5wjZIHeSfnGm4JGhk3K1Wpfjg3Vbsh5YLs8nv7w8uj0FF2VUPAqrSRNTV5y2PQczyXPLl4fkb3dwR6IGGPbgsQc/kQWAwlZYNiW1mGpiJuDfj/Xkre0obFwb6unGxGZrDkT65vB54c83VwyM2DRReOgvHXQDq8TFIo5srvzTgRyEkDr1tbWS7WcD6939A7qd/HgYeVh5TlLwblX0m29Ywo2052JzNkVc6kbnXkWC09dP46+hx6JDfdGV68GJkqbSb4CCRjuETLH2OSkPRpzQsYd2jKxT4rl3eV05rtwlC4FF/EZ7dgQFVwFJx/xCqoGBAuMamCuRTGBD0p52Y6DgvsYpEe+FmaReQx5kE7oYUlEnMFaD+CwJcc4Yedzwp9K4eeVrOYiKwcTNkKIz4gdqOBHeIG/gPkONdcJ4HuZkd2GCiXJpItKtyehyBjKZx2JovgNyHBmO1aQEZ9bry33TU41E9vFVS1d+yid+TiZTMxd4VkpdZXUXmQ3bKGd7sZ2NRNCPAWbUnPRMLobpdq0E0t+U/Q0UI+gny7fnf0CSVWIGX1uRHtOh0vmGEkaJqo7miU2ZXtqyW3JvXk01HU7UOX2vj7bemMQmCz2fwi82K9H/H0dmvUdDrAEj2yrkl/k4SkS+mNSiun59f7DZOMucfjSh1NmfOAsGfxl6eNSQnUvB7Nk/5dblARc3iSHUDjWpM04i2DfhV4pcK3TdCJywxbcujNeQE8ayIXiwbthkZ7KEk0VwIjYhxUQIGaABeQxwLewfvFynzSud6HI3w5AbS/s3xS4xxquaM6F0IzhefWWEL3Q0BhjYrniY3mknWUPaJlp2jVZqC8Sqm6vrNvBSzMXzQd2mKOA1ghUwT4UQGUYTQ6481NsNuQLu3cJAXY7tzSwqRvpUh55K2lRGwQQAhJuVsde77p+4bDgicpGli9xUNKd0+18gsJ6jlF2d61BjFKZtA5KiZB748slwizXv0ZNZl2CiWs42C+cxdYvdJywuqaEJZjj5654d7Q0FxTvz2g4071dGC97jqWe+DoJRzfJGowzqVC+Eih4C6w0w9OU6zVfvC3QY9k2tyF/Qbxdfg7kN/KEmSW0AhlptjO7NQq+tNao3Jm7TPswNDl6m+OzOT6PdHwe99TgTxrfTAtj7kM5MO7VLZEsogQz3PvQDCGNvAYWw4oQXIy1GLWgTBv30YAz4bnwHoDzIIZeq4oXYdHQg6DJZPRpGN55gcavcC6eEJAfZYdYCj4iz2XGHV1ApbgZ7oaLHVKTqnTkLS/8QfaG5P3Va2O/kKqUblcmqw07wmTbxYfMDW0olKH8BKl3DgtDI2JBQGGdhum5E3sKFUJsx44WsBUCr+0ktwQd2V0/Zr7jLSCkqcUx4LFpEDMxMpNjJG06uTCwYyz+xyPB4Q2SvoFeBQxFm1XoHzW2oPzOZ/GYlkQw5HsM1RPh8B7NReRXrhcIf0qigE6gQS2MOiCHb968+xXI9Ps3747+XlGQBQd2uh0+7kPRll1yUCYBYwasV80ZreUFw+2kCc2Imo6+KmBSJ1h0eTg8epNin7dDyh1Alz1v4GwrHLv6EqBWQnJtuVy347kiOJOaelwe8kAzjCyDKo1zRi7Y1JM9jzmniTwwDfFt1KFXRkMcdOROy52Vf1/+/fQcN9b3HNtcjCADrYr++TAIWHtMog/Y1BsF1A5ZWfdtGTfz7vyQjGMbQsCISKUPsbkLvo3BYxK9DIq9cd6uQzLfcXmcYlGQTht8k6BdkFJEp7pAZDpVcNgjf2cLDhoGuvJwruHOrsqfkZXLhs0egSNTwr5rxapirCf9pI4Y9JcxdWS4UYGouhUMN8fN8XAfHr1pwczlt8tOlOSFIoRT9kvjjZzn4OTUmFSreKHotK35UqYTt8gBsEPgVT1yAnxKMC/uVPZ9RrHr2xxq7XpuJjmgtRkrQd0JLGzpI9aA/SUM+D6FvBxhic1NkZ+lm3MkuFZEc8/3GZIXxs7qPPquMYldTo9BjAU8TSjZjwHDyOR4lHWPnKTMKQ5ZiD3Ie3/1qXkDwf1g7P2v3l/Tb/1XDXDDnR1eni7Shby/xt9BcIXiZhgbA5ERFuO1zDAKQYYl2qG8E3jbvDCVLbf7L3drpcsUJhheuCfryZB/vf0NrKBXc9thBWZ+4/IxovIbESgnYza1XeyThg+uBa/rXXeS9Q92t/bL+LMWShhfgPPbuTwEOWbOTHafdIf9krWR+O//vKMqzEZQTVAUv9OF9YqnBMQqPFziPX4RAVmJ4KiwR07gEe9+EdEbDOk24e6svidqJa9ESvlXoX5OwzvCdpdbq3hPu9a5H2GDUlnHU4yFbn1OMk6WvGQJZh4ZE03ZFAjO7VkVvquVNM7FEzjQEqvIj3wWGNzFHs5sX225SIRstqx8kZw65a5dWsr4dphbsodZHgY3zFvPih3WgonVUxteXHOclzwTRZMggVN0WdApxKtcl2/scQD9gtvcl449XvdlucS2lN8uPADyMgpiE7puttgemg0DyZ1Yh0Z4s6DoFMrp8VQ6YY+czmVsJ5ZA5dGzJbePVE3oHSguZtLxCVfCO2GhaFhx0wnaEPQSY2ZxNJPR5RxQRETvr8qy/qv3V8Dff73KRKqgNoM8PdWcHQYdPmIX52ZWvVjaUAL8MZ5T1wATPuIKBr0iRUJ/AM1E3e0sBcmL7ymJJ81F/pAhyxZtYpKbF8lWXvhSbX4ImT+347ztrm7PW/scvqVrSOy/JFQed25dNEyTu48wjBSUxJr6cHZ7vrV8K5GydTbdBzJqrslB3MIbYDETa6sntrBUSF3KIPZ0nAPJvqZGKn4nYSQcX61bkz0Xiz6x95iL9qB3W3OnA7fkCERBexnUHrC/GCeQGToZi36JCmpZh8PhKZ3Wh3FBFL0L1bdVIwy1vXrWkjTZ5lbABYrYJL1joYD9InG38j7U5zQmZvX622mdjLzNSc07MzIN6TgjXI9/45wFhmCswpni3bIgsC2QBFX/BndthE/Nt/EVsfSHPZi6E1nwyLQ4S3wbm1Rl0evSKR0mooygRKm38PhhuP+/C0kB5BaiDT8+xY31wohXow4k0fvQyyRwu8QE8scmkcOdHVUNaKsEt9mi5JyLRUqcY0ua5pnYaUGMZc+q/NZbUc2nGEqfrZtxn99ZRxX5gpe/UAC+8R4JcLr1ZTPuwhHXzF9Dom8T+wE4B2TB7JyAAEELvCXRTGQOE0zCBoYpihgBjmlk8xAtLGGUphbPbMtiWHgAeta9P9XKJrjakUPHTFPU4g38nJTEw6GiQ6c3IZTANBwunZTGe9Pxn4vMe06h6I3o1weD0j69sE5e5gi6yHaJ7Y+oZYGZo4vdbbskDmy0k3UJlMgYzVk086wudDWOPNNzusR2oy6CVzScomLul2AblkoJH2ncsAWzyLM59Z9zqGBei32SuTl3kxEf+a9ryEy47nzQYpgn0ujzgKxbO/SCBZFjCG4Ej0Dgmj9KolDq/hUJvTmTA0AchZx31eXLS5iWX9Y1cjSmojq6eEoFNXMozmTgrlnkGX4iQU7qvjAiXjqRm5TdxbMUVX/5QP72N9Lr9Z7rReUgbkiNGNLTmBhjWwCgoUXslTArXvgkjG2RtY9rRxWYw6bNhgIjUsUec1IP4+mUhRE6B3Fa0NbiuSR7Sma2G4luuX4M3aLdKayOUwF5f9rFfadYlpIFhnAUQZlK1UuwxOYne6RR7dLWvrI62iRvfwy7RJQmgzPZk+Wr4MBed1bLX0why3AVSa/8QKsHTd3vrspjszz6Em+leiYt9BJeu0FnisWaDmk9TJApuBaswxIIPzZADm7TTOf31lepetVot1T6eduAntiKHxX4VhHGmf0pLlvuOmQeHIs6iiimuot3E+y6s5ZchiwRfe7+uzkudPNwhMI0+bOb/CKqmyq/JKxUXTOfef0LzutyTxIBQsy8XL36ZSuK5LNIIM7plEm5d6kiXV+5eN8+KVyDxPIvJaWiGwAfO9EpjK5UJpbTHlRgmukSWrppW6RrQzsltJND5FdOP0sVvdjQjj41XEXiN0I3zapebAimvEjFt0IpbdPDNzSjp5kcHr9y6mkTT7KhmJyfLcXd104lzd26GyIpccZ+7TTCA903BLJcpsC3QR2XTbrjbgikJJXka6cRzPKoqH2zIZPqryjY+xYoBfN2NnSyFJ1w3H3lVJLLTdqQynLV7VMEflv0cpbtErehmWVoBpH4ldONzGDbEEvbrySY+xoppKE+vJ44+E19lqdcn+UrCqVXN6v42WMPc8cwO9pigX0LEbOBN8+SwfeQ5R6KEgy8IAymhNrhMomqw20NVr6CujWFLKV8DZ8vMUMpqV6ToaOKYjb1eRItTEtfBq9tVBtHJP7JQY9WH+fJpRY1K7ejR19tyZ2HqLOzxtI693cLlNbaeYvx6EQOQL4ezZgdPFyxnfuos1PCjLOVir5EhpzsZMnJKeFHLdhyY8cQJ4jiBvyqEdNEwo14hyfs2FFaaeM1ps3cMOaHamGpZBtF0VsjTdpOs4o11UrTTOzqjPq5Qv26ansrFIFIv99NUFWCa15t6mERLqomYEEPoMtXInNpbVtQLBj7dHZE7kM7D8ZapBHxpVz6SzC2I6w1BQjGKs8Q600sEYcvxF2Rbzzo94kL6THulDjsFgssnfFcInxVVGqB7Kcw9qFeEtRGP/fCaBqwy5/fGC6A6kATaf4ZLHHEE6VMxiyyu7OztcuF5FegjyEL59IRjyUPCd5DBCUYn7rQsB5yVefUIaH9J0ooKgeXidRGmE8mid0b17vDA9sk+j1JTLhvoaSqzNR7pboUH1gsLyWbHfT+GrIpQPxfXb6JnssIdfwZdeM5C2wTUmxjF3LXTJBJxOgeuWATFoC0B6eWStVbgauBsv24VaceM41b3T9x6OpvQJUbNCxs1eo0+3SBKUObw6w5zN/SgVNrGgZYo04AnzL8dZQ3XKKQlubcZE5HQx/uOm7KjQ2u1AYHRSYf1AD3RCphPuaNkrN/tTN5bbLaNE6oJbPX1u0pauIb2mSXrbqHxSyyx9zH1m0xv9X9yyPqkfetZWHPb3XXsmh69D3bZKy0y0x51N3aZI60yhB5zL1qV5/lW92uDJYeecfkiuoV6GwsY2kT2xTjGndVt5Pqc3VYyhYAaYUJkzsDJRz5NX/reUbN84kekzI3+T7t8noec682eTfNZsvm1zz6jn3j+S/t8lwec7d4SDxEwn8P3vKNttkkgyCPriexh5tcomVyhp7Qvn3bOT1L5u485v5tcmva5NA80k7JvJsGamicMdtV6aFmHISeriRkt+OzYORnddSqmSIvos6o+bdbxYBJULqdxJmrfE4iKXencYNqPb6qQ9tcz2IQbmfx2dYa26YEtS0pvggf5ioHRcuPMAQf7dGrTJ0zaaeu4PXD28r2IZCWgpOutmQ/3uPAddES/2yTjk/6mIfXMQbG+w4Vod2ycLFwe1dHOmBsQ8B0WWaFiUXPCpdG9i0jp8evsBluUqk88LyayArIHlv9SKzQivRYQY2ovU9d8u49RBSJ2At89rxLRLfLHpEJJq8Iw4SE8UL266hv6IebBtjShsweQWNMQ6DTTmuPI4HYIVJIV4aHQEyGiJZKmnO+UlqJGEES/RTRYMqiHrmcUR9SA33mWiHxci9/F6pNMksafGpbkdVFTHkWG93YrmbF516IOy/jvqKAsR55w6Y0CZPj4NZAS57Ru/AAKe6FF78QW/eKpK1GD4gXTOWDF396LnveI4dJux9OrRhzk3xiSRTsFmNcyk7UmTw5mS3+LhRbCBFsnPiTSG2EEgbxtA7ZfFo9cj1ylfaTwdDBMZP4DbG8f9LLFabA5UUeMT0X4gFTMAhsWYP0z1YxaQkpqAche6ZbaHj30sD2lZqfeksd20rRwbGuHE3Ok7WRT5VNb596ON1DNOXlhKqeYhG5qTToVR+/SsgdUx++mF69jxnjpp6Q+qC2pVT1p07Km5t/c/Nvbv77uPkfh7FpRYh63saVtDQsp0Wz8xZdnC8U9Qi6E5d1dCanx1Utq+4nQ7ld02UYdUCwwyAwRdkXt0zMecpdltPmymmbdPIMlVU4XaDXwjlwGA10KRn53SiYCutzQnTtbdfdDRlYQbHVccj7ScMCAwYkGXl8L3U4TvI7kzbIS7dF1pwEpWv3Y5D/w3RC1qAbYGyUTqvPflcxGdEp4E98xMO+ZOTfnxPy7ZG/swWH1bHndsTT5Yc7mfo5yP3FJRt5BE5TSRpH23R6pGV1xKC/TM5Srolyi/7IOW4v4/paMPu6hsaSTYqGwtqGxuvpXqw5QYKRiVeyPYzxwueNjJ9aH+MG/DHh0A+QElfaEThLPUomf1PS2dQAe8o1wOrJsLRGQc0V/WXXuvr2LpikBlZp0SsdK7hkbbSGJ1KlSnOLiBettOXl6fH9ladKhJx/FRpXN61V1aielGah4sXCQtF64wWJEv0QNaVWR0NT9pWtiLR6PakySR5qS/ECgg9VVopX1Vlvbalvj/klO53lcWm0ZgsmV0+TwjkA866lBMKXkde+xLaU3z45s3yL7VnJQfY29cLARrJPNq9pgrTd2uP1EB6lVxnLcOpFSnVyfoyfuMNoCeJRNzpLPDI47SlJLs11hZAhL3enorKKuJqRYpNLPamAdv/KQm7HZ9S1HO2e13uENsJ5tXAuybh5/OkXUVv2S6D9Ry/U8wDnSl9TVOL1y64omqi3VU4xazASODVSj7POucCd4YpXOqJT7fX/ic59kMk7/eEWG/R3JtvMZJN9ar006daA7m/tDa2+ubWzld2zrWF+/SDQ09iyo4yXBQD2bSMQsduG6c3n7Sp9VKkb1mCUBFbnosxbvKaEf5cV9GTk8PyUmKBq3tGQiDcmsaPzECQ45WgREhb88eHz5ywdVEWKJ9HsH0rxaAhHRxt8JtD9S+Y37/X7W0oCc+fMI4EXRyzxU7+/OO18/pA9o9W15So2Jv3+h1ZzFNpmJCsVCAb9sqCm3+f2inMtPo9/rbTBY7gWjD9ixvsQ5440CW136jCCzwlfPAa+EHwv8ztwPnfxboKbXINjPq347Ofuvwt+9MicLRvdXZg+jx4++4duJ7Ij5ELz2IlsXyzTVr0yYmWfBbIElzSoxqx+6TMTuB4voAvcOozo3BdXslQwaSgiRNA3SF1yevluf7c/IJw56ril9hpIWeiwPxwag4Ex2Lka7B8Mdw62t3vb28P+y73fCtdFKbsEw/6YhsywWERtJ0zOvOY6RCc1jpKa+/GAyAl0QmGV7FWzkQrCNRLCxHbYCMpUNpgJxho49nO383sc2KFlJ467mnfV4UZy1BURpeb9BLtu0uN8PsI9aELMONDg+uFnjoURBNcr6nrNDPCKobyS7PLEC9KdBnkk5gJd0/Uo4sDnbuc2rajVdAL5Cp7RkpmLjtWU3FRh4xkIms+r5Y1P4j+G5r/kf5Y4NSWRgwqcMKIatPnCkKM79V9Uz+eDnbfHPjZPhzy5hGz4NICAAkOoXMa4kdVk/ScYv14K5VOBLp+4mPvOhxz0t4UCfZpT4weeFUvvfMmhSVm/9jJTjul3IVY97oIZMa8T84LJ6scHw9JP5k+KTlRY4N3peMIIyeOAosA2o/ylis9iF+0xYQSuJnTEk1MREer5PEA2BE9cyNyom516ZoNaFhJ76nqBPgw+xSiLFQMt/jFhVkDnPiiGIYhNDdacHvevbfFFh5IWGavmHkv+zrvYfe6qGgz/gk8DOq+cv2B0S+foTOwgjM5hCkgdZqbnWvwvOXtgz2mwMCQajZk2lkTdzIBNxVbyW0RupJiqS+wJobfUdniMfHH/hJO1K1+8sx0HApMVgdl0vJDBP3wvDG0RlgzDzTjAYOY4ZFqrfbrFdy6uWW5y8if+zx2L8Yjz/6E+NTvdjmdWUD3qGAYU8W5wFc+oO2XWyBrrosVcD2yutghzktQ/o+BfZi6hYKnhMTqhNwdVYtEljn3DeE4xdkDy7kJt+KAOdg6Mzo7sxVNwpFjSPeJNyMy7I3PqLvAT5I5x5w9crRYkNwDEiIgu7k3g3doWf3L58xs7Ar76MfzDsSO2NRIp1/zrz55/1LFYLa7joMQ9hRqJeCpVksuf3wjllH1iZsxJzA1ti2XQ2yPHHguxZL7sJwWrdFkE9j0CBo/YlekODQF1aBiNAu9OG2p8hRH4dyQNOYbhABqD6v74zHYJJTyngDskXfLx9Ozq5IeTC3J+cfr28OKf5O8n//yox3WPXKFmkRwbnOPjr6dXP757f0Uu3v16evyRWB4u2vf82OFn1dZedroFAg3gna/x5+J7sDQkFBgEWyNN05pd6QrEwxCkORaSZwAaRljAJOCkcBkYNGhgOwsSsCgOXGY9bwXvXQDMRUM9OZDFuPZQN4UmBPO4NRovRqbn1HZLBWMGvmCMFwa+kJlC8NZadsLBT3gJt5onRzdhNmI6IMeIZsN5qplJChG/BVotS7wC09h/shHm0WiuGvvPNAhUAsxzbtIVwoEVl0iVCKdbQmTPbVdn//+FBrYXhwmLCRMTJX6z3uIR/uGM5Mujuc7D8JQY2GepRvCbjVsLW+ib8iqs2X7l3kzsrE2kGWmRq6mgwpcQ0LtHW0BpWRUnnrtt5DbBwareSP6RGmCzGw0m1rw4WEApiH6ZL3BSaIDmJvpfMZXRcyf2VJI9nKnjAb8xlKnqT5c+Rwnv2dxcGK+SHN70BL0PGfmOxpH3nSK8ive4E5w6jncH4MGoOY1ssNovCPrbYbI5oYEX8+6J4Bl0rC5Yyb+z7BBOloUTwxkFNzycz4SBJZ95ZkfEpC4PqKRkwu7IzIsDzmyoqKeBIyMPhGJRaaTG3gXwqvE2/E8Jll6szenpiN8P2ci5iAUBBbu0YcpNHNuOHS06Bx04LTEYnDzhA+80IpIyc/OToZK38LMgE0vcrhigfjwQNBPmiKZIK6GeWOTkKblkPuB6GnoBqSgO6/TZte0/38OcKKLFZzQLGCMOiyJoL0XtAHs2gdNPXm3wLl+ZlEN0l6lmNW9+vCi38hTkCU2ADCqoWctAXqKQos9SAJ6cvL9Q0P3r2eHbTrdzwv/nV/5QjDk8PzzqdDvvjip0y4wbq845xxteBfi/Xow1d+gccieK7qz84UhNCTV3nhgIl8IfThMZ7w+nYPeD3xTfm7oGwSnE3NnV/tOLg1Qo6pFL3hAtJInzLoxohNFPYZf87tkul29DNreB4NywS+5mtjlLzApcrhKOOO7PrN7dy5M3J0dX5C/k9cW7t2S+QD2L/PrjycUJmdjMscjfyH+TdxfpH6/EilQXjvbQuIkSwt1CMo5R9ayRKzCXiBgLEPmI47lTHvAC/JHnaoven3DZjIFdOKCix75e+suYMi0Gcfy8rlalbQtckEYU0FvmGGPPu5nT4EZHnvIZMC1umgN1iZKQe0pNvmNFmT5Sx2DKBaLDrvOg9Pl/Bob4xxD/sc2GE6NP97cYHU5Mxsbm7s62xfq7231zezgcs+1djDNpsFgwUXoBq7itZLlA3sSLItCEv03E2wROXsNbS8VunZdQtyldHamxu5Kd4cUTtFuSqFlVi1Ci+9K69HmiEI9EONw4DVoD+TltjFf7FXXjj9PbEd+zlGAKZ1Gyt37AbkGvG90HktsiWGSQ6NdOjqgLhxmue6z75lpeZqg9IS5jlk4YkCK6CnkSm6DZHwxIIBiRkIYw4IdRIlLIOYEv5NUkkrVI/ppshjDRuozCT6kNOMUSxaCSBAl2mH58uYiIbaPPIyKGB/3+Qb//W9kBt6d2RB2DffIh8sM1mTH3XDvy4Esy6m1U5YwW/SkVP7Rjuzd81dStCkZUGNeA7m3tDq2dvT26a271By/p9t72xNqdbO/v7A9ro+DqFzKdBmxKIzYC8muQDXA7fasqfGn9zUKgk8WciJ6b6qTJ9ZLs08Tx0KNceBv27pwFtlfv1224QJhx5PMp86KH8rUPLXCmTlmLuti1I40WnwqFqNVhg80FSmYsjC5il+fYYLC1Bu/5hfBxXfGx1msJHW8FIhDblnAQjbkih3M+tCtmbABuNuhQZmmtLYCz8uNLxXY2nnGVuECtNbYq7lOapbgTsXnF39x9Bg4bRUIVpq60oBA38MCty4JbO2M11kiaWOtIJxscCRcePJWlq3w6tV30Yjh2GClfr/+GUne41OAvVgJR4/jVhvMP+8VKxTqcyfnTG08qZ2ADChkNzJmip9V8s59+1adaz11Ok0AYcKhUJ+COChJhCxJEKtHY738uBE/WlZle6mSvO0L7WzvgLezmhUv4Pvd3s6lLbOp9b8jTjd9faoebh/Y3nv5Rov6r6WS9Yf/NSYab53SoWEFY1zCJWqj0BuejJHWYW5VVc3ONMe+no2YfhVCHMnMPMlu4a3FgVdWHnGjNwTzSOiUOlTVUL+H1O2y+gH6XAmbg18q3qUteB9Q17dDEqAIUZYKFHqgj/rAeqPeXBRVAXW32MwL4D4V8iwY7M59T19LG2BRVcvShEfFOJfg7ezv7EzZhBmV7zNje2do36NbLsTGYsMkuHZvjl/2XTegGvxSOLAYCcZaE6lKq8Y3iqt4IAZg59hQj3+TIpkTHx59qEHaMTwqx9OR2u1h0AVV+GH6mj3kvTjWDjE0iMza1M8o1VTNOS8wdpjjASoZs7kWMmNSHogRhkY1iYRj5ygWjoc45dDrJfQMs6PKlrlB04FVyN9N4gbjGEXruyZzaGvfF+xBqw0L9VDMiDMYQalkBZ9fFqUTBhdUkmGQWXgrDDiNusKsgAXWYlh565J3LXS4GhFpKIuxyqx3PwnUW6avgWoGB34XZuUWtXv66Fp1gqYpXlOHEHHmLxfITptO0SCionDFNMSgywQZs0I9HvhlB4BX1/XruIsZr+Pv5exKjYd5ngcnciE5ZF3aJktCkDqrGfV4FoK9TGgumvjnPMk8Trflf/cZFUQ+VAh1l2TN5VaYeX+ioH0HVu1GzdIhcmn8eAp1ReS6zF4va+Z0dsEmxzp0nqo9oK5hqsYOqvlo8J3a0GKp174tEcA5zvXDID2wD46FzRxfhOxVnqVRboIAxhWiBxdGMBlOAu9VLC9NhOjtloVlU+RxL268bhXDWy7U4k+tyY8gVQlEkteLH/Xh5wPHd7xeHGa7RLs+2DWfS9U1bs0By6t9u6wgzn7GxwnXCRxm2n6RlJJ/efaRPLyuGaXkNn/JCuah1U8swgQMMZ8tKFj3SRJLQRq0V4w+qirfJ0WA9TK0QEMr3MQvRRwzpYdTqcbk9vLlg1PreX5ZlwAzv4XNLnz2Y4dfAjtgKQHizy3jMa+E24hUsjOw54PaNF4ZLQz6xA3ZHHefE5fFjjfg0+J3u6OJRjmf67Yc/nxA7Fs7oDXtDI+aai4wzrYj00r22Q/9RcMe/+/B4g5BqpxFRy6DOFax+om2qiJe/MG9X4AxikkvmRqtPEtpWIxzktM4VtEVlovtRQen8UDrC/j5eEj0Bnb8PmbU0B0vfv0fZJ6DzEcTM1AlAX5hSrltBpNElLyC62YgC2+cBQ6CFQ0VIM/UZ/3p4cU6i2HWZo4uCWx9/CaIIrQDh+k0K4Z0dmbM3nnnT9Ca8DyMER+IlLrFoPUvRjEVNWYQxopAXxQNJs17ne8A//3i6BfzvxirOek0s3c6dPbEvowD9Ucfj+VJMKKdAowKnKDPiWlI4aEJ43Uw0jASrqdJtWOyTAeFChrw0IeRObxowM1kTom4TD38WTZxCcdR5IZ/MuTQdG2tIYsMnqK7AKxqxMKqPWJ15ulQfXjMoxDZVzLV4TC+EBWbn1NjjZ1HkhwcvXlg0nPXSQrE905uXWF/0XcQwM2Hhc3tJo6+qIVv8zyigJkMnZ1nM/pxFM6/k6z9eXZ3LWBnCByJE1ZD8cHKlAAJ/leVsJO/ITajBHceTXJuEHD+Ro3DRQwtnXYFYq+plHiY1DBOSpGMIlNFQngZLRzNm3giKpuEspTF2C6kRW30yt9044t7d5cBnqcqTv6QL/SmwEVsKO3gToIPIrT6fNhMLsDR8uI9tGn3nViELNiDASpkyTKS9eH1Etra2XooupsvF5G4Zg74xGFxhQK6IyS0WWmqXZIb7SRvkay7PX4ulXu/hQ8oHsHtLQmvr/5acHL1iEQtu6YqKQ9mHktmbVnxa6iuyNhRvYDlSmxMsn7G4isSTB5QDZiSAJbCWSI3LHAH40KhBbaxGqjhCzfvGy8b2DdgFlrEQ4586z9C7QBJ6TQ+gYC7LX3rqCcvVMfbuiDeBShMpGiFxIohrkl22+vPlb7FmzqTjk3/wS5dX9ofUE9QhqwFDAQev3xmjDjSxhFu5Paz5A1MkvpN/YN+qkMiDxAtZQNoIZJov10WkDshPI5XFLBrEqPCFtQhRwc4ss0UIKcMyEqFJVUNzvP3SHO5NjL3Jyz1j+6W5Y4x3J1vGZM/sDxi1+hNrr+k+jOywgRxhr6jCKuY+hXdpRHY4F5iJO2Uu5BthLq4dihDmarRMBnvb7GWfGhM6Ycb27vaWMR6PTWOb9pm1PTH3twc7CQQyUr4EkCQfESFq8nU6GA/NLWvbYDuTXWNv/2XfoGPTMthkMNza3tmFX2RkAujHgU5vSlKwvAlvIAgkcnp5jizXG/Oc56VTpHaN/kBJkdKlbgjI0m0qoKspcwTCahMIBcPvxzynEHohvB2/2nhJmMw38m5ZgEYZ/QYa4xgsL8ySR3rOoNCd1vBSKIMM3umRmbi4s7N/z58TfC4ygwGYfK7sGnGHBgzHg5QSHqYnYdRGlUgA05iSB4OPW4A/Zzzro0jYnQolJsQAYSJ4IBCVjKlWcTmPgENwWWIFj9HY193IdnjDC2lEswDKx/lxlBRg4h3TscTgg1Mnwo3406MXAX8q+IXSY6wCwfj8qWFYX1gF7YhYSOURDpNwoY0C87aEXs9EeSyOPeheaN8y6zHRKGGGVPEmMIeYKfcE4A11EpOE9fIS6hw+PAWAAy5JuhvdaMptJp5IcnH4Fg7Sje14HLUPjUrVW6hxph2+fQoMqrGj7+Hwp7j2Mr49rQ+VP34MWow8H4PhlMZrutRNzydH5+/BbBHGc6yToox/MLgFoGECOZ6kWsgvDt8+NuQCUAG56nUsQswdog9LrVlHaAqjXiQVID6WOMrNPSPB5DUoFPaLtMzkY6ge4MwFqNGbO7K4Ozcnh9jGa5tAIzIKG86HpoAC47e+nz8IvI3tRVyphMMn8T8K47ks87pUCn+a8s5tBqJuS7pspbZDSaNWsdP6SPwSiyqHppU2HYepOj0qz8PMrjqjgK9sF8gr9YITlh8G4IDyaWKUSSsI5qNp1m/JqKCYgoEjs5Sugrom2/TJ4GUnN9U57id5vzQH5dMIrG73ag8rcSl/XncJCPhM0t1gQz4PWPthnV7NLI3cb1EJpJhYn4Xepq9rzrPY3zMGu2Sww83f/3e/rwsoWsK9WN8rtpB3wXXo9Xx8+T3G9kpq/lppLlqTLDjpm7tfzvXJkN9BugQg14HG2t6sj0VLeXeF0suVb1umlWuzs8VrPLRwzWw4cSknvrdbeN0MNXts6kUQEWSlIer7i7tiFWlGOpbTij2lbufWObOpL1QcvSXiRfLhBA2EwAkVRFZO0jI0AkIO4W9RfpKIl0v6ebRnjmVucttSY0gCkZS8+pXUPG4lKE2EXjFKqJmr2w64OEudhqU2Le/OBcME1QejFyLiY7/56HqTQ9JbZARh4eyT/q4T0ccn/zg5en91+u5sdPTu7OrkH1ej07NfDt9gd/d3769G716Prt6fnZ286XQ7p2fy3/VImziMRVL7b18xZXMbbYo+boo+rrfoYxPlctV7v2ibWk2qybARx77dSLQPYpqCrUzSz2rimRZHol7G+mkKNxyvXF2m5XjxVsQpPPyXz5VM2of/+mXiF334b/9S6OD7YB/nHizu/A2RMa/2Nc18n9duGs1wsIwbZMPGnhQbuz9mIlXgXMX+z/d+lis+/EWeJVCtkzKMf8ReRFucIxyvF7WinGAsv8Gj1E3eqcN27chGCRYrT+raQCSN+fjHeJBinXSX/diM3jLez7PV96AfSVQWrwwrBMd4EmyO0BF8J9Tp1ZpA8/xGqgsUy+1kwGi5m833Ub5SdWQKb/jYWA/60GuNSdrI+mJ9LWGEbTFLUn9Ja5bC6jsOKzNxFavG6OdQ6z20zEyxitUoqus2Fh7JWJfCAyhGMWKyhkkxtiC7y01iKcBqOhKpxCMROWc77SqxuqFs5wRh/G9XZLAKEOIUenFgstcsMmf3MD9GIQT3toCWO9Ac6+UFBOLAkYY+TDULF240Y5FtqgFnDZP7D168ED9gNjxUa4oiv/T+z9fDyDdKQU0fLYiiMM0KUUNgW4YzhMVjMlEoaybI9EuZr0hExOFRjZST63KM7wz7fY1lMmELW9WPt6sf75Q9ruhH08BVV9WyJl2VugQVXhU4bSHrtZ/0ko1b/4kv+ZBeHtTUC4fjygfLkkSK4BLEbpqzKW1VU/uW8VZ/YJ+zPUsTo6bs6M5efu80sOl3oARfulNWOBPdwpH/oHKQ72vNHI/DP8wsVLpGeq9/3TCaDaPZMJp6RiPKPj0Wv9Htf3mxAXTNiqfQbJFXgmogSYEfOWRYq6m2MEF/tjPvo+wpSzCVORIxpOFDk3pJsk6Sh6VmUSkNYteVzTTrhT1RzqiZ/3glsfIwcmgY2tQll/bUJacuOQeFV1+aZBn7TewCrJaw1IwCNhmNJy/ZkI7NyWC8t093TTreZ7ts+JINh8N9OhhoTaMV1UcaiPUyc7/YQOFcdjQgMADUW9mxXSatzzy/R15Dc+SQQN9P3nv5/PTUmKLx4tlHWOHHLvkoZoJ/uiya0/DmY5c3VXcc8lF28P5IwnhsYLfl8LnSdzSKA5fPDV927IgFPPwf6Objdefi5Pjw6Ork+LrzEeEDWyM0K0eeYXlYvAlZB7x+fnoKLGJuY632HvlIQxdBDD0B00dRye0jNmXnlc9TKMCaFlgQdwBkBrNRtGv1rhX1uayKumgRUYHsHrlQ1ptbnPQ85tZQScfD/lav3xsMtnpIPjTUleuKI8/15l4ckstFGLE54f7VaiY62Nra2sEpNeRTnPJdMKWu/Wd1BwClBtibd++PX785vDg542deUslqV5Ptj5KJyrMj4GAS5QQ8C6DyWMjI8dklAZUW2Qzyr8Qv/HztW2eHviEqHvdy6q04RRrQRWIHPF0/Le3s9OT/9XMtMwoELZ6RZx8H/Fient9ud8nHYfLXbpd87H+Edsexe+N6d+7zGoJrxs9UQslC9QPzpgH1Z7ZJ5CCVufXIoePwbu8hnv37ZT0NGEZ5Lyh+gta9wWVNpEa27ozLJlLQYho7dK0bHGg+xcVkpocAhCr2wg+8W9s12f0BcnQIgPxpa1ps/3Z6/sL3QvAi3MunX24P+ntNbnIIrsFOKG3Mczj+vqJCRJh/E/tu6v2tBfkh3FfF1s2Z/uvN3KMtnBQZfTnlfEmbnQEPHLI8M55Dzjia++NAZ15XmjhqnnFFph7JWG6T90cvIKCgOaFKI79aUGWkUnXKFy8bGKRtHusxqq1JAdI+lqSIXYsFig6kFr2F0lJ1io4feJ8W9fW09IFooBQoHr001q1RjFs3DQMeqNvdAJjInH3bfY/qcbRE9GBNLJ3SB2un327DFG9L/enb6ReB9nf6aTaqMHvoDR4J5MXuAi91E79cx8Q7uol31jDxS93EL1ecuBH1rKv9X8OeCoWvvPOhRB5ImiGqUNVs7M52Le+uQUlkkFZW9b7re1kKL3kS19C8gWow1Ux7xKchNJjitRdq5GWaVJo+L+d3hZkIXu8goVGSoLLop66o+Hha6lCnYeiZPHoD5D18VNaqtCT1otxpXzHRQ4YC6IO+ZVGWSSWoqd3w/OTs+PTshxEkInS6yZ/vz9+8O4QkhMv3R0cnl5edbuf14embk2O0Mcqgg9w9ImvBpx8mz1hv2uuS645vUv+6A/8KfSZSpOBvLyDXnTsa+IZl0+l1R9OMbKlgBV2/kNrTtbauictUIHqY1pANMJfUALqHLiRZfM9t9yKK3mu+9JavAPqfZ75ou2Rum4HHS3Tdc6ONQuYRL9qkgzePmacA5y80aALqLQ1sCpr7I8NcT5kl8ZS1x/o+esQ8dQ043wSsvrtoahevZW7CgF3QlTUDtd7xwjjVXNjMGlc7Zc5qVjs+Y+GqHS3MUDXjPlck0Oq6lElzcu3Yp2fzzVe614eblUo/9b7Arb0h2937/9l79+W2kSx98FUyNH+U/WuSJqmLJc32Rqgku0tTtqyRZFdNtRxUEkiSGIEAGxfJrA5H7DvsG+6TbJyTmUACSAAJEpJpF2cmpiwCyOvJk+f6naP9vf5wn/XH9IBSemDvHx6Mj1h/vH/EL8F3iEa1c7w71EFGVM8AzJcjWdSkQl8Vr5Axm/gBI5aQvHIoXXrVNTU1qHrsQTM9NvQDkGmKYzxz5syTZgB4K9Gtx5r66spoMmETUjTMVGHiudmtl2FKbWE5ozLHBmchwQQOKdbKQjb8s2qCgeoJo5AxLzNR9Vc5UfW3mR8HLmhJAX00GX+JOC5dQPx5DdQ8x0oWlVcaB3XUc/aHaXGA9IEFmKlppMJXsPg5/VJsfeZMZxDqsH7rjobJuf5jK40DklwDE/GagUrF2zwJgqqIYeLfaGJT8pkdOJd6gi2LZXsOKmpQU7IFqmrS29pU1qCzb011ZUN9bipsYvYCOn1w2ON7DvNvRK2/RNHipBgGmrNipgDAajwYz/lxXR6+pNSnwAxwOe7V9p8+TG+SqndrDzAtoBe2N0TcnpLgQCUvHt7SAV5qoF1Ea59l4xpWAsdANptMhW+v2kudH6+sGptdVo2tpGp7RWW9pBXlZ4CDccDjbMcYl5CpFqnrobT4nTMhqFzDYDWVjLCirKzRIyIze+SNG/IvlJch7iHreEti0jpJTkhhXBBIeMVXX3fMqtM2ClGaa2vc8J9E3w8LtFXs8HN2Dk0Dx2VAd866mlR6JEIqrojf+K9TbTLSUy+FGJhmRbSBrWtWNpMoQqsEyK4eG1tai5QXNVouWIfA5oNZWSktWm7+1pQhrYihBaYLNwI/aQaBtOZOWHTAighqX1d4S0n5+35iX9WVXZ2pgMHyJnAWz8JQMp191s3g27GU51wIyU6y66FjJUpFw6LnpgxZURTA1RcIVBYqbT5JAE7q5taKo3mxUQofBgIqgER4/mO5ow3NPSStJibS1DEOzubqAoTCHR70BwQmgHoDF72AO80d13WEpZ2g6Ymwha+L26gt32g0mWwpgmYm84oCaolGBO0bjL1aQ2lUvyExHWq6bzGETpSRkj7EIvh3UU0y3xAugX8Xu/EWhirqrAnXfdUOrKFlmi+f430ni3fOVSPz5WtgGjJfrqSex3exZjVFUJ7p+OviCNrlARl/++Zvi0EMQKbrNZY+U4yotfUWi/BdLPY1T3IwZhslgtda65Uv/LP5q6bEoJAFhUKhmFMGpch4WR3IDpkzGsaBCBATtl1evogH8bVNzYViRa1skKFhGEVGIkVGsXqGzY+k9Fq1oxXSbltVyk1GnNNpTMzE79XXKpxFMyeM/Ey9oBZvGQ1CGOguNyWemWp9GZbzEh0UbQ0KtSHu80iO3RNlrOQ6hXNXvG/FADrqVD/nX5IbZnCSEg1/TXijmb8ITyWQbWuwQ5yFvfPDcG0kizxgkqrcPzOWkWbR20A0gifyfkndLCtnoA96+L+rWjqNRvA0gAA5k6ZZ6kcLK/ZD5OyrVr8NR7BqieeUwIW0yHsq5tAqH/oOgU/0iCe5RVG3Or8xevSkHA1/9xhKW1L//km9EuNnPYqvdQcIn4PwQKAMoVzrjeREXHlZsHtBo1kTEEyc9UUp6oW8jEVGEO5IQNNQAK1b9Fv6czdPyik6XflWXdJo1vwqD2FcwmZUFqaK5gPxHp87szsQYk29ZYe7dLkVIUxjc8hv4DPGr+BlGfMSzvxHiOCBnF70NM0YmTgBOLgxNCb2kvYiGuAhZtSapd3LXTLJ4Cjk9VeWq4HoWO4+M41l5O91eMufm4e/8RzyG/9ksbiKovdl+Swkm3qTJsDxFPTIhz0BpxvT8ati8oDo9XTyZgpZEet1rbh6GTa3ykDOvXZH4ngrDuU8XHMnALbKuNe2+Fq7KIPoyVaNdgUyLd26MuJqElwpUCeeT/tdpW5X/rYUJZRWvDSlkLiGIxdaSBKKja/fYiqxEyZF2mESulhLJcxPVw2svExDEpwIXN7xQsdmEC3gxxH/50SXZLn6mhRHJ8Ts4ihPPJKGaCKpLUIS0XvmkfEyI6/4JMD7iBdKgiDFMAJAjizMTp3y0XaKmbM4aZDhVpWQVn2FGieoYcKZ0ZvmyWbIVivub856upHfBT9mR/nbmnT53ZT/VdwTmZ+dcAH8qpjCZprrVtC1mscoB/IOqieRKHINJBV4qwwDNnaj87YuIha22lY9I0sZcbn6wI3tIE5We3lsvDy8aVrMItc6SVgKGbMprQVGLHPtCXcZ/7Se9gtRwXzHBDMzuKxyTs7mDsX6bHd4PXyntVynyYX4EnH9MOqQcOE6EXDXJFn6+fPIcTxXzGLOgy5YPT/wQLy5UYOPAuqFcyfS5gUUZ6C8vkHTuGa6+oj50YPCuBmD5ueklt7FaxtE8WJEJjQvB79ZVJ9MwJDu01lsHOWLodXRvpzB5lA/XiS/YSCJTlNG3DwegIJQSCLkxBb5QhyKIw0QNklnrfe4cpvrCtWATezJ+RpeWbNyfWCjpo/6W9tkYBe1Q0rLeBlIXUW96PKcXImcG/Lx4/kZiei0WuqZDF7vsaM+7U7ohHX3DvZ2u+Px2Oru0T6z9ybW4d5gPwdncFA7ulJICBWKUbxUp/X3ewYBQgDaNOJpbiNrRr0pG7EHZhKRWwHpdZPqkedn7dQ5F71lgLWKyAlgbbVAyz/GbJ4ckFeP3OghusQo7eRzyU7U2ujyqeN73QQYFPDryF2unzvQ+SNG7XamPgl8DaQdnwoHUsjANmVyFrnfAatFPjqRNYNCeIE/X29gKs2IIchkxPIAhQTrW+gzc2rNHI8ncyLFgWtBjq2g2dRCslXv7PqbELLAoe5IcBlt9/wVteR042lWxV0mDUiIkhYwkNKoQCym3SKVRf6T0Fi2Hl52rIgwSSIHe1dsWbrI2kZ8UfZfH4jIi0uOyk+BeKMEgQ4MYaKJiGocVdDCIh67YAIWDaUoPO3QuZiyWaBRkRJWX2ukba08U7AxUm/5YbJz/M91jC/YZ+RPpy7L3ntfO2s3q7tOv342XAfdmDaf8DSp91vp4Fmkg+2t+73funDeS+YGzoWsuwjf1kr+wjmA2bb+ZMJdjC1el+5idGLbjnfCGcB7ulgYZeAArjBQj2QXo8i/Z1ro9MRdILefxuhdRP2SwxbXGdyTQcbRrKCdFpvrlI3uc2bGMY83Se+d3AxdQBmyRxx3059EI1+p0FMZJlHM+Cmzlcv9/RBMi1HydSMQzRYdI50CUFFN9xc+rkZhBCXtJ+sYRRTkwjeA5qhRv0HI5OYXwrASCkqUccgAV/qBuo5NIz/QWYCyw9cVd9YQVpmLSy2YQq7BY+ySa2bFAYD1XCQWBrlIdaSIswVA5coker50YqF+ZjP64PhB/bmqrEOQhaYpBkaXhlgFTng/ctkDq0dCdRejKye8f4cv5yco5pYFAVAaT8eXn7mBnD2uerUMx7xuLsnKF0I20u7kWE9BwrOBwVedFdd/xHIethMDyCIAn3FYxeUI/620Bl77k0caME9b1ezaEpGDwsGP5tKASbQiODIYvuYT33OXotoSLyEB7oQ4wKBMBs4ucs+Wj36gRwbOLnMpuNG5BDcKn3ZcCsGG90498K+7GF3fOwvcHYk7nxfa1I1NwSqw+WQ/EKEC70eoomEifstTWMsRZKMn/BOucXGC1VmYA2c6ZZDfCDGILhRGki8XCoQ0S99Sx3IqGxVLVlnfpOCXX4XP6JlFuh3KmnTk6mZ3B3PxubT5s1HZFif9YGTKv4G9XVt+oPbG2TmMf8IC4ABawfiEJM+JY/PbTGCLhDGPK5UBN9yo2yMCksRd8uCkcObHro0f8HhbePcECyR2P9xHlJyfXZLzM/KCor36Ye9l79YDIKTw+NUrG3gszD7sWUmwIFS8e0UXziufV8PwvfAVr7jY5fJPtOwK4JMg7E5Z1KVet+wFE/T8iHnUi0alcW5jGmaK1/P3OwSqDZDbHTkZ/nPPv48oTOF2pzIXNQ6c4m2b3/vM2BLCisPInycSSk0kG0exGVFtpK02M7aIZNzaSSsyuiTockVZCN12UcQCI7Z2KV79iss0cVx5Kqp71/HnwqwFctBaK51IkCNHV3Xlk3wc8rPHRdDkBIcdOKuO3YGA+TkEZw76PXLiETZfREsC5eLAD+iFIlguCpa3Xvo18XyP9W69Wy8paCeOPu+HeTYWCQt75ALA/uRLQhaGC5TNx8wWeEQ+hhlKO1nYIWFszW49GhKx9JU4i/kNKOy6atSwfNflUnlXvseinew7EQsCCq12E0Mgz+ZATOT5Ioa98xdcIquUg5Ujldn1lBKLQqNyZj/iF2vKzcbhcCufj5VIUVwGCU1pCfKKLVxqiSwGiWcesghJ74PYgQ6JPde556aRgMlAYyckUP3smPgQOIDpBxFxGX3INUdRj0PlmVDX90AG9Am99WRgOFx0IAFC5n6quIVw+QGSJZjSeVDpHKZALQtvlh65hhjTu39+voOrjr+1yWRcKfbopZsGRHyTVcK3hLwl5GfixzlazVLoJb9fDPQhR0aij6plFoHnP6FuiFHg0oyFNRktmSSay09hLsbxn727JDILnUPlRlxbSqNasR0e20nYF4sxmxOBMBYDSelicpI9cbxod5jJhFQG3c/Wa8oUbJKONDQRjKJZwMKZ7wo9ISligOaBuhOnmBp4q7isNGsryAtRBo1mLQ5fOzmJtpDcwFdUiBjVyMvG8i+N6MgCoAFdqY4zGlEinurzN8Rg1jhechAR1VXNwxHAo6fsvgqimrtXUnRqoScVO67SGVCCrLJBG1kxd7TGFJXxcAsNAIULBoTco8xr5Ni52ZAXsEYvq3W7nMpS7Z2uWCZdkVbfCppxqxCqtETOgxMtuVFTZ7hL3yH8nZVpqdbylXaFJtkrNkEKC2c0YPaoTUJoet/sFNQ4A/YC9VyYTcR3q3KZlfQN3T2UJRDtxXiCC7rGAmev2a+6Pky1nJav4Po7UlO6S38B5ncxfyHqGnqqO8/0BiLnZ2jFTs5uWpBUnlxyPuEyJ0Rdsy8Apgg55OIDtNhCwm7s8cgOey2hsLBGBrfY5s/h+a7CPBg0HLDE2AJxAlmufOudC91i4jDXhmCCdJnEV/5jYthJv0xLOIwZMVi0WvWLN6vaO7T3srnu91y33vMR3kr3pC6zs3BvZif5Ae1w4rEwWiu+Lz8gitl5rQHjQDJ7rlXbCnfSfBHd+AvH2lqzn8IuHeWWNmlLifgXpe3ln8NWzNkriTSpb42Pu5RYvp3/o8jwpZlCx/ktzrQXOHKCk+I2JsO74FmJ7xtveulmP5XNfLXYk5VOVJ0rOUvuIAydgkT3TBSuimWtGQnql/8LoA6F2tdboGa9CNC23vqkZ0ZZIe181K0rP2EFqlpbA0zp82u+bVgXXeBcqqRwjLHU70i9AkesDJsrMuDzswRHJemmRQtNVaPlu1dYdWMu1sJprNdb1jqd68BxPMOx1Oerir24oQbRwN9C0vwub+/P2ZVthbPADuV27JRGbOpvasTLujtXd9ibLFrE5lAx21SDeII4lpVkQFyCz/pNb4uoEiIqIa4bOn3e6IxSUirEsd5d+B67Iy+E9eFlh1DisUc0mKHxBgw3wtFFUOV/dKBIJ9yt0k6hvHvrmdir9SRStniC7tZcu805TcmECmYMlaKzkeNVVCzba5ualXFq+/3mJK239wpLKawpmTigPadpRHQa9m69boHqj4nnIxlz+5p46dqfsxf//Pzy7pjYzGUR47WKk0b4816vJ17J9Mki8jfiB3YmP3DtLUkYSUEUqXdG5raxvXPVKMhZbSxH0N+YoNT1gbiSeomAhmwkpU61B0XZt3w3nlfnQJnQQMiiU2wJl/VZjE8am5PNR2JoYbJ8OwfpUe9Fy4SQrMuvvXg+spib0QP0fR/scb3eCjL7ruZfRDSKm2zXx4XrU/uaf1bj/72O/ACCeKQbWKxz4gZOnMAQAHYD/hXHs9zYhthaVCeDzG4JJkZoSB6Z68J/YxxNte5aSS6igRbomC9MiQ2/w+9AsdrqFlbJeHJwyRZqyC89ip+z57yVaxP4RY5/iPNay0XQRGEkVEO2M6M2C0atkTxfudGa1J3byWRG+faz41dH+1m3dm3tjMI51V+BnErAUYt2E3EhGNOCngHmMpDFGxLQSBbhBqCRIqs15Zpz+sWcBHLfphxQl2gOz9QxvvlCrYigf/09RhqKQYcKnwrR+ytB4B2PCGfzb35gQ+JANUta0DCEpDiMty1bRhhcbgWRk3Lak4XMTRcUzkUe/T1hIenadhKq0Ox0jpov2OOnwiW4aTJFC/d1O5TXlBja2c26PTSVTYv7lwfhiFgwdzwWQkojECYmfSrpbjw7FFNdKIHmuklzZE49jwU8DpwnlPJ54XEUHkFoj+SPlkI9Ty34mZu+QxZ1yDwOMTqE49oZ9PA1vzEoTtRuTGNhcF2BrxUS1QhCBcJUutUcH5mMjblayY3Mny2YJ/8V+JDnKE4cdWQaKoR9R4rLwV1cM0wr0AVavbuU6DhdtL+DEozv6sDl6+P2qEfdZejokIwF1vzJeZJ4LV8mmGqBzk/IqYgU6B8ck/5M+JYGXUX28uH0arVWF3SJ0o/rT6cCKqQ+vwQ/eedPxToXaCPfaEe7ZHxKmm1L+Vg+q+BfMSSRzH2buchOUMKG27N8X3u33onr8qAwHqEkIxZ65L2D5CQfIoYAI7YzQfccpPlCJ5cfb8hDSC5Pbk5/OQajyuXHm2Myz34LwgMKHo7nRABJ8SL2ZLAts1/yisLcJsMbyjdwz9giNVeK1zeRFPPxZtVGnsY5W09A5k88Ys0RWr29+hjZwvFTA87wJPlWDElTbx1vyoJF4Jigkz2D5ygNIt4RkZ7GKiVGhTV0I9Q2ysOnRTFVE1GyMt6iXdvLahvQ4DqvA/ZHzVhRkrUW/+wKKpJArcO0SKLrK9Iasq84Et9LDJ0thg42ezn2VoLovlenezFkTrO7phL3k7O9FjndlrOtpKisxMlS7SbdkAb87a+KS7RZMerVoeaOH2QLSJmakILYMET9KTik7Dyh42QiddhMDaj2JKHJMlot0+B/dn3rHhtMAFbrfZo5nEQBJVXEQcwNcl2BIT2kX/Ntp1Rde345UBMHAzTu8YP8CK2KgBfQsIFr+ZFaINT460/4RaHqoWyzk05Ktl4gkQ/KtMuI4dx752Dl3ws/Sv6NVvgrNmVf+APl70In18rSlHVyxSxn4QikUAB2wBN89u5S5GGFxWY/yQVLwULLwD5zHBKwOHNvpK0vIq08WYxFTdJ0M0OInAhRLYXzgb9Rp/9vFsPdQlxtIa6+D4iregxf7qkoguiuioaVYsgWjjpP9iGY7fPtzv02tatytczoZcQXZCQzmtbNAyyQzGWavWpIKRkYXCP4iCycjbof5QV1E3blhCT9Au3nEKobQxF26W2X51FmcXMQdcciFo2o60+h5OOtx3jcI0el5WFHQcb5lpLMKlgXT2oYaf32eaCBQz2j8I6UQnAzP4kvDUg4zYyuptyMniEpRUesCiTrM/K1DdrZVv0Mz8HFlHT4p+BeSjSOIT3UhCpghAGWWucQ1sX4gluvjXCGW++UY8qlWL/oSoIWRdCREyKD0npZv/l1zXDhMZdvQ2zHVYGsz0HpuCJQ5YOuT+hJRGeOXHVHQBqriWKt/l6Evh/bF1FPM3L+I2X+T8EmIfCQgL1ke2u2pnsDzx/BlVBlMswN3IAk0mZXpIO0AQ1NfFbNRdqCFgZxIQ/UEctZyK3jVeZ5WH9ekJ/RECJGAjb3IyzhhCWkhAkjC5ejUMo6vVEPA27mwG7SfnjKvAjSpV5xTLqB5G3Kyag6+qXJLPSHyQV7VIBUDWvZuYvRBXtUEepr69TxT+C4w2kXH2XGogwjB4gllSi+fhz0CtQtmgBb4cJJgAGC9Qoo+oM8XvmxmoTWO/O1yABp3R3tNQTNAR3QfNWhqrpawmbT0SrjHVW/6WQk3Y4qDXT0bL6TOerKHNJotdLKLDXUmfizO6Xlq74xjrSxsWwLOf1XgJxur1RZlcmhrT4qddqSTjIn/DcnmnGAt8SnVDjthSSlpwwBLAm0WCijW9kpql46K8DIltNQMroMm6Oua3i35i/WZkRQZs4v2/+O3h8HHTcdcgG4bdXR1xiXjaei8Tc0m1fOxPg8516ZR8EI3mz4illy1fGvxFM6FYbRZjNAOxpwgVXHX2X9qB9+wYzXbPSl0ZjN52GmkdfPqMIq02xuOVm+8YQq9Mn6WeTtBsVrLJ+Js2mX2Nft3bC9G7Z3w/Zu2N4Nz3Y3ZOmlPmR+65LbuuRWWK4n8rFJMi4w7mfJ/dhYr8k3jzVoJbNH2VTjwmbfCnhqUyo+mROeWnLXjMayC7Va4FU5+9nEIkhtkX5urZVYKj7bwvTr0zWKh+MqCfbVU600wUGAnQLszPKw1ElUMBZNmYAPSRm/bKaDzcz8x1svmrElh9fkuF7yVpeeKAwKBJQGUU/rLmBWHITOA/v74K7eFdWgCF1uIpWVX8C2H0T89/OzddKh5MI73jSLDl5ameTN8w6M2UXFJscBEHugAj0A9lOlAlzpOfXolIXZgjphBJTA20M4pZPrnyH6M6UH7i259cYspYsZd1nyENE7OEh3Bp5dzQzUQ5WhHHlw3jlzJzKoLoDYO1y7DiBBpbzOzHteZFIWrfQnUurF7xIqFIW70E2rABeY4D1pYIwEPE2KGFM3JgnZhx+UDaZDqBX4IT4nb87e4yE//e1dCpy14mg12pjZqDVBR20uZRwy23CbL6q3VzgR3SVJkT/aGmDNZl+UbLLJkOp3nJxp98D2MSaDg29E/iMNbMEJXDhhK0/VjFIuaijkSXYjx31KOUQVWelOr3aXqw5O5VpJRpcLR6lleM+UertCCELTct3ZmYPl+9wADWBz598IRcB0sZRGC+u2rSPdQh3p/D61VUazBkX7m9fZfOpiz08+hO9E/c8EKn41KfW84TUmn6W0sl4Rw1w0ntSaqMkvZMHIrnQpnbp+bE9cgJGTb3UA2nrpxwF574Ac5U8icu5xIgP6uAx8GcAoP3m5zkQv2KNSbbKmzqTKz81LTT4XBIe5efN5Ks9dsMcGxec2s3DcN60IV7LcDQq55bbCqF5VS8GxNeeocTGm1mJ2S2qI0Cn3r6GZMOWllhhgj7yPo5i67hLkITcGa5uwvillku7WZEVJ9SWT22et8kwGxUPqN3DFmhmb5+G84/6wO+njhEso9tLw9iIf/hbFNIriG8yD5TDlIX77wve6wmtbWE5OtZ5PODI/grhS95EuwwRTfdC79a7552DBKP1Mff997EYOxyknp9ef+Ov83TDz8rB3632QceNKifFF4D84toggFwISR24l/Q4YNK0ZwToYEWjmYOVESzkJAWOahmSwAnK+gfM2u+j/YB4g9TBCpVdcbiosO9RMh7Mlw+URzINrWKJ8R/qdxK2XjAYWGrcS0b7PJ5w4c01BXo/nyybAsqQWD3Fk1Q9+DhYudVAxMTD8lpzutKJF9ky3WpSiyiRUWj2iPLljddU+1d/VAByBISyWoj6Anrdidisq7yp9XrDH0u7UPVoFmbYRqmyLyId6WSbbgTK3797E1lggb5LpwxAFxDzZ5ztOjdGYIvMxkYW1+hgyW5HleHnDNA4SLnfV9cbjhYB/X1a+g04J6hEhQwgfMnlwKG7JyeU5CX28k6BaCschR97P30zBoX4KUzz1Wm9tJck2AkPNEmReYknuYZEbCgZxuFZh1P6jByxQ2hVuvbd+oC6oXB0H7yDqggd/KYUsqr5ZYdepqxWpz/LTW13TjfxWltcnMI3qLZzfv6m0BftdYb/VXFJ9VE9jE10jfq7P1spRqaL1/yPw40X7912ZKfFdYj7M67tTGMjzKLt5o8eaNtdvqw4XJrMhdhbVuFk7pLbumvLqcJrrPBvHvd4YS4kDzQVVHCa/qnq5hDdTnMZlKiFWjx5919oRphANJsfnU/p2AdM4g/6a1rd4T8N7x5sm1JmPFMGn3LGAjn1RiIO4/pSXd+uSu0nsunfHGHzEvMgBu714ywEY7PAeK1Z2yd2CBlC35e6YoHlH/Jm8jdeNF+W/slxGg7tjcuHjz5hYHgrbEEp06N3ItsG/FNz67hidm3GIwkiYmBFka1iTxvGDKtgDmCOKoDhkiByEUSk3QnFpZeUegxgoHAc31ZrpE9rtg+soHruONbpnGgH4Zxqyg70uNyfYhL9K7hmvwMM8K1guUKnN7DG5iF2Xu4CV36diF2wnRJo3sl61HvWpCdgsq9xiUOhImV5asQruN4d7v4GGkt8lkmvv1vuYgiG4bEqtFOa1Q2AN0CIjKxGBzSviQacEYQscC2/UGQvYrfdi7EczBJgltzu8YCKav+zbHV4mCcoadcjtTlIKSZCffP7x5mW98lCgt1QQlP9qUiLn6WmQ85lrqTl4vtfleLxjbI5wGoKHnAUXKDUVZJwH5kF/PbVFCe+btiPoOt8QfgVmStAExQ7gFkc+R7ogscejc23yAjfrJbyZ7pY4LuRFbqfKDs3XarJ+h/RmQtwKdWrpPKHn5tSzsZSCOwMvN9jctomMa8Xc3A42b3wptYEozcjbaMJoFAeMBGBWsYkfR1gQ7Zx7CxJtXDCUjshzEvZIsZ/cwjBm5J4tIsSaFkhFMvY3qb/GffLys5JFS+YB0Yvcf5/MaI3B4RVqdHckx6Bo5KlxM22RebfIvKJIVSOo3c96ijMt/7oCMJW+w0/p1FPXRpYMT4hioTw5l3jhGEjmTAAOjldEzsCHV2qd+fblYe9OKKRfEPZl4VKPSi/mY8JZFrqB8J4DJoo/ays9F7YcPxrx10x2PYm8QbgzAzgtNVinmOqb9l6Fw5Rfpyn6Ad28EfR5FlxWMmi2zDWrxD2bbmNMp803tVbYSfN2UQPzpXJjfOdG0/qcx2JUg2OnEZp5oz55AXxeK+uW3ijVJaNNHAermHL9BfNG1LKSLSu965UUK5Bj+Dc8lYx6SygBYpBUpU1Q1BFz6ZlCujOwL2zOyWrsgRDjrQ8tTcVyru1keaOkE3LiLRO/lKpfJzKpxqCxQrxh6XAVjxpEbYwZ8/IC411uzmsZ1Len+Vue5jz16o9UyXGpOfamkuhf24Op4R8rxzw8RYpBUxfl+oW/m1BBUe3WjHI938wqniOtz6gwxu0B2br4W3Dxp2dAg1VeBHbDd+pMqNt8vm+sfK1CrVnMm4I84WXAOB5pKIIotOZNQ4Qcc0iOJN/LlmboVLB58lTBJ+3+O0kTrL+s9YErJkL4k0nepcv0pUtj24kyK/Vc2Yur0lJ7yYtrE8L6kEgG7MWlIayR+G51LlNnAlyvSKde4VFpqaYC4ze6U7fmw63BYaMMDm2Wlqy2RhSPowqXa3oetxCBW4jAbwsR2EYlzhYhBQsFx8RJOsFlXUsHFuAU2XZzNppVC2wJXB/DMlsZkHhlohnvbMWOnGP05k5n55THcSrmHf8LAF4tf2POdKaRkX7xH8k8tmaE8qxWuEcDZxxH3DlAubL7U0jSa5srwjw9ZeLHnk08RoMxD9u5ZguKOZ0YppEU/PopJDNnOns1Z7YTz1+5/qPaYCIHHHNOz4c4ZiFAOJKIuS5Pb2W3Hg7SCTvohpgpzUQyuRNSZ72pUNIdrT9XLlsYBT7HaYBMUdjxzs4jo/ea5fMDzS18wteMAztSBzXKqgWjiwWjQYjrlVoS6mPHHpPNMyDqzH6LaG39NYCDhwjOWUBDhsF4vn8P3hTIWQgjJAbqeGTw//0//+9geAgImgG1IkxC9kSYMmaK33qYJe54SZ64q6+GJi0eO6isuJB8GwegxXDbScFmiYPvyAXQbkuSzKfbn4DFPGgN0q4xBgBbAiUJos975ASraomqW0jwuaJucmMRvyDdUn8CyWk0SpLQ+EqEfK99L5GbeG69uvPjJYcnBSEiwDwv/MaDj2yD6ncriAiNbxLNrWB2x65zp+Y3D8XPxC+Z5HSm2Zj7fYUkq+ntl/PLkxMitAS+KTtIaxKEdDTG22SFlTJML/ADBQN3tZu6jW1Mkjf0/CBUuFmBhaXcXvK5dSwLWeZqlB1bJZ/LdJLsltZjFeuZSRvihY5Hfa3s9bfA0QXdw+bQKLmXsfbkQjbA2XhyOvAWPiGP0BKENfG6hBggL9JoHY9AWgaWD7y7/HhzR+bA7EMmEBBgQgB8m8Jc8Nv2f+Gt5BIWhCLCtjmGbhqjyXui5O4fb27uSMCiOPBC8uLOse865O7e8fC/ma2669x6d+lmwfN0t+5eYgqAM/V8LBMKdRQgUQAqIKaIDkIzZLYDgwAeG8ZjERE6ptb9rUfDrmOQJ/wNOVK751PNXO+TBQsUQiHv4Q3Hm956fF1DxHrBRcW4d7gy53QpkFS5KJCAhHDJ5xEK76K9MQ2NtujCiajrhLwW7633G78CAwjZxe2jIW5fEh8tFqVDaDo8XGYQFy3qkoBZ0B0XEiBOejrDpOpb7+6f/77FNbvdOSa3kOsOxTBvdyDbg9/1/AEX9W53vnZI5gPboVPPD52w+IkUCuGjWy/z1Tzwiu+D5Hi78/XzWpEnLTDFDD+UXK4CbbtI51L0SRDAS1HWXV+N4K8Gcb/1UvBzxyBjoszudX6W1CkpK06yoo2rpL28nDBaHfQ9jXlvD0g9wYWTpvnsYNXSmzmwqCykIA4V9fInGWa2fGfVTV4y/spdyNN5Bu5ew8lT6sxtUZiWpa4hfwNJneM8j7K4eEUaTJ+r6FZieGM28QNWUrNAS6z1BydtvsXTU9Uo7rZQzZssB7IW9sAChMq2HW6y9DIG4Z/CJDYRqq8/MBtxL+/AbnkHooLn33rp148C4mVOHU8H/U8U5P/Yixw3y8lwRFS0futxTC04MxLCxA/KN6cOiCPjHCoST8kiprQ/ZV/SZOb/jplJrg8AeXNL9ngZmVUQwBdlZhRImdPYpYG6byCJcQVBQnnJ6gl8VyLhmgsYh0jhsOx8ZyHjDkAye0RkgnOkGH7d/587vFzu/nbXI8i/HkEQCtiC0SiBsAMsMEoCLPdx9+95x/uKta2h5nbgWNGtt5ANizRo2aEcqDYjy0PjAM+B5h/cenzYgBUWYt41oMWlSWOyYSxwv2CWM3E4mhguYI9cO3AnFJcvvPVgCh9v3nYPRZo2jpfc9e7SpSXxAsa/J1v7BW+Yu96/B53h/sHXu1sPYmVBEOT7J8biT8igP5RfNYR503gDyrLwKzPpc6R6hWRdT6soHeoi4nKd8feSzpzw/s0DM0H0YvDaCIqgOxm8tSR7RWsGqfILBE54b570CUNN8jxB6w8jOl8UG9YaCLTcROk/YS1pw4UlMgCXBc7paufK8i00LwqTbBVMBnz1I8wCHuEETe0k5vilK+9OCZwsLk2yEOrq5oFMNF6Vib/TEc5vbiff6eyA1TzTzrXlB0yR4Q0iNXlBCYhG0t+3CnK0eBfCk7SXOLX0uKMZR60qK6EcyZO3UR/nDJp9WfiBNB6gRQI2goQwN70X1yiMTO1YCSWD9q/enu7u7h4RTi+rh33UO+OVQYBC+/Hj+dnDnpGYpXrNpA/OhCTzJCFz+RKZVotSdqKoJednRDr3sd4TJBk7XEO/TlBhRTI+wrOh77374T6i5PzsMrPw52cA7hCySeymIZOwvV3c3sy7Ho+d9NGfnwtgQnBP37NpsIRnAqITnMWY4B2H3CdEo6xeomIYedSLRnGgQWiBLYMEdfLx6l2S6M8/6JE3AK1+uzOLokV4/OqV+Nm/j2jP8ue3O9reHpnrju49/9Er71HtjGMJkWtn6lE3JG8DOmePfnCfZrlzCmJ8MK960EEXO3gVhqybee3Vv1XaAXr6+up2p0fkFCDIwrF7HotegRwSih+60NBE9twdjPq9WTR3/yOYWL2QGxp6B71hb6CZse6uUTmNhpxzFJnZocICJrwmc/arOOHaJlste/1a0WOdWxbOR3bI8XxOTYTyOGTBWhfpx5AF0CPA/Re1bd68HFlz6LQniFKpjToxDAtpHz8eSeBpkNK+XTlTsUxlJLD2WSrQ1NeSnnCJTZNO2oF5KyWuLMc+n5C7C99jd+SFz50ILzsC/5QDeyWAHCJiPVVIO2hEkgAe6dtYVtAk9LQEtrNkDW8EDa65gN/ykCVTqDhsFYSuzquWuGVfrRN5ZhK6F56KzsvixEWwn4P15Ryo9g2gKWix459wwLcclR+jQQaJVkjo/LVrf85e/PPzy7tjYeFCYBu1If5Gr9cTL2V6ZhH5G/EDwGRvJx69wD8K2YarY2CanD1DbMoNvixLb7VvcitpzisucZvnNL3RdQ8+AHXqjxESLrOTQCJ+PqDaF0j0oKykKRkc9xW1IERanArlBTUo2RbcDMk5JI5nswXzbF4WMmk/9frXexvwCwl4vmrqUG7b0jbLNgecTpW65YI6OFfNEiWKHreNWslNKcADaSSWsnbu+JopdreclMHLueVIulEaKVuY9i7lRlUA1MbKhvaNxa3k9KVwuq0kRT8JqO71vbNIEUOyZC6ibQl0xrE0vvDCJBj8KkM7qEfdZeiEwn4BoTB4cYqIwXriLnHfCvQ4SxkEIrwSUaf73lmsMIYykzofhFwVvl8ntu14J1zpf08XCyPYVhpHs5FoeS7txXUcnPcUR7PCuIrNZcf4s0CpXZO22jIUZ8zxeVrLjtjAFD+uepXa3ONJ3cvMR7Wmg+y6Fe6EtNPsuJ+ihEqBxTSuorI+m+KzewOm/avYZZeB4weOdvxJsQxRpGIOvtqFywj6BUgQA25l8jmEQVGP0MifOxahaG7r3HqRT8J4gfbxxE0ZYoR+SMJHfspENEDSEpieH32lG5MYN/Y4WmTmYkpAlf7B3H4Uwb+z3WZJSLGt/ezbBnayNfwR6O2VuEUQ4ch9ENInIZV77qpIEbOjmRPYXQC0Xuo9FeZWd0ekDoiwRdh1xObOmuDJaVItHGcTmhjkz8/IC+l7eNm79aQh2AbOAwsY9qzE6wNW7Vd04YBVmC9T+Ipn13U51nK07ArEpyDsTlnUpV637AUj+DwTy3wcuNKlwt9PbOENDPPqxR84BW6cMUALWkooUrWgrusUrciQzcA7oMeT5XzVlT5fXol9DS9zuQ4YsmAlaUp+2Mm7RXMjza5NZvJyEz5lgPzzwyjm90rLuxvPvHwjugyRqyQ/xJ86Fj+OxRQQC9k0JIrAeXM8rsDxkBLwmiE8vhSlMKSIhzjfejyQxE4rLookpUiS9ti3kY8UwVGSSFACoaAknURHw1K2WS7bLJdtlsuPkuXS2QH2UeVZTLI/RiLMexWabDGZRow4k/7+mx/cs6CScUnAXiLeDdjUCSMmcgSUbICN5RcJnkE9JfA5nokPvntec+49+JD9oeQ2fVNOw2daHuUkSiHwnyHASd5dkgh/CiUZ8kh4C1NiihYSzVr0B8Pdvf2D14dHdGzZbJL/+xtywjpO8ohTbp2BKLuxAhcpSG5ruwCKGXjJL7+KFSqSDJrUMNtOPSoiTQ4UoAXWrIQQ8FBSE5f8wAYXScw4l/uBqzLR8/y8k+xLfrQK0Wu0XtAmE3Ux5gnpSsbXGbjtuDE+TbRCagfFMuK1lTF8Wqbs3e31j+46WIvTmjHrXsZHByFP37pi1O5CtYUeOVHaBEsjypwyIF78e7zkthFpw8iLoTgWUXEKsw5vvfESkxmTAteQyGdS6bMUSjjfKxhQZDRZlitKn894iZxzHTHgRKyGwHhIrNUlaIQXSax9cazZUWaWOvLNAroTzrVbVS9aHWGK3SEpsmGpuTa8oBtUfuMJ4ni41DUCblHF6Wo8dmbhP2lPRSt0Vk7JAnfyviVYQ+ffCQN7YJGvFDaQo8u2eR3RKNZMIn8bjTw/GqEYnjDCEQsCFCHlfcTsosmG91IJCLGVOLcS51bifEICbVsmLDnbawuEeV7xVd9PgWWVMIMwec+sY9FufrlEMyWTbgAPwblmE3a2Dl95ztOPpyTY/POnD89Qxiw3mS6croSwUCxCBj4HuBKNaG7OwpBOOddK/t3wuzCuBWlk5OTynECCBqbfiC8msastwJYsZsZ0D398TtKFR46R96VEir7xI+oqeau8zTDJwQh4vUcGkVnBg2OpEr6QcZRhDkBIpFMNoQsPHYGnMnppQaeOh9ks0igveq/vgwUjfT8XhZkAogf2atj+sI9FwiLqlmkefM1k+/SBOijn4rT8GCJJliRkNLBmUIiYzlnu5Or67Ke9LiTpaXLJk9nhqzgvzA2L0grJfFw5iHXNMvb7XwuSsSTgjjw4ylkoOYvz+V/8HLazhN0Jddw4MInvSpYyGdU/4XjbbOf4db+/m/QHp8EngR9HLDnOH6/Od75+Ro32HeY67xwP6oW7sj1JB2AAC6w2EpQmM4ulBd3xs0aFfLqdRbDdpH/8q9HeJpPSbjLYTvSl6uqWTXfcRA/qVpTJePlLwFYHofGwDzgnskWgksiWC/R++4TQdGCvfhxYBuSMtYFZoGmjwJ1w9GmvhRqBnZ3Yc/4Vs3M+eWkRSYkU1y0cnaIcfQmO6S8/O57teNNzbxEbhGJZjq1Rmc8vAfp54nwBTnx6fnYFVjlZG5OMHU+byJIKSoN+r98b9PqvhnvcygJtaUNjshAlC4pXato9D5XhMFTcUQ2jqe6cDsZDa9fe67L9yUH39eFRvwviWZdNEnGtz+MSJMM42OOQBkAZ2gLLV/iMV1SGKM859SjUrebfhOQFBKkANFQsIKVYfLujBeJOh8ni7CAGw8MsF8sTS7qKHb5tmTFLUnjLImt2iUIwH/WVOGr1tGBy+qoPdzjCCtTyHPOaASmD00TvJqy/pQ4zS9rPMOa6lvhy8aUr6mgJoyzjj+Eoc/5WPXo3gsYTC/0YTGIrQv6M+Vi0Xzc9lPz9EpSf8qNzw7Fi5PEByJTk7i4dXrODgSfC7HRktuhSSutg0TY/Jq3TbE4Gaa/VglDSuM0sSX9tSUVLVRociBT3LUWj0rg0viI8Uqgz8X5Y0H/F2EAoQASxNBPEw2Bj5I1a1v4xxSEC+AvPJ3M/UTP0OFbl6lkRKInPSSppuokUpABR2pDPTuntczX/XEWYy+6g9lxsbwzDG0N3OppdGZk7x9idpg+MbIJlUhR8fRuBqtZquxxxJ3NBNOL1nZ0HFoRZ05jCEcTDUeOlqcYiTIbbURc9u0zpyLTD0G3x9sZZRQrbXjg/3oXDUz9W0VirhM0L9qgKmxD0HIbO1NMraPBfa2JRjwbL9tU1jfQpoXJ4/sTE0aUdnyfPuE+niNNV46MY7rJBf3+yxyw2OaT2kUV3B/Rw9/XQ7lu7+7vZWewOM5OAP3X17HDwT+2xCFe0lIZbj8XWY/FX8lgUzmK7Hovv8By2s4Qb7LEo35MGHovwL+axCEdjao+Cv5o2m9WezLVZyNIyU2LFqOUqZ4dgcAsaumywm5E1o44GM/zDgmcpk3gRRgGjc4KvJ3lQcNpOLs8f9vjvIvnnMaALYvuPnvhGXKhEnHz1hmhPx9J5gqr9QGJhp77/F6Rf1RpTT41yrWZ+GOkjks4urol8KmBHuWxOXedPyALHSjgARgqVY2wfMOKl7ftPqDBKfnNc26JJPROeqC/s2JDaiJmtmKlM7v5PT7AzyE6+qxTVJ76vvlxSSxomZ6YwtK0YlI1m66VdzUuLDFYzsMINCy9Xqbliy5dgW0CfZKIoTLk5qpwKLFpBZvJYJIepAfPJGuDqTn0KRp7PD0xwneVg0rOroDtXznHYH+x1+4Nuf3DT3z8e9o/7/R66fv/QGS1VxlE37OTdgk2z7kvlbfjWjyPhI6z9ULyaJ8pkKDlzpXw/Y7j8nGzwxt4l5pxeWbwCMhPPEiCPM8eaEfEimbNo5nOIlpDlDotCX5U0ZXuhWsha/F12kJqC+BtTr7ZDL+wi1FPkWE+rGmY6WklJLG1ho9XFugXeXMXRaMfMVcjS5n54ZbKcBFYMhKs9tIVeoSJRcZ0wJ4JjKoIoGviPaG2z/PkYDHuivJTtzAEO0PdE4mqVnpPLEJBfavaI961pvgPFeaCGh5ckfdYMiFh+wFfAxi98nj0Q+I9VQ80J+tk2exm2evHh7OTmpB78UplvQdD7WtyTqtWBOc9pNxTVsVMTa/oVAoUiKqY0ZY5raij/Cwo8yWIP2cHw9GPNSK7ZNBGqZZKy45GfkvwRwkGg/ICv3E8VFTPSkUiCPfVt9ve/X3x4c3X14aqTjO/vfz8pDnGDFJnMuLCkU3FI77DSk2qZhwRpZoNIETiWvpKSat5VRAbQcLiOo+eiW2XKXJnKrSDuRZMDKD6B04f0anDkTsEP0Yk9C5Ou8a8ief/LrPpaQ54Kwmklxy5jgzJ/XX9mdW7ndJ3zr+LULkBMhh1QWI35LSc/Asgzed7Mv+afIMGW7bdcOv5G03V7n37VK+y/gxJB1XqlVMJFB1y8G2fOTh542lcIhd+azZl/ggcx0LCnIq0gScPLBKC4HjHkgAGEWUpNUNx3zEQ4J8c56JIX0DDDu/clYDf8jbygyQ+rkh55sVpf6cr/rQG95t/tZikWqzo2W33+SYWAkNKi3F3Zj6TwIrcK2ELsZQ2P2Ep7TyHt1bKPZG2hW1zc1P3OP+2RN3Ci8DlCL3MNIB2G2fgv/DmWSBDMKv+1hFswIj+9pAqlcl1dnmzqoOfVtqDebPTImJdERIFVgiP50RBCv31Qk5hNEKixA8Ij9XzUzziy2sx/hKSIZdIgbDpWUJW4paKoZqU//KCfQ8ac0y8aPi0CoNQwCeRxYiVf8DUgcwGbq94GQGqcBF+qGKvUfaRLXgQY47Z4C8X0ae5e0wyJD/obDSmROsxZG/8ELZGPujiHfESK/5iEOPA51sU15DYSQyVKO1KXTYpm1Ar8MES8ciQk0yUsLlA+LgtmnIyIbyinNOXIyEXlP8n/lHFzKKKbLVW5ZerfOVP3CJUrI9djHPj3zEPvMaI1A4tEteeBuuuxfYPG17tEcoPbXirbS8X4UtmqsltVdqvK/hiqLK8CPrKZy+UQ8waU79ZSiDMj+PzXEEDFnOV1XnXcM/e+OmMkBxyIlFTESyCtJJKaALSTwotInEdp7FGO8BibDCMa8Bs5BTdl8F9nznq3nvExUeQr9oVaWLDi0ecpKRoRkncLHcrOyAuYHUNMP3f5kgdeOaGxBARsSScsDvvD3e5g0B0MbgbD4z640f8oc74XzmK1tLSaBpGjgdxznWpR5lLV6xTmZxm/2Mpyf0FZbmsgeCIDQfH4JiJSzhWLDBALRVHJAdGxiOoojBsns2CB49uwoufXH8jhQX9Q4ZKtDSjScMLiePVimaEP+wnlNI1DLiMfdRTpqDCrrLiTq9vlOVFy5yZ+eFz+Oif8zI8DBcCWulhKKI78nc7OktEAyYMGEXfL+l40w1r37B7pBahGtGCzezp3vDhinNDgH0VaSgS+7ATeePa3o6TdHCVxeMUuHjcWQD706BR/urjWkZWwmYuURgHOSNKvDaArPbgjLX3NjxNck5OTE6iTY/E6NWHoWw7SMIormLCr66/Gmsbf0gWZ854QQL6afE4U2oF/wzg5GH8xTgHZVmV/ohZkSF5Qj5xfPuzBaTq/fDgg1LYDFoY1p2nQw//VRhd+1dwmRrVMvHBkFFSrpxz5NW8Imly5HTGeFKo1u46fWABFaLlRk78kY/+1xKFZvwdsgtnKps79B/x7wdkZBwjgL33WVbDSbTykHkiY0xWmnkbadIdFlU05O+leJaukdA5GQFHahR9ncnFtcOS7w4pDzwuwbc/89sxvz/wPdOYN8Rs2i0rygM2ied0SED7B8oWglpemWIyeACJB3+2qgfg1TW2BFLZACt8XkMLa8EM1akxzqAYTPlGeP7DlEVoesf42trOLT4yH8+Nv5JbZb5n9s6HmGB3itrMlf9AD/GRrv9GJlA02s1FGZU27f4XUyjrqWD3H0vDMl48DnWsNEuf/8sxhe7tvb/dnUeXy3jyAltcY7XR2tjn9IvILKyCGGl1mWTbBzd9bRrFlFFtGsWUUVYxid8sotoxiyyg2l1Ho/IDPwymmLNrqHVsuseUSz8olmAdj1xTFkjQLbnIAkgtl8FoX4T+L4SyhCQnrWEnq2K6csQhXILw3mKBS8ACzLwV+aeW0VYQa5GI8JndfhZMpiRJpgcdV4QGdiNjA9B0o51wdl7H7esgOXh/t7/WH+6w/pgeU0gN7//BgfMT64/2jIjZQFg+yHCuoLtxiA+CMqoe4qyEoHojVZIEPjo7so8ODvaG1f7BnD9nh/j47OjgYHB4djV8P94drjXaLhZRv2gwLqSJORstE3v732YWGhVRGBCsomSk1eOHABMG4MgTHgM0hawP4bswMUpnemLm+N4UQ9KfhcqWDj7axPltBbSuobbQ6t0aQCMZPtiPiRNton28Y7aMJhF1xHzE8ds4iKhMuazZwq0eY6RFixSdOwB6p6z5HXFXS16oHRdvA9hLdXqLf1yW6AmMsO6ZtR079AEe05dXd6Nio2u1qFBGlbe2vEAel3//Vo58qT2uhzyii1v1o7kTOlMorN2eSw1dI+gowGsg1VhCFVpCHPCKedggkUc9p5MBeLGVHjATUs/15l2eQEz5STDxfBH4EWf9JFTBIkhNy04pik++5yxGU7B3JRkexN2PUjWaaWjxgO0zHKUeGFX+TMYnxkJCxOUnbMiCtRKYqG+5XXfkgdVeTxLMR9cDvjBd61WHwScAmUCgFhEAvfGQBEahRCY84ufgfzHhccYGz41P+6FpuHGZtZyXUpKVV89NQ+PqrkqFXWCjjdkuaAJsdYIZR1x1T675Rk5kPvyaC9QhhyEdRZIQDlfLTwtdfE/l81SYLXyuF4I1bSXL6GGzIA1txMJrPgR3TiBmjtCVtpV8hR48Cp6HgIb8BxC7JSJxFszYyHxZ1Jd3h6S5oZM3Wui20Z9Ksbz/UXtGZHEtuRc5M7fP2gG8P+PaA4xEbJQ+dRaqENjm8mhYMeUdVvEndGdYRmo6etURQejxzR0vd7HTXOjsORPTlpo5D8m3MwccqeFsms2UyWyajOSdr8Bds0LEbNaFEfXzNHtFGNKN8V6jrWc3uAgb6GOvaXqjjdDmHfqQJTnlPF2CIE3yTnF9K4BUONnd5c5WHatFoyNS2nQiLUF5mYW4yXRXb0kCgG8+3bfFQXUrjMSSmCDCadsUCV9038EoTw1GTIerv2zLDMoLtZPY66ykB+8Nb0aAkjx5BKwGEkxI7hh1LCAeLtIIhBbCLLOp5PpaitmbUm4JpnEaZuAxNlbGhYiUYKp6XgQqxOKiZd2XIDfWWHyZoQ8xZ9V0/ticuDViXrwGzcfrqEuXw43Z7/d5gsIvIQ0loibN42DOLsm0wgoOSEfQHx2c/Hx7T8fHx6dvcKA6MRvG5cPoy4M3ZSaZ/Dff38G8xgJOfxQCSX07P8JfPhmhL5dv5xGEpP4Bpfus923rPNiIExVAbW89Vl2MOeBmObK9JOfC/JHdYfQOrZZ32NpN7hrb7+FT7qDmIa2xdXn0vdcBM/OCRgrjvOsD3zy8RJN93H1jwkoTx2GMRcSbE88kbkHZO+WvX4gH4mVQdody7VOuc2axyvRUGiMLofl4SIRV3SColgn8OEjBRbsevk9oK/NqmIYGAYkLDW8/xbAcRG7Eg04yRm5t3oIgx54HZZBL489TDp0ZrkZsZ7gE6Rm+9kEWI0h4v4DYd+7FnE9/jocx2HKD03yNv/QAHBLrBIg4WfghVoWbOFEji5uZdeOs9Oq4LuoHNQGkAXUKoHGI5OMI5TNvx5KDTgfRuvVtPHRmxfRYS0DfoZAIuVDlF3oy4GDnmKF+iW09ZSV4KmS8k0l/YUxcaBysg6iU5iw5uPd6DwVKqhSiK1/BRpr4y/pVoP7sH/QzG/G7fhK62+Qcr5R9UmPE2/mAS139sfC75N9lj6Xj5YylqPvyIx/LWu/AjhkkZHaz5IfGV04l0oOGAwX3k+WQa04B6EePfEHrrJUVt5ALyytp8tyPiMigsgtkfC2ahoU/ZllN8N20klDUGAoY4vITRwIWEpgnu34JaDpTICAivScLL3aPlDdqgoe/VMZsDldccrM9qskbP7Bl5B1Pnb1hJuUWdYWkVCP/BXrc/6PYHN/394yFA+PcGw929/T8qkneyBnYtLnV+ZER4iMrlgvdLcvLIQn+ut5llxYKBqPyihKTVD1brBcgrhsrJA+tq4Lu8WA1ym8zAwhmWquHcSTaukuAL1pv2OuTi97MP70/OL17yEwQknI8E+k5Pfe1lXHkmsnFKBhuY8bjoS/ykSj2sjYxTWmAYO9QZ4txGchgxd86il34clN4TjGDHwLyYN/EDi9miVXglU+ZEhM2LBYQbZRJQS55aXjfVmzjTOGC2KFSFHVAriqlL6HQaMBHjJsIwqaiMBAW9AmRsDzSAa1NAi8M1pdRT4rFlsM+i2FaPXCU0iY/FrnLKtX2kM55bG/mCGJyQz7hHrnn8P+wW/Nd2QjTQ4OjwlfoiTf2MGVr+T1YoWoUeUvdZueEqSiLVJizi97Z6bMJyAicvknWR5cocz4kc2CQunbystEOV2OGHaqUjg1nmvXxNrfIf1UjIa06cpRb5wdGw1+8N27LHl/RdY4sf9PtPZYxX5zc4OuztD3oDuPFUu7vsvhD0bGyGF7D6I6jpcIX/1onpElAeK1SI14qW5jloCSYWC9mp/KSBw1x+Kv3li8D/4jAjH678VH4CiokMAW7wefINWG5ps2/xffjOzK2ffMbd+NKFqikf8kBdx87Qa66k4F6/f2yN+/3jYX/v6Pg4f2jMKBaW23mA8A4IvIe3NIWd4P2QiBeJx6JHP7gn4gOpYPiBM3U8E7NYwpgqDD+8jfxQrozrm0A9E6XESWl5k3zFBUVO5Hv6OX+qDI7U9jxt8nna058nhSHvrXb//KBHKVMqqJ1DdGpyM51uL6YNPEhv8VyAuQv2R7wGcjojP4Gi8BMWYGQRPk53rVcIijI7UjK9OeeDTuYAYjbFvvgE6qt2TVyxkLl5wc+Js1zboDbPOJWs9/frZetIW9+W8mKJ0LEY61Kq/65ipBNhV6jYHxMnDGPW4f95dFy7QxzfZpOaUlv4eslalxT6+oQquRifWBRuvJw4zLV/ArVuTj2oDSm0Qm65hLghP2ReGYyPPvt6TW51mrn3T1u79k/fXN0YsKw3VzdbnrXJPAs2qIppwfNn41rQmSnbou7UD5xoNtfINvJRJa86bMqrLOgcbb66KKD0oSkm5T1bjrT871e2JDe02oyjctqD/f1dE16r5SQ3WRaiMR027akNrvXm6kZlW/BnS3zr4uT9GwPGBa/9qJwrV/NaPEnu+rSQZf0pBGVg5CM3qM4chndIWvpT2nynzGNYubpTLA+K78iIWwjEZXbWSQj2X/CmerZwTLEvFltwxxGxaMjCHkkcYVxk8Bfc9AujoYuF6zCZpwwLlVYm9WziRGRG0TvGuNHf98CwjB4qxXoPOxt7ePDDtIwp11hIDCFAmQqgbSkxYNBosPCFddWs/XbhTRZ+4sLN6Y0svbftfJIuvUURQAjlZ+Qnshytz32hGDNkE/YlYoGHGfVYKnwmIx1hCkI1TxZIeLHSarovk+bAycSglngYMWpLATXTsxOFzJ0UNzP20lhP2M/ctnSgNrAF28mW6MqQ3iq+FhkY5jUW9+vmSEjSPCJxFXvkfRxGeCjmkKGhyP4/ccxD01t/3ZsRtlO9GvHvdu7Gs4vrX9/8T/3lyN/7UW/HH0KuF1tUIdmLN55LthfdPZt0v99Uuq8yg7QtiQMsim/5moiHS/GkssfdpnNbxGPXsUb3TCMtXOIz8itbPptNgtOCwsTEDy1xsWsDDna95V6bzL2uKznX9fNxLXNNaG2O1fhU286UhZp1PMPfTeUR3spIf6R5U6TWRtDY7vu8to82eNa1yq+uW+JVv9zcXBqwK3xty7E2mGPxHapgWvyF5+JbvDdT1rUIHOBPOuFAPGndFEmDqRb7Fn+vPom9Fbw11S1Sd+H9/XZnttuZDW93CNi0Zo4X/f12ZzB83etDhjD/+UD8fHw8uN15KukI905hNvzvdvjNuw+n9dzm3YfTLa/ZYF4D+1PBaeBxls+ktHV+gY93X5O9A/i/CzIYDslwl+zuk99If04G/f6c4P89KX+CQZgLVpETxbbmSJ2IJ9Cm64tYfMcjBmnJagzs3vBw7+jg9bB3pHKu7kCExepm6dJoZLNpwHTxrmf8AY6K8hFWC36vlcEc9eu5J/buBCl2QD4/QSxL8k41w7lQmA38u4TZ8H7njhdHulm/5w+MZ713oOKQH5nNmoeNa50Y+GDV3ntHRyYj8L2p2bb73rR+DINhBhDk0GTncQQVWy87Nt3735S9B7Pib6V7Dz0bbb7R3Ie7TXcf+jfafqP+d/dX2H8A/nJCyBCc+cGfxVH84gfOn76H8AXyVZU3GXOko2JMfu2QHliguTU+AR+1nnFAofOnhlNfO3+uwqUH/VUG0YIM9u7DqXIw4K925K/3v9eLX+9/30pfGyd9SX/QnDquzClKfEMZ0pl/ydXc0tXoMgyeTbSywvN6sK10L0Qz65+K978rh+L97y2diYuTy5ur+mOBr21PxsadjFQv4TtUoZnwF57LBsJ7ayMK1tSU6ge2DorjA/zc4J4zdiKxCQuYZ2mO9GXyrKbf5t0GbMq+6JjIlH0xXaiALVxqsbmWoK7Sh6btCQAvnVyYR/Z6Ws8W0pyqTuHfLfFJA0PxxdZKvHkcUsoOahkvkAVIUXgoVux8hpCSC9XaeNGWqfHD5ZuLy39cGgWUpO9uyXcDyZfjmJGfacgO9rrMA2Aam3xYMO/yH5fkJqBeOGEBBo+l0QTkxdXbU7J3eNgn19wSQQaD3uDl89B0SlEKbSs/tkPjRoLrVmzdRKo+8+fU8ThPRkwmJd1Qmw757Gw5K0m0J0dcvz9//8Yg3ZC/tyXdjSPdVOMSW1Shcok3nkvnEt2ZKl1tZ9RgaK7jTUuiWd6Lx/XxLP2m8SwhA/wJX6P9XYsn7fYXh1qM4I/wc5tRRi3oRJwmFFYmfmiJm119MmBlV5+2fGzj+JgMLumQR+ZMZ1GHLPwg4skosGM8SCTD1SA3QaYtcAQg23lwbEBqSgbDUZzyYAZ9cn6Bre6Tw8P+AVGu8ydmiVefzANxfJ0PB+Co4InM6DCBK4c5rmJSat/kXBLpU0iw0PAQneW8TCDTTYeTlX5BRUIMf8U4kvy5og2vrz6pDPPqU1vc8vqXt5cG/BJe23LMjeOYiuSHO1Ql+OELzyb3YW/PFio9bJzc4XhTFiwCR7uq6cP1krjaDpNug5HAxqisBP9uiZl8Ov3ZgJd8Ov15y0o2mZXABlVxEnj+bIwEOtvGLX+PccuwdSqngT/bYTQ3764N7FXw1pbRbDCjwQ2qYDT4/LkYDXb23dupGuddfTd2qoY9tcC/gCIU/oV/tsS/fjeAyrr5fYuUtXnc64Z9iSTPUirHWQLzjSXP5gAPYfleKOq9/Sv2gefd7lgzCoDjgE6ONBfe7nDX6KC/u/+yw1HKEb6EEhfRjeHzeAFccbi/T8bLCOBUrvnHiLTCbG7/ckJCXSh2YSdFZkQLiNERR/6cYvSvuyThwnUiBLZ/x2jgkbmPZT3I/zWLokV4/OrV4+Njz0rQVcCq8sqFNx1vCiumrhr+O/oSib9f/d9ZW9vtzsPfw8VkADU33Nhmx4qlhnSp66IM8gwetJvfVRAp+Kud8/zx6rz+PH+8Ot+e5407z6k0AvtTIYzA4+eSRaAvU1GkVANJbZpyVpVnA4798atXytFM/j2L5u6TWlSHjcMOv25kPPTHq3OFv8Bf7fAXunDSuoRPUyVWdrVq+UDd99sasdsasd9XjdgVykWWnNH5fHs+M+ez3aXtTqjjxkGjEqppnRFZCPB1v7+rVPHbufARaJ4lxx1Y+NdCoZF190qpyLdaY4VCxsncxZJDrZ7P+ZI9T7rjAsNP9I9/NdrzZFKVm88DT3UTN11G3THN9ahI4wUxbc6FtACA/6B41BgYXA4jVYH+LuJWZoob1SDM8IjEBxakheUCqUCU1SWSk6jICT6Tj0C0xRQVZfTAPnXDSsAad2hoKUIO/ws6KOxc+u/uGAxYXZu5LNLunkoljg1SUw5VtpGWopTBRZZeOagF/P96NrLGCDo71HVF7SfTBpRh8gECF8qvUu3U/FDLJFYZBDRV21+s7W5jFhLn0GgdS4kjrea1wkCEYNRFZRCqcq3YhmigavwlFPCdDL+qUHq5BiV1faFtp4YOrlwppotOYnkR9ogO0IP4AFlrZ0fgHUPhz86OWgYULq+IAq/aqNUssS1VVzBFhOhItRjgRygBuGl1U4B9/jB30FziTDIFY8UXlVFbZSVOh+UlTvM2FrXGW8SCgELjXVmxkY4dFw0CMOtFHHFLlbKDtROHCUuE61WmUlGttY2prM48BbUWCy59iQKqoGh3RfleC+AYKBa2TIUcU5uUzag9mmq92Kmg6YRkKkqZIhI1r6cqCmCOGWJlE0rCGTdpB+TimoAEMeWSUETvsU4Us5gNea3EfxDyq80YKLnqu4A67jEG0k3UI5e87ibHHn9ECghi9p8kANM7qq44MIsGWJwSX7tzQpzRHbcN/vOjl3tbLPrnF9J+brMH5sKqhHkzOljP59SjU9ZVjehJiu6rcEZtsOLLR/8Rp711oTf54GWmymupIpYlPaCj0GR7TkDQVZDiidwyXvU0jMc2F1EzOyMW6B9PvihtLIRsdDTWBI2cn4UyxFaRj5GY+Hdq1SEx7WvR4JNOPTvbQqnRlCHtvh6yg9dH+3v94T7rj+kBpfTA3j88GB+x/nj/qMDivlatUaogae1Aqq2JL5X8MinQpCOUb7BiUKpgmsN/ykAvFVFlcqtSWKfV+HmjS7l4GW/gDZWKTpU2BilnUA9KFcjqAuOlWs+Ba9kmhqY2Bg7yXzMhCb4gjyAC1YlIMBvPxw9WE5D2n3DPKjTk0KKe0O2oBQU92tImuUpr0m/AsJtNsRmEMxowu4vGnbBe2d06dp/WsdvYk6ZVmjTbaDtw8ufgj+GxUbLs4AXuCX//6yqqX1rZs4myp1TXa/JZpoBHow+vV/hIBa9u8l0KQtvkKxUmqsl3mXTnRh8mmYWNvlIybBp9lwbTN/lMCY1t8lkawVJlj8nYKp711KwyJ6W8e6OjphSEa/JdAuXXiIhXOS8FJJUmH692aNKIxRL6QLe4uLMFPdTejtwfoF6jBVVmBeEi42vAOBH44Ym6EZIM9OKH0RP1gXZrrNryVD3E0IFe7OEbG7AHhz1ywcx0e7nI2PaIizIplwJgCE/Yl5BDy1ZJOBQ3gf4To/nT0X62iycg/GwH7ZO90n7lfm4O2WdWpEVqz+o9xbUYyY5H1EK7zyiJ4N+GtuRCzwycnx6v7ChMaSMICtcY5d+L4O00vkl10MsQb2oFfoh/Etku+dP30ggosWM9AgYCMJWj1duZpK9Ds04oC1T2Ki1kgyLYMliSczMqye+Q8W4lM3remewXp9HyfvD6aiVzuIhhnhNRkhTe6bpg6cQUAdp4EzRhPi3tRdUsmi1wTk/PjC+3+GtFimUY1tgssuMvyqia3UE6+aa1jdpGNG8jmrcRzU8T0ayRTdoWoFviAs4cMI1GIGtv2cBK0mXArHBEbZub/suOTeayh5erwY4Sqk1cBTQIdT3kGY3aD/+mpqP2SImrbVtSav3+1+jDrW1aeWz3dr9asRm0sEdR4EynLCg9WStF4YuNr+oXVJCt4WG9q2Ft/VZKjLAZeS1WqIXmiuzwSZVYITDhSKv16f1vo6gqZrdi2FnyrDo/pD/cZYP+/mSPWWxySO0ji+4O6OHu66Hdt3b3d3cwoknmLe0O65NG5lJjLiFdn+AbaBwQ8q9YgCQvhkbEZRAO43uMvKDe8mWPnE8wgzryyR113bsOoVYUEte5h/hO159iPbKTizMyZtEjYx6ZOC5K1JkvvWXJlx+uiOOFEaN2j1z4EeMRehwNNGKAtQAxoLLtiE5l+2AwgmDxAPRPEaTGyF1Ep12c510q3Sc9qGFkOgQmb5lNlnFdNVkGn8JveXpQ2U6ZmJ5X92yVGaa0nVDzgOsctm/FsD0YczeKA1f5Ko36S5LgNM9CPw4sA86LsOmconNtFEQ7HH3a6+diRHHsOf+K2TmfvKBVJXEut34yVKaYVw8uFoU3IMB7RyBRSNRY4BPJA3IZe0sYX/Xpy6KNKgdNgtMoCYN1566kTtBbTCHTJmmNl9VJWiIERhKe+FPEx6QJEjwfQgb/5BdVr4Bfgqqdst1Ux6/QvZOBDVT6zHdnoPNnlAqh99eBtaadZ6oq7RdMqYUBlcLJXQlSxjvx/e+IUJyCNoT/SZyp58vnPjJPGTS4XLCQvBjHEZnTJQkjx3UhBDJgURx4KRc6uTx/2RN4ISGHg+FR8GJQEJgOYYW86FPAsmmHTghkM4ZYeIiQx+1xPDKhD34gQ5rl7MQnwmSDAfQQ9T+ni9ZLRekizkzCRHmQNXMe5IFdsACDJiHuH9Y+ZFaMcxkzj00cjqORhpKaCFYJlYhM1rrx8/uvOPwTkJZCcT3CeKGyZexGzsJlCoAIB/pQ+FLowFvUY34cukuxm8r9E+Jt5tmCqGbxnHokDlkQdjBxQqL7QFz1eQS4QNSKyJjN6IPjp9/DC4j/47JJRGJPpHuA+8LDhQ5j5MBAP9aMelMmhalJHMUBKwzs0Q/uoW2bLWB0XuQuJYXdiVtURAf2yFsQEPg40d4IS8TCDlmAyMBgNvgdPzCp2U2xsdVcv0XMorxaoUY35vHO+JNEzlVSemszXgBqceRjHK42bFj4pTo8meQk4WGP4vhPmccCWBWOdq4kXYh3YIvHLMlN4rsgkc/zxAGYUAu+08SikGicEYyckPj4mI+GLhYuUGTkJ4HYiegPNBEVs5gfxRlVorUhbjX2EPVO8CvcysCZOp5QEs4vH/ZARjy/fDho60gCmGWDhS+sq2bttwtfv/D5SIGIThtpDyCFP6UGoUj5a2sRAZvGLg0SdpZhyvwCj0OGgprlz8eOx8RnIA7B8kMpage3HbeHszepg2A3NGDeTxEJmIucMRK5Ak+kbETaypancRj5c57VoGGBK6EaFHSYnKabVmuADRPXBtzsKI0fIxIueQE/Yl2mPKYeniKXRRG/BVFGCTsk9mwWhJYfMH6QZsvFjHnhy8zi+Y8eC45hWSJGTSs4JWv9z8/ZVIvUhdmV7bBCwryIcM+ZzZ05Izc+eec8MPLi5ubdS7kOinDgeESUOoekqUjWphqQOaNeSH5KoP1+6hHECeZLNWbJgTjo41IcHuz1+52UTQiJjQTMji1Oebt93P43oMotAifk6lG1e2v3AARpVcpPQ3xzLyUyIx9KKjPu9vMdQICqoObB58LDkrr0mQVfD85LRf+Ef8PtsdPZOeX//80VgAlitPBOZ4dH2sM/oHgiRsLvdETZcCyTLCuBYnHFTDU6/ntSFYeXepA47QJEWWCRcgDDUmAxPnsp4iQRW6rMU2M79SZ+YDE0vspLtc4KmnRX+PhrZwcNt4IujGyqSWvqH11pXiy1aGf7+Vy3EiND1I9NXw8ZflyY79MDxiV9rWo91zawDbDYBlh8XwEWKzgByo5p25hxP8ARbXl1Nxo2rna7GuHGaVv7KwDH6fd/deS4ytOa71NizWASd3kGOURRPC/WTI2o2BwuDqbQAliciXxTHBJvX5ph+F3rsUcRqiwWlXN1wEQvxCyXHPqJC1DQ3oi67sgCjbMZl9R8DqWm/NizufPN9ho2mP1UDbdv2pT64WhMQ4y3QLs0WOIfHOGAMucq2U8hWz1RcI0b8RJ8bq7d0mA5AhifwLEbLr3ue/Rc0mbN+LQrFwdF9bnwshq3kH4lEvgR0CiosjfbIN2AGiycG8pXJJoFfjydkceZY81SX2U482MXUJJS2ckAKVyrDV8kvRGZN1+qECum9TCisN62crr1T5Vfqf0AHpvcr/LdXkA9G52pFlqieuLYpj9EzKNeVIqp3RT6YuQLU61GgarWPrcMqZQhVfpUhLk8ye+pX4AE0YcfLEcXdzpj5PxMGs3weEQ+mVDXHVPrnkR+8YZak1r+OoyzqkyBXO2fQnL9wbx0EvuycAJdrUSwg6Z2TuhhzIAlxujBgT39V8yCpfRdz2mwJIJx0Ql6IpFHJhMikocKZhlG/oKr4ErUR6WCd9DfO8yYLId7g6Ns4JowYmprOjleicV3xgiIczAlN7X6cpYB0FgPgD3HnccKmJbioK8d+eCw0tR6UDZkfRjNjbLi6eXUEQsOYQxjxl0gGO4QR2NgE+IoBtQLJ9INA3pFh2TwBmkYOlMIfODGfumUi0O9VJxeRveBE0aOR3teHh5sJ6/A6GcbsEnAQo14mSdFI/IKWNeaMWA4M6YcCF4+hAksKL4m4D4Zg1E+Xtg56V9rZajZy5LNDFgUaLyiK04uCpZ4/jDuBD/RnEPQaACqEK9J56GaRod7K86rnEjZnDouJDUELMzwKEJtaDiMAkAmUfwfEycII+LSMQNzlEgslQzC9S20EKWVtjMd1NRihB579TWpm7AIMQqFupwoZO7EwDdT4XbRF1hZ84bcSs/fmfSs2ltwDgUrjEaaLAiTBdFIL6FwASMRfVRyyYmUWTKothqg5lZr2fv+ZOqtkr+5Sn615ljqZlzN7SdHXf5GFWL6934Mtqrlj3Rct6rlVrXcqpZb1XKrWm5Vy2dWLTdBr6nWZBAUyjBG7fsT5Lb6zObqMwWzy+pHtYGWg/SudlyjV+H7W11nq+t8H0d5q+tsdZ2trrPVdba6zlbX+dZutHVksg3Qmwz8QRCZapDNkYvUNV6XzIdqDa/GLWW/bFDwJxVgRMUfDDNrvLtlYjZivLXjusC9KO+jpDytpqYPH2+TuPf67k3Ly2JN2Mw4OlnyyRNBR1uQaktxXCg2K8yVGgE0lbnUvTRBEDTOIflLJ9s0gRssTzI12qTucLtNz7pNFeYT/YYhguoTQ3T/QJuxzSHd5pB+U5DuCvFmvSTVIjNoH6n3B2IEa+/VGlulgyuowkTCt0WtDwFApEFRFTc8R5Sb0QdGaAjvdTmIEQfJYfaUdQAqhwa2K8wGULJcNPYTQoRJsBfobJnCguUgkrJYslJJJLbPeIl4FGKXCj4cBHqyecjcBwbQe6KwO0V0mpDMsE43WyJcnigvrwyaV6Ge+1Bw2CP/fMOXMJmfaTVqnBJo+lEcvhL7gLWpoZGXRimwtUmaejdGKdqSeB23F2FKtPC46ep3iB2jqQRowHXmDocMDdHSqHwvV49bhBbsC7c2UveRLsEiJzvOWOTWmXbB0ZJPvpIYhz3yMcxEAPegdw7MxM0tjJyIMFpyobxmMs4USrHUGpo19sgPABQoTRbPzgYgpOya8R8TTRQwYkTFASCJaaeEaD+aOOHkOzgmk0kG1ukxwaKc+w88XY0K2D9kk9Au4AveFvOeNwvPuMKB/JfxrZWvQ5XZYw3XfB45O78qhdvqu0ebbhmerSjDbMGgG4FBl5i5DGAYXKAh+dU3B2MousVLTwgX5TjAbFd+ARe4dCtaNA5ZqOJFRj7QtfNAI5ayI/bAEFzSI57vdZW3FXGQfXHCiGNkRj7C/QH6n1ooIC8X2HGA3tcSV2Yr0kG5GwshAwXPhZ2uvn3mS3xpZSzvzID4JdzVj+2EcHLmgM4AE5pAjit3Px++4q3OqpKaGXjhwMBRVjbWkEVd4ZHrTgM/XmgkrUTQoN7SgiODL3LkU5D1pctQjNjyA37XINC6fIisrAf4gugFRYUC54fbhfgiNORkljYADL4b+V0gIFiTDtdMeJPVkJMJw93p7IzBcg8MRuHShtCPc/pF8J/d/JGuXVW+ag0ClqTFX4fHknAvhVbg2loXTmZ40O0fAQcbDI/7wMFMeVdDe35udRwbfQILMCCv1c6iKyA3V/JpKC1JF0eScFdpP8jtAnJb/TmpYXhFm4J+uXP+3LXtRXXU2p0zgcapnAHOFsUfg/yFrjrMxM52VJpW1rbGn2s6uPrKu4uHvfXI62Gvm/AbTrIPe6OUU66+3hmeKyCt1xzqQWGoB08y1HWOGj9mX7XeXtyt7BKLdclOpo5eOM3VU4fBUfexDpIlpSY1zXgS+HNiYxiVFa12+BMbgwni+eaxyspU7XdOCPUIQEBQmCWKkRljekKy2cX2iRNBJQwkkpBQKT2hfJSIHsyD0CqtqNQaa+TUtAI/FFTdhNNl+zJgb6mbZA2y4G082cGum7TOdpJaj3Czae7CrTEpoRJ28PrwiI4tm03yfxdNSoqwb2RhKlvDCpcYovGnxA4HwVMfHpSfBLRPpV32yAlUKFBYEZjsFINgTjhBUHBZZQPlbYwW1ZZIS+RFx4sO9jI+q1w9HxkSt6uaG1ZaOsHX8gY6F+34iiuiK6qWWOT8kptswHkQxrKeQlYsS7UExUAKnynlEnAx7jhrvcMtuZN3wp0IqYUA3YDB6iUN/ifH8n90QtbhPgZ4bDvh/4LxI9F4ChfAKqu81spmZJfiEcsRpAwlRoJTl7JSzUoO3eBo2Ov3hr1BZn78Rn9aTSsn+egmetDiRIf9/uDYHh8eH+enevDkUy0peIZQHyzo2mzieExWOxM3pmJMkD698VIUCuLDJOxfMQWrMnkBdoluyLzQgUh6Eevr+eSj53BLBUzXdf5ES+LLHnkvCg48UNexycebt91DPEcUDGthRIb7++LX8TJiomgR/GjNKNToQwssTJ9MA7qYoa1V9pW+gk48UZDyP8H2i6YFsNwH1HHh348zJ2LhglqMl42C65LXbREig0U9LOiCxY3sJFwA/5YhyyGLfgozjNUPtNYGzZ1zGfh2zAFT1Qu/TbsSEEAJNOpHjIUPuQsUjTA6kuAXhyxEwlybL6xcrQ63B0J1T0+sU4+ceITNF9GScBGEiNAUSxbihLVFbzUTWRa6Ve2RE8xe4K+jswUJRhHwMnze8hfM5mYNWFAQBSKX2//VIn7MdaYO94ckMTN8D+XwxEUhpc7khlRa5PKFcntmxYsSyasdERrNDbxIDHUvlQ5QEaghBdWulNbdWHVA0lOoxCR0WjQn7HytkwIT3d4Mz2drK/vmCmBD848xAXxT407LNpinN5Uc1C5s8WhvT9fmn65nt0TrIPm/iS16w0zQ0MrIZlBRuDKIYhsFaVCRfv2zWtzxlgpH5HZ8GwS/DYLfBsF/X0HwZRpSo1D4ZERZ+jbmF9s4+bbi5Mu3sxV+X1aaszJ9XIB2KFLXi4vrlzIYqpLgZfJ4VSnMWnsQhsoUB/0WQ3k1pXrGS63dSkTHCFEpIyElYXQ6nU3P8y6Bu6WsIWWrRXaXGsH1du5ChyswWm13yTbsq11nNmS/3xd4EaXDKUGM0RaDp+Q6gYSADZERwOAteCEyL16mmQ5qEWgeeC8i6jGMKhdk104UXYIhtUWr2aLVbNFqtmg1W7SaLVrNejkncKW0kmqS3E1ZWW8uRJZA/lecbHkIOvLWSbkyX/iCKFNAutFcgl4U+G4+tKC0woQTVpeWWMFLkx9kN2V/zRw0xYbQQ9jF8H6e5NFCa2gBrV1pdRK1apJRBY7q89lWCY6yIhoVPjxthY3a5cltTe0aeeFIG0RzKvMfCzFBQlgX0miSBJeTNjTSc1kY0H59sEobO5mvcpJsYnX5k+RvmOBz76PYmnqHsmJNqImJE7eDdJj7jyBV8TAQNdrpmue1abd4PX9Ja3tZ2MOWdqejWVHtjiU4a+VGEGTu8BpyeEh3j10aQCjE6dnFK1DtMO4id3g0U04y9NNJqyzH9uTT5MUSD4wGYkkrWEizJi9I6TrevYx7csJ8dlTB7FZsDhfi/KyXmdTu6yE7eH20v9cf7rP+mB5QSg/s/cOD8RHrj/ePaqMtTUKmVAElNch35afc8WZ7YcisEXWnfuBEs7lOMxePyD1bEogyqt6wwa5GwTDM7MOhPGmpd+hhRZNg/tMNL+9espabXNi9anOalHTPt/MXKOZe2O2Vy7iXncG0H+HYFX89nRH/ez2rGoLT8MlVAGxw9Z0pCzWC6xn+DtaTWTWD3jt8c7R71N8bvjkcng6H+3vD0593X7/+ef+wf/b27HR/eLJ7MDh98/bs9PXwzeu3R4P+6zfDnw9+Pjva7R+c7O2vx9758KsunBtAIvEnhL9JkjerZ3X9y8lw/6CVsekFtVPfBkEABgdMrtnohmsOzAvv2XLErRr1J+xEXdwKvWS3blBfOztvXToNq9sZ7h8YNPSLbYJbX5jtaMaowK2/DPzIt3y3ejQmk7qMx65j/cqW1UfU/935x/8E1zcf/vbu+vS/duf+zDp8c/m30z/fHv365ef/PXy1tH//r+Fw8Wv8x+Xup5PT3Vfv7Vf3r7/8Mflz73X/1L9a/vFfB9NPBw9zt//6/HTXPvzyr9nJ3/9eSwwSaLB0NWpJ4NSlYc22DQwW6kIYE8vXSDHh9ern1dm5sl0hD1SNrW/SUiAPank7e4cGDd1EdSSFNsLGWwaWe8ebju4zdFayYffsvshzfmVLwjwrWOIPKIBjODh6ExDUAp9JYzMiVdwzvfsy3TF7ykb37H4kjRIGSwSNi2lkR/iGj4DZav8AR8MCh7ppiDlfirLBJYGOkPGQGezH3T/csWP/ef7LH67l3U+t4af/teaf+uf/iFz23yZHqbOziMfasXMuINQaL4JIFxqGvuWgHzbNeKoeu8Lk9w/ILhnskk3hGyGz6gkvcxObyIbJ+9BXIoyY8HX+cvLZqGnXhc/SpiQrMG8Fv0iXi0PJoLOtwT1V+DJtELwl6Lpr1lr6WdpUHLKRFzJrt1lT6WfQlKnYbPOaPfLaN/iCv/u1swNML6JTw8/k2/JD8x1MXv+aDb0w1AuUL/TcwnUsybQN2lM+AE0DgQ0NPxUvF48tThGeagTRd86EWUvLZQRfIBGFWIeIWrM0Qe/s4vr6zWk9y0J8I6aCbckfcFboJGJfOIAZ9xehtgL/evDvxb8QA6/C7FZ2VorW2glBriZQmvhrci5OKOE4AclP2hg7PMcN+DN+tHDZrSfhnULuXg4AiFM00xXudO72jNKUVvAn9m49BPnDdDiumOENdnZx/eub/0lCDV6wLxbDW9eHHNc48uc0gjQ8d3nrTZnHArxAxkvFkf+Sg4KCczTdJbR+3nq3HgBr/vN9cdKmmJp8dV+py9YVv/HICZtF1HHXApLS8qjyLaQ8oCcLpyXDHThgYnFHbr00Uw1+poCoKGAjqEckJRK5wZ0kfJPvl+NNb71sl9AMBnfK3RPEM3GXuPQ5SNUJwz4xCCH050yF9+yJjVI6oGEasGS6WejzCFkUL8S/kyCQV5Ya+NFN4g1e4duv/oMvf4MdNVEstzacNYMvFWFrVZOO5povOVacBXL3Ovio/Am5uH5zuksif8pXAeVWwTMVRtm79U79+RgTW/EV4Qsh+TPNz2mMefoJz1U7vPV4j0nkFSY3CRrG3GjHKz+yvVvvfFLsFBNcESxSIksiNyIvhJLyskNyvfJIKJXhQhSgaI5GMgheMnZxdsXC4Apggw1ZLF+OLm7Tk/DWP8P7+uPHL6RVzClwkN75HGu3gbQVRn5Ap2zkyk8V20COUiUmbKKsSh3wj+tfq4WRP0NVJy0IZtdcD/vVWDDTqOGg7RsLqAVRTCOnwZifNu3lR+CgK2Yp5I7FKuj8QqMpBn9Dav3ZdTEut8bERcAWRM4v4NvBwdE+6vtD8m1t6omylpujS6dSfgWmV5irJupw//VaI9kodOtS5lVEzuFvEACZZp4NV1rAcopUatRyQoiWDuoicG0aURGNJ7Ur5acHZHPVSpOiTxd9EbizMK6ITiv3dG+41paqunlVZEB99Mqb07Prk8vh/kEbvpot9HO+aSPo57wBRJ+qLqWkpwF8/mO9nc8aaEpNusj4zBj8N7PXVs4ztSTlmRX8DpI/36YOAZaCVpE4RPiaEC0X3DoEQjEP3LZQW/AYXJkQla7kXxkZhBiiE0OklROiHSb9sav8hFexlrEVkPvhqM2p40HUtMesaHTph9EZjWj9yeEfag8feMD1p9KZak9aYRigEbzBaZiJcdUeMmyJyINb1t91stvVHYb593S+cCEX6fryGLOZ/fPyGoL9TTp0/amvXc6IzReuFjRUeTgCALpaUS87RPnt9QJV6uIcMi/UOzh4xOdN1o9duCzyZIHNQL6Z8lBKvhk7b+4+wQFjJkSXxtFsdLIA1ZfZ13gnXClx/nmwc258IVR8QEJ+uIi4TepSx0RGoiYyJCmb0kEVXqYu0mglzBFk54P9m0H/eDeL368r/FJX5QXquNylI7pLakbAIisjLcpAEuoKxhhGdL5oeTZFlLmE5xTDPPkeEfFK1WUDuzoNHLvn8QhMR4cff8VC3wUaOL9UYPjQqHJ9+bYiALVwSlMJAOEGBweHvQECDg76PfjfAWpK8oKvJ55EeFiXegbHe/vtUI8ypCz5qGMtulFSwcZqlZAKEysQkj5FizMIbjN5ES0X3KPAvRM0FKT1sjoIinn2PwIebh66sUZz+Hj1rjsJHObZ7pIo2poJxXYFxWpVEjH6jx/Pzyobmwxe77GjPu1O6IR19w72drvj8djq7tE+s/cm1uHeYL/AQ5OkjLM5DawrtvCDKLziBj7d4eGWv7FvczHw8uTm9BfyyoaPuwH/uj4TlzubdCEPmHGLMWAo9ZCz9ydXoF5jw9m0AQOrSTHq9N5ZjB6dP2mg6f363llwzRQ7Rc8AES8bGCBzneXWWVne8otKPsGJ/uPNzauVllfeciPOOUvQsBHtWn8fhuSFP3ciDNXAWn0AufiygjVWSSD19/XX9Dra3rBPdcOWnjlpoMyeNPDAyU/qztn2knvmS06olw1O3h++x8688Ep8CG3EFHxEE+eLRtXH37maj1Rx9fFEkZVe7A67gIZLZuyLwOytvjuPhru71mF/Yh0eTfZ22S59PX69d3TQ358c7A8ODw536jizUgAhlEy6GXs2Dh/Js2yhPJbdzUhAorpcQjzr2mBXpuT8QJCKSysC/oFZwmaCSu2otffddYmdhVNVktCNp4dvD8dIBkcJ3EChiBzglSHRfIZfOiEvy2RF7jItq2kj0kOSIudS6x4S5PgnN7/fyNR1fwLZ68R/9DqJWybgWkFIRnjX9v4NTXyFL+IAAAWglqtnEwZYEYht/DijEcPUQghwcH3/Pl4AWkEceCEADHPMFBrlGsS30TbJcfUFVLVkvjy1Hl3CAZtAPdgZo240W/4nxzkGCbbre10pEOD7AhqeUe//Z+9dlNtGkjXhV6nl/hG255AUSV0syzMTo5bkbvZIso4k92VaWgoEiyTaIMABQMmcCW3sQ+wT7pP8kZlVhQJQuJGULz06EWfaIoC6ZmXl9UvyJcs6qWJGkQ+Q2YkeLIiud42WO2GbmjlhiNYnTfIAG6kIBGqlJZLU+wuoaGUcLVpTgUL8wPkXQvJCE/gpKXi3KTqSXKsvYN1SMttihjgQIMxILT8uH1yu2FNwqkkSw4WSz/WjcP8XXMvuWzb/i+d7/C0LFtZfYMSRfxAsrL8l1kZ3eHs8e+cpxNDUCVFzYCVSP98dDnf2XndeW/ud3t7+/n63N9odde0349dvXr8e7TRytSKtDwFfkN+LoGIdVYLckKhLGxxkWCZDr9hLZw2OoVjUlyE4+QGvZQi6hIw1iynYnloAO+PjaY2sYILQ3RIBHIVQjerpbbCry1Gx4SIChHfEs1mQPgHPqVM8Ym+ZEHS3EBCcWsPvF8iU4HXAiAfkoxnGYisVRKzcS1FyGIdgCdEd6xfiHDhVmHsVswQxKwyL4sEMoakQsw7LP0dTy8NCorBQdLBFKB0tAFsSUro8iLKDNrvw5wsXgzUIoxwBUxyPeAZtnwhUCJvix3A+jn/CWnf07kdnNshCiNUyiOiHhBDd6x0TU8qgGbBEByuJ0WUKUQO2CV3Q6HkTB19kbecfiOtfrjN3Xt/DcpTKvp2yQnoMTdqQWgBWUw6eBFGd8uriHdzZcxHiUM62TEniZA3HNGL2d89/8IiAwoMbr8Xu6IoaQI4q1BP5f//n/yKjBDoTtxc9wpeBMjw/orLX9LLn4ygF2eMDfFWA5wMx0YviDVUqPYwAxwbDgu7u/xLOx927xIfE9+nbi6tTuhFJJtBG5Pr+fDDiEdYGoJcpoJFvBXzkgCzAKHRXvpToZMahCoATzuhTwAqy/YnnoHcnYDPLBQmdj5h6ET8HVgC66gBjFQcQnQo2ftm/iMeRb0EkVkRbSMGNUK+UvmAvhSjhe1BrO5pCrwQrNlyMJjx6hf3NrE8D2o2Q+rh8d8Re9zr7rNtpiW3CllXDJfV/tQbRKUQBVQbiVHAGRKRxdRvxCXspQXZetWGowOAzW0ixIgfIr8QzYVwTekLmS21fTB+rxyzinyL2krcn7Sa7aYjn8Ljb275pvFINp+hEb1SMBFkvlqQdCbAlfy4/p2oUdExhUcMDJGEBz1Sy1mJQjQJ79jENIQ6CoK58G0tEFCsOqbtXc5In+/hhMbO8FiiNeOPxhI+sqINSWssEYaY852reKRlOmtyFDUxmWqadNBlBHXfKioVwyaj8cUZMB7kbFICrBZSAlQ0swgUaeuFyEHWpaIdRQfAXUQhQh3idC1cWVOsgnKUmCwUyBamGSiHRBUyAn1AaSyy0R2DewRAvbTAomVijFiBplKMV5kqm10KK0oX/eAxQ9CnEauWqXk2LthpryvuxlEy/tnNF21VubYNwm4+ZhtZ4qX8RwltJMIFJCH3MqstJ4ruajxV8ZIFrEO42ZQ5gLxXjeSXhhOPrGbaX4l5hGne4A3dCSRV3EtEJ1jFChByytMT8q2W57k0D/vW/Z58OtAkhK1NV5xFx2nrQL95w6UXWJ9rwuH0gYDf0NfDlkAPWcsQhcULM4I6iBuVQQVCdB/4ksGaYZAFHAMDlbsrlDyFLlFaZg4Mibh86SvEKB7LUzkvASZWsh+6Ws1+a7LDJTn7pX11fNVn//Oj0w/FJk12eHPcvT46um+zi+vKAdeHd/sVOk/Uv9prs8PT0gHX00ZuyX4EkEcDbMG4C9obFhh3GBRJ9w20te48vJVgrrBYl7gf9iy31emxkoqWtaH26mo+vA84blePlk99e0je5cq46E5R3//LDxcXJ5dHh1UmxKa9/saNZCQ5PTxvNxmGj2Tj7pdEUD/sXEH9Gmwd/0no0mo2L68tGsyHXBS8JPDtFg5PYnNE0c5raNx5c2f2LnS3cfwwcDNnvUAMMyD3277KXng9Cw3zn4KYBWwn/3oN/U0tAdSc0xfCA3TR6nW1w33a32106pPEPna3ejvxNFV7b2hO/FRxrklqQORyArNxOPC2RLLQBZe5goanQSmpo4YkzepvhiZeKplIGlYt3mtQlwNPV0hdYjOYWhgt7fBEFmNEGwnsDAvbG0UD82xNuOz6bDyi8B7HrZ+KP7CjxBJh0NCEQJPUmPLYV2Fd8eAy2bysIBROIX9Pug/DVCo6vxB30mNKoy8VFgiMW86wnJcax8BlQaCEbm9TReEmbTETeg+kDYiQ0ZH1xDVJen7z3RKP4LjHa+JlFtQBQ/2mKtBWEk2b/XDj2xxsP0KcBBwzNeS6EA4cLHhdygwArNBFhuhuA2ok6yKIiQxQsbEgxg+OM9XhR9I27Z3dSURlLgHJh/l4KkdyJlCwOjWiGJmcMGrCYnXKP4jR/vHp/rjtKEzfoqr7ShC0hE24a5AjRl0lhITZf5hMMqeQMmKPGZuSqHaRYFQMW11C1GaRqWVpHQ5cE5jwQyrZlB35I4qrcpcLbu5dmfiooKLb3JsbV1M96ir2kfGIGJ/m9LurHNUAoORaLGFEuatJYlMN0hs7MGQR5nX3XP+trYn24PgElDefoY89Y9ww3r2axpRkf/71/xkKsf+sDmDaeLPk35fMKc6vjjThErXIvcpdv6URY6tUXocExYVHz8cR1jwz6UkgJpIdCOQO5QBNpsXN5pAUUJXqHILyAKjNCXe5Vi3FXWVLduFq2prFLiGFAuFASjWuTUoi/ycXRjMwVliZZVqBshTxkdt/sAhUfxdTJeBKWUEK5aQJ8kjHITSg7RroHM1zFNiRtJHPhKRE6KaKlPsgygtVdxwS3LU1M5DqSVAo4fhPsgppAYo1NTxugJpNNzWALqRo6YD4OXt5xyHEsJeIOCg9+8tw+AV2lXDNPCH2q9bJKMmnO518zBGrxun61MKgVNqoyFGpOW390ONS8nV8NErXkfCb7+3ryX017/5wqWTlVkpYvhIvbiZaDQ7QznHiiZky55QYQcs0hmdcyADO+zi0yDKnvKqdZZk4oDEPlOOcZwS4uT37qn/zcaDb++8Ph5eH5df/8ZHB5cnpyeAUW0KsP3531r67678/BZPr+pxM8VKYKE/ECpNMcyw+UaWk1kHoKhQzqLyJwHcdzIqdWUeUsq8tNsyviihkGlw63TxJqvFvFJHdRuPbJnRn77sh0TAwDV2VCB0MjEGrBByMnnPuhk0dp2TWiOqQV13OIgXq+JwJC63wh/Qgl3zzmrfepP3mKU77yCc+EVcfdxpHcpfHsd/pg48BbduKhtuA6Y37Azv17LB7Nuk0GpcVNY8xK7tmE5mr5CMYBNdIszIwMLVZTmeiKYkSRgYFDR7K3y5Oj08Orq/67X9O8zsgNJbPM8sDc2JT4NSUH0ojLHerx6U3NnOLq6DG2CqB7TK2VodqW4YBnosKhspmvlQs2DlVPlC7PSS9qoowfJo5Us4Q9Qijmhe86tmFqGH+JtcjgLTbH16qEM8xm0uFSEFQXLBD425XxKiFmJgnPAw+jvyXLmmnCWrfT2zHwr2QSTvpE1bhLY5bwKIt6hSXsyYq0kly0UEx82WaHopQdBHs7M95kJ7iqV6I/5kw8dGfG35IBQwR7wzq5DpeWrPEC/R4MshTZHazCHdgcbJdbdEqwXyuPdsqzU15LoAlIM8oBmjDJynTNrLHuGjH20cLhhAMIVJhjPwMgD9OpPvkEvpgwpiPhvHKIouCkY8bv3Jo12dXcB9bnjdh3C/cj025gsg69ZWeW69iOv6B6qFeLcC7+TLwbRoCcZs3niQCfepBlTjjgOHawnThzxxi18t0SvK2cPCcU7IYDGMeRXqEqrKPaWWdMBYOJb0QIcfLH7MeFuxQ33W6b4Z1kmFXeXal9vVdpxCaTVwYeo+LdWTjOhlyKCf9kFEkrrmUezVZcyAiYJGR3YjPrLyMt0IZXMW+QYg1DOHErr0Dm/H+ttFQwULEQyXWqftKBDUEBLS1xInH40+xuVTBTwCgaVM/uNOdSlgvDGxN+zbmcq9/0qRTQTQkQc0goCXIAL8RDcdXLYEC6/ummZuRoRcTdO/E66md3ByqlLFmSFojj5Oywf0oxiOwO8Ix0aeruVVN9KgKlFcTk8fuzw/65/DL1ESb6zF34oH9xv8MwJOt+Ly6GG7Cj/vElG7q+/ZEi5C5kU912r73d3rlryn9CeBX81dvr7B3svO506H8Out1u9w77yjza2tm/e/VWc/yB/Bmqmgl+wMgk1cKiuk0M9wYwuiaeH/nrwhMB70DJcLhwLsPAt0Y2JPqq7Ncmi3GUoyl3cLY7rZk1nyOmyP0eA7H73nIx4k85nTA8Uw7OUnuMbiwO8VXwq1h43xv6VqChWYvg5CZJhdA1pBoV2zqriMtJ27np/OvEVc2ToQj+gj4FzRJI/p4HzniZL7B5Yx9SKNBf1kS/rgw+AEsr2HfpxAunMIQmpURmdORNfQ8idFBkdrjwEwIPTTezEkNMaVUOFkrUEQmS/LJYueqbouA1rUrLzS0U2hcLHEdNIJAi27ZptIAZUWTmXk2mb5jMRYi4PxPCZqUw+RwYxbP+2QnFt0r1WTVdQYXGdJkYdDZ988lMHxEjqRID6/RR6wY5jnWNU6gbjpqoLBJT7DmKx0Rg/+Ij4yHIrMLYcbk5jB9wipNLCzFxjmtkTZl2Z6Ndw5Yd72KhtRV3zDzOmKIEBpDlYuoW4O8hILaY4atKfYRTq2uw0/xw2F1n5OHUAuROU7tQ/Wadlp1/mTCRnH8ZjgUYFKBSkG71MvioOhkPIvRhYHffwa3PR1c5XP+QxAKBQAOh3XRpbMqghN3LtjGKnMSib9yWJISH1YxJYoX/I61JCXJU9iSl0ZsZqJSw75IFl/knSPvAjE6Jr48oBK4T8cByRWbWqjaXZ8XrWfF6VrxWV7y+Id3IIAKn+VTWLmS8Nr8CjSEx8g3qDElBwrRkC/cjOZrPiDMdY+J6uQpBLrUBpEvWH9XC/Si6o74vqJXHpmw2z2ue40QFEcpyeRBVddAnhZLVHN84KRnLVLVjLfKoxoIl9kYPv8vpNkmycOj8MBo7n4yvkx8ZIkbqLYghGiMKlgNrHJlkVjQ/RGDMgUBYLT7GgeBggVmxengM9a1Sa1MyeE0cs/zTEeOaUXuD3EiyMteytoGJ7UkegWbqnKl5JGecIGiTPpEzjwK3uSWt4qgAYHm0Ibj5xK797g+LghwuTs6P++ffY7jC+6OTqyv64+j92cXpyfUJYDO9O+yf4j+ODs+PTk7p31d/719cnBwXz0HDWa3Co8xSi5gHEOLv/lCGbqCIAgBlSzV9lGYkxFLIrcCeMtwNHkFlpuqRHrcULDMzugPfC5gQAM4AMBZ4NpS95iy2wfASRoCMZJz0pSwgqMf/OCF7AcN8UVPoPLMcd+h/OtY6JKUMcx7T0Vgp84fvjReeLeaLMfMpkfuY2ysE/mRVoTIR/DqGyXMAdUcbV831MBmZiFZWvyGv8Ht5NabYhyUhj5K95JybH/1h4qKFPXFgTxBIi2CXxNFZUhUtWm+4Vr3l+zFGmGeCjXRae6adJO18aoULL+QRae57rW4vrbmvSV2VJKRMyLq4VPTNy0QjPzbTe13WV8zhTN1lO8in0s8lfaYPxFqSp8bUywXPVJDmatLOJsTX3/1hVelR+scHtuXZ3DUCIp+pABpwHT1AWrh6+4AFUHpV/c3uHUtpwEMC/6Fsfdu1nJnUafGjB6xp63itsetMpgpTkIFGM4qDreEODziZ0i0JEehSyZk2u5a1KCkxC/P2QxZakROOl4ySn9UkgTNCSj0fsb+o0ICBKCzD/iv+Kc4l0X8lSTbx3kcHtW3tJ7UUBoOxvuDUmFmiTQ+t5C0xirKdk7NfMjnsl2AEEUpvk82nTjhlcYBz2NRMrLALtuUh9iMep1cl84uXMEdq3+gdmg7hXzcSvz7TWUN/kEn6Bjo1rV2KE4vTXqpdJNZb0zby+zYQonmDs2RtoE4js6mi3vzoD40Wn6TO8jWYehKUUKiBraRwHfevjt7/dHJZX/3KWVmTpWYDAqTtQpxgMkQyY5h4ljL/IFJmM7vfFQTPSjSynnRaaWA5JyNxu1SVWV3fAIifcUx9f3LNthzvHpYQUuK3/q39MXBGj1txcyvkz8ReNVnfuCiWs4orq86AE+Gcut02HdXDg4j1j6W/XcWViOAD8N4OlxUtIwBmGSxzaxgeixcEoH7NHurZTqQxl3qMRYI4UHXgo6ReUNBBAP9Q9JYW4YpYzmijogAbcxVwteklhcTOEE9xlhAQQdUhy5kja0Ah5q7wqdAvzTh+Xv2CnjfxAdoTwaFVafe4Z6x6hKQuZgsSGwssb2IMoin3rfdandet3u51d4dqwvxDoEfZ0SBc0HkuWx3SVMTbMDkuQxRxqcg9ik261Yh2DCpM8U11rCdSPCHNmu4GacHOs7IKOhcCTPnwqmQDH4sM4GMj1HnSKWIcTat/DMUhgFKVv7oeK5nxKHBsUwfwu8BnVY1qRuOK7SO8tUEunFs2bwEfmzkI20aNgqbbZkdWyFuOF3IP9ugez0B6tw3JeLnJKUbKjk+0I0g66bP35eGvFl6VE9tkPlTEWzbS7yyaD6bc9QeOIU8Ve+dhuv+rs+sL9sPJ6XsGecM80FEyM2e82jBAETWoK3zieB7YGTbK2vYyrG01pgZxo5ZDpSNCDlWNH6gMAoJEL5kfjMyKVUGGdBF6hx9fZrZrhWFcNUr7Xo8j8gNngoYfOYEKMo8pkuCIAmRz0zkVJpaIOU4Eps8EEVkTWCtC55Ir6AdUBRAz54iQK0TtPU0IXVltMy0BE6G+JWdZJSPmOffzs0XrJWiXovWeKCzMHDacQtL3tGjnTN5zbvApmhmBD0oekww26u3uVYk1Ameqgb8UOlvni2AOPK/ukBGmewYoAHLouiiYGv9O582egSvmxtldZqMntSOSYjjFg10EEwiB/hNllrT/JLJkUuvb2dmvssBUXscMCByp9HsRPazFCjqhGPTIMOh1Ap4SxE8gBakaO1cfvvsRgbRxfgJyxzi9snvBZG88St4LX97cmBjxBiPLkjdk2VKJnciJHw2iFKXoSP6SZCoRt9zcWJuIf/nu/fGvJhsnVhXlhfAN9Arc2Gn8hkRekyEJ3ZSumpONHx9/Lbw6nQGWip+shLdmziDKWYeS1AO5EgUZCPqSGGe0xgxS8Yw5cyiR3tQckkJceuyiuls8BcnsYtGp3uBTRyZn8MfKFlNiToTNBEu2NG3N/JHpslOWLXwOZ0skSiar+wT+YjLdEBOWXZ4B7tkjXiySz3YyXDc2LgrMdLAtyhNO3Luozj1xDDkNXxaTMrEJE7ccBVD4SLOilNtY4BNd5xAb4HiTJqM48d9uGmeHp/2j/vsPV1TD4Ori8OymcXu3qQU2mWMSi1xpXXPBfaYQ9ob+E4nwA6qYbXlNjIg/vOi34C9UVGnpQ+GOUJ1GPAgsuOBaqmDp0HGdaNk4wCCIBTBEWRyrnqPiCrqGXXxH4wehGdyeJK0brT8x1KG8aY4Or75j2mcCGleW2Ax1+ybpEfrLmJdMXCDEKAa5HE0GsZwteSil8YsCGqjgmg9W5qVnV5EIKikM80HAoQU7h4CpcDjYLNCKEOLekkoHd5AA5IcikUtRyksUZkMYlN/RYVa9omGe/qcEsO6bXrvT7mHyRKOpVQTZ2u6hVKYRclVKBhhjyJIYTH0Trn5cWweei0oINmfwieR9YGPgDiCyk30wpOASgNr1qEaC1BDSRgb2stvqdUyhDjgZyv3rdXSwygo7u85xQuvexEwNl/RApHhT4LeGgCHzcaXVXnG070/ff3d4CkwM81p+u2kAc9sYS6NhbeK2EHf4IHLDgeMNoeRibjQsuz69YpiKhu+BROAJV0qFLN+n2LV47P4iqjZ4+eIXH30UWF6INY9zrxSm3mFTP4xUztbZL1t9D30minWCUwmO29kvEkf8SNVNk2+FscYgcrRmn9qJjK8qjhAjYoGl8PN0tEvhJTVW08iRyLIc2iR2xCc2V0Xpz+Y8CH3yqMN5CSOTpyBWVhz9A8jAxC9iaH6DtIsdk7hO+S0ktNcTdM0DzZvWFUUNkdx7Ga9TgeAeimA8IfZpi5ueltoc/gkdpjVnkju2vMlck6p3nCOxqhkIlVDzXJSqTYQnppTK0Jk5rgVd15xTcoh5E/kQuH00qF7k2aToPcjt/XB5KqyvKYQWCScnUyg+XJ4KkKWAPwROJEopVs9Zr2HHC7gVQjFcAXiZHF+xFUGskF6qVtTKlbCxpYnvhbmPlex7ssaSWrfIFwuav4KGuUyjaB4ebG2JX25ugC1utf+0SvJmHa4op2riZosg9AMqpSbr05eRQEnJRJQ4sLwCVKECld5KuMuMYAxQdu2ToVkaH5Ukh/q5qbbynVpzY2XZOLbngB1S2XNZZ6VTPWInnkE2QieeU82YMis1HNRSQPhTXWCIzpwHA/Pc0jswR1NQlaWfB/wesCALl1++VH0LKE41h16+9Z1Ixa+pbWk2pAlfn77x5IWRP+PBVS6YuDSb8tC2XIvK5sEm8Af8J1QAF3+YAjCydiBIdUiZVouPOmnvq0OdZrGmDOsgBpaxdW54aBncjDqDyxgxNzy4jJuwzuCqGilrj4oarjucXMl4w6Mz9lN3sEXy7obHm9dV3SFnpNoNjzPRft3BmSTVDY8v3UWdIcaW8AJ2K4r7NhvfHR01mo0f33+4PD/EKsEXfcw2u758P7g6Ojw3dpK2Bhu173sejBw7SkdNQFTNxBOl88TVVJjULA3bEIkn/9367uQIweuvLtTDq4v379/hfw/PYGIfTv8OBY7Pjy5/vaAUhJNfrk/END+c//38/c+AeX/+/vzEOEmomFV+b4lauRPfh+vK8RAhptHMKyBk5D7r+F6ewHtSyeglDdfpWiubKIhCq3KY6OHJgL2oMtpKOVY6iSS8RvnaURLNprKD6IlcOJV2GtsJBwqyY8ObjewhvFCtJ9xEX9DBs7ogAWxg6H8aUOVkcykaxd0cqK3rj2ERv/d9qM6VyzuyPqd63hyz66aak6WeR6WaC+U/HDot40LKqHubNpc/UVSev723O4i4Z3mV4ZA0Z9FGXTnr+GsqeC+ewNHytL1Ccc+Vrrar+TidOrwSP4wbSfhqyj24hgAvk1hQLjlJB7tptVdMi9bLTq2ChfCY3eUE1Eo8ZL0zk4wq75ws9xRpT188HJAGssE4QOlGyOuqXGSPU5cPj677iK6hkpOv+2cn7z9c1xTgf4KQOZEpUM3AjJefPeVgrjHGqP8sgSbgTaxvD3V48Qus8CdgKeB2dCC03xgx/IT4Apnj/SkSZYQH5ijtdwvXVfMQ/lVCeSY/6sAet1QfLXtquS6HFJQS52qyawy9N6ij/keu4YXOF0MXQCVEZH48IFPNrxSAMk3YcBbTcmwpCazNRqT1tUBAz7GFm78b6CbyogZK+FfOqMq7LeF27xwFO5LOjqHCtlrC7pjeRaO+ycyQd1uYMO0LgeeT6EGbwai3wtC3sXwngWFHZLbHGX2GPEt0EFSalDzp5Y4qP0hd10WyIfhRK70a2n6igLWH3qHE8fEX8IHhW8UqSnoxXDQV4yIOywMinsQRnW69KirpxiwqMuqwYmRkHKWoRk+ls5eeLWIFmxQbp95s0TOjkyx79NR4PH9kTtYtGhR89EQjo+CXbKZ5It30pa+i3V+pJCEKOoaQARx5VJIw9Ls/9dojn/+t3P7EP1EMwqDCssU6epudiO80mdO8lp8HuiTlUV47yS3XE5MJXcoHqMe3asLTCyp4Bqj/ugDqzTIu3KautUymINY8qj/6U48d+8aQH2OIT+Dfg+3FNhUPobDqJPMSTJ9isDcrTVzEY6l8b5q0137BtfnUOm3kRPh63E01Rdc4uQ3qvTkxjoaBxDA4prX9gGj/OpdOyMiIl+3we0EgLAbVyUlMjhd45/z3+fZF5+r67F89u9P771av09vBpOTd665ISm51e9s7u3uv9w1xgKeO97FcbZrikplgmURsVZk8l1RWsDmDsmGA86qYtoJ1qbXyrkXOzT44CsD/uvA+nohIWBligDTSbFxyBL6DGeBP+FhE8KafXUCurVE7TWEAreweJqiUQaJqONaCG3w4Bwy4d300o9BPYFX5cAlYKhfvL6/Vz4fff3958v3htfbg+ofLk8PrQf/8+uQ02fhV/+zD6eF1//158vesn7rcWGMGQiqFZhKMvIKvWrhnCVbQv8f//nNhBZYXOZ4IbaL0FgKF4AG9C9ZgW7zNF+pzCVtYtJ8E0P9NYYGtVZMOOz71JyeeCPH+ovhh5RpWCuutjstNhxGb5RzYzcGCSe+/AblsA/uWi0GWbygZkCGg5orx0XgARdgq7Q737rnrz/kArrp6X0R+jXFVxdp6csMOmpCMLC/JAoDf3cnX74RWhfJABeYQo8NVZg7sOG250zLDsow3s95fxIr3bIb7nGa4LHjnRqwGHwqpvQ6xJy6JygwFXhxU3sBpNHNBzh1Qgugi4NWZHd1YhpiCOkpIQrcg2wfCzwxifCyzn9UJB7okZHynZmkjSHyOI+KAAVg5CckXiRTp+E1ZhYWPmASYrMBsquAGYnCiJq4Sbq3BeWWcVVw5qY7yTR/2U/WXTNEGBWuarrlhwFcUnhswN8evV/CtQAyj6yAwSW5e0oWezqV9kdmcUrRBQ3c55YevReVh9YWetCU3OybeQcBdboWEZp7FVJGhmpkfdIwWChXUU+rUb5hyZy/R/ONZE7BcGXqRmzrwRkFW9TEsB8KniOXQgh3MlkpVickKmfZhwbprp1jvqdo+a1/U3+eHqRPxSvt8yieWvZTsHYwe6Q3HItR/nF0nW8fcXSaE1aJ73PK8sngEnTbEB+zlh+sjY+JzxQAEUJGqdwrpdpvoEd6oti4KwpPQOAWSZ7XvpHcbwvwqfxiDZZZHI03BnjsAMWjiB05xVHj59bOuXhP5aWlmlUYqqCh3MbWuYIMo8Dyt6LgwDadBAq4zUgbEuDhBjZv9p7gJgKwXzMkYoWREkv80EAgikL1bjQazySa4KyaDRqqaYFZ/b+rWp4wkaJYhE8JDof2LOqtpCDOSYaw2bsrqERe0R9vEl9b5NzAjGYNjOrUCxmazFqMfsFFcPoBv31Tr6Gt4VLDQA6dS1J4V5gS3gSdAd/pZi8j3/BlkEofLMOIVHG1AgOFAqM7mDlTuc1kXBSEHE15NFqh4U80rmSge695TdVL5sN0japYcYkmWuyKjTXFArc2Y0k2zSpKUpNpmXEBRZzPa+cxncuIIlFKn2YqQb2NJT1EgstDb+cO5oIzs8vGEdsC5F059g2R3yIZWyPd2GPdsHwqrXZx/z5wZyHg6MmeFgMy4k/whX1oVhhvQS+lxfrh+19pXw+QzqM/j1h0ltJ0/vGvABisfYDZXIS+4GPF/N3S8YGynjsfNxopMJbi8RAbkAQZTxLc1hbRYJHZEm5lplx0Ic1WiypXJUpazDHwG4AqYN5+lze+SJ0iCiwrKPDk7RUo1hkwrtAVN5jJGeMWD1eriKDy6RQjYfeoVEQsnGgf7kKX+4iN6O+BghK6KlplXPqtOJosaniYeZa2N1Yp3iAWgSfBRkU/YGKuzEduekr1FKHV2+JeqcgbXQwl5WGECK6EtaqB5GdAQXTkw7mczWZs8Mz3TkfLv+SUP574XYuRD+UlK10HNMzRA8IYyEDP11boGh7j7RNh/iYqrD3odJdc4xlUd5zmjMlTPS89OPZTRMhIrq+AYZQXTiM/y8HbS6EAYg7EZoJ01408rMJuSwLbMQigqzbdox4SsHB2Vmi6o1JPDWqrWoDEG3LxXw6Q3KhZ0wUKf+UZsvKniluF1PkosgDJap2VK0bSB8cjAe/Otsll1PvfmSl8OZLy+LnRuSAu3hMZr33gtdnJ22D89iMs5sDEkaSU2VqZnweX9t0QuFjRw/P7ssH+utyAQEvXMrsxX/Qv9i7kLH/Qv7ncA57V/cb+X7rvb7rW32zuEA9vb6+wd7LzudOh/DrrdbvfuFTw66h9fki8h+SFkqZu/3drZv3tFYMuAqUzBWSGbB849oCb6AVtgtGTL9W3LbTLX9+eQst3EUnLy14UXzrmNUcYEu4xzGQa+NbIheU/dvk1RRU8kajg4253WzMKyxzhzoMJ7ywWywB0SOCUHGj95y5b+QlY9pmANR2AHY2gvFnMK2GI+on8j2LwDvQ8XEXOgXNCSQZdWAF5P/skJ8T2IrgVH3o1XGOWJNKO5SOTfRAqNZqN/oeGr3FaKnb0A89/3CysYXfJUinDuda6E4oxwu0Kx8mw6WyrTbnX5Mze0o4KxsnIUgW8jDuF6BdqT0mm546GOp6CqUV+bSCL8f0WJZkVbvnkUmXKuPt4QjinhEl3pjo9OPmOwsrUxk2z68FxbOU4VCmw3DabKzsSn6gtujHEQj80GMruNHnmjAwRXsKmYjzrI2mYnWYVBgjBtVzm7k+bNNcx7qo0CE1+sZxot0NnUrqKg6NzEAJMMk8hiyYuvPuxeYYy4CEa/On///uLXFlRWGLx/965/dDLY3tuNH5h++/79++9PTwYU4P7+0lig5zJV/K+OxWbF6sKq3qAxO8h4hT6lCSceztdtxUmRuFr8nD6L9noJIPc8rCB7fJNGuc+zo1mWob2QiOQIp/7CHbGpdV+YUYHofArMT8cCFDB/CvUvhgLM1F2vTguT3HkQYlGiiAXPL2NRNCWqawEpLB9AbIbpodyMIzeMCcOOpLGrnDrjHJT14tMp9WStNp4k4jQppZYILc5ovSTWimKJ3k29XNWEYXfhbWTzKgGFXvK5a9k8r26AYIZUOxaIO8D3Je+YxTWwSH2+oz/uYgOYg4wPjSXu8sazhhi3JWts6GYCeHk2WyCFMAuLrpIi63sJZfS5Ltlz8bDn4mHPxcOei4c9Fw97Lh72FZTfei4e9tUUD0tqwU9VFix9l23sLs41+LiuxEEQUAkVcRmr1/g6LCjuJapKeWM/sHmIFPzyWpHEqbXkgQK2f8XEHmBkH86W4hcok1C4iGw1a9YfY4N4bdHmNZGCKJoTBTdx+QEInL+I8HVsDF+TPqesylkBTqzAv0Ozpc4oSYZGIXpW3La8JtXTIYzlaC3HUoi3IrmotGtiC2H6xabKKvhYVNfNZJURe5uunAUj0ImjuniSlEVC2YPONPJcbGsjXhXV8njGlXoSXCkDmk/BLmQpMJ+RfaWgSXmz2yBuUn5FRcNwFOp1gRMiWfHD44soQJ3Qn3NvhRIgdZwLtiintRqmd6oYV8LibNVtrDgQJtl2UcBdbKjG5L7YKg1qDzyXdWMibhmzKKrF38WjGRqQOpOAi0LnRrP4w9TXx5QYcKUwpfWM+lrX3Jplrfp4HacM/sl1rBZKJnTENRw0pfSg+tARWlLbcPyOwZOMS6NOfKDqp8hQDHKqeG5yoUhVGQUJzDmFWUWVl3MR2b4pTegizpwX78iua1KV+Pop9ysgC3DN86u+qhUwm+iu/gGNO11hKeOOP8tiVoq10Ne+MNpiY+JRTo8FQZsaLSdx0mquv5brnGGI8IChnq23HZVE3pu6SHLeKjbAyBhO2fdGEBTA0d6G1keLWPOMRFdQmDzGPeFVlVib5esipYtrboHm8SHkhgz/bKCqPrHUmTXp73lRq8V+2xgc0tFYIdzQZe7bhMO2vFhbXi22eNxUxLdCGIYwFhvSeqD5IPCNZZlyXJjFgTW49KpDw/BTKYoVXLjabtQdpBaBVhFWyCAIxylTlTK1PD9LRPC1TFkVhRbIjO36E4PxGc3ik8mGwzZzy7pUjXpTY/oqMAYMozEqjdfFReEPVTX4hCN3QwYk0TmbW0Hk8eDLW4vWtoRcp6uFImYBQraY7i0Oln6sMxLwe3B605vuUiAZg39fmgGFVS1wJhN0yjKLXS3CuWNjFWowNVuu+EPjyMVo4AXOt7AUo1zkCdREKc9QUD2QcifUQXHyVhQLdAui8gPh/LPmCIAdLyjK7HAvMdEkWEpdF91hPoTOB9LzEH/UZhe0VSETMEQF2zP3wY1edTOeodk/NzR7LubUdRzmofCefGKF0nOoO2PqGIozrG3meOqHiuXN0lwmO37BWEdfS22vxIg3aLJLXl+GpfqA4d6pMu8pmHN8BYRxdIdRFgwG184c70K71rq1KE3vM29cmSrv5pFRqhIfMcKL0EHn1hpisvu8QWaqvecMUgawbmj9kt3mDW79sshfXejXf1h813NE13NE1zca0fUHDeF6DtmSIVtfPC7r24rD+k+Nu6oktJO8UrEgYCyTltUFXEvGyqkUlDP26pFSSibMD5hae+z53vqc4ZeYutSYo4TytPY4UypKzuA+BG5/4vkBv8jTSek9MLV8uDxlAX8InIgzBz+SGsFbJjTlkPmeu5RVxe4dSDCjDNQnqyVJGJ4KqCU5sGINWaqrcDdhYcCAkwDCAEXXsY0VzqoIHLkK/qXBWkWCFya9fbg8zYRm0Yrn1FWN5zKNonl4sLUlfrm5Abax1f7TSqp/s2GNRg4tuk6BwlSUpksDcZWS1SGSU3K3RDAjTj5UOCC0KrgW5GSV8YwvQo0kkwv0xyexFSAkska1J4jJS+/8Z43F21iqf6E8UdsAmbUkbmy/vn1Ok/FTapQdz8/gszRQWvbyyvKYrzTO8KcEImwlNlbJ8zr66FQAaKl1xOOhxnF6o5kV2J+hn3BuKK244V4MQnTmpYLoy7kVhomwyzFVTSSXfpOiMyuEXVpzpxWIpGpNCywnD+yorvIp1V8NCm6dJiphn4FZyIbofQpgwy/GC7eK71AsNvxxi0wEgi4qYmTnQPNd+xHc/8ouQm2G6tqPY7jE1a2NU9WTUsPsInM2lTA5AuAesFdjuQgnmqK3B8Hv+Qi9e1rv5X3wYGDu5zwzkzna8AnAuEr7vQ6CKEWWmwdnSGsm27fuLQdJWuWDWN6ShdwK7Cn4Ra0Zj3hQ1menk4WxleTUlMStEanhakgdndns+dgYjs3G17gFnG4RVAjJidc6NnvCwYSsldedzrYWF9M491ngLyKuDuKHy37j8TYtXGxg0+Kx3K7cXpAb/lVUFONJt15obaJ//KvW5qtJlVEBhFq6xt2vsZims5vtVxOvClwZxYJsp7fNu53d8Q63+XjfGr2xre2utb/9ujfq2Nu720mBdrtXSY7T6SnPJpy+jhKFUzVDubKNA0+EnDJ7AXIfOXEWgaEgZElAGXktyo/n3Ed91RRYmMHsgtHHvd5mVXACqBRJxxlnh4GmEvjDlTSleE97nS4V9O5ed3YPelDQu40Fvf9RIoajUW+ABoZDCuJ+n65wlOfipdfLQsLRrttkL9IwpS+Mpt14Run39bDJrOPVtZZMGaMV/H9mED/6U48d+/zFqzaTpo+3LOQYFAasCRwcLocYJScC+FB6AstEpT1knLvHnChk/kOJGUT2Zyzjo17T1jI7bTnruK10UrH49rZwV69ocFl7lJdaKitGfqUJ1d8m0yjmzkkqtLf0ilyJjQjJqpAh1DzKKRT15N351QxyQ3dw9jrd6PWpk4SpFnA5qKwJ1K2VA+oWF3RpJ4/lT9+dXDqdT6e///ff220j5FshfBrYvF7Ejb+gdGzItvBGELuCdUiSnedpzVpF5FvEn3W5mcu9E08UhytpX01W4MfNR+NGbvLEWf/sBEssZldO8U5rPncF7OLWfDR+0WQvoODtFvKKMm6e+riR4n9qfw1bk9gJfb301dJnGTul050miTdZ6UC1JT6PwURz6Pe7heNWqv6Tql6W3VZttUMMB3HIlYpVdwpz0kcOtDUDHZp4KyBWCz6v19oulkDNhxJiZ1xMNKj8NbmA9dpqai2W57RPo2T6Vb2qe8Vd1W5D//o2IZ19NoqEboe2bWBsrgMRAFYwxGIXcwhRF/j+L0NNemmzQ0b6h7jH6fA1mYXy0CgWWZA4myIPCikJDjt3QMlKsMffYEQt1V3idr9dY8uSksgq+5UQUKEBdRC+mkHdPqZOK/5i2uGjL7O3z1u72a2VSPBZwAcepCpxsBNHJCbq8rXYNdpDtCDGsrg3wp1OSi8UlZxSEr6qVdLqTaZtwAB0IJZFBtdZIfvIly2q4zS3nMAYNKFJC7+0qJ2WrL8nYLNz/fcm4XoazdzsAH+4PjslaM1EGTl2QVEdzIpAPQRTtUh95Z8i2EBojb30fK8FfsVliTT052n3rz9w1/X/vDXt/vXP879eIJQsg5KDlAhDl4cQDPio/eet+V8bsmj0IDJk9QFs6LIV+ZumNujR4eHXTG65icpkiQi1dOXifTnzvWjqLpmodQHnnX8ytHuBC4p7/+S0gnRy4914pTTSUKUfcgoDJS4X5oyZbcN4hrYNAb0ycOlJbp3nK2djV07KcqQrF59RbpUXn/k2Iua6Kp/TTnT6SMoTWedY0KnIpcGyqC/LdQUxxGSRLjaSNRkl37Ht8neGxpdu4bWcjmElSpvFrTC1e5vUhnE745XPUXozatfnNt04P333/vKh8/fvJ/7h4eHh+dWH6cmHyeFhjhlHtGpM/RAZTwAzswgJNSHgYx5wzxalmzQriOMxlA3uHYvZzugAvHHSNPJnZzZhYWD/5aYBj1x/4t80/lrC1+GtaoYmUsNfYNjSbCgwK5JDiy3ecB8V2ZuETv9EtiaYVHsusvhXtjSh3WNr7k3q2ZjUZ/nWpWLq0YmF9ifNM8XqJfilmnOc8xEPpMjipHW3gvkJNIwVaw8UuGsoB+9h6tjTRFEI8LuqNgAUno8cK+Lussg6lTmN5QJBxYKMMTJUqAoelojc1nfbn/7+ZnbR++flbni9v/ip8/BLd/mPHft4b/z96+mPbz6edvSxoLg958HMgkt7ABkZtimDMbN8mFwjv3OXjL6skSeV8RP+c8EXVXYOTittnUrCgH2jz/EpAI8Fa4wkXMwxrJKPBmoDK6wJpEJCIb0hty2qi8eXDNJAfAlVNVfRmhAI1GaXPFoEHh9R5lXcbWy7oEZBo3FCkXA3UvxK5kEoXM63lL/24FDvMqiJjREHNovjVG9hkuxGO2sFgq9O5qtQp5E4IYBDUgv8O2e/frtNMaZEmd94/KoxU2d5rWf5FbIq66FyGZ8aJpXCM28QTdGXN+MDze+WTXTCWptwUbXi4vLQqUS2YldUIodqRvLY73P57ojtbvd6yrQRLuwp2DfeBf6sya79JhPYWZT2KSSQFpQCpVRSDEiGR/GCikQSec0Hev0PuCMC32VXZ9cXjHv33PXnHMOGHG/yFt9/J1u89tWwRFN4F0sOL5t6AP5FHYkRvJBZWrZLB4/87SWLD/0esOwW3AQ33rV/wIwHAx6KFTpgJOIHN56+TAcsFgjgGfw/vthkP/uBO/ofiTrcBt50qgINcypxb/pGSzKHIq0pSZlfbgWTC7iy4mTQLrR2U9NVXAPq3ywo1ieGQCiNC8fZGJSMI/moFUC2WTQNeDj14ThJkZ+D7RCeBapfrdhxqfquDfdaNo6KhwSEJXZpUH/w9889rHBuzQaUum1UOK7m1qylnn/20S3COfcQNQ+rDQ2m/sJkRgZOOcG07TkPHB8EizHkOsTfEzclk/JsAewSUg0fpr7LtVDnEXAx1o8Y2jdkFt/DFHyy2D7A+QaUlIEIezx6SxKJ6SmEVRBQvGVj3DD+6EcM/6C0zAdEtgFz2SLyZ1bk2PqgTWnjKvDL8aK9nUQY9N6+FiyHaScLN3LmLgdjQW+nNJ8tYaFI0WtTO1UZssndKdMpjne4gqd8EDjhRyOuKZZ6w4xRNKJaQ/+eJxQVSEiFPF244EixbEFjbGh5aNMcBwS5wIY8euDcYx28FrumsOw42s5fDN1EqF2n3dnVkvm72hZ0HtUfgxH3fM0vn51LOLNcFy5y7joTB4LHCZKMKEcl49O82uw7Dlg58FNTny8Q5UcHhWsL/cVYe9oajxHoLCbFF2G2gnslGuskwAoem40HKwA4i83skWjsCfaol7tHdU6FNtmmTp3mfY6pX6y60GHL+aEW1ptpI1iYY4vTsJoK46O8O2hyIL+ADkl9qvGx/EKlTlb8LjlRKjVfMfmAGlCfaOGgFT/F11Plnyt+qj5JBBNX/Fh8QLWla3wXUbnof/meQXz4BziVIO8HDoGjZekK4Z9BE+WZwWb7HzYuXYH5In5Ses1AfIrZGpqOrJKo0voh6uki0XE2W+IghYO5a1VIioFFN0Er86AFj9jIGY8Vk6KawSEwDVx2cqUmua8tsp/INHKpbVKhwlFOKtnZDZBiHlOKh5gRuIimCPaD/46sYMKBiYIu7wdRSiORwxqN8KyDZ2HmRzzBcH5Ta/ngBx+RNYu61781ZsuW+BH9DYrPCFaLto9xl/dG2/bOcNfae/N6f3/vzevOfvdNz9oe7ti7o72Gzid++zdV9m4cgN9FDVCgXcZdN+BoJDX/2/joNh4A78glJqSWIPOJal4UMd/kClBeEi5Ax+oOe/b2aIfvjvc6r7v7vTfb1s5w194bveb74zerLYDvjmrOP/2FanzEXV5p+mM/eLCCkT7/oYMIny2A4latezzKX443433+erRn7w53rO03vf3u687eeJfvjLbt3rBrdVZbDjGO/CWx5k5iNUwfqPYBUMd1lLetFkWgIbKUKLbtndEu3xvTWegkCAIIJr0K8qS6Lk7Lf/B4MKBOBsJRkei4jBj+VDbxW7qZyH5ZgV/jy2IkyU0o4tQDGyY5sFx3gBA85Zxbiksrcc64N2xGW5Bs9F5kT1uQkkZvIKqwa+E9DGAOEkPj7k9/kwV4w6k1L7lRk6uejrYXY2nSHLPSZv5EnkB8xB4s121tSo5cQRhUY4ilwnRyjCqop14pXje8GytQmTrzK9EZfV6ByDzfc2xMNZbWShV9EzA7RYMl1nDDDZ/rpr1wLQ/cL7Qe6LAtCfBHEUHLaxB/y6uzqW6RZsxEbgultMQqPStABgXIwOUz2fBWXMrmZ8HoW/DdCKy9HzG/FrT1By8UVn9YcxRMRSWjOLsdVAxh/C9RDND9IxAG/WAtramEQiq6lJL80AhES/J7fKYMkjqbWZ41AUfmUgj9c9dHXBlay41L8unb7zG96fU0ysynj3SXFKyHBwrm17EYxC3TsR3pjf0tFgFWEdDzhap86SgjcOGuNKzXfG88fP16t7Nt73RH+9br8Xa3u23vvenuj7sdu6EW/7cNjLWaGGy8BCjG7PMMwKCXfcbezVrAY9odntnMQplBZu0P8nEAVkbcWB1o48vD0qx60DNCXCWEjlyO8RVLDmtd/2tKutKsWHJvSltRJqh84XIhHYao+Hgq/MYJGTS++cuQZPPHR03zrG9c1/TQDZg9c8UTxRSeCMHqW2YMz3hV3z5eVVd1ObeMDAJ8gfEm4as4KRV9BIcy4GJQ4Fov7g/hsQwYB2vylsZqmFsDFS5kouPyIYx4GDmEAy2bGmjUH3fzGcDwnlnJMyv54tB3X4KbrHbwnxhj71s8jesv5BoQaoXIad+iIfzz2hMNNvSVIys+b2jEY84mPyvkaynkaR/YSoebwKzLxJzyjYHGqg2bXk2Pln7NjEsE9VQfyDdqI1j5JG/YyPylQq7q2EgEacikFZU6VItOzIYFrb4lplUKERDOOFpK2CF7cNyRDTkkkHZKxfMoGtkivwxG4/KIM5ePo5kfRsyFim7s5d2fkgVzRPYITjpMRCOrLmQ5CcqRgvsjcjkmd2LU9IgHWPyKcrBaF1Y0VcV+miLpBfOuolAkt0E93bHzqRmHWkcMx9jrdMFIBFGdiPQBocLs8Oqo34d8EygA5PjeWzUyDDDHMQ8hp1t2WubXHLaLvOa4JeltNhXxhKlTFaARA4BNGdclOZhyvU6tkA0h8Eu0VbkEgwGvs3fd6RFe5z9MMXT52mIREuyxYdDF+P+adct6s9vd7tnd3dfbvZ1ub9Tr2d2d13tja3973HttlYXeFcCNrn0daHtX4R4TL8vea10j1aWwkr3RamBUlBLk23WEItMgBOuFkpPVe1dva9KVqfFnEWstn4cyHq0mXeVtdyVGAMG37KVeegYgfiybPLkmfheT86t1WUe2CE1xHG/BjJ+N7M+WsT+4ZeybNrJrPG41JufBAYfCkdl5a0m8PoiNHucjkZmImhNk2CVDVlIeybpgNcfnV7KKpXgnhZIGlRq67dmntq2KXGKYswGTJgfFPO4BdYSXfsD+ps4bJh1Yc/6pBAMllVAc89be7m5OJS1NNTOWJR2JAp9NdnX5EwrHAH0jVr7NPniYFDqUFYLFHGCIIeA40AYh0BxoNQETHUK6JUBAzBFzJ0hI0QbK1PO59nZ3t3f1nC7zzKLIAPB3jYK9zwDiAJQZFkJV31HYlEFy8T602ZlQZ2Sixx6lo+3v7XQ6iHvWxbV5oZI5XxRPQoc7U79u72GOnZwcNZ4oEJxsEMJlBMfv3mYe3uashTHKU6O58gjP8ystvPOw0WwAgk6j2Tg6Pzw7aTQbP1xfX8Ar179cN5qNq8ufGs3G6fujRrNx9kujSZ8fnVzCw+Pzq7+f/Ar/gB/PDy+uL+ETwCOAFq+ufnh3Af/96eg7aPD0Cn6F8ie3VbSNxwQLCXkEDOBZWHgWFv7YwsIXc6NtRl7QrvsVBQal5WfnDHe2ZaegPiTHhxIWNYtcJK7WNzn3jzaqwUhVQS6zM6+TOGy7lgN5+giJaMzQ/nkq8hXxVTC8uZSPzYaub3/ko9bYCcKIiTYAJHToR1OGRt1w6syVyBVwtGfCyjrewl+E7pI53j0UDGyzwyHicvmLKAQkVAwxhw8Rk4owG1Yymr15A0az7e51t3fQIaMZThsyIwYKvC877fdz658LziTIAeNe4Lsugs7FkH8QG+s6kEkfsSM0HpE9dO5aEYyMrJsza67aCSn22Qm1VkBAQNGTKlCz/nGTefweVngZ10y3XL8MjFZ20trpteLxtrqpeqO9fQAR9MIBhWPPjOIrngE5+fli6DrhlMuAf4G0BcIAAGEFi0zJeaOgSYV9NZlA/XQrRiRIJTucd4DT6cxmi4iE9TB0Jh5imOr2ZRB5pfiuisi3WZ9Ql8A8LnBqwfuLBn8m73jKwJW17d0lE8Bi4VsGp43MG2IyIQunCK2gGdmTjG8Fbqaf+gRry6syEPkfudcOu20oXNoeLv1R255a0WQetYmvqTpA9rjbFi1/5Mu2NYHu23J3BXuaL4K5H2LyJhRCjdnpYAyAFL81hJsDJKqQgzgEP0Pb8bSlYHevioAOQlEFtDEXn0v7ImHDDiaBv5gDd5PsYmB5S5RYMzPtVZlp7wln2vtMMw3mJZNskROldH50UgdzK5oWT7PGrJIDLtBixWhzxqh0yG4nMWI6vYbRyifxaFFJKBwqhvx/EnWYdvSiTDuA5y5Yq0FsVFl0/BMKAYJPxRyxmqPJPPeEjr2tHAcpWCVidPFtTbIHIBfikIRzMGbz9Wo0Q0LJttW1Wp0dPmrtbO9vt97YQ94ajXf57l531Nsf72M5cmfM7aWNIRJQ2t0kHyzFrSA4qhNiPTSZzoog4eC0Q4FbtFa8bJj3lwShVT/dJgYVqhrDaUOEGIx69W1iICOfE9CSM5uDx9SOnHvO4JgRzJ5k6yNGHfueuPVCBkor2+nsFE9B60wveJz4NTGnVNnzlPEKMOFhrjKAvs0+CLenL+QU/Lk15pCQtghCPwBYHVL+LA/nYwW0JU4oUK5yJYqKQlVHF6oMdnh5Ygv00jQ52zBW0tlcrHHC5b4kjGf/bqTPOtyYQK8171nbmltDx5VBA4JvrDxgrPr3uUarXy4mzVdwKhDSYlmcRgIy04jDYAR+Nio5cfMM9tLxBFxmwURWmERi2LWglZCFaeqOxsEz8qyBSSTPWGr94s2P6fbWqJHpu5Brb5CREn6g5FGhsNP6qpqTGi2V25rzWPCZZU8dD4Raa4S3Bv8E6S84szb7qcvow/CAzREfcUBYbCNkb54fofDLFl5sU4jn+FbdeSiUCn2tmf51BNYGRLXixEEToo/4CnQeEKfiazSjJL5lcJ/5i2iw8Cz7o+c/uHw0AZejjLLxfNDbrNGyKYGL9J9EEJE2l6bSxgaS5O1lzgtTbrnRtPhhGFnJRvVVSf2aWBVUopILkvwx0S2uYSzbgB48WnC1gsIsFh9UIDUsRQtiCoeyHJ7N3zJ5x7AZtyBfm1sBQgo6aL+ZB/6EKr8cuYQciwpr5LscQdkWHuyAx8aLaBEIcEQBVQTaLmlAMdewQp2Iqumq2ZVCTpxzr8vzpXWK12KbXeOAYsKGQeYMv8YodX6tXeOJX0l4wPt8EliEYaDGgUwEZPUgAmDE5YB/mkOYlfGaPwENlCxMsarrWmHUwnm0Jr4/wgIxKM1wMpjE+JOy/7Wv9O4u2UnqMGexY3k8syJIRtr0ZQAJF0YSkoaQBp1QSUUXyVXhHvsIVT4cgUc8kNDecClqNgRCFp85kQjN0qulaOa1xpthx9oZvX49Gg/397t219oevh7tdbn1Zmdnm3ffZO+hhNkjVjhyNAPqpIpobhKCU+JlQqLMFdpiGU01Iwg6KRAZnqYFEPWKFhJUVzyAdmHLDEdfwxVJ7CaUPAwcYZsa5VPHWxb5s2EYgZFImiQtTdIHHIt7q6QoQGKsmiEr+bPqCM9D/JcR0neEfdu+ZzuuYwldAz1sVCM2O8ICMld9pch4o6RXjbKEsKJhgdUVFeOFq8WKkH4KGZHm0FNOvjqevTwrX/L7x4qFn1PufnA0CTFiBcuhkkDEadyQr8XEzR835AyMnWcyOxxdS2gjp70xQtDGbqwUoO7UCgczPzBFVQcLLiBqPBl7APcyH5GvDiOpUZLUMWwADt/jn6IBKdblLlOI2Ijfz/ctTLn9ce47CryXYzfCbRiAsO622VUEONWOOOwUDy1wcqSJxbBMJta1/LHX/91fnh792LFn7xZ2793vo+/d+6H7Zv6Po/7e+XE/7M/O/V9/3vX+8ZP4bbvTKHR8XipHrQhH0JyFKtdfuEJLdjEJG5zy56kRNAUVJZdY2/TbwurkK5Uj1w5kkuLzmMzXzV02zQ/WYAQZckgc5EqHiIxdmQP0lmGpRDrtyEwckhDGjidc2JWOy6fTox9/t2c/TUff//Txl+2fFtYv0/HwZ/d3e/bmX/3f/c7Zsf3w/vrD8uz48EH+/+nRj3h8+r9//PT++1//9ev1u+np9WHnHz//d3R+fLZztuzs/tr70T39+XJ2/vOH7vnv7z6e/T6dvT/68U36vOUvUd1D8iQno8pxQM9oBaqo6pSNXaew7SDPGdy0EEkGuSGOqFmKRX7Akao8qli9LQqWwnXLQmsM5anYsQORw7bm6A3Rzkdtxw0tPCnoqjbfMivlsRWeXGXHR5lTil4b8+bmuzJOkg4MffLUaJsdGnNsRF0CVJJyUnvKkndedt901cmUcMax90rkAL1qs59lNk9T1hQVoMnQS0jGENkp1l7CYqngj8WtmrAj5XxqSYwxUPEoBhKjU4DizKpxTXdNHUlUbUvOyUgGrK4YaHoot0hAOjL04om/QgpkUbE6KogBPY1vVfaU8umTa+CeB0MrcmbJkNUKHufkYlUOZSUqRWsgk+Qpgg5knJHclRchbG3J0ani8M644fwhWNVyXDAYBSqMM1ATLYwgS47PQfShD3VQdRAklXlhUy6WwtDbs19EXCzZ/RLmIYrGVQG4des5FMXRPmrO24xsCKVTpNcyaXEp8f+RW14q10kvtvTZa0b6pKs468wVtkJH1tojOzCVksvbqYxMJEdj8BMYyFyr8qTc7I96OEEmsPbv/TMmHzeFpBKopE1/zOh+yWwsfqjZstrsnD9oJ50yJO1xlxyb416bnWgPRc6brIejvcc+cj5nIf0d9kpPnLZj9BcFTITwz7DXuK0aU6yd/eI+ZbSC7FX+ffYLdmaIDMjIE9rBlRW5kRMpeUKEEFUxEmcNxDI8AYU2VNfoX5hKrKPaNhtJCziaEUNuD4b+RBhVTaEkGS5K5dvlTUuU4TqWEF9CMCgDR1Vel+J5JQNV4tklf7+tdSNKZqFqlgr3nbzdUofZtIs5dylKqSvpWyma8FD5nmF1KAxtW0BGA8RP0ydFTKJwHdL3+chwFkTYh7eYcSh8Ay8dsF7n9R6LfWiocTfh19fq1zjbutd5vY+hDWOwLeLfb4BRDJ3RiHvw936HxZ4wlvA69Tr7XfbPhR9ZjH+yMUUGf+wl/HlUscd1Zk4knm/HMiHwJ7hF8fcdNUC0yOJvu7GfCmppLgKOiRG9zv4eI++IApEWBpc63qmatxssol4SiyKic2s9/rCYWZ7Rz/qWjXxcduC2Fkj56FyzZlSya+RAM6LsT/Gx64sVUzK7sGkrYTKtqSElxYM21PdORRCO4omr0oHlvd6mDA5pwlVHRb5EljNUl2S5S3WK2NTyRi4P3gq4YHcp9HUI0STN8/mcPZ+zb/ec3ZoMbeoqgsJ/icj/3ByeQ/fBWoYMSTtWLugMyfKtxRZpcSrE7Y1/1buzla2nRlJFnjuivExCXtDY1dQCilWh9TKuZoLu/0PN9U8qLGYnhOo1WDqOyQS6FzngEysYuSK1A+BJaNytcM5tOIcivCAnCir2hT5N3Fl6zjKsqGTO8rWvd861IguqBmZ93bb2+n7wDdtqc1Yt4Z0uXrYqAdPa/YSRKgrsv5J7fY2A6X4qUlr0yBO5NU8TJF0Yu3stcYHEAsT+/KcMva0arD1yQms+58hmlLgGmc4gUHAv8oPlARMefNjJ45PTk+sTLNUpMKJkgPRblsglGwlX5XYHa+bCnrhgIo4j/o7Pr95KQaRJAYjKnm5b3shBaKWHqR/G8RrS4CwTkkbMmgBPW2Chd4t5CdOHHBJ0XNZDbLUXnmHNVoqVjFeVjvLi2xOB4Vqlm8Qi4me4QuoRTKam0p2OlU3GwQpayWEPny3KuIRjF4XNwbMldIBbjMuk7/BbZonkQnAZxaOEyCB6d52TuJ+00K5sRLYTSxkbpjZoPV4tfljGXMrwyYAXBv+aw4XBhlgSh7tqEGq8oRjZqU74wkMZh2gRNls+ecrAVDWYVlKRwyt4DTOijKjLWgrFEmtGwkLiU4sFOABkYVYrFqsX1bKK6lDfBmJJBS5DXTw+CefAptY9/7wofMlxk7cPrQqDoT+qUJmwOhRnsielvmb0TNPbGthoxkgSKX6FvlS1lkAqCbicmkASTdJD60ABJgddBGaYxPFRY66KZ/h6d6/bGVnDN3zvzU63Y+337PFrvtPpWJ033Ob2OniGyUnoOH8rkrJs4jPTcg4iEWmY/pgtIV/7X6UZ63p51+rLBvXrWw/OvywT0NM715qACwmj6wCNQAI2qLL3lLftjZ3JQuR1U1ubIeG8MedcHFcykzyUhw2XTkjXTVUXGj1jUMExMXBU94qXGMMZE95U+nvhyaa4cFDl/71FSA/4lfhn5XlT+TAAxxUgGvnpdfE7cG5fzt1F2Ip/eAV3+NT3fNBVMKwL/WiIK+vZ/gyzXBCsA1QCQKTIKZm9+c01IinmcKFiMMVS1lWMp1iBda2Kp5iY8ROCsJrv+rqY2OYbrgZIa+5tUxueNYfl10LaNl3vzQYwtEHMB+s2o7PRhGhbuyEVam4+7bXby7ZSB9o2ezbT9jJUiIUyLGkjR9p8Bq5dD7hWLuOKuLVFYl6/ojxXodR4igXmCyJVrMBm/2NBHC85w0a+vQCVSySDBq7BopxwmWWexaD3xQSKOQe0ommLdV2fF0gEzj8XXMBqyLVKuMFSKNVrwKgD5UI+5OeTerXCDAbfHMEesbkVgQux3Ipljn+6RtFuzATbA6OmnWf5iecx9oMH4NyaETHw5zR/8UCWPjUTtKhwmgeUKuwsMnxXDElag9yl9EuDrG0JWCX6qMhxn+zrJ/RaYZqbmrFuJlUUIAjgb0l9IYWoll4r06RjOJhM9Dx+fmvaecPIcZWs5P4XRizUqgHSSI5UB67pJgeYKiWUR6NxFLYqVq1Lx+tSrhV3onWwKMuu/iOQcN+bL4Rt9Gsm5EzJqWKKrkwuq9J5mm7rE7yox2KyZuODNDVukNxF1212zMcWoF46IXthue6LEuemq2PfwV9Gsq6zm3qpH/MZkG98xi2VO/OYHHSumVGvES/M9VWE0hEtfpHyni/HpSuhFQ+qquWwQv32lS2Hep2mHKKH8Yq7CFia4KLSoBSlIBpzSF+URc+Y1eBnIiI4BfIIFC4HVlaX9B75eVy82mEr7Cmu264fr6b6vd79EYsl1abJw6gu1muFQ55/ttObHeq7Hfl5G77qwc45z2YTcOLclCPkQagSDDmBl+vxSDGlROzHXukBMVUhSw7wAhF3wAzHXtLv8N4r6eb4GT+lPBH/AZYWE9FhNEzB24P18ca7I33rDtj/3UNggfgQ3LVvvA3ziIfAiXgNJpGfJHQhnqgIGfMNoGCbFYvtlGPnJwbwLZTJ+7xFMzdQYe9LlcRbs9Tmc4HNtY1o6MFY0YKmb6Vhaj6jhFkB7Yx87s6aO3cMsbdDNrLC6dC3glGTTbiH0fKHF31yTF3zILDA3vL2xos5oMQaE+0Be5RJucMlswSLfREy+UX799D3bCVOhzde5ItBoJ9HIDNBbgDywlIWO3d05iX+VpIB/iX7zhMNUvRcfM8V+3QCsyhZ7MmpcE2s6skhalqpcHKavSfbfC6Y8Vww4w9dMONbrq4l75CVLhEJvokGs3rOX8xyMq8URCG7EKE9shyBngt8kvKiYqsdbm+bnS/gMMpqFPSSQyjOSx4xE6JjTr5NeogLz8mpgIDeCKo+oQaEPZcE+Fp6xAX9NfUXgcxLNimd12pSuMjFYEnoMno0cPiFOZ/qOl7IF6FKEE4uO36aWuaA0xLHW0VD9AN6HUF1+GzuB1YAbZmBNStuA8gbgxxy0TmzjDyHoroye47yWLJkVCE1is4Xj8zBxXH5k8Si0TI8ON7If2D0ed7SCXBxenclh1Vvr9V5DZHGGEwpHFbptcyQQmhEC8EAk5BhPLQMlEF3mzYtJznjzMgNBLnTM5DjYx7/eNYG1nOp5zHj9Zh7wOcL4X2uq8Hf8wFBS+cxetmyQKBm0TTgIeZVaPDplqimE/kJzl9JMr1UXVzQQGB6wGpBcCk+2TFj1MapXM2qkfQNpLMhUa4HAjLj95/oqD82G5PAshH3NSidnDzEhxG7dMKPImUQAJ4YtiJvN9EY1C9yCC9iSDkKooIA2eXhwNpcRlUmGoAFC7hqBtdKVnMSnZPS6BlX0bY8uMmHXMdwlkUSIT98neV8U7ycebGZ5ltTI5KMs8IgCxBsuC4PxL88WIFH71vRIHDCjxnoaH3Zy0mYULigbAKepyiwvBBD7uGCBKUabkk5DzF42imxozpNIzX/QGNlYt8jLW0gCiyIBCVwLnUGKKN8VLA0GzkDK6QTpBbTcIpSHKOZYm2FHPP5StvElWa+gta71sLFMAYUrz4U9ZnR3pF9i6KlCYbGEIahVYlVtQxaiWDupsB8hevRCcMFhEBFiFrHRgus3TIP+L3DH5oqvw6AL51PVYoUmzAwThBEAJ5Jq9RSIspGwvmG42izOwR8k3BF4PC48QIugpWAlePR7/0Xu/7lWuVqIjgfE1UCkvBWN/CBB0wHkkrINB4K77RMJI4h/WT9ZPb//s//ZbOFGzkt6uPGw2bhsprzYEagCFQ30Jk7mLOWTMLSE98fpo49vQEKCJaYCugHAbcjmKwCjoO0TMi1H91BKiO0IyDEbrw7DV/uz4oK/nqHrFBttdL7tdlAVkTzxsPIZiwMQqk19iIir1M4tUb+QxgvW7yo7EGlvr698XRUPMqZo4xn/PL8ionRy8gcbCvyaU2W7RvvbjSzAruNwfNzK3KGLk/Pk4GOQ9iMSq8K/AdQa1zfm/DgxgutyAkR2BIul+Ozw8sjRNLE/E48s6JMX7iwpwyFBNf6BPeGKyDLmjeeRbUu2AR0QA9pHQ9CnP/gBxPLc/5FQTRuS0K/+1B+ECortG+868x6iD2N85fiE5bMo5hZ3gKEjLc3HpzTd84nKZAIxVeD3YCVyxz/xOFg6mwMl/LQSthpUW58dONBkqVjA7BzYF7kB3/hjtgElMfQn3F8BhZ5i42cMSL9RTce4L5hCgSe4GhZZhtPnGRNKJl9amsYZZ/agAbnTLAwznysPYK/Us/gRELjhM2nvZvui+hNe05/a99nCBJ+zB7HuFyPYQfwCpB/ZC6ArIQnNkQxZfU6bgKeAtlaGEPJxgbXcif3n9p6dADGxxJuqXlA2ti1W4NwhiQ/kalV9arkxjh0xo51ID6YtoJ3HY1IKzMchlXGIDc8G9ggnuQsQSixlhDYhJaUgNpQRYEDfnXxDs4TsaGYca4XBVFUaBiv1gKhgyqKk+C5CkDJH144XA2lD0vPgnASxlKSbs6SSg5lrUo8m9VJoETeI6rIqV17zEOMGkkSMq1ozL42R6H5Cu3hZBIQB8XBUMphdijsTqb5SV/uSEwhKdshM5R3rBTShgsU+gC/IsIjCQLR1CILrXBFkEN0C8yFAwQyhd6Y7SIOiZGXFicvqqzEdB7jbTajYUXloTBYUAIuxVdH5YhBazi07dGo2+31trd3dtJ/rxMxaNJkUBZ5ZkSbZUR+YNboMhxK6HFUFhW34gtyJY0b4W1P4uaQK0jgp+RRGzuWT5aHqmWeghw7yIduvk7rtxDNSMuHTTEho8c49yBZhgrgnDL7xacItuxMPGKud6O//Hlohfyvd2XwywJU35TJBEkVmFMJmQd8NFDqccEhs6iWqZByiUCozjpWMIg17Lhd5nugkzqhxgaha0Fe8Sc4xchxXdBQHQwyIos/GBUAqQlucW5hLTxArpRHRvnOcUwJRScf9jDDHuGnEBDxwRDQimQEU3xyZW3PBpDGAmyBsip8KuTQvHKUwS1vBARTIf1Cwo2bjlMut8psZr3cY1O2sUED0ivaIggWFh5z+ThCg3KsnQoV/i6h0ZTQZrgYJvQf85Ulr6bS9UXPZRpiNkF0wnkhWuRKZ0JrLkS/un4luJJNk46GY59b4vBa1WJowXtyUxRDoVNO6LkGlgKgqHdxhY16vKOd3akM+VWOBC0UoDLh79akKCE725ZmJ0Y4PbAAVbkAEu8Whe6QTVIUAscv4uswK+x5KZMAho1UcZtvJ2opZFRLNdraa/Es4q3niCgjtU2JL89uo43u1qb25TmU9TmU9Y8dyioQ2L/VaFbTyV/x6At8kpXi4fNBkVQHiznEOVB27MByP0uKVCbbe91cqRUSnrI5yqtnPpmy+io2kfl0nUyoFIXJ1dXW5za971ru/0Ak/9fa/DxT7rEBHkVF9PheyxrNUBVyXdCvZ9aSKkaFXMP7FN/xkA0t+yOmYSr41LcSfEy5jB0+kh7dkFHz88C5d1w+KQM81uBLpSU37kmHN62SEJ9BBxUrnbAtrwZUVo6EqXANc5DaYPFb/lwp+9wbUYXfFulmF++vru+27gSM9ha0FG79G/4zcEaPRHNb0j4+8sK7mpe0SH3PgoN9WZDEXGiwbwUIUItlFuT2DWW6fpl01Q0z7S+V/boCzy+zUqeccrqzzB+zu5Qp7A6scXf5Rtw79NPfeGjywuKpI6gNgjgOKnVSYftLiy4AEMM5AiMfgKZT2GbCqJpDx/+Z5uQN2P++ShPnyvOBCFxv+X6MNcUSJf5S0zTUSUp+UEBQ2W/jw6aEhjUA5VScs8KGp3Bo8npD/JcSfZZ8NTD0OmhzQg6oxqWSkAQY/eVSrB2oGX5eyYZLLkqIUoRh/KoOYuUxrT3ICeAQlkgxoXf43p2obRaCqHMHq3J3wO6A0O5AkIBTLaiuye5m1ifSbOUzjwljaJPdwWU7IG0xfowqIVY9xQdhk91BwjaP3yCCEG6ymePd4W5DV3eyceKBon70HW2ZGh39WYXhmfFpDuOFw2jZGpXH1HJo8jAsFjn7E48GSo3G6WMQeyBrIOVkEh5Rxeec/aVyJ7YPAaiRiPSFF2kPxbUhSwzw8AC3kS1xJfVNVSNVz7RN1YauPc5uKk5Ke6NgU5uC0aMHXQ1H38XYtrGr86YUDwTukzLIaz8pMM1/Z6o6iZ14TPnA4dUkvcysT9pncSdg6jc9SEkY8BYSgpH7pV4mEmhqAEIJPjB38gLSNTZgCRxxulilwZC8UBUAo8zB5eeisiJXQebFnpC6FQGxWfF2Ccqg5bgUvjjmkT3VOVt4ENdIxLItAdMjJ/JhUE0LnTv05FKD7RSuDLxG5QyeZOll2+WLX2flK635SguoTO6iXKVRDac6olo4PSyY+IDJFirUEyqtAFd4AZsPWdUycbWalkuWtJwai0RiZh2GneDpkKthJKQ1KlDmt56bYr1yvTp9NbQ/TAk2Ar9TeyuOnA5klkVcuKycRpJSVPVNiz+DQHQKIxqAeJgddf/qPdvf63RRSg0jazZnL2eOHfght30omQSycIjJQZ6PL9EsxuOQR6/iLEp90uDkkQVu2DvkNQfs7tdff/21dXbWOj6+/uGHg7Ozg6ur9hj/rxSxrNfpdVudN63u6+te52B7+2B7r93B/8PgKCpdVn2CuYMWLWFaExUDFre9M0ZRXDwvGy5KwyPn8y86pQtjzzWXdOeg09WWdMytSPC/ylQnv8mpjniijTVWHDCjiv9zYbky51o0wyDdomQO4AnKQaZCfH05oqZ+kFIHIrlTKWIqYgDJAIdqt4T8AnCn5nNKvZJuQL3pOreHGXSVnjdrlbTewH1jHoxR4NjcUKrcT6eGVTb4e2m1NzIy/a54fHI/+WbuN+3YZ3w9duAMuah2PVrYkTqoVhj6toMubdSaUqp7OdwrtQP+ErMhxfUnmI85CfwFHpqXyAXRICUHMeSQDQh2t5ISdxrLMPMpKbs6mWquoq+adcfBdf+RG2ApPmDZAnnDfORLRY/ZjkpnYg6tTAnOFFiZNxlDHxcgvF8aGay+a01itzBLMZIMZVWrooEwdhuupDFzvPhPuNpAcW/xTwAeEPlBODicOydSQ62m7GTU8WolMVJIqD7G9Ilbzx+PZbwuwrljXfkfr96fswsqlUHoCWn7efnpKqi0kdxQ+WJGwTcoTpk1PMZb83KD5a+L+Gz+FhbfR4cKr2GFK2ltUqhZ16ToNrukcBeHFK66ylX2JtFDrFa9SDKbgjvyTBLfNElI1/PGaEL+87Jq0pP8wKBQyEdoQS5BZ3dn4AGdzaPQWKw8hUe6HunBhfl+Ec0XkTC55pXJiCcnh2BcNAS+Fw1WWDB0YhkdLz87AR87LtwmZImPXy4xYOJHL6dRNG9LbyVePwCb26YPwjYVO2myktfERRP+9qdbBbxx0/hfW5KEtm5ubm5G/7Ul0jn/v5vGq3wJh4oClCfA0+ZnTpwM+I8XzbgD2o6WbkBifCUCGeLxam9k5yBHsznq1KmJlmNsVGDV+Komkvpz7llOy55a2XWGTtRMjEt8RTzl+b54svui1nKkGfXnkSAC/gDxqcI+Wqg0HPMxOAfRqScgw6oSal0dIjk088G+VtWdQKKf8wBoIzbUKbBBPbMnCqzx2LFlZLge78ZHEtTOiRFGy4X9mSCp4q0WU8GXiULUkav0ISHcxOYv8Ec6M+4vKpCZaEK+j0FtqcUdzIw+JQypENWOxEqLZSaUGwn2rkLDfz58x+aW/THHVRSDs2OQMCfftnSGh85s4ZJFcAiZ/WA2VK8lidXzZ5a7HBTy/UMWLmYzK1B1L+aLYO6HfGu88GgusvhH8aBjIj4ibPz3Px9eXbBrf866HXa/cD0uYmYcPBsjBCdpm2QewwQiXrQBCPVn6SOUkRD4PVPfNxm37KlC3gf4IPgwtAEnhY5E4EwmHJAWWJ/mTaH99AqUc3Pd+CWxrXQMQpkBB7CCGGg0Qk4gslsTK9jUiq6lX5NTeICwrSEA6H/kJVKQmGilxcxPddWNMJV3m7b5zB9dcXuB9VOOYKVALmFXaIEpH5LoCEaVV4lWHy38lSCIZkMGB8FFA6YdIOz05ifo4yWO+1Up3/rWzs7zUal8VFTNC/VLFFhShjLWcC+PPlOknQxA+/JnrloBazX8uGp1xbC7nImn7s1KLejfEFS3pJLqw9e+SV3kcwBIJPGgtfn0xViEWSGD0fhxeUJYOoC0RviCFFUfPkdCZKWp699sQFxP7vZs9k3s9JfasadY7pYWr1R12eMK2VIVfd3pbGvaZ+Pcx7yVGJ/rw2W/8XibcKl0i3MUS/dPq9O9Qkv50EliyeGQ3n6RsyrAXzZlRzXtvV59qWzfc20K+o2HwOswWxWUHnfRZheQI4KCDK4KugV5RB+IBIe2duFvoLHbWiDbSQeVacE2i3DwlLdQHDucLrKRTWTIeUPajG7/GIyO9q7lVKD1L799xa6X9HhXlPuyEU/f8FaHEjhO5HqW73JkBZO8iJFk2ii92Wa/+gsClIUUZNSk8AHDUn+hJ0r9hXNuCxxyy2OHi8j3/Jm/CNnVMoz4jAmwhZeHV+evFO5OaaF5K/R0ZSj0ygoxHV5J4IPIJ4thcQeHV93e9s4ukkWsnLPDq/PkarQb+rqDd8bcvwpVwzQ9RN6FkHDKxCHvkQC4RjO4jGPQDJgSjrPcO/dnJJO/4o0hoxvUrRFAVhMWmuGj9p+36NWkibbb6e109GnZzij4svTkzAciW8hAVP0Llf5F6SeVyUg2q9GS+qmEoDKdKrrCidgIXwwFtELM6hs7n5iL6xuyu63unsiD2ert3KE82L+436GGRHZT5pvt3l2T3W3t7IvEmbutvfjbPfFt8XS7b/bbu912t9Np72x199LEnZlSAaXHXLUluGqryL0AK7agAK1sIBiAUENQT0kJNr73+jXf3e/uv9nfHQ27vf3dUYfvd3q93XFnj++WAauWjD7fSh77IaCcER5eSzkdpF82MdTfw4HJCJ61fDfTr4qyqtpvt8mj2TN6NPOnNbcAaS7HpIZXT7pAAEaziRaVJS0u6UQNVqvCVjiw3JrW1wimmqprjWVs34tcVcEwEUMv8oV9TYCw+rYAGfCDEQ8gb9r1H3gguX88WYtNnQnc3LIvtAhCWLpMum4K8x+FYSoznhqbNOCJTsFvwgFJX/sMoXziHorAdHY7uNMEHdfr7rze2d/e23mdwJMzL+nCakGPLVP4ZeHB+wD4EIcTuFW+A9o0VA43HMTt1z2+9/rN7k6nt8s7Q2vPsqy90e7+3vAN7wx336yGcKxNLHXPGC7ThZthTlmbeCz0V5MF56muQRmo+OX93qrfGq7Wyt9mpbzq3YKHN1imP7/N3QiT717F2scXBw8h1+Oof3wpLiSBRCxOCuQNPNChtVCmFXaQ01Bc6U6c+f4PSNE49e2PI//BEwxA3qwCaQBRsmI8qztnTtAKsbSQnENRMEFNalGX3spUI1swUcDtY2ojQPIbmNOWhUClZEN5uDFSiJ2Jig8CigKZuw+74HiTA3YX8U/RFkIggnCBf32auXeYsXOH1fsozWMLQo5KYEfl18nzD2yt5LybSPEzy5diEAbxkolHoqxSVclSfKXd/vKXErkyevBbLo8gqKx/9b613d3ba3WZ5c6nVqtHg4glzXeQMgs3jhY8A6XKx6Tn/Na/YId0zvBKOmAXCkvuFsPPwoOtrRG/5y4sbdi2VX4NwMVuPVjjrcj33XDLmbfowOJNE27FmHRb/1NM7FXxgny4MuIE6xKottT5cqdINsq7GuIMMKwIxeP9SqTRrYH70L3u7BLuQxtVxCz6QxnBp+I9DIyVXkkeawvhVkiJVPqjKSRGD3FhcQmlWAXVlEpHoFqpNH2o8XjPgwCKPMblqESGqDRcY60aqispPoR/CeGsfeOd+xEQWx/RtRCxRu+lqadxYY/SbCnjUX64PjsVXc6xhHF/zG4wGuemAV3dxCL0TaMJj9JiM/zsB+wmIV/Dj3ldU8Uu+aYARYQlhxmEU0TS12RD/OZGxfrcNLKpTjl8S5oIKt0R+DIVP0rcABXveO2jpEORsvIGFIc6cMaDhVdXTdAWUiyP5Ya+SOkk73ecyCSiZAmWDHKcAg6ZmD5azhLKRkjci3u2RPWhbw0KR3ZCa+o5WspqhQyxbO8tGmqVmFY12ko7Kd+v582n0YRmVb1RyxeAQS1yFLfJqReFmmjgCFDzLBl3QiIdchHS5wAQyfKcyPmXKEIK4l1kTUIlP1I5PHNBmTjLKoBahBGTVakw4c2TkAKYIjRzIgeq5rBhIBxyNmdWFFn2xzBrCyvh59qcBwTZagy6oby0yJewrsBMhTihvYtJlaKYWAbezmQIHS5C557nYPBrYyyOsIFrYoayBRyNkbBtT6EUutJlnWT4CpxhVV1VL4Ri+4sgpFgaZR5hIoSnOHyHhvDyTjy4I7p49YWierJxj4monvQtmg3sUfGUbXYdB+lkp6tF8MgpUxsjbsu7JjZCQbgQzdrBezeelozalGveH8dngKYMe6beT8yG7jW5hWgZCfG2k2NVKpwo6f1SK9nWZBZ7gdatF7I9fP3B8VCagMfqbpWvlMiLeljTKmFPivQRWytfbYJCGVTURdo+/Rg8s3iI8MbfkuUVNM7xJmGuKcojuVa3nJ5BUircn6h3KwnzAfmEW9ybOB6nP1uu5U0W1oRvxR2HWyU7k8xbWQROGwtb/G9202j/6WHeQnbbnk/nIBUFrOjtTzM3mNv07itk+c68DfvAPM66r3vt7l6712t3d3cTt331ezZxOa17a+rNPTZTqUGVGtc+2ehdDojpUoBbtz3RUpzKUsuaAe+WiBbZnWyRaPHHjnFbw01dJsk9h8+Vk9S3E6zy2cjm2w54KNz9PzgnqbH9z7G1ReTx7XCFmlv+BznG4NaEkmflOxRnEtaSV8Rnj80VhUX6B1nFK8iMtbh3WdsrSX6FEl9VSPZKjn1sD7GNqtO++qCm+EliZx4FVS+d9kxF//FU1GzE6mVNp7Biv/XsutJu/HibT8JUiKAl9Ohn1fcPo/qSHeZZXs3h2P/p0mupeGSkHaH9PpPQMwlVIiGRDbLpErNfiT6UpYc/jnaU2btv6Og/b2GprFXTpZ6JlTC4by45/GhHMgJTFpKC3BQoOQ5QDrLYXSIdoJ0O7OtUnFDtuOQq0yiOQt7rliCXFnkMyyXE2mEmFP6ydhx9PU2xNvFowTDFi4/R4qFCXFI7qOIAHO8eijNNKAITXMVn/cvWdreEhCroqnUpqfKcSgiqUwRjJf+xsCjHowL0bSrYtV7IcCrieC2rgxjzZs0O5uwEuDrqgGrkpenUV/rSGt5jwe5t+FiVU54MWNIZsojrYbaLddP0I4ZhHk6oZ2/oIU0WOz72r0Q0UzaYqWjiOSXSk6S7XrHn3CNjAtv7UiLKN6wdpNnOuu6SHAKJ/SZ5xLESEfyn7fnGN2zKrREPKsKlqYBw+qpiZvTRuHVk2VPeuiK4pZLIQzEif24eDxAP1NejZL5E7d8Ddsf/eScqN940sKrJTYNyXz0eP4CwbPGweOSenozJ/wlAAtxcoDo7/oKMDQpeNa9pkz1MHXtKeSc4MYiZsyN3WTzUH/rXZQtbEc3zc6B4ZpKgPnt2eFleeI2M8EQueI0s8Dgr51pXnWTcJPAhK6Dctyj5JZZ0EWWuhYG/RiJ3QRZ3QR6NTJErilim8lumRPdkCHOdeOVuu9febncg+7yMvue1xraBUe2kViiT1fnZyXovh67v91ah7L0Eae+V07bWTbW7odfpdA+Ov9s/6HY6BwdH77K0qTVZQJ2uSPvctIpbvkpp6wid1hBqg43mqsSIPKVCVmcfPchRjamxWOwunF1tFdeQJ7vh9O3CY4pUYbqBZL1ZcQNKWwFuA+gpiEFCKX+wpg9WIGLxVSZbeTIVXbKFqOXJD6RgVEk81IWpx2aDRJg6X/rzhn7E6nxKH2UFRGmCrOQEnvFo6o/qyMP0PojD8KyGKC3ff2w2FoFb+TN49/ExhZpdPCk/cCaONxD0VLmn1GePj0kbwLpVPpVmRJqYduB+u032o7Yke8Z/uL6+YOINA56MuAUg9WUxhPsimYNx99uLi/dX1y+aLy4+XL+4vXuFtTGx9jm1+PLutxeDw9PTATwUYgpVh9bSN+nCwTxZyn+OD2tR+nyGC2tzwWRy7PgOZiUNpPrYdKS7709A9oWpwH8+wP8en5yeXJ/An4fXRz80mo0fTg6PG80GNgoifMze6Os0+zOxsHiH9C6Tu1UBFEZk+ZSkg5dgoqOmWBcXppgv+yM0F62aKY21L2Ujm86XLhz5hnGHP1ydXBYCenuQrbyKJNGExGwopUcwTyOqMhbwmeOBOo1nc+5aXhqhJA8qUia4cQ8WBtBkbDBXYv6ax8hGiD4F30Y/AiJKw+qzX9pli5rlmrkODIStwgwoz7YSlRWwovaIhJ6lv4ApQqui0rbQdah4hLzQY+4BVd1ZXziWbCuErDFvycxdDJeZTG1Q8wvbNvOzOB09+VxHz+wTQmYTs8FTGjxlgQO3vUldPTcNOP43DfTS0B/Wve+MmMsnlr1kQz617h1YJizQAxzDmxCYUDJ7XNz54U2DiatuabQkFW+wyNpfQYKEoyQ/f1oMrpI5aJD6a4L5iJYGmMvp1ITVSQH8J1FxDC0/STBejg8mm8hbMdIw8dkmYOErfSpl5y+C5G6qYbxyZQY9g1e7exom2jCdQGWSU2nCT2WZK7rr5AhzPD01T1keLj0ctSdxGqlFNyhGxlNqcFh87VExm8Qqzn7z7cTNpPZz6frWaOD6k4njTQaiAnDxXs4XQ9exB8ZqwXK2MMtferu73TeMXofKwU2Q5EJZdBzyT/Z2CJgBTfdsu8eGywiQOlEc454dLOdRqEAhxWjDdgIlJfIBfUJJV3F3b9lHzucCv9C5B6kGyhcjsiG2DAgWE73dQn7xq+1Mtv4RbM3/Mfvozt59OH/zxgv+K7I+XLq/9qPTN93Jf53bP3z/6/y7/b8kecfOTiJKZmcnU9Q2XtGy7fkWj15FHpQlxW/3XGFVtHwFkaF0b/semA8QeA8rdEuUisgXIrn02Uk5XuFw0GMdakPDzYgxqxS+iBOKSm1ZqCZZBS7VCGnihdCabzo6tub+3g7+LWE1u2UIdXr+SUX7h4JGlN/CUg2XcwviO8Aso4CZUfNehBJ5445eutOmJe0FIJRIO2+j2VhY34nAiaFjN5qNqQ9HKhTFdU4BBwI23Yr4KahIjWbjwRonbSXwQ+bS0GcOXw9QwyqUaaJCdF+T/egJYEUT4zYV4TwEoKogUgBTHMujs0NAQwwR5wt9SCDEsIC7ArhKix8r4bvmCLfksIxS19fOFjcaoq+yZRbuc2j+rZE6/mAXZnrHv82bMkUfZeGdC8/gBtb5JQFUxeC11H6oMBbF/cBHaBJzEujo2RuuiyGRE4PdVO9TRB8juqG8cufWxPGQ18krS4ykvD8eDMr7zM5wzgnWsWpfPeChuFyDyusq+7LuLQfZS4zG7S1loEAMYlrSf6eTdBYF/CFwIp5bvfZKYBlTCHiT7niqX4g2XlGmu8mcKMyKMhra3dy17BjYKwd4TAFrVgCflNHJlQ7ugzVOT/VR91Ks144qGLteK05It8darShXzDrNJElkUYWDCzxsNDvl+ARjCqZ+RFqBJUDQoV5zYVWCtewt6ahrzWX2MHUiDizDWNK3mgMrI8CtFhafCYf/FkCC65lg4+gQ3RQrTcCfWmMeeC3pPGiRibahITa3hGFzpV3/ql2JmVVV7rxqBmp822gqFkuWPKNpGr1NH3pNth98S/mUGxXyn4X7jPgIpFEUsvshoz8LO0FpQNc6kbs4LNI3Bs7oWyTY9WHSTLz18dvVU7Qd/Za2sxZf+Xa3xhxoIlD0SbJL2KMSYPyWqs8uqqXYSqcI2+wEQJLBcYCGtxibfyZKgGDU+THhMsvPqJQYwitrRegA5hf+dkb4ojBFsg+eCyGxMDIwypLoLYLEsC3uhYtAYEjjW4AIT9EssUQwCfzFXObGOmGsFQ2563sTsJQKuGgtCM3jD1AuF7HARomAhSb2hMOW2PwWu8NOwju5BMhJ73Cd7gqUJbX7/250O51OdxdEEqFg5AK7/DsRH0E6zf/P3psvt41k+cKvgtD3h+0eUuKmzXXnxlXZcrW6vWgkuap62g4qCSRJjEGADYCSWBOOuO/wfU84T/LFOSczkQASQHKRt+JETJdFIBO5nDx51t+xvCZBi1Dag0YoBVip9auSYfmH2yCaSHsyRsaABypTK6IQoovOIURlHvtQrS5gDdFKUt7fqLCZkKz2WntBBN2T4Tt/YlTC6/dZgHDV0OxvohzhFyshaM5mttgvcailpUxatQrruyWyEJ8R4Xn1RLJgVJCxqq5agwNhwfbqNxn9zwhM7jDsPSsqoKceESevSjyKuct9iLG7hWG2cZi3FK4r8gCxfYOvI/rDDwJ2cLjfcZ6+Ya4fplEy/cm5CFMeOG+Y67y7dn53up1htzc8fOaczecB/42P/u6nB0ed/n5vf+A8/TvUeWk5gf+JO79w91P0zPmVxwARdtDt7Hf3u841G7PYly0KJha7fJBi4OZ8Ec+jhB+MF6G6TVeKJwWdpjae1DCuL18XQqWrNMUNGqTf1aIH8zWm6kd12ht3j3udHvdORt5R3zs6ZUdHo5MjNjhlJ+Oj0Ybxg2ou30s+4uoXxJ8jOzFngdqoKOtqIfkmQUY3dG4clb8ZjswG1VgN49JM8CWgmRIMp3WVVooJCdM4ClatyNpcjxWcN7marJov5LHKslru6BZDDoKCS8pAvK8uXre7nU5dsEHO7WpggGvaO3cujJ0LY+fC+AZdGJCzGc1N5SSDAMsbJk50H2beZFQjkFdO2Z1mnxEFnpo1KVVYyQ7/F9/eJPGARlPn+8cFsM/1hhXQLn/xZxRPWOj/odhdYXc+l38xcd1FHFRwQ6x2jGmQVMNYS+B3sqSSTG0Hjf3eDzwXcp6ElY+DtYZ70Je67njisnl22S0gwUqAjyBQyrJoBkh8WAfVtzNnUHW2vkqyVnhu7u/PlomfUnWpJJrxA6l0/MUyA/OhnaTMR6uiDl4rm/K0LBRW3TGov4o3alJnQd6mtzAbFlpdQzZsyxlF6VR1IJ89aemviHRa/aXGdNrVc2bF8GpyZsUA9vOIMTDOcjRn7sKDdyB5Fl9tFFWzknjmJddr5tkp0Ure3ANRTzt64s8Z9/zFDC2CYBeMxuOCOVBlERmk5kQoXyBj3PFbowCtja9U0E5oPljbtnbs9AG9KB39UFuFToU6V1w/KhI6q5cuCvUV450F0BtoP9Iw/0I+JUMV2X8YWNOzdMNbCqu+VSmGMGG48kaBn4AonQ0BA7Tw7VrJ+CgXRN1ATXAjRosKDbsYaS5AJIl71YWBG9ZCFjwvBqs7ExSJYDmBCcYEGSV3XUxXL138BQoOP0mcF6rk8CVD5xEtRm3lYbnFtbsjo9wro94bNmzBvq4NBWyp5WLsmu3TGvhmwfRLntUZTZRcxCSsokz5IZgTG5PoAEyiaE9J/VHAf3LeXF+cO0f7nZ+c3/zQA8Xv7Y1zuN/9ybn+tfusuSq6NqAak8ki9pvxkt5fXZgtjTL2E4WTFU2NdPdDVccmW6NABjHKRFL8UJd3C41SEejv6LKcRklKVYEdrCCZLNwp5GndygqcUTzBUfzldt95C+J4IKQ4OMGSywvpiMq10gd9lbi179z+5TYTtqjE7cOchR7dDwTghl255NSU2S7/seDxUthyE1HeOs26vRb0TZwIyPsvt1qHyOwFPE5EmfVV11C27H/ZL0185dLFK0up0teSSxn/1kXVZBrN1WKBsPo48qnmzTUuqXJ0F2yXeo6Pbm+QJgkNJ0Q6ozNx5KNB4quLUv2iIzOYHKsHCxQvkbFsIuw1TmivKxealQwtdp1kTQwi3zrJ/tZ4Z6vpz01AY2XDiF0Aj9bGsAAbQjMjgNTq9j1stHpR+9xe5icmBlQEC8APtYoE+LGKlHdJX8Wz/WePCzUHh5lp5gdLBSvSwXcTx5ffs4BNkqk/H57N/Tf0avMOzUovagm3+njki4UvzS3uRMHLWFr+SqXtvnQhS3yX0gMqQWfdvXx9ZDAfnYMxWBqNmAv4z/fTKG9lp2fzOerVt4sQMTaFTrgIlU+pLCTX4b5oS5SbUG64uZX/mSX8RRR6llA/LE1jf7RIDUuYE86P8lALXcSXJChsU8sMtXrB8PoJo3So/hCmjSGYNsB6xpNE/lt/NIzirI16KfcreG6ZH8I/k5TFaTIEAxIOwFP/9kMxAPzHlMnxwL8+WgNeygX+WxKFvyq0S+vbO1tobeXkt3M7+GIKkWhBNDkP0xiJMYNYKWzeWNR9tBr4q4CRgRWA2eo2jYhODaoAXlJBtepN+YGWGJ4B1OULzUNUlvrW5+H547HpoFaF7+a/CeB269AupKiuSfNlhNfGrSButa2tEGtW3hHzObrM32Or+eUrTuXn3Jd0fmuJSWXm142gb7LZ62gCSI5ay4/GEXW/3pC6VWPqfb0x9arG1P96Y+pXjWnw9cY0KIzpJbLSs/n8aqV8pkZBx/ARYIu2X7FiIwr9SX7nHOTmVXSUjRiHJnR/Lqgv2+y3OtFM8GDQYT/Wq7IFtaRa81BaRlkFya80iDdocditueWaizV9YYwkfTfn4SvOUnCd4muOG3lcZRaMmQ84vFytutEiL67ky6t3v168PL8avn13M7w6P3v5j73W3qvXZ7/gD6/evX/7EgGsr67Ph+dXV+8AlPjmH5fnwzcX128ErPXN2dUv5zcXb38Z/v38H/Dg+uLtL3utvYu3v569vng5fPHu7c3574BV/cv52/Ors9d7NepsDVHpi1JBYLYsA5r+3YSw93euwgLEAkJwY8AmBo0NhpYyj6XM2E9b5KaJdxyWJJHrY4fKv409O1c8XcQhIiMHyyyOCx46U5aoLkzRTVXyYXZjlGirrCWrX4RHFtn+jD3oXWIKbsxZYrLHX+Hv+rJFsQgRRZ0Ynb+x30iO1zdnNxcvcjQlqezl+auz968RV/3i+uzn1+dAmNeXry9uNlPfoGnsMxNCy1sNuVsNn2IdkoUMwKDySVEAySkVOSgmkfbvKNHKT6uVraJrK2AOV17cBtuUutQVnl3KH0SaZcJSPxkv80lDWjzSWejw2TxdOsgvJRAMegBFP7U+LTvJOhNXYLWiIBCBF3YEL3TtGrNGaTlw/uoVwkKHFUhS3/20dEYL9xMnjO6X5BxC1+Itefv9EHbwFqO92SjBQoipxnMxIKKVdQL+2piFXjTDQJWaWP96c8ucxy4PUyOA0aV6BkRbBDd0nnb+5//+v91Op+VAJmvk9ACo05+xwEHAnuSZhDEvHFfnVRQ7s0WQ+u17tnSSeeCnCaGOuwt0pQHS/GIO8xpFCwiFYW4cidSaxHnK9yf7Tr/Tco47Lafb6TwzhYCokI9uLuAD/g2fngcc2Flnv9MtwXtmSwKnBycxVMMvL9Ov2kkm+yw2SSTjlfQvyFwLzsE8ZT90blXviTHxMLdnq5iHtANcnkiONaDZwALCGwl3k9UQ1xAEB47HaNXEB376BAsujxapE0a5BdP5y6aLV3JMFiUhWlZVkK89hqy+iZ6Dtu9cpI4X8QSDG9h4jFmYMKd6CUlPUej2DOKbKHhQEdhHu5stICUKC65JBwPDQoJ7tkzkmt+WNuzW4Cj43NozogObwTjUCAR0GiUu7EO6J0JxwXg0vgWDun75d/RZGENo6vnTn08iMsMj3MhbQux1JkzCkicuDz14eCuzeW5/kpWfEw2XliL5/TAp38EYcqLWZBUyWu9+Rgnkc2VA+zUW02j74ZhjjQ8RM7SccyeZYo7eaImkJktcB2zyRLtlzNFaMsFNecjUI3Vv/FdCAe961EvK45hBuGWWpT3yAwwJ3oM5LtB3LnjHxk6iklaQTaq8Tm8Y5mpk0iRWh0kjITpCkhX9M6F1owwBfAfW8qlYipaI2mqJfDRkzH+7fvdWpJkf4CY/04AyEh77EFum9iZJgWIEU+h2/v7zKmdpZXvxKrcgGXtxKC3DFZZbYHkAM3ZcuiZfqvQEYyhAWTE0vmZnh/8BLtzdtba71rRrbaNLo6DAft4xxyrmWOZ/8hxas8CyI8xkd0jKDDLZimuMHJl639kUbQqEVNNoy0ja21p9k0N3tZmbOqM1zLtPSt66ZoNOANF8m59D3RuHvO2CmgNrC2hUQ5tAjjO0Br+7IgOu9YVe+kRLzax2gbpfYYV639UK9b7CCvW/qxXqf4UVGnxXKzT4citU9Et/u4tEjqSLTXDz3yoMeVwkJ5bCnyoZk084FYl/e7r1E0L9F3ESGeCNXuDvWMsV6rOMmPsJ/hhzSM5BDHuwb8M3UP6BW1ezcPqkNWDs4rwi8bVg8fpctFUu0HEhxpdfvT+Zu6IacCaTgAlI5rnS+qRFKNGxYXSMmYSsQZlGJ8CshHFds6IU090MlNTdOVV2TpU/p1NFHc6WhX8lZguvWCFyNtti8gt+YK1MhlLLyjyE375u/kHtQrYhPGURr5QdkoFBwKUBITHHnU6/lWUn7L2NnDgChiNNQ++vLrCSpE41DWk/tTuTDeHjqt1sIz5oy/srTon4Pv61AVJ0eaurE4Cal850+LKvLNLp0IXU0Ng3GOPOHPEsCpESoERuDGwP0vAX6RQsiK64jRepG824ABv+5IfercBBkY2Qefnu9EMY4WrjU0qTVteavA/2P4SNyEPwDYOjaCqsV9E4G/y+80KB5aGp8JZARIZA/bdw7UH8SRRXgGVpScRZM0121n+tAFTRXjEQIEG+4CsYe5ZoaeETyMSgxHFRaF3u5v6HsO28oSsJptvtiMZwyWVzh7cwCRuj2orQ3sVPO0+7nU778PT0GTZ8gR0i0Df3FpjyDnZYrIaO6wU29ITd0WDezXzESwg4gEktQhfDu/Ed8vHgW5cSoTsvV97+8yOmw7sBZ7GYid6wRsRU9/Lh6WmupmOnJMPlsHB6nU6r1+l+xJtdKk7GQpAr+VuAMD/mzlh2UIYJT0HWMsvoGjwGHAc3YEkiYC9A0worTl3iECS6EBfKdHJFw0ucW8CRgFqWYx9h0KEgJRfo7IB8AvtzTZwKN1ncLpKcGJKCH3p8zkOPDhRuEAIh/M///f8ADwg9seKYUVeKxdx+CB2ijiTrGnd6EabRAnASyIwMtc6cOx4nLCOs24qVvAV4AT/mBB5ItIdATooAsY9r/XzhMYAABsAvCNjcGfH0ngPQSM3kbbiSaFPDVF/kWKpww+AWi0hT2mm5e6iIWLD5HCfPbru1BpLde1sZTP3hUQeF/lc/Hw1ZdtUHy26IpsbgjtaPiF1vuSZa4Xr4HZwuQ/4wB7hbK5gC1WOp5XormSUSjyLPomL2Dy55W+crm4hyPbm9Dlb7Qj3bboGfCtCX/NrXGCCLtiVPlz9NFhEokNja8yJ3MQNNF4+VwPoxBHpX5UG39pJoEbsW+gyCDHKDUfNzyVEn5DWVVF1m4mQLEiKADEjLdBS1csaDXkm2r6ANFQK4FG1A2BTXrVKummF+BLCKpycBZ/5M+bAKzK+aoZRG/lpAQGkvUQn6lIuiA9AHQpcjogzJjwoRnASIvEyqdZXd5RjOjrIiGlK3IzNijII28HwXFyFJvPobiEVE7ACDHJxuZ9DpOD8zz7mSpbnBjujxlPmBQmy/lQfolsZRL50Wt9W0Rxo+4zRN5/vS9gYcex9Cr/75QV0mH/Y+/rPzEQESo0+L+RBCtobU+9Ny45jdA1Zd1vjZXkHe/dzam0TRJODtlE3aE5bye7Z8TKON4Wvr3CMN3XzL5hy79f5mbTsrbKC1oaehzx/d6mOYfvknEX9Znssv+KpzwybOL/RqAWyRyggWLpoqYqqKWDvHBwkwb3HnJI7hy8qPVPhc5UkyMkSBImwIjdXqKoPqSu8RHCB8eh5HD6jFaEN7g0idcXZRwaWMMW6jJArgMBCaIKBd+BIw9cnBkxb9K4yckMpww2syJG8+ZeFixmPfddwpi5kLiP2k+JI74WDG09h3k2f1l7t8reJqmPoef4caPQsu5gbjke+JtYjEW44b+ODs0cpsAKCBXBB0IUiVf83tmXEGVd5A0rswUMq1QFqGURm2QQCMgDc3drSuoDIdLd0vN2/av9P/wTu/yD9+//33htWElpe9V/23g+P/qFjRhKfv5zfMcI4AohHr0nE96lCbgbCwAGWDLSaaMVAhAxl9uMKqFsO2jDYnnZVkAp86GyXiKG7MxwxCtIlF7JmZ0LejutRdEDs9xlqPMSwjUHOh9NOKN3Ueo3/KWZBO3Sl3PyVDwYHMlnqAc8Wg1CguVBvS7JjoWMTIjHgROtS5Q707FemvivTu7+910M8qFpsbcF4Q2zZcX+5b64i9lR2sCtu3EgTfY1pirKD3ctPeSlnmul3fprrzBXb8G1Z3Vlryb1bjsdpDa13H/gj/YFpO9f5vF+PySzDZUqKIFvBeuMg/fpfnE/8zjPnEbCo8U3jx4hVSMgjC23RZ7ztvwdZHqZalgg6++8lhjsjNEF3a10357e3Zm+fOb6CkxSEAv6dT5wx1M9ZyzvHhOTM+/O38fdbwfAHE1nLO4UfZQP749hq6webw83W00Pu5xqf4o+HpuxfPnXcuZ6HPWs6b8+fOG9/zAo7faDlvz149l+Mai+7gJ9GJ+Oni7XPnIvSgh+vzs2v5GLpwzhL4+S3+TB1pP0MBmavzXy7evb1+TollYsOe/vz++uLt+fU1arTnb2/Ory6vLq7PHXeRpNFMqrPPdAhwWOm91t45/ee38/fwB/4vrA9giNB/3gHsyJtz+P3sFfyM/3vxFv55fgZFat7Sf7TRGYHMNdOo+Bp8usQELSQ7FziNu4BQwCFcNBVCaagCjbUG6JxNHHmqiNZZjsAlkj1asDGoESRceiGNnEVI/14aI0tVZZmKkhyVExFnu6okknkyqtEmE9radBpq904XMxa2IWsYowwK9XC1MWF39frAX/XpgTiwhoIgXfxV4D03WokEGUJA7zr+WMba+ImRIAxDLmVMWwxR/8PCkZ6paNZ3omwDEfXFe8K6k3xLqptYPqH23ZVaF7rMnZW1us16WKlqQK4/VWVww8IBlWcIfH4lGrXuqdAUSCtNZS3llXrS21nVLMi1ztsU0EZyxxpLDea7kI1Wq3Fgv1sSJtu6N2yA0lkaWyRYFpReaqPCCVdqnQWlJIsEo7dW246sFWRlumsRhNYMixupamAr7Qa00YAz7NtCA7SpVVJpOV2BxWzG0bBPJaioOg8TZfqiGP97XXUDVTFcKJc79JGtxKZylhHGpqG/Gur9YcoONB9T/T+V6Z67rSHrioZj1BfydZ6r3NBzhJhTkUKleGCW8DYMnKr+gSQxamfV68EjrVeUkuqdg65oyENBx5Bo4BOG0BjyMVq6xU+WCJqx+BNEm1rflZmik1Xqq/S4i6lWxOTCLS7fkVEOYjIUQkiOig97vU7nw94zR8JGxhC+oD19ePiwR+43zJeClnk3U+9ZgxjTEFCQF5F7Dw97rb1+pwcSslqEf8IobWXmcYTkGXPPj7mbGtbmFb7hqDdArskFnkJmXuIwp//woAcXr02XU848kwdCFf0Ujj2HXkyovlnoSTrMrSwAWEH+DAebE7I0qrLHoRr1XyPVC0DsiMFRWDsE8rTPsAabeMNlIVDwiMs6WB4PTcdfbdB/78EH0J2jCZ0fW3u/t8/m8/bFS0S1H7ndXh8V8qqs/JWCS/I59Abr0Yyn06gimB6Xl15ALSbJzGhNYnd2Bn85v9FUSPrrr+dnL6tClrCOnPlI5vy9SgsRLFBEyzf4W6lJboAHFUsHSQGGWwHKuQvNiirdhxAeBemipqXJ5eaddPC0QIqCn6hbZDDoF3++rlesTqri1Eu7W5CqVDjo92Rsqx/nBpLl5+/SNGfnld2yU3ZlLVSX2csnWT5VofcIHZM/ONdTSDKJ1btQpHHpTEDw+NfCdz9Bcm8kxCK0aOUvInn1YEhh0kKwJ5Qt/BB0t4Q7QcSKaRMsce65tBCAUUTmdjpB5JbA1Qwn88h4Mgtrsyl6torpJh9Y0ctbVjpM9UCnyMcEKJBMADDwL9j1qoCXljNdzqc8pKiYRQjXrxvFImsIJd3GrCoCu+vaGF/+BTU2dfvGzrzxWOaNLZkitmU92NQA8NV09R9A3c7jQYZsBkcYYleW6ZSogyTEIYsnGDYD1d2zjjK1/fMGinv+4hS1vORBLTG9R6y4+O2EcKzgZs6ZhHehHxU9rgtOcxOlLNCcLdRnovQBoZ9yD6OZfJfXVW1HDA0jeoZIY0aIGQmnN2cQ/QddZ/5Y/HjjJyCVxfiZt6V5QErxXIB2WHTf62AprJRBsd2aBZPdq0J+OKloATW+l7JC+VzZ4Oo/2emUjXsa767zjYnX0LSXppBhApYDMHZR2XHBv6RDDOxS0h+WSY2ZjQqAKbE/FIGoQwAqms24ByGlQYPTrCICMn9BYMDEd6nMrc2zvj9FrSpDTPcRCi3FGPTIXDeKPWFdXc3VKYhRrxdH5TP3WtozRbR7uqTycQ1tLyfnFFTSsaOetiCaPh/ECacE0YnEHGkJNjEWGmUgW+P+zYvLFe35dfYz6E0YiMBjvaklLetqCG6pUeAn01xeYMULVYa2R7BvPYrdSpNeDYAfgj0/xYMDqETJMxOvztsKE5FwXz/eQxsiUz5Cg0UWsvcACH0PXDlteDV3THud7qDd6bY73ZvO4fNe53mns9/t9QeH/7mO41/K1uU1msdRGrlRUEt6Gk6KQkRRLemgPgHb5JMW/ff6CWr9T25eXD5pCLyAt3OUDL9UafzLOY+9GDTSx47Gzr601mVnbl55TxFgNeEs57i+urRE00cWqLNhb0ecrtyvrcZR/yh79TjL/O3GTjfvm33ktLmv7cdNb2n3txs9XbH/68GDNRza/Peyf7ZdhhBdps/ZlVWt7bat0AyayqzWdyOz5T5/bJqINZdSIzOmDYLsGi/Qki5edMQHgHKu/+O1BqIjBSZw9SFNGInIICU1z4WqjD/S3lDv29oi0dsqO1X4/kpbVj6k+ftzxh6G+Vy+TBos842UBXx4P/VRBZeBOjZtQdKNCgkEBW2iciBFziHftKiibj3gEncyNzSXCdcb6rAkMgn1hTgRGgXZbbmWk775jgs2nNvy6vxlAS7neDKXPqdlEBZ1Mo0WgQdWsgRscCLqBObA89rRUUc2BVclxI4IzbNCDVEXCTgVFcxd/yiHP9u1i+upJoHqyWcmMjlsNTF0xaKZwmEO9p0hzuXm3D1cc87dwzzIrlXKdJHUFHtporQ6rlJJv9ZXbPW90ziwGtqvmuy3d3V9d4fthzlB64gR9lblasrCOmGEWI22WUlSfqKOj7lqVSWhyB5tCcVIIUZY9yrGusKe64Nbc88bahdU3q/V26kMnw1OrUykX5udlRMiqtcH35MA9FKx+qvqMg9MYbIrNdvUjqVNDQxqzzsdW2uaRShZtgr5FIVChkH19LFKhHz7G1yDWWoRmWKkBWxpG2th7EEGXZAPYL0+qG17vAiCrKuhZhgP/Jnf7Imq6zvrrE2dkRECArttCQD3vbzp0lEwjyJyYfEHgF32wSarvuDc+UwG2MMvKix2H+H10NlIFIXdQC28kIM/aYSBdoYet0dhRSmtmeIKjM0H+UWEdwgyaGJxmt5bDHKTkeHgx8CXIMi74pg5iwSlqAfmElQ4wYizIOBxW5WoFx46N+Z4/CEqEdG1Zohu5GGw4iQ7txsp3vrs2uAbFwS4rupd7k8bba0KnmtpazLZxsUi9/abYkyPzU1MwU62m1PaVtgmqSgIVx4ROnMuAxby9NoFOURv0uTx3G3s2tdEYWdW73uOe9ZOYNPyx1e/Nov7V199SrBbvbeVyE37rpHSyjxzR2JfjMQaSGGLwpaZqmwv8TlUvPhy2sr2KMIQWsYshHoqrlwMvc9LJEJ31eBSPJZMRxGLqQrH2eWFVqGNqu2KAgupHEdWB6G+lFevMzgxawTVbGUT6QbrRrCEE2SO4BuEZui8lM/W+ARGfQOLXF1WgjS+NkN/3Bqt7+ZuW8R3qtYfUaj6QlJD0wmzt+tshfuqz/3pbQMNHLn49e0KBTvDxM4wsTNMPIphoqUYZbV0o665ZmO69qbBTaPJFctoEUuhWraqD8CbR0k6iTGkxOrKhyq491Fc5TKCHRRvOCHnHgkydHOaR4cp9BA9QxsuQQIQEAJrSbQROhtFGCtBBRvlN1DhUmQuGzg0ax550VbU8aleCHj6JTZF925m5/EdDiep9iPKoRDfMd4+mruf5tzKaFHMXqMI+xgts7DXNM7En4QsXcR8BXkFAuUXYTr0K8KwNQFavEqxXfJTWFktiv0/wMd5o5V0zu7xQgMfMC1m8wUWwbvjMRUuwzrUiZDr02nOqgKZLGnI4yeJ8+L1xZfAzFajLS/KX/lDm4cQ9OcZVkFGTMs9UWJZ/ahPx73Ridv1BvyIHY/67qF3wk/HHdYd9dy+N+CHY/j9xD31Orw77rH+aOAeekf8eHzCTkcdV+YpqmDq/Jjfh/6Do563nMzl14LKxgJ6MrdLcFH5SbLgHjEgw3YQcA5VLrzjsdTDtEUJPSfmQHbCYydXqZQNbliS7nFH/J85pCt//DQy1ldC38nqi0abW3tOBXMqMFPUtuaWQzShcpyjJbFmquzeuPMkf6L4qSUj6L9WZCDUyGuloc9uXl8bCltoaTOZnLLvvFDgLDghBNv59fKFc00ammiS/ORAr7IupjTiC0wA7f3mNBCXDTWUJiMrImHLeXGWw3O6eOlEI6yI4DlsDIAHizkgE8ApFK82cAvxf23D/wjiE+Kz7QhpqS3HKOpNbGWcQCVjHiMFw9ouSfJ+vqcNpu1jPE+SBDOB51/MX8FrFSJXQCKZp4lzK07Zbcu5pUPedtkt8Wz5A9yPt/vOm2Wu4dX5f7y/uDp/CS1/Pb+6ePWP4Ysz2VL8cPHy/O3Nxc0/bonJCC4yQ7Qn8WGHFXb9J5UYCk/pXddAssV29SusTWVPFxhgP6uv3m/EkFU7M/GvdjZsW1F2NYXJuAxPk2icPlNRJzlUVdE8Ka6Rn0j4Cyrn+4nnE9wyGRHKpsmiaaLJc6fXQeY2jjkkOIlcwEUIZe27HXo2Z76Xf7b/IbwoRAi1JIgVhhKVew09CJTKdbf/IXzBYzjs2n61FWskvomRLCMOUTZCs2PO1J9AqA8uJHQCdV7cVN90H8VkVBnK7zdHQMpomKqsrEa121B1dzZC/TcTdTLZWtSoxnOoe4Wz5KiQp/dR/Elhw5huCQ0pXJzGy8Uo8F3dyLmpTN7ag1oaeyKj7+NOs9xplittClJPrW1ojjSLphnmTjFKtFC+pWqgzmXs37GUtwAfcj5i7ie6PQM//NSGgxNoxV9E1jywMCvwIPWVZhRnc7Jrbo6Q+Fo5DT0k83DQ7yHT1GSNKHb6/c4R/kxCxGrRmtCnFox4dHjYP8yHeRtjOTO2ckaOC0jYJNxKyWCcEZ/6oacz4ptFGPJgm5yHiYLTKAySBpP/KeFuzHfMacecVt2UEmXVHuIXovrdS5WyR9uTRp8ANpfSnxFCV970GbzCStPoYJ720fHJKRu5Hh8X/95nMrGveVLibNhM7BpfLUzuZo3JbUqa9ivR9PeeJVk331LwhvM0fzE9W49KrW+WHA9WLDe7JtNpHC0moMn9FsWfAG7i18sXW+G8wtkMR2LHVXdcdbVN0YjHDNCZWb4Fr9HIV1nRdHwQovN9XQlGuE0+wbJ+8hygdVWKRMXO8NhsnxdXHNxqY2qlQ92wcwGCYOejKZU6CZIumlap5LgeNiw16tEyVw8JuTfa2zFGs9rsUuHYQFsmC8C/iRo6yNl0pPLhnkWDhTLIUM8JF2AbhJYNJ4zA2KFjOl8znjKYKE4yM17JGu6oN8d8HjA0t4pq7JlJObGwqWIloqFczQos05xNWwKaGm7CvAx/K0/MbVGSR9vebJn8K7jNpPm1o6fU4EcxC91pzRx0a5uRmKgHq5HkARpqx7X+gLY0kiiesFD4U9YYjd58SyPS/SerM3ujJ2ZLF0jBY6S6N61icY8raFENTEvVrooMr2SY2dzq6nW/v3rt0Jtk4s7DS1lfetK/lF158p//Ap0Wj66Fx6kOR1s4QnIsN1GB81RoV1WyeLRKyFYIUNWhj41+853d5zu1++S5QMH4W2VnzhPLY2OQ14bV2kR07JT+ndL/zSr9xgO4gg10A6Nt/nBtA79YX810VSxjbUVXATPORX2vAmzc/L1KZGNzln4NynHtt5phjsvruiLkccP3JeZxbQ6CweepJC6W6RZGM5WKfsEomYSnwFsS5ynEE7QcEYHxTNf9hLyUxdDo1gDgUVKEKsfi2IbiOH6a8GCc8xhX0PvOyFHEc8qZDFe2WkIuA5sNWQVs3hkWBotix+PhUlP0ZWUmGRseLWKXN0TOoRioCfvyb+i6SrYXY5OHsYEX1qSk3MjYO8X2VGKKoBP5mXXC0wftTh/C07u9573u805vexkosACUnT3MnrbF03Y+KSXgE+Yuh+OATQxb+RqfKqMSvtVsr+GggMxjP+HDP6KQD/+1iFJW7vxcvebAaw6+hkudpCz0ZFBQ1lsW4QLCD/4rY5yi+ZQhqooM0onGTqd5wIoPlweZweBnZdicwsg1Ro6w7yhMdWSSA41L1DkE+nXxPoMCiZA/MWWLJG3E8Dk6gfQpuiANvFzcnNltVhxhffcnvc+a7lHs/U0p4Kk8/5K2ZvhK7xAuqs+GEqqCyw9HhnqTlwyn5kIYkQ+Ruh5PsfBN06bOseEwiidGxp9pCfSi806znLRg84Am+YOf6GUODCxqcNg/Grlj5h2OmeuOut3uaAAIqu7x6Wn3eMzW0+e10ZttYW81O9iGM3jJZ5FzWe7DkiHFUWSzzPDa+ot8BBHkLj854m7fO+2OGe90vFF/dDIanLicr7fIhCI29PxkHrDlMFtzAyu8CD0MvczArCpW3pn6PAYJbilRykbcEZ9AWLYmnGCLnKTKvGPBFx1h0mvY8zN1fZl9QyToVX9FvdHIYEcLrMKDoYBDPmO+IQrvmoNIHDr4siNedvBlkJewyNuSyqjiGzEHU4dRgDAWew3HUezyYXofjZmbRqayeaU9nnHgecnUn5OvBOI5xeSFQAXSHks/hDf3UfsV9uucLdIp3LEuk56TDJOvtPmN1QzydZdSHscMhIu2MkqO/MBPl1gXgFJRhtGcLir7WkuazNTG9+vy3vCFj3lJqy2/IiU1eYej8CavCw0yNKtcq/VSa4yVVKdn47DJ/l5OjcY3cuUPtyIpVQ37cZHp4RPrwJwX2327ZZ1gpOvCz380b8I24ea/yw3YzhJ+s1DydXtijSFf7GT74PEb7+xWYeNLm7weXnzVcav+Qtu3AGz+gQ9jHWkVk9FXLWhsr+eXL/N12YSw+gw1QOJKrR6cCPtOWaiKsGIvLrGI78pEJFWFiQXBUnAJPxERUaHDsPBvKIUwm+2wgcXGlfS9eAhWZoMZRNieLy7vBgcXl3dHzouLl1eZ11IbRsl5VpAwcz3s57NET0/3e8f73d7Jfueg17UVaxXLM3TQG3Q6z91Rp/P8+UG/p/Yxk1SGJOBmlTLBnjKcRwDBIJyCQrZ6Q5IwxfNcyhcaTUE//sleT86xqfPZPHXcu/yWfV7nYJcIAjSefF1BmUOoHif04TgKdnTwLdAB7Mlj7H41SyjRwnzHFr4pciBcxq2xhggwD6QT28Qc8J58B+YPEbKQOFfytR1JfEWS0HduS2SQuNGcJ01kcI1v7ajgG6IC3LjNiUCPM912AeLd/q63v7rvZtMNxpT+BPIVhpM4Wsxrjno0hgOO7nyH3t2d823QQVPD0hatZT7V9hxk+d1h/jYOM+zFxocYI1/NJ1deyRJgRsbXUZPdAf6ae497MKRo7fUowMIoWLZNVbu7Nstf0Gz7VSB1YtTF4e7CuHZhXLswrl0Y1y6MaxfG9WcN42oRNBrlSR4dOu9vXrVPnNEybYqd3oV47UK8thLiZZA+kpSliwZ5HH22sJpiiSUH0c0UcH8CADwDcMg7PxUotDwETNF68qZOtdwA9QP2REWnq2XNkMSAZtFSpDoN/bmdLqDexp2hjy3CNDZcijeIkIkPgfYy7GJcusC/azri768LHLNUIVkOgeo0WcvTW2ZLVEM19FgQhVVgNJFzCwO+RWkxmvmpc7sI/fQ2V7Uv68V5BfCVYkT7zsVYYhd7LTrEiNuoEomob7MuqCl/G53E7Bzmp4eJX8s53vOStYw4guaS2rLvvAJxmQfjNpWFJcQLHictTOuUgvQ+skZNki68lz3JRxZosZiKF+V/nMcc5VkTP5JPAcggi+QC2n0Cs3oiVlrckmHkBFE4wXIOcHvkkqEEwOv6a2wRnpRjca09oCHTNUCaHXCbmAcszcDaUx6yMIXk/hSy15GmINkM8ooz0swIUSdQkZeLOywyGFmYEyv2nWvOnWmazpPnBwcev+MBnLtk31UZnpBuekCjOJhG9+00OiDJWh7f5KBZFzLmumUzcy5e1jKWce/omPcH3XHf8wZHp8cjrz86HR93Pe/0qDc4NmaZbXaLbdo6jFLJreWFhluf4zwfi8tmrLGolVigbZVCVJ6Z0n1T8LE2G02lZNREyPQiQhdkfRf4MRiWgKvIVxyWJJHrIzmjXQ85IQ20Lkip0QyBM5YBJ/i1Ja56JgfYeaXb2S0vZYiiGELz1qat50l7nkOBSIU4pOqdofiUR9gW1XHFnuDzx9oQtNQ3B/094vbQ9Gv2RvLBK3wxv0HkgzRU6sUHJDS6CMqs7HT0hHYvEaKSuPET3agDSgV/SJs55Ce+XIH0Zb4qeVrIiSr+FzoC/CIammlW0raenwOqOeWBIzhDZqS5zrVRlywKNX/wONrCsa6Zm2STRSqAOWdT/pjb3QKbABuOAdTDUl2BN62tpfTFQtm1spfMPrTO4GFD+762XKt0V2xp1MAUdkj54+Vva+fPuPiG+07bqDlbQvkGC/O6ri4126zlyxieOgcNemjXVHvbslAbtJJl2cIoHY74OIrtWmVvFy5ZO/eMFlZlrHia3V/5RW/gJAYlkQoRlTjiPOZtD7ElPJVOT/BoWIQoy5J6GvifMrn04qXDU3f/WU7ec6OZLoGyub8vQ6z56PjEOzrsnXZGvUHv+HTEjsaDwXGvO+pz1ncHVblR1syl8hqg52AEinmC0WQAj6GmCkYZAJ0QzgJRgIGJCu0SbICMAV/wOqD+6VYwcE17atA6ejSi+E/QpFelCHAW7Pf642qyYN5hA1mAhUPMeRR5y3UtErr5/D0YTbDLeqPJm6Xzlt/T67/A65WQYVVy96USt9OUudNMd8yGsMGtrC2NuNAQIonWSSvnkk1Ak4PtFJpsnNL9nxCw1NwkUEcxSb1Dlg6l69RszCJLrsiLkPuCxqz7qVSSPQGEA7BVjMBARJXRD6GqMOaA5dwR5x4lJcm+3t0DaYOvH5GvEsKTYY4YKQ3hQwgxAJk7r5YeYHz/Jw/1pJnUTjuW/lw2G3phMsTiO8IuPHSNpYlevr129NcceG3fAQEa1QM4o7HCFRSkBY1ufr9xYu4CRLJYW1pwL5pBnRaoXcYCn/BV70MyatfPPTvhQ4X8OkyS6N8bvfxiynw8NvPwbwAEpsIJQVZX3fVgINhNSaZyTDl5yHCC4Lle/BhN5FRsK7MP/+23G+fN++sb5+27G1AEqFAV96iETxyBBFlhQG+MaOh1DHVTq6Yz9uMkrXBtApN5AnbYOLEAJPhbNA3zy3hUMmZXj2MSszC1UPPhJGtvVTrvTN9BLrxeYz1PSw6C3hWdomdI+gtIZFk5fAdbmbLjq92x48Nxx+0OWI8Nut5h56jvef1Od9Qbn/ROx53Beu7YbArmUIDVLoqS/LbV4yjHKbSmCo5xXjlaQE/zvAxnsR6DeJsjNjGQ3+AqzBaNAuF4aCzIZxXZRHzg8HlvpRLpMEost1nJ5SRryzgayQMwYOkTWWvMJ+3O8bpjhsLX9awMS2M3crKz+TzgCUdf8JrsDIcC2MjGFXydq9CdrRw02ITl9yCIrT9Yddn8JP0RTD7bsvWYjDxS/DasVYWFptIeW3ae4u+SKwlXe9YOXaNgL5TuUcdbxMr3iPE7em3AJ8L3/gRK9wGEP7w6jqOZ80QKGU8cgHHOvUzoh2nsT8DxxyTe/wyE9/zAlE7qh86NdPLkQBxLAN/yu2gSw+8Zhb4NXbc1Vj+ThYKUJ9CY1MsWIZXG0KoS+qSFDuuejLnX6/S51+8M+u6IdbqH7LTPvO5R92jctUKBRBSA2okbjdlSU1TvipwPsscAQm0GeSnuRSL1TSzVVTuTS4Cn9W1eGyjVg2+e9PjRAJSaw6PjweFoNBp13VO3d9zpjsYn3aPR3ufCAuXPdi1doA3HM6o4j00cR97xuDc+HB+Out6Adfhp56Q79tzTE2/Q74297nrEYWCFVX6OOJ8NRJSREYKw0QG/2QJNFPbkc37U5eTlLbsB7a4pLa+6MZa7xt9LaBliFWU0u5b+vf5iGm6mz9VOzivp2/QnoTzmfiLcf5v6NQueyyKR0SCfJA69ImvYlBFBTJaE7Cqpv11shB9zDaeXFNec0xI0J7DgiNmeWcThr0yTea28qZn29vbzEtgKA8leBpHpPhpSEOeQ5YItdeiZRk9NYyflQHaTu/vj5zxbwcNmU71ARts1DbSY8AJlAoxgOxboTMVWj8OkMrHHaPyTyD7ae4ph0ZlIi8e2uA32AnuSi8ewip0AMkv2VgqRKMS+Gkhi1VigHYF8SQL5Ju/Vr0esq9oX32hx8qvYGB8lryaXIFqTaVkMY/B0A26W3JTV2YFqCq09L3IXoLzSXbGIA61V5s5UwbCGZySTNrOAeYTlmgx9lGJucPTZV0uxjBjr+q8Fv6DJl/DBlDwfeaidrWRbko02Mcv11jLLVZSCw5HBs3ryg69gMRucSp7Yur0aO2s+mKTChEkvlMyYj+WaMZo3qyaQw3wpTeEVxGxDPBmLqfgk4bXQ645MGE+oqCNaZA9E5UaR4ZDowLs65k9zphBlGQ7dKE6GVPuiLo5SvO68eHd1LUpl1ALulY6ihpAn4651y3uFA1HAHJmp76+LGQvbQFtYJkOvSaivY2McAr18Nq8KQRCDWMS+wSZ99Vp+cxrNuCpagwnOFp83rYV5FOhcG0JPK4MNDfW2oA9Ek6hxOtQU7O3RJFp5EgfYal6ZJCaNfgLByGBQJcwiZbSA6USx/wdYQlEymbGl43E3gNKA0pgKpwXyUM6hqAsWzpIlWJMI7B2cgVHWuaWP3orqqvSl22jOQ9+7bTm30XgM3d5SkTz5pxDYbrUSO3IW654EKVaR/7HiDAjjeuV+4RLhDZZQHaE5FPtzl1KSktfo6nsoOqqMzEnSIWzzAnDIPD+GOKlF7NuwEWjbpraObAsoxNvkKQfUf9Wyrjrk3DAzEIPiGd941ACeAab96nELRMD1WEGhOZZCNZ9AtQLEHxN5IOWkMfJNLA5WUsIbad95EQVR2Pa4zEwTDVVNSXEV7zsvo9T8moyfyeIHsxpdgllfXogGPzmJD2snxOF0qXckU+khgyiN3CjIDnvhTNNBJw5ATT2PgAViPovuYCiLNIJcJcLEBVgQLIh1q/FW0U1+iW83ZQ4YqFBBDBQEy0MPzz+aV4Yznk4jK00yRxg1XeGHkhU4UMrjGRrfRI2rDXhQGlVVcMzVo1xVK81NPa8zZ9d9Loxs5QUtdQB9C4QUZhAGM4SUexlBkBMHN3XL9w4NIUVWVW1ZMoyjFAdeVSjTnNEvRo65xY7owqEuiGjgCTCFJYf7lIeOxwOen2A1KHsJ+mIeR7Nok+WVHQAVU7VdB6rFk89yvUU/ancO290+OPVXWnSS89efCkZJiE6+LLlkK1Ye+a/q2eqS+pxqGOtFp3GLULWhRzY+g01THHPGAK26qDbtjwblb5jVxHgUHXCn7O2UvZ2yt1P2dsreTtnbKXs7Ze+HUvY+m43czguUqRwSofaMUpdM8EN63dOgV0USVq6/K/HaivqjEO2MsqEIVNYv5SI7Kh1zdUxr99wEo1ErDDQdenwXMXJqTv4i4fvOrbygswSrW3hPzv8nOBfjmCdTorRbvMBHEG/qBgs8a+IyDWoDElV4UOlzuGjaF4w1DfXzZdWDjRentjoiiBjk/9Pds4gxEK4gp7LuqOf2vQE/HB+Z/l3h9MmXXLSaTPmCqSUR+boNlVjsq3QH+t5Q/hO3pmEz5Tt2M0SzgzBcmEGY8Y08J7gmI8WuZEJ98bSCZ59WvMpGhJAa/F5SDL3WEGE9buNmtunldsjv2/KpSddPeJj4qX+XgTuuAdxse1MaJ5iPcHPoVf2gLFCZTzVHtey8KUlUW9whyNSaJSQEXKVW4Z0RS9A6Ymhpe3jI0qBfn4/pwH5Pjyqu5J2JY2fi2Jk4diaOnYljZ+LYmTh2Jo4fy8RR7ze7JMdk2dWHSaHC/WX2WhKIyy09QC1dUuxPjsdnEaFcRM6t6OVWlldIFnPA/RbkJl5UYNzMCaOwzWfzdCnHIgCJo0kEPKUl0FW4J5+/v7pwplGS0jXEUifg4KQE8CPoK0/wDb5A6fkruAKzFJF6V3y56kM2RIHjAuAkcRTkMWIgkNsCxqoqb0rWlij1uShyYLVY9evgh8N5HE1iodLIxRApVK3Cc7kh4P5lPiQdgMoDeIfloZ4/ADKLhnVD4gceDQnnTDwljRAWB4gvju400Ju85GU5Iw0LJ7eFuMHJlMf/Lt+ttArCh34tBF6USAJTEqs01ceLyyWkJ7Iu7HSanU6z02l2Os1Op9npNDudZqfT/IA6zS5Gdxeju4vR3cXofskY3ZaNHzLvg3QkkjPiB2Kiqky+FScBgxugGCX3QDplSglczX+5ku9yjVjjqpIOYel2JnBvhd4N2rwGJFMdrVDl+mUpn0Sm8lovxBMUxxAdCNQAcccL2Jj3F42IMXDNDlnoDUd+EEgk6wofLM0tYCMeiGAE+SEld4DYhAeTANjCCYgReBTh36sFa+gyQGUxwUZF2MLqpYp5iC9VSYUUheLxOFjCbBQQlJj9059B9aI/nhEJEFi5SKFWaFmEJ6TTC5AK2IUW8xy25koyUzWmOZjvjCj+vqfDZ9OAUPlUph290mZjnMJ20XVsgXVka4mtU8DmsG1eBbhSQBCQIGCIEUWgcKSTw3WeVcWqAEstR+xkRBgEzmXs3/kBn/DEaTvXizmPnTMP4BuSNAb8b0OGf5GqzWpTQViwR9qoro6oLMI2gIKwN54RVlBYPtmcpGf1igFUe+toc0WUv0cAnoMwGFNd6bM0jf3RIs0XUZKIgtXjUvPVEJeRIQP+ZsS84YgFLHR5PGRAOFnIY13Ng73P9tfOmSOfISIrDJn2rASZaCyUqBfjs6xeW+gXRIasl4qPaN2WJpAVJfK1OnlsBPYYO6oAvqu2ec1ZCOEA+qmYBY8CswQM3QUsBJGCh147GrcDf8wdtJODEg4yVotuYQmLaikFI6YZEpMB/hCvfcGi8f6zXqy6+5Tuv3IhMcuu6wTubCdM3T1RJRSETB7X6js19YxzVa5XYimvI+Y5P4sTa6ViVANZFtlwbTztZTZMqrFhAD0SUkHp1Vww7LYu+4oZfDmM1se/sdaRleo21UQLhtD1x0WQraOTl0nVzn470LvbwdzNbvmt3MXEZvawfJHQSWx3pDyS8YiK7qz8+Tds4rvOW57eR/En500U+mlErLDMcmzgAEMWLFPftdoWUfHic2tPqqUrNXKhbtFwvognVhpE1tCz0xlyDYbkyF+xYTBa8f1osuIXirqbfcsksUJkzRrcs/FqDaDI1jDhKVgFVpwWNF2pSb48SY4MK2uVaJ8xvCNC4EuHQPBo5QNxoyDgrp3u/CdIdBiCvG0zUv11U5pEExBipfJyGUfewk0zFUa42P2kLKCPOFT6LsB4l+D7VY3r4TxgKYjUUOTSR4vajLlT8LMFnMUhNQN2AY+IugDldA7m1EUMAmxrL14EnF5QFlkceSsXvgOuO+iDx9EwjRcYxK/IGh8hs2jthcS7h8ITRUkZng+olKLkGYwSyYKGR3wTfp3zGPWD0OVUtbNkJ2ztRUAplSkPBgXvktwKFy9NK2rsJBkmHI6QWdXSiRUIlceoVlGTim3NGycZpYrYkHTJiGJWBkpi0FtzRRXTdKv0pKvMcBhpcIxlIT4RwPwWKWI1IkCrqTyi+Q0hZBSecG/C9+Pe/mjhfuJpOQPNqOR8bpBjsxNeQZooLB274+PemI17vc7JoMvYyB17YzY66bqDvjsYH+2VCIx2Wsg/P1NvJIFlm9NgaG3lRmc4gTi0U6836J8cu0f85HAw4L2RO+j0BqzTPz3t9vun44ahaXqjH06eS+GMAucuoyhIHmXUXo91Tzo91z1l/QHvd04Oe+OTUb9/cnQ66o37bnnUwltpP+zf8IZdc9xGZkxy82hw7PWOT47YYX/gdk5Yd3w64PxkfDo+PD3lTev9WxR/4nHi/P1X5zqNYohz22R9q8c5Ph53uMcOj06Px4PjQ/e0czI44idQgHR0cnTURLKGcT7SgnbZcdftn552+oejwelhh3VHXndwdDQa8cF40OtYDvQaudxm1Fo9SN45OfLYMe91j08Hp13vtMv54bh/OOq7rNftsBUHueJSlpwuNjmS5YpP5vqsS81iU29jGveOjnl/0B33PW9wdHo88vqj0/Fx1/NOj3qD47GN2anKb8yCe7ZMwMPq5XIdZWVXLE9S1P2RVSvLiIVkrIpwNpaIoDe/tfJadlDo6mVj3XQxtfq66bmK6YJM0JxalBSI415lnxTbpta9bRZupKO0sUrcSz6LZFHbgtOqUwNLjeZqGCaPh1VOaL/kxpGBVhSKpbrQSvHuO68QKuBDiD7Odu4leKFF0qKIVMgFlGjnzLmkkr0fQpQib/Xhwlpgiocs6wsrDBXxsjgVbeR+8iFchJYlfC1QC4ql92zhx4szMC85PNEj2uoWulja+EOov1hV57gh2qPMZjEsQ2Ib2M5WhGmaq5M3M6Jm63++NFTtnN7ye3n+fpGGx4ooE6ObRFhAS1+0K/Hepk9VhAXQw3Jh7cLHCqvqGzy/Ej/jEtqmsU9l7C38t1YWK9f3YqxBgVbLCCwGKzbL24ag+T/3ur3+vvz/zkEPjlfvqHP0HAo7PH9+0O/Bysiv5V/vdkoNRKvBCQVh6AumQAC+IhkSNID3bZBiAa+gity+epW6/MA2jhqwYV9rRBFUjtIUQ5D5s/dQZyuHBHziS2MEEqaaGJ7Y+UtXWcoaqwQfHZ94R4e9086oN+iBunQ0HgyOe91Rn7O+O7Bc5S9B9WbO63sZ3zUSeq1KII9vozO38OKjuXJLY6/z+BkLKm7JjVvLC9bxyFbvyrr+2EYOoXtZixuY+Vi/uQqWFaUrc1pR4wixOFTDADU21mC43O/1Rl2PH467bocPgDecHo9GXX561B91jtigv/d87y+woAYNmIXLd2PcNWtVDkXqIW39UHHMdTsIeQJhU5+L/MH4VrnAFcNjQI+z9dVduOULgqlYqcu8L7fi9/pIrL239HHNJq++VDgmtVMU3VdNUeRE0VubzrSQmEldaxMQXwn8T9z5sPeXD3uGwCE1l6JXcChok9YuO+EEBYeaO1NHQr27g0x7RE+iRQV3CpNYx7inSABqZAVcdVaz+/Smk7lm/vR7v9oubb5JRfl2t/J1g6TVWnPd9ZPdkBYjz02xbl7KAidcQC1HIUYsgjTLWBaaNybioSkrWwpqpK9EF1QgUQHRDDeCgAci5n8OPnRUDDQZBj7e+AlwXBg/87Y0D0gIkCgLFt33Opi9mrJgWLtgsvsslwkmBfHQLFw6CWexO3XmLGYznvK44ZOdjgqNwXrXjXtZG639MvtLpl08yZVVbcjsybIn/Dsuq7IKbQIk95hrZmorO6KdlgCFTa0zXArKXCTymOySlpoSRGwmtWLKTF6UKn6gLMqVFF1hZ9TnnR/ER42CVi3liuu3ShHXfr6I6+npaa6I66hcxLXSwJzVs63NHFJqjV6HFzOIiFMRmFSh4ntd7pAlLayVLGQq0LxG1rkWYKr3qEnDfnjnkz00gxL+s9+5X0/ShXAesSXrSbtyh/nDHJDNjAV5f1O+MfwQQaQ5EHgHNbJdYNrr1ZIdyATuNWry5hIKS0N+p4XVWrDpF8oa0XIuQnd/BW+oKTPR5JI1Fxr3E+d9kgsOqGEg/w8GJD6PKQxDH+DRNthGFW7bNUG0oS3YTzRe2JgZjDAqWhym9lOG0hZzYBu8EkGEhujPhnlwaRp2Rbq3EYZaQfoBphmQ8/WLizdSxmz2OtTnqzleXgZKy2jYNOAGeSHf5M5nws/d2+84P3MW85icsXvFEuHvTdgnZ6Hz15ubyzbzPEDBQ6kR8FAQCgWzw6LqkTq5/o2JXRWFsSHSk4pTmDtuPpA06eKE57E/Y6aQ4SyJzB/nggREi8atqOD3cKHMufsIayus5m7F2hZBZ54fHNzf3+/HY7cNTqAo3o/iyQHcIwfx2D06PuzsqXBMC2B2MQh4v/7b6MEf4TaQH794x2BTo6yo2cPxoBVI+5qOr37AR4vg03DMWbowVTx/oQdbI/vEbqGRltXVfI5n7OGdet28WjP24M8WM01H1dLGEAADvyoBpbJP+mHKJ3ldC7S7GXu4ZEvINrr2/6jYIfnNOb3oJP4fCNwwWgJZYxGNFb+q+F21MFRYPPLnKOTTZoibssQhP9kqrHNpEYrk8TMM5ZXYfJ0qUHbJyZuF6wla40sODynI0Hl69eqFc3w0GADYJNILuP6f7TtXEsYEeFMQOIPff8cYoMPff9eQLRFXlvoVaFPJ/ofQ4oZImW9My53m8S+EFCbujJFM08VJ1J/HixChx2hwghKeI7QB+mu1KjQUH4A3e52AWYdVsYjD5z5Px8/RqpA8h+14zub+cylFPu/td56fw6hRnoTnN0YWdEYDpgUSm/WJL+8BWrVyr4pBSopnig7cKCR3QOI85fuTfeeWis+EiJcGDbzFPMB7QQgtz3K7aFjerIO9HABD+bgC65fgtVCRxUEEKeqyfgsHnU7Z9CY2Sn2zeDpwkbOCLPr5qGSYV1wsHo5M+FvkAT1YhJk8hJ8Q/Vjg+zbzFaBm0R/mO9ixFFPudPax4pKYeMXYD1Ier3yHUDPEwVntIrkS5j3LW4S+UzIU1rPybseSmWez2NaSt/Q5ltafJmPahsqgH2wIoiw5xpXbL5akKvCHhBmCMFsoOkCyib5iE4N94BJvqLYWc5JlkvKZfBsAKknSZ06m3ZUyjVoOMOU2ol7xB9BOkCqIXTgzFrIJBxH4mYMXsLtI0miWG9YYokdfXL1/+cxChfCTecCWb81hu8VbAlGSpFH8l+bIm5xdqQqTkD+kPA5ZcFEfQ5X7LPA2wkhSqpMKF0VUW4offHrhXT6rH6Lvzdu4bu3B4VFVOplhZO+NVcXUAFsZfNdoqW33vnOtEQWJN/OYj/0H7jm3WQhC+67b/l8ZaWCfN2zyv29/kjsuOgAwLea8f3/xsp2ky4A3my3zH+n0+rzbORwPuMvHJ8w7dVm/C5niPa/j9g/71nFmqILXxWaIV6QqSuQjrtRovgjQCQKLKCb49HLKEu70nsmpRqHjh55/53sLFji/nN9k6N6EXizOCJE6AsYDnILDnFt0L906T/GYpGzyDEUsiVHn3IpjcOs8xQTHZ3XWD+MBMvNb8ZDOjehazp8OKw25fsNg0P9HB7vWo+cMSGNijoaId/tvNpJFY66dWpjy+NXwLT5TgifUghqbQ+Yk5x9ik0eSP0Wfz90o5ih/UjRsOY9HiVTozNBZb/EmU/G0hWmUy2cWBSx84IwijwD+tIzVrGPC8L7VBnBLmN8CopuqSMAJ0X6d+CEFF9y+eHXrPIXLMb4TJ1a/6JJnVorJpveOc3X+H+8vrs5f7jtv5CCTlMWpcZDEYrGLjBe36TL1nDs/ToGlmMZvhr+/8C7FHn2fd1qBMhtJ0RGR/LL6W5kym6pwTooRpmQ/0D4hRS9KusmRlDKgrXhVardJJiBlvZXuzYaNX/nmNCzkRSnmVVtEuCqb7ArgD1TRPsq8ADPNL2NiVGNRQrU4n1d6tOW6riBtZslihnZSdPFD+0seXxqjF7AqpR7BIGajw71Sin6jnnL4pQwO+p6Q3QE40UXo8QfzBLttAkP34RV5O4/9mLCfFkGqZpnwBrtaV8Zq1Gp+aUWEy4ylADZB1p5/LXi8bFrSykstN4iWRkFmjoJ+baP5QLuxqyPW4bHHUlbiI806j6Qps2EI6c+UadBsmv5FBSyXYhvK838jJJLCtOewIUMS0YYVUt6ZlHSpXIeQdxdEUKL7y7ObF39dyXhgI1KKNRGfBxwzTwP831CkbKg0rq3dJSyS84ZG8SuFjlWsZDRfQVoSdFRYO7TMFu0DJuZ6aMlc64z9MtyjuH+42PN5fX3uFRiyXB3Rf1F6j+bQv4d+UQYOXaXhKeH9n/+9ihj/+eOXYsZIHO9q5W9tA4rMSbSWko7zlBKfn9UQmFxCU6YKheEWCYporSj2XJOVK3FumYc1dehUyZI6MZ8HzOW3WEFD7Aa8pYvx4tVM/Ly1ocfIYBmDY58NGLD9CdmnwcPu5Zzr+BfNAv+BE6is2YN0Vpmq5sBzJ2XxhCuHuZ9kY9yHsIVsYWDIs8jzx8uc1otBAmihw/pGfugGCzCVS0MofwCzXyLmTF/LrPyij5ZDxn3x5z+JDfN/OR9Q171hkw97H2+bpMnsQBkrAlRzY3z0NHmm1AdtDV5lpkLmeQdiyTU+0kJjpixTY7hHEuokrx3CDxpRiSIJ0JnMZMAuaMo6H1lJ0c9SZdbnaLmb83OBVUISTYHBlLhENK8QWOjSeadzzMIIxGqvcOFQi6J+7jy9fH/z1Y2334Ka67yTtnEX0NAogoI/+ElaoLnNDLyV1ksRNzKHAitis9D4Lg8OSOfZGCHCg4rNoO8tFIYU0Opyo9z83s5Tef5mLSQ3gXFEmEKd2xXsV2vXYNqSjazZJnElmFu1UUJqnSv4fVhe00TjtXLDQ/0tTtV35M0hSOcnNMRTRGLORC3d9VTuK419fqcafe0TvnPP/HncM9uwmP8gnMXO+u5cS5OVxla2rFNCoO2PoFLaKJNS+tdEWwrUVoFbHzektipNcLv09tj6JtBEQd1cX9GsJKnt6oSiprnSUP3EcSnXLVhmcR8/kWIrtVnUbalupAjCVuljFE01WkCxuzsogekQjhlobqk7hRLmLOFtP1Q1uoJlkxyY0d9XUk8xZ4GNIKakpTzSqnQ37uAiYLGQNx8cJrtumpk4RlvXI7P9VGl9OEsBepZMo0Xg4eBlQj7mm6sVAXHkgFTLOfPjJKed4nLpamm5TxstNTfE/PhEvHXI72VLMl6qPSossA72nWNMumJadHn/d4mTZN7wKtVTBj2tqY3W6aEKO8Mcdy3E3ivNAF6+frJwpqNn+w4lUo4AKSiDv47GMtxTtkWDCLCuFt2eFGDhpzmAIWKIdnGrNZkNN0Wr/JOkKAlrDeqlLbyBz7IUMymu2321FG2vpP2YB5Q6KkLuwd0Dsfj1ozlA5l9XSq84AvRvx85CirvNs91bVRzM0ZQSC6vzLHJDtEiskIOiD9tNWyRRHOCyUkOoMd0QR2MlPuaHc/6QwhVjTqFSoU1Y3trkL4IdotFx1dHG0hb9MFQ9Fg0Ajyda64yjUcIWCRjqRKkdLjI05dPDbivZ2YbecSPTMznJB1/YQZ7n2SYHebU7tveNeLhXc0/XzWdz93KOnGrczAa+VtY6DF5mIyE1C9RB5FZI78Dg3l9dlBjIiBMQEVmj7MqAA3KVBmQF1cAlANBBky3hAJbl4K53oM8wOZAMcQO3efHH+rnkuEzJA5zf3pIXveoWEaLPNXHjGqHnGIUesF2R/MgyrESQbguCD84uk34cGYZjxUOyrk3jLekBBGcmDI/mwQkJa0s3DPSOG9AojlGDLcphVfKPEHS041Ka8sY3/0rSkViqZrGoaolWFZAe+Yq/Fne03eWuUXCRDYuOymeTyMqYJK0oHY3HmEmlauOK3Gg6v8Zj23jeXBZGoe+yAENGKg6dhJUA+lINSIPMAIEy1dHetIT1xRJ+/sBcg3pRyBdWOHTZmoBRBaweyuZhkw3ZVNS05sCqnHHDXDMCmy2C1Mf1rK3M6hf6gtlg0zaurFVmJ3wsZXZVO10/dhezJIVCRAkV39Yq4OTsAdmYRG1V6blA/6z4o/6EwvLJKg/SuqTM8q3cY3+Gk8Ca81gWDN/5WMs61AifJBbsQqZe0p095jEPxVVujCTTNqF81ehLWr74VElLzHdS3/JWOxQZl1mNfGQ7O9KRYlTdVxBxn+l8CIwYmgFDcAGwWepOQqmTUGFPLTEFSKj0/PL9Tcu5fHd904LHZLEtZ1AbNtbjYwbgLJoFE+toYMWuOxSks1ekgwJl9cXorEbUkNIOk8C6yWLU1iQLVYhAIw8Qe/zEuRVCSq2JfS2Rw2zAKp4GlM2bAzNL5dfUDxnFeNz1ZyyAgSu9BIJcbgglRlE3laqCSePaavm5NZQ1je5zJSdEfWXIDx9HMbEo2U/eiEokVz+9kGprycmJP8k0tNfamwTRiAXlK12vxpFn5EWILdVKv8Jy7Fg7YLk1MUsFjiJHk3yQGTZMQoJ6KmWBYg1oVhmyWxkPXMWA9OTh7Lv1vKfBkqVJrsWZmIpHm4QwfUMq1vc8sw2V13czO0pBg/oWLChiWXamk01NJ2Jvq20murZjZSwpUMsPZSa5FnS4mnb5xcwo19mpMG1y2XJCd9NQ3k2ilqh5jCp86lrcaJfyRstVIDUoaoc5pxLJ5CoRV4d9SPQseeFETvYhJjERwVY+hTAs0qgtv4oxWL4AUcBTIjyaNuaYHBwQoQFtzpzMGGGwKwB1Y91NDokIVMkpCyf8kiUJQJZYd6P1sD2srqJUo4wcbhQmixm2m/Jg3gTfZTqpqkpfUjyw40XoMewtSOTplf9ty+K4eFjbCU8X8wPk3imzqgleXCwKD7dvmUf9oPABd7rOl7+M1Yd2UB5iAiWhyyqKrQCc88OuvIpoGQTtq2UtkbP4rtivVsXRLF1fRV4k5qFzOaw2WxcPmo/JqoIBESEJJgiQrp3tV4QYlEfyMwmSwkghdHCZogfDf5I4LI9PTBA9+841xzjTW1R6MQXC4yrwUrVvUbqW6NKPdSxZxJlCXa+EI1sJQGoKO6kNXC1BIyTT6D5UxjUY477zigVB4gBoCsyDkDtBxqfbMdYQpsaU/M0b1Oe/sZA71zM/nVZFugI+g8lIglq2jichoq0klB8UvXWwdZZPeSvHt7lqjIiqVHhbA0eui8s9C02Rr5jFt1L0/Q1csYIOEydJoxiMRKGXWT8gRovCoVMez2MZ+6RF1DaG98Kw2mzkdnvmFMDWXnNlmmJ2eaHiNc5cFGbfBzhV8qCMonSaB+lJ2SRxnlZF/N5SVEsZcgearRtkuGK8rwkPY7UAaGIB5vhnDSFl42TO9cuT1Sb5FsBpv3SOL4nxJuBaab+1P9PQYpjFi2010hrG+ciB1rgUaAOTFueVqZD/C/IkhBgp7jZipELmrEVxxjfroXIswC8Kni01mZa8o4tihtTk8pu5MTQLCh5PwTD8TAC00IV064x9Hni62UlFO4oLqPLuEfmgNJEs2vQW1sEqNfRRxJQ3uWHgYiDboRXJaQbbFTr0M08EmCyoDwJnFDJJGkEgH15McF2QfMEfALnRx4hmnraccU4+QfyGShnlkQSTc/2kaN5JEqBuNLBhQSCw7kglO/Fki+LJjvF/74xf4/nirNUy/zo0pPJpMDox9KlCQZl4ubqMU4k93sCc5+jLgrNSteLV2ONVceUBG/Gg+CHdUzdehKggU+58y/mwB1rThz1gkx/2ptGMf9irP4zwfgP0XX5ZKT14QzoqEg193UgVyI7LxNCEjFXE61sWZYIsWC1vfdhcRC/PoQKeCieymd8oN5VvBZxqIaX5L4ZJ1f9G3E4/ECZVfwueL6TOar9X6dauRAogStOFzCdAJzDRvCBYQdtjNvODGhGWngtE0YAB8iGb8Wf6BxvcQjWCppJgK74NwMLwuZaIQkVOFQTOzPc8WZ2q5eDCJqR6JIsxmFISBESYw1RjcNW3NGFZk7xXkJNL6vfEv+Nh9brhY7FsRNQrrht83QqiCklJBmDlKWgLACFCSwR8EJF1Kahd5FUquV5EKdGp+MmJBCA3DzwKYJI+t6+mBb4TA/gJLLjRzAdiaFHwnqiTqET7uQTy/K5M3H8qbfNiXLJH4MahJ8ZrOX66Uz936udO/axVP41SSSXMTWRWxfABwdu60WwE1WVFNDc9EQnUwj0iTihwaVnJHLecP6TNwsonvrSjvGjOh/Dy55boqtabkx8n6sV1g1uDb0Tz7AAU9wXGmQ3zo77cQzHhIq+XcMKF9Z7HvC3ZiVLikFtjcnRGnE+xDrysxnnx0uGpu/8sDwsTzfQACAhgkvcXHx2feEeHvdPOqDfoHZ+O2NF4MDjudUd9zvruwMYXY4jsL61UJa2J5P9Yq+4SLjWnCgSJQ2w9gjkw1PZQGgx8YJgTcKqmopLjlmmO+iDSM2zzR8M0H3eP/zMK+cobDEUW93v9cfUuM+9wk12miuW7Oqrr1S7PVzxdo+ApLb/AdFN15MHHM5xHIAYKS4e4GpR9Bb1Al/KNpoOz2y0xSFzm/OpuvG2gWVhsXcUbu61bYetgqduwfu1tbB+WkxySYJ/5cDUOKHZOmPypCugL0gOUqWi3f1b7l1trPAEJd2NeLva+7v6ZNu6aYrV2G7eljdtos7Qa2Ds5o7gL+UXYYJkzYErCckyMB6MgRmRl6AjxfHc27M5GcbE32bg4Cnby98o7AKu2yapjGem6u1+dFMTYoBdViq8IxRIhwVSSend0rDaOFh4FgQzJeqNNbOZzu51af6fAP7zJHgkf2I691Vz7xUUY8dRkmgdXNcEy4AtkY1NuDIxEiFPf9efkjfPDOntpwXYOPchSyeOA5X0SYIsaBpCUNWQ4/SEMwIQMUvLQojErtrLeyVelO6o8yhfCR5gP+Wnw5tZY8Fngu7xgwi/NAB3HQ1uHi/b259belCXD0SIBpIVkCKtYCxhwL4gOt3PKyKIqmzvU3EBzEv+BYC8MM4BRcPJG+QlfcxxZBxuOZB5Haw5hHkcbfNuUMHFRqpbaHBNw5B2Pe+PD8eGo6w1Yh592Trpjzz098Qb93tjrmmgIYjasSSh7GTwnmva0UeiT3hGBRy6SOQ+9RnSU/D6MOA+drOk6G5HygM+ngFdhcwmpl6HlfTQcMzeN4mKGLQ/B4G2VEtvcSe2Xgggqem/2IdHH59beH/7cjTyrlZCvFu9iTGAg3lYG8LK5p5MIsr5DDiNtvptIEvaGxmx9f8aTlM3myvMqo/vl8bq+fudkH6th1oDC0k4JhiU7e71O77Dd6bY73Ztu73mv+7zT+0/TeaPQAC+aMT8s+5/1HgslljU6aoYX8u1SsPX11QNDwZmNJZVsFxMjv6jJY64nOdmHY+7FbDYfBiycLESEpIVXpNwOwnd5DLW0FMjDamumtx764Tgi/235xQzIrVGlQ6Q5Fvh/UJgVAIYnSWRayz+voEprbaOMa6+bxNzVnfU5nlTy1q/M1mrjseEMvZBv6t5bWbZFGpVz72lB0y0L0XY2i8Jh9rQtnrb9cux1buA7Ov4yym6R4jYluDLPar5ZLQUBL0zy3ZNYgMHe6aIi7pqeyWtDb+5A8yxAMvdoHkduRWBUdomAKJhHWmP3zE/pp+zhmPkBSoz0BcCxUmw8JxKWNdMniaPeELHjtSP6t67T7fXb4v8hFmbGHl7zcALVPHqd1l64CIJ8Oam8vcNir0IKTrJTbOXLoBCDRBTJ6EUm/I+2PVU2xpi6uR/zZGjXlfa2tShDK1RgWUmyUBJMUwfZy1IpggLGlo1z7wMPgkqfvnVz/fUNMrmlYhZG6XDEx1Fs1yp7G3BhtCgBuzXPvN5IiRSdinlGVu6KfItCHzK9a5VesE2O5djNQ7yPqSI4L0RdWGEd6H3VnlINVvg+vZ8xHjrzkbfUL9gb+FUFBSMQcawF6Vtc+BovMeIvqv38WLyfcwOrTSPDQRrElWpdx+seHx4P+idHJ4eD0fj4hB0ddwadEe+w4+POqJPnk/2eHZyDgUgrq5GR9dCRL2aAFCIqF/vZJMoTe16KSJuSR5SFnqoAQAEkJcoyXp70TNUSwoVH50XLoUOtpU0h7HACcctUnNgnb9GH8FanQExikLl/DhMTp+QOEVBJah/8ngj3E6ATfwhjUHI8h41TFJf8REAFgLDEPK8JDc8ds9QSqKN0bMuic06qKO5eXdkqJSrIHzw/IdVbXmSesSgX/JRAbHrAk6Sd8jhmoOMqLDgFFY2ArQtUrkXOSf5oZZyjvN+oaA8cd8pi5qaALFPe+tzuOrc6EcHmfgjLu3uRgpEecgMILPWL7Dfrjnr5gz1o7c38UPtrNVpA8W2Zxb0JP0/CJ4DLtvPwWHl4vo6stonMsu5Nb7JWimdrmStL/uNyvB6dUkmgLTqhhePbXDdgJ+HvJPydhP/dSvgaZkRTQxmHIjmMjZepyWGW3kdt6sTJdwIigOinkIYoEj+ycuNYpxcERbif8r0Yr6ZmF6iNV2rTySm8qtHSAXuNrLghoJbLUQtMAmtG4/WnRW6RNvVUiBRvvI2rFZczWY5UV1lyyPMokdFnN1FcRCSaSFQgNaZs+M6pjeLSe08OoTe0hvn0kOrFgfg5i5Wx4z5aOkSjiVt9uJAEDz8X9MGtLKwKFKzSYc7ER6BsI6kzfliRKm5UaKiMcU6lUT9J62cJwNEsZJtxal/yFJKz9QgFnQqF6pztQXM6nQqvaRQhJLrNJkEwdjRk6yJZP5TiS0UPlMKg8mdYc9XXHGGZF4rnIn+OKaQOTRqZ5ap2v81Vht5qUAXvFa5pPbm/WTpv+T29/gtFPrdq2Oel4pppyrCGt6DW7Hs1R9vEigz9LzUjWP3ox72jY94fdMd9zxscnR6PvP7odHzc9bzTo97geAyTYUpfbCIF8SYsQNHSZCVsFRoNfS/RawWs0FW+CXVk0ruYVK/KAy5/12SZVASr9l+7a7TnQhHLdlnF4VKxoXnxgqqINyiE/0VhGkcBhUBKJI1o7Lzi3tXZm0tHttRz/B1vgSXVwHkbRBM/rNXphYRRlDg2NjllJ9Z0/9AK6UKGMlJa1LfbKB5nYTiHKwSPDNqdfn0wToU1yToWr5opWSQ+WyXxyjOjXzIFxbNgzAbrIKxGYZBoPZItayNRt76ezQy+fi3rGLzdCB7rDjDxewNU0eo821KvJn9Cnjq2wu63w+vzbBfSHaNYBHk6arFWZuOli0N4rTRekz8jH0t8rtZ1pX23OtxGe+nRYm208ZL8XB6rEMp04mXa8XgMYdvEHc/yNShsJZ7B+HDccbsD1mODrnfYOep7Xr/THfXGJ73TcacME9IQRvIVVCUDQRrITSjOHupKJivGS/FErWBI7BhOCqGwagRXUjsbLl9mAEr5TVZQFB9U/pqceFLJkpsviyOI3Owe3nQ7z/ud551OdSTsjvrWp741tfKibejLKObG0KkM+bB+hc4gG8a0JcZSEwk3xkpW9n7sHnqMHx4e9vr9k5PjAT/sHPbHvcP+wOsdHx2zxrQJ49wUGKYd/qWJs6zNa5owfv2cQMugiqWfEPi/OE5vMjZTvvTExfMl7j4ZNQGliZVJYXMR6ztQizfWiPMrWYtwlvF7raZ4iXWtbODUdEujaJfkhikgi7bsoJZUto7LUSBQNdMsvucNR1bJhNrbWltxcq3ZrLFduT+jOvsydzWA2Oipq19PxqrnXIfs+KRz2DnqusdHzGPd0y73Okfj05NT1+17zC3HbOVjWy31cTEfSx9v9nYhQ61hJfRXs6W594MAKoNI4WjbC2KzAPlJQLoklGj2wwkYfMneu1ebE2TZtfkye6evS/NtlkGJtqCu1X5+yt1Ox27OyhNj40LBkSd1UeYyOTcfaY60YkHnBvEsCx3XHsYc2FVjmFjpIi8d2DLhypu+ptaAHv9VO52TN8f310fTF/Pff3XbL6Or8PLyH8P3L367nCxPGGeD35ZHn17ww5v81p108qFZxo1MoMgzQTNr/k8tkbA8bPEQ8ILnUZIioKbHwZ0ba0aswL9rKjoO0fSHNuH0M4jZGYrbrVZSkqrFKrKkRZWDdQJZxaDnflvGDrWzjLL2XW9rsW30obXC28pNbUPOAEPVDxdE7gSEYfcx8R+sBGHo5PPnDcPsVoyys0HZrYkjUwv2sXLLQYb+xvf6R1zyNmQILeKVQEIyHGmZP3Xc6fTVt8EIHjlxtEi5ErnfX13sff6IjPaCZOxug2JVv4XZED6u3E/12RXLD5z1o4HBPtrmC4+X+Dz+9ejbTxHE3/iJ22Ph8t0YCa2oBJbwzT9+98fT4wEA128fuOcb2JyyEU6t7X9//3cZ/sdCGqA441VEABmbTGbHgFsF4ejtVSM724DetOCeFRVkrZvLmrJ72eJeY6DZ+6vXtoRHPZVbI4xDEDHPIoBI70k1wlDV2GdhutpQVCOKXNUfjVjiu+ILK9FCQaVjIUZsqMiBKJbJJxjOEVKRC0DoRw3i4qVJbs/ppr2BoB6DJhA6OHoHoNbjpQMbJlJkQs7BNnCPLpUlVTqg2VHaO3RY60ShLiuKaRg9HqEqlqNqPxvrSyyjRUzjNg2gqv4xEqPZqE5+VawY84kv21RrBAuN7DuwIYsE9TWKHv7E+RyWAKv78RDqk4GlKaTKP6LMNZbZcqOYmsxYyCaID4YUU3ZKVJ2RxqhgUPdxA0Vzqpo+CQlVjHRnzfBpVX7QFIxjCJyMDWhhZ877q9dYR55D+RkmyQtT3aPYn/ihFXnh+ww6q9dKp2k6T54fHGiQMgdzlk4P0uggiCbR/ryCJErH95EPpKbPd45Hp4eHJ23P6xy1B6OR1z4c83H71O253aPR6Pi00ymf4LKNsUadphl5fgxlFmhRZSms4V3X0hBtLM7AHYyapMQ4re47foOsihBFPyJiA/vRvvPGD/3ZYvbceRvdO//m9JyZHy5SDvWJ2YP+5MiZRou4viRMpWe2i5g6vZtO73mPPLPlPa5YEQsjw6NSh8wy+u5X3J7Vy5pkzgWyhxfE7S9e7jvv58A+gOQxFzQhBkxl8DhC0mWFDJPFCA67KIG3SMcnWv4oNoSlwXqMThjFUP5LBkUeOE/HUXzPYs9JApZMn6nXYSWd9++bjjH4mQ/85GC2bNNdhfbN0ql9hMtotPZd1PoGLqM0krSaJLmQvQ0uo8aDLtJmrXjfN2xONHp6cMFLclIDKkGvx0/50ajtdnqj9qA39truoHPYPnL7PTY+HPMjvIPKYRm4oO+vXps5Fd79wJxCLU6fe5JZuUS8cx4Dc6GgHEDanGRgwX+9ubl0Lt9d3zhPZ4sg9QFd9QAjf+HAPJOQEHZCAX12Hxfc42Bqj5f7IU8PXj28X4yX9z8vo86sd9d/mP792n9/cmC1Kj+A6bX+jHznJvcNz8gaPozdoaiUsH+Ec6KbXUxkBc8tHMiaNqJ78g4PV3KU0ZCmPI6GRv3r/dUFEBC84AhbBUVahtX6spL0FrFvJJkyrby5SQfvbrzOqHN/yP7rwEalOYAx2aYqVJihvvDBzg3jE19WRBL8nS8t9l9KMWt+WvHnzDv6rfNpa6PaJ77UKqf8IGwDNq0iqgEIxiKe4Z3/0BmN3rKbk6sJP71cLB/e/xz/18XRH/EkTJZ/O/z3NWnJIgV5ZTOzOh3WGADmtSqL8nniaBx5YX6rRfaVFupzeTxfTXkz6m7OGzEcKvpMFa1dzj3SoEfL1JzPlnlfqM7nXlYXJDdbMtmxoPa2kS99azeOHNc652QO5bP1+vFf1z70jVHd2wgMLeGEQ0l5tLHMuVvMwduaNUGIyNJmIMTjCKzIfpo4YKqBsuiJqFgP23nbEqYHFKjB7gD25kRYHyY85HGWMkBvQp+fOGJ/3Pn8Pvv+vnOFdcYTgfX7HoIrAZ+QlsByNVaIXyydwi2tX7aCuHa0jH76pLSEOLAtLuCWPA6FNREC0SiIRrmYkL3/JVxaQTRCh9b/hnDGorNana2S+7p0lRdg134UuetHkbTS6WI2CgG6q+6SUm99a7eUGtg615TuBa9MhfN85oAAhPsnW6xl8+8OCjb//W6vb52AbnCkDxHw1bdTZ1aMX5CfKODx8TseX20UjyA7rugK4s9xF9brVbY1JgXLh6VDIFuPfUNa5A0ipaaOWM6lQ49HPHGmETHqe99DccRzptyfTFPH82cQ9AwV5JNptAg84Ps+FSSCMKV63SVxWcDbXnQfasHluR8hqpX59K87TLRy4wiy0uesIry8asYBS7+bmKmVqUE7Hz8Iu5YzIzorT0W4KCUd+jKEYO4/8EBXZhQovZrF8dEJxphCewwxtSaivJGpxopKRizNmHR6usJnMJ77R6XVH8+G08DoLYVwKW+AGC7AuFVcDIjP0SLV/aQtJ+YTFnuBqLNHL4qGLsHxPIpEXbyAysE9QRDdJxB9BQIVQbUrh29C5VAS/w9OqZaeP0YFM8XoKZclNsg64vpamU1CO6h1p3jKyj2IpgVde+VuxMNc9CPerWv1Ri2LxAyT1YYpP6CmX0nHKxo1vltRqVFKmi9Gge/arwSy/Z18uop8WjJiyPb2159osbHcVDmU0mE1XFYsdc5/v3iFhgRNEkYA+fiOSlVgnu0inS/Sam0ykyFCqLmTScVgj0MpeL6M8fi26I1VZODEh75/WMnihxUs1M1gFoFJKVtFAu72j47WE4ENC/oOaUdYM5cYknDHfAxClUJNUmVFKTleMgOc9e7nDTtgqbNuqjzkK7XKeTvQDpglmj2i1edR/OyP5EoxgfU0KAO2fH6966hwlZeYfXUSrRHrUr6TRStSJHvIH1Jnjt6AS4Y2dICWcv614PESaoCzGYWyi3HAYcECPL/2HDb3IfJ0HvlmvKRtYEmUJ/y93AUNItVMfmBTh67w5f4At0dhg7/7iL1HS5Jv7cjHSD6AFmIRBIIYEattBfY8pIYGTkyPGZgRTC6LDGOF0gISR7zqLJK8dGEQfDrwf+twS33MjWuijX3VVZFNoVoNwbastbaiaeXqan03ra541XJ111/b7+UqWnEvvn9lRF+1dRikuoJkFWoNl0H/CmnXq4Zyfct3VlOYWREbqhzQwx4kEkan0wEQuXgRYmC41q2ki+I+49f1Jt8/+IEIIMFQQFtnTBLN+N/5soyNVMOYEF3QDyef/HRICXPwFooPPExV1aZiVuubizfnlKaKpXRERA1/wKw0j9JVZ/4krkbdEtYeHMbBf805/Eh/UFA4/fuej+bqj4k/Vv9md9ofU+676o/kbvJvD7Mgt5jaJAExP/BdKJQ1ZXd+tDAEqf0VnMCRM2WhF3CHSF4UDWIBcP0l4Wg6ooqQhxpO5VyV52Ev+eTPdQcw/Qn+XsS9rBkzlPT27/x0OXSn3P30g7ANM1zYG+ZO/ZC3YaXRuIJTILwwf+zoq+FQRW/TqpfwavR21xUAcjpvyH0HV504BK+qdyl2NfokT/kelWNkiQnC/6+LGQuLc9ReWX+q379gXkn885hL+rd0VQj8NwMTK4O+SWCA0cL9xFPnqSojBg+ues4dD70ofmaMSKU25liTUCuCAFGoGI2H7zdhVfROcmh8XVzXiW8stDEFtyM8c6a+LOWqTea6j2GOhtGbsJ24G5tmcy1G78Ycl40FwuKJ+wtWnuyTJu8msrmcsYzW1JLH6HQhGhZJTeyD6ljNpYK86tJprsV7zic/VfVQGvJqsii5he/lUUNd1j065kftAR902gOXe23W65y2XdYdnXreEesdHe6ZB6muUivrAd5vP+vX24pLa7gjP6vKC2epSQoxhsqVkeBDb6UO6m1/KGCTxPGC5JWb5dxU/kM8RYEFQ3bh4pVVeUxiyjpmERtJ6rMJp9Kg+b+RY7LL5SrSXIVF+pKl08uKEuNngc/oKM/VW85TjwPDhV23YxtBNLlOo/m8IgATL54gmmDsPN459LLjLbBgEqRqJIl/x+El5y4KFjNzsHRpgvOaqYnJpBE4KQHQFeueowfJlTgLRsiH0vTiKEpfYppwZAKnQBwXfzaP4lQJjViKnUD4RQV34R8VzKT6GijzZGxxYVjam6w/gvtX5EOjSVAgt6Gc8kcBLGK7Z9aymmsNF8wKOzewS1nS0j5v5dG45/fGqR7rUDVJN1/yiDWMpf7A+aVaYfIIRmKnuOWxK0nL8rsVIouBvL8PZXDd8/79WxbN2/cDOSbVpDb1LlUQwA+m1Go0EE0srqWVRW+TaHYjjHlrX7tBNFFy7CyZlPfhdTRxxBo4VAbL0lzR+Nkf6KgE0eRRDgmS0g99UCrM0VgVAWzR0RgVBx6m8bLOQpdhT5Aocf3JBzXkfZgs5vB3TkorvnVeFuSKr1yEdyzwvTeQaaaencPcr3gaL88fpmyR4OALDd/d8RgixhE6Tc4cG75C458ekaO/cg1Suv7D2SjK/4Cd6D+8iGBH09LYhYXnRcCSpHlT5nE0iXnyo7ixNrNPfM5tdfLCbHd8p7sTyKZLsjO01KgWcssmouwQbRAdo4Zus4OsJOWc0VjvNjlz3QUIqk2G8AVENoKnnIkGUMYDnB4zlhqzuoEHuSwMgWSNw72JoARIBl0ohXnRKi/Cm4efEMG+EOpW07rQ25mpQdRB80VkRVrhxSl/0MAALL894i6D5I90yv3YcTVdD3mwVBFrv67zltU/K7JfXQzbFuiOHgfPitVXoZrvWnNFC7if4Cexp9qvSTa4+qeWEu4Dicf/gzuBP/MrjlVS5nirEdEiuzCUXd+Fbmq/Z75mNichsbyq84pBbGjQ2b4B50cUVggZ4bu5FXeKuZE8LeuLWQU6ZJXE5nEknGV7reJ4AZljhKe3apB0IzYT1Pb8kZkHa7Zs04jaoveiV6gCckEYxmDvxevWaAtWhWCvqf+1fCUr+ucMIzKj4J0507yDHxddOmVLco15tZO+ttIWjl/jnqLrlz6YVLuAs+8ukjZnSdrumnj/Yu6tst1YG1e0WX/PN/cR152llZ0E319IQc0RbrSCfxHybrbFbyMgwbmesjkIvMCM4SyI5f86kQq4sK2VAxaKRPtDShjilvuhxAuxcT+QJVNcKls0Zsp9/8EUA7H1P7ZW8AOfWZJgVkCKMN6Z70kOWuuqjBFz27O8L003jeUMd6T5nZBmJo6UpUMXcpuUXEhvFqIUbITFpK8Hq8MfcY+GE45jNhTi7g0zeALLovCWqymnfoots/rOe9nA5v5NkFzzFCy8hr2+eX0N0J74lKTFfKQ1IFn4uUNZ5ZflMWxE7I8B5wgsBzNzAezX1w68S+/BjmRNAKw2YwdyHJhxLQrWY5WwD+GHsO3cftjDtsshGPg/7N06//P/s/euy20jy7rgq1RwzhnLK0iKd1169j6jttXd2seWvS159zqr5SCLQFHCMgiwAVCyusMR5yHmz7zePMlEZlYVCkABBCjK9nJrrYiWSdb9mpX55Zf/+/+h4u4zNTg33AuIvy6MEzxx9qTZ63m2IIdvLAYejW2CIunSEIYtS3K9GNa4qwpyQ1L0Unm46IAbJMoUjc4UPnRrpvLPwJFEaqWdcDn3AsWoOjNyTiFuRBh5yf3sGGaO4EYvTpgXXwWSyZVsKpUNqF76xiijlsNWveWERy5c2mdpu8xegx8DjGl17Qe9sTvvDXudw8HooDM6PJp3Dnuu2+m5k8F4IsZH454Vref4HiC4jAqr27jEhYmZsnMTuGwVebfw74/CbkvVjeWjo+FiPh91hqO50xkN+ocdPhk6nUmfHw0HQ+4cDMYWq3/2JCzZSelh8yNwNb0TK5874pJH1wLOnRh8xjbfVQnPWNx1Ku66SInD/bfZ9NmXOHijYY3TGoxG2Fhq4FkR2pWW06ZWpR18Ybqn0AF0gtL0ttI1lipLAiOZR12h71+uuX+RcOfjL2EdgcZb3Y5sBgMzjF8X/t/HU3h1O6lOvRCHvePjPhE8JXdh9LFed85l4s+mc6VqXtoG1QRdT6aaZB0EwsfJbPX6R33XEaPOEZ+POgcLR3Tmk0mvcyjGrnDG/YOBy4vUTlCdrCMtOZ3KX+QhWW9s1ZFaPWJGREcpCoX+rYimjYbvncxVMoxpSzLV2WvT33mrGAZFDz4EN37oCOuWWOo2xjlJVtkFbvJeU3/sy+OhqwHYZKZgZmsdH/YOe5JeRn0zGg2V3qx1J+YdvlqlJyikhBmshfia8vp2ukwwQiQm7o8ve0fHQxWMsKBXVeNT+xjBBW3oBMuXK3Sb7lyUuim7PD8bqOTHPXE46vU6YnA074z67qjDD/qTzmg0mYzHoxFwHNg6lvjxNDbEv/xY5zHqmwcgJ1Lq+WsweJcSOSfV4Q+e2n7veDQundp0geo6lBXYqMQLkuHArIBWs0mYVRAyzKXerGzcFxVl2xWkCSGscLGme//s7Rk42VufP2dvb0f7Z29vJ4y7LsCTCGyj3yLIR4oRGFkkOMTlZXQxbxT41T1oAaBhAc9irFzVW6O8KSQtFnn2Vrddymr5Ftru4MOD7mDSHRx1B6Ojkuijt16UrLmvTtOpzZ62p8JOP2dvpRQoszGZzWbioAZi3IRw6SWJcNvSOxqfHYUizl5SuFYZjKOZsc45OJgfjEaiwx3nsDMaHC46R4PxQWdyeHDo9EYT4Y7HthGAr2Ig2gY62U4ioohj5DgH7491xOeej6J9C7bzGvapGgxpRpKyTfUKmHylFTAZOb3jyUgcHi9689HxoTtfHB/0e6Pjg8G8dyycw8XxYizsAeqe1sbD1sZn42y6HT2GXP04ovIjSMZFUQ32RO0h+eKPh0d9KtjfCOdGJdWP17QJm0SnwmtTZ03rzT8BNtaflfPL36IF83VBcNhxT7Tkv1zWcox+kqifJOqtJeomomnhSep6cIMuAVxMGvslX0HMMXyjwnOwsrPFV267lTgbMl06uTyf9X64P6eXqfLkqclEW9KWjYSyJc0pDJe6HZo0R1+09VqhL6F6ybM6snp5MqqfYieVC1YZShDmlV5Y5noKI9gj5BabJYEoFMBjBxmHYscogNSRTY/IrNz3UumFYQOB8v7uxnNuDOHOhPdtFUvpqNM77AxGl/3RcX98PBiUHrBliKQgDDoSA0ghBfHVh3H9KKZfHQkaR6xD8KGOTK9hh000v/BUqJdHPmXBNopxCx80A6qIx5sCpU3PvYD4dcx4rEPkZcT+0+UquSdC4CBkCSYFbxKZ3GZoq6mbL948D5HhLQz+hiYSybqMPZKdr/x224HyXu7bz7mSrR7ptAIqza15qcC0qE5Si6ppo7Ayx9lP9C+lepV61VUYJ+B61nHndB9KjdR4hNZh6jocp0+q1ifB8FFVrXy1Aj/IJHRCv3qm1Jr93TcdA8wvl/fw94Pt8eRspc+l7bAjnStfeR2FEOo8QuB1rGQrrFAh50NwPnWiSZlAH41MIt7X+kTS1S6RVGasdWgSfQa+ZgV8ioWiGAlcri2CknJiWamAW14A/4bXiXAZwFON2jfXIaKpvZ7zQk9WIqJaa5Y/QCJYGJZp5Zip8tNwHDqOWABoHh45NxSUQCQi2lRnL611pRafBYCve4dJsV+xcluFSzgSsl0ANdrEJk3aw7rQsNIdWU8T8p3vxl0NZAecs9dRIyxkSvisyE0Per2hrhF2RciicJ2kiK/3785anz9kAZx1rsmymTE4p5sWU477lgMMd4ftcnq8+ZXB+mT9+KnRDGdRlMWpLg9hvXnobJtP11KHS9xOhlu43dPbm84mN3TWSxEkhJOSQZ4L7yK95Cy/1XUixBgtNtrp4nmFrU9r/VCUuulpLlm+NX9jhiA9SIQPU/LxJvRF/LinW7aq7c658jK+7RNv4zB/w2dfvXlrcAqWF/j9n4eFhZCG0aGFMDUWQpNhrFpTm2qWbjIClEZP+73ivVEcnIceBVVsyCeBzbKvaJGrMcLN8f1Fx+98UwNiHkrfobv3XvnOF01DlaR9/CFza4vnS8lsklsrPtas+qSczOTZoDPwPntx9vIdm/uh81EvVVkHi9Y+fCCkVhgRXicISZ5ie6J73W2z/tGg2+sOur39weh5l72NwlvPFYwzI27Qj//rzdlbqglNDffhGj2P0fMlvAssBKgFsQk6UDUgXi2E+9bjYHU8VxrRMrYBN2OJuFN+/5nxfTSyB2hAgemhft+0yv6hnUNqA1Xa9l1UM24FWyGxs0xADLeZZsyFH4ILUxJau/pHGIhpYvPOgnLhVzDFgBUmdDxU/qCvTaEe+yo2lP20+lrmlmllVxEoU4ed3qTT64Mytaf05Kj6d8VwwMV40BseDEbC7R26jjOYiKODPh+5g8GilZs1XRhoZkep0j0zlK2jIYDLJuKodyRGAIlzDo/44fhwfLQYTtwhmEnTAWqNnKNJXxy5R6PFqMf50WBwcDAeHQ7nR0L0D52FNMLY9+hj+fV+r9fPA66Zh90yT4/yhz/K9S57Ery+juCVHnM7kbzS+WwmetlRGAVuGlm69YKKBtO6HDfvBopCB0jxk1Br1+Mue6c4dbwFiGDsjgdGMh/M2cp4wuah65Ge/t2grE1lN7HnGq3xgjjhgSN2X30Z1Q0KA/gb+GRqiefdAFcqxnjdZWOKFDilrAKVC7QunVK5pKIkahBWUM4G0ZrElMrltaUYqwWuryTCVvZpW/E106kdia7fzAmwk328ScjNLNPWYDhcjMZi0l+4/cWBGPRFX/THI+GK0e+Dw/GRXf4dd/qDy/7geNA/Hk+6BwcHk/FQi8E1BNYSMfjwsjc87g+Ph6NufzAcDvpQpsTJLO/1fmxlxht+0WwicrRUf6f02Sbz6s39JPQ+ntCbv+K3uOGnKYAOYQmwoa30gSc6HTPSsUj4+CSUSD5AguB23EyKEa/jlXBg5S+5f8cjMV3wpedb6BIuVEr28ucTJlMzSl2tT7RC0z6nfX9soApUsvXKrLYxFGTDFBCdP+QK2t8PNreLrwuF2TwaZoaHmTIe3WC46zn/hg2F9Ub327YT7sg6+C9hE9zl3G4LioCC5KdOKTiCalv5kufFciGlP5K4r+4flAatOs8yV0ITA5uqbmyg5s0w2xev3rx/+dOrk3enmy6fOKhdrc4xTQe0o4bwUUQrPUHbH2W2Er5dsQrnYzsRCriQrsPIE/EUNOPTeA1oR/ktxGWPp0pgzhurm2t40nLtdbXsmrmN2TY73D58l9jSVrWkqpZ0Iz22gvGLSXA5fUepYF5jLdvzEgrdPFJrFGVkoOjoGP0xXfM1V20xH2rDl9yr2RBKO8W1hXN/I0Dx5NqKbrKR6m/bTK0Qs7FePbk8mVIiL/6I4aoesc2rcLX2OTDRTSMe1HCCh4rymWABQ1tjJ6yJ8pka6VXuR+1pwYPnL/7K+WKiwpc6H2tstVUHHBOeZr4w84+phvueZMUGE2ZsqnTimsmcK45xzDtuEHfm9x1vta0Ear0Cy/aR3c9HBYlKy+h+8zKg5cQ31QZQUH881kruS+HcBKEfXt+3rJUOJp/NMa3hShSJZB2BJ/OcA5lsGBC4q5kvUV/XmcpDG2xhT7Lhk2z4TcmGxP4TT5NwGolFzRYXcv0rSJm5zdq58WIVhH4D+FLW9cfmANj2jE0ASSVnaHrmjMe11FnGkfmQ4xbPVRFUO5uDFTnvWt3v9EadYRkTHUYp3K7MXr/mlfKQoyi/WKabB9zRuGFJqluuD6xC4Z9VRjfbHeK+sn1f6Ri2HKxFlhScDwY/SoKUWVVzZ4iVmNkO5xlylOhf2gCpkRfj3AZnqDdiX+LwV28m24KsS69EJdyOavAeyaQTNNFUjIF8w208TzMTWk/Q3Kmm/zUZojdoJ8uoG1MuBuJCNKgcFT66eqmU8B+a5U5yJ1+vf9x7+ePh8XFlyXXQr1UzrR201IvIpo5eenH2Pqxxf8pdyV3X9ozJPl/u2dlLYnNyTehSGR1h9VpIO3A4+GAIupFYhrc2z/+yxlCGHbanPx7TmLogh4fRlPJXLVt5mRlh7tUXWb56wCaXbdRVscvK8wUja3gLlm0SRB2eQfkz8KSBf01mtqOxyNJkufSFs0bh074QLuTPj7wS+v2Ddn/Y/2A2qHQ9lLZp5wvicAgtkrjyxjNES4HmaB35sy47pZKr0x+zmREIYGMuKPmYzZAg/Hh/38i6H4i7eN+6MqrO2C9BYFKmsHkYjcvO9QjfBZdLJCCyO2grnTCy7fF3lIC9PL9gfhh+7KxXMQvnSG8FYdcjFdET0a0rEXlh5d7PztjCi+JkGgthQR38BL8x+I0gtBIhCg2h1m6u/eGPlCp+Q8UsmWIizt6iclQPD726sY0WhzB7fQAFLhmRV/wLDkjJS9DyajNOh8dernatSKG2n/1wzn3TMbTf631kkBjGR4GYEHU97DGX38f0mNB0RSqJmv0uQ0L5cIWFwMqnV40Xsz4Rp/vhHUD4iz/3eu1er2f0rQ4AJaevqYsZqKFKT7xP5nMWSOa5v7ZMmUl3H6kO5QCnNnr0Spn6c1kPbVf5SjgUHIIbB+dCRCKAwNlJyMBhMozYEqDnaXNFvsFxukONb5lDR7V/z1Rbstt0C6tYftoy3f2u7YE5Fd1f3Cz4xD73aFfA12CfM7ZxRmdeIg9AIoaJ2lLj5cEZhucsm4vkDq7wHttTV4YXf3wOx1mf7d141zf6u2LDsu34IkqrEvjo4yD4n8zb2xxAHzZN1u5h99/BRD1ogOs8RyUw2hDhyuUbLdco9x6+TsIgXIbrmMX3MdzDbO/k4nnmraHEsyYIbDw4MzY0iwz3/qJEON2gCLZhs89PL+uoiG1hTPUQdGgIOp3Bgg8O3YN+ZzgeHXXGfHjY4YveuHNw0JsfHHF3IvhhSW1KXZcTcoEaME6itZOsIf4YKE7wXeXF7OTivFrUhceBF1wD1zCoeyJD02f5yYuBrTyMrnmgFLElSj8tkNfUzNRgtZfmh4LddgsTZ3oV7Qp4okqsZfUc9rXV8+2NF99QlTaISf/zB+PmLpw3T4wTzRgnzGvqu37KGGf8X/wZYxNMnp4z39Fz5gmruku/Jmne21KyBIDNVARubb4XCfLJoS0ofmOs5Eip5EKN8U4VwQYkqLwFUrnK5mIBOjpiYnfTxUpv4p1q7I3FnVN1FgXwy7O/s0G3b3B+HDNlK3NDJ+6GPPbiTrgSQTeMrvedxNuHUvdvB93+vhP3BvixAx878LF7kyz9/2M6Gd3f/iE+rsd87FSLkGCo7YAc3+nMOR9PDoXTmYiF6IyPeoPOXIzHnd5kMjwcDt35eHhQqTNeRwBrSYTve9fwlKhv58+ChSoN7PhcsfHTvX/36mG603zz8350JBo1wh1jFhQG+1Uo5MXa96dWQy4o/eFX6B09vZCtJQxBx79ebXgeWKyuK57cNDY0XZruttLqkx3uDeHp7RXql0CFFR1VWfha+HZmXZrdpziW1sGCX5iusvaQlc9O7kTXCyYTjUq3yRxaK1b7Q+metXf/q3mMphuoZukP9zEtjMiTjLJLGaVwSTSVVj7ypReEUxHcelEYwHO3xox8WoGiyqo1kvHrTQ+HklBZhZcYcOgi9dLUFSs/vM81Jh2+Qk77JkCUfuzV8coojsJUZ8UBXViLByxFdhQ8a8ioyajYantcKKgpLbdtDnXJABmdtM/ntO4grANohCu3ACg5p8PRfD4Rw/5hrzd3eoPegdM7HPLFgvcHLhC4tqw1xlP5+qsj9Ka5tn3mW5ZwQW2Sqcc+TvFWZ9IDGqx0OJ9zh9SOiqx3jJSMA+TMnny5XZgfYJmnvcWBoyv89lcL9Oi7XSb5vlSpyna8GgwlaiOAtC8+TU+UHuWlACV9GekNPJl5DOyGYBTQdhfNJh8RYbfDA8lJudn4Iku0vJnNqlDMR9J7Qm6qwzGePS/Kr5/bsrISST6VOLw42yOwSVNfOrETrgALSV2SH62ysgpqTBklYzdODA15sQH/cfHmnF3gjzSI9PMcUTkyLnCcbZ74tApjEW8ez+ynfFp7wFr1+NGLr3xj5FXrqRGpbFxk3WR3AAhenPDlaoqdLHmqRN6SR/dMJ5aRknERkG40HZnN0QvUCivWrmcou2A+VGyKV16cvPtCZxe04b9Gp1BGZ1D76LINxkMMAKXHwwZDwIbTbdOhBtW+wDNEHgTv6opDDU6UJJTnVO2zxf7Eox1rVxRFoR9LyIve2PTS8YJrqKbLTPUgvH60VvsqkFmQIpfPYxEk3atgS+0CDOmr8PonXPufHxSEGrrsJzYF4huZhr0Kr1frGDoNCdkqEgjFF+R4AMPpqOjg4hbaKT3ZrtHi0b0KLoRgv2VLiT/saV2kuBU+THvczTot7vvhNdxyEjywL3PuP78Cf3MW3wcJ/4QOdfIFGWdGtHyedzJgU54k3Pk4TSK+WHhOxeUUqpGjHEzmIKdBWEJqaP4ZzjNL6CqYQXNneFTG6xUE5AX4La1+uZbCpZfAMLOLYgIeiasgtxXabLbwInHHfX9K0zVrk1eiDJU95QH37xPPiacwAbPMoKbPzt2OaslJr84PueFfioR7/r/SqV2qb6vzGjF6rvtceTTX0O7VOa3zdVrEx1fhNTv9tPLDSERatInXS7juuwzuVrCFoCVfeaXQZY9HNiw3WLfyVGR6iUD5P7B1LBSX97UvOlpykgXSuZNEnrgVzMseo7WCruecQH56MRwOjwwhhRwOAEyvCc1Rn0WFbBBaatGZ72T7ILvF7oXuEnAUlWdlOX9P5PJqns5e2gp9rAEQvkC1GsRET1Gb9qNYJYbnwZz0R112QRzvM+Q1nSlrHiWV/ibFyU53nEvn9Q67lblsRABFWQZd9ckPr+VdC71KYf/cSbzbSin7i/VBiuS2pfN2Pfc9h529VHaM/As0F4GhYts90gJr/gBNEYuMB2aHOHapydPz0Xq1XrkPPxDRxUiW9E2dimVS/KV6k2dvnOIm+bYl80tDZiwI5WhqUEz6RpfYGxIUrwKcw0BLpRDXJNflb0Z0zgrH6u2QE6R112AerwIt/ZJCJoRYi0p6piGhFn1NuTZ7rJgnZNuUVTL7NHMHpxeD/QrUeyAn012QiPYk0j2JdE8i3ZNI9yTSPYl0/woi3de6Ru2351/TdJCTIB7faICd/grjvMtRrmGvazSO+lzBq63g51fb0lwY387gX2Elb1Snbj/sZZC/mjNRQ/XaaHL0I7IGDGSDOJFaqRx/7Qp57ZKY7gWGtGEVJKpglnlOG23bxWLvROTwuCZ1oR0ApvqmRuU/1yK6/xc/Ehq3gTod3n2BI1dX1RRxAJnf4yXb2MhbR9rPCfRkXQ3vUulfubVWicRfXI5PQkZpkLLFi/GfhnBfS5DfvQrmARZuxheJPFFIpErtlVdB3ubN/mIm76tA27zZ2UIZZolASXzy0GfaULr5YpGwdeDc8OBaPlppDAOGLBWMDhG2N7tqXbVmSKLh+IJHEloE5XTZG1hpd14s2ldBJFY+dyT2SK6pZ7GqEryAIuHff32D/MaL95s20BtTexVk5jYWCf61Te53ZJzPX8rqjtwGrpgKhI1ze3EST1WY5LLgyyfyqX72Mj1tgccKXD92zWhthIusS3AtO1GffabyiLQVpiIhlv+4I5cTqmAbV5NizlRmKkSj1eQJfxaErpRXIXPBoBdcqdPKS7HwAoGX1DcT/7R0rr7Z+KfVk187/mnVSsj3d9v4pzubcJRFN7zHG075fO1/BIdcsprYIqRmZ9m2TzaPL9Qy1bVMVyIAPeAUsPzrIFCxnhuXA+l8QcrILbLD0oa8GOHhi584X+t8yK/qBy4e63TU8JQ2km4eN3Oia1BzUqa0YRRbNE54si4x0Su3fkqjzQjxfeDcRGEAtFG6uOpLPG1qqpBPv6uji8/vaFQay8a3zbLK5kGu60edBKHkr7xNV64X5ZagjF+YPlX8y3EGTm1qrZU52wjmAlIUko2AmwV5jiz5J6ALMjhQ6HquGejjm15FcgrTJSS/ePj6oYmrtY4sx/QOeHO/5rDKHhnjmn6juvjQIU6HM7O/it1699MLljORhYt0i+gu4Zmvy6ru4KA36HV6/U6vf9k7PO71jnu9f9TcELLN0oZlU4nVaDRuUWwvlfPIrc3x5+XOooDpMHG3QuFK1PKBAmqcOcg0GoTImWI8vsa9XlW74CBqKiPBfzHj1FtNgRGhplCT5lPcCdvlBoVTBLbMrXJDhHfK+CEzCo8lUX5Po/Uke24he6pxLO8D7NugE4hr2v/DAZt7CZMEAVb+eN368XhysGl/TyHgRS0hS/EobJ4jLFfl+JwiCjZzBxRO7/wx2kDkoW2F1/IydIHHqX4LzAyFJpi0M8bItN5G3i2oulMO1la272U3BfSoNXB6C+dowY+GB/N+X3Denx/0nZF70Ovz+eEET26zG7qwfu+yP1KF2W70zHCaZeSWoTHHJUtx41WEsmv1fWQdpQ1rVLZsKhfnY67Wz9maN8f5iDVE9uTixdnZ3sFz5osE0baoBuegJv+DjBmud+0l8vsefH/UZnee7zo8cmO297fnpLPGEBP3K5BG9jrPi1GAxSe0RwM3t5NUNBHWrIQ1IwJLVaVpo2ICQrbZ37oGMdTzLvsVJaFoLdiexMM9px5Ea18QXDCmOEbxek4Ed7HMRdqdQuJ5iORQgkVhmKiAC9BZo4CNR7GkeDJ7XL7QNlFd5bZKpuACH2p2VdiU5mqToImPQKApkg9ygW0fbSIbRbbhaN4fjEaHR6Pxouwo2JEGXcoeVrHz7O3tSO1RWJj0xYuzl+/Up0n6M0D65HeQYkM0kF4X/l8WXMdomhJQ7GK8C2PupXZs4Aul9JbQ2QTimKbrzYpN0fBPqaW0tQ+4dCCUD/J6TeP1YuF9qi6sfBp0Wb8DgmAqB2vblklqLivJcMne2Aei0HIux2QNL8ASqmPdpGGvr8Uk+PewN2gPewftYe+whM06Xs9x9JY8cW4e0uWER9ci2dxlZaSF7vpesP6E3I21PD/TQc1UV31IbI+eSd9e2csoxricZQavsufIDprQjOh3HcU13gFbsUR9fnpmbP/MiDuEPOlIo7ndYFpYJ1s/Z9MHwJZv0m0L0E/ibQuAd63O+yHdhB89G7cuhgDTEQKkSoadcueGvpbiYcxiiuzgpJJyzPbMAFVtCC4Qtw3xLIz0jRajIGhyxBr6P/yg78oM/yQ8Lj/kL2PdpXqRfnf7gMupuzYXZ2Zo8ACkCcUHoJq5zZkw5c6fjCnyc3NBFLkcLLPLaYPTOk0u8yq4Eei+JeCofkm2zFZ1sVxlOGxmm8vbUOtBijcdghTFdvGF6nLBNV5MxUH4aym/HnALVYkvu5nNp4Pq6aD6UgfV05avueVLMYYFNclma1YdLemOVCN2eXDjESSV+TX1jpAaA9pvr7DMzg+KeyV9QFvNN9eB79E+kJ+Rdm1NfHbG6iq8t5izmuum8Jja2BZTO1uzQTrLTrdCqs2t6le9TfH1OvW9bw/jqdp8j+hZrLtRHjSPTdaXoQDZ/AbZGKovq6zf6S7xVmXtr7czvmzjv/fdgIqc5vvAW9XeAY3nq956KWjtarzpUtNOzeboLDvdAbrUyn7V2w1fr1Pf+84wtJvN94eexbq75EHzWG99xR3EfmYCZ26n9cigULfArebam/nxr/XS3aHJhaZ4N9quLYx3qNj/a9nLHjBZDw2IUXCyzMYlK552D0IlI9eQKq0eNjkDEmuiBbEji3KgZCMsgbJ/vUfeOi/WtBbKUzhwCReUhiSKq7sA5fXzuOXKJpv6yOIo5xwtFCwnp3uyBH7tNRq3csVmVZN+007l+3zl7SuP2zh1GWdGqfUa3kjrpQ//prbfb985znL1VaklU88Fg5HN9NbgzmZXjZHLDw8Oe0LMB/2xmDjzg8Xo0HWPDvvOSPDeoO5eDLnbmXOf02IC7KG97c/gp2fsRnAXNhtwfSD0L7wVUeS5xCWpo0YCQ5tc/r9cXr5V0Za7TIVLVtBGL2b9XNm6RAhwHEbetWcOReH0LMPl1SK4yXWfu3wF584UvG8ldqiEk2MheLKOhOQ0xTPzXsIQMStFZSYSARinVQi5kJMTu4THgzrdIYF7H/Cl5wBNJ7G6xG24tm4Yj5m7jtSmxEDst9xnc5HcCaDxIArCG8H95IYtw8BLQkytau+yn8JI8T+02R8iCjtueBfAXcBgGcOAs9ABfA3zlkvhQtRN/16yhASywWwunBCgA+sg5RNx19h2nOPxoN9m48EAIXvjwTDtHcC8YqRpgNuZQgEFId7U1Ox7VYdcMzGsIRixthmrmyFTAFCSuiwMHMH4NaDtJIUsh2MMom4X10yJNKT6PuVOFMbxFKeoOOWnnxIRuHHpwGXnOdshBdXVbcM62kwR/qrUaQKkrogtAwG8CkQPKEMtpy2IXKTdBBnIZfN7zZaRrjYWJ0LAqpBYWtifCH1jewnBHRGKW9bHO8/3CZWLy0SvPdVJGfc802KgTxFsFtNVPIUWBV5yDxwgkTdfJyKmKBoO7ShGFVHj6PbGoCXzKPyINbFI8Dj2roOMZFIqw21G+Fn3P+HGrSdgCqgBcM3tCNoEsNTn6gyn0cDlD2DsFbJuAlCacuGGUSdkl6UwbwFbWrgM90Z8E659Fxkx/FsAdsMDz79Xk67qgKkFFuW5YDw9dldR+MmjNfAi5YlhlyFOOKLscZ35+xIc6qY421svStbcnypaE89ly3WcMO7HIVRTwjhp0HMg9LYsend+pOECmXpBDJF/LXLgSyKJvuW+5yLLD/g5wtZdEOsPLhR52CGVMRxBF12GTmlpvO8MWSsuYCwRFx4eWjCOmFUVVgMsXg8+mu+wYompixwpx8T2gTCVdt7WT7ls46i0TtrGXNhrvS9a/aPD7rjf7fd6XYgZKtl00oeT5N+ij5IbYwo7F2f1PGTyO3gsycNPpQb9Yb58GWY7DpeiQ40kiQsOGNtAmu4z2ablKwPPmIPR3Jnww/nRvOe6fOhOxv2D3gEfHA0O59ztOS008oIT9VSPdz/bKGxIJvpaywIWttKymm+p/kh574yPB/CW6vYHw9H4Hy3rKbXyOit+DbHChFtXEdD8Dbsl6Uy2rVs9/MuL+CqRjjU+uUGjzZxlc/hYtD/fzwxsrXvZONjfLm9PvdmrT+BTXt7umXwevAZ2y+BTsQpSb+unLVca3j3V0uT5AYvUXyUpFCx8Z7Po3Ajn4zQS1/BCsOgPSZmJjzJMQg8wIoYEqsh1oJ7KWFLcZedr32dLwYMYmCMjU3RGakDmoIBepYPITcv5yetj9ivwTkYBOw+j5IadLEXkObzNTvHHU2798dfT92nG0zWsxDY7hS9VBvXl+QUUg9nh64twbZZzgb/il5Zf37w4Zm8cwQOPt9nr02P22nNdX2AdbXZ+8tOxatdCFgdfyUL0VxdGBScxFHVxqr/EsuTX5/g1lWh8/eKXs/OTY/bixgs42zs9vzx99/bd2cUpc9ZxEi7BzRUE9udtdvLq1fTd6c9nb84vjpHPVE1tRa6u4cMA89Fqt07pz6+n7+ED/hdGsdVuXdCfNy9a7dbrU/j+5Cf4Wv73Av57in/O6Q+2vdVuGS0rukLYnwXpwa1aAs2ynbL5ha/PjI48MzqV9B5vcG8y48vq59urkLvsR6xORHiB3d3ddbM6tRrvHEszG7DyZrURqNeB8tlctqvR46y21tPSZs/dKoz6X/CSeLAXRLZPxkcR2WcGaHMXngAK8J3dKpX1FMb0TP+2a8bSLXT2lrbbbWugxHp5fpGqi4DaOI5Dx0ONipfcsPtwHbHMSSDVtl6cZuM+tPJeqSo5UIlAuRTABFSX6Q36LIaf2pKz1zxhUKeY8I+gtRKOcAVqdCVJgVEcppOqrnW8ySy5qzNL212fXtXf6qv6wUT+ZQq6z7YHu2WN0Bvi6Z748o+JdqnUj9zSkSdiTQHi3XpkTVjy1YqiMHIpQdpMRIYG0YvDaZzwwOWRi6Y/KPo+XzBZt9gixPAHZxdv2LA/mXT6jPurG94ZYHr9Ndll5eMF9Qiyvcane+RFmPIBVHqCXIT0tVQ8vuABd7nxvdlNLMf4wijr5EeMdJL+JMs78eciSjiOvD3njy/sOX+MvMSLb9iL0F8v5x5H5aytG79cFrvxC/cSr2VP//rvxfSvxSfPCUsyvL8oZngfeEDvfpHwRMRbDNc/SoYr8v4Ig6rhwkmz5HzBfW8RRoFXmflNSebQDyPuhhVZfzmzZ/2F33HPq8j4+tye8bUXBCIOK9fG65L2vvZigJhUVXv+X/as5+IWFnh5xjfv7BnfROIaPSTLMl7+3Z7xUnzicUW+95f2fO8TflOR7deShfArj4GaJAnRnPFBHQmSD4UerKAyeTzpFiLfaTFxe6ojS1Vo0kMQBdiRLVIoWhOXPPooXLYOlAUcGWvJBCe01RoNkKCplRIopkW9DTtnRlWEa7Ny1jVs89rCWJRp8eb2rngcP3J76RwrwSuc4E0nISgyrbyk8O5TVyVkZ2cvY7aHAAIJHbgRXpQa/leRF0Zecv9ca7SvvVsRqGK77CS413WAkC4+rXzP8cDcqgAJKMAvQJqYYyiPkK1jhWZxwojEJ5cQK7gLsGGqDx6g6dRTQ/gSK0NPfBqBDbf4zz+iF9rcPeothoeOcHsHzkAMFiN3Me7N+4tJ3x31j0Ygmb+/wFCGYkPKdqvXOxpQmrLCPpdFZyrO1oz23fFv9PfDjFE3YI4+ivvOLffXAJ95YUwlDA9OZ34yu80iteUDMxQXW2aoq/StejltXk1d9hbRUGqFIPAB1K3wvoN8slKEUqCl31gZBAuBtaYipVCYacbl2izIdhvUtSeq6cWXZVZf1z+Yj48mA/fgYOxMRpPFcHF0MBg7c+eAj4fuAhbG0YDWzthcOwd6YUzqrp3CJOxU0QdH1QpIyOUBZoILWvXOIBk7yx7b9DKNZhffAE5wvSLwhWcCZQCcoYqRwA0ZAQ/Dn5NCApIjFsnIB48SnXFnQVCLfdxab2nEFsN7gOBQL2WTJRRQ6zVA+4F3goHagiUuyRhdsmDkjBZUGByQnJYvFudwgMLw4D6rNY3liethyDa9HSWkKBCfEipjz1tA5ue1bHTN1azi00o44FkzD11rvHOITdgBTFAQe5IIdN6RMbfgrAvDj7jTJdRM4wuhvFRPJTMAQjyEiG7rQEb8UssHRiq90HmcSiE2/FBj1JBly3HfuxVb7DI9Ynh92zV6Ko0C2hqYS4bwOlewCKAwCqZmrqTH6vDg06ctugtCAsgIUwXvKfZWHtUkRUgYGIgWhCZN7wdXJDQqmemtGYY93ywKXkbRtyyz8BM5IMjf5V204lHiOWufRzq6FbF27WEXQgVtfk4eDaDxkKHsMji7shCNdJZYNNMLPDtxT+pDKAglbk63DzeK4hbT7Ss0rTKMuTwHdhg6zowYp/Falh4itWWQtFksCAZp9A5Xr+6iXOsyMgJy0krcKyTBtC/f/HouQwba5oLtwfJSv9sGZHPQWluU0MIa+ySyJqfC4agV0TBnMpAjCkwgECuYqJSm1dnu+B6g7QElLbiLky3h6fgUoIuJEMFrpPMFZDXox9Y+Uu3yhHxq4iRcxWyxRnOzdLMBuTQfU6KUNjlIgGaZUtn2NZBosmcvKF3n8n4ltD9AEqo4ufmDf8OhCx2iZbH/z5i8ObPGFvved7hdzkqb+UqmeXATi9YKo4WD3ujQ3kb56C+5Ry/hPjdaxIk6GJuON2V1VAdBkRN/Eb4fZhvU7w1GtehcS8ZN7kK8kWh74VIFOa/mU9jyPiG9q/aRtR3PpJnVKUAKjUSyjgL9SFEuA7u4DXcJGqblZR9S069GrkN8EeKZKFdh9qo/kx4U5NkNkuV9uCZkOKLR1WpOH2AwIALOxKhzcg0HiUzh8EBa5KSzjit2M3i2Bzz5JP2W0UV9aLf+3jlZrTpnL+l17/QHw8pX904fxTSuU1ck3PNrILr/0oafrwDQsi0juOvQM6/OO34VruQkQ9aTJYCvXL5ss/NX8EUOTK7B4b/92Rr0ev3jlz8eHh+PlY9RfQi8YXWGk3QE5NdRAgJ0f9DtA7Gd1Apnl5fuWn6w35YpNjKc6ZuHw8ovnhmibL2vclOMT1qFNHCzUtlm6aFUFFQr11wv5FYH1TIt/93XWb+2Pj6Kl4UctM/0v91o+OWBJH16q3adGntK2dbaOlIyeNc3cJ3gY/sO/qVUdm0takq5DyQdMGu4a+6rl7UsG93ObkUE5wi+KOh7ukwyigkoNJbBs6M4YeqdBHLnDaco7FgcvAxjrT9WWgvtTgpOVo4jVrC4SF1KSkI4OKTeGkNaMJw+9tuVNLhw/6rVZletaz+cw78//IDKE3pMOuFyDj4WcilF4p/4opTnUVbjMxc3/FZACL6PAooHKTJfdreiXrbkH8ETDLid5epFjz2QxsGXLLxTo9vGsQAJzRwNKoi5wiGbNL2LVVEwlEHIFpGIb3BMMbR5kqrcuc/kKsTogb4AmGYYCL2TApbB3dZXrsKUx064Qjc1Wh66keC0eX0dQQAiQSumy3DgjpUIvfaTNOQ3wS3ME59JB/CCrPMDSR6pnyqOR+ZawYsGy6Y7xSx2L9NZaCcAPV+eXJ68QMTpxfOuHrhjxlksQOpJRNo1cF2mFG2aVKOjukNGlYYLJTy5ZM441CcorQYvcAX4v+OS/6F6zgzteGH65Ho5xvR3YeS7d+BwrZtvtJZ8Y1HHYpQoC5KngnxhKPWNib3F+dSYB/wn1b0FXtZaxqaH9ROQ8ysBOR8Fp5kFZZbLNIs+n/Oj4WR+NBr0h2I8P3Qd3nN67nzRXxw5Tj3Fn/K1tx9rBU983OjZJ9fFTRjhW0imBRTSPfOWqyi8NfyrwUbRZvN1QsppLwAOqlhelmFgPFERbnknpKyDR8ly7SfeyhdMqS7shmX9/JyUcZzkgLg88ZJ12YNe/aqUyubxCdoe7umDWTUcjwo84qRJBD7AkbPEm+s6EpokgAJLxiJpMz8MrqmmCm9kTU1Sp18mwHjzurdRQjRBFeazf05xSNqk2qC8bN5m3GzZklKHVStBec7q26DgbN6GbOeNfB4+Gx7HDy1XFfQZ3JZzZogGJWfz1mO7ewAAPtVXQoAnnojr+8bV5fM35NtrsKpq8aPWA7dDaURU0HR56mzSjXwai6RpGWk++RDeZp+k+ehBD8wNTYuQueB25YEbLqeK56MpsDqX+7OGpG3Ts0xWKGrtNxaJKA/IQzkCkYblFLJbijQ4SR5YulmSraIkaXqgWItAlTtN1XQV+p7TeFRyuUHn2bhpsiUAJZzuZmunqESbqj9zMnaEvuetVnH5K0tvcxbfcIlLyioh6AptM4piRdwqK4geZ1AovVGcXUCSd09SuBfhu3ymBNsZQvySiHsBPNkDloQrdutxNuO+/2Yx26zp+taFjSexYFdiwaNc20/369P9+nS/fl/366Z7cLPrarmWZHJ05B4dTkYDZzwZuQNxOB6Lo8mkf3h0ND8YjAdbPKiffCmffCnzOharP+XGVfPkXdlEefuAydmNZnbjfK4RsvQ0nVtgJl7lbKYA3UfZXIJNAyQHXQc1gKPQ2anGhdvfTilptGHxyQLKrRpmjbv3gmQyMns7/oxAMsWiN12JqALj60Mk7Dgx2mFQ5oJ9VloCEb24RUMkpZ+EH23Q8sdL7vsCadGJbFKr/feAVlUAXW/83Bwpw2JmQTjVaeWkhzo4yttgjrasbphFOtSsTNsj0u7m3bHqVN4fyHdCk7q3qWiUP+lyW8EY8XQ4VNNKlm/FYtoZ4RU2M74RrltGSE2jIplyVEqGkqdyhF+JCIwzUJn25MttnzKkuXq2UwklqHz6EY1B0osFkIg3prW7hMVYlk/NBYdChCEjkjEQdwYXMICaZdlgKw/XifqRKdndZhHSZq8eziFMFiBZe3rq8BebmJsqLNQDoNjxbOszXgmZ2eiyE0ZvQJWUPvn3mCTWzmvGSKbKpxNAcNyonHCFwQMIEBXwNVkQbwR78VPnRRgEIGEH1x2DrhgZC6ga30/Zqmk5c8SBEE21Wf3ZW6uPR+rTQT0wbP36C2gWSOdWqLB8b9VdT+j5CS3UK6HuylKrQ66sna4N3YuStQFmD0KlGBMHJk2ivZcei8W+7QEs/zb0XHDrQTnFI1gPz3hlWWYDxzydi/IpKDgj1PfPkCvPnZqOGhsVU+Uc+iptZ87BNqwezTg2QRh0FJ11uhOIUjz7uJ4hXE3wKGA34V1aCsCLFgvCbG085pZW6PpLADIvMbQMBmlYJzeAhqPYJKr1tN1PX1wol7MVBtKIhNtmbihi6RcN+DvtHID90UzhP4vw7C26t61XUMg6MMTIq6DDZlegBbtqzY5l+BNhYmDfhm91Y1RyyR8eTb1sNiJWot90vTKrJOivbA4ifiobUIk1NZqVWb2rcGUsXvpkpi05TGikp8LZIKKfQrdfkC/MxXoegFvP6YuL57KrknN9LtKpU5gm+5SrUeb+Hb+PcYBP8J+yAFgNKk0A+DJMci7ICTqfApf50kvuMdVb/TuB2HB15df8v2VzqZKuRdioDEq/yXcROpadLVW1MWc6Gfa31c4kuhZhyWFkO0Ak4KPkcaDxII+OPFEQlx0BT5ZgUqo8YwgEr+9n6dmLDhpaKkLoJpsl4Sr0w2s6/LBksmvJIymM2EzO1zE6AxrpTBngB3KwvgsRL7tcQwQA/55cj2PvVoDsoRuBDtlByGZYzoyKE1mhorZAad2wgXRcVCUTNDMNHqPdTgibK8h5yBiNWh6LVo8PWUJTFa3MJicXlvMuL9PHjh6Wry25CUtCF9FvSsBVTwiLK7EcbBTTnv18evlMe/7sk9cP3fUShAuS6TNHCq1hMAXsyNz3QL6jjJcv3socWaeQyiPr59NL25bc8dzkIwNYh40SWVQZFDYITpa50KQy2m8V9xw6c0UpM4C+oNPSCtFmCCcvwOGNgqRh0raWk/Pe7ykBDw80VYuFHyCFUpdqXdL4FPWOQ8k9sRmBVwgV0sQkns2MBvEiQ1Ejg2kue67I9eYouJXsQw8yjOet4HnChQZFZfOahWkugm1Ko8xgTbf4bTYxqOezk8u49JZsUJDMBEg9Qw/YBOessqHKWZ2gjRTOmAnEWU7OVE0s1JAFNWhRUzsAZiHT+FxMAXrT3DquMqKuS/IYNrRCUS4ZQSVcN+2FypU93CGUGmnLVvfJDe0jGucpj67XFAo5qwHUKjxV4uc0bmuzFkGWR0PmPgiH/0jITosULwczg9J6OuafjvmnY/7pmP+ejvmKo+86Cterzede9pooPiHsIZuVNRIrQcuzLKcuH1qt6GNWz5AKKroTUKVFGS46pabJNLjy9fY28pZcemRKvY62zOkLME/n1mQjygWALcEw9bCj4ZlkecQpT3bVAq1GyvXjIWiZzILpUFNaOU1CCp3qqJETieVC3379YOxvgkA/8iLKGUY9t5VdVul02JQUtsGqvcnsbIWbBgmGh7uu0LRKZYt4pzttM/0grEMNS4glF6Emf8k1sgSEkiINpo1FSyNjWgwyHWA/6rYb1bOg+jCCF6Paek+bT8iQY7IJPN/MUQhtWsfJdC6mGykkMm2yq2WE1sqgAjKIPVeGbaWya4y03F5bLkPaq7Tkv+6WNSY+XafFFVAc/40bWsWgFyls9Akq1gQqpplXJMOHYhSQw6qBBplFVcXnkB1qXZDmcitc5NIg9DdcRWBNkwQAaFiLykx5qsHTTPTbSmoAnaWMx7wyU1n7rRbzfIiKTCzI/Jikfc11qw7VTq5TrRVJQx3X6fRbheZTINzdRdfLb8ZaoWWfNuMusdPZ58PnHUahfYwlQlDMp7N65yht2zLY3eQ9XbNf9pp9umCfLtjcBnyK2v7X8olS9m6rN1RhWTzFp36U63TXF2mqRLS+589eKvXna/nc+hnf8AaMBvEsOQ47AyaiaeFUGIntKOyzKp46Df3iTbTHLFUaZQw8upfw6+dZ/wWGSGsMtResMcA1c254xB0g1Wuzm/vVjQCeOkC3rAPgSHbCSNJDotFwU0DR3PVQpyOG37xdalApQMUT5eOihhFGxzEUelXCw8aBfiDoyaDfczTgt9Vu/dPFj7atYfLxT8WSe1bPKjPaSxDeMVdAGFiOBJtnxP45FyhA3ZLeNRNT9oUIkoj73h/CZedGfQiY8hwiHI+P9/ddcSt8ODDjbtp+oJDeX6wDl4OFiPvxfiaGwD4xlWLTtQ+FYtbORhTIxh4AdCb2zOEBKAl5YJKkQnHz8BPD8BDwAbYU0LJ22WtF4YZ16vyakx9D7AJtN2eu8AFVCx55kLVy7cbhUoSB+L8N5uw2fJfcheZ3W0TqyMwxxccoTrKMi4FaU+SEzbDEZodufp8LkxFGOZrgbcJkUI1Nbc7ZcB/SPe2BhZhbyWyXDuShWZWpKq2wJk32IzttpO3ZxE+Dm6EpOEPmAuthNmxUE8yDkbPaWNKEpsHC8uLzJBHB1NmCTIWGcZotYlvEgmpbilzYokV5Tpct8AOyUwpGcOtFABJXt1xzo5GlgM/t1p3wrm+aNk1msgnUkms7Der8+GvbuYEoS02HQzZUZd7pUs5xz2/TLllGR5aRDczTfBWpzGDHb4qgki3yVjvZC+VrxpjH8ueMussAeEHpS1ntGzHO15qF4k1LvzP6HSXktSKav8/duwTWr5QbsjEK6jczDQewgUu4BiymuHiruly3PzJ5WbdKzcRvMkP4sCnOBXnIV/UuE8ENnVyrJ1D7IOm6B70St1WMJVHSt3eXl2zvHUTLY5eRt2KX3lI8rxnHaNDrd8dL+6ha9R3pXrY/R1Pf5b2zt7cjkAbP3t5OnqtXqozXUx3X4uiwO+53+71etyyGRZ37uyr6o0zJXpyfvD7FyDqRawRYo/La0uFSvqCXkPFk/+Tk5ETnmItFiIsTohIZLswUvktG6II2Z8MOkFsHQSPDSPl1xrI5cgTJl57oCvEF7N9DDdkWyCrIQco84NQ0YAAEGTMJXyMRv8t0WzvlYyvW5FCKj6FYhhpYeqhh0W6ooBGSeTMjrjJU+3JVzqCKz8MTbl9gKgLp6na0761uJ7qfELozXHIvII0DRCGm5yf46aoABhBBYePbo3iA1VGKGCdQoe+1DpM6jonyGKilmDdeLQ+KZYNnEsWymUyWsS2qUk5GsEX+I/dAelzJoHxSiWKsWfk2N8K/gOOUXNu189qiRm6O7dXwZp8qgdwW6TJK6CZfxUkk+JKlfnLICYGBTuBA7MngSFk6DZkbNWVRmISO4fwFiKtqH65eaYtNBsRSKhI9moZHf6qz0wQA4K+veWQi2Pk+Re1EBoAH0H+U7MkqKo9ERsPMNz1D7aHd65HqAn2tL7DNoOuRORWzh0oLVAz2lHNF5kFxfOuxeahiMeDHNFwnccIxfPpU+eCWVpZwVON6QRJqAJvyF6bQuPigAnUpBBnwffiLUQ3o92ex6ciY1mzy5BpKYbaESw3ilZhpcKKpImDyiUJYqqCYSIR/z0CdwSLhk799ElIsnlynjY3whfq6wpj3xvYr9jOfZrt+sosMQwj6zfZ1zLz9QaYVD6FnaVcsIP2jUdlXIROp9K1VEa1K7RDsUh4YJCGB5JKYHACx4jPLRrnRIaVyzrVtmMRbD2HACgzqJbHwF/ZIYw8PFVYbBF70FnFuiB62pjb+QdruEj0+4JAX/DbEHWSwhZwXohEbBhAvuMa4R4j/RS0vRatN68EdxwMmlqvkXgX7nl21rlozpHyRccCq3wbGtrCZMJSHjmWYAncVekECBOE3GD/zjgcYMA2I4NZwCmXD0fFrDtF3HyvQ9r58cz+6u7tSTG/A2Zthphqu+WzeRwxtsq3bXQnX+PY6bV3gY+i2DUVgMTpgM885M/M2LqgWXmJYYEaAoSb0pSqbXKMZbryGNKhpXizMIJ5pVJDKZ5BLGjdXE5RCLvfjhWIx2Bce6vAx1Y5uD3TC2kKnu0OuevtF2aSwYgH5YlNL6bblyhI0Y+e2hPT53FkK0MYFxVaFOtL4KxrF1MJTTqNIafA2ROkFfX9AziNpYoYFSsF9RlZ6Vzg+BF8EMZrD2ARapJ7lWPe72abMfrAQHklCoVzOWaW6tdcdmPyBWfZAFZ3tzQIS9nd/KZcAZ5A7FVRYeeclWkF1QS/1FKcqXoNFuRyAzJRE98jdm2URfhbLGYVID7MuwV7g3/h0UnFmceYpbivGqv3BiBd7dxPGQvNRIZYLWS4lWxbo7GYyQrmIZ2wPaLEW3ieRxoScPSdskKyNAq+GK1SmRGKzRkFd3cWev6RfSHSNV8KBTazJtBDkguqYIEROM4i7bnR6ayKrbPcaoxYymZG1WZKWNTnbiQsrPdDzkK6b9ZIHYMxycYSMZareZll0h2WF3gV82ZHLlNh5X4ngGqT2UuOHXggNu6OW6DQtIKcY1YNksohpIfi31q/nJ6+JEFhijnOtz7QsF2amdTQ46i2Gh87Y7R04AzFYjNzF+GDeX0z67qh/NNEcxce/bYY/f7AEtlCKgV2Tl1nGzXpKYexkD1FRBb479IHEbZzb46AAhWXhJCxezyFLuACrxNoHeJix6Y/NYiOx8rkj2TzVZMEp4ouY+/Lw52iOoEyoY9jDUyqGo0K9TJPczQMJOjLqEr1TY7by1zGbZaZzhmdNkcCUdJ8JrtcuOwESLiqDo2KJhriOyWGHEYpKLu+mGydXgipYXuLblKiymrzhDcuIHyHCyyPtHlsw90CvCa0EU0s8bpdenLS66eIkJsg7D1SZ2WvXCDFthN4GDSGPTIpeWp97MzMW0Yzts1kmaBh+owMx4adMHDD8prAd9osCGHyX20qQCoIYzZ4DCphx9vbk8sUv7VQ3RH3fS2WMY/bbh9lz5gBZcMpYL4ft7sbzBQuXntI4Calw8gWGdtdkzToPWwcS+7EjrZ8Wox5jLRk7Ln8fg5UTne7lOjp7iRpAZx0n4TJVlJvqajSZoRmcuPgby+IZUX47SVyfgsZVvPG2PO51xyBJUTJhJuvpZCNIBmERuOt6NKxvMydtHSvrrmfQOnVwVbVpf0tIcH4W4VYiEyexqroMmopOaqDBfWdeiRJB4Bp3I0yC+MSdhG69WKgJf102YzkB+0Ho9SwCvY54s/NRf/KV/FK+kjnnkSdHyUd0lKwR+i3vKHl3d9fNeg3kfSUzRFutz+3SBsl5MBu06PM5PxpO5kejQX8oxvND1+E9p+fOF/3FkeNYGvQqBDvuCqIhKXVmsU3a8WtnLpyZeJTZpX4KbFWryIsFPhOOWeZuzTHmp9pwPKd58fTeU+f6/F4CuDQ37yrygJb+PnWHgiL3Us6s5112EtzDtyoAwQriwcAx7oqF5M5Gtl+AhHDnIyEclOjjhBEddmi7N2U6hIcFzJD7dB+9BfNkqIOYCT/Gmz8j7224vV+d/B1mZuPt3N58z39ot1798g6Z6efuxuIWR/0NhV38xwsorNc7GlBhJWV9qJAa8pf3jLb68W/098OM0aDAIvgo7juI8EEJ/S2hQZd8hWslv1K6TS/VzBFr1dxWwpIkMoKsnoAQQMWilRT8ndxxis27zd6/fEs6t4vXl28Vn3fe+in5wWVkBnxz07KVuswoId0ArViO4UL0KwV/3oOCjrVq+bDXpqLTr0aj4XMrCqoIadjatFolXUTi1hN38ppJVVs1TsLsFJcX/SSvNGFtKQWNWc966Sgro5HheZ2iRem0huEHvMYt6Tg3nX58fucHq/E/578Ho7Fwrj+5vaGI5tfJp+R37vXglgRNInupD/lWu3UrDm+O/MjxVuNgPJ9f86P735fuXTw45PdjtwcaxNPT92ae2gfUpbIaoIKWx3HoeKhXQDlf2xTOXtbz+KV4LcaS35LE+PPOLvJ0l1gF13f4PZwvBvBXR8qizAD7ivKBb7ab3D/zCFptkPtNeQyGgTBFsO4joHJRTCpbH9mN0RSrbBgYy0T8soq39TQiCDhFnzRLJCNd7pucaG2RtjetoacDd+fEDblNuru9b7Ih5wSzOPaugywlZBIysVz7XKpSpD1PuAyKkLpDKBNj/T0O1OthHtsqlH3lXN+EcUIuGDoi1jXoUNF1XrhsDw2Pz8FLIoxA85n+ArU+bwSVrzBi5mlZsjrASuQ5BTkhvSKhhothrwz0thGWkSChGoKOlxxMqRTmTAgvGtLr1LQBpP0+FpliEHfpgCUKkcjw07PYjrSurDAPkK5ZTx7lXDs46FbYDklTm4EEkGoIXsjwZk13mUxrKo1B2toMyzCD0jSAaFhCze1Ch05qcjkSngUAXjE0/yqKbxsQSCoL7A6PJ/o5ayhIpPW8y0DiPWa/ihjMCew8jJIbdoJEL7zNTvHHU2798dfT92nG0zV0o81O4UuVQX15fgHFYHb4+iJcm+Vc4K/4peXXNy+O2RtH8MDjbfb69Ji99lzXF1hHm52f/HSs2rWQxcFXshD91YVRwUkMRV2c6i+xLPn1OX5NJeqvraFB04sD4QepOlR+PKU/v56+hw/4XxiHVrt1QX/evGi1W69P4fuTn+Br+d8L+O8p/oHW2G5XPd+FKPCG/PlEKVpLVuLBPRxMv/1ZUEvkVcGlKZSe4INNoN2FNGUagTccjpQU1Vk7UXuS6YBKJZWnPDqaaj2b6Clx79TSBrZpu+1KqfkIysV36YR8Of2i1tJrA4GtC6mJiBZKRlJQRWyWUoqWIkvgSYkyJd9mlYFcodEzcI+ciLww0E7oOpn1+FVeV00MT8rQWHVJpqlgVPZUoSiUo25iT1X5nJ4wloEqvLt3NPJP5qgG5qiNlkaDymCT4dtmgyyK4oS7VLq0FHup13NhXrcjxCtYNsu9bRvUC7i0dF9lJzd1aJAUWnWjDee4Qjd4N4EZzNKfMOG+4S1KZcKjn0xp5FCIK2MDbQcGh7q2DNkLowzl6Lji117AEwP2ISuurKQPdYhoaq/nvNCJFdy6tVqewDBMK8dIFZpGE1W+3Dy4Z7HgEbxGleKkuiODXi+tdaWku+qZwWRp7dUD1evZF4yOf2UB3BvDh8nw+EwSwKPBo87hsSCgqow+pZg/IBprNmo13EQpBQF7J8tD3koqEJ7Fy6VwPfQornbnH9TTs6x9UYXWPWGp1I6etyopdnO1UpHG6dohKC64RaK8guj7FIv7TGN6n8NLGBr0AOQrd/kKQ+tJDG5DQb+QHaP9GTjGhuVl837WE7FVYdm8yOu1Q5ivChk+jZOIJ6JxBOxi/r8CdjiDAWlUwCotZFu1Jr59COuutyA8fQi8KlyWHTfmBTciAhB9Qaf0LM6p5540pt+7xtRcJ8Qg02R57NINbrfu6k/62Sb62bzCphFHvpEVFGPEwjNVLDxN/Sjy2S1FTnmSRN58nTTW4FWVZKsoSZpeqNYidu9d0m41bxq2ZMdAdPS4KO6vH08vT9hP6C5xHibsZxGIiPvsBNWJcGfoJwrkT539ckdZyMQnCJJcqauwL31pTSwoMvCSJMWXEwYwDgRolFIpMUulgmxFy6RbTdfyLJSF2Y/zVAIWn1aRIrQySwR6siSbUv5E3H1IeoZPA91OUPZkcPY6MCn2WBF9kR+di6c+OcWkdQBZin/H75Xw/RNGYIzg/kmQhRy1gpa2t9kKLk1wWatDtJ5dQfvEwg+3c2fOY8/JL9sOLpF9o75qvQA0oCsv+e468rrIzCLnOmZXrf1EoOPOVZmlvKkPLzRwk/8u6a7z6+hb8eq1q4jOtS5ILiMZXUHH50T9ESO/XTw0qmcm9TzBKVHzgEta/jPFK3cf2Ys397ZFMBrZEuy7llzmgCfsxnNu5LmVwiLkOYVyFkkJoO0JJYMYiApd9iq8ExEJWdKlXWVCJ7wu+y/6yQ1RdgsEYQeB+B+Wc5B43MezAT3VqLVKB6BEuDBif4gobGvzE0fwSmymn3OYQKmNMh0Clf6NzmQ4va1aBFOO27XYlohoiVosy6VytijRJEh9QZt+dvgaSE7x3DPc+EFgT8IV4wsMQhCFcBVpLilc3rbdWMfpongt2qiBNju+W8JklwVQsYfHZjI+doe9JWqyiP39f/1jC3SQjYmoKmhHfBPexWy9ImCTl7Yd5kYVkqcHAw9sDR0FBViaC+ylKhvjVt9/azTbfBjwBl3dHF45lAFYsqS7JrVvyjmnqC1fqk6krHR4R4C/kyPwKSFJ6UDuoEPB8RFChcYbEzwvnyO6Kt+n4Z6LdKyUGVQrmbPrZ4eEpbl4BNZDU17DjNLo2M7w9OcxxtCWkhsDhTvMJyx9xeiGqDh1k7MXmocv1pSIabnPfgnj5Nnm9zYka3hTYBab6jelsXrCee4CWL8THrGdocEthT/MJtdoV1VTpRRNdmrf1yFC56tVB+IiiahuCCvVqixev8I2t8laWl5FTUDQUyDE7yYQIlkeqg5YCn74dMjuHkxPQ7+jAxPNtZsnR/t9V6NalHM4GgWVLVSahH9fi2hX1LoW6JF9MWLV07qX2VbzIYfQXn1RrZodvAup649TkFK4KJCiWywG8hUL4R3X+GwzzAY8Bi5dcDS6akmGvVT8gjrw+XnMkI3bCcOPnkB7yZvAoGVTYiBih6TjQbYNbYxnB7lBmLtGdWEi3DYTgRO6RNydCojhQr7CpSicGKKm0nQtwuiOR0jOHAKL9ly+obX9py3hhCyG+5MiaygmE/wq10BVcGykU9zweJlKlR12Apst4ra+l911xM13nUyHQn+MCiP4WywzAuLIIBu5wMgP8YbEpxU61GYkAJXfDFwgPbU5MukXkjncd9ChxaXgmBASgKbVW02Nmf0R6LnkIovJETAz9/CAEasEf4cV53E/rUyBBeD1hxIH1pVRSNBMPIuZt9IU99QOkva3XV5qI3wU97kKlVWV3G/koyJme6DOnFVYDLoyJSEWbIs2KbyB4lR7FidhRCvbtidla4FpW+xgtasVm61Fv75xIlULbSsdE2TWTPna1kfOtotbFaCDfnqAoLdVV5yeJPFnLBagHIofZUtcwKpQM48spBVLZEa2+fSdqy5averyvqIWaZq2VkaLAweyAX6TH3VCvWNbOthgCca0gX2sCo6QJqOl3TgShxtxL5iqqa2sC9cAJE9XAs4aTnlexxRqhTUikQq3YRpVVx0HZQp6KyKsNGgPrI6NvUAncFjGmXMHVL5kTcm1FVQj0Amp9Sisu5kZI5idJAyhDAwcEo0KZCCjdQxgMx3CoMsuQ3nt062IHE/ymomlGhrGsc28ABVUGM02EUt1fi1CCJ8sg7sseXKc3grH/xf9xVdtp//v7cznwb/DrbEnh/W5jMEjbkV0n6DgRxpbOqp9aaii6LedWAA60MQ8youR/OulGhTt/LAQMvcUHnMkpiEzHsR6kN2dC8hC+91EYCz5JwPTlx9USWQkg/Xq4BDEn4fms/twHbGVz4NjNsaNkhLEtFmfzgrQ6hG0wOcZW9cmkHZQaFDOhoLrdekF+nO9uNz61PntQ7u1Drzf1+KMmqDhvXimTbnvT0uX/q91V67U4pNRQA2mUhuqFQqBgjKbJgzMjZuJL5MJcpSTYFNjjBRhoUsoYbwqKQ03jrQmsr9x3/+buvYy7UklaCllpldGYV/rw7NNM3/npbsf2xY8S5gMfiBFITQNNmmncRh84QZva+IEiSP2Ehv4OXuKXvCluPASkTaLhZaTnva2NLKxq9bJOgmvWnp1JBEPYrrrk5BdtV7xT1ctECCuWuf4+pH7WPIanZClHGBh5LNtHr3nYSKOTT6aW1knldSWQo6zjsxGw1IHwwBKXgm14hyOwatWtXwAPclIB/ILJR3Ij6/4J3DRI1HhArlyy6QCatvmkc93oda448hdtTAUukOYBltZqRSaqCvmQiSdF/Lhg4uznQ5RreLS4SXGoewqwFG35a0987uYJiofZgo6VjZDYOSduuFdAIavqfKH2zhjkK2jsqVudHOR3IGcnQudJNHZmyQnJXMJnsC4geCsbTVeAFoPnngK3M9OouuwzS499Oh7wZ0bQXPxIw/cO8+FFL7vgfS18bCWagnwf037kvCPgI8FEktTFo3ZygsCzcajhP09ZcaTBysg6cOIR/dY7qWOMJd9EfGArmj6by6u7jpIPN+oA0kxZeUqzqThdPADrEpBooO0XwP1YUL2fop6JEWUG8FvdTULnxCMsuFx4jkfZatvLMJjql1Zr1z9pIktL0Uin06ffunTSJ1s/7CvIpxeakc66pnVgJDUTECzQjvn93JvV28mqqbGm0hPaKutMtX1BSpDA+bsnN5StI0XSFsuAJ5qMlQnSVMTS4GWhEx9r79B7zqUvFdedE8Gcf0CjgBIAsKRbcaW/J5diyRdnsz1FqjMTLKPWtpRKiQWQ8oOcumxiGQy0KFFvQdUy3m10KVhdFbicrhggyG7CddRVgpTakbDGxdDIBQbB0XIbQ/h2eQx9Vv/sNdrs0lvdNjrfShqh0raArm0amCn7Rn22mw4wbbQDvkVt0Lp2m6n+wPfJbQw0ofOPQMdG0hROPlaZZRkfIpUV7ToVv1aPSx7rm7AmhYVzYr0+y2tEDtGUoVoDBcLjaDPkX2rJNciTJNkCMT3c/Th+wZ5OCEUgehP6fxS1S49FjEnNi/PQg6oFEFYI5J4ZwW/lVlFbE+6F/OBPd37gC89ByJSicC5112KMIh2AkG0CeUSSk2o1HeGMajyCC0TZP3OwXkXH1fS4yMDB3muKsb+L70krVIBUOJnTMXHwvNex6aqakTK+pljKFVjRC4IuUFXyjadaOMAU1RXy/w1DGlKra6M8Vnkjy8N9yldOTYFNn2L0/NVwpo+dn8LwU3zff0KoU3lwOA4/ApH95KvkEdenR4gmkP4xXWjM8R4v+qjqlrwyG3yPLZOSR/hYtFqQ9Na7TTQajGv3rnN46+2W3V1uuu56916sWLcmfKBRYq5Czu+SOD+MdITCwRp9gjbenbxhg37k0lnUD1ML07qIUuk32uJU7h0it1LpavnNg/ZbIDNGCXSTQGtx7WbRzHzKvEug15/1On1O73+ZW98POgd93rd/mA4Gv9jO0yiotuf6khCOa5RZO6P08Nmfq/PXbBQkP+0Ey7ngKVVtpJVuIpnbXUXegI+YPwZyZAyY3umnogcnshc8fwHpMEgo9NS1q6D8ZB6A8hOIY4GPByDe7YKV9J2QkFzRPe6q6s6Zr9dIRPKVevDTMYJ0M3CH99f4E+qrrR2L2DCw3cXkp/KW+f9xfPNRgZdQxXyQK/wPuP+6oZ3BlqSQJtul702+29Y4xCTTCm9WPtfQLkPjXmw5J+kyrVPXu4wlTWZsxRZdHXDkYD8kRtthIGtzfgliYHk6oEZhxV8Kv/+evoeor1U9EuW8rhd27FPVekzk6h4bgXbu7x8pWlnXp5fyJB66omQBocH3oF1FJT6n5DmBt8gKsRWEiLHY0czOa4DKZ89z2aupmMY1ntslDOCrKIwCR2KUQiXup1O3IYKVjlJLnkG0sSzNv65eNZmzy5fvIU/Zy9ev+28PTv/GT68f/m2A188oxPxGVCRP6u+4dDRKXP9wzeGCCA/qnSJA5/W7mrqORiDFf5MV1RsvExWNa9z1C4Uh+w0cMEFgMR8fGYgigr3gfKsgZe+F2pf4LOLN4eTXl/a62pj7DPX3qTT73f6/cv+8LgH194/6l37t14E0WJUwFUJKC0uApmOyXQgmwQiYWcvTR3eXMCzBnZ4l/1XLgOaQbgfhzKVUmpxB4/qDUDZ8WQwckei0xuNeGe0WPQ686Hod8RgNBkPx0N3NB9Z9m+VL7f0JVZeVbIHRb9ipYnNOBP8WAJbkYVSEDtgOFE+BeR8IdXYLuNLGIGcklcXjyJ2Lg5st4kfvmqG8oxPp6jSBX9DlTZP/Oqayp3wbU7qk21IQXslrKB+eA02tyj0p3KFTbP48WowoM6ci4xtlAqiOEzDNFwo12teAjQ9gbQw8AbPHlfYznJ4aSUPb9qQlaex2h0wxu+SuFHXsh0m15r9i+JxG0BqP2wc146kb28yvibtGtGsHvR6Q10t0cKTQ6a6WN+/O0NKyCxC4IETlbbjw1ZllcNt5XgDxeWHfIiOR51uuT9k/fjpIbGE7DNPkHdbv2sOom1/ZutzlvMpXSKbF1b1sVO3SeWFZF8HNctTOTCQbn7+rR3VLgTT8vH9i55Y5lbL08bWbLuxoB5wAC58bqE+ukTNMogOaBgN0f6JUDP2KrxerX0fRqJOrzfca9nrOueArH+rlht7g6Ho98aLkXDE4pC7Rw4f9vnh8GDg9pzheJiFZQ1LydiKq6LC4yav6nDN1W1x3paPcjd01ksRJKSbX0d+8Q382bg2LL+R+8TmrbQKPYw3Uyyj4LOHrU9rLfAU23Foxl2THb5SxcN5hu3yeiMSV6xzrATjyca50ytWr+zqYVKpam46TL7pBMy24ekUfMxTMDffDzgJIZTIjp4PcEBOiX3nf4r7sw3um4MjfjRY9PlETA4PD9yDo8Vw1OvzUT9XGrxvNpV1dNRfLBZDd7Do9w5H8+FouBjzw5E7P+z1F4IfmkX+uHY+iqS6vJRMpuOH17GZ/RVYUqyHngnZ7plvvJ6ExMqPRmFvI7HwPlW3BVQ7+hm8b5AP7//58uTy9LPZuAvhRCLRU1Bd8OHkaD4R/aPxcMQnB/0xn0+OeO/APZiMjgbu5GC4OOwPR65Z/qWyVLz76cVwODyyVbBRnTMYdHqTTm9y2Z8odY6qIr555CcfVrHluVHI+40/9sqG81t+6VXOT5NnXqGgv8AbrzjhWz/wSreiURMoe2NhUUGaAo9M1DXY2FIduvwxVgD8BWJYpOrxt5eK3Iu9DJ34w14d0q/reF972MLHDhH77m8IVpI5YwvqdvMXpXenJ6X5i1LF8fk6FhD5KiHV4FTcwuhCCm96zRNxx++N70Cqm+IlY36Y3gL7/NyLw+k6FtGUa3u8w+P5dOGhjpOaeus5YroK44QC8iHZNf7waYrmFomISXTfPk1lJvT7S9vi+qspmL2D2HOmTrjycI25QTxdeJG4A88L2VD4Tv4TvOv8KWK50ZXLF1Fi+R7aN3UFGJYio/u6YP2NGiE3MD9JM4f6KBXv0vBhzoK3ioWj2rbk154znV+vsl94bjwF3JAe06WzwuCzXHdwGSynC1AkyM+BAJkL0tAnMijwgPv3iefowQCq72l8A2su7VHsBR9vQl9gJ1RKjNEZrZdGsvhG/QjWtDjxfGNu7ni0UvoF5wYhlerbJLwG4gLjWzGPQxBy0gbCt2H0UUTxNIm4YxT8B4/4H8ZHgHwn0TpOtNlEoQhbhdOx9FlC5wMahWjxQcuLB8V7fF8BgFuJkmSDp8ce24vXzg0GxwhYPGRzFNyU6xacHV0NsIQK0R8tdYLM+D4a/O7G+SOdUIyGIsp1LpT7mRVsrwWcdeRl4cLD4/395T21Ew+j/0HvvX9bx507ESedQfZlN+od4dMuhi0HppmNY9ixoGpoFNmvYn6Bs67Nsoj2lg5oRAOlrg6ifUrt4P/f//5/Yybca2s0hNL+3sVwHEM/8wexF4AZJkHhef8u3ldLaP/oyB0d9Od9hw+dwdBxDsWwN59wRzhjd350eGAfn3prjEKAPwKBx7+w1Fgl9+T3cm5wcDSNfE2MOI34kUzppZQf7SdQxOGCTl1wJAPcP8O53T2mvMX1wkHKJkGDp4ZuqsAXiDyKa5+C1KvmpP4IIG6jC8VPMkAuIgbW8RocL7osEiuR4O7X7qnHwO+5Alxrytt6F4H3GYa2T08reSRKykwExgKuSgr4hK1ygHYRof/GQpKskBK0xbHR6BZgdpbAvGAexa+lzwZaRKG7trOiyf1AopnNm8judEvpNyAC0Rvi7G2b/vGOBAMgV8t+81okN6Gb/e79u7P2qXstTgNXv3Pxi3fyRPnxPhFx5puLhCdr+uoi4VGS5nvH789elsIU1AD4SRmpHf0W5xDUdE3Dl6l/tLsfIslBeCvoWEf/XzyVU3Zdg9ikTXGWoJDffqJatpCtZfs2CdZ/XrXwur5qHf951eKBewVPyKvWR3F/1Tq+amUm4C1Pbq5a7asWhbcOI0yiSHXxFwQB4tf7ILx6zhWEWCopD6a9WJ74PVeSoVK5ghBJnwvruDBntmv4p3TG3AguXfBdIti0JvGl+dvFkL0gDGCxe0Ghfw7X3dq8GoGLASJ1SHBHiYs1EaFKEsmYvXwZXjDKqFEhuBRpFV4artZenPPNIi9gU4oHzF3uXaAwpHbBe6Yfklv7AetBwEYENoeULOWDK1aRcMip6i0RUyMofMk/TdcrjBP1t5kpdYJIJLjbZeTxoytiIKMh84oBS4zRl38uEYfhAgcSVhbubeMGQBwuQq/SApOQ3XjXN7IQfRoAysfnEXBG/77mQUI0vfAeX3LfF0Dt7QN+01ogYDyoPFWUypUtS1ZARVU/ub3rm+xLW32hBjYn0KgEfnjX9CVyLZJpeBeIKL7xVk8C4m4ERJhjRSBZPs14bTg3sFaCa9FRmbrJp6QM9lpmBTSLLcmLwc6rZday1bK1yGpDFconmecqNdg/w3k1y3U51EtW8g0ZjKlF9MQjbdU/w/nm3WTTB9TZG5Y3MJLTK+mxThkyNeZTQle9fPK6J64IGValTk6Z2oj3UYd5VuZNc5QZXa1zMH3UQMff1ylXgDZUBzqupzEvbIrtT5XSqd25Of27mtbSy2vL6dtu9j56QQnWHH5JxUK2pzw0npu85dqxHqIsagfwV1Q4SsLw4oQv2EupUocbJmZ7xKJRUHCSeLzhrVbmZQj/dAkgs+tADGq8fMJgQ0NsXDzvUIkRpwoOooQIIyk5o0wKzuzkyZ6uKODEkJphyfqH2Q09CI4oLEMoDcshF/xBr3/Y6R10BsPLfk+aqWFqct/36XvlEkQ+agp3T48FpaK25dTNAv0L0DAEAikL18CSgl/8kyjURKAZ5GD6b3gMfvuQ7p74ZBRVpVkjxt6p7XHRRKBOlUJ1J0t1UnpNso1qs26qN4O0mXRISErueTRgVKoaMxiWzBowHA4dwWIP/msqyohvER04ikqwfIiSHY6iRFXQjrBGdy17ciKJQbhOVoBzpeyz9In5ImP6oAZj7KDYYO8F+yHzvY/akQ1DxFAYVOndg6os6bkT4zwsvWsoFZ+H4VK64hMykq+8NnPCFR0568hnezD6+K8wooUMvyCtsmwUupfhCxWvA1B7tCWFAJ11uJQ/CgExP9iSf9ShVDA97Nn7cA1EF/RmjUEJhwUI1QVwOYvCVVQIWGu1b3RSfmbzaKRx+TdU6rW1jrGo9vs/9ajF/xYtHITI2J60BRtH42WjZNonkW8L2WBDHMMKr8xtBQL1t95DKQVW1HofyeTIoribJxaUZZhi6hShkn+WQ2FaTGrlz2TSDzWLPrL+uy2fGUo1FXy1StIZPrdrBQ/RWoHP7ZaSA+vkwLSwZPKyUJ3M2UyqFH1D1y6CchiIP+NuqlVILhu5MSuN6Py+VjBNeXLk82XLQpj3LUeICXA2bFFsoYhsDWQ626ZgldMIelenBEwL0eYy93rd3LlclYoD4zh6ukC+ss7AvBp2cb88aQq+gKYgO2nbzZntYCwqDCSMnK2R4xJwPSin+/CO+UOQ9R4NRcpMJO1tSiSmJ6li4la6hNmYvf5xRka1Pvv5x1kbZPRZb0bqBwpA6iXENEe4C+A9cniA7IoAMmJSd5025gcSzZeCBxJ8BM5UaAtSuKolILqU6Si54ZIugzoAZVi15Hpmxz38Xw15ud3iwT24Uf/2p1oJvQ+Foj+3/8zi9FX5Wi+va8znLJlJ27VUPqkqtcHsqBQRyvqXm878RA57OIlDg3RwbwxTAzT5z5vNqqS9TmdWNy/XphoTjSyR0Ksb0ERFuqg4nfXqqR4+0iwPM9M7rD+zhjhQPqEpwRmMiO8FkvkSB27DVML6w8nst2HFwScs4IGTWNmkTTOpuL2XQLa0EBBalkqoOYv9x96tOV/DDbP55OG4jYdjKpwW1v4bqczNRGn2SUuHdl6MzE61dDMIh/X1NXEc6hVMzNheTOSysCS94Bp0tNS/NimrUJ8dQkgXrKANqZf8I2wJJnjsEbJJ2kvvSbmUtb7aXC5TCFDWCjruD5opZ4qye/GwiJNo7SRIqhIJ5JCGlUMUorkH1KzLEHBDcC+t/ULVD+lDczlmOR2wdx2EUQYVWbKsXvzXaWfQG/Q7o9FgcGjFOUrsH4F/sAKMgkzRJBzS3DqEA5n9tz9nilZGxyyS5wqF+ZA9dyUv26c/Z1ahrs7Y40k2XWlfujyRbCTjf2O8DGRZB9MIMfwhOyWdzlvCGan2eL3YXDuQ12HlxMH78LpJBQhuFUvPCiVMq/9nCHTeBKE0w9eka4SYzWZ0z02B0hqY9WYyiPLDmoiRS4rNe2VCO1V4k9AE4KtFpIxftL8I2QjfL0PYO7gVCPAahApqBseI6+LqVHptsgC0WYxIKrqB9Y3p+6kNJZaNgVQc8ZOJiEhHngl8uhWxW3rAarxqq90qapNb7RbBSD/g1RGBb8l6rp1dNm5RI7E+D7AYl2CJSMrEI4PlWwKJNyL0tFvXtltWHpN2YrZsjEFKimEAoUvkETIL3H/GcNoh7XJ8O0tlq1izcUsObdUHmL80ehjKYHHbCLugKK9uwhiiFKTVdtlFSPbGJSfRDYPXywuJppr9vg4TvKVguaTM6DroQVrcBmAc9czkmFdfOPFtGX2b3LS1TgLcXbGIaDF3VAtpiMh2B49twl+HVlBRnSmWTXrAsUwlPLD+rQ/mndSuTtGq+vEKjZlKiuvVaIEy62mPSrm6YVFgnEH5wleBGk7S8w7xBPIA1cWnQbmEeqTNjEN6pribzbA7yBaPRwjY1dYrSIMuAHAOL3mCTlrs55DNEvEp2U/vDrjcgRsMng/IzMYjly3WAbneyR0Ez1Zpj4GvwnAV4+HVUeXEbSYSZ9upICTWNLJPQ+aswaS4wZHkEDq18EMyeMp31DWGUpDKC3qv8YQtwzhh/S6ECaICvFhyXZI/a7iiaw6sEnRKBCD8XfPIReZqFbBTxhOYyTarV/PMdKe1Uc1pGyY2F88Tx1/H3q14rR4q2vJoZZ6rM5DauDlV1ZUvajPKG6Wmc1jbR42zfB14nwIehAD8hn/DX2k9Nf65jOm0lx9BNrado/LQVGXSGwdiEqX2WF1g+m/ybrTY+yqU6CmiWONbLQ8klYjpRCwJPwoUTyB6W9b9UJe5Acpp+V9T18IUzmh5oeBvBk7JM/aHoN2hGW3oygDJQ8KNKCTJMbuSW++qdcz6UES/1/vvRBNIeTIJepTiv1PImJBlaHJsqoXqh1gWdWmF56rQGWUwXSvRyEb/xapGYfwv2A6Z93sZHVochw7AFlxQM9ukZykTI/QLn9EavSAf0ml128exLrRcGhkWqPiWkWWmttPgVwVLMjKjIl9mYnvvfnrBYPtZkWmbiUQmnd4h0KH3BykvbJYIHTQzzazpZkezlvW0Z1uUZGRvZEc2C8kS7jSxLJqlKCujjNDUbOYQNbUMXQrit5P56/cu++PjYcn8fbbvnqlSzBXProv/fJVpNoVxZ6+lhnY4YP/zR/LBISRSJoYhZz+9e/OaOT4qNtR2wvigDJ0LNDKp+AKyHBcXp69OX1wyjRhi+J6jOvLMBRns/cHksPZJAogNYIN6cmypa/HL63hx+MpXE60Tmay79QRv0tbWtRtmph5PUlVLnb66Wx0amG/nx+DDjrDc8OGXbeph2XCVUtZcpijpwtXJyL8SFJsB6Asi7xY0Iwr/qFfIs9g8PLrsLPW5hej0gY+nEFrH+JyeXhmOHGXCmQszqpGuh86xRjQ2TRTX2WkCGNHTebLdeVJGM0+j6ppL61nMzl5Wi7mjwW5OitzOLTHjOOs4CZci6hiBpXXC6sX3TrjcSWL29uxM6R9w7WIAYBVXBQEKTUk+SmQgezQfY99uHtr6Dng2+XfrleCngvvGRvYHQ+OkrC7LfEmq0NzlExYPO+IT6HkRc4Y9mCZltLhAEwnPb8lyxRJ+/UBvQ6NSqxbY3MTSOQAa0YmdcEVYf9kW+U11c/7Ixu2UH2UJrQ+lcqZ94F8UtgnGuwcNh1qgMk5SZaMi3DKdleflGV9LA0cVW7iKxK0n7urLAF6wssXCOmGEF5MMyKh6RFOCrIrt/cfFm3NGhVrjIOmO/ZnaNY5b/aPD7rjf7UO0qla7yNBQML9aDCHH/YPBYNyH6JcGSIeMI8ctPndcscBQWJODw6MeLC07xFtpBH/3txeC8mfx7z68pXFMy87edIqeLlTrhZpbiQFDHQVqZfQwusbCjLvsP9ciIrUtT0CR5q4d0G1T/AwWhXfy+uFqWeMUyRhPtx5n78/PTy8un8vgRRiLjCYD0THSXhOFd112Dm4sUlajtwApcuEUWpNTCxVeMBkUVC3lyzK/nTJ2wqoNVb4LimyWO5AjnuDC28OFGx4428OBrRP2BAe2TlbzSXn4nJDu7enZrp7tZeN0K6K41gFTQw3txUwWt3sddLUOs219CGiOEPWgSUNcy3ZaHwa6RV6QTEY5g0iGZNwYvJyVjkK7e9zXI0KGxA2I3Ez5ZQKzLPHpnvhy94TeJlvfF6jahhPpiSVpJ/dFcTy3vjZ0UU8TshPaqn8heqn4hkfiX43Bnxq9Cwr/Ykl/AQ5/6jRppeySzOx/4K//hsBcpX9qK4QjLhMJzpY2zTXFsMdcMyYJ4rvsAmkw5EdELaL/COI+2xr4CgAtHykAr0Vi4Box0usCmUdXJEjpeJu6KoU040iDCeIE+3fW25YHjUZG2Ih1LgD1CQOwp2FPzxGppjEqiuCCiGMi9Ey4JB4JjDzAwUfhk0F6YUSDB1UjQIlUcHj0x+EBGHFCH/ZLmguVEeBAH0ZLRDIr4bLLZiJwjSFRjCQLpOUmdy0meOR7ClsWhHcIhVFZ/BR2NkOei1mXvZTz4RieffQbufZl6oTpzaDXQOVxE66jbk6mBZ6acWfQS3lqWqaDTt5zpeAd87k0xrCcxDLmX1A0z/YlWbk7k8fR/F5jHklXA7A8wrm6CDvS3MAEq8MIgLE2ZeA8hLciijxXZBCUhDqXwCUJWEPsXuB6t54LEX5TwDysIh4DGbMW03kkjgH09xrAf2l1cuvLgNfk7QhwxlxT56g64on66ZajPguVVqowaLr69w9s0GU/+ZABz0jY/uhOmXq9YDBi9KcA7tk4iQRfsj1vCUp+6lgSsh+960v00RGJ8/wHNuyytyLCVwUso71EhgBfRSEcWu3UvfM5MsDM/ockQ5kR2j4llXHblpH10ujgcscV06CjGUYvgH0BUFFohPR8ydaXnncZhKwRghy7j1g11Sw9iQRzjdMdkSZBqCdcrpzliKdNBOvdjZeIeMUdkS41ZevCMpE0nVYLsG6D26OkqFIeCJFZqxsKGkLAlYuIykx0Zr1YFIZXn+/5ka9Jik38NVZHgxr7tYEE+nFT7CnELJcyrOiKkYhNvyQB8TxF98OMKAGMyaqLSHjcPxp0e91Bt49EyNhp/H7Ud91F/2DUW0wORqOBiz8XR+OqddwfDyaH/d7g8GhwKM0Nn6+C76ueeme60kZnxJM6fpRVwp2eUaAlb2VmPOL3lTbed9yIFrKB8DQ/PlkjW3+SV9Rs2AVlgFl5TNHP+WOKK8xsuIBd7txQaHLCv2YORzhbZRm9bn9GpG79LGBWefGkuUzAecQDN1wepyIZSLMyExwXeCFJc0cqycmy6UKS4h5mQT60Ww5kXT5EQoc4LYHhTqyPXG2TKcqnWIZxQSjR0IDHS0ek8nLb2PgUfmxUeBG2pf+gHrneWMo+1IqDWZv82rSDGJfh68MF4JFTl5db7uGjoU2MYZ+8JTKGkYRWHPhf00LhUEfnbd3gGGjL62Rq18lWHVq+Ipx89XKGQ6JKlkYXPJKl5+LaCwJ0kvp2JOoTCdVCh2i8Ij3wB/Y0kEp8cgTc7f8/e+++3jaS7Am+Sq72UnI3yeJNsqQ6fc6oJLtK07asY8ldVafthZJAkkQLBNC4SGb1er55h/1rX2+eZL+IzAQSQOJGUrLo4vQclyTkPSMjI+PyCz5GcYf6IHVnxGC+6hZdhpWCcP8RBOE0HKK4ET8mYm9HCZuAaUj2ycWJ5LjQkHyAJU9XVj67hAB7+x8KPN0tocEMQ9bljonYQSGJKYEbiRCTyB/KeNQh9MiVF4Y2CJci9g5F5CSoQw30kAEeKo4BL8iPb1JWciy1zzCZ2Q9pS8nrIFuSb09N0J0SLpJioCp/VMNKREiJ+CLDSuq2WpNn9WvCeGMmtC4qke3oMZNuZjtaRdlY3sJzTsBZu8BPr8QTMA81OrzH3LCmStvtUdnltjnUmNtOr6Vwk0b0pM9U17Ok40nx3Bc6MOcM8Ay1DnPwV7ifsQw+4fm7vpKb2CY+/1KmJ/4gGR7+Wpyo6TleA6ssQj+3IRZo18BqDe3MmurCzKwdsyGHlBN6eMJBKEGgRDUHPmfuPbzWz951yIdrzSYlo6jsqN5D02Juf1DSfvPoBr5T7RYxgfFsVzWBj5x7/sqvw2yTc8+Xc4UtjSDBTGSE8WJBg5bElasLrUEuTOSXKIoZbQenqV9CeHq4BtcjYY4iQvW5RFGN73jpyw9CunvkbG67VHzBZHJu8nzhjD8ZV1jljdaWNrPYFRZzeXZTDX9groViuTFn1InmnG81INYMe2tBsmk9RK7lnWtY5JyRi6skQaZ4zMxBf5vyS85AQ0JnkHYsqjyhw/6o1+8NBqPeYK/UTTvxrkcn4eIlAI8mXJ+qnt4uySs5rwLOUzp9ZfYNdyWj1mvQah2Q0G4Pm+1hkyjQ7ArFMSaEabmtj+CA883I9Os647Q6Xq1dAFrt8ma9O7/JHd7gTq61kfq8Ga+wqjDIJxkW5OEFVI3kUk8+eag9RbGmNreLks7lzIsBbgvswZSveNo0GPZPyBm8SgbNiw6bFx01LzrWrJ4iD9bSOrytNHSmxhcoz69KUak57UCLqsTqU8jRC5kqw5ZUmKmptBSKaOX2LWFNpaUoqg2E0TcEFTU3UTP91obVWwVv29yYfM1YCvID7FqD97dDJ8zRkNRrNGYDjBQNZGJqYW5wSRr0QVAxLTLSB6DDtBLrBBiNEq0/5O7lTYIBRbaLRYOYa+Ip+en9qz9fnL29Uk8PJoh2QaPKVbbKJ8qJ3fQWws2gOY5dcacBGDeIIkP3kJBQC+9vbkB3vAiLFgxte4IaC42Rm5s3Wq+hRGsxOFCMIIdj1QpS7IlRt3zojLrtxr2DlM01XQ8pm1tBu2I7BIZxmx3Ry+8Qachld3HgxfnvCABkHpcvjIwcjy3zzmjAG1TG3wDcpzYSo6hahDeD364aeB5DNhDJtprXFHVETox0h1oIfWk9JNTMuWsjO6YVv+AxWa0ZW22lvW5R4ubwKzB10Wx7eYqacDwjQGy8X2k2ubpf1EMmqGvv9HowGo0O9jjV7A16+D9+gRrgTuiaS+y43+uPxmKHcn8fcpNy/s+DsVzCPc9lPeX/9vIrNEonmm9kMDw8Hg9fHh4eHxyND8cvi9eMgqNcfZ6U+6MdgaIkk4y5vdpCrahIVj4LVpeuZGVozwvaUpmI6H+goKC025J5Wi1HU8kKw2WbWS5uJChuXv6kZDnyZeLwIabNVSk0tTIL6BN0drN0mSHKetTbR26EfYQXwgwF1Y+mRraRzl5kwr+xBf/OAsb//XOJ4ST/GqhdE5QjXU/x7YYMh8JFtvmaZCiyrlMEp6ER97GsFb5GqgNKv1L2yr9gGg0EySJ1mtSPp7Qr7ZQRKUQ4ukL+VLJ/c/PmRaNmPZ3TDKBRfzi/Qs+Fm7OrTibRYhbhERrg8NUguudL2q6NcXko1oc885hwpuiRcxXXmPSFl//c8zhCK5kAwgr/KGBlEyhZP/Aiz/Sc6p3sq1L0wcHooHIzi9dXHgxU4L1a7N4W8JZc9np/cxM2lue4eqNkD/EbKn95MoCLq/tD9CaCH8plN/WUy2uxpONWhrYN2bxUA19q9FrF2KV7pBdNaDn1yGwGyLToXQ+PjzCyTQmmAEk6PfCrmUjkg4L2SQcHwuWRRxZE0mY3KIDw6VXua/GhEXJ/ckmWgh7H36tECV6aHIGZ52lW3JT0polqY1y2pJkk2kBMlU+40tL9o3iSFTPmzmrw1FaDLJtZ00igN2jnGCe6v+L1xwFWpIIoz5FLL0E0RBUD2j9ksKw0rBacsdlxn3andMq648PxqDuZTMzumPaZNZ6aR+PBQU6/d1joPCPXFnxXOU+CuSn+pi8wOIbaHINakTAx0wzq3Wr0S8rFeJALs+eju7dDm+c67y7chSGApXIK0fKVOZweD/pHR3TcP+wPBsw6PqDMGh0MDw4P2ZE1NksiNPR9Z33NHucY5/pc/TRXNFR7ynTo3OtwglUZAY9jWGW6av01fdCqqWDzLp1PSgFPvLGPvRPPNoC71dY2DuZuf9KfIrD7qZ1Eq8jiMaz3T8ui07CI6qS4ECZRUkIKtp+2+bRvODZObzvJ9+kuMG27PaunICHTGDLVyWokkHRoFNprpVwvb1eq25GjBYbtr0isaYtKS6geDXx4E9rmqscgbTnTVgkudWGdMlPLjafBThcXvqiVoo4zoeZdLq0NhBU73gORlEomDL7JZEBS9wYoiFx+lrm15ui1gVGMIpSKK1IzrfPRYXJDkVCLT1MXxZaRr2sQIBrRi1ZJJCFr6/2t02czaM8AnVkCxK42pmSDdR4I92NydnH+Pomow7LcHRi9f2CLMN0Pz8n2/WgoVQci8EskC1LztVVPL6sjWGtCayq6mizZlwbj4dfmxqGRvsb9ucairasA+br3pZaNFufxjmOzJloz7gIDVQivIsxHLrk4Rz187ri3gOguQ+ZjanfVR+1gdNgfHR5Z3cnoYNAdvzwedOmEDbrHo4ODvkUn1uig7AzqGdml4rrQeBRvl2rZkv42wqT0HtHqQJ+Mi+Wo04awf3EHp1NtSY6Pxu5Ukq9keJBxsoFXSRx5kHHCNKh1D38OMbXwyqOEXo2yRjH3rWs92FY0N6J5wMK55zR0aS/rS9cguELFAW0CXlrdeNJKC9/7vL4G2mmfh6l6XDnPkg0tZaE16AGTcRoowq3ZutpS0vIaojRfWd9IGvoimcA6DUq3jN9D0wPMA5ENr3FcYlm7mvbSXtqY62o6SKx4RVjDMiaXLGCnlB2Ila1kgvzoi2rQbwsp62nZUM3alNVrPnss/4eXNSsIYtvlz0r60tjPZpBPABJHThEn8QHfxZjK9ix9QYJtSTZJHYCCk81K19IrcVJRYpIQXzGAZ9iUvIXBkhtu9EqdxPE75qeyZzNIQSAEq2z8J7xe0bU908rK2brb39nah3gK8TOxMwqGNEV37LAEJQeAsNGZxQ4FlIuSkBzASuR93kEne4cFEYSUJLlXeOJ6N+oR6UYMkD/8beARYc+rBNcZYJqRlTUTuDocZ/y58cxtFt12AtdO4PraAtcjyFrqQdEoMReow4R3OPotAlxSch8kJJcgWyb8ElJxAxKulkNyWKipDZFJIou8rP/P2L6nDqiEAT3VTXQPUw/QVeHtfyQxnv7+cW+wQOzBA/6fQV/8V/w+FL+PxH/H4u+H8Psn3Ws/dbkdLBSHW/zlAP4Z9PFf/HmIP4/w3zH+5bC/KMNjangc9JtwcUXkjvMdgHt+4bl25AXJ3QRAfHiNvZVYv1yFEiCsFkoJqQqj//1wjLlpyQEgwaWofGmVGvdFRR3y/WjYVq9bYAKb1nPklrVWx1Ghx1ejd7IrzEOOeuSaa5AgFJ8G1IxACDrt/leH0O7vHdLvHndI7FoswKNO9o0XHWLRcE72uy86II7YnkX2ey8EDqvtWIzs/48XPfKbFwNI2v/6n/9fROb0HrYUUWCJKrShvhG3cnhwqIygevsWSz7t1hp5/ZVTI3cVbTvPWfRaW/bK377ZpeHit7RnQXBA5OF5FcCU3FeMt4GiPMlwdi6TxyEqoiHI8x4AlC3DsjzBASo3nn2mqoND8nsYT1zGf/BZAD8W/B5WWQp9SMTby7fiBln6NePl96My4JToOunHzCqsxoP1kkN23G/YPUMET6UU0iXsGW8A51Vz+Ob2bK7MyPEe8O1o2THcIvh1I4tfEFNyZ5R7sQvWpgyfUJc6y9CumQa8ppRpiF/FWd/IDELFHfib0IBs/I7b2/ki1su44U6JJkhlq9Vl975pgOVvt53pSkTeHXO/oZ3l8ynGBsUASx5JMQ9LCbEJkOnw/v3b1Rl5jSk4eHppkJ2UStV32X//5dX3//2XG6zDm0fBWN7zNfdVjgXWBWxp41J5eIQKR84z5CSCcgJ9HbJA2NXLxVjUMs20KaTR7k3gq1QA+3QGYYIy9UTaeW0XkGRY281lYR4g+2OnzZofQrgQIqaXBfLyBUsSCSWKaDVzRshoAGGIFIDC4VVU3WW//6X0pZg3wWqfPLZV+VKsflEfHffZ4RRiMUYYizE5oMPR9GV/ejidHJnTpi8136R++OTRGLzXjTDLYlP1AlTe2fcpgX03LhXxBXgcuUhLHY8apfE0lPGMYblX3JDtCdao3uHVwzUaMIKtzcTXkiQeOVDjibh3IYeFEpyx4WCMr32gv07KhRJMuvLteaJoEd4r/3eyjJiBefT0MpRQ06pm+yVkKYQcIdSP4kBmfOGZ3Hi6O9SdYpnbaew4tzJIQNTQAD4oYz7oC61vCici/98KqmB1rk+pvnpWEpiar2aFrhMJSILM4kYBm1i/MaAPzl92MmIVB0souCypQN44hg7ZJiBLBOmrXAnYyZ7eJF+TQKIxObDsvhdY/eELzMxEFgBJ202Q4cn+u/fnL9Y7/Ro2iz22e13xfxV8HXSs1i8RjAikrGQ5JjEMbuPTCEcn33+PA+vyHv4jYDPbc/8Sh13I+dpVsGZKJoSEYiTCogbAFkvIEC5ujOZlJuBPNl9q9puAHJuk4dzcfC+9xK6ItjTGc1hObSfiGTATSAa8bMjMvmduj1xBAlwwn1v2dKnWwPwFSw7d3qtdKl7JuB/oNz2/BFhatXPydQA758KPljzlgpwOxifwmlZ9KIlKhSLGQT8mFQ6qiETLO6/DLBr2Rr1xyVlRB6LHq8qPAtV0Zf0X7+mjktxyEmWqZCvEV0WgaNjfob47Dm9avdYivcZjLLPovnyFRd8tF3cwHJXlRa08CLpIJnRaOS/j/5VzPzw86g9NenB4eMTGL+lwcjQ0h+zw5fiQjQ/6o5dFmVd5uFZnHSuZgDedhqwM2gVmIlP/EV5SyRKI4FQC8Ngj/4xZsCQQ+fpAIbUjTF8c6VQTqPjcOpAScDieV7EF4ZGETFJC5whNsG4deeY8SOFDI9bFKWWddob9bn/Q7Q9u+kdpasH2S/bgsiCc275hzqnjMFd3W2A2YlmQJAUxsTPe5iF3XxKrIW7F6ptaNtdNmuseHx2Njl6OmUlNUJuaR+OXB+PR6ODlMT2cTA+mvehzVMvNlQn9wVSlK6lk8oumeuTvhOp6oVpdOTzL9bSmkzVX3rlCY/lpFgq0mlLTh+4jz6mzJ1nNWg3rmF0SyVdkeZyPYTSwJu1eTsIFuq9meXXsreY+RLhnGsVlYgp+k1KChlv3yBl/p/nMtWx31pGHE8RlIdhXv0rSAyP8hERLex3lG29pjyv9Jgs7iljJ8iaXcXoLJ0EqYumBhVBLeCG3XnDtHfmlA6njbbhV1xtX0soqg9CFGIvdVdetUzxYylFocZKfys3iiS7EDV9026ydzs9LkuWzuY86eyUy5mbZeN21px9G7cIK/+gKJTdXSSiu0abnRtR2uTxMy59M5S7LGeX1mnpriWIttRBNHbw1WosCmmepfhYpj6tna8kva0RYmSiUZr509jK6zpXbVJLBajjxI4g4qR5q5ZbTVtLwtPVXN9MQcMxlGLHFWk2KJsA3CHBm1x9j2owwDKwYjZZpE4PRcrxFGa/oIlkQlfI0JFPLbuTRgd+yZtY1rCW8yc1YXpST/aXxbETXtazgEU5ATiW0+p2jtPMHPliI1MasJzpbmcXJH7UG1KeaCXf3UNN7qGA6Wrn1bEuPc8WtAMOT03krOXdUIWnNI600lnm5r36seRPYmJeom9Yca66p/KN99XaTVp4/T9u0sNCYL33Fa3Ejp+aR7tbNnpU/HDk/whVdR9HfmHZpC/ydtl9j1VyXnXPAqLCZVumqY/fO9R7cjK461V+LlLj4fnPvWRCi50PyWfmjWhI6i1hW6d3mum2lfoa6PmbxLq4Jz+gmmt2Qe47GAF07vdUV/poJcdyjldTrdeNMOLiG9vAb93oDP1VuRG7nz8Q7F+lmFBrM/r1pbHuV2NLEY0kiLZA0nU21b87hOKOFlL+vo4XU3E+PMfRRZuCj9YetxTzAvHHZVJCJQ+TtNTL829RMJeYrFascGkQcw6QQeJEHMP2l41ErFDgXbjdXuYbp8bsmpbfkD0gr7ejtqwRCVmvHNxMJWd/HeqGQle0/UixkTZ9qMGSSWIr6GrzmsziMIEufD6jLUzRiIIiJK3Hs650YlfaNhs8MI1fnS2dPZr5rJtlhxbQKZrk2OA5KiwZkhTYIcVhRqmaEP1/7jrP12kjuWF+rScutKeRZtyPkE6cincGp7+/pyELrCMhxIGUmBCCQulxt1DzsWyOrPx4dDMdHw6Njazw+NJllHb3sT8zpWO1bc5P9aFt2wP23qENOz94Q33Nsc4kE6bLowQvuIPfcFBzOxaGnJLSjBpjtmZ7yHZ+nvyWc6vTsTfVkTx2MV3c8EzLjiVFNWPTAmEuuLi6JL9m6CXhR4M8dYk6LLyhpgZuhgZWdZjB3Rr5S80d9Dn3aoa7RTLNgONTtUtPpygwdCaAitDFcs41mkQm1GwFrfUUt0iVnsNDvxULvKc7FK8dKxS4MxTL470bApsbRyyk9ZgdTdjw9nBxZh/2XEzawpgcvR+O+dTw4xGMZuyotN1unXJ0MA3e64BHcRXA3jW8/d03hXsMcM46n/61ct6P+Ub973O/3M8eyK8Ck2r2KDdvvSp/qRi9fw7StQDEoQdeGxeB1ZT2OWmF1LcKqLinI5bYJ3gM3AYMr7N0ufN1deEwF224Pmu1B7Ld2q/oGZYydtLB90kIIAU4pD0not4W8zWluJ3XvTsTWnggt/DbfPLkBn7Kn5rFD/jd+866MSclv5O26kuHoGxCiZJi2P9eBc2As3i10dtvhIcSx6zIH49XjEALWoXqXVyf7t68uz94blx/evLl9IUPZXl1fyVr7V3OINh6+qLefpYN8ZHCmTVPQdlHAtgEtbQhX6evDKD1x3utHx0/aOCP+o6ayLjEqJPcoSCE/SzU9yGXfewFE1l9zzTdmPJKhdiLSTgh1FjNtsL+HOjGzjWpKNX80000tqEtnzOI1MlMtkaur6XJn2VjFspFusUqd6cIo5o2EwAqUAvudCbtLV0apL4ixtnZubmoLHLahtKFPWlkUC2XpaxIweufFmtdacvI9IgslZwUABuaYheA7sCxbvme7UUi4OOwse+QScGwwC25wz0KJTEAmbE7vbS9oJeCkg8RkCSwImGU8UFfHrU4vCcQQBVNqcm8UXoN49yxIRvHL6WXYIQCdz8Ko6we2FwA2/9QOwojHsKJPy4RJuCFho0yWAXHCyX7yu8xIAwNXhbcVxGTVcpJZA5FGufj8yrEvknm2JbZV369/Pau00OzwJDVWtg0Vd7Rdz3mSwCb5hjZvLKkBfMiOWGOrcm63igG3orFPKnvZvDF7Jbusjvlkh6ZcS42HlquTH1ruszK0t/yLfmifNEdhpatxPRJ/ZsT6ZUdVm6eqrTKE5EeWl/SbUZS4WrbtGSB3rK3ZZDPuQ+txkk0cgufHjzS78w3pOFtjIeUO11dNvbP+acu8KrPjff2f55dtn9aF5VXcuuJo3jOTLMU901sUDApZWtNbJs7t0HfoklsnpGYtKwlrzBNKeuRzGs4nHg2svUxv6hnJp2sTbwmwhfDJ90gfINrE2wN8c5dg0pqRGTqfB/BRNGj/Dq71+8LX1FnyZ0gfrUsDBHoMefJAZr0oYiaoqA6KU3I/M/Q/2u2WUcVs2YErakRyyOBX92PMwdns6JH9i6v7Q1EBUUMTOotdHWGt8HpFJ6ssOiX+j2f9rDrBf4xZ6r39z2jEZl6wlBbUWhZ1DqkFPV+myU7bbysK7TSFm9MUcsCs9OnxAfcCXh7kUlG/lSr7uHJOW/+GwxJU19dqKpVG1lVaKk2tr79UG6tTZaoUHqZWGn5wt+ECe+IERE9+UymbIqa0DbtSIlZs3eL/wR9Y23584shb0Mg2jYBFceAa4AcA971G0Q+5rqckqYFBzGwaQywXVCWiKgnnXuxYYJBgLiyLTBPN3Uw6BC3mxIOFeLBD1iPv+fhDXJZb04t9hwUGPiy4GeE2CcuZOnQmkimKxn+QQXaQTjuKePywzUOB0TMmCSzDDADYwIPtONBEwGCrMxG4pYsuXlCJ+b800tCYzFRzSU1cIYajscCgoS6V5PUlj9P1uLOOLA02Lymt/fjTFQlZCOKn7lGWBDnbboTyYeZlxrNPSuQMXVTUxbnakUg/4AceYHQmacAj4T8Spum/LWmkk2OuCaUaTIbmyBqzg+nh+OXRcV/9w8ujY4Tt+RwFVCQs16kBrsQX7tpkhzwuUu51+ciIxSA0s4NohpZlRzxtJw/g5NMSzlI8REzSOe5976P7ippziG8NlokljiaepBJS33bxUQAp4LllDB8QrkdAbiKQjxqTc+/DURHLQm4Hx8Nevzfs9b8fjm87UPejm/xxAH98ga9z7Nb1IhIwn1EIocTTxQfVI/gkkeuGrxJqmsyPmIieT2LUhSPYHEBp3Y/ubWLLlAkEDm97H92Kx0tCbeKNUnyM2IsNU1zATGbfA5MBgPvNUtzCOjDumEbR8vb8gNyxJQwD/Oxg08QZzGdy/eh+dC+9SOQf+RPSpR3iZlGI+I5RX7NgNIwD9qcegZaT7zzMSSllzqlrhwseYh3N2UcXRiHKRxxOgMDuQaWARSIuiuMl2CH5E+z3n1I9Dsf9D9g9jNidfXQXdpgx4CLRYSmLTTlaBM86EkZkQR3btL04JDSKqHkX4mTBH1csTwfui5BFneRceFMM+v6dBR5x0LGM+y57bogxzECNYvOnHvg/4jlb+gywMj665pwG1IxYcAI9/YmcXp9dXBDq+HPqxgsW2GZ4Qm7/Tru/n3b/q989/nQLpa7Bik4dktROzjOcuNvv/rf/9r//H//n//1//Wn/xZ///ulfX/7t37/vdX44Mbr/4/Yv5OPH/+cW+rpw+YVFHrzACjtyhpDOZSnxUDFy2Q9sFxmDGFzSKaGhbTFOpS57cGyXkf3+5/7pi85H95+xZAsLGtyR/duPe7cvOgQ5Fnp+0wkW/vFFh5g0CGyIyBbXLvz9/EUnKXP8ogMbtiBTxqyPLvzp7EVCMQTvSqWn/7h9wW9gfoWix8ESt9mVs+S8ynMZAGkvvIDhZkRzFjJi2SE6qjJLXd+KC1bhBarckrkIP2XuUsErMHGOQZN8B7mr0kzYNr1jnKVR4dXIU+6EfAacuiIazMAfS14Vgr9UcwyYpwI+IH+3mLvUD1m2Wi8G8KNrZLxnqzNlFNLnNQ4+kAcsw1nroxBgh73A9wJ4OYs3NSdnz+36AVvYIcqYiaC0l8V7H/SH4xZ+GuK3btZfI08E9e2UURA0JkP/1ll2ve7/dWAz13Jyyv8Vlvyd270K2IJc4L0ZZpd0eHCQ9dEFpRKn7OKQ3giUCBRDpDTQI6r0AryMBpBYyiWeLwJlwng6tT/z+0s6JIUikwxvRrBylLlxjUnAHAqpyKUYlSlHLk/Id//6tfPbl++So5lrSPBn2zWdOIR2eJTv33/tkN8+weEOGLkk//YX8iv88xv8s6CfyT78Y4dkNMQlB91thwyGR/K3wxcd6Fnpl32m4DEmR/Yr2QeedE8dQNuIPPKvXzu/foFaf/4OGg7nXhDNgZVCi/+67EC3X8i+Mkf4CK864JPdJF+cOC8dPiV+jUbJehA7Cpkz/UFc+HAdcw52CZ1GSqJJXuNFj7wDTG68w8T2yKVXhiInp/RUZQHLaYUz0qpokV8EkjL+DPcBbqQYRVYr3e/h/74/+tdRZzT8UrwCkJYvePcDxPDQ+DClSMPJ4HJsIKX5LBMOmGVDV5M4YkL7qns1sKArslBF3mwGnnVwnwee48AucTrn94hoAyVotXHAQY88EFfFcRLMfSneqKFaWnrFwWWkNlvvHwfvbds8eaAa/v5eGQ7hBcHPMH2/8PEV37kF/UHaSXY1xeNaqynJXWaJBVP/qn2Ps07eY2BGEBeJYvsEAZ8u/PSGlhoAFC1A6Ma/nl6rJK159sby3Zsi4IxGowMVNmlTN4FKEs3vJi2VFqSj7JLm+sptFGLLGXBU8ecG4oesxoqTB4jfqRH6jN7Be82vXB7bvx/nasjUb+XW4sODg8J+JNJg247z9VbrvmQtUtHvx5+ujPN3v1zudfDHD1fih1fXN6c/vrm4/vni8ifclsj0DUCCmzh2OOeYYPkD2NnjZjPLoNGqxKc5xChe5HrPdKVQjeda4ileWKcUZCkpbk4HBniWPgOx9pTM4wUF8dO7tyGLjlWUc89eD8h1NnxXI2+9obFrzjEwdDRO/Ymzw2miE85hz3hcD9DQsitW1kiqPa6UWlg+lFZFklSJxCjXT0iAiXI3du1/xpkkgUUELV34rVhhXbjqpwKNGeoCVhObQzVRBG9oZEexxSqIIcETS1Zy6ng0ytD+Ue9gOBiNjo/Gw/7x6Gh8gFurU5O/8dzZBnrsHvV7B4f94+HheHw0ODgaj0o38VIEP7uMBiwEqfXB7RDThpSMXkDubcehsxrqP6M+g8gDes+CbHR9shHS/Q9u5frNkKUnGuXZh/dvCDr+MddMXghCBJNq04BJmQyIDq966BjEYdE0mSx1c8ozxuJEmk3gWbAuGGrNaQrsBQ2W5Ow1+en9K6HABa4xCxrKIPoN5i2gDSYwPdcVVtU1mtsMP7X9kJlrjmQBE1q3jU0w5YXvhJtc4jWYPB6uWgbf7Cr1OU0aQEByaNLVpf3+Z86tHghQfSdG3FdFOb7ZzfpU5j8DB+ZTvWsKkF9tscLRqa1RJIX6KkjGxWKaSxSXbuJZDfxVhM8M1tBaZ5LjKJlUKedW3eXQJiHZWdtD39xPqgGx5CZYiErMNrFVDqst12e7XFI1W1uJWyzpUZwnuFX3oeoL4tjuHSrgFNHWU3QP34WyspbPiScg8AvNJanj6vLKkddXyaS+IVea1pS4naT4jXKHLWUMXLeh0fDSIAL7L/8uIciFU1Ii0pBTDBmXu4VKXqnp/oFbpjHhQIjWc3RCEFKR8D8icMFiNSlvrAkY9ojKjQ2oJZ6hRqFAEn9IjrptzBQ8hUohfrNWqIAhpgP6qoCN8uKKGwar6UP1okrjFRSVOlziEkVCL1RcXCWOXDQM7ZmbepEpNgt08BAHM32N16X3GPX6vcFg1AOUtnKnQmW4KERsfMAXVyEzWw85HZ+aBzA7nmvT8xnkGfGQG1Q3bjG3X7MSsqcKG3fSWZqK4dXZ2ysSwlDWQ8hQUhVmhwTYizo2rkyfF6lBfLw6PaufP2+pbgVEqcdZAzHfL9VjlS10pT9H9ZWn+B2ot90UzO5taPSGezKi3f/6ivy6VzWkRD/AW97eW6NMGSvmp7E+aWBv5GKoT5iVATHFc159DX35smUXVJFgmiGRqrMGF0zx1aQu+FSGc3TE5X/jfhV83pwGa1Rsrm14alywZpC8oW3DN39sSl6NYLecXgUpbNVztXpkuy39Nq+q3aUjdxzH7QXd8lRFZ7IMSdXlJKKzNZMWVcpzaFbRuDg/QtaAr+umvFFH452P8M5HeOcj/Cg+wsLsW+sQLDgXqHqENNQcsKsiRrZBjHBZbQDxmvnNeUuK5FShumrwdi+prHpPrtCqtmrRB6Z53IdaEdIlMupEc8OcM/OuWUNimzMVwYMkH9PYQprIVNO1dbhiY4dI6FHcULCK4nbwJQrVSxSTKGqYZgIKlhw6/aaX06du8atP6DYItI2Wv5t6Zm2REMp3JGBW7FrUNcGlx4v9Dcl67zSKPo24UyenMfCl1Kwm1wBy1CYrUX7jBNbSfSqrwftOluOLMti/fyoV+35GAxk4QmGYaEb4SxvPj7Tcz6orS1YKfTXutmKnITJj5e2tX7scT3fZ52juNbwCZWGBO2l/blZNlG0NLZnBZAaNedPbC4p+6ew9MHs2b8gfRNn8Homhp+ukzKF0674Njomz2UZmKR1CNXl6EjgJHKYornura51HVfPb4GW3f9gdjG/6/RP8//9V8C6tfMTjtW0EbOEhPDjoDiRZVBPN9J+Wq/UKPBWgC+Tir6+IAHAAPyxA5uSvQng3golf4G+IXpdF0yMoyj+6M+ayANEMeIsh5jQKIxFXjs3gE8iecu9w0T/iHeArTELnIyjB2xR/gGMLBAty+2+ijkMnzPn33r/JCLOL83/v8U89NLXmsEBvBcxB2unFObE8xkEYXMYnmLgz9MjNg5eZIgcNmFN4+sLjDI0C2NJHV6xwj/zsPbB7FiCEgoTzUBtBkI6kOp92lOB4PHiyr4+usDfk+ktFNCme6WL0czSjeRq0Mj0niCuPaimXQ13TTq4dbJZULxFyhbOMDpkoqRgAWYJja3jwKIWlD6jJRDhm5JFS98JqMztPGawTybaB8deJE5gOWWPbQclK5krOzry10MZr5Zm97Luio+3KU9TYzI7+WqTKx0yEEyPtVpPsJXtQEom57EHqhJqeXWtu+oZX6g8n+O35z2dXYgJ4l6C6DDSB/Is8C9pMSrkoH0yHVtBCK+3zWC2yP+gOD8agU8M/hwIWeXhwIKLBMdMMBCWR96/PyHAwGqZlRx1yyAFYDjiOMqL7COXthJmUhzMzRJKZOrYZcSVaagSQMU8ZbB5t4HMS1zo8GOeiWut9pmG3xbwFcFDEPkcnACeEm82VpzDpyTJi4YsembPPJ+hr4nZD5lN+Zc/ZZ16A7LPerEc+7vUHJ/3xCaUnk8mJaX7cQ51opiHbP+EeXffjhCPL2oN+b9jvjfq9cf/j3ose1sHSsStYtpg/6Xehzf0BFnnR47rYsqIY+Uv2h+kY+Key8uPh8fj48OXw+IDsj2Wlj7o3q/QRh9XbA93VZ/T93uvsQS1IzALjEvoQ2Dc4t7ji+v1R96TD/Qr8gCHWk2l6AaqKxa2FW4mOqnrMneSwSuI/PEypCEYohqEu+l4+Gh0qJqE2vELKeTRpZ4szslgIrRFRGHXdZpSmxoXQ/iRBb49cII4UzPHjHuLvAQmhFptn8EVQANGWmiUq9XXLtgFMp0kTYg4Sfy9nd8M24SwLDoQeweL13OENypxPkcdhDzVIg8nCiZC94mJlUyol9oLIQ9kpYzLlSv9IDkUwQlzUexYgQNmgd5CrU88mi9Li5v0k5ZMIYoV8GkSJyKW60TSXmL6o6yrVb9un608RHZrXLiJAPKbRIPPuba7fz0ToFUIj/ximiLWgsJ6xISMbHNt8gmpFXbzs1hhI1IjUzVpJlJGukoDs8fjbzii5M0p+e0bJ/CBrnX4VLWbG3VdihIY+pgYFwNgCLGmKkzo4UNE0vYA4LAz5E7LUfVhqCZvq0356/8qofo0rky9m9mi1wRpWlfSingVjQhvpsDj0t85/LGLBwnbR+SjJHxvELuG9YCdhBo+8FfZ3uWo9oPWgX7ELu2UJbmIEbGowNrHMo8Mjk72cvqTseMiGo/HoyKT0aMxeTg72Em+t0ndUZLv8YaBATdMkKBHfg3zyBGffI6fTSGiqlEXhSaJM6oexw6XwqBRyXAK5o3QOISXMnHsJ5qt4Q0nJH6Db+MAEDDE+TuXDiOO0a8+srHabqQc4xjPXC2ROXJsn/RW6LHWThX68cLrJPqpfmj1P+FRfQLdocxCN8i3pEWlXsF3CSZWbFmxe+XMXKbzrsofu3OzySjBIi+fdEs9RoCA82kLJIpvQV4f1nEAMHPIQln1atskTnjl3gsYAYyKnM/jUCoAh2yjHX9Cf9B1VP1eqrlUHsOmUoVFDv3vJ58wOJWfmYkq+C+k9s9Bbki18AKoSpqtkQeSy+54vdo4n3IK9o44p/ia1K9z85bnkp1c3STqIHrkQS2q75Ord9U2HXH244Zfo1enN2c9pyRZ2pyZmVpydfm3wk35drpPsFYk9j28iLpFkDrZrAbQ8JsuQxFy2IA+KtXQ921p6hpU3aAU2TGVn/eGIDfoH0zEz2fSIWscmHQ3o0ejl0Oqbo4NR1pVllAIP5oM+nr0qRx1w3odTjZdtEnGpD0J7NAVM6ydSZq41cZ9t8Mk4zkrOdWwDOs6Vnm+ZST5PdU4u7uWb0+0k7bV9b1YcIUE2Go62WMQ8m4O6qgmZScU8FyzwQKFN0l6wHnmH2QZOPrpdMGF93BM/9A7kj0P4oRq5oIcPgHs7iGLqIJitwU2N2FHj1M0aissfqVM3E0UEd4vpBRijgXeNHWaXIL2OoRScQTTi/G1Izi4vskUlIlhPc32WOpyUsc56th8arqd7GfoBM9HlinwIUwkQ8JSrEaQlgLSVtJBqqZvYRd4zanU5fgxwqEHv4AdisSDNWVM4aJVOYQh1rB/NJnNJNVkTtc9nMP9vKpkVGsL9p8lo9dHNprQij5XRSslelaa0Iu0zWu1yUO1yUO1yUO1yUK2dg0ovbmwKtUaHA9IYtUaVoCKPvHt/vqcfbf4Vs1Od71Tnz1/JuFOdN1Cdd/aSLSqhYfk5ubEc70H+rGxpj7yy8UjHrrrrHREmz+PBvQm85hbcP33pxeTepgUGlvBw7nEsKkwoKDJVf7uksuczl3MzF27hAuHxEUy8aK4MAzpROsDfZ552QNUcNdNXJpowuxKK02bhQ7YNdAPH92yJhpejX2ccWZH+y84c5y1hj1wnElH6WirVZ5ELpGdpAOdQALdJ67fw8TbT3W0qWIMUJFRo+/BHCGVxIH2E9ULfUHZNbrl5W85ONilwO9+/PhscD464pZtzOuqDfzmzEHq5i06VAq1hcHjcGx6Me8MxoAAM+0ggOaaSOFeLKsdHvfGgNzg+7g2H4++HL+vQH5XiB3XabfViLTV9b7Pe+VnrdS+5owQX/UF+rTwDP3AkXhQU7UiIopC5mGCExJOofLdEafv1lKu5s5Vfq3yEx2jQndiRDBvZ/340KOgZXsinI77LHri+Iezg2wB1DaC8KAoiYGBzUJieS1yg9LmePvT8wL4H5KCLK87ATojEKPlf//P/BZ/4gwP5fx0yeDnsDQ7lx5fD3migfDyGj0fyq/hN1m+IWDuq9tCpIaQSH+37cSraJVxchqBnUQtfewF5e/XmOvMeCTsfXVA5UPL9qA8MG7aJbxmvAS5I2Qq6sh9dJSi0R/5Wds7lJYdtDFQMnQVdfnSpE3INCJWfkm0VEZ3fhagR8QL7d2YlSrUf+Gv6wQ5Z56Mb6okDgnnwNhOrU3qThSWRIBvY00PdQRkMX4KOjVxc/e0wM28FPVvaDfiEkmJI16kCXxLAhEnr89QOQmg5CQDjCwIrjq5n4HImpHlZ2Zvme+uRVzMQxfODsEMyPOwfnhyMzcHJy5P+CT2espPB0BqenHwPs+oU3x2HxJQY4WV1ByfDfh/qV9u5G9Su2Bm/W8G6uKJMlfuaHXIluhMjVpvHKgDPMtzYcQzT9ufcIt9AwihU+9J5DkLL48c9rOyTnIskfuSoB31kflN3Z03tMjtNCw/q4gq0FiTrZcddYMVXMr43l/M4HeTctv3wzliwiFo0os2aydRAP27foUsAk4xYC8jFYrXKQAwNJ6j2/s7MFnyYW/k/F2qXeUDXFdyGJ2cpQt0mme6OPX7j0SbrM6LG/OdR2c6GOA43NBtiWnmBM4WWAPxOYZS+uv4rt9G4ZdkSypCXsWedMRwfjX99pfoHJQpNNFKI+F3hWKJo7phVm5tlOBofGHRiDoYji03HB4doBp+YFpviN/x9T2b+lCvT9ILPXuxtyWPdey1/F+Vm0EnXnI8t12MJVTSLQypgKm0u+QA2beSfLXJ4MAX00tCRLFAn9yvhdsQklr0lrZZR6bl2+iuknGxHKjqhAz7odzDENVIu97y/lJJOjHt1cMfwq+u/cjXNInYi23eys2wQxu+HdxWYz+IUX5xzD/nrvxKf2oHa7Cog7HrS+FLAuoOhVS/X9gMcqQxbZe6aTXlL/cyeoE2ulOFbLKK2ngKk+xd1rjJjaSu+KlcR7F3srjD+KbWdGA06NJRpiZCohbspqHiAO00SH6s2Myr4dmwVXpNDG6S4n3iu1fjuk4VBcqQG6CuLy4D+N2hEF15keJ+/Ob3Evfn5FM2xtjvrcZMk+P/xbYNEc/zi+PmUwKMBrZaiGGjioQ2A7BNYaEJdKAaiR0FZ7VK3Q2MSMHrnxRpeWj0/bqrtQsypRWQjEvtFP8RQAoOCKnmt/pR2KruU130BF92lDV8pUBCutPkyBLNJw3sNSiJJ43NJYNPvrZWRI9MWvzXBf9LaUOtqWzwJoo0PvVWoimOeSQG98VPaoa5RrAou/PAlog2bSUor5jOHul1qOt2Ma2Q9y4CWysQlRaCX1h8gVXD9eKA8twHXV8JrIoVjwnOv8abrYGfNxFPoh58D8WpIAOj4gLXN8/gHtLZohEugGGgeSgmbTKFx6BYvG+lxpSI34V1w9kagOmE7GHuvNMjTwsrmOuCcsohd4WcLvaH7JZT33PTsg98R909cT5iC7YfGuzgYJHGe8KN6MTa/DF91FThnwss94RolsxeGq4urUDWLtZm9TCDTYMKyqDpnfGVtausTzpaTNMQRz8gSRgpjuQ1ycyPOul140LgJAGcJMVTLBo8D8HEK5LVRldwU4Sl5cSDtdR9oiU3zS/a24aPn/dQPX0Hu1Aw9wfp3ZHrSApJnWA3lScBgIWys6KKmrgLEkXO/5vUWQ4UfhbXA333Pc0B913491QbCiDYVvXJNuKGyCfmwp0aajZL21s2vplIOHgAZl6h/D/qgw/Cm5O3pGUmoHDY9BQ3Ek5SnMwWxst8/GQxOhsOT0ehkPD45OFDN6P3+Xmfv9PTkxx9Pzs5Ozs9PXr06ef1alADXm0Fv0EetVdkLMh+BpWIZeqadhSFQpqELLMicpC3LwfmNcuOtSn/5re6B7l2VO3fC6Qg0DCKqTImztl0yt2dzQu+p7dCJ7WBQmmehpzH4MWewUu0wjczZt6fS67mDb3O4QV5kkfYrWs+OPON7TR3PnXHOEDLTcy2K6fEs6fuk8QcqM+S2scdhfKO8ZBIpo9kjVakjW0gvmRZNiEpAh3Lm7YyKchLSTWyFyjmqLBrVYLRtvbi/cVXbTmm2U5qVKM2eo+YrXMktZneGd2d4d4afzxne1lzlK+wJCudbJZ2nbnyFzN7bsFXNPBSzU9uu51PZLEIDlGpbsk2rnyjd9m3p/gmHnnBL9qxh8IWY1LYdKkysBP4tOqUlz7pEfR9AF2yXJ3hSksrUPughNhEEmaZmHt830iro9ajKCM0akBVwksn0GgvCuTqtvHKhjnTG5ULfCsPP1muFoQD1Bepwlixyk/rU2YvsCL0Z5Saf+v6ejiy01nOVMi7Oq90lUydgpX3lWK7CEiXjMGx36u2paZ3+rtB2NlqkNiWpQwFQSVRaMzHpwcmwfWLSZMDS8W9bBcaSkcn5KSVLeJwa65PC6K/5TlDTkG+Zd5wIYM8fQkx1R24C6oYLm0OffXDtiOy/vfnwApS5PAuddG5RMiOgR7TIjpcmjT14eajFPUxQQwbjl4eVFCw8c0U65iRb5/bTbnlyziLpJr4HiI63gcft9tFrlg62zP73GFzsj0sLQl1V4/3B1S5tMtsL40faD4sA/UkBys2Bq7DoNaBDZS1kIg7DjhoIszyTsQEXv1bpeMM/AOPl1iABF8eTAcDgQrKvopeN+i+0/DbZjFFfyWh6MO73cylNhYDgQQSezoKvYDAJx8N0FUTNmvikw2FvcHDcOzzgcfpph1KjmO3yw/mV8Hwr6S67AMP+wUHNEkARZREwaWluFWx3xZ2RFXV7M6gb2OCgem9CKGe7M0Pi+2WHdC0+E/iMo5FrFTDIaRpCGte/QJL3YEl8at4Betig3++TvxAEhcGf+QdI3nqujr1m5H2VrKCd7NgL6U4VIvtUct5aBOuuf4r+aIfmuZyQ53Yg6k5oHZ2X0fI35imTuxm3S3pgn6O5pzmn6FHPPkfdueeDC91pDsepedb2psnZ5eGtILi0bCLIFJzqrjgKEcB6OTQMIbMdB4vqnnsLgDB+L8DIubqhKVLWcFw9eG511ESlXokvNenu0+lWdKIP1A6oa3kLZ0lmzGU8RTpCXgtv/BS7FC2nwgm9JCJWswbvRpOHv17/w6Xe2edz78Pnf5j/HL+/O/qvv96x3//zg73EIYfMDW2esyk/ZEMM61tRs2xjpPhW8aT8bIuMCYJSZQkeayE8u0PuvB2JMjCL5FDUP0BAQ2kk5ddCwVEuv4BZsWtR11was8CL/XoKy6I/NVKT1iVYKvGXV/9cxQOuAnsBXoci4DadEuFTSsIr87Hm2XLEbpbCq1Higqz6ebVV0keT/RwvqNuFwogSKtA2yofr89XpirUo3/pvTfIpkPZW8ZnC7iCy24ItJtnghd0p/RZPKdAG7LQhr5l1/K8SQlLb/FLFCVRa+2b5QfZEbTVz+OashYUJbuwM6LZ+y0TQkhNdb8bSiqyvY8dJUKx4MgoaCkBx7vNRzHSnAHplu1QcFnKCMe8AP2r4oEg/wHHR8Q0DCGKuvVdYK9FCDiSquCSNVZK6S+fDhxRNSS5NkAFmXu/uySZ5PWyyaidkFkBSM1gbTBQAq7PWSiJSE9ZX11F11tU957GADC4PAG8cL7hoHnjxbK4CoPGnT5LGJc0QJpyjJ0tCCUeRpo5NQwnRLFURgJgQ2r8zbq/WFEzypHn3LHAAdAfPaSYWHb3LO0riDhx+dQOZQkxtqMErDYZp4DBXMGglntcr2MKym5ttp6Mbl7rrGijAQmDaLfCuW5GummtoeEWSVkxgBdIMZ3YeGa8bed00WZ/MrFGdTwkz1Si+CPh7On60jbaUiRss7GaTBOcQLVdTzrRGwa1Dv01VrE10ybwwKH1aEKgoi7VSRWSTeqI03M6m19QPjhf90tl7YPZs3lA4FGX1aHbyEMn5KxP5lCXClUJ11qWk3R5W7mGb7RNOS/xs6uSEdue1SE2fNBKTZgAL6i6bE9DG/EuU+ReQVkQn+hX7Nrx7VvbzaunCs1WPjZ0Tl+LE9c1v9FbpgBtwxW9+w0Rs/9e6MET3eXT/hpdHEZigab9VKQWqRraRa3194X8nsq0pdleLUZaiwag+CW3jqWEsRuOdy6JPrf2oz6wIjiJ3oL49PfAf1nNa2u25EiILSL0dO9vkeCgpv7Z4d/RRZpijmAPIWgSsh6o6GQYvKq8ZbQahZq2jzeT410ntrkQUNU7sfn1Ffq30IpMDU67boi6ymQXYHNOXo8OhdfDyJT00R/3BMR2/HE+tw+n46OBoOMhp4YerrF9lmGEtAXz1oMPCNHbBh8qLL5OIYb07KMvptvQq0gYiApG3DkbM5lldPRyxMERxQf7RlVIq5a5GoNtIn2Lzd7qqP/b+f0MqrD/yPn5zQshOnFAVRUWfG54Qw+F5v16dvb3iYSgNkGNNz/GMFkgzSnkeoecZAZtJ8O6G9WUNxY8ygYHtCtnGC7p6BJWZbZIzWUbNRRLRWY/gUmCsgB6QF6F93epX15F1+LI/7lujo9GBNTGn40OTDY8tOh73LXN8NKx+hdmN/CnkBBoHmmSWpahGzc6Gg1HCfIsreA2YkvrFwewVgCMZeQjK2EkRlQFkck7vGYkePJKMJcT3WRC7YTkEcrV3ili71VTJ4JnTXI8M8+gmVVrhE2HVBKAoQSxuv4slZK4ehMwoi8kcPJk9ZCqgrl3i0MiOIP0BbAZgSuNvTcJiNH5qb0RjlSdk9LJ3ODguOwiOfuBiXDV5PYe90dHgUNtybpGaZQzKQRRo+sR0T9UhjFhku15GzYh6y1SH9vbZ07/Zfdiqt8I3uwtt8el3gkdW8PhWRYjVkM931PHNUocm0fynHMVsq9JgBS0A5/Zbxe6jyNFIu2Aau/HIG8Ca2b+5eYMWAzeGOB6QgOeeH1YaHTXWgcNxlSi8MxPgvFN0zWbjyoJobhXd8Q2fM+pEc8OcM/OuwWbztHrF6Z2ziAUL2+WIDnymHrBqwjvA9gVyVZFaS+ebEG+52VaiJ1XtVewCY7SEOtUI2NRgbGKZR4dHJns5fUnZ8ZANR+PRkUnp0Zi9nBxg3B4NZrqYL7RiszCyXf5mT5JAuYQScSljhJqYPMHZ98jpNBIUoCwKaK4sZlI/jB3EgqERDy+U8UDMtbKBd/yevAB1IDPnXhJgNPWCBxoAhAxcqPM0zgzsiXZIpjZzLKKCut3KTpDuZQijrHabqWeHxJ65HiS4gl2c2EmcEnWymyyylaBFc0pNliTJ2ofAMhqG9syVg1SjoEhoWyw71RfQbQy6P9Eo35IeeQtxapirVUZogmMA5OyCUp+7SONdlz1052aXV4JBWjw7pCJ0oEiRQu5gE/rqsJ6TkLkRhBqKFjDoCgiZust3072TvzfhGeqRMwSNfekUhKpPraCus40uud9hskUlNCw/y0UHWCz5s7KlPfLKxiMdu+qud+CoB0zmEp5ASOyC53CEnNH3NlW9O9J4Q2BEouiEmndQXiECWc3zIaYOaMgFqL8CyfG+J57Iv8gHgPJh2gH+PvNyQ6lWG2V6Ue/PvezslcjSwodsG58UGX5nkC3iWP9BbtqtUqxUj+yPtnfb+4aq3cA1za5bDCKf49plUh6m9BSJyZQbk/tt2SFkhye+59jmUtVnfNxD0eDjHhfWeAEuqWEC+NxlJtrPtgCT1DWAFmHeihwXiEGucqGLfPVRJpe9kEw7vBVxr2WkmNzqp0vFtZHabFCJCioHo0iDyKYO4VWF4P/jT1eEN0BEAz1yGhGHgdcnTEBQ6ZLjEExYgor4g8zVSlJCJiAuOGwakdg159SdMasHj2bTYTQg1CXssx0idKTqqhuCPH2r/OWEfNz7uHdbb1er9Aw+L3oDZ2daKXScwm4yCzBFfA8BXyVkAwJEeG7XD9jC5hmxFRfdQX84xl2KzLlBE1Gv/twqW5mpXIre9DqwmWs5S26Ek16LK0zxndu9CtiCXCwADSE3n+EBh+pN5pe8wjQc5Y1IHn92cf4+gabokVfUnBPmRsGSLOiSmDTA9Lup43YYTwHqAsE4Qp+ZII/As9U25xIGw8H+UZTF5SGQGxeBf8WrJVOOXJ6Q7/71a+e3L9/x4izMNyQgH/A4htBOAPRK/v5rh/z2Sciyl+Tf/kJ+hX9+g38W9DPZh3/skIyG3Fn86n7cIYPhkfzt8EUHelb6ZZ+pGTlLObJfyT5wyHvqwMMl8si/fu38+gVq/fk7fAnNvSCag5gMLf7rsgPdfiH7yhzhI/DqhRewrlgvU9JnR3AYOGU0StaD2FHInOkP4LxqWwBS7HLvjUvoFBoXOMSixoseebew+cNXbo9cemUocnJKT8qxLVxfWXJBMnG9iL/ZRYuYhDOhjD/DMwM3Uowia8Tu9/B/3x/966gzGn4p5nlHWr7g3QO+Msr9tqumlR/omKqSAcyyobEJBp5i5iPNTK5Y0OUfSeTNZg7DPNdR4DkIGM0pmSfyEW0gq1Qbhwsh8oAhiwOTcF6u4gnV0vK+Aw6tNlvPMjl47skD1XDM98pwJMruL6eXwsUpGZ/mWvpSs4ZNrSLJo9OgoW6AOFVq3UOVkC2AjXJ+rEL6eCSgC1+ccNARmKYXuxG/ZJPUp6fXl1rtbBLOENtuNBpm0JNHowJwubqFzRh9YypTVlXN75ldkr8BStHFOfpjkd9Z4HGYYjeis1kmXkODBj0eVumfBYlU71hGyaGHTeeOZEBHqu4tBVEXUq+MNOJIRnZIMLEu4TIfF4wSv/vbhW3dVisNHO8hoypYYLim1A/wr/xvYLVCIXRV1yhqGRPqUNeEbF8uCwyEote8vaty5q6WA7cZaPYvIsuvlE1hyHzEkAq5SCLYsHdvQ4gEswzLe3BxlncTX8f70qJEFuW7K6Qu6N60AzO2Eb3/zna8iR2FxAccLLSiVZPpQRElv1+Ays8OOfYbDpgX3OhwNaD+uuGiU8FqJLdi9uCHx8seDE1vl6Gq0XJtl5sKbMKWqTG/0V3YKsXit7oHOiaZHfe+fGa8ABuTUGd0UEQ8//nsqkeu4wm8gVI3EWk3w5cT9wpu5vlSlmpIAC+0gl+c0Yg90GQwDW+QDMpDYUbtRpBW14wlu8Y/8QKJRTbJfiKbSJ2J4AKmmqWsdyyWSUYGBfcbOa7iqtVQiwBWLFenXfP3UVpDm7ftl9NL+ZD2GhNW4nS1I65vlLj4G7A1UfXI1enN2c9ChRtyvTPX+jHHChPdLMeSvfpww8FPQd3A8ZHVtnb0szH6IdfcQuAiTLWH4Lz3jNgNcyNBSARU1UZgAAG19T1+7Fd5g5d35Uu7xZu5sDKP+ob+6g/hJpS04hNZs5JP+GRecWJNHtOaiW3yhSyZ9aYeyqs5jH9LirZWxz/jcPiNn/4/ohpskyc1J7Ovc2JzoHaStj5lT/K2OqGs4FeCSoDt0gIkGI8lWaF4AUnwGM2Pcf+kC/oAKUy3SDHp0hmzuhabMjdk3fvYgUR4XFDsWnZoQgqHpXHmuaHn2HCpWGcxZsp7z4C63q9AQqttaLOBvuWLi9uuEt9T9amQWpFsVDpprs5af4egmzUIczMDqCUQP544dhpSlS+cFZg6m1k0dZxXSv+4WLnctI86Ej6Ec8+MwUL8t6EcQWhHXmA/Pg2ruye3TfS+LLgkIIAtdYUpqBRcL441wWWyYm56ncz2J6u/KgEWptAwXVHNXCpEOT5gvODjUNeUFC9dLzIASRC20GeY98kI2L3NHuQihHMG6wNeJVZAH1xcBVy3+taFHIENUNNkPv8xiF2XFwQa4RFNnb0ptR3+mcGa4I8mSLgO/Fmf2Ehk3FOHk598q01D8SfdqPdNHxf6jaj1A3vwgjsWGPxuNVZq5EsH1Ew2v5BVrxyRTKcklHLV9djdr8/jfi1uzNNcq/p+QdeZRAtVkmM+AaDKEje3MFb2uuCPs0118QFbOwsYuhRQJ9Sk5Up6TzrXYJk/v6Uqn0dx+O3J5tps4hCFnepc6+RY0F03TNypY9f+Z8zQ61ENVqxyomyx7JOAuua8OJwf8e+gh4O7p0fOlRBEHhImh/tdmGiFeGM6bVDNPTH3Qp238KvPvmObdkTgOzox4+sLHIZh2dM/y7WicTT3Avt3EfCIyqt0pGTCph46VcL9T6glQF5/IPJGFu2LvJFkPByincTy0DHfZ0EI/ssU16TJRmSmPcpOu9ITdci1IFII7OxxKhC/Vyq66u/T4pWpzUOgiKANBhMxhy1YFCyNB9u1vIdNneIb2e4vvNlWAgE/a+1PsrVpWVaTs85GZ3oDL676TkyB1FEmiQpJSzQqRM1PqdhQVfcXrEt4XcLr9ooCKQ4hbfDTqhTI1wLizjVH/pr7SINsy3rklj5QGxxghcvr7QkyH6mMLOdBZE5D4gIOyWIBOsklBCDf+oFnckXg7QmEF4gZcyO6H3gzHnl9iw+G2xPhMo1RxNyiB8Evt3yBxFB0a4d5Tb3YsZBrTBi5Z0EpOLrchNxMOQGI0QryWaaPiE8aghIVKzZaXNVSLte0UvUGkeNKd6/VwSp7/DfTVMArzaBR5UmrTHAOTB+YfbNndGfvHph9Znipbk/RTxckirSXtI1Odg4rL9vuefJcnidfReW3ATXf06nxNqWmk+8waY5LmX7Tk1yhPFPD8oZH1ZJStuOOolpbW5f2mtpOHLBne7wz4t9XOuvlYdLipIOe+JPO0l/PJFByXMeY1G46Nasj7YSG7U69vRbtX9EZwNvA0XymhLQt9wRf+o1xMWjyAjdzFRLLDqoNwRXMHPX08JmZMQTNGmG8WNDM80fLNRODvSrfzxgMJ0oktrymg8tI8gEtVB2IiwQidRICLpqBoiDVhRFd+ErceLNMQ186e7AY1HGMkIEgHmnnJEVkM7Aj20REGPRGgQ2x7HiByefBZpBswlPai3QXYdFGhEBZVXKrmOQQYYrsyKl9uxX2ts3jOzcg2WVHQ2SaPSpYrDJE1f4UvIIDdkWjeQNPKjtSd5RD+Klif1+orLTLlz0KJXJHtpCfHVZZsYI9SnmRSDeag+Nj9X3C45kbbxn3woKZiUElnXb4qqyw7p8BDoo6b2y3AVjdalTZ2YsDp1oWDOx8I+OjVksjiRd6ar8Kr200PdYvAI0iaoImB2lfjzsP0BtdP7DvbYfNAF5DFCVyvBwozZ7NmIR8wN57JHFs8VzisBk1l4SLq0Q+XMMqHQUTewnWzjiag3nApNyQichx/JPvhZEBzC7wAP5iTyeUgXcYjrmSdeYUpFDvQU8dWWqQ4zTAcfFJmHOOzjPs+aBfzgeq3h+oIqSmnsukFce6G5jXNGxLo2I7FYZqQK2JQF3FC3fNOQ04MgiHLSGmDaUmy3VoqG5P1YUaDXM4v/mj0sKugdgm9ZTi2C7TM9RMCL/MwZ1vLe+Tn2UZAl8F+5CNAOsAmDwDRR/t+X7nAkZe7AIEUOwGLPScew6i402JrLbyWVYoB/1FdS7f3tRYsGju6ZK+4N85vqMXEJcxAV5pOl6Y4Ap607V5TRgFsRnFAUft++yzwAYhljMfky+yoivFJ7hx53oPDrNmCGvD6CJdZR0T4jNFVXNxomdxEAD+Cl92x54yc2k6iWZ6zdnhalmKT0o6E/EHPiPlD+kaKH+ESWrnFjBqzgWvehoG+F7tkR8FEJ03cZjB8mBwsV/rjqPx7gdJcaZ/vVToeJJ6nWyfKO97XmSYNA7r5BMtQ97s20O2ZkxoaGuXJN99o9ecduSJYW/NTQzYlAXMNatfS5UWUiEDV9o4XE+kyu7Aj+ng8VdEJ9oT4Fs6pyvefEcdLD6W5mAWbHid8sKQjZY5X/kyXVWcjgKasSQ9Itu4ga6uI+bj9j7QqRHEThMX9jad/EKn77HV9q8hKfcrD9Pc6eNSqSK5pMctwzXksmak30TIy/JLdSVyzFw9ke0fIj970XY/giPPLzpmPsVDGBck03/71X83CVlwz6zGW2Dce06csbE/k41YfzHl1FZfRXGqN7qQjVfoiZ6VGYrB2yp2WJk1K+dlASUbmbGLz4DW2yuHles2s9Ny4drv+Hu9NFueOieMFyxoska84QwRKWBc9zbV6yEaL04yFrUv3nD7ZUh8oW6SLAc1hC/96lYVt+5sV0tqWbcj0N8G9szmvvPP0hMMJyIdDVdY+URKqV3zZiqFhrcdCIM6C0ri0ohgBBHzuRNTB+RNnu8AgB8QK8RGByfwRFIkz+8yfpH7lDj2JAA4A3Rd4iSbpG0ED0sulb4AJyoazW8FJKibA1mlkdJspYEmNc6LNLoFUfZhrnmutNpzcdcI/Qvvibe7EgEAMt6Z50bsc5OTF0VaWqkcfD7USWOrNZ7w7klNJl9QxIiesnMpqMoXGgsb3uEFt41MXXUencySfspkj8nv2+NFoeWZOn8FbZh2WkhAyfPr6YQbKch9yW9eRnjgA4NtemATg4Yhy9xtm1gm+JnWmiU2+C5lk1OcxzvZMdL7Ex6zZATpYbNDno2mcgQtFD+VeQgbo7cUrsZkrwwE762RcLV+79kcicUmi37xBe6SLlZHpZ5U1G1lY+QcgDOADr9DMtTe/t5q/EZKkejLZL2J45l3e8kAQDnqAKQ3rOM/wsyvjjfDsSKelAV6tKqGBQSI1HUmKCA1hFMw+vmI8lBSWNVyHh8WauNuCKPrPTNgXxv02cj/vSjUUU4N9VTeOvgxswwdual5Ok8HkNki/SqsTHNa5pyPPhJxa0933SZ3jbzt2dcaQN3m5odQ5BRoQeJruMIuFe+eevcwkW6uwdHYpEYqNUbWKWZYgC8MwXAe45pUepCXpUMnayXlWWkg7+FsfmmvqBFrmSjkki3NTmYNemqm3KT3M4MrDQzIoeiaSyNj09AIpxpZgQvwQdYmlFZNwIVyMi4YhReUY1FzH8RvTsOqmWJmuTolO7DOxmdP37e0/2024yus/PusuNIsGdJmBPEVRBR1HG0n3TQoU0DYrRUy1jC+ZBfIuQvkXD2Qc7XAzZaBmh31PKx25M5ZRG2nnr43j+OQxbqAsKtHl7UQyaHgY1+FgsGHtdrSQlK0XcjOcw3ZWR8csT2ZbyBOaKUItUKcST01Pj9Xa2HieqLBSM/+3Dj66Fy8sKN6dXLWFyvnjFWJEoLTfeTopsZhtkqNhhrcdZwSuTnOMFN73EZd0lRbX3vEESVKOL8qqm+YJuYpPy+Fmlc9x7t75VlABhQkqW8x2JRP8Ma7Y+6O8J4J4dXDuW080F0hwgbv4VLjnQINntPfmHEQ8sd2HriZAlYacE/bjXnoMC/bI68WfiRcYlyPTOMAsah9OhMRx5p4Da5RNvzss7t2hIWwAj5HpbFkBm1WtRm8XII42kb1UTQ1rKYKqdBR5DJg68Jx5lQfWyGllwS4nv/Zdi32mf9IXeosf5cPbLjDxQBtlzo2ftAHyTxdCDfsXg6KMIwg4G6zG/XEmLXA1yY8Ldpaqran9Bks6E2SEGdOgbk5Zfapkz1fhSB1VafWhjJ2KoCdCkCqnb7W4z/HoWqpcF0M76/D7x8VNfz5AIbnWdrqmOGcLHas6VkI84JDPLL8fs0b3O36irveYn/abEtemCk8fz7cnJGL63fdo8P+gCAixz11euQa5BduHDOdOLTvWYcw14K/sM/JXwDoGAxhsl4CqizdwbAEjcjCCyEx6T1ziUWXYX2aSKaPIdGDNaGw1bR4MXo3ED4trRa2+ERuoPf27YCFhl2JtDQ67Pc5E1h4+rDlGoQaiDe8Y3UejUeD42EdeCEOQDbXUcePKwVpLLupFE5NfLMK3W8h4Bm+ESXlfFX6t/5wxAb9g+mYmWx6RK1jk44G9Gj0cmj1zdHBKDuV0VDzOsiPDgzYllF8bDYzuQv/jqrnagOLeWFMcRh5CxYYcDCi0JixyCgyjMfhn5XLsxFuWdtDOW9sfgfmOgmY6QXQD65oxa2n3nA1uwLuNmGEm1MOKFmtoErJJx+Gv9aSFmabl+6w0Y4YTsu57ghxHUKsJ6LN0KYdboIqU91o4cW1UYLFUQNOELVoRDdCsLAAO1LdKKkqNLUekYYu9cO5t7vZNrBLci03tiXP91pTpro6f9BOdEeCG2EUVUS0MfLcrptNDnwzl1tuGXZku2myXfeKY+49c7IoBH/ELSlZOu2K4ROlmK4L/kwAaYP4ThwSLNYNfWbaU9skPl2it/fUZo4V9j66H920Rnjy0e2S2wvXjm5PCPzHBk0+x72EgeDnN4zeg+/4deT5fu4barlOI+BhaPjHYmi4IzT9KxZ9bbt2OFfKCoXn7Qnhn5rUEUkboA53Fs/XwN7fe+AAfxYs/eivbKmMyYQ/kTu2JIFX6CZbSzO6FrUL4yypqwz36s5WRnr114vyXq7ubM3w6qoUxlSogJ1/8GcBtZgylpj/RWlTlNEMorRsoXe15I8OC8Nrx4vSFvFPAN7neRFhbhQsSeh4Ubb4FTcTQfFsMYm+smQRmfCWsjULw4k8XlDb4Xtmeq5pO1A++Zm3eAahvLM4YGeOF1tThwbMuoldlzm3JyT5aBHlM4nwu2j5ji0v3DCijvOjF83xHOJvgBHMTySxXYSmRV2wF0f8lzu2DNMmcK8ylV32kFS8Y8sOuWN+RDwnbSKt/Z6For74CTvvyqAOEkAhzIYIzbIACRnCrQKbKvM4te7BUiYnHixgrty5ErAWCyMKHyhylGROkQeF0gbPhGHu9oScM7TQ4QSyU3/PQhYpJSDBPZQgdArIygEzmX0PqQ2oS2IXEF0x6+AdW2IbP9ObgLoczBtHLmyB5OdTHkgDUxDfRQXEaOGkwOx7RAxOmv35lOCNJYpqeCu0G0/CZRixhSiVZ7FqkVpN/13VpVARMwNj2uvsYd97nb08K9/r7JWxbN0ncaBkQ1l2mFTQ8tiSr9oWr+7sXPGUGRY/5JoQrCgpl2Vj+T+nlfPsSf2TYEHqn9KKCa/Y6+yVMwosmGUD8k/XwriinlL5qzht8ldJuEpphLVQ6Rt/RerFnwQFCPqrws0oBsPflQspqQhfH5BapN0be8EhrTkRP9CQmJ7j8NO1H8KKWiEJbdfkxT649mfCfM+cv0iJPX2/aE7HX3XnApwmikWvwXUAeuINdjgGd+QRUBsHXNgKOWNMULuStCm64WgkOM2EpV669Xxz8iSFEuCgsNcp2bCcBlyDeiZGgoOrtzqupND8Rha/s3df7OBvaSaWSmuX3Ca9oSvR6BQXSX6p25oJTGXjr3VolSeJQNNlwEyH2gsMoY0DTQT03hmaMb0pkUVgQ0U1Evocq7eohVBbZ1aKiVbSeFKSSNSx8ia9wJIhv9WjBbhpMW9BJBgjUto2yg0LO2q6Gmr7oi5iyui78OMUg6mkUfFS84Lwe9MLWGk7CF4TB8wY9DVjvGKBCUkAZgzBCeHAgAWfUDLoE35ECHcg5WCEEQ3vQvLAAgxEdrg3VXW/hy37JQvbjSO2brejfrt+DzbUb+RF1DFiTd838IW3w3veX9hm4AlGpOU50DIUNWYIubfQtQothT4wOOH0Rii5t4Mopg45u/oAIddYm7y7hh4dx27Ro2ubrHm3UNoSvbXoyrac2k5sl0AxIbW3adyD8PG65qEMZji/+P4dJt8QAlernoJ/1nUD6Hy2CYuFTkFB7Edhmy6abIftEsd7gHRGHsTAwcUaEMDOb9NR6E2jVvMRFVrNJowYdSq6iDyHua0axEdVgwXiBVuvCixlg9bbrLjFnEgjKF9iAeBRLosAo4CkWHiE+r5jM4tYcYBLn3vIaruZm77hMBpuTheaiAlp2ygsWHa4RtxyaSccnamzx/zQdnRZfq7tRQwWF0uIlJtbvDkty2lzCWKpNyUQ+yuRMNAXjsi8F4WHyJwa99SJdY0BRrBtEvxMaBh6po3zQSm4pAuy3yd/IZYdgl+21SED8hcCIHXggDgkf4FCrjVZdsgIf0EVRIeMyV8IgoJoaRJ505TWJBZZaRuTpnEvbS+9N6ex42xGRsH7tdHFXeh/E7LKGt1vRGZZo/+Nyi5q66G32JAACi2tMD0cwCZ2d53+227vaNMD2Oj+3rHAZY4xQcfhQoOos+ctZV/adSod3qoZfdY8ftJbUYTzk/DBhsRDoRDXQVPAr3bI9hY8ZNQahU7EE0r3dkt7mnrBnRw7mA+atGcgsqvuzZm2mxQmojARMEdSDG3UkYxzadSR7aKsDjdF/n5KuwCLokEBSGHGjMFCQypzRjyXdQVtogVSlK9t76Ckval9v1qDg/IWpxFj7kqNmrEmElqhPZ7Izlmmq8n3hcD1Z8UObCJ4cke2/lme6WxBP1d1Vt4yJ/l0MBhzDaaY9BToOl+whYf+6AhIO1lGOvJ/i4V4D4AXNmHM5Rq6hRcwNLtAn1Xtu55rzOMZg/DssKyfS8/tQlJHMqF4BKACRpCHZMHNR7YbeShQd1F/xMPLI1h07dKqvbfqeROdSiS0sj5fCRxDlBi9B7KIzTnhlTNIasgB0BwA+w2WNRRazQQKu2wEYGgz6zYVtxF6QL5DLHZvmzw/Jvwnnk5ZUNkHL1HWyXuRvsJZkogB9BvkwAgjD2gdew3oA4ird7z7qp5MCkRf1tGF2xVLh+WwbdhQ0PGCT0TgLfAk4MOhopMFNaYBK1201wFj5OztKdkH9Bp7FntxSMRKnjqYocwLXnDyqemG374l/fALeAMdIayfgUhJ1X3RhVQlynVMWElKiWA5ZyBSepiXuDF74cPAoO5SUjnND0CkWoEBtO7QsgPIH1dJ+Q9z25zDSZM3beSRGYvIQwBDdZEV8LQrtWRTRTJw/YTxAib2xntAAgLj/s/2bA6/VLQKb7zKptMlg1L4JlxULgu22IDwUmJo0GbC1WEQ+vmnT3CFpdt8L33Pc8RTJWCJJ0ey5Y16DsL7SulK6RUYA995KkAvIeVreq0tqMU6ZBJHgGIiRgEwJ1AAXUxkoUYDC+PAbzgwdTnoxLvnVihIdhnOPafZOuDWlpCg/TuTGYewj0zvTVq3f6+mcdFBo0Ztt5HEwTcq2RuHO6hwaQNvroou7qQNqeoO/iuXp9J9Vp4OQtZ6sB0Hfc8WfqQasPBJofKqkDsClI6HC+sh5J9vzANTzhd5ifAHLVQtruM9tGEbjvdQfcKhvVZMo7ZFLliVXrJ4b8u9v2fyzKXCGG+mogOgP4OLaI3X2mKWnaw1EIDjPYDpwmH3DI9LM7kPQIhARVxN2ZmNxTPJgq7px/xD5AWJBRyvoczXWsHvq2rRtGN4Wk2adghPrE3TjmGjGpd8D19Fq6YdxBNr1rRj2Mh2rzuIx9jvsMm9dgWIBN6UhA6dCM0AdUF2T70lPLfF5RUasSsdPtp0KXC9V+0VV4N+XX4egvzbuFOR3JFnIl/40/qWa7Ui6kN9siRYi6NJQPsd5SrhlqEm8hfv2l9YNVfx9Ry9mMXk8voQ7sTTpluHTipe8ELAAX9CEkZBbEboNYQv+qpWH6hfox4Qa6h4IeMK4t1quyBroBIURD2wBz9QH7UHdZ02k7KwOb5UeC7sUHlcx26NHIsdtRK/lP6Sp3tFBw3ajtGeSN6fvq1o536BlGiY89gtlXDfQGKlMOIQklyrwRVP3pSIBuAdSNPX+bT6kSx7bTAL+UKR/UgZO2C0QQewTfV7rZ9DzRaDxoFNKt4FeY0Ffzw5SzJhoLhYQWORdhkt/Iac5/WH61f4fk5VeUkzDVSFv3NSru4rwz/njPyOxIxaWdfqoCNOgDEetR1VcLV0u0AzvFwAFQpiAN0ksjjec4fEbk2f0NQjhEaivx9YxV0WWex+8z3wdnk+TIdGAJSjudTFlyowGvBu9eLoEdwDsFkeV2dHTAuWc21HrGZwobvwDduEf1yDWlZgLGgI2gG/0tJ3cfb2ipxaFkbFvKXhHXnPfGdJZBChiDbRU4W+z9b9IZjdCj2aYbww0mjKyi4LrfP7fEItYs6ZeRfGC+2pznRogXcgiIjU1Dnr5ro8hxROLterfXCTvO0rTJSZc6/ZTr4y597KOwjdNOxiX0AQvlilm7V2DL6l0aAJFFp1l4twtkKHtc36NFiAXXpS3/gVDeiCQfjWVeBNHPDDa91dwCw7YGZU39t7UXKFTsLANDBKoQGFi+xM/4nFV+gL/QvZZ9Oq7wqdDV99NhmzUFJfpSsMo1iJI67KoZJem00Qi65+trw42iTnD0scSUo6XHdRm3W3YRbcrNP1+G/zPlZnvg37aMl5uSQezQHiERwwlsSyeRazEJAfrRhtpe05MoylHUsWlgmu5YDO6zvYDHNutrDrcOZmPWyALTfraH2e3LyfFgw5ZY8rna5NMeLq3nxDpB00okhjoDwXOQm5r7OwUkJ33Ruv+wawURHUQn65uCJzRi1V3C92OPWCBwNUSbOA6pz008klheBx+0AxIJC/om1wInGpQ6yUXdb1STFWzGDoCqZ7sYCLAWTJgEc8xMmEEK1+cUVmNGIPVLFqKWguSQcBnRk812DDKc0YQLJG/EUN1cHcXT8R6AcC1Rr2AlivfOEmzKRxyLJdkQRqu7pHr/quTPsT6ClgVElnVd2BfIjVs3rb9eNIOznB13kT0mJ/cUUov79rureYY9+zdn1nJioa4OR5ccV90vzAizzTc2p757No1bsHOVwe7JCla1DTy/yRVrj+vOMzAIXBVl0nbyh0EVNiHaq7it0713twDVz9NeYq2oGwvNgNYx9Q5DnwDm5q1ShQ6GuwqV4crbWr0I/rGamOp3FHRa7gegTbAUQRc17fr5o+uglXENE8qKRUwmqrugkYDRf1vC6JYbZYxAEKhIYS6odsMUE/tRkE2c21rg/Z/lbjdElf1SvHuwjYP6sJQ/JNVZGAcq3L5Rbu7deqT5AmvLjSV1/6/6e9g9/XHK53boaRCX6VlS3tODJ96bvs+cytnC5KOuTm7EqJ78KQ9OvfLrvXry5vOAs4e/Pu+tV5dY9c5q4nmtIueSe8w6R7L8Cf35/97bzDEb5ytd5cXN+8ukxrQcnKgYKZyQCZbVI1ShgfqGCZyXuyXfLq+ub0xzcX1z+/Oodh4XC7v5xe3FR2hz0BVhyrPrGNlmW1ITRXfkL3ISscANCkSb1n3ZNNdMiCVXqyXd58Xeshq34OaluvbHRBP0MCTE3Q5BvwE5ZOtmhRU1w3c2RS2QXy7hq+nRl4iGHXsPjvr2/I1KGz2vZbLUzl8wRa9GkYrs9G4ERy8uVntbLLgGELbXdYYk1UybvYfOTpw0ne8rR64rXls4A3Bhcaxc5siHZXhHe4TfGmU+9UInh9g6jm7JBsDeG95bn9nnhIscUl4yaPxA/nV6pko0ri8KkuJEPtr543ZTubprB1TOkZwycYDYH8UKQD7wKXOJRb05UREeHRqrxiCaafrhqo6xlQpsU4U1E68bGGYTGE2gHd2LpDQom3/WaVnn2ODwBhfAIwoNgmBC5yN7GpGk/YHi+oCpBIAvusi0kEq73IplfZjCFWNIymWI5o+Ah9cIA06CL2q4FArnk4RRI0hRsEKmwC2DfoLy7QFyy954vogPuM6Hr44Bc3vcPz+1gYKpLFj4jhRy03XhMm6n6vFG6pDClJD3dUDlRUhUHFMZ+K6y/p9UdPnXUJGpVMUJc7rDRdX4nLkMIB6Mz4SfK3bENn3JWK8O8tmswtdzazW+WqKBAX5Wtz/vPZFeGF6lbIdGxWkgzoDD+Ri3M5MRGgJ9Qi0nAEjAP7gmtCt3qYj2hp6KOzX+FHopJ8OvoV+NDcCyP9rv8svqw5m2RXjQ0Rl+0bUodXdExMB4bue+nodC0tqFne1NvTs6StdVYgj5aeXY7sbmeHlJmqslMdhQiraR/8yiqoPuN2VkLv5Vqrc/ElQVyyMgoQHbHJxowFC2Y6hXvSpiigaWPqxOFcG4rCP7QYjo06wVkJKX3/TvX9tF2SlNW5ltF/6JJwn3OKwa/ieaZ3htMvx3tGK9diYbtVvcLXil7151FUFpRWdB+DIZWNtPnShwwCZ0Ij1WpqjC9YpEbxKdqBYZU3gXHFTYckPDTLW5MunHUNotwiRg9mphr4qbRkgzcRto1HoUHLslzTdpVzUTtoD9rFs9KwcdiLBmMWxZq2CnvSoFVRrEGrD8yezSEKutGK/CJKq8Jmq6VB51xdw/j39GCV1y3lqaKJMi5SuJ8Mhc9xtpYwKMlxkty6nBvkjmHxKOnpqkgQxc2s2Yhk4fKrUHkvpuJF+eV4URRBSm7IOaNONDf4814jFXqLBe2GzKfctOsg1sc0UQfAA5w3QUJ4EumYruiCfy+6SM9mAQOLdKYdst/vDvp9PcBTIlc8JlBYIrt8Kb1sWgt/sPAliG4frr4/f/fLpQBXa/Vc8Zn2AoI/lzZE9id2FIL+S5hJ6nGfxaFJ59CMSstl1CK1Sqm0lmqfWiynWVG6/ZuvIDgrHVau42ZgzzN6n3WQzx9fuaRFG69eIj1icTKct/i9jqRqUXROE3AShJHBGJ99LKtdqbQ92/Ws6gZ5CTCHIJJMKeYIfBVgo5oXBEaWca2h5/JB7r/69WbcIZc3r687hEVm74WW+PnVZ3iYqrcoUkegJXfRGZEJ9a9YBJtLp12sqXMnwqYX3j1GhrVvWtbUNY2ZKApNAg4/2rVx+j+fn3fI9fV5xeSRegzfs3U0dEWjOQwtSAeF5fUv8npehI0ssvSY1m8QWdaI9Hg7ZWTHG2pGcvorQOQAUakxu46Vx1WEA5Wf10teYHPaPq750L8HzfvqBcePldZObEMJ3dLJUOIb8SG8rMZ6iu1ZgaeBc7kS1eGrX1Fbbyf+kbYYwNSeehoec/H6HcaxB7He+sTrBtqteQ1/JtSxZy4i4ZTbvLGVRexEtklDzbF8Kz81n48oWLbNTdoB604TYqkzm0IzJg0CiCKrMC3JIQlf70h6rImqVS4D2IPnVLuMQAG7NBWAaKOcqtWGCvTdZAn0JF6cvyB2CZxc620Fbdc5SmRsuTULueJJwLoNqa5yufQ8WOFcOQpXeYDKTdSDnTmoRRZWOIEZ4s/NTV1ydWvV5cvQZO4IFGmt8vrgoZrlt8d7/F6rGFbcrIvqQHQcVA3GFAzx3HPcC7gX9f2YnF2cv9fdKtK/utDwT/xD8pyQzgUuQMrOPV8rnNU8ddLHk4yermtRLzjBpOF8Wcy0uYvD0mcnIq1ch0wCRu+8OOrAAjhUY1QEPUsU2GbZevKvPyA4RiB+4y55fsCmLAhK9EOoQdHpbDngI+EF0KXHdmFv2D9j6nRNL4y4C2jtkRLyTNb1XkymsAGVxCnN1+XkeSNK1FrqQItkUscwmWPaWnOkKCEdRjFYHjzw4WchASWaD7JvsVnAWEjOmBPacUnCAW4wqOhTmEDX78qhE6ZbJ+aGXqDEWSdnJGlfbwv7XD5o6YW07qBzVMNnUE0O3NOgghqEi0NDLV1NNgDeXaJH4zD9wu+7I/687BCYKbUAjt/yHlzto0j0t1LCADEKJUtAMgRIEpAMA7IEpEOBNAG54aimrmoeCKiAottUw4XW3327x3rk8zRYDDr4n1Hv+LjiNfgPuIRLcm3wDgJIKtmNAtsnkPXBNZfkngY2vydsl6jKcj3hYyVtFwf9aA46OUCOgtd8VNplg45cGllKru7cSyKeOLZJQkAAj5L7KGBRHLjpLXJ5eiO80D0t4AF2UUaUgkjUNjKpI4R3O6cKlMXQExvGm6SQcJj4i5YssPsIcF50ain8e36GEIyonx9kgkP5Ek3lcrw8jC/rL5bOn7dmLKJYw3VuPoDYsGA0xFytExY9ALogOrw+eISBTkywoUimbNS9XYAhi0Nj+JgcrEKw5eXlISNYXrBQO6zvJ3bb9pTUaN4X/6J1QhFnrApmI++7lDRWYBOdLNvMcbWEcRvU5B5LfEDZ7sDDgYL1au9krz8csUH/YDpmJpseUevYpKMBPRq9HFp9c3QwQovT5zfMnUXzvZPRkBuY3qFSDXJdJh1OKB5M33PDBrnKN5JLvG1S9w0kSM93ieY3uTqDdonjDddzWWHvRQMdJTt88pZLVi3d5+x4arqV+2PY7tTbU9pAt3QvMNJEWiJMUoYQNZtQUr1p239AckkPU78luWiXUjSwNhVpmgaz6G6P1D1ap4+qvXuEzSsMOtk1zUsbqmBAtYgNoCRps1fY54Bh5hZNy/qMyFPqhCzfiB8HM418dQV/TjvnolWvaCmBWaDmQjQvlpBnfX5+IwvncQTvgOc4tHgicwuoK6fYbwJ7NoOICX2B0kTYYgYL+ln96wAvzNxfVNrPjEeh8TiMvAVgQ8tpNrAdQ2QjguAXWUdn73OXxpYdcRsez9r9uRtG1HYBJ70Lp4ICdlvXFOnIRaa4vZM9OOUxDNHz+bzRkZLbY5pxAzkbUQleg1azqnFsW8nrEc6twRF3DYsuQ8ObGg+MaTxMIenFA+ib6TIR0KEkHveYp3EPe0QiSQBIouNgaYWQVuB7Fl0mg/qy+UUvrkLMUxMacy/O3AuJz+WCK072ToZjpEX+y+AJxsYWExrMPIjB0WJ7Ci8k/Ez2f/vtt9+6b992z89fcMALuUuoXRRprtbbHHVA4t674LUH/f4TLAjsEVCHxdXK+Z3adP8ODfHRGUQTpuNlmh5lrZAx17gXkSdtKsa+leNA1XVsk4F8fseW+iprTN/1siCT5QNZsyPwCvwdnjaP3lfeHwney3yaHYX757ZCGWANTdbzlzo+XMsFqm44A1F7wud20e1unt3Ns7t5/vCst4Jx6ZRHdZbrlYVnMaYQ3RN3jHDHCHeMcMcIv54MKjhZlVy303+vqP8u6oDW1Zxq9sZiENW125vnuDfMsqPmQsVOGthJAztpYCcNPKU0gDzoHn1NDaHMKxLWL0A92BUJmEQYJqI4uWNLxT9QMcPlb4HqJ5jglbtb7NndYjO225hnuTE7h4cNOjzodmzzW8aV+juZcCcT7mTCnUy4kwmrZcKEW+6uuOchfKR2j+p9aOsdFLLApo4hTmlD5wNeRuMs7gLz/fve29PL058Q2/3NxdmrS4B5/6RrqWiVL515YrzRgCpSE0DePBejgGyrQzKTwpC9wrkiizjElNn4xcrw3sqlfV4cgOuHMcdyUpFQ4rIHzhHMFhxhFWJYVyFe7/SXEIQqe1TQ3nXsco+Mt5744SZmIf/pF2a58ueb+f/P3rtot20si4K/0pdzZmLvIWmSIvXK3feOLMmxEltS9EjOTuShm0CTxDYIMHhIYvZ41v2HmS+8XzJT1Q80gAbQpCQ7O9FZ55xYRD+rq6uq65lG4p9vIo//4xKi4+CfGRrmmKrJ65E3m4XhXzSoQaeWD6N1WUyAOcq3wfe4HuLPvsh/Hl/kh3sSK5wL8nKd2l+Q+n6O5fHmf+gb/rDbhwKBJf9fhAFLvN/500zEj3W0qDVjhGoaeL+lTMuwLDp2S0FuetQZnUz3JlsDd2vXGU1HOwM6ddnW1tY2c3oO2+oNrFa49Dry5DpOuFiERpzOH+ADqaU+v5qbB1N9bj8cO+qHr0YSxScBTh+KKNOIKQ1Q7YhY/K8JXbzs8t379KCujp4RgAZK8sFAUCzOCMnZWoek1lM6rfztrL5v60d5Nl4//Y+OpBbM92YeFw47WAaog/XbbPRyDoMyrFcsWsRn00sWyYdRMe1UMPWiRUx4BwqisCA877UFEZmUBFKxxbxuFo5oZEX65al40NRyplxqP/NGSidnCT571vSXoGzWD/dKUOsgroid3Owq1s3yfIT/9kdYwQ6KzxFMIGwSiyEzRZvM0wUNOhBBjyky9YTDlETsnzyDqcxW1BaVbmVKzTpFcjksr6nih75bou1WTW8U4cR7HAq28F/oElQUIr8W30CrzN20siCVEF9GRpJ/Dj/LWqbxgvo+lHf3AtcDxQiAMQ28JEt+w1UUmLdthSn5kvATC9qEBSh3Y8Vg3OOCQkIX2FiXvBd6I0ocGoQBpiCSbeAFO2MRLOHXfq/XaxP4//g/H/ahJqcvEqP/zqIwbqPahpIJWAC+vzw7lTXgMPcnB1AXMiaRJd8Y/MwhpRQ6U++euRweBO8D2BpugJ87yU0LJ7iBKjzhTesl/iXVXjTBuhcJ4evMQYxiMkv8TUJmSh04cgovNYcGJGZJ4jPy4j963V6vL9ByuyMBgYCEHPtzAOL15dHhS7FbwCYxK/4PefEf/V7PPMDLLuGqrrncHMDgphVG3szDaOYkgmS+7k0L2/DfkYFjYmfI8Bx5Dqb1WgV0AWcF1UMDl9c0S30m0glCmkEO5X0BViiTKWEViiJp//N//L+EBiulMuQZgPRyRTet3k2rrR+gqsjqJeQuTH1evH7CCAumYeTACV8IEglGujsw6HH843lEEAc57uHCYS0wFgDMDAnYVvytOD1I5xOIIrAxYUJVigBleBNwC7H4BeHG5ZK4/lk2GMHh2Ty+chcX1tYShUkibwHpxnh87oIuIYEK8jZY5Pq0HobmMmRHuxSQsbsIoweNzUfraKNhlavw0Rb8WbGK1Slme2px1Nc+5PTR5Yc2P8cO1FmcQTaj0sNbXmpYQZdc4uER6kQh5ORLfR+XBvgRsaVPHSwHiPhgzYW114Yx9E4Wbf/QbtFgdTZt7f+6KY+vBOMjDFg+7M/1jAn7igTjxtyKcD5gS/wmzp1C3CXvPV6KG2/inC7Va0Uehop3hyyoPE3T0g9XkEkJ0w63SRyKWo2cniCh5oWFXTKBaoU0lrUAkYkUVW5VsgoswH4rbcmBIQE6cqkV2rgZkBqKPO14sUxWXGRJxChYTA6IcA4qm9rD6wlQ2b0Ed7jW0T4L648trBfvzhNI6tnVfmZCGzOhPx/BLi/GkHo8I0s8zyPlsreQzYFA00S9KfhTCRxHmslrZeGN3n0HUsPiLINeB7IPkzm7p1JGPsair+lCZvcDHgJbcKCYoCoRw6VYEHOhxO8t9T2XHJ+cd0YjVX77W/AO62BiWuwLsrjvd9LlUvyQDQaEnPpxSKT2ij9QZH5BnAsqPJM7eEskJHYixgIQXoHaM5AvofAKgtGLBQuDQi0RCKvOPGeHN6kn7/uDreFoe2d3r0cnjsumVX///e9/rxBPc1Cu04WeR2zhpQtycH6iuGxe/znqVyhApYBjopvKniUN6Ibu95gM2ihC/OwBUvgJ5EBXzWTOwJXM4Sj8HEUpRUFHJXftkjdhdId12cgtiyY08RZSqrjg4kYMu26L6sKINejHBocXr4KE3tef04t5kiy7YhHdNPK6UDSVsN/ITevVksNVvE9zLRcsmYdYs/1fN63vjq9uWuSmdX52eXXT+vyy4jxNcvCZcDIgmJV0mSZdcoKvNFEBEmVhSJZ878WY91mXOwAU3AEKXlpQPBCk4DYkakblcDDjcOCCM4d8spISNL4fK6Tob9X7DTLZC98N9NbgsvhBAEvDI3NDxpPf4+Oteq2eJkPlFAd4kOrtirXSNcTAm8wj2NyNRXsgZTbR2A2KHJAzOHspneN/DnsDtV/eqEsy/YbAayE1L5kDC8v0OVyR8a1SgYiC5/Cklk3SpUT8rDvv1iWvw2Ru1LDI65Qo3QwqDOqvBBcpMsWY/BsZ94OtCRrFaLeyuqMCrvKgrJlhmZE2sMR5GEtYVKhiNBUMZxpG/YvSzmhw/UKKmGdO/cypnzn1M6f+c3LqNTmsSbPsY7EWE3U36dm/rVay2xD5eqwtv6czxlr+9sTc1YKrIsk08dAo8agvcTgJQdnvBTO/qKSFNNqZZSLmCB5w3FiELsot32YoxBt9YmwJnbwow0iu7/9r8Do2nYIu6XY9rqew1ov/OpzumbU9kLU9/kNos4Gknq6eujUTrGf19hOot59Kpx2zxNZ9rsKY8yaF+FBhF5IvuwvpbSDmQKmHoe0GD4E4PqMRjy0tWLOuNMPVAlqGAUSJKPv/sCfNkoIQK2L+rSLWAF4aeTEQlpgAye94QcyC2AOa3iXHtyxa2ZD2CZuGkbSXIel5EruSOAJTXOxawoaNNeoPqC/59lGkRrQecoKPTP4JZchahYzJZGMUI+tOCUT9Z1fNdWjrs9ecnddcTporRQeKUtJANQHhiDgKeOuCvwB2zN6i+Cj2GZfJ8KEh51RLjdGXgPckXmKMJzb68WmuHo/D+/J41ogx4EiltRIOeq0M+01nW5wTr/Ha4S3Qq54A7U37u1t7k+3+aOAO9napQ7eHzpDt9bYn225vZ1jpXvWbVrSpelWHfpi6Ux8fR7y5Vlmq4UnTFAUgl/E0kTWPcIbF960twXuiqWuJoQS7KSa6OSSncArY7OkOoRB7DaMQ+Bbv3wQdMuj3ev19FBxBczUJ3RVJwpD4UI2OvHh7dXVOhv2tl7LtwNAW3VDJK1UTjxcy5F17PdV1C7r6dAU3Lp6jQn/CyNYAlBHEmdOIOgmLYkPP4T55Qz2fO1K5DH0tcXYwK3gBV0agP26570jvyx2roGe54fY+uQ7Y/ZJzHCHzINBF45HWeEfuBbSIUyh3qEYcqka7spHvgWaS3TuMucoV2IvVJZdd91TXvX1yhR65vGvEKGg1cL8Lek/6Pe5vG4O8RyKcpDRIv7dPTgRwQiwkinwBx1Au0QG4w+MDIU4nwsP0prUE7hzPlT8yfHMib8JuWmXI9fvZPHwpiAAwD/4DJ5OmG5yqPMRA7pfdL71IoGD4/78EYBT8TWqgJgwEykWIxjwakD5ZMRqRME0Mw25lK0uXcRIxuiDXF+/yMAgIncShjyV/w9+S/VevQHMF+oUY/g3thf/IHB5C5VmG+wRjl2bAc8VGEZSB1EPDfPCLl5Bbj5Lz6ytCp4lUXSHMUN+XR/6M4NuSMZ0O4f3P2n8oETmNjv0qyQXitjZJ64C8D38US+TVUgFxT47IHY0z5O8Krx0Lcl2mtNWy5HoheHIzIuh4farsKPY7/uddMvbiOK3n0p0FDegMSoIeu4PRqL/XEQ683/98JS/oC3xIgYz2Ux9LVL9sVuVqC+GjlBdxwB3PpVb5xa8fuGiMF+zl5s/lEhRwAXhOGTyqZOCsK8K0KelIfqayvIn91LxtA1gqTo6vuVnUxMtpjKGGlBhQR6YF+ssOuIXx+4KEqHwa72nggk/i6lsjceJ3/aOY76NJkjNP+M/EM8iuSCgz01gAZHfmxUm0wtQhLzSWGr+sFxunW7Q/GThb7pCNplz/nfu7pvK1NAO2iUz80gGNU+10y8hb0GjV4fESSM8yzlSe4pLfJgq503yRnesOFNNYgxbBAKoqN+zC5XJCGsWMRKGKpkDcvwFvgQVh9wlWsE1CMvUC1plF1IPB34c/XhFBCpBfxVizOEJqB1yF3gRYSx4kG2dOgxnr6qS5dL/Ug5DzUAznF9xTI8JZOpKMCFd1yYdHx8yJjPWDQcOjyE+XnAvScHb67h+gohGs6BWhaRJ2xF+RimR5Ec/Du+AmCAOHvfyWcMuKXl8ZDqAtfo+TMGJuDg4mdc3q+/nkO8c7875/88vRSf/06njU7XZ5sSOpFTQL0YD4Odxoq9uaXUN5+6sI9VkAKLCQzzvNe5i5nTRAh09EosyHGRZX52VcIFn2ZFSsseymi+D73GQkrhkPPiJ/rtARc97tsoR6fkxeBKHgTDZ8CKUaG6aBk4xF+8/t9UmrNIna95CV1essb6Gb8uwz78CmeIkCYKtGE3TTEulNUA/KdU1oj2wrS20Iqpo7LzZrCiRnk6Mgjlbk6dBSZtTS4L1eSbZLMSYnuxEKegIsbXl0H3QEGWfnmd82f6XkXKG75MD34U3Q4bgRE/DEupuHPhO/6L4XCKqbQEgjmVlb7y88PLiCOG/dzhGSClyU8ruVDJM1FrohBYFydQYTKFDSRTV6RitBt8aTc3KisaReRF6AOg49UijKlzfBr4KIt4mi4R94HGDAyK/Zbx2QCV+2CbzssvlAbwUIfhNwMt8mdxFdLpkrfVH4vYeIw1vmh0sr0H3BayyWVyW0ZISWvMiRY8LJcRiQjzDRx5eg15QsC54cN8E8BA8JZOumQ4HjENDMnApNIK3n3k0QknT3i5Os1OSKdckDB2VOSRU5mGkN15IGn4AOSYSooEiYlhmAb3jhTCYRu/VwW5yHgd4ExUAltViwsK/FiL4K3c+AC0/qsa3GPQ3057embEjChPqmT5KqclFiLKmR4RT52X0Tl0StNjxWgKEGgqiJq09e0LyodhMgcXiJQn4895ZZWHQoJLwXH/PiEdCPQ9+D20u8BO/GTfBR4OLHNonvPHD8U+SGh7p7swBebmnwKQjvAnysc3UZOsOgWZE6kJv5JsBXyIJ+AlcmF0lNCNLyIrzlYd+4KtCtyaeDDZ3WiOeDyVMxhlcMLRFEMkjTgQl3NqUwe3/245XUhwrmxizy96WR4dF4XTso6Nq0fA2aYi5TwgEjABdLTMQgcgxkWjQwerke9feVKu9FRO/Ij9cnhy91rd5N8OJnNrmKaBAvwygB3BLOSoiQwrvvxfn11ctvMzMkrgD1iuanj6IPaeSV727kl8BvYJQSQtxHDl6tEfjaGuEl3LSopI/U92OMG74JkpCLr14i43T9EBJfZLCWJlZU5jOXv32X1GGvAM0/2SCslSe2dF+q2fMZxB0zl8g3fj3qxV1yDGyeBaDxADU6PFu5TPoCVJIiQQc/lpcQZL1kUUcNmg/54yHXNwF13UzKmqZJGrFMBRCg1E/W0gPYyqi8wLgA1q8fOGnlJqLbYck4tNY0kk+OZaK1ssJ3p9fb0vW9pyGJQrhxMl/J9cVJ6zNXQkh/xX5uhRtkkKsFTWHrBbWyXVct3ammMi5mKHU9h3sncv0AOGiCRwuqtjMDPJCNIDRZ0Is650IaOKNXUQ50ZV1+gxdDldunPNUPueHL2vK/0Mk05X3jkJqAu3An9n43iC6gUBPFCmSen3AqVYWoSPRE2AO4yREcSluLSqOvjmdkyunP1+GEQZyCClWrdlF8mGpWV7icKAUKyQP5FUoeRI5kIN51ii1gjONl6vs1RwhtOqWVtlt3YfQJ9G+VHXmDctdqbZhlyHrd0I1dzdv5/KF0ItW6ApG2A88kYkL98cXPQaxvo4MQfZ/kJNTYax+F7CnOgt2yIOm4DFRG1Jym5Sj7WGDwkpEJ1QvvUD6UhhWWltD5LWUpfzFWf22kvNhsbHraZ25JCbhiJISPWBY669L9Fwjaiueo0QFZrcPE+eIun9amGIAw16kt5Q4vDtPIlKbhEn/f7MisUVNfQsdbIMeywMpct0+3a3eJBmt3iVMQVWM/jZb4Al+v9y0m5gZmtm5PfnnjDvU6i9Bl/sYDTFLPd2Px58aj8FPfqPvUD+9i9a8CCcmjQOPtrL9GAqWrb5CYpk7+KKLYUy/p0639cqLBky8nGtgvJ381nnplONulmMx6jdkFfOr1ZTNZL650x5tT4kOzsdRv5lcKYoLkUD/zkcnBCeEjW3CpfB0SiCbgAtBylcw5g5cCiVhAi3pjbUGfPzfyuUYgCogceF2+7LVBmad2T33mYtbXOGlXTFoR4sC/WpydGMZGrqiDhKDYjSDg7cYJNZghr+gsj1FEjPoYQo8tdLtizrVwocB0vgQi4JRdNWUNGsB3S0TAodZHBV1Ms/W6GlPDIzdLHqsNia/+zOZhYZQxkhvw/YVYCT2CV39PrPsAaNmFdBT2gl6/6PdiUFoYlTswr0FJIqsV4ndhq0DfzNx0cxq4PoZn2CmY8sUY7HNCXJfsjvUyfEOxEm7VWhNFfEiOrFnEHg1Rmu/OBpvMHkRrSLjm3KzajcoDT1lhJZ6qafPYr7BMCMtmzUjjzXYZdcc+gwzGY/X+bdgdtutwjg6+bQmoTyxEc9S2jaXirmESTcvHC2CNI5ZEnpXeckHvO7I1Aj+JVmNX+ls1dMbWHd76c7uFSc0xpGwM6BemydjCVvDbOOvXEf3y4k8Vn8iUSdbv9woMsA1/lF3GFlUNfyvkO5FobE6o8AAyb8DK6qsMzQlvzlUuWI1QhEjwrN7eFD3fs3T0lleea0YkNXm+GH/ci8EvQV2o3gEkgee6q0cL0SsV6snjcqXx4J9p5MWu5xTkL5NHbqpHT8MfGPE5ZW5EF8vKcOnfxlB5ACIqDYDI0iopDTiYZMlNyws6U9+bzSGOXXpYY0OwSE8Y+NClEKbNEyhR8iOgfJf8I0x5cA54fBF00lVRJ2D2FynhIPWOA54aPnNnIve+mKUhijxzS/5E//PEe3f4vT9ZvIe/X7//5/Xgx973R++u51enV8erk6DX7f64uxz03R3XYRfbt9fTu2lydur+2P3+p99+mR1cdn75tPP+t8VvjvOP5OotY++P/dO39Oy9N2M/u5Pdd6v3Z7Pu1WD89qe9vcN//P4d/TGdX61+3r2IZ5NgeXXxy9uL99unO9fhJT34gf1QmaKf3zgnDBwMV3YM/r7vS9Yq1TxRBgnhNCByPMBPMoGVF8sjuGQI348QgPMRIZ0m4YImoh5DuMTUXSKtwNKnCVDnb2JlLnsRMYgtZYHL3Je1NrF+tU1MJzCWxjnZvGbCrdr57qiXcOZinFEzA3q+78XMCUVMAXQULhVIVHmcgQ+JomQ2CyjtsFiieQjDGH2Pp+yrNxkaC4HzBS/RWdCseFjXbKPGstC5RgOtuRAYLO0dCgk3dnIyWeY+G9i+mmmMTmzjopebgnW5Z60cYkOTiwS5YUO55vr7Z/MVyPN5CJw1lCgDSU2wHnjrBCOzt6R9/wcLVlYdVQcpJfCfJzJdXNMTCbxeBd1oojFG8mIkIki7Fd3JLlmZshhJyUPTikggZGVPc7DR3Fy+HDSUwLEuPErZANYgprn9dhJ2b2XDyvf6ZwxU4IMBgPxT8wsgdFflVpwkJixIxk3SMU5TJxgbtrnuqjJ9k+2qcBqbVSWR5xiw6TWLkw6bTsMoIaKRUlL9xsWen3hpJRCNwP8UcqrcewvwBHVTpoq4QKSlN0m5zyT6CYZTIqzljS6T4J3ph7MxZGGsQHl4joF4hU3QHTLQBF0380ASzop88fVC1mBovvpyOYp8193AB69jZF5E6IMyShZNxhdgnNDFcmz0jw28e6KawNw5UUy84vmQFSvOL5hcYJBjTHrwsBfO3/Xg3On39ka9vdGwPzLCtaBYyQO5XcCB+v3n6EBz/Ij4V0c6i1RIjny4JWOfSoyrIauIoLixidVnALJj22aSoG9nznw/BMuE75oktab4ikmvPxmN9obTnd2h2+tvj5zB3u5od2trOtre7rnlMav4Y0JdmlATkVOT/at1+KZzyGlZ54q3QpLVhg9cVfCen/ClUP22XBrPjdIV8gsLJcoUgzQK98UWb5u3bs7Jo9AHwt6e0adxnag7sVOIKjXLV8G6r4VI9spNIeFpesaCItckLboiAJp3xeTkvp/z41UC4ibcS61pCcUKTJ58ujuzZEFqOfr0mDWTq2v8FeHj1fud1xEtzk0iBrgBSdGWLPJCw/rKQOP5KnhORxqQNBArzDjoHag2JozDNrdIg8ZlONo2azEEFuj6hGY5MnU+sWRcxQrrHAOqvZDGfNRa8VLQ5JL2M1xSMH1GbMpALSdyggNvzeBVo9TEAOiCXnOZRjMe1fTnVmjqVgD71x+/z0KptuABORqssuyQ/IkoYncE59lUGclX1qk3BVPht1J7WotVZlhTzjcVsxrsG2vpJXl0mBJ7IXDS8dPYu2X+CqsJQ+L1A5WJSszRzoFzAqpciHPcGKzbdUrMKgf+L2Ft5r5IlnojHQO+pEWuoPG3sMrpPR5q1oPOoG7BV4mdUS6vR3+YadDGmFfnCGd2UdcP/kMVGj6bvL+yyfv5dv7pb2fu7tnLgCVn0weJf00rDJjf4YgPQYxjTZtdkgUhUFEVc5YMNBRpRG3yLVWnbA0jNSA00waTSRlygkyvn88VmR/ybT7rtpWUKbK7jlFgbcw2WYabCkbWAoYLAIQKKbhZBUOV5qY5Fv1Bidcrzvgxkq5XDV2M283SYBozPYIpHiWvPISMKue6vJnVfqoVUbYWgc/rJtvUQBIwfyyItcnJBhN5x04IGZBOj98V4sRERwvkULe61lGXD4dysugAdTE8fJfjRvMV0KGOug8JJ2Q5MRkPDCsVlgX4JydsCZkybi7weGvhlJnLIlD5xK9QXuU38wvkQ1G7sHRLCjBeQxLDgIdBlKYr2KSrfHLF3CV33C45IL+zKBTP3Re9Xq/fwf+96vX28X9/eUk8pSnRB8P8FZh2EH2G2P3S9xwPNCRYwxkSt0B2MvkMlAmhypnF6gWrDCKD3mAIi+uPrvq9/S1cnEl/yCmh/fUHXDdTT3TjVUgqR85DvfrijCtqlZVCxlWYuMRM6wv0sK1aF1LhXWp2ahGMLVmG8MYR2WzW2u3T8JJSooYvzljWODxJk5+UedSnzxfrtmQiCkPL2pEy4+C0YZ38Nuadn7IEpEfCRbR34Wwm+Yco2SENzFhagiCdFJ/aZBKFdzFofSMGOYhIIAbj2wVNV5Zp+psYdyHrx9nwjCJgs7IeOdjBymo9XU+ymA7rOhkPdXWFJcbO+IDnx78yBYsdiqTDKok+hJQZ0uviOEvvNQ3cO89NDGRSfYLHbuogi6YxQd0bFCydR2E6m+POVabjKcUySAfnJ3VpQEe99612q9/D/wz4f7b4f4b8PyP+n/530AD+3+g77IF/4/8f9b7jRxY749ez5SEvbmShlhBLHdPYwLEPLk9B38w10drGAMPkMb/+7pzEqoZm6bGhmKgXJFuDFgYOgTtma7+HJCiJ6FjUnTTQjmP4TkTBAUjH6jlEtkYNunsLe4mV24Vc4TexvkaxvpvgXPYVdctQcIBEYRPIASnNFQGs2fd+59UgZIkzefEmPF2kv+reBEcpSBkoi0AuKUwrBWmoc7aOErlWMDnovu4edo9enZpQUsv43N8bdPvbu92t7vDVVp8ro9zR+BMzefcejTC/N1TQjTl7E9sH99w53FKH5269CW6C0zAR3tZ/S4QIy3NjxcxJI0gcvmA0TiP2ty6BkdV3Xi5BawXJrrx40Zb1u24CWIVon4g0nDTmQ0dMSl5Kcv4bgPRvJE6XQOYEUVxGGHLkBbObYOHFOfLcFoUFIpDleFklQmfUC0CgpCD8hWkMmmfqfIpxs0DlBXjaoKuKIXOqKi02xUx8KH76SHJwJ6C3wxg6yM0v0GkawhmjhIQBdeH0JlCVSfZhpr+Rg8vDkxNC/eWcBqD385x4n3z8lXZ+P+j80uvsffgIrS6h1hr19bomnpKRycdv/sv/8b/8x//6f/5vf3vx8n//9cO/Pv/X//aq2/52f9z5vz/+ndzc/F8fYa6TgGcbBgu2G7flDuN8fT6squ4FvGAyX5yalNDYc4V/d8DufC9gN8GL3n3v4GWb/JaGCWeHCxp9Ii8+3rQ+vmwTvHeQKi6hEwJtX79s81puoHvgGcHx96OXbdVm72Vb5FmfMubiT4cvFcYQlEO1mf47JGi8kLVGeV26lcicKNEck+2FsGBQfYSRVFfG6IIlLqMOX3nJVZlmA2UuvIyLSgydZpZomEaF3xsVNVeCaEIwuZA+D09PujcBJCIvYtg+YMlHUUdvjDnXxuyeJ5ZDDPqoSOAYUPRjDZ8xj4KFj/Uh1A4yueLSS4xJO7VKVLGX8MT4ZXjK4QKvmR8JNt0ohubZPrh5zJY2nTTeyDthsgDLnnieoI9PIR3tskba0HgPSmKdJOzgP4jvBZ84LYIgXF7fiHLdzQRczvAmIgEA1TvHKiCbH5eD5dhb1leF0PlJJmYVuEelS0uWlzLlviXAxSORpNzksJB91UN6gZ/y16MXA2ab8GFBZ55jA/X30PBSOVO3WxwMBtBnqFgP/IfDz/Qqz4GqrdBYrTdDGrn5D9m1OETu+Ee7HMXTf7RDLMKvCnQlOEEwezOUijHr672WBaHiGv17U8Jjg0xbzy/4xHIfR1zxBJa1C2vrodmh4ErTYynRHItpyQdlAbaFIyysUxk6YZlvqIMeBSdWyaG1qvJVUC/PXZER27SqtppBru/EjJ1W2fNcL8Je1Sigjz4+n69iEHXGr8GVsN2aOcvxkkZJUJ1ErzTGd87ynHfhozw0k17DIpvCCZrXZ4JzqZUB7lhytLXfyprWkbGyoFCVJT28C0xVpSoNd4hFM2OoKyirlow12uFLOgEMQY6SlPpjeKOMeakKXkvUiqWa/QwkhivCVzeJ2pbxgPJYUHM8suFXOxzHicYuu/UcVumkV7JPTQVNsjm4HP2CExcibCPxzwu90NMPE7vj1fCqtN8/AOLIjQhgyNVqcDXhVLVw8ngkls/xGIRWjPTU5Na44HWJbtVaq0/hCxDgygs70VWj65JNKLsChhmjxuqcf8TnPNSn9lxeSuy7w/NGmUXcBE3e1mbSF10D1KclmpUAfQS60iR5lqAj5zRB4wtJ1znB7enE7Pybw8Y9z029KodxngbMkLxMewwlqd0mNP13yTlGW0N+Rj6+3Jv9tsTrQGr3H7I6fajiQi7svXE3Xk/5+OUi/DCxfKVs+n7+0sKKsYiTHybk5Ki2noigFqHjpEuvMeEcDOjFRLYWefLLFkNNeqoWpOvJNEodalnNAghs9gvRI4U+T0eLLrGOYBWOlsSogqQCZq+CqFLwc0yo6XQyxe85t46US+fynoaaz8UpIkZjYz51j84C0Pc5xAs4jNAy402zQIBm/Xq7eQtH4V3w77z+62DOqJ/MVw/YROMkb9edAhA0nPBnQhitsPqG9J3pZDW4TFhbd61qhlwsePKSpiaN996uGIk+jXILWaMiSVX/p3V2sQhRaPKdbIDvJuV4HqkqkD3qVB2Y5re02WDVpeTFTYL7/eHLO8gWKgOtc+ZqU7WHz73cnvo6c8IJDD2Xx7i6uEVoDl/ONwMf2lqzDzRoKGMesapsB7iI+JxF58Zp8tFzCdqjs0i3JdQdy8/+EAdJHZgwbCcbo8NLdHHMWHAHlktnztzUr8oToqc9Ez2wIB52yTZRH/FoBpoa8AoAYj99AX71YcEVMYFyCz+uc3CGfX+Nw/uslNMbS676ND6dMJ+5Y6EY1kavBMuB2r5oaZGSBnynG2w8D1gxA7XAMvJy1rDHnAAv/9MMvYzCJxmZY0o1bV0j/PCvJi7Z+jPXMK6HiFyoPHg+HqvjaVLMGVNOZdko8JoROp0Wvbns2FhVgZGERRGFF2HLUGME5hR5mj4rer4hpqAOuiM50zPOPALOSGCuszfVB1T2QpdpzecxHxeWBXwQLggVo7QYlCWZRJVmg4b1wu7R8eUPV2fnug5F/fL+7PXJu+OqRM76kuxc/h/bzb9pVQVOafBMhNMQso2oCE2wU7Ocg82MWha1oZPwjrbJ9eVBxWNibUEx4/iFfUJa7HmYxmyM2DM2h/4CavB4T/gufd/eqc6EX5z6Uzo9uxpfHB8cvj14/e5Yw5ri70enl+M3Byfvri/gL/j69ur9u1a79e7ku7dXb8+uL4/HVyfvj8+ur1rt1vXpD6dnP5/aoJq2WR7qYt5oblvQzCJg2jfQqcN0kfoUaqyQd3QF9Zsv5960KfNLxWuEX8grcXFtj12/758FgbDhiM0Oq81IhItOqGeovn6EvzNX4JRV2DfvE+9DlMT+/vHFxfjw7PT0+PDq5Ox0fPju7PL4qOKyTL2A+kdevMQUUdemcvBw7NgMC7y7sq2M+UjjJgok/tV1wkVlnaKpY/AqfeNFcUJE5jSoJXxOIa5qIxyBfKkXiLGVm4TtiU1NIZBbw/XvL89Oywhfm9HAN+3oHZQJfbQ9LVmEWvPAYZdOaIrWL1xZrQOJoUftvHtVj3/PYB8DWxI5CVx2v9lelHp9g4ulbDTJxES2IPc1ee2HDmahuvIWTYlYK5aYJNOJYXhvwchVSDiyvl4lG49uAKscHM32vCbVJqPXcDYFd0OOW/hk5GdV9yC784dn78/fHV/prOzi+vT05BTC5bSPwMuOj2wY1EMjcVVqC0+YefMBuEWJsgMyjK055vlpUHgabKyF0YV5OS4/sbUEuqzbQ14EBjyo1uE/48C6Gp/iWW9+SOPEzv9lTRajcq0KF6RPSbi8UMLxBoxKSNbKx8R2COlasggnns8eaQnZ821TFWlmB3iDGQEt8muZHv3jqer9ud1KuXhmDZrIL7/cACfiZ+L9WMS76M3xh8SbRFrBHpcFbYSO5UzKDyFwJjtW+UEN+tAY7Wky2YKdXc1gWTIlK6sofGqyG9l3L1iF7DvmbT62/YpkwkqBVS/npnHHYUESUb+vibo09miH0TiBH/GPIIySufmXgfwlDtNk3s/9pXqkMcxR/JmlcJR8KO1vbHPHcm0Mfw7yf27l/xzm/9zN/7mHGKtGxRkpBtpnG8/DJo31D/DPIf+n2nYai/EsXgMFydDSilGNLxV5w5ciM9/6CMqicXPnilnN1ZoM/Y110opYruvjDUptwHTZpJlaTB+PYK/PRzL+8RhCQsno8yzcP6Jwn1l0HsD6DIhjVk/Kz1JbAVjdoDI9OHn3D908I/7++fj4h3f/sCFB2evANi2wnr2uP5Sp9Ub7A8he1+0PtoajXyq0ibmJIxa4FlRvDb07wTHrsubkvfEsa3StodV9ohWspYV9ojWsraZF1ewTLaZBeftEs9oqZp9qekvN7ZNNb6fafZLpi2wP53h2dHhUZscp8kM4XWoySh2ASephtrXCLKkptun6+uSowXW3vzNkez3amdIp6wy3h1udyWTidIa0x9zh1Nkd9kcFP4LtitVg0foZTdgd5f7Myu5aTBWq16nmtlDMlCYPnCe5snCdNFvtT3laMM1y35Stu7+1RrbuNYy36TKGBG0LIqIC9omDeYmy9MPk7O3V1blNOu8yeCsXnAewFn9D/Xwh8EcGuH2C9N5jZ0ffDILqeVCZE/0yoYFLI1fPyAUQEx1UHvCnTmpbdbkeI0N6NWZ9zpHML5gXXQzOk37Xj/4YSdHzQR4lcIiunersx1VoohLp30U8hQNeOT4ZViyC+lWMp11cB4UKQi/mUZyKzLVtUToEErTzhdeJHY+BdObVGOnOk67OIgVzVYQfDgZBu1xca7WzX7xA/PbhKyZjXgtn876FT+4/GLDxwZKna/XC4KjC+ekNEAqatSPcSwpvdxhMQhphotHrk+Z7AOlWxwuWzENT2eosBCOflpWIHhvjG+wzTebvcRi8BJCgdhZGBtXFTyxwQfgQDYy5GwuZDwpZkSOPgT+q+s08BHfZGpvTmBUY6S1fU2UuSddfjhtTbh+9OyexQ4NAZNpWaWUN2F0RcC9goxVI4JldPx6cXr29ODs/OfxIOkT9wT/9fIk//nyJf74+uXp9ffjD8RX8qP7gn87+E388+0/88/Ds9M276+PTw2P4NfsLPx5dnJ2L9uKf+PN3J1dvr1/Dr/xf/Mezs+/eHYPL3fXR+PzdwdWbs4v32Mb0Qe/y89nFD5fnB3wFxd+w4fcnFwfwEf6LP7w/Obw4uzx7czU+Ob06vjg9eAefy79i47Pz49ODE2jA/4U/Xh68O758c3bBZ83+4h+PL346OTw+PfsZP6q/+Md3B4c/4O/wD/zpl7Mz3Cr8tyYPqjqyVrt18PNlq91SRwP/PvtPdBCSJwAurxzorXaLAxr+YYJm9ruCW6vdAmiBz3UJKq12i0Oi1W5lO4c/1E7hD9heq93CTX3AvIw8AbkMHyuweJakUO86a6Oicav8JEvyjh/ODPa9d+EsJEuazK3GAEu/Q2MT572OGcFP3DMbPR2xeIugtQ8ifdcxO6QxE+S9ZPbM0WSNMhbTreQoVp7mtGXGT+0YBMz0bX+o4jn2WR/tBKk6aJlLauQ0NyrdgEzOYqg7YZ5etqhbgIGb6JNUSe1XKH5iUhnmYohPtylI2cjebUUhMReXgphrZhMFVFKFJ+QMhhOXOUwKrF8TL2BvkPPb99Dea/tMW0e2eFyJ4jJdLGi0Wk+wIC9Yd9Yl57zEkXfrJas2OTh5+QgChzS44PO99ET5s8kgApALz4nCOJyC/TlhUUD9NpmF4cxnWCYvXlKHvXyWV57llT+AvPIY0sSSRVhY0CjyHPg+0RpwqSKGUmBesnoI0TtXgyK1U/d3zIJbLwqDBfQor+dY+yqqd/NrLAaIyYtYKGLaZMrciC6WL9dgovXS1aUqoJFKOesR5KmM6j+ZQCUkKP2oK2FuFLTSZH6IBULKQDmDj4XqTrwyCkjLUz+8E2WwAWbY2I4Fh5H3O8+wajSfoDKBz51rjYE+iKa/pSxakSWN6IJBeQqr2+D4Hgtk7kjjRrEBMRtVSsOJ44zHy09OTe3D8x8Oj4GNydM3czEU5A1oyRfGv0KMk5C41kT7yAdnRIfNQ99lJtH4XPsKYlUZ7HjM0wgN7y6v/jL1fH+dhRiuQB4R9CMqwleByLAdHZWF/qZM7UzaomLZdUFxmpF4LalIEyarRSMTVh5oHesKTkL3eKyeCNUSOy8ZpNdx1NZWgZgbU29925KEPwBdCpSQPyazXVeutIwcVTpMFcCprxz03KL0KMijTsTwIKgfE07veY1M7VX7NbBnDn24UEtxFeMMdFXowIm4vGUEhyDaEJDYUnsdEIcGUGtFVFUnyzRi/kqUBgWdOIrYbfImjATthg5gC9U6AfEG3yXQqehzvbSX7de5FPUqn4QtO5NVJ06YQfMTTmShM+3IbV7TJ/qk6Im68kPqjpVivlysDT/kUEt04sxOo3W8+pcRxep0FmXBUCyKL7y8JgybveT4LfVg+vr4rMApzs8ur8ir28ErDVViA5vabJ0R4xnRzXICRzPZBtkULJYTcclxsVZdEbfXr15VID81F86s6CqiQekMCpstky0pS9beiJg3QjigbkQVtfx342mN5F9C6IjX5xI+gQayzr9jTTcQ76ZI19ThvAI75tgLlmlCgBRY0G+V66KYFRWXWMqYUU5qXowA4QuDr1L54ITL1XgCHnbw0s3+wo/snisvxlCYCb7nfqh5Emfj8AJsWqcPQk5M2GLpGyOLUQoUXzlh+te/yC2NPESIz5/5/VqGPmcXL9Cwr89hUFsZrjxSuDEU1TN5oDLfxecvyMIzWQ2Rl+DDCbMd2sxWwDF+rqKXRK83vK74JUifJk8vWXccIQI1LjMCJ+R2i6tXp7oTC3hca6Fc9Vp3V66kge1WvWUOioDhBd+1wu2yaPtjKR9Kudhrnta8wgdfujr7MFogzhkPHgsyIkbC2cOriRRoic3J88zuFQWWX1PnE3h9wmZTEKA4vichlLjrwAOMZ71Qq7C6YrXoduHFn0D0m7A5vfVQGe37ILNJOYBPxhWqUOaTe/BjPU/ukMZrnOJK7a68F4+hXO7YC0Rer4Y3DF+BB2JSlEhFdhhwd30ha6J2okKqzKbDmu3W08V0irA/P7g6fAs+LuDgeO/xun1mRbo2bQXXKF5MnKyahZhvNyeMur57QZeoMNCltk9sZTYdaBJmrW6AJOzeGJ5hENyoi1Uxa+1HCrKTIp5TqWTAkqOByyLmYmXSAn3Q4Nv84lHTNehi1ENy6vk8z5BZfYo1UqEN8rkgVo8H7JcuUYRHrr6Oqa8ES7PUII4caY0uOcARgUwA/8UfljSOocYt/Cj/zcWIBfV8FB/gH/iTtnD4oP1ZI1XATCjP8rHhCwwIwTRa/1Je5vKtN13NtuLKgk7ruKoNWHFsBWZ+UvsiPLF+BNYTdajD60Lm/WoVQ+696fHSvdCFcK+6ZnlYzZFtTdEfXqDn2WD+VAZzDdQ/Db6myVxbyLOTxF/vzM9pGj9f87/UkV+wOF2nAu7zmf/7n/k1SkLPZ/5XOvOfBlKIUyXiig6rkUd973d41oDOe5C31fA3sFidhcique5XuVO90t37Yz+dSYtP0Rnm2YPq2YPqj+BBpfnY2PoDcLROwclaWsi9KQkXXpIw16jMytdoKvucZO9Gg+Jf083opefLaiQL65lwr1xGITx/a+gv+FeKVuTkCJVENI5Dx6NJraIiXy/RoEVa0PsT3njQq9RUQXU+K9/TXHTSYLSdB3WTc5vcbNZI6pz56S5D33NW8pBjOGWMXKt1KMuf9VruZXI90rkMNKxS8Q1Ih8fAgij0/S45SIgPeZZAp5n1eOHQeNImDotf6jqsb8EWF44jtmCuJ5CZrkBvRl2oCEz9MJjFnoujTCTN/vUb+OubNvnGYTH8pzjINx9qQZHfHRisaDxBUxWNJ9yCxWL8m8X4Z3F8+Fb8TbdU0XgC/kCowim1+1CGftG5SONn+VuoFEllVziTILAm4xVhb1lkKFiFTB6FdnzY7vpXppfI7iboY89QHytoRS1xvMpfzm9ic7CdPYFqVHNWrDDzD0MjpZGKZ35q0MaWkBanL0bCS0mxSRyugHwmHsuF25gidQgUTJPcsKut6wPnLuBWYxRRgyIUMF5V9DCRW2Pmo9KpaFdpzO6XnskhQedrvA1JPJOd0XbSesYGDO1cfJUmxAY0WJ+5ldbEC5OOReyVwa6D32VsFicEOpGee0G9P9xaj7DS8kz2W42+VTi5FsFQHjYeL0Hr1FAkGf27eMOaU8jipEvz+DROxvOVG5nx+x1wR7T2mZBc9tsc4R4su5RGjLGYcf2Z8DZGCx23hqxz0wGCRHTbHBBW8Ygb3rmHIHgtu9d5m5GPZJTTSNAKBKd01zPvU3EXiviqZAxx6tn5NYodICiCFL2u4JELhPsrCBr1DLzoDFPh32KysVUzYTz13MhfiQn/mxP3Z+r6Bahr081cg4JmxLJE99ahc+d05gXwtRDpK6N9n1qr/UfWXKu0OjDOgyKOC1HUhmocBfcefiqC2FKXJrSZe1iWl/QC4qRRBM6ty3ySL5k1DKgBuI8YvU0B4+FrsbOBokWeMf7RmIHsUFuSqHJsXpmeC7p+o1gNuXKHy4jdeqGJPsldyhYb77SQebrAZTFfZ5Bfs2mpn7+o2aMu7xFH1jLlKATxPJOOxyQdxQipZ9rxTDv+PLTD+Mx6JiCPSEDMD9lnKvJMRf48VAQThb3xw7tnyvGIlENB9ZlaPFOLPwO1SKAACnfcy3HFDf25eMSRvTtXrdvJOY3gixbTwCNj0AdhwaKZMFvL0Kav4IfCF/CY9rt/D+eUWUSDJCvRbbn5L+OX8ud1HZG3NgsdLd8Z9e0Vz7mZy5aFV1YYBh450F7DkcpY3dgcm8zdNjsBrxrEl90Uuis2VAcAEkOoG89GSHx2y3zp7+mHd3A2fniHfwLQ0wX8wv+FP8692Rx+gv/yw448sPZgIJr8d41PIsgIQH9hQLDMebM5aqhFx1KUWSHKl4NK26gk2ZkEYiDNMtsVzxIU5BJdmzPo1OWfdNbItvVC1HrAmbFBZ0LB8ILJt17auDdrCb50wa425HXdLEG1EcUA1cbodZNJSwN8A97axbzDQNWXCHI/GA4l4rGnviCUPGsOTxRBjqkzx3+/UqGlU5/OZswlH0vhjR9ffSyFN37Ec70ToPcg3BXd9SQDMAU1twvZWDp8KPIChYSXOUQ1RSe3Mbo7zMWKby6wQxadB6b5MyWKemiuv1Lkv8wSpS9G2LOUDQsQoDGPVH7nZY80wosREpFWCA8ry5fXJeehv1qE0XLuOYRf5TAoBglXvmLEWRhz2B3Kr7k4cJ4UQ36B8e1i8mtvNGw9l0wWuaGKYRUQtJuHZ2cZO7bpWzC5R8w3Zk7jUosoTYhdyCZjisfGmbjEbCB2KiuEWOMjrStLRfGZW+otEnwhBmaewnXrMadHsMrGIKf5MskY5GzxHDCNJxDx7oHEVZC7b+JcDgSet4KSiHWkYxB75TKfJaxDsb6aWLKGW0gxKZ8aIs9xNkhD48yznA0V0MxyVNbd2KxV5Y3d2LG2pEBKvMSUhwwvNX6ru1yvQpRhZK4qcz4J/oN5glySI7FLnuNI/IGftMnho/Ynz1Og1oNpCtRf+DG/QmiQ/6VGulSLyCfwEgoNPgdUj8mPt3FqA1yGZCz5FPxlwgJJUdUzjT8/+KMRcmWINxuPIxFO6Papv4APjavS9lyKWXjRJkVMuDuKF6s1PYS6FVIG1zIf6RnzuAmRFGQrBUQJYoOMuOQXMzsFoT9JIlrOAbU+6dczUH2ukJUVVNZJqqafe0PmYbX7XO61Qppjg3phNk/uGPz/DMJPnZuu+SgtASiTHKm4m2aIVqSpi2Y0EB6ocYcuvfGBU6wSXq3JA7PDOOemuZG7YOWjqVFGi1kCXNVgjii9byeoawqDhDrJmKeBsZmBooZ1TJfLKLylvhZZYLXj8nhLbyzG1OoNlDwTDVIvT8cFoIHqm0a2DZjy69HpJbkUcPnwAgp0xfuvXrmgDgGAxF1H1YqDGp+v6NJ7pYrBxa/cIO5IsHamYdShQYdynOjA3ejoDV4i/2PU7ZIjKP7oVHkduuprZUZNBnXbHDZO7sIpdZIwsgMMHKtY39hJ4yRcjIN4PFlVZx3+w0Ep210jmAqXugwzI4ZVonHbeC8sgGpGSKAoCZ2ZclLxwQh8bROpOoI8XFxS/sgTGbMxNPg7bPWjfCBgyPwDAro0qa9KuJIvevwJUkVGXswMwpP2JsehNALU1ulhLWUFxfYFmmZOhBmxls2WhjmnM3YVfmKBNohxvtfwDODB+u8ZWKxizcZTTy0XvL1BoOABx/DswAqcoiGhvLo4plKmvL4ullucwBo2FjFKW+K7uUQ9Bt9T3oLS75VvjBE2OljWhMrjrLqYNIv/bEYc3v9M+10ElVXa7JTcJ81Y/N3fJgz0gr638IQtp9/u9Xrk+upNZ5dMVgmLu+RAnp3sC1rXWRBG5ltYkNch6zZSGteNhPGzeOtMxRxVv0rOXNurSmCo7bSch4F1L5UvVpr2K3R7NqdnjXBmoRJCU/ThUJps66e6PcodaWNyANOGlzRiNmIgF+HWuxD66k+OSpdByKYC/za9bzX3pTihipixuruNIIEwFAsHHHtML3J97FliTziteRdHqEbSISJJX6FAbe0hr73QykdGeT1fayXiCds88SdmkPqL00Aj8zxvaeD6uR2fBLdeLo1O/fxZIFGVFAMy3jLBZxaO8MECLmJU85rfsRl1VtYPQikwLtOJ9QNO9knozPgSVN83lODaj/JMXeOZ+TWei/nH07jy9WT5WmrwPjJMte6jo3EVJdqm40m7hGkFPMkdunZ6dVieOe/lZXNL7z2Dq5pwd6t3hit/LfiflRzL8nDh7cRs2tD5ceo2fsUCaqXukSYQC0SGa4fHyqKxmWCXX//rDZ/gquW71eJiVnDbz+3WHZvEnmlulOfERJjqV59mk2zJfCiDAFklTHu+7wWzcT0RBGDrnhmyubmluBgTEzNrt9zAApRBPF6God/ccBl5UvlqoclzQqDgNq0Ld0BOow9SIiBy0XAVwBPCuE97jYIXgM+1OhnQyyY+U44Fj/PavY5ZxK/ncTZ+S8PKLzutNnFl8Lr8zhIoW2pBVeah57BNDkNaDfVlVclIWYsqOUN+rrph4nsaeI8JaQ7l68Azm/NTb6xQtWh49hyoNLLsoJsbcWk8n4Q0ciGrDYs8XvYAq/JBhvrMJMb38S162chsXDBb88sezNrjMJrF49QrL+iCz5MUnqaxtp7iIsxWaZyGN2icyUcGRjgU152qKAjr2ysvo0RPNHzK34oiy8jjVhFVy1yhzNvagvdKJplnrqU7V0BWDY3MYoDtq5azjjFyYGs+vYl2gC8I9ALgTmlmlLbEod3CfHqmajatI16cSzaQHiJCpTn3llDfWlNUA1IdXV4onSd3PsaU+Xl9zEXoP8CuWgGPc8wLyB3aLJ6C4FmLAmHgyswUABKeWIYGDgMR3fhClKkS1jxpqfTYZG+XKZ4XMB6TMkjP4hBjcQVEi3YOJfPLrkP1kyODwlQ/P96MnByZ/DFksbwW3ZnsOVvugO1Oh7Q/GTnbbo/tTQd0a7LjDN3dCkViw/laKkDKWnlRUgUchKhIIom63DRw5jQAx0+RWfITY8sY60GdHH1LKCl8RqsLlrJwSYqklpKA3Rkzt8BRhT57RI6owwKuUVm9v/AC+VeuotPjzy/cGuoWUAzMCXlWJr1YU/MWN9J5WSu4yjuyVXUVLHgFIvcCnKR0Kyldel3BboHzdP9rQmf/7eNLMBVJ65+xj5ChVftPbGXEtDidxCwZh1OzRjwK06SgF59qUwtnF6IsI16gopbQT0l5ESVpFAgvokLnJ6Ho0nnGWpNYJpmPqWo2+2SYW65jdcm0ReN8Iq1aNwgbvW5W1EfKX41TVQA2dL3p6gkNNd/EMhSn0WQDlFskd25zcxy6embEnJdbAx91EoSdcGky8lSbdYxu2rDcLMgU/5O7TidHXXJAXG86ZfhRLUGKFt9ymVs6T0GZXaiyuwhvGViE9cEaw0OabUY1Z9hkHpVxhtIUqEydXITokrMy6NHcLdynI8A4jbVmiZFvAsiMHE6zoflJC3Nom6DREQdErFWlxIIw6OBkj2NjLbrabmZzXWsUO53/pjZZm1EsbLSW7gHvw1smiL+tYUqqguzJp8vAJZxTJn0JawwRhymo4g29C6EtaNDnQ3GHG3jpiCUT13NFOWwI8cFwV6ixrV39CZuGEU9pCrfZjthUqPC5QG9eeD1QzGRbJwwmdQFSKwe9kfP0TITAHCpxhADOkEXo5iocPtpzuNL/sZjZ8WGE8cGP5hJmR2zszD3flerOWJh6vInPwGoTRrOx5jFU4uLlDMUei2jkzFdjs7eYDG1z5kBmw2keGaEPL6yLAfRhmOS/Y6RPEt4EL0Cu445lXjB7yblTrqmXxMyfdslFcRApCBJ6E/CwqQ7jilCCsh8G/YgKfMmceRHBSensWxKnk45pqJvg46+w2Cs6a5Nut4tFiXn4L7vibnHIdPE7LOuKzj587JLrmE1TH+TRmwCqmnLXfwj0yKUYFy73yZwmJGBcqHDCWxYRCChdEXjzxwkMIvBeHcI60WvwGArorNqCIHRPSm+5OS6/wSEadbOmzK7rCKZf0s+lemVFEmAn+Cq/lY1dZYSkZNa6CHk6r2VB4tJMid+YFdfHgV7kmQeF5BTGFpHK0nAMy/JMZn3Nb0A2GmNgNIuFTlcams22AtkZg6+aZlh4IpyrvlU48XwRvl5qlHksjB26pDUtOZUd8zu4YBVGvjidIE2ugVAFb1Y91oCgAV4m6BhgUbVz0z4Nu2pGQq7pe5AKT4SktQovIWvlXtnjJ9O356/Ge6V3zpQQdJqwiMzBd0gEEhYkmFsv4e8pwgfP2i7DZerTBDJVYFrkkyNUc6Cs/614lSR3YYe/lEUO4ja2gZseJ3SxjCWbI1ptW/7us0v18m9nMDBZpp+17Ztp202O6s2aFHafoAvLOIGu5WsC0RtckFvS37Di/CemZHnMcSVTKqH5M4k8dosvl5sgy4AFYZ7nWWQrTxgeQlXpROVl4j1FfgV8potnvwdx5BNeXT65CZQWEUPrKE+GhasyR6CiX07s/W7Kp4XSNc6PzQhd4ANNTwNG+YJUGiJOll2x9rhLQI1zcH6C6qOYFOAJu/QCFxRioHMgC3jWaWNDqLTnpD7lgXBVqa2qBYlmp5a/tId4Icoxt7rSHksraZehZ5q34jpKpdj61TobXgcZ8cwsJb1CBsDHUZz/NHzPx9Sy8T1A6M3laCs9WwV5h+Mtmf9tMq9VnIPm9NHsSR54yTgzSD+J60kmd5idUPgSqnzWZItKjyD8WuOYg9/NbjlF/3bZUp8yP0Fxue0yBJsORQNH4/FIMbUOOqJNDQRECysYaG2LQ7dLyzFvNXPvOvD9sLrQytIgJxlWj9Lg+vhnWsVPOFTJ04b7zfB57Lf0k1wXDVZn09b+rwZ3aPUTz+io/6I2+LAia/96uBNeCT4Fbc3nJpjoXnzNauwcTjx8zVp+gvUHlMEZRZSQA7b15ZrB8NPwGAj0Y3K9h7CsL8cSi7ssv2uaWd+U+vF6vK/qEOQaG7Yny0TxpKXCix4iCLyO/NRxwOnKsaNa2WHWzconUXsoHNN6Pa2SvoJ47lDfx4I9osc09Y0h4UpbwQlMTigpJSRueJDbJbXlY2aFf7O65RDn7Tm6+UcQTm2ZfbtswfB+Ab2CzF6t0tiJ2ZvnsEgpLHcikwrbjo+JWC0SAcvx6S318HLhtsI0ITRYkZiBel3LoNQwZy+bdWlOnA1Pu+yc+BMRm8r3L/g6REysC5K71YOx1/tccjxput3GG7lYPN/GRwNkZ0o93yomMQOoWtevcM1d1trf6fW21IxwK0LhIiWv9fXFSevzh2Io8OYnky3hw7rDVHMtAWBgXh/qedgjny+yvgcwwtwjkO94koINtSrHKk+EmlHdZRQCDAj2gr9gKhvnEJyEOnMQX6vsL3xQ0ao4pQ3i2zl18P0uFjQwZ4WED0r5pjZaWINBbx8sFyRKA97F0jlEdyxwPYP+/SCOWRKTME2WKfhEgHN4GK2kWzjOVb+sdZYDlmDzOo7UzKDATDlhF1Csn/+V5dx3bDKmAfVXiefE8t1p8AXzaRx70xXauOlMZG4V3epX4jDWd3a2pttsuDPccnuTEdueTPq0N3EonTjOZgs1K4RhqZiolSs411hlb9Bn/d5ox+nvjoY7zKE7k5296WDU3572tsOde+MqZY7pCrtsGbbmbWRkwWVLP1zZvs48c7b0AyU/YRNyffEuJuiF53GPHlSZZ1PZ2/yrlJ2S2Ldk7qRJRANnjpnNxCXm/8YKHy67bZUIuMFyX6SRzXwk16MU713iCoFIHy0BsVHZ0wyFBr1Bv9Pb6vT2rnq9/dFov7fV3RtsDUfbv1hZ9THlk1jKOIm82cxkGgTTCaETECzvwL/DyUqcGo+0Ul2V6akK6KNUHMTL5kI7BF+TBePB4zfCXHiOiaHInC6XLDCDO4MsmFoqkA+IoYfU05QPXmf92jnL2XlnPHYcwEoMqFnFnMaGXb+l8VxyjspF1AOAunuO4+71d+luvzcY7WwBsWLD3mB7h/X7g50tOtjeGg769UBaZA/vorkZPzxwkbyQCJiU2H13nix8G09AgSp5EJZWXDjnD5XZW3+2uRJGAI/noaPZcWdeMk8n+8sUl6M+8/HG8zD8VJNTo7o4s1Bg5tSyLLgd31Lbx5BqzXvK1N8GXrha4onyJddvHyvlsDtt/9kvyyh0RYLZD3ZkzFj42S1jV/2aptvDnd1dtteZOo7bGbpD2qGDXdpxJrvD6e7udNuSqHrxOP7kLZdNBaMLfED0sRGAbVaB7hdom2jWfPGD5k3hYQV+7N6abAxLP8ueD2dmu/ujvW5vONoejWyZmWD8Rh/kDBusZPydSX97wOhOZ2dre6czdLd3OhPHZZ1+f7u3tzdyR2suSRqomg8h14OHJEfmLV3CF3Likhe74KsaUSdh0ctNkd5yQ4Ck44jR2IwaKzvENgntRfqr5Z7OfxCEQhNd47HrxTLvS0Y9KlvQrNpIW/CD7G9+DEk4hnhmFsXwBfJLcjeyOIX8nFAqa/xbylJwRcV3V6N4WedCb3k9eVvuFFRb2m4JV5E32jRsrEARdA0PhMBz0iDu7Hant3XVH+1v7YEA2t8abu3s/iI9OPdbHE7csydKKrru7vdH3e3ebn9v+EvmBLQvvZvAlpXNC5BWw3uBl/ASYYUpeCs1kuf6teM4PmRujtgyfNg48h3+gCE43tqMUeKPYNOODGnS4Z3qQ70jKFWXhARuUM2zzHBB5UtLEoxu4AX/pJ8gVCmItYeWHeKnMYvH0zTAi9qgQtPICXQjqpuRVa5/DYvuqOKZW3gPFvI6GV5OefFIE7NEQRVNLiiw5zzLzXGyAg/RGIKiHoog8LM3Pe7FJsbce9Liqe+NJx66ExrO5hDiAJjvi+gc0Y6r0kABco5GgTeGU8o0qxKt/tU6OBm/Pjk9Ojn9roVZezIe3orDBeuIXzoeL/FR5UpZeFKeyHV1DYmBdDFh7UgirfuH4sZwgRjKC0UNxuKMgbzSxOP+xeOGYh6hjAVOY/5w5YOQ3CAE3z31sF7vPZlpiFgw8wIGy6SgkjTAVjYlx9j04RhwevDuH1cnh5fj49PvTk6PdXwQywBOAEne5NTroELFcsuIoeaqq38oGjU87nJrtUAqObURoyZReBcbEyK/5l8efAKvL85+vjy+aO3/yx6uhbm7BtJbnPG+E4M/t8/imIebdsQnBRNOcb0FuIwu6D/DaCxFLyNHwyZENMnpygmOAdcpjc03hfwkuvV5FHGC5TswaCuJ5SuB55aGqEO0EsiZtrrkDDL9UNnum5hPG5M5vWVkwljAe7VzheNkf7XMGHXsUC4vcMlHffdYoTFdziLq8mzkMUuI6Fp+wkj/WO1Utyo1M43E6LBMaywQy3APBr3BqNPrd3p9eNPh//5iug551EhYFFF4LXZUajkZlYLLT5EJi1QKrdKeKrJW5TeFjWx29VAFdRr5Y5UfFFiz20faOjGr0o/6RH3d9DYf9XUKipx0OByxwd5o1Nkb9WlnuDXd7dCt0aRDh27P2e1v7U63t9agqUf9aipqLCJyfXIkr6e2w3rksVqzZfZdE1l1Aa98NuY/8VICS+oY98ubkjNsSrKmGx/RmX5Eajwu9ozYZHtrMpmwXp8x5vb2tpzJYDCZ7E5H1HGdtQ4qv/DKQ8uvoKQ8yQ6vAhD1J9m4IYtTzK3QeJ6bazXB5WEcLk32PU0ug1YEWmUx7NrLhJMqmXViokIjbNR5JhIyXy1Z5EbeLauRxN+qRg8WAd7+4/z44uji5KdjRTTozjbd25s4W8PB9nDosklv4Gztutvbvd3BYHtA18DD8kKrCEddvFzDch5ACz7d1t7/H356hDv/w09f5s7ri334jddH+yPccsxaY9R9YcTR+sfiLNMxz67VKyUfkN9KssT5NcYp8hw64P+2gGy5PANsXC+X9Xs9C0CImUFgWCR+PHZgUVOMnDKsZ3H17vLBFOD91btL3HQ2FcdNd8dx3f6O09nrb087Q2ey06F0wjqj3RGbbO0OmDNka+CnvtgyXhZnr6MIVguzAXZ+TiPeYQyq2e51Lj8Rkex70xNYoO9cK17QyJAJg3+tnhy+199QPrAFQHAqwD3U3Y65St34Av0RGpBz0eDBOPjj9fH18fj84uzo+vD4okgvpUoIV7UGxpkXaaaJ9a9/HKkByNkKLQmeGeGiwXiSOp+MKpiLARHfNgX0xaAKuHzgNaALi6mC6D/TyItdTznM53t+r32VEFZbq4cySy29uJrP1HJGHTgPOljhx26A5KX4sumhXh5f/HRymNOfsSCJVuiKBV4XK14IpKiq3tdN7mqBAGU+doebwtbACbGTasTQ12XS7GTf0TvTg8QAYXPl7IrneK3XwpwRuVytoW1KOwWsunHNFTdtKqSI0fN7MKJVGqPSDPJHmReDDXiCqfU1ObkSJ6WqJ5MU0MrFiMdJmAbIQ8vlBBv0PrKDFwadzHX8wPcxBazSyAXhnVKOX4o16JvrYmAgerF6v9e9nn6SbR7Mtn46Prw6uzj5hb+dwB1JWPxbi9UY/17j7pSWZXgqaVPUCUhqdpunUTamEb/uIgqZqCJpSmp2PftZ9CC5ChEZjNdyl5o4/cGWy6bD0bZVlarM9pa97i2NM0YlqVnLWKexzl/JZqvcOLJN+Pnnss4VKfiztS5nrVO1kZ6tdwXrXT3iPFvznq15j2/No1mCH3D8xaCd2/zUPPdSo3FO3etnQ92zoe7LGOrqCeaz4e7fwnBXf4h/NkNeMYBUPYLJLY08mEU7SkG0gepbnGrlQXgw5QLCNXkhywVdLkU869KnXjBO2H3S4MWt2klDIy8QF7HEorfWUHXP1MGrU/60xP2UkiYZ9qlS0Fh4n5fXDX6qFp7CpiVjzPLXNq4qPvvXtrXa0P5n2+tT2V4fh2g/22KfbbFPa4utx9Nn2+yzbfbL2WabaeazrfZhttp6CD/bbp9tt1aI8mzLXcuW+3Wtt+o59GzS/com3YYX2bOJt7Qbkwm1SWvJTz3r0CZUq7M5WelqBp7FKJKVbOE4SnVhyukM0pTXgbTPI8H6g8p6QIXt+aGel7nCHlxI/1zShOdb+545rXwpkNhUoKbUrJgvGQxkOIMRw3g9LBaPRWkPFsEOzWlgy+uBlJNa0+xBV16TdpM5dH6VG28d+iFWzoJQ79iDXGfdLh5wrMLSh51B76q/t7812h/sdXs7w73d/t4vqAoTg7yBCmAyJJqnbuk64eJVVl72lVxC1chbPePI5G+EpyQg2v8MenvOaDLp993dvdHW1nQ42J4MprvD7b2JQ1l/MHUdZ7rTn5DOfyNvjq8O347fHh8crTv1uu1hDrB5AfmmiVwkMaXledJ1rNv+kqdO3CdvvMCL51DrrYQTUNICQ6rXGvkkiBPqYwkcl0FBFhZg+feqYUZm7DpfJfMwUIZFCP1LQjLo7tQOtLfVH/R2cwPd9gfd/m63h7VafbgmK+LxNQrtqWG07f3eoDvY2t4b9fq50U6RTcPmgtBlRA3+AlIi3m53+8Pu8GXdoNu9we7u7nb+MHiOA0gbCzwymGFmSKDNPCWjn868oAqCfNTBcARZYvTrKQ/2AaNuDXvbu3lwHiQJWLoRU9LJSh3QoLvT7bcJwJfXBswnAqicY297q7eXX/l1bB69ephhdzDY2u7tDg3jnL89V8OMutt1g4yGo15/NMgNMuoO1sWcYXe0M+yNenuG1VzeedNEW8+gfpid3tao6na9TWch6XVHw26vYZD+dj8/Cna9hMpVDrmEqlXfsQAYPfge8BE7r/sHu4PD7f7BK6hvAkk6iO8F6f0runC3h+Q14NARTdg+GfT6e53eAAzn/d5+b7i/halPKhY06g53drd3t3ftbsAs5P+qH3BvuLW9bYn9ViPu9vd2dnIDzjJniVnYx3uuA6RutL3ecG9nZ/vxhtvd7o22qtBi4cWIaSJjac0FH3X3+ttbo8JR/MQib7rCoGyVg7VpjL2t/M07vmdOKlWNkVzKPmHOPCQ3mEEJzImCEsUJW+5DMSSRFVfkpY2XzMGEIDdV3E3OP9zeykN3zQkahh/1dneMyFXfb2fYB1LyoUbkE9ZKLtRt9YqCJP5e3b3dUunsikKzZQSolvo0GyTEzI/Nyew1rbSohGoqmqi/CnyWgHueE62WWm7p1iwMZygk5r5b5r3Lpxutl9QrEoDihiu0+fap9zbpaZ8TTSxSpURrrImnckLxn7PKeKpYnsvwn5RXyZv4ofMJ/4W5tG3Bf0t9zxVJnY0VeIwp0/WsmDZaqQVL5qHZ2iK2C+8QuI73SVWZv8cHmQKUabrkvqomU3V7VcrHUrFWnfJSK0mEkPuAyqOI39cnPqxmQK+PjJb7hW3+DjnMjLWcNq3ymxEIVZJXwTeXEMtMErUlle+L6Vg+FGjx2GwEeJP6/or8llIfmRjhjVE5qxRPXPUjlIxtSL4/B+XPR0GT4b3+scFSkbWsVdg8eyz9aTyWDHUeeHvPhfomU8+YIlt9a8r5vgU536dD5rDpLuRYplt9uru1M3B7ztYI3DIW9F4WxNga1OGcTTGnYgUelxnVZwsv8BZAnfq8DIwbOilgLL+WIp9gflefteoepiLQKq9lPY1FqxCHaGGMUmkYXH02a0m9iNX2fkuZKAFZcvDNCIuofYIVF8bOnDmfxuLdYB+CA6rxuhScoD3C+sVw8XljUOHgbHjz2b0XJwzczkX1HFwPgfeabl5q8GrOuzDTveHuXm84HUx70+HO3mR3ure1PdmlPWfk7u3uwnN70htsbw2GzvZebzgZ0D1nMpzs7rrb7nbf2e27/VapzojYqSX41i909qesxqNXlVkDQSCkAEMUxDMWdUkF5EBmETBRtoSRdOmH1M35Qq6FNOtjxJqVZ3L4wldruGcNtAu8zreH1YeH0iPoqnhDwgKgFxYOouCAyAyJ/N8Uz4czbcoTuXGsJp/YSl5fzr7Nl9hUraUJ6p/brerKnuXaarjOK2xUyrV/8v6YQH8lGEmUQSSsXyewx1fIY0t1EPVJP+i1OKsB2SWYPVycESTFg6vDU+Q1n6BheZff/RRPvtuNT964t87i/tPJj3//e2mhcL5yeRpU2xKpzD5lJtyNWcQLBqwTrbkhq4jYDDhE9G/KH8RFx3oza/CFf94ZaCZmOu9A+mKXfP/zlSraBM8MELywnji/gLx+EbnG2QXM6u24jUV1YEna7sryZjlokWAraKRbAtQDoLmeSSJucuUjMpPqK57gFbfR9B7hV68Mm4IdVXzUplaztObM90NyF0a+axLwayvq5vLeN2PIw4v0VKXZNDhwRizGLPYyJkHWRRP5OAEHVbChHqmYD2WUYYjmoEI+SsDuoLBiwLr5PKC5uMmPQAw+lgLI44+wuACtl1HSkGq0GflA6qiP1GzeshFYDc7Ydkq3JKxfm9WasgjPElDM0ZqWypNqJU0OqLldwB1waBAGnkP9QkGutbTY7SLjD+OERMzBsqfKSVB3eCmXxGjKnl5glJYVryQmPLTcVX/HEKS6Zp0rcWUMgQRaDUTNmABXjhpS7la9aEUZm9rhRSMxDbKldU66kM39c65kTsPEBTR48NzlfAuZM6qExQdlaDBF+GfF4+I4dDysx+ukcRIuhFavVJbyEaN++UR8HqHmy/0URrOyNQCi2qCsLrjWGgRe+alIBNF1woT3NhisJqymfj/lI+enT7KO+gilL1pcRyTseCKK+bhkcvMCQLLcDV9nhTpc94mXxIV/rz8KnFK4iHc6fawduNPJSnFZ1jiSBXeqyvCdZ2RH+LYVQEquhUgvtKwrM8NqcHOuqdqnLXINQKolPASWGkF8wpJA6SSzXZeFokPllkhUS53eQuVw+wuM0j4K+09a90WSrC9R9EW3bxmEBROxqZDaCmax8u2oREbzXS/BTGc+Jr5QelOpvCxrkJ9WcRCL+5Kzt3XJ+zSGWO2ZF3D0osQP71jk0JgRnyWg2gBJy5t5Cb6QhIMHCQN/VWoat3nLuI1t56vlnDVFPYBaqePFncVKpanqVRWsrLYJGVISEeGmwdwnet7rdrf13veX2LPqRV+h7Sg/8vUFZK/8DZ/2GUWrFkz1+87bIz5Eod8MzXV0AXxsTRkgj8K6KzdiFr2V+M7FsMWta9qKBkd+rWAdC3i9urqsCbwN6MHCBfoz6u8WVFpAOVFVhJlJ0Gqu7zcBvtJkebw2eIrpo7zQuGD2cnlJ7jzfB/ODKH4FqnG5Cur7MK6JTj9SANF1zMjHikJ/Am4feUmVcrHAsQgE/oh4twCLyiyiQerTKEO5z+1WeBeYTL3ATfGTpHoaLOuFk1UHHhPm24wjGmNZsvkyKdt2SiGD7FbSvGQ+Zvfcv67uYQYNhXUqnoep78LBi47C4VmgAaAaLTxvF1zx7/muA2Fd8SpI6D158fFvH1+iaihdgtZqHQNWBT/H/Uh/wbX3c0cTdJGFmyJqEH+9nUAI1mJtOnB+QWQ3o5RkFoz5BRFlMG3QgTdleQhCYpYHw03KDFzDj1JD7Q0WOtiP/Mn+8RHgngOGDS4ZgfGnAUR5LiMbB6KJDAcRkldsRSOW3H4GpTrImIiZkIioD87AQRgwpaGpkows3qNX+ddd/k1qTdCtXpvrsnQdQEaVbaDDNzFtxPruw04rmc6jsxuczfyKgPkC7SWxBk8VBVubc3IazkEyeY3/FrlikauYaXM1Ga2mKbWXrPHdaN6OPFAd2CZhNIAHnWbALiSJyILgQIbSkE8sj4vsYhzO8r/zEj14Dk1a+ffgGmL8fWfKoqAjvQc7KuUFrL+j6rH+UaV9OUkZx/MvG7KgAZ3xBDHLKLz13Cb/QR5oqkcPyB9mXuLTSSVJ1Ko5mxeGLr21tcOrHLlUCeNK6w/OS7DhRlafurrwmxTdrqZBThpFcBoycobOGtxjVKVmeSCq2HWuLHWutrQsEC36VnvsR412NQ5Z0fThsB1B/e49pOKbwjbzfy/oJRKMqOf4JcFsAWDN10zqRtQvWAJbc6OHHIJpxLhizmGcJMqKy1YhHQ023Mz/PVL6PYX/bd0PXxSRp54hm8cBgd9JzGK01gApjZOI0QVQUoht4i8qWkpd0HwZjcYZ5Zsswa9P35DJdY8OXWe626dbe8PelE52h6OtyWDCtqaT3W02NUXpG8uPn4kkwORnNrmE8IZEFiIXXARzQIYRGl+8W9RYwCrZLZDmNtdl6FkbtH1gVpX6fdzFEKYP7UFVzXyAWdzlqnrUXr9af6eG7IZ48KvOkkUdJ6J3/vh1mBwgtr7Pu16XxFtnTiOsAz5ZLWkcG4Y6hP/PomPIpWPhJBMm44y7aO2lQIg+BwmbhZEhbE37mI8Mk74RkDOTQQKoxHPMLTTS4wUJxnSW/Oq9YBqavcv17BqRZ+rLN+ead2YOPQI1SzAJaeRW9eOOYqHJHb3div3UEFYDMgWLQQiqiKErrRyCQsd0lj+W6uY8Qoa5m4P51ou9SU67q235bkLtFv65hJFHNPKcQ0vNJiBkeMuiyHPN9eerYlvqJbXqy8YTCav3Vnnny8hz2DiN3fHCc6LQkYGjRculx130s0akT64vj8jfCWSP7PH/0z5nb/ceKEwpWaR+4i195H6iC/mPXrfX63fJBQ1mbF/8+T//x//zH3vtvb29LvyfySNpQe95oMYe/58e/I8WvwH/FrNBAE0fv9cf3SEaq9aDtH7yxbIr2YPIAN52AQ/KnrfGlf4SBuyQBq/ZcelAq94SNBhP2LgWAWo/mu5EFSCLy+P5Tx5nkeZ1WLAesZYjy4DmUuCzogMLL5ABSX3M+eqwIGZjdr/0IvCNNjwgj2nkg7wRhEEHyAjXFceQkRi78SRRWXCD4zA0piHOEDqLGH8UwetzmU58iDePCAQSEt+bMmfl+Cxuw+3C0VE4CJiHKhSxLltZuEQt5f6qBFndQB0zH2s9VO/Ai6Ww668IF1QJSjkYyu4SOk3kmqnwEajUgEkxl++Qn3kA6gGPb2Ece4HJzJZ54eVBic54Po1jHkEJ0pcfOtTvgAG2jYcnh8aHv8+4+vIUYI7Bi/IrDFefI6sW5OtQYiHCliGvwTzIUeM3QIQDCXxxvDzkwIuFAg1Gzs7JCwibTpmTfIvbpIFAKlf19hLZ16dxUjh+I+UusOmSdioU2sQC+hnvWyVxNWBDA2GIL6w987OAJntGUZoLRlDBUWMQANcbkA9xAv3yIV1FylkZspQLT2pcazMNT6M4NJgJz5b0NwhtoY4TpkHSwRSKhLdWBu8AAgTgqdglJ4mkXIImwA2dh2nEncdjTumEE/PUg6fUsuLxXLpfmutllVFgwyNtlaM0OTyySQ2AhqCxy0cIEC0OfBKFwaFPXTRIUKtYgtA1P38s2f/72EL0rQi7tY6z5XkInHmePz/gCGHVnxsCeCFKqozV71lCZeybcNfh2cCCjkwdSqBnB242EDyMfpiEaYJ4izvp3gRXQHynHvNdshCyMg3kuIKr/xeDsqOE2ba+cvruBeYZTvP8/PpMvAAP9XSWNn4bmFR1bMfJjnhrwXcK7Mr2cWF+V7zgL4mXZMKSO4gw4X8jEXng26Ivfyg/MBpk6YrnuCnpclt7QdQCtUxWqk7PnsNlMcmPfsceedRNeHEldn8ZfrzOeVlx3uc7t8GdW+vF4MVEasQe8bEgh4y75GSxSJOCx+Q6b4cmnex6JMVSfq7H22dqY3W7/2A0x1Zj80xzNuPzCy/Qtbr9uoPBd77Vwwue6/woDEa2gkaGv/5pkrM/AlFpjn8rrJOv73MDMTHK+/8WRPmAFzReoDtkLNxx0FMERH1Q9XyTzco9cx+LfGcWGKNX0iXyCiJPBAoGKFB4tRmYCkmVNJXm1kCkqQpj5lYhE1c98VbUJ/SOeggMNTtXAIHReXN0ghZu6levQqF0xFTBIxlZMU2TNGJCbQV17Giy6UoKPFQ/ES1C5lH5KM5stArl77zC0sfhbyWiU9JmZBNarP+Z9Vcd7Nfn9ufi7h44XAixTN1CncL736CVh0uJekUc4YPSZ5so2DnP/ZgjYUI6cDP3BpHwRVEXRXh+K1S0qrECZ+y8iNM0i84WyzTiti0bFrFu1GjNNjKBEtHXqVYZZleo8IxKanZQiqqemTEJnXOKjkbXV4fEpasuOcgRzwlzwgXThxECQm4Q1NLKETY2ctTZy7BIkjKRwTFk1gzNYAZDxwldLLvkXJlywmXSAf2aZB8xGCekgtm8j0UYJHORiimzjCigCgi57SyaOExj8V0pqRsAJRNl1YK7S8B02rnzXIzBUdPzrCuZow+aq/IVZjJwYlZ6Ru3d3x5kf1pPii9fVbsUsUIeQec2jvOKwqDhr2jdkMaiCn6sXdLqu/7nZl9FyXMzGe0rcTHJvb4MOV7PpoxLQ572R7QuG7ZXzZ2vpV2Yp6IDH3a8fdxij8YJ/CxS5ztkKdm5OB8ry281vSmTCsydXJVIu+igVUzEIra5jrXYhlTwrVpI60tD04dJ6+oelAT1bK76Vf+5idxGwPya4rkSY5DC8geu0Jo9uow+lpUPkX0GYcKdGoo3pmhnMnioGaRpM9YVdld4etRl7S4s2fpMm+GptB0bDsrRhmXDAeosNh3tAjtng4E6w43o3YbD/Sy6ywHLKcjFeX22TzK+DjSaM4+vufwHDWc8/weOmT+wzxZ4XwDRI9xnicAfHia7P5mGvfwY31zlXv94tzGK153fIxyGuP5fiagWb8wjbEiRoC+2pWsQCiBAykKomqQrY613dCTnL2leNxfwdBaFcSbNJtTPcq1kkW4rFqErGfjTupjIY7ISP2NILgykVFEnR3Wh5WvRlWzXr2EyFGVktuuC3n9JIxDNvQXrxCzyICiKJlQU0AB4SMc4uauCa9xjLfSIJvQc61zzWqYJi26pIdoJdCB0NovYjCsrZMvMbVWpq4RpBbT6cILEFQqOulh4cAvE+lcrxCdwQR2naMF0zeolb8GEsyrEqhARgiwqLHd41lgShb6fLjEf6lSU+MpcrCdsColSEqWLg2YAPJ8lD3H9rXhengRSGYb5o9DJTIWGx6F/q+DFnSUB4ArI1PdmlWW/DcuSlWUfghlXfAAI7wkSU9DfceYBD/fpyfZSqvgscFSCWi6wjDYKCm1JZHIl1hpur7Xtps6ylxnxFJ3CpWxg0lPTVdpccbeWlnyoNpSjpjRJIm+SJiJfDGgFOMmE2BbT2WoXKFOURBDemDISz2m0vl5fFo1HB+Pymk/TxYTHfPILLu+7iKlcewsPtTvkDYn588lvpfZsGrAxI9FPipFlLbUnmBI6LD8Jwi5Z5IXuGFXudSQzp5MHaoJu5JBqj642WHcNxdz09uDachODbA6adC3K7kvcmIfgc+442l8IvZ82XCMvi/5B4zRMfLcRGg9F1wIJ3Qhb1zcW1eFj76H0X1iZlUh65wVueLf2KgoH+DBEf5pAT5nbsNL2arQZy16EX3QhnUEwGJ+LmzmAismGvGKwvwJaO1kR5nszb+L5XgJk9zYUvlLcwlESqEvTBS65m0NpGDFfl1yoas760BRyixA3ZDHmYHN8RiPi2ZJyC4NJfRCttVlbk3sBch0fEjEIsy/fc5ccQ1E0TCgk7d9gD8ZkxSmCh6D0yrkHrF+ASBmJteMQgM7BEE4Go0VpBm/sN6cAvfxqNn7UGIOH1nXye2QjWhiRNJAmdLHrL+CBjcywcEfzFzKHQrqvtq0TWZFmPJt4qsnp17P0/CFj5OW61gv2emY5zyznj8VyijG4G9Bbu8vxTFtrCMdXJq6bxNA9k7JnUvbHImV/TTH5C0jIz6GK6xDzrx6mWFqRrcBcQ28qJ4p1yfycrqB2avNMeDcezbev4oGAqf7uRU33vvCakH8WrxFfUfkOXBxfXmHWEQuO+BjJOoxfNslVoadKMRyfhmIWGzPrvEWy0oovLBpXf+XavZqBhfpPXvMCf4OPPMWpFxNhB2ARiUOeSt+bEq3J3/9OeuSOiSAZ3gLycLGbAIpaeYELFdF7hNejIuECsHCZrMgdJuTHkqsRE/VWUWyA7CMhDHHnxUwmJYH/XYC2lEL6MVgWzzXPIrKgK/AWipi/QnN0QCiPlATSjglL5158E0h/M1H0VS+PAL5GE6wn+0/ueuTQVCWT6rV54SPe4ibwpoRmNbEDBkY5kSTaNcUVlLHj0psFFMIC33nBJ3ti73vBJ5N/TC4jp2k624w+FCpWJabaKufyE8cIPjWcLcaZBjMQR5w5ub44gVCoaEXUWARB6WpZZsrVjNvZ1Lx65Riw5r5mGeeQzpw7cOASIJu5/AnLiMjZ+Tnx1RVX0r4JMFs6hSpmspBwxAigrXI849U0s7gdcLxRw5vDSLTMSIXli4uEMPz+8uyUyF9+vXhzuL3X63+QpQO0CnBg50xUNXvhlkIk0bsJWHfWJTetV2Czu2nxxGgQE7Sg0Yob8vh5o8+IaPdK2ZjjV4mX+Ex1VC70qsUaNc1NyJdE3hIYJuQSBlxvxkMzBW8Y2k5BJBLsVwX6YAwQDDoW2cGMGVgNS0G71wVac3jaTgsuzSBhcI3FM2cejed0MNo2WMPfHnQGo23izJnzKU4X8inC7inU60onCy/hkckcbTCvluECYkvMO200ur8PgzDhFfUwDR8EI2BsSdYPylLETriUXgt4TRLP8ZZIsR1leXqAZTe/ynYOhApGZSmjfDpPa601YMNj21q1KX6ivuei7LOZJJUhAbJe4xffC0yiRgFJq9OWFV9VsIKsveX2vtih5aYUr42nPz1b1ZA13ejpUu8DAcFRq7jV/P3jc5V3+4d4yJjTFZs4Vmm5P4JE83hrbuaZpRXwJ9cfBmyP+QKkSw9x6+voPLL3Z15HUVxB2T12Ha0BXXqn4Z9dtfNlFTE8GlJJgFNv9ueF7Hp9ywL3VzqiGUueT6ZESw9VxauvdCbPd6bhznxFi+GMJVcsWjwHQ4u+pbzRX/lcNlTc/bkPyQyUP8pJ/blPqagKLsmpX+kMnl3/1nqFfp1zgkLJonjZn5zjNOjDBAweZ/ZcObjPn7/WAwnNMCVFwp/7mO37VqqkvtxphTGwpw5deuODOGYGPyP8megFG3h8MOjdoZYD2nbAmClKAnq/FwOUK53LsvqCtdsrrvFQdkQPqYRFAfWN9oJj8TEXpqcSAfJau/EqTtiivjyknKQz9XzW8dxOf7CVj9gb9QdSc20yZUuDcqxb1DA1q7CysWTjcPQidN6g+rxUqVT5QRdC0QPvt9QYx1hclcHQm3Lzh4LTLu0Nt1w67bhsOuwMe1uss+cOdjsuHbC9LXdvsjsYCj3+p/JSjtDBj8BHzf7YtAYs/5gtYZ4kS6jlGfvU+YTnFXedcPHq6h/fv93aOTr8oXPcG2ztfvfd9uvdzt5g6o5Wo+2dYf40B73hrsnzzFgX+G26oEEHgI0eYnqZ8srlZ+vFdBVON77Fx7gItzZgkEztmBuaROEduWURGr6qIjc3K/u73entdfq9q0Fvvz/a3+p1+6Lsb9k1TVzG/F1Ul0GA7YOJ2BxqFCC/X/nl/2PvS5jbRpI1/wqCuxFtRxAU78OzvbuyJNvy6GqJas/rkYMqAkUKFghwAFCyvOH/vpFZBwpA4aJod7ufJ6LHIgnUkZWVlZXHlwm5w4ttpalao9ZtCbcLEVYM45lh+w4Zja35omfOJ+OF2e+OJ+a8s+ia3a49H/Y7vfaiv0BZzErR6uWD9Hjzp1A8cG/7A/XsxDidEN2awAwv/EUE5e18j76EEE8clGEa+x+uRA0y9nrTuOqJbyoVxT336GHASspltgJ7SzcP+AXGVYH3YXc2sIQpjE/fXMHUixu/AgGgrcorn2E8Um35lNUDYsiecQ7xFHi3aV8cf5W/JR/Xboo3wv2ZOoZl/VMem7T9ztCLX1mCGQWw7pzCfreSxvwbkMTakN7cguuqNM3tPu7vDUQjI5IXsBXEzORwVZxmXqndkHoQ1vNATRHw0vrshp8bKXZihM2bNQMYOwgoSh/iGjz3m4+zMYXICMbk3TQHJR7Vss0V6gOHVNQUL2YB7GaGMdF5Gh/+qIrKFxcktIh7QEL6smlgvM++F90F/tqx9tfOP6lWbMZETD0sMO1XGkSfN1xZ8iBkxEUujEOFZNAd4NCwyDqQOStEL1jQgHoW5XLdCRlBbzycTZOF7GHME6NXy5j6ax4sH1MIY69u8c1bGISsL45DufEA+AKUx9CgEFLfxGf5drnV7T998WJdpLe6MJI+BQt+4oSF3jyFO8Vd6t8f1TvQvz/Gd5d/JxgDf02ximYRc5+4DjEQLff3D35wH64JhK5+VCTo/tn03eX5xfFB+l3teN460bvN/DxYEo9fPDRdsocgmCB0InZx0D/ChqyO5u3x9N31a/xOXqVE2cSkxuKvVqiFsbWA4MSNhUUXUDi7rrF/cQxpGhiXh9n8eVfdquq+XMTUpXab95V7Yn49W5gBxF5hQgV/Y7FRYW3F5VJhvIQJsFDY0BBgFTZrpsAKrSVk2ATyGwNgrnZ2W2K76Hds+S10nsWOjSNp+BIp1C7YmTvblWVbUBWjFaR+FUsURovtV8WIVq7hx7mBW5qY4aKKNxi1R9x/0qd3HKwnxuNMPyy/AcWCYU6WY6jLcsmOJ/8kgXXnPOgQ1EWlsHiafFLNGFw9JhuMID4RKhP8teYiBNrKJsT9RyKDP8hONtiN9+zQjWmTWnDbrrmOq6T6oCQu7HqFA59tgHjsYmlgvnhorrDksQ2nM8wKkMcc14X3P2aDRzNcUH0J2aybklwasEYNjz3K80u7avLnxGoZc+r63jI0Ir9w4Tgn7qdYX3txr7AfttjSthOuXfJ04LvsblZr/+2YW6ovpbIJKywiyvr/KcSnVNw/hVCwlimIfrDcswOyiPa67W7b7HT5WdLQ6G3YJ8Sxw7EkpDTEXc3uQVX6+lOH2JUOscUZz69GOzrdrzYryGz4/jctUFEr3rOYNltwwSiYn6oR1ZmjLpMrqeIxAYjXNg4rmNX0lAZ3rOmJdftaYHc6IB5LMlA1TmYz4Kvx9vz87cnR7MP55T+vLvYPjkoWJL7RpBaDj6CZomB6XV6TkL5hd92p1vD2moSOlbwOK+ahcosQWa9dh4azyJ8R151hFDdLKy3czVilW+mTNwMLC/loTzLbHy7yvASd0rYwwDAqaCTA12b17cPr3svB/AK5WK5jPRkUVo7kwNDGq/TW95culZfSN9w4yQYQs0q6gao8qKwf21vhEag7mSMgn/daMBzVaZZe05pDOYgt9xlXUbJOTJ4vQmSrJbkAs+3Z+9v5Hvpmu2N2BtNO+1Wv/ard/kM3wsSYspVVQdYDaET8dWzuw7EWM8NU5e04uw+VcGKA0Rcy4Z4AOBMtvoq2BwZqdOpAsiaeLQ4HBtDV/AooJhJlp3BJl74RP2DMiXUvskgT9G4ZbyB9MGsRC5vGknqAMwm4F8S6F7DfLIPVsKnlEr7L0eLlsyytlnGFPlGld/a7LEC38aw7gHzVrG+OmxGvMRnnS/mK5DtdSLc9ngxs25xYvbnZ781tkwzbY3PUsSZja2h17UlfxzeK/Jk5OmftsSL8imUcw7rIF53ACgvihoW5i+kZai5efMr/bgwGbTrut9sm7U7mZr9j900y6gzNfn84HAz6fagIADooozTPgeDzxnqt5ViQXGIj77LCeXIThFjANDSIhdiX6JJh+XS/hKpYD1vGHzTg5PEY/gcidVPPsGmEaJLVYCTl1Dv9rq4QVUW3QYX9zjYxug8uxObdl5sXlsEPnKWj2aeqbps8gEMeW2CuiEeWDB5FZIubBQJSXIPZ23CnwZcaHzUk+M+GBMSLHE/nNBZD4weglIFploaRbkIoVsW1L08C+reMC+ZUZsnnTOAHiSKTsbqeGV0IWoATPT3n3LzibWhPS1FBW3RkYGo1ZzyVJ03FvcofBRjrAOohoA0/bCn+962PPcBMN3gj3/DsK3KYXhFytXfg+htbaBB8H6xdEkH/zJ/HctHVSThqcEoVVcmIDfjaMQb6g+2A64QibiG5TfmRdgy5vSsWzADVHIl1x+laLDk2jhf1ulq3bwZ2klsRlAAGqY5Lxk1r4hACTr0oJ1SK/8qdeEjnw5OLmqo46pvfPFSHDied9rg3NvvzScfsD+jEnHfnfXPSmc+7PWs+GQ27sfqrl7Rn9UJd0L/JVHbhorXd9cwCon3WAS0D7fivGW937NvbxQXx0F0fsI5YmRF3PVsHPqh55ScmjJI/zBXEhUuWS2GlTY8xZlpJmW6qS71achhu0duz1A2r011024OJObYhnKu3GJsTOp+YdnfU6XTtSXc+hDC4cbdrtQedudmez/tmf9QfmeNJd2L2Rx3SsQftIaUL3EiKPK6zOIpCJm/vUJ4CapXMyGLhOpgtMxP4R2nMAKhGQi0EnSMRVeiEIpuTb1tp3WmbnfG0M3k16L0ajFrD7nA4mGSjpOSuTuyo3Flk+UHHlKn9kyRwjuQ6+gy6v1plLnXriAEacJ+hngJy2eKyjWIDYbkgS85A5+N3AXNk/qTytHF8WGjxqcO+dNIh3d6wbdpk0DH7C3thTkadjjm3bGrZ/WF32OkjmRIjjeWMXiCJgcrQVyGEGWF2Io1OLi5YL7KOUHxjKSKkalvZISGtfmc4t3pjczSwLbPfHSxMQrsD0+qN5gN7MbB6I7bBV+Rz+Ybkw41848Ghj5KvhBgDjSCIARxZEGN1XL2sMtXuTNugSaEy9RWzw3c0SIZZ+cwx9nRjxEpbmkPgHL5HwBOuzvKL5u55kIsL7JB5Lij4pLJDusLvjYgGKyDXghGOE6xiVFUcBKiZc8zeIhYQbBu7mKNqh0tyfNq+m3UI58mMHLHL6Kix2SXn+hbsNY7FKq1l1jnr72GYqDXP00Pxkpi4XrvjI49vTizsEB5mDCcGWbzIieNOOt/VL3UHmyrzio/K7MpImkgVXxuBzDBxLtBGvMV5SAyPPgoTc6L2fAUd35Km9aqLxsbJasSGx956g1mode327PLeZPdBNnTFngVeuYT9St4vmJmnZWATaNJqGilDmrHi5TI1IHQajx42UmbGlSGpKTPuI0P3c6SJH/B5S3wwm8iHLcqgoxjSH7fTcistywxhijXe8IWtKpkb0MFKnJ/NMCKO59IwNCMaBAQkgCnZgIEHN141YFWhhNbM51NRPOs5t6pD9iuzYYkVKOGznAmbcIe24UIvporTSyU7DAZJGOKUa4mtHZdECG3oLNQxOaGK/yvxgav4c/mdfwYPalWbadrIoi66k8mmaRn7rmuISQOz8J3GmBNNoBoDeq2L84CM7AntLszOvGeZfXtAzfFiSMzRfGxN7DbtLLqkUcXODHNzMrbmzK4EYGom3L6/vbk/GS2G1CLmsDsamv3JpGfOF3RuDnrWfD6fk+GiPQaz5DN2Q0Z4K1tDxTIuknRZRmpKEauX+pcxi7z352qkXlr880gM2IcqX33y5/wowHgNPCQq3Ini+IyUIxNWCSQbPmCIAIQKmIdxNdl43T6mYjly+lLUFuLuos/qma5Un+V0JcNB3CcZ65Yi+040v+T6Ixcu0GGoUT+ZIzF38UmEQLLfYFjQ8yag2YBUQT856I/fPvimRtRMEnEus/c+0Pmd79+/9+fhFmrXZg2aSqcNYL/YDuMJA70+0iYH34lcp3Xg2xsLc6X4K6iuYEgCFxvCtwU/lG9i3VsF2yztQIObOcwhBMh+nufIB7azG/toVOooBCP5cFj6WAdXUSFcwUzFivAJRoGzXNKALcYiEeDx7b2gVSdXiBanTrupX/cKPJ53uGwR7Vf1dPmbR//t8nhJiJEdyPB46ascK0rv3+ZIiYdT5zjZubTf+oItCFT3hr2J7sBNxgwns0ifripSVRMPMx+yuHjx/ovvWu9O9w9MwPpJOvBZVN7+JrprNBtnvgca7WtKAhqIL6FGqWMZ7yixWUHtREsf2f04crxETYHUJEiwpJFxfXmSHnOKZnB5xyAeWC0gMFqvHx0slwOn0XaJ9kqS4x7vGKTBHZ9SZryQsMYCTTBgiT8H5wUvOw+BVWIGGs36uTuB0VpaUOJz5f81IEj7VeNf5gEOzWRPKgma7F+Mb3fJnGoWY58ZSoTNDKsWsds8vlCyQsURKlxdkAnGIeOSWUitQOeMvsLvMedAcjSwl8Ff5NfJ7EYBxekmwYk3jeKxrZ5MNgrzHvORHgMnorH3HS+I0tYrg0Nkik6msna0CYVfOYeXeeAHCzXl1gecj4hhK8bziOvosHYS34ntm622k5WMjA+y27SplUAaEclzgd9R4kZ3bOpols3CTOATRiipozp7LNlQiRmMtfKkzPLYc+A95wt7NH7g2rvjf6eHrfinCl1kNWU2wDg7uhvrEfsBnQoEQp1ibAQnVL2Hu3W+CeykusAp+gFVicmo4rDMtder0RglQ1AT5j3iWZCMfqw4MYrCZcQq5TMFo5t2FZ/EypGcIe4Ey0PlQcQGr2nhG8xJ1xpa5hhRbOZdak46/bFJRwM6ng8ti1id2suQP5C4YxAHTmQckMA2WHwJKtZFTvTjQxneRTCq6hszXwFjKMPM8AZ1aexqKTe2gSFefYeHI1aSIiVU4v4CbLwEyyJNod6C2XjNIR0Qs7/ozc2J1bXNDm2T8XxkDe0Bza0rm+t/y55/GJstnilzrlkJr5rFPYrZPuMAp1phVkQTPlv32vVBhEuqHT07SWBgtnsYejN61R286o1bw8lgMhrl5ArgctcYWhUG2WZo2RQArF2gtavAmJjQ3GEsR7czpwtrODZJdzIy++1J2yQWBDGNCMRwTdodCzWeoW13aGdoLkZjy+y3O8ScD4Z9sz+w+rTfJ6Q/HLGYrtqSmZO53t4bDQe9xaJHTLs7oGYfRjxu9/pmrz9sT3ojq90fzBtKlDt2MYN4FEgS1QXwwVAuneVdZLz2N54NVYr8BXcRZYeoidobdLroR2NVLrqd/qg/7g37I7X0hWbBUyN0vMIRntDF1gPsPH9467jWQ3Zsp+pQDP4oi0nEVniRK3EAOp6Bl7kcKR5DInwtwkvRDLnofIRxXsjQspoZJvNumwzbc7MLaFD9eadnEmsyNrt926K0OyJWmxaCtuVKl+eHiVeXfrnGnljyJEgYzyd9hhzxPLoz+ljbqhNRXnlWf6ET8V7S+ONUgLF6jo0n8uFSLOUSDC9tdPghTD7Sj5CeBH0AbZCBDPw1bDoV6PzXsO382IaVtEN9K8OEbquXqu1ys8c8KPOOcOGZ6bGCI0Op4FWItcmf4+FBc5YeSdXOisnL58ZeiL0RDWmdmokiZalhTKcXwhIDT8SZkQi8GVuthPOmZbQhasaSpR0MZmovyQtot6v6VR7VmSR9K8YLiH4HMBGj+/mzdDe9fI7TV6VOqoCaykUYjQqeEE2SZXzPIHN/E2Hpd3wefCEVosv9Rw/0jRwJeUdRPM6flESnUOf+4X1aBM4gQ7QaryQIV8Cj0drVagnS/sCi7a7VNekING8y6piTsTU3J71Rt9/vDboLu58ONev2dVeGnCCSA2YeCxOXOEiewuc5IQAlD9MxfQtTPW3D3rCi95wQ3Amlm25mJKgz5GdhzkmYTsXEavJQvDfcAy6N85MFuXUsoLdboS/2WGSlzli4d9fsjqbt/qv24FV3+Ec60G2YN4c1iTShzRh9BiXg4WfdHIww8oPYHCnwaPBrkEsv4mzay+7L4hnt8cSKPX7hNmXCLQDP9Pfa3b3uaK/avFtW+JDBp9bMvd7lrXht8vXoSoyfcAhUzg2N7eUKJm3Vt6V4Ah1RNAJ7vcTSxuhgcvUFg1JKMVnoaNTpQi7UvENp3xpQm7bH7e64M1gMBmQ0SG387jiFLJoUd8+RL0J6MBRbZQeL+IZwxiaocBbnJ0TLrdiNWEzhdI+pw7tpKLQuJ4/O7iiB17DhuLncY0iuc+4toar4iecgFP/4G/6X2KGQYcoi6fFulog7S4+U726NX3G5DOgSBWUcThQLecw0Rc8ji2sSuUkQFsWKlkPA5cr5wrVVKLmBoRhQngHxThFoleOHh7HVzyCA1cPad6IwjmEC2jth5FgVtDkGJFCeSMkBB9aBP3cpxmoroANSHtniLhFSa4OJ3FkLpc5aozELCpC1CkPjT+5wQDpAg0W8/lvAyuRhbwB60LBvUA/UNVuDv1Ew8Kx4nz9FSWvE6eH+I/8vwn8P2vj5ZKp8F//3+fxT/DnxTPK9+L+l/6sWyGPp+YHO7HIINdFXjgeLtFDT2+PTmL9bIUVBiyDC479K2SbyI+IaL/YZY4M5nfPRy2/E5aNiwJM6jPW8rNtMvQL2ohG/yJJxYW95KaiRHVnERu12p9fR+gNEev9MYEBsseMELsW5aCKT8quKvYywaSonBp5mgp0z/JVcwYI8KO1Z8nrj3rOsoerGuvnGvZeZE3BX5YpBBR8Q1n/XnF/syFGiYXmM6Bqgu/CQKTIDpRXZleNJVanY3fFdhNNHtQLxoKQCMSdRznJtUxGjuovOn0Mlgtqi4Dx+TajJPKi6VgYbe2VbbT1FoFhnTyrKiSk2jsNww33TbLgNgEeJ6XTBOkirl2oj8cv8rZKVK1AyleoYKuJJUdERJThAKpFC5Yy/EdPIGRpTgFkeba4U4Gm2iYRT5C+x+xXluIIkyD2deT+YQAqQQkAJ/nAsaIwrGmE2MRzB8Ac+GlIqjgoUDZWihqtnz68gLnLt0m+VRj8Y2KNeb0TNjt0mZn+ysMzJuDs0J93BnPTb9qLdG2ydRi9XCU0T0riTyqan6QO4ZRwwyxcx5MkKqsfx1bkxHrY7BpugweqL0LUPtjRxtm91UHcmZht8aNNOHyoLdbtbJ+UXTlnk5v8VZjzWzTgvxf8Dmul4tTDupmKRjSInXJEdOwmMTUgJTFRPioqvSXmft334kH4JpUATqTclga1MIgupxj8ighVLbMoBHtg3whh6oLiLRJ5vI1YAtdGG8YwkVBjWB9kJra9kxxrUgYPL4+nxwf4JTvsvhYew/+EKYl+LjhcN4+jhK/KPmBrYMt8Q90DZgLX2n4bvMpq8YPLMD0KF47F0ygnUKkMKUrDKypAQcvQDaarS7TGB/iBNP3Bly15LjWNPJvjA6IMFsWjTeKSsJo9IdPtFSAkjQg+e4xmAoXr4GirzZKAmmym7FYaTTCa4JhYJKwSOlp4pPEYDbPmZmYKHIr6R7+5aOuh3/pDYanU4mMHObY2b5nDwRwdLKAlIm8zlYScoas8uP5lmhpo+hyqZ6zCmcCaLfhQ4WJ0scxp3JGSYpqKBStYkmXAgADAUk3DhxRlo0mkbKwXOLJ0ZHQPjpQfbZNKL+dlknhmqPi/UFhdOEEYvWTbtL2FEXPqLrDYnMJAfFbdzOitaiepUlc70cH4JjdTGNF4Ak7yMNTcnMl4giV62jGOcfcBI7oG444TP9F9AAP41zEXkPIF+t1pHTwZy/O4TuFWseZHhq78WqmugpgQ63oOvnJMIg6kPoMrW69NQoWUcQQsY+aXa+xUDHfT6gnhPPLzhpbGmQarL6uwhWAKmcV/KEhIsPskauP6en0jUVBCFObt9pwXmESPHcl3iNU6b/zIHNRP3GdC+hABQGKXksN6hYS8+cCta+GQKdCVTXzrxvZrNb/c4JVpLnDKVEoLvxIoSE6Oyrpt/PimmFOmgYtu2GvbS39rOsDvwvx/FzvBXhRLU7iOdnUHRjv69o5u/jI7EbOdszfuqY6t9la2/z/8qd1rtaZAH7NfSAfuJL+tD9eWIYEWt0p1ysQ643Dg2fY6HZBGQFcVaHrqOXPpAvMg48Fdr18HVfSOfr4CbpD27rs4PAIrl+Oq8O+KIJJmbE06ryszzEmsUEG6A6Pws7oEhgAGyeP84uG0N3nNe9iPytVh5rbxYA3VIxzXz67au6LFaE51p8jAJGsjS/yJee5m9VEyri2wZF44PCFGUsLFDBE7gEiYB8w6+ct8iuhTp4874zDjBH8vS1M3rK92MoztQeivNmD1a3M8hAEHgdAB8BmKBYjpZMa8/OL7LC3zglSYZTpjc2co+Euwr/NxstSR55Gxy9n7Gz54VxaKQQ3rfC4EmLGSVcxhnc40DFqqpGceHxuOdr9ThpLKORDGNO91ev5EqibFVCYyUv1MdMetE7aNxAMZmi8FOatKA4LWCagepmmNp2m1XUSGNeVteu+xnrbId1SojrstLeD6zahmU0kyHJxTULcvc3j6WVDLbeqAyfgJGmJSb6b2v1kX9WefsZ52zn3XOftY5+1nn7Gedsx3XOat/lCXVvcxJu9OaZ9qT+WcVtL9pFbSEs2ELE55qh8kzpYGqeI4yRB8F+UblFiZswjgphZUPKdF+pcAQEoQLjqb4peAek9hcxYOLg4Rqju/OWd6poxN3sKb4BaiI1Qxd/7FosL8T17FZ3C1kbek05dT9VZuufEqsO8ejcd60xt3OLib+QiQmNLmB0AOxeeORB+KgTtcyzpn2ZPggcx+dsOTie3n09nx2cH56cXxyNDu6vDy/xDLGvrtZabZFx4SkUdtgvwPT37qOR2/jbqXY4QOFvCcoS+Jj8QkwKkSYPXHjsZzfOX8v9DeBpd83yvGLCjfWia9kTmJDKCbADQdIvWnIEhk4MnzSuGmAO+ymAYfmDQKw3jQamApEXa19jbn0uClXIQMrqw76WpPBrwizLueQJ165xV/ceLecsdSi4rzl25bB8JxjxuI68ZpVZwd/MJVQbjceMb7QwOfL5ng2/dxkvmpGAOM2pYj+u/3xtmUcoVtWrOWNJxeTeHwlSRQFznyDVhYfIo4cD6RtvKBIghIDWnzvAHuc42k2h+A4+BXuOrfxS7cwQO7PEgPEknGAx5PkSMZtJSxp1OfIXgzMrOPIdUCx8Vdo0r9lrHtbd0O+MjaeTReIrBjQxSvDAQSNFrPl4w9ORN2nmedHMzJjrPcC6dVrwk41Ov2XCDwmhpMHRYEbKx8vIMfYkJk3/xEscSGvPKnmLKLwhoR+YUwpOcbTtZ5iyb1/Nn13eX5xfNBoYghks/H6ePr6+uCfR1P4+/xfEKh6fvbm5ProDF88vDy/YF+/PZ6+u34Nf7DmD07Orw9nFyf70zfnl6fx92q3748v9xvNxunxweX51fkb6OP84uhs/xhgY/ZPjq7enF/ig1dHl78fHxydnX+ADyf7B/9sNBt/nJ+fZkiqXPIYlF6Wmhea0jLMbeKp2mQF46nrUE9fuvQcwG8M9gDYUJNlbSphDcSG6BmG4+rwD6SpGp+o0IuiU0QEMLZsEV2XWw9HXDawsGtc+kZGHmU6K0hN0DTPVyM+oetZC+xhfzTsd6nZnhDL7M97fXNMLMskVq+9GIyIbXUtLgvvs52fON49RmiIqkrWBrTPXECIFP5FZs30F1c+RfixnoJtXPFFMjgvA7PHzirdfFgkiurR4ohEUh5n1quW904k4j8+PraWOFyydkLMxwecnT1irxyvxfyckOJj+yvieC3QxOCiCSphzRYQa0C+/zHtDsjskpizU4zNbKKYfl+Ja8RyVliWfCEkwqWyoErsh4QPRwLD1BNDhTiUsK1A83iu7bYDOR2d9rTbftUZvup0WuNBpz/Qp5vG6MwzBqk8qw91UQAVnegB0RscHYXhWoyOXjCNYjSKVKVzoKRZHB22t2VxSw1M3WjS7mqRMLWgG4lMrHqisFLVUhYCvCZgQym2eS2dB5rgRDSA44sCvCYFA1IjCBgsJrO7Jzso4NxHoYrmrdY3QRUcjSd9LVOXox/rd61Gzh/xq0IyzzmJ3FMm6qfSNxebvVSxn42PzRtgLfn/NvA361MKVuXWJSV2a98FDRe/jr/QWTTXUh3bIiM/Pv/yUPSFfSlMoOlXXpIYBj4z8Fy4yxPgP0W+PosV68jXzXoZMMtG8RZO+CxU5uDoX9kB10CFYIOgM9sJoV0dga6P4agECSzcKjg0ooRbqKPiLcaJBrLp7YRMbC+tlxAGbPYlmlEv8F0X9EENu6EjZBqAfYMn/em2nBNW3XNVRwj9Yrc8u1yTeJILgJoUujGOuSJm5DZV0IYE/yf4Tol0SJEqfSNLJ9OXpokryejFe1Yku8vKDvzzsRcCzjHcYcHVpQv0kOWJk0MpL0f854U0vpHViDE/HMMx5yWXvFTaXe1wxAuyBCxNavPUe4zpgEuGzjKbg5KZrPK1Fi2CHcVlvYfZmJc/t7IXs19imes6TbDXTHzt+9YHS0XeiPp0IuUNLUYGW6idJM6q7JDNBKlSPYsRN5ffJITZT2b7UZgtRsvYJafFkKrfgs2S6WuC11LWG8lEIs+noEDrf/MyuDk9prMWd8gfmsK2qQ1V5kAsiZvhGM7gmRMBk2uyLPFidMFEsQlCnbf+AL9X5VOpouNBaQLW3ozhduuqAmhdJgfKmHm92BKXILt4zvTNZekC7rFygnQA2BnR4fIilaYIHeel2y+j89e/ZCVgxny5lSJ18gecQD8Pux/lsFMlGru7fBORxlAud3jw4eWOZdGGrGxAdo48XRbixD9TaxNJu6l09mClaVbsGBKRl2D84RFmliRJ68bbF89jHACvZmeQyHApmE4g1oK/wEMPYbmwNQ7rSp6E++LGgyorPn9LIX/54as8jOD/2kyneDlJdv4vlL5f7mKJRWUw2SsjuizkEKPrdZRi1MxjqWN7nimeHfruBsv7SAz0K0swVUvWdIo4Lr+mwvSOytELx2yhk3H7tT7RaHH4KAsCF6n0nID2N1luFn/CifG1yhKLUWvBEFJDl1tz56t/gL0qI09Jpiz5s1PTy6QTf1nKJEIyQYlZXm+JOyLW0qUfblYyyMsJFTyJlvHaj+4YMAKL8CHuI/zJQSGkwIG1h2CdWsxWIlMQwiFck0dZMkORpfEQd7ZcJ74auqjjtAIpgoNN0/ibjzdddqWItwphI2SLZeUXpwnGUWJBcDMtnOQGyuEBva3ukBdBVsPVeVckYmmKmB0fGQEp0f33N5FvirnTOAMlvCMMQdJlmpW2LAivmBTlzZSHBNgkvJv7JLBbxkGcJsC2h4QUYWP7h7H21xtXBHgRkTkW0AeHxfVCOAo6B9dhFFCyYpgCLHk0zB+K3tsZ0yFjvOTWa5h3LgvoNoEmuz59P1WYnxcLIYXcX6cyZyZJJtV50wg3DsMKY9Xh/TA0EVKMepYjsOlTL4ag7RbTL/g0g2xrBYi2nGUzWi7ujFKWvaSAfmMcieogV3dEeBK1XHoB1UY4m6aXIsOhhT3v+R7ds0g431OJsyfmnuIgbIdn6ZawUT7v8DDNDHsYrr/kNXBzQIhAkWVaBo+wlUxGllDWJlJC/DSgYAXFB/h5VFsGp0/grby2efIXOE/kUuR4/BXhoBAS7m8BtcDjgYfRgetY9+/8TUibwB7xR+OQRBTyNQTUyIvr6UFJFZpuuzs0232zPZp2egqKCNehtpr4lL2bOHYTfCfJoLjbRIdNuYK57JhuX3uyZXA5cO9aLH5DITSADifDXfJ8WySiM5HmVbCAomMMHAZ4NZkb1kzAwewZl28Oer3ehK/WduvEcGNn/gIT9AI9RlFAqYk5MO+vzs/4VV1cR2GoogIRdB9HUwhEQQ5N+4K2li2WIeo/ejRo4hGMTkLLXwNs2xUyhfFAsMQIGMbUCN1/SPU0NMI7DJiG8zEyNt695z96UF8P6vAuAF/hgbpPLeMMajHJoCV5oAb+o3FHIN7ayE5ft5AqXDgMHRQ217Ho/wWOJt4TBN+Bx5fLaYEf26hbmJRPF1X/nDJZumMmEceMbCpvMJXDWd9+eMWy/DQpug21hoXEoMyP45EcEFAWsm68gGVvGnYgoLibBo2s1ssMwwfEgf3FBXjxkH/rz2Q1+rC1tllwlpI8UJ2CB/tXrxNhUkhFFpjAiVgpW5KNhxpvP6THUnpwJwLFtjy01XgV+KA9tbNMllndZkpYacianZ1WluTK4NIqkfsJXMMdaZSeY93ruQLAOkzw8opHBGvo0RO1Vxxd+uz5gUFcGEBF/U3f3bYMIS55e493Wl6Q9ChS4HLMbCX3AGHJ9HOMQRUNUNrsADif4/JqWS1bZ76rEAA6ICN7QrsLszPvWWbfHlBzvBgSczQfWxO7TTuLLsmQUDfgUjom7FclhGTZKWmbnkaq58bUoLyrIA33XDKnbh5Zy+4sCPrEcsR5hnhJPmleAWY4QRjOQtFdquS2hsOZscNsRioPR8tu+ZjDVQb1HfhNQ9Zmct3zOLJ6jV6iNTt8w/uU5jJVF8mHpeQ3E+ajGKUCnCWJCE+xqhy8oWVgEyw6EmxN4l1WhsRXdR205iTSFqshataEk+GTeHYyQi7IeF08GXlspvBkHlELVayetk/DlnHirByeoNlpt9uGdUcCYpUnSIMRD0ufESjFqwOYMxYBory4DFE4BtTA/CwnxByWLcgsXo2zN7Ejtvn5Hkm9d+PFaV7fYXkqi/fUyZHayOradAeDWkuTsa/GZtXStDjVZhGTzTikAcLTIrWV9TNeiAQ6tsrKL05obLyQRlUKVafuWnlKRupmlXDgpqKVW8bxarVhhkeG8Spg0/8BqclgA0apwwCCQJw8OERAKbKE6U9pBJidnSF1sfRLRP2u8PS3QSGapuPy1WWJpfuukIUqIkXz4HB57y6RNFynUVHclfrr2YuNED43Xqn0SWPeq0XMb7zYtWkA2RVnhO8Zb4+mstnwHwaZc3yb+EvcjjceO3v2OPOKmvXFFc93IuxqAs0ocvwb5DrljlNXe1g56BPTyHJ8sZqTFVypIyB5YMcCuMwuqolPKLiTb3m7S/qyK9ztcm7fiEhcTyD1FkwkmkM6IGZ/0ZubE6trmx3aJuP5yBrag6ylOTveQuKl3PsF9CurxfDtr3fakZQYM6iH6gFigum2Z4XlzT9zKg/om69x2d1JqUupd4qzByrWaSwrZ1YQratJf80kQ6c9ghVubHWrDCVHJWsOFd1tpLejoCDM1mJ6hF6O8ave5FWn1wKM28FQe5wIUapj1CNe/TquP1u8jN+lcKw6ZmGy1XrJD9O+AenGmlP4KBX2mupmtR1WQbvOjrC+/WQ0GliDRW9s0oW1MPvz7tyc9Oy5Oe53x5PRhM6HpJsZTHkactmAlDV3ILzAX0T5vhMm0KkN5gNZTXB7I1NyA9dMap8XJbWX+k22ytSWFGoIFTk3G7hQJOxEfdPLhWpGSZ5fqY6N7aQ1DaDzMkfApWqzSHIIMgeY3xPZ2VtWkEqgPMTXkfnTjAAcSP7M8Ged9zDNfsyrCgEadEmsJ/Cmamp4OaGAZIPlk9eMYiIBHoJyFPKP3Bw3i/x76jWa4DX9qHGeJiZbLHJy54rzO6UEvdo2BeRPzFzJElJLhuLZtRnHjcYTMrdsukh/1iWlJDpGemQPqhVxpFYHjyDgfO4aMlRkTlMTacroEcpaf1jdy4loQFzjprHPHsV8gCk8ftP4B0uY4Hfu5Mvp2M+cZf6//CO6zrU3Jpk/rTvxdNcg5TTXyXytkVzj18ySPHV7S4gxUaWrWFPbBxoVFPquuwefvYtKhqv38TNE+myxlNoapork/gwlU8Fub1AeLKfX5UQknXq6CkMKD1FgLqdiylY9TJkjXENAGQwigmJ0Nz8Go7fz3D4kGSbB436rp4Okx5SjeeQChbEcfcBMvBeekwpNIkiYApPKka9iN/hKqBcIf4VG5z2GGhhWhxd7t1kRL8Y6VZ2OuWPUaDgFINk68aYyrISS4Iyj1DqosFEPlN2USl4UdbVL92xmpjk7F5AlHF3h36sYOhqfQHbmYQuZEhgaMp579BAs/vkBtkz6lCvleIF+BnpJyG0moO/KAiqasFelUgmjSYWleqMHaU3Lhd2tl343nq95b7gfdTIoFyv1e2/OGLWjLPLKpQYsGS495vjmtIU/Gi84hA9rqskTZ5tYlJD5jEoCX2UZJ1OgHrY+u+FnOGm9Jw7gnnYsyG9Yb+o3sipMpuYZFw1sTsU89oY47ibQVZDS2IUWrBBImrGE16piUr7msFVT8blfeC5LxrERlqwlG1kkyialx7gLMwgL4Ep3VKTLVLhsd+lw3rfGxJzYnYXZp725ObZGxBwsJrRrdwj8mhuPl1RvGXGLl1u57GXlsYTxqjSneA5w50mWW4i/WQc+Hmr4AZEjKdOBGSEZlyIAubcsG/sWuI5bKJp/lgmSeYrGUIygMygyQX5HU1Cn26Nw3zTpeDI3O127Z5L+YGj2u8Nhp98ZQZUUboMoBkZzwmyaSWjga8aLrap5l7jsRbTMLq0j+qpoSLniJUQA1Eq0lKTkAGti+HJHFV57E3dO1lDxlgoP8I3q1Z2ZqFeswdUBWTRCS3Pfub6GCs6cj5+gJ1Ev4VhTMrSun75q+N6+AeNIDAN5WE0wnX6f4D0t2fTTKFnr5xWXTi94tnhvXkpewlmd2+McIAvcyEmBdEJB710FZgwG9qjXG1GzY7eJ2Z8sLHMy7g7NSXcwJ/22vWj3BkhEKFpdFDeQKt6cIQ1/N12x2gkRHBfk/59QuXmQV6t6dzMVhar/3Ilqi3L/+SWqtbvxO5WoTsQ9FkG6xpsxfVxnir7viBBJ94OyW2MdMlYbP2YqAlWlqn7hq8u5H6G4dsGZrOEJ1SbNNIZEge2ZtC/pcn8yJnCpg2SbfX6J7jQ8T+0ghpQJKG8Bi8KW93X1L1lM04vwpRER8IpwbIyt8iB0fj4AE1iyonTLtEe4OIonXbkvkx7CApWhhbhOgQURJAsXQksr5g0lcjgSJkwcu2kcwaD35aArhdDmVrXE12RBtdSdAn/jWZ4yVqGegjYko0l70OmZ8/l8YPYnvZ45now65mhIRv0+tQb9/rioKufO0z1G9qg3JNbApDYU5hzaA3PSGw3MUbs76IwGc9KxJxW90SX8UDlqod6K664rWTdcWSpKMkAxLR2uZA21/PgqWZ0wrtrCwTMrVVt7d/z2nSIgDy6Pp8cH+yeNpvjl9Ojw+BpK7pycf8gbYE49OM3w0ARTKXv0XbIM3EFcBo7/cirKwJ1oysBVtAZ5CtBoiSE9hknjI7qQp3j8m7A5NiFnCBI0N8wSdOyZF4G/hMpYmaFONx5NVWuvfmvF44hlgHKq/hLWqNju0ceZWn5Ts7Mgx1wtgsksxpAxtF7HmT/ZJVUAFhnBOs1us9fsZ0266hjSxLnG41YkaNWnisdqdWJsyp+SsSVR2P7UdK1kVLWspLcO/AfHroSIX5b7JL0olXKfvll+U6LwBWRVNRufzRCgGVwahmZEg4DAoWRKNpg7LjI/6uIQuD3z+VTKVZHqCUVbZw2lKnkMirKIXrO146o/2nacBFyUUnHLD+JsrioZQjtLRTEu+d7//oWxq6WvPItjMvp/4qxX0g8KsxrykhOYNJRoAc8Sh2UR5nnycBPdgSpoVQkQTD7MSi2nItxLlIDT/QPzyll6SSfMaxJCXvUmAj3gzPeAtq8pCWggvoQz3rGMd5SgcaSZbOkjk2YRx0vW41FMSbCkEap+xVH5IGoxZQ2gUjFWjkRE4idC2tBWvmMlJkxAFwA/3/Ep5YI6snK+Bn8ODguOegp3ITGDgPHITqwenB8ZreV5F++7/9e4p7Bd/mUe4NBM9qR0477i/35lmWNzXXVCHndnxhnGfGsZLI+jdt5EXiIHWJAYl8xCagW6yK8r/B4QdmKOBvYy+ItcsGU3Cgi0mwQn3jSKx7Z6MtkoTCBhs/EYOBGNXWYoqoTrPa6nnmMBu0oUM9qCUrH4Ehsx/kYcJlkbCFvR7IZramWJHH5a9mmL7sa5RWmplYr98VcrJXUvBXYNyhQEdCZy9/5KQNffEaK6cniQdjmgkToA09UWmQ+tQgCGhkRHDzR4krWFsfhwHNljEc/GDptGyJRqtjtWoqhVuAkWBFCPSHTjARplovjyLXr4bxmC9Ya2jAvWTYg9MGOdK5DnLH9FbzwEMYMaz67rPzIIOlHieC1eRtMn+43V78ZbgGfcsiDy210I7YI66V+/8tCFYn6TtEsmhj+imWqONxG6hnmR0HR0CBBpRmF9SjbJ8IYMYSu3kLJwtD0RfsfvOcEzDaWHGK9FbU04Bl5z7h2MkF8YDtSOYrjA4mYSowhXCQDkwJ5PhrMC8wSBlGhqbfACLhpnIOdP/iYwMjVF+S0Q0DWXiEkH96Xwjtj+o3E8bRorJ0xiPjdZsDy7XjUZfLHPQpMysWnl5llbgypWZdrpeRRbJOu0fNmeXFy2P7/5V8e+uL6PptdHbw4vf/sVk8hcf+lr1Cl/6SeUv/xuSlU5y/ZaD9SKAuczlB0ICCp1h8gaUI+QWPcz6C/cYxSQBNhbttbsGlPNFl6JyOnS2QKYU7cFYlxjuL4FlKXHc6NPpreMNCoC/EtuxEwdmBA1+Jl+cbh67+5wjXxvHdBVK3YUwBrReotUVucvLrP5C2QErdYkQvOypv5fEVWL7riAdKbxQyWy4FO3UhS6SGcZeq0Sv7QmX06kcKG1hBmsGC0YYH5NyaCUmcfS8vtedBf4awcqLb92ovnGukfsvtc+RKFCLrq7oR6+eBj46zl+/daJ3m3m8AdrHvOMjQuXRMAu8fdqt++dgID1WebyKX8bUGQU4tih9vyaeqz2PE8QvyIuDRd+gK1csZPpzH+E2vO+v8qjao4Je7OGc4HaCRIiTVVTQk1BoND0bPru8vzi+AAoi/R9fTx9fX3wz6Mp/H3+L6Dp+dmbk+ujM3zx8PL8gn399nj67vo1/MGaPzg5vz6cXZzsT9+cX57G36vdvj++3Ac6Hh9cnl+dv5mqf8+Oz6ZHl2fokji/ODpjNN0/Obp6c36Jb18dXf5+fHB0dv4BPpzsH/wTaHp+fpqhKb+pavQaLRIBkDNkVn6p43h+FMdS/Dcyl9TE5tJDOzw7mBQDYDqDaacNkYgQAKPH6Pp7WnbYAwzaV1fXRPCI8TvYU5j+6fmRsP/YnKG5HhlQEiZ5OHPQJHkZrTiZfCE5JqaIvIBrTWCRkJakDHw2maHKZLMqyFTgXeCvLWMKM+WJIQLbJ6DRJvCYtx+uwQpET/GM9SYX2Id+4HxBJjBFjbQKtpevGa2mdlCzhAveAQLIYNCm4367bdLuZG72O3bfJKPO0Oz3h8PBoA9huW3dBvrzbHBvIX23fmHunN17vJA+jibbuhbxYEPwzWuAyrBZ3okM7V0bwmpDNOVLzeen/KPo7Lannf6r/iBPdD7QINRefX9nPygl9dAEkEOy2PcbM6fjRb1uoopfJaiofOuhjMvSmxHzMabEJHO0A9WOrYmV4kK4xKxunHsGi0DfOwIBgiamOdQMAkkJ12vmR2dYd2zO+BJz8TQNHzDO4Mhhz60o8cB4fE/pOvbh4G8JG3KOGlJFdJf6KGOZqPNKVhLe0vfnC/IgLQSJMhQwUHxHQG0wQ8C/GgoUj5xrOpjq3en2kmPvtyfDtImjqqhXeRUInMNPxxK5rjTNR4OEp+J+K2UsWB5k5cMiLyGSRDSMZp906EnTgoGkNY66/VbKRFI7/AtnISnD/PMykBJcUjP7SBSifW4WUp2D+lsk3mWMHpUyiATg2XeHZ6uknCkD/NOVshykOJxWcpBNVbDkSMXKiG16lilCawP2JXkp86gGZpO8k3tI11G+KbMqutuuBVp1ZDcWlTgT+eZFKff8GU5+fZZyNZqIXtmta4uAgjiH+xKbEHkE30k+bwMWVpx3XQIUlkUPSSUcVGetb4sQtiYBWdGI1nOIx6t6Eb+/VR5r3FIVhK/6rSYBinaIplUTCKr4dCrBha3AYbrzMiHWU6zdVOVrgg2Uc1azCFkCFoBIwTf5Z8ZzsaPKFJA6MFEZMVXtQOM4C+qW/SvCTCjj+5YQE1uL52rwEt95CyV2Tx0si6IjTxPgCb/hCZe4lRWss8xZCFZOiJacQ+o5PDchTkm+9sgDcdhdWDqpjCmFKAQSOO5T+glWmuaoZE4XiQMjOZn4N36praXwPZMtvwOism6E+ZSqimJSUY5VRytJDwlc0uiR5gDP1WRb1pGdo/RsE37zOnDoQperqPTKR1tivuV/VYpleaDB3A+TYRZ1O2R+ZZY5ZlwJd8TrwL9njo/ciP43LlliBS98YI/blkUWBA/DcJ0wSpbcifH8LD9gzhBk+4M4C3KdGXdOdKCSsy3u/LkhOV4WWXBLimEYQwqWJNmh+CG9hsXEVmjNJocAJrI3dQeQtWMKR5Jp+a4bp0CnxbE2qnRNlmCwprYRv1zBY/znRpoyV+cMAtzqNMFeM/G1bx+vWiPANDmjtJBLLTHECGssWfVjh//KK/zXWZv0ajCd0EzUzw3iJJcSy8/W6XXoTlYCWJUsO4qxw9JA6tmiQL0qa/NC7/KjrdktynKJbhmYmQp/LB7ciwsSWsQ9IJDhh+WEU3FpgAL4skJUVeKFhhxfDBmZbmCbGGMlmikTnE8834NsPxHMBNpLnE7Ho7EAyDnkIKQ6ylDuQwpbjbJcxRTGqUajSKDeA84L9xozPGfjlHx2VpuVAd6jyrXBWCRhyNMWoTyyND/6vrEiHqaTBGHWQYXHIFR61/tmL+kSanyKB+K8L6VyinG7JtY9XA7VAEcSzlssCuMWufuWhRsbAV36rYfOLboniQ2hI0RNymwZh74aWWKIxiH+jDVhU8slIgxNDdqIXfCs+JedKhC2JXW5ksJjdYxXvxo3jTUJw5vGjXfjqd+CwnvTgMxIB3y8LQYeypIuTxzv/pA78I1ff2XphzeedklKMyKlsxNI6/meSePMgSppj/9gLlB83olkksHOIKMq+B8+NhsbtKwesy6kN3T7jNrqsMOChZObUXBHd1CdOY4+493ngTJY4itemjzlxR4iIlGcDL+t2EuAIqSF3SHnU5lPj1F+uMaer54rcel4+aj/QIPAsSlzf4Og06OjJqN9E9I8efgo802ImOL81My5zeK4Uud2nJpVlW6vSagm/jQ01kntBCU8tAJDXHXSfuAsHU8JCqlBh/wYk4+a6PYyisHV3E0S7mdO2/fNaStk5OdotvhEYmkzlh3PJoFt4IOaJf1hLxXHng1xWTTk0DwsM53ZnCoEGEhLFn7KePhrrQECvZif/PnPPfYn7jEGYwfe/+csptiiwqj6c0n/xCXlZ7ZAsd3Jwv5czz99PXeyjhll8Odift/FTCvVz1lUlTzVUkagamSet1pxWMNjeugwGSyOUE4rx4O7H/sIVh5ebKIg1+eEF9kJqEsfII868c5W6Ts2INnBLMNUtugeWTt78AO7IOyBY0Zokyp/lV5/+XNlAJVMmeKePWonqlsjO2Ixp3LbKW4mXTW191fnZwb/VXibeIUobihDpike5x6Ei+yRKAqc+Sai4R5e4r5+TXMi8kpMI90dSskQ1hgmUtwq/S9mRluAhSkXRnX9On8lSfRD+HFUeZYygoNYAR7LxJGwtdoJblFWb9mZYynLez9Z7kdjud1z2rflMFS1frLZj8Zm6LzaIa9lFb6d8ZxKQ00c15Ln56G/g3tcFKScCmlBEGypCS3xI+IqmYes6RjylFuVQAFiAWslqiTE62+CUBdHeYDfs3ow+Kc5J6BZreXkSiKLnt6v/zg4Hh7XrWd+cBwer96s/lh9Xv9X73I97w4Wf7x90/7jCto6Gpx9gfePotPDN9enh/tD/t9GvP/BeT/RlpGjnzUEhcR3rs3BAzA7qhC2glKc6WitVWtFEhB2wGsgxkLG5Wnt2W5zVm1Ng5m+o7MMc6xpUDAvTQdduFCsA/rg+Lp8JoVm4qFd0C0C3p4VMr6YkYy7jMHFvCdRKCOOxS6bZbudqTTBPBf/DQIvCqMC8hCMS+MBwJUskZT/hNiAn47oP8URXYkLfnqpW8bBHUehczCZGJywEBsaxlncygYX5hKWMGCzMJM78gCJ4rLprOe7jr+ax06jrvzTNvnNNV6BXqNNsdglAHE9VTePK34yxJ9nrI4XsuY6BpSp63kRvTvxnctOtloF7dvfdg2k9xw+1HeeFxHVXMQpb1WJqyKCM8fAqN3uKVbxxplvBP4mik/c68vjxtePaPiXRR1KjrjSVUoYkes3FXN1et6c2KDjf9So+t9urZ8bKiEnVbDsLDxJN+1qJNRtzERvcc6IJopE/lasQbW7PdppDxZ9atHFmNgTi/Q6ZNwbde221RuksF96XdAgycZ2ouRdNrvutR1emRtYJddVRk1WHEaZ37bw7qTaqO2C0TtdkritMfXiv9iRXz7UFadeNZZS1gneg7ls3DqSOP6LvQhEvfMfUXsMwsiJHOJWby37aip/ic2uQRBZlA/135lQsDv/EVRdtSFAS0LX252/RqNDNo1JjQ9HR2WLX+Bbm8BprUl0Z9D/GDeNPWjjptHQzhTX86P2J5H6tXI8Feqh02xEToR770IQwjhgq13ICzMhC2YQrf7ziOZHdGWlKX+TbX/Mp/aTJhHKiwLfDY14qW2BjixP7C++R1vGrb9Y3ArwvTB+rHnj3a58z4n84Bbugn5gK78qsPmLBXzlLQEzzQgtP6AclfyWBKvbG48AfH7iVSiKhW8pr7QwdD//vPAXi4aS38g/i+RZ9okPF2KBgxWrDlR0ZCRlSjljF5qk9r3YgP6gTVSBTkpQfAoEiusv0SKLGLAxGRr6SeZmqao7AQYEFiIoYfRAq2wA2a+w6Wh6Lsh+maJhBmv7KjkwzHoABtGV42GVMKisKeD54pGuSGTdlYFPF8lTJCEK1IRhjhUey84kL3UWDE6m77lPau4sTkLJ2QXDydKTeb/la98j7Z49HA7mxGr3e7RHhuM+bdu98YD05x3azYAF6Qe980NRlU+JcPvs4x91J8zlhiWq5R/lWiKLuhrC8RA3iC8lZdi2dok8SfA1MV4tSfW7Kh4lvBRm9rIwy0Kd3pDX7YUNTiDtifGsKgZz96FWrmFWlOmsv+nFWnay1amtffsvfbEuIupf92JdukrVL9bapv72F2v9sm95sS7cmIneaESWGtXCsJ0lZXIQ6HN8gdB4LeM6pIsNww0U56dSSBLh8+4AvI4lbxafP2RM+4OePbE73QnpjYaTfnvU6Y4mvSG1F/a8nRyosw4rcD2fTTXi4NNw7K4f+jPLsesII+Ud1sJwixbEO8znqk519snG6NG/75SbDT7Fuo0kX8uQTp2X3tWg6EzHFw994+D48BLymEHRoIUuh5TdSbzcSiK3Tiat7qjV6Y5b7b1uJ+vfTA94WG/Aw+cMeKgZcLffbr+y5u32q1d7CMJdNN7MommGjISB65jsMGwaqL6u/fWGFQlyFsbt//Fo9AjwAr/yVrFWGjgTay6CHxg5c6u3GD8tevUtekHXBLFvWiQirr+ccVQ8U4vDGVIW2QH46KKImVqXuth+y0AmR+MJmVs2XaQ/N3Sj2Y0O9SxmKFzXbFEI5B1O8U5KicobR6qJpNqT1WCSGksZ2fJqJ4LFhzheyML8Q6EEJHSpjafVprZKDLniIMZhnFuQlxtSlE1xyPAP1WayfFc7/aCMiOoq5pBRiYYkrsjyqFGBpQrVSnJqiugmx6m2E9HPml27c+rlq8HbXCmrcHuNO2a1dU/uya3bE23UvVZWarQgQftxV27/1DhYKTZTH26V5N3LrsGerlCQYvXEupGV3hT727CXuNn2NKPi/xZsAv5EvRBmPpqSeSr448+YMsMdx0OWuLPcqs9oNEIsQPlwqsAMe1XXd7owRh2mjrsz+djysLsVnYFpI7EZ9ImXmsUmvw3A/qdN4IS2kwPul1w4nCDU64XAQkN9U5bE4UM1mF06CCMO3mggbpUTMTeGEwkgJHaRbhk8Vtp9Moj7SJ5C45Ybxm+LmUKYz0GcEZDyHqKMxi7XDHuzumGhoTwu7UJZSktGfxYvsH9NpUvTkm7CKqJB7EZWZGxJPciyhJJmgHQpyt0CZZXdVFKBjL/V6fZmqydlU1UDJM+bouB1Hbg2h6+RIkspdZ7XHPpRWKilEpJdcG6LEFcJtiHhQw0ScyfWdiAeD10FH+yNJ4rrIKMzrgqxiNaTv5FIX7fxtmZlqUXShWHdUes+vPEY6vYdZRV3sJC2wCu9o3x5eEHrMAIvHWwGkljlX8IbT+XOuM+m4Tr3rJQJvqz8FBoy9TZh8M6vQcNf3HalFQEnlkaramuXMg8KRq6lDCvkHM7exWBZ5dAgobKqpXPeTvryviEt7FvK4SpSQAXhrTSsst2eu0uL9iRW7kWpb1YQs/HTLK+ICzKFv8sXDgRFaWRMFaHLGoIrKdbAnIXOFzpbzbdtmrViQtqCCU1llVbsL9NdIXWz26pol0ghx+UBJ68iF8rJy/D9syltLJyfsZ5iogPtmAk3DPS1OLC2cdktZkGo1W7GkAEQ8mpiOyaUGW1UKDMWFyLIo55IAC04IYT7k79SgT6PJKB3/ibUXW7BHiiVZbji5ph7anlR87T1jH1LGVkRVTR6xw41o/QlXez3rQ+WjHzhWT7BQ/3TSp26bAO0HI+swzs/AmAshx2bdZsWTZhxE3LARQdhdjWqHIgJhSBxfwG1T7ncZK4zpRrAbEuVT3fD0Svhu1KWU+yv6Ux3Kay6NeQxU3QG40MgP9QFiVFPShJkq1ZOrTJcnrdY65Rg7+hO4Wztj223GR8X5mSGOpt16q5QgpqXLKFXUdnBMySmsvzC8fifRUTOHOtZlqA8ioo9iomLBjzKdJxY5XE8Y0WXZP4EyMwGzytDZfOm0emOE8VLNRPpdMfKLIb9RpN/1R0MG83GoNPVTySWoMnFyKq/+HNCS0sKlxdgBkPo4lDerV7+rTQ2Hf1iybYO/DnN5dTYugTZf1h/MCOJDWzCNsgSNmNUnYsfiOuookJ8djzxF5lDHWc9C2SE825NY0qtyoDiKJSyK/KbggHCMmC0VREwKAOFjThOOZTmiy+GjwFZr0HvDAV86LFF5zRYGrdTeOGURgR6vL3xMJVYHtfrYIMxHaiiQVpqhetyMj2jDuexOSrvo+GdDW27tuTbSkszl5fGLTu+rnpMv4ocoOn15bEIpxTZ5oKIomWUbTeeA9fulnEOdZnB7gTxeBEB/PKIBTmj3QMzVcGs90QhNRjsH/6KvVIWjBz2Xu3tyavp3mwWdLHSmti6e493pmPvCXLuifHtwQW6Y5K51RJftT6FLAoooNEm8KgtVTXNLkh6y2KYDfkKmxlZrykJQJ7fym7kI7eQDr3GFm48vF+QyOi0jRfpcsbzJ+M2EoXPzVV4+7JpzDeR8CzyNbjxRMuQgA6WnU0UQkoxg/tg9Ygdz/Yfm/wrDjaCNio0KLF7yI0XgrHJpYQlbvsGMdZ+GOLaI/YCzLTTSayNFn5O8fe3URjPXTpDW0fxZUtwE9vC19fHh03gG1bFJ/BDUE7A4FCCHrGtUYXhSxSsflLViFJQKzEP4O3alrchnEFTVBbmAqUEwaPb7XR6CTpmrC9SRiQonJ2GlrMVsaKTt9qLUFZYWHfU3rgMc4w9ZMxp9Egx9T1YEZcvpao5Bpsyvbdzp9MD1SEFG8+UWnS5H9TmJ9QsER4Qk12yjuNFwz5CLoDXcJYbzqK+gDFCmTjLFY0Cx9LG6OUXgtW0o5tlpnJZQLEI+2xFPGcBMfu8bBm/Wevvrx8T1vu8ptGfSW21+lmzEd476zX+5fnRLNh42XrS8biVcpfqOpRxHSwxS3opX19Zoo0Xfs0VDWoF1wypE8rMjLWRT5hK9GUg6VQmSekazIyjJrcWMQ1HoSoMltn24pbcg7D+/iay/FW1Sa4DZ0WCp9mzNxq/rmprGU4VGPXjQyPcIPAFx+ZAO36w8dBt/58N3VDbeHAIi+cg3oa47FsJStA0Qt8QKxqirwb1KDxpnYC/5D6ZcRVVaN7hXd05cCw8oUUR5L+xj+ounhIgE421Y91T29is4eDn4nPtu27ysMg977KU2YgayxUEXhiRoNYGqiQ9go3nsW+0cgQPjWCzZsUVoVl75m8iLFPhWdR1dZXq+bS0+1WRNcqEdBuigvgJC+EtkhIIoMEQbmsmzeOlWwC6+FYbk0vOjAkY+2xmhltGjRK7gNbsyI1HWrCt3VuD82wY3854m+pHZxlAXRWKhZm51eQl6eSzDMpKXqj4m5UstLm1z5OKq6geZcjLBQip46tzYzxsdwy22StXQk+HOiST5LivEmdWl+ox+ZIXYvl9lTsF3CLYpQxAqNH/Uvcu8TVRr6bAMqJUki+mrXG2cV24x3kABFW7+HwJyTWFjhj9M6TT7Xst1UvsBHcODQBaDwvTxZy8JgGQG9PwiMDyZFMDO8obKF/HtP6m8e+bxjzwvS/0ptE0bhrEI+5T5FjhTeOjEVBuJIod26wD8U5LeTxxPc0LDdaCq7G2QEMXrUFs5op8FuHHw3Qwcj7tMnhZFXyM8m2W2x1Hp2gRNXNzpMskDXuC2orRBhaCWHeqEAIVid0bZ7xJiWV34x3Bw2wAsSEhsTRNfn0Hd5PcCmHx2mwnG8SEv+ogPRPsXkQUGG1YRghsRCGDzJNVSgfLjGNlNXGmxXOvAwLY7kwm88lkYg7Hw4k56o175nzeWZh2r03bg4k96HXB3s8fm5tdazw2R715zxzb87nZ73Zom44X3dFg1NDlCMYjz/NgK3PjPuysjXpHy6uK/q9ZzSU/RMdfk/9sRGBV5BsLGll3+TiuN96+AZSA7BlmiDagSCagaKpnJ4p4eLfMQnl69V+fz75cD86+XHfOplb/bLrfPp3et99/2v98PnUd+O9k+v7T+eEyOvty5pw+tft/vH3vnEx/ezr9cP34x/RudfrJ6pw9ZnXHPAGvV2vxFpNwk1TGK01ermreQHQakW4sVXXsomwgdn/TpHdkboh1J5EkNe9HCd7XTLLA1V8USCHNuPFrEAcb4WlZKvdX5LPseKbNWEilPnDQTdgGaJ8XpkEWjRs+hRFdGTYFu0qo2DZ912ZoC/xay7bCG6TiK+N/MXPo//5fG8+J/jcIz4BCpBwCodrGC5s8hS+bxp3x4s7fBPDnynixcjyodfGyCXsvNF6E1AJB+hIOGrafwlfGTWNk3zSMFyODt3HT6I/v4Jv+2BCN3TS643F7Bd92m+Nx2xBNt268pDsVGivbwiObpx/FdlPAzIS4z1LqMrut3kMABVbg1Em6eDvtttYmnDH3qHVe1Mw6fiPfpSM1J0BNT5Jmlger7o6KfmfdDtmJA7p884ghFG4d2aX7pMkCqsxKib6qMJK+3wIW+rZMo1l05ojbOhZUiEHmUkGXAkx55XypqBWj2kBdZwnOLO0t7ogEAIobobYqLITUCJmLA1Q84kGlcWcl1AsRP80uc/iGiMrZ3eX5BwqN2DqYNcMcFcUBY4S8YJR/GIosgEhUsUn+7vEojJzl98BI4uPLm+APbGXabcxF1QAJqHhhXPUwNCKWTWDoh8NBtFKeLVYtOCNhNeC9wm2T10FTQjC4UMoEXlQaSWV//U/bWp4XPl/MVTOqEZ5ewtdWwTnjlUFqJLJUyRWJJIB/SUjqA2ylxu6tuiU2ywKCbmNp41FIf5KVjQve+ha2mGDCvBab1pipTciOHVrakseJzsoWDyvXYMQJzo1FcnV3ZS7KivAf1FTUPZ0e98+m192zT/ddaSr6cPTlZHr/+XR1HZ11/7g7vWoP/uuL655Ml4PT6f7n07e/ffmv6bJ9+luxNK9h/8yyaC3bp8IR38b4STpmd0za5qhD2yYZ9ag5by+sXtca94djKo2fpGP2rFHfHI16HXO+GPRMe2wNR5TY7dHE1hg/c8W73rTGQyyfnzCDDX1LB2neBSyVLJNGuPyLJM+w0ddNoclbnUqnRSZuLZPxUGZSeG5qSy5zVUhsqcasz8gJeTZ9dsjKfyGPfyrmOp+iMgx9f02sTOir1BleMNEICQMI1duBM6cL5swrSg1RZNlhL7cIttXyg+UelBra+x/J4Zj8MixLNG1c98bDL42ALmhAIb8WQA3ZAXaLUda3eM1AOjF5ddUzRFA41oxqAnbqkgQ2lJYSmTcbz6aB+8QyPY05se6pB1HdN96Js3Ii0YGMiW7GH0zXX95yAGs5dPiOHSXikLnx1FjpTtugXhSAPvsiGzfdMvYZTgQY3MKc6OkXEP11y7+PhY1j376EGmueBI9Nh1mTCJIGIMJanxygwNrL1pHtEBWs02xo+my86rUHg1F3MhwNBqP+YDJCmGQONWCGfhCZePzis+ova2qJ7xjzmJx5Gq+6zQYoJablu5uVx3rhX4Www0EmMENj41Wvz3/hFyiTecDb3WFvPBj1BpO2ekuuG5CvxB+biCwDMKgQLoCRsTgJBvjPWDb+k5EMacHuNQ2o9TZz7FkMFIHIcIK2UUC8EAgBTiF85N+d4UfEc41JBZ9SWbwQUNtak+A/GxpBvXIBvGxCrKLVeNX4EkY2cy8tpMBH41HpIgoXVUA8647BkzEplJ4xn0Jyog1V+LNTmjfo+qgtsfe68j26Io6b/5bQsj6qirwpiA0D6XwUI5REla9uAK/qYyxy+WpWIoOyRRuvOoPBoNNuTwaD0aittshIIUKbec729gkg0KyZHU+/RR4Cv5GeaGZbdJoVZhZuVhDcCtygxG9D3TXqIc+UTV3u7hRLfGw2lE0Pj7IJMltN5USH/Aj03COt2Kf5vVyTfzN33U+vxG79jKG7CaDu7YHveVDq4sGJni4rxxdYyltX1RIjYoS5hkSOlINAS/l7f35ZNdoCKjbiuaOJY0iVfkgAoJYsghjQFb7w3p9f4W+xW6JGG5fdKb4imkjN+e3B1YlzTw8Caof8kXKyuw71oiM8pHShHesAkWv+SbUVPEtRQNTmE419zAydEajquGP0usyQ7+lTFXxSxTEcxxi2mW6TrRkd3V0EdOF8rhRbHlIrqLWwmpX72mywcsFF22AJQZJpmvPXVPAuNp4Uzd/78xN/WWOHMufTvp7qn/y59nvXZ8XdC2axcngB1CvIGkDJw7844KlF6nf7cz/50BFKAOWLC7IJE69c0nCzopl33qCJGC6FjrcR6VLOau0HEf5+SaPg6ejzHdmEiR+vWALWFfMzHUCV2PRv56j1f2F5FuoPR4Bidi4InPjp2oMUGR/yJmBM1IumLKsi2cBnNEcXPXLMks5Pqe2Q9G+8wHIIc3Mo2Ig+FkEC69KbcPA5AkEfhKZw3EXgL0GX3xXbsWwWRlBdwpYEcsy86Re9w3PsCtutjMSiTP9Kgq+wmxENgsJesgTcGeEczwnv9D9rvQx6IhYcmolTknhP5wtUpyvLcZH5VRw3qC9WX/sMeK7IL5fVYY+JalEj6KrHTjyxoFzuZyG4a5DsLzhteUSJecujfpcTTyOjVt2R6mt/Lv2KRzwLnfX6acartjMPmyDoZbcaPT8+X2ZJhXVr5WxHC7UbujFtOkU3jcwtv4/EqZZrUD4Y4Ase5TwZHBOkMxpYihh5rYvLR7NBN1AHAdSNBbUDslqnmxTMsAM9+s/aU3++On7VK9TG67PcNup56rL3F1jJH5OO2UGUkpLhZP6TPh3rtR7W0b54aqubsdpHtsXMHHa2q1WtKuUdw+T6FOqQeJwFmq02EAYWxr6v4hCzHelmOxcIAV3mSNxvLjvKtMOtODxlWtKhnkj1u/I0EhwHylh1W8a2r6YOr6+peQII7UOfFcUoYqDC3kQxZ6iVkAxueVZFQu1ItyjuU5FSCVLUKw+SakLMs6g6YRxarCurExfdAPe456thxRUrFepKen7VkjRrqSiRH3llelNlo1LdZCsW/TdeOaWAaP5CiVpbs6IQW7VCMC+EIGKY/UdPVlYJKDMclJTg6vZopz1Y9KlFF2NiTyzS65Bxb9S121Zv0EsWWul1k8N06QN1ZwpQVHKkp+wHDDG3RRFqC0x98NeTMafg7zUivwKUvbfACB6Pn+8VVB/saIZ9yyGy2xuGrWzbglgp254xJJ2Z7YM/aFY5JdVy1nfaQNN9z8BC5xKxmz2IMnN6cmWw8pzcOTa9oyGVj6BSMaciPPW1Dyt9dXWSTVIoVxV0e53NMTvkMwWhn5HDYI+Cg3FOoaih3mu3XcVxWduClfiTZRFYwQleiCIxDqxoAaE8C8ejNsMP5CN8dFwAe+NN2tp9qxvmyvGmJ1caducuWFiq33m0U5Yu2CsMeM2AkxzP8lcMnpM57yD0GQYNsJIIZ2irPttWW7uhuQbUabUBMrfVwf/v4v/38qrYQ93rYw21//A9CiJFt6zVlvJrImJI8A7gpC6czy3+k8lbtPxVQ1l75q8VY2v0hhYZ9snQnnTH3dF8TIbzSXtOe/3+fN6ZL+xGSt/jnckW4pY/5m/cytbgv9HOPWTsmCixsVhQCyts1F/yKrsX3Pt8xzoh38JQAIlVVECMTLaDQx7akD8SxT7+cztuuR2/zz6MAd95W3wf5pVO2zdYbcC46k3FlD7ARrO1gPYHmTw+bW5zPQvP7FPKsqMmvZW8yuYVp8kp5XCqvYlPozKD7lOmqVQxByWeF7oML9lXNRiKPX6mzclS9YHM6hWKD8SlyMm+gRbZ72otPcx90nZUMxOHYXqESiR+gi6ub92bwaZKuUpAfXAEE1S1F8xkByZZYog8b6P81q+8itFPW77rMP3ISbbwsYpQZ3ceAUUJiX6YI0XxKKmsUmkrVbH0QSVxkNkOeEfF95oT37rH7GnuocZ3u30Gs5EziLU0fiUHcrnBJGNoDEpek/XafQLhz5ve26xdn9gyNYyfcHghQwjHmFGXDgRhs36acT029gUGws0BXRmNtTYWObL8NWV0BTDreD6i08oHQKbsVbzQGRUpzfeVJQM8/AxAyOyGS23FgsTiE/5LufCRNTLWxIKPdBMwEsDx98g+PbJPvqU9rNEyDfGUkC5gAgAoAWXNlPkjLKug8Qq9VhvIDBYpmo3EdPR5rdVkqJLRys9xbWnUfrI0qp7zc+665Rf6R87kDEH2CUEKHO8FY054JGBqHgRJVAAxkc9W4BXWBMcjiK/3outtW+D8ZvlBWFHmo+KvE5EsJIUrs5hHwh81/MBZOl7YhCyZOx/AHTzbuKPEFncGlHIH55dXaVFXAsHN7YLJAfKGswNMRhCzBFBhn2VmFhMipALfNfdh5OY7PkTWImhoWOWUJ1mi+QOmKWSuwA3mEpFVNjTmgf8Y0qBlHECevcloIV7n1QdE+Umu7ArSvKCtZcv4bEIegenYL43wzt+4tiAxDBz8KvxpEhr7jOB83EUaQrydPotsMmqb86eq8pWv5A6IfMp5ojqRSQ6Fi6bLheDbo2mj2bi4xv8/v4J/Do9OjqZHjWbj3dH+oVLau3j+nKV3MP9zxhDfdvpytcEJ92pvD4v83vlh9KoHGQaVJp3OYeQcENMCFajPaz+k76ptQcG5uAe4OsAasDEBjaWUsfsyfPXE7FnvyQO5wkaNFbnHyheIXpLdXrK+q0eZgsEtZ6LjOX3yAe4S7uBkQcGcARjgogQNf6wJRu872F88gNI88iwfS25ANaiFaUESH6/D08T+0MohtqkTGYCqVm2B0l1U3ZA6lfJ4K10S2dIABcM1DsHi7a9XrNyP1jpIPu8v6RUDgCtbcLJC+z0c9pAd8cIBoCgGHSfYmCH/iJMj8g0kLjscQHF0neVdJJcobBmvxXsrAlDtKyeSBV+7TP+FVQLVpcmSArlXQ+SssC36Yjzst9svQZ2X1hiFTDyZSCFTbwheZe1SFJ5VCX8+P0q5HsqCL2dMPZ4xIL/ZJ38+y0335YkKWOGY7yJsA+BIWDMma8b45M/L9ZFP/rws7pq1eoiN4rjzbhHMtW6sSASZL7I6FgfIAH9+y9g3PN8z2aWALQPuGyjeDIV49m4BuEHcGthQ8INgJ+DuQCqNJZgN4O/fi/y9Rq0lEiSRE/0YB4PxKTJiGO/9eSOxjgnjw0yGkW+/orxBk7mUZIPV1tbGg4SHzCtB6AVrfSVcR83Gcdof9ZGF75exS6h0dSoGzAqZMK/9ToayzYIq68gHYeAoDDlMZUW55bz8/lJqrcxeY9ize+zNpHEy5+5CbSf67+SM25GfrLqV/a/nB1sH9MHxNyETkzuywSft5ClLuJgtNvK1gPF+OpN+VGfSX4/Nd+df2toHpPfrfFQ2wIp4gM9XW/TuSIwF3ZZNH+qtasFOT803ZRplH3lYLXlkVqs8vUKjzXSledg3LH/9JO+xVYJgUiG1qbsNegiJtnA9gl05DPtKXsJdMsf6RMZNgykOxj/pk3F8eNNgl23mVAOrlQcttW48hi6Gt2xo5t+XXcMm4d3cJ4H98YUIZ4WvWnHZe+Cpvf8T+b/uveJhQ3tBdw/Cr7A5BLa+8a6AoGyzbASmGesOxwLpUeqtP/KNyy5Ws0Jc7htvzrF9mMFceZ3DeXGqP/mbXwIe8QHtsW4XfqBTllGZ54HT9SOttRHOySX7Hddh61W7wvaNePF+rlxR6HgilS514n64AkygnK0JZHvm5kxsMFxxzzjeP1ULEb9wbArw14wQzDgjXOFybC+1jus8V7qqiCemWPUUVtk/143yGOZFNMQh4llys9/gFARHirBZsQWqP9DSrZbZK7tdBD3Dfc2m42XPkC88uPnnKfL3lEU/T5EfdeVqnyKwlY3Xrj83hAWFizemy253qADFtOvOV+yePsX+FByB6Jy/3DJONxGW9TQo4B6EzgPHTA9JOEUWqTT1phhNeeSPfhwVZbmkWZU+9NTe6fmGAjrnhBMU1Bw4dwTKp/JFunKWHolgwHwPbbdgMTvs8ghaWj+vMX9jMfbzAPpRV67uAfT24Op5d5gqF4m4k8oCPQmPlc5mgh8NRHisr5PHg9HfjJLIW2mHHP623WWgsGP96VnlsOFAH5XEdtj7KbX/vnv/p9T+UVeuttSmHg2Im8IMEGv5o1qjrgONsL++PBGUTc4W2G6rrIEqQjXMTbn5scxGMkt6Bzn7rEko6PXTfal1X36HZNafHsyaGXJhGkIqD4X20aNBeOdoQJPPxU8Ga0wsd0GAigj0oh4PP4SaDQ8U8WzxT8IQquaQtoB/UQ6mufHuPf/Ry51OqBGRwO0WTGWBmAN8mEUDg7wdh7jOF46dVTbOSqNLwxmHAD0b0/XjlvmKEKfoYB2oypEA0I3e4oQdYUjY8/uplbHsezTtKeeBVTGHKjyYoj8uu1ymr3VyLFVqpF33YlB5eZh8aJlkn3TWY5LGKnwVr4WcE90P2uNyQwLiRTy2eM7KCOpFpsSCVoHZKkC1yb/MO2d5VyE9B2udNF410umakADnLKj1ZGXy7nQ1T9hPKADlawbij+IPKOtYZhhZRDQAJYGHdgZQjgriFT2Eg49DfCsV9d1P4LTEIO26rRKVBB9CW1V2e8QCPHnvH9PE+l7ZYHGPyVyw+PtUzuPz1s2HTAJ+1FoGNF0hiJREWoprMem3WbJD6KDGmuGAMitWMZEJwBZPN27kQBmTa5ZgOJWkypI3/g2pCK8bvrf0QTlYiXaMbKZileTZyryRSpn9+lVJbdSXi7PFysPRIbM5IblS5Qs8vrL5AXmZazlR31Olxb9TCqkI/galGsO9Of5ydXbhcfh8MDW5o3pqdR6fVEiPzhMzX1mhhB81NfoIyp/QRHK076Kl4Y54ZTnSavy6wtvFjA8mjDviLSm7zQhvHUaX+wsNC2x/UoiUgHgnNzKJWsn0Z41KVNjct8IA+DaMmlyxopMmm0ZQQQyoSeSJjiQlw5SFIaxhYuBvFKkQP20SP20SP20SP20Sf1ObRMWbfMZgrLVnsEpsP7Zto3T80aOvR7LSD1/yIxs5/6gO3J7Y3fFgPLAHi/FiMG8vxoPRvD0YzBeDUX/RmXCE3cxCxWcgJA7PuLI9S9SY1V5P4p/ZrRXzjsUFwY/T3ctV5lJxn2zbCQUUYqxO8q6MD+BO4782ucb2S2hghVcnREdbFLvNPEoCipVNMch34QRhhKnqnkHCJ8+6C3zP34TukxHQtYtCxU663H4JjXXgQAlC3kjVxA5Jcy2iUoGFILbfAFnu4xuTNOQAUe78RwNBS+ubcZSU8Iw1J1lh77vZdsSQPqapVt2wUk62jRc57t/NtFIMnVWXXnEj7lM5Zcomdixbqz49Pq9MKldVVZ3tWt3R+5ppk8eHukMvgS38bP1Yio68lLDvpRw/PyUtpmej3en0yIT2B/2JtZjMO4tFZ74YDGm7b5O2RReNpnImbuZm2fMtNrqSPD85gGYWylEwi4K6XfEKxF7UAS/lYk35nlLTVJiuYtwMYU2AgjEVJDGvoXvlfNEFcItWs0AXyVpnqei49PCybo+4lTV5gtO2ZACJaRlzEf2B562mWU7XDFCGZtfwT37AQn+yoBjGfsqm6Ej4cwIPMO1WQZ248R7vfFeLOpGrl9hTR6c9fxDVYaEfUVytZezPQ4gRfLxzXCp/BmCSCK6Bt0dnv10fXR8d3oLF7fby+uzs+OztrT40R3N6VLax4VpA7rkPpuK7NIZIooyjwIFIGcX42O8dT3tnLwEV4V9oFjUijhvGJyxXpbZAPGHPqtX0ynidvwFMKpYm9I0FUYPwNYpOG8gessPhwKVEE+0/DTZKwWBoGPD2eUU+NCrCexrgEwMj17DktLCIE2ShG4+hg8StzOnCD6iBFSUNflQhkwfEQiQl6NIBeCp7Y1E7wVQKBnGu+V+uQgnwSwrUZUWJp4N0qQ7oojHWN9Ory4uZBVGF3aiQvmIR5hqV0mYxJCKAwfDXtHbbGH9GXoPjKTSzO0eguxaWVIgtA0oo5G/wGpN2AbWo80BDMCcxIwjateFCgMsKS3bZFUsKoEr6St8V1J0MGm2p6oWP6zQvNgG94hVzTQf+R0jHhP834W+TdEgH/68D/5FOpwiytzwbCB8rHgTeEE18MA/mpcyZXBYPmeOn2Id2YKTx+vFn2dKjpTEKnOWSBsnlf4a/IuiaRAYixGVUGhebSJa1PfDXosbtRzCMwWnEKzgJzVidSBZGW/mcAJQTxxjfEExsI88m5sduJiyYQeBrFy/iWXJzQLwvz+eNw86LljhPiCbbFVUbUCVAbypsQ3EacT8pqOfMPFQ4Yme13MtzdG0WOxwMa614MK1Pa5qbQqGWoU0dMQLTPD4qceVKBHbcb7fd7ZvtidmZTLudV4P+q/641W8P/ijYiDppgyjJ30zYZAq/se38UQaFxFuq4Gacs7+ajUPFh42/sWKTqWCIRrNxInxt+AZid+XK8cShVq6K800COI/LwN94Npy7TcN24DH0TjEt65Yfgbct45JGm8CTyteNh0j3VCgy7+H9tzRSPiOAJEKqx9+FskAdQtCFK3QNryk3QlrEu/GIG1BiQ8ke4/bg/PQCIEIPbxnLYSy9EfCxMBVJGTWrM7Yi6zUshoyVEMpsrpDM3maaOfBpFfHuk5BzPMMCzognbnUWusXX6rXeNKOs4LEtHNZHDffMYk0qjY4vYppi31EOKxVdOMQVqtFs8PsT7AKxzo1m483+8Qn+cbB/dnB0An/rxoneXQzrKzuQ4eFcYxGq6I5w/AUBSNc1WRYihtbRMFG19OjnSK1bn5PIOxX5IGsIVyChcWulX7qFnwNWDJ5yA/jnzIhVG0gSfy9UaMkZiZtIYmqmURHhe7bYagEybiXgsqn8unevS3qASwtklb8A29pL6Y3k9zzWUrWbyOrJ5I9Hn6NGLKpZXAA/JvkkWWJCNkuPLLlj3oAH4JYRx/PJa1SoAKCWRxJtgtDX3AKUrtgjsKyQVsQ5ERcVZSe/QLEicLlrD5Rjc9P7SmPkw6f3wR//unfOnfeP//WvS/+kd/lw0u0MTj5MHLL6/ZN9MGjTd785i99+/bXBIq4A1lVnqzzwVytfxIdRuKLA7kcxTQzxXpBEdTWOiHUHF010tqwDCtoMWHtAdqxvPH+Bt1QjvCN4OSWGpfZibNbC4CA7aBlH/9k4D8SFnRv5xlXvl9C4ZYO74GO7vfEA1BQIyun5e/f2H9gOu7qjadd2FguGTGxBUWjBjfSzw3CgL7uYPPQIl2QekaHe0ctjMhT1W16gQf77YPPdw69wezrhLAo2HvqqimzElK85KmDyDQxGQEckT1SjCo+Vig5NBUihM9Ngtua1HLO7WED6Zgyo8rQ21jRI96ax1nTbyubl20pnsUXjKm5O4sU3qipbEkOEhHlWw9fMky4eAIY0WU7imjiBvixMfuexoT0XKVVnuqYRWeoJDTep6MmIyFJCO/DejWPPeH91fobSam9JFahmdjXgCZYBebzx7uhnw3aW4Dp9AdPwN5ERbgI8woHZ/7PxIxq+xBAl4910emHcHk3J8jaN0G343o0Hit+58FxC8FNoXL45MEbdXhe1wOMr4zEga8hXA2em0o3tb+YuNVlvZTDCdr9jjy17Ml602/Nuu08n43Z7MhlTazHud0eoTUGOZ2Jxyw9rfgAm32SFj/VLENvT+MG11RHVbLgkjGYr30bZqO8KbFxIQgTtjhcbtzy8b4j3K5rKstexjtkZTDvtV732q3b7D7SlaT0GMBz4RchFPhDHM+ZPUeIw1Dqb++PBaIhhP9QqFmqiYbgsWMHTWu40wqNcaGCGm/XahZAw/gicpPcJrJK8UrY7K2WVxzmZueHukeIkLT5qSi9I8OBFDDTRUxLxHZ6D/TWnd+TB8YO0rChk2BX5DMEMvwLOOvADdoqxvDkbIsmlBP0nlioZfwk5ljw7+inGBWtVlSos2+mavc6023s1mLwaTJBlLQbdf+iEaz8vKDymDlc8CJPFGW2vKp1IFBHrDgD6/2EsHBfq+tBfb8QDrU/r5U1DGZwsK1AwMjyt2ePA2qzSAeG8zlWfKkNbfnHWStcnxFtucs9ul/+a2tn83RKF0jOvr5Se8r1Rp8enRwY0lOymzGxGlnQPzVXKvltvouddW1gcUoWwpjrHcFyKqMLEqpxlNa5MtfrOPZCqCf5UX/IEMF4QBpUPHZacifw82EFhwWQdpponqHh1h4fnA4sk1g+G/2hcX8d+oFpL11vYg3mfjM1Ot9c3B8PR2CRzyzbpog3fwBeTeKfQlf9At067r1KImXWxFfJ2JZhoDTZ/IUp06oK/3e1831DtLgKmAzOkWBEoxbWxoBE/6epfxjvm+6l98H56/GQ710+nzvWX36ZH7un9qXv66f0X++2bJ/vozcp++/sTPPN+evYa/v3j7Zsu+XD5aH94H5IP8Oyxe9b+Da/r+Xe008z9jA+RFUsHL0byapYtu9IFR3rkR8SdIUqKzoAVEVfpgsW4chuhNLPJmleGmijLXemsyryD/s8Y2H3+BAdsRANe+Gcd209ga4OqCF4lhmRn+V4I1YQ8FkfJMV24j4S69IGZt5n9D60IJcprv4tJBEA/iCZIB7UpFBFcWC0J8qej8Kej8Ed1FOZ6yXADIEhUhROmCENMhBqROdgmuGKMEevUNpQ3K8eoV4AVS8VlSIgqxqB5QE9AzhsvvxRSjGeq8xjqVroKOh5nYJ60JNCJtkEzqon4VZiReoUVOv1FDFyViO6vmrOVh2BVyBSJnb0bCEI9kY0X+x+umojMBxtMq+t6G9dNAkXkLbMWvyoJWgVoVi8QvcuxctC7wucNZQdQuMYL9uuzxlEVB76JAIZNQNxqFgPn5kHDX7KMEYY0oqy1yJ2CNX7OXGS8QOaCk94xapIybBiPPrpP6XtB2DQ2CDOi5EOi4+DRCbUhTzHsiVLBq1JRr9wwgyJncsWgA/PRsenzyqn9jOktiektqPz2Fw7BzA25qKFFpGvaaQwZSUgAfojDYc+4ENeIeT34cQIXDFXd4C3ceNgExKq7j+Qp5O7DHB9GxbJ+C+K41H4N1hSd0xjj+bmxZU4hOQyrWUAMNLwnLgvcyqC/1SgXGdFf5RBs2TJT3nmvcvuW9ydonDND7kNaJyYq1yU247lPLeOC2XBRYEp34Ac/uKcBBnVUH4x4u3hQ0oD/nUa1xaLox1TaY3jvgGuuPtfxF+uzHX9xiynyNyt0oa1xuZU8SMGg1i+QmUglz46rmSvBstyQaa9KpHr+eRB0ZxFdrWfsagTVU+2welW1Kgq0RIKuejHJzX06X3N3jS+kRHQXqoi6VMFJTQFNl8Rm5Fxw1ySQK1mMb3sv8W3xmoDviXgRhnGMJwrQ2g8g01gdqUU8MHbRzxai2UlkYEhMBrCQML2rFNxm+btm48bvyprOAuEi7r2IsYm9cjwTojFNuPUCKylfgWrcEOuVfEr9Dh/LUSlF7FDBYvPAn2+/2FHk5lbShtBHdB/wBdavY5yn3eSBSsN2f9xui2+NFyPDJk/h/2fvzZfbRpJ94Vep0B/ddhyKlmTL28SNuGpJ3a0Z2dJIcvvMjBxgESiSGIEAB4tk9oSf577H92RfZGatQAEEJblXnjjRYxG1ZG1ZmVmZv3zqs7Jqaf0NhGVLb5qtt9RC3yBOy3wuf7DO07/0t0yb8Dw7XJcinrAN7i/IZOy95l11s5qmK/rtGeJGWBMML8veKFC3H6eSj9oOHtb3lWOVVUgqZCoT5I0vIcoa+M5dzfjB/AuBk9GW/EWEVY4vkf3T67hbh/da/cb4dEn6AiW36sRaZfBnAlRXsbm3L9ZYJgNJvUK5kAVBkrKChldU0kVxU/rditEAS7d6p/sK8Hz01gQlykhiftcU4rSwKk1JQXY2UGO3RqSp/NSYygCkcpno7bc+pXoCwJryqW5U+SoT7vgC6f7xr0dbAfC/+z1M/1ff0apr/R67yjBglb7XYrgdEgE8gav7Ji6Dg5NDHejY1AQOThh9JmmpgFQMGPqLL9Dg/4BGQuVQlU3YXAh8CkDIPtVagQaDoprPeR4jbd3bQJb8WRs7uqH1zWgu7YpyYCDH2MSs096VXVG1Bw3GJb4F6dmrzyo+8l4KLYauuG+1/1vgs5sZKVrPLj5WUfNgtqs50KHbK8qDnHy2f9pTVYuBDBiSFhqOfhdY4afdZiGWZ9ncQfkAOxcbgYOFmGxPZ/G/b5KR7/If54LfZFUZQAsPyJvQNqk049EZiNK1OL2AexSw0g3UU5Mnq3hkhEbrIo3Waxsr+Oame5Fl9T4kJfGtCCBCLg7jBU99KqLxPLDLqbieZKk8EBq9GtCMOf8MwFmySu/+lPu70y891sPzQo9+aTcGUVwsEr4MUm+s8xWcxc4DQgYa0Ih8izGP06oUCA1WVHPf+501JCrLVFnIMhIKexwEGGwvuwVhkk95KpmT96AfLBYsjmiOZhm6g9gD8crY1N0627JBodOaN85NRYGZKLf2Tao05dOTn463BlvH749ktFrpNeAr78fVDcq13aJtX5S54HPSgNT2wm6qRbQuE9CO47Lu6qPnszi5XLxl+8qWLatU8wx3nzjPjm1uLWdjOIzRmaCGNFBFcdYmEJwZF1iZM9pB0wOkOJ5HKpc06OYZbWV46hbwey7CLI/6IAUBYHEqPG/ASCErIKFnghaQO77EOy9OEeIfP0/oVQt9aXKQOGz8swJjssjm2P1GWJQiF5m9A7M0w6nF3z/hE3Hkc90/hJ9ZVSCEifb7puHjb9IfBd2ZZXjST+evn/10/gZf4URCPl6gaMPTr1yTAQE5o/+zWSntGUYGLXn5g98YL8RAOgQAPZLj1qryqszA0TukFErk/3Ob5ePYawgz03NwcGjNzbtzeHWG3z6hLr3I8jKAhfDNDvrqF3AISaDOGFWw168QGAMt0KLWkKk1GdpWpUQyawu37G44NDk4ZfhM+xBIgfoQi9MxbpUn8pzlTyV5cHQh/i3sEe2ITwSBRDCJLDHIXAtw0AVPwGc+IPCStmJIhbw5mk+kgAGZe6vSp2BcwWscxLjyZY9yYg5/RkHdS8e6oFtImWdF8J+KJ3Hp72fB0fkxSLLC37Aq0DlvC9E+GQtCDGr9XhR56G1U3xCeal9W7qfDal4lnMxKDc41nQKHLDHga+XO0h708o5avdNaFrmvdH3KS5GGS2sEeh1gndaS1M+x2mlWFG5zck8E82y95kQegkE5EXRo/QtxLpd89cHOqlLOv9om9z/Z8LLZcZZ+nWPTStSqY5GX/nqPd1ycVep5XPqs1/rn5Te6t/UiPODg1mf+kKdRDELfOY/bzsfJ4TG8ulE5DOutzy4now7c0z0cS295jHbLQIHDB+O4zF1UWbOPTPGsKjGFTWdxOnuAcsJBngyyFPa8/5rocQOvOMpKDMcI3aDM40VQSn+hRlmMX5VbS/UZOKfEnfbjRRbO2DxOklg9iWkgIVRJqC1UUVR7XmRLu2MYyWN1WrjhblaHCKytt0zAoygXviQXnrIt7KdeLBXlXZbfBEpzXFkB9qZ/WeoF86zMQooXXdlqLhJSmNYYoarTm6LeY6xyP9VpJlGKrK82RqK8G/odmn4C2KrrBiKhStFzjzQKt91R9XKtU9ws2bXqjdKtK9Io2bYkFAazmm00+PWMl+/IkL/aeBzOeBlE2V0KLkmKlJrj5cWp5dMLFViSTQsVaaIq+21CjfYD0Rb2DO4AmpGoKuiojQovhTivhORpDqiDiLoF4xgeQi7We0LtY+qIpJO9AkCBemRiyEK8H6LVNo0s8sg5SDAq6F1xZi92Xpi3rrZG1Oeu6BUs+RYcusmTEwwHiFLTXAYiSTX6qe/LmIEuw+IC3bUxJqsHEEH3A1djtaX7/30X/T7rhcgF0g4KJZwd4b0o5dbxiLga+oTiyj+XVgwHtjeQ2EFKOhqyn3gCPAefF/DNT2LJAKC9zK4UF0Ulir+QJ7wqNedLXVLnBqDoPyiwrc1jCP6D6o8BYasHCaAvHCSlV6RQl8P7vOqYAZ1AI1sm/TY9FAGemx8jhoIMPAfBDEZOa1NcRZi3fsdJBuiNyZaHrxfgOZ9n6dTr9ZILXnihFtBTic0RhUKgmxD+QOW1/uJf9xWx69o8HKA3CTFH8bAzfUkfalmRpCOk951b2+QecpZlt/1Psx9g5AicjHMXoNGwpuZ+WHsiPG11WCd9E/HJGC1bxl6boZO0FDnFD7fZ6A+cZ3oeUYh/ZDy1yww+5sYWXQykhRr8e6N4GkO48pyDdza47xUiJ4sVNEe2aGlez1SYlTplVQ02BGLD1UEkfEsNKijRPHLISkhuoCdHzwE4orDvXAJosluExInqTBAEeYxgaSoWLeFLQF3EQSdxio+MP55eKmgy7CmrykVV4iDIqXkKky/tcoSuBlgoEJkyLHneTDS3Ii+IBwdMTX6sYVaoM/2enk30BHQ5n54cPSdvZ7VvmjuitmWaxgEPtpf6xhIqDaCnZR6PK5z0J7aeuD3mGLIzy0Uxy5LIcdxsmZjdnZ15EWR5MMVXqJyM3MEkbyDGmjtzb3/9Ovv36IffTj2/1+XxU/PeuFpq6PBBMGDBqGnrVh1kfV4OYG+cXJ41t143EEfDPSCKi7aQVI2uE0/qxMQQt0MVPWweH3dKkac8WeGsUqWRyJMlnGQrfviSOoH+WJwuKs/wVnpIGGI756aq4ggbSwHTLShEfuuL5cSQB/yGqkqZWU92F1fvzuUrXQ6mkIjgiIgPglMT2SFriUEsky5PK5gopGDtZaBqwL6xmWQJFxmAY1lU+ZdIvT33cyei11nTNyQZiyeMp16H3IZHot8vw4546F6wRoOKj/u1WVivOzFm0phAWthtLO7gxgKVFiEeM3bHFQxJV/cdXg+XzoXfPYaa18PJ0Sk6P1xcnF0gcO/J+5/O/ob/end8dXFyeBlcHB8c/UNGIEKrgRfaSMZMQjCFBO4A+3Y6ZZDW3qZJJtHoe5w73au7XCg6eZjtRPF4jMznbCGdKdyj7UylnanRYljO2ahttXZHCYuX1g+1JcZZ90TrDdLbKfBeF4nt0fIVLhSR50E/rWng2YmKOIqR7MUJ+t4DnmefHvdBS2gLhiWBLSuyM0GaSwGvLZxiSgcvNTfFTdFqLvmo1yAQp7fZjXwWuOfayiYesLaNqTY9rbg11rx9lSPSPUcrqz/mSIsyg4DJ+1OE1R+Tonsx3Dbvtcc88HStrjgqiHAFJenUuIdFXcx3MgETvtHWd48WvD2c3t2XLg+qnaXaZqutdBd3r7GExsC9TN51Rfbw+jidHvZMI5SX84Vf3EFhTwqmcuU9jqz2wctjxzwETb999owP4R/DZVaV1RgT+j6Dqd1zHNp9tNeG9066YT7iBWahD5pLS4aHwo6y8ls81sbuJRiv5m9tPtlyw8ITG+zIHpK/uj0knB5WY1NRlnXRnCmm6Jf8FxAWXpQBvJis6PaQgNPId7JOgGxHvvzfCXHj748MSY82UuUiCqkeigxsPvC/cwGJvf+dxTItW3N9GhSBhGdyePW1Rl+oumbvSzYb3AixCDiuLpQOYng+9aXOxGcwO/DVMESumXYuMEu1hAMcSAA36wFem3TZDPi7mJQtI2+Gy750o2V3LBiAlzsd+o79iqMWKS7Y6ODw6uSnY8KCOXkv/xqyDwXydXjZg1ckTPNHZjlYKNBTTemuE6VzKGNR1JXkP8k+TSE9AraYfK6uuwTbDqzKmifDjZZWUFIhPXJNOFABSXzwvinYlRuxVGbkoCtzboOuL59LVb6AiN3GnH0U41mW3RQwO6rLg/MT/9aUbLZPCINXU1WUj9eeDWvM5olWLbJw82hbBPcXTBwE2egX4OE+WaGvn7vXiavLMiodYsBZzLGOrrZ+7q9pkdzdWdtUurad9KsYSTF/y/SkF8qsSKMgm0wK4XHcsESX5ztKf+hTercJxdrRcl/40hoBA5t2Syq0Ru+dl/Xfs5xX0NZMi4TJMZUCWX8nRpta6+Wr/X2+6yVrQERrShrz0vaidW7F7njA6KxkONaF2CN6pEPylJheceGROr+uyCkxp+3XWm8QGCMQWUcGODmynqnkayY9ft3DfO6fy3YNfrV9d0WLTQNvHJYyHr/pqYQvjbLE2iSj7tPsDzZS2RJAiPhUZT2jQGePK25G7x6TFX7xK9G769wp6bg47ZNszmr7MUaUC/TpkF7s7syoL+wuTqPszrO8EI80A4/o0EIap0mTdeKC/SvNyoCSRw9U5owgS58qMU3KoxD2ifIsT9nuzg4izQzZEcnJBW00wrJFXxbCQk6zO5TYdYXV4IuaAA8T+/6QPX/+/A2zQg8pbwv88DOoNeBDlksFwNhNiC4zFoBKHLJ3VYF/qcfjCg6JOyQzNWyRVIVvHGvg+b/c3t3Z3tm92t19u6Px/E0X9xqwpG7VWO1BlVYqQmhnyN7xpTURC170PzXeAe680QNsSjYm/PK0F47FGoHoEmfe7P8VOJP3vVZOjjCFIl0fdHWgBwWlLK1T4WV53XHYR/RVgwU4Y4KRglaookNbzfXQTZW3wF83A7FdW2N9Gt0Qc78t3jNV587FK0H453xhdmKWE7AJBnNCHNqJZ60QtjROV24DnRvIJp9qrpwrsAvcp3ltT+hqHAPsTERiI4gzFagzsERnQaXC2pfN6hGB2yAzIexdFqdhUkUKPnwk/wysDkeYmS2v7p901AmyEfkxNEvicpcw4Eg1UjDwJLd7iHSwggF8W6A7QcOs34sZVIUO7qoJVgXknYwM+Hj3CJossAxn0tRx0RcL0QJEX+EhN9hq22bHtKPwjb+kh3+ggcxOkM9P5nxAvtaxVWogAkMDgqB+UWgd6m9rgv6Kh9H/7VRMCGNHGg6HZF37gIvmPF94Pqr2wFh7uUxDpxNjsrF+lCYmFMwaXvSrt7ScPu+WbYscaEw7+MGoo77eUwRkhSvePnsmmxsWcSmejfee8/3xONoOX413tl+EItrmb8Te9qvXXLx6/frN6zevPDFt5kx7NKiwlTkZAzMZtj0s6kHqZSMffEytyt7XvdzJOtODVekuuiys58fHF8HhxfEBZZXGP/96diITTuOfp8cHP8Gfn1ZrkR1d9oJVeVcHU+El2dWUEqZS2Hgv7h7yjke5MI1aqDD9VFbRwllhI4J+3rNpcwHBE6MOMqqpSfiYauWF67qKhD/DhVr0Hy7OPpwHhwenp1uDrY/H3528P7gApIYPRydnwcXZ2butAXotXV5dHB/AH4c/HlxteZHn5EtIL/iiB0x1kckoxl7dYWHda3OGPLuovet+9u7Wo73mfe3jaZbweWQCRzbqxh9X3bi/YW6jXrTf3Y+lLACRuVAxpus0ckG14Ixnvle/R1I1XDa5cs/84TQTM9P+qxlROi0oA1rM1VJe74TZXmLeWUmzLUyP9Rv6u6zcMfAjcRv7EkMdsLmIYs4i/M6ehHwucj5g8zjMs8UsS8UAX60Xgt+IvEckBzW04kKmQt6tCklamlX/FqcRVKaK5C4hVQZyryd/SwWF1R40kPCxDzLsx2rOUxNvh6VWErtqtqUK59M9AKJLKFMRnGpI9aOjlqjHAvgmp7AovDfAprkaVCPypnQ9kk2ikjwWsMze0MEHsURnq32RUfC3fcmp0q9PUAfghRHdnHWXDGyt5W/VOXX3IqqrmlGVK0nEZadGT12PH3lsJCboVRUcsr+JZcFuwSNlocTUv8BTRyUj3xY5ZPoE/4Yi5AnPC/aEJmAgE5YOmLTYIKMAadnLJfzxuf9tJAQzEcX1s9v0OmhiWHzqZ+JoV0l7bRDtHENrqKL719oj71qXyhJrKIcSbkMdIOiRbHpwBeCRgeQrAW3pRwHcbeF5XxDdN7uDC93elN1UyhpNGcVqzcoT3SgjAPfQj8eBogWfCl8uyS+DrTsxniZBUS1qQCHGGFlTA2GAFmgIj/M+OhhaMcDrUKMkPcYaeKCbvmggr1+mty+IYUA3f78c0ovKD2EYF8E8G8dOImDL2SzzA8NkRcfG+OLYjh9vxxsNIF4EVgzy6tHzYu1CljKq84s3PinO1/iQZ1Xp/6KMS545C12QOQvuBbyecv+3eHH7wr9E+dRPms4z6WXG8BrcQl+Kfndr8BfigjIo0tsjSo8dJfBchb4uG/up9s6BKbmB3JWAVbmYJOIzFFVX/627EI4fM1g/VpcrokUXrc1ngi7QvsEWOKSs7PVL/VLCyzDL5q5Vs6msRjdB60aGj501u+4HhZkrL8I+96BPuXmYFLoCENE3aVL7+oXvbzoLv2Sf7dLS3416XHsgQO1Vas8+rMd7iEkKcfUxxurBE4ZRuh0FoeNhfP+2XbhJ6kThYT7aaFwQ1S+Njh4ymjboTzgEYS5EWsx4LoJfbJ3aO/1Ka9bs8BdYv/ZOf4G1JDbzmGv5k0RD71hLt9N7jrLZz6pRPuZaYu/da+l2+pBRdqzlL7Z+v8ia/WLr9AusTfM6dXGEfe9lBtNHBSqRZ+atwHSvYJBY6GZ6+L3640IGW4v9Hf/vr/b9v7/xlW+MMEtslM02mtIsXc4zRwG1ZGX1Ujr2KzizOBLBbebKQlb1Fc93QGGPp5CMQsw8RsS0uIMHR/m93U5aNz20AfQDLJfH2AVIg5JmbnfpM5rVZ2MFLS2grS0yfyuyx6emqFyP0YGhSXV1S5HpqQbPL5BK2PfA+3f5hfHixsRVeJdRzkTUNRNe+2BtdJoYsw0awWn4FtjL4tQrtNwKoJdR7SRSm1Tx1pSYAHAZua/l70TcCic3bmP8JqBKl1GZqL9YHn//8vmWQMYb+3rTe7qmEsicUuZpnioxrFWopC8Yp0mhtfTQQkAd0v+7cUygc+LZNHTPvHg6pqLUJVjTb+Mihhce2E/SstvjRa24KTOPQbrZH2FOqV6tzmQb6mXJO0Btdes7Kqt9qtzefG2by74GemwEtRnFHnM4aXhuGiF5LIZMTN8yvATVFuyn4jV7kflmVMuoPlIeIdlwjxAPdGUNZvF0ZgPT195hsBD7MZ7OmFRqZT/QI8IuqkhkP64adSLTC7U1f4mfezVZkxm9M9OceWza9uZwjtjKqZrkfC4C/wx9D98YBiTXjq5v1/6nzTCgJrfWBuvwgpsB872dQpDif+h/JvhTNYuaCeTNfrMG80kJdvedRqz8mPNnpwX7lpr3wAJoJACMpm2dU+ek1Vu/98QOtop4XiUh96HfyQ2tS7TM2D2wZlsWsFZKzZh9RD5J0JsWx8wryyfT5KNrm5s1XS89BCpCfHdU26WpuC0mmJ+IPN2WG2y5TWKYdEDdDjXGRd9YCL8bl8pN3uOVDPDrFiVAhUwhRwJKQy2ytix6x2NEa7MLt8FW1FwbQQ6gVphshelWfPw35GkgeyXdDTpYQSXUIY8PxyXSPym1eiKKy0ZyS3/RxIdAWitD7gbt34tFVibxdOZ7A5U4/6sXcJHHt25WljbplCgSUuttIcnNP2F9RXhe/yel1HjeJBysa9X+wKFloDQH6gHO+6IaJ3HYb0iFF3TjkKcUFaHSL4NPDwVsJ96tpofX0g5CLFu5nNtnoaUBRJPvaKB9smrTUyso52qgNwJlQcTXIhEFWhjpNZk8AQSKztr1DXMXl+HsPlXKDA4oRFPMGwBWXbPSSuMqglb0/sng8zqcQ8uwzdH4ihv23zIkfzUtyDSLz+IoEqldeg2WGxvNocwoA0HRmv2BPAKkl1Tup+YmDm/qtDRLdaoXNi++pwZBUvw6DcHaSwOg/5TKj+Th2IWKdHp69hHDdd6fXQXmr8OD98HF8d8/HF9eNU+p3funVUrApfn4dYboyOg1MfXrjLdFTicZ96uM8RcYVov0qjZQXYpdxI1D3Dw4i6Saxj5T5Dl+WHuuwiQrWmYKPzHZobGa8ATso0vIp+BJpWBLSmFLzgNoHArItqU5obWtFpg6vDkRik7NibeBtRHlyJpH06lA5TzLTBNnU9gcue4elzdLfDllwEq+/qqhVbxl2Shih7prm1NQVPzVERZ0ReWsrW/4Ahaotvq+eaShWC1bFH7S6IAi76HgmXzNEAXScbgvjg/PLo6OLxx1Dv98f/ZewtjNsjvnBk5cIAnbnweVI17HZLonS1HttQdjW7hyOAvdRbU+Bs4+/jn8qJStLJszqb62DeLybyfnW4Ots/fB+cXJTyenxz8cHwUfLo8vguP3Vxf/2BpgieDsfXBweHh87mGSbXriSn2uTQmra0v1PdMlt/UR0rokMo/A0+TkjrrX0A99S2QYvVdYV9xECVJSGfTKgm1buZcqDNuxilcrB5GADO+UzKiHLjGm1cl5FFedRwaWYLGFLpMy2l98LnO+bf4O4zysEk7piWS7d3FUzrqaTcGPcbAFQKqgOUnAwTBLsj6ewwA/P0UKVpd9ubPTJOTLYOtVy++vW35/0/L77o73Q+3IARXUJ/VA7cnaOHE57zOa5y1UvGj5fb/l9/VmpTaY50j6C/zvPv7XDA+VNNjRfo/SJnCe5UbpWincD4DeWZ+juqPq2O9Se8fz1FX1WsZF7Q/s7aUHo7V8l5iBheiniTBdwmxMMkCL5PM48b+gT7NsmogAinm/J9k08x0lBzIC3SI5urdDviGrvLFqq7dGRH2cCd/zsjmgEeSzQiYF/0JUDuDsjbvEZSQ1BlAjSnWrD3qjNZeLNT6ry0YJd67UVsUO+BqZX70vxQBJdVKKefMivrDyn/0gSnaQJIzqFIy8xh8H6oLMABTC6oJ4fyV87hZr9P2wC1st233Bb93B25Gx98fxcxdeL7F3AzjKRZsm5z6y3oglbQupM334cHK0TmRXV0bGpsW/QBgQeIPtOqTffzg9RSnv8nJrsPXTyfHH4Oz9KaXImfE0SkRB3uVZmqzhlO5D9+7xUEFBVZ1pdU+kC43yHZ3EiJdNuAcD/Ab4OfCqpRpSYYCUNsooGBYU5Nr4lr7EX2ukAzZENNIBPzYpnZmDa+F3TvpgibB4zwQbHqrAuh0U8c++N9YY3yR/bqqBmFUDc8X74NdX9tnN0nQvK7mar+meGWVMWL9ZdSudTM/5BRc2TKIY4DT6WSxOY2rxWYOQ5eO1BrS/HY/jChONGMpLF2jfatdyO+qHIqNzEtjgNc7xnGRelJ360qzcBX3T4fiWioclpYHTSXEQNJTSt6k1ZB8KKsTZRNypyZFFR/ZOGT0khY4/hcChxOisJ41tXXoruaXOkEbmFAKl+nB+enbg/BuLmMRq5wcfLo+PpKGjX16ftlMg6w/Z2YLutr9YGTsZ3DqGPZmakJ5BL8wYDd2ynXvOrs9tsJYO3cdUB747y+Z0zlnwHGErYdoaWXUsIdVcr233bpuMogswx5VGZWEAPFiDD6Kg8AiXE90SYaPRBVywkt+IgoGnlshh8SYiF2koWAYJHg8WC1lDFZepYy8kuX+LS/B0EwkIAwzCk3gyvG4mDG6NLlrTPKxiRqQjhl6NACiPP3ueoqII8dDxs0KZGItpnCLakTxxk/W4r5Wz5n55U1ryBqGDSlvuKJMYBjmwdEV0cq5ZHNjKpwJpg+E3hGvmTKqCMNKXO5rfIbizajSbsL0XbJZVuffq1i5Sr1++aKZLscc5rhCabP0Jsv79HbZhJZgpM/C/v0ejl1TTNKXDKNZsSEVOqNeJxon2p4KSCbDOva9MvTTKOn9sAiDOeewRYY/h5zri3CqkpH64da6xs9HIaoWyLzmtIPgHKPMiNgyKOevi4TdU1xWzvFYmFbM5PKtf3x/O/uzlHFYU/jyoB5SDHfKgqmmmxhHjqJoPmVUiLjAjkRqUjhcdTcNi5FTk+D4xvE6v0/cZAtNxCRI5iUUSmZYkeJAGsysGUiDI41LUYG30PONHM9H+ZKuAdw9B57PMn83HBsOnYuY+vN4qJuXieouwIt0ZuW6Gcxhh62/H/0DZ6fLy49kFSU/E2lZsbaeHbwtGlbxbcJZ5Mx5f/ggO62Wc0ohk4mUojCO6/P7q3Dca7wHiRXEnXd569aIqdPZEMp61KrAJrvVcXW8N2cmk+f1vx/+43hrQ3imcm83pFWexmDHpPgXb9d47Z8HpWaKOXl7OGGAHYPSDEhBwneBFrjSIfa4ci9C+Y3ih56EX7wZeibwJ3lomO8v7LqkVCkbT4ucB52bO6AiUGUsyMF+VmUMBUCSp6CJg0FxqbNas531XxuBe1OXcKXqIezmY77hq5OSq2Ba8KLd3SacNc99RvcTfu5jkZTyPE57DhI0Mux0NWIy+Wy5Lc7idzQbvvWO739wdxtylKvI7UFL4z1VOr7HTuORJFpJn+DSEj8AX6bmxgNTPvju7Zd+qCmuyoy8+3d8KV6NnWMlk7VvUuSNtjCz3clRTp+YAhukFAa+ZQAf1htxbdh6npyKdAiPZdTZu7UO9+44l8FJVf7GXFOgem5F7X4lw2hj3IdG9qq2dJe86yR8bI2lf09rVb1/OKym0OWWfyfN3ZSSAlf2py7bZ2acv9RDGS5m0EQ9Wm9J/KYOQD2v+Wi3SoYxZbvE5ORKTOJUXblEuTTpFWW3AigoScBbKLXvASghylMYEAsLkCcCR8yTxMR8dcbJlHLv1YTSu3hBmaSJDsMkAmgSZGnlpEM5EeBOgqwDYKXN0TYKXyThZgu9XGlXgo5ClmOQR/se0Bxg3dOQAxSjIhfZrwpdcZV5qzk4Jj4tqgtA5nMq2TtMi4XCxYqhwzuY8vwHDUvfEqFLWzGAzgXxt1t+BYNhMQQIAhL6LrHStAiZAEappqGVttiXqPRZgi7z9HTsvKvgq2M/I+zu24uvbwLU9fpXz8IY+nfKl4yHQFtm12rhjGW6MhQcyky3xOkKnfCsTHFpAUORMkASPzIaXaeBHXiX/aPgG3ZAoOGQ4MPtZiGy6YHYmDL1CPl+BtNC9IZRTlL418O9P9kxjbziBrdOssmCsnGCpeZ/43SqMk9uKdz33fcxUaz6QeVEm/d10vn21PHuhSE5vX16Bw8nFqMfePtKVxNX5uJl8yawfugbyoB7Jvj+snn4rja+dw7bXUjR7O+5ahGzC6LvJUCZSCLJlqSBtQ68OZoEqbvFA+qBB29fGMwMdhH5yDkptLVoXq+PSdQrVrO0rr+AbsUT222KV1gi0cNmgBTaeL/IMYvABRRVUt0iUEv5UYeLa9HSBCzRnOOHptOJTn2Tv6N+qHIMrk5RwZxLKjIm0AOOaJjMXBWSeQ00/m8dlqd7zdVsxMMEy26YBSXPMIivKbXUnPfk4i4uFyJ+2jrGh14h0+8Ml/r198h4ZKfpgwga5BTm0QkdOKIAvO/jqnJA3eJ5NeBqXS3jPKeky8gfBwygw31YhNdFsMgE97dYeXOrS3DcEt7lVW29PwoXbQF1soC5+V1AXGyiLDZTFbxzKYgNT8ZuBqfjyRS7Hr4gnsYGA2EBA/HkgIP6saA6E6f6HgWHYYCNssBEeDxvhDwmA8HtGOSA+vcEn8DPK3wA+wQZfQN9DG7wAn7jyu8IL2ASd/z6Dzn/zgeS/q+jwP2DwNgkS6tXBeVKoPTf8xBPIawaPcEVReX2uizidJkKZByBNoqzBJjxOqrxHfk54YPJZnsNZnAqTgdRqWuR5luPDlNfhEp2Qu60y5KeM4grQKSKreX+sRxa2xNeBJ7e5y2ga+jZseXxwjJX/TyUwKGmcRUsJAY3qa7PbWn5W66MipnMtWt5c9TDVLJLLzJYhpP7YbQdB9HiRikToM7FGImRVgQ61HU62lIXMGyJmvCd+3Hv5wppY+edP56/xv29wAOIzeGRgFFfra0EBD9mkk2aMKsgnFjRMFGKB7iTJsikCWeTI16uZUPaj2iri701RiDoCUT3+LGwpy3joaC/XV3s7Vof4l/HXebO3U+McdxwemoEneEQK+UlGkGHmXOUM7Qm1bTN1ZUXcclbkFzVgQ0vXilJe9Gxhrar1U44zSP/Gn8dZWWZz/UX+SeZqX+jypRW17CGoZZD9VlS3h2v52beO7uIo+aW2MPDz/dpEOa7NYaTZ4hzO+Ir4dWyzD6X328+7e6/tDU1/tu9o6y5zArL8bMrKoNPcnSLfLiiDdpyOQcpjT1Rynaf6eVXlU1t9sWHQu7LlRs0rnTRPyt3TkgFkEudBe6ISek0yO7GlQF0orn0vgkggX+0skmP0aleRhchl2KK31L/BISTv+BSMq8kEc/olfNmjnCAXk475uRHLoMcQ5y2TP8+KwHpSa9RbcHBLL4IkK/z9qwKdWwC03rbl18mQWr4XRR56G+1MqLjyaBw6qZdqIt90mosp+lH2OCQmeoecuVYfGtqy7l7qn0bRTefUPAEPaCkGEbiHjpjwKWy6UN2AjbVJM+lL0llqkWV5kIsiSzD5VFfhL+1HqHckMi9FGi7dzF/N47OCZNzucByKteYaq51mRS3xmDx6wTxbr7n60nn3u5t+rOsqyKpSbnN1Gu9/FxSijZP/Inxeys9fh4lbu6Wrn6/ObFvneJHEHXO8itWq3Yi+96gjacyVXoajNGpfnnBRtXCK1GMJACAZ0EtaOIGH0FzwIvMkADbyNFAwsKgcKEMZ9fSprV3Nnugpv/BSm5f+KX+826st4V/X7dXnXP+Bri/0XEth7IBaMREiAmNmN0Pve+XpfRN4NklnD+GiWrvOo9+f3r294r5tcrvf5d2oD+cDBIX6ifwoxrMsu+lhDeoFk2hwh+6oYRsssS9YkAkJ3tvZ29ve2d/ee3218+rtzu7b/efDnVf7//TCaJgnmkakFZpF8kqwWOrQkri4kH7Ffg/PW5jZZoPH+HttmGD1QkcWmWkcuFGHd7Xi5QrpR+IPoe2OfhHy5UT9bb2U/TWL07Zvp2JSWl/A3+lymYYi0iDPsruyKmTm8oHlVO75qJoyL2LWjzKswxNcaa3jH2iYKzFW5IbogaNmtvlOtDvZefkm2n7xfDzefvH6Dd/m0etw+5UYv9nff7M35q+9CKKrHRrbqTG9A2QqbXVdvDcyqP+8rwkNer/z3monsw+4OZZyhKXPt6MG+GjomZXlonj77JlsbljEpXg23nvO98fjaDt8Nd7ZfhGKaJu/EXvbr15z8er16zev37wSHXlfiXLNXdpxaAxLq5vxJdMmPnRJb3AXolhkadHDZzHiJbdK/QlZk/fl0rwH6PX3QQcZ+Gicx5aluaC3pdWL0XlrqTcN8qBzNnYxy6oksgJj8CQ2Ltr2R46Vl5tCCXKO0hTu0jyeTkWO4LqbG+6PeMN91XulnW17xalfmW/7WHbLmb83I+4rzn80s/iV2VcBaNyPfrGsPc6vOFAeonUpiCNQsSaxL570aobxslCOmXKs5H6QVyPO7T0Xuzv7kxciFJPXPHoT8ue7/PXzV3vRTvh8/zmFAikEl+d7EMECfsClE0PpULtYeNF9kcLFYi3qdl/w529eilfbIX/xYvvFm+evtseT3cn2zv4Of/lmd/f1/ovn9Qe5NmjH+19vjXd7zdIK9EmtFhTzDpqbBVxq8NggbrkgzQ6DcwdsZIf7jwZs1ASLHdVKSVCAEbvL0m9LuE0t4IksZ9wLKtqWnEmLa+aRswMT055fvDQu6oa/VnfTJOmDxbGaiwO8D7ubZRpseTWSsd5G1qIEJYg67dhXgDABPqQqkjdFjFqcXqAAl7JUheKCjeDXEUajp4TXhciG8GtwEo0YTyM2gtGNcKt0ocorIeTs4oeD9yf/PLg6OYOoc/Cm1NBZwUnLycLpsTIyiLzI0vXmq13ni17uTl6+2X+5LV6+nmy/eP5qH47hznb4/DV/tfMi2h2LUJtrCp9/hoEAiOsv+AT1TDSSpw58v966RO9qzjTo6fXWwfkJLIUpteBgKQMkbfLhBUfTy6uDiyuFSHO9dUgOzVzF811vsYPzkyEDjMmTOi0xxBbFZczrxNSav94yXQ/M9oxEyWPgEyARgBQM+H3ZAgxa3Ut+cH6i4ghrPbnoLPbZaxzLbPGrnkp8xt+cyt6nsud8/TKnksjgRN2ydio6ANQ9G/jk/dXxxfuD0wBB4SEe9vQ0OD8+vrgMTo+/b2xovWslalxR5jzf5ot4u+BpNM4+B/DvXAp222E2n/fZ4ujJ2UOS83WoI/uMm+QjtEQgJltv/+tKim3RagLYFKKfEYekGpMq8YJ/OOKlXhb4o5HnyAibco6sQWoqP62zGtvSC3SdVTHaqPLTfbWz89xyS916n1FSJP1U9uHiZOvLJ3TROiExfXfwiKtrKPr00Gb1UjemQy4MgJD4sEi+3r4guVP1j3899s4Iq7ygp7EqKYM4nXiC4c7zDJ7YCkaFt8ElPWILPlWon3NRclCChgzUOibSCIG3C2ClqHZfp6oIbgxqx2phyM55QQxtRB9H4LBcCUDR4wz9oK9TIzhIQSGFkF7tZZ2xiSiltzB+WfCpGLKDlIn5ooSEH8D/rtM4jQALWjJQMAEgBIKmpUemgha4mfcaFwVVUkWmBH+TiEigVHhB9vSy7wF6A01Ds4+zBf9PJdQUIqAdjFpJPdbA5ZRCyKyaynImrlM9wzitzJlVzopqXMCMpnpmHziFHiFCLP+6c/LvLH7374Pl+8udu/fxzuf3P/3987t/Z3fvjrK7d4cv7t4dHdy9O/qOn8R38Tg+eXky/+vyH//7z9vT+X4SHf71jcRMCBZef/gmUg2tCCakgNlZtQD1tLi0GlaXA7kJ2o9WlM0Bt5GgKnNjr63DGdP2BR9/OhxQHpaT6jN+y+OEj+N+yDRUyYvUVKAf8qSCHCv4YjyJRaR6AbmqYE++//vR++IpnCUkg3RUmwB2zMOZqjSvipKAsCICmhOfS8DBwh2wzd6RW+5btisr0K+0NG/Z3o78mZZF7TYoc4WiDN1XUtArdOEsZVUqYRRFZPoEEb6csZFajXEi3pLqTrIjh08gtYwo4KPZ05wvEaqMzXkCIlxjesRwOhzIPzB6ExIKpYaEp87OX4W/5ph35T+HITqrq79SAjqe88/y9pTuzuoubaRLlMvfe1f2Nb39hkUzj+GHU/ixcPau3NIKl+7+R+kA1hXOkueEGti7C/oHHiFrv16n1oYNidY+e/Y6pU271o7t3o7rz39988ACfOnag795mbmHiOQbtAcdGP4aCxBXZBQcwEVnOXoQ3YqOvaIQaAU7xA2qxKeh/FvuKJaLCUAXW+IEUruUicL+IqUtMWfxHAErIBxJwXCqoZW9/Nb8NgTYeR3XB90eTzGuo0qXCikSAJLhDCBOM8kHPIl/bvDWE7h5uo0PNo+kRAehDNRcfyvLyoE9MVsdavfBYiF4XlgpzOxDO0IDhnVwxWdEbVZKOqwg3jcjffqDNCsDzRaC25iDmjZ6yw6TrIomCdg4LhTpBjYYBTrdiBIxI17MxhnPIzauSgttWHzGy7mA3AS4zRZ5Ns35fM7LOHQ2BStneVZNZ9QBWtu0MQQsOFRW5Ow25myk3r+g32GoCYaVefZf8/Tx5ZlkBs/sropR51S0TYEeS20K4GUiF8my3ijg0iRJdlc4azx6i+PSxb4tzEEqxXyR5TyPkyXYqQCigac0kZNciJ9FwVJx50wbMnpJYWFNfMhTyvYgZ80SXlzyiWrJYxa5mMfVXNIoz0fI8xzMPfIjkztX5m5D5tlEl0YMdNgPDrEEN233WKWSIyVi9BYF/c/g7IoYX6biALawyG/lH1lO0Dtm5nJ4FI4JlXaOyeNKMwCrD0K79Ahv3Qe/SayN+Np9oggrwFfC+eLfLZgn0F4a84NNjH15jH1RpCdaYWo/gCKJp7G8GeAIyQSdGT4S8QSdmcyM43VESwm3n7tlwO1QTzklgbPYvytCSPldat9yc40Y3QzUAfG1t+zAWedFLp/O3cYvBekCrrBNGXzJ1D5kl9lcAwRbcPlyg8uzMkDppijBLq+UjFEZi3y0WjJAa2Xbk6scI4MSJiWiVFHYQY2xk/KcTeQ8M57c8WVhT5vKdDWQ4crSEwbRm0fqII6wpznkaJLj6+pK3iRavIvlSujW3rLL2glfasaAJQ0rOXemlZQkndqRZkJLIKqt7uOoqLABOsxP6qS0JWu3D8pKqcsviWiLFO8hkAzkWikTiT7z16lU6EaWYAEvuPMlQkcM+WIxejq0DxY2W6XxfyqQrfSreHGd8toxsK4whPoppeiQpa4whrovtQ4b/gbtK2WtR85SXlY5T6DL+SJDr2vMUVQ/3BqacaUNxtE3/f4BHetSCJ6Hsz++AknjfASlEewvismwoppOIWsSXMkxrFkibjkmWAXcGsvghjobs81tvLTpCiFjVB5Dls4ynImI/SzyTDOYr6H7mYX/Myl/7qj7aH+NlTZM9pLWzuh5l84mQz0uzdLtmgIJ1nNcf7gVQrhBZfLWkIczATmrBTs/u7xiUujeJnsH2PLAJySfW2KEo4aCvqJugo26+Ourizy6jYsMFHt7X7QuMNpona1CBoHfm775B9IJf0s6ndUrl5vSKvCn0bt89jdHy0KpqowxBX1R8kQMPExYnkh87GzRvdQkmynuwZl9bNdRvWpXBMHyWApfStqjR93zGHZARTPqmaWYfUW96jrtp1jB4+IjaFbX6W9WtVohmP8SypU+ftsgEHpiNGxGmi9pYPoJHy6sv16evWeXeGWyKAurOVoCGnsPimI0wAReYREjq5YLp0WkUJ110abdDh4ooJA4It29jEWKfZ/BBYPrMmDXW2E2rG4gPzEmjYZ/erHhSh/aHHR1dXq0qhPKR607ooSysi8sSf+ufVmJ4yb3BlBm7wmMbCaxp0mxs8Ak3hoFekH5muJ0UZXgFFBRYvXG8psV9xg+G6umQFEBs+SxyfJswl4k1WZSb0v/LDYH0OcMWp5ZSSLqUeO/Q3368ZTOGqP68ktrlWpULZ5Rh6scon4NT6LVzkMIz6td9CyXoWPLy4e0ljRjc5BM4Hvh5XftTjj1QXQ433xpGBIe6NfmOV2kmP++T9bDT9DvwCzTvqpdwVQn+ttjB081IsNXrFgHB/Rj3TY80Qyg4c7Ojov72jh/RVblvpwDpxK8VckccYoQsFISlpnvqkK6s+NyrGZXaLDyzT7ey+f0VWGEqh5BOpfOUhYycNUDgFZ119hHdRjaJt1kpJd+Uiok2XgLt66iMvQo3OW2h4c0rXiipXy4HsB0hXY+DHGgFIJa+bmSZ0o5s3FKAbC9FJx0BWizkKwX9ZsFPbkCmG8Yz7EvEcbyyRjVm1Tc8SQIs6KUwRGOSEK/ZzmoV1ImkUVBJMrJx1MGWRQgAOOaDK5TsOiAdhTFgB7HIrwwtKUiV9gjLBQ5Oi8ppQuo+h7HPq+SMqahGXGLQm7039+C91NRYmJmDGbIJBRzXpQMql6nckzOME1pAY6Ilrcq1KG3GhyI8ZexLs7r1LxY81IotRL8GwiyimW3sH/juejlBoythp4UayeXZ9sv9nZfMVXESpwqNWXjT3i99eHyCKT6663jDxf0jx++O7/eWmHf/HB5RLeDmSHPjlWbTBajWW++euLERnpiscpYLLM0oucoszDAUJw1dj0FeGpaoVNynWKaV0UA3DGCT0p46Hhn9hkqyp4tPLhOBWbFRcsM5o1z34llomOKAUtqCsikFOl1Cg0VJMiUM3RmQVJWPpK9Hu6/ajAlveq1qV/NUxwL14a3bHjLhrf82XlLzY7gn+crNUc0JzjLZWacy+zZfjx+Nuj40iS6nft1c70DZTyteTGQWMtygbwqLZWVR6nA8MYlaLuoedBvhKvlWNg0AY6pXQ2CMurdinZXBrnNC2Wsx9D++gtpu928C9/uI6FcaXM+KF1mVEN2TnOg0LBEy2Sh755HS+8Di7W/vbO7vbt/tbvzdgf+3wuJVXPKubcTATZAmRfiXBS95sT1laOK4HwJicXcBzETkaJin/5C77AuB1iINEJXN7wL9EWmf4Z7iq5UBjF/95vWl55pbUQQJll448OwsBVy49lHpR2rZq8NiDlHQ0CJ9GVYOZTn6uOPZyeXTJZlc/tmaXEK8PCZXEQS/dI8YmSTCW4p9UWmySorX9ZP18Wd1tx+1SZMKvfhja5/IcOAMGktvtk1H9W82+CtflaWh4ougDilN2xRFOrFr7ZR3rIjIkDbmGNPNdqxkUuyZ09H8jWqKhaI6yQrGGd/9cHaFWpU4Bsmx5THWa0vkRKLpJVURdk05yG6qMWZ7FqOC2DDRSka/YObUZU4/cs3xET0Cf7TeJhqY+gffMtim9TNT3KqtsCYJaeD9pY7ARivZw+maUiwGZLejzXIPItLDeybo3ak9DnudxVuzP7t7bteNr+60X/9AXjCqh/moebStO4O+3Oavuu+Wr9jw3dN3k5LHrZ5roYl04H2LeKTdDOyDAvXaQyjHVMSFaUwu1XRUXDAIiF5KsusyFf4dp0qsaEQJaayJhd+8oghRz/IKy5lDMIqKfoow3AXe1D9juFnyEsF12xDTEnJZU6GHpDjTS4Q1ge0tvm8SuNQiowNLw3baTy7S0VezOIFuxV5PJGVyIagVIM0K0Ht9l9+WkykcTi3YcT/b81PccI/N4f6Pf+sgtnjlB0Pd1++UN6Syon9f3aH+/r/wG/9bEHek8Pr9B2ojK6UHGWMIpRwk4Inve5i1RXu9IRvgDOZm6BmH4CfW8h+y0b/8198/cyXARgwvgz/SyW/jFCCy+ANf8HBlgHrx4sZyPvHRETxtj5e9uTD5VOYhRcvhns7r3b3nr/Yf/kKfv4b/vx6d/hc/vh6xJ78lS94usIG0hxmBo5hD7gWfMc4sFttPIDMKPGC2jh22fW4RSCPiW+VlkUc8oRBHxjR3nqgmGysx7u2zNxRY1DgdZfloMIgYj163nQvwkEF4WiUHctsFo+N5C7bTgTkI2GyIJnF4NH55PKMPd99+XJ7l/FkMePbe/rQfLiEgI8fvoP/Hh7Af4+ORyttY9Zm8FNzjh9hqP88OW/JTWk3+er1q53dLakR+bLSlWhSXICJOA0F+iDBsgAv/0Bhv8Y9lI/HubiNSasgAxbaNkMMB1Mjv/pfcpy7Ep95MWCjs/f091la8jzOVszB1f8StbkQnovoEn/XG8mw0nEVJ/CPZ0UVl4o1rICT3HvO3sE1dNl0x5H9D2i7qdlz16a2cdY8NbUj71vlZ+rc1A31aK6SBwaVKIleRgFxsYRjAeYBuokqSt5ooM+mQtrsdcAcEhij/VlxbVX9OiWgMk7ubPb9Bax9Lv2XE17IHuobY4Cu3ITWA0JQlIFrc1aCl6xYgLMJIMWUyhJJcUlphC3SXzguZBvaFk6TIUfW66q32NQj8VfVYivu8PfgA5iIKXc9AWV9ZyaTRE19RGUNafQ2k2Kwzm0cVXT8pfswxC9oUya6EvdZU+YsKb3Za+/YfqsKtkN8VpJDkg2rPYYmMhmxIj1tJ8YhkY0OIs5Os1uR8FCM/qJkBsRN9u0HSYq9HVZwd6t9TGWUT3ka/9xiKz6zvjLM+Ttf8FTeIlrckeEjehXM9bWCGClbsJM0bHOhVHtpPS7iu3Q1ppZPZvdF9OEb2BUBEm4buZsOBAqw1+noh+Mr9kzG3xduJL4m95kBIHn2X/3vLyPwro5TIdkSnXoRaQLzLEEB7BZAoxrRCXYst9rJFJoAgFPq/JulGJHIrbQtkRdDdkj/QJ1hIXctj6JYLisScJ2qaOFRKcIZSPAExRuBzwzOWQYgkmjTHcdJgqZcbTe3Yj/lxNnhz/MhQ6szNyqPHgpP0V0cBgqEDKx4lOsUnzRFDtZGcqyRc0bvTr7h42p+NOZ8covJME5UxFobpTgW04SKy2bAY70N01NosSxKMYdIMhlSRBvh20K50Ou7eZxlN9cpuXnzok3eYzZUNepDBP6E8QvTKlcwb7r18sEYEYPrlJhZORNLekYlVFjA00HEeRksZcYhvdUROIcuLdzKmmPzaS4EeKoP2ZEOYFK6qrWnFxbLpAAuvmRlBuuc8qmnz1jQE/VHqbfIFeTe2ZZUSvTn+lQPFM1NDoCJuws7hXiv+9Q6GD6PUHm6nHJm3Q8UGzCBbCvPUVzgEZGHydaqfccJJCA5civEyzpR8YpztHUf5EevQeXLYEuyjI6JkiX6T5Fk0fXAljWmSO+N6/Q3MEWm6Y5Z8vGQk4ka0MDPlK5TzzmJMSAWvPqLUvDosUejb5GOwegyf9ZF/9JT3EEGbWMdruBN4U2a3SUimiJX7hKTEIeoXl66QxWEiBxas288OWqsdJJkd0M32rP2ymjkKeLEplwUF2GG4o8K3bYQIPQ9jjfNjVi2aDta3Pzv1kTUXX3Q7ab2EDYRkAV9x7hgyB9gTYx0dG5NrHzv7fJxOE4JjSeHQeE/G94OQ3ZkR9vJsLlYn+HhdXpJV6cVqIdFKZwvLggaETSRuGTZotyG6EipDyHMhbWvEXGS51PRIq4s+BKWHCIrZhnkwIMaz3eu0wjAWKRHhnrpxJwL5CEDsbmWKVuPEhx+htfphTTfKl87DK2veWsxCu/ILEO4CQfsg9+rMyPh35TnHTVTI4h37HzV6bbe5kq6NDtTeqV5LOAP1QlsiJPGDidJC6J3RWTTgP5Z9ZhxKyLTCpkaGo4wbE6LBUN0nSrTrwEDGlbFCMJXKrn7wIw1rG5G9u2D6PLyq3T7G4Z8JPV96+uQnUE4KO5lKWQ32fq3RY2fSHah49BHnkGsZARSXaeX6ypfZOB6vnUOoQg4ugBCmKdZDhzicBfthJ0n31Y7690+zpWA1pTH9gbqdlC5FCUx2b4eKi7/0o4nEnwum0zAc4O4X+E2qv0pZA1wDSFUHf10JT8xraLYV78K2MfQYkaGHgv1U24WPQR6R5Itrnp7sV1rNGPp7XAD/oMeZqPn1tnbpcjndBHuwhTu7qCLZiHlF0uUA82P2L8doG0LON8CXi7GtDTAj+IsUutnXbZDhk9W1qwp89guUoHutYlgBRnR6FOSpVORX6eqKxiA9oQdDXk8MoLWHg3mKbEWjrH1krvjm2VSZEyAQTcESasApZfNJap0Y5Yw4FxpaXycKTuAqjAh2DOctyqVzs0Dij93Ls/rVIJ4qpl0toMHqnoXo5VUsJAdOdTl6dLTfEVq9mrs6jJTGjm3AAR9D89kw4KYWyVBeXAusC1oYWREmJGCuXiQa2cfsWeFWKMNugVrE1/QeNZPfmGt4st1ulp+YSvEl+v0YfKLSns2j1P7ltlt3T13WX4DEvY2OVL92R1Q1HQE0q/s9+2DokeDtTskVvxu8iqRRVXVBhCqcKbgJoEximhE3tykl+mCKJs9cQMAiM0MmCjD4VO8OKs0EnmytBBLlwbbMoK8BvM4lQ+kRoCmMJuIqfEP2UfVLVFPRezwAQ2qzH68ujqXxUY0k//6NIQKIyUEA0xVlm7vff6saQHUyyqfgLMlVRrKvkfqrkQVdyKNb+Jzn0d2r6D0jkM6CLEN3tvI48yIlDi/VN70MgmMTCO0yqmXpjfIxb8RaGHLjUx1qfixmvPUogEArlInIFX2TYEaSqZvajtNbBpvWiq99ESbbVYfNkMeauGjq/d8Eqc3XnnaXRHlit+cD8xAWnOrorLdI1upuTlW82c1X6JCJJMOWuJCelV/dWKcL9uKH9YZFFDbYzHa3MYvaSwQFJIyXizTGuSYaqDPyaKHUl8mdg0pdWex7Bp7A+R+Yj08UcztALy6w1AI8OrG4DmH++nwPRI0/qIdseF5C4GwyJ0cX7tQog/U3On3LnJAHqmwBWm06ZFkSCqN4rMvykvxdXO767NJOFgUm6ewrfBBJNSlQSlXHM2SQUc129l1qqewqJTS71mnbsXXibHpFa3RiHHRt1u9Zzds4z6adO0GhcgPxVYe0Bi10e47ZMApnY2axBMRLsNEyP1p+/5Lp39dlt9x0IEWeQYChAbCsnclgGGpryo15JCBR2qcVpBRkV5NRkjtEE76CJXjg1RBPSYsEjxK4LZOYnwIRWZZ5datIRmWMFEg9jGoUb3g+P6JCTjIfFwqhGroWe9KqeXXIKrLbKHEbQB3kfRXaRkn+rqGZhSrqFmAtTa/bc4lIGiXszgHrJi8XBrka+tW8IIQZtgTZ0lW2NDs+cCAcOtok+acjwUCPdApYwypkdFNRZao1O6YitEQJwWXqFDxKIpzvWVXNcZ2Zcfe6vmILMkVNTeccfltxASAgipmR+BWzuUxcJbI/jRSaVPs5Ap1xHpzoUkYPeS0q2inYkMPoUiNpBXh80iGI6kPmW9NqDMmKZSs0IIU57gAuBnBQ0/cGeC/Ml/WNTLPBWydOMvSYwJj3O+187E12JI7cUsqIoICZ2jYlBkTBeyHcNCGix655JkbtRZdY/Wo+GFDBPjF0kk+XIn8A6WP/N2mjXzkdJF/3jSRm/SQm/SQm/SQj5oecpMWcpMW8reTFvIXTAf5tUSrTfrHr53+8U+V9nGT7vGPlL9jk+Zxk+Zxk+Zxk+Zxk+Zxk+Zxk+bxt5PmcZPe8beV3vGXTOv4ayiCf/o0jn+u9I2btI0btW+TrnGTrnGTrvH3qj9t0jVu0jX+NlSkXy9do5JiTI4FaZP232FXCn7YtjBQYUIg63nBaJ5mcWuL2/7Fuk3Qv1NxPL00978U6k+FPqbcYLi6vuLOar4aV6phXqrI6C0z+SRNk+gmVXgzV9pkwfAIc330lr3P6poacCuJyV5D43RagahKPS/uJPEkR3xzTNZRuJ6C5tbjudOedjY8rXkLAgIVCQlyXNuLPJvF4xhMdOgUaEsi2t2ffjT42OoFomO+nkzsrJYKL9RMp0GLJj+8p+6EVGURR8Ls+7s4jbI7A7Qd05suOiToRsFFlVHJWv+5CIlMZaYVkdvhnH8OwFsbJp/c1Bxy77IqgYUEfzkXtkHF92EMoHSJRXiWAO4hBJyTt42ElIlQ9JOxGGhdyvJcG+AalQOSrMEmp6sRCMx3vBAvX7hYMDCgtChEGAiMc4M9cPT+8vL4kGHEHf42ZCclvdCPhYqCi9SFpvHksbGfs1TgHp9kVaq8a0uIcis1FlDCYeG5vWmhmne/Y3u0dwI5VNlovbY0qxtA9RRjMJ3cD+6UYdsQYiJbxGbgbzlfuinJhBE/oiaG2ZzKDVKkqBLH2k0QZ7g8q64I51w+kkTWELe6uJwpbziW+c3hP+ZnTW6NEVgV/efUFFDnCh1Ta1vb95vc7tCAs4+3BlvuXlQ/uJvJalJvB1sQNfPX/6q9r3tO6bmMH8FNR6U6GMv9mDEBohIva1lu/b02zEf+YArpT9gIq521gJ0SL9oWKXwmDvfs+PxcsislUNXesfHSulDe8lokvDo9KoYSxQFNBoQALIEHwcQCzV9jV6vQlsfL0s3H8Y/59z//8+ofO6cfv9+NfpiW/9h7c/PPv/+f/+MBM2giRK6whzi+USvWYZXRoyty25M02bgB7TbdgDqXeC0focbZ+IPZiH2L9ggW43d8UbhGMAi96+pL4hGQDqRjHQg8dmASkKCmNFDZ2UDMb4Ma8e+Be1iPm1vgz2BF9o+6n/4lEaps4/IQlV1aL3zCpZdGCQ77FmQSysNMdkhnudEQSWEoUO4sRTCDeaZDePXV0FZZhgT28GJuNw8To1M3T2EbDnogej+mfVdLONq26z2BtYDoltOH1buuS3/09cNPEerz3hjlJrv/YhLirLKhmfhUpTNzW8nVs1CX05WRTH1f5AIJK2L0bOAqpZEydtm70C0Lsrdjv6pxqNZwVL+1xBm4WfBPgy2eLs8mGGBSj8fWe+K3vKj2Hb7jWeHmdHVwPXWgas1Ar3FJ4O3W79JRtcENvgx+v3NpSUD959IfN9M2he+zdLvXNDZvlVpG9iZIjf0ski/JTKkDZOC6x2Tbl4Q8FmVhZcAQHQsUZsv0mLBWcn7VWRdtOqjngc+MDuS6Bf/0vW3Bud4Ks2F1A+lLs5xdb8E/PdnDB1tl4onYh66uTo9WdTLBpnVHYGsuVF9Ykv5d+7Iyh7niXYmrdpYGA69JsbPA9Eht3FsWBHARpwvIkFLmVVgChEdj+c2Ke9wRPefdJFp7bLI8m7AXSbWZ1NvSP4vNAXSdvV8q+9pX02Qe7hJSY0S/fp61RhLI7nDCXyMOb3XoXZndCJP/wwq4O7Zi5Eg8TzMpNCEEkY+ftYew1QfREbr2paGg3TMa1HN6viKw11c7Ofc/Ib8Ddba5atqN0bNnT/S3bp1tZ++52N3Zn7wQoZi85tGbkD/f5a+fv9qLdsLn+4BUOuefT0U6LWdbb5/veXBVWlZmbWmyEZdpIA93dnZcSKrGeWpDZzrNQgebStqRpQ2GcjpwhCHHyw6hHlayH3w78M063qPn9FWBQqkeQZGSIYQqdBmJWC1oqO4a+6aOdtWkm1xepdCscHBMrHxj9ZT6Dby5y30XU7Trt/V6fiTOpvGtSI3ueSXPjgrthCO0UDnmZV57OFE4frSjLShgAZDewniOfYkwLhTU5MhOWz5SpjJLdKDfAYvJ6BxUFESXnCKdQVcGX00QVHEtBtcp+FHNTYL5CBm/foGmPMT4LkBYn9rVQYElOUnujVhEwPj6728LSvaOAMFCo6pixh3EL5WIxrVhmtKIxGzFbEMd8niWSHUqysy6ADXC8RLHoZw50HhQg8buFQyv0c0bzOfybPvF3u4rpoqw0AbzlQsunbivARsdpO/rreMPF/SPH747v95amaztiLi/lb++uWPVJlPpHHHWmzEDOLGRnlisMhbLDHJfugtDmemtNXbjbFA1k63QKblOAWxoWxEAd4ngkxLciN+ZfUaA/80tPLhOBaJyoT/UxMDf64gkAiqO0xh8pmqKwqQUKTypgKMCCiTlDEPBkJSVruavh/uvmsq5WvXa1LfzEsefbMNTNjxlw1P+7Dylpuf75/lKzRHNCc5ymWlfH2e2H4+PDTq+NIlu53r6AWPD8TYcb8PxNhzPOUG9uZ31lvdLczuX4Can65brDnxpAjR4o8mZquzMjgsgbQ/j1dkc+D1yBChDTiMzAMtCMP0pX0mE6a9HWrX74bvQtI0uU9u3EMxGZlSQwhXnwOB0+ieLHPt8y+7FbTR7YW9nb397Z3d7d/9qd+ftDvz/P33QuDUfqbXf9VSiF5w6UfSaCzd2nioCGAO4RbuBNQZxSmGa/YXiudyTriBu6R7Tu1f/TMCoiJ8MGH73m86XnulsIAJKD8tOU6KJ9KfSzntKr43XnVXnUJ6nvkl1euem6cpC04bffVhzEdQO4sonHdq4rQXw0DUvJMwXAH9jIU9wjncbaLd2dZiI0UN4o0LUlU4RtY2ivdGNl7KnGu3YyCXZs6cjBbNbQPu6ggH9UR8a3hq5gJhxOSbIpuP2JVJijbSSqiib5pCJgCo40M8BeuaLRv8QllwlTv8yFokc+Vfdb7Qq1sbQP/iWxb5XzE9yqhC9Vk4H7S13AhCHzx5M0yRqMyS9H2vAtBaXcpLp1Y6UPsfdV9/mwbEmCvz6z439CffAoD7M19Clpe/O+WM/ttVjtX+HT201lYKyp/q9jusp3z1XgwwvthT+6xQA8KuxzBBbzycieTVPowGLhAq7yiwkSvh2naprXqW+JggeioSlwP5xEoc61x3EsbVkM63tuzmPPXl0j+FnnQLbk6QSIm4ldBAF3OYi4TI19HxepTI3YtGMzrTBXzAteTGLF+xW5JCeQk4ZpdcjET7NSlCHVwQO0Dic2yvi/7fmtzrhnz2BAvyzApWNU3Y83H35QqEjKDCa/9kd7uv/A/wZlWZ4eJ1izjtXqpWRDyrFHWcT3cWqK9fpCb0JZlnqe6+Dn1vIfstG//Nf9KPIlxj+8WX4Xyr5ZYQSF6Q7l0EasH68mIF8rnJ1vq2Plz35cPkUZuHFi+Hezqvdvecv9l++gp//hj+/3h0+lz++HrEnf+ULnq6wTTSHmUFA+D3YvO/4BnZrjSdXnNCB3jB22X7cIZDHwrcqywJzTkPbiCjbeoB0WurVZqS49JiQDsH/OctBxeDoC73aifugAvg4dIexNofHXnGXbSeiBEOsLEjmKXBXObk8Y893X77c3mU8Wcz49p4+JB8uIdLhh+/gv4cH8N+j49FKG5W1+H5qzvEjDPWfJxSf1N3kq9evdnY7UqtAwiEIcAVTbRoK9E6EZQHe/UEmctQwEHw8hqQPMhURGpJk4lfwH1Ujv/pfCpC/Ep85pM45e09/n6Ulz+NsxRxc/S9RmwvhuXgu8Xe9kQzrHFdxAv94VlRxqVhBd0+7e8/ZO7h2LpuOerL/AW23gc4BYa9NbeP0PC21o+1b3WfqvNQN5Wg+UvnbQbmhiBoJXBdL+HOVp0JnWUb/VNAzUyFt5hrYDgmMRWFxZ1X9Ol2IvMDs8dCAfU8BC59LfJKEF7KH+oYYIFQLoeODkBNlAF2SYeStWIB7GiCzl8oaSDhiaYQt0l+U1hiGXstZrPPF98mmadjTA/moaunLoMUjGILsZFpm2ydY1ndmMElMoh0sa0iiN5EUwbZu46ii466zdkbGpIgQIX3WkjlLSd5AGvWi32qCDQ+fc+SQZMNqb1FiIwoSkggaVgQ7Gx1EnJ1mtyLhIWQGkzJBAcj6vn0gSbG3wQpubrUPC5TlU57GP7fYbM+srwwzC84XPJW3hhZnJByUXgVzXa0gRsoO7CQN25yp1V7qxzW6squHPlm8Zl5VAPT0tAZPaVauZ/KGBsH0oanWIzGJU5UMjU65iDSBeZagYHULSRkaaEM2xqrJcQzWT0jooM67WYIRidJKewKsDHZI/0BdQMIVMBM5SARcpwrFc1SKcAaSeYIJ6SLwwsM5y3Kdji7G/FMjTx7161ROnA1LOpcZkrlRZfRQuE44jYQMLMiA6xSfEEUeq7TLas7oncc3fFzNj8acTo52GeI4ilhrl4RLZZpQeKmYkMvbMD09FsuiFHOG6ccQIqyRD1jdweMsu7lOKdCDF21yHV5XCnIB9RyCcEA8ommVqzQquvXywdjNg+tU5zZf0rMlGsfgwMtkzwR+ZsYh41UQuJ4uKdzKJiXaNBcIvDBkRxpCRumg1p5eWKySANn4EnNjz3nKp54+Y0FPwh+lPiJXkHtnW1KJr8fNqR4ompscQCJJOJAbPe5P62D4fMbl6XLKmXU/UGzAANOtPEdxgUdEHiYHr8RznEDikSO3UDisExWvOEdb62RS8hpIvgy2JKvomCBZov/USNZcB6haY2r0nrhOf8WpMU12zI6PZ5xM1EAGfiZ0nXrORYxAlhDHU5SCR481Cn1bdAxCl/mzLfKXFWIMMl4bjGQFzwlv0uwuEdGUYG46xB+ZF9Mtr4LWVZZXM9vGI6LGIjGrrovKWHvFM3IScVhTLoqLMEOxRuPtuKlhjax/I5YtWosWH/+7NRF1lxl0X6k9NE2EILwM5c4gf2jHzJDvqV2+A8cpod/nClmp6UUwZEc2Kp6Et4v1WR1ep5d0JVqAeliUYPfiglILgWYRlyxblNuAgyX1G4SXtvYxopIAYlOLGLLgS1hyiKmaZRGrFlDj+c51GgEkgfR0UC+J8B62JN86wNC0TM96lJxSfV5Ic6vyWUPo25rXE6PArswyXBvYvj757uQY3AzGoGkaAbtj56tOt62s8CQ1mp0pvbs8FuuHyvo2tHhjh5MEBRBOIrJpQD+nOrarhZxYmmDIoeEIw+a0WLD/16ky1Rrw/WFVjCBwrZK7D8xQCMhj3TKwOuqrdJ8bhnwk9Xfr65CdAWwj7mUpPDfZ+LdFjZ9IdqGh/UaeQaxkBFL9ppfhKl9kEKyydQ7BSji6AGASplkOHOJwF+183dmlLXWy3u3DroDCg0B0b++aboePSyFxzPp6fLj8SjtyyOQu2WQCnhDE7Qq3Ue2fIGu8ZRI2q9BPS/IT06qGfbUrIF3ElWRkqLGyZ8nNoYdA7zyRTrzc21VFM5LeDizge+fLP6/m1tnLgIBGF98uTOHuDro2FlI+sUQ00OCI3dvAqbYA8y3kl8Not0aSgTiL1PpZl+uQ4ZOSNWvKvLWLVKBbKqQAJyMYfUqydAq5rVVXMADtQToa8nhkBKk9GsxTYiUcMW8lN8c3xaTImABDbCgQwi+7SzVqYmOWEAhWaVt8nCl9XlWYUFoRnLcqlU7BA8KFdS7L61Qmx1Iz6WwHT0rHXYxfVGGEdkxhJxhXt9xGavJqELkyUxo1txLz+B6EyQZlIxN6cKexLcy1bkSVkYKdfpBrZB/xZoX4og2xBWsTU9D41U9OYa1iynW6Wk5hK8SU6/RhcopKhz2PU/s22W3sGu3qFN9D2G/H5QNx/Pj8/Jmac2X9V6h8y6zKm7B8AxywwfPDlwx28f0he/HyxWv2//2/F0N2NkZ3fFrh9qa+JftqniVswVOR1BH/wI5vWNMAIVYX5DH+4W/rgvuN58mL8fN3/3P+7/1ZOH+fnX78vBinP73YerjMztCF3Lhdrhbhv5r8evGriq0GbMa17N1Haq2BdfyWJNYT25NYWXz9BgiQXLUDaKGgUciQ/2cQWruFTY+MCYnOFotkWTtT+k2scE4XaUd2pgd9I9iNPimXC2Lqtrz5dB0hsF3ca1pn7rL8Biwe2+Q4+mdx0FPDVkDAv08fPT0KrNVhIcDvKtcCHX3OVG2ACwxnKp0eCKYiGklgarSD6YLIWZ64gUsk7g2YKMPhU2ScVRqJPFlaeO1Lk7svgvzr8ziVDiWG81N4YMTUuIfso+qWqKcidtiTThbLfry6OpfFRjSD//o0RMhyxb4BzjFLt/c+f9a0QFa/Kp+A8zhVGsq+R0pXQZPiRD5iiM99nJK8vKOB2mhGpMwnSxUVBPNfaQzMVUEKNL0BgXqLaMvFDHGp+LGa89SiARL/pA5UiOybAszUjdS0LjVzdnhouzBLT7TZz5NDPwKeBezRvteTOL3xXgF1iL82gJQPF6cNd1Mq2z2ilaKG8+r4rOZjWYhk0kFLXKhUBF+bGOfLtuJ/dYYE1HYsQlvYyyWNAYLZUsaLZVpLvaQa6HOS6BL1BBX5YEFFnZ1BxnFiNTxRzOwAolJCyH0AHA6YhcPtdJgxKXh/0YEk4BaACPUUDoNeAnilBmrOtJ+AzFihwq4URm0PnFCSb8RnXzSq4uPmttZnkfIBUQyxyvGDD8mhLg0ipOJgls4/qr1NXKd6CotKiai9IZi9sYG9os0asXn6Nqv37IadrSP01W5KiFhTbOQejVDddl9Kk4zP2ZhJPBHhMkyEnfXBxGA5Vy2HHCCYexcEA50AyN6FkARIfYUWwXVmyMAjP04rwRYZvTKPkNohnOgRGh8PUpXaLmGR4FECt3ESo8MIMsUqt24FyZiEiVqzt32N6gVHPxG4MuVzXKky7ELPehdKqbaWYrfMFkphBZg8SX+VlnGir2NoRsvX7ouatpZum3MIGYDLWZwD6l5eLk3mXov7e5OvZdgTZ0kt8czAJBHW0XHNOR8LhNiiU8Uop4yMxiyy5FYY7csiTgomUaHi5xSnesuuaozsysYE0PMRWRIpWshwxuW3ERMA+q8xtxEG1LkkBs4S2Z9GBrrdJIevZ9w2F5dEVI6THrRTsaGHUKRG0oqwyySjkVSHzLYmtBkjAUpOTNpnoB3cjOCxLO5MwrMyX9YtX56L1jpxlmplAvnc77XzsTXYGuvkI3pBgRHisPGGJQH6IRyz4bJMLsrmBq1FA1o9Kj5IVz0aXYMDkidO0qiCo3AMs3xxjwwJ9wuyIxqOiU3X9MOHtPhOSpZfLGvVvz75ogJbrhtXRVwPetmj3zlKnXfizyGBbv+Jj2U1r7xUyWRXCNiJKlFtk8N9gH7uBn7c38hb9iEFHwvb0FDJXyxQaVOoDlzY1bCTqFE3biW7sTuwC/fvRE6yPOY6gFf/aHXhFF2jhwiMOscwpcAzwchodwVfA+F8tfv0Vl6j82keh1UCeMV2p9avdmdO4TU6iXMQGooBO1BBIN+wA5FnGD1l9ysLBlyWC7guZdMhi5nm7MbWoCuN54qcI1HEU3uTcvUxiOiTTYCuqKut0etiwXORsG/Y97yYuSY4Tt+Cifxi9ymrmUprdJmHs7gUBEv9DTtPeJrWdrRVArNHpfXNbTdhNbAGESCqZfVQePOj3ZldtH8P3/EUE1F9w76PU54CmA27FPktxD1afY6pWDBRhYJCFbJoUI15m1qDpjzjUQjREe/A+GSTob4EaJZy+m5UWqNDGdDE3nFMrJ4U7BuQOAmX3N1uKvgpmKuyYOE2JW2Sms3WGl2HxAKOb6FndMAuK4k59Q07/k8VL2pccCxr6JXCjHBQIRC6uENtrQfTgd18f5IhOWIFVvsfeR7dcYdbhvJbMFPfLEp8Fe/R7WU2Kdu6LdQ3X7dWxXW6NSsLuye+jRN2nE7jVIjcZRz2fglCKBgIq6BDktWor8n16KvmImfHACeRZ2kcFjWa4HMgrM81SjzV79H/D1kWeXue4gdfn6rKPXrz8DLdoY+F+Squ020xF2V9ZtVvTjem4BrN58tFmVngWroP94PdUb3KGr0txzgPYZVTYKbuDT4Ehfpg91av0r+3IzER8HrxDbusSTgRfQkaMo2qcrm2FHO8fSp4XrvPRZCoH61OjplVdI0eoirUYlvIIzF3LjKhPgdcfbT71JWtqvfp+x2GwNQuBtP33Hz29u5UX6P/Frm8VSK/vyx+nN7GeYb1/IKLsAt4T3xrE2tQQdYqX/f4xd9vo1L/Dr/nIaQhg7vZ0+lEf/V27K+8RudgzDzIywE7rT5X+ZLYM/uG/VXciSS3OQV4NgQ8L4MESxKLD/4ty9k0yTbdJk2Da1CXZRH7hn0nbkUOxgiLmCyLgrH63e4cqlgV1uisytO4pghO9G92F1bB/s3/wOfjhKTzQ17EaWav8lR+DEL5yepOVzTV1urVZYxT+sFtf12G+AP4yNU5wtT8aLduF+3fw4+CJ+VswD6KJEFBFnSaMnWtijMsFNzJMsFElrC6p3ZMM6aRNWjJSPI/xGBnEtIPs3SaZHPCn7NJorJBqMqCQmGVtElrNFtvdA0S4a0aEpGhRRn0iZJPJrTbLkSYV3HNgjODCoEyQRfwQInlg9yUtml12zfNO433p/fEAmi4gtivLMmmS5AXmhzQAnMISl3Wyw1bmr0XZzxJiyrnqSO9xPo3p1NTcJ3m8UmJHgbZOcEuHUwmPM7dwVvFAkJnCrgs5hDR2dx96brKeSTQOnQrkqyulbrElVA2iKySrfRRs26j65IompQIT5di3bZvRVGiw7FX3or19xaBq62B/iSc8jv2fQx+99+wU/RQ9ByKhN8FEygUoBOj9zSYhhrNrEGNiIsqFwNYs1u02l1lVR4Xc5sYKgM74FYkQSkL2KRQCdWIaWINQjJ4O4tDZSxZssMZxgCczMGsDYaTz/APmy5VhawlyyCEGkGMFQJBxW0qVXmnB9WBbr4/zWYHkBKb1Liw2UJod5LfLYraGliLhGrCwWwZp9MBk65VAJ/m8F2/cWNuVw7mqq7NhluMHU63ple70/saP97xPFbAu5pO+ZNDgS62Vts3ooSLToBF2O3iRpRwY9IXt6dapXU7pIv6ILqF56mivgayRMCt743uoQm3gTWIACMreEdE2uSFN0gxq5EC5eD5Vpaj+4hK2QTVm3MaW48sCAk/EtJISsJcCGEjyqznFxnmVBMuIzSWznRFbSz0csxaj94O78VFVcPnObx442AOkzhFbvZjVizikuzUUlw9dC2dajgLVTsIqXIwU3XlEIOwZgdtdKz6tbp1O11jUKB58hzYB1w1xxTrVbsw57JQADeWsIrYRKqGms2sQ01KHA4YDc3mOwHjc4hJkZHJIsGcCjikpMiwVCO6iTUIyWjTx/hWRJpLYl+X84wOjywQ8DQKJlDEpqPWyEEaqWbWoKQqREVyRDzOOYCl2GTQ1yDR3+z+ZVW74lodxyFwNOc6nsOvYEGodQSS6poX63txVyw4gHNZ7afmRztds110jR6ydJFnk9geQKp/c9NB64L9mz+LkwE7TkU+XQ7Yh1LZcL5hH3lR2mc/wwcFKBdUqlhwh4UsIs7wMQFKWY2pptagyoL3wm0DqJD6ucqmyi4YIHhkoN6oHLqcBhvNrUFZVaLuSTfl2WRSQFybcztlpkiQmQI2NVYjThP96Tif8XzOQ1FhJGExYN/FWWkLUgeJVHRuBXH9OLWXc+HWD8Z29YCbyvgoipWtAdR6r3Xe0vU6g8vKbJrzxQxPL6CzwIL5HiQXVtEgo4L+p0inUV+Ta9CXwc6G+va+sqlSBQIHxs6mpq2JNajIIfr2G3YUT+H+bLxrL+B7ENHX5ts2Va9XXqf7bAJOrEqRpgsLLFIoZE8dSkxRUM7o9gtVQYcoX6NWk/3puxCwvsqpTpGSC9gf9KvVr1t4nU6SeBpnVQFmmjIuK2QwTn+yQBDbBZyuW5pYhwqIEUX0g2/s1wuHDlUksF4vXDp0I24T69BBmgco57M4vWFXHJwUbSqoQFDC56DEzw4NsgG3+loUlLxChEe3W/2r25tVeJ1OSgnOrdvHH5ymZZH+raoHTuMq8Y20AsVTXt9W6p3U+GHEblGLlmbDjWbXoDJDF5yT+QICfuG0Izp6ufSpPwUWBjsHoq+mURCq4l61x20cRE1v82tQC5YS4CB1/4BCfmj6BzSqrNFbtRA5qcmweD+Al39N1i2sIsFUF7D7txuxm+hPxxW4W7io9XL2FARsjk8HPM9jV3ItGzXVOgULVZPWUdW1KO/VLS6q6XiNQUGULqyNjF+8nMWLBSpa5zy84VO6fI5EEgOOlz0mp2JQyHrBQlWDDC1UyR6MU0v3ZnVmdbXWKG5FMmCnWSQpVuqv6w0hLZgJFdPqdc0zQloxVWNuU/2J+jgDXFWe2Pfknf7N6s8uWGsePeJT8JkP0NjVRIKI51b4hHJ6RlTPsZDRqIDPyeNuv36V2Wpn92qnK7MVYmQGEG/qjXbLEW9XmNSAmiJeINvyimM1Ql70IkTkRezDMP6JPqisB5oSLwE2YEyYVEV8K94pgBgKqtJ4MYgfVw+5sr3atce5Ic6ZL3clOzzdLzHWfOPqvnF137i696Vr4+q+cXXfuLpvXN03ru4bV/eNq/vG1X3j6r5xdd+4um9c3Teu7htX942r+8bVfePqvnF137i6b1zdN67uG1f3jav7xtV94+q+cXXfuLpvXN03ru4bV/eNq/vG1X3j6r5xdd+4um9c3Teu7htX942r+8bVfePq/id3de/v7N3q1W3yvSkGeoGfftrt49O9qDypT07gZ8iPwOeQOaow6R7KjE1Bu5LJRq3Ozb1A3bOfds38tHQPgwlyyJfZsg74TSeskskLMIUCpSqFjAT/qZDzDNmHggik9Hm4fDKvbTbBlC3wUSVYgmSeKU+WRVysTosj0qhltxynESYjL0o+X+hkCKWh/Yn2+H86BDW/hF1Eqeswewi2OwSvcbEoC3ZyecZev9zZpfgG2lYFJM05gr+JPG8OKG/KAk+8w+vueAdDU1vgRfdocXrlaH+xMa06YbU8DWqAA7OujdwB1s6Ew5ZVpTwofbIedBzJI17yRt4nOoW6l56nG5tand5V56lqLqiVQFcWYydHFMZC/WPCPXXeMeVqJ8ub7O49f7H/8tXrNzt8HEai8Tcmm5QEqTTlLkm1dGlQSOVJkxU7KbBGJJN8QpftkStXNot3+xluAlg2ASybAJZNAMsmgGUTwLIJYNkEsGwCWDYBLJsAlk0AyyaAZRPAsglg2QSwbAJYNgEsmwCWTQDLJoBlE8CyCWDZBLBsAlg2ASybAJZNAMsmgGUTwLIJYNkEsGwCWDYBLJsAlk0AyyaAZRPAsglg2QSwbAJYNgEsmwCWTQDLIwSwKJflYCHyUKRlnHhcqc/1N3DOR88+9HCGJAXkt/ttwRR7Y4usQEfHuxhuDHCEjnPjGv1kZ3t3Z+fpkL2vkoSiY/S3uGDSvfmZ5YkM/v1jkYYzOGEFAztKlfJbHqNvvuXtTwkUbGfrV/vDfU9owiZYZBMs8hsJFhlsldkiwDMEuykYL4N5jNe8iAJoQBRl4Ym3UBVYOeOlFVgBEzPPipLpVtiTMYR7iehZOONJItKpiJ4y3bQePs9zDjwoLsUce3T3IkVMNAh5T0lLsolukUHuEGIONKylNcd2+hI5n6/fPH/hZC0ZbMl6AU8WM77nj7WA1X2++/Ll9i7DYtt7qjsWZpHwratZwg+XW4OtOf98KtJpOdt6u4cE6L/qi6eiRWp0faqf3y++5YTL+IFrmYgpPEfAtn1CzW0W8Ksu4CwrSggY6n0ef1QV8NbDlZvF05koSpXWJ5v8mkdS5RRSA+te0d39F3s7tSVVNf2Lqb7SFs5FKOJbEWkCuheTL+Kh/GsYZvNGUJvuWi5g+7rlVdJ/zb6Pc3HHk4RhLaJcrgvcEmZpzEH8ikuE3Zd5PJ0KjI6F1ZrYFHau2F7jCDodemPjmI6Nsz4CTXdICsbuVfA18+gy9vp9B5PGUG5jc57EIVlGzguImLuJU0+8IOwZ+KIi5ZyRuvFyYVWUmIyqLVoO2kJCsUEjQw4fK2rugBEN1EuYCzzD4yVSXhUit3uS5Nq+0GoAq/tZ5GKbxMiIOqNHft1ZsSxKMbe7kwWa7/6eSD2MBq0S4Y3g/JDG/6kEiyMQ9Ccx7c7G0nTug5e7r59HL1+N98f74xd859X49SvxKnzFt2S/hfAHj7Z2LSuxMEtLaVbU27KTEjEZvxq/Dt+8eMPDFy/3d/jOm1fPX05CoITc0Pxbkr41z6I1C+jI6+7QOz7p2J6azVxi448e09lo/+DyvR0kVriRcMW92iQZxfH9l784sQyq0Nrtn5zbflILxylqcb8G2QUqeHazKgzbblwXW7sLbaM7BV80n6EvwQ8+s56qsnan/8xSAW9hN5G7hX7OUgFvafS71WW9wto9fjz43rYx8IljXcCtv3ab+ocLOOGOnzh9oJvcdQyvVVm70w8HDG8q++DxAG985+RxXWztLi5ARD+N587LLwjzQYI/2tZmu+jaHX13cmhH+MWhE8AXh/dp88ezK8cZ2SH3x+xedJ6+YkdHZ5e2X92rIIpcJ3UoFPXyTW+0/xNkq6y/5N2aH61enKLrT3hWsu/j6cwJrMzKYIK/2ZNvFVyfdZ+fgNlSJHZQPl/EYAGFH52Q5tgUvddwvD6qMCa/c2qjytqdHp3aXD5KHDZ/lNyLz+sfjNTT4CUeGclT7f5dawGv0XNTGGxWesAmYZcIF+I/BWbbBIQqEvjPhdlI3uYeQt5VdiPSldSVUGo1cZ7GHjR1oHiloWDvYvWq1jJ5sqDSKTumz9tkQwhvsU0oydyRlV09TguvUq1q0YPBdaBd7b2s5nOOGXZ5KT2WybSNFcgGI80YGdbhibRnb0M4zra0bWOQSh4X9hhbzNgtSvAVEEr92ZrwCtPE3v7Ozk7dOCEfL8BH22vUlw8YfCoYFVE2LgEq1y3qq3JcTxZZEaMbzP8Bo30ueCEGLBVTLn+MBP34tPPlYXd/+Ny/0p8aa2SsFZvV+h2sFllgN0v1210qUIY8nI/mxdhjsRh7EmVzHqfFU4aPleZNs9vgtl+bKavnAF/4fvbtkfe1ztHScCdyoR4II02Ffk9V74UrDID1zO/2BFnQXTXYLOcx1J2/ljENbChB3/Nx4wrq4Hdth6ufGb7Ha0u/97XV1mMbSe04z7N8NV4avGJYpTxbGQ7cl8HWXBQFn9plPSatg6qcwQTL12iBNDQPQgTzrxq0if5BlAT3diGKRZYWYvUA9EtU4LMhfyRgSxfhDaJ2eJIskYslAt86sjRZAjcoIBIJH/xlBbRwp3ExE9HTTnOeenHd3b/aefN2Z//t3nPvK7IkGFxG+tkZ9buIqcl4WYr5omRPiHmX+fJZJKJKg+f5SNUvxlUVR2BkBGfScOml4kJMRI5iYpkRo8Syzcc/PbNrdHgr8sJr8f+JPijLqt0nrFtV1BA57YU1nFsyHnIhAHMsL9nuUz9jkg/y7xRTIkhSh2cCu/cRe6auRyrAQCpn5MyEnUZRLAuAZVh8LhkfZ1VJNmOiGS7hqmBPxHA6HADkaiiShBaYGh3QEWIRev0VT7dcjD5URwA6DsR8UHiLDhPv+0z7iiiSpetV5D5CyFINdD3982qdRkKiyhGJiEWVIAcTJBleruZxAWFczKZezUSayZtH8fOnNoXecbsBqtjJsTsva9M8FiGvCmFvRdiFUVzAeXYmTW5s9anujx0u2ZH65H/woCPkNfcTt1JbBl11wLNnEqewz4omyCw232hpuWgwlb5otobZGRA7VVED6wREYHC7ixz9lieVeAQA0cbtgTSp9pu6pZrLdXmrdTSI7adF6Q1597A12WMhyhJXxOM8kU7iaZUbH62uqafHeeM3ZIlWUQzNzuOUl3S5y6VfvsdHbyL1iwMp2LHC7FJR3LaHHmMDdF/fPb3c6LHLcM4QlJEm3RtftD+6L5rPmNQKZHxP1kHXsp8bWzKYvL3VMzDWdd9cgc9FFXH9TscARxxA5wB92z763Wx1CHxPkYi7xIzO7tYMw34ltMa2XpcE71YmSzYWIAFocdLuU1FSQ/Ixv67V64wbKZ6ZpoeOOZw+13Ce6Le1OgMhwUgRcFffxUnC0gxZine0urjzUq1/9MoMelWCCd0FKzSfYpZVSWSUn7xKgemJEOOCDLvoVB26D7hUfdqZlia5t65m9ucT9Gl5TFJf///svQmT2ziSMPpX8BQvou39pLLOOrxHRLXtnq4ZX+sqT89RDjVEQhKnKFLNo8qaDke8H/F+4fslLzIBkCAJkqDEKpfdjI3dbZeIRCKRSCTyfD7Zr01BqmLkn3N5GaI+sgrvnxxB8luaqIXqC/lN4Rn+IA/7K9gWsDp5RPyRyHENnvfvaWStRRFtmSXwo2/vTBo37FHSPPdaalDRvKsJ3tUE72qCdzXBu5rgXU3wriZ4VxO8qwne1QSvna2rCd7VBO9qghtO2NUEL8euqwne1QTvaoIboNjVBGddTfCuJnhXE7yrCd7VBO9qgnc1wRsh0dUE72qCdzXBWVcTvKsJ3tUE72qCdzXBu5rgFVh0NcG7muBdTfCuJnhXE7wU264meNTVBO9qgj9ETfBczHESHpyJNoZoa4eFr52wQT4xJlwqSVDF4pkmGW08+xorXC5p7Ea95//8lMZaHwxeRoEXJghYiP8oB59PmOJZibpg/GjNAjX5MZO6AYaVW5ZmNyQ5uUn1ccvyA3T1RX4SxZ9u5cL3XUY9NURbJAnIXEoVndLcW54YCwmm6e9KddAEdygPypHFWu4RZD9U1wsVqSYwDPPEA7ZmHiRMpTUPRJoCuN135I3v2XTHE9Ng1dlajHzyaA0pDJmEPrl7vZqE7LLUxWSFTz5+vHhJuCewSfa3vlwuuj4HSe1VrJqbn1AeQMjX9QaQjr6rzpD/hbEbd5dPROxlqiKPUswSpinmUwaQb/0Z0vVDmVEpvgbSP+FrfU42jhdHUPc3Dghszsb3ojW5Y+zGprunR+QVR+05+WFIzsh/kP8gox+QM7J7SiMCWS3k/E3l8hIYPZ7+6NhzqDNSlp+HSXZ3Sc6LoKrIDYHkYx8qNbPlklnamOiW0u4kqpGvT5qsRpN93jpgqXvib5woEllkQjZshfzdN0tnNB5MRlfjyfPZ2fPZmR71ukoCaR0VlXOxsgs8OJgQCKmE2/g2JtL1edZneFDxgNwtpUkFEuVN8hzfTwRzusYMT+myF4vpVrFlgckpvQ0UqcuvXviycJvKccl1UrhVd3i/faVL9avco8nC9qHykrphFZkFeSrofel4K5f9YbWYEuoX0787babTZjptptNmOm3mm9Jm7ktZ4Wfyj3p5moApVly7373orDEV1piull1Xy66rZdfVsvsOatl19ddYV3+tq7/W1V/r6q919de6+mtd/bWm9dcevt7a1/CpYOH2QRRQiwXztAC+1I+Km3SR/FbdrnQ4nrDRcLacMostT6l9ZtHJiJ5OTsb20JrMJtnOtJNxv/d5QGPbiTKrzSO4dQaBeLsPIPqGs5HpE776LZ2ZKXma557pe4JQdq3cMQB9dyywcSPf8xHL2D2qNfOb7nzi5klQ0zFBkcaDJXVcyLxvQOsEwX/KUoAnw+FEqfYHb6jAB4OyVE8+frjoffmUtV/329i0FJdPe8MrdwkJ2sNJ/VR9YFveevTqNffxJauqEgWHm6Y4B80hjzxR0pQJ8P9VQc8SC6x2oGmFEdui0QkUB3zaI9RkvgJHUkvv87rgsEiEdcl5t9Q+7IVH+BDoyAJ3iewra9RRFW9T+EYnzKhI36MB3bCIBZplGmCVjOaKp+w/TEPy58t3b3v5O0RB7/cevIl709PRdHI6pWdsZk/PzkaLs9PRzLaW1nhmj5ejJXC7Dv1KF6IOcXg5iC5duIa8VxGRR8NDMYIvo0X7GyZpr0MsdV01Iqji8ZLGsA3UB01tArX77WyPwsAiHiOjI/yfEgz17Z11uElaeUrj5/SnSmTAylMyP66r0i8dUMzPQXwoOsmAIuKvmkNWdyHpsND7RqupgK7SJlRImAVaIgt/kA4ZmLPEW3ulEkPoQjv4g+wFVDq56E43LOODROg1uIT4mC9y2kpkxQO3GkEtbl/072peeWQQrinmoisdkgqIiDq0inGtbQVR0QvK9cUSjEt2GoSSE25duks4jXqyfG81/nK95yV7XURl68yTa9HyXagC6LSpwObmu52KgfeufybqEb/tmyKqjq3VXz41IG2CTjV928PdALd23yxfb8vb2CegxfzB3xYXXMOsfVpU0Ha/6Lz7UP+bxvTlFoUmFTaHf7I5GsBt7OdmOVsH6qOIu6h+c6puhqu0IjooWWKatAeimjU6iGiwQi8y4gQUaLRLCh4V7f3qaaElgd5n6e6E82hHfk2HpbP9im5fXBahqZ9JfNAHLflXlQS5IUAh4A0W/BASTFTJEOyIXCyJxxzkJYgoEm7IfnagOgQNzCGzj6492BooZWTtyBK78/6q4s27PLItbAe4+km483xvt8FTVbJWm9ee4er+NmDC+STbW4aMkV8/D8LYC1n0K7zg0LODkz89uq7v5lnFaC/FhICu69CwAs8j8jFkZWsA3x+jkj4L35bUgasFiCtcdChXXpMtjdbpu0z6A0LQJ0Cp6JO7tWOtsdUnD5K6fPkXaQb2g5AfBBtqIHmrmFds4RCQP5Oj8wR7XuKUT9PDk6yg8B3g/fQImpivEY+Qm6HBge543IW8YOkGQw8Bl4yH45PBcDYYH+f3SuyOndA4VfVDKDzqsjAcKFs+SKUxNm/gFARD/IJhRAjghK+ush1SMIcSMAmmlSx21MtiFN44W57sFwQU3vO9WhtQhUjp93IntfEVnR+Pkqi4/BopilEcsJsBsxjEaSC/HC4xDeSi4YVQvEw0d6DQocPCtUC9yluBvIMII+q6/p2MOUyZKPwVeRy61ULwg6QZ471Nj8iVJBXx7zwWgKtGuGYkzkfkpYj+YXIYcqCz8vyAO272tIntd/viC/6z1Ft41xT5oGk0IZ8Jh6p8d4iVr9Edml+Iwm73hgP/tQQFePbSVfM5OHAcmlczkLomCkYOsdoTBWWT9nmf8GlwtIJVM1nj33mhuG74cBEiwQ1m8ENWceA3EFyMB8kjBd09RK1C4hSIClNaVPaDymNtCp7CdKr8THri9/nGVnCM3m7HScx5hbuc+cf7xWdMBsOzwXh0NTp9Pjt+PhkfHY+nx5PxP0yNGxrppWOsS5S7r8THUMdWKC9KSFZEV9WWlyllZ8eL05k1nZzOhsuxNaQni7PRcESHjC1Gp+1YjmTouhnxXWibIod8nS3QaCa5B0vmDfCozHSKChRiHQ0eWVYRhyOCSDBmhqUxOJKfAubykkwi5FboDVdrdu39Cq2VAmZr5vqVPAFdAIqUhrLLPAo9NFk8RYv4DUrCa0+8zzgCYG1GNxE+5v+TK+DUulkFfuzZgJjvQc14Tvw7P7hZuv7dtWcHzi0Lya9iOVqUIv+OBjZxoqNr79obkF+Tj7zVr+T/+3/+X3KVWTvwI+iFPLPMtpnN8ZGzEie89gjZxvypgaSxE8keQsyvr39bHGWmZzaf/TIPYE1vGdfyU1sGoIK9cEDlh+krJoDQT5MlbvxbiAu5dSh5+er1q6tX8JZ+//EKwAds61Je0PBpYfl8rHbx8mHFYdShZ0ACiWY14Nz6gF8CgLdBNVbwIfReXtCQZd7JxdjMlHQQdpZgysNHs79mlgIvo4antVzG7yfaJ0v7dLY8mS4m45PpeDlaLJfHU3o6Gw7PbJsOT9qWNsmFjNYyTdQoRownj+2NH0biaCVZA5GPjL3LqEckf4KOyCvI6BNBlfzJ4vkiIl15FMO26y+QlEgKacMk9NtjcNCgnKcSym16dZQRZB6xAIKN3WrzJV+FExL5OZxDfJ4umLQ38JAzBo8p2ySiJZ9ou+86SvMjZFn9JPkuFU/ZresTZ5kX4LBjvoVCW11Nmg2xJ/oZZVd/rATWj+3+Vp8Z5bSGwq4gxY4Kdr5KqJWESSPSCA2hL6KM2IBbmVdkyr5hcjK/hn70+ORsOBkPFovFeDBdnLDBGbWsgW3PrJm1GJ/Q0Yn5MRPLKFNsEjpd4gdazJJmoCKN1WYuk9KcYQJWAzmeewiVYHO12+qpJKNX4zDyN4PUPb+iEbujuwGPf1T+YEMlNt6QYOBslR8Wrm/dDLZ0xQZhmpQgf2WfI+bZzB7AfegO8NXJUXDs7WDJbBGROVhBfTvANIjDSPyrMTXqRYbIrdKefNO5VJdj9cOf95ItYPM2Scbl0EJuTU9VY6CmFsW0BS/kkVFd6sULBQZaux0IPVrB3jGbuCIaS0xsMAkL5vqJiqvYsoBPazrBGOxIkQ91P0tIdQU/KtnLcirJSBmyLR0Xw6sWbOkHTK66bLsVLIYpHlsZO1eNB35G4lCisHJumZcQoHq+2VBvri21JgruaujKO8B2o1gv9jDgIYg9cNBbIsDspzzoG0FMBhaqvmFeh2rKkagrs2kNOxUm3y5ApDrIwiSreQ9bbvmB+bJfrEOTLZ6XBxToQlUecun7LS3EigffE+feA23vh6s46ffgqPs4NNpR5a+bx2cq4BjL+N0yBTjkb23hjDVXwBV/nNbImUa/Kt7dcpK82UlD1C/nP4k2SDb5UB45XYLQg2sK+SjNvUBJt2Zq0FLYskwxBCIraqF0iEqL2w8psB+4pRcsdUk0gwM6t7sjmExrS1e08Ogxm4BlEsGID/IIhT+kcSM1SvSwJKcgNee1uFrHW33l5epX24JGmbF4tkCyDLyvS7QSFskafdtd8ldnlJI17yGRkrtJydfYAwAObee10UqQx73EKykhG7mAHtU0IFwhaHyj+JIOouxtdiDPiBn0zNKGZpyYhBSdLbXd7QFQDFbCTnJnj65CksqTNM5Q0OtCEsfxhL8f88vjrc2LRXIdMBQV5hBYwAj2YcQqbPCxgwVx7MLXEMQhaQtDsTTar0pgI1QLYFHjgA41VgbWDV7T/UIvJKQUgvZFLtJ0Mg/zjJJQPBXal3uy11msK/TyVIxtYlGBvzR8+FLEDEdKrA1XIJP4T9SJuXWoJEZy7wjeLky3C9P9nsN0H1FMLT483yunY2QiQNI3WP6GTVkJstWUyBYlMESJHuEbqgauuM6SWTvLzT4tsxEgJeEZ5Nx1rz1FJ4QdD1gUB4rXDVUA5tlb30GZtqKBDZvM87cBq/+89riVnVguwBmEjs3AzYoagCh4mpvFY8zGnIWGsueQZ6k2Fqmh6bIisOmr2cjvwTR+H5G8xTDivDpWa5DXUL2plb58fjPz5gG7kwtPue94WMXxeSjCEhRofEoMSSt0SKNS8vvPyaRMmSWYZqmm+945Zb6GU6ZdX8wjdsE087x0DpdGlGyVYx7SvdLIq9L4cvpaqkfm7mknqaVV/WXemv746JNXWrn7izf+3rpyNjxOq92V3Of1CTaKNUdr62mmGqSb02kGX0czqHkKNBPz5dv5tfWCwjKbLKPTCioM+e1xy8PqBFrGL/u2k05fQzq1JJQelywyFEGd5NFTrQVOeEg5YyBeUjXvPpMUFPdhU3epxlKcdhJ5n6FVrr52FSIZ/2X5ynl0RdbVaLxo7tAtjbILNVUDvl4pimrs7xHpWqdrRb2JMmRLvLUf+A/Cywj+yvcfr8gzsc3hs9/TB8eXZwgrfPa7DCn58qvIPMY//BAmNQd/BbfZr+iV/xU4/FcoRgLuPo6UDHrAMqncnXJErvxrD58tO8VD0ieiucq196spUs/UiilhvJCUufbkZCF58v7d5VUfcmr7IsXWyPvbQtzKw5XlyDFAotw9YFmOHK7lBSHEvWcwn1p9uRxQe74aidkX5f78Z2YNEV2thI2EheFcbSFTUk8UfIbKZ+TiJc/d5pTizkLeIbEAUfQYSn1SdW181Dja5ehkys6GdLCkSzaYHk8nkP1nDaZ0yOzp0jqdjma9kqUplqNcvLEROSUkpQR/1UQFa1BJaiRPfMQSu+A05qMHLrtlrmEeJGTP89C79IbLEZ373uCPUPVgm/5TpGHOI/+GeamHTvHVpamD1JmLrD/+j5DRwFrPlXZM6R8x6GBL+V9dhg3K5knOYfKXO7ZY+/4NGH5cP7aXLni751HseQw8RNZdOLfZ1vV3ImUa/pBASf8x5wjCH4AYrk8xpX40l2n5qNzAQuE/4gBueKFGZTAVy5uDm1z5pyjN62wgGKPfc7xlQMMoiK0oTtSOXr93c5sBBljMF9QF2gTzje85EXrAsn/f+r4rAqNw4DzZTcxAm28DX8i232IWoyFtPF/E1g2LVMsYikg0pAWMbuaucwsSZhtH6d+g9qCPbTatyA+cf8MHNvvc66cMxP8jNbPVqESVLD8Hus85SxY7PsW8UiF8U8LzeCRC8iRa+yHPc8Ss/M9RQFM5gxEU4dPufHTn4/7Px2HHIXu26g5G9uvsoTDhdqWxjeT6fQ/3fTZ2yc21X2uXCiCPu7lLPaUfcXsXw61r0OClAuL33+Ilt3grDkI/aKUYwYVnY71MrmgWM+2TGEGnaY0CzO7nmBanfc+rHUNkM/8k4TYPmsTmywjI+Hn+psY+gBIh/F48+iDaNYm/1eb/63q/7P68/vv47a39y2z4t7F7c/Ev//Obf70Zvr36++Tdy5u75f9q2ozpdoUbyHgIvkAokfaovdRYJzivIyGk2Y2nAvDKqlo9KOSB1s+wU+yz3+H/oYmAj/MDbCFbGKNrSLqh2y2Qhsdh5jUg02NZS4O5UCgyCtV9Qc/qZ/cxCz9U9wQ40R7bnyBVRu8Ddl63vcc5Up2x/Ulymvf9TSAV+dZn0LwL2p8j+8y4F/j3tQO5R9C9wE/eVK1DV59o7QPnL7724ZY9IFufKfMevTfo+LxtHTp/LbcPVvv4bn2azFu+deh608A9T4OWhtbnKBguWp8hawdpHTw3q7QONrXStA86a/RpHX7RhnRfU3CTVOvQ8xau1ie4L1bPmbDag58D/CV5Wu/eor80F836Re0Z38iosQcqrc+AxPyiNTsYDr6PV26t51oNL25qE1TH7h2pberuKG08kI+Ezre72ptJDtmPEkvzt78hOoP7l0SG7IFzOrLJDqszGu82WnkOtyi1Yxpq422WLkgXZJA6vraJ2WIOrHa4aUqZWL7YsCTu3AJGXqJl9H4mWPthxKNtWoVue/ArFCNvGfCaUTdaW2tmHWamKELO6Nktw97wUmpznq1+j7sqTjE6TloGje2h2wfZinExD/phVaPi7O0CLZdF5vqREbgDNaa6GKr6y7o0tKvpTauBsmc+3b3oApzxM4pAKf2aq2v9EjruwywHa9La2538w/cYhONZ/kb2TJEldr4hlU6zjS0q2CyiK03wxRVdqXVOgez+NnI2UFjIArcjd41aO3RBBr57RH7CSEVRw+m6dzt6/l9rGq7/57oHpbsC6EW0ZlCzZ41NOLD1UMiOp3HgDpgH7nmbXP58PhjPjsmTKIg9Xnwp8slofEoWThQ+laVgcOM3dHvtWdTzPceirvNvKDuEVag+/PSCnJ6czsiTP1++e0tepJ/wAM1LoDR7ekReuLxwS7j2Y6w+w2h07b0S8frE39LfYiaaoYQY/7ylIaK+wbZJSbW3i+XgDfaYWzNqg0vZI3eBAx2fpOIWlnTDSRyzt6PnH358e+uPfvn3P6b+hw+/DX85G6xv8CsohAa9JMsjU5RAzIrOE2334DAKmlEjIMpiePPOe1uN8ki97RvHczYQYyBC+m3fisENw2VPHLiaHAkl2EPzG8e1Pp4AA805cfM5GPkTiNins34qypnYc36LmYj3F2SriUbOm07nHr11VjQqefFSe4Bhx6ChwYnYiIYmKBzdpM/Tq19eKGX9ZYkprL63gSyFhcuuvWRq8gtOTS5eHpEPMlACp4GKSnS1YvYgCc4CN0So1EWEoMVrTxbuS7H/b1j/EXm3cVByYI0/1/dv4i32f/boLXUwFoGIiAlr7bj2tZeU/hKJOkfkLbtlQVJEEIvB0RU/htBYmoQRdEWFc42Bk+hMMs0S4KR3tNWV1UChL6qRW6YX1AzgO2f29Ze8LChmDySoFlDJTqVls9ydVxmmzbnYtD9NvWwxEiYJgvpq1D/HG+oNgETIMmphajM8N7sBP2ADDlYb1l64zo3C2c0QwPePWXiu3mrwuEN39UaNspDeonWiaFG4r8jf1LRwQBiwakc4LCi4aZBwhS3gcUQQ56wIBYdGXx6FzPPdNFI3hOTHFkLTRJcnrnBC97Vyi/09xZhVr+SgALNGoPeLLjOeolFoWSOojU0/htCbB5UZA943oqzpBM3DFgxn2DOWrCH0poFkZuAPiCIznGC/EDJz4PdC9T2Dx8yBN44cMwO9T9iYIeRmMWOGQA8NGDObZq9osWagG4WKmYFuFidmCPOgIDGzOfaKEDMDfVh42D5zNIoNM5tg78AwM/D7RYWZwW4WEmYGs3k8mCHc/YLBzIDvHwnWCH6zMDAz0PvGgJlBvxeW3jP6qwb4g4V+NcWjXfAVQV8mI7uIr8qIr4ZFUSRcbTmUxt6sZozVxYo9cKzYQ/FGbaBZgU/2iTLLG4e+TohZxVLuMb6satbDg8vMoTeOLDMAvUdYmQHUfWLKDMDuF1BmALiFaDKDWfYKJTOA2yiOzBDe4ZbEh4sgM5i6RYhNY8f2g9UFjj3ewLGHu9kbRJ3VHoIu5GyfkLOvquFHdDW/Ybt5GG82NNjVh+7cMI3kOMfgkBu2q6mW4d06ge+hnf5Lv4elOHT9RF1XtNyzIl6vIxQVPiDQrTBRIfypEJaURgPBYuzYEm7yMIIyH6teoboKLDLBz4RuD1J1uxAC9k3WMlJL7mRne+F70BoQQgMJbioGm/D9DpMyv06QZ46D+7+WHYYM6wjWzzBxysOlnNWX4yJGN5kBzFs5HmPilGxdGvEWiF9SGjUrdi6Xoanwc3AFKUGasGP0+2L0hKklx+8r4rIMKtguYCulvcmjYy1+Kjrm2ou5WrwHHyV3rLAouVBkyhtd3VPEkB4BjQZfGUrY+mwlMYrtzFMZ79jOFGUxlIdDLwnFbAewPrLzUNg1MaKHgzeLOm1tnqpA1kMnqY+LbWuGujjbQ+cxD949cCbTcOBDpzEJMG5njvJ45UPhV0Q/twC6LI66NdC6qOwWgJdEeB8IWRssfihMTcj5oSCNgtcPncQwKP7AaaoC7FsCrQnWPxCyLu7/QJDVyQOHAjfJSDhwjsrshgNhm6VKtDlJdf5FqzPVZ3QcOF2zXJEDJ6vNPTkQvj6R5UCgxWyYAwFWpNUcCjkL7ZDAvJIZarN+2oFflkF0IPTShKQD4erTmloBWpYi1Q7wXMLVgUB1SVstgExgFT3mBzrKza0ljT3mjU0jLc/AjSItA82aQVoEjlaQluEpbNMS3NTw0SLIvLGjfdCp5tUa7JxZo3W40pjRGmCt9aIt6BqLRWugi1aKlkEnxonW4GaNEm2CbZndcoaINsEmJoi2gKrWh9ZgcutDa+BSy0NrIMvsDG1NkLEwtA0UbQttAVXNCm3B5HaF1qBpDQltQc+YENoCmrUd3AvUxFhwP9DRQNAW6ApjQFtTFEwAbQHOvv3bgsof/21BS1/+rUHMvvjbAlt85rcMmT/w2wKaf9e3BbdlFs286FsGune+XNVbvk1g6XOsQeSE7imuidvlcTgljZYzHZazwTgyPrYQBFpegQmQl2UTG5EGB33p9w4P723UurwAY6/u5couhXKw6Epuz2m0Fxx1fD7wRgQEY8w3zilWLWhfqKt3EEdVpBhUMpaug/eh/CVxATa754yDjotb52Jh+9yDOHJcw4OQTliaG3EfR6UkgeJH6GKtJE4YHBnyBCKl/TjipfIyUXFPv3ZOTndCvoETcsDRaH4URNiiyUWBnx5+N/AZO63j+9A6crGpJnyUGXI4P2Ux6Pjq2+crfbfrPCthdeeDuAfn6Rjm+2CYykRYjR6nK1xzmO7WcdF9c1Ep++zBLkk4h4mckV8fLm/S2r+d3PnG5Y6Sf1LNQ8mHh7BPOlvHOd8+5xRSjOo4KDfgME7Kz95x1HfDUUqAuyFLpR1R2uCpdP6Oqb51pspnDlYzVPbrQ5gpN2/HSN8LIyUZomacJD5vg5XkzB0vfeu8pE8FrmYo3ZhDuEqLQ8da34h/xdgDeQif6rLIK5m0OOAADtXM3rHnNy75dAUDqjmqMOAQjirO3nFUJ/DKky+MeFN+fThjJvN2XNlxZWnqTg1TZj4+hCezs3Ys+a1fvUoRmloOOtj+oczWcc53wznzemdj9uNWOGjeuRq/Ey5Ky0nV8pD89EAOSmbs+Ocb559MzbBK9lG+PIB71Pk65vnWmUfUhavmG/zoEJbhs3Tc8q1zi1L2r5pjkg8P4Zp0to5zune/QZmFGqYsGXYIi5Zh0jHsNy7qsnVBK/lK/fQAXsrM2PHPd8I/vPirEf/Apy3wD87Y8c83zj+ZCr+V7KN8eQD3qPN1zNNpW/mqS9U8iN8cwH18jo7vvnGhVVLwu5p1dGMOYSUtDh1rfeOslS3vXslR6qcHMFJmxo5/vnH+ydXwr2SgzLcHcFB2zo6FOq2qruhiA76UY9rizwSHjk+/J1Enmnw04CsY0BpT4ewdR33jHFXVz6WSs8oHHsBhFdh0nNbdsRXFe6uZNf95BYt69NZZJdlJjSiSn2WuwPrSr2X+wpo6lv/GhWuupVQli2a+PUCEZufsWOgbZyHROKySdfCbA1iGz9GxyjfOKkpbuEp2Sb47gGXSuTq2+dbZRv5bNP6r5p3Mx4cwUHbWjou+cS7S9HesZKTC9wfwUnHujp2+D3YSnTxNOAk/PZyJ+Iwd/3zj/FNo11rJQrmvD+Ci/LwdI33jjGRkXqo1KtWxTWfw+Z64RXZdNuAZ/unBnCNm7Pins5GX9uMyYkfx8eEMKWftWPKeWFLQeQ/ypCMbs2U6tD3GNCz9XsagXe33PwRrGvFkAx7EroLVIhE+OUAQ4gyd+Otu5Fz3ySb9LmBA1+ziD8eMBlzYlOvM2maonx4o+rqGGd8a192vCAwEn80t33WZJQNsaqRVEPhBc6JvWBhCGAQglvz3IUDCGHuWFU/PL2sWrVlAojUj5+8viEVdl9zRkIgRy9g9SmXywvddRj2g6Ge62UL6aBTELDk48A9xsmM3UshDg4DuYG8ittmLBzVyQew/zATZPX5jsFYchH4wV0HkWUrSrS93UtkPIxGWcE3oeCuXdRxTyzHtccZh26hZ+gvfi6jjheSG7Qa31I0Z2VInCIm/JDDiiPyF7UKyoTti8U8JjcjGDyMynh0Ta00DakUsCI/IX2G0/tPRcDxVviXUs/G7BSNss412PJGI7Qa+5+74vBqtKSH37z3m3TqB7/FClMBudszFV78XMbrpPe8xb+V4jOEtCO2SbduBD6j7PsObG/r5NfNW0br3HJDs5+7PL/3e5wGNbSeCwhN8o8uIm7tKsnR+43t+5HuOReRrGQi8Th8zP4S47uf4x8jZsDCimy2hYeisPGaTuzXz4LdrDz4jdyxgxKVhRO4CJ4qYd0Q+sCgO4NMFVEykNmGevfUdLwr78Kfx+xdkG7AtxAg8QUASk2hNI3LnuC7sRzKh7xHL32ycqE9iz2VhSCjsqxUHAVT0hGkBA88Or72lE4RRnzgeuVs71ppYoDNT4rE7FiQLdsIE+NM+soDAik8jkKJxtPYDJ6KRc8vETxGzJZSnR+Sd+AvwTOzx46Ko4tSzrz2buSySw8PnhBL+l/RDsqYh8Xwi1yPgc8TwY8f3wmsPyOUHNgs4YdktfIx/IAEVUoN68JOAcHTt9fJs1O8t/WADfNEDFhnA/qoM3RsPx9PBcDQYza5Gw+eT4fPh8B894DNqv/PcXTnjZd71OanGPSAXL4HyUnQQPGE11sWCDpngOVmejOnx2WgwnS4mg6k1Gg1Oj6fjgTU6paentk3pjGlVD0UxymL5D3jRl+Goe2tp8Ns4njzEk3G/mbh1bOZBQDsLyvFOZLFUsrNLuJAgQn544QnoL3XIH1USF60TJv3f+yVtE/q60uL9QlnnvlrrqZ+pRdDPZdH1q8L/+1lPR18uIPvUMJSgRUJXdBjnJMrvwysv3hi2FsdNqt6NKvLXb9EBywYzRN0KsaighsFwXSGIUj9kBIwSIOPY5yig6fFaOsy1w6fNmPGbZziXetTdRY4F++UMpBY7gDvC9wZL6rhx0Eib3eshoKCRUXAd74KPH+XU3fZmuVcVeEndMNWB8V+fGuusOrTr9Wf+GuGPnSyQgEZs7jobJ5onf9SYWyBBCr9yvBVJPuSiBE+ZThvNcoVLF8zVwH5Dt1uAugz8DcGSQxcvSeSTdbyh3gDud+BSogxKFMPY1c6raMGj8YRNZ8cnA3Z6thiMxvZkQKez48F0fHw8m02nw+FwCLvl+tYNcf2V45FFAL7tpQ+ywvfIM/xrr987Pj4+O51MZ4OFdXoysCejMQd1NjmZno7PJtOT6WnveS9ISEXu1r7LSOhErEq/zqnTwIKOtknjZUSDSK79t5gFDrNRDyZbFjg+qnsbioofDcmHn16QyWRyppNhhqrWcHQ1BD0LVS2wBjkbNreZG9Eicly7IE8cj4TM8j07fCpRRRRDtoKnSEhs59axYb/hJ9AKAqYuQkHX8SK2QoGXoDY5Hg6TE3Q87OO/T4+nw2F/PDsbD4fDTwLPEMij4bYrjgz8yIV/ysxQRBY5mlFrncFaQWpvIaM7aPMU0zm+Q3D7Yy9yNBmyrz5bbhyCys88+0HZYJxlg1JF9W28YYFjwfkV6OUkQ7qjydSOFx1P1WlH40lBKOJ5kITJ8GFfipXMruclpZb2FJ/Dc+yTzIJ6oYefE/w8JIvAv2Eesf07fNiIH3MqU4kgpK5md19gg3l/ySUgh4cmBurtuL4cBc5qBY+shgQ9GQ5B+riuf1cxLf6enXzfCWc44YJqgjeS6RbUa2uyL+KurJgNf29xvtDZxK422TiZUn7Szqyj4fDLFxOmtnzXnzMvCjS9I84VDgYTE7+8uYmSwEAD1uXrOFju5c9e/sTLeYwOMlB4HviuG29LFx35EXW5VW3LggGsNneiOTW2NIgcK3ZpUKpdPBBF+j1AUq8vhfyKwlVgQ6PIJ04UZlYEBkcN9mVayEHIK1wHOykMJhrc38abBQtQ3lhovZKfJipdqj3l6K/RBkZ5tkkm7if7IsloxEmF67jITkVtITlCJRpDCePgY6zC2gy/i6drVt+O1k5YO9e9bLN60Ez1VBXRgzSThopRe/PWKCN8H5G9+PM6nJ9beAIvNCrS1ZqR2HN+i5miJVH+fY2xZbE8W0zG9uTUmi1nJ2O6tNlkMjlm1tBik+EYNaAIPxXzk4uXPRWtH+GR8yE28UfRxNNZRF/qOj5IUiBYYnjnd92GRtaahbrVpAgK24i0neD7C4ko5OCWBnTD9HoZIJH+Dhb3pbOKA/mmACR+kLJQdzZstqTc7fQljxJ5n85bOLDiGa1HSP4KdAnX/l1KFP62BNM+2MAyV38J9cE3pO0fBhOJH2GeAN0ZRxk2+f3aI+Ra2hGue88JNzvwP6MiBH+87u38mKzpLSMLxjyOJLOve9fel6y5eJTS6IXAS+MCEliVmH+vFJtvVLaGCtZPjYfP/hUi41QiSK4AFAioiEYxXE92CVL8AwIfaJFJL50N/exsgFmnZ2c4vfgXvEfl9Jcc2guYriA2FFQScvVyhPuUwpIBLj3U+8C2t/IDEyEuTzsc9BfpsC/97PKLFxsUvkTxB5K03tqS7FNynHrKCX+pAFe3EmWQ8Or9FrMwOgLMmAcmnvqYEHVtr8QYBQHuY84Z4AD8560fgr00YOiHoO48qWNsPh8H8iKB8QJBcPABC/XR6sBk6e/EZkvHA0HFnYBRQJdLx+KeRZSblZROyehsj8LAIuw3MjrC/yk9Eq9S5MyCktQ1X2AcEvhQpee25Gwnzlh/mbsNwECKTtiNb4MDyN7LEDEcFuxReddfuuTXMN1HgS+YukPQqMA/OwhvnC0GDbEgoDAr3jmuj56GOtLEHuja9pz/ex6w5fxkuBxbx5Zln9LpcDaZnVLrhC1Pl9bEPj6ZjSy8f2nEUJNqRPoPySgUJMuyW2fJAuZZTD2k6CaW1+DFS7BPiCNS49DY7GBRpaz0gS17qXavRyjvuq/l5FHFRv5VzFS/h/p3QC/Hu4p45XIIlSFVRXqxpq7LvBV7nGqSJdF7ZKrS93RDXYRhzAj1yAW8ocUzNeEL4vCpbp0Qa13yEImIhL57C8+LsmHbwIGnm99dfd3V11193dX3Fa++VCgVrz9/g0dGPj4e6S0osEzCbB/qNjS3FVAXLrVovdFZ+DD0QwTIYRNVsR6AmQ6s8jnmTYaa8UByfrccaYpFbjTv4bdgSE4e6LUgy/nay8bFiH/SOPKVG6vfW/3b2fb6vUXgR64DISphlOHT82Tet1TY4Qo/FTYpGyeiGRGi6Q4McOIjDH7Jux/Srz99T7rNG7iIdhU7HIfMhhjVSLFodWpKp6Z0akqnpjywmpJk+KnXW1FjwWyeEks5/ga3ViwSBWHBHvscYdna6lXbf1pvrbH777//MnPZn36KrD99dl+syi3PHA8VtZcv/cuXO49uHOtx6lG27Ydzm2PYGRTu7dJ9LzaMknDLLAjUlbsJfr+Ax8L58DNDryn4HAKPumQVOzZzHY+F/Fbi6RUvXD+2ly4Nuou5u5i7i7m7mB/6YoZ7jYiLrXghv0pi/3PClmA34iQYTwav7x1aKyd8wwH1lPvklQydLz70VEw/MyuO5IWxe3fLgsCxdTE5Ke7iUtqJwBxfjjkiVxCV4/PbA4zCsIU8EHqwdlZrFkaQWmiBBLQYocuIBWqITwrJ+Nl/XobNEWdDNfBnXK5rGB+rRH+o0k4kDri2UD4lJaIYcZ2NV3D9lTaeQIzY5+7faXH0VPOGxEfBuHjWWrhdtfkj0opCGHKgOPNagmkSSiCsgXmhEzm3TrTjdVmM8RM8f5kCeI3jdQRTZiGcwRRNWo9t5hTAf0GWoojegAXDSBQf2zUNddpqXholbKDaL+XmyRNrbAQqjDSVEW9Qu7ZfUl3mgwjKQT2YynMQJ/2GcCSPFhSXZX0A0DZeuI41v2GaKF7UwPF3SAfn3GQFu21UmCtMjluFNvSn337c7C4+fo5/iUbB7Wf/fE2Dt2c/ffybxz7++Pn82d9HZ+93u+DVn4b/XXq7vefo/IXtChuorETZQkFPggTV0LtSFgs1OZGYqDxvt+5Outdkx1YO1DSEtw1ZeO7pRCHkifHzgvtRuCpcH3LAldsB06V53Lhnp8Iqc0eYStAm76fSG/FhJWFCr5ZIVRSgSextE7LAijIkuX8xfK4XwnACMPK4RULhn/cV2TltQxENGYLpKPr4zCKcFx+hU6nhCzRkEIGsu9nTyGNZNAtOIl92VrZMT0fTyemUnrGZPT07Gy3OTkcz21pa45k9Xo6WOsEjrqG5LW7LJidCvWi/9Hu+eg80gaOwXbFI2Xfl0hELJtTzUaYmt15nG+psQ51tqLMNPahtSEqjollIp0NVGFq0phGtkaVoXWliQtHM8yjMJ+lBN7WYPKCCrmFB5VpoLgzrdZS8oSalxim1ThfWmB4fj9j0ZGafTYdnp8Pl2WR0shyfspGOVKHlB2werQMWrn23RPjiRyT5KO9GLM1OTJJBcPxVMsnjsNskqLduqnGy3lvYtMYGmswoU+NMgSi6Eq+pXzeJP0rcoMlfNsx24g0W3LmDD/zlUl2TMhHhM6nY/AQFQ174nserhL5w/ccaP4elTeZWgurcAlw7D/C96ejIC8T3Vj5Q6eerq/ckpb681sRO2z7jEeU8bZDKYPE+WcQRcSJemIZffbz+E09cEwCPyE9+gFM8G+OTHv9zos7Xlyl44g9JXUNkAxvr90GYuxORRcDoTUjEy4IjApnJHirbPufDEAzrKbju5dG9PLqXR/fyeOCXB16/JL1/CRe6hYfIn8NHnuP1r3DepXk9WJoX8Xxv4CgpW3+mt/QSRxyc9NUnb3ihRvVPfqCfoksQ667S7irtrtJHcJVq5VPhIn3tr3gm009QK/eF7984DP+z5H6y8AtRWRcEneuvzC11eQgKAJPcpkIAEIKq23G+qIpqI4hPkp2kUhnR+FT4FglkHq+iDAoriP+B3slo+aodCOhdWqbmgH0owjlwNxJga0ZtFtRtS1qYmH9fukE/489igwA1KO51y+Z2zOvJ6EzQiunT9Vck+ZTc8t4NAmV89BbQLe17kVzDogZwEjkjUCIvU5TqWOkDvSNJckQzhioOrWQrroXUsxR+djhHKWAOZChjPsIpG7GR0ebwleyzN8rI6q2pP+5RQL0Q7gDe0uHgY18Orzv+D3j8r5Rt2FMMlIOo5LlH+Vx2fWjphMX0kRcfQ9hOMRwqX98N7nWOr/k7ukLhQk36Lm07dRDkojYhOJKF0YGQMxcK7/XQBsIFbBVRNW8Fc+XE5BbxXVVne+2vSFo5lPBzJe6MzhjRGSM6Y0RnjHhgYwSIJFExBUVunSGiVFIb6LQHv2NKwX2z75msqrjPu6YUQkHXfLQKZueGuVeNo/N4dEpGp2R0SsbXVTIKeoVw3j7ycIGkF2AXM/BgMQMFt35dgIBmhB90lWK7a7G7Frtr8fFei0WpVXZJJo88XY6NBJN8RPglYtQIZek6VhTOIQ1GT8wC9JB3a8c2ScWpE5D54gh7Vp/JrR+zWZTOJbY9h+2SrXqd7Zw/zos9uvPv57L9fpEs4BegiSZHwuQ0K5dJiQNMR1pIFBEjTdxeiXgVk33p99YUeqDwFTSdPLt1PI6Dt6Z3dwOBloYdqjEVHrkyav9MoZ+LwNeEsA0uDw3vaJJq0r3KUU9zUNNjWHVGy/pS5Rrupm3fpaAqTKOTWnqxmO5irilVHjltlp7mjJuKEKkfSzeQPH5aCsjsQzmftFdpmak2t/AblXvUdd8te8//eQAX93/fUwZ+6qRgJwUrVSHgpoUfzbeBH4n0NclNbQrP/I9FSVCSnZjKG+HabihwRDRGJ3E6idNJnEcjcUJmxQGkbT+MrCkIAZOmBWWaToVMqsIsrFbT3oMhxlBX26LRRogi8qMfraWTlQZM5KBT9z95DroonImpqmQb+LeOzewkR1W8Uju9r5PCnRT+o0nhTu/rJE4ncTqJ0+l95Vob4YpZRncTFdI1gkNUYTeRE7oW2ueylz020Ob1hZxQAzUtj5TQdzQcqr2zedNsqMFTimwEnVsKvl3tfJrtDP0Ni9bgVlxQm6zpdss83DO9wVL1AUPpJj8OrLIm4vhbBTZlVZ59TDzXLfXPl+/eEvG79AWLQEKQvI6oL69MzMyowE/Ds+EzKgMJSko6C9wK9ZzF39WySJw0heeI2Ej1FKSl+vPMWVkM7o4G6A++z54BCR41Rafes+C9lj8xZjPeLLi5XH6fdpWHmI983yHNsZgoreZnQ6XTvLo5LCDv84T8wGwnYFb0U+BvXjuhRtqfk0B8QxYUKv1ACxqyiN0bTmnX92/ibT3fasuSn3uqCx+5lEHOFOQ0SQ5WZoHa5dWcuo6i7ZGMf1jGrjuPA6eUX19zqFiCvG8YVYvoRL6IKaAr6nhhVI3UZjeHUUqsCJC6IpS238uVPv8RyC33qnQD/wrZZmY7qISJkHSfDKSPTIf7LWbBbi4WW5UQd8PYFqfDEYSPkMT0A2flQNJIErLSQlrc/+JEl2nhvohGMdywussIRTF+wK+jfNU7Qbma4zccJ7FVk+GoD/+eDCf9yfCkPxmeqmKPTyXvLV50fh4Hrm7bPn54zSWB2D110yJft1kb+jmXQ1aXVVYVYVN3Oqk5hppTYfmeRaMn13hmw+fPnomfjix/c93rk8xRjgPnaEuj9dOKEAqBQzYs57bsTByCugbjerz46VT1sCvecuDjh9cFMaAwhso9jrdyWbUgeJwBh5LMjyLRsvEhWQb+hotw4zij/L36pc+hJPzYGIzkn+8pNvKD5vR1YYtd2GIXttiFLT5451ghigrRisKaKy9W24ElbhyPRryH7IZut4JZsPxq7W7+CF8huH4vjcCvG5VNKehrGtrXQhAjpMlIAMp0dK2Dke9P2086nzRoiMMPuK6ccB2Q0nrJ/WwJxDo4+YKOeORN0vvTr7MFJBoWH+BQimkYhtbIPPKJemWqUCTj7gLHYO8+8O/kKN9kvz/46W5jWfTaEVj8XI7AVyZ2fawfB99i+8ZkcDS3qLVGBosC3zUAEb2AAS/49wU4IYsix1uFxoAuxYACpIg2gHJFsxBQDTYajV/KoSgf6wbdOFvxfZKQrPilok09ERN7shQwP1+9eS3FqdCod2j1eC4fIPAa8HZN/Dmp8AQ3jtGQ7GkxH6YTl8aj84LSeKAqJ40HlcpFYwh5iWg8UArFJgPyotB4rFb+GY/OSL8Go1LhZz7Ib7yHqfgzH5KVfA3GFcVd48EZEdd4dCLaGo1MxZr5MCnYjEdUyLFPJYphjcceh8jGp4FstnWgP0LVS78oj95/5jpqhDltVmqLOjux8CWaBgKwpG+zmWjjn6cOu8bOF1kAiueQ6hYQuxzvRK0PeZuO9JrxYtcFS0HOPJBUpPg93YdCsYrMhsGn+XSc5C/cq6P+JbE/ABOFsWWxsKqW3JqR8/cXxIJ+jfBmFiOWsau1kic2QgE4/wIKJCHkzH25e8puZN5Dgk90zNO9hbq3UPcW6t5C3Vuo3bdQmZOmkPSp2Me11m3F/FwY69jaPwuTYu7v2silFL505vT4+BSxT93DrnvYdQ+77mH3bT7sUsHwdV52GcFU/ZqL3ejCW/pFNC+kA5c78z1666ygKLWonh27kUHAjxUHoV/moYcm4P6SiG/qgdGliFw0E9MIVnXmw3CS/rnypuJzqc0UxErUCAxOPoL0y5IVJQOvefjqoBAZdPgn8UQmNRm5K7euEGPWjavH/N2WBbQ80MOXP6uxHiI4rBxRiUcKvHT+0oA0iLhyrD1os9mJOpUDHkhRQyQRM1GGnzZ+dEPRaS1it3mMEI7R8XeC2e89nj4wgNiggeIRVZWxbHhi6pP0030C3RZZNK2o/D57hhKtKo84x5iH3dMsiYETbbtYSNR/GAZJ44CozWutNw2DKTBV/rj7ymQcuHL0z22bXHJ6/CyrnBatPtX0FEaBGoJmVe/mi8ue6q+0PRWkVdaXo69QifcncJ5hxUX6lRkWjuPDM+wli9pnWC1Bv3GG5dvTmGGBvvszLF4JG/+WPQL+5IhU0SBj04WPS1cssttyoZDZKzWvfqYvqEcYc8oNeo8h5LQmwFRJ+2x+BHFLIM2h4eiPgfPdhZPiwpSMhrRbEI/s9oPEydXFmXZxpl2caRdn+uBxplxGacJME6lc+cz7+OECaqOs1WdpLkmL8qT8hpfBexhWSN2EPyrow+z4oYm+BB/ztK9SXPHnPZDFJK8CthxaDl3+aVHbKehumIxWmcwGA6hiRANsIubhQiNfpLMdlMr+jiOB93LZHmmzmYpMURO60YJVK7WNID0SJOrypwK2Yp/nAdu61GJPtIlefXLde7b0/f8bUsGue88WNLjulWd/AV1MM78Owx2QqkYjfe+ZZBoVDpZ+4/9XnhOjM/ZVtp5jceDeIxDY8aXv/zduOvyjaut5uuehe2+GvECql599/y0Xckzdc3Aw/eyHkXimma7i56ur92Tth1H6TK2pbYAGhiOTJEZARz4bC7i+K5Gb554QiIgpfFmStZp7C/llaeiiMD6uUQ/y8FWiF94PtBjYLIwg1AlOBnxTgoQmQfh0qCToH89mk1lJjj7M/KXyGS4viPwuPNI3OIbHfAsvcD8p92aujeROKhjAkrNgDiHd0dBr8IiHoZdvL76zJ/wlcyEJiyayA4OfAuWo5fK0u0d894jvHvHdI/5hH/EoiopPeCmTNcrDJZdjEPJHLjwb+nbDSp9cvr14SvxbFgSObaC712u2EhZS8PLtRZsakt6VpXFf6daaJVVDdcWY88/TxLKunVVLF3R3x3Z3bHfHdnfsw96xhds1le73/H7Nz/oiI7yLM6fCvYSqe4aBplPvzDs9pbjWFCXMgK9a1w5WRQ04hQdh+8FuEAUUdpi6payqLkx7a1RmxuGGhms/dm0o8C7yrvatd2tyixTQeSGUBa7HQRCjuMRIeokRvMQcb1Wv2G1pGN75gT1vaJ0N8cHMS3tKGFDCzpZBySk2IUeneg/jwJ3bDGrhZY2zC9/eHcGp+uf19XWCLfz3p38OP1VZ5gVO2WsuDlkAsvqQ5QIMkJ73vlqJbP1qP4ovM6vNiT7d0vva/f+UURKQt1K2JIl2k1cItGdZ1Ny9eGku+Cd0OLGPj2cLag2nJ5PJ2WIxmwyZtZhOzujZ0O5lhXW+SRf87XV6bxeNw3gQypRuceOTBVvTW8cPDNwatYLDJyvmQVwU9GN1/VXtBWEuRHJ7rKRBpcVGOSnyJHrvh06pRq+h0d2aBUzR3kSPC/SnaFtcpMZlMVEegw+q+tNwm5CYOLjBTllrCi1sWeCEkWNpLtUX2Q8KUTye1M7hjykGlh9j7WNJE8ezArZhXvZmqCmMjxdfZv7c9EfZMpbLI8t3/SOnvCp0djXFzIXcza4fVnad45odb9VUkOI7h4XKESjSMb1gVUqSi0hqq0mR3hBkHg1VzkgnbFCyF+VuQO/g3XTdowvLvu6V01UsPXe1bJwIEl3g7Q/vFD/W8PV7Fji+jRvrbGB50D3G96C5DCaZpOwltErJUrYT8hL2S991/TuY3YlCsnSCMBJqSHbFGm/QsVrC/E2CLbkS2IILCvErxVvBF8w9Crpy65yQLBhipz0DWqwUn5SCIJ+yJwQcC6NwvmXBvAxDfGyuAxaufRcJLEfxUtYc/xoiS3UuSQ3h5IWtqi8Pr/esfVCx0Cwp8ud18R/ypAFtsemQeGZAoyE4RKnPwglJwCAXzkghLStonKAc+UTxEUEyYe0O4FfKPii0B5rWU74J1acqP2OyY47KHOdck5O5vt62UoVE+LFRn0p6Oi12SuXovlgJpLZDIW4ui/ja/ZT19XdEps2IPteI5+qXyR++1KQBg8g50pb1zt94yQlXH7yA5OvEoKDe0BDmrqMU/8m4XEsL9sNseqOGaueZkcBsm5060sTY2NAGFrIIu3IUnsT5a/YQMxnQ+WtbyiqL1Oca8ao164027k2yTaUMz1k7Y1/K491k01LjkUHRATODEWbPFQ9Po0dRLaXGy/GS0cV4OD4+nZ4NT04XdHo6W56NTk/ORgvb6hVw0j2NQhb9xfFKELtxPLsRToHvR0rchaimAqVxMCMfK5XgF//2vYyvBnHQ4PZ+TXVFotBjAj81wg50vKSp3tIJ2B113XmCmsQaq++4U1mHxz2B5jgwlD8+0soj8s+86kxSxwj/mC9Hk/yQWnn7WYRyZU1yv4o8qnlSV6Zftxz9z+mWZH53acTmSZWR/K9CJ8n9tQyVkHpO5PybFf6+WBYga6YU13MZOeTPonoGP4zZ30ppkf+9QIxs/7MMdhu6ciz+FyfK/3vu2KECLftb2d9TTlAOAmd4zUn4a0Nreu1pGPWKBnR1XtQrLqTyoo9EcyMKKo61pt6KKWrPYpfoRNRDjc5B5XWLj/9bUJyIx1Z4x9f2lJFIprgU0HycYWdcb3sEYWdZMjjqnpqXDlHIn78Zk18+fes+ZvWAJAsW7eM2scsnxH3Nx3w1bAio+hh40kKlb/pT553uvNOdd7rzTmcfG+Ltn/dRp3WbzsOQRW9rW4pRwlUlQuF7nqYPTayELRVVWyVltYoSs+EwVYX1O4BIEfmM02ANdaO0OgdnFmHpsPhX1ej8fu0Rcs2LjF73npPr3ujz589iRb6FTUHt696196XCwMuxqcT1CjHQWvH5BwRwVHL38SUve5M2ITDdbl0Ry/bsX2G2cEbxJ2g8+QxrBYr/3rrUSX74vMl0dhJrIbgY/XIfqaal1KZ8IH2r0IsYKDePBBs0LK+mMlGxV1xDYLy7G2/uljcAqmhmiiNql7P/SspmztRryWuq5IkY/VSb15ljMRAiifW2IZapWCwU7ErBVqOKIDSIflcqMC+k6PxbvO1YcCvaJnIJ3+nAnQ7c6cCdDvx1dWDUVFGsV2nCyq3YtP0qCrtqM9VsqOZWnp2dKf7frGMy23pVQTRTMvWF68f20qUB49SsikLkVlg0TPBICXQLLxhBdRC8qDw6IoVJXrx8S9DAalQloMw1rABELCvW81LiqLMjIiYDURhcWY6lxjaq7RQQMhGgSQq7X1qwAkptZWhVrAFhJauZ+4Lm+xS7ze3cYeXISihTk0nDol62Nlk/KdClLZxpUrQLa5UphK4ruyGKfHU0P4DmgoYVZP9kcuR+caL1/8bUhTtbX2zU6ADygC1qWWwbhcTH0dQlvyWQyRMlVCJ8anBgCaBG3klQCpINTjJ/RWvw6dhNrY37WwUHJDsg60mrGwk488G7HOGfsKPVUR+vyeveNnBuacSuewT/6fkDXNl1Lx0QqkpLTfzjeSbupgyFbBDk3wb8vTJISguW1eoQpNAFQRY+0oc8djLzu5eZpXWj9xCXlNjy7zxFNo2dNJaTLyWESxF0+VdRfLqhqKzBpeM2KTJLspwBvVIKJo8GHVo6//bxsCTidc+CvZ3A+ZYEzgG18R/qFJSh/lg9AflGU48g/qKu7I+z2cQRbwa439lKuY8X/xrQ1eGw0jsQgMZhNAigCJsDFph2EAWYsQehVhH1zO2ZVTCl3tnK6hUdkIMOI+ya1g6eaXRZGwCF/n0P694G/udd23u/jRcuNDdsAVQ42NDPrTN8GFGXDZzlQHS8ax/23dpxWZt0Veb4rqpxvQF/w05z6YknYvrABEWMeiJPpbTGduem6txUnZuqc1M9sJsqItnnvcZZle18d540X8I/gwSC0pxaa5m03KUNm7A4aMjNECA2QQgotSq4QCMZZbbWJifrjfLRCVgORKkzalppNF0hSZZIsPxo4c1clp9cCiIkT15Bjt02cEI2gN1+WleLJL8BPwb+XciCq6vXRWL87N8R1/dWhHfcIgv+bShpjDeV7HLHryHVA8d/3sbBSiTPe34k/ikDxvAT2KH8FH0S+mTtrNbyL+Tq6nVINnRHXEbR34cahiZCrjQlT1YQ05wwZRLyJLV0PCXOkuz8mFhr3w/5Uq97su6byBm57oEYrrGBlOX8vuRYwcS4/aW+WxXD3HQaAZBDMdOrJdwyS8l3WeygIMZ8sZtLCvU1w/lX6mEHRN7oArBwDcqHP6aYV4qCF/JNU1GMhqfUQDUEGSG5DPyNkqcKGcHMdVYOHBGwU4nze4QnRySRM3fJGTKM4P/abMs8O2NzIDn1i3o28EFAfJ6gLGBlrKGNylnwxdaS4y9M6xjnmbjyrssXbYCz53iWG9u8WgsWzBH/TMjFl3nDduqJjUPuC8E3YOZgA5y8N70sThBNE8hPt47FknjB0lIhIQOjRMSkNJDCYUFDlmzLrRM6kR/8EBIOFmNNG1Mcru2XfLwMROTo2gyM2GBAocHG19QCz/YmiKBQB9Lyji0ELRMQhEYRtW5CzA9yGaGyfoFovIbxd0jnhVxz84W8TGY7R4S/yATE+Q1rbr9MmA5BJKwHyu3Kg5RyrNo+55ImnPuBtl66QqMoYDRKKxIkUcBYvoKXgFcsUfKXPgnYigY2qCSSq3EuEq1B/hYGclZvQr0LXA+vBk8u+XrIO1yP2q+UE1nQoPqMfmAYmlskh/wK6GEDvhvHY6DJ18qzElnGkRLzkSdC6ILnJfsLte0BVE53qfe0/rzKKcr3MwsdsOKa1RG5gD1yQvgbkBnlJE0E0YYBn3P4jutEO2JBEf3AoX1V6qAoTsvrQ/n5OLDQI5qZuVG5ILmoL8m9O186LpuHkLWpvWHFZwQ+I/BZlvggE+kKBWEZVto6GeOp/uZ/I6b7Caa7BKwKpY3kGj7l+VKyXCVvZo/yYbdI9RViEjvu3zjNrT/6tbzgwL70ew3LyFeDTWvLy8YIbQAVnQ5U+dkSaBRhl4lTH4qdtQQZaqtlpSHPnDEUirrNKmU/+DUUNUSAv5Lycg2YC2xGc7DIwKO96uWoTIeDEk+mHEz85RG5yv4BPsBUHD4WpJ2iXJXhalD7Si0cwaFXI5YzKwjKlqf0IETMADAvhAVzv5eU1D8lxeoN6WywrXuTSsB+AMJciDWXhMlkQYcNjkdZ6xl+PJTW2A9xPJTpGh8POfZ+jkeaU2Z8PET78prG5e0eDVkdSUfkDd1uRWZJPvSMJjuA4Q4h6lVUfuaEYpmRJGhyRXt2WpCJejtJLQ4lqeTUx8JpIorDbHt0bddTksIjP9sefoC28tzfxtwvXdJevYwJBfKRr9ju5St8BStFW08F34iPkzL9HIwy9sAm96Ycow4Ki5yv45/yZkQvJGehawQ3sLaMGhgx+aeqgURyVfnm1yvXAmpaK83gTmgmy/aWDyV3QsvSwPA+0HVyNtAXtYZYkbCBq4W+XM0vAtnXq5Jj5BzZJmCHcMvHEB8sHBrXh1USCQV5D6W35NLkRgK+gRkjQ4bx0hfNXg8aMXYPHJrNatLlLheN5LpGIoG6bimalbgpG85tyrDdn4rS4dx10dHp6LvMSblwKKkaSgr9dMpsWclR3YNSjm6kS0r6vAbCaARI1jEHJbE4r2930Zp7CMWG70RqMJ6dOdL5yxf1bImZKgV0kzPzFbhVzl7FrWbCScurQo63wKvt32nlnKq94+6BUyV17p9T5X2qb+yZ5iukRttc158mlo2q69WqroeNhfDpStHFG9wZpv4QeQWnk2W9Hgfdxjnvx4r5DXEJfwh5addgdxAiLzgMHgujv82rKQKjYmGR3RuL1wJIRifh9q8Kpnplr1i1xzyXjMrsFSMei+784KbCe36YExsnebwe7AS9B3dfa73WmRIk8yhy9zaepmnXSIMad/grQYZKBuMvKzUCssI7k/OkUGfDfbiBY0XujlCb9zHwyYefXpCT8WTa5ICIOMNsWE8x6qR+MZih/p6uGPQpidZBXHnik/YR6iHC/PctXTGeguKEIVgK8hEAvI/pHmvk+fWAIhE4+vFqbbC0D1AaUhYRLy5LUC1MXH/KmpYM4//BBEQhMIYXp8ovicIHIZN9jwIsRZk4V8GuATEx/pL46GD0XTaA+v5qH4VquaI/tTkJnJ32iPwqTtyv6P4D5zrvSxFz2xzUvyUrJry/fhxxV2F99Fom2QH/4S+XSkCtcpiMAlDE9uIukWSbqrb1A6P2VVlHg3Mimh0IE9OCRXcMojPvfBLGlgWBobdAJ9gSmWUSqgUXeCRJhlvJzw44GB2Luu6uj/Qrn0WA5nCRVxSOAntivqevE5LRcJhkwIF5Ee4E+JxGEdtssdo+tjm3Y0t0OJ+Np6IGDlkwi8aiEjHHSsybn6lPuFpgBYyGPK8EeENdSfUtc5YpMnGc6zKgVpmAPZKNHBoKpA/8ErmMAt9bvYroSnNoNdJV3NviCgIBCzf9qyu6Ik8gejnakYiunkpLF5KZl5PIRMX53i2D0D11vGIcu2P0JvPHJpJMrIxcprBrOP2RZzglxZG/gRSn1NLNkYcYiflWRrPupVqUhsd+6fdEROBBqosS/SlDofb3IcuQNr5zB4UhKQFIHFqQBtnsD1EJmwBl9CDKySdA0oo+l5K3L1yN5pdOgeJ4DhrQfKtoUQdMVNTK0tnwvpdlzPfnYZ2O9IXHp6ttg/aCrV7UCJO/DrhonTMp2veEXbgl4NGAZRgx9nj/BwPAuEQQAHFNA2bPbQdFDg32PzaXCOllCggfOYGzPZASYHHZJncJh4g5ADL95DDIkFryRkJKJsA74LCwIYQOf0wChm4PIe9fkaTfVdqZbK0JhQ9FsCIoqGswiGWif8MkULXLM+vyzFiXZ9blmT2GPLMkxLo20Uy5c3VvPS8tCJ7JK+LPXMPMB9GykGsHcwz+5+iXeKvLXpgCTlKMNosRTypY8XXhRkFnmzDKopxajxp5B8TMSCjyC870Ua5ANZHzipSJDmOukuisY7nuzlwhIqlCRJROOEcEdytkUeZV7Xj/wm7FH0M2OA8H6YTJ09r3uJDGvJ0ki07ecKGBjQxGz7dgMAk0B+jjh9dE/JiEpxWx4fcEtkuCSDqI7RJjQNkEGRuK6+Xjh9chtpbhzg9HyRFAc2BKnuoz+oxnnTz7V/jsP47+FXIvbSIgZHi6RmK8QVTfi/UWjGwZaqiHk+9eVgs1tJ1XuF4x/Q9sW9utu8PDyullqVVNQ4KB+mmVU3zChFU+2Jy3cVx45o/zfJCrXJ5HGMxebqHWqkB7zT0gkV9tBRtXlFodVZRaVT0auHQdgtyM6y+zhKvGMfXw19hAQPboLxfXv2MBWfix0m8NMGmJEj/BxCCgNP5MbEC33e4zPU5oMP2VnxWP6b5wu3NNrS3sjQvRrQWfIMoS1aF3RM6FSdhfkiFm4/wWO7fUxQYMvlTky3MZk1wsDkWtY5iBPRgdDtxfcviYUHjdqyb2MOum0xcHSwuC5Qp/6UMY1I0AEdI0PVp5+lamMMJnWVNu3oeTbOiCLf0gSSxvcjtfJrNUG3WLr+p63OHzgfz+/heRma5+Mekjvn4llywaiBj/e19GOlflGv5apvlwvyA8t0Xua6KPEDBVpCmwMgAl8S1knG/ygMievefvL3gqHlbH5sLd2xFAo9D0l/co91mI6flrCvmDYMoXEbNEOtMbBSfsbV8R0QRpclddLD1eKxa0ycySKI2uj9bMCTg5i9W2y8PdeVlL1fvR8+Cl6/K2jxtmOxRjeULsD7ehK/bsji22oFzgP7beij9uyiLg9yZSmqmW015mighNYo8r48r/WqegqZtSzcEJY/1VVbul71fLU/z2cBZxxGQF9wbxVGVeqZ+F9SqTCIAZqgxektzGsYgd185eZdlJNaq0uv/SVSUKI/R7WyVkoK98WmixUuzHwv/8KbsrRDkKJtxQvTlU6qW5U5JuQPhH2gEecwaBXyU+RGz2vUxizJA4CcQkmQR7AhAsbpa8+X7lgmMgh/4qqNCkBk0S2hbRVcnMb+IwgvoB28DxsK4iOb98cXGRjQllXva5d1z62Evi4HSxofSz0JbGw+IIVEUy0rCCnvgdBjE2p+g+hEznO4SMGeGukHM8m5U+nnFijLKspOhoqBsTmsqI9CYoiAjQEl9VGLfPPdW2jVoAlOmLaSQVBoLkxXxO/iyhK5mgVnlIodHwkQw9igPnaEuj9RH7HDFPGPZMrN3aBR1aSxbWUIM9tW213Zxtp+Vj+1hN1riILCD82OMr0C/4CGIryup7n9u2snMkxqCiQr5kgaCHll2+Tz7hODdWAIGbRC5hbcHsTKEmICG3lgMI8oQD0fefMyG+KjeKlM/60xqvMCsDHu82VuyAQoGKXUgXarITogJ3dxIOOgmCivsdhtIt6M7DPudBsxfNjgQ4AbvzcNB5SP2oTQ+DnvjdSdjnJOR3ofIYfFetV/NFrzkz0TD0LYfbCaQ3oStz3YUfdeFHXfjRIws/QoFdGnqk3MtVtbLKbSu15q3c2ELRE95KIKKr8mJYch11ZqphiYNVKh659aNt4DyGztqesywtP4i1FhPLEK/6gwMIhbEQuAIJUQZFrsJqB62A+uLyEuc0Sqop7Ql7eYn+qWhTXbtAzPnz1ZvXh08KUGDWfxmt88/0ll7iF4fPnMLKhDjA5g7e8N3V7v4jNn0hfo/B7FWbUiRPwRyMquE8YFgntZoHROX6czkW0/kuyQcxtomXuwwG7DjNnG5jfT4vGSCTiXfJqVuQLCR+AaEjAaTb8aJsT368ePG0yapKAPVEBTfmIYtAll5NlWPZI0BWs8dBeIeJvqF49iOfvKHBje3feY3QfCHAvkhwAb1dxJjS7baaC2QQqRIkeb7dlux+pjiKzbYBs7jGpg8PBUC5m1UOcnxvsGFhiM2KernJMeOUfxmJXAK5ni3dzbcsmFsBvasWq3Jh7+mOvIf4WRjRoObLS914FZUg1oSwaRD4wKgLIZ4BeeN7UJwcRMKTDx/flOxyJTYfPr5Rcfg3Dei/jbD4B3y5x4Q4Dp8gG+q4c3+xjEOr5EldZPlXMIi8Swc1qh+XHwxoLH1PlzxfnFrhqZ9gTKMjlRvLq/1GruNBhUws625IgJ/5KPI+GdUEj+JoHsEWUF3MZnH2N/il2a1edpg5DKNjzD8FD34K7oi88THwWtgJsO49wWvq+bNnNrtlLtxk4VHaW/PI8jfPwi1j9jPIXt84/8Zxz9C/Gj7jy392xO07kDgbe1iGZ848K9iV2CqKxHmnjiWvkrGNSkKUwADctr7rhGu9ovAefyMuLB8DOmWCVU3JAyxwkNQ8wH+5fhjCnoj/hIcAuqCVs8xn46883iEsnC/9YE6deRRQtBZUEkyOgqcXD/w7vyByJEFRLOvBUs/3QBnncelLjKMVhXfwktPUsDHIVhdIo6v//IJcSaTFm4yF0RwKWcwX8XLJ9EX/rpTyTFj0IvnWoNAMNmWkgWro83wPDXzpL8vYdbOma91sMv8UiGCItAxCvAesM+hq50F8feuGRXPXLytCnD9aH3AAee3nAjHqt1odyPNorRhUrzkeFT2FLsU35HULx4mFIbe9ubu5PGB3IpAv3vT6Peg2hOHBNgvmvIVH9tWvIpOkAgfzECoNieKBRhcY5s4Eg0sIgBMl+hpdYrrxiE9YRsfL161IpKXLPmNDAnEmeKouPnJEyvg2d1QuL/HRGn6ulkOSMM7KYzasaY15G+TJ5d/+ZKQyl99yeZhG950ekdz9Bwu7Y4uNtZ0rFuny4GTMmAJ5+QtbvHnxniwCB0pB8c/7wqrLzc28nA7k+f8A0heC+KBbjHi2nF+ISmxNmIZPquC8hRY1RYx/jD0bmqYJJGFygp9iTBC0oISqTCCvk2yqtCIQxBRtttFORA4JFTXE6o0I5Ii82zgyhQCTn2RhQpfR22Td1g0JmcsVIxJ7fBfsI/JShikLhilSk3d3amJDgxUOcEoHjfPQE5aIjr2+n4RUi2kgbSGAaDQfxZ+aSjU+LRjZ8ga1ZG/+2bPGWwoArO2Ay5EB74AGpydnd8tuIbmCLXmPu6ctP/w9eYhK8tPzRdA791DnHurcQ5176PG4hzJJzUUP0Y2zfb+moTY/cws/oMZw42xxqewzs2IhW0XWMK/+BhqJDwHTsOU0wl5Vic98G/h2DI8rP//6TWkl1DsrDgJx9yRPS0RPi3SlOwuxD83Rdzwd7nLSIu6F+9yY7UMW8UX1NcxVQ3TjksmCQHVZhkBKsT1VxHTZilo7It9K6ZYaINqg2jQtm6hyniT/wrF6aEXrcYH0GkVL+sLj76V+L6Y/ur51A2YMCpIA6kO+9i20iwPnpQeXQ0xIynEx3wJJWINNeKQ+KhBD34B3aitFmJnzJxF6YENLBEmzsaiZbpWjYz5cDpI80Gg0ChBFHDYfzDKZXPuMD7+z4lOwNClV4BkpsO3z/+qLq6SPGj7vuys3vtPzOz2/0/M7Pf/r6vkgvrSq/Qd5vVTkrYsB5OJlrgUckh/+6oisPPllOyp1UaPWJb9PT0fTyemUnrGZPT07Gy3OTkcz21pa45k9Xo5A1vZOqXW6sMb0+HjEpicz+2w6PDsdLs8mo5Pl+JSN9ur+ll09q1/8Xk+BC1v7CLh4ybVhRKIBAikr1tJEOQqxa96JhXNUQbdv1kMur8NklRNdpaBWOW/Ph6hGecoqRTXcpByyNo4PKCPijSsqsLf1ODVgSnNGrD3ARQI34kVW/766CqgXgnCVDkjwEz/OB1ckUZ0nHlyM7nwEb7AsYTBQZUN1Lcy5Qss9KBhbAp+RZGXcEuXLBqLlDWcSFQhgvKGavuQpEt9VNso5lj+jImYvSzdRGqPzM3Tvj+790b0/HsX7I7lfSRLhg6Kr8CT5GLhvReWTkvjOc4jqIpmPCL8Q6jMvQsvfllQ1xJ8kHWEGT52hRjyAFpZVDpU/LfyI1/jxMuV9LhGXLxKu9pzvOEoFdKQ6wauopYGi1WimwY2qFqv+MVhak7PT48zOAbj8hke8Vgwnp/JxYWcye/sP3wMRpy95idqZUCBlR6bq5ZwtR6eTs8XxaDa2x2en1KLHU2vKzobHi2N7eDJVrlGYmVy85Nhs5nTrDOT1OLD8zYbzWTXv8PZC9UJlMxexOaLYkPjvhuNEc6aKKB1ROg9yjlDqixHLuCS+XA21ye+nnK0vV6kg/qmcaIMlddw4MFCSU+KlYSW/93hZ2pPhcJLM13vee+uTwI9F4A4/jRe9L5/yYtKUmoNxfh9SFD41BROwUBSXKxgk+HnyYtf91O/B/wOdKXlp3N9+igwoMT/+qyCgq/Y3WVSy0XHkz6HilLbf7cVSBDTZvPOXkr0Ves52yyJ4l2Yy4kTBa8arZPlYynaAcofZJDRN8/k8oLHtRBmqAroW1mkbgJQZiDiben5c+5mvNNJF/BeEgfdkT2LolVa9g8Iaw+Mclb7dYaJ7YnnPBcPgWUbDOMioaGXntd9zwvkW+ppVBe4lCECwWozVOAMIQTNgIPBU0WgdKkQpGAiqQsT+A7SC7I7AzprvSJ7r6s5l5nvMjAgNNL7NfC16uMP9AhWlTMYk3+aWaKDdb+aJsi5vH5Zw8e/1244DIEwxkb1/sJtKlbk5IwJGb/JfSzXAfW660ghZabbwgzRc9MPHN1mrHJTBX2D7X5vHu+ADTWVXOJ/COgZLPET4Sa4vKlTwC8ZMKL0cVwHdlQreGhlYjgN/5JZDCeLq0TKQVXPXJL9V4zkcT9hoOFtOmcWWp9Q+s+hkRE8nJ2N7aE1mk2zw62RcgU2IJJ0HbMU+V4ZIp+aDhNKyrE/AVrFLg1yBmdobvAwn14k0t47BPYxmDohAXrDsFXzrhJACqNSafvVRi2IZSqqs2MucLC2XYCvL3iSfclMMxlWT5BLrRZsD8XVatl2tgz8EE55vxRvmRfhGmceBq73eEpVU81vox4FlIIu3PkZha2B8yYsmxD6dtVA2Xm/C1lAOK9WgQhSa3782c1kE+aQl7sCM0ys9tOir4GP39y1scFpVFHxRA18qPSaYJoK3MYhlbnqowuRQPdDozi8sJ6dANtP2HkJ1K96bUtXxA8gxWmjKYlzxwE0g547fd+Dv8YNI2PXFLuEFXVeGFfYhNUqIf0otS3L2Vptx+oL74TAFBX1gwhu6pSvHw9JM5ah48WaRbewwknOxoGS+tzgG4CF5eW5iFAdoleFYmM41FJPxj7k0rD2plh97JZd+5EfUJV4OQVlLTKFTdXMLxKt9YutmgolKKQ1LEg1NCosypXrZ8pBU86a0rOnAMksAb8vLdecB46fVgCcFi4I8nYGRj3Lf54qJepl4HkDbWDDRx8HO9uTZS7lsR9Y++GO9ZDH3+37XT5rcCzofcLQODXev5jrRz527YYAlHR9irBUAOpEIWWRFeCq/Dxw7tUTyVgF/4Edx9bL3PEMF5dTk3SxMcN3GmPSVEaJ7XzpXvpuveA4oOfeou4scK8xr7dWSeTk6ATcKHSzpkg2mx9PJYLFYWIMpHTJ7urROp6NZxePQTG8/9LXQUyVCqHomXDetjPIHZb3qZRtmFMidbJJIIMaw6AARIiaq2braLHYlDg5aw/HvzUztxjITCrRlVQ80FYNi1OhVeZgxWoOJoUhA4jyUVNhIj0B3QZheEJs5kGzPS0IMrqev4o+oQyn51viYOHZPbSdZ9/mtaKQoVmG2gkN9R/t7cx5CkPZ7QAVT8ZB8m4zzb5hBFXM5Er+GsdyIbDRQfJrZte6cG5/zvc840jmiqwFoVp2DMA//tdA3s/ceEA3LECtG7EOU0fTAHbSF3XExU173k4V7742cqk6bQq4yVaUM/JVlalRWpBthhV/fK0Ld80vLwXuJEnERZPwBtaqC8vlejJ7e9fmAB3BK2hrncjU//df/NRiotU+zXDkY/M9/8VkwwvW/f9j4NkRPkzCw/vsHWZUTOr47llKR0/FCZ7WOQqzMuWDU8r2jjeMd/Sv8gdg0ogNrOeB//u8ffr/uIdtf956T697Cmg7p2B4tZqeT6XQ2oQt6OrNGizM6Gc6mNr3uffnhf/7rGcfpfxD5V55duYCKE5GqiJonYG3o/WgqQ+9nz8cQen80Gk+mM10AfikC/moFlrh4Y+7+Len3jhXzMaSFOXhIFoy888As/W6pqTSSKcrnpQohd8s+cESYYiKofdYkCS6N48hkdEbd9/jdwU/9km2SXjk4M+gHw6ikD+gfC8k7rw/b1Ydte0O9mLq1O1fOXIBTp3PW6pxApryWWegWVLysD9JEc+zS8BJQGbOoV+B67lm/CZnlQ0XY3cD2wjm10Dmbs2pVTDqiJ5PjsT07OaHH1mQ4OqPTk+nSPl5OT2en44mhAM0j4dazdr0hJAs0XdFggoaU7RxjohtCkaO+9HvS4Gg+GkYMpgVtwYEMLoSmoPWpSBZ35Wv45PLiTwR+CpxovakJ+NhQaxCu6Ww0PjJjh2z6QdtaZnayfURQOYT7FUbZ2vlF5XG/YJJcjIKIq8gXtIQwUhbcOpYaUKKPqTEPJ9k/bsckZkeupGmszrg+aARpJuHTW+pgwAYuy48hGx+KltHAWisJ2DVzDocmESXpPvHYEvxUFoUAWRMwGScdZlR3rf+9+WO58qS2mV313ZzStgn8aDOxzHbMOCOrHNz3nplVwQLlFkNzUuoObXFWeGEFbBmwcD3nP2no9rN/R/xlxDwSrv3YtQklCRiuRwIcIuBAtDwNbEg1BgH28u0lefvu6uKnvx9de2/9iAckWShIgQu3gbORcKqF5+nxFEKJknoF4t9JKPhEH2iUX7NscsOLLLBg3vaT57uRaaYuj3r6ApDDRGQZ1PK3jfwS39BxyOvYqNxWrc+KTkW2kS5re+Eg/Uv6XzCNoV1EcwobHHYdBCOPbtlDZv9HCNbIZKzpOeFDqp4v/Iu+nlxFjuEmoO6Y39Mx15D38FNeAvTeDrmsg2Nyxpd+YLGOi9rlooSoh/NOdn8yWWbdDrWzQ1AyoZ090p7qXyCvln9CPy8D8lvMgp3SpSWbZdvPFMXCGgUkdGD1hJ/06qP/7i/NTj1ffhXOnh9B99vHgLVjd4LK5Bjclxl4j/iE0g3sJNlX2UKUde1t4qTbxK+xiZMWNtHMWzU+PrNPwTM1mZ7MLDqejqwpO5kMF2x8erwYD/fyVmXYsXL64zPLHrHRcEqXE3bM7Im1mEyny/HxZGkP7Rk9dPpJzeony+XsbHo2O16Oh9aYnoxHx8NjdjY9mc7oKd1z+m2REy/e306fXby/PSbUtgNhY5IKvx8ohil4NfLmZn1onMc8G4tfe+QO6lrz1wN2gWP8kobCojxPjvyUt0vxLy/e8/qTos7pxXtZ2kw3qRpsgrl43AhG4q3v8dlFez8+XdagVjehRK5iupB5Njn/208fnl387acPSZu82izO0dn4aHg0PjJ06qquzlx6kOv6d8wmxR3DAQb7Foo6LPlURmm8Fo4Q4VeGj5FGHLwTJhnsFDAhaTFwuRUX77n/K097qLIMvykkRRChjp6YUVo0ZJIXFy8/8JbjWIVSYJJkP/tL8mw8xYFAIJzz2XHyh2NUEcEjesvcnemOPRufmm3a52Ug3tq6EDG0zeIqk+c1tKf2Ld/ty0qYQF+gxhGBM60adbHbZIage2e7ltxUXfkQ4/IhGvNcYcOxliL8VM1md3d3R0qWk5mTH6MSNM8mjCy4YTuDeaPQWR1ZcRj5GxYcWcsGE09KvKui8xRKUlYX+7LZDeCjwch83mn9vNSqidna7AbUcg1nBQQfIqylaUALjsoKmwbDlYH7h8Qg5tBOvaE5GkaAqz50VvOmhJODyq3ZxbOZmMxLe9uBnhLR1d4RZVWmfiW330CVGw7PxsPl5NRiwxNrzMbLqb2cDRej5fHIno7OpiCr1IrDaXTPQDK8yIMq0rxAAXAgwi/3oOhVeRtnE5ODl9S96gKYugCmLoDp/gKYDs3GKAro5kG1tUe/M9V1h787/I/98KOyfA+HvzPxdoe/O/yP/PBD/seBZz9kVqDLrUSbBv+xpm0HXZ6c0ZPT4XQxnE4mJ9aZdQw9cE4WbHk2OhvSERsdn5wtZrY9nNinlI6GyxNqT2dsRM9sujgbL6ajk9OzY2s0s6f2cHhinVgjeHjNJqf2mM7s4ZItlzazrBk9WQ7ZyJqdDK0lPRkOTycnFu8Hw7zQibCknvZlw2NQ5+Jwzf04Wvmix097XtJHGmNWMLWVU6dzsrcYayLU8oMOZ3ZjOo28pa0RSlObW9PpS+1sDb/SWtyZedLrqtugfWMW7i+mGzsvMhurEjQUrw6/OUV1rAMgHHbny06GByDwNdQGcPLRecgCh9aWL8idr3TcoeEo+aOq6mXdUd3rqH77BwqbNEpffdAdrL0OVgYFTTtJ/E193q4ZuXx3npghVs4t8/I5B7p39OhsNBxPzZLV5EbqW8bi3JRAoIgD1c3ZLfNq3p4w/WA0HIynV6OT58Oz59Px0enp5Gx4+n+Go+fDoZG7GfX0+itQ1BRocOXBiINOA2/qt6ereCzeeUF9lUStRaDqYSk+6XOqFNlP8TPrajDE0RqWaPFmoTIgCgOcgAeyuTDOMukCrm8X3ChssIQdAhaFgzDyAza/xH9dYgZOMbAlbQIiXLM93tb8lmGPbGg0Y3OHcd08+gIiOX85/4aYdpo6O5017DSVjWMsInnvZS2Uyfa8n0sgdLbhzjb8bdmGm9/45Se15bIW38cpbZvAj7mshcGONSlrUQLuD1DWoowF9i5rUXNoC7PC35lO9P0UMIZN6yP2OSL8twVEi4ko/lrXDVxWhC5ATG52JFHq6nUX/kTkmtI7vmxNuHKCtjlB5CBztVcZzP+VPOGw/XtD0STGmJaEzw6WxeGzvCZUZv5jiS+mSFr47zLK7kEZ/L+cMDr0TNHSN7TwFIbDoyo+1jFfbYHR8WQwPBuMR1ej0+ez4+eT8dHxeHo8GZtWGM2iLdtGtu/Z+j5uxPJKkR+45uKEBGQ33kWcmATIhS83VY1KyJlvBHfIlcsn5GIm/JAWZs1jij+QhW/vEM9F7N5wZEEYCpA6XPOuXw3RZcFMwd3pYw2Dlw/vLppdcGkY82Rpn86WJ9PFZHwyHS9Hi+XyeEpPZ8PhmW3T4UmvcMU5tpaiMWa2fNeyez8BV/UMv9RtfvXVWrthNS9xE+HmeGsW8C/mKcGKDxU34WF8NEL6HY2wajJ03sZocg4YS/Dicb/LSXUxVUjgf3H2H0LC5zwil/AB1gTAsY4HVUt4/2lfjiR0RR3viJx7BPvFc6RcFoXE8yVmAh+N8lI4U9IKc+cHN6KQjjNf0Yjd4Xc2+4yGGSFsLN+D8H3+4R1b8AehwhXazrNmsDPginquXs53SV9Nkr5UCgpvm5kiIr9+BJoIHoj7lbr7CE2NDDlU+a0RtL/FfkTrLCpiiEgu40ZQbJMWOZHLs0/jsMb8Ve6SyGPT6YedXbOzaz5IzGtTjTD8CIz/TnZ9P+Q10YqKdETebRxUd3xPvHNBaUr0alXlwcsopyt91/pPkeSKVl+bRGxisXrz9/n5+4v5X179vXixiMk6WX54PF6Bqu0cwHvVfgy7JOrNWqZu+tK3uqqXNuAFOeprvZn16l+YOL/NIWXc5giDE2kfQ2Wm9FhFFIKcIt18ZSOSZdS//cW/7jn/+fuSIp1G2GmEXzMLqvyKauGOymidhZtKfNMMyRgg/i+8NsvuUgHVQFzVGyzhC+OoIYN+SAfbKhUPVL0iCN9Woyykwvzz/IbtwjISdapgJ8Q7If7InvWKZ/tAUV3lI0+jK5uhp4nK/Apvi0fzwiiPG1AVcY32bXiLdTp3J647cf0t6twZMX6QHI9D7fYaOYQszmvujsRhttz8vg6hgp5euFoSB5Y5tfiQL/1estaGD4eC+OV/7Qtk6qVtSWdeIDL+lDPCkjeisuvxlPzF+ZE8OZ71Z5NjsthFLHx6RN76YOoGGznaxp2Q/HAXQDd333N3P5BBIv48BuV8A9HqFz/G+f4TTOjsswNFZ2EM2M1TczpeIztN6I7mKQAxlNhMe8A/H4zGuRfL8Ww2Oe73EMHsq0VbNiIOnGg3sBg4ueevPkcs8Kh7vnU+iJvqRRJcXbOJGUDloZ5m8/2UhhofOG0StWw2/WUS57r3vCJUVjOfOMoXJlpNZmBWNyoBC9ZI9sH4ERgwGD63ITDAA0cCJvZQqZKU3/NSIME1z4G4O5IMh6wmKKtMiYAs+mA/kRWdw7V/J27gdEayoJ7HgqcGwc5o+6VJwyF9bAQi63sDm22gOjP8L9AWOtvDf1GPl3cWIBKlQJajrm86nb8DMhj1K4n7SbeF95rPkJlqT82wFMYjz2kwlg+PMKvBaN+a5DWUAvwDZDbUCuzmuQ37XHmokb32DXJweY8Be05LmqhBEFcY0c02jV/kQ4hvoaZoHgimUxTl9IudfnpqRcjbNCIbajNl/iPyQ7gLI7b5gSc5x5G/wYtBdE3AwEsK7v/AuIs9B1iGKteLjdW+pcOgE+oyEvwp0X6LAZ3qNxjf7zJaQszscdAjh4Dmgpp65PhcSEqckH+rJYgIhBDOPlCxWTC3XBqGkEUuLhg9IroM5Y8fL17enqixvslVCOOJ66/g+RXs+shuAz+wWR1jxbFT1pXPCcOY6VOlof/DS7lBjhc6q7VQt3OYkIC5NGJl3TB0024Dduv4cdiQQRaQb8QMOMTzIyLncHe5F2ojZuGpBlTX2+HdVnTASL6Bzg63jq3oLwLNPSeHTPTSzcE09YuXhIahbzl4nMEsoG6X6CexDVgIFhGZ3D5w2S1z5Ufq+yaN702Yx/Gi46l2G79UCFNzrfcPqDO1YArR32Bf2jLVZWwfiJM0/QjJrrf9pOyT2pv+f/bedTtxZFsTfRW1x9ijqrptpyTANrl7ndO2udhOg41AYNhZAwdSADJCUkrCXHrl8/RLnH/9YmfMiNAVSQjszMpay2uPXWkg7jFjxox5+WaJXgeOmWAnfLDQtwVp0zEDRmdAOGFcj8ZdjggNezcrpJGxMTivzU1fFZXwVM9U4XUiasf4jD113s4JHqKAimxgyjbcGipx6qNqJzdZf5o9OiFV5xQZgKo5c81x6HW4UwLM02KWefjHGYZzjQyuvN1H4+1LMkXOEK9cbKhYHYILJF5lbvIyxGq8+3aKIKeljuwJ5iy01k3ExBJGbg43xq4yhUCzVw3RE0p74rChklCJgxMGaeGpZ17nVIogQs/eihSoek1q+g3RLg9opwMViWGArFSOTcYutfkM59idmgk3bYWGNbMzSEv5ubBodf+2zSTmHmbFiYGDDp6zFzoGnc0Y29hQYBfnC93VIIHp7aOX4gs7nKrZWAGtDuPCpF5a7h4iNbhokm/32J1h6q94CMk88u65V8ej6jx1HNDGau46qbwnSN+by6Pjo4apQpQnPIWubQ2wevRUWBvNiIQN7f+wCiKP9qE4Vivir7h9vXj3ZZBSOyyfZWuWPVwfb2n8L9japyP9LHzbwV4zWvjae/8p+6aFTXoL7TkmaOI62kKi4BniI5m5FZG+RGsHmh1OXddyINFwSE2Y+wIhXWVH0h3OBkNO8BAcpJi2OlSRMdEZ4FPWHJLki4A5Zhw8GKWuIUPBw1fN1OlaHx/hOdL0odciWUvLdLAKEqaNHNdeKC5o646PNIOUAlM6xcvymlhiNBtGUbdoUEBQaugsJhPsZL2WUyf1vpvg3SGhPci3MkkL/xFweVDAZWQNDbxsK8jIH3/vuMgmoffICFkcwCBwyrUJut+aCwQNUH2F5BdiEAFPdGqOVJBBlGPsYQ9N0vgZOiFaGhmQ0pK2wkGb5GpGxvphTDTSsTj/95Bx4t4wQZsJttjkEbxZXEscA201cRBBztDH0HCYABornkkIeVULsDOJ6pNLgzPp0zNBz6YZmkvVKYRkMq9otYTLRVy8OCnxxfFJEZ2PT9CFUjzBvKqImC/h0ljMrTtJfqNSitWYAKoc6NyS9DRMHILtGti+dBzsUgSO27foEZrZOoTUx/WW8in02g5xQv5w1cKP0SdIvi7By0y7l05hx7Rpk/QCCN8HQEuZZyvKoWGnQpNIOmmMDKo03DkZ/akTWGd/g1coAimAo5pFb7lZOxyZIr3os8+TZeO5tpiHpJIRcrCuGSSdBPsxp3zAOr+lovY1DPRDK3kgxnMmeaWwgj2VUluSBDTzZvsyI4I2dkEicHJs/C4fhhS6pvAABzovpKxH7kOdJfvHVqCOP07BTzgFvwwZMWXBgj6yUhQVSc5EoHkcYWxwc0AOCRuX2LBPuWdPD/HMzTHx4KGFyR6MzYWhHnPP8DYlf3uFwjOfElsdR5+4QTZnMgJSd0hynoerhsdnmCzJvGt6PccGeUw8jZ4ZWLLXTrAkrBmXI288QE/m1l6UPbGoeYb82B6pmkM2Kfs68/U0wX0W+spfGfI3nSm5mSmwc+I19z3t4L8vn3w0nQ828U7B7Jn30Zv3DduPyc8Gz1t52+E+20090cSVJX0mDMo21YXiZmo98qiLw2owb1lUI3kh4K3WSob2IV9zYBAF8RoOMHDWqGYAYMR8J0RQPHO6NteAA8BqeTwH/haLJ1NzYXO2qYM6jltqhmoud8P7+c77u8ytsYFxNuiZDOgq9nzyRrI1gqQtpNrYFFeC9M6Dx/AbOi9se48TBhgsSdqO0nj+H/3if6d3PrUE2O4ODzEOnIqmmjL1+6bMiFY9hoWWatdcoVAoc5RkD4MPOzvhiydCoSMWPpfKn0vlwWGmitTFYReaZsB5n9ge0gu7RhOuJLY3kVUKUBJSKMABBMz8BJA3OCKFd3iuzNsL5AFxxtnG4bibu4h926uAjMyPuUhaMPa5s0qUX+MhijPDXOpYncADP5NZB55ktpbTwyvEu4mN4vOnT+yrU8Wcf5oiXT8xxydjNMenU3euk/koyDANYuv74YNZLpen4QGdLrGun8CKGP7mnLor6qxK8IuUTH+dt40KLAmu+dnr+H+FRgaNYf3z/xBORF44KZVKJzyNMEla1oAg6IiDpQ09SA55RGBDsddWLDpyv0XYTRTWxDqZYbrs5Kb/XFJFtXCORudnavFcLZydDk0LG9bEgmKhqv8vdPWPh8dq87H+COhMx0esYHFs2Z9LY1HFpZIoKGcFdMELaFQqK8rojC+oxbKKi8WRWBZ4fkxXamWBY8WbDJ9TzY6mEfsJR+rFHDnBflumrinrnzsCVXMU3XQWNj6h3YeGQ3wcIJuWjozJImYTS7hxsXHMgWPy2M6tP/e8C1oLbK8fIRwya/re/aUTf4N54G+ghPwN9lyUWFuJLHqKVHN5Yzp5cqmxkTCPie0bm70mTny301ANYrZ6XhiEpT3Th+zCCEJITZtbGPDwnhjaZtdDdqpNpqE7n7UKy6nqsGZs4lilyltSPEVNC0RivoLPcqKU5MOoeiqCsWY7LhfUIj9OTedwqah8Ipx1BP5zgf/M86eCWBiknWLTgVfakC1vgpUBNsEcQbwyVjlW3LMV2jt2IHvFq/Qv7oY2mjFCL6w+va1XyziN3iiJTlzWkDkcJc8zcEgKpuxJ0Gn7EV76wil/KgiF01K2E9kuSxJ1guHangvVNTlXvjNzojs0GR73yNygSbynZoRdoempPIFynBcyktMv2p9iMWyZeqtG19/YyL4kkORxhEvEj1c2B9rjYfVvruJ5kz3Ew5UYuvbCUFLTWGyphW1smfBO8gKdyS9AwKoJGoHfHELXXNABmbHfycF+n7T51BsnGEEIugHiqxkL3BEvvZsR4ajZ8QD1Wthw+T1050fn8+jbzemRYKPnqsTBg2RyYMZHTwH0fs+9QAr4ng8DIgRFEBps+F4cYQMjxvDo/uzJwAp8Dg4W1T4Hy+yTTXQ23vocJ5+DBGyRA7Y77q7wVqUqXeGBaeRzE3+7OLO1XT9IoEk72Ze+JBkaGDvjhPlo1EjCdIDbBqmDzjld5iEQ8u5rP2GA9ARskz0dMvXmyBjzT7/T/QOyPfH89zZQ5ce9/fe8t017ggxtQ2wQvzketb77/f2X3Z/EgvkT70/CoQ+9P6nhOMRO0s3tP+Hy/Pvfmb4zcfyAmNwEG0QhokZjU58V3VyoYx3Z+Jms/rX/+SSo4j3sjjkTTtpSYxj1nhdC5iUU9BB2dA9/aWvODLQgud3O6UTfzec8iCIJO5wHI0xc6yC84033b3Kz7zc1L5wkoa+FBQLNZQQnx/fv3m3jy8CaqRqeeov5aDBLZh5vmp2HNtp30t4kxKtsx/g7IMjgsQZPpmh4TMgLmZ2Sa2RAdvLfCMMfWiYFjPrtmPsNbOKWOwQKho/kePzm59DKPhjR1kKHY+uHUC+gVYdOjo4TwUfyUdn2AsmEFnKoQ989kCgzvF/yo/r9YP7oVnkQBBIjEKrhixUCaLLwRsH2sK3KB5aQdHoINALxaP0QBd8aaP8+3quhnFU5tnQr3OGtty8IM28GMZsj23WmBBwlUxHs6SaBlMNKYeovYNraRDMIhifspsnZC4ObYqS7U06ZYmUGgHvZzClmm027vsLjjUL9vDuSa6irgw5ESv2AOoNgoe24mbjPVICxGKFpKBqzuP75lyPF5l2VcLXDMaXSKeJd8dt+ODXkrR2ZJKv+CwPA7bNZvy4KXI7dz48At5MU4nP/5dDf/ALBThyw/P7iwYp5s4fZhabkgU1mklsmaf0UfhvqHPQfuwk4yV8xgEjx7lUC9+RQv+G8MFseHPow6RVyjxyXOiSy/HKk6bfnLRWKJ7xwwgsdvvRZ9DTSxdIgAfNqdx6PbdT3+BorSJmSVBsgcAwJNNz2XPvmws+mdw0VOIlW4K6hAkH/JX+swac1UuKYGy1c+J6bLxw30N+Tp2Wk5Cl3a3BzYpJDDviukHVdaroODzh4d0IYuePFUmgGJxY5cKJ1Tjk2QFBY2/iEPjBjI11ONZ3tlWWbQPXwuDCNiQkUwX3B2AJl91wzmOZxHbS5MFQTxDUFgth12oifRz3Jd5nopgBMfXuxUug3i80tDJAX1SH9PLTxeCiOSvi8VCryRVQcjdXzi7IolgUFl8+VYvnsQj369yXfITbUoZsifLMZM8Uywd1zE0na394gtOXQNMQCf8KLHUH8zEfXY5dUnjQ3P99C/L2UCoqcdhN+nPD9TvjHiX6PEw0SkHc680p2GWfcixl4hxb9dpib/254id0NuimJV+hPobH/SfVUeYf4XqyNRRK8kbHx78HY/CXPDqzwEU0zJ5atH7k1TkIhF57mNvrtdRCIkWM+oJcZ2niimUmxD5chYAlShALKsyCWBA0Pg2WlwZaBVYdySktTZgBGj8cIECRpk1mGwdhDpnnZ+Mz1AGbBNrimabtT7nKObU1Bx1yV/FhFiT/2qnJQsboAjnfMVeFLr4L3ZbMNzZDq8HXbXITbaZNfyZcJvz5cf+YeFIwMDR1zjepnrqGpqo5JH8dc87L22RvXmDUHX7FG2Fe3zc8c4ALCr9XLtvczNMFdOvB1k3xNGwp9fXl/P5Sq9duHZvszwaTxNuz3K7l926y22yQettrsVKVH6bZd5ZSF45pzbNM0GATu3yMoWOmj46Mq/adXleED+S+sz9HxUZv+83ANgG1V+P6yBl+T/9424c/qZRu+p/+ERrcr9zPrDbrOa2cI07NJoKjAgjEEPcLOHDehChyp4OEr+rkTwvTt4RATAwBcUcTHlBZwTW5h0L/XiSZkRvfp0Jwp82Av3d35esJz8Su9ZT7vNZvIoLd5zHQxR8YJ3MBENAr97LHM8JizOeRNeHagbNhfpcz0T5ApwkkacJixs7IcLQtw1CyGTnMSqSFhxEc5s1qGRkjbpRx3tyAdUunnVi+yKgR7PnZD5BYsIhVpLNX22czd2lblWIuRU3JIq0EDQd69YQ5rY6i5ADsxvqffY6+W/G2GqwGE/RZx5m0oVvM7jSNjkH37NBSuli/FYKhy1PJE4OVeadRf7ha8OtuvinfZp1zJCkONeVnQbeza2n7k51XJn/k8VNkJMp4vHItgDe9V3a8E6k3lEEII1WLAoeZiLyuGV8VXsO5RdW2xQNk00kzwWvPy5HEOhVZT4JJDBnfT6TzCExr+baddNmncVdfN5dBDwNzutWISZ9RXpGvwHqHuBFCdOArgAGckci8v4OYmw0nUzfuXb5Yz4MoimMNDgEdMunZBk3ECA2epyDhnMTqhFxSsi26a9Ab1kIeZ/obALZ5yt2P2WKcVmJ8ww34JmYM9Hckc2TOscij3vRgo+DNnB/aGFMnIK0P31x8/qcH9jk8np9zXI5Hnvx79QRQopgoIEJAWJfh1tfp6RFOn6Dqr6aNMkigj8Y8dQsoOAIyo9CuuVkfHRwVeBOHX3+X/glHmFYfHJqFIG1Po6IS1qZESnF/Cy6LBdszLmYe4wmrlyTMw9YNJcYpRahAd2xuK5EkLUihObPjQE5GV5W6JVzq47s3nhIMRbZiDXQ6RoDnWCjdae0/NUw56Is5XlxMQ21gJpkEbYQ48QW1NVXGiTjxk6aLxm/8VcbL78/jo6eTSsk5uKwSxZKRAnPafqR7i24amTFtOzPa0bfpLQzD3l5eBl8MLxQlMcLuEan9nj+rVTuh1SD/dVC8raRoGC4E5NfFIMmh6zkLhJwbjemiCNGNXPOEnWiUywE9p2WZMO8Ev+NG0Xe/ZBNph0zAYomvi0nAV2g8hywuenBaAj9Uc/+IoFgvxr9vZr6aLNE/hbcNusvT0E3Mr7Ps8CUt12yTg/cqNsLsEmDGMlGlsxdtT8KO3/bION0drbgKX1LeFpsywDbeN72sX52Aez/JyXIGWn9xDmgGCvYM5kk7BNMKVkMMtsfdwhKeyD8ivm6yb7C09S0vzmmTqP9DT1jeiUH+ZLQTluFyacO07U0L+4Mblmh4ozjqB7EkGIaRbU2QsiI4LFtRGCkhQx9x0bU0x3BKGCiYIbDsKpNUm0TdEJtoVWU79xE6EHC/ybxDXH371fjx6f8Sj931eqO/0qnzjy/AvesX9+77EorYiFsHuHak4b/LZ2IfH5ofH5vBdEpcl58gKBap7AN1w72gKzkzYTmTYJHDF631Q2Hd2kQon3swD3ZjVvMjnC47zmg/QYWBS5sLlkAHZE5GtTCHgiilOsrvk+S2FTIidZlkuWDGijnFdyLMATz9QUBDgD46xJ89cAboEz1oRSG+BXoGTWHtEGKENQkDZHHBqkIv1HSaNtHxiYaZNEtUOp8pQC9jZvz0P29+dJE03/P3v6M0cEMUHRaRQxIdc/mGM+jBGfRij/hWfQH/jK4t8NWTfTbD7cYGlXWARD8Acq+MLkVkU4Xm8Qg4IVmE3NaTkkSc6VjXZ2TAjiiQEnRCZYTjANSs/FfVrBlCLIH971IU6s1NzPA6ZGEiWPfjqTxYgOyFGlKGrEZwcMsJff+0lNmyuQ4bNliPXHiTP+FfYC8opIJgrinP7i+5BG4bLSXS4+dY+OsO3rPmlPTGjI3jzwv+9TgCd+/7knzDXXTEEHeI5HsQR4NxhBBHX8BIBVeM7ovi5VPgsiqfl4hlfvhgkCWcH00V4QXZQhJFOEGEvwFQtT0L6+GhIfhJqKkQcZid2KG0JH9s7FucVaXz8OHbjJM7sp6tHf5RwZUG2og/x6kO8+hCv/pXEq8TBfIhZH2LWh5j1txazfpyY8/eUaMKijBPKrbrlXGwajkldnlUvZTpJTUMTmnlVY55Wl4+31GQLGI8a0jmKFhh2vEozC3/IDR9yw99QbvhQy3zICx/ywr+QvJDnwtyysPz82/On6m4+Luu//oL4uKw/LuuPy/rjsv64rH8hG0ouYYFaDJKjeGlmLleZkqhccvlTemmTRt793fxTWGfGfh14i/1UtW7G8Pdk/AcPex9+uXO4P2mpt/ncG3R2oYjd5EmwYULFvY7hXyu1f4jRf7Xo9iFGf9jKPsTpD3H6Q5z+6baybXfznZibi5TkJADYa6sM6GY/gDkWYxZagyAnevCbH4t2FPaI/3N/LIWIO30M8GHM+b8ec4YZf5TYQG+G602RrsDBGC4pvvZ5UZY61497AitloZpAawy2A1AC34pvEjQ1hFCMEUVyDm1xSoE0+JMfgDryI9BEQkESyZi8EHL5Ozk1immozh9J8ZdRABeHICJGmFrCcEs5SMyPiklAyXkL8PO+B9CLBUl4d9umayqmnkl3HIsY1tecs7BYelCvJj2kvwFcDORxI7AxvxFEjd8614+JacJCSJdQOkLG8E0amoahWRZ2nWHVdyeMQXBrkFKXeAJwnhvAwTk7vc4aLP/H9wCEnPUfHpJXahs6jXwaQRyvQbwg2MByvIxIEpIUhByKdcLaigNbJaX94nmeD8GoQ9spWTd2zyTctYtXO7COHBNYGxy1EVK5KbIsbBDGFM1a4w2tEuo0R1ICb7h/Bi2Ediy+PwlEc00ft9wS2eSF+yMJpxHySvXLPSaudlTaUcIh+5T/7tjvKLitn9s1tNCk3x0n7RHbu4Y3NZfcHALtvTB8gNQm6Gt+vH/2UMVSOGq9lDJYbHN5BiylqjYkOibwQYJj6OlAHG7h0GsAUg6Qk7j7aOb0Z47xq31cmbfoNsvRCsC2PRzGgzyuvFVuZ8AVxs4d8606zk72FzTtb0xst7wMvtuqKB92jgNQDbgsQUxyTc5Ar9rEg6FkVJeHnSYqxikhU3a6jbzBsPvCx283MYcTKQcMl+ZGTkaam+yO1IxwixjuRr6K7CjvwtQIL0jcYrC92MlXTfIaULSOrJWgA7OSGXXWwKwYx04cVjJnoaN6ZC6DO+neokzIX/7ooI+PvCTY4TWOHgNIG3DLkM/83WnTP5Ju3TFJQc6xojkIPRJpn8wpnACylbVL2ASrelBCCp73xFWWkGIQYizXtGHuIfFOT9ABZOokdsyCqCvelHMlcy4N1nL+ybDBDXMFwscookmC4WNEGNriyFIR5US4sxDleRSWQHU1Tc+SjMbwMzfCusnw9c3wkufPfeEdYERazGzQ36GRZiB7HVp9GGvCliZKsppxS0ciROs7SYvQQJrRMNVFklYvckmQ3LFUITOmGY+QbyJhsjGs2py05ZXcXqwESRnqnb44qaIxDJFjY9whB4WpJ/sNkW9k6yErd7RFUVyT4qTlGY+0SKQ0+nDzzrANhfKTVZxDkvqnW2wxhhYS02vY5qumYnij+cLGa2IWB6/x9LWqrgAABXPBmlE2FUo2rDmccEr/L/L4Pcr/DAK9DkrOIb8tDpocZoNKmEKq431co+Y/f1nHqaDWMMfEZWZb5VJca1aMHiAV1G1zzSBMnWTmsdEY9G5zMFmyZ9DuxdesU8dWOPzNW+DUw1QNxpk8kSQ1fJgRLAzt2wJzt5X8pFFAfEE9OyuNkMIXzwuF8mhUKvBYGRULZVTm1QTVjjfc20rKMOG2G1Jz644B++ooGLB/c8Kof+S1mTYhki9NZuPO5B7vd2+S7F84vPGRLmKLuX15ctIifPuEQkQTykVvmYGf4zy6QbLDEsaNQVNHQMOzaCzmkZNAY+WxcFEoj86EkqiK5QukoLOiUsRl/mx0pvLnxRCPgTFxqYQF43DtxfwEGUhfu5ri/PBE5ds9HhQHnN3MXwtQedAjdW9gyNA4fxgy5O4+3gYNmdn+D8KG3NEnz+96pEYhIekzlRT1VAkgedme2gJsqdnLSOAo9wh6+zPXwX3XfPL/eof2h6z3r5sSPv8GhoDa39Tm3yhB/GHRpjsogmJqJM1/z0VNOtdp/VuA8kpYXdJTfz5HJyrWtbkWZvVt1hB3aVk6S1TA3aq/O3+Q5DkWfTaxZDl+chovXY7XmmtmNETFfyLlZws2GJVLQkFUhNJ5QSwKoiqKilA8Pxuji8JYPEfHqiCKSmlcHI3OBSyWFKWML87QqFgYCUURi+OUlVFMfTHPwQ5VbQ5ZhhhoZ9rbNDr+7zSzia0pFDjUxx+Jl2esPwltxC+au07sM/Nz2p55dEYxikAGbOHCofs3sjGacaq5pLeYilwEuWkgm4UB6MS2NlqAvyf3QBogRuHPX42vRsXrg4v/759EcbD1daREle7+V+Mk9X//TP9pd4mvBn4FgSe59+vAO6OaVOyfngPEMeflrj2G1Nv+t9RdhZh/jjlF17ABujYXnIS+GsiybispPUdOSUKhf3JFXj07Vy7OlTNFLY4uLsqoOFZL5xd8SRRL+KL01VBM3UxeYZiZbmYt/z+5du3hq6FZXWynbN7tI/fKfiREMqIvFjpLOsRj7ixLjeM5ppAtAKB9WBCiQqcDh7LeAHZlXI22kcKDx2TtE4hdZlROC3C2uXRgPvA8AlcCcBcJzsopR/fQIRnbR2B9n480A6vMkvggEe+Hy2aFY/cMp5sTTTklX7lohiFBOlawig2FZm2COhq1TUZ1Iw7N+vQgseTKkMnMgYxQof4QDGCOuN+PSQawB4mb4fXStFXOWdg25DKju7Ocai52LKRg2iiMJqtVB8812AqD+/0/SctQYXfTTdMN5cEOGtEgGRfzhVODLCwwb1m6d7jf7bEinBcu/iCrZ2CsElPyCMPbQMGGe4INkIFI+rX/KFydcpAkGtka5Cw1Y1znwZtXAuHu5jqydM9VaWc/kPP84x/pI6h+W0DCoIwx/keh8h+Fylfjv2W0UjExzWiHk5v7J/ffSBtfv/4/6Y3Uia3B5jpTtM0G2FCq0Mb/TG/jHpSeaQ2wNq7JONJmE4zDhWZMm84JKCQ8Djad/5neDBlKWhveUGgzBtXNYA6NzFfM/N0c114oLuMUzg6JBZjSP/4R3Aj/IfKXzcp/iLzH4v7bP9q1hxS55K/Jk5VTE5QnB1SyO9OWhTYwytL3tWoqC/DrJbffcGHrCWJVxE1p6zfHXNhKjocWyeJGlzcutm1Z3KjDVNjbKNY0VdUxg5OvC48ktkpaRl82jG7wQ+jqYYUoAc6thYu3xawGKZNM8rsYHhcWtZJ+kg3NfRsj3FEqk08S/U7KoIkzQaBpIQcuzuf+yQFhZTXw1RitXezcGkSEixdpL+bQg8Z+JUW3G8roo72Ysx6qCR0EPeCMDnL0oC5scmQuXydbBS5fsU0dBX2J1ise7uE0uQPun1wHvP/BqqnpusZcaYMuG5CSxIjWYN9l9fiWLsu8O43XIN8xaQEss0l9v6XLckKX5R/QZR6h2fMzCVOu97HqfQqRROgT3ZnQF7Bu4Y9ld7pL3k7sPoXJkcx3+76v91SEhCpDTodA0N+zHa8mGNZAe5Fkq55rbjTtz8IGuZmx6W19blQHsLfajNaEpdUMZbcdbLsJWo/ci/bubAIJ9aHad7jhXG13Yont+rRemhKCUEegxEKTiY3Bu+9DP73TqJRf+KLP4m0fy5CaQcsUKfdcmmhSkjBTyrAF0YsPwn0Sz1CE1exsBh7Y2mvEkB00FXDpzJZCxRKbCbPX7bVlV65/DexsMCZyeuqQTA4fnkl0QFsi6nvYkWKHNV2P/XFS005q2u2HXJTsGEUJB3TUTnDZMG2bP0WO7MzBMQupWnGgGRjaUEcJNB4cFSa5+PmQPY9pEjUKCh3iXWLZJskIpVJJ/ZjTTvFpEEHgNWKOqYJZMRe6ChqgueY40eDWbVNpIex0/J28a7cH3EArKOGZX8FoRjI3OxhcGYJLnEOKbToO0cjBUE73Z4EQunlEvRATxkFH+jPH4Uthe9an9YCSzWWSwTvumgC6U2brprPL3LVSbNeAXvyEVCmeguS9R8VmLwv3Qplh1/nM/ZfjIts9hhTtf2YdhkNPRRDRt2Vl8TwDUtfop+11PFID9o2e4qPQYaaUSc+JP3SPTN7DBu6LqzGPNNih7S10TcrCjjk1FDP6TGTHZ+6EO+Om5sIGfbjvxTZfOJBNE6hNql0XCoUyR13UaD5viO2RO9fcwtDhWW0Cc19qDvZCepOd3N5CEGmyc6KXCPzCmbaK7ZAbj+cU8p/0Z+IT5oQmqugL0IBrBvfMqOYZ1ETPwfPnOYvss150/8N70p3kedMRSkuy3weYNRGpjwSFRCW4Epx35Ef5PEauw23RKHPx3zm+NqcS1H8QRXe3aqh56Tt8Tf7dSBtcEYc29gLFs8WbgDVmlxshQ11qKmijdxVFesLax5R1sFoRtZprI8MZY9tOeRnglOdFkopuV1ta2lslUaOY3Vr8baDrR0EH/rC32HawnHCOyY7lyC6Z/Z6LdeE16t8hKRwDyjmMXt4/dcy/7tPhw3P0w3P0YM/RkNgfJZc36xLfqgyMiZekWa/VbdVFHo3XngMJX197qUa8NU32+KOQMj/NU5519yZml9DGB6f74HR/L0536Hs1+bz+EAf5f4Wz+v7L/Ov7xe/Yt/2d4hMa/LfxiE8ihDe6w2cc4Xw9n9A30cdh38N6ESXE+GLt8chkk8x4YWrqG/SR/q6H0f72AdDYZxKsZhKo5f4rQiM2wnbUGCjGXjTEqiYNDdkTc7iFP7vXULdbALvRHp4crCGV+m9gdYKHmrV3db8eLLg1HGs2XjI10V60GKr6/fiIevEPVc0GatmzrWjlUGv7L06oZtCOtY9PR7Qhi/l1sI9L055hex/9ULS5oP5Wm7kCuDNbJS1stRtAqB7eMmvjO+ECBNFw3/b8erSN1Xr4hpbCtUGQ1veeHlSBmhQ/wcd+3KuJcF1A5NVsd4H0oYFdWLUDaCShhcTg/DRkm6PQ9lDOEpthNtMffjzBP57gH0/wH61sTMq0vp9+bltcywyJ3Iu5ovXEzGz5HaXM4Q9yjfpXYjZROjmYPN5KBe+y61nBOpeWtcO7Mo6Rc+jDKXlsYWlkhxNaFkYW8IzxQtcjCGgo5EHq9ZMdktTQDKzYaOxydWinTcDsYehGIlYZcZWYEtjx9+n2iIGbp3DFgAPDPYIJJDAp7t9iNOY5odcti8ScepsdfT4rlQpxYNtoGFTEF0Mslc5Kf1IZznCSkdgJvLn3M6ejNdxMHph3OCA3aakyV8pVrC3ZLNw32ylvFcOjTDwdia/LuMcErLiTkNiDrToEjwbzOP1qQJSp85mDQxPaMigMsPqmzcmVx3AVhyU1C4mMcKuBD8bXI/o4+3q0PyhawnxHyMEf6oZUdcNeQn8SPXmTTrqqqOwS9mrfgWr6Fsab7B8TUmQkS12IOcQSEjTHXKXZBmd1CKr2OIwPlhGm+Z24r4c8slXD8Z/WhzwUoT59JH5PXoRhOlcP8/PQIiTlIUxeh21Xr6npuIw5hfDnnekp+3SqmPOU3Rq6boI7EcnT0bmHYZoLG8RhU1943vxr+Co08iDJRCISsc/9z4h8nrqUyax+m1oOWKhgUa6bl41qKDmI9/myUpGq7XbiyQtr5RIuTmOtgI83lAJwCFrJC37w80qwHaIbH2PrYSzM/+2HNrxq7hpuVz10balrA801BfYykCDjb9Rw9aQRBwgWTiivBYxUM0YAbhCO1+BMI3Qu2VxvH3dEgNNBe4vMvLas1yL954ws8+5NT17SwNePq9DlQDrchrpuKoQqWDWHJPZIGjvBnCBZhBAgUfhUFF46oHIPkvCU3revSNcYzRGyIUQJm7pjMbxNCxbE+4aI4HHutjpxAFIXPBxPXpGtIYPB2YZ2P77p6dQJshmJpFg4rjmHd+8S4ihgFZaYG9kmUsmyvGrIXyJf9vCpFhh38hnbAVJbhb2IkU2wMkJZPOVPRYJWmuWjG5R7J8JpQ5R9Jt3465VBL5rlsAXOJBbGW/KSi0PGFqIW9sWexMJqfU/iaL8gxEKCCSJVXL595C7JU5XijR4mK4eF5FwG4Z0S8Ac2xBuwIeICdH4xdyd+7w8TdrcMZMkxOyx9XYCDDXhhl4RvzNHag1APksqGCxJy1U2kciOkI0OJRoNtR8mHX7OfP30SxPNT/pQ/FT5f8Bd8WGQEv5Atppsxx7+HXB+MNhDv3b3NUZ5YfODjIDSI9DdCfKRvfSpsZQjM+Upg9XY8FOJTeousznrkvh59PQJ0LA9qz/HTJFBgMT96+PLT5eXlJWtyx+UZujZBqof/v7yEf9pSN1G4j5mTt2elYsf1BkN0Tgzhy5sGuV580QJEBcU0XhYGBcMgsw5W75RroDWRLwjiPmH30blT/bnHM6DDYxo6x2BqnuFGeAaIPShMFiDagI0MaqcJNeHE2vh6BK2cgMXk69FzcFVCVkraEIVCI/MlDR7HEgVR1aAX70i6JLE7BM8ysWxkiaDAV9+y+fWIRnxFhENRDL9xttSGW9fTn8cZesf0jY9Y/2NYRBaN0OJ6pAxHf+NcNOF+p9W428ofXgZB5MRfor85MSKJvLXiMkiCou7rEe3m69F/cvMF2JH1NYdXir5wIEtDhLbIHXQcIjX/b0pDURP7MZXot1SUp5yrO+RWMmHEIxiDOR5/PQJ6+3o01vFKG+k4ojJMSnx7fj46vxBKysW5UCwUR+UzfnTGn4vls1KZ53mUwWJinhMxw2SIH7JN8Vd4rrmEzXhiAvtdo0hwY/KuhSeu61C2qiADfhhhqt14zSM77Bx2Wm7be9OcLaxYWtvYDGSaipbT/Cw/BE0wGDCJCo+PmZKWHx8PlBVpN5lfeg9zTyoG5bbpDskqEbmNZsXdynmbsABbhqUPxW9saIf7g72vB9bb/Xze5rmSdP2Gx5SQpRXun+gjHrnctW4u1LGObPybQx7t9FbdukMTLs+vIBd/Eui9xy5R/8JMvim9Cv5tucuI9EkUk/ibN9MPl5wPl5wPl5yf6JLzpri5JHeCNwfdbDtLJuu5HqEc/NdPVR1+eEh4TB8P/0XLs+Jes3/+PnVdy/n86ZOKX7EOZ8Y5VXzWCS89f5qfJtgF8e+EwIhg9RMZ4YnX1Kc/qHUAVtjXQkHmKqTpxEDwKD089YOBdoXjra9EKnK2SSOxmWWzVHM8jiQLo589EYZ+egUN8qsIiY1IB4nL/tfAJoS8UzNfzZ37NkdTgbGL7i1mrjxr5gnz8OeCWGigISXZmyHuVRvPb+YnMQNQIwJi5NroFesON7bNOT3HoF53TWo+9IiYaPW2HBKOA5URyangYFAwscRotJC+jrVF6Wv7CUbWl8B824CLFozn2SPv5/gw4OB4Tx5yiLZHBH2so5IIZHD/RBK7c2OM3IUNuc8dTnPJ8B1//DmGTQcdZIDTADmd3Hrw/kMw+/iYvZfisd+PRjHlPLbhPWL9Z/hozT3HH8E7pBsmS4Ypy//Kt215X8DKsX+AI9I+EomLJh6LvSF+CQ+57bEmu4SnKA5kmWYwQxyrxrFqhJ+yN7enqPHpY2qbi8mUcxeGgfV4zcT3nM+8FgsahhAfNQOrSLf6kJRoP9FZD6s/OPQUq4eKwbGaP1r43Zl5OYd0kbyav3KEacb27BNXGmsmb9jez4gffdO+xmNIYYMXrgnpWZWhpSMXTvwQsj/MtQ01CoahZbbzGdum7nCXXhPcI2uC4Kl7TXC/Xz4+/OGpkNRHsECdhtIm7qruUCFym7r8ZUhba9Mmei1y0bFWvCQjnkYhMPICL+N+B3dDFWRPcpcGFzFn6ZB4BETeP5L3KXhsHtPg3m3WljctajQ/pTf0Ha4x2fuYnFrbV9jtqPznrhTixFhKELoiiw30/aYUqBnScTxiNs9ivyJ9kfHaJj/vv/SmERaC4QNIwn+mnNUtKJZ85zBt6FtuYYecxq9G2xP4qFreNSHxEgycaLOsIJ8zHTfL3kG6Bn724K0UtLXH2aazCltkYi8AOohdkzqNvUIS0Na3fCSQMsXD0XqoYtDTpLxAekHKZ1IBpFtagcjSOTg2wCOPs68DQmlUFl8BS/IktYD77L7wsxJYe33BNmkOx8rlatOz7WZAh/pFwEbCiAF8ZsDhDWc5FWR5Zi2Xy4jtmOrvlClWZpmbxMoEpE2eQZa+AEkYcmIrsUduxrZBYiYrGXEuvHuO5mKajSnoFL7Ltb5La0gHl91H6B4KOmGz0kCj5bhIz7encWcb+oD3MpAHcw6PbRtAKpAf4MLc9kD6F76b/SfH/hcF05iBrgssOzhFx/Nx0/7QmxZ8QOz1EFKT5xBur0hp7rLd4e7QK2pTY72FbCcIpwnlEWf3XqjWh/iaZ2eDTcmWVEPlPoTS/Y/K8ZEOLgDuG85MuiC6dWBGeIpeNdP+/NU48UTLz1yNajE9AVM9Zb8a8GOotien0J/puJOLsByLsEC0mBeIwITRFDcFuiBkbbJWxVuDwMgxHJtGUsBj1ZgST25y+JZ4BGLAb2AcNFwOkgG/YnvNHP2Dk1mDtk65Cv2dq5smGJlvTId69EACLqJbpsrdpcGp5hxpxvFXY2SakAQA24RiDQVTpS9mo1g4JIZRe0XKOmTWickTpHsu4ghMmApJlQa2UjgMwVIy/hZv4IO7ZR7GMVujDMZGi3zwtB9+/cePcRpDC8vfzPASej0B+foMLGHQqTayzFEnjJHxXxtpUV1cwklsQ1HuCor6ycP/nQ7mh2T+hqO5B7l/NSohzH16cxOKqNmYbjl4ifog+mq0MAgBKffy+x70qTi0bM20NXcPXTaxtorcY6RiqpifXPpD4s9z5La2J/t+3C7+cVceIv/TAMS3n6Vdz4Dko5H8IoDE0CPIq4Ntj1tw0e4ibwQoHnGRYIpyrCbXolP2atJPsZKcDRF/uZ8LWYvoLdkvFQwJ45mjCSC0O9pGMyZ5eGGImdxCZU5ilVP5YazYByPMc1KjG5PNBWNlP1jgISzQtPCuN386J4wdo11sMHYiDtCI+HVD0hiQvoPm+ISajubErxVCa7yaFs6sy2oQvQK43zK3ubimJXfXb9a/5NgSbwPyhENnuXd4jI86gidFDmN1SLMHeboPZwjR/Es4YzT4JQ/3XE41xYujIonlOdYItVMRP3G6fkRrA/ZVk4v1G1W6UFrqRItwl6zVB9bTB9Pdn+nG93cfJrxV91+dKZvzOTpxMPjqh4MRPOpmbodUS+kE7CaTykEw+3r036nnAWmJ5G30Ts/vTCr8YwdDOfCluOu0/41WwieHkPX8WFGjkdhZ7DW+FopooVzCovh4yTnaxPDkQ3Y1BDlqt90auESOti1Qxlke7euDz+3P52A392JupMK/Okf7BbTSicduh6oucuSSJLwt9pJHGMsUvraGSf2ws/gDYC5g4Hd4SeJRoi0cx+UXasMKn3DKORF9bEYEojhfULzOIrGdHxwiO7Q0cUuzmURKnQ8+8fP5BAsfSZVQEg4EmwBBi4gxCDiNXppkIF7TCzmBaLzLzvXNf341TAaJECqm47HLLQxlCjHPakQ0Sc82GxGa/9WFK3KP/hqcPNbUTuVFnMseoMOIN7GvHiOrfk5dRloTP0N18d0/vgt3ONJ0PacCViY4Z9sbQFvwtbCAIbgw3LDcvKPmv7PszFYrH88O9iv7QgyV+7gEf/glGDpFKaP0Qt33PEEUseozZ4L/FOMQx1vEzrByIEZ2hJTZbrt2MN1M4ZpEU3qRjS6eb0/rMnaRQykmHbMAXIXuBVyCzIq/GxFPGdOuXZSAJU8iOAGbKjuKcy+bVdIS7GY9WTwnT0TkoazDu9nyLsBue84uDsEwKWPMYScg5U4OIRIOIZQ6Av+5ABziZ/AGz5kkP3tIZgXsZiP0uH0KCHNwbYzmQ0TiHwmEaxKkwJjgCdg+wit8PpmA0xSVk+Hq5UxwxYQPJNJ9igwinWGVk6V7zjVnGFT6OjxIPchY2qBla3NkazpAcM6wVxJAzDUqSPsQvv6tSNw0w46WURBauCiD4HqI4Yc2OQutAb7T8fDhnkOzfg6i+hkIKIHdMwLUZijGIrmc3fwB+ahCCUDQFI8Q/EphwgQmDfnmDQ9qAJHlOQUgQDeopDnc80g3ldnzMYukIUtMJ0h+cIjagO4T/IVth7bpyWyk2V2Q4eYyChpOPpP20/gxuQ3sBJzzy9Aiiic6dl1CJ6Q0B4HNBF7mtv3AFYSzsxOBu9StKToRObq9PiglxTNkyxTegh1RUimHQ7Oyh3r7+FoE0e32sXsWAoE1be76tiI5P2pYyTF1EDgWxgGCPSTRdE4wBIJj4A2DuzS4Z2Ssn6P4FfBy88qQC4/dCWQyCIhuqemqgmwyNYqs4XmXIIZCj8awgcRXjbmAZLN269SxwxjayCCr4n2tWacTbGrWqUdA6c8Bn1dByUxnkU5IaA3KwZ38U5xH2EBV9XKhambHRspMCvuhvgeuAu3jIGCF7ap/WfKtHONEqncRkNXcgr7bCcqQ3EyOTFR+Hog8o4RGh16d7/C4HeHd+H7hyrQGGXGunKLhulCFYCwvcqAv0oqRdMehdaLKooc0JRNlRQH6lRO20auaY+mIZn0iCqVTrgoY5mkqKEDz93gusCNAb33+78+El/mcyFmMWPlTrjq33DWtwDoO+oIBjDC99Mi1H1JtvIktR8Js4yG23rL9QAiVv+9RP/Co/p0AVLI3Jz+CynY76RAqbI3hGfLnXwGowvqnCqbDwVQSdjs9Z2UeVphwBkP9OEoaNyPsg3IjR8GGSqGgVBoVQVBVd0bAuymp2ZJuh4QXlgGo3/AU8PeHVAEdtjKjOGcjov1bU7gwTyiDIdOv7cTxRQeULa6QMe6SqmgeibBQRXQpBhfcr+GhZ4tbGJVLQkFUhNJ5QSwKoiqKilA8Pxuji8JYPEf7iVuhSzRBCxQAtNMp6GtvEvS6oiuN5qYxAasJ2YfwHpCGA9TS4H1J77kcYG0mPHvmJGTQXqc5lGxf6ltzabOu6S3MnEWIijqCaZ0+LiaIf1vghQ+TvPbOa6q+jY5MQWQYgGGgKcOFBS/q3Ux5rCVpqYCeenjU7XQ4KBB+eZMcULQreHI5ixFRZnj6hezl/l+fZAfbzqfZWsefKtiZuab1ybVPX93ESOk4AyOD/XN7ymmI4iQ/qL/0iJtgA1MDHKuZtQne2muGZZsTO8Q4822Es3vx/fHklBb88l4f+4qzviCrI2OyYCC6ueqx4vvKwLEdCouziq5Z3tur/b4Jkf++YtmeLzB6PR768IIdsLA6BGsjbWq4SNIZh24XKs6H7pjf5dvKHz/x6a6Y1jp4u++mmDc89lgGqW1FVOjukaX7U46wGZKqmOb3AHlgMdI1BZIOmAsyD/KIYsktuGeIJ+JuqpeV56jSh/5Qr3aeGeJ6oDYKdeJMSZYDKlCR111igyQ2H3HPjDOfkBafuSlGKqFayJtgKPpCZfeVo20CPbeWrIoMQDRtLRoAx3CUQ1hHjmvaaEJBlOnSklbnVrLVJEbDdBvC1Eow9IeaYS0A64RM8mgLq4eJVddQ2LTzsjft1WuY1ae9mQSJU8U6drFEMutoxuQStGwVtM7LS0KN214bQ9ImY+AhqKv9mvMqEv7mov0bgFqAQ0wTHwCmwr25vEcuNpT1/q3RFoa6uRzqrA0KdEXn/Jbl8pznjpLtqBECMRduJoXst9ystdBS0x++4LwrxFoIqgWsJX9tqBA/IfBdeDjbwFaxpUlh7WBgowDL1IyPuTlWNUTtsTtyJOe144sdXqR2/FQs8NBIzYQnziWxLZ2oxOSlxp85wahZA9lXEit0oqlDNFJUTHwLovfQWTFznJQpqFEUgw/ZJaYXSTKKzg4VV+hbjb1swuc7l3NeSG2aRxSIVvp+fKTsdaOErg+8srQk69v20aP2Gzo/anxk6g+iZWCOGmAatQ49jaKQ8zTO0arCLNJtmrY6L/VtV9zveiKnOHIzMVJpE4OqLN3nHcp2PaAlZYrVhY7VincD52tsux7cRNPFfGQgTe94WRMec6Qgog0m1wUURQR5ApA9y9mQX36IvMOxdcISdiXjYH1wtHSOlrIU70pWh1mKjo/oBsrSfTKzAW8PZHALAy3cKdSjGZ0ZvwF7Mxh5mAMWzQ5F3xWPD+0Oy7yKbPcTcJkTOJz+WyP7so3Bn35yyJ8WcqdvIncnIdvunjeJk6RLfQR4YJr4HTEPGU7HLnX4xNQUZjvesjEOHc63EQYxIv35yYHwyjKJPpC0BVRK3UMAkFfXYLb7q7KzpRRzaZBDbWFbATggWFcQXBJ8SkMZ9YjuckIRZ2EVWG3wnx5hd4mxwfHk2hJ4PinRkJ9jUuD5UIZJPt9Y99fmeVV/iDrPH1eyA0g4PY1XNOwQgmz8mXtme/Z8zD2Tp/COHCKkTDSFCPsrlEPE/4aWzjmLRK2Gxx7AtYT6awER5FvgnSoBL0v8yZwvFDalFc/PnDNjYeihTEt0lIQ97DI9fPJX+RNbgtO5Vcx+VXhVsFqzzQRXVEJaJPk3WQbKA4NK1C3f9/jyWRAcE6IfD72SuFcNMXbAeATzuSURJiTV5kLfkc3JXzlzbiFjTZZFNyfmqZVqB49NNIfymR3q6xBHyMF+0znKvqrh+Hnf61kcIeetW4A2eLw1xT8TFupD3kmWd7bUngwrn2gVvdWjnG+G1+AAgpQp/Akk7kdawSVBsuQCDje4n2pjqnmMtjBFEImDjQRVQ9qrznMVSnAvg59OSK8+36IZYCODgHRXOwexByk6VFeYYkimWbKpaZgq0X/y2A6WlbzA0+QpeW7LYdMm2L4d+sw45S4DB+rnE+GZm2Nk0OvFrwv5zWkyXarm9n8YYcUELP7QbUqeyFCbyV9AYCM8BnzXUP8OR677JNkkg3mC1/4+toW/yg8tZETDRoJSL+I64V1LoUUKLOSgJ3gvtV5kUCSP4NAJVAdZhnLsKUA8TR7dRTBPhUkpGKeX4Tx7N4GqJYwc07gmPkbpg1hOQ45xHDg0Uac5bIB3EhBl+P7GxNNNG0cJDtQz1GnumfT8TGRVfMo9ErW4zULJiPCJ5jT9x8LZ4e9dlaRh86E57N5Wqg+5p9vBqwQOlHe6LIgQcdPFHBnkIJGjRzrgGIuAqVaNia4507ctT+b0O8wSRe41aAEsAhODgOORhwmNPmDzYCarjDXatp9nXquemwP0HsjCIN9d3h6WtcwfyRRrk2nKNUF/8zgqjZiFjLnaCut7n4Isr6HL0FP1JJhgiiNRyCrwE32HglGciAmP1p8LPciGRI2mNENwAnO7DRtV3ViOZcaVkxKXOosRC0b/tgBs9cT8wXs7uBFT2u67LIsg6fliZBlQYsbV7pWNXey0+Dve6tlHYKmpsJ3pUyIF8s2IFf0rJ/Q9tqlD251biVFhNOcwiUcn5Zl7HQQoa6/ATKyFy9i81Gk8tneL2/saPUMDZJbP4Wxf02e4DfrMS1yAcPvJD3us2NglTxPwMXRYYFewNMDRyTqQRQqtUTZTEcejgjIqj4VzfHaBxNLZhXqGR1i9UEslvoTRrKBgNL5QyiNhXCiXsDA6PxudlwsFsVg+V5BKsYscbDgaZJfaZjPR6SfOjQ4bdBZrc+FnNmOJEUa2iVQFOS62jxmCnzvFazZzOk/PPz97qmQUnz99giqx/Nifi8UC+f5Tnuk4dqKTbRrBbtNrW+rsplYLOY41tVkyp9yk5tiemX4YasGfwm1urXy8NZpvdl/KhwaS6T7adCJhaFv48aGlTD8G0eVNSv4gls7wGUblQlFQSwLG6KyolIul4lmpjEvnZzukkYx1PvzstqXOL3hyve1LnBcM+YefWsd2U87s+flFniks8ch2E3zz9zmwPTySOte7z+y+p4OOLeWAhH5M822WOtc/fgcOVIGPxMLZSMUFHo/481FZ5YWCcFEu8rg0VgpYRTNcKKICHo8KF+UzLFyMRVURz88VfKYo5XIBqZ+WZIKfiBuiM83e65dlQhrCDgthhi0kSj2Du+t9YZG/O+T/9Z2giLL2oN1tUE/R7q/vbPVmBp/bMl8ln1GvpT1ot0Ljpbrpi4Npo3O7Grwoy/7L9KXRaRQblX6xOR/M+5tGodG7mzbWt87tvOYM1rdnt/pdp/Eii7faUhtpt2e3L1cyMtRvHVFHXVH40qw0xcFLUx5tpOpImLq9msq3Z+qDVND7g/m0pN5Ijb58Z0gvVVfq1p5kWbpH9fJ9f16etkVhhWbNK0UUNqjQ5fuzVbcpXHUf6pIty6WqJFiFdqHbUzaXRaw3UbPuFlFH4qWe2pJrVkmtqLNeteGOanq71yuXlFntRnqRrnr1aamxuS31Z9OKXKndjW7urlt6+QrxqjGaS41WTxVGxnTQuLlrD8Sm2ClYVv9JEdu8VZTmpZeG3r1v1NTuQ/12qVSk+zY/vVEqtftORZ+hzdVTtzKddXV91Z9320i2vrXEVVfqCebDjS4+yE2nIwym8ka6x3W93zSmstyRqj1DEaV67ctgpvcaQo3vzFVRqQsa7q0e2vNaq10vbZTCnalW7m7awmWp+XKnt0XLlLt3DuqpYrs2/dKplhftefnLYLbS23L3tqcJFq6p874gVTvypNQwmjfqvFxoyNIjMqYNJDcfGk/WbXstmE3xrjESpjKSV0Z/I9kq2WNCN1eyXLuG/R1c357dGqrV6lWXSC7Ne0az3643H5RuY9XuTQ15rm66N3c3aC10lJre74q6hCuDm45cnvX0uy94Nq2jTZMfzaSqVLt7bd40vww6V6snXq0+9Gabpl5dD2ZdpLaFEtatqlK9mykFufRw03TRzbQpC+UO4p3SU6Fb68umMJiXz7ri7bpZuJMko2bed3VNlssNuTOdyUbzUboZzFt6+WYkuqte724z0u8qUmG26c1q6KE+uBuIJVN5upKbVUt7uFEd1FtZDXmywjVr0yhIRqfnzjpVfdGZC+tG7dJVOv3VoOo21cJdf9CVzHavWVX42XokDoT7Ts2V5kKjZ6itkTioj+Yr1OmVW03BGktyyZLrzXGv7vaam9oU3Vw9DKplS+mV0EgfuI2bq+tmtdRqC/ISV6Re56W17uuXm1512pDn1qwrTu8e6m6hfS1cqU/Tb6PC1T26ueMl0X1V6sLLoCbNGsJAUqs6eqhL1uDmat14sq5Q1XptacLZoKvfok5Nxnp50K7VdJWvSXL71rk1LuHcr7udQa0r381QQS50DLXSfzLXzc1g0as3VtLTZNm9sZqDF7ko87Iriw0Ry03U783Ezmy56cqS1dOEefNGv1Vn0n3fqNXlJ/W+V2kuB7wuom610OdLrb5szUbVchO3hbksCvXOk1zoFqb6qDvoo3lN77zcXTdmUgVtpq0+36w+dCcrWZxOpUJVGMhqu33TfBh1Zbddaa46daEm1a2X+56uoY10M+Cl5kjUu/2XlvhQX9UGN5dLWbRuH55U50FWnX5nAnxudftiag+90kJ5mpQGRrPZF9XbgViu4Pl03H25m6PK1JTkldyWGyVU028fulfXnXoZtV4Gt6gqdHp14QUJV2206Rqybj329Fq1yfNiZ6M3UG/w0pzXKt0ntTp6udJbG1nsz2qVpty0ld7q5aFy53Qr002npzdw727deZkWRj3TVV6aL+3OVb3V0cftemvdrvaFwWyyVoy7OTa631S+2WsUlM2IL8tqwSqqwqSgiKsvo5kuIcOaYr0stDfVda/qLpTuYKDI/SU5qzewt3er1kzvyB193JWbPdQty4ox4WW53O0bA7Mrl18UsSb3Zs0b9HKnNTfNhSqX+7iqGw83tcVAV9tto1mU6qWNKta+oCf1pdm7e+kbg0JDmPLd+lRShatmz5hauCrIjZtavanX6r1uv9R7Gmgj4+5MrlrF/kxtqp3BN/Qy6Cuifiu/1PRRTy7IfFnvVhrFp82ER7XB+uGpeybPmqLUc9wRL/GNG91Ue+V+dwNt1ppSpyoqdbfR5Qcz+UWV5KrktGQZ9namtG/PbuelTUu2CvhpUBv1Lly1V1rKvPCt/9K9atxcnTWqq2vp5WrQrDVWuC7d9Z+a4/vuVbu/UXm1M3W6NbXX0C9cXF1VH2rSmTqffnvi9Xmfl+6kwt3doN780nzRN93uwJCERmFgDGaKMSn0RWHRfKmtkSY8KXOZl7t3Nela0LuCuhpUdEsRa11pPinJ9e6Xgehej2qDbtfou6qhI7Wr99RaTURCU5b50kAqSG73SRe74urLoHL12KvWbqR5+UWt62M0K6MuObc1C2h5xKt91Fvdt8TmF+mpWVOrVQHXS8WerNZbvZIsvzSX6mxwLz9JpTZf4+X69AbdzNajeWmNxO6mKUgSqtZWjfr0XuoNXFmQNqgqTJu16VjlS6hRddwnocarM9VsVqYWvlE7nUr3vlNdrgZGzenzM7FTKz/JRo1Xaq1VWxTupaqkyzeSOKp0r+VNrT56mSzb9dpSEoWSMh9IPVkutvlySxLlpaxfiG0BeKHwqhTUfqvQHKu81G/UyuJg0zSb8kq6Nfh/ZEtMM7z2dMnxTEwfFuR94pfAcnyoOzBsgp/+QDF1HfvIPh+bEHdb3MJWiIGmBfEBeZwW6buA7IBX04cb28tr8USEitDOjrizBHf/0Otkx3ukrI7KZR5diGdnZ6paOheU8/NxuVhEJaWkXKhJQSWH02QOz5u/drXZcy9HTSgJkUEUvC9HBSgZfoynhHx3CD4pjSil0dsePAm4Whlkdw0EjDcoRrU/9g5Io87//f/s2f/9P2kZD+PRrNkjIziBBnd1/cgVz3O9fN0dxjiv6Q++dTDfyh9z7Bx8ire3KR384t94i/bbisN2QnPcD6SuN0UmpDjKXXpoeqFoZifqgJMFzXQQOtjB59EPCU1XRaMRONinmADe5R4OBaaGruG/Q3AwSCWSCe426mXekxtqCaoPbVp/iNz3CTf2oF8PaMWrCaKJjtYj5qu3Z7CyV/PvE/p8fOQb/PeznvtVH/dbLm+NglaY+XYfEyardmjXXgv7eJaH1jHkW55bYA5Vj8ZXUaPKAVaqoPKhy+C18z2JK+4b3h2y0f3s8O4MpIVth0XM4AxZCe62An5Tcccpzdlh9803nBCjTQuMCoOAhdYwlOLCA26lQbrMYLif+9ZO18Fk8kyKl0/x48trJT87G+HiaHxeuDgvn2NewMJYQYUSOh+pWFEVdS+nuYz7ZH+qhRa4JYZcLQAjzto65R68ZC6mHSru0IiDKXrFnIEBQGUKbvVTrNm0Ja/+ux2AOAp5vnXxr8cU7AMGl04czGZ4fUKdzwBlBfuYx+QewgD4T3HSnLUDIhsIevRKIWszRwaagO4ktEhJ4pI/0f99ZKA5eeECEDazgwtHydwofLUfwI7ejgz/BqZEpz5kAZueA8G/p9j4qwh5b765MzBjkiTCTHcXKEXd4wOy/c0JXEZCKXhu7tuAkFe5bN/AidPGFMgJkAhC5zR2Am4ru98tKnKm+woQUIc6yxwfTfW8dOZXn+pOYqgdNHVMB5T4YEuSjJMzRIQSlLAFYWwGYqEwfGH7CY7uzeUJk9XJKv9+f39yc9/+45izsbpQoMhER45z4pon5A+O9R3B3kculS5MmouLVMUqw+zkSOylq400XXPX+ztg52U4wfF9F3jnWNBPICLR+/6dMZ8vDRbtwepAs37g0V+J+ZzNH3fEvgfO+irBsia+3L4bWESw8Bt3fCRYBgx0yvVo9ghGxV6YLMV5I9kevLq+HzilfXqta0EeAwXpykIn1ybn40Vw3mzohUoVN8gNWqXSEANzg9AcF+Ly6Dw5w+Roertj4FAsoMEHjAPx5ZmNg8gUc/MV7mwOrzSHZHDZHkZSqJ2/T8VSCAWgkA0DkLh1U03F99or7pKjew2BFwlsmiZrg8UElD2PDQfbyRz36Olf+mlp/PwiNEUNwdODMT3/jFM/3xGaFqUUL1udr6gLyfJcG7NUZv7OPZvj8TP8Ydn4FYJLUZg+aHkcKo4Wrkki057p6Z1oRrgKJV3IPqV5eVJM40TFc/ieHhMGeHFP+bdpkSOCtVdC5rufHP4AItgHND9dNFtdUDIb9yBx0RMRhdJYggZYE9TdM5ReL7ixp17Smq1WQ6lrHOxCOkoHguzGpq0AH6BAC4qXH4+xSNpTsOYh723GSvyAocSH3A+jVF8RtbVWVIylq+A7mKMEHBSWeODKo2IVW9hQydQJgBsJtrw1uDlcyQpysHMcCpchHFYzNFcjmYfY5ULjbRxPIKNFdxMqCvIYkXOPXM2JPTjeE08sz40Pklkynzu0g6TmqFieG/g3lWe9AZgr55kkebLm2Fy4+0GQJTYfa+n798jrNnHd2Tmhq8XYTsKUWbH4UPnkx3HqiJJeHdiek/xeBHV+TnLmADsgWHFhFuRlEKPm8zAbh8F7eLFLpLleEFqYqwcHhSUeJS2Hz8wp98w/UzGF4qSrTMlCDiqIieSwkmOnRXGEdOTCe93HPmBjYZmNEiPffEa1h6DwYU5/i40QlvKWSLRvNL1na1LI4xGkzmTNUDxU1sZzhjkfFrn9VHPKwnbgQW5S2k0kJX95BJ7ngZ9AF/l639If0lxeDBwLrhlIGq3HwnMTui6UShdn72D7/PBGeKs3QsiO/PbdyEIpU0zDoGwoAli2Q/EepI6BnH2kBZYEIvETrUVx44aq5rCvoWVXH+KVgrFKalCAh6FrDoMiwXd+e6C3xsthJBvl0EMbPdrKZrOTN98mG+w7cX2X/871QqV9cc+dht8TO+ISFR5dqMrFxflIODsvlUdjtYzUsiiKBR7xQjGHsQK+GmPbOIFeTpjC+96byW0I/DkJ5TRxogwILwR148OZMGMMe1hYFAnomib9g1do+GeK1U4hMNbYwxWjq6Zr8MzXXMfv5JSTLYpCR+pRSogDv3gDIkI1UAN8Bbw2yFqSFQ4fKClYOHwSC/RhAAtnfAQIUMgknhgC7M+zhlDFVT5DCClLYKMJ+tz3+PAPzBBDdl3XuW8LBHpHmlA8Qis7cjpG0A3Zi9miiZMYNuzxkYcKRSv7yWYidaOZZ46JiHASKpH96g7WIIlFBouAOJXo1rEaWQDvocjw9p7JYhIB9DkYwjOorhiYzLFXDlvPTN1lY3dhGw73TFBtNGNCy3uK+OddrR9zz5biQ8c9++0hT0bYQsKMaNiIyG5ZtrnS5vCZQdGRtFW0TXJSE8bgzeg5BmD0TDNExHB+nv3g1VCaJ7qohJITJIIoJlKOezNe6/vxUQLa0H4NkVrge6Psi0AYrsE8Q/JWDR/NLKtQWP7J6UDPVnObB/o8j0qgqqksSKIpcr0y+2L0PH8PJcJL+I3iVO6W/iwTRmEntLEli5LRB71uJRI4PqK+BLd08ltq+JCEtK/xN5Zq4Ocbfyk/T8hKNoVMLaFvPU3cFvpnNkduIHuGiTK6S5P1hDWbO4ZmggVTIaQiZ8G2LqfgC7HEo6lpzgJThJOSj2snYmvYqpI5QtPAAF9O5Y1qbqB7pnvHEemHzIQIOZxuGhNsM3QvuBE8PFXHx8dPDAR4d+IwLaRobsqciN5EXyjEsBhG64oKTvwp/0wSqDshPC/PHASI0dCMhSDX/DFl8cKOGqaFvi3wKdc0yUWDXA9tjWGFgWWQ3N+cg+faSaQDpsWlhgLQ+ZPO/AQDNNF7RqdZZh7+9LwUom4hDASdGwaaJjzZ5rC/RNqW3J4IrHYMn/3QrC9p91RsljsM6yH9OK1PhWQiqQRedWFvnBAf8UrSLmneK9K8Sq1u0fbDCSuSax9zYJGKo7lkDeeUkx3s0y0zm4BlS9EcIFDSFKB5OC6yXZpvyzUtztHmCx1cM1gH7BGkAG93NQNRxaeuzTDXNxedxYgyqs5Sc5Xp+7rubVNFbre9YPWyr5sRwqiolpWSUIK38AUvXpTVklIoKGNeEOJJbnY47fmplD7Uqz8sWonxu0P1g/Et+tANHqYb9LfhLbsQuWOSkhewn30FRTgTB4cm4FUDnIud9N8czkX2BO848ovNGp2MhfL6ZCJOyidIxPikJLyI2THsoSsmK1sI49gLMO8QjQqtvhsu7vOnT+gU/jhdmwt3MaK5P4Cd7xiYBQ9ZGjOxParlVHOxYyElyERBLgz1BZHnNVYn2OF+Vz3bGUnJ7JkI/oiiVHuOOExmo4JaYL4yTI4NJSyWBb8jbrwAOzQU8pINM5hIcD8mHPYYLNPRwZDh6hPT1tzpfIc4JYSNYad86SCBKvbCfvesHwn7T66ZrCHhtBwMUcSpx2ojV9ztfZt379vCtSSrdx3tClCmJnLt7q47q8lS++pe6s5cUqZlNduyXlPq6l1rVrtq880rWe5eNWrSN1W0HlHXehrJJt8oDOYNQXptVqXXXl3odwvSF4kv3eDudI5udF6trqatuVpvtN2a3FWl69m7I0jZo9rsi6zrr/jp7kri+3yrOzVxp7F+6N3dtoTLVbu3Wrdmt6+tnnszEEuzTrVmqL1Ssde5Wstz9UWdlc9Qr1ZoztwvuDpY9Dd33TYgRbXMYv/latmsuvftqrpsyG7joSfZjZoqP9SlXu+ppg26d1Z7blVGtW5t1JsU8VO/1BJXj915rdOsukXUnYi4JknNqoTUzaDal6359buiSLkMRar1RaoKtw+du41UGLyqm1q1I1rFTl2vdF5qZ+2qY6OKqnXq5X63rjcGYoNHBfVOqtaklnx3NeL161a3Vm3x+rWiN+8aHd3F9eZMXZprpbrqIlm9lvhmsVNoTruV7v2oPp31ZavarpcH6kZejardRafXfOrW5XWfF5qdmfoNPalOU2iuH2p6qzFbzZWqhB5qd25zozauZyW7I7r1hjErNAp6qS9Pa7i6LLWF2rqxdnh5Xl6Mrt1vHd0S+0aXb3XVVbvSNdVqlVerUrEhq4Vm9aL0UJ0U+z29o9SnAu61vkiyrnXqkt2al4oPdb0ykNXVqHZljG4GZy1Bve/yq+5An9ZHT5bemNVK8svVBvUa6/7TQLrfDNaK3l+OClZFrbeEDt81Vb5cQBNriq6dQlNQB11B50ezqo0q06dBd2DjnvKq1otFuXN39/Bklgbdu76qD1aS6KwalcG90pPcQU3VZNG9HWwuiwqAO9Wn3YZooWuj8TqoN1/UqvrQ6NVqyNDlVq/PtzbqTUfUbUVWhUa91kE9AeFK7aEhSr3W5socGZN1++XOVfVps8V33QE/KXReusZAXvXk2uWXh546a72oV60Z7Kt63ZJLTkec1lvdKercdM/6fM1VNrrwpXC5avCldqcn1R5urNsv4qCGalf2aFbeDEThaVTofpM3s1WrI7mDibX4wgtms6CWRh1AJxIqo8pM7MnNRrPuPjZ4SW7M9X5Pl751ngaLxs2V2a2uhMZTs6/UV71m5W6B5pIxqKsFpXZVbfA1417ol6717mtXnK7U7tREwm1BqlmOXJ+UmvOZgKpVviFcvY463cfWvHyFZ+7dqKrYncLgizybTgfV7iu+Lr+054O2UlPFVq9805rVWr0X+UvTaM57FbXarurXzap7pWykeaMnLZr1wZ08ayyxXBN7XfX6XpAK8mZwI/e6ZrMm1UaV7qI9ay17s/JA6qryqNu9+lKwHpEx6DQvrUWDL7sDcdVsdeRSu64Kg55QaD11JaXqLnu1qwelJr92qtId6kzdpmHNO7L1el+olhp886Gl11oDY7IZ1KfFQXdafHiqio3NpHA9vyi2eqvZQ7UoSnWn2OlMXyTNKbT1JsJy9+6hcre536iWWpcc/HQpjmrqPapLbG9dQ+a7tlzvr1q91UB9uRQf6t2aVF9+kTYK351Ji05VtRt6zRxtdPfLZiY0Rct5qDXv5Kq7bGxqtizeNeWOXOjIqtV7at52BGUjbZRi56Va6HakbkeWziSxOVAEqfbQsu5RvWu3dLU+0NUGoAs+3FilvqAW0WwljDYte1RR71Dlata7uVqonatvo7lTuhcuXzu83uu3y5qyuZIUY/pFvqldNUVAB7tbXc/6K7V29yTJ0nVn3l31Zo0Vqk27g85VVd10pdas9irxd1dtoGux2YT6SvdqrVQGXTSbrb8ItYe22Ci1Cmp7UFUfpSfppVdrfJEKd6170Vz2qheFvjH40u3UnMFN/1URmoV7Xi42N9LgvqDfNvhaqWXUSu3atDJ4GmjSbDBozV2hsVE2/c5Ub/DW8ktBmjavy47SMjeq3K3Js+rraL5ylF5p3nu6uxlV7wYDvbVBXf1Lq2v1urOBdl+4LY56d640v+t2Kt0a2lx96/J369581VReaktZmM6k+qrQmk+n17Npo/fU5/Fc6DFavm/Nl7xSaxqjWbPdqd41ZLn80nuZPrXmU6n9crkcVAYarjXtTr1pDfiV3KzdvfYL0rLZ6Qvtm7vHRuXyS7tbu1eregdVJwISnUK7K92ocv/1oSo9DapNUX25avSN6euge3WniM0aarsd9DQr9SqDZa/afETtixUSa+t+Vy7JhStrUFA2aGIW+i9dXe52eVk3Xzuz27XSvVsqheqmUVWv5WrzGzKmC7XanX8R9W9Yn8ptftWUDHUtV6ZXjY7eam6kh2a922lcmlTmkLsP0nWWTGLuQJsKB6bkCwyJOZJBAEqD6NkfaZIZavqthHTbaYH/74dpujOtl2eZ+0THMLfUFCGSha9sS48QCuK18ivOqLC42AXsvh2vkzjTSEwReap5L0oSBRJo4o59G3iC53Ik1uj91mVX3Gj+nU6LQtq9+3/3JUkjle01yZEEwCtLvTt/YhaA6CAPTgQQayYO+ZzeS05I8cga+ckA/lII8YQpp2ppUuicMyHUOcdU3gHcPwLX8EZa/DEI/+ERvgvIf1KD++L8R9pIJet3QvvfovIfjPW/Y8UPPZs7R/2zTmYmvv/Oc7lzGu95KvPg+McO5s8A8o+NL/0E7ILz37naW2P/FbH6dWI7ytpPpsdOcao1lUgqRqbW7hInCq+qw/IRLywL2xIkaQJPM/LpHo/JB4hJin7wyhEtOKiEsf0c9j7wvuO0iWHaTJf8zJTnz0Eeq+z1p41E3GOCUe5gNTaGULDkdSFk8JvDsUKcBQptWbqN560zGXjIwnA1nfO8BuEXzwvil8h+vIQwhOzlIL4fHZP6Tmfp/MOANn5KKqBDaJVmuMqR1o+6mniR9SRmMRScGkTxOy4N4PPNDG/MoReZ5mWC3BE1btCwKTcUyU1nMcIKmuO/Zto/znNprxDXbTpQqCM6YlGqPvIClJBvK8z3IxItfQzh6aQ7ltV+vnCIA0iQWZAFmIetPK5Jli/xqf4eoayOgvQ0YUPb4GiWRRvrFHbWc1d5xTaYosMlmWsy4R0+Z6MOL0hFFlmQqWlrG9NwWQLkV7gcFaT7yf+8+DyIY000PMKoYYV+XzgsZevWWJFzojl/BKZJ7nms6bqXUNXV7O313G1iFA4zMfpwAJWcEAtRd8CEQ7mFpvBzwQzAL9sPljj2KRm5nI7BQ7XAU2wIIisx90WYyk852g5GtpKg53ukjuDEdItsiJLmlhDjQAPXGPE8g7/rs2dgJd9ApAXzmj/l2rq5pFERWNUWcxJhAj4IbF90bWQjW8POKddAJAZ7YQRpDwkzhNSVtEpQOPPitxaWtSZRFNnTJrxlSHgLYW/YyQN/SviXtNBxitLQT1UOWLMkTovG5dsLnQRyOa6NNMP1g9RJ/6fcJYvep3xypJvKjACq+NgqfpwiMrjbx2Pu9pGzfSIdrTmSPdRe+y1Bf0Q64zAQK+GXhLzGmu24dB8cl1AmooMj++qFyIdc5pDiRbUjy9I1BktnmNx4YRM2n9DVW7FeQ6sc8QyHDWCLTdYIItboxMG7Rm4fHR81nkIO55p1OsGmZp16pb4fh5ogawtDs6B2uXAqXBRPReHslP8kAvWIRZ7/rIx4/vPnTwUx2qxjK9HGvPF40zbWR9///B5Ex1AazCQZdkF53IVEWxkUg4Rel+H7kPjPMOJqPBaDBO+6ZszSQnyCKzDPnYdX1o4RLwxtxWHLBGarzbHjorlFBw7sbqwpWkRaYlAJ9D5nco8XEkgFJS/CjZT3XCv9tO5ikZuaC5sxSs1xFkSIAE5JQ1/CAjg07mCX0rMXLw6CuYFJK2w4rJWEiLPvx0djHSUhVDx48ye/R1IIeNuz+2FLwYuS4od9/zWThQmFYJq8a59jkdDU35teCvAgy7HZ5E2cpvrxt/a2QqNMWchkOD0CrLVFTT8sUsrC8+dg5REAk3hubzsQWka8WsTjc2FSLIql8YWqjFCZLwpiQbgQCjzPpzBxYzR+E2kGQXOE0nwYA58lb5Pn/gTGWk2nsOS5pbozBYwCOfisyBKsq5xla68guWy5OW3lhc65nZp62G7u7ThVrUUcpxTxoqgaV68PNavae5JmD/JkM+rpj6gnfOs/XW66T3q3wZvrQWG27Mj916YgFUf63UIyZkvpxqpcz1bf5FnZQLWB0+Knj635ylELzS6qlusyr6/7RrP4hS+5cke9wu0y36lZT+36atGt1wpy767Uqw/qD233Dlem3bbR1Ns3V/WuYH5pdmulgXDXV0Vda79MhUa36wzEla7MBzeNmbXAuvrSfbIGnU113Z65g2ZBNduzpYBepIdGb7Ia1O6a8lOr1BKs2aCmX7d60uahZV2rM15UXqRao6KsWrNpC8+mPVxp2HLnVuj23MWorsrNp9tlu1DTGkJV6POq3tGvnvrCnY17wno0u6v2ehL/8CQVca3WGAnq47Wub5pPqtMwuv1erdu/57t1pdJYoheZb86tM2Wj673q6r6vNyujl7uXTmVQ61bLZ31xVUD1ckWqr0QkdlsdvmTL1fJ9o9L90pQbXzpzoaPW1GmjXp52hW5d2jT4Rk0vKN2u3au7xQe57DYN9UkV7nRVFhay8P+z9ybMiSNruvBfUfibiOo+ZWxJiK2+6YnLDrbBZre57qC0JCAjJKyFbaL++41ctCKBhO3qrm7PmZlTRpmpVC5vvvkuz1PzB04Najf3DY0RF5nFfVUy7+s3pdZMY3rp1bbz0mS6rHI/rLY3wqB9A0aZdPuxezNqjPudZbshVqWdNBDXktJmR/XCYqjUhr3hE90fSY3OYvg4qNb04V4y2qNhSWw0ubJaZMY1KdNbdB+f+u2FtFBqvWph3auungZpqfS0MLbj/bja6reHPNtejJnqrltfae3h3BpV5o1x2Sw9sSLbW3b7ndFsez8yn3qN6m1rkeG6A7M0rJSyXTmf5pkZ21p0F91qrSSOtsvOYlXvPd5o0rC5Hg+k6nA05+7Yldzvd+cd9qYs1iS5Ra/UbrVw/7TMmD1mrLU2q22PHW/Gy+54XG2PB4yyHw22eruvbLuVGjustTcwjqJDD3lpVBje7tv77rA9lxY3e35gMMKAXvf3T5nxotvqPrYH3TrTAv1hp7ycV2/TpVbnsUn3lHm7/VLbdOvDUo9W0uJg+Doa3eyER6XSbXQf+wPppq2O92O6yoDHzn4wuOFb1cJ6yG4yncFiI4222hhStz12bsfsuNbud7vdQVsdDYalNl1L87QyH1ar+6dlh2svCi+94Vht1xR9VF8w4jLDtyuS0WIW3JDl9uJLcz9YDpu9x/mdtFCU7sDsCbNVRhgotXalZnaHpVJvqdRHtdXdLTN86D9KC9ArVEW1djOQzXmfuZH7bFse0szLaDBjO/vZWqgzG2l4U+Mfq+neiBkIMCBSLXJlVVEHi5XeGq30YaXIif3mur2ccQAGzLzcvLZk0+Abtcf2vtu+H5i0uNxsxX5XGS3H3UGtW72jGbPLtCGNYmXMKLXOozR/orlbvmeabWaVldQb8y7dtsCixg6VcaZXNTfjxhDSllW7C0bly4UlXy6YY3rcGDPdzXhkDu6Hw4yQrimg3n7qPEqb1lCZ39GM3Olou3Z/eDOsjLvC43jcX2Z27cdVdrTcyiILKePmxpOirIXRfDlSh4/9xvyxm55D+rP77kjiW7XhUBoM+916ay2MtuzgcdwQqmavvBhrfH1eGoyUYW8pVfjl/IFvLJieUpLb9Zoi1bu3Ej3Y3kIqu1G3xleZtTO39fxuzGbKLUbjxEVmy6fbe7BUSmDB3T4t21ZLuRkKlZt7flRYgZfSppe+afGVGt9nC+12NVMCi1VHerkx+Ea309pLZo+emz1mftdqiPvuS+21X51tev3Sdrzc1obL4VjorHoDZm7xC6nB729eBuqq9DQY7u/rM72zb89BpUqPaWY1Hpj1Qbr02h6s2vfVWlsYDsf3jx1GHAznbbb2JKY1esiMtfuB0npaDvvlRVdu75X57X64kVjmrjMs6aJaMvqN+W5ck/QOK407SrvdawxLo6FUEpY3T2OmVOmxtfFoodSHo5v2YNTmxeUTPVZXow6rLJ8Wxu3TaNzgl6t1V2k/jB+l6n1dqt+mSyNpdNPt1zdbYVGTwYDjwILZDitdnm/Md8JgvhJrymvr5abCN4Zse9lOdx9vTKHelXvqatPZrEottcsPH6VFf8FUezWlNahnlEFDGUPKv5GqGIPH2hCMGK5XX+ykqjLoDLZtcWTe3deH6fFIehw3VgtQn3d6yk1PHGRu+P1cLy/HzWFjrg4GZnnM1KqDmsgOHpvbp3Qt3XlpDyR1OJJGXW5U774O+lJTrNQ06XGut6vDEV+t3YwV5bZdm/f6I6Y9qGaeemx+IzUGt9LAzN7tq3RnxHBdWlr3Rjfbp6HICJXWHtTaJhhs52CZ50SlPWjTZq//MrxtVQs3vYaojxfdTK8220qN1bD3Mi73FakiVmt9cbN6EUZS+xaul/3wvk1vWGHR5se1m84T24QBYXV+2O0M6vPyoM48DEe1ykBdVbv0uHXL3jy1mOGGf7m5FUZi4aHzxsCpH5E2g0/6mMTQUGjoooP1HWMvcr85yITkEYI6ngLetPQTWdJgdzMX6iLmiN43mbYMuYDNFeL/XQ4y43ozc98vze8rTbb9Ml6MK4N0a9RKt9mnTLvSnbdHLeZpP180VfoK7G720qgJ21Ke+gum1W/tnvZVpr1v7dqV6m5cacK/6fZ+vHzqz/bjl2b6qXfm+yDv6eN8A7kxW/3Bvr3vsK1Ki22j9jLyGPFTV2HEJd3ut7btl4E87Vzdj+ev98VusaIysiXcZuu3ospm5u20OkjNy7Va5rWwYcvczlrRZU6S6zm+1dQ2cnf1kAIVTcpLQvHGEgy5ZvVv9dcHcbkr346eDHlN9zsWsBavQkep5Rrle6Y/TGm1bFXJpHKKdMNlQSU17tCPM7H5VL3VO/dPtVpernSE14dlulsdSdmS+nI7lsBQv9tbXV7uqePC62ttVbcy0nTbfCqk1PFtxRJuGq9lPd1cmgLLMMNmfSIUWpJ5X2BvXtaLSi+lb/uT1aI67Y97/FRh7gepQr6Yuy3VzYfeTWPPSo37blMfyP1iVlM50HzsvxT42rwuyzqn99SUrtL3Lw/dvnnTGjUrLa2zq06mG733tC/lWg/W/o4182xpxFeFxrg/lbelZaYYIQ3OS+kKo92Lkdru9278bHoN6CY47ezwYC7IKiXsTJ+FNgS+lynQhWz6+Jth0u3hqzFodQCVGttxAoBE/An/aoIhCvQKIS1OjCicJj8kD04eRlPpiyClREVeeeCbYhsHnJ5oOqSUswzweRCdcxB5aGLiEM+R0jbmXw8Pf0tWLTPKE4ARAJe4CNwrZOI11YSphQhayuGn5EVkocZuEFiEh0DqQJSX0OAH7cGhe8pZzlNFw1RaId27g5BeUSmkqCAl8hiZArkbbMoTb79CraPogyLQs90REG2gUdtdeUC5c/Q15wpcc24tBZWXleg4H1dwwdRYu/wvHMzhfIPh/vPqZXWCtcgp2rftpA9i1Iw6llTsX3AHjQB82Njy0kHOp4NgYnqCaFyMuT7aGdC1bUeMYcmY2siG970ICtpt9pKSZARXhW2wBlwkntIkQRYvRAekzu96dwy7DghdqGE3+KkQN4KHqirqLm34Wz3uJc+wBZZj/NC0Z/jJTcuAwt9ahvuW/CdRf9CDISOmJmoK9KoaeNjdD7e90sTjjUQTQO5X4pEmTtKrZxXGahnfkMNGU5UdZVgrCJEPJLthOBi+F8oGxVzRVycSfVERD9Ic/vs4NhxuLfrbQ4OSvq81CQO4weia78d7BYsc30HWCqoTDq6q40sOpNPg2S4nOnmOMJz9a3h/fhFCxSPIOmSBOOgaESvkbaBEgXPS/v0Afs3bLbixJwqBbzkeZONV+UlEEBEMjtaPJIJfmvCUqqkpFcxwJBQ51sPxPeNJPdLpaEDPsrZc8ikDwHAqKJNcOM8VL0PnsQb9/nb4mU9M+TzOKNjVIqENJd4AKdfndvWs9hyhB1nfvpFQmEuHuAEbLSxdQeCPJI6DcO3AX5wDxTmuViIKknUQ4eAfTjSRvS3hj0t+ax9m5P5wQoTBrlF8fWgI9fxMYgs7od7545I66Okl5e8nNX6cz4XHkjHuZV4Eljak+nAvldG//zglEzGo7JnIfXb1n3LPRefCRNRWO+/eDK6q1cFJSJEYKYT0aZnfqd+woNGB9Ds6XSxd+Q7hQyCsFFyLv38QH8Qh9cPZ95sIYuSio7MhrC6cXaHDYHh7p68sQZFFZUfpmmViGg2ImYV3CfW90e8/UI1qsfLdHj4M8I8f1Kv97zigyXnqewnB+cdXXRSvF9qgHaVHLlkp1OJ3ag54CRBGI6LeHMo0hL2IFSLZxi8hk0kuAij2H83pW2EQr5c7O1mRS3hGBuCMYSxEBOSkPWHwOUI7I0yWYMaLu0hCshDpEejsuTwdoZQcobGeMRo7rAeP36ibTIwGw+u6+Vf/4u3gXINdQQbP/Cm/1lCCGJF+770pnHMw5gw65Se8SY4fpBTx6u5+ioIHveoRlnMhypG/GJz9w0J/Bs+O8D3oCaGd8oZ5SYEtLyLCU6h9kEBaNU4g7XtEvOKefqLvfSD6HjZxnc9MQkxkP4uUxKZWfAc+krNsdIEV+Qk2eB7YoHfVnTsJ+IYaIwD+L1ZPw6ky4kzmYcW3Kl74iCdZryHSHz220fMD/h987uLwZVMBl5Qxh9dMGLx9ifJPVKCQv6BaoGgz7fTdgdSbwHoXIeynfsqVH5cXsNlYBVHv4reLvilGyR//QnUyKvI6GqiXGKoJm4udmbwGujzd+TIP4XLCG/mExnDKk4A6GkBhj2ORCsFv98bPYIeRIq96Jq9KvC79PHmjyKsVkGq6tkS4+YNmJa7swTUn0Mxvy0oMzHC2DAOqBIcpmfwCquT3PMe+qz8411h0gf1i6cqXX+ICi6xWCYCXfpl7KooKSL4EQsIP/rpLL/UbMSSgC8olQtf4gvnrKYg7DHifteuvvREWzYF7H/RRlYTIhZD5OdizQf3J+CskWdxzhNzoMdOLwwEmG3YmEYwqwq0iZ+bbjw5PgFNcyQjeJlJtc3jMmk5xrxCNUY+w/V26FJcJXEdNu/J767D8tifvQWkXGYpiZ9Uh+47trQkopIQzLuyu52xZWTWzbxf3Xk6fOA3YxaHG7cEuTIAIQ5yINqhHnJqk9L9Ly8dzJXvVMk+4z4feAQIQI7GOaW+dYCPFuDszWOvvrTiQgMw49WFRQmhmxbd4eIj2vLpFUn0Cgy997BUqjrz2E+a8043Gbim2CHOKv0WHMXxXqTBj90kV5Iy7Z0J6spPaQQy+mNCvFHhDFmN/KOxo+Jfi4C343OWIPf5J/+d6YADduNbFOVCvKyTN3rh2+na1UqMi7OybTYx5RkV/XF54OMLirE9SGp5TLtFFnAOOlIYVPThgcWraxZFwI3A4sQQaLBtUwNFM/Rk24/Gi5Hk7Tv5gof70aHm368cYmaK3W8g3fPxmC+n9p4foAz1EQXF+hsE+ZKY+PSfneU58s/HGyYiXLEOCh+PkybAFLhdzzzr2jX+wChDDxJLM7nB41HjgelwLSxxzgr8SBJUHCGYyXnVS+FNfCNMXEl16Arsx0V0h9PiGCjvk4IrbBirrW76YRTc+wpiXpfc4RO3Pp+kNYRCOs1IDtaJjcoIlT0bnHAzW0VAddy4+j81z8+aSEnKTMf84Nu7Asvxrt4wB8/YUYBgpYwFR5aL3zV/dPxUx5MKeYNsgmeUdiWS7aHu73L0jMg3hqUcoORhrPeCdtqcfhpijvP1Q8Mb3S7N2hHUI1yPmUgyoYSt5C5T46bcm4JdGSgJrWQQGwSmcGECXeWWCNbgJBH48TAU6vqvClLLBAEOwEUBHmPp8Al+fyXGgQPOpKT8FKS7LpVOCIIgpjqeBxE3FPMcE+XqzocqXf+RlnEKCrbkXPfStVBtrq2EjYueDngTShAWd9K3gZ7mhps7Y++zSxwqG+5PhGkAeZSeHRYf3Wykk+TRkcCHnJcR0jNJWA8MA3XbQcwEmBiJ+PiLGNZxzgfqEGOkhqTSqRI2K3QeHLBO2FgvjOg60Y1h3ceTIsRMH4sCJAObx4LKUV7AZmDKbp1Sw8eYBwu8SFRnmPEM0ORvd9QO/BEG0TBTAr0OWwcG4k6oIEhVWIWCLM16V93wg6vItpN2BjqqmvJZ1y0gqKkgq2UZWJW0zkUiyn/8b206EJ4IVRvGdKM3afqkdQC7YM4lzsWX16IU098N161wU7bZChMBKTtk6Vur9jUj+l52jbkW3cNrGc5BLdxgr91dobhNZnWrJvttbMclx64zSn6dmfrn8xWb9Z8/eh416asrLiqUnutt4YZZhkuPFtxxNp50uIKUQZbO4QVmDbvPix58oddPWKZjLd5hGtyt/nttc9IWGzADct3/+1O1LTjHyfvTXhyyB973W/lRx6/TUNRAcWgD8WtqPnzuJH7iLV4p9iU2oE8B/8ybKRt8ZJjhptrRUqAhLE/z3RAfTCcfk8xlJ4rJCAdBsgWMznMgV0nSGZ3PpbJ7BFsOwu9UDb85dvBj3I47r09eCrF6LfCQTzxxSbR2+rNcopthM9njbQkYQClKeZjienhYERsoygGVArpCVcnlJFKUpk86wUzYtSmk2z7BTLp+hhXwuzwOuwHFi1N0PxiOsdDkM7qZHULpEOClTTCThlj/eXZrnBV5gGVqQhEIhDwrilMtIPCsWRJDOsIVcjhcyaUbM5hkhx4lTBnD5nAAYQQCFKciGY1ME1iSausvDheK52RXdqQtR6SwTJkirKoiChuGXNs4Psv240Fbk2oDrErCuOb+GoyXAe40kGwio4Dhmih8s5bR+LejaxgD6BGxNaFrQVNj7qTw77HwJl6ScktDNsd1RNrDDFdUlA4kvOMQJgm6u8EZz8CZkAJPVNWLKghsDXeNINeN0fBd6PeyuqWvH0OHt++KS39mDiH4Uwj8odBESoBVLxYwTFzBYDP0jAnQF982DUxHdt4huoEugCE09oXI2dCVD3wOGPn/wjBQ5Tv2yP7Dsfd29DAztoQwW+RXs2QTm6IYm0UEwfpKxScpSuGwoCp1/Txxd4Ezeu8TRX6cXucjrgqYKCiS1+5WOjBoMz4CPPs+IX+uMKLsL7vCMEOdAXFRkYxGidt0RNpy1plhLbIdDB4MAKFSNYBMAVdR3q4D2EHUFt/U/L0HMRfni8gKG8NfDdjeyQk0845901/iqHrHZlh34Nsghzc+A5J31EyuT4SRJFLmUIEpsipOmXEqQuGkKCGxOyvAZWkzTQTMuDJ0PgdUto7sg1eaXhE4GkozpmglEaPEh4GixO+Z1JhzkUfgHBnXHu26w/a/slgpZPoezs2b/SRME1/mEcHWE80mXoYqiL4PTgu4nEJROXhLEIcJ2rKHDFg/gFTUCSM9aLoEKMYnACkMcQdZBfABSFvL9hDYvgZWi7YgdEPLK8F5akdNXoqgV6HmNZzUSYAmoudgEa5A1BfKEQcaUNa/LmPeIYCH81/9SP+AIEFymewg691//6/O7/EBq13/971wzTChefiDYJqyEOe0dn1hPZbjIr4JvwKLGBKoEJATka2G7SKSww/BRhFkOzsbK0leaQXIvXJI672TgdAMEBCG6CZ/nEmr5t9hh5ydIA/SLULwRixY6DSA0AdS6TGLD/RPlExCL/+n9CM+UhJ3EVaB40C3DREi3SU0MvprIPfOT1B3DQsMw4SFwgoogz5BD9ciJ6J37Hq5OFd3qaLsY556Gfv+v4f5xYLQ4FOAH4uqEanAg4qkhGynliX8ozgISF3CdhkfX9TyRdaRkWGxdZCqTVwFn0wybyWVppLXil4bGEkA/vam5fGued8djhLZrGh6UVzwsKOdxzTglrrGXx7gmw3XN0ix3xTBXabpwRWMDGmSQBBMbvOHwXk5K4NAMB2ruBOc5zXIphkkx+T7LfMvkvmXyV1wuP/a+UdVCfYVd8jr0mJiFYKYhARw9+lp0Jtj9JSDIBkRQ1nRqKm8BRkiSlxCgBCzhfr1CMMTuWjr8fOJ5tP2R+K2nv94zyIGNYr8tMPYh2qYjVVJEqqTiOaZxAxD0BQZMYMhEPYZJrbWjRpq+MFa8CKh7FVBNt2ascIaQHn9gLPjfyY2XxMmA/ztF1MaUCsyNhgKI/2oz9N/LFRiymLBf4t3x6v8aB0XQ7PQuC+gXdFuEzLMd0xMCQAVtpjAsAYs4++pFhuC4eDMVw2OxhH9F2ChP9s8KDYKHV8OPCLCCCabwwhI/NgRbqqOhSNG5hso4iOZYbyRnJrn36VIKEjfvvCcIBbc44QoNs0Q7H/u/F/xKxgqQo7jwBsOmr/jNUsJ49MWHJvTUWeY8UFDlryywhA+uNvaJpKkY0oE4Aq4xE9AluW2gy7r9didcSHKf26GHwTLkd19Icfyt6PQOJnoGxx26GuM3JeraRoKLZvHGhqyVuRMPFkGyNmTVtN76QQtNkaU3tmHyqmwt39YGDH6VVaDAGTLYNw4MZlwIbSdMtJES7nn1r92IP5KccBHbigzj4ThHZXqOoL/NoxK/OaMzl6KzKYbr0zB2/EhGZ+ytfTrO1Z68sLVTdhtGpzqEa4p1heRX8pVlpNgrT9eO5G14pvZUN8iMnzoKQxdIQFTHfBUunuh15A1hgeOXFzapSrzPJYXjf7BdAR1OJ30q9vT7u+WdkeCweU0qno6Wsff66NpMaivHAgDFm4QM1QO5f3pukSdHSRBzojAVhFSWpvkUxwIulefZdIrLCBmQz0zzNDeNWKMwOWRigDB2wJptF7ZBVjQV55LA4pfUChsMEMoZtMyYgTmWNNGC1oIYV2gmI6XnLL3kjIheYgvYaYSiEPthmgNTmpdyaT6bFtPTXBZITI7mJZFn8kwhjcw5WhjZvEEN41hPmPRV+iqKLx0iv/FKiBi6xw+ON12IahbuPk2PDK3oocd46Z77BjPUshW2JFDRd10OmqrIKvDcOpwftOmU/MtSF6q2UaMuI5HGqbfPKWn63rMkQ19B2SWOv+t/PN/53xeXF/8NCR7gj/8D//HHH+FfGDQj+2RKhCzrsT3KAcMK6mcQ8HgSMGQEPouznSTwzHzgZ7KK5vK6jNGSYa0YKErhvGVtDyozpHhxXFC2+hJOhYb7HbK9VjzMqsakpigQCgln1KIKtohnyvOywxmC1migT1ahjiZ4mimQ3c2Jv1PP6z4Chp5EDEn/AK4atxyWyuFa2oMoTz6VlryJcQfugpeNfFaamtMr3pCmOYHPX3g/naEDvYTtBwMY7NKX5AVO8yG6feRFIE7qEsz6OqpUQRIJycnfW/GG4XL9fS/XUjipK4WdJqlmxQHlRyFmcxmFnuHSRIU4wfCSzwvTtJCV8lkmy3BZbprN0IVpjoVcmwWQyV3hXqOLsq//0dqabNhJfXG/o4eKv/lbBElKM6IgchIQCwW6kEmDdIHJpqeCIDAFTiyk00xa5AtTms8CjqXTXJafFqQ0mxUYieUzEYrhcVUcrQeqgi8aYbpPMg3d8byhdlMGa0Tq55Eq48FCi5g7r5g9+RmRiqS7IX4RPfLj1TFD1PRwahVEJ2Vn5tEphqYhr6XNYO3klEHpTsJs0rpEYSuA7dghOPveYzkkLpCmj5+xdi89g5FoPUQcxE4o4jFL9EpTZHFn0+WQPEqbMfEKx73OdM1aOdGvMKaB0Ctix2CQ3iI6bSJ5MqBNmIf/dpjaJrjbMQR9WBZnfCvIYXUohIKplknbs6vabQWSHRM25639A5mQfGHeCVrz1oQK0UEkbQIjnb/uD8/cx1iN9mGFUhHwdkTcFvAQIm+I4yoJW14kyhp/7JRXlDhYpIE1GdoEbFuFpk5eF+cTw5oid3fClkMacCgc7T0g6gCBm/AK7MEc/lOMBZwbCCSK2aifQvJnTV2MZFywRVFnScOncCW3/kSbTuEIyKvEkVgH9X9cXtjrYSJpkBEmYZsHtX9cXsx4E2z43QSjO01Og+H4mzysDttUNAFOtSgCBcSDXQ60GtIAAmI+Y07sSgiXCC6ixN/o8wriFAcnvyNh5Jq3Jjq0Z7JhQpOfagJ9yqOJnsAAS7hZk3roj7aFlBVxOVmv1ImgWZBcYTchZGNJhyOqGWTv0dGOR4famk3YcqAy8nejpm21PEFbnoqwHXS+TkjuSrKWfFWhDmEhdGWbEzRh5GGgMkSgUiEcPq/gX90YmgQewbAWEP+6blowPNWOIEjU6kHtEByLKA3qM4TjqGb5a0ZyYDLpMHOGDoEBp0FPHCkfKzY8+CYYbA6NsBN0PYhxx8RevwmfUJoF3zTxNBQMzXAgZt7QPD5C4sD4nWjIhvdzDrWk2mCwQU9DCMBaep/x9DQUMp7ERB3pICjbQZ52fKbPm47jRyV5OgU6dPuZvD4DJgXUtaxrKgkAfY+4+EA3D8Cn0DUbzcjBJ11e+FaUZzjCNljoYkyADfhR6ypiVniV0lY48ZJSSLw6UdWbFcNn8eDxRT9BoHqS5cGbEJsHdkAF4WvlYxYCQrZo4naY4KoIXxCxp93efIe2yG6tnE6nC21e1dyIbWxNxSLYbo8YV06ERfgim7MpmoUREEz6G5P7RtNXDJvmMtlcvjAOMwIdirfQHuOkqrDOHe9QJkODPEfTKcAWhBTHSFyKzzHZFMdls5kMx9E0HeX9irPOQyx3MGM6NdVloErKzs8wlazrVXUmqwAgJtcu/H+BnC82kwniopzxGfG26anNiSxtRz7vxFaNukI7aSb4tegGlWIuLn1/sxdh+ByxTpW/nWDsgpXCi4QsGZo5EJdLcOjfVwaGvdNfh0Jv+aiTMO5kva84Q+EdsagMk8s0T/9CMUzdXyIyMnTrFAY2SryxFCxbeGmJ0DAQcCK28EeFl4QFisdySNqe2wQGW1IpPl1XeNAess46F4ckGxBXQvXRLSq5wcVb0WPsIj+fa+xyq59xI8B2Gp233TOwiVVCk9YK1iIJwgnidcGO1DtjJJ1awUis+E241RAnmTjhJUknV+AEN3dPRcwVBhKaYHCVs25hvjwtFI7lTVSM346nHjaauUnEiU1mnqqucSr5BHsruve/hHYoUgnWN5J+CqrhD4hKfCyFm6jCs2niuK3JgZt8gYSENJ+jgoT2PDJxEL4El0ks2mzbdvJ1E5XeE38m3pwIGcwSwtgBqODSMkyUIo/8EyfYYf39Qopq3DM4RY7+lCeC/4OWWMjSOne2katgndT76tQ6a1EfWbzJF1/MFWdPDtS4YsxKQANMsmHdinE9m0gLdCE4yOKFGFgUfJ9lAumSgnazlAZBLVBgyRXVRFAtKNAB28AckGvqFqXl+HRRgvBrmNB9Cnl4EcK5YVgAB8tRKKAHU0zCRU4h3JCNbMQCYT4w6gFIg3eO09it96ZFHYN1NbiiHeLVxEEcuMpZW8Fe9wZhcky+9lGts3bO8R3z6b/BN6tf1U/zGc70s8OZjsFJxm81spWPDJhK7NXE9c88I+0jO3BWfkZOfUZOfUZO/V0jpxRetcW7rFqJJflhdV+bhiWowJzEoXGLatfbxHl6nC2XDvS5WFdQ+6yNx4BYRLwiFbAGCjx/Db9jiKEjsF3fLX4NiFCqiImj15x6n1Fwn1FwKNZiYgLD9F6p3+BaIi1KYItaxVqGn7sJ7osp0NVUCKnTZ1he9A3g8zr3jwrDC5/cTwi2GPP9icAW7h0Nielw9RWCMpnAHv5+XMx/P6fySuFNiCTzS3p//1a+W161prwIzdQJfYW+mn8HL7AEZ1WbJG8rUNfXmg7W8lm+5WD9d/NUu39BE5XOn9sWqY3E2FpbnBFn7Kn3zh70f5rn2z79vMD5McRzpHEJYZpZOgq4hogqlnEQBYUsTj7McpjJDLsJzU1TgIh+XeYbnKwew/4UPPfsPkYdbaGf/s6k3r+mKhy+KH5lffgXv+S8u/L7iTccXCZRHgb/QDSxLPuObf76GujfMQYBlHI8ZVeksCUYeuEhXMFKBxCG8tJLZoxM7rA8hSqgHAgBYvvMLEiy4QhNZFG/xoD5VKXdg1A8mgLlusvHAXlZsFjF+RaUjLEjTI36Dgf7eyLjfXyABDJmU02fILjEk1uLORxRiCCmw5AEyBnq0My47GcMNdesE9hTBYbOQgqFKI761c6c45MzyFOvqTj0M5TE/l4lTvB08m6nUbdPMIZk0pksy+XO6Lc518GRnvfxY9j3EIarU33Pxul7gcvlCzn2jL4b8ja65z34EPabYc9YKyzqOXu852mO5dKZwjmjvgHK+tiwk+ew/yyXvP8shxf7iQ9g8/lcNs2d9wGquZtMNUs/+hWquauhMqER/LIRSeVYcZ4ZkB/dQbIhpHc2xosFtSyqjtxRWMvTyNDEwnKJJZoWE5cOLDEmkY+LLIEBwq3nHktFJeHl01PPS5kO26WqzjeF5CYEHdGnP/RoOkMxLJkBHkH4JRR+yYk8JwJ8ijwuMBHQ9pGGzKJ/PZtA13loSUk5mXqCrMjm7uLbhR37NrHzC7Fyan/z4ZXkoNfowF2tINcVSiXBpypclcZc003KpnI6IQXtz7oSNX0VB56LdDJEAQkPQwhn/Tn4HEyHB933O/gP+85E9eynkM0KwPBAFAUoq5SmQ+woamAAmKcJlitzhzOBcH3A6++TEnS4KL3xJf/3zzdOeuBlaHFNXjRZBVLSTY8rh8g09Ht8crtj0K9+Cqkg2CMpQfVQieNvdK2uNuqm/UscoM1jVEz4e6kbNIiHY4wovSIu/jClUDQpVIQitjxbcEA7xvFPgiX+j38kPY7vQixOU7SQJ4ImhUa0nUgkTBCyE1giwAT6UlaBAaWJc1Xy2C8QG5shK0A1lR2M2HVbBC4XL3RF24YS9/UG9VtLFnXN0KYmVVVNnf+dgr5DwKNrx0rXliu0bqAOQYLEUgIPsRZ9L/LnOb8nVJonqidcYOkaDOygSDkHA9IzQF8MCrtZ30fsGCtFNonj1i9x/vfCsU5fMPQV+s91HhEBeB/QV1kOPWLo4LNs4YrNkIfZi8vgWmiUH6iB6tD4Bmvn2CsmiyuzwWcFlvSH5UIeMdm8/VL/Q5blouqxnP2JB08ymSvP/12n2fBPKekahDUkXAlu/SnI09++weEJVms+rLPUnawuqDtNRGLaV0+iYb3giE+nNAObC37bdEqzEb+nI37nIn7PkN8PD9/wqLIIG4gGJRvl7sjmAzp8e3DFUX204vBChybNZHFzSTdcNMnLORuPKmnmnPpCyn5BAf9fSJzXFxt6UUDhTHY7Bgx2Ip34mI37jtqBPWjeV+DoH4+/6kQQ9DmOLd/7PB6u86NkvQ36QmWDYLDkZdEr/nAsoOab+OLwHn2/vLBffWZrqHpwCNCPYd/vzUIJ4s6bJF/eKYQyz3E6tpM7gy57FLYoXlHNKVaiL228bEsxKR0sMT4NuuJbqikrlIwu/fC+u9Fl0wSQb5JSwQZSLPKYmjewQ0+AvM/DVno4U2uYH59oj8dpW+PIpEAY7EdcPgP21UtKko2Vwu9cwUa0rUHz+KARHVfYQUxqNK+QlRbZK2DUJYQTiBl26VqCw77BhndoPtjqML6pzXlVUoBtJkaXT+v9cGhgEMCJCzF5s3sZRpGtwbswGhRl97a7T9wbcGD9fEYunYw0/3TinAjEf5fI05BB994m7F0GbUE6rwKsJ3t/RRYi/6+EGNn/I9ptzks8D8J+U/jAD3NtCYK/GIHOICvV4TtDfjqsC9u/4vUVH/w+dLj5fzQjKNFQZHdCswzYyiSIOHw5azryscGmKVz2XHzmn8TyDRnKDz+nBvsPHx0XtteCrF6LvBnFdzPn2UyIy6fXKKbYTPaN9GBwPufWUljpchjTR0+eoRAOb2yHW/74u2meF3iBZWhBEgqFPCiIUy4j8axYEEE6wxZyOV7IpBkxm2eEHCdOGcDlcwJgBAEUpiALDkQIGuXjnONoyMtQizvUoKayDjYwODvpao0KjKmSDO53XJsfYz5EEXznGRHdpDPfKOORPBzjUMCd6C4/VNLpaoEuPkL+VEhSkhYP+FM7F4dpAZHv9eVmRb83WyhIhXyWY8VMlpNYkM9kQCGbZfKFgpBjMyEs9RGJWv75It6voqeQmygENdLyXFb5KwqxGNr3XZju742Kooi3zWaqCjaK8KNsvdNjM/TEFkBQROOKevDwposmtdMs3XHX6YBEMPAwTxS+C88z4WAgEVua6qt1RfUAoBzWeiedyUNbj4kk4WfasBqQVlIEK9O4xmOY8o7h9WlaJpJHxqswB8L2KUafHWgooeXVoJb8jsL1lJ3jjcROS8vUINOmeDC6cMokIKLYtSuqgscT6fcIJwEp0zj+A1F1xNr8MXIoIcULUKWVJqthB2Pz4RtM64Fob7oMDAegEOp8TrV3hO9jCvmrDHMFTabMN45Lw82/5LcE9zJDEqndnPHAHckeXTTwuFToQMPgaAjqig3baOSRnRyqK+bBBGDwi7fNwBFrXKSYJz3nQ3c1dMJZuPfKDnfu2W7q+eLco2HJG1CMnbEiWsVeZ1Al5j/P2qCqMtoeG1kHM4vXJbdxqG4FX+jg6ISM8scvrpBOxh+BkayDOqz86wwCy9H54Cgc3APDI2HDBytkBQVlzKEmT464Da+vfHL2hMXHFzqSKHnfg6bgoEAma8StFhLUEvY9CVzH7/JdL5ZB9ObEVlV/1aCi5nmNRzELC7+xbfmROk1wgH7hoNp3CJcO3QW/Zpy0LP1DZ9Pf8/Nwo378qnMKPf9TGdum3/OG44GMOOp3JOV+ssPfBaeI6nhsx2msD/jbOU696Bzv6EC1By/UoRnqZrBjgGSVKjcrXah3LXl0WyVt2eNhj2RzSn0nlb5DP5kTOv8dWiS/Yy2LDCd5dsI9hmIqWBwb8f5BhzEGKLmbyxdKAJfC+Y6uJhlmaJFFaD7YMu4f9jiuro8fJ9v7G+msQsgqx5cOXiS+deOspsRL5z9XJ1xbHz8mPyE64eimfkuUwsnNED9aIXpsPjha4fQ3nBO1EL38Y0YvOCiWh3sFc8uaGlzlKEIBSBQ/g3veDDOfeVi1D03MF4qsWtsL22XhdT54/QDvYLy/vODV3f0UOdQSeOYO3UnQDZUIgwVefB2K5Dc1diz4OFlLnlTotzQT4cNI1ggUk7IKFE1921CLvC5oqqBAR+pb2iEU1r7E7AkMs3jb3B3NF0nYQwiiJ/JvboesSo837b2bW7Nv+1DVlNeybgUpv5O1gmCKVhCL681LzHVXvqkdWTWtN3ZlgWCW39SEyauytXy3vXvIzJ5wcKMI3kPc/F7k8MMTyn7qEKADXpwHoupQIDxS7uayLqUw83nxoYkTVr4vvyMLLsELpH4DV7Mr6ntm+f13dPf6PsfPURqj/ZRh599/P3FXoKOyN0IXiIO1HjerzD5mwseliVq1FftTHPfkX3ZxjBZD3mAAUQcR+oH/LbhkojeRxpHuC2FooUvQGSe8SiDC3omPJOXif6ZdAZljAoz2npdeekY5OB4e2yfpRtnBz40hAWLg9S9XisyrEFsKQV8cDkHZKUL1UJHjX2+3aHoDNT2/qZrq/dNSF6q2UdEDkxxDcBVDiM+ZzotgBXRZk2wzUlRYJ7EVExCig294IDu16ZIZnJxGQcyJwlQQUlma5lMcC7hUnmfTKS4jZEA+M83T3DRO8KC/a5chQ344yT22RzVtDPeDQMkQV9Gagw4elMVAriQnxMYV+k880bGyES5jrKczWUvdd5zgKz3/WuS+IZrV4Kzm7PpnoGd5WsHS8AycV08bb4Du97Ti8MKdCavqacqPsEowbd8wSG4Lb2B09bR3jMv1CCMqHmf/YvSNl/dbo/lSL4/g/RxsiASevaPGOw/BaViqNA5QaD7Ew/11jjptSeLPg66MRJEIXrfEQU9+IuL35y6MuwvDCWK9i9+3K/DQxFjtZ3MrhiybBFyxmSS8ihEnyt9yy508vBLuRQ+/z5khQMcOwhOMuwlHbJqjp9NCPpPiOTBNwSDM1EEQZkJFaOJIiMN+wniVqayYQIfJWFAVQ8lYdrqKFzDTuKKKa15Gs4etoMY36vkC+0DN3RXcTs8Xl96fUJpT4DdEImpcyVL47yGtkCdhjRn8UpnwpqnLAryo+mK8wtAkfB2j/viDekah9P/HHzL5fHHgsInKTjouEZMRHCdcKUiPLjsdp3qapaPq8ZBiw0Vu6CJxn0cvaupO2wCdrAtKViUcnj6XZ3Bfui1cHTkrffgZvCECVYLHJULSwG+G0bAQDcwzMojyDejeoYnMJYtxSJzYzT1U8MRd7AO2cFLG5b9Uxp9Qo956b/lUeGIrPKeX1DvrLomIoRMpMAfBe0Eebt4gAKeabkcEe0P2/WF40JgBCNufLX4MC1FWOBEAaBFTijY7QSZt6ei92nSKX4LkOQkHWFn6SjOwrn96wxNY6TDSa1jgi0GtLEGRRWoBTuSM7sCC7g2etPsOQ69bdaP5VARrbf846Kw6Zrt2U5vW6q/V7nWpLv5xONZekuJAZ3Yr5xA42QnR0teAzWSYQryvxzb9d7b6EkLGD7b6+t/yvlbfoIkujv2V9CfK/hrqPjkd/mCZc2QGjNATYPiVNrXHgqQP+PFx8MYjjJgoNxyzZHl8E46GgOJJsB6qqc6qc3BfSFPHgrtsk25dQ0bZtmZixJjLixHc8yXIp3JxeVEivCp/Hs7XicDxYMMwbFxWSdg4g1hMXi1A/v4bWn9hbyzVxKltWkiGfRnlJ9nPj/fifzxG9P++uLz47z8uLtGP/wP/8ccfUeZwDxVq+LpqIyc0SvOHRU9Zi5PbuQ83zhGbdigbV0hk3hINHVy1ENpCVh1vGo+xqGSE4AhJESnscyc5ZrJO3RXbV1SRhJpoU4rGZxQqDh/aFTDgBdwVKtia+PTRgfttlzBEdk7x8J06EDTNpBDChsKvTG1FbfgFOjAhJIahALC6otqaSYAzXWUbwWksIZSG5MJn2LHMlDyl4J0eNmyphk/qEVR3z+SkYynmkdxkISJH3ruSARV2rlMYcIKMlENO/cEfyHLxPtBDA3FgyVC9cO5IoSIzis2InisfIasK3RA4EhQmt/MmSCH4YL/6xeRSdBaqXzT9Df3vONYpHaCfiNJVqCUvxvPu0HSKplOZKvr/6RRNx+yGn73iSD/cgui+fbw3rR21msPjhqTyH7w20pQiaqokI0OJvb6cw91zkpkapVuqwz39PqHJqOkJrBgSke15ePKEd8hVzqRkCXm7JxPhnA91QEowjoX39D20zDpEJNGrAZaItQwe4Cr4baVrqcffD9dBInpCLxn4CWpCaSmrVA/FXpFjL54155AE5bBndzDYkMLFYgyBJViqaSV8u5c05UQP7KKnfL/0VTyJ4OdYOXy5E35JEbB3UvpUyArqwJG3uVwsASuLhMUBr0S+mpKAycuKcUXVIBsHBgjAAFeDUpf6bYAu0lTJkhWJ6pLx+h2XbvEiPJLk+x6u8KBrkiWa1JA0XYW9wkXRsONSaOyhsRQWQUsVxvPEGonf+N/hC7P5fAH+9wAtDwoiI3JHhyfhJeMvxnG1kSC0kywyIegkaQ5MaV7KpflsWkxPc1kgMTkaojsyeaaQpsPpio5/HVXxTlkbTtlvKGwYJTmfCLg6uofj7Fp7NWlT6r7n70r8XjDMVToyfONzI3k3UvgYRco13/ScmIT0VTpCkp6GHbE74NkdnjvTfc8erBBBYKeyQkj+OCFeYUlvA5vKk3KpPF1bHqwT9u2nLSnwZYdahK/LZwQ0rF2wlcDVfr4zZIKCh2ynlSuqS/qDDauGqK2Qv9I2nqiIuECQJQmogSI2DMgx3R9lV0bg6lmEBw8FcR521r104yhPeK3azGURh436Bh9CuluKRNAYMRhjqIdmyW/lJRTC8Jq0lFX8BxMBtQQ/9LirF70cR1ig2zNYA31nj53sp0TQdGRFWvnnIHTPkHOC1LywyQojURrDLaUQTpEgtzj3Af+wuT0/1o1QHts48EGoQXscDyb8xLrH14FgEv5JOhrekdUPvrr+j8P3BF/VE735V+ROhw1wohQLf+1fNat6xc9k1U7vwKiHpw6NUNOhK8GgTUyXnKRMey2FyCgEHzeL8oPzM2JxUp2mY7QH9El0m4q8lF2blXpel03N5JVICyp8GNIybwdzHGtzZe+E422iYsdb9F7dnSlj7OFmvOPE0IFPcn8g/WEOwOhmUMQ5TRC79oW/nbClZs6P0ICgx4ivAyVNwFmy2QY8EHyaSiFVOD4gjd+JcA1fA9Vj9A82rJvk0CJIbmFxJcj2WwmeaVGOHBEqRT463AhjnjvFuI4/IshZt+QwpYphhXh0AmoILgrqD3N+DdQvME0YYeEiJlF4PBN24BOxHRFuDOwIi6MoJwN/JuaHOGFrMYMBw5zpRGV5S/RfqPU2NCYdjfIbe3k4V/F7eXIsQ3u99tJFR9r3ghfE4x2002/jzO6c16UNr4dr9kUKt441Pez1U3aUgw+C3Zx2E3Cxr2XdtHgFmsnnsgqo34at0Ft0nK5Fub5xPzzRS0d0XjcAUSzwQpYXUmmhwKW4NFNIFQock+IyBS7LCmkplwYRVwrHrfHGxYV8HrCdj1levp56RVXECW33xifWgqIvROaeD3vk4yknpg0fffjEpjmO6C5yMJoa/G9X3n1ET23y5LheoVaxHM8rNM18o5lvufQ3cfqNYb+x6Zgze5Zf6IRRvtyqxn17tAPC9Twk2Y0tXl9Qw2Yz7vstxZQj1gZEzJRJEKV9RUb65f9FtVJozcBe/vlbDFBR58+UpoJr1+Vs2P+2l8g1BO+6lsBK0XYwPvB6KS1Tnj+JNTbldP369zj3jrCvT+KUOekFxLrUSaNlotPIMVditepcef9vMZnGGQscEBeaaPif/1QcpOL//OcbDFWE90loGiMcvjaUJGQIqVQfqRSU8zEgdfmVDB2TKODauN4DXZuYumWY14YluL9LYOv/YaoAGMyA8iiDRfFeWQJzrknGNcRbuH5WY2ZFBgGZ442cD+Hh6DLGJY8sWo+sLPVy2UyxV8kX4yZ78LOwI4OHcK6GIc9UHPXgu2XYfIr4AMNSzentnIek0BRs9wQgC1DXsq6pKGoZUgagRYzN3GiqoPeI18FcswwMoRLPuBX+nTHDbeOoRufG18a7IhxJJYzODfSpfpfhF0wy1yevt4mD3cOXUBesFB5y40LDlhm2noK24IOFpYOltva08JPWky/1BJrKDxbYkt96qzChYVWRb0C4y4ez4In9OMedinHtL51LFa9KuoZWj6zBp+Jc15ZAi/S7BnqD+NYnhrVc8vrRqGgX/tkORPfPs2z4FPfT1hEn5/KYyTTq3bLhw363f7ZvC4dOG1vDca/m5704/Fbuaf10cktE06ecu9OpkM9OU+kpLaa4NJ1NCRzPpkCWneZzrMBks/xFQuUsRhfOkqja9ECoHowjDrib8+oMSM60RSyg+GI3voz1iVV7KbprI0R6Js7ewnsrQcrWA6wArRhvytQ6jJaMmahlZ6xEW3+IVRYWgJve9VNGigjseiMZIE4UKIxgd1aIZ0uTgw8prC7cKFklJ+JPeERc7QgV+wdHfOI/Ca0sZpYzIl18waHBCxNCs0DQH5i+AlN8EHKfFGbT9RDpEq3p4H6A5thuF1kOvhgkmNZ5CdSlEYQQIqTQ1NRKB0sZcmBg5mxI1/ZO6e3RlpFIM7gDD2liZkF8EvCUIaszhRAlUy1434QJGH5jNaQRFoAz4Sgc2Kl5woxyDF0kkcLnMzT9zY3CB339a0zDyXylAQMb0jo9drbTR2X8AyHW+Ri+9CPTwdwsMEx3AT1Ufp4aT5C4Hfp+tJeDr53+Q4buGqMpuKs3apyp1Cvqsg6sjWnsuextuaFn7nfz0StNdw1pqnCZ5UztFK3qTbZ8Tz/pi11fKdQG04xcooXNUzc946rVWrUxN63sS41/nbb0UqvU22dlc11odB4XfLdwL4Pbzh9/RH/9EYlvkkQ0F1PQHQ5hd8AO7upfyEEFU9eosqXrmC78i5up9gUVdWkrENS0AcQVm8nqDH6KaT2OD6hTJbFF+j324Nss6KF2FqQzJIwL9+vwSOnx7Dt7cs/ctqg6ahN5EN9l3EhbH+Z3IFC0p3MrCVtKymVHcTlRjvcOl4nZnzcYJcLX3MeaJi4vbNt2cg8FcbhN5NWaC/9Y2yWHgBVsYPWgzYBIU48q5J8xLGii75yhIeb0VQEy1seVFZ5PCaEiDHxK9md+Cpuls9+4HEwnEqcMAs749i3eZ4VdieABGCY0nEM/tknq8NoU6mMLzzHD8gsFQSQ0JbhS88Bf7DbqzRQhVw73fnXiBvoOLryglD7M4TmmLYXcMNCXkOcUWApAwvwOBgx8PGMQPzq2I4lLPZkvPc3yPM3RXCqXnzIprsBzqUIB0KlCbprJZeg8k85kIzrws3xZkZaIEzsmbIC63iMBBjdXX6EQMjUHLKJCgS2kH8RM79gWZpDrOkH4+Fu7I8Mc1UyOAwWaT0HWzGi0F49NN51NetM9ogf7jmGPGeSSkoAur+0rrCd+Jpa54r2sE2hlFZUQn7hj07Sj66CRHcKE46gyV69/H8yuT7Lzw4Bh9N8pkp2YgtmJxifjeXST58YhHwbgGohF0z3akZ8LIlrgfO7jNtPIEGVyn8VhytA6J6sUiaUGEqXYvEv47affERm23D74khW0F8O3xmyfpeMFLdvtO4HF6LM0y6R4dUcZgNchsDmv80to1jz1TpoO1W3gjW/ilVihtFVFZwADpxyKD8atvE8yd/CY/eE7PFiajviG8FtcEE/gxC33o1ADDFFcTtYrdSJolirxOtQ3V5Ax9KiJeuORL15rju2rQGPfK5dbOO5SNnFEE1I0eWr40Kbs111Rv5EQl4OExRCxRIhp4xDVBj9zDiRLCdk0D5qiYLANuMJUcedSpHo+7AAIB3XgG4Lep35baYpCcpym0IpFAEV+v6JaOJfqG/WdWX4/ofXOY04YWpupQzSmUOQDj72d+M4R0bWMkLG8UTdhX21q8LqArJdzFJjHQ9/bod0yzOduzHk2k4XTmBGEgpSnGY6npwWBkbIMYBmQK2SlXF4SRWnKpDPslE2LUprNM+yUy2doIZ/L84ArcBz0XJuKMTE0cQEvzFCz07Qrgde/QVQyuAsTUEsoRhDG6vQAu/lNnyOcbITJyEUO8XEwxDAIROIhPbqRkFN056C9UejdV35VPxPPwWl39B/DEeqSTQWz/A6ipf78qxXO91EU7Sk8H2uXtHQCZffjIXWxDjoxtQWMM7cOWj3A3IVPiSjBf2jed2rGFbHc4L+JyQKGU30QXG/CTRdtaSEqUyzQoKUmQMMdsUtGvuzzGnrqGiq7uHeft9GIVYTDEf4hZ8X5lusTK+cXPkVO+70D0FKebz9h3/OywXkNfYHfvVxvBmsg54q5Ew3EdQRpf6B7BmElorheRKWGywVI0S5s0ir0RyyzoT0KCL3iaDTqRxlfo0kZz8IvSggjxDH5fEaSuKxQADRb4NgMJ3KFNJ3h2Vw6m2dwlroZombU4BkEHx1fBB6e0dDMAKLxB1vvNYopNpM9gUX69ltC6Px4+FAP+iXP0C3Im5Ttlj+BPvhWatUYThU0V5eHK8MDodNzF1yI8hCgGUyKkMyv5ImlR+Sl2W++J0xeUCAOunfHR832yNj8zZ4eXqnAjAmaHHz1z0BPtsfiCHZysFtRIMrH2R9PzwrOkTDn0IMd4XpuB9PvSemT1tu/CmQYuk7VKcIqjT53vdmHuOzp4xbhBE/wKMRpGZeM1S65u0RyCrZJnAR+7h6+J8DPbcxWH7Wg+5skG+F/4oY8f/zpgNKhTI4oBO7iDO4ET0ECcn8EWkjlEfe0bsq8ouxsBBnYHd4ytcnUCvx68AMqFtqA/c8JZkK8vJCEiajpuoW7++dHA+3FxXsObvYI0OcPSZarPhZbD3fVRquS7Ya+El3EoQ98smZPC5RlKHaanXvsRZ71mgYtVTrVz5WubXfhAVrblAFtkAowjJQJdJ2HdsiUY64UZEU2d4Ro04KhOTbxCNJhQu3/KMBV003bY4YizlBcJ4o4R51BX3QCaTrUCvCmHv944/cG5vfzEnfMC/0r3t5WimxOcPTccato/OEBW1GxJOBrG+d32HALyWimo9uba+Fk076SRzEe7EBDWaXKzUqXwj4JBMyH3+qiq+PmrqjmlPpOqn3HGdkAqlWX1HfYne8YOZuk25BnJ9xbBfaKvmKv6Gs2FE3zfbewd2iSexl6sDrVx9GW0JJ2CQNgVgq/c0loiJQeNE8cJWSAbd4ZSYNQjEZwwA94zX7qCKEVFn52ou7i0LZTywUvDN9acVZQ4uXynyv7CiNqodzkHzcasoo+8r0EBWnu3QRFdHuxBIVd/dPgffCe0FXwaemOHqPPNXR0DX2uncDY4MiiaJPXoHsHTxmFt1Rx7ma09IAqUTUAJIEXF5RgmSZGiREVWTyZFGRbxAgqy/UcKP6035DTYCNDZg5CPnUsQBYT/8A+2sBepqWriHHOuc7h1lC+mmtL8KgQidJxYwc8Ect/YoskmtjJEeq25tQ931ESiiw52eeQN8zVkL6Xa6kiai9VRu2lmpXv1Bzwkn15nMsuG+B3YgA8ESWVzwvTtJCV8lkmy3BZbprN0IVpjmUKdKEAMrkr/AUIxcP3LVH2zoPvwQVjf1MPFX/zdwmSlGZEQeQkIBYKdCGTBukCk01PBUFgCpxYSKeZtMgXpjSfBRxLp7ksPy1IaTYrMBLLZ0JNrJfHLcx9tEaSGZYla7ncpfDqSvErORjwv1KsmaxeE4wV43rGm2DD765nOr+avypRZGenbdKks38TUzTpTZQFmuy+hIbnvxcBHZClY3xYEENsqeluQpGmUkCW3AzXS0oHUyIU3fmTNNGC+RzxEDvSKTqXYuk+m/7GZL+l2aiYVi2SJ89myMMo9Dh5i9JlYzFRYNIKTN70fejxLp3LpOe+MN5AwvIUKv/mUVS0jafT+K8lkGQL3qogpAjyKcuQB1KJ6r4hajqI5iLswccfzEWIg9JRR+INIapAoQrJxjDEb/MW3kLytiMmbJPXZ8CcSGA7MWPJiagcOFlymKKrjyT2EbWNzyJ4M48Mnzw/1e093nUY/k8GxYPcFTPXgxhqInne59aSV1MwfxlF8vmI3vFLKc9Ljy9mErmOpvSgvxFhIgevcMGIT2wdG8/rgE7i8NWX/mE4VMWdvPEjiQnR/MzoWnIko/xEsgJTyNEpmknRTMJkhZDw7ZPrISpmAvm5cdwERCac28u5f9fzxSsQ5dBFr4BWFmoK0xcoaEP1BE4jMxgvYF0SogMovO5raw10hymb+g0hUwKJ0jXNNC4xO4ub0H9JAVP83VFDbTgRVArHUQBv2x8c+/EjGCJ+uLHsrHXb2EzGE64F6vkCjto3ePt7vnBZV7zuLvShCBbZFxKPh18k+clwcmBLJzI/Nc0NXg9uFu9XhOyLkPD10KXTIqH6tg8a9gxrg1T3kBLic21+rs3DtRmHKujEcoXTNDFMTQ8jA7HZMlApCpc6RZrxPqly3n5NkLrnZ9Zw+MsQCMjx78L1w6INiRoZaCzWQYLtl5C3SRO1EKXcl+uGMOuwM8iuQTDcTx3YBCLGb29K0MHYeDSu+ol2Y0wkmhj9SBrveppKFeJoeGaP/Ilw/7D0ceJWLy4viPng4tKB64M3KTcH/SIIl+wLc4VXG14XNFVQeEQoP5V1sOEVeLX3IIVfXmA31+RFk1UUJEPu/Z59EfojjP6ATiFTXsu6hWJxEbODx34WFYx7GMbrRO8GI37fHrcbylQWJ7/TqWhbs7xSkcgpg+KDnH8/J6czONZJzS1h1ygkMk8ZVSQ+LYF8ppDKT7MgxeUAn+JZIZMSWC6dzmfyXI6JMqq8N4mqi+XrkOMlQvc9zTDpv80OMHMJtn1SzcrhbdZS3ydz227nr8rdJtebI/cjT+L2+XehsxO3cdT/+4YcD1Cb8QzCuipd4T5cydpxs24kXCJ53/k2XYxDFWb4jmFRfvPbj1iUbRkNAWAjrDX260m5k1LHebldAS7jU5ZrPEDevhwxapMeRRm1bYi3E+5dmBKYbHPiKg64U/yKboGULzXlqO0KqDr0Vkv2/oWf9cWIkUx4o81VqrhaKcAAQArD47LzYgJyDm6nwanp/aiMmTWHI33Pimd8u+Bdc26UAPERI+Erq03cGBNw6X/QKxMESfqd9IeKCz5okZpyEKBI3nF51EV+eN8J63LIeUkekSsJQUTWAfQ5YxclkJ0Qgi/4vV+gh+OL/eovGFEbRQLy1JpDoj6EwvIECTQp5SGl9HQ6kEYeRu3slg8ZimP0PV71MxalN4aSi3oJOT1P74g3WHdt27K/19Rv4Gp2dUltbHqfJS9qxglEM5fQIRYY5bGBNFZAhJeYYLeQgQNirp10zWWvsldsmovHXO7etEJGMmQNEBxNYrYJMW0MCY6mY9hBu82Fkz9NAhdQi2AgR5i2Z9tQ1oEXIi3VVQJlgyJNoLAQ1JsrCqmKwY8hcPaX0EKnAOgthfTXQDX1HYUwPfGwHdN7gzTicZw5HutLrKPmT5+Qtm+25G8H4TuCkKPvYdo4HDmI8W6gUFASZOeGV5BB/I6uBkfVafLpiQ/Q0LUa3E8+nYosDfdzDxes78r+vjr5yG6agpkwRDV3CbLIwAVKSUtZpSq8MRc0Xo8ZIMUbDJu+4jdLaYkiOYoPTRRFY5nz2L2zzLmmy3t8kYP9lMDKpqBQMScBvImdktp2l1T+ygJL2IMrZ4RhJiNClsQWr2sEh+HJa4xSt/09Fe0L7HuOZOB6gBXRGBeR0K6RMKSP69458TDOYvAO95Ebhb+3UReLiN1zzP0S1nACx8vnjvvH7rhka/eUKE8cwbVcKTKviiAyabXsFKF6qMipbFVc3PRlq7q/qZrq/dNSF6q2iUSB/TtFmB0NoLkMGcpIuXIktgZSQKaQNylFUI3Jo5StKsaKKIHdnkw1HcVNhARAARNrg/AxpchL2byEq9sAoqZKiLyTNykeBwnDaxv0JQat5lBxFHYw3BRdc8IiksL1OhPoMPsYLIE+gwCGE4gmD3/AuM1hS1A1dU3xwzja7VBOO95w5SngMZyJYcNBn4v+G93fqazOgB4BJUFc4tAj7ilH/ZblqDnY8hIQ5SWvQOYnnRch5ujvtoes0e8/2NRHPo+3fUeI7pGl49QmW2JdHvEMw5AnBAuGPOHQmY5d8vjFXwzKAc2iPEnJqL48U2HwGoROtU89mwTKqe3ruGcAJA0YKLEKbHkRUqZgzDK3Oyf8B4IoQV90JpvLF+jkfyVelIjTYM1HHG72U3g3crnCfHwxwBTnhLY9dKXi91ySHEfEDWZQPCXZGI2ED57cv58vMksMf8Yu0zTBTGPmzxcudieVpu2NfHwsM6F5akdHI/KUx4sWnuco1Y6MhYY//9THk/sVXJa4HZh7MOfXSOYgEg1NDzJQOOEjMbMpSDYnc41fGfHlxH07Qbnh0QKpih5QpDTJJMeIfESR6ZcfzhU4dh8safX2fgwqZ/cDhtL4nMfEtYp9Uqf65C0MJZsbdu+ghsIXRIRyJOqoZYDJ3py4ZCaRnbJgqjxVrreLfR9Jy3lvPrSnnz69U//2LP0YCs4vk7OvGCnP8jVSvCqloEiCrhljwktrqA1Kvj204sWFazrHyA3vthSO9+estRG/yb8kT/CN/Q/OTKLEwSRL4HhclC9EkhdPMOzZjXpjKOyfoqJrTnRzJTtyKfUBqbH/vnX5yfPwD+F5sN+6sldlSG6J83U4hQcVtW1F8AoFowxRv6Ab5fgwImaJd5ZB/s29XH5u7I/VEc6bk9SUlxVLT6QMuC4y29Wdo+m0x7l90dYoXbM8toNBt4mQ0pey6oC3nFDfzptkt29/vlv70foomSuolv5cGHgS/Hk0xuLdFErvqolWHd8w2GGyIka/DEMTZXwt/EiEjX+PtPlUIz7ViDerEXFwY94iK9xdf084Od77lDx4w+nkSbyQ3/hpditw2ztesbe0hxpJMTSJwTxeWuDjWIdsutqwgCkn4vsW7CDaGNXr3SGRRCqdF/bN2SmwmW+sHfbtp1WOsCa7lsI3jKHdyo/LCxv97Q2tYeSxWAG8xxta4BH220md/Gh0FmkS/HfCmUKoFHbVnztfdiTyG0YFNYFl+VJG7DQhQs9lp/EUcw4n74A4IYnkoEFuSXJ62Yk+sj/1JAohK27I2f9nGMo3OFoXl/jfQJJRpMgBkbiNPfuG4UJNvLOwYS8clvh3WuI2Rlgk0S/ZmWRInM9xJYB/QVx6ZZh/n8Q4HASdV6UJygwN0Ug8BjUScWKiYMUlr1oQYBoyF8pgYy8eTfdDF0cr+mdY1wRLlRQYJm3OtZPiJgSimsnyIp/JCRJgC9k0SzNiDmRBvpDh0lmREZkYGrrIH45R06E+9HrVvaZIGCNKlYvQ+aYAfvoerpoY9tjQQA/vhLrilTL52Ym4Xy6TF0GGT9FiOpPixNw0lWfFXCoPClw+J6Wn0ywdM0khRs+RcT88p8L7AQ8QFe50ggWfy03zgpRLpQUul+KyApfis1MmlcuI00KeoQsFLh+VeRXb7B2ui+41FXzBste7IDR/PAL00pq2ExxC9PAm+O1UTHgK/k+pWm+2qXK122/WmuViv4p+fVZbzWbF7JfLxRU7K26apeKseVNsNYqb6eM4c/0wahXpern3Wu81hXSlUy2VN4NiqzrYlvfFm9KsPXxWS8WnfnFRG7a6rU2181QZdjrN6mbVF1hGuRu26afHrtLqVTeNDXp2W93ObwS1q4jLjCKVS4/PKj/qqvxjd9+slWjQK7WkemfTmIvtVv9pc19p0q3+E93aF7cj/Nu21W/unN9eSrVntdUxNmX87np1c1Ma9qv9VqlaLzKDarnUuh2wBXPcY/pSvUaP+9V5q5THz+atp94oQz+r48cba/zYmQ1ZZTFmFVrclTpSYzHrN7qLVrNZar4U26XZ4nW+kOuFDV0qdqq1YvG+XOzki/D5s1qe3ZaLnWpx02lowBSVwteMvKjvh1mxtR+Zo4ebxutjP71ZCdVFd1B42ueU2VqSlnXJFOvC7Jp5Vsv1sUW/3NQXLW210gYaJ6Yl00jLm9fu07IkLwYPudxm88R26svKeMPW1oub8o1yq/JCs2vV16Vn9Xazr/aaj7PbBUszWb7/kL2Wii/Vxk7L9oB2m1cWzV1vsL6lp7v7oWLIVaO8vF/JkqnePl7zXzPPKl1/KeUK5ZsGV+2yyt1wrM7BQ617vR/c7x62406HU/nGNLezroXMy/yenuanG/PralfbNh9fhGrzWZXGijzqLrotc6837m+ac315wxaZm5x8r8u6IMB4ls3LS3s4GD1M082bdIthe4VVFWw0jQf37LMq79v9alesFxr7Ii8Kw67KPrG9UXPXv2bynWal2CmWNK6utpr1RatEw5mUKrPOqFTqX98JVe5ZLeijKZvPt7PGTTFT6grZ2k2zXikxcMU2eq2q8FIyZqR0WNlntX5bu1lVxU23X71rFRdotZTmrXJnONhW98UubKlUnPXLSnstjAbmIN2dS/XBttkvTu19ofXrVcWS6sOdsBzSzZq0GtelldRozQaNbqZZ3dLjZnC3bdDXVDcduKqLrVJxmt9UOk83t9q4OV+L7WKnelfqFCuzWbVUbDRqG4U2G/SrNXgaP93T0vjJ5Lq53g29Ki/ZZ5U1eFPe7RsKd68+io3KCiyKWu6apwti9m6fLQ7yafF2d/11m76WXp4ajyOBzzVWVYuWumlr1nl4VluKzu31uVTY3o7p2/Gt/LQ0bxpf+QV33+Lu0jWhT2ubwfhh93LXU+Yt82Yoat1VpnxjvBRbpUH9We2tK/nu49c+zWz22va6I3xVVLWt3iv8aPVq5YF2D9SdsL1dMXxhcLdvDtft67uiKH5luLWs1V7hV2y6I3OpiaWike90CypnrYWV/LTu5cGTBSrlUavFTde1aWnOV8bpdqEpmLvePN1b1aROZb55Vp+Elxarbx/l3V19W+JKmpLr9NfcviFPc2MzX6h1Qf+6Xdpx+p43FpWbp8xddrt8+uNZRWKy2q6EiM44WoD7KMUmFfzBn6Dw/2jBz2TU3FTazrtmUPCXOqGCXxn2P0LwdzatfXXb6i92rf4gMyK/tSvVjfNbmOAfDvZ/neBfv6aNW6OxApJ105CX97dfp+uOdGs08/t8kc60xrvd3Yq97l7Xq/naS3v9db4YPjGjzrN619z12+1OI1e+AWKVUYX+VMs/ZbK93PZan2/L2evKTb7VtBR+VXtQNf2Vy94OsrvuVm7RrU66/ayq/ZuG0iiy2n5s8tmnUmk6nM4bI4Wp0c1pW3gs392u65vRqCWUt1z6fjrK3vYXQletZme10a11/6xOe/eZOWtl+vxoaPWa+9L6ycgN93x2+XVmPhXXt8WbIav2xl9Br1p7qGhsQdT0+13+69yq3g/u8s9qplbccKXag6EzfUVX6g812ZSszqBR13t3OWOxYKq9+p6nTS0t3Ju6Jt0CmTUKwiLTelzmlPGz+tr8OhrfPHJjq/B1uR/PxcKqPJTz+vWr8mgdFfzdNb+efn1WjVGLa25u5UbhsbBh1kpWHQy7B4Iflw4r+6x2IwT/cNh6d8Hv3W0xBH/NEfylJ3a8L/EjWmoZxWI/Zz7c7PXhaLjvbLO3A+5ZHVRLd5bUVEYPyqK46avNdnnUvc6D9ku5vKwXuTkYSI0lv5dWD3y+u9/cL0W63Wfandd9b7cwzWd13X8VOLlRyX3NTwut15vCdc0wytO++apfdwzzel5vcKOlNGWqN9fZ2utTsShk5K7yMDPmtfF2kH9WrUezmJ+P1Oz0NguavUqhUZLEYq2vDda37TFTalYe1vPCtJBpqiDP69ldXcpk+4O23ujmQaNkPKvV3nafkaRh91obdXdG++YrXy/unl4bvXzv2jSX5ZzOPZaLjdfHlbloPJTr3ddFcW6YQH+aS1wz/6xei6U9eBloQrv88tKoCeaieHfde9mO7+9GX1ftxXgzBU9SKy8/LCoZbmDxzJo1pc0xwZ9Q7KfDxT6KxCsX/bc/lXqotkhY6hUFbR5h5QwKhvTBBMKVCaT/33cmoEMieHXEFWAEMIHXPoX+c/LgkF7K5aKSdQ+OB7U1o2vG1+sSHXpjqBnbq6ur9zxOufBxvdflGeQw8Y3YFTUiOGQq2CiyClJAhd7bNw5DeV0pl4t8p1zsFDfS/lBeVPrFOyIvWqXakH4azbaVPTxPsJwQW6XFdiUsu2vhpTpqlTr4bJpt2t26ovKDtiKqnVlvlHm5e6l2W0Vydm02Tfj82S6xbfSLAn5Pq1WrD7mnEbMR6gNrDFsZoTLWE1swg+fZsxp2otnnWf5rX8tJX9nFwwiU1teaPkjfDYWbTUXvdQRwyy/LS+1Z3awywmtl29wMWXr/2hVyxYfB/e2TNqzWavfVjpHtZ2fNpdrUlLkgN7JLbj8bX5cf1qPS/WIsfhWfVeZBY6vLdWn/tVjJGCWpn1ns651iti2MduO6Im275rx9d28wYHo/l9RRzZo3mSz7uhSnymwlN5/VUcXavHLlwvTr0wLczNtqQaplvmqbZV687ywr+jDfbkty/1VW86/p16dio3HTHbH5mXIzKI8X/fGzumnyvW5W1EudfF94aldpSfxa5vl05b652DPVe6Mx2ve3X1V6fzt9FYXZo8xVbrZfy4zwsjKfHrrPaulhfJevFMHIKuaBYEnDPsftqqs8Wy9kr+szcZqrpdPb1hbQO/HrI5/VNuQ8KxaRnH9WwyU9vRD1mij2lrXKcqtt6TagmUHztWdUXhuzu6+Py0b/8Wajg2zlWZ3f9MYbYV0172/pevqrpHM1g2FG1qBtZl7FO2Ob4fPWgqtni7eN1t6a3xk3ucfxy2zZeaxXy6unZ7XDLcvpXT891sr1VfNR2HyVH9LKslp9nPGdO7q/zdzVlGttcSvcPm2ar215dzu6b73kxt3rzXY0u35Wx5V618hktpYG7io31+NubVoQml+bfHkgMU/69ElsNJV0PZ8rrr/qXOFpuHntVvr0sDLMWXezV/VZZQuPTeZhNRy0yw+dulpYXYPHbEfLrVcV/mEndM0i28093t2+dPhaQXscgfLgdcfM1ze8WOjU4AWykLsXGF5ZNR60cW45kqvWzeal9CDLWb7QKtTTtDrQ0gWlJDPHJX2I7TmBhMocVfiP2Pc+bTifNpxPG86nDefThvPxNpwIjjAoulWohyvyHkyI1mijWiQ7BiLAe+3Cn2fA5xnweQZ8ngGfZ8A/+AzIhZ8BBCPV56mutt54CiyhUUIrX11dSfNKpfph95sJr/LKbv8BLMj/vqjjw6F758BO37zZ4TkRizI0kgfBU2AoAsOwEuL3zzRt5kP0luSZDGtD+G77mQJMw4bthqFMBowYXp6ZXxf6vWEuuPCvNQCMpAeSEweHw5UoCtIIwQhxaKFFadYqik/2uencVmwEPYdzCMbQwfFBUfoG9X8NQGAhUEj1NMBR9OdvDqUa5HmCO8kIkqkZhnKNqIsgy8C1V+bY/ZDBKT9hYOTtSfqZMxNhJT+yFnHYeIDuwnAIJ9AqhcEyumbN5gmX58/88hA7dvhX2xQa7v47PD5Ow1rhSKkjCBXZvJAVclwqJ9BiistlMql8nqNTHEgLeZHleAkIJ7igohsvu4gENjlKuYiWPUlMj2Z+SphVHIKMGkz5RQkGEJKRkmFegzNKMTBOo4TpO+VFewUWRGTy1Ar5MBh2G0hpJkkMSK74cpvfMxvhIMfeG+P2A2F/2bONQ0fhanjjK0NahBiT4noiAQXM7IQoUdOlkKGqlIdUxSlHkXJo/RESc0JP48dCe89Bc19AuomT7AJKGCz/1jehNvACenPI/cFU++PtV7q85PVdMMjxLeHZuMX3jtDOIB8jAQZ4Q3OwCTy0nvl0ldvAqgsuLQqXxMcYwtwRAEDLEchrl6gpXKf4rVz8/dja9EuqI0DRBysed+v4Sdmrdoe1YvOOUjRtAUO5rRVVLhIRvlpdkZJQM4kCdDtUcz1jGC9iO/4eI+35XxIpHzwHqfHFOzKkxs+TCXaHZXM3kfjdu7zBaSs0nQB9ly15AmeOswkTXjQOToXDZahSsirJa1mCuEDeFU+SGvljSB0Rx/NB9H+0doWLUrjo8aVvCfKrJZsaSq8IT2VZQaqb40lHPow2CNsFf3R3N2njrOwjlotJmDgD2sR7DTnsbg9dXHYkZRVCg8KMBR1gsNCVLq9h/xdgZwPMz4EiUYoGr8S70xOk8AJOkTky2oZHHcd/WISMFiAaXtFCSlc4Y433CPV/WcNeqJQIkRVtaSsbcQnOAtD1vgwmv/T7j08aRlwZ4mdeHF+dOZAT8hIQ+HwmneenWTYDGfByAptJ03SaEyOWArpLhNDh9SPPH3RoOZerBDaAO2B+Maiqc5cK6068xD2fmPi4xL2DDoZlounyEUsKMhpc22WgTu4CFvplnUuSGBfTE2HqmVYY1bGXeg1RQ6Kbo5PRF3fCquVKrziSzTnG1IzqRxSGref7jBggtryIwKUj4OZWisZLSdeFXQtemt2b5wcukB+XF3uECPxWDcarXocd1vYp/YZj2fOK0AWEsfy9mV9Ix6OCDR2f1XSeZafTAp0CPFtIcZw0TRVAJpNimTRNC0KBYwpCzBzZpB/4amkm/2mb/gjb9AFUuo2F9rYvRTN28e5oTAcr4xMw5RMw5RMw5d8AmHJgFv55suUTZ/SfjTPqbf/zQPk8UD4PlH/FgYJYUr0lPvRICREsOIbhU7R8ipZP0fLPEi1ej8vPFirpT6HyKVQ+hco/TqhAczQKBIR9gwWklIYSpFMrS1F+upjhPsXMp5j5FDP/ODHjeYRhg2Fw1E+WLZlP2fIpW/4msiXzF8gW5qRg8YgS94WxR+wvECLpnyNEZBhXoOw+5ccHuojfHoKMLG+RoN8/ZaF8+nT+Yp9OmPX1Z037p+H1b+HMOwxf/sAp/zSL/WVTftJy8dMWwafR4u+w7z33yp82859XyvdVCd/9cvCzVsJkRfhvPhfD33IxPCBuoY9cDmvt/7H35rupK9v66KtYudpac+4EsE1jmNKWfnQhkEBo0x2WMgu7DA6mTNzQ5GhJ5yHuP1e69+XOk1xVY2MbA05CZrNW9pbWDHa5alQ3atRovjENAl0EZ/6HXYPoGfgogz3pjyi1yiN4L/v1VUQvWKHYvVeN4c5AAabVoe9DgcwxYwbcQCENabaG4VpoSRa14v7ySpMgK+xHj+NY6Etbm2lo/Gg4ZM4gCS1+VOBcN9YziOz3R/zHTad2vBha3ysa+BoMUHtPYjCvokTmKPHFJGoCGPM9i3oTqfSeuApaSTh85j2BxV49Rw5Vzp9sx728o1ZfTa5u/g2y109avbmPWr3Zo6xe968fvIKhqQH9kalq35190VfX77A9Ch+3PdJv3B4xlAU0Kdh7dgWIAgQ5kmaFIhp8xD47DgrFzNb3ZX084v6iBKPjZGWklX3YdmXVf8SGPRZSRvrjNmvmbZu1Hes+97ldP7frP3e7KiRR6LsvkZuKEpkowMlfhC9YMdjBhwi35AYlW+9dZLiGD2IHaTcDNHlzJGHZOgqPiacOIe4nj0fYHoGqNlVDxUPYOU4D/grDaq3NANJlE0lFqNevU3dZu1LVeYAKEUmJjgNa60KXDy7718WH1pN8d/PQfcoYHZvvXVi6IAuL5haM8hCVOsXlICJf1/lTceDm36nctCYjrVSTZ+fOvai/3It5DwCa5uIpT1uTUU2fjdINB9xWV+f9Yp9+bTQrVS+rDsvHUxyfL/l186m6aj7VV0PUehpkWxUF1Ir5NQU2L66v+1Wx1Z/yLcE4SN8Q7aMwDn1DFKSwXC726uHRKjHQ6XYRj3jHKBMA6mZXvu4ux0PUOO8rci0l1i7rp/L5vXZdalUun8oPg7vq9eLu9j4jlqYXheVKa/bzuUL5+hSiorDMzuvmnbHMTctD1BSsjjW/uAA3s8ZAN+xqs7FaG1fnajGVv7SF6uX52hhdPzkPlthbrm/WDdHq2YuOM+hUDWtw9TBE5VbtofpsXGTHuZdJs70Cq5n0cGWaVuWhMAOt2s2zIVVvr24vzIes1Ellm3bfHK06V6fw7mkwaxSG6DI97Z2mneqyqTx3cw/pku4MBG0B0LwtC+WWWGtNlGs+NendZ+6ntSpyrqznxrqipOW6VhKaqyFyyqVG5gE8XyviQrsRbuV22hikldVNe5Zp3q7V+7quNG9LQuYcTHry6mpyq3RRs3D/kNIK9XP5aojW8zvLeZEqT2ajbbcH5eKyWiyC1qyJQfExxH2Xvy6V7qvn7Wzj5WoAlq3zUzldvLPu+9Xbi4k0RC+i/MIA7pX6snPfLIHirtKkbDFDIdSX1VJq2akOEd5Npadij8CldwkIebVcKdaKnYtUcVwtRSUFKGbqpWKnJJ+WoDRErcpkXuULa2ly1X6oddu6IPcuS8tMt87f1Rc5Ux/1+udWtgpH837tabJKLSet1bL6MCkVLh4kQRgi4RoI93o/v5rWCxVrUpLys6fiRfmyVGxIuZlxmbenNR48K/fzRuZBbvRvSiVJL+S7i7Esvah9bYg06RbO+mtJVGBp1INa1b4Di1mmes7Pbp8uJp1sazVHc54vPaPsWFjly+t+ZT0fz5wxgvPTVW2ITrXzl9asr1gv0m290E9J00rz7rkkNVPn7dvSdXfdK+SvG8+tirUsX53nR/WH++WgVIWno+7FuYGzXPUmzRdQTtsLbSbdlkdCDhmVaa/f1NXL68wcLS4nc/lG6Y2XsukU+zfS+vT29GoxexGv+6mao2WGqDF5hkYfLq0VOojLHYNdE+jXMLjaz5BfpNAV54MRUam4ZMxmBno8gsTvr4lU7CDbfDflrJZjCXYfctMjAvdfZyeqhsbQnJsash+tCcBIT++rPqLCo2CQbq34qAvlEa4Rm3r+OjvBmHZuPP876vSq+evsxDDHAGkvx6g2UFWoaqA/Okh77+0tqsYPvR6nP+R6zKqdau+tcKq5mux300bqOLJaXBBOPhI6NK7paO9W3bYAb2fB6IPx3vsEr+QLssQrCaAU1EQmn0knRoWCmsjJMi9mRT4nwQK294PVFURje3LyLZ07O5lpyP/zGKhj2z39BAP5jEz5dSNTPqPejhiwsi2DHz0MYQ9/+YxG+MnOqVHTf+TZj0ygED1ChkkyfNsGBxTFh3fKldinW7ls+hj2mGDP4i8AZzkjBgpvqJyFNF+qGcvSMYoxByyaeITcmrgWTl+oqXg34nbx6O6fDBXo1hsP2uCNL8R+feRg7nEoNcrezCRHgiM1kKqNP4jxeA4npIzyqKG5Q/0fY15MI0aQvDjDaVAWmrJJQlDudfcP3KB3pAEzoc/eFD4cNIvT6NLD4LzkD/dTwg3Y12/DTecTvJjgc30h/00QvonpZDYtFArZXRC/sTsSrUaP6IoKdH2EM9JQc8a7eyQUEgKfEPObHqWljCC8v0M7sjSRjix3wTC/oycCz0fgLh91tUXlX4qcJFu3MKOzMSfF3aJzhQHv3R4yBqtZ3tp823pMJ3gpIfB93GHhW5ZPikJBkN48fdYOhGf/faunjRHuWJcKxNyXcq/7Nck1HcvGwOQs92ECItlQoqfykK2H61Y7g2qvv7H5lFcv5XIR5MvFTnHZq+y1jvTDtpEhwtYRN3ltqSj3i9NWqdntLKtjkj62Ul3aOqyd23JtpV/hFLWVoD1kiPZaRK5W8Ml2MqPTp7ZyDs+13PXAWsN8/77RKc3St2p5cTVEF062utCemtepzIPYr8+Wxd5oOTiX6mb++mp8cTqr6Z0H+LxuLWpG77pZBQ83d/K9Ou8KE/0GTPNDlKnVbsxTPlOvqdflZ1AypqB0Xl++yHrtYfRyObuqLesdzWitaurz+SzXrd3XiukRFBtQ1CxYkoeola/dCMv72eK+yne7p+vbJWyU+w0hK8HVuvviSNbNClRvC+d56aXUuVpfo+WdnMuYqn5n6d1nbYjG0rm0zNZB5/5az68Xs2nqqdouFydAUqfaQK3OnzItQTw12l2tudBh47yQlyerp0qmeZEuyNn6EDnXlj64mpi3DlInUq0kPC1vW8XCOpO54C1kqqerhbEW+/LFbLWYgUJVR3lmDynmmpVxbYh8VohG5alqNsvTZWNJrCTdUrm4vDDqVw93k8normQ99LLOw12vXEkraWWdJbM8RJt5Dif4tViC32pRLoG7nHKN6nkkF7tmvfDQOxeLjbvT/Gw1RPP+xb14ei+W+ZuFeVOpNe1RqXuR7xbWzdHzra2vIGzV1FTqCjanvcveOchMR3NlJYo5XXW0fGqIgNOtlPqN2krsCrI8WM2uHu5Wmdmav81q9ebKQc7pFL6cliq6I436fVEzeOeu2b1wYEbLPTsXQ7SWs9potRg1mk9dSXkeyQDdVAU+lc4Yc/PlrmM1UjeznvPQurOfRnbvsqLP5Pky1zdSEBYbp40hmtytp/JAmywu1rVMUZiJ3dzzvNgqPaEiP7+AK3XZTPXG6stiPloMxnxfcEYzaOZL4/6yfFm/tYZIkW/v+/akmRUa9eduSW09rzMduYTuTmv3fHat29WqtezUs9mlovXS5ad+v5iTLGUkd/6zI9FqYPPHsW4QnfevybXuk8lkMk4338at7Ueg49do/AhnOAnk9jBU8XMss2O5HLI8Uix7FFfuc6QCfBmgbZBMk67sjz3tk1yRm4GVNnNmWFwWeN5X2Qys8dhR+dUxoZLkqkCeuCW4GRtcQPMjcd3zMpdNiyIH/VRxACm0KL6TyAbC2XVx9gBjNgNJknJ3l1zsnY+kwq05C2ZccfPA/J9g6hWgzDQUePYnUQbWaSMC1Ue8YiYQnsOIVC3u5csddbwaNYtj5YOjHuOa+s4FYzkjH3H7MnL0TYCsOcBJQ9cbyv3fu7KOxfI+hLqwS9fgLdn3XKy39wCe9c0cHKtuVmP41u4+j3ND3zH6n1qaXzZ2cNd+ObbuZtfKoP6Q22PoHmIjQ1mTPUcK4m3pZy6RW/RvvC+BomjU9tj2dYjpkd66abdhRA5uz62ccu/oa7Au7CTAsG0s8/2pg4J1fYxH6MmOJHLvqHyrumNmQT2O/8F+AKKjx3dN4VqHFjGPL95dLasssOa3862955jw1RSVJ83QNXl9zAUTVWMoIdt7aner+Q1i4T4suObkh+Uzc1uJz7zdB4c5t7/kEXTux+Qlnh4/yEgsS3/vwrAoQg7Q9Wv15Nt/HYHYTf//3JGQjryNP4O26Vh2wrIN86e5LqZ/7QAqtkrIQD2SgfqHx8RLHxWYJP6wwKRo/scGyZtR/1wEnGtPAus1SGNgaGLvQ7IhHgFSsIwQYyNuSUHbN5m6ijU9pOAmZMRvFdKscKrTt4SMKDjAQc+5ISONYhs1x/y5dZoq8VGO7c1za7VTdcfq9UnjbDi2NZA47THLhbm7j7H71u7Wb7Dq8LJ6v+lbddGpl4pbiuzqebHYK5cu5eV43HsqjqvFooGd9cupXrmUDfZtu16ikLQgsjSCg+IlZPevxojpDQzIK5cVvelsD2MRK/0I1AsdQf/iwJpDPMRzoJkW90XAjg0i+wV03VhC5esHJWKP2hF/+RWHIvEhdLWIrxqLWI6Q26Phy79qg/H+VSVmsnkZZkGCl9PZREaW1ERelKVEHhYyeUlJq2qO33aKfIvO0btjRkytO6eHFfUHtRZ7nT5Iimrq+EHcAL5Q35WvntL1oOtCUGfsG5ZcJnpYdrpP9JdGQoe2DU2u3rvm0kIulxA4oM8nICFy7DMOWyFiOFNEtrzHO8LLf1zudd/vDEESHQvZvsB/S7/G4L7TzNyuNl0LzL41cSzrDLYpDyxiU754SiaTMck/rt7FL6RN4doLPY0+TIA+xpfNyYwm6rYNbgwRNPEgxVrHpgVEPpP34WBtnszFbG4h7IKvwmEJemT68jJOWG6YnFuC2+XOsCGjBxB3bgIka5Zs7FjH4diHYKPXvrcxGtz4bJ1xdSQnY7TpC4rY3TTQcfZr289IsN4Vs6gDGdPRWEMQsueR2dIBilCf92jlXFG3oYkAPp6JMxt2fpV1B+8cDUWsha2zb5+pLMjtlstlMmQf25XdPWLl9vBjvDyIuxiSYZzZArqmGibSQOTYRInF3tYJMMBXyCDRZuRjHlFAJtz90QYRrplF+tJ/iAPLMmSNeAthh2rqLnRwh4tpyOelkSIURrKgZHgAC9lRThULkphLyzBuCvXP8/TzPP1B52mA7i1mO2ds1vc4/jLD04IL+5Yb9mJWZGAqO6b783T/Iad7NGO5cGYAJfCiIXEkhLnEnuzmmmO3onKv+3cQKg5T8ClF/HJSBPMXduFZYhjvyQeYHXtaouCgf9iN1/N+AzY3Myyby2U4eQJMIIfitF53gP+g03ovR70McFPbwAw12PcKVAEJW7MNjnFJHJ+CfdCsOZSJhTIut1VoXTE58Mey2w9ncj+Oo72BfQWmuGhzOgQ4oBJBrldsYWWyu+WTHN4iJNzSmhiOrricj8YlbLbOPu7nW/ZiNrff/fAgN/T5HGb5sPLwY9jilkqXbVu3Pd9CDa2q4AWBzdN7+GTU5euTUx6NU/4sGfuTSe9i0h8uAH8eBPEOgk/+/jH8XYvwgcfM1qfh8ibJW7U0QAFrUg5bfaWRkEtnBCkhKOIokZHzmQRI50FCVEcS4GVFkrLiGyMrIq/wu2xwmOzX2N5i0h2yvR0jknHTrU/kkU/kkU/kkX8E8sjGAH90xJG9/OQzCeYnR/nkKH9rjuJivH0wT/lMuv0bJd0Omb1+xPr4jJv8FXJtMxHjB832p3TxK8z3B+TYDYW7gLnmFy6xTuL3nfhw57yO/bQV8QMnTwWa7sQJ4NnM3i7hJSwEK/5aNWTDMRGLZhrCwBVELMKSmGLIDs7QCWhwtalHWrBZhyPfWYZjyjG6MDcwFWZEHVvnIaF+0+qf28YMB2nPDmTKQqbp2Sge//zBy3O3QMEWFnJ0/c+zE/xP0LL/YeuahXiz9smvV61sr1NvWOIx9IMe+txrlIS/DGpxqL/PjmGDwxsAR1/g6nbogL3Xrh3PGyNSv29oNrvZ85/TkJ3LhG490X2DKxlCZR8YCzH2slusg1cDNwEW535HXm9oDdP2OtTKCTCVRxnMo0fEBdnZXAZDI+NFtHAjqBomZK6G7l3e4gC5JuLZCCjO4wyguGsAsRL+0KV1i042nvoa32EdC76SmGwkLaHtvFlfjEjfZPuG+g0bmkxyIH33p6zxK0qfIY70wZLM38pe8msvjQ/TWG2AAP7a1rO+KxHbpqYftQz9KyEUUYsoa6XGdrccZ0LbMdEGrDd87hbb9fh+nrtOW79M+tae/e7KnN9icx0FHStyUx176c+gDRRARc7gUA3ItQj7zacWQHcg5xaNwNbFzn4WJCLSHJpeK9wX2go0v+4FyIpGloqzK2L3k2Wn3CD4BDvrQih6lGM/if/9n//H4kYQIgylSOMF1oZjcpVWj2DwYQh2gLjiGVcsFotn2I+k3Co2qxgA0jAPeFdQgsSAF8t7bhBuB5G23btisF8UaH4EOQuL5W6vGMdiuNd0oHAPe606mfH+VY+bAKRYEzAlM65ZnAyQH4AygFrvgi3iYYmsm9DDLGZ0gLg/vrm5MjHBjxMIFGh++4NbTjR5QsmWAfZic1HHOVrEteawr3GfRpAGedAeJLkWBb8kSJqe4YljTmupMOw3JXH/DGJY/mPN3g5gkb3AkR8fj368+62/f38rWe+nnzqfluxPS/avbckOwEt9kL0ykr982rV/H7v2LmStH7lefver0S+xXI7NLj5g9uMDFgZj09/TtU1FEfBmEXex9+8or7ZNA1uXoPe3Eqxyuyn03jSf2/X9dfYbAkkaSwRNa6LNHxfQpDUcIedsdKU7m3uc2Pb8Q9qkNR8PMPO4YIUEXDJA7lFYeFSNcXKyKvLiUYE6HNMvf39byC9x8BxR9eY4mnJN6znyAYSnHedQVxYAyVAJwNHNgTz9FEZ+K9k1PHsfKbkqcK4bO3AwIVpopoFmTJ9Hi25lgLONM1fhRSI+56ahOET/ckDRZeOb+jgQ47n51hfmuSnoe70DiOIQgu+hNC9ujs0J5C4pojrX613hyEMD4ZeGqsZyJTiCjovRGhViXdEsMNKxanOAtAU0LaATMk04MxbY5wCtffZ8IJMIy2BRf8NEL0O0tUSzqprGjN79lTFF65ybcIFXMKlYdTBq7d7qcAUjiOkjmUhx3H6dqG5Nqs1HOIUp5VXBLzdK3cBjD3/VVSBRffAZt9AszTZMy9M9O2TQSI5Usi18pTkDq4cv+v12LzlEQ1Rac0r0OJ7hweAcpEDTsnH/iXqb5HE0sDcHSdmxSb/q5dFhQ6VCnHUHMqKY5kRDG2Lp0GxIJS/oBDBSHUSWHiZjAhZwMwAgClAVR5o6pjwBRDONIseWdPnf3EWv38P/FvUlWFvcwIJ0RPCz6/ncMG0HaZatyVwVyeaaLDjyDuFw467h4J6SCtCaa2MFWNfRiaFS0UysdUVjzjaBqmoy7hmre4h62kzTgamvz8gaws+9b7yCHBtlN0nmRNMZhNJmsOemsVr7MzCFBtmx4P4RtjTbp1RjJoYAPK3ta+8Pi+wCMnp1lUyIYhAWQebF+961RESOfWSVZLXgHjnIwvtJU8nIMBMHGBkLGL3ITOj2ndiG2HeBEcW+UFj5CVif6YCecUuI6dMsiAOrF9v8w5/VyrccPyixlcvgInKO1tVNH6liFNuJyFQTjsKBje2JQQrIpIh/1AmEM1qTJaNBZadFDS8bj/t9cF8jcpHWkcLY3JIdQpiOhA4XUOeAY0/w4U9d2djGmDu6bvn2wAfTnI1Ds/vZq+jmihx2OOWoJXhhaApl2C6GYlCG2Nm3oNPqe/r6eWv6ERLycRJKbbbU0YVidzUsTS0K3+HYwqIC5yZkfrdvX8HeetwS5JkPBS3BbPWQHCPEFoUFNPewNdfkBDeo0EjOrnDy6uM5HJ1glwfKgy0mFxITkzPnZMPEB5m+TnLXzHZO8Z6IX4DH0VOYoacoM1eQxSqLNcUkyYKb+iEkXlPoRiaNbCea51iGhgPGcT6dxnnHRb4vpr8J+ePltg4mNNmBbRo4CV2JHrNlkvZoXxcOZx/PfUzO7kB+lXg9e0c3BFEkSdQLfSH3LVv4lpGO340I0SayG0Syod8dWlRChg4+5w4+d8rzPM8N+uWjkx8hrfyA9fVhOeF9PYuQabDGQyGTceyF9lH9cRmza8b4FF5+tq3RnRE6IcdW84Zq/xl2xuhESkdZTq6p4+xk07/3WJTYFBzX5pP5oARV26Maw+KjamgMzbmpIfvRmgAxm9vpb+vz6mMahm2x5sDJk83JYiZX4MVMOp0tqKO8rArpAhDE7Ejhs3CkCkohlx9JAszIQE2neUnIw4KalfMgX4DgOCwvKilpCHyNqAPWzM9sjNVWS6J4JFf8uUmlWozbzdxMJ1BXKCagTvEqjbmtzZjKYQ5Nwt6RDJNMSSUbCFH/QqLuxhoGuGLwy8SRWYZYpqZnumUzxaTq4OohVaphtcbIYR6zGpKxWsqYQU4HNsnXTYXx0J3CBRfHywybe6i3qus66yYbgByCAI+QF3jmoynJUdBIFpWG9Z+2qY0cgiVoGxz2a8L/DpK9pP8768x7VU0Otl6Z3tuJNp7gtt2s7YGSHjBksF2NDqOu+9Vd+DuvAf+k+CfkIISoDkYwIlzYv6xJUjbX0kB/ODgWjXbk0e1ItL0hxh7Ff0XLGlPf9KId+ICeaOH5FMTCKBWz6TftLr8DRATeaij4ZOP0TQKnPZdvr8BCA1TRtp+zgPk8uacr2aMwDk8/FXGz6DO3b+o6jvw6aLz0qJs4EQgpz/TLhZ5m3rNAHERAPNzf9/Qv4soR6F+wR7ZuBVXLQQ/PWNS/h9qAnjBBBz2B9YQxpBucxO3dxlbPsQYY8z2pn31vjmfdTeSOl159o6w9viPTkbKdxhxqdkS76Rnfl+PZrQk76xwrXa7XD1JGeWTr868YEnycIfj9ozMCvfyMy/iMy/iMy/gnxGXEONSPbagJcBrq2/apBfvpWrBdB+RHzT22FruN/CCx0a1lK9PccbRs6Ugt228iKB5T31b4qITwESMc8zbvW3Ofss2vJtu45/QGOIM4xRnMw+d1B/XfQcDJ/gQBRzgo3fjkmU2DsUfsh0kywaPl44SXjbvT4eXvfX+kPlqUac9s3QrdSKOl0sGgXqGudUEvcC8DiKsQsw3CJWZYje6/wjYBAmNInMohUojqkLgHI4OLIAKrh8faAqIzD52BUO3p23z5dl0FJHN49qmTaZsKVy5GXZn3w/G9We0bnlvrUzT9Ed5lH7JBPmzvMxFZQ3PnZwivv4dM+ZoNF7xz/Hpa5Meji8ek1o+RkTe1U6b++O7gUl9Nm/o/SLP+O9/Mgj5+76nV7/T0YbYBy3LeHfvNKsEnCzQ1oD8y2e+dOyVQF65cGyNgM0zr91Ts1fMPufPOd5qyf55l+B3WiQjBpYjvEPgeshEzDdNLi8nRJyPDQZ50G4ywuvA+m7HMo9Tt49nB2f2wxzKL76KFvpx3Ki3rKzeCuoHzJhLHaxz8YXkXViCTWxv3BSbHyTPuu280vmPavlvOyD9E378muVtGLzPoOiSsi1yCcTCgxQHu+7+T30mkmrZiojzVnXI0eMNt7N/hmiuGQ2+GbgNfvv87GSpF4poIjrrmGztcVDWM7cLM65s5q9D8vt6AW46KSXQHE3AzR7e1BHHrcIfyS4hMfGEgQVnUxeb7v72nyLC/JnHEEwZvT9UrLT9KM45MlGWIfXNoZJZjGxiPk7oFyQZaQJPdMeYOWocyuG7noNzcIYTtFX7ALT645P8d2gKhGQ8lqeS3klS+Qszdc5v2b8owQN0xABXxX3uzB2xznQ224saC5W8h+QpnmbDV82hdivI3KRuzGeAsiNUpfn3RpkOMQUT0isMR4RZLbSwbyAbMIEShI+dwdcbNwJpsKvf1DAOP2xOAuCxPx+uMrHG33AhycDa310eM7Ni/hCPyrK4SFqYVe0QlfNno3GahfRIsY0PTBNg9KrGBX9Ro3l+cBHXu4DPPYCmSTw5P1j4DfN17dwD9X0xDgc+qGShDNQ+UggzSAsinJVHBJvh0SNUgvun4IlLSG+NW8B2cfu8CCvvfFl3n/UMhCCKNa0kfO65lI0VGiBg+QjdRBqSzrEfh43hvJ2q6MQJ6TxujY5K+y7nsyMRf/6dK/yYZnc+u/rNJHnzW6/8nkLT6rPyfQe84fWQOi4nQje2ICClYWR9jrzJCYjvQuI60/ml4jSNNRhHzmYwiylDK5wuCnM4o/Cgn89l0FogFAW7v6+ONtufEpEWkoGgzb+Z62/XqxsnZexQIFwuj+/sl8En8f+FtPnwugZ9GsF/NCPbp4PPp4PMRZrGoA+DYivEtrvKJWPVroZjRM/qHTDrTy3/O+6+KVHZAEDu61cxtz3YQooE94Ys1uwqSwCJ86Dl4JQUiqeyJaTjjCQf89uE+qfBwQFFQGDvCyPkqxGCSCB7BGOXW7dYWngRfm5smXzH6PipDwx8eUO5GM20H6FwL2kvDnHL1yn6JVErnsmlJAol8FmQSmXSBTxQyeT6RTQtQlRRZAmn5bdIqSTymRd2ar9ibMwwrsdAU3+W4191Pbs+YQRJceJwLlp/z7Dq+P5Noviph0cxQiOI9PlYG5r46sGzO/fRtEBmZjwn5j/CQ+RsFjqCdsYdxgiUjdb1+3h+kWcjzRyM6SvFzzZSPHF3ENDFNhEY3yWECaHgvfj1xZgBxmDCm0YzV10cZkHXxNu5I7Hs70I4+cvjfQKphjgHSXnYw82vf2zcwdP/nx9mwfnKB/uggLeIKeh0ohE1U9juJZ7Ucqw8uHkOQ7PsNtmDI9uulNw2lgdp232PJovb3zAW+OL4xmCGnsM0Th6ni7bDK8gWOOhb4L/ET6IJVlYvxtblpMZ+V8tl0usCLYi6fy/OiIOYzBZHPSmlRkngpK6b5fCEtFDJiOpM70pzuRI4Pd1cjkH3ABUukscMMO2GuA5kaRX14YW4jh8XpaH6PUcFaLrOMk/TsUVYTobx2yZhhyqTOKAK6tLe4wP7G7ZUvizb5tQOamIAcRt5ZbLwHNiq6wx3OyjIvyXwmAUFOTGRAFiQKWZVPZIRCOp0BeSkLMrG85g4A+kcshbkJLQIFTKLHjSlELC0aydXgMSvissvhejjH1N+8QHAFjyNDiQKo3mr7GGN2RptkAvL2zicwq4PuVTDjnTyB8hR7dzgk31zYHcY/tsTwSgFJNgk9oenC2xHjrze0+3uEKf2WStEqkja0bLzSU8kl1PXEFBlLlNreGAl5AnQdojFMxUpWHmcVYf2t5yXkogl8Ojv/cqo7NjUfk4Ng/yL4NA59God+PePQPzc46uOB4jJRjtLHdj5OH9v3VhA/yvk2GzUenkz4nnxBpI6//grLUsdWvh9g8DQHzSdz/yUP+wqdnGOvCEPX5AjR3A/BR8tQcVnB3HGmYf/mw+h8rmzth+f7W0Dw4cwZsjEb4fMQ999QOXL4mBq0ztxsBt5NSjM5e2lwOrRxh2hB/L0CuS/4AmB9S6UgSi61qTaHigaShjlO4V+peu/6MS3kcgnhEejzCUiI/9c1zsuh4ZHEcYnaGOFcUYYCH6FOAjKtr+7FXp4YFo65tBx5gn3G/2Atf+PqrT/O8BN8yyBv6DR+46oDN6M2SYFiuS7y1QGb6VASGNswOBUuAxCBnAVszVIpCLm3es44bXPXMiFe0FBJDlHLsOE34jGO9yJ137ZoDnlVw8sGWBzUyIYdntCqhifYa979FYCSHJ5g1wtXc5XkuoyzucHkoYp31LH/yvbFG8ZB7yum5Mtm9L6+TXUbQUX01ZXtRH9BX5j82uVpLAc77afmK0IGhw3JEBGQZOBWOgEspT32U4mYEeifAFb1ZqzxRhwi2lB4/vZOFaOGZGfpsY3j5y1frK9vBP8coi30z3Ni86G6MMbZMSq0CS2LKJvx12ymvw3RcP9cD0+G6F0rZUuUOLhMzBg4lLiUn8vNHETNRyNoL/H8+ky8NDGSC4r4hxVglluZ7iO8pDI8n/cl/2K/fUrdXDabfptad25qM2BGHE31LRxcVjToHEqWNlY477dWQ2mUV+AI5LPpPFBzYjaf5UfSSMymeT6deaOleo4DZ4gje9RskfQ3KbcMR9MkufCUfjOmD46S9oftNro9Cb4p2RG0HlrchGDKYUGNA7JpWBZJmaWD+Rzz4z9wakl5zTKS/hEItaBn6b4StAVA005ZzhyaMlQg94eFtMjy+285bx1YP7Dg9tjiEIo/LD+bSHItg1ozsMiEcy2xfKyyZTJwAtdMc7aZCxlY0F1bHsOhrNTUINaSeoD55V7XVawTVjRa+7bY/tWXwP8rVWv1FtftFbl2t35T7Fe5y+o9eTNEzXq9aizrpWLxslzsVIvLzoUBbVkvnGa1ae3lJic3X27t23bj4vmun17OR9Vpd1C4f5H08UJRZrUhUmy5NhqnhHLtweGfGrVp05jPjYGRkdOKbaW15XP3flbSpoO2JC2X92KnNqs8LMXzxbRRbuiXaIjAqN51aovS5fKl2qvfjS+nOH0E6LdzKaX4VL1YG7keNC7z+rS+7g0Wl7y6vr7RLa1qlWfXc00ZIhtd3qXAaZavPZWkQrlxkal2Rf3q5gFNYPu8m3oZXK/bq4dOJ4PAhSqtndQo+zS55tW8urRP5+shOl/V755G1bryoGu33Wm3ab+YF9eN+sScNcSi0JC0a1MzRyO8QpdPT62bwW1bTdcb6aYg9grz6hDBpWEAeC1qL61+tSvXChcvRSCPbrpIvBd7t/V1PyXkO/VKsVMsFY16qVgeTfr3d6WH+8vZfbs8GqKLUleol/Rypyiiq5rKP3edRqvxMM5q1Zc7Y2mlcracv1/PHqadqoQMHcxvrc6pM5+K6+ydMk8NEVhpztysW4XGy/T+Mn+94s1TRV+Wa8K0d3s6KI7u+FEn9Tx41q3+YpCbOTdOs51fPNxfrBrp5Ww0RKeO2i1dvtjtfidl3t+C+448LvPd27rIX/TPS82V3i+uW6v71u3LndS9PJ/Wbm7WpULXKtozWc6Ph+j0KXOtGNZIbRmNdo+/gHW1NS++oIp6camsKlPxXhbsm1z3omSWhTVaX1ULp32g6vWiYojNm8UQXV41r56zQu35/tIeN87reqnb7jxfGus75SWt1hZ3Zn+qpm7vC53WM98QbqbZahe2H7KZWSuvPZSkISroy3WqOC2P76vF3Pndi2GtrCVoiMvOFTTuZUmGYAnvUr1lf7G6GN+9dNeNer3Pw8bteCWkb40hSt0W0/UXTZtZT2ruuXraq6fyOli152Ixn7tpgrqdfkjPGq1U+bl3U1vmry7FYseyT6+XSntdaTpDpAG5mtefUvXzWjk/W7YGxVGh/FIbpBvzQaa9WtXOn3op2LRrsHtXvp1eZlrV0xqfJzQLl/PCELXEhnmjPw9eTsfFu9Or9qxauK42i73CbafXsdTyRc0Y188rtZrcUqVTZ1lqSrUi6DXqbV54kQ04RDfF8a3ycldepM+vJhZ4MBq57vrq+gqss/PJyBE00Dczg9b9LHtr3/dfmi/Pk7wunDbPzyt6YVUpDdFicOWU63VzrDezTdhLPaPeWHCaxoVo3LSfCv0by05pJqV6ZdalW6vwIGdKtsS3hKJ1Ohgifd17AtWbh3Jz+ry4aOT6Zefm4VztGFXe5JcT5UrpXg3EtnV13j59lp4BfOg8j0ug1buEN3LlvjtEhdIpuk89Xc86Rhsu2zfWPLXo9MuomurmBWvu8LM5f1/PyfUJ7AsPhZfiOi2K1kKWM+kGuMXrYVYdwef11XU785B57l3Ls/HkodSrlsf3xfKiW7iz+EoNnS7L1m1m8QJTItQkqVnJXHcWcN6un98NkXL+YOuldbZYkcfVwgsvOzelXFm7yldGymV2urwvzGstM38xKNf5tHYxvc09WKf8FX8/0yZq9QYOUbsmFNq9l8tCGVSUSaVwef7QG12tb85nt+rq2s7yF9J9t9/X2s3x0/p8rmrZJ/E5ncmvb/q8Xe30hkiddJ9B57I0Lsq3bWM6a0jV0X2nBpujnnRRzsPb61R3DWY66qmqUlZ6suTA9Ity01jNi9NO/naInp08P6/Wz3MmqHfUoppv3mnagwSc8+seuuj07wajSXm+qFxdanxz+Zyu5ds6L+mnopVTOrVcf4j0Re6u3wHNtZpDwvrp5epUfamYF+nnu+bqonmdGgnpKmzfzSvN+b100ZkbVxVtiMhhU21VdhxCNGwPIkvDmDxvOKp3xVRFHNafx+Xncfl5XH4el5/H5edx+Y89Lg/lf/BV83l8fh6fn8fn5/H5eXx+Hp+fxyc9PiNSnvZDmtzIGI6g0YxAbSEIFRbT4eWodyxI1MOWZ1mlEYrAdRoN6vDtCfcATYPrm46FTSwj3ZCnxDco9mkdfVIvOvVSsVJslcbT58lUqxWWfKnYqZ4Xi71y6VJejse9p+K4WiTnS6dSvatM5Xq5O0jflRZDVJhoWhuVbutP435nbSxnN+eriikIs+vW+KGUkpv3T9XU9aLztEDzZUu+Br1LIde8nhefWqPq1WV3iFai/qDdNMBVt1KW5efy6m7ZTpVNpVueyM+1F0OajVpTq6nLmmJWzRF/pVdLl1fnZbHz1J11L5+HqHR6f21l+pX8rfXgiL1cTiqK6sPsqauD5+vVuSZMciKEfPu0fzXIiflBOYX0jNDQ1J6drS5saYgmzcoFmMKZsnwY6a17U5zn+ulW50mZPN3f9e12ZjC7rjVKk4akSZeaPE4r6XJ9rPSbo/G4B2t4Fzwhxczoyg2qFHLnrbR80886lXMLieXGXf98rMDSrTFAzV7mBg0eXtq3NTWz6JXuyvnnG+nKOh2iZSa37kt9oThulorFank8rhY7D2ieMp7LsNW+7ub0bE+8OhVsdcWPb58epPykcWPDwfyB1y56l0Mkneeml/B6tb7WTEVaDO5u+OnMOJUbz6f8ZM5fwgwEs1yGPy/Pl5fqvdHrZFLd9GLsPNVuGwhoQzQpt7L2Ims1oc3fwUbbeck+V6XilXFZXizrOXB3dWGJPCjCh3ql32kUOqNar4YaNy/Xt+i0UekPkabUxw/zVlbqzu/UXnGJGu1+5zLVbuW17IvA5ycWqFwr1XFttrp/kKb3z83nlzuRv7yb2ZNs/qoyRGpbW1nZRs3u5XhNuyynltdy7WVaElNFpd8znrpSzqgOJEkuttqp9Mu1mG3VUqnlZKDc67e8zQ+RIrXHd6s6bMDT1fgegVml01ilnw10s7YzF5I0Afz1qFt8KmC+16lo8oN5etNfnjdR9aqdBqdDdH5XQ09w0tWcnqBJzbva5aq1hOXKqXKuN6/487ne6/TyXUNEp0ped/Kl0l1txT/Pcjd3Tr47QUMk9YuDq9zzabs8VoH5slLrEyCPUv2H8rOqwfqF1dRvSurkJntRvkPT06lm8bZTTrW7RVO+7S8rQ3TRGDTupqXJYjqwWtZy0XkBi0q7Ll0uCdVK6nZ8NX2Sium7rDquXzxcpGqjSq+k3S1fLken5vkQZR7KffHufFxLXRdvpQWYq/Jdanm6OM3qpau1aciz62Iv3a7VipNmtp++uEKDckdFl5nn8dwSrp6HSBtN5UJ/hiyU468AGjw5g6Z1v0i99JYSbxsvo5dJg59rRnV+q3ZX3YfSi30tds18y55Jk9z5dIgkXqje1VrFO0J1uSKsrKe12EhbZWjWFfmFd7LPd1fF9hQ6D7en6cwsk3JkZdm/Xcr8uPpSGCJ9Yg2uzp8K80wtnRVerhytip5PpVnx9kquNPRZ/To969i5xkS70q4K93w/Mx+XZqvZ7fPl5b1dtIaoUeKrs+b9qVBqtTKZWan73Fw9nPcbjiBfKZN+amXZ5jU06u3ntT1F9y2A1H7zQX+pY5ovzKshuoNZ45m/a7bzitxEsCoXB0sLDDJzMzftKOmrQnU2mOrZF11qFMqnFbC6LVad5UtpmdJqjq2vhuilWzo1KynJenGEzLIhFqrPd6NK7bL70pyfWjCbWqulp5m0qj4Ik5v2UmovS72J+mxnpbtU5tJ+HiJJX16g2UWuK9cm8mlbui3JWe061Stk7otKfZ5fXffTc7XQKBq1YpXvTJ8bg/vTbHNsnqqla/6mNUQ3kvhgtBewNr89rcBswZlcFq+RI7zoT53ywJ5mC7PcaeVOnfF26/7SBkuQRXmtJQkPk1MrJ66G6K5np+f3mnCfLZfLs0X+PlOaLOtye3l3OU2/VBdX497FTX9e5kdgXSyA3nVmNHoY39yB7PL0gV+mhmixUOeFyq0h1HvpKup0zZfcbfO++B/feR4+pt52kj87hg0O+yBivyz8eUQMe8cByMYW8aJbxnfSbuKro8zP2NS+p8KBFbuuGDEXzJr/GB3B1HOxaUkAE6dAi9ivDRSQL74MWarlhGmB4Qn3xbTA1zPOewplGT+FskKeE8epCAwYXAYLOdv+H9bX/WLKpnVfCFXg4YaSk7OotncFW8UbPag8EszFnd4WG2d5BfsthLKB+oaShe+MGCrlfq/zjJT1+b3Qn6z30lmaPyvwZ+lc9kxK82cCX8ie4RJv7edn2MAnptQ7MaUOrrGFMfWc5WMiLLCP3oStIGYSfCHB5/pC/lsm/S0jJQtiPl9IHwliYQt8fHuQQ6G/tIte4pPYkb85KZOW8lIunc7lC1IhnSsUhIwgCZk8nxdFKZ3NFPg3gvMFOhEHljLQpQPwEOmsiKnMiAWpUMjm81khz2dxnHI2k81ncmk+k85kCvmcIGVzuWzhA6Zll5Y7cmJYUMqrM96nR6NCRlWFTAbI2Zw0KqhSFii5XGaUk7NZNa9kYSYv5MWj9Q8zz539wi+ZsuBVYKFjYMMlCf55E1EkiGBnMiDsJNujZSguxBAxZGbHEz3mECmWOxeswm9DlOC+y9p8Ak3r+zf2AXatRRxwQdjpa85yNLw+Sc8sD5v8v4Yn1XLlopro9oqJYrUniPlErdxM9C6KYjY3PMFiTMTjP79/TZK2Zxp6xFgqWErRDBSggXSLvWANc1++D0+EJD88+X7GkT+FzZ8i+ROjseNf6eGJ2wh20Bf9VX8fnhhoePKdFTZUdXjyPXL+mDDEhogi+vgJPqGRyuIbBaBgKOhh0eAzQOz3DxB75aqoxAzo+lwb/4y14U+bsn0SEGaPM2cAa7LBMnrVSUV59K1mT7q94pEOVZfoSBj+gCXcK8oBfYyd4iezfYy5Wq70iphWSvXJGSZf2BAf7MwbmbRH/Q5xZ/egR8g6P37wp1qEZsIhXIQAVcfF1c/DtJQFqpDOFwCfKwBeLYiCmpflPBTgSBAVKZ8ZFTLHEjStCOwPEhzjsb3N2g4ifRwGNBk5SNHh4wzaE+MgzqODcKXKI/39aEL1UcgBGWSlkQLFQi4t8oIswRzMF7KZdE4WZCGUUevRQ5t/L2+OrBM3xuIhfCqZ7aAbdWPfiroluaGVsW1a5Wq3Xz+vl4v96samdd6olMul4npcxF4o43qnwmvq7Cl1r2Vb7ZQ4Vgbr3kh9Cdu8rPNipdQaombHWpY795WbTqdWXTZuBi/Vm2apWSsKg2p50mx2azoCg5Yuo864d5t9avbkZYOWr1RX2Woymey99C7Uu3lWR04qfcPn65L4LHRaL9fl8b1wB68ytcsb+SljmDm5n7PvckbjQoLt9kw1S+pzPXU9RNfwIj9uNk7PnaV9d19tg8ykpKbzzSwcZFe3NcmnMN0eA/90kPCUaKbhQwL0uAWdGxyMssnjeXBCpJGQS2cEKSEo4iiRkfOZBEjnQUJURxLgZUWSsuKOawcjc2ckjmtm3btsPh2WPh2WPh2WPh2WPh2WPh2W/mYOS4q8IIAqY4rHRyNEIzT+lfINV/HKsUhSKp6y9HjEHEXe7svu9b4bJGuAkXnyV1SG1EA604ibjDbzA+IFpEP2LWdE4uEdNhcIOFsVNRcIwjcxncymhUIh+7BDNvEy0YVyQ3omqE2WRwznF1NCeW9CtW08y39vYVxiyJZIXPYQHiFBM3kFHnQsoMDXp1H3p42NEFPJu9cMcQTlFW2s4TtwHe0Kxn/zTUzKA2WUlrIqn5NzSiYnKkpBHBUKUISymhX4yDy2MSwW7+jte+xJLqDTezVhlu7VFM61G9F5T+fyvo6HlReRHfQUfaGbPXnuokG4PfmDujHsQCSIIAFbObClZMMOfcoiDWm2BnTthX4VWZbiZym+13gHYOgR3yMFznVjjaF6Ag91yCpxHxGW6VFB+CeumWCw4vr8BD1inqk8Gg6u08fN/Y9dUgIPN8SEHlNyAg9dwmQMm+LgxBOWjW37oS65Dz1CFchwY+nIach7g/GgnTlLh4itIYYeHqI/Y+qDmAvNKxlAARQK6SwoAEniCzlpNMrxGQAzAsgLMCNCgeqCA3nTX3fukVs4q+BtJx//upPPN/kblLaQwBGWKjhakuoNJmABKQ6QCWWo+fCA/f3aZED8Ui5+3XdGBnVnvuwU4aN5S9ihZB3gGtXuzXmxfsXphjHFNj5nzpWLRap4iAEfHYG4FxhDn9T2Y+Suv85O3NTJEUo4pLhILD4QO/+8yBjtBZs/3Ur2Q9mpQLcid1QcY4JFoPBxe0D/hAw+Morge2xO7qQcGysQz7hvyVKx6xMe+Adn/DqmtTN3EmR38STp+FyNLREFqkRaMdDx84mRRekHvt+xHoOD+KE5FgPZGP6KOGPidGpuWBHOeCEbFrEXEhg/Ynj3HIs+TVoeANfjyAREbt29jw2TpFDHKKSK4ofHK7FPPSMLQW5LcjRSjKKhKQoHOMsZMfHFUDkLaclN+5alkyQ6gIIa4rzxBqK5MTQV+1IRjE3TgW88qQPmu0c6ke8d1e0KP62Ev5SVcP9C+DQcfhoOPw2Hn4bDT8Php+Hw03D42xkOP9ic8RE2gg9Uv/4+2jD/0G7f2jz4CLfY4VuZGziwrSxFNC2Ba81kBYnUhOMeaIoGajHGUNEYsIIVmTmWjUMcWTRZycCyE6aPaqKPaO3cE9pxcubGdfQuiGNtZI5gYOrrx4mGoiy5oatbFZflLnBZfMWACBN1QIINWHfID0NVd3n50jiNQ2TgzBbixxAQDh2JlJxZxuhg7Iszx4jwh4gRkqKPGiGJkwMLSYH8VyT/Te/xgH4UHiPcm0Ojg6kSkumPGJ84G9SOvLFi0yF8Q6LW8rEcrGOZNBlQKrsP9XpX+4nzDGzu6G0eeHbELVtlyKQY2/IWS9EYsXeCPfQFnr+1b26Pjkp4xLLeaW12zZzRTi5bduaoPmxe0UePJqTGUPpwZiwC5mWf2Xjb9kyAhgJPZtrYsyi7z8jKx5yClMQZKB83RJCfHnG+X49gDlfuo01D5KcKNJ02G6jaLfXGOAo6HRHQTsHpcNMMs5zGr5+VoDH7gPX/kC3ftzbj2tnfNTzZfcPjl4wOJ8YI9fjTDeJnu0G8fVXktldFl8EHkAJv8Ip5OzHSR591cbZqmN9GM1J3tR31QMkf6n/AzSIm73rTIOznV+4g/CDOVXjNsDDNNbAsQ9Z+o+E53ioS+L2xkNyGLLbHPXU/zeq9DfMS90R8B81CBM1bMY4WNwNrfEOlg82R/PEEaOTMS1flEmbCzQbBBTfPF4bsulOzbOechhJz0xhjixwHrDWSJ6aBDMfibBMQFYyBDnDC3aJnFEGBxy495NJAevO+7SJECNSVA3Nu65arfPgx806BbvD18NM76Ed6iPwwSzsNv2eX+Xc2wGqhVbqIXjhhrXYchxRfbUf3QYkGcPOiu8M51WhXLVc1Q7YpLcIS8VkMoUwxiOJEQyQvKtdr1V29HdaleElL9+/mTXa2Ex9i2UmAJh9PCz/3ff42joUpi0QvYoHvr7uWbJzbNiTPJhtyZwCBMVQ8hIhgD84C3wNlgW8C5OLqsqoNRN3JWWgs3tH9A7H/IfkGp6Ejqm3sejIxliR1KrA8ECR8DC4nBkf7anGavX/MtubYe8CAhR7ZqBERB28E78FxhJbNoB9m+0dlJmIsWIwg2kd4mjSiUrb9jt4hJQPz8lbADi1rLCfvdEKI7eQdH3QkWmcdjeemA8vmZoZCUhe/qR9CJsELCV7o89lvIv+N548E5+br0K6dhKdmuatn75gbgec/vE+ReOURy+6I3eJFMSEICVHsC9K3tPgtzSczOamQzr9/yUXooCJ74xNH39+bdIKXEgLfxzMkfMvySVEoCJLw5t7sCfnYuX88NyXbOJAA9CduJK9j0YCCsVbdO8JZhEJC4BNifsPp0lJGOMI8vZUx/JJ9eTtDeE+k0ZE5grPLBzEU8Extvz7PxAOX8JEsiGkFqplsbjzRpLdTFxc4z+3Je0IycBVxRJFIX/zgEN5sAqSapAhnQezn7kOOom7Ke4fRXvnNG/QXNnLjhzOg6W+Udrfoj2Izvh7QQvhWg7NqMK/P0IXg9d1hHZHZBQC/PFZ30ofXyw+OpwjeZLcbj3F/3dtChJ6JIpEvwtP4zik62spjsXQHwOK8jOC+ftAvY3jmuBiG29yt3Co2q14+cDdcH69szPc2gBD7B+sRyDOYkCdA1yEaw1AcYxxJgJD4aANzDCOvNSFKaUGGcvpaahV54Yt4eAWRZMJ3oGDj0AhD5UgRHGaBFbeQBanuD0elkRmYodgGh/cbVta/DkzjtcgOCna9sWwT2Ib5f4KTtYSjGbBsGHz+J3MqehwZyg4/eNlANlbmxu4xXM0xLJ9tcKqGFI59RVpxTJ1THNMNENo3FlEKBJBOZKVMQUwX0iLIixkpK4/y2YIo8rwqABGIaQIZ4jYV3R9MA40wwMSOICdPIPYIcAl7JVG4sW+pVCjKN5VcQl1PTJGxRKn5VEtsqkvhbihAEIEgi1kojTJ5Wc3zGT4v52RByqVHeSAmMSeKDTWwj3XsdfzYAlexV/bjbqbi8ZHYa4GMLTtQ+3d9d5vvGmrudewoTmg17ZMHcBoBPL0h65XdetuCyQv8SFKyKi8I2UxWzIwKOWGEY1WyUh7IcjxdkadLxskkdog2mOQKzjVxUDDbJBBh56KQ2SSPeMc56BK4CzU+lBMjGm3U26ekSg6oNrNoUEeFRwNxSjASx9cdd9TTuSz/vn5sTADb/XALcbQQliO9JB+h5WTRwcfnvQY4mtyhf9XbNxkF/s1TsHPNX/U8pQcpxtDWo3DWv2+Q27/TSE+m/GfZOrg5sCdhFHY/+DrxEcZhU1Eg7Bracv79QGB24GKw+zTb9g6P1f/9n/+bMxBRjL8KsN0j330dQnCPosH1HMeeuym/6y6hIhLq3dcMeUnQLwBaX6sn3/4rPOcDL0A3MJsYRt6dsyRXjDlnyZOA0BHLwdr37M+d8s1fW4JQxKp/RdfC80+c0KPmOhnH5zjspBxDNnsFrXR1JLnbXSvBT6PfCznkqHyYqjgXMX/k+MGLJolsfiRH4juvmP6aWKj2I756Px5B9xGqLBQJfhQ0g4gKw8BV74l18QGQ/wi4BNaMH9PATf50JFACWl+4kaNMRVSN4YbiRAu9phlSX1gRErEmXrkBdwIo0YgaDBDgB05aQvwAkWxSRM5YTjQdcra5Joed4TrzQQ5EITO89wraYkcmcTnBB1axWCx6aJKYWGOJ3AAHnCFFJpRufKpMmBhDBE1iYsZlTWuizTn/iHC2MYXU3In9ElTDQUry1cPqLuZ4yhl/8/hLLKgERf0d3JF2fceliuAvGGpAB7JXa+7zJ3APA38DvrtvQKlF3+4QI1kFO3U0VCVzHCqpTOrXOYRURP7r2ltjbHawk3036IMTfcYZM83Ga1JTg4WYkxuGlEDkvh/Hpeot4nwU7wr2iSnijSCFB5QqoYlyf8+gDTCe5xv1oNh9OoGvzticggsoCZaAce7oMRwwQvgexzmVE9njO4plTjyo1HfUhofrERjzgAyxsUXhNnypxd/ZmD9JuUhOLKDr7N5wnIFmNq04suahnu/1L34N9KyYyeZlmAUJXk5nExlZUhN5UZYSeVjI5CUlrao5fht6Npa120EI6o/sKIsEPfGh+bgnXr2yH4G1UFAK+VxGlLO5jCLCfDYLC7mckC8URpJIUE38pIr7SaN660cVzDQ9Qs9bb7uqbY4WOeOgRu4h3xeZ79yXenuR+Uqun4sc/Zn7upf6RcbHUsiPRY6e0IyguZZwnXATH4DYRlt5k9/t9qeHUbq2gLWQo+tBzNh3+Oi+1UU3nrxO++v/4jVuqd7o7J5cjDT1i0/sD56g448v1bB+wAjTW+Abx5h+/EPd01/rUb17RHH8KLu1xx3XzT0Ip0BW4Mk3iefTZxu42ZOWwZmGY0NPNTzo1k/++jMAcS6cvWcLbGj489X17PbsZ2OM2dqfP5K7MSwM1jz59SHbh03267bRz5ju7f341gmnNf2UKY+Ff/Jxc44z38ZAJ9x9mO2tN3oNva0lOkfue1Oe7DDRe9Klwl33OFxQs6FM4PCJxcY2OGhhyVCzJlTvIhsIUZlrv9Ssa8hZPYKZksv4SJFVJUH//PtKcbHmTFaVR/rnP17qi1oTm532K6+HV8/zbyQr+giPALv3XUv7pBDVITPmYHFrwzHd6JKAO/kfFgeVcQxIX/dSjDVJMRnu5hqNjTQGUrXxo2XKcWdq8wH9nLG5uEvE9wWOPDUhUV65dVke8EjslRP6yqvIRV54bVX+73Bl8XMms1o2H0Q4ALGQ8vjV+T6IqC6GYoxWw/6hk451jwqwQexdzYpjFhwnq3OgSfIF2WUzw4Zs/cTmn/5v4ueApl9v7FK2E9McFaCcGZx8m504z0QqoAaDesVVdm/verboo9NceGp9YjgNGMJHUJGzvJLIiKN0IiOl5cRI4PMJVU0rAi/zSkHMvkul5nXoUUNzJ8I48Qt1a183DN3Y41bnIxwvY06G2HTnz8L8CoGtcn7rF9S81RwRk+INkqqNHQpuQ+xwGqLwBKajwxj4gKz4diNXDBdw7ox0Td54D268uq0kV7Q5HeKQP2w49LfMIQgVCx87I/aJz4ON0v7mPHSM2dDWug5FFp9piEH/CX+dndBTr0t9nGJWGPwGo0YCc57AN8BI4PcqMSFwTB3PIWgvDXPK0dhXTjWNGXdb7LbxQjDJQIRLkrulleTcqBzXaUhTfYOEU3oTfywLexBAhX4VNa2+445tzZ1BsSER5q+tRH0EU9QGGsIxzAm3Zs1Aic3tmJCtalBXMPHaGBkmtQz77zOWhmToOWXhGLukwCf55EmwBWuqzf0Wwi1hYA9uJxkuOoKA0w0stK0p4Afm7vra2yL4JkUXHldXue+k6PczFgDtH3IHC74c4O6LzStOxfZ35kzHZKkZkCcagrSaTW8j62JfPkDT4Pomxs1UgDUZGeCQm++m3mDEPabaH2nPfvuK/xk1glFOnL/JGP5hhbjcccZ03wgGV6cNTRPgAyfh0THSdAKHcYLZiYMlKIOMKtC32Pd+tE13a3iWbDzgkcw9yQ2o+6YNTUQmyDY4DEET2HBLzZ7EGR3XT3UXtbucfkP0sqO6HCD0cCus5F5LWz9iDGJfWGJLrkEr7avEx43c+GopHkdOWjaYzaOkbstwTDmuMBnY4Zthfr3k7jmMuWs1fuObJbPNvdnEHR+z5/c2dLxWgRHYBG80k2xk0LffMXYIsD/zkhHUEeyVz7f6YnEjaC9xnkK/rgRL0fuUJW+RVtnPxKbtk78iO+FXW/xm/YmSQV8lR5JYEcsGps2Z0HZMRGQIxMHZ3F5T9/Yk1zc4FdoyPeX8XceO7y5KGSHyjJvjywmkUXw4Yg1SgUfhIFLmhoZs7nuKHRlW6r83h8dfqf/23dI3v/AbX5PfgwdbWL8UmjuX52NCPTABdtJ7+n1IQu42d6pNa9EqPCI/Yc319zN/fViWY5qmN8Xx8wUcx4+xMNLfeIodEe5qSAP2is6OoEwyV7EKuC/ICExkVEe/7unph/UzcKzH6aAJ6eHtR1p6c65yISFmMSyEKH5LZ5JpQcpnM9sQHhtyg8q/V5PLPt8aZ6/QhHnskryubukjDfruXpG9/9Hiw7GNUz/d8n58UwRcadau1VVXPez7Mw9ozkD62ls8fvd2F4HsCz6X8IJia+krN4KqYUJ6FcXrJskNulfEHf4QHolj6glWLrEfakUQ+7z0r3RR5P+VLmb5ZFb0b3kVkiCNiBk5Z288NY2X+ix8Hu87WX2Rx4C51G51yycXTMBOD2gsClwUXf9lcvY1oTXhkKHA/apTLw5JVXUNEeRRrF0iGKQMjHSX1zCjynUQ3x9m7F5pQwqrqCQNqqrJMCEk3bt4jMYfsY0do4pGJTZxL+Oc700Yaz8OYewvzm0rHmXPDjTXu+mrk4yNZ3SDkOwrQZKszSWeSjOsplik/kvk3YYjKCP1x3Df3pAegxNuzcgvb9fyL+BXdDCmr3jUmDPTmN9StAfJMcxGolRZG8uwz/vf/xBrrx89RsAekKvWWJMxT5o/WhD/MSbqMBlpB7b9G3QKad8ifJttL6RU2B7V/TyI+m/VK6+7tKoSr6qFfDYBMlBNZHKZdGI0GsmJDOChklHlfEbIxuQFlM6PTG/967vZhNjPP93VZtfa+Nu422zP928k52rybI7z2azWjz6LWdj1RtUBCcekRQj59XKzzZEPPdHQDRZhFr83h5Ztqaq3ZYqYwHe8mIYCn1UzUIZqHigFGaQFkE9LooIDa9KvikvxW2C3KGoHzcYHNfe7hcpQTRujeqz8A+ww9QPNHMs+jKEztsllBTwpTrMIxgY7inCebvIo2KkD6NvOiLRFUi+SPkeMkmnYhmzoRNvnhgNhbBZo2SyNHxkwnHq856Zzw+uVfGV94xgU0hn5wyJ/OUhbkT9smb6yrAn511TmXoFTW6elrdnoWyqV5Io6sVDhiwS2HALElHkcILgI7pUFX9YorhR98O2/8JM/OQyMwf3hf5HhM38kh1H4CEEgJ0wGuUHgUf2W53lhi1f7Eb3ZSPr3/vwkImbap8zmk0KSTwppyW9qmT+y/R0ti7hmfxyFhW2qOPyKMwEae9e0TcY4skbwFZor1ytdfDmOEQMqSGJSyCX5JJ8ScvvFkg2tj+y2HMFK2inSOCVRQ/gO7t6tGcZLTHL+JZ4LOf9IYeU2MWTvHjGsfMI0E+WTZnELzbQdoHtOEwy9lNUT5rRv4rDHMfZud25T6of2kjngey4DuxKSHq3bmwQlbD3vNetiQDoNOZCoeW0TQ3P6db+4qxZcQBPoGOuFXIc90Kg1p2gWK73xmwH0vj/TXlx8AU6bYX0U5HRgQySvCU80oa6xPmG+6FGLM5lwXGBGAmp3rPbcNIv3qmPjZi2bIlsRYAbcD1d3SgZ8ux5PUa2v6clFv8Oqj5gT+lbbioNkOm+467g7RIOLXQ0WmOY+QePanka/UQYZSw7oSwyLZUKabwJTlfStBOq3gRUACU/rt70Sml6pgG4QuqgQuLEJWEDXj8o2DkQ4GGMr4MwxDtg8Z9CaPIKl5XOl2y+GqMiMvFWe6wYFe2qxLdp11eL1CoF5sgnapGwgBZhrrtqqU42nZnFkmD3DHNbPEXQuHLSEUwsfUOsgLcELYjqTzUn5AhjJClT5rWONUR3ueNgETwQTDyzykA4o2vewTRW9ZsLLRRzyUum6YAzWBATxyCbgcWYoMMmd41hksLSwtw92UME8AYPwfaf9+M5KeN5FgTILbW65JZCB4Heyu78rmkWkdbf8CDKzoWG64A9RXnPBmyjeUyo0SZInPBbrBBVJ8ZVhwjhjAKgr3jUqsAQxsFTcz8gI+D8EiqLRvdz2zZbHIQL+ibT3pKOEreLBSrnDhHM0RLmHkqB/NlHx74mTR/eTLYGLPT+0NOOad968LNssg5fqrj26bOga2zUa2+vjJ039n55zkjtkO73KmgYybANp1IlPQ1izSpzxgk507PszWgIzZIzYgzgI5AnXHvSjvbiOrNd9z0J7t69TMGNLjO99H2z1JbTsN6TtmrdN5wOjGm+ffKyu6G/uTLWP/7zRtSqwMrf6fKGNJwmwAJruyp+4nCfVe2a7pHugzSBAFrbu+bzCsdSJDNfOanKa5XfKXUOb+4LgEl+4mXmVChruFYLpHb4mfSdlsJ3VXNdkzcZ+pY6JPc0NVU0yVulg0OzibY/INVieIcR7EozHRkk59zJTb1vcl5t62/rqeuySUtSDVQWHFDdg6Rfs8MBgR2hGOz6EyXtqMdxvuNjmp4fh97V5FDAv7hIGYSPO+G6vNpcb4u8f1b23eFgRqhfa/BEi21yTHQlWLMQhH453wPQ+zk240IwoY7FLOEk3zDlzTLqCXY1ZzkvXq1cxNdX+SLq3Mg3gcQ5vpM3HB+eJKboieuwtQk8Z9sWvgfl6QKeCgxT45LYCyW0wSLPHKHeNW1iIUfy8e4MZzNBNT74JPM/TI9+Gq4gL9bVr4CZsKSD04A+iJJlo0ZHtFO/KuIXqGkZEpCeWW/7P7XZoKhY24VsQgxHjFgi5P9bIKYbsYKGG8ncGJ78FWLu723437P1LkPgRUp18eOg+dPA2QZZbMHLkjZfZ2B8VsGVa3ngqua38t8/caqiqCWbzR2JLjm8OIXzQNti/cXQcB40fWwr7kIIpINvOgQlm0MZxV+4hG45i8+8YV0PjJpj17ur+wAp8W2D+tEyNHicYIZI34asrFnuuJBeF2/LsAi6BZ6GoDl13IeohFdHZl39YXFlNFElLicbSThQtC1NAkglQhO8JBEosch2lDyKuVrRyDsyxgACYiybWbRA8NAY1bRucSegK9GJjq2GuUVzRUTSIY8JsMLaIcWDkA4Lz0Mm9kBVyOmmAPCQRiYyauYGlFSyVtOvxAVCDG3I7Jw1au8uV9tB1eVQdXdV0LIa5g0HTCryE1fO71Hd4IUMwazED1+6D5wWaRsLGYTsJwxwDxJqgeoitw4jOmK9uck8EbcOIUDq3sRWKrLO9KRIiYO+xvtTnUM5Ur1QbzFkTw9GxfouGvBKvJo2V99eh0aFkYYyj9d70dpvgf+y5akQFD7MXhF7PfZoGnSG45Prldsh52u8S71rCSEfgings+vOiAayMDOCu9K96ZyyjLhW9bdMgKwKbbnSLUbM/j4FATiYqwpYnDppCpYoNK5HxpRVazuJkWpKmGFehSR0iidp6YEHV0dlwk/1oOoh6zXO3vVp9m1V5MZ8UxVW8pj6I25vetrH6jCa/oepg23BHjwb3YWOemOSuWUAfU7r5LiXAorbE3c1fGJZ9QdjTNgU9aNMZIUZDXJJxMm7D27ANGNnuoqbXi51W4b9wVl44L+raApb3RY00wYpgzG8SXGiKDjn8McAfRwZcsFgMfExsbxXFgHT1mxATI9tM5Y3zR2xakQ0kO6aJe+Rr4dCS4v39OrhbqC2FrmOAdnfMZc3Y8gHMoPttBBkFnsj5tjzpteq2gWcrYk05dDXR9UHn1nMWDUSH0mXrZx+xTCR+gwgCM7at5mt7QhVlrjIX0/mIMzrbBnFWoS5myLgA8/m6uoYjoEcllGI7khD6v//z/05waQ6y4v/7P/8fB/QxZqSTGWFK+LqRItZeL9WvyxfpSnWtffiUmRELk7tzfDDcnoU+3imDjP5V7wbjB0cAhXoshWVP2MAgb+ePxljeFtUKjtbBJX2LpRFy8HMArQMfkbB330TS+H8sCM2DCvg9XaCf9sgSaEV6hHirhuLd+OPN6WHEklgRarbZ/o51tWETxIunH+mnGWgMRyrhiGnq9cMqp2ZNZGHbI+VdrkihIdsg5xIJwCAfaWh8Rk8wOgpnXK93gWWebqXNeIe3LHBCd5zhiHmJ0kbd9DqEFmzNI8mD2NlMINu/ccOT4Yl3rJtw7OjAZJ9jdjU8sQx5arEygOtdly97WVogyu0CyzLy/NJlOTt8WaP4Den8htvgfA6Q2lIxz8P4FX4OFMFZt1jEgbxBPEUwjiVDsBxv9PDEG2QCkGJNwBRGCw9n7rFLzJXyxLCoyOAely4kk4H5LF4HvVg0C7zf33UOxvCRnhBRAt3Yn4VpDsbY0QdjRBB1qJ9jsCp8bgGC/87saxCapNHt1lpeQ6x63DVFs+Y6WEe1NKOnKL2RRze2Bdqzx0tiExRPDyYft/RQCjzuExn8vmWcZxVGSC4eBEIkZkGMm2yUsX6v/0W0/X7AAhc3Ud4u4gaybAiUMI4GReEI351D7q6HDGxOVNBCPySruGtgw1aIQIa5IvOr2l4RmzVOnOeiFlmZyT/4LdFaaMi3rnUGScMaP9jEK9byHJq00XjVi4Sz4DF53DtgbvVM+6/TThHGiPCJgcEefeqK/U3yAdbwIbEc1CX5twnkiG368wdh+HzP4gBEbNz73mNyJOAKVCft+YfFriXiw62VsDveyNMVm3AGzCmLiRq52dNihEFVg2FQG62O9+0GoCboQSzwuxL3heZlLxxBDBJjhmwEcAbCZPz9PPF/Rwd800GvDyn3iY2EeCYNHz0kPAL2YNtG4cfxi8MxvfKY39Ifr8NhcUsTrZkPrC4Wsohb/jXsNAglgr/c4QbK3Kn8ckmskKHI+vDdcA7Rq0LcQwvDh7Nw5Lh87+LKvMgjHMGpCcJnkfRFpHqKO98FMxkvvEqbE2+WOEn2Imfvr7BhYHu5EyQ8L5bwc/WHVv/ff1UG/FSC4eUxV+i+VbYnxN0KJPpi5kum5CB5xmhauu8umMh37gs7EojtBnuSM3dnB309474rcGwCBTu/uOU8v2waOUMUfAa9qnuaG+LyjYF0OAdNINDtyZpQBnGV7MGravxKs84qxhJtvsM3W2IiCbQNLE5zLVFhmJQQ/kCVAKXsj5OhxPo8a9yRI1IcHRzsnOaVwzT6z2fLGSEYCXYRYgRgDmQSQBAPUIhU++h9RXbza64ubgV/u7sL65h30EbE0Lyilu3vX4e7zOpxmebbiAjcqdhDNy4+fjV2GEE5vIaiMmW5L/3pAT0tBq3gsKmc3PwPK0monxhhANgBi9m2txqJ0AKK2Qw+060oM3UrVD9UXlt7RowatTfiaWw1GAtHI3Bh/KDYpM3GiTxa/DfM3Z34SJSA7e3w2ghCCsbMDmha3avDB3k+mcvQ8EExHr1viOMLRbTRmrYC23AsEo4RwyFd2I9gBIkpLPQV1tXtC4X7QaFvfk4Y4ROFcZ8TqqlBpOhrzucNE2/LkMn2ne09Fm3UtmLN0asxaOh3x8eeCdATPVaxiQkGku8YtH+J/GbY/iXydOD+JfJ46Lbo+mcjczBZ7p+OyBFeC38b/d9mfn8jBWD0bDxuVuivPS2HIsg+b0mft6Sfc0v6/XjAYay0OKLURqX6yJz6fZBpEe9IehNAjhhDX0AF668YfNr+QCPshhtPN/JplD2uUfbN+ZfeadJlP96et+qINuHHyMtKuNwrSI381K85YOv9Hy5Eu7v+ny5Fb62Gv40Y7Zvh3+gM3SQZiYg4OWhTEjLYpsQLfT77TcRm8CRBIXnYr32g//yd08q+CgAikHg01hdB1Fbv4z//8czFby2OUrfRN9wXez1n0Bc+S/pX6ik+AxoBkbHCdjSwI4tfjKA5ltY5TmpUXHSTFPU9qXa8PKSvtliTVe9HOY/xtVf8XUbyjV9PnKVDC786I5E3Pn/tWDq/TSaB+KIk2xO/2eG0tTB/m5k5pugYnsFPHq8f9AZlTiAfYauLnxTWozUqUd7PoXZXBpUNqelfhdTDA/tKqxqIBZo/0o3xSWRTUbP4zsbAXEt4sl+oSe+KRFAPf3WG9wqdCunOb3kSWVA2YYRk6YUh4yQpS8NUOLcxgnngoE3G1ASFwNykSG2yyCIvo1da5EZrAmmKFDevDXbwAtwIWDCX4eg62r+wip16pVQc1ErLcak4blZLnfuLcrFaLi4756WxXPe9/w+ND4LI0oiLV/Re8xbhtpqVBbH1CTinZtEQf0LwDMoTgDRrRuRnx55gCAcSA0oipubQ9CJL4+0XuG5M6k+G1ro911q1QfYhmUxuqRdjdeeg0jgOOT8hwYaP/h3ekOTVpgfk7qJqGG+bG63POAviUCIWsov1xcAfA/gWMKeArnSL0tBldfflLMJ1NHwjAyG0hh99JYt9lwp3+mhXq0CypzhpFrzyr7qX+f2tf/adLHIB/TYXgfj7J3qj/Jbn5O7l/9vM2/EvcDvn9x99nwsCrO6JiyDgLVg+ol8kuZajE1Qb6r/P6jl6Is2wZ8auC9TeBO5+QAgXRpFISQH0IJshOezJoRygWkxKGHxwQwI1xSV8ZtJjWpjDlr6/n605KoT2HX4i73YQ2WFbDW44ctdmTo8RLW58f3ZBCO+a19fGCIfyU+xfvj0bB+yPuZt2mVyXifBmyQT2bU+osJjdrxiItpTv1mbEoPkjfbtj2ed/vQ4cxzV6l9PBK3ykX7XkHCuB79cJIbGYy69cVp8ODOHD5Z8utyz+nl4MEdP8G10/QiHI/z97b6LdRo6kjb4KLv+Z4+UnaYpaLLnnzr2yLZfV5W0s2VXTLV8KzATJLCUz2blIZtXROf0O8z9hP8k9EQEgkZnIhRTlrdSny5JIrAEgEIjlix/Yw2B9L4E/+bmt2iI/zAmuXPbv7BxXqM+s76uS6jCHumnCsoFOPdMZ3ouZcKc3BeFvBkC4rpyaXJ5adSgBGFKVODebJKydTDXkNITFjRICcm6jApU1JABDfjlWcy0ZGahnSqk6ouDyFZ6PhVq6IRWnvmpTZr0f5z2b2cqR/2Rg8K34jyy+2pPVtMwCz1lFV50pqm/irG2cNcDJHiFOtt6Bl16yHCkM9+9NGVkxNns24jYKinJFwAKpwPNv0aC16ncUVhIFkLBRjMAsbwiP8/kmBUfVyXq7xFb7Vom7erajGir2IB1QGq104LLUFiq1x+PBYNvIy9F5E8rEyUov8OH9cef6E+KJapC5Jpm5aVmMDBvrNNU29u82l5PAk29+PMZhMpp401lSkcvqeMLyRQi+FzHYVcC/Ybj14hggekhXxElP5C/PAgBoDmKEHJ9x3xfBVCCChdpT0NycQ4qHMI2hx5jdP3pziiHiD3KgxHVo4Dalj5oopEKKeOCIkS8ubWLa8YSdqtKYIGs+Fq5LSfJyxunYS4RGJ77y3KlIFA71NOIA5q6myHSn3bNApjDH6woRD1yAAJ17gYR8VUUZjk8iacciaUiEjcloNKJPlj4rm3Cn2/kt1mNCbRm6rWDkW1a50ldBU1AKRjbLyC8K6UrSA3ayLL+WGccajbA13P6bTYjKhuiKhR8uhTu69CyZcmTmApLBZdY0XBUadBdzBEfooiMLoG8CJIjggXsWePN5isQhlOsrBBkm3PKeKyIP0r5qSGLqQOHk/gXAOc4CMhT2YBdAO332ljKVZtX0gQD+R+PSlDwLxmISIpI+pPlFYGDx2QMU3qZ06VcAH+ITKozcIsZHGjMZ0qQvPGiKLzxMT3QRIByUzS+nbq+4IXh61KbIKkO8x+RppJPJ5DD1FVpZJHJA9TTXGJFEzgK1+wAkHdElEG+fUJ1jweSouur0ehHEk8pPiYTmJtyGjGBb2/0tC2lt08+ulULlzGbYd8J5p4uOiX1ZHD/6VEBRzRFTLGZiDhmyrTaQ9wJK4uY5UgUhSbEXsEfAqhD3f7lpdqpT+Fhwyo+z7+r25GC4LbYGu5Md4YjJPncPHL69xfe3Hw/dgbO9u11wIx2uuge9QGVQGnnzuXAhNZZvA4maAJycrey5edmZSOIq8x4jL0LccGcB2NK8gPI2kfxyFbJZmEZxn72F2/7Ki0VXZY6OCArf6O4syIbhdmUSc5n3hFKweIlOABCJ3zA9ecVqNmLi5EgFxni43TEnUy3zlLaqOYIFCnDRYnN507P7xKe60oDfZfT2Bei7s0DOOJIYRQ+KnBM5JKtmkNCG4ofoO4DdYqLtNXmiyfW+CFNskziwThrVJgrSnpYzxemO1Eq2vapVhS95V9tthC/TOQexkLsSPR3HCGX77E2YMEqY18/JY+l0SjnV4GJfhilstoQ2BDoWQtpTL5hC5iSaFUmbFwLOEyRLpiwekqVR8hO12egYXiFMlZcol9imrYX8Pc/1mR/C+QFqFg2WO8XXTf02CicTn49tIuzzkPAkZzJTi0GkccQRXlelOJCE3fCtEImp1XHmPX4uyWiIXCq5A9JUpj/hAcxhjC+FALyrKaWIksfspM+cDK7CyM+daPk3pHLgzULuXe6EHyd3Qv5xjLMzJtqVy5cfW56RVgcJ4GV2IZYZNj7t6Hq/hcHnncPDF4PB4eHh4dNg8H44fPnLfHCw//Lj099mbvzfH5xKB349JC8RF8IixnxAzpjlVoxk7Er2qF17hD0aWEEaqz9I1NnIFQn3rEaR4rjuQfJqKCzcfOr6RiNIWYfRTqdTqId41CUlQbumihUNw0Mbv2nLE9tqe8i/btu1mauFmXL106xlA7ICCByFl0i7BnK1rrsdq7TZrqlyVVDtrbTqcmOqJS/ISi21gUYly0K1M7LkBCFS1ut7vV1NXQNZnbp629WV5UFHqZlcu5qyPNTMeFHLqrJCSXEpP9eDyR2f/CJpD0m1L+UG0CToFhmCQdryES9s6k82JgZ3aT0L+0VpanJ5iQnKmy8Wgkeo7oSGQF1xx9LuWNodS7tFlrZ5xvQt8SO7qYZ4EHtNXdRZDC692AOpzbQXBL28JcEspQwGFa+nFLQaPR5wf5l4TgzGwhEaoNq8oGwzOYLKDL5rTIaLqlJtPrRqE3pam4CDYrJ0vRz8lLtMZZ8vbgqHKKx6/VRBAmNU6xDhNVVvQYZVSNBq8uvMeOz5PqTvwc9H4G4yWoSePTyUHPSYrMKwCoUNYBUVdA+Gl4WIvNDtYgJuTtDncwEplek5DVZTaAbntohCN3WSOKciqAwanYaQ290XGED7FKK0696+h9E0xLy2soKM60ZzEuiZsrFa10or0bwg2dsxib07wP+BL9CcT8V7EXu/e8FU7r3aMR1DBaZqZLrimw9qa5eG5Ifcfcp9HjheMP2vVERePZVehdxlugJ7/uaE/YNqbWJQkk6oL6fX7immSFdpHWqH9hpqSfUhQ1LLBOu69gaGuCPpBlvklTf3EmMlDyGBcn1+h/dgMVT1svXkVHNTmw3uR0iXHKVz3PanMs98VD+4E1lH7vwkq7WBge3rUxAnkeDz116QJiL+6IkGkp1g8YwHzKkiu8Sam9h1Q7mmtrP4IfA+M427x+6LRejMwLgTBm78IMP/h/R0ZDq52Vj2DrZ3h3s7OB4wbYoo/vnje8Hd2q3/C5VkP39ExfomNvq2XC05iDbcSo1ig2xqSJvmuvE6Mp0DC5q8hAcuj0xPYna5gy452hRv3D35K0t3h5dXs7du5giVH8Qrqaul77tMzBcJJiOWDj3rOjVXC2bXBY8o+3iMlDncV6LDRkejJIrrnFtVQV6ATmA4VfKCTbOOmwpzpmxquJUCzk19IpvzS1f7eUmaaYcvm2SGX613BEhgVlU3tcH/3Nv5CA83p00dMXAZhKOOE6kbS57yeevvhj0P63dkO9dD206scxoxNh/gsGPym6x8g9FiRU8Sy9BI7Fjl9SIlj+bHS/Ox+SZlnm9O5LFd87ll29gtn1vau0v+i17yX+dyrzr+39rdfomhZt7vtxrXkHWyTlyDvbZe9+8kgKSW0N9s6EPzyrUOfWhYxtK8JdVBDtm0ONLGL0l2j39tfNU3G1B8q8erBr++KEAWkwRcf9F1u5WzSkaanhe44nNP3hdt9O9gtO1k6evl18seWb061J4s1vbYmJWUJwtaPA0qtl1qasus2tIkV2zCCjsk7VdyfrUUbRtjmZG0vpzrzcHXqUX4cYkYWU2KiI08Z9U2ZC1wf4OYgkYfiGJ9WatIT2NoemSfSubzgoS6EA68dAh7NpOvZUwIvYeMqBoMlQjY8cnb/b3BVg2ObDNi2rC3tdXbIsS03Sc7O/2dneHg4HHZfddu/dvchq51W25NINXKt0OhGxxU21lU4dyrsjksfmoFyy0QV8Lmqo6Y4ofoJQ2tWJ/j0pSsP9BumYr7V5iPVetvrA7h+aGtOCS9iOD9HM51JPxIVbdG8hQdR83xdQ0yWjllaXXaskwVRnHc6IZiiACyTg/xwArbhaIv1t4uN1sWDF+beQ6l88Wu2VzCY0tIhC+0Yp9aEeWrrdI3G0hVL8m0ZCF5f7gkBE9//b7R57ZdjqVKCaAkZK1zixcb+WQhgdw89HHcGy97nrsC/7VZ6Q61oz61aug8MXqFusziQ+kkeYGL2OsYAklg9clsXV1INkv6rWdsyXxU4+7WcMsd729t7+7wnYGzx4XrbE/EFnfE7pazewCX6cFAjHcOnOHW4PHO/h4fuxP38b6z91js727vbA86n4r7v46y7cVNe1wBxOHCVxpikdo33ij+0sKOLD42O0NEa7GtoNJcWRaw0C0GKF0JjFkyBrCIQviDotxoOHnM2M0tZ3viXw6/KlcsyYcNDMf4TlG9hViAEUdezOZLJj/MarXhiVUs6Dt597R8t9QMoWFVshiorE6e/dceusd7+3h1eXMQLbd2IZXM3Avkn+2WaCqSL8qwI6CbuPzxWbaNsFX2lwKPjDGyi815AlF5U+a5tfaG4qrckDomelbJqArvrnjBHZPpGS+agnbskvtpfTxvPkSNEK2qDbk0u04czhU77iHOrzlkHoSgeOuhf7P+C0cCSpw0TsK5wHpPdvDWUoP8+6C/vzXsDvp7w63uoD/c2/oEohL2KBtp1SWsXY/bexxu7W7lqZj9Dq0aYznYg1E83oV/92AsNlYDxqkV7qFNsVV9I39YnIbPeSJQK7CSTiKLUYcraQxbHdUT2WW/Of3ETm/wuDcc2vQT9Zj3lQ/ybPav5RSaz0Nre0L+4leL/swuw1VdKIqTSDQQsnq3uVTQdW1gfUVaN2AsouTmomh+Gs1CKfXbJJXiBWlbwptKqk1juWWJVFL9W5BB4bbX99yNt8Gb0v6NEL7FcNvQfTREPoBCOY3iMDr6vPBI7jw1M0BXoD5QHSagkoitTGgtHrTbG+z3toanw8GT7eGT3WF/Z+9ga2fnYNfChjATw2mUBoQdWmdbigQDZ405QHwokmUB4mOxDAO3im5VFvduJxCfk2dICIsjEhFISalQtDra3fKmiNMPp/z5f+++e/HBe38lPjpO8PsyOQge78bpm3fjX1++i2eXz35Pxe785W/Jb49fieS3y9/93/mB+Om3wcGBjVoYoV7BIItoA4pKrRki+frIai24Bh75DXECPF1QlQ5fPubEiM5/Jv8wt002ZpvkkL2MWqq6I89RCiqH+07qc/TCd704gfCsOpW3E8ZegCcidXzPlQg8YdKTESlVmm+r0t9yzxpJ8+i3nlrVNq1mtq06SlCpShVd9ZD+X2fyaMy592g8Fb14zn2/J4Le5VZ/16BQbaHcl5AYseo7n0dT88twIQLuPUrE56RHcH1eMO1xl/cGgyFaNIGBPMKvevPUTzzw4AVM/Mthf9B2Vaz6wRbq8w1aFOXHtn0O8TXL9m9ayh5oe9ZqHb5MMCg+Q6+5/EY+hKawQPBIxPDTm87G5B8MXNHmGqe3yR+dGY9Hl9q38d8Cw8cAna/At3rh8wQRcp50ApFMfO+zJAXcka+NF0nFfRHK6zRvlOBxHDoevr3x3Ulwi2EMk5AsxOqnlcfQ0uP4qB99bUZBL57NjSEJFz/bNZ3ZFVBcIZk3MjAluDJoyq7R267eafa+JBrLpZHaUQGTqc0C/ckbtDCaFl7O6r1sPo4H/d2u/K/kKyLHWndAbkeAL4lxUrtDBCrfu6B/gLegbQOVtCRUsrLNr6cosTkKOWFUkYYVv8q/MCCUMoxcicWlbxrAgJH3rbySSxt2Ha1LabhlLYxV9qetg6+QO/ZqMrYg1PPp0soJN5uhjMtdk/9aML2CMCgEq2tDPMqB3Pc7n+748/fMn1d66t+x6LVY9Gq67R+RoaeLO23el9fmSap/XW0eahrWd/uRFY/xzqlbjdJtmDW0go1rVVe9ql6XX81Tb7URre32VTr1OaGotGx/z9E2m3h+ZmSAC9I5eoKjQ5FZSw/bVitOInutTGawVYNvZb1P+Y17y6jBVcfHyvhTK8YkLDePl4GT2btggvSbEVaHvBJBXWM7DGUxvanptVaR1TMbPoFOr+rluCnv5aIrhfFdnsplplnj9ieDST+S9FSrdc6ZjHuruQTu7VgQv2p0tS08J252i5TSIiMNUz/oxYAPLKJiVNamc0Lm+lorTKeqgduNJmzK0LieG92qeMa1z5gNARo393EzROPa9m8J0rihz0HW68Ie05t/ZmJRnJe2BsEZowj71E9Yng1byIhR1ysmjao7phuNUv0xjuiGqfvthqa2Wa720alVrX2VANUWeBkbi1A1Jz4Ofd7jMbyuQG678AKL3HaI35MOiAfs5enpO0bpGRFakHmx4rWcYuq7TPSnfUydQFXl4PTiDz9/ViXJkwATkTC583Sxnc+fH+2qov2ygSxDcl/loOKcZ0my6NEketh8Rz8FLNZT+dyBSjIx5YhmPKK6pdXAFrrmCD9Z3PbKwxqH7rLGCxJJr/EmoDAlkhFXQB3Xg7JzuO1IqzfniwXMAOCACZ6wLXly4+hRZUgChqNYqw2s2+0EAGQaprDN1msnCJMeNdDtgNl23XawbulF2sETcN06oKT1YBtDSlotwU1bkZO+WSO4ktd2VmIbdGkXP4V9C6l/MN/ZOIWcLCjaoF6do1/jh9MXvf0+e8+vCC2wy8Csv7fTEwHwnBaQOPBshHmVD/R1t6MYXdVJp5EjdK7pZFRg0cVTj612s57N2m3oReernlw8lumh/nry9s0tUwHH86WJkJ2ZstgdEs+Du1MRpJkETbPMWFKJjWPVNoMmTtRy5XBvM6iCmx+S1XyxJcWB3v6SOpHA1zj3e1Ho27KCqsc66fqgEEgP9A6kKGzu0mMHM/OxrEXMpzYNL0UUxNJxL4REX+fhVSAizLiWC+nGj7vsnCcJdy6gBE8SwE6i5E4kmajSVjuiIh62BNZC2VLz5GNhQ8B6lp9LJCYiEoEjJCIxe/r21SGDJmnqsnGwu+HUzgI11awnquqLqZd4cyNtZKzzjGbzPwvMekADogew4TSZoVLFlYRphYSsyNE00ePnmbZP1mlW4gEIPNJ9hdbza9+ij8KGb7nQZSGynLcKPoandFFqtlrjCyYD/rnc4GsKZmL3vcDxU0iI+yAnjEvDTRHbKjMW6Wiovd3d7V0jHAqRkT3LBfSaStxKlwXCzzFLHkzcTvG5SGah5WZA6tKXdQf4p6PTTrfz/OjV0elRp9t5d3j67CX8fHsCn7/7cFrRbZgmTmizWLylL4AEPGD6IQXM6OIc08bFUrktv2EL+NXtQjZIz7cXmWAKoy7klHRCRXKzqGIIDqYMhvtDgAEUjn2upVpedgGnADIrgR9E1k8FBSKxCCMrmCEyK6ggIj72fC9Z4vgY1eiySxGBj4qMTZ2kCbzwxGXop4UhVpyCrOfVhFaq17vcokc9/DGi0iM5pPJsPtIXekdjLUa16oh5uVWWHexdqqHUkrkXp/M5jywput5eQloHX4+MyjUT8VJErudY1k81KAtou29pPftNsEWluag+y54c9HktBS63qldnS42yfuu1QM2sIvMJfYHH2oecj2JBFym4vGC24JWpUVhZkMDseNcKVTHJMlJiwHeUrh/QXRpNQlkpSjokGpwam32FEmHLZfSeFMJAMYVvCgWbF2ERiYmPqU2qcC8xmYckBag7KHUzLAoTn4VT5CMbIE0vg7/EtbfsENwS2erQQG7gE2EfB/TeIWtuxQH+aB5cSDacp/1mj6wiR/XGyJSJVXpEhPFAuikhn08h600iWa58LbWHjK6N8S8kL7EE+esBd0ER6UtL85UaoTMTzoUNasZ4bOW7/Bnc4uAcmNfwautQ0MiCCDwGy5gt1Omt/Ib8EBkmSVWoOZlMoYhtlc9Kquw28k5J0lhtiqqLOrt3V7089eyzodVswfz7q/HdoDcj5pBt3G42z4bj54oi+Wdqq9eN/YH8Hl7ElY2uRuvia9xiHpfDqKGqzsdkYc5Ew9BxUszm4aaYI5m3vAFWOcCEJ28UsR5MAqy3Z0V6k84FRGoJnSJK523WLiY+j2ONtNxl3iSzv9ajT6dekGxD4FD2xLF5GtY6etjJb/ijWG0CpDjJMdZmyoMSy3aVU2PwLU0+sIqYJbaR7bPRWgdvjQuycNavu52Z4K6IMIGc5d4GNT8uLRXLIeqIIKm7vgu7jHxn27xGV5uWbBSgyiNL2tujz9xJSBYF3P8P71/Jdzl6zs7COOlixqSl4RXwICO19rSoZ02RR161kQcLPHL4Ap5tFnp+lEWYKmL4cujExiA0bE4wUqPqyS7LcqwkIVGwtC0LW8Q2zdpz2M44Z1C8raLafhrLNr/V91TerHiTQ2KZTYuDQtqiirkZqqTVFVbSGmvXv5vNQ4k8JzczDVgGUOXXXnwz0dRKmwoXs2YfoWRfnRsCXzdoUW93h2pJzOZZrL8zFnIlyXsTT5nsYXB93a3McaDfepIEYO5LIa0khJzA4Od8qeR0xscI3AGu6wEMhIDuPOHXowHd6D24xj3c/g5d6wpUIyLflfWY060PUbGewukxtq39rJSYveXIqDJgypDFMuysEuesP0dg8hwBsFa5I7DOvePJrBR4B3xE9is9X87POv/W99yzzrlVPA2s3u/6KoWvs4aULWNU1Z4dizubSAVhqxQKh0oXWFJio25N66+veAQv5VIBVyTkzePFcQqGe6sam86/oc4x9dq4eJHghO0FinV4WYB6Ww2tSbEtB9eo25aQu0gR+GwFyPecULEGXylaCa8JjQBc8izv7oUIwHWMmmOumHiBR8aCMHMsSwMX3MzgwjANh2eBtBx6BAjqxQ5YT5kIXJkgBcRJJwziJEqdRJsOc7a/bPdCq6MmVymYItmZAXEhGYng0ovCYC6CZFQVG0BFmVEUhquUz6tZ8OzdmoM3yF0UES3MSG4U8yXddqf4oaMRH1pvEaMjXR/TqdLvIzsLAcFNKQ1IHmH4xg0vPMGuEAunoE/wYjLFzoRrW24zQOBQ2ob1YOxjKDzYoVB9wM6hO/cC3L+YP1sG89m3iDFyUnfdRzYpK3dZLPlyEl6I4EGf/RJ5ieiFgb/snwVvBOx6Ey5JXQ7WrZ5L5gwRrhE7+vXw9btXR6PTtz8fvQE2A83nwdBiAIHDDNhWcVFyZ72mxSVVs2+xAQFSpPUm3NBavSM4GiAxerJmfgT2e6hqGkVeW9ITALPnLBBXNlMUMrdzfZTPWc7z8SyIBQRzGHcSSggBPZu9hN6oME6MLQI/HCk04i6odaMEttby/NovlrLLYcaSrlcQruo6sBUkhtgzGOLaIU7FqymhxF+1SjlzE70G2X2R7SRjTFVBx5vdun+D8H99N63ElyUZabnsZ1u2atv68rDYhC6DsymGDLcfJZiTrjxSr4oNAtQjnAPTmYedI/NAF6grzflw1wcteV8racd6g7/jGHpT8NOqT8BYDNezhy7XKhJv3sGPeT/XJxLZ6JXdIp8CEr+8ibqN92HNKeqZC1eKuKglJez/ME2moZklve5RQYuFPpCwVpXAXxUjldrw1Q1LzzZ9mm5fDmi7G+zLK5Hk5Y1WmY1TB86oNych3suwtJsa8SSef8unR7sJl2aK2Tvr5qgyjmoNhgguhR8uyCuWcXYOV+W5mjN7qyKm47NA+krAIgnA2pHhemNySJbQNQbkZZs74E8VVFcXB1aSUBpCZBsUyKvE67UL+t5sruMWrK4NwkDRid019QeGtl+j81O0qhs6KUiGdCdIk1hJJ6EDDS3fkfqsmf+iLoQIW9SwlZFFXZGtUzm2q9shnINjmrwkWQE2wSTgAkCAKrQLBUlxsfDBa56DfQ8vBoIt6DN4h0ogzvDSc0Exia8aiZjwFxbOvSTJPo7EHATxNKDvWxiofkxJ6dvQZOR0FezrqCoad2VB5fDt7Mwvod6wU6f+Xf3FKHQWnAWoFTF6PKfSLE4X4HsK+pBIkLlTxE/Ogh57+FC2+/DhE+YLfimyJul7kjHga8cXPCpmypGFzminn3WwpEQBhqJT71IEEhS8hYixuqKBvQXEQ4A+zI++q0ZBEzgLwDYEM8CIY0llcFXFoSFoMS1Fw+n6cXQXxe0MP9d7pJyACH7zp0lViMHHnAJQer5L2dZlfJJI0Q9fAsoMHEsLyIwvYMMuRODGLAyygjDCPnsncz+gngTjE7zAi2dS9rfG6NzMHConWTSjWIwhEpfL7olfb3ax07fKCUOBpvjeRDhLx9cOEfL6bepT5pNF48pMuKmPvy98UlKBZ2GqflPUlaEnED5oH+sNrUbodISRAGkQKy+HTb3kqkaXNy5JapckvfJ9cQv6V8ng0Hrqup4sIJXdG1XOWlelvCLfouLibwQCW739NqYYNjVdVdphs35TtOwzP0zdiQ9pLcAan5lJ2YcYxYtzi1mkfxbIk+4rpFGEWsrEA2SC57+HgTiXp6qFRQSKtyIQFJTSksUIouwfpdVYgcEWesh9J7Hd2rywXqQUYOVzR8DmhVtCigu+X3Yvunsr/SnfShsy65b3Ze0bazN781sxBsvJr/KEKhHgFt4Uf5IHwErGS5O3NsorTc5BeGdAF/DLKOFTi1CaXXFQiCWczJ30l8wD7ocZWDSgR6dB0nTi3X2xP3H40HUGk/2DvYn72BnvOOPBYHtrzIc7B0XlZwWwkx44zOKKT3pzHvCpcHtR6ot4xH0/vBLuaA6B/uXJPQf3LXmXZ+7I9C7PMAxSX7BpFKZru86XxwXjKaT3RGYVTiYgiZcQPBtmRn+NkogrGbPtXLG6nqojXyC/HL7AaW92wpZRbpIEQTjnvsVvf62JM6UiAlQOalk6VMLRV8XW9m6uIpCcwwbJ4opg2X5jKGTORRjHHpCJO+SvLqUaNXGQZgLmJYjxEnnTKfiFb5gYpZHnqaISKKBUjKy+24m9OST7gl/HfuiAA6oz474vAjIOtKEeLcEI/rJauIJswt26rYGvvMgbA9YibiIWyhB/0P7xRELvZwkdoI1o7gUCXcC1B7uHLcWei673c+57jhemcZ/9d5gy0rRQNisSLgkpFNqmILpIxLPQB7feKEynFI16TwlRXrK8p9G8zTVecOeCT62Ba6X3VD5QdBF5YeQhynee+XY7czLWICtFTD7sA17sYLfxEhJHKyl6E8Dn8jrLb/LQz2pwDa2lAVzSroKUiMRktLs9dPfHB4/39necg8H20HW398Zc7HPHdcV4stvRT/TVhgn/jrKSPTXsfO4Ig5Qr91BoSS3fyu3omtfFlV+5KTtjv5Y76Ias9dp+7G8XhNoyqDUs8vWtVJrlFYO/+hKw1Ctub6Py2kCqjau5SaziH3Ylb5X63yyWcfvlbA1oXN/k5lGNN7YpNopu3LAtKLry7lCu4P2UIeEWLV95EgKsbEUJ5UezyWUFONiyW9GdbPZtymblPDu2Na2fVO0LspxXRmG42dQoNsWQ2Hv8WOzub+0f7O+6463h/q47EPuD4XB3MtgTu+284spzku/F0dwKRmJOQZaUb99HcwmtyLVKJBusemUqhdq6T1FLdJ9tBjUKVDUB8AAIyI7nXQoFTAfjRySl/EowN6wAWtUz/InKidibBhQJsYhCeJrpmPXjd2DbhEBcIePa0R6mnrkIe7pceMAOl1mCTA4eIuz58/BEQpDGFpN+kUjtVlrziZX00audqAJrWudwN3KOeejC7+5IlZfpSVZ+/ZRbMRTiq7WGtTbK1W40udyc7C+7GzEuXqENsRwUPtzlB/yxOHAGAz5xtibjoRgMd3Z3tw7cx8Pd8bp865aThlXopmtJhQpyk6/HKjcYmf0K7J6h1uw8DM67Rg1ZjvgQcAydlX3si0dpXMB4suSSRX2TjjY3lKQtCWtXSdt1fsqJTU9CaYxJG2omZEXVqMSBVUBWUpmXUysbnbL7OI4HVsWyZa9tZOZt9OV498mSch0rKZHphtehRjsl+y3RYjUlOckFdNVVE2AhIriGiQCZjrxyB8AYWm+AktyxhjK8NX2sl1A1eYzsYnjQZUqa7LAj4WbgJToWImCqBw0V4kVaBNM8oWAPtuTUMjjDYF3JwW4kzk3OcPFoK9G+i0IQQNjLMBBL9i4kLfo64zNfANVjDCPwPPFM/ElAy7303JT72S71Yg2WqtYIQ7JrZ7XeuDeRus6cYfKF0tiZfTpfKKVdxVG6tfR2ZbpuPNWdXTBTFrZ2GX4aLHVNuXTK1Q3mS/x/A+2QNEEN2YWrFjqD9Z7XFpO9hRVNDrYPXLE9Fvs7Ym9PPN59zF3Hdcb7jw8G+4OhJeRszQMP00QmMtLy551V5atYVSwq5xta59WepXf2SlklG3SJtm1zpym+cZzsN6o5xtW+Yw8/Gnug6+/W9skdP/iR+cFaL0z5usypZIovGFtK5E08GdVlqMxgq20TrFXbbiulPwaspmPfc2yJFdqJhif/9Yp5wW9S+SLxIBWw4cnRq6Nnp6T4m8vUczejV6WSvipeJ+9mJn3JzC3z6U7B/4Mr+DfrWHYzh7Iqc8MqD7pctK7M2FOd4mrDuCGtX7KNTrCmGtNwf+VpTC6pEy8SV+j4GjJvPheuxxMBcGiQLScwFTaYW9bVHwIfz2sA2WHA7uHY7hmq1lyj8GWuTURdC1mIV6xSSZKGehGFcFmR6/L6jq0503JLP9fTGu3/nafrd+JNsWlPV1t8xE18XsvttfP/sOvGbpURpIs6VpDjAqb+vc8O2T0YYhU/oHeDq6KTalsHzP1UBz2Q48d9EH8k7+2ye2hJuffge2AqeYPSHU/5c/IUWxRN0RVqVcnYqH0zBlUeXBV/koGePXAiHaeB64sv4bJv6XVd9UBDU81KmBJZvoKH8Ibdxtsvam94t6xfBG7xdpdz04EYX2Ehf8xzhjEa3/sZ+/HOymbCZrYGW4OBGTfzIbgIwqtAZl7EbJEgvi98wUFSj5bk27tGKM0Kq75SPM2qbPYHDqpZbeesdqhte2eQ3zsAQwMiL4GqMJmP68+7UW7MWL72Btm+4QbZPshvEMTuDRAnPcLkRuYOkTi8f6YN8v1yks1bWr+G4L1RY+cPKPzRKn/3wt8XW+fvQJJ00jgJ5z3tSl9jgWJUFr36wwm47EegnXsE2QWvwsg1ciyiy/ocsJbZK8EvhMuMpBjPZsK5AOTCtikf1lh3PZ8e5WtXY6yenlDRJoCCmSWLBJDhGJyiaToqLEHPGdO9qiCFWlOcH4YX6WKEOR7p6/uzJFn0VWXMdRnxqy4768TCiURy1nlQgXWpaF9v5m8/HdXeLU0Hmq+azHXj3lQgx1Xb8hlApAYJO5EpltQ+zaZ9ixvNGKPeaks/5JtoT7XUkkY9G66rxSH4+HmW5bsd7YzIte3dAR/s7jic7+8MnIOxcNz9A2d7vDMZbB1g5Noak85rxlegTIMXPk7FkVMUn5NIhuMUk8EmIWUu1WVpl2hvoY0fiInni+rTXU+AJFx4TvMN7POxsAQnfaA9gN+aCL/sNcDzydA8QpUF00DkwDPfFwl477P7/F///J/fH3SZ600h/uP+4F///J+DB100cc2Wi5kIGoKRAG/SS3oOj9w473swHOTehUOMRZAzLa5xyW0JSzKHJ2IaRsvCZIb/+uf/7A7Yh9MXvX02XhLOOCQQBGYXLJnPg2kKcRIAQE24uphcGTLQIhxzvOAOJMUlv7C4yxZp4CQpvmpp7vFyPg59aJeP4y7zAZlrHAl+EUM7l9z3XJnMHLMZBpceQaZR8DUGuzkzDtsTyAwRjkGYMGmdaUNRBhRVAyzB49BeUARtlgawnEXlXMKM1OWK6OR48nKr4kkIvcNjdiKcFAxY9PdiEetzp6/tm+DDNR2da9x38nk5HNRx15wYsSpvlfwnN6ds3bb2+dbOmE843xfjLXcy2HHE3v62cLb2ncd7u1aU69tjriu7IG3a7aith2CdjH97Uc+WXjMdiUWC/p4fR+sfr4wEP8jjt3KN/3Q25LU4j21b/JCW6OI+QRn1bous9tz54QzaxV3RVqr6tjfDDaWv7xO0sG51Y4EC/J9xYfXUf7g11WmX/mwrShP/Mdfz+zdcrL2iveEXz8a74bU02WwhQ6NNoyACkCMwj5XMjAZfcUxF0awOptqWJ78ilLVPT3WrvcULvVUQrk4DUZUALgfiIsHijYlWWV1uMPXnCnM+O/phhHqqShMPKLJke222z0rGAfNI18OPSZIUVd3NpFDRcvVd+DxOJDCRdHSBBDns/vHJW7a/N9h6oJSUJV07Da5ekzIcDHd6W8PeYHg6OHiy+/jJcLu/tTsY7h78rUJ7XJGTyUKVcFJHFMtg1N5Ycakw8UqTAq1wVDagVMIBecA0ojCcj7KkeiNEgrYcKszomkHZKIigX6gV9j4M5+zQveQBJLGM07GR0vQwS9k3C+MEjWmg613wBMwK8zGA/yjLqAJb8mImR8hgiDoshCPul4vJcyLUS4PubY4fQiEXtb0SUkwErtph0Bll3Kkdg0rFo5SWGO+CnbiYkooiVcyR1SYvyR8a6LlM2dyY2lOA3Q9CPeH4QWFuahqUg9dD8FI3hCS7XVgd9SvkVSNVrK553wP7NfR6cvKKopY5P5En1YtpM7J35OTohsjlyB4gZHrNmYBmwMDz5NEj6AJ+jZ88evSgfhPHs3Ax7Mu/+044rzjFsGZlMp6IJNYrbaKlwcyArnRC8aMcXWGLnhY/VMRWlxbekHCPpGNoP2Y8ZlfC9/vsGPcXQLVC6pCrML85dI5WIK2s3C2PQR2nOYw1XggHOKaaCY3EmYWxCPrsF7XkuCf/kYpoaaBIaQOJttbU0/wREv2RA5dSmCY5YMhHVQlEC54gRWZy2wElWVfrCZX2+l9UACxBj6yF5Xb6hfDbnn0hzLY3XwCn7fR2sNlUrwu1Bcs8PlsnwofDosqMDsJhJOS4wI2oAXMDTHMrvCI+1Z/RzQaU3M75rHYprdOMFk7lDV5etcTb5PP5B2Bvm92Z33DWk+a1WsGretV9/6P42lcs/qb9pr8uWzLhosqetPWes7fBxCid8ognMrmezVVFxfPHKvlyVlqfmpwYS8VAnEZ9jxMtFyAhyNpxEkbolQg+j/di9dSWN6DZELxRnBnI2P9IRSogj6KXtHJWBDk79hKbEJPNBro74XNx4iXGnJSobp3RR9AcsHOeJuG5FsmTiAexj0IQQHn7/PM5PHfOA0w57oqFCNBJypuwhw8P/Su+jCGjOXt5evru5OFDQynWZ2/CRGUxBDgIeoFdUq/YXlcmOYcoM2PQoJwI8amnEMUDyB993oCynyZhTtaXHyggbPmnzz/DRqbE8tCMk1RBXtPAmsleHH8boiPlzhF92cGcshozvNScWhoghtxYJyLpPaMdSNnEu4pG7VvMSExuauZGQLrbaq60ATaxXEQoWDGYnn2liq81yQfidDLxPlsUyAuYAxzae6N77H8bnu5YQeGBSEWLkeXYVAzd0wwENAz3RyNnMjLG8AAf0ee5kZwDbc46fOy4Zx0JkJ81oZf5vNjWCGqcSw6E+cOhIcUtmdZtnJdUXk0nZuy4uSWodFA1aAuZW4RGfannXFy/ktteQwjLwbX7yEpIJIVWCgAkhqJ7pWZUPXQUU37Eq7eSVS1edXK2ueZLNxtuUHyJjWbJ3OLoewNdJu4r0AeyRMwXwPsZ9MHAa9lIQjuGp1xAuWaVLtKdCtzoQciKQ4QWF5T43u3mkidZlVLgmE06Kz0IL86weED3x52ZYPe15k191J96ySwd973wEXugdKhwXGOBhhJ2ySMPiGKkIJJZJ4TLxktS1menHCb15CzY6rM//jiHsZ56c/EzREWfX1+zQ/AT970LSGMkhRd5pWHjJveFJAYzfunBUoQs4RcyNzK0yRJvjjNEx1+1bF1cN0idBOtEpVFaAOQWKP3wIRzJhw/7Z8EwN74X5FksXBjjUZx4c5xd1pXaECCn9NkLE7loAtmg5l6Qoqv0oY9BmpAiyl922VKmEk5jIMp2rlPoK9NvyBbgV5EfAJnisOezYCfXxMswjeJ8OzP4qLYVdv/8Nai+J34YRvdVU4/2Bg/OH/TPgt1SD69paPbx8nF4SSrUwqjkut7XH//73gA72MMOcGGO4xep70PDz2Y8mFLyDrVKtIBByOaQznkhwoWPwg1qvF1XaOgpbKp/FpwFpyG79ASh1E1S39eaKL2JuwwiD9QJPHcm8ojDCT+XkQwS6nMsXJbCiaWiGKqgvV8lXzvPkjxDIAA+ovJMQ76mGgxXf/zxv3Jn5fqa/fGH+uT6Gqgdsz/+eFQu9P8VP/ovlI9hxytNdbneqteWQiZSzGWkogDsei0dIyAtLYp1od5OtaE4X2XbJRYYsHMR9D6cnLP7R8HU9+LZgzwDrDfHxb2jk9zEsTFDZtJ/65K950edbmcS9V68RxtO7/i00+38xnt/fdfpdi7C3s/w+SLpPYWfv896z97Qz9NfQObye29ewfd+7x389Nze8XMYY9Q7hfI86h39hFirvfcfoB/eO4bPx9PeU/h8FvVewt9O3HsG9kuX957/DOW83otjkMWT3isYj3/Ze/URnnhx7/V/Q7/j3pu30G7Yew8/hd/7CdqZid4xjGPm9Y5hnLO09xL6jaPe00P4edE7gfZjv3cC7ceXvROYf+L33r2En7PeKfxML3ofoPyl1/v4pjrhjbl9aqB2D4GJS/5vsEtMXeS6dPhdkXDPR2aTJqXXQWOSGDCxgiWvx56/ZW/enrLXb58fv/jvlU8BZQAaxSRmjCIRAOreRqWJ59RHzECAh1SDDpPdwGGSPUvBNyYpGUZ6Do8Qxh1H4PMa2TweDcwGpAbsKpw/xbyTkI2j8EqiCMIruc8OJwmyPJ7goVsa7SQhm4a5hPc5YQSxTWhMqAGCQemXfW7kmeVSzRJzGOJMSWIB4WNpCSWr1j3ppZR/N62m5I6jMPKmXgBgdnMeuDaPGX2LaH8VrMJUlTpzr+ItkbgMLzA7VHGnkllZBthUh3Po6f29KN3qi36EF6E7ApKbWiIAjpiiuaCRJropsl2AcH0pbtIgYF23kL+PJ/SSRrEY6tAOAV+dyHPLJtp7MTsvtmrcxVczEL69BOVynAPdNqnvl/rwgpmIoGhDxOIGr+gj7B2vN4FrBtN61PbmLmoR263BLfBgbLg18yWS35AFq7ngUKz76jtYwNUmWXPrNPLE1XoKxBUd9REYZOmOuMGpV80qAo3mIpmFbv0iRTxwK908qvtQcvmPYxto23qJDtD+7RsLrN02ey2g+ssdraYCghd4nPD5opQb4brbsfGA9WhXaml9DVqZ5V7rBJK2g7zegKsaBF0bFhSBi8RbvQtdU7cVJzxK1mzNqNsSb7jYAoFF6IQMG9w/7ZI5FMejkjlUscz1FtTaGqIf0y1zo0WwNXLd7Vi483qDLzaEFqD8u2P9xkstQeuzdDIBfXdibrM1dqe9HeShMdg6VlN7yzZ0Ve0IVBSm16OEpa2SBaeBdje/0jf6Omj9rF7nkVDR+CbfCpn4tZ5kbnLpglgeMOUXzzQTIyl9zqOLuOjR3EIgHw6GW73BQW+4f7r1+Mlg8GQwqHKNt3LhWuFtuPt4d288dCdiT2w/3ueDvfFge3u893iws7X9ePfxCh39gBLd6hhKtlvw+kvJdnbErEPlBq980yXIxdLYgIz0X/5ixoN0LiKANdF4LV0FfYNWc9Svxw55gUSiHYjLQj8qR1cC3PQjGnLr7VV1a9+c3dhavjmvIRsjPMoRakg5MxiHHvouM2XTOhEz7sdhwY80Y9Vz/tmbg6pquLXzeGd/e2/nMfq9yQ8BiXQ97lYhu6zI6CjXe8jGAhRv+skNT22cKRuLCSgpMhpidzHZRNUYKAYCvwELEAQsJDn7nWrmvCi3NrgCmFx1N+Oq61HMIpHdfGMWGr1lXZl+xa9HgR+P96/G57/wK/5WM8X+AL7Ld6EZd6EZNw7NuHk64CoucRPf+lxL36f67vtR292p634Mdd13qaa7FfXcnVrOpo7rdpI0CuLEy5xxV2+32EKu1XaZ4arbNPPsNq7pRt4fxVY3+QCxvGK3B8brdWvdd0j1Vi4RRBp8u/I5KgUF/fDUQQjUosvohQRqEumJWH5xsvd0qUvH23MLZzhXPrAwv8wVOY3FJPVRsow9Cb0r39BzEJlojDim30Il0yCR9YDlsDBIHT1gQVsDrgFXPMCgEjkTKDWnWPoYYh0m3IsCEcd99oYnKQCtLLuwtnN+Ib16KaBdBOReoEPwwTlfQBXpuItEKb1a3TRSKOw0YHi7IPh0GLkCv1NxQg8fTrxJ+PAhQhoIX/k44bCh3JwvCdUhECAu8WhpfRis7FZkuX7X0OqSkiKn12WHCdEJKnVJCeKaa2mmSEUROacfKuR7PtWd4PIqdAitFgkDpRUpKEWUrLGSSmR7NUVzjsMXQB3oK1hw0hYi3IekEHEmjHmSXnHZToGjMQ1C9L+HtLURnwCigqLcjAP6ipvPX1uIQTIJuLm9Yr+Gbs5ya/WBt6qJbNCCfjVdpO1a3gCdC63ejm5N+hH6IfzlBRMv8BJBUl2nFOu7OkGURLFJckCbt0qMcDJBYkiAeHRJxt9GQRiMMF8WdWR8I5PlrkOzerAeVkTrqcCPqQLrWRM/R4P8tAEvakbbaQG2Y5KkDgn9+Nbgz5tGZQ3V2KibtuF3LfV2sYpGKSy6vIUpzpSdH6KL9hPaBYSA9giGKyNHI+EIsEdw9teTt2+YmoMKTMHmQAsJ4UqY0SHQYUm14dMgEIWLRRhnUTNGbnao5zns5enrV6jokmzeOoQZtBSI7FgXY2ho+xMKl6wjc0soyW0Swr0Nf2E4ZkzhYudeYLbzhD2V8WEyKExGzarp4n1umeh9CnnVUUQPKNirEIpW17ojFaiiHAcmjZSQ11NFsDx8iJc9yJnoLa/TUah91ce4ryzq6wkEMXsuXaAo6hbGlotUY8d0LZrjtA+SQuIM335FKNxYOAULvfrsFxyCkrRfS0Ebx0CPFJoavSyUdKVGvDt4JyIHzrkvzik8TX833DW+s8y6tkuKqd4IYaQ4YYnmG+7+u8rNJR9ZEMEA6t2I7NkTHiciTtj94W4yA/22nI6Mk7OT4Zuc6u6g7VR3B4WpsmMV2QY5vMCAz/2JeprkXiEY//kZ3mPEZnwMuZf8RgZNXIkxxJnoR4WVhJQiB7opNjkWslXGMU7FSyiiULfz+JvfdY9b77rH5V332JhqFrX6hJ3gvcpcL174fKmGlXEdlTxHYBI2GT6HQ8Jx0I1mm7jmbpZuibXIPtnDh2mguR4G2e73WS7Os47rFsRI0kJgXhikrL+kgE5YIGSveI9ChUBcqe2XSAUDANn2z4ID1f1hTd+ZC4ES0OSWtt6i2Dvef6p0zR7vnwVbgz6ggMTJhwXgnFavVKYI4Hhzag0BCUzquMmLHlFUYQ3mi4QOGr+04BjCcBuGiOKjuk9JFROisobxgA696obO23kkJpGIZ3AOokvunwgnDFx4WcKQtHpCgSBS06T80anyWBKGLA4hHZSXRcebj/McyTK8DQeDhIGsIC9UjORJ1RnNTHoxFVVTynWWwlHLSRm1VLkZ8X8paboMtnQeCZCeSIkRyXB3BQUJKkSaPzGXf/3z/5ydjRQ5pQw0Fuzhw99FFOJp3Br2S/08wfXX/jSkZjPOHCZ8k0H+ebHhGN9xwkNqZLo2U2h4+BASP8pwQamIe/iQZkUjAsHIi18cv3iLoTOtGQSMCzYU1GT3X3hRnPSOgx798jZNHuiY8K0d7OI9Dmq9Tqiu5EhXuBTEMJBtczS2an0udLmLXb7L5r5evwbx5HTYz0IspIznGtBAZskMQEZKbXkpnt7vcB2Kz+AKYFyKwCXNyw6Bi7wYY53eZXFO+TJj4XCZIzMDw4U0eHH2MMI+pyFzvUg4sKtypwEotkeLhDtjPWLRrsqW/XFfj/0QVQDVF0CQKQizjR+CjA+ct0/BXlLyl6yAGBHjxVtLI1ZIPTU3jutCRF5IrrrIIAFEIoOcMV91eYwCpZhXhni7IaBrsSBIYKKC2lZdbG7opHBR0kMSJAE078OwcwTG6nGODE4YxJ6EMkHisrFIrgTxsljplaFzcE7Gq62r4HHhp6HFNwPoJIW8CVwLuD1jWMr9vnUbWmS7/ILnBbdVFt8cVM690NN+hWfBFogXMLcPcGNgxyfwXc3Aqk5RpVgZlOA2susp5+Z4FgwH9uG0EBJtk2glL1ZOKxMaa0fUJD8Ot0pzOgrcVVd+bdqCmQFGMbSNYmW6wshXoWpuLlUEzQ2kkZxw3Uq73WHSaseucJSUyFQ2fiKaUMnwqa18xY0MN7ZWIp8/YUfzRaKKq4+ZFwf3kgwrr7wCPCAYpoRPgWMrqkCHp7qVK8+dikTrXiHWGVfujz/+0F1dX1+fq1YIM4YcjijkXMMtZSZQWxeg7xM8wvmheCAV+DWXnZkxRl/fXmwC+UhCq8YMIJzDQAEUMefD+1cYyF20ZqU+CKhPoPhZ4qSRz3q/sp+OTtlZR6mXDWWw6U9w1mFnZ1DrLOm9ZGedKqXmWQcahz1dAZ5jShJolMv8INnMk+jt5rAR5kLNrCDZVD/vSThVrzfN8OXdVaDEHzSxs05Or3nWecLUN8lZJ6erhO/QgpB9n3tJ13wPX20NLF+YyjMoZCtjqkyqyjxu0Y7mIFDgrLM1UBzxrGOUNh7yUI5MnIWvD+3fGQ8s6mI4GA56g/3eYPt0uP1kZ+/JYNAfDAZ/y3Vof99BA8NBsWO94tQ+LHiuLeORYVmN3PvANoGyNG8vZUiw9gIGU60pYFyotlKWO7W4tHXXLpHIuBxylCrdL/VNmxdQfcOWi0dPjkpdw4/rb4Nl5DSCppT4PTGN3RZMw9pQkWts2VoqrPuuiSq0tfvd8xDaAXVcxHL+82ykxGZuh4uUuvk2mUhuEzVxkYoNVMFEgAImD7kNvKg5/2ziI3lzIT1b1ot9bpOHuxhX4trhWDJHRwpuyL3sR2lkwcW5NnDvLd/FYRo5LcKvFiE6WVjaKEUl4OizXjMgLN10CQjLklw8o9864al5DeYXj1JtsSvaRabqxEbZGzazguQgZ3PaZ0puQMhq1LQ09BNSJzmOuqCgASc43wsym1XWkdEJkEIa4yD0RzV5Ekonn0UYo8+NhtKW2bmY7yWJLwhWKozUnz7oUZVbnhPO8R1tjjznmqcKLoBpRIG0/nBpa+NRmErh4CqMfHddP7Pm9fqc1DjurxvoChQXnxPTIyof+fpFwlGNyd3OnLDVLzKVBU+c2R3s9g1gt7sdlXJh5WZ0xXWwu+9Su204tdsqmd0KSxEJQFf+AcOzC1KNnKeUnNp2bVb7EjAdhWHmDwgo/chWSe4pmKEhtwsxUhc8uUGFGUY88sihWzbbtJekM6oxoLjvistHsvqj7V0+2Xe2hr09d2+/t7M32O+N+XjcG+9u72zv8l3XnYxb7Dnc8hLeozk+9S6Y9BsPJr0L37wL37wL39xQ+Gb+DsFDYjmxJYZQvEeIxUq+3ZrJrspfy5y1qCAw2rUP0fikhRRvS2DddrDlygBVYMuP1nr6pcpZi1mmpRVbkxVvCKNgv/NqEj60bbi6kfVv1c3fp3U3aTVEfOujW9HEdVfn/m7bFJa/7nYqo1vaNmRvYI3beVP3cuWNLN9+rSVwKK9uW0j6s0rlrNLN7mvLTa0/ogCdkbMi/7fWv6EEYL3717mZN3gnb/423uw93O4GxnNacSisFLLcdtn2LQVk5jJa6eQfvp/TilI2rdhQo3KpRM3SIVIcf1kv/iZEbbLWxPKATUWSV8WGkGAryWXUg9AgdPnLRyTJ/pxwDkGIWVRUCxCuVS00jcB5WmtUdHiudnPGvFTk0QUabaV6YZMonGPxhw/lMB8+LDXrxeRStV6M4Xsx5ZGLWnEz2CZrvwtuV+d6P5wbvr8YHW9YrQ2PxgJERVkRJjNb6mQyeW9d0J7FwgyZkM7msSg6xMp8T7AVpR3WzGsD0BCki7tE57PC5FC5JSMDwZ3jnD18eF+S+sHDh09Y2es756JNUk3RTVtOGsEiVLxe5F0KV0YJktH3/InN6dveovJng0BQc72wXe6Tsy+FABpu2udPIOunoiB8YXhHV+bXCdzqUIJD8oIGTVEXcdGM+E7fm3vKD1uursTNgODGmacAOMzss2gYUvEAlHRNWYcg01CW5k561/GxTx7P+WhMjFg913fE+QMWh9J6FHB/mXgOaTGBrUL4q1RjZjgDql9vQvAj4DAJ7AxMcMT2JJ8KwICMcCPjNNEwJZGgJLW6mPbMLjs5Y4ACIO+xSxHFXIYzyiiM3IJBuMp8LlyPJwLzFv1GtNRcIc9EcmsThObhiQSXweKF+Li6Zamhi/SDNwlDLS1EBM6nhHwCNrAAeE6Xjf3QuShTp8pvnd1XbOUBkitfnboSmac47DbDlf6ZdBwvkh9nArzxkjsO2B1dL6aHkocqdZ5IRkqAH4XRxt406KUL2S95vWMgwpUXCxphbFKEfO8TomQsLBp6DCrI4m/w4CWxmpgBf+DFFJNNLKqrGQjSJnfgdbCPF9vuCcW30UdRRtXkwzJUiaCOtZdmgiz44UN99FXQUI4NP3xYr+uFyeWsBfIDhcMg/9Sor8a8UX2ND/QWeeKq5OT8LQ6pklWoO5RgkQDBjG4q6RkrsSaC7Nq0WoANWMihMT80/crJwe/w7c7woMUM7qBU76BU76BUvyMoVVOneCMkVdMHwEoG+i6fyxgpoG3fbA5eCqIhVex4CexVDXyEI89Yse3bNnyr6HtgnYLxiXqSQMWGNOklSQ2lpK1Bfzjobw/6O4NVk8DlPBxsbCtQOBXIgfQ4TUFqlednOxeTosdEmZtEXiIij0PGWwJDUXtA+UXh+msupjAFmknsLfpx5MCR+sMga5tUczhoz0JFWO7j5+1XeQOpP/K+IqURvRf61cZUKXxo4eg6ZX9CHizfTjpP/l70o/QCV3wut//O546ETaHNoo4nd5Ksw0wuluoCKUwoLvcf796eHJ8ev30zevPh9dOj9//ZZ+9UXSoSy/BIlBu3+uwIAh1RXkv9jC/iHyLJXhSGQJ5vj4XBFY9cGWXlTRL0kTNoBEBTavuD6HoVeUkiggdWiai8SNdFyl53ixSl6MhmksooSvz9P95/eHU0On7+n314WJFczKMpOq4SbUDIxdAvLH/8XCUUP+ucdR4gBKVIsrY59TMBZUBuASUl67evHs26JEAogWYKEOLAbRIAoSFuff7W268tjPidg53dwW41pG3Fuq+7GBsxSik4YiV9tkbavu52QOexzhxUvRKccO5b6wUjv2x/y2y1vEbiu4fY3UPs7iH2PT3EzBvkRg8xot1IgNlGjJyIX/kiGtG7qOZsKZXypYhIzJJrQO0w2Q4Gt1FbjEtYvYL7rxez38MAdP4fG5oy9fFJxJ0LstvgvrHbo1i8jBMx754FoCfU9Sm4HFayYC+QGvb+WXAL5rZmoPhX3kSg0hjFdHJaYfczjMIHKMGMl+yZH6buxAcRVoMhsKtZiIZHaWgx7Y/oiM01QhO6QAP8SL4pjnYaLzDiQkiZLaEalSo/obQmaNrQgTRUCVBjpc2QOrbJzJpwuzUI9I3U9IIpnYAfzLd6LU3MrTtPk/64HLhmShtKHW2oV/JOnvRdEGbumZ2uWStzjWihgpE67y+WaVP29+NtuMKodcgm4fqt4SlqbwEk/ywc9Ga+qHXtaC/s1Z4Hxe10jbypJoK19aJUtwLHVp+r1Qb6RSImVksroNSV09CIRMwbdu35BnKpBeBumobW6ptIIZA94Sz8gtCGOk868DLsKW9gI7Zua6c32OoNtk4Hu0+GEFvX3xpu7+z+rZR5qcVAWmQx0P43SeHdIEEV8N6VYoUOpiKHI3AYYBhujBc6Iqgdyu9Qd2qCnoeTAiJ6GEhY6oLd2TME8KpYWF6Ohl15+AouMYuIDdmMI863TtCShevI8DIdHgvSj9FFXEGibzA8tjnhwi+0LBbbCGfjEInmioS8K1KQkTJoJUBWDaeEenUWIDmDkHnzBShsQyNLrELl67LYmy/8JbsQYoFnGoRu2i1XmBnnLBiH0nNB9+oFBW8tLVVnME50M0gArlgErmwIDdJ4krPRAL8T3Wy1pRwaQFy2dAdZhml0FiiHq1IvkcoLpB3HzAHmhH3NCjIDC2WQaMon0X5l7ZkjaF1LMFgwLKAKQEbCaSIq4yKFSeafcSLEWfD3PJBWDtXg030FUeWKS+HDhR/3HS36I2CVHuIjB9wVF0n8iEbx6H/Rzx6MJn5wFqhzTYYZypZEOqk4N/IYRkbsPpxMzjPPJ1zIsyAbLJ4iehbJlzU4u52IJNG+hLA3giWoMqYSNjOZ8eAsoKYRe1MltrjpkpsZMjaUO6Npf5A2kpRxm1APUOpJiuAuKhpNY2ej5Lx3cOAe7O/tDJ3dvR13KPZ3d8XB3t7W/sHB+PFwd9hCci7098OL0KsJnsXV+BKC3V1kUHVk0LeVs/Uu2Oj7Cja64dm/zWilbyG97G1HQDXjy7TvobalfF837iLf8l0c110c1zcdx1UQJ8B+M4pJWI+bBYomi1P7paxpp36QP7wM+oVoXJBF6wp/2rxYm5dvxXh7xBdeTy1t7xZcGaCPtZa3WLHREHxdXOE6j4cT6ewW51Cwb833oXGmZvn1HyyWBZ3Pv+nF/HprtGki9ybc89NoJf6YgU8q8M3Hg8G2gZzZeRNK3avSIH14f9y5/oRqUpWwcqvBBFq3agb85YqtVPNZSWY4jKUcqF9ovaVtQ44E/9rkipMp/e5YtWF9BXfVKLz0XOmwCn0qmvZr/auLV3fZWbaihEKL3fzq93J6wG9tA2xeAQddGcl4i/T03KK88t0w80zq2byQ++XEn+bm4J8eqF20TuFOXBpB5mDQJ4CLZ6UN8anKuiX9iGUl9AttiKWC2GAzegr/tvfuioR7fovnYMvXbdX06KFX1f13cQZWm7ci7De0w3+IWzFHZMgu69kcg/XkzFPDZHFjgqsztFL/y459a9N3FWu+RN+OwtAwhSAeVtsSFF3XsfKaQ1YfrWhKgcZqFc2rWCQqRlawTqwhJKymQ2+cE63DepPBuhWsTy3E9ygH6HFV6kFKQ85O6uqEhIpFg+ufUlbIH95K3gJzfwZxrpFmMuQwNtF/WziNRZL4r/m7vx1MnWdHi3/8fBru8X/sbU2Hwa8/fZi93vGevdoWV0/3Xj3/9W/PEi88ekreVUpDsIvhG5VzkJ4PFErTvOU3x+82z6M2wCHyOwQ/7Oo51+2F2uh2fdcELFzIjKyWaPfyRVS/KxR8z3xpqbrKJrit6ICvLvxJueDbYVg/pugnj08tH0TfPIPx1Utblt3ueK7xlqK/1EjQpGsfn3IVa8vgbvq+6m7iiq1KZCELZDNdkXuvynOLLipB7HvBRbuqsmxbtweoo3QTCY+mot1xl0UrwDLlt5pem+DSSolSv1tPM958/O7FCZvyRFxxZOh2tmzQtvoQPX9z8soLLqQbuUJow+OFM4UevcWkAePlkbcI4kdhMA555AJyGlbJ+7d21LgMib52aFm51Qg1GG6LrcHuZEc4YrLP3QOHb2/x/e3HQ3fgbO9u5wm2PbS8DPLXxZpaMu0DRLJiKTkY9gHvmeW3fdz0I8eewsxcMrVA5LqP4Q86EFLuJ7lt2aXH2bM3h6+P6hdT7XIjs29+/Ya7u2p8m4gQz25vW+DEbcWL53t1vlD0eL7X8iw3H0tuo+7GI8v1fv2RhNCStv1O/tyg/JlFAdbtV4nhWLiM7slgJ/Rma4AWUwEKSubUH4Anm4qC8EUiK8LIIXjBfj9lMk2NjJxnuivdo3CHm6HEGOmVAvuV38CPURp4iD7rF0TmLxTop7rLn49m7v8VVaObEYG/vvp0ZSG8ZaytcSDXlNxhU4TRhYji3sXliAdLY0OkwQWkq+4Uytyy31rW01oXh7361wXgaTngdfWln2oXaKN+aN//4myUrt+u61nzQrV3QLO31d7j5XMvTrgXQLBzD1HverJoo/fDjTfAZt3R6vdCEPbawuT9aU7bBrfJ+gd3nPoXPQgKbrs8qOGxUOi9fsNeiCXFki84DIhAHZOZ8CJSDyH2FuiysAObRK+p9kfnQiy3Ok+oV4DBuxDLofp7CEuWRSa+q1ZxdGS+jRTwIuPQ8fAJrAYGI+7nHhKFZ0H3j8Jb0fhEe753/6gYi/Ut8um6KF8UVqIHo+vNRcJdnvAvsy4AHKF6bFykKsI3mHk/L7yW0T4ZaYxKeMYzmpRXWY+/ZqFbdgsSHyBEAnHW3FKr9FQ4xNStMd1PpU1k3UJtD3LGuUYXYlmlasmgAXH7ZJX8JZOIugwBDXxhgLfBQBh0VnzN2iH1up00yA/HspHf8LmI9UBQMwgSBuU/GAvLaCCXEJpxIM2IGowSHGJco1pXnwIXsFF7RF2tq9s1WoM1gBcONithi46pja0BIR0W+4YZ13ZdgCvmsdjbKRP2OHA9hyeGpieMEL8HlRUiAoCOeBamvsuoCeYKTECR6BMgEY7jJMTMJF6C4L6T1EdqwzjhY8llcOmuoL3gXmJmLFEpkf568vYNI6rHXdhyMwCk8eZwf7VADyJs2ptymeyvUZI0R2LamsGK13hn3WgjGPyuZRtotdP1qnnYIftw+qK3z0QAC+pKossDBasp3C5LF/DBcJe99p7CreCjmF2v9DmBvGf6c1PPvjfc2tkB9Wqe2wGN1DDLjK7hNEhrI1AtXnBHjMahu2zmgL+lkRe7Xju7atZbrhppQyquB/hGKct+oQbYzx+ZHmefKSXbuRfECQ+ScwIBwglRRiJdGBaBJso4tHJMNczW3s69xExP164tx+dxDJmksoYk8CxklcpG5pH6EjMSxemCUlZBHgffc7yETneDKpCaMrSB6hOEVpmIKOjJJVr2SC/U0aN6LaOGEy/xmxVG2XJlu4Jqlnxp8NNP1h0VCTyJq26sLzPENIpDi+3z7YL/IxXK0kP4UhciyNIFeQHkeNLqlD41dN5n7wDe1UtYGjiQ/o9wwGDJz2URhgmJjXSAmHkL5Uuy/YjPiTb1FG5XGybNs4stnw8+fv7rwP1t5rnzrdfur8MXy+c/fX7180chXv7tb/O3709G+7+Kk3T2+8HJb8d/fc9P+NAP4heDreS/3r6MJqc/Hb7bfr/769bPl7vexw/p6/Gbn2e/vDn89eVbf0+8ezo4/fBqP7jq5N9QGXX0hsMLM40WYYzbDoL6adojPEydaxv5N2IszEMj63XSwGaAi0X2upb2qy1EK1Hbo+UmlBWKUk7+Ks0P/Ai+k1aNC0gqCGh1joiAzIi41mVzwWNMxucFhmkwFk4IqIOxRwk1Bfvw5vhXJhahM6uf2e7j/Z3t3dINUL6tq8RY1XUaJJ6vRy5oJn32Oo0pDWTCfAE5BfYGfXbKLwRmHHOEK2DEkE+CnWedSrY9DiF9QWRkraidzPbABMvdK0ypzr8hS1Fi4v46uL9k3rirIK68dxrO5U09HyqgpCpu0FrDk1kyn9dwJnJTQlCyNOJjuJxAcGH4CCSzd589g6csXFyYAjaB5c2q0g0ZSnzFWtKI1DRlwR8T4UZk2UjjSoSwnHRnE8PQ2wFkZS7vUXYoRWuSwlgaUP7AqXcpAtyyc76kjJbgenUpXHSFQJEd2pLvzwZVW83ZBvll3SPcBfoS8qQ6YAj2R6dMIk4qvov5WebwdqNciNnzTgOJynoNjOHx/vbePjKGTUjMrcxSZand7vD1qbQJKrxgDmH692LcD5QlFneGXGuesDkAfO5uDdl4mQC/OoQ8qpEX4IaDLJtB72rmJWpnzzjA2cH5Bw6BzyvKu7IQkSOCpIeSv5T5EQeQlgsPB1z/C8jZgzjmH96/qj8br5e9n0XRvXdraJ86vW6+yvxvPon8ZilPIhp7ScSjJb1kVVLqopqIr6eOsqmub8G1DHQy3j9SIV9dZU5WM381UaB6jhSaJ9PkHxGLA33kjeigWXmzCNbC3m2Ty/P27w0/HFcezVwBKNErLB6lkT9SJ9nCyiOA9pWKM60mC6T57JVOCPDh/aseqXbcgkaHUsfK3YH5tyX+81kHNsZZp0sLamudx+ys8+/bL846WRJ2utPwm//nrNPGctJGwtj0sws9ua1vL+vGqJHSrI//ehlsMuTO453xzsH+eGd/MNx3xnv72/uPnZ3hlhg+PrixDFbYTXf6i5vpL6qIq/dkIZlvOudBD5YMXRWl3s2QAlffMa+X7O1VwN5oXli8wxq3xF1qpLqH43eXGqnwkK9UAYMkxWJYl4BOVivdb0HX+1Faq+psqNpdDxDrMRCs5H6ZjTgcwwbhY8/3kuWITxFeMcs31xgMiN6EMMdjS9qDtwsRnApfzNE+NBXBiHt9s1Lfc+X7i6Q3xeWlB6dMXCv3XTLTj+/yEQUfu2CRJqeghLP5hqZz2ElYhjR1oAKSzGm8BBE2YfGCI5a9xMp1lTO8HAhxThQsgWMGIVaQzcTUdo+0gCkIjOW9I7PpHaIj6WvLMI8gufxEplpMQOFHCwTX+BRTsgeXoUPPaEkSObgu3PMfAu8zvQ3Z3PN9T74eARtcYvpzRP13RaSsiCopgR2kX2lNBlKO8i1jfo4ZRp2EUYHVybqCbbDbCdOkeZmp0C2tMzXeuNALcq62ZarQFJuKAO2ll4IdHjNd45ZJKCs9l5ie1n3o8wWoRTGfA2aJlZVOAHr1NYaJmDu5yzDvlrHlGrdTvkHLUibyTYz543jkexs7Ds1jq/Awf6t6z5zLS+MA7452uwy9hkDvQwk0SBEKyXWN7QYzDajkX/TkR0E4MisHoWwLXKVUIan/cUNBKcymKY94kAjJa00GC/I7ORaYjgdWOUjh+xdHkjnAwzUccUc8a/J0cNUpwOLlh7s5Qjcli2lOtMHNGYEJpWlFCy+Owr1V2osFLm07MblJ6g2jmaR5/Ftet6Mo/XauXIhL5ZRGnHKnWmIlrruGE2EFg6MCOX6GjwN9jvCMeDqrTE5QbcHKbv3Oz4QPL5YDLN4OgZCttpQAbusetQz1W7tZV6LmN3jP3pTE8jFWN1R6kapnGw4xErEIbuP0YP06Fl3T001ZcotLlvqhYjW3ZW6Qtmszu95udl2qduTAcrVr7krdffmOXE0EwyqGAIZ/HwXuWuJXVnmlVwjS2NwHNxO0sAnbPXaKJDaCyrVmo+IqMomzsjC50VkVvUrkFAtDzK1AeTuow2nwDMPNvE7c6BZlhGr5AyQwZHQS9ko6tBbwD1PnAg/P8DmbeXESTiM+J1tVkM5F5DlSjYjWesqd945YltQszniUnAL8hxeze2af95ptp2PPxqFOvbnojXFgzOdjuC3vH5+87e3vDbaUS+ODLnIH0CPNeRJ5n5kT+ul8xbcSdfIUEtpxO8Tde37F5FCEa6S8RiELbWyUWy/wkq5U7MjycV/++b/ZFpoLXb3LndAHb5TY4b6gRINkSITsX3O+gPxyLeahLkk9j9dWHTStMGaPA+29BJZAS2UEQ0dXY02BPrvnh9N7cIu6KdxQUxGCtOk5NP+/sHuQzpBHRpGJ91m4vSvPTWZUqI5fUtI4agM3r6RWeeCoDevhdSO3QWnNo/CK3Rf9aZ/d2x3865//szUYzON7D1bbBNSWhauAbs4Lpj0njCLK54fqqbgvu/87Df3Y/fzp72MvgJ9KP66TnBpaXMxughsIN4/a4fd0K/f0rYsHwAvYPWr2Xt2EqrZFoUYpLzqevYz8mg6WU5HbYNUMZ+L5iYhGvuATm4qUvobHB8U8QOpx36O9SD5xShOMxnXp9EABFdLrWQRuBmTherGDXClT9iKrohq5mAxpiHPCIE6ilJIG0nDiZiZl9TZ5QZMh3kiGdhi0zgCPI8d7fRGJSy9M4/wcmWQFWE5Nq8+eYaQXfeoFjp+6gv2bMhL35WXRNT6idE3mJ0nkTaciMj+SJu4uEib7GC8c63V74QWWW/u5B3/NwTwQ0pUNS63WNQhd8iW44suY3aNP79ElIYXcvygfBOmqUscnqD7uNh12YLFghPMFj7wYAHywVBj12QkZgtQH8RNFyhh8G8A2o/7CVEPxCOT+LqyC+jUSU/G5z44+e3ECCv0nTMCvIInFI4jNoWSOcwFHLZ55C+hCNc7uY/KsXizA0AA8gHbhgz57Q1fqEyb+0WUB/DNN4D/RZT7cH4ndPKXtZDRumTfc+NOYB5Z39e84E7Q0wPiBb9AEMH+jbggK/AP+wn+nCf4DlghMLOLjr/93p9v5v+Cf/4T/4Jf/gP/gl+M3z159eH500ul2nr89Ohm9eXs6kp91up3Xh6fPXo7eH/109Gun2zn69fjkNFcSP8FWOt0OVe10Oyenh+9PT0a/HJ++hFpvnsvfPxlQgIXtCX4RCogMztbEOKPSKXHOE+lPxZ0k5X6uPNjexyLjDfUbVH+gLUfK7v6pOlbA2K/SRc0YlhxSFt+HPqvo7vGvf/4f4i3LTHtW4Il9dhSAi5kRUYKTu08DfUTDfCQH+YD6lIohYmNQXJ8eR4+UzAoOB3x8EcQeCDwQFTQVn0GWiNn7oyGLl0HCP7P7Qcj8MLzgM8Hd+BH8OhYzL3DjBzcPDiwF1lK8Q8Ye5GI13lCBVVA6kY4gLKDX7jQK00WMHoHAD5+we/iJVazNJpa/O6jDZ1l+6bIIYiCQBPCOQG3r4ZvnnW7n7Xuci7ypbhofVU2Ka3zhqNAQg/9XjRQJ0Smvh4czKE86m4MlLOUGo0dRo8bi6cVxKkahQyhObVybELLvcyskQW2ILl2fZRNr9h2kNLPGxSn1QWPPMx64Mg9iKXy2MxcQduDF87rlIyEI3FF7MqMz9Cx/jxPuXMjfIVFyTz9HxWfIhEzrGaaJE0qnTA0sYJluAQLGoJE3DXiShzYwvoVB2MV1CxCgGoA5/a6mk9nXJ43Wkj/7H9BNj2U7hR0/rzBDK1NQ80KNgcOeeL8Lq3TuRBU7xDY+qTc0DFEqZKRinL/F0cJ5rRMXlr6fc89/EYWWbUKuv1X1VDrG0heU/dv2TcSvKokQ8eWxvaPIWSSnoX1zODPhpr5wT725vVnQrlS0S7v5mbwBWuuvyhopKYOUD3hkCZ14L1yOL0i1bOQySK4phYAgy/OZkJXiEB5hz/wwFoXxZzPXxY4uhZU7Wd3zloiErKb7SZZphYIIF33+cmoMbrewPnNIqkWU9EzkqoIiOTurulQ7vZ7xQo6459fdq1X3ug+Z4yvOTjUztOFwFZ/r1VwbWHLpylVLZ4BD0diykViv3Px0Krl0GExD6Q5bvmsWHLzHTmrOWvVXNyMFNNyKFvKCkAPJ5lOmyafM06t507tevADm/sbiM23YTwH/GGVz+9efhYOKUlCr2DcT7fc3lXcofn3Kp7WyocUyhPU+iqidI5hXsYR82oq/lPFwslmVqJCbVKmmdCbO1ld5J8iFy93P6nhXi4cLEaE7XeCQ9z541lnVDP9FHDorjnYrMOo5UssDryh4qUG8YZ8dy6c507OTYUBReBWD3jcIwDEQ1DEYgsHAibXPnivzlFL9BCKBkaOdJnBaBCPxMQjFkjeVfZHxK3juHrp8gYrrp17C3oML8P3Dp+8fQNgT6jxJSaz01XhB9dnxhCFsDgH4PH0vm/NitmVjrjizEcyszgiZBiD0RyKOhUmMjKroaWvl3oJsaHYDAryfVXhVbh4YAZda8DRgr4VXzSM217B5mIUdrMZs9pUjVfVuxdG3eJi4s9Apj/94YpDgiscAGwFu246XgCs3vxRuNniDyUt0Rhs3tiBHZhWeLq1MowDQWGLwWVIMHKhZPOeKDQAGljRnFazKHidGXSgw8cJIcrDGgzw0Gt19UlrrlDBCHO47qY+sxGLWeEYu98+MQuiJH84XAMlmhItlR69G/e+aSlljLEu6NTpKC4owTxXSDPc9brsqNOqG7fPTpju6Vj+mh1XTgiPdr569/fDmtHwZ6CZaCDjf6AwhOoz2Gj094PpDVFd+iXtQuB7G8SwGgy38Qf/uwr9bA/h3iL8/xn8P8JMD+v2A/j3AF73riktEBok8uL0UTUfPj09Oj988O0UtLWhnX5Pu9cNr0EF9/Ak+OXp+fAgfvqMxvJP/Qi/vcAzvcAzvcAzvcAzvDuj3A/r3ANW5z58ffex0Ox8P3x8fvnl2ZNEeGdo866piDbhkY6u9EDTyCKMvS2i7Up+9EvxSACqDvL+UwQkA6NTNDVVWMBwWIeStmr7yADl74XMZKArfjQEB+EoygDFEjmaa61hFgBWZwDqaw6IeOph4U6UtfiG7S0K0yS2VX5Sk3hqK0U0rKK+7pHN8agO1ek4ht5KOWE46LklTW0tWurC8Utc9/Vr/Xy8eyydLFWTPNWixLsHfoWkJX2IxCONClTwhe5H9Axw+zcvGMzaVpFF7qlSxy5yNropkDTYmG90qxKiy5r+GhL4392zY3Hgc8Ut10MohV49YJJwwck1IkWVGP6uzEP9MKqStHDQFKJQCIVxbJJvcweDU9hllYYnUIAOW0hiNUqnv90A5LT9ufg14MVppKjTF8IB9xnNY/MbXeiFuaLOxSG31R0IuJOwpiGR5ajG+57c+FlOHvAwAs7Qe/gqKYVvVV4utqzq2HDsdEnnrbYJqNoT2YEiGsAeoT3NuY8tdUEXF67Js1KGkSSuI9LKCVaS3vdClSJ0X3uldkpOcs9eF+WzIBmj23PAuGqnVsJpc0a/TuA644n5pQAAJi3ABJIcHHbmQuALSACi+kLnAXnriStpVyZ+nm2OuXUNFH3dl7EMXnD0wGiB+0OIJjwXL8zjEUJQoDViczufSWSvnipdxdRwl+ONRY/f67Ig7M5mQS/scx+hORe6uRkhAzv22GADT/qbAmjbnz+Pn2atZO2uWAm0oa41KYREGFs8IeNFAtTfW190brj1rN9BRU2TGM+N7Zp3hyl2uE36R8+TOaznaxFtYJnaCig0TCY0wrqRSBSA51MZcPW7z2AzegG0Nnt1OFMax6bCfTeee9Mv/CzPUddxHzxs2Bm1/MEVh/lZCM2hghaFsMgrjbS784tbp0Sa24icRtImpWHfHVYdM1EVKlAmw4ciIKjpbydgY6YA8m+IcNh9IQHHvOmhDR0u2sX21CREwZg+6KW7a11p3s0IMQCNDWSEU4GZjt9oevrC7v/U9U69fPJxOIzFFWcYomPnWNokMZuv3wCMVBYNYKSgR3DwCu8d91M91Gb+cdtni4KDLROL0H5CDms6xiM/x3njJxpHgFy5C6qF/Lvg4xwLEmCKHahQs5ARrrV6tgDaOLG7a+C4Cvkny3ROKEKP4OIkMt/DBvJCADOpr9YLE46FafXacMPGPFL7PPyxzxWgRqMVj2SDaU6xHifQu7Sdd9Vbf1NNuNfhhlAVoirYHMABD4kqgqhYplSOL9iyeSTxVROjDzv4C1qoSFYM4AaOaBeHD1Z1lCUJylS2H6lJEAFdSWHy19uRLmS0+StvmSuOoua36FnvE7ut9BfsuQkQe6RuPG8RLMBzNC6b4CHnwxAATuhczcJgYqeojrD5P/cSjFsZLxD5Z+DwBESHrx3C/N8A34K1CM8/gE3GYKrouEPZZsysRKQK5WV0+Di+Frk5daI9+9CzNYiUIioBaQKbQlciF3ElkBB/8P6DHGZAVD5SyxPa19dN6fCqe3++RMeos3Rn36zPJ4OJ0LrkcKeS7hZgdcpC9Et50JiUjga8tIMu9uLjojReNylmgzB9GxcI2tR6yalOHMTe7O4GIvFWYaiGnxp+BBU+8KE5OhLAT8I5B3xqDBsiGSrrfce877v2DcO/Es/p6lbDsScFaldGmAIhi8P2uKT5rlm9/ZmAESH0Qi+WFkam+dOQbBrkvROSFruX9IfuRTwbYIyIAnZPbZyecMmCQtzq84czXyd2T4e7JcPdkuLt07i6duyfDt8uC754Md0+GO+59x73/DE8GE/5nPa8/G2gR2MIv7U4RkHbx0nMhbJ6OXWszB7VoGjj0Doez4odTBiA1JpiIBs5o9OFoiestz5HuNBvmfQDKgHhb4Zo3kfZqclMEmUbntZxTiREdUUGyVxLW28tIl2hIycoRbda3U3c4wg5x75DjTfV4lWOORH3JzMBFXmwkzRynno+JWdxlwOeewz4cr/BqrAB+UYgvCtWkYhxW26X0KW0EroA+JHBDVy4+ehEp9IZmBzC6uLGM9ahmkpsFfMuwy+ngmfz0uhLlquBhx6YRD1KfR16ygqvtalKh9TFfcRBHxSD9zE2zKDFgfLufxoAKq3w26fOcC+eoRp6ziiEjU0JqElvaDqJatrGOYexZw/xKJQt7aKRupGwOn667P4ZYnnlX1ShN8hP8ifzeLf7TVhSpqvDnDUjo367QfSdX/+hydYFH5GTDryrB5tA5bE5NRF083bSchkvm/QxP40Gz8Gj0o3xrATwKfJcMYA6F5YhxNb6vllfqx3mFW20j/9ik3FUCCex2JFD56o1LP+w0UE5xtJnWa6wqNFs5gNkkFwIUVs7RNiG2cWGp7Up/ac70+0QjGKO7k5fE5DTY1U549GjU/ouw1n4eS7hBzqny/z2SUMmUtg7TjqcBwpWZqM0S6NabANNazT0yCkNEdajxq1YOdmFIHqBqP3sJQfwnFshqA9slDJPTiAcxxzRu9n5ehVPPIddGVTDL7ZTr3NqHJHz1e6LoYKoWaPOI28VnXy2wd8Fzstn1Uzt9yjWhXXlTD1A6TEI66m3W81OCLVngn0unaw0P0FOFKx4l6469EuO54Ma5shto7mTZz0GzbgY4bI7BNobGpJZg1PcmV4P4Ml8YaBVGjAyfgnYk0cnU3po9SOGC8CryKgxMhOoRJ8waJmdXrVCz4Gm0iJAhAcsahlHO5Hz8PJfM2YuN2B9rpEcGeFDQNSkI6gxuqHCNgKM3yJeyCWvzbmRRKvwyE8lMSPfnK9ywrmzvvjKrgwC3AMgWlFwt6R7x5aJf3xbGrRmQ6Xsr8X+tgB8vvSmMSgJNSrxnNsfE0CLhnk8Z6CwuvBkXqEFbs/l+16+NhsAoYgsjfkVp42V3cxZ01tVqPNqE4VVAEK5mCEWLPfg1UTZaZogzKxSKfboD6rgD6rgD6rgD6rgD6rgD6rgD6mihfFreAXXcAXV820Advi+FhptaGLp/NIJ2lC6FO9iObwu2YzNvhG8F+SOvTr4JOCe77zagbLbB6LiD2fwBYDarAvefIa50UtJa5eQTu44iYyKYv+ToOUrwr9+9OoLfFaL1JLI+c091esUCKfVA+uweUOIem0PWkLFCF4GyPGD3kvBen70J2SQihSL3qzSdFft6IhHhbTH1mdarsM5qQn1SsmblCorW2it4uLu9MxhuDwaPD+B/RSD20GIGkbrprzOmongYAhcG6n3Kc+p1VYjg4MFkO1ZVGOSRqEDXkdsUSrCrWVgwy9Rp2GwsXYlPmdbV3MR6IAaOgamFJIVntYa6aJG06fZIOV1wUsvMcmiC1w57XTSvoLOUzFuHXkwIw82EzEYLpnyp0G4+FP8msZHs77NM4fxMF5MjNBSKJOeLIPIw5w4m9vHDKfFMqQdd4kQCl7linE6n8BfmL1nBuUQq13SKL9tZVqk/tB6Uic9gqUhMNosTQGisOMuqFgl0GfiM6VddM+0awAHhG0ZNQXkFtNOlOhUeRRZtfqYztivvocZJlenPaI+U2Qmti0wgjAfEU6tHeQXlru0CAJKIbX534PXgu8gjrX5mrRy6nDCu9aiC7zHJZJypyq3eAyv2q4yHlo0CVt0WgDIrdigCnbXD0t8a9saK1B2ynzc29VNTTwEPwnJHBWCuBrt8V3uHagYPHMr0JZAZjKu7OBVzcDaySQr0jfc7INIRjL9Of2uOIpMvUdmCSUC9uefzSIKH2TuH/a9SthRo5/0uCj56Rb7sBSRfNq/RBPywokXkWc8+JGIKkh7I7IDKp4vq/KWkP9Lzqfa6rTFB0ZCPn1P2RukQJwHOyLEKiBdOJrFQQ8mQ0KydVTwLXsH1hHI88RU/nHaJ0XfxnuiyKx6BpRSWxc5mjMwi5bbVgoPaoa72WnvKNzqo3lHKI6Wie7iL7Z4er+meRucOfVoKlzyc0tJ9bu2JMmKWe3mLn+tjYvD4iUicWZfptEJdhsmM7KtQTHpi4S2ZCEaFywmo2cwTEaiGbCqBDP/JIt0Fk4hnAdGqYNO1qNMsVd6H7/kyB1t47kx6EV+eM8rGkylPyLmNsqZTplEpV1qvI2MIYmq9Z4wx4MJCiI2IUJ031YKTTOVlDqGiE/yuYa6Ghx7NAwzYYGEgiQxIoF0iTNTGcIpW+tXcjZSbEX5Ee1zBP4I13RQ57A037DRDHNDxHCAowIqhVgNs4F7AeI1DTVzp7PUynfOgBy9mFPQM/ysvrvG9WvDgpAoVbyGCU31l4MmQ2HjaOS8M/CUoetHbps/O0yAWyXnGGrCS67moxIlROazcSjJHFHKyIp0wSPyUAVg+5NFJgy9QDq57xGPPoL++yIHyZfN7XcWTK6ep2GTFdI1ZUnEvZufY8zkJ1poRwxxiUbFpIH2eddfAF+wRwNv64XIumiVqdKSqEdnWcrSqEAh0X5ViW31vTYJbPvdbYaefnr4DVe0iDGJNfCd0RUknXXo3rigC67e/bZbopLz2BHMeZ20dBmH5o2a/wVVnWeX997zkQXv8HF7uF9mplZCnyjWzaqo38h/14tqbRN5tNletmptPChQ/HZ2yR6AXibvs3duTU/YIrQGxFCzUEbYLGMqcad0XECTm+DyOyW2KunMmPXqm9vAa6Rof+OHU3ktFlsIsOaHlhi8loWylQQKG+W/yGV17LSsHw80rT6rcaeAkjH3xFtUSFYnqmpK4FdIstlPQYK0mrxUUSztGukto1efRvCOTh6qkm92OgHSesBj0I1qAuQVTgHaMlJAyT9rED69AbxdcBOEVGcGbUtFlg8qRTCr9hC9i8kJVWWFtlEI0IHFlo1WrdHPVmWT91JqIrigPliviPmzIrnfTLHm1+SDtGfQaMifWJSWN0sApGAm1Xbc2C5/ekC18tJxFCpf0a3v0nOvxaRCi9e3ZDKw3/pGORG7nuuBQtdXJWZNT0hJLpHIIqu7qMmZSbHuLnI93LOWOpfx5WEq3c8V9v5IZ1HEcta7mzs011zX4jM3FUHsY2m3w8ktToz8WfhhM0XtOCk5a+JDyUoWCPw7TyPa2f8+vUDe24Es/hASer/kSrLLwHkVTCOT9yPDrXEajl8lFsEBA3nBSyQZvOmmj6jd4cFQzAyutahIpZ08OnUP5Js+46ypGNeF+LPI7Qq1gPqmrJLdpx6o2IKZwFEbac6z+QFU4mGEGGJ8DWLzLPX9JvmbNhiss3La5/5+9d2Fu3EjSRf9KrSY2rJ4lKVJvtXf2rtzdtmX3y91qe8amDlkEiiQsEKABUBI90RHnR9xfeH/JjcysKhSAwoMU1eqe4Z4Tu24R9cqqysrnl2CcUCmggOSAMRg8ZhPvRoDJHK02LUrsVa64bvdpt8s+XD6zhlFAA/voaACiqBc9PlgSVOdeZeiCRA6R8RLF+F8ctyVXDzsDiy1OZBwJ8TSTEQ2520GoBf233HOBFC/A4jePvJjI1mFz7rlPIQoYGqR50rOqScNoGGPkqQLmECc84BYK/QImFhlQiJQWhn8RavbOBXpDIa4P7Q3XQsxTEAPKiGpBnZw8iXFQCMFI2GTBIx4kAODijTNUQPe+Ghs4RBBi8k8keAwhHpArwfBPt14sTJsWfA0LVF3FLRl7BurTKAoXk2nCRmDh8dBUYjXGl0SLpQkd+93943av2z7oXuL5e9rt/rpjSeGgzG5Mk7dYa6YI6ZlZ+VexouBIwHKuxTxpyYMOxLYANRjz6na6PTNms2g7stobdWqVNsZ5anw3CudzVYf5drrssFdgI5TpTjPJy11XuF+zBILUmBRw1Ce+dy1YANT0O/2gLf/zKawydYfFuE78Xe569lLA4YrJCGhQFBF6klijrSziBfd9mJEDgcNwOeYcg7ngK5NrsfPsiQawHPyIjigNh+gDCwCzYvqifM04nS74jT7jo3CRsF5Xn3wZ64UUAzpazxzjYzDhp8wL1h4JOH8OLl/1BjZ/2gPrRcCACidhMYW1V91+ovyODCGmwC89YJGDIcMyIlbMo2yyDhWSbDw/g+fhjNvhVHJajIiSgc31mLqHLl++Z/CZN/ZAxCKLRRoP6OJIlTd4scAYnfTyno3d8dm+c9o+PnT224f8wG2PenzcFr2jg+7h2XGvd3iES+TumwAeL5IY7tp84XpJ5n5LFN6KK4XgvTIK1mXTME7QwAamtXCR6NAQYy0Q3Oh6MXbcgh8CZYWLVS6Drcdbz/epppHArlOwDeNraZe1DCH1BGwKF19HzwXyK0wExBu4GNFMdbBf6XTkVHLxiEo0NvaEKOyKMQcwszKCw59iiB8CzaediCjisMttNb6Ud3ae7qhCLANVY4V0yhsvCoOZNYZKGu6MbxiP49ChoDBMkqw+b+n5knEzFNhbRC9qcq4UGS02eEVgSXt1aJ7xALfL08fuT6xNNxd3UsRW26Zawu8d9i5ztLzYvoNVh6mSFnw+78h/dZwQdGjbcq0sYDaT9yNlBk2o745Erzs6HDm9E2f/7Ojg5ETwkXvc7YreyenJ2G14s+V9iAe1V1x9iby66lLrq6Rb5C8JyLqNrleHfRtGTC66paSnEkYzzG3C0MJVhrNleyw4qGCd/OclJ0FxDLwbYA0wOxnipOIFCF76S3HnxQhVNS6wGy/OMyS9ghKOVM1QpCKlOYr896ZZSqlL20QAkaylgp3kbmE9R1W74MWNbuFsKZX3kvsHrKDmHUZuYlTATGefHsrKORydHThnztmhK472z0aj0Zhz58Q5OnCE2z08PHFtU7vn7uCy7GzU3J97L62Gwd1rFbZwYyU2ZZ+0dBvNlRtviYnJUWBvqSxjCnIYr3e+gBSnWlnO6jIGRzKGXYA3DGkrVUKMvPYoyYQvkmkYYVRVEqosFVnnzikP3iS5ttft7h9cVcV+yQAEBBnQW2xOw+fONQzliDh9BxU3rPXf4cINw3iefIjrFXAfQm5FtFFC8kCrW54cBT3CQsYuknHAcSBZw60hYnd/LSIaU6Ah1XAEX4LBV/DxZOG5mHgEDyNVyFR3DUX6+9P5lRdDQNJbyKDaLJWZmgZ6fXWKFhzfGQ1aR9uVDyjZLPS4tjEJO2sxAZw+iaDmTIVzjTT98O7l/SlKT8tFcMP9jJl9MxxAPosq0sxRGMMejZeHS7Fe/N7qdF3aBvf0sC0ptIBxwwc+JFz2w/s3rzdFzZfNrLAr0tK0HhIksoxHkLYgIxlYWRa574e3tVzh4GRt1ipJTCYVmNhIiCCdnZ09bIrM8L5D9qnvOZultsqJUTIcPGEgS3AftIqlknGrqXrYvS9VlWyvhvUCxCW1sYQwhB+Y643HAkNt7QLN+nR+YAahliovaA1pe8f3ZAnlw92bUG9J6KKk8YdhBLlFJGHIwKEHJ2EkA9Px4GoVtKhNWdlA72itE2tMJ7YPzCB7FXFXEcj96BBKZmOqlTXzYm3av1dq9SNTn6B51WTqDvPBekJZfi5EXMrcOD5IKSyZM4hkqdlhY1QPk2/DRfBgfEHnqCPLrZPA7v2O3XIabQxr2hSNMkCB72XGOyTBPwRP5QHL+IVzKNCNWexB93QtYmaGi7U9ZySSW5AMuvh69ciXB6GzmyLyJZ888BNFgNsJn5hmBCXHWvmZ/bYfrndI+SRWbFSOjy4T/L96cPLEOeFsxtEgPAOgRL65o3zJJ5+AtaaUpoBXg7EpURd+9HEmdfReXeVVsgKMYTD4PLpn5VTuTeWHpm+NAoHHrZn20Ftd8dUTQtpV6A5ZMTcSM4B+x6NxL1q/bRovJyFZBrYkgl9UgspbZSOvQjwtiTZo4qWgHJWGs/gqZjPIkY4EJJCZ+S3m9NgQohiGyqegVoBxKeC0p61QAzdeTTY0Ir+6FXxAckLVFtnjgxEfO+Ksd3J2dnh6fHp6enw8Gu3v7x+filHPOW5IXj+czBfxtNz3Iz8wCrJqx09xnqmbotYtUQrzaUs2W4Uw0qq5N1u2RxEPMNI1gw56bJ9NRnAoTisLeByLBO5lXEGLkktV62zLCjAPQPZifQt7+FhWdsIMaHNqHfZtGrPDdnvsb6zX7f5ni3U79N//aalIZWxUz5htr8RpirkblohLwX28dewCv1hpO/LXdMXtifJjY82NjW7RR7qXtipY4eQeR8/Fx6QM6Pac+RIT3/wOMhEjQYk2yj0n7sC2ja6MlRA49cp/u1oz1gSnsXmC3+dOwJQ+xVXQ6VYD+9FQJDLS0O5HrYrAAcIfr9wmDVIODpF1mVjZFEjYcbmTSGx7ecZKJ0RoR/SVjGJAaUoG2EZpxhvibRLhApmZGK99qmpqlDzGRaYpfQZXWU7k87rMcr8f/jrXXiHKiX3YS/TRyHEpk0o/vHvZjvnYWqdjFXGsbYpjTQRT0MEs24aamSXMpDiXwiHOgJnuH9ogbzRENMSTJIJDsMNs2VYZRle5gz/jdxfU+2k2AsIJfV+gX7+tBhFUZ4l7/sAJg3gxsybCvsHNVw4ssilNw4UP2E/YyECnaLjsLOuojxVRs2sadgNLaqtG1uibnGoa2AucFJhKA3JKaLzmGqqhHfrLcmS9e+iri8i3Saxhep+qGH5h91JST5NkHj/d2ytcqLaOfepIFb9D+PGF853TSG2BN8gPNIIrXsK8apQqjYXzLJffMk0HmV2y2CGeayXdZsuR8UMoz8SQTYAADOCuxgeaCvNBdoYKtzN0/sUc8rGalJIBw2LZc/pKAeRRGDyGTukx6vuWqwUg9ZmXDOKpBY7vW8j1oA/Y++/P7XF0ekxAjEpEFqnv2YUZ1wspaGTTOj4swHBZbvHp6JiL0cHp4dGR2B+f7YveSdcVo8Pjg97B6KzbOz52HKcnjrKa9PGh/QaoFZfaxHIavoIysdKXXarMQ3yNu92uzJnyxmiXrGNQ33oAVDhaoMmsAGddNf35wvcHUjIcyEe+yDhTmyHEi2LODmBgRZMUYGhzu7nfbbKbvcOz4+Oc0WOVtSZeYgM9v4Q/f6qVHvX2myz13AUsHCcMfRaIWxXQll37UW9/hcVbETEgJurzWrh6DCZeMl2MICxzL01j1RUaYvcaV7dnORK1ZIEItthLwmhZSxRK1WRpixwB8OmFKtwJEuAx6bEiEWQidW7lsYjaEnTNtRawM/iXWkiv2+jy3vQ63U6vwKtqZqkAWgYjm+VSlV2wobngQ23AAFmfNss86YEfyFd3kDYb8LnXSFTCFOFY1YZpUHBkIL+mStauvczGN/IXxpOEYzldGW9uXkeOuJsoa8G66eWO+wE53KDmp0RoE7NY+DegEZ4HUpwANySLATh0KIKbIQujfjBU8xm2JDwXoqoTZFTMRmEy7bAPJI1g1ZZUJp2GsegHEiEw4wHUYSSIV0+R1ORRhjAoHLzTB/GqCek0wQBlFugi468b0z7bCLFqZ3OeeDL/2pVKdqOuii0L/Y19qf6t3iE1xR5NwOZmHekWlEy15vm6FkuSUyXZKR6NnQf9oOwQsSZnqPF2w9RRn8VCQMVVPBeOz4Ep3CgTUGxhXqbP9znBc/QDAugg+CkRs1313nkRGwIWLJ+IIWaCisB9giuBxatUqn6Qwp7EHfYmwFXGLZaEs1GchACw5ntj4SwdHzHJsKwgj0Q/CAkRocXikLL0fHP2u0OpciBAXj8YUv62F0zaCP01FtHwibT8EZBbhw1lY8LUG868CfHJeNgP4MvZIqF0Ww11BkgNtIMr7AUNMqAbPJjx+Y4qcmN1bcjHlD5gAgCwACCSJ4DWDopovc7hzBeDmQ1m6+0HApWTUACNUN4kxz/C9OrFSKVUFXt/r3+U/c/T8OPqvkEYh+fgXqkwENk1mIUAaGM395meRPpORVjQEeJsiMg4Qwk0GnXYK61eSl2SRQJDTB1d+EtQ/b/REv9Rn0mD2Omd3+OSPKX0EFo0Uf0bXlZ5JRndSLtZLCOJpM0RS13Wq9dQkyYaZMaXnwKQNDnvBJk6iBMxHxirAbSSJs1Jo7d1IDEmHKFsBU260w2wfvggCAcy3RuLJwBoyEwhE+WFPNBJ8UebXFe5x3HCA5dHrmmGNf+Y1iTTfxotENsW4ZNGGFN4ZcustR4ZPMvWkmMuFEJAfjLjc1lvl7LrHQLWlhGbNt5SB89FHQxAOjk+tN84+q0NtclBUpaXTrastLqBpJwh6a9/n96ODn7oXnz3zv919m1v9P1PE3EbTi6++/ZP8cvR7xff/eq7370Of/z+B9/5+8++c/BTfPHdzwvXu5384+Dd4Y/vvzl55p1PLp59s/z17+96zuxwMpr9fHDx7Q++c/DNzSh47f/4zL349Ze7eLT85u+jgx/iX5+9CH78KZxcfN/9cfzT3/6mhApYNs3ctmhFWfgiy25q84h9jzx3e7/zG079/pfkaKXhEnbO1pAHWU2zuUW28lttM902stZSEtyAMMWKAETw50LVEsmGLGoV4nJQiSS4n+mPmnfJQmw8YOdvL1gSXgtrYnUTq66cujWCJ9X/Gk5+zTk0CscqCXnapIVbCTSAqhw4nu+V1Y5YzGY8WqaaZVHmzHZBz3EEQbwBKGNerIQt9jacQ1U1IQEa9JtFv5tlTGQ5L7cf8MCQ8EZ+6Fx3cm+mFjDdCGaVnc3X/WAINHsqq38M069DpgJRCcJWZ1TGtOTVhcPs0AMqFldWteB5M9jmIkBIk93VL+7AavvIEVB/jVGJ7I2srJOLrNNx7KC55sSWOnNIYdofdQlPKy+U4qV5EejzFsE4IYISWJ0AG8ImlTYhUhkUHPJ/3xNGfQq6gSuJD7dQ/ctvPhlY1mI+gCtsFftVhTZT2GfxnFDHldFB9lInqN/HCXbu+ykOBDrCKGjfv+XLWNZmUjfJSquCSJIe8MizObwMh66yEJ4dnJ6Ik2O3nfp1O7NlO81XMX1oV418ZjoCIH0lco+dzS9W6Qojx9fWIbZ1iG0dYluH2NYhtnWIbR1iW4fY1iG2dYhtHWJbh9jWIbZ1iG0dYluH2NYhViJGldpVJArl1rCyNaxsDStbw8rWsLI1rGwNK1vDytawsjWsbA0rW8PK1rCyNaxsDStbw8rWsLKNNN5GGn+pkcYWC2D8DY9FGlRV86jlxdbcYYefmfxZAk4DZyMFB2QwcavEbnzq1pJ6q2XCmlHLBMPVhLp7SA7IyAJx6y91ELRJkfWf32YLkDNfE9+wejcLSDubAxPc0FnKDp5/y7Izeat+0gWZSEnf0FSqHsVNYuGUH7UvHxZnRY7XuK74qr6IG+q4uSNifbO8GurxbPLrmeP0vL8wW1xxay2TJMVkDYtblacNK77il6hKeIEuP9LpB/3gt+EA0NxEFA+vdpXp1RU3wocDF3dS0ytaYhVpgMl4Tps63pM97P3FWcRJOGvLfz8h/f234SASrheBZnOPQXQfe09QP4sVsxqJfqCSUrDoDgnR0liRro9MA8ZcSLfKCHnDRNwle4gkLU1ydQjZTcLIK/agdgSQ1AZznlheWCyAvhj5niOLSlFtjLF3xxaBiylSWLWaRgZFEQt7uVC7GKtfKx0f6yzLCsVQ8hiKOe4Nv4a/zMMAbEMRqC8xkmkK5QOh4loMH3UYJB3I443YjpxNIu4uuG9qodrYmRAsoACzWRh4Dvdp9A67hEIzPJhA0eUWG3tRrPClzRuUL7Inm/AEEQSr79eeGzrxXkaT27Pg1W66hOA0mfkDtENYITSfQ02umRcIgqDXxxOPayRuIw/4cThOa23Ccfr+8tXLKvXLUEYWSQiGMw+Gb8c+R1yxlAT235Vea/8VxVFLp1E4L/4VimDvlKBYBmEywGoYqxCIDiUJT1wfYp0DNeMJlgwl9kHHn/TlBBE6sWKgzsrBgaopeNg9bM/hnTXJhqsyK2PjP41PyXiC/2obCmEZJaJFMCDGN8CzT3TIYnGm1psCt6G6Z5yQSZETRMgEIUEK0uhCXxdBTUKzxK+kg+ZQHfadH47Y7l+lxVdMyLa8+x9PZJfISKhWOPCSd/hHvOCY4kRcVY7w1d5X0PVX/7H3VYedJ8wXHJBTA6jnHrR159CxLuah3v9WdgI0+JTfCDb1JrJqriNcacHjQbFLFArKMVYzkisYtXL5sqitxCbdZCYVQABfC5N81I5xeGvgrvKUu8YdRsmjwEko9wpUoT8W3g33BWVkDX/r7+z9tb9zNQQOijwSZykdW4r3oTABdSU94aM5L1f8Oqc5fbxCOeH3W4tacgnJuprUbDGHoJwFlq8cL3zlIJMroecW9QC4bxNATAVJZ8YDb5w1Cevrc9eORRB7sBemzHLPDOUKOUobnFRGmCFYxSL632yF1U+Tk9xI7Dvsnjojxx27h67LD497J2IsxofdUffQ7R2f8mKCpn22piN160d8GD9iowxxdVsfOD18NVegnJTFDyidDv1g6we8nx9wm7b/yGn70jDzADn7Wxfv47p4oQyZdDlJ+WgotfyhFJF2RWfSwV9W9g0/aehheQA4h/ciSe+sejd0cj4wtBzgg/pmKisJZgopsTAj0m8aFGLD/uzUlFfjzLbR5fNyZW/UbQtWuUvUEohjx+xLttFplA7JFkQ/+O09Kebn2Gb9wZ50Ko17n95GuHWzb93smwX0aoLDo9jj5kF45ty5hrAaV8xFAHYWz1prZyp0PZxgPmOylXQo3qLFLYgT7vuy6mLq+UTZUGkRptqEAear3C09guGcK05T3HEn0QSj+XGQtuPQv5GzS+c6IsOzXA8YO3itP+yw0zvp7O/XHL6USiWF1M0u/dAFO2q6Hz/EYVC5TMNUHoM1NkBjPRiSExGAACU76vwe19km/g8tqFd27i1TahU3w37+LQdukyFh60FINbLYfFr8qN+yAFKrPJhznyfwQuyRfrL3F/qhLbtCq8OTOmn/UyFSaYHwuRJc5YvNuO/xGJu3WOyBvRf/IrBkMZZFpwIo0JXukzPXG2OEZ2LZ1U0jXcn6MCsAXa0RtNjocH7SVNAqsK5qRC461A1ixZqY3Iz66o9XIpcmsVaFXCNb5LMokNskBEecjk+6Y3fknI5641F3dOq6ox4f946Pe6fHJ0enn6A+bmGamyiPa8YkNQxFojO90Ui10iU+WNXbexLz36HobflmfIqat/faoBVL3jY9dv/CFW8f7T58bgVvf8tVvF1FAM3c7T1orTN48R9/SfvGPzxZeysetprufWbwL1pM9xOwiC+hlu6jsYkvrJTuPe9wFM75hLjVPPQ9xyJJPaM4p5hNw1vmkSIj54b2uLuE7eI/KUV7jwiY8EQ8YdL+C+q2FzjhDCmt4u1g28lX5HZYH8NCwMGIulF/h03DIIzikhFTtyx3MCgh8Mi0xCHu0VOfQ58SQB9GcBwxT/o7bBGALcAjt5m/ZPRDyVgd9o50MYqTk7uSEk5hasBRGemDDK0oLxlDQrXXpby5R8p5foNhfYuSYMQ0mDClHLhwcDk7LRj5qkEgpiyprNLp0bw6KAvBvRQzMH+I1fIu5HK0XbJjk+qb+bAtmVH4Esis09KEjEg6laWtJJumKjVFYPdklsUjC95ND9jnpAE/9uI5REgOQP2J59wRg3CR4HlqliNinxDiMKiOKOKZqaGYHmq1hBGanVVp1apq5RjrqK1SMaSx61XEVcefLduqSVs32dGGkZrVSmpT3Y2HWr6cSVP1+B6zSXXnvCkppUZ2Pq3swSjsVdHUDAIA2uNs/ln0hTL5O3CKgMBsJBJE4dGqc/HBf46Rv9Vs5OXL98z4mqFSmjJTx5xYkYYgOIRxYt8hhCBTP+vsKrNDMwoMfvwTA3JrPRGpmdOMpSwzKz23Dn3/0wmTrSHun1mv130Gqr8EDQYzqWUzmeq9TFdnDt/Knyv7IaeYi4GEwFmRlefiVFQsoAcTB+tl6g9b9U40ZeS5GehmbCTgnMK7/Wk5+70nBKye+mjTpmyC4edmpTcIpZvH5P33mNgnegb+WAir4e8n/LtMgAWRSuZLxus+AziQzryt2WH8OM1+zUir999PmkqDGWxqqPqT02C42bKNXxXOg15OZriWheLWEyBF8/XFXDruv4FRywNOIGPoVzGJyTivNp978Z7qYE/22NZ/eNL8uFXvrloHTHwjfp1GnpNVRy1nAfp627b0Y9HJVGQf4IVUImCrWv8pPqOabVxRRC11ZI2npZ8e0IcDnf3VdCszPaEH8OgoQMBF5A/ixXjs3RVn9jYiJZSnOUqRxu+VuajKvw9SDqOO4G/gwbSs6DfV+sO7l6tcqwzf3FMmgr0nGf8wxgJiEiyozWGAFg6p+BvGvRbDaOKhGv2/aSX/08DRP+yAKQEzZcHIgM5cwzrCwltM07PuYQtyq3jkQkwY3KNbue1DbfCQ8xvCblM+WRwyysx1RBrwC2/vkhmEpNU5iwgMXzLPosPORzGFmJiZA5mJBqF9ptV3uUk8hMU5nV9lhUfCXNpGDsmKlt1NpwhbUVnB7MtdN4LTUHOIIfegnjE8xNFc6UQaqwBYssxxhBBoZBMf3r3c9NHMxfYUsWbXObAfEWHF5ji75BN7yHu9HJmBp9g/rI5DAhAUwSGbEUrtIRAASBUUvGO4PGb87oIGOG0Yd7pJ5Jh1dcZq+eLx0GJy3qQG1JTRaY1DmIz4IX+pYts2GNBUKmDJA23KOfn4lTRgp3BKMqFemVVnrN5mEJi80W0lMtWHg0nqD3Kxc8Xs46I8M4mECAaS/xqNqoCmTNwfPvfaCnzA2Oz6OYsoCptnnCrlE7Ok1H+v0VZmc1dLk1C32YEUbzh3af639dHLJZtLpw784wpPFKTmYRxug6A+2HUL4wwT7stAdkK8gD5TQVp65AQ9f17GumxxbWLItA0e6Rm9PAx+VYgscz4B7zMmq5JDWo5eP4aIBvZxXhdWAkl2OGrD/vchjy8Bsgwqaab65zfcQx8aLgvQnngAUWU8cqaAbspnAKZRN2Y3HXWujp8ljD0tmIBzwE9Vfh64+TBwAeYFKlE1GSGjMM+X1AFuqQtk3Ier8ns5m23vJN7JzZGzPeaeD9UYViBrKqfAdXfFztOTbvdAjwm3I8TQcKGv94d3FzsfQV7xAi0ENXO1lu1POomr1TuSycaWNUsyW93WD7rLUluX4+O/VtpnvajSDYfFtMtX/m93idY+Bpu4fZS0ahu6UY0FC180R9rCx23h47bwcVv4uC183BY+bgsft4WP+wLg47KyS3v/IV/Oh3+blWhhf5old0bezZn6luqU7KrMZSpdpEKsjChmnFP6Atdg3OxBivko5JG799d+8Pf2t2AoaL8haLen7PmL1/8AaU+KVPDNOe51W8Zct899P7xtv4m8iRc8ZX+F65FKSo3Wlz5cuRXOwXOQ/or+xfBuiVwqNq4MLhjtQsGkbrnjMGR7Ix6xg26vH+wF4AT6K9sb+eFk72kMYcNYmmwrO21lp83LThuXjb5AQWgNuadEyNkKNVuhZjWhprWDvHhAl923ZBLpuanTXkgKosshqPgkXQyCk5GpasTtEUxGrh7po1hn9tIQLUhIT1kNdlVD3CbmrDyOw2cr1MnQtwEcTluioCq0g2fOD29NcuCVns0WAUXT43XTeTQ2Scz1oPMZuHzCiDzv87lkm9xriJ07uPYCd8AhpoB7A/KyrNhUtTJ6SAPT1uvLaA86H/eXiedAVM3EC1bsMt+4tQPYUmOOQt0qHelWadmKVZpTk9bOKApvY0ANWaGxatPacXsrNXQBBRGwUwcjPxyt1lS3ssUbrtZVsXk+SHHdnss6ae0gYPLUm6/Un27U2pku5yJC8NiVejCatXa8GTkIVmgvm0Bu+1REXrJaY9mmtQOwWCs1xQatnev9lVpd70ObmzV3L9MQnAmux1fqgFooNwSyvpVaq1atnVnixwMjRWW1jvKNWztzby58kFNX6ihthUBiXjAAY/xqXaTNZNjvSs2pRWsn2h+MFs61WG3wtFVrB5K8EbJrtR50KxBxnEgkg2uxXKkLo5nuY2Uymu1UL/EAkMSF/G2N7nIdQL+BqwoJrNSbbkaCoLfixVNtWjuwwNXfhrRVa+dGOEkYeX+uNoO0FfSAYvBA4Xyv2FGucWvnZu4MApHA56t1ZbSjXtahrdmutXPL45nGiF6hF7MdiZdjP7xdrQvV6KM22i1fY1AiSZIfV8UfzkuMTYGHS8TF+zUfmHloa3SUMv/15pEXK9frRcuU6zUnmXKttkqkXKux21uznZYp12telCPX66dMalyrN0PiW6u9EtrWazyTISVrtEWRb62WGcFtzesHktt6TfPS1lq9GHLSeu21qLYeBffXaydTCtdpmopW6zXXst1azU2Bas0OtNCzZnt6k9dqnAo8azVPpZ01m+dknHvsQE4GXasnrSXf5ySAfL5We0OuWae1IVittxmGfLd2B0rM/HhlMR4q+ao2dlGlmKwyBWyjjeQ2nyAML2O7qTAM1Yad6lRhZV61V+BQniHPHuZhx+DGXipooQ2TdSRB3O6gFBvhUlY5azvTMEYgcfqckEPYK3BVIAwRuASV+xAqWjBoSZNDwGaaTwsciElL5reQY4Mw1hm6J/Z+D0foyib3gBys2sOURgK2wZdbkghyn603jDVldQUIJIK8BpJCIwHFlMHz1GHPyQOKbqi+8of2dwAKWNbD6jDCpQFXPlSUc8PgK3Lh6u4J+TqmtDpolnOClJNoHoXughJXSmAAH/xwqwO56hlv5U5o/ZkfZLbr4RhCzakwb016QgrXZiTGYSTU1Wm32S8SZ16iz8UMXcZpbWkFEc1kfD7bfbfPSNAAf2ciouAJ3T7zoKUz8MweCeGFHOuQRoi+boBGk0la4AWNOARsjCGAgaNfiO0+e/fhOfsvlWLyX3ipn0gfjb4AOjgmMe/Il3JQjVO0+pE12pYe14KPpjYLjicckgtra5vIDxHyD4iSQc60gceHMzFQvW+eez74luUpufp+qcWX71bqAXtElnKuZmFcZ8BHjfPgZcp5rtHpFU4jcZ6RYPvt4wO4thF3IDesZYYs8ICdv392ccG4P5/yABI9PSf9uKVigihTu+rTuMXcMIlbFB8VO2EkZDms6XI+FYH8BwY8ELykTJzm8gNiZOlqdZxKIGjNI6Frr0pOqo6OVxenMxFBghng2p2S5mEfH2QykvYfiRnpU/cwLEgng3zBUjOtYWOSs3Y2f8lEUYvYGFXAid7kecLgyWalk5/3mGrR+KG6k//Ttvwv9T8lD9ijT6pBZZVs3KNqANACaf4kFglUzgmsHYJVQyJBmUsQQmVsxLCz85k/3m5vzedaHbXyM5sGcTzkXZ7zqIFIhuHNuVBarNCrQkoZoDdIqGcJRzNUgGNSi46XQcLvhgqBoxb9Qpa4G3mPJUunO7BeZaHspiOhy3fbEnDziJJacD+wYDPIw1peRmKXWUBaFBjzbcN8BMQHsETrv+UxGGAIbQSTHhSuy3O1njQMD/6sR1Z/nkbhYjKV5fQsIAT3hoPRvdbYh6RdRcEGrosCo4/eBqieVk8vdvZC/waklVGgIQn0YelAlSgoIrjxojBQVfby4+kfFWXXHEZ7/6t2ba2+CSjiwRlWkYk8iOBdHslXi6ECEL0VplpdLQM/zLChLFRr9ZV5tZRfv1HT2HSShp1fFxdUZJ423FkZdW5YXNeAY1/j6iDJi9eHPsGlNRYjay1fG3mtpHDepA+zjZKTm9zVex4Mg3Z2esu9lsViLBjEUDF87AWQN+GNIb0KsgzuwC7KfY1L2RBBDKt2V5R6u+diH5yhlTGajWmGadBwHevi83kNJPG3si9I/zPuDQrDqg4JjMcEpLA1wErm83m7t39weHR8cor/kftf8Pezbm8/a/vp7Z9+eUZQvQ+rP1hyY0q32IzrrvUmNlKzv9c9quoLWJq5Iac8OhmddE+Ox0enI3G4f9g72z85HnePTvnp2fFp7/TkCzRhGyRewz9WsXcqnv5LtmbJNWyMZek8gaZEqVbvZHdggKZRakSrfwy+uXj9/OL1d2W6ne9WvH6h79aMzi7GTOampXRWKWrKToTK3FANNUS7Ef2X8teJ27Q288UYbe72Xq+FmKdpxji3kUhuwSql0pRrKfLm5fMaqjz4IZOHogRpQwUU1fC3XM1m0t+w48yEgPrg2fB0LesUSvvieYvJXnwvERH3WX8HSlrF4MY1OtT6eB45FBL2hKs6bMms9Blf4iaOSGhSZYaNAtyZEAU1ojRMpc6kGFG21GxF4KKmGssM+OGechzv/VP+18BzP2p4JvV//ykzeuE3dUqG0vyVIUaHEeysHsgsYyNFQZmjCJ4k+RfVnn5pqY7RX2VQkzK+UWo0x5SJuwDZBVnuRyfV55e6y6S56z9thmNRblIdu1JfZU/nD+/fvCZTYxJCTILNNmHKsDxYfhFPJq529ceSmpUR+toCLnLOftyHLGTBZymPPdeQm3imIPJBnvsMoviP+/WmoPsQmaZVJlNzY+bhbZBW81GY2sQEsvnJ1We9q8VmPnJcMc7/+5G49/X+GkdBEq/8MNx8cmPyfdXzT0Hqm81YxypVDpnY+CVLrbSEjQmtRsLmI7o1XqlZmOa4TRm4Hn5HFAkfxKhbTIitNebWFQ4sKM5m8cCmdBfj28V+cBy3/zg+c9v719FZu3d6+Hv78Kx3IE6nB2e96+MvUGUukHv1Tc0X2CvbWSM1+UE9yXKYavfJW/lV4/2HMhGq58e5eCn9Vt8jPfXy3THSvh/0wZAjFKmENZ8J06sgY1s25Hvh+2EL3F+++x+PtSUp0VbfE2pWth8yhf4ht6Jp0Tms8bfKRVHJYg9OfxpoddIbKy/dAAOJoG4T6LsSSqZh5StQMNpva0AD28H+fRF5sevpIhpFAv9mftIE+jna39OVRvZA0237IcVN7f3F7IsjxnkS0b/iJ+qU6HXWvKMLY//wH2PhRnw2T/+rDXhcUAWlhNN93i9qem5WP5fmQSo/mCnAxafUpuqEKpgWw3mtIdWC/lsWDeHRN7YdM8Ysq/1ZQhlNwGKn1N+uBhPDuiMi8kLXhMa0FuKwr2DmJd4E5zWAnK5wYRn4uQJFxSKIThi4cYrgieZJ3Qnj5Ojh40Ri7hlkQCetI4QLqVA/c99z6UklmL0u23W9GA0rT1qs10Ub6WzhJ97cJ7TG4y5boNfw9Piw200D3ScYHR4RMF4YAd6ccgMLSR0CQwTQvD9FFGYg3L0gEZMstY5LiEV92XdGjpOSqLPGELkLqEBf5LhXn4JD6At8T8VfX45SXmFC2dR6lv1JGHnJ1AYgp35qx3PhgLDPrsXSjEdjv70UPArYLIyE5bXpzMI/Pd/nnTCa7Img/eE9oZr+IkZ7528v9t4vRokvnkXLeRLueTOIvvlRLP+ip/TEbm8tHh9V1qtwv8B0Sz8qhnUtlg80bRqnBkg34reZMwH/ml878Sls6/wagPF+v70uewGvxXIAsbvHh8W1foN/b4sAase4uFPwnnfYO3msIKBjSJPE4oN9GL6/02J9mgH8ZxixPs6jv2NbB+K7Zkul5fEJaZKwhsIMf5RTgqv8G5rWfxEj9qNYbm4PwEI9uBUjOPtP5M5XUeD32+vMSvUpa7TSz1kgMXhAyWFaxPZKVYhMLVwG24BPT5zWY3y423Mtlh9wQpVlnLUIGTjQAfqN1H/F3iQgfCdvvMRfICbgR5H+9zceYiLeRnxOf14E6r+v8pTMFo4sjmcjaqPqhpWMXjKylsGW9UbVsfvH1OJpCivo8a+Wsk2n6WX7RBfmQdR6O6LbQ26VXE29mi93TgMGh1FthH2KKGeV3HGN1cFq+E0+pSM9D+WDn0KN9YPTk173VByejcTp0fHxWe/47OTsQJyM3P1HsghZ93cdp5okXXb/Ko5VCuhXL+chVx+4Ik4Awxf0Elkr2fYIvJQlHWUzZjRjulkVp9aVVhVyYBV7hXT/3v/KP4BdArmeiPYzfyt5x9TKgBoiWmVR1OJzW49lhyySbXE/dAANzrCy+q1aQ3qxYHa5CX9pJhjjNmzMc2gkZTxMTkrCo4lIGoUPvFp+j6AW9mLMNcH2b2TgdCbi3hubae+LxPO9P8EgEKwCNJEG7jxoFH5tekyaUNXU3Foemf5JTiutZ41XQrUsO7QGyurnmbyJPp+HT95M7spklIfe3HQHHj5500DErYercsVdA5nwZ9Ulwxar3Cls0C5NFvy8X5CUlOsALWnaVmxVHnr4Sw7SKaxmY69uBlK5PmsCfBKJpSiJKr3yHU/ELV8y9aUWlHREojQQxUyOOvAUPkp/xxn3nso/y6hXhwcyGNgJZyNIlpIGkkUQCB/aQh2cAPIJfc/xEtnJTSCSp//94cPF8/8BTCk9UsZmXjQbLwJwH7RRsGkjUsxD+MfS6TTx+sivTcbAPsRFaiUhiwUYQczIya8wxwxkBnbjRQl4FFR/PGFyvdIUWaRb2qVJ4XxHFRA+8J2/BH+Jv4ghiya7dyW7kSZEpwsse1xUV0VKwiIUDZ9pRyy7xBYZapbNs/bYpPlbI8fFZC1M4DrrinF7MvV+b1/7syCc/xHFyeLmkZ5H835vlGk0Ftc3IIk2vCo/v33GlDjT9B39TK0cJoXXFlsrg8Uy+PWfp+z6ixidx7GYjfylLHz9CSRZoMsjbbq5JQ8vzGq03Xsl8z8r5O//IvvtsPdUwxwzD4wycaYuDB8a6fCU89ykXJ/UKVUZhHsxmapM7veUqEMp8rCpjirdl12rTD1LS+G5RpqSsSoC1my8tEc6iGp4dXjgHw2UGb2jK1oGaBcrz3J2FrZDbZ/eOfuB33C5izc88jAZBrczL5rWzPQb+qxkS3KzqbCIqi9keVxZSFaZpdg/wgUm242BfuD3Y3wULpK0GWCrLiIGjr6nrD7qTGWyZcJ39igkhUdJm1LP2kqz2PuLGqjKQrvKNcOKeRmbrXpPIKPyxeufBz+fv1NuHfR5yGovcnATz9/cdweIJ1EKLOSGopjcZ8/gq1+ywUt65xXNscQh9Id4jEDiVj/AuBufJ2DJpVtDpWw5Gxok5vP5kP0J9TFznfaDczaEJTyVD9KQoeFSyctDgkCJh2zG57jj4Y2IIs8VyC76ATn4sIQzo7qjLLV8ZiTSMrYdhXGsFWEkV5FMv0wF5i06dBTTyr5YNHTKwZXPsSdl9ZMd9gM6ObFMEEUYbFfMwc5PCCNDmWE27LCLhCChE77E0pX94HaKD75B8/G4xWIZ7qTjJFm8iG68G6iLuohAMOgHqk04HqOKOOLONQuDDEUq6k1mq87bjbs47WpayVmbSXR2vI57TAUcLq7rkTX5rbG3soXJLdWkMzckdMWAEMwHcQJBURNU3S3O9LReUOWI2QM2C10bx8WIuhzYCUxFgqnHzJth0lEi/GV1Pr38bOcq/zbgyEXkq9Zq0+d3A1f43GLOeC/o0ZzxO2+2mDGKRYRDbYQO3nJPw2JDYWQlttIyJVeRqOktmcxMurjqFkfHEEQv8yDr0Ef54c5TDBZEqFf6N/y3jCqEfet2ut1evmI1BEbadwgLlEKQ400elQYXNvVGAEKTCLU6XJFcnhfhZlaiucDtjfAwNtu37KGdzXniER4NPAWWBTyHucHz4shpoWcHvIxU5Thrk4iVoaPDvuHO9S2P3Jhq5uJAPigfdyJWsZbyYzYOgUy0asDqodKtvo9yHh+PydTSEKJnv7vfa3fh/192u0/x//9aI0lkCQG4KUVCABINiXhCGuDCiMkAVHipdDChgqUpIUzl3IPQFb+r+aw8acvTjPg55rSNWWPqGGA2yxnHpXv5QaJJyy4Wc1kEWTcMIxbO8SzAfy3wTdIEofrwhNFMifpYERlf98IJHN5XFrLsZdaLnaXxlfE6/HbVKNQpuwU+3AYl2hH0cFs97Q0crIAo0HhtEvMVyiXt6P9eo60s5lz+7MIpAEwHB8D7b3lslH9u8t5K7gT/wHLtIkb61qIV2IpRn4O9lOgMotAO++GXS4lfIYEyIuEKAQgmGLNNVRGgPHhOimpaiDrHRxWtWmqvDNJnmSkqqwBgYa1b/Uz9bhGQeZGxrWEfeE8GZKJNXihA20FMVoKJkOxUz1krSA2hF7MkMiZlpUiFhpZ+U6KjPUs/QMFdGjjMj21LpQQA480oWjrW5C6ZXc7pWubuFAATP67MXTBNQfEUyWFiEcNhbsvzUXunVBl228VSv7Hd3+Y8mV49Zf+c8njaYrH3p/j4BLWlcCwrvEP4I06hw85j8lLgwltsuAc1dvamkMPYxhTGzjSZ+UN2i6eNoGwwewNGwWBbyzm3S5MNeZtcSBsVuZ3CHdZEuGpK3i0HX4uDU86XZVqY4KSSkJKQzfi1SI8Uo02oupy24FyKesOmFIKEsgWIFoI7UzUeI/2XRpLGp4pu0ToO1yDXJfKSsqTAj4WJN7rpjT4qeRXhGaSQZMaxfM8UfDRO+qjoBRep+yDvH5XcGNhyOFE9SwygTh6rEh2VAX0gELZBBM0J+L0Ti4AfCe5mo60rZOdFFIc20OY5/wNDva+xrlmq9YClJIy9RKNe0yubhPiCecFCkPQhz5xqE0BIkDyokXDCCGw455IbplYnxHHAKSmZJhzhM+OmkF70e8xCCWlKBKWLOQBQboD1WTggj1frGOfwP68X0+evT97/zp3L4P3P8fPFwS+/9F7exMmxe/fDd5e/v/vH0TfTu7d/d8fHL48Xl87cHbz+Ofl9GvR6bz78413884vl9V344fbb9g8/fTh0g+Oflv6v73+8fPPD4ruuF7iRGwxe+d/PX71L4rvJ33+P2+/eut//4+Ln2UHovhgsbl78NHAvf/ru29lp6F3/+iqcBvHB4fOX30yin+aO+QoSIJEK/6uJBoYIBl5ipXwlza4Z2SHFPYMR6uUvZeLV1Rfyo3y/mHF4PriLMon8ThqWc6Oxy2gRoNcJptLrdrtstESrzZiBm6ZO031ORb9Giwmo1Z0cZGm3LIVTrSGJvMlERMIdjCx2mTcqT0b6NdTHdBh16bFxOQktMzY2M39hkfEAGwujQvB3eahvk0tfZpvLyefTMIzxFtP7qfJVG1rXUK8GYwzQY1ZlkVJTMI1RllSRCrthM0HVsmiw2smXHexXV3kzltValGXsjXh1k12hOIPS7hYLTBho0hO532y9mbC/XtPeSk/Ie7VxwLKjcEFcPuJjMHJIwz1hNMZJiqIYd9hwLiKAYuQTMWTx3PdAXtHt4FXAnkISW2S7r+JMu0rkDv1ZDValTV7M6MhxxkBDxjiDX72A+ckHCAt0qapfnA1TOMwhw4AgcBjwzBq+Zuk/YkUxkE9DaRDFPpMw4T5www67kP4bZzxkz15etNicSxqDrAP+OpC2QP4BrxDmXupcrWG7rVEkW0x4eKu9AIBjWriD8nCYH7Kvfvtn3wD27O887e909w9Er3s0bu/zw/324fh01OY9p9c+ORgf831+0HW64/5Oq29sQx/Z78err4YY8IVvOKf5oXiJMU/muP+rDwukelbawHKlOtKtL5br0L8hm5YHDkI3FOyfF1uMIyVgANo+3staxztgDb8HPmqYidb/udxWk2cNtWYJYwKt3B3JOzMyWrxJU1ysuZJGx0Hq+jXzo4woYl4G3zFua4b5msJ2sVRCw5ABsKPA4X8rva3xOqVoGhdK0NPNYs67Ao2mA3LL2pSbofwEUIhnozgJA/GURSLBaFZyW0onsXANhA7lGuwHZO9CFgT8BTD/Y5k4Dkoe/TyTeBB8FIMfVYnayt0KJTPgtYdegpAh7n+umKJCzQQkXQVNjz3oObWo3a0XmyC74M8klFmAtnitOseyvegP7gcymwtAeMn0iW7fKBJ4Oka+aOKXjhOrU+dSEZVkOyI2Ebb6FGivE+5OBcDEKx5dx8RhyBUPOmpelqL9b1CsQFm7rlby0+r0Q/Jrlh5HcTcHxTuYDJKIB/FYRKUn8zLNbYohfAARVZPbsD2fYn042Z7tDnHUp/1Ad95WPw6fwJ46ENIQq5ihNGaJvkd7BuA3ezdwFCxHXB5hrR4O9dzhT0Nl7sSAgX4ABX6ZDz5I3I0WOdbMy6VjXiCcyb8RZq2mfkBc6iuzyCj4hnxS6in8yQlnM7hlslinnlAk3GE/0EN12BASQlEWgpuVnzgEQ6hd/JoNJTr5IAmH/SDzfUR/xQa4HHlhmoRrKCtuNcNMzeO7Lm2Yqy4+cYiv4n4wVOE8ndSWPXxCGwvxEvIW5I5+GFDVmn6gz0wsksQXsUK6QUt3GKS7BqpCTXD0bNlOl5YvYPGxVcoO6k901SUtHnG8bXKXm1o36coNVCvgLObBKLEB0tEz4v2Mi5PlZxJhXWIA9QOVGg5tFBuH81V83CgS9i7psLeRwJcCQnJAl6C3dGi54013jBaQ5uwVtuwLYa/pduf3rZrxlrz/fjFcQi5Hs1ZlQBxmtGsqc94PdDQZ1jU3QsqyZwKseV4UK9jrFpvB1oNmn/SDMGDxYhSDRU8DY8vqxAG8wmy2SNAMgKo/PaFeQlsBd6kfCApdwDsFokQbLzX5w00+iNKAjeW1+kGR35UwTYMHwrqI3/cDPB9fBFMko0k/0DUl0n0yfZVtGX9lY5S03IfjlC+RGdO9Yq84uiKlkefrTBjyUJ1O2/VLc4vlV8aVVH/ZDAf9/JkHzbWWSQwwnjiwuZbOg4KRTrIKWt2uDA3Nznf4pCUtEChqM98bC2fp+IDiAZea9ARVmIsR0xmShC5TtWJ6wOXM4DqQgU/v/ZOvKS9YS9vUNdvV6g3cb3ndh62syPQELzrZk24M0ZLEz36wa3t2niAnQM3Ex+pm4NmRa0HFPyLfA0yDwm7FHXcSsMu0cXJygZQBSJb0r5VaAgxG2rYwaCFdOslsUp3Bm7easdL+LoC1co3WOe1yzV4UE75fLybvvl9P5UrKx4rLk1uFTdNWxy+raaNBukLV/koqIKTpKjXEizFmAEDagAcaD5k8glJTIO2bLzFKGUUxVLTdRaQcZxFEBC4SdusFbnjLdnmAhWfhDHr0Hghiu086/UA/pC2LdlD/WjZ5HNOl2AVRE0gmrbMpxU3XG8PN1bqaSYZ+sEvRr0g2uvTKLqHfV67Vt92UuRB7ywqymUj3DvsFdhGFjqdSZJlLCdYL2HcvLkGKlUHodQ/ma3H7mrJE8mXxcr6LCjUja3UgkuYkMnWuKiEnaS++JOtDyzxAFffVwi9sd9Z8J4znZVepQxWK3JOn/WDKIawayr9EWFtR1U622tTAERaQeUqqWV5AT4epOrWwBZqV81eQrr60muDRnnK0avigQi3TslOcpG9gAaUq1dJkJMrMpzgJW5mRoGVEcxJmMhKDeVUxkdRQtzFznBoor6wUdqISqyPdBLoomU2pZ2JmCp0Gzi3RmY3jUK49s90wYqMQkr3DQJuQgX0/AynMYlQ2CJERMEy21g9sfI01Zmt0LMv0bxtz+2I4Tm7HTa6TJjfVpXaV5nTpRClb4pXKm0InuN6aRKddpRmdCGMwwfyxfjDMTKajcpqkzZMnRueYv6QjfCFoBpKWjIylQPYKqcuQp4ml3sy0LghT12X1yKreyKR+r5QlgzoNgvA2n6YkgpvixL+pypJsgVhCjF2ltRJPGCqL8RCoHoHSnTIHYLHgrUMcN4wWJU9tONa+XtpQ7kylCAlhE7Hwb4Q0sXBVqg93F8LcZObfTG0askL7lmlC/tNMfIQIgQaZj6VEbqiGBze5hMzsBmR/tDzvZgZimsIY3Eih7jyQP01D0Mo0zed8CeTqB0Rw+gZyA/VGoWlexSHJ2p7ycC9bbCQcvogFMXMlxkOWj+8ZUlqHvRdC94lrGOoYNj2FcEyxDOrIQK50k8v1YNnWKchbutErXTC6kQV2m7tcj4FUV+V4FYktlel7HsMtl0+8xHloqdDDRazScy7G7ddhINqv0D88FRxgJTHMUWWp1ZTH4GdHvYN9p3d0crB/2Nt39/ed3uHJ8ZifHoz3T3gxBsyYOZl96OFpfksM9cfgXNIehHxml/eDIVE8RTAcGkpbq/hwmz+GUT8YSlPPMJeJbGAA0ZBkjqY3ctgPXA/WMAMZK4xMKxJLwnnbh8RySASG93RYfFC1cRMFXuC5S0ZP5jD7QLdkyPMwZ/JKOwB5aryI8L2KxNgzCkHaTV79wGLe6rDLCtNWalrIWbFBdb2bI7YnSJwQtAqqbWqBSyG6+wHpwGjH8pdf2xUDLzbsZDlfVupgs1vBWNYItgs71aLVPFFLb2QNY+XGsMy2U1LGfC7r9uUkvnUMZaltVF2fum5kpV1tkVJcePmaUlfwSn9c1YqX7/Uetr90SRnrVs7CbS08Ylxb+R16HETggn73BxRQ1icGQrJnM0ijd0EzhIcr8JdPVAPcWKh6rVUSCObzxYQ7y/b1DXajcXHQDTEG7sAlv7idQkBpqs4ohVfceZAFwWP2489tHMr9Osu++gFCeyjVxsBDgNmYM0jDNSrh1mjdO60d3XSnSNdYctvBjM8ttE0vomRucY772RluR/4qPVEkeys+tJvVHp5IroZMrah0gGiS0QI6BQ0r12/e5t8P4HZyPw5178JlUxFRlI8LcPrGjsH5CBzP96gQDztP+gGW1u51u2qsr43XgRgrT6j+dm//FHx9EXewqkidoHruzjwMsdXwEVrVyKie6o5/bO08Aw2cHHb6TqR7LT/PcZiPrZ03vmu0NE2bukdtxNPWtor+tD/LNnfUTIqTv6+QnREPPqLibvYC4ZfF853dzwEmtFTIFiM/dK5BtMy2ozLgAK8IOmfq/rw5pF/gpBNEjKqADt7QjisS7vnxUGEkq0uU7bwfjLnnQ/44FRvfRYNWr9s97O4/6bBz38d3Skb/0KfKPgL9CbDGhBNURUFJhr/AjTSM0k18wfC1XRBPO6JV4CyBEUKGgzUzqmmuBMAe8iBf8yrtp7qI12W5BVNPMxI+vflQaxHkWAzBd2D0+ohTjN4krBTQfGhsC5HeGHGCcT5QkN4EHWyFJ4zciFroYbuiM+lABFUxCJIaKB6LHj6/H6junmS2thA5nCMownGJgEdeuNqtK9wj3Q0mJk4mYEa0pYGdq3JfuN1TeAgwlB4jzpTBFndKbY8qqW45D7Yc5B1jSem5s710Nk4wMJM+i4dLXW+mb3ekGACGvH1/efmWHXa7NHXYLKhHFkIsp3bkpAqKeqngCuf5yy6NAze/H+irf5lRE+iToVzjkPHJJBITLdFqHqH5CQoc0+yNm0dhLL6WtStk8phr8Betz0P8Bdp4kNkNKRPwt6tOhrGtz27SHNpmUe+OxFqRX1vKpRHVtABE/7yqYkbnioAtKiLXpkyBHMXixWzGya4CwtmyH6TUyu2ipLtNMMN5NAFKlqS15qIUt8s+gVjtSz8o35i1kuErn9VCIqlaSwGpBncz3RlJm2KU/j1TpstzmKtSorK51uUWW2mAlV3hvwoLrUql1fNrwK3AumoTW8CxUiazoNNLetBekMMLmW+ccF8Y4bkx2+UsCNvhnOQUnQFErmmU+NNvKYXN7Qe6lFbGxR8nAOKjvHLo6JawQcJlUFix7Ya3iDHTD5Sjbs4TeNeebFZMSZf/BcgqOM3Hl1VQ2aItNHIbJB4TbDp56tm5e+PFYbR8Ks1OcAzFbJ4sc9FPHhlNlmCe4WM8dCwSs/BGsP/v//6/COOCuRHJVMRptgqeLCM6vY2aHwyPkZuPLvJsVA4hZatCJZEXzha2U5+8XB5HHUbexAOjnwwheGK+E1a0gxIXMtgnjKu3a7rRLTUk89TDGWLvjYilGHrubUzf6FvlJHAt1osch3QxllTmDymokzTim4JMJRAj3Q2dK8kDQ7JDDtzpB++y3XMw9YZBicXi65wfNTXVmj538Mq4IaHf8ijxHG+O8HcvQBSRLjZgb/4tX8b9QHled+dhDClDS4bX8gn4Th3fg/OORn8vEVh1dxEA4J7UyX0IGn4mv5LAQfEiGgOXGt5yRIiM0X8082Cy/rIFIT2o7wK3HTKe9AMIjYgYMDoC5CLfHnjzhnj10fQnlzoECRXW2t8B/sCSECRnUIEodGoJWKyk8fd3UH1oBs1JAbUVcMpkyCJEB541+CFUhcGqqzIzi0db5UlVjp03E8KIsiFI0lY9cLVp2OWF16a0oN9HtJ6hUGC88y2Di2effMs7/0S6CCuEl+GDyZ64VOIqudNl4ROmqGLuRbpYLTEE4S2JSnh+9fNlHs+UA+wG+LBJeHXjIZYut9UVdWWEsyKAlrwH90YVrn6jPpoZOgBFqxwa2RxkCD5r99LwZbi2scRCEW6uXhh4bR5o1oWpfswGRVnuKOazwS0sibeL2S7G1rX3K4u7bmDSOFkCc2jETOyyJTAWSllBLX7uZ7M8GxxDxfZrmIn6rJoRyK/uDfhY3b3SQ7PADxmJTedgKAqnjLtlmr+Nw2I5+gZ1JMe1MaEGYo0poeaVfugLkpQgwkik2kjCJ7IM0HiJG4BPWd6wrDpmFD5Acosyt9HcMSDKVBWVADCDOO1RxAMAgJB6IUEteEGcCI6xGXMexRi9qaxS1U4phCiRkHkhYBgpitAbrk6w/GTmxdA5Rl8quz9gu6DHSroDZDfSoCB/0wDXMEyAzjcBgW9SUA+j+ZTDMOaQZmK79KwMYBkwCwxSBY0rEmKQeALshlRnaaBdL16ADmblCwWJVjINmZ4gF4UPpzHlwmfS3jsYLQfK3pvi3pvfp3L2IHScxdzLn1l1UJFI43AR5H8nHqzoXPqjWj6yvgEMra8C6Q5GD+XfpPpx5ddyWCKWsUH2r/k4EdGA8pBrpuouUJnGzSof1wssSAuV6yprYdJyhU9r5pGiUS60jTk975kP0nuWdbhnPrr1IgzqAj0gpnuS+V3hYOf6iE1+mH495xFA8BobUf/RAODzcQMzp9t+W1AgG+ivzAFkCvBA+twHUmq1feKAKW8x12C+TXi0fpjLNXWnTnzQ0oP89Em9Al9h74rzwiypqPDmG8NbdXmcRgnWgRLb8JsOe7aIItT1pI6JCM60TDtCUVpgTH2XeQDU364qTAqWqHRcGojk4W0+pbe5pygJ1U1eZcfLRV2983ObzFsl8oLJlbJXy/Me7msPlYHuOJxxSDgg60scq5JE/4+tCsNRNgE/m6+ACO4jYZ4/SsJvvEWFBPIaWW9Fm7hsBp58QkV6CjgvSkzqB/NwvpBGWJB3yL6ShC6HpNJS6QXCgvqBNJVg7hYKVJhD0kisobgiSNOJXJLPnqSCmLLEoMat7DE8WGrlHe8Gn88FL4mNXteELqm1cfu5Sj9Su7Fpc7qa930N6p+J5XjK4wEBupanIKSJEaqCVgECttyFVRVPDINT1bSVRpdN7j28p2HDiqOnkGLVD5HC7zoUjhifcvfM4Qc9fnpwsu92nYOjg2wS0MF+9Yx8DzBvbEABiIWjUSTLi9aU3cv5YlAGUcxn6J8Jx+zZ2w8MK2iYSOcqX8IL2MzzfU/WUTHGtDjMj0rAQuPFSOE2l1j803ot6aeF+SDe8xyjjfGL6smUYZeamRR+OJkv4mn5MXxJH2CsJ4VpFMtRNTmQTeoYlQCR1/r3AWfaTlZEoDYKNlrZYizrY1veZShzbdZ79ALClrUQPs+IcFKyc5PzmM73e8ZpaPhA2GkwlIfOAjIiiEUuIgv4a/ZxKZIiDwJaQnHyHkY2+1ZNXEIhIKG1swi8PxbighavSlppJMEM7bxJJPl/IuZNAj8IxEAWM7BJNr4qoSDrHaTm6JyLKY1ezotfNSa/krNeSIkMxO2KEyWb26NMlGw0m54vOkPe//TSk96Azc9dGXhWmDhOqnzOpCAKDB3FvpvDjiqFIL+Uehxjreit0fRj/gZaCWXaTxoQK00yhreh+kQyLrEcwKsqXzcsnY6SMmZN0n+6MqdGgegWnpuHpC+qErTYz3OPPloZY8InA+1/jutZJFxma3rbJZ9QPfVEOZRR8E+YHgsM5tVS4s1+U0qFvls+jYUsnHUjIm+8ZHwC4nBSOqeCmAi1bpOpWDI3DL5KCB+hZWBtZXBEqxfUa7h/5t6ELgjUzWs6+BxWJFs9TmWHtNpq4QaURcV4Vm3m3MhZlvoL2w3HiQjMMrfY+AlY8OaRF2fKTikEzvOE+QIIAzY/WVtbIbyoCA1gItpuqxMKZrpiQcyG4E6WutcQvDTDUeguwXyaDCFMACaC0Tr/PYr2/uctBXwILJ8kgqR9uZyL3RjhoZ6yodR8YaV7v/MbTlP9L9k7oOiIu8T+i72ppY3+0117vkymYVD4Q1sKWyD45buG+ty6Aebs5r8InQTsWUkk+Cz/m0RVnPF5pXdRn0bI7ouWNgm7UYUWtU/FQwSQ320RgCTpGtupi0FooGHYR8IrTnXnNPmpXl1MLQJNTBOy5tE+TN6sorxCrWEMqdVH0OIQNiAD9SpREymW9pYchPIetMYC6UF4nzDLMqCaDJgmNxaJMx1CAHYAGbYXVKcFqzBWV6avZpHUpPM7Lq2Ai9Go6EKm0ZdReuLRykpYi4+uXuERWxb60+Uw1ysZGRMmPHmj10iFVEmP1uzt+yY9olW38JSvYpI08jzTdeYMlZVxlQ1DKgnniweIpYpyjY6rlKZ1mTd7q4QJzSoUswR8s/Ioy7L8T0zkBHQzczr5GMv0awqpBJ4UeaNFQqGHhMpNayaa3ytoCmNVP7Z2roWYlxpw3wkqp0E1zSiMAyMWZI75PBI3XriI/WVKqWwFj681foPviQVGZSAuBrHStJAm1bgiNJE7eDm9hA1p3KESLhN+LSD6UTjCxQrhgN/DhsYKhg0saGrN5kNjLwapkDygQ1SnoB0pXmrhA3mAmoctNXzDU0Nuk12WX0O71AzZqKH8HDNWtUB3v+cTOlKCZe4NpdNIe6+eTUB/80WUfzhlB2s/mFqRsZXe0r9lLeL5gtg8jkPHQ7YgE0oyunOB5632dpF7Fg1wA2O2TYEKdPBDoQN4zsIRSB6c3pCmpyHTiMSxOXeuIdrIFeBohrBRm3JyKcsMwREJ5jMmW5k2HVA0ue8j33SJKUguq2naDyTTQOVttPD8mnSKrMypR5BFW+zTJGwNNZAOSpBlBmh26VwlCIlcD1Qo5bVl0A47vZPO/r7yE5a4KVIqlWQ1mF36ocvplso2P8RhULlMtUCInEkiDh5/HjM4sQmWElSDY4Gf6sH/Dy2oVzDMBwTAaZlSq7gZtio3NsUZw0AVZlGTQ6sbyGDr1k5iLT2uuDqtMDaKVcL3FR6xDXF0yDYESSdezETzAq25VhB3C9Z/YNTCb9qJ2aToV9Dq4lXBbmHhLls72KPYwSC6TMwbvmVY996tPsSNnpisl6jGdJpGAtaeER3lUbhK9jJ8BVguxViLfrcSOzNeHKEiYoups/aVtOFR2xZfrim+vNbZSmmsybt2rV9LX/VHUFYyGzWWjoxoj0IZykZqfdrCcqK1cXvdCeWs440OkdGk5JKZUU6NnhoZnVQsBNcIfKukjpy+2ANMBW7aXaYNuuIWAJAmkcGav8G5ZiW8gkZr88BVhRTbUEMJhI22HVtTGu1B5FTymmqBT469Ql4aTibTtzrsPcZOqqJd5VNgI4SeJtRNozpxS2UbSiT6NCseIccKAzYI5GusXttxXjvsH+ECQ3XGkOsNuCXSTq2bQajeImJu6MRP2TRJ5vHTvT1XEBhKFHccP1y4YwhC7zjhTO3mXsaitZf6Z+jlbitpaO8vaqD7vqJZ8NVsbUe6HCYobKsRJuzVBk3CG7R7mrVkLGKPvRqy1U6aPTLfwp8V5jKq6GBj9mL8T0dEaKUaC54gsIx0V6nbEy0Q0qHDPkipT3axmDuQKzxJG4YRAjOj+AR4zKguzIXjQaFSKpNEmAFmVVqOQec5Stw7i6xIlob0TE/XThC64nfVFShgenN+u2qotGzW5qwsnFAtZhWbcx5t+ws0OWONtvVMzvq0QcHB1UzOudl8DcCnjU3O7IEszo9g2nxgW6D9OP4rWgPvZ5wZBOEAcBwXcUF8KDXbXALnLxLfEjK7Fp9N1mGss2U7ERyQQWbL9nwx8j2nDRXdrzBWW8Zf9rpFv2Oh37VtR3aRSj15ZNaElAzZiPnhxKjOqiWuTRHRnJ6K9fpoW3+Dxd7fwFUhnVNIanu08K/b5fh6zxEbTAmcC/+aQllldoiUgunxt2V6VQfRNo9XXlXtKga7paAfqeZUGef+sbVDSRWRzUpS8KVV0rqOvjJxh3EVHaGfPkMRKNV+GuQsbFhFt+S83l+v3bzanprAmuvIOSNM7Za26bnaWsRyFrHVLF9F2t8ToM/oGvdna7rczEattUPWjanMGXudFpjVX9X7RLrjfe6cHI4Oz05Hh6fd/VNndHx6cHriHO73xP7J2WoZZAr4v0Gq0PskjIT73BppaO5fTkOZwi5iU4YleRtsY4HH2dIuL54rvSxXx7eSemNxcto9GDtHR6Oz40PRPXPPDo+Pj48OjzgfHZ+eugfHXed45PLjsxE/ODxzhNsTR+P9U3d/7Ow7p0UO/DFDzZzgncM7NH/O2v6sIu66NaAy0yhWgqrMP2uSbwa1WAYxkBQMXZG9qhyhxuEnDPHdYPDMzDrsW5BQu/D+99huj/0NkMb/s8W6Hfrv/zRBCSjTLyO/GLPt2WfqxfHCFsHwTnAfA8DZBX6xymbkpdwVNyfKDw1W2I1u0EfSnm2KQzhZ/9gZSAiVKS3md2DniKQ6ohLyyWKAYt9KbvecOcuistWRHqexcXLf5z7AjD7FNQhuQgpOH9gPhqLQb+mXOLer3eaW9szd3oPW6qc2/uMvad/4hydrb0W51xzm58WWgHDjCDD5EcYUrskcq/JXIuFyJxn8sRDRciCPb+l88CsdpEKFFACTlrAqVL4y+/DuJSqgdIIBDTfCejDrnlhqbjmlEfp9HoFF0Iw+AyYhJ/JZsQm52w/PKGrvD87kIW8QHSk+IW41D33PseUsgOU69GM2DW+ZF4wAUEzOTRd8xX/OOWRL7hEBqawWVZJDhyJATc0InUMiB8C2U4iq22H9Hb5IpiCaQ5yqC7CvYRAiVLVtxNSwDxjWszkPPAWiinhs8nPoU8U/93eoglN/Jw9/K0s7lYwFoDGE+kZoPrQrKeGUkwuOykgfZFU0JmYgw6Q+iPLmEjQ7v8ESo7uqlmyGcpDogcvZaZWkaNhYaalk3d7/MmXr2gKr9+ERhbPchF2w5zI3x4tZr5J5dDu9Jrv2Lyly1xfG3ZTEXb3Qx5bADZ9IKgPufEpp/EFvUFNh/CEuzb+EgN5gdx5YQM/NoF5etxetLm7I1Wcg2K8DDbQxQf/BONOGBP/N8qb1lIAH5U7NdYAH4E8PrhesenG3asJWTVBqgp2Hm/4YHZfSlmXaTQSuEk2gDOoRuYsq9x4ZrptqxwO/lWXAJnYeqWI65Adp8cE0G0WNed/4jZQaNFgxEt8j7Hmaqp2QsunaZKT2jcm3iNuAYtIupqV5ZVst57+CU1QRuGJ7srsf6/gkLzJ2TI68uX3Sp7awU+mUrUQoKdb2rBBy+dv7GY8SCLyghqvIldkQ6xg6ausZQD0WjKldQpKw+NtX+PtXOGhuTIT/x8qV6hrsTcM4AWcq/ke99g4IQAMecH/5p3AH3PJeYeoqwOFI3MoMgJBq+dAUWQeaaP+oFproI5VNXqx+wFSY3sdM1fUsbWcSTTFLzxfIbeNPTC1dWBy+tQt5+axHmL0lKTW/ypSt5aucwL2XTAs5MiJaA3aOmimI8bSN7Ct1LZ9Si69q34anKYNrsBo5ywbrUReouCIsGKt+LllSzbTnXkf+C/azycT1dBpO3XKBn9GsUVnCMu/rTN0dmTN/enR4sN90+k2mbr8rl8UjAx9WHXC1rjJF5ss4rjOCMv1yTm3rU+2gnVBf2i35DMj1Wd1K+t1iB1GIfulQ9GnMdh1d2wJTICgqVpZ0oI/uXeYrfe7lBD9mAtgRFzn9R1Pqy76K9C8XSI3EgH9h0TQVpABLjhT2t8aBlFa7fw8pawUSfBlvWtVjtsJiH/ulW0k+W3Fdj/0sNRbe7n0/t5Ldv8Rl+AzkmH+Zy/cZ0PLLuexbgbFcYLRvwhcvJpZIWa3as1JqvCumr+PfYS6PIze+//Ds2Yv373daOx9ev//w9u2bd5cvng/O3759efHs/PLizeud1s7F6/cfvv324tnFi9eXg4vXP7+hX97D6lcBXi8cVYsTWta8S0LAiKB67hKzIIByZZsS4Ru93Bt6ov8FpNJHEkGfbvQFbChrmhwOA0Qa+KR4xG2VuH6GEk8xk05fCU3+/wxpEdPQR++UF7Bh/Ic/bG0MIw5n3cZJ4aLjPyzFkvBhUBlovUIS3R/+ToEQ7dGynQGDK4swz5R+Hdjx4zKjt3ZgAK+6cFTjpRc9cMUZpSNal5kDs2u2UDsCXmGpvy8iL3Y9J8n6ZguseSzciM/m8JcFBPdA/dqrT00qCSiamXMV7ejUQbkBzZZLkN51WJBehox9Kd7AdgHfripj1u5QxJ8IhSFOwvkcZLGpYHIlHfZGluLFSApxA4FhMjwM8klFpjheGtFEE7Nc/TeBIHQcLGmHPeEFVzFltRc9XybNX8yCyj3PzU0WnainWRTeAjIMN2+p2okW/Soxai0ffJSfWMxhHOrLh7cYVhYzKHV4Q+zQAwhcWE49EdZge1RW72OuT0vlNiKonL4kVvE1KD7etOHFM6rr+eVFGlnzC3/vsG/8cKRiDWXRQS4Lx6IYCCX4JKWytRdWvkatfxYOh67nlyePuZwoXCQNmB+x9bz8tzpI4pwnULW+SLm39AM8nIjmagvxIpTYDvvtpeBRgJh068vNsHAvmOD/FfHeX3BUKLQ8ElN+40GR3Uqhw5A49v5aonCnSBDlaO4y2kHKwB79ESdFhBAWXmTOY7Zsq5hhOVwDxQ/fRLUX5nGA3VMI9NUnIgvukZ9fE03BiUqeRL22v+4ddNlf6f+V2zRM+I7V55FnFTCpPEVmPG5XZ7xX1Bs3F3Q0dnsOH4/Hp2dHh70z53TkOMeHJ2Pn+JCPTsfdnczA9XCW1VtkAExaWFX6Yy4cVGFhQjGI9BsFTekFUxGhdYM7URgbWSOyFM3XVGsGCzdAkNzYEz6AqXFVml3carRNjDGe8hvo2sTDrA8sUpe6aYFp+Z1Ra0mv8jJaBBjtiCG83W6XKqPCXfTDoBZu/lvvDqJFF4gSYQA9yFKmaqJWLOwPsYhULJlrgk6oHdGTfMXvoEIqzK9QuNUKa93pdnqFCZnzibzJREQa8DYn0cyFgt8GIUp/jJPCq29U6k4pCfuN0NvcbWNULVg2AXBc4vhjWfW6wEIEIbLDOmxBTbegpvmTswU13YKabkFNt6CmW1DTLahpwT69BTXdgppuHNS0SjPbAv7dA/CvVuW9N0CjBRm1xszx+cnDD1LcdNNYrULqu40ed/j2fnLhVzGbQSQN1KYMdHm5lqoWCgJ5vnoulECC6qtGwtgQYBH5RAz7wYg71yJwn6AGCwqVW5Q84w67DGejOAnBsOt7Y+EsHV+klV3BZqIL78YhyWS+uYrdoSTjEAbqByCIAf8KJu0k4kE8RjnWNCCTXLCOJdYupcryj7ZHUtm14BFQn6Xp4DzGKtWp2EopzvT7upniWJNyByynZIekVEJARF6torXRQiMqY832VTpQTUrwLhV9dDUzab9ZGnbd1W23TSynmFXnirkfLoU7gAfYPjvH9ygYSt8MKBQrZ0vtS2ru2ap7RhyEyWhDUnNJcTjIauYTO5CoWRRO1Y3Mro3qWKt854YLu+k9XPkmd1B+v14jV5G3sgXv7BQulY1PMQ/mCiKvssZqrmSyo8Yexk1d+sBYwvrgEFCL7qq6WqfhMCmMZtnSV0tJxTcpDnve1/fZKDCZLnR03Wr9yEg+V0B1ZszcL3Ec7tii1NZKTW00Wukl92azBTI1ljpRmrBMcTo+6Y7dkXM66o1H3dGp6456fNw7Pu6dHp8cWeCAUx2woeoWf17VQkuFV0PZ2WobDSsjboX9rbC/Ffa3wv5W2N8K+1thfyvsfybCPvf9Fbw6ufbgzakVxa9KRP91R1b4NE3H3ioC91QEIHYVIhWLVHyHf39AdxbFiBY8Lx+LUG/3tcdvy1rd23myuWJW+b2RgVlbLWqrRW21qK0WtdWitlrUVovaalFbLWqrRX1BWhRe/gHefjspZSInhhYriakJKb3AFXed3+MSFNgoWcwHEDI+sCbpZapAr5G3lB+hXpDf6lob07WUarQplWvFPK/1RYuNsPNiRGZ+unaEnUcKzN1G3X6qqFuL73obJ7tB9vMgsbEDrBBRohwRwhWjpHNMZMIvZHaUF7PnXjzH9O3XloRYy1t3auYkqhnYhdpi0nT1ewzzaXvxYLZU9OraEfSs49sq2m1kBuZwwonswEj0CyEDYEGROPZAuEumUbiYTBlXCYu2RFnXg85mUNWH8DFmfD6XpZGo48G1WDZNMLz2AndgNGupPmRG4cqdUK6hvuXL15StiKv4uGqCS8UA63cAy8yAJNDf23iy2xKPoLhtP7x/85q9EtFEsLd4B3bfffuMnRycHT/RSCCj0KVMoNHCv1bbLJMAyUxVzQyphS3jiM/xPlKPpI4C/JxxkOKn/aDN3hPgFlc/0UDwJzKrQZYiZXJ3jM+HwP6HZAPxhfwNUFTgT76ADO5FQOtw7euw40SVIl3odo34IV0k4IDSjDmwixdv5jQFnYCeYAqoStGSqE2QoS5hGVRqc+MF6VTlkrOTvnqr7J/O2oOjQ6wb7LPyNDSfXcPnJSVn9k8lnPmc/cBv+HtJMR55qIimeGSY+I3rKHItq4nvPU1gNcA5Y4qDReQPROCErq2kGOT9klgFswGVGyuf6Vfd2ANIZv/w7iWTfTV52FebcnTjORVvnbSfQzEoL8hVYKsyjta9c/a0QNtDRPCVkMIfjlNjYnpn6pEaAnFbYriEbQixb07QEJC5GmdslrzmrNzs25IkbWsPfbd8GsrAeyMiMEZLpJnSORWMpewCpYIlc8Pgq4SAW1pG4i2BIgB5MofIblltuCBixO5AemVsu+frGknkuNHsO28x1fAlpFg0t0uWnLPs/EF7ELcrTlS+Ro8x0fgP30vEpueLqqyEh3qYuUeC7OcrTBwnVT5nUj4F+tKw7+b2cuViyS+l0dlOwjWbFo3WNkIpP2HUjFjq89iSw50/kYwz1xuPBepJkn2D54F8Eih40X+6YuwFBPZgd7s8JH2hsdLtP8s9ysgei5EbzrjXJMq9toxoinLkmSX9QoJJkEN2XHHD9LAbK/06j8SNJ27jwQrT/Cpmb6kZVaYFv/YGp11jxUpEFHGAxW1r+AxlK8SAigVGM0ihumCBSIv3FlZ+Zdtf0rlrFCDLYbBLQumXTczn+mNzZlJeqByGcv0zMEv7h9k+Bij8200qpOIDX4hjbxIoFQSEjGuxBAguJmbzRBUuhlOLNUkBbAlATWAiiWAfLr9tnyoxFVvvQjfXYsnm/iJmw78NqZixHlJDg9A/sWBo0MaxnrDZIk6ogOgdwGEyWFMBdqpkhzQ0YjnZ5lHoLihxBQvcVUEIm7tEXed26N/Simyuv319szWn3secCkQcXN/c34KqOlr1QLYQFRRu6x7dRtq7DkNc1c/jkmuCwyt740VhQO578zIDzBgAAuv7UHq5LfENM35nfgG3pUqHBUdFg9N+N4diy7LyaJ4jNdHVN4V8uoisuNwrO3oRuhM6a5mLu8pR5t/Ew1S2aEO2zQv1kUDh3BHSCirhV9emQakkatyRUjOk8ZWCfpXS6SLxfO9PiCkKajBFM/fPdoK1hlIxEVf5bfTHJjjtSAAQZtzE/pQOVgKJ29Tkhfa5WNZBTwjADTe3dgp+OGmrjxvJfnJKmTsULWKQbeW/m0jqGiIwJSEI6+JOOCAmE6pff0f23N9hMx4EiGiHlecNtUR+0mJewqbwMuAzpETDeMoBiBMDptOY3j+hyImcwDMEvDt/e9HC56DYxVC6IzrOeKgcAFgCQ2IXvpOQy5a5LQI9OzkDBQwr5yVRYdWcaAqZAbEXqf522DdLFQfbMgnJc2Ts7+iR+zsb08j0di/nAs2D5BmzVCpZzuWTC68tINpxLwBSYXzyh8CDN5n5AhCVEfKRXKRxC5caxU4YibgF8PBe6MZYlWa6nE9FED+aIM+eaShTEB8BmRXqqIuxd2fsKhycea3V0uR2GWVo/+i4UBJBB2ZRGBLFHG8l2JpU9hrPjjzkOSGqu4pIa/I/DJprY9Dcdmea7kyWGPcPVVzEIhqsBmxpNtlAelZuDXnwagDUxh/zCOJecBM6BShvC+OIEx64PHIzIL/GH3UtrvRPowVEWKMUHGCxnbq6XDkyWhC4lS02EnG4iBxBBdzocVVvEqpsahpska69XhZ05ouBrWIQMH4+g3AbEHyevf3AIHrTNAcjVvUixpd95vm+FwP+aaY8iSWo5qhgaPhYTN4z6LOwpWrAhXmn6PHhw8XzemfcuHdyKM66vD3mY9E+PD48aI9GI6d9yLvCPRw7p4e9o+zzcHBcvXUKBRAUjPZ44TfQ+Gxr+RB4f8DTWI6vXrmu3un47OTg4Kzt7J+etA9PT/bbZyPXbYv93sGR0z0RTm+/oTapHPm2dRgaNl8k0zAaiBkqucgI/jdbK1N+AavdOeyeOiPHHbuHrssPj3snYizGh91R99DtHZ9y8CiauWo7+939/Xav1+6eXvZOnvbOnu6fdXonx/vHx7/u5LI6ar6l40E1xIyYHlV/ILOKQs0Y+LMKp4IVstupcqO5zTfHQpsmG2HQr1DVIT0m955dg61pVirDTDUsvHKBOSF84WSD6slV722TeU15LL0T1a+vmhqws5Fg0h1QElBRiJ7P5Rk1WD5kezHV7KGJoC6Bjb1L/pktlKDQuuuq8hnv3yK4DsJboA79XWeWgclN+mjgDeUxpAI644Hje/Lfg0TM5j4B6eNjQXEMWNjLc64HwvUgThATW5aTCF9UzYEdr1ndx4+2ZC4qTVTEOwddMEg8IwyLPjUIItuaWRHNNkM94Q3QnsxiEvcxaOVLMayWDKRnkSnhtM64efJk1oTxjAWPr9W6i16vnd4BP9g/7IrT8eiwd3h03Bt1D46PT3sHkCU0PtwfHYhjZ8y77pk46Yqzs9ODI5eL0wO3657yk7PDHTNPVmWpXtkTMeWhzmf//fZPexeqvsXyGebBUVZWVhGxRvp8z2Mw4UmjFijxpK9WvPz3J0IzNvqpE4oNoU2mD5ecnoqUYytjaGCyfZRUXDphTTbjs8pBNe5lo6tQKLn6ibNWH/NcrZILK1RETmiiE9RlyBKRi5WJSleZBriY9XmaMbW1qGB7h2VWg6xYU6TQO/rBWiHF4jIvU3KteB05UAqIkJNBt1gfTBX6jRdzrP5bVmTnG+5c3/LIjclGjQP5gpGpUhq15cdsHPp+eKvLj8FMyLOD5szxGKPdm7INQzrsdp/i/28qFn66GkSN7uNdk7u41r1bA4MEolgk3gjTcCP94IHxRvqBBhxhjfFGoKyQCTjCPj3eSJnt6p3FXFV9ZY3nRBmljrqFR+Mx7FV1LPWzxcFoxgw+pSFV6YxFQ2kr/WxNra7kL5mSuVL/uiqz48XTMGpgP98a8raGvK0hb2vI2xry/g0NeR/LHg9VyHD7fmzfj+37sX0/tu/H9v3YOoK2jqCtI2jrCNo6graOoK0jaOsI2jqCto6grSNo6wjaOoI+pSNI3/9BBHvteL5H+mVR71vMZjxapsJqkTtku8Ct6gcRDwjxAjLISHNmb8P5wkdTDF5YnQyl7IT9QGOnEX8BkSbAuwsDDdnID53rTu6UpPUo3AimlZ3O12wI9H8qcTeGmoe4YT+AxwU0isgbLRJBb5IHKSe4ZuIIq3CA7NADmaRhx5TO3QO4k7n7x+I5iNJhwH6TB0t2c7U7TZJ5/HRvzxU3wgcuEHccnSEGBjU1tT0wIoCdYY/Yzd5f6Ie27KoNM3pSfdN7hcykVF9vVTsRzbzqSpSJkTM+PD3tHrdHB72T9uHBUa99JsRJ++BYnLhHRyfuIdbMzaUjFE51bvi4DbBA26So9ZKi8ghXa9lZLN7kTdSi0htMoHfbLb4PpkYxc2dz+yMTR7f7s6n90U61e+8R/V/5eFmSysrEc/nws93sy/qkIz+lB1mK8gSC5d/yZUwS+u4QCmmIp8rbMSRVwOFRtGRB2A+krgA6VSr5jz3huzL/WmFYsSFmtUuxgIU3Ioo8V8T9IAPJNfHDkf5YVS3rSHCrYSo6GhaFBuC+2FuRaJTOr6Zi7Zy9URPNQIf1g9UninLUCmKKblgs4YabUlzPy1TQ67BXfAmOIKl5fa0sl6jMa3XLJvGm6aLyK0PgVX+50lBzRbjd6Do2lk4APGXH0ipxy7Ek4OrVSkBW2BnM7k8e8T8HfO6ZVd1ns3BjFd1pgHVYWrHlQzO0BihtDdlRKVnbY+75i2ilN8O02DlYauik2z3QQ4MlOGRYI1MrbR/eXaDhzkQ+qL5P1fuUTuFq1W7KJTN5giEv+MqSHvxwuy0vhBwf/3V1z60e8Vi0Z04DXx/wdS+YXEbeZFIJj6S+ZAl9yi6eV1ro8wzCepol1/oWnx6boYz8NvQ00XEKQ/8rAHDJ6/61UN8pkn7evPfP/OZ8tKbQp/N9u4jmoQ22XE0Y8HZAsZzTh+ziuY1n2gwi9ViYYegz5NP4ofVolblvLEoxkRMdASrtf7TUwR1NZ30jAjeMXluH+Bl/S/HPL599S/guHg9SSs1Cl/stps48fvlsESfhjL3iAZ8Ilz3T9xvFGfnr95evXhJR0BrKWXaPJJCkPdqhfClvQ99zlh8ii1WK1oNApN4Nd5aMvkVg9C9gffLmWIRR+kG7O9CGxDiO3WEvPMnkPMLzEeGLG5wq3k0C9KalbQp+fxGQx5H+PYjEeNA7Fc5+7+C0dzg66I2PeuL4hJ8cHTjjUVc4B+4YBXbdVelpBwNMBNItDNCUbnrFllv/4u27F8/OL188Z22m+CVfhZzq4yIxAUp9FMLGRxgfBIeplfsevTgJv8YPHOECnNu6sHTrUn0uopkXx/ajpWhifMQmEQ8S8lknEvEJp3LvN0WVASrdfvXBp308SsGAC0+w5NX519E82cYqs6TPiQBw2LZCwFYI2AoBWyGgVI1cnRWlXMbxPecaXQAiEFE7WvgNdEm6t1ZvhbJYQLcvZa9lgFae24zFZJ+E6qnFAnz5odWVYkX9l+aUsoXczXmCkadQoLgE3Il7ybdhdMkz80udRDMv8GbQmxUB+KPFktJKl5HtvqBWInouV2ipmkzG/uL5a8/odLYzspUZBIFljoJEFi/TVXe278723dm+O9t3Z6t8bpXPrfL5eMpnvaCiHnrH8F9afG86Aka6JClqjDvANsBlJAUFK0XLPAuxw+fCJWeT4uJNLgXN4NJelKZWUkpbtyxTKEhKD6Svt3KyUip5CQqQb994sYyV3Zh0Lbv+Wff8+UrYBWx62Xh1SRbLNsWLkST9xogJ/b7X3X6+lGztYKEk6YJuILWVkd7oaPVdyAarleWXVod0dvcPRK97ND4UjhifcvfM4Qc9fnpwsu92nYOjg1wQ276dGjQfipxpdBSab+FM1bdq8nE4rzpdz968vjy/eP1+p7Xz4qcP5y/hP95fnr+7fD/45eLye/jz6+f6v1+dXz77fvDuxXcv/r7T2nn95nKQ/ct3716cX754N7j8/vx17p+DN+8GOMJOa+fli/fv1Tf6v9MPSo54aaGrZjVciGhIj5ZR2Up6cG3651a53CqXW+Vyq1xulcutcrlVLj9r5VIf3E+nV+XUKTN8rGwT8ombrrkoi0G+1+1CkpgbOgudyzywFrb7aITHWX5LkTKqZRoMwrTleRTD/XH26ahXxQOxQPAfWYxTpyzpwDpNudiJQt9vu2KeTDemNVGnz6HPT6kyzcPY04/EynJq2np1xScWTiSSAfpJRk1oGKxgCam7fzT4/QV3THwVAVDhpoRG8spKP1RejqeuH4sK9IeNqy/VS4bsr805RrG3T3ljkOHccL+aEx6VVCfFjLj7ezX1JFSPq98/deTaqGdubD9Ut6+4hCv4VPuyko3Bct+aH2/dWOnoqxNfpsE8zrVXGQnNrv3nZaQuDmv2WNiIak6E/1tWrm9DeFhRjvwVPskCXtQb8HnA/WXiORa51PAXvAoDwNMCO0uVmJrtus4q8SxnjVAqI8je6YAbs1Ccuzc8cIRrLiYSlKKNxU1XtFzEAsXVF3fzSysCyXv6nWFlY5n6DVnMuzJ92Z5VPON3xFpPjw+7XYPVHtt5LWqWSMdyApMBDgvzrng6RoskCYNLcZdcAiqEz7X8taKyduBwIcYnXX5wyg/+f/behLltHPkD/Soo7auKPSPKOm3L/5qqlY8knrEdj49kkvGUDJGQxDFFaHhYVvblffZX3QBIUCIl6rBzjGprd2ObuBqNRqOPX1Nrt7lbr9TMPau5ZzXNWrNeUNgi7vhkkKyGPXPXZZtFDrVsch14jAUty/JkYki+tkjRc7CanLqBx8EMslLjD3bQn6TtRF1jgfUw6jMPa6cKbnWo2wshDRDeCgu9GXPJMZPzB5stRFa0Cx1dXy/WAAlxbPumQ0E7OrZ9eAYmMFFnH0MpZc4kPfKOromLyYdysdC3LYbblHsWUobl3r5I5jnDPjVcKO9smxO267k7OSlutWHzESH/TZ1+V+lDTj1Sv2hkWZbLn59M38BZSzeBf5WpcM9KWCjie2kZllD9pbJGYHaPlDk67RRmmJpAIwIElDM6TnNDHgM4igN/IwmoKgSiWfiKt1gn7P2WVkX7RtaxBnu50LvwWxwmr8bStyGVe3zUp24vTX9A5AZyCbvdAhwfAZkTwYotrq9kGSDfQKAudeRC8it4NAz4qQt/uo4wOCeM92HABzSwTWLjdzB/3lUD4YeLu4wQ4/IpOHE92+ynMgELqO34CpNHD3YBQ7T9yIQrA0BifTmZI9GprCD/zQa+zHtTqJv7mA+onSLggG8t/JtcNxrpAdwKOHnk2QhhB8QB7Bj4N5BI9JkK1pR6t0J+MkuFDz5Rf8Js20V3nqGnozW0LyEwe1rfFa4p5loi4R2WhLXgPcMHtIHAo+YDEZ3kP6QWO3kSjpkr1mVeGsO9tZFUTH5HPPjQYx463xZdJIx4eqkpphM76NmDAYx2ekmo+GipIX4PmTe+pB5Ng1u6YgP+CIPAAv6BLwE4kw6WGwrqUrd6qU+UaKDIMkkQ3woAVAm0I9iQiD2aMTpYalw7yM8Ygv2hjRREeTlCSLLTrgc4o9NjnWYLOtsNOLFFw4UJOTCvOJ+9PkhXwLWluG7FOSDd0DWFdmAHC5xoMdiixEUxsxhx8YguOg42Es/5f0Lm5z3cE6J16jZDxI3MABTl6YL7koRDEroWUxNKvLKLsQ4HLlS4kVSsyqRai4IXLT+TX859t69B+ZUrItpvc0v8J4SjuwqdtCOBvxZxHLBLEa6dWpztI4xpd8JNP+Xii72d82Ej4tgw8IXO/z4tFypfS81HkK9BajBjvqZphvB8LacdgfnaZUWyfkH7JVB5+U3fbPh3t+EZ4VpyTxcJXPHHPkD8z7D9D2mPwa6mW//Tn58xQ04IpdQ3qKJuCvu+V39aRr6rfnMI+OjTpIQn7+EjfMJEk8T3zHjIiPAIoz0A5KbCAl0ucCQHJ034fXPy34TPPF+rSWcTRK1YNmzMwHapjJce0OEQWAXDqNE5vtBMiorVFlp1nFex0Pyjd6O0UYsdQrs9tngvsOuyvDlRTJgqKiLftIJbUj0I89NMOXcwyCaO1YkPQiIoJza0aLaQiYlnuai4hWaT7DxTOXw7yqHYeLM23qyNN2vjzdp4szberI03a+PN2nizNt6sjTdr483aeLM23qyNN2vjzdp4szberI03a+Pc2HizNhu+8WZtvFkbb9a/0ptVlA6s1Dz6pRg8ydcIapGqvcAfkvWEs9/X62DVaeCcnJdBFu4rSL2v4QyUtqG1Vzn7vgsC6fVs8lhLFYMmWXBB8/FssstiU62UOWGZazgTsjzuZGltoIhsnnZpgtZAQbQB9hhW1cx6kKY4PU+Pk5Ji+uUwW2CEQ2uVZTnUB5lirbw2wC46TVlfa/JilaulpomFiaEdGfU5GYYdx/b74FWeQYx5fruu3ct3PhKHWBSCnjJlY/5wzDc6saMFR6NOy58FayNNzGgjTtLFyXq2drW9wS43ScqbsI5NWMcmrGMT1rEJ69iEdWzCOjZhHZuwjk1YxyasYxPWsQnr2IR1bMI6NmEdm7COTVjHxsu/CevYbPgmrGMT1rEJ69iEdWzCOr6TsA6PjyIo4k1cwb86rmCJoIBJptoECc3z6mdpoJuz968+e8XZL+ajxNq1v5Ghxx9tK1labWpKtj9vTstFBCXccusJCwK9puvwUZaeov6eRlalz3uMOnK3hx57tNkoq/hA2sgb4bVySFK0iauyBHeZkaxYOn8K2vfQEfO4EXihHxg9GrARHbfl6TUc3jP4MJioRpSx1Q7vtamTUrPveshMuzsG1VUWUSQO7xEgv7ISikJktrCN2okCaikb0aWOz6Jwg+jntJ2BSWHVrhSGyJgXd51xXHBzuRkKVpk/wS9Z9E8XcmrGQsKKOCYOhd1Ajsd2Her73LQpFnjzaLdrm0Ui9jwYF/HKsBisgQy5H4QQb/UExe1EaTgmiuPRDsYrcY8weEfAXRNwcg+zvk+VLFHtW+oAX8eyRnifu114V8g/IXVBQTeRbC6X//Bpl/mMelhldRx4DLo3A6y9ZvvcgYK+8Hn8b/7IPM/GOmJOva39xHqeOEYe87nzCL/6J6RQ9s52Gf7asj3Bxl3ujaiXYdvI3J9HMMfAAcl25qrtUp8je+X36WaG0WUdKDlMHtZ0Q8eJV5kVDTH1UYxyFTDPo2hNi+5NWaj7oCBEBnWypIsb2Maj7YV+HtpFHy9OubbFRy6YodrDvnzAzRSO01PN6CgOWmqHw7UMkOjmS7HQpbbTNh0uw68W7FVvDfvIQdqLmIW2TvIFu03v5zk5ZWhHuoZhcsdhk9WuVlM7pkdcSgeZ3U2mQnLqWkBMFp/j1TQTKXDhh78ipaRtu12+xAr01ovoKH/l2snBYLOLeXbxWQhvgHgIvYW098nvBrarqtdXiuvanslBVuh2ypwQdSrpCxLrr0nB9TL7LLVBORH8aaGdTj4D5my5j6Fra6Bu2gnOGn9owGCpewqxTO9cZ6zYPadJOXUUFYc337I8s3lb+AEyqTlsp1p2xCNqLF4FWnclAusj3GX6b0FLT1ain234yZgJtJ03HSZcU2iJmZzaeegE9tBJTM0nJnWJ3wcnFrT2oVg8dFEiGGblqzLR97Z1j9W1ich7YVZihdhktfVFOzq/7uXE/kmiLM4FUesvkTmnTee/5af7AnuKH9DBcIrLI9vgErMTE1O+3kUVNjpgRr2Q+cycPAN5razPQKCZxr1LYcIjlPh9iLf1w8GAemPkRZ2PR3bQF0w/wYspz9SW3jD0Ra4TyLXQFXKeQ6gP3A7cgx9tqB/fCX3bhTA/qf2WCqvsrcZ5z77BflvY+dp+QIMQfso24U2d141ilqVeL7fz8zaljXHVbrAezTv/cHmkrscfQQAMh8tsXLL9qhIXhEgbzHVzZK+r1r3krCc6AHeIuyolJnuIfT3PSItsMZFcy5RrBR7zIo7AtqJgftUsIYNnxZBF3ibbDXbr05rCl6ThIH7wG0qMsyBD5+ywgOYUAfCLHvcwgMJ2CbREm6gfijQfuAYwDySXFp9Tt+nYLsSly5M3Y6YwQ9g1A83QFhs6fDwQYdfQMvImwpnsyovKJXF+8CufMKvHSuSNGJncnF2L0BWTCX8YKHuQZaB1gYSAbl/RR2rjg+gV2ULPEA99Z4wik1nkFZoY2attnE36BasixphYcLwCsP+q3kGwRB84TKYo2a7oHyyxk++EvHQGy7IB4Wo5bIv4MYGPIU+Jh8ECJsYONR96Hg9dq21yh6dkIujGem2kuCHBhkD6+/94Xq/X6dwTcURiUz7mSoFzEqNi7M/MEktsQ18r52OnGJLFt4LHRJR3PPf1GJbB4M4D5rUhySc32UQbgolBy1MnVv8MQ/RoGFnZEoxai05StFnnJEWPmZOU8YZtmYeVa4fpEI4ekU3wbUe9HgvaoWcT6us5Jixgnl8iN9EzEiIfQS5NLU65U6CT3HkUDu/x9jA1w0AncDd0HMx+kc9QaEa6tsPWQuN+EAz9g50d6NUvmXywQ0vDzKMECfEBb9OslKCEh84a2C5h0AQzJCAowBevDDeg5npYBAf5r/wZpj974vKSmz1xdRM6tiuS0XANUZCMyAiaYP11rOUQvmOWSDY6dUHtHWcth1tpeZrT3K4YM6Y+1W5Lo899WJG2EO4RKifPPCMKHrm9Ok2bfOTiLWh3X0Fl1E+sXnM7wjlJdTgu5ztJjwXPkFKBHazp7MSEzNimSCudqfHQQLnW8fYVbzMwR1nk0aY4yXdez8fHm8qHFHIImFNcVZ4HSpIMXEiVQJM301wNI/9WgIoeBsLZ5vPQM5kKoZij6akwqYD2JiOnkCySCjp10nbkpZYWDjFOoC2uzlznT7UhFmYCM4uASwmUHNBFcecZ6fAANA1JgVWkSpaiDoHX0S03+6TcXp2mC468l950dB2MmX5AHrNizhNsoiLO3XDQYZ6i0zRDxCbXaPWVF+KO53MCQ40tAwJEIHkph1YPpDk+uyS26w9l+ucEFECGSh83aM++XvAdnOwdFCcZOXNvMTa8h3vk3u9jxMucgBn4Xrs95I+ybWbGzXNR2+Mjn3mGCLGBt/d8ih85NnMDGJkciubkVDVf4EnlcretwpTaS7xZXO4aqj3hrkcHwwihAS6KqbktG+4Xeo6iUzui0zIznkW45Sb3fIwhzSa5ABaVNWZBGxY2A6OgQ/1lbGqi3bQzYcFutNZGbWkD/+p2/Ya4cztJymd4RhyHJD6VqhFcmdLeNcsyt+D04pHGBRnUPGFzTdud2N6UQ6boBi71Na4py65VIqddEro+C4oooDXIPMjWJ0ct0qeu5aCxS2s2/1qYcaRRX7jVgvy1WaNPqYsGHn2WJ64fSker/jW8sJV1TKlFYMibZYUrkRZxbUfMQKgivr7ugKOhD7qSJJhzEVU6td262TAqtUrFqO/uMoNWmnWjW2bNeo2V95rNbiZy0pSSkQiV/2t9ckgzW+aQRFN210VlUrIDkE7xBLLPI3JgK7HDW5FZd3ue1ccwjMOTN6cX5Ojk6ub09elR6+YEf3t3556fnh4Pjo+OWvyo1xqdHrZ6p7e/3bxrfbr42/zj/aerv+v896B8/dZ3Kmbl8Xx0/PvHX3/jn077j+ZF6/eTs8PfW6Pbm5Oz89bDm1bl9uSwf370/v350+u/W7eHvYv3h63e+fH7i37HPnxjDl6HH6vO54/V/aeTz60r8Xfz/Ojhot954ww6tV9D+uHk6fVN60b8jZ8fn7yvf/xQGXXe3PauPzT+Pvu71Xs9Ko/P/z55Ov/79Oni79vGxbFF37T2x+c3p+Pzm9b43c1J9eLmoXxR4S88t6Oj1vXpJI0OD39vHfd6J5ctoPPv/KjXOzlsnV+Z765GvV9f31jmm53qm99OfzZff7TfHV4c//b30afbP07ePf7x4WO9evjwtjl6ss9v9nebR+9+Zm6rMmoMT70/+Gj34ei84v/uD9++pe8Hv946PDg5//VpzM9ed1s7+78FlZPfXo95593f4Se/ej0avx//WvWvg8ffw9vfT7h/e/bp6OLNp5N/+NtGb/dz//zyiT4N9j6deZ5//Kk5oBdv3v/D904+nH14631q7P2+0zgPbrzO0+9nP7M//r4d/Nr8rfZw/XMtPBmdW/9c7X6qHTrhbcV+pO7w0qwcXVTfXPStd+Wd/vXH+seHNydueOb/8+v42KqZp/Zh5fwpPDr8tf6J/vPOqj7a7ysfzMsav61ZT+8vB/XzD+Pux1PHOv9wWKm/pv1r8+ms/8G6cs+bHz/t2M3T1+bZePiHH37eO/7b+/UyuLw9ao1OWi16MTh/8/vo7e8fj99fld8dHn48eX3Z+PXz2S0dXbz+2ay1/vA/3px8eNvf+1w1P58f7gN/WKej3z+eH9LWzG9bdfz2eHRyuDP6/QTOzOHfrWvgibdX54et7v7J0XHrTev3tzut3snheav85uj6nzfXp53a8e8nh0ej21arfnrY+v3Q/PmQ7V0c94cn5eZ4r392+enN1aVTMa9/OxzVr07Lf5w+7npO5/rmtd84YZ3hzZu/+087o/7F0+jkU/+w+fbTXqVSeUcrH52b/aeH0+ax3z/c2x/83Xp79Nth69e93QH/bT94eFOm/1gfh7/WP5m/3rw/PNxzmvtXjz1z73P3xrb3PrDBzXivarHDzjWzT4I/6OOgfvK6PPjw99v+742Lp6E7LJcP/3EbvcrT/tH45ng87A3CnsuGPz+9+dl+/flicGP5n/c+nDZvdvYejs//+Odw73zn9eWHw3dX4+vm/rtf/7k49kdHZ6/3O6efPo5uD0/Yz52rt6/5gF/3zz/To1rwaA/2Phx1KrsuP364vjl3ur+9qw/dx9/6Q/O9dd0bmV7Yunm/N/75w89nj4PP1Xc3O29Cu/5r/x/Gb9jIf3Kt/vHxyd2di6Lt5OI4TdylOXRfwmmMULHMby+lQaaNAX4P2+0xb+jZaXYh/ea4ftuqNnaJ9n2agpH7QjlpHlSaB/XmQat1cHx8cLx/UDk5OKocVMsH1Rb8WK0eHL4+aDUOXu8fvD46qLQOXu8dVMoHzdcHR3sHjcOD3eZB6/CgfFCrHDQrB/uHB7uVg8M6NKocpQT1ZWdHLuolD4UabbvtMA23eMrBm+n1DH3mS304g4TkIw/BOQo4DpCHjx+LHHqhWznjErnhUZ4gSwxQjFQtNYVkNqaybSIcL7nXJnGfsZHxq2+avIvb7mzfD5nX5l5vjq2Jez3q2p9lSB8YIbGptQL7iX+RU9cs5WUWMVuPpmQ56gcFHvuwEfg56drMsVY6Ke9+0SdbPPvliDp2l3uuTYvXN79cU5e89qhr2r7Ji0e/3F7nXI/Hesu9RWXDL2rSiwfdYWzrSwSXwBiQxMKsNQrNjIgVs6sM7KnBsPrzTHsPKdN6Igw3hQt2m02rub9br5qN3bpVZfuNBmvu7lb2m83OXrVRFdjgKv69Vs2Yo7JiZFmDbLMfW/shXhpDM8TlRobcsc30dzy57whH2T1Bj5lPQhdgzCVkh3SLgEVA9u6XyL0H6H7UuRRRF/ekBcZFMGHjr4VLLxqzEwbEsn0BdaPAQErk3uU44D259AR0Y5QnOZugQ48N7HCgGTm7HpPJx/IPcknIVvpMMd8PR10gP89Eu5oROedyxAXZPnG4DGSWkCmyefT7tSWlps1YROCl8EvLDELqEPWBEm+XrSP0gc+ku4IYJK9t17r0+NP4Nfdur862Qs8pEvB9bpP/yWBuclc4Pr06Obq5K/wf+ZI/ajuPmyv2W6DFSUUbAeKXRlTxlb6Aank9l1/atP3HNhgKcoabv4TKCRg1y1g99ZW0sZNV1C2jCs3jDtW9Mw1eq7IMom9nCwFBwjZsuiYI9N/+JSCaIMIVTC4Y4ppyIEg/HFDXAPqhtQy/IzIOltjifESTIl10O8qsDPBFgqM48uXF38kAO9sn96JJqttmKmEoq7rRDQbywd/UkY3pNHcufYAkAUhuBtEJcZyyM841p6woQ5hTMo4w594NI2E8Ed8HQX0iZk/krDJRBkfMHDf0q0W1ppyLucd8bY4DOEPA0+0V1DZxElfwIGSrTwnSiBSxmRkBm/D/tYX/Jy+eNQT4S8C0Bd0rIrYz08ty+PGdcfnbqYz9Ew8rG4I4hh6Dr63/w/du8h1ru37AaCr44Tyr/AzlIcLdS0wWW+YSWskQ5GcKjVnC+UvTNoGGQZ974MBGxHS7h4ityqQg0TzWFYe7rGdr6/RYPBjOwcyS3BbusTlv7KW9TJN3SS4wq9XVR/QnK7bPIm9qfQwYrcs815CePdW31t3a3GIYRh+RZsZxsjBloEtU3H0RNCbqpioWqRSdH060FgU9V0KgekXMA8qOuQ9VIObZ1JGvEiHvMIzW9gMPgE399By4RRfWnrtlcZxBdfZJBNjf/GvE5zLpUIuMWMe3Ib8DACwhZhJ6sz18+kUQwTkfesmwiEVyNEWVi+jZlxKQkLKIa5y3xxyBY8QJs0LxDo9fw8I+OQm+C+NwFLZaOIQfgrXFJ9emzVyTFckNM/sud3hvDKFaJ1rncI3ZQRilMy1Bn/o0fY5V/KOOTTfxmJ9NEfUVMuwxe+RDnwSMZkV8z55i25aQz3MOFnyWmPKW4uo5Yr4V+gFsBFxYjJxeFrQCeuWs6QEqVVuiUs0+ESPbY13bgZyQGL0qjrmYALgy+8x8AGVGqIBU1cJR1rIBDUQdGp+6dmB/hqIQGiZWh3W5J243uI6DPhugK2AozGDkRkkDkRdFLM/uBrFHQAwAbKxNNUqhl6cC5qVU8Dkh/+54K0mqEq7PLw0p1Gv786e/oNP/3RUqtfL+Xr3JjK7Z7Rh11jGNTrlRMbqsXK12dmvV3Xr9rvBlezKQ/SWEn+sbFgMWEVGG9tA3bAsf9fP0wQi9Th2fIbXx36eXj3VViAUMl1oRy4SBbzZ5y6xOa1Vz19jtdvaN+n5j32hWm7tGc7/bqOzWKmyf7SYIlrPB1yMq1BKaF866OlHJB7BjoD0HCxdFfykKm4z+jojR5dDTxgkoFcXEuDL0fWL4rTzE3sYhwoAbarZycqg/rjQ5j0V9ipl6TNxtoSuSRlNhVhdmrpfhlbbGK2172IYF5QipouZDOGzbwzQdPF5pZa9a2q2Xarul6ky83PXTCqyI1PYyLJdTDzLFc5LhqOlx3yeDCChF+lDIlvhgGzOEolA9rGzg24/MGUdHQmWhkAsInxbdwhDSwSPSqfUsJD5ykdV9smUxIerEONN5SPhRZ8zt4Zz7V4yrWeyiX0RDgNsFesryrAw9G1S4Bba6khs2W+u7qLGUvnUZ9o5pxn3clckgizxoTy8fd2WqScfjYa8fqPxCORDxuZabpOTFK1+0VPW+YLsd/KOeGHeIesJHHnrk3cgVLbYOP76Df2zLUT0q+Y8KBcAPqGtRz9I9lvEkZ292p7zf3avWKoZVb+wb9WbDNJr7rGtUmuXdct1sMrZfS3m6rSn7LGOTJPKmF0EFth/r88WLYLbsPdQvBLWX4dAPPEYHRA05m1rVEv4nS3Zwb0Z+JCWYTyA9WjLCVqWhTc+DHAs1AROIGjW4bELMHIG7Vr8rUlJ3GuVGLSOcgIcBawd95Nv20LMfwYfisgBghfOYQjGKxZVoB8jfasYEMFRhlaJTIjsF5ChfxMWgu+LRZeB6h18sm0Uhu5hBapcoLiOPtoduUDmd2CseU/rWF0WO0Gc7+b1tAen5wA4ykNA1p2llr86aZWp0aZcZ9d16zeh0OqZRp2Vm1bvmfr3SyCXmhotEPS9ybaccrN21HKzdVQ9WuVw5OD7cPzjYnK3N2foez9Zu3cg05Z8Iu/3xxfVunfhjN+gz3xbmw+OLa8RNAEsTlgfLfiClvkGQeMK0EL1EwDsMlSqRjzCaZD0BKOu743m/rUpA5nAaZpE11VF3/O5tXF7Sjkp0xryZLyhnbT6eBOtIxl8KSmrYjlrHPN0O+AObgfeeSRnZ3hdFLaLkR/AiwT+/Foky3M4WD56RYW5+fIbJoCszfUMmuuakVhTqNoCbR8p5cqKJsecMdmODYTDexBssGW+QpNUaAgjy+66VJ8qeXTN54TIYs6aVAuKf28Ou1Q6Q+AHgAlMd5uPxNb6Z8+ohWbUFVly36O4bXrWQ3ukIhDLlQsTlRsafSOT7MwV9VrQX7y8T5aWrPRAcwJcJA0rchWAMHQrjyMLXw2N9sp/d5frZ1fqZl9ALk5VjFZGMggzry/LF9KsoNnfSk9oFEF6RABJ9J8qgYYigLHEjXitWVO4SgKvhhsMwd8jloQ/MB5O+ySzwCYvnGdqD8YtXPrkHklmhw+4n63DKoAkRH0UszkThbEBJQ0Pw25ubS7DgqkeSiq0vkWsW4DmKEYzuLde/R8maAyVDrWc2XaZWT+WiRJUYhDMe2G4YwIyi5yf4az0rfnsj6De+Q7QNuY/1LIwngIdi6KQjf8cwNGXN/dvIqlw+FAyWdbX6SaO9WI/tE9kwl2B7rvgvmS64MjD2hIzv85FAdFefxNHCcv1yZOG9DiAmAHkQcjIIOrxFChsqel0OWR/k6vURqdVqTWwjoyYIJbc3R+CuB7ODaCnqQoM7gw0DH/FVYPbyI5EmYnL3kXkBct1AWdBBVDxSB7xotzdHP5fLB+UykRMRAF7g+/bjVUnobgoRbrYD99WnEjmJz3aUmWL3XPDEiwQPgh1ACTSxfEEK0nN4Bx37EkYhMgmReJewZWnCeFWpG+WKUa7clBuYG1n+lLcq6MxwsJg1nsFmwZ4C5lrMMhCjT9QmlwWZM+5Q+VgUuISJoE8oAj8CbTUWVmiyGPMwxgW1feEKlcyhvBYiZgL7jL21MrQhepfCC0ULe0FdMuDCYkLUSmQvWMgXLnbbnTkxmaeUwEhLzFDYY6Ynx54o5HRCUBD0M4wjXwaA0jHVKYj8MXh0REeYUHpfEkBPP98DChT6z9dc2EvQBtYeEYR3tR30yRYenZ9hHqV4FtsiFgZLm9oBBLwBIV9PEXJNoaTfEtDfDwTs90xLeQnUue8MZW6i4Nrccyl9uKo6JOK7uvjaQsEBcXrf7EtLxM3NgdAbejzgJndArjhQOR0fmFEtSNBJFq0tWSJH4HeA86yCICgR2SdCOZgFUbXgTENhLlfBD4DyC9qV62OlSL1ApO5Rgxs6CQ2cF2JbNZJD/YUpwqdi8hXUfdUPWXsyzFMO8fXp5fUCkHqBk9LXCQBwmoyY9hCY2Q8x0ha2DsL55amX+Wdw4wjdDEeu1MtG9VtDppP/b6iqtWJnDdO2ckQz9RhXBoPZXNZjvOfRYd82Y+upKrF0dHp8hRE+83fExCXNGshE+ELZs1gLOb1MKUgNiXahG3jz+hMf5eryi2aJWCQEI+42jRTxhNFcAbD37fmIxWa0MSKuRiTM41iJCYiBWUoykDSHtBUnzPF9q6f6Eiubck8q+4i+Wn02xQTjZRhmZzC2ARMxIEJ7/cW4/1129FWxEGdJn4UKvudkAof3epNAuLO33WMWNYP20E4BPk4LXxDfQ8E6X+JJqOhgVG10/GY8mHp5Y5ga2bo8PRVObD8yLwjtmZxeFrXHi/z36XFRaQ3wz9ursyLxoPKcxzyhU+BntMfcIB0hZwmPQxQ70xm34SGaK1M3dBG/py1+bnus22b7u4x19uudPdasVs1aw+x2yuVahe7Wys3uXifTazdvYzcH+2UScucesGc4xHlqhovXoq7rJTc9byHnFJ4tNxqUdmvNyn6nW2129ytmuWnVmnW6v1uv7FcZLnnCzzhrXfqjeMOpy7pyp1RTZR6mveXZGlsviweShFkS6BxgJPPaS6ISJNt/WeP9GE1UPB82nLgaJ36TQullkB9fArBkfWwvhcOMd6vMZohgFOahn6kYTQjRhAhNCNCciM/MgX7WYy5gXDDEpTCknWz+qXykjm0B/v+QeTa32hYdp12STDicEtgDqikRTcHcDa3Jlgd5WQekYlTKxWajLH67Q/6/WpmMGfX87WQkcaW4X23Ipo3oi59+Oh2A+4K6wU8/HUzAYqBJy1d+XStUWaKJ+YnMOIgDJUd66b0OM/kAnCWDQSg6oF1Ia1XfEyP2xe6gro1gG6AW3+9YLP5NHAuBfgMX0JD0CTh2l5ljc66rdr+6m2rASd9oSCU3fAaVGrk3Q7GRHhXMPBefI9Saq57XKR6JNbhPWGSOBR+I20M/A8xBmGyzx17BYPuMpq75hchjlMCoCnlU8HL1EuRxmuhsoZMCuhg3XRF8cd7M5mEpPOfcliDkLCyFicxcMaM5CabVGquUG906M1l3n1pNk9YqdL+2V7XKZq1Rm5TeC854nvFyTlp+5AlWfuofKSdfLa4E5T2Hfgk0nDgXv2u71DXZV0q3n66BnLvGb1wl3QYKQSdfqchvXHNpxj0joqCUY+hpvHgdqPTiT3P7JYRUSshstnkQQTapspni93qjKEjMJTdHl1v75e0S+QCeFvDCWMz0xhIjxC1GvcnmPra8Vh441UW9XtvGE3N7LH6AOVVLxBq7dJA2qchzZrEgnpUcRMwOupsajLoilqM0OVcZTg4p8WS6s+sUAKu0zGUklZ65rH4hF/LSNbHSMuf0YLuk6FKaryW8Cnq06unlLPyEGDgc883hhQfhipGPGVEJVDPsKv5b6FqTMLY5UvXKVmf/YL9BawflMgZplcsH+7TKDsq1vfLBXq1Wf74YhJm5DvMfCpkJeUm3TuzM8eAn8OHkoAuS5GAHxdfcXDQ1k4yHmp7AMXOyCLcDQaoQoweon8piHjmm8CGjRTorhV9GQ8WYPRDsNAR/vMBIl9GaVEA+Y6ko1bcvLmBsFmA8LOt24bzik0ZiqS6aV7OqS0Xjg+c81Dn3A3jGF34R4BcTwmTFs0Hmec4re5+ZgYluTGTMx13BmuTMHtiB+AWWqh3QJ4iZhXnsVMoiYhObTf212kiGM1aa1VK5VC1VdmrVvGGMcwPM15y0hSv5RrO2ZtFj3VJKd6d74ucJdqjHbDix7fXZ8myCDVaXZvHyc56fSekV+/Kj22sSZINwz+7BpcnmiScb2QYik1Hi4flYmrNWl1sabzyn5NJzNdZ+JN/vfqtHcsVEysfd+amU+lfrO967E8d79+soIjoBllNFtCiZf48yonHEMx7qdG0hFY9xprbxFeoWrAs0XWBSQnwyBIMu0Zdol+q8XtrmAHQ1bHcYpoR8tyxLVrSQiS8TFS3mbM4PTThEv4d5RYne7bj5xj2b3z3bhoCr+QTLyEqADDJhpQh4QB1ZksKPTZ0RMjDmtviMemafDKlHByxIZrNM12epINReLy2QUyWuqYQN+AwDiW0X/o3KnRVdNHJW8wdjXnvOgHG2gloquD1w+JwDVQGeFqmVVdwmTstL0DRGBYSF8jBAQ9liJK2Wy/HwQ8W8M7I0xBTiVWOb2YQsl6UHesmIKSHO1uDERhmRo/xEihq5kRZrC4CDXVjbduaIR40O1aLRSNgueSOBPVhkO0a6l3bPyjIoB6IUi2iPrP9dqUVrKOe0tPIrTvqKVWhWKl4oFvDVqgipF0Uevsak5LZWdW5RBk+WrXspPp3CU/XbS7HbLEjv1HEmcFsXH25Gf2LA3bqObrP4ABocHCJ99Nt+2BHlDJboMG4LGWOm39ZAmxbsSod8wvIzGnbKol1FbVeSMzWRbrPUCztKDdL2c4bWJbGDJ1xrmhE1wuFFYOcogsIi6byeqHIUlYqdY1dNYB6vpULvBAHaAhV5Bh3EB98IGaprIsOAPrWDwFlGCaNPBrRc7bqSVddWMjTWEyB/X+3uUgRJjfbwuOMT4CThYxbKN7m5OfOxoIpJh8M0y5qoyAIIMtLkoWKo7uXGtX1m+vdRmjh5p6At1Qf3AosK6xAlMC7vbbfPPDu4XzZEI+pAVfvOml2J3APWj2db7F6rDK5hfN/r30qICeueOIw+Mu3xjOTKCf2vRtQCG+R8C0X9j2q0LFR2NbPp9Z/J+RsS8cSEXQRqT21xEWJ5fAZVg/0SuZJqv8CWuQfi3mMdzIhIEiOowxTM69SnEekRz0gRbHakaW23XMYDL2CB4EcdJmi3nDPYUtO4BGNEhJ0DzYJfrw+0Sp43I313Wiq/iD0yJ+fOqJAQj2ENDz/xvQ8I9REreszknuRIiyMYFXsymQKZEPn15CJ0HDJg1AWnGUyiRE6o2cd+oyMOVQokBYtE8UARdlaBrcCBFQjJSTjJ+IzngolYBwOsb/e05/8yvoPIzIn2ugQmQMZ7eX4ONNrHVJ2ubNHSgupl5FqUNbsQZc3yx6LKW2/2RNQO55iMKPz0ThR+UjJpwemkBMVO1UObP5XOVCG0BacxJxEevkmJlMQKIdqPMMHZE31NTdbh/GHB6TVmTy8K/J5Pqaj+WcbhwOF281NDhEhGPsGZYy9VygwntDc9oQttEvnKqi03PJdpFVhANzMYNQlcqUpUI5y9z7xXvkp79tFKLxNHqIsInjGA57OkROgrSE98SK3ZI9K5Rb36pxlY/tqAKgVctkkkkFMfAYfH6ebx2XMZ+HNSnyJ6cySwiurWV57GGqnZ4uKt3Q69FHU6rl9we3Um8J0s28M4XdhmkY8DweraykvkFMsVsKA4NSmoyu36hEqQIbDo55vnCu7pvIHkceni+fawlzBeybLeC/Y+URd8dQNr3KEydSZZBOIa4C8gmnLWXBfkQ6O69mTQf/uXyMgFMz3UOUY7fYreSfrhgLpohxMlq+C76HDYE4XgiSjjPr9GvSwkD8q/aHKftp6p2vSxm2KaQuJv07Xp586lTyVeEdTA1dwo6eaLqTll1aG+6atK09NzylN6Wtu3+DcCgBWq6yLVCsWCmjlu6AtYC1LO0fwzkhmaMmABhS9kldCOyn0ETC0M7EluFQWxCHsKxJUgIWpnLQZkkmVqyX3yUKWYBdInPqQm3Pp5HFFYRXYZI0/U9HtzJhn1NZh5VzGv7aGP1AmXwTTAZi9yRooFedMvSiMvO3Q4RppOUSGYwKoV8MtcIo0KSGhyxkfMEy94SMKSXuS+3QMFK+61RFoBYfCajy8FguDxxRi4T75L4B7A3kEpor4ppFM8vG4zuAIoHtBh/nyn/swEhNyAucFfWwB4d7CzY4FdA46XXzKjFMuSyQc7DqMegNAbQxr0/R2fmaHHDJGQzgJDJgXtYA4L4skaKiF3Bydk8K6hjbjzH5HcbMRLNyDgItZvtrUMaA3fG3J/o7TAfGmw61egVM6VEeVc5VKixddRxpZm3LchO5I6pDMGAxHvKnDk6VyrNTwe1jGNFYBmny/+cgrZZCbeJH4qHrxboR9i3lecVzynMmf8YfZcnsaGejwbeubt19e4V7w6Hmw3hdNupkwGBD+cRcaILJo9Xf0qw3S+yr21K2J71uD9fbGIhqSxWxIUaZBhkMxgPEPw1Xz++543d3VqDX+IAyrz4hZ2evprPt1DfeszSxT/q090hCqaGZE3xaJf4yi/yE6uSBrx+LdhrQOIihCGlAEdDmV4YXwJLwJ2lnqNizCZpbsZSiA2DHC8EPGNuAlfigBD8a5bOPhzGWC2qUFW7kQt+EvWFoQdxzbbDywFVERPfDmkPsNILJNDfYi3l7+dENGWPLCxMLgyF0EIfHJ9/Zb4Es/D4T0suMMIvFH8mY8UUyvH7rIdLbdX/dtQQR07oc8Mk/rM3/H9PvzXsN2uR/3AC00APQecR+b7O/8RqrUBX5h8MICnjYSXnBNWMxw7u6eV4Gzvqftr+Prj+89/OLcf9sM//nCGT6z39o/Dz2+ODn+j169bv+R3WixWpEFVestVoOElCzHklJ4pJesjbBIQ1AZ8OrsCTLlcqlRr9cantHs2dRq9+WUVosgqIj6fAgqD6p3cswMoQAX8PaCB8OzaPhnargCPkIE1MkTH1AHFcAtHzJOQYxCsodIR5JCzmW/koids7u5l0WCT7bOObJ+F9Ye49XPAXOscthZc6xQ+EUEIG075vjllOri0DfGnz8Y0tQ3TfP9Mo3KQnodF6hsW+f5ZJI48eC42aWzY5Ptnkzhh67nYZHfDJt8/m6Dz89lYZG/DIt8/i9DhEGEuno9N9jds8v2ziYyytp+RT5obPvn++WTS4fBczFIpb7jlpdB1ZiKxKFgYVbtYwh1CgCrzIOx/SWydxKBp+Dr0WRB2EsNmo+ysCK2TQtHvHl7nB4Rq24SRvkAY6VS483pujI3U+1dKvYyoZHgIzy2nEBWp1wA/oSE41+XvIbB4LJA6Id9KZaCjFxlfUegwxgIBUIMDzgENbFiXKh7kY05UXLdDxJr6qnIHOoW9gV6Ensi0LD8OlxZZNjCU2Wfmw5TuMOAWYGAIdAAZ4Hzr49+MKJc6CrUW/Ubu6EBWSFA1RnBm8wNsqWW1+4xaqTXXAUPSDP2AD4j8BkGeJfJqDJGMvmADZ4Z4Hr6Yt2iDoajqI+kBHtAh9gS3Dgbkyk/F4krkrf4jGdC4KPv9f/+n9gSLmHy5J4/UE9VfsS4rRFPLUSimtQXMG3IHjx4VgezM6knK3v/3v/+7x8RD36SwN8SxA+ZRB8a5L5GWjmddLatpRuZen2xRyyI/w6aTn4nFIFVmG5zhikh4CCFifCyz2TWi4MK0ZPhqY1eGKAOPMO1rQdqJz+vkt0PB5Lh6ZG84AfcQUHIvQ+ixPrpAmxCZUUzgWeD8UtEsopP5v8L52LhgT4EhtgOkepfzQrHQoViN/g/jCJlD/t0QAT9/Fnw+YIJtBHYniHtqWbYIcr5M8F+kcCR9/vH9ojST1LisNcRbIyHaZt92rHZnPKRp2v61IJrMTj2/viT4vcfwxIlWuuARKWEUrwH4WiJ9+IhegDvQt/3SpKgS1cAgP9txpFgCaY55Fmsp/rUcgTq2z9sUsvgxswiwWaYpFCcTdzw+gorItg+HDliuw/r00ebe0rwqukpLsppWCoYpAUTx5ODv2nxOu2oMjw14wFBnKsrEWJO6cNiwiZyBRWRuVZxaIBpGq1ZYu9ykDmQZDDucehaOFCTK8tEOZJUVsXu4LURhmgg2ukRasg4OkgrTCh+Zh5Fjv/xC7gqP1bvC7FAZbUlakKNKqNCwXIqJTzNCIC0zDe1JEA/5TzsgsCZjSH0JsgMLUFV9BDRLciWVu8J9KoOnziMtFyR9GhYfuQ6n1nPMIg1XPX0WD2yMPEBC0H3XPhG5xllMr77RGB9h0GeyPoFaWlFTn3TCQJ0Inz4yWdMsk6012j8Da8dMvDJb5+fqoWe7q3L0pMhOnVKYe0rh8Jn4WzHtLLZKMnYGc4mJag9SIdr9oth8OoSEJUB6lvJTRqL6ZKtru5YQj0VB+iL5zPmgKMruoQpoUMfZRq2IPTEzDNj/EY4KdTQ1xEYHvkS0AghIBLntgWqlUoHxhUSOQMpDzziUKhPmh3jNSKkOOHWuSAOGK0BdhjNOwQSJljoImIucRUapGMp3N+iNUDIQ8hODqCveXeeZyppJ1gGDayDl6RqzEX6w4J0s2kzdxRO3Luj+PL66hXUse7PkhfVNiyslg2YSFDk4JqisH1wkl7KxVp3ipRaXsRwhv2YtRnyRZI/07Ytk4dfawIw1yqFmuhCg4JB2XBE/c0qNVvIG8GJCxxJGjbR5x/U7HyvalPGHx2rWPEeD1Aq+iQKqEOw9oN4DOT0mW7e3p8eYzCysK1LzjY6bWoDMd5DXgkRTKMrN8bU+PZCrCDIksXAmu0pbaxQ1D5bbxJ7V9xq1esMyjUa12TTqnV1m7Hd3qVGzaqxu7rNmt0InCs7uIr6b+rGSkeS71BsKoX/TrXja60SYWmJknbiYPfD9wBZp89wj8NSL68UqIMn46yUfWjhy6jNr8m2ZfHYtg7wk38zrh14KqNdjgIZkz+bm26tTmIc4fQr2CiSKxwRCUjpoZsxxnp2n8pE2nSXRHGPmaWemw8sK5sL+PMFFqexguX6CGyQnTLPAc9TPml6dx6ifJiRPnoYOaGKjvgauh0183YIvtKSU8yMrjNiAofYUkC27q66F7UyyFMm9U78Ximby2Chwn3nHJuUKQfhiifSH1xZBqAmoN+3Z/kPKEVsXfdE61RbWKLSo57FvRRYr3b4FGrDo55Wv8D/w3RFZxLIsXd+weQtN8W15S82SzipxT9juZxq1nPp9CvcsbImdLXStMAY7m9rO+HQgeK6ae9djft9luJvwT+5YcZVz4WIA1nRBxjn2Z3A36GpJhLsyk9Vr5XIWlqVESsmUX2qeGqLKUqJo2XtaGPCzHSJXbMAfWeQMwZfHlDukI0Etv5b3YH0+gamogDxwhDG0bOEP451jKe8B+AsE/YxzRDZeh/UeEnoAzMt5TN2vKd0q+hYfmDwMGCoaNoscU4HUBtSXEf1v3dCX+YrklfwrJhRJtOF2nKX7CnS0xDcCUAiwWF5pahogG6vheywQE7Ii9HIJlW863Ge+ZoUQFUil7H2kji0hrynu7yt/Yl/VRF5l3XgRBe+nxHFeBXD4qOexrCNNS80pQjBtP9Yx7gBqaTz/WLsiomEZnmRYgXkWMwLgp4LPvkTIAlXAXrSFM/yRh3iJMqXZ2ZGjGzdOO8onouSzsgnBzdO1HVCaERgbYNEljH0E0CVMJWI0TJ/+0Lq6FGUuU3hEfLcyd+QsMxxwfNnAyGLgfFWE00sIy9oVXeo4UJJi9jTUV3PmEyuCqtoHfg+YiYJ+5FW5hP95lZPouRZYy17gHPRjLI6KRVEXJS5Wej0+3J9Z6HWZQ9LlHnN922zPc9mpJyMVnjhpHnl7c3Opblwysh0H8P8RpxECPALuYfCN2iZ8NaBoX4Z95z26fAlQJx6zw7E2hZyP1uVpOEo10r8WfxBLhqnp5JKFuj9w74F5WoGF3GqCHHYJlXWEY861M0n8DDFDsDXJTRdPaTXzmXxbRmyE3b39Ju2YFutO/pzn5R7PdsmHu91zucfaJmhrKhQfKjEgH6YYBPHzGBldfghRK0cXrfMTIgB9BCxiVGlBGtZ4t6shKcZx/8KYpiAzaA86wArHiT6nGjCt/yzrAb5wZqsPz208sF0B2NiWVli4zX1mtlEpynodpSAHytIRxxfX1ydHJG5NtmC5LdCL1fW6Tf48vbg+Obq9OvlrjmVlORfgkpQY6skeWaLq9BL3V1bqEPptxG/CrCLeg/7YD9hAWVpwcZJT8OmhsUuI84RgtDRV5dvmnmFb3s3ca3cZs2YEXPtpqPFp5Ix6JNBjRNTIC5P8u/RMTlE4XQ/7Vgjn1KOaQCnGB1e7eJReK580EBPpYJWvRF2wSNVCDyz3gkyryuybyam347JAS6ip2SGmkZLKPaFNyRnP0dxK+J8MvU2V10sfkSIhVFivprbdHF3u3B5fRsVv9DnMQItdVslYuJoETdYLEOJ16NCxws5OlpeQSpq6ocSlZ801Ga7dhzFPy8uozLBiSYpU8fJsrpHUqhQihtP+nKwDApZz99mqUkRMDvUkBK+J+hRcVqeIi1PEgaMvUaJimROiDmK7z/2ZBxr+jtcnsHRcu0plI0RCUzML5fLdpJyCNDGY5tgW/wKQudUQplPpIeE6s8hBUfRzDyfNu3ibapQBSkhp8FwUmbIdLS7804T9glbSuGG1hP9Zl3F0SMcQE9F2+MyAkeOzSyI/JQoBcI4Jef3iNWUSE+kcL+kH+CekHtQ5cmf666O8E5FtoMIg4sbKSbZuYkIJibZI/5/5kI6uTGiA0tSnrtXhT7POQBTi8gQIhEML3soWN8X/DsT/PUG4UgB/GQ4D8b/wqyfHF/87EP8Hv/uMGKueyBjIIYOX3DHltE9JYsF9ifeKRw7+fNuTKVFUN997wATG5HiPrA0lENrUtdrYVa5JQSVW15KBlBBG4FpTE4kD9ITjAhPIhOUOngVRfMS/N8Ij3VM0S/RAMLA08sHCBMlVCJbsAW9NmdiI4Y2+slLKDDhmkVcQ5t22rVfAQRgtWyIXHNUv6VR6lXCxvULU1aj5pJsrzRUmjAHfkrdqQWeAcvXHsW6RYTlB6qhWKkABE8vudiPmf3Xx7uTq6t0VOgZjs7RqgCWKZIabtLYI65wonCrUolct4VZstVqtV5E2lKbeSQHuchcluEAytrJjdCUPzCZHYqmYHBAV7dbEUzYHPqsKPpsHs8OlOBrvs1zAwvMLX8VlMfDhiqYcIvW2hPmnRI5kkgQL0s9P9uHRfcQveGiWL3my3F75LJgVYDF0qMkIe7JFNLYKtYA7bjLQIrqYY5pO5aGeduHhJaImLM58GTFh+2CKw9QAallgb9iknH4TKad/GLc+84zTCNL+zwLc2r/8938Ksl3swbedVBq6GGTALMQmnpkuqS4Xcbyh+rwfeIwOErDbNlzOQgyANcwl19dnslYiN83QW2PMT847lGaUh9LfzHKoIfOAZEqhgDUq8iQW6TMmS+8pCSs7gCgIXCsuAn2ZeMU2qrtzzBtYdVIrdAiRkPJ+KMjQUwVQkX45LnUfLdAob2UuAQk4FxQj3pVF8eREwxerGIjFMJcbQ2v8rCgyVREQCLpLe8h9qJ2wVI+JDr4UdUvIgn2plmg+Gtpx+Oei/cSNIYpAhAot0Y9quRLajgTricuILVrdJ6rksRpoT02ULtHLIC4MohY1lmVMo4IWyx4j7Ch0WMLxsgSaaAyiAgoYmFRlHPii6ESqKXTTp56QlIt3o5pCN1iItS0Dx5fpLNkBXPLC6bhEX6rlCwEwablhCw6gWkLilihg2Y4LBS/Y10QHGeWKNO4uaulv8uKIiR4LlAyUJ2mCzGVeYnFay7Tlcn315tP7X6EWZDGyMbSzFCX9bS31HLSGPWhxazIKQ+XdQzgoWiZsJz0EX6o5qNNF+k2WXvNMxSp16ZKtGqqvhHcXqk7TQLm+VIHVlUIgMpijO89mCOdVvOAeqeNPhBDa4t39CBMirz3bomO/GKUruqA6+XGpWrT8lKFSj1GtQ70eEmWvRsZRDM4NmFVMDGIxSRJmaSOVJrI0hJ0ySEnSEBxRlJZPfMtSCB/Q8KsAHQrqq1MSulpH+OizfbT/zYmw24eFVaoHtXKxUjuolY3K3kG5nOV5nncE8tP9nLuL0X3LBCs1PsW1p/WuGNIfOnbgb5eW3Bo5me95a3w6w/+w2NZc0yD0XuhQRGN917QP13YsrsMFj8WyLC8H+p7JHvTTMFaWIvtNP/T8lyF8NNR3TXp7wNqfeZpjfWoD4LMo10UFN8dYApT8KUxi8ccm5NOCwioqv0NVReaWRvaDPWSWTUvc6+3ATztnth+0ebcdfG6D86VDfdaOpub/B/6MNlVZT9sqRvk61BkBZmHoS01GwX3iJETEAg3iKcm5Tmy37cc7rjqOeoyXAyiT3sB2FXCNFj0XB00CeI3DtVZy12KunWoSW8KlAiVSAlR5ktn73RowzzbpzgUbkY/ce8ja6DDPFuc7YyF7qSMmR/qeT9ho1ttnMcJ/YJb7UqSPx/p+ib/CqyqvIVg3BM3BQnwBQ26ySu6i9rK4MboFmdVe3ozYeKEq1xm7otnCFipei6/byfK1X7lgLRxuhPgS0QnzOW1TsUFH1F+teOnKIOoTu7epW/rM+6eX/lv75m3qhz7v5ukF+da+eZvKns+7eapM3to3blNr83k3brra1Nq3cFMH83m3MPYnr3/vNgUqn/n4URM8iM+wdW0I0MJ62e3JELzNRubYyK//oF9b+NRqQUEYe7UsopNot1o4UBwrungMyXjIxAJewhyxhjMsC5Ulef726szoejZzLQhAT2ITX7aOMAZBwNzNtJ4NqQkhcHyYhQg4P6BnamqXwiafgL4NaE/NLvoVGFzkmYkMj2mzfUHLSthRaBvzj3uHBXQJvsFmEMfpyFI2i9ojsN1aIylrSwsD21o1rK9RyLTZhR0BuDHbWg4RKZA7jHHH1wqjA5kLIqLsR+bLDBCRlVCKPUVhwCE9D26JMekxFwwFzM+No8kdu+Y2Pz98brw0k4pFCtNRNmWiDxU6BRX+Kx3bw1Y4aQByZzp2EtBz5qJL2KgUp/GoGcps9bkUSV9eLE1T8Cyj1D8Q3AZ8OoGGVqkb5YpRrtyUGwdVcHqUEFjqUwYtA8efUb8uJSDNdiGXJSDMNb3xECQXhrvL4Lr1Br/lHmuxfOtniivTgjpnINTbHhPhh1AHw5NosugNRdesRKNRSAsx9m3yrAo2EDkxPnXtwP7MfK1Hn3QYANghzJtMqhyUyE1cfS/2QEFUJVN1AhVie+yJ0qYZlfiTh0Z4wSQK18xDA77ukoLCDj07gg67K5R+ojtD6gU2dXYgx/anuwIuK9EEgClg1P+nXKmVq81Gxag3u02jvmc2DVovl41ytbnHdsudXVopJyoMrIYakdfppTSxGYUpQRoYGCaop5RAwyI5/PjOuPztlGwJENhtyKGRQtoYUJf25vkAo9eC+FgLtRQ9FopTn/y1vIAS+uNMPscaovDh7Hlfn1ydts606Ua/uL2C/z1+d946vSgUCyfnrVP4xelloVg4at2cvHl39bFQLJy9O2rdnL6DT45P3p8enRSKhVbrze3pcVYuaZpG76oyP206TIMEOVKZr+hgtnylycUNRWUjaaudBV4QCXDbDRCwcgIYaSI1RytNrqjIggwmTAWyuXXtf0IWYdeoSlu6ljz/6EKYypCaGVfdzm6zaTX3d+tVs7Fbt6psv9Fgzd3dyn6z2dmrNqo7CSV7Sa7D+hnTR0yk+Aqm0w+WqBlAoAbI7PV1K3t11ixTo0u7zKjv1mtGp9MxjTotM6veNffrlcZ0GY4FJp12VBLTlmIUHxXf0rxraQqIlrtm1RqN3WanXjFZ3ap0qdllu/u1RqPcbdTL+7v531MyzWZ9VMouuvL8VGvMWQeEEZCvurmi5unsXHqI6s/xAth/c7K/V61cnbzOv9vz6w3BDNSLPq4arV7IW9FNup0KLBfXpn7JR8l0kkvG4iiRn4rMAiiaowaD1PHQYUUMB3JTSydN6q7TC1xiNdxlhkpx4G6bDm0jsnVDvTuxWWuxk04MtZSRdEYfmRbSD89gGF3UsjWfzAYgdMs0zrzkjnG6oLosAF7ulcu1aOzCQeFCFRJQOG63V6eFL39N1pJax77Fk/lr+Q6zzc2S/HAIphDInnX3JRSuHB9/Wmj/o0XNZQThsEhb/CLkTDvCKSPHACmZl5Y9F8i6WmOVcqNbZybr7lOradJahe7X9qpW2aw1ahPXVDXjnsjihxl1FCYrK1s62eL7YGC7kFJTOKiUy2WsSGuGULdFDCSV5ikchuj4pPxNKCHzDyl6jwVtJ/qYMovj7ONR/5o2o4SoyJ+KxU9h9MV85VJnHNimb9Ch/fyiPDHa8tI8s5tIFqx4vJ9Rtqec7Xl78I3L+VybuqCon7/DLyntX1rYZzNEtrz/Dg5lgbrjd11kyUnFNLmaL8XML5RI/Ov7PeEd6loj24LzNTnxQ4/RB7C64AuGB5DPAMczaqJsqWiK5V1ZIGuuGZ06KbYesBXjGNqrSWAnIXyiKA0lxxPZQF7SP6oZoUwKCdDpY0z2jr6mEcPSEIiGuyVKYMOY21BtLEYnyxhMFErOMKO2YjQrNCvyLqBo7WgoWuA08MS78YGNicdkFVc/AhmFRqocs5iYKJ+IT02VaxHEa7PdBOXmYEKZwLPV2l69WikWena3cABOl2q9Wiz0g4GDP1aqzXKx8Dd9pGJt+MtqvVEs/D1kvcLB3n69urf/BakB8EMp6IoLEwLLOAYjblh2z4aC4NixwCaatfpJvkHUPBp1MIcarTdAjHq1vl8rFt6cFg6a+1Drtli4vRaUqDfqtRqs1PdTuLhFOnBoiDo1iZnEjs48ribpNsrHxbNG0Hg1dFfsN61bSQwIPAy4yZ0UESjJoqiiF/MTRdcAcUu1n0+cm7Prx8q8BUSD6Gu4Obsmj5VSOZ082G9ppZ4rs3pOMabm77k6q+faKj3X0nt2U/NIc3Q7i1FCdznh3GUCqzwWzpPAt+LXXtbAs66+dmfcNrnDN1fgclfgt7SpsI/rz656YdV0wU4gydpkroILe0lNFNDcJZz1gpPGdvFOrVOntajf7/DU4m034gyjAgGxKgKaFgg4/9DGDZZYrtYYoh9xGst0Ixp+wWT/AI1Yx2q1JCbmbLL8+86H4ofN6UhKi3maGpAgoh6J+hGY2h3Qxo0oywvifQBK1SeOPbBlqd0ThOv1bF/AJwj87VkxBpOGUYengmfDxUJtD6s44ZNAmoMhZ15akLS5zQnkeP2uIMEz1nC8I2Vi9WMed/Vl2igRnf/W1K7EO5whCfLZztdsOp8Kh5913JcsQRzlSkD5hkIeKzMUMALA9ZSzkKX8RU3WqOdFfWbpelhgNl398hn1zH6bub3Ukio5Xt6R0SGqYYBdEtEl3pbxVPt2kLpy7RXdobYVdjjYCWpgJejYbg9/bNT2qsVCj/Oew/AXtUYVfjO03Z7FB/h9rfElS7mbkIqplGVP1Ay0Ahk7UUyqxE2OjovEzhcRjFi5BEIEcyoDvp0Hx3R6CaKdwuqxmCPi0FOk2wAD7YH1YP+3bJcMbDcMmL8tVGjEE8cjj74aonGLVGtiW5KIxex51A0d6gGOj6r6ag8Av1R+LkMkt1ipVxL9d0LzgSX6JpOdA89UDDE38uiTimHRMeL7mNQxQ4HU3okDYQAOyFLl6nB8UTxZoQGpOgdJrIbEcyOwnSVIL9p9+ZJPFKmnbX65EAWpLykWJkTCxNt6wXfeRGfyZZevz2/OoqlRI481s9Ko1WvSmFmtVfb2NVNmvVqpJU2Ztcp+FSKQhCmz0tyvluvfji1z0sKyuDmztldt7gtjZrVZ26/vCmNmvbJfqe3WYaEQJpkZ/PPb/JVhZLtov9SaJHw+FarcnCVVy2W8Jpq7TbDR1sqVwkEV/lXHP+zvNWEz6+Uq/FDdh3/WYeebtcyaBsopl8eim2nxWqdRN9cgy9l1F7bYbUy7G9Puqqbd2TfbpNFvAWuf6mlxC+6Pc1lnXFI55PY3eiPNEdMzb6vlrualL7DkzZXP4brCBfaVTln01pmWF1tYbNG3H9k26bCe7WJ0sIp4FjNglu6uEFYiQVjAXO9gUWvWo4iLKKcy/SKN1yVfQVH2I/UhWdQR7QOJ1akND9s3oFALmHvRiC6hHZ878GSJ3odqIxHKEMutXb0+IrVarVkiLQkvFz+17AHDIlcSP17WcKIKADKeWw+zpBG61CUAITpm1CvduXfuFbx7fAVexzQ/Cxmxjp6Wox5HwHGOo36SnicApAcyDZlnc4s4aHNBIYdPOJzywZ1rkDOYzm45ouAWsoTRaMJajcr2AanIvwno0hCGjhrukT4PvahVvSKa7ZahXSPqNKVlpZFsut8UTetVaFsrz2q7V50YtlYtY+NmGQfGv040fOdYit41AqCXZMtoVBu7ZdESusCmFh1rLZMFh6vlSkNmo1aqB9XaQbn8SU/OMyrl8n65qEURTYZaToVzfskwQQV94JAFHpqywRrNT8ogKAs2YPcqA1te/bm8jtkvpmd/KA0oFDbgoR8LvmgBUvTlv6RuCwfNSrFwdFE4aMCbMQ4A+aJhV0zTdZFVIpWJgixY0/u3z4NSh7ql0H1w+cgFi1u1DqZY0+Mls++UTDoMzD498Ty8hCr63/72zb6Df2nUYMkAbYy92UO59owLImk6nyAL8AzauXxV9A+Lj7OAovGKdngYJIxN0uQlbFaa9xj/6pOt+MhuC6jbCMdZWpkmTGcdFoyYKvoBVxnSGq1B6RV95zglEiFzC9qg4rZYQlyzPS/YUdxWuoaUrWrBfqKm8NRb2aYZS7JFHR6y5RcVLL5MJ6rlWmyEE/6WeYyf/QLZHIDZQTfr4V+9u2+Fj1+GBSMf43zlQfoGJ5PbszByNnLuh5dzs3hqMaPKV+CtjQhZanc1xluD5Uv0ptW/kPVwczmvM2co151icGBPkcEBqov/eKaG026ypAMOklymXlwh5claTX+yrue1Co+CHyiUbAL9jnkGlnmZCHXCdHfHkTFMFIOvbFnkXhWBmaU/LXp+gcZYx+fLJmJNkkNYt1JMCyk7RURmmjg60iwmtOfnvZm0iSY1oBVuJ73PtSoxz3S5pJJgtgYRR9NrRi6q714xSmp6ptj6OWgczXK1WV4wrF43u2O72WM09/YqewsH0+e27esjVRt7tTz7lzMERl1KWZv3Yi42bY2NSr1enrnG9DJps6QJXgx8pL2zJ8R+rrjxXMaBlOtHMxBMGAbu3PyWgVgdi6wCExaBdV9jUm5/WSUcNtGR2NLMqGBRpe3ZACDSShaBUtAue0GKQlE2rm5uiB+BEPrhAP8kiyNL5ERQU7GeXSEO6xUt3yPe0ZQqFUFQZKkE3MMKdKKQl8DIVArpgFtAmYmhyVYUlzcGj4rmixo61CUOe2SODlqk6ROxAlEUGecpEXapAGjHSq/FGch5ztkxIHOMuYc//oU1cMWq2mnoTA4o7lJZ1wgCqpJqNxOKa2HA0nlgR1CePB3J6khWPBSvlgzyaIiusAE5tHohLPTfqP3TfqUlvE8izMcAIgnZAAgNaitwKrzbLUzlpyOOmVjvFDhI4vxkwXu914mhjlQms8QAmjCb1AmqQUVt8DS5jEHQaEKV34CqP2QeJvrZMniWej0Qu6piHtYeQ3RQ+POdqxBASUt2ASfQY5btATIsVIV0OZ5WQDjkHvrZPNuKttovkk4Y3KF/ucODfunOnSGcLRsWMABwYO5pRtvxBSI8FwTcc8wr82Sw3xbVOEH6thFJETkjRzMF9ypatT028mwswJWrecfjI5D3qAa1g8BZtF2fmQ9524yH1PflUNxtm5w/2CxnY9GqA3DcEEcu4mUXaWoxkw0F5pE34N5CbR/YuN21mWPlJatohmJ8oRbLUSUIHKCMDNPJ19KyfZCYAsd0sSbyYFLxtFmkpc/MEALiF2z2mXr0c842zOqxhbmZDajttHmnG/qmrICWr90TBI3YgRwQdEqP5x20y70R9SzAAgRsqXyNAN+43WfUYl5bSbCcTe1hu8e4ytLK2Whge4AZlO9jPoQUsdC1fZBHMko2/1jiOdVGkwW6ItooL4K+F+bsYcgd2+/n/FgWDF6UjGB0YWbQ9gOPu702C2hvgZaYL9UJu10WKQ05GnJ4cbQBj5flFVzqqC0khHzuBdK2JC54YFLB3Hl78POOBZpZW+DoA2sKns7ZdkS7wmSqY12B0ltI3kuR4gfqyJe/kqiX/gNEWvxZiNAvdVXFegTxZrUti6cFPso/Y6y1QF0WVoFjG+jWAcBMcsxcmzqgr1zL3Ket42N+vU1oEFDzwY+0/xHr+HbA4pRO6pLQVc8OqZyiDdv2ySvuvlImcpP6qKgdhr7tQjFseFdOJoHqz5xo3jARchlNfvPmiZX85NbHCm3y95tX0A/wCkpsaa7nUIIqd+4FD5h/QI7FGwhfLSAJuBcdyZ+Ruf0VH07iacBdJzXn9AOUPZcmjqJ+rtB2F2eIm3wIuYS8iwGvcMH6hD5SG5kmtmr+eQoSxGUBaXlm335kr3zygY471Hwg5xSqTbC/thTYOxWflLjX2xmxzs42PNfwfAswERBZvNuFiZfIFeuKeh1/tnBF5B2uKO7NAhkAcsjXEOQROR7voB2M3tkR5DAEObaR3AMoYWHLsugqB10JPX0sci7wMzfiTom7BG9p4i7x+424+xHEnb6li4u72TLMzSXCYuvGXA92KoN3YzlH3TG5h74Odnbu79GqY6NZ/5F5Eg/jXsmVewgA5mGvT+idWytXIrtQwsgTn47kGYgnnVop5MuUqLn1mUggLCygcU6MlVYM4ooNnTGashwn9tCA2Lm9OpOpDVCX5w7Tdu4KqvqBvmLlRAfmeaQOHATxuX9XgG4wJGLMQ8QOISPqBiJbX7aWPpqwI+11ahZFoLxvQyoAFqoTfhVyp0gSKpLcFfDmiUvYSdJ9AlY7wc0lKWTcyOukvI55cha7bqT2DyO1o11dt+Ceq3w+LzK4v3TEkf+CBR2WKeGQSjoh1tdPPFGmdTnyibbfekWMdHLWvkVe/B6x6NPJW/8WyfusJF0fa37L0P3ZW7EQWn8G20+t96ULsDzDSZC7uZj8/gr7OX0RLLmjoqN/Q4md2Ru+0A2zOcBrqamxzu1cvk5SlgI3a5zn0u/WpJBMP4m0t83Ek+Z7qrORvhfizf2tbcYzv1TyH+N0i1uOQIIYtDTlRbsO5T7av81zSSaKvNyewvLWt6tZ0WlLmX9vADGUuxi91+2SlupcWAnJlew81YCmbGRZE8ooAp1hbMGIRQFhxGdMJN26nDRSTZte5hmZM0ZbxNicQYU0o7O0ySI7Z4xMuowGocey46sT1t3s+W+svMrKm8WmeTh5Y/X9Aay+Gbu7epSCpKXFhsy1fAUNDE1e+dohWNHdF01/6NAAOKfNh4E9sD+L4MO54j813DezVjJi/ugS4U9sj2ny2B4T5fPEGUQTN9TEDX3iOx6EMDDXZCIiwRDdG9D9DmYBSf9kHiNFsWB2F1iTLqs8/jTOPZo4ctHmqcFl2wVmEEvuS0kc8k4jzqoTgthWlw7SMrdaLsEjhpDo6jMJ9DRvVnABfOCedQn58hheJ6rHJmY5FeAfSTs13NR5SIQfFkajUUn+CIwUL1f+5Pf5MPEBHJYR9yzIh09ZceYmQKggQXA8KOuDuWbR6pYi+2jYHjphz55RaH36fGnMmKSv6Co+atESMURI/NXfiU+dODW26wfUWY5xJsSrYms8XTqJ9ZXqzFZMFzaxMAOVoTCFy/OjaCeR4r+4liLFKNRIbg84RlBvNI+vpHkspWV0PB44dkZEIUYYY3y2ivKQQR3Uh+APP8RofwGdd4gdEXheejL9kjo97tlBf5AISURETQwNJHSyFbPII/OwsaQ3jqS/I2SLo3iczashZkK5nbFmJn+xeRF8Ey8CjLTg7pIvArGXzxv9Ec9QG3UiP3Apy82RyIwifT4iDnd7iAQbeibzFf421LcSwkYOCYiiA2q7sNO2NTtQb3qWi5tzYuwDn5kcnkYBF5PTJtvlACZ8Lc8HHpaAk7JUe31yV7gS6UHk5MkWAvMtJrb4d4XEElJQFGq75TJmwNsDWFWt0oDflNEzJH5VnmMZOhRkIEc465ubswVMQlMkTLMFTQ2AlXIkvbYJrByEhR/vcywqjQhoXRET7wK5yUq0Ptq+HXDPf4W3QohQiVP3R5+7EIbojokDScGegHqKhkdm0mLQSyTSRuWlNfnq65s7zDVCf4d6gW06zN+plsuV3f3q3u72xPUzReDN7RPfPhOHcOYB/YHupEzhS+LTUbpzz8U5FlcXYvjB/iFY+GuPMQDJFh/Dby49nvyFyihJ/jbO9tJ/rwQUxTPKu6SMb/M45DfgxGcOJH+5PXKfJbPuMaEMXsyAei75EtwZmNNS+uo365QsjS42AKSZJ0yXvYWTjLzwhfzD88SKuzJFaczkXC5dwBVrQKRvcbG88pV+gRMXWaeQNgC+fWcMLw5u2lhFDYLn71x/SAcD+ASWbTIPLlPAh8hy7kwKPJz9Ks4ldedAVlYPq8kdQZ/P41vKGGwZPQLazdIhJoYAlvLtge1QzBA7pBY5ZH36aONNbxGH8weR6yD2SpQRUftHO1hXcMD9IN7Lzpgkds9irh0BCsIgeJ1CNkKJkNNA6BbU8Tkx+2CMAtwmpY+I5AqL493dp/h8BaAkQntwdjArwuUu7JtrQflW7Y9bok81LZxpZyzmjKxUJKZHRw7Mk8cq0PayesteubyfobfIzdzoLJM6iyRMxvH9gXSV7/j9vJpHLbGlL5z9loF8s9Sldoh9yZcpiLUuAwwk7Y2ahCeMEnG7hBKP9aAm6Z3LniJDHWIogVzsUTDDE0rE9AiYx4mE61WQAwplafbll77cxW9BOV2izTbgmEuGSb8wcRRF8XwVfLCGBxVnHUvSidcbd8kRtrtz5R7n8Q9C2pq/A3eGIf4ZOwTjOlpG/Mv/CFqIx6/BXUPM1ZBDbt+5AScOo54rSxOoZO2UpatLYM7NL0b8pfTT/3v59vL65Pr69PiX0k9JcL1KozwZcTpbL0il3AJqgVg/kqxNWc9O8/HBr+PaSxYTvieLsB56lk4vVV0i7TZRt7jgdZEMjr9w6Jh5ZI98aL3GU3J0fKFqEMsCvVq30BPwOcJ7RpjXzjjujppYzIb4sv4aZEjCDWi7kO7oM30WRGGvwC0vtEpVNSrwaLdrm+KMUuIPQHNWdWx0VO80oMsoAAjpl0sBzn0lTu1+IhpFDhiFnuDPc2/Fs2/tVpwjf3LCbelcLO+R1IC5TNZf5fLJLHaa4cvXoxFVlFbsppeKXaoelkaqIedOKhboiThL8HdiW2TUt/FK6oJKC/nKpOfxcCir1aWebJWgLZpOWvxM7royeXkKdDdFBMI8DNQKUqRa6sYoH+8Sj8yFHahplP3+D1LeIyBRvvrV9oA+AcwUo4OU2+CdEKVvq+ScPpFr8RmC+Nu90GPC7TigT3olT+6aUruNkuNRWE/7H11LL5vgg6IjWQwu2hG4P+G9FrpYEhBoLWpPTihVRQVOqX6rfKJ2UCIQdiVhm7qJ68HizBehHOJzWOQgdAJ76LAn2+0VSePpiYiwWjKgY3hm8Y4q3T3Etx7oBs6YNKplv0Ra8L50o+FgQlYi2Mv2yX2lXL5PGGswJsrHWorDQIeNEmE1diCa3Zfgf8iAUVeSc2K6iH0skPpS0afVtZW6o7mO2EJa+cybLJ35NN099e//8psulSiL3nyzOpm94emS4HqKA9KAyXVrYyVpaUxVeWfMHKaN1XBljEKmyIJZonFKWVzfy6AGn8loib7d6wOGO36lQh4mhRQNAjYYBurBgwJIkyISLU6xGmqY/oRmPKAPAkFjp6pJRJ7sZit+H8kAbdki4JL0+fGZ+nxkBHxHaBcGtKoaATfEUDvbxXSspm2hj0+JrLtC9a6wuMi6K1TuCjkEUbRPcn++jiiaYqspYTT1xUYcpZFlSYGU0U0ukTTJQSlCaco2Ui0UC5UsU4gO6jsd+7y4bnrNoOJgwFSQBQDUYoiFMs4mPSNarPRsA096wOQKTg5hWDgck2MxhZvsKazo4UgbaVE7xhSW9FKbI+E3hS0AEPmESS/qO8IJHfVtB4gl3BPSkgC0s807F0PkUKp31DZPXA2PzBNBGZFyeHt19gqkaMBcH6s4KxOgsPAFoQdFLO6PBLcYQKL7PAwxSZbVOeI4IkYLenxOlpgYamGe0DDCVwqRklEskDY4JiPYskfq2SK8KOAES8BbTLxRLGbaFop2eDWDzVMZgVXskuQFqR6YoR/wgXyUR/VKxCiqxZ0bSQefD1iAFlYujQjUJX+HfsRFeZhCo8tf+ubPyf+ILOSpVPKlnUB85kP1dkY9ZaQWG/obG4v5TfSM9n9h1jbTitJE9jjVOVAGXZQqZV81JrxbRMWMQ+EAsTOyrp0NJsMgpI707M+uJhBzcJfzwqRldlbagfi+Q/GwDejTqehSmnflTxXwmAm+yble+fVXnvV0VdZiQeJEz2MM5RjuwVok5F3MFuTkiZqBA9ZZhjV97uWC78Eido8WYPgBLGVPEELArNVYSU3nh2AlSZ6c67V7Lve+Nifl4n990t8u/3M/pfLRsZLlEf9DJIRYkH5r5BGQEhd/ljE57hB6e6uNJQdArViVKgP/4Z06hPLZqRM28hSnrVdHo5976gEEFBsQ0UAruD0tCe7cFFFAlpME2pGIneUTdmI8B/iUzZii6Fjdnj9pvmzN357FvFnLnjiBWUy4LFNnMu90gkriDGZSSfLV1yCTfua/Ip3STgFEE01z/2uVdo/qFTpaLEu5eXzpUEawV9cyMCBpS8TYb+NRuHPnyoKZ2bdHDvV98bSg0WGnPrkf8I7tsPsiubeY/xDw4T3W6L1H/Tu41zRM1CNhYi2IlEqXCsVCj6WUxZac4mt5Sq/AQRC6gTcuEot5dqJYY+xdzRrGoWkiJjFO1/b8gMCHIYDYAsSTqiTIrCj04L5lwlvCOJPf3SvpiJEUsjigmHJeQfgl8WBBNT7euYXfKqImyFLPlNYQMIjFQwIfDHCQEvvJxStKxJKyOZkb+nwWey7+RO5FpMP9gW72jJwr4vlz58J31LfNe8iAd+xHkVmSCJYRD++RTHoTHlKXC1lx5xIpLkRfvj0YOmhC0zuMvEiqZziM7JF5YyyQ6Ipse7wHiTIi6aJI9E176A+1HxmsiYqoHPBX4Vs/st7gO75P4dRN9yEIikPj0+3+gNxgiXPsSXUBcDSiUwxrjYaC6XXB2iAMrR025q4lqgLoNJaWWmFugDay3/yWYvDVsWHg78i+ZIBMR4Z87vwn8XvLgEkZkcXC384XBDMVk4SC3LdNSMiONhIi3CLKR+nAMQlzGhDOkImXOoppcbJap6QburKonTxpXcFCysQjEBvQio7Li02+6DzHnjA2Vm56zP9bdomVisT0/SKxB4DeU0SW+JU+0mucjbTOx+RKdi6UiymGVvYJPB8i7Hwi/0d0GxM+bc4a80dTLpL4dYQFwiXIeeIoLJ/x00hGzmpcn9zlTQitPGm6BM+Q6/+28NlvI142IdNSpN5yYbTaxq45iDYx3/yLSE5sxeBaod3EavFJdAkotWZLl8sqijNWgCgYYaciN0WZ0tQA2zzq0dcOof0KAacrRppOlMRcihc093JsNweRDegH4n4CmQMObrjlyNbNzdl2QhVGgzwiGirHxmRsNrh9VJJqnFQbB85hJ1boCSQbLkK4pYapbDnxveCyYMS9B9JhXbiTO8x2e+Dc8R6YJVU+B4aGcB2TepZ6HklPwbWYIzxqVEiscAXduZCuEo38yo+CB66jm0zNPVr/xNLvXFVn0U8EKEmgJpXqsxUl0Mi3hQjpVd4uUANFMk/cm+gBTpYXSi1Jf2fFlIZAb0HqG5XZ7XLXUIowOtKKuLtUv+wjb9Sdq4kDyLwDreYS3oFXUMwkIobLDT/gSmMwlGMH4hjuXIePROK06OB+QJ8MeCLu3PvGgD7BP7ejqGI/EbYhVnLnxkyj8prU11pl1jxyJXlIFpMtLfLr9bsLIs6TegMrx2TMReL1YEPWlic4AhW3m5szeIafULNPHtjYENfpkNpeXNsw4qhx1KfIxofCz/D8wcPR5ZFHdOwG9AkSIO/F922Yw/0BaUGYNsYGyWvbD0Ea+6RaLsOuNMrlEtGawING94gysBDq65p5jN8DXIF4NU4cpw4LRoy5pFIuG81mszQ51bZH3R5M+FSfrUh6EwHjQE1eijvXmsVpHO543lyxA5EVokdBRunz2KGYHk4hjYYiH4510eaMB1pJqQghxvZhIIRv0JJeEb3TjfQDbf+QSf2D6PxA661kgqpR2S7C3wUnTPyxnHwVxkjl6qb6X6FaLhvVZrNwsL+Lqai1ctmow88F1WmhWGiUy0ZD/RJngrW8o/SOy8TVkWXJvFeN71MXca8GnPpzeTth4NQmFk3nL/361T6YawddahejLQQBqhKXdbpKYk7E4YEpc+pGlwdaXjVHohhf7qtdpWUqIJKJaBdk4HEMPkFVbIuerzyR/olwarQbgHUuAugFCxeHtcmM6TgfdEvJDkqOWpc3R29b2yXSwuaBXB6IJvY0BK1aj6+R0BWQOhpw1T2kkbpsFA9QIh/g3oXgYwhSpqTSIAapN8jAdgE1Por3wwjmZJhgDIsRfdXhjyxu7S+fUVqpTbyLI4rgBbiBwki+iROMql27id9v3sVf411cK5eLzXK5WNkvl4vVvXK5iMA7e1X4XRl+KWAKqvvw78Ye/FEIuN1yHds0mlUIJVboBUu+o3VWWOUlLSmmwyzALJ9xufESbJe25aOjnZmClPBNTxx8RrCT6OWiIYiKqzwSN/DVhfzqJIJ43EicSOKk7YUuedL+/q+TQD9iYnvq1r5QlcCU7ZGTsod95mUg+YImFgWdiQ/x1N2cXRMhK0RiAHgIwPoiPxlA5GEnMnwccpjm9fUZEew2hTev2ulINRNDbESIJkLklmlCQ/5mIya+M1xXuXGrCIGpaLdZ8WwnR8dvT4yr65bROrmuVPeNN0fnxvXbVrWxWygW5O+u37ZgypFQgfpUoWv/EzIZC5MUIGCKbncdeN+4qbFfEwcSG5C4AVaexzxhiw09hgnHilnSvHsXrfMT8joeL/ksVX3Y3DXiYl430RmPwL0gi0IN939k6CA4AJjbgdbHF9fKSujLMmBgt2TUKpHzibQoAk7+ud70buhaFACYqePv0KGt4VFoU/Z3/lMtVxtGuWZUKz+qzHvLR/AKlhwglEvkCQuhi8WVMssmOslx/zqx922oQ3IH2jRoe5yDAS/6jeMsqyNN7G0uyTglUXKpStPTn5Y/OZf644qgeGNE4BD8/yPzgrQoRwQjV4AV0qGgsIJ9rGFCXSIi7lScnYZXHrCnYAdcYBYfucU7NwVZAgYmb2/OzyKfFZoHz2UjqV5Kjw8MHnD1t61tBSpTunOjRFqMl4oIRixuhkgfWFCeEClQ5JnnG9TeUcGc0RIMMWFw5O5sp+fT6u9mGe91FJH3BxX+Sym8U7ynXQZTf/vX3QbfkBK8NhD1qW19aTx18NQGGQx0IyMK/IAOhjC2ikiNnczITbKPdTNTnpRtsYipuh8pNr/oC3IOXkhwUnCPerZCw/IRQguiZCHMgmhdwmlhMfLWiHV8LDInUFSIy8CvIsENzD64KpPeHJnyiNK9I3HLIgn0SuB/OsxDAKIYRc8HxzyK+6ijIumE6P8KfdYNHTUBkGMD+oBiMB4ee0L4BBVju+XYDywKqsQIS+7pgZXCicNDxyL4KQLwgvTgfrwyz+71A0JHdFwi7yBRDOkFQDBTJMMVoxQC4tVIn4de5IJ3SVTaCjNLA97rQTBIt6vfF5P7trkuZlS7iQ/61J82l8U3cVnoSJxArLaoNpBqTshRQe8G44wC5j1SJ1n5QOTwi5DniVMpXME+2Rpy3w4gUEw6yLfhqCAfKG/xlst6NPmJyhO1OEy8RE670yOAw9mFcHXSYbGqXBScFaGp4PlI8xtNFKCYYItlbtnJ4/BCxuh4fIFG1abD4UqVZrtdjEDHenHJDIjWcOjn0eSll30HdHTDon6/w6lnGTAxrQaa+Hn7zt2KH25ZGQ5K4uhLnJefcCw+xlkvEG6hxtCiylaj5p375xU3H1hAzji803JRcMiYtZOowSgv2B0P+zIc7AvQhSjg3P95yR3b7+fpW9zNO0NssJOT4jo18hL+UmuzOP0VnOjKxD8ZUNsh7zrd0DfzP0Zpdyfg3AFIHo8OmeH3Id1wBySpY8iUOoPHne5sF2GjAXbmDMBs4V7bGnrs0eahr+CuipqNYjvvNGLDgsN61BzvcMcyQJEzHDmQGPsaJ0qucaKrrBF7g6TiLXAobZMzbuIjfLE+YTcNRzaN+RSQaQfUpT2IuANIouek0oh2DTmYBC7Oye4R8+Xl9WvVYHFG/0w9+nlFgf3nJ+gkD61wtLxkEFPLSwOcwwIEYADm2O7bbpBeUF671GfAxKGoJOHw/2fvTZjjNrJ00b+Cx54ISb5VRSy18k7fCLZEudmjhUPS9oxNB5wAElWwUAAaC8nqDv/3F+dkJpDYqoAiKdFSTcS4qULuy8mzfgd9oxEyDcRGII+YWAQVVeByrKnGb5KqC+OnfnvnBZ9+yyEQcqdR1wuInxeWwbTPEIDy7zDm7mF/GJJ8jNMd4nR3q7Ckfg7SSMFmy0emOK7yrwcZ5JnJIPuw0tKGfm4umjpL+tC8fzWX3Dyn3tZAlqUfWsS/CbhTy0j57sxZ0iJC5jsWoZ2iby0QXE+KN+E0bDtdr0xuV+xDxbV5ew6jXbFN5bn0eSZKg24KGr6G21ySTNHDW1psphYDNVKSxUyTVqTgK+nJ2D7xQJMSRa6O/0CUBVEun6r24/atkeZnQYsN8GkdgEOspguP2GZnWPgkXGLHhp47xs7QE5a5x2ozvXCPHRjjyVQUVgcTbV540O5J+Esnpj/tLymtOGnC8ARySzzcaIWBUiQCt6O4SXKDI+WlFAj5V8VQB3naOeWvCi4iJKaDT7ACmLZO+asCS/Vqm5cyLvoX35p8uUGaNSUp9iFiSIAxTq6rfPddTeT+7rttPij1YTwEQ7PW+dPgZ9a66fOkVSfc9KqdBXa8iVIFCyuEp0jJXwOIvkNRB6UWllCNYaZ+ojTiRvt1zitApEy2hmSF++dX08rRME0rcHgUxaNYO9Nbz/u39jR+lVJLdVs/c741eh/5nu2l/AG1WQT2fiSdY30zflfEckspdKxNHssO1xOeP3wQuZovfyuZBYdHbPN0GdXK0kvLi++QYprn+ZA3o2m6T/NsNPXU4+Vww/iOxBBNbmbxnnt7SR0vpnaaYEQyKHoBQy9gaMc8wj9QfkM0S0PVjg1VB80Zq8SVYYhs+ctPnu8ApEKBqAH7LFSxD08ud8fbH4r2WxWXEi5haYEkr8Pyh46yb8uySoHoW48WxqJLyCMcQVpaTUPVME4XUAzWJECwNPmrzr4KT5JNUVWOlzZUbWCoelN26KZZ8qNTHzY/DKIPOfkhi8Hn7PV//DvI1n+UITsUZupliB0vvnuRYxqEAFJBPPEklMk/nI+T4+O7u7sR/5EZwMI1xfQWx/+hHRO2z8f/oR/zYyp+MGp4K2r9cDRlw5Ju5Nv8YMD0e9zFlW5GsRfGXsptdA3e2SypCOoOLkplFWbcS3JgEMQM28DaFThlPDefyBJWpCjx1pAxkBa67hIIBqT1xey7eWYmCHVXbAHJ4ebeOnm3aMXHHL0eJIEKfufYa0xP/hNzzZSZv/aZHbhA6XTXjkhBkOrfDlzgs+ICB0cMAWlPdrC2v59HlS2NOh9JmKQmUxCbAkHoIUhhJE/XICNub5PwG0fQn2GDZjA8gT+p/IX5DbC4hRlvu1RWPDE19OKtbBuiff+d+dl/FBPo8VSEqe8FgJqP2U8a34qyxZNBjGMt5SKvJfDYmB6bJzdhjBtzF7VJwHLs2Z/AJorE0SKBc+c56QoYbyvzfIfBQC9FA7iU6BWCKyzRVeZZehpskOgUeMeYnipglUqFlZWXyp6nA+WOcvB/9HqFYfP0gABcDGMVnCdWl2MYVnQ9Ui5oGPkig2HK1fiEazTAtQBfP2A7bz16J6aBOpE80T1zaZWX6S4MXqRySxAL4jONCcwNVoQpCL1YAfdYXK0HqE70suqkvrOHV1N6Neu3RSYltY+Hd/NZvZt7Ppe1ff3cpl/M3NfMw+u54qN0oaoMsa7g2A53uSzf6fL1xX8fbuzXcGNhKztdUnY3Hu+WGs231Oh2S43DLW26pUbllhqHW/q13FKj8y01HumWenl++IYDWnzbdiZV3aCaOnHH1KbunDgLmxgamRsz3VFtY1JR/Rl6Q99NZtWi9+1Xom/320IHUSoxY5p4/2qMwjlHOeo6JkGSe4MmCqj4EOs3DIYOXTPVOmtioBQB0QwYWAoVQBLEBaGKBrHk6pT7mZVDuJsH0zucm4cZ7HZ1bezvQJyLk1g5PcW9q3w4kOtnRa4HR2FE9w3ZLm9tG/nOU9OBzzpPi1UYaQe5xRVjcAVv5AXKbzAyoC/3m98wmm5PTSOfYD7oyFzS0A8f4kskXULiOIg4+3Z4fvGaZbhiKfY43oUEv83sTKwIs7mBiqlA385tVByWdpcVsTIT6cqVPzzE5gzQynzo5xfK90WrXM/4NPbnxq56aDLLC9Dst4RKtUpH4H8EKMCyvzP/nO9KEdHOw9/xacNY9voGY8kHpLypQPuWh3t4fva4C4fn5zk9P3u+O6U9/cwOTF50O91CT26nmGsGDAGZJRyLmKd/XCIsAkxX2Zs6TOZV6nA7PdAEmSbgehSU4HZ6uP/P4/4/DCoIdvJzowOtyb2ZRWDHq/f5nkUcKYn3L+yacCBdJAmsknxP35N75QfW1Fd6WwvlRv9bKy10sSHSj9/cDX4WV1bD+I/JAJKFabPJAKI3dH0y0CcAXT/B+BBDnwyMiTowZpMBBHKM9clgPFEH49lkMMFYEfgP/IXhHjr8ZSB+Pfw1hr/G8Ndkb+T+4pg8MCoHb/JeQTgw+FIYjl5E4WhSEI5WisEpPCGLVAFSDM7nX/18RRmapXxYavDD/xFT9+jk6C/HkDklBO9QAGtY0TUBN1kW+mmCXq0MTVzvhAlqbd2UKaXwaq0tYBHrqarqH4Ojkk6w4o8sJQEXqJ0N35ij425NQRQiAlFDG39UT7PNQKpEr7UT3Qy/3Lh2XmCmfmJyPWuDk3wAzlCIwZmgZuJKylwmHGtIqgAWKfOlBSB2MHCHdugLuIsiBdVIeQt6GjaUASCvQXlthB7CIrP0gP+ogv4joDz3mwhwjenvvBSLBdJG2kDRRjrLb6uNDOWl5woG+VVeDZyPvVTA68lw8u9FEN27K+VHPuDbg/ms8rBWTor0ula+HJ7YL8IVayP1aHCkjTT8r47/NfZkkStb+sjcMhvprnEXY4nLpHU/Tet7bAbc/jNwOy8cBtEj3NoIa5IXKOvQArpixeFdwvAGzlO8xAXAJDqkY/JYl1Ucrii53RSYlkBCMG01oE/yBmViBqQK/cu1XTpQPn/5vsWc6u+tl2WL8bja13Yw/vdiBrtBr/kulZCuOeynSJVOfC/dMJgIRJ7A/G6o+YCiN8EVpY+Oba1pQ9Vg6RqzGOm8Q1Pi+TyKq6time1ck0L5tAThyS2d3GM1P2vQv9Aa5+rkUJzXm8ChgFedyFg+6Bvrh0sIXEmZSfPk+Bh+qS4IG5s+TEIfwISGrNEhQg+9gmycDRZOnPyufVeY8fOjZL3teRQw3W3pQOyHZ96AOMctuGzyx4f3vgPZ+dZe9+epAnuYCpzt5ZMowdpzIpRfkOd4/Yv12XbAu6J540V4qiPfHdN7nfmpFyHgH0sOsU1KLk73NrGcNazGKTu/u4sS5xai9hzTccKkYx2MfGbhsiahS69rPeLfkU1ihoHvBbRfnSyh6EsGqoSOFcW7zeqZMb2Lgf/r3IAVg09498LAkZaQonrWhDCVzrVYP/gida9TyoTatU5TDsOOdWv5HDrW4ynQOpauphDqVq0GH96tmgz217FGFUCsY7UGkJZuNeuRnR3r1UNbOlZEp/ruZY2OZWvOHl2r3U47FpWsDx0rVBQqXWtx4aJb8YB2vZ0hCldZ4CVA5yiD7OmzVuUGwqD7nEJMWG+mIf+rczUAoDBpHIexCWFtJjjYmOkqzvrRPv788PZWOu5lksaUrPd5xng70Agc0Z4bzNCsO08gAok2tVfwR4/DF8Xgkxc4nQlpFHu3xN7gEneuEt5vTGBhTOB6wqwrHxElNHNCuHzjjjUEzAPCipjEMxGmoTsFj2nkExsMEIiXTM3fu04yt11YmetSYPk6bx3DPzcZ/nnnWvxfw4IniXySApNpykxv19Yoie0VW7Ul7f4SCVhpHgrdt1Y/ZoNhWJqJ51CT3tt+1vmJTVZEM7neqGuVME7Nf2Y03piMhcfFYfe784CTHpNLfDOmdrhe97mO8HBopg7876ZXla4PJpRmSdqA+111rRVnVFTzIn44Oi8FgJx3LkuttR315CJ5Jfh/sPH1qhQR+1PX23FHrah70QTpQMKTxfJ3m6xb1LvMXUyBAhBTHiu/XL59rWiqMZFiGUhK0pjYn2g88mjqjsJ4eeyE9vEqXfvHsWtD8b8kjDMb6iNjNH6Foq1AHkd1AOITcC1XFoGiUZ8YkNgoJnZKY0DpA0gVSuyVktAlJjR5eXPkE4v6N0evUGNG721KUa05lavuQJwrYxsUsSn6xNgmAwOz0+Z0l+eeB25BeRculzComAJlQA0/V9Rxc/3faEpeKZIJsbH+16pJ/LmUj7JjmBGsfqEGgn8dlIhfUolYOZmcUJ7UOpKGjYdEUvbhv+uOCZ2UjwHdA/X2qO7j8HjTkH6RGso/bheD9rNMfpRbU87y1kQOPWF8RNw62wZnIIwL+eHyPEFiDG6CfBDUQdcFSCwXUB/NlQJ3BNyIk9RLIRssEA/04GBYIXnoHQRpMMOaItgwLItgInfgl3Sb+QGNkVoK54+dtsO21ZL0wW1FHoRy2LKuT4R02NJbD5vgFum65cVikSKtB0gESSF+TS04nD967bXzWl/rE7aPMexBp/nw1v35DWZtu/sAR9E3HB6WrWXFWxSqvEikS/CwqJMmDVzdB8FxMOG2nw6vbm0RgQjvD2QfpUsv9dakwK/iCFTXYTxgj1YRpCjcXASGGVxt7FTk1E5EanJYInrvpUoQOjSpeeYJaoV1L8Ms/YpZ64fTJbavbSSJfT1Qo6+OGuHGPhdCtAs0o6bRb4Dlht+BdPC/Xn7UP74SfDG2Us5oA0Vffzh9fwZ/MAQ8VgrxYUtFR1v9lao9d3JTupZvScVvrWUqgHYcRT5QnXLqZqBB1PeWmM2AzyFwJEc3flIAdDlwvWUW42j+b/mqguZPAOH6CIxBFZYwUPmof1RuNeXle56dEJftlRKRdLWvV0VXR7oD2ZYoUfUSSFem+ulAsL8Ggl3Z1acIOn4sx6sDQetI0KTdbTU376ccqiQbksO+UcnMcG2XNEBfdIcx4l6SZIiGFKRFlk82NJ7rDZOMl5OIiyVOY2+5BHWT3AG2iL7xRVM79Shb1kKmcu2lHiHHBVPFozfeBUkSaPZJM1009NdHA7TVW2FbTAOGNqExXWGA2DQubSACZ22UiaoPJuqYfUrYwZKOhSyLJSsmx5E8e0nj4eMu+U5IuZ4RMbPTUJnouugGLrqXKJjAmaUjlCIdQborpx7MlzBRPh6wSR73Rh1YiK+BhWjd4M8NIoy9g0fT7teNsHCnXXG+3JmWF/5jcGTHFF42flo7eFkV5VuvYgenPhlVsX5pOvjgSRUaxsE9JjfdGstLQxAxPnHd6vGycBZJvKRpx2qicOPpFB8H+Y5Ks8mHV16x0i7Kpwci7hpoY+B4wGYm4E+fQ77hsfUSxgOyxE0SoX7z4SpXKY6U05sAFprThjUlQVK0gW8lvBAxtal3SwtbF7xpRWaZm8CiAXW9iomrIP4V42E+LfTO24/fYyknWN4DKUX7BTaZG3T4RZamf4V54UkU7eJu+OCKW81/6M9r5QgGfHCbMFPuSJDmAoCAN+vGLvphkgCDVENPkT7An5udrNiFmGJXtit3p2xIHrYOb2mirGlKwGEGWRm4Nzw9Jc5PZGGAmECSpDSWEhVhdMhI+RtJPFt5+Y5P5dWJconRp7iNAu3l4sP3A+UfF2ffs/D178/fKq4HRr4hiEneOiJ2itGkXpIRX/lnhvGPovH/g1VZH5tXJ8pbHp4Y1zvCgqxpadClCMOR8g7ueYxlE4ScEm71uLFRHC5hDeD6sPkP8uBEovjhHY2HkNnJz1DcYm27XpykODcaYEkvUIiy8parcmnuDDtSPrBLyv3eGNe28qCoEq3CNFzGJFptWJYLmYXkJ7Ix3PDATe6iBN8aj/hMmMIWYrcXi8i28jNAWzWMNx9D4T6+I/uPdENQDgUwaDpkdSkEx7/HPH25+og5JLPcm6fnih2TOx80FpL0WqgpXiRKFuRtCVfsErXIOzuQB4k8FNsnkYjix2+OTDxPUfJhAHjFfn5uGLxaTEoH7RargYqsHy7fSWiYXoAO/45IkSZuOfdcSLiSqrsO6kL0JUZ3IAwyYSjvXIk8lD8diMSzIBIP0zdVd/WzK5kkXUldDBVfRcegjRowKB/ImUcxGezdyrNXUlC+h/kmwJeWOjcBd6JFh4GRcsolEoXtjOLl2gghq+R9liHMbgLPRSkYob+JYkMa5yG4TBUdv4ThKacnym8CceC7316hEy4TnRFZ5SbIM04WNQHSnXyC+VKbOmCE4o39TWoM6xEfGh2IVjb1cSPhYZWVJFS8VBFpKhP282lJWm8CFdwWY1GKA6xt2gX7ivYRsNjBXSfCy1mh9ykNEHdN2OVys1Op4jUlazk3MBTANoB80PuIxh6uEcwUyWkOk2NtCie1TDhWS1Iy3/bQVV6fXly//vtpgraQYB/0dQ1wErXFQp9O9CEf/xDG/2q7/0l1jV4WRV918kVpWuSiDXgndVU3RsrL0yAIs8CmGJkzzI2iTbhAfFuHsK0wgMAhsXP8CgX6l6cX54o0FIGKJDX5OAhM46FqDA3t1eFFll9k6b7Jr7H08+El/ipe4mJHO73C2+hIacU+I5zP10+apP2qRbe3Yn7j1bNoekcBQugOniRQZUQ0JpIxgOvSS6IKGP0vofA17+NAGiXSWNsBmUDWPn5NZLKDwy8rss4STA8tTp+G92aqquoXJ5zlHmQGVJ/sSUKre/4Af+kOy7d1AvmgJDCLRiGHvXQJTfktpMoFVoE8IePSTRBUQfr8Vef/LD93LYvS+rLJCy/RBenXr4kg/OmsIcRxBHjI4AhEVIRUEz/tyUMVm9uNhep7pppUn7smIgbXjlHT3YSCylLRENhS2U09PVdEY4XFJA3hRocBOOmiThXgXbMgV6Si6UVoUwcKDZIM5guNAYiZn7A20b0wS1egXCAp2IQ5FptMki7F3JBonJ5DEkw2t6+UNO3Dr7QfgOJItZf55ojV8xTyHmaTad3ez22iaQK82gFXzasoooryD3JLrrC44ntWTGIPvLoAEiYhLmpdHeF/QvyUxgGSjzwbsKNkASa/dILfmR9xBK4lTCcoBXMp/LT4G4EAzvy93FBo+vLeT8BfaeMCkWRtR/yfIy/kWs+cYHWYzIF4ycSrfmBkslX/eiBYz4JgPUwr1bCxn9tEhM5jt9QUZoz9nC9fr1hMUxEtQxwHvNzyfLpMDBMZbBiXVBzLXS6OtVHKl6Pyqb8/ZmXIuTsmhMLyVpHy7hplGVlrq6flJRu18rGYUFefS2AqqZ0Cfl4YLE2akuWjREhZm5QO3TAewh8KHOVb4tPA3igIeJwUKrYVvQkkSoroffjE1KOlmles2LraTB4SuXTJ2lOusD3l7JoskycJWWrqqOcOllEtH2UDhcu37BS2CjPfUe6Ix/QfiHeUeoBsg9kummPcFIu6IUO/uSMx8zdNxU2WM2eMlL9tIGUGUpuKNxrEvwOqH01zIsCgCxWCHMZGIXEMAg+M4SbY4+hUlvChJwfdXv4mmvtMaV3qHXcPmEdf6Zgb5fdL9fKgQ7sNXSmMRVL5RMkrwEqLZiQXfVAswpsgAiylY7QmG14dS96tQp8qEdkwD3FwUvA9jL5LIS41BLN1+ayBQ3SWFGZrdo4tKmqyp8heZcEncDbfKPlhro9M4aDFCpMyIKcbC88DnpSNss5ed3SfepoTIvMJDzokB0a9YESqdGc7UTqw6V8Dm17d1y/ApWd+yjJ47mQV7DALGsyl12FKfMlHh7WZ5HYRDknFyZ1n01GDESbfXg1C8UgT9ow4Jvg8AdvsBfC3F6CR2veSVOp9dx+URWrW+/lQm0kkAog6tq9DctIUlsXcumaifXJLPLw5OK0wS9GhlvvURyQma1qB323qUy16jURe1+07xYptWyhV/aMA2Swhnz8KZ3mJLSrvsEWh4e4RQyfoY2lgD+LX5AE9DYsv99CHTarAztcD48prCR58DITCH0ZZHIWQCjbZBPYqDoMwS2TVGUOgT5gvBrpwi/QhwE8xb3R4PPAF5XYEnt9VRJjhJ2DhX7CW2chKPfqbkQL7z3Gby+NFE4m3XlPHIyn1N7kXIYGsenhSX8hDwZctCdcUw/kgnjTJgEsiCfpcADv0FmPbLogHANfX128vXrEoPkSegoP2250XOOHdKAxgFr+xNl+SJMnWHC4vRhZYXimeL5os6SvO6gD7wd1LozDxUhZ/JyIDcV2+D8NlESQTk+ATxvOhvSjN4gD5k0HTipQRWxwqGFYpwyV4s0ornnvDIAOK3YPJiKN+B2EZzEVgvDhyXsIfYJHRZQe6KI3q1w4Ol7mrpa6q2nSuTqavlMYMhUftt+LAFwq+sETaWknegRv8CrhBeUs/NyPYNT9JbUC/5OYm5YLXKMX34rX7KYydC9CBSskOWh388iEMxRCGpbyAr0RIIl7cvGmmQELhv7jMLxIFsm8pPH0ZCxYHtSKoirzYGUYkRuf7IC1FG/Wa1IFeFddx1/kpDuGukgea9nzSELDkddbGZFmMTVZ8N0gIP+a/ME2+BRwM1Feg/mOQgsL1l2X6Yc0PofljRL7j3jjN96KUeABwbdwec5IvIPr7du2NnZwaUImUIqHjCHbRqAcOaBUmKeSSafIwCBQ8KXCS82IwvJjuHFWJcqKYYqfeLUlLo6ylPs0vreiudrH/kGb0y9Hd3d2obDUr/ytZhVGpAFCbuzB2EEakxybgowM688IJIp/dXst+F5mRny29BoLXfr+kw1heX9ZUcdXyKWJuIfY1OS5uHbs1ELUPiUL3OTgVzkcca7xd8hLLM5UP26CZ2OzHUtXzpHV32kN/lwT9/AF4/Vy5YuIbLo6IYxN0/CZADJV7ELNB8j4e3VHfH34KwrvgmHhDLvrRwIlCkEdRyD49V9io8OnH5GWjm+A9iT854V0gWTRQYhXQSCRgtU6U/z19/06xSUQsD9Xslh/anxTiACaMl6CtCQ1r5b5lNodPCb3/2PocWJn8Fa4fnoJ5qX87sCvPQgR7mKNfbVs/t4NfNUHjNgiGHCONJ4NozilzJUr9nX47upUXSXV1dl318rLLF7385XDNn49UAgXtFJxxgwR0kfntqU/1CouCfzsrqohr0St32db7wUaj5KMpTmAfRhyON4NOMZPMYlkjG/lRLIPK36IcXsPWcXTqHNIfN1rF3pN74DsU9KOxQ8xCwU5Mlw7rpqX5dIwGqyBMAs9tkLyq5CcUmDLKi/8ZvmZGiOH1JqLDjwyb8UThbb2o3/n2CbeC3fD0NrkIKoBnxLT/fnV9VVamd+jvjz3T8lXIUPEsbT+7hxtyuCF/vhtSyvi49QjnJ489fE3ngn3JNw0XVVpT9jmfokidWbt3yLPs6cPMkiMUELJcbvzuu5w3ewetf/ddkR5QuLAVZb77brcdvDLaXYbwdn4IwzBMkqbE/lRjWAGiJ0g9sEiaAnLwDuCFqeNloFwBaJujQbmRXWbx8lL0sIvXkpM3+JCHYPyG5SQRbFcMJuaC+ERxCE6rBS4NJHf2UjrgGEUNhlji/A4RxphDWdxx0RznnRJM6AAu3zbvP+R5AADylQQIYnTrOZmc2ZPXzZ0EcVzYvwWYq1R5jS3sg3sDxtiZCsbYRulALPs3IBx0lf5Ld6n9kn1rAsFzEvT3I0UP48Bw2x9ZL5CP91GmVwwZvIvNxHOoSe/xaWy4G27h6JIAzpccLJzfUk4Smd4yj2MB/ajFgNBiSvwc0IvlMC6XTUNlBfEu+LQlWRJ5tgduSEUd4NRyrDbwwQ5hTHcxiUTmSuZ3BH4sso/Y1ZmSEqC3P0FR8JwTRWsjsKjCF8JpHYhwQysCFUUPJ8p//n/DYZLQ4fD/wV/H7M8S5JxcRlH+Rpyi3bsweAGsH1XWGwDLDgSw2UCZTCZD/v8TpdQ0wFqc4AgQZB/fArRk4zKAZ0/+zuC6YXj42gsAqo4ZXHLdNi5EPgaYophYyVNIScIstsEnngaKl6IqJb7FzE5xmC1XJS90aAHHlKTwX+H2nYdh2QSC1ElSNsnXBwnac2ir7Dce2jYmJx2mKzp04d1NBJgoGyODghcDgxkIQ78ID2OL/yJBiPgshTCAvd9Oo/p2ovP+FZzqM369Dg+o9IDWqY/8ita/fnNP6bPSrT2SF1PDxj5FQr1trkwcP61BWCtWeHfKFTVO2Rp2yI3j3IJF0DEdJ0w61mEOCxBllZiELr2u9Yh/RzaJGQa+F9B+dbKEmkj7MIFOp4q5jw7WM2OKKCndG7DiMPW97oUBcJQtjZmmfp9uWE0IKO1ci/Uj5MaOdVZgGMd8kanfuY4XEJO/TKbQWXSsy1gZU6T6iLvW86IVjTsfRrC9m65P0pQGguTsrsYddwCMD7IrdT2OlMT+xlx5YDbtWMNZ0j2OBV0TzzdDy80SHsfWteZKFxjHwh2tYz047sEnwDRLWZr1rhXTNOo8uDSNjI5lEYUYwny8f3XfVy8ylzT0w56L5kW3045FQR+XRahz61jBC8zUT0yeiKZzrZgsaecJBLTrlS4n+aaBHW+iXmvVlP69Y81qEuKu1bYlsuz/ZvH2VjruJY9g3b8daATOdc8NzvNEdSxeRcPvXE3k2OhaQcL57VqlhnzZsaIEjdetRjtaVdf6ddiYrjUbYr07Vq3EP3Wr1dWtvWNrNa+frvXKTgQ9a/XjUJokq441V0QzuVDctQpYZNBzzWScOi4Ou9+dB5z0mFzim0X6sa4rCQ+HZurANG96Ven6ykJpBgwALPOqay2waeXhUF0PU6WWiRAEIDAjIe3eSkbFkL2IH8zO23BH3O5lqbW2o55sL68E/5/FXR9lXgnAQbouwx21ou5FE6RBydEfNWHTRJ/kulGdaygaPZZLYRMVqa7Sei5A9xVgec09xNheNWvCbL9+5cnvUzMXbPtVbhFuezXCBNy+Vcpi7n61QdTtv0kl88UeIm/Pmg2Cb78WquJvv9pMCO5XpyIK96pcFYh7VZbE4n71SsJxv6pVAblX7ZqQ3K92TVTuVx0E5t41jF41ysJzv6olEbpn1dtprwqFMN2vWlmk7lkXBOteVYKeZKdNxH5AIyhm96tfEbZ7Vt6VFf6RxO6HtlYVvnu1V0psup8Y3rdyOUFif5G8Z8WW9AS9xfNe9XZhDu8tqves34JQtIfQvidz9qgCe68xNDvd7iO896zaZkHrL8b3q9guzPdrJ+k3YVk836Nivze9Iqr3q9skNPdq4Y64/cqXhOd9qnIRep+qKEj3rRj1rcCFalGtJlo3+HZzsVoGzpKDMbcFEtes1kXQMPPePSoJWBWHjsI0n4bLpQ8yPRP8j4rRV5sRjHlrU0yLjz7KRyeGNjEgT83gaA0hwNocvZXlPgZHSbZcIqAaWzNoDMtBxcFMV9WBpsK/tTH4OsMndaDP4ZexAV8nM1FQHTB/aG2mw2d9soDvxngyFYXVwXShYZPGXIeiujrDfvTpbA7/nhiTKXY2VWcq/CBm8GvTYjxsTdlafqIb0/Wo71SjVX+pG/wrK9dcOqE+dw8AVdrZOko3wt3DXoWejaWFczmqbbi/yuBonfmpV4AI5B3KVBSvwgO7gs8g70PsNOAdlPtmDfCuJR3ztk75eKVeOeC1s63tMEkfMp3Ok7DD8JNH95iEHDM+OFrSEJwmCUPxbekLMo7CKaueM4falEkcJF6H1cjJ3sfWb/CwbjiD0lysDU8faZHEs+Hie+vIRzcnWIflEgLpvVuax8zTWxpvABdxue1stowPdAcWnFnAwtt9sxq2oa19DthrkiiqNVwvFdEYtdtwQHYWzoNBWkuWtSN7EWEkqR2I8KOT3omGJHaqjrFNXV0g5R1rrGwDoa0pdPY/tQVIN6rg29ph57V0cA1VGxiqvuUIskNm2sJnhLdVdPkD9iguKFgAioGVVSv7T5DeR75neyk/HTYL09m/vSpU257N1AIPuhOMfSNzOlOKZp/OfSea9DpV3Cfe9ek9OJ3Dn5kPLbAIsU7zkJhL2dZZB7gB4qZc/f1UE3DVsuPvNc6s9Plrdfz9uQT07cDpcr2d0fTy2kouv/LPB1/fZ+Hr+0C4jLqm4fMhZbQrKx4FmpjFGYSxk2cYwM4U1lnC0VtLv/HIFQgGJGuM+s1sCOccIOQg3iAGapvsSviybXLShdpS6iEgyP+Nk7rCJpWrME6fBAi51kufoM+tbifbQFMwWAW05ilmKuGZz/I9K+8nDzfBLxiKCSkdoJOBEtMliR0YqDjbeFTEPypnpWOyBrE039O0sjBf5eOyV1TJw2/G4eV5Di/PA6NMdqqqPx9ybvLIuABXV+9yIAA+3DPAsH0NzbkcATAlVhNe/tW74+t3Vx2QApLd8AD1J6IwwmKuWRZfKXWfAVhdihDjAaSxSkNGTLrkX8oPKefqy09/K9c/OOI2zAh+3okycPWuzyuTNOIJwP7wleAYxHKUIc5chDRCRs1lRmInUWww6KWKTWKHh32y7Jkh0msAP4WoR8UhKYF1wyycEKEqh9+O8GwAHU/JJ6pkEZScQCRllrKVh8XZ5JCaAOqOF0uOv2RfaU7p4zBMFQaXAc/G3d0d/9dI+ei6ABmCvUpJ2sR8cZBFwwxdv1Jc7jdw8tmIzEfKS4j6/fv19QWgo7iuZ78aKW/5Zp907FgZDvMvCaUJtneVT5BhOUBEcq+xjZT/DTPFwYDZgLJHm+H8B2wbaFyKj+bVWE/iWLDA3yJAVkTeYjA1gdR38LSw8QoEHOVt5vsnymNOnoXX9pr5C98vT5vd5Dt58tCj7w4TbwkpDPA3krKxAvvjU5KkbDrKS4Yv9OpR9/QxpkXg8fScfFacwhYYqA17LDI/SMXXgAdiwcbiWlgbhZS+i1zcm0F+iOh95PEsDA7rkcWdZ0xmgBkw87tTTaUjriuoN5SXAjv11f6hzWOtEtqMdPLAdAqmM/Grb+e3xkQ+E65xhwpwP16yElPQgHMVh74PTp3ijgo+67KoJpJbcdCgFNNqYyZB8G7kt5mXVl5aG8xkCUciorEXOp6toO4+eYUdrMOEo4QVnYkzVGepkiYtZcMYtyG39Y69kDz6Gy+atGrsZMHVbxjUzqtX2pzSNSx9wc3vtsVmK2IdsHxSQYUWk6hTioIa1VC8q44wPaSRmwAwP5IT5Q2NMNkpzzn0L4ZrWhDG3vqzLfcmHzGz/u1QEMFwLgDq7jLz6fb9Y8xmaWjcdufIuSDyUuJbi3AiRokinx0GCXrFNWjwufqkKLIbxhD+JmnYQABg9muSYtoQUQpftgyTaqU09pJPjJ2PvIii4ujO8x1k9uHXF2H8Iq+ZbBc4wQ6F0HXF8vC+wRwiffxnRnz4IwhTE//B/+Zl9pDv2D0F6SOK/A3TaonppmHTsBulLZkC54ua0+F8F1MSL2mT8SVncwBE0WNJybAsjEBunLeAyyJOwq+DDqQMHKJ45cpwWs4+ZsPlJWCBKEwGmDYA2AEUOD7kba5HHfzL8iHJXknlY16cUulY8D09+k5KaXCM3uvJ8Xf4ovK15rbU7jJwKXSutjTAXrAcuIly/e5KG+klOxn+gsBFXys3uZd9rLSmxS0v/fzNMZjPU0v5MPtYg2PrZ7OPiQDW1kzar0GBFcK1VbSRUUCPNqLIc6hXUbhg6FjRr/V67yMsioWvXmzjcKefx50WKvzB0b/ifWXGsuf5ftw9XmW+gM4OXn8vG4WYoDxoOUq9zum8u1Jes/z2p1m6EslBS9rjXep9JYPMM6D9Yg3JSrCXktETDtmrCrcgdw5PaaOH1zdPXOQtLBMZ+cuB2DwrYrM/makHq9TWZ+u6PMC0WQWoqEPeQ7pmljOgKMYyZzkgKwdDh665IhtjaAcKi+ROhIUsrOaGY1ILfoNGwnb00ReJQPuUkhfDCvxyDm1Uh9Ul3yAXmV5h97/8iP3v0QwLyzzOl2+IM0mO/7Jk2wKyV5xS55XihHYG2qVi/tuyJDcu9zdGHpWrFcFEe9zm07jXuH+N27eDvNaWNievlS8H8vqsyOsA9CJ7i2k7EHU6kr1TVk35yKoBzUP1aqJUOjjQuX3oXHV9D3Tvyehe7Qa00sFaya+KLobrNRkmNCIx5KdVfC9JYW/4nLncA868j3sti/vEf2Bo58/vvj6rN6FS4gkegjb2+3BOdtH16uZtCad/NOf96zijQ6ZQGJ5f8PSXVcdKiaB/4JkD2n0nJXLZNHCZSDZ9f4hLPkxGaEfyyewa5n5++Y1d9fCabEMWbA6ySnhSJHYtwHTpBcwGCbbVylhenn4ia+KJTXwl3DFYH4lyR9GrQlwwdu96e9+3LcC3xG08xfH/mjiDP7/EtK+o1I6A8tk87lnVutsAOLWwfjBOHjPDkFR58+EKbj+4SVKnmj5opJwqEXhDElE1uQnSTSQSveHHgMZDXh3LoN3r9YfT92cwo2zne8G9bYopVnzc+T/5OMAvB/NHkhj9B4BUBcSXFkByX6gtww+X7yRvie0v6cGB5pEdaGDxI0COjAN4ZbBbhSyhQ+YXbXPCIdxFFKglaqwJS10Frr3Mt9+FZ6BYn5cvvnvxCtYGQb1WoQ+vXie3HPk0tjiJdHHcaXfZYV+U/AFL+WqEIpKy6h7TlHUyli8F/KuZV8nvwS0JIFAeETu5J2TD2AIFySAMRWSBzRL+9jLmgzlS8xYKfgHM9jdBGWPob2Degqg/OJUSFwEPtLwVNe+f/JkS7toMbOIdDZZgitMnRgOfXLgBHQWJNpI2Do5qopd++VW6BL8UxOKOuI/CU//y0+lbZU0CsqQO+kMlyssoprcseRpT6Q/AkBlTMPY5r7pIGnfEPQYwwBjwYI59uiT25jj0nSEgTPPOGFbh8avRTQARGTYJgK1iLpwwOO4zKCfUrA/11iOFy+LO+FtYs+Ikwr8ewrx3WLhXT8PL/3T6tgfnzlC9GycDU4DBwNln4Tr8Rie5FTiPUVLOwU86iQC8ULHCdKV8f3aN9+Xi49V1URF+AUdDeKjZskBMBvUjiLVNgYHOUsXzfbr0Um8N9mMeIsQCo6TfRXZCkWqPkVWJfYbh50MSpYnjAIAOPEkx0KqyuzbD0cExFAG+XkDiDSbcS+sdQNWYrZCUVhDQhRSLrsitF8aY2JURR6iBgUEvcnzlF/gBwkxE5AsyK8CDLHmwHYFnIF3RNYw1yay1lwIrcnpx/frvp0qS2TZNEhYEVpanVtSLMfIrDPLx5x0DsXOJh1kCMU0ui2DjiWeVJA2jCAKTfloRLs+sKQmQRlZCAF8kxcQsP7Q/YT5GsW+5g5wDj1hpay3qouIAnkaCfILsWiCH3uwZ46KrlRiXn6ilnMLx4ykI33oxvSP+IQnudjp4kOL+/FJcgUL52WS2ShaIpqskpSqV7oMX/I5UG2kmtd6/vlCs2IN46Jfsf0e/J6AISkNMK3oTCMjapHzlBhBvF6Jv0puP71m0IU8T+zqmDsNNgicgxP8qJLgJvGDIkQuV03MFEWSRkQjIrbcE5ngEYdA+tnOfQrJWTrCGgJCkALzVTWCvAFosUWAyYqc4j5k7DidCMPA3oNOyaEpwhB68oPztuAlQPsDWKnQMFuUsEEEVB+olqFf5zEmErPzhQNOeBU17mK91I1LuZ/O2ruSrqQdK4B/Eh2i/IfYbkXQlBgLs6IsEg6vhKotAcpRSrY1E+m6CtR0N2fchd7AEiqUAVC9QLTQ9AeUA9ZXcNrTLaBswzzcBfOK0LVdCrIAQCRTQktoCGFAYIBK3gZKEipfeBIJ5x3gYCPgWoq3Qy6MXOXp6ImBBolDXBe4aUkvfBOUdYwI3jh0DIGvzxCl6CYcvGCnvKLmlNwEFCEphLzhe29ET0FZGX50oBE3ZgcBWCaw49TUCKz58TQT2MgzTYUx9giAaeGteopgWiisuYz+9YovK95Xdw5uA8rM0wG3nA1Zujo5J5MERvjkaKVdZ7BKb5sYsxgcBQWDcD8OmugkAMGQItyWLfYWkaexZGUjhp1YS+lnKkBAgx0poh34xcJB3B4obkyWYb5PBTYBUY0ViYqdgSwuzFJmYy7evFWMxn+JUmdAOE/RyjoYNa6ScBgrexZuAvT22T0nM+LbwlsYxNJawufApIFwMXtnStsEvX/xVan8LKno7dTx/yHtVhmc/nLbPdNraaRo/fVv3u7KHLOFchzc/H1nocpgAKwscePz4Q5O/5Xy5K9sw+j3JsX2StodVqb2rNwEoffC9VErPZbE6LxKFz5i9swlNR8oPwacAeBL8Bd715CZAkWwZhHHBmvCxdX92bwLx7ipbn91rWI0LXNzDo1t9dCO+LpUnl/38NT24bd5V0pUZFicURXd+RfL9vQnYBkv0b6DcHNl6RAY1RvPm6NVASVro4U1QIogI1zVkF1amhpw4Ka206SZoIE7IkWaenw69oH4dn5vc1vmFnEwf8kDKSUgOZ6P9bPTZDmmJoxZVHNoHmODFDTZAH3C66LXIle+5Xu6C/w46L5uBV+GvIaSNSsCGUcD6K5hoNIXiMGfJV4v4vBlGaEqKQIaiBruhENa2iCPK7TNyE/J7coEpylil13n80eFRKT0qUfkxib6uR+QbVotFX0AZJjIl128Sta7YN2ToIWpHAs1EyynYqqVAB4kSCeVQGU9UOQ9QdkCqIBov2hxsaQHuLuRYYbCbFkF7JV7hdIXGVzD/AqsKtC9UYkoToBBATBLIvQKBFYzvXTM2/B6ZWSiOLUITXtA2MsVFfMTqkrgpDQoPlZgSHy8Js5XbRKwTeBaBT+stGnLZ1JZgoV+OlLcNjthKLJzPf3lNAuUcJYASfU2RRPKt+3U/O+t0MZ5Oh69JMDwfZgk4YItKQ+hgWEx2WLXG8t8PZLlElpN8VSTiLH48kOivg0SXc+B9NkKN0C07fcOIbYdZk4voNbqK4MdiZBb1Q8DOL+GF9fA6O89BlLbeDFU3qKZO3DG1qTsnzsImhkbmxkx3VNuYGGWm19Cb3bdYfpimeaEZg684n+P2q3rG9WqnfEE+QNPoqyhEjuYbCp0VtzSKw9CFfsO7gMbJyovwrjKvJOrk7xcuNd5iAgIDt4k84Cbr16p6omr9bjLLlZ5kruvdt8Z3MLfXIsYDXX6F4yWJ6P3oJvjumgYkSBOm0nodBq63zBg27nfbl912gsrDBBfLhgQPLQueizf5GvLSj00Ia8tVzQ7ffBjQ3/uW+MpLZHHAETx5xVzeUL0ntcJQ2BFHGHRzL8G/AfWt0MaSxq/gZcTDxco4ysuALkm5CMcWvgkE6ve5W+9jRSAI+RZd2WRHDXxVGMX2EkWVlpDTXWm1WBq1bm/l5yQCa5qSphjvlCAPRyxgAhtyi7Y51TtBC1retTh03LcYWEE86Jw9ef3mQzPLISYsrh3eHVNC1jH/mYVNk/iAmwD05DW7b+UcAmI8wCsBKrXUOz8ecu8aHOEg2XNybz5cdZqcG2ZgZYC0i05T7L3cDwZfMMb1bV6tc0+YkR0cT3evXuE5zAHPui6ZqkJHKy8BZ1JTkPEts1ohKDwNFNcnyyVfO9HA9mkJ7NkkpZH0qjcMS8d3aSvjWKeSSEeeimmsUYX2l1nCPh8pFzRWfgGjkaYaE8nhnKQkjYn9icYjj6buKIyXx05oH6/StX8cuzYU/0vCxLChPjJG41e5Do6IKCLkAbgcweIx9IkhWa0G7Ogh/mdC0bSlvLw58olF/ZujVyiT0HubUsR5nspVtz9qZT//apRAGyPTHgKRMzQCLloGyk8Asp7pRndmT24KYtgWtGCF1iioOv1jWkKfNHxoEqWEVg+oAaafrc0O4rvgi8g9gIxU6CrJnZeytFtpKEd8bV16YNteryiJygs/UTuwQ/lQt+/GR6GnLG0Jd4Beh7fbRvzgHYEwEjFOvqJSOEnTl1/7zDymSw/ixRpiwC7FpzybAb/Jj7Ft34dviONsujCtyFk33xH8JMtZXUWY3dC+BTbsUSt1+yDJHDiUbhLHx1gST5umBV9ymWJ7m2G8JAGH42LSS0RAFdVtkrws1IJICKYgq4/pHYb5KFKZIm6MhQCxqIk1xTQ5IAQ1AwrUbkMxkb9ALD+NT2D7m65EEackDoocJSO+wuuwpklClhTXEsJIxQMdU4zCQzO4EPqKEScjXAafNLytpyzmHOI38p9bZpifuvp4K1wnCUzentVwDK5S5Pg87m8od8wfuFxK7cZkMOO+3cIIOjQI117A+DF+ooUMuP0A/nD1hlEsFvTqb0weOdUgJHBfl585NyhCrCD3SsDSKsFJJcGm25RcNHQ1zunv4R3Xy5akWS9RLIhiaWSHijmtwyBd+ZsiUUJfcuElxd42LMSWza0pBrbMn1090/GSFn0PDxviV1SUUyQ30Hw/evXYGHxYdCSrYuBCbV9sN6b0qUhsFENS4sbTsQZ9fPVwRGRT5trrQrGmjhYLoLO7yc8F5FOiuePOb+yoHP8b/sf0nD+O5Z3/TTm9OL+BqIgswuxCRAaVHSmvhZ1CkuDRwsqUIcc2GGr9m4AkSWh7aFyXmwezR6jcevROKeJjMQa2EnVxE0DKq1/wjl7A9y5RoeCYBn7IDM2GTTPJrOIn7On4FdLYbSkrmK6UB2IGnbmJPB2F0J16gQfhIQhhCSwAS91yNChKrsNblrWixm+kqNpqHh/mXpPfXOIrWeClLKyuMFcUSlXlpbD8EIW1jPG5UhOvPi/TUlWWMk3eQ3WmbGomrEWLlmwNSc3hYEcEzQZ7riKmQi+tZZJZw8+wnn9ILFuHzBBQEm0nTx7xrvx5A95vacyUW6A9+kQbHvIfpRLKJ7ph6hUZ/4MBemw9tvp8bIzH48ViqKnzsa5r+mRR12E0mYL4MtQUwUIqGeTGFq6WrEj2bTJmowTWIDuXNONlDVDFTsF517KtyORmp8QUQXamHfo+U6PsNiTROA7jjqlQ+LOXHKGClv/duyYPiG63HAPFOr04Z+EyoOUqQqi7qBBjmuDp+3frLSgslLtHrsYps0HuLooeVDZ1TMcJk451WHpsjLQ3CZySrn35d2SDal8voP3qZAk18bkf6l0rZmkIUpDN6pkxvYu9lHZvwIrD1Pe6F4YIKJ44OE39Pt2wmitqf+pci/WD3gXd64gofRhf1zpetAK60LE0i4M1GTR3yq3lHeohDXJ9gK8JhNl9d7Ua9etWjZLY35grL0i7zos6S7rH1mIePjO03CzhPHjXmivdjGIP0nzmKpRu9eDIBp9MCJzgxLRjxTSNOg8uTSOjY1n0oDQFaHvXSpG5pKEf9lw0L7qddiy6JvdmFvkhcbpW8ALE0Bcen11rxWRJO08goF2vZYiOVFngJUDgimzanbsqNxAG3ecUxgRJSMj/6lwNk2vjy22iwQzc5cx0FWf9iB5/d3h7Kx33kuGM7vN+8XagETjXPTc4Qn/gzhOIwHMutVfwR4/DF8VwhTA3ZdcK3i3oQ2CJO1cJ7zcmcJ4m6M/DrCsDESU0c0K4fOOONSB/eQxQDKYbxibxTISF604euL7U9AKW19T8veskc2bTysCbHABou25djI5VJuwagpB2q8X/NSyYkcgnKQg0ppyvomtrlMT2iq0aQEh0nTYuE0h7HECzZ61+XAaTJExwpDXpve1nnd/lZEU0k/uIdq0SxqmJgYsilScsDrvfnQec9JhcJVVst1qlfHx9qnR9ZaspezrWqmSi2KtWDbe9ayvN2L7dajN8sY5lyxAdvSqJsPNelVjgXOcqUfeiwln3j1//qCoFhHw6ELKxJOy2id4AYePDy4JROWUZ8ymyOzdkVa52lLutdqEzOA3u6drQOEz7DBbjklP9PnqFNil827iwszckJUe17eEN50PCUjuHk2vsG3yIbe72V/HNAYOkjKQuQERq9ZkCfPcYMOC7BKae4+JXJvkr84TixjoTzJC7m88NRFW7RkVRG6bg5pC7UTF1SZI7APAzDLYFljy96m4WldexpRvhOY4weTzkgk9Jignknde6oIyx3d3Nh9o8IhqzTpub18H5K4U1MHstmGi+UMSKUBQA02PsBCgtyRoQBytdqmrDBjtBgmnNYycxi7+b9lk+/rI7ya+Ym9uOPTTrMoxffiY2qLY/ORI66m4qL3lIp5dsPLtIaqnO6ek+1RC1eY967/9nj0ofrvao9PHi7MPF9xf/dfa/e1S+uL7co9b1/1zvs5T7bcDZ5T6dvflwtd+KvNlnDwDhdJ967z6+3ueYnO63bVfvz9+f7bMHV5c/7lPr6u9vL/ap9+Prv+1zKN9d7TO3Hy7PRS2gfGGWLkNgOHaaiRmHTGMJuJcoUeytSbypOoNtBdpmNmPwQ/sVoz+AwzM9J2rBrZc9tJiBMN2IFIoxmtlzYFl8NOXcy4BoC/asvPygiPKDuLZfcht7OVNLFyN88c9hGNBjMbRjz4mGyLew+IzjVzs8ygIKmonIKwMYSz+Sf2UxPX0DsPdkDWYXmwZp7LnAwUGgvRWGn44GR0svXWUW/BGGS58OSRQl+b/Ap9QLPoGnLdi9PMeGtzUL4R+f0I4WBtQPl/g58oIlS1q9IYFD76HLfLKIw58kn+iGh9eRJRgjKPHTFdP2d9hHVhxLY9xoFgzQX2yjYESnhP3ulNIAe4nyG5b7bfuiCuZfjvbCetIai3+Lsi0I1lkAz7zDdR5mTF1zOl1YrmVpU1tdaAZxZ+psZhu2thi7lms7aotFPjdu5x5fhPlxbglWa78/R7ck9iAmCHcBrJpg1zdTj8bUYbqCzzOO1DZF7zgUZlCIKWpMPs8Qyl3+2rxr9lRXVWrM7PFkTggx7LFOp3RiLRYLyx5ri+ahMpWAGCYD7ytGnzCAQfx2RciVHIO8/YR6Mt4m+weYVdoGb4ypqxJnZpCpYRvubEodbaYSxybaXFsYDUfuI89PsH0Y/08axX8eDY7+869HA/zx/8Eff/1r23jG2nw+cZzx1FpQVV+M9cnYHi8MdUL0mTGda23jwT3eJCld73AJJLYc0esFTniXMCKW3aOjhN3jwi7IYmFMyILMZupiOrOsqTomdKyRuUbHOm0Y7Tsg+7Drt8T3eNxMGmKgQyIHSwvfjZHyhjlrS+VfOrevlHWWpKLa9ik7t9KMndse09OtCZ1NJmN1TMaW68zmC11faDZdzOzxYjp/UKz11kwZpXtnIlTLUcut5F9bjhOllmPPp3ObztwZoQud6sbYmNuEzMd0Zk2afQq5Q2oqclz56UphbwrgdGZB2wuy9pwd74cf3pXejnXpurKv7LeVt1y1bVWsm4kXRRtTcB91dYP0HOk9dnw2J45lzCauOrWnzniqO85CtxYLqlPbnWgN5IAfTzBlx6FfOqZvXv/4SlnTdBU6bad762IBqyRNhP8zvU8LotZ5YtqU2GQysxyqL6aGrmr2jE7pfDEZG1Nbsxtu6qmSWd4/My+FZAIMLg590PFMeMsVTVLg/ixieT5wjqGrWBTIEHOGog7DZr1b0RgwsG9pAA7STIcLbmE8yYGDupIwVrIgSyCFRhrDzU7SMAaoudOAZeomvhgDohKhv/EqjFMYhb3CaI7AUQJ6Bz+gCoq76WEbLHbZDWObimb4KBORkADgZa0sVZyQJhhAhY7cd+Bxht5KG8XblUUmX67SES/9nOeYkX/kE2SRbDbtsavzmUsWdOLShTu15s5UnVlUc9zJzBirzkKbNuyq8M8TOSJB8ZoFwjNNICgmOQqKFE357vRDglG6QSgVROwKdg+dATRb+cY7Gsl52hDpMHPgv569jo7qWTRlF6c2pWvhs/dvrt+cqaoxKPSgRx9CJQ6zHHQL8CDPEUFh7QXCH1AbbBXxCCF7+YRV6z2ZRxj6tOdry5BBeqn7B+16/E5+c4+1Qrt92na1hndm6IfLBBX80pLvcKhrNDXs7C3yhsJCPIRrBIbZNh5Z0yeOMbEta+YuDEKsxXxhO9rCcmbTMXWmXTTfYCBJdy1DmgUB9U089aaoIwETkK4tSBUaEQV82qs5qUJrKH7neXkY6sVzk3es6UWmqAC7zX/s2m9RHrx9vTjNwBOWtde9lYaKcPQqihs/XEZZsjI5K0HNHJKj6ZRUww5rBjLP2X0B2rKdNZxkR5vr8/ncMqZwkGfTibOw6YRQlxiquqCLDie5gALYuW5+MpSKJ0MSOEPBPCUyEMFwyry4EZGCB5Y/oOWioeGkW/jUjgbFXyYJoxKAQjXgKskYO/uAvngjQAFp7MF5Y0afh7Vabgsa95YBpsN9aMN5O6Wgmoe0iI0MF9Agc9vLwQYe0KrU0tBourhNbDcIE7rhOpZK6GSuTm1nTtWpPl7ohFjTLnSfOT3k/OQOWzeNwyFy0MMlSekd2XCviaFooNdb0NAcunyBZwr6fSUpWUeND0QA/rYA3snNu1HSgU429AcqdqmhoRclQ88ZYnhtYz+3UxMTgO3d3Zb2WIfTsdnVw6Gxg+l4WLiXHDnhCoIsWbzMHg0WdeFE2knuEtW/KWonw8Kh6kjgt++Of2hoKq/bLfi03kKWeQ7cs8ERe/h6VvciVvV2LO9nQwzrKrxjEZ7c4iKVVs4vbsciXR9DQmJJSbxYTinXfNZ5cJPrUd8BMEVnCLdmuwipzfTRdDwypiOtdqnKkZp5GsWhENC4HI55aNdRlrLTVV0AE7Amswbw3XwdWIFnsgz6Iy0D+OtCFEP/c7Qm90MW/5DHIfZsAaqh+5ngWPe5T7iPeX1815wnJuKdHjhdX9jaZDGZTSx7OicLW9fcCdGm2mSqL2y38YHbzrKWIdS2TeyOeKBdjcNwvf0x4rhV6EYOQDx9GgbFVWrWWvij4kHTt0G58h/o4gIrYnJwV3DfhpyQe7Tb0hBsJhagAfPY7t90XjNvK0lJnO7ZmlS30wtRb4G9xxUwqUc5L10uen08WAtv+R3En8WJCS5eay/Idgs6Da01tYJQAKCbz+iDFr+pkT8GR/gb+CwwpXX/dqsNoAjCDqLDYRX3OCnVFqDVVea6PjVJKh+nPdpubgeVRwlE2+/m8RoazavmbngsXJ9taP8GG9pAHUYcJKkHo7f3W9laC6VWBVLkvm2yELv6K5LY3tpkz3WzadiWYTiFDY05byLfDJYDolyhtZPhF8Zhkgy5JeZcuLK8R1gWBo529fr8/SuGmpbmdnLZ3WVnqH1rAtFTRMzDXHS1zODQba573tZpoZfJBT2u122wE/ZlgEyRs4lRWjYKkzEQpsiI02DLDByO1wisIWGTwU3m0B4ABYF4SfnMcisXBDrZG4WCbZAZ7ZUfEsj9lEe23Bwh8pv4JyDuFIgh0OqLpGgXM3ZnDOjOS9k+IkcpsaM4PByOgOsQfcYUohxYh8wGFFMIsVlB69zwEQbKMg6zSMZ+4rMcVCfJRomgJYhbENp2FivEhdThhdK+3slI+QkGLg2ItwlmKGwO7E5gSYRz3GV+vL0g5Be4pUmL8lxHiFHEGuI7iIazjXJH2CIjcSlVjOJwHaUs6QgbN59Qo/GyMHvlY5LsPvlus0cXQk8GUsEmu9cDTzvSGsD4as6OeY3yToJ5whCsVM4njuv0oz5S0SwjBNqmWdcllLr1LqEEuD68+0mjJFoQkpgCqktxD6Au7NTPNA6Va7SP3nGYzA2CgTJgMKl1SL/FMKNycniRe/YxicwmAd9ikbArw0XGTuWRYu5LPxH0rRmn66nJVkLtmDZAspwWMqWShp9ooCxpQFlSHrFGbCcl10GYkZi0oM6uF3Ms7JGinKcsI6lDEPwaXqHMSrhTBPdrS6CcCzD+ih8mHOce/sVuDxVXxo1psgKqRVLlmDll5j6NuQNDcnziOdH5m2Ne3sSDyybd7cQlNGAYzIW9uLKPHZ6umN6Gn9jzmh+9hJ2BAMByBBzL90yOfMgp/PyHqMWgodOxri7GumvNZraj245uEcMmM2viGjrVOsS89JBYqWXs0Jv2ECqhsaocGSTgjtqtKi/bTfyCGmVbRR/Ja+e8O4lc0IqQsroZCrAKLwrMLYmXdLeYgKNlRbtpQSZ0qs3nhjFXDarPp461oHRmz4yZPnPn1rzBD+MKHag3AEjPk8FjuBA4IGOWRFQ5d8D8ZpU7zUigbUBHJnYkfqoj13/eQ9wwssq5/vIHtAtkVttkWIBSp5OkTiaEuMZCm1uuvnDnmq0uHGMxJvPpWJvrTQib4iRxLDMhL+0+PChQYsR2uNxDiSiqg8PFUPTK4rDgQ7z7djY1GqTeECuXmmQWGBEu17NNrDyEyuU2Q2djJsAGwZu6R7OhsxmK+uWWOUaPl4R+J6VHU+usjWHeRqmHHjb0JpOgZDcvtVrD99+ncWxk2NYHAKyCboSj3awJw1zex8TEWxpiS8O8JUBU9aJ9Dh9UKw0WjL9mQgFoLNxpP29oEOoPRf1Sy14AITR7no2icqlNbuQAtnGf2XNLxxCro6aRufHx7AH7DTVPyVw0Ao83CRwrvN/H2slrAkX2wd6EUDZ7NATG/mLxWnhDbaLak8mE6jN3YjiWNVZtx6ZjZzodj11X7RCTDSKvmTP1LKnKrtGyYiTeDMGk1tgCXFZwyKbdlPnlFoW6Vzz5+7ew+1ku12t5n/cfQBe2sVxT8I8R7aCKLVdlVTAYnnB3mH4NSPU6cgNUm+i2Qcf2ZGLNiWqT6cTQJrM5Gev2ZDruIJv86U8JpP8wRYxkfDgt7afFmE3UmbFwZzPdshxXtSxVdaZTY2zbtjo1tN2nhWVz927pD00wENXYhJPjYwkV9Rhf952IGF0hKyoezKJgPZsdekzaOZvVPuSL66M8oG97SRqQdVnGbC97HlzE4RI8I456uRxDBsp1w8TLmWt0Y6hOhqpxrc1O1MmJOh7Nx8bPaP/vv0NYLSv5gzZ1SulkOnfUoeXO1OF4rs+G1kLXh9ZMnc9t1VUnU5d5wSaeULdsXfbM8j27tqE4EDaNfKEHTY7qPJ+P1J204fl+Dspnt+WGzOb6VNdVyN3lzMfGRLeIpqlzZ0Gd+ZxOJk03JJ/Jv49OP7y5/Hj+Boa/mI30+XwxxwMp5MYEvrBNmw/V+bWmnmiTE1X9GcdDHMdjuqiLMoizuBpV5VyQrWns2Qpb1HIWSk1tSi5RunR/VG+3PM72C9qYTamG5VLeTKnltpWfWITOVNvV53Rq2dQ1pmNrMR+rjmVYDrV206ZHHD1Pjbm1oYduxpYlyrtvWauFqur6bEydmW3NXMOxJ9PZWNeooU30BTE6cJ3gsPWkkxtAF9Mn7uKznNcBWyw+oZYdsQixF87MIZru0IlBFwttrLtzajvGYq7TSf1ho4Fz7TXB1p86v2eIPEQDB3HSwZaIyJh7pTbT9aG6GGozoDW6fjKZjSaTyc/88YrTHWPAMo83iml1FNUwpHxIg3yBmtLTcq8CE90KuJDW35GMwx9SSDdBTTsmdz6NTWuDKJc9/Bq2tlOb4rbCv3bh4sbTqa45Y2digZRpE0In9kKbzqw51efzaeMbVZ54yCLCwQVzJ+cNWkqAd5VqVKdU+thpClNds4nhTilZkMV0rM/shapbqqON9dnCdee7p8AtQWYCZ6yDegjBMoYFjzBcB2sT/p9Zhsxaex2lgV3tCvkA45Jis4PaaVeLUkt4E+IIcKs9e3c83a6WS21VNzlPEFBZp9LUKuPpdhacGZnNiW3brj2bGGROF4ZmafaYznRrSqZ10lliUJtyW04m0u61M57X1F4FoR8uN4wzjxBvPaXLMBapf6poeK2pE5qoVNPLvbDIbGyRqaoDcMl8ZhPVcMZ0rtmurU0bgc/q+iKG/EocwET3Etol7K917zHNaFujoKomgXPnOekKoJVpsgr9nSRje19NDYJJqKP73/bGZRfA3bStsS1spzm/zP7jytUEBFF/H2kpa60x90/Xu2dq8we2LreUt/wAMsNWNjLzhjpazbY3KMD9/pXYYQx+zczNgYud+7fb0F7RSzc7cacOJDtyPUNkc5aWfAEHreSgAEfcTYHpTJ06Ezo3prPJdDwZj6m+WGjEnevUstRZB3Giu22YsROlXC8PsQ6z5nrbglk1NMAyJ/FPXtCxEpbsZztmFcspbfbyb2AN5W7k2drsFPnOq+XFeV3EY6OBjSjXnp92UGAWLTVV3pZYCJdNHnP7GLakAup0nMlCc1XLmemUjg3DVTWVUtt17MXYtl190YG5LB/nlvTT/0U36A13dfUO0Rh4pcfJP13PPN3sNNgxzHBXMHMRbCgSGT8wkvlRQqI/sRXeEg3dLVF4daeeIF941/3qcst3rEphcdiSyPa0SH0o5bIVrozygojfbA5VzB2I0YORZWGkildGDatpWHZCV5Xzp/0lSXyR/hb/po6XNmYo7BKmumO5RKzqY8aN6wVCxCMdcd7YNgrK06ThfCSFuLi75QPxUBpquQuqE8t2NWs2J1ObWHM6pfqC6ro+J5pWF8qk+PN2+Bru9e8xUCWBDyaOYD0zo7CNdKImjrf0UuIP6X1EY48GNh2uw8BLQ8zjgOaEVrFwe048NrOOIp6jE23qzCjViGOQ+XzuOJO5rtkLbe5MNLeDiJenJXwcRIlHocXc8ydHqSjT4SR56EWAFmATiO93gOjuNNhi/r82bG7+tdN9mBkOnVtTY2xZ4/l0OqM63IqpPZmqc9WedLGcgrlquz7iQ5gqb8MscEa188hqt2EHTeaTuau5C21KFro2H0+pak21yYK445lKZh20aSQlZrO5kUX9xZv2zyz4LDeA71CZFF2VGi430waWMaWTycIeT4ihOdZkPFeprrkWXahjC7y0+6uAK1kPGtN+t1ONUrnAA4U5y3hdm7XNcmmyA8egrFjiIJHVYOuwCh3X2gu8NRxWDeD0B1szOnypvA1isq0Wedhb758ZPWf8wxb0OoNoY2cyX9AZQMUuVM1a2LY9n6n6RHPURcPCIZbJa3hG4s2pH62Ivn3bmM2/VO3Dzr2+gFRnSxZ3kmcY2W3P2oJnoNZPTMNMmgYqRtDxdRpr+pjo+hjQmVRNn9kzl+j2eDI2dG0xm+htS3p69WG70tXQx0a+kqdXuxfx/dnHp18/GHZlUD0XTJtTW9eMuTa2DM2daHQ6I7OJYbuWSm3DcesLxoLVrpuhuMPQ5yGS0Hkn3Ffh3ewFy+vYWy4bMyu/47lEREkl5UWV8zdbkyHv7h5ICU8vU+7z7JblNtkA7FHdmxzdbONOo2blHnHMSCk5fdGqR0PaoIalrY2aT7/jeTFsQqk7U4kxJwZxpovpWDPsmbOYOQvbWHTwyIMQsCiFPFj1BfuIVRTETIUs0QxB0yfBMoNsL0B5G/3621xLOu0+mofitbnemPYqFJamZzCwmEIrz2alascs38fSUBsXtIXjmU8MW5vMiGNMF6qmLhYTakwsOtXGVDXGhrv7NL09PX/3GOR1cPTh44ezx2np4vTq6glIPg6Qtz5gE2+zOULslTOejfXJFIRbdaEu3JlmaXNdp/O53X1Zn9C7Raz3E3YhNuJz+Th136G5ZcwNYOydhWup+gRS2c+ou7Dt2czRFx1kGuHi9PDjKjyZHvm4dnArWozH45kxsclUnWm6Y9nunLjO3NCpNZlp0w6WGZrTqO0SNUtxmafyy6vluoOnzyXBM+dG/2QiUg8DS2XwZUtLheMgPIibhWPzOqgWflyN8EjTjfHk5wYJtIueuIUr/hGR9Plqf8T1Ui7CJFX+OyNBmq2Vszxzs3LVaxMKXAaO70dl3H3MMwy+9eiBW3wPXfeohiWN6hU2gUFx/gby7+gTm+LSSbMY1mcB568to/JXePZrczxchO4X4T25VyA9mvIjW7yeN0BsBYjZWq9TXT/N1aG0yAqUanS2oI5t6cbY0cb22HH06XQ+V13ddfSG5+sfVx8/DGkA3KsDmSMIiCYKsSAFIyyFgKCFJIwpg2L4KYw/0biMmbQ79BdjXyMOmVXJNgmpePjSQwkB4bDO/NTDH7j5SElXJIer4SkZsB3lJR0tRxxVw6eAHMkwJcC+DOgcIrPPb5jd/DcmMb8aKQXiEFF+45k5lTs2wWQTpOT+Nz7f7a8xqzL6nUdFws0LncxvOGgPmSyiTbGGqzOm90BD2aTFJFcE8k7E1WnyBvac3h88V68pvI12mR78DmjgaCf2HRMRjbZreViwgzY0tGttcjKZnhjTn1l4K2byLsBpG4QsHLxkaNg5+odbOSRLMzhXlcwc3YAeDN2ZW4vZdD62F6qhO44xtQidE9txqOU25NN5Q10v4GlGwC+Iw0yloXK38uxVyTj70+lbVsaiftgphL8LbqI7XCMSmjOEthOzKDTkhYb9/eHqzTJbzB8NZt4m0jifUmrNx9aMLnTdNiagcFMNjUwNENWs+jq+FnlIFD9cLqWnmAPDEXvF1q6ieGsziTSZ1Xf08ebDFaiyAE/Thx564yWg/RPhEhgqDYsxh7Q+fYcCr88xJgt9ghH5DS/TjvF8YMi0jz6YlrhsMNRNqaHNVdWyVV2d2ercIK4L8Rn6bNbBR74DbdtsNm36WuqG8Q799/39fasaqckiP3ENy9HmY3W8UC17PJ+5LnXn48l0NldnVlN+JoDvYnBWJElC22OYVwLikGVT4Q9TmKWYLTpmWY3ydJH84W00GF7llqMKQQOWhJmVWDLQfBxJ47PF+a7Td++OBken5+bfPl5fsb++P70+++n0f48GR3/7/gL+y768/vjhw9nr6/OPH8zTDx/fn76DEq+vjwZHbz5csf+a70+//3B+/cObM/7v0ytNA87uzUcocfb+9Pydefnxh+vzD9/n/746e/3D5fk1tPb2J/yPeQFf4Rrx/zFff/xwffnxXf7Py9Of3p1dmpdnb88uzy7Fzx8vz78/x7Gc//f50eDo3dnpf529MV9fnr05+3B9fvoOPn04gyFffoRZQaLjo8HR1cXZGaQb/enj5X+dXV6Zp+coAVQcItvP1Gt0+bEzZFOuw2BJOEz7Gw7V0YGdF+C9zQaMs9x20Wdvvz/7cHZ5Cqv28Yfr0++ZDugSFsK8uPz4D7aZ8OP5xdm7c9QRXV+evn17/jrf4V8x+cV5kKQkSElAw6aUucLXhFlYAJZOgTRi4AYF5ktk3kDkwRS1+Fc1pEnyOGFpW1sCnfOFy2IvD6bqt8opWW6NWyu29W8fr83X75jSbIeGTbqY8j6Wz5A83OJ4yDOur3VX++JsYlA612azhaPSyUybL8a6qs4WxCLWlIGl1dK1r0kU8RgeAXzXD0HkfjMU8IvDvAWWF2DvZiIpPlYkkhfOvzIf2DWtfMcuH9yImH5bpqkpZC1dzGZjR51Re7pQx65Gjcl4MlWdqarPtx3J8m37IQA4144mzDW55/Y4tQsf7Wq2apG5Ox5PVc3VHUun6sxaGIuZNbXHLO1q2yi7xu2hFz5PKtaJuZ+prm5PbduZk7E6MSZzYs+oO3dtw5nOJpq9q3Pkg2mamJeZT98xNonJFeyqM3t7WYfTkMsTGXTMlnXEMjgxDYmAVvjlVznF2i+/yonTEKI9EXKZpg5V/VrTT9SyogaEhpYUoxwPvNqEWm0C/BPxRcqHKoMf5JbF3XMFjbDAT+g720ecx3kwjJpgHHrMJAhT0wX3ruZ5CK8fTRvrcorCHxjyJkKFprFHb5musdJ6rsDDhln+VTnDbJG2kt57mBjXJllCEY80gDyc4CgM7xR1FKK8hg6US9aB8ho7yKM8RyxBYuOaw+WRVgdhOjsuD7OQQgbtmGs6t63RpLRG11kcKKHrVgaebAIbFi6KQ5sK3hcTzT3FNBwagK4VZ8Nfs60zKCWiLA+8Dr0r9ovk42eouyBLb4CvEafz0acFOv7eZKaiW61fxFyZeoJGhN5Xqu2EPNqggi5jcrL1emNi56Zw6dux70BY5I2/CtdUwWKK+PHBG8itCTaAVfMU8SY/KiZe/xZSKpGgSTMJYl7lkEZXEeY6RG8p9ZXbQOpUSBxYNopHOKtNU7UgYpEnlDTRazEgvpk74G6dt9Y8b9ZYpzmf8w7Zpn6OKXINtDS3X460hT5SRzqmidJVVTtxrPnJiYZiVP/2t53svjeufQ0rgQr4Mk+HKuiPcybl5yPJJuQSD4OfoFdcRorpOH75N+9kiAKAvBQC3OkoS4aUJOkQfrylgQNH44jcJciBy7XlxSvXtwG7lfilFpZ2BIx3B9LRvuoR/rfnuVWbzy1PRbD73Aq+4TOeXjbPhsP776M9923/Ddtj2Ic78VnuhBdgilqT5fjbegem8h04Z/VA1YNRUZBMnhlnzy9EqronOt5iyGwFzAJQbis7OCsxtCtIQA/V89TpyMEHLwQDz2Om+C0uFZLYfBFalSAGNCThw5Hytp9m+o8n53QnWzvEnSfaaP4/PA8z/NmJWE9KB/UtXliYt8jnLDaVLMEumn6GLeNE2ITLLg9+H1rRr0cgDrUe96Av3XplyuBnR7M7lX4A+d6T9KZhaK5JAMDPqJ/dKTVMx/LBfk/uIVZJYQmhwZp0fqGIpnJ/FJ5hBS7vE93SW/3J2eV6F3tyB7teb/NBr7f5EAZpnxOUr0uUpc2c3hefVv9ZHLaWLwo77L0Xonm6+w9DsFsRWUpJnLtzirw+KEAxgQT4eZE1TWk8UNYZ6koVi6Z3kLtIQ5c6TVWfjFR948wjrEBkrr0kB7DqvpHgs6jkp6uYDTYFGdyebMjgt9jzHvzS69nflzhs68Jo6mIfCiImlQczo5/O0YkOeGewMxqCU/DsLLoqYr2LYjz2m62Stj8pYCl11hHD/uqzG62TULtNQq1MQt1/Et+O/HSrt0oeDzj2nfveUxp48mu778H5Ovj1ZK8L/GAhjQ1YMKZ7ckXJPi/BU8uX/V6affWDvbt4Wl51pWMwTZLGlKwTc6I+6qaUWy+WetKD7FdjfUz9UYdYCyUqbJt6FxqTh3mVD3h/bt+CgAhoBiKuxUjZvjJH2ztGlJhTeemQZRG8uKkHuLyhH2L2hPNTcJA8++kSZHO51h1N0qHeUuvq7PToV6BWqG8q9SadtqaaHy/fQM12HQrLv8RXHVJOfaL3Js/v7TzATiCQ/XiqU9zbhq4aiEFrCFa/OfARPMIUpNP5eWfQxzCvqovSa8iNBphlW3nB5/ICXC0gCEsBYWPL+/f0G1h+UrkrQgEHm0XLmDiQ4PfhR7GJzCSJL/W25pA/XSdSECOG1bVlY1sn9vDz+RTzCuh9ij6DELXlYPrIvIq+fSmg250L0fNMz5tsYldX746v310ptIgWLoUHMqlgwJLXw6hAYcA2SmGoFuDP94xOTH4XWM5IaxM6LPsorkuSrdckBpdi/tug3znhgScICX+0sFQydmYzx7Xmc83WiGHNnKlGyWI8Nqi2OMIcyyYLfWLI7JjSEozq/FtM7TB2xEbx/LxHZMf/jRJt5Hzy1iOY3chekXQZpSOcsEAWOzmyXW1ksoC6T3QzIkvwPx2xFaMx5ngaHIUWejs5Jvqk6+piwddcZtWiLI5COGBH0OlR4WVuusCQQSKLAKI2wTG8SIAJAygcgl9/OH1/xlZbGMgEDCf7DTm8mEXcwVcMfQMe5i6gcbLyIpMEG2Qv+6yT3mWd9C+9TvqXXqc42rFEQyvMAps+zurENM3iALwnVtsXqfOalKeLWSi00fp+hPyq65OYjgKaFhN6yDRiL4wxKkFTS5MKs5QnwahMSHwpJvT+f7bP5lcJk7JtsIwCaXPXIBoZqmPqDMfG3BgubIsOHXdCJ1PN0efuHIM5XGpvbJ8WPaGiF4QB9NrPSe+2mYt5ABkVzXAqCgSYb1vzV/nIMlGgw1IXy4K1aXH2t1Zs5M/l10CkDOJxndKbwL8oTpAcXoZn8DJwd53D2/BFV+rP+zqIVfla3od8Pn+eFyJiG4bEtuWZqBSpvhX0PvJimlR6npe1ib3eE97hzpfCJhFh6VrMJEsizCBffjGKEkpR4vByfPmX4yBTfOl1+vO+GgeZ4ku8GDElCWp+Ip+kEH5oOhQJamBvzCwgIo2JTMgLmlt+Wh7c1nOSV+wVABNURBXxY6e3RqwCLs3eUtwfJY8VNkBG4x77FXveB/XZC78sg1l5h4Ca8d/TcG0laRiwTAvi71KykaOYrsNb6jSuu62SiT5z5kPdpZPh2JkZw7njjofzqaVRQia2TacdllXjiZLYRWUOhJBQdpsP0YoAkiHA6XBLCqrY7SxO8NWjm3/o57+Hm3ev/6Ha67eZrb/93fnev7X8RfTz6/Pphzfnyfn6Q/i/P02Cn3/kvxnqUdmdZ9d1ZNl0KteR//iNs35PzdUJxv1Z83VPzbI95SI8kGl7Gn4sF9cehSN7UmYrH+qzZ7c+s4DeW/Z2KNp2K3Q2//UbJ7QHGftPJGN7gQMhBIhyRZ8j2T7I2o9E/ss7/fwfgZz9FoMCEm9Wz2vemUR94TTF4M6XAo5IE/3HTnlG1Bbp/Ol7fU5yPEPr4U+r9KLxXw8v2uFF+7O8aAet8df+kj251ris+WHjbXjfpK97P25SG901xzsrPb+nJQzMSJLeKk8MRHcWmoNWR1FdnZdCgc6gF+UNUiUFIRCLgDBMM52yrCE5JuCJQgKFktiHjCg0iEPfhxeHZU7wEkWcJ3QkxWyMJqaUgSzNAGSXpJ7vKxZFPxymFfy/GMe2URCIWwEkbyWhdhg4SdX19E88i13hUvJ219il8n4HiVKTOQ68xRfmLZ5eCvy6eIyD1Nx1bb4WnuPPJj0/ogq10+L3lJubL9DD+IwgYRBXJv7mBU2RFfD8sOASfHTzQodH6Ms/QgcB90uv05/30TkIuN/CI/NEEqpLSZrFtOR8VXo1eAGl7J21TU5dqK0S3unFOQhhKV1HYUxiz9+U2m0VGh/WZA8Jzg1jy3McGlQWIf95+9Rni9Zx5hKskjd2UpmDNG4O7AT48ey5bV+bJ+6zx+KJCyuw2is24lw0zz/v0HcYrRPLm/KSorV2lcMeDfWYtoADK+iVPGsBXZZ/3XGCZk3RwIJlUpzysE+UO893bBIX7ScKiSnqT4oswO1n56l667F8Ao6lWDL8pRdX+ss36ef4xTxEWl0BtarnXz8XPsQGgwwg9RBA+MSTg/SNAXzkw/EcZJaDP9/Bn+/gz3fw5/ui1JqnDjb/xd3UC2LNvyAC3VfC5JUQH4uZAufDft7B1s1bR1c00c6mda3dY0IF+eIcanli+WdFfD6oCb+8mvAQd3+Iuz/E3X/jcfcPskkJWi5Zo8o69QdpE4trlTcWkTj1iF+X6IoXRpRVeNkDzMszeW4OVqnDY3N4bA6PzReyTf0zC1Ni0nuRh0V+PfCbkn/bIWRqrfJTpZ128bJXEz3ksNw70QR8T9+zK8rwwnsx/75jsu32oJpDJFfhB2G6onFhomhfhcdpu9fysOQDMUmp6XtrrxbizUsoUEIRJXYsUbs8XWpN7GluNMNwcrCnlT5vWa8n6KjH4iU0zaJ20y5+7mHYnbdbYQsYj4pRccva7NtajwUoPcftR0gu1usc6a1TqDfZ4bTs3VzfJdmY/8xo1rgMG4V/+sYZ8IOJ5WBiOZhYvjV29/EgE2JK/NRb009ean5P01P0tb2iCczyQ5i+BZ39pQQRX5BhVlThZZV2EwMz5cDbMVZLUTUfQoX59ioJbwQbQAefNcXwKdNzlKnl6tbcokN17DjDsbbQhtZU1Yeaps8XukYMdWo1Y7hvm9wVK908N/5REeD4OCSXpvYKAnLKg5bn65CU4CuTJKHtAaQPe2g6TWEgYIDEtuqA8j/U9GttfKJrJ8Z4ZCzmsLUYRMZKwVMqDvZcM8aGbs+Ghj0hw/GE6sMFsd0hpe5MnWr2bDIf48G+pUzfZXsRCdIETWyQ5cUOAzuLY2CQy9/xxWcb4nhJ5JONye/ZNTCH72keZOcFWUoTaCnJ1vBy6yNjbIwhYc+SBN6/2O3F4bIzGm+f8HxeOsvvzn88K2j2Ou+XZadvbmgK2P+z+bg554d8Ri6KSb/zkvRKlC1xo01Hgx+FF4kir5tS9RASx6O8uMA5VDbe4BkeNPVkop2o85FqLGAdGDmTN4ct5dz4p6d6wJKUd+c9iT/Brzwbw9HJZDRXFzN+XlR14o6pag/Hjjofjp0xHRJjoQ3JbGrR2cR29AUgcf0eYtadLWODofnUTRvLTE8m09FU05nigyY0FaO7o5YXkFieTsNWNrSFZyJLaMxmrxJ1bowNZ0gWjj0cT1x1uHCpNZyS6Zi4tj125xp7yrYss3piTEfzyf/P3rsot40ki4K/UsGzEW2fS8iULMmPufdEyLLcrWk/NJLdfWbaXqoIFMkagSgMCpDEnnDEfsR+4X7JRmZWAQWgQIKy5Lb76D6mLaKeWVlZ+c7Hq8D8uJjNsjaUfxJJtqyBeX/r2c7+YwPmve1pNH22Nw2ip88eB7tPtnnwbGdnEjyJJk94NNne3d17vBrMtLbd/X98HKyC9JPnj3e2dnd2bwPSNNbj7Tqkn+6JJ9PRNAqehNv7QGGeBc+i/afBdPuJmI5GT8JdMekorrXinv0q8/mJENnRpUjMpet/5zxXjhywUgGhlzCkvr+D7h0UUPGG4LJ+33tAOvfx0YEudlMnR0en47++O357/PbHkq/a5dPHEx4G08ejSbA7mjwL+GR3L9idPBP7YjrdfrbN7fzY4cmz6OmTkO8FT8Tuk2B3b4cHk8chPI1Pd3d49HR3Mt1bg6a0wGc7/1h7v/dXbuX10cEvm21lcttb2a+28umeUn5FSvnN3Iee2/8e7sMtbOV278PXes9Wy0xOQ/ZW5ezVxgITrN2ISfjKyYj1Yvs98tHn4WAuoP4ZvrYTGccymQWYoiJIVSxDKfT46D1HyTQSOsxkSpcW64JjkyU7N1Uhz4doYRDREF/nQgsocHd+PA3eQNHs8y1g48O5WODraxh4nWfEv4trvkhB8Tv4OHj8cUCyqggLUBtgXUUqpAiqG6mS91Af2bMq+NkpOitzsYBUBlh6vOq9xU5RVSIMCA/Pfik5C+1dpkxyMRNAzyANMqKXTPL9XRJ4oNQtlGleveSsSEKb+LW+7F/nAm0PsEpA6ERkLBMUpcDyOc9NhfVYXALepBwENMa1FvkPmoVzGUfO7tgV1yy3s22+14lSseCJ9wTADfPQeGE2d/Eu5f8qBCMnzbLgO/TAScFZc4sdTDSs/Wou8FAyYeIyGGTlZaSl9S/LYMpnunpok3ihIkmcIk9loOdQXnE8KeKLgOhekBUxfS9VWNA0jY0i5dE/NWlTWpPxLOPwTCECwe//Vyamg+eD/3gUqkWqEngrHlEv/ciZ3MxL1aBx+sCsFRb+udJzGTIybK0cyt3d4rrTDGKrcgMm6UG+0yIW7PglBVSlWN4epxKa5aqStMuLWl6AokCfi+rijqJnk+mTURg82xHbwe5k8jh4tru9HTze5Y8nYbj3bDQCkr/g169FMsvng+eP94eD64AXtRJ/AJTQ6rl6wt10+Dysb653f6dXgCVty4qbvYewPaDzNTxWerMlOJ0+u0rq3gOUXT4PB7nMyYjWsy+2p52nSssNoVd2qWP4b4BvlQJXTf4pwj73gOpHBvSYb3QL+t5St0DlYP166FJTr5vcSrPzYeM2hpmIRAKOZBuSGNuroi23gPc3RhvsqC5EMtaqyIzo3neAWr9yIILbhqNgpyYG0grr4GkutzbrsHYsn/oiB1DsO0HVlQ/K6qXhU3LrWPunQLT1RMgBXtC4qHdwxuWNxgd4wyO+K9zDwW+EebNYTXg8LgvAw0h3scL6PKbQyXjCtdh8jTd4bpoX5ctXXSdejrUzElMOkVELmcsZ/WR4nvUkCkKlygj7ctqvt1///N3bvrU9amSpN8e+5j5LFvffg8dPt59GT3e2g71no+1gd3v3ScB3n+wG073pHhfhdrS3i+3ae3g+iBXY0weT7Sfh09Hu4+DZMz4KdndGO8HkSfQseDp9EkYTIUY7YdQ1xCRW4QU+cjyKkOfi8Uk3eR68KxMrAIevWDUmozHZgqcpgKpF5z3TN0d/0xyNouy5ZlMVx+pKP/+Y/Cc7j9XsnAUsVrPSmQzlP/tHmUgRyK3KFrBQOgz2n+wctwz9I5EssWS4BskEhUstc7HJWIlKBAylL2TKsiJJwJhrPleXjf0nA6MqC1gYC56Bb+CSiWupsbRrKrKgyldhMO1j4pGUKsmIjg2kClAU/DZIKN4QEGJoP8KUn4ZoznVkoc+bs89pJi6luLqBELmxoLFuKdTZMDG3yINQISKfTgq+UI5NYQ525cGoVCQ8lePLx87pOD+C4s+myqhPdsDmxYInQSZ4hElJMHDTaj16TJ2KXOeg9DBtQehD9sS/sYxfmZZDJrZmW0Oc510qEkiQUn6RqEjimv317N1byC3694M3r1eu438b/J/KGF134Xz0f6HPSfX8OOJwAwwJZAqFc1QZkya3qRlRamb7DX3KJZfmm4wjeLAlILxLWP8WGKz7YrJfx7k+0HgV8xnQIzyEFhQQO6phtnxQWbs5erb/AM50NfOX8mUAlDHM+FU8fskzGR5uLnmsWlb3DLii+kG85Dk3NmKkz2wKJ6MSjPTWg+YG/FqozhkPN6dnN9qZmWfV/qZFHC9BWRzzED2TWG003C+r6ztusvmTkw/ESqjssDbY3cCgczoPKE5MT7A3KNPpDnf84Xa1UhtNeqPdM8PofyEQgMtUmscHyOidGmJw52DwT9sXEKnpzSIRSv0FqHBSTGKp5yI7yWQovhIMVk26BgKp7cpS6GvY85vu/h8qEV/1EnRNuGbXbWL3hcgP69CHPHkhjugJP+HLWPHobnfunbHP1kUsZ9JUE6eN3+ypay3ib4XIlne799VzenYPHdjxS5QFw7kIL/A9rL9+DkBuBxCEh18ZEvVJ74rbcd0ZDqLIcVR4oaLlbZo9/B5DbQGrSCQYlJ2G7PjlFvu7Ktii0DnTqQghDojblscvSwHM6UTuCEbgGbIPH45fDhkGWTAeRWBzGzKeREwrBq4BLWGpUwR88C4lDcxD9hYrOUybU3tGc0WvNzxbsrMCyFND7B8OUhlCOtOVsx6wD6evAf85M83hj4kA34vIBwrveiqDbiZry5vneaqfP3okt+RiVmAExaNc6Hzrn+nMu2TXQ6e57BqEsCEuPE3jJWlzZM2Pc8uzUKMDHTwfYNzNOORxjMksS8PAuovW4bLzHvr+AoIZEIqmaOpuq8vfrUModecjZv4gTW/xKllQNyG1kIk1sW97Je3e6zWO/bdMArgcV3apvgd2cGzlPRPBoPNM8MWYYoGyvI1zZ0ggwJNBEuKZcAGm56qII4bd2MwQTRiThhQREE/86hHSHUS0RaRbNwE8onQOOm7Pso6njJdLAXUJ3QW307D8Dn+xK1xuJjDEEu41Z1dCXKBHj/FuKreW8lD0WDWeNkQu3hr8aDgRgfZJK9AJw38XAt5pcNjU7hA3gytNgdaDjdHn1PatsMg4kI8vhEjHHHEKWo8lWBBCjzr9vVygU5spu0Mvy9Vcgs9MGcJEx6RNkNDQlOuBvcdc57XnbM41AxfVDsiQI5sLmP0R+s+Qw9n+aOS4n+1TGjxwNJS/izGqqXzPapGrBc8lEM8lm4lEYJSu8VAECm3WoVkBtj+WZzyhATT4kiHF0Ox9+Suq/enZMXouek5DnsBvULJIiksRsUvJ2a9iMlfqQoNm0k55cHLcD19Lo3HzUPK4fFqqgKAmTWwhk93YZGNgOSApPdnKuyGSSPfZz2cPI0c0txxqAlS3F5k+UXF82zQ6UclyoQrPNZBTdqlykWkgkxz8QGMy/JRd2prN4WAuIzGGft0j0oCQD5yMSplgEG4J6vWJmIKynCOZVAk1985DnT2TvJRTzPmQm/F1ySKhTG1cQzoc6ZpeiMNB2ak10d/Ml5LfURii1x7CfZedNdgdfPKgiFEAIG7g+ikDA6r+EnFl5+qDM8jXbIw1vfkrHL5DXew2PIpkfnfSxo1Z95Wc+195IthL9RU59/WM+2b8eBcEbsaaN62W60/9ZxleOKeuv4aQ6V7kdRccX9Zj+riNioHeIzU9ZFeODNadZPluipEnNbGjMeEniOdwG3Rs8dPnXmTjQoYXaM52Y+emmVoA/a3HN2+xg5zFApgX4OXUlJ03Jj2H9/zcv6BzEtbhXIF7RUN7gRzqSvx4U+TiII7vEEU4uCiMi2RR5J77IaeMuNA6hK5U8kMOFxVtvrli1B/uzkKL+BIyCVl+b4kPGHz2GEB78QOtU1sUROrjuL4smXiOrQ+I/6RX8Ju8cubw1h/cH3HfTsU0E3re1IrcHXvQrX5pBledonVT/OEayQ8+fSR6JKUQqDNZmjAdXG2tWV3EuQW9Yh/55vvgQ76Y+bgjdd2puFQX4ouvw2rEK5WWnuA6B314kc/BDcOk1cJeAJwM1+g7kutAiwSCMi4dR7KaXzzO3AMOZ6DjKXUnPfZumGTc3xH9m20PyIGGQhzp4V0UcS5TLORtBtel4gesE8rR8YCvaCJi3KHIBIQlQXhkCCL6wSFy5hAtNwYfpnIX8AeiAXjETeW1Cx+I58uI6jrTGCgev3yMTwa/Htv6yqR4KTPSQEDsk93dUbjPg+1dDIjlz4Jnu8+eBZOdx9PoCX/8dP8pH9RBOSnCC5E785V+RGbFlzIStW2bPf60g5GGrU1C+KaczfPB8yc7o+HgikO1Tkg2AIFfZRjPgDRMKgXHKvk7HoHttz0cXMmI9MTDQZHFRu3//NEjc46YN+lz1Wzn6Ygo9GZslve0m3j/YskMUzR0NKQ4AGgG4iW+h+UIeAWKhPGccQZA3mJoMcNPc8HOO6c+h+vFFwIZNQXBksJOs1QF/CQTmUvUxZje1bSaVVly4qWNLtVAx6wKj73H6mS1Eak/0wKmzkGxEQmlS19Fp7spH1RqK2oWbT1kugB9o2aADRmXOVuoCOuIxzyJdMhTgb/0U6o1r1pvbTz0q1Sp7cvWej3RimmeSHuC6HQI3bzPo/+W9l3hcdW7WmftUnfru1GhR3pWZlMV4HNYLd1VA2c8meF2UH5iRicLZ7tf1minV9YOqqZsZ5fNVZG5ysIqzLhU8j7d322reV1K1LIuvGzoQivkW/14F1icczXF6gt7598vcIzqBLJ8kY5VcZNRX5cWmroaP1cZn90ERc6oZzUUUsAmRE+41owzYiVYkcXOdebZROagxdZhJoTPC7zGHXmIfN+1/gL9So/HRsREhQ99n/T3GQ8vyne9J1/jvu0vuJZh7V3f/H2EpULun4oOsIp8lOPGfGlSFJTU69/e1z0V/IJuj4gkH5OXOFE4nOomC9zgpXPXWQ/CIHab4UoYNqsT9S12PGVqIXPMnnBqzupnmRs0002J3wxlLDRzYd/NFiCdK1+uuit0pC8mIuoQJr6GvbRge9skyaTrWAVazPqkpjUYYaYM4yFkZmNnGLsAwnYOu3Do+YNzO835Q7DKyoQJnsVLNhE5J3E6LKtHouZHCxJPTOXZrRXWAyfmfWdvv26g9ykI+bXVVhji7yovVt78xosGV10bbGnuGA3JpfKh5F0+aMHOCZfPietCGxewMYmAhBQKLda8jWt3Dd2VVI34i3t/BZ9JbDN/BJNF5+59Er49H4T/wT4GK90KTPbNVYlrHAQ6Pzh8f/zLEWkpj9+av5CyZBpq88YYoudo0eFsgBZVrT1L9djhbHMneqv8ofz26U/lGPGFjhBf3fHBa9gwwuAmjg7GC/ZujdbuJF2mawirFLk2VvRT+nOj1TRSpGB2ZxOdANfXxHhh7pSmT6yZndFD5ePuVmZr8ATvEbcFb7bz0WKRmW71JTyo9URLx9LtWfltDkrcHbysJ4SQa1PtlHA3ED+OSL0WvUvipdWHtXC9Bk+vohWOXud8kcKeS6S2cIZcWkhSba7vlQwrhubBgDX47IxGI5MYHHNzV5XP6ms3kHkN030wS+40EsDSfRGomxzcm/KYBi2W1CzmLZZCqTAUsbe+7k0O7ZcS0VsnZWN6NxnuZ+gD/M2c67XpRJqdT7CTvdH9e5NZDwdByceCylKCNWTjDdWcxXcCEOf2Aje7pziBrCLrFna6aRqRSAJCLmTCTaIqk0sA/klB7esW+gJa4bxD0PHHsUgwzeHqXoe2pe2pFpg6a5yVKRfXjWB62ByNZqAoUnocLRO+AM3GmjFevlRnL6mt6S6uRYi+BGt6HlE702uqMqqplFD6vnEYqx5beAXdDsteh9DJjPhPPe4PzL/qJjghK8G6Xq/VrGo9Nka2KcQM9+l6iO1fQXMzii3R3H/dBsebi89EJDN4CNdfY2pY9rvKZI+zO6V2tpfqc96nqjptHapsfY8zaGV7QFmzsUkLuq4ftD2CpmXnfBzycI4Ilmcq7jFEfggdDql9axybWqX3QGemQ2uknG8wynteH8GIZj16Y0vb9UKm6ztdyNS0zy0FLUnLeJ4v1gOxpLyWwPz0/s1rHPNzyaAt35o6JWXqwjrn5ubhq9xVWgwc8X2lOhHNR5hX03IBJG9NBEO3hMjHMtoX7AX52J7YmZtLIh9cPy9COj5bRQ0nBv0BukKUS6EBtthBwsQizZfkm8JCXmhjdLEdy/Uyk/00V+lqZibie+Kp2Bvth0/Fk6dPnkzFaD+Mprvh7jaPor3d1j7xPbxjiB6gXN4JUBTbvwCe2P9G4JyoPFeL1RDdm4RhNJns8L3t3Z0w2tkLefR079n2zt7eJNoZPWvu82sA9DiJxHU3QCV87hB0oCPorVCV0oLl0KyJ2m2DGgM+TWUGte+KWHjNdCWwth2VyXZjuQCXT3Wvs15sXMUdAVh7dak/h/27+fih3r2bnFDvji4j1LtTJ+PTe4Qmy9O7o+V6NunQ5HV69/UyOL1719ibDXpV3E3/TmrjM6z4m/5d6qzNBv3a/MzGnWs8zMa9S95lo54V39K/m+VcevdYwah0GZJtV9JQHCV5tkyVTPKbKMLutVv32q3/GdqtL9QxbaAx3lAdRUdxf3nvL+/95f3TqabvkGxk8VtArdgUdLx9JXZrBv+KdCLTFJkf+kdjIeS+y7P8EdyEwNZ+66JiL8VUJhBlbIbtTcwWIud28Ib3IJSMjcDWSS0Yn6iChHAzSY/RuUzGCxUV65OmN+HxhsvkDfVs+Q45ozoY8MZuZVWa4U2W8ErGlNy/7rhkZiHfYe2uwB5lvxM/3TjP7ZozRxTsffK9rqh/zc0DoaHagGC2uQ8cVyq7EJke/4r/PckUgPMmuenWuEBBxl+/dx+mCC3dpsU1eHK9LDIk/O9I94O9UelC69tibyBIbSJMEieJ7kYz8iZB93d4MdBvaCwj8KcXZgwKbiu97yfC+q+Ba4VN6UxO5ggC8K8goud1MbfO3eOFx73FALPyAJcJW0CVLOOb41UJuQWiHu+4jjV7o1HNtWZ7NBqZR9TudC10G3At+9p4P7v7zQFuD9gLJjNKWZijOzVTmBaOMw79NRc8HXxqYrsL+g5h0+J2BaIiXZd5jV9ygt+qO3/Kr9hf+SU/w9+M+1osZjxcMjC4yFAENDnTyyTn14yuF7n+fEzOeRRhsVKoXgreMedb7OiMETG1XWycxjkF7lgf3XMm9ccEHKCMu6OIKIhE6jKNOSHRFnulMmdcQHHUB39M6JcAsudHZm16iE6T554n7xyP+GNybqnulkP7z5kkHFta5BGlUI8+nltrsps3YfHgByyU/cOQPcC6gg/Z//kvqsO6RWaUCHy+H0C2Cqt2ePDDu59/ePjwIbkS+99skYTKxqDRk1FhwXvjd+tFhP9F+xyyXFznvt/93VrtzQ/XQbrM5ypp/BkY7F0ISDnnDnnF9cI0TmMuk/pXFeYiD8iRs/6FsmAHC56iT7DDYazYtTZlmPpxW/aClSAPzN1Bx4b69u/v03d5n1bRVTrCe6L6p0eCe6J6y0R1NbNcQrKl1MLIEHQmRjBp9kBNc5HU7g10fsjQq0lqyuxkLgoN1sgPYfB4Yfg7jH+HCCHghwWGkIb2MrhSqGbnNXwFX23ww8VY+XPIZgALwdjM/z3JHv3XidKUieuQ4BQAoB7oh5Dk5Dk7X4kl50N27scT+OLv6ulT/mTRo/WDiy/NoQFjyg6IM80WLtY0v1V4c74q0Kfk/rE88dLHS18HGjj1WGgdVFVbA9tO5E3ErCMRFPYI8NqKyKdUIGIuIgwC0IgGBnvqIWdrBVusL7tWsrVPCbWmEpITKAliIrz79C3bQ1+Lgu2du6kiyl2igIY1co0EpE0BFrxLD6BUijHkA62PIrpPsaGqtpDQORLXcyKoD7fYMdU0gWw+7Ny8Xaz2dp0bqK5WY1KXrX/i1sjtyUlP1wc29U6fKfGBUdxBRBHPxWzZhtXhXCktylokZUqNhvwIg9lU4UwuMG4yFxBon8HLSqEdiy32KyifywBFN+DQLsEWjQV49PNzKHfo2xBYMI0Q6S2M1CqL9OkzOYLy3CT8HtsU9f3W0OrZGg+Savc/Nk/XzzaFgy83oQhjyAsAmgzTqEy/YhDNXuOKkfgIc2egGnhwDuB4blD0/CELeZYtGSJPIyP+VGUfE7ww1UDEjKDtv6/63G7ULNZ45I3Nu2p/hWCqJJSxLJXEjeiuKrqGkKoNhfoQdNUznnxMlGHviBRssROVFjEGrlVBizVSYYnlx0QmYVxgmFhiGUl9ztBneat5RSyIo0xeio9JfTl/YXXAV62VrUKWZ3KCGcIUgB3S/dKeCeabgLg+9ZiKZaN9AmPLSnLdTENFeaDws/F+wmJmhkHHcmGq0PGygpTBNKM4+wtlA5IJi6UoMMoWddpESmHhsagS05A72jW8nDJn5zTvuRmb5fxCaJgzhMpCoWDqUmTs3NnBuSeGyCGpNm8F9nAfmvquX5t4YNOCwYAYjQX9KE+D3bgRf1a96jd7w2O5kP0fUNP6M7pUp4We9+5ommPccM1OcPPnE4M6DWPZeEMJG+ns7bM550kUi6z5cNYktxs8mAs5M0lP2rt5U36rHjdA6Prt1YD3KpRIFlDNiVewWkmL5m32dlF11LHORTp2VrvO/6audvENAM+ZmgDnwU39ip7YUOtkKnrz8ALyY0QiFQncOm+pSFCx2yj6JF0w00sTdlyRb6TOwRstQq4SiYKhsiVMPyaGaKB5elLIOK9JuusK1NsZfqmMuu1lkonBTkTr4/BSaBVfmtVVazV52cx+GIUarEHD3a3tJ1s7O6tt3A6UOnLYuEPGKuJ0S02fv2qVrNym3WCoEuCLQHPANQOMBYlRJnbyLZBPV0/+f9OGtrvq7nmWNGwfRruWe0cRFfCsXRg9Uh+kLTuMwekDY1T5KqpOO9Q2TwDXDNobhql2v2+XoudcxsDp6GJhMn302V2jFya0gPsISZrivoO4XdCVOFF5F208qD6WTGSJTBi1am5FxT2tlQbNOh4thIaVtCf9qe7xYdo5gqk1w7H3WZGENsMAGMHYZJlTgH+skrV385W8hvUXGBruJNYw5jS70JzP2ouECPSAuBfgaKxtLWuCaYu9MYmatu3yVi/qcntrtLXdWtDnVipkx/L96V7J/mfRr65SshuUClLVMsh/u0rZlp7tXi17r5a9V8t+C2rZ+svf79XmseQ+zK+EI2xh3pROhxmXgOqcz0y1qerJ23/svMChWixkPtZzD7heQYF1asDOfjrwiGnlWzxkkchFCJ9QbodPh8dMJJcyUwmgVPVa7+/2eayfTva5mDx+uru3J3amz3bE9pNRJCa7+4+3H0+ejbb398Mw3BZ7jb3tOnv7VtigK4tDlO+zmx1Kizgem5d6bJL+tFUE+HuZjhnOCFyuRDYr/alu66R2erFV27vP9vfr+9rp3FWftDh3uqe97Z0+mzqIItSbqRgrtpgEZ/Vd7m3vdG3Tm6MS0nh/Q1u0pQNnMp8XE6wcGMaqiKYxz4SVaQIdXeDWHnmOuQ6ATGA4tMqWa7dPLwKretTEn1IrgVv9I3e+artfV3bhyTKohgsAEoG4zkWW8DjQS52LhU+w+TI7320Zw/6EFh+pq6O0WjVHuulj8/mYtIw+7K5tPt+BRv570I8PjY3GCNYgUuLxGSUc+9CEzTot+r369179+1XVv1+q3VwVprJKmdZWwuAvpKwxQQwh5Imachl7K6PAE8tSsiNTmk2j2TIdhrcT42SWwVMZ2OUFIAupJLAzkdqQJzxe5jLUgYAE82L8gkdOaEejegKP7IIpYOJfUEHdqXSA6eudmkRSs4XUqMoAdpHHICWLiC6ss9FKMh80coCbRhgWYFMU/dvk2lyCFwp9R1rP8Dt7cPLu7P1DCEWj9N6eNmT6w4WNcQ/1Qd+YNTe25wyJpeONkYCGfF7uFJNUsXPsfO7XHpWFZbxH8EplExlFvrot5actdlAv2QLHaj1neBiqIslZpIRGJ4E5v8Rfhcb38MDOyI5wxiGzZXgs70cFYOr9bcgLvhepyHC/KtGmFoX1YcpEXmSJZrujxyTsQ+nO+lqBfMJPKjORdxb9NXtgoYgrGDKZXELZJvsnkAI06i+kXkDKuWG52eoXlQFxLqZTGUpB7AwIaMBs64cb4B4s0YdzDcjDHn2bcdDloPbdoODmiPEjz8UVX0L+XlV47qf5zkwD946K61AIPNm5YPujgOKLGCWUw0fO9jmTizSGove57TxkCc8ydUVZkiB5MFSjIKzhUcQWkNIpg0zRkgKlpjLG2q2YFT0qQtGYZ4MzyKu9VgfwN7OlxtodgDcgcRNgY3GPhMeYFiQ7smjQiJ0yjRi1YtgM/VOKRFynJPgRWVIhxpRFEOtVEZdyE+YWLTjUeyEODmrOQPYMROIJDy8EsB1aFwKyAefZshGIZnI0czbJpJiySMR8SUwekH7gzDahvNJszXcDym1r2jY1qcB/pjJAmytBbF2R2CzMAlrA1paqyAgEW+wEVNqQ+nfJ+AzYXvCxyrZucmiIGWcFUrr2abl4IyIwREG7aRHHS4AoODtprKhINIySfCfiKpaJCCKB/jMiYqCIZQ/evoT/PgTuz1iwttgRD+cMWgPYOTU0uakyYfTz+BhCkSF1BZww+VhprM8AZ/nq3embg/fUNYwhzxYmTNeVJt/cSTp4ettpOnIVqc1KdX54zoeoMab00BnUDMJXShM+zAWPjLX5vwMEUnDcXZ2upReQuoXMg+6Tc7nG0fZP//33f2zvPN49eHH48ujV3v6Tp2Tr2qBMCPxmXdVqWIqAIL28WaABNnvgQNnhFP49IM37b5hddLINez7D+1Ik+YOHg+fbezuPwfPGfn155H59uvvk8yfS4OMYxNibxiVne2YFyrKBHaBs8uE4yfd3BzAYnNXg+c7n/gFXrTsBPPcrhII1K1LctQPW6yCJfKClX73AJfSvw9WhAP/+SPv+OHj+cfDh7ONg+NHu86OB48ek1ujlUaMRgLPR5scXjTb72zufPzZNdA2h23t/b3RXa5v1mX87qNIZsUYfEn7JpXExbvmpGvbJaeS+3/8qRCHYFdTiMq8dqAGQFavqlmcK6BmWLogx+30ICofaeFLTQ6RZkUQiY3PBL5cMHSdR0k5FFliOSmVsFqsJj6tyZOGSkRchkkkNamVQ+Jr3aN1jtMHrg/sdr3j9CSDtl5++wu8RAygByEwxLexCQCWdI1LWBhhu9Tl6r9QbniyNQOXTiSjFoAWzTWwgOp0AVFaocW5VXTiDF3ga9BiYszJCC+j+obZJEcfEqKH2AhXX2AcVGnOZswfUIVcKsOZqiP9agI/GQiwUvDSE8Ph7zLOZ2ISHpjHI9bQhZOEXsxi7SecgT2vLfc7+XnIMVgrRzaWCxWvJtGFgLXdEfVRmuFj7c8XIboE4iK1WIZzDbhpQ9VtsiYpfuLpCjOEw60s7ca4r3Qhs070wQLgFIBzMCzpe7BVVL7kZbcU1QI1HEefjXKkxIkR9TcRIMaqzalCm77liT6mrjgS0Mqrm9fGb4/eWL6oBzWEob3JTPySGegKh/JtVCTT5H6cNOwKpckn39exvr80WSAxnKLSawluHqHexOVNNYIB1hkLOGer7WYcNcjlMLhJ1BYq5uFhAQcYiqZyiYDJj0dPswV/fHb/VQ5aoJDg7en10+B7q1eRG2B2SzsOKxoKqIl1jJk6q9Aj84I+n7z6csBd/Z5dSkVpKb3DDaSM+KQEW6m7TQYLjJC2IBBkB/3mtJWRRtdmJ2fYeOkaCAshupD7Pe3eP9R2unjJETwdwEpgAHwD3jrgzBAtxYcaKUFo0/xcDdTLmowdFJB3UmA6qvqwPtUOsTrjXmjTWuWogwnM4ZoysgFPB6Uu0GFsjb2MNXrxZvQREKXzga954G10r/a94lR5rhfIKCsKIDIgAzG41K/DVKKksrSgvDLcgbndHNVVuPCDAZaIfYneobDbbvhWSO1QHmH/OiNF1DcHWqhVusoI3VuHaqdF97zBsqH0wHYZWq+UcEllA/kk6DWPzODg5ZjOjazF8qMsDZgJMhcS6IDUgJrd1CKsV3f0CJupbP0glpXItRZ41ARP17kZ/1B7lkw/Ob1V+DGgDRLcr0x5hLT4B3L2KZF0y6CqrUW4NCfAxew1v7ZFlslYssOQ2HX6x0uoHWKMJH+6tut4A+f/gwJ9t/KyqT4sSjMGUzOiwttiJcV0sI+osT1MiUjkvgMou8i82YBTZl5KHcNgL85C14OVPpoQ1sMvkSaOmIuILz+BmaqlDYgEITVzyx/E9x0DEfJ6pYjZn5/95DrBB/gJ4vLLPOqLIDmMZXvykCi1+0GXgLYrEIrkUsUoFyiKkSQKdBHEOwGpIDdv8SxWQ52qwquRu8RJHAFi53otGHTUmlCA5YczzMXq5brHXasaOrtNYZSJzVgbd3GlKExy6eoN4iq8kvOT/rtb8udzMEN9zEA+LStwuVzUEN4GAsA3RUCM5rDa75U4OeoRTdVXaPTr0haRaqLq+55MzU6ib7Mnvz34xYzCBJbYhlHES6LIRqu3sujmjy/eXGoiAwErIZwh2G0pNhpPjYw+RauhcDLZt/BkQGvglUHGgPvArEOazf8WI7zckzBWiglrrS0Z6rWYWbI1hPq1Sj3WpmTwYIVBRAsB1lUupyFDtBDW9TWlDKJFa095GKizQN8yrYzIhHTXsCOiIe6ywhngPVAaI99CsdQPE66P+AjBbce/oes4LveZ5FLZRpbQqCbq+tRexjzruoDJ1WsMmiKVikaqMZxJCmR1F3W2trI8UWpc3wdaZ68pGTXy7YeWHRtok/RcZUqdFEpIRNpshjn0RXFMZ6DlQjvGkiC8CCv0KMMtkoLveu3c/b0JkVrufk/y8ViderdO4S1P0r/33zbp3btAtWgocMjy/yD5XT/vqEHRylDPZKeCPT5XWBeMX18IF3y2fvjHnMUtKJ2xrELEOnlVKS8uqe+q4ViVJ0NfI56N+aJSU8NXW603Bmx8JivUCs5r0tXOIbOyf521rJ0Becdae46Ozdw5gGa+EmR2/IkwlRUwgOI5n4dy5hmvmHFWzphYDPf5flbM8rgGbWjMgSGZkdzfattVgNA61lSmny1+u50WgEg5NZyl7JYb2YjqXrJz8k594iEjm96TjnnTck4570tGfdJCHeDCD+L2uS3VqCmFXBR+A/8F4KZOrOGykMKpuRClb3pprZnPtZs6ABIDSX7PNYpmtUiKr7t2eify72A3ximZT9xT/Lij+Bmt9Dw6Wh+4Rttykb3pDK6Hg/pj/6GM+9ZVpuOHBRiIW9zf47o92NUjWFw9y9lMUMoKUTbf1+hoUuM273XMntdAG89ioyT/b7wyKFfc4+ofiaKMQV8+Nub16VcnyIHpZ6aR3T2qPPPaFSMZG+bjJALV+t3bVSvH4Hov/TI/oDFIDyTDojBi7FeHl1uPLOgixP8astdvu+LhX38o679+Mb+W23Z1kAqd8T1G/hTO+VYqKftBjbSoq48M57taWlJPcH/OdH3PjaO7qxGfi/sD/Rx24ze1/f+Z/3jMHy4/hye4NhPcGwnsD4Z/XQOjl+G+Ritw7GdzTkHsa8uemIbfqZAAHTGFfUBbHcDb3YsY3w3J6z+e2GE//4fcUOTCKw9Q/i+6R4c+JDBodGNcomj4gDjBbkIeVowSxuBQxo504kcPMjn4jp517/GnhT4PLs/Bnxy8x5pruKFvIXM6MlYU85Rc8TSlzTROoVXjTSQ28X4Kp43AOYf9jqGFxtw+YNub7nkSMGt8Tsbs0lFdn9Ie6dXSgC/DF9xzPvex0Lzv9uWWnLg7qlogL5OAWV/damHtKck9JvhNK0lUpyG5zPFfe/GYHcczgE2Q6hFBo9juEQ2M2y8myEoH0ivztPa8czEIpcSBJ5TH1NunCTU4ET+hxhRnVWijXz7ntdM7OMaPSebXGKntECbndkT9TuZwlKttwZtOn38TbXRMnN9iz7dRv6r2OqZ1jXfEWNSh0EmHNiA1OvOzyeTiYm8p3GyJLzKHajVHObOIiuhA654uUPEwXIp+rTfqbDi6obsbvDwd4TBv0pLxSKgsq9QMN8flzK/c+DI/NRdR1v3+q7vbURZ+vdbOR4vVEcUN91twmL07fFutDuzMRMaudIEVUlQjBokPE6twBS1Ru/rdPmP2mrMHTt6YGlAZzJqzAWqbSgUphw1aGBTpQk/wKBqGENdRsIqgOyoWE6p5TyntdpWEz2/w8HNhcGXSNTO2mRrKC8nTa39rL0nOoSoq5USCnDZeJTcrYuQZy9l4PdKRXlCGptcJYhZ3VdkteCLODpDyfOznuoBRjDXC4ODscfDUlZ6rlG+agTPdvc2xssTMh2G9lhSkltE5EtpWI/BHPchnGQj+CxCsnPJ8/+vSgZ8OHyDnC2uHP0m25WY6whWZVNrYt2LP+7ePgUaFF9ujf8L9Adz5/HHzaSjEBbDs/RePOIppWmDBs/tAqPuIjOQ15oHZ37m/L/W25vy2N29ItShjBNSni+NNwAP+pcZF3JzdPeawrwRn/alX96fXAlx/XvfR9rYRf5b2/J1P3ZOqeTDU1BOU73njh72/L/W25vy2rbss37w9STGIZji2q3uyhL3/rfOp72tLvjRq36MNxRj4zCHqqpmhysCqr8YYyhL6K9w1281bVO7cecHYTRLcLsMV7uhZ7206Md7lWVELeu13emw7vTYffj+nwpmp/987fmu+BmWcsrvOMh3nl5bCGrIAd0zElGAjdnYx+T2vuac09rflyWtMzQ311JcpLvj6bvJO+lmsZul2bpcK/mF7de17eE6J7QvQdE6Ib6ipuh4qYjLEmoVGYCazgy+N778s/XDnlHMaXhShl+fgF7y70dWzKP9iCSqgXqZcmfA419LB6bFn6gopED8viEaXjky2r/GBRwGCCnb46fPz48bOHWCnHVq2DYjpa5I+oPNsjcDRi6C3Uq85MvRg5LqDyvBo06pH71+eWdrZY+JvV1m9vj0Z7jlocYLjFU7lV0pstM+2AyjpbRKxGGI123AFObEf2wzRTix+w4pGFHS6E/bAz2tkNtreD0R4bjZ7j//thi53NVRFDKV8kS8tUPGc/GJD+QHWgDWKB3srBajReolMCHd0YzrUOmzfmUFXGxCLNlzUUuHsAjdwB4KLJhE1Ezp+D+h7q4UwywS9ggRT3pLd67Ld/MewsHzcquJXXZUV5wuNEF9OpDCW+tlAui+plmuq8VV088NLSImORElRba84vsXqZ0FjurP76m/uAtfVsmdWDpCx2lvNZVcbSqjKxKCvZh9DqwhNzjOcW3ucMX5uN71SixmZBY14SSafAt3J2jqyMab0WZx77cKa0r0gHtmMHtt8lDn1IqgKVHq1BvYCiJatQ7w6tTsyEe+IDhGlDATUuBJzlx8QSteqjjQN9/jE5Pz+HM8X66GZnH61nw0dzLB8Bih8RjB8JjqPhRwtJrKfeWCB2+wiwK5vhIPA3AfMjQfMzLmCzYmE3AfFExrFMZoFORRIFqYICc0KP64Upx8WqQk6HYFQ93x6Nts9N6W9TzilEigt3FqufYwVtU8lSyxkaPC/EUtvS5qb68S1tuGtja3NUdnScdtOyEgA7BgCmGGDMwwtdEih87p37/uD8P8xUz6FC4DkSAPiXHrLqE1g66NNVJnOhH5ZFWi1Ns2ZWMHqWRJIoXN4ipZYofqtQnkudQzXzvgj3vFlC9VJkpdWXis9XNcSY7bj9+Pw5s1Xe7UrCZWhqocWFpzeAPZJYNiyyGFuV7YSDlSr6PxxqwV/NZeichTl8xmezTMAFoFP+Zs9ATseIPuOKU+48gScG48+Pp8Eb6HRuitdhrduKL6pebxVD5VMqPY0pd9GPA85NG0P9twkUU0i4qsLth8j26Bw5jiKhh9NoJES2ugLxt7RRkgMMpTBRE20Z3yI+CHRlUePqio12z5/XyNTxS0AJM/o3v3tLh7I+ZZ1XgcDKJhUYnAb7TgMq+VuRqJ3z54aoMCsBGoo1NmsfE8UCVjeOv3mIfjEku5Gpardn2oHgZWvxEnjBL2gIWbxzLhNdys9W/FYZ5u/WTnIQImx0aw2rRqI1vehFbDzJqLL6Nwv/ROXjqSqSVVT88Tm+aEWWiKiqEI1DLCvSjQV/AVJwSiZVBRUp5rFW7crStr58HKsr0JzCiQJI8yvFQq4xdzoW40VDH1+I0pXkmwRkkdRYqRXgHNXZwIoNnjTYsW93r4Dt40mswgssOhXL0HNzyw0/Mxu2J89j4HCoHDVI0wlyTezcGfbcohdp8KUGP8GoCL9d1tRwKH3g8fR8y+WIPFw5bf4HXXKh52b48y32StRbMT7jMqFC3sh2lr6hibj6hhinjEOHTOUCk/oEPJXjl0evDj68fj8+Oj19d9qG2EtTbZyorB3/9vbiWxJKwavWfHbwy9HL8d8+HJ3+ffzy6PXR+6Pxh7cHvxwcvz548frIYxvklyIyxYJLP7napUezAD5pd7ozXAjWNH6J1Nktv7xqvx8OD4/OzjqNntMido6ma5QPb09O38E4AKTx4bu374/evm+PWau/zA4JFl/zwMX1xlp8R5sI/NvtLVZc+3Uy8OFwBZlxS5FYWouvs67I6a1L+itXu0LT26HPtdxBqdwDZa5V6zobGCKlewEV0kXGjq5zkWhK3VbWDEfmxLwxzf0ja2fbmusgY5kv6zeU1Aae/l8JfsdGvDxDWfHIL2PaRjWJ8ist8K3KX/m5SFt+HkGJnOZXWlKfIvPdeLMeF77SNjZScN+2sNG5skLGkd6EUm6ypNLC6zNv7DRMfj6K3LRkrDNFDFdDgTa7Ag6riTF8YQGLCtqzKCNdbhEmu89cmJR3rk79vzZYNiEKt4kfNWvV23KGr7x7wx4dga2wDYEq+WXl7tDbeljbed9d2ajefjef9nBwcuzf3Hul3vBkaW6/x7vjFBAdlVZMXIdCRJvlrVxzxHvbNXT3zPWVD/tGZsjbxPmam4D1OCCjJXhClIwUrYCU8F8NSGGsimiqslAEKhGBuISO44NU/rJ7GIMZuoOjoY8t8Q8C4BZcxgFsatxnBPp6S6+iM/d6sZcaaxEWmcyXvRZ7u3xbYwHrV3zBFzJR4xAX02nP8J/MLa3ZLAFHHzcKmMcbSmjoDaWLNFVZbuXwW1to3MEf1RcZ7Kxd5rC2SOPngcKJNQCgKrpeZ/LutlGmso1XipoHlUPNlMQi8JxaJ3PCriAP1Fda/grZ09JJx+zuSpmu51DpPfM1UKdcsg9zWh4EzurBxSzB+rkQjd4Ume9+DzXAr2L/mmC9A+lwFYDt0rrg2z73hp3jK4HQ8sn66HrOC+21K6BGr2R8mLVEs4VYKOuEYPaAPNLteRZ0QljN0iKOHQpYNmit/qhmQItEziXol900B+YwNlr2naZiMW7oqzM6VHkDdM6zvLTSTsRUZeDmHnVk/OuT+6KZZ2BVlp9VeX3WpOj5/Ll+oK+lzn8WS/3u5+4DfW2CIMB1iywacJybP7tfeoJtEN02YOsrgv16XkiYANMgYi+CijEzA1xiNdNkJ66MPyWsei7STQcxgGwY1piuH+2MdnZGe6Pt8h/vR/h//jF2f9h+PPrH+NnO9nTv2XR/K1azrdnvg+HtDUXBWN1o10QzW3D7tZqtRLW34iqWiQgigYRNkBkfYdoD1aoL+u+Php89PkGnzO0t/L8fB0P7wZAxSLaJLUzfrVAt2q3eYHJRbPfj0fv29w+nx/jxEX46imbiKIneW8d5/AQgDUZ7wfb2+9Gz53vPnu/u/KNsbQHyYpmjd+jj/ceNL2c5zwv4tIMOp/DpDIhQz0lO+fL4JTZ5MnrGt0ePw91QTMWz7acfB5/R4fXbBdc2ufTvrQLX0y8FV32SJrjCMBRPdnZH4TME16CG266ioBuzGwoDJ0aF8Uy4nnM38Zj6lh7HD2iYcTjVSRFeiLwyYpf5gRwgbH0/T+eCJ3wmoiASUwHc3WURJyIzhoUgkjpUlyJbjl91paI1t+C2VfsbrqvB4fXtvZEIAH5DjhiAQZjLIBVZEGb8Kh6fnHxYJfi/4BE73dzYsApI9fl5Kn3cbmuR660Bf+z6VgjE1ac/dIXdaAPa/Feb2gu+fIFK50Um0F0gg0BOw294hEelGCjGLSbq564eAVE8K7XVlac4n+YmErKMjf2YaBGqJCoDY8+xaXAATUs36gc8vuJL8I4SWiT5X9g2Odolii1AzLBpzj4mkYg5Oj2iZ+PDrY8J7rTkRin53fb2aGeXPTg3O6bAIUigaRZ8/hAoEE2OZNBZlOe0ykBfu5dcsSsucysFocOSzWznyHmtt8qXz49Uy7eCBM75ehSkZVknHkN844XMxwdRdII55mTKfcHVxvhzB4XjQOPmI6cGAzR4z1cr82XeajzfmCA1GnPPLn4ln02prfgC+Gs6GGdNuUAfi8y6h8qEHZ+9M9GfW62UeMOBiQt9PsCIaOiPobQ8epfEy/KhDQudq8XY2YnX07zM3+g0BO/fmYDnKKciF4BbpM1urwfqNHjGPX5p8xX6YdneDRQEgNHABdhzEcB9td+ILZ4jlWHu5Qw+nL5GvomZFhsvOZPe+QCR8rF/Iyf4kSECk0/O2hmhcAAVeOiPY6bD3eKYuE5lJvRY+bySYE6em1gd2CPZ0nSuUs0mAmgWMt4Qms0+vD9sekhDYcJk1nkZVy+1Yo93Rjv7wfYoGG2/396mYOV/IJqpfEw0tGPtaPRrrl7qr73o0TNn0bgIv8LVmfAHjcZKs2TUjYQcwk2pag1YE/6pSHvC2UIIKI1F260uOtMyEr6VXwcaHH0gtsifeFAiZ+GlPvWrMXQpZw3F7UYhlyeo4ikuvXwrVuVEsM+GRonUXugqr40nHUJEPrKr0yg6S/kRSKMMzUwNRsd94g5xeycq9pT3sM8angbCweANtL71p25NCaSQFuXRi6Vm8avefnfLuNmeyiq3H/nTflMMwUue84pimlfQg0g34ApKtUgXa8B4/qfhDsyVX8MkeF5FCFnYkHdY9Ux2A92Wzb1boDfzGK+mkERFO+jjypTF3xIFNA07vDWMZuRGN7ovQXJXsHKh+UEIb9qpCFUGb/h3SID6wqTa4x+BR0Pa7s3QyZzSGeVM9xAs/MzMd7b5kbnZRbg711kFJx+cbb9Hq9bb3qFHUF+DI30PuQ6ojR/k5tK7FUoNkEtHBVlmj5vJS5FYVvO4h+qp8xjcddz4HOwgHQdxB7Qljt/Q5ldctLujK2s0+RsTELOXAakeZ4Za9uYRsccxZCvsaxDoQU/KldSEBvhl7dE4bOef4nhqstKf5IiQK/KczhHN/z2dDm4FnDygIsWf4oAsPei8O6ffKst0M5lN/BEi22oByryt66Ukz8ixvBRjnWeCL8ZQLB0s956zJEMI5BmtTQmVdiC4i5y0ZlRpncGYNKSIoGwpfvVko6QkrhpyA4dzH9xr0x6CLstkjeXNBZhxkOng7EqIC/98GbK/t7ZTGg4QQDOtIGAU/rsQUCUa1Gy643xaK8KMI+idvAklKJl5ilpFckBczvhCiHTM8XSh9VgmYy1CX0pZRNnE2piGlA4LVZ+cmdFYBn7wCfggAyc1dCxuUIK4piGAtASxmOYdOy+T0Jbywj4EHPFrMkvtY/iRNVLtj0yJ4GJNBlR7SFKz84PD98e/HJ2De8f58Vvz1xb7oEUGdaLjuMwWYVwn4KAgk0LVetWNMhlTB9R0MBzYXkYyh/yD8ncBKCa8LHORqwUH5xSomWeVKcwkLoQrbSbXrKAwlIwnNAAmc0MCrtn78lfM6J8r2JGJ06W8IUbtmxl3sIhdSs5+FZO5UhcaA3fNlAcnx37UNM9AG2PyWKylPdDfrHGyMTScPVepT+whiyTS/gX3VQGJr68BGg64vMENPzi2V9uraf/+dUT59633vRFb/t0pXpzVA4ReZWpxIkR27PVMoryv5IuOO6gZxAxRS4XI2PFLMKVBzXXrxIA/ZwICeW7RJ6+fJSStI2LvkxUic+FD+76JHaQBaDPQxhD+bgDnSN4gEd0UZChSvTB5o78z8nFjs5GxmdRlkDsSL2iuWzbBOBtAFtJ0vblRq3xaV8O4kk3Gl1JciWz8r4LHsjzXRjSGbcyoMaPGSxaLSxG7XEhLRVAysaOyjXXD+uwQ7d98taMX/Hqsw0yIRM95JrpqULwhrtmpCEGdGPbSNes/ce7glMGNRtZAsu14zK/H4DOsjFjogYtnYmpKU4KT9aXUEhO7grAWCcgKshb/I6EvcpX2mQ8XWM7qTGbGMFNq7wbVRPr42u5dOeNT5+7hG++vmWtY7o3q80bSQz3ewM/1GFWmiL/fYmL2nP2CmzYouBaavIikas8CWaEyFduRUdw7gKZ24PVObyRmjOdyNh9PZA4cu0c5R67pP8nZnP3N3BqaB2ZcqiIrBR0vL28m0bnIhGcbZvgz/NxrSNLzl5fKC5k25HFol3+pXbG1oJpCpYGxH0Kv4Bs5tDaurg9r7bF7IhgJuI0x2ArZdQ509nIGSr9/0X+m+FMxjwatUvIVvjmbATTGO3hTMGLn24SfM7j+gYb3aB1KRcPj0SqY1m5ac/QbA3Y40HJRxCH3OeAbhC5bdEDMW9SlfE3Keho9DrDRykLMvSJ0yuJqTDO2nnQIV6/rAVbA5sfTdx9OxocHr18PhoNfj14cvz04HQwHBx9eHr8bn75792YwHLw+/uXo7P3p0cEb3wLtQnxvVNejaantJ/Bem4osCQyCLQPy0TROF6a6UE8nVD9HRPrMsiBED9+rUKQ5aCJnogwV9HG+Q9sUvL9BVZh1Zo6ptGJ1FxrkA2gUZkZh5Sg++hvyZGxmNclDQa24epXQh0pY1Hxb/EBp9MOqw5HUacyXpfusv2nFw3W3IbVq93edqjyWs3ne0cToo9dIPpm8NKRpDWdPKxLoONm5JKMha3+dylh0gA6K3HuFpYbHkR1/WFuL6W9ngPtOJbz6bUl7dXqHHLTJSWTj0jEGg1R7sRfVyu11jAPfmVM6qhsKHQPA51UDdAOrAZ5GQwOrYYkIn0gSSTA3/XjhmP3XA5PHucjGK3s3EeZKQiWBG3TJFVxQyFCzqMx3PaDSucZ1C1ozO8DN1H+oUY6Sh23vxte8Iv8dW/J3KxmZdvM5xnON01VKyk6SKyvJIVdMQSNUvCcq92Kx1IZsUTRQu8GFDC+aa2m3WileuLT4hhIEcfGbDARnT4+Ij+3miUlPDalMYcYVRpfXr9/9evRyMBy8ffd+XP11ePB2fHr0tw9HZ+/bt9Sd/dM6IeCs+ng3W6zx6A029W7228GnE497J3v8Ctvq4F4tAjW52FS2LrHHGB0XM5l4XqIT/LAxrMJY+cLTAVL4iZkJK62Jzf2kUuHR9bucUqXvag8ODczYRp3QOVaHFRxfTrR0W5h4B9jYnEXKWgJnh2GrApy7wvbOy+k/mVAF37mpON781FCf2nFs+I3RdF0wBUHF3x2+rOusuuaGL6CB6urvgyNtxRnZWeGn0vlAZD0EvNJPAY00Ky736dHhu9OXR6c1cQ7/fPvurbGSz9VV7QWGChb+O0nCEW8aBW5IUux4xlDewVK7pvXVTUt5TKlFBwx/tcKWghgrEl+7NnH28/HJYDh493Z8cnr8y/Hrox+PXo4/nB2djo/evj/9+2CILcbv3o4PDg+PTjxEsktOXCvPdQlhTWmpiTOr+LY+TNoqjszD8LQpeU3ca8mHviOqCL2XWbfUxDJSRhj08oJdqNxLFAZ0LGQPW5OAgn5jDIvrIUtM6HQyHsli5ZWBI0jhQMEdGk0v4jrPeFD9HcosLGKe4VLNuFcyyuerhk1Ugjg+l/CETY07Qqjiel6UrtXz8GKWWS/v1W33R6P2Qj4PB086fn/a8fuzjt+h2oznQ+PKwSpoTpqBxjO9P9mKDut387hjFbsdv+91/L4ZVBqbeYxL38X/3cP/rbaHQhpgdOYdv225dTyB6lqK+gdwDmrCqGpBar7JzPvximdJXdTr2BeNP3TRq9xMKeXXFzN0nCfKRVRTAjSmKsnHU76Q8dK7vJlSs1iMoZn3e6xmyneVakHmANqUh1gdmWtPsqBaVge4eGLhTxtkLmjEswtK8wL/GoAPKFD21ltSJyQNAtBYlJ22vOit0epUrPV5pT+T0cmWLF9dz4pU1PVaJu3s9+dm8z3Hn3k0B+NIXSVQnHZcZJ4o6OOpKaEKTelgGSpQtAYXRvgGORqwcrMZyLoJYR+HI3W89TbO2eDxJVi9bljU1VxkosEWG0O77Xz7SxljygWPtapyrSh9JW0/BKFJ1dDbdXHtqkAdOtbyd59RTqIR6/e23IBpEyaQRs7nDrx2ztU+KuUsN/GBl8mluhAROkr3gC5imz11cGAx/XvC9/NwoIo8LfIxgtFvbUIwJo7JqZzR62lbOZFHxvDq2YfKeeysPK87fjvjOn4q1p28VwBC6S7egJFE82+f8IS1WIDagBseFQ/zAt2MzSDGi53SkdgzZB80NeJsKq7KzEvU9NzFlPMb3qcVLu2Hpl5d/VlacfTVo3789pd3P6PES/L38dsfB8PBh5PX7w5q/8YmWDAO/3Vy8OHs6KWRjFWafsEtMP232Dvsw+O/MFmm1mIqiZcVeap6YhVDezATYZLEpL1vkx+6WT7OBDcvYV/lFPY7pW4GHjcaRaW1QTJQOGyuKjujnqvcv2vvlP+tGPqeYpeA1664hzKVyNogk42r2EAfhwH6YwPOv5QT+6ZjQu95rnue657nuue57nmue57rD+e5bonPAa176ZFyk5wU3z2X9CfICWBSrRx6g7pt/BKPYxZi7QbrJoaRTAbQdxDF1BeWsOw3Jvv6TSKSzO47A7h+FHkZvMUnqsjL+C2wtVgA/HH7//LsQabv6twqAAbXrZrFpvbJzaDhZg1yJobIspukb+oY4vOwOfivMp9DDCCUQdC3MJMd7wjK/NF4N8oVtcZztXE0XSLHlwTzfQHmVNHt3fQDUw8qgGctYPxboSLOFm4FEGcUrb+CnlbQcJIJuJH03xxk7J6+AEAdhAUeF7NTbWvE3r3E3tFKi5bz+40vWoM4f66zC6vXIZJorKZTMI75Ko6Q3mxFgxykmSoYsdMKObrB3f9Zhhdr03FBIzza2rtBFVqdCJRvJYEueK+IyPX/0F3QuyHEeoCrBqo/+iasyjZ8yy9Smwe50Zv0psjFWryERm28RHL77WHlosjvDikBEj1gBfmRoHAhVLH4HmD2jSKn039V0ZdaUIIvOed5PRMx5U7yJik+34wRT/0LvAlv/HXzdp6KmUje+zPu333awVv1xbjdQg3fXBGGOy+wgKhgMp63Cy04deaw/43KJtDMNZDUCmz8IfmcvsCX6VSADqzj+nxnrkwrym5kuM0aVtw2TnwXJ1/EmKB1fLRIfcH0BwkT8MWpdO/26qzdd4BV+9wk8RsJrc3ByqobdNA90lyUpRxXPi7l7ql5o5Bir65vbIdaPUXPBoqY1l1qjbFtaZEAtfyn4YAny3fTwfPf/t2y7dQ3/Hn47y7jclUgkngcaNrkitoSYptpWYm/bgbHg5NjrMtOZg3qMS1ib7oDu/2zEl/N/jH9Qcu1NLNQqvDbHK1zVDVdvB+931DZRlRfwBPj2dEBM41Y1eoPx97mUFbPKtzi4StzGW2CxE7iyMGRBTNVEjmm8QgVzZH99unT17wx7eNpAc5U57ShMWOnXF/7CbCwtOPaeqPV+KvguhZ5ep92aGpj6jFkyPWv1YOaGHiIdsX21OWQmHR31TZ4HBt60+/sGvfoOELSUTFoPIrGgCRjqiwzlml5CC07PGKPTAxqbTfN19XJH5bbAQ27HyevAw3FHGOhdaAvZIrvsMgyDsvEt9iJBuumZW1YSm1zs3oJWs0m51wfMxnEoXM9Djsro66evH6QpDcno3e8DMyyPMixeqVIaruh/RPXzKnXuh6wslMw7IM/Hht9DZsmCqPeckFRbxabvPZie8QNoH9aQURcmtdNCXw4V1UDHlsKvynBMe/CPcW5pzj3FOeboThahEUm8+VXojUtIuAlNs3khB2czgqa9D9ZuoBN3plwcUr/8HKx9OlejviG5Ah7XJ5Y7aqnRxEiE1JOQi5W52PpdkjDep0OS/JyUOsJmvzF0u1Z6ngGzoJfOivZjPiZrR633Xg9TrGQy3dsc/l6eYK8dGpUU8c50eB4mQ94oSIow9HfJdHV745AuYv63ZHV73Y/HK9hug9myZ3p/2Dp82LBkwDGwVSNNVfhPgf3pjwmspa/FskMWKftajGQZRCjnqGeCeFQc92bHNovZhjPSV3IbltM13A/Qx8wh81NIPImnU+wk6V5/XsbgoWj+F/Ry3KXNfQro4Zxq3bVdv77l+xuX7J32ctseVr4yGDrRRsyLNtTbYdF2TLIioRsPaRKv3/+vqHnz+LKN3SFht141vew71/v+9f7/vX+Tl7vJiveJgCn1uiLiBplyzE8KVIzOIqtltlsDQX78z3R3mfNNrp/b+/f22+OZbVQG8NLvAkRKuKcgqPu6EZ9yOK38K7F8veOUNADDAuuNbq/Yt/QFWudTtuNP1RpB2+Bnyw3ASMl7kir+QqZhGpRDyx1fpooNB1gUj0HD89wLeVV9rJqJnlnazmQERWYMPKGOoxVEU1jnonVywzLds5Caz9m0/Dxs6f77jIhgWjrzuEcQwPOezH8dimSTmSarnSrIq4IYq1vz7vKjhnHCBk7YlnCFOx9t+t2Ve5zc7ersqtLKjpP/TiJAAoCmMhbOv7rAMKNcxfT6w5MLuVqAms1z9oa+q7Q620Re/J0lLgF6/p2Eas+B8Qr6lt685q45X3zbvTAfcNYW+fNvmGkPaN/rMBb0/Qedf/Hom6vjVhEumNEPawwz4tbFlsNhgI0HOehcBqIJM+WqZI0Rr9omeYi3nCZvFFREQsKCHOuw6KIcwne74+Anwys/33XjYDtcEkqw8bSKykGBvFdCB5FMsccJye1q7HJVl5hGR8Hr83vzACarTmP08JbqOigIhvQ4J543BOPHsjoV4neMgVZha33iPo/F1H9hNlu4YuBW76PLVLr6GV6KfHKIe9OiVdAg4AnPF7mMtTjCS9d4tqgesEjWzeRBZDBDAzUEAHGFyI39b3+VYhs2eNOuZGyjUm1zfYxODZT2EmrqcB2wuNCuFfnN3DMjcTg+fZotD0qt28WbnySB58/uWgNJagtZsC/S5w11UR7x9k2AYmLKn0IO6A9VdkEC2v47oguplMZgkuuW8YHqqlRRRibE02rIgv7kDEX5LWZXYD7Z10H7tG2C+5X5eDfErCLBOITVSZ/9xl4D+qxi/aKbQjW5hwVZN8AJJMZXBF7cerhkmtBXMPojuX+oQC/LOIk0CFPEpGNd//7vz20Fj3M6TXb6N1dtbbatDyVgV1WEKrFQiWB0fWZVV6p7EJk2r/ADykmMf0V21R8uRlhi/1qrf4FNSw0lpoXH5NIhDHPyD3iXFynKsv1OZtKEUeMJ1Et6wNIJlJoHPZjArkJk1DGEjc/NPkKzcyScj2ZAVm97ceE+AKRXIoYlPAP6G/AGbY9Gu2Odh6SF3oqsiCMudYm+RqTycfknNDst09bC5HzLZOW7Xzr40b51yoN9qpDslBfeT7DfmMYYIzrwGjh5Kf6ee9QCZg+531rqGnnpimrjRP2BEAQ4poHiHP1Oy/yv8tSIbiFndHOTjDaC0Z770d7z7f3nm9vb+2PdrZ3n4LriMj5bPB88OTJk+nOLt99PBHTven+s+0nu5zvPwsFn25Hgu8/ebb/NNrbHvHH29H25dVjsfsserzLR9tPn4Sj/WgbnfSTKEbp+rfBVOThHLgKcMaBakc6kHq8WNqNjqBDrGZpoedl8IL1i6kve2f0fvvZ89HO8739rd3d/d1nO//AIlU8FAsraSMJHOgFFMOzuZqKFPNIjjEOZTQcAO5CEIEuFsKQTpFcykwlNMygKvyFGS2zSwmVHAeLZRCrWWB7IgFFajeGaWM0ovAk4llUY2lN/FLDElNDOOSogU73fmzocfC/wLeYs6wSNUq8Q2yru/V0sMDNQKjILbdjE/m6VXnw4Wqy3BFkAkYhgAQljIsSQE4zIHmJomQC9JACy2PMdsTzULIax4llezTaeYwlmlRYwHkTRTDptNtZgOwz2q4T1MjXQw2B/MZcJu21xjy80CU/pmh5U8FzeC0QYZA5W38mqKfyFpf63CpuCDCvNjFs/vCpLWp6o2Fc2a6GCH0o2sKR826m+r4La2MzXmplaPwqgWlYyVXm4yfP5T6GI0t4fCaySzq7Jg9P3xk1YNiJBewgYUUirlMsvsc0faSnW4UYLNaH7/y+rzsHGFwk6go8Sw2YapCARM0uNKqrPtr5ilfdWWf9hJCrSzN1KTGv9KyQEU9CgV6tmQAOxVYPkFoX99TgT08NiIlclYssZ/iJBZbhjJSgx05cS53/6e88HGDnzp37/eQrP+VmTYBSsCTMEnd/X//E95UO/CRTkMXepxJeQBkBDemt0kxNgcxDy9I+5xgajfUseCl1qrS0/o+ti+rU5rRdjpJQ2YqHXe0rd7PZ7zLFfXQSicsk2qKqm1uQ70FNiunqoctohIlMMBVxN5Be8Oi0Sy1stbQEJaz3bPS1KmNFoosUXkNhxexbl67763xqW/qQ8EsuDU63cJhIQrUlUMSIRaoynsl4yYqq81ffD5ZJoQj7M+hqMnimciwWXCKdlLAHwlIbTPB88N8ByJ3BETaqyH8qfxbLFr0EL8o0E5dSFbqUxUhcxfUSo4NkD8QxqMlh0x1UXpVw/YcgKUWQsTBUyT+LBGU3aszZj7GacLKeXYgl0lzYx4VYrtsFrfkr7cEo/lKltZzEAreEi6aKriC054JH4HFa35Eut1Sm0qOZ4dIJnrnF5Od5nnZtYSqI5fyiPfx2iHojxmnZnx7AjPr5o0eRIP1hprcqp9atUC0eTYsk4vgKx/oRT+WjmcgDU9bjEamhAhzs0UPcKQjFY6Nc6XOKH7TIgjNq3+tIP2gb0uLd8rtMzmTCDg9YCK/zFM2M2mz/FymuHlFdcrZURQYH9OVA4AGc86P/uJTiigYPYPBA4VIC8x3AAxdXXJOs81KFnpfTObFTHvGMvXSZIGAFgA0arF9yBr0fDRxKgRoxh0YAq1Betd8+ge7VQVP6oX2av30C/dh1MFXZjGgTTyIiP5NCi4AEH2+6xslC5igz5RmHTObQ3ghKWK6JpXOp51i3a8HjK56JISnOkZdIVSzDJbuUKkZYaKYSB8GDNFPXEoRpmSMDAHWuU0MXU8F9pUgO8AMTsZzJiYxlvsRl1BYGEESAefojHdUMqw15Oy5kLme02nbvN+VHo87SLOeY5LUKjUBbX31UwCEeYs5q35boC9Mih3uhh2whwN9bD1mmYqGHTBeTsoMmADt0DLaBN8NBRDNbE6b2jetwWXDPJiwogSxMRomVmTsArYKyrvi+AyjhGs9U5gtVHbzI1JWm4nhVM3p0csXQ6iGny9aQKpvxxJBSz6hALFitDeNaq1DiVszz5QHTZ5QN/HwljulsNkfiTqwlYlDHgHh2HcOhtQi+s5IhobE0lBxHMUfZsSpsEDycs0hMSRCCwhgY++JafJHDd5Bl/XbSmCd1BGM8z3k4p5MwqttyV6YaepsImleqGhijJVqImmZqlvEFhCSHNRVs8+Uzt0YGM56LK+7J0nqSqevlkIWw1iEDbA1iuZC5oUATVExZrhZnOTg2uh9we/j//p//l71LRXJwPGQHST7PVCrDoWF3NYOfcTeU27i6RoTsQaQWXHppRO1OzJXO4fU0ecQyBcnkqzXNM1XM5qCvOjhmP5qdwtWhScrVdk5jjiaI4VWxk9b2idR7LiRYHCOUeUtKAzOBdOSPrHwp0kzA5Yye2zOdyjgXwNOEKo6FoYBqyswZsVjNzCWeLJkAy3h1daNlwhcyDAAE3orxp3XY8DBTWjPy2IxFfVN4lac8jic8vBgyNMxNeMyTEN8i2LOJ0hURi0QaqyW8yL6FbLmffUCI1ZKZPub8zNAEW2AhnCnYXEJpuaVvJttv5fWRiQYdM9P8UkTVVFhnoLYMfOZKGAfAgq05RYyWQ8s0dYOU+tCLcNM5LyxTWujGFGtG16Ey5U4RDSR4pxvsovPSIibleWN6mMVg0GrQUK0+iACqbguRFZ64RMoOtrXi/kAVPxo1UzlMUKQ6zwSv3R6UBgyVn1W3E/bnk6jx4AD7EhyS8DASWOHIXhErZSOMAFPosrwWMx4u2WsY2VI+LXgWegyRNokafQ+4DnhgGL7nLMz4VQy55iNxTQtA567SbRlP4uA4SNUV3uRMxOISdeAIYUAEU5XJuBBVlK8jJ6N1RcYpaTcHx+wMF4dCFoyOh/xPNfE7FopreNH+qSYsllMRLkPzHnaMgwQ15aHntX6tZjLkMcNVA43DcQxLAJN0DLniXYvA6MvjirB5hyjPzHLu7asCyTwBtRYpAOufRD+H7OTYPDVFovkU+MdUhnh/8oyDVRmeLmTwDo7rDJHnWaLO7dnfOUxRAHgqaeBUhi0GzG6RdkIHkaa6RKFImLSkZtfWwag96z9UIszTZPdStsYHOOJ6PlE8i0wFMAnsLvq9qFixSSb4BZS4tExvNlMs5rlIwiVbiDyDSWtAULHyMAoiQ0//IBQgfrIH0OyhZ0XlfGW1kd8hihVfSbNOD/s+m2VihgwmtHa2VN+qfdiGbMKT6EpG+RzchoC6me2l8MTCc6IptQnu0zMhQOEM/CrYKT0sJUyqGfVcXdn6vUGugqnMdB5AYWUmF0DehHkP8QSzmQdsb0UOyi2m0lwurPrCmMnNk6FTISJWpPRw0bhAUSQ3shnVc6shMYnY9XNDL5F1nEE5kGGa4HymXOdATROz1pTnc92Yyjh2Q7kHTN5SQgujP9DhFyhhAIykf3oRFaGwo6Hv0WTJ5vwShi1SQFcYAsdjhGOazKLEnDJgzwVUJ4FCGbAQnMhdI53DhGtUPuQ8Vp51HIdiIjJwe1mkPAedlpmSOiDSnu4gshmCZ0PsgZoAlw2CBnEtJQklAnn2t9fmnRDJTCYNaTysiKCHQprZDTPvtMWRre6kPjx7cJby7GLI3mcyUUMm8nDrIYrfHFRECRDVgJ57z5TvUWBympYcLW4e4ROW2raosJvWCU/1HO1XqcxMaDnoKGTjXfHJx+ZhcQCHVwChBDiPFMBAGB5ZEzbknlB9ji1q3LG9chB7us7ifMNs9Yecocgu/CxnZYVmEKBsVY4e82WF7+38iThhIALuXNDYieiHmiMECLoDMo69t9CqSUwDK4PTYtH5i2ANSOeIkg3RNokYj6IAUIM4pjqm20E9Cov6tMZDkxPPvxD5XEVDGBpMUEPDyF8qGVpNsLCcRmFNn01TJ0lWjZ3Abo27CSy2+yWBGQ1xZuQXl1ZP9ETliciDqfA5Ub/Aj+YpQg1tHMuZQLcIISKa8/iEXuCztwZ7cIUqYeRlYZSKAfx/YBMyBd6q04zrPCtCWFRdFaV9+UbKsWm5qGK7hFcE57IvmiH1Rgak6Q93mrORwc1/CcyGYXM19KjfAiKTyuijkVS4B4lgLWQc+SaA3w3zj+KjVSpggahQJQnJQaAg1DJXxPbkpCAn6Q+HtnVyYCSQF7ZqQKSxg7lSF936gUnGk3BecXw/vX9/wrCLecFBI06zkdkDVShdeiNsFyxkguUDSXVFDz0KUmKaCT2vks6Bu1+nuHQK/Ju4FGartD+0F6eqez9k3K8gt7TgxOsNN8bC+kW1py7m3qpqPDx+fRTgKOpHSeNmcjbzSpeHpaQ6V1e11aKxQZtNt1Fky8nG5hn3lUwic1otzaaxftrOOJKxTnZuvVpZAJoUYQZv3AQHrMYignyNh9MusplheqJSXKhL7ofIEZ0K5I+GjHgvZngvo7nhmeSopsouyeZdIb010ACBDzIx69DT0+6sYQkas1NqzAyXSQSTy1iB91r9/SMTjNGRrTjbG+zFGXmLlo9cacmAetOfgO0/zN3xUUpUsZotETVdxtOwDZyVd34mQOeazkFxhFM2VoHL94pNWmo8QnjHUfct0UOE5+xCCJAI6aS5xvxrAioz8imIWOJSEgOGFE9EFitqoN0itn/17g+KXKG2mMfxEkXPbCET0jNNgPXvYsBRhPNBrLYEcz4+BREy8JGcIs3P7V5rCrmEyQVSWa4NJwPeM2Eo0pyR8ZQ9+FVMTobs4JfjVyWbizcIo2oCLSOxQmlAsTfBmYxEJZDDe7xQCVxb9ld+yc+ww9ClhENz69QFSPUqIVkDBEwCDLh3xMsgnEMQJer7L5qSdDmWh4ucyywKIIy+Tn4XPBJAPKltc15YNpkR8ZzENWiTDYXJpL4gmxEt2XfraC+gTZws3XGR+BmLkX2qkdvnCxGAaRE2mMmJkSHDC1si1XL+nRqtEuInpinhvmVwqNKj3awhcyUw0BwUx+qKMKNaMOIfdWpPXZ0nI+6WlC3NMcymySxuN2WsL7BU8J3AgCJHV7OKpr3CK1UkYIXxYNxEgLSLWYsId4H6ms0qjw91XWBHGuCw5JHMRJjHS7L0AW0u9a0ln/vg4NezITv4vQCL8o+HJxQSpYrciuHkdlxH2syf7cBqSSjXAR7hgqdOfGoOIqr2LMdaTNx9T1UWigD0Qh0qPsTnAgVUeIVQQDg4Oa4vlZy3AkNY20OZGCdiqwyjZCzsgNhpKdIWOjXnjUNKYRXiPF5qaZwFSV7wENcyRUXl/VWKfXhh00wqRAGwHVgcQ3rP0JPEYFYX5BtgcGTKhmU6U5dd9n78xICTmcbqqiGXls5THjM/nUKj/bVYdJlGj+w3X0dTYKRbG+/pA+x7F1TgG4A01I1OeSZ8TECBGYAvrfsBtKp1pLBQ7tvXGVhzPpy+1kN2fGKeBmO+NIrOtuRnvICrK08B915e0tjIHNvvYdm6prCuu3/8oNmM/K6MSLeBt8KblfOQ+1b191alp++y2rhDla3ZRMQKFFZkj181Q6biWBXe8uGG0zYN6Pk1aqnMct0rx+4WB+ziXaZk7djAA+rc75bRhisxOE6f2ghbK1WDP5oyxPVBlq7AVcvQgwHBvkXZJ41CMHX1qg2ZRlMl/u7IHDIhSbe0JmPackM/689kypc4aA37xDX6EncYa8nK7rQxXukijilVEMU1o+yXK1L4lksrNbLAUoKlEBIkQDLUhEngma6Mzsa6AFh/8VVeBhTkYgx4cSyAKyA+obL+GyYdHwfji4RfwWjRIMfGp4B6bOZ6YPpUDk9Br314xyq5Jd9QW+gjKq6CLuH+hL67zierZwFArNvz75VBq7Vh/NZrt+1R6ov40n12jg94FW17KPg2uErXSLN574aG0YKyZMi3g6hD3OfZ317LHJqC8UCLBYfYWFBKFjLOA5mwSGowz2QYAH8psiU9PUZPAf/EOwoeQmQ8qOu3yHSV8UvheeDBv64UcJFHC2RC5h0ge0WKtBAZ5pfb5cIHlRukSGWsZoXJfEEh/o7iivEJMJtY1v09rgEgIdh6L85o+1GpJ3zk7oGgL/ksUdpvLrUWt6oRy5WKK9FJoOOHbnLUP2gSsQGkpZPPHMqbg4wgmrKdbRJQE9OijaxGxCxHRDpmFX5Npt5mLJAqkiE7Pnxz0lgBsjblFnwcTrJqj3XhHpQeBCRRs/1R2J7F9CJDc4ehuD4fEJ4LKN7i4Lglz+SdDNXpyJQEkY7ErA+ZjMAHdYpJG1QWycQkgdDmORgavt0aHMFbik9UWeS8OoqVFifw1nlJe2DvcFmu9cn1FQJu7VJGBY/N+h0eprJFLeqatC6o+OathkPVUuWAYUIbkA1fZ8C1SaIZtoYzvBQZZheACiO5AaM1ogjMTGT1sHgcmSvIgedfDu4vcVzKp65XasRevj1D0pM1HvdyAo+W27cgWm61LFICcHD5DQWkDpmq7IpnwH+gNAKot4pbwwCbWIUXyCw4q6xyCkyWjEQYI7uukLHeABSasK0Wi2pOWl+ZiozU2dUGoctEXdcgvlpfYLeCtjesf1Ffr+NiWKHHKjUXiN20dO2quWRyCesE94rKV8IIGahceTRBQFpdjnW5Ilcb45teP/xub5WD0nuCrq8NBzb6tnweL82v5K6BbiVLx0uF8qmjMGVtVwM0E8UXAe9Sph3oZRLOM5UAMwoeUkZDAa4UGJUcC3hyBTyg9gTZAg7degGjKxIavtFVbmiVgzUfbVgEDo/leCqw+hSfOKAxYZbgp9MpUQjmM66Peal0RPoNfuv8yvK7tAjwkmeZWIhI1tznqbqL1PNZ4XWuOYFvP8I3TN1gQhUgxM+cbRmM0FgP2OIJX4z7HuJoBvqy1Zh9VEfCuiEEJiGE0yKJ0CkbsdDBP8vmV78YURugU2hYWPmDXAADoRKbUITEI4IYJMHH7C3WagCxGF0SyakoPeaddo7GFfNe4EGAh6OFmZoyjNNkFAR5acgFuqtEzsHWL3ESeWn8maAwEefBNLTI8QmnzrBIq4CoBBQghDVw1+5tl12ypEQ13t5O9K9C5dzoZqmeLxnYDUQ7nbgrG0/HksH+4azbEnBiecjEUKQrZEjg2smXLpZ4s3PFbA8RNei3E3lggwKc0VE1R0dE/tle/W6MZhlHZLWWzpg8T6cyE1fwlhotqSIaU0nQpA0EzpbZajx4tRJx5TGf2eE87IVvviH5zsHVsv5+5E5kvuLl5zOAGN6/0r7268ErlvLwwoQQ14RYqKTc8WgenwRks3GnMbkj4EIPaZphJU9jxb+rucwFeVEb3TZpsOIlfIUHwToMljvxO0WWO3Vnzqyhr4qLAK0dHBK4XxBK4JtgyZjRXUAypNkqpxlzK9JiEssQnJppQgIeDsHMECY5mmIiCbNlmhMWAMG1apJuTsR7ssZVv41/m+FTwbuO8gXSY+DFS9VHibM1uxyGLR4gDhnbXJWR4IpPO/cDUFq4Sl6Lb0P6k3Bu6DLhBmvRjepSZBkYU9p7IoXDSjxFB1oTSQM44GIrugeZy4DlKAFxUVdJuFlOsRZLHDfd20ERoEUU1B7kfNYdwvMjtmHv+cy683eZCAh6vUagpi3l+Gph9wzzhcVwNWtiq2XGSBSu2Z7qDjB+kbzhXCbIu7dtUAXLC6/N3OA8jO8oOYtgaHuOGbaq/Gi0yWUqsiiTPns+2KVj0sdWBAYzecB4VkWC5Ma4MKDPpjSPUKoUOsDVbJwmnCQiciT5wkNqUdVrXITMxI5JCMlAGcFWXiabIbX8ATkY+wcMdXb2jpUmyIYXXzle4LpLtdyZMJSvOXcl3k2ECcijUDgnko3gUTmO2tV2TvcSovZMTJyZARkaY0O2r7odRzNug2fBPgOT4ooIfMhdaI/HtsO1YJJCBosPyLHNwAkNGVUiO9GMMnRD0krXXWmP0BpGbdR4537fWf/j5vDoh2wAje7BXIPnhnMKBHLM/4cojbaDrgAeRBT5exVqA8yU9ViHBAbYuXqlUUowLh9DZoMtIcrHjICmaWtnqCEVGB/XhjgkutIgYoe6xwAYBMySONUxwlWSu61ds0pKrhAvFeSv8CXwwN/tcEh+zh5jpU3hC6Oy/nPOlvEAZmSjIddWeVlZa4D1QGe0Tg8ZMyQogyKzlxK4ZFi0AEGCRQut7Q7PF8yOPh+TtlEyVgo1u8YhNRNpkRvVG/HmqMEdgpeqSZmqh+zXn94dn1mPXGPUJMfWXi6p9RWgb/0VGMbmMh2CZ1WsQrMEMsdPwLXUTE6iZ5GrRC1AutdLjSFUYNJAn5tAF9mUhzYE37MAbMZMs/ZaIKuqLj2whgzS6oqM3qRSHVJ3jQXfh9SwPV411QncwEtSTNU8bymyEb3gSebRKi6M6EriD+zXylSYDQr+GdiIyA4HcRzQnJ+RgSsnHhubZMJPrPskOu1hJd5yGh/VtUjRgBp4G1G4ImkRTfTT0Do3WLfKtk9xiUEBYVA32tYwDWc1rsYTyhDgRs9TpH2MRQPQWd7aJtFcX6oLjFqANDhpgO191kka7vjEjIiCnmPnL+X66hmDuAz0ayGyC8N7haZSCGmBtHYTEL6AklovShUQREIbB3pyrjGXhJIu6PpBe3UcpebNeJHR6bb6slBlmaj0S0Xms02DfqW2i7oXxtVcSU8vJCZ1LC1d9a16QCZhXESkm6J2AAL7b6OVQw26cWFCMnix48FfUsKD6BmhIyPpDChO1TwtS1UYLlCU19Dgl0mPS28DReDWcgPUIrBozPYaft6x8w2NviMToOAqSR4wUWjHq2x76IuEEJBJWuRVXofGQslHBgffWpO24KwWxmEfVdweZ+Uah8YvTi0WMs9FFNjsXizmM4JzLPgFeJuWLghBl0hgAjYhmihTCwlbcD3FMRRsJhNH2lwS64562RngQm7iEybkAlDy2A0//rzT09K4GlRX1l6ypssByGlXc5EhcZnKhPSllHmAYgu1vkLkcFZsIFIFz/vde9DXY+J69JnYfCMO/f/tXVtz3MZy/isovkSuAlaxkj9AL2WZx6S04VJyJW/YxXCJQywA40JqVaX/fqpvMz3ADEg6SvKQ8+KyuIO5T09P99dft+ijxJnnFwy/l9BKczBN1g/GdNZmI6jrEOggbsLgVzCF30lvaRaKeQ8FLUgeFbKUw6UlfAwKVrCKROSs2WDotegeJhSow0CKeQw6T0FUQ/6AcWNcCo7sgfj3EB50nxPJwjQcBY347vE0b2elQlTCjj1XAG18/LBljdzaBL0h4/qqtkKhXtGXKy9R2zU7M8FuWl8NIbqhGe9NrZtcxR/PAoAA5Tq3I/InjxkHTE+t8DblRzUApPhN7TX57FyqaSJxL683HDJAFGx/CHDchG6iT55RQR2mJ1Me7tGTwZva7nMUvjwIuNX7+6YqWENQaP9J5BlWvaLPIi9iMZLrWULWFppi/Wdm0wnOt2vtR8xhrQUNcfU8txc4HcNYDUSc4VlWwlskvBmiISYfpkEVStGSwA6aLxF+orrcEWTFWQ/Igxd847IrjsQt2FTDwqhP3uB0W9dfn04E5U9wrEHwkU+RF0UugJAj7Ko5yLs1nd754N9TMb+gAK6vf+EJBfffKbm8kOeaoCHQV15Qdo2ZcQ+aWezDRD+T6oK+MGoIOjg1Ah7zQ7nPGDGSuWsq4DGpmif2EQjARNbOfSbqBu8jAEzklekU2hyG/mWzRmNAUsLbZebZisYp+sZ71ercKYmQcGwVhFw6EwpeHKOm/4mBClxjykFRkBVLBeJzI7y1MRqOZqBnsXFXfk3y4hHmpDeWguex3WcRe8olzpGbM+RJobhJD5svzgJamseyL1UkYl43x5zDhZR1lFYfrRJlQNO4uGi2QLnE/mO17FAe5/nDzfu3l5ve7CFYojZw4hDIzZQ8fZpcQxvJH+cfidUuVbY3YXnYPwB6Pm+RSGGCTEEqliIr6l56gn2bA/epYHJR98nGFpwcElvdsG9fVt3tvl2org0pMucOXpzliK+dyjhcKTcvHHdqTGdL7pDpDdmAEDBxaDPyGGULAdkfNuJWsqHgBMlCeYGngayrDCjzAnLg+VmXZG2jrt3yMvPCSj/iSAHogOUdmLZcmLscbh+wIBHJEJFb6St8se39XYZkmbx9Qm8Dh40T4OCl+iJ5s/54+VNSlfUDG2bIttnen3o0uTRd8lh2A/irWrqhkDupM5l0Y37p3bznPrrQGPsYw0YRcWlPTqMBfG4X8HDZ0GD28Qb1WVNNEtiwMxlryuCuUj4FNCyTc8oUcn5RcdjnoS288Y6kDxovzG4kt5cNZxI3G1vKo0sYQzputcSQFwyuzeVGZOaU7MRiXWcSCDWIMtiQO3MUBk4iiVAsgCla33y+SJOr849voQxuNzQzevdLmpyvr6ZyrG2nhWCTfzQDXJv8E8vcfRu1HF+vNwkYdeA5TUgypuCCH+SRMOFzOCeV4/xSjtvE9UPVvaTJ1BEdcls0CmTBv4b/6ItSjDWxikN9T7XBACyN7cQyC9AvvEBYExPF5JmTv5EjTPxzfIbFeq+/TXZmeDKGQwcnhmAcrPZYhuJw9nXIDkaAvQWxo72EHEeGvWNxFLrPPWlxxp6Bl8wCascSjsh3bDdAAIauwaJzSXpcfTqnJSCKBR0YGhf5vkY2qZ1vAnrUkvQPhJVXTTAQz9KAepXe5XtSavAza4hHQyjspj0qPEMMJk2b6hnO1GsgWMzQveozpyp6GwkYUdS0OHckfe3QR8DEASSRvI/kNAxZeeJTy81S4BUZMr1uMXoxLO8u4QfpfZP8vQGw8vx7HkNgKthJSaHdkc9WO4A7hHSowjlRZ/0GsxtYb85eRDXLkFr0TxMgQ2hndIgCG52m/cRVCV07+Hd5TELd/pe0V5BeoW36IftzzOthPGZ8kwYVx/c1blpdHi9j85Vjk1kvsrJA5JHmzK0Lj66LhCfBm4Ke31/HqgIqbyCkdsqndTDg8f5QDihFD+QMIcqM1BoyFOdnqimOxZU04QSKIOU36NGU31O/VkdrEmhBDOR8RNuyNRXSbkXeQ6nzpaZKn/T9Aehbv3mXOho4BK0RF7fCe7MNOK/Ig+a5AUA8h0zh6mMyM0uXSeCUffLUgcmdnqM375LdCDpVn5JvwKpuqkcS++ycAKHR7zD5Dvkhtd8D2Xtw/Dzw3HWJiYZBUeB8Lmgz2o9dH4pW38hPvjqfW/a/uL2JL38OadpIue/p2Z+jGYNhLsiOB2HRDOWGgrBt5WSIC4VuTfSXpOLroLVHAZTxAB0iG15V+7wyU+OCJFec+bK4IUI9ejQbEtiQU7Ysvx28vHPstzmbJLWZTOzY33tBB/wV1TtW+AbJ9+AjqTCACYJULEkS9xvmH2hlQlOJIHkwi7WM0o128hn3Eq8j9c6nDMPHBOyzDHFVtV04iXahbEEB99323zRVHwfmCJUKSqlvpmsSc0CX6p0R1VxOjuNCZTwhHXdtyxHYChyPY3kI4Ka5toAKF+LVdQdXuTHXn262qjfpRFgu9IvHDCBFelBT3aswEWyABBli+WAsdUGhEXzl2W7qSsE1VmUC3ZnvFvkGfWiVJAOe2a37EXC8fTV2bSg94DXOsjC0IbuNwKT89ZaFZqls55UimUw/HlEMkFw3nY3NkIQ1p+xlsdX9fdMNWYUmT78H2lvJ3jNAmctLUjo0Jfuj7cyMqf/kovwnF+X/Wy5KTMgSUkpgG5khewJct1hqZpCYXz5sUvA5swo0dKYuxOhAHEhsm+dX9J9jjm+9su7B7zexDANuPetMXsCWDb2fENhuCzCf8knzjCjNX6nf8uhH/upAvZfw5iB3EY+BwEuQaJmd4K9qg8jRIxgfzJ+jiiTHvEM8BeIW4Xaph0TmX9S/N804EB5/j4dxP8LtaY9x3v/8c+B2Pt/+/PM7xASA0nvf+JwsxLMJRhwCwpHEeGyq8WgkkwVZNAQSxfGwAu0LadEXzZbcE8pkXuUneDPTppA98qgdBkPeHYANUzH67A4BoxrYoyVCFk+6RFiAC6aum7EmfFcPAEmJkxowopJeEwCN4Tbvy79Df2iCz4hBNKie65Owa1xcjIxkiq7z7N9uvtHiHXDJrF1CKLKwtnmH3M0ghZRHjM7RU3XKMAC80JmkoE3iHzhbznfRPNWgEuAeop0ohYlE/u4OXxeyEOzWZJb+GJqSU4u5PcRnCGPzmtYpUQinfMR3kWUEv/i43b5fJ3nRtKKeLBIe2bBF1cjF9fnN+u128+vbi98vr21dKWxYfkzaYEp/QdB+E6SJuWqaB6D9Pt9+FFIhD6XoUEqo7RzNkOOO1B5wS/iOXgcHH1z2tUspV+fc6+4Ru/OJwTxt81sBBDOmXdw3lZ6026utJdVh+e3+ucPcRQzToQF/2no7+ywENAtGTEEZpacopJeStYjyRVi/tz61GSJOVDbMsnDRjovErgPJMgg4o6a86RKS9ojhV+M5BZth7bhvzOqwSs6P+TfYZbsTL8xPKtTTetKZwx/hIs6EFHhJagOTM0jZ3ayYVNEDJJPnbiMRVfQ2x5s2Ls+Uycpey9xXcrcD730qRPK0Bf4O5o8OxisInJNQJqMzKK8fgkCDWysEEi6j4tac2GibdqxyPNzP3rFdA+I6G74GJOoN/rYavg7+5GHeECNeQnj8z+fwyewcXiWKVnGiU75FAUGyIiwm8N2zbyGBpoGOl0cTJtO6XW/02mB52lf0ib7CVSJjUbEYBiQkIenZEORvvm1aYbmmhXlze3Xxky/GWGnMnVrEDCewsTMCIARl54WNT7diisuS6bcee3TnCCthWTuFR59kAlIwX0UWvp/lPdTcMRD10DQF3NN98oYi53bNkCa/lPUB/wd1psA5lc6IWiyptuJBoBILi4AUinVyYBIV+mmRBzdQ7krKlfVLgkLBhokmzIBpSLhX8rEomzQB2dQoY4klmnwFJd1DCDSyvfhdiNaOxnACP/A/lfuypTAjQjvTL/BOt3hq6M2T2RGDN2DAy2G1wE/xGZVtPDi2FpXyA5/cPCO/Q9rGCe+bV/tKdSSEzPuR9a+KvKxCGXHgzz9iLBEAr8zXqyoNYlxiX+lnt1t9nwZoZmCCZhZnHxIigUFTyLO5ZkajqU/VSZU2Aw2s+igLwVZcotOp0f3jGmV8IbdZeN/bKFOImUz1UJbqXyF1Sii1E1xKUgE6za2vl9t0kIBwnau2qUJq2Ab+zAxxg9fKZFZtfa7/i4dHkalO2dr1bNupnTaj5zPkfnK/osR8bZWrGKfcuV652eaQ2fF6x+20dIWHjtDYs9+Dvp5TzCM7TKrzWUr8mgBThOdJWnOSNborp3sko+Ah96WgU+mfsy3kCkY35jltGlVlZMZClWJ3lhd33uXn6o+feBVyx4XYEuUfXcgDxz5H/Fgc/vrNphtawQcB/QOD5z2fjAoi1COYnjRb8QvvqfkBe21Drztrr67dBH1wG+MC4f7a/LglmUt3+Qn0v9fWq9Y+oCC7H1/Va6vszJ2R9IvC+NF+a5nviU19043v+ZymrazYfBWYmGeq1UrZsfkzhI/+D7SzcxA1gjTIhMJRwFB4x8TBKNcSdd0dmz9X9HXQPwy1wouu7Buy5ENrmjpgn3fIBQbVituYuyBhNTbYtJu0GJX5tyTsxRuMKevNQrVIl844JXTtYv34PrwbA3P+62dQnbw8uH+Y3c3tmgdiVXM7osn10t+NEfWM67ZIkIlDyQK/bOwovdXGLoBouf1885Gi47Gj96ZqE8rVgCAxsgh/PL9lZj3murEVrsLR979DhRIFeQi57rDdGTEyQ1EzIsYMn8S94dAnoXB/asaqAPYKdt0TFxrCSL2njotQ8O9iwVH4bKxd2Be1LY9jlbvEvQp4QTSDu/EgdPhAE9MrKEvvsCyEmd6XvfJBCqkG2NnClGP3Kuc2v9hVSAzERLKruuPHZGpZYiw4Hbe1Tb3Oms9lsUnuTMHaW3KAGN6echAwesVyKLNvrafYGgWo8vmkwZluIGXNvmzLsFiyEDgpzSgGH+KVkT/AMPyOg2Ger5QpphjYoT/mCQvJIktHolKC22+/LxD/2y8lpFBZqty+k2WZML1F4tqJb9lbbRszjyYmm2xbrE1oFSaLFvekZHJ/TfDNAwmo8nAnIG9Ucm1ysMCicRFSuiSWLPInRbOHGTwRf5Ama4gmg5JfSkYbI1gXsy0Fk5cu5FAIJh5xBN+U9ZJDLyiL0ynxOikg8Qzwg8Hb15VVKHEKWjcutp0CDIn1R6Uq2Zl8D/6cumxbM0gygjIwo9v15XXybvWvZC+G+bcMm4yj7hFeqpl+ZvQzhJsG0Y64QYm61ZO5GHY7TblgJU0kh7bs5uQWs2VPkjzs780xD0lG+mFanAxPNrV7FmO22lJBCMehQa/nvFbEwhM0FSGOdZofwuw7sK9i2umQs60eurxCEhoqOiVqwg+RCIkoc/TTfgq2wNBNsv8K0gxd+Sg9mbfKPwBI1hiVYMTlSKZEuddxONQrtLvQv7E4P1gYhCNg6TM3CyEwq4SMPJhTBhHDxtbpsmpBY6sESFKSjGYyKwlYAxraiuCMTRiBS5NKP7N+0VSFilWZN0xGFATYqLR0dGlxAktZW3T9cZLjYOPkGwRPy9jpRMWWO9Wj6uTiAkdIkWnDs8GyTPM5Z/yU4YJliHfnjpGw9h1+PJq6EKsJbSB9zMmpCbCK7fYqJXa+ecfAkn0mBHjxXmh+vdmIGcCDtydwOwDFKuwyMLoPpxTD1axXG0wWeTVZi6AH5tqxeb5dPZmqytA2/1a+Qt8Mgr0txUPvOicOZ9gFNr8EBgRM1wE6ggnW+nsIuQ0sAeaQ3uKvSgXy+O/4bGMCNc4UpwkIPGQWFMq4ULavTAg746XMS9ZQaCLRqPkoK4dmGghIOEANBq/yTdd8PQmgFYk98m5XAiHLKbldb95+vthMTbsBlVkcSagIIp4DHBaHucK3YMZXvglEWtiXs3Js+UbrLY8qlCYmdLQCxYOkDJAFS7zfQmoHobtDM82yJZMbCrj+tINSOcKrKCH4YAlju7FOruAw3Td4H4xFOTBP9EPAhcZCm4FyCeKyEd+BNfoT7IgiwjncMNSfU7TZXtlY/dmrh+NDbRyO1S4sCDyMcQbqRlPorGxkkNeDYwKs1BulogvlngFdgVUpYALCOgX8Uqi50XMewnKPkOEPBg7+YzKmPtoHZt8HwCTb7dVbQEBoEM1EE9A/QURznyafa2B16wEIC4KZXJOaHA2qBNjYVMr76yqdz8b20AFNa7B/bpBUpakh8tZ2D3RU0EEojsaVlZFJ3X4s/KRbARzKwMwSXBAgt1yjAiVgh6wLfx7a8i+9N30TB9F3Gw8x78AX8GJCU02BbDo2I4ViPySSQ0I3k78xE3KkfQWkdRDmatcEApYK8o6GAwjQf5rFrNTnRZEmpigHfmsRIN9llcOv2eYCk5FTUwj3ymNg/M/cd7GTcN2cBU++E3vUUA4S+o1144v8CEFtbWWSKq8PoyTXgfEHJAXDztHJTDMBBe3j21Kk0m+7E0OoT+yHYlIywygETmPZhuAlRNnIkyAxCsxE1iRbchr50Sve0iLKDJ+zjHMP7VE2LuWknaM2D00Q6Sjmaa0LjPeTfFrcHZ2WkbqCzTEqLo7XLzRu7nrz7wkIuXKQfGR2tApCB8omB1viBgxdkrzcRC92fcU7FZNa8juTo3Tsjgqb3raa8XLRBMdUr8i5rRGe1P+2yk/g6EdsF5wq4jYLPSOICIT0Qvx/KE9caNoMjOuzsILhvmmvHGqFZqGjoKIW2cIawovWZQdnt6WUtykeZRMa8WHTSQuhkA+dObi+yPtrhhMmPkKjGbOecmCCyruge0B+c1wPuJ8B1lnlJ5eJF7meEKqL7bNxTrfyrAvC8yk4uaLCcQR3DGjrU0rZ17zkvggvD1KmYrAt/ey4ccP69F+IlU2oZu7E2NX9EAw0XZ9vbte/nWd3kEUSYLv6sk6eyuJgBkfchdoy2msJ0La57C2/WgERlgWzgiPBOzBGA7WQHgrXGNh+0kdudKqTodEBUviSvYGtEl0zKLXC8b4f/aD970T+mHE6vpA2xYkx6bgzCjaVRIGpMlhIMhEm8gTqZsy2ya9WFlbkySM2XFTmPPue6dum7sMZvvGXuVkK/xwEyj9JgkP+lGM7kMGiSIoRVUMQF5QUlLODRuZgatEKphGVyhw/BgOgYaR6YuyMTpDSVqIjDemj6YpyLySEsHvmTf4n6E7Kcox7jCUAEO7bcO/Uj11Pk12JPCypYPV6VEcchfckGS8WDulb5kmqEi2eLa6EM5WwbPtawB6+KQyEm6LvTmHdfNM1V4shCvFsGb9KMgV/iXzOxtX/ATFfpAfC0xd6gP9Ymr5YB340a9+kndeS+AVY+iwhnOLn85kxPaBLqAMr0LljfflMrx5AX4KrQVRhzdYZrXeRHRCuUmEIFHLAuwA/X7DmZzfGS8kFX7Yf/gfpB6ctxQbm6bAiJ1EjdvkkvFFLTfM2/jdoCFWTgDZ08MoYjIL3vLUXEjU3wZTIB3UFs/uLnd3cc0ctR2R/mdijVU7TtsrrSZA2cLJji1YIny2pYbf0Ay4MSmzSocDyZRXz5QBl7lXgZlGhtu5G4DfdocuPZIhwSU/d/beM/TWdSzPgwltssFoumje0bBmV8EHKOTwciSSl/EX4OMSZld8COskHSZngyHULjktzeWAxBQ3wXBBYklLAcka6dGrmIRF3c/5hlhNcUg76rMhyhWZlXZivYSi9vWYff06+yGAS/GCav53B+1RbCC7I4H5uDcdG/HJu4BLr9R2fKwhVz7qmCUHTvjAtE/FAsCn/vmuGoVIMirxHUMVlna01+UNSwFwykI0gDOU3fElyq5zQN5S1+Zl+TeiUpT4ojd50eZbHoFPWAMmPIPZRUMw64LltwiOvao9Zo8+RzqDKx5oQIeKtaSNEzOj5RyuAHj82W6G6QHZ9ukc6TM23nDRTOdV3J+DGxpuyKSCDntdvuYip3/JOtlgXGxexxBqlUoR4dTNLlBijm4dyZgwEUyDwU4W90uJHYNoKYrISkiiGMrM/HYsU8i+0V/VDeSS4ZA68dWS6wp3NxzF03qrm5HsJbeJcBwd4+8f59np2yF8aZSH7+HkWLgw6FY+o3WD9CIy5veXgItMDhSsjfKEDcBnE5Y+DYSeKc6rMtRPiX3ripNXKo6JOSyxrOFkyhSKUM7CTjb7jySuSHK8eGEvOo0G7m+MSiroQmXZGFfUud4lYPFvKkYEZRu6JEBP/zyf30HA9bSCUrlpDQK7yIFL4I8QBBbQuTqrGy2aNCWB9NZ3+ewLU7Y95hVPgkRTFYKlcN/1J2WvQS02TMfMYtlXOaS/m253jhp3TyPMO8QS4CvzHfkRhQ63Tp76z9evMU1aLIy/txrZCaKUIteR13uKj30aPDY07IY3LEuye8B3GR7ecwg2IOUDJpwwaPJNkE4jMOc8Cz7kKeHD8MeoEpsrPbBPEDjlGzQg9RqpybZKoIvnmUQJFQRzXFr6A8Amij7KzkMg4HBIniE2Q4DDfLvKihKEYKElTvirMoxuMNT5TMgid2ZoOkHfyUA8Nhnr7h3+guG+Hs7anPqK+pii4UqHY8ZIEc51OcKjrILtrugyuW7QExjYCXfAbKUa5AmWDeYQljeCbPX5c3paYfrQ+aScp6tHcSAqODNIDbEvg5xxrybFLc4mchsn5ZSb2fnYgiKfLZq0Xk6zQsqWMMxIaI/Rws/HD01J5ZNkSXcvlXx7ny8TeJxVlRFxJdvSyKHRFIP6Rb5r5mkgud1jvSFy5TUiDRgVI69EmtjhfFWOtVHp+yFv/KxkBe8u8SS8owBhOTcY243x4pzGfOpWZnNP4CbBfxm6Db3mXfwsLBCCFQr6X/MDHpcOHF97ww33ZFRkg1uF2BOPPG0XC15ZfkSqcwmvDmSKtHCCwObX1t+2LkmACIWLyX9D1iaXEyeCB0gMwR7sgtyBZ2068pyC4BOzAylNIBSStKtSaqOMk6CDtMrlHibK0ZGJm8LLaBygwG4Tynr3Hv3sGp1CLOSVK7JC0J/nb9tPHpGj2o+RGiSYeW3u1yGYQAy+SsCHHg1i4EfaI7wvIyhXoCdPUYaxERIfs7y1LXWgoYj5BifDAVHjoN+T0tbI0ct4WdjedLJjspZbeFF1+NySP/cpGeRTsvwJeugxFaWDu9M7dnm/fWxlMPgBySZJtAygxEcTKmMM0ubjapI47/zAB4/uESL05wErOwVXBB/xFeQCgdfLeuqASlcUAu3aqh3sDYgjBMmlyVxnhruF+Mi7b7wfAq5OizA91Y7k3iqpdkZQFJO+xHbKhaYOWmwswKlyB6YVzfsMaZC75G975VEdCdeDKnV9yvK8klFe5DKh5ImirMM/aa5slbxF9a/USl0Pe1JQPXtPNes1CVl9H7fPqQdsv2YsrDHHYLVAHY42dMvvmf3GjfJSdsQA5adGzLUxJINPVcCaNv3p88M18VlGTkJG6KYZWdIsRcqJnl5MTQFqWGuIRtjm7sXqWjdkdZCLp2q4Mvi6faYsrSXQlTJWPOxRoOEGzwNnlwrYLSF+0kje+pKJ8aRccUaXznWMNzNA0DqTvG2JDAr+vZLq0bUcsQsuDjtSsQlkY9deVTWfht9hoPbzqiGB2eaWSO0IgqYkrjhFwROolfDfPGoPo+Xaj2AaE19varWXrxfXnVVlQHBgBDXWud/uYjQqzeJ6P5+bJ+pVtFZMqWU7/dckcrrWFeAfIhxNALy3X7L6c1S5iAcDjeN/9cHmnWuAgm2jbrz4l87rV0SADKGayVGdSN4ol/luNUg0SrLE01Jhtcbkt34OvsaNQKx+BoB/+xbtYToiqbFY9bMKvcIRPGeZ0fP0G1J8vN0Wv/9e2IIaE52tekdn6xQ3YiZo2wfZvNPqX/QM4OMJRoxjPdwMpardURNcqnH4DvcNVpuBpxSt2DYyx+KtpGzw14lFQGkJe7Ud5OC23KZT2EeBsvFX9oQV+gPVRNYcgw7xabnXRpb44tV4XdifHxqvS0U0aZhLT164h33J6ZI644jtHBUUcNWwSZeu357eg5z4az/ZsSvPZs9nOZ+WC59aAUMqA+R3+PLFf3DVBtexX+POkKOdruH+XHfOvWZQngz31v71LrvOvDO6NVAX1AFlixppktDKo6bdhaJMvAVuKrW6oeuSIrkok5wUjcNxoi4RhXD1g6tf2Q8zHY508Z9F43fE4tdlCcES268CiOjfrYOTEL/DjxBL0/fs/AD067Zhb89oA" SPEC_TMPFILE="$(mktemp)" trap 'rm -f "$SPEC_TMPFILE"' EXIT echo "$EMBEDDED_SPEC" | base64 --decode | gunzip > "$SPEC_TMPFILE" diff --git a/src/cloudflare/_client.py b/src/cloudflare/_client.py index 86df8d7335f..15b667f9a5e 100644 --- a/src/cloudflare/_client.py +++ b/src/cloudflare/_client.py @@ -40,6 +40,7 @@ from .resources import ( ai, d1, + k2, kv, r2, acm, @@ -110,6 +111,7 @@ custom_pages, dns_firewall, healthchecks, + monetization, realtime_kit, security_txt, abuse_reports, @@ -154,18 +156,17 @@ network_interconnects, vulnerability_scanner, workers_for_platforms, - magic_cloud_networking, origin_ca_certificates, origin_tls_client_auth, certificate_authorities, leaked_credential_checks, magic_network_monitoring, - tenant_custom_nameservers, origin_tls_compliance_modes, origin_post_quantum_encryption, ) from .resources.ai.ai import AIResource, AsyncAIResource from .resources.d1.d1 import D1Resource, AsyncD1Resource + from .resources.k2.k2 import K2Resource, AsyncK2Resource from .resources.kv.kv import KVResource, AsyncKVResource from .resources.r2.r2 import R2Resource, AsyncR2Resource from .resources.acm.acm import ACMResource, AsyncACMResource @@ -236,6 +237,7 @@ from .resources.custom_pages.custom_pages import CustomPagesResource, AsyncCustomPagesResource from .resources.dns_firewall.dns_firewall import DNSFirewallResource, AsyncDNSFirewallResource from .resources.healthchecks.healthchecks import HealthchecksResource, AsyncHealthchecksResource + from .resources.monetization.monetization import MonetizationResource, AsyncMonetizationResource from .resources.realtime_kit.realtime_kit import RealtimeKitResource, AsyncRealtimeKitResource from .resources.security_txt.security_txt import SecurityTXTResource, AsyncSecurityTXTResource from .resources.abuse_reports.abuse_reports import AbuseReportsResource, AsyncAbuseReportsResource @@ -304,10 +306,6 @@ WorkersForPlatformsResource, AsyncWorkersForPlatformsResource, ) - from .resources.magic_cloud_networking.magic_cloud_networking import ( - MagicCloudNetworkingResource, - AsyncMagicCloudNetworkingResource, - ) from .resources.origin_ca_certificates.origin_ca_certificates import ( OriginCACertificatesResource, AsyncOriginCACertificatesResource, @@ -328,10 +326,6 @@ MagicNetworkMonitoringResource, AsyncMagicNetworkMonitoringResource, ) - from .resources.tenant_custom_nameservers.tenant_custom_nameservers import ( - TenantCustomNameserversResource, - AsyncTenantCustomNameserversResource, - ) from .resources.origin_tls_compliance_modes.origin_tls_compliance_modes import ( OriginTLSComplianceModesResource, AsyncOriginTLSComplianceModesResource, @@ -447,6 +441,11 @@ def accounts(self) -> AccountsResource: @cached_property def organizations(self) -> OrganizationsResource: + """ + User API tokens can list and create Organizations, but reading, updating, or deleting an Organization requires a Global API key and your registered email address. The `cloudflare_organization` Terraform resource therefore requires a Global API key for its full lifecycle. + + See [Organizations authentication limitations](https://developers.cloudflare.com/fundamentals/organizations/limitations/#api-authentication) for credential compatibility by operation. Each endpoint’s **Security** section lists its supported authentication methods, with **Accepted Permissions** where applicable. + """ from .resources.organizations import OrganizationsResource return OrganizationsResource(self) @@ -559,12 +558,6 @@ def custom_nameservers(self) -> CustomNameserversResource: return CustomNameserversResource(self) - @cached_property - def tenant_custom_nameservers(self) -> TenantCustomNameserversResource: - from .resources.tenant_custom_nameservers import TenantCustomNameserversResource - - return TenantCustomNameserversResource(self) - @cached_property def dns_firewall(self) -> DNSFirewallResource: from .resources.dns_firewall import DNSFirewallResource @@ -800,10 +793,10 @@ def magic_network_monitoring(self) -> MagicNetworkMonitoringResource: return MagicNetworkMonitoringResource(self) @cached_property - def magic_cloud_networking(self) -> MagicCloudNetworkingResource: - from .resources.magic_cloud_networking import MagicCloudNetworkingResource + def monetization(self) -> MonetizationResource: + from .resources.monetization import MonetizationResource - return MagicCloudNetworkingResource(self) + return MonetizationResource(self) @cached_property def network_interconnects(self) -> NetworkInterconnectsResource: @@ -1371,6 +1364,12 @@ def pipelines(self) -> PipelinesResource: return PipelinesResource(self) + @cached_property + def k2(self) -> K2Resource: + from .resources.k2 import K2Resource + + return K2Resource(self) + @cached_property def schema_validation(self) -> SchemaValidationResource: from .resources.schema_validation import SchemaValidationResource @@ -1659,6 +1658,11 @@ def accounts(self) -> AsyncAccountsResource: @cached_property def organizations(self) -> AsyncOrganizationsResource: + """ + User API tokens can list and create Organizations, but reading, updating, or deleting an Organization requires a Global API key and your registered email address. The `cloudflare_organization` Terraform resource therefore requires a Global API key for its full lifecycle. + + See [Organizations authentication limitations](https://developers.cloudflare.com/fundamentals/organizations/limitations/#api-authentication) for credential compatibility by operation. Each endpoint’s **Security** section lists its supported authentication methods, with **Accepted Permissions** where applicable. + """ from .resources.organizations import AsyncOrganizationsResource return AsyncOrganizationsResource(self) @@ -1771,12 +1775,6 @@ def custom_nameservers(self) -> AsyncCustomNameserversResource: return AsyncCustomNameserversResource(self) - @cached_property - def tenant_custom_nameservers(self) -> AsyncTenantCustomNameserversResource: - from .resources.tenant_custom_nameservers import AsyncTenantCustomNameserversResource - - return AsyncTenantCustomNameserversResource(self) - @cached_property def dns_firewall(self) -> AsyncDNSFirewallResource: from .resources.dns_firewall import AsyncDNSFirewallResource @@ -2012,10 +2010,10 @@ def magic_network_monitoring(self) -> AsyncMagicNetworkMonitoringResource: return AsyncMagicNetworkMonitoringResource(self) @cached_property - def magic_cloud_networking(self) -> AsyncMagicCloudNetworkingResource: - from .resources.magic_cloud_networking import AsyncMagicCloudNetworkingResource + def monetization(self) -> AsyncMonetizationResource: + from .resources.monetization import AsyncMonetizationResource - return AsyncMagicCloudNetworkingResource(self) + return AsyncMonetizationResource(self) @cached_property def network_interconnects(self) -> AsyncNetworkInterconnectsResource: @@ -2583,6 +2581,12 @@ def pipelines(self) -> AsyncPipelinesResource: return AsyncPipelinesResource(self) + @cached_property + def k2(self) -> AsyncK2Resource: + from .resources.k2 import AsyncK2Resource + + return AsyncK2Resource(self) + @cached_property def schema_validation(self) -> AsyncSchemaValidationResource: from .resources.schema_validation import AsyncSchemaValidationResource @@ -2791,6 +2795,11 @@ def accounts(self) -> accounts.AccountsResourceWithRawResponse: @cached_property def organizations(self) -> organizations.OrganizationsResourceWithRawResponse: + """ + User API tokens can list and create Organizations, but reading, updating, or deleting an Organization requires a Global API key and your registered email address. The `cloudflare_organization` Terraform resource therefore requires a Global API key for its full lifecycle. + + See [Organizations authentication limitations](https://developers.cloudflare.com/fundamentals/organizations/limitations/#api-authentication) for credential compatibility by operation. Each endpoint’s **Security** section lists its supported authentication methods, with **Accepted Permissions** where applicable. + """ from .resources.organizations import OrganizationsResourceWithRawResponse return OrganizationsResourceWithRawResponse(self._client.organizations) @@ -2903,12 +2912,6 @@ def custom_nameservers(self) -> custom_nameservers.CustomNameserversResourceWith return CustomNameserversResourceWithRawResponse(self._client.custom_nameservers) - @cached_property - def tenant_custom_nameservers(self) -> tenant_custom_nameservers.TenantCustomNameserversResourceWithRawResponse: - from .resources.tenant_custom_nameservers import TenantCustomNameserversResourceWithRawResponse - - return TenantCustomNameserversResourceWithRawResponse(self._client.tenant_custom_nameservers) - @cached_property def dns_firewall(self) -> dns_firewall.DNSFirewallResourceWithRawResponse: from .resources.dns_firewall import DNSFirewallResourceWithRawResponse @@ -3144,10 +3147,10 @@ def magic_network_monitoring(self) -> magic_network_monitoring.MagicNetworkMonit return MagicNetworkMonitoringResourceWithRawResponse(self._client.magic_network_monitoring) @cached_property - def magic_cloud_networking(self) -> magic_cloud_networking.MagicCloudNetworkingResourceWithRawResponse: - from .resources.magic_cloud_networking import MagicCloudNetworkingResourceWithRawResponse + def monetization(self) -> monetization.MonetizationResourceWithRawResponse: + from .resources.monetization import MonetizationResourceWithRawResponse - return MagicCloudNetworkingResourceWithRawResponse(self._client.magic_cloud_networking) + return MonetizationResourceWithRawResponse(self._client.monetization) @cached_property def network_interconnects(self) -> network_interconnects.NetworkInterconnectsResourceWithRawResponse: @@ -3719,6 +3722,12 @@ def pipelines(self) -> pipelines.PipelinesResourceWithRawResponse: return PipelinesResourceWithRawResponse(self._client.pipelines) + @cached_property + def k2(self) -> k2.K2ResourceWithRawResponse: + from .resources.k2 import K2ResourceWithRawResponse + + return K2ResourceWithRawResponse(self._client.k2) + @cached_property def schema_validation(self) -> schema_validation.SchemaValidationResourceWithRawResponse: from .resources.schema_validation import SchemaValidationResourceWithRawResponse @@ -3752,6 +3761,11 @@ def accounts(self) -> accounts.AsyncAccountsResourceWithRawResponse: @cached_property def organizations(self) -> organizations.AsyncOrganizationsResourceWithRawResponse: + """ + User API tokens can list and create Organizations, but reading, updating, or deleting an Organization requires a Global API key and your registered email address. The `cloudflare_organization` Terraform resource therefore requires a Global API key for its full lifecycle. + + See [Organizations authentication limitations](https://developers.cloudflare.com/fundamentals/organizations/limitations/#api-authentication) for credential compatibility by operation. Each endpoint’s **Security** section lists its supported authentication methods, with **Accepted Permissions** where applicable. + """ from .resources.organizations import AsyncOrganizationsResourceWithRawResponse return AsyncOrganizationsResourceWithRawResponse(self._client.organizations) @@ -3864,14 +3878,6 @@ def custom_nameservers(self) -> custom_nameservers.AsyncCustomNameserversResourc return AsyncCustomNameserversResourceWithRawResponse(self._client.custom_nameservers) - @cached_property - def tenant_custom_nameservers( - self, - ) -> tenant_custom_nameservers.AsyncTenantCustomNameserversResourceWithRawResponse: - from .resources.tenant_custom_nameservers import AsyncTenantCustomNameserversResourceWithRawResponse - - return AsyncTenantCustomNameserversResourceWithRawResponse(self._client.tenant_custom_nameservers) - @cached_property def dns_firewall(self) -> dns_firewall.AsyncDNSFirewallResourceWithRawResponse: from .resources.dns_firewall import AsyncDNSFirewallResourceWithRawResponse @@ -4107,10 +4113,10 @@ def magic_network_monitoring(self) -> magic_network_monitoring.AsyncMagicNetwork return AsyncMagicNetworkMonitoringResourceWithRawResponse(self._client.magic_network_monitoring) @cached_property - def magic_cloud_networking(self) -> magic_cloud_networking.AsyncMagicCloudNetworkingResourceWithRawResponse: - from .resources.magic_cloud_networking import AsyncMagicCloudNetworkingResourceWithRawResponse + def monetization(self) -> monetization.AsyncMonetizationResourceWithRawResponse: + from .resources.monetization import AsyncMonetizationResourceWithRawResponse - return AsyncMagicCloudNetworkingResourceWithRawResponse(self._client.magic_cloud_networking) + return AsyncMonetizationResourceWithRawResponse(self._client.monetization) @cached_property def network_interconnects(self) -> network_interconnects.AsyncNetworkInterconnectsResourceWithRawResponse: @@ -4682,6 +4688,12 @@ def pipelines(self) -> pipelines.AsyncPipelinesResourceWithRawResponse: return AsyncPipelinesResourceWithRawResponse(self._client.pipelines) + @cached_property + def k2(self) -> k2.AsyncK2ResourceWithRawResponse: + from .resources.k2 import AsyncK2ResourceWithRawResponse + + return AsyncK2ResourceWithRawResponse(self._client.k2) + @cached_property def schema_validation(self) -> schema_validation.AsyncSchemaValidationResourceWithRawResponse: from .resources.schema_validation import AsyncSchemaValidationResourceWithRawResponse @@ -4715,6 +4727,11 @@ def accounts(self) -> accounts.AccountsResourceWithStreamingResponse: @cached_property def organizations(self) -> organizations.OrganizationsResourceWithStreamingResponse: + """ + User API tokens can list and create Organizations, but reading, updating, or deleting an Organization requires a Global API key and your registered email address. The `cloudflare_organization` Terraform resource therefore requires a Global API key for its full lifecycle. + + See [Organizations authentication limitations](https://developers.cloudflare.com/fundamentals/organizations/limitations/#api-authentication) for credential compatibility by operation. Each endpoint’s **Security** section lists its supported authentication methods, with **Accepted Permissions** where applicable. + """ from .resources.organizations import OrganizationsResourceWithStreamingResponse return OrganizationsResourceWithStreamingResponse(self._client.organizations) @@ -4827,14 +4844,6 @@ def custom_nameservers(self) -> custom_nameservers.CustomNameserversResourceWith return CustomNameserversResourceWithStreamingResponse(self._client.custom_nameservers) - @cached_property - def tenant_custom_nameservers( - self, - ) -> tenant_custom_nameservers.TenantCustomNameserversResourceWithStreamingResponse: - from .resources.tenant_custom_nameservers import TenantCustomNameserversResourceWithStreamingResponse - - return TenantCustomNameserversResourceWithStreamingResponse(self._client.tenant_custom_nameservers) - @cached_property def dns_firewall(self) -> dns_firewall.DNSFirewallResourceWithStreamingResponse: from .resources.dns_firewall import DNSFirewallResourceWithStreamingResponse @@ -5070,10 +5079,10 @@ def magic_network_monitoring(self) -> magic_network_monitoring.MagicNetworkMonit return MagicNetworkMonitoringResourceWithStreamingResponse(self._client.magic_network_monitoring) @cached_property - def magic_cloud_networking(self) -> magic_cloud_networking.MagicCloudNetworkingResourceWithStreamingResponse: - from .resources.magic_cloud_networking import MagicCloudNetworkingResourceWithStreamingResponse + def monetization(self) -> monetization.MonetizationResourceWithStreamingResponse: + from .resources.monetization import MonetizationResourceWithStreamingResponse - return MagicCloudNetworkingResourceWithStreamingResponse(self._client.magic_cloud_networking) + return MonetizationResourceWithStreamingResponse(self._client.monetization) @cached_property def network_interconnects(self) -> network_interconnects.NetworkInterconnectsResourceWithStreamingResponse: @@ -5645,6 +5654,12 @@ def pipelines(self) -> pipelines.PipelinesResourceWithStreamingResponse: return PipelinesResourceWithStreamingResponse(self._client.pipelines) + @cached_property + def k2(self) -> k2.K2ResourceWithStreamingResponse: + from .resources.k2 import K2ResourceWithStreamingResponse + + return K2ResourceWithStreamingResponse(self._client.k2) + @cached_property def schema_validation(self) -> schema_validation.SchemaValidationResourceWithStreamingResponse: from .resources.schema_validation import SchemaValidationResourceWithStreamingResponse @@ -5678,6 +5693,11 @@ def accounts(self) -> accounts.AsyncAccountsResourceWithStreamingResponse: @cached_property def organizations(self) -> organizations.AsyncOrganizationsResourceWithStreamingResponse: + """ + User API tokens can list and create Organizations, but reading, updating, or deleting an Organization requires a Global API key and your registered email address. The `cloudflare_organization` Terraform resource therefore requires a Global API key for its full lifecycle. + + See [Organizations authentication limitations](https://developers.cloudflare.com/fundamentals/organizations/limitations/#api-authentication) for credential compatibility by operation. Each endpoint’s **Security** section lists its supported authentication methods, with **Accepted Permissions** where applicable. + """ from .resources.organizations import AsyncOrganizationsResourceWithStreamingResponse return AsyncOrganizationsResourceWithStreamingResponse(self._client.organizations) @@ -5792,14 +5812,6 @@ def custom_nameservers(self) -> custom_nameservers.AsyncCustomNameserversResourc return AsyncCustomNameserversResourceWithStreamingResponse(self._client.custom_nameservers) - @cached_property - def tenant_custom_nameservers( - self, - ) -> tenant_custom_nameservers.AsyncTenantCustomNameserversResourceWithStreamingResponse: - from .resources.tenant_custom_nameservers import AsyncTenantCustomNameserversResourceWithStreamingResponse - - return AsyncTenantCustomNameserversResourceWithStreamingResponse(self._client.tenant_custom_nameservers) - @cached_property def dns_firewall(self) -> dns_firewall.AsyncDNSFirewallResourceWithStreamingResponse: from .resources.dns_firewall import AsyncDNSFirewallResourceWithStreamingResponse @@ -6037,10 +6049,10 @@ def magic_network_monitoring( return AsyncMagicNetworkMonitoringResourceWithStreamingResponse(self._client.magic_network_monitoring) @cached_property - def magic_cloud_networking(self) -> magic_cloud_networking.AsyncMagicCloudNetworkingResourceWithStreamingResponse: - from .resources.magic_cloud_networking import AsyncMagicCloudNetworkingResourceWithStreamingResponse + def monetization(self) -> monetization.AsyncMonetizationResourceWithStreamingResponse: + from .resources.monetization import AsyncMonetizationResourceWithStreamingResponse - return AsyncMagicCloudNetworkingResourceWithStreamingResponse(self._client.magic_cloud_networking) + return AsyncMonetizationResourceWithStreamingResponse(self._client.monetization) @cached_property def network_interconnects(self) -> network_interconnects.AsyncNetworkInterconnectsResourceWithStreamingResponse: @@ -6618,6 +6630,12 @@ def pipelines(self) -> pipelines.AsyncPipelinesResourceWithStreamingResponse: return AsyncPipelinesResourceWithStreamingResponse(self._client.pipelines) + @cached_property + def k2(self) -> k2.AsyncK2ResourceWithStreamingResponse: + from .resources.k2 import AsyncK2ResourceWithStreamingResponse + + return AsyncK2ResourceWithStreamingResponse(self._client.k2) + @cached_property def schema_validation(self) -> schema_validation.AsyncSchemaValidationResourceWithStreamingResponse: from .resources.schema_validation import AsyncSchemaValidationResourceWithStreamingResponse diff --git a/src/cloudflare/_version.py b/src/cloudflare/_version.py index 2f99be27298..248da8ded62 100644 --- a/src/cloudflare/_version.py +++ b/src/cloudflare/_version.py @@ -1,5 +1,5 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. __title__ = "cloudflare" -__version__ = "5.9.0" # x-release-please-version +__version__ = "5.10.0" # x-release-please-version __api_version__ = "" diff --git a/src/cloudflare/resources/abuse_reports/abuse_reports.py b/src/cloudflare/resources/abuse_reports/abuse_reports.py index 505dcb3b126..c9dba4f780e 100644 --- a/src/cloudflare/resources/abuse_reports/abuse_reports.py +++ b/src/cloudflare/resources/abuse_reports/abuse_reports.py @@ -114,6 +114,16 @@ def create( `Trust and Safety Write` permission. If the account is not entitled, the request is rejected with an HTTP `401` response (see below). + Delegated reports: In limited circumstances, Cloudflare works with select + customers who have established abuse-handling programs. For these customers, + Cloudflare may forward abuse reports directly and in full—including reporter + contact information, comments, and supporting evidence—without redaction or + preprocessing by Cloudflare. This allows the customer to investigate and respond + using their own policies and processes. For delegated reports, the + report—including contact information and comments—will be forwarded to the + customer in full regardless of the `host_notification` and `owner_notification` + values. + Args: report_param: The report type for submitted reports. @@ -139,7 +149,9 @@ def create( email2: Should match the value provided in `email` - host_notification: Notification type based on the abuse type. NOTE: Copyright (DMCA) and Trademark + host_notification: Notification type based on the abuse type. For delegated reports, the + report—including contact information and comments—will be forwarded to the + customer in full regardless of this value. NOTE: Copyright (DMCA) and Trademark reports cannot be anonymous. name: Text not exceeding 255 characters. This field may be released by Cloudflare to @@ -148,7 +160,9 @@ def create( original_work: Text not exceeding 255 characters. This field may be released by Cloudflare to third parties such as the Lumen Database (https://lumendatabase.org/). - owner_notification: Notification type based on the abuse type. NOTE: Copyright (DMCA) and Trademark + owner_notification: Notification type based on the abuse type. For delegated reports, the + report—including contact information and comments—will be forwarded to the + customer in full regardless of this value. NOTE: Copyright (DMCA) and Trademark reports cannot be anonymous. signature: Required for DMCA reports, should be same as Name. An affirmation that all @@ -163,7 +177,10 @@ def create( URL should be unique. This field may be released by Cloudflare to third parties such as the Lumen Database (https://lumendatabase.org/). - comments: Any additional comments about the infringement not exceeding 2000 characters + comments: Any additional comments about the infringement not exceeding 2000 characters. + Comments are kept internal to Cloudflare and not shared with the host or + customer as part of regular processing. For delegated reports, comments may be + shared in full. company: Text not exceeding 100 characters. This field may be released by Cloudflare to third parties such as the Lumen Database (https://lumendatabase.org/). @@ -225,6 +242,16 @@ def create( `Trust and Safety Write` permission. If the account is not entitled, the request is rejected with an HTTP `401` response (see below). + Delegated reports: In limited circumstances, Cloudflare works with select + customers who have established abuse-handling programs. For these customers, + Cloudflare may forward abuse reports directly and in full—including reporter + contact information, comments, and supporting evidence—without redaction or + preprocessing by Cloudflare. This allows the customer to investigate and respond + using their own policies and processes. For delegated reports, the + report—including contact information and comments—will be forwarded to the + customer in full regardless of the `host_notification` and `owner_notification` + values. + Args: report_param: The report type for submitted reports. @@ -235,7 +262,9 @@ def create( email2: Should match the value provided in `email` - host_notification: Notification type based on the abuse type. NOTE: Copyright (DMCA) and Trademark + host_notification: Notification type based on the abuse type. For delegated reports, the + report—including contact information and comments—will be forwarded to the + customer in full regardless of this value. NOTE: Copyright (DMCA) and Trademark reports cannot be anonymous. justification: A detailed description of the infringement, including any necessary access @@ -245,7 +274,9 @@ def create( name: Text not exceeding 255 characters. This field may be released by Cloudflare to third parties such as the Lumen Database (https://lumendatabase.org/). - owner_notification: Notification type based on the abuse type. NOTE: Copyright (DMCA) and Trademark + owner_notification: Notification type based on the abuse type. For delegated reports, the + report—including contact information and comments—will be forwarded to the + customer in full regardless of this value. NOTE: Copyright (DMCA) and Trademark reports cannot be anonymous. trademark_number: Text not exceeding 1000 characters @@ -259,7 +290,10 @@ def create( URL should be unique. This field may be released by Cloudflare to third parties such as the Lumen Database (https://lumendatabase.org/). - comments: Any additional comments about the infringement not exceeding 2000 characters + comments: Any additional comments about the infringement not exceeding 2000 characters. + Comments are kept internal to Cloudflare and not shared with the host or + customer as part of regular processing. For delegated reports, comments may be + shared in full. company: Text not exceeding 100 characters. This field may be released by Cloudflare to third parties such as the Lumen Database (https://lumendatabase.org/). @@ -321,6 +355,16 @@ def create( `Trust and Safety Write` permission. If the account is not entitled, the request is rejected with an HTTP `401` response (see below). + Delegated reports: In limited circumstances, Cloudflare works with select + customers who have established abuse-handling programs. For these customers, + Cloudflare may forward abuse reports directly and in full—including reporter + contact information, comments, and supporting evidence—without redaction or + preprocessing by Cloudflare. This allows the customer to investigate and respond + using their own policies and processes. For delegated reports, the + report—including contact information and comments—will be forwarded to the + customer in full regardless of the `host_notification` and `owner_notification` + values. + Args: report_param: The report type for submitted reports. @@ -331,7 +375,9 @@ def create( email2: Should match the value provided in `email` - host_notification: Notification type based on the abuse type. NOTE: Copyright (DMCA) and Trademark + host_notification: Notification type based on the abuse type. For delegated reports, the + report—including contact information and comments—will be forwarded to the + customer in full regardless of this value. NOTE: Copyright (DMCA) and Trademark reports cannot be anonymous. justification: A detailed description of the infringement, including any necessary access @@ -341,7 +387,9 @@ def create( name: Text not exceeding 255 characters. This field may be released by Cloudflare to third parties such as the Lumen Database (https://lumendatabase.org/). - owner_notification: Notification type based on the abuse type. NOTE: Copyright (DMCA) and Trademark + owner_notification: Notification type based on the abuse type. For delegated reports, the + report—including contact information and comments—will be forwarded to the + customer in full regardless of this value. NOTE: Copyright (DMCA) and Trademark reports cannot be anonymous. urls: A list of valid URLs separated by ‘\n’ (new line character). The list of the @@ -349,7 +397,10 @@ def create( URL should be unique. This field may be released by Cloudflare to third parties such as the Lumen Database (https://lumendatabase.org/). - comments: Any additional comments about the infringement not exceeding 2000 characters + comments: Any additional comments about the infringement not exceeding 2000 characters. + Comments are kept internal to Cloudflare and not shared with the host or + customer as part of regular processing. For delegated reports, comments may be + shared in full. company: Text not exceeding 100 characters. This field may be released by Cloudflare to third parties such as the Lumen Database (https://lumendatabase.org/). @@ -422,6 +473,16 @@ def create( `Trust and Safety Write` permission. If the account is not entitled, the request is rejected with an HTTP `401` response (see below). + Delegated reports: In limited circumstances, Cloudflare works with select + customers who have established abuse-handling programs. For these customers, + Cloudflare may forward abuse reports directly and in full—including reporter + contact information, comments, and supporting evidence—without redaction or + preprocessing by Cloudflare. This allows the customer to investigate and respond + using their own policies and processes. For delegated reports, the + report—including contact information and comments—will be forwarded to the + customer in full regardless of the `host_notification` and `owner_notification` + values. + Args: report_param: The report type for submitted reports. @@ -432,7 +493,9 @@ def create( email2: Should match the value provided in `email` - host_notification: Notification type based on the abuse type. NOTE: Copyright (DMCA) and Trademark + host_notification: Notification type based on the abuse type. For delegated reports, the + report—including contact information and comments—will be forwarded to the + customer in full regardless of this value. NOTE: Copyright (DMCA) and Trademark reports cannot be anonymous. justification: A detailed description of the infringement, including any necessary access @@ -442,7 +505,9 @@ def create( name: Text not exceeding 255 characters. This field may be released by Cloudflare to third parties such as the Lumen Database (https://lumendatabase.org/). - owner_notification: Notification type based on the abuse type. NOTE: Copyright (DMCA) and Trademark + owner_notification: Notification type based on the abuse type. For delegated reports, the + report—including contact information and comments—will be forwarded to the + customer in full regardless of this value. NOTE: Copyright (DMCA) and Trademark reports cannot be anonymous. urls: A list of valid URLs separated by ‘\n’ (new line character). The list of the @@ -450,7 +515,10 @@ def create( URL should be unique. This field may be released by Cloudflare to third parties such as the Lumen Database (https://lumendatabase.org/). - comments: Any additional comments about the infringement not exceeding 2000 characters + comments: Any additional comments about the infringement not exceeding 2000 characters. + Comments are kept internal to Cloudflare and not shared with the host or + customer as part of regular processing. For delegated reports, comments may be + shared in full. company: Text not exceeding 100 characters. This field may be released by Cloudflare to third parties such as the Lumen Database (https://lumendatabase.org/). @@ -514,6 +582,16 @@ def create( `Trust and Safety Write` permission. If the account is not entitled, the request is rejected with an HTTP `401` response (see below). + Delegated reports: In limited circumstances, Cloudflare works with select + customers who have established abuse-handling programs. For these customers, + Cloudflare may forward abuse reports directly and in full—including reporter + contact information, comments, and supporting evidence—without redaction or + preprocessing by Cloudflare. This allows the customer to investigate and respond + using their own policies and processes. For delegated reports, the + report—including contact information and comments—will be forwarded to the + customer in full regardless of the `host_notification` and `owner_notification` + values. + Args: report_param: The report type for submitted reports. @@ -524,7 +602,9 @@ def create( email2: Should match the value provided in `email` - host_notification: Notification type based on the abuse type. NOTE: Copyright (DMCA) and Trademark + host_notification: Notification type based on the abuse type. For delegated reports, the + report—including contact information and comments—will be forwarded to the + customer in full regardless of this value. NOTE: Copyright (DMCA) and Trademark reports cannot be anonymous. justification: A detailed description of the infringement, including any necessary access @@ -537,7 +617,9 @@ def create( ncmec_notification: Notification type based on the abuse type. NOTE: Copyright (DMCA) and Trademark reports cannot be anonymous. - owner_notification: Notification type based on the abuse type. NOTE: Copyright (DMCA) and Trademark + owner_notification: Notification type based on the abuse type. For delegated reports, the + report—including contact information and comments—will be forwarded to the + customer in full regardless of this value. NOTE: Copyright (DMCA) and Trademark reports cannot be anonymous. urls: A list of valid URLs separated by ‘\n’ (new line character). The list of the @@ -545,7 +627,10 @@ def create( URL should be unique. This field may be released by Cloudflare to third parties such as the Lumen Database (https://lumendatabase.org/). - comments: Any additional comments about the infringement not exceeding 2000 characters + comments: Any additional comments about the infringement not exceeding 2000 characters. + Comments are kept internal to Cloudflare and not shared with the host or + customer as part of regular processing. For delegated reports, comments may be + shared in full. company: Text not exceeding 100 characters. This field may be released by Cloudflare to third parties such as the Lumen Database (https://lumendatabase.org/). @@ -607,6 +692,16 @@ def create( `Trust and Safety Write` permission. If the account is not entitled, the request is rejected with an HTTP `401` response (see below). + Delegated reports: In limited circumstances, Cloudflare works with select + customers who have established abuse-handling programs. For these customers, + Cloudflare may forward abuse reports directly and in full—including reporter + contact information, comments, and supporting evidence—without redaction or + preprocessing by Cloudflare. This allows the customer to investigate and respond + using their own policies and processes. For delegated reports, the + report—including contact information and comments—will be forwarded to the + customer in full regardless of the `host_notification` and `owner_notification` + values. + Args: report_param: The report type for submitted reports. @@ -617,7 +712,9 @@ def create( email2: Should match the value provided in `email` - host_notification: Notification type based on the abuse type. NOTE: Copyright (DMCA) and Trademark + host_notification: Notification type based on the abuse type. For delegated reports, the + report—including contact information and comments—will be forwarded to the + customer in full regardless of this value. NOTE: Copyright (DMCA) and Trademark reports cannot be anonymous. justification: A detailed description of the infringement, including any necessary access @@ -627,7 +724,9 @@ def create( name: Text not exceeding 255 characters. This field may be released by Cloudflare to third parties such as the Lumen Database (https://lumendatabase.org/). - owner_notification: Notification type based on the abuse type. NOTE: Copyright (DMCA) and Trademark + owner_notification: Notification type based on the abuse type. For delegated reports, the + report—including contact information and comments—will be forwarded to the + customer in full regardless of this value. NOTE: Copyright (DMCA) and Trademark reports cannot be anonymous. urls: A list of valid URLs separated by ‘\n’ (new line character). The list of the @@ -635,7 +734,10 @@ def create( URL should be unique. This field may be released by Cloudflare to third parties such as the Lumen Database (https://lumendatabase.org/). - comments: Any additional comments about the infringement not exceeding 2000 characters + comments: Any additional comments about the infringement not exceeding 2000 characters. + Comments are kept internal to Cloudflare and not shared with the host or + customer as part of regular processing. For delegated reports, comments may be + shared in full. company: Text not exceeding 100 characters. This field may be released by Cloudflare to third parties such as the Lumen Database (https://lumendatabase.org/). @@ -693,6 +795,16 @@ def create( `Trust and Safety Write` permission. If the account is not entitled, the request is rejected with an HTTP `401` response (see below). + Delegated reports: In limited circumstances, Cloudflare works with select + customers who have established abuse-handling programs. For these customers, + Cloudflare may forward abuse reports directly and in full—including reporter + contact information, comments, and supporting evidence—without redaction or + preprocessing by Cloudflare. This allows the customer to investigate and respond + using their own policies and processes. For delegated reports, the + report—including contact information and comments—will be forwarded to the + customer in full regardless of the `host_notification` and `owner_notification` + values. + Args: report_param: The report type for submitted reports. @@ -706,7 +818,9 @@ def create( name: Text not exceeding 255 characters. This field may be released by Cloudflare to third parties such as the Lumen Database (https://lumendatabase.org/). - owner_notification: Notification type based on the abuse type. NOTE: Copyright (DMCA) and Trademark + owner_notification: Notification type based on the abuse type. For delegated reports, the + report—including contact information and comments—will be forwarded to the + customer in full regardless of this value. NOTE: Copyright (DMCA) and Trademark reports cannot be anonymous. urls: A list of valid URLs separated by ‘\n’ (new line character). The list of the @@ -714,7 +828,10 @@ def create( URL should be unique. This field may be released by Cloudflare to third parties such as the Lumen Database (https://lumendatabase.org/). - comments: Any additional comments about the infringement not exceeding 2000 characters + comments: Any additional comments about the infringement not exceeding 2000 characters. + Comments are kept internal to Cloudflare and not shared with the host or + customer as part of regular processing. For delegated reports, comments may be + shared in full. company: Text not exceeding 100 characters. This field may be released by Cloudflare to third parties such as the Lumen Database (https://lumendatabase.org/). @@ -776,6 +893,16 @@ def create( `Trust and Safety Write` permission. If the account is not entitled, the request is rejected with an HTTP `401` response (see below). + Delegated reports: In limited circumstances, Cloudflare works with select + customers who have established abuse-handling programs. For these customers, + Cloudflare may forward abuse reports directly and in full—including reporter + contact information, comments, and supporting evidence—without redaction or + preprocessing by Cloudflare. This allows the customer to investigate and respond + using their own policies and processes. For delegated reports, the + report—including contact information and comments—will be forwarded to the + customer in full regardless of the `host_notification` and `owner_notification` + values. + Args: report_param: The report type for submitted reports. @@ -786,7 +913,9 @@ def create( email2: Should match the value provided in `email` - host_notification: Notification type based on the abuse type. NOTE: Copyright (DMCA) and Trademark + host_notification: Notification type based on the abuse type. For delegated reports, the + report—including contact information and comments—will be forwarded to the + customer in full regardless of this value. NOTE: Copyright (DMCA) and Trademark reports cannot be anonymous. name: Text not exceeding 255 characters. This field may be released by Cloudflare to @@ -794,7 +923,9 @@ def create( ncsei_subject_representation: If the submitter is the target of NCSEI in the URLs of the abuse report. - owner_notification: Notification type based on the abuse type. NOTE: Copyright (DMCA) and Trademark + owner_notification: Notification type based on the abuse type. For delegated reports, the + report—including contact information and comments—will be forwarded to the + customer in full regardless of this value. NOTE: Copyright (DMCA) and Trademark reports cannot be anonymous. urls: A list of valid URLs separated by ‘\n’ (new line character). The list of the @@ -802,7 +933,10 @@ def create( URL should be unique. This field may be released by Cloudflare to third parties such as the Lumen Database (https://lumendatabase.org/). - comments: Any additional comments about the infringement not exceeding 2000 characters + comments: Any additional comments about the infringement not exceeding 2000 characters. + Comments are kept internal to Cloudflare and not shared with the host or + customer as part of regular processing. For delegated reports, comments may be + shared in full. company: Text not exceeding 100 characters. This field may be released by Cloudflare to third parties such as the Lumen Database (https://lumendatabase.org/). @@ -1011,7 +1145,9 @@ def list( domain: str | Omit = omit, mitigation_status: Literal["pending", "active", "in_review", "cancelled", "removed"] | Omit = omit, page: int | Omit = omit, + pending_notice: bool | Omit = omit, per_page: int | Omit = omit, + search: str | Omit = omit, sort: str | Omit = omit, status: Literal["accepted", "in_review"] | Omit = omit, type: Literal["PHISH", "GEN", "THREAT", "DMCA", "EMER", "TM", "REG_WHO", "NCSEI", "NETWORK"] | Omit = omit, @@ -1038,8 +1174,16 @@ def list( page: Where in pagination to start listing abuse reports + pending_notice: Also include reports in an open Notice and Takedown notice period. Combined with + mitigation_status using OR, e.g. ?mitigation_status=active&pending_notice=true. + per_page: How many abuse reports per page to list + search: Free-text search. Returns reports whose report ID starts with the term or whose + domain contains the term, both case-insensitively. Surrounding whitespace is + ignored, and an empty value is treated as absent. Combined with the other + filters using AND. + sort: A property to sort by, followed by the order (id, cdate, domain, type, status) status: Filter by the status of the report. @@ -1071,7 +1215,9 @@ def list( "domain": domain, "mitigation_status": mitigation_status, "page": page, + "pending_notice": pending_notice, "per_page": per_page, + "search": search, "sort": sort, "status": status, "type": type, @@ -1197,6 +1343,16 @@ async def create( `Trust and Safety Write` permission. If the account is not entitled, the request is rejected with an HTTP `401` response (see below). + Delegated reports: In limited circumstances, Cloudflare works with select + customers who have established abuse-handling programs. For these customers, + Cloudflare may forward abuse reports directly and in full—including reporter + contact information, comments, and supporting evidence—without redaction or + preprocessing by Cloudflare. This allows the customer to investigate and respond + using their own policies and processes. For delegated reports, the + report—including contact information and comments—will be forwarded to the + customer in full regardless of the `host_notification` and `owner_notification` + values. + Args: report_param: The report type for submitted reports. @@ -1222,7 +1378,9 @@ async def create( email2: Should match the value provided in `email` - host_notification: Notification type based on the abuse type. NOTE: Copyright (DMCA) and Trademark + host_notification: Notification type based on the abuse type. For delegated reports, the + report—including contact information and comments—will be forwarded to the + customer in full regardless of this value. NOTE: Copyright (DMCA) and Trademark reports cannot be anonymous. name: Text not exceeding 255 characters. This field may be released by Cloudflare to @@ -1231,7 +1389,9 @@ async def create( original_work: Text not exceeding 255 characters. This field may be released by Cloudflare to third parties such as the Lumen Database (https://lumendatabase.org/). - owner_notification: Notification type based on the abuse type. NOTE: Copyright (DMCA) and Trademark + owner_notification: Notification type based on the abuse type. For delegated reports, the + report—including contact information and comments—will be forwarded to the + customer in full regardless of this value. NOTE: Copyright (DMCA) and Trademark reports cannot be anonymous. signature: Required for DMCA reports, should be same as Name. An affirmation that all @@ -1246,7 +1406,10 @@ async def create( URL should be unique. This field may be released by Cloudflare to third parties such as the Lumen Database (https://lumendatabase.org/). - comments: Any additional comments about the infringement not exceeding 2000 characters + comments: Any additional comments about the infringement not exceeding 2000 characters. + Comments are kept internal to Cloudflare and not shared with the host or + customer as part of regular processing. For delegated reports, comments may be + shared in full. company: Text not exceeding 100 characters. This field may be released by Cloudflare to third parties such as the Lumen Database (https://lumendatabase.org/). @@ -1308,6 +1471,16 @@ async def create( `Trust and Safety Write` permission. If the account is not entitled, the request is rejected with an HTTP `401` response (see below). + Delegated reports: In limited circumstances, Cloudflare works with select + customers who have established abuse-handling programs. For these customers, + Cloudflare may forward abuse reports directly and in full—including reporter + contact information, comments, and supporting evidence—without redaction or + preprocessing by Cloudflare. This allows the customer to investigate and respond + using their own policies and processes. For delegated reports, the + report—including contact information and comments—will be forwarded to the + customer in full regardless of the `host_notification` and `owner_notification` + values. + Args: report_param: The report type for submitted reports. @@ -1318,7 +1491,9 @@ async def create( email2: Should match the value provided in `email` - host_notification: Notification type based on the abuse type. NOTE: Copyright (DMCA) and Trademark + host_notification: Notification type based on the abuse type. For delegated reports, the + report—including contact information and comments—will be forwarded to the + customer in full regardless of this value. NOTE: Copyright (DMCA) and Trademark reports cannot be anonymous. justification: A detailed description of the infringement, including any necessary access @@ -1328,7 +1503,9 @@ async def create( name: Text not exceeding 255 characters. This field may be released by Cloudflare to third parties such as the Lumen Database (https://lumendatabase.org/). - owner_notification: Notification type based on the abuse type. NOTE: Copyright (DMCA) and Trademark + owner_notification: Notification type based on the abuse type. For delegated reports, the + report—including contact information and comments—will be forwarded to the + customer in full regardless of this value. NOTE: Copyright (DMCA) and Trademark reports cannot be anonymous. trademark_number: Text not exceeding 1000 characters @@ -1342,7 +1519,10 @@ async def create( URL should be unique. This field may be released by Cloudflare to third parties such as the Lumen Database (https://lumendatabase.org/). - comments: Any additional comments about the infringement not exceeding 2000 characters + comments: Any additional comments about the infringement not exceeding 2000 characters. + Comments are kept internal to Cloudflare and not shared with the host or + customer as part of regular processing. For delegated reports, comments may be + shared in full. company: Text not exceeding 100 characters. This field may be released by Cloudflare to third parties such as the Lumen Database (https://lumendatabase.org/). @@ -1404,6 +1584,16 @@ async def create( `Trust and Safety Write` permission. If the account is not entitled, the request is rejected with an HTTP `401` response (see below). + Delegated reports: In limited circumstances, Cloudflare works with select + customers who have established abuse-handling programs. For these customers, + Cloudflare may forward abuse reports directly and in full—including reporter + contact information, comments, and supporting evidence—without redaction or + preprocessing by Cloudflare. This allows the customer to investigate and respond + using their own policies and processes. For delegated reports, the + report—including contact information and comments—will be forwarded to the + customer in full regardless of the `host_notification` and `owner_notification` + values. + Args: report_param: The report type for submitted reports. @@ -1414,7 +1604,9 @@ async def create( email2: Should match the value provided in `email` - host_notification: Notification type based on the abuse type. NOTE: Copyright (DMCA) and Trademark + host_notification: Notification type based on the abuse type. For delegated reports, the + report—including contact information and comments—will be forwarded to the + customer in full regardless of this value. NOTE: Copyright (DMCA) and Trademark reports cannot be anonymous. justification: A detailed description of the infringement, including any necessary access @@ -1424,7 +1616,9 @@ async def create( name: Text not exceeding 255 characters. This field may be released by Cloudflare to third parties such as the Lumen Database (https://lumendatabase.org/). - owner_notification: Notification type based on the abuse type. NOTE: Copyright (DMCA) and Trademark + owner_notification: Notification type based on the abuse type. For delegated reports, the + report—including contact information and comments—will be forwarded to the + customer in full regardless of this value. NOTE: Copyright (DMCA) and Trademark reports cannot be anonymous. urls: A list of valid URLs separated by ‘\n’ (new line character). The list of the @@ -1432,7 +1626,10 @@ async def create( URL should be unique. This field may be released by Cloudflare to third parties such as the Lumen Database (https://lumendatabase.org/). - comments: Any additional comments about the infringement not exceeding 2000 characters + comments: Any additional comments about the infringement not exceeding 2000 characters. + Comments are kept internal to Cloudflare and not shared with the host or + customer as part of regular processing. For delegated reports, comments may be + shared in full. company: Text not exceeding 100 characters. This field may be released by Cloudflare to third parties such as the Lumen Database (https://lumendatabase.org/). @@ -1505,6 +1702,16 @@ async def create( `Trust and Safety Write` permission. If the account is not entitled, the request is rejected with an HTTP `401` response (see below). + Delegated reports: In limited circumstances, Cloudflare works with select + customers who have established abuse-handling programs. For these customers, + Cloudflare may forward abuse reports directly and in full—including reporter + contact information, comments, and supporting evidence—without redaction or + preprocessing by Cloudflare. This allows the customer to investigate and respond + using their own policies and processes. For delegated reports, the + report—including contact information and comments—will be forwarded to the + customer in full regardless of the `host_notification` and `owner_notification` + values. + Args: report_param: The report type for submitted reports. @@ -1515,7 +1722,9 @@ async def create( email2: Should match the value provided in `email` - host_notification: Notification type based on the abuse type. NOTE: Copyright (DMCA) and Trademark + host_notification: Notification type based on the abuse type. For delegated reports, the + report—including contact information and comments—will be forwarded to the + customer in full regardless of this value. NOTE: Copyright (DMCA) and Trademark reports cannot be anonymous. justification: A detailed description of the infringement, including any necessary access @@ -1525,7 +1734,9 @@ async def create( name: Text not exceeding 255 characters. This field may be released by Cloudflare to third parties such as the Lumen Database (https://lumendatabase.org/). - owner_notification: Notification type based on the abuse type. NOTE: Copyright (DMCA) and Trademark + owner_notification: Notification type based on the abuse type. For delegated reports, the + report—including contact information and comments—will be forwarded to the + customer in full regardless of this value. NOTE: Copyright (DMCA) and Trademark reports cannot be anonymous. urls: A list of valid URLs separated by ‘\n’ (new line character). The list of the @@ -1533,7 +1744,10 @@ async def create( URL should be unique. This field may be released by Cloudflare to third parties such as the Lumen Database (https://lumendatabase.org/). - comments: Any additional comments about the infringement not exceeding 2000 characters + comments: Any additional comments about the infringement not exceeding 2000 characters. + Comments are kept internal to Cloudflare and not shared with the host or + customer as part of regular processing. For delegated reports, comments may be + shared in full. company: Text not exceeding 100 characters. This field may be released by Cloudflare to third parties such as the Lumen Database (https://lumendatabase.org/). @@ -1597,6 +1811,16 @@ async def create( `Trust and Safety Write` permission. If the account is not entitled, the request is rejected with an HTTP `401` response (see below). + Delegated reports: In limited circumstances, Cloudflare works with select + customers who have established abuse-handling programs. For these customers, + Cloudflare may forward abuse reports directly and in full—including reporter + contact information, comments, and supporting evidence—without redaction or + preprocessing by Cloudflare. This allows the customer to investigate and respond + using their own policies and processes. For delegated reports, the + report—including contact information and comments—will be forwarded to the + customer in full regardless of the `host_notification` and `owner_notification` + values. + Args: report_param: The report type for submitted reports. @@ -1607,7 +1831,9 @@ async def create( email2: Should match the value provided in `email` - host_notification: Notification type based on the abuse type. NOTE: Copyright (DMCA) and Trademark + host_notification: Notification type based on the abuse type. For delegated reports, the + report—including contact information and comments—will be forwarded to the + customer in full regardless of this value. NOTE: Copyright (DMCA) and Trademark reports cannot be anonymous. justification: A detailed description of the infringement, including any necessary access @@ -1620,7 +1846,9 @@ async def create( ncmec_notification: Notification type based on the abuse type. NOTE: Copyright (DMCA) and Trademark reports cannot be anonymous. - owner_notification: Notification type based on the abuse type. NOTE: Copyright (DMCA) and Trademark + owner_notification: Notification type based on the abuse type. For delegated reports, the + report—including contact information and comments—will be forwarded to the + customer in full regardless of this value. NOTE: Copyright (DMCA) and Trademark reports cannot be anonymous. urls: A list of valid URLs separated by ‘\n’ (new line character). The list of the @@ -1628,7 +1856,10 @@ async def create( URL should be unique. This field may be released by Cloudflare to third parties such as the Lumen Database (https://lumendatabase.org/). - comments: Any additional comments about the infringement not exceeding 2000 characters + comments: Any additional comments about the infringement not exceeding 2000 characters. + Comments are kept internal to Cloudflare and not shared with the host or + customer as part of regular processing. For delegated reports, comments may be + shared in full. company: Text not exceeding 100 characters. This field may be released by Cloudflare to third parties such as the Lumen Database (https://lumendatabase.org/). @@ -1690,6 +1921,16 @@ async def create( `Trust and Safety Write` permission. If the account is not entitled, the request is rejected with an HTTP `401` response (see below). + Delegated reports: In limited circumstances, Cloudflare works with select + customers who have established abuse-handling programs. For these customers, + Cloudflare may forward abuse reports directly and in full—including reporter + contact information, comments, and supporting evidence—without redaction or + preprocessing by Cloudflare. This allows the customer to investigate and respond + using their own policies and processes. For delegated reports, the + report—including contact information and comments—will be forwarded to the + customer in full regardless of the `host_notification` and `owner_notification` + values. + Args: report_param: The report type for submitted reports. @@ -1700,7 +1941,9 @@ async def create( email2: Should match the value provided in `email` - host_notification: Notification type based on the abuse type. NOTE: Copyright (DMCA) and Trademark + host_notification: Notification type based on the abuse type. For delegated reports, the + report—including contact information and comments—will be forwarded to the + customer in full regardless of this value. NOTE: Copyright (DMCA) and Trademark reports cannot be anonymous. justification: A detailed description of the infringement, including any necessary access @@ -1710,7 +1953,9 @@ async def create( name: Text not exceeding 255 characters. This field may be released by Cloudflare to third parties such as the Lumen Database (https://lumendatabase.org/). - owner_notification: Notification type based on the abuse type. NOTE: Copyright (DMCA) and Trademark + owner_notification: Notification type based on the abuse type. For delegated reports, the + report—including contact information and comments—will be forwarded to the + customer in full regardless of this value. NOTE: Copyright (DMCA) and Trademark reports cannot be anonymous. urls: A list of valid URLs separated by ‘\n’ (new line character). The list of the @@ -1718,7 +1963,10 @@ async def create( URL should be unique. This field may be released by Cloudflare to third parties such as the Lumen Database (https://lumendatabase.org/). - comments: Any additional comments about the infringement not exceeding 2000 characters + comments: Any additional comments about the infringement not exceeding 2000 characters. + Comments are kept internal to Cloudflare and not shared with the host or + customer as part of regular processing. For delegated reports, comments may be + shared in full. company: Text not exceeding 100 characters. This field may be released by Cloudflare to third parties such as the Lumen Database (https://lumendatabase.org/). @@ -1776,6 +2024,16 @@ async def create( `Trust and Safety Write` permission. If the account is not entitled, the request is rejected with an HTTP `401` response (see below). + Delegated reports: In limited circumstances, Cloudflare works with select + customers who have established abuse-handling programs. For these customers, + Cloudflare may forward abuse reports directly and in full—including reporter + contact information, comments, and supporting evidence—without redaction or + preprocessing by Cloudflare. This allows the customer to investigate and respond + using their own policies and processes. For delegated reports, the + report—including contact information and comments—will be forwarded to the + customer in full regardless of the `host_notification` and `owner_notification` + values. + Args: report_param: The report type for submitted reports. @@ -1789,7 +2047,9 @@ async def create( name: Text not exceeding 255 characters. This field may be released by Cloudflare to third parties such as the Lumen Database (https://lumendatabase.org/). - owner_notification: Notification type based on the abuse type. NOTE: Copyright (DMCA) and Trademark + owner_notification: Notification type based on the abuse type. For delegated reports, the + report—including contact information and comments—will be forwarded to the + customer in full regardless of this value. NOTE: Copyright (DMCA) and Trademark reports cannot be anonymous. urls: A list of valid URLs separated by ‘\n’ (new line character). The list of the @@ -1797,7 +2057,10 @@ async def create( URL should be unique. This field may be released by Cloudflare to third parties such as the Lumen Database (https://lumendatabase.org/). - comments: Any additional comments about the infringement not exceeding 2000 characters + comments: Any additional comments about the infringement not exceeding 2000 characters. + Comments are kept internal to Cloudflare and not shared with the host or + customer as part of regular processing. For delegated reports, comments may be + shared in full. company: Text not exceeding 100 characters. This field may be released by Cloudflare to third parties such as the Lumen Database (https://lumendatabase.org/). @@ -1859,6 +2122,16 @@ async def create( `Trust and Safety Write` permission. If the account is not entitled, the request is rejected with an HTTP `401` response (see below). + Delegated reports: In limited circumstances, Cloudflare works with select + customers who have established abuse-handling programs. For these customers, + Cloudflare may forward abuse reports directly and in full—including reporter + contact information, comments, and supporting evidence—without redaction or + preprocessing by Cloudflare. This allows the customer to investigate and respond + using their own policies and processes. For delegated reports, the + report—including contact information and comments—will be forwarded to the + customer in full regardless of the `host_notification` and `owner_notification` + values. + Args: report_param: The report type for submitted reports. @@ -1869,7 +2142,9 @@ async def create( email2: Should match the value provided in `email` - host_notification: Notification type based on the abuse type. NOTE: Copyright (DMCA) and Trademark + host_notification: Notification type based on the abuse type. For delegated reports, the + report—including contact information and comments—will be forwarded to the + customer in full regardless of this value. NOTE: Copyright (DMCA) and Trademark reports cannot be anonymous. name: Text not exceeding 255 characters. This field may be released by Cloudflare to @@ -1877,7 +2152,9 @@ async def create( ncsei_subject_representation: If the submitter is the target of NCSEI in the URLs of the abuse report. - owner_notification: Notification type based on the abuse type. NOTE: Copyright (DMCA) and Trademark + owner_notification: Notification type based on the abuse type. For delegated reports, the + report—including contact information and comments—will be forwarded to the + customer in full regardless of this value. NOTE: Copyright (DMCA) and Trademark reports cannot be anonymous. urls: A list of valid URLs separated by ‘\n’ (new line character). The list of the @@ -1885,7 +2162,10 @@ async def create( URL should be unique. This field may be released by Cloudflare to third parties such as the Lumen Database (https://lumendatabase.org/). - comments: Any additional comments about the infringement not exceeding 2000 characters + comments: Any additional comments about the infringement not exceeding 2000 characters. + Comments are kept internal to Cloudflare and not shared with the host or + customer as part of regular processing. For delegated reports, comments may be + shared in full. company: Text not exceeding 100 characters. This field may be released by Cloudflare to third parties such as the Lumen Database (https://lumendatabase.org/). @@ -2094,7 +2374,9 @@ def list( domain: str | Omit = omit, mitigation_status: Literal["pending", "active", "in_review", "cancelled", "removed"] | Omit = omit, page: int | Omit = omit, + pending_notice: bool | Omit = omit, per_page: int | Omit = omit, + search: str | Omit = omit, sort: str | Omit = omit, status: Literal["accepted", "in_review"] | Omit = omit, type: Literal["PHISH", "GEN", "THREAT", "DMCA", "EMER", "TM", "REG_WHO", "NCSEI", "NETWORK"] | Omit = omit, @@ -2121,8 +2403,16 @@ def list( page: Where in pagination to start listing abuse reports + pending_notice: Also include reports in an open Notice and Takedown notice period. Combined with + mitigation_status using OR, e.g. ?mitigation_status=active&pending_notice=true. + per_page: How many abuse reports per page to list + search: Free-text search. Returns reports whose report ID starts with the term or whose + domain contains the term, both case-insensitively. Surrounding whitespace is + ignored, and an empty value is treated as absent. Combined with the other + filters using AND. + sort: A property to sort by, followed by the order (id, cdate, domain, type, status) status: Filter by the status of the report. @@ -2154,7 +2444,9 @@ def list( "domain": domain, "mitigation_status": mitigation_status, "page": page, + "pending_notice": pending_notice, "per_page": per_page, + "search": search, "sort": sort, "status": status, "type": type, diff --git a/src/cloudflare/resources/abuse_reports/mitigations.py b/src/cloudflare/resources/abuse_reports/mitigations.py index 7e7a49375a6..ae0b76e61b8 100644 --- a/src/cloudflare/resources/abuse_reports/mitigations.py +++ b/src/cloudflare/resources/abuse_reports/mitigations.py @@ -145,6 +145,7 @@ def review( account_id: str, appeals: Iterable[mitigation_review_params.Appeal] | Omit = omit, data: mitigation_review_params.Data | Omit = omit, + explanation: str | Omit = omit, type: Literal["counter_notice", "content_removed"] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. @@ -170,6 +171,9 @@ def review( data: Counter-notice details supporting an appeal. + explanation: Optional explanation for a "content_removed" appeal, such as how the content was + removed. Not accepted for other appeal types. + type: The type of appeal being submitted. extra_headers: Send extra headers @@ -195,6 +199,7 @@ def review( { "appeals": appeals, "data": data, + "explanation": explanation, "type": type, }, mitigation_review_params.MitigationReviewParams, @@ -326,6 +331,7 @@ def review( account_id: str, appeals: Iterable[mitigation_review_params.Appeal] | Omit = omit, data: mitigation_review_params.Data | Omit = omit, + explanation: str | Omit = omit, type: Literal["counter_notice", "content_removed"] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. @@ -351,6 +357,9 @@ def review( data: Counter-notice details supporting an appeal. + explanation: Optional explanation for a "content_removed" appeal, such as how the content was + removed. Not accepted for other appeal types. + type: The type of appeal being submitted. extra_headers: Send extra headers @@ -376,6 +385,7 @@ def review( { "appeals": appeals, "data": data, + "explanation": explanation, "type": type, }, mitigation_review_params.MitigationReviewParams, diff --git a/src/cloudflare/resources/accounts/__init__.py b/src/cloudflare/resources/accounts/__init__.py index ae6cab682c0..09d574d6e1a 100644 --- a/src/cloudflare/resources/accounts/__init__.py +++ b/src/cloudflare/resources/accounts/__init__.py @@ -72,14 +72,6 @@ EntitlementsResourceWithStreamingResponse, AsyncEntitlementsResourceWithStreamingResponse, ) -from .pay_bad_debt import ( - PayBadDebtResource, - AsyncPayBadDebtResource, - PayBadDebtResourceWithRawResponse, - AsyncPayBadDebtResourceWithRawResponse, - PayBadDebtResourceWithStreamingResponse, - AsyncPayBadDebtResourceWithStreamingResponse, -) from .client_secret import ( ClientSecretResource, AsyncClientSecretResource, @@ -168,12 +160,6 @@ "AsyncPayInvoiceResourceWithRawResponse", "PayInvoiceResourceWithStreamingResponse", "AsyncPayInvoiceResourceWithStreamingResponse", - "PayBadDebtResource", - "AsyncPayBadDebtResource", - "PayBadDebtResourceWithRawResponse", - "AsyncPayBadDebtResourceWithRawResponse", - "PayBadDebtResourceWithStreamingResponse", - "AsyncPayBadDebtResourceWithStreamingResponse", "ReceiptsResource", "AsyncReceiptsResource", "ReceiptsResourceWithRawResponse", diff --git a/src/cloudflare/resources/accounts/accounts.py b/src/cloudflare/resources/accounts/accounts.py index 126273395d3..039ce08ed5b 100644 --- a/src/cloudflare/resources/accounts/accounts.py +++ b/src/cloudflare/resources/accounts/accounts.py @@ -75,14 +75,6 @@ EntitlementsResourceWithStreamingResponse, AsyncEntitlementsResourceWithStreamingResponse, ) -from .pay_bad_debt import ( - PayBadDebtResource, - AsyncPayBadDebtResource, - PayBadDebtResourceWithRawResponse, - AsyncPayBadDebtResourceWithRawResponse, - PayBadDebtResourceWithStreamingResponse, - AsyncPayBadDebtResourceWithStreamingResponse, -) from .client_secret import ( ClientSecretResource, AsyncClientSecretResource, @@ -168,10 +160,6 @@ def payment_methods(self) -> PaymentMethodsResource: def pay_invoice(self) -> PayInvoiceResource: return PayInvoiceResource(self._client) - @cached_property - def pay_bad_debt(self) -> PayBadDebtResource: - return PayBadDebtResource(self._client) - @cached_property def receipts(self) -> ReceiptsResource: return ReceiptsResource(self._client) @@ -225,14 +213,18 @@ def create( `standalone: true` and omit `unit`. Providing both fields is invalid. If you omit both fields, Cloudflare can determine the destination only when the User is an administrator of exactly one Organization. Cloudflare creates the Account in - that Organization; otherwise, the request returns an error. + that Organization; otherwise, the request returns an error. Account names are + limited to 65 UTF-8 bytes. Args: - name: Account name + name: Account name, limited to 65 UTF-8 bytes. standalone: Set to `true` and omit `unit` to create a standalone Free Account. If provided, this field must be `true`. + type: the type of account being created. For self-serve customers, use standard. for + enterprise customers, use enterprise. + unit: Information related to the tenant unit. Provide its ID and omit `standalone` to create the Account within an Organization. See https://developers.cloudflare.com/tenant/how-to/manage-accounts/. @@ -283,15 +275,16 @@ def update( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Optional[Account]: - """ - Update an existing account. + """Update an existing account. + + Account names are limited to 65 UTF-8 bytes. Args: account_id: Account identifier tag. id: Identifier - name: Account name + name: Account name, limited to 65 UTF-8 bytes. managed_by: Parent container details @@ -503,10 +496,6 @@ def payment_methods(self) -> AsyncPaymentMethodsResource: def pay_invoice(self) -> AsyncPayInvoiceResource: return AsyncPayInvoiceResource(self._client) - @cached_property - def pay_bad_debt(self) -> AsyncPayBadDebtResource: - return AsyncPayBadDebtResource(self._client) - @cached_property def receipts(self) -> AsyncReceiptsResource: return AsyncReceiptsResource(self._client) @@ -560,14 +549,18 @@ async def create( `standalone: true` and omit `unit`. Providing both fields is invalid. If you omit both fields, Cloudflare can determine the destination only when the User is an administrator of exactly one Organization. Cloudflare creates the Account in - that Organization; otherwise, the request returns an error. + that Organization; otherwise, the request returns an error. Account names are + limited to 65 UTF-8 bytes. Args: - name: Account name + name: Account name, limited to 65 UTF-8 bytes. standalone: Set to `true` and omit `unit` to create a standalone Free Account. If provided, this field must be `true`. + type: the type of account being created. For self-serve customers, use standard. for + enterprise customers, use enterprise. + unit: Information related to the tenant unit. Provide its ID and omit `standalone` to create the Account within an Organization. See https://developers.cloudflare.com/tenant/how-to/manage-accounts/. @@ -618,15 +611,16 @@ async def update( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Optional[Account]: - """ - Update an existing account. + """Update an existing account. + + Account names are limited to 65 UTF-8 bytes. Args: account_id: Account identifier tag. id: Identifier - name: Account name + name: Account name, limited to 65 UTF-8 bytes. managed_by: Parent container details @@ -857,10 +851,6 @@ def payment_methods(self) -> PaymentMethodsResourceWithRawResponse: def pay_invoice(self) -> PayInvoiceResourceWithRawResponse: return PayInvoiceResourceWithRawResponse(self._accounts.pay_invoice) - @cached_property - def pay_bad_debt(self) -> PayBadDebtResourceWithRawResponse: - return PayBadDebtResourceWithRawResponse(self._accounts.pay_bad_debt) - @cached_property def receipts(self) -> ReceiptsResourceWithRawResponse: return ReceiptsResourceWithRawResponse(self._accounts.receipts) @@ -930,10 +920,6 @@ def payment_methods(self) -> AsyncPaymentMethodsResourceWithRawResponse: def pay_invoice(self) -> AsyncPayInvoiceResourceWithRawResponse: return AsyncPayInvoiceResourceWithRawResponse(self._accounts.pay_invoice) - @cached_property - def pay_bad_debt(self) -> AsyncPayBadDebtResourceWithRawResponse: - return AsyncPayBadDebtResourceWithRawResponse(self._accounts.pay_bad_debt) - @cached_property def receipts(self) -> AsyncReceiptsResourceWithRawResponse: return AsyncReceiptsResourceWithRawResponse(self._accounts.receipts) @@ -1003,10 +989,6 @@ def payment_methods(self) -> PaymentMethodsResourceWithStreamingResponse: def pay_invoice(self) -> PayInvoiceResourceWithStreamingResponse: return PayInvoiceResourceWithStreamingResponse(self._accounts.pay_invoice) - @cached_property - def pay_bad_debt(self) -> PayBadDebtResourceWithStreamingResponse: - return PayBadDebtResourceWithStreamingResponse(self._accounts.pay_bad_debt) - @cached_property def receipts(self) -> ReceiptsResourceWithStreamingResponse: return ReceiptsResourceWithStreamingResponse(self._accounts.receipts) @@ -1076,10 +1058,6 @@ def payment_methods(self) -> AsyncPaymentMethodsResourceWithStreamingResponse: def pay_invoice(self) -> AsyncPayInvoiceResourceWithStreamingResponse: return AsyncPayInvoiceResourceWithStreamingResponse(self._accounts.pay_invoice) - @cached_property - def pay_bad_debt(self) -> AsyncPayBadDebtResourceWithStreamingResponse: - return AsyncPayBadDebtResourceWithStreamingResponse(self._accounts.pay_bad_debt) - @cached_property def receipts(self) -> AsyncReceiptsResourceWithStreamingResponse: return AsyncReceiptsResourceWithStreamingResponse(self._accounts.receipts) diff --git a/src/cloudflare/resources/accounts/api.md b/src/cloudflare/resources/accounts/api.md index bffbc60e17b..1495b4399a1 100644 --- a/src/cloudflare/resources/accounts/api.md +++ b/src/cloudflare/resources/accounts/api.md @@ -89,7 +89,7 @@ from cloudflare.types.accounts.subscriptions import BulkCreateResponse Methods: -- client.accounts.subscriptions.bulk.create(\*, account_id, \*\*params) -> Optional[BulkCreateResponse] +- client.accounts.subscriptions.bulk.create(\*, account_id, \*\*params) -> BulkCreateResponse ## Tokens @@ -209,18 +209,6 @@ Methods: - client.accounts.pay_invoice.create(\*, account_id, \*\*params) -> PayInvoiceCreateResponse -## PayBadDebt - -Types: - -```python -from cloudflare.types.accounts import PayBadDebtCreateResponse -``` - -Methods: - -- client.accounts.pay_bad_debt.create(\*, account_id, \*\*params) -> PayBadDebtCreateResponse - ## Receipts Methods: diff --git a/src/cloudflare/resources/accounts/pay_bad_debt.py b/src/cloudflare/resources/accounts/pay_bad_debt.py deleted file mode 100644 index a4e7c73636f..00000000000 --- a/src/cloudflare/resources/accounts/pay_bad_debt.py +++ /dev/null @@ -1,196 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing import Type, cast - -import httpx - -from ..._types import Body, Omit, Query, Headers, NotGiven, omit, not_given -from ..._utils import path_template, maybe_transform, async_maybe_transform -from ..._compat import cached_property -from ..._resource import SyncAPIResource, AsyncAPIResource -from ..._response import ( - to_raw_response_wrapper, - to_streamed_response_wrapper, - async_to_raw_response_wrapper, - async_to_streamed_response_wrapper, -) -from ..._wrappers import ResultWrapper -from ..._base_client import make_request_options -from ...types.accounts import pay_bad_debt_create_params -from ...types.accounts.pay_bad_debt_create_response import PayBadDebtCreateResponse - -__all__ = ["PayBadDebtResource", "AsyncPayBadDebtResource"] - - -class PayBadDebtResource(SyncAPIResource): - @cached_property - def with_raw_response(self) -> PayBadDebtResourceWithRawResponse: - """ - This property can be used as a prefix for any HTTP method call to return - the raw response object instead of the parsed content. - - For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers - """ - return PayBadDebtResourceWithRawResponse(self) - - @cached_property - def with_streaming_response(self) -> PayBadDebtResourceWithStreamingResponse: - """ - An alternative to `.with_raw_response` that doesn't eagerly read the response body. - - For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response - """ - return PayBadDebtResourceWithStreamingResponse(self) - - def create( - self, - *, - account_id: str, - payment_method_id: str | Omit = omit, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> PayBadDebtCreateResponse: - """Pays outstanding bad debt for an account. - - Discovers all debt automatically and - handles invoice deduplication. - - Args: - account_id: Identifier - - payment_method_id: The payment method to use. If omitted, the default payment method is used. - - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not account_id: - raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - return self._post( - path_template("/accounts/{account_id}/pay-bad-debt", account_id=account_id), - body=maybe_transform( - {"payment_method_id": payment_method_id}, pay_bad_debt_create_params.PayBadDebtCreateParams - ), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - post_parser=ResultWrapper[PayBadDebtCreateResponse]._unwrapper, - ), - cast_to=cast(Type[PayBadDebtCreateResponse], ResultWrapper[PayBadDebtCreateResponse]), - ) - - -class AsyncPayBadDebtResource(AsyncAPIResource): - @cached_property - def with_raw_response(self) -> AsyncPayBadDebtResourceWithRawResponse: - """ - This property can be used as a prefix for any HTTP method call to return - the raw response object instead of the parsed content. - - For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers - """ - return AsyncPayBadDebtResourceWithRawResponse(self) - - @cached_property - def with_streaming_response(self) -> AsyncPayBadDebtResourceWithStreamingResponse: - """ - An alternative to `.with_raw_response` that doesn't eagerly read the response body. - - For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response - """ - return AsyncPayBadDebtResourceWithStreamingResponse(self) - - async def create( - self, - *, - account_id: str, - payment_method_id: str | Omit = omit, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> PayBadDebtCreateResponse: - """Pays outstanding bad debt for an account. - - Discovers all debt automatically and - handles invoice deduplication. - - Args: - account_id: Identifier - - payment_method_id: The payment method to use. If omitted, the default payment method is used. - - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not account_id: - raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - return await self._post( - path_template("/accounts/{account_id}/pay-bad-debt", account_id=account_id), - body=await async_maybe_transform( - {"payment_method_id": payment_method_id}, pay_bad_debt_create_params.PayBadDebtCreateParams - ), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - post_parser=ResultWrapper[PayBadDebtCreateResponse]._unwrapper, - ), - cast_to=cast(Type[PayBadDebtCreateResponse], ResultWrapper[PayBadDebtCreateResponse]), - ) - - -class PayBadDebtResourceWithRawResponse: - def __init__(self, pay_bad_debt: PayBadDebtResource) -> None: - self._pay_bad_debt = pay_bad_debt - - self.create = to_raw_response_wrapper( - pay_bad_debt.create, - ) - - -class AsyncPayBadDebtResourceWithRawResponse: - def __init__(self, pay_bad_debt: AsyncPayBadDebtResource) -> None: - self._pay_bad_debt = pay_bad_debt - - self.create = async_to_raw_response_wrapper( - pay_bad_debt.create, - ) - - -class PayBadDebtResourceWithStreamingResponse: - def __init__(self, pay_bad_debt: PayBadDebtResource) -> None: - self._pay_bad_debt = pay_bad_debt - - self.create = to_streamed_response_wrapper( - pay_bad_debt.create, - ) - - -class AsyncPayBadDebtResourceWithStreamingResponse: - def __init__(self, pay_bad_debt: AsyncPayBadDebtResource) -> None: - self._pay_bad_debt = pay_bad_debt - - self.create = async_to_streamed_response_wrapper( - pay_bad_debt.create, - ) diff --git a/src/cloudflare/resources/accounts/subscriptions/bulk.py b/src/cloudflare/resources/accounts/subscriptions/bulk.py index 4b816bfe91d..315a2721d03 100644 --- a/src/cloudflare/resources/accounts/subscriptions/bulk.py +++ b/src/cloudflare/resources/accounts/subscriptions/bulk.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing import Type, Iterable, Optional, cast +from typing import Type, Iterable, cast import httpx @@ -60,7 +60,7 @@ def create( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> Optional[BulkCreateResponse]: + ) -> BulkCreateResponse: """ Creates multiple subscriptions for an account in a single request. @@ -94,9 +94,9 @@ def create( extra_body=extra_body, timeout=timeout, query=maybe_transform({"idemp_key": idemp_key}, bulk_create_params.BulkCreateParams), - post_parser=ResultWrapper[Optional[BulkCreateResponse]]._unwrapper, + post_parser=ResultWrapper[BulkCreateResponse]._unwrapper, ), - cast_to=cast(Type[Optional[BulkCreateResponse]], ResultWrapper[BulkCreateResponse]), + cast_to=cast(Type[BulkCreateResponse], ResultWrapper[BulkCreateResponse]), ) @@ -135,7 +135,7 @@ async def create( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> Optional[BulkCreateResponse]: + ) -> BulkCreateResponse: """ Creates multiple subscriptions for an account in a single request. @@ -169,9 +169,9 @@ async def create( extra_body=extra_body, timeout=timeout, query=await async_maybe_transform({"idemp_key": idemp_key}, bulk_create_params.BulkCreateParams), - post_parser=ResultWrapper[Optional[BulkCreateResponse]]._unwrapper, + post_parser=ResultWrapper[BulkCreateResponse]._unwrapper, ), - cast_to=cast(Type[Optional[BulkCreateResponse]], ResultWrapper[BulkCreateResponse]), + cast_to=cast(Type[BulkCreateResponse], ResultWrapper[BulkCreateResponse]), ) diff --git a/src/cloudflare/resources/ai_gateway/ai_gateway.py b/src/cloudflare/resources/ai_gateway/ai_gateway.py index 9fc0b74636f..f5bdbd500f3 100644 --- a/src/cloudflare/resources/ai_gateway/ai_gateway.py +++ b/src/cloudflare/resources/ai_gateway/ai_gateway.py @@ -202,6 +202,9 @@ def create( Args: id: Unique identifier of the AI Gateway within the account. + authentication: Require authentication for gateway access. New gateways must have authentication + enabled. Once enabled, authentication cannot be disabled. + byok_only: Requires customer-provided provider credentials and prevents fallback to Unified Billing. @@ -211,6 +214,9 @@ def create( retry_max_attempts: Maximum number of retry attempts for failed requests (1-5) + store_id: Secrets Store used by this gateway. Omit on update to keep the current store. + Cannot be cleared while stored keys or secret references depend on it. + workers_ai_billing_mode: Controls how Workers AI inference calls routed through this gateway are billed. 'postpaid' bills the account directly through Workers AI; 'unified' deducts credits via AI Gateway using neuron-based pricing and delegates billing to AI @@ -311,6 +317,9 @@ def update( Args: id: Unique identifier of the AI Gateway within the account. + authentication: Require authentication for gateway access. New gateways must have authentication + enabled. Once enabled, authentication cannot be disabled. + byok_only: Requires customer-provided provider credentials and prevents fallback to Unified Billing. @@ -320,6 +329,9 @@ def update( retry_max_attempts: Maximum number of retry attempts for failed requests (1-5) + store_id: Secrets Store used by this gateway. Omit on update to keep the current store. + Cannot be cleared while stored keys or secret references depend on it. + workers_ai_billing_mode: Controls how Workers AI inference calls routed through this gateway are billed. 'postpaid' bills the account directly through Workers AI; 'unified' deducts credits via AI Gateway using neuron-based pricing and delegates billing to AI @@ -614,6 +626,9 @@ async def create( Args: id: Unique identifier of the AI Gateway within the account. + authentication: Require authentication for gateway access. New gateways must have authentication + enabled. Once enabled, authentication cannot be disabled. + byok_only: Requires customer-provided provider credentials and prevents fallback to Unified Billing. @@ -623,6 +638,9 @@ async def create( retry_max_attempts: Maximum number of retry attempts for failed requests (1-5) + store_id: Secrets Store used by this gateway. Omit on update to keep the current store. + Cannot be cleared while stored keys or secret references depend on it. + workers_ai_billing_mode: Controls how Workers AI inference calls routed through this gateway are billed. 'postpaid' bills the account directly through Workers AI; 'unified' deducts credits via AI Gateway using neuron-based pricing and delegates billing to AI @@ -723,6 +741,9 @@ async def update( Args: id: Unique identifier of the AI Gateway within the account. + authentication: Require authentication for gateway access. New gateways must have authentication + enabled. Once enabled, authentication cannot be disabled. + byok_only: Requires customer-provided provider credentials and prevents fallback to Unified Billing. @@ -732,6 +753,9 @@ async def update( retry_max_attempts: Maximum number of retry attempts for failed requests (1-5) + store_id: Secrets Store used by this gateway. Omit on update to keep the current store. + Cannot be cleared while stored keys or secret references depend on it. + workers_ai_billing_mode: Controls how Workers AI inference calls routed through this gateway are billed. 'postpaid' bills the account directly through Workers AI; 'unified' deducts credits via AI Gateway using neuron-based pricing and delegates billing to AI diff --git a/src/cloudflare/resources/ai_gateway/billing/billing.py b/src/cloudflare/resources/ai_gateway/billing/billing.py index 4229618032c..f5610436453 100644 --- a/src/cloudflare/resources/ai_gateway/billing/billing.py +++ b/src/cloudflare/resources/ai_gateway/billing/billing.py @@ -203,7 +203,8 @@ def usage_history( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> BillingUsageHistoryResponse: """ - Retrieve aggregated usage meter event summaries for the given time range. + Retrieve AI Gateway usage cost, in US dollars, aggregated by hour or day for the + given time range. Args: value_grouping_window: Grouping window for usage data. @@ -404,7 +405,8 @@ async def usage_history( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> BillingUsageHistoryResponse: """ - Retrieve aggregated usage meter event summaries for the given time range. + Retrieve AI Gateway usage cost, in US dollars, aggregated by hour or day for the + given time range. Args: value_grouping_window: Grouping window for usage data. diff --git a/src/cloudflare/resources/ai_gateway/billing/topup/config.py b/src/cloudflare/resources/ai_gateway/billing/topup/config.py index ccb25ae21a7..4159cf2efc3 100644 --- a/src/cloudflare/resources/ai_gateway/billing/topup/config.py +++ b/src/cloudflare/resources/ai_gateway/billing/topup/config.py @@ -2,12 +2,13 @@ from __future__ import annotations -from typing import Type, cast +from typing import Any, Type, cast +from typing_extensions import overload import httpx -from ....._types import Body, Query, Headers, NotGiven, not_given -from ....._utils import path_template, maybe_transform, async_maybe_transform +from ....._types import Body, Omit, Query, Headers, NotGiven, omit, not_given +from ....._utils import path_template, required_args, maybe_transform, async_maybe_transform from ....._compat import cached_property from ....._resource import SyncAPIResource, AsyncAPIResource from ....._response import ( @@ -45,6 +46,7 @@ def with_streaming_response(self) -> ConfigResourceWithStreamingResponse: """ return ConfigResourceWithStreamingResponse(self) + @overload def create( self, *, @@ -60,8 +62,10 @@ def create( ) -> ConfigCreateResponse: """Configure auto top-up with a balance threshold and top-up amount. - Dashboard - sessions only: API token, OAuth, and service credentials are rejected with 403. + Requests that + add a payment method first return authentication details. The configuration is + saved only after the authenticated setup is submitted. Dashboard sessions only: + API token, OAuth, and service credentials are rejected with 403. Args: amount: Auto top-up amount in cents (min 1000). @@ -76,25 +80,105 @@ def create( timeout: Override the client-level default timeout for this request, in seconds """ + ... + + @overload + def create( + self, + *, + account_id: str, + amount: int, + consent_version: str, + payment_method_id: str, + setup_idempotency_key: str, + threshold: int, + setup_intent_id: str | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> ConfigCreateResponse: + """Configure auto top-up with a balance threshold and top-up amount. + + Requests that + add a payment method first return authentication details. The configuration is + saved only after the authenticated setup is submitted. Dashboard sessions only: + API token, OAuth, and service credentials are rejected with 403. + + Args: + amount: Auto top-up amount in cents (min 1000). + + consent_version: Version of the off-session auto-top-up consent accepted by the user. + + payment_method_id: Card to authenticate for future automatic top-ups. + + setup_idempotency_key: Client-generated UUID that makes payment-method setup safe to retry. + + threshold: Balance threshold in cents that triggers auto top-up (min 500). + + setup_intent_id: Successfully confirmed payment-method setup identifier. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + ... + + @required_args( + ["account_id", "amount", "threshold"], + ["account_id", "amount", "consent_version", "payment_method_id", "setup_idempotency_key", "threshold"], + ) + def create( + self, + *, + account_id: str, + amount: int, + threshold: int, + consent_version: str | Omit = omit, + payment_method_id: str | Omit = omit, + setup_idempotency_key: str | Omit = omit, + setup_intent_id: str | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> ConfigCreateResponse: if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - return self._post( - path_template("/accounts/{account_id}/ai-gateway/billing/topup/config", account_id=account_id), - body=maybe_transform( - { - "amount": amount, - "threshold": threshold, - }, - config_create_params.ConfigCreateParams, - ), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - post_parser=ResultWrapper[ConfigCreateResponse]._unwrapper, + return cast( + ConfigCreateResponse, + self._post( + path_template("/accounts/{account_id}/ai-gateway/billing/topup/config", account_id=account_id), + body=maybe_transform( + { + "amount": amount, + "threshold": threshold, + "consent_version": consent_version, + "payment_method_id": payment_method_id, + "setup_idempotency_key": setup_idempotency_key, + "setup_intent_id": setup_intent_id, + }, + config_create_params.ConfigCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[ConfigCreateResponse]._unwrapper, + ), + cast_to=cast( + Any, ResultWrapper[ConfigCreateResponse] + ), # Union types cannot be passed in as arguments in the type system ), - cast_to=cast(Type[ConfigCreateResponse], ResultWrapper[ConfigCreateResponse]), ) def delete( @@ -194,6 +278,7 @@ def with_streaming_response(self) -> AsyncConfigResourceWithStreamingResponse: """ return AsyncConfigResourceWithStreamingResponse(self) + @overload async def create( self, *, @@ -209,8 +294,10 @@ async def create( ) -> ConfigCreateResponse: """Configure auto top-up with a balance threshold and top-up amount. - Dashboard - sessions only: API token, OAuth, and service credentials are rejected with 403. + Requests that + add a payment method first return authentication details. The configuration is + saved only after the authenticated setup is submitted. Dashboard sessions only: + API token, OAuth, and service credentials are rejected with 403. Args: amount: Auto top-up amount in cents (min 1000). @@ -225,25 +312,105 @@ async def create( timeout: Override the client-level default timeout for this request, in seconds """ + ... + + @overload + async def create( + self, + *, + account_id: str, + amount: int, + consent_version: str, + payment_method_id: str, + setup_idempotency_key: str, + threshold: int, + setup_intent_id: str | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> ConfigCreateResponse: + """Configure auto top-up with a balance threshold and top-up amount. + + Requests that + add a payment method first return authentication details. The configuration is + saved only after the authenticated setup is submitted. Dashboard sessions only: + API token, OAuth, and service credentials are rejected with 403. + + Args: + amount: Auto top-up amount in cents (min 1000). + + consent_version: Version of the off-session auto-top-up consent accepted by the user. + + payment_method_id: Card to authenticate for future automatic top-ups. + + setup_idempotency_key: Client-generated UUID that makes payment-method setup safe to retry. + + threshold: Balance threshold in cents that triggers auto top-up (min 500). + + setup_intent_id: Successfully confirmed payment-method setup identifier. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + ... + + @required_args( + ["account_id", "amount", "threshold"], + ["account_id", "amount", "consent_version", "payment_method_id", "setup_idempotency_key", "threshold"], + ) + async def create( + self, + *, + account_id: str, + amount: int, + threshold: int, + consent_version: str | Omit = omit, + payment_method_id: str | Omit = omit, + setup_idempotency_key: str | Omit = omit, + setup_intent_id: str | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> ConfigCreateResponse: if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - return await self._post( - path_template("/accounts/{account_id}/ai-gateway/billing/topup/config", account_id=account_id), - body=await async_maybe_transform( - { - "amount": amount, - "threshold": threshold, - }, - config_create_params.ConfigCreateParams, - ), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - post_parser=ResultWrapper[ConfigCreateResponse]._unwrapper, + return cast( + ConfigCreateResponse, + await self._post( + path_template("/accounts/{account_id}/ai-gateway/billing/topup/config", account_id=account_id), + body=await async_maybe_transform( + { + "amount": amount, + "threshold": threshold, + "consent_version": consent_version, + "payment_method_id": payment_method_id, + "setup_idempotency_key": setup_idempotency_key, + "setup_intent_id": setup_intent_id, + }, + config_create_params.ConfigCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[ConfigCreateResponse]._unwrapper, + ), + cast_to=cast( + Any, ResultWrapper[ConfigCreateResponse] + ), # Union types cannot be passed in as arguments in the type system ), - cast_to=cast(Type[ConfigCreateResponse], ResultWrapper[ConfigCreateResponse]), ) async def delete( diff --git a/src/cloudflare/resources/ai_gateway/billing/topup/topup.py b/src/cloudflare/resources/ai_gateway/billing/topup/topup.py index 34d5114426e..5bc5303c3da 100644 --- a/src/cloudflare/resources/ai_gateway/billing/topup/topup.py +++ b/src/cloudflare/resources/ai_gateway/billing/topup/topup.py @@ -72,12 +72,13 @@ def create( ) -> TopupCreateResponse: """ Create a credit top-up for the given account, charged to the account's default - payment method. + payment method. Requires a dashboard session; API token, OAuth, and service + credentials receive 403. Args: amount: Top-up amount in cents (min 1000). - payment_method_id: Stripe PaymentMethod to charge instead of the customer's default payment method. + payment_method_id: Payment method to charge instead of the customer's default payment method. extra_headers: Send extra headers @@ -121,10 +122,10 @@ def status( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> TopupStatusResponse: """ - Get the payment processing status of a top-up by its invoice ID. + Get the payment processing status of a top-up by its top-up identifier. Args: - payment_intent_id: Stripe invoice ID to check status for. + payment_intent_id: Top-up identifier to check status for. extra_headers: Send extra headers @@ -189,12 +190,13 @@ async def create( ) -> TopupCreateResponse: """ Create a credit top-up for the given account, charged to the account's default - payment method. + payment method. Requires a dashboard session; API token, OAuth, and service + credentials receive 403. Args: amount: Top-up amount in cents (min 1000). - payment_method_id: Stripe PaymentMethod to charge instead of the customer's default payment method. + payment_method_id: Payment method to charge instead of the customer's default payment method. extra_headers: Send extra headers @@ -238,10 +240,10 @@ async def status( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> TopupStatusResponse: """ - Get the payment processing status of a top-up by its invoice ID. + Get the payment processing status of a top-up by its top-up identifier. Args: - payment_intent_id: Stripe invoice ID to check status for. + payment_intent_id: Top-up identifier to check status for. extra_headers: Send extra headers diff --git a/src/cloudflare/resources/ai_security/custom_topics.py b/src/cloudflare/resources/ai_security/custom_topics.py index 1a0d82aa9f7..9ae696441cd 100644 --- a/src/cloudflare/resources/ai_security/custom_topics.py +++ b/src/cloudflare/resources/ai_security/custom_topics.py @@ -69,7 +69,9 @@ def update( - A zone can hold at most 20 topics. - `label` must be 2–20 characters, using only lowercase letters (a–z), digits (0–9), and hyphens. - - `topic` must be 2–50 printable ASCII characters. + - `topic` must be 2–50 UTF-8 bytes. Text in any language is supported, including + spaces, numbers, punctuation, and symbols. Tabs, line breaks, invalid text, + and invisible formatting characters are not allowed. - Labels must be unique within the zone, and so must topic descriptions. Args: @@ -189,7 +191,9 @@ async def update( - A zone can hold at most 20 topics. - `label` must be 2–20 characters, using only lowercase letters (a–z), digits (0–9), and hyphens. - - `topic` must be 2–50 printable ASCII characters. + - `topic` must be 2–50 UTF-8 bytes. Text in any language is supported, including + spaces, numbers, punctuation, and symbols. Tabs, line breaks, invalid text, + and invisible formatting characters are not allowed. - Labels must be unique within the zone, and so must topic descriptions. Args: diff --git a/src/cloudflare/resources/aisearch/api.md b/src/cloudflare/resources/aisearch/api.md index f861fd17930..c2b5ede370c 100644 --- a/src/cloudflare/resources/aisearch/api.md +++ b/src/cloudflare/resources/aisearch/api.md @@ -44,14 +44,15 @@ from cloudflare.types.aisearch.namespaces import ( Methods: -- client.aisearch.namespaces.instances.create(name, \*, account_id, \*\*params) -> InstanceCreateResponse -- client.aisearch.namespaces.instances.update(id, \*, account_id, name, \*\*params) -> InstanceUpdateResponse -- client.aisearch.namespaces.instances.list(name, \*, account_id, \*\*params) -> SyncV4PagePaginationArray[InstanceListResponse] -- client.aisearch.namespaces.instances.delete(id, \*, account_id, name) -> InstanceDeleteResponse -- client.aisearch.namespaces.instances.chat_completions(id, \*, account_id, name, \*\*params) -> InstanceChatCompletionsResponse -- client.aisearch.namespaces.instances.read(id, \*, account_id, name) -> InstanceReadResponse -- client.aisearch.namespaces.instances.search(id, \*, account_id, name, \*\*params) -> InstanceSearchResponse -- client.aisearch.namespaces.instances.stats(id, \*, account_id, name) -> InstanceStatsResponse +- client.aisearch.namespaces.instances.create(namespace, \*, account_id, \*\*params) -> InstanceCreateResponse +- client.aisearch.namespaces.instances.update(id, \*, account_id, namespace, \*\*params) -> InstanceUpdateResponse +- client.aisearch.namespaces.instances.list(namespace, \*, account_id, \*\*params) -> SyncV4PagePaginationArray[InstanceListResponse] +- client.aisearch.namespaces.instances.delete(id, \*, account_id, namespace) -> InstanceDeleteResponse +- client.aisearch.namespaces.instances.chat_completions(id, \*, account_id, namespace, \*\*params) -> InstanceChatCompletionsResponse +- client.aisearch.namespaces.instances.move(id, \*, account_id, namespace, \*\*params) -> object +- client.aisearch.namespaces.instances.read(id, \*, account_id, namespace) -> InstanceReadResponse +- client.aisearch.namespaces.instances.search(id, \*, account_id, namespace, \*\*params) -> InstanceSearchResponse +- client.aisearch.namespaces.instances.stats(id, \*, account_id, namespace) -> InstanceStatsResponse #### Jobs @@ -69,11 +70,11 @@ from cloudflare.types.aisearch.namespaces.instances import ( Methods: -- client.aisearch.namespaces.instances.jobs.create(id, \*, account_id, name, \*\*params) -> JobCreateResponse -- client.aisearch.namespaces.instances.jobs.update(job_id, \*, account_id, name, id, \*\*params) -> JobUpdateResponse -- client.aisearch.namespaces.instances.jobs.list(id, \*, account_id, name, \*\*params) -> SyncV4PagePaginationArray[JobListResponse] -- client.aisearch.namespaces.instances.jobs.get(job_id, \*, account_id, name, id) -> JobGetResponse -- client.aisearch.namespaces.instances.jobs.logs(job_id, \*, account_id, name, id, \*\*params) -> JobLogsResponse +- client.aisearch.namespaces.instances.jobs.create(id, \*, account_id, namespace, \*\*params) -> JobCreateResponse +- client.aisearch.namespaces.instances.jobs.update(job_id, \*, account_id, namespace, id, \*\*params) -> JobUpdateResponse +- client.aisearch.namespaces.instances.jobs.list(id, \*, account_id, namespace, \*\*params) -> SyncV4PagePaginationArray[JobListResponse] +- client.aisearch.namespaces.instances.jobs.get(job_id, \*, account_id, namespace, id) -> JobGetResponse +- client.aisearch.namespaces.instances.jobs.logs(job_id, \*, account_id, namespace, id, \*\*params) -> JobLogsResponse #### Items @@ -94,15 +95,15 @@ from cloudflare.types.aisearch.namespaces.instances import ( Methods: -- client.aisearch.namespaces.instances.items.list(id, \*, account_id, name, \*\*params) -> SyncV4PagePaginationArray[ItemListResponse] -- client.aisearch.namespaces.instances.items.delete(item_id, \*, account_id, name, id) -> ItemDeleteResponse -- client.aisearch.namespaces.instances.items.chunks(item_id, \*, account_id, name, id, \*\*params) -> ItemChunksResponse -- client.aisearch.namespaces.instances.items.create_or_update(id, \*, account_id, name, \*\*params) -> ItemCreateOrUpdateResponse -- client.aisearch.namespaces.instances.items.download(item_id, \*, account_id, name, id) -> BinaryAPIResponse -- client.aisearch.namespaces.instances.items.get(item_id, \*, account_id, name, id) -> ItemGetResponse -- client.aisearch.namespaces.instances.items.logs(item_id, \*, account_id, name, id, \*\*params) -> ItemLogsResponse -- client.aisearch.namespaces.instances.items.sync(item_id, \*, account_id, name, id, \*\*params) -> ItemSyncResponse -- client.aisearch.namespaces.instances.items.upload(id, \*, account_id, name, \*\*params) -> ItemUploadResponse +- client.aisearch.namespaces.instances.items.list(id, \*, account_id, namespace, \*\*params) -> SyncV4PagePaginationArray[ItemListResponse] +- client.aisearch.namespaces.instances.items.delete(item_id, \*, account_id, namespace, id) -> ItemDeleteResponse +- client.aisearch.namespaces.instances.items.chunks(item_id, \*, account_id, namespace, id, \*\*params) -> ItemChunksResponse +- client.aisearch.namespaces.instances.items.create_or_update(id, \*, account_id, namespace, \*\*params) -> ItemCreateOrUpdateResponse +- client.aisearch.namespaces.instances.items.download(item_id, \*, account_id, namespace, id) -> BinaryAPIResponse +- client.aisearch.namespaces.instances.items.get(item_id, \*, account_id, namespace, id) -> ItemGetResponse +- client.aisearch.namespaces.instances.items.logs(item_id, \*, account_id, namespace, id, \*\*params) -> ItemLogsResponse +- client.aisearch.namespaces.instances.items.sync(item_id, \*, account_id, namespace, id, \*\*params) -> ItemSyncResponse +- client.aisearch.namespaces.instances.items.upload(id, \*, account_id, namespace, \*\*params) -> ItemUploadResponse ## Instances diff --git a/src/cloudflare/resources/aisearch/instances/instances.py b/src/cloudflare/resources/aisearch/instances/instances.py index 6882a0b1354..af796a9752c 100644 --- a/src/cloudflare/resources/aisearch/instances/instances.py +++ b/src/cloudflare/resources/aisearch/instances/instances.py @@ -117,12 +117,13 @@ def create( """Create a new AI Search instance with the given configuration. If type is omitted - or null, a non-blank HTTP(S) source infers web-crawler and an existing R2 bucket - source infers r2. A missing or blank source without a type creates a managed - upload-only instance. Search for Agents instances require the default namespace. + or null, a non-blank HTTP(S) source infers web-crawler and any other source + infers r2; r2 sources must name an existing bucket. A missing or blank source + without a type creates a managed upload-only instance. - Deprecated: use /accounts/{account_id}/ai-search/namespaces/{name}/instances - (and descendant paths) instead. + Deprecated: use + /accounts/{account_id}/ai-search/namespaces/{namespace}/instances (and + descendant paths) instead. Args: id: AI Search instance ID. Lowercase alphanumeric, hyphens, and underscores. @@ -137,14 +138,17 @@ def create( hybrid_search_enabled: Deprecated — use index_method instead. Defaults to true for new instances; set false to create a vector-only instance. - index_method: Controls which storage backends are used during indexing. Defaults to vector and - keyword indexing for new instances. + index_method: Controls which storage backends indexing uses. Defaults to vector and keyword + indexing for new instances. When set, both vector and keyword are required. rewrite_model: A Workers AI model ID or an AI Gateway model ID compatible with the OpenAI Chat Completions API. An empty string uses the configured or default model. + score_threshold: Minimum similarity score a chunk must reach to be returned. Defaults to 0.4. + sync_interval: Interval between automatic syncs, in seconds. Allowed values: 900 (15min), 1800 (30min), 3600 (1h), 7200 (2h), 14400 (4h), 21600 (6h), 43200 (12h), 86400 (24h). + Defaults to 86400 (24h). type: Source type. When omitted or null with a non-blank source, HTTP(S) URLs infer web-crawler and existing R2 bucket names infer r2. A missing or blank source @@ -252,15 +256,12 @@ def update( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> InstanceUpdateResponse: - """Update an AI Search instance. - - Submitting Search for Agents metadata requires the - default namespace; omitting or removing it is allowed elsewhere. Submit Search - for Agents metadata and restrictive or unknown public endpoint changes or custom - domains in separate PUT requests, even when resubmitting unchanged metadata. + """ + Updates the configuration of an AI Search instance. - Deprecated: use /accounts/{account_id}/ai-search/namespaces/{name}/instances - (and descendant paths) instead. + Deprecated: use + /accounts/{account_id}/ai-search/namespaces/{namespace}/instances (and + descendant paths) instead. Args: aisearch_model: A Workers AI model ID or an AI Gateway model ID compatible with the OpenAI Chat @@ -270,14 +271,17 @@ def update( (1h), 7200 (2h), 21600 (6h), 43200 (12h), 86400 (24h), 172800 (48h), 259200 (72h), 518400 (6d). - index_method: Controls which storage backends are used during indexing. Defaults to vector and - keyword indexing for new instances. + index_method: Controls which storage backends indexing uses. Defaults to vector and keyword + indexing for new instances. When set, both vector and keyword are required. rewrite_model: A Workers AI model ID or an AI Gateway model ID compatible with the OpenAI Chat Completions API. An empty string uses the configured or default model. + score_threshold: Minimum similarity score a chunk must reach to be returned. Defaults to 0.4. + sync_interval: Interval between automatic syncs, in seconds. Allowed values: 900 (15min), 1800 (30min), 3600 (1h), 7200 (2h), 14400 (4h), 21600 (6h), 43200 (12h), 86400 (24h). + Defaults to 86400 (24h). extra_headers: Send extra headers @@ -360,15 +364,17 @@ def list( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> SyncV4PagePaginationArray[InstanceListResponse]: """ - List all AI Search instances in the account. + Lists all AI Search instances in the account. - Deprecated: use /accounts/{account_id}/ai-search/namespaces/{name}/instances - (and descendant paths) instead. + Deprecated: use + /accounts/{account_id}/ai-search/namespaces/{namespace}/instances (and + descendant paths) instead. Args: - hostname: Filter by exact Search for Agents hostname (case-insensitive). + hostname: Return only instances with this exact Search for Agents hostname + (case-insensitive). - namespace: Filter by namespace. + namespace: Return only instances in this namespace. order_by: Field to order results by. @@ -428,10 +434,11 @@ def delete( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> InstanceDeleteResponse: """ - Permanently delete an AI Search instance and all its indexed data. + Deletes an AI Search instance and all its indexed data permanently. - Deprecated: use /accounts/{account_id}/ai-search/namespaces/{name}/instances - (and descendant paths) instead. + Deprecated: use + /accounts/{account_id}/ai-search/namespaces/{namespace}/instances (and + descendant paths) instead. Args: extra_headers: Send extra headers @@ -479,8 +486,9 @@ def chat_completions( Performs a chat completion request against an AI Search instance, using indexed content as context for generating responses. - Deprecated: use /accounts/{account_id}/ai-search/namespaces/{name}/instances - (and descendant paths) instead. + Deprecated: use + /accounts/{account_id}/ai-search/namespaces/{namespace}/instances (and + descendant paths) instead. Args: id: AI Search instance ID. Lowercase alphanumeric, hyphens, and underscores. @@ -535,8 +543,9 @@ def read( """ Retrieve the configuration and status of an AI Search instance. - Deprecated: use /accounts/{account_id}/ai-search/namespaces/{name}/instances - (and descendant paths) instead. + Deprecated: use + /accounts/{account_id}/ai-search/namespaces/{namespace}/instances (and + descendant paths) instead. Args: extra_headers: Send extra headers @@ -583,8 +592,9 @@ def search( Executes a semantic search query against an AI Search instance to find relevant indexed content. - Deprecated: use /accounts/{account_id}/ai-search/namespaces/{name}/instances - (and descendant paths) instead. + Deprecated: use + /accounts/{account_id}/ai-search/namespaces/{namespace}/instances (and + descendant paths) instead. Args: id: AI Search instance ID. Lowercase alphanumeric, hyphens, and underscores. @@ -646,8 +656,9 @@ def stats( """ Retrieve usage and indexing statistics for an AI Search instance. - Deprecated: use /accounts/{account_id}/ai-search/namespaces/{name}/instances - (and descendant paths) instead. + Deprecated: use + /accounts/{account_id}/ai-search/namespaces/{namespace}/instances (and + descendant paths) instead. Args: id: AI Search instance ID. Lowercase alphanumeric, hyphens, and underscores. @@ -746,12 +757,13 @@ async def create( """Create a new AI Search instance with the given configuration. If type is omitted - or null, a non-blank HTTP(S) source infers web-crawler and an existing R2 bucket - source infers r2. A missing or blank source without a type creates a managed - upload-only instance. Search for Agents instances require the default namespace. + or null, a non-blank HTTP(S) source infers web-crawler and any other source + infers r2; r2 sources must name an existing bucket. A missing or blank source + without a type creates a managed upload-only instance. - Deprecated: use /accounts/{account_id}/ai-search/namespaces/{name}/instances - (and descendant paths) instead. + Deprecated: use + /accounts/{account_id}/ai-search/namespaces/{namespace}/instances (and + descendant paths) instead. Args: id: AI Search instance ID. Lowercase alphanumeric, hyphens, and underscores. @@ -766,14 +778,17 @@ async def create( hybrid_search_enabled: Deprecated — use index_method instead. Defaults to true for new instances; set false to create a vector-only instance. - index_method: Controls which storage backends are used during indexing. Defaults to vector and - keyword indexing for new instances. + index_method: Controls which storage backends indexing uses. Defaults to vector and keyword + indexing for new instances. When set, both vector and keyword are required. rewrite_model: A Workers AI model ID or an AI Gateway model ID compatible with the OpenAI Chat Completions API. An empty string uses the configured or default model. + score_threshold: Minimum similarity score a chunk must reach to be returned. Defaults to 0.4. + sync_interval: Interval between automatic syncs, in seconds. Allowed values: 900 (15min), 1800 (30min), 3600 (1h), 7200 (2h), 14400 (4h), 21600 (6h), 43200 (12h), 86400 (24h). + Defaults to 86400 (24h). type: Source type. When omitted or null with a non-blank source, HTTP(S) URLs infer web-crawler and existing R2 bucket names infer r2. A missing or blank source @@ -881,15 +896,12 @@ async def update( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> InstanceUpdateResponse: - """Update an AI Search instance. - - Submitting Search for Agents metadata requires the - default namespace; omitting or removing it is allowed elsewhere. Submit Search - for Agents metadata and restrictive or unknown public endpoint changes or custom - domains in separate PUT requests, even when resubmitting unchanged metadata. + """ + Updates the configuration of an AI Search instance. - Deprecated: use /accounts/{account_id}/ai-search/namespaces/{name}/instances - (and descendant paths) instead. + Deprecated: use + /accounts/{account_id}/ai-search/namespaces/{namespace}/instances (and + descendant paths) instead. Args: aisearch_model: A Workers AI model ID or an AI Gateway model ID compatible with the OpenAI Chat @@ -899,14 +911,17 @@ async def update( (1h), 7200 (2h), 21600 (6h), 43200 (12h), 86400 (24h), 172800 (48h), 259200 (72h), 518400 (6d). - index_method: Controls which storage backends are used during indexing. Defaults to vector and - keyword indexing for new instances. + index_method: Controls which storage backends indexing uses. Defaults to vector and keyword + indexing for new instances. When set, both vector and keyword are required. rewrite_model: A Workers AI model ID or an AI Gateway model ID compatible with the OpenAI Chat Completions API. An empty string uses the configured or default model. + score_threshold: Minimum similarity score a chunk must reach to be returned. Defaults to 0.4. + sync_interval: Interval between automatic syncs, in seconds. Allowed values: 900 (15min), 1800 (30min), 3600 (1h), 7200 (2h), 14400 (4h), 21600 (6h), 43200 (12h), 86400 (24h). + Defaults to 86400 (24h). extra_headers: Send extra headers @@ -989,15 +1004,17 @@ def list( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> AsyncPaginator[InstanceListResponse, AsyncV4PagePaginationArray[InstanceListResponse]]: """ - List all AI Search instances in the account. + Lists all AI Search instances in the account. - Deprecated: use /accounts/{account_id}/ai-search/namespaces/{name}/instances - (and descendant paths) instead. + Deprecated: use + /accounts/{account_id}/ai-search/namespaces/{namespace}/instances (and + descendant paths) instead. Args: - hostname: Filter by exact Search for Agents hostname (case-insensitive). + hostname: Return only instances with this exact Search for Agents hostname + (case-insensitive). - namespace: Filter by namespace. + namespace: Return only instances in this namespace. order_by: Field to order results by. @@ -1057,10 +1074,11 @@ async def delete( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> InstanceDeleteResponse: """ - Permanently delete an AI Search instance and all its indexed data. + Deletes an AI Search instance and all its indexed data permanently. - Deprecated: use /accounts/{account_id}/ai-search/namespaces/{name}/instances - (and descendant paths) instead. + Deprecated: use + /accounts/{account_id}/ai-search/namespaces/{namespace}/instances (and + descendant paths) instead. Args: extra_headers: Send extra headers @@ -1108,8 +1126,9 @@ async def chat_completions( Performs a chat completion request against an AI Search instance, using indexed content as context for generating responses. - Deprecated: use /accounts/{account_id}/ai-search/namespaces/{name}/instances - (and descendant paths) instead. + Deprecated: use + /accounts/{account_id}/ai-search/namespaces/{namespace}/instances (and + descendant paths) instead. Args: id: AI Search instance ID. Lowercase alphanumeric, hyphens, and underscores. @@ -1164,8 +1183,9 @@ async def read( """ Retrieve the configuration and status of an AI Search instance. - Deprecated: use /accounts/{account_id}/ai-search/namespaces/{name}/instances - (and descendant paths) instead. + Deprecated: use + /accounts/{account_id}/ai-search/namespaces/{namespace}/instances (and + descendant paths) instead. Args: extra_headers: Send extra headers @@ -1212,8 +1232,9 @@ async def search( Executes a semantic search query against an AI Search instance to find relevant indexed content. - Deprecated: use /accounts/{account_id}/ai-search/namespaces/{name}/instances - (and descendant paths) instead. + Deprecated: use + /accounts/{account_id}/ai-search/namespaces/{namespace}/instances (and + descendant paths) instead. Args: id: AI Search instance ID. Lowercase alphanumeric, hyphens, and underscores. @@ -1275,8 +1296,9 @@ async def stats( """ Retrieve usage and indexing statistics for an AI Search instance. - Deprecated: use /accounts/{account_id}/ai-search/namespaces/{name}/instances - (and descendant paths) instead. + Deprecated: use + /accounts/{account_id}/ai-search/namespaces/{namespace}/instances (and + descendant paths) instead. Args: id: AI Search instance ID. Lowercase alphanumeric, hyphens, and underscores. diff --git a/src/cloudflare/resources/aisearch/instances/jobs.py b/src/cloudflare/resources/aisearch/instances/jobs.py index 5c2f734d6a8..607a16aa05c 100644 --- a/src/cloudflare/resources/aisearch/instances/jobs.py +++ b/src/cloudflare/resources/aisearch/instances/jobs.py @@ -66,8 +66,9 @@ def create( """ Creates a new indexing job for an AI Search instance. - Deprecated: use /accounts/{account_id}/ai-search/namespaces/{name}/instances - (and descendant paths) instead. + Deprecated: use + /accounts/{account_id}/ai-search/namespaces/{namespace}/instances (and + descendant paths) instead. Args: id: AI Search instance ID. Lowercase alphanumeric, hyphens, and underscores. @@ -115,8 +116,9 @@ def list( """ Lists indexing jobs for an AI Search instance. - Deprecated: use /accounts/{account_id}/ai-search/namespaces/{name}/instances - (and descendant paths) instead. + Deprecated: use + /accounts/{account_id}/ai-search/namespaces/{namespace}/instances (and + descendant paths) instead. Args: id: AI Search instance ID. Lowercase alphanumeric, hyphens, and underscores. @@ -169,8 +171,9 @@ def get( """ Retrieves details for a specific AI Search indexing job. - Deprecated: use /accounts/{account_id}/ai-search/namespaces/{name}/instances - (and descendant paths) instead. + Deprecated: use + /accounts/{account_id}/ai-search/namespaces/{namespace}/instances (and + descendant paths) instead. Args: id: AI Search instance ID. Lowercase alphanumeric, hyphens, and underscores. @@ -225,8 +228,9 @@ def logs( """ Lists log entries for an AI Search indexing job. - Deprecated: use /accounts/{account_id}/ai-search/namespaces/{name}/instances - (and descendant paths) instead. + Deprecated: use + /accounts/{account_id}/ai-search/namespaces/{namespace}/instances (and + descendant paths) instead. Args: id: AI Search instance ID. Lowercase alphanumeric, hyphens, and underscores. @@ -307,8 +311,9 @@ async def create( """ Creates a new indexing job for an AI Search instance. - Deprecated: use /accounts/{account_id}/ai-search/namespaces/{name}/instances - (and descendant paths) instead. + Deprecated: use + /accounts/{account_id}/ai-search/namespaces/{namespace}/instances (and + descendant paths) instead. Args: id: AI Search instance ID. Lowercase alphanumeric, hyphens, and underscores. @@ -356,8 +361,9 @@ def list( """ Lists indexing jobs for an AI Search instance. - Deprecated: use /accounts/{account_id}/ai-search/namespaces/{name}/instances - (and descendant paths) instead. + Deprecated: use + /accounts/{account_id}/ai-search/namespaces/{namespace}/instances (and + descendant paths) instead. Args: id: AI Search instance ID. Lowercase alphanumeric, hyphens, and underscores. @@ -410,8 +416,9 @@ async def get( """ Retrieves details for a specific AI Search indexing job. - Deprecated: use /accounts/{account_id}/ai-search/namespaces/{name}/instances - (and descendant paths) instead. + Deprecated: use + /accounts/{account_id}/ai-search/namespaces/{namespace}/instances (and + descendant paths) instead. Args: id: AI Search instance ID. Lowercase alphanumeric, hyphens, and underscores. @@ -466,8 +473,9 @@ async def logs( """ Lists log entries for an AI Search indexing job. - Deprecated: use /accounts/{account_id}/ai-search/namespaces/{name}/instances - (and descendant paths) instead. + Deprecated: use + /accounts/{account_id}/ai-search/namespaces/{namespace}/instances (and + descendant paths) instead. Args: id: AI Search instance ID. Lowercase alphanumeric, hyphens, and underscores. diff --git a/src/cloudflare/resources/aisearch/namespaces/instances/instances.py b/src/cloudflare/resources/aisearch/namespaces/instances/instances.py index f9c9923ece9..f27452da62e 100644 --- a/src/cloudflare/resources/aisearch/namespaces/instances/instances.py +++ b/src/cloudflare/resources/aisearch/namespaces/instances/instances.py @@ -38,6 +38,7 @@ from ....._base_client import AsyncPaginator, make_request_options from .....types.aisearch.namespaces import ( instance_list_params, + instance_move_params, instance_create_params, instance_search_params, instance_update_params, @@ -85,7 +86,7 @@ def with_streaming_response(self) -> InstancesResourceWithStreamingResponse: def create( self, - name: str, + namespace: str, *, account_id: str, id: str, @@ -128,9 +129,9 @@ def create( """Create a new AI Search instance with the given configuration. If type is omitted - or null, a non-blank HTTP(S) source infers web-crawler and an existing R2 bucket - source infers r2. A missing or blank source without a type creates a managed - upload-only instance. Search for Agents instances require the default namespace. + or null, a non-blank HTTP(S) source infers web-crawler and any other source + infers r2; r2 sources must name an existing bucket. A missing or blank source + without a type creates a managed upload-only instance. Args: id: AI Search instance ID. Lowercase alphanumeric, hyphens, and underscores. @@ -145,14 +146,17 @@ def create( hybrid_search_enabled: Deprecated — use index_method instead. Defaults to true for new instances; set false to create a vector-only instance. - index_method: Controls which storage backends are used during indexing. Defaults to vector and - keyword indexing for new instances. + index_method: Controls which storage backends indexing uses. Defaults to vector and keyword + indexing for new instances. When set, both vector and keyword are required. rewrite_model: A Workers AI model ID or an AI Gateway model ID compatible with the OpenAI Chat Completions API. An empty string uses the configured or default model. + score_threshold: Minimum similarity score a chunk must reach to be returned. Defaults to 0.4. + sync_interval: Interval between automatic syncs, in seconds. Allowed values: 900 (15min), 1800 (30min), 3600 (1h), 7200 (2h), 14400 (4h), 21600 (6h), 43200 (12h), 86400 (24h). + Defaults to 86400 (24h). type: Source type. When omitted or null with a non-blank source, HTTP(S) URLs infer web-crawler and existing R2 bucket names infer r2. A missing or blank source @@ -168,11 +172,13 @@ def create( """ if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not name: - raise ValueError(f"Expected a non-empty value for `name` but received {name!r}") + if not namespace: + raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}") return self._post( path_template( - "/accounts/{account_id}/ai-search/namespaces/{name}/instances", account_id=account_id, name=name + "/accounts/{account_id}/ai-search/namespaces/{namespace}/instances", + account_id=account_id, + namespace=namespace, ), body=maybe_transform( { @@ -223,7 +229,7 @@ def update( id: str, *, account_id: str, - name: str, + namespace: str, ai_gateway_id: Optional[str] | Omit = omit, aisearch_model: Optional[str] | Omit = omit, cache: bool | Omit = omit, @@ -264,12 +270,8 @@ def update( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> InstanceUpdateResponse: - """Update an AI Search instance. - - Submitting Search for Agents metadata requires the - default namespace; omitting or removing it is allowed elsewhere. Submit Search - for Agents metadata and restrictive or unknown public endpoint changes or custom - domains in separate PUT requests, even when resubmitting unchanged metadata. + """ + Updates the configuration of an AI Search instance. Args: aisearch_model: A Workers AI model ID or an AI Gateway model ID compatible with the OpenAI Chat @@ -279,14 +281,17 @@ def update( (1h), 7200 (2h), 21600 (6h), 43200 (12h), 86400 (24h), 172800 (48h), 259200 (72h), 518400 (6d). - index_method: Controls which storage backends are used during indexing. Defaults to vector and - keyword indexing for new instances. + index_method: Controls which storage backends indexing uses. Defaults to vector and keyword + indexing for new instances. When set, both vector and keyword are required. rewrite_model: A Workers AI model ID or an AI Gateway model ID compatible with the OpenAI Chat Completions API. An empty string uses the configured or default model. + score_threshold: Minimum similarity score a chunk must reach to be returned. Defaults to 0.4. + sync_interval: Interval between automatic syncs, in seconds. Allowed values: 900 (15min), 1800 (30min), 3600 (1h), 7200 (2h), 14400 (4h), 21600 (6h), 43200 (12h), 86400 (24h). + Defaults to 86400 (24h). extra_headers: Send extra headers @@ -298,15 +303,15 @@ def update( """ if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not name: - raise ValueError(f"Expected a non-empty value for `name` but received {name!r}") + if not namespace: + raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}") if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._put( path_template( - "/accounts/{account_id}/ai-search/namespaces/{name}/instances/{id}", + "/accounts/{account_id}/ai-search/namespaces/{namespace}/instances/{id}", account_id=account_id, - name=name, + namespace=namespace, id=id, ), body=maybe_transform( @@ -358,11 +363,10 @@ def update( def list( self, - name: str, + namespace: str, *, account_id: str, hostname: str | Omit = omit, - namespace: str | Omit = omit, order_by: Literal["created_at"] | Omit = omit, order_by_direction: Literal["asc", "desc"] | Omit = omit, page: int | Omit = omit, @@ -376,12 +380,11 @@ def list( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> SyncV4PagePaginationArray[InstanceListResponse]: """ - List all AI Search instances in the account. + Lists all AI Search instances in the account. Args: - hostname: Filter by exact Search for Agents hostname (case-insensitive). - - namespace: Filter by namespace. + hostname: Return only instances with this exact Search for Agents hostname + (case-insensitive). order_by: Field to order results by. @@ -403,11 +406,13 @@ def list( """ if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not name: - raise ValueError(f"Expected a non-empty value for `name` but received {name!r}") + if not namespace: + raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}") return self._get_api_list( path_template( - "/accounts/{account_id}/ai-search/namespaces/{name}/instances", account_id=account_id, name=name + "/accounts/{account_id}/ai-search/namespaces/{namespace}/instances", + account_id=account_id, + namespace=namespace, ), page=SyncV4PagePaginationArray[InstanceListResponse], options=make_request_options( @@ -418,7 +423,6 @@ def list( query=maybe_transform( { "hostname": hostname, - "namespace": namespace, "order_by": order_by, "order_by_direction": order_by_direction, "page": page, @@ -436,7 +440,7 @@ def delete( id: str, *, account_id: str, - name: str, + namespace: str, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -445,7 +449,7 @@ def delete( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> InstanceDeleteResponse: """ - Permanently delete an AI Search instance and all its indexed data. + Deletes an AI Search instance and all its indexed data permanently. Args: extra_headers: Send extra headers @@ -458,15 +462,15 @@ def delete( """ if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not name: - raise ValueError(f"Expected a non-empty value for `name` but received {name!r}") + if not namespace: + raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}") if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._delete( path_template( - "/accounts/{account_id}/ai-search/namespaces/{name}/instances/{id}", + "/accounts/{account_id}/ai-search/namespaces/{namespace}/instances/{id}", account_id=account_id, - name=name, + namespace=namespace, id=id, ), options=make_request_options( @@ -484,7 +488,7 @@ def chat_completions( id: str, *, account_id: str, - name: str, + namespace: str, messages: Iterable[instance_chat_completions_params.Message], aisearch_options: instance_chat_completions_params.AISearchOptions | Omit = omit, model: str | Omit = omit, @@ -516,15 +520,15 @@ def chat_completions( """ if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not name: - raise ValueError(f"Expected a non-empty value for `name` but received {name!r}") + if not namespace: + raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}") if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._post( path_template( - "/accounts/{account_id}/ai-search/namespaces/{name}/instances/{id}/chat/completions", + "/accounts/{account_id}/ai-search/namespaces/{namespace}/instances/{id}/chat/completions", account_id=account_id, - name=name, + namespace=namespace, id=id, ), body=maybe_transform( @@ -542,12 +546,72 @@ def chat_completions( cast_to=InstanceChatCompletionsResponse, ) + def move( + self, + id: str, + *, + account_id: str, + namespace: str, + new_namespace: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> object: + """ + Moves an instance from its current namespace to the specified target namespace. + Use 'default' with --destination-namespace to move the instance back to the + default namespace. Fails with 400 if the target namespace already has an + instance with the same id (ids must be unique within a namespace — the same id + can exist in different namespaces). + + Args: + namespace: Current namespace of the instance. + + id: Instance id. + + new_namespace: Target namespace to move the instance into. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not namespace: + raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}") + if not id: + raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") + return self._patch( + path_template( + "/accounts/{account_id}/ai-search/namespaces/{namespace}/instances/{id}", + account_id=account_id, + namespace=namespace, + id=id, + ), + body=maybe_transform({"new_namespace": new_namespace}, instance_move_params.InstanceMoveParams), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[object]._unwrapper, + ), + cast_to=cast(Type[object], ResultWrapper[object]), + ) + def read( self, id: str, *, account_id: str, - name: str, + namespace: str, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -569,15 +633,15 @@ def read( """ if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not name: - raise ValueError(f"Expected a non-empty value for `name` but received {name!r}") + if not namespace: + raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}") if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._get( path_template( - "/accounts/{account_id}/ai-search/namespaces/{name}/instances/{id}", + "/accounts/{account_id}/ai-search/namespaces/{namespace}/instances/{id}", account_id=account_id, - name=name, + namespace=namespace, id=id, ), options=make_request_options( @@ -595,7 +659,7 @@ def search( id: str, *, account_id: str, - name: str, + namespace: str, aisearch_options: instance_search_params.AISearchOptions | Omit = omit, messages: Iterable[instance_search_params.Message] | Omit = omit, query: str | Omit = omit, @@ -632,15 +696,15 @@ def search( """ if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not name: - raise ValueError(f"Expected a non-empty value for `name` but received {name!r}") + if not namespace: + raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}") if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._post( path_template( - "/accounts/{account_id}/ai-search/namespaces/{name}/instances/{id}/search", + "/accounts/{account_id}/ai-search/namespaces/{namespace}/instances/{id}/search", account_id=account_id, - name=name, + namespace=namespace, id=id, ), body=maybe_transform( @@ -666,7 +730,7 @@ def stats( id: str, *, account_id: str, - name: str, + namespace: str, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -690,15 +754,15 @@ def stats( """ if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not name: - raise ValueError(f"Expected a non-empty value for `name` but received {name!r}") + if not namespace: + raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}") if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._get( path_template( - "/accounts/{account_id}/ai-search/namespaces/{name}/instances/{id}/stats", + "/accounts/{account_id}/ai-search/namespaces/{namespace}/instances/{id}/stats", account_id=account_id, - name=name, + namespace=namespace, id=id, ), options=make_request_options( @@ -742,7 +806,7 @@ def with_streaming_response(self) -> AsyncInstancesResourceWithStreamingResponse async def create( self, - name: str, + namespace: str, *, account_id: str, id: str, @@ -785,9 +849,9 @@ async def create( """Create a new AI Search instance with the given configuration. If type is omitted - or null, a non-blank HTTP(S) source infers web-crawler and an existing R2 bucket - source infers r2. A missing or blank source without a type creates a managed - upload-only instance. Search for Agents instances require the default namespace. + or null, a non-blank HTTP(S) source infers web-crawler and any other source + infers r2; r2 sources must name an existing bucket. A missing or blank source + without a type creates a managed upload-only instance. Args: id: AI Search instance ID. Lowercase alphanumeric, hyphens, and underscores. @@ -802,14 +866,17 @@ async def create( hybrid_search_enabled: Deprecated — use index_method instead. Defaults to true for new instances; set false to create a vector-only instance. - index_method: Controls which storage backends are used during indexing. Defaults to vector and - keyword indexing for new instances. + index_method: Controls which storage backends indexing uses. Defaults to vector and keyword + indexing for new instances. When set, both vector and keyword are required. rewrite_model: A Workers AI model ID or an AI Gateway model ID compatible with the OpenAI Chat Completions API. An empty string uses the configured or default model. + score_threshold: Minimum similarity score a chunk must reach to be returned. Defaults to 0.4. + sync_interval: Interval between automatic syncs, in seconds. Allowed values: 900 (15min), 1800 (30min), 3600 (1h), 7200 (2h), 14400 (4h), 21600 (6h), 43200 (12h), 86400 (24h). + Defaults to 86400 (24h). type: Source type. When omitted or null with a non-blank source, HTTP(S) URLs infer web-crawler and existing R2 bucket names infer r2. A missing or blank source @@ -825,11 +892,13 @@ async def create( """ if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not name: - raise ValueError(f"Expected a non-empty value for `name` but received {name!r}") + if not namespace: + raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}") return await self._post( path_template( - "/accounts/{account_id}/ai-search/namespaces/{name}/instances", account_id=account_id, name=name + "/accounts/{account_id}/ai-search/namespaces/{namespace}/instances", + account_id=account_id, + namespace=namespace, ), body=await async_maybe_transform( { @@ -880,7 +949,7 @@ async def update( id: str, *, account_id: str, - name: str, + namespace: str, ai_gateway_id: Optional[str] | Omit = omit, aisearch_model: Optional[str] | Omit = omit, cache: bool | Omit = omit, @@ -921,12 +990,8 @@ async def update( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> InstanceUpdateResponse: - """Update an AI Search instance. - - Submitting Search for Agents metadata requires the - default namespace; omitting or removing it is allowed elsewhere. Submit Search - for Agents metadata and restrictive or unknown public endpoint changes or custom - domains in separate PUT requests, even when resubmitting unchanged metadata. + """ + Updates the configuration of an AI Search instance. Args: aisearch_model: A Workers AI model ID or an AI Gateway model ID compatible with the OpenAI Chat @@ -936,14 +1001,17 @@ async def update( (1h), 7200 (2h), 21600 (6h), 43200 (12h), 86400 (24h), 172800 (48h), 259200 (72h), 518400 (6d). - index_method: Controls which storage backends are used during indexing. Defaults to vector and - keyword indexing for new instances. + index_method: Controls which storage backends indexing uses. Defaults to vector and keyword + indexing for new instances. When set, both vector and keyword are required. rewrite_model: A Workers AI model ID or an AI Gateway model ID compatible with the OpenAI Chat Completions API. An empty string uses the configured or default model. + score_threshold: Minimum similarity score a chunk must reach to be returned. Defaults to 0.4. + sync_interval: Interval between automatic syncs, in seconds. Allowed values: 900 (15min), 1800 (30min), 3600 (1h), 7200 (2h), 14400 (4h), 21600 (6h), 43200 (12h), 86400 (24h). + Defaults to 86400 (24h). extra_headers: Send extra headers @@ -955,15 +1023,15 @@ async def update( """ if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not name: - raise ValueError(f"Expected a non-empty value for `name` but received {name!r}") + if not namespace: + raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}") if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._put( path_template( - "/accounts/{account_id}/ai-search/namespaces/{name}/instances/{id}", + "/accounts/{account_id}/ai-search/namespaces/{namespace}/instances/{id}", account_id=account_id, - name=name, + namespace=namespace, id=id, ), body=await async_maybe_transform( @@ -1015,11 +1083,10 @@ async def update( def list( self, - name: str, + namespace: str, *, account_id: str, hostname: str | Omit = omit, - namespace: str | Omit = omit, order_by: Literal["created_at"] | Omit = omit, order_by_direction: Literal["asc", "desc"] | Omit = omit, page: int | Omit = omit, @@ -1033,12 +1100,11 @@ def list( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> AsyncPaginator[InstanceListResponse, AsyncV4PagePaginationArray[InstanceListResponse]]: """ - List all AI Search instances in the account. + Lists all AI Search instances in the account. Args: - hostname: Filter by exact Search for Agents hostname (case-insensitive). - - namespace: Filter by namespace. + hostname: Return only instances with this exact Search for Agents hostname + (case-insensitive). order_by: Field to order results by. @@ -1060,11 +1126,13 @@ def list( """ if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not name: - raise ValueError(f"Expected a non-empty value for `name` but received {name!r}") + if not namespace: + raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}") return self._get_api_list( path_template( - "/accounts/{account_id}/ai-search/namespaces/{name}/instances", account_id=account_id, name=name + "/accounts/{account_id}/ai-search/namespaces/{namespace}/instances", + account_id=account_id, + namespace=namespace, ), page=AsyncV4PagePaginationArray[InstanceListResponse], options=make_request_options( @@ -1075,7 +1143,6 @@ def list( query=maybe_transform( { "hostname": hostname, - "namespace": namespace, "order_by": order_by, "order_by_direction": order_by_direction, "page": page, @@ -1093,7 +1160,7 @@ async def delete( id: str, *, account_id: str, - name: str, + namespace: str, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -1102,7 +1169,7 @@ async def delete( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> InstanceDeleteResponse: """ - Permanently delete an AI Search instance and all its indexed data. + Deletes an AI Search instance and all its indexed data permanently. Args: extra_headers: Send extra headers @@ -1115,15 +1182,15 @@ async def delete( """ if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not name: - raise ValueError(f"Expected a non-empty value for `name` but received {name!r}") + if not namespace: + raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}") if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._delete( path_template( - "/accounts/{account_id}/ai-search/namespaces/{name}/instances/{id}", + "/accounts/{account_id}/ai-search/namespaces/{namespace}/instances/{id}", account_id=account_id, - name=name, + namespace=namespace, id=id, ), options=make_request_options( @@ -1141,7 +1208,7 @@ async def chat_completions( id: str, *, account_id: str, - name: str, + namespace: str, messages: Iterable[instance_chat_completions_params.Message], aisearch_options: instance_chat_completions_params.AISearchOptions | Omit = omit, model: str | Omit = omit, @@ -1173,15 +1240,15 @@ async def chat_completions( """ if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not name: - raise ValueError(f"Expected a non-empty value for `name` but received {name!r}") + if not namespace: + raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}") if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._post( path_template( - "/accounts/{account_id}/ai-search/namespaces/{name}/instances/{id}/chat/completions", + "/accounts/{account_id}/ai-search/namespaces/{namespace}/instances/{id}/chat/completions", account_id=account_id, - name=name, + namespace=namespace, id=id, ), body=await async_maybe_transform( @@ -1199,12 +1266,72 @@ async def chat_completions( cast_to=InstanceChatCompletionsResponse, ) + async def move( + self, + id: str, + *, + account_id: str, + namespace: str, + new_namespace: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> object: + """ + Moves an instance from its current namespace to the specified target namespace. + Use 'default' with --destination-namespace to move the instance back to the + default namespace. Fails with 400 if the target namespace already has an + instance with the same id (ids must be unique within a namespace — the same id + can exist in different namespaces). + + Args: + namespace: Current namespace of the instance. + + id: Instance id. + + new_namespace: Target namespace to move the instance into. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not namespace: + raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}") + if not id: + raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") + return await self._patch( + path_template( + "/accounts/{account_id}/ai-search/namespaces/{namespace}/instances/{id}", + account_id=account_id, + namespace=namespace, + id=id, + ), + body=await async_maybe_transform({"new_namespace": new_namespace}, instance_move_params.InstanceMoveParams), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[object]._unwrapper, + ), + cast_to=cast(Type[object], ResultWrapper[object]), + ) + async def read( self, id: str, *, account_id: str, - name: str, + namespace: str, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -1226,15 +1353,15 @@ async def read( """ if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not name: - raise ValueError(f"Expected a non-empty value for `name` but received {name!r}") + if not namespace: + raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}") if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._get( path_template( - "/accounts/{account_id}/ai-search/namespaces/{name}/instances/{id}", + "/accounts/{account_id}/ai-search/namespaces/{namespace}/instances/{id}", account_id=account_id, - name=name, + namespace=namespace, id=id, ), options=make_request_options( @@ -1252,7 +1379,7 @@ async def search( id: str, *, account_id: str, - name: str, + namespace: str, aisearch_options: instance_search_params.AISearchOptions | Omit = omit, messages: Iterable[instance_search_params.Message] | Omit = omit, query: str | Omit = omit, @@ -1289,15 +1416,15 @@ async def search( """ if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not name: - raise ValueError(f"Expected a non-empty value for `name` but received {name!r}") + if not namespace: + raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}") if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._post( path_template( - "/accounts/{account_id}/ai-search/namespaces/{name}/instances/{id}/search", + "/accounts/{account_id}/ai-search/namespaces/{namespace}/instances/{id}/search", account_id=account_id, - name=name, + namespace=namespace, id=id, ), body=await async_maybe_transform( @@ -1323,7 +1450,7 @@ async def stats( id: str, *, account_id: str, - name: str, + namespace: str, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -1347,15 +1474,15 @@ async def stats( """ if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not name: - raise ValueError(f"Expected a non-empty value for `name` but received {name!r}") + if not namespace: + raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}") if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._get( path_template( - "/accounts/{account_id}/ai-search/namespaces/{name}/instances/{id}/stats", + "/accounts/{account_id}/ai-search/namespaces/{namespace}/instances/{id}/stats", account_id=account_id, - name=name, + namespace=namespace, id=id, ), options=make_request_options( @@ -1388,6 +1515,9 @@ def __init__(self, instances: InstancesResource) -> None: self.chat_completions = to_raw_response_wrapper( instances.chat_completions, ) + self.move = to_raw_response_wrapper( + instances.move, + ) self.read = to_raw_response_wrapper( instances.read, ) @@ -1426,6 +1556,9 @@ def __init__(self, instances: AsyncInstancesResource) -> None: self.chat_completions = async_to_raw_response_wrapper( instances.chat_completions, ) + self.move = async_to_raw_response_wrapper( + instances.move, + ) self.read = async_to_raw_response_wrapper( instances.read, ) @@ -1464,6 +1597,9 @@ def __init__(self, instances: InstancesResource) -> None: self.chat_completions = to_streamed_response_wrapper( instances.chat_completions, ) + self.move = to_streamed_response_wrapper( + instances.move, + ) self.read = to_streamed_response_wrapper( instances.read, ) @@ -1502,6 +1638,9 @@ def __init__(self, instances: AsyncInstancesResource) -> None: self.chat_completions = async_to_streamed_response_wrapper( instances.chat_completions, ) + self.move = async_to_streamed_response_wrapper( + instances.move, + ) self.read = async_to_streamed_response_wrapper( instances.read, ) diff --git a/src/cloudflare/resources/aisearch/namespaces/instances/items.py b/src/cloudflare/resources/aisearch/namespaces/instances/items.py index 2bb468bcc23..7c1947e9791 100644 --- a/src/cloudflare/resources/aisearch/namespaces/instances/items.py +++ b/src/cloudflare/resources/aisearch/namespaces/instances/items.py @@ -74,7 +74,7 @@ def list( id: str, *, account_id: str, - name: str, + namespace: str, item_id: str | Omit = omit, key: str | Omit = omit, metadata_filter: str | Omit = omit, @@ -98,22 +98,23 @@ def list( Lowercase alphanumeric, hyphens, and underscores. - item_id: Filter items by their unique ID. Returns at most one item. + item_id: Return only the item with this unique ID. Returns at most one item. - key: Filter items by their exact key (object key / filename). Keys are unique per - source, so combine with `source` to disambiguate across data sources. + key: Return only items with this exact key (object key / filename). Each key is + unique within a source, so combine with `source` to disambiguate across data + sources. metadata_filter: JSON-encoded metadata filter using Vectorize filter syntax. Examples: {"folder":"reports/"}, - {"timestamp":{"$gte":1700000000000}}, {"folder":{"$in":["docs/","reports/"]}} + {"timestamp":{"$gte":1700000000000}}, {"folder":{"$in":["docs/","reports/"]}}. - sort_by: Sort order for items. "status" (default) sorts by status priority then - last_seen_at. "modified_at" sorts by file modification time (most recent first), - falling back to created_at. + sort_by: Sort order for items. "status" (default) sorts items according to status + priority, then last_seen_at. "modified_at" sorts items according to file + modification time (most recent first), falling back to created_at. - source: Filter items by source_id. Use "builtin" for uploaded files, or a source - identifier like "web-crawler:https://example.com". + source: Return only items with this source_id. Use "builtin" for uploaded files, or a + source identifier like "web-crawler:https://example.com". extra_headers: Send extra headers @@ -125,15 +126,15 @@ def list( """ if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not name: - raise ValueError(f"Expected a non-empty value for `name` but received {name!r}") + if not namespace: + raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}") if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._get_api_list( path_template( - "/accounts/{account_id}/ai-search/namespaces/{name}/instances/{id}/items", + "/accounts/{account_id}/ai-search/namespaces/{namespace}/instances/{id}/items", account_id=account_id, - name=name, + namespace=namespace, id=id, ), page=SyncV4PagePaginationArray[ItemListResponse], @@ -165,7 +166,7 @@ def delete( item_id: str, *, account_id: str, - name: str, + namespace: str, id: str, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. @@ -190,17 +191,17 @@ def delete( """ if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not name: - raise ValueError(f"Expected a non-empty value for `name` but received {name!r}") + if not namespace: + raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}") if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") if not item_id: raise ValueError(f"Expected a non-empty value for `item_id` but received {item_id!r}") return self._delete( path_template( - "/accounts/{account_id}/ai-search/namespaces/{name}/instances/{id}/items/{item_id}", + "/accounts/{account_id}/ai-search/namespaces/{namespace}/instances/{id}/items/{item_id}", account_id=account_id, - name=name, + namespace=namespace, id=id, item_id=item_id, ), @@ -219,7 +220,7 @@ def chunks( item_id: str, *, account_id: str, - name: str, + namespace: str, id: str, limit: int | Omit = omit, offset: int | Omit = omit, @@ -247,17 +248,17 @@ def chunks( """ if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not name: - raise ValueError(f"Expected a non-empty value for `name` but received {name!r}") + if not namespace: + raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}") if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") if not item_id: raise ValueError(f"Expected a non-empty value for `item_id` but received {item_id!r}") return self._get( path_template( - "/accounts/{account_id}/ai-search/namespaces/{name}/instances/{id}/items/{item_id}/chunks", + "/accounts/{account_id}/ai-search/namespaces/{namespace}/instances/{id}/items/{item_id}/chunks", account_id=account_id, - name=name, + namespace=namespace, id=id, item_id=item_id, ), @@ -283,7 +284,7 @@ def create_or_update( id: str, *, account_id: str, - name: str, + namespace: str, key: str, next_action: Literal["INDEX"], wait_for_completion: bool | Omit = omit, @@ -302,11 +303,11 @@ def create_or_update( key: Item key / filename. Must not exceed 128 characters. - wait_for_completion: Wait for indexing to fully complete before responding. On RAGs with vector - indexing enabled, this additionally waits for Vectorize ingestion confirmation - (up to 40s) so the returned item reflects a queryable state. On timeout the item - is returned in `running` state and the background alarm continues polling. - Defaults to false. + wait_for_completion: Wait for indexing before responding. After processing, vector-indexed instances + use any time remaining in a 25s wait budget to confirm Vectorize ingestion. + Processing itself continues uninterrupted and can exceed that budget. If + confirmation times out, the response returns the current item state and + background indexing continues. Defaults to false. extra_headers: Send extra headers @@ -318,15 +319,15 @@ def create_or_update( """ if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not name: - raise ValueError(f"Expected a non-empty value for `name` but received {name!r}") + if not namespace: + raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}") if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._put( path_template( - "/accounts/{account_id}/ai-search/namespaces/{name}/instances/{id}/items", + "/accounts/{account_id}/ai-search/namespaces/{namespace}/instances/{id}/items", account_id=account_id, - name=name, + namespace=namespace, id=id, ), body=maybe_transform( @@ -352,7 +353,7 @@ def download( item_id: str, *, account_id: str, - name: str, + namespace: str, id: str, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. @@ -378,8 +379,8 @@ def download( """ if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not name: - raise ValueError(f"Expected a non-empty value for `name` but received {name!r}") + if not namespace: + raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}") if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") if not item_id: @@ -387,9 +388,9 @@ def download( extra_headers = {"Accept": "application/octet-stream", **(extra_headers or {})} return self._get( path_template( - "/accounts/{account_id}/ai-search/namespaces/{name}/instances/{id}/items/{item_id}/download", + "/accounts/{account_id}/ai-search/namespaces/{namespace}/instances/{id}/items/{item_id}/download", account_id=account_id, - name=name, + namespace=namespace, id=id, item_id=item_id, ), @@ -404,7 +405,7 @@ def get( item_id: str, *, account_id: str, - name: str, + namespace: str, id: str, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. @@ -429,17 +430,17 @@ def get( """ if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not name: - raise ValueError(f"Expected a non-empty value for `name` but received {name!r}") + if not namespace: + raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}") if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") if not item_id: raise ValueError(f"Expected a non-empty value for `item_id` but received {item_id!r}") return self._get( path_template( - "/accounts/{account_id}/ai-search/namespaces/{name}/instances/{id}/items/{item_id}", + "/accounts/{account_id}/ai-search/namespaces/{namespace}/instances/{id}/items/{item_id}", account_id=account_id, - name=name, + namespace=namespace, id=id, item_id=item_id, ), @@ -458,7 +459,7 @@ def logs( item_id: str, *, account_id: str, - name: str, + namespace: str, id: str, cursor: str | Omit = omit, limit: int | Omit = omit, @@ -485,17 +486,17 @@ def logs( """ if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not name: - raise ValueError(f"Expected a non-empty value for `name` but received {name!r}") + if not namespace: + raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}") if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") if not item_id: raise ValueError(f"Expected a non-empty value for `item_id` but received {item_id!r}") return self._get( path_template( - "/accounts/{account_id}/ai-search/namespaces/{name}/instances/{id}/items/{item_id}/logs", + "/accounts/{account_id}/ai-search/namespaces/{namespace}/instances/{id}/items/{item_id}/logs", account_id=account_id, - name=name, + namespace=namespace, id=id, item_id=item_id, ), @@ -521,7 +522,7 @@ def sync( item_id: str, *, account_id: str, - name: str, + namespace: str, id: str, next_action: Literal["INDEX"], wait_for_completion: bool | Omit = omit, @@ -532,18 +533,17 @@ def sync( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> ItemSyncResponse: - """Syncs an item to an AI Search instance index. + """ + Synchronizes an item to an AI Search instance index. Args: - id: AI Search instance ID. - - Lowercase alphanumeric, hyphens, and underscores. + id: AI Search instance ID. Lowercase alphanumeric, hyphens, and underscores. - wait_for_completion: Wait for indexing to fully complete before responding. On RAGs with vector - indexing enabled, this additionally waits for Vectorize ingestion confirmation - (up to 40s) so the returned item reflects a queryable state. On timeout the item - is returned in `running` state and the background alarm continues polling. - Defaults to false. + wait_for_completion: Wait for indexing before responding. After processing, vector-indexed instances + use any time remaining in a 25s wait budget to confirm Vectorize ingestion. + Processing itself continues uninterrupted and can exceed that budget. If + confirmation times out, the response returns the current item state and + background indexing continues. Defaults to false. extra_headers: Send extra headers @@ -555,17 +555,17 @@ def sync( """ if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not name: - raise ValueError(f"Expected a non-empty value for `name` but received {name!r}") + if not namespace: + raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}") if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") if not item_id: raise ValueError(f"Expected a non-empty value for `item_id` but received {item_id!r}") return self._patch( path_template( - "/accounts/{account_id}/ai-search/namespaces/{name}/instances/{id}/items/{item_id}", + "/accounts/{account_id}/ai-search/namespaces/{namespace}/instances/{id}/items/{item_id}", account_id=account_id, - name=name, + namespace=namespace, id=id, item_id=item_id, ), @@ -591,7 +591,7 @@ def upload( id: str, *, account_id: str, - name: str, + namespace: str, file: item_upload_params.File, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. @@ -616,8 +616,8 @@ def upload( """ if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not name: - raise ValueError(f"Expected a non-empty value for `name` but received {name!r}") + if not namespace: + raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}") if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") body = deepcopy_with_paths(file, [["file"]]) @@ -628,9 +628,9 @@ def upload( extra_headers = {"Content-Type": "multipart/form-data", **(extra_headers or {})} return self._post( path_template( - "/accounts/{account_id}/ai-search/namespaces/{name}/instances/{id}/items", + "/accounts/{account_id}/ai-search/namespaces/{namespace}/instances/{id}/items", account_id=account_id, - name=name, + namespace=namespace, id=id, ), body=maybe_transform(body, item_upload_params.ItemUploadParams), @@ -671,7 +671,7 @@ def list( id: str, *, account_id: str, - name: str, + namespace: str, item_id: str | Omit = omit, key: str | Omit = omit, metadata_filter: str | Omit = omit, @@ -695,22 +695,23 @@ def list( Lowercase alphanumeric, hyphens, and underscores. - item_id: Filter items by their unique ID. Returns at most one item. + item_id: Return only the item with this unique ID. Returns at most one item. - key: Filter items by their exact key (object key / filename). Keys are unique per - source, so combine with `source` to disambiguate across data sources. + key: Return only items with this exact key (object key / filename). Each key is + unique within a source, so combine with `source` to disambiguate across data + sources. metadata_filter: JSON-encoded metadata filter using Vectorize filter syntax. Examples: {"folder":"reports/"}, - {"timestamp":{"$gte":1700000000000}}, {"folder":{"$in":["docs/","reports/"]}} + {"timestamp":{"$gte":1700000000000}}, {"folder":{"$in":["docs/","reports/"]}}. - sort_by: Sort order for items. "status" (default) sorts by status priority then - last_seen_at. "modified_at" sorts by file modification time (most recent first), - falling back to created_at. + sort_by: Sort order for items. "status" (default) sorts items according to status + priority, then last_seen_at. "modified_at" sorts items according to file + modification time (most recent first), falling back to created_at. - source: Filter items by source_id. Use "builtin" for uploaded files, or a source - identifier like "web-crawler:https://example.com". + source: Return only items with this source_id. Use "builtin" for uploaded files, or a + source identifier like "web-crawler:https://example.com". extra_headers: Send extra headers @@ -722,15 +723,15 @@ def list( """ if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not name: - raise ValueError(f"Expected a non-empty value for `name` but received {name!r}") + if not namespace: + raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}") if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._get_api_list( path_template( - "/accounts/{account_id}/ai-search/namespaces/{name}/instances/{id}/items", + "/accounts/{account_id}/ai-search/namespaces/{namespace}/instances/{id}/items", account_id=account_id, - name=name, + namespace=namespace, id=id, ), page=AsyncV4PagePaginationArray[ItemListResponse], @@ -762,7 +763,7 @@ async def delete( item_id: str, *, account_id: str, - name: str, + namespace: str, id: str, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. @@ -787,17 +788,17 @@ async def delete( """ if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not name: - raise ValueError(f"Expected a non-empty value for `name` but received {name!r}") + if not namespace: + raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}") if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") if not item_id: raise ValueError(f"Expected a non-empty value for `item_id` but received {item_id!r}") return await self._delete( path_template( - "/accounts/{account_id}/ai-search/namespaces/{name}/instances/{id}/items/{item_id}", + "/accounts/{account_id}/ai-search/namespaces/{namespace}/instances/{id}/items/{item_id}", account_id=account_id, - name=name, + namespace=namespace, id=id, item_id=item_id, ), @@ -816,7 +817,7 @@ async def chunks( item_id: str, *, account_id: str, - name: str, + namespace: str, id: str, limit: int | Omit = omit, offset: int | Omit = omit, @@ -844,17 +845,17 @@ async def chunks( """ if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not name: - raise ValueError(f"Expected a non-empty value for `name` but received {name!r}") + if not namespace: + raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}") if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") if not item_id: raise ValueError(f"Expected a non-empty value for `item_id` but received {item_id!r}") return await self._get( path_template( - "/accounts/{account_id}/ai-search/namespaces/{name}/instances/{id}/items/{item_id}/chunks", + "/accounts/{account_id}/ai-search/namespaces/{namespace}/instances/{id}/items/{item_id}/chunks", account_id=account_id, - name=name, + namespace=namespace, id=id, item_id=item_id, ), @@ -880,7 +881,7 @@ async def create_or_update( id: str, *, account_id: str, - name: str, + namespace: str, key: str, next_action: Literal["INDEX"], wait_for_completion: bool | Omit = omit, @@ -899,11 +900,11 @@ async def create_or_update( key: Item key / filename. Must not exceed 128 characters. - wait_for_completion: Wait for indexing to fully complete before responding. On RAGs with vector - indexing enabled, this additionally waits for Vectorize ingestion confirmation - (up to 40s) so the returned item reflects a queryable state. On timeout the item - is returned in `running` state and the background alarm continues polling. - Defaults to false. + wait_for_completion: Wait for indexing before responding. After processing, vector-indexed instances + use any time remaining in a 25s wait budget to confirm Vectorize ingestion. + Processing itself continues uninterrupted and can exceed that budget. If + confirmation times out, the response returns the current item state and + background indexing continues. Defaults to false. extra_headers: Send extra headers @@ -915,15 +916,15 @@ async def create_or_update( """ if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not name: - raise ValueError(f"Expected a non-empty value for `name` but received {name!r}") + if not namespace: + raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}") if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._put( path_template( - "/accounts/{account_id}/ai-search/namespaces/{name}/instances/{id}/items", + "/accounts/{account_id}/ai-search/namespaces/{namespace}/instances/{id}/items", account_id=account_id, - name=name, + namespace=namespace, id=id, ), body=await async_maybe_transform( @@ -949,7 +950,7 @@ async def download( item_id: str, *, account_id: str, - name: str, + namespace: str, id: str, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. @@ -975,8 +976,8 @@ async def download( """ if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not name: - raise ValueError(f"Expected a non-empty value for `name` but received {name!r}") + if not namespace: + raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}") if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") if not item_id: @@ -984,9 +985,9 @@ async def download( extra_headers = {"Accept": "application/octet-stream", **(extra_headers or {})} return await self._get( path_template( - "/accounts/{account_id}/ai-search/namespaces/{name}/instances/{id}/items/{item_id}/download", + "/accounts/{account_id}/ai-search/namespaces/{namespace}/instances/{id}/items/{item_id}/download", account_id=account_id, - name=name, + namespace=namespace, id=id, item_id=item_id, ), @@ -1001,7 +1002,7 @@ async def get( item_id: str, *, account_id: str, - name: str, + namespace: str, id: str, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. @@ -1026,17 +1027,17 @@ async def get( """ if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not name: - raise ValueError(f"Expected a non-empty value for `name` but received {name!r}") + if not namespace: + raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}") if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") if not item_id: raise ValueError(f"Expected a non-empty value for `item_id` but received {item_id!r}") return await self._get( path_template( - "/accounts/{account_id}/ai-search/namespaces/{name}/instances/{id}/items/{item_id}", + "/accounts/{account_id}/ai-search/namespaces/{namespace}/instances/{id}/items/{item_id}", account_id=account_id, - name=name, + namespace=namespace, id=id, item_id=item_id, ), @@ -1055,7 +1056,7 @@ async def logs( item_id: str, *, account_id: str, - name: str, + namespace: str, id: str, cursor: str | Omit = omit, limit: int | Omit = omit, @@ -1082,17 +1083,17 @@ async def logs( """ if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not name: - raise ValueError(f"Expected a non-empty value for `name` but received {name!r}") + if not namespace: + raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}") if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") if not item_id: raise ValueError(f"Expected a non-empty value for `item_id` but received {item_id!r}") return await self._get( path_template( - "/accounts/{account_id}/ai-search/namespaces/{name}/instances/{id}/items/{item_id}/logs", + "/accounts/{account_id}/ai-search/namespaces/{namespace}/instances/{id}/items/{item_id}/logs", account_id=account_id, - name=name, + namespace=namespace, id=id, item_id=item_id, ), @@ -1118,7 +1119,7 @@ async def sync( item_id: str, *, account_id: str, - name: str, + namespace: str, id: str, next_action: Literal["INDEX"], wait_for_completion: bool | Omit = omit, @@ -1129,18 +1130,17 @@ async def sync( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> ItemSyncResponse: - """Syncs an item to an AI Search instance index. + """ + Synchronizes an item to an AI Search instance index. Args: - id: AI Search instance ID. - - Lowercase alphanumeric, hyphens, and underscores. + id: AI Search instance ID. Lowercase alphanumeric, hyphens, and underscores. - wait_for_completion: Wait for indexing to fully complete before responding. On RAGs with vector - indexing enabled, this additionally waits for Vectorize ingestion confirmation - (up to 40s) so the returned item reflects a queryable state. On timeout the item - is returned in `running` state and the background alarm continues polling. - Defaults to false. + wait_for_completion: Wait for indexing before responding. After processing, vector-indexed instances + use any time remaining in a 25s wait budget to confirm Vectorize ingestion. + Processing itself continues uninterrupted and can exceed that budget. If + confirmation times out, the response returns the current item state and + background indexing continues. Defaults to false. extra_headers: Send extra headers @@ -1152,17 +1152,17 @@ async def sync( """ if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not name: - raise ValueError(f"Expected a non-empty value for `name` but received {name!r}") + if not namespace: + raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}") if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") if not item_id: raise ValueError(f"Expected a non-empty value for `item_id` but received {item_id!r}") return await self._patch( path_template( - "/accounts/{account_id}/ai-search/namespaces/{name}/instances/{id}/items/{item_id}", + "/accounts/{account_id}/ai-search/namespaces/{namespace}/instances/{id}/items/{item_id}", account_id=account_id, - name=name, + namespace=namespace, id=id, item_id=item_id, ), @@ -1188,7 +1188,7 @@ async def upload( id: str, *, account_id: str, - name: str, + namespace: str, file: item_upload_params.File, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. @@ -1213,8 +1213,8 @@ async def upload( """ if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not name: - raise ValueError(f"Expected a non-empty value for `name` but received {name!r}") + if not namespace: + raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}") if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") body = deepcopy_with_paths(file, [["file"]]) @@ -1225,9 +1225,9 @@ async def upload( extra_headers = {"Content-Type": "multipart/form-data", **(extra_headers or {})} return await self._post( path_template( - "/accounts/{account_id}/ai-search/namespaces/{name}/instances/{id}/items", + "/accounts/{account_id}/ai-search/namespaces/{namespace}/instances/{id}/items", account_id=account_id, - name=name, + namespace=namespace, id=id, ), body=await async_maybe_transform(body, item_upload_params.ItemUploadParams), diff --git a/src/cloudflare/resources/aisearch/namespaces/instances/jobs.py b/src/cloudflare/resources/aisearch/namespaces/instances/jobs.py index e854c086a34..01bf9bca8c9 100644 --- a/src/cloudflare/resources/aisearch/namespaces/instances/jobs.py +++ b/src/cloudflare/resources/aisearch/namespaces/instances/jobs.py @@ -60,7 +60,7 @@ def create( id: str, *, account_id: str, - name: str, + namespace: str, description: str | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. @@ -85,15 +85,15 @@ def create( """ if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not name: - raise ValueError(f"Expected a non-empty value for `name` but received {name!r}") + if not namespace: + raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}") if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._post( path_template( - "/accounts/{account_id}/ai-search/namespaces/{name}/instances/{id}/jobs", + "/accounts/{account_id}/ai-search/namespaces/{namespace}/instances/{id}/jobs", account_id=account_id, - name=name, + namespace=namespace, id=id, ), body=maybe_transform({"description": description}, job_create_params.JobCreateParams), @@ -112,7 +112,7 @@ def update( job_id: str, *, account_id: str, - name: str, + namespace: str, id: str, action: Literal["cancel"], # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -123,7 +123,7 @@ def update( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> JobUpdateResponse: """ - Cancel an in-progress indexing job for an AI Search instance. + Cancels an in-progress indexing job for an AI Search instance. Args: id: AI Search instance ID. Lowercase alphanumeric, hyphens, and underscores. @@ -138,17 +138,17 @@ def update( """ if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not name: - raise ValueError(f"Expected a non-empty value for `name` but received {name!r}") + if not namespace: + raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}") if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") if not job_id: raise ValueError(f"Expected a non-empty value for `job_id` but received {job_id!r}") return self._patch( path_template( - "/accounts/{account_id}/ai-search/namespaces/{name}/instances/{id}/jobs/{job_id}", + "/accounts/{account_id}/ai-search/namespaces/{namespace}/instances/{id}/jobs/{job_id}", account_id=account_id, - name=name, + namespace=namespace, id=id, job_id=job_id, ), @@ -168,7 +168,7 @@ def list( id: str, *, account_id: str, - name: str, + namespace: str, page: int | Omit = omit, per_page: int | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -194,15 +194,15 @@ def list( """ if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not name: - raise ValueError(f"Expected a non-empty value for `name` but received {name!r}") + if not namespace: + raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}") if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._get_api_list( path_template( - "/accounts/{account_id}/ai-search/namespaces/{name}/instances/{id}/jobs", + "/accounts/{account_id}/ai-search/namespaces/{namespace}/instances/{id}/jobs", account_id=account_id, - name=name, + namespace=namespace, id=id, ), page=SyncV4PagePaginationArray[JobListResponse], @@ -227,7 +227,7 @@ def get( job_id: str, *, account_id: str, - name: str, + namespace: str, id: str, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. @@ -252,17 +252,17 @@ def get( """ if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not name: - raise ValueError(f"Expected a non-empty value for `name` but received {name!r}") + if not namespace: + raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}") if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") if not job_id: raise ValueError(f"Expected a non-empty value for `job_id` but received {job_id!r}") return self._get( path_template( - "/accounts/{account_id}/ai-search/namespaces/{name}/instances/{id}/jobs/{job_id}", + "/accounts/{account_id}/ai-search/namespaces/{namespace}/instances/{id}/jobs/{job_id}", account_id=account_id, - name=name, + namespace=namespace, id=id, job_id=job_id, ), @@ -281,7 +281,7 @@ def logs( job_id: str, *, account_id: str, - name: str, + namespace: str, id: str, page: int | Omit = omit, per_page: int | Omit = omit, @@ -308,17 +308,17 @@ def logs( """ if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not name: - raise ValueError(f"Expected a non-empty value for `name` but received {name!r}") + if not namespace: + raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}") if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") if not job_id: raise ValueError(f"Expected a non-empty value for `job_id` but received {job_id!r}") return self._get( path_template( - "/accounts/{account_id}/ai-search/namespaces/{name}/instances/{id}/jobs/{job_id}/logs", + "/accounts/{account_id}/ai-search/namespaces/{namespace}/instances/{id}/jobs/{job_id}/logs", account_id=account_id, - name=name, + namespace=namespace, id=id, job_id=job_id, ), @@ -365,7 +365,7 @@ async def create( id: str, *, account_id: str, - name: str, + namespace: str, description: str | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. @@ -390,15 +390,15 @@ async def create( """ if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not name: - raise ValueError(f"Expected a non-empty value for `name` but received {name!r}") + if not namespace: + raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}") if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._post( path_template( - "/accounts/{account_id}/ai-search/namespaces/{name}/instances/{id}/jobs", + "/accounts/{account_id}/ai-search/namespaces/{namespace}/instances/{id}/jobs", account_id=account_id, - name=name, + namespace=namespace, id=id, ), body=await async_maybe_transform({"description": description}, job_create_params.JobCreateParams), @@ -417,7 +417,7 @@ async def update( job_id: str, *, account_id: str, - name: str, + namespace: str, id: str, action: Literal["cancel"], # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -428,7 +428,7 @@ async def update( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> JobUpdateResponse: """ - Cancel an in-progress indexing job for an AI Search instance. + Cancels an in-progress indexing job for an AI Search instance. Args: id: AI Search instance ID. Lowercase alphanumeric, hyphens, and underscores. @@ -443,17 +443,17 @@ async def update( """ if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not name: - raise ValueError(f"Expected a non-empty value for `name` but received {name!r}") + if not namespace: + raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}") if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") if not job_id: raise ValueError(f"Expected a non-empty value for `job_id` but received {job_id!r}") return await self._patch( path_template( - "/accounts/{account_id}/ai-search/namespaces/{name}/instances/{id}/jobs/{job_id}", + "/accounts/{account_id}/ai-search/namespaces/{namespace}/instances/{id}/jobs/{job_id}", account_id=account_id, - name=name, + namespace=namespace, id=id, job_id=job_id, ), @@ -473,7 +473,7 @@ def list( id: str, *, account_id: str, - name: str, + namespace: str, page: int | Omit = omit, per_page: int | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -499,15 +499,15 @@ def list( """ if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not name: - raise ValueError(f"Expected a non-empty value for `name` but received {name!r}") + if not namespace: + raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}") if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._get_api_list( path_template( - "/accounts/{account_id}/ai-search/namespaces/{name}/instances/{id}/jobs", + "/accounts/{account_id}/ai-search/namespaces/{namespace}/instances/{id}/jobs", account_id=account_id, - name=name, + namespace=namespace, id=id, ), page=AsyncV4PagePaginationArray[JobListResponse], @@ -532,7 +532,7 @@ async def get( job_id: str, *, account_id: str, - name: str, + namespace: str, id: str, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. @@ -557,17 +557,17 @@ async def get( """ if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not name: - raise ValueError(f"Expected a non-empty value for `name` but received {name!r}") + if not namespace: + raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}") if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") if not job_id: raise ValueError(f"Expected a non-empty value for `job_id` but received {job_id!r}") return await self._get( path_template( - "/accounts/{account_id}/ai-search/namespaces/{name}/instances/{id}/jobs/{job_id}", + "/accounts/{account_id}/ai-search/namespaces/{namespace}/instances/{id}/jobs/{job_id}", account_id=account_id, - name=name, + namespace=namespace, id=id, job_id=job_id, ), @@ -586,7 +586,7 @@ async def logs( job_id: str, *, account_id: str, - name: str, + namespace: str, id: str, page: int | Omit = omit, per_page: int | Omit = omit, @@ -613,17 +613,17 @@ async def logs( """ if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not name: - raise ValueError(f"Expected a non-empty value for `name` but received {name!r}") + if not namespace: + raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}") if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") if not job_id: raise ValueError(f"Expected a non-empty value for `job_id` but received {job_id!r}") return await self._get( path_template( - "/accounts/{account_id}/ai-search/namespaces/{name}/instances/{id}/jobs/{job_id}/logs", + "/accounts/{account_id}/ai-search/namespaces/{namespace}/instances/{id}/jobs/{job_id}/logs", account_id=account_id, - name=name, + namespace=namespace, id=id, job_id=job_id, ), diff --git a/src/cloudflare/resources/aisearch/namespaces/namespaces.py b/src/cloudflare/resources/aisearch/namespaces/namespaces.py index 7d77eb1f5db..3c161f8fa7b 100644 --- a/src/cloudflare/resources/aisearch/namespaces/namespaces.py +++ b/src/cloudflare/resources/aisearch/namespaces/namespaces.py @@ -133,7 +133,7 @@ def update( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> NamespaceUpdateResponse: """ - Update the description and/or the public endpoint configuration of an existing + Updates the description and/or the public endpoint configuration of an existing namespace. The default namespace's description cannot be modified, but its public endpoint can. @@ -186,7 +186,8 @@ def list( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> SyncV4PagePaginationArray[NamespaceListResponse]: """ - List namespaces in the account, including their descriptions and creation times. + Lists namespaces in the account, including their descriptions and creation + times. Args: page: Page number (1-indexed). @@ -238,10 +239,11 @@ def delete( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> object: - """Permanently delete a namespace. + """Deletes a namespace permanently. - The namespace must be empty (no instances), and - the default namespace cannot be deleted. + The namespace must not contain any instances + (instances whose deletion is still in progress do not count), and the default + namespace cannot be deleted. Args: extra_headers: Send extra headers @@ -516,7 +518,7 @@ async def update( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> NamespaceUpdateResponse: """ - Update the description and/or the public endpoint configuration of an existing + Updates the description and/or the public endpoint configuration of an existing namespace. The default namespace's description cannot be modified, but its public endpoint can. @@ -569,7 +571,8 @@ def list( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> AsyncPaginator[NamespaceListResponse, AsyncV4PagePaginationArray[NamespaceListResponse]]: """ - List namespaces in the account, including their descriptions and creation times. + Lists namespaces in the account, including their descriptions and creation + times. Args: page: Page number (1-indexed). @@ -621,10 +624,11 @@ async def delete( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> object: - """Permanently delete a namespace. + """Deletes a namespace permanently. - The namespace must be empty (no instances), and - the default namespace cannot be deleted. + The namespace must not contain any instances + (instances whose deletion is still in progress do not count), and the default + namespace cannot be deleted. Args: extra_headers: Send extra headers diff --git a/src/cloudflare/resources/aisearch/tokens.py b/src/cloudflare/resources/aisearch/tokens.py index d4aef9b7fe2..c64f479e38a 100644 --- a/src/cloudflare/resources/aisearch/tokens.py +++ b/src/cloudflare/resources/aisearch/tokens.py @@ -168,7 +168,8 @@ def list( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> SyncV4PagePaginationArray[TokenListResponse]: """ - List stored AI Search credentials in the account without exposing their secrets. + Lists stored AI Search credentials in the account without exposing their + secrets. Args: page: Page number (1-indexed). @@ -219,7 +220,7 @@ def delete( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> object: - """Permanently delete a stored AI Search credential. + """Deletes a stored AI Search credential permanently. Credentials in use by an instance cannot be deleted. @@ -430,7 +431,8 @@ def list( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> AsyncPaginator[TokenListResponse, AsyncV4PagePaginationArray[TokenListResponse]]: """ - List stored AI Search credentials in the account without exposing their secrets. + Lists stored AI Search credentials in the account without exposing their + secrets. Args: page: Page number (1-indexed). @@ -481,7 +483,7 @@ async def delete( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> object: - """Permanently delete a stored AI Search credential. + """Deletes a stored AI Search credential permanently. Credentials in use by an instance cannot be deleted. diff --git a/src/cloudflare/resources/api_gateway/api.md b/src/cloudflare/resources/api_gateway/api.md index 103bfb691ca..3e3168185ba 100644 --- a/src/cloudflare/resources/api_gateway/api.md +++ b/src/cloudflare/resources/api_gateway/api.md @@ -30,13 +30,14 @@ Methods: Types: ```python -from cloudflare.types.api_gateway.discovery import OperationBulkEditResponse +from cloudflare.types.api_gateway.discovery import OperationBulkEditResponse, OperationEditResponse ``` Methods: - client.api_gateway.discovery.operations.list(\*, zone_id, \*\*params) -> SyncV4PagePaginationArray[DiscoveryOperation] - client.api_gateway.discovery.operations.bulk_edit(\*, zone_id, \*\*params) -> OperationBulkEditResponse +- client.api_gateway.discovery.operations.edit(discovery_id, \*, zone_id, \*\*params) -> OperationEditResponse ## Labels diff --git a/src/cloudflare/resources/api_gateway/discovery/operations.py b/src/cloudflare/resources/api_gateway/discovery/operations.py index 62550c70a6a..4d9b1f96502 100644 --- a/src/cloudflare/resources/api_gateway/discovery/operations.py +++ b/src/cloudflare/resources/api_gateway/discovery/operations.py @@ -20,8 +20,9 @@ from ...._wrappers import ResultWrapper from ....pagination import SyncV4PagePaginationArray, AsyncV4PagePaginationArray from ...._base_client import AsyncPaginator, make_request_options -from ....types.api_gateway.discovery import operation_list_params, operation_bulk_edit_params +from ....types.api_gateway.discovery import operation_edit_params, operation_list_params, operation_bulk_edit_params from ....types.api_gateway.discovery_operation import DiscoveryOperation +from ....types.api_gateway.discovery.operation_edit_response import OperationEditResponse from ....types.api_gateway.discovery.operation_bulk_edit_response import OperationBulkEditResponse __all__ = ["OperationsResource", "AsyncOperationsResource"] @@ -186,6 +187,61 @@ def bulk_edit( cast_to=cast(Type[OperationBulkEditResponse], ResultWrapper[OperationBulkEditResponse]), ) + def edit( + self, + discovery_id: str, + *, + zone_id: str, + state: Literal["review", "ignored"] | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> OperationEditResponse: + """ + Updates the state of a discovered web or API operation. + + Args: + zone_id: Identifier. + + discovery_id: UUID. + + state: Mark state of operation in API Discovery + + - `review` - Mark operation as for review + - `ignored` - Mark operation as ignored + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + if not discovery_id: + raise ValueError(f"Expected a non-empty value for `discovery_id` but received {discovery_id!r}") + return self._patch( + path_template( + "/zones/{zone_id}/api_gateway/discovery/operations/{discovery_id}", + zone_id=zone_id, + discovery_id=discovery_id, + ), + body=maybe_transform({"state": state}, operation_edit_params.OperationEditParams), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[OperationEditResponse]._unwrapper, + ), + cast_to=cast(Type[OperationEditResponse], ResultWrapper[OperationEditResponse]), + ) + class AsyncOperationsResource(AsyncAPIResource): @cached_property @@ -346,6 +402,61 @@ async def bulk_edit( cast_to=cast(Type[OperationBulkEditResponse], ResultWrapper[OperationBulkEditResponse]), ) + async def edit( + self, + discovery_id: str, + *, + zone_id: str, + state: Literal["review", "ignored"] | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> OperationEditResponse: + """ + Updates the state of a discovered web or API operation. + + Args: + zone_id: Identifier. + + discovery_id: UUID. + + state: Mark state of operation in API Discovery + + - `review` - Mark operation as for review + - `ignored` - Mark operation as ignored + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + if not discovery_id: + raise ValueError(f"Expected a non-empty value for `discovery_id` but received {discovery_id!r}") + return await self._patch( + path_template( + "/zones/{zone_id}/api_gateway/discovery/operations/{discovery_id}", + zone_id=zone_id, + discovery_id=discovery_id, + ), + body=await async_maybe_transform({"state": state}, operation_edit_params.OperationEditParams), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[OperationEditResponse]._unwrapper, + ), + cast_to=cast(Type[OperationEditResponse], ResultWrapper[OperationEditResponse]), + ) + class OperationsResourceWithRawResponse: def __init__(self, operations: OperationsResource) -> None: @@ -357,6 +468,9 @@ def __init__(self, operations: OperationsResource) -> None: self.bulk_edit = to_raw_response_wrapper( operations.bulk_edit, ) + self.edit = to_raw_response_wrapper( + operations.edit, + ) class AsyncOperationsResourceWithRawResponse: @@ -369,6 +483,9 @@ def __init__(self, operations: AsyncOperationsResource) -> None: self.bulk_edit = async_to_raw_response_wrapper( operations.bulk_edit, ) + self.edit = async_to_raw_response_wrapper( + operations.edit, + ) class OperationsResourceWithStreamingResponse: @@ -381,6 +498,9 @@ def __init__(self, operations: OperationsResource) -> None: self.bulk_edit = to_streamed_response_wrapper( operations.bulk_edit, ) + self.edit = to_streamed_response_wrapper( + operations.edit, + ) class AsyncOperationsResourceWithStreamingResponse: @@ -393,3 +513,6 @@ def __init__(self, operations: AsyncOperationsResource) -> None: self.bulk_edit = async_to_streamed_response_wrapper( operations.bulk_edit, ) + self.edit = async_to_streamed_response_wrapper( + operations.edit, + ) diff --git a/src/cloudflare/resources/argo/tiered_caching.py b/src/cloudflare/resources/argo/tiered_caching.py index 789a9032f60..bd90c376263 100644 --- a/src/cloudflare/resources/argo/tiered_caching.py +++ b/src/cloudflare/resources/argo/tiered_caching.py @@ -58,23 +58,16 @@ def edit( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Optional[TieredCachingEditResponse]: - """ - Tiered Cache works by dividing Cloudflare's data centers into a hierarchy of - lower-tiers and upper-tiers. If content is not cached in lower-tier data centers - (generally the ones closest to a visitor), the lower-tier must ask an upper-tier - to see if it has the content. If the upper-tier does not have the content, only - the upper-tier can ask the origin for content. This practice improves bandwidth - efficiency by limiting the number of data centers that can ask the origin for - content, which reduces origin load and makes websites more cost-effective to - operate. Additionally, Tiered Cache concentrates connections to origin servers - so they come from a small number of data centers rather than the full set of - network locations. This results in fewer open connections using server - resources. + """Enables or disables Tiered Cache for a zone. + + Tiered Cache reduces origin traffic + by serving lower-tier cache misses from upper-tier data centers before + requesting content from your origin. Args: zone_id: Identifier. - value: Enables Tiered Caching. + value: Enables or disables Tiered Cache. extra_headers: Send extra headers @@ -110,18 +103,11 @@ def get( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Optional[TieredCachingGetResponse]: - """ - Tiered Cache works by dividing Cloudflare's data centers into a hierarchy of - lower-tiers and upper-tiers. If content is not cached in lower-tier data centers - (generally the ones closest to a visitor), the lower-tier must ask an upper-tier - to see if it has the content. If the upper-tier does not have the content, only - the upper-tier can ask the origin for content. This practice improves bandwidth - efficiency by limiting the number of data centers that can ask the origin for - content, which reduces origin load and makes websites more cost-effective to - operate. Additionally, Tiered Cache concentrates connections to origin servers - so they come from a small number of data centers rather than the full set of - network locations. This results in fewer open connections using server - resources. + """Retrieves whether Tiered Cache is enabled for a zone. + + Tiered Cache reduces + origin traffic by serving lower-tier cache misses from upper-tier data centers + before requesting content from your origin. Args: zone_id: Identifier. @@ -181,23 +167,16 @@ async def edit( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Optional[TieredCachingEditResponse]: - """ - Tiered Cache works by dividing Cloudflare's data centers into a hierarchy of - lower-tiers and upper-tiers. If content is not cached in lower-tier data centers - (generally the ones closest to a visitor), the lower-tier must ask an upper-tier - to see if it has the content. If the upper-tier does not have the content, only - the upper-tier can ask the origin for content. This practice improves bandwidth - efficiency by limiting the number of data centers that can ask the origin for - content, which reduces origin load and makes websites more cost-effective to - operate. Additionally, Tiered Cache concentrates connections to origin servers - so they come from a small number of data centers rather than the full set of - network locations. This results in fewer open connections using server - resources. + """Enables or disables Tiered Cache for a zone. + + Tiered Cache reduces origin traffic + by serving lower-tier cache misses from upper-tier data centers before + requesting content from your origin. Args: zone_id: Identifier. - value: Enables Tiered Caching. + value: Enables or disables Tiered Cache. extra_headers: Send extra headers @@ -233,18 +212,11 @@ async def get( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Optional[TieredCachingGetResponse]: - """ - Tiered Cache works by dividing Cloudflare's data centers into a hierarchy of - lower-tiers and upper-tiers. If content is not cached in lower-tier data centers - (generally the ones closest to a visitor), the lower-tier must ask an upper-tier - to see if it has the content. If the upper-tier does not have the content, only - the upper-tier can ask the origin for content. This practice improves bandwidth - efficiency by limiting the number of data centers that can ask the origin for - content, which reduces origin load and makes websites more cost-effective to - operate. Additionally, Tiered Cache concentrates connections to origin servers - so they come from a small number of data centers rather than the full set of - network locations. This results in fewer open connections using server - resources. + """Retrieves whether Tiered Cache is enabled for a zone. + + Tiered Cache reduces + origin traffic by serving lower-tier cache misses from upper-tier data centers + before requesting content from your origin. Args: zone_id: Identifier. diff --git a/src/cloudflare/resources/basin_catalog/api.md b/src/cloudflare/resources/basin_catalog/api.md index bd65110b18b..728b859f1fd 100644 --- a/src/cloudflare/resources/basin_catalog/api.md +++ b/src/cloudflare/resources/basin_catalog/api.md @@ -15,7 +15,7 @@ Methods: - client.basin_catalog.list(\*, account_id) -> Optional[BasinCatalogListResponse] - client.basin_catalog.delete(bucket_name, \*, account_id, \*\*params) -> None - client.basin_catalog.disable(bucket_name, \*, account_id) -> None -- client.basin_catalog.enable(bucket_name, \*, account_id) -> Optional[BasinCatalogEnableResponse] +- client.basin_catalog.enable(bucket_name, \*, account_id, \*\*params) -> Optional[BasinCatalogEnableResponse] - client.basin_catalog.get(bucket_name, \*, account_id) -> Optional[BasinCatalogGetResponse] ## MaintenanceConfigs diff --git a/src/cloudflare/resources/basin_catalog/basin_catalog.py b/src/cloudflare/resources/basin_catalog/basin_catalog.py index e6dc9ecb861..cf0dbf2eb01 100644 --- a/src/cloudflare/resources/basin_catalog/basin_catalog.py +++ b/src/cloudflare/resources/basin_catalog/basin_catalog.py @@ -34,7 +34,7 @@ MaintenanceConfigsResourceWithStreamingResponse, AsyncMaintenanceConfigsResourceWithStreamingResponse, ) -from ...types.basin_catalog import basin_catalog_delete_params +from ...types.basin_catalog import basin_catalog_delete_params, basin_catalog_enable_params from .namespaces.namespaces import ( NamespacesResource, AsyncNamespacesResource, @@ -229,6 +229,7 @@ def enable( bucket_name: str, *, account_id: str, + credential: basin_catalog_enable_params.Credential | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -247,6 +248,8 @@ def enable( bucket_name: Specifies the R2 bucket name. + credential: Contains request to store catalog credentials. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -265,6 +268,7 @@ def enable( account_id=account_id, bucket_name=bucket_name, ), + body=maybe_transform({"credential": credential}, basin_catalog_enable_params.BasinCatalogEnableParams), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, @@ -504,6 +508,7 @@ async def enable( bucket_name: str, *, account_id: str, + credential: basin_catalog_enable_params.Credential | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -522,6 +527,8 @@ async def enable( bucket_name: Specifies the R2 bucket name. + credential: Contains request to store catalog credentials. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -540,6 +547,9 @@ async def enable( account_id=account_id, bucket_name=bucket_name, ), + body=await async_maybe_transform( + {"credential": credential}, basin_catalog_enable_params.BasinCatalogEnableParams + ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, diff --git a/src/cloudflare/resources/billing/__init__.py b/src/cloudflare/resources/billing/__init__.py index b9b1f2251c0..ca23ec3b91e 100644 --- a/src/cloudflare/resources/billing/__init__.py +++ b/src/cloudflare/resources/billing/__init__.py @@ -56,6 +56,14 @@ RatePlansResourceWithStreamingResponse, AsyncRatePlansResourceWithStreamingResponse, ) +from .spend_policies import ( + SpendPoliciesResource, + AsyncSpendPoliciesResource, + SpendPoliciesResourceWithRawResponse, + AsyncSpendPoliciesResourceWithRawResponse, + SpendPoliciesResourceWithStreamingResponse, + AsyncSpendPoliciesResourceWithStreamingResponse, +) from .unpaid_invoice import ( UnpaidInvoiceResource, AsyncUnpaidInvoiceResource, @@ -66,6 +74,12 @@ ) __all__ = [ + "SpendPoliciesResource", + "AsyncSpendPoliciesResource", + "SpendPoliciesResourceWithRawResponse", + "AsyncSpendPoliciesResourceWithRawResponse", + "SpendPoliciesResourceWithStreamingResponse", + "AsyncSpendPoliciesResourceWithStreamingResponse", "ProfilesResource", "AsyncProfilesResource", "ProfilesResourceWithRawResponse", diff --git a/src/cloudflare/resources/billing/api.md b/src/cloudflare/resources/billing/api.md index 17fe1669c34..f08d38d94f4 100644 --- a/src/cloudflare/resources/billing/api.md +++ b/src/cloudflare/resources/billing/api.md @@ -10,6 +10,52 @@ Methods: - client.billing.address_validation(\*\*params) -> BillingAddressValidationResponse +## SpendPolicies + +Types: + +```python +from cloudflare.types.billing import ( + SpendPolicyCreateResponse, + SpendPolicyUpdateResponse, + SpendPolicyListResponse, + SpendPolicyDeleteResponse, + SpendPolicyGetResponse, +) +``` + +Methods: + +- client.billing.spend_policies.create(\*, account_id, \*\*params) -> SpendPolicyCreateResponse +- client.billing.spend_policies.update(policy_id, \*, account_id, \*\*params) -> SpendPolicyUpdateResponse +- client.billing.spend_policies.list(\*, account_id) -> SyncSinglePage[SpendPolicyListResponse] +- client.billing.spend_policies.delete(policy_id, \*, account_id) -> SpendPolicyDeleteResponse +- client.billing.spend_policies.get(policy_id, \*, account_id) -> SpendPolicyGetResponse + +### Audit + +Types: + +```python +from cloudflare.types.billing.spend_policies import AuditListResponse +``` + +Methods: + +- client.billing.spend_policies.audit.list(policy_id, \*, account_id, \*\*params) -> SyncSinglePage[AuditListResponse] + +### Activity + +Types: + +```python +from cloudflare.types.billing.spend_policies import ActivityListResponse +``` + +Methods: + +- client.billing.spend_policies.activity.list(\*, account_id, \*\*params) -> SyncCursorPaginationAfter[ActivityListResponse] + ## Profiles Types: diff --git a/src/cloudflare/resources/billing/billing.py b/src/cloudflare/resources/billing/billing.py index 39e8ba13570..7a5657feee7 100644 --- a/src/cloudflare/resources/billing/billing.py +++ b/src/cloudflare/resources/billing/billing.py @@ -75,12 +75,24 @@ ProfilesResourceWithStreamingResponse, AsyncProfilesResourceWithStreamingResponse, ) +from .spend_policies.spend_policies import ( + SpendPoliciesResource, + AsyncSpendPoliciesResource, + SpendPoliciesResourceWithRawResponse, + AsyncSpendPoliciesResourceWithRawResponse, + SpendPoliciesResourceWithStreamingResponse, + AsyncSpendPoliciesResourceWithStreamingResponse, +) from ...types.billing.billing_address_validation_response import BillingAddressValidationResponse __all__ = ["BillingResource", "AsyncBillingResource"] class BillingResource(SyncAPIResource): + @cached_property + def spend_policies(self) -> SpendPoliciesResource: + return SpendPoliciesResource(self._client) + @cached_property def profiles(self) -> ProfilesResource: return ProfilesResource(self._client) @@ -195,6 +207,10 @@ def address_validation( class AsyncBillingResource(AsyncAPIResource): + @cached_property + def spend_policies(self) -> AsyncSpendPoliciesResource: + return AsyncSpendPoliciesResource(self._client) + @cached_property def profiles(self) -> AsyncProfilesResource: return AsyncProfilesResource(self._client) @@ -316,6 +332,10 @@ def __init__(self, billing: BillingResource) -> None: billing.address_validation, ) + @cached_property + def spend_policies(self) -> SpendPoliciesResourceWithRawResponse: + return SpendPoliciesResourceWithRawResponse(self._billing.spend_policies) + @cached_property def profiles(self) -> ProfilesResourceWithRawResponse: return ProfilesResourceWithRawResponse(self._billing.profiles) @@ -353,6 +373,10 @@ def __init__(self, billing: AsyncBillingResource) -> None: billing.address_validation, ) + @cached_property + def spend_policies(self) -> AsyncSpendPoliciesResourceWithRawResponse: + return AsyncSpendPoliciesResourceWithRawResponse(self._billing.spend_policies) + @cached_property def profiles(self) -> AsyncProfilesResourceWithRawResponse: return AsyncProfilesResourceWithRawResponse(self._billing.profiles) @@ -390,6 +414,10 @@ def __init__(self, billing: BillingResource) -> None: billing.address_validation, ) + @cached_property + def spend_policies(self) -> SpendPoliciesResourceWithStreamingResponse: + return SpendPoliciesResourceWithStreamingResponse(self._billing.spend_policies) + @cached_property def profiles(self) -> ProfilesResourceWithStreamingResponse: return ProfilesResourceWithStreamingResponse(self._billing.profiles) @@ -427,6 +455,10 @@ def __init__(self, billing: AsyncBillingResource) -> None: billing.address_validation, ) + @cached_property + def spend_policies(self) -> AsyncSpendPoliciesResourceWithStreamingResponse: + return AsyncSpendPoliciesResourceWithStreamingResponse(self._billing.spend_policies) + @cached_property def profiles(self) -> AsyncProfilesResourceWithStreamingResponse: return AsyncProfilesResourceWithStreamingResponse(self._billing.profiles) diff --git a/src/cloudflare/resources/billing/spend_policies/__init__.py b/src/cloudflare/resources/billing/spend_policies/__init__.py new file mode 100644 index 00000000000..058b7d69f44 --- /dev/null +++ b/src/cloudflare/resources/billing/spend_policies/__init__.py @@ -0,0 +1,47 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from .audit import ( + AuditResource, + AsyncAuditResource, + AuditResourceWithRawResponse, + AsyncAuditResourceWithRawResponse, + AuditResourceWithStreamingResponse, + AsyncAuditResourceWithStreamingResponse, +) +from .activity import ( + ActivityResource, + AsyncActivityResource, + ActivityResourceWithRawResponse, + AsyncActivityResourceWithRawResponse, + ActivityResourceWithStreamingResponse, + AsyncActivityResourceWithStreamingResponse, +) +from .spend_policies import ( + SpendPoliciesResource, + AsyncSpendPoliciesResource, + SpendPoliciesResourceWithRawResponse, + AsyncSpendPoliciesResourceWithRawResponse, + SpendPoliciesResourceWithStreamingResponse, + AsyncSpendPoliciesResourceWithStreamingResponse, +) + +__all__ = [ + "AuditResource", + "AsyncAuditResource", + "AuditResourceWithRawResponse", + "AsyncAuditResourceWithRawResponse", + "AuditResourceWithStreamingResponse", + "AsyncAuditResourceWithStreamingResponse", + "ActivityResource", + "AsyncActivityResource", + "ActivityResourceWithRawResponse", + "AsyncActivityResourceWithRawResponse", + "ActivityResourceWithStreamingResponse", + "AsyncActivityResourceWithStreamingResponse", + "SpendPoliciesResource", + "AsyncSpendPoliciesResource", + "SpendPoliciesResourceWithRawResponse", + "AsyncSpendPoliciesResourceWithRawResponse", + "SpendPoliciesResourceWithStreamingResponse", + "AsyncSpendPoliciesResourceWithStreamingResponse", +] diff --git a/src/cloudflare/resources/billing/spend_policies/activity.py b/src/cloudflare/resources/billing/spend_policies/activity.py new file mode 100644 index 00000000000..e5d17ce9440 --- /dev/null +++ b/src/cloudflare/resources/billing/spend_policies/activity.py @@ -0,0 +1,242 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal + +import httpx + +from ...._types import Body, Omit, Query, Headers, NotGiven, omit, not_given +from ...._utils import path_template, maybe_transform +from ...._compat import cached_property +from ...._resource import SyncAPIResource, AsyncAPIResource +from ...._response import ( + to_raw_response_wrapper, + to_streamed_response_wrapper, + async_to_raw_response_wrapper, + async_to_streamed_response_wrapper, +) +from ....pagination import SyncCursorPaginationAfter, AsyncCursorPaginationAfter +from ...._base_client import AsyncPaginator, make_request_options +from ....types.billing.spend_policies import activity_list_params +from ....types.billing.spend_policies.activity_list_response import ActivityListResponse + +__all__ = ["ActivityResource", "AsyncActivityResource"] + + +class ActivityResource(SyncAPIResource): + @cached_property + def with_raw_response(self) -> ActivityResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers + """ + return ActivityResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> ActivityResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response + """ + return ActivityResourceWithStreamingResponse(self) + + def list( + self, + *, + account_id: str, + cursor: str | Omit = omit, + limit: int | Omit = omit, + period: Literal["current_billing_cycle", "all"] | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> SyncCursorPaginationAfter[ActivityListResponse]: + """ + Returns configuration history from immutable policy revisions for the account, + including deleted policies. Entries contain before/after values and verified + actor attribution. Pages use descending revision IDs, not event or commit order; + refresh the first page for new entries. This cursor is not an incremental + consumer checkpoint. Defaults to `period=current_billing_cycle`: each revision's + timestamp must be within its product's current subscription cycle (inclusive + start, exclusive end). Each product's cycle is resolved independently from + canonical aggregates, including for disabled or deleted policies. Set + `period=all` for history across cycles. Filtering happens before pagination. No + current cycles returns an empty page; unavailable or disabled cycle resolution + returns `503` with code `1013`. Cursors pin resolved cycle bounds across pages + and must be used with the same period selection. Cursors obtained before this + filter was introduced must be refreshed. + + Args: + account_id: Represents a Cloudflare resource identifier tag. + + cursor: Opaque token from the preceding response's result_info.cursor. Pass it unchanged + to retrieve older entries. + + limit: Maximum number of audit entries to return. Defaults to 50. Values above 100 are + capped at 100 rather than rejected. + + period: Select current subscription billing-cycle history or history across all cycles. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + return self._get_api_list( + path_template("/accounts/{account_id}/billing/spend-policies/activity", account_id=account_id), + page=SyncCursorPaginationAfter[ActivityListResponse], + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "cursor": cursor, + "limit": limit, + "period": period, + }, + activity_list_params.ActivityListParams, + ), + ), + model=ActivityListResponse, + ) + + +class AsyncActivityResource(AsyncAPIResource): + @cached_property + def with_raw_response(self) -> AsyncActivityResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers + """ + return AsyncActivityResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncActivityResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response + """ + return AsyncActivityResourceWithStreamingResponse(self) + + def list( + self, + *, + account_id: str, + cursor: str | Omit = omit, + limit: int | Omit = omit, + period: Literal["current_billing_cycle", "all"] | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> AsyncPaginator[ActivityListResponse, AsyncCursorPaginationAfter[ActivityListResponse]]: + """ + Returns configuration history from immutable policy revisions for the account, + including deleted policies. Entries contain before/after values and verified + actor attribution. Pages use descending revision IDs, not event or commit order; + refresh the first page for new entries. This cursor is not an incremental + consumer checkpoint. Defaults to `period=current_billing_cycle`: each revision's + timestamp must be within its product's current subscription cycle (inclusive + start, exclusive end). Each product's cycle is resolved independently from + canonical aggregates, including for disabled or deleted policies. Set + `period=all` for history across cycles. Filtering happens before pagination. No + current cycles returns an empty page; unavailable or disabled cycle resolution + returns `503` with code `1013`. Cursors pin resolved cycle bounds across pages + and must be used with the same period selection. Cursors obtained before this + filter was introduced must be refreshed. + + Args: + account_id: Represents a Cloudflare resource identifier tag. + + cursor: Opaque token from the preceding response's result_info.cursor. Pass it unchanged + to retrieve older entries. + + limit: Maximum number of audit entries to return. Defaults to 50. Values above 100 are + capped at 100 rather than rejected. + + period: Select current subscription billing-cycle history or history across all cycles. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + return self._get_api_list( + path_template("/accounts/{account_id}/billing/spend-policies/activity", account_id=account_id), + page=AsyncCursorPaginationAfter[ActivityListResponse], + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "cursor": cursor, + "limit": limit, + "period": period, + }, + activity_list_params.ActivityListParams, + ), + ), + model=ActivityListResponse, + ) + + +class ActivityResourceWithRawResponse: + def __init__(self, activity: ActivityResource) -> None: + self._activity = activity + + self.list = to_raw_response_wrapper( + activity.list, + ) + + +class AsyncActivityResourceWithRawResponse: + def __init__(self, activity: AsyncActivityResource) -> None: + self._activity = activity + + self.list = async_to_raw_response_wrapper( + activity.list, + ) + + +class ActivityResourceWithStreamingResponse: + def __init__(self, activity: ActivityResource) -> None: + self._activity = activity + + self.list = to_streamed_response_wrapper( + activity.list, + ) + + +class AsyncActivityResourceWithStreamingResponse: + def __init__(self, activity: AsyncActivityResource) -> None: + self._activity = activity + + self.list = async_to_streamed_response_wrapper( + activity.list, + ) diff --git a/src/cloudflare/resources/billing/spend_policies/audit.py b/src/cloudflare/resources/billing/spend_policies/audit.py new file mode 100644 index 00000000000..2ae52e0cc36 --- /dev/null +++ b/src/cloudflare/resources/billing/spend_policies/audit.py @@ -0,0 +1,248 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal + +import httpx + +from ...._types import Body, Omit, Query, Headers, NotGiven, omit, not_given +from ...._utils import path_template, maybe_transform +from ...._compat import cached_property +from ...._resource import SyncAPIResource, AsyncAPIResource +from ...._response import ( + to_raw_response_wrapper, + to_streamed_response_wrapper, + async_to_raw_response_wrapper, + async_to_streamed_response_wrapper, +) +from ....pagination import SyncSinglePage, AsyncSinglePage +from ...._base_client import AsyncPaginator, make_request_options +from ....types.billing.spend_policies import audit_list_params +from ....types.billing.spend_policies.audit_list_response import AuditListResponse + +__all__ = ["AuditResource", "AsyncAuditResource"] + + +class AuditResource(SyncAPIResource): + @cached_property + def with_raw_response(self) -> AuditResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers + """ + return AuditResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AuditResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response + """ + return AuditResourceWithStreamingResponse(self) + + def list( + self, + policy_id: str, + *, + account_id: str, + limit: int | Omit = omit, + period: Literal["current_billing_cycle", "all"] | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> SyncSinglePage[AuditListResponse]: + """Returns the policy's evaluation history, newest first. + + At most one + threshold-crossing entry (`limit_reached`) is recorded per policy version and + billing period, so a policy update can record a new entry without any change in + balance. Disabled policies still return their history; deleted policies return + `404`. There is no pagination: use `limit` to set how many entries come back. + Defaults to `period=current_billing_cycle`, resolved from the product's + canonical aggregates, not calendar months. Crossings match their recorded + billing-period bounds, even if recorded late. Set `period=all` for history + across cycles. Filtering happens before LIMIT. No current cycle returns an empty + array; unavailable or disabled cycle resolution returns `503` with code `1013`, + never an empty success. + + Args: + account_id: Represents a Cloudflare resource identifier tag. + + policy_id: The unique identifier of the spend policy. + + limit: Maximum number of audit entries to return. Defaults to 50. Values above 100 are + capped at 100 rather than rejected. + + period: Select current subscription billing-cycle history or history across all cycles. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not policy_id: + raise ValueError(f"Expected a non-empty value for `policy_id` but received {policy_id!r}") + return self._get_api_list( + path_template( + "/accounts/{account_id}/billing/spend-policies/{policy_id}/audit", + account_id=account_id, + policy_id=policy_id, + ), + page=SyncSinglePage[AuditListResponse], + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "limit": limit, + "period": period, + }, + audit_list_params.AuditListParams, + ), + ), + model=AuditListResponse, + ) + + +class AsyncAuditResource(AsyncAPIResource): + @cached_property + def with_raw_response(self) -> AsyncAuditResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers + """ + return AsyncAuditResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncAuditResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response + """ + return AsyncAuditResourceWithStreamingResponse(self) + + def list( + self, + policy_id: str, + *, + account_id: str, + limit: int | Omit = omit, + period: Literal["current_billing_cycle", "all"] | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> AsyncPaginator[AuditListResponse, AsyncSinglePage[AuditListResponse]]: + """Returns the policy's evaluation history, newest first. + + At most one + threshold-crossing entry (`limit_reached`) is recorded per policy version and + billing period, so a policy update can record a new entry without any change in + balance. Disabled policies still return their history; deleted policies return + `404`. There is no pagination: use `limit` to set how many entries come back. + Defaults to `period=current_billing_cycle`, resolved from the product's + canonical aggregates, not calendar months. Crossings match their recorded + billing-period bounds, even if recorded late. Set `period=all` for history + across cycles. Filtering happens before LIMIT. No current cycle returns an empty + array; unavailable or disabled cycle resolution returns `503` with code `1013`, + never an empty success. + + Args: + account_id: Represents a Cloudflare resource identifier tag. + + policy_id: The unique identifier of the spend policy. + + limit: Maximum number of audit entries to return. Defaults to 50. Values above 100 are + capped at 100 rather than rejected. + + period: Select current subscription billing-cycle history or history across all cycles. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not policy_id: + raise ValueError(f"Expected a non-empty value for `policy_id` but received {policy_id!r}") + return self._get_api_list( + path_template( + "/accounts/{account_id}/billing/spend-policies/{policy_id}/audit", + account_id=account_id, + policy_id=policy_id, + ), + page=AsyncSinglePage[AuditListResponse], + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "limit": limit, + "period": period, + }, + audit_list_params.AuditListParams, + ), + ), + model=AuditListResponse, + ) + + +class AuditResourceWithRawResponse: + def __init__(self, audit: AuditResource) -> None: + self._audit = audit + + self.list = to_raw_response_wrapper( + audit.list, + ) + + +class AsyncAuditResourceWithRawResponse: + def __init__(self, audit: AsyncAuditResource) -> None: + self._audit = audit + + self.list = async_to_raw_response_wrapper( + audit.list, + ) + + +class AuditResourceWithStreamingResponse: + def __init__(self, audit: AuditResource) -> None: + self._audit = audit + + self.list = to_streamed_response_wrapper( + audit.list, + ) + + +class AsyncAuditResourceWithStreamingResponse: + def __init__(self, audit: AsyncAuditResource) -> None: + self._audit = audit + + self.list = async_to_streamed_response_wrapper( + audit.list, + ) diff --git a/src/cloudflare/resources/billing/spend_policies/spend_policies.py b/src/cloudflare/resources/billing/spend_policies/spend_policies.py new file mode 100644 index 00000000000..5e91db954ce --- /dev/null +++ b/src/cloudflare/resources/billing/spend_policies/spend_policies.py @@ -0,0 +1,832 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Type, cast +from typing_extensions import Literal + +import httpx + +from .audit import ( + AuditResource, + AsyncAuditResource, + AuditResourceWithRawResponse, + AsyncAuditResourceWithRawResponse, + AuditResourceWithStreamingResponse, + AsyncAuditResourceWithStreamingResponse, +) +from .activity import ( + ActivityResource, + AsyncActivityResource, + ActivityResourceWithRawResponse, + AsyncActivityResourceWithRawResponse, + ActivityResourceWithStreamingResponse, + AsyncActivityResourceWithStreamingResponse, +) +from ...._types import Body, Omit, Query, Headers, NotGiven, omit, not_given +from ...._utils import path_template, maybe_transform, async_maybe_transform +from ...._compat import cached_property +from ...._resource import SyncAPIResource, AsyncAPIResource +from ...._response import ( + to_raw_response_wrapper, + to_streamed_response_wrapper, + async_to_raw_response_wrapper, + async_to_streamed_response_wrapper, +) +from ...._wrappers import ResultWrapper +from ....pagination import SyncSinglePage, AsyncSinglePage +from ...._base_client import AsyncPaginator, make_request_options +from ....types.billing import spend_policy_create_params, spend_policy_update_params +from ....types.billing.spend_policy_get_response import SpendPolicyGetResponse +from ....types.billing.spend_policy_list_response import SpendPolicyListResponse +from ....types.billing.spend_policy_create_response import SpendPolicyCreateResponse +from ....types.billing.spend_policy_delete_response import SpendPolicyDeleteResponse +from ....types.billing.spend_policy_update_response import SpendPolicyUpdateResponse + +__all__ = ["SpendPoliciesResource", "AsyncSpendPoliciesResource"] + + +class SpendPoliciesResource(SyncAPIResource): + @cached_property + def audit(self) -> AuditResource: + return AuditResource(self._client) + + @cached_property + def activity(self) -> ActivityResource: + return ActivityResource(self._client) + + @cached_property + def with_raw_response(self) -> SpendPoliciesResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers + """ + return SpendPoliciesResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> SpendPoliciesResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response + """ + return SpendPoliciesResourceWithStreamingResponse(self) + + def create( + self, + *, + account_id: str, + action: Literal["notification", "usage_block"], + enabled: bool, + name: str, + product_id: Literal["workers", "durable_objects"], + threshold_cents: int, + notification_email: str | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> SpendPolicyCreateResponse: + """Creates a spend policy. + + Each account can have only one enabled `usage_block` + policy per product. A second one returns `409`. There is no limit on + `notification` policies. + + Args: + account_id: Represents a Cloudflare resource identifier tag. + + action: The action taken when the threshold is reached. `notification` sends an email to + `notification_email`. `usage_block` blocks further usage of the product until + the end of the billing period. Raising the threshold above the current balance, + disabling the policy, or deleting it lifts the block early. + + enabled: Whether the policy is evaluated. + + name: Display name of the policy. After surrounding whitespace is trimmed, it must be + 1 to 200 bytes long. The value is stored as sent, untrimmed. + + product_id: The product the policy applies to: `workers` or `durable_objects`. Each + product's balance and policies are separate. Both products support + `notification` and `usage_block` policies on create and update. + + threshold_cents: The spend threshold for the current billing period, in US cents. Must be greater + than zero. + + notification_email: Email address that receives notifications. Required when `action` is + `notification`. When set, it must be a bare address (`user@example.com`); + display-name forms such as `Name ` are rejected. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + return self._post( + path_template("/accounts/{account_id}/billing/spend-policies", account_id=account_id), + body=maybe_transform( + { + "action": action, + "enabled": enabled, + "name": name, + "product_id": product_id, + "threshold_cents": threshold_cents, + "notification_email": notification_email, + }, + spend_policy_create_params.SpendPolicyCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[SpendPolicyCreateResponse]._unwrapper, + ), + cast_to=cast(Type[SpendPolicyCreateResponse], ResultWrapper[SpendPolicyCreateResponse]), + ) + + def update( + self, + policy_id: str, + *, + account_id: str, + action: Literal["notification", "usage_block"], + enabled: bool, + name: str, + product_id: Literal["workers", "durable_objects"], + threshold_cents: int, + if_match: str, + notification_email: str | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> SpendPolicyUpdateResponse: + """Replaces the whole spend policy. + + Every field is required, as on create; there + are no partial updates and `PATCH` is not supported. The `If-Match` header must + equal the policy's current `version`. On success, `version` goes up by one and + the new value is returned in `ETag`. + + Args: + account_id: Represents a Cloudflare resource identifier tag. + + policy_id: The unique identifier of the spend policy. + + action: The action taken when the threshold is reached. `notification` sends an email to + `notification_email`. `usage_block` blocks further usage of the product until + the end of the billing period. Raising the threshold above the current balance, + disabling the policy, or deleting it lifts the block early. + + enabled: Whether the policy is evaluated. + + name: Display name of the policy. After surrounding whitespace is trimmed, it must be + 1 to 200 bytes long. The value is stored as sent, untrimmed. + + product_id: The product the policy applies to: `workers` or `durable_objects`. Each + product's balance and policies are separate. Both products support + `notification` and `usage_block` policies on create and update. + + threshold_cents: The spend threshold for the current billing period, in US cents. Must be greater + than zero. + + notification_email: Email address that receives notifications. Required when `action` is + `notification`. When set, it must be a bare address (`user@example.com`); + display-name forms such as `Name ` are rejected. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not policy_id: + raise ValueError(f"Expected a non-empty value for `policy_id` but received {policy_id!r}") + extra_headers = {"If-Match": if_match, **(extra_headers or {})} + return self._put( + path_template( + "/accounts/{account_id}/billing/spend-policies/{policy_id}", account_id=account_id, policy_id=policy_id + ), + body=maybe_transform( + { + "action": action, + "enabled": enabled, + "name": name, + "product_id": product_id, + "threshold_cents": threshold_cents, + "notification_email": notification_email, + }, + spend_policy_update_params.SpendPolicyUpdateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[SpendPolicyUpdateResponse]._unwrapper, + ), + cast_to=cast(Type[SpendPolicyUpdateResponse], ResultWrapper[SpendPolicyUpdateResponse]), + ) + + def list( + self, + *, + account_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> SyncSinglePage[SpendPolicyListResponse]: + """ + Returns every spend policy on the account that has not been deleted, including + disabled ones. Results are sorted by `name`, then `id`. There is no pagination. + + Args: + account_id: Represents a Cloudflare resource identifier tag. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + return self._get_api_list( + path_template("/accounts/{account_id}/billing/spend-policies", account_id=account_id), + page=SyncSinglePage[SpendPolicyListResponse], + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + model=SpendPolicyListResponse, + ) + + def delete( + self, + policy_id: str, + *, + account_id: str, + if_match: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> SpendPolicyDeleteResponse: + """Soft-deletes the spend policy. + + The policy is disabled and no longer appears in + list, get or audit responses. The `If-Match` header must equal the policy's + current `version`. + + Args: + account_id: Represents a Cloudflare resource identifier tag. + + policy_id: The unique identifier of the spend policy. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not policy_id: + raise ValueError(f"Expected a non-empty value for `policy_id` but received {policy_id!r}") + extra_headers = {"If-Match": if_match, **(extra_headers or {})} + return self._delete( + path_template( + "/accounts/{account_id}/billing/spend-policies/{policy_id}", account_id=account_id, policy_id=policy_id + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[SpendPolicyDeleteResponse]._unwrapper, + ), + cast_to=cast(Type[SpendPolicyDeleteResponse], ResultWrapper[SpendPolicyDeleteResponse]), + ) + + def get( + self, + policy_id: str, + *, + account_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> SpendPolicyGetResponse: + """Returns one spend policy. + + The `ETag` response header holds the current + `version`; send it as `If-Match` on a later update or delete. + + Args: + account_id: Represents a Cloudflare resource identifier tag. + + policy_id: The unique identifier of the spend policy. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not policy_id: + raise ValueError(f"Expected a non-empty value for `policy_id` but received {policy_id!r}") + return self._get( + path_template( + "/accounts/{account_id}/billing/spend-policies/{policy_id}", account_id=account_id, policy_id=policy_id + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[SpendPolicyGetResponse]._unwrapper, + ), + cast_to=cast(Type[SpendPolicyGetResponse], ResultWrapper[SpendPolicyGetResponse]), + ) + + +class AsyncSpendPoliciesResource(AsyncAPIResource): + @cached_property + def audit(self) -> AsyncAuditResource: + return AsyncAuditResource(self._client) + + @cached_property + def activity(self) -> AsyncActivityResource: + return AsyncActivityResource(self._client) + + @cached_property + def with_raw_response(self) -> AsyncSpendPoliciesResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers + """ + return AsyncSpendPoliciesResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncSpendPoliciesResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response + """ + return AsyncSpendPoliciesResourceWithStreamingResponse(self) + + async def create( + self, + *, + account_id: str, + action: Literal["notification", "usage_block"], + enabled: bool, + name: str, + product_id: Literal["workers", "durable_objects"], + threshold_cents: int, + notification_email: str | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> SpendPolicyCreateResponse: + """Creates a spend policy. + + Each account can have only one enabled `usage_block` + policy per product. A second one returns `409`. There is no limit on + `notification` policies. + + Args: + account_id: Represents a Cloudflare resource identifier tag. + + action: The action taken when the threshold is reached. `notification` sends an email to + `notification_email`. `usage_block` blocks further usage of the product until + the end of the billing period. Raising the threshold above the current balance, + disabling the policy, or deleting it lifts the block early. + + enabled: Whether the policy is evaluated. + + name: Display name of the policy. After surrounding whitespace is trimmed, it must be + 1 to 200 bytes long. The value is stored as sent, untrimmed. + + product_id: The product the policy applies to: `workers` or `durable_objects`. Each + product's balance and policies are separate. Both products support + `notification` and `usage_block` policies on create and update. + + threshold_cents: The spend threshold for the current billing period, in US cents. Must be greater + than zero. + + notification_email: Email address that receives notifications. Required when `action` is + `notification`. When set, it must be a bare address (`user@example.com`); + display-name forms such as `Name ` are rejected. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + return await self._post( + path_template("/accounts/{account_id}/billing/spend-policies", account_id=account_id), + body=await async_maybe_transform( + { + "action": action, + "enabled": enabled, + "name": name, + "product_id": product_id, + "threshold_cents": threshold_cents, + "notification_email": notification_email, + }, + spend_policy_create_params.SpendPolicyCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[SpendPolicyCreateResponse]._unwrapper, + ), + cast_to=cast(Type[SpendPolicyCreateResponse], ResultWrapper[SpendPolicyCreateResponse]), + ) + + async def update( + self, + policy_id: str, + *, + account_id: str, + action: Literal["notification", "usage_block"], + enabled: bool, + name: str, + product_id: Literal["workers", "durable_objects"], + threshold_cents: int, + if_match: str, + notification_email: str | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> SpendPolicyUpdateResponse: + """Replaces the whole spend policy. + + Every field is required, as on create; there + are no partial updates and `PATCH` is not supported. The `If-Match` header must + equal the policy's current `version`. On success, `version` goes up by one and + the new value is returned in `ETag`. + + Args: + account_id: Represents a Cloudflare resource identifier tag. + + policy_id: The unique identifier of the spend policy. + + action: The action taken when the threshold is reached. `notification` sends an email to + `notification_email`. `usage_block` blocks further usage of the product until + the end of the billing period. Raising the threshold above the current balance, + disabling the policy, or deleting it lifts the block early. + + enabled: Whether the policy is evaluated. + + name: Display name of the policy. After surrounding whitespace is trimmed, it must be + 1 to 200 bytes long. The value is stored as sent, untrimmed. + + product_id: The product the policy applies to: `workers` or `durable_objects`. Each + product's balance and policies are separate. Both products support + `notification` and `usage_block` policies on create and update. + + threshold_cents: The spend threshold for the current billing period, in US cents. Must be greater + than zero. + + notification_email: Email address that receives notifications. Required when `action` is + `notification`. When set, it must be a bare address (`user@example.com`); + display-name forms such as `Name ` are rejected. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not policy_id: + raise ValueError(f"Expected a non-empty value for `policy_id` but received {policy_id!r}") + extra_headers = {"If-Match": if_match, **(extra_headers or {})} + return await self._put( + path_template( + "/accounts/{account_id}/billing/spend-policies/{policy_id}", account_id=account_id, policy_id=policy_id + ), + body=await async_maybe_transform( + { + "action": action, + "enabled": enabled, + "name": name, + "product_id": product_id, + "threshold_cents": threshold_cents, + "notification_email": notification_email, + }, + spend_policy_update_params.SpendPolicyUpdateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[SpendPolicyUpdateResponse]._unwrapper, + ), + cast_to=cast(Type[SpendPolicyUpdateResponse], ResultWrapper[SpendPolicyUpdateResponse]), + ) + + def list( + self, + *, + account_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> AsyncPaginator[SpendPolicyListResponse, AsyncSinglePage[SpendPolicyListResponse]]: + """ + Returns every spend policy on the account that has not been deleted, including + disabled ones. Results are sorted by `name`, then `id`. There is no pagination. + + Args: + account_id: Represents a Cloudflare resource identifier tag. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + return self._get_api_list( + path_template("/accounts/{account_id}/billing/spend-policies", account_id=account_id), + page=AsyncSinglePage[SpendPolicyListResponse], + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + model=SpendPolicyListResponse, + ) + + async def delete( + self, + policy_id: str, + *, + account_id: str, + if_match: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> SpendPolicyDeleteResponse: + """Soft-deletes the spend policy. + + The policy is disabled and no longer appears in + list, get or audit responses. The `If-Match` header must equal the policy's + current `version`. + + Args: + account_id: Represents a Cloudflare resource identifier tag. + + policy_id: The unique identifier of the spend policy. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not policy_id: + raise ValueError(f"Expected a non-empty value for `policy_id` but received {policy_id!r}") + extra_headers = {"If-Match": if_match, **(extra_headers or {})} + return await self._delete( + path_template( + "/accounts/{account_id}/billing/spend-policies/{policy_id}", account_id=account_id, policy_id=policy_id + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[SpendPolicyDeleteResponse]._unwrapper, + ), + cast_to=cast(Type[SpendPolicyDeleteResponse], ResultWrapper[SpendPolicyDeleteResponse]), + ) + + async def get( + self, + policy_id: str, + *, + account_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> SpendPolicyGetResponse: + """Returns one spend policy. + + The `ETag` response header holds the current + `version`; send it as `If-Match` on a later update or delete. + + Args: + account_id: Represents a Cloudflare resource identifier tag. + + policy_id: The unique identifier of the spend policy. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not policy_id: + raise ValueError(f"Expected a non-empty value for `policy_id` but received {policy_id!r}") + return await self._get( + path_template( + "/accounts/{account_id}/billing/spend-policies/{policy_id}", account_id=account_id, policy_id=policy_id + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[SpendPolicyGetResponse]._unwrapper, + ), + cast_to=cast(Type[SpendPolicyGetResponse], ResultWrapper[SpendPolicyGetResponse]), + ) + + +class SpendPoliciesResourceWithRawResponse: + def __init__(self, spend_policies: SpendPoliciesResource) -> None: + self._spend_policies = spend_policies + + self.create = to_raw_response_wrapper( + spend_policies.create, + ) + self.update = to_raw_response_wrapper( + spend_policies.update, + ) + self.list = to_raw_response_wrapper( + spend_policies.list, + ) + self.delete = to_raw_response_wrapper( + spend_policies.delete, + ) + self.get = to_raw_response_wrapper( + spend_policies.get, + ) + + @cached_property + def audit(self) -> AuditResourceWithRawResponse: + return AuditResourceWithRawResponse(self._spend_policies.audit) + + @cached_property + def activity(self) -> ActivityResourceWithRawResponse: + return ActivityResourceWithRawResponse(self._spend_policies.activity) + + +class AsyncSpendPoliciesResourceWithRawResponse: + def __init__(self, spend_policies: AsyncSpendPoliciesResource) -> None: + self._spend_policies = spend_policies + + self.create = async_to_raw_response_wrapper( + spend_policies.create, + ) + self.update = async_to_raw_response_wrapper( + spend_policies.update, + ) + self.list = async_to_raw_response_wrapper( + spend_policies.list, + ) + self.delete = async_to_raw_response_wrapper( + spend_policies.delete, + ) + self.get = async_to_raw_response_wrapper( + spend_policies.get, + ) + + @cached_property + def audit(self) -> AsyncAuditResourceWithRawResponse: + return AsyncAuditResourceWithRawResponse(self._spend_policies.audit) + + @cached_property + def activity(self) -> AsyncActivityResourceWithRawResponse: + return AsyncActivityResourceWithRawResponse(self._spend_policies.activity) + + +class SpendPoliciesResourceWithStreamingResponse: + def __init__(self, spend_policies: SpendPoliciesResource) -> None: + self._spend_policies = spend_policies + + self.create = to_streamed_response_wrapper( + spend_policies.create, + ) + self.update = to_streamed_response_wrapper( + spend_policies.update, + ) + self.list = to_streamed_response_wrapper( + spend_policies.list, + ) + self.delete = to_streamed_response_wrapper( + spend_policies.delete, + ) + self.get = to_streamed_response_wrapper( + spend_policies.get, + ) + + @cached_property + def audit(self) -> AuditResourceWithStreamingResponse: + return AuditResourceWithStreamingResponse(self._spend_policies.audit) + + @cached_property + def activity(self) -> ActivityResourceWithStreamingResponse: + return ActivityResourceWithStreamingResponse(self._spend_policies.activity) + + +class AsyncSpendPoliciesResourceWithStreamingResponse: + def __init__(self, spend_policies: AsyncSpendPoliciesResource) -> None: + self._spend_policies = spend_policies + + self.create = async_to_streamed_response_wrapper( + spend_policies.create, + ) + self.update = async_to_streamed_response_wrapper( + spend_policies.update, + ) + self.list = async_to_streamed_response_wrapper( + spend_policies.list, + ) + self.delete = async_to_streamed_response_wrapper( + spend_policies.delete, + ) + self.get = async_to_streamed_response_wrapper( + spend_policies.get, + ) + + @cached_property + def audit(self) -> AsyncAuditResourceWithStreamingResponse: + return AsyncAuditResourceWithStreamingResponse(self._spend_policies.audit) + + @cached_property + def activity(self) -> AsyncActivityResourceWithStreamingResponse: + return AsyncActivityResourceWithStreamingResponse(self._spend_policies.activity) diff --git a/src/cloudflare/resources/billing/usage.py b/src/cloudflare/resources/billing/usage.py index c1d12c47a8c..d38fcdf24a0 100644 --- a/src/cloudflare/resources/billing/usage.py +++ b/src/cloudflare/resources/billing/usage.py @@ -79,8 +79,9 @@ def get( includes all metered usage, including usage that falls within free-tier allowances and may result in zero cost. - **Note:** Cost and pricing fields are not yet populated and will be absent from - responses until billing integration is complete. + **Note:** This endpoint serves `usage` records only; cost and pricing fields are + absent from responses. To retrieve rated costs, use `POST` on the same path with + `Metric: cost`. When `from` and `to` are omitted, defaults to the start of the current month through today. The maximum date range is 31 days. @@ -244,8 +245,9 @@ def get_account_usage_v2( includes all metered usage, including usage that falls within free-tier allowances and may result in zero cost. - **Note:** Cost and pricing fields are not yet populated and will be absent from - responses until billing integration is complete. + **Note:** This endpoint serves `usage` records only; cost and pricing fields are + absent from responses. To retrieve rated costs, use `POST` on the same path with + `Metric: cost`. When `from` and `to` are omitted, defaults to the start of the current month through today. The maximum date range is 31 days. @@ -433,8 +435,9 @@ async def get( includes all metered usage, including usage that falls within free-tier allowances and may result in zero cost. - **Note:** Cost and pricing fields are not yet populated and will be absent from - responses until billing integration is complete. + **Note:** This endpoint serves `usage` records only; cost and pricing fields are + absent from responses. To retrieve rated costs, use `POST` on the same path with + `Metric: cost`. When `from` and `to` are omitted, defaults to the start of the current month through today. The maximum date range is 31 days. @@ -598,8 +601,9 @@ async def get_account_usage_v2( includes all metered usage, including usage that falls within free-tier allowances and may result in zero cost. - **Note:** Cost and pricing fields are not yet populated and will be absent from - responses until billing integration is complete. + **Note:** This endpoint serves `usage` records only; cost and pricing fields are + absent from responses. To retrieve rated costs, use `POST` on the same path with + `Metric: cost`. When `from` and `to` are omitted, defaults to the start of the current month through today. The maximum date range is 31 days. diff --git a/src/cloudflare/resources/bot_management/bot_management.py b/src/cloudflare/resources/bot_management/bot_management.py index 045d6100fd4..5b3b5438e67 100644 --- a/src/cloudflare/resources/bot_management/bot_management.py +++ b/src/cloudflare/resources/bot_management/bot_management.py @@ -51,6 +51,7 @@ def update( self, *, zone_id: str, + ai_agents: bot_management_update_params.BotFightModeConfigurationAIAgents | Omit = omit, ai_bots_migration_opt_out: bool | Omit = omit, ai_bots_protection: Literal["block", "disabled", "only_on_ad_pages"] | Omit = omit, aisearch: Literal["disabled", "block", "only_on_ad_pages"] | Omit = omit, @@ -137,6 +138,8 @@ def update( Args: zone_id: Identifier. + ai_agents: Configure blocking behavior for supported personal AI agents. + ai_bots_migration_opt_out: Temporary migration flag tracking zones opted out of AI bots managed-rule updates. @@ -186,6 +189,7 @@ def update( self, *, zone_id: str, + ai_agents: bot_management_update_params.SuperBotFightModeDefinitelyConfigurationAIAgents | Omit = omit, ai_bots_migration_opt_out: bool | Omit = omit, ai_bots_protection: Literal["block", "disabled", "only_on_ad_pages"] | Omit = omit, aisearch: Literal["disabled", "block", "only_on_ad_pages"] | Omit = omit, @@ -275,6 +279,8 @@ def update( Args: zone_id: Identifier. + ai_agents: Configure blocking behavior for supported personal AI agents. + ai_bots_migration_opt_out: Temporary migration flag tracking zones opted out of AI bots managed-rule updates. @@ -332,6 +338,7 @@ def update( self, *, zone_id: str, + ai_agents: bot_management_update_params.SuperBotFightModeLikelyConfigurationAIAgents | Omit = omit, ai_bots_migration_opt_out: bool | Omit = omit, ai_bots_protection: Literal["block", "disabled", "only_on_ad_pages"] | Omit = omit, aisearch: Literal["disabled", "block", "only_on_ad_pages"] | Omit = omit, @@ -422,6 +429,8 @@ def update( Args: zone_id: Identifier. + ai_agents: Configure blocking behavior for supported personal AI agents. + ai_bots_migration_opt_out: Temporary migration flag tracking zones opted out of AI bots managed-rule updates. @@ -481,6 +490,7 @@ def update( self, *, zone_id: str, + ai_agents: bot_management_update_params.SubscriptionConfigurationAIAgents | Omit = omit, ai_bots_migration_opt_out: bool | Omit = omit, ai_bots_protection: Literal["block", "disabled", "only_on_ad_pages"] | Omit = omit, aisearch: Literal["disabled", "block", "only_on_ad_pages"] | Omit = omit, @@ -569,6 +579,8 @@ def update( Args: zone_id: Identifier. + ai_agents: Configure blocking behavior for supported personal AI agents. + ai_bots_migration_opt_out: Temporary migration flag tracking zones opted out of AI bots managed-rule updates. @@ -626,6 +638,11 @@ def update( self, *, zone_id: str, + ai_agents: bot_management_update_params.BotFightModeConfigurationAIAgents + | bot_management_update_params.SuperBotFightModeDefinitelyConfigurationAIAgents + | bot_management_update_params.SuperBotFightModeLikelyConfigurationAIAgents + | bot_management_update_params.SubscriptionConfigurationAIAgents + | Omit = omit, ai_bots_migration_opt_out: bool | Omit = omit, ai_bots_protection: Literal["block", "disabled", "only_on_ad_pages"] | Omit = omit, aisearch: Literal["disabled", "block", "only_on_ad_pages"] | Omit = omit, @@ -662,6 +679,7 @@ def update( path_template("/zones/{zone_id}/bot_management", zone_id=zone_id), body=maybe_transform( { + "ai_agents": ai_agents, "ai_bots_migration_opt_out": ai_bots_migration_opt_out, "ai_bots_protection": ai_bots_protection, "aisearch": aisearch, @@ -769,6 +787,7 @@ async def update( self, *, zone_id: str, + ai_agents: bot_management_update_params.BotFightModeConfigurationAIAgents | Omit = omit, ai_bots_migration_opt_out: bool | Omit = omit, ai_bots_protection: Literal["block", "disabled", "only_on_ad_pages"] | Omit = omit, aisearch: Literal["disabled", "block", "only_on_ad_pages"] | Omit = omit, @@ -855,6 +874,8 @@ async def update( Args: zone_id: Identifier. + ai_agents: Configure blocking behavior for supported personal AI agents. + ai_bots_migration_opt_out: Temporary migration flag tracking zones opted out of AI bots managed-rule updates. @@ -904,6 +925,7 @@ async def update( self, *, zone_id: str, + ai_agents: bot_management_update_params.SuperBotFightModeDefinitelyConfigurationAIAgents | Omit = omit, ai_bots_migration_opt_out: bool | Omit = omit, ai_bots_protection: Literal["block", "disabled", "only_on_ad_pages"] | Omit = omit, aisearch: Literal["disabled", "block", "only_on_ad_pages"] | Omit = omit, @@ -993,6 +1015,8 @@ async def update( Args: zone_id: Identifier. + ai_agents: Configure blocking behavior for supported personal AI agents. + ai_bots_migration_opt_out: Temporary migration flag tracking zones opted out of AI bots managed-rule updates. @@ -1050,6 +1074,7 @@ async def update( self, *, zone_id: str, + ai_agents: bot_management_update_params.SuperBotFightModeLikelyConfigurationAIAgents | Omit = omit, ai_bots_migration_opt_out: bool | Omit = omit, ai_bots_protection: Literal["block", "disabled", "only_on_ad_pages"] | Omit = omit, aisearch: Literal["disabled", "block", "only_on_ad_pages"] | Omit = omit, @@ -1140,6 +1165,8 @@ async def update( Args: zone_id: Identifier. + ai_agents: Configure blocking behavior for supported personal AI agents. + ai_bots_migration_opt_out: Temporary migration flag tracking zones opted out of AI bots managed-rule updates. @@ -1199,6 +1226,7 @@ async def update( self, *, zone_id: str, + ai_agents: bot_management_update_params.SubscriptionConfigurationAIAgents | Omit = omit, ai_bots_migration_opt_out: bool | Omit = omit, ai_bots_protection: Literal["block", "disabled", "only_on_ad_pages"] | Omit = omit, aisearch: Literal["disabled", "block", "only_on_ad_pages"] | Omit = omit, @@ -1287,6 +1315,8 @@ async def update( Args: zone_id: Identifier. + ai_agents: Configure blocking behavior for supported personal AI agents. + ai_bots_migration_opt_out: Temporary migration flag tracking zones opted out of AI bots managed-rule updates. @@ -1344,6 +1374,11 @@ async def update( self, *, zone_id: str, + ai_agents: bot_management_update_params.BotFightModeConfigurationAIAgents + | bot_management_update_params.SuperBotFightModeDefinitelyConfigurationAIAgents + | bot_management_update_params.SuperBotFightModeLikelyConfigurationAIAgents + | bot_management_update_params.SubscriptionConfigurationAIAgents + | Omit = omit, ai_bots_migration_opt_out: bool | Omit = omit, ai_bots_protection: Literal["block", "disabled", "only_on_ad_pages"] | Omit = omit, aisearch: Literal["disabled", "block", "only_on_ad_pages"] | Omit = omit, @@ -1380,6 +1415,7 @@ async def update( path_template("/zones/{zone_id}/bot_management", zone_id=zone_id), body=await async_maybe_transform( { + "ai_agents": ai_agents, "ai_bots_migration_opt_out": ai_bots_migration_opt_out, "ai_bots_protection": ai_bots_protection, "aisearch": aisearch, diff --git a/src/cloudflare/resources/brand_protection/api.md b/src/cloudflare/resources/brand_protection/api.md index e2be15da0f0..5da459d48d5 100644 --- a/src/cloudflare/resources/brand_protection/api.md +++ b/src/cloudflare/resources/brand_protection/api.md @@ -4,8 +4,6 @@ Types: ```python from cloudflare.types.brand_protection import ( - Info, - Submit, BrandProtectionSubmitResponse, BrandProtectionURLInfoResponse, ) diff --git a/src/cloudflare/resources/brand_protection/brand_protection.py b/src/cloudflare/resources/brand_protection/brand_protection.py index fcfde5b9b5c..dfdc2b102a3 100644 --- a/src/cloudflare/resources/brand_protection/brand_protection.py +++ b/src/cloudflare/resources/brand_protection/brand_protection.py @@ -114,7 +114,7 @@ def submit( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> BrandProtectionSubmitResponse: """ - Return new URL submissions + Return new URL submissions. Args: extra_headers: Send extra headers @@ -147,7 +147,7 @@ def url_info( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> SyncSinglePage[BrandProtectionURLInfoResponse]: """ - Return submitted URLs based on ID + Return submitted URLs based on ID. Args: extra_headers: Send extra headers @@ -222,7 +222,7 @@ async def submit( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> BrandProtectionSubmitResponse: """ - Return new URL submissions + Return new URL submissions. Args: extra_headers: Send extra headers @@ -255,7 +255,7 @@ def url_info( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> AsyncPaginator[BrandProtectionURLInfoResponse, AsyncSinglePage[BrandProtectionURLInfoResponse]]: """ - Return submitted URLs based on ID + Return submitted URLs based on ID. Args: extra_headers: Send extra headers diff --git a/src/cloudflare/resources/brand_protection/logo_matches.py b/src/cloudflare/resources/brand_protection/logo_matches.py index 7134e929c4e..8fea0c8a75c 100644 --- a/src/cloudflare/resources/brand_protection/logo_matches.py +++ b/src/cloudflare/resources/brand_protection/logo_matches.py @@ -57,7 +57,7 @@ def download( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> LogoMatchDownloadResponse: """ - Return matches as CSV for logo queries based on ID + Return matches as CSV for logo queries based on ID. Args: extra_headers: Send extra headers @@ -104,7 +104,7 @@ def get( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> LogoMatchGetResponse: """ - Return matches for logo queries based on ID + Return matches for logo queries based on ID. Args: extra_headers: Send extra headers @@ -172,7 +172,7 @@ async def download( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> LogoMatchDownloadResponse: """ - Return matches as CSV for logo queries based on ID + Return matches as CSV for logo queries based on ID. Args: extra_headers: Send extra headers @@ -219,7 +219,7 @@ async def get( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> LogoMatchGetResponse: """ - Return matches for logo queries based on ID + Return matches for logo queries based on ID. Args: extra_headers: Send extra headers diff --git a/src/cloudflare/resources/brand_protection/logos.py b/src/cloudflare/resources/brand_protection/logos.py index c8bdd8d39a4..62875a0bf0c 100644 --- a/src/cloudflare/resources/brand_protection/logos.py +++ b/src/cloudflare/resources/brand_protection/logos.py @@ -57,7 +57,7 @@ def create( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> LogoCreateResponse: """ - Return new saved logo queries created from image files + Return new saved logo queries created from image files. Args: extra_headers: Send extra headers @@ -103,7 +103,7 @@ def delete( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> None: """ - Return a success message after deleting saved logo queries by ID + Return a success message after deleting saved logo queries by ID. Args: extra_headers: Send extra headers @@ -166,7 +166,7 @@ async def create( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> LogoCreateResponse: """ - Return new saved logo queries created from image files + Return new saved logo queries created from image files. Args: extra_headers: Send extra headers @@ -212,7 +212,7 @@ async def delete( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> None: """ - Return a success message after deleting saved logo queries by ID + Return a success message after deleting saved logo queries by ID. Args: extra_headers: Send extra headers diff --git a/src/cloudflare/resources/brand_protection/matches.py b/src/cloudflare/resources/brand_protection/matches.py index c7f14a5d848..81881dbbc3f 100644 --- a/src/cloudflare/resources/brand_protection/matches.py +++ b/src/cloudflare/resources/brand_protection/matches.py @@ -59,7 +59,7 @@ def download( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> MatchDownloadResponse: """ - Return matches as CSV for string queries based on ID + Return matches as CSV for string queries based on ID. Args: extra_headers: Send extra headers @@ -110,7 +110,7 @@ def get( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> MatchGetResponse: """ - Return matches for string queries based on ID + Return matches for string queries based on ID. Args: extra_headers: Send extra headers @@ -182,7 +182,7 @@ async def download( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> MatchDownloadResponse: """ - Return matches as CSV for string queries based on ID + Return matches as CSV for string queries based on ID. Args: extra_headers: Send extra headers @@ -233,7 +233,7 @@ async def get( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> MatchGetResponse: """ - Return matches for string queries based on ID + Return matches for string queries based on ID. Args: extra_headers: Send extra headers diff --git a/src/cloudflare/resources/brand_protection/queries.py b/src/cloudflare/resources/brand_protection/queries.py index 53c5d644219..f6a0a0c5976 100644 --- a/src/cloudflare/resources/brand_protection/queries.py +++ b/src/cloudflare/resources/brand_protection/queries.py @@ -53,7 +53,7 @@ def create( max_time: Union[str, datetime, None] | Omit = omit, min_time: Union[str, datetime, None] | Omit = omit, body_scan: bool | Omit = omit, - string_matches: object | Omit = omit, + string_matches: Iterable[query_create_params.StringMatch] | Omit = omit, body_tag: str | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. @@ -63,7 +63,7 @@ def create( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> None: """ - Return a success message after creating new saved string queries + Return a success message after creating new saved string queries. Args: extra_headers: Send extra headers @@ -121,7 +121,7 @@ def delete( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> None: """ - Return a success message after deleting saved string queries by ID + Return a success message after deleting saved string queries by ID. Args: extra_headers: Send extra headers @@ -167,7 +167,7 @@ def bulk( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> None: """ - Return a success message after creating new saved string queries in bulk + Return a success message after creating new saved string queries in bulk. Args: extra_headers: Send extra headers @@ -221,7 +221,7 @@ async def create( max_time: Union[str, datetime, None] | Omit = omit, min_time: Union[str, datetime, None] | Omit = omit, body_scan: bool | Omit = omit, - string_matches: object | Omit = omit, + string_matches: Iterable[query_create_params.StringMatch] | Omit = omit, body_tag: str | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. @@ -231,7 +231,7 @@ async def create( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> None: """ - Return a success message after creating new saved string queries + Return a success message after creating new saved string queries. Args: extra_headers: Send extra headers @@ -289,7 +289,7 @@ async def delete( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> None: """ - Return a success message after deleting saved string queries by ID + Return a success message after deleting saved string queries by ID. Args: extra_headers: Send extra headers @@ -335,7 +335,7 @@ async def bulk( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> None: """ - Return a success message after creating new saved string queries in bulk + Return a success message after creating new saved string queries in bulk. Args: extra_headers: Send extra headers diff --git a/src/cloudflare/resources/browser_rendering/accessibility_tree.py b/src/cloudflare/resources/browser_rendering/accessibility_tree.py index aa762a9235e..2adcb0d14be 100644 --- a/src/cloudflare/resources/browser_rendering/accessibility_tree.py +++ b/src/cloudflare/resources/browser_rendering/accessibility_tree.py @@ -51,6 +51,7 @@ def create( *, account_id: str, url: str, + browser: Literal["kitesurf"] | Omit = omit, cache_ttl: float | Omit = omit, action_timeout: float | Omit = omit, add_script_tag: Iterable[accessibility_tree_create_params.Variant0AddScriptTag] | Omit = omit, @@ -134,6 +135,8 @@ def create( Args: account_id: Account ID. + browser: Rendering backend. Set to `kitesurf` to use Kitesurf (beta). + cache_ttl: Cache TTL default is 5s. Set to 0 to disable. action_timeout: The maximum duration allowed for the browser action to complete after the page @@ -188,6 +191,7 @@ def create( *, account_id: str, html: str, + browser: Literal["kitesurf"] | Omit = omit, cache_ttl: float | Omit = omit, action_timeout: float | Omit = omit, add_script_tag: Iterable[accessibility_tree_create_params.Variant1AddScriptTag] | Omit = omit, @@ -271,6 +275,8 @@ def create( Args: account_id: Account ID. + browser: Rendering backend. Set to `kitesurf` to use Kitesurf (beta). + cache_ttl: Cache TTL default is 5s. Set to 0 to disable. action_timeout: The maximum duration allowed for the browser action to complete after the page @@ -325,6 +331,7 @@ def create( *, account_id: str, url: str | Omit = omit, + browser: Literal["kitesurf"] | Omit = omit, cache_ttl: float | Omit = omit, action_timeout: float | Omit = omit, add_script_tag: Iterable[accessibility_tree_create_params.Variant0AddScriptTag] @@ -449,7 +456,11 @@ def create( extra_body=extra_body, timeout=timeout, query=maybe_transform( - {"cache_ttl": cache_ttl}, accessibility_tree_create_params.AccessibilityTreeCreateParams + { + "browser": browser, + "cache_ttl": cache_ttl, + }, + accessibility_tree_create_params.AccessibilityTreeCreateParams, ), post_parser=ResultWrapper[AccessibilityTreeCreateResponse]._unwrapper, ), @@ -483,6 +494,7 @@ async def create( *, account_id: str, url: str, + browser: Literal["kitesurf"] | Omit = omit, cache_ttl: float | Omit = omit, action_timeout: float | Omit = omit, add_script_tag: Iterable[accessibility_tree_create_params.Variant0AddScriptTag] | Omit = omit, @@ -566,6 +578,8 @@ async def create( Args: account_id: Account ID. + browser: Rendering backend. Set to `kitesurf` to use Kitesurf (beta). + cache_ttl: Cache TTL default is 5s. Set to 0 to disable. action_timeout: The maximum duration allowed for the browser action to complete after the page @@ -620,6 +634,7 @@ async def create( *, account_id: str, html: str, + browser: Literal["kitesurf"] | Omit = omit, cache_ttl: float | Omit = omit, action_timeout: float | Omit = omit, add_script_tag: Iterable[accessibility_tree_create_params.Variant1AddScriptTag] | Omit = omit, @@ -703,6 +718,8 @@ async def create( Args: account_id: Account ID. + browser: Rendering backend. Set to `kitesurf` to use Kitesurf (beta). + cache_ttl: Cache TTL default is 5s. Set to 0 to disable. action_timeout: The maximum duration allowed for the browser action to complete after the page @@ -757,6 +774,7 @@ async def create( *, account_id: str, url: str | Omit = omit, + browser: Literal["kitesurf"] | Omit = omit, cache_ttl: float | Omit = omit, action_timeout: float | Omit = omit, add_script_tag: Iterable[accessibility_tree_create_params.Variant0AddScriptTag] @@ -881,7 +899,11 @@ async def create( extra_body=extra_body, timeout=timeout, query=await async_maybe_transform( - {"cache_ttl": cache_ttl}, accessibility_tree_create_params.AccessibilityTreeCreateParams + { + "browser": browser, + "cache_ttl": cache_ttl, + }, + accessibility_tree_create_params.AccessibilityTreeCreateParams, ), post_parser=ResultWrapper[AccessibilityTreeCreateResponse]._unwrapper, ), diff --git a/src/cloudflare/resources/browser_rendering/api.md b/src/cloudflare/resources/browser_rendering/api.md index 8ad772e4f79..c3a8b71cc69 100644 --- a/src/cloudflare/resources/browser_rendering/api.md +++ b/src/cloudflare/resources/browser_rendering/api.md @@ -152,8 +152,6 @@ Methods: - client.browser_rendering.devtools.browser.create(\*, account_id, \*\*params) -> BrowserCreateResponse - client.browser_rendering.devtools.browser.delete(session_id, \*, account_id) -> BrowserDeleteResponse -- client.browser_rendering.devtools.browser.connect(session_id, \*, account_id, \*\*params) -> None -- client.browser_rendering.devtools.browser.launch(\*, account_id, \*\*params) -> None - client.browser_rendering.devtools.browser.protocol(session_id, \*, account_id) -> BrowserProtocolResponse - client.browser_rendering.devtools.browser.version(session_id, \*, account_id) -> BrowserVersionResponse @@ -169,12 +167,6 @@ Methods: - client.browser_rendering.devtools.browser.live_view.create(session_id, \*, account_id, \*\*params) -> LiveViewCreateResponse -#### Page - -Methods: - -- client.browser_rendering.devtools.browser.page.get(target_id, \*, account_id, session_id) -> None - #### Targets Types: diff --git a/src/cloudflare/resources/browser_rendering/content.py b/src/cloudflare/resources/browser_rendering/content.py index 524b2111124..35e03839082 100644 --- a/src/cloudflare/resources/browser_rendering/content.py +++ b/src/cloudflare/resources/browser_rendering/content.py @@ -51,6 +51,7 @@ def create( *, account_id: str, url: str, + browser: Literal["kitesurf"] | Omit = omit, cache_ttl: float | Omit = omit, action_timeout: float | Omit = omit, add_script_tag: Iterable[content_create_params.Variant0AddScriptTag] | Omit = omit, @@ -130,6 +131,8 @@ def create( Args: account_id: Account ID. + browser: Rendering backend. Set to `kitesurf` to use Kitesurf (beta). + cache_ttl: Cache TTL default is 5s. Set to 0 to disable. action_timeout: The maximum duration allowed for the browser action to complete after the page @@ -184,6 +187,7 @@ def create( *, account_id: str, html: str, + browser: Literal["kitesurf"] | Omit = omit, cache_ttl: float | Omit = omit, action_timeout: float | Omit = omit, add_script_tag: Iterable[content_create_params.Variant1AddScriptTag] | Omit = omit, @@ -263,6 +267,8 @@ def create( Args: account_id: Account ID. + browser: Rendering backend. Set to `kitesurf` to use Kitesurf (beta). + cache_ttl: Cache TTL default is 5s. Set to 0 to disable. action_timeout: The maximum duration allowed for the browser action to complete after the page @@ -317,6 +323,7 @@ def create( *, account_id: str, url: str | Omit = omit, + browser: Literal["kitesurf"] | Omit = omit, cache_ttl: float | Omit = omit, action_timeout: float | Omit = omit, add_script_tag: Iterable[content_create_params.Variant0AddScriptTag] @@ -434,7 +441,13 @@ def create( extra_query=extra_query, extra_body=extra_body, timeout=timeout, - query=maybe_transform({"cache_ttl": cache_ttl}, content_create_params.ContentCreateParams), + query=maybe_transform( + { + "browser": browser, + "cache_ttl": cache_ttl, + }, + content_create_params.ContentCreateParams, + ), post_parser=ResultWrapper[Optional[ContentCreateResponse]]._unwrapper, ), cast_to=cast(Type[str], ResultWrapper[str]), @@ -467,6 +480,7 @@ async def create( *, account_id: str, url: str, + browser: Literal["kitesurf"] | Omit = omit, cache_ttl: float | Omit = omit, action_timeout: float | Omit = omit, add_script_tag: Iterable[content_create_params.Variant0AddScriptTag] | Omit = omit, @@ -546,6 +560,8 @@ async def create( Args: account_id: Account ID. + browser: Rendering backend. Set to `kitesurf` to use Kitesurf (beta). + cache_ttl: Cache TTL default is 5s. Set to 0 to disable. action_timeout: The maximum duration allowed for the browser action to complete after the page @@ -600,6 +616,7 @@ async def create( *, account_id: str, html: str, + browser: Literal["kitesurf"] | Omit = omit, cache_ttl: float | Omit = omit, action_timeout: float | Omit = omit, add_script_tag: Iterable[content_create_params.Variant1AddScriptTag] | Omit = omit, @@ -679,6 +696,8 @@ async def create( Args: account_id: Account ID. + browser: Rendering backend. Set to `kitesurf` to use Kitesurf (beta). + cache_ttl: Cache TTL default is 5s. Set to 0 to disable. action_timeout: The maximum duration allowed for the browser action to complete after the page @@ -733,6 +752,7 @@ async def create( *, account_id: str, url: str | Omit = omit, + browser: Literal["kitesurf"] | Omit = omit, cache_ttl: float | Omit = omit, action_timeout: float | Omit = omit, add_script_tag: Iterable[content_create_params.Variant0AddScriptTag] @@ -850,7 +870,13 @@ async def create( extra_query=extra_query, extra_body=extra_body, timeout=timeout, - query=await async_maybe_transform({"cache_ttl": cache_ttl}, content_create_params.ContentCreateParams), + query=await async_maybe_transform( + { + "browser": browser, + "cache_ttl": cache_ttl, + }, + content_create_params.ContentCreateParams, + ), post_parser=ResultWrapper[Optional[ContentCreateResponse]]._unwrapper, ), cast_to=cast(Type[str], ResultWrapper[str]), diff --git a/src/cloudflare/resources/browser_rendering/devtools/browser/__init__.py b/src/cloudflare/resources/browser_rendering/devtools/browser/__init__.py index f14e498662f..6f0aa09e9f3 100644 --- a/src/cloudflare/resources/browser_rendering/devtools/browser/__init__.py +++ b/src/cloudflare/resources/browser_rendering/devtools/browser/__init__.py @@ -1,13 +1,5 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from .page import ( - PageResource, - AsyncPageResource, - PageResourceWithRawResponse, - AsyncPageResourceWithRawResponse, - PageResourceWithStreamingResponse, - AsyncPageResourceWithStreamingResponse, -) from .browser import ( BrowserResource, AsyncBrowserResource, @@ -40,12 +32,6 @@ "AsyncLiveViewResourceWithRawResponse", "LiveViewResourceWithStreamingResponse", "AsyncLiveViewResourceWithStreamingResponse", - "PageResource", - "AsyncPageResource", - "PageResourceWithRawResponse", - "AsyncPageResourceWithRawResponse", - "PageResourceWithStreamingResponse", - "AsyncPageResourceWithStreamingResponse", "TargetsResource", "AsyncTargetsResource", "TargetsResourceWithRawResponse", diff --git a/src/cloudflare/resources/browser_rendering/devtools/browser/browser.py b/src/cloudflare/resources/browser_rendering/devtools/browser/browser.py index aa51c024ea6..55e05511c8f 100644 --- a/src/cloudflare/resources/browser_rendering/devtools/browser/browser.py +++ b/src/cloudflare/resources/browser_rendering/devtools/browser/browser.py @@ -4,14 +4,6 @@ import httpx -from .page import ( - PageResource, - AsyncPageResource, - PageResourceWithRawResponse, - AsyncPageResourceWithRawResponse, - PageResourceWithStreamingResponse, - AsyncPageResourceWithStreamingResponse, -) from .targets import ( TargetsResource, AsyncTargetsResource, @@ -28,8 +20,8 @@ LiveViewResourceWithStreamingResponse, AsyncLiveViewResourceWithStreamingResponse, ) -from ....._types import Body, Omit, Query, Headers, NoneType, NotGiven, omit, not_given -from ....._utils import path_template, maybe_transform, strip_not_given, async_maybe_transform +from ....._types import Body, Omit, Query, Headers, NotGiven, omit, not_given +from ....._utils import path_template, maybe_transform, async_maybe_transform from ....._compat import cached_property from ....._resource import SyncAPIResource, AsyncAPIResource from ....._response import ( @@ -39,7 +31,7 @@ async_to_streamed_response_wrapper, ) from ....._base_client import make_request_options -from .....types.browser_rendering.devtools import browser_create_params, browser_launch_params, browser_connect_params +from .....types.browser_rendering.devtools import browser_create_params from .....types.browser_rendering.devtools.browser_create_response import BrowserCreateResponse from .....types.browser_rendering.devtools.browser_delete_response import BrowserDeleteResponse from .....types.browser_rendering.devtools.browser_version_response import BrowserVersionResponse @@ -53,10 +45,6 @@ class BrowserResource(SyncAPIResource): def live_view(self) -> LiveViewResource: return LiveViewResource(self._client) - @cached_property - def page(self) -> PageResource: - return PageResource(self._client) - @cached_property def targets(self) -> TargetsResource: return TargetsResource(self._client) @@ -190,136 +178,6 @@ def delete( cast_to=BrowserDeleteResponse, ) - def connect( - self, - session_id: str, - *, - account_id: str, - keep_alive: float | Omit = omit, - lab: bool | Omit = omit, - recording: bool | Omit = omit, - cf_brapi_guardrails: str | Omit = omit, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> None: - """ - Establishes a WebSocket connection to an existing browser session. - - Args: - account_id: Account ID. - - session_id: Browser session ID to connect to. - - keep_alive: Keep-alive time in ms (only valid when acquiring new session). - - lab: Use experimental browser. - - cf_brapi_guardrails: Optional base64url-encoded JSON connection guardrails (mode) - - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not account_id: - raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not session_id: - raise ValueError(f"Expected a non-empty value for `session_id` but received {session_id!r}") - extra_headers = {"Accept": "*/*", **(extra_headers or {})} - extra_headers = {**strip_not_given({"cf-brapi-guardrails": cf_brapi_guardrails}), **(extra_headers or {})} - return self._get( - path_template( - "/accounts/{account_id}/browser-rendering/devtools/browser/{session_id}", - account_id=account_id, - session_id=session_id, - ), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - query=maybe_transform( - { - "keep_alive": keep_alive, - "lab": lab, - "recording": recording, - }, - browser_connect_params.BrowserConnectParams, - ), - ), - cast_to=NoneType, - ) - - def launch( - self, - *, - account_id: str, - keep_alive: float | Omit = omit, - lab: bool | Omit = omit, - recording: bool | Omit = omit, - cf_brapi_guardrails: str | Omit = omit, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> None: - """Acquires and establishes a WebSocket connection to a browser session. - - Session - guardrails may be supplied in the `cf-brapi-guardrails` header as - base64url-encoded JSON of the same `guardrails` object the POST body accepts - (for example `{"allowedDomains":["*.example.com"]}`). - - Args: - account_id: Account ID. - - keep_alive: Keep-alive time in ms (only valid when acquiring new session). - - lab: Use experimental browser. - - cf_brapi_guardrails: Optional base64url-encoded JSON session guardrails (allowedDomains and - allowedDomainSets) - - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not account_id: - raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - extra_headers = {"Accept": "*/*", **(extra_headers or {})} - extra_headers = {**strip_not_given({"cf-brapi-guardrails": cf_brapi_guardrails}), **(extra_headers or {})} - return self._get( - path_template("/accounts/{account_id}/browser-rendering/devtools/browser", account_id=account_id), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - query=maybe_transform( - { - "keep_alive": keep_alive, - "lab": lab, - "recording": recording, - }, - browser_launch_params.BrowserLaunchParams, - ), - ), - cast_to=NoneType, - ) - def protocol( self, session_id: str, @@ -415,10 +273,6 @@ class AsyncBrowserResource(AsyncAPIResource): def live_view(self) -> AsyncLiveViewResource: return AsyncLiveViewResource(self._client) - @cached_property - def page(self) -> AsyncPageResource: - return AsyncPageResource(self._client) - @cached_property def targets(self) -> AsyncTargetsResource: return AsyncTargetsResource(self._client) @@ -552,136 +406,6 @@ async def delete( cast_to=BrowserDeleteResponse, ) - async def connect( - self, - session_id: str, - *, - account_id: str, - keep_alive: float | Omit = omit, - lab: bool | Omit = omit, - recording: bool | Omit = omit, - cf_brapi_guardrails: str | Omit = omit, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> None: - """ - Establishes a WebSocket connection to an existing browser session. - - Args: - account_id: Account ID. - - session_id: Browser session ID to connect to. - - keep_alive: Keep-alive time in ms (only valid when acquiring new session). - - lab: Use experimental browser. - - cf_brapi_guardrails: Optional base64url-encoded JSON connection guardrails (mode) - - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not account_id: - raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not session_id: - raise ValueError(f"Expected a non-empty value for `session_id` but received {session_id!r}") - extra_headers = {"Accept": "*/*", **(extra_headers or {})} - extra_headers = {**strip_not_given({"cf-brapi-guardrails": cf_brapi_guardrails}), **(extra_headers or {})} - return await self._get( - path_template( - "/accounts/{account_id}/browser-rendering/devtools/browser/{session_id}", - account_id=account_id, - session_id=session_id, - ), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - query=await async_maybe_transform( - { - "keep_alive": keep_alive, - "lab": lab, - "recording": recording, - }, - browser_connect_params.BrowserConnectParams, - ), - ), - cast_to=NoneType, - ) - - async def launch( - self, - *, - account_id: str, - keep_alive: float | Omit = omit, - lab: bool | Omit = omit, - recording: bool | Omit = omit, - cf_brapi_guardrails: str | Omit = omit, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> None: - """Acquires and establishes a WebSocket connection to a browser session. - - Session - guardrails may be supplied in the `cf-brapi-guardrails` header as - base64url-encoded JSON of the same `guardrails` object the POST body accepts - (for example `{"allowedDomains":["*.example.com"]}`). - - Args: - account_id: Account ID. - - keep_alive: Keep-alive time in ms (only valid when acquiring new session). - - lab: Use experimental browser. - - cf_brapi_guardrails: Optional base64url-encoded JSON session guardrails (allowedDomains and - allowedDomainSets) - - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not account_id: - raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - extra_headers = {"Accept": "*/*", **(extra_headers or {})} - extra_headers = {**strip_not_given({"cf-brapi-guardrails": cf_brapi_guardrails}), **(extra_headers or {})} - return await self._get( - path_template("/accounts/{account_id}/browser-rendering/devtools/browser", account_id=account_id), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - query=await async_maybe_transform( - { - "keep_alive": keep_alive, - "lab": lab, - "recording": recording, - }, - browser_launch_params.BrowserLaunchParams, - ), - ), - cast_to=NoneType, - ) - async def protocol( self, session_id: str, @@ -782,12 +506,6 @@ def __init__(self, browser: BrowserResource) -> None: self.delete = to_raw_response_wrapper( browser.delete, ) - self.connect = to_raw_response_wrapper( - browser.connect, - ) - self.launch = to_raw_response_wrapper( - browser.launch, - ) self.protocol = to_raw_response_wrapper( browser.protocol, ) @@ -799,10 +517,6 @@ def __init__(self, browser: BrowserResource) -> None: def live_view(self) -> LiveViewResourceWithRawResponse: return LiveViewResourceWithRawResponse(self._browser.live_view) - @cached_property - def page(self) -> PageResourceWithRawResponse: - return PageResourceWithRawResponse(self._browser.page) - @cached_property def targets(self) -> TargetsResourceWithRawResponse: return TargetsResourceWithRawResponse(self._browser.targets) @@ -818,12 +532,6 @@ def __init__(self, browser: AsyncBrowserResource) -> None: self.delete = async_to_raw_response_wrapper( browser.delete, ) - self.connect = async_to_raw_response_wrapper( - browser.connect, - ) - self.launch = async_to_raw_response_wrapper( - browser.launch, - ) self.protocol = async_to_raw_response_wrapper( browser.protocol, ) @@ -835,10 +543,6 @@ def __init__(self, browser: AsyncBrowserResource) -> None: def live_view(self) -> AsyncLiveViewResourceWithRawResponse: return AsyncLiveViewResourceWithRawResponse(self._browser.live_view) - @cached_property - def page(self) -> AsyncPageResourceWithRawResponse: - return AsyncPageResourceWithRawResponse(self._browser.page) - @cached_property def targets(self) -> AsyncTargetsResourceWithRawResponse: return AsyncTargetsResourceWithRawResponse(self._browser.targets) @@ -854,12 +558,6 @@ def __init__(self, browser: BrowserResource) -> None: self.delete = to_streamed_response_wrapper( browser.delete, ) - self.connect = to_streamed_response_wrapper( - browser.connect, - ) - self.launch = to_streamed_response_wrapper( - browser.launch, - ) self.protocol = to_streamed_response_wrapper( browser.protocol, ) @@ -871,10 +569,6 @@ def __init__(self, browser: BrowserResource) -> None: def live_view(self) -> LiveViewResourceWithStreamingResponse: return LiveViewResourceWithStreamingResponse(self._browser.live_view) - @cached_property - def page(self) -> PageResourceWithStreamingResponse: - return PageResourceWithStreamingResponse(self._browser.page) - @cached_property def targets(self) -> TargetsResourceWithStreamingResponse: return TargetsResourceWithStreamingResponse(self._browser.targets) @@ -890,12 +584,6 @@ def __init__(self, browser: AsyncBrowserResource) -> None: self.delete = async_to_streamed_response_wrapper( browser.delete, ) - self.connect = async_to_streamed_response_wrapper( - browser.connect, - ) - self.launch = async_to_streamed_response_wrapper( - browser.launch, - ) self.protocol = async_to_streamed_response_wrapper( browser.protocol, ) @@ -907,10 +595,6 @@ def __init__(self, browser: AsyncBrowserResource) -> None: def live_view(self) -> AsyncLiveViewResourceWithStreamingResponse: return AsyncLiveViewResourceWithStreamingResponse(self._browser.live_view) - @cached_property - def page(self) -> AsyncPageResourceWithStreamingResponse: - return AsyncPageResourceWithStreamingResponse(self._browser.page) - @cached_property def targets(self) -> AsyncTargetsResourceWithStreamingResponse: return AsyncTargetsResourceWithStreamingResponse(self._browser.targets) diff --git a/src/cloudflare/resources/browser_rendering/devtools/browser/page.py b/src/cloudflare/resources/browser_rendering/devtools/browser/page.py deleted file mode 100644 index ecd5b32b0fd..00000000000 --- a/src/cloudflare/resources/browser_rendering/devtools/browser/page.py +++ /dev/null @@ -1,207 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -import httpx - -from ....._types import Body, Omit, Query, Headers, NoneType, NotGiven, omit, not_given -from ....._utils import path_template, strip_not_given -from ....._compat import cached_property -from ....._resource import SyncAPIResource, AsyncAPIResource -from ....._response import ( - to_raw_response_wrapper, - to_streamed_response_wrapper, - async_to_raw_response_wrapper, - async_to_streamed_response_wrapper, -) -from ....._base_client import make_request_options - -__all__ = ["PageResource", "AsyncPageResource"] - - -class PageResource(SyncAPIResource): - @cached_property - def with_raw_response(self) -> PageResourceWithRawResponse: - """ - This property can be used as a prefix for any HTTP method call to return - the raw response object instead of the parsed content. - - For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers - """ - return PageResourceWithRawResponse(self) - - @cached_property - def with_streaming_response(self) -> PageResourceWithStreamingResponse: - """ - An alternative to `.with_raw_response` that doesn't eagerly read the response body. - - For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response - """ - return PageResourceWithStreamingResponse(self) - - def get( - self, - target_id: str, - *, - account_id: str, - session_id: str, - cf_brapi_guardrails: str | Omit = omit, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> None: - """ - Establishes a WebSocket connection to a specific Chrome DevTools target or page. - - Args: - account_id: Account ID. - - session_id: Browser session ID. - - target_id: Target ID, e.g. page ID. - - cf_brapi_guardrails: Optional base64url-encoded JSON connection guardrails (mode) - - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not account_id: - raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not session_id: - raise ValueError(f"Expected a non-empty value for `session_id` but received {session_id!r}") - if not target_id: - raise ValueError(f"Expected a non-empty value for `target_id` but received {target_id!r}") - extra_headers = {"Accept": "*/*", **(extra_headers or {})} - extra_headers = {**strip_not_given({"cf-brapi-guardrails": cf_brapi_guardrails}), **(extra_headers or {})} - return self._get( - path_template( - "/accounts/{account_id}/browser-rendering/devtools/browser/{session_id}/page/{target_id}", - account_id=account_id, - session_id=session_id, - target_id=target_id, - ), - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=NoneType, - ) - - -class AsyncPageResource(AsyncAPIResource): - @cached_property - def with_raw_response(self) -> AsyncPageResourceWithRawResponse: - """ - This property can be used as a prefix for any HTTP method call to return - the raw response object instead of the parsed content. - - For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers - """ - return AsyncPageResourceWithRawResponse(self) - - @cached_property - def with_streaming_response(self) -> AsyncPageResourceWithStreamingResponse: - """ - An alternative to `.with_raw_response` that doesn't eagerly read the response body. - - For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response - """ - return AsyncPageResourceWithStreamingResponse(self) - - async def get( - self, - target_id: str, - *, - account_id: str, - session_id: str, - cf_brapi_guardrails: str | Omit = omit, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> None: - """ - Establishes a WebSocket connection to a specific Chrome DevTools target or page. - - Args: - account_id: Account ID. - - session_id: Browser session ID. - - target_id: Target ID, e.g. page ID. - - cf_brapi_guardrails: Optional base64url-encoded JSON connection guardrails (mode) - - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not account_id: - raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not session_id: - raise ValueError(f"Expected a non-empty value for `session_id` but received {session_id!r}") - if not target_id: - raise ValueError(f"Expected a non-empty value for `target_id` but received {target_id!r}") - extra_headers = {"Accept": "*/*", **(extra_headers or {})} - extra_headers = {**strip_not_given({"cf-brapi-guardrails": cf_brapi_guardrails}), **(extra_headers or {})} - return await self._get( - path_template( - "/accounts/{account_id}/browser-rendering/devtools/browser/{session_id}/page/{target_id}", - account_id=account_id, - session_id=session_id, - target_id=target_id, - ), - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=NoneType, - ) - - -class PageResourceWithRawResponse: - def __init__(self, page: PageResource) -> None: - self._page = page - - self.get = to_raw_response_wrapper( - page.get, - ) - - -class AsyncPageResourceWithRawResponse: - def __init__(self, page: AsyncPageResource) -> None: - self._page = page - - self.get = async_to_raw_response_wrapper( - page.get, - ) - - -class PageResourceWithStreamingResponse: - def __init__(self, page: PageResource) -> None: - self._page = page - - self.get = to_streamed_response_wrapper( - page.get, - ) - - -class AsyncPageResourceWithStreamingResponse: - def __init__(self, page: AsyncPageResource) -> None: - self._page = page - - self.get = async_to_streamed_response_wrapper( - page.get, - ) diff --git a/src/cloudflare/resources/browser_rendering/json.py b/src/cloudflare/resources/browser_rendering/json.py index 7bb3f463214..043c20de5d2 100644 --- a/src/cloudflare/resources/browser_rendering/json.py +++ b/src/cloudflare/resources/browser_rendering/json.py @@ -51,6 +51,7 @@ def create( *, account_id: str, url: str, + browser: Literal["kitesurf"] | Omit = omit, cache_ttl: float | Omit = omit, action_timeout: float | Omit = omit, add_script_tag: Iterable[json_create_params.Variant0AddScriptTag] | Omit = omit, @@ -133,6 +134,8 @@ def create( Args: account_id: Account ID. + browser: Rendering backend. Set to `kitesurf` to use Kitesurf (beta). + cache_ttl: Cache TTL default is 5s. Set to 0 to disable. action_timeout: The maximum duration allowed for the browser action to complete after the page @@ -191,6 +194,7 @@ def create( *, account_id: str, html: str, + browser: Literal["kitesurf"] | Omit = omit, cache_ttl: float | Omit = omit, action_timeout: float | Omit = omit, add_script_tag: Iterable[json_create_params.Variant1AddScriptTag] | Omit = omit, @@ -273,6 +277,8 @@ def create( Args: account_id: Account ID. + browser: Rendering backend. Set to `kitesurf` to use Kitesurf (beta). + cache_ttl: Cache TTL default is 5s. Set to 0 to disable. action_timeout: The maximum duration allowed for the browser action to complete after the page @@ -331,6 +337,7 @@ def create( *, account_id: str, url: str | Omit = omit, + browser: Literal["kitesurf"] | Omit = omit, cache_ttl: float | Omit = omit, action_timeout: float | Omit = omit, add_script_tag: Iterable[json_create_params.Variant0AddScriptTag] @@ -454,7 +461,13 @@ def create( extra_query=extra_query, extra_body=extra_body, timeout=timeout, - query=maybe_transform({"cache_ttl": cache_ttl}, json_create_params.JsonCreateParams), + query=maybe_transform( + { + "browser": browser, + "cache_ttl": cache_ttl, + }, + json_create_params.JsonCreateParams, + ), post_parser=ResultWrapper[JsonCreateResponse]._unwrapper, ), cast_to=cast(Type[JsonCreateResponse], ResultWrapper[JsonCreateResponse]), @@ -487,6 +500,7 @@ async def create( *, account_id: str, url: str, + browser: Literal["kitesurf"] | Omit = omit, cache_ttl: float | Omit = omit, action_timeout: float | Omit = omit, add_script_tag: Iterable[json_create_params.Variant0AddScriptTag] | Omit = omit, @@ -569,6 +583,8 @@ async def create( Args: account_id: Account ID. + browser: Rendering backend. Set to `kitesurf` to use Kitesurf (beta). + cache_ttl: Cache TTL default is 5s. Set to 0 to disable. action_timeout: The maximum duration allowed for the browser action to complete after the page @@ -627,6 +643,7 @@ async def create( *, account_id: str, html: str, + browser: Literal["kitesurf"] | Omit = omit, cache_ttl: float | Omit = omit, action_timeout: float | Omit = omit, add_script_tag: Iterable[json_create_params.Variant1AddScriptTag] | Omit = omit, @@ -709,6 +726,8 @@ async def create( Args: account_id: Account ID. + browser: Rendering backend. Set to `kitesurf` to use Kitesurf (beta). + cache_ttl: Cache TTL default is 5s. Set to 0 to disable. action_timeout: The maximum duration allowed for the browser action to complete after the page @@ -767,6 +786,7 @@ async def create( *, account_id: str, url: str | Omit = omit, + browser: Literal["kitesurf"] | Omit = omit, cache_ttl: float | Omit = omit, action_timeout: float | Omit = omit, add_script_tag: Iterable[json_create_params.Variant0AddScriptTag] @@ -890,7 +910,13 @@ async def create( extra_query=extra_query, extra_body=extra_body, timeout=timeout, - query=await async_maybe_transform({"cache_ttl": cache_ttl}, json_create_params.JsonCreateParams), + query=await async_maybe_transform( + { + "browser": browser, + "cache_ttl": cache_ttl, + }, + json_create_params.JsonCreateParams, + ), post_parser=ResultWrapper[JsonCreateResponse]._unwrapper, ), cast_to=cast(Type[JsonCreateResponse], ResultWrapper[JsonCreateResponse]), diff --git a/src/cloudflare/resources/browser_rendering/links.py b/src/cloudflare/resources/browser_rendering/links.py index 33d96d34db5..3adc1bba8ca 100644 --- a/src/cloudflare/resources/browser_rendering/links.py +++ b/src/cloudflare/resources/browser_rendering/links.py @@ -51,6 +51,7 @@ def create( *, account_id: str, url: str, + browser: Literal["kitesurf"] | Omit = omit, cache_ttl: float | Omit = omit, action_timeout: float | Omit = omit, add_script_tag: Iterable[link_create_params.Variant0AddScriptTag] | Omit = omit, @@ -130,6 +131,8 @@ def create( Args: account_id: Account ID. + browser: Rendering backend. Set to `kitesurf` to use Kitesurf (beta). + cache_ttl: Cache TTL default is 5s. Set to 0 to disable. action_timeout: The maximum duration allowed for the browser action to complete after the page @@ -184,6 +187,7 @@ def create( *, account_id: str, html: str, + browser: Literal["kitesurf"] | Omit = omit, cache_ttl: float | Omit = omit, action_timeout: float | Omit = omit, add_script_tag: Iterable[link_create_params.Variant1AddScriptTag] | Omit = omit, @@ -263,6 +267,8 @@ def create( Args: account_id: Account ID. + browser: Rendering backend. Set to `kitesurf` to use Kitesurf (beta). + cache_ttl: Cache TTL default is 5s. Set to 0 to disable. action_timeout: The maximum duration allowed for the browser action to complete after the page @@ -317,6 +323,7 @@ def create( *, account_id: str, url: str | Omit = omit, + browser: Literal["kitesurf"] | Omit = omit, cache_ttl: float | Omit = omit, action_timeout: float | Omit = omit, add_script_tag: Iterable[link_create_params.Variant0AddScriptTag] @@ -434,7 +441,13 @@ def create( extra_query=extra_query, extra_body=extra_body, timeout=timeout, - query=maybe_transform({"cache_ttl": cache_ttl}, link_create_params.LinkCreateParams), + query=maybe_transform( + { + "browser": browser, + "cache_ttl": cache_ttl, + }, + link_create_params.LinkCreateParams, + ), post_parser=ResultWrapper[LinkCreateResponse]._unwrapper, ), cast_to=cast(Type[LinkCreateResponse], ResultWrapper[LinkCreateResponse]), @@ -467,6 +480,7 @@ async def create( *, account_id: str, url: str, + browser: Literal["kitesurf"] | Omit = omit, cache_ttl: float | Omit = omit, action_timeout: float | Omit = omit, add_script_tag: Iterable[link_create_params.Variant0AddScriptTag] | Omit = omit, @@ -546,6 +560,8 @@ async def create( Args: account_id: Account ID. + browser: Rendering backend. Set to `kitesurf` to use Kitesurf (beta). + cache_ttl: Cache TTL default is 5s. Set to 0 to disable. action_timeout: The maximum duration allowed for the browser action to complete after the page @@ -600,6 +616,7 @@ async def create( *, account_id: str, html: str, + browser: Literal["kitesurf"] | Omit = omit, cache_ttl: float | Omit = omit, action_timeout: float | Omit = omit, add_script_tag: Iterable[link_create_params.Variant1AddScriptTag] | Omit = omit, @@ -679,6 +696,8 @@ async def create( Args: account_id: Account ID. + browser: Rendering backend. Set to `kitesurf` to use Kitesurf (beta). + cache_ttl: Cache TTL default is 5s. Set to 0 to disable. action_timeout: The maximum duration allowed for the browser action to complete after the page @@ -733,6 +752,7 @@ async def create( *, account_id: str, url: str | Omit = omit, + browser: Literal["kitesurf"] | Omit = omit, cache_ttl: float | Omit = omit, action_timeout: float | Omit = omit, add_script_tag: Iterable[link_create_params.Variant0AddScriptTag] @@ -850,7 +870,13 @@ async def create( extra_query=extra_query, extra_body=extra_body, timeout=timeout, - query=await async_maybe_transform({"cache_ttl": cache_ttl}, link_create_params.LinkCreateParams), + query=await async_maybe_transform( + { + "browser": browser, + "cache_ttl": cache_ttl, + }, + link_create_params.LinkCreateParams, + ), post_parser=ResultWrapper[LinkCreateResponse]._unwrapper, ), cast_to=cast(Type[LinkCreateResponse], ResultWrapper[LinkCreateResponse]), diff --git a/src/cloudflare/resources/browser_rendering/markdown.py b/src/cloudflare/resources/browser_rendering/markdown.py index 449e58fd055..943ec6a1213 100644 --- a/src/cloudflare/resources/browser_rendering/markdown.py +++ b/src/cloudflare/resources/browser_rendering/markdown.py @@ -51,6 +51,7 @@ def create( *, account_id: str, url: str, + browser: Literal["kitesurf"] | Omit = omit, cache_ttl: float | Omit = omit, action_timeout: float | Omit = omit, add_script_tag: Iterable[markdown_create_params.Variant0AddScriptTag] | Omit = omit, @@ -130,6 +131,8 @@ def create( Args: account_id: Account ID. + browser: Rendering backend. Set to `kitesurf` to use Kitesurf (beta). + cache_ttl: Cache TTL default is 5s. Set to 0 to disable. action_timeout: The maximum duration allowed for the browser action to complete after the page @@ -184,6 +187,7 @@ def create( *, account_id: str, html: str, + browser: Literal["kitesurf"] | Omit = omit, cache_ttl: float | Omit = omit, action_timeout: float | Omit = omit, add_script_tag: Iterable[markdown_create_params.Variant1AddScriptTag] | Omit = omit, @@ -263,6 +267,8 @@ def create( Args: account_id: Account ID. + browser: Rendering backend. Set to `kitesurf` to use Kitesurf (beta). + cache_ttl: Cache TTL default is 5s. Set to 0 to disable. action_timeout: The maximum duration allowed for the browser action to complete after the page @@ -317,6 +323,7 @@ def create( *, account_id: str, url: str | Omit = omit, + browser: Literal["kitesurf"] | Omit = omit, cache_ttl: float | Omit = omit, action_timeout: float | Omit = omit, add_script_tag: Iterable[markdown_create_params.Variant0AddScriptTag] @@ -434,7 +441,13 @@ def create( extra_query=extra_query, extra_body=extra_body, timeout=timeout, - query=maybe_transform({"cache_ttl": cache_ttl}, markdown_create_params.MarkdownCreateParams), + query=maybe_transform( + { + "browser": browser, + "cache_ttl": cache_ttl, + }, + markdown_create_params.MarkdownCreateParams, + ), post_parser=ResultWrapper[Optional[MarkdownCreateResponse]]._unwrapper, ), cast_to=cast(Type[str], ResultWrapper[str]), @@ -467,6 +480,7 @@ async def create( *, account_id: str, url: str, + browser: Literal["kitesurf"] | Omit = omit, cache_ttl: float | Omit = omit, action_timeout: float | Omit = omit, add_script_tag: Iterable[markdown_create_params.Variant0AddScriptTag] | Omit = omit, @@ -546,6 +560,8 @@ async def create( Args: account_id: Account ID. + browser: Rendering backend. Set to `kitesurf` to use Kitesurf (beta). + cache_ttl: Cache TTL default is 5s. Set to 0 to disable. action_timeout: The maximum duration allowed for the browser action to complete after the page @@ -600,6 +616,7 @@ async def create( *, account_id: str, html: str, + browser: Literal["kitesurf"] | Omit = omit, cache_ttl: float | Omit = omit, action_timeout: float | Omit = omit, add_script_tag: Iterable[markdown_create_params.Variant1AddScriptTag] | Omit = omit, @@ -679,6 +696,8 @@ async def create( Args: account_id: Account ID. + browser: Rendering backend. Set to `kitesurf` to use Kitesurf (beta). + cache_ttl: Cache TTL default is 5s. Set to 0 to disable. action_timeout: The maximum duration allowed for the browser action to complete after the page @@ -733,6 +752,7 @@ async def create( *, account_id: str, url: str | Omit = omit, + browser: Literal["kitesurf"] | Omit = omit, cache_ttl: float | Omit = omit, action_timeout: float | Omit = omit, add_script_tag: Iterable[markdown_create_params.Variant0AddScriptTag] @@ -851,7 +871,11 @@ async def create( extra_body=extra_body, timeout=timeout, query=await async_maybe_transform( - {"cache_ttl": cache_ttl}, markdown_create_params.MarkdownCreateParams + { + "browser": browser, + "cache_ttl": cache_ttl, + }, + markdown_create_params.MarkdownCreateParams, ), post_parser=ResultWrapper[Optional[MarkdownCreateResponse]]._unwrapper, ), diff --git a/src/cloudflare/resources/browser_rendering/pdf.py b/src/cloudflare/resources/browser_rendering/pdf.py index b38dd6f939b..a5709fd4f31 100644 --- a/src/cloudflare/resources/browser_rendering/pdf.py +++ b/src/cloudflare/resources/browser_rendering/pdf.py @@ -53,6 +53,7 @@ def create( *, account_id: str, url: str, + browser: Literal["kitesurf"] | Omit = omit, cache_ttl: float | Omit = omit, action_timeout: float | Omit = omit, add_script_tag: Iterable[pdf_create_params.Variant0AddScriptTag] | Omit = omit, @@ -133,6 +134,8 @@ def create( Args: account_id: Account ID. + browser: Rendering backend. Set to `kitesurf` to use Kitesurf (beta). + cache_ttl: Cache TTL default is 5s. Set to 0 to disable. action_timeout: The maximum duration allowed for the browser action to complete after the page @@ -189,6 +192,7 @@ def create( *, account_id: str, html: str, + browser: Literal["kitesurf"] | Omit = omit, cache_ttl: float | Omit = omit, action_timeout: float | Omit = omit, add_script_tag: Iterable[pdf_create_params.Variant1AddScriptTag] | Omit = omit, @@ -269,6 +273,8 @@ def create( Args: account_id: Account ID. + browser: Rendering backend. Set to `kitesurf` to use Kitesurf (beta). + cache_ttl: Cache TTL default is 5s. Set to 0 to disable. action_timeout: The maximum duration allowed for the browser action to complete after the page @@ -325,6 +331,7 @@ def create( *, account_id: str, url: str | Omit = omit, + browser: Literal["kitesurf"] | Omit = omit, cache_ttl: float | Omit = omit, action_timeout: float | Omit = omit, add_script_tag: Iterable[pdf_create_params.Variant0AddScriptTag] @@ -439,7 +446,13 @@ def create( extra_query=extra_query, extra_body=extra_body, timeout=timeout, - query=maybe_transform({"cache_ttl": cache_ttl}, pdf_create_params.PDFCreateParams), + query=maybe_transform( + { + "browser": browser, + "cache_ttl": cache_ttl, + }, + pdf_create_params.PDFCreateParams, + ), ), cast_to=BinaryAPIResponse, ) @@ -471,6 +484,7 @@ async def create( *, account_id: str, url: str, + browser: Literal["kitesurf"] | Omit = omit, cache_ttl: float | Omit = omit, action_timeout: float | Omit = omit, add_script_tag: Iterable[pdf_create_params.Variant0AddScriptTag] | Omit = omit, @@ -551,6 +565,8 @@ async def create( Args: account_id: Account ID. + browser: Rendering backend. Set to `kitesurf` to use Kitesurf (beta). + cache_ttl: Cache TTL default is 5s. Set to 0 to disable. action_timeout: The maximum duration allowed for the browser action to complete after the page @@ -607,6 +623,7 @@ async def create( *, account_id: str, html: str, + browser: Literal["kitesurf"] | Omit = omit, cache_ttl: float | Omit = omit, action_timeout: float | Omit = omit, add_script_tag: Iterable[pdf_create_params.Variant1AddScriptTag] | Omit = omit, @@ -687,6 +704,8 @@ async def create( Args: account_id: Account ID. + browser: Rendering backend. Set to `kitesurf` to use Kitesurf (beta). + cache_ttl: Cache TTL default is 5s. Set to 0 to disable. action_timeout: The maximum duration allowed for the browser action to complete after the page @@ -743,6 +762,7 @@ async def create( *, account_id: str, url: str | Omit = omit, + browser: Literal["kitesurf"] | Omit = omit, cache_ttl: float | Omit = omit, action_timeout: float | Omit = omit, add_script_tag: Iterable[pdf_create_params.Variant0AddScriptTag] @@ -857,7 +877,13 @@ async def create( extra_query=extra_query, extra_body=extra_body, timeout=timeout, - query=await async_maybe_transform({"cache_ttl": cache_ttl}, pdf_create_params.PDFCreateParams), + query=await async_maybe_transform( + { + "browser": browser, + "cache_ttl": cache_ttl, + }, + pdf_create_params.PDFCreateParams, + ), ), cast_to=AsyncBinaryAPIResponse, ) diff --git a/src/cloudflare/resources/browser_rendering/scrape.py b/src/cloudflare/resources/browser_rendering/scrape.py index d0c0a47e8b2..9d5591b4896 100644 --- a/src/cloudflare/resources/browser_rendering/scrape.py +++ b/src/cloudflare/resources/browser_rendering/scrape.py @@ -51,6 +51,7 @@ def create( *, account_id: str, url: str, + browser: Literal["kitesurf"] | Omit = omit, cache_ttl: float | Omit = omit, action_timeout: float | Omit = omit, add_script_tag: Iterable[scrape_create_params.Variant0AddScriptTag] | Omit = omit, @@ -129,6 +130,8 @@ def create( Args: account_id: Account ID. + browser: Rendering backend. Set to `kitesurf` to use Kitesurf (beta). + cache_ttl: Cache TTL default is 5s. Set to 0 to disable. action_timeout: The maximum duration allowed for the browser action to complete after the page @@ -183,6 +186,7 @@ def create( *, account_id: str, html: str, + browser: Literal["kitesurf"] | Omit = omit, cache_ttl: float | Omit = omit, action_timeout: float | Omit = omit, add_script_tag: Iterable[scrape_create_params.Variant1AddScriptTag] | Omit = omit, @@ -261,6 +265,8 @@ def create( Args: account_id: Account ID. + browser: Rendering backend. Set to `kitesurf` to use Kitesurf (beta). + cache_ttl: Cache TTL default is 5s. Set to 0 to disable. action_timeout: The maximum duration allowed for the browser action to complete after the page @@ -315,6 +321,7 @@ def create( *, account_id: str, url: str | Omit = omit, + browser: Literal["kitesurf"] | Omit = omit, cache_ttl: float | Omit = omit, action_timeout: float | Omit = omit, add_script_tag: Iterable[scrape_create_params.Variant0AddScriptTag] @@ -434,7 +441,13 @@ def create( extra_query=extra_query, extra_body=extra_body, timeout=timeout, - query=maybe_transform({"cache_ttl": cache_ttl}, scrape_create_params.ScrapeCreateParams), + query=maybe_transform( + { + "browser": browser, + "cache_ttl": cache_ttl, + }, + scrape_create_params.ScrapeCreateParams, + ), post_parser=ResultWrapper[ScrapeCreateResponse]._unwrapper, ), cast_to=cast(Type[ScrapeCreateResponse], ResultWrapper[ScrapeCreateResponse]), @@ -467,6 +480,7 @@ async def create( *, account_id: str, url: str, + browser: Literal["kitesurf"] | Omit = omit, cache_ttl: float | Omit = omit, action_timeout: float | Omit = omit, add_script_tag: Iterable[scrape_create_params.Variant0AddScriptTag] | Omit = omit, @@ -545,6 +559,8 @@ async def create( Args: account_id: Account ID. + browser: Rendering backend. Set to `kitesurf` to use Kitesurf (beta). + cache_ttl: Cache TTL default is 5s. Set to 0 to disable. action_timeout: The maximum duration allowed for the browser action to complete after the page @@ -599,6 +615,7 @@ async def create( *, account_id: str, html: str, + browser: Literal["kitesurf"] | Omit = omit, cache_ttl: float | Omit = omit, action_timeout: float | Omit = omit, add_script_tag: Iterable[scrape_create_params.Variant1AddScriptTag] | Omit = omit, @@ -677,6 +694,8 @@ async def create( Args: account_id: Account ID. + browser: Rendering backend. Set to `kitesurf` to use Kitesurf (beta). + cache_ttl: Cache TTL default is 5s. Set to 0 to disable. action_timeout: The maximum duration allowed for the browser action to complete after the page @@ -731,6 +750,7 @@ async def create( *, account_id: str, url: str | Omit = omit, + browser: Literal["kitesurf"] | Omit = omit, cache_ttl: float | Omit = omit, action_timeout: float | Omit = omit, add_script_tag: Iterable[scrape_create_params.Variant0AddScriptTag] @@ -850,7 +870,13 @@ async def create( extra_query=extra_query, extra_body=extra_body, timeout=timeout, - query=await async_maybe_transform({"cache_ttl": cache_ttl}, scrape_create_params.ScrapeCreateParams), + query=await async_maybe_transform( + { + "browser": browser, + "cache_ttl": cache_ttl, + }, + scrape_create_params.ScrapeCreateParams, + ), post_parser=ResultWrapper[ScrapeCreateResponse]._unwrapper, ), cast_to=cast(Type[ScrapeCreateResponse], ResultWrapper[ScrapeCreateResponse]), diff --git a/src/cloudflare/resources/browser_rendering/screenshot.py b/src/cloudflare/resources/browser_rendering/screenshot.py index 8323a16f1d0..ab00ee694a3 100644 --- a/src/cloudflare/resources/browser_rendering/screenshot.py +++ b/src/cloudflare/resources/browser_rendering/screenshot.py @@ -50,6 +50,7 @@ def create( *, account_id: str, url: str, + browser: Literal["kitesurf"] | Omit = omit, cache_ttl: float | Omit = omit, action_timeout: float | Omit = omit, add_script_tag: Iterable[screenshot_create_params.Variant0AddScriptTag] | Omit = omit, @@ -133,6 +134,8 @@ def create( Args: account_id: Account ID. + browser: Rendering backend. Set to `kitesurf` to use Kitesurf (beta). + cache_ttl: Cache TTL default is 5s. Set to 0 to disable. action_timeout: The maximum duration allowed for the browser action to complete after the page @@ -189,6 +192,7 @@ def create( *, account_id: str, html: str, + browser: Literal["kitesurf"] | Omit = omit, cache_ttl: float | Omit = omit, action_timeout: float | Omit = omit, add_script_tag: Iterable[screenshot_create_params.Variant1AddScriptTag] | Omit = omit, @@ -272,6 +276,8 @@ def create( Args: account_id: Account ID. + browser: Rendering backend. Set to `kitesurf` to use Kitesurf (beta). + cache_ttl: Cache TTL default is 5s. Set to 0 to disable. action_timeout: The maximum duration allowed for the browser action to complete after the page @@ -328,6 +334,7 @@ def create( *, account_id: str, url: str | Omit = omit, + browser: Literal["kitesurf"] | Omit = omit, cache_ttl: float | Omit = omit, action_timeout: float | Omit = omit, add_script_tag: Iterable[screenshot_create_params.Variant0AddScriptTag] @@ -453,7 +460,13 @@ def create( extra_query=extra_query, extra_body=extra_body, timeout=timeout, - query=maybe_transform({"cache_ttl": cache_ttl}, screenshot_create_params.ScreenshotCreateParams), + query=maybe_transform( + { + "browser": browser, + "cache_ttl": cache_ttl, + }, + screenshot_create_params.ScreenshotCreateParams, + ), ), cast_to=ScreenshotCreateResponse, ) @@ -485,6 +498,7 @@ async def create( *, account_id: str, url: str, + browser: Literal["kitesurf"] | Omit = omit, cache_ttl: float | Omit = omit, action_timeout: float | Omit = omit, add_script_tag: Iterable[screenshot_create_params.Variant0AddScriptTag] | Omit = omit, @@ -568,6 +582,8 @@ async def create( Args: account_id: Account ID. + browser: Rendering backend. Set to `kitesurf` to use Kitesurf (beta). + cache_ttl: Cache TTL default is 5s. Set to 0 to disable. action_timeout: The maximum duration allowed for the browser action to complete after the page @@ -624,6 +640,7 @@ async def create( *, account_id: str, html: str, + browser: Literal["kitesurf"] | Omit = omit, cache_ttl: float | Omit = omit, action_timeout: float | Omit = omit, add_script_tag: Iterable[screenshot_create_params.Variant1AddScriptTag] | Omit = omit, @@ -707,6 +724,8 @@ async def create( Args: account_id: Account ID. + browser: Rendering backend. Set to `kitesurf` to use Kitesurf (beta). + cache_ttl: Cache TTL default is 5s. Set to 0 to disable. action_timeout: The maximum duration allowed for the browser action to complete after the page @@ -763,6 +782,7 @@ async def create( *, account_id: str, url: str | Omit = omit, + browser: Literal["kitesurf"] | Omit = omit, cache_ttl: float | Omit = omit, action_timeout: float | Omit = omit, add_script_tag: Iterable[screenshot_create_params.Variant0AddScriptTag] @@ -889,7 +909,11 @@ async def create( extra_body=extra_body, timeout=timeout, query=await async_maybe_transform( - {"cache_ttl": cache_ttl}, screenshot_create_params.ScreenshotCreateParams + { + "browser": browser, + "cache_ttl": cache_ttl, + }, + screenshot_create_params.ScreenshotCreateParams, ), ), cast_to=ScreenshotCreateResponse, diff --git a/src/cloudflare/resources/browser_rendering/snapshot.py b/src/cloudflare/resources/browser_rendering/snapshot.py index 4df16cbed87..c94ee864ff2 100644 --- a/src/cloudflare/resources/browser_rendering/snapshot.py +++ b/src/cloudflare/resources/browser_rendering/snapshot.py @@ -51,6 +51,7 @@ def create( *, account_id: str, url: str, + browser: Literal["kitesurf"] | Omit = omit, cache_ttl: float | Omit = omit, action_timeout: float | Omit = omit, add_script_tag: Iterable[snapshot_create_params.Variant0AddScriptTag] | Omit = omit, @@ -133,6 +134,8 @@ def create( Args: account_id: Account ID. + browser: Rendering backend. Set to `kitesurf` to use Kitesurf (beta). + cache_ttl: Cache TTL default is 5s. Set to 0 to disable. action_timeout: The maximum duration allowed for the browser action to complete after the page @@ -187,6 +190,7 @@ def create( *, account_id: str, html: str, + browser: Literal["kitesurf"] | Omit = omit, cache_ttl: float | Omit = omit, action_timeout: float | Omit = omit, add_script_tag: Iterable[snapshot_create_params.Variant1AddScriptTag] | Omit = omit, @@ -269,6 +273,8 @@ def create( Args: account_id: Account ID. + browser: Rendering backend. Set to `kitesurf` to use Kitesurf (beta). + cache_ttl: Cache TTL default is 5s. Set to 0 to disable. action_timeout: The maximum duration allowed for the browser action to complete after the page @@ -323,6 +329,7 @@ def create( *, account_id: str, url: str | Omit = omit, + browser: Literal["kitesurf"] | Omit = omit, cache_ttl: float | Omit = omit, action_timeout: float | Omit = omit, add_script_tag: Iterable[snapshot_create_params.Variant0AddScriptTag] @@ -446,7 +453,13 @@ def create( extra_query=extra_query, extra_body=extra_body, timeout=timeout, - query=maybe_transform({"cache_ttl": cache_ttl}, snapshot_create_params.SnapshotCreateParams), + query=maybe_transform( + { + "browser": browser, + "cache_ttl": cache_ttl, + }, + snapshot_create_params.SnapshotCreateParams, + ), post_parser=ResultWrapper[Optional[SnapshotCreateResponse]]._unwrapper, ), cast_to=cast(Type[Optional[SnapshotCreateResponse]], ResultWrapper[SnapshotCreateResponse]), @@ -479,6 +492,7 @@ async def create( *, account_id: str, url: str, + browser: Literal["kitesurf"] | Omit = omit, cache_ttl: float | Omit = omit, action_timeout: float | Omit = omit, add_script_tag: Iterable[snapshot_create_params.Variant0AddScriptTag] | Omit = omit, @@ -561,6 +575,8 @@ async def create( Args: account_id: Account ID. + browser: Rendering backend. Set to `kitesurf` to use Kitesurf (beta). + cache_ttl: Cache TTL default is 5s. Set to 0 to disable. action_timeout: The maximum duration allowed for the browser action to complete after the page @@ -615,6 +631,7 @@ async def create( *, account_id: str, html: str, + browser: Literal["kitesurf"] | Omit = omit, cache_ttl: float | Omit = omit, action_timeout: float | Omit = omit, add_script_tag: Iterable[snapshot_create_params.Variant1AddScriptTag] | Omit = omit, @@ -697,6 +714,8 @@ async def create( Args: account_id: Account ID. + browser: Rendering backend. Set to `kitesurf` to use Kitesurf (beta). + cache_ttl: Cache TTL default is 5s. Set to 0 to disable. action_timeout: The maximum duration allowed for the browser action to complete after the page @@ -751,6 +770,7 @@ async def create( *, account_id: str, url: str | Omit = omit, + browser: Literal["kitesurf"] | Omit = omit, cache_ttl: float | Omit = omit, action_timeout: float | Omit = omit, add_script_tag: Iterable[snapshot_create_params.Variant0AddScriptTag] @@ -875,7 +895,11 @@ async def create( extra_body=extra_body, timeout=timeout, query=await async_maybe_transform( - {"cache_ttl": cache_ttl}, snapshot_create_params.SnapshotCreateParams + { + "browser": browser, + "cache_ttl": cache_ttl, + }, + snapshot_create_params.SnapshotCreateParams, ), post_parser=ResultWrapper[Optional[SnapshotCreateResponse]]._unwrapper, ), diff --git a/src/cloudflare/resources/cloudforce_one/threat_events/aggregate.py b/src/cloudflare/resources/cloudforce_one/threat_events/aggregate.py index 69970228f70..b19daa8b6e2 100644 --- a/src/cloudflare/resources/cloudforce_one/threat_events/aggregate.py +++ b/src/cloudflare/resources/cloudforce_one/threat_events/aggregate.py @@ -59,20 +59,22 @@ def list( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> AggregateListResponse: """ - Aggregate threat events by one or more columns (e.g., attacker, targetIndustry) - with optional date filtering and daily grouping. Supports multi-dimensional - aggregation for cross-analysis. + Counts events grouped by one or more columns, such as `attacker` or + `targetIndustry`. Optionally filter by date range and group the counts by day. Args: account_id: Account ID. aggregate_by: Column(s) to aggregate by - single column or comma-separated list (e.g., - 'attacker', 'targetIndustry', 'attacker,targetIndustry') + 'attacker', 'targetIndustry', 'attacker,targetIndustry'). With `tags`, an event + counts once for each of its tags, in the bucket counts and in `total`, and + events without tags count as `Unknown`; `tags` is not supported for analytics + datasets. - dataset_id: Dataset UUIDs to filter by, or one standalone scope value: 'all'/'\\**' for all - accessible non-analytics event datasets (analytics datasets are silently - excluded), 'analytics' for isAnalytics=true datasets, or 'operational' for - isAnalytics=false datasets. If not provided, uses the default dataset. + dataset_id: Dataset UUIDs to filter by, or one standalone scope value: 'all'/'\\**' or + 'operational' for readable intelligence datasets (isAnalytics=false), or + 'analytics' for readable analytics datasets (isAnalytics=true). Scope values + query at most 50 datasets. If not provided, uses the default dataset. end_date: End date for filtering (ISO 8601 format, e.g., '2024-12-31') @@ -153,20 +155,22 @@ async def list( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> AggregateListResponse: """ - Aggregate threat events by one or more columns (e.g., attacker, targetIndustry) - with optional date filtering and daily grouping. Supports multi-dimensional - aggregation for cross-analysis. + Counts events grouped by one or more columns, such as `attacker` or + `targetIndustry`. Optionally filter by date range and group the counts by day. Args: account_id: Account ID. aggregate_by: Column(s) to aggregate by - single column or comma-separated list (e.g., - 'attacker', 'targetIndustry', 'attacker,targetIndustry') - - dataset_id: Dataset UUIDs to filter by, or one standalone scope value: 'all'/'\\**' for all - accessible non-analytics event datasets (analytics datasets are silently - excluded), 'analytics' for isAnalytics=true datasets, or 'operational' for - isAnalytics=false datasets. If not provided, uses the default dataset. + 'attacker', 'targetIndustry', 'attacker,targetIndustry'). With `tags`, an event + counts once for each of its tags, in the bucket counts and in `total`, and + events without tags count as `Unknown`; `tags` is not supported for analytics + datasets. + + dataset_id: Dataset UUIDs to filter by, or one standalone scope value: 'all'/'\\**' or + 'operational' for readable intelligence datasets (isAnalytics=false), or + 'analytics' for readable analytics datasets (isAnalytics=true). Scope values + query at most 50 datasets. If not provided, uses the default dataset. end_date: End date for filtering (ISO 8601 format, e.g., '2024-12-31') diff --git a/src/cloudflare/resources/cloudforce_one/threat_events/attackers.py b/src/cloudflare/resources/cloudforce_one/threat_events/attackers.py index ed1d4fdbec6..1d8109ed763 100644 --- a/src/cloudflare/resources/cloudforce_one/threat_events/attackers.py +++ b/src/cloudflare/resources/cloudforce_one/threat_events/attackers.py @@ -54,7 +54,8 @@ def list( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> AttackerListResponse: """ - Lists known threat attackers tracked in Cloudforce One threat intelligence. + Lists the attackers referenced by events in the datasets given by `datasetIds`, + or in the default dataset when `datasetIds` is omitted. Args: account_id: Account ID. @@ -118,7 +119,8 @@ async def list( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> AttackerListResponse: """ - Lists known threat attackers tracked in Cloudforce One threat intelligence. + Lists the attackers referenced by events in the datasets given by `datasetIds`, + or in the default dataset when `datasetIds` is omitted. Args: account_id: Account ID. diff --git a/src/cloudflare/resources/cloudforce_one/threat_events/categories/catalog.py b/src/cloudflare/resources/cloudforce_one/threat_events/categories/catalog.py index 91cbc64e115..d31fb1f30c2 100644 --- a/src/cloudflare/resources/cloudforce_one/threat_events/categories/catalog.py +++ b/src/cloudflare/resources/cloudforce_one/threat_events/categories/catalog.py @@ -51,8 +51,11 @@ def list( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> CatalogListResponse: - """ - Lists categories + """Lists every event category in the catalog, whether or not an event uses it. + + To + list only the categories used in specific datasets, use + `threat-intel events categories list`. Args: account_id: Account ID. @@ -107,8 +110,11 @@ async def list( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> CatalogListResponse: - """ - Lists categories + """Lists every event category in the catalog, whether or not an event uses it. + + To + list only the categories used in specific datasets, use + `threat-intel events categories list`. Args: account_id: Account ID. diff --git a/src/cloudflare/resources/cloudforce_one/threat_events/categories/categories.py b/src/cloudflare/resources/cloudforce_one/threat_events/categories/categories.py index 8fa4f55c698..1e89ab991cb 100644 --- a/src/cloudflare/resources/cloudforce_one/threat_events/categories/categories.py +++ b/src/cloudflare/resources/cloudforce_one/threat_events/categories/categories.py @@ -75,9 +75,10 @@ def create( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> CategoryCreateResponse: - """ - Creates a new threat event category in Cloudforce One for organizing and - classifying threat events. + """Creates an event category for classifying events. + + `name` and `killChain` are + required. Args: account_id: Account ID. @@ -123,8 +124,10 @@ def list( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> CategoryListResponse: """ - Lists all threat event categories configured for classifying and organizing - threat events. + Lists the event categories used by events in the datasets given by `datasetIds`, + or in the default dataset when `datasetIds` is omitted. Dataset scope values are + not supported. To list every category, use + `threat-intel events categories catalog list`. Args: account_id: Account ID. @@ -167,9 +170,10 @@ def delete( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> CategoryDeleteResponse: - """Deprecated; use DELETE /events/event-categories/by-id/{category_id}. + """Legacy. - Available + Use `threat-intel events categories delete` + (`DELETE /events/event-categories/by-id/{category_id}`) instead. Available through 2026-11-28. Args: @@ -219,9 +223,10 @@ def edit( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> CategoryEditResponse: - """Deprecated; use PATCH /events/event-categories/by-id/{category_id}. + """Legacy. - Available + Use `threat-intel events categories update` + (`PATCH /events/event-categories/by-id/{category_id}`) instead. Available through 2026-11-28. Args: @@ -276,10 +281,11 @@ def get( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> CategoryGetResponse: - """Deprecated; use GET /events/event-categories/by-id/{category_id}. + """Legacy. - Available - through 2026-11-28. + Use `threat-intel events categories get` + (`GET /events/event-categories/by-id/{category_id}`) instead. Available through + 2026-11-28. Args: account_id: Account ID. @@ -351,9 +357,10 @@ async def create( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> CategoryCreateResponse: - """ - Creates a new threat event category in Cloudforce One for organizing and - classifying threat events. + """Creates an event category for classifying events. + + `name` and `killChain` are + required. Args: account_id: Account ID. @@ -399,8 +406,10 @@ async def list( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> CategoryListResponse: """ - Lists all threat event categories configured for classifying and organizing - threat events. + Lists the event categories used by events in the datasets given by `datasetIds`, + or in the default dataset when `datasetIds` is omitted. Dataset scope values are + not supported. To list every category, use + `threat-intel events categories catalog list`. Args: account_id: Account ID. @@ -445,9 +454,10 @@ async def delete( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> CategoryDeleteResponse: - """Deprecated; use DELETE /events/event-categories/by-id/{category_id}. + """Legacy. - Available + Use `threat-intel events categories delete` + (`DELETE /events/event-categories/by-id/{category_id}`) instead. Available through 2026-11-28. Args: @@ -497,9 +507,10 @@ async def edit( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> CategoryEditResponse: - """Deprecated; use PATCH /events/event-categories/by-id/{category_id}. + """Legacy. - Available + Use `threat-intel events categories update` + (`PATCH /events/event-categories/by-id/{category_id}`) instead. Available through 2026-11-28. Args: @@ -554,10 +565,11 @@ async def get( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> CategoryGetResponse: - """Deprecated; use GET /events/event-categories/by-id/{category_id}. + """Legacy. - Available - through 2026-11-28. + Use `threat-intel events categories get` + (`GET /events/event-categories/by-id/{category_id}`) instead. Available through + 2026-11-28. Args: account_id: Account ID. diff --git a/src/cloudflare/resources/cloudforce_one/threat_events/countries.py b/src/cloudflare/resources/cloudforce_one/threat_events/countries.py index f7f6e2a6927..597b1d02042 100644 --- a/src/cloudflare/resources/cloudforce_one/threat_events/countries.py +++ b/src/cloudflare/resources/cloudforce_one/threat_events/countries.py @@ -52,7 +52,8 @@ def list( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> CountryListResponse: """ - Lists countries referenced in Cloudforce One threat intelligence data. + Lists the countries used in threat intelligence data, such as attacker and + target countries. Args: account_id: Account ID. @@ -108,7 +109,8 @@ async def list( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> CountryListResponse: """ - Lists countries referenced in Cloudforce One threat intelligence data. + Lists the countries used in threat intelligence data, such as attacker and + target countries. Args: account_id: Account ID. diff --git a/src/cloudflare/resources/cloudforce_one/threat_events/datasets/datasets.py b/src/cloudflare/resources/cloudforce_one/threat_events/datasets/datasets.py index 8aa1e9b2e82..4781b7bd2da 100644 --- a/src/cloudflare/resources/cloudforce_one/threat_events/datasets/datasets.py +++ b/src/cloudflare/resources/cloudforce_one/threat_events/datasets/datasets.py @@ -73,9 +73,10 @@ def create( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> DatasetCreateResponse: - """ - Creates a new threat event dataset in Cloudforce One for organizing related - threat events. + """Creates a dataset for grouping events. + + Set `isPublic` to true to let anyone + search it; otherwise only the account can. Args: account_id: Account ID. @@ -122,8 +123,9 @@ def list( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> DatasetListResponse: - """ - Lists all threat event datasets configured in Cloudforce One. + """Lists the account's datasets. + + Set `includeDeleted` to include deleted datasets. Args: account_id: Account ID. @@ -165,8 +167,10 @@ def delete( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> DatasetDeleteResponse: - """ - Soft-deletes a dataset given a datasetId. + """Deletes a dataset. + + To see deleted datasets, use `threat-intel datasets list` + with `includeDeleted`. Args: account_id: Account ID. @@ -211,9 +215,9 @@ def edit( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> DatasetEditResponse: - """ - Partially updates a threat event dataset in Cloudforce One, modifying specific - fields without replacing the entire dataset configuration. + """Updates a dataset's `name` and `isPublic` setting. + + Both fields are required. Args: account_id: Account ID. @@ -269,7 +273,7 @@ def get( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> DatasetGetResponse: """ - Retrieves details for a specific threat event dataset. + Returns a dataset by its ID. Args: account_id: Account ID. @@ -314,9 +318,11 @@ def raw( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> DatasetRawResponse: - """ - Deprecated; use GET /events/datasets/{dataset_id}/events/{event_id}/raw. - Available through 2026-11-28. + """Legacy. + + Use `threat-intel events raw get` + (`GET /events/datasets/{dataset_id}/events/{event_id}/raw`) instead. Available + through 2026-11-28. Args: account_id: Account ID. @@ -390,9 +396,10 @@ async def create( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> DatasetCreateResponse: - """ - Creates a new threat event dataset in Cloudforce One for organizing related - threat events. + """Creates a dataset for grouping events. + + Set `isPublic` to true to let anyone + search it; otherwise only the account can. Args: account_id: Account ID. @@ -439,8 +446,9 @@ async def list( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> DatasetListResponse: - """ - Lists all threat event datasets configured in Cloudforce One. + """Lists the account's datasets. + + Set `includeDeleted` to include deleted datasets. Args: account_id: Account ID. @@ -484,8 +492,10 @@ async def delete( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> DatasetDeleteResponse: - """ - Soft-deletes a dataset given a datasetId. + """Deletes a dataset. + + To see deleted datasets, use `threat-intel datasets list` + with `includeDeleted`. Args: account_id: Account ID. @@ -530,9 +540,9 @@ async def edit( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> DatasetEditResponse: - """ - Partially updates a threat event dataset in Cloudforce One, modifying specific - fields without replacing the entire dataset configuration. + """Updates a dataset's `name` and `isPublic` setting. + + Both fields are required. Args: account_id: Account ID. @@ -588,7 +598,7 @@ async def get( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> DatasetGetResponse: """ - Retrieves details for a specific threat event dataset. + Returns a dataset by its ID. Args: account_id: Account ID. @@ -633,9 +643,11 @@ async def raw( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> DatasetRawResponse: - """ - Deprecated; use GET /events/datasets/{dataset_id}/events/{event_id}/raw. - Available through 2026-11-28. + """Legacy. + + Use `threat-intel events raw get` + (`GET /events/datasets/{dataset_id}/events/{event_id}/raw`) instead. Available + through 2026-11-28. Args: account_id: Account ID. diff --git a/src/cloudflare/resources/cloudforce_one/threat_events/datasets/events.py b/src/cloudflare/resources/cloudforce_one/threat_events/datasets/events.py index 2d5b06456da..ab0d552b4a3 100644 --- a/src/cloudflare/resources/cloudforce_one/threat_events/datasets/events.py +++ b/src/cloudflare/resources/cloudforce_one/threat_events/datasets/events.py @@ -54,7 +54,7 @@ def get( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> EventGetResponse: """ - Retrieves a specific event by its UUID. + Returns an event from a dataset by its UUID. Args: account_id: Account ID. @@ -125,7 +125,7 @@ async def get( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> EventGetResponse: """ - Retrieves a specific event by its UUID. + Returns an event from a dataset by its UUID. Args: account_id: Account ID. diff --git a/src/cloudflare/resources/cloudforce_one/threat_events/event_tags.py b/src/cloudflare/resources/cloudforce_one/threat_events/event_tags.py index ecbc8274a20..3a6ff3dfd45 100644 --- a/src/cloudflare/resources/cloudforce_one/threat_events/event_tags.py +++ b/src/cloudflare/resources/cloudforce_one/threat_events/event_tags.py @@ -58,8 +58,10 @@ def create( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> EventTagCreateResponse: - """ - Adds a tag to a threat event in Cloudforce One for classification and filtering. + """Legacy. + + Use `threat-intel tags relationships create` + (`POST /events/tags/{tag_uuid}/relationships`) instead. Args: account_id: Account ID. @@ -107,8 +109,10 @@ def delete( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> EventTagDeleteResponse: - """ - Removes a tag from a threat event in Cloudforce One. + """Legacy. + + Use `threat-intel tags relationships delete` + (`DELETE /events/tags/{tag_uuid}/relationships/{rel_uuid}`) instead. Args: account_id: Account ID. @@ -177,8 +181,10 @@ async def create( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> EventTagCreateResponse: - """ - Adds a tag to a threat event in Cloudforce One for classification and filtering. + """Legacy. + + Use `threat-intel tags relationships create` + (`POST /events/tags/{tag_uuid}/relationships`) instead. Args: account_id: Account ID. @@ -226,8 +232,10 @@ async def delete( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> EventTagDeleteResponse: - """ - Removes a tag from a threat event in Cloudforce One. + """Legacy. + + Use `threat-intel tags relationships delete` + (`DELETE /events/tags/{tag_uuid}/relationships/{rel_uuid}`) instead. Args: account_id: Account ID. diff --git a/src/cloudflare/resources/cloudforce_one/threat_events/graph.py b/src/cloudflare/resources/cloudforce_one/threat_events/graph.py index d4c4e18616b..9bf30c35247 100644 --- a/src/cloudflare/resources/cloudforce_one/threat_events/graph.py +++ b/src/cloudflare/resources/cloudforce_one/threat_events/graph.py @@ -78,8 +78,11 @@ def list( otherwise. dataset_ids: Comma-separated dataset UUIDs to restrict neighbor scope, or one standalone - scope value: 'all'/'\\**', 'analytics' for isAnalytics=true datasets, or - 'operational' for isAnalytics=false datasets. Intersected with access grants. + scope value: 'operational' for readable intelligence datasets + (isAnalytics=false), 'analytics' for readable analytics datasets + (isAnalytics=true), or 'all'/'\\**' for every readable dataset including analytics + datasets (the graph reads analytics relationships from R2). Intersected with + access grants. direction: Edge direction relative to each seed: out (seed→neighbors), in (neighbors→seed), both (default). @@ -195,8 +198,11 @@ async def list( otherwise. dataset_ids: Comma-separated dataset UUIDs to restrict neighbor scope, or one standalone - scope value: 'all'/'\\**', 'analytics' for isAnalytics=true datasets, or - 'operational' for isAnalytics=false datasets. Intersected with access grants. + scope value: 'operational' for readable intelligence datasets + (isAnalytics=false), 'analytics' for readable analytics datasets + (isAnalytics=true), or 'all'/'\\**' for every readable dataset including analytics + datasets (the graph reads analytics relationships from R2). Intersected with + access grants. direction: Edge direction relative to each seed: out (seed→neighbors), in (neighbors→seed), both (default). diff --git a/src/cloudflare/resources/cloudforce_one/threat_events/graphql.py b/src/cloudflare/resources/cloudforce_one/threat_events/graphql.py index d912018c795..181d0f8fc4d 100644 --- a/src/cloudflare/resources/cloudforce_one/threat_events/graphql.py +++ b/src/cloudflare/resources/cloudforce_one/threat_events/graphql.py @@ -51,10 +51,10 @@ def create( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> GraphqlCreateResponse: - """Execute GraphQL aggregations over threat events. + """Runs a GraphQL aggregation query over events. - Supports multi-dimensional - group-bys, optional date range filtering, and multi-dataset aggregation. + Supports grouping by multiple + fields, date range filters, and aggregation across datasets. Args: account_id: Account ID. @@ -109,10 +109,10 @@ async def create( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> GraphqlCreateResponse: - """Execute GraphQL aggregations over threat events. + """Runs a GraphQL aggregation query over events. - Supports multi-dimensional - group-bys, optional date range filtering, and multi-dataset aggregation. + Supports grouping by multiple + fields, date range filters, and aggregation across datasets. Args: account_id: Account ID. diff --git a/src/cloudflare/resources/cloudforce_one/threat_events/indicators/aggregate.py b/src/cloudflare/resources/cloudforce_one/threat_events/indicators/aggregate.py index adf83b094d6..35d8265dd2b 100644 --- a/src/cloudflare/resources/cloudforce_one/threat_events/indicators/aggregate.py +++ b/src/cloudflare/resources/cloudforce_one/threat_events/indicators/aggregate.py @@ -81,10 +81,11 @@ def list( created_before: Filter indicators created before this date/datetime (ISO 8601, e.g., '2024-12-31' or '2024-12-31T23:59:59Z') - dataset_ids: Dataset UUIDs to filter by, or one standalone scope value: 'all'/'\\**' for all - accessible datasets, 'analytics' for isAnalytics=true datasets, or 'operational' - for isAnalytics=false datasets. If not provided, aggregates across all - accessible datasets. + dataset_ids: Dataset UUIDs to filter by, or one standalone scope value: 'operational' for + readable intelligence datasets (isAnalytics=false), 'analytics' for readable + analytics datasets (isAnalytics=true), or 'all'/'\\**' for every readable dataset + including analytics datasets. If not provided, aggregates across all accessible + datasets, including analytics datasets. event_date_after: For measure=relationships: only count indicator→event links whose relationship was created/observed on or after this date (ISO 8601). Bounds the activity view @@ -197,10 +198,11 @@ async def list( created_before: Filter indicators created before this date/datetime (ISO 8601, e.g., '2024-12-31' or '2024-12-31T23:59:59Z') - dataset_ids: Dataset UUIDs to filter by, or one standalone scope value: 'all'/'\\**' for all - accessible datasets, 'analytics' for isAnalytics=true datasets, or 'operational' - for isAnalytics=false datasets. If not provided, aggregates across all - accessible datasets. + dataset_ids: Dataset UUIDs to filter by, or one standalone scope value: 'operational' for + readable intelligence datasets (isAnalytics=false), 'analytics' for readable + analytics datasets (isAnalytics=true), or 'all'/'\\**' for every readable dataset + including analytics datasets. If not provided, aggregates across all accessible + datasets, including analytics datasets. event_date_after: For measure=relationships: only count indicator→event links whose relationship was created/observed on or after this date (ISO 8601). Bounds the activity view diff --git a/src/cloudflare/resources/cloudforce_one/threat_events/indicators/by_dataset/by_dataset.py b/src/cloudflare/resources/cloudforce_one/threat_events/indicators/by_dataset/by_dataset.py index 87cb7bd6051..ff680bcce3f 100644 --- a/src/cloudflare/resources/cloudforce_one/threat_events/indicators/by_dataset/by_dataset.py +++ b/src/cloudflare/resources/cloudforce_one/threat_events/indicators/by_dataset/by_dataset.py @@ -76,10 +76,10 @@ def list( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> ByDatasetListResponse: - """This method is deprecated. + """Legacy. - Please use /events/indicators to retrieve a paginated - list of indicators. + Use `threat-intel indicators list` (`GET /events/indicators`) instead. + It supports multiple datasets and cursor pagination. Args: account_id: Account ID. @@ -142,7 +142,7 @@ def get( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> ByDatasetGetResponse: """ - Retrieves a specific indicator by its UUID. + Returns an indicator by its UUID. Args: account_id: Account ID. @@ -223,10 +223,10 @@ async def list( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> ByDatasetListResponse: - """This method is deprecated. + """Legacy. - Please use /events/indicators to retrieve a paginated - list of indicators. + Use `threat-intel indicators list` (`GET /events/indicators`) instead. + It supports multiple datasets and cursor pagination. Args: account_id: Account ID. @@ -289,7 +289,7 @@ async def get( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> ByDatasetGetResponse: """ - Retrieves a specific indicator by its UUID. + Returns an indicator by its UUID. Args: account_id: Account ID. diff --git a/src/cloudflare/resources/cloudforce_one/threat_events/indicators/by_dataset/tags.py b/src/cloudflare/resources/cloudforce_one/threat_events/indicators/by_dataset/tags.py index e43b623d152..b4600a4358c 100644 --- a/src/cloudflare/resources/cloudforce_one/threat_events/indicators/by_dataset/tags.py +++ b/src/cloudflare/resources/cloudforce_one/threat_events/indicators/by_dataset/tags.py @@ -52,10 +52,9 @@ def list( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> TagListResponse: - """Returns all mirrored tags from the indicator dataset (DO mirror table). + """Lists the tags applied to indicators in a dataset. - No - pagination. + Results are not paginated. Args: account_id: Account ID. @@ -119,10 +118,9 @@ async def list( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> TagListResponse: - """Returns all mirrored tags from the indicator dataset (DO mirror table). + """Lists the tags applied to indicators in a dataset. - No - pagination. + Results are not paginated. Args: account_id: Account ID. diff --git a/src/cloudflare/resources/cloudforce_one/threat_events/indicators/indicators.py b/src/cloudflare/resources/cloudforce_one/threat_events/indicators/indicators.py index 43e77a2eaf8..d147005326a 100644 --- a/src/cloudflare/resources/cloudforce_one/threat_events/indicators/indicators.py +++ b/src/cloudflare/resources/cloudforce_one/threat_events/indicators/indicators.py @@ -109,12 +109,12 @@ def list( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> IndicatorListResponse: - """ - Retrieves indicators across specified datasets, ordered by createdAt descending - then UUID, dataset ID, and shard ID ascending. Use the standalone datasetIds - value 'all'/'\\**' for legacy all-datasets behavior, 'analytics' for - isAnalytics=true datasets, or 'operational' for isAnalytics=false datasets. If - no datasetIds are provided, uses the default dataset. + """Lists indicators across datasets, newest first. + + `datasetIds` accepts dataset + UUIDs or one scope value used alone: `all` (or `*`) and `operational` select the + intelligence datasets you can read, and `analytics` selects the analytics + datasets you can read. Without `datasetIds`, the default dataset is used. Args: account_id: Account ID. @@ -138,10 +138,10 @@ def list( that has since been reconfigured as analytics-only yields a 400 `InvalidCursorError`. - dataset_ids: Dataset UUIDs to query, or one standalone scope value: 'all'/'\\**' for legacy - all-datasets behavior, 'analytics' for isAnalytics=true datasets, or - 'operational' for isAnalytics=false datasets. If not provided, uses the default - dataset. + dataset_ids: Dataset UUIDs to query, or one standalone scope value: 'all'/'\\**' or + 'operational' for readable intelligence datasets (isAnalytics=false), or + 'analytics' for readable analytics datasets (isAnalytics=true). If not provided, + uses the default dataset. format: Output format for indicator data. 'json' returns the default format, 'stix2' returns STIX 2.1 Indicator SDOs, 'taxii' returns a TAXII 2.1 Envelope with @@ -296,12 +296,12 @@ async def list( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> IndicatorListResponse: - """ - Retrieves indicators across specified datasets, ordered by createdAt descending - then UUID, dataset ID, and shard ID ascending. Use the standalone datasetIds - value 'all'/'\\**' for legacy all-datasets behavior, 'analytics' for - isAnalytics=true datasets, or 'operational' for isAnalytics=false datasets. If - no datasetIds are provided, uses the default dataset. + """Lists indicators across datasets, newest first. + + `datasetIds` accepts dataset + UUIDs or one scope value used alone: `all` (or `*`) and `operational` select the + intelligence datasets you can read, and `analytics` selects the analytics + datasets you can read. Without `datasetIds`, the default dataset is used. Args: account_id: Account ID. @@ -325,10 +325,10 @@ async def list( that has since been reconfigured as analytics-only yields a 400 `InvalidCursorError`. - dataset_ids: Dataset UUIDs to query, or one standalone scope value: 'all'/'\\**' for legacy - all-datasets behavior, 'analytics' for isAnalytics=true datasets, or - 'operational' for isAnalytics=false datasets. If not provided, uses the default - dataset. + dataset_ids: Dataset UUIDs to query, or one standalone scope value: 'all'/'\\**' or + 'operational' for readable intelligence datasets (isAnalytics=false), or + 'analytics' for readable analytics datasets (isAnalytics=true). If not provided, + uses the default dataset. format: Output format for indicator data. 'json' returns the default format, 'stix2' returns STIX 2.1 Indicator SDOs, 'taxii' returns a TAXII 2.1 Envelope with diff --git a/src/cloudflare/resources/cloudforce_one/threat_events/indicators/types.py b/src/cloudflare/resources/cloudforce_one/threat_events/indicators/types.py index 2561053740f..16df04a8789 100644 --- a/src/cloudflare/resources/cloudforce_one/threat_events/indicators/types.py +++ b/src/cloudflare/resources/cloudforce_one/threat_events/indicators/types.py @@ -54,14 +54,18 @@ def list( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> TypeListResponse: """ - Lists indicator types across multiple datasets + Lists the indicator types used in the datasets given by `datasetIds`, which + accepts dataset UUIDs or one scope value used alone. Without `datasetIds`, every + dataset you can read is included, analytics datasets too. Args: account_id: Account ID. - dataset_ids: Dataset UUIDs to query, or one standalone scope value: 'all'/'\\**', 'analytics' - for isAnalytics=true datasets, or 'operational' for isAnalytics=false datasets. - If not provided, queries all accessible datasets. + dataset_ids: Dataset UUIDs to query, or one standalone scope value: 'operational' for + readable intelligence datasets (isAnalytics=false), 'analytics' for readable + analytics datasets (isAnalytics=true), or 'all'/'\\**' for every readable dataset + including analytics datasets. If not provided, queries all accessible datasets, + including analytics datasets. extra_headers: Send extra headers @@ -119,14 +123,18 @@ async def list( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> TypeListResponse: """ - Lists indicator types across multiple datasets + Lists the indicator types used in the datasets given by `datasetIds`, which + accepts dataset UUIDs or one scope value used alone. Without `datasetIds`, every + dataset you can read is included, analytics datasets too. Args: account_id: Account ID. - dataset_ids: Dataset UUIDs to query, or one standalone scope value: 'all'/'\\**', 'analytics' - for isAnalytics=true datasets, or 'operational' for isAnalytics=false datasets. - If not provided, queries all accessible datasets. + dataset_ids: Dataset UUIDs to query, or one standalone scope value: 'operational' for + readable intelligence datasets (isAnalytics=false), 'analytics' for readable + analytics datasets (isAnalytics=true), or 'all'/'\\**' for every readable dataset + including analytics datasets. If not provided, queries all accessible datasets, + including analytics datasets. extra_headers: Send extra headers diff --git a/src/cloudflare/resources/cloudforce_one/threat_events/queries.py b/src/cloudflare/resources/cloudforce_one/threat_events/queries.py index 1a37c3a787e..5f6284e5205 100644 --- a/src/cloudflare/resources/cloudforce_one/threat_events/queries.py +++ b/src/cloudflare/resources/cloudforce_one/threat_events/queries.py @@ -48,11 +48,11 @@ def create( self, *, account_id: str, - alert_enabled: bool, - alert_rollup_enabled: bool, name: str, query_json: str, - rule_enabled: bool, + alert_enabled: bool | Omit = omit, + alert_rollup_enabled: bool | Omit = omit, + rule_enabled: bool | Omit = omit, rule_scope: str | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. @@ -61,23 +61,25 @@ def create( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> QueryCreateResponse: - """ - Create a new saved event query for the account + """Saves an event query under a unique `name`. + + `query_json` holds the query + parameters as a JSON string. Args: account_id: Account ID. - alert_enabled: Enable alerts for this query - - alert_rollup_enabled: Enable alert rollup for this query - name: Unique name for the saved query query_json: JSON string containing the query parameters - rule_enabled: Enable rule for this query + alert_enabled: Deprecated and ignored: saved-query alerting and rules were removed. - rule_scope: Scope for the rule + alert_rollup_enabled: Deprecated and ignored: saved-query alerting and rules were removed. + + rule_enabled: Deprecated and ignored: saved-query alerting and rules were removed. + + rule_scope: Deprecated and ignored: saved-query alerting and rules were removed. extra_headers: Send extra headers @@ -93,10 +95,10 @@ def create( path_template("/accounts/{account_id}/cloudforce-one/events/queries/create", account_id=account_id), body=maybe_transform( { - "alert_enabled": alert_enabled, - "alert_rollup_enabled": alert_rollup_enabled, "name": name, "query_json": query_json, + "alert_enabled": alert_enabled, + "alert_rollup_enabled": alert_rollup_enabled, "rule_enabled": rule_enabled, "rule_scope": rule_scope, }, @@ -120,7 +122,7 @@ def list( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> QueryListResponse: """ - Retrieve all saved event queries for the account + Lists the account's saved event queries. Args: account_id: Account ID. @@ -156,7 +158,7 @@ def delete( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> None: """ - Delete a saved event query by its ID + Deletes a saved event query by its ID. Args: account_id: Account ID. @@ -205,24 +207,24 @@ def edit( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> QueryEditResponse: """ - Update an existing saved event query by its ID + Updates the given fields of a saved event query. Args: account_id: Account ID. query_id: Event query ID - alert_enabled: Enable alerts for this query + alert_enabled: Deprecated and ignored: saved-query alerting and rules were removed. - alert_rollup_enabled: Enable alert rollup for this query + alert_rollup_enabled: Deprecated and ignored: saved-query alerting and rules were removed. name: Unique name for the saved query query_json: JSON string containing the query parameters - rule_enabled: Enable rule for this query + rule_enabled: Deprecated and ignored: saved-query alerting and rules were removed. - rule_scope: Scope for the rule + rule_scope: Deprecated and ignored: saved-query alerting and rules were removed. extra_headers: Send extra headers @@ -270,7 +272,7 @@ def get( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> QueryGetResponse: """ - Retrieve a saved event query by its ID + Returns a saved event query by its ID. Args: account_id: Account ID. @@ -324,11 +326,11 @@ async def create( self, *, account_id: str, - alert_enabled: bool, - alert_rollup_enabled: bool, name: str, query_json: str, - rule_enabled: bool, + alert_enabled: bool | Omit = omit, + alert_rollup_enabled: bool | Omit = omit, + rule_enabled: bool | Omit = omit, rule_scope: str | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. @@ -337,23 +339,25 @@ async def create( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> QueryCreateResponse: - """ - Create a new saved event query for the account + """Saves an event query under a unique `name`. + + `query_json` holds the query + parameters as a JSON string. Args: account_id: Account ID. - alert_enabled: Enable alerts for this query - - alert_rollup_enabled: Enable alert rollup for this query - name: Unique name for the saved query query_json: JSON string containing the query parameters - rule_enabled: Enable rule for this query + alert_enabled: Deprecated and ignored: saved-query alerting and rules were removed. - rule_scope: Scope for the rule + alert_rollup_enabled: Deprecated and ignored: saved-query alerting and rules were removed. + + rule_enabled: Deprecated and ignored: saved-query alerting and rules were removed. + + rule_scope: Deprecated and ignored: saved-query alerting and rules were removed. extra_headers: Send extra headers @@ -369,10 +373,10 @@ async def create( path_template("/accounts/{account_id}/cloudforce-one/events/queries/create", account_id=account_id), body=await async_maybe_transform( { - "alert_enabled": alert_enabled, - "alert_rollup_enabled": alert_rollup_enabled, "name": name, "query_json": query_json, + "alert_enabled": alert_enabled, + "alert_rollup_enabled": alert_rollup_enabled, "rule_enabled": rule_enabled, "rule_scope": rule_scope, }, @@ -396,7 +400,7 @@ async def list( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> QueryListResponse: """ - Retrieve all saved event queries for the account + Lists the account's saved event queries. Args: account_id: Account ID. @@ -432,7 +436,7 @@ async def delete( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> None: """ - Delete a saved event query by its ID + Deletes a saved event query by its ID. Args: account_id: Account ID. @@ -481,24 +485,24 @@ async def edit( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> QueryEditResponse: """ - Update an existing saved event query by its ID + Updates the given fields of a saved event query. Args: account_id: Account ID. query_id: Event query ID - alert_enabled: Enable alerts for this query + alert_enabled: Deprecated and ignored: saved-query alerting and rules were removed. - alert_rollup_enabled: Enable alert rollup for this query + alert_rollup_enabled: Deprecated and ignored: saved-query alerting and rules were removed. name: Unique name for the saved query query_json: JSON string containing the query parameters - rule_enabled: Enable rule for this query + rule_enabled: Deprecated and ignored: saved-query alerting and rules were removed. - rule_scope: Scope for the rule + rule_scope: Deprecated and ignored: saved-query alerting and rules were removed. extra_headers: Send extra headers @@ -546,7 +550,7 @@ async def get( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> QueryGetResponse: """ - Retrieve a saved event query by its ID + Returns a saved event query by its ID. Args: account_id: Account ID. diff --git a/src/cloudflare/resources/cloudforce_one/threat_events/raw.py b/src/cloudflare/resources/cloudforce_one/threat_events/raw.py index a0745946d4e..5e929975983 100644 --- a/src/cloudflare/resources/cloudforce_one/threat_events/raw.py +++ b/src/cloudflare/resources/cloudforce_one/threat_events/raw.py @@ -58,9 +58,10 @@ def edit( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> RawEditResponse: - """ - Partially updates raw threat event data in Cloudforce One, modifying specific - fields of the event. + """Legacy. + + Updates raw data stored under a `raw_id`, which new events don't use. + There is no direct replacement. Args: account_id: Account ID. @@ -117,8 +118,11 @@ def get( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> RawGetResponse: - """ - Retrieves raw threat event data for a specific event in Cloudforce One. + """Legacy. + + Returns raw data stored under a `raw_id`, which new events don't use. + Use `threat-intel events raw get` + (`GET /events/datasets/{dataset_id}/events/{event_id}/raw`) instead. Args: account_id: Account ID. @@ -191,9 +195,10 @@ async def edit( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> RawEditResponse: - """ - Partially updates raw threat event data in Cloudforce One, modifying specific - fields of the event. + """Legacy. + + Updates raw data stored under a `raw_id`, which new events don't use. + There is no direct replacement. Args: account_id: Account ID. @@ -250,8 +255,11 @@ async def get( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> RawGetResponse: - """ - Retrieves raw threat event data for a specific event in Cloudforce One. + """Legacy. + + Returns raw data stored under a `raw_id`, which new events don't use. + Use `threat-intel events raw get` + (`GET /events/datasets/{dataset_id}/events/{event_id}/raw`) instead. Args: account_id: Account ID. diff --git a/src/cloudflare/resources/cloudforce_one/threat_events/relate.py b/src/cloudflare/resources/cloudforce_one/threat_events/relate.py index 76b2990135b..c36713fb1ce 100644 --- a/src/cloudflare/resources/cloudforce_one/threat_events/relate.py +++ b/src/cloudflare/resources/cloudforce_one/threat_events/relate.py @@ -55,8 +55,11 @@ def delete( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> RelateDeleteResponse: - """ - Removes a reference link between related threat events in Cloudforce One. + """Legacy. + + Removes references created with + `threat-intel events legacy references create`. Use + `threat-intel events relationships` for new event links. Args: account_id: Account ID. @@ -124,8 +127,11 @@ async def delete( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> RelateDeleteResponse: - """ - Removes a reference link between related threat events in Cloudforce One. + """Legacy. + + Removes references created with + `threat-intel events legacy references create`. Use + `threat-intel events relationships` for new event links. Args: account_id: Account ID. diff --git a/src/cloudflare/resources/cloudforce_one/threat_events/relationships.py b/src/cloudflare/resources/cloudforce_one/threat_events/relationships.py index 7d4bb08ddf3..a08118384e4 100644 --- a/src/cloudflare/resources/cloudforce_one/threat_events/relationships.py +++ b/src/cloudflare/resources/cloudforce_one/threat_events/relationships.py @@ -66,9 +66,10 @@ def list( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> RelationshipListResponse: - """Deprecated; use GET /events/by-id/{event_id}/relationships. + """Legacy. - Available through + Use `threat-intel events relationships list` + (`GET /events/by-id/{event_id}/relationships`) instead. Available through 2026-11-28. Args: @@ -170,9 +171,10 @@ async def list( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> RelationshipListResponse: - """Deprecated; use GET /events/by-id/{event_id}/relationships. + """Legacy. - Available through + Use `threat-intel events relationships list` + (`GET /events/by-id/{event_id}/relationships`) instead. Available through 2026-11-28. Args: diff --git a/src/cloudflare/resources/cloudforce_one/threat_events/tags/categories.py b/src/cloudflare/resources/cloudforce_one/threat_events/tags/categories.py index 8152dbbe811..ad4231ac3d7 100644 --- a/src/cloudflare/resources/cloudforce_one/threat_events/tags/categories.py +++ b/src/cloudflare/resources/cloudforce_one/threat_events/tags/categories.py @@ -65,8 +65,10 @@ def create( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> CategoryCreateResponse: - """ - Creates a new Source-of-Truth tag category for an account. + """Creates a tag category. + + Use `schema` to define the custom fields its tags can + have. Args: account_id: Account ID. @@ -112,8 +114,9 @@ def list( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> CategoryListResponse: - """ - Returns all Source-of-Truth tag categories for an account. + """Lists the account's tag categories. + + Use `search` to filter them. Args: account_id: Account ID. @@ -153,9 +156,10 @@ def delete( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> CategoryDeleteResponse: - """Deprecated; use DELETE /events/tag-categories/{category_uuid}. + """Legacy. - Available through + Use `threat-intel tags categories delete` + (`DELETE /events/tag-categories/{category_uuid}`) instead. Available through 2026-11-28. Args: @@ -203,9 +207,10 @@ def edit( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> CategoryEditResponse: - """Deprecated; use PATCH /events/tag-categories/{category_uuid}. + """Legacy. - Available through + Use `threat-intel tags categories update` + (`PATCH /events/tag-categories/{category_uuid}`) instead. Available through 2026-11-28. Args: @@ -283,8 +288,10 @@ async def create( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> CategoryCreateResponse: - """ - Creates a new Source-of-Truth tag category for an account. + """Creates a tag category. + + Use `schema` to define the custom fields its tags can + have. Args: account_id: Account ID. @@ -330,8 +337,9 @@ async def list( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> CategoryListResponse: - """ - Returns all Source-of-Truth tag categories for an account. + """Lists the account's tag categories. + + Use `search` to filter them. Args: account_id: Account ID. @@ -371,9 +379,10 @@ async def delete( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> CategoryDeleteResponse: - """Deprecated; use DELETE /events/tag-categories/{category_uuid}. + """Legacy. - Available through + Use `threat-intel tags categories delete` + (`DELETE /events/tag-categories/{category_uuid}`) instead. Available through 2026-11-28. Args: @@ -421,9 +430,10 @@ async def edit( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> CategoryEditResponse: - """Deprecated; use PATCH /events/tag-categories/{category_uuid}. + """Legacy. - Available through + Use `threat-intel tags categories update` + (`PATCH /events/tag-categories/{category_uuid}`) instead. Available through 2026-11-28. Args: diff --git a/src/cloudflare/resources/cloudforce_one/threat_events/tags/indicators/indicators.py b/src/cloudflare/resources/cloudforce_one/threat_events/tags/indicators/indicators.py index 0aa51c57223..b881c06a87e 100644 --- a/src/cloudflare/resources/cloudforce_one/threat_events/tags/indicators/indicators.py +++ b/src/cloudflare/resources/cloudforce_one/threat_events/tags/indicators/indicators.py @@ -73,13 +73,12 @@ def list( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> IndicatorListResponse: - """Returns indicators associated with the provided tag UUID, with pagination. + """Lists the indicators that carry a tag, with pagination. - By - default fans out across every indicator dataset the account can read; pass - datasetIds to scope to UUIDs, analytics datasets, or operational datasets. - Analytics datasets do not expose tag associations, so the analytics scope - returns an empty result. + By default, every + intelligence dataset you can read is searched; use `datasetIds` to limit the + search to specific datasets or a scope value. Analytics datasets don't store tag + associations, so the `analytics` scope returns no results. Args: account_id: Account ID. @@ -87,10 +86,10 @@ def list( tag_uuid: Tag UUID. dataset_ids: Dataset UUIDs to scope to (repeat the param for multiple), or one standalone - scope: 'all'/'\\**', 'analytics' for isAnalytics=true datasets, or 'operational' - for isAnalytics=false datasets. Analytics datasets do not expose tag - associations, so 'analytics' returns an empty result. Omit to search all - readable datasets. + scope value: 'all'/'\\**' or 'operational' for readable intelligence datasets + (isAnalytics=false), or 'analytics' for readable analytics datasets + (isAnalytics=true). Analytics datasets do not expose tag associations, so + 'analytics' returns an empty result. Omit for 'all'. related_event: Filter indicators by related event UUID(s). Multiple UUIDs can be provided by repeating the parameter. @@ -180,13 +179,12 @@ async def list( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> IndicatorListResponse: - """Returns indicators associated with the provided tag UUID, with pagination. + """Lists the indicators that carry a tag, with pagination. - By - default fans out across every indicator dataset the account can read; pass - datasetIds to scope to UUIDs, analytics datasets, or operational datasets. - Analytics datasets do not expose tag associations, so the analytics scope - returns an empty result. + By default, every + intelligence dataset you can read is searched; use `datasetIds` to limit the + search to specific datasets or a scope value. Analytics datasets don't store tag + associations, so the `analytics` scope returns no results. Args: account_id: Account ID. @@ -194,10 +192,10 @@ async def list( tag_uuid: Tag UUID. dataset_ids: Dataset UUIDs to scope to (repeat the param for multiple), or one standalone - scope: 'all'/'\\**', 'analytics' for isAnalytics=true datasets, or 'operational' - for isAnalytics=false datasets. Analytics datasets do not expose tag - associations, so 'analytics' returns an empty result. Omit to search all - readable datasets. + scope value: 'all'/'\\**' or 'operational' for readable intelligence datasets + (isAnalytics=false), or 'analytics' for readable analytics datasets + (isAnalytics=true). Analytics datasets do not expose tag associations, so + 'analytics' returns an empty result. Omit for 'all'. related_event: Filter indicators by related event UUID(s). Multiple UUIDs can be provided by repeating the parameter. diff --git a/src/cloudflare/resources/cloudforce_one/threat_events/tags/tags.py b/src/cloudflare/resources/cloudforce_one/threat_events/tags/tags.py index 6845b4e339e..b0a2ecb97f5 100644 --- a/src/cloudflare/resources/cloudforce_one/threat_events/tags/tags.py +++ b/src/cloudflare/resources/cloudforce_one/threat_events/tags/tags.py @@ -106,8 +106,7 @@ def create( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> TagCreateResponse: """ - Creates an account-owned tag for threat events and returns its complete owner - projection. + Creates a tag in the account and returns the complete tag. Args: account_id: Account ID. @@ -200,15 +199,13 @@ def list( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> TagListResponse: - """Returns all Source-of-Truth tags for an account. + """Lists the account's tags. - Supports legacy free-text - `search` on tag value and `categoryUuid` exact match, plus a structured - `filters` JSON array for filtering by metadata fields (originCountryISO, - actorCategory, motive, priority, etc.). The authenticated account owns these - account-scoped tags and receives their complete owner projection. Country values - may be passed as alpha-2, alpha-3, name, or common alias. Purple TLP remains - CFONE-only. + Use `search` to match tag values, `categoryUuid` to + limit results to one category, and `filters` (a JSON array) to filter by fields + such as `originCountryISO`, `actorCategory`, `motive`, or `priority`. Country + filters accept alpha-2 or alpha-3 codes, names, or common aliases. Tags marked + TLP:PURPLE are visible only to Cloudforce One. Args: account_id: Account ID. @@ -288,7 +285,7 @@ def delete( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> TagDeleteResponse: """ - Deletes a Source-of-Truth tag by UUID. + Deletes a tag by its UUID. Args: account_id: Account ID. @@ -353,8 +350,7 @@ def edit( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> TagEditResponse: """ - Updates an account-owned Source-of-Truth tag by UUID and returns its complete - owner projection. + Updates the given fields of a tag and returns the complete tag. Args: account_id: Account ID. @@ -501,8 +497,7 @@ async def create( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> TagCreateResponse: """ - Creates an account-owned tag for threat events and returns its complete owner - projection. + Creates a tag in the account and returns the complete tag. Args: account_id: Account ID. @@ -595,15 +590,13 @@ async def list( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> TagListResponse: - """Returns all Source-of-Truth tags for an account. + """Lists the account's tags. - Supports legacy free-text - `search` on tag value and `categoryUuid` exact match, plus a structured - `filters` JSON array for filtering by metadata fields (originCountryISO, - actorCategory, motive, priority, etc.). The authenticated account owns these - account-scoped tags and receives their complete owner projection. Country values - may be passed as alpha-2, alpha-3, name, or common alias. Purple TLP remains - CFONE-only. + Use `search` to match tag values, `categoryUuid` to + limit results to one category, and `filters` (a JSON array) to filter by fields + such as `originCountryISO`, `actorCategory`, `motive`, or `priority`. Country + filters accept alpha-2 or alpha-3 codes, names, or common aliases. Tags marked + TLP:PURPLE are visible only to Cloudforce One. Args: account_id: Account ID. @@ -683,7 +676,7 @@ async def delete( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> TagDeleteResponse: """ - Deletes a Source-of-Truth tag by UUID. + Deletes a tag by its UUID. Args: account_id: Account ID. @@ -748,8 +741,7 @@ async def edit( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> TagEditResponse: """ - Updates an account-owned Source-of-Truth tag by UUID and returns its complete - owner projection. + Updates the given fields of a tag and returns the complete tag. Args: account_id: Account ID. diff --git a/src/cloudflare/resources/cloudforce_one/threat_events/target_industries/by_dataset.py b/src/cloudflare/resources/cloudforce_one/threat_events/target_industries/by_dataset.py index dcc27905d2f..0f09751afa1 100644 --- a/src/cloudflare/resources/cloudforce_one/threat_events/target_industries/by_dataset.py +++ b/src/cloudflare/resources/cloudforce_one/threat_events/target_industries/by_dataset.py @@ -52,8 +52,10 @@ def list( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> ByDatasetListResponse: - """ - Lists all target industries for a specific dataset + """Legacy. + + Use `threat-intel events target-industries list` + (`GET /events/targetIndustries`) instead. Args: account_id: Account ID. @@ -117,8 +119,10 @@ async def list( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> ByDatasetListResponse: - """ - Lists all target industries for a specific dataset + """Legacy. + + Use `threat-intel events target-industries list` + (`GET /events/targetIndustries`) instead. Args: account_id: Account ID. diff --git a/src/cloudflare/resources/cloudforce_one/threat_events/target_industries/catalog.py b/src/cloudflare/resources/cloudforce_one/threat_events/target_industries/catalog.py index 57fa505fd5f..3016b3e5561 100644 --- a/src/cloudflare/resources/cloudforce_one/threat_events/target_industries/catalog.py +++ b/src/cloudflare/resources/cloudforce_one/threat_events/target_industries/catalog.py @@ -51,8 +51,11 @@ def list( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> CatalogListResponse: - """ - Lists all target industries from industry map catalog + """Lists every predefined target industry, whether or not an event uses it. + + To list + only the industries used in specific datasets, use + `threat-intel events target-industries list`. Args: account_id: Account ID. @@ -109,8 +112,11 @@ async def list( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> CatalogListResponse: - """ - Lists all target industries from industry map catalog + """Lists every predefined target industry, whether or not an event uses it. + + To list + only the industries used in specific datasets, use + `threat-intel events target-industries list`. Args: account_id: Account ID. diff --git a/src/cloudflare/resources/cloudforce_one/threat_events/target_industries/target_industries.py b/src/cloudflare/resources/cloudforce_one/threat_events/target_industries/target_industries.py index 8f3029c5b23..a69af194891 100644 --- a/src/cloudflare/resources/cloudforce_one/threat_events/target_industries/target_industries.py +++ b/src/cloudflare/resources/cloudforce_one/threat_events/target_industries/target_industries.py @@ -78,8 +78,9 @@ def list( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> TargetIndustryListResponse: """ - Retrieves the catalog of industry classifications used in Cloudforce One threat - intelligence. + Lists the target industries referenced by events in the datasets given by + `datasetIds`, or in the default dataset when `datasetIds` is omitted. To list + every target industry, use `threat-intel events target-industries catalog list`. Args: account_id: Account ID. @@ -153,8 +154,9 @@ async def list( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> TargetIndustryListResponse: """ - Retrieves the catalog of industry classifications used in Cloudforce One threat - intelligence. + Lists the target industries referenced by events in the datasets given by + `datasetIds`, or in the default dataset when `datasetIds` is omitted. To list + every target industry, use `threat-intel events target-industries catalog list`. Args: account_id: Account ID. diff --git a/src/cloudflare/resources/cloudforce_one/threat_events/threat_events.py b/src/cloudflare/resources/cloudforce_one/threat_events/threat_events.py index ee9aca5d3a3..de1d8db079b 100644 --- a/src/cloudflare/resources/cloudforce_one/threat_events/threat_events.py +++ b/src/cloudflare/resources/cloudforce_one/threat_events/threat_events.py @@ -267,11 +267,11 @@ def create( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> ThreatEventCreateResponse: - """ - To create a dataset, see the - [`Create Dataset`](https://developers.cloudflare.com/api/resources/cloudforce_one/subresources/threat_events/subresources/datasets/methods/create/) - endpoint. When `datasetId` parameter is unspecified, it will be created in a - default dataset named `Cloudforce One Threat Events`. + """Creates an event. + + Without `datasetId`, the event is created in the default + Cloudforce One Threat Events dataset. To create a dataset, use + `threat-intel datasets create`. Args: path_account_id: Account ID. @@ -336,6 +336,7 @@ def list( page: float | Omit = omit, page_size: float | Omit = omit, search: Iterable[threat_event_list_params.Search] | Omit = omit, + search_branches: Iterable[Iterable[threat_event_list_params.SearchBranch]] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -343,15 +344,14 @@ def list( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> ThreatEventListResponse: - """ - Use `datasetId=all` or `datasetId=*` for the legacy all-datasets scope, - `datasetId=analytics` for datasets with `isAnalytics=true`, or - `datasetId=operational` for datasets with `isAnalytics=false` (limited to 50). - Scope values must be used alone. When `datasetId` is unspecified, events are - listed from the default Cloudforce One Threat Events dataset. To list existing - datasets, use the - [`List Datasets`](https://developers.cloudflare.com/api/resources/cloudforce_one/subresources/threat_events/subresources/datasets/methods/list/) - endpoint. + """Lists events, with filters passed as query parameters. + + `datasetId` accepts + dataset UUIDs or one scope value used alone: `all` (or `*`) and `operational` + select the intelligence datasets you can read, and `analytics` selects the + analytics datasets you can read. A scope value covers at most 50 datasets. + Without `datasetId`, the default Cloudforce One Threat Events dataset is used. + To send filters in a JSON body instead, use `threat-intel events search`. Args: account_id: Account ID. @@ -364,16 +364,23 @@ def list( result_info.cursor field. Use cursor-based pagination for deep pagination (beyond 100,000 records) or for optimal performance. - dataset_id: Dataset UUIDs to query, or one standalone scope value: 'all'/'\\**' for the legacy - all-datasets behavior, 'analytics' for isAnalytics=true datasets, or - 'operational' for isAnalytics=false datasets. If not provided, uses the default - dataset. + dataset_id: Dataset UUIDs to query, or one standalone scope value: 'all'/'\\**' or + 'operational' for readable intelligence datasets (isAnalytics=false), or + 'analytics' for readable analytics datasets (isAnalytics=true). Scope values + query at most 50 datasets. If not provided, uses the default dataset. page: Page number (1-indexed) for offset-based pagination. Limited to offset of 100,000 records. For deep pagination, use cursor-based pagination instead. page_size: Number of results per page. Maximum 25,000. + search_branches: JSON-encoded. OR branches of structured search filters. Filters within a branch + are AND'd, branches are OR'd, and the result is AND'd with `search`: + `AND(search) AND OR(AND(branch 1), ...)`. Max 8 branches of 1-10 conditions + each. Not supported for analytics datasets, and `indicator` filters are not yet + supported inside branches. Cursor pages carry the original branches, so do not + resend them with `cursor`. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -403,6 +410,7 @@ def list( "page": page, "page_size": page_size, "search": search, + "search_branches": search_branches, }, threat_event_list_params.ThreatEventListParams, ), @@ -424,12 +432,11 @@ def bulk_create( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> ThreatEventBulkCreateResponse: - """The `datasetId` parameter must be defined. + """Creates multiple events in one dataset. - To list existing datasets (and their - IDs) in your account, use the - [`List Datasets`](https://developers.cloudflare.com/api/resources/cloudforce_one/subresources/threat_events/subresources/datasets/methods/list/) - endpoint. + `datasetId` is required; to find dataset + IDs, use `threat-intel datasets list`. Set `includeCreatedEvents` to return the + UUIDs of the created events. Args: account_id: Account ID. @@ -477,9 +484,11 @@ def bulk_create_relationships( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> ThreatEventBulkCreateRelationshipsResponse: - """This method is deprecated. + """Legacy. - Please use `event_create_bulk` instead + Use `threat-intel events bulk-create` (`POST /events/create/bulk`) and + `threat-intel events relationships create` (`POST /events/relationships/create`) + instead. Args: account_id: Account ID. @@ -538,8 +547,8 @@ def edit( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> ThreatEventEditResponse: """ - Partially updates a threat event in Cloudforce One, modifying specific fields - without replacing the entire event. + Updates the given fields of an event and leaves the other fields unchanged. + `datasetId` is required. Args: account_id: Account ID. @@ -604,10 +613,10 @@ def get( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> ThreatEventGetResponse: - """This Method is deprecated. + """Legacy. - Please use - /events/dataset/:dataset_id/events/:event_id instead. + Use `threat-intel events get` + (`GET /events/dataset/{dataset_id}/events/{event_id}`) instead. Args: account_id: Account ID. @@ -745,11 +754,11 @@ async def create( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> ThreatEventCreateResponse: - """ - To create a dataset, see the - [`Create Dataset`](https://developers.cloudflare.com/api/resources/cloudforce_one/subresources/threat_events/subresources/datasets/methods/create/) - endpoint. When `datasetId` parameter is unspecified, it will be created in a - default dataset named `Cloudforce One Threat Events`. + """Creates an event. + + Without `datasetId`, the event is created in the default + Cloudforce One Threat Events dataset. To create a dataset, use + `threat-intel datasets create`. Args: path_account_id: Account ID. @@ -814,6 +823,7 @@ async def list( page: float | Omit = omit, page_size: float | Omit = omit, search: Iterable[threat_event_list_params.Search] | Omit = omit, + search_branches: Iterable[Iterable[threat_event_list_params.SearchBranch]] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -821,15 +831,14 @@ async def list( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> ThreatEventListResponse: - """ - Use `datasetId=all` or `datasetId=*` for the legacy all-datasets scope, - `datasetId=analytics` for datasets with `isAnalytics=true`, or - `datasetId=operational` for datasets with `isAnalytics=false` (limited to 50). - Scope values must be used alone. When `datasetId` is unspecified, events are - listed from the default Cloudforce One Threat Events dataset. To list existing - datasets, use the - [`List Datasets`](https://developers.cloudflare.com/api/resources/cloudforce_one/subresources/threat_events/subresources/datasets/methods/list/) - endpoint. + """Lists events, with filters passed as query parameters. + + `datasetId` accepts + dataset UUIDs or one scope value used alone: `all` (or `*`) and `operational` + select the intelligence datasets you can read, and `analytics` selects the + analytics datasets you can read. A scope value covers at most 50 datasets. + Without `datasetId`, the default Cloudforce One Threat Events dataset is used. + To send filters in a JSON body instead, use `threat-intel events search`. Args: account_id: Account ID. @@ -842,16 +851,23 @@ async def list( result_info.cursor field. Use cursor-based pagination for deep pagination (beyond 100,000 records) or for optimal performance. - dataset_id: Dataset UUIDs to query, or one standalone scope value: 'all'/'\\**' for the legacy - all-datasets behavior, 'analytics' for isAnalytics=true datasets, or - 'operational' for isAnalytics=false datasets. If not provided, uses the default - dataset. + dataset_id: Dataset UUIDs to query, or one standalone scope value: 'all'/'\\**' or + 'operational' for readable intelligence datasets (isAnalytics=false), or + 'analytics' for readable analytics datasets (isAnalytics=true). Scope values + query at most 50 datasets. If not provided, uses the default dataset. page: Page number (1-indexed) for offset-based pagination. Limited to offset of 100,000 records. For deep pagination, use cursor-based pagination instead. page_size: Number of results per page. Maximum 25,000. + search_branches: JSON-encoded. OR branches of structured search filters. Filters within a branch + are AND'd, branches are OR'd, and the result is AND'd with `search`: + `AND(search) AND OR(AND(branch 1), ...)`. Max 8 branches of 1-10 conditions + each. Not supported for analytics datasets, and `indicator` filters are not yet + supported inside branches. Cursor pages carry the original branches, so do not + resend them with `cursor`. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -881,6 +897,7 @@ async def list( "page": page, "page_size": page_size, "search": search, + "search_branches": search_branches, }, threat_event_list_params.ThreatEventListParams, ), @@ -902,12 +919,11 @@ async def bulk_create( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> ThreatEventBulkCreateResponse: - """The `datasetId` parameter must be defined. + """Creates multiple events in one dataset. - To list existing datasets (and their - IDs) in your account, use the - [`List Datasets`](https://developers.cloudflare.com/api/resources/cloudforce_one/subresources/threat_events/subresources/datasets/methods/list/) - endpoint. + `datasetId` is required; to find dataset + IDs, use `threat-intel datasets list`. Set `includeCreatedEvents` to return the + UUIDs of the created events. Args: account_id: Account ID. @@ -955,9 +971,11 @@ async def bulk_create_relationships( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> ThreatEventBulkCreateRelationshipsResponse: - """This method is deprecated. + """Legacy. - Please use `event_create_bulk` instead + Use `threat-intel events bulk-create` (`POST /events/create/bulk`) and + `threat-intel events relationships create` (`POST /events/relationships/create`) + instead. Args: account_id: Account ID. @@ -1016,8 +1034,8 @@ async def edit( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> ThreatEventEditResponse: """ - Partially updates a threat event in Cloudforce One, modifying specific fields - without replacing the entire event. + Updates the given fields of an event and leaves the other fields unchanged. + `datasetId` is required. Args: account_id: Account ID. @@ -1082,10 +1100,10 @@ async def get( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> ThreatEventGetResponse: - """This Method is deprecated. + """Legacy. - Please use - /events/dataset/:dataset_id/events/:event_id instead. + Use `threat-intel events get` + (`GET /events/dataset/{dataset_id}/events/{event_id}`) instead. Args: account_id: Account ID. diff --git a/src/cloudflare/resources/cloudforce_one/threat_signals/articles/articles.py b/src/cloudflare/resources/cloudforce_one/threat_signals/articles/articles.py index 3c5f456ac03..4b02eb4d05c 100644 --- a/src/cloudflare/resources/cloudforce_one/threat_signals/articles/articles.py +++ b/src/cloudflare/resources/cloudforce_one/threat_signals/articles/articles.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing import Type, Union, cast +from typing import List, Type, Union, cast from datetime import datetime from typing_extensions import Literal @@ -96,11 +96,14 @@ def list( fetched_after: Union[str, datetime] | Omit = omit, fetched_before: Union[str, datetime] | Omit = omit, include_total: bool | Omit = omit, + min_relevance: Literal["low", "medium", "high"] | Omit = omit, per_page: int | Omit = omit, + pir_id: str | Omit = omit, published_after: Union[str, datetime] | Omit = omit, published_before: Union[str, datetime] | Omit = omit, read: bool | Omit = omit, search: str | Omit = omit, + severity: List[Literal["informational", "low", "medium", "high", "critical"]] | Omit = omit, sort: str | Omit = omit, source_type: Literal["curated", "custom"] | Omit = omit, tag: str | Omit = omit, @@ -128,6 +131,53 @@ def list( `per_page`, `sort`, `include_total`, or any article filter alongside it returns a 400 `CursorFilterConflictError`. + feed_category: Exact feed-category filter after trimming. Omit to include every category. + + feed_id: Feed UUID filter. Omit to include articles from every account feed. + + fetched_after: Include articles fetched at or after this ISO 8601 date-time with Z or a numeric + UTC offset; normalized to UTC. + + fetched_before: Include articles fetched at or before this ISO 8601 date-time with Z or a + numeric UTC offset; normalized to UTC. + + include_total: When true on the first page, count matching articles and return an exact total. + Defaults to false; cursor pages do not recalculate totals. + + min_relevance: Beta. Return only articles at or above this relevance band for pir_id, or for + any active PIR when pir_id is omitted. Excludes articles that have not been + scored. + + per_page: Number of articles per cursor page, from 1 to 100. Defaults to 20. + + pir_id: Beta. Active Priority Intelligence Requirement to report, filter, and sort + relevance by. Omit to use each article's most relevant active PIR. Returns a 400 + error unless the PIR is active. + + published_after: Include articles published at or after this ISO 8601 date-time with Z or a + numeric UTC offset; normalized to UTC. + + published_before: Include articles published at or before this ISO 8601 date-time with Z or a + numeric UTC offset; normalized to UTC. + + read: Filter by read state. Accepts true, false, 1, or 0; omit to include read and + unread articles. + + search: NFC-normalized, trimmed literal substring filter on article titles; ASCII + case-insensitive, from 1 to 500 characters. + + severity: Beta. Repeatable intrinsic severity band filter. An article matches any selected + band, the band reported as its severity. Excludes articles without a severity. + Like the severity field, severity is reported only while the account has an + active Priority Intelligence Requirement; otherwise no articles match. + + sort: Sort by fetched_at, published_at, title, or relevance (beta). Prefix the field + with - for descending order; defaults to -fetched_at. -relevance lists the most + relevant articles first, by pir_id or by each article's most relevant active + PIR, with unscored articles last. + + source_type: Filter by curated or custom feed source. Omit to include both source types. + tag: Legacy human-readable tag-value filter. Ignored when tag_id is supplied; prefer tag_id. @@ -168,11 +218,14 @@ def list( "fetched_after": fetched_after, "fetched_before": fetched_before, "include_total": include_total, + "min_relevance": min_relevance, "per_page": per_page, + "pir_id": pir_id, "published_after": published_after, "published_before": published_before, "read": read, "search": search, + "severity": severity, "sort": sort, "source_type": source_type, "tag": tag, @@ -205,6 +258,10 @@ def bulk_edit( Marks up to 50 Threat Signals articles as read or unread. Args: + article_ids: Array of article UUIDs to mark (1-50). + + read: True to mark read, false to mark unread. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -251,6 +308,10 @@ def edit( Marks a Threat Signals article as read or unread. Args: + article_id: Threat Signals article UUID + + read: True to mark the article read, false to mark unread. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -293,9 +354,12 @@ def get( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> ArticleGetResponse: """ - Retrieves a Threat Signals article with its summary, tags and indicator status. + Retrieves a Threat Signals article with its summary, tags, indicator status and + relevance to the account's Priority Intelligence Requirements. Args: + article_id: Threat Signals article UUID + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -368,11 +432,14 @@ async def list( fetched_after: Union[str, datetime] | Omit = omit, fetched_before: Union[str, datetime] | Omit = omit, include_total: bool | Omit = omit, + min_relevance: Literal["low", "medium", "high"] | Omit = omit, per_page: int | Omit = omit, + pir_id: str | Omit = omit, published_after: Union[str, datetime] | Omit = omit, published_before: Union[str, datetime] | Omit = omit, read: bool | Omit = omit, search: str | Omit = omit, + severity: List[Literal["informational", "low", "medium", "high", "critical"]] | Omit = omit, sort: str | Omit = omit, source_type: Literal["curated", "custom"] | Omit = omit, tag: str | Omit = omit, @@ -400,6 +467,53 @@ async def list( `per_page`, `sort`, `include_total`, or any article filter alongside it returns a 400 `CursorFilterConflictError`. + feed_category: Exact feed-category filter after trimming. Omit to include every category. + + feed_id: Feed UUID filter. Omit to include articles from every account feed. + + fetched_after: Include articles fetched at or after this ISO 8601 date-time with Z or a numeric + UTC offset; normalized to UTC. + + fetched_before: Include articles fetched at or before this ISO 8601 date-time with Z or a + numeric UTC offset; normalized to UTC. + + include_total: When true on the first page, count matching articles and return an exact total. + Defaults to false; cursor pages do not recalculate totals. + + min_relevance: Beta. Return only articles at or above this relevance band for pir_id, or for + any active PIR when pir_id is omitted. Excludes articles that have not been + scored. + + per_page: Number of articles per cursor page, from 1 to 100. Defaults to 20. + + pir_id: Beta. Active Priority Intelligence Requirement to report, filter, and sort + relevance by. Omit to use each article's most relevant active PIR. Returns a 400 + error unless the PIR is active. + + published_after: Include articles published at or after this ISO 8601 date-time with Z or a + numeric UTC offset; normalized to UTC. + + published_before: Include articles published at or before this ISO 8601 date-time with Z or a + numeric UTC offset; normalized to UTC. + + read: Filter by read state. Accepts true, false, 1, or 0; omit to include read and + unread articles. + + search: NFC-normalized, trimmed literal substring filter on article titles; ASCII + case-insensitive, from 1 to 500 characters. + + severity: Beta. Repeatable intrinsic severity band filter. An article matches any selected + band, the band reported as its severity. Excludes articles without a severity. + Like the severity field, severity is reported only while the account has an + active Priority Intelligence Requirement; otherwise no articles match. + + sort: Sort by fetched_at, published_at, title, or relevance (beta). Prefix the field + with - for descending order; defaults to -fetched_at. -relevance lists the most + relevant articles first, by pir_id or by each article's most relevant active + PIR, with unscored articles last. + + source_type: Filter by curated or custom feed source. Omit to include both source types. + tag: Legacy human-readable tag-value filter. Ignored when tag_id is supplied; prefer tag_id. @@ -440,11 +554,14 @@ async def list( "fetched_after": fetched_after, "fetched_before": fetched_before, "include_total": include_total, + "min_relevance": min_relevance, "per_page": per_page, + "pir_id": pir_id, "published_after": published_after, "published_before": published_before, "read": read, "search": search, + "severity": severity, "sort": sort, "source_type": source_type, "tag": tag, @@ -477,6 +594,10 @@ async def bulk_edit( Marks up to 50 Threat Signals articles as read or unread. Args: + article_ids: Array of article UUIDs to mark (1-50). + + read: True to mark read, false to mark unread. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -523,6 +644,10 @@ async def edit( Marks a Threat Signals article as read or unread. Args: + article_id: Threat Signals article UUID + + read: True to mark the article read, false to mark unread. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -565,9 +690,12 @@ async def get( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> ArticleGetResponse: """ - Retrieves a Threat Signals article with its summary, tags and indicator status. + Retrieves a Threat Signals article with its summary, tags, indicator status and + relevance to the account's Priority Intelligence Requirements. Args: + article_id: Threat Signals article UUID + extra_headers: Send extra headers extra_query: Add additional query parameters to the request diff --git a/src/cloudflare/resources/cloudforce_one/threat_signals/articles/content.py b/src/cloudflare/resources/cloudforce_one/threat_signals/articles/content.py index f9dca101166..5926c1af01f 100644 --- a/src/cloudflare/resources/cloudforce_one/threat_signals/articles/content.py +++ b/src/cloudflare/resources/cloudforce_one/threat_signals/articles/content.py @@ -55,10 +55,19 @@ def get( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> str: - """ - Retrieves the stored body of a Threat Signals article as plain text or HTML. + """Retrieves the stored content of a Threat Signals article, unchanged. + + Depending + on how the article was captured from its source, the content is HTML, Markdown, + or plain text. The format parameter sets only the response Content-Type; it does + not convert the content. Args: + article_id: Threat Signals article UUID + + format: Response Content-Type: text (the default) for text/plain or html for text/html. + Neither value converts the content. html is deprecated; use text. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -122,10 +131,19 @@ async def get( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> str: - """ - Retrieves the stored body of a Threat Signals article as plain text or HTML. + """Retrieves the stored content of a Threat Signals article, unchanged. + + Depending + on how the article was captured from its source, the content is HTML, Markdown, + or plain text. The format parameter sets only the response Content-Type; it does + not convert the content. Args: + article_id: Threat Signals article UUID + + format: Response Content-Type: text (the default) for text/plain or html for text/html. + Neither value converts the content. html is deprecated; use text. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request diff --git a/src/cloudflare/resources/cloudforce_one/threat_signals/articles/skill_outputs.py b/src/cloudflare/resources/cloudforce_one/threat_signals/articles/skill_outputs.py index f57b837fe8f..fad25a9c2d1 100644 --- a/src/cloudflare/resources/cloudforce_one/threat_signals/articles/skill_outputs.py +++ b/src/cloudflare/resources/cloudforce_one/threat_signals/articles/skill_outputs.py @@ -56,10 +56,19 @@ def get( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> SkillOutputGetResponse: - """ - Retrieves the stored output of a skill for a Threat Signals article. + """Retrieves the stored output of a skill for a Threat Signals article. + + The + custom_output field is parsed JSON when the stored output is valid JSON, + otherwise the raw string. Args: + article_id: Threat Signals article UUID + + skill_id: + Custom Skill UUID or a Managed Default Skill ID (IOC-context: + default-ioc-context-skill) + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -125,10 +134,19 @@ async def get( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> SkillOutputGetResponse: - """ - Retrieves the stored output of a skill for a Threat Signals article. + """Retrieves the stored output of a skill for a Threat Signals article. + + The + custom_output field is parsed JSON when the stored output is valid JSON, + otherwise the raw string. Args: + article_id: Threat Signals article UUID + + skill_id: + Custom Skill UUID or a Managed Default Skill ID (IOC-context: + default-ioc-context-skill) + extra_headers: Send extra headers extra_query: Add additional query parameters to the request diff --git a/src/cloudflare/resources/cloudforce_one/threat_signals/articles/tags.py b/src/cloudflare/resources/cloudforce_one/threat_signals/articles/tags.py index c1037f043a7..c7565a8ebe4 100644 --- a/src/cloudflare/resources/cloudforce_one/threat_signals/articles/tags.py +++ b/src/cloudflare/resources/cloudforce_one/threat_signals/articles/tags.py @@ -63,6 +63,10 @@ def create( Applies a tag from the account's tag catalog to a Threat Signals article. Args: + article_id: Threat Signals article UUID + + tag_id: UUID of a tag from the account's catalog to apply to the article. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -109,6 +113,10 @@ def delete( Removes a tag from a Threat Signals article. Args: + article_id: Threat Signals article UUID + + tag_id: UUID of a tag from the account's catalog + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -157,6 +165,8 @@ def generate( tags. Args: + article_id: Threat Signals article UUID + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -223,6 +233,10 @@ async def create( Applies a tag from the account's tag catalog to a Threat Signals article. Args: + article_id: Threat Signals article UUID + + tag_id: UUID of a tag from the account's catalog to apply to the article. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -269,6 +283,10 @@ async def delete( Removes a tag from a Threat Signals article. Args: + article_id: Threat Signals article UUID + + tag_id: UUID of a tag from the account's catalog + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -317,6 +335,8 @@ async def generate( tags. Args: + article_id: Threat Signals article UUID + extra_headers: Send extra headers extra_query: Add additional query parameters to the request diff --git a/src/cloudflare/resources/cloudforce_one/threat_signals/feeds/feeds.py b/src/cloudflare/resources/cloudforce_one/threat_signals/feeds/feeds.py index 12dda6b1dff..0ca54584797 100644 --- a/src/cloudflare/resources/cloudforce_one/threat_signals/feeds/feeds.py +++ b/src/cloudflare/resources/cloudforce_one/threat_signals/feeds/feeds.py @@ -109,13 +109,35 @@ def create( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> FeedCreateResponse: - """ - Subscribes the account to a custom or curated Threat Signals feed. + """Subscribes the account to a custom or curated Threat Signals feed. + + Adding a + custom feed when the account is at its custom-feed limit returns 403 with + `errors[0].reason` `threat_signals_feed_limit`, and + `errors[0].custom_feed_limit` and `errors[0].custom_feed_count` give the limit + and current count. Curated feeds are not subject to this limit. Args: category_id: One of the predefined Threat Signals feed categories; see GET /:account_id/v2/threat-signals/categories. + curated_feed_id: UUID of a curated feed to subscribe to. Provide exactly one of url or + curated_feed_id. The account must have feed creation entitlement and not exceed + feed allowance. + + display_name: Override the feed's display name. Null clears it; omit to keep existing or + derived value. + + enabled: Whether to actively poll the feed. Default true. + + poll_interval_s: Polling interval in seconds (60-86400). Default 300s (5 minutes). + + title: Override the feed's title. Null clears it; omit to keep existing or derived + value. + + url: HTTPS RSS feed URL. Provide exactly one of url or curated_feed_id. The account + must have feed creation entitlement and not exceed feed allowance. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -173,6 +195,26 @@ def list( Lists the account's Threat Signals feed subscriptions. Args: + category: Exact feed-category filter, up to 100 characters. Omit to include all + categories. + + enabled: Filter by enabled state. Accepts true, false, 1, or 0; omit to include enabled + and disabled feeds. + + limit: Optional 1–100 alias for per_page. When provided, limit takes precedence. + + page: 1-based page number. Minimum 1; defaults to 1. + + per_page: Number of feeds per page, from 1 to 100. Defaults to 20. + + sort: Sort by created_at, title, category, or url. Prefix the field with - for + descending order; defaults to -created_at. + + source_type: Filter by curated or custom feed source. Omit to include both source types. + + status: Exact stored polling-status filter, such as active or error. Omit to include + every status. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -224,6 +266,8 @@ def delete( Unsubscribes the account from a Threat Signals feed and deletes its articles. Args: + feed_id: UUID of the Threat Signals feed + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -285,9 +329,21 @@ def edit( Updates a Threat Signals feed subscription. Args: + feed_id: UUID of the Threat Signals feed + category_id: One of the predefined Threat Signals feed categories; see GET /:account_id/v2/threat-signals/categories. + display_name: Override the feed's display name. Null clears it; omit to keep existing or + derived value. + + enabled: Whether to actively poll the feed. Omit to keep current value. + + poll_interval_s: New polling interval in seconds (60-86400). Omit to keep current value. + + title: Override the feed's title. Null clears it; omit to keep existing or derived + value. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -342,6 +398,9 @@ def poll( Starts an immediate poll of one or all Threat Signals feeds. Args: + feed_id: UUID of a specific feed to poll, or "all" to poll all feeds. Omit or pass "all" + for all feeds. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -424,13 +483,35 @@ async def create( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> FeedCreateResponse: - """ - Subscribes the account to a custom or curated Threat Signals feed. + """Subscribes the account to a custom or curated Threat Signals feed. + + Adding a + custom feed when the account is at its custom-feed limit returns 403 with + `errors[0].reason` `threat_signals_feed_limit`, and + `errors[0].custom_feed_limit` and `errors[0].custom_feed_count` give the limit + and current count. Curated feeds are not subject to this limit. Args: category_id: One of the predefined Threat Signals feed categories; see GET /:account_id/v2/threat-signals/categories. + curated_feed_id: UUID of a curated feed to subscribe to. Provide exactly one of url or + curated_feed_id. The account must have feed creation entitlement and not exceed + feed allowance. + + display_name: Override the feed's display name. Null clears it; omit to keep existing or + derived value. + + enabled: Whether to actively poll the feed. Default true. + + poll_interval_s: Polling interval in seconds (60-86400). Default 300s (5 minutes). + + title: Override the feed's title. Null clears it; omit to keep existing or derived + value. + + url: HTTPS RSS feed URL. Provide exactly one of url or curated_feed_id. The account + must have feed creation entitlement and not exceed feed allowance. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -488,6 +569,26 @@ def list( Lists the account's Threat Signals feed subscriptions. Args: + category: Exact feed-category filter, up to 100 characters. Omit to include all + categories. + + enabled: Filter by enabled state. Accepts true, false, 1, or 0; omit to include enabled + and disabled feeds. + + limit: Optional 1–100 alias for per_page. When provided, limit takes precedence. + + page: 1-based page number. Minimum 1; defaults to 1. + + per_page: Number of feeds per page, from 1 to 100. Defaults to 20. + + sort: Sort by created_at, title, category, or url. Prefix the field with - for + descending order; defaults to -created_at. + + source_type: Filter by curated or custom feed source. Omit to include both source types. + + status: Exact stored polling-status filter, such as active or error. Omit to include + every status. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -539,6 +640,8 @@ async def delete( Unsubscribes the account from a Threat Signals feed and deletes its articles. Args: + feed_id: UUID of the Threat Signals feed + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -600,9 +703,21 @@ async def edit( Updates a Threat Signals feed subscription. Args: + feed_id: UUID of the Threat Signals feed + category_id: One of the predefined Threat Signals feed categories; see GET /:account_id/v2/threat-signals/categories. + display_name: Override the feed's display name. Null clears it; omit to keep existing or + derived value. + + enabled: Whether to actively poll the feed. Omit to keep current value. + + poll_interval_s: New polling interval in seconds (60-86400). Omit to keep current value. + + title: Override the feed's title. Null clears it; omit to keep existing or derived + value. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -657,6 +772,9 @@ async def poll( Starts an immediate poll of one or all Threat Signals feeds. Args: + feed_id: UUID of a specific feed to poll, or "all" to poll all feeds. Omit or pass "all" + for all feeds. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request diff --git a/src/cloudflare/resources/cloudforce_one/threat_signals/feeds/raw.py b/src/cloudflare/resources/cloudforce_one/threat_signals/feeds/raw.py index 1b432b30b8c..c1b9008280d 100644 --- a/src/cloudflare/resources/cloudforce_one/threat_signals/feeds/raw.py +++ b/src/cloudflare/resources/cloudforce_one/threat_signals/feeds/raw.py @@ -56,9 +56,15 @@ def get( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> str: """ - Retrieves the feed document fetched by the most recent poll. + Retrieves the feed document fetched by the most recent poll as text/plain by + default or application/xml when format is xml. Args: + feed_id: UUID of the Threat Signals feed + + format: Response format. Use xml for application/xml; omit it for the default text/plain + response. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -123,9 +129,15 @@ async def get( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> str: """ - Retrieves the feed document fetched by the most recent poll. + Retrieves the feed document fetched by the most recent poll as text/plain by + default or application/xml when format is xml. Args: + feed_id: UUID of the Threat Signals feed + + format: Response format. Use xml for application/xml; omit it for the default text/plain + response. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request diff --git a/src/cloudflare/resources/cloudforce_one/threat_signals/feeds/skills.py b/src/cloudflare/resources/cloudforce_one/threat_signals/feeds/skills.py index 1568a3ab762..203cb221b44 100644 --- a/src/cloudflare/resources/cloudforce_one/threat_signals/feeds/skills.py +++ b/src/cloudflare/resources/cloudforce_one/threat_signals/feeds/skills.py @@ -58,10 +58,18 @@ def update( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> SkillUpdateResponse: - """ - Replaces the ordered custom skills assigned to a Threat Signals feed. + """Replaces the ordered custom skills assigned to a Threat Signals feed. + + Requires a + paid Threat Signals subscription. Args: + feed_id: UUID of the Threat Signals feed + + skill_ids: Ordered array of Custom Skill UUIDs (max 20). Replaces the feed's custom skill + assignments. Free accounts cannot assign custom skills. Managed default skills + are unaffected. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -104,9 +112,13 @@ def get( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> SkillGetResponse: """ - Retrieves the effective skill pipeline for a Threat Signals feed. + Retrieves active non-IOC-context Managed Default Skills followed by active + Custom Skills assigned to the feed, with each entry's source. Free Threat + Signals accounts receive only those Managed Default Skills. Args: + feed_id: UUID of the Threat Signals feed + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -169,10 +181,18 @@ async def update( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> SkillUpdateResponse: - """ - Replaces the ordered custom skills assigned to a Threat Signals feed. + """Replaces the ordered custom skills assigned to a Threat Signals feed. + + Requires a + paid Threat Signals subscription. Args: + feed_id: UUID of the Threat Signals feed + + skill_ids: Ordered array of Custom Skill UUIDs (max 20). Replaces the feed's custom skill + assignments. Free accounts cannot assign custom skills. Managed default skills + are unaffected. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -215,9 +235,13 @@ async def get( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> SkillGetResponse: """ - Retrieves the effective skill pipeline for a Threat Signals feed. + Retrieves active non-IOC-context Managed Default Skills followed by active + Custom Skills assigned to the feed, with each entry's source. Free Threat + Signals accounts receive only those Managed Default Skills. Args: + feed_id: UUID of the Threat Signals feed + extra_headers: Send extra headers extra_query: Add additional query parameters to the request diff --git a/src/cloudflare/resources/cloudforce_one/threat_signals/indicators.py b/src/cloudflare/resources/cloudforce_one/threat_signals/indicators.py index b34b7774967..88e71384032 100644 --- a/src/cloudflare/resources/cloudforce_one/threat_signals/indicators.py +++ b/src/cloudflare/resources/cloudforce_one/threat_signals/indicators.py @@ -67,11 +67,27 @@ def list( articles. Args: + article_id: Article UUID filter. Omit to include indicators from every article. + + cursor: Opaque cursor from the previous response's `pagination.cursor`. When provided, + page size, ordering, and filters come from the cursor. Sending `per_page`, + `sort`, `include_total`, `feed_id`, `article_id`, or `search` alongside it + returns a 400 `CursorFilterConflictError`. + + feed_id: Feed UUID filter. Omit to include indicators from every account feed. + + include_total: When true on the first page, count matching indicators and return an exact + total. Defaults to false; cursor pages do not recalculate totals. + + per_page: Number of indicators per cursor page, from 1 to 100. Defaults to 20. + search: NFC-normalized and trimmed, case-insensitive literal substring search of indicator values. Requires 3–500 Unicode code points; the upper code-point bound is described here because OpenAPI string length cannot precisely express it without imposing UTF-16 semantics. + sort: Sort by id. Use id for ascending or -id for descending order; defaults to id. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -150,11 +166,27 @@ async def list( articles. Args: + article_id: Article UUID filter. Omit to include indicators from every article. + + cursor: Opaque cursor from the previous response's `pagination.cursor`. When provided, + page size, ordering, and filters come from the cursor. Sending `per_page`, + `sort`, `include_total`, `feed_id`, `article_id`, or `search` alongside it + returns a 400 `CursorFilterConflictError`. + + feed_id: Feed UUID filter. Omit to include indicators from every account feed. + + include_total: When true on the first page, count matching indicators and return an exact + total. Defaults to false; cursor pages do not recalculate totals. + + per_page: Number of indicators per cursor page, from 1 to 100. Defaults to 20. + search: NFC-normalized and trimmed, case-insensitive literal substring search of indicator values. Requires 3–500 Unicode code points; the upper code-point bound is described here because OpenAPI string length cannot precisely express it without imposing UTF-16 semantics. + sort: Sort by id. Use id for ascending or -id for descending order; defaults to id. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request diff --git a/src/cloudflare/resources/cloudforce_one/threat_signals/search.py b/src/cloudflare/resources/cloudforce_one/threat_signals/search.py index cfdea21d4c3..4ba1b57547d 100644 --- a/src/cloudflare/resources/cloudforce_one/threat_signals/search.py +++ b/src/cloudflare/resources/cloudforce_one/threat_signals/search.py @@ -64,6 +64,14 @@ def search( retrieval. Args: + query: Keyword and semantic article-search text, from 1 to 1000 characters. + + feed_id: Optional feed UUID that restricts results to articles from that feed. + + max_results: Maximum search matches to request, an integer from 1 to 50. Defaults to 20 when + omitted or empty; multiple matches from one article can produce fewer returned + articles. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -134,6 +142,14 @@ async def search( retrieval. Args: + query: Keyword and semantic article-search text, from 1 to 1000 characters. + + feed_id: Optional feed UUID that restricts results to articles from that feed. + + max_results: Maximum search matches to request, an integer from 1 to 50. Defaults to 20 when + omitted or empty; multiple matches from one article can produce fewer returned + articles. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request diff --git a/src/cloudflare/resources/cloudforce_one/threat_signals/skills/skills.py b/src/cloudflare/resources/cloudforce_one/threat_signals/skills/skills.py index 05f23c1c392..24f6a386ca6 100644 --- a/src/cloudflare/resources/cloudforce_one/threat_signals/skills/skills.py +++ b/src/cloudflare/resources/cloudforce_one/threat_signals/skills/skills.py @@ -69,7 +69,7 @@ def create( name: str, output_schema: str, prompt: str, - type: Literal["summary", "tags"], + type: Literal["summary", "tags"] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -77,10 +77,20 @@ def create( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> SkillCreateResponse: - """ - Creates a custom AI skill for the account. + """Creates a Custom Skill for the account. + + Free Threat Signals accounts cannot + create Custom Skills. Args: + name: Custom Skill name (1–100 characters). + + output_schema: JSON Schema serialized as a string (max 4096 characters). + + prompt: AI prompt (1–4000 characters) defining the skill's instructions. + + type: Optional label; does not affect execution. Defaults to "summary". + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -125,10 +135,16 @@ def list( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> SyncV4PagePagination[SkillListResponse]: - """ - Lists the default and custom skills available to the account. + """Lists active Managed Default Skills and Custom Skills. + + Free Threat Signals + accounts see active managed defaults only, with custom_skills_available: false. Args: + page: Page number (≥ 1, default 1). + + per_page: Results per page (1–100, default 20). + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -170,11 +186,15 @@ def delete( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> SkillDeleteResponse: - """Deletes a custom skill. + """Deletes a Custom Skill. - Default skills cannot be deleted. + The skill's stored outputs on articles are deleted with + it. Managed Default Skills cannot be deleted. Free Threat Signals accounts + cannot delete Custom Skills. Args: + skill_id: Custom Skill UUID or a Managed Default Skill ID + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -220,11 +240,24 @@ def edit( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> SkillEditResponse: - """Updates a custom skill. + """Updates a Custom Skill. - Default skills are read-only. + Managed Default Skills cannot be updated. Free Threat + Signals accounts cannot update Custom Skills. Args: + skill_id: Custom Skill UUID or a Managed Default Skill ID + + config: Optional skill configuration (stored but not currently interpreted). + + is_active: Whether the skill is active and eligible for feed assignment. + + name: Custom Skill name (1–100 characters). + + output_schema: JSON Schema serialized as a string (max 4096 characters). + + prompt: AI prompt (1–4000 characters) defining the skill's instructions. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -275,10 +308,14 @@ def get( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> SkillGetResponse: - """ - Retrieves a default or custom skill by ID. + """Retrieves a Managed Default Skill or Custom Skill. + + Managed catalog definitions + are readable. Free Threat Signals accounts cannot read Custom Skills. Args: + skill_id: Custom Skill UUID or a Managed Default Skill ID + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -339,7 +376,7 @@ async def create( name: str, output_schema: str, prompt: str, - type: Literal["summary", "tags"], + type: Literal["summary", "tags"] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -347,10 +384,20 @@ async def create( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> SkillCreateResponse: - """ - Creates a custom AI skill for the account. + """Creates a Custom Skill for the account. + + Free Threat Signals accounts cannot + create Custom Skills. Args: + name: Custom Skill name (1–100 characters). + + output_schema: JSON Schema serialized as a string (max 4096 characters). + + prompt: AI prompt (1–4000 characters) defining the skill's instructions. + + type: Optional label; does not affect execution. Defaults to "summary". + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -395,10 +442,16 @@ def list( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> AsyncPaginator[SkillListResponse, AsyncV4PagePagination[SkillListResponse]]: - """ - Lists the default and custom skills available to the account. + """Lists active Managed Default Skills and Custom Skills. + + Free Threat Signals + accounts see active managed defaults only, with custom_skills_available: false. Args: + page: Page number (≥ 1, default 1). + + per_page: Results per page (1–100, default 20). + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -440,11 +493,15 @@ async def delete( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> SkillDeleteResponse: - """Deletes a custom skill. + """Deletes a Custom Skill. - Default skills cannot be deleted. + The skill's stored outputs on articles are deleted with + it. Managed Default Skills cannot be deleted. Free Threat Signals accounts + cannot delete Custom Skills. Args: + skill_id: Custom Skill UUID or a Managed Default Skill ID + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -490,11 +547,24 @@ async def edit( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> SkillEditResponse: - """Updates a custom skill. + """Updates a Custom Skill. - Default skills are read-only. + Managed Default Skills cannot be updated. Free Threat + Signals accounts cannot update Custom Skills. Args: + skill_id: Custom Skill UUID or a Managed Default Skill ID + + config: Optional skill configuration (stored but not currently interpreted). + + is_active: Whether the skill is active and eligible for feed assignment. + + name: Custom Skill name (1–100 characters). + + output_schema: JSON Schema serialized as a string (max 4096 characters). + + prompt: AI prompt (1–4000 characters) defining the skill's instructions. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -545,10 +615,14 @@ async def get( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> SkillGetResponse: - """ - Retrieves a default or custom skill by ID. + """Retrieves a Managed Default Skill or Custom Skill. + + Managed catalog definitions + are readable. Free Threat Signals accounts cannot read Custom Skills. Args: + skill_id: Custom Skill UUID or a Managed Default Skill ID + extra_headers: Send extra headers extra_query: Add additional query parameters to the request diff --git a/src/cloudflare/resources/cloudforce_one/threat_signals/skills/tag_categories.py b/src/cloudflare/resources/cloudforce_one/threat_signals/skills/tag_categories.py index a5d8181f891..c1b667bd161 100644 --- a/src/cloudflare/resources/cloudforce_one/threat_signals/skills/tag_categories.py +++ b/src/cloudflare/resources/cloudforce_one/threat_signals/skills/tag_categories.py @@ -60,9 +60,15 @@ def update( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> TagCategoryUpdateResponse: """ - Replaces the tag categories the default tagging skill may choose tags from. + Replaces the Tag Categories the managed default tagging skill may select tags + from. This configures the managed default tagging skill, not Custom Skills. Args: + skill_id: Must be default-tagging-skill; configures the managed default tagging skill + + category_uuids: Up to 100 unique tag category UUIDs that the managed default tagging skill may + select tags from. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -107,9 +113,12 @@ def get( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> TagCategoryGetResponse: """ - Retrieves the tag categories the default tagging skill may choose tags from. + Retrieves the Tag Categories the managed default tagging skill may select tags + from. This configures the managed default tagging skill, not Custom Skills. Args: + skill_id: Must be default-tagging-skill; configures the managed default tagging skill + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -173,9 +182,15 @@ async def update( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> TagCategoryUpdateResponse: """ - Replaces the tag categories the default tagging skill may choose tags from. + Replaces the Tag Categories the managed default tagging skill may select tags + from. This configures the managed default tagging skill, not Custom Skills. Args: + skill_id: Must be default-tagging-skill; configures the managed default tagging skill + + category_uuids: Up to 100 unique tag category UUIDs that the managed default tagging skill may + select tags from. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -220,9 +235,12 @@ async def get( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> TagCategoryGetResponse: """ - Retrieves the tag categories the default tagging skill may choose tags from. + Retrieves the Tag Categories the managed default tagging skill may select tags + from. This configures the managed default tagging skill, not Custom Skills. Args: + skill_id: Must be default-tagging-skill; configures the managed default tagging skill + extra_headers: Send extra headers extra_query: Add additional query parameters to the request diff --git a/src/cloudflare/resources/connectivity/directory/services.py b/src/cloudflare/resources/connectivity/directory/services.py index 237046d6a2e..506e11e6a4f 100644 --- a/src/cloudflare/resources/connectivity/directory/services.py +++ b/src/cloudflare/resources/connectivity/directory/services.py @@ -75,8 +75,6 @@ def create( tls_settings: TLS settings for a connectivity service. - If omitted, the default mode (`verify_full`) is used. - extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -113,8 +111,6 @@ def create( tls_settings: TLS settings for a connectivity service. - If omitted, the default mode (`verify_full`) is used. - extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -204,8 +200,6 @@ def update( Args: tls_settings: TLS settings for a connectivity service. - If omitted, the default mode (`verify_full`) is used. - extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -241,8 +235,6 @@ def update( Args: tls_settings: TLS settings for a connectivity service. - If omitted, the default mode (`verify_full`) is used. - extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -507,8 +499,6 @@ async def create( tls_settings: TLS settings for a connectivity service. - If omitted, the default mode (`verify_full`) is used. - extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -545,8 +535,6 @@ async def create( tls_settings: TLS settings for a connectivity service. - If omitted, the default mode (`verify_full`) is used. - extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -636,8 +624,6 @@ async def update( Args: tls_settings: TLS settings for a connectivity service. - If omitted, the default mode (`verify_full`) is used. - extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -673,8 +659,6 @@ async def update( Args: tls_settings: TLS settings for a connectivity service. - If omitted, the default mode (`verify_full`) is used. - extra_headers: Send extra headers extra_query: Add additional query parameters to the request diff --git a/src/cloudflare/resources/containers/applications/applications.py b/src/cloudflare/resources/containers/applications/applications.py index f43028c48bf..0266507d3f1 100644 --- a/src/cloudflare/resources/containers/applications/applications.py +++ b/src/cloudflare/resources/containers/applications/applications.py @@ -165,6 +165,8 @@ def create( scheduling_policy: Literal["durable_object"], configuration: application_create_params.CcContainersCreateDurableObjectApplicationRequestConfiguration | Omit = omit, + constraints: application_create_params.CcContainersCreateDurableObjectApplicationRequestConstraints + | Omit = omit, observability: application_create_params.CcContainersCreateDurableObjectApplicationRequestObservability | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -201,6 +203,10 @@ def create( configuration: Configuration for a Durable Object-managed application. + constraints: The jurisdiction of a Durable Object-managed application's primary control-plane + object. Set this when creating the application; it cannot be changed afterwards. + Other placement constraints are not supported by this scheduling policy. + observability: Application-wide logging settings for a Durable Object-managed application. The application publishes these settings to its runtime metadata. Updating them does not create a deployment or rollout. @@ -230,7 +236,9 @@ def create( max_instances: int | Omit = omit, name: str, scheduling_policy: Literal["default"] | Literal["durable_object"], - constraints: application_create_params.CcContainersCreateScheduledApplicationRequestConstraints | Omit = omit, + constraints: application_create_params.CcContainersCreateScheduledApplicationRequestConstraints + | application_create_params.CcContainersCreateDurableObjectApplicationRequestConstraints + | Omit = omit, durable_objects: application_create_params.CcContainersCreateScheduledApplicationRequestDurableObjects | application_create_params.CcContainersCreateDurableObjectApplicationRequestDurableObjects | Omit = omit, @@ -630,6 +638,8 @@ async def create( scheduling_policy: Literal["durable_object"], configuration: application_create_params.CcContainersCreateDurableObjectApplicationRequestConfiguration | Omit = omit, + constraints: application_create_params.CcContainersCreateDurableObjectApplicationRequestConstraints + | Omit = omit, observability: application_create_params.CcContainersCreateDurableObjectApplicationRequestObservability | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -666,6 +676,10 @@ async def create( configuration: Configuration for a Durable Object-managed application. + constraints: The jurisdiction of a Durable Object-managed application's primary control-plane + object. Set this when creating the application; it cannot be changed afterwards. + Other placement constraints are not supported by this scheduling policy. + observability: Application-wide logging settings for a Durable Object-managed application. The application publishes these settings to its runtime metadata. Updating them does not create a deployment or rollout. @@ -695,7 +709,9 @@ async def create( max_instances: int | Omit = omit, name: str, scheduling_policy: Literal["default"] | Literal["durable_object"], - constraints: application_create_params.CcContainersCreateScheduledApplicationRequestConstraints | Omit = omit, + constraints: application_create_params.CcContainersCreateScheduledApplicationRequestConstraints + | application_create_params.CcContainersCreateDurableObjectApplicationRequestConstraints + | Omit = omit, durable_objects: application_create_params.CcContainersCreateScheduledApplicationRequestDurableObjects | application_create_params.CcContainersCreateDurableObjectApplicationRequestDurableObjects | Omit = omit, diff --git a/src/cloudflare/resources/csam_scanner/csam_scanner.py b/src/cloudflare/resources/csam_scanner/csam_scanner.py index 29fc7213da6..aa0b0a0974a 100644 --- a/src/cloudflare/resources/csam_scanner/csam_scanner.py +++ b/src/cloudflare/resources/csam_scanner/csam_scanner.py @@ -65,6 +65,10 @@ def edit( CSAM scanning, updating the notification email, and configuring scanning sources. + This is a partial update: fields omitted from `value` keep their current + setting, and `sources` is merged per source (`null` clears all sources). Send an + empty `email` to clear the notification address. + When a new email is provided, email verification is triggered automatically. The `enabled` field is a toggle; the server may adjust it based on whether the notification email is verified. @@ -188,6 +192,10 @@ async def edit( CSAM scanning, updating the notification email, and configuring scanning sources. + This is a partial update: fields omitted from `value` keep their current + setting, and `sources` is merged per source (`null` clears all sources). Send an + empty `email` to clear the notification address. + When a new email is provided, email verification is triggered automatically. The `enabled` field is a toggle; the server may adjust it based on whether the notification email is verified. diff --git a/src/cloudflare/resources/d1/api.md b/src/cloudflare/resources/d1/api.md index 460ca20787d..81f50d6fc89 100644 --- a/src/cloudflare/resources/d1/api.md +++ b/src/cloudflare/resources/d1/api.md @@ -32,6 +32,7 @@ Methods: - client.d1.database.import\_(database_id, \*, account_id, \*\*params) -> DatabaseImportResponse - client.d1.database.query(database_id, \*, account_id, \*\*params) -> SyncSinglePage[QueryResult] - client.d1.database.raw(database_id, \*, account_id, \*\*params) -> SyncSinglePage[DatabaseRawResponse] +- client.d1.database.undelete(database_id, \*, account_id, \*\*params) -> D1 ### TimeTravel diff --git a/src/cloudflare/resources/d1/database/database.py b/src/cloudflare/resources/d1/database/database.py index ccf850c16e1..6cef972997f 100644 --- a/src/cloudflare/resources/d1/database/database.py +++ b/src/cloudflare/resources/d1/database/database.py @@ -20,6 +20,7 @@ database_export_params, database_import_params, database_update_params, + database_undelete_params, ) from .time_travel import ( TimeTravelResource, @@ -862,6 +863,68 @@ def raw( method="post", ) + def undelete( + self, + database_id: str, + *, + account_id: str, + new_name: str | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> D1: + """Restore a deleted D1 database. + + The database is restored with the name it had + when it was deleted, unless `new_name` is provided. The restored database counts + against the account's limits. Undeleting a database that is not deleted succeeds + without changes, unless `new_name` differs from its current name which errors. A + database can only be undeleted within 7 days (7 \\** 24 hours) of its deletion. + + Once a database is undeleted, Time Travel (point-in-time recovery) cannot + restore it to a bookmark or timestamp at or before the undeletion. Only states + after the undeletion can be restored. + + Args: + account_id: Account identifier tag. + + database_id: D1 database identifier (UUID). + + new_name: Restore the database with this name instead of the name it had when it was + deleted. Required if another database in the account already uses that name. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not database_id: + raise ValueError(f"Expected a non-empty value for `database_id` but received {database_id!r}") + return self._post( + path_template( + "/accounts/{account_id}/d1/database/{database_id}/undelete", + account_id=account_id, + database_id=database_id, + ), + body=maybe_transform({"new_name": new_name}, database_undelete_params.DatabaseUndeleteParams), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[D1]._unwrapper, + ), + cast_to=cast(Type[D1], ResultWrapper[D1]), + ) + class AsyncDatabaseResource(AsyncAPIResource): @cached_property @@ -1680,6 +1743,68 @@ def raw( method="post", ) + async def undelete( + self, + database_id: str, + *, + account_id: str, + new_name: str | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> D1: + """Restore a deleted D1 database. + + The database is restored with the name it had + when it was deleted, unless `new_name` is provided. The restored database counts + against the account's limits. Undeleting a database that is not deleted succeeds + without changes, unless `new_name` differs from its current name which errors. A + database can only be undeleted within 7 days (7 \\** 24 hours) of its deletion. + + Once a database is undeleted, Time Travel (point-in-time recovery) cannot + restore it to a bookmark or timestamp at or before the undeletion. Only states + after the undeletion can be restored. + + Args: + account_id: Account identifier tag. + + database_id: D1 database identifier (UUID). + + new_name: Restore the database with this name instead of the name it had when it was + deleted. Required if another database in the account already uses that name. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not database_id: + raise ValueError(f"Expected a non-empty value for `database_id` but received {database_id!r}") + return await self._post( + path_template( + "/accounts/{account_id}/d1/database/{database_id}/undelete", + account_id=account_id, + database_id=database_id, + ), + body=await async_maybe_transform({"new_name": new_name}, database_undelete_params.DatabaseUndeleteParams), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[D1]._unwrapper, + ), + cast_to=cast(Type[D1], ResultWrapper[D1]), + ) + class DatabaseResourceWithRawResponse: def __init__(self, database: DatabaseResource) -> None: @@ -1715,6 +1840,9 @@ def __init__(self, database: DatabaseResource) -> None: self.raw = to_raw_response_wrapper( database.raw, ) + self.undelete = to_raw_response_wrapper( + database.undelete, + ) @cached_property def time_travel(self) -> TimeTravelResourceWithRawResponse: @@ -1755,6 +1883,12 @@ def __init__(self, database: AsyncDatabaseResource) -> None: self.raw = async_to_raw_response_wrapper( database.raw, # pyright: ignore[reportArgumentType] ) + self.undelete = async_to_raw_response_wrapper( + database.undelete, + ) + self.undelete = async_to_raw_response_wrapper( + database.undelete, + ) @cached_property def time_travel(self) -> AsyncTimeTravelResourceWithRawResponse: @@ -1795,6 +1929,9 @@ def __init__(self, database: DatabaseResource) -> None: self.raw = to_streamed_response_wrapper( database.raw, ) + self.undelete = to_streamed_response_wrapper( + database.undelete, + ) @cached_property def time_travel(self) -> TimeTravelResourceWithStreamingResponse: @@ -1835,6 +1972,12 @@ def __init__(self, database: AsyncDatabaseResource) -> None: self.raw = async_to_streamed_response_wrapper( database.raw, # pyright: ignore[reportArgumentType] ) + self.undelete = async_to_streamed_response_wrapper( + database.undelete, + ) + self.undelete = async_to_streamed_response_wrapper( + database.undelete, + ) @cached_property def time_travel(self) -> AsyncTimeTravelResourceWithStreamingResponse: diff --git a/src/cloudflare/resources/diagnostics/api.md b/src/cloudflare/resources/diagnostics/api.md index f3058910ae9..20f84f88fa2 100644 --- a/src/cloudflare/resources/diagnostics/api.md +++ b/src/cloudflare/resources/diagnostics/api.md @@ -31,6 +31,6 @@ Methods: - client.diagnostics.endpoint_healthchecks.create(\*, account_id, \*\*params) -> Optional[EndpointHealthcheckCreateResponse] - client.diagnostics.endpoint_healthchecks.update(id, \*, account_id, \*\*params) -> Optional[EndpointHealthcheckUpdateResponse] -- client.diagnostics.endpoint_healthchecks.list(\*, account_id) -> Optional[EndpointHealthcheckListResponse] +- client.diagnostics.endpoint_healthchecks.list(\*, account_id) -> SyncSinglePage[EndpointHealthcheckListResponse] - client.diagnostics.endpoint_healthchecks.delete(id, \*, account_id) -> EndpointHealthcheckDeleteResponse - client.diagnostics.endpoint_healthchecks.get(id, \*, account_id) -> Optional[EndpointHealthcheckGetResponse] diff --git a/src/cloudflare/resources/diagnostics/endpoint_healthchecks.py b/src/cloudflare/resources/diagnostics/endpoint_healthchecks.py index b64ac76beed..06ea0b7f5a8 100644 --- a/src/cloudflare/resources/diagnostics/endpoint_healthchecks.py +++ b/src/cloudflare/resources/diagnostics/endpoint_healthchecks.py @@ -18,7 +18,8 @@ async_to_streamed_response_wrapper, ) from ..._wrappers import ResultWrapper -from ..._base_client import make_request_options +from ...pagination import SyncSinglePage, AsyncSinglePage +from ..._base_client import AsyncPaginator, make_request_options from ...types.diagnostics import endpoint_healthcheck_create_params, endpoint_healthcheck_update_params from ...types.diagnostics.endpoint_healthcheck_get_response import EndpointHealthcheckGetResponse from ...types.diagnostics.endpoint_healthcheck_list_response import EndpointHealthcheckListResponse @@ -123,7 +124,7 @@ def update( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Optional[EndpointHealthcheckUpdateResponse]: """ - Update a Endpoint Health Check. + Update an Endpoint Health Check. Args: account_id: Identifier @@ -182,7 +183,7 @@ def list( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> Optional[EndpointHealthcheckListResponse]: + ) -> SyncSinglePage[EndpointHealthcheckListResponse]: """ List Endpoint Health Checks. @@ -199,18 +200,13 @@ def list( """ if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - return self._get( + return self._get_api_list( path_template("/accounts/{account_id}/diagnostics/endpoint-healthchecks", account_id=account_id), + page=SyncSinglePage[EndpointHealthcheckListResponse], options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - post_parser=ResultWrapper[Optional[EndpointHealthcheckListResponse]]._unwrapper, - ), - cast_to=cast( - Type[Optional[EndpointHealthcheckListResponse]], ResultWrapper[EndpointHealthcheckListResponse] + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), + model=EndpointHealthcheckListResponse, ) def delete( @@ -396,7 +392,7 @@ async def update( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Optional[EndpointHealthcheckUpdateResponse]: """ - Update a Endpoint Health Check. + Update an Endpoint Health Check. Args: account_id: Identifier @@ -445,7 +441,7 @@ async def update( ), ) - async def list( + def list( self, *, account_id: str, @@ -455,7 +451,7 @@ async def list( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> Optional[EndpointHealthcheckListResponse]: + ) -> AsyncPaginator[EndpointHealthcheckListResponse, AsyncSinglePage[EndpointHealthcheckListResponse]]: """ List Endpoint Health Checks. @@ -472,18 +468,13 @@ async def list( """ if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - return await self._get( + return self._get_api_list( path_template("/accounts/{account_id}/diagnostics/endpoint-healthchecks", account_id=account_id), + page=AsyncSinglePage[EndpointHealthcheckListResponse], options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - post_parser=ResultWrapper[Optional[EndpointHealthcheckListResponse]]._unwrapper, - ), - cast_to=cast( - Type[Optional[EndpointHealthcheckListResponse]], ResultWrapper[EndpointHealthcheckListResponse] + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), + model=EndpointHealthcheckListResponse, ) async def delete( diff --git a/src/cloudflare/resources/dls/regional_services/prefix_bindings.py b/src/cloudflare/resources/dls/regional_services/prefix_bindings.py index 3f00f07fab0..411c77fa771 100644 --- a/src/cloudflare/resources/dls/regional_services/prefix_bindings.py +++ b/src/cloudflare/resources/dls/regional_services/prefix_bindings.py @@ -68,7 +68,10 @@ def create( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> PrefixBindingCreateResponse: """ - Create a DLS prefix binding + Bind a CIDR from a BYOIP prefix to a region. + + This requires the **IP Prefixes Write** permission in addition to **DLS Write**, + because the binding is created against a BYOIP prefix in Addressing. Args: account_id: Identifier of a Cloudflare account. @@ -123,7 +126,7 @@ def list( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> SyncCursorPagination[PrefixBindingListResponse]: """ - List DLS prefix bindings for an account + List the BYOIP prefix bindings configured for an account. Args: account_id: Identifier of a Cloudflare account. @@ -173,7 +176,10 @@ def delete( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> PrefixBindingDeleteResponse: """ - Delete a DLS prefix binding + Delete a BYOIP prefix binding. + + Like creating a binding, this requires **IP Prefixes Write** in addition to + **DLS Write**. Args: account_id: Identifier of a Cloudflare account. @@ -218,7 +224,10 @@ def edit( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> PrefixBindingEditResponse: """ - Update a DLS prefix binding + Update the region of an existing BYOIP prefix binding. + + Like creating a binding, this requires **IP Prefixes Write** in addition to + **DLS Write**. Args: account_id: Identifier of a Cloudflare account. @@ -269,7 +278,7 @@ def get( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> PrefixBindingGetResponse: """ - Get a DLS prefix binding + Retrieve a single BYOIP prefix binding by ID. Args: account_id: Identifier of a Cloudflare account. @@ -340,7 +349,10 @@ async def create( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> PrefixBindingCreateResponse: """ - Create a DLS prefix binding + Bind a CIDR from a BYOIP prefix to a region. + + This requires the **IP Prefixes Write** permission in addition to **DLS Write**, + because the binding is created against a BYOIP prefix in Addressing. Args: account_id: Identifier of a Cloudflare account. @@ -395,7 +407,7 @@ def list( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> AsyncPaginator[PrefixBindingListResponse, AsyncCursorPagination[PrefixBindingListResponse]]: """ - List DLS prefix bindings for an account + List the BYOIP prefix bindings configured for an account. Args: account_id: Identifier of a Cloudflare account. @@ -445,7 +457,10 @@ async def delete( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> PrefixBindingDeleteResponse: """ - Delete a DLS prefix binding + Delete a BYOIP prefix binding. + + Like creating a binding, this requires **IP Prefixes Write** in addition to + **DLS Write**. Args: account_id: Identifier of a Cloudflare account. @@ -490,7 +505,10 @@ async def edit( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> PrefixBindingEditResponse: """ - Update a DLS prefix binding + Update the region of an existing BYOIP prefix binding. + + Like creating a binding, this requires **IP Prefixes Write** in addition to + **DLS Write**. Args: account_id: Identifier of a Cloudflare account. @@ -543,7 +561,7 @@ async def get( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> PrefixBindingGetResponse: """ - Get a DLS prefix binding + Retrieve a single BYOIP prefix binding by ID. Args: account_id: Identifier of a Cloudflare account. diff --git a/src/cloudflare/resources/dls/regions.py b/src/cloudflare/resources/dls/regions.py index 10dbcb360d5..f0d11158abe 100644 --- a/src/cloudflare/resources/dls/regions.py +++ b/src/cloudflare/resources/dls/regions.py @@ -62,7 +62,7 @@ def list( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> SyncCursorPagination[RegionListResponse]: """ - List DLS regions for an account + List the DLS regions (managed and custom) available to an account. Args: account_id: Identifier of a Cloudflare account. @@ -115,7 +115,7 @@ def get( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> RegionGetResponse: """ - Get a DLS region + Retrieve a single DLS region (managed or custom) by ID or region key. Args: account_id: Identifier of a Cloudflare account. @@ -182,7 +182,7 @@ def list( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> AsyncPaginator[RegionListResponse, AsyncCursorPagination[RegionListResponse]]: """ - List DLS regions for an account + List the DLS regions (managed and custom) available to an account. Args: account_id: Identifier of a Cloudflare account. @@ -235,7 +235,7 @@ async def get( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> RegionGetResponse: """ - Get a DLS region + Retrieve a single DLS region (managed or custom) by ID or region key. Args: account_id: Identifier of a Cloudflare account. diff --git a/src/cloudflare/resources/dns/api.md b/src/cloudflare/resources/dns/api.md index 615b12f2d15..50c14054e34 100644 --- a/src/cloudflare/resources/dns/api.md +++ b/src/cloudflare/resources/dns/api.md @@ -138,6 +138,26 @@ Methods: - client.dns.settings.account.edit(\*, account_id, \*\*params) -> Optional[AccountEditResponse] - client.dns.settings.account.get(\*, account_id) -> Optional[AccountGetResponse] +#### NameserverSets + +Types: + +```python +from cloudflare.types.dns.settings.account import ( + NameserverSetCreateResponse, + NameserverSetListResponse, + NameserverSetDeleteResponse, + NameserverSetGetResponse, +) +``` + +Methods: + +- client.dns.settings.account.nameserver_sets.create(\*, account_id, \*\*params) -> NameserverSetCreateResponse +- client.dns.settings.account.nameserver_sets.list(\*, account_id, \*\*params) -> SyncV4PagePaginationArray[NameserverSetListResponse] +- client.dns.settings.account.nameserver_sets.delete(nameserver_set_id, \*, account_id) -> NameserverSetDeleteResponse +- client.dns.settings.account.nameserver_sets.get(nameserver_set_id, \*, account_id) -> NameserverSetGetResponse + #### Views Types: diff --git a/src/cloudflare/resources/dns/records.py b/src/cloudflare/resources/dns/records.py index d102c12e8c5..2c336bee6e9 100644 --- a/src/cloudflare/resources/dns/records.py +++ b/src/cloudflare/resources/dns/records.py @@ -3347,10 +3347,11 @@ def list( parameter works independently of the `match` setting. For automated searches, please use the other available parameters. - shadowed_by_name: Filters to records at or below the given NS delegation name, excluding the NS - records that form the delegation itself. The value must be a subdomain of the - zone; the zone apex is not accepted. Requires `include_shadow_metadata=true`. - See + shadowed_by_name: Filters the response to records at or below the specified NS delegation name. + NS, DS, and NSEC records at the delegation name are excluded because they are + not shadowed by that delegation. Those record types are included only when they + exist below the delegation. The value must be a non-apex subdomain of the zone. + Requires `include_shadow_metadata=true`. See [Shadowed records](https://developers.cloudflare.com/dns/manage-dns-records/reference/shadowed-records). shadowing_name: Returns NS records that shadow the given name, searching at the name itself and @@ -8804,10 +8805,11 @@ def list( parameter works independently of the `match` setting. For automated searches, please use the other available parameters. - shadowed_by_name: Filters to records at or below the given NS delegation name, excluding the NS - records that form the delegation itself. The value must be a subdomain of the - zone; the zone apex is not accepted. Requires `include_shadow_metadata=true`. - See + shadowed_by_name: Filters the response to records at or below the specified NS delegation name. + NS, DS, and NSEC records at the delegation name are excluded because they are + not shadowed by that delegation. Those record types are included only when they + exist below the delegation. The value must be a non-apex subdomain of the zone. + Requires `include_shadow_metadata=true`. See [Shadowed records](https://developers.cloudflare.com/dns/manage-dns-records/reference/shadowed-records). shadowing_name: Returns NS records that shadow the given name, searching at the name itself and diff --git a/src/cloudflare/resources/dns/settings/account/__init__.py b/src/cloudflare/resources/dns/settings/account/__init__.py index 90a8fa4dbdb..e9c8d887339 100644 --- a/src/cloudflare/resources/dns/settings/account/__init__.py +++ b/src/cloudflare/resources/dns/settings/account/__init__.py @@ -16,8 +16,22 @@ AccountResourceWithStreamingResponse, AsyncAccountResourceWithStreamingResponse, ) +from .nameserver_sets import ( + NameserverSetsResource, + AsyncNameserverSetsResource, + NameserverSetsResourceWithRawResponse, + AsyncNameserverSetsResourceWithRawResponse, + NameserverSetsResourceWithStreamingResponse, + AsyncNameserverSetsResourceWithStreamingResponse, +) __all__ = [ + "NameserverSetsResource", + "AsyncNameserverSetsResource", + "NameserverSetsResourceWithRawResponse", + "AsyncNameserverSetsResourceWithRawResponse", + "NameserverSetsResourceWithStreamingResponse", + "AsyncNameserverSetsResourceWithStreamingResponse", "ViewsResource", "AsyncViewsResource", "ViewsResourceWithRawResponse", diff --git a/src/cloudflare/resources/dns/settings/account/account.py b/src/cloudflare/resources/dns/settings/account/account.py index 64ca3dbb9cc..4ec6a1e72c2 100644 --- a/src/cloudflare/resources/dns/settings/account/account.py +++ b/src/cloudflare/resources/dns/settings/account/account.py @@ -25,6 +25,14 @@ async_to_streamed_response_wrapper, ) from ....._wrappers import ResultWrapper +from .nameserver_sets import ( + NameserverSetsResource, + AsyncNameserverSetsResource, + NameserverSetsResourceWithRawResponse, + AsyncNameserverSetsResourceWithRawResponse, + NameserverSetsResourceWithStreamingResponse, + AsyncNameserverSetsResourceWithStreamingResponse, +) from ....._base_client import make_request_options from .....types.dns.settings import account_edit_params from .....types.dns.settings.account_get_response import AccountGetResponse @@ -34,6 +42,10 @@ class AccountResource(SyncAPIResource): + @cached_property + def nameserver_sets(self) -> NameserverSetsResource: + return NameserverSetsResource(self._client) + @cached_property def views(self) -> ViewsResource: return ViewsResource(self._client) @@ -154,6 +166,10 @@ def get( class AsyncAccountResource(AsyncAPIResource): + @cached_property + def nameserver_sets(self) -> AsyncNameserverSetsResource: + return AsyncNameserverSetsResource(self._client) + @cached_property def views(self) -> AsyncViewsResource: return AsyncViewsResource(self._client) @@ -284,6 +300,10 @@ def __init__(self, account: AccountResource) -> None: account.get, ) + @cached_property + def nameserver_sets(self) -> NameserverSetsResourceWithRawResponse: + return NameserverSetsResourceWithRawResponse(self._account.nameserver_sets) + @cached_property def views(self) -> ViewsResourceWithRawResponse: return ViewsResourceWithRawResponse(self._account.views) @@ -300,6 +320,10 @@ def __init__(self, account: AsyncAccountResource) -> None: account.get, ) + @cached_property + def nameserver_sets(self) -> AsyncNameserverSetsResourceWithRawResponse: + return AsyncNameserverSetsResourceWithRawResponse(self._account.nameserver_sets) + @cached_property def views(self) -> AsyncViewsResourceWithRawResponse: return AsyncViewsResourceWithRawResponse(self._account.views) @@ -316,6 +340,10 @@ def __init__(self, account: AccountResource) -> None: account.get, ) + @cached_property + def nameserver_sets(self) -> NameserverSetsResourceWithStreamingResponse: + return NameserverSetsResourceWithStreamingResponse(self._account.nameserver_sets) + @cached_property def views(self) -> ViewsResourceWithStreamingResponse: return ViewsResourceWithStreamingResponse(self._account.views) @@ -332,6 +360,10 @@ def __init__(self, account: AsyncAccountResource) -> None: account.get, ) + @cached_property + def nameserver_sets(self) -> AsyncNameserverSetsResourceWithStreamingResponse: + return AsyncNameserverSetsResourceWithStreamingResponse(self._account.nameserver_sets) + @cached_property def views(self) -> AsyncViewsResourceWithStreamingResponse: return AsyncViewsResourceWithStreamingResponse(self._account.views) diff --git a/src/cloudflare/resources/dns/settings/account/nameserver_sets.py b/src/cloudflare/resources/dns/settings/account/nameserver_sets.py new file mode 100644 index 00000000000..55ef77768c3 --- /dev/null +++ b/src/cloudflare/resources/dns/settings/account/nameserver_sets.py @@ -0,0 +1,616 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Any, Type, Iterable, cast + +import httpx + +from ....._types import Body, Omit, Query, Headers, NotGiven, omit, not_given +from ....._utils import path_template, maybe_transform, async_maybe_transform +from ....._compat import cached_property +from ....._resource import SyncAPIResource, AsyncAPIResource +from ....._response import ( + to_raw_response_wrapper, + to_streamed_response_wrapper, + async_to_raw_response_wrapper, + async_to_streamed_response_wrapper, +) +from ....._wrappers import ResultWrapper +from .....pagination import SyncV4PagePaginationArray, AsyncV4PagePaginationArray +from ....._base_client import AsyncPaginator, make_request_options +from .....types.dns.settings.account import nameserver_set_list_params, nameserver_set_create_params +from .....types.dns.settings.account.nameserver_set_get_response import NameserverSetGetResponse +from .....types.dns.settings.account.nameserver_set_list_response import NameserverSetListResponse +from .....types.dns.settings.account.nameserver_set_create_response import NameserverSetCreateResponse +from .....types.dns.settings.account.nameserver_set_delete_response import NameserverSetDeleteResponse + +__all__ = ["NameserverSetsResource", "AsyncNameserverSetsResource"] + + +class NameserverSetsResource(SyncAPIResource): + @cached_property + def with_raw_response(self) -> NameserverSetsResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers + """ + return NameserverSetsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> NameserverSetsResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response + """ + return NameserverSetsResourceWithStreamingResponse(self) + + def create( + self, + *, + account_id: str, + name: str, + nameservers: Iterable[nameserver_set_create_params.Nameserver], + advanced: bool | Omit = omit, + ip_set: int | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> NameserverSetCreateResponse: + """Creates a named Custom Nameserver Set. + + Only the customer-defined name can be + changed later. To change nameservers or addresses, create a new set, move any + zone assignments, and delete the old set. For details, refer to + [Nameserver sets](https://developers.cloudflare.com/dns/nameservers/custom-nameservers/nameserver-sets/). + + Args: + account_id: Identifier. + + name: Customer-defined name, unique within the account by exact string equality + (case-sensitive, with no Unicode normalization). Must be valid UTF-8 and at most + 255 UTF-8 bytes, not 255 characters. Only graphical Unicode characters are + allowed; leading or trailing whitespace is rejected. The name can be changed + without changing the set's nameservers or addresses. + + nameservers: Lists each nameserver and the number of addresses to allocate to it. Requires a + unique name for each entry in the set. + + advanced: Whether to allocate the nameservers from distinct Advanced anycast groups. + + ip_set: Selects the account-specific IP set that supplies the nameserver addresses. + Nameserver sets with the same `ip_set` and `advanced` value may reuse addresses; + otherwise, they use disjoint address groups. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + return cast( + NameserverSetCreateResponse, + self._post( + path_template("/accounts/{account_id}/dns_settings/nameserver_sets", account_id=account_id), + body=maybe_transform( + { + "name": name, + "nameservers": nameservers, + "advanced": advanced, + "ip_set": ip_set, + }, + nameserver_set_create_params.NameserverSetCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[NameserverSetCreateResponse]._unwrapper, + ), + cast_to=cast( + Any, ResultWrapper[NameserverSetCreateResponse] + ), # Union types cannot be passed in as arguments in the type system + ), + ) + + def list( + self, + *, + account_id: str, + page: int | Omit = omit, + per_page: int | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> SyncV4PagePaginationArray[NameserverSetListResponse]: + """Lists an account's Custom Nameserver Sets. + + For details, refer to + [Nameserver sets](https://developers.cloudflare.com/dns/nameservers/custom-nameservers/nameserver-sets/). + + Args: + account_id: Identifier. + + page: Page number of paginated results. + + per_page: Number of results per page. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + return self._get_api_list( + path_template("/accounts/{account_id}/dns_settings/nameserver_sets", account_id=account_id), + page=SyncV4PagePaginationArray[NameserverSetListResponse], + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "page": page, + "per_page": per_page, + }, + nameserver_set_list_params.NameserverSetListParams, + ), + ), + model=cast( + Any, NameserverSetListResponse + ), # Union types cannot be passed in as arguments in the type system + ) + + def delete( + self, + nameserver_set_id: str, + *, + account_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> NameserverSetDeleteResponse: + """Deletes an unassigned Custom Nameserver Set. + + For details, refer to + [Nameserver sets](https://developers.cloudflare.com/dns/nameservers/custom-nameservers/nameserver-sets/). + + Args: + account_id: Identifier. + + nameserver_set_id: Identifier for a nameserver set. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not nameserver_set_id: + raise ValueError(f"Expected a non-empty value for `nameserver_set_id` but received {nameserver_set_id!r}") + return self._delete( + path_template( + "/accounts/{account_id}/dns_settings/nameserver_sets/{nameserver_set_id}", + account_id=account_id, + nameserver_set_id=nameserver_set_id, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[NameserverSetDeleteResponse]._unwrapper, + ), + cast_to=cast(Type[NameserverSetDeleteResponse], ResultWrapper[NameserverSetDeleteResponse]), + ) + + def get( + self, + nameserver_set_id: str, + *, + account_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> NameserverSetGetResponse: + """Gets a Custom Nameserver Set owned by an account. + + For details, refer to + [Nameserver sets](https://developers.cloudflare.com/dns/nameservers/custom-nameservers/nameserver-sets/). + + Args: + account_id: Identifier. + + nameserver_set_id: Identifier for a nameserver set. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not nameserver_set_id: + raise ValueError(f"Expected a non-empty value for `nameserver_set_id` but received {nameserver_set_id!r}") + return cast( + NameserverSetGetResponse, + self._get( + path_template( + "/accounts/{account_id}/dns_settings/nameserver_sets/{nameserver_set_id}", + account_id=account_id, + nameserver_set_id=nameserver_set_id, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[NameserverSetGetResponse]._unwrapper, + ), + cast_to=cast( + Any, ResultWrapper[NameserverSetGetResponse] + ), # Union types cannot be passed in as arguments in the type system + ), + ) + + +class AsyncNameserverSetsResource(AsyncAPIResource): + @cached_property + def with_raw_response(self) -> AsyncNameserverSetsResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers + """ + return AsyncNameserverSetsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncNameserverSetsResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response + """ + return AsyncNameserverSetsResourceWithStreamingResponse(self) + + async def create( + self, + *, + account_id: str, + name: str, + nameservers: Iterable[nameserver_set_create_params.Nameserver], + advanced: bool | Omit = omit, + ip_set: int | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> NameserverSetCreateResponse: + """Creates a named Custom Nameserver Set. + + Only the customer-defined name can be + changed later. To change nameservers or addresses, create a new set, move any + zone assignments, and delete the old set. For details, refer to + [Nameserver sets](https://developers.cloudflare.com/dns/nameservers/custom-nameservers/nameserver-sets/). + + Args: + account_id: Identifier. + + name: Customer-defined name, unique within the account by exact string equality + (case-sensitive, with no Unicode normalization). Must be valid UTF-8 and at most + 255 UTF-8 bytes, not 255 characters. Only graphical Unicode characters are + allowed; leading or trailing whitespace is rejected. The name can be changed + without changing the set's nameservers or addresses. + + nameservers: Lists each nameserver and the number of addresses to allocate to it. Requires a + unique name for each entry in the set. + + advanced: Whether to allocate the nameservers from distinct Advanced anycast groups. + + ip_set: Selects the account-specific IP set that supplies the nameserver addresses. + Nameserver sets with the same `ip_set` and `advanced` value may reuse addresses; + otherwise, they use disjoint address groups. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + return cast( + NameserverSetCreateResponse, + await self._post( + path_template("/accounts/{account_id}/dns_settings/nameserver_sets", account_id=account_id), + body=await async_maybe_transform( + { + "name": name, + "nameservers": nameservers, + "advanced": advanced, + "ip_set": ip_set, + }, + nameserver_set_create_params.NameserverSetCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[NameserverSetCreateResponse]._unwrapper, + ), + cast_to=cast( + Any, ResultWrapper[NameserverSetCreateResponse] + ), # Union types cannot be passed in as arguments in the type system + ), + ) + + def list( + self, + *, + account_id: str, + page: int | Omit = omit, + per_page: int | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> AsyncPaginator[NameserverSetListResponse, AsyncV4PagePaginationArray[NameserverSetListResponse]]: + """Lists an account's Custom Nameserver Sets. + + For details, refer to + [Nameserver sets](https://developers.cloudflare.com/dns/nameservers/custom-nameservers/nameserver-sets/). + + Args: + account_id: Identifier. + + page: Page number of paginated results. + + per_page: Number of results per page. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + return self._get_api_list( + path_template("/accounts/{account_id}/dns_settings/nameserver_sets", account_id=account_id), + page=AsyncV4PagePaginationArray[NameserverSetListResponse], + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "page": page, + "per_page": per_page, + }, + nameserver_set_list_params.NameserverSetListParams, + ), + ), + model=cast( + Any, NameserverSetListResponse + ), # Union types cannot be passed in as arguments in the type system + ) + + async def delete( + self, + nameserver_set_id: str, + *, + account_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> NameserverSetDeleteResponse: + """Deletes an unassigned Custom Nameserver Set. + + For details, refer to + [Nameserver sets](https://developers.cloudflare.com/dns/nameservers/custom-nameservers/nameserver-sets/). + + Args: + account_id: Identifier. + + nameserver_set_id: Identifier for a nameserver set. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not nameserver_set_id: + raise ValueError(f"Expected a non-empty value for `nameserver_set_id` but received {nameserver_set_id!r}") + return await self._delete( + path_template( + "/accounts/{account_id}/dns_settings/nameserver_sets/{nameserver_set_id}", + account_id=account_id, + nameserver_set_id=nameserver_set_id, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[NameserverSetDeleteResponse]._unwrapper, + ), + cast_to=cast(Type[NameserverSetDeleteResponse], ResultWrapper[NameserverSetDeleteResponse]), + ) + + async def get( + self, + nameserver_set_id: str, + *, + account_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> NameserverSetGetResponse: + """Gets a Custom Nameserver Set owned by an account. + + For details, refer to + [Nameserver sets](https://developers.cloudflare.com/dns/nameservers/custom-nameservers/nameserver-sets/). + + Args: + account_id: Identifier. + + nameserver_set_id: Identifier for a nameserver set. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not nameserver_set_id: + raise ValueError(f"Expected a non-empty value for `nameserver_set_id` but received {nameserver_set_id!r}") + return cast( + NameserverSetGetResponse, + await self._get( + path_template( + "/accounts/{account_id}/dns_settings/nameserver_sets/{nameserver_set_id}", + account_id=account_id, + nameserver_set_id=nameserver_set_id, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[NameserverSetGetResponse]._unwrapper, + ), + cast_to=cast( + Any, ResultWrapper[NameserverSetGetResponse] + ), # Union types cannot be passed in as arguments in the type system + ), + ) + + +class NameserverSetsResourceWithRawResponse: + def __init__(self, nameserver_sets: NameserverSetsResource) -> None: + self._nameserver_sets = nameserver_sets + + self.create = to_raw_response_wrapper( + nameserver_sets.create, + ) + self.list = to_raw_response_wrapper( + nameserver_sets.list, + ) + self.delete = to_raw_response_wrapper( + nameserver_sets.delete, + ) + self.get = to_raw_response_wrapper( + nameserver_sets.get, + ) + + +class AsyncNameserverSetsResourceWithRawResponse: + def __init__(self, nameserver_sets: AsyncNameserverSetsResource) -> None: + self._nameserver_sets = nameserver_sets + + self.create = async_to_raw_response_wrapper( + nameserver_sets.create, + ) + self.list = async_to_raw_response_wrapper( + nameserver_sets.list, + ) + self.delete = async_to_raw_response_wrapper( + nameserver_sets.delete, + ) + self.get = async_to_raw_response_wrapper( + nameserver_sets.get, + ) + + +class NameserverSetsResourceWithStreamingResponse: + def __init__(self, nameserver_sets: NameserverSetsResource) -> None: + self._nameserver_sets = nameserver_sets + + self.create = to_streamed_response_wrapper( + nameserver_sets.create, + ) + self.list = to_streamed_response_wrapper( + nameserver_sets.list, + ) + self.delete = to_streamed_response_wrapper( + nameserver_sets.delete, + ) + self.get = to_streamed_response_wrapper( + nameserver_sets.get, + ) + + +class AsyncNameserverSetsResourceWithStreamingResponse: + def __init__(self, nameserver_sets: AsyncNameserverSetsResource) -> None: + self._nameserver_sets = nameserver_sets + + self.create = async_to_streamed_response_wrapper( + nameserver_sets.create, + ) + self.list = async_to_streamed_response_wrapper( + nameserver_sets.list, + ) + self.delete = async_to_streamed_response_wrapper( + nameserver_sets.delete, + ) + self.get = async_to_streamed_response_wrapper( + nameserver_sets.get, + ) diff --git a/src/cloudflare/resources/email_security/settings/allow_policies.py b/src/cloudflare/resources/email_security/settings/allow_policies.py index aceaac1db22..b6c8b389bbc 100644 --- a/src/cloudflare/resources/email_security/settings/allow_policies.py +++ b/src/cloudflare/resources/email_security/settings/allow_policies.py @@ -2,7 +2,8 @@ from __future__ import annotations -from typing import Type, Iterable, Optional, cast +from typing import Type, Union, Iterable, Optional, cast +from datetime import datetime from typing_extensions import Literal import httpx @@ -68,6 +69,7 @@ def create( pattern_type: Literal["EMAIL", "DOMAIN", "IP", "UNKNOWN"], verify_sender: bool, comments: Optional[str] | Omit = omit, + expires_at: Union[str, datetime, None] | Omit = omit, is_recipient: bool | Omit = omit, is_sender: bool | Omit = omit, is_spoof: bool | Omit = omit, @@ -99,7 +101,8 @@ def create( (e.g. `example.com`), or a plain IPv4 or IPv6 address or CIDR block for IP (e.g. `1.2.3.4`, `1.2.3.0/24`, `2606:4700:4700::1111`, or `2606:4700:4700::/48`); the API rejects private or unique-local, loopback, link-local, unspecified, and IPv4 - broadcast addresses, including their IPv4-mapped IPv6 equivalents. + broadcast addresses, including their IPv4-mapped IPv6 equivalents. The API also + rejects a pattern that equals a domain onboarded to the account, ignoring case. pattern_type: Type of pattern matching. @@ -116,6 +119,10 @@ def create( verify_sender: Enforce DMARC, SPF or DKIM authentication. When on, Email Security only honors policies that pass authentication. + expires_at: Timestamp at which the policy expires. After this time, Email Security ignores + the policy. The value must lie in the future. Send `null` to clear the + expiration. + is_recipient: Deprecated as of July 1, 2025. Use `is_exempt_recipient` instead. End of life: July 1, 2026. @@ -150,6 +157,7 @@ def create( "pattern_type": pattern_type, "verify_sender": verify_sender, "comments": comments, + "expires_at": expires_at, "is_recipient": is_recipient, "is_sender": is_sender, "is_spoof": is_spoof, @@ -171,6 +179,7 @@ def list( *, account_id: str, direction: Literal["asc", "desc"] | Omit = omit, + expired: bool | Omit = omit, is_acceptable_sender: bool | Omit = omit, is_exempt_recipient: bool | Omit = omit, is_trusted_sender: bool | Omit = omit, @@ -199,6 +208,9 @@ def list( direction: The sorting direction. + expired: Filter to return only expired policies (`true`) or only policies that still + apply (`false`). Omit to return both. + is_acceptable_sender: Filter to show only policies where messages from the sender are exempted from Spam, Spoof, and Bulk dispositions (not Malicious or Suspicious). @@ -243,6 +255,7 @@ def list( query=maybe_transform( { "direction": direction, + "expired": expired, "is_acceptable_sender": is_acceptable_sender, "is_exempt_recipient": is_exempt_recipient, "is_trusted_sender": is_trusted_sender, @@ -381,6 +394,7 @@ def edit( *, account_id: str, comments: Optional[str] | Omit = omit, + expires_at: Union[str, datetime, None] | Omit = omit, is_acceptable_sender: bool | Omit = omit, is_exempt_recipient: bool | Omit = omit, is_recipient: bool | Omit = omit, @@ -408,6 +422,10 @@ def edit( policy_id: Allow policy identifier. + expires_at: Timestamp at which the policy expires. After this time, Email Security ignores + the policy. The value must lie in the future. Send `null` to clear the + expiration. + is_acceptable_sender: Exempts messages from this sender from Spam, Spoof and Bulk dispositions only; Malicious and Suspicious dispositions still apply. @@ -432,7 +450,8 @@ def edit( (e.g. `example.com`), or a plain IPv4 or IPv6 address or CIDR block for IP (e.g. `1.2.3.4`, `1.2.3.0/24`, `2606:4700:4700::1111`, or `2606:4700:4700::/48`); the API rejects private or unique-local, loopback, link-local, unspecified, and IPv4 - broadcast addresses, including their IPv4-mapped IPv6 equivalents. + broadcast addresses, including their IPv4-mapped IPv6 equivalents. The API also + rejects a pattern that equals a domain onboarded to the account, ignoring case. pattern_type: Type of pattern matching. @@ -470,6 +489,7 @@ def edit( body=maybe_transform( { "comments": comments, + "expires_at": expires_at, "is_acceptable_sender": is_acceptable_sender, "is_exempt_recipient": is_exempt_recipient, "is_recipient": is_recipient, @@ -575,6 +595,7 @@ async def create( pattern_type: Literal["EMAIL", "DOMAIN", "IP", "UNKNOWN"], verify_sender: bool, comments: Optional[str] | Omit = omit, + expires_at: Union[str, datetime, None] | Omit = omit, is_recipient: bool | Omit = omit, is_sender: bool | Omit = omit, is_spoof: bool | Omit = omit, @@ -606,7 +627,8 @@ async def create( (e.g. `example.com`), or a plain IPv4 or IPv6 address or CIDR block for IP (e.g. `1.2.3.4`, `1.2.3.0/24`, `2606:4700:4700::1111`, or `2606:4700:4700::/48`); the API rejects private or unique-local, loopback, link-local, unspecified, and IPv4 - broadcast addresses, including their IPv4-mapped IPv6 equivalents. + broadcast addresses, including their IPv4-mapped IPv6 equivalents. The API also + rejects a pattern that equals a domain onboarded to the account, ignoring case. pattern_type: Type of pattern matching. @@ -623,6 +645,10 @@ async def create( verify_sender: Enforce DMARC, SPF or DKIM authentication. When on, Email Security only honors policies that pass authentication. + expires_at: Timestamp at which the policy expires. After this time, Email Security ignores + the policy. The value must lie in the future. Send `null` to clear the + expiration. + is_recipient: Deprecated as of July 1, 2025. Use `is_exempt_recipient` instead. End of life: July 1, 2026. @@ -657,6 +683,7 @@ async def create( "pattern_type": pattern_type, "verify_sender": verify_sender, "comments": comments, + "expires_at": expires_at, "is_recipient": is_recipient, "is_sender": is_sender, "is_spoof": is_spoof, @@ -678,6 +705,7 @@ def list( *, account_id: str, direction: Literal["asc", "desc"] | Omit = omit, + expired: bool | Omit = omit, is_acceptable_sender: bool | Omit = omit, is_exempt_recipient: bool | Omit = omit, is_trusted_sender: bool | Omit = omit, @@ -706,6 +734,9 @@ def list( direction: The sorting direction. + expired: Filter to return only expired policies (`true`) or only policies that still + apply (`false`). Omit to return both. + is_acceptable_sender: Filter to show only policies where messages from the sender are exempted from Spam, Spoof, and Bulk dispositions (not Malicious or Suspicious). @@ -750,6 +781,7 @@ def list( query=maybe_transform( { "direction": direction, + "expired": expired, "is_acceptable_sender": is_acceptable_sender, "is_exempt_recipient": is_exempt_recipient, "is_trusted_sender": is_trusted_sender, @@ -888,6 +920,7 @@ async def edit( *, account_id: str, comments: Optional[str] | Omit = omit, + expires_at: Union[str, datetime, None] | Omit = omit, is_acceptable_sender: bool | Omit = omit, is_exempt_recipient: bool | Omit = omit, is_recipient: bool | Omit = omit, @@ -915,6 +948,10 @@ async def edit( policy_id: Allow policy identifier. + expires_at: Timestamp at which the policy expires. After this time, Email Security ignores + the policy. The value must lie in the future. Send `null` to clear the + expiration. + is_acceptable_sender: Exempts messages from this sender from Spam, Spoof and Bulk dispositions only; Malicious and Suspicious dispositions still apply. @@ -939,7 +976,8 @@ async def edit( (e.g. `example.com`), or a plain IPv4 or IPv6 address or CIDR block for IP (e.g. `1.2.3.4`, `1.2.3.0/24`, `2606:4700:4700::1111`, or `2606:4700:4700::/48`); the API rejects private or unique-local, loopback, link-local, unspecified, and IPv4 - broadcast addresses, including their IPv4-mapped IPv6 equivalents. + broadcast addresses, including their IPv4-mapped IPv6 equivalents. The API also + rejects a pattern that equals a domain onboarded to the account, ignoring case. pattern_type: Type of pattern matching. @@ -977,6 +1015,7 @@ async def edit( body=await async_maybe_transform( { "comments": comments, + "expires_at": expires_at, "is_acceptable_sender": is_acceptable_sender, "is_exempt_recipient": is_exempt_recipient, "is_recipient": is_recipient, diff --git a/src/cloudflare/resources/email_security/settings/block_senders.py b/src/cloudflare/resources/email_security/settings/block_senders.py index 03d7a29233a..c332cc06ac1 100644 --- a/src/cloudflare/resources/email_security/settings/block_senders.py +++ b/src/cloudflare/resources/email_security/settings/block_senders.py @@ -2,7 +2,8 @@ from __future__ import annotations -from typing import Type, Iterable, Optional, cast +from typing import Type, Union, Iterable, Optional, cast +from datetime import datetime from typing_extensions import Literal import httpx @@ -64,6 +65,7 @@ def create( pattern: str, pattern_type: Literal["EMAIL", "DOMAIN", "IP", "UNKNOWN"], comments: Optional[str] | Omit = omit, + expires_at: Union[str, datetime, None] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -101,6 +103,10 @@ def create( - UNKNOWN: deprecated; you cannot use this when creating or updating policies, but it may appear on existing entries. + expires_at: Timestamp at which the pattern expires. After this time, Email Security ignores + the pattern. The value must lie in the future. Send `null` to clear the + expiration. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -119,6 +125,7 @@ def create( "pattern": pattern, "pattern_type": pattern_type, "comments": comments, + "expires_at": expires_at, }, block_sender_create_params.BlockSenderCreateParams, ), @@ -137,6 +144,7 @@ def list( *, account_id: str, direction: Literal["asc", "desc"] | Omit = omit, + expired: bool | Omit = omit, order: Literal["pattern", "created_at"] | Omit = omit, page: int | Omit = omit, pattern: str | Omit = omit, @@ -161,6 +169,9 @@ def list( direction: The sorting direction. + expired: Filter to return only expired patterns (`true`) or only patterns that still + apply (`false`). Omit to return both. + order: Field to sort by. page: Current page within paginated list of results. @@ -194,6 +205,7 @@ def list( query=maybe_transform( { "direction": direction, + "expired": expired, "order": order, "page": page, "pattern": pattern, @@ -328,6 +340,7 @@ def edit( *, account_id: str, comments: Optional[str] | Omit = omit, + expires_at: Union[str, datetime, None] | Omit = omit, is_regex: bool | Omit = omit, pattern: str | Omit = omit, pattern_type: Literal["EMAIL", "DOMAIN", "IP", "UNKNOWN"] | Omit = omit, @@ -348,6 +361,10 @@ def edit( pattern_id: Blocked sender pattern identifier. + expires_at: Timestamp at which the pattern expires. After this time, Email Security ignores + the pattern. The value must lie in the future. Send `null` to clear the + expiration. + is_regex: Whether `pattern` is a regular expression instead of a literal value. pattern: The pattern value to match. The format depends on `pattern_type`: a valid email @@ -390,6 +407,7 @@ def edit( body=maybe_transform( { "comments": comments, + "expires_at": expires_at, "is_regex": is_regex, "pattern": pattern, "pattern_type": pattern_type, @@ -484,6 +502,7 @@ async def create( pattern: str, pattern_type: Literal["EMAIL", "DOMAIN", "IP", "UNKNOWN"], comments: Optional[str] | Omit = omit, + expires_at: Union[str, datetime, None] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -521,6 +540,10 @@ async def create( - UNKNOWN: deprecated; you cannot use this when creating or updating policies, but it may appear on existing entries. + expires_at: Timestamp at which the pattern expires. After this time, Email Security ignores + the pattern. The value must lie in the future. Send `null` to clear the + expiration. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -539,6 +562,7 @@ async def create( "pattern": pattern, "pattern_type": pattern_type, "comments": comments, + "expires_at": expires_at, }, block_sender_create_params.BlockSenderCreateParams, ), @@ -557,6 +581,7 @@ def list( *, account_id: str, direction: Literal["asc", "desc"] | Omit = omit, + expired: bool | Omit = omit, order: Literal["pattern", "created_at"] | Omit = omit, page: int | Omit = omit, pattern: str | Omit = omit, @@ -581,6 +606,9 @@ def list( direction: The sorting direction. + expired: Filter to return only expired patterns (`true`) or only patterns that still + apply (`false`). Omit to return both. + order: Field to sort by. page: Current page within paginated list of results. @@ -614,6 +642,7 @@ def list( query=maybe_transform( { "direction": direction, + "expired": expired, "order": order, "page": page, "pattern": pattern, @@ -748,6 +777,7 @@ async def edit( *, account_id: str, comments: Optional[str] | Omit = omit, + expires_at: Union[str, datetime, None] | Omit = omit, is_regex: bool | Omit = omit, pattern: str | Omit = omit, pattern_type: Literal["EMAIL", "DOMAIN", "IP", "UNKNOWN"] | Omit = omit, @@ -768,6 +798,10 @@ async def edit( pattern_id: Blocked sender pattern identifier. + expires_at: Timestamp at which the pattern expires. After this time, Email Security ignores + the pattern. The value must lie in the future. Send `null` to clear the + expiration. + is_regex: Whether `pattern` is a regular expression instead of a literal value. pattern: The pattern value to match. The format depends on `pattern_type`: a valid email @@ -810,6 +844,7 @@ async def edit( body=await async_maybe_transform( { "comments": comments, + "expires_at": expires_at, "is_regex": is_regex, "pattern": pattern, "pattern_type": pattern_type, diff --git a/src/cloudflare/resources/email_security/settings/content_policies.py b/src/cloudflare/resources/email_security/settings/content_policies.py index 6dc03b0b2f2..635c1c91750 100644 --- a/src/cloudflare/resources/email_security/settings/content_policies.py +++ b/src/cloudflare/resources/email_security/settings/content_policies.py @@ -2,7 +2,8 @@ from __future__ import annotations -from typing import List, Type, Iterable, Optional, cast +from typing import List, Type, Union, Iterable, Optional, cast +from datetime import datetime from typing_extensions import Literal import httpx @@ -64,6 +65,7 @@ def create( name: str, pattern: str, targets: List[Literal["SUBJECT", "BODY"]], + expires_at: Union[str, datetime, None] | Omit = omit, notes: Optional[str] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. @@ -88,6 +90,10 @@ def create( targets: Parts of the email the pattern is matched against. + expires_at: Timestamp at which the policy expires. After this time, Email Security ignores + the policy. The value must lie in the future. Send `null` to clear the + expiration. + notes: Optional note describing the purpose of the policy. extra_headers: Send extra headers @@ -108,6 +114,7 @@ def create( "name": name, "pattern": pattern, "targets": targets, + "expires_at": expires_at, "notes": notes, }, content_policy_create_params.ContentPolicyCreateParams, @@ -128,6 +135,7 @@ def list( account_id: str, direction: Literal["asc", "desc"] | Omit = omit, enabled: bool | Omit = omit, + expired: bool | Omit = omit, name: str | Omit = omit, order: Literal["name", "created_at"] | Omit = omit, page: int | Omit = omit, @@ -153,6 +161,9 @@ def list( enabled: Filter by enabled status. + expired: Filter to return only expired policies (`true`) or only policies that still + apply (`false`). Omit to return both. + name: Filter by exact policy name. order: Field to sort by. @@ -185,6 +196,7 @@ def list( { "direction": direction, "enabled": enabled, + "expired": expired, "name": name, "order": order, "page": page, @@ -320,6 +332,7 @@ def edit( *, account_id: str, enabled: bool | Omit = omit, + expires_at: Union[str, datetime, None] | Omit = omit, name: str | Omit = omit, notes: Optional[str] | Omit = omit, pattern: str | Omit = omit, @@ -342,6 +355,10 @@ def edit( enabled: Whether the policy is active. + expires_at: Timestamp at which the policy expires. After this time, Email Security ignores + the policy. The value must lie in the future. Send `null` to clear the + expiration. + name: Human-readable name of the policy. notes: Optional note describing the purpose of the policy. @@ -371,6 +388,7 @@ def edit( body=maybe_transform( { "enabled": enabled, + "expires_at": expires_at, "name": name, "notes": notes, "pattern": pattern, @@ -466,6 +484,7 @@ async def create( name: str, pattern: str, targets: List[Literal["SUBJECT", "BODY"]], + expires_at: Union[str, datetime, None] | Omit = omit, notes: Optional[str] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. @@ -490,6 +509,10 @@ async def create( targets: Parts of the email the pattern is matched against. + expires_at: Timestamp at which the policy expires. After this time, Email Security ignores + the policy. The value must lie in the future. Send `null` to clear the + expiration. + notes: Optional note describing the purpose of the policy. extra_headers: Send extra headers @@ -510,6 +533,7 @@ async def create( "name": name, "pattern": pattern, "targets": targets, + "expires_at": expires_at, "notes": notes, }, content_policy_create_params.ContentPolicyCreateParams, @@ -530,6 +554,7 @@ def list( account_id: str, direction: Literal["asc", "desc"] | Omit = omit, enabled: bool | Omit = omit, + expired: bool | Omit = omit, name: str | Omit = omit, order: Literal["name", "created_at"] | Omit = omit, page: int | Omit = omit, @@ -555,6 +580,9 @@ def list( enabled: Filter by enabled status. + expired: Filter to return only expired policies (`true`) or only policies that still + apply (`false`). Omit to return both. + name: Filter by exact policy name. order: Field to sort by. @@ -587,6 +615,7 @@ def list( { "direction": direction, "enabled": enabled, + "expired": expired, "name": name, "order": order, "page": page, @@ -722,6 +751,7 @@ async def edit( *, account_id: str, enabled: bool | Omit = omit, + expires_at: Union[str, datetime, None] | Omit = omit, name: str | Omit = omit, notes: Optional[str] | Omit = omit, pattern: str | Omit = omit, @@ -744,6 +774,10 @@ async def edit( enabled: Whether the policy is active. + expires_at: Timestamp at which the policy expires. After this time, Email Security ignores + the policy. The value must lie in the future. Send `null` to clear the + expiration. + name: Human-readable name of the policy. notes: Optional note describing the purpose of the policy. @@ -773,6 +807,7 @@ async def edit( body=await async_maybe_transform( { "enabled": enabled, + "expires_at": expires_at, "name": name, "notes": notes, "pattern": pattern, diff --git a/src/cloudflare/resources/email_sending/subdomains/subdomains.py b/src/cloudflare/resources/email_sending/subdomains/subdomains.py index 3165f0bfb80..cac5f5b9ce8 100644 --- a/src/cloudflare/resources/email_sending/subdomains/subdomains.py +++ b/src/cloudflare/resources/email_sending/subdomains/subdomains.py @@ -86,7 +86,9 @@ def create( name: The domain name within the zone. A wildcard is allowed only as the complete leftmost label (`*.example.com`) and requires the account wildcard Email Sending - entitlement. + entitlement. The derived Return-Path hostname, including its bounce prefix, must + be at most 201 characters after ASCII conversion; wildcards use the base + hostname. extra_headers: Send extra headers @@ -348,7 +350,9 @@ async def create( name: The domain name within the zone. A wildcard is allowed only as the complete leftmost label (`*.example.com`) and requires the account wildcard Email Sending - entitlement. + entitlement. The derived Return-Path hostname, including its bounce prefix, must + be at most 201 characters after ASCII conversion; wildcards use the base + hostname. extra_headers: Send extra headers diff --git a/src/cloudflare/resources/flagship/apps/flags/flags.py b/src/cloudflare/resources/flagship/apps/flags/flags.py index 5cabfa2fc8f..4c864d47a32 100644 --- a/src/cloudflare/resources/flagship/apps/flags/flags.py +++ b/src/cloudflare/resources/flagship/apps/flags/flags.py @@ -73,6 +73,7 @@ def create( rules: Iterable[flag_create_params.Rule], variations: Dict[str, Union[Optional[str], float, bool, Dict[str, object], Iterable[object]]], description: Optional[str] | Omit = omit, + metadata: Optional[Dict[str, Union[bool, str, float]]] | Omit = omit, type: Literal["boolean", "string", "number", "json"] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. @@ -84,7 +85,8 @@ def create( """Creates a flag. Returns 409 if the key already exists. `type` is always inferred - from variation values; legacy request-side values are ignored. + from variation values; legacy request-side values are ignored. Optional + `metadata` can be attached at creation. Args: account_id: Cloudflare account ID that owns the Flagship app. @@ -107,6 +109,10 @@ def create( description: Optional operator-facing description. It does not affect flag evaluation. + metadata: Key-value metadata associated with the flag. `null` or an empty object clears + existing metadata; omission semantics depend on the endpoint (PUT clears it, + PATCH preserves it). + type: Deprecated compatibility field. Omit it; the API ignores this value and infers the type from the flag's variations. @@ -132,6 +138,7 @@ def create( "rules": rules, "variations": variations, "description": description, + "metadata": metadata, "type": type, }, flag_create_params.FlagCreateParams, @@ -158,6 +165,7 @@ def update( rules: Iterable[flag_update_params.Rule], variations: Dict[str, Union[Optional[str], float, bool, Dict[str, object], Iterable[object]]], description: Optional[str] | Omit = omit, + metadata: Optional[Dict[str, Union[bool, str, float]]] | Omit = omit, type: Literal["boolean", "string", "number", "json"] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. @@ -168,9 +176,10 @@ def update( ) -> FlagUpdateResponse: """Replaces the entire flag definition. - Omitted fields are dropped, not preserved — + Omitted fields are cleared, not preserved — read before writing. The path key identifies the flag and cannot be renamed by - changing the body `key`. Each update appends a changelog entry. + changing the body `key`. A changelog entry is appended when the flag content + actually changes; identical updates are no-ops. Args: account_id: Cloudflare account ID that owns the Flagship app. @@ -195,6 +204,10 @@ def update( description: Optional operator-facing description. It does not affect flag evaluation. + metadata: Key-value metadata associated with the flag. `null` or an empty object clears + existing metadata; omission semantics depend on the endpoint (PUT clears it, + PATCH preserves it). + type: Deprecated compatibility field. Omit it; the API ignores this value and infers the type from the flag's variations. @@ -227,6 +240,7 @@ def update( "rules": rules, "variations": variations, "description": description, + "metadata": metadata, "type": type, }, flag_update_params.FlagUpdateParams, @@ -371,7 +385,8 @@ def get( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> FlagGetResponse: """ - Returns the full flag definition including rules, variations, and audit fields. + Returns the full flag definition including rules, variations, metadata, and + audit fields. Args: account_id: Cloudflare account ID that owns the Flagship app. @@ -447,6 +462,7 @@ async def create( rules: Iterable[flag_create_params.Rule], variations: Dict[str, Union[Optional[str], float, bool, Dict[str, object], Iterable[object]]], description: Optional[str] | Omit = omit, + metadata: Optional[Dict[str, Union[bool, str, float]]] | Omit = omit, type: Literal["boolean", "string", "number", "json"] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. @@ -458,7 +474,8 @@ async def create( """Creates a flag. Returns 409 if the key already exists. `type` is always inferred - from variation values; legacy request-side values are ignored. + from variation values; legacy request-side values are ignored. Optional + `metadata` can be attached at creation. Args: account_id: Cloudflare account ID that owns the Flagship app. @@ -481,6 +498,10 @@ async def create( description: Optional operator-facing description. It does not affect flag evaluation. + metadata: Key-value metadata associated with the flag. `null` or an empty object clears + existing metadata; omission semantics depend on the endpoint (PUT clears it, + PATCH preserves it). + type: Deprecated compatibility field. Omit it; the API ignores this value and infers the type from the flag's variations. @@ -506,6 +527,7 @@ async def create( "rules": rules, "variations": variations, "description": description, + "metadata": metadata, "type": type, }, flag_create_params.FlagCreateParams, @@ -532,6 +554,7 @@ async def update( rules: Iterable[flag_update_params.Rule], variations: Dict[str, Union[Optional[str], float, bool, Dict[str, object], Iterable[object]]], description: Optional[str] | Omit = omit, + metadata: Optional[Dict[str, Union[bool, str, float]]] | Omit = omit, type: Literal["boolean", "string", "number", "json"] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. @@ -542,9 +565,10 @@ async def update( ) -> FlagUpdateResponse: """Replaces the entire flag definition. - Omitted fields are dropped, not preserved — + Omitted fields are cleared, not preserved — read before writing. The path key identifies the flag and cannot be renamed by - changing the body `key`. Each update appends a changelog entry. + changing the body `key`. A changelog entry is appended when the flag content + actually changes; identical updates are no-ops. Args: account_id: Cloudflare account ID that owns the Flagship app. @@ -569,6 +593,10 @@ async def update( description: Optional operator-facing description. It does not affect flag evaluation. + metadata: Key-value metadata associated with the flag. `null` or an empty object clears + existing metadata; omission semantics depend on the endpoint (PUT clears it, + PATCH preserves it). + type: Deprecated compatibility field. Omit it; the API ignores this value and infers the type from the flag's variations. @@ -601,6 +629,7 @@ async def update( "rules": rules, "variations": variations, "description": description, + "metadata": metadata, "type": type, }, flag_update_params.FlagUpdateParams, @@ -745,7 +774,8 @@ async def get( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> FlagGetResponse: """ - Returns the full flag definition including rules, variations, and audit fields. + Returns the full flag definition including rules, variations, metadata, and + audit fields. Args: account_id: Cloudflare account ID that owns the Flagship app. diff --git a/src/cloudflare/resources/hyperdrive/configs.py b/src/cloudflare/resources/hyperdrive/configs.py index 70d710a3c3f..0771fbcbd3a 100644 --- a/src/cloudflare/resources/hyperdrive/configs.py +++ b/src/cloudflare/resources/hyperdrive/configs.py @@ -131,9 +131,10 @@ def create( Args: account_id: Define configurations using a unique string identifier. - integration: Connects to a PlanetScale database using credentials managed by Cloudflare. The - Cloudflare account must already be linked to PlanetScale in the Hyperdrive - dashboard. + integration: Selects a PlanetScale database and provisions credentials managed by Cloudflare + when creating a Hyperdrive configuration. The Cloudflare account must already be + linked to PlanetScale in the Hyperdrive dashboard. The selection is returned as + read-only metadata and cannot be changed with replace or update operations. name: The name of the Hyperdrive configuration. Used to identify the configuration in the Cloudflare dashboard and API. @@ -230,7 +231,9 @@ def update( The request must include the name and complete origin connection details. Omitted caching settings are reset to their defaults, while omitted mTLS settings and origin - connection limits are preserved. Use the update operation to modify only + connection limits are preserved. The integration association is set only during + creation and cannot be changed; omit the integration field even when replacing + an integration-backed configuration. Use the update operation to modify only selected fields. Args: @@ -412,7 +415,9 @@ def edit( """Updates and returns the specified fields of the Hyperdrive configuration. Custom - caching settings are not kept if caching is disabled. + caching settings are not kept if caching is disabled. For an integration-backed + configuration, the integration association is preserved but cannot be changed; + omit the integration field. Args: account_id: Define configurations using a unique string identifier. @@ -674,9 +679,10 @@ async def create( Args: account_id: Define configurations using a unique string identifier. - integration: Connects to a PlanetScale database using credentials managed by Cloudflare. The - Cloudflare account must already be linked to PlanetScale in the Hyperdrive - dashboard. + integration: Selects a PlanetScale database and provisions credentials managed by Cloudflare + when creating a Hyperdrive configuration. The Cloudflare account must already be + linked to PlanetScale in the Hyperdrive dashboard. The selection is returned as + read-only metadata and cannot be changed with replace or update operations. name: The name of the Hyperdrive configuration. Used to identify the configuration in the Cloudflare dashboard and API. @@ -773,7 +779,9 @@ async def update( The request must include the name and complete origin connection details. Omitted caching settings are reset to their defaults, while omitted mTLS settings and origin - connection limits are preserved. Use the update operation to modify only + connection limits are preserved. The integration association is set only during + creation and cannot be changed; omit the integration field even when replacing + an integration-backed configuration. Use the update operation to modify only selected fields. Args: @@ -955,7 +963,9 @@ async def edit( """Updates and returns the specified fields of the Hyperdrive configuration. Custom - caching settings are not kept if caching is disabled. + caching settings are not kept if caching is disabled. For an integration-backed + configuration, the integration association is preserved but cannot be changed; + omit the integration field. Args: account_id: Define configurations using a unique string identifier. diff --git a/src/cloudflare/resources/iam/resource_groups.py b/src/cloudflare/resources/iam/resource_groups.py index 6974e0c8ce1..3be6d5fbddf 100644 --- a/src/cloudflare/resources/iam/resource_groups.py +++ b/src/cloudflare/resources/iam/resource_groups.py @@ -70,7 +70,7 @@ def create( name: Name of the resource group - scope: A scope is a combination of scope objects which provides additional context. + scope: The scope associated to the resource group extra_headers: Send extra headers @@ -125,7 +125,7 @@ def update( name: Name of the resource group - scope: A scope is a combination of scope objects which provides additional context. + scope: The scope associated to the resource group extra_headers: Send extra headers @@ -352,7 +352,7 @@ async def create( name: Name of the resource group - scope: A scope is a combination of scope objects which provides additional context. + scope: The scope associated to the resource group extra_headers: Send extra headers @@ -407,7 +407,7 @@ async def update( name: Name of the resource group - scope: A scope is a combination of scope objects which provides additional context. + scope: The scope associated to the resource group extra_headers: Send extra headers diff --git a/src/cloudflare/resources/intel/api.md b/src/cloudflare/resources/intel/api.md index aeec89a4452..edefa589d28 100644 --- a/src/cloudflare/resources/intel/api.md +++ b/src/cloudflare/resources/intel/api.md @@ -103,7 +103,7 @@ Methods: Types: ```python -from cloudflare.types.intel import Whois, WhoisGetResponse +from cloudflare.types.intel import WhoisGetResponse ``` Methods: diff --git a/src/cloudflare/resources/k2/__init__.py b/src/cloudflare/resources/k2/__init__.py new file mode 100644 index 00000000000..2ab1034b2b8 --- /dev/null +++ b/src/cloudflare/resources/k2/__init__.py @@ -0,0 +1,33 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from .k2 import ( + K2Resource, + AsyncK2Resource, + K2ResourceWithRawResponse, + AsyncK2ResourceWithRawResponse, + K2ResourceWithStreamingResponse, + AsyncK2ResourceWithStreamingResponse, +) +from .streams import ( + StreamsResource, + AsyncStreamsResource, + StreamsResourceWithRawResponse, + AsyncStreamsResourceWithRawResponse, + StreamsResourceWithStreamingResponse, + AsyncStreamsResourceWithStreamingResponse, +) + +__all__ = [ + "StreamsResource", + "AsyncStreamsResource", + "StreamsResourceWithRawResponse", + "AsyncStreamsResourceWithRawResponse", + "StreamsResourceWithStreamingResponse", + "AsyncStreamsResourceWithStreamingResponse", + "K2Resource", + "AsyncK2Resource", + "K2ResourceWithRawResponse", + "AsyncK2ResourceWithRawResponse", + "K2ResourceWithStreamingResponse", + "AsyncK2ResourceWithStreamingResponse", +] diff --git a/src/cloudflare/resources/k2/api.md b/src/cloudflare/resources/k2/api.md new file mode 100644 index 00000000000..a41f9ad2cd1 --- /dev/null +++ b/src/cloudflare/resources/k2/api.md @@ -0,0 +1,34 @@ +# K2 + +## Streams + +Types: + +```python +from cloudflare.types.k2 import ( + StreamCreateResponse, + StreamUpdateResponse, + StreamListResponse, + StreamGetResponse, +) +``` + +Methods: + +- client.k2.streams.create(\*, account_id, \*\*params) -> StreamCreateResponse +- client.k2.streams.update(stream_id, \*, account_id, \*\*params) -> StreamUpdateResponse +- client.k2.streams.list(\*, account_id, \*\*params) -> SyncV4PagePaginationArray[StreamListResponse] +- client.k2.streams.delete(stream_id, \*, account_id) -> object +- client.k2.streams.get(stream_id, \*, account_id) -> StreamGetResponse + +### Subscriptions + +Types: + +```python +from cloudflare.types.k2.streams import SubscriptionListResponse +``` + +Methods: + +- client.k2.streams.subscriptions.list(stream_id, \*, account_id) -> SyncSinglePage[SubscriptionListResponse] diff --git a/src/cloudflare/resources/k2/k2.py b/src/cloudflare/resources/k2/k2.py new file mode 100644 index 00000000000..d9010cb57d2 --- /dev/null +++ b/src/cloudflare/resources/k2/k2.py @@ -0,0 +1,102 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from ..._compat import cached_property +from ..._resource import SyncAPIResource, AsyncAPIResource +from .streams.streams import ( + StreamsResource, + AsyncStreamsResource, + StreamsResourceWithRawResponse, + AsyncStreamsResourceWithRawResponse, + StreamsResourceWithStreamingResponse, + AsyncStreamsResourceWithStreamingResponse, +) + +__all__ = ["K2Resource", "AsyncK2Resource"] + + +class K2Resource(SyncAPIResource): + @cached_property + def streams(self) -> StreamsResource: + return StreamsResource(self._client) + + @cached_property + def with_raw_response(self) -> K2ResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers + """ + return K2ResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> K2ResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response + """ + return K2ResourceWithStreamingResponse(self) + + +class AsyncK2Resource(AsyncAPIResource): + @cached_property + def streams(self) -> AsyncStreamsResource: + return AsyncStreamsResource(self._client) + + @cached_property + def with_raw_response(self) -> AsyncK2ResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers + """ + return AsyncK2ResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncK2ResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response + """ + return AsyncK2ResourceWithStreamingResponse(self) + + +class K2ResourceWithRawResponse: + def __init__(self, k2: K2Resource) -> None: + self._k2 = k2 + + @cached_property + def streams(self) -> StreamsResourceWithRawResponse: + return StreamsResourceWithRawResponse(self._k2.streams) + + +class AsyncK2ResourceWithRawResponse: + def __init__(self, k2: AsyncK2Resource) -> None: + self._k2 = k2 + + @cached_property + def streams(self) -> AsyncStreamsResourceWithRawResponse: + return AsyncStreamsResourceWithRawResponse(self._k2.streams) + + +class K2ResourceWithStreamingResponse: + def __init__(self, k2: K2Resource) -> None: + self._k2 = k2 + + @cached_property + def streams(self) -> StreamsResourceWithStreamingResponse: + return StreamsResourceWithStreamingResponse(self._k2.streams) + + +class AsyncK2ResourceWithStreamingResponse: + def __init__(self, k2: AsyncK2Resource) -> None: + self._k2 = k2 + + @cached_property + def streams(self) -> AsyncStreamsResourceWithStreamingResponse: + return AsyncStreamsResourceWithStreamingResponse(self._k2.streams) diff --git a/src/cloudflare/resources/k2/streams/__init__.py b/src/cloudflare/resources/k2/streams/__init__.py new file mode 100644 index 00000000000..8041b14ff24 --- /dev/null +++ b/src/cloudflare/resources/k2/streams/__init__.py @@ -0,0 +1,33 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from .streams import ( + StreamsResource, + AsyncStreamsResource, + StreamsResourceWithRawResponse, + AsyncStreamsResourceWithRawResponse, + StreamsResourceWithStreamingResponse, + AsyncStreamsResourceWithStreamingResponse, +) +from .subscriptions import ( + SubscriptionsResource, + AsyncSubscriptionsResource, + SubscriptionsResourceWithRawResponse, + AsyncSubscriptionsResourceWithRawResponse, + SubscriptionsResourceWithStreamingResponse, + AsyncSubscriptionsResourceWithStreamingResponse, +) + +__all__ = [ + "SubscriptionsResource", + "AsyncSubscriptionsResource", + "SubscriptionsResourceWithRawResponse", + "AsyncSubscriptionsResourceWithRawResponse", + "SubscriptionsResourceWithStreamingResponse", + "AsyncSubscriptionsResourceWithStreamingResponse", + "StreamsResource", + "AsyncStreamsResource", + "StreamsResourceWithRawResponse", + "AsyncStreamsResourceWithRawResponse", + "StreamsResourceWithStreamingResponse", + "AsyncStreamsResourceWithStreamingResponse", +] diff --git a/src/cloudflare/resources/k2/streams/streams.py b/src/cloudflare/resources/k2/streams/streams.py new file mode 100644 index 00000000000..135c4c3af5e --- /dev/null +++ b/src/cloudflare/resources/k2/streams/streams.py @@ -0,0 +1,724 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Type, cast + +import httpx + +from ...._types import Body, Omit, Query, Headers, NotGiven, omit, not_given +from ...._utils import path_template, maybe_transform, async_maybe_transform +from ...._compat import cached_property +from ....types.k2 import stream_list_params, stream_create_params, stream_update_params +from ...._resource import SyncAPIResource, AsyncAPIResource +from ...._response import ( + to_raw_response_wrapper, + to_streamed_response_wrapper, + async_to_raw_response_wrapper, + async_to_streamed_response_wrapper, +) +from ...._wrappers import ResultWrapper +from ....pagination import SyncV4PagePaginationArray, AsyncV4PagePaginationArray +from .subscriptions import ( + SubscriptionsResource, + AsyncSubscriptionsResource, + SubscriptionsResourceWithRawResponse, + AsyncSubscriptionsResourceWithRawResponse, + SubscriptionsResourceWithStreamingResponse, + AsyncSubscriptionsResourceWithStreamingResponse, +) +from ...._base_client import AsyncPaginator, make_request_options +from ....types.k2.stream_get_response import StreamGetResponse +from ....types.k2.stream_list_response import StreamListResponse +from ....types.k2.stream_create_response import StreamCreateResponse +from ....types.k2.stream_update_response import StreamUpdateResponse + +__all__ = ["StreamsResource", "AsyncStreamsResource"] + + +class StreamsResource(SyncAPIResource): + @cached_property + def subscriptions(self) -> SubscriptionsResource: + return SubscriptionsResource(self._client) + + @cached_property + def with_raw_response(self) -> StreamsResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers + """ + return StreamsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> StreamsResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response + """ + return StreamsResourceWithStreamingResponse(self) + + def create( + self, + *, + account_id: str, + name: str, + http: stream_create_params.HTTP | Omit = omit, + retention_seconds: int | Omit = omit, + worker_binding: stream_create_params.WorkerBinding | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> StreamCreateResponse: + """Create a new K2 stream. + + HTTP is disabled when `http` is omitted. Enabled HTTP + requires authentication and allows all origins unless `authentication` or `cors` + say otherwise. At least one input must be enabled. + + Args: + account_id: Specifies the public ID of the account. + + name: Specifies the name of the K2 stream. + + http: Configures the HTTP endpoint. Disabling HTTP keeps `authentication` and `cors`, + so enabling it again restores them. + + retention_seconds: Sets the record retention period from 1 hour (3600 seconds) to 30 days (2592000 + seconds), inclusive. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + return self._post( + path_template("/accounts/{account_id}/k2/streams", account_id=account_id), + body=maybe_transform( + { + "name": name, + "http": http, + "retention_seconds": retention_seconds, + "worker_binding": worker_binding, + }, + stream_create_params.StreamCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[StreamCreateResponse]._unwrapper, + ), + cast_to=cast(Type[StreamCreateResponse], ResultWrapper[StreamCreateResponse]), + ) + + def update( + self, + stream_id: str, + *, + account_id: str, + http: stream_update_params.HTTP | Omit = omit, + retention_seconds: int | Omit = omit, + worker_binding: stream_update_params.WorkerBinding | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> StreamUpdateResponse: + """Update a K2 stream. + + Omitted `http` settings, such as `authentication` and + `cors`, keep their current values. Disabling HTTP keeps them, so enabling HTTP + again restores them. At least one input must remain enabled. + + Args: + account_id: Specifies the public ID of the account. + + stream_id: Specifies the public ID of the K2 stream. + + http: Configures the HTTP endpoint. Disabling HTTP keeps `authentication` and `cors`, + so enabling it again restores them. + + retention_seconds: Sets the record retention period from 1 hour (3600 seconds) to 30 days (2592000 + seconds), inclusive. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not stream_id: + raise ValueError(f"Expected a non-empty value for `stream_id` but received {stream_id!r}") + return self._patch( + path_template("/accounts/{account_id}/k2/streams/{stream_id}", account_id=account_id, stream_id=stream_id), + body=maybe_transform( + { + "http": http, + "retention_seconds": retention_seconds, + "worker_binding": worker_binding, + }, + stream_update_params.StreamUpdateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[StreamUpdateResponse]._unwrapper, + ), + cast_to=cast(Type[StreamUpdateResponse], ResultWrapper[StreamUpdateResponse]), + ) + + def list( + self, + *, + account_id: str, + name: str | Omit = omit, + page: int | Omit = omit, + per_page: int | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> SyncV4PagePaginationArray[StreamListResponse]: + """ + List or filter K2 streams in an account. + + Args: + account_id: Specifies the public ID of the account. + + name: Filters K2 streams by name using a case-insensitive substring. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + return self._get_api_list( + path_template("/accounts/{account_id}/k2/streams", account_id=account_id), + page=SyncV4PagePaginationArray[StreamListResponse], + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "name": name, + "page": page, + "per_page": per_page, + }, + stream_list_params.StreamListParams, + ), + ), + model=StreamListResponse, + ) + + def delete( + self, + stream_id: str, + *, + account_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> object: + """Delete a K2 stream in an account. + + Deleting a stream that does not exist also + succeeds. + + Args: + account_id: Specifies the public ID of the account. + + stream_id: Specifies the public ID of the K2 stream. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not stream_id: + raise ValueError(f"Expected a non-empty value for `stream_id` but received {stream_id!r}") + return self._delete( + path_template("/accounts/{account_id}/k2/streams/{stream_id}", account_id=account_id, stream_id=stream_id), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[object]._unwrapper, + ), + cast_to=cast(Type[object], ResultWrapper[object]), + ) + + def get( + self, + stream_id: str, + *, + account_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> StreamGetResponse: + """ + Get K2 stream details. + + Args: + account_id: Specifies the public ID of the account. + + stream_id: Specifies the public ID of the K2 stream. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not stream_id: + raise ValueError(f"Expected a non-empty value for `stream_id` but received {stream_id!r}") + return self._get( + path_template("/accounts/{account_id}/k2/streams/{stream_id}", account_id=account_id, stream_id=stream_id), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[StreamGetResponse]._unwrapper, + ), + cast_to=cast(Type[StreamGetResponse], ResultWrapper[StreamGetResponse]), + ) + + +class AsyncStreamsResource(AsyncAPIResource): + @cached_property + def subscriptions(self) -> AsyncSubscriptionsResource: + return AsyncSubscriptionsResource(self._client) + + @cached_property + def with_raw_response(self) -> AsyncStreamsResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers + """ + return AsyncStreamsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncStreamsResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response + """ + return AsyncStreamsResourceWithStreamingResponse(self) + + async def create( + self, + *, + account_id: str, + name: str, + http: stream_create_params.HTTP | Omit = omit, + retention_seconds: int | Omit = omit, + worker_binding: stream_create_params.WorkerBinding | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> StreamCreateResponse: + """Create a new K2 stream. + + HTTP is disabled when `http` is omitted. Enabled HTTP + requires authentication and allows all origins unless `authentication` or `cors` + say otherwise. At least one input must be enabled. + + Args: + account_id: Specifies the public ID of the account. + + name: Specifies the name of the K2 stream. + + http: Configures the HTTP endpoint. Disabling HTTP keeps `authentication` and `cors`, + so enabling it again restores them. + + retention_seconds: Sets the record retention period from 1 hour (3600 seconds) to 30 days (2592000 + seconds), inclusive. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + return await self._post( + path_template("/accounts/{account_id}/k2/streams", account_id=account_id), + body=await async_maybe_transform( + { + "name": name, + "http": http, + "retention_seconds": retention_seconds, + "worker_binding": worker_binding, + }, + stream_create_params.StreamCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[StreamCreateResponse]._unwrapper, + ), + cast_to=cast(Type[StreamCreateResponse], ResultWrapper[StreamCreateResponse]), + ) + + async def update( + self, + stream_id: str, + *, + account_id: str, + http: stream_update_params.HTTP | Omit = omit, + retention_seconds: int | Omit = omit, + worker_binding: stream_update_params.WorkerBinding | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> StreamUpdateResponse: + """Update a K2 stream. + + Omitted `http` settings, such as `authentication` and + `cors`, keep their current values. Disabling HTTP keeps them, so enabling HTTP + again restores them. At least one input must remain enabled. + + Args: + account_id: Specifies the public ID of the account. + + stream_id: Specifies the public ID of the K2 stream. + + http: Configures the HTTP endpoint. Disabling HTTP keeps `authentication` and `cors`, + so enabling it again restores them. + + retention_seconds: Sets the record retention period from 1 hour (3600 seconds) to 30 days (2592000 + seconds), inclusive. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not stream_id: + raise ValueError(f"Expected a non-empty value for `stream_id` but received {stream_id!r}") + return await self._patch( + path_template("/accounts/{account_id}/k2/streams/{stream_id}", account_id=account_id, stream_id=stream_id), + body=await async_maybe_transform( + { + "http": http, + "retention_seconds": retention_seconds, + "worker_binding": worker_binding, + }, + stream_update_params.StreamUpdateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[StreamUpdateResponse]._unwrapper, + ), + cast_to=cast(Type[StreamUpdateResponse], ResultWrapper[StreamUpdateResponse]), + ) + + def list( + self, + *, + account_id: str, + name: str | Omit = omit, + page: int | Omit = omit, + per_page: int | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> AsyncPaginator[StreamListResponse, AsyncV4PagePaginationArray[StreamListResponse]]: + """ + List or filter K2 streams in an account. + + Args: + account_id: Specifies the public ID of the account. + + name: Filters K2 streams by name using a case-insensitive substring. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + return self._get_api_list( + path_template("/accounts/{account_id}/k2/streams", account_id=account_id), + page=AsyncV4PagePaginationArray[StreamListResponse], + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "name": name, + "page": page, + "per_page": per_page, + }, + stream_list_params.StreamListParams, + ), + ), + model=StreamListResponse, + ) + + async def delete( + self, + stream_id: str, + *, + account_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> object: + """Delete a K2 stream in an account. + + Deleting a stream that does not exist also + succeeds. + + Args: + account_id: Specifies the public ID of the account. + + stream_id: Specifies the public ID of the K2 stream. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not stream_id: + raise ValueError(f"Expected a non-empty value for `stream_id` but received {stream_id!r}") + return await self._delete( + path_template("/accounts/{account_id}/k2/streams/{stream_id}", account_id=account_id, stream_id=stream_id), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[object]._unwrapper, + ), + cast_to=cast(Type[object], ResultWrapper[object]), + ) + + async def get( + self, + stream_id: str, + *, + account_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> StreamGetResponse: + """ + Get K2 stream details. + + Args: + account_id: Specifies the public ID of the account. + + stream_id: Specifies the public ID of the K2 stream. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not stream_id: + raise ValueError(f"Expected a non-empty value for `stream_id` but received {stream_id!r}") + return await self._get( + path_template("/accounts/{account_id}/k2/streams/{stream_id}", account_id=account_id, stream_id=stream_id), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[StreamGetResponse]._unwrapper, + ), + cast_to=cast(Type[StreamGetResponse], ResultWrapper[StreamGetResponse]), + ) + + +class StreamsResourceWithRawResponse: + def __init__(self, streams: StreamsResource) -> None: + self._streams = streams + + self.create = to_raw_response_wrapper( + streams.create, + ) + self.update = to_raw_response_wrapper( + streams.update, + ) + self.list = to_raw_response_wrapper( + streams.list, + ) + self.delete = to_raw_response_wrapper( + streams.delete, + ) + self.get = to_raw_response_wrapper( + streams.get, + ) + + @cached_property + def subscriptions(self) -> SubscriptionsResourceWithRawResponse: + return SubscriptionsResourceWithRawResponse(self._streams.subscriptions) + + +class AsyncStreamsResourceWithRawResponse: + def __init__(self, streams: AsyncStreamsResource) -> None: + self._streams = streams + + self.create = async_to_raw_response_wrapper( + streams.create, + ) + self.update = async_to_raw_response_wrapper( + streams.update, + ) + self.list = async_to_raw_response_wrapper( + streams.list, + ) + self.delete = async_to_raw_response_wrapper( + streams.delete, + ) + self.get = async_to_raw_response_wrapper( + streams.get, + ) + + @cached_property + def subscriptions(self) -> AsyncSubscriptionsResourceWithRawResponse: + return AsyncSubscriptionsResourceWithRawResponse(self._streams.subscriptions) + + +class StreamsResourceWithStreamingResponse: + def __init__(self, streams: StreamsResource) -> None: + self._streams = streams + + self.create = to_streamed_response_wrapper( + streams.create, + ) + self.update = to_streamed_response_wrapper( + streams.update, + ) + self.list = to_streamed_response_wrapper( + streams.list, + ) + self.delete = to_streamed_response_wrapper( + streams.delete, + ) + self.get = to_streamed_response_wrapper( + streams.get, + ) + + @cached_property + def subscriptions(self) -> SubscriptionsResourceWithStreamingResponse: + return SubscriptionsResourceWithStreamingResponse(self._streams.subscriptions) + + +class AsyncStreamsResourceWithStreamingResponse: + def __init__(self, streams: AsyncStreamsResource) -> None: + self._streams = streams + + self.create = async_to_streamed_response_wrapper( + streams.create, + ) + self.update = async_to_streamed_response_wrapper( + streams.update, + ) + self.list = async_to_streamed_response_wrapper( + streams.list, + ) + self.delete = async_to_streamed_response_wrapper( + streams.delete, + ) + self.get = async_to_streamed_response_wrapper( + streams.get, + ) + + @cached_property + def subscriptions(self) -> AsyncSubscriptionsResourceWithStreamingResponse: + return AsyncSubscriptionsResourceWithStreamingResponse(self._streams.subscriptions) diff --git a/src/cloudflare/resources/magic_cloud_networking/catalog_syncs/prebuilt_policies.py b/src/cloudflare/resources/k2/streams/subscriptions.py similarity index 51% rename from src/cloudflare/resources/magic_cloud_networking/catalog_syncs/prebuilt_policies.py rename to src/cloudflare/resources/k2/streams/subscriptions.py index bd08faf33cb..4cf46f7e661 100644 --- a/src/cloudflare/resources/magic_cloud_networking/catalog_syncs/prebuilt_policies.py +++ b/src/cloudflare/resources/k2/streams/subscriptions.py @@ -2,12 +2,10 @@ from __future__ import annotations -from typing_extensions import Literal - import httpx -from ...._types import Body, Omit, Query, Headers, NotGiven, omit, not_given -from ...._utils import path_template, maybe_transform +from ...._types import Body, Query, Headers, NotGiven, not_given +from ...._utils import path_template from ...._compat import cached_property from ...._resource import SyncAPIResource, AsyncAPIResource from ...._response import ( @@ -18,49 +16,53 @@ ) from ....pagination import SyncSinglePage, AsyncSinglePage from ...._base_client import AsyncPaginator, make_request_options -from ....types.magic_cloud_networking.catalog_syncs import prebuilt_policy_list_params -from ....types.magic_cloud_networking.catalog_syncs.prebuilt_policy_list_response import PrebuiltPolicyListResponse +from ....types.k2.streams.subscription_list_response import SubscriptionListResponse -__all__ = ["PrebuiltPoliciesResource", "AsyncPrebuiltPoliciesResource"] +__all__ = ["SubscriptionsResource", "AsyncSubscriptionsResource"] -class PrebuiltPoliciesResource(SyncAPIResource): +class SubscriptionsResource(SyncAPIResource): @cached_property - def with_raw_response(self) -> PrebuiltPoliciesResourceWithRawResponse: + def with_raw_response(self) -> SubscriptionsResourceWithRawResponse: """ This property can be used as a prefix for any HTTP method call to return the raw response object instead of the parsed content. For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers """ - return PrebuiltPoliciesResourceWithRawResponse(self) + return SubscriptionsResourceWithRawResponse(self) @cached_property - def with_streaming_response(self) -> PrebuiltPoliciesResourceWithStreamingResponse: + def with_streaming_response(self) -> SubscriptionsResourceWithStreamingResponse: """ An alternative to `.with_raw_response` that doesn't eagerly read the response body. For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response """ - return PrebuiltPoliciesResourceWithStreamingResponse(self) + return SubscriptionsResourceWithStreamingResponse(self) def list( self, + stream_id: str, *, account_id: str, - destination_type: Literal["NONE", "ZERO_TRUST_LIST"] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> SyncSinglePage[PrebuiltPolicyListResponse]: - """ - List prebuilt catalog sync policies (Closed Beta). + ) -> SyncSinglePage[SubscriptionListResponse]: + """Lists every subscription on one stream, oldest first. + + Lag uses committed + positions, not reserved read positions. A failed tail observation preserves + subscription metadata and returns unavailable lag. Args: - destination_type: Specify type of destination, omit to return all. + account_id: Specifies the public ID of the account. + + stream_id: Specifies the public ID of the K2 stream. extra_headers: Send extra headers @@ -72,59 +74,64 @@ def list( """ if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not stream_id: + raise ValueError(f"Expected a non-empty value for `stream_id` but received {stream_id!r}") return self._get_api_list( - path_template("/accounts/{account_id}/magic/cloud/catalog-syncs/prebuilt-policies", account_id=account_id), - page=SyncSinglePage[PrebuiltPolicyListResponse], + path_template( + "/accounts/{account_id}/k2/streams/{stream_id}/subscriptions", + account_id=account_id, + stream_id=stream_id, + ), + page=SyncSinglePage[SubscriptionListResponse], options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - query=maybe_transform( - {"destination_type": destination_type}, prebuilt_policy_list_params.PrebuiltPolicyListParams - ), + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), - model=PrebuiltPolicyListResponse, + model=SubscriptionListResponse, ) -class AsyncPrebuiltPoliciesResource(AsyncAPIResource): +class AsyncSubscriptionsResource(AsyncAPIResource): @cached_property - def with_raw_response(self) -> AsyncPrebuiltPoliciesResourceWithRawResponse: + def with_raw_response(self) -> AsyncSubscriptionsResourceWithRawResponse: """ This property can be used as a prefix for any HTTP method call to return the raw response object instead of the parsed content. For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers """ - return AsyncPrebuiltPoliciesResourceWithRawResponse(self) + return AsyncSubscriptionsResourceWithRawResponse(self) @cached_property - def with_streaming_response(self) -> AsyncPrebuiltPoliciesResourceWithStreamingResponse: + def with_streaming_response(self) -> AsyncSubscriptionsResourceWithStreamingResponse: """ An alternative to `.with_raw_response` that doesn't eagerly read the response body. For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response """ - return AsyncPrebuiltPoliciesResourceWithStreamingResponse(self) + return AsyncSubscriptionsResourceWithStreamingResponse(self) def list( self, + stream_id: str, *, account_id: str, - destination_type: Literal["NONE", "ZERO_TRUST_LIST"] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> AsyncPaginator[PrebuiltPolicyListResponse, AsyncSinglePage[PrebuiltPolicyListResponse]]: - """ - List prebuilt catalog sync policies (Closed Beta). + ) -> AsyncPaginator[SubscriptionListResponse, AsyncSinglePage[SubscriptionListResponse]]: + """Lists every subscription on one stream, oldest first. + + Lag uses committed + positions, not reserved read positions. A failed tail observation preserves + subscription metadata and returns unavailable lag. Args: - destination_type: Specify type of destination, omit to return all. + account_id: Specifies the public ID of the account. + + stream_id: Specifies the public ID of the K2 stream. extra_headers: Send extra headers @@ -136,53 +143,53 @@ def list( """ if not account_id: raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not stream_id: + raise ValueError(f"Expected a non-empty value for `stream_id` but received {stream_id!r}") return self._get_api_list( - path_template("/accounts/{account_id}/magic/cloud/catalog-syncs/prebuilt-policies", account_id=account_id), - page=AsyncSinglePage[PrebuiltPolicyListResponse], + path_template( + "/accounts/{account_id}/k2/streams/{stream_id}/subscriptions", + account_id=account_id, + stream_id=stream_id, + ), + page=AsyncSinglePage[SubscriptionListResponse], options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - query=maybe_transform( - {"destination_type": destination_type}, prebuilt_policy_list_params.PrebuiltPolicyListParams - ), + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), - model=PrebuiltPolicyListResponse, + model=SubscriptionListResponse, ) -class PrebuiltPoliciesResourceWithRawResponse: - def __init__(self, prebuilt_policies: PrebuiltPoliciesResource) -> None: - self._prebuilt_policies = prebuilt_policies +class SubscriptionsResourceWithRawResponse: + def __init__(self, subscriptions: SubscriptionsResource) -> None: + self._subscriptions = subscriptions self.list = to_raw_response_wrapper( - prebuilt_policies.list, + subscriptions.list, ) -class AsyncPrebuiltPoliciesResourceWithRawResponse: - def __init__(self, prebuilt_policies: AsyncPrebuiltPoliciesResource) -> None: - self._prebuilt_policies = prebuilt_policies +class AsyncSubscriptionsResourceWithRawResponse: + def __init__(self, subscriptions: AsyncSubscriptionsResource) -> None: + self._subscriptions = subscriptions self.list = async_to_raw_response_wrapper( - prebuilt_policies.list, + subscriptions.list, ) -class PrebuiltPoliciesResourceWithStreamingResponse: - def __init__(self, prebuilt_policies: PrebuiltPoliciesResource) -> None: - self._prebuilt_policies = prebuilt_policies +class SubscriptionsResourceWithStreamingResponse: + def __init__(self, subscriptions: SubscriptionsResource) -> None: + self._subscriptions = subscriptions self.list = to_streamed_response_wrapper( - prebuilt_policies.list, + subscriptions.list, ) -class AsyncPrebuiltPoliciesResourceWithStreamingResponse: - def __init__(self, prebuilt_policies: AsyncPrebuiltPoliciesResource) -> None: - self._prebuilt_policies = prebuilt_policies +class AsyncSubscriptionsResourceWithStreamingResponse: + def __init__(self, subscriptions: AsyncSubscriptionsResource) -> None: + self._subscriptions = subscriptions self.list = async_to_streamed_response_wrapper( - prebuilt_policies.list, + subscriptions.list, ) diff --git a/src/cloudflare/resources/kv/namespaces/namespaces.py b/src/cloudflare/resources/kv/namespaces/namespaces.py index 99041d89557..b3c65373949 100644 --- a/src/cloudflare/resources/kv/namespaces/namespaces.py +++ b/src/cloudflare/resources/kv/namespaces/namespaces.py @@ -98,6 +98,7 @@ def create( account_id: str, title: str, jurisdiction: Literal["eu", "fedramp", "us"] | Omit = omit, + mode: Literal["instant"] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -120,6 +121,11 @@ def create( jurisdiction: Specify the jurisdiction to restrict the KV namespace to durably store data within. Can only be set at namespace creation time. + mode: The mode of the Workers KV namespace. Specify `instant` when creating a + namespace to create a KV Instant namespace. Omit this field when creating a + namespace to create a classic namespace. Currently, `instant` is the only + supported explicit value. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -136,6 +142,7 @@ def create( { "title": title, "jurisdiction": jurisdiction, + "mode": mode, }, namespace_create_params.NamespaceCreateParams, ), @@ -583,6 +590,7 @@ async def create( account_id: str, title: str, jurisdiction: Literal["eu", "fedramp", "us"] | Omit = omit, + mode: Literal["instant"] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -605,6 +613,11 @@ async def create( jurisdiction: Specify the jurisdiction to restrict the KV namespace to durably store data within. Can only be set at namespace creation time. + mode: The mode of the Workers KV namespace. Specify `instant` when creating a + namespace to create a KV Instant namespace. Omit this field when creating a + namespace to create a classic namespace. Currently, `instant` is the only + supported explicit value. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -621,6 +634,7 @@ async def create( { "title": title, "jurisdiction": jurisdiction, + "mode": mode, }, namespace_create_params.NamespaceCreateParams, ), diff --git a/src/cloudflare/resources/load_balancers/load_balancers.py b/src/cloudflare/resources/load_balancers/load_balancers.py index c272468d1d3..ca4c9ab9c49 100644 --- a/src/cloudflare/resources/load_balancers/load_balancers.py +++ b/src/cloudflare/resources/load_balancers/load_balancers.py @@ -146,6 +146,7 @@ def create( enabled: bool | Omit = omit, location_strategy: LocationStrategyParam | Omit = omit, networks: SequenceNotStr[str] | Omit = omit, + pool_sets: Iterable[load_balancer_create_params.PoolSet] | Omit = omit, pop_pools: Dict[str, SequenceNotStr[str]] | Omit = omit, proxied: bool | Omit = omit, random_steering: RandomSteeringParam | Omit = omit, @@ -201,6 +202,13 @@ def create( networks: List of networks where Load Balancer or Pool is enabled. + pool_sets: An optional list of pool sets, evaluated in array order with first match wins. + Pool sets are independent from the standard steering fields (`region_pools` / + `country_pools` / `pop_pools` / `default_pools` / `steering_policy` / + `random_steering` / `fallback_pool` / `rules`). On a PATCH, an empty array + (`pool_sets: []`) clears all pool sets, while omitting the field leaves existing + pool sets unchanged. + pop_pools: Enterprise only: A mapping of Cloudflare PoP identifiers to a list of pool IDs (ordered by their failover priority) for the PoP (datacenter). Any PoPs not explicitly defined will fall back to using the corresponding country_pool, then @@ -320,6 +328,7 @@ def create( "enabled": enabled, "location_strategy": location_strategy, "networks": networks, + "pool_sets": pool_sets, "pop_pools": pop_pools, "proxied": proxied, "random_steering": random_steering, @@ -358,6 +367,7 @@ def update( enabled: bool | Omit = omit, location_strategy: LocationStrategyParam | Omit = omit, networks: SequenceNotStr[str] | Omit = omit, + pool_sets: Iterable[load_balancer_update_params.PoolSet] | Omit = omit, pop_pools: Dict[str, SequenceNotStr[str]] | Omit = omit, proxied: bool | Omit = omit, random_steering: RandomSteeringParam | Omit = omit, @@ -413,6 +423,13 @@ def update( networks: List of networks where Load Balancer or Pool is enabled. + pool_sets: An optional list of pool sets, evaluated in array order with first match wins. + Pool sets are independent from the standard steering fields (`region_pools` / + `country_pools` / `pop_pools` / `default_pools` / `steering_policy` / + `random_steering` / `fallback_pool` / `rules`). On a PATCH, an empty array + (`pool_sets: []`) clears all pool sets, while omitting the field leaves existing + pool sets unchanged. + pop_pools: Enterprise only: A mapping of Cloudflare PoP identifiers to a list of pool IDs (ordered by their failover priority) for the PoP (datacenter). Any PoPs not explicitly defined will fall back to using the corresponding country_pool, then @@ -535,6 +552,7 @@ def update( "enabled": enabled, "location_strategy": location_strategy, "networks": networks, + "pool_sets": pool_sets, "pop_pools": pop_pools, "proxied": proxied, "random_steering": random_steering, @@ -686,6 +704,7 @@ def edit( location_strategy: LocationStrategyParam | Omit = omit, name: str | Omit = omit, networks: SequenceNotStr[str] | Omit = omit, + pool_sets: Iterable[load_balancer_edit_params.PoolSet] | Omit = omit, pop_pools: Dict[str, SequenceNotStr[str]] | Omit = omit, proxied: bool | Omit = omit, random_steering: RandomSteeringParam | Omit = omit, @@ -742,6 +761,13 @@ def edit( networks: List of networks where Load Balancer or Pool is enabled. + pool_sets: An optional list of pool sets, evaluated in array order with first match wins. + Pool sets are independent from the standard steering fields (`region_pools` / + `country_pools` / `pop_pools` / `default_pools` / `steering_policy` / + `random_steering` / `fallback_pool` / `rules`). On a PATCH, an empty array + (`pool_sets: []`) clears all pool sets, while omitting the field leaves existing + pool sets unchanged. + pop_pools: Enterprise only: A mapping of Cloudflare PoP identifiers to a list of pool IDs (ordered by their failover priority) for the PoP (datacenter). Any PoPs not explicitly defined will fall back to using the corresponding country_pool, then @@ -864,6 +890,7 @@ def edit( "location_strategy": location_strategy, "name": name, "networks": networks, + "pool_sets": pool_sets, "pop_pools": pop_pools, "proxied": proxied, "random_steering": random_steering, @@ -1006,6 +1033,7 @@ async def create( enabled: bool | Omit = omit, location_strategy: LocationStrategyParam | Omit = omit, networks: SequenceNotStr[str] | Omit = omit, + pool_sets: Iterable[load_balancer_create_params.PoolSet] | Omit = omit, pop_pools: Dict[str, SequenceNotStr[str]] | Omit = omit, proxied: bool | Omit = omit, random_steering: RandomSteeringParam | Omit = omit, @@ -1061,6 +1089,13 @@ async def create( networks: List of networks where Load Balancer or Pool is enabled. + pool_sets: An optional list of pool sets, evaluated in array order with first match wins. + Pool sets are independent from the standard steering fields (`region_pools` / + `country_pools` / `pop_pools` / `default_pools` / `steering_policy` / + `random_steering` / `fallback_pool` / `rules`). On a PATCH, an empty array + (`pool_sets: []`) clears all pool sets, while omitting the field leaves existing + pool sets unchanged. + pop_pools: Enterprise only: A mapping of Cloudflare PoP identifiers to a list of pool IDs (ordered by their failover priority) for the PoP (datacenter). Any PoPs not explicitly defined will fall back to using the corresponding country_pool, then @@ -1180,6 +1215,7 @@ async def create( "enabled": enabled, "location_strategy": location_strategy, "networks": networks, + "pool_sets": pool_sets, "pop_pools": pop_pools, "proxied": proxied, "random_steering": random_steering, @@ -1218,6 +1254,7 @@ async def update( enabled: bool | Omit = omit, location_strategy: LocationStrategyParam | Omit = omit, networks: SequenceNotStr[str] | Omit = omit, + pool_sets: Iterable[load_balancer_update_params.PoolSet] | Omit = omit, pop_pools: Dict[str, SequenceNotStr[str]] | Omit = omit, proxied: bool | Omit = omit, random_steering: RandomSteeringParam | Omit = omit, @@ -1273,6 +1310,13 @@ async def update( networks: List of networks where Load Balancer or Pool is enabled. + pool_sets: An optional list of pool sets, evaluated in array order with first match wins. + Pool sets are independent from the standard steering fields (`region_pools` / + `country_pools` / `pop_pools` / `default_pools` / `steering_policy` / + `random_steering` / `fallback_pool` / `rules`). On a PATCH, an empty array + (`pool_sets: []`) clears all pool sets, while omitting the field leaves existing + pool sets unchanged. + pop_pools: Enterprise only: A mapping of Cloudflare PoP identifiers to a list of pool IDs (ordered by their failover priority) for the PoP (datacenter). Any PoPs not explicitly defined will fall back to using the corresponding country_pool, then @@ -1395,6 +1439,7 @@ async def update( "enabled": enabled, "location_strategy": location_strategy, "networks": networks, + "pool_sets": pool_sets, "pop_pools": pop_pools, "proxied": proxied, "random_steering": random_steering, @@ -1546,6 +1591,7 @@ async def edit( location_strategy: LocationStrategyParam | Omit = omit, name: str | Omit = omit, networks: SequenceNotStr[str] | Omit = omit, + pool_sets: Iterable[load_balancer_edit_params.PoolSet] | Omit = omit, pop_pools: Dict[str, SequenceNotStr[str]] | Omit = omit, proxied: bool | Omit = omit, random_steering: RandomSteeringParam | Omit = omit, @@ -1602,6 +1648,13 @@ async def edit( networks: List of networks where Load Balancer or Pool is enabled. + pool_sets: An optional list of pool sets, evaluated in array order with first match wins. + Pool sets are independent from the standard steering fields (`region_pools` / + `country_pools` / `pop_pools` / `default_pools` / `steering_policy` / + `random_steering` / `fallback_pool` / `rules`). On a PATCH, an empty array + (`pool_sets: []`) clears all pool sets, while omitting the field leaves existing + pool sets unchanged. + pop_pools: Enterprise only: A mapping of Cloudflare PoP identifiers to a list of pool IDs (ordered by their failover priority) for the PoP (datacenter). Any PoPs not explicitly defined will fall back to using the corresponding country_pool, then @@ -1724,6 +1777,7 @@ async def edit( "location_strategy": location_strategy, "name": name, "networks": networks, + "pool_sets": pool_sets, "pop_pools": pop_pools, "proxied": proxied, "random_steering": random_steering, diff --git a/src/cloudflare/resources/load_balancers/monitors/monitors.py b/src/cloudflare/resources/load_balancers/monitors/monitors.py index 321c38845c0..e533d1058fd 100644 --- a/src/cloudflare/resources/load_balancers/monitors/monitors.py +++ b/src/cloudflare/resources/load_balancers/monitors/monitors.py @@ -555,7 +555,7 @@ def get( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Monitor: """ - List a single configured monitor for an account. + Fetch a single configured monitor for an account. Args: account_id: Identifier. @@ -1101,7 +1101,7 @@ async def get( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Monitor: """ - List a single configured monitor for an account. + Fetch a single configured monitor for an account. Args: account_id: Identifier. diff --git a/src/cloudflare/resources/load_balancers/pools/pools.py b/src/cloudflare/resources/load_balancers/pools/pools.py index fd71c20242e..ad224039e90 100644 --- a/src/cloudflare/resources/load_balancers/pools/pools.py +++ b/src/cloudflare/resources/load_balancers/pools/pools.py @@ -15,7 +15,7 @@ HealthResourceWithStreamingResponse, AsyncHealthResourceWithStreamingResponse, ) -from ...._types import Body, Omit, Query, Headers, NotGiven, omit, not_given +from ...._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given from ...._utils import path_template, maybe_transform, async_maybe_transform from ...._compat import cached_property from .references import ( @@ -88,14 +88,17 @@ def create( account_id: str, name: str, origins: Iterable[OriginParam], + check_regions: Optional[List[CheckRegion]] | Omit = omit, description: str | Omit = omit, enabled: bool | Omit = omit, + health_sources: Optional[List[Literal["local", "regional", "global"]]] | Omit = omit, latitude: float | Omit = omit, load_shedding: Optional[LoadSheddingParam] | Omit = omit, longitude: float | Omit = omit, minimum_origins: int | Omit = omit, monitor: str | Omit = omit, monitor_group: str | Omit = omit, + networks: SequenceNotStr[str] | Omit = omit, notification_email: str | Omit = omit, notification_filter: Optional[NotificationFilterParam] | Omit = omit, origin_steering: Optional[OriginSteeringParam] | Omit = omit, @@ -118,12 +121,24 @@ def create( origins: The list of origins within this pool. Traffic directed at this pool is balanced across all currently healthy origins, provided the pool itself is healthy. + check_regions: A list of regions from which to run health checks. Null means every Cloudflare + data center. + description: A human-readable description of the pool. enabled: Whether to enable (the default) or disable this pool. Disabled pools will not receive traffic and are excluded from health checks. Disabling a pool will cause any load balancers using it to failover to the next pool (if any). + health_sources: A list of health sources, ordered from highest to lowest priority, used to + evaluate individual origin health and overall pool health. The load balancer + uses the first source that has data and falls back to the next. Currently + accepted values are null or the exact array ["regional", "global"]; any other + combination is rejected. Null (the default) behaves like ["local", "global"]. + ["regional", "global"] makes each region steer on its own health, falling back + to the global decision when a region has no fresh data. Setting regional + requires at least one region in check_regions. + latitude: The latitude of the data center containing the origins used in this pool in decimal degrees. If this is set, longitude must also be set. @@ -142,6 +157,8 @@ def create( monitor_group: The ID of the Monitor Group to use for checking the health of origins within this pool. + networks: List of networks where Load Balancer or Pool is enabled. + notification_email: This field is now deprecated. It has been moved to Cloudflare's Centralized Notification service https://developers.cloudflare.com/fundamentals/notifications/. The email address @@ -170,14 +187,17 @@ def create( { "name": name, "origins": origins, + "check_regions": check_regions, "description": description, "enabled": enabled, + "health_sources": health_sources, "latitude": latitude, "load_shedding": load_shedding, "longitude": longitude, "minimum_origins": minimum_origins, "monitor": monitor, "monitor_group": monitor_group, + "networks": networks, "notification_email": notification_email, "notification_filter": notification_filter, "origin_steering": origin_steering, @@ -211,6 +231,7 @@ def update( minimum_origins: int | Omit = omit, monitor: str | Omit = omit, monitor_group: str | Omit = omit, + networks: SequenceNotStr[str] | Omit = omit, notification_email: str | Omit = omit, notification_filter: Optional[NotificationFilterParam] | Omit = omit, origin_steering: Optional[OriginSteeringParam] | Omit = omit, @@ -269,6 +290,8 @@ def update( monitor_group: The ID of the Monitor Group to use for checking the health of origins within this pool. + networks: List of networks where Load Balancer or Pool is enabled. + notification_email: This field is now deprecated. It has been moved to Cloudflare's Centralized Notification service https://developers.cloudflare.com/fundamentals/notifications/. The email address @@ -311,6 +334,7 @@ def update( "minimum_origins": minimum_origins, "monitor": monitor, "monitor_group": monitor_group, + "networks": networks, "notification_email": notification_email, "notification_filter": notification_filter, "origin_steering": origin_steering, @@ -478,6 +502,7 @@ def edit( monitor: str | Omit = omit, monitor_group: str | Omit = omit, name: str | Omit = omit, + networks: SequenceNotStr[str] | Omit = omit, notification_email: str | Omit = omit, notification_filter: Optional[NotificationFilterParam] | Omit = omit, origin_steering: Optional[OriginSteeringParam] | Omit = omit, @@ -534,6 +559,8 @@ def edit( name: A short name (tag) for the pool. Only alphanumeric characters, hyphens, and underscores are allowed. + networks: List of networks where Load Balancer or Pool is enabled. + notification_email: This field is now deprecated. It has been moved to Cloudflare's Centralized Notification service https://developers.cloudflare.com/fundamentals/notifications/. The email address @@ -578,6 +605,7 @@ def edit( "monitor": monitor, "monitor_group": monitor_group, "name": name, + "networks": networks, "notification_email": notification_email, "notification_filter": notification_filter, "origin_steering": origin_steering, @@ -674,14 +702,17 @@ async def create( account_id: str, name: str, origins: Iterable[OriginParam], + check_regions: Optional[List[CheckRegion]] | Omit = omit, description: str | Omit = omit, enabled: bool | Omit = omit, + health_sources: Optional[List[Literal["local", "regional", "global"]]] | Omit = omit, latitude: float | Omit = omit, load_shedding: Optional[LoadSheddingParam] | Omit = omit, longitude: float | Omit = omit, minimum_origins: int | Omit = omit, monitor: str | Omit = omit, monitor_group: str | Omit = omit, + networks: SequenceNotStr[str] | Omit = omit, notification_email: str | Omit = omit, notification_filter: Optional[NotificationFilterParam] | Omit = omit, origin_steering: Optional[OriginSteeringParam] | Omit = omit, @@ -704,12 +735,24 @@ async def create( origins: The list of origins within this pool. Traffic directed at this pool is balanced across all currently healthy origins, provided the pool itself is healthy. + check_regions: A list of regions from which to run health checks. Null means every Cloudflare + data center. + description: A human-readable description of the pool. enabled: Whether to enable (the default) or disable this pool. Disabled pools will not receive traffic and are excluded from health checks. Disabling a pool will cause any load balancers using it to failover to the next pool (if any). + health_sources: A list of health sources, ordered from highest to lowest priority, used to + evaluate individual origin health and overall pool health. The load balancer + uses the first source that has data and falls back to the next. Currently + accepted values are null or the exact array ["regional", "global"]; any other + combination is rejected. Null (the default) behaves like ["local", "global"]. + ["regional", "global"] makes each region steer on its own health, falling back + to the global decision when a region has no fresh data. Setting regional + requires at least one region in check_regions. + latitude: The latitude of the data center containing the origins used in this pool in decimal degrees. If this is set, longitude must also be set. @@ -728,6 +771,8 @@ async def create( monitor_group: The ID of the Monitor Group to use for checking the health of origins within this pool. + networks: List of networks where Load Balancer or Pool is enabled. + notification_email: This field is now deprecated. It has been moved to Cloudflare's Centralized Notification service https://developers.cloudflare.com/fundamentals/notifications/. The email address @@ -756,14 +801,17 @@ async def create( { "name": name, "origins": origins, + "check_regions": check_regions, "description": description, "enabled": enabled, + "health_sources": health_sources, "latitude": latitude, "load_shedding": load_shedding, "longitude": longitude, "minimum_origins": minimum_origins, "monitor": monitor, "monitor_group": monitor_group, + "networks": networks, "notification_email": notification_email, "notification_filter": notification_filter, "origin_steering": origin_steering, @@ -797,6 +845,7 @@ async def update( minimum_origins: int | Omit = omit, monitor: str | Omit = omit, monitor_group: str | Omit = omit, + networks: SequenceNotStr[str] | Omit = omit, notification_email: str | Omit = omit, notification_filter: Optional[NotificationFilterParam] | Omit = omit, origin_steering: Optional[OriginSteeringParam] | Omit = omit, @@ -855,6 +904,8 @@ async def update( monitor_group: The ID of the Monitor Group to use for checking the health of origins within this pool. + networks: List of networks where Load Balancer or Pool is enabled. + notification_email: This field is now deprecated. It has been moved to Cloudflare's Centralized Notification service https://developers.cloudflare.com/fundamentals/notifications/. The email address @@ -897,6 +948,7 @@ async def update( "minimum_origins": minimum_origins, "monitor": monitor, "monitor_group": monitor_group, + "networks": networks, "notification_email": notification_email, "notification_filter": notification_filter, "origin_steering": origin_steering, @@ -1064,6 +1116,7 @@ async def edit( monitor: str | Omit = omit, monitor_group: str | Omit = omit, name: str | Omit = omit, + networks: SequenceNotStr[str] | Omit = omit, notification_email: str | Omit = omit, notification_filter: Optional[NotificationFilterParam] | Omit = omit, origin_steering: Optional[OriginSteeringParam] | Omit = omit, @@ -1120,6 +1173,8 @@ async def edit( name: A short name (tag) for the pool. Only alphanumeric characters, hyphens, and underscores are allowed. + networks: List of networks where Load Balancer or Pool is enabled. + notification_email: This field is now deprecated. It has been moved to Cloudflare's Centralized Notification service https://developers.cloudflare.com/fundamentals/notifications/. The email address @@ -1164,6 +1219,7 @@ async def edit( "monitor": monitor, "monitor_group": monitor_group, "name": name, + "networks": networks, "notification_email": notification_email, "notification_filter": notification_filter, "origin_steering": origin_steering, diff --git a/src/cloudflare/resources/logpush/datasets/fields.py b/src/cloudflare/resources/logpush/datasets/fields.py index 03912ec0e98..a74df8a0bd0 100644 --- a/src/cloudflare/resources/logpush/datasets/fields.py +++ b/src/cloudflare/resources/logpush/datasets/fields.py @@ -49,6 +49,7 @@ def get( dataset_id: Literal[ "access_requests", "account_abuse_protection_events", + "ai_gateway_events", "audit_logs", "audit_logs_v2", "biso_user_actions", @@ -173,6 +174,7 @@ async def get( dataset_id: Literal[ "access_requests", "account_abuse_protection_events", + "ai_gateway_events", "audit_logs", "audit_logs_v2", "biso_user_actions", diff --git a/src/cloudflare/resources/logpush/datasets/jobs.py b/src/cloudflare/resources/logpush/datasets/jobs.py index cb61aedd33a..4974d1e5613 100644 --- a/src/cloudflare/resources/logpush/datasets/jobs.py +++ b/src/cloudflare/resources/logpush/datasets/jobs.py @@ -49,6 +49,7 @@ def get( dataset_id: Literal[ "access_requests", "account_abuse_protection_events", + "ai_gateway_events", "audit_logs", "audit_logs_v2", "biso_user_actions", @@ -168,6 +169,7 @@ def get( dataset_id: Literal[ "access_requests", "account_abuse_protection_events", + "ai_gateway_events", "audit_logs", "audit_logs_v2", "biso_user_actions", diff --git a/src/cloudflare/resources/logpush/jobs.py b/src/cloudflare/resources/logpush/jobs.py index a1e9c3837e1..6fbdb33465a 100644 --- a/src/cloudflare/resources/logpush/jobs.py +++ b/src/cloudflare/resources/logpush/jobs.py @@ -58,6 +58,7 @@ def create( Literal[ "access_requests", "account_abuse_protection_events", + "ai_gateway_events", "audit_logs", "audit_logs_v2", "biso_user_actions", @@ -578,6 +579,7 @@ async def create( Literal[ "access_requests", "account_abuse_protection_events", + "ai_gateway_events", "audit_logs", "audit_logs_v2", "biso_user_actions", diff --git a/src/cloudflare/resources/magic_cloud_networking/__init__.py b/src/cloudflare/resources/magic_cloud_networking/__init__.py deleted file mode 100644 index 3c758eda376..00000000000 --- a/src/cloudflare/resources/magic_cloud_networking/__init__.py +++ /dev/null @@ -1,75 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from .on_ramps import ( - OnRampsResource, - AsyncOnRampsResource, - OnRampsResourceWithRawResponse, - AsyncOnRampsResourceWithRawResponse, - OnRampsResourceWithStreamingResponse, - AsyncOnRampsResourceWithStreamingResponse, -) -from .resources import ( - ResourcesResource, - AsyncResourcesResource, - ResourcesResourceWithRawResponse, - AsyncResourcesResourceWithRawResponse, - ResourcesResourceWithStreamingResponse, - AsyncResourcesResourceWithStreamingResponse, -) -from .catalog_syncs import ( - CatalogSyncsResource, - AsyncCatalogSyncsResource, - CatalogSyncsResourceWithRawResponse, - AsyncCatalogSyncsResourceWithRawResponse, - CatalogSyncsResourceWithStreamingResponse, - AsyncCatalogSyncsResourceWithStreamingResponse, -) -from .cloud_integrations import ( - CloudIntegrationsResource, - AsyncCloudIntegrationsResource, - CloudIntegrationsResourceWithRawResponse, - AsyncCloudIntegrationsResourceWithRawResponse, - CloudIntegrationsResourceWithStreamingResponse, - AsyncCloudIntegrationsResourceWithStreamingResponse, -) -from .magic_cloud_networking import ( - MagicCloudNetworkingResource, - AsyncMagicCloudNetworkingResource, - MagicCloudNetworkingResourceWithRawResponse, - AsyncMagicCloudNetworkingResourceWithRawResponse, - MagicCloudNetworkingResourceWithStreamingResponse, - AsyncMagicCloudNetworkingResourceWithStreamingResponse, -) - -__all__ = [ - "CatalogSyncsResource", - "AsyncCatalogSyncsResource", - "CatalogSyncsResourceWithRawResponse", - "AsyncCatalogSyncsResourceWithRawResponse", - "CatalogSyncsResourceWithStreamingResponse", - "AsyncCatalogSyncsResourceWithStreamingResponse", - "OnRampsResource", - "AsyncOnRampsResource", - "OnRampsResourceWithRawResponse", - "AsyncOnRampsResourceWithRawResponse", - "OnRampsResourceWithStreamingResponse", - "AsyncOnRampsResourceWithStreamingResponse", - "CloudIntegrationsResource", - "AsyncCloudIntegrationsResource", - "CloudIntegrationsResourceWithRawResponse", - "AsyncCloudIntegrationsResourceWithRawResponse", - "CloudIntegrationsResourceWithStreamingResponse", - "AsyncCloudIntegrationsResourceWithStreamingResponse", - "ResourcesResource", - "AsyncResourcesResource", - "ResourcesResourceWithRawResponse", - "AsyncResourcesResourceWithRawResponse", - "ResourcesResourceWithStreamingResponse", - "AsyncResourcesResourceWithStreamingResponse", - "MagicCloudNetworkingResource", - "AsyncMagicCloudNetworkingResource", - "MagicCloudNetworkingResourceWithRawResponse", - "AsyncMagicCloudNetworkingResourceWithRawResponse", - "MagicCloudNetworkingResourceWithStreamingResponse", - "AsyncMagicCloudNetworkingResourceWithStreamingResponse", -] diff --git a/src/cloudflare/resources/magic_cloud_networking/api.md b/src/cloudflare/resources/magic_cloud_networking/api.md deleted file mode 100644 index 77aecf0410b..00000000000 --- a/src/cloudflare/resources/magic_cloud_networking/api.md +++ /dev/null @@ -1,135 +0,0 @@ -# MagicCloudNetworking - -## CatalogSyncs - -Types: - -```python -from cloudflare.types.magic_cloud_networking import ( - CatalogSyncCreateResponse, - CatalogSyncUpdateResponse, - CatalogSyncListResponse, - CatalogSyncDeleteResponse, - CatalogSyncEditResponse, - CatalogSyncGetResponse, - CatalogSyncRefreshResponse, -) -``` - -Methods: - -- client.magic_cloud_networking.catalog_syncs.create(\*, account_id, \*\*params) -> CatalogSyncCreateResponse -- client.magic_cloud_networking.catalog_syncs.update(sync_id, \*, account_id, \*\*params) -> CatalogSyncUpdateResponse -- client.magic_cloud_networking.catalog_syncs.list(\*, account_id) -> SyncSinglePage[CatalogSyncListResponse] -- client.magic_cloud_networking.catalog_syncs.delete(sync_id, \*, account_id, \*\*params) -> CatalogSyncDeleteResponse -- client.magic_cloud_networking.catalog_syncs.edit(sync_id, \*, account_id, \*\*params) -> CatalogSyncEditResponse -- client.magic_cloud_networking.catalog_syncs.get(sync_id, \*, account_id) -> CatalogSyncGetResponse -- client.magic_cloud_networking.catalog_syncs.refresh(sync_id, \*, account_id) -> str - -### PrebuiltPolicies - -Types: - -```python -from cloudflare.types.magic_cloud_networking.catalog_syncs import PrebuiltPolicyListResponse -``` - -Methods: - -- client.magic_cloud_networking.catalog_syncs.prebuilt_policies.list(\*, account_id, \*\*params) -> SyncSinglePage[PrebuiltPolicyListResponse] - -## OnRamps - -Types: - -```python -from cloudflare.types.magic_cloud_networking import ( - OnRampCreateResponse, - OnRampUpdateResponse, - OnRampListResponse, - OnRampDeleteResponse, - OnRampApplyResponse, - OnRampEditResponse, - OnRampGetResponse, - OnRampPlanResponse, -) -``` - -Methods: - -- client.magic_cloud_networking.on_ramps.create(\*, account_id, \*\*params) -> OnRampCreateResponse -- client.magic_cloud_networking.on_ramps.update(onramp_id, \*, account_id, \*\*params) -> OnRampUpdateResponse -- client.magic_cloud_networking.on_ramps.list(\*, account_id, \*\*params) -> SyncSinglePage[OnRampListResponse] -- client.magic_cloud_networking.on_ramps.delete(onramp_id, \*, account_id, \*\*params) -> OnRampDeleteResponse -- client.magic_cloud_networking.on_ramps.apply(onramp_id, \*, account_id) -> OnRampApplyResponse -- client.magic_cloud_networking.on_ramps.edit(onramp_id, \*, account_id, \*\*params) -> OnRampEditResponse -- client.magic_cloud_networking.on_ramps.export(onramp_id, \*, account_id) -> BinaryAPIResponse -- client.magic_cloud_networking.on_ramps.get(onramp_id, \*, account_id, \*\*params) -> OnRampGetResponse -- client.magic_cloud_networking.on_ramps.plan(onramp_id, \*, account_id) -> OnRampPlanResponse - -### AddressSpaces - -Types: - -```python -from cloudflare.types.magic_cloud_networking.on_ramps import ( - AddressSpaceUpdateResponse, - AddressSpaceListResponse, - AddressSpaceEditResponse, -) -``` - -Methods: - -- client.magic_cloud_networking.on_ramps.address_spaces.update(\*, account_id, \*\*params) -> AddressSpaceUpdateResponse -- client.magic_cloud_networking.on_ramps.address_spaces.list(\*, account_id) -> AddressSpaceListResponse -- client.magic_cloud_networking.on_ramps.address_spaces.edit(\*, account_id, \*\*params) -> AddressSpaceEditResponse - -## CloudIntegrations - -Types: - -```python -from cloudflare.types.magic_cloud_networking import ( - CloudIntegrationCreateResponse, - CloudIntegrationUpdateResponse, - CloudIntegrationListResponse, - CloudIntegrationDeleteResponse, - CloudIntegrationDiscoverResponse, - CloudIntegrationDiscoverAllResponse, - CloudIntegrationEditResponse, - CloudIntegrationGetResponse, - CloudIntegrationInitialSetupResponse, -) -``` - -Methods: - -- client.magic_cloud_networking.cloud_integrations.create(\*, account_id, \*\*params) -> CloudIntegrationCreateResponse -- client.magic_cloud_networking.cloud_integrations.update(provider_id, \*, account_id, \*\*params) -> CloudIntegrationUpdateResponse -- client.magic_cloud_networking.cloud_integrations.list(\*, account_id, \*\*params) -> SyncSinglePage[CloudIntegrationListResponse] -- client.magic_cloud_networking.cloud_integrations.delete(provider_id, \*, account_id) -> CloudIntegrationDeleteResponse -- client.magic_cloud_networking.cloud_integrations.discover(provider_id, \*, account_id, \*\*params) -> CloudIntegrationDiscoverResponse -- client.magic_cloud_networking.cloud_integrations.discover_all(\*, account_id) -> CloudIntegrationDiscoverAllResponse -- client.magic_cloud_networking.cloud_integrations.edit(provider_id, \*, account_id, \*\*params) -> CloudIntegrationEditResponse -- client.magic_cloud_networking.cloud_integrations.get(provider_id, \*, account_id, \*\*params) -> CloudIntegrationGetResponse -- client.magic_cloud_networking.cloud_integrations.initial_setup(provider_id, \*, account_id) -> CloudIntegrationInitialSetupResponse - -## Resources - -Types: - -```python -from cloudflare.types.magic_cloud_networking import ( - ResourceListResponse, - ResourceGetResponse, - ResourcePolicyPreviewResponse, -) -``` - -Methods: - -- client.magic_cloud_networking.resources.list(\*, account_id, \*\*params) -> SyncV4PagePaginationArray[ResourceListResponse] -- client.magic_cloud_networking.resources.export(\*, account_id, \*\*params) -> BinaryAPIResponse -- client.magic_cloud_networking.resources.get(resource_id, \*, account_id, \*\*params) -> ResourceGetResponse -- client.magic_cloud_networking.resources.policy_preview(\*, account_id, \*\*params) -> str diff --git a/src/cloudflare/resources/magic_cloud_networking/catalog_syncs/__init__.py b/src/cloudflare/resources/magic_cloud_networking/catalog_syncs/__init__.py deleted file mode 100644 index f9bf98aaa56..00000000000 --- a/src/cloudflare/resources/magic_cloud_networking/catalog_syncs/__init__.py +++ /dev/null @@ -1,33 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from .catalog_syncs import ( - CatalogSyncsResource, - AsyncCatalogSyncsResource, - CatalogSyncsResourceWithRawResponse, - AsyncCatalogSyncsResourceWithRawResponse, - CatalogSyncsResourceWithStreamingResponse, - AsyncCatalogSyncsResourceWithStreamingResponse, -) -from .prebuilt_policies import ( - PrebuiltPoliciesResource, - AsyncPrebuiltPoliciesResource, - PrebuiltPoliciesResourceWithRawResponse, - AsyncPrebuiltPoliciesResourceWithRawResponse, - PrebuiltPoliciesResourceWithStreamingResponse, - AsyncPrebuiltPoliciesResourceWithStreamingResponse, -) - -__all__ = [ - "PrebuiltPoliciesResource", - "AsyncPrebuiltPoliciesResource", - "PrebuiltPoliciesResourceWithRawResponse", - "AsyncPrebuiltPoliciesResourceWithRawResponse", - "PrebuiltPoliciesResourceWithStreamingResponse", - "AsyncPrebuiltPoliciesResourceWithStreamingResponse", - "CatalogSyncsResource", - "AsyncCatalogSyncsResource", - "CatalogSyncsResourceWithRawResponse", - "AsyncCatalogSyncsResourceWithRawResponse", - "CatalogSyncsResourceWithStreamingResponse", - "AsyncCatalogSyncsResourceWithStreamingResponse", -] diff --git a/src/cloudflare/resources/magic_cloud_networking/catalog_syncs/catalog_syncs.py b/src/cloudflare/resources/magic_cloud_networking/catalog_syncs/catalog_syncs.py deleted file mode 100644 index 71e11119d11..00000000000 --- a/src/cloudflare/resources/magic_cloud_networking/catalog_syncs/catalog_syncs.py +++ /dev/null @@ -1,881 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing import Type, cast -from typing_extensions import Literal - -import httpx - -from ...._types import Body, Omit, Query, Headers, NotGiven, omit, not_given -from ...._utils import path_template, maybe_transform, strip_not_given, async_maybe_transform -from ...._compat import cached_property -from ...._resource import SyncAPIResource, AsyncAPIResource -from ...._response import ( - to_raw_response_wrapper, - to_streamed_response_wrapper, - async_to_raw_response_wrapper, - async_to_streamed_response_wrapper, -) -from ...._wrappers import ResultWrapper -from ....pagination import SyncSinglePage, AsyncSinglePage -from ...._base_client import AsyncPaginator, make_request_options -from .prebuilt_policies import ( - PrebuiltPoliciesResource, - AsyncPrebuiltPoliciesResource, - PrebuiltPoliciesResourceWithRawResponse, - AsyncPrebuiltPoliciesResourceWithRawResponse, - PrebuiltPoliciesResourceWithStreamingResponse, - AsyncPrebuiltPoliciesResourceWithStreamingResponse, -) -from ....types.magic_cloud_networking import ( - catalog_sync_edit_params, - catalog_sync_create_params, - catalog_sync_delete_params, - catalog_sync_update_params, -) -from ....types.magic_cloud_networking.catalog_sync_get_response import CatalogSyncGetResponse -from ....types.magic_cloud_networking.catalog_sync_edit_response import CatalogSyncEditResponse -from ....types.magic_cloud_networking.catalog_sync_list_response import CatalogSyncListResponse -from ....types.magic_cloud_networking.catalog_sync_create_response import CatalogSyncCreateResponse -from ....types.magic_cloud_networking.catalog_sync_delete_response import CatalogSyncDeleteResponse -from ....types.magic_cloud_networking.catalog_sync_update_response import CatalogSyncUpdateResponse -from ....types.magic_cloud_networking.catalog_sync_refresh_response import CatalogSyncRefreshResponse - -__all__ = ["CatalogSyncsResource", "AsyncCatalogSyncsResource"] - - -class CatalogSyncsResource(SyncAPIResource): - @cached_property - def prebuilt_policies(self) -> PrebuiltPoliciesResource: - return PrebuiltPoliciesResource(self._client) - - @cached_property - def with_raw_response(self) -> CatalogSyncsResourceWithRawResponse: - """ - This property can be used as a prefix for any HTTP method call to return - the raw response object instead of the parsed content. - - For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers - """ - return CatalogSyncsResourceWithRawResponse(self) - - @cached_property - def with_streaming_response(self) -> CatalogSyncsResourceWithStreamingResponse: - """ - An alternative to `.with_raw_response` that doesn't eagerly read the response body. - - For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response - """ - return CatalogSyncsResourceWithStreamingResponse(self) - - def create( - self, - *, - account_id: str, - destination_type: Literal["NONE", "ZERO_TRUST_LIST"], - name: str, - update_mode: Literal["AUTO", "MANUAL"], - description: str | Omit = omit, - policy: str | Omit = omit, - forwarded: str | Omit = omit, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> CatalogSyncCreateResponse: - """ - Create a new Catalog Sync (Closed Beta). - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not account_id: - raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - extra_headers = {**strip_not_given({"forwarded": forwarded}), **(extra_headers or {})} - return self._post( - path_template("/accounts/{account_id}/magic/cloud/catalog-syncs", account_id=account_id), - body=maybe_transform( - { - "destination_type": destination_type, - "name": name, - "update_mode": update_mode, - "description": description, - "policy": policy, - }, - catalog_sync_create_params.CatalogSyncCreateParams, - ), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - post_parser=ResultWrapper[CatalogSyncCreateResponse]._unwrapper, - ), - cast_to=cast(Type[CatalogSyncCreateResponse], ResultWrapper[CatalogSyncCreateResponse]), - ) - - def update( - self, - sync_id: str, - *, - account_id: str, - description: str | Omit = omit, - name: str | Omit = omit, - policy: str | Omit = omit, - update_mode: Literal["AUTO", "MANUAL"] | Omit = omit, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> CatalogSyncUpdateResponse: - """ - Update a Catalog Sync (Closed Beta). - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not account_id: - raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not sync_id: - raise ValueError(f"Expected a non-empty value for `sync_id` but received {sync_id!r}") - return self._put( - path_template( - "/accounts/{account_id}/magic/cloud/catalog-syncs/{sync_id}", account_id=account_id, sync_id=sync_id - ), - body=maybe_transform( - { - "description": description, - "name": name, - "policy": policy, - "update_mode": update_mode, - }, - catalog_sync_update_params.CatalogSyncUpdateParams, - ), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - post_parser=ResultWrapper[CatalogSyncUpdateResponse]._unwrapper, - ), - cast_to=cast(Type[CatalogSyncUpdateResponse], ResultWrapper[CatalogSyncUpdateResponse]), - ) - - def list( - self, - *, - account_id: str, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> SyncSinglePage[CatalogSyncListResponse]: - """ - List Catalog Syncs (Closed Beta). - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not account_id: - raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - return self._get_api_list( - path_template("/accounts/{account_id}/magic/cloud/catalog-syncs", account_id=account_id), - page=SyncSinglePage[CatalogSyncListResponse], - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - model=CatalogSyncListResponse, - ) - - def delete( - self, - sync_id: str, - *, - account_id: str, - delete_destination: bool | Omit = omit, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> CatalogSyncDeleteResponse: - """ - Delete a Catalog Sync (Closed Beta). - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not account_id: - raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not sync_id: - raise ValueError(f"Expected a non-empty value for `sync_id` but received {sync_id!r}") - return self._delete( - path_template( - "/accounts/{account_id}/magic/cloud/catalog-syncs/{sync_id}", account_id=account_id, sync_id=sync_id - ), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - query=maybe_transform( - {"delete_destination": delete_destination}, catalog_sync_delete_params.CatalogSyncDeleteParams - ), - post_parser=ResultWrapper[CatalogSyncDeleteResponse]._unwrapper, - ), - cast_to=cast(Type[CatalogSyncDeleteResponse], ResultWrapper[CatalogSyncDeleteResponse]), - ) - - def edit( - self, - sync_id: str, - *, - account_id: str, - description: str | Omit = omit, - name: str | Omit = omit, - policy: str | Omit = omit, - update_mode: Literal["AUTO", "MANUAL"] | Omit = omit, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> CatalogSyncEditResponse: - """ - Update a Catalog Sync (Closed Beta). - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not account_id: - raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not sync_id: - raise ValueError(f"Expected a non-empty value for `sync_id` but received {sync_id!r}") - return self._patch( - path_template( - "/accounts/{account_id}/magic/cloud/catalog-syncs/{sync_id}", account_id=account_id, sync_id=sync_id - ), - body=maybe_transform( - { - "description": description, - "name": name, - "policy": policy, - "update_mode": update_mode, - }, - catalog_sync_edit_params.CatalogSyncEditParams, - ), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - post_parser=ResultWrapper[CatalogSyncEditResponse]._unwrapper, - ), - cast_to=cast(Type[CatalogSyncEditResponse], ResultWrapper[CatalogSyncEditResponse]), - ) - - def get( - self, - sync_id: str, - *, - account_id: str, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> CatalogSyncGetResponse: - """ - Read a Catalog Sync (Closed Beta). - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not account_id: - raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not sync_id: - raise ValueError(f"Expected a non-empty value for `sync_id` but received {sync_id!r}") - return self._get( - path_template( - "/accounts/{account_id}/magic/cloud/catalog-syncs/{sync_id}", account_id=account_id, sync_id=sync_id - ), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - post_parser=ResultWrapper[CatalogSyncGetResponse]._unwrapper, - ), - cast_to=cast(Type[CatalogSyncGetResponse], ResultWrapper[CatalogSyncGetResponse]), - ) - - def refresh( - self, - sync_id: str, - *, - account_id: str, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> str: - """ - Refresh a Catalog Sync's destination by running the sync policy against latest - resource catalog (Closed Beta). - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not account_id: - raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not sync_id: - raise ValueError(f"Expected a non-empty value for `sync_id` but received {sync_id!r}") - return self._post( - path_template( - "/accounts/{account_id}/magic/cloud/catalog-syncs/{sync_id}/refresh", - account_id=account_id, - sync_id=sync_id, - ), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - post_parser=ResultWrapper[CatalogSyncRefreshResponse]._unwrapper, - ), - cast_to=cast(Type[str], ResultWrapper[str]), - ) - - -class AsyncCatalogSyncsResource(AsyncAPIResource): - @cached_property - def prebuilt_policies(self) -> AsyncPrebuiltPoliciesResource: - return AsyncPrebuiltPoliciesResource(self._client) - - @cached_property - def with_raw_response(self) -> AsyncCatalogSyncsResourceWithRawResponse: - """ - This property can be used as a prefix for any HTTP method call to return - the raw response object instead of the parsed content. - - For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers - """ - return AsyncCatalogSyncsResourceWithRawResponse(self) - - @cached_property - def with_streaming_response(self) -> AsyncCatalogSyncsResourceWithStreamingResponse: - """ - An alternative to `.with_raw_response` that doesn't eagerly read the response body. - - For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response - """ - return AsyncCatalogSyncsResourceWithStreamingResponse(self) - - async def create( - self, - *, - account_id: str, - destination_type: Literal["NONE", "ZERO_TRUST_LIST"], - name: str, - update_mode: Literal["AUTO", "MANUAL"], - description: str | Omit = omit, - policy: str | Omit = omit, - forwarded: str | Omit = omit, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> CatalogSyncCreateResponse: - """ - Create a new Catalog Sync (Closed Beta). - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not account_id: - raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - extra_headers = {**strip_not_given({"forwarded": forwarded}), **(extra_headers or {})} - return await self._post( - path_template("/accounts/{account_id}/magic/cloud/catalog-syncs", account_id=account_id), - body=await async_maybe_transform( - { - "destination_type": destination_type, - "name": name, - "update_mode": update_mode, - "description": description, - "policy": policy, - }, - catalog_sync_create_params.CatalogSyncCreateParams, - ), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - post_parser=ResultWrapper[CatalogSyncCreateResponse]._unwrapper, - ), - cast_to=cast(Type[CatalogSyncCreateResponse], ResultWrapper[CatalogSyncCreateResponse]), - ) - - async def update( - self, - sync_id: str, - *, - account_id: str, - description: str | Omit = omit, - name: str | Omit = omit, - policy: str | Omit = omit, - update_mode: Literal["AUTO", "MANUAL"] | Omit = omit, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> CatalogSyncUpdateResponse: - """ - Update a Catalog Sync (Closed Beta). - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not account_id: - raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not sync_id: - raise ValueError(f"Expected a non-empty value for `sync_id` but received {sync_id!r}") - return await self._put( - path_template( - "/accounts/{account_id}/magic/cloud/catalog-syncs/{sync_id}", account_id=account_id, sync_id=sync_id - ), - body=await async_maybe_transform( - { - "description": description, - "name": name, - "policy": policy, - "update_mode": update_mode, - }, - catalog_sync_update_params.CatalogSyncUpdateParams, - ), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - post_parser=ResultWrapper[CatalogSyncUpdateResponse]._unwrapper, - ), - cast_to=cast(Type[CatalogSyncUpdateResponse], ResultWrapper[CatalogSyncUpdateResponse]), - ) - - def list( - self, - *, - account_id: str, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> AsyncPaginator[CatalogSyncListResponse, AsyncSinglePage[CatalogSyncListResponse]]: - """ - List Catalog Syncs (Closed Beta). - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not account_id: - raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - return self._get_api_list( - path_template("/accounts/{account_id}/magic/cloud/catalog-syncs", account_id=account_id), - page=AsyncSinglePage[CatalogSyncListResponse], - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - model=CatalogSyncListResponse, - ) - - async def delete( - self, - sync_id: str, - *, - account_id: str, - delete_destination: bool | Omit = omit, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> CatalogSyncDeleteResponse: - """ - Delete a Catalog Sync (Closed Beta). - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not account_id: - raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not sync_id: - raise ValueError(f"Expected a non-empty value for `sync_id` but received {sync_id!r}") - return await self._delete( - path_template( - "/accounts/{account_id}/magic/cloud/catalog-syncs/{sync_id}", account_id=account_id, sync_id=sync_id - ), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - query=await async_maybe_transform( - {"delete_destination": delete_destination}, catalog_sync_delete_params.CatalogSyncDeleteParams - ), - post_parser=ResultWrapper[CatalogSyncDeleteResponse]._unwrapper, - ), - cast_to=cast(Type[CatalogSyncDeleteResponse], ResultWrapper[CatalogSyncDeleteResponse]), - ) - - async def edit( - self, - sync_id: str, - *, - account_id: str, - description: str | Omit = omit, - name: str | Omit = omit, - policy: str | Omit = omit, - update_mode: Literal["AUTO", "MANUAL"] | Omit = omit, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> CatalogSyncEditResponse: - """ - Update a Catalog Sync (Closed Beta). - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not account_id: - raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not sync_id: - raise ValueError(f"Expected a non-empty value for `sync_id` but received {sync_id!r}") - return await self._patch( - path_template( - "/accounts/{account_id}/magic/cloud/catalog-syncs/{sync_id}", account_id=account_id, sync_id=sync_id - ), - body=await async_maybe_transform( - { - "description": description, - "name": name, - "policy": policy, - "update_mode": update_mode, - }, - catalog_sync_edit_params.CatalogSyncEditParams, - ), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - post_parser=ResultWrapper[CatalogSyncEditResponse]._unwrapper, - ), - cast_to=cast(Type[CatalogSyncEditResponse], ResultWrapper[CatalogSyncEditResponse]), - ) - - async def get( - self, - sync_id: str, - *, - account_id: str, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> CatalogSyncGetResponse: - """ - Read a Catalog Sync (Closed Beta). - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not account_id: - raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not sync_id: - raise ValueError(f"Expected a non-empty value for `sync_id` but received {sync_id!r}") - return await self._get( - path_template( - "/accounts/{account_id}/magic/cloud/catalog-syncs/{sync_id}", account_id=account_id, sync_id=sync_id - ), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - post_parser=ResultWrapper[CatalogSyncGetResponse]._unwrapper, - ), - cast_to=cast(Type[CatalogSyncGetResponse], ResultWrapper[CatalogSyncGetResponse]), - ) - - async def refresh( - self, - sync_id: str, - *, - account_id: str, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> str: - """ - Refresh a Catalog Sync's destination by running the sync policy against latest - resource catalog (Closed Beta). - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not account_id: - raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not sync_id: - raise ValueError(f"Expected a non-empty value for `sync_id` but received {sync_id!r}") - return await self._post( - path_template( - "/accounts/{account_id}/magic/cloud/catalog-syncs/{sync_id}/refresh", - account_id=account_id, - sync_id=sync_id, - ), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - post_parser=ResultWrapper[CatalogSyncRefreshResponse]._unwrapper, - ), - cast_to=cast(Type[str], ResultWrapper[str]), - ) - - -class CatalogSyncsResourceWithRawResponse: - def __init__(self, catalog_syncs: CatalogSyncsResource) -> None: - self._catalog_syncs = catalog_syncs - - self.create = to_raw_response_wrapper( - catalog_syncs.create, - ) - self.update = to_raw_response_wrapper( - catalog_syncs.update, - ) - self.list = to_raw_response_wrapper( - catalog_syncs.list, - ) - self.delete = to_raw_response_wrapper( - catalog_syncs.delete, - ) - self.edit = to_raw_response_wrapper( - catalog_syncs.edit, - ) - self.get = to_raw_response_wrapper( - catalog_syncs.get, - ) - self.refresh = to_raw_response_wrapper( - catalog_syncs.refresh, - ) - - @cached_property - def prebuilt_policies(self) -> PrebuiltPoliciesResourceWithRawResponse: - return PrebuiltPoliciesResourceWithRawResponse(self._catalog_syncs.prebuilt_policies) - - -class AsyncCatalogSyncsResourceWithRawResponse: - def __init__(self, catalog_syncs: AsyncCatalogSyncsResource) -> None: - self._catalog_syncs = catalog_syncs - - self.create = async_to_raw_response_wrapper( - catalog_syncs.create, - ) - self.update = async_to_raw_response_wrapper( - catalog_syncs.update, - ) - self.list = async_to_raw_response_wrapper( - catalog_syncs.list, - ) - self.delete = async_to_raw_response_wrapper( - catalog_syncs.delete, - ) - self.edit = async_to_raw_response_wrapper( - catalog_syncs.edit, - ) - self.get = async_to_raw_response_wrapper( - catalog_syncs.get, - ) - self.refresh = async_to_raw_response_wrapper( - catalog_syncs.refresh, - ) - - @cached_property - def prebuilt_policies(self) -> AsyncPrebuiltPoliciesResourceWithRawResponse: - return AsyncPrebuiltPoliciesResourceWithRawResponse(self._catalog_syncs.prebuilt_policies) - - -class CatalogSyncsResourceWithStreamingResponse: - def __init__(self, catalog_syncs: CatalogSyncsResource) -> None: - self._catalog_syncs = catalog_syncs - - self.create = to_streamed_response_wrapper( - catalog_syncs.create, - ) - self.update = to_streamed_response_wrapper( - catalog_syncs.update, - ) - self.list = to_streamed_response_wrapper( - catalog_syncs.list, - ) - self.delete = to_streamed_response_wrapper( - catalog_syncs.delete, - ) - self.edit = to_streamed_response_wrapper( - catalog_syncs.edit, - ) - self.get = to_streamed_response_wrapper( - catalog_syncs.get, - ) - self.refresh = to_streamed_response_wrapper( - catalog_syncs.refresh, - ) - - @cached_property - def prebuilt_policies(self) -> PrebuiltPoliciesResourceWithStreamingResponse: - return PrebuiltPoliciesResourceWithStreamingResponse(self._catalog_syncs.prebuilt_policies) - - -class AsyncCatalogSyncsResourceWithStreamingResponse: - def __init__(self, catalog_syncs: AsyncCatalogSyncsResource) -> None: - self._catalog_syncs = catalog_syncs - - self.create = async_to_streamed_response_wrapper( - catalog_syncs.create, - ) - self.update = async_to_streamed_response_wrapper( - catalog_syncs.update, - ) - self.list = async_to_streamed_response_wrapper( - catalog_syncs.list, - ) - self.delete = async_to_streamed_response_wrapper( - catalog_syncs.delete, - ) - self.edit = async_to_streamed_response_wrapper( - catalog_syncs.edit, - ) - self.get = async_to_streamed_response_wrapper( - catalog_syncs.get, - ) - self.refresh = async_to_streamed_response_wrapper( - catalog_syncs.refresh, - ) - - @cached_property - def prebuilt_policies(self) -> AsyncPrebuiltPoliciesResourceWithStreamingResponse: - return AsyncPrebuiltPoliciesResourceWithStreamingResponse(self._catalog_syncs.prebuilt_policies) diff --git a/src/cloudflare/resources/magic_cloud_networking/cloud_integrations.py b/src/cloudflare/resources/magic_cloud_networking/cloud_integrations.py deleted file mode 100644 index 8b5474725ba..00000000000 --- a/src/cloudflare/resources/magic_cloud_networking/cloud_integrations.py +++ /dev/null @@ -1,1111 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing import Any, Type, cast -from typing_extensions import Literal - -import httpx - -from ..._types import Body, Omit, Query, Headers, NotGiven, omit, not_given -from ..._utils import path_template, maybe_transform, strip_not_given, async_maybe_transform -from ..._compat import cached_property -from ..._resource import SyncAPIResource, AsyncAPIResource -from ..._response import ( - to_raw_response_wrapper, - to_streamed_response_wrapper, - async_to_raw_response_wrapper, - async_to_streamed_response_wrapper, -) -from ..._wrappers import ResultWrapper -from ...pagination import SyncSinglePage, AsyncSinglePage -from ..._base_client import AsyncPaginator, make_request_options -from ...types.magic_cloud_networking import ( - cloud_integration_get_params, - cloud_integration_edit_params, - cloud_integration_list_params, - cloud_integration_create_params, - cloud_integration_update_params, - cloud_integration_discover_params, -) -from ...types.magic_cloud_networking.cloud_integration_get_response import CloudIntegrationGetResponse -from ...types.magic_cloud_networking.cloud_integration_edit_response import CloudIntegrationEditResponse -from ...types.magic_cloud_networking.cloud_integration_list_response import CloudIntegrationListResponse -from ...types.magic_cloud_networking.cloud_integration_create_response import CloudIntegrationCreateResponse -from ...types.magic_cloud_networking.cloud_integration_delete_response import CloudIntegrationDeleteResponse -from ...types.magic_cloud_networking.cloud_integration_update_response import CloudIntegrationUpdateResponse -from ...types.magic_cloud_networking.cloud_integration_discover_response import CloudIntegrationDiscoverResponse -from ...types.magic_cloud_networking.cloud_integration_discover_all_response import CloudIntegrationDiscoverAllResponse -from ...types.magic_cloud_networking.cloud_integration_initial_setup_response import ( - CloudIntegrationInitialSetupResponse, -) - -__all__ = ["CloudIntegrationsResource", "AsyncCloudIntegrationsResource"] - - -class CloudIntegrationsResource(SyncAPIResource): - @cached_property - def with_raw_response(self) -> CloudIntegrationsResourceWithRawResponse: - """ - This property can be used as a prefix for any HTTP method call to return - the raw response object instead of the parsed content. - - For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers - """ - return CloudIntegrationsResourceWithRawResponse(self) - - @cached_property - def with_streaming_response(self) -> CloudIntegrationsResourceWithStreamingResponse: - """ - An alternative to `.with_raw_response` that doesn't eagerly read the response body. - - For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response - """ - return CloudIntegrationsResourceWithStreamingResponse(self) - - def create( - self, - *, - account_id: str, - cloud_type: Literal["AWS", "AZURE", "GOOGLE", "CLOUDFLARE"], - friendly_name: str, - description: str | Omit = omit, - forwarded: str | Omit = omit, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> CloudIntegrationCreateResponse: - """ - Create a new Cloud Integration (Closed Beta). - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not account_id: - raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - extra_headers = {**strip_not_given({"forwarded": forwarded}), **(extra_headers or {})} - return self._post( - path_template("/accounts/{account_id}/magic/cloud/providers", account_id=account_id), - body=maybe_transform( - { - "cloud_type": cloud_type, - "friendly_name": friendly_name, - "description": description, - }, - cloud_integration_create_params.CloudIntegrationCreateParams, - ), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - post_parser=ResultWrapper[CloudIntegrationCreateResponse]._unwrapper, - ), - cast_to=cast(Type[CloudIntegrationCreateResponse], ResultWrapper[CloudIntegrationCreateResponse]), - ) - - def update( - self, - provider_id: str, - *, - account_id: str, - aws_arn: str | Omit = omit, - azure_subscription_id: str | Omit = omit, - azure_tenant_id: str | Omit = omit, - description: str | Omit = omit, - friendly_name: str | Omit = omit, - gcp_project_id: str | Omit = omit, - gcp_service_account_email: str | Omit = omit, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> CloudIntegrationUpdateResponse: - """ - Update a Cloud Integration (Closed Beta). - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not account_id: - raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not provider_id: - raise ValueError(f"Expected a non-empty value for `provider_id` but received {provider_id!r}") - return self._put( - path_template( - "/accounts/{account_id}/magic/cloud/providers/{provider_id}", - account_id=account_id, - provider_id=provider_id, - ), - body=maybe_transform( - { - "aws_arn": aws_arn, - "azure_subscription_id": azure_subscription_id, - "azure_tenant_id": azure_tenant_id, - "description": description, - "friendly_name": friendly_name, - "gcp_project_id": gcp_project_id, - "gcp_service_account_email": gcp_service_account_email, - }, - cloud_integration_update_params.CloudIntegrationUpdateParams, - ), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - post_parser=ResultWrapper[CloudIntegrationUpdateResponse]._unwrapper, - ), - cast_to=cast(Type[CloudIntegrationUpdateResponse], ResultWrapper[CloudIntegrationUpdateResponse]), - ) - - def list( - self, - *, - account_id: str, - cloudflare: bool | Omit = omit, - desc: bool | Omit = omit, - order_by: str | Omit = omit, - status: bool | Omit = omit, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> SyncSinglePage[CloudIntegrationListResponse]: - """ - List Cloud Integrations (Closed Beta). - - Args: - order_by: One of ["updated_at", "id", "cloud_type", "name"]. - - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not account_id: - raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - return self._get_api_list( - path_template("/accounts/{account_id}/magic/cloud/providers", account_id=account_id), - page=SyncSinglePage[CloudIntegrationListResponse], - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - query=maybe_transform( - { - "cloudflare": cloudflare, - "desc": desc, - "order_by": order_by, - "status": status, - }, - cloud_integration_list_params.CloudIntegrationListParams, - ), - ), - model=CloudIntegrationListResponse, - ) - - def delete( - self, - provider_id: str, - *, - account_id: str, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> CloudIntegrationDeleteResponse: - """ - Delete a Cloud Integration (Closed Beta). - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not account_id: - raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not provider_id: - raise ValueError(f"Expected a non-empty value for `provider_id` but received {provider_id!r}") - return self._delete( - path_template( - "/accounts/{account_id}/magic/cloud/providers/{provider_id}", - account_id=account_id, - provider_id=provider_id, - ), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - post_parser=ResultWrapper[CloudIntegrationDeleteResponse]._unwrapper, - ), - cast_to=cast(Type[CloudIntegrationDeleteResponse], ResultWrapper[CloudIntegrationDeleteResponse]), - ) - - def discover( - self, - provider_id: str, - *, - account_id: str, - v2: bool | Omit = omit, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> CloudIntegrationDiscoverResponse: - """ - Run discovery for a Cloud Integration (Closed Beta). - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not account_id: - raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not provider_id: - raise ValueError(f"Expected a non-empty value for `provider_id` but received {provider_id!r}") - return self._post( - path_template( - "/accounts/{account_id}/magic/cloud/providers/{provider_id}/discover", - account_id=account_id, - provider_id=provider_id, - ), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - query=maybe_transform({"v2": v2}, cloud_integration_discover_params.CloudIntegrationDiscoverParams), - ), - cast_to=CloudIntegrationDiscoverResponse, - ) - - def discover_all( - self, - *, - account_id: str, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> CloudIntegrationDiscoverAllResponse: - """ - Run discovery for all Cloud Integrations in an account (Closed Beta). - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not account_id: - raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - return self._post( - path_template("/accounts/{account_id}/magic/cloud/providers/discover", account_id=account_id), - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=CloudIntegrationDiscoverAllResponse, - ) - - def edit( - self, - provider_id: str, - *, - account_id: str, - aws_arn: str | Omit = omit, - azure_subscription_id: str | Omit = omit, - azure_tenant_id: str | Omit = omit, - description: str | Omit = omit, - friendly_name: str | Omit = omit, - gcp_project_id: str | Omit = omit, - gcp_service_account_email: str | Omit = omit, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> CloudIntegrationEditResponse: - """ - Update a Cloud Integration (Closed Beta). - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not account_id: - raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not provider_id: - raise ValueError(f"Expected a non-empty value for `provider_id` but received {provider_id!r}") - return self._patch( - path_template( - "/accounts/{account_id}/magic/cloud/providers/{provider_id}", - account_id=account_id, - provider_id=provider_id, - ), - body=maybe_transform( - { - "aws_arn": aws_arn, - "azure_subscription_id": azure_subscription_id, - "azure_tenant_id": azure_tenant_id, - "description": description, - "friendly_name": friendly_name, - "gcp_project_id": gcp_project_id, - "gcp_service_account_email": gcp_service_account_email, - }, - cloud_integration_edit_params.CloudIntegrationEditParams, - ), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - post_parser=ResultWrapper[CloudIntegrationEditResponse]._unwrapper, - ), - cast_to=cast(Type[CloudIntegrationEditResponse], ResultWrapper[CloudIntegrationEditResponse]), - ) - - def get( - self, - provider_id: str, - *, - account_id: str, - status: bool | Omit = omit, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> CloudIntegrationGetResponse: - """ - Read a Cloud Integration (Closed Beta). - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not account_id: - raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not provider_id: - raise ValueError(f"Expected a non-empty value for `provider_id` but received {provider_id!r}") - return self._get( - path_template( - "/accounts/{account_id}/magic/cloud/providers/{provider_id}", - account_id=account_id, - provider_id=provider_id, - ), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - query=maybe_transform({"status": status}, cloud_integration_get_params.CloudIntegrationGetParams), - post_parser=ResultWrapper[CloudIntegrationGetResponse]._unwrapper, - ), - cast_to=cast(Type[CloudIntegrationGetResponse], ResultWrapper[CloudIntegrationGetResponse]), - ) - - def initial_setup( - self, - provider_id: str, - *, - account_id: str, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> CloudIntegrationInitialSetupResponse: - """ - Get initial configuration to complete Cloud Integration setup (Closed Beta). - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not account_id: - raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not provider_id: - raise ValueError(f"Expected a non-empty value for `provider_id` but received {provider_id!r}") - return cast( - CloudIntegrationInitialSetupResponse, - self._get( - path_template( - "/accounts/{account_id}/magic/cloud/providers/{provider_id}/initial_setup", - account_id=account_id, - provider_id=provider_id, - ), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - post_parser=ResultWrapper[CloudIntegrationInitialSetupResponse]._unwrapper, - ), - cast_to=cast( - Any, ResultWrapper[CloudIntegrationInitialSetupResponse] - ), # Union types cannot be passed in as arguments in the type system - ), - ) - - -class AsyncCloudIntegrationsResource(AsyncAPIResource): - @cached_property - def with_raw_response(self) -> AsyncCloudIntegrationsResourceWithRawResponse: - """ - This property can be used as a prefix for any HTTP method call to return - the raw response object instead of the parsed content. - - For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers - """ - return AsyncCloudIntegrationsResourceWithRawResponse(self) - - @cached_property - def with_streaming_response(self) -> AsyncCloudIntegrationsResourceWithStreamingResponse: - """ - An alternative to `.with_raw_response` that doesn't eagerly read the response body. - - For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response - """ - return AsyncCloudIntegrationsResourceWithStreamingResponse(self) - - async def create( - self, - *, - account_id: str, - cloud_type: Literal["AWS", "AZURE", "GOOGLE", "CLOUDFLARE"], - friendly_name: str, - description: str | Omit = omit, - forwarded: str | Omit = omit, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> CloudIntegrationCreateResponse: - """ - Create a new Cloud Integration (Closed Beta). - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not account_id: - raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - extra_headers = {**strip_not_given({"forwarded": forwarded}), **(extra_headers or {})} - return await self._post( - path_template("/accounts/{account_id}/magic/cloud/providers", account_id=account_id), - body=await async_maybe_transform( - { - "cloud_type": cloud_type, - "friendly_name": friendly_name, - "description": description, - }, - cloud_integration_create_params.CloudIntegrationCreateParams, - ), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - post_parser=ResultWrapper[CloudIntegrationCreateResponse]._unwrapper, - ), - cast_to=cast(Type[CloudIntegrationCreateResponse], ResultWrapper[CloudIntegrationCreateResponse]), - ) - - async def update( - self, - provider_id: str, - *, - account_id: str, - aws_arn: str | Omit = omit, - azure_subscription_id: str | Omit = omit, - azure_tenant_id: str | Omit = omit, - description: str | Omit = omit, - friendly_name: str | Omit = omit, - gcp_project_id: str | Omit = omit, - gcp_service_account_email: str | Omit = omit, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> CloudIntegrationUpdateResponse: - """ - Update a Cloud Integration (Closed Beta). - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not account_id: - raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not provider_id: - raise ValueError(f"Expected a non-empty value for `provider_id` but received {provider_id!r}") - return await self._put( - path_template( - "/accounts/{account_id}/magic/cloud/providers/{provider_id}", - account_id=account_id, - provider_id=provider_id, - ), - body=await async_maybe_transform( - { - "aws_arn": aws_arn, - "azure_subscription_id": azure_subscription_id, - "azure_tenant_id": azure_tenant_id, - "description": description, - "friendly_name": friendly_name, - "gcp_project_id": gcp_project_id, - "gcp_service_account_email": gcp_service_account_email, - }, - cloud_integration_update_params.CloudIntegrationUpdateParams, - ), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - post_parser=ResultWrapper[CloudIntegrationUpdateResponse]._unwrapper, - ), - cast_to=cast(Type[CloudIntegrationUpdateResponse], ResultWrapper[CloudIntegrationUpdateResponse]), - ) - - def list( - self, - *, - account_id: str, - cloudflare: bool | Omit = omit, - desc: bool | Omit = omit, - order_by: str | Omit = omit, - status: bool | Omit = omit, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> AsyncPaginator[CloudIntegrationListResponse, AsyncSinglePage[CloudIntegrationListResponse]]: - """ - List Cloud Integrations (Closed Beta). - - Args: - order_by: One of ["updated_at", "id", "cloud_type", "name"]. - - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not account_id: - raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - return self._get_api_list( - path_template("/accounts/{account_id}/magic/cloud/providers", account_id=account_id), - page=AsyncSinglePage[CloudIntegrationListResponse], - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - query=maybe_transform( - { - "cloudflare": cloudflare, - "desc": desc, - "order_by": order_by, - "status": status, - }, - cloud_integration_list_params.CloudIntegrationListParams, - ), - ), - model=CloudIntegrationListResponse, - ) - - async def delete( - self, - provider_id: str, - *, - account_id: str, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> CloudIntegrationDeleteResponse: - """ - Delete a Cloud Integration (Closed Beta). - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not account_id: - raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not provider_id: - raise ValueError(f"Expected a non-empty value for `provider_id` but received {provider_id!r}") - return await self._delete( - path_template( - "/accounts/{account_id}/magic/cloud/providers/{provider_id}", - account_id=account_id, - provider_id=provider_id, - ), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - post_parser=ResultWrapper[CloudIntegrationDeleteResponse]._unwrapper, - ), - cast_to=cast(Type[CloudIntegrationDeleteResponse], ResultWrapper[CloudIntegrationDeleteResponse]), - ) - - async def discover( - self, - provider_id: str, - *, - account_id: str, - v2: bool | Omit = omit, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> CloudIntegrationDiscoverResponse: - """ - Run discovery for a Cloud Integration (Closed Beta). - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not account_id: - raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not provider_id: - raise ValueError(f"Expected a non-empty value for `provider_id` but received {provider_id!r}") - return await self._post( - path_template( - "/accounts/{account_id}/magic/cloud/providers/{provider_id}/discover", - account_id=account_id, - provider_id=provider_id, - ), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - query=await async_maybe_transform( - {"v2": v2}, cloud_integration_discover_params.CloudIntegrationDiscoverParams - ), - ), - cast_to=CloudIntegrationDiscoverResponse, - ) - - async def discover_all( - self, - *, - account_id: str, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> CloudIntegrationDiscoverAllResponse: - """ - Run discovery for all Cloud Integrations in an account (Closed Beta). - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not account_id: - raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - return await self._post( - path_template("/accounts/{account_id}/magic/cloud/providers/discover", account_id=account_id), - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=CloudIntegrationDiscoverAllResponse, - ) - - async def edit( - self, - provider_id: str, - *, - account_id: str, - aws_arn: str | Omit = omit, - azure_subscription_id: str | Omit = omit, - azure_tenant_id: str | Omit = omit, - description: str | Omit = omit, - friendly_name: str | Omit = omit, - gcp_project_id: str | Omit = omit, - gcp_service_account_email: str | Omit = omit, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> CloudIntegrationEditResponse: - """ - Update a Cloud Integration (Closed Beta). - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not account_id: - raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not provider_id: - raise ValueError(f"Expected a non-empty value for `provider_id` but received {provider_id!r}") - return await self._patch( - path_template( - "/accounts/{account_id}/magic/cloud/providers/{provider_id}", - account_id=account_id, - provider_id=provider_id, - ), - body=await async_maybe_transform( - { - "aws_arn": aws_arn, - "azure_subscription_id": azure_subscription_id, - "azure_tenant_id": azure_tenant_id, - "description": description, - "friendly_name": friendly_name, - "gcp_project_id": gcp_project_id, - "gcp_service_account_email": gcp_service_account_email, - }, - cloud_integration_edit_params.CloudIntegrationEditParams, - ), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - post_parser=ResultWrapper[CloudIntegrationEditResponse]._unwrapper, - ), - cast_to=cast(Type[CloudIntegrationEditResponse], ResultWrapper[CloudIntegrationEditResponse]), - ) - - async def get( - self, - provider_id: str, - *, - account_id: str, - status: bool | Omit = omit, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> CloudIntegrationGetResponse: - """ - Read a Cloud Integration (Closed Beta). - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not account_id: - raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not provider_id: - raise ValueError(f"Expected a non-empty value for `provider_id` but received {provider_id!r}") - return await self._get( - path_template( - "/accounts/{account_id}/magic/cloud/providers/{provider_id}", - account_id=account_id, - provider_id=provider_id, - ), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - query=await async_maybe_transform( - {"status": status}, cloud_integration_get_params.CloudIntegrationGetParams - ), - post_parser=ResultWrapper[CloudIntegrationGetResponse]._unwrapper, - ), - cast_to=cast(Type[CloudIntegrationGetResponse], ResultWrapper[CloudIntegrationGetResponse]), - ) - - async def initial_setup( - self, - provider_id: str, - *, - account_id: str, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> CloudIntegrationInitialSetupResponse: - """ - Get initial configuration to complete Cloud Integration setup (Closed Beta). - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not account_id: - raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not provider_id: - raise ValueError(f"Expected a non-empty value for `provider_id` but received {provider_id!r}") - return cast( - CloudIntegrationInitialSetupResponse, - await self._get( - path_template( - "/accounts/{account_id}/magic/cloud/providers/{provider_id}/initial_setup", - account_id=account_id, - provider_id=provider_id, - ), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - post_parser=ResultWrapper[CloudIntegrationInitialSetupResponse]._unwrapper, - ), - cast_to=cast( - Any, ResultWrapper[CloudIntegrationInitialSetupResponse] - ), # Union types cannot be passed in as arguments in the type system - ), - ) - - -class CloudIntegrationsResourceWithRawResponse: - def __init__(self, cloud_integrations: CloudIntegrationsResource) -> None: - self._cloud_integrations = cloud_integrations - - self.create = to_raw_response_wrapper( - cloud_integrations.create, - ) - self.update = to_raw_response_wrapper( - cloud_integrations.update, - ) - self.list = to_raw_response_wrapper( - cloud_integrations.list, - ) - self.delete = to_raw_response_wrapper( - cloud_integrations.delete, - ) - self.discover = to_raw_response_wrapper( - cloud_integrations.discover, - ) - self.discover_all = to_raw_response_wrapper( - cloud_integrations.discover_all, - ) - self.edit = to_raw_response_wrapper( - cloud_integrations.edit, - ) - self.get = to_raw_response_wrapper( - cloud_integrations.get, - ) - self.initial_setup = to_raw_response_wrapper( - cloud_integrations.initial_setup, - ) - - -class AsyncCloudIntegrationsResourceWithRawResponse: - def __init__(self, cloud_integrations: AsyncCloudIntegrationsResource) -> None: - self._cloud_integrations = cloud_integrations - - self.create = async_to_raw_response_wrapper( - cloud_integrations.create, - ) - self.update = async_to_raw_response_wrapper( - cloud_integrations.update, - ) - self.list = async_to_raw_response_wrapper( - cloud_integrations.list, - ) - self.delete = async_to_raw_response_wrapper( - cloud_integrations.delete, - ) - self.discover = async_to_raw_response_wrapper( - cloud_integrations.discover, - ) - self.discover_all = async_to_raw_response_wrapper( - cloud_integrations.discover_all, - ) - self.edit = async_to_raw_response_wrapper( - cloud_integrations.edit, - ) - self.get = async_to_raw_response_wrapper( - cloud_integrations.get, - ) - self.initial_setup = async_to_raw_response_wrapper( - cloud_integrations.initial_setup, - ) - - -class CloudIntegrationsResourceWithStreamingResponse: - def __init__(self, cloud_integrations: CloudIntegrationsResource) -> None: - self._cloud_integrations = cloud_integrations - - self.create = to_streamed_response_wrapper( - cloud_integrations.create, - ) - self.update = to_streamed_response_wrapper( - cloud_integrations.update, - ) - self.list = to_streamed_response_wrapper( - cloud_integrations.list, - ) - self.delete = to_streamed_response_wrapper( - cloud_integrations.delete, - ) - self.discover = to_streamed_response_wrapper( - cloud_integrations.discover, - ) - self.discover_all = to_streamed_response_wrapper( - cloud_integrations.discover_all, - ) - self.edit = to_streamed_response_wrapper( - cloud_integrations.edit, - ) - self.get = to_streamed_response_wrapper( - cloud_integrations.get, - ) - self.initial_setup = to_streamed_response_wrapper( - cloud_integrations.initial_setup, - ) - - -class AsyncCloudIntegrationsResourceWithStreamingResponse: - def __init__(self, cloud_integrations: AsyncCloudIntegrationsResource) -> None: - self._cloud_integrations = cloud_integrations - - self.create = async_to_streamed_response_wrapper( - cloud_integrations.create, - ) - self.update = async_to_streamed_response_wrapper( - cloud_integrations.update, - ) - self.list = async_to_streamed_response_wrapper( - cloud_integrations.list, - ) - self.delete = async_to_streamed_response_wrapper( - cloud_integrations.delete, - ) - self.discover = async_to_streamed_response_wrapper( - cloud_integrations.discover, - ) - self.discover_all = async_to_streamed_response_wrapper( - cloud_integrations.discover_all, - ) - self.edit = async_to_streamed_response_wrapper( - cloud_integrations.edit, - ) - self.get = async_to_streamed_response_wrapper( - cloud_integrations.get, - ) - self.initial_setup = async_to_streamed_response_wrapper( - cloud_integrations.initial_setup, - ) diff --git a/src/cloudflare/resources/magic_cloud_networking/magic_cloud_networking.py b/src/cloudflare/resources/magic_cloud_networking/magic_cloud_networking.py deleted file mode 100644 index 1e3121e7530..00000000000 --- a/src/cloudflare/resources/magic_cloud_networking/magic_cloud_networking.py +++ /dev/null @@ -1,198 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from ..._compat import cached_property -from .resources import ( - ResourcesResource, - AsyncResourcesResource, - ResourcesResourceWithRawResponse, - AsyncResourcesResourceWithRawResponse, - ResourcesResourceWithStreamingResponse, - AsyncResourcesResourceWithStreamingResponse, -) -from ..._resource import SyncAPIResource, AsyncAPIResource -from .on_ramps.on_ramps import ( - OnRampsResource, - AsyncOnRampsResource, - OnRampsResourceWithRawResponse, - AsyncOnRampsResourceWithRawResponse, - OnRampsResourceWithStreamingResponse, - AsyncOnRampsResourceWithStreamingResponse, -) -from .cloud_integrations import ( - CloudIntegrationsResource, - AsyncCloudIntegrationsResource, - CloudIntegrationsResourceWithRawResponse, - AsyncCloudIntegrationsResourceWithRawResponse, - CloudIntegrationsResourceWithStreamingResponse, - AsyncCloudIntegrationsResourceWithStreamingResponse, -) -from .catalog_syncs.catalog_syncs import ( - CatalogSyncsResource, - AsyncCatalogSyncsResource, - CatalogSyncsResourceWithRawResponse, - AsyncCatalogSyncsResourceWithRawResponse, - CatalogSyncsResourceWithStreamingResponse, - AsyncCatalogSyncsResourceWithStreamingResponse, -) - -__all__ = ["MagicCloudNetworkingResource", "AsyncMagicCloudNetworkingResource"] - - -class MagicCloudNetworkingResource(SyncAPIResource): - @cached_property - def catalog_syncs(self) -> CatalogSyncsResource: - return CatalogSyncsResource(self._client) - - @cached_property - def on_ramps(self) -> OnRampsResource: - return OnRampsResource(self._client) - - @cached_property - def cloud_integrations(self) -> CloudIntegrationsResource: - return CloudIntegrationsResource(self._client) - - @cached_property - def resources(self) -> ResourcesResource: - return ResourcesResource(self._client) - - @cached_property - def with_raw_response(self) -> MagicCloudNetworkingResourceWithRawResponse: - """ - This property can be used as a prefix for any HTTP method call to return - the raw response object instead of the parsed content. - - For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers - """ - return MagicCloudNetworkingResourceWithRawResponse(self) - - @cached_property - def with_streaming_response(self) -> MagicCloudNetworkingResourceWithStreamingResponse: - """ - An alternative to `.with_raw_response` that doesn't eagerly read the response body. - - For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response - """ - return MagicCloudNetworkingResourceWithStreamingResponse(self) - - -class AsyncMagicCloudNetworkingResource(AsyncAPIResource): - @cached_property - def catalog_syncs(self) -> AsyncCatalogSyncsResource: - return AsyncCatalogSyncsResource(self._client) - - @cached_property - def on_ramps(self) -> AsyncOnRampsResource: - return AsyncOnRampsResource(self._client) - - @cached_property - def cloud_integrations(self) -> AsyncCloudIntegrationsResource: - return AsyncCloudIntegrationsResource(self._client) - - @cached_property - def resources(self) -> AsyncResourcesResource: - return AsyncResourcesResource(self._client) - - @cached_property - def with_raw_response(self) -> AsyncMagicCloudNetworkingResourceWithRawResponse: - """ - This property can be used as a prefix for any HTTP method call to return - the raw response object instead of the parsed content. - - For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers - """ - return AsyncMagicCloudNetworkingResourceWithRawResponse(self) - - @cached_property - def with_streaming_response(self) -> AsyncMagicCloudNetworkingResourceWithStreamingResponse: - """ - An alternative to `.with_raw_response` that doesn't eagerly read the response body. - - For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response - """ - return AsyncMagicCloudNetworkingResourceWithStreamingResponse(self) - - -class MagicCloudNetworkingResourceWithRawResponse: - def __init__(self, magic_cloud_networking: MagicCloudNetworkingResource) -> None: - self._magic_cloud_networking = magic_cloud_networking - - @cached_property - def catalog_syncs(self) -> CatalogSyncsResourceWithRawResponse: - return CatalogSyncsResourceWithRawResponse(self._magic_cloud_networking.catalog_syncs) - - @cached_property - def on_ramps(self) -> OnRampsResourceWithRawResponse: - return OnRampsResourceWithRawResponse(self._magic_cloud_networking.on_ramps) - - @cached_property - def cloud_integrations(self) -> CloudIntegrationsResourceWithRawResponse: - return CloudIntegrationsResourceWithRawResponse(self._magic_cloud_networking.cloud_integrations) - - @cached_property - def resources(self) -> ResourcesResourceWithRawResponse: - return ResourcesResourceWithRawResponse(self._magic_cloud_networking.resources) - - -class AsyncMagicCloudNetworkingResourceWithRawResponse: - def __init__(self, magic_cloud_networking: AsyncMagicCloudNetworkingResource) -> None: - self._magic_cloud_networking = magic_cloud_networking - - @cached_property - def catalog_syncs(self) -> AsyncCatalogSyncsResourceWithRawResponse: - return AsyncCatalogSyncsResourceWithRawResponse(self._magic_cloud_networking.catalog_syncs) - - @cached_property - def on_ramps(self) -> AsyncOnRampsResourceWithRawResponse: - return AsyncOnRampsResourceWithRawResponse(self._magic_cloud_networking.on_ramps) - - @cached_property - def cloud_integrations(self) -> AsyncCloudIntegrationsResourceWithRawResponse: - return AsyncCloudIntegrationsResourceWithRawResponse(self._magic_cloud_networking.cloud_integrations) - - @cached_property - def resources(self) -> AsyncResourcesResourceWithRawResponse: - return AsyncResourcesResourceWithRawResponse(self._magic_cloud_networking.resources) - - -class MagicCloudNetworkingResourceWithStreamingResponse: - def __init__(self, magic_cloud_networking: MagicCloudNetworkingResource) -> None: - self._magic_cloud_networking = magic_cloud_networking - - @cached_property - def catalog_syncs(self) -> CatalogSyncsResourceWithStreamingResponse: - return CatalogSyncsResourceWithStreamingResponse(self._magic_cloud_networking.catalog_syncs) - - @cached_property - def on_ramps(self) -> OnRampsResourceWithStreamingResponse: - return OnRampsResourceWithStreamingResponse(self._magic_cloud_networking.on_ramps) - - @cached_property - def cloud_integrations(self) -> CloudIntegrationsResourceWithStreamingResponse: - return CloudIntegrationsResourceWithStreamingResponse(self._magic_cloud_networking.cloud_integrations) - - @cached_property - def resources(self) -> ResourcesResourceWithStreamingResponse: - return ResourcesResourceWithStreamingResponse(self._magic_cloud_networking.resources) - - -class AsyncMagicCloudNetworkingResourceWithStreamingResponse: - def __init__(self, magic_cloud_networking: AsyncMagicCloudNetworkingResource) -> None: - self._magic_cloud_networking = magic_cloud_networking - - @cached_property - def catalog_syncs(self) -> AsyncCatalogSyncsResourceWithStreamingResponse: - return AsyncCatalogSyncsResourceWithStreamingResponse(self._magic_cloud_networking.catalog_syncs) - - @cached_property - def on_ramps(self) -> AsyncOnRampsResourceWithStreamingResponse: - return AsyncOnRampsResourceWithStreamingResponse(self._magic_cloud_networking.on_ramps) - - @cached_property - def cloud_integrations(self) -> AsyncCloudIntegrationsResourceWithStreamingResponse: - return AsyncCloudIntegrationsResourceWithStreamingResponse(self._magic_cloud_networking.cloud_integrations) - - @cached_property - def resources(self) -> AsyncResourcesResourceWithStreamingResponse: - return AsyncResourcesResourceWithStreamingResponse(self._magic_cloud_networking.resources) diff --git a/src/cloudflare/resources/magic_cloud_networking/on_ramps/__init__.py b/src/cloudflare/resources/magic_cloud_networking/on_ramps/__init__.py deleted file mode 100644 index add114e008d..00000000000 --- a/src/cloudflare/resources/magic_cloud_networking/on_ramps/__init__.py +++ /dev/null @@ -1,33 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from .on_ramps import ( - OnRampsResource, - AsyncOnRampsResource, - OnRampsResourceWithRawResponse, - AsyncOnRampsResourceWithRawResponse, - OnRampsResourceWithStreamingResponse, - AsyncOnRampsResourceWithStreamingResponse, -) -from .address_spaces import ( - AddressSpacesResource, - AsyncAddressSpacesResource, - AddressSpacesResourceWithRawResponse, - AsyncAddressSpacesResourceWithRawResponse, - AddressSpacesResourceWithStreamingResponse, - AsyncAddressSpacesResourceWithStreamingResponse, -) - -__all__ = [ - "AddressSpacesResource", - "AsyncAddressSpacesResource", - "AddressSpacesResourceWithRawResponse", - "AsyncAddressSpacesResourceWithRawResponse", - "AddressSpacesResourceWithStreamingResponse", - "AsyncAddressSpacesResourceWithStreamingResponse", - "OnRampsResource", - "AsyncOnRampsResource", - "OnRampsResourceWithRawResponse", - "AsyncOnRampsResourceWithRawResponse", - "OnRampsResourceWithStreamingResponse", - "AsyncOnRampsResourceWithStreamingResponse", -] diff --git a/src/cloudflare/resources/magic_cloud_networking/on_ramps/address_spaces.py b/src/cloudflare/resources/magic_cloud_networking/on_ramps/address_spaces.py deleted file mode 100644 index 1a79fe310fc..00000000000 --- a/src/cloudflare/resources/magic_cloud_networking/on_ramps/address_spaces.py +++ /dev/null @@ -1,360 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing import Type, cast - -import httpx - -from ...._types import Body, Query, Headers, NotGiven, SequenceNotStr, not_given -from ...._utils import path_template, maybe_transform, async_maybe_transform -from ...._compat import cached_property -from ...._resource import SyncAPIResource, AsyncAPIResource -from ...._response import ( - to_raw_response_wrapper, - to_streamed_response_wrapper, - async_to_raw_response_wrapper, - async_to_streamed_response_wrapper, -) -from ...._wrappers import ResultWrapper -from ...._base_client import make_request_options -from ....types.magic_cloud_networking.on_ramps import address_space_edit_params, address_space_update_params -from ....types.magic_cloud_networking.on_ramps.address_space_edit_response import AddressSpaceEditResponse -from ....types.magic_cloud_networking.on_ramps.address_space_list_response import AddressSpaceListResponse -from ....types.magic_cloud_networking.on_ramps.address_space_update_response import AddressSpaceUpdateResponse - -__all__ = ["AddressSpacesResource", "AsyncAddressSpacesResource"] - - -class AddressSpacesResource(SyncAPIResource): - @cached_property - def with_raw_response(self) -> AddressSpacesResourceWithRawResponse: - """ - This property can be used as a prefix for any HTTP method call to return - the raw response object instead of the parsed content. - - For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers - """ - return AddressSpacesResourceWithRawResponse(self) - - @cached_property - def with_streaming_response(self) -> AddressSpacesResourceWithStreamingResponse: - """ - An alternative to `.with_raw_response` that doesn't eagerly read the response body. - - For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response - """ - return AddressSpacesResourceWithStreamingResponse(self) - - def update( - self, - *, - account_id: str, - prefixes: SequenceNotStr[str], - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> AddressSpaceUpdateResponse: - """ - Update the Magic WAN Address Space (Closed Beta). - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not account_id: - raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - return self._put( - path_template("/accounts/{account_id}/magic/cloud/onramps/magic_wan_address_space", account_id=account_id), - body=maybe_transform({"prefixes": prefixes}, address_space_update_params.AddressSpaceUpdateParams), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - post_parser=ResultWrapper[AddressSpaceUpdateResponse]._unwrapper, - ), - cast_to=cast(Type[AddressSpaceUpdateResponse], ResultWrapper[AddressSpaceUpdateResponse]), - ) - - def list( - self, - *, - account_id: str, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> AddressSpaceListResponse: - """ - Read the Magic WAN Address Space (Closed Beta). - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not account_id: - raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - return self._get( - path_template("/accounts/{account_id}/magic/cloud/onramps/magic_wan_address_space", account_id=account_id), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - post_parser=ResultWrapper[AddressSpaceListResponse]._unwrapper, - ), - cast_to=cast(Type[AddressSpaceListResponse], ResultWrapper[AddressSpaceListResponse]), - ) - - def edit( - self, - *, - account_id: str, - prefixes: SequenceNotStr[str], - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> AddressSpaceEditResponse: - """ - Update the Magic WAN Address Space (Closed Beta). - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not account_id: - raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - return self._patch( - path_template("/accounts/{account_id}/magic/cloud/onramps/magic_wan_address_space", account_id=account_id), - body=maybe_transform({"prefixes": prefixes}, address_space_edit_params.AddressSpaceEditParams), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - post_parser=ResultWrapper[AddressSpaceEditResponse]._unwrapper, - ), - cast_to=cast(Type[AddressSpaceEditResponse], ResultWrapper[AddressSpaceEditResponse]), - ) - - -class AsyncAddressSpacesResource(AsyncAPIResource): - @cached_property - def with_raw_response(self) -> AsyncAddressSpacesResourceWithRawResponse: - """ - This property can be used as a prefix for any HTTP method call to return - the raw response object instead of the parsed content. - - For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers - """ - return AsyncAddressSpacesResourceWithRawResponse(self) - - @cached_property - def with_streaming_response(self) -> AsyncAddressSpacesResourceWithStreamingResponse: - """ - An alternative to `.with_raw_response` that doesn't eagerly read the response body. - - For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response - """ - return AsyncAddressSpacesResourceWithStreamingResponse(self) - - async def update( - self, - *, - account_id: str, - prefixes: SequenceNotStr[str], - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> AddressSpaceUpdateResponse: - """ - Update the Magic WAN Address Space (Closed Beta). - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not account_id: - raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - return await self._put( - path_template("/accounts/{account_id}/magic/cloud/onramps/magic_wan_address_space", account_id=account_id), - body=await async_maybe_transform( - {"prefixes": prefixes}, address_space_update_params.AddressSpaceUpdateParams - ), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - post_parser=ResultWrapper[AddressSpaceUpdateResponse]._unwrapper, - ), - cast_to=cast(Type[AddressSpaceUpdateResponse], ResultWrapper[AddressSpaceUpdateResponse]), - ) - - async def list( - self, - *, - account_id: str, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> AddressSpaceListResponse: - """ - Read the Magic WAN Address Space (Closed Beta). - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not account_id: - raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - return await self._get( - path_template("/accounts/{account_id}/magic/cloud/onramps/magic_wan_address_space", account_id=account_id), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - post_parser=ResultWrapper[AddressSpaceListResponse]._unwrapper, - ), - cast_to=cast(Type[AddressSpaceListResponse], ResultWrapper[AddressSpaceListResponse]), - ) - - async def edit( - self, - *, - account_id: str, - prefixes: SequenceNotStr[str], - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> AddressSpaceEditResponse: - """ - Update the Magic WAN Address Space (Closed Beta). - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not account_id: - raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - return await self._patch( - path_template("/accounts/{account_id}/magic/cloud/onramps/magic_wan_address_space", account_id=account_id), - body=await async_maybe_transform({"prefixes": prefixes}, address_space_edit_params.AddressSpaceEditParams), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - post_parser=ResultWrapper[AddressSpaceEditResponse]._unwrapper, - ), - cast_to=cast(Type[AddressSpaceEditResponse], ResultWrapper[AddressSpaceEditResponse]), - ) - - -class AddressSpacesResourceWithRawResponse: - def __init__(self, address_spaces: AddressSpacesResource) -> None: - self._address_spaces = address_spaces - - self.update = to_raw_response_wrapper( - address_spaces.update, - ) - self.list = to_raw_response_wrapper( - address_spaces.list, - ) - self.edit = to_raw_response_wrapper( - address_spaces.edit, - ) - - -class AsyncAddressSpacesResourceWithRawResponse: - def __init__(self, address_spaces: AsyncAddressSpacesResource) -> None: - self._address_spaces = address_spaces - - self.update = async_to_raw_response_wrapper( - address_spaces.update, - ) - self.list = async_to_raw_response_wrapper( - address_spaces.list, - ) - self.edit = async_to_raw_response_wrapper( - address_spaces.edit, - ) - - -class AddressSpacesResourceWithStreamingResponse: - def __init__(self, address_spaces: AddressSpacesResource) -> None: - self._address_spaces = address_spaces - - self.update = to_streamed_response_wrapper( - address_spaces.update, - ) - self.list = to_streamed_response_wrapper( - address_spaces.list, - ) - self.edit = to_streamed_response_wrapper( - address_spaces.edit, - ) - - -class AsyncAddressSpacesResourceWithStreamingResponse: - def __init__(self, address_spaces: AsyncAddressSpacesResource) -> None: - self._address_spaces = address_spaces - - self.update = async_to_streamed_response_wrapper( - address_spaces.update, - ) - self.list = async_to_streamed_response_wrapper( - address_spaces.list, - ) - self.edit = async_to_streamed_response_wrapper( - address_spaces.edit, - ) diff --git a/src/cloudflare/resources/magic_cloud_networking/on_ramps/on_ramps.py b/src/cloudflare/resources/magic_cloud_networking/on_ramps/on_ramps.py deleted file mode 100644 index aef7640bfba..00000000000 --- a/src/cloudflare/resources/magic_cloud_networking/on_ramps/on_ramps.py +++ /dev/null @@ -1,1238 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing import Type, cast -from typing_extensions import Literal - -import httpx - -from ...._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given -from ...._utils import path_template, maybe_transform, strip_not_given, async_maybe_transform -from ...._compat import cached_property -from ...._resource import SyncAPIResource, AsyncAPIResource -from ...._response import ( - BinaryAPIResponse, - AsyncBinaryAPIResponse, - StreamedBinaryAPIResponse, - AsyncStreamedBinaryAPIResponse, - to_raw_response_wrapper, - to_streamed_response_wrapper, - async_to_raw_response_wrapper, - to_custom_raw_response_wrapper, - async_to_streamed_response_wrapper, - to_custom_streamed_response_wrapper, - async_to_custom_raw_response_wrapper, - async_to_custom_streamed_response_wrapper, -) -from ...._wrappers import ResultWrapper -from ....pagination import SyncSinglePage, AsyncSinglePage -from .address_spaces import ( - AddressSpacesResource, - AsyncAddressSpacesResource, - AddressSpacesResourceWithRawResponse, - AsyncAddressSpacesResourceWithRawResponse, - AddressSpacesResourceWithStreamingResponse, - AsyncAddressSpacesResourceWithStreamingResponse, -) -from ...._base_client import AsyncPaginator, make_request_options -from ....types.magic_cloud_networking import ( - on_ramp_get_params, - on_ramp_edit_params, - on_ramp_list_params, - on_ramp_create_params, - on_ramp_delete_params, - on_ramp_update_params, -) -from ....types.magic_cloud_networking.on_ramp_get_response import OnRampGetResponse -from ....types.magic_cloud_networking.on_ramp_edit_response import OnRampEditResponse -from ....types.magic_cloud_networking.on_ramp_list_response import OnRampListResponse -from ....types.magic_cloud_networking.on_ramp_plan_response import OnRampPlanResponse -from ....types.magic_cloud_networking.on_ramp_apply_response import OnRampApplyResponse -from ....types.magic_cloud_networking.on_ramp_create_response import OnRampCreateResponse -from ....types.magic_cloud_networking.on_ramp_delete_response import OnRampDeleteResponse -from ....types.magic_cloud_networking.on_ramp_update_response import OnRampUpdateResponse - -__all__ = ["OnRampsResource", "AsyncOnRampsResource"] - - -class OnRampsResource(SyncAPIResource): - @cached_property - def address_spaces(self) -> AddressSpacesResource: - return AddressSpacesResource(self._client) - - @cached_property - def with_raw_response(self) -> OnRampsResourceWithRawResponse: - """ - This property can be used as a prefix for any HTTP method call to return - the raw response object instead of the parsed content. - - For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers - """ - return OnRampsResourceWithRawResponse(self) - - @cached_property - def with_streaming_response(self) -> OnRampsResourceWithStreamingResponse: - """ - An alternative to `.with_raw_response` that doesn't eagerly read the response body. - - For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response - """ - return OnRampsResourceWithStreamingResponse(self) - - def create( - self, - *, - account_id: str, - cloud_type: Literal["AWS", "AZURE", "GOOGLE"], - dynamic_routing: bool, - install_routes_in_cloud: bool, - install_routes_in_magic_wan: bool, - name: str, - type: Literal["OnrampTypeSingle", "OnrampTypeHub"], - adopted_hub_id: str | Omit = omit, - attached_hubs: SequenceNotStr[str] | Omit = omit, - attached_vpcs: SequenceNotStr[str] | Omit = omit, - cloud_asn: int | Omit = omit, - description: str | Omit = omit, - hub_provider_id: str | Omit = omit, - manage_hub_to_hub_attachments: bool | Omit = omit, - manage_vpc_to_hub_attachments: bool | Omit = omit, - region: str | Omit = omit, - vpc: str | Omit = omit, - forwarded: str | Omit = omit, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> OnRampCreateResponse: - """ - Create a new On-ramp (Closed Beta). - - Args: - dynamic_routing: Enables BGP routing. When enabling this feature, set both - install_routes_in_cloud and install_routes_in_magic_wan to false. - - cloud_asn: Sets the cloud-side ASN. If unset or zero, the cloud's default ASN takes effect. - - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not account_id: - raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - extra_headers = {**strip_not_given({"forwarded": forwarded}), **(extra_headers or {})} - return self._post( - path_template("/accounts/{account_id}/magic/cloud/onramps", account_id=account_id), - body=maybe_transform( - { - "cloud_type": cloud_type, - "dynamic_routing": dynamic_routing, - "install_routes_in_cloud": install_routes_in_cloud, - "install_routes_in_magic_wan": install_routes_in_magic_wan, - "name": name, - "type": type, - "adopted_hub_id": adopted_hub_id, - "attached_hubs": attached_hubs, - "attached_vpcs": attached_vpcs, - "cloud_asn": cloud_asn, - "description": description, - "hub_provider_id": hub_provider_id, - "manage_hub_to_hub_attachments": manage_hub_to_hub_attachments, - "manage_vpc_to_hub_attachments": manage_vpc_to_hub_attachments, - "region": region, - "vpc": vpc, - }, - on_ramp_create_params.OnRampCreateParams, - ), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - post_parser=ResultWrapper[OnRampCreateResponse]._unwrapper, - ), - cast_to=cast(Type[OnRampCreateResponse], ResultWrapper[OnRampCreateResponse]), - ) - - def update( - self, - onramp_id: str, - *, - account_id: str, - attached_hubs: SequenceNotStr[str] | Omit = omit, - attached_vpcs: SequenceNotStr[str] | Omit = omit, - description: str | Omit = omit, - install_routes_in_cloud: bool | Omit = omit, - install_routes_in_magic_wan: bool | Omit = omit, - manage_hub_to_hub_attachments: bool | Omit = omit, - manage_vpc_to_hub_attachments: bool | Omit = omit, - name: str | Omit = omit, - vpc: str | Omit = omit, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> OnRampUpdateResponse: - """ - Update an On-ramp (Closed Beta). - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not account_id: - raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not onramp_id: - raise ValueError(f"Expected a non-empty value for `onramp_id` but received {onramp_id!r}") - return self._put( - path_template( - "/accounts/{account_id}/magic/cloud/onramps/{onramp_id}", account_id=account_id, onramp_id=onramp_id - ), - body=maybe_transform( - { - "attached_hubs": attached_hubs, - "attached_vpcs": attached_vpcs, - "description": description, - "install_routes_in_cloud": install_routes_in_cloud, - "install_routes_in_magic_wan": install_routes_in_magic_wan, - "manage_hub_to_hub_attachments": manage_hub_to_hub_attachments, - "manage_vpc_to_hub_attachments": manage_vpc_to_hub_attachments, - "name": name, - "vpc": vpc, - }, - on_ramp_update_params.OnRampUpdateParams, - ), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - post_parser=ResultWrapper[OnRampUpdateResponse]._unwrapper, - ), - cast_to=cast(Type[OnRampUpdateResponse], ResultWrapper[OnRampUpdateResponse]), - ) - - def list( - self, - *, - account_id: str, - desc: bool | Omit = omit, - order_by: str | Omit = omit, - status: bool | Omit = omit, - vpcs: bool | Omit = omit, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> SyncSinglePage[OnRampListResponse]: - """ - List On-ramps (Closed Beta). - - Args: - order_by: One of ["updated_at", "id", "cloud_type", "name"]. - - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not account_id: - raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - return self._get_api_list( - path_template("/accounts/{account_id}/magic/cloud/onramps", account_id=account_id), - page=SyncSinglePage[OnRampListResponse], - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - query=maybe_transform( - { - "desc": desc, - "order_by": order_by, - "status": status, - "vpcs": vpcs, - }, - on_ramp_list_params.OnRampListParams, - ), - ), - model=OnRampListResponse, - ) - - def delete( - self, - onramp_id: str, - *, - account_id: str, - destroy: bool | Omit = omit, - force: bool | Omit = omit, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> OnRampDeleteResponse: - """ - Delete an On-ramp (Closed Beta). - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not account_id: - raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not onramp_id: - raise ValueError(f"Expected a non-empty value for `onramp_id` but received {onramp_id!r}") - return self._delete( - path_template( - "/accounts/{account_id}/magic/cloud/onramps/{onramp_id}", account_id=account_id, onramp_id=onramp_id - ), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - query=maybe_transform( - { - "destroy": destroy, - "force": force, - }, - on_ramp_delete_params.OnRampDeleteParams, - ), - post_parser=ResultWrapper[OnRampDeleteResponse]._unwrapper, - ), - cast_to=cast(Type[OnRampDeleteResponse], ResultWrapper[OnRampDeleteResponse]), - ) - - def apply( - self, - onramp_id: str, - *, - account_id: str, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> OnRampApplyResponse: - """ - Apply an On-ramp (Closed Beta). - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not account_id: - raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not onramp_id: - raise ValueError(f"Expected a non-empty value for `onramp_id` but received {onramp_id!r}") - return self._post( - path_template( - "/accounts/{account_id}/magic/cloud/onramps/{onramp_id}/apply", - account_id=account_id, - onramp_id=onramp_id, - ), - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=OnRampApplyResponse, - ) - - def edit( - self, - onramp_id: str, - *, - account_id: str, - attached_hubs: SequenceNotStr[str] | Omit = omit, - attached_vpcs: SequenceNotStr[str] | Omit = omit, - description: str | Omit = omit, - install_routes_in_cloud: bool | Omit = omit, - install_routes_in_magic_wan: bool | Omit = omit, - manage_hub_to_hub_attachments: bool | Omit = omit, - manage_vpc_to_hub_attachments: bool | Omit = omit, - name: str | Omit = omit, - vpc: str | Omit = omit, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> OnRampEditResponse: - """ - Update an On-ramp (Closed Beta). - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not account_id: - raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not onramp_id: - raise ValueError(f"Expected a non-empty value for `onramp_id` but received {onramp_id!r}") - return self._patch( - path_template( - "/accounts/{account_id}/magic/cloud/onramps/{onramp_id}", account_id=account_id, onramp_id=onramp_id - ), - body=maybe_transform( - { - "attached_hubs": attached_hubs, - "attached_vpcs": attached_vpcs, - "description": description, - "install_routes_in_cloud": install_routes_in_cloud, - "install_routes_in_magic_wan": install_routes_in_magic_wan, - "manage_hub_to_hub_attachments": manage_hub_to_hub_attachments, - "manage_vpc_to_hub_attachments": manage_vpc_to_hub_attachments, - "name": name, - "vpc": vpc, - }, - on_ramp_edit_params.OnRampEditParams, - ), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - post_parser=ResultWrapper[OnRampEditResponse]._unwrapper, - ), - cast_to=cast(Type[OnRampEditResponse], ResultWrapper[OnRampEditResponse]), - ) - - def export( - self, - onramp_id: str, - *, - account_id: str, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> BinaryAPIResponse: - """ - Export an On-ramp to terraform ready file(s) (Closed Beta). - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not account_id: - raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not onramp_id: - raise ValueError(f"Expected a non-empty value for `onramp_id` but received {onramp_id!r}") - extra_headers = {"Accept": "application/zip", **(extra_headers or {})} - return self._post( - path_template( - "/accounts/{account_id}/magic/cloud/onramps/{onramp_id}/export", - account_id=account_id, - onramp_id=onramp_id, - ), - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=BinaryAPIResponse, - ) - - def get( - self, - onramp_id: str, - *, - account_id: str, - planned_resources: bool | Omit = omit, - post_apply_resources: bool | Omit = omit, - status: bool | Omit = omit, - vpcs: bool | Omit = omit, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> OnRampGetResponse: - """ - Read an On-ramp (Closed Beta). - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not account_id: - raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not onramp_id: - raise ValueError(f"Expected a non-empty value for `onramp_id` but received {onramp_id!r}") - return self._get( - path_template( - "/accounts/{account_id}/magic/cloud/onramps/{onramp_id}", account_id=account_id, onramp_id=onramp_id - ), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - query=maybe_transform( - { - "planned_resources": planned_resources, - "post_apply_resources": post_apply_resources, - "status": status, - "vpcs": vpcs, - }, - on_ramp_get_params.OnRampGetParams, - ), - post_parser=ResultWrapper[OnRampGetResponse]._unwrapper, - ), - cast_to=cast(Type[OnRampGetResponse], ResultWrapper[OnRampGetResponse]), - ) - - def plan( - self, - onramp_id: str, - *, - account_id: str, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> OnRampPlanResponse: - """ - Plan an On-ramp (Closed Beta). - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not account_id: - raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not onramp_id: - raise ValueError(f"Expected a non-empty value for `onramp_id` but received {onramp_id!r}") - return self._post( - path_template( - "/accounts/{account_id}/magic/cloud/onramps/{onramp_id}/plan", - account_id=account_id, - onramp_id=onramp_id, - ), - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=OnRampPlanResponse, - ) - - -class AsyncOnRampsResource(AsyncAPIResource): - @cached_property - def address_spaces(self) -> AsyncAddressSpacesResource: - return AsyncAddressSpacesResource(self._client) - - @cached_property - def with_raw_response(self) -> AsyncOnRampsResourceWithRawResponse: - """ - This property can be used as a prefix for any HTTP method call to return - the raw response object instead of the parsed content. - - For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers - """ - return AsyncOnRampsResourceWithRawResponse(self) - - @cached_property - def with_streaming_response(self) -> AsyncOnRampsResourceWithStreamingResponse: - """ - An alternative to `.with_raw_response` that doesn't eagerly read the response body. - - For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response - """ - return AsyncOnRampsResourceWithStreamingResponse(self) - - async def create( - self, - *, - account_id: str, - cloud_type: Literal["AWS", "AZURE", "GOOGLE"], - dynamic_routing: bool, - install_routes_in_cloud: bool, - install_routes_in_magic_wan: bool, - name: str, - type: Literal["OnrampTypeSingle", "OnrampTypeHub"], - adopted_hub_id: str | Omit = omit, - attached_hubs: SequenceNotStr[str] | Omit = omit, - attached_vpcs: SequenceNotStr[str] | Omit = omit, - cloud_asn: int | Omit = omit, - description: str | Omit = omit, - hub_provider_id: str | Omit = omit, - manage_hub_to_hub_attachments: bool | Omit = omit, - manage_vpc_to_hub_attachments: bool | Omit = omit, - region: str | Omit = omit, - vpc: str | Omit = omit, - forwarded: str | Omit = omit, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> OnRampCreateResponse: - """ - Create a new On-ramp (Closed Beta). - - Args: - dynamic_routing: Enables BGP routing. When enabling this feature, set both - install_routes_in_cloud and install_routes_in_magic_wan to false. - - cloud_asn: Sets the cloud-side ASN. If unset or zero, the cloud's default ASN takes effect. - - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not account_id: - raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - extra_headers = {**strip_not_given({"forwarded": forwarded}), **(extra_headers or {})} - return await self._post( - path_template("/accounts/{account_id}/magic/cloud/onramps", account_id=account_id), - body=await async_maybe_transform( - { - "cloud_type": cloud_type, - "dynamic_routing": dynamic_routing, - "install_routes_in_cloud": install_routes_in_cloud, - "install_routes_in_magic_wan": install_routes_in_magic_wan, - "name": name, - "type": type, - "adopted_hub_id": adopted_hub_id, - "attached_hubs": attached_hubs, - "attached_vpcs": attached_vpcs, - "cloud_asn": cloud_asn, - "description": description, - "hub_provider_id": hub_provider_id, - "manage_hub_to_hub_attachments": manage_hub_to_hub_attachments, - "manage_vpc_to_hub_attachments": manage_vpc_to_hub_attachments, - "region": region, - "vpc": vpc, - }, - on_ramp_create_params.OnRampCreateParams, - ), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - post_parser=ResultWrapper[OnRampCreateResponse]._unwrapper, - ), - cast_to=cast(Type[OnRampCreateResponse], ResultWrapper[OnRampCreateResponse]), - ) - - async def update( - self, - onramp_id: str, - *, - account_id: str, - attached_hubs: SequenceNotStr[str] | Omit = omit, - attached_vpcs: SequenceNotStr[str] | Omit = omit, - description: str | Omit = omit, - install_routes_in_cloud: bool | Omit = omit, - install_routes_in_magic_wan: bool | Omit = omit, - manage_hub_to_hub_attachments: bool | Omit = omit, - manage_vpc_to_hub_attachments: bool | Omit = omit, - name: str | Omit = omit, - vpc: str | Omit = omit, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> OnRampUpdateResponse: - """ - Update an On-ramp (Closed Beta). - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not account_id: - raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not onramp_id: - raise ValueError(f"Expected a non-empty value for `onramp_id` but received {onramp_id!r}") - return await self._put( - path_template( - "/accounts/{account_id}/magic/cloud/onramps/{onramp_id}", account_id=account_id, onramp_id=onramp_id - ), - body=await async_maybe_transform( - { - "attached_hubs": attached_hubs, - "attached_vpcs": attached_vpcs, - "description": description, - "install_routes_in_cloud": install_routes_in_cloud, - "install_routes_in_magic_wan": install_routes_in_magic_wan, - "manage_hub_to_hub_attachments": manage_hub_to_hub_attachments, - "manage_vpc_to_hub_attachments": manage_vpc_to_hub_attachments, - "name": name, - "vpc": vpc, - }, - on_ramp_update_params.OnRampUpdateParams, - ), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - post_parser=ResultWrapper[OnRampUpdateResponse]._unwrapper, - ), - cast_to=cast(Type[OnRampUpdateResponse], ResultWrapper[OnRampUpdateResponse]), - ) - - def list( - self, - *, - account_id: str, - desc: bool | Omit = omit, - order_by: str | Omit = omit, - status: bool | Omit = omit, - vpcs: bool | Omit = omit, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> AsyncPaginator[OnRampListResponse, AsyncSinglePage[OnRampListResponse]]: - """ - List On-ramps (Closed Beta). - - Args: - order_by: One of ["updated_at", "id", "cloud_type", "name"]. - - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not account_id: - raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - return self._get_api_list( - path_template("/accounts/{account_id}/magic/cloud/onramps", account_id=account_id), - page=AsyncSinglePage[OnRampListResponse], - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - query=maybe_transform( - { - "desc": desc, - "order_by": order_by, - "status": status, - "vpcs": vpcs, - }, - on_ramp_list_params.OnRampListParams, - ), - ), - model=OnRampListResponse, - ) - - async def delete( - self, - onramp_id: str, - *, - account_id: str, - destroy: bool | Omit = omit, - force: bool | Omit = omit, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> OnRampDeleteResponse: - """ - Delete an On-ramp (Closed Beta). - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not account_id: - raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not onramp_id: - raise ValueError(f"Expected a non-empty value for `onramp_id` but received {onramp_id!r}") - return await self._delete( - path_template( - "/accounts/{account_id}/magic/cloud/onramps/{onramp_id}", account_id=account_id, onramp_id=onramp_id - ), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - query=await async_maybe_transform( - { - "destroy": destroy, - "force": force, - }, - on_ramp_delete_params.OnRampDeleteParams, - ), - post_parser=ResultWrapper[OnRampDeleteResponse]._unwrapper, - ), - cast_to=cast(Type[OnRampDeleteResponse], ResultWrapper[OnRampDeleteResponse]), - ) - - async def apply( - self, - onramp_id: str, - *, - account_id: str, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> OnRampApplyResponse: - """ - Apply an On-ramp (Closed Beta). - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not account_id: - raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not onramp_id: - raise ValueError(f"Expected a non-empty value for `onramp_id` but received {onramp_id!r}") - return await self._post( - path_template( - "/accounts/{account_id}/magic/cloud/onramps/{onramp_id}/apply", - account_id=account_id, - onramp_id=onramp_id, - ), - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=OnRampApplyResponse, - ) - - async def edit( - self, - onramp_id: str, - *, - account_id: str, - attached_hubs: SequenceNotStr[str] | Omit = omit, - attached_vpcs: SequenceNotStr[str] | Omit = omit, - description: str | Omit = omit, - install_routes_in_cloud: bool | Omit = omit, - install_routes_in_magic_wan: bool | Omit = omit, - manage_hub_to_hub_attachments: bool | Omit = omit, - manage_vpc_to_hub_attachments: bool | Omit = omit, - name: str | Omit = omit, - vpc: str | Omit = omit, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> OnRampEditResponse: - """ - Update an On-ramp (Closed Beta). - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not account_id: - raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not onramp_id: - raise ValueError(f"Expected a non-empty value for `onramp_id` but received {onramp_id!r}") - return await self._patch( - path_template( - "/accounts/{account_id}/magic/cloud/onramps/{onramp_id}", account_id=account_id, onramp_id=onramp_id - ), - body=await async_maybe_transform( - { - "attached_hubs": attached_hubs, - "attached_vpcs": attached_vpcs, - "description": description, - "install_routes_in_cloud": install_routes_in_cloud, - "install_routes_in_magic_wan": install_routes_in_magic_wan, - "manage_hub_to_hub_attachments": manage_hub_to_hub_attachments, - "manage_vpc_to_hub_attachments": manage_vpc_to_hub_attachments, - "name": name, - "vpc": vpc, - }, - on_ramp_edit_params.OnRampEditParams, - ), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - post_parser=ResultWrapper[OnRampEditResponse]._unwrapper, - ), - cast_to=cast(Type[OnRampEditResponse], ResultWrapper[OnRampEditResponse]), - ) - - async def export( - self, - onramp_id: str, - *, - account_id: str, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> AsyncBinaryAPIResponse: - """ - Export an On-ramp to terraform ready file(s) (Closed Beta). - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not account_id: - raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not onramp_id: - raise ValueError(f"Expected a non-empty value for `onramp_id` but received {onramp_id!r}") - extra_headers = {"Accept": "application/zip", **(extra_headers or {})} - return await self._post( - path_template( - "/accounts/{account_id}/magic/cloud/onramps/{onramp_id}/export", - account_id=account_id, - onramp_id=onramp_id, - ), - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=AsyncBinaryAPIResponse, - ) - - async def get( - self, - onramp_id: str, - *, - account_id: str, - planned_resources: bool | Omit = omit, - post_apply_resources: bool | Omit = omit, - status: bool | Omit = omit, - vpcs: bool | Omit = omit, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> OnRampGetResponse: - """ - Read an On-ramp (Closed Beta). - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not account_id: - raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not onramp_id: - raise ValueError(f"Expected a non-empty value for `onramp_id` but received {onramp_id!r}") - return await self._get( - path_template( - "/accounts/{account_id}/magic/cloud/onramps/{onramp_id}", account_id=account_id, onramp_id=onramp_id - ), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - query=await async_maybe_transform( - { - "planned_resources": planned_resources, - "post_apply_resources": post_apply_resources, - "status": status, - "vpcs": vpcs, - }, - on_ramp_get_params.OnRampGetParams, - ), - post_parser=ResultWrapper[OnRampGetResponse]._unwrapper, - ), - cast_to=cast(Type[OnRampGetResponse], ResultWrapper[OnRampGetResponse]), - ) - - async def plan( - self, - onramp_id: str, - *, - account_id: str, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> OnRampPlanResponse: - """ - Plan an On-ramp (Closed Beta). - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not account_id: - raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not onramp_id: - raise ValueError(f"Expected a non-empty value for `onramp_id` but received {onramp_id!r}") - return await self._post( - path_template( - "/accounts/{account_id}/magic/cloud/onramps/{onramp_id}/plan", - account_id=account_id, - onramp_id=onramp_id, - ), - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=OnRampPlanResponse, - ) - - -class OnRampsResourceWithRawResponse: - def __init__(self, on_ramps: OnRampsResource) -> None: - self._on_ramps = on_ramps - - self.create = to_raw_response_wrapper( - on_ramps.create, - ) - self.update = to_raw_response_wrapper( - on_ramps.update, - ) - self.list = to_raw_response_wrapper( - on_ramps.list, - ) - self.delete = to_raw_response_wrapper( - on_ramps.delete, - ) - self.apply = to_raw_response_wrapper( - on_ramps.apply, - ) - self.edit = to_raw_response_wrapper( - on_ramps.edit, - ) - self.export = to_custom_raw_response_wrapper( - on_ramps.export, - BinaryAPIResponse, - ) - self.get = to_raw_response_wrapper( - on_ramps.get, - ) - self.plan = to_raw_response_wrapper( - on_ramps.plan, - ) - - @cached_property - def address_spaces(self) -> AddressSpacesResourceWithRawResponse: - return AddressSpacesResourceWithRawResponse(self._on_ramps.address_spaces) - - -class AsyncOnRampsResourceWithRawResponse: - def __init__(self, on_ramps: AsyncOnRampsResource) -> None: - self._on_ramps = on_ramps - - self.create = async_to_raw_response_wrapper( - on_ramps.create, - ) - self.update = async_to_raw_response_wrapper( - on_ramps.update, - ) - self.list = async_to_raw_response_wrapper( - on_ramps.list, - ) - self.delete = async_to_raw_response_wrapper( - on_ramps.delete, - ) - self.apply = async_to_raw_response_wrapper( - on_ramps.apply, - ) - self.edit = async_to_raw_response_wrapper( - on_ramps.edit, - ) - self.export = async_to_custom_raw_response_wrapper( - on_ramps.export, - AsyncBinaryAPIResponse, - ) - self.get = async_to_raw_response_wrapper( - on_ramps.get, - ) - self.plan = async_to_raw_response_wrapper( - on_ramps.plan, - ) - - @cached_property - def address_spaces(self) -> AsyncAddressSpacesResourceWithRawResponse: - return AsyncAddressSpacesResourceWithRawResponse(self._on_ramps.address_spaces) - - -class OnRampsResourceWithStreamingResponse: - def __init__(self, on_ramps: OnRampsResource) -> None: - self._on_ramps = on_ramps - - self.create = to_streamed_response_wrapper( - on_ramps.create, - ) - self.update = to_streamed_response_wrapper( - on_ramps.update, - ) - self.list = to_streamed_response_wrapper( - on_ramps.list, - ) - self.delete = to_streamed_response_wrapper( - on_ramps.delete, - ) - self.apply = to_streamed_response_wrapper( - on_ramps.apply, - ) - self.edit = to_streamed_response_wrapper( - on_ramps.edit, - ) - self.export = to_custom_streamed_response_wrapper( - on_ramps.export, - StreamedBinaryAPIResponse, - ) - self.get = to_streamed_response_wrapper( - on_ramps.get, - ) - self.plan = to_streamed_response_wrapper( - on_ramps.plan, - ) - - @cached_property - def address_spaces(self) -> AddressSpacesResourceWithStreamingResponse: - return AddressSpacesResourceWithStreamingResponse(self._on_ramps.address_spaces) - - -class AsyncOnRampsResourceWithStreamingResponse: - def __init__(self, on_ramps: AsyncOnRampsResource) -> None: - self._on_ramps = on_ramps - - self.create = async_to_streamed_response_wrapper( - on_ramps.create, - ) - self.update = async_to_streamed_response_wrapper( - on_ramps.update, - ) - self.list = async_to_streamed_response_wrapper( - on_ramps.list, - ) - self.delete = async_to_streamed_response_wrapper( - on_ramps.delete, - ) - self.apply = async_to_streamed_response_wrapper( - on_ramps.apply, - ) - self.edit = async_to_streamed_response_wrapper( - on_ramps.edit, - ) - self.export = async_to_custom_streamed_response_wrapper( - on_ramps.export, - AsyncStreamedBinaryAPIResponse, - ) - self.get = async_to_streamed_response_wrapper( - on_ramps.get, - ) - self.plan = async_to_streamed_response_wrapper( - on_ramps.plan, - ) - - @cached_property - def address_spaces(self) -> AsyncAddressSpacesResourceWithStreamingResponse: - return AsyncAddressSpacesResourceWithStreamingResponse(self._on_ramps.address_spaces) diff --git a/src/cloudflare/resources/magic_cloud_networking/resources.py b/src/cloudflare/resources/magic_cloud_networking/resources.py deleted file mode 100644 index bf3ddc2c1ef..00000000000 --- a/src/cloudflare/resources/magic_cloud_networking/resources.py +++ /dev/null @@ -1,839 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing import List, Type, cast -from typing_extensions import Literal - -import httpx - -from ..._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given -from ..._utils import path_template, maybe_transform, async_maybe_transform -from ..._compat import cached_property -from ..._resource import SyncAPIResource, AsyncAPIResource -from ..._response import ( - BinaryAPIResponse, - AsyncBinaryAPIResponse, - StreamedBinaryAPIResponse, - AsyncStreamedBinaryAPIResponse, - to_raw_response_wrapper, - to_streamed_response_wrapper, - async_to_raw_response_wrapper, - to_custom_raw_response_wrapper, - async_to_streamed_response_wrapper, - to_custom_streamed_response_wrapper, - async_to_custom_raw_response_wrapper, - async_to_custom_streamed_response_wrapper, -) -from ..._wrappers import ResultWrapper -from ...pagination import SyncV4PagePaginationArray, AsyncV4PagePaginationArray -from ..._base_client import AsyncPaginator, make_request_options -from ...types.magic_cloud_networking import ( - resource_get_params, - resource_list_params, - resource_export_params, - resource_policy_preview_params, -) -from ...types.magic_cloud_networking.resource_get_response import ResourceGetResponse -from ...types.magic_cloud_networking.resource_list_response import ResourceListResponse -from ...types.magic_cloud_networking.resource_policy_preview_response import ResourcePolicyPreviewResponse - -__all__ = ["ResourcesResource", "AsyncResourcesResource"] - - -class ResourcesResource(SyncAPIResource): - @cached_property - def with_raw_response(self) -> ResourcesResourceWithRawResponse: - """ - This property can be used as a prefix for any HTTP method call to return - the raw response object instead of the parsed content. - - For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers - """ - return ResourcesResourceWithRawResponse(self) - - @cached_property - def with_streaming_response(self) -> ResourcesResourceWithStreamingResponse: - """ - An alternative to `.with_raw_response` that doesn't eagerly read the response body. - - For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response - """ - return ResourcesResourceWithStreamingResponse(self) - - def list( - self, - *, - account_id: str, - cloudflare: bool | Omit = omit, - desc: bool | Omit = omit, - managed: bool | Omit = omit, - order_by: str | Omit = omit, - page: int | Omit = omit, - per_page: int | Omit = omit, - provider_id: str | Omit = omit, - region: str | Omit = omit, - resource_group: str | Omit = omit, - resource_id: SequenceNotStr[str] | Omit = omit, - resource_type: List[ - Literal[ - "aws_customer_gateway", - "aws_egress_only_internet_gateway", - "aws_internet_gateway", - "aws_instance", - "aws_network_interface", - "aws_route", - "aws_route_table", - "aws_route_table_association", - "aws_subnet", - "aws_vpc", - "aws_vpc_ipv4_cidr_block_association", - "aws_vpn_connection", - "aws_vpn_connection_route", - "aws_vpn_gateway", - "aws_security_group", - "aws_vpc_security_group_ingress_rule", - "aws_vpc_security_group_egress_rule", - "aws_ec2_managed_prefix_list", - "aws_ec2_transit_gateway", - "aws_ec2_transit_gateway_prefix_list_reference", - "aws_ec2_transit_gateway_vpc_attachment", - "azurerm_application_security_group", - "azurerm_lb", - "azurerm_lb_backend_address_pool", - "azurerm_lb_nat_pool", - "azurerm_lb_nat_rule", - "azurerm_lb_rule", - "azurerm_local_network_gateway", - "azurerm_network_interface", - "azurerm_network_interface_application_security_group_association", - "azurerm_network_interface_backend_address_pool_association", - "azurerm_network_interface_security_group_association", - "azurerm_network_security_group", - "azurerm_public_ip", - "azurerm_route", - "azurerm_route_table", - "azurerm_subnet", - "azurerm_subnet_route_table_association", - "azurerm_virtual_machine", - "azurerm_virtual_network_gateway_connection", - "azurerm_virtual_network", - "azurerm_virtual_network_gateway", - "google_compute_network", - "google_compute_subnetwork", - "google_compute_vpn_gateway", - "google_compute_vpn_tunnel", - "google_compute_route", - "google_compute_address", - "google_compute_global_address", - "google_compute_router", - "google_compute_interconnect_attachment", - "google_compute_ha_vpn_gateway", - "google_compute_forwarding_rule", - "google_compute_network_firewall_policy", - "google_compute_network_firewall_policy_rule", - "cloudflare_static_route", - "cloudflare_ipsec_tunnel", - ] - ] - | Omit = omit, - search: SequenceNotStr[str] | Omit = omit, - v2: bool | Omit = omit, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> SyncV4PagePaginationArray[ResourceListResponse]: - """ - List resources in the Resource Catalog (Closed Beta). - - Args: - order_by: One of ["id", "resource_type", "region"]. - - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not account_id: - raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - return self._get_api_list( - path_template("/accounts/{account_id}/magic/cloud/resources", account_id=account_id), - page=SyncV4PagePaginationArray[ResourceListResponse], - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - query=maybe_transform( - { - "cloudflare": cloudflare, - "desc": desc, - "managed": managed, - "order_by": order_by, - "page": page, - "per_page": per_page, - "provider_id": provider_id, - "region": region, - "resource_group": resource_group, - "resource_id": resource_id, - "resource_type": resource_type, - "search": search, - "v2": v2, - }, - resource_list_params.ResourceListParams, - ), - ), - model=ResourceListResponse, - ) - - def export( - self, - *, - account_id: str, - desc: bool | Omit = omit, - order_by: str | Omit = omit, - provider_id: str | Omit = omit, - region: str | Omit = omit, - resource_group: str | Omit = omit, - resource_id: SequenceNotStr[str] | Omit = omit, - resource_type: List[ - Literal[ - "aws_customer_gateway", - "aws_egress_only_internet_gateway", - "aws_internet_gateway", - "aws_instance", - "aws_network_interface", - "aws_route", - "aws_route_table", - "aws_route_table_association", - "aws_subnet", - "aws_vpc", - "aws_vpc_ipv4_cidr_block_association", - "aws_vpn_connection", - "aws_vpn_connection_route", - "aws_vpn_gateway", - "aws_security_group", - "aws_vpc_security_group_ingress_rule", - "aws_vpc_security_group_egress_rule", - "aws_ec2_managed_prefix_list", - "aws_ec2_transit_gateway", - "aws_ec2_transit_gateway_prefix_list_reference", - "aws_ec2_transit_gateway_vpc_attachment", - "azurerm_application_security_group", - "azurerm_lb", - "azurerm_lb_backend_address_pool", - "azurerm_lb_nat_pool", - "azurerm_lb_nat_rule", - "azurerm_lb_rule", - "azurerm_local_network_gateway", - "azurerm_network_interface", - "azurerm_network_interface_application_security_group_association", - "azurerm_network_interface_backend_address_pool_association", - "azurerm_network_interface_security_group_association", - "azurerm_network_security_group", - "azurerm_public_ip", - "azurerm_route", - "azurerm_route_table", - "azurerm_subnet", - "azurerm_subnet_route_table_association", - "azurerm_virtual_machine", - "azurerm_virtual_network_gateway_connection", - "azurerm_virtual_network", - "azurerm_virtual_network_gateway", - "google_compute_network", - "google_compute_subnetwork", - "google_compute_vpn_gateway", - "google_compute_vpn_tunnel", - "google_compute_route", - "google_compute_address", - "google_compute_global_address", - "google_compute_router", - "google_compute_interconnect_attachment", - "google_compute_ha_vpn_gateway", - "google_compute_forwarding_rule", - "google_compute_network_firewall_policy", - "google_compute_network_firewall_policy_rule", - "cloudflare_static_route", - "cloudflare_ipsec_tunnel", - ] - ] - | Omit = omit, - search: SequenceNotStr[str] | Omit = omit, - v2: bool | Omit = omit, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> BinaryAPIResponse: - """ - Export resources in the Resource Catalog as a JSON file (Closed Beta). - - Args: - order_by: One of ["id", "resource_type", "region"]. - - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not account_id: - raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - extra_headers = {"Accept": "application/octet-stream", **(extra_headers or {})} - return self._get( - path_template("/accounts/{account_id}/magic/cloud/resources/export", account_id=account_id), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - query=maybe_transform( - { - "desc": desc, - "order_by": order_by, - "provider_id": provider_id, - "region": region, - "resource_group": resource_group, - "resource_id": resource_id, - "resource_type": resource_type, - "search": search, - "v2": v2, - }, - resource_export_params.ResourceExportParams, - ), - ), - cast_to=BinaryAPIResponse, - ) - - def get( - self, - resource_id: str, - *, - account_id: str, - v2: bool | Omit = omit, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> ResourceGetResponse: - """ - Read an resource from the Resource Catalog (Closed Beta). - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not account_id: - raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not resource_id: - raise ValueError(f"Expected a non-empty value for `resource_id` but received {resource_id!r}") - return self._get( - path_template( - "/accounts/{account_id}/magic/cloud/resources/{resource_id}", - account_id=account_id, - resource_id=resource_id, - ), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - query=maybe_transform({"v2": v2}, resource_get_params.ResourceGetParams), - post_parser=ResultWrapper[ResourceGetResponse]._unwrapper, - ), - cast_to=cast(Type[ResourceGetResponse], ResultWrapper[ResourceGetResponse]), - ) - - def policy_preview( - self, - *, - account_id: str, - policy: str, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> str: - """ - Preview Rego query result against the latest resource catalog (Closed Beta). - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not account_id: - raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - return self._post( - path_template("/accounts/{account_id}/magic/cloud/resources/policy-preview", account_id=account_id), - body=maybe_transform({"policy": policy}, resource_policy_preview_params.ResourcePolicyPreviewParams), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - post_parser=ResultWrapper[ResourcePolicyPreviewResponse]._unwrapper, - ), - cast_to=cast(Type[str], ResultWrapper[str]), - ) - - -class AsyncResourcesResource(AsyncAPIResource): - @cached_property - def with_raw_response(self) -> AsyncResourcesResourceWithRawResponse: - """ - This property can be used as a prefix for any HTTP method call to return - the raw response object instead of the parsed content. - - For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers - """ - return AsyncResourcesResourceWithRawResponse(self) - - @cached_property - def with_streaming_response(self) -> AsyncResourcesResourceWithStreamingResponse: - """ - An alternative to `.with_raw_response` that doesn't eagerly read the response body. - - For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response - """ - return AsyncResourcesResourceWithStreamingResponse(self) - - def list( - self, - *, - account_id: str, - cloudflare: bool | Omit = omit, - desc: bool | Omit = omit, - managed: bool | Omit = omit, - order_by: str | Omit = omit, - page: int | Omit = omit, - per_page: int | Omit = omit, - provider_id: str | Omit = omit, - region: str | Omit = omit, - resource_group: str | Omit = omit, - resource_id: SequenceNotStr[str] | Omit = omit, - resource_type: List[ - Literal[ - "aws_customer_gateway", - "aws_egress_only_internet_gateway", - "aws_internet_gateway", - "aws_instance", - "aws_network_interface", - "aws_route", - "aws_route_table", - "aws_route_table_association", - "aws_subnet", - "aws_vpc", - "aws_vpc_ipv4_cidr_block_association", - "aws_vpn_connection", - "aws_vpn_connection_route", - "aws_vpn_gateway", - "aws_security_group", - "aws_vpc_security_group_ingress_rule", - "aws_vpc_security_group_egress_rule", - "aws_ec2_managed_prefix_list", - "aws_ec2_transit_gateway", - "aws_ec2_transit_gateway_prefix_list_reference", - "aws_ec2_transit_gateway_vpc_attachment", - "azurerm_application_security_group", - "azurerm_lb", - "azurerm_lb_backend_address_pool", - "azurerm_lb_nat_pool", - "azurerm_lb_nat_rule", - "azurerm_lb_rule", - "azurerm_local_network_gateway", - "azurerm_network_interface", - "azurerm_network_interface_application_security_group_association", - "azurerm_network_interface_backend_address_pool_association", - "azurerm_network_interface_security_group_association", - "azurerm_network_security_group", - "azurerm_public_ip", - "azurerm_route", - "azurerm_route_table", - "azurerm_subnet", - "azurerm_subnet_route_table_association", - "azurerm_virtual_machine", - "azurerm_virtual_network_gateway_connection", - "azurerm_virtual_network", - "azurerm_virtual_network_gateway", - "google_compute_network", - "google_compute_subnetwork", - "google_compute_vpn_gateway", - "google_compute_vpn_tunnel", - "google_compute_route", - "google_compute_address", - "google_compute_global_address", - "google_compute_router", - "google_compute_interconnect_attachment", - "google_compute_ha_vpn_gateway", - "google_compute_forwarding_rule", - "google_compute_network_firewall_policy", - "google_compute_network_firewall_policy_rule", - "cloudflare_static_route", - "cloudflare_ipsec_tunnel", - ] - ] - | Omit = omit, - search: SequenceNotStr[str] | Omit = omit, - v2: bool | Omit = omit, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> AsyncPaginator[ResourceListResponse, AsyncV4PagePaginationArray[ResourceListResponse]]: - """ - List resources in the Resource Catalog (Closed Beta). - - Args: - order_by: One of ["id", "resource_type", "region"]. - - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not account_id: - raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - return self._get_api_list( - path_template("/accounts/{account_id}/magic/cloud/resources", account_id=account_id), - page=AsyncV4PagePaginationArray[ResourceListResponse], - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - query=maybe_transform( - { - "cloudflare": cloudflare, - "desc": desc, - "managed": managed, - "order_by": order_by, - "page": page, - "per_page": per_page, - "provider_id": provider_id, - "region": region, - "resource_group": resource_group, - "resource_id": resource_id, - "resource_type": resource_type, - "search": search, - "v2": v2, - }, - resource_list_params.ResourceListParams, - ), - ), - model=ResourceListResponse, - ) - - async def export( - self, - *, - account_id: str, - desc: bool | Omit = omit, - order_by: str | Omit = omit, - provider_id: str | Omit = omit, - region: str | Omit = omit, - resource_group: str | Omit = omit, - resource_id: SequenceNotStr[str] | Omit = omit, - resource_type: List[ - Literal[ - "aws_customer_gateway", - "aws_egress_only_internet_gateway", - "aws_internet_gateway", - "aws_instance", - "aws_network_interface", - "aws_route", - "aws_route_table", - "aws_route_table_association", - "aws_subnet", - "aws_vpc", - "aws_vpc_ipv4_cidr_block_association", - "aws_vpn_connection", - "aws_vpn_connection_route", - "aws_vpn_gateway", - "aws_security_group", - "aws_vpc_security_group_ingress_rule", - "aws_vpc_security_group_egress_rule", - "aws_ec2_managed_prefix_list", - "aws_ec2_transit_gateway", - "aws_ec2_transit_gateway_prefix_list_reference", - "aws_ec2_transit_gateway_vpc_attachment", - "azurerm_application_security_group", - "azurerm_lb", - "azurerm_lb_backend_address_pool", - "azurerm_lb_nat_pool", - "azurerm_lb_nat_rule", - "azurerm_lb_rule", - "azurerm_local_network_gateway", - "azurerm_network_interface", - "azurerm_network_interface_application_security_group_association", - "azurerm_network_interface_backend_address_pool_association", - "azurerm_network_interface_security_group_association", - "azurerm_network_security_group", - "azurerm_public_ip", - "azurerm_route", - "azurerm_route_table", - "azurerm_subnet", - "azurerm_subnet_route_table_association", - "azurerm_virtual_machine", - "azurerm_virtual_network_gateway_connection", - "azurerm_virtual_network", - "azurerm_virtual_network_gateway", - "google_compute_network", - "google_compute_subnetwork", - "google_compute_vpn_gateway", - "google_compute_vpn_tunnel", - "google_compute_route", - "google_compute_address", - "google_compute_global_address", - "google_compute_router", - "google_compute_interconnect_attachment", - "google_compute_ha_vpn_gateway", - "google_compute_forwarding_rule", - "google_compute_network_firewall_policy", - "google_compute_network_firewall_policy_rule", - "cloudflare_static_route", - "cloudflare_ipsec_tunnel", - ] - ] - | Omit = omit, - search: SequenceNotStr[str] | Omit = omit, - v2: bool | Omit = omit, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> AsyncBinaryAPIResponse: - """ - Export resources in the Resource Catalog as a JSON file (Closed Beta). - - Args: - order_by: One of ["id", "resource_type", "region"]. - - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not account_id: - raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - extra_headers = {"Accept": "application/octet-stream", **(extra_headers or {})} - return await self._get( - path_template("/accounts/{account_id}/magic/cloud/resources/export", account_id=account_id), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - query=await async_maybe_transform( - { - "desc": desc, - "order_by": order_by, - "provider_id": provider_id, - "region": region, - "resource_group": resource_group, - "resource_id": resource_id, - "resource_type": resource_type, - "search": search, - "v2": v2, - }, - resource_export_params.ResourceExportParams, - ), - ), - cast_to=AsyncBinaryAPIResponse, - ) - - async def get( - self, - resource_id: str, - *, - account_id: str, - v2: bool | Omit = omit, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> ResourceGetResponse: - """ - Read an resource from the Resource Catalog (Closed Beta). - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not account_id: - raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not resource_id: - raise ValueError(f"Expected a non-empty value for `resource_id` but received {resource_id!r}") - return await self._get( - path_template( - "/accounts/{account_id}/magic/cloud/resources/{resource_id}", - account_id=account_id, - resource_id=resource_id, - ), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - query=await async_maybe_transform({"v2": v2}, resource_get_params.ResourceGetParams), - post_parser=ResultWrapper[ResourceGetResponse]._unwrapper, - ), - cast_to=cast(Type[ResourceGetResponse], ResultWrapper[ResourceGetResponse]), - ) - - async def policy_preview( - self, - *, - account_id: str, - policy: str, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> str: - """ - Preview Rego query result against the latest resource catalog (Closed Beta). - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not account_id: - raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - return await self._post( - path_template("/accounts/{account_id}/magic/cloud/resources/policy-preview", account_id=account_id), - body=await async_maybe_transform( - {"policy": policy}, resource_policy_preview_params.ResourcePolicyPreviewParams - ), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - post_parser=ResultWrapper[ResourcePolicyPreviewResponse]._unwrapper, - ), - cast_to=cast(Type[str], ResultWrapper[str]), - ) - - -class ResourcesResourceWithRawResponse: - def __init__(self, resources: ResourcesResource) -> None: - self._resources = resources - - self.list = to_raw_response_wrapper( - resources.list, - ) - self.export = to_custom_raw_response_wrapper( - resources.export, - BinaryAPIResponse, - ) - self.get = to_raw_response_wrapper( - resources.get, - ) - self.policy_preview = to_raw_response_wrapper( - resources.policy_preview, - ) - - -class AsyncResourcesResourceWithRawResponse: - def __init__(self, resources: AsyncResourcesResource) -> None: - self._resources = resources - - self.list = async_to_raw_response_wrapper( - resources.list, - ) - self.export = async_to_custom_raw_response_wrapper( - resources.export, - AsyncBinaryAPIResponse, - ) - self.get = async_to_raw_response_wrapper( - resources.get, - ) - self.policy_preview = async_to_raw_response_wrapper( - resources.policy_preview, - ) - - -class ResourcesResourceWithStreamingResponse: - def __init__(self, resources: ResourcesResource) -> None: - self._resources = resources - - self.list = to_streamed_response_wrapper( - resources.list, - ) - self.export = to_custom_streamed_response_wrapper( - resources.export, - StreamedBinaryAPIResponse, - ) - self.get = to_streamed_response_wrapper( - resources.get, - ) - self.policy_preview = to_streamed_response_wrapper( - resources.policy_preview, - ) - - -class AsyncResourcesResourceWithStreamingResponse: - def __init__(self, resources: AsyncResourcesResource) -> None: - self._resources = resources - - self.list = async_to_streamed_response_wrapper( - resources.list, - ) - self.export = async_to_custom_streamed_response_wrapper( - resources.export, - AsyncStreamedBinaryAPIResponse, - ) - self.get = async_to_streamed_response_wrapper( - resources.get, - ) - self.policy_preview = async_to_streamed_response_wrapper( - resources.policy_preview, - ) diff --git a/src/cloudflare/resources/magic_network_monitoring/api.md b/src/cloudflare/resources/magic_network_monitoring/api.md index 3f86cf66f2f..56464773d10 100644 --- a/src/cloudflare/resources/magic_network_monitoring/api.md +++ b/src/cloudflare/resources/magic_network_monitoring/api.md @@ -63,4 +63,4 @@ from cloudflare.types.magic_network_monitoring.rules import Advertisement Methods: -- client.magic_network_monitoring.rules.advertisements.edit(rule_id, \*, account_id, \*\*params) -> Optional[Advertisement] +- client.magic_network_monitoring.rules.advertisements.edit(rule_id, \*, account_id) -> Optional[Advertisement] diff --git a/src/cloudflare/resources/magic_network_monitoring/rules/advertisements.py b/src/cloudflare/resources/magic_network_monitoring/rules/advertisements.py index 8324bd8b499..bbe051645c7 100644 --- a/src/cloudflare/resources/magic_network_monitoring/rules/advertisements.py +++ b/src/cloudflare/resources/magic_network_monitoring/rules/advertisements.py @@ -7,7 +7,7 @@ import httpx from ...._types import Body, Query, Headers, NotGiven, not_given -from ...._utils import path_template, maybe_transform, async_maybe_transform +from ...._utils import path_template from ...._compat import cached_property from ...._resource import SyncAPIResource, AsyncAPIResource from ...._response import ( @@ -18,7 +18,6 @@ ) from ...._wrappers import ResultWrapper from ...._base_client import make_request_options -from ....types.magic_network_monitoring.rules import advertisement_edit_params from ....types.magic_network_monitoring.rules.advertisement import Advertisement __all__ = ["AdvertisementsResource", "AsyncAdvertisementsResource"] @@ -49,7 +48,6 @@ def edit( rule_id: str, *, account_id: str, - body: object, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -80,7 +78,6 @@ def edit( path_template( "/accounts/{account_id}/mnm/rules/{rule_id}/advertisement", account_id=account_id, rule_id=rule_id ), - body=maybe_transform(body, advertisement_edit_params.AdvertisementEditParams), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, @@ -117,7 +114,6 @@ async def edit( rule_id: str, *, account_id: str, - body: object, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -148,7 +144,6 @@ async def edit( path_template( "/accounts/{account_id}/mnm/rules/{rule_id}/advertisement", account_id=account_id, rule_id=rule_id ), - body=await async_maybe_transform(body, advertisement_edit_params.AdvertisementEditParams), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, diff --git a/src/cloudflare/resources/magic_transit/sites/lans.py b/src/cloudflare/resources/magic_transit/sites/lans.py index 6e0395cefd1..dc0a1ec250c 100644 --- a/src/cloudflare/resources/magic_transit/sites/lans.py +++ b/src/cloudflare/resources/magic_transit/sites/lans.py @@ -64,6 +64,7 @@ def create( name: str | Omit = omit, nat: NatParam | Omit = omit, physport: int | Omit = omit, + remote_subnets: Iterable[lan_create_params.RemoteSubnet] | Omit = omit, routed_subnets: Iterable[RoutedSubnetParam] | Omit = omit, static_addressing: LANStaticAddressingParam | Omit = omit, vlan_tag: int | Omit = omit, @@ -121,6 +122,7 @@ def create( "name": name, "nat": nat, "physport": physport, + "remote_subnets": remote_subnets, "routed_subnets": routed_subnets, "static_addressing": static_addressing, "vlan_tag": vlan_tag, @@ -147,6 +149,7 @@ def update( name: str | Omit = omit, nat: NatParam | Omit = omit, physport: int | Omit = omit, + remote_subnets: Iterable[lan_update_params.RemoteSubnet] | Omit = omit, routed_subnets: Iterable[RoutedSubnetParam] | Omit = omit, static_addressing: LANStaticAddressingParam | Omit = omit, vlan_tag: int | Omit = omit, @@ -210,6 +213,7 @@ def update( "name": name, "nat": nat, "physport": physport, + "remote_subnets": remote_subnets, "routed_subnets": routed_subnets, "static_addressing": static_addressing, "vlan_tag": vlan_tag, @@ -334,6 +338,7 @@ def edit( name: str | Omit = omit, nat: NatParam | Omit = omit, physport: int | Omit = omit, + remote_subnets: Iterable[lan_edit_params.RemoteSubnet] | Omit = omit, routed_subnets: Iterable[RoutedSubnetParam] | Omit = omit, static_addressing: LANStaticAddressingParam | Omit = omit, vlan_tag: int | Omit = omit, @@ -397,6 +402,7 @@ def edit( "name": name, "nat": nat, "physport": physport, + "remote_subnets": remote_subnets, "routed_subnets": routed_subnets, "static_addressing": static_addressing, "vlan_tag": vlan_tag, @@ -500,6 +506,7 @@ def create( name: str | Omit = omit, nat: NatParam | Omit = omit, physport: int | Omit = omit, + remote_subnets: Iterable[lan_create_params.RemoteSubnet] | Omit = omit, routed_subnets: Iterable[RoutedSubnetParam] | Omit = omit, static_addressing: LANStaticAddressingParam | Omit = omit, vlan_tag: int | Omit = omit, @@ -557,6 +564,7 @@ def create( "name": name, "nat": nat, "physport": physport, + "remote_subnets": remote_subnets, "routed_subnets": routed_subnets, "static_addressing": static_addressing, "vlan_tag": vlan_tag, @@ -583,6 +591,7 @@ async def update( name: str | Omit = omit, nat: NatParam | Omit = omit, physport: int | Omit = omit, + remote_subnets: Iterable[lan_update_params.RemoteSubnet] | Omit = omit, routed_subnets: Iterable[RoutedSubnetParam] | Omit = omit, static_addressing: LANStaticAddressingParam | Omit = omit, vlan_tag: int | Omit = omit, @@ -646,6 +655,7 @@ async def update( "name": name, "nat": nat, "physport": physport, + "remote_subnets": remote_subnets, "routed_subnets": routed_subnets, "static_addressing": static_addressing, "vlan_tag": vlan_tag, @@ -770,6 +780,7 @@ async def edit( name: str | Omit = omit, nat: NatParam | Omit = omit, physport: int | Omit = omit, + remote_subnets: Iterable[lan_edit_params.RemoteSubnet] | Omit = omit, routed_subnets: Iterable[RoutedSubnetParam] | Omit = omit, static_addressing: LANStaticAddressingParam | Omit = omit, vlan_tag: int | Omit = omit, @@ -833,6 +844,7 @@ async def edit( "name": name, "nat": nat, "physport": physport, + "remote_subnets": remote_subnets, "routed_subnets": routed_subnets, "static_addressing": static_addressing, "vlan_tag": vlan_tag, diff --git a/src/cloudflare/resources/magic_transit/sites/wans.py b/src/cloudflare/resources/magic_transit/sites/wans.py index 3323c42af35..47df437cb05 100644 --- a/src/cloudflare/resources/magic_transit/sites/wans.py +++ b/src/cloudflare/resources/magic_transit/sites/wans.py @@ -22,7 +22,6 @@ from ...._base_client import AsyncPaginator, make_request_options from ....types.magic_transit.sites import wan_edit_params, wan_create_params, wan_update_params from ....types.magic_transit.sites.wan import WAN -from ....types.magic_transit.sites.wan_static_addressing_param import WANStaticAddressingParam __all__ = ["WANsResource", "AsyncWANsResource"] @@ -57,7 +56,9 @@ def create( load_balance_inner_flows: bool | Omit = omit, name: str | Omit = omit, priority: int | Omit = omit, - static_addressing: WANStaticAddressingParam | Omit = omit, + provisioned_download_kbps: int | Omit = omit, + provisioned_upload_kbps: int | Omit = omit, + static_addressing: wan_create_params.StaticAddressing | Omit = omit, vlan_tag: int | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. @@ -77,8 +78,12 @@ def create( health_check_rate: Magic WAN health check rate for tunnels created on this link. The default value is `mid`. - static_addressing: (optional) if omitted, use DHCP. Submit secondary_address when site is in high - availability mode. + provisioned_download_kbps: Provisioned download rate of the WAN circuit in kilobits per second. + + provisioned_upload_kbps: Provisioned upload rate of the WAN circuit in kilobits per second. + + static_addressing: Static addressing configuration for a WAN. Omit to use DHCP. Submit + secondary_address when the site is in high availability mode. vlan_tag: VLAN ID. Use zero for untagged. @@ -104,6 +109,8 @@ def create( "load_balance_inner_flows": load_balance_inner_flows, "name": name, "priority": priority, + "provisioned_download_kbps": provisioned_download_kbps, + "provisioned_upload_kbps": provisioned_upload_kbps, "static_addressing": static_addressing, "vlan_tag": vlan_tag, }, @@ -127,7 +134,9 @@ def update( name: str | Omit = omit, physport: int | Omit = omit, priority: int | Omit = omit, - static_addressing: WANStaticAddressingParam | Omit = omit, + provisioned_download_kbps: Optional[int] | Omit = omit, + provisioned_upload_kbps: Optional[int] | Omit = omit, + static_addressing: wan_update_params.StaticAddressing | Omit = omit, vlan_tag: int | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. @@ -148,8 +157,14 @@ def update( health_check_rate: Magic WAN health check rate for tunnels created on this link. - static_addressing: (optional) if omitted, use DHCP. Submit secondary_address when site is in high - availability mode. + provisioned_download_kbps: Provisioned download rate of the WAN circuit in kilobits per second. Set to null + to remove it. + + provisioned_upload_kbps: Provisioned upload rate of the WAN circuit in kilobits per second. Set to null + to remove it. + + static_addressing: Static addressing configuration. PATCH updates only the fields provided, and PUT + replaces the configuration. vlan_tag: VLAN ID. Use zero for untagged. @@ -181,6 +196,8 @@ def update( "name": name, "physport": physport, "priority": priority, + "provisioned_download_kbps": provisioned_download_kbps, + "provisioned_upload_kbps": provisioned_upload_kbps, "static_addressing": static_addressing, "vlan_tag": vlan_tag, }, @@ -302,7 +319,9 @@ def edit( name: str | Omit = omit, physport: int | Omit = omit, priority: int | Omit = omit, - static_addressing: WANStaticAddressingParam | Omit = omit, + provisioned_download_kbps: Optional[int] | Omit = omit, + provisioned_upload_kbps: Optional[int] | Omit = omit, + static_addressing: wan_edit_params.StaticAddressing | Omit = omit, vlan_tag: int | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. @@ -323,8 +342,14 @@ def edit( health_check_rate: Magic WAN health check rate for tunnels created on this link. - static_addressing: (optional) if omitted, use DHCP. Submit secondary_address when site is in high - availability mode. + provisioned_download_kbps: Provisioned download rate of the WAN circuit in kilobits per second. Set to null + to remove it. + + provisioned_upload_kbps: Provisioned upload rate of the WAN circuit in kilobits per second. Set to null + to remove it. + + static_addressing: Static addressing configuration. PATCH updates only the fields provided, and PUT + replaces the configuration. vlan_tag: VLAN ID. Use zero for untagged. @@ -356,6 +381,8 @@ def edit( "name": name, "physport": physport, "priority": priority, + "provisioned_download_kbps": provisioned_download_kbps, + "provisioned_upload_kbps": provisioned_upload_kbps, "static_addressing": static_addressing, "vlan_tag": vlan_tag, }, @@ -456,7 +483,9 @@ def create( load_balance_inner_flows: bool | Omit = omit, name: str | Omit = omit, priority: int | Omit = omit, - static_addressing: WANStaticAddressingParam | Omit = omit, + provisioned_download_kbps: int | Omit = omit, + provisioned_upload_kbps: int | Omit = omit, + static_addressing: wan_create_params.StaticAddressing | Omit = omit, vlan_tag: int | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. @@ -476,8 +505,12 @@ def create( health_check_rate: Magic WAN health check rate for tunnels created on this link. The default value is `mid`. - static_addressing: (optional) if omitted, use DHCP. Submit secondary_address when site is in high - availability mode. + provisioned_download_kbps: Provisioned download rate of the WAN circuit in kilobits per second. + + provisioned_upload_kbps: Provisioned upload rate of the WAN circuit in kilobits per second. + + static_addressing: Static addressing configuration for a WAN. Omit to use DHCP. Submit + secondary_address when the site is in high availability mode. vlan_tag: VLAN ID. Use zero for untagged. @@ -503,6 +536,8 @@ def create( "load_balance_inner_flows": load_balance_inner_flows, "name": name, "priority": priority, + "provisioned_download_kbps": provisioned_download_kbps, + "provisioned_upload_kbps": provisioned_upload_kbps, "static_addressing": static_addressing, "vlan_tag": vlan_tag, }, @@ -526,7 +561,9 @@ async def update( name: str | Omit = omit, physport: int | Omit = omit, priority: int | Omit = omit, - static_addressing: WANStaticAddressingParam | Omit = omit, + provisioned_download_kbps: Optional[int] | Omit = omit, + provisioned_upload_kbps: Optional[int] | Omit = omit, + static_addressing: wan_update_params.StaticAddressing | Omit = omit, vlan_tag: int | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. @@ -547,8 +584,14 @@ async def update( health_check_rate: Magic WAN health check rate for tunnels created on this link. - static_addressing: (optional) if omitted, use DHCP. Submit secondary_address when site is in high - availability mode. + provisioned_download_kbps: Provisioned download rate of the WAN circuit in kilobits per second. Set to null + to remove it. + + provisioned_upload_kbps: Provisioned upload rate of the WAN circuit in kilobits per second. Set to null + to remove it. + + static_addressing: Static addressing configuration. PATCH updates only the fields provided, and PUT + replaces the configuration. vlan_tag: VLAN ID. Use zero for untagged. @@ -580,6 +623,8 @@ async def update( "name": name, "physport": physport, "priority": priority, + "provisioned_download_kbps": provisioned_download_kbps, + "provisioned_upload_kbps": provisioned_upload_kbps, "static_addressing": static_addressing, "vlan_tag": vlan_tag, }, @@ -701,7 +746,9 @@ async def edit( name: str | Omit = omit, physport: int | Omit = omit, priority: int | Omit = omit, - static_addressing: WANStaticAddressingParam | Omit = omit, + provisioned_download_kbps: Optional[int] | Omit = omit, + provisioned_upload_kbps: Optional[int] | Omit = omit, + static_addressing: wan_edit_params.StaticAddressing | Omit = omit, vlan_tag: int | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. @@ -722,8 +769,14 @@ async def edit( health_check_rate: Magic WAN health check rate for tunnels created on this link. - static_addressing: (optional) if omitted, use DHCP. Submit secondary_address when site is in high - availability mode. + provisioned_download_kbps: Provisioned download rate of the WAN circuit in kilobits per second. Set to null + to remove it. + + provisioned_upload_kbps: Provisioned upload rate of the WAN circuit in kilobits per second. Set to null + to remove it. + + static_addressing: Static addressing configuration. PATCH updates only the fields provided, and PUT + replaces the configuration. vlan_tag: VLAN ID. Use zero for untagged. @@ -755,6 +808,8 @@ async def edit( "name": name, "physport": physport, "priority": priority, + "provisioned_download_kbps": provisioned_download_kbps, + "provisioned_upload_kbps": provisioned_upload_kbps, "static_addressing": static_addressing, "vlan_tag": vlan_tag, }, diff --git a/src/cloudflare/resources/managed_defense/vulnerability_discovery/repositories.py b/src/cloudflare/resources/managed_defense/vulnerability_discovery/repositories.py index 71a6e735cfd..ff2b0b6b82f 100644 --- a/src/cloudflare/resources/managed_defense/vulnerability_discovery/repositories.py +++ b/src/cloudflare/resources/managed_defense/vulnerability_discovery/repositories.py @@ -67,7 +67,8 @@ def create( ) -> RepositoryCreateResponse: """ Creates an upload repository or reserves an asynchronous deployed Worker import - by name. Worker imports require Idempotency-Key. + by name. Worker imports require Idempotency-Key. Push upload source to `main` or + specify the `branch` to scan in the scan request. Args: extra_headers: Send extra headers @@ -245,7 +246,8 @@ async def create( ) -> RepositoryCreateResponse: """ Creates an upload repository or reserves an asynchronous deployed Worker import - by name. Worker imports require Idempotency-Key. + by name. Worker imports require Idempotency-Key. Push upload source to `main` or + specify the `branch` to scan in the scan request. Args: extra_headers: Send extra headers diff --git a/src/cloudflare/resources/managed_defense/vulnerability_discovery/scans.py b/src/cloudflare/resources/managed_defense/vulnerability_discovery/scans.py index c8c40928d36..f62d9ec040a 100644 --- a/src/cloudflare/resources/managed_defense/vulnerability_discovery/scans.py +++ b/src/cloudflare/resources/managed_defense/vulnerability_discovery/scans.py @@ -2,12 +2,12 @@ from __future__ import annotations -from typing import Dict, List, Type, Union, cast +from typing import List, Type, Union, Iterable, cast from typing_extensions import Literal import httpx -from ...._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given +from ...._types import Body, Omit, Query, Headers, NotGiven, omit, not_given from ...._utils import path_template, maybe_transform, strip_not_given, async_maybe_transform from ...._compat import cached_property from ...._resource import SyncAPIResource, AsyncAPIResource @@ -53,8 +53,7 @@ def create( self, *, account_id: str, - repos: SequenceNotStr[str], - repo_hosts: Dict[str, SequenceNotStr[str]] | Omit = omit, + repos: Iterable[scan_create_params.Repo], telemetry_window: scan_create_params.TelemetryWindow | Omit = omit, idempotency_key: str | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -68,12 +67,11 @@ def create( This endpoint does not immediately start execution. Worker-imported repositories must be ready; - explicit `repo_hosts` must be authorized before the request is persisted. + explicit repository host scopes must be authorized and explicit branch + selections must exist before the request is persisted. Args: - repo_hosts: Explicit hostname scopes. Every hostname must be authorized for its repository - before review admission; rejected scopes return 422 and do not persist a scan - request. + repos: Repository names must be unique within a request. telemetry_window: UTC ISO-8601 interval. Start is inclusive, end is exclusive, and the interval must be positive and at most seven days. @@ -96,7 +94,6 @@ def create( body=maybe_transform( { "repos": repos, - "repo_hosts": repo_hosts, "telemetry_window": telemetry_window, }, scan_create_params.ScanCreateParams, @@ -284,8 +281,7 @@ async def create( self, *, account_id: str, - repos: SequenceNotStr[str], - repo_hosts: Dict[str, SequenceNotStr[str]] | Omit = omit, + repos: Iterable[scan_create_params.Repo], telemetry_window: scan_create_params.TelemetryWindow | Omit = omit, idempotency_key: str | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -299,12 +295,11 @@ async def create( This endpoint does not immediately start execution. Worker-imported repositories must be ready; - explicit `repo_hosts` must be authorized before the request is persisted. + explicit repository host scopes must be authorized and explicit branch + selections must exist before the request is persisted. Args: - repo_hosts: Explicit hostname scopes. Every hostname must be authorized for its repository - before review admission; rejected scopes return 422 and do not persist a scan - request. + repos: Repository names must be unique within a request. telemetry_window: UTC ISO-8601 interval. Start is inclusive, end is exclusive, and the interval must be positive and at most seven days. @@ -327,7 +322,6 @@ async def create( body=await async_maybe_transform( { "repos": repos, - "repo_hosts": repo_hosts, "telemetry_window": telemetry_window, }, scan_create_params.ScanCreateParams, diff --git a/src/cloudflare/resources/managed_transforms/managed_transforms.py b/src/cloudflare/resources/managed_transforms/managed_transforms.py index 259a392cd9a..37ed1fe3e9b 100644 --- a/src/cloudflare/resources/managed_transforms/managed_transforms.py +++ b/src/cloudflare/resources/managed_transforms/managed_transforms.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing import Type, Iterable, cast +from typing import Any, Iterable, cast import httpx @@ -72,16 +72,21 @@ def list( """ if not zone_id: raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") - return self._get( - path_template("/zones/{zone_id}/managed_headers", zone_id=zone_id), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - post_parser=ResultWrapper[ManagedTransformListResponse]._unwrapper, + return cast( + ManagedTransformListResponse, + self._get( + path_template("/zones/{zone_id}/managed_headers", zone_id=zone_id), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[ManagedTransformListResponse]._unwrapper, + ), + cast_to=cast( + Any, ResultWrapper[ManagedTransformListResponse] + ), # Union types cannot be passed in as arguments in the type system ), - cast_to=cast(Type[ManagedTransformListResponse], ResultWrapper[ManagedTransformListResponse]), ) def delete( @@ -153,23 +158,28 @@ def edit( """ if not zone_id: raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") - return self._patch( - path_template("/zones/{zone_id}/managed_headers", zone_id=zone_id), - body=maybe_transform( - { - "managed_request_headers": managed_request_headers, - "managed_response_headers": managed_response_headers, - }, - managed_transform_edit_params.ManagedTransformEditParams, - ), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - post_parser=ResultWrapper[ManagedTransformEditResponse]._unwrapper, + return cast( + ManagedTransformEditResponse, + self._patch( + path_template("/zones/{zone_id}/managed_headers", zone_id=zone_id), + body=maybe_transform( + { + "managed_request_headers": managed_request_headers, + "managed_response_headers": managed_response_headers, + }, + managed_transform_edit_params.ManagedTransformEditParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[ManagedTransformEditResponse]._unwrapper, + ), + cast_to=cast( + Any, ResultWrapper[ManagedTransformEditResponse] + ), # Union types cannot be passed in as arguments in the type system ), - cast_to=cast(Type[ManagedTransformEditResponse], ResultWrapper[ManagedTransformEditResponse]), ) @@ -220,16 +230,21 @@ async def list( """ if not zone_id: raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") - return await self._get( - path_template("/zones/{zone_id}/managed_headers", zone_id=zone_id), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - post_parser=ResultWrapper[ManagedTransformListResponse]._unwrapper, + return cast( + ManagedTransformListResponse, + await self._get( + path_template("/zones/{zone_id}/managed_headers", zone_id=zone_id), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[ManagedTransformListResponse]._unwrapper, + ), + cast_to=cast( + Any, ResultWrapper[ManagedTransformListResponse] + ), # Union types cannot be passed in as arguments in the type system ), - cast_to=cast(Type[ManagedTransformListResponse], ResultWrapper[ManagedTransformListResponse]), ) async def delete( @@ -301,23 +316,28 @@ async def edit( """ if not zone_id: raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") - return await self._patch( - path_template("/zones/{zone_id}/managed_headers", zone_id=zone_id), - body=await async_maybe_transform( - { - "managed_request_headers": managed_request_headers, - "managed_response_headers": managed_response_headers, - }, - managed_transform_edit_params.ManagedTransformEditParams, - ), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - post_parser=ResultWrapper[ManagedTransformEditResponse]._unwrapper, + return cast( + ManagedTransformEditResponse, + await self._patch( + path_template("/zones/{zone_id}/managed_headers", zone_id=zone_id), + body=await async_maybe_transform( + { + "managed_request_headers": managed_request_headers, + "managed_response_headers": managed_response_headers, + }, + managed_transform_edit_params.ManagedTransformEditParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[ManagedTransformEditResponse]._unwrapper, + ), + cast_to=cast( + Any, ResultWrapper[ManagedTransformEditResponse] + ), # Union types cannot be passed in as arguments in the type system ), - cast_to=cast(Type[ManagedTransformEditResponse], ResultWrapper[ManagedTransformEditResponse]), ) diff --git a/src/cloudflare/resources/monetization/__init__.py b/src/cloudflare/resources/monetization/__init__.py new file mode 100644 index 00000000000..7c04ab78d30 --- /dev/null +++ b/src/cloudflare/resources/monetization/__init__.py @@ -0,0 +1,33 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from .rules import ( + RulesResource, + AsyncRulesResource, + RulesResourceWithRawResponse, + AsyncRulesResourceWithRawResponse, + RulesResourceWithStreamingResponse, + AsyncRulesResourceWithStreamingResponse, +) +from .monetization import ( + MonetizationResource, + AsyncMonetizationResource, + MonetizationResourceWithRawResponse, + AsyncMonetizationResourceWithRawResponse, + MonetizationResourceWithStreamingResponse, + AsyncMonetizationResourceWithStreamingResponse, +) + +__all__ = [ + "RulesResource", + "AsyncRulesResource", + "RulesResourceWithRawResponse", + "AsyncRulesResourceWithRawResponse", + "RulesResourceWithStreamingResponse", + "AsyncRulesResourceWithStreamingResponse", + "MonetizationResource", + "AsyncMonetizationResource", + "MonetizationResourceWithRawResponse", + "AsyncMonetizationResourceWithRawResponse", + "MonetizationResourceWithStreamingResponse", + "AsyncMonetizationResourceWithStreamingResponse", +] diff --git a/src/cloudflare/resources/monetization/api.md b/src/cloudflare/resources/monetization/api.md new file mode 100644 index 00000000000..b1a29e5e994 --- /dev/null +++ b/src/cloudflare/resources/monetization/api.md @@ -0,0 +1,38 @@ +# Monetization + +Types: + +```python +from cloudflare.types.monetization import ( + MonetizationAccountEligibilityCheckInput, + MonetizationAccountEligibilityCheckResponse, + MonetizationEligibilityResponse, + MonetizationEligibilityResult, + MonetizationZoneEligibilityCheckResponse, +) +``` + +## Rules + +Types: + +```python +from cloudflare.types.monetization import ( + MonetizationRule, + MonetizationRuleCollection, + MonetizationRuleInput, + MonetizationRuleInputFixedPrice, + MonetizationRuleInputOriginControlled, + MonetizationRulePatch, + MonetizationRulesetInput, +) +``` + +Methods: + +- client.monetization.rules.update(\*, zone_id, \*\*params) -> MonetizationRuleCollection +- client.monetization.rules.delete(\*, zone_id) -> MonetizationRuleCollection +- client.monetization.rules.delete_rule(rule_id, \*, zone_id) -> MonetizationRuleCollection +- client.monetization.rules.edit_rule(rule_id, \*, zone_id, \*\*params) -> MonetizationRuleCollection +- client.monetization.rules.get(\*, zone_id) -> MonetizationRuleCollection +- client.monetization.rules.get_rule(rule_id, \*, zone_id) -> MonetizationRule diff --git a/src/cloudflare/resources/monetization/monetization.py b/src/cloudflare/resources/monetization/monetization.py new file mode 100644 index 00000000000..3ec07220613 --- /dev/null +++ b/src/cloudflare/resources/monetization/monetization.py @@ -0,0 +1,102 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from .rules import ( + RulesResource, + AsyncRulesResource, + RulesResourceWithRawResponse, + AsyncRulesResourceWithRawResponse, + RulesResourceWithStreamingResponse, + AsyncRulesResourceWithStreamingResponse, +) +from ..._compat import cached_property +from ..._resource import SyncAPIResource, AsyncAPIResource + +__all__ = ["MonetizationResource", "AsyncMonetizationResource"] + + +class MonetizationResource(SyncAPIResource): + @cached_property + def rules(self) -> RulesResource: + return RulesResource(self._client) + + @cached_property + def with_raw_response(self) -> MonetizationResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers + """ + return MonetizationResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> MonetizationResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response + """ + return MonetizationResourceWithStreamingResponse(self) + + +class AsyncMonetizationResource(AsyncAPIResource): + @cached_property + def rules(self) -> AsyncRulesResource: + return AsyncRulesResource(self._client) + + @cached_property + def with_raw_response(self) -> AsyncMonetizationResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers + """ + return AsyncMonetizationResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncMonetizationResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response + """ + return AsyncMonetizationResourceWithStreamingResponse(self) + + +class MonetizationResourceWithRawResponse: + def __init__(self, monetization: MonetizationResource) -> None: + self._monetization = monetization + + @cached_property + def rules(self) -> RulesResourceWithRawResponse: + return RulesResourceWithRawResponse(self._monetization.rules) + + +class AsyncMonetizationResourceWithRawResponse: + def __init__(self, monetization: AsyncMonetizationResource) -> None: + self._monetization = monetization + + @cached_property + def rules(self) -> AsyncRulesResourceWithRawResponse: + return AsyncRulesResourceWithRawResponse(self._monetization.rules) + + +class MonetizationResourceWithStreamingResponse: + def __init__(self, monetization: MonetizationResource) -> None: + self._monetization = monetization + + @cached_property + def rules(self) -> RulesResourceWithStreamingResponse: + return RulesResourceWithStreamingResponse(self._monetization.rules) + + +class AsyncMonetizationResourceWithStreamingResponse: + def __init__(self, monetization: AsyncMonetizationResource) -> None: + self._monetization = monetization + + @cached_property + def rules(self) -> AsyncRulesResourceWithStreamingResponse: + return AsyncRulesResourceWithStreamingResponse(self._monetization.rules) diff --git a/src/cloudflare/resources/monetization/rules.py b/src/cloudflare/resources/monetization/rules.py new file mode 100644 index 00000000000..7820c78533d --- /dev/null +++ b/src/cloudflare/resources/monetization/rules.py @@ -0,0 +1,779 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Any, Type, Iterable, cast +from typing_extensions import Literal + +import httpx + +from ..._types import Body, Omit, Query, Headers, NotGiven, omit, not_given +from ..._utils import path_template, maybe_transform, async_maybe_transform +from ..._compat import cached_property +from ..._resource import SyncAPIResource, AsyncAPIResource +from ..._response import ( + to_raw_response_wrapper, + to_streamed_response_wrapper, + async_to_raw_response_wrapper, + async_to_streamed_response_wrapper, +) +from ..._wrappers import ResultWrapper +from ..._base_client import make_request_options +from ...types.monetization import rule_update_params, rule_edit_rule_params +from ...types.monetization.monetization_rule import MonetizationRule +from ...types.monetization.monetization_rule_collection import MonetizationRuleCollection +from ...types.monetization.monetization_rule_input_param import MonetizationRuleInputParam + +__all__ = ["RulesResource", "AsyncRulesResource"] + + +class RulesResource(SyncAPIResource): + @cached_property + def with_raw_response(self) -> RulesResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers + """ + return RulesResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> RulesResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response + """ + return RulesResourceWithStreamingResponse(self) + + def update( + self, + *, + zone_id: str, + rules: Iterable[MonetizationRuleInputParam], + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> MonetizationRuleCollection: + """ + Replaces the zone's Payment Required ruleset with the submitted desired state. + Submit an empty rules array to clear all payment rules. + + Args: + zone_id: The unique ID of the zone. + + rules: Full desired Payment Required ruleset. An empty array clears all payment rules. + The ruleset may contain at most 40 unique wallet addresses; address comparison + is case-insensitive. Every address must pass wallet screening before deployment. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + return self._put( + path_template("/zones/{zone_id}/monetization/rules", zone_id=zone_id), + body=maybe_transform({"rules": rules}, rule_update_params.RuleUpdateParams), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[MonetizationRuleCollection]._unwrapper, + ), + cast_to=cast(Type[MonetizationRuleCollection], ResultWrapper[MonetizationRuleCollection]), + ) + + def delete( + self, + *, + zone_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> MonetizationRuleCollection: + """Removes every Payment Required rule from the zone. + + Any rules the service does + not own are preserved. Deleting a zone with no payment rules is a no-op. Returns + the resulting (empty) rule collection. + + Args: + zone_id: The unique ID of the zone. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + return self._delete( + path_template("/zones/{zone_id}/monetization/rules", zone_id=zone_id), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[MonetizationRuleCollection]._unwrapper, + ), + cast_to=cast(Type[MonetizationRuleCollection], ResultWrapper[MonetizationRuleCollection]), + ) + + def delete_rule( + self, + rule_id: str, + *, + zone_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> MonetizationRuleCollection: + """Removes a single Payment Required rule identified by its ID. + + Every other rule is + preserved. Returns the resulting rule collection. + + Args: + zone_id: The unique ID of the zone. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + if not rule_id: + raise ValueError(f"Expected a non-empty value for `rule_id` but received {rule_id!r}") + return self._delete( + path_template("/zones/{zone_id}/monetization/rules/{rule_id}", zone_id=zone_id, rule_id=rule_id), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[MonetizationRuleCollection]._unwrapper, + ), + cast_to=cast(Type[MonetizationRuleCollection], ResultWrapper[MonetizationRuleCollection]), + ) + + def edit_rule( + self, + rule_id: str, + *, + zone_id: str, + address: str | Omit = omit, + description: str | Omit = omit, + enabled: bool | Omit = omit, + expression: str | Omit = omit, + price: str | Omit = omit, + scheme: Literal["exact", "upto", "origin_controlled"] | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> MonetizationRuleCollection: + """Applies a partial update to a single Payment Required rule. + + Only the fields + present in the request body are changed; omitted fields keep their current + values. Returns the full resulting rule collection. + + Args: + zone_id: The unique ID of the zone. + + address: 0x-prefixed 20-byte hexadecimal Ethereum address. Mixed-case addresses must + carry a valid EIP-55 checksum; all-lowercase or all-uppercase addresses are also + accepted. The effective address must pass wallet screening whenever the rule is + patched. + + expression: Wirefilter expression identifying the requests that require payment. Forwarded + verbatim to the Rulesets API, which validates its syntax. + + price: Price in the smallest indivisible unit of the configured payment token, encoded + as a decimal string. Must be a canonical decimal integer in [1000, 100000000]: + no leading zeros, and a bare JSON number is rejected. The price is required for + the fixed-price schemes ("exact" and "upto") and must be at least 1000, the + smallest amount the payment facilitator can settle ($0.001 for a 6-decimal token + such as USDC), and at most 100000000 ($100 for a 6-decimal token). When the + scheme is "origin_controlled" the origin server sets pricing dynamically and the + rule carries no price: the field must be omitted — any provided value, including + "0", is rejected because it would not be enforced. Responses always encode this + as a string and omit it for "origin_controlled" rules; the pattern matches + exactly the set of values the server accepts. + + scheme: X402 payment scheme. "exact" requires the specified payment amount; "upto" + permits a payment up to the specified amount; "origin_controlled" lets the + origin server set pricing dynamically, in which case the rule carries no price + and the price field must be omitted. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + if not rule_id: + raise ValueError(f"Expected a non-empty value for `rule_id` but received {rule_id!r}") + return self._patch( + path_template("/zones/{zone_id}/monetization/rules/{rule_id}", zone_id=zone_id, rule_id=rule_id), + body=maybe_transform( + { + "address": address, + "description": description, + "enabled": enabled, + "expression": expression, + "price": price, + "scheme": scheme, + }, + rule_edit_rule_params.RuleEditRuleParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[MonetizationRuleCollection]._unwrapper, + ), + cast_to=cast(Type[MonetizationRuleCollection], ResultWrapper[MonetizationRuleCollection]), + ) + + def get( + self, + *, + zone_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> MonetizationRuleCollection: + """Returns the currently deployed Payment Required rules for a zone. + + A zone with no + Payment Required ruleset returns 404. + + Args: + zone_id: The unique ID of the zone. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + return self._get( + path_template("/zones/{zone_id}/monetization/rules", zone_id=zone_id), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[MonetizationRuleCollection]._unwrapper, + ), + cast_to=cast(Type[MonetizationRuleCollection], ResultWrapper[MonetizationRuleCollection]), + ) + + def get_rule( + self, + rule_id: str, + *, + zone_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> MonetizationRule: + """ + Returns a single Payment Required rule identified by its ID. + + Args: + zone_id: The unique ID of the zone. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + if not rule_id: + raise ValueError(f"Expected a non-empty value for `rule_id` but received {rule_id!r}") + return cast( + MonetizationRule, + self._get( + path_template("/zones/{zone_id}/monetization/rules/{rule_id}", zone_id=zone_id, rule_id=rule_id), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[MonetizationRule]._unwrapper, + ), + cast_to=cast( + Any, ResultWrapper[MonetizationRule] + ), # Union types cannot be passed in as arguments in the type system + ), + ) + + +class AsyncRulesResource(AsyncAPIResource): + @cached_property + def with_raw_response(self) -> AsyncRulesResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers + """ + return AsyncRulesResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncRulesResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response + """ + return AsyncRulesResourceWithStreamingResponse(self) + + async def update( + self, + *, + zone_id: str, + rules: Iterable[MonetizationRuleInputParam], + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> MonetizationRuleCollection: + """ + Replaces the zone's Payment Required ruleset with the submitted desired state. + Submit an empty rules array to clear all payment rules. + + Args: + zone_id: The unique ID of the zone. + + rules: Full desired Payment Required ruleset. An empty array clears all payment rules. + The ruleset may contain at most 40 unique wallet addresses; address comparison + is case-insensitive. Every address must pass wallet screening before deployment. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + return await self._put( + path_template("/zones/{zone_id}/monetization/rules", zone_id=zone_id), + body=await async_maybe_transform({"rules": rules}, rule_update_params.RuleUpdateParams), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[MonetizationRuleCollection]._unwrapper, + ), + cast_to=cast(Type[MonetizationRuleCollection], ResultWrapper[MonetizationRuleCollection]), + ) + + async def delete( + self, + *, + zone_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> MonetizationRuleCollection: + """Removes every Payment Required rule from the zone. + + Any rules the service does + not own are preserved. Deleting a zone with no payment rules is a no-op. Returns + the resulting (empty) rule collection. + + Args: + zone_id: The unique ID of the zone. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + return await self._delete( + path_template("/zones/{zone_id}/monetization/rules", zone_id=zone_id), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[MonetizationRuleCollection]._unwrapper, + ), + cast_to=cast(Type[MonetizationRuleCollection], ResultWrapper[MonetizationRuleCollection]), + ) + + async def delete_rule( + self, + rule_id: str, + *, + zone_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> MonetizationRuleCollection: + """Removes a single Payment Required rule identified by its ID. + + Every other rule is + preserved. Returns the resulting rule collection. + + Args: + zone_id: The unique ID of the zone. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + if not rule_id: + raise ValueError(f"Expected a non-empty value for `rule_id` but received {rule_id!r}") + return await self._delete( + path_template("/zones/{zone_id}/monetization/rules/{rule_id}", zone_id=zone_id, rule_id=rule_id), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[MonetizationRuleCollection]._unwrapper, + ), + cast_to=cast(Type[MonetizationRuleCollection], ResultWrapper[MonetizationRuleCollection]), + ) + + async def edit_rule( + self, + rule_id: str, + *, + zone_id: str, + address: str | Omit = omit, + description: str | Omit = omit, + enabled: bool | Omit = omit, + expression: str | Omit = omit, + price: str | Omit = omit, + scheme: Literal["exact", "upto", "origin_controlled"] | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> MonetizationRuleCollection: + """Applies a partial update to a single Payment Required rule. + + Only the fields + present in the request body are changed; omitted fields keep their current + values. Returns the full resulting rule collection. + + Args: + zone_id: The unique ID of the zone. + + address: 0x-prefixed 20-byte hexadecimal Ethereum address. Mixed-case addresses must + carry a valid EIP-55 checksum; all-lowercase or all-uppercase addresses are also + accepted. The effective address must pass wallet screening whenever the rule is + patched. + + expression: Wirefilter expression identifying the requests that require payment. Forwarded + verbatim to the Rulesets API, which validates its syntax. + + price: Price in the smallest indivisible unit of the configured payment token, encoded + as a decimal string. Must be a canonical decimal integer in [1000, 100000000]: + no leading zeros, and a bare JSON number is rejected. The price is required for + the fixed-price schemes ("exact" and "upto") and must be at least 1000, the + smallest amount the payment facilitator can settle ($0.001 for a 6-decimal token + such as USDC), and at most 100000000 ($100 for a 6-decimal token). When the + scheme is "origin_controlled" the origin server sets pricing dynamically and the + rule carries no price: the field must be omitted — any provided value, including + "0", is rejected because it would not be enforced. Responses always encode this + as a string and omit it for "origin_controlled" rules; the pattern matches + exactly the set of values the server accepts. + + scheme: X402 payment scheme. "exact" requires the specified payment amount; "upto" + permits a payment up to the specified amount; "origin_controlled" lets the + origin server set pricing dynamically, in which case the rule carries no price + and the price field must be omitted. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + if not rule_id: + raise ValueError(f"Expected a non-empty value for `rule_id` but received {rule_id!r}") + return await self._patch( + path_template("/zones/{zone_id}/monetization/rules/{rule_id}", zone_id=zone_id, rule_id=rule_id), + body=await async_maybe_transform( + { + "address": address, + "description": description, + "enabled": enabled, + "expression": expression, + "price": price, + "scheme": scheme, + }, + rule_edit_rule_params.RuleEditRuleParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[MonetizationRuleCollection]._unwrapper, + ), + cast_to=cast(Type[MonetizationRuleCollection], ResultWrapper[MonetizationRuleCollection]), + ) + + async def get( + self, + *, + zone_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> MonetizationRuleCollection: + """Returns the currently deployed Payment Required rules for a zone. + + A zone with no + Payment Required ruleset returns 404. + + Args: + zone_id: The unique ID of the zone. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + return await self._get( + path_template("/zones/{zone_id}/monetization/rules", zone_id=zone_id), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[MonetizationRuleCollection]._unwrapper, + ), + cast_to=cast(Type[MonetizationRuleCollection], ResultWrapper[MonetizationRuleCollection]), + ) + + async def get_rule( + self, + rule_id: str, + *, + zone_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> MonetizationRule: + """ + Returns a single Payment Required rule identified by its ID. + + Args: + zone_id: The unique ID of the zone. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + if not rule_id: + raise ValueError(f"Expected a non-empty value for `rule_id` but received {rule_id!r}") + return cast( + MonetizationRule, + await self._get( + path_template("/zones/{zone_id}/monetization/rules/{rule_id}", zone_id=zone_id, rule_id=rule_id), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[MonetizationRule]._unwrapper, + ), + cast_to=cast( + Any, ResultWrapper[MonetizationRule] + ), # Union types cannot be passed in as arguments in the type system + ), + ) + + +class RulesResourceWithRawResponse: + def __init__(self, rules: RulesResource) -> None: + self._rules = rules + + self.update = to_raw_response_wrapper( + rules.update, + ) + self.delete = to_raw_response_wrapper( + rules.delete, + ) + self.delete_rule = to_raw_response_wrapper( + rules.delete_rule, + ) + self.edit_rule = to_raw_response_wrapper( + rules.edit_rule, + ) + self.get = to_raw_response_wrapper( + rules.get, + ) + self.get_rule = to_raw_response_wrapper( + rules.get_rule, + ) + + +class AsyncRulesResourceWithRawResponse: + def __init__(self, rules: AsyncRulesResource) -> None: + self._rules = rules + + self.update = async_to_raw_response_wrapper( + rules.update, + ) + self.delete = async_to_raw_response_wrapper( + rules.delete, + ) + self.delete_rule = async_to_raw_response_wrapper( + rules.delete_rule, + ) + self.edit_rule = async_to_raw_response_wrapper( + rules.edit_rule, + ) + self.get = async_to_raw_response_wrapper( + rules.get, + ) + self.get_rule = async_to_raw_response_wrapper( + rules.get_rule, + ) + + +class RulesResourceWithStreamingResponse: + def __init__(self, rules: RulesResource) -> None: + self._rules = rules + + self.update = to_streamed_response_wrapper( + rules.update, + ) + self.delete = to_streamed_response_wrapper( + rules.delete, + ) + self.delete_rule = to_streamed_response_wrapper( + rules.delete_rule, + ) + self.edit_rule = to_streamed_response_wrapper( + rules.edit_rule, + ) + self.get = to_streamed_response_wrapper( + rules.get, + ) + self.get_rule = to_streamed_response_wrapper( + rules.get_rule, + ) + + +class AsyncRulesResourceWithStreamingResponse: + def __init__(self, rules: AsyncRulesResource) -> None: + self._rules = rules + + self.update = async_to_streamed_response_wrapper( + rules.update, + ) + self.delete = async_to_streamed_response_wrapper( + rules.delete, + ) + self.delete_rule = async_to_streamed_response_wrapper( + rules.delete_rule, + ) + self.edit_rule = async_to_streamed_response_wrapper( + rules.edit_rule, + ) + self.get = async_to_streamed_response_wrapper( + rules.get, + ) + self.get_rule = async_to_streamed_response_wrapper( + rules.get_rule, + ) diff --git a/src/cloudflare/resources/moq/relays/relays.py b/src/cloudflare/resources/moq/relays/relays.py index cadf95db426..fdb6fc22d20 100644 --- a/src/cloudflare/resources/moq/relays/relays.py +++ b/src/cloudflare/resources/moq/relays/relays.py @@ -134,6 +134,9 @@ def update( Args: account_id: Cloudflare account identifier. + config: Relay configuration. All sub-objects use whole-object replacement when present; + omitted sub-objects preserve the existing value. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -425,6 +428,9 @@ async def update( Args: account_id: Cloudflare account identifier. + config: Relay configuration. All sub-objects use whole-object replacement when present; + omitted sub-objects preserve the existing value. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request diff --git a/src/cloudflare/resources/network_interconnects/cnis.py b/src/cloudflare/resources/network_interconnects/cnis.py index 7b94cd5bd7f..4867424970b 100644 --- a/src/cloudflare/resources/network_interconnects/cnis.py +++ b/src/cloudflare/resources/network_interconnects/cnis.py @@ -136,14 +136,11 @@ def update( p2p_ip: Cloudflare end of the point-to-point link - bgp_mode: The BGP mode for a CNI. + bgp_mode: + The BGP mode for a CNI. One of the following: - Controls the customer-facing data path: - - - `DynamicRouteExchange` — Full BGP: routes flow through to conduit via CRE / - bgp-bridge / bgp-bridge-receiver. - - `AdvertiseOnly` — static advertisement via taserver, no routes exchanged with - Conduit + - `dynamic_route_exchange` + - `advertise_only` extra_headers: Send extra headers @@ -424,14 +421,11 @@ async def update( p2p_ip: Cloudflare end of the point-to-point link - bgp_mode: The BGP mode for a CNI. - - Controls the customer-facing data path: + bgp_mode: + The BGP mode for a CNI. One of the following: - - `DynamicRouteExchange` — Full BGP: routes flow through to conduit via CRE / - bgp-bridge / bgp-bridge-receiver. - - `AdvertiseOnly` — static advertisement via taserver, no routes exchanged with - Conduit + - `dynamic_route_exchange` + - `advertise_only` extra_headers: Send extra headers diff --git a/src/cloudflare/resources/organizations/billing/usage.py b/src/cloudflare/resources/organizations/billing/usage.py index c3c62f784ed..76954a629d9 100644 --- a/src/cloudflare/resources/organizations/billing/usage.py +++ b/src/cloudflare/resources/organizations/billing/usage.py @@ -68,8 +68,9 @@ def get( allowances and may result in zero cost. The response includes usage for every account belonging to the specified organization. - **Note:** Cost and pricing fields are not yet populated and will be absent from - responses until billing integration is complete. + **Note:** This endpoint serves `usage` records only; cost and pricing fields are + absent from responses. Rated costs are available per account via + `POST /accounts/{account_id}/billable/usage` with `Metric: cost`. When `from` and `to` are omitted, defaults to the start of the current month through today. The maximum date range is 31 days. @@ -162,8 +163,9 @@ async def get( allowances and may result in zero cost. The response includes usage for every account belonging to the specified organization. - **Note:** Cost and pricing fields are not yet populated and will be absent from - responses until billing integration is complete. + **Note:** This endpoint serves `usage` records only; cost and pricing fields are + absent from responses. Rated costs are available per account via + `POST /accounts/{account_id}/billable/usage` with `Metric: cost`. When `from` and `to` are omitted, defaults to the start of the current month through today. The maximum date range is 31 days. diff --git a/src/cloudflare/resources/organizations/organization_profile.py b/src/cloudflare/resources/organizations/organization_profile.py index b8e2724e896..29de5add496 100644 --- a/src/cloudflare/resources/organizations/organization_profile.py +++ b/src/cloudflare/resources/organizations/organization_profile.py @@ -2,11 +2,11 @@ from __future__ import annotations -from typing import Type, cast +from typing import Type, Optional, cast import httpx -from ..._types import Body, Query, Headers, NoneType, NotGiven, not_given +from ..._types import Body, Omit, Query, Headers, NoneType, NotGiven, omit, not_given from ..._utils import path_template, maybe_transform, async_maybe_transform from ..._compat import cached_property from ..._resource import SyncAPIResource, AsyncAPIResource @@ -48,11 +48,11 @@ def update( self, organization_id: str, *, - business_address: str, - business_email: str, - business_name: str, - business_phone: str, - external_metadata: str, + business_address: Optional[str] | Omit = omit, + business_email: Optional[str] | Omit = omit, + business_name: Optional[str] | Omit = omit, + business_phone: Optional[str] | Omit = omit, + external_metadata: Optional[str] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -60,10 +60,13 @@ def update( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> None: - """Modify organization profile. - - (Currently in Public Beta - see - https://developers.cloudflare.com/fundamentals/organizations/) + """ + Partially updates the business profile (name, email, phone, address, and + external metadata) associated with this organization's customer record, creating + the profile if it does not exist. Changes apply to every account and + organization sharing that profile. Omitted, empty, or null fields are left + unchanged. Each profile field is limited to 1,000 UTF-8 bytes. Only available to + members of the organization. Args: extra_headers: Send extra headers @@ -106,10 +109,11 @@ def get( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> OrganizationProfile: - """Get an organizations profile if it exists. - - (Currently in Public Beta - see - https://developers.cloudflare.com/fundamentals/organizations/) + """ + Retrieves the business profile (name, email, phone, address, and external + metadata) associated with this organization's customer record. Profiles can be + shared across accounts and organizations. Only available to members of the + organization. Args: extra_headers: Send extra headers @@ -159,11 +163,11 @@ async def update( self, organization_id: str, *, - business_address: str, - business_email: str, - business_name: str, - business_phone: str, - external_metadata: str, + business_address: Optional[str] | Omit = omit, + business_email: Optional[str] | Omit = omit, + business_name: Optional[str] | Omit = omit, + business_phone: Optional[str] | Omit = omit, + external_metadata: Optional[str] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -171,10 +175,13 @@ async def update( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> None: - """Modify organization profile. - - (Currently in Public Beta - see - https://developers.cloudflare.com/fundamentals/organizations/) + """ + Partially updates the business profile (name, email, phone, address, and + external metadata) associated with this organization's customer record, creating + the profile if it does not exist. Changes apply to every account and + organization sharing that profile. Omitted, empty, or null fields are left + unchanged. Each profile field is limited to 1,000 UTF-8 bytes. Only available to + members of the organization. Args: extra_headers: Send extra headers @@ -217,10 +224,11 @@ async def get( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> OrganizationProfile: - """Get an organizations profile if it exists. - - (Currently in Public Beta - see - https://developers.cloudflare.com/fundamentals/organizations/) + """ + Retrieves the business profile (name, email, phone, address, and external + metadata) associated with this organization's customer record. Profiles can be + shared across accounts and organizations. Only available to members of the + organization. Args: extra_headers: Send extra headers diff --git a/src/cloudflare/resources/organizations/organizations.py b/src/cloudflare/resources/organizations/organizations.py index f14410fc0a0..6071ab35039 100644 --- a/src/cloudflare/resources/organizations/organizations.py +++ b/src/cloudflare/resources/organizations/organizations.py @@ -3,6 +3,7 @@ from __future__ import annotations from typing import Type, cast +from typing_extensions import Literal import httpx @@ -43,19 +44,20 @@ OrganizationProfileResourceWithStreamingResponse, AsyncOrganizationProfileResourceWithStreamingResponse, ) -from ...types.organizations import ( - organization_list_params, - organization_create_params, - organization_update_params, -) +from ...types.organizations import organization_list_params, organization_create_params, organization_update_params from ...types.organizations.organization import Organization -from ...types.organizations.organization_profile_param import OrganizationProfileParam from ...types.organizations.organization_delete_response import OrganizationDeleteResponse __all__ = ["OrganizationsResource", "AsyncOrganizationsResource"] class OrganizationsResource(SyncAPIResource): + """ + User API tokens can list and create Organizations, but reading, updating, or deleting an Organization requires a Global API key and your registered email address. The `cloudflare_organization` Terraform resource therefore requires a Global API key for its full lifecycle. + + See [Organizations authentication limitations](https://developers.cloudflare.com/fundamentals/organizations/limitations/#api-authentication) for credential compatibility by operation. Each endpoint’s **Security** section lists its supported authentication methods, with **Accepted Permissions** where applicable. + """ + @cached_property def organization_profile(self) -> OrganizationProfileResource: return OrganizationProfileResource(self._client) @@ -92,7 +94,7 @@ def create( *, name: str, parent: organization_create_params.Parent | Omit = omit, - profile: OrganizationProfileParam | Omit = omit, + profile: organization_create_params.Profile | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -103,10 +105,19 @@ def create( """Create a new organization for a user. Sub-organization creation availability - depends on the organization's capabilities. (Currently in Public Beta - see - https://developers.cloudflare.com/fundamentals/organizations/) + depends on the organization's capabilities. The optional `profile` object + accepts partial profile details; its individual fields are not required. + Organization names are limited to 65 UTF-8 bytes. Each profile field is limited + to 1,000 UTF-8 bytes, and a non-empty business email must be valid. At least one + of business name, address, phone, or email must be non-empty to persist a + profile. Args: + name: The Organization name, limited to 65 UTF-8 bytes. + + profile: Optional profile fields, each limited to 1,000 UTF-8 bytes. An empty profile is + ignored. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -139,9 +150,8 @@ def update( self, organization_id: str, *, - name: str, - parent: organization_update_params.Parent | Omit = omit, - profile: OrganizationProfileParam | Omit = omit, + name: str | Omit = omit, + parent_id: str | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -151,10 +161,17 @@ def update( ) -> Organization: """Update an organization's name. - (Currently in Public Beta - see - https://developers.cloudflare.com/fundamentals/organizations/) + Supplying `parent_id` verifies the current + parent; this endpoint cannot move an organization. Organization names are + limited to 65 UTF-8 bytes. Args: + name: The Organization's display name, limited to 65 UTF-8 bytes. An omitted, empty, + or unchanged value is a no-op. + + parent_id: The current parent Organization ID. A different value is rejected; this endpoint + cannot move an Organization. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -170,8 +187,7 @@ def update( body=maybe_transform( { "name": name, - "parent": parent, - "profile": profile, + "parent_id": parent_id, }, organization_update_params.OrganizationUpdateParams, ), @@ -190,7 +206,10 @@ def list( *, id: SequenceNotStr[str] | Omit = omit, containing: organization_list_params.Containing | Omit = omit, + direction: Literal["asc", "desc"] | Omit = omit, + member: organization_list_params.Member | Omit = omit, name: organization_list_params.Name | Omit = omit, + order_by: Literal["name"] | Omit = omit, page_size: int | Omit = omit, page_token: str | Omit = omit, parent: organization_list_params.Parent | Omit = omit, @@ -203,13 +222,20 @@ def list( ) -> SyncSinglePage[Organization]: """Retrieve a list of organizations a particular user has access to. - (Currently in - Public Beta - see https://developers.cloudflare.com/fundamentals/organizations/) + At most one of + `containing.account`, `containing.user`, or `containing.organization` may be + provided. Args: id: Only return organizations with the specified IDs (ex. id=foo&id=bar). Send multiple elements by repeating the query value. + direction: Sort direction for the `order_by` field. Defaults to `asc` when `order_by` is + specified. + + order_by: Field to order results by. Currently supported values: `name`. When not + specified, results are ordered by hierarchy. + page_size: The amount of items to return. Defaults to 10. page_token: An opaque token returned from the last list response that when provided will @@ -238,7 +264,10 @@ def list( { "id": id, "containing": containing, + "direction": direction, + "member": member, "name": name, + "order_by": order_by, "page_size": page_size, "page_token": page_token, "parent": parent, @@ -262,12 +291,12 @@ def delete( ) -> OrganizationDeleteResponse: """Delete an organization. - The organization MUST be empty before deleting. It must - not contain any sub-organizations, accounts, members or users. Sub-organization - deletion availability depends on the organization's capabilities. (Currently in - Public Beta - see https://developers.cloudflare.com/fundamentals/organizations/) + It must not contain active sub-organizations or + accounts. A root organization must also have no active managed users. + Sub-organization deletion availability depends on the organization's + capabilities. - **Access Control:** Restricted to enterprise organizations. + **Access Control:** Root deletion is restricted to enterprise organizations. Args: extra_headers: Send extra headers @@ -303,10 +332,8 @@ def get( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Organization: - """Retrieve the details of a certain organization. - - (Currently in Public Beta - see - https://developers.cloudflare.com/fundamentals/organizations/) + """ + Retrieve the details of a certain organization. Args: extra_headers: Send extra headers @@ -333,6 +360,12 @@ def get( class AsyncOrganizationsResource(AsyncAPIResource): + """ + User API tokens can list and create Organizations, but reading, updating, or deleting an Organization requires a Global API key and your registered email address. The `cloudflare_organization` Terraform resource therefore requires a Global API key for its full lifecycle. + + See [Organizations authentication limitations](https://developers.cloudflare.com/fundamentals/organizations/limitations/#api-authentication) for credential compatibility by operation. Each endpoint’s **Security** section lists its supported authentication methods, with **Accepted Permissions** where applicable. + """ + @cached_property def organization_profile(self) -> AsyncOrganizationProfileResource: return AsyncOrganizationProfileResource(self._client) @@ -369,7 +402,7 @@ async def create( *, name: str, parent: organization_create_params.Parent | Omit = omit, - profile: OrganizationProfileParam | Omit = omit, + profile: organization_create_params.Profile | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -380,10 +413,19 @@ async def create( """Create a new organization for a user. Sub-organization creation availability - depends on the organization's capabilities. (Currently in Public Beta - see - https://developers.cloudflare.com/fundamentals/organizations/) + depends on the organization's capabilities. The optional `profile` object + accepts partial profile details; its individual fields are not required. + Organization names are limited to 65 UTF-8 bytes. Each profile field is limited + to 1,000 UTF-8 bytes, and a non-empty business email must be valid. At least one + of business name, address, phone, or email must be non-empty to persist a + profile. Args: + name: The Organization name, limited to 65 UTF-8 bytes. + + profile: Optional profile fields, each limited to 1,000 UTF-8 bytes. An empty profile is + ignored. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -416,9 +458,8 @@ async def update( self, organization_id: str, *, - name: str, - parent: organization_update_params.Parent | Omit = omit, - profile: OrganizationProfileParam | Omit = omit, + name: str | Omit = omit, + parent_id: str | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -428,10 +469,17 @@ async def update( ) -> Organization: """Update an organization's name. - (Currently in Public Beta - see - https://developers.cloudflare.com/fundamentals/organizations/) + Supplying `parent_id` verifies the current + parent; this endpoint cannot move an organization. Organization names are + limited to 65 UTF-8 bytes. Args: + name: The Organization's display name, limited to 65 UTF-8 bytes. An omitted, empty, + or unchanged value is a no-op. + + parent_id: The current parent Organization ID. A different value is rejected; this endpoint + cannot move an Organization. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -447,8 +495,7 @@ async def update( body=await async_maybe_transform( { "name": name, - "parent": parent, - "profile": profile, + "parent_id": parent_id, }, organization_update_params.OrganizationUpdateParams, ), @@ -467,7 +514,10 @@ def list( *, id: SequenceNotStr[str] | Omit = omit, containing: organization_list_params.Containing | Omit = omit, + direction: Literal["asc", "desc"] | Omit = omit, + member: organization_list_params.Member | Omit = omit, name: organization_list_params.Name | Omit = omit, + order_by: Literal["name"] | Omit = omit, page_size: int | Omit = omit, page_token: str | Omit = omit, parent: organization_list_params.Parent | Omit = omit, @@ -480,13 +530,20 @@ def list( ) -> AsyncPaginator[Organization, AsyncSinglePage[Organization]]: """Retrieve a list of organizations a particular user has access to. - (Currently in - Public Beta - see https://developers.cloudflare.com/fundamentals/organizations/) + At most one of + `containing.account`, `containing.user`, or `containing.organization` may be + provided. Args: id: Only return organizations with the specified IDs (ex. id=foo&id=bar). Send multiple elements by repeating the query value. + direction: Sort direction for the `order_by` field. Defaults to `asc` when `order_by` is + specified. + + order_by: Field to order results by. Currently supported values: `name`. When not + specified, results are ordered by hierarchy. + page_size: The amount of items to return. Defaults to 10. page_token: An opaque token returned from the last list response that when provided will @@ -515,7 +572,10 @@ def list( { "id": id, "containing": containing, + "direction": direction, + "member": member, "name": name, + "order_by": order_by, "page_size": page_size, "page_token": page_token, "parent": parent, @@ -539,12 +599,12 @@ async def delete( ) -> OrganizationDeleteResponse: """Delete an organization. - The organization MUST be empty before deleting. It must - not contain any sub-organizations, accounts, members or users. Sub-organization - deletion availability depends on the organization's capabilities. (Currently in - Public Beta - see https://developers.cloudflare.com/fundamentals/organizations/) + It must not contain active sub-organizations or + accounts. A root organization must also have no active managed users. + Sub-organization deletion availability depends on the organization's + capabilities. - **Access Control:** Restricted to enterprise organizations. + **Access Control:** Root deletion is restricted to enterprise organizations. Args: extra_headers: Send extra headers @@ -580,10 +640,8 @@ async def get( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Organization: - """Retrieve the details of a certain organization. - - (Currently in Public Beta - see - https://developers.cloudflare.com/fundamentals/organizations/) + """ + Retrieve the details of a certain organization. Args: extra_headers: Send extra headers diff --git a/src/cloudflare/resources/pipelines/sinks.py b/src/cloudflare/resources/pipelines/sinks.py index f8b256f59dd..e475d5fdc22 100644 --- a/src/cloudflare/resources/pipelines/sinks.py +++ b/src/cloudflare/resources/pipelines/sinks.py @@ -116,7 +116,9 @@ def list( self, *, account_id: str, + direction: Literal["asc", "desc"] | Omit = omit, name: str | Omit = omit, + order_by: Literal["name", "created_at"] | Omit = omit, page: float | Omit = omit, per_page: float | Omit = omit, pipeline_id: str | Omit = omit, @@ -133,8 +135,12 @@ def list( Args: account_id: Specifies the public ID of the account. + direction: Sort direction. + name: Filters sinks by name (case-insensitive substring). + order_by: Sorts sinks by this field. Defaults to `created_at`. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -155,7 +161,9 @@ def list( timeout=timeout, query=maybe_transform( { + "direction": direction, "name": name, + "order_by": order_by, "page": page, "per_page": per_page, "pipeline_id": pipeline_id, @@ -347,7 +355,9 @@ def list( self, *, account_id: str, + direction: Literal["asc", "desc"] | Omit = omit, name: str | Omit = omit, + order_by: Literal["name", "created_at"] | Omit = omit, page: float | Omit = omit, per_page: float | Omit = omit, pipeline_id: str | Omit = omit, @@ -364,8 +374,12 @@ def list( Args: account_id: Specifies the public ID of the account. + direction: Sort direction. + name: Filters sinks by name (case-insensitive substring). + order_by: Sorts sinks by this field. Defaults to `created_at`. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -386,7 +400,9 @@ def list( timeout=timeout, query=maybe_transform( { + "direction": direction, "name": name, + "order_by": order_by, "page": page, "per_page": per_page, "pipeline_id": pipeline_id, diff --git a/src/cloudflare/resources/pipelines/streams.py b/src/cloudflare/resources/pipelines/streams.py index d93b6747a25..49ce20b8298 100644 --- a/src/cloudflare/resources/pipelines/streams.py +++ b/src/cloudflare/resources/pipelines/streams.py @@ -3,6 +3,7 @@ from __future__ import annotations from typing import Type, cast +from typing_extensions import Literal import httpx @@ -167,7 +168,9 @@ def list( self, *, account_id: str, + direction: Literal["asc", "desc"] | Omit = omit, name: str | Omit = omit, + order_by: Literal["name", "created_at"] | Omit = omit, page: float | Omit = omit, per_page: float | Omit = omit, pipeline_id: str | Omit = omit, @@ -184,8 +187,12 @@ def list( Args: account_id: Specifies the public ID of the account. + direction: Sort direction. + name: Filters streams by name (case-insensitive substring). + order_by: Sorts streams by this field. Defaults to `created_at`. + pipeline_id: Specifies the public ID of the pipeline. extra_headers: Send extra headers @@ -208,7 +215,9 @@ def list( timeout=timeout, query=maybe_transform( { + "direction": direction, "name": name, + "order_by": order_by, "page": page, "per_page": per_page, "pipeline_id": pipeline_id, @@ -451,7 +460,9 @@ def list( self, *, account_id: str, + direction: Literal["asc", "desc"] | Omit = omit, name: str | Omit = omit, + order_by: Literal["name", "created_at"] | Omit = omit, page: float | Omit = omit, per_page: float | Omit = omit, pipeline_id: str | Omit = omit, @@ -468,8 +479,12 @@ def list( Args: account_id: Specifies the public ID of the account. + direction: Sort direction. + name: Filters streams by name (case-insensitive substring). + order_by: Sorts streams by this field. Defaults to `created_at`. + pipeline_id: Specifies the public ID of the pipeline. extra_headers: Send extra headers @@ -492,7 +507,9 @@ def list( timeout=timeout, query=maybe_transform( { + "direction": direction, "name": name, + "order_by": order_by, "page": page, "per_page": per_page, "pipeline_id": pipeline_id, diff --git a/src/cloudflare/resources/precursor/api.md b/src/cloudflare/resources/precursor/api.md index 76bce11f72b..8d92f2d8a91 100644 --- a/src/cloudflare/resources/precursor/api.md +++ b/src/cloudflare/resources/precursor/api.md @@ -3,7 +3,7 @@ Types: ```python -from cloudflare.types.precursor import EnforcementRule, PrecursorConfig +from cloudflare.types.precursor import PrecursorConfig ``` Methods: diff --git a/src/cloudflare/resources/precursor/precursor.py b/src/cloudflare/resources/precursor/precursor.py index 84d92bff868..6c6ab09cb6f 100644 --- a/src/cloudflare/resources/precursor/precursor.py +++ b/src/cloudflare/resources/precursor/precursor.py @@ -21,7 +21,6 @@ from ..._base_client import make_request_options from ...types.precursor import precursor_update_params from ...types.precursor.precursor_config import PrecursorConfig -from ...types.precursor.enforcement_rule_param import EnforcementRuleParam __all__ = ["PrecursorResource", "AsyncPrecursorResource"] @@ -50,8 +49,10 @@ def update( self, *, zone_id: str, - default_mode: Literal["off", "min-friction", "max-security"] | Omit = omit, - enforcement_rules: Iterable[EnforcementRuleParam] | Omit = omit, + cloudflare_version: Literal["1.0"] = "1.0", + mode: Literal["off", "monitor", "arm"] | Omit = omit, + rules: Iterable[precursor_update_params.Rule] | Omit = omit, + show_interstitial: bool | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -62,28 +63,32 @@ def update( """ Updates the Precursor configuration for a zone. - `default_mode` sets the zone-level enforcement mode. `enforcement_rules` is the - ordered list of rules that override enforcement for matching requests. + `mode` controls whether Precursor detection is off, monitoring, or armed. + `show_interstitial` controls the zone-level response when armed. `rules` is the + ordered list of overrides for matching requests. This is a partial update: only the fields present in the request body are changed. - - Sending an empty array (`[]`) clears all enforcement rules. - - At least one of `default_mode` or `enforcement_rules` must be present; an + - Sending an empty array (`[]`) clears all rules. + - At least one of `mode`, `show_interstitial`, or `rules` must be present; an empty body (`{}`) is rejected with `400`. - Rule `id` is read-only (assigned by Cloudflare) and ignored on input. - - Rule `mode` must be `min-friction` or `max-security` (`off` is not a valid - rule mode; use `default_mode` to disable enforcement). + - Rule `show_interstitial` is required and controls the response for requests + that match that rule. - Rule `expression` is limited to 4000 characters. The limit applies to each rule individually, not to the combined size of all rules. Args: zone_id: Identifier. - default_mode: The zone-level Precursor enforcement mode applied to requests that do not match - a more specific enforcement rule. + mode: Controls Precursor detection for the zone. `off` disables detection, `monitor` + records detections without affecting bot scores, and `arm` allows detections to + affect bot scores. - enforcement_rules: The ordered list of enforcement rules for the zone. + rules: The ordered list of Precursor rules for the zone. + + show_interstitial: Whether Precursor shows an interstitial when it takes action on a request. extra_headers: Send extra headers @@ -95,12 +100,15 @@ def update( """ if not zone_id: raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + extra_headers = {"Cloudflare-Version": str(cloudflare_version), **(extra_headers or {})} + extra_headers.update({"Cloudflare-Version": "1.0"}) return self._put( path_template("/zones/{zone_id}/precursor", zone_id=zone_id), body=maybe_transform( { - "default_mode": default_mode, - "enforcement_rules": enforcement_rules, + "mode": mode, + "rules": rules, + "show_interstitial": show_interstitial, }, precursor_update_params.PrecursorUpdateParams, ), @@ -118,6 +126,7 @@ def get( self, *, zone_id: str, + cloudflare_version: Literal["1.0"] = "1.0", # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -126,8 +135,8 @@ def get( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Optional[PrecursorConfig]: """ - Retrieve a zone's Precursor configuration: the zone-level `default_mode` and the - ordered list of `enforcement_rules`. + Retrieve a zone's Precursor configuration: the detection `mode`, whether to + `show_interstitial`, and the ordered list of `rules`. Args: zone_id: Identifier. @@ -142,6 +151,8 @@ def get( """ if not zone_id: raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + extra_headers = {"Cloudflare-Version": str(cloudflare_version), **(extra_headers or {})} + extra_headers.update({"Cloudflare-Version": "1.0"}) return self._get( path_template("/zones/{zone_id}/precursor", zone_id=zone_id), options=make_request_options( @@ -179,8 +190,10 @@ async def update( self, *, zone_id: str, - default_mode: Literal["off", "min-friction", "max-security"] | Omit = omit, - enforcement_rules: Iterable[EnforcementRuleParam] | Omit = omit, + cloudflare_version: Literal["1.0"] = "1.0", + mode: Literal["off", "monitor", "arm"] | Omit = omit, + rules: Iterable[precursor_update_params.Rule] | Omit = omit, + show_interstitial: bool | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -191,28 +204,32 @@ async def update( """ Updates the Precursor configuration for a zone. - `default_mode` sets the zone-level enforcement mode. `enforcement_rules` is the - ordered list of rules that override enforcement for matching requests. + `mode` controls whether Precursor detection is off, monitoring, or armed. + `show_interstitial` controls the zone-level response when armed. `rules` is the + ordered list of overrides for matching requests. This is a partial update: only the fields present in the request body are changed. - - Sending an empty array (`[]`) clears all enforcement rules. - - At least one of `default_mode` or `enforcement_rules` must be present; an + - Sending an empty array (`[]`) clears all rules. + - At least one of `mode`, `show_interstitial`, or `rules` must be present; an empty body (`{}`) is rejected with `400`. - Rule `id` is read-only (assigned by Cloudflare) and ignored on input. - - Rule `mode` must be `min-friction` or `max-security` (`off` is not a valid - rule mode; use `default_mode` to disable enforcement). + - Rule `show_interstitial` is required and controls the response for requests + that match that rule. - Rule `expression` is limited to 4000 characters. The limit applies to each rule individually, not to the combined size of all rules. Args: zone_id: Identifier. - default_mode: The zone-level Precursor enforcement mode applied to requests that do not match - a more specific enforcement rule. + mode: Controls Precursor detection for the zone. `off` disables detection, `monitor` + records detections without affecting bot scores, and `arm` allows detections to + affect bot scores. + + rules: The ordered list of Precursor rules for the zone. - enforcement_rules: The ordered list of enforcement rules for the zone. + show_interstitial: Whether Precursor shows an interstitial when it takes action on a request. extra_headers: Send extra headers @@ -224,12 +241,15 @@ async def update( """ if not zone_id: raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + extra_headers = {"Cloudflare-Version": str(cloudflare_version), **(extra_headers or {})} + extra_headers.update({"Cloudflare-Version": "1.0"}) return await self._put( path_template("/zones/{zone_id}/precursor", zone_id=zone_id), body=await async_maybe_transform( { - "default_mode": default_mode, - "enforcement_rules": enforcement_rules, + "mode": mode, + "rules": rules, + "show_interstitial": show_interstitial, }, precursor_update_params.PrecursorUpdateParams, ), @@ -247,6 +267,7 @@ async def get( self, *, zone_id: str, + cloudflare_version: Literal["1.0"] = "1.0", # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -255,8 +276,8 @@ async def get( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Optional[PrecursorConfig]: """ - Retrieve a zone's Precursor configuration: the zone-level `default_mode` and the - ordered list of `enforcement_rules`. + Retrieve a zone's Precursor configuration: the detection `mode`, whether to + `show_interstitial`, and the ordered list of `rules`. Args: zone_id: Identifier. @@ -271,6 +292,8 @@ async def get( """ if not zone_id: raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + extra_headers = {"Cloudflare-Version": str(cloudflare_version), **(extra_headers or {})} + extra_headers.update({"Cloudflare-Version": "1.0"}) return await self._get( path_template("/zones/{zone_id}/precursor", zone_id=zone_id), options=make_request_options( diff --git a/src/cloudflare/resources/r2/api.md b/src/cloudflare/resources/r2/api.md index 4cdc33f6c5b..781d3892a8e 100644 --- a/src/cloudflare/resources/r2/api.md +++ b/src/cloudflare/resources/r2/api.md @@ -153,6 +153,20 @@ Methods: - client.r2.buckets.objects.get(object_key, \*, account_id, bucket_name) -> BinaryAPIResponse - client.r2.buckets.objects.upload(object_key, body, \*, account_id, bucket_name, \*\*params) -> ObjectUploadResponse +### Jobs + +Types: + +```python +from cloudflare.types.r2.buckets import JobCreateResponse, JobListResponse, JobGetResponse +``` + +Methods: + +- client.r2.buckets.jobs.create(bucket_name, \*, account_id, \*\*params) -> JobCreateResponse +- client.r2.buckets.jobs.list(bucket_name, \*, account_id, \*\*params) -> JobListResponse +- client.r2.buckets.jobs.get(job_id, \*, account_id, bucket_name) -> JobGetResponse + ## TemporaryCredentials Types: diff --git a/src/cloudflare/resources/r2/buckets/__init__.py b/src/cloudflare/resources/r2/buckets/__init__.py index 59726b5e380..07ba7902802 100644 --- a/src/cloudflare/resources/r2/buckets/__init__.py +++ b/src/cloudflare/resources/r2/buckets/__init__.py @@ -8,6 +8,14 @@ CORSResourceWithStreamingResponse, AsyncCORSResourceWithStreamingResponse, ) +from .jobs import ( + JobsResource, + AsyncJobsResource, + JobsResourceWithRawResponse, + AsyncJobsResourceWithRawResponse, + JobsResourceWithStreamingResponse, + AsyncJobsResourceWithStreamingResponse, +) from .locks import ( LocksResource, AsyncLocksResource, @@ -122,6 +130,12 @@ "AsyncObjectsResourceWithRawResponse", "ObjectsResourceWithStreamingResponse", "AsyncObjectsResourceWithStreamingResponse", + "JobsResource", + "AsyncJobsResource", + "JobsResourceWithRawResponse", + "AsyncJobsResourceWithRawResponse", + "JobsResourceWithStreamingResponse", + "AsyncJobsResourceWithStreamingResponse", "BucketsResource", "AsyncBucketsResource", "BucketsResourceWithRawResponse", diff --git a/src/cloudflare/resources/r2/buckets/buckets.py b/src/cloudflare/resources/r2/buckets/buckets.py index d3a79b58735..50efd98802a 100644 --- a/src/cloudflare/resources/r2/buckets/buckets.py +++ b/src/cloudflare/resources/r2/buckets/buckets.py @@ -15,6 +15,14 @@ CORSResourceWithStreamingResponse, AsyncCORSResourceWithStreamingResponse, ) +from .jobs import ( + JobsResource, + AsyncJobsResource, + JobsResourceWithRawResponse, + AsyncJobsResourceWithRawResponse, + JobsResourceWithStreamingResponse, + AsyncJobsResourceWithStreamingResponse, +) from .locks import ( LocksResource, AsyncLocksResource, @@ -123,6 +131,10 @@ def sippy(self) -> SippyResource: def objects(self) -> ObjectsResource: return ObjectsResource(self._client) + @cached_property + def jobs(self) -> JobsResource: + return JobsResource(self._client) + @cached_property def with_raw_response(self) -> BucketsResourceWithRawResponse: """ @@ -489,6 +501,10 @@ def sippy(self) -> AsyncSippyResource: def objects(self) -> AsyncObjectsResource: return AsyncObjectsResource(self._client) + @cached_property + def jobs(self) -> AsyncJobsResource: + return AsyncJobsResource(self._client) + @cached_property def with_raw_response(self) -> AsyncBucketsResourceWithRawResponse: """ @@ -874,6 +890,10 @@ def sippy(self) -> SippyResourceWithRawResponse: def objects(self) -> ObjectsResourceWithRawResponse: return ObjectsResourceWithRawResponse(self._buckets.objects) + @cached_property + def jobs(self) -> JobsResourceWithRawResponse: + return JobsResourceWithRawResponse(self._buckets.jobs) + class AsyncBucketsResourceWithRawResponse: def __init__(self, buckets: AsyncBucketsResource) -> None: @@ -927,6 +947,10 @@ def sippy(self) -> AsyncSippyResourceWithRawResponse: def objects(self) -> AsyncObjectsResourceWithRawResponse: return AsyncObjectsResourceWithRawResponse(self._buckets.objects) + @cached_property + def jobs(self) -> AsyncJobsResourceWithRawResponse: + return AsyncJobsResourceWithRawResponse(self._buckets.jobs) + class BucketsResourceWithStreamingResponse: def __init__(self, buckets: BucketsResource) -> None: @@ -980,6 +1004,10 @@ def sippy(self) -> SippyResourceWithStreamingResponse: def objects(self) -> ObjectsResourceWithStreamingResponse: return ObjectsResourceWithStreamingResponse(self._buckets.objects) + @cached_property + def jobs(self) -> JobsResourceWithStreamingResponse: + return JobsResourceWithStreamingResponse(self._buckets.jobs) + class AsyncBucketsResourceWithStreamingResponse: def __init__(self, buckets: AsyncBucketsResource) -> None: @@ -1032,3 +1060,7 @@ def sippy(self) -> AsyncSippyResourceWithStreamingResponse: @cached_property def objects(self) -> AsyncObjectsResourceWithStreamingResponse: return AsyncObjectsResourceWithStreamingResponse(self._buckets.objects) + + @cached_property + def jobs(self) -> AsyncJobsResourceWithStreamingResponse: + return AsyncJobsResourceWithStreamingResponse(self._buckets.jobs) diff --git a/src/cloudflare/resources/r2/buckets/jobs.py b/src/cloudflare/resources/r2/buckets/jobs.py new file mode 100644 index 00000000000..0d4a17bb88c --- /dev/null +++ b/src/cloudflare/resources/r2/buckets/jobs.py @@ -0,0 +1,797 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Any, Type, cast +from typing_extensions import Literal, overload + +import httpx + +from ...._types import Body, Omit, Query, Headers, NotGiven, omit, not_given +from ...._utils import is_given, path_template, required_args, maybe_transform, strip_not_given, async_maybe_transform +from ...._compat import cached_property +from ...._resource import SyncAPIResource, AsyncAPIResource +from ...._response import ( + to_raw_response_wrapper, + to_streamed_response_wrapper, + async_to_raw_response_wrapper, + async_to_streamed_response_wrapper, +) +from ...._wrappers import ResultWrapper +from ...._base_client import make_request_options +from ....types.r2.buckets import job_list_params, job_create_params +from ....types.r2.buckets.job_get_response import JobGetResponse +from ....types.r2.buckets.job_list_response import JobListResponse +from ....types.r2.buckets.job_create_response import JobCreateResponse + +__all__ = ["JobsResource", "AsyncJobsResource"] + + +class JobsResource(SyncAPIResource): + @cached_property + def with_raw_response(self) -> JobsResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers + """ + return JobsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> JobsResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response + """ + return JobsResourceWithStreamingResponse(self) + + @overload + def create( + self, + bucket_name: str, + *, + account_id: str, + job_type: Literal["prefixDelete"], + prefix: str, + cf_r2_data_catalog_check: str | Omit = omit, + cf_r2_jurisdiction: Literal["default", "eu", "us", "fedramp", "fedramp-high"] | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> JobCreateResponse: + """Creates a background job for an R2 bucket. + + The `jobType` field selects the job: + + - **`prefixDelete`**: deletes every object whose key begins with `prefix`. A + non-empty prefix must end in `/`. An empty prefix (`""`) empties the entire + bucket. + - **`storageClassMigration`**: migrates every object in the bucket between + storage classes. `sourceStorageClass` and `destinationStorageClass` must be + provided together and must differ; omitting both migrates from + `InfrequentAccess` to `Standard`. + + Poll the returned `id` with the Get Bucket Job endpoint. Small prefix-delete + jobs can finish synchronously and return `COMPLETED`. Objects uploaded after a + background job starts are not affected by that job. + + For prefix-delete jobs: abort active multipart uploads before submitting the + request, since a synchronously completed job does not abort them, and avoid + writing objects or starting multipart uploads while a bucket-emptying job is in + progress. Each request creates a distinct job, and the number of active + prefix-delete jobs is limited per bucket; wait for an existing job to finish + before retrying a request rejected with HTTP 429. A bucket cannot be emptied + while event notifications are configured (HTTP 409 / error code 10083). To + protect a bucket with R2 Data Catalog enabled, send the + `cf-r2-data-catalog-check` header; a conflict is returned with HTTP 409 / error + code 10081. + + Prefix-delete jobs require permission to delete objects; storage-class migration + jobs require permission to write to the bucket. + + Args: + account_id: Cloudflare account ID that owns the R2 resource. + + bucket_name: Name of the bucket. + + prefix: Prefix matched against object keys. A non-empty value must end in `/`. An empty + string empties the entire bucket. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + ... + + @overload + def create( + self, + bucket_name: str, + *, + account_id: str, + job_type: Literal["storageClassMigration"], + destination_storage_class: Literal["Standard", "InfrequentAccess"] | Omit = omit, + source_storage_class: Literal["Standard", "InfrequentAccess"] | Omit = omit, + cf_r2_data_catalog_check: str | Omit = omit, + cf_r2_jurisdiction: Literal["default", "eu", "us", "fedramp", "fedramp-high"] | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> JobCreateResponse: + """Creates a background job for an R2 bucket. + + The `jobType` field selects the job: + + - **`prefixDelete`**: deletes every object whose key begins with `prefix`. A + non-empty prefix must end in `/`. An empty prefix (`""`) empties the entire + bucket. + - **`storageClassMigration`**: migrates every object in the bucket between + storage classes. `sourceStorageClass` and `destinationStorageClass` must be + provided together and must differ; omitting both migrates from + `InfrequentAccess` to `Standard`. + + Poll the returned `id` with the Get Bucket Job endpoint. Small prefix-delete + jobs can finish synchronously and return `COMPLETED`. Objects uploaded after a + background job starts are not affected by that job. + + For prefix-delete jobs: abort active multipart uploads before submitting the + request, since a synchronously completed job does not abort them, and avoid + writing objects or starting multipart uploads while a bucket-emptying job is in + progress. Each request creates a distinct job, and the number of active + prefix-delete jobs is limited per bucket; wait for an existing job to finish + before retrying a request rejected with HTTP 429. A bucket cannot be emptied + while event notifications are configured (HTTP 409 / error code 10083). To + protect a bucket with R2 Data Catalog enabled, send the + `cf-r2-data-catalog-check` header; a conflict is returned with HTTP 409 / error + code 10081. + + Prefix-delete jobs require permission to delete objects; storage-class migration + jobs require permission to write to the bucket. + + Args: + account_id: Cloudflare account ID that owns the R2 resource. + + bucket_name: Name of the bucket. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + ... + + @required_args(["account_id", "job_type", "prefix"], ["account_id", "job_type"]) + def create( + self, + bucket_name: str, + *, + account_id: str, + job_type: Literal["prefixDelete"] | Literal["storageClassMigration"], + prefix: str | Omit = omit, + cf_r2_data_catalog_check: str | Omit = omit, + cf_r2_jurisdiction: Literal["default", "eu", "us", "fedramp", "fedramp-high"] | Omit = omit, + destination_storage_class: Literal["Standard", "InfrequentAccess"] | Omit = omit, + source_storage_class: Literal["Standard", "InfrequentAccess"] | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> JobCreateResponse: + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not bucket_name: + raise ValueError(f"Expected a non-empty value for `bucket_name` but received {bucket_name!r}") + extra_headers = { + **strip_not_given( + { + "cf-r2-data-catalog-check": cf_r2_data_catalog_check, + "cf-r2-jurisdiction": str(cf_r2_jurisdiction) if is_given(cf_r2_jurisdiction) else not_given, + } + ), + **(extra_headers or {}), + } + return cast( + JobCreateResponse, + self._post( + path_template( + "/accounts/{account_id}/r2/buckets/{bucket_name}/jobs", + account_id=account_id, + bucket_name=bucket_name, + ), + body=maybe_transform( + { + "job_type": job_type, + "prefix": prefix, + "destination_storage_class": destination_storage_class, + "source_storage_class": source_storage_class, + }, + job_create_params.JobCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[JobCreateResponse]._unwrapper, + ), + cast_to=cast( + Any, ResultWrapper[JobCreateResponse] + ), # Union types cannot be passed in as arguments in the type system + ), + ) + + def list( + self, + bucket_name: str, + *, + account_id: str, + continuation_token: str | Omit = omit, + job_type: Literal["prefixDelete", "storageClassMigration"] | Omit = omit, + max_keys: int | Omit = omit, + status: Literal["ENQUEUED", "RUNNING", "COMPLETED", "FAILED", "CANCELLED"] | Omit = omit, + cf_r2_jurisdiction: Literal["default", "eu", "us", "fedramp", "fedramp-high"] | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> JobListResponse: + """ + Lists background jobs for an R2 bucket, including prefix-delete (and + bucket-emptying) jobs and storage-class migration jobs. Jobs of every type are + returned unless `jobType` is provided. + + Args: + account_id: Cloudflare account ID that owns the R2 resource. + + bucket_name: Name of the bucket. + + continuation_token: Pagination token received as `nextContinuationToken` in the previous response. + + job_type: Restricts results to jobs of the specified type. + + max_keys: Maximum number of jobs to return. + + status: Restricts results to jobs with the specified status. `jobType` is required when + this parameter is provided. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not bucket_name: + raise ValueError(f"Expected a non-empty value for `bucket_name` but received {bucket_name!r}") + extra_headers = { + **strip_not_given( + {"cf-r2-jurisdiction": str(cf_r2_jurisdiction) if is_given(cf_r2_jurisdiction) else not_given} + ), + **(extra_headers or {}), + } + return self._get( + path_template( + "/accounts/{account_id}/r2/buckets/{bucket_name}/jobs", account_id=account_id, bucket_name=bucket_name + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "continuation_token": continuation_token, + "job_type": job_type, + "max_keys": max_keys, + "status": status, + }, + job_list_params.JobListParams, + ), + post_parser=ResultWrapper[JobListResponse]._unwrapper, + ), + cast_to=cast(Type[JobListResponse], ResultWrapper[JobListResponse]), + ) + + def get( + self, + job_id: str, + *, + account_id: str, + bucket_name: str, + cf_r2_jurisdiction: Literal["default", "eu", "us", "fedramp", "fedramp-high"] | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> JobGetResponse: + """Gets the current status of a background job of any type for an R2 bucket. + + Poll + this endpoint with the job identifier returned by Create Bucket Job until the + status is `COMPLETED`, `FAILED`, or `CANCELLED`. + + Args: + account_id: Cloudflare account ID that owns the R2 resource. + + bucket_name: Name of the bucket. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not bucket_name: + raise ValueError(f"Expected a non-empty value for `bucket_name` but received {bucket_name!r}") + if not job_id: + raise ValueError(f"Expected a non-empty value for `job_id` but received {job_id!r}") + extra_headers = { + **strip_not_given( + {"cf-r2-jurisdiction": str(cf_r2_jurisdiction) if is_given(cf_r2_jurisdiction) else not_given} + ), + **(extra_headers or {}), + } + return cast( + JobGetResponse, + self._get( + path_template( + "/accounts/{account_id}/r2/buckets/{bucket_name}/jobs/{job_id}", + account_id=account_id, + bucket_name=bucket_name, + job_id=job_id, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[JobGetResponse]._unwrapper, + ), + cast_to=cast( + Any, ResultWrapper[JobGetResponse] + ), # Union types cannot be passed in as arguments in the type system + ), + ) + + +class AsyncJobsResource(AsyncAPIResource): + @cached_property + def with_raw_response(self) -> AsyncJobsResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers + """ + return AsyncJobsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncJobsResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response + """ + return AsyncJobsResourceWithStreamingResponse(self) + + @overload + async def create( + self, + bucket_name: str, + *, + account_id: str, + job_type: Literal["prefixDelete"], + prefix: str, + cf_r2_data_catalog_check: str | Omit = omit, + cf_r2_jurisdiction: Literal["default", "eu", "us", "fedramp", "fedramp-high"] | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> JobCreateResponse: + """Creates a background job for an R2 bucket. + + The `jobType` field selects the job: + + - **`prefixDelete`**: deletes every object whose key begins with `prefix`. A + non-empty prefix must end in `/`. An empty prefix (`""`) empties the entire + bucket. + - **`storageClassMigration`**: migrates every object in the bucket between + storage classes. `sourceStorageClass` and `destinationStorageClass` must be + provided together and must differ; omitting both migrates from + `InfrequentAccess` to `Standard`. + + Poll the returned `id` with the Get Bucket Job endpoint. Small prefix-delete + jobs can finish synchronously and return `COMPLETED`. Objects uploaded after a + background job starts are not affected by that job. + + For prefix-delete jobs: abort active multipart uploads before submitting the + request, since a synchronously completed job does not abort them, and avoid + writing objects or starting multipart uploads while a bucket-emptying job is in + progress. Each request creates a distinct job, and the number of active + prefix-delete jobs is limited per bucket; wait for an existing job to finish + before retrying a request rejected with HTTP 429. A bucket cannot be emptied + while event notifications are configured (HTTP 409 / error code 10083). To + protect a bucket with R2 Data Catalog enabled, send the + `cf-r2-data-catalog-check` header; a conflict is returned with HTTP 409 / error + code 10081. + + Prefix-delete jobs require permission to delete objects; storage-class migration + jobs require permission to write to the bucket. + + Args: + account_id: Cloudflare account ID that owns the R2 resource. + + bucket_name: Name of the bucket. + + prefix: Prefix matched against object keys. A non-empty value must end in `/`. An empty + string empties the entire bucket. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + ... + + @overload + async def create( + self, + bucket_name: str, + *, + account_id: str, + job_type: Literal["storageClassMigration"], + destination_storage_class: Literal["Standard", "InfrequentAccess"] | Omit = omit, + source_storage_class: Literal["Standard", "InfrequentAccess"] | Omit = omit, + cf_r2_data_catalog_check: str | Omit = omit, + cf_r2_jurisdiction: Literal["default", "eu", "us", "fedramp", "fedramp-high"] | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> JobCreateResponse: + """Creates a background job for an R2 bucket. + + The `jobType` field selects the job: + + - **`prefixDelete`**: deletes every object whose key begins with `prefix`. A + non-empty prefix must end in `/`. An empty prefix (`""`) empties the entire + bucket. + - **`storageClassMigration`**: migrates every object in the bucket between + storage classes. `sourceStorageClass` and `destinationStorageClass` must be + provided together and must differ; omitting both migrates from + `InfrequentAccess` to `Standard`. + + Poll the returned `id` with the Get Bucket Job endpoint. Small prefix-delete + jobs can finish synchronously and return `COMPLETED`. Objects uploaded after a + background job starts are not affected by that job. + + For prefix-delete jobs: abort active multipart uploads before submitting the + request, since a synchronously completed job does not abort them, and avoid + writing objects or starting multipart uploads while a bucket-emptying job is in + progress. Each request creates a distinct job, and the number of active + prefix-delete jobs is limited per bucket; wait for an existing job to finish + before retrying a request rejected with HTTP 429. A bucket cannot be emptied + while event notifications are configured (HTTP 409 / error code 10083). To + protect a bucket with R2 Data Catalog enabled, send the + `cf-r2-data-catalog-check` header; a conflict is returned with HTTP 409 / error + code 10081. + + Prefix-delete jobs require permission to delete objects; storage-class migration + jobs require permission to write to the bucket. + + Args: + account_id: Cloudflare account ID that owns the R2 resource. + + bucket_name: Name of the bucket. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + ... + + @required_args(["account_id", "job_type", "prefix"], ["account_id", "job_type"]) + async def create( + self, + bucket_name: str, + *, + account_id: str, + job_type: Literal["prefixDelete"] | Literal["storageClassMigration"], + prefix: str | Omit = omit, + cf_r2_data_catalog_check: str | Omit = omit, + cf_r2_jurisdiction: Literal["default", "eu", "us", "fedramp", "fedramp-high"] | Omit = omit, + destination_storage_class: Literal["Standard", "InfrequentAccess"] | Omit = omit, + source_storage_class: Literal["Standard", "InfrequentAccess"] | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> JobCreateResponse: + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not bucket_name: + raise ValueError(f"Expected a non-empty value for `bucket_name` but received {bucket_name!r}") + extra_headers = { + **strip_not_given( + { + "cf-r2-data-catalog-check": cf_r2_data_catalog_check, + "cf-r2-jurisdiction": str(cf_r2_jurisdiction) if is_given(cf_r2_jurisdiction) else not_given, + } + ), + **(extra_headers or {}), + } + return cast( + JobCreateResponse, + await self._post( + path_template( + "/accounts/{account_id}/r2/buckets/{bucket_name}/jobs", + account_id=account_id, + bucket_name=bucket_name, + ), + body=await async_maybe_transform( + { + "job_type": job_type, + "prefix": prefix, + "destination_storage_class": destination_storage_class, + "source_storage_class": source_storage_class, + }, + job_create_params.JobCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[JobCreateResponse]._unwrapper, + ), + cast_to=cast( + Any, ResultWrapper[JobCreateResponse] + ), # Union types cannot be passed in as arguments in the type system + ), + ) + + async def list( + self, + bucket_name: str, + *, + account_id: str, + continuation_token: str | Omit = omit, + job_type: Literal["prefixDelete", "storageClassMigration"] | Omit = omit, + max_keys: int | Omit = omit, + status: Literal["ENQUEUED", "RUNNING", "COMPLETED", "FAILED", "CANCELLED"] | Omit = omit, + cf_r2_jurisdiction: Literal["default", "eu", "us", "fedramp", "fedramp-high"] | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> JobListResponse: + """ + Lists background jobs for an R2 bucket, including prefix-delete (and + bucket-emptying) jobs and storage-class migration jobs. Jobs of every type are + returned unless `jobType` is provided. + + Args: + account_id: Cloudflare account ID that owns the R2 resource. + + bucket_name: Name of the bucket. + + continuation_token: Pagination token received as `nextContinuationToken` in the previous response. + + job_type: Restricts results to jobs of the specified type. + + max_keys: Maximum number of jobs to return. + + status: Restricts results to jobs with the specified status. `jobType` is required when + this parameter is provided. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not bucket_name: + raise ValueError(f"Expected a non-empty value for `bucket_name` but received {bucket_name!r}") + extra_headers = { + **strip_not_given( + {"cf-r2-jurisdiction": str(cf_r2_jurisdiction) if is_given(cf_r2_jurisdiction) else not_given} + ), + **(extra_headers or {}), + } + return await self._get( + path_template( + "/accounts/{account_id}/r2/buckets/{bucket_name}/jobs", account_id=account_id, bucket_name=bucket_name + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=await async_maybe_transform( + { + "continuation_token": continuation_token, + "job_type": job_type, + "max_keys": max_keys, + "status": status, + }, + job_list_params.JobListParams, + ), + post_parser=ResultWrapper[JobListResponse]._unwrapper, + ), + cast_to=cast(Type[JobListResponse], ResultWrapper[JobListResponse]), + ) + + async def get( + self, + job_id: str, + *, + account_id: str, + bucket_name: str, + cf_r2_jurisdiction: Literal["default", "eu", "us", "fedramp", "fedramp-high"] | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> JobGetResponse: + """Gets the current status of a background job of any type for an R2 bucket. + + Poll + this endpoint with the job identifier returned by Create Bucket Job until the + status is `COMPLETED`, `FAILED`, or `CANCELLED`. + + Args: + account_id: Cloudflare account ID that owns the R2 resource. + + bucket_name: Name of the bucket. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not bucket_name: + raise ValueError(f"Expected a non-empty value for `bucket_name` but received {bucket_name!r}") + if not job_id: + raise ValueError(f"Expected a non-empty value for `job_id` but received {job_id!r}") + extra_headers = { + **strip_not_given( + {"cf-r2-jurisdiction": str(cf_r2_jurisdiction) if is_given(cf_r2_jurisdiction) else not_given} + ), + **(extra_headers or {}), + } + return cast( + JobGetResponse, + await self._get( + path_template( + "/accounts/{account_id}/r2/buckets/{bucket_name}/jobs/{job_id}", + account_id=account_id, + bucket_name=bucket_name, + job_id=job_id, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[JobGetResponse]._unwrapper, + ), + cast_to=cast( + Any, ResultWrapper[JobGetResponse] + ), # Union types cannot be passed in as arguments in the type system + ), + ) + + +class JobsResourceWithRawResponse: + def __init__(self, jobs: JobsResource) -> None: + self._jobs = jobs + + self.create = to_raw_response_wrapper( + jobs.create, + ) + self.list = to_raw_response_wrapper( + jobs.list, + ) + self.get = to_raw_response_wrapper( + jobs.get, + ) + + +class AsyncJobsResourceWithRawResponse: + def __init__(self, jobs: AsyncJobsResource) -> None: + self._jobs = jobs + + self.create = async_to_raw_response_wrapper( + jobs.create, + ) + self.list = async_to_raw_response_wrapper( + jobs.list, + ) + self.get = async_to_raw_response_wrapper( + jobs.get, + ) + + +class JobsResourceWithStreamingResponse: + def __init__(self, jobs: JobsResource) -> None: + self._jobs = jobs + + self.create = to_streamed_response_wrapper( + jobs.create, + ) + self.list = to_streamed_response_wrapper( + jobs.list, + ) + self.get = to_streamed_response_wrapper( + jobs.get, + ) + + +class AsyncJobsResourceWithStreamingResponse: + def __init__(self, jobs: AsyncJobsResource) -> None: + self._jobs = jobs + + self.create = async_to_streamed_response_wrapper( + jobs.create, + ) + self.list = async_to_streamed_response_wrapper( + jobs.list, + ) + self.get = async_to_streamed_response_wrapper( + jobs.get, + ) diff --git a/src/cloudflare/resources/r2_data_catalog/api.md b/src/cloudflare/resources/r2_data_catalog/api.md index 1e281cf1a50..7c59452d5c3 100644 --- a/src/cloudflare/resources/r2_data_catalog/api.md +++ b/src/cloudflare/resources/r2_data_catalog/api.md @@ -15,7 +15,7 @@ Methods: - client.r2_data_catalog.list(\*, account_id) -> Optional[R2DataCatalogListResponse] - client.r2_data_catalog.delete(bucket_name, \*, account_id, \*\*params) -> None - client.r2_data_catalog.disable(bucket_name, \*, account_id) -> None -- client.r2_data_catalog.enable(bucket_name, \*, account_id) -> Optional[R2DataCatalogEnableResponse] +- client.r2_data_catalog.enable(bucket_name, \*, account_id, \*\*params) -> Optional[R2DataCatalogEnableResponse] - client.r2_data_catalog.get(bucket_name, \*, account_id) -> Optional[R2DataCatalogGetResponse] ## MaintenanceConfigs diff --git a/src/cloudflare/resources/r2_data_catalog/r2_data_catalog.py b/src/cloudflare/resources/r2_data_catalog/r2_data_catalog.py index 4006a8a5d4b..81ed97917c8 100644 --- a/src/cloudflare/resources/r2_data_catalog/r2_data_catalog.py +++ b/src/cloudflare/resources/r2_data_catalog/r2_data_catalog.py @@ -43,7 +43,7 @@ NamespacesResourceWithStreamingResponse, AsyncNamespacesResourceWithStreamingResponse, ) -from ...types.r2_data_catalog import r2_data_catalog_delete_params +from ...types.r2_data_catalog import r2_data_catalog_delete_params, r2_data_catalog_enable_params from ...types.r2_data_catalog.r2_data_catalog_get_response import R2DataCatalogGetResponse from ...types.r2_data_catalog.r2_data_catalog_list_response import R2DataCatalogListResponse from ...types.r2_data_catalog.r2_data_catalog_enable_response import R2DataCatalogEnableResponse @@ -232,6 +232,7 @@ def enable( bucket_name: str, *, account_id: str, + credential: r2_data_catalog_enable_params.Credential | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -250,6 +251,8 @@ def enable( bucket_name: Specifies the R2 bucket name. + credential: Contains request to store catalog credentials. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -266,6 +269,7 @@ def enable( path_template( "/accounts/{account_id}/r2-catalog/{bucket_name}/enable", account_id=account_id, bucket_name=bucket_name ), + body=maybe_transform({"credential": credential}, r2_data_catalog_enable_params.R2DataCatalogEnableParams), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, @@ -508,6 +512,7 @@ async def enable( bucket_name: str, *, account_id: str, + credential: r2_data_catalog_enable_params.Credential | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -526,6 +531,8 @@ async def enable( bucket_name: Specifies the R2 bucket name. + credential: Contains request to store catalog credentials. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -542,6 +549,9 @@ async def enable( path_template( "/accounts/{account_id}/r2-catalog/{bucket_name}/enable", account_id=account_id, bucket_name=bucket_name ), + body=await async_maybe_transform( + {"credential": credential}, r2_data_catalog_enable_params.R2DataCatalogEnableParams + ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, diff --git a/src/cloudflare/resources/realtime_kit/api.md b/src/cloudflare/resources/realtime_kit/api.md index ee1ae5b49bf..746c1c83875 100644 --- a/src/cloudflare/resources/realtime_kit/api.md +++ b/src/cloudflare/resources/realtime_kit/api.md @@ -43,7 +43,7 @@ Methods: - client.realtime_kit.meetings.get_meeting_by_id(meeting_id, \*, account_id, app_id, \*\*params) -> MeetingGetMeetingByIDResponse - client.realtime_kit.meetings.get_meeting_participant(participant_id, \*, account_id, app_id, meeting_id) -> MeetingGetMeetingParticipantResponse - client.realtime_kit.meetings.get_meeting_participants(meeting_id, \*, account_id, app_id, \*\*params) -> MeetingGetMeetingParticipantsResponse -- client.realtime_kit.meetings.refresh_participant_token(participant_id, \*, account_id, app_id, meeting_id) -> MeetingRefreshParticipantTokenResponse +- client.realtime_kit.meetings.refresh_participant_token(participant_id, \*, account_id, app_id, meeting_id, \*\*params) -> MeetingRefreshParticipantTokenResponse - client.realtime_kit.meetings.replace_meeting_by_id(meeting_id, \*, account_id, app_id, \*\*params) -> MeetingReplaceMeetingByIDResponse - client.realtime_kit.meetings.update_meeting_by_id(meeting_id, \*, account_id, app_id, \*\*params) -> MeetingUpdateMeetingByIDResponse diff --git a/src/cloudflare/resources/realtime_kit/meetings.py b/src/cloudflare/resources/realtime_kit/meetings.py index 738a15822e2..c9cd1ded936 100644 --- a/src/cloudflare/resources/realtime_kit/meetings.py +++ b/src/cloudflare/resources/realtime_kit/meetings.py @@ -28,6 +28,7 @@ meeting_update_meeting_by_id_params, meeting_replace_meeting_by_id_params, meeting_get_meeting_participants_params, + meeting_refresh_participant_token_params, ) from ...types.realtime_kit.meeting_get_response import MeetingGetResponse from ...types.realtime_kit.meeting_create_response import MeetingCreateResponse @@ -162,6 +163,7 @@ def add_participant( app_id: str, custom_participant_id: str, preset_name: str, + token: meeting_add_participant_params.Token | Omit = omit, name: Optional[str] | Omit = omit, picture: Optional[str] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -184,6 +186,10 @@ def add_participant( preset_name: Name of the preset to apply to this participant. + token: Validity window of the participant authentication token. The window is + [not_before, expires_on) and cannot be longer than 100 days. Defaults to a token + valid from now for 100 days. + name: (Optional) Name of the participant. picture: (Optional) A URL to a picture to be used for the participant. @@ -213,6 +219,7 @@ def add_participant( { "custom_participant_id": custom_participant_id, "preset_name": preset_name, + "token": token, "name": name, "picture": picture, }, @@ -597,6 +604,8 @@ def refresh_participant_token( account_id: str, app_id: str, meeting_id: str, + expires_on: Union[str, datetime] | Omit = omit, + not_before: Union[str, datetime] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -613,6 +622,12 @@ def refresh_participant_token( app_id: The app identifier tag. + expires_on: RFC 3339 timestamp with a timezone at or after which the token cannot be used. + Must be in the future. Defaults to not_before plus 100 days. + + not_before: RFC 3339 timestamp with a timezone before which the token cannot be used. + Defaults to the current time. May be in the past. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -637,6 +652,13 @@ def refresh_participant_token( meeting_id=meeting_id, participant_id=participant_id, ), + body=maybe_transform( + { + "expires_on": expires_on, + "not_before": not_before, + }, + meeting_refresh_participant_token_params.MeetingRefreshParticipantTokenParams, + ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -959,6 +981,7 @@ async def add_participant( app_id: str, custom_participant_id: str, preset_name: str, + token: meeting_add_participant_params.Token | Omit = omit, name: Optional[str] | Omit = omit, picture: Optional[str] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -981,6 +1004,10 @@ async def add_participant( preset_name: Name of the preset to apply to this participant. + token: Validity window of the participant authentication token. The window is + [not_before, expires_on) and cannot be longer than 100 days. Defaults to a token + valid from now for 100 days. + name: (Optional) Name of the participant. picture: (Optional) A URL to a picture to be used for the participant. @@ -1010,6 +1037,7 @@ async def add_participant( { "custom_participant_id": custom_participant_id, "preset_name": preset_name, + "token": token, "name": name, "picture": picture, }, @@ -1396,6 +1424,8 @@ async def refresh_participant_token( account_id: str, app_id: str, meeting_id: str, + expires_on: Union[str, datetime] | Omit = omit, + not_before: Union[str, datetime] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -1412,6 +1442,12 @@ async def refresh_participant_token( app_id: The app identifier tag. + expires_on: RFC 3339 timestamp with a timezone at or after which the token cannot be used. + Must be in the future. Defaults to not_before plus 100 days. + + not_before: RFC 3339 timestamp with a timezone before which the token cannot be used. + Defaults to the current time. May be in the past. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -1436,6 +1472,13 @@ async def refresh_participant_token( meeting_id=meeting_id, participant_id=participant_id, ), + body=await async_maybe_transform( + { + "expires_on": expires_on, + "not_before": not_before, + }, + meeting_refresh_participant_token_params.MeetingRefreshParticipantTokenParams, + ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), diff --git a/src/cloudflare/resources/registrar/__init__.py b/src/cloudflare/resources/registrar/__init__.py index 3be6b78b280..b25c9cab40b 100644 --- a/src/cloudflare/resources/registrar/__init__.py +++ b/src/cloudflare/resources/registrar/__init__.py @@ -1,13 +1,5 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from .domains import ( - DomainsResource, - AsyncDomainsResource, - DomainsResourceWithRawResponse, - AsyncDomainsResourceWithRawResponse, - DomainsResourceWithStreamingResponse, - AsyncDomainsResourceWithStreamingResponse, -) from .registrar import ( RegistrarResource, AsyncRegistrarResource, @@ -66,12 +58,6 @@ ) __all__ = [ - "DomainsResource", - "AsyncDomainsResource", - "DomainsResourceWithRawResponse", - "AsyncDomainsResourceWithRawResponse", - "DomainsResourceWithStreamingResponse", - "AsyncDomainsResourceWithStreamingResponse", "RegistrationsResource", "AsyncRegistrationsResource", "RegistrationsResourceWithRawResponse", diff --git a/src/cloudflare/resources/registrar/api.md b/src/cloudflare/resources/registrar/api.md index c05900822a6..7e9e48ea03a 100644 --- a/src/cloudflare/resources/registrar/api.md +++ b/src/cloudflare/resources/registrar/api.md @@ -18,20 +18,6 @@ Methods: - client.registrar.search(\*, account_id, \*\*params) -> RegistrarSearchResponse - client.registrar.transfer_check(\*, account_id, \*\*params) -> RegistrarTransferCheckResponse -## Domains - -Types: - -```python -from cloudflare.types.registrar import Domain -``` - -Methods: - -- client.registrar.domains.update(domain_name, \*, account_id, \*\*params) -> object -- client.registrar.domains.list(\*, account_id) -> SyncSinglePage[Domain] -- client.registrar.domains.get(domain_name, \*, account_id) -> object - ## Registrations Methods: diff --git a/src/cloudflare/resources/registrar/domains.py b/src/cloudflare/resources/registrar/domains.py deleted file mode 100644 index b0acc662947..00000000000 --- a/src/cloudflare/resources/registrar/domains.py +++ /dev/null @@ -1,474 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -import typing_extensions -from typing import Type, Optional, cast - -import httpx - -from ..._types import Body, Omit, Query, Headers, NotGiven, omit, not_given -from ..._utils import path_template, maybe_transform, async_maybe_transform -from ..._compat import cached_property -from ..._resource import SyncAPIResource, AsyncAPIResource -from ..._response import ( - to_raw_response_wrapper, - to_streamed_response_wrapper, - async_to_raw_response_wrapper, - async_to_streamed_response_wrapper, -) -from ..._wrappers import ResultWrapper -from ...pagination import SyncSinglePage, AsyncSinglePage -from ..._base_client import AsyncPaginator, make_request_options -from ...types.registrar import domain_update_params -from ...types.registrar.domain import Domain - -__all__ = ["DomainsResource", "AsyncDomainsResource"] - - -class DomainsResource(SyncAPIResource): - @cached_property - def with_raw_response(self) -> DomainsResourceWithRawResponse: - """ - This property can be used as a prefix for any HTTP method call to return - the raw response object instead of the parsed content. - - For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers - """ - return DomainsResourceWithRawResponse(self) - - @cached_property - def with_streaming_response(self) -> DomainsResourceWithStreamingResponse: - """ - An alternative to `.with_raw_response` that doesn't eagerly read the response body. - - For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response - """ - return DomainsResourceWithStreamingResponse(self) - - @typing_extensions.deprecated( - "This operation is deprecated and will reach end of life on September 27, 2026. Use the new Registrar API endpoints (domain-search, domain-check, registrations) instead. Refer to https://developers.cloudflare.com/fundamentals/api/reference/deprecations/ for details." - ) - def update( - self, - domain_name: str, - *, - account_id: str, - auto_renew: bool | Omit = omit, - locked: bool | Omit = omit, - privacy: bool | Omit = omit, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> object: - """ - Updates an individual domain. - - Args: - account_id: Identifier. - - domain_name: Provides a fully qualified domain name (FQDN), including the extension (e.g., - `example.com`, `mybrand.app`). The domain name uniquely identifies a - registration. Cloudflare permits only one registration per domain, making the - domain name a natural idempotency key for registration requests. - - auto_renew: Auto-renew controls whether subscription is automatically renewed upon domain - expiration. - - locked: Shows whether a registrar lock is in place for a domain. - - privacy: Privacy option controls redacting WHOIS information. - - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not account_id: - raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not domain_name: - raise ValueError(f"Expected a non-empty value for `domain_name` but received {domain_name!r}") - return self._put( - path_template( - "/accounts/{account_id}/registrar/domains/{domain_name}", account_id=account_id, domain_name=domain_name - ), - body=maybe_transform( - { - "auto_renew": auto_renew, - "locked": locked, - "privacy": privacy, - }, - domain_update_params.DomainUpdateParams, - ), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - post_parser=ResultWrapper[Optional[object]]._unwrapper, - ), - cast_to=cast(Type[object], ResultWrapper[object]), - ) - - @typing_extensions.deprecated( - "This operation is deprecated and will reach end of life on September 27, 2026. Use the new Registrar API endpoints (domain-search, domain-check, registrations) instead. Refer to https://developers.cloudflare.com/fundamentals/api/reference/deprecations/ for details." - ) - def list( - self, - *, - account_id: str, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> SyncSinglePage[Domain]: - """ - Lists domains handled by Registrar. - - Args: - account_id: Identifier. - - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not account_id: - raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - return self._get_api_list( - path_template("/accounts/{account_id}/registrar/domains", account_id=account_id), - page=SyncSinglePage[Domain], - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - model=Domain, - ) - - @typing_extensions.deprecated( - "This operation is deprecated and will reach end of life on September 27, 2026. Use the new Registrar API endpoints (domain-search, domain-check, registrations) instead. Refer to https://developers.cloudflare.com/fundamentals/api/reference/deprecations/ for details." - ) - def get( - self, - domain_name: str, - *, - account_id: str, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> object: - """ - Show individual domain. - - Args: - account_id: Identifier. - - domain_name: Provides a fully qualified domain name (FQDN), including the extension (e.g., - `example.com`, `mybrand.app`). The domain name uniquely identifies a - registration. Cloudflare permits only one registration per domain, making the - domain name a natural idempotency key for registration requests. - - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not account_id: - raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not domain_name: - raise ValueError(f"Expected a non-empty value for `domain_name` but received {domain_name!r}") - return self._get( - path_template( - "/accounts/{account_id}/registrar/domains/{domain_name}", account_id=account_id, domain_name=domain_name - ), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - post_parser=ResultWrapper[Optional[object]]._unwrapper, - ), - cast_to=cast(Type[object], ResultWrapper[object]), - ) - - -class AsyncDomainsResource(AsyncAPIResource): - @cached_property - def with_raw_response(self) -> AsyncDomainsResourceWithRawResponse: - """ - This property can be used as a prefix for any HTTP method call to return - the raw response object instead of the parsed content. - - For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers - """ - return AsyncDomainsResourceWithRawResponse(self) - - @cached_property - def with_streaming_response(self) -> AsyncDomainsResourceWithStreamingResponse: - """ - An alternative to `.with_raw_response` that doesn't eagerly read the response body. - - For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response - """ - return AsyncDomainsResourceWithStreamingResponse(self) - - @typing_extensions.deprecated( - "This operation is deprecated and will reach end of life on September 27, 2026. Use the new Registrar API endpoints (domain-search, domain-check, registrations) instead. Refer to https://developers.cloudflare.com/fundamentals/api/reference/deprecations/ for details." - ) - async def update( - self, - domain_name: str, - *, - account_id: str, - auto_renew: bool | Omit = omit, - locked: bool | Omit = omit, - privacy: bool | Omit = omit, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> object: - """ - Updates an individual domain. - - Args: - account_id: Identifier. - - domain_name: Provides a fully qualified domain name (FQDN), including the extension (e.g., - `example.com`, `mybrand.app`). The domain name uniquely identifies a - registration. Cloudflare permits only one registration per domain, making the - domain name a natural idempotency key for registration requests. - - auto_renew: Auto-renew controls whether subscription is automatically renewed upon domain - expiration. - - locked: Shows whether a registrar lock is in place for a domain. - - privacy: Privacy option controls redacting WHOIS information. - - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not account_id: - raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not domain_name: - raise ValueError(f"Expected a non-empty value for `domain_name` but received {domain_name!r}") - return await self._put( - path_template( - "/accounts/{account_id}/registrar/domains/{domain_name}", account_id=account_id, domain_name=domain_name - ), - body=await async_maybe_transform( - { - "auto_renew": auto_renew, - "locked": locked, - "privacy": privacy, - }, - domain_update_params.DomainUpdateParams, - ), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - post_parser=ResultWrapper[Optional[object]]._unwrapper, - ), - cast_to=cast(Type[object], ResultWrapper[object]), - ) - - @typing_extensions.deprecated( - "This operation is deprecated and will reach end of life on September 27, 2026. Use the new Registrar API endpoints (domain-search, domain-check, registrations) instead. Refer to https://developers.cloudflare.com/fundamentals/api/reference/deprecations/ for details." - ) - def list( - self, - *, - account_id: str, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> AsyncPaginator[Domain, AsyncSinglePage[Domain]]: - """ - Lists domains handled by Registrar. - - Args: - account_id: Identifier. - - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not account_id: - raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - return self._get_api_list( - path_template("/accounts/{account_id}/registrar/domains", account_id=account_id), - page=AsyncSinglePage[Domain], - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - model=Domain, - ) - - @typing_extensions.deprecated( - "This operation is deprecated and will reach end of life on September 27, 2026. Use the new Registrar API endpoints (domain-search, domain-check, registrations) instead. Refer to https://developers.cloudflare.com/fundamentals/api/reference/deprecations/ for details." - ) - async def get( - self, - domain_name: str, - *, - account_id: str, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> object: - """ - Show individual domain. - - Args: - account_id: Identifier. - - domain_name: Provides a fully qualified domain name (FQDN), including the extension (e.g., - `example.com`, `mybrand.app`). The domain name uniquely identifies a - registration. Cloudflare permits only one registration per domain, making the - domain name a natural idempotency key for registration requests. - - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not account_id: - raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") - if not domain_name: - raise ValueError(f"Expected a non-empty value for `domain_name` but received {domain_name!r}") - return await self._get( - path_template( - "/accounts/{account_id}/registrar/domains/{domain_name}", account_id=account_id, domain_name=domain_name - ), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - post_parser=ResultWrapper[Optional[object]]._unwrapper, - ), - cast_to=cast(Type[object], ResultWrapper[object]), - ) - - -class DomainsResourceWithRawResponse: - def __init__(self, domains: DomainsResource) -> None: - self._domains = domains - - self.update = ( # pyright: ignore[reportDeprecated] - to_raw_response_wrapper( - domains.update, # pyright: ignore[reportDeprecated], - ) - ) - self.list = ( # pyright: ignore[reportDeprecated] - to_raw_response_wrapper( - domains.list, # pyright: ignore[reportDeprecated], - ) - ) - self.get = ( # pyright: ignore[reportDeprecated] - to_raw_response_wrapper( - domains.get, # pyright: ignore[reportDeprecated], - ) - ) - - -class AsyncDomainsResourceWithRawResponse: - def __init__(self, domains: AsyncDomainsResource) -> None: - self._domains = domains - - self.update = ( # pyright: ignore[reportDeprecated] - async_to_raw_response_wrapper( - domains.update, # pyright: ignore[reportDeprecated], - ) - ) - self.list = ( # pyright: ignore[reportDeprecated] - async_to_raw_response_wrapper( - domains.list, # pyright: ignore[reportDeprecated], - ) - ) - self.get = ( # pyright: ignore[reportDeprecated] - async_to_raw_response_wrapper( - domains.get, # pyright: ignore[reportDeprecated], - ) - ) - - -class DomainsResourceWithStreamingResponse: - def __init__(self, domains: DomainsResource) -> None: - self._domains = domains - - self.update = ( # pyright: ignore[reportDeprecated] - to_streamed_response_wrapper( - domains.update, # pyright: ignore[reportDeprecated], - ) - ) - self.list = ( # pyright: ignore[reportDeprecated] - to_streamed_response_wrapper( - domains.list, # pyright: ignore[reportDeprecated], - ) - ) - self.get = ( # pyright: ignore[reportDeprecated] - to_streamed_response_wrapper( - domains.get, # pyright: ignore[reportDeprecated], - ) - ) - - -class AsyncDomainsResourceWithStreamingResponse: - def __init__(self, domains: AsyncDomainsResource) -> None: - self._domains = domains - - self.update = ( # pyright: ignore[reportDeprecated] - async_to_streamed_response_wrapper( - domains.update, # pyright: ignore[reportDeprecated], - ) - ) - self.list = ( # pyright: ignore[reportDeprecated] - async_to_streamed_response_wrapper( - domains.list, # pyright: ignore[reportDeprecated], - ) - ) - self.get = ( # pyright: ignore[reportDeprecated] - async_to_streamed_response_wrapper( - domains.get, # pyright: ignore[reportDeprecated], - ) - ) diff --git a/src/cloudflare/resources/registrar/registrar.py b/src/cloudflare/resources/registrar/registrar.py index efe96bc7d76..dceff7fcf3b 100644 --- a/src/cloudflare/resources/registrar/registrar.py +++ b/src/cloudflare/resources/registrar/registrar.py @@ -6,14 +6,6 @@ import httpx -from .domains import ( - DomainsResource, - AsyncDomainsResource, - DomainsResourceWithRawResponse, - AsyncDomainsResourceWithRawResponse, - DomainsResourceWithStreamingResponse, - AsyncDomainsResourceWithStreamingResponse, -) from ..._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given from ..._utils import path_template, maybe_transform, async_maybe_transform from ..._compat import cached_property @@ -178,10 +170,6 @@ class RegistrarResource(SyncAPIResource): state or requires user action. """ - @cached_property - def domains(self) -> DomainsResource: - return DomainsResource(self._client) - @cached_property def registrations(self) -> RegistrationsResource: return RegistrationsResource(self._client) @@ -585,10 +573,6 @@ class AsyncRegistrarResource(AsyncAPIResource): state or requires user action. """ - @cached_property - def domains(self) -> AsyncDomainsResource: - return AsyncDomainsResource(self._client) - @cached_property def registrations(self) -> AsyncRegistrationsResource: return AsyncRegistrationsResource(self._client) @@ -912,10 +896,6 @@ def __init__(self, registrar: RegistrarResource) -> None: registrar.transfer_check, ) - @cached_property - def domains(self) -> DomainsResourceWithRawResponse: - return DomainsResourceWithRawResponse(self._registrar.domains) - @cached_property def registrations(self) -> RegistrationsResourceWithRawResponse: return RegistrationsResourceWithRawResponse(self._registrar.registrations) @@ -955,10 +935,6 @@ def __init__(self, registrar: AsyncRegistrarResource) -> None: registrar.transfer_check, ) - @cached_property - def domains(self) -> AsyncDomainsResourceWithRawResponse: - return AsyncDomainsResourceWithRawResponse(self._registrar.domains) - @cached_property def registrations(self) -> AsyncRegistrationsResourceWithRawResponse: return AsyncRegistrationsResourceWithRawResponse(self._registrar.registrations) @@ -998,10 +974,6 @@ def __init__(self, registrar: RegistrarResource) -> None: registrar.transfer_check, ) - @cached_property - def domains(self) -> DomainsResourceWithStreamingResponse: - return DomainsResourceWithStreamingResponse(self._registrar.domains) - @cached_property def registrations(self) -> RegistrationsResourceWithStreamingResponse: return RegistrationsResourceWithStreamingResponse(self._registrar.registrations) @@ -1041,10 +1013,6 @@ def __init__(self, registrar: AsyncRegistrarResource) -> None: registrar.transfer_check, ) - @cached_property - def domains(self) -> AsyncDomainsResourceWithStreamingResponse: - return AsyncDomainsResourceWithStreamingResponse(self._registrar.domains) - @cached_property def registrations(self) -> AsyncRegistrationsResourceWithStreamingResponse: return AsyncRegistrationsResourceWithStreamingResponse(self._registrar.registrations) diff --git a/src/cloudflare/resources/resource_sharing/recipients.py b/src/cloudflare/resources/resource_sharing/recipients.py index adf0a3598bd..c4dd95ace79 100644 --- a/src/cloudflare/resources/resource_sharing/recipients.py +++ b/src/cloudflare/resources/resource_sharing/recipients.py @@ -54,7 +54,6 @@ def create( *, path_account_id: str, body_account_id: str | Omit = omit, - organization_id: str | Omit = omit, recipient_account_id: str | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. @@ -82,8 +81,6 @@ def create( from the recipient account (in the body). Both names will continue to be accepted until 2027-05-26 (see `x-sunset`). - organization_id: Organization identifier. - recipient_account_id: The account that will receive the share. extra_headers: Send extra headers @@ -107,7 +104,6 @@ def create( body=maybe_transform( { "body_account_id": body_account_id, - "organization_id": organization_id, "recipient_account_id": recipient_account_id, }, recipient_create_params.RecipientCreateParams, @@ -151,12 +147,9 @@ def list( include_resources: Include resources in the response. - page: Page number. Defaults to `1` when `per_page` is supplied without `page`. May be - omitted entirely along with `per_page` to receive a non-paginated response. + page: Page number. Defaults to `1` when omitted. - per_page: Number of objects to return per page. Defaults to `20` when `page` is supplied - without `per_page`. May be omitted entirely along with `page` to receive a - non-paginated response. + per_page: Number of objects to return per page. Defaults to `20` when omitted. extra_headers: Send extra headers @@ -342,7 +335,6 @@ async def create( *, path_account_id: str, body_account_id: str | Omit = omit, - organization_id: str | Omit = omit, recipient_account_id: str | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. @@ -370,8 +362,6 @@ async def create( from the recipient account (in the body). Both names will continue to be accepted until 2027-05-26 (see `x-sunset`). - organization_id: Organization identifier. - recipient_account_id: The account that will receive the share. extra_headers: Send extra headers @@ -395,7 +385,6 @@ async def create( body=await async_maybe_transform( { "body_account_id": body_account_id, - "organization_id": organization_id, "recipient_account_id": recipient_account_id, }, recipient_create_params.RecipientCreateParams, @@ -439,12 +428,9 @@ def list( include_resources: Include resources in the response. - page: Page number. Defaults to `1` when `per_page` is supplied without `page`. May be - omitted entirely along with `per_page` to receive a non-paginated response. + page: Page number. Defaults to `1` when omitted. - per_page: Number of objects to return per page. Defaults to `20` when `page` is supplied - without `per_page`. May be omitted entirely along with `page` to receive a - non-paginated response. + per_page: Number of objects to return per page. Defaults to `20` when omitted. extra_headers: Send extra headers diff --git a/src/cloudflare/resources/resource_sharing/resource_sharing.py b/src/cloudflare/resources/resource_sharing/resource_sharing.py index 91e45ee1405..ae87bc48ada 100644 --- a/src/cloudflare/resources/resource_sharing/resource_sharing.py +++ b/src/cloudflare/resources/resource_sharing/resource_sharing.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing import List, Type, Iterable, Optional, cast +from typing import Dict, List, Type, Iterable, Optional, cast from typing_extensions import Literal import httpx @@ -84,8 +84,10 @@ def create( *, account_id: str, name: str, - recipients: Iterable[resource_sharing_create_params.Recipient], - resources: Iterable[resource_sharing_create_params.Resource], + excluded_recipients: Iterable[resource_sharing_create_params.ExcludedRecipient] | Omit = omit, + recipients: Iterable[resource_sharing_create_params.Recipient] | Omit = omit, + resources: Iterable[resource_sharing_create_params.Resource] | Omit = omit, + tags: Dict[str, str] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -94,14 +96,20 @@ def create( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Optional[ResourceSharingCreateResponse]: """ - Creates a new resource share for sharing Cloudflare resources with other - accounts or organizations. + Creates a share that makes a resource available to specific accounts in the + caller's organization, or to the whole organization. Args: account_id: Account identifier. name: The name of the share. + excluded_recipients: Accounts to exclude from an organization-targeted share. Only allowed when + `recipients` contains no account entries. The share owner cannot be excluded. + Duplicate entries are ignored. + + tags: Tags associated with the share. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -117,8 +125,10 @@ def create( body=maybe_transform( { "name": name, + "excluded_recipients": excluded_recipients, "recipients": recipients, "resources": resources, + "tags": tags, }, resource_sharing_create_params.ResourceSharingCreateParams, ), @@ -138,6 +148,7 @@ def update( *, account_id: str, name: str, + tags: Dict[str, str] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -147,19 +158,9 @@ def update( ) -> Optional[ResourceSharingUpdateResponse]: """Updates the share's display name and tags. - This endpoint does **not** modify - recipients or resources — those are managed via dedicated subresource endpoints: - - - **Recipients**: Use `POST /accounts/{account_id}/shares/{share_id}/recipients` - to add a single recipient, - `PUT /accounts/{account_id}/shares/{share_id}/recipients` to replace the full - recipient list, or - `DELETE /accounts/{account_id}/shares/{share_id}/recipients/{recipient_id}` to - remove a recipient. - - **Resources**: Use the share's resource subresource endpoints. - - Updating is not immediate; an updated share object with a new status will be - returned. + Omitting `tags` leaves the existing + tags unchanged. Recipients and resources are managed via their subresource + endpoints. Args: account_id: Account identifier. @@ -168,6 +169,8 @@ def update( name: The name of the share. + tags: Tags associated with the share. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -182,7 +185,13 @@ def update( raise ValueError(f"Expected a non-empty value for `share_id` but received {share_id!r}") return self._put( path_template("/accounts/{account_id}/shares/{share_id}", account_id=account_id, share_id=share_id), - body=maybe_transform({"name": name}, resource_sharing_update_params.ResourceSharingUpdateParams), + body=maybe_transform( + { + "name": name, + "tags": tags, + }, + resource_sharing_update_params.ResourceSharingUpdateParams, + ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, @@ -200,6 +209,7 @@ def list( direction: Literal["asc", "desc"] | Omit = omit, include_recipient_counts: bool | Omit = omit, include_resources: bool | Omit = omit, + include_tags_from: Literal["api", "mirror"] | Omit = omit, kind: Literal["sent", "received"] | Omit = omit, order: Literal["name", "created"] | Omit = omit, page: int | Omit = omit, @@ -238,16 +248,17 @@ def list( include_resources: Include resources in the response. + include_tags_from: Include share tags in the response. `api` reads tags from the tag service; + `mirror` reads a local, eventually consistent replica. If the tag lookup fails, + the response omits `tags`. + kind: Filter shares by kind. order: Order shares by values in the given field. - page: Page number. Defaults to `1` when `per_page` is supplied without `page`. May be - omitted entirely along with `per_page` to receive a non-paginated response. + page: Page number. Defaults to `1` when omitted. - per_page: Number of objects to return per page. Defaults to `20` when `page` is supplied - without `per_page`. May be omitted entirely along with `page` to receive a - non-paginated response. + per_page: Number of objects to return per page. Defaults to `20` when omitted. resource_types: Filter share resources by resource_types. @@ -283,6 +294,7 @@ def list( "direction": direction, "include_recipient_counts": include_recipient_counts, "include_resources": include_resources, + "include_tags_from": include_tags_from, "kind": kind, "order": order, "page": page, @@ -350,6 +362,7 @@ def get( account_id: str, include_recipient_counts: bool | Omit = omit, include_resources: bool | Omit = omit, + include_tags_from: Literal["api", "mirror"] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -369,6 +382,10 @@ def get( include_resources: Include resources in the response. + include_tags_from: Include share tags in the response. `api` reads tags from the tag service; + `mirror` reads a local, eventually consistent replica. If the tag lookup fails, + the response omits `tags`. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -392,6 +409,7 @@ def get( { "include_recipient_counts": include_recipient_counts, "include_resources": include_resources, + "include_tags_from": include_tags_from, }, resource_sharing_get_params.ResourceSharingGetParams, ), @@ -434,8 +452,10 @@ async def create( *, account_id: str, name: str, - recipients: Iterable[resource_sharing_create_params.Recipient], - resources: Iterable[resource_sharing_create_params.Resource], + excluded_recipients: Iterable[resource_sharing_create_params.ExcludedRecipient] | Omit = omit, + recipients: Iterable[resource_sharing_create_params.Recipient] | Omit = omit, + resources: Iterable[resource_sharing_create_params.Resource] | Omit = omit, + tags: Dict[str, str] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -444,14 +464,20 @@ async def create( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Optional[ResourceSharingCreateResponse]: """ - Creates a new resource share for sharing Cloudflare resources with other - accounts or organizations. + Creates a share that makes a resource available to specific accounts in the + caller's organization, or to the whole organization. Args: account_id: Account identifier. name: The name of the share. + excluded_recipients: Accounts to exclude from an organization-targeted share. Only allowed when + `recipients` contains no account entries. The share owner cannot be excluded. + Duplicate entries are ignored. + + tags: Tags associated with the share. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -467,8 +493,10 @@ async def create( body=await async_maybe_transform( { "name": name, + "excluded_recipients": excluded_recipients, "recipients": recipients, "resources": resources, + "tags": tags, }, resource_sharing_create_params.ResourceSharingCreateParams, ), @@ -488,6 +516,7 @@ async def update( *, account_id: str, name: str, + tags: Dict[str, str] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -497,19 +526,9 @@ async def update( ) -> Optional[ResourceSharingUpdateResponse]: """Updates the share's display name and tags. - This endpoint does **not** modify - recipients or resources — those are managed via dedicated subresource endpoints: - - - **Recipients**: Use `POST /accounts/{account_id}/shares/{share_id}/recipients` - to add a single recipient, - `PUT /accounts/{account_id}/shares/{share_id}/recipients` to replace the full - recipient list, or - `DELETE /accounts/{account_id}/shares/{share_id}/recipients/{recipient_id}` to - remove a recipient. - - **Resources**: Use the share's resource subresource endpoints. - - Updating is not immediate; an updated share object with a new status will be - returned. + Omitting `tags` leaves the existing + tags unchanged. Recipients and resources are managed via their subresource + endpoints. Args: account_id: Account identifier. @@ -518,6 +537,8 @@ async def update( name: The name of the share. + tags: Tags associated with the share. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -533,7 +554,11 @@ async def update( return await self._put( path_template("/accounts/{account_id}/shares/{share_id}", account_id=account_id, share_id=share_id), body=await async_maybe_transform( - {"name": name}, resource_sharing_update_params.ResourceSharingUpdateParams + { + "name": name, + "tags": tags, + }, + resource_sharing_update_params.ResourceSharingUpdateParams, ), options=make_request_options( extra_headers=extra_headers, @@ -552,6 +577,7 @@ def list( direction: Literal["asc", "desc"] | Omit = omit, include_recipient_counts: bool | Omit = omit, include_resources: bool | Omit = omit, + include_tags_from: Literal["api", "mirror"] | Omit = omit, kind: Literal["sent", "received"] | Omit = omit, order: Literal["name", "created"] | Omit = omit, page: int | Omit = omit, @@ -590,16 +616,17 @@ def list( include_resources: Include resources in the response. + include_tags_from: Include share tags in the response. `api` reads tags from the tag service; + `mirror` reads a local, eventually consistent replica. If the tag lookup fails, + the response omits `tags`. + kind: Filter shares by kind. order: Order shares by values in the given field. - page: Page number. Defaults to `1` when `per_page` is supplied without `page`. May be - omitted entirely along with `per_page` to receive a non-paginated response. + page: Page number. Defaults to `1` when omitted. - per_page: Number of objects to return per page. Defaults to `20` when `page` is supplied - without `per_page`. May be omitted entirely along with `page` to receive a - non-paginated response. + per_page: Number of objects to return per page. Defaults to `20` when omitted. resource_types: Filter share resources by resource_types. @@ -635,6 +662,7 @@ def list( "direction": direction, "include_recipient_counts": include_recipient_counts, "include_resources": include_resources, + "include_tags_from": include_tags_from, "kind": kind, "order": order, "page": page, @@ -702,6 +730,7 @@ async def get( account_id: str, include_recipient_counts: bool | Omit = omit, include_resources: bool | Omit = omit, + include_tags_from: Literal["api", "mirror"] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -721,6 +750,10 @@ async def get( include_resources: Include resources in the response. + include_tags_from: Include share tags in the response. `api` reads tags from the tag service; + `mirror` reads a local, eventually consistent replica. If the tag lookup fails, + the response omits `tags`. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -744,6 +777,7 @@ async def get( { "include_recipient_counts": include_recipient_counts, "include_resources": include_resources, + "include_tags_from": include_tags_from, }, resource_sharing_get_params.ResourceSharingGetParams, ), diff --git a/src/cloudflare/resources/resource_sharing/resources.py b/src/cloudflare/resources/resource_sharing/resources.py index a68127e9f32..286f3012431 100644 --- a/src/cloudflare/resources/resource_sharing/resources.py +++ b/src/cloudflare/resources/resource_sharing/resources.py @@ -84,9 +84,9 @@ def create( meta: Resource Metadata. - resource_account_id: Account identifier. + resource_account_id: The account that owns the resource. Must match the `account_id` in the path. - resource_id: Share Resource identifier. + resource_id: Identifier assigned by the service that owns the shared resource. resource_type: Resource Type. @@ -139,9 +139,10 @@ def update( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Optional[ResourceUpdateResponse]: - """ - Update is not immediate, an updated share resource object with a new status will - be returned. + """Updates the resource's `meta`. + + Only resources with `status=active` can be + updated. Args: account_id: Account identifier. @@ -217,12 +218,9 @@ def list( share_id: Share identifier tag. - page: Page number. Defaults to `1` when `per_page` is supplied without `page`. May be - omitted entirely along with `per_page` to receive a non-paginated response. + page: Page number. Defaults to `1` when omitted. - per_page: Number of objects to return per page. Defaults to `20` when `page` is supplied - without `per_page`. May be omitted entirely along with `page` to receive a - non-paginated response. + per_page: Number of objects to return per page. Defaults to `20` when omitted. resource_type: Filter share resources by resource_type. @@ -427,9 +425,9 @@ async def create( meta: Resource Metadata. - resource_account_id: Account identifier. + resource_account_id: The account that owns the resource. Must match the `account_id` in the path. - resource_id: Share Resource identifier. + resource_id: Identifier assigned by the service that owns the shared resource. resource_type: Resource Type. @@ -482,9 +480,10 @@ async def update( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Optional[ResourceUpdateResponse]: - """ - Update is not immediate, an updated share resource object with a new status will - be returned. + """Updates the resource's `meta`. + + Only resources with `status=active` can be + updated. Args: account_id: Account identifier. @@ -560,12 +559,9 @@ def list( share_id: Share identifier tag. - page: Page number. Defaults to `1` when `per_page` is supplied without `page`. May be - omitted entirely along with `per_page` to receive a non-paginated response. + page: Page number. Defaults to `1` when omitted. - per_page: Number of objects to return per page. Defaults to `20` when `page` is supplied - without `per_page`. May be omitted entirely along with `page` to receive a - non-paginated response. + per_page: Number of objects to return per page. Defaults to `20` when omitted. resource_type: Filter share resources by resource_type. diff --git a/src/cloudflare/resources/resource_tagging/account_tags.py b/src/cloudflare/resources/resource_tagging/account_tags.py index 72a2bfb0546..4f6c98abb80 100644 --- a/src/cloudflare/resources/resource_tagging/account_tags.py +++ b/src/cloudflare/resources/resource_tagging/account_tags.py @@ -99,9 +99,12 @@ def update( resource_type: Literal[ "access_application", "access_group", + "access_service_token", "account", "account_ruleset", "ai_gateway", + "ai_search_instance", + "ai_search_namespace", "alerting_policy", "alerting_webhook", "cloudflared_tunnel", @@ -110,6 +113,7 @@ def update( "cws_policy_set", "cws_workload", "d1_database", + "device", "durable_object_namespace", "gateway_list", "gateway_rule", @@ -118,6 +122,7 @@ def update( "kv_namespace", "load_balancer_monitor", "load_balancer_pool", + "namespace_worker", "pages_project", "queue", "r2_bucket", @@ -174,9 +179,12 @@ def update( | Literal[ "access_application", "access_group", + "access_service_token", "account", "account_ruleset", "ai_gateway", + "ai_search_instance", + "ai_search_namespace", "alerting_policy", "alerting_webhook", "cloudflared_tunnel", @@ -185,6 +193,7 @@ def update( "cws_policy_set", "cws_workload", "d1_database", + "device", "durable_object_namespace", "gateway_list", "gateway_rule", @@ -193,6 +202,7 @@ def update( "kv_namespace", "load_balancer_monitor", "load_balancer_pool", + "namespace_worker", "pages_project", "queue", "r2_bucket", @@ -287,9 +297,12 @@ def get( resource_type: Literal[ "access_application", "access_group", + "access_service_token", "account", "account_ruleset", "ai_gateway", + "ai_search_instance", + "ai_search_namespace", "alerting_policy", "alerting_webhook", "cloudflared_tunnel", @@ -298,6 +311,7 @@ def get( "cws_policy_set", "cws_workload", "d1_database", + "device", "durable_object_namespace", "gateway_list", "gateway_rule", @@ -306,6 +320,7 @@ def get( "kv_namespace", "load_balancer_monitor", "load_balancer_pool", + "namespace_worker", "pages_project", "queue", "r2_bucket", @@ -445,9 +460,12 @@ async def update( resource_type: Literal[ "access_application", "access_group", + "access_service_token", "account", "account_ruleset", "ai_gateway", + "ai_search_instance", + "ai_search_namespace", "alerting_policy", "alerting_webhook", "cloudflared_tunnel", @@ -456,6 +474,7 @@ async def update( "cws_policy_set", "cws_workload", "d1_database", + "device", "durable_object_namespace", "gateway_list", "gateway_rule", @@ -464,6 +483,7 @@ async def update( "kv_namespace", "load_balancer_monitor", "load_balancer_pool", + "namespace_worker", "pages_project", "queue", "r2_bucket", @@ -520,9 +540,12 @@ async def update( | Literal[ "access_application", "access_group", + "access_service_token", "account", "account_ruleset", "ai_gateway", + "ai_search_instance", + "ai_search_namespace", "alerting_policy", "alerting_webhook", "cloudflared_tunnel", @@ -531,6 +554,7 @@ async def update( "cws_policy_set", "cws_workload", "d1_database", + "device", "durable_object_namespace", "gateway_list", "gateway_rule", @@ -539,6 +563,7 @@ async def update( "kv_namespace", "load_balancer_monitor", "load_balancer_pool", + "namespace_worker", "pages_project", "queue", "r2_bucket", @@ -633,9 +658,12 @@ async def get( resource_type: Literal[ "access_application", "access_group", + "access_service_token", "account", "account_ruleset", "ai_gateway", + "ai_search_instance", + "ai_search_namespace", "alerting_policy", "alerting_webhook", "cloudflared_tunnel", @@ -644,6 +672,7 @@ async def get( "cws_policy_set", "cws_workload", "d1_database", + "device", "durable_object_namespace", "gateway_list", "gateway_rule", @@ -652,6 +681,7 @@ async def get( "kv_namespace", "load_balancer_monitor", "load_balancer_pool", + "namespace_worker", "pages_project", "queue", "r2_bucket", diff --git a/src/cloudflare/resources/resource_tagging/resource_tagging.py b/src/cloudflare/resources/resource_tagging/resource_tagging.py index 997a91345e4..4e082f6d34f 100644 --- a/src/cloudflare/resources/resource_tagging/resource_tagging.py +++ b/src/cloudflare/resources/resource_tagging/resource_tagging.py @@ -112,6 +112,7 @@ def list( id: SequenceNotStr[str] | Omit = omit, case_insensitive: bool | Omit = omit, cursor: str | Omit = omit, + include_navigation: bool | Omit = omit, name: str | Omit = omit, tag: SequenceNotStr[str] | Omit = omit, type: List[ @@ -119,9 +120,12 @@ def list( "access_application", "access_application_policy", "access_group", + "access_service_token", "account", "account_ruleset", "ai_gateway", + "ai_search_instance", + "ai_search_namespace", "alerting_policy", "alerting_webhook", "api_gateway_operation", @@ -133,6 +137,7 @@ def list( "cws_policy_set", "cws_workload", "d1_database", + "device", "dns_record", "durable_object_namespace", "gateway_list", @@ -145,6 +150,7 @@ def list( "load_balancer_monitor", "load_balancer_pool", "managed_client_certificate", + "namespace_worker", "pages_project", "queue", "r2_bucket", @@ -181,6 +187,12 @@ def list( cursor: Cursor for pagination. + include_navigation: Resolve current namespace Worker navigation by immutable child tag. Optional + read-only navigation is omitted for deleted or unresolved children. Lookups are + limited to this page, at most five concurrently, with a shared two-second + budget. Tag identity, ETag, filters and pagination are unchanged; name filtering + still uses the stored resource name. Defaults to false. + name: Filter by resource name. Performs a case-insensitive substring match. Example: ?name=my-zone @@ -229,6 +241,7 @@ def list( "id": id, "case_insensitive": case_insensitive, "cursor": cursor, + "include_navigation": include_navigation, "name": name, "tag": tag, "type": type, @@ -289,6 +302,7 @@ def list( id: SequenceNotStr[str] | Omit = omit, case_insensitive: bool | Omit = omit, cursor: str | Omit = omit, + include_navigation: bool | Omit = omit, name: str | Omit = omit, tag: SequenceNotStr[str] | Omit = omit, type: List[ @@ -296,9 +310,12 @@ def list( "access_application", "access_application_policy", "access_group", + "access_service_token", "account", "account_ruleset", "ai_gateway", + "ai_search_instance", + "ai_search_namespace", "alerting_policy", "alerting_webhook", "api_gateway_operation", @@ -310,6 +327,7 @@ def list( "cws_policy_set", "cws_workload", "d1_database", + "device", "dns_record", "durable_object_namespace", "gateway_list", @@ -322,6 +340,7 @@ def list( "load_balancer_monitor", "load_balancer_pool", "managed_client_certificate", + "namespace_worker", "pages_project", "queue", "r2_bucket", @@ -358,6 +377,12 @@ def list( cursor: Cursor for pagination. + include_navigation: Resolve current namespace Worker navigation by immutable child tag. Optional + read-only navigation is omitted for deleted or unresolved children. Lookups are + limited to this page, at most five concurrently, with a shared two-second + budget. Tag identity, ETag, filters and pagination are unchanged; name filtering + still uses the stored resource name. Defaults to false. + name: Filter by resource name. Performs a case-insensitive substring match. Example: ?name=my-zone @@ -406,6 +431,7 @@ def list( "id": id, "case_insensitive": case_insensitive, "cursor": cursor, + "include_navigation": include_navigation, "name": name, "tag": tag, "type": type, diff --git a/src/cloudflare/resources/resource_tagging/values.py b/src/cloudflare/resources/resource_tagging/values.py index 52f05020f63..4af3446715f 100644 --- a/src/cloudflare/resources/resource_tagging/values.py +++ b/src/cloudflare/resources/resource_tagging/values.py @@ -54,9 +54,12 @@ def list( "access_application", "access_application_policy", "access_group", + "access_service_token", "account", "account_ruleset", "ai_gateway", + "ai_search_instance", + "ai_search_namespace", "alerting_policy", "alerting_webhook", "api_gateway_operation", @@ -68,6 +71,7 @@ def list( "cws_policy_set", "cws_workload", "d1_database", + "device", "dns_record", "durable_object_namespace", "gateway_list", @@ -80,6 +84,7 @@ def list( "load_balancer_monitor", "load_balancer_pool", "managed_client_certificate", + "namespace_worker", "pages_project", "queue", "r2_bucket", @@ -174,9 +179,12 @@ def list( "access_application", "access_application_policy", "access_group", + "access_service_token", "account", "account_ruleset", "ai_gateway", + "ai_search_instance", + "ai_search_namespace", "alerting_policy", "alerting_webhook", "api_gateway_operation", @@ -188,6 +196,7 @@ def list( "cws_policy_set", "cws_workload", "d1_database", + "device", "dns_record", "durable_object_namespace", "gateway_list", @@ -200,6 +209,7 @@ def list( "load_balancer_monitor", "load_balancer_pool", "managed_client_certificate", + "namespace_worker", "pages_project", "queue", "r2_bucket", diff --git a/src/cloudflare/resources/rulesets/api.md b/src/cloudflare/resources/rulesets/api.md index 0f6149294ab..706e9f750c3 100644 --- a/src/cloudflare/resources/rulesets/api.md +++ b/src/cloudflare/resources/rulesets/api.md @@ -18,7 +18,7 @@ Methods: - client.rulesets.create(\*, account_id, zone_id, \*\*params) -> RulesetCreateResponse - client.rulesets.update(ruleset_id, \*, account_id, zone_id, \*\*params) -> RulesetUpdateResponse -- client.rulesets.list(\*, account_id, zone_id, \*\*params) -> SyncCursorPagination[RulesetListResponse] +- client.rulesets.list(\*, account_id, zone_id, \*\*params) -> RulesetListResponse - client.rulesets.delete(ruleset_id, \*, account_id, zone_id, \*\*params) -> None - client.rulesets.get(ruleset_id, \*, account_id, zone_id) -> RulesetGetResponse @@ -45,7 +45,7 @@ from cloudflare.types.rulesets.phases import VersionListResponse, VersionGetResp Methods: -- client.rulesets.phases.versions.list(ruleset_phase, \*, account_id, zone_id) -> SyncSinglePage[VersionListResponse] +- client.rulesets.phases.versions.list(ruleset_phase, \*, account_id, zone_id) -> VersionListResponse - client.rulesets.phases.versions.get(ruleset_version, \*, ruleset_phase, account_id, zone_id) -> VersionGetResponse ## Rules @@ -94,6 +94,6 @@ from cloudflare.types.rulesets import VersionListResponse, VersionGetResponse Methods: -- client.rulesets.versions.list(ruleset_id, \*, account_id, zone_id) -> SyncSinglePage[VersionListResponse] +- client.rulesets.versions.list(ruleset_id, \*, account_id, zone_id) -> VersionListResponse - client.rulesets.versions.delete(ruleset_version, \*, ruleset_id, account_id, zone_id, \*\*params) -> None - client.rulesets.versions.get(ruleset_version, \*, ruleset_id, account_id, zone_id) -> VersionGetResponse diff --git a/src/cloudflare/resources/rulesets/phases/phases.py b/src/cloudflare/resources/rulesets/phases/phases.py index 82504f43d75..33ad1fecc72 100644 --- a/src/cloudflare/resources/rulesets/phases/phases.py +++ b/src/cloudflare/resources/rulesets/phases/phases.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing import Any, Type, Iterable, cast +from typing import Any, Iterable, cast import httpx @@ -194,21 +194,26 @@ def get( account_or_zone = "zones" account_or_zone_id = zone_id - return self._get( - path_template( - "/{account_or_zone}/{account_or_zone_id}/rulesets/phases/{ruleset_phase}/entrypoint", - ruleset_phase=ruleset_phase, - account_or_zone=account_or_zone, - account_or_zone_id=account_or_zone_id, - ), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - post_parser=ResultWrapper[PhaseGetResponse]._unwrapper, + return cast( + PhaseGetResponse, + self._get( + path_template( + "/{account_or_zone}/{account_or_zone_id}/rulesets/phases/{ruleset_phase}/entrypoint", + ruleset_phase=ruleset_phase, + account_or_zone=account_or_zone, + account_or_zone_id=account_or_zone_id, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[PhaseGetResponse]._unwrapper, + ), + cast_to=cast( + Any, ResultWrapper[PhaseGetResponse] + ), # Union types cannot be passed in as arguments in the type system ), - cast_to=cast(Type[PhaseGetResponse], ResultWrapper[PhaseGetResponse]), ) @@ -372,21 +377,26 @@ async def get( account_or_zone = "zones" account_or_zone_id = zone_id - return await self._get( - path_template( - "/{account_or_zone}/{account_or_zone_id}/rulesets/phases/{ruleset_phase}/entrypoint", - ruleset_phase=ruleset_phase, - account_or_zone=account_or_zone, - account_or_zone_id=account_or_zone_id, - ), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - post_parser=ResultWrapper[PhaseGetResponse]._unwrapper, + return cast( + PhaseGetResponse, + await self._get( + path_template( + "/{account_or_zone}/{account_or_zone_id}/rulesets/phases/{ruleset_phase}/entrypoint", + ruleset_phase=ruleset_phase, + account_or_zone=account_or_zone, + account_or_zone_id=account_or_zone_id, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[PhaseGetResponse]._unwrapper, + ), + cast_to=cast( + Any, ResultWrapper[PhaseGetResponse] + ), # Union types cannot be passed in as arguments in the type system ), - cast_to=cast(Type[PhaseGetResponse], ResultWrapper[PhaseGetResponse]), ) diff --git a/src/cloudflare/resources/rulesets/phases/versions.py b/src/cloudflare/resources/rulesets/phases/versions.py index 3a9038913e8..337a13b657d 100644 --- a/src/cloudflare/resources/rulesets/phases/versions.py +++ b/src/cloudflare/resources/rulesets/phases/versions.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing import Type, cast +from typing import Any, cast import httpx @@ -17,8 +17,7 @@ async_to_streamed_response_wrapper, ) from ...._wrappers import ResultWrapper -from ....pagination import SyncSinglePage, AsyncSinglePage -from ...._base_client import AsyncPaginator, make_request_options +from ...._base_client import make_request_options from ....types.rulesets import Phase from ....types.rulesets.phase import Phase from ....types.rulesets.phases.version_get_response import VersionGetResponse @@ -59,7 +58,7 @@ def list( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> SyncSinglePage[VersionListResponse]: + ) -> VersionListResponse: """ Fetches the versions of an account or zone entry point ruleset. @@ -92,18 +91,26 @@ def list( account_or_zone = "zones" account_or_zone_id = zone_id - return self._get_api_list( - path_template( - "/{account_or_zone}/{account_or_zone_id}/rulesets/phases/{ruleset_phase}/entrypoint/versions", - ruleset_phase=ruleset_phase, - account_or_zone=account_or_zone, - account_or_zone_id=account_or_zone_id, + return cast( + VersionListResponse, + self._get( + path_template( + "/{account_or_zone}/{account_or_zone_id}/rulesets/phases/{ruleset_phase}/entrypoint/versions", + ruleset_phase=ruleset_phase, + account_or_zone=account_or_zone, + account_or_zone_id=account_or_zone_id, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[VersionListResponse]._unwrapper, + ), + cast_to=cast( + Any, ResultWrapper[VersionListResponse] + ), # Union types cannot be passed in as arguments in the type system ), - page=SyncSinglePage[VersionListResponse], - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - model=VersionListResponse, ) def get( @@ -156,22 +163,27 @@ def get( account_or_zone = "zones" account_or_zone_id = zone_id - return self._get( - path_template( - "/{account_or_zone}/{account_or_zone_id}/rulesets/phases/{ruleset_phase}/entrypoint/versions/{ruleset_version}", - ruleset_phase=ruleset_phase, - ruleset_version=ruleset_version, - account_or_zone=account_or_zone, - account_or_zone_id=account_or_zone_id, - ), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - post_parser=ResultWrapper[VersionGetResponse]._unwrapper, + return cast( + VersionGetResponse, + self._get( + path_template( + "/{account_or_zone}/{account_or_zone_id}/rulesets/phases/{ruleset_phase}/entrypoint/versions/{ruleset_version}", + ruleset_phase=ruleset_phase, + ruleset_version=ruleset_version, + account_or_zone=account_or_zone, + account_or_zone_id=account_or_zone_id, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[VersionGetResponse]._unwrapper, + ), + cast_to=cast( + Any, ResultWrapper[VersionGetResponse] + ), # Union types cannot be passed in as arguments in the type system ), - cast_to=cast(Type[VersionGetResponse], ResultWrapper[VersionGetResponse]), ) @@ -195,7 +207,7 @@ def with_streaming_response(self) -> AsyncVersionsResourceWithStreamingResponse: """ return AsyncVersionsResourceWithStreamingResponse(self) - def list( + async def list( self, ruleset_phase: Phase, *, @@ -207,7 +219,7 @@ def list( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> AsyncPaginator[VersionListResponse, AsyncSinglePage[VersionListResponse]]: + ) -> VersionListResponse: """ Fetches the versions of an account or zone entry point ruleset. @@ -240,18 +252,26 @@ def list( account_or_zone = "zones" account_or_zone_id = zone_id - return self._get_api_list( - path_template( - "/{account_or_zone}/{account_or_zone_id}/rulesets/phases/{ruleset_phase}/entrypoint/versions", - ruleset_phase=ruleset_phase, - account_or_zone=account_or_zone, - account_or_zone_id=account_or_zone_id, + return cast( + VersionListResponse, + await self._get( + path_template( + "/{account_or_zone}/{account_or_zone_id}/rulesets/phases/{ruleset_phase}/entrypoint/versions", + ruleset_phase=ruleset_phase, + account_or_zone=account_or_zone, + account_or_zone_id=account_or_zone_id, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[VersionListResponse]._unwrapper, + ), + cast_to=cast( + Any, ResultWrapper[VersionListResponse] + ), # Union types cannot be passed in as arguments in the type system ), - page=AsyncSinglePage[VersionListResponse], - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - model=VersionListResponse, ) async def get( @@ -304,22 +324,27 @@ async def get( account_or_zone = "zones" account_or_zone_id = zone_id - return await self._get( - path_template( - "/{account_or_zone}/{account_or_zone_id}/rulesets/phases/{ruleset_phase}/entrypoint/versions/{ruleset_version}", - ruleset_phase=ruleset_phase, - ruleset_version=ruleset_version, - account_or_zone=account_or_zone, - account_or_zone_id=account_or_zone_id, - ), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - post_parser=ResultWrapper[VersionGetResponse]._unwrapper, + return cast( + VersionGetResponse, + await self._get( + path_template( + "/{account_or_zone}/{account_or_zone_id}/rulesets/phases/{ruleset_phase}/entrypoint/versions/{ruleset_version}", + ruleset_phase=ruleset_phase, + ruleset_version=ruleset_version, + account_or_zone=account_or_zone, + account_or_zone_id=account_or_zone_id, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[VersionGetResponse]._unwrapper, + ), + cast_to=cast( + Any, ResultWrapper[VersionGetResponse] + ), # Union types cannot be passed in as arguments in the type system ), - cast_to=cast(Type[VersionGetResponse], ResultWrapper[VersionGetResponse]), ) diff --git a/src/cloudflare/resources/rulesets/rulesets.py b/src/cloudflare/resources/rulesets/rulesets.py index 7b44df6a507..cefe9a7ff9b 100644 --- a/src/cloudflare/resources/rulesets/rulesets.py +++ b/src/cloudflare/resources/rulesets/rulesets.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing import Any, Type, Iterable, cast +from typing import Any, Iterable, cast import httpx @@ -33,7 +33,6 @@ async_to_streamed_response_wrapper, ) from ..._wrappers import ResultWrapper -from ...pagination import SyncCursorPagination, AsyncCursorPagination from .phases.phases import ( PhasesResource, AsyncPhasesResource, @@ -42,7 +41,7 @@ PhasesResourceWithStreamingResponse, AsyncPhasesResourceWithStreamingResponse, ) -from ..._base_client import AsyncPaginator, make_request_options +from ..._base_client import make_request_options from ...types.rulesets import ( Kind, Phase, @@ -297,7 +296,7 @@ def list( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> SyncCursorPagination[RulesetListResponse]: + ) -> RulesetListResponse: """ Fetches all rulesets. @@ -330,27 +329,32 @@ def list( account_or_zone = "zones" account_or_zone_id = zone_id - return self._get_api_list( - path_template( - "/{account_or_zone}/{account_or_zone_id}/rulesets", - account_or_zone=account_or_zone, - account_or_zone_id=account_or_zone_id, - ), - page=SyncCursorPagination[RulesetListResponse], - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - query=maybe_transform( - { - "cursor": cursor, - "per_page": per_page, - }, - ruleset_list_params.RulesetListParams, + return cast( + RulesetListResponse, + self._get( + path_template( + "/{account_or_zone}/{account_or_zone_id}/rulesets", + account_or_zone=account_or_zone, + account_or_zone_id=account_or_zone_id, ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "cursor": cursor, + "per_page": per_page, + }, + ruleset_list_params.RulesetListParams, + ), + post_parser=ResultWrapper[RulesetListResponse]._unwrapper, + ), + cast_to=cast( + Any, ResultWrapper[RulesetListResponse] + ), # Union types cannot be passed in as arguments in the type system ), - model=RulesetListResponse, ) def delete( @@ -466,21 +470,26 @@ def get( account_or_zone = "zones" account_or_zone_id = zone_id - return self._get( - path_template( - "/{account_or_zone}/{account_or_zone_id}/rulesets/{ruleset_id}", - ruleset_id=ruleset_id, - account_or_zone=account_or_zone, - account_or_zone_id=account_or_zone_id, - ), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - post_parser=ResultWrapper[RulesetGetResponse]._unwrapper, + return cast( + RulesetGetResponse, + self._get( + path_template( + "/{account_or_zone}/{account_or_zone_id}/rulesets/{ruleset_id}", + ruleset_id=ruleset_id, + account_or_zone=account_or_zone, + account_or_zone_id=account_or_zone_id, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[RulesetGetResponse]._unwrapper, + ), + cast_to=cast( + Any, ResultWrapper[RulesetGetResponse] + ), # Union types cannot be passed in as arguments in the type system ), - cast_to=cast(Type[RulesetGetResponse], ResultWrapper[RulesetGetResponse]), ) @@ -707,7 +716,7 @@ async def update( ), ) - def list( + async def list( self, *, account_id: str | Omit = omit, @@ -720,7 +729,7 @@ def list( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> AsyncPaginator[RulesetListResponse, AsyncCursorPagination[RulesetListResponse]]: + ) -> RulesetListResponse: """ Fetches all rulesets. @@ -753,27 +762,32 @@ def list( account_or_zone = "zones" account_or_zone_id = zone_id - return self._get_api_list( - path_template( - "/{account_or_zone}/{account_or_zone_id}/rulesets", - account_or_zone=account_or_zone, - account_or_zone_id=account_or_zone_id, - ), - page=AsyncCursorPagination[RulesetListResponse], - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - query=maybe_transform( - { - "cursor": cursor, - "per_page": per_page, - }, - ruleset_list_params.RulesetListParams, + return cast( + RulesetListResponse, + await self._get( + path_template( + "/{account_or_zone}/{account_or_zone_id}/rulesets", + account_or_zone=account_or_zone, + account_or_zone_id=account_or_zone_id, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=await async_maybe_transform( + { + "cursor": cursor, + "per_page": per_page, + }, + ruleset_list_params.RulesetListParams, + ), + post_parser=ResultWrapper[RulesetListResponse]._unwrapper, ), + cast_to=cast( + Any, ResultWrapper[RulesetListResponse] + ), # Union types cannot be passed in as arguments in the type system ), - model=RulesetListResponse, ) async def delete( @@ -889,21 +903,26 @@ async def get( account_or_zone = "zones" account_or_zone_id = zone_id - return await self._get( - path_template( - "/{account_or_zone}/{account_or_zone_id}/rulesets/{ruleset_id}", - ruleset_id=ruleset_id, - account_or_zone=account_or_zone, - account_or_zone_id=account_or_zone_id, - ), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - post_parser=ResultWrapper[RulesetGetResponse]._unwrapper, + return cast( + RulesetGetResponse, + await self._get( + path_template( + "/{account_or_zone}/{account_or_zone_id}/rulesets/{ruleset_id}", + ruleset_id=ruleset_id, + account_or_zone=account_or_zone, + account_or_zone_id=account_or_zone_id, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[RulesetGetResponse]._unwrapper, + ), + cast_to=cast( + Any, ResultWrapper[RulesetGetResponse] + ), # Union types cannot be passed in as arguments in the type system ), - cast_to=cast(Type[RulesetGetResponse], ResultWrapper[RulesetGetResponse]), ) diff --git a/src/cloudflare/resources/rulesets/versions.py b/src/cloudflare/resources/rulesets/versions.py index 7abd681259c..6cac1763092 100644 --- a/src/cloudflare/resources/rulesets/versions.py +++ b/src/cloudflare/resources/rulesets/versions.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing import Type, cast +from typing import Any, cast import httpx @@ -17,8 +17,7 @@ async_to_streamed_response_wrapper, ) from ..._wrappers import ResultWrapper -from ...pagination import SyncSinglePage, AsyncSinglePage -from ..._base_client import AsyncPaginator, make_request_options +from ..._base_client import make_request_options from ...types.rulesets import version_delete_params from ...types.rulesets.version_get_response import VersionGetResponse from ...types.rulesets.version_list_response import VersionListResponse @@ -58,7 +57,7 @@ def list( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> SyncSinglePage[VersionListResponse]: + ) -> VersionListResponse: """ Fetches the versions of an account or zone ruleset. @@ -91,18 +90,26 @@ def list( account_or_zone = "zones" account_or_zone_id = zone_id - return self._get_api_list( - path_template( - "/{account_or_zone}/{account_or_zone_id}/rulesets/{ruleset_id}/versions", - ruleset_id=ruleset_id, - account_or_zone=account_or_zone, - account_or_zone_id=account_or_zone_id, - ), - page=SyncSinglePage[VersionListResponse], - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + return cast( + VersionListResponse, + self._get( + path_template( + "/{account_or_zone}/{account_or_zone_id}/rulesets/{ruleset_id}/versions", + ruleset_id=ruleset_id, + account_or_zone=account_or_zone, + account_or_zone_id=account_or_zone_id, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[VersionListResponse]._unwrapper, + ), + cast_to=cast( + Any, ResultWrapper[VersionListResponse] + ), # Union types cannot be passed in as arguments in the type system ), - model=VersionListResponse, ) def delete( @@ -229,22 +236,27 @@ def get( account_or_zone = "zones" account_or_zone_id = zone_id - return self._get( - path_template( - "/{account_or_zone}/{account_or_zone_id}/rulesets/{ruleset_id}/versions/{ruleset_version}", - ruleset_id=ruleset_id, - ruleset_version=ruleset_version, - account_or_zone=account_or_zone, - account_or_zone_id=account_or_zone_id, + return cast( + VersionGetResponse, + self._get( + path_template( + "/{account_or_zone}/{account_or_zone_id}/rulesets/{ruleset_id}/versions/{ruleset_version}", + ruleset_id=ruleset_id, + ruleset_version=ruleset_version, + account_or_zone=account_or_zone, + account_or_zone_id=account_or_zone_id, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[VersionGetResponse]._unwrapper, + ), + cast_to=cast( + Any, ResultWrapper[VersionGetResponse] + ), # Union types cannot be passed in as arguments in the type system ), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - post_parser=ResultWrapper[VersionGetResponse]._unwrapper, - ), - cast_to=cast(Type[VersionGetResponse], ResultWrapper[VersionGetResponse]), ) @@ -268,7 +280,7 @@ def with_streaming_response(self) -> AsyncVersionsResourceWithStreamingResponse: """ return AsyncVersionsResourceWithStreamingResponse(self) - def list( + async def list( self, ruleset_id: str, *, @@ -280,7 +292,7 @@ def list( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> AsyncPaginator[VersionListResponse, AsyncSinglePage[VersionListResponse]]: + ) -> VersionListResponse: """ Fetches the versions of an account or zone ruleset. @@ -313,18 +325,26 @@ def list( account_or_zone = "zones" account_or_zone_id = zone_id - return self._get_api_list( - path_template( - "/{account_or_zone}/{account_or_zone_id}/rulesets/{ruleset_id}/versions", - ruleset_id=ruleset_id, - account_or_zone=account_or_zone, - account_or_zone_id=account_or_zone_id, + return cast( + VersionListResponse, + await self._get( + path_template( + "/{account_or_zone}/{account_or_zone_id}/rulesets/{ruleset_id}/versions", + ruleset_id=ruleset_id, + account_or_zone=account_or_zone, + account_or_zone_id=account_or_zone_id, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[VersionListResponse]._unwrapper, + ), + cast_to=cast( + Any, ResultWrapper[VersionListResponse] + ), # Union types cannot be passed in as arguments in the type system ), - page=AsyncSinglePage[VersionListResponse], - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - model=VersionListResponse, ) async def delete( @@ -451,22 +471,27 @@ async def get( account_or_zone = "zones" account_or_zone_id = zone_id - return await self._get( - path_template( - "/{account_or_zone}/{account_or_zone_id}/rulesets/{ruleset_id}/versions/{ruleset_version}", - ruleset_id=ruleset_id, - ruleset_version=ruleset_version, - account_or_zone=account_or_zone, - account_or_zone_id=account_or_zone_id, - ), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - post_parser=ResultWrapper[VersionGetResponse]._unwrapper, + return cast( + VersionGetResponse, + await self._get( + path_template( + "/{account_or_zone}/{account_or_zone_id}/rulesets/{ruleset_id}/versions/{ruleset_version}", + ruleset_id=ruleset_id, + ruleset_version=ruleset_version, + account_or_zone=account_or_zone, + account_or_zone_id=account_or_zone_id, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[VersionGetResponse]._unwrapper, + ), + cast_to=cast( + Any, ResultWrapper[VersionGetResponse] + ), # Union types cannot be passed in as arguments in the type system ), - cast_to=cast(Type[VersionGetResponse], ResultWrapper[VersionGetResponse]), ) diff --git a/src/cloudflare/resources/secrets_store/stores/secrets.py b/src/cloudflare/resources/secrets_store/stores/secrets.py index 94b1840c8b6..0e5735c4539 100644 --- a/src/cloudflare/resources/secrets_store/stores/secrets.py +++ b/src/cloudflare/resources/secrets_store/stores/secrets.py @@ -271,8 +271,8 @@ def duplicate( account_id: str, store_id: str, name: str, - scopes: List[Literal["workers", "ai_gateway", "dex", "access", "containers", "websearch"]], comment: str | Omit = omit, + scopes: List[Literal["workers", "ai_gateway", "dex", "access", "containers", "websearch"]] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -286,10 +286,11 @@ def duplicate( Args: name: The name of the secret. - scopes: The list of services that can use this secret. - comment: Freeform text describing the secret. + scopes: The list of services that can use this secret. Omit it on create or duplicate to + inherit the store's scopes. An empty list lets no service use the secret. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -314,8 +315,8 @@ def duplicate( body=maybe_transform( { "name": name, - "scopes": scopes, "comment": comment, + "scopes": scopes, }, secret_duplicate_params.SecretDuplicateParams, ), @@ -336,7 +337,8 @@ def edit( account_id: str, store_id: str, comment: str | Omit = omit, - scopes: List[Literal["workers", "ai_gateway", "dex", "access", "containers", "websearch"]] | Omit = omit, + scopes: Optional[List[Literal["workers", "ai_gateway", "dex", "access", "containers", "websearch"]]] + | Omit = omit, value: str | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. @@ -351,7 +353,9 @@ def edit( Args: comment: Freeform text describing the secret. - scopes: The list of services that can use this secret. + scopes: The list of services that can use this secret, or null when the secret inherits + its store's scopes. Set it to null in a patch to inherit again. An empty list + lets no service use the secret. value: The value of the secret. Maximum 64 KiB (65,536 bytes). Note that this is 'write only' - the API never returns this value; it exists only to create or modify @@ -681,8 +685,8 @@ async def duplicate( account_id: str, store_id: str, name: str, - scopes: List[Literal["workers", "ai_gateway", "dex", "access", "containers", "websearch"]], comment: str | Omit = omit, + scopes: List[Literal["workers", "ai_gateway", "dex", "access", "containers", "websearch"]] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -696,10 +700,11 @@ async def duplicate( Args: name: The name of the secret. - scopes: The list of services that can use this secret. - comment: Freeform text describing the secret. + scopes: The list of services that can use this secret. Omit it on create or duplicate to + inherit the store's scopes. An empty list lets no service use the secret. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -724,8 +729,8 @@ async def duplicate( body=await async_maybe_transform( { "name": name, - "scopes": scopes, "comment": comment, + "scopes": scopes, }, secret_duplicate_params.SecretDuplicateParams, ), @@ -746,7 +751,8 @@ async def edit( account_id: str, store_id: str, comment: str | Omit = omit, - scopes: List[Literal["workers", "ai_gateway", "dex", "access", "containers", "websearch"]] | Omit = omit, + scopes: Optional[List[Literal["workers", "ai_gateway", "dex", "access", "containers", "websearch"]]] + | Omit = omit, value: str | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. @@ -761,7 +767,9 @@ async def edit( Args: comment: Freeform text describing the secret. - scopes: The list of services that can use this secret. + scopes: The list of services that can use this secret, or null when the secret inherits + its store's scopes. Set it to null in a patch to inherit again. An empty list + lets no service use the secret. value: The value of the secret. Maximum 64 KiB (65,536 bytes). Note that this is 'write only' - the API never returns this value; it exists only to create or modify diff --git a/src/cloudflare/resources/tenant_custom_nameservers/__init__.py b/src/cloudflare/resources/tenant_custom_nameservers/__init__.py index 0d4c08302aa..fd8019a9a1a 100644 --- a/src/cloudflare/resources/tenant_custom_nameservers/__init__.py +++ b/src/cloudflare/resources/tenant_custom_nameservers/__init__.py @@ -1,19 +1 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from .tenant_custom_nameservers import ( - TenantCustomNameserversResource, - AsyncTenantCustomNameserversResource, - TenantCustomNameserversResourceWithRawResponse, - AsyncTenantCustomNameserversResourceWithRawResponse, - TenantCustomNameserversResourceWithStreamingResponse, - AsyncTenantCustomNameserversResourceWithStreamingResponse, -) - -__all__ = [ - "TenantCustomNameserversResource", - "AsyncTenantCustomNameserversResource", - "TenantCustomNameserversResourceWithRawResponse", - "AsyncTenantCustomNameserversResourceWithRawResponse", - "TenantCustomNameserversResourceWithStreamingResponse", - "AsyncTenantCustomNameserversResourceWithStreamingResponse", -] diff --git a/src/cloudflare/resources/tenant_custom_nameservers/api.md b/src/cloudflare/resources/tenant_custom_nameservers/api.md deleted file mode 100644 index 7722c63c5e7..00000000000 --- a/src/cloudflare/resources/tenant_custom_nameservers/api.md +++ /dev/null @@ -1,17 +0,0 @@ -# TenantCustomNameservers - -Types: - -```python -from cloudflare.types.tenant_custom_nameservers import ( - TenantCustomNameserverCreateResponse, - TenantCustomNameserverDeleteResponse, - TenantCustomNameserverGetResponse, -) -``` - -Methods: - -- client.tenant_custom_nameservers.create(tenant_tag, \*\*params) -> Optional[TenantCustomNameserverCreateResponse] -- client.tenant_custom_nameservers.delete(custom_ns_id, \*, tenant_tag) -> SyncSinglePage[TenantCustomNameserverDeleteResponse] -- client.tenant_custom_nameservers.get(tenant_tag) -> SyncSinglePage[TenantCustomNameserverGetResponse] diff --git a/src/cloudflare/resources/tenant_custom_nameservers/tenant_custom_nameservers.py b/src/cloudflare/resources/tenant_custom_nameservers/tenant_custom_nameservers.py deleted file mode 100644 index 1f63248fe2d..00000000000 --- a/src/cloudflare/resources/tenant_custom_nameservers/tenant_custom_nameservers.py +++ /dev/null @@ -1,403 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing import Type, Optional, cast - -import httpx - -from ..._types import Body, Omit, Query, Headers, NotGiven, omit, not_given -from ..._utils import path_template, maybe_transform, async_maybe_transform -from ..._compat import cached_property -from ..._resource import SyncAPIResource, AsyncAPIResource -from ..._response import ( - to_raw_response_wrapper, - to_streamed_response_wrapper, - async_to_raw_response_wrapper, - async_to_streamed_response_wrapper, -) -from ..._wrappers import ResultWrapper -from ...pagination import SyncSinglePage, AsyncSinglePage -from ..._base_client import AsyncPaginator, make_request_options -from ...types.tenant_custom_nameservers import tenant_custom_nameserver_create_params -from ...types.tenant_custom_nameservers.tenant_custom_nameserver_get_response import TenantCustomNameserverGetResponse -from ...types.tenant_custom_nameservers.tenant_custom_nameserver_create_response import ( - TenantCustomNameserverCreateResponse, -) -from ...types.tenant_custom_nameservers.tenant_custom_nameserver_delete_response import ( - TenantCustomNameserverDeleteResponse, -) - -__all__ = ["TenantCustomNameserversResource", "AsyncTenantCustomNameserversResource"] - - -class TenantCustomNameserversResource(SyncAPIResource): - @cached_property - def with_raw_response(self) -> TenantCustomNameserversResourceWithRawResponse: - """ - This property can be used as a prefix for any HTTP method call to return - the raw response object instead of the parsed content. - - For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers - """ - return TenantCustomNameserversResourceWithRawResponse(self) - - @cached_property - def with_streaming_response(self) -> TenantCustomNameserversResourceWithStreamingResponse: - """ - An alternative to `.with_raw_response` that doesn't eagerly read the response body. - - For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response - """ - return TenantCustomNameserversResourceWithStreamingResponse(self) - - def create( - self, - tenant_tag: str, - *, - ns_name: str, - ns_set: float | Omit = omit, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> Optional[TenantCustomNameserverCreateResponse]: - """ - Adds a custom nameserver for a tenant. - - Args: - tenant_tag: Tenant identifier tag. - - ns_name: The FQDN of the name server. - - ns_set: The number of the set that this name server belongs to. - - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not tenant_tag: - raise ValueError(f"Expected a non-empty value for `tenant_tag` but received {tenant_tag!r}") - return self._post( - path_template("/tenants/{tenant_tag}/custom_ns", tenant_tag=tenant_tag), - body=maybe_transform( - { - "ns_name": ns_name, - "ns_set": ns_set, - }, - tenant_custom_nameserver_create_params.TenantCustomNameserverCreateParams, - ), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - post_parser=ResultWrapper[Optional[TenantCustomNameserverCreateResponse]]._unwrapper, - ), - cast_to=cast( - Type[Optional[TenantCustomNameserverCreateResponse]], - ResultWrapper[TenantCustomNameserverCreateResponse], - ), - ) - - def delete( - self, - custom_ns_id: str, - *, - tenant_tag: str, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> SyncSinglePage[TenantCustomNameserverDeleteResponse]: - """ - Deletes a tenant's custom nameserver. - - Args: - tenant_tag: Tenant identifier tag. - - custom_ns_id: The FQDN of the name server. - - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not tenant_tag: - raise ValueError(f"Expected a non-empty value for `tenant_tag` but received {tenant_tag!r}") - if not custom_ns_id: - raise ValueError(f"Expected a non-empty value for `custom_ns_id` but received {custom_ns_id!r}") - return self._get_api_list( - path_template( - "/tenants/{tenant_tag}/custom_ns/{custom_ns_id}", tenant_tag=tenant_tag, custom_ns_id=custom_ns_id - ), - page=SyncSinglePage[TenantCustomNameserverDeleteResponse], - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - model=str, - method="delete", - ) - - def get( - self, - tenant_tag: str, - *, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> SyncSinglePage[TenantCustomNameserverGetResponse]: - """ - Lists a tenant's custom nameservers. - - Args: - tenant_tag: Tenant identifier tag. - - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not tenant_tag: - raise ValueError(f"Expected a non-empty value for `tenant_tag` but received {tenant_tag!r}") - return self._get_api_list( - path_template("/tenants/{tenant_tag}/custom_ns", tenant_tag=tenant_tag), - page=SyncSinglePage[TenantCustomNameserverGetResponse], - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - model=TenantCustomNameserverGetResponse, - ) - - -class AsyncTenantCustomNameserversResource(AsyncAPIResource): - @cached_property - def with_raw_response(self) -> AsyncTenantCustomNameserversResourceWithRawResponse: - """ - This property can be used as a prefix for any HTTP method call to return - the raw response object instead of the parsed content. - - For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers - """ - return AsyncTenantCustomNameserversResourceWithRawResponse(self) - - @cached_property - def with_streaming_response(self) -> AsyncTenantCustomNameserversResourceWithStreamingResponse: - """ - An alternative to `.with_raw_response` that doesn't eagerly read the response body. - - For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response - """ - return AsyncTenantCustomNameserversResourceWithStreamingResponse(self) - - async def create( - self, - tenant_tag: str, - *, - ns_name: str, - ns_set: float | Omit = omit, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> Optional[TenantCustomNameserverCreateResponse]: - """ - Adds a custom nameserver for a tenant. - - Args: - tenant_tag: Tenant identifier tag. - - ns_name: The FQDN of the name server. - - ns_set: The number of the set that this name server belongs to. - - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not tenant_tag: - raise ValueError(f"Expected a non-empty value for `tenant_tag` but received {tenant_tag!r}") - return await self._post( - path_template("/tenants/{tenant_tag}/custom_ns", tenant_tag=tenant_tag), - body=await async_maybe_transform( - { - "ns_name": ns_name, - "ns_set": ns_set, - }, - tenant_custom_nameserver_create_params.TenantCustomNameserverCreateParams, - ), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - post_parser=ResultWrapper[Optional[TenantCustomNameserverCreateResponse]]._unwrapper, - ), - cast_to=cast( - Type[Optional[TenantCustomNameserverCreateResponse]], - ResultWrapper[TenantCustomNameserverCreateResponse], - ), - ) - - def delete( - self, - custom_ns_id: str, - *, - tenant_tag: str, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> AsyncPaginator[TenantCustomNameserverDeleteResponse, AsyncSinglePage[TenantCustomNameserverDeleteResponse]]: - """ - Deletes a tenant's custom nameserver. - - Args: - tenant_tag: Tenant identifier tag. - - custom_ns_id: The FQDN of the name server. - - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not tenant_tag: - raise ValueError(f"Expected a non-empty value for `tenant_tag` but received {tenant_tag!r}") - if not custom_ns_id: - raise ValueError(f"Expected a non-empty value for `custom_ns_id` but received {custom_ns_id!r}") - return self._get_api_list( - path_template( - "/tenants/{tenant_tag}/custom_ns/{custom_ns_id}", tenant_tag=tenant_tag, custom_ns_id=custom_ns_id - ), - page=AsyncSinglePage[TenantCustomNameserverDeleteResponse], - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - model=str, - method="delete", - ) - - def get( - self, - tenant_tag: str, - *, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> AsyncPaginator[TenantCustomNameserverGetResponse, AsyncSinglePage[TenantCustomNameserverGetResponse]]: - """ - Lists a tenant's custom nameservers. - - Args: - tenant_tag: Tenant identifier tag. - - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not tenant_tag: - raise ValueError(f"Expected a non-empty value for `tenant_tag` but received {tenant_tag!r}") - return self._get_api_list( - path_template("/tenants/{tenant_tag}/custom_ns", tenant_tag=tenant_tag), - page=AsyncSinglePage[TenantCustomNameserverGetResponse], - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - model=TenantCustomNameserverGetResponse, - ) - - -class TenantCustomNameserversResourceWithRawResponse: - def __init__(self, tenant_custom_nameservers: TenantCustomNameserversResource) -> None: - self._tenant_custom_nameservers = tenant_custom_nameservers - - self.create = to_raw_response_wrapper( - tenant_custom_nameservers.create, - ) - self.delete = to_raw_response_wrapper( - tenant_custom_nameservers.delete, - ) - self.get = to_raw_response_wrapper( - tenant_custom_nameservers.get, - ) - - -class AsyncTenantCustomNameserversResourceWithRawResponse: - def __init__(self, tenant_custom_nameservers: AsyncTenantCustomNameserversResource) -> None: - self._tenant_custom_nameservers = tenant_custom_nameservers - - self.create = async_to_raw_response_wrapper( - tenant_custom_nameservers.create, - ) - self.delete = async_to_raw_response_wrapper( - tenant_custom_nameservers.delete, - ) - self.get = async_to_raw_response_wrapper( - tenant_custom_nameservers.get, - ) - - -class TenantCustomNameserversResourceWithStreamingResponse: - def __init__(self, tenant_custom_nameservers: TenantCustomNameserversResource) -> None: - self._tenant_custom_nameservers = tenant_custom_nameservers - - self.create = to_streamed_response_wrapper( - tenant_custom_nameservers.create, - ) - self.delete = to_streamed_response_wrapper( - tenant_custom_nameservers.delete, - ) - self.get = to_streamed_response_wrapper( - tenant_custom_nameservers.get, - ) - - -class AsyncTenantCustomNameserversResourceWithStreamingResponse: - def __init__(self, tenant_custom_nameservers: AsyncTenantCustomNameserversResource) -> None: - self._tenant_custom_nameservers = tenant_custom_nameservers - - self.create = async_to_streamed_response_wrapper( - tenant_custom_nameservers.create, - ) - self.delete = async_to_streamed_response_wrapper( - tenant_custom_nameservers.delete, - ) - self.get = async_to_streamed_response_wrapper( - tenant_custom_nameservers.get, - ) diff --git a/src/cloudflare/resources/tenants/__init__.py b/src/cloudflare/resources/tenants/__init__.py index 74459d119a6..271919adc02 100644 --- a/src/cloudflare/resources/tenants/__init__.py +++ b/src/cloudflare/resources/tenants/__init__.py @@ -16,56 +16,14 @@ AccountsResourceWithStreamingResponse, AsyncAccountsResourceWithStreamingResponse, ) -from .memberships import ( - MembershipsResource, - AsyncMembershipsResource, - MembershipsResourceWithRawResponse, - AsyncMembershipsResourceWithRawResponse, - MembershipsResourceWithStreamingResponse, - AsyncMembershipsResourceWithStreamingResponse, -) -from .entitlements import ( - EntitlementsResource, - AsyncEntitlementsResource, - EntitlementsResourceWithRawResponse, - AsyncEntitlementsResourceWithRawResponse, - EntitlementsResourceWithStreamingResponse, - AsyncEntitlementsResourceWithStreamingResponse, -) -from .account_types import ( - AccountTypesResource, - AsyncAccountTypesResource, - AccountTypesResourceWithRawResponse, - AsyncAccountTypesResourceWithRawResponse, - AccountTypesResourceWithStreamingResponse, - AsyncAccountTypesResourceWithStreamingResponse, -) __all__ = [ - "AccountTypesResource", - "AsyncAccountTypesResource", - "AccountTypesResourceWithRawResponse", - "AsyncAccountTypesResourceWithRawResponse", - "AccountTypesResourceWithStreamingResponse", - "AsyncAccountTypesResourceWithStreamingResponse", "AccountsResource", "AsyncAccountsResource", "AccountsResourceWithRawResponse", "AsyncAccountsResourceWithRawResponse", "AccountsResourceWithStreamingResponse", "AsyncAccountsResourceWithStreamingResponse", - "EntitlementsResource", - "AsyncEntitlementsResource", - "EntitlementsResourceWithRawResponse", - "AsyncEntitlementsResourceWithRawResponse", - "EntitlementsResourceWithStreamingResponse", - "AsyncEntitlementsResourceWithStreamingResponse", - "MembershipsResource", - "AsyncMembershipsResource", - "MembershipsResourceWithRawResponse", - "AsyncMembershipsResourceWithRawResponse", - "MembershipsResourceWithStreamingResponse", - "AsyncMembershipsResourceWithStreamingResponse", "TenantsResource", "AsyncTenantsResource", "TenantsResourceWithRawResponse", diff --git a/src/cloudflare/resources/tenants/accounts.py b/src/cloudflare/resources/tenants/accounts.py index 6913e4ca2f8..f55ce66250e 100644 --- a/src/cloudflare/resources/tenants/accounts.py +++ b/src/cloudflare/resources/tenants/accounts.py @@ -2,10 +2,12 @@ from __future__ import annotations +from typing_extensions import Literal + import httpx -from ..._types import Body, Query, Headers, NotGiven, not_given -from ..._utils import path_template +from ..._types import Body, Omit, Query, Headers, NotGiven, omit, not_given +from ..._utils import path_template, maybe_transform from ..._compat import cached_property from ..._resource import SyncAPIResource, AsyncAPIResource from ..._response import ( @@ -14,9 +16,10 @@ async_to_raw_response_wrapper, async_to_streamed_response_wrapper, ) -from ...pagination import SyncSinglePage, AsyncSinglePage +from ...pagination import SyncV4PagePaginationArray, AsyncV4PagePaginationArray from ..._base_client import AsyncPaginator, make_request_options -from ...types.tenants.tenant_account import TenantAccount +from ...types.tenants import account_list_params +from ...types.tenants.account_list_response import AccountListResponse __all__ = ["AccountsResource", "AsyncAccountsResource"] @@ -45,17 +48,59 @@ def list( self, tenant_id: str, *, + account_pubname: account_list_params.AccountPubname | Omit = omit, + direction: Literal["asc", "desc"] | Omit = omit, + include_total: bool | Omit = omit, + name: account_list_params.Name | Omit = omit, + order_by: Literal["account_name"] | Omit = omit, + page: int | Omit = omit, + page_size: int | Omit = omit, + page_token: str | Omit = omit, + per_page: int | Omit = omit, + status: Literal["active", "deleted"] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> SyncSinglePage[TenantAccount]: + ) -> SyncV4PagePaginationArray[AccountListResponse]: """ - Lists the Cloudflare accounts associated with this tenant. + Lists all Cloudflare accounts across this tenant's hierarchy using the legacy + Account response shape. Use `GET /organizations/{organization_id}/accounts` to + list only accounts immediately attached to a specific Organization using the + modern Account response shape. Use `page_token` and `page_size` for cursor + pagination, or provide `page` and `per_page` together for legacy offset + pagination. Cursor pagination takes precedence when requested. Args: + direction: Sort direction for the order_by field. Valid values: `asc`, `desc`. Defaults to + `asc` when order_by is specified. + + include_total: Whether to calculate and return the exact `result_info.total_size` for cursor + pagination. Defaults to true. When false, `total_size` is omitted. Legacy + `page`/`per_page` requests always calculate `total_count`. + + order_by: Field to order results by. Currently supported values: `account_name`. + + page: Legacy offset page number. Must be provided with `per_page`. Values below 1 are + treated as + + 1. Cursor pagination takes precedence when requested. + + page_size: The amount of items to return. Defaults to 10. + + page_token: An opaque token returned from the last list response that when provided will + retrieve the next page. + + Parameters used to filter the retrieved list must remain in subsequent requests + with a page token. + + per_page: Legacy offset page size. Must be provided with `page`. Values are clamped to the + range 1-100. Cursor pagination takes precedence when requested. + + status: Filter accounts by lifecycle status. Defaults to `active`. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -68,11 +113,29 @@ def list( raise ValueError(f"Expected a non-empty value for `tenant_id` but received {tenant_id!r}") return self._get_api_list( path_template("/tenants/{tenant_id}/accounts", tenant_id=tenant_id), - page=SyncSinglePage[TenantAccount], + page=SyncV4PagePaginationArray[AccountListResponse], options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "account_pubname": account_pubname, + "direction": direction, + "include_total": include_total, + "name": name, + "order_by": order_by, + "page": page, + "page_size": page_size, + "page_token": page_token, + "per_page": per_page, + "status": status, + }, + account_list_params.AccountListParams, + ), ), - model=TenantAccount, + model=AccountListResponse, ) @@ -100,17 +163,59 @@ def list( self, tenant_id: str, *, + account_pubname: account_list_params.AccountPubname | Omit = omit, + direction: Literal["asc", "desc"] | Omit = omit, + include_total: bool | Omit = omit, + name: account_list_params.Name | Omit = omit, + order_by: Literal["account_name"] | Omit = omit, + page: int | Omit = omit, + page_size: int | Omit = omit, + page_token: str | Omit = omit, + per_page: int | Omit = omit, + status: Literal["active", "deleted"] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> AsyncPaginator[TenantAccount, AsyncSinglePage[TenantAccount]]: + ) -> AsyncPaginator[AccountListResponse, AsyncV4PagePaginationArray[AccountListResponse]]: """ - Lists the Cloudflare accounts associated with this tenant. + Lists all Cloudflare accounts across this tenant's hierarchy using the legacy + Account response shape. Use `GET /organizations/{organization_id}/accounts` to + list only accounts immediately attached to a specific Organization using the + modern Account response shape. Use `page_token` and `page_size` for cursor + pagination, or provide `page` and `per_page` together for legacy offset + pagination. Cursor pagination takes precedence when requested. Args: + direction: Sort direction for the order_by field. Valid values: `asc`, `desc`. Defaults to + `asc` when order_by is specified. + + include_total: Whether to calculate and return the exact `result_info.total_size` for cursor + pagination. Defaults to true. When false, `total_size` is omitted. Legacy + `page`/`per_page` requests always calculate `total_count`. + + order_by: Field to order results by. Currently supported values: `account_name`. + + page: Legacy offset page number. Must be provided with `per_page`. Values below 1 are + treated as + + 1. Cursor pagination takes precedence when requested. + + page_size: The amount of items to return. Defaults to 10. + + page_token: An opaque token returned from the last list response that when provided will + retrieve the next page. + + Parameters used to filter the retrieved list must remain in subsequent requests + with a page token. + + per_page: Legacy offset page size. Must be provided with `page`. Values are clamped to the + range 1-100. Cursor pagination takes precedence when requested. + + status: Filter accounts by lifecycle status. Defaults to `active`. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -123,11 +228,29 @@ def list( raise ValueError(f"Expected a non-empty value for `tenant_id` but received {tenant_id!r}") return self._get_api_list( path_template("/tenants/{tenant_id}/accounts", tenant_id=tenant_id), - page=AsyncSinglePage[TenantAccount], + page=AsyncV4PagePaginationArray[AccountListResponse], options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "account_pubname": account_pubname, + "direction": direction, + "include_total": include_total, + "name": name, + "order_by": order_by, + "page": page, + "page_size": page_size, + "page_token": page_token, + "per_page": per_page, + "status": status, + }, + account_list_params.AccountListParams, + ), ), - model=TenantAccount, + model=AccountListResponse, ) diff --git a/src/cloudflare/resources/tenants/api.md b/src/cloudflare/resources/tenants/api.md index ffac91773b5..cf9a920d9b0 100644 --- a/src/cloudflare/resources/tenants/api.md +++ b/src/cloudflare/resources/tenants/api.md @@ -1,59 +1,13 @@ # Tenants -Types: - -```python -from cloudflare.types.tenants import Tenant -``` - -Methods: - -- client.tenants.get(tenant_id) -> Tenant - -## AccountTypes - -Types: - -```python -from cloudflare.types.tenants import AccountTypeListResponse -``` - -Methods: - -- client.tenants.account_types.list(tenant_id) -> SyncSinglePage[AccountTypeListResponse] - ## Accounts Types: ```python -from cloudflare.types.tenants import TenantAccount -``` - -Methods: - -- client.tenants.accounts.list(tenant_id) -> SyncSinglePage[TenantAccount] - -## Entitlements - -Types: - -```python -from cloudflare.types.tenants import TenantEntitlements -``` - -Methods: - -- client.tenants.entitlements.get(tenant_id) -> TenantEntitlements - -## Memberships - -Types: - -```python -from cloudflare.types.tenants import TenantMembership +from cloudflare.types.tenants import TenantAccount, AccountListResponse ``` Methods: -- client.tenants.memberships.list(tenant_id) -> SyncSinglePage[TenantMembership] +- client.tenants.accounts.list(tenant_id, \*\*params) -> SyncV4PagePaginationArray[AccountListResponse] diff --git a/src/cloudflare/resources/tenants/entitlements.py b/src/cloudflare/resources/tenants/entitlements.py deleted file mode 100644 index 1b93df15472..00000000000 --- a/src/cloudflare/resources/tenants/entitlements.py +++ /dev/null @@ -1,177 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing import Type, cast - -import httpx - -from ..._types import Body, Query, Headers, NotGiven, not_given -from ..._utils import path_template -from ..._compat import cached_property -from ..._resource import SyncAPIResource, AsyncAPIResource -from ..._response import ( - to_raw_response_wrapper, - to_streamed_response_wrapper, - async_to_raw_response_wrapper, - async_to_streamed_response_wrapper, -) -from ..._wrappers import ResultWrapper -from ..._base_client import make_request_options -from ...types.tenants.tenant_entitlements import TenantEntitlements - -__all__ = ["EntitlementsResource", "AsyncEntitlementsResource"] - - -class EntitlementsResource(SyncAPIResource): - @cached_property - def with_raw_response(self) -> EntitlementsResourceWithRawResponse: - """ - This property can be used as a prefix for any HTTP method call to return - the raw response object instead of the parsed content. - - For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers - """ - return EntitlementsResourceWithRawResponse(self) - - @cached_property - def with_streaming_response(self) -> EntitlementsResourceWithStreamingResponse: - """ - An alternative to `.with_raw_response` that doesn't eagerly read the response body. - - For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response - """ - return EntitlementsResourceWithStreamingResponse(self) - - def get( - self, - tenant_id: str, - *, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> TenantEntitlements: - """ - Retrieves the innate and custom entitlement allocations available to this - tenant. - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not tenant_id: - raise ValueError(f"Expected a non-empty value for `tenant_id` but received {tenant_id!r}") - return self._get( - path_template("/tenants/{tenant_id}/entitlements", tenant_id=tenant_id), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - post_parser=ResultWrapper[TenantEntitlements]._unwrapper, - ), - cast_to=cast(Type[TenantEntitlements], ResultWrapper[TenantEntitlements]), - ) - - -class AsyncEntitlementsResource(AsyncAPIResource): - @cached_property - def with_raw_response(self) -> AsyncEntitlementsResourceWithRawResponse: - """ - This property can be used as a prefix for any HTTP method call to return - the raw response object instead of the parsed content. - - For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers - """ - return AsyncEntitlementsResourceWithRawResponse(self) - - @cached_property - def with_streaming_response(self) -> AsyncEntitlementsResourceWithStreamingResponse: - """ - An alternative to `.with_raw_response` that doesn't eagerly read the response body. - - For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response - """ - return AsyncEntitlementsResourceWithStreamingResponse(self) - - async def get( - self, - tenant_id: str, - *, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> TenantEntitlements: - """ - Retrieves the innate and custom entitlement allocations available to this - tenant. - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not tenant_id: - raise ValueError(f"Expected a non-empty value for `tenant_id` but received {tenant_id!r}") - return await self._get( - path_template("/tenants/{tenant_id}/entitlements", tenant_id=tenant_id), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - post_parser=ResultWrapper[TenantEntitlements]._unwrapper, - ), - cast_to=cast(Type[TenantEntitlements], ResultWrapper[TenantEntitlements]), - ) - - -class EntitlementsResourceWithRawResponse: - def __init__(self, entitlements: EntitlementsResource) -> None: - self._entitlements = entitlements - - self.get = to_raw_response_wrapper( - entitlements.get, - ) - - -class AsyncEntitlementsResourceWithRawResponse: - def __init__(self, entitlements: AsyncEntitlementsResource) -> None: - self._entitlements = entitlements - - self.get = async_to_raw_response_wrapper( - entitlements.get, - ) - - -class EntitlementsResourceWithStreamingResponse: - def __init__(self, entitlements: EntitlementsResource) -> None: - self._entitlements = entitlements - - self.get = to_streamed_response_wrapper( - entitlements.get, - ) - - -class AsyncEntitlementsResourceWithStreamingResponse: - def __init__(self, entitlements: AsyncEntitlementsResource) -> None: - self._entitlements = entitlements - - self.get = async_to_streamed_response_wrapper( - entitlements.get, - ) diff --git a/src/cloudflare/resources/tenants/tenants.py b/src/cloudflare/resources/tenants/tenants.py index 5ac7ec47e5c..df7aa1f5c91 100644 --- a/src/cloudflare/resources/tenants/tenants.py +++ b/src/cloudflare/resources/tenants/tenants.py @@ -2,12 +2,6 @@ from __future__ import annotations -from typing import Type, cast - -import httpx - -from ..._types import Body, Query, Headers, NotGiven, not_given -from ..._utils import path_template from .accounts import ( AccountsResource, AsyncAccountsResource, @@ -18,60 +12,15 @@ ) from ..._compat import cached_property from ..._resource import SyncAPIResource, AsyncAPIResource -from ..._response import ( - to_raw_response_wrapper, - to_streamed_response_wrapper, - async_to_raw_response_wrapper, - async_to_streamed_response_wrapper, -) -from ..._wrappers import ResultWrapper -from .memberships import ( - MembershipsResource, - AsyncMembershipsResource, - MembershipsResourceWithRawResponse, - AsyncMembershipsResourceWithRawResponse, - MembershipsResourceWithStreamingResponse, - AsyncMembershipsResourceWithStreamingResponse, -) -from .entitlements import ( - EntitlementsResource, - AsyncEntitlementsResource, - EntitlementsResourceWithRawResponse, - AsyncEntitlementsResourceWithRawResponse, - EntitlementsResourceWithStreamingResponse, - AsyncEntitlementsResourceWithStreamingResponse, -) -from .account_types import ( - AccountTypesResource, - AsyncAccountTypesResource, - AccountTypesResourceWithRawResponse, - AsyncAccountTypesResourceWithRawResponse, - AccountTypesResourceWithStreamingResponse, - AsyncAccountTypesResourceWithStreamingResponse, -) -from ..._base_client import make_request_options -from ...types.tenants.tenant import Tenant __all__ = ["TenantsResource", "AsyncTenantsResource"] class TenantsResource(SyncAPIResource): - @cached_property - def account_types(self) -> AccountTypesResource: - return AccountTypesResource(self._client) - @cached_property def accounts(self) -> AccountsResource: return AccountsResource(self._client) - @cached_property - def entitlements(self) -> EntitlementsResource: - return EntitlementsResource(self._client) - - @cached_property - def memberships(self) -> MembershipsResource: - return MembershipsResource(self._client) - @cached_property def with_raw_response(self) -> TenantsResourceWithRawResponse: """ @@ -91,62 +40,12 @@ def with_streaming_response(self) -> TenantsResourceWithStreamingResponse: """ return TenantsResourceWithStreamingResponse(self) - def get( - self, - tenant_id: str, - *, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> Tenant: - """ - Retrieves a tenant's identity, status, metadata, contacts, and organizational - units. - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not tenant_id: - raise ValueError(f"Expected a non-empty value for `tenant_id` but received {tenant_id!r}") - return self._get( - path_template("/tenants/{tenant_id}", tenant_id=tenant_id), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - post_parser=ResultWrapper[Tenant]._unwrapper, - ), - cast_to=cast(Type[Tenant], ResultWrapper[Tenant]), - ) - class AsyncTenantsResource(AsyncAPIResource): - @cached_property - def account_types(self) -> AsyncAccountTypesResource: - return AsyncAccountTypesResource(self._client) - @cached_property def accounts(self) -> AsyncAccountsResource: return AsyncAccountsResource(self._client) - @cached_property - def entitlements(self) -> AsyncEntitlementsResource: - return AsyncEntitlementsResource(self._client) - - @cached_property - def memberships(self) -> AsyncMembershipsResource: - return AsyncMembershipsResource(self._client) - @cached_property def with_raw_response(self) -> AsyncTenantsResourceWithRawResponse: """ @@ -166,140 +65,38 @@ def with_streaming_response(self) -> AsyncTenantsResourceWithStreamingResponse: """ return AsyncTenantsResourceWithStreamingResponse(self) - async def get( - self, - tenant_id: str, - *, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> Tenant: - """ - Retrieves a tenant's identity, status, metadata, contacts, and organizational - units. - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not tenant_id: - raise ValueError(f"Expected a non-empty value for `tenant_id` but received {tenant_id!r}") - return await self._get( - path_template("/tenants/{tenant_id}", tenant_id=tenant_id), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - post_parser=ResultWrapper[Tenant]._unwrapper, - ), - cast_to=cast(Type[Tenant], ResultWrapper[Tenant]), - ) - class TenantsResourceWithRawResponse: def __init__(self, tenants: TenantsResource) -> None: self._tenants = tenants - self.get = to_raw_response_wrapper( - tenants.get, - ) - - @cached_property - def account_types(self) -> AccountTypesResourceWithRawResponse: - return AccountTypesResourceWithRawResponse(self._tenants.account_types) - @cached_property def accounts(self) -> AccountsResourceWithRawResponse: return AccountsResourceWithRawResponse(self._tenants.accounts) - @cached_property - def entitlements(self) -> EntitlementsResourceWithRawResponse: - return EntitlementsResourceWithRawResponse(self._tenants.entitlements) - - @cached_property - def memberships(self) -> MembershipsResourceWithRawResponse: - return MembershipsResourceWithRawResponse(self._tenants.memberships) - class AsyncTenantsResourceWithRawResponse: def __init__(self, tenants: AsyncTenantsResource) -> None: self._tenants = tenants - self.get = async_to_raw_response_wrapper( - tenants.get, - ) - - @cached_property - def account_types(self) -> AsyncAccountTypesResourceWithRawResponse: - return AsyncAccountTypesResourceWithRawResponse(self._tenants.account_types) - @cached_property def accounts(self) -> AsyncAccountsResourceWithRawResponse: return AsyncAccountsResourceWithRawResponse(self._tenants.accounts) - @cached_property - def entitlements(self) -> AsyncEntitlementsResourceWithRawResponse: - return AsyncEntitlementsResourceWithRawResponse(self._tenants.entitlements) - - @cached_property - def memberships(self) -> AsyncMembershipsResourceWithRawResponse: - return AsyncMembershipsResourceWithRawResponse(self._tenants.memberships) - class TenantsResourceWithStreamingResponse: def __init__(self, tenants: TenantsResource) -> None: self._tenants = tenants - self.get = to_streamed_response_wrapper( - tenants.get, - ) - - @cached_property - def account_types(self) -> AccountTypesResourceWithStreamingResponse: - return AccountTypesResourceWithStreamingResponse(self._tenants.account_types) - @cached_property def accounts(self) -> AccountsResourceWithStreamingResponse: return AccountsResourceWithStreamingResponse(self._tenants.accounts) - @cached_property - def entitlements(self) -> EntitlementsResourceWithStreamingResponse: - return EntitlementsResourceWithStreamingResponse(self._tenants.entitlements) - - @cached_property - def memberships(self) -> MembershipsResourceWithStreamingResponse: - return MembershipsResourceWithStreamingResponse(self._tenants.memberships) - class AsyncTenantsResourceWithStreamingResponse: def __init__(self, tenants: AsyncTenantsResource) -> None: self._tenants = tenants - self.get = async_to_streamed_response_wrapper( - tenants.get, - ) - - @cached_property - def account_types(self) -> AsyncAccountTypesResourceWithStreamingResponse: - return AsyncAccountTypesResourceWithStreamingResponse(self._tenants.account_types) - @cached_property def accounts(self) -> AsyncAccountsResourceWithStreamingResponse: return AsyncAccountsResourceWithStreamingResponse(self._tenants.accounts) - - @cached_property - def entitlements(self) -> AsyncEntitlementsResourceWithStreamingResponse: - return AsyncEntitlementsResourceWithStreamingResponse(self._tenants.entitlements) - - @cached_property - def memberships(self) -> AsyncMembershipsResourceWithStreamingResponse: - return AsyncMembershipsResourceWithStreamingResponse(self._tenants.memberships) diff --git a/src/cloudflare/resources/url_normalization/url_normalization.py b/src/cloudflare/resources/url_normalization/url_normalization.py index c111aeccf77..6eb8d846f71 100644 --- a/src/cloudflare/resources/url_normalization/url_normalization.py +++ b/src/cloudflare/resources/url_normalization/url_normalization.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing import Type, cast +from typing import Any, cast from typing_extensions import Literal import httpx @@ -79,23 +79,28 @@ def update( """ if not zone_id: raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") - return self._put( - path_template("/zones/{zone_id}/url_normalization", zone_id=zone_id), - body=maybe_transform( - { - "scope": scope, - "type": type, - }, - url_normalization_update_params.URLNormalizationUpdateParams, - ), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - post_parser=ResultWrapper[URLNormalizationUpdateResponse]._unwrapper, + return cast( + URLNormalizationUpdateResponse, + self._put( + path_template("/zones/{zone_id}/url_normalization", zone_id=zone_id), + body=maybe_transform( + { + "scope": scope, + "type": type, + }, + url_normalization_update_params.URLNormalizationUpdateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[URLNormalizationUpdateResponse]._unwrapper, + ), + cast_to=cast( + Any, ResultWrapper[URLNormalizationUpdateResponse] + ), # Union types cannot be passed in as arguments in the type system ), - cast_to=cast(Type[URLNormalizationUpdateResponse], ResultWrapper[URLNormalizationUpdateResponse]), ) def delete( @@ -161,16 +166,21 @@ def get( """ if not zone_id: raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") - return self._get( - path_template("/zones/{zone_id}/url_normalization", zone_id=zone_id), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - post_parser=ResultWrapper[URLNormalizationGetResponse]._unwrapper, + return cast( + URLNormalizationGetResponse, + self._get( + path_template("/zones/{zone_id}/url_normalization", zone_id=zone_id), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[URLNormalizationGetResponse]._unwrapper, + ), + cast_to=cast( + Any, ResultWrapper[URLNormalizationGetResponse] + ), # Union types cannot be passed in as arguments in the type system ), - cast_to=cast(Type[URLNormalizationGetResponse], ResultWrapper[URLNormalizationGetResponse]), ) @@ -227,23 +237,28 @@ async def update( """ if not zone_id: raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") - return await self._put( - path_template("/zones/{zone_id}/url_normalization", zone_id=zone_id), - body=await async_maybe_transform( - { - "scope": scope, - "type": type, - }, - url_normalization_update_params.URLNormalizationUpdateParams, - ), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - post_parser=ResultWrapper[URLNormalizationUpdateResponse]._unwrapper, + return cast( + URLNormalizationUpdateResponse, + await self._put( + path_template("/zones/{zone_id}/url_normalization", zone_id=zone_id), + body=await async_maybe_transform( + { + "scope": scope, + "type": type, + }, + url_normalization_update_params.URLNormalizationUpdateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[URLNormalizationUpdateResponse]._unwrapper, + ), + cast_to=cast( + Any, ResultWrapper[URLNormalizationUpdateResponse] + ), # Union types cannot be passed in as arguments in the type system ), - cast_to=cast(Type[URLNormalizationUpdateResponse], ResultWrapper[URLNormalizationUpdateResponse]), ) async def delete( @@ -309,16 +324,21 @@ async def get( """ if not zone_id: raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") - return await self._get( - path_template("/zones/{zone_id}/url_normalization", zone_id=zone_id), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - post_parser=ResultWrapper[URLNormalizationGetResponse]._unwrapper, + return cast( + URLNormalizationGetResponse, + await self._get( + path_template("/zones/{zone_id}/url_normalization", zone_id=zone_id), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[URLNormalizationGetResponse]._unwrapper, + ), + cast_to=cast( + Any, ResultWrapper[URLNormalizationGetResponse] + ), # Union types cannot be passed in as arguments in the type system ), - cast_to=cast(Type[URLNormalizationGetResponse], ResultWrapper[URLNormalizationGetResponse]), ) diff --git a/src/cloudflare/resources/url_scanner/scans.py b/src/cloudflare/resources/url_scanner/scans.py index a2c1862ef86..6bcb91562e9 100644 --- a/src/cloudflare/resources/url_scanner/scans.py +++ b/src/cloudflare/resources/url_scanner/scans.py @@ -63,199 +63,144 @@ def create( url: str, agent_readiness: bool | Omit = omit, country: Literal[ - "AF", + "AE", "AL", - "DZ", - "AD", + "AM", "AO", - "AG", "AR", - "AM", - "AU", "AT", + "AU", "AZ", - "BH", - "BD", "BB", - "BY", + "BD", "BE", - "BZ", - "BJ", - "BM", - "BT", + "BF", + "BG", + "BH", + "BN", "BO", - "BA", - "BW", "BR", - "BN", - "BG", - "BF", - "BI", - "KH", - "CM", + "BT", + "BW", + "BY", "CA", - "CV", - "KY", - "CF", - "TD", + "CD", + "CH", + "CI", "CL", - "CN", + "CM", "CO", - "KM", - "CG", "CR", - "CI", - "HR", - "CU", + "CW", "CY", "CZ", - "CD", - "DK", + "DE", "DJ", - "DM", + "DK", "DO", + "DZ", "EC", - "EG", - "SV", - "GQ", - "ER", "EE", - "SZ", + "EG", + "ES", "ET", - "FJ", "FI", + "FJ", "FR", - "GA", + "GB", + "GD", "GE", - "DE", "GH", "GR", - "GL", - "GD", "GT", - "GN", - "GW", + "GU", "GY", - "HT", + "HK", "HN", + "HR", + "HT", "HU", - "IS", - "IN", "ID", - "IR", - "IQ", "IE", "IL", + "IN", + "IQ", + "IS", "IT", "JM", - "JP", "JO", - "KZ", + "JP", "KE", - "KI", - "KW", "KG", + "KH", + "KR", + "KW", + "KZ", "LA", - "LV", "LB", - "LS", + "LK", "LR", - "LY", - "LI", "LT", "LU", - "MO", + "LV", + "MA", + "MD", "MG", - "MW", - "MY", - "MV", - "ML", - "MR", + "MK", + "MM", + "MN", + "MO", + "MT", "MU", + "MV", + "MW", "MX", - "FM", - "MD", - "MC", - "MN", - "MS", - "MA", + "MY", "MZ", - "MM", "NA", - "NR", - "NP", - "NL", - "NZ", - "NI", - "NE", + "NC", "NG", - "KP", - "MK", + "NL", "NO", + "NP", + "NZ", "OM", - "PK", - "PS", "PA", - "PG", - "PY", "PE", + "PF", "PH", + "PK", "PL", + "PR", + "PS", "PT", + "PY", "QA", + "RE", "RO", + "RS", "RU", "RW", - "SH", - "KN", - "LC", - "VC", - "WS", - "SM", - "ST", "SA", - "SN", - "RS", - "SC", - "SL", - "SK", + "SE", + "SG", "SI", - "SB", - "SO", - "ZA", - "KR", - "SS", - "ES", - "LK", - "SD", + "SK", + "SN", "SR", - "SE", - "CH", - "SY", - "TW", - "TJ", - "TZ", "TH", - "BS", - "GM", - "TL", - "TG", - "TO", - "TT", + "TJ", "TN", "TR", - "TM", - "UG", + "TT", + "TW", + "TZ", "UA", - "AE", - "GB", + "UG", "US", - "UY", "UZ", - "VU", - "VE", "VN", - "YE", + "ZA", "ZM", "ZW", ] @@ -631,199 +576,144 @@ async def create( url: str, agent_readiness: bool | Omit = omit, country: Literal[ - "AF", + "AE", "AL", - "DZ", - "AD", + "AM", "AO", - "AG", "AR", - "AM", - "AU", "AT", + "AU", "AZ", - "BH", - "BD", "BB", - "BY", + "BD", "BE", - "BZ", - "BJ", - "BM", - "BT", + "BF", + "BG", + "BH", + "BN", "BO", - "BA", - "BW", "BR", - "BN", - "BG", - "BF", - "BI", - "KH", - "CM", + "BT", + "BW", + "BY", "CA", - "CV", - "KY", - "CF", - "TD", + "CD", + "CH", + "CI", "CL", - "CN", + "CM", "CO", - "KM", - "CG", "CR", - "CI", - "HR", - "CU", + "CW", "CY", "CZ", - "CD", - "DK", + "DE", "DJ", - "DM", + "DK", "DO", + "DZ", "EC", - "EG", - "SV", - "GQ", - "ER", "EE", - "SZ", + "EG", + "ES", "ET", - "FJ", "FI", + "FJ", "FR", - "GA", + "GB", + "GD", "GE", - "DE", "GH", "GR", - "GL", - "GD", "GT", - "GN", - "GW", + "GU", "GY", - "HT", + "HK", "HN", + "HR", + "HT", "HU", - "IS", - "IN", "ID", - "IR", - "IQ", "IE", "IL", + "IN", + "IQ", + "IS", "IT", "JM", - "JP", "JO", - "KZ", + "JP", "KE", - "KI", - "KW", "KG", + "KH", + "KR", + "KW", + "KZ", "LA", - "LV", "LB", - "LS", + "LK", "LR", - "LY", - "LI", "LT", "LU", - "MO", + "LV", + "MA", + "MD", "MG", - "MW", - "MY", - "MV", - "ML", - "MR", + "MK", + "MM", + "MN", + "MO", + "MT", "MU", + "MV", + "MW", "MX", - "FM", - "MD", - "MC", - "MN", - "MS", - "MA", + "MY", "MZ", - "MM", "NA", - "NR", - "NP", - "NL", - "NZ", - "NI", - "NE", + "NC", "NG", - "KP", - "MK", + "NL", "NO", + "NP", + "NZ", "OM", - "PK", - "PS", "PA", - "PG", - "PY", "PE", + "PF", "PH", + "PK", "PL", + "PR", + "PS", "PT", + "PY", "QA", + "RE", "RO", + "RS", "RU", "RW", - "SH", - "KN", - "LC", - "VC", - "WS", - "SM", - "ST", "SA", - "SN", - "RS", - "SC", - "SL", - "SK", + "SE", + "SG", "SI", - "SB", - "SO", - "ZA", - "KR", - "SS", - "ES", - "LK", - "SD", + "SK", + "SN", "SR", - "SE", - "CH", - "SY", - "TW", - "TJ", - "TZ", "TH", - "BS", - "GM", - "TL", - "TG", - "TO", - "TT", + "TJ", "TN", "TR", - "TM", - "UG", + "TT", + "TW", + "TZ", "UA", - "AE", - "GB", + "UG", "US", - "UY", "UZ", - "VU", - "VE", "VN", - "YE", + "ZA", "ZM", "ZW", ] diff --git a/src/cloudflare/resources/user/api.md b/src/cloudflare/resources/user/api.md index d241b0970e4..3ff3e0c9a61 100644 --- a/src/cloudflare/resources/user/api.md +++ b/src/cloudflare/resources/user/api.md @@ -103,9 +103,15 @@ Methods: ## Tenants +Types: + +```python +from cloudflare.types.user import TenantListResponse +``` + Methods: -- client.user.tenants.list() -> SyncSinglePage[Organization] +- client.user.tenants.list() -> SyncSinglePage[TenantListResponse] ## Tokens diff --git a/src/cloudflare/resources/user/tenants.py b/src/cloudflare/resources/user/tenants.py index 3f46301eb9f..47b0f650878 100644 --- a/src/cloudflare/resources/user/tenants.py +++ b/src/cloudflare/resources/user/tenants.py @@ -15,7 +15,7 @@ ) from ...pagination import SyncSinglePage, AsyncSinglePage from ..._base_client import AsyncPaginator, make_request_options -from ...types.organizations.organization import Organization +from ...types.user.tenant_list_response import TenantListResponse __all__ = ["TenantsResource", "AsyncTenantsResource"] @@ -49,15 +49,20 @@ def list( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> SyncSinglePage[Organization]: - """Retrieves list of tenants the authenticated user / method has access to.""" + ) -> SyncSinglePage[TenantListResponse]: + """ + Lists the Cloudflare tenants in which the authenticated user has direct + membership using the legacy Tenant response shape. Use `GET /organizations` to + list Organizations the user can access, including through hierarchy, using the + modern Organization response shape. + """ return self._get_api_list( "/user/tenants", - page=SyncSinglePage[Organization], + page=SyncSinglePage[TenantListResponse], options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), - model=Organization, + model=TenantListResponse, ) @@ -90,15 +95,20 @@ def list( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> AsyncPaginator[Organization, AsyncSinglePage[Organization]]: - """Retrieves list of tenants the authenticated user / method has access to.""" + ) -> AsyncPaginator[TenantListResponse, AsyncSinglePage[TenantListResponse]]: + """ + Lists the Cloudflare tenants in which the authenticated user has direct + membership using the legacy Tenant response shape. Use `GET /organizations` to + list Organizations the user can access, including through hierarchy, using the + modern Organization response shape. + """ return self._get_api_list( "/user/tenants", - page=AsyncSinglePage[Organization], + page=AsyncSinglePage[TenantListResponse], options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), - model=Organization, + model=TenantListResponse, ) diff --git a/src/cloudflare/resources/vectorize/api.md b/src/cloudflare/resources/vectorize/api.md index 70125007eba..4fbb0cc27d3 100644 --- a/src/cloudflare/resources/vectorize/api.md +++ b/src/cloudflare/resources/vectorize/api.md @@ -14,6 +14,7 @@ from cloudflare.types.vectorize import ( IndexUpsert, IndexDeleteResponse, IndexDeleteByIDsResponse, + IndexGetByIDsResponse, IndexInfoResponse, IndexInsertResponse, IndexListVectorsResponse, @@ -29,7 +30,7 @@ Methods: - client.vectorize.indexes.delete(index_name, \*, account_id) -> Optional[IndexDeleteResponse] - client.vectorize.indexes.delete_by_ids(index_name, \*, account_id, \*\*params) -> Optional[IndexDeleteByIDsResponse] - client.vectorize.indexes.get(index_name, \*, account_id) -> Optional[CreateIndex] -- client.vectorize.indexes.get_by_ids(index_name, \*, account_id, \*\*params) -> object +- client.vectorize.indexes.get_by_ids(index_name, \*, account_id, \*\*params) -> SyncSinglePage[IndexGetByIDsResponse] - client.vectorize.indexes.info(index_name, \*, account_id) -> Optional[IndexInfoResponse] - client.vectorize.indexes.insert(index_name, \*, account_id, \*\*params) -> Optional[IndexInsertResponse] - client.vectorize.indexes.list_vectors(index_name, \*, account_id, \*\*params) -> Optional[IndexListVectorsResponse] diff --git a/src/cloudflare/resources/vectorize/indexes/indexes.py b/src/cloudflare/resources/vectorize/indexes/indexes.py index d84f200ed70..dd8497f2873 100644 --- a/src/cloudflare/resources/vectorize/indexes/indexes.py +++ b/src/cloudflare/resources/vectorize/indexes/indexes.py @@ -53,6 +53,7 @@ from ....types.vectorize.index_delete_response import IndexDeleteResponse from ....types.vectorize.index_insert_response import IndexInsertResponse from ....types.vectorize.index_upsert_response import IndexUpsertResponse +from ....types.vectorize.index_get_by_ids_response import IndexGetByIDsResponse from ....types.vectorize.index_list_vectors_response import IndexListVectorsResponse from ....types.vectorize.index_delete_by_ids_response import IndexDeleteByIDsResponse @@ -330,7 +331,7 @@ def get_by_ids( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> object: + ) -> SyncSinglePage[IndexGetByIDsResponse]: """ Get a set of vectors from an index by their vector identifiers. @@ -351,21 +352,19 @@ def get_by_ids( raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") if not index_name: raise ValueError(f"Expected a non-empty value for `index_name` but received {index_name!r}") - return self._post( + return self._get_api_list( path_template( "/accounts/{account_id}/vectorize/v2/indexes/{index_name}/get_by_ids", account_id=account_id, index_name=index_name, ), + page=SyncSinglePage[IndexGetByIDsResponse], body=maybe_transform({"ids": ids}, index_get_by_ids_params.IndexGetByIDsParams), options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - post_parser=ResultWrapper[Optional[object]]._unwrapper, + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), - cast_to=cast(Type[object], ResultWrapper[object]), + model=IndexGetByIDsResponse, + method="post", ) def info( @@ -919,7 +918,7 @@ async def get( cast_to=cast(Type[Optional[CreateIndex]], ResultWrapper[CreateIndex]), ) - async def get_by_ids( + def get_by_ids( self, index_name: str, *, @@ -931,7 +930,7 @@ async def get_by_ids( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> object: + ) -> AsyncPaginator[IndexGetByIDsResponse, AsyncSinglePage[IndexGetByIDsResponse]]: """ Get a set of vectors from an index by their vector identifiers. @@ -952,21 +951,19 @@ async def get_by_ids( raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") if not index_name: raise ValueError(f"Expected a non-empty value for `index_name` but received {index_name!r}") - return await self._post( + return self._get_api_list( path_template( "/accounts/{account_id}/vectorize/v2/indexes/{index_name}/get_by_ids", account_id=account_id, index_name=index_name, ), - body=await async_maybe_transform({"ids": ids}, index_get_by_ids_params.IndexGetByIDsParams), + page=AsyncSinglePage[IndexGetByIDsResponse], + body=maybe_transform({"ids": ids}, index_get_by_ids_params.IndexGetByIDsParams), options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - post_parser=ResultWrapper[Optional[object]]._unwrapper, + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), - cast_to=cast(Type[object], ResultWrapper[object]), + model=IndexGetByIDsResponse, + method="post", ) async def info( diff --git a/src/cloudflare/resources/workers/api.md b/src/cloudflare/resources/workers/api.md index 0528f6c82f5..31f8b1f00c3 100644 --- a/src/cloudflare/resources/workers/api.md +++ b/src/cloudflare/resources/workers/api.md @@ -39,6 +39,7 @@ Methods: - client.workers.beta.workers.versions.list(worker_id, \*, account_id, \*\*params) -> SyncV4PagePaginationArray[Version] - client.workers.beta.workers.versions.delete(version_id, \*, account_id, worker_id) -> VersionDeleteResponse - client.workers.beta.workers.versions.get(version_id, \*, account_id, worker_id, \*\*params) -> Version +- client.workers.beta.workers.versions.profile(version_id, \*, account_id, worker_id, \*\*params) -> BinaryAPIResponse ## Routes diff --git a/src/cloudflare/resources/workers/beta/workers/versions.py b/src/cloudflare/resources/workers/beta/workers/versions.py index 166ccaef9fd..c751cd4f946 100644 --- a/src/cloudflare/resources/workers/beta/workers/versions.py +++ b/src/cloudflare/resources/workers/beta/workers/versions.py @@ -12,15 +12,28 @@ from ....._compat import cached_property from ....._resource import SyncAPIResource, AsyncAPIResource from ....._response import ( + BinaryAPIResponse, + AsyncBinaryAPIResponse, + StreamedBinaryAPIResponse, + AsyncStreamedBinaryAPIResponse, to_raw_response_wrapper, to_streamed_response_wrapper, async_to_raw_response_wrapper, + to_custom_raw_response_wrapper, async_to_streamed_response_wrapper, + to_custom_streamed_response_wrapper, + async_to_custom_raw_response_wrapper, + async_to_custom_streamed_response_wrapper, ) from ....._wrappers import ResultWrapper from .....pagination import SyncV4PagePaginationArray, AsyncV4PagePaginationArray from ....._base_client import AsyncPaginator, make_request_options -from .....types.workers.beta.workers import version_get_params, version_list_params, version_create_params +from .....types.workers.beta.workers import ( + version_get_params, + version_list_params, + version_create_params, + version_profile_params, +) from .....types.workers.beta.workers.version import Version from .....types.workers.beta.workers.version_delete_response import VersionDeleteResponse @@ -370,6 +383,85 @@ def get( cast_to=cast(Type[Version], ResultWrapper[Version]), ) + def profile( + self, + version_id: str, + *, + account_id: str, + worker_id: str, + duration_ms: int, + actor_id: str | Omit = omit, + namespace_id: str | Omit = omit, + profile_type: Literal["cpu", "heap"] | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> BinaryAPIResponse: + """ + Captures a CPU or heap profile from a recently active isolate running the + specified Worker version. This endpoint requires the Worker profiling feature to + be enabled for the account. + + Args: + account_id: Identifier. + + worker_id: Identifies the Worker by ID or name. + + version_id: Identifies the version by UUID or UUID prefix with a minimum length of eight + characters. Use "latest" to select the most recently created version, which may + not be deployed. Use "latest-deployed" to profile a version in the active + deployment. Versions are tried in order of traffic share until one has a loaded + isolate. + + duration_ms: Profile duration in milliseconds. + + actor_id: Identifies the exact Durable Object actor to profile. Must be specified together + with namespace_id. The actor must currently be active and running the requested + version. + + namespace_id: Identifies the Durable Object namespace containing the actor to profile. Must be + specified together with actor_id. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not worker_id: + raise ValueError(f"Expected a non-empty value for `worker_id` but received {worker_id!r}") + if not version_id: + raise ValueError(f"Expected a non-empty value for `version_id` but received {version_id!r}") + extra_headers = {"Accept": "application/vnd.google.protobuf", **(extra_headers or {})} + return self._post( + path_template( + "/accounts/{account_id}/workers/workers/{worker_id}/versions/{version_id}/profile", + account_id=account_id, + worker_id=worker_id, + version_id=version_id, + ), + body=maybe_transform( + { + "duration_ms": duration_ms, + "actor_id": actor_id, + "namespace_id": namespace_id, + "profile_type": profile_type, + }, + version_profile_params.VersionProfileParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=BinaryAPIResponse, + ) + class AsyncVersionsResource(AsyncAPIResource): @cached_property @@ -714,6 +806,85 @@ async def get( cast_to=cast(Type[Version], ResultWrapper[Version]), ) + async def profile( + self, + version_id: str, + *, + account_id: str, + worker_id: str, + duration_ms: int, + actor_id: str | Omit = omit, + namespace_id: str | Omit = omit, + profile_type: Literal["cpu", "heap"] | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> AsyncBinaryAPIResponse: + """ + Captures a CPU or heap profile from a recently active isolate running the + specified Worker version. This endpoint requires the Worker profiling feature to + be enabled for the account. + + Args: + account_id: Identifier. + + worker_id: Identifies the Worker by ID or name. + + version_id: Identifies the version by UUID or UUID prefix with a minimum length of eight + characters. Use "latest" to select the most recently created version, which may + not be deployed. Use "latest-deployed" to profile a version in the active + deployment. Versions are tried in order of traffic share until one has a loaded + isolate. + + duration_ms: Profile duration in milliseconds. + + actor_id: Identifies the exact Durable Object actor to profile. Must be specified together + with namespace_id. The actor must currently be active and running the requested + version. + + namespace_id: Identifies the Durable Object namespace containing the actor to profile. Must be + specified together with actor_id. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not worker_id: + raise ValueError(f"Expected a non-empty value for `worker_id` but received {worker_id!r}") + if not version_id: + raise ValueError(f"Expected a non-empty value for `version_id` but received {version_id!r}") + extra_headers = {"Accept": "application/vnd.google.protobuf", **(extra_headers or {})} + return await self._post( + path_template( + "/accounts/{account_id}/workers/workers/{worker_id}/versions/{version_id}/profile", + account_id=account_id, + worker_id=worker_id, + version_id=version_id, + ), + body=await async_maybe_transform( + { + "duration_ms": duration_ms, + "actor_id": actor_id, + "namespace_id": namespace_id, + "profile_type": profile_type, + }, + version_profile_params.VersionProfileParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=AsyncBinaryAPIResponse, + ) + class VersionsResourceWithRawResponse: def __init__(self, versions: VersionsResource) -> None: @@ -731,6 +902,10 @@ def __init__(self, versions: VersionsResource) -> None: self.get = to_raw_response_wrapper( versions.get, ) + self.profile = to_custom_raw_response_wrapper( + versions.profile, + BinaryAPIResponse, + ) class AsyncVersionsResourceWithRawResponse: @@ -749,6 +924,10 @@ def __init__(self, versions: AsyncVersionsResource) -> None: self.get = async_to_raw_response_wrapper( versions.get, ) + self.profile = async_to_custom_raw_response_wrapper( + versions.profile, + AsyncBinaryAPIResponse, + ) class VersionsResourceWithStreamingResponse: @@ -767,6 +946,10 @@ def __init__(self, versions: VersionsResource) -> None: self.get = to_streamed_response_wrapper( versions.get, ) + self.profile = to_custom_streamed_response_wrapper( + versions.profile, + StreamedBinaryAPIResponse, + ) class AsyncVersionsResourceWithStreamingResponse: @@ -785,3 +968,7 @@ def __init__(self, versions: AsyncVersionsResource) -> None: self.get = async_to_streamed_response_wrapper( versions.get, ) + self.profile = async_to_custom_streamed_response_wrapper( + versions.profile, + AsyncStreamedBinaryAPIResponse, + ) diff --git a/src/cloudflare/resources/workers/domains.py b/src/cloudflare/resources/workers/domains.py index b786628f8e8..93c638c4a01 100644 --- a/src/cloudflare/resources/workers/domains.py +++ b/src/cloudflare/resources/workers/domains.py @@ -54,6 +54,8 @@ def update( account_id: str, hostname: str, service: str, + enabled: bool | Omit = omit, + previews_enabled: bool | Omit = omit, zone_id: str | Omit = omit, zone_name: str | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -75,6 +77,18 @@ def update( service: Name of the Worker associated with the domain. Requests to the configured hostname will be routed to this Worker. + enabled: Whether the configured hostname is routable for the domain. If disabled, then + requests to the configured hostname will not be routed to the configured Worker. + If disabled, then preview routing must be enabled, and only subdomains of the + configured hostname will be routable. + + previews_enabled: Whether previews are routable for the domain. If enabled, previews will be + routable as subdomains of the configured hostname. For example, if the + configured hostname is `app.example.com`, then requests to + `my-feature.app.example.com` will be routed to the preview with slug + `my-feature`, if such a preview exists. If preview routing is disabled, then + hostname routing must be enabled. + zone_id: ID of the zone containing the domain hostname. zone_name: Name of the zone containing the domain hostname. @@ -95,6 +109,8 @@ def update( { "hostname": hostname, "service": service, + "enabled": enabled, + "previews_enabled": previews_enabled, "zone_id": zone_id, "zone_name": zone_name, }, @@ -114,8 +130,10 @@ def list( self, *, account_id: str, + enabled: bool | Omit = omit, environment: str | Omit = omit, hostname: str | Omit = omit, + previews_enabled: bool | Omit = omit, service: str | Omit = omit, zone_id: str | Omit = omit, zone_name: str | Omit = omit, @@ -132,10 +150,14 @@ def list( Args: account_id: Identifier. + enabled: Whether the configured hostname is routable for the domain. + environment: Worker environment associated with the domain. hostname: Hostname of the domain. + previews_enabled: Whether previews are routable for the domain. + service: Name of the Worker associated with the domain. zone_id: ID of the zone containing the domain hostname. @@ -162,8 +184,10 @@ def list( timeout=timeout, query=maybe_transform( { + "enabled": enabled, "environment": environment, "hostname": hostname, + "previews_enabled": previews_enabled, "service": service, "zone_id": zone_id, "zone_name": zone_name, @@ -291,6 +315,8 @@ async def update( account_id: str, hostname: str, service: str, + enabled: bool | Omit = omit, + previews_enabled: bool | Omit = omit, zone_id: str | Omit = omit, zone_name: str | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -312,6 +338,18 @@ async def update( service: Name of the Worker associated with the domain. Requests to the configured hostname will be routed to this Worker. + enabled: Whether the configured hostname is routable for the domain. If disabled, then + requests to the configured hostname will not be routed to the configured Worker. + If disabled, then preview routing must be enabled, and only subdomains of the + configured hostname will be routable. + + previews_enabled: Whether previews are routable for the domain. If enabled, previews will be + routable as subdomains of the configured hostname. For example, if the + configured hostname is `app.example.com`, then requests to + `my-feature.app.example.com` will be routed to the preview with slug + `my-feature`, if such a preview exists. If preview routing is disabled, then + hostname routing must be enabled. + zone_id: ID of the zone containing the domain hostname. zone_name: Name of the zone containing the domain hostname. @@ -332,6 +370,8 @@ async def update( { "hostname": hostname, "service": service, + "enabled": enabled, + "previews_enabled": previews_enabled, "zone_id": zone_id, "zone_name": zone_name, }, @@ -351,8 +391,10 @@ def list( self, *, account_id: str, + enabled: bool | Omit = omit, environment: str | Omit = omit, hostname: str | Omit = omit, + previews_enabled: bool | Omit = omit, service: str | Omit = omit, zone_id: str | Omit = omit, zone_name: str | Omit = omit, @@ -369,10 +411,14 @@ def list( Args: account_id: Identifier. + enabled: Whether the configured hostname is routable for the domain. + environment: Worker environment associated with the domain. hostname: Hostname of the domain. + previews_enabled: Whether previews are routable for the domain. + service: Name of the Worker associated with the domain. zone_id: ID of the zone containing the domain hostname. @@ -399,8 +445,10 @@ def list( timeout=timeout, query=maybe_transform( { + "enabled": enabled, "environment": environment, "hostname": hostname, + "previews_enabled": previews_enabled, "service": service, "zone_id": zone_id, "zone_name": zone_name, diff --git a/src/cloudflare/resources/workers/observability/destinations.py b/src/cloudflare/resources/workers/observability/destinations.py index e2b32c92d91..ab2b5314fd8 100644 --- a/src/cloudflare/resources/workers/observability/destinations.py +++ b/src/cloudflare/resources/workers/observability/destinations.py @@ -108,8 +108,8 @@ def update( slug: str, *, account_id: str, - configuration: destination_update_params.Configuration, enabled: bool, + configuration: destination_update_params.Configuration | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -139,8 +139,8 @@ def update( ), body=maybe_transform( { - "configuration": configuration, "enabled": enabled, + "configuration": configuration, }, destination_update_params.DestinationUpdateParams, ), @@ -322,8 +322,8 @@ async def update( slug: str, *, account_id: str, - configuration: destination_update_params.Configuration, enabled: bool, + configuration: destination_update_params.Configuration | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -353,8 +353,8 @@ async def update( ), body=await async_maybe_transform( { - "configuration": configuration, "enabled": enabled, + "configuration": configuration, }, destination_update_params.DestinationUpdateParams, ), diff --git a/src/cloudflare/resources/workers/scripts/deployments.py b/src/cloudflare/resources/workers/scripts/deployments.py index 4321cef9c2c..e1712a336b7 100644 --- a/src/cloudflare/resources/workers/scripts/deployments.py +++ b/src/cloudflare/resources/workers/scripts/deployments.py @@ -58,6 +58,7 @@ def create( versions: Iterable[deployment_create_params.Version], force: bool | Omit = omit, annotations: deployment_create_params.Annotations | Omit = omit, + code_update_strategy: deployment_create_params.CodeUpdateStrategy | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -76,6 +77,9 @@ def create( script_name: Name of the script. + strategy: Strategy for routing traffic across the listed versions. `percentage` splits + traffic according to each version's `percentage`. + versions: Worker versions included in this deployment. Each object must contain a `version_id` UUID and a `percentage`; percentages across all objects must total 100. In the `cf` CLI, pass the entire array as one JSON value to @@ -86,6 +90,11 @@ def create( force: If set to true, the deployment will be created even if normally blocked by something such rolling back to an older version when a secret has changed. + annotations: Metadata attached to the deployment. + + code_update_strategy: Choose whether to apply Durable Object code updates immediately or defer them. + When omitted, the default strategy applies. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -109,6 +118,7 @@ def create( "strategy": strategy, "versions": versions, "annotations": annotations, + "code_update_strategy": code_update_strategy, }, deployment_create_params.DeploymentCreateParams, ), @@ -326,6 +336,7 @@ async def create( versions: Iterable[deployment_create_params.Version], force: bool | Omit = omit, annotations: deployment_create_params.Annotations | Omit = omit, + code_update_strategy: deployment_create_params.CodeUpdateStrategy | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -344,6 +355,9 @@ async def create( script_name: Name of the script. + strategy: Strategy for routing traffic across the listed versions. `percentage` splits + traffic according to each version's `percentage`. + versions: Worker versions included in this deployment. Each object must contain a `version_id` UUID and a `percentage`; percentages across all objects must total 100. In the `cf` CLI, pass the entire array as one JSON value to @@ -354,6 +368,11 @@ async def create( force: If set to true, the deployment will be created even if normally blocked by something such rolling back to an older version when a secret has changed. + annotations: Metadata attached to the deployment. + + code_update_strategy: Choose whether to apply Durable Object code updates immediately or defer them. + When omitted, the default strategy applies. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -377,6 +396,7 @@ async def create( "strategy": strategy, "versions": versions, "annotations": annotations, + "code_update_strategy": code_update_strategy, }, deployment_create_params.DeploymentCreateParams, ), diff --git a/src/cloudflare/resources/workers/scripts/scripts.py b/src/cloudflare/resources/workers/scripts/scripts.py index 1f128936105..c257148815c 100644 --- a/src/cloudflare/resources/workers/scripts/scripts.py +++ b/src/cloudflare/resources/workers/scripts/scripts.py @@ -194,11 +194,21 @@ def update( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> ScriptUpdateResponse: - """Upload a worker module. + """Upload Worker code and configuration. - You can find more about the multipart metadata on our - docs: - https://developers.cloudflare.com/workers/configuration/multipart-upload-metadata/. + For ES module and other module-based + Workers, use `multipart/form-data` with a JSON `metadata` part whose + `main_module` field names the entrypoint file. Upload each module as a separate + file part; JavaScript ES module parts use the `application/javascript+module` + content type. + + Raw `application/javascript` and `text/javascript` request bodies accept only + legacy service-worker syntax using `addEventListener`. They do not accept ES + module syntax such as `export default`. To upload a module Worker, use the + multipart request format instead. + + Learn more about multipart metadata in the + [documentation](https://developers.cloudflare.com/workers/configuration/multipart-upload-metadata/). Args: account_id: Identifier. @@ -207,9 +217,10 @@ def update( metadata: JSON-encoded metadata about the uploaded parts and Worker configuration. - bindings_inherit: When set to "strict", the upload will fail if any `inherit` type bindings cannot - be resolved against the previous version of the Worker. Without this, - unresolvable inherit bindings are silently dropped. + bindings_inherit: When set to "strict", the upload will fail with error 10057 if any `inherit` + type bindings cannot be resolved against the latest uploaded version of the + Worker, which may not be the deployed version. Without this, unresolvable + inherit bindings are silently dropped. files: An array of modules (often JavaScript files) comprising a Worker script. At least one module must be present and referenced in the metadata as `main_module` @@ -544,11 +555,21 @@ async def update( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> ScriptUpdateResponse: - """Upload a worker module. + """Upload Worker code and configuration. + + For ES module and other module-based + Workers, use `multipart/form-data` with a JSON `metadata` part whose + `main_module` field names the entrypoint file. Upload each module as a separate + file part; JavaScript ES module parts use the `application/javascript+module` + content type. + + Raw `application/javascript` and `text/javascript` request bodies accept only + legacy service-worker syntax using `addEventListener`. They do not accept ES + module syntax such as `export default`. To upload a module Worker, use the + multipart request format instead. - You can find more about the multipart metadata on our - docs: - https://developers.cloudflare.com/workers/configuration/multipart-upload-metadata/. + Learn more about multipart metadata in the + [documentation](https://developers.cloudflare.com/workers/configuration/multipart-upload-metadata/). Args: account_id: Identifier. @@ -557,9 +578,10 @@ async def update( metadata: JSON-encoded metadata about the uploaded parts and Worker configuration. - bindings_inherit: When set to "strict", the upload will fail if any `inherit` type bindings cannot - be resolved against the previous version of the Worker. Without this, - unresolvable inherit bindings are silently dropped. + bindings_inherit: When set to "strict", the upload will fail with error 10057 if any `inherit` + type bindings cannot be resolved against the latest uploaded version of the + Worker, which may not be the deployed version. Without this, unresolvable + inherit bindings are silently dropped. files: An array of modules (often JavaScript files) comprising a Worker script. At least one module must be present and referenced in the metadata as `main_module` diff --git a/src/cloudflare/resources/workers/scripts/versions.py b/src/cloudflare/resources/workers/scripts/versions.py index 94877cc3cb8..72203a5ae24 100644 --- a/src/cloudflare/resources/workers/scripts/versions.py +++ b/src/cloudflare/resources/workers/scripts/versions.py @@ -87,9 +87,10 @@ def create( metadata: JSON-encoded metadata about the uploaded parts and Worker configuration. - bindings_inherit: When set to "strict", the upload will fail if any `inherit` type bindings cannot - be resolved against the previous version of the Worker. Without this, - unresolvable inherit bindings are silently dropped. + bindings_inherit: When set to "strict", the upload will fail with error 10057 if any `inherit` + type bindings cannot be resolved against the latest uploaded version of the + Worker, which may not be the deployed version. Without this, unresolvable + inherit bindings are silently dropped. files: An array of modules (often JavaScript files) comprising a Worker script. At least one module must be present and referenced in the metadata as `main_module` @@ -312,9 +313,10 @@ async def create( metadata: JSON-encoded metadata about the uploaded parts and Worker configuration. - bindings_inherit: When set to "strict", the upload will fail if any `inherit` type bindings cannot - be resolved against the previous version of the Worker. Without this, - unresolvable inherit bindings are silently dropped. + bindings_inherit: When set to "strict", the upload will fail with error 10057 if any `inherit` + type bindings cannot be resolved against the latest uploaded version of the + Worker, which may not be the deployed version. Without this, unresolvable + inherit bindings are silently dropped. files: An array of modules (often JavaScript files) comprising a Worker script. At least one module must be present and referenced in the metadata as `main_module` diff --git a/src/cloudflare/resources/workers_for_platforms/api.md b/src/cloudflare/resources/workers_for_platforms/api.md index 8db18ec6c6e..62798f7903f 100644 --- a/src/cloudflare/resources/workers_for_platforms/api.md +++ b/src/cloudflare/resources/workers_for_platforms/api.md @@ -113,6 +113,7 @@ Types: from cloudflare.types.workers_for_platforms.dispatch.namespaces.scripts import ( TagUpdateResponse, TagListResponse, + TagDeleteResponse, ) ``` @@ -120,4 +121,4 @@ Methods: - client.workers_for_platforms.dispatch.namespaces.scripts.tags.update(script_name, \*, account_id, dispatch_namespace, \*\*params) -> SyncSinglePage[TagUpdateResponse] - client.workers_for_platforms.dispatch.namespaces.scripts.tags.list(script_name, \*, account_id, dispatch_namespace) -> SyncSinglePage[TagListResponse] -- client.workers_for_platforms.dispatch.namespaces.scripts.tags.delete(tag, \*, account_id, dispatch_namespace, script_name) -> object +- client.workers_for_platforms.dispatch.namespaces.scripts.tags.delete(tag, \*, account_id, dispatch_namespace, script_name) -> TagDeleteResponse diff --git a/src/cloudflare/resources/workers_for_platforms/dispatch/namespaces/scripts/scripts.py b/src/cloudflare/resources/workers_for_platforms/dispatch/namespaces/scripts/scripts.py index 45ff7df3444..c5d67ee2921 100644 --- a/src/cloudflare/resources/workers_for_platforms/dispatch/namespaces/scripts/scripts.py +++ b/src/cloudflare/resources/workers_for_platforms/dispatch/namespaces/scripts/scripts.py @@ -145,11 +145,20 @@ def update( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> ScriptUpdateResponse: - """Upload a Workers for Platforms script module to a dispatch namespace. + """ + Upload Worker code and configuration to a Workers for Platforms dispatch + namespace. For ES module and other module-based Workers, use + `multipart/form-data` with a JSON `metadata` part whose `main_module` field + names the entrypoint file. Upload each module as a separate file part; + JavaScript ES module parts use the `application/javascript+module` content type. + + Raw `application/javascript` and `text/javascript` request bodies accept only + legacy service-worker syntax using `addEventListener`. They do not accept ES + module syntax such as `export default`. To upload a module Worker, use the + multipart request format instead. - You can - find more about the multipart metadata on our docs: - https://developers.cloudflare.com/workers/configuration/multipart-upload-metadata/. + Learn more about multipart metadata in the + [documentation](https://developers.cloudflare.com/workers/configuration/multipart-upload-metadata/). Args: account_id: Identifier. @@ -160,9 +169,10 @@ def update( metadata: JSON-encoded metadata about the uploaded parts and Worker configuration. - bindings_inherit: When set to "strict", the upload will fail if any `inherit` type bindings cannot - be resolved against the previous version of the script. Without this, - unresolvable inherit bindings are silently dropped. + bindings_inherit: When set to "strict", the upload will fail with error 10057 if any `inherit` + type bindings cannot be resolved against the latest uploaded version of the + script, which may not be the deployed version. Without this, unresolvable + inherit bindings are silently dropped. files: An array of modules (often JavaScript files) comprising a Worker script. At least one module must be present and referenced in the metadata as `main_module` @@ -398,11 +408,20 @@ async def update( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> ScriptUpdateResponse: - """Upload a Workers for Platforms script module to a dispatch namespace. + """ + Upload Worker code and configuration to a Workers for Platforms dispatch + namespace. For ES module and other module-based Workers, use + `multipart/form-data` with a JSON `metadata` part whose `main_module` field + names the entrypoint file. Upload each module as a separate file part; + JavaScript ES module parts use the `application/javascript+module` content type. + + Raw `application/javascript` and `text/javascript` request bodies accept only + legacy service-worker syntax using `addEventListener`. They do not accept ES + module syntax such as `export default`. To upload a module Worker, use the + multipart request format instead. - You can - find more about the multipart metadata on our docs: - https://developers.cloudflare.com/workers/configuration/multipart-upload-metadata/. + Learn more about multipart metadata in the + [documentation](https://developers.cloudflare.com/workers/configuration/multipart-upload-metadata/). Args: account_id: Identifier. @@ -413,9 +432,10 @@ async def update( metadata: JSON-encoded metadata about the uploaded parts and Worker configuration. - bindings_inherit: When set to "strict", the upload will fail if any `inherit` type bindings cannot - be resolved against the previous version of the script. Without this, - unresolvable inherit bindings are silently dropped. + bindings_inherit: When set to "strict", the upload will fail with error 10057 if any `inherit` + type bindings cannot be resolved against the latest uploaded version of the + script, which may not be the deployed version. Without this, unresolvable + inherit bindings are silently dropped. files: An array of modules (often JavaScript files) comprising a Worker script. At least one module must be present and referenced in the metadata as `main_module` diff --git a/src/cloudflare/resources/workers_for_platforms/dispatch/namespaces/scripts/tags.py b/src/cloudflare/resources/workers_for_platforms/dispatch/namespaces/scripts/tags.py index b8aa562d1a6..7550277c92e 100644 --- a/src/cloudflare/resources/workers_for_platforms/dispatch/namespaces/scripts/tags.py +++ b/src/cloudflare/resources/workers_for_platforms/dispatch/namespaces/scripts/tags.py @@ -2,12 +2,12 @@ from __future__ import annotations -from typing import Type, Optional, cast +from typing import Any, Optional, cast import httpx -from ......_types import Body, Query, Headers, NotGiven, SequenceNotStr, not_given -from ......_utils import path_template, maybe_transform +from ......_types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given +from ......_utils import path_template, maybe_transform, strip_not_given from ......_compat import cached_property from ......_resource import SyncAPIResource, AsyncAPIResource from ......_response import ( @@ -16,10 +16,10 @@ async_to_raw_response_wrapper, async_to_streamed_response_wrapper, ) -from ......_wrappers import ResultWrapper from ......pagination import SyncSinglePage, AsyncSinglePage from ......_base_client import AsyncPaginator, make_request_options from ......types.workers_for_platforms.dispatch.namespaces.scripts.tag_list_response import TagListResponse +from ......types.workers_for_platforms.dispatch.namespaces.scripts.tag_delete_response import TagDeleteResponse from ......types.workers_for_platforms.dispatch.namespaces.scripts.tag_update_response import TagUpdateResponse __all__ = ["TagsResource", "AsyncTagsResource"] @@ -160,17 +160,22 @@ def delete( account_id: str, dispatch_namespace: str, script_name: str, + api_version: str | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> object: + ) -> TagDeleteResponse: """ Delete a tag from a script uploaded to a Workers for Platforms dispatch namespace. + On `api-version` dates on or after `2026-10-01`, `tag` identifies a key and the + operation returns the complete updated tag map. Deleting a missing key succeeds. + Earlier versions retain the legacy string-tag behavior and return a null result. + Args: account_id: Identifier. @@ -178,6 +183,11 @@ def delete( script_name: Name of the script. + tag: A typed tag key containing only Unicode letters or numbers, underscores, + periods, or hyphens. The complete UTF-8 encoded tag (the key plus `=` and the + value when the value is non-empty) must not exceed 1024 bytes. + Cloudflare-reserved prefixes are not accepted. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -194,22 +204,22 @@ def delete( raise ValueError(f"Expected a non-empty value for `script_name` but received {script_name!r}") if not tag: raise ValueError(f"Expected a non-empty value for `tag` but received {tag!r}") - return self._delete( - path_template( - "/accounts/{account_id}/workers/dispatch/namespaces/{dispatch_namespace}/scripts/{script_name}/tags/{tag}", - account_id=account_id, - dispatch_namespace=dispatch_namespace, - script_name=script_name, - tag=tag, - ), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - post_parser=ResultWrapper[Optional[object]]._unwrapper, + extra_headers = {**strip_not_given({"api-version": api_version}), **(extra_headers or {})} + return cast( + TagDeleteResponse, + self._delete( + path_template( + "/accounts/{account_id}/workers/dispatch/namespaces/{dispatch_namespace}/scripts/{script_name}/tags/{tag}", + account_id=account_id, + dispatch_namespace=dispatch_namespace, + script_name=script_name, + tag=tag, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=cast(Any, TagDeleteResponse), # Union types cannot be passed in as arguments in the type system ), - cast_to=cast(Type[object], ResultWrapper[object]), ) @@ -348,17 +358,22 @@ async def delete( account_id: str, dispatch_namespace: str, script_name: str, + api_version: str | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> object: + ) -> TagDeleteResponse: """ Delete a tag from a script uploaded to a Workers for Platforms dispatch namespace. + On `api-version` dates on or after `2026-10-01`, `tag` identifies a key and the + operation returns the complete updated tag map. Deleting a missing key succeeds. + Earlier versions retain the legacy string-tag behavior and return a null result. + Args: account_id: Identifier. @@ -366,6 +381,11 @@ async def delete( script_name: Name of the script. + tag: A typed tag key containing only Unicode letters or numbers, underscores, + periods, or hyphens. The complete UTF-8 encoded tag (the key plus `=` and the + value when the value is non-empty) must not exceed 1024 bytes. + Cloudflare-reserved prefixes are not accepted. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -382,22 +402,22 @@ async def delete( raise ValueError(f"Expected a non-empty value for `script_name` but received {script_name!r}") if not tag: raise ValueError(f"Expected a non-empty value for `tag` but received {tag!r}") - return await self._delete( - path_template( - "/accounts/{account_id}/workers/dispatch/namespaces/{dispatch_namespace}/scripts/{script_name}/tags/{tag}", - account_id=account_id, - dispatch_namespace=dispatch_namespace, - script_name=script_name, - tag=tag, - ), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - post_parser=ResultWrapper[Optional[object]]._unwrapper, + extra_headers = {**strip_not_given({"api-version": api_version}), **(extra_headers or {})} + return cast( + TagDeleteResponse, + await self._delete( + path_template( + "/accounts/{account_id}/workers/dispatch/namespaces/{dispatch_namespace}/scripts/{script_name}/tags/{tag}", + account_id=account_id, + dispatch_namespace=dispatch_namespace, + script_name=script_name, + tag=tag, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=cast(Any, TagDeleteResponse), # Union types cannot be passed in as arguments in the type system ), - cast_to=cast(Type[object], ResultWrapper[object]), ) diff --git a/src/cloudflare/resources/workflows/workflows.py b/src/cloudflare/resources/workflows/workflows.py index d505b4b0a07..11135036343 100644 --- a/src/cloudflare/resources/workflows/workflows.py +++ b/src/cloudflare/resources/workflows/workflows.py @@ -3,6 +3,7 @@ from __future__ import annotations from typing import Type, Iterable, cast +from typing_extensions import Literal import httpx @@ -81,6 +82,7 @@ def update( script_name: str, concurrency: workflow_update_params.Concurrency | Omit = omit, default_retention: workflow_update_params.DefaultRetention | Omit = omit, + jurisdiction: Literal["eu", "fedramp", "us"] | Omit = omit, limits: workflow_update_params.Limits | Omit = omit, schedules: Iterable[workflow_update_params.Schedule] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -97,6 +99,10 @@ def update( default_retention: Default retention applied to instances of this version when they do not set their own retention. + jurisdiction: Jurisdiction where instances of this workflow run and store data. Can only be + set when the workflow is created and cannot be changed afterwards; omit it to + keep the existing jurisdiction. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -119,6 +125,7 @@ def update( "script_name": script_name, "concurrency": concurrency, "default_retention": default_retention, + "jurisdiction": jurisdiction, "limits": limits, "schedules": schedules, }, @@ -308,6 +315,7 @@ async def update( script_name: str, concurrency: workflow_update_params.Concurrency | Omit = omit, default_retention: workflow_update_params.DefaultRetention | Omit = omit, + jurisdiction: Literal["eu", "fedramp", "us"] | Omit = omit, limits: workflow_update_params.Limits | Omit = omit, schedules: Iterable[workflow_update_params.Schedule] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -324,6 +332,10 @@ async def update( default_retention: Default retention applied to instances of this version when they do not set their own retention. + jurisdiction: Jurisdiction where instances of this workflow run and store data. Can only be + set when the workflow is created and cannot be changed afterwards; omit it to + keep the existing jurisdiction. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -346,6 +358,7 @@ async def update( "script_name": script_name, "concurrency": concurrency, "default_retention": default_retention, + "jurisdiction": jurisdiction, "limits": limits, "schedules": schedules, }, diff --git a/src/cloudflare/resources/zero_trust/__init__.py b/src/cloudflare/resources/zero_trust/__init__.py index ccf9f997430..d136c3602cc 100644 --- a/src/cloudflare/resources/zero_trust/__init__.py +++ b/src/cloudflare/resources/zero_trust/__init__.py @@ -1,5 +1,13 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. +from .cws import ( + CWSResource, + AsyncCWSResource, + CWSResourceWithRawResponse, + AsyncCWSResourceWithRawResponse, + CWSResourceWithStreamingResponse, + AsyncCWSResourceWithStreamingResponse, +) from .dex import ( DEXResource, AsyncDEXResource, @@ -122,6 +130,12 @@ ) __all__ = [ + "CWSResource", + "AsyncCWSResource", + "CWSResourceWithRawResponse", + "AsyncCWSResourceWithRawResponse", + "CWSResourceWithStreamingResponse", + "AsyncCWSResourceWithStreamingResponse", "DevicesResource", "AsyncDevicesResource", "DevicesResourceWithRawResponse", diff --git a/src/cloudflare/resources/zero_trust/access/__init__.py b/src/cloudflare/resources/zero_trust/access/__init__.py index f8e1684a27b..0f3d0f897f3 100644 --- a/src/cloudflare/resources/zero_trust/access/__init__.py +++ b/src/cloudflare/resources/zero_trust/access/__init__.py @@ -1,5 +1,13 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. +from .mfa import ( + MfaResource, + AsyncMfaResource, + MfaResourceWithRawResponse, + AsyncMfaResourceWithRawResponse, + MfaResourceWithStreamingResponse, + AsyncMfaResourceWithStreamingResponse, +) from .keys import ( KeysResource, AsyncKeysResource, @@ -120,6 +128,14 @@ ServiceTokensResourceWithStreamingResponse, AsyncServiceTokensResourceWithStreamingResponse, ) +from .user_populations import ( + UserPopulationsResource, + AsyncUserPopulationsResource, + UserPopulationsResourceWithRawResponse, + AsyncUserPopulationsResourceWithRawResponse, + UserPopulationsResourceWithStreamingResponse, + AsyncUserPopulationsResourceWithStreamingResponse, +) from .saml_certificates import ( SAMLCertificatesResource, AsyncSAMLCertificatesResource, @@ -216,6 +232,18 @@ "AsyncUsersResourceWithRawResponse", "UsersResourceWithStreamingResponse", "AsyncUsersResourceWithStreamingResponse", + "UserPopulationsResource", + "AsyncUserPopulationsResource", + "UserPopulationsResourceWithRawResponse", + "AsyncUserPopulationsResourceWithRawResponse", + "UserPopulationsResourceWithStreamingResponse", + "AsyncUserPopulationsResourceWithStreamingResponse", + "MfaResource", + "AsyncMfaResource", + "MfaResourceWithRawResponse", + "AsyncMfaResourceWithRawResponse", + "MfaResourceWithStreamingResponse", + "AsyncMfaResourceWithStreamingResponse", "CustomPagesResource", "AsyncCustomPagesResource", "CustomPagesResourceWithRawResponse", diff --git a/src/cloudflare/resources/zero_trust/access/access.py b/src/cloudflare/resources/zero_trust/access/access.py index 9efd000a88a..de55751f886 100644 --- a/src/cloudflare/resources/zero_trust/access/access.py +++ b/src/cloudflare/resources/zero_trust/access/access.py @@ -26,6 +26,14 @@ GroupsResourceWithStreamingResponse, AsyncGroupsResourceWithStreamingResponse, ) +from .mfa.mfa import ( + MfaResource, + AsyncMfaResource, + MfaResourceWithRawResponse, + AsyncMfaResourceWithRawResponse, + MfaResourceWithStreamingResponse, + AsyncMfaResourceWithStreamingResponse, +) from .policies import ( PoliciesResource, AsyncPoliciesResource, @@ -132,6 +140,14 @@ InfrastructureResourceWithStreamingResponse, AsyncInfrastructureResourceWithStreamingResponse, ) +from .user_populations.user_populations import ( + UserPopulationsResource, + AsyncUserPopulationsResource, + UserPopulationsResourceWithRawResponse, + AsyncUserPopulationsResourceWithRawResponse, + UserPopulationsResourceWithStreamingResponse, + AsyncUserPopulationsResourceWithStreamingResponse, +) __all__ = ["AccessResource", "AsyncAccessResource"] @@ -189,6 +205,14 @@ def logs(self) -> LogsResource: def users(self) -> UsersResource: return UsersResource(self._client) + @cached_property + def user_populations(self) -> UserPopulationsResource: + return UserPopulationsResource(self._client) + + @cached_property + def mfa(self) -> MfaResource: + return MfaResource(self._client) + @cached_property def custom_pages(self) -> CustomPagesResource: return CustomPagesResource(self._client) @@ -274,6 +298,14 @@ def logs(self) -> AsyncLogsResource: def users(self) -> AsyncUsersResource: return AsyncUsersResource(self._client) + @cached_property + def user_populations(self) -> AsyncUserPopulationsResource: + return AsyncUserPopulationsResource(self._client) + + @cached_property + def mfa(self) -> AsyncMfaResource: + return AsyncMfaResource(self._client) + @cached_property def custom_pages(self) -> AsyncCustomPagesResource: return AsyncCustomPagesResource(self._client) @@ -362,6 +394,14 @@ def logs(self) -> LogsResourceWithRawResponse: def users(self) -> UsersResourceWithRawResponse: return UsersResourceWithRawResponse(self._access.users) + @cached_property + def user_populations(self) -> UserPopulationsResourceWithRawResponse: + return UserPopulationsResourceWithRawResponse(self._access.user_populations) + + @cached_property + def mfa(self) -> MfaResourceWithRawResponse: + return MfaResourceWithRawResponse(self._access.mfa) + @cached_property def custom_pages(self) -> CustomPagesResourceWithRawResponse: return CustomPagesResourceWithRawResponse(self._access.custom_pages) @@ -431,6 +471,14 @@ def logs(self) -> AsyncLogsResourceWithRawResponse: def users(self) -> AsyncUsersResourceWithRawResponse: return AsyncUsersResourceWithRawResponse(self._access.users) + @cached_property + def user_populations(self) -> AsyncUserPopulationsResourceWithRawResponse: + return AsyncUserPopulationsResourceWithRawResponse(self._access.user_populations) + + @cached_property + def mfa(self) -> AsyncMfaResourceWithRawResponse: + return AsyncMfaResourceWithRawResponse(self._access.mfa) + @cached_property def custom_pages(self) -> AsyncCustomPagesResourceWithRawResponse: return AsyncCustomPagesResourceWithRawResponse(self._access.custom_pages) @@ -500,6 +548,14 @@ def logs(self) -> LogsResourceWithStreamingResponse: def users(self) -> UsersResourceWithStreamingResponse: return UsersResourceWithStreamingResponse(self._access.users) + @cached_property + def user_populations(self) -> UserPopulationsResourceWithStreamingResponse: + return UserPopulationsResourceWithStreamingResponse(self._access.user_populations) + + @cached_property + def mfa(self) -> MfaResourceWithStreamingResponse: + return MfaResourceWithStreamingResponse(self._access.mfa) + @cached_property def custom_pages(self) -> CustomPagesResourceWithStreamingResponse: return CustomPagesResourceWithStreamingResponse(self._access.custom_pages) @@ -569,6 +625,14 @@ def logs(self) -> AsyncLogsResourceWithStreamingResponse: def users(self) -> AsyncUsersResourceWithStreamingResponse: return AsyncUsersResourceWithStreamingResponse(self._access.users) + @cached_property + def user_populations(self) -> AsyncUserPopulationsResourceWithStreamingResponse: + return AsyncUserPopulationsResourceWithStreamingResponse(self._access.user_populations) + + @cached_property + def mfa(self) -> AsyncMfaResourceWithStreamingResponse: + return AsyncMfaResourceWithStreamingResponse(self._access.mfa) + @cached_property def custom_pages(self) -> AsyncCustomPagesResourceWithStreamingResponse: return AsyncCustomPagesResourceWithStreamingResponse(self._access.custom_pages) diff --git a/src/cloudflare/resources/zero_trust/access/ai_controls/mcp/servers.py b/src/cloudflare/resources/zero_trust/access/ai_controls/mcp/servers.py index 8eafc50c2fe..1fb59bd0228 100644 --- a/src/cloudflare/resources/zero_trust/access/ai_controls/mcp/servers.py +++ b/src/cloudflare/resources/zero_trust/access/ai_controls/mcp/servers.py @@ -85,23 +85,35 @@ def create( name: Display name for the MCP server. - auth_credentials: Static credential for the upstream MCP server. For auth_type "bearer", either a - raw token string (e.g. "sk-abc123"), which is wrapped server-side as + auth_credentials: Credential configuration for the upstream MCP server. For auth_type "bearer", + either a raw token string (e.g. "sk-abc123"), which is wrapped server-side as `Authorization: Bearer `, or a JSON-encoded object of the form `{"headers":{"Header-Name":"value",...}}` for custom or multiple static headers (e.g. Cloudflare Access service tokens: `{"headers":{"cf-access-client-id":"...","cf-access-client-secret":"..."}}`). - - client_secret: Pre-registered OAuth client_secret. Write-only - accepted on create/update when - auth_credentials.auth_mode is 'manual'. Stored AES-GCM-encrypted in - server_oauth_secrets; never returned by read endpoints. + For auth_type "oauth" with a pre-registered client, send a JSON-encoded object + containing `auth_mode:"manual"`, `config.authorization_endpoint`, + `config.token_endpoint`, and `registration_info.client_id`. Also provide + `registration_info.redirect_uris` unless `is_shared_oauth_callback_enabled` is + true. Optional fields include `config.issuer`, `config.revocation_endpoint`, + `registration_info.scope`, and `registration_info.token_endpoint_auth_method`. + Send the client secret in the separate `client_secret` field. Omit + `auth_credentials` on update to preserve the existing configuration. + + client_secret: Provides 'client_secret' for a pre-registered OAuth client. This field is + accepted on create or update only when 'auth_credentials.auth_mode' is 'manual'. + It is required when creating an MCP server with manual OAuth credentials or + changing an existing server to use manual OAuth credentials. Omit + 'client_secret' on update to preserve the existing secret. Provide a new + 'client_secret' to rotate the secret. The secret is never returned by read, + create, or update requests. description: Optional description of the MCP server. - is_shared_oauth_callback_enabled: When true, the gateway worker uses the shared Cloudflare-owned OAuth callback - endpoint as the redirect_uri for upstream on-behalf OAuth, instead of the - customer portal hostname. Defaults to false (off); opt in per server by setting - true. + is_shared_oauth_callback_enabled: When true, per-user authorization uses the shared Cloudflare callback URL as the + 'redirect_uri' instead of the portal callback URL. The default is false. Set + 'is_shared_oauth_callback_enabled' to true to enable the shared Cloudflare + callback URL for this MCP server. secure_web_gateway: Route outbound traffic to this MCP server through Zero Trust Secure Web Gateway. @@ -173,23 +185,35 @@ def update( Args: id: Unique identifier for the MCP server. - auth_credentials: Static credential for the upstream MCP server. For auth_type "bearer", either a - raw token string (e.g. "sk-abc123"), which is wrapped server-side as + auth_credentials: Credential configuration for the upstream MCP server. For auth_type "bearer", + either a raw token string (e.g. "sk-abc123"), which is wrapped server-side as `Authorization: Bearer `, or a JSON-encoded object of the form `{"headers":{"Header-Name":"value",...}}` for custom or multiple static headers (e.g. Cloudflare Access service tokens: `{"headers":{"cf-access-client-id":"...","cf-access-client-secret":"..."}}`). - - client_secret: Pre-registered OAuth client_secret. Write-only - accepted on create/update when - auth_credentials.auth_mode is 'manual'. Stored AES-GCM-encrypted in - server_oauth_secrets; never returned by read endpoints. + For auth_type "oauth" with a pre-registered client, send a JSON-encoded object + containing `auth_mode:"manual"`, `config.authorization_endpoint`, + `config.token_endpoint`, and `registration_info.client_id`. Also provide + `registration_info.redirect_uris` unless `is_shared_oauth_callback_enabled` is + true. Optional fields include `config.issuer`, `config.revocation_endpoint`, + `registration_info.scope`, and `registration_info.token_endpoint_auth_method`. + Send the client secret in the separate `client_secret` field. Omit + `auth_credentials` on update to preserve the existing configuration. + + client_secret: Provides 'client_secret' for a pre-registered OAuth client. This field is + accepted on create or update only when 'auth_credentials.auth_mode' is 'manual'. + It is required when creating an MCP server with manual OAuth credentials or + changing an existing server to use manual OAuth credentials. Omit + 'client_secret' on update to preserve the existing secret. Provide a new + 'client_secret' to rotate the secret. The secret is never returned by read, + create, or update requests. description: Optional description of the MCP server. - is_shared_oauth_callback_enabled: When true, the gateway worker uses the shared Cloudflare-owned OAuth callback - endpoint as the redirect_uri for upstream on-behalf OAuth, instead of the - customer portal hostname. Defaults to false (off); opt in per server by setting - true. + is_shared_oauth_callback_enabled: When true, per-user authorization uses the shared Cloudflare callback URL as the + 'redirect_uri' instead of the portal callback URL. The default is false. Set + 'is_shared_oauth_callback_enabled' to true to enable the shared Cloudflare + callback URL for this MCP server. name: Display name for the MCP server. @@ -470,23 +494,35 @@ async def create( name: Display name for the MCP server. - auth_credentials: Static credential for the upstream MCP server. For auth_type "bearer", either a - raw token string (e.g. "sk-abc123"), which is wrapped server-side as + auth_credentials: Credential configuration for the upstream MCP server. For auth_type "bearer", + either a raw token string (e.g. "sk-abc123"), which is wrapped server-side as `Authorization: Bearer `, or a JSON-encoded object of the form `{"headers":{"Header-Name":"value",...}}` for custom or multiple static headers (e.g. Cloudflare Access service tokens: `{"headers":{"cf-access-client-id":"...","cf-access-client-secret":"..."}}`). - - client_secret: Pre-registered OAuth client_secret. Write-only - accepted on create/update when - auth_credentials.auth_mode is 'manual'. Stored AES-GCM-encrypted in - server_oauth_secrets; never returned by read endpoints. + For auth_type "oauth" with a pre-registered client, send a JSON-encoded object + containing `auth_mode:"manual"`, `config.authorization_endpoint`, + `config.token_endpoint`, and `registration_info.client_id`. Also provide + `registration_info.redirect_uris` unless `is_shared_oauth_callback_enabled` is + true. Optional fields include `config.issuer`, `config.revocation_endpoint`, + `registration_info.scope`, and `registration_info.token_endpoint_auth_method`. + Send the client secret in the separate `client_secret` field. Omit + `auth_credentials` on update to preserve the existing configuration. + + client_secret: Provides 'client_secret' for a pre-registered OAuth client. This field is + accepted on create or update only when 'auth_credentials.auth_mode' is 'manual'. + It is required when creating an MCP server with manual OAuth credentials or + changing an existing server to use manual OAuth credentials. Omit + 'client_secret' on update to preserve the existing secret. Provide a new + 'client_secret' to rotate the secret. The secret is never returned by read, + create, or update requests. description: Optional description of the MCP server. - is_shared_oauth_callback_enabled: When true, the gateway worker uses the shared Cloudflare-owned OAuth callback - endpoint as the redirect_uri for upstream on-behalf OAuth, instead of the - customer portal hostname. Defaults to false (off); opt in per server by setting - true. + is_shared_oauth_callback_enabled: When true, per-user authorization uses the shared Cloudflare callback URL as the + 'redirect_uri' instead of the portal callback URL. The default is false. Set + 'is_shared_oauth_callback_enabled' to true to enable the shared Cloudflare + callback URL for this MCP server. secure_web_gateway: Route outbound traffic to this MCP server through Zero Trust Secure Web Gateway. @@ -558,23 +594,35 @@ async def update( Args: id: Unique identifier for the MCP server. - auth_credentials: Static credential for the upstream MCP server. For auth_type "bearer", either a - raw token string (e.g. "sk-abc123"), which is wrapped server-side as + auth_credentials: Credential configuration for the upstream MCP server. For auth_type "bearer", + either a raw token string (e.g. "sk-abc123"), which is wrapped server-side as `Authorization: Bearer `, or a JSON-encoded object of the form `{"headers":{"Header-Name":"value",...}}` for custom or multiple static headers (e.g. Cloudflare Access service tokens: `{"headers":{"cf-access-client-id":"...","cf-access-client-secret":"..."}}`). - - client_secret: Pre-registered OAuth client_secret. Write-only - accepted on create/update when - auth_credentials.auth_mode is 'manual'. Stored AES-GCM-encrypted in - server_oauth_secrets; never returned by read endpoints. + For auth_type "oauth" with a pre-registered client, send a JSON-encoded object + containing `auth_mode:"manual"`, `config.authorization_endpoint`, + `config.token_endpoint`, and `registration_info.client_id`. Also provide + `registration_info.redirect_uris` unless `is_shared_oauth_callback_enabled` is + true. Optional fields include `config.issuer`, `config.revocation_endpoint`, + `registration_info.scope`, and `registration_info.token_endpoint_auth_method`. + Send the client secret in the separate `client_secret` field. Omit + `auth_credentials` on update to preserve the existing configuration. + + client_secret: Provides 'client_secret' for a pre-registered OAuth client. This field is + accepted on create or update only when 'auth_credentials.auth_mode' is 'manual'. + It is required when creating an MCP server with manual OAuth credentials or + changing an existing server to use manual OAuth credentials. Omit + 'client_secret' on update to preserve the existing secret. Provide a new + 'client_secret' to rotate the secret. The secret is never returned by read, + create, or update requests. description: Optional description of the MCP server. - is_shared_oauth_callback_enabled: When true, the gateway worker uses the shared Cloudflare-owned OAuth callback - endpoint as the redirect_uri for upstream on-behalf OAuth, instead of the - customer portal hostname. Defaults to false (off); opt in per server by setting - true. + is_shared_oauth_callback_enabled: When true, per-user authorization uses the shared Cloudflare callback URL as the + 'redirect_uri' instead of the portal callback URL. The default is false. Set + 'is_shared_oauth_callback_enabled' to true to enable the shared Cloudflare + callback URL for this MCP server. name: Display name for the MCP server. diff --git a/src/cloudflare/resources/zero_trust/access/applications/applications.py b/src/cloudflare/resources/zero_trust/access/applications/applications.py index f6ee2e04de2..12e13d1fbad 100644 --- a/src/cloudflare/resources/zero_trust/access/applications/applications.py +++ b/src/cloudflare/resources/zero_trust/access/applications/applications.py @@ -121,6 +121,85 @@ def with_streaming_response(self) -> ApplicationsResourceWithStreamingResponse: """ return ApplicationsResourceWithStreamingResponse(self) + @overload + def create( + self, + *, + oauth_configuration: application_create_params.AccessEndUserPropsOAuthConfiguration, + type: Literal[ + "self_hosted", + "end_user", + "saas", + "ssh", + "vnc", + "app_launcher", + "warp", + "biso", + "bookmark", + "dash_sso", + "infrastructure", + "rdp", + "mcp", + "mcp_portal", + "proxy_endpoint", + ], + user_populations: SequenceNotStr[str], + account_id: str | Omit = omit, + zone_id: str | Omit = omit, + allowed_idps: SequenceNotStr[AllowedIdPs] | Omit = omit, + destinations: Iterable[application_create_params.AccessEndUserPropsDestination] | Omit = omit, + domain: str | Omit = omit, + name: str | Omit = omit, + self_hosted_domains: SequenceNotStr[SelfHostedDomains] | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> Optional[ApplicationCreateResponse]: + """ + Adds a new application to Access. + + Args: + oauth_configuration: **Beta:** Optional configuration for managing an OAuth authorization flow + controlled by Access. When set, Access will act as the OAuth authorization + server for this application. Only compatible with OAuth clients that support + [RFC 8707](https://datatracker.ietf.org/doc/html/rfc8707) (Resource Indicators + for OAuth 2.0). This feature is currently in beta. + + type: The application type. + + user_populations: The single user population associated with this application. + + account_id: The Account ID to use for this endpoint. Mutually exclusive with the Zone ID. + + zone_id: The Zone ID to use for this endpoint. Mutually exclusive with the Account ID. + + allowed_idps: The identity providers your users can select when connecting to this + application. Defaults to all IdPs configured in your account. + + destinations: Public hostname and Workers destinations secured by Access. + + domain: The primary hostname and path secured by Access. This domain will be displayed + if the app is visible in the App Launcher. + + name: The name of the application. + + self_hosted_domains: List of public domains that Access will secure. This field is deprecated in + favor of `destinations` and will be supported until **November 21, 2025.** If + `destinations` are provided, then `self_hosted_domains` will be ignored. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + ... + @overload def create( self, @@ -265,7 +344,7 @@ def create( session_duration: The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), ms, - s, m, h. Note: unsupported for infrastructure type applications. + s, m, h. skip_interstitial: Enables automatic authentication through cloudflared. @@ -363,6 +442,7 @@ def create( domain: str, type: Literal[ "self_hosted", + "end_user", "saas", "ssh", "vnc", @@ -515,7 +595,7 @@ def create( session_duration: The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), ms, - s, m, h. Note: unsupported for infrastructure type applications. + s, m, h. skip_interstitial: Enables automatic authentication through cloudflared. @@ -544,6 +624,7 @@ def create( domain: str, type: Literal[ "self_hosted", + "end_user", "saas", "ssh", "vnc", @@ -696,7 +777,7 @@ def create( session_duration: The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), ms, - s, m, h. Note: unsupported for infrastructure type applications. + s, m, h. skip_interstitial: Enables automatic authentication through cloudflared. @@ -724,6 +805,7 @@ def create( *, type: Literal[ "self_hosted", + "end_user", "saas", "ssh", "vnc", @@ -801,7 +883,7 @@ def create( session_duration: The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), ms, - s, m, h. Note: unsupported for infrastructure type applications. + s, m, h. skip_app_launcher_login_page: Determines when to skip the App Launcher landing page. @@ -867,7 +949,7 @@ def create( session_duration: The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), ms, - s, m, h. Note: unsupported for infrastructure type applications. + s, m, h. extra_headers: Send extra headers @@ -931,7 +1013,7 @@ def create( session_duration: The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), ms, - s, m, h. Note: unsupported for infrastructure type applications. + s, m, h. extra_headers: Send extra headers @@ -1002,7 +1084,7 @@ def create( session_duration: The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), ms, - s, m, h. Note: unsupported for infrastructure type applications. + s, m, h. extra_headers: Send extra headers @@ -1081,6 +1163,7 @@ def create( mfa_config: application_create_params.InfrastructureApplicationMfaConfig | Omit = omit, name: str | Omit = omit, policies: Iterable[application_create_params.InfrastructureApplicationPolicy] | Omit = omit, + session_duration: str | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -1105,6 +1188,10 @@ def create( policies: The policies that Access applies to the application. + session_duration: The maximum duration of a connection to this application's targets. Connections + are terminated once it elapses. Must be in the format `30m` or `2h45m`, in whole + seconds. Valid time units are: s, m, h. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -1260,7 +1347,7 @@ def create( session_duration: The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), ms, - s, m, h. Note: unsupported for infrastructure type applications. + s, m, h. skip_interstitial: Enables automatic authentication through cloudflared. @@ -1379,7 +1466,7 @@ def create( session_duration: The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), ms, - s, m, h. Note: unsupported for infrastructure type applications. + s, m, h. tags: The tags you want assigned to an application. Tags are used to filter applications in the App Launcher dashboard. @@ -1495,7 +1582,7 @@ def create( session_duration: The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), ms, - s, m, h. Note: unsupported for infrastructure type applications. + s, m, h. tags: The tags you want assigned to an application. Tags are used to filter applications in the App Launcher dashboard. @@ -1513,10 +1600,17 @@ def create( def create( self, *, - domain: str | Omit = omit, - type: ApplicationType - | Literal[ + oauth_configuration: application_create_params.AccessEndUserPropsOAuthConfiguration + | application_create_params.SelfHostedApplicationOAuthConfiguration + | application_create_params.BrowserSSHApplicationOAuthConfiguration + | application_create_params.BrowserVNCApplicationOAuthConfiguration + | application_create_params.BrowserRDPApplicationOAuthConfiguration + | application_create_params.McpServerApplicationOAuthConfiguration + | application_create_params.McpServerPortalApplicationOAuthConfiguration + | Omit = omit, + type: Literal[ "self_hosted", + "end_user", "saas", "ssh", "vnc", @@ -1531,12 +1625,25 @@ def create( "mcp_portal", "proxy_endpoint", ] + | ApplicationType | Omit = omit, + user_populations: SequenceNotStr[str] | Omit = omit, account_id: str | Omit = omit, zone_id: str | Omit = omit, + allowed_idps: SequenceNotStr[AllowedIdPs] | Omit = omit, + destinations: Iterable[application_create_params.AccessEndUserPropsDestination] + | Iterable[application_create_params.SelfHostedApplicationDestination] + | Iterable[application_create_params.BrowserSSHApplicationDestination] + | Iterable[application_create_params.BrowserVNCApplicationDestination] + | Iterable[application_create_params.BrowserRDPApplicationDestination] + | Iterable[application_create_params.McpServerApplicationDestination] + | Iterable[application_create_params.McpServerPortalApplicationDestination] + | Omit = omit, + domain: str | Omit = omit, + name: str | Omit = omit, + self_hosted_domains: SequenceNotStr[SelfHostedDomains] | Omit = omit, allow_authenticate_via_warp: bool | Omit = omit, allow_iframe: bool | Omit = omit, - allowed_idps: SequenceNotStr[AllowedIdPs] | Omit = omit, app_launcher_visible: bool | Omit = omit, auto_redirect_to_identity: bool | Omit = omit, cors_headers: CORSHeadersParam | Omit = omit, @@ -1544,13 +1651,6 @@ def create( custom_deny_url: str | Omit = omit, custom_non_identity_deny_url: str | Omit = omit, custom_pages: SequenceNotStr[str] | Omit = omit, - destinations: Iterable[application_create_params.SelfHostedApplicationDestination] - | Iterable[application_create_params.BrowserSSHApplicationDestination] - | Iterable[application_create_params.BrowserVNCApplicationDestination] - | Iterable[application_create_params.BrowserRDPApplicationDestination] - | Iterable[application_create_params.McpServerApplicationDestination] - | Iterable[application_create_params.McpServerPortalApplicationDestination] - | Omit = omit, eager_redirect_cookie_setting: bool | Omit = omit, enable_binding_cookie: bool | Omit = omit, http_only_cookie_attribute: bool | Omit = omit, @@ -1561,14 +1661,6 @@ def create( | application_create_params.InfrastructureApplicationMfaConfig | application_create_params.BrowserRDPApplicationMfaConfig | Omit = omit, - name: str | Omit = omit, - oauth_configuration: application_create_params.SelfHostedApplicationOAuthConfiguration - | application_create_params.BrowserSSHApplicationOAuthConfiguration - | application_create_params.BrowserVNCApplicationOAuthConfiguration - | application_create_params.BrowserRDPApplicationOAuthConfiguration - | application_create_params.McpServerApplicationOAuthConfiguration - | application_create_params.McpServerPortalApplicationOAuthConfiguration - | Omit = omit, options_preflight_bypass: bool | Omit = omit, path_cookie_attribute: bool | Omit = omit, policies: SequenceNotStr[application_create_params.SelfHostedApplicationPolicy] @@ -1595,7 +1687,6 @@ def create( | application_create_params.McpServerApplicationSCIMConfig | application_create_params.McpServerPortalApplicationSCIMConfig | Omit = omit, - self_hosted_domains: SequenceNotStr[SelfHostedDomains] | Omit = omit, service_auth_401_redirect: bool | Omit = omit, session_duration: str | Omit = omit, skip_interstitial: bool | Omit = omit, @@ -1640,11 +1731,16 @@ def create( ), body=maybe_transform( { - "domain": domain, + "oauth_configuration": oauth_configuration, "type": type, + "user_populations": user_populations, + "allowed_idps": allowed_idps, + "destinations": destinations, + "domain": domain, + "name": name, + "self_hosted_domains": self_hosted_domains, "allow_authenticate_via_warp": allow_authenticate_via_warp, "allow_iframe": allow_iframe, - "allowed_idps": allowed_idps, "app_launcher_visible": app_launcher_visible, "auto_redirect_to_identity": auto_redirect_to_identity, "cors_headers": cors_headers, @@ -1652,21 +1748,17 @@ def create( "custom_deny_url": custom_deny_url, "custom_non_identity_deny_url": custom_non_identity_deny_url, "custom_pages": custom_pages, - "destinations": destinations, "eager_redirect_cookie_setting": eager_redirect_cookie_setting, "enable_binding_cookie": enable_binding_cookie, "http_only_cookie_attribute": http_only_cookie_attribute, "logo_url": logo_url, "mfa_config": mfa_config, - "name": name, - "oauth_configuration": oauth_configuration, "options_preflight_bypass": options_preflight_bypass, "path_cookie_attribute": path_cookie_attribute, "policies": policies, "read_service_tokens_from_header": read_service_tokens_from_header, "same_site_cookie_attribute": same_site_cookie_attribute, "scim_config": scim_config, - "self_hosted_domains": self_hosted_domains, "service_auth_401_redirect": service_auth_401_redirect, "session_duration": session_duration, "skip_interstitial": skip_interstitial, @@ -1696,6 +1788,88 @@ def create( ), ) + @overload + def update( + self, + app_id: AppID, + *, + oauth_configuration: application_update_params.AccessEndUserPropsOAuthConfiguration, + type: Literal[ + "self_hosted", + "end_user", + "saas", + "ssh", + "vnc", + "app_launcher", + "warp", + "biso", + "bookmark", + "dash_sso", + "infrastructure", + "rdp", + "mcp", + "mcp_portal", + "proxy_endpoint", + ], + user_populations: SequenceNotStr[str], + account_id: str | Omit = omit, + zone_id: str | Omit = omit, + allowed_idps: SequenceNotStr[AllowedIdPs] | Omit = omit, + destinations: Iterable[application_update_params.AccessEndUserPropsDestination] | Omit = omit, + domain: str | Omit = omit, + name: str | Omit = omit, + self_hosted_domains: SequenceNotStr[SelfHostedDomains] | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> Optional[ApplicationUpdateResponse]: + """ + Updates an Access application. + + Args: + app_id: Identifier. + + oauth_configuration: **Beta:** Optional configuration for managing an OAuth authorization flow + controlled by Access. When set, Access will act as the OAuth authorization + server for this application. Only compatible with OAuth clients that support + [RFC 8707](https://datatracker.ietf.org/doc/html/rfc8707) (Resource Indicators + for OAuth 2.0). This feature is currently in beta. + + type: The application type. + + user_populations: The single user population associated with this application. + + account_id: The Account ID to use for this endpoint. Mutually exclusive with the Zone ID. + + zone_id: The Zone ID to use for this endpoint. Mutually exclusive with the Account ID. + + allowed_idps: The identity providers your users can select when connecting to this + application. Defaults to all IdPs configured in your account. + + destinations: Public hostname and Workers destinations secured by Access. + + domain: The primary hostname and path secured by Access. This domain will be displayed + if the app is visible in the App Launcher. + + name: The name of the application. + + self_hosted_domains: List of public domains that Access will secure. This field is deprecated in + favor of `destinations` and will be supported until **November 21, 2025.** If + `destinations` are provided, then `self_hosted_domains` will be ignored. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + ... + @overload def update( self, @@ -1843,7 +2017,7 @@ def update( session_duration: The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), ms, - s, m, h. Note: unsupported for infrastructure type applications. + s, m, h. skip_interstitial: Enables automatic authentication through cloudflared. @@ -1945,6 +2119,7 @@ def update( domain: str, type: Literal[ "self_hosted", + "end_user", "saas", "ssh", "vnc", @@ -2099,7 +2274,7 @@ def update( session_duration: The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), ms, - s, m, h. Note: unsupported for infrastructure type applications. + s, m, h. skip_interstitial: Enables automatic authentication through cloudflared. @@ -2129,6 +2304,7 @@ def update( domain: str, type: Literal[ "self_hosted", + "end_user", "saas", "ssh", "vnc", @@ -2283,7 +2459,7 @@ def update( session_duration: The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), ms, - s, m, h. Note: unsupported for infrastructure type applications. + s, m, h. skip_interstitial: Enables automatic authentication through cloudflared. @@ -2312,6 +2488,7 @@ def update( *, type: Literal[ "self_hosted", + "end_user", "saas", "ssh", "vnc", @@ -2391,7 +2568,7 @@ def update( session_duration: The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), ms, - s, m, h. Note: unsupported for infrastructure type applications. + s, m, h. skip_app_launcher_login_page: Determines when to skip the App Launcher landing page. @@ -2460,7 +2637,7 @@ def update( session_duration: The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), ms, - s, m, h. Note: unsupported for infrastructure type applications. + s, m, h. extra_headers: Send extra headers @@ -2527,7 +2704,7 @@ def update( session_duration: The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), ms, - s, m, h. Note: unsupported for infrastructure type applications. + s, m, h. extra_headers: Send extra headers @@ -2601,7 +2778,7 @@ def update( session_duration: The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), ms, - s, m, h. Note: unsupported for infrastructure type applications. + s, m, h. extra_headers: Send extra headers @@ -2684,6 +2861,7 @@ def update( mfa_config: application_update_params.InfrastructureApplicationMfaConfig | Omit = omit, name: str | Omit = omit, policies: Iterable[application_update_params.InfrastructureApplicationPolicy] | Omit = omit, + session_duration: str | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -2710,6 +2888,10 @@ def update( policies: The policies that Access applies to the application. + session_duration: The maximum duration of a connection to this application's targets. Connections + are terminated once it elapses. Must be in the format `30m` or `2h45m`, in whole + seconds. Valid time units are: s, m, h. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -2868,7 +3050,7 @@ def update( session_duration: The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), ms, - s, m, h. Note: unsupported for infrastructure type applications. + s, m, h. skip_interstitial: Enables automatic authentication through cloudflared. @@ -2990,7 +3172,7 @@ def update( session_duration: The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), ms, - s, m, h. Note: unsupported for infrastructure type applications. + s, m, h. tags: The tags you want assigned to an application. Tags are used to filter applications in the App Launcher dashboard. @@ -3109,7 +3291,7 @@ def update( session_duration: The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), ms, - s, m, h. Note: unsupported for infrastructure type applications. + s, m, h. tags: The tags you want assigned to an application. Tags are used to filter applications in the App Launcher dashboard. @@ -3128,10 +3310,17 @@ def update( self, app_id: AppID, *, - domain: str | Omit = omit, - type: ApplicationType - | Literal[ + oauth_configuration: application_update_params.AccessEndUserPropsOAuthConfiguration + | application_update_params.SelfHostedApplicationOAuthConfiguration + | application_update_params.BrowserSSHApplicationOAuthConfiguration + | application_update_params.BrowserVNCApplicationOAuthConfiguration + | application_update_params.BrowserRDPApplicationOAuthConfiguration + | application_update_params.McpServerApplicationOAuthConfiguration + | application_update_params.McpServerPortalApplicationOAuthConfiguration + | Omit = omit, + type: Literal[ "self_hosted", + "end_user", "saas", "ssh", "vnc", @@ -3146,12 +3335,25 @@ def update( "mcp_portal", "proxy_endpoint", ] + | ApplicationType | Omit = omit, + user_populations: SequenceNotStr[str] | Omit = omit, account_id: str | Omit = omit, zone_id: str | Omit = omit, + allowed_idps: SequenceNotStr[AllowedIdPs] | Omit = omit, + destinations: Iterable[application_update_params.AccessEndUserPropsDestination] + | Iterable[application_update_params.SelfHostedApplicationDestination] + | Iterable[application_update_params.BrowserSSHApplicationDestination] + | Iterable[application_update_params.BrowserVNCApplicationDestination] + | Iterable[application_update_params.BrowserRDPApplicationDestination] + | Iterable[application_update_params.McpServerApplicationDestination] + | Iterable[application_update_params.McpServerPortalApplicationDestination] + | Omit = omit, + domain: str | Omit = omit, + name: str | Omit = omit, + self_hosted_domains: SequenceNotStr[SelfHostedDomains] | Omit = omit, allow_authenticate_via_warp: bool | Omit = omit, allow_iframe: bool | Omit = omit, - allowed_idps: SequenceNotStr[AllowedIdPs] | Omit = omit, app_launcher_visible: bool | Omit = omit, auto_redirect_to_identity: bool | Omit = omit, cors_headers: CORSHeadersParam | Omit = omit, @@ -3159,13 +3361,6 @@ def update( custom_deny_url: str | Omit = omit, custom_non_identity_deny_url: str | Omit = omit, custom_pages: SequenceNotStr[str] | Omit = omit, - destinations: Iterable[application_update_params.SelfHostedApplicationDestination] - | Iterable[application_update_params.BrowserSSHApplicationDestination] - | Iterable[application_update_params.BrowserVNCApplicationDestination] - | Iterable[application_update_params.BrowserRDPApplicationDestination] - | Iterable[application_update_params.McpServerApplicationDestination] - | Iterable[application_update_params.McpServerPortalApplicationDestination] - | Omit = omit, eager_redirect_cookie_setting: bool | Omit = omit, enable_binding_cookie: bool | Omit = omit, http_only_cookie_attribute: bool | Omit = omit, @@ -3176,14 +3371,6 @@ def update( | application_update_params.InfrastructureApplicationMfaConfig | application_update_params.BrowserRDPApplicationMfaConfig | Omit = omit, - name: str | Omit = omit, - oauth_configuration: application_update_params.SelfHostedApplicationOAuthConfiguration - | application_update_params.BrowserSSHApplicationOAuthConfiguration - | application_update_params.BrowserVNCApplicationOAuthConfiguration - | application_update_params.BrowserRDPApplicationOAuthConfiguration - | application_update_params.McpServerApplicationOAuthConfiguration - | application_update_params.McpServerPortalApplicationOAuthConfiguration - | Omit = omit, options_preflight_bypass: bool | Omit = omit, path_cookie_attribute: bool | Omit = omit, policies: SequenceNotStr[application_update_params.SelfHostedApplicationPolicy] @@ -3210,7 +3397,6 @@ def update( | application_update_params.McpServerApplicationSCIMConfig | application_update_params.McpServerPortalApplicationSCIMConfig | Omit = omit, - self_hosted_domains: SequenceNotStr[SelfHostedDomains] | Omit = omit, service_auth_401_redirect: bool | Omit = omit, session_duration: str | Omit = omit, skip_interstitial: bool | Omit = omit, @@ -3258,11 +3444,16 @@ def update( ), body=maybe_transform( { - "domain": domain, + "oauth_configuration": oauth_configuration, "type": type, + "user_populations": user_populations, + "allowed_idps": allowed_idps, + "destinations": destinations, + "domain": domain, + "name": name, + "self_hosted_domains": self_hosted_domains, "allow_authenticate_via_warp": allow_authenticate_via_warp, "allow_iframe": allow_iframe, - "allowed_idps": allowed_idps, "app_launcher_visible": app_launcher_visible, "auto_redirect_to_identity": auto_redirect_to_identity, "cors_headers": cors_headers, @@ -3270,21 +3461,17 @@ def update( "custom_deny_url": custom_deny_url, "custom_non_identity_deny_url": custom_non_identity_deny_url, "custom_pages": custom_pages, - "destinations": destinations, "eager_redirect_cookie_setting": eager_redirect_cookie_setting, "enable_binding_cookie": enable_binding_cookie, "http_only_cookie_attribute": http_only_cookie_attribute, "logo_url": logo_url, "mfa_config": mfa_config, - "name": name, - "oauth_configuration": oauth_configuration, "options_preflight_bypass": options_preflight_bypass, "path_cookie_attribute": path_cookie_attribute, "policies": policies, "read_service_tokens_from_header": read_service_tokens_from_header, "same_site_cookie_attribute": same_site_cookie_attribute, "scim_config": scim_config, - "self_hosted_domains": self_hosted_domains, "service_auth_401_redirect": service_auth_401_redirect, "session_duration": session_duration, "skip_interstitial": skip_interstitial, @@ -3639,6 +3826,85 @@ def with_streaming_response(self) -> AsyncApplicationsResourceWithStreamingRespo """ return AsyncApplicationsResourceWithStreamingResponse(self) + @overload + async def create( + self, + *, + oauth_configuration: application_create_params.AccessEndUserPropsOAuthConfiguration, + type: Literal[ + "self_hosted", + "end_user", + "saas", + "ssh", + "vnc", + "app_launcher", + "warp", + "biso", + "bookmark", + "dash_sso", + "infrastructure", + "rdp", + "mcp", + "mcp_portal", + "proxy_endpoint", + ], + user_populations: SequenceNotStr[str], + account_id: str | Omit = omit, + zone_id: str | Omit = omit, + allowed_idps: SequenceNotStr[AllowedIdPs] | Omit = omit, + destinations: Iterable[application_create_params.AccessEndUserPropsDestination] | Omit = omit, + domain: str | Omit = omit, + name: str | Omit = omit, + self_hosted_domains: SequenceNotStr[SelfHostedDomains] | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> Optional[ApplicationCreateResponse]: + """ + Adds a new application to Access. + + Args: + oauth_configuration: **Beta:** Optional configuration for managing an OAuth authorization flow + controlled by Access. When set, Access will act as the OAuth authorization + server for this application. Only compatible with OAuth clients that support + [RFC 8707](https://datatracker.ietf.org/doc/html/rfc8707) (Resource Indicators + for OAuth 2.0). This feature is currently in beta. + + type: The application type. + + user_populations: The single user population associated with this application. + + account_id: The Account ID to use for this endpoint. Mutually exclusive with the Zone ID. + + zone_id: The Zone ID to use for this endpoint. Mutually exclusive with the Account ID. + + allowed_idps: The identity providers your users can select when connecting to this + application. Defaults to all IdPs configured in your account. + + destinations: Public hostname and Workers destinations secured by Access. + + domain: The primary hostname and path secured by Access. This domain will be displayed + if the app is visible in the App Launcher. + + name: The name of the application. + + self_hosted_domains: List of public domains that Access will secure. This field is deprecated in + favor of `destinations` and will be supported until **November 21, 2025.** If + `destinations` are provided, then `self_hosted_domains` will be ignored. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + ... + @overload async def create( self, @@ -3783,7 +4049,7 @@ async def create( session_duration: The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), ms, - s, m, h. Note: unsupported for infrastructure type applications. + s, m, h. skip_interstitial: Enables automatic authentication through cloudflared. @@ -3881,6 +4147,7 @@ async def create( domain: str, type: Literal[ "self_hosted", + "end_user", "saas", "ssh", "vnc", @@ -4033,7 +4300,7 @@ async def create( session_duration: The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), ms, - s, m, h. Note: unsupported for infrastructure type applications. + s, m, h. skip_interstitial: Enables automatic authentication through cloudflared. @@ -4062,6 +4329,7 @@ async def create( domain: str, type: Literal[ "self_hosted", + "end_user", "saas", "ssh", "vnc", @@ -4214,7 +4482,7 @@ async def create( session_duration: The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), ms, - s, m, h. Note: unsupported for infrastructure type applications. + s, m, h. skip_interstitial: Enables automatic authentication through cloudflared. @@ -4242,6 +4510,7 @@ async def create( *, type: Literal[ "self_hosted", + "end_user", "saas", "ssh", "vnc", @@ -4319,7 +4588,7 @@ async def create( session_duration: The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), ms, - s, m, h. Note: unsupported for infrastructure type applications. + s, m, h. skip_app_launcher_login_page: Determines when to skip the App Launcher landing page. @@ -4385,7 +4654,7 @@ async def create( session_duration: The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), ms, - s, m, h. Note: unsupported for infrastructure type applications. + s, m, h. extra_headers: Send extra headers @@ -4449,7 +4718,7 @@ async def create( session_duration: The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), ms, - s, m, h. Note: unsupported for infrastructure type applications. + s, m, h. extra_headers: Send extra headers @@ -4520,7 +4789,7 @@ async def create( session_duration: The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), ms, - s, m, h. Note: unsupported for infrastructure type applications. + s, m, h. extra_headers: Send extra headers @@ -4599,6 +4868,7 @@ async def create( mfa_config: application_create_params.InfrastructureApplicationMfaConfig | Omit = omit, name: str | Omit = omit, policies: Iterable[application_create_params.InfrastructureApplicationPolicy] | Omit = omit, + session_duration: str | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -4623,6 +4893,10 @@ async def create( policies: The policies that Access applies to the application. + session_duration: The maximum duration of a connection to this application's targets. Connections + are terminated once it elapses. Must be in the format `30m` or `2h45m`, in whole + seconds. Valid time units are: s, m, h. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -4778,7 +5052,7 @@ async def create( session_duration: The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), ms, - s, m, h. Note: unsupported for infrastructure type applications. + s, m, h. skip_interstitial: Enables automatic authentication through cloudflared. @@ -4897,7 +5171,7 @@ async def create( session_duration: The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), ms, - s, m, h. Note: unsupported for infrastructure type applications. + s, m, h. tags: The tags you want assigned to an application. Tags are used to filter applications in the App Launcher dashboard. @@ -5013,7 +5287,7 @@ async def create( session_duration: The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), ms, - s, m, h. Note: unsupported for infrastructure type applications. + s, m, h. tags: The tags you want assigned to an application. Tags are used to filter applications in the App Launcher dashboard. @@ -5031,10 +5305,17 @@ async def create( async def create( self, *, - domain: str | Omit = omit, - type: ApplicationType - | Literal[ + oauth_configuration: application_create_params.AccessEndUserPropsOAuthConfiguration + | application_create_params.SelfHostedApplicationOAuthConfiguration + | application_create_params.BrowserSSHApplicationOAuthConfiguration + | application_create_params.BrowserVNCApplicationOAuthConfiguration + | application_create_params.BrowserRDPApplicationOAuthConfiguration + | application_create_params.McpServerApplicationOAuthConfiguration + | application_create_params.McpServerPortalApplicationOAuthConfiguration + | Omit = omit, + type: Literal[ "self_hosted", + "end_user", "saas", "ssh", "vnc", @@ -5049,12 +5330,25 @@ async def create( "mcp_portal", "proxy_endpoint", ] + | ApplicationType | Omit = omit, + user_populations: SequenceNotStr[str] | Omit = omit, account_id: str | Omit = omit, zone_id: str | Omit = omit, + allowed_idps: SequenceNotStr[AllowedIdPs] | Omit = omit, + destinations: Iterable[application_create_params.AccessEndUserPropsDestination] + | Iterable[application_create_params.SelfHostedApplicationDestination] + | Iterable[application_create_params.BrowserSSHApplicationDestination] + | Iterable[application_create_params.BrowserVNCApplicationDestination] + | Iterable[application_create_params.BrowserRDPApplicationDestination] + | Iterable[application_create_params.McpServerApplicationDestination] + | Iterable[application_create_params.McpServerPortalApplicationDestination] + | Omit = omit, + domain: str | Omit = omit, + name: str | Omit = omit, + self_hosted_domains: SequenceNotStr[SelfHostedDomains] | Omit = omit, allow_authenticate_via_warp: bool | Omit = omit, allow_iframe: bool | Omit = omit, - allowed_idps: SequenceNotStr[AllowedIdPs] | Omit = omit, app_launcher_visible: bool | Omit = omit, auto_redirect_to_identity: bool | Omit = omit, cors_headers: CORSHeadersParam | Omit = omit, @@ -5062,13 +5356,6 @@ async def create( custom_deny_url: str | Omit = omit, custom_non_identity_deny_url: str | Omit = omit, custom_pages: SequenceNotStr[str] | Omit = omit, - destinations: Iterable[application_create_params.SelfHostedApplicationDestination] - | Iterable[application_create_params.BrowserSSHApplicationDestination] - | Iterable[application_create_params.BrowserVNCApplicationDestination] - | Iterable[application_create_params.BrowserRDPApplicationDestination] - | Iterable[application_create_params.McpServerApplicationDestination] - | Iterable[application_create_params.McpServerPortalApplicationDestination] - | Omit = omit, eager_redirect_cookie_setting: bool | Omit = omit, enable_binding_cookie: bool | Omit = omit, http_only_cookie_attribute: bool | Omit = omit, @@ -5079,14 +5366,6 @@ async def create( | application_create_params.InfrastructureApplicationMfaConfig | application_create_params.BrowserRDPApplicationMfaConfig | Omit = omit, - name: str | Omit = omit, - oauth_configuration: application_create_params.SelfHostedApplicationOAuthConfiguration - | application_create_params.BrowserSSHApplicationOAuthConfiguration - | application_create_params.BrowserVNCApplicationOAuthConfiguration - | application_create_params.BrowserRDPApplicationOAuthConfiguration - | application_create_params.McpServerApplicationOAuthConfiguration - | application_create_params.McpServerPortalApplicationOAuthConfiguration - | Omit = omit, options_preflight_bypass: bool | Omit = omit, path_cookie_attribute: bool | Omit = omit, policies: SequenceNotStr[application_create_params.SelfHostedApplicationPolicy] @@ -5113,7 +5392,6 @@ async def create( | application_create_params.McpServerApplicationSCIMConfig | application_create_params.McpServerPortalApplicationSCIMConfig | Omit = omit, - self_hosted_domains: SequenceNotStr[SelfHostedDomains] | Omit = omit, service_auth_401_redirect: bool | Omit = omit, session_duration: str | Omit = omit, skip_interstitial: bool | Omit = omit, @@ -5158,11 +5436,16 @@ async def create( ), body=await async_maybe_transform( { - "domain": domain, + "oauth_configuration": oauth_configuration, "type": type, + "user_populations": user_populations, + "allowed_idps": allowed_idps, + "destinations": destinations, + "domain": domain, + "name": name, + "self_hosted_domains": self_hosted_domains, "allow_authenticate_via_warp": allow_authenticate_via_warp, "allow_iframe": allow_iframe, - "allowed_idps": allowed_idps, "app_launcher_visible": app_launcher_visible, "auto_redirect_to_identity": auto_redirect_to_identity, "cors_headers": cors_headers, @@ -5170,21 +5453,17 @@ async def create( "custom_deny_url": custom_deny_url, "custom_non_identity_deny_url": custom_non_identity_deny_url, "custom_pages": custom_pages, - "destinations": destinations, "eager_redirect_cookie_setting": eager_redirect_cookie_setting, "enable_binding_cookie": enable_binding_cookie, "http_only_cookie_attribute": http_only_cookie_attribute, "logo_url": logo_url, "mfa_config": mfa_config, - "name": name, - "oauth_configuration": oauth_configuration, "options_preflight_bypass": options_preflight_bypass, "path_cookie_attribute": path_cookie_attribute, "policies": policies, "read_service_tokens_from_header": read_service_tokens_from_header, "same_site_cookie_attribute": same_site_cookie_attribute, "scim_config": scim_config, - "self_hosted_domains": self_hosted_domains, "service_auth_401_redirect": service_auth_401_redirect, "session_duration": session_duration, "skip_interstitial": skip_interstitial, @@ -5214,6 +5493,88 @@ async def create( ), ) + @overload + async def update( + self, + app_id: AppID, + *, + oauth_configuration: application_update_params.AccessEndUserPropsOAuthConfiguration, + type: Literal[ + "self_hosted", + "end_user", + "saas", + "ssh", + "vnc", + "app_launcher", + "warp", + "biso", + "bookmark", + "dash_sso", + "infrastructure", + "rdp", + "mcp", + "mcp_portal", + "proxy_endpoint", + ], + user_populations: SequenceNotStr[str], + account_id: str | Omit = omit, + zone_id: str | Omit = omit, + allowed_idps: SequenceNotStr[AllowedIdPs] | Omit = omit, + destinations: Iterable[application_update_params.AccessEndUserPropsDestination] | Omit = omit, + domain: str | Omit = omit, + name: str | Omit = omit, + self_hosted_domains: SequenceNotStr[SelfHostedDomains] | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> Optional[ApplicationUpdateResponse]: + """ + Updates an Access application. + + Args: + app_id: Identifier. + + oauth_configuration: **Beta:** Optional configuration for managing an OAuth authorization flow + controlled by Access. When set, Access will act as the OAuth authorization + server for this application. Only compatible with OAuth clients that support + [RFC 8707](https://datatracker.ietf.org/doc/html/rfc8707) (Resource Indicators + for OAuth 2.0). This feature is currently in beta. + + type: The application type. + + user_populations: The single user population associated with this application. + + account_id: The Account ID to use for this endpoint. Mutually exclusive with the Zone ID. + + zone_id: The Zone ID to use for this endpoint. Mutually exclusive with the Account ID. + + allowed_idps: The identity providers your users can select when connecting to this + application. Defaults to all IdPs configured in your account. + + destinations: Public hostname and Workers destinations secured by Access. + + domain: The primary hostname and path secured by Access. This domain will be displayed + if the app is visible in the App Launcher. + + name: The name of the application. + + self_hosted_domains: List of public domains that Access will secure. This field is deprecated in + favor of `destinations` and will be supported until **November 21, 2025.** If + `destinations` are provided, then `self_hosted_domains` will be ignored. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + ... + @overload async def update( self, @@ -5361,7 +5722,7 @@ async def update( session_duration: The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), ms, - s, m, h. Note: unsupported for infrastructure type applications. + s, m, h. skip_interstitial: Enables automatic authentication through cloudflared. @@ -5463,6 +5824,7 @@ async def update( domain: str, type: Literal[ "self_hosted", + "end_user", "saas", "ssh", "vnc", @@ -5617,7 +5979,7 @@ async def update( session_duration: The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), ms, - s, m, h. Note: unsupported for infrastructure type applications. + s, m, h. skip_interstitial: Enables automatic authentication through cloudflared. @@ -5647,6 +6009,7 @@ async def update( domain: str, type: Literal[ "self_hosted", + "end_user", "saas", "ssh", "vnc", @@ -5801,7 +6164,7 @@ async def update( session_duration: The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), ms, - s, m, h. Note: unsupported for infrastructure type applications. + s, m, h. skip_interstitial: Enables automatic authentication through cloudflared. @@ -5830,6 +6193,7 @@ async def update( *, type: Literal[ "self_hosted", + "end_user", "saas", "ssh", "vnc", @@ -5909,7 +6273,7 @@ async def update( session_duration: The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), ms, - s, m, h. Note: unsupported for infrastructure type applications. + s, m, h. skip_app_launcher_login_page: Determines when to skip the App Launcher landing page. @@ -5978,7 +6342,7 @@ async def update( session_duration: The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), ms, - s, m, h. Note: unsupported for infrastructure type applications. + s, m, h. extra_headers: Send extra headers @@ -6045,7 +6409,7 @@ async def update( session_duration: The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), ms, - s, m, h. Note: unsupported for infrastructure type applications. + s, m, h. extra_headers: Send extra headers @@ -6119,7 +6483,7 @@ async def update( session_duration: The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), ms, - s, m, h. Note: unsupported for infrastructure type applications. + s, m, h. extra_headers: Send extra headers @@ -6202,6 +6566,7 @@ async def update( mfa_config: application_update_params.InfrastructureApplicationMfaConfig | Omit = omit, name: str | Omit = omit, policies: Iterable[application_update_params.InfrastructureApplicationPolicy] | Omit = omit, + session_duration: str | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -6228,6 +6593,10 @@ async def update( policies: The policies that Access applies to the application. + session_duration: The maximum duration of a connection to this application's targets. Connections + are terminated once it elapses. Must be in the format `30m` or `2h45m`, in whole + seconds. Valid time units are: s, m, h. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -6386,7 +6755,7 @@ async def update( session_duration: The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), ms, - s, m, h. Note: unsupported for infrastructure type applications. + s, m, h. skip_interstitial: Enables automatic authentication through cloudflared. @@ -6508,7 +6877,7 @@ async def update( session_duration: The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), ms, - s, m, h. Note: unsupported for infrastructure type applications. + s, m, h. tags: The tags you want assigned to an application. Tags are used to filter applications in the App Launcher dashboard. @@ -6627,7 +6996,7 @@ async def update( session_duration: The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), ms, - s, m, h. Note: unsupported for infrastructure type applications. + s, m, h. tags: The tags you want assigned to an application. Tags are used to filter applications in the App Launcher dashboard. @@ -6646,10 +7015,17 @@ async def update( self, app_id: AppID, *, - domain: str | Omit = omit, - type: ApplicationType - | Literal[ + oauth_configuration: application_update_params.AccessEndUserPropsOAuthConfiguration + | application_update_params.SelfHostedApplicationOAuthConfiguration + | application_update_params.BrowserSSHApplicationOAuthConfiguration + | application_update_params.BrowserVNCApplicationOAuthConfiguration + | application_update_params.BrowserRDPApplicationOAuthConfiguration + | application_update_params.McpServerApplicationOAuthConfiguration + | application_update_params.McpServerPortalApplicationOAuthConfiguration + | Omit = omit, + type: Literal[ "self_hosted", + "end_user", "saas", "ssh", "vnc", @@ -6664,12 +7040,25 @@ async def update( "mcp_portal", "proxy_endpoint", ] + | ApplicationType | Omit = omit, + user_populations: SequenceNotStr[str] | Omit = omit, account_id: str | Omit = omit, zone_id: str | Omit = omit, + allowed_idps: SequenceNotStr[AllowedIdPs] | Omit = omit, + destinations: Iterable[application_update_params.AccessEndUserPropsDestination] + | Iterable[application_update_params.SelfHostedApplicationDestination] + | Iterable[application_update_params.BrowserSSHApplicationDestination] + | Iterable[application_update_params.BrowserVNCApplicationDestination] + | Iterable[application_update_params.BrowserRDPApplicationDestination] + | Iterable[application_update_params.McpServerApplicationDestination] + | Iterable[application_update_params.McpServerPortalApplicationDestination] + | Omit = omit, + domain: str | Omit = omit, + name: str | Omit = omit, + self_hosted_domains: SequenceNotStr[SelfHostedDomains] | Omit = omit, allow_authenticate_via_warp: bool | Omit = omit, allow_iframe: bool | Omit = omit, - allowed_idps: SequenceNotStr[AllowedIdPs] | Omit = omit, app_launcher_visible: bool | Omit = omit, auto_redirect_to_identity: bool | Omit = omit, cors_headers: CORSHeadersParam | Omit = omit, @@ -6677,13 +7066,6 @@ async def update( custom_deny_url: str | Omit = omit, custom_non_identity_deny_url: str | Omit = omit, custom_pages: SequenceNotStr[str] | Omit = omit, - destinations: Iterable[application_update_params.SelfHostedApplicationDestination] - | Iterable[application_update_params.BrowserSSHApplicationDestination] - | Iterable[application_update_params.BrowserVNCApplicationDestination] - | Iterable[application_update_params.BrowserRDPApplicationDestination] - | Iterable[application_update_params.McpServerApplicationDestination] - | Iterable[application_update_params.McpServerPortalApplicationDestination] - | Omit = omit, eager_redirect_cookie_setting: bool | Omit = omit, enable_binding_cookie: bool | Omit = omit, http_only_cookie_attribute: bool | Omit = omit, @@ -6694,14 +7076,6 @@ async def update( | application_update_params.InfrastructureApplicationMfaConfig | application_update_params.BrowserRDPApplicationMfaConfig | Omit = omit, - name: str | Omit = omit, - oauth_configuration: application_update_params.SelfHostedApplicationOAuthConfiguration - | application_update_params.BrowserSSHApplicationOAuthConfiguration - | application_update_params.BrowserVNCApplicationOAuthConfiguration - | application_update_params.BrowserRDPApplicationOAuthConfiguration - | application_update_params.McpServerApplicationOAuthConfiguration - | application_update_params.McpServerPortalApplicationOAuthConfiguration - | Omit = omit, options_preflight_bypass: bool | Omit = omit, path_cookie_attribute: bool | Omit = omit, policies: SequenceNotStr[application_update_params.SelfHostedApplicationPolicy] @@ -6728,7 +7102,6 @@ async def update( | application_update_params.McpServerApplicationSCIMConfig | application_update_params.McpServerPortalApplicationSCIMConfig | Omit = omit, - self_hosted_domains: SequenceNotStr[SelfHostedDomains] | Omit = omit, service_auth_401_redirect: bool | Omit = omit, session_duration: str | Omit = omit, skip_interstitial: bool | Omit = omit, @@ -6776,11 +7149,16 @@ async def update( ), body=await async_maybe_transform( { - "domain": domain, + "oauth_configuration": oauth_configuration, "type": type, + "user_populations": user_populations, + "allowed_idps": allowed_idps, + "destinations": destinations, + "domain": domain, + "name": name, + "self_hosted_domains": self_hosted_domains, "allow_authenticate_via_warp": allow_authenticate_via_warp, "allow_iframe": allow_iframe, - "allowed_idps": allowed_idps, "app_launcher_visible": app_launcher_visible, "auto_redirect_to_identity": auto_redirect_to_identity, "cors_headers": cors_headers, @@ -6788,21 +7166,17 @@ async def update( "custom_deny_url": custom_deny_url, "custom_non_identity_deny_url": custom_non_identity_deny_url, "custom_pages": custom_pages, - "destinations": destinations, "eager_redirect_cookie_setting": eager_redirect_cookie_setting, "enable_binding_cookie": enable_binding_cookie, "http_only_cookie_attribute": http_only_cookie_attribute, "logo_url": logo_url, "mfa_config": mfa_config, - "name": name, - "oauth_configuration": oauth_configuration, "options_preflight_bypass": options_preflight_bypass, "path_cookie_attribute": path_cookie_attribute, "policies": policies, "read_service_tokens_from_header": read_service_tokens_from_header, "same_site_cookie_attribute": same_site_cookie_attribute, "scim_config": scim_config, - "self_hosted_domains": self_hosted_domains, "service_auth_401_redirect": service_auth_401_redirect, "session_duration": session_duration, "skip_interstitial": skip_interstitial, diff --git a/src/cloudflare/resources/zero_trust/access/applications/policies.py b/src/cloudflare/resources/zero_trust/access/applications/policies.py index 427699cd72b..1c1f3591537 100644 --- a/src/cloudflare/resources/zero_trust/access/applications/policies.py +++ b/src/cloudflare/resources/zero_trust/access/applications/policies.py @@ -138,6 +138,7 @@ def create( connection_rules: policy_create_params.AccessInfraPolicyReqConnectionRules | Omit = omit, exclude: Iterable[AccessRuleParam] | Omit = omit, mfa_config: policy_create_params.AccessInfraPolicyReqMfaConfig | Omit = omit, + policy_resolution_account_id: str | Omit = omit, require: Iterable[AccessRuleParam] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. @@ -176,6 +177,10 @@ def create( mfa_config: Configures multi-factor authentication (MFA) settings for infrastructure applications. + policy_resolution_account_id: The account ID used to resolve policy resources and identity for cross-account + WARP authentication. The account must be trusted by the account that owns this + policy. + require: Rules evaluated with an AND logical operator. To match the policy, a user must meet all of the Require rules. @@ -212,6 +217,7 @@ def create( include: Iterable[AccessRuleParam] | Omit = omit, name: str | Omit = omit, exclude: Iterable[AccessRuleParam] | Omit = omit, + policy_resolution_account_id: str | Omit = omit, require: Iterable[AccessRuleParam] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. @@ -258,6 +264,7 @@ def create( "include": include, "name": name, "exclude": exclude, + "policy_resolution_account_id": policy_resolution_account_id, "require": require, }, policy_create_params.PolicyCreateParams, @@ -362,6 +369,7 @@ def update( connection_rules: policy_update_params.AccessInfraPolicyReqConnectionRules | Omit = omit, exclude: Iterable[AccessRuleParam] | Omit = omit, mfa_config: policy_update_params.AccessInfraPolicyReqMfaConfig | Omit = omit, + policy_resolution_account_id: str | Omit = omit, require: Iterable[AccessRuleParam] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. @@ -401,6 +409,10 @@ def update( mfa_config: Configures multi-factor authentication (MFA) settings for infrastructure applications. + policy_resolution_account_id: The account ID used to resolve policy resources and identity for cross-account + WARP authentication. The account must be trusted by the account that owns this + policy. + require: Rules evaluated with an AND logical operator. To match the policy, a user must meet all of the Require rules. @@ -439,6 +451,7 @@ def update( include: Iterable[AccessRuleParam] | Omit = omit, name: str | Omit = omit, exclude: Iterable[AccessRuleParam] | Omit = omit, + policy_resolution_account_id: str | Omit = omit, require: Iterable[AccessRuleParam] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. @@ -488,6 +501,7 @@ def update( "include": include, "name": name, "exclude": exclude, + "policy_resolution_account_id": policy_resolution_account_id, "require": require, }, policy_update_params.PolicyUpdateParams, @@ -832,6 +846,7 @@ async def create( connection_rules: policy_create_params.AccessInfraPolicyReqConnectionRules | Omit = omit, exclude: Iterable[AccessRuleParam] | Omit = omit, mfa_config: policy_create_params.AccessInfraPolicyReqMfaConfig | Omit = omit, + policy_resolution_account_id: str | Omit = omit, require: Iterable[AccessRuleParam] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. @@ -870,6 +885,10 @@ async def create( mfa_config: Configures multi-factor authentication (MFA) settings for infrastructure applications. + policy_resolution_account_id: The account ID used to resolve policy resources and identity for cross-account + WARP authentication. The account must be trusted by the account that owns this + policy. + require: Rules evaluated with an AND logical operator. To match the policy, a user must meet all of the Require rules. @@ -906,6 +925,7 @@ async def create( include: Iterable[AccessRuleParam] | Omit = omit, name: str | Omit = omit, exclude: Iterable[AccessRuleParam] | Omit = omit, + policy_resolution_account_id: str | Omit = omit, require: Iterable[AccessRuleParam] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. @@ -952,6 +972,7 @@ async def create( "include": include, "name": name, "exclude": exclude, + "policy_resolution_account_id": policy_resolution_account_id, "require": require, }, policy_create_params.PolicyCreateParams, @@ -1056,6 +1077,7 @@ async def update( connection_rules: policy_update_params.AccessInfraPolicyReqConnectionRules | Omit = omit, exclude: Iterable[AccessRuleParam] | Omit = omit, mfa_config: policy_update_params.AccessInfraPolicyReqMfaConfig | Omit = omit, + policy_resolution_account_id: str | Omit = omit, require: Iterable[AccessRuleParam] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. @@ -1095,6 +1117,10 @@ async def update( mfa_config: Configures multi-factor authentication (MFA) settings for infrastructure applications. + policy_resolution_account_id: The account ID used to resolve policy resources and identity for cross-account + WARP authentication. The account must be trusted by the account that owns this + policy. + require: Rules evaluated with an AND logical operator. To match the policy, a user must meet all of the Require rules. @@ -1133,6 +1159,7 @@ async def update( include: Iterable[AccessRuleParam] | Omit = omit, name: str | Omit = omit, exclude: Iterable[AccessRuleParam] | Omit = omit, + policy_resolution_account_id: str | Omit = omit, require: Iterable[AccessRuleParam] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. @@ -1182,6 +1209,7 @@ async def update( "include": include, "name": name, "exclude": exclude, + "policy_resolution_account_id": policy_resolution_account_id, "require": require, }, policy_update_params.PolicyUpdateParams, diff --git a/src/cloudflare/resources/zero_trust/access/custom_pages.py b/src/cloudflare/resources/zero_trust/access/custom_pages.py index 0434e2b9210..709535bdc13 100644 --- a/src/cloudflare/resources/zero_trust/access/custom_pages.py +++ b/src/cloudflare/resources/zero_trust/access/custom_pages.py @@ -20,10 +20,16 @@ from ...._wrappers import ResultWrapper from ....pagination import SyncV4PagePaginationArray, AsyncV4PagePaginationArray from ...._base_client import AsyncPaginator, make_request_options -from ....types.zero_trust.access import custom_page_list_params, custom_page_create_params, custom_page_update_params +from ....types.zero_trust.access import ( + custom_page_list_params, + custom_page_create_params, + custom_page_update_params, + custom_page_validate_params, +) from ....types.zero_trust.access.custom_page import CustomPage from ....types.zero_trust.access.custom_page_without_html import CustomPageWithoutHTML from ....types.zero_trust.access.custom_page_delete_response import CustomPageDeleteResponse +from ....types.zero_trust.access.custom_page_validate_response import CustomPageValidateResponse __all__ = ["CustomPagesResource", "AsyncCustomPagesResource"] @@ -327,6 +333,63 @@ def get( cast_to=cast(Type[Optional[CustomPage]], ResultWrapper[CustomPage]), ) + def validate( + self, + *, + account_id: str, + template: str, + type: Literal["identity_denied", "forbidden", "login", "interstitial"], + version: int | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> Optional[CustomPageValidateResponse]: + """ + Validate a Liquid template and return its errors and warnings without persisting + it. + + Args: + account_id: Identifier. + + template: The Liquid template to validate. + + type: Custom page type. + + version: Contract version to validate against; omit for the latest. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + return self._post( + path_template("/accounts/{account_id}/access/custom_pages/validate", account_id=account_id), + body=maybe_transform( + { + "template": template, + "type": type, + "version": version, + }, + custom_page_validate_params.CustomPageValidateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Optional[CustomPageValidateResponse]]._unwrapper, + ), + cast_to=cast(Type[Optional[CustomPageValidateResponse]], ResultWrapper[CustomPageValidateResponse]), + ) + class AsyncCustomPagesResource(AsyncAPIResource): @cached_property @@ -627,6 +690,63 @@ async def get( cast_to=cast(Type[Optional[CustomPage]], ResultWrapper[CustomPage]), ) + async def validate( + self, + *, + account_id: str, + template: str, + type: Literal["identity_denied", "forbidden", "login", "interstitial"], + version: int | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> Optional[CustomPageValidateResponse]: + """ + Validate a Liquid template and return its errors and warnings without persisting + it. + + Args: + account_id: Identifier. + + template: The Liquid template to validate. + + type: Custom page type. + + version: Contract version to validate against; omit for the latest. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + return await self._post( + path_template("/accounts/{account_id}/access/custom_pages/validate", account_id=account_id), + body=await async_maybe_transform( + { + "template": template, + "type": type, + "version": version, + }, + custom_page_validate_params.CustomPageValidateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Optional[CustomPageValidateResponse]]._unwrapper, + ), + cast_to=cast(Type[Optional[CustomPageValidateResponse]], ResultWrapper[CustomPageValidateResponse]), + ) + class CustomPagesResourceWithRawResponse: def __init__(self, custom_pages: CustomPagesResource) -> None: @@ -647,6 +767,9 @@ def __init__(self, custom_pages: CustomPagesResource) -> None: self.get = to_raw_response_wrapper( custom_pages.get, ) + self.validate = to_raw_response_wrapper( + custom_pages.validate, + ) class AsyncCustomPagesResourceWithRawResponse: @@ -668,6 +791,9 @@ def __init__(self, custom_pages: AsyncCustomPagesResource) -> None: self.get = async_to_raw_response_wrapper( custom_pages.get, ) + self.validate = async_to_raw_response_wrapper( + custom_pages.validate, + ) class CustomPagesResourceWithStreamingResponse: @@ -689,6 +815,9 @@ def __init__(self, custom_pages: CustomPagesResource) -> None: self.get = to_streamed_response_wrapper( custom_pages.get, ) + self.validate = to_streamed_response_wrapper( + custom_pages.validate, + ) class AsyncCustomPagesResourceWithStreamingResponse: @@ -710,3 +839,6 @@ def __init__(self, custom_pages: AsyncCustomPagesResource) -> None: self.get = async_to_streamed_response_wrapper( custom_pages.get, ) + self.validate = async_to_streamed_response_wrapper( + custom_pages.validate, + ) diff --git a/src/cloudflare/resources/zero_trust/access/logs/__init__.py b/src/cloudflare/resources/zero_trust/access/logs/__init__.py index 3897e836cf7..01301da48cb 100644 --- a/src/cloudflare/resources/zero_trust/access/logs/__init__.py +++ b/src/cloudflare/resources/zero_trust/access/logs/__init__.py @@ -16,6 +16,14 @@ SCIMResourceWithStreamingResponse, AsyncSCIMResourceWithStreamingResponse, ) +from .jit_requests import ( + JitRequestsResource, + AsyncJitRequestsResource, + JitRequestsResourceWithRawResponse, + AsyncJitRequestsResourceWithRawResponse, + JitRequestsResourceWithStreamingResponse, + AsyncJitRequestsResourceWithStreamingResponse, +) from .access_requests import ( AccessRequestsResource, AsyncAccessRequestsResource, @@ -32,6 +40,12 @@ "AsyncAccessRequestsResourceWithRawResponse", "AccessRequestsResourceWithStreamingResponse", "AsyncAccessRequestsResourceWithStreamingResponse", + "JitRequestsResource", + "AsyncJitRequestsResource", + "JitRequestsResourceWithRawResponse", + "AsyncJitRequestsResourceWithRawResponse", + "JitRequestsResourceWithStreamingResponse", + "AsyncJitRequestsResourceWithStreamingResponse", "SCIMResource", "AsyncSCIMResource", "SCIMResourceWithRawResponse", diff --git a/src/cloudflare/resources/zero_trust/access/logs/jit_requests.py b/src/cloudflare/resources/zero_trust/access/logs/jit_requests.py new file mode 100644 index 00000000000..246dd1beaa1 --- /dev/null +++ b/src/cloudflare/resources/zero_trust/access/logs/jit_requests.py @@ -0,0 +1,354 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Type, Union, Optional, cast +from datetime import datetime +from typing_extensions import Literal + +import httpx + +from ....._types import Body, Omit, Query, Headers, NotGiven, omit, not_given +from ....._utils import path_template, maybe_transform +from ....._compat import cached_property +from ....._resource import SyncAPIResource, AsyncAPIResource +from ....._response import ( + to_raw_response_wrapper, + to_streamed_response_wrapper, + async_to_raw_response_wrapper, + async_to_streamed_response_wrapper, +) +from ....._wrappers import ResultWrapper +from .....pagination import SyncV4PagePaginationArray, AsyncV4PagePaginationArray +from ....._base_client import AsyncPaginator, make_request_options +from .....types.zero_trust.access.logs import jit_request_list_params +from .....types.zero_trust.access.logs.jit_request_get_response import JitRequestGetResponse +from .....types.zero_trust.access.logs.jit_request_list_response import JitRequestListResponse + +__all__ = ["JitRequestsResource", "AsyncJitRequestsResource"] + + +class JitRequestsResource(SyncAPIResource): + @cached_property + def with_raw_response(self) -> JitRequestsResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers + """ + return JitRequestsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> JitRequestsResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response + """ + return JitRequestsResourceWithStreamingResponse(self) + + def list( + self, + *, + account_id: str, + page: int | Omit = omit, + per_page: int | Omit = omit, + search: str | Omit = omit, + since: Union[str, datetime] | Omit = omit, + status: Literal["PENDING", "APPROVED", "DENIED", "CANCELED", "SPENT"] | Omit = omit, + until: Union[str, datetime] | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> SyncV4PagePaginationArray[JitRequestListResponse]: + """ + Lists account-wide Access JIT request logs reconstructed from request lifecycle + events. + + Args: + account_id: Identifier. + + page: Page number of results. + + per_page: Number of results per page. + + search: Case-insensitive search over request ID, requester email, application audience, + and application hostname. + + since: The earliest request timestamp to query. Defaults to 366 days before the current + time. + + status: JIT request status. `SPENT` is deprecated and interpreted as `APPROVED`. + + until: The latest request timestamp to query. Defaults to the current time. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + return self._get_api_list( + path_template("/accounts/{account_id}/access/logs/jit_requests", account_id=account_id), + page=SyncV4PagePaginationArray[JitRequestListResponse], + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "page": page, + "per_page": per_page, + "search": search, + "since": since, + "status": status, + "until": until, + }, + jit_request_list_params.JitRequestListParams, + ), + ), + model=JitRequestListResponse, + ) + + def get( + self, + knock_request_id: str, + *, + account_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> Optional[JitRequestGetResponse]: + """ + Gets an account-scoped Access JIT request summary and its lifecycle events in + chronological order. + + Args: + account_id: Identifier. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not knock_request_id: + raise ValueError(f"Expected a non-empty value for `knock_request_id` but received {knock_request_id!r}") + return self._get( + path_template( + "/accounts/{account_id}/access/logs/jit_requests/{knock_request_id}", + account_id=account_id, + knock_request_id=knock_request_id, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Optional[JitRequestGetResponse]]._unwrapper, + ), + cast_to=cast(Type[Optional[JitRequestGetResponse]], ResultWrapper[JitRequestGetResponse]), + ) + + +class AsyncJitRequestsResource(AsyncAPIResource): + @cached_property + def with_raw_response(self) -> AsyncJitRequestsResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers + """ + return AsyncJitRequestsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncJitRequestsResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response + """ + return AsyncJitRequestsResourceWithStreamingResponse(self) + + def list( + self, + *, + account_id: str, + page: int | Omit = omit, + per_page: int | Omit = omit, + search: str | Omit = omit, + since: Union[str, datetime] | Omit = omit, + status: Literal["PENDING", "APPROVED", "DENIED", "CANCELED", "SPENT"] | Omit = omit, + until: Union[str, datetime] | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> AsyncPaginator[JitRequestListResponse, AsyncV4PagePaginationArray[JitRequestListResponse]]: + """ + Lists account-wide Access JIT request logs reconstructed from request lifecycle + events. + + Args: + account_id: Identifier. + + page: Page number of results. + + per_page: Number of results per page. + + search: Case-insensitive search over request ID, requester email, application audience, + and application hostname. + + since: The earliest request timestamp to query. Defaults to 366 days before the current + time. + + status: JIT request status. `SPENT` is deprecated and interpreted as `APPROVED`. + + until: The latest request timestamp to query. Defaults to the current time. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + return self._get_api_list( + path_template("/accounts/{account_id}/access/logs/jit_requests", account_id=account_id), + page=AsyncV4PagePaginationArray[JitRequestListResponse], + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "page": page, + "per_page": per_page, + "search": search, + "since": since, + "status": status, + "until": until, + }, + jit_request_list_params.JitRequestListParams, + ), + ), + model=JitRequestListResponse, + ) + + async def get( + self, + knock_request_id: str, + *, + account_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> Optional[JitRequestGetResponse]: + """ + Gets an account-scoped Access JIT request summary and its lifecycle events in + chronological order. + + Args: + account_id: Identifier. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not knock_request_id: + raise ValueError(f"Expected a non-empty value for `knock_request_id` but received {knock_request_id!r}") + return await self._get( + path_template( + "/accounts/{account_id}/access/logs/jit_requests/{knock_request_id}", + account_id=account_id, + knock_request_id=knock_request_id, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Optional[JitRequestGetResponse]]._unwrapper, + ), + cast_to=cast(Type[Optional[JitRequestGetResponse]], ResultWrapper[JitRequestGetResponse]), + ) + + +class JitRequestsResourceWithRawResponse: + def __init__(self, jit_requests: JitRequestsResource) -> None: + self._jit_requests = jit_requests + + self.list = to_raw_response_wrapper( + jit_requests.list, + ) + self.get = to_raw_response_wrapper( + jit_requests.get, + ) + + +class AsyncJitRequestsResourceWithRawResponse: + def __init__(self, jit_requests: AsyncJitRequestsResource) -> None: + self._jit_requests = jit_requests + + self.list = async_to_raw_response_wrapper( + jit_requests.list, + ) + self.get = async_to_raw_response_wrapper( + jit_requests.get, + ) + + +class JitRequestsResourceWithStreamingResponse: + def __init__(self, jit_requests: JitRequestsResource) -> None: + self._jit_requests = jit_requests + + self.list = to_streamed_response_wrapper( + jit_requests.list, + ) + self.get = to_streamed_response_wrapper( + jit_requests.get, + ) + + +class AsyncJitRequestsResourceWithStreamingResponse: + def __init__(self, jit_requests: AsyncJitRequestsResource) -> None: + self._jit_requests = jit_requests + + self.list = async_to_streamed_response_wrapper( + jit_requests.list, + ) + self.get = async_to_streamed_response_wrapper( + jit_requests.get, + ) diff --git a/src/cloudflare/resources/zero_trust/access/logs/logs.py b/src/cloudflare/resources/zero_trust/access/logs/logs.py index 5b42a260539..d4bbb47ee1c 100644 --- a/src/cloudflare/resources/zero_trust/access/logs/logs.py +++ b/src/cloudflare/resources/zero_trust/access/logs/logs.py @@ -11,6 +11,14 @@ AsyncSCIMResourceWithStreamingResponse, ) from ....._compat import cached_property +from .jit_requests import ( + JitRequestsResource, + AsyncJitRequestsResource, + JitRequestsResourceWithRawResponse, + AsyncJitRequestsResourceWithRawResponse, + JitRequestsResourceWithStreamingResponse, + AsyncJitRequestsResourceWithStreamingResponse, +) from ....._resource import SyncAPIResource, AsyncAPIResource from .access_requests import ( AccessRequestsResource, @@ -29,6 +37,10 @@ class LogsResource(SyncAPIResource): def access_requests(self) -> AccessRequestsResource: return AccessRequestsResource(self._client) + @cached_property + def jit_requests(self) -> JitRequestsResource: + return JitRequestsResource(self._client) + @cached_property def scim(self) -> SCIMResource: return SCIMResource(self._client) @@ -58,6 +70,10 @@ class AsyncLogsResource(AsyncAPIResource): def access_requests(self) -> AsyncAccessRequestsResource: return AsyncAccessRequestsResource(self._client) + @cached_property + def jit_requests(self) -> AsyncJitRequestsResource: + return AsyncJitRequestsResource(self._client) + @cached_property def scim(self) -> AsyncSCIMResource: return AsyncSCIMResource(self._client) @@ -90,6 +106,10 @@ def __init__(self, logs: LogsResource) -> None: def access_requests(self) -> AccessRequestsResourceWithRawResponse: return AccessRequestsResourceWithRawResponse(self._logs.access_requests) + @cached_property + def jit_requests(self) -> JitRequestsResourceWithRawResponse: + return JitRequestsResourceWithRawResponse(self._logs.jit_requests) + @cached_property def scim(self) -> SCIMResourceWithRawResponse: return SCIMResourceWithRawResponse(self._logs.scim) @@ -103,6 +123,10 @@ def __init__(self, logs: AsyncLogsResource) -> None: def access_requests(self) -> AsyncAccessRequestsResourceWithRawResponse: return AsyncAccessRequestsResourceWithRawResponse(self._logs.access_requests) + @cached_property + def jit_requests(self) -> AsyncJitRequestsResourceWithRawResponse: + return AsyncJitRequestsResourceWithRawResponse(self._logs.jit_requests) + @cached_property def scim(self) -> AsyncSCIMResourceWithRawResponse: return AsyncSCIMResourceWithRawResponse(self._logs.scim) @@ -116,6 +140,10 @@ def __init__(self, logs: LogsResource) -> None: def access_requests(self) -> AccessRequestsResourceWithStreamingResponse: return AccessRequestsResourceWithStreamingResponse(self._logs.access_requests) + @cached_property + def jit_requests(self) -> JitRequestsResourceWithStreamingResponse: + return JitRequestsResourceWithStreamingResponse(self._logs.jit_requests) + @cached_property def scim(self) -> SCIMResourceWithStreamingResponse: return SCIMResourceWithStreamingResponse(self._logs.scim) @@ -129,6 +157,10 @@ def __init__(self, logs: AsyncLogsResource) -> None: def access_requests(self) -> AsyncAccessRequestsResourceWithStreamingResponse: return AsyncAccessRequestsResourceWithStreamingResponse(self._logs.access_requests) + @cached_property + def jit_requests(self) -> AsyncJitRequestsResourceWithStreamingResponse: + return AsyncJitRequestsResourceWithStreamingResponse(self._logs.jit_requests) + @cached_property def scim(self) -> AsyncSCIMResourceWithStreamingResponse: return AsyncSCIMResourceWithStreamingResponse(self._logs.scim) diff --git a/src/cloudflare/resources/zero_trust/access/mfa/__init__.py b/src/cloudflare/resources/zero_trust/access/mfa/__init__.py new file mode 100644 index 00000000000..fd7adab27ae --- /dev/null +++ b/src/cloudflare/resources/zero_trust/access/mfa/__init__.py @@ -0,0 +1,33 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from .mfa import ( + MfaResource, + AsyncMfaResource, + MfaResourceWithRawResponse, + AsyncMfaResourceWithRawResponse, + MfaResourceWithStreamingResponse, + AsyncMfaResourceWithStreamingResponse, +) +from .authenticator_catalog import ( + AuthenticatorCatalogResource, + AsyncAuthenticatorCatalogResource, + AuthenticatorCatalogResourceWithRawResponse, + AsyncAuthenticatorCatalogResourceWithRawResponse, + AuthenticatorCatalogResourceWithStreamingResponse, + AsyncAuthenticatorCatalogResourceWithStreamingResponse, +) + +__all__ = [ + "AuthenticatorCatalogResource", + "AsyncAuthenticatorCatalogResource", + "AuthenticatorCatalogResourceWithRawResponse", + "AsyncAuthenticatorCatalogResourceWithRawResponse", + "AuthenticatorCatalogResourceWithStreamingResponse", + "AsyncAuthenticatorCatalogResourceWithStreamingResponse", + "MfaResource", + "AsyncMfaResource", + "MfaResourceWithRawResponse", + "AsyncMfaResourceWithRawResponse", + "MfaResourceWithStreamingResponse", + "AsyncMfaResourceWithStreamingResponse", +] diff --git a/src/cloudflare/resources/tenants/memberships.py b/src/cloudflare/resources/zero_trust/access/mfa/authenticator_catalog.py similarity index 51% rename from src/cloudflare/resources/tenants/memberships.py rename to src/cloudflare/resources/zero_trust/access/mfa/authenticator_catalog.py index a7ed4279bf4..8adfd8e0de4 100644 --- a/src/cloudflare/resources/tenants/memberships.py +++ b/src/cloudflare/resources/zero_trust/access/mfa/authenticator_catalog.py @@ -4,58 +4,60 @@ import httpx -from ..._types import Body, Query, Headers, NotGiven, not_given -from ..._utils import path_template -from ..._compat import cached_property -from ..._resource import SyncAPIResource, AsyncAPIResource -from ..._response import ( +from ....._types import Body, Query, Headers, NotGiven, not_given +from ....._utils import path_template +from ....._compat import cached_property +from ....._resource import SyncAPIResource, AsyncAPIResource +from ....._response import ( to_raw_response_wrapper, to_streamed_response_wrapper, async_to_raw_response_wrapper, async_to_streamed_response_wrapper, ) -from ...pagination import SyncSinglePage, AsyncSinglePage -from ..._base_client import AsyncPaginator, make_request_options -from ...types.tenants.tenant_membership import TenantMembership +from .....pagination import SyncSinglePage, AsyncSinglePage +from ....._base_client import AsyncPaginator, make_request_options +from .....types.zero_trust.access.mfa.authenticator_catalog_list_response import AuthenticatorCatalogListResponse -__all__ = ["MembershipsResource", "AsyncMembershipsResource"] +__all__ = ["AuthenticatorCatalogResource", "AsyncAuthenticatorCatalogResource"] -class MembershipsResource(SyncAPIResource): +class AuthenticatorCatalogResource(SyncAPIResource): @cached_property - def with_raw_response(self) -> MembershipsResourceWithRawResponse: + def with_raw_response(self) -> AuthenticatorCatalogResourceWithRawResponse: """ This property can be used as a prefix for any HTTP method call to return the raw response object instead of the parsed content. For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers """ - return MembershipsResourceWithRawResponse(self) + return AuthenticatorCatalogResourceWithRawResponse(self) @cached_property - def with_streaming_response(self) -> MembershipsResourceWithStreamingResponse: + def with_streaming_response(self) -> AuthenticatorCatalogResourceWithStreamingResponse: """ An alternative to `.with_raw_response` that doesn't eagerly read the response body. For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response """ - return MembershipsResourceWithStreamingResponse(self) + return AuthenticatorCatalogResourceWithStreamingResponse(self) def list( self, - tenant_id: str, *, + account_id: str, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> SyncSinglePage[TenantMembership]: + ) -> SyncSinglePage[AuthenticatorCatalogListResponse]: """ - Lists active Cloudflare users with memberships in this tenant. + Returns a list of Authenticator Device AAGUIDs for MFA configuration. Args: + account_id: Identifier. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -64,53 +66,55 @@ def list( timeout: Override the client-level default timeout for this request, in seconds """ - if not tenant_id: - raise ValueError(f"Expected a non-empty value for `tenant_id` but received {tenant_id!r}") + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") return self._get_api_list( - path_template("/tenants/{tenant_id}/memberships", tenant_id=tenant_id), - page=SyncSinglePage[TenantMembership], + path_template("/accounts/{account_id}/access/authenticator_device_aaguids", account_id=account_id), + page=SyncSinglePage[AuthenticatorCatalogListResponse], options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), - model=TenantMembership, + model=AuthenticatorCatalogListResponse, ) -class AsyncMembershipsResource(AsyncAPIResource): +class AsyncAuthenticatorCatalogResource(AsyncAPIResource): @cached_property - def with_raw_response(self) -> AsyncMembershipsResourceWithRawResponse: + def with_raw_response(self) -> AsyncAuthenticatorCatalogResourceWithRawResponse: """ This property can be used as a prefix for any HTTP method call to return the raw response object instead of the parsed content. For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers """ - return AsyncMembershipsResourceWithRawResponse(self) + return AsyncAuthenticatorCatalogResourceWithRawResponse(self) @cached_property - def with_streaming_response(self) -> AsyncMembershipsResourceWithStreamingResponse: + def with_streaming_response(self) -> AsyncAuthenticatorCatalogResourceWithStreamingResponse: """ An alternative to `.with_raw_response` that doesn't eagerly read the response body. For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response """ - return AsyncMembershipsResourceWithStreamingResponse(self) + return AsyncAuthenticatorCatalogResourceWithStreamingResponse(self) def list( self, - tenant_id: str, *, + account_id: str, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> AsyncPaginator[TenantMembership, AsyncSinglePage[TenantMembership]]: + ) -> AsyncPaginator[AuthenticatorCatalogListResponse, AsyncSinglePage[AuthenticatorCatalogListResponse]]: """ - Lists active Cloudflare users with memberships in this tenant. + Returns a list of Authenticator Device AAGUIDs for MFA configuration. Args: + account_id: Identifier. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -119,49 +123,49 @@ def list( timeout: Override the client-level default timeout for this request, in seconds """ - if not tenant_id: - raise ValueError(f"Expected a non-empty value for `tenant_id` but received {tenant_id!r}") + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") return self._get_api_list( - path_template("/tenants/{tenant_id}/memberships", tenant_id=tenant_id), - page=AsyncSinglePage[TenantMembership], + path_template("/accounts/{account_id}/access/authenticator_device_aaguids", account_id=account_id), + page=AsyncSinglePage[AuthenticatorCatalogListResponse], options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), - model=TenantMembership, + model=AuthenticatorCatalogListResponse, ) -class MembershipsResourceWithRawResponse: - def __init__(self, memberships: MembershipsResource) -> None: - self._memberships = memberships +class AuthenticatorCatalogResourceWithRawResponse: + def __init__(self, authenticator_catalog: AuthenticatorCatalogResource) -> None: + self._authenticator_catalog = authenticator_catalog self.list = to_raw_response_wrapper( - memberships.list, + authenticator_catalog.list, ) -class AsyncMembershipsResourceWithRawResponse: - def __init__(self, memberships: AsyncMembershipsResource) -> None: - self._memberships = memberships +class AsyncAuthenticatorCatalogResourceWithRawResponse: + def __init__(self, authenticator_catalog: AsyncAuthenticatorCatalogResource) -> None: + self._authenticator_catalog = authenticator_catalog self.list = async_to_raw_response_wrapper( - memberships.list, + authenticator_catalog.list, ) -class MembershipsResourceWithStreamingResponse: - def __init__(self, memberships: MembershipsResource) -> None: - self._memberships = memberships +class AuthenticatorCatalogResourceWithStreamingResponse: + def __init__(self, authenticator_catalog: AuthenticatorCatalogResource) -> None: + self._authenticator_catalog = authenticator_catalog self.list = to_streamed_response_wrapper( - memberships.list, + authenticator_catalog.list, ) -class AsyncMembershipsResourceWithStreamingResponse: - def __init__(self, memberships: AsyncMembershipsResource) -> None: - self._memberships = memberships +class AsyncAuthenticatorCatalogResourceWithStreamingResponse: + def __init__(self, authenticator_catalog: AsyncAuthenticatorCatalogResource) -> None: + self._authenticator_catalog = authenticator_catalog self.list = async_to_streamed_response_wrapper( - memberships.list, + authenticator_catalog.list, ) diff --git a/src/cloudflare/resources/zero_trust/access/mfa/mfa.py b/src/cloudflare/resources/zero_trust/access/mfa/mfa.py new file mode 100644 index 00000000000..e7d62c60929 --- /dev/null +++ b/src/cloudflare/resources/zero_trust/access/mfa/mfa.py @@ -0,0 +1,102 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from ....._compat import cached_property +from ....._resource import SyncAPIResource, AsyncAPIResource +from .authenticator_catalog import ( + AuthenticatorCatalogResource, + AsyncAuthenticatorCatalogResource, + AuthenticatorCatalogResourceWithRawResponse, + AsyncAuthenticatorCatalogResourceWithRawResponse, + AuthenticatorCatalogResourceWithStreamingResponse, + AsyncAuthenticatorCatalogResourceWithStreamingResponse, +) + +__all__ = ["MfaResource", "AsyncMfaResource"] + + +class MfaResource(SyncAPIResource): + @cached_property + def authenticator_catalog(self) -> AuthenticatorCatalogResource: + return AuthenticatorCatalogResource(self._client) + + @cached_property + def with_raw_response(self) -> MfaResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers + """ + return MfaResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> MfaResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response + """ + return MfaResourceWithStreamingResponse(self) + + +class AsyncMfaResource(AsyncAPIResource): + @cached_property + def authenticator_catalog(self) -> AsyncAuthenticatorCatalogResource: + return AsyncAuthenticatorCatalogResource(self._client) + + @cached_property + def with_raw_response(self) -> AsyncMfaResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers + """ + return AsyncMfaResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncMfaResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response + """ + return AsyncMfaResourceWithStreamingResponse(self) + + +class MfaResourceWithRawResponse: + def __init__(self, mfa: MfaResource) -> None: + self._mfa = mfa + + @cached_property + def authenticator_catalog(self) -> AuthenticatorCatalogResourceWithRawResponse: + return AuthenticatorCatalogResourceWithRawResponse(self._mfa.authenticator_catalog) + + +class AsyncMfaResourceWithRawResponse: + def __init__(self, mfa: AsyncMfaResource) -> None: + self._mfa = mfa + + @cached_property + def authenticator_catalog(self) -> AsyncAuthenticatorCatalogResourceWithRawResponse: + return AsyncAuthenticatorCatalogResourceWithRawResponse(self._mfa.authenticator_catalog) + + +class MfaResourceWithStreamingResponse: + def __init__(self, mfa: MfaResource) -> None: + self._mfa = mfa + + @cached_property + def authenticator_catalog(self) -> AuthenticatorCatalogResourceWithStreamingResponse: + return AuthenticatorCatalogResourceWithStreamingResponse(self._mfa.authenticator_catalog) + + +class AsyncMfaResourceWithStreamingResponse: + def __init__(self, mfa: AsyncMfaResource) -> None: + self._mfa = mfa + + @cached_property + def authenticator_catalog(self) -> AsyncAuthenticatorCatalogResourceWithStreamingResponse: + return AsyncAuthenticatorCatalogResourceWithStreamingResponse(self._mfa.authenticator_catalog) diff --git a/src/cloudflare/resources/zero_trust/access/policies.py b/src/cloudflare/resources/zero_trust/access/policies.py index 0b8f26ad29d..67dfe610af8 100644 --- a/src/cloudflare/resources/zero_trust/access/policies.py +++ b/src/cloudflare/resources/zero_trust/access/policies.py @@ -65,6 +65,7 @@ def create( exclude: Iterable[AccessRuleParam] | Omit = omit, isolation_required: bool | Omit = omit, mfa_config: policy_create_params.MfaConfig | Omit = omit, + policy_resolution_account_id: str | Omit = omit, purpose_justification_prompt: str | Omit = omit, purpose_justification_required: bool | Omit = omit, require: Iterable[AccessRuleParam] | Omit = omit, @@ -107,6 +108,10 @@ def create( mfa_config: Configures multi-factor authentication (MFA) settings. + policy_resolution_account_id: The account ID used to resolve policy resources and identity for cross-account + WARP authentication. The account must be trusted by the account that owns this + policy. + purpose_justification_prompt: A custom message that will appear on the purpose justification screen. purpose_justification_required: Require users to enter a justification when they log in to the application. @@ -141,6 +146,7 @@ def create( "exclude": exclude, "isolation_required": isolation_required, "mfa_config": mfa_config, + "policy_resolution_account_id": policy_resolution_account_id, "purpose_justification_prompt": purpose_justification_prompt, "purpose_justification_required": purpose_justification_required, "require": require, @@ -172,6 +178,7 @@ def update( exclude: Iterable[AccessRuleParam] | Omit = omit, isolation_required: bool | Omit = omit, mfa_config: policy_update_params.MfaConfig | Omit = omit, + policy_resolution_account_id: str | Omit = omit, purpose_justification_prompt: str | Omit = omit, purpose_justification_required: bool | Omit = omit, require: Iterable[AccessRuleParam] | Omit = omit, @@ -216,6 +223,10 @@ def update( mfa_config: Configures multi-factor authentication (MFA) settings. + policy_resolution_account_id: The account ID used to resolve policy resources and identity for cross-account + WARP authentication. The account must be trusted by the account that owns this + policy. + purpose_justification_prompt: A custom message that will appear on the purpose justification screen. purpose_justification_required: Require users to enter a justification when they log in to the application. @@ -254,6 +265,7 @@ def update( "exclude": exclude, "isolation_required": isolation_required, "mfa_config": mfa_config, + "policy_resolution_account_id": policy_resolution_account_id, "purpose_justification_prompt": purpose_justification_prompt, "purpose_justification_required": purpose_justification_required, "require": require, @@ -449,6 +461,7 @@ async def create( exclude: Iterable[AccessRuleParam] | Omit = omit, isolation_required: bool | Omit = omit, mfa_config: policy_create_params.MfaConfig | Omit = omit, + policy_resolution_account_id: str | Omit = omit, purpose_justification_prompt: str | Omit = omit, purpose_justification_required: bool | Omit = omit, require: Iterable[AccessRuleParam] | Omit = omit, @@ -491,6 +504,10 @@ async def create( mfa_config: Configures multi-factor authentication (MFA) settings. + policy_resolution_account_id: The account ID used to resolve policy resources and identity for cross-account + WARP authentication. The account must be trusted by the account that owns this + policy. + purpose_justification_prompt: A custom message that will appear on the purpose justification screen. purpose_justification_required: Require users to enter a justification when they log in to the application. @@ -525,6 +542,7 @@ async def create( "exclude": exclude, "isolation_required": isolation_required, "mfa_config": mfa_config, + "policy_resolution_account_id": policy_resolution_account_id, "purpose_justification_prompt": purpose_justification_prompt, "purpose_justification_required": purpose_justification_required, "require": require, @@ -556,6 +574,7 @@ async def update( exclude: Iterable[AccessRuleParam] | Omit = omit, isolation_required: bool | Omit = omit, mfa_config: policy_update_params.MfaConfig | Omit = omit, + policy_resolution_account_id: str | Omit = omit, purpose_justification_prompt: str | Omit = omit, purpose_justification_required: bool | Omit = omit, require: Iterable[AccessRuleParam] | Omit = omit, @@ -600,6 +619,10 @@ async def update( mfa_config: Configures multi-factor authentication (MFA) settings. + policy_resolution_account_id: The account ID used to resolve policy resources and identity for cross-account + WARP authentication. The account must be trusted by the account that owns this + policy. + purpose_justification_prompt: A custom message that will appear on the purpose justification screen. purpose_justification_required: Require users to enter a justification when they log in to the application. @@ -638,6 +661,7 @@ async def update( "exclude": exclude, "isolation_required": isolation_required, "mfa_config": mfa_config, + "policy_resolution_account_id": policy_resolution_account_id, "purpose_justification_prompt": purpose_justification_prompt, "purpose_justification_required": purpose_justification_required, "require": require, diff --git a/src/cloudflare/resources/zero_trust/access/service_tokens.py b/src/cloudflare/resources/zero_trust/access/service_tokens.py index d22db5cb68b..7e4f3cba26d 100644 --- a/src/cloudflare/resources/zero_trust/access/service_tokens.py +++ b/src/cloudflare/resources/zero_trust/access/service_tokens.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing import Type, Union, Optional, cast +from typing import Dict, Type, Union, Optional, cast from datetime import datetime import httpx @@ -63,6 +63,7 @@ def create( duration: str | Omit = omit, enabled: bool | Omit = omit, previous_client_secret_expires_at: Union[str, datetime] | Omit = omit, + tags: Optional[Dict[str, str]] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -86,7 +87,9 @@ def create( client_secret_version: A version number identifying the current `client_secret` associated with the service token. Incrementing it triggers a rotation; the previous secret will still be accepted until the time indicated by - `previous_client_secret_expires_at`. + `previous_client_secret_expires_at`. If the service token was reported as + leaked, `previous_client_secret_expires_at` is not required, may not be in the + future, and the previous secret is discarded immediately. duration: The duration for how long the service token will be valid. Must be in the format `300ms` or `2h45m`, or the special value `forever` for non-expiring tokens. @@ -95,13 +98,20 @@ def create( enabled: Whether the service token is enabled. A disabled service token cannot be used to authenticate; both its current and previous `client_secret` stop being accepted, - but the token itself is preserved and can be re-enabled at any time. Defaults to - enabled when omitted on create. + but the token itself is preserved and can be re-enabled. A service token + reported as leaked is disabled automatically and cannot be re-enabled until its + secret is rotated; attempting to do so returns a 409. Defaults to enabled when + omitted on create. previous_client_secret_expires_at: The expiration of the previous `client_secret`. This can be modified at any point after a rotation. For example, you may extend it further into the future if you need more time to update services with the new secret; or move it into the past to immediately invalidate the previous token in case of compromise. + Rotating a service token that was reported as leaked discards the previous + secret entirely, so no grace period can be set. + + tags: Tags associated with the service token, as key-value pairs. On update, replaces + all existing tags. extra_headers: Send extra headers @@ -136,6 +146,7 @@ def create( "duration": duration, "enabled": enabled, "previous_client_secret_expires_at": previous_client_secret_expires_at, + "tags": tags, }, service_token_create_params.ServiceTokenCreateParams, ), @@ -160,6 +171,7 @@ def update( enabled: bool | Omit = omit, name: str | Omit = omit, previous_client_secret_expires_at: Union[str, datetime] | Omit = omit, + tags: Optional[Dict[str, str]] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -180,7 +192,9 @@ def update( client_secret_version: A version number identifying the current `client_secret` associated with the service token. Incrementing it triggers a rotation; the previous secret will still be accepted until the time indicated by - `previous_client_secret_expires_at`. + `previous_client_secret_expires_at`. If the service token was reported as + leaked, `previous_client_secret_expires_at` is not required, may not be in the + future, and the previous secret is discarded immediately. duration: The duration for how long the service token will be valid. Must be in the format `300ms` or `2h45m`, or the special value `forever` for non-expiring tokens. @@ -189,8 +203,10 @@ def update( enabled: Whether the service token is enabled. A disabled service token cannot be used to authenticate; both its current and previous `client_secret` stop being accepted, - but the token itself is preserved and can be re-enabled at any time. Defaults to - enabled when omitted on create. + but the token itself is preserved and can be re-enabled. A service token + reported as leaked is disabled automatically and cannot be re-enabled until its + secret is rotated; attempting to do so returns a 409. Defaults to enabled when + omitted on create. name: The name of the service token. @@ -198,6 +214,11 @@ def update( point after a rotation. For example, you may extend it further into the future if you need more time to update services with the new secret; or move it into the past to immediately invalidate the previous token in case of compromise. + Rotating a service token that was reported as leaked discards the previous + secret entirely, so no grace period can be set. + + tags: Tags associated with the service token, as key-value pairs. On update, replaces + all existing tags. extra_headers: Send extra headers @@ -235,6 +256,7 @@ def update( "enabled": enabled, "name": name, "previous_client_secret_expires_at": previous_client_secret_expires_at, + "tags": tags, }, service_token_update_params.ServiceTokenUpdateParams, ), @@ -519,7 +541,9 @@ def rotate( service_token_id: UUID. previous_client_secret_expires_at: The expiration of the previous `client_secret`. If not provided, it defaults to - the current timestamp in order to immediately expire the previous secret. + the current timestamp in order to immediately expire the previous secret. If the + service token was reported as leaked, this must not be in the future; the leaked + secret is discarded immediately. extra_headers: Send extra headers @@ -584,6 +608,7 @@ async def create( duration: str | Omit = omit, enabled: bool | Omit = omit, previous_client_secret_expires_at: Union[str, datetime] | Omit = omit, + tags: Optional[Dict[str, str]] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -607,7 +632,9 @@ async def create( client_secret_version: A version number identifying the current `client_secret` associated with the service token. Incrementing it triggers a rotation; the previous secret will still be accepted until the time indicated by - `previous_client_secret_expires_at`. + `previous_client_secret_expires_at`. If the service token was reported as + leaked, `previous_client_secret_expires_at` is not required, may not be in the + future, and the previous secret is discarded immediately. duration: The duration for how long the service token will be valid. Must be in the format `300ms` or `2h45m`, or the special value `forever` for non-expiring tokens. @@ -616,13 +643,20 @@ async def create( enabled: Whether the service token is enabled. A disabled service token cannot be used to authenticate; both its current and previous `client_secret` stop being accepted, - but the token itself is preserved and can be re-enabled at any time. Defaults to - enabled when omitted on create. + but the token itself is preserved and can be re-enabled. A service token + reported as leaked is disabled automatically and cannot be re-enabled until its + secret is rotated; attempting to do so returns a 409. Defaults to enabled when + omitted on create. previous_client_secret_expires_at: The expiration of the previous `client_secret`. This can be modified at any point after a rotation. For example, you may extend it further into the future if you need more time to update services with the new secret; or move it into the past to immediately invalidate the previous token in case of compromise. + Rotating a service token that was reported as leaked discards the previous + secret entirely, so no grace period can be set. + + tags: Tags associated with the service token, as key-value pairs. On update, replaces + all existing tags. extra_headers: Send extra headers @@ -657,6 +691,7 @@ async def create( "duration": duration, "enabled": enabled, "previous_client_secret_expires_at": previous_client_secret_expires_at, + "tags": tags, }, service_token_create_params.ServiceTokenCreateParams, ), @@ -681,6 +716,7 @@ async def update( enabled: bool | Omit = omit, name: str | Omit = omit, previous_client_secret_expires_at: Union[str, datetime] | Omit = omit, + tags: Optional[Dict[str, str]] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -701,7 +737,9 @@ async def update( client_secret_version: A version number identifying the current `client_secret` associated with the service token. Incrementing it triggers a rotation; the previous secret will still be accepted until the time indicated by - `previous_client_secret_expires_at`. + `previous_client_secret_expires_at`. If the service token was reported as + leaked, `previous_client_secret_expires_at` is not required, may not be in the + future, and the previous secret is discarded immediately. duration: The duration for how long the service token will be valid. Must be in the format `300ms` or `2h45m`, or the special value `forever` for non-expiring tokens. @@ -710,8 +748,10 @@ async def update( enabled: Whether the service token is enabled. A disabled service token cannot be used to authenticate; both its current and previous `client_secret` stop being accepted, - but the token itself is preserved and can be re-enabled at any time. Defaults to - enabled when omitted on create. + but the token itself is preserved and can be re-enabled. A service token + reported as leaked is disabled automatically and cannot be re-enabled until its + secret is rotated; attempting to do so returns a 409. Defaults to enabled when + omitted on create. name: The name of the service token. @@ -719,6 +759,11 @@ async def update( point after a rotation. For example, you may extend it further into the future if you need more time to update services with the new secret; or move it into the past to immediately invalidate the previous token in case of compromise. + Rotating a service token that was reported as leaked discards the previous + secret entirely, so no grace period can be set. + + tags: Tags associated with the service token, as key-value pairs. On update, replaces + all existing tags. extra_headers: Send extra headers @@ -756,6 +801,7 @@ async def update( "enabled": enabled, "name": name, "previous_client_secret_expires_at": previous_client_secret_expires_at, + "tags": tags, }, service_token_update_params.ServiceTokenUpdateParams, ), @@ -1040,7 +1086,9 @@ async def rotate( service_token_id: UUID. previous_client_secret_expires_at: The expiration of the previous `client_secret`. If not provided, it defaults to - the current timestamp in order to immediately expire the previous secret. + the current timestamp in order to immediately expire the previous secret. If the + service token was reported as leaked, this must not be in the future; the leaked + secret is discarded immediately. extra_headers: Send extra headers diff --git a/src/cloudflare/resources/zero_trust/access/user_populations/__init__.py b/src/cloudflare/resources/zero_trust/access/user_populations/__init__.py new file mode 100644 index 00000000000..5a53a1b342b --- /dev/null +++ b/src/cloudflare/resources/zero_trust/access/user_populations/__init__.py @@ -0,0 +1,33 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from .users import ( + UsersResource, + AsyncUsersResource, + UsersResourceWithRawResponse, + AsyncUsersResourceWithRawResponse, + UsersResourceWithStreamingResponse, + AsyncUsersResourceWithStreamingResponse, +) +from .user_populations import ( + UserPopulationsResource, + AsyncUserPopulationsResource, + UserPopulationsResourceWithRawResponse, + AsyncUserPopulationsResourceWithRawResponse, + UserPopulationsResourceWithStreamingResponse, + AsyncUserPopulationsResourceWithStreamingResponse, +) + +__all__ = [ + "UsersResource", + "AsyncUsersResource", + "UsersResourceWithRawResponse", + "AsyncUsersResourceWithRawResponse", + "UsersResourceWithStreamingResponse", + "AsyncUsersResourceWithStreamingResponse", + "UserPopulationsResource", + "AsyncUserPopulationsResource", + "UserPopulationsResourceWithRawResponse", + "AsyncUserPopulationsResourceWithRawResponse", + "UserPopulationsResourceWithStreamingResponse", + "AsyncUserPopulationsResourceWithStreamingResponse", +] diff --git a/src/cloudflare/resources/zero_trust/access/user_populations/user_populations.py b/src/cloudflare/resources/zero_trust/access/user_populations/user_populations.py new file mode 100644 index 00000000000..098547c56ea --- /dev/null +++ b/src/cloudflare/resources/zero_trust/access/user_populations/user_populations.py @@ -0,0 +1,685 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Type, Optional, cast + +import httpx + +from .users import ( + UsersResource, + AsyncUsersResource, + UsersResourceWithRawResponse, + AsyncUsersResourceWithRawResponse, + UsersResourceWithStreamingResponse, + AsyncUsersResourceWithStreamingResponse, +) +from ....._types import Body, Omit, Query, Headers, NotGiven, omit, not_given +from ....._utils import path_template, maybe_transform, async_maybe_transform +from ....._compat import cached_property +from ....._resource import SyncAPIResource, AsyncAPIResource +from ....._response import ( + to_raw_response_wrapper, + to_streamed_response_wrapper, + async_to_raw_response_wrapper, + async_to_streamed_response_wrapper, +) +from ....._wrappers import ResultWrapper +from .....pagination import SyncV4PagePaginationArray, AsyncV4PagePaginationArray +from ....._base_client import AsyncPaginator, make_request_options +from .....types.zero_trust.access import ( + user_population_list_params, + user_population_create_params, + user_population_update_params, +) +from .....types.zero_trust.access.user_population_get_response import UserPopulationGetResponse +from .....types.zero_trust.access.user_population_list_response import UserPopulationListResponse +from .....types.zero_trust.access.user_population_create_response import UserPopulationCreateResponse +from .....types.zero_trust.access.user_population_delete_response import UserPopulationDeleteResponse +from .....types.zero_trust.access.user_population_update_response import UserPopulationUpdateResponse + +__all__ = ["UserPopulationsResource", "AsyncUserPopulationsResource"] + + +class UserPopulationsResource(SyncAPIResource): + @cached_property + def users(self) -> UsersResource: + return UsersResource(self._client) + + @cached_property + def with_raw_response(self) -> UserPopulationsResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers + """ + return UserPopulationsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> UserPopulationsResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response + """ + return UserPopulationsResourceWithStreamingResponse(self) + + def create( + self, + *, + account_id: str, + name: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> Optional[UserPopulationCreateResponse]: + """ + Creates a user population in an account. + + Args: + account_id: Identifier. + + name: The name of the user population. Leading and trailing whitespace is trimmed + before validation. After trimming, the name must contain at least one + non-whitespace character and must not exceed 128 UTF-8 bytes. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + return self._post( + path_template("/accounts/{account_id}/access/user_populations", account_id=account_id), + body=maybe_transform({"name": name}, user_population_create_params.UserPopulationCreateParams), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Optional[UserPopulationCreateResponse]]._unwrapper, + ), + cast_to=cast(Type[Optional[UserPopulationCreateResponse]], ResultWrapper[UserPopulationCreateResponse]), + ) + + def update( + self, + user_population_id: str, + *, + account_id: str, + name: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> Optional[UserPopulationUpdateResponse]: + """ + Updates a user population's name. + + Args: + account_id: Identifier. + + user_population_id: UUID. + + name: The name of the user population. Leading and trailing whitespace is trimmed + before validation. After trimming, the name must contain at least one + non-whitespace character and must not exceed 128 UTF-8 bytes. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not user_population_id: + raise ValueError(f"Expected a non-empty value for `user_population_id` but received {user_population_id!r}") + return self._put( + path_template( + "/accounts/{account_id}/access/user_populations/{user_population_id}", + account_id=account_id, + user_population_id=user_population_id, + ), + body=maybe_transform({"name": name}, user_population_update_params.UserPopulationUpdateParams), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Optional[UserPopulationUpdateResponse]]._unwrapper, + ), + cast_to=cast(Type[Optional[UserPopulationUpdateResponse]], ResultWrapper[UserPopulationUpdateResponse]), + ) + + def list( + self, + *, + account_id: str, + page: int | Omit = omit, + per_page: int | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> SyncV4PagePaginationArray[UserPopulationListResponse]: + """ + Lists the user populations in an account. + + Args: + account_id: Identifier. + + page: Page number of results. + + per_page: Number of results per page. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + return self._get_api_list( + path_template("/accounts/{account_id}/access/user_populations", account_id=account_id), + page=SyncV4PagePaginationArray[UserPopulationListResponse], + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "page": page, + "per_page": per_page, + }, + user_population_list_params.UserPopulationListParams, + ), + ), + model=UserPopulationListResponse, + ) + + def delete( + self, + user_population_id: str, + *, + account_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> Optional[UserPopulationDeleteResponse]: + """ + Deletes a user population that is not attached to an application. + + Args: + account_id: Identifier. + + user_population_id: UUID. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not user_population_id: + raise ValueError(f"Expected a non-empty value for `user_population_id` but received {user_population_id!r}") + return self._delete( + path_template( + "/accounts/{account_id}/access/user_populations/{user_population_id}", + account_id=account_id, + user_population_id=user_population_id, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Optional[UserPopulationDeleteResponse]]._unwrapper, + ), + cast_to=cast(Type[Optional[UserPopulationDeleteResponse]], ResultWrapper[UserPopulationDeleteResponse]), + ) + + def get( + self, + user_population_id: str, + *, + account_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> Optional[UserPopulationGetResponse]: + """ + Fetches a user population. + + Args: + account_id: Identifier. + + user_population_id: UUID. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not user_population_id: + raise ValueError(f"Expected a non-empty value for `user_population_id` but received {user_population_id!r}") + return self._get( + path_template( + "/accounts/{account_id}/access/user_populations/{user_population_id}", + account_id=account_id, + user_population_id=user_population_id, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Optional[UserPopulationGetResponse]]._unwrapper, + ), + cast_to=cast(Type[Optional[UserPopulationGetResponse]], ResultWrapper[UserPopulationGetResponse]), + ) + + +class AsyncUserPopulationsResource(AsyncAPIResource): + @cached_property + def users(self) -> AsyncUsersResource: + return AsyncUsersResource(self._client) + + @cached_property + def with_raw_response(self) -> AsyncUserPopulationsResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers + """ + return AsyncUserPopulationsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncUserPopulationsResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response + """ + return AsyncUserPopulationsResourceWithStreamingResponse(self) + + async def create( + self, + *, + account_id: str, + name: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> Optional[UserPopulationCreateResponse]: + """ + Creates a user population in an account. + + Args: + account_id: Identifier. + + name: The name of the user population. Leading and trailing whitespace is trimmed + before validation. After trimming, the name must contain at least one + non-whitespace character and must not exceed 128 UTF-8 bytes. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + return await self._post( + path_template("/accounts/{account_id}/access/user_populations", account_id=account_id), + body=await async_maybe_transform({"name": name}, user_population_create_params.UserPopulationCreateParams), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Optional[UserPopulationCreateResponse]]._unwrapper, + ), + cast_to=cast(Type[Optional[UserPopulationCreateResponse]], ResultWrapper[UserPopulationCreateResponse]), + ) + + async def update( + self, + user_population_id: str, + *, + account_id: str, + name: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> Optional[UserPopulationUpdateResponse]: + """ + Updates a user population's name. + + Args: + account_id: Identifier. + + user_population_id: UUID. + + name: The name of the user population. Leading and trailing whitespace is trimmed + before validation. After trimming, the name must contain at least one + non-whitespace character and must not exceed 128 UTF-8 bytes. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not user_population_id: + raise ValueError(f"Expected a non-empty value for `user_population_id` but received {user_population_id!r}") + return await self._put( + path_template( + "/accounts/{account_id}/access/user_populations/{user_population_id}", + account_id=account_id, + user_population_id=user_population_id, + ), + body=await async_maybe_transform({"name": name}, user_population_update_params.UserPopulationUpdateParams), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Optional[UserPopulationUpdateResponse]]._unwrapper, + ), + cast_to=cast(Type[Optional[UserPopulationUpdateResponse]], ResultWrapper[UserPopulationUpdateResponse]), + ) + + def list( + self, + *, + account_id: str, + page: int | Omit = omit, + per_page: int | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> AsyncPaginator[UserPopulationListResponse, AsyncV4PagePaginationArray[UserPopulationListResponse]]: + """ + Lists the user populations in an account. + + Args: + account_id: Identifier. + + page: Page number of results. + + per_page: Number of results per page. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + return self._get_api_list( + path_template("/accounts/{account_id}/access/user_populations", account_id=account_id), + page=AsyncV4PagePaginationArray[UserPopulationListResponse], + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "page": page, + "per_page": per_page, + }, + user_population_list_params.UserPopulationListParams, + ), + ), + model=UserPopulationListResponse, + ) + + async def delete( + self, + user_population_id: str, + *, + account_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> Optional[UserPopulationDeleteResponse]: + """ + Deletes a user population that is not attached to an application. + + Args: + account_id: Identifier. + + user_population_id: UUID. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not user_population_id: + raise ValueError(f"Expected a non-empty value for `user_population_id` but received {user_population_id!r}") + return await self._delete( + path_template( + "/accounts/{account_id}/access/user_populations/{user_population_id}", + account_id=account_id, + user_population_id=user_population_id, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Optional[UserPopulationDeleteResponse]]._unwrapper, + ), + cast_to=cast(Type[Optional[UserPopulationDeleteResponse]], ResultWrapper[UserPopulationDeleteResponse]), + ) + + async def get( + self, + user_population_id: str, + *, + account_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> Optional[UserPopulationGetResponse]: + """ + Fetches a user population. + + Args: + account_id: Identifier. + + user_population_id: UUID. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not user_population_id: + raise ValueError(f"Expected a non-empty value for `user_population_id` but received {user_population_id!r}") + return await self._get( + path_template( + "/accounts/{account_id}/access/user_populations/{user_population_id}", + account_id=account_id, + user_population_id=user_population_id, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Optional[UserPopulationGetResponse]]._unwrapper, + ), + cast_to=cast(Type[Optional[UserPopulationGetResponse]], ResultWrapper[UserPopulationGetResponse]), + ) + + +class UserPopulationsResourceWithRawResponse: + def __init__(self, user_populations: UserPopulationsResource) -> None: + self._user_populations = user_populations + + self.create = to_raw_response_wrapper( + user_populations.create, + ) + self.update = to_raw_response_wrapper( + user_populations.update, + ) + self.list = to_raw_response_wrapper( + user_populations.list, + ) + self.delete = to_raw_response_wrapper( + user_populations.delete, + ) + self.get = to_raw_response_wrapper( + user_populations.get, + ) + + @cached_property + def users(self) -> UsersResourceWithRawResponse: + return UsersResourceWithRawResponse(self._user_populations.users) + + +class AsyncUserPopulationsResourceWithRawResponse: + def __init__(self, user_populations: AsyncUserPopulationsResource) -> None: + self._user_populations = user_populations + + self.create = async_to_raw_response_wrapper( + user_populations.create, + ) + self.update = async_to_raw_response_wrapper( + user_populations.update, + ) + self.list = async_to_raw_response_wrapper( + user_populations.list, + ) + self.delete = async_to_raw_response_wrapper( + user_populations.delete, + ) + self.get = async_to_raw_response_wrapper( + user_populations.get, + ) + + @cached_property + def users(self) -> AsyncUsersResourceWithRawResponse: + return AsyncUsersResourceWithRawResponse(self._user_populations.users) + + +class UserPopulationsResourceWithStreamingResponse: + def __init__(self, user_populations: UserPopulationsResource) -> None: + self._user_populations = user_populations + + self.create = to_streamed_response_wrapper( + user_populations.create, + ) + self.update = to_streamed_response_wrapper( + user_populations.update, + ) + self.list = to_streamed_response_wrapper( + user_populations.list, + ) + self.delete = to_streamed_response_wrapper( + user_populations.delete, + ) + self.get = to_streamed_response_wrapper( + user_populations.get, + ) + + @cached_property + def users(self) -> UsersResourceWithStreamingResponse: + return UsersResourceWithStreamingResponse(self._user_populations.users) + + +class AsyncUserPopulationsResourceWithStreamingResponse: + def __init__(self, user_populations: AsyncUserPopulationsResource) -> None: + self._user_populations = user_populations + + self.create = async_to_streamed_response_wrapper( + user_populations.create, + ) + self.update = async_to_streamed_response_wrapper( + user_populations.update, + ) + self.list = async_to_streamed_response_wrapper( + user_populations.list, + ) + self.delete = async_to_streamed_response_wrapper( + user_populations.delete, + ) + self.get = async_to_streamed_response_wrapper( + user_populations.get, + ) + + @cached_property + def users(self) -> AsyncUsersResourceWithStreamingResponse: + return AsyncUsersResourceWithStreamingResponse(self._user_populations.users) diff --git a/src/cloudflare/resources/zero_trust/access/user_populations/users.py b/src/cloudflare/resources/zero_trust/access/user_populations/users.py new file mode 100644 index 00000000000..398932710df --- /dev/null +++ b/src/cloudflare/resources/zero_trust/access/user_populations/users.py @@ -0,0 +1,976 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Type, Iterable, Optional, cast + +import httpx + +from ....._types import Body, Omit, Query, Headers, NoneType, NotGiven, SequenceNotStr, omit, not_given +from ....._utils import path_template, maybe_transform, async_maybe_transform +from ....._compat import cached_property +from ....._resource import SyncAPIResource, AsyncAPIResource +from ....._response import ( + to_raw_response_wrapper, + to_streamed_response_wrapper, + async_to_raw_response_wrapper, + async_to_streamed_response_wrapper, +) +from ....._wrappers import ResultWrapper +from ....._base_client import make_request_options +from .....types.zero_trust.access.user_populations import ( + user_get_params, + user_list_params, + user_create_params, + user_update_params, + user_replace_params, +) +from .....types.zero_trust.access.user_populations.user_get_response import UserGetResponse +from .....types.zero_trust.access.user_populations.user_list_response import UserListResponse +from .....types.zero_trust.access.user_populations.user_create_response import UserCreateResponse +from .....types.zero_trust.access.user_populations.user_update_response import UserUpdateResponse +from .....types.zero_trust.access.user_populations.user_replace_response import UserReplaceResponse + +__all__ = ["UsersResource", "AsyncUsersResource"] + + +class UsersResource(SyncAPIResource): + @cached_property + def with_raw_response(self) -> UsersResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers + """ + return UsersResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> UsersResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response + """ + return UsersResourceWithStreamingResponse(self) + + def create( + self, + user_population_id: str, + *, + account_id: str, + active: bool | Omit = omit, + display_name: str | Omit = omit, + emails: Iterable[user_create_params.Email] | Omit = omit, + external_id: str | Omit = omit, + meta: user_create_params.Meta | Omit = omit, + name: user_create_params.Name | Omit = omit, + schemas: SequenceNotStr[str] | Omit = omit, + user_name: str | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> Optional[UserCreateResponse]: + """ + Creates a SCIM user in a user population. + + Args: + account_id: Identifier. + + user_population_id: UUID. + + schemas: The SCIM schemas that apply to this resource. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not user_population_id: + raise ValueError(f"Expected a non-empty value for `user_population_id` but received {user_population_id!r}") + return self._post( + path_template( + "/accounts/{account_id}/access/user_populations/{user_population_id}/users", + account_id=account_id, + user_population_id=user_population_id, + ), + body=maybe_transform( + { + "active": active, + "display_name": display_name, + "emails": emails, + "external_id": external_id, + "meta": meta, + "name": name, + "schemas": schemas, + "user_name": user_name, + }, + user_create_params.UserCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Optional[UserCreateResponse]]._unwrapper, + ), + cast_to=cast(Type[Optional[UserCreateResponse]], ResultWrapper[UserCreateResponse]), + ) + + def update( + self, + user_id: str, + *, + account_id: str, + user_population_id: str, + operations: Iterable[user_update_params.Operation], + schemas: SequenceNotStr[str] | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> Optional[UserUpdateResponse]: + """ + Updates a SCIM user in a user population. + + Args: + account_id: Identifier. + + user_population_id: UUID. + + user_id: The SCIM user identifier. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not user_population_id: + raise ValueError(f"Expected a non-empty value for `user_population_id` but received {user_population_id!r}") + if not user_id: + raise ValueError(f"Expected a non-empty value for `user_id` but received {user_id!r}") + return self._patch( + path_template( + "/accounts/{account_id}/access/user_populations/{user_population_id}/users/{user_id}", + account_id=account_id, + user_population_id=user_population_id, + user_id=user_id, + ), + body=maybe_transform( + { + "operations": operations, + "schemas": schemas, + }, + user_update_params.UserUpdateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Optional[UserUpdateResponse]]._unwrapper, + ), + cast_to=cast(Type[Optional[UserUpdateResponse]], ResultWrapper[UserUpdateResponse]), + ) + + def list( + self, + user_population_id: str, + *, + account_id: str, + attributes: str | Omit = omit, + count: int | Omit = omit, + excluded_attributes: str | Omit = omit, + filter: str | Omit = omit, + start_index: int | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> Optional[UserListResponse]: + """ + Lists SCIM users in a user population. + + Args: + account_id: Identifier. + + user_population_id: UUID. + + attributes: Comma-separated SCIM attributes to return. + + count: The maximum number of results to return. + + excluded_attributes: Comma-separated SCIM attributes to exclude from the response. + + filter: A SCIM filter expression. + + start_index: The 1-based index of the first result to return. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not user_population_id: + raise ValueError(f"Expected a non-empty value for `user_population_id` but received {user_population_id!r}") + return self._get( + path_template( + "/accounts/{account_id}/access/user_populations/{user_population_id}/users", + account_id=account_id, + user_population_id=user_population_id, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "attributes": attributes, + "count": count, + "excluded_attributes": excluded_attributes, + "filter": filter, + "start_index": start_index, + }, + user_list_params.UserListParams, + ), + post_parser=ResultWrapper[Optional[UserListResponse]]._unwrapper, + ), + cast_to=cast(Type[Optional[UserListResponse]], ResultWrapper[UserListResponse]), + ) + + def delete( + self, + user_id: str, + *, + account_id: str, + user_population_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> None: + """ + Deletes a SCIM user from a user population. + + Args: + account_id: Identifier. + + user_population_id: UUID. + + user_id: The SCIM user identifier. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not user_population_id: + raise ValueError(f"Expected a non-empty value for `user_population_id` but received {user_population_id!r}") + if not user_id: + raise ValueError(f"Expected a non-empty value for `user_id` but received {user_id!r}") + extra_headers = {"Accept": "*/*", **(extra_headers or {})} + return self._delete( + path_template( + "/accounts/{account_id}/access/user_populations/{user_population_id}/users/{user_id}", + account_id=account_id, + user_population_id=user_population_id, + user_id=user_id, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=NoneType, + ) + + def get( + self, + user_id: str, + *, + account_id: str, + user_population_id: str, + attributes: str | Omit = omit, + excluded_attributes: str | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> Optional[UserGetResponse]: + """ + Fetches a SCIM user from a user population. + + Args: + account_id: Identifier. + + user_population_id: UUID. + + user_id: The SCIM user identifier. + + attributes: Comma-separated SCIM attributes to return. + + excluded_attributes: Comma-separated SCIM attributes to exclude from the response. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not user_population_id: + raise ValueError(f"Expected a non-empty value for `user_population_id` but received {user_population_id!r}") + if not user_id: + raise ValueError(f"Expected a non-empty value for `user_id` but received {user_id!r}") + return self._get( + path_template( + "/accounts/{account_id}/access/user_populations/{user_population_id}/users/{user_id}", + account_id=account_id, + user_population_id=user_population_id, + user_id=user_id, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "attributes": attributes, + "excluded_attributes": excluded_attributes, + }, + user_get_params.UserGetParams, + ), + post_parser=ResultWrapper[Optional[UserGetResponse]]._unwrapper, + ), + cast_to=cast(Type[Optional[UserGetResponse]], ResultWrapper[UserGetResponse]), + ) + + def replace( + self, + user_id: str, + *, + account_id: str, + user_population_id: str, + active: bool | Omit = omit, + display_name: str | Omit = omit, + emails: Iterable[user_replace_params.Email] | Omit = omit, + external_id: str | Omit = omit, + meta: user_replace_params.Meta | Omit = omit, + name: user_replace_params.Name | Omit = omit, + schemas: SequenceNotStr[str] | Omit = omit, + user_name: str | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> Optional[UserReplaceResponse]: + """ + Replaces a SCIM user in a user population. + + Args: + account_id: Identifier. + + user_population_id: UUID. + + user_id: The SCIM user identifier. + + schemas: The SCIM schemas that apply to this resource. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not user_population_id: + raise ValueError(f"Expected a non-empty value for `user_population_id` but received {user_population_id!r}") + if not user_id: + raise ValueError(f"Expected a non-empty value for `user_id` but received {user_id!r}") + return self._put( + path_template( + "/accounts/{account_id}/access/user_populations/{user_population_id}/users/{user_id}", + account_id=account_id, + user_population_id=user_population_id, + user_id=user_id, + ), + body=maybe_transform( + { + "active": active, + "display_name": display_name, + "emails": emails, + "external_id": external_id, + "meta": meta, + "name": name, + "schemas": schemas, + "user_name": user_name, + }, + user_replace_params.UserReplaceParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Optional[UserReplaceResponse]]._unwrapper, + ), + cast_to=cast(Type[Optional[UserReplaceResponse]], ResultWrapper[UserReplaceResponse]), + ) + + +class AsyncUsersResource(AsyncAPIResource): + @cached_property + def with_raw_response(self) -> AsyncUsersResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers + """ + return AsyncUsersResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncUsersResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response + """ + return AsyncUsersResourceWithStreamingResponse(self) + + async def create( + self, + user_population_id: str, + *, + account_id: str, + active: bool | Omit = omit, + display_name: str | Omit = omit, + emails: Iterable[user_create_params.Email] | Omit = omit, + external_id: str | Omit = omit, + meta: user_create_params.Meta | Omit = omit, + name: user_create_params.Name | Omit = omit, + schemas: SequenceNotStr[str] | Omit = omit, + user_name: str | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> Optional[UserCreateResponse]: + """ + Creates a SCIM user in a user population. + + Args: + account_id: Identifier. + + user_population_id: UUID. + + schemas: The SCIM schemas that apply to this resource. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not user_population_id: + raise ValueError(f"Expected a non-empty value for `user_population_id` but received {user_population_id!r}") + return await self._post( + path_template( + "/accounts/{account_id}/access/user_populations/{user_population_id}/users", + account_id=account_id, + user_population_id=user_population_id, + ), + body=await async_maybe_transform( + { + "active": active, + "display_name": display_name, + "emails": emails, + "external_id": external_id, + "meta": meta, + "name": name, + "schemas": schemas, + "user_name": user_name, + }, + user_create_params.UserCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Optional[UserCreateResponse]]._unwrapper, + ), + cast_to=cast(Type[Optional[UserCreateResponse]], ResultWrapper[UserCreateResponse]), + ) + + async def update( + self, + user_id: str, + *, + account_id: str, + user_population_id: str, + operations: Iterable[user_update_params.Operation], + schemas: SequenceNotStr[str] | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> Optional[UserUpdateResponse]: + """ + Updates a SCIM user in a user population. + + Args: + account_id: Identifier. + + user_population_id: UUID. + + user_id: The SCIM user identifier. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not user_population_id: + raise ValueError(f"Expected a non-empty value for `user_population_id` but received {user_population_id!r}") + if not user_id: + raise ValueError(f"Expected a non-empty value for `user_id` but received {user_id!r}") + return await self._patch( + path_template( + "/accounts/{account_id}/access/user_populations/{user_population_id}/users/{user_id}", + account_id=account_id, + user_population_id=user_population_id, + user_id=user_id, + ), + body=await async_maybe_transform( + { + "operations": operations, + "schemas": schemas, + }, + user_update_params.UserUpdateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Optional[UserUpdateResponse]]._unwrapper, + ), + cast_to=cast(Type[Optional[UserUpdateResponse]], ResultWrapper[UserUpdateResponse]), + ) + + async def list( + self, + user_population_id: str, + *, + account_id: str, + attributes: str | Omit = omit, + count: int | Omit = omit, + excluded_attributes: str | Omit = omit, + filter: str | Omit = omit, + start_index: int | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> Optional[UserListResponse]: + """ + Lists SCIM users in a user population. + + Args: + account_id: Identifier. + + user_population_id: UUID. + + attributes: Comma-separated SCIM attributes to return. + + count: The maximum number of results to return. + + excluded_attributes: Comma-separated SCIM attributes to exclude from the response. + + filter: A SCIM filter expression. + + start_index: The 1-based index of the first result to return. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not user_population_id: + raise ValueError(f"Expected a non-empty value for `user_population_id` but received {user_population_id!r}") + return await self._get( + path_template( + "/accounts/{account_id}/access/user_populations/{user_population_id}/users", + account_id=account_id, + user_population_id=user_population_id, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=await async_maybe_transform( + { + "attributes": attributes, + "count": count, + "excluded_attributes": excluded_attributes, + "filter": filter, + "start_index": start_index, + }, + user_list_params.UserListParams, + ), + post_parser=ResultWrapper[Optional[UserListResponse]]._unwrapper, + ), + cast_to=cast(Type[Optional[UserListResponse]], ResultWrapper[UserListResponse]), + ) + + async def delete( + self, + user_id: str, + *, + account_id: str, + user_population_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> None: + """ + Deletes a SCIM user from a user population. + + Args: + account_id: Identifier. + + user_population_id: UUID. + + user_id: The SCIM user identifier. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not user_population_id: + raise ValueError(f"Expected a non-empty value for `user_population_id` but received {user_population_id!r}") + if not user_id: + raise ValueError(f"Expected a non-empty value for `user_id` but received {user_id!r}") + extra_headers = {"Accept": "*/*", **(extra_headers or {})} + return await self._delete( + path_template( + "/accounts/{account_id}/access/user_populations/{user_population_id}/users/{user_id}", + account_id=account_id, + user_population_id=user_population_id, + user_id=user_id, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=NoneType, + ) + + async def get( + self, + user_id: str, + *, + account_id: str, + user_population_id: str, + attributes: str | Omit = omit, + excluded_attributes: str | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> Optional[UserGetResponse]: + """ + Fetches a SCIM user from a user population. + + Args: + account_id: Identifier. + + user_population_id: UUID. + + user_id: The SCIM user identifier. + + attributes: Comma-separated SCIM attributes to return. + + excluded_attributes: Comma-separated SCIM attributes to exclude from the response. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not user_population_id: + raise ValueError(f"Expected a non-empty value for `user_population_id` but received {user_population_id!r}") + if not user_id: + raise ValueError(f"Expected a non-empty value for `user_id` but received {user_id!r}") + return await self._get( + path_template( + "/accounts/{account_id}/access/user_populations/{user_population_id}/users/{user_id}", + account_id=account_id, + user_population_id=user_population_id, + user_id=user_id, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=await async_maybe_transform( + { + "attributes": attributes, + "excluded_attributes": excluded_attributes, + }, + user_get_params.UserGetParams, + ), + post_parser=ResultWrapper[Optional[UserGetResponse]]._unwrapper, + ), + cast_to=cast(Type[Optional[UserGetResponse]], ResultWrapper[UserGetResponse]), + ) + + async def replace( + self, + user_id: str, + *, + account_id: str, + user_population_id: str, + active: bool | Omit = omit, + display_name: str | Omit = omit, + emails: Iterable[user_replace_params.Email] | Omit = omit, + external_id: str | Omit = omit, + meta: user_replace_params.Meta | Omit = omit, + name: user_replace_params.Name | Omit = omit, + schemas: SequenceNotStr[str] | Omit = omit, + user_name: str | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> Optional[UserReplaceResponse]: + """ + Replaces a SCIM user in a user population. + + Args: + account_id: Identifier. + + user_population_id: UUID. + + user_id: The SCIM user identifier. + + schemas: The SCIM schemas that apply to this resource. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not user_population_id: + raise ValueError(f"Expected a non-empty value for `user_population_id` but received {user_population_id!r}") + if not user_id: + raise ValueError(f"Expected a non-empty value for `user_id` but received {user_id!r}") + return await self._put( + path_template( + "/accounts/{account_id}/access/user_populations/{user_population_id}/users/{user_id}", + account_id=account_id, + user_population_id=user_population_id, + user_id=user_id, + ), + body=await async_maybe_transform( + { + "active": active, + "display_name": display_name, + "emails": emails, + "external_id": external_id, + "meta": meta, + "name": name, + "schemas": schemas, + "user_name": user_name, + }, + user_replace_params.UserReplaceParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Optional[UserReplaceResponse]]._unwrapper, + ), + cast_to=cast(Type[Optional[UserReplaceResponse]], ResultWrapper[UserReplaceResponse]), + ) + + +class UsersResourceWithRawResponse: + def __init__(self, users: UsersResource) -> None: + self._users = users + + self.create = to_raw_response_wrapper( + users.create, + ) + self.update = to_raw_response_wrapper( + users.update, + ) + self.list = to_raw_response_wrapper( + users.list, + ) + self.delete = to_raw_response_wrapper( + users.delete, + ) + self.get = to_raw_response_wrapper( + users.get, + ) + self.replace = to_raw_response_wrapper( + users.replace, + ) + + +class AsyncUsersResourceWithRawResponse: + def __init__(self, users: AsyncUsersResource) -> None: + self._users = users + + self.create = async_to_raw_response_wrapper( + users.create, + ) + self.update = async_to_raw_response_wrapper( + users.update, + ) + self.list = async_to_raw_response_wrapper( + users.list, + ) + self.delete = async_to_raw_response_wrapper( + users.delete, + ) + self.get = async_to_raw_response_wrapper( + users.get, + ) + self.replace = async_to_raw_response_wrapper( + users.replace, + ) + + +class UsersResourceWithStreamingResponse: + def __init__(self, users: UsersResource) -> None: + self._users = users + + self.create = to_streamed_response_wrapper( + users.create, + ) + self.update = to_streamed_response_wrapper( + users.update, + ) + self.list = to_streamed_response_wrapper( + users.list, + ) + self.delete = to_streamed_response_wrapper( + users.delete, + ) + self.get = to_streamed_response_wrapper( + users.get, + ) + self.replace = to_streamed_response_wrapper( + users.replace, + ) + + +class AsyncUsersResourceWithStreamingResponse: + def __init__(self, users: AsyncUsersResource) -> None: + self._users = users + + self.create = async_to_streamed_response_wrapper( + users.create, + ) + self.update = async_to_streamed_response_wrapper( + users.update, + ) + self.list = async_to_streamed_response_wrapper( + users.list, + ) + self.delete = async_to_streamed_response_wrapper( + users.delete, + ) + self.get = async_to_streamed_response_wrapper( + users.get, + ) + self.replace = async_to_streamed_response_wrapper( + users.replace, + ) diff --git a/src/cloudflare/resources/zero_trust/access/users/__init__.py b/src/cloudflare/resources/zero_trust/access/users/__init__.py index c5766c1427a..aac0396004c 100644 --- a/src/cloudflare/resources/zero_trust/access/users/__init__.py +++ b/src/cloudflare/resources/zero_trust/access/users/__init__.py @@ -8,6 +8,14 @@ UsersResourceWithStreamingResponse, AsyncUsersResourceWithStreamingResponse, ) +from .passkeys import ( + PasskeysResource, + AsyncPasskeysResource, + PasskeysResourceWithRawResponse, + AsyncPasskeysResourceWithRawResponse, + PasskeysResourceWithStreamingResponse, + AsyncPasskeysResourceWithStreamingResponse, +) from .failed_logins import ( FailedLoginsResource, AsyncFailedLoginsResource, @@ -32,6 +40,14 @@ LastSeenIdentityResourceWithStreamingResponse, AsyncLastSeenIdentityResourceWithStreamingResponse, ) +from .mfa_authenticators import ( + MfaAuthenticatorsResource, + AsyncMfaAuthenticatorsResource, + MfaAuthenticatorsResourceWithRawResponse, + AsyncMfaAuthenticatorsResourceWithRawResponse, + MfaAuthenticatorsResourceWithStreamingResponse, + AsyncMfaAuthenticatorsResourceWithStreamingResponse, +) __all__ = [ "ActiveSessionsResource", @@ -52,6 +68,18 @@ "AsyncFailedLoginsResourceWithRawResponse", "FailedLoginsResourceWithStreamingResponse", "AsyncFailedLoginsResourceWithStreamingResponse", + "MfaAuthenticatorsResource", + "AsyncMfaAuthenticatorsResource", + "MfaAuthenticatorsResourceWithRawResponse", + "AsyncMfaAuthenticatorsResourceWithRawResponse", + "MfaAuthenticatorsResourceWithStreamingResponse", + "AsyncMfaAuthenticatorsResourceWithStreamingResponse", + "PasskeysResource", + "AsyncPasskeysResource", + "PasskeysResourceWithRawResponse", + "AsyncPasskeysResourceWithRawResponse", + "PasskeysResourceWithStreamingResponse", + "AsyncPasskeysResourceWithStreamingResponse", "UsersResource", "AsyncUsersResource", "UsersResourceWithRawResponse", diff --git a/src/cloudflare/resources/zero_trust/access/users/last_seen_identity.py b/src/cloudflare/resources/zero_trust/access/users/last_seen_identity.py index e0203e75850..c6d946f7fe4 100644 --- a/src/cloudflare/resources/zero_trust/access/users/last_seen_identity.py +++ b/src/cloudflare/resources/zero_trust/access/users/last_seen_identity.py @@ -18,7 +18,7 @@ ) from ....._wrappers import ResultWrapper from ....._base_client import make_request_options -from .....types.zero_trust.access.users.identity import Identity +from .....types.zero_trust.access.users.last_seen_identity_get_response import LastSeenIdentityGetResponse __all__ = ["LastSeenIdentityResource", "AsyncLastSeenIdentityResource"] @@ -54,7 +54,7 @@ def get( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> Optional[Identity]: + ) -> Optional[LastSeenIdentityGetResponse]: """ Get last seen identity for a single user. @@ -86,9 +86,9 @@ def get( extra_query=extra_query, extra_body=extra_body, timeout=timeout, - post_parser=ResultWrapper[Optional[Identity]]._unwrapper, + post_parser=ResultWrapper[Optional[LastSeenIdentityGetResponse]]._unwrapper, ), - cast_to=cast(Type[Optional[Identity]], ResultWrapper[Identity]), + cast_to=cast(Type[Optional[LastSeenIdentityGetResponse]], ResultWrapper[LastSeenIdentityGetResponse]), ) @@ -123,7 +123,7 @@ async def get( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> Optional[Identity]: + ) -> Optional[LastSeenIdentityGetResponse]: """ Get last seen identity for a single user. @@ -155,9 +155,9 @@ async def get( extra_query=extra_query, extra_body=extra_body, timeout=timeout, - post_parser=ResultWrapper[Optional[Identity]]._unwrapper, + post_parser=ResultWrapper[Optional[LastSeenIdentityGetResponse]]._unwrapper, ), - cast_to=cast(Type[Optional[Identity]], ResultWrapper[Identity]), + cast_to=cast(Type[Optional[LastSeenIdentityGetResponse]], ResultWrapper[LastSeenIdentityGetResponse]), ) diff --git a/src/cloudflare/resources/zero_trust/access/users/mfa_authenticators.py b/src/cloudflare/resources/zero_trust/access/users/mfa_authenticators.py new file mode 100644 index 00000000000..c957e25e0a1 --- /dev/null +++ b/src/cloudflare/resources/zero_trust/access/users/mfa_authenticators.py @@ -0,0 +1,212 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Type, Optional, cast + +import httpx + +from ....._types import Body, Query, Headers, NotGiven, not_given +from ....._utils import path_template +from ....._compat import cached_property +from ....._resource import SyncAPIResource, AsyncAPIResource +from ....._response import ( + to_raw_response_wrapper, + to_streamed_response_wrapper, + async_to_raw_response_wrapper, + async_to_streamed_response_wrapper, +) +from ....._wrappers import ResultWrapper +from ....._base_client import make_request_options + +__all__ = ["MfaAuthenticatorsResource", "AsyncMfaAuthenticatorsResource"] + + +class MfaAuthenticatorsResource(SyncAPIResource): + @cached_property + def with_raw_response(self) -> MfaAuthenticatorsResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers + """ + return MfaAuthenticatorsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> MfaAuthenticatorsResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response + """ + return MfaAuthenticatorsResourceWithStreamingResponse(self) + + def delete( + self, + authenticator_id: str, + *, + account_id: str, + user_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> object: + """ + Deletes a specific MFA device or passkey, including a PIV key or FIDO2 key + enrollment, for a user. Admin deletion remains available when MFA is disabled. + Successful deletion revokes the enrollment and returns a null result. + + Args: + account_id: Identifier. + + user_id: UUID. + + authenticator_id: The unique identifier for the MFA device. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not user_id: + raise ValueError(f"Expected a non-empty value for `user_id` but received {user_id!r}") + if not authenticator_id: + raise ValueError(f"Expected a non-empty value for `authenticator_id` but received {authenticator_id!r}") + return self._delete( + path_template( + "/accounts/{account_id}/access/users/{user_id}/mfa_authenticators/{authenticator_id}", + account_id=account_id, + user_id=user_id, + authenticator_id=authenticator_id, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Optional[object]]._unwrapper, + ), + cast_to=cast(Type[object], ResultWrapper[object]), + ) + + +class AsyncMfaAuthenticatorsResource(AsyncAPIResource): + @cached_property + def with_raw_response(self) -> AsyncMfaAuthenticatorsResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers + """ + return AsyncMfaAuthenticatorsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncMfaAuthenticatorsResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response + """ + return AsyncMfaAuthenticatorsResourceWithStreamingResponse(self) + + async def delete( + self, + authenticator_id: str, + *, + account_id: str, + user_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> object: + """ + Deletes a specific MFA device or passkey, including a PIV key or FIDO2 key + enrollment, for a user. Admin deletion remains available when MFA is disabled. + Successful deletion revokes the enrollment and returns a null result. + + Args: + account_id: Identifier. + + user_id: UUID. + + authenticator_id: The unique identifier for the MFA device. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not user_id: + raise ValueError(f"Expected a non-empty value for `user_id` but received {user_id!r}") + if not authenticator_id: + raise ValueError(f"Expected a non-empty value for `authenticator_id` but received {authenticator_id!r}") + return await self._delete( + path_template( + "/accounts/{account_id}/access/users/{user_id}/mfa_authenticators/{authenticator_id}", + account_id=account_id, + user_id=user_id, + authenticator_id=authenticator_id, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Optional[object]]._unwrapper, + ), + cast_to=cast(Type[object], ResultWrapper[object]), + ) + + +class MfaAuthenticatorsResourceWithRawResponse: + def __init__(self, mfa_authenticators: MfaAuthenticatorsResource) -> None: + self._mfa_authenticators = mfa_authenticators + + self.delete = to_raw_response_wrapper( + mfa_authenticators.delete, + ) + + +class AsyncMfaAuthenticatorsResourceWithRawResponse: + def __init__(self, mfa_authenticators: AsyncMfaAuthenticatorsResource) -> None: + self._mfa_authenticators = mfa_authenticators + + self.delete = async_to_raw_response_wrapper( + mfa_authenticators.delete, + ) + + +class MfaAuthenticatorsResourceWithStreamingResponse: + def __init__(self, mfa_authenticators: MfaAuthenticatorsResource) -> None: + self._mfa_authenticators = mfa_authenticators + + self.delete = to_streamed_response_wrapper( + mfa_authenticators.delete, + ) + + +class AsyncMfaAuthenticatorsResourceWithStreamingResponse: + def __init__(self, mfa_authenticators: AsyncMfaAuthenticatorsResource) -> None: + self._mfa_authenticators = mfa_authenticators + + self.delete = async_to_streamed_response_wrapper( + mfa_authenticators.delete, + ) diff --git a/src/cloudflare/resources/zero_trust/access/users/passkeys.py b/src/cloudflare/resources/zero_trust/access/users/passkeys.py new file mode 100644 index 00000000000..495b2783831 --- /dev/null +++ b/src/cloudflare/resources/zero_trust/access/users/passkeys.py @@ -0,0 +1,214 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Type, Optional, cast + +import httpx + +from ....._types import Body, Query, Headers, NotGiven, not_given +from ....._utils import path_template +from ....._compat import cached_property +from ....._resource import SyncAPIResource, AsyncAPIResource +from ....._response import ( + to_raw_response_wrapper, + to_streamed_response_wrapper, + async_to_raw_response_wrapper, + async_to_streamed_response_wrapper, +) +from ....._wrappers import ResultWrapper +from ....._base_client import make_request_options + +__all__ = ["PasskeysResource", "AsyncPasskeysResource"] + + +class PasskeysResource(SyncAPIResource): + @cached_property + def with_raw_response(self) -> PasskeysResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers + """ + return PasskeysResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> PasskeysResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response + """ + return PasskeysResourceWithStreamingResponse(self) + + def delete( + self, + authenticator_id: str, + *, + account_id: str, + user_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> object: + """Alias of the authenticator deletion endpoint for passkey management. + + The + identifier is the passkey's authenticator ID from the last-seen identity + response. Successful deletion revokes the enrollment and returns a null result. + + Args: + account_id: Identifier. + + user_id: UUID. + + authenticator_id: The unique identifier for the MFA device. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not user_id: + raise ValueError(f"Expected a non-empty value for `user_id` but received {user_id!r}") + if not authenticator_id: + raise ValueError(f"Expected a non-empty value for `authenticator_id` but received {authenticator_id!r}") + return self._delete( + path_template( + "/accounts/{account_id}/access/users/{user_id}/passkeys/{authenticator_id}", + account_id=account_id, + user_id=user_id, + authenticator_id=authenticator_id, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Optional[object]]._unwrapper, + ), + cast_to=cast(Type[object], ResultWrapper[object]), + ) + + +class AsyncPasskeysResource(AsyncAPIResource): + @cached_property + def with_raw_response(self) -> AsyncPasskeysResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers + """ + return AsyncPasskeysResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncPasskeysResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response + """ + return AsyncPasskeysResourceWithStreamingResponse(self) + + async def delete( + self, + authenticator_id: str, + *, + account_id: str, + user_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> object: + """Alias of the authenticator deletion endpoint for passkey management. + + The + identifier is the passkey's authenticator ID from the last-seen identity + response. Successful deletion revokes the enrollment and returns a null result. + + Args: + account_id: Identifier. + + user_id: UUID. + + authenticator_id: The unique identifier for the MFA device. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not user_id: + raise ValueError(f"Expected a non-empty value for `user_id` but received {user_id!r}") + if not authenticator_id: + raise ValueError(f"Expected a non-empty value for `authenticator_id` but received {authenticator_id!r}") + return await self._delete( + path_template( + "/accounts/{account_id}/access/users/{user_id}/passkeys/{authenticator_id}", + account_id=account_id, + user_id=user_id, + authenticator_id=authenticator_id, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Optional[object]]._unwrapper, + ), + cast_to=cast(Type[object], ResultWrapper[object]), + ) + + +class PasskeysResourceWithRawResponse: + def __init__(self, passkeys: PasskeysResource) -> None: + self._passkeys = passkeys + + self.delete = to_raw_response_wrapper( + passkeys.delete, + ) + + +class AsyncPasskeysResourceWithRawResponse: + def __init__(self, passkeys: AsyncPasskeysResource) -> None: + self._passkeys = passkeys + + self.delete = async_to_raw_response_wrapper( + passkeys.delete, + ) + + +class PasskeysResourceWithStreamingResponse: + def __init__(self, passkeys: PasskeysResource) -> None: + self._passkeys = passkeys + + self.delete = to_streamed_response_wrapper( + passkeys.delete, + ) + + +class AsyncPasskeysResourceWithStreamingResponse: + def __init__(self, passkeys: AsyncPasskeysResource) -> None: + self._passkeys = passkeys + + self.delete = async_to_streamed_response_wrapper( + passkeys.delete, + ) diff --git a/src/cloudflare/resources/zero_trust/access/users/users.py b/src/cloudflare/resources/zero_trust/access/users/users.py index 2b0922764c6..58f90c0395c 100644 --- a/src/cloudflare/resources/zero_trust/access/users/users.py +++ b/src/cloudflare/resources/zero_trust/access/users/users.py @@ -6,6 +6,14 @@ import httpx +from .passkeys import ( + PasskeysResource, + AsyncPasskeysResource, + PasskeysResourceWithRawResponse, + AsyncPasskeysResourceWithRawResponse, + PasskeysResourceWithStreamingResponse, + AsyncPasskeysResourceWithStreamingResponse, +) from ....._types import Body, Omit, Query, Headers, NotGiven, omit, not_given from ....._utils import path_template, maybe_transform, async_maybe_transform from ....._compat import cached_property @@ -43,6 +51,14 @@ LastSeenIdentityResourceWithStreamingResponse, AsyncLastSeenIdentityResourceWithStreamingResponse, ) +from .mfa_authenticators import ( + MfaAuthenticatorsResource, + AsyncMfaAuthenticatorsResource, + MfaAuthenticatorsResourceWithRawResponse, + AsyncMfaAuthenticatorsResourceWithRawResponse, + MfaAuthenticatorsResourceWithStreamingResponse, + AsyncMfaAuthenticatorsResourceWithStreamingResponse, +) from .....types.zero_trust.access import user_list_params, user_create_params, user_update_params from .....types.zero_trust.access.user_get_response import UserGetResponse from .....types.zero_trust.access.user_list_response import UserListResponse @@ -65,6 +81,14 @@ def last_seen_identity(self) -> LastSeenIdentityResource: def failed_logins(self) -> FailedLoginsResource: return FailedLoginsResource(self._client) + @cached_property + def mfa_authenticators(self) -> MfaAuthenticatorsResource: + return MfaAuthenticatorsResource(self._client) + + @cached_property + def passkeys(self) -> PasskeysResource: + return PasskeysResource(self._client) + @cached_property def with_raw_response(self) -> UsersResourceWithRawResponse: """ @@ -363,6 +387,14 @@ def last_seen_identity(self) -> AsyncLastSeenIdentityResource: def failed_logins(self) -> AsyncFailedLoginsResource: return AsyncFailedLoginsResource(self._client) + @cached_property + def mfa_authenticators(self) -> AsyncMfaAuthenticatorsResource: + return AsyncMfaAuthenticatorsResource(self._client) + + @cached_property + def passkeys(self) -> AsyncPasskeysResource: + return AsyncPasskeysResource(self._client) + @cached_property def with_raw_response(self) -> AsyncUsersResourceWithRawResponse: """ @@ -680,6 +712,14 @@ def last_seen_identity(self) -> LastSeenIdentityResourceWithRawResponse: def failed_logins(self) -> FailedLoginsResourceWithRawResponse: return FailedLoginsResourceWithRawResponse(self._users.failed_logins) + @cached_property + def mfa_authenticators(self) -> MfaAuthenticatorsResourceWithRawResponse: + return MfaAuthenticatorsResourceWithRawResponse(self._users.mfa_authenticators) + + @cached_property + def passkeys(self) -> PasskeysResourceWithRawResponse: + return PasskeysResourceWithRawResponse(self._users.passkeys) + class AsyncUsersResourceWithRawResponse: def __init__(self, users: AsyncUsersResource) -> None: @@ -713,6 +753,14 @@ def last_seen_identity(self) -> AsyncLastSeenIdentityResourceWithRawResponse: def failed_logins(self) -> AsyncFailedLoginsResourceWithRawResponse: return AsyncFailedLoginsResourceWithRawResponse(self._users.failed_logins) + @cached_property + def mfa_authenticators(self) -> AsyncMfaAuthenticatorsResourceWithRawResponse: + return AsyncMfaAuthenticatorsResourceWithRawResponse(self._users.mfa_authenticators) + + @cached_property + def passkeys(self) -> AsyncPasskeysResourceWithRawResponse: + return AsyncPasskeysResourceWithRawResponse(self._users.passkeys) + class UsersResourceWithStreamingResponse: def __init__(self, users: UsersResource) -> None: @@ -746,6 +794,14 @@ def last_seen_identity(self) -> LastSeenIdentityResourceWithStreamingResponse: def failed_logins(self) -> FailedLoginsResourceWithStreamingResponse: return FailedLoginsResourceWithStreamingResponse(self._users.failed_logins) + @cached_property + def mfa_authenticators(self) -> MfaAuthenticatorsResourceWithStreamingResponse: + return MfaAuthenticatorsResourceWithStreamingResponse(self._users.mfa_authenticators) + + @cached_property + def passkeys(self) -> PasskeysResourceWithStreamingResponse: + return PasskeysResourceWithStreamingResponse(self._users.passkeys) + class AsyncUsersResourceWithStreamingResponse: def __init__(self, users: AsyncUsersResource) -> None: @@ -778,3 +834,11 @@ def last_seen_identity(self) -> AsyncLastSeenIdentityResourceWithStreamingRespon @cached_property def failed_logins(self) -> AsyncFailedLoginsResourceWithStreamingResponse: return AsyncFailedLoginsResourceWithStreamingResponse(self._users.failed_logins) + + @cached_property + def mfa_authenticators(self) -> AsyncMfaAuthenticatorsResourceWithStreamingResponse: + return AsyncMfaAuthenticatorsResourceWithStreamingResponse(self._users.mfa_authenticators) + + @cached_property + def passkeys(self) -> AsyncPasskeysResourceWithStreamingResponse: + return AsyncPasskeysResourceWithStreamingResponse(self._users.passkeys) diff --git a/src/cloudflare/resources/zero_trust/api.md b/src/cloudflare/resources/zero_trust/api.md index 0acf15a16f9..3ed25636298 100644 --- a/src/cloudflare/resources/zero_trust/api.md +++ b/src/cloudflare/resources/zero_trust/api.md @@ -1,5 +1,189 @@ # ZeroTrust +## CWS + +### BasicAuthCredentials + +Types: + +```python +from cloudflare.types.zero_trust.cws import BasicAuthCredential, BasicAuthCredentialDeleteResponse +``` + +Methods: + +- client.zero_trust.cws.basic_auth_credentials.create(\*, account_id, \*\*params) -> BasicAuthCredential +- client.zero_trust.cws.basic_auth_credentials.list(\*, account_id, \*\*params) -> SyncCursorPagination[BasicAuthCredential] +- client.zero_trust.cws.basic_auth_credentials.delete(credential_id, \*, account_id) -> BasicAuthCredentialDeleteResponse +- client.zero_trust.cws.basic_auth_credentials.get(credential_id, \*, account_id) -> BasicAuthCredential + +#### Secrets + +Types: + +```python +from cloudflare.types.zero_trust.cws.basic_auth_credentials import ( + BasicAuthSecret, + SecretDeleteResponse, +) +``` + +Methods: + +- client.zero_trust.cws.basic_auth_credentials.secrets.create(credential_id, \*, account_id, \*\*params) -> BasicAuthSecret +- client.zero_trust.cws.basic_auth_credentials.secrets.list(credential_id, \*, account_id, \*\*params) -> SyncCursorPagination[BasicAuthSecret] +- client.zero_trust.cws.basic_auth_credentials.secrets.delete(secret_id, \*, account_id, credential_id) -> SecretDeleteResponse +- client.zero_trust.cws.basic_auth_credentials.secrets.get(secret_id, \*, account_id, credential_id) -> BasicAuthSecret + +### Deployments + +Types: + +```python +from cloudflare.types.zero_trust.cws import Deployment, DeploymentDeleteResponse +``` + +Methods: + +- client.zero_trust.cws.deployments.create(\*, account_id, \*\*params) -> Deployment +- client.zero_trust.cws.deployments.update(deployment_id, \*, account_id, \*\*params) -> Deployment +- client.zero_trust.cws.deployments.list(\*, account_id, \*\*params) -> SyncCursorPagination[Deployment] +- client.zero_trust.cws.deployments.delete(deployment_id, \*, account_id) -> DeploymentDeleteResponse +- client.zero_trust.cws.deployments.get(deployment_id, \*, account_id) -> Deployment + +### DomainACLs + +Types: + +```python +from cloudflare.types.zero_trust.cws import DomainACL, DomainACLDeleteResponse +``` + +Methods: + +- client.zero_trust.cws.domain_acls.create(\*, account_id, \*\*params) -> DomainACL +- client.zero_trust.cws.domain_acls.update(domain_acl_id, \*, account_id, \*\*params) -> DomainACL +- client.zero_trust.cws.domain_acls.list(\*, account_id, \*\*params) -> SyncCursorPagination[DomainACL] +- client.zero_trust.cws.domain_acls.delete(domain_acl_id, \*, account_id) -> DomainACLDeleteResponse +- client.zero_trust.cws.domain_acls.get(domain_acl_id, \*, account_id) -> DomainACL + +### Policies + +Types: + +```python +from cloudflare.types.zero_trust.cws import Policy, PolicyDeleteResponse +``` + +Methods: + +- client.zero_trust.cws.policies.create(\*, account_id, \*\*params) -> Policy +- client.zero_trust.cws.policies.update(policy_id, \*, account_id, \*\*params) -> Policy +- client.zero_trust.cws.policies.list(\*, account_id, \*\*params) -> SyncCursorPagination[Policy] +- client.zero_trust.cws.policies.delete(policy_id, \*, account_id) -> PolicyDeleteResponse +- client.zero_trust.cws.policies.get(policy_id, \*, account_id) -> Policy + +### PolicySets + +Types: + +```python +from cloudflare.types.zero_trust.cws import PolicySet, PolicySetDeleteResponse +``` + +Methods: + +- client.zero_trust.cws.policy_sets.create(\*, account_id, \*\*params) -> PolicySet +- client.zero_trust.cws.policy_sets.update(policy_set_id, \*, account_id, \*\*params) -> PolicySet +- client.zero_trust.cws.policy_sets.list(\*, account_id, \*\*params) -> SyncCursorPagination[PolicySet] +- client.zero_trust.cws.policy_sets.delete(policy_set_id, \*, account_id) -> PolicySetDeleteResponse +- client.zero_trust.cws.policy_sets.get(policy_set_id, \*, account_id) -> PolicySet + +### RegoMetadata + +Types: + +```python +from cloudflare.types.zero_trust.cws import RegoMetadata, RegoMetadataDeleteResponse +``` + +Methods: + +- client.zero_trust.cws.rego_metadata.create(\*, account_id, \*\*params) -> RegoMetadata +- client.zero_trust.cws.rego_metadata.update(rego_metadata_id, \*, account_id, \*\*params) -> RegoMetadata +- client.zero_trust.cws.rego_metadata.list(\*, account_id, \*\*params) -> SyncCursorPagination[RegoMetadata] +- client.zero_trust.cws.rego_metadata.delete(rego_metadata_id, \*, account_id) -> RegoMetadataDeleteResponse +- client.zero_trust.cws.rego_metadata.get(rego_metadata_id, \*, account_id) -> RegoMetadata + +### RegoModules + +Types: + +```python +from cloudflare.types.zero_trust.cws import RegoModule, RegoModuleDeleteResponse +``` + +Methods: + +- client.zero_trust.cws.rego_modules.create(\*, account_id, \*\*params) -> RegoModule +- client.zero_trust.cws.rego_modules.update(rego_module_id, \*, account_id, \*\*params) -> RegoModule +- client.zero_trust.cws.rego_modules.list(\*, account_id, \*\*params) -> SyncCursorPagination[RegoModule] +- client.zero_trust.cws.rego_modules.delete(rego_module_id, \*, account_id) -> RegoModuleDeleteResponse +- client.zero_trust.cws.rego_modules.get(rego_module_id, \*, account_id) -> RegoModule + +### TenantStructures + +Types: + +```python +from cloudflare.types.zero_trust.cws import TenantStructure, TenantStructureDeleteResponse +``` + +Methods: + +- client.zero_trust.cws.tenant_structures.create(\*, account_id, \*\*params) -> TenantStructure +- client.zero_trust.cws.tenant_structures.update(structure_id, \*, account_id, \*\*params) -> TenantStructure +- client.zero_trust.cws.tenant_structures.list(\*, account_id, \*\*params) -> SyncCursorPagination[TenantStructure] +- client.zero_trust.cws.tenant_structures.delete(structure_id, \*, account_id) -> TenantStructureDeleteResponse +- client.zero_trust.cws.tenant_structures.get(structure_id, \*, account_id) -> TenantStructure + +#### Nodes + +Types: + +```python +from cloudflare.types.zero_trust.cws.tenant_structures import ( + TenantStructureNode, + NodeDeleteResponse, + NodeBatchResponse, +) +``` + +Methods: + +- client.zero_trust.cws.tenant_structures.nodes.create(structure_id, \*, account_id, \*\*params) -> TenantStructureNode +- client.zero_trust.cws.tenant_structures.nodes.update(node_id, \*, account_id, structure_id, \*\*params) -> TenantStructureNode +- client.zero_trust.cws.tenant_structures.nodes.list(structure_id, \*, account_id, \*\*params) -> SyncCursorPagination[TenantStructureNode] +- client.zero_trust.cws.tenant_structures.nodes.delete(node_id, \*, account_id, structure_id) -> NodeDeleteResponse +- client.zero_trust.cws.tenant_structures.nodes.batch(structure_id, \*, account_id, \*\*params) -> NodeBatchResponse +- client.zero_trust.cws.tenant_structures.nodes.get(node_id, \*, account_id, structure_id) -> TenantStructureNode + +### Workloads + +Types: + +```python +from cloudflare.types.zero_trust.cws import Workload, WorkloadDeleteResponse +``` + +Methods: + +- client.zero_trust.cws.workloads.create(\*, account_id, \*\*params) -> Workload +- client.zero_trust.cws.workloads.update(workload_id, \*, account_id, \*\*params) -> Workload +- client.zero_trust.cws.workloads.list(\*, account_id, \*\*params) -> SyncCursorPagination[Workload] +- client.zero_trust.cws.workloads.delete(workload_id, \*, account_id) -> WorkloadDeleteResponse +- client.zero_trust.cws.workloads.get(workload_id, \*, account_id) -> Workload + ## Devices Types: @@ -357,15 +541,25 @@ Methods: #### Groups +Types: + +```python +from cloudflare.types.zero_trust.identity_providers.scim import GroupGetResponse +``` + Methods: - client.zero_trust.identity_providers.scim.groups.list(identity_provider_id, \*, account_id, \*\*params) -> SyncV4PagePaginationArray[ZeroTrustGroup] +- client.zero_trust.identity_providers.scim.groups.delete(group_id, \*, account_id, identity_provider_id) -> None +- client.zero_trust.identity_providers.scim.groups.get(group_id, \*, account_id, identity_provider_id) -> Optional[GroupGetResponse] #### Users Methods: - client.zero_trust.identity_providers.scim.users.list(identity_provider_id, \*, account_id, \*\*params) -> SyncV4PagePaginationArray[AccessUser] +- client.zero_trust.identity_providers.scim.users.delete(user_id, \*, account_id, identity_provider_id) -> None +- client.zero_trust.identity_providers.scim.users.get(user_id, \*, account_id, identity_provider_id) -> Optional[AccessUser] ### SAMLCertificate @@ -575,6 +769,7 @@ from cloudflare.types.zero_trust.access import ( ApplicationType, CORSHeaders, Decision, + DestinationOverride, OIDCSaaSApp, SaaSAppNameIDFormat, SAMLSaaSApp, @@ -835,6 +1030,19 @@ Methods: - client.zero_trust.access.logs.access_requests.list(\*, account_id, \*\*params) -> Optional[AccessRequestListResponse] +#### JitRequests + +Types: + +```python +from cloudflare.types.zero_trust.access.logs import JitRequestListResponse, JitRequestGetResponse +``` + +Methods: + +- client.zero_trust.access.logs.jit_requests.list(\*, account_id, \*\*params) -> SyncV4PagePaginationArray[JitRequestListResponse] +- client.zero_trust.access.logs.jit_requests.get(knock_request_id, \*, account_id) -> Optional[JitRequestGetResponse] + #### SCIM Types: @@ -898,12 +1106,12 @@ Methods: Types: ```python -from cloudflare.types.zero_trust.access.users import Identity +from cloudflare.types.zero_trust.access.users import Identity, LastSeenIdentityGetResponse ``` Methods: -- client.zero_trust.access.users.last_seen_identity.get(user_id, \*, account_id) -> Optional[Identity] +- client.zero_trust.access.users.last_seen_identity.get(user_id, \*, account_id) -> Optional[LastSeenIdentityGetResponse] #### FailedLogins @@ -917,6 +1125,77 @@ Methods: - client.zero_trust.access.users.failed_logins.list(user_id, \*, account_id) -> SyncSinglePage[FailedLoginListResponse] +#### MfaAuthenticators + +Methods: + +- client.zero_trust.access.users.mfa_authenticators.delete(authenticator_id, \*, account_id, user_id) -> object + +#### Passkeys + +Methods: + +- client.zero_trust.access.users.passkeys.delete(authenticator_id, \*, account_id, user_id) -> object + +### UserPopulations + +Types: + +```python +from cloudflare.types.zero_trust.access import ( + UserPopulationCreateResponse, + UserPopulationUpdateResponse, + UserPopulationListResponse, + UserPopulationDeleteResponse, + UserPopulationGetResponse, +) +``` + +Methods: + +- client.zero_trust.access.user_populations.create(\*, account_id, \*\*params) -> Optional[UserPopulationCreateResponse] +- client.zero_trust.access.user_populations.update(user_population_id, \*, account_id, \*\*params) -> Optional[UserPopulationUpdateResponse] +- client.zero_trust.access.user_populations.list(\*, account_id, \*\*params) -> SyncV4PagePaginationArray[UserPopulationListResponse] +- client.zero_trust.access.user_populations.delete(user_population_id, \*, account_id) -> Optional[UserPopulationDeleteResponse] +- client.zero_trust.access.user_populations.get(user_population_id, \*, account_id) -> Optional[UserPopulationGetResponse] + +#### Users + +Types: + +```python +from cloudflare.types.zero_trust.access.user_populations import ( + UserCreateResponse, + UserUpdateResponse, + UserListResponse, + UserGetResponse, + UserReplaceResponse, +) +``` + +Methods: + +- client.zero_trust.access.user_populations.users.create(user_population_id, \*, account_id, \*\*params) -> Optional[UserCreateResponse] +- client.zero_trust.access.user_populations.users.update(user_id, \*, account_id, user_population_id, \*\*params) -> Optional[UserUpdateResponse] +- client.zero_trust.access.user_populations.users.list(user_population_id, \*, account_id, \*\*params) -> Optional[UserListResponse] +- client.zero_trust.access.user_populations.users.delete(user_id, \*, account_id, user_population_id) -> None +- client.zero_trust.access.user_populations.users.get(user_id, \*, account_id, user_population_id, \*\*params) -> Optional[UserGetResponse] +- client.zero_trust.access.user_populations.users.replace(user_id, \*, account_id, user_population_id, \*\*params) -> Optional[UserReplaceResponse] + +### Mfa + +#### AuthenticatorCatalog + +Types: + +```python +from cloudflare.types.zero_trust.access.mfa import AuthenticatorCatalogListResponse +``` + +Methods: + +- client.zero_trust.access.mfa.authenticator_catalog.list(\*, account_id) -> SyncSinglePage[AuthenticatorCatalogListResponse] + ### CustomPages Types: @@ -926,6 +1205,7 @@ from cloudflare.types.zero_trust.access import ( CustomPage, CustomPageWithoutHTML, CustomPageDeleteResponse, + CustomPageValidateResponse, ) ``` @@ -936,6 +1216,7 @@ Methods: - client.zero_trust.access.custom_pages.list(\*, account_id, \*\*params) -> SyncV4PagePaginationArray[CustomPageWithoutHTML] - client.zero_trust.access.custom_pages.delete(custom_page_id, \*, account_id) -> Optional[CustomPageDeleteResponse] - client.zero_trust.access.custom_pages.get(custom_page_id, \*, account_id) -> Optional[CustomPage] +- client.zero_trust.access.custom_pages.validate(\*, account_id, \*\*params) -> Optional[CustomPageValidateResponse] ### Tags @@ -1097,13 +1378,23 @@ Methods: Types: ```python -from cloudflare.types.zero_trust.casb.posture import FindingTypeListResponse, FindingTypeGetResponse +from cloudflare.types.zero_trust.casb.posture import ( + FindingTypeCreateResponse, + FindingTypeUpdateResponse, + FindingTypeListResponse, + FindingTypeGetResponse, + FindingTypeValidateResponse, +) ``` Methods: +- client.zero_trust.casb.posture.finding_types.create(\*, account_id, \*\*params) -> Optional[FindingTypeCreateResponse] +- client.zero_trust.casb.posture.finding_types.update(finding_type_id, \*, account_id, \*\*params) -> Optional[FindingTypeUpdateResponse] - client.zero_trust.casb.posture.finding_types.list(\*, account_id, \*\*params) -> SyncV4PagePaginationArray[FindingTypeListResponse] +- client.zero_trust.casb.posture.finding_types.delete(finding_type_id, \*, account_id) -> None - client.zero_trust.casb.posture.finding_types.get(finding_type_id, \*, account_id) -> Optional[FindingTypeGetResponse] +- client.zero_trust.casb.posture.finding_types.validate(\*, account_id, \*\*params) -> Optional[FindingTypeValidateResponse] ##### RemediationTypes @@ -1117,6 +1408,19 @@ Methods: - client.zero_trust.casb.posture.finding_types.remediation_types.list(finding_type_id, \*, account_id, \*\*params) -> SyncV4PagePaginationArray[RemediationTypeListResponse] +#### AssetSchemas + +Types: + +```python +from cloudflare.types.zero_trust.casb.posture import AssetSchemaListResponse, AssetSchemaGetResponse +``` + +Methods: + +- client.zero_trust.casb.posture.asset_schemas.list(\*, account_id, \*\*params) -> SyncSinglePage[AssetSchemaListResponse] +- client.zero_trust.casb.posture.asset_schemas.get(asset_class, \*, account_id) -> Optional[AssetSchemaGetResponse] + #### Content Types: @@ -1899,6 +2203,40 @@ Methods: - client.zero_trust.dlp.entries.integration.delete(entry_id, \*, account_id) -> object - client.zero_trust.dlp.entries.integration.get(entry_id, \*, account_id) -> Optional[IntegrationGetResponse] +### Validators + +Types: + +```python +from cloudflare.types.zero_trust.dlp import References, Validator, ValidatorArray, WorkerValidator +``` + +Methods: + +- client.zero_trust.dlp.validators.list(\*, account_id, \*\*params) -> SyncSinglePage[Validator] +- client.zero_trust.dlp.validators.get(validator_id, \*, account_id) -> Optional[Validator] + +#### ProximityWords + +Types: + +```python +from cloudflare.types.zero_trust.dlp.validators import ( + ProximityWordValidator, + ProximityWordValidatorArray, + Weight, + Word, +) +``` + +Methods: + +- client.zero_trust.dlp.validators.proximity_words.create(\*, account_id, \*\*params) -> Optional[ProximityWordValidator] +- client.zero_trust.dlp.validators.proximity_words.update(validator_id, \*, account_id, \*\*params) -> Optional[ProximityWordValidator] +- client.zero_trust.dlp.validators.proximity_words.list(\*, account_id) -> SyncSinglePage[ProximityWordValidator] +- client.zero_trust.dlp.validators.proximity_words.delete(validator_id, \*, account_id) -> object +- client.zero_trust.dlp.validators.proximity_words.get(validator_id, \*, account_id) -> Optional[ProximityWordValidator] + ### SensitivityGroups Types: @@ -2254,6 +2592,18 @@ Methods: - client.zero_trust.gateway.pacfiles.delete(pacfile_id, \*, account_id) -> object - client.zero_trust.gateway.pacfiles.get(pacfile_id, \*, account_id) -> Optional[PacfileGetResponse] +### DNSDestinationIPs + +Types: + +```python +from cloudflare.types.zero_trust.gateway import DNSDestinationIPsID, DNSDestinationIPListResponse +``` + +Methods: + +- client.zero_trust.gateway.dns_destination_ips.list(\*, account_id) -> SyncSinglePage[DNSDestinationIPListResponse] + ## Networks ### Routes @@ -2442,7 +2792,7 @@ Methods: - client.zero_trust.resource_library.applications.create(\*, account_id, \*\*params) -> Optional[ApplicationCreateResponse] - client.zero_trust.resource_library.applications.update(id, \*, account_id, \*\*params) -> Optional[ApplicationUpdateResponse] -- client.zero_trust.resource_library.applications.list(\*, account_id, \*\*params) -> SyncSinglePage[ApplicationListResponse] +- client.zero_trust.resource_library.applications.list(\*, account_id, \*\*params) -> SyncCursorPaginationAfter[ApplicationListResponse] - client.zero_trust.resource_library.applications.delete(id, \*, account_id) -> object - client.zero_trust.resource_library.applications.get(id, \*, account_id) -> Optional[ApplicationGetResponse] @@ -2456,5 +2806,5 @@ from cloudflare.types.zero_trust.resource_library import CategoryListResponse, C Methods: -- client.zero_trust.resource_library.categories.list(\*, account_id, \*\*params) -> SyncSinglePage[CategoryListResponse] +- client.zero_trust.resource_library.categories.list(\*, account_id, \*\*params) -> SyncCursorPaginationAfter[CategoryListResponse] - client.zero_trust.resource_library.categories.get(id, \*, account_id) -> Optional[CategoryGetResponse] diff --git a/src/cloudflare/resources/zero_trust/casb/applications/applications.py b/src/cloudflare/resources/zero_trust/casb/applications/applications.py index f6bca764079..532a47e5fe8 100644 --- a/src/cloudflare/resources/zero_trust/casb/applications/applications.py +++ b/src/cloudflare/resources/zero_trust/casb/applications/applications.py @@ -131,6 +131,7 @@ def get( "SALESFORCE", "SERVICENOW", "SLACK", + "ZOOM", ], *, account_id: str, @@ -271,6 +272,7 @@ async def get( "SALESFORCE", "SERVICENOW", "SLACK", + "ZOOM", ], *, account_id: str, diff --git a/src/cloudflare/resources/zero_trust/casb/applications/auth_methods.py b/src/cloudflare/resources/zero_trust/casb/applications/auth_methods.py index be55d977620..5fd93eaa07e 100644 --- a/src/cloudflare/resources/zero_trust/casb/applications/auth_methods.py +++ b/src/cloudflare/resources/zero_trust/casb/applications/auth_methods.py @@ -62,6 +62,7 @@ def list( "SALESFORCE", "SERVICENOW", "SLACK", + "ZOOM", ], *, account_id: str, @@ -158,6 +159,7 @@ def list( "SALESFORCE", "SERVICENOW", "SLACK", + "ZOOM", ], *, account_id: str, diff --git a/src/cloudflare/resources/zero_trust/casb/integrations.py b/src/cloudflare/resources/zero_trust/casb/integrations.py index 59392a01f17..42ef0120257 100644 --- a/src/cloudflare/resources/zero_trust/casb/integrations.py +++ b/src/cloudflare/resources/zero_trust/casb/integrations.py @@ -71,13 +71,14 @@ def create( "SALESFORCE", "SERVICENOW", "SLACK", + "ZOOM", ], credentials: Dict[str, object], name: str, + use_cases: List[Literal["casb", "ces", "auto_remediation"]], auth_method: Optional[str] | Omit = omit, dlp_profiles: SequenceNotStr[str] | Omit = omit, permissions: SequenceNotStr[str] | Omit = omit, - use_cases: List[Literal["casb", "ces", "auto_remediation"]] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -110,20 +111,22 @@ def create( - `SALESFORCE` - SALESFORCE - `SERVICENOW` - SERVICENOW - `SLACK` - SLACK + - `ZOOM` - ZOOM credentials: Credentials for the integration. name: Name of the integration. + use_cases: List of use case or feature slugs to enroll. At least one use case (casb, ces) + is required; auto_remediation may be added alongside casb (e.g., ['casb', 'ces', + 'auto_remediation']). + auth_method: Authentication method slug (uses default if omitted). dlp_profiles: List of DLP profile IDs to associate. permissions: List of permission scopes (uses policy defaults if empty). - use_cases: List of use case or feature slugs to enroll (e.g., ['casb', 'ces', - 'auto_remediation']). - extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -141,10 +144,10 @@ def create( "application": application, "credentials": credentials, "name": name, + "use_cases": use_cases, "auth_method": auth_method, "dlp_profiles": dlp_profiles, "permissions": permissions, - "use_cases": use_cases, }, integration_create_params.IntegrationCreateParams, ), @@ -502,13 +505,14 @@ async def create( "SALESFORCE", "SERVICENOW", "SLACK", + "ZOOM", ], credentials: Dict[str, object], name: str, + use_cases: List[Literal["casb", "ces", "auto_remediation"]], auth_method: Optional[str] | Omit = omit, dlp_profiles: SequenceNotStr[str] | Omit = omit, permissions: SequenceNotStr[str] | Omit = omit, - use_cases: List[Literal["casb", "ces", "auto_remediation"]] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -541,20 +545,22 @@ async def create( - `SALESFORCE` - SALESFORCE - `SERVICENOW` - SERVICENOW - `SLACK` - SLACK + - `ZOOM` - ZOOM credentials: Credentials for the integration. name: Name of the integration. + use_cases: List of use case or feature slugs to enroll. At least one use case (casb, ces) + is required; auto_remediation may be added alongside casb (e.g., ['casb', 'ces', + 'auto_remediation']). + auth_method: Authentication method slug (uses default if omitted). dlp_profiles: List of DLP profile IDs to associate. permissions: List of permission scopes (uses policy defaults if empty). - use_cases: List of use case or feature slugs to enroll (e.g., ['casb', 'ces', - 'auto_remediation']). - extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -572,10 +578,10 @@ async def create( "application": application, "credentials": credentials, "name": name, + "use_cases": use_cases, "auth_method": auth_method, "dlp_profiles": dlp_profiles, "permissions": permissions, - "use_cases": use_cases, }, integration_create_params.IntegrationCreateParams, ), diff --git a/src/cloudflare/resources/zero_trust/casb/posture/__init__.py b/src/cloudflare/resources/zero_trust/casb/posture/__init__.py index 0e63720a723..805a46d8d54 100644 --- a/src/cloudflare/resources/zero_trust/casb/posture/__init__.py +++ b/src/cloudflare/resources/zero_trust/casb/posture/__init__.py @@ -56,6 +56,14 @@ RemediationsResourceWithStreamingResponse, AsyncRemediationsResourceWithStreamingResponse, ) +from .asset_schemas import ( + AssetSchemasResource, + AsyncAssetSchemasResource, + AssetSchemasResourceWithRawResponse, + AsyncAssetSchemasResourceWithRawResponse, + AssetSchemasResourceWithStreamingResponse, + AsyncAssetSchemasResourceWithStreamingResponse, +) from .finding_types import ( FindingTypesResource, AsyncFindingTypesResource, @@ -84,6 +92,12 @@ "AsyncFindingTypesResourceWithRawResponse", "FindingTypesResourceWithStreamingResponse", "AsyncFindingTypesResourceWithStreamingResponse", + "AssetSchemasResource", + "AsyncAssetSchemasResource", + "AssetSchemasResourceWithRawResponse", + "AsyncAssetSchemasResourceWithRawResponse", + "AssetSchemasResourceWithStreamingResponse", + "AsyncAssetSchemasResourceWithStreamingResponse", "ContentResource", "AsyncContentResource", "ContentResourceWithRawResponse", diff --git a/src/cloudflare/resources/zero_trust/casb/posture/asset_schemas.py b/src/cloudflare/resources/zero_trust/casb/posture/asset_schemas.py new file mode 100644 index 00000000000..8b635d4120b --- /dev/null +++ b/src/cloudflare/resources/zero_trust/casb/posture/asset_schemas.py @@ -0,0 +1,333 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Type, Optional, cast +from typing_extensions import Literal + +import httpx + +from ....._types import Body, Omit, Query, Headers, NotGiven, omit, not_given +from ....._utils import path_template, maybe_transform +from ....._compat import cached_property +from ....._resource import SyncAPIResource, AsyncAPIResource +from ....._response import ( + to_raw_response_wrapper, + to_streamed_response_wrapper, + async_to_raw_response_wrapper, + async_to_streamed_response_wrapper, +) +from ....._wrappers import ResultWrapper +from .....pagination import SyncSinglePage, AsyncSinglePage +from ....._base_client import AsyncPaginator, make_request_options +from .....types.zero_trust.casb.posture import asset_schema_list_params +from .....types.zero_trust.casb.posture.asset_schema_get_response import AssetSchemaGetResponse +from .....types.zero_trust.casb.posture.asset_schema_list_response import AssetSchemaListResponse + +__all__ = ["AssetSchemasResource", "AsyncAssetSchemasResource"] + + +class AssetSchemasResource(SyncAPIResource): + @cached_property + def with_raw_response(self) -> AssetSchemasResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers + """ + return AssetSchemasResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AssetSchemasResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response + """ + return AssetSchemasResourceWithStreamingResponse(self) + + def list( + self, + *, + account_id: str, + vendor: Literal[ + "ANTHROPIC", + "AWS", + "BITBUCKET", + "BOX", + "CONFLUENCE", + "DROPBOX", + "GITHUB", + "GOOGLE_CLOUD_PLATFORM", + "GOOGLE_WORKSPACE", + "JIRA", + "MICROSOFT", + "OPENAI", + "SALESFORCE", + "SERVICENOW", + "SLACK", + "WORKDAY", + "ZOOM", + ] + | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> SyncSinglePage[AssetSchemaListResponse]: + """ + Returns the catalog of asset classes available when authoring custom findings, + grouped by vendor. Optionally filter to a single vendor with the `vendor` query + parameter. + + Args: + vendor: Restrict the result to a single vendor. Unknown values return 400. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + return self._get_api_list( + path_template("/accounts/{account_id}/data-security/posture/asset_schemas", account_id=account_id), + page=SyncSinglePage[AssetSchemaListResponse], + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform({"vendor": vendor}, asset_schema_list_params.AssetSchemaListParams), + ), + model=AssetSchemaListResponse, + ) + + def get( + self, + asset_class: str, + *, + account_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> Optional[AssetSchemaGetResponse]: + """ + Returns the fields and related attributes a custom finding type may reference + for the given asset class (JSON Schema). Used by the custom finding types + builder. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not asset_class: + raise ValueError(f"Expected a non-empty value for `asset_class` but received {asset_class!r}") + return self._get( + path_template( + "/accounts/{account_id}/data-security/posture/asset_schemas/{asset_class}", + account_id=account_id, + asset_class=asset_class, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Optional[AssetSchemaGetResponse]]._unwrapper, + ), + cast_to=cast(Type[Optional[AssetSchemaGetResponse]], ResultWrapper[AssetSchemaGetResponse]), + ) + + +class AsyncAssetSchemasResource(AsyncAPIResource): + @cached_property + def with_raw_response(self) -> AsyncAssetSchemasResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers + """ + return AsyncAssetSchemasResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncAssetSchemasResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response + """ + return AsyncAssetSchemasResourceWithStreamingResponse(self) + + def list( + self, + *, + account_id: str, + vendor: Literal[ + "ANTHROPIC", + "AWS", + "BITBUCKET", + "BOX", + "CONFLUENCE", + "DROPBOX", + "GITHUB", + "GOOGLE_CLOUD_PLATFORM", + "GOOGLE_WORKSPACE", + "JIRA", + "MICROSOFT", + "OPENAI", + "SALESFORCE", + "SERVICENOW", + "SLACK", + "WORKDAY", + "ZOOM", + ] + | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> AsyncPaginator[AssetSchemaListResponse, AsyncSinglePage[AssetSchemaListResponse]]: + """ + Returns the catalog of asset classes available when authoring custom findings, + grouped by vendor. Optionally filter to a single vendor with the `vendor` query + parameter. + + Args: + vendor: Restrict the result to a single vendor. Unknown values return 400. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + return self._get_api_list( + path_template("/accounts/{account_id}/data-security/posture/asset_schemas", account_id=account_id), + page=AsyncSinglePage[AssetSchemaListResponse], + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform({"vendor": vendor}, asset_schema_list_params.AssetSchemaListParams), + ), + model=AssetSchemaListResponse, + ) + + async def get( + self, + asset_class: str, + *, + account_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> Optional[AssetSchemaGetResponse]: + """ + Returns the fields and related attributes a custom finding type may reference + for the given asset class (JSON Schema). Used by the custom finding types + builder. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not asset_class: + raise ValueError(f"Expected a non-empty value for `asset_class` but received {asset_class!r}") + return await self._get( + path_template( + "/accounts/{account_id}/data-security/posture/asset_schemas/{asset_class}", + account_id=account_id, + asset_class=asset_class, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Optional[AssetSchemaGetResponse]]._unwrapper, + ), + cast_to=cast(Type[Optional[AssetSchemaGetResponse]], ResultWrapper[AssetSchemaGetResponse]), + ) + + +class AssetSchemasResourceWithRawResponse: + def __init__(self, asset_schemas: AssetSchemasResource) -> None: + self._asset_schemas = asset_schemas + + self.list = to_raw_response_wrapper( + asset_schemas.list, + ) + self.get = to_raw_response_wrapper( + asset_schemas.get, + ) + + +class AsyncAssetSchemasResourceWithRawResponse: + def __init__(self, asset_schemas: AsyncAssetSchemasResource) -> None: + self._asset_schemas = asset_schemas + + self.list = async_to_raw_response_wrapper( + asset_schemas.list, + ) + self.get = async_to_raw_response_wrapper( + asset_schemas.get, + ) + + +class AssetSchemasResourceWithStreamingResponse: + def __init__(self, asset_schemas: AssetSchemasResource) -> None: + self._asset_schemas = asset_schemas + + self.list = to_streamed_response_wrapper( + asset_schemas.list, + ) + self.get = to_streamed_response_wrapper( + asset_schemas.get, + ) + + +class AsyncAssetSchemasResourceWithStreamingResponse: + def __init__(self, asset_schemas: AsyncAssetSchemasResource) -> None: + self._asset_schemas = asset_schemas + + self.list = async_to_streamed_response_wrapper( + asset_schemas.list, + ) + self.get = async_to_streamed_response_wrapper( + asset_schemas.get, + ) diff --git a/src/cloudflare/resources/zero_trust/casb/posture/finding_types/finding_types.py b/src/cloudflare/resources/zero_trust/casb/posture/finding_types/finding_types.py index 6c1cbd3d264..36dc6187092 100644 --- a/src/cloudflare/resources/zero_trust/casb/posture/finding_types/finding_types.py +++ b/src/cloudflare/resources/zero_trust/casb/posture/finding_types/finding_types.py @@ -2,13 +2,14 @@ from __future__ import annotations -from typing import List, Type, Optional, cast +from typing import List, Type, Union, Optional, cast +from datetime import datetime from typing_extensions import Literal import httpx -from ......_types import Body, Omit, Query, Headers, NotGiven, omit, not_given -from ......_utils import path_template, maybe_transform +from ......_types import Body, Omit, Query, Headers, NoneType, NotGiven, SequenceNotStr, omit, not_given +from ......_utils import path_template, maybe_transform, async_maybe_transform from ......_compat import cached_property from ......_resource import SyncAPIResource, AsyncAPIResource from ......_response import ( @@ -28,9 +29,17 @@ RemediationTypesResourceWithStreamingResponse, AsyncRemediationTypesResourceWithStreamingResponse, ) -from ......types.zero_trust.casb.posture import finding_type_list_params +from ......types.zero_trust.casb.posture import ( + finding_type_list_params, + finding_type_create_params, + finding_type_update_params, + finding_type_validate_params, +) from ......types.zero_trust.casb.posture.finding_type_get_response import FindingTypeGetResponse from ......types.zero_trust.casb.posture.finding_type_list_response import FindingTypeListResponse +from ......types.zero_trust.casb.posture.finding_type_create_response import FindingTypeCreateResponse +from ......types.zero_trust.casb.posture.finding_type_update_response import FindingTypeUpdateResponse +from ......types.zero_trust.casb.posture.finding_type_validate_response import FindingTypeValidateResponse __all__ = ["FindingTypesResource", "AsyncFindingTypesResource"] @@ -59,13 +68,199 @@ def with_streaming_response(self) -> FindingTypesResourceWithStreamingResponse: """ return FindingTypesResourceWithStreamingResponse(self) + def create( + self, + *, + account_id: str, + applies_to_all_integrations: bool, + asset_class: str, + asset_vendor: Literal[ + "ANTHROPIC", + "AWS", + "BITBUCKET", + "BOX", + "CONFLUENCE", + "DROPBOX", + "GITHUB", + "GOOGLE_CLOUD_PLATFORM", + "GOOGLE_WORKSPACE", + "JIRA", + "MICROSOFT", + "OPENAI", + "SALESFORCE", + "SERVICENOW", + "SLACK", + "ZOOM", + ], + description: str, + expression: str, + name: str, + severity: Literal["Critical", "High", "Medium", "Low"], + integration_ids: SequenceNotStr[str] | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> Optional[FindingTypeCreateResponse]: + """ + Create a new custom finding type with policy definition. + + Args: + applies_to_all_integrations: When true, this finding type applies to every current and future integration of + the vendor. + + asset_class: Asset class this finding type applies to (PascalCase, e.g. GoogleWorkspaceFile) + + asset_vendor: Canonical vendor enum for the platform whose assets this finding type evaluates. + + description: Human-readable description of the finding type. Cannot be empty. Maximum 4096 + characters. + + expression: Rego expression body for the policy. `package cloudflare.casb.custom` and + `import rego.v1` are added automatically. Do not include package or import + declarations. This field cannot be changed after creation. Maximum 4096 + characters. + + name: Human-readable name for the finding type. Maximum 256 characters. + + severity: Default severity used when no integration-specific severity override exists. + + integration_ids: Required and non-empty when applies_to_all_integrations is false; omit when it + is true. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + return self._post( + path_template("/accounts/{account_id}/data-security/posture/finding_types", account_id=account_id), + body=maybe_transform( + { + "applies_to_all_integrations": applies_to_all_integrations, + "asset_class": asset_class, + "asset_vendor": asset_vendor, + "description": description, + "expression": expression, + "name": name, + "severity": severity, + "integration_ids": integration_ids, + }, + finding_type_create_params.FindingTypeCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Optional[FindingTypeCreateResponse]]._unwrapper, + ), + cast_to=cast(Type[Optional[FindingTypeCreateResponse]], ResultWrapper[FindingTypeCreateResponse]), + ) + + def update( + self, + finding_type_id: str, + *, + account_id: str, + applies_to_all_integrations: bool, + description: str | Omit = omit, + integration_ids: SequenceNotStr[str] | Omit = omit, + name: str | Omit = omit, + severity: Literal["Critical", "High", "Medium", "Low"] | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> Optional[FindingTypeUpdateResponse]: + """ + Update an existing custom finding type. + + **Immutable fields**: asset_vendor, asset_class, expression, and category cannot + be changed after creation. + + **Security**: Only custom finding types (not system-managed) can be updated. + + Args: + applies_to_all_integrations: When true, this finding type applies to every current and future integration of + the vendor. + + description: Optional description of the finding type. Cannot be empty if provided. Maximum + 4096 characters. + + integration_ids: Required and non-empty when applies_to_all_integrations is false; omit when it + is true. + + name: Human-readable name for the finding type. Cannot be empty if provided. Maximum + 256 characters. + + severity: Default severity used when no integration-specific severity override exists. + Changing it reclassifies existing and future findings that do not have an + override. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not finding_type_id: + raise ValueError(f"Expected a non-empty value for `finding_type_id` but received {finding_type_id!r}") + return self._put( + path_template( + "/accounts/{account_id}/data-security/posture/finding_types/{finding_type_id}", + account_id=account_id, + finding_type_id=finding_type_id, + ), + body=maybe_transform( + { + "applies_to_all_integrations": applies_to_all_integrations, + "description": description, + "integration_ids": integration_ids, + "name": name, + "severity": severity, + }, + finding_type_update_params.FindingTypeUpdateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Optional[FindingTypeUpdateResponse]]._unwrapper, + ), + cast_to=cast(Type[Optional[FindingTypeUpdateResponse]], ResultWrapper[FindingTypeUpdateResponse]), + ) + def list( self, *, account_id: str, + direction: Literal["asc", "desc"] | Omit = omit, + max_updated_at: Union[str, datetime] | Omit = omit, + min_updated_at: Union[str, datetime] | Omit = omit, + order: Literal["created", "updated", "match_count", "name", "vendor", "type", "origin", "severity"] + | Omit = omit, + origins: List[Literal["custom", "system"]] | Omit = omit, page: int | Omit = omit, per_page: int | Omit = omit, + quarantined: bool | Omit = omit, search: str | Omit = omit, + severities: List[Literal["critical", "high", "medium", "low"]] | Omit = omit, + types: List[Literal["Content", "Posture"]] | Omit = omit, vendors: List[ Literal[ "ANTHROPIC", @@ -79,7 +274,6 @@ def list( "GOOGLE_WORKSPACE", "JIRA", "MICROSOFT", - "MICROSOFT_INTERNAL", "OPENAI", "SALESFORCE", "SERVICENOW", @@ -99,12 +293,38 @@ def list( List all available finding types with pagination support. Args: + direction: Sort direction for the primary field. Defaults to 'desc'. Ties are resolved by + case-insensitive name, then ID, both ascending regardless of direction. + + max_updated_at: Return only finding types updated at or before this RFC 3339 timestamp + (inclusive). + + min_updated_at: Return only finding types updated at or after this RFC 3339 timestamp + (inclusive). + + order: Field to sort by (case-insensitive). Defaults to 'created'. Name and vendor + sorting is case-insensitive; vendor uses friendly provider names. Ascending + order: type Content then Posture; origin custom then system; severity Low, + Medium, High, Critical. + + origins: Filter finding types by origin. Supports multiple comma-separated, + case-insensitive values. + page: A page number within the paginated result set. per_page: Number of results to return per page. + quarantined: When true, return only quarantined finding types; when false, return only + non-quarantined finding types. Omit to return both. + search: Filter finding types by name or ID (case-insensitive substring match). + severities: Filter finding types by severity. Supports multiple comma-separated, + case-insensitive values. + + types: Filter finding types by category type. Supports multiple comma-separated, + case-insensitive values. + vendors: Filter finding types by vendor. Supports multiple comma-separated values. Each value may be either the vendor enum (GOOGLE_WORKSPACE) or the friendly name returned by the read routes (Google Workspace). @@ -129,9 +349,17 @@ def list( timeout=timeout, query=maybe_transform( { + "direction": direction, + "max_updated_at": max_updated_at, + "min_updated_at": min_updated_at, + "order": order, + "origins": origins, "page": page, "per_page": per_page, + "quarantined": quarantined, "search": search, + "severities": severities, + "types": types, "vendors": vendors, }, finding_type_list_params.FindingTypeListParams, @@ -140,6 +368,49 @@ def list( model=FindingTypeListResponse, ) + def delete( + self, + finding_type_id: str, + *, + account_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> None: + """ + Delete an existing custom finding type. + + **Security**: Only custom finding types (not system-managed) can be deleted. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not finding_type_id: + raise ValueError(f"Expected a non-empty value for `finding_type_id` but received {finding_type_id!r}") + extra_headers = {"Accept": "*/*", **(extra_headers or {})} + return self._delete( + path_template( + "/accounts/{account_id}/data-security/posture/finding_types/{finding_type_id}", + account_id=account_id, + finding_type_id=finding_type_id, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=NoneType, + ) + def get( self, finding_type_id: str, @@ -184,6 +455,114 @@ def get( cast_to=cast(Type[Optional[FindingTypeGetResponse]], ResultWrapper[FindingTypeGetResponse]), ) + def validate( + self, + *, + account_id: str, + applies_to_all_integrations: bool, + asset_class: str, + asset_vendor: Literal[ + "ANTHROPIC", + "AWS", + "BITBUCKET", + "BOX", + "CONFLUENCE", + "DROPBOX", + "GITHUB", + "GOOGLE_CLOUD_PLATFORM", + "GOOGLE_WORKSPACE", + "JIRA", + "MICROSOFT", + "OPENAI", + "SALESFORCE", + "SERVICENOW", + "SLACK", + "ZOOM", + ], + description: str, + expression: str, + name: str, + severity: Literal["Critical", "High", "Medium", "Low"], + integration_ids: SequenceNotStr[str] | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> Optional[FindingTypeValidateResponse]: + """ + Check a candidate custom finding type without creating it, so problems can be + corrected before publishing. The request body is the same shape as + `CreateFindingType`, and the candidate is checked against the same rules, so a + valid result means the definition itself is sound. It is not a reservation: a + create can still be rejected for a reason that does not belong to the + definition, such as the account already holding the maximum number of custom + finding types. + + A candidate that fails validation is still a **200** with `result.valid: false` + and one entry in `result.errors` per problem — that is the answer this endpoint + exists to give. `4xx` is reserved for a request that could not be processed at + all, such as a body that will not parse. + + Args: + applies_to_all_integrations: When true, this finding type applies to every current and future integration of + the vendor. + + asset_class: Asset class this finding type applies to (PascalCase, e.g. GoogleWorkspaceFile) + + asset_vendor: Canonical vendor enum for the platform whose assets this finding type evaluates. + + description: Human-readable description of the finding type. Cannot be empty. Maximum 4096 + characters. + + expression: Rego expression body for the policy. `package cloudflare.casb.custom` and + `import rego.v1` are added automatically. Do not include package or import + declarations. This field cannot be changed after creation. Maximum 4096 + characters. + + name: Human-readable name for the finding type. Maximum 256 characters. + + severity: Default severity used when no integration-specific severity override exists. + + integration_ids: Required and non-empty when applies_to_all_integrations is false; omit when it + is true. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + return self._post( + path_template("/accounts/{account_id}/data-security/posture/finding_types/validate", account_id=account_id), + body=maybe_transform( + { + "applies_to_all_integrations": applies_to_all_integrations, + "asset_class": asset_class, + "asset_vendor": asset_vendor, + "description": description, + "expression": expression, + "name": name, + "severity": severity, + "integration_ids": integration_ids, + }, + finding_type_validate_params.FindingTypeValidateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Optional[FindingTypeValidateResponse]]._unwrapper, + ), + cast_to=cast(Type[Optional[FindingTypeValidateResponse]], ResultWrapper[FindingTypeValidateResponse]), + ) + class AsyncFindingTypesResource(AsyncAPIResource): @cached_property @@ -209,13 +588,199 @@ def with_streaming_response(self) -> AsyncFindingTypesResourceWithStreamingRespo """ return AsyncFindingTypesResourceWithStreamingResponse(self) + async def create( + self, + *, + account_id: str, + applies_to_all_integrations: bool, + asset_class: str, + asset_vendor: Literal[ + "ANTHROPIC", + "AWS", + "BITBUCKET", + "BOX", + "CONFLUENCE", + "DROPBOX", + "GITHUB", + "GOOGLE_CLOUD_PLATFORM", + "GOOGLE_WORKSPACE", + "JIRA", + "MICROSOFT", + "OPENAI", + "SALESFORCE", + "SERVICENOW", + "SLACK", + "ZOOM", + ], + description: str, + expression: str, + name: str, + severity: Literal["Critical", "High", "Medium", "Low"], + integration_ids: SequenceNotStr[str] | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> Optional[FindingTypeCreateResponse]: + """ + Create a new custom finding type with policy definition. + + Args: + applies_to_all_integrations: When true, this finding type applies to every current and future integration of + the vendor. + + asset_class: Asset class this finding type applies to (PascalCase, e.g. GoogleWorkspaceFile) + + asset_vendor: Canonical vendor enum for the platform whose assets this finding type evaluates. + + description: Human-readable description of the finding type. Cannot be empty. Maximum 4096 + characters. + + expression: Rego expression body for the policy. `package cloudflare.casb.custom` and + `import rego.v1` are added automatically. Do not include package or import + declarations. This field cannot be changed after creation. Maximum 4096 + characters. + + name: Human-readable name for the finding type. Maximum 256 characters. + + severity: Default severity used when no integration-specific severity override exists. + + integration_ids: Required and non-empty when applies_to_all_integrations is false; omit when it + is true. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + return await self._post( + path_template("/accounts/{account_id}/data-security/posture/finding_types", account_id=account_id), + body=await async_maybe_transform( + { + "applies_to_all_integrations": applies_to_all_integrations, + "asset_class": asset_class, + "asset_vendor": asset_vendor, + "description": description, + "expression": expression, + "name": name, + "severity": severity, + "integration_ids": integration_ids, + }, + finding_type_create_params.FindingTypeCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Optional[FindingTypeCreateResponse]]._unwrapper, + ), + cast_to=cast(Type[Optional[FindingTypeCreateResponse]], ResultWrapper[FindingTypeCreateResponse]), + ) + + async def update( + self, + finding_type_id: str, + *, + account_id: str, + applies_to_all_integrations: bool, + description: str | Omit = omit, + integration_ids: SequenceNotStr[str] | Omit = omit, + name: str | Omit = omit, + severity: Literal["Critical", "High", "Medium", "Low"] | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> Optional[FindingTypeUpdateResponse]: + """ + Update an existing custom finding type. + + **Immutable fields**: asset_vendor, asset_class, expression, and category cannot + be changed after creation. + + **Security**: Only custom finding types (not system-managed) can be updated. + + Args: + applies_to_all_integrations: When true, this finding type applies to every current and future integration of + the vendor. + + description: Optional description of the finding type. Cannot be empty if provided. Maximum + 4096 characters. + + integration_ids: Required and non-empty when applies_to_all_integrations is false; omit when it + is true. + + name: Human-readable name for the finding type. Cannot be empty if provided. Maximum + 256 characters. + + severity: Default severity used when no integration-specific severity override exists. + Changing it reclassifies existing and future findings that do not have an + override. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not finding_type_id: + raise ValueError(f"Expected a non-empty value for `finding_type_id` but received {finding_type_id!r}") + return await self._put( + path_template( + "/accounts/{account_id}/data-security/posture/finding_types/{finding_type_id}", + account_id=account_id, + finding_type_id=finding_type_id, + ), + body=await async_maybe_transform( + { + "applies_to_all_integrations": applies_to_all_integrations, + "description": description, + "integration_ids": integration_ids, + "name": name, + "severity": severity, + }, + finding_type_update_params.FindingTypeUpdateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Optional[FindingTypeUpdateResponse]]._unwrapper, + ), + cast_to=cast(Type[Optional[FindingTypeUpdateResponse]], ResultWrapper[FindingTypeUpdateResponse]), + ) + def list( self, *, account_id: str, + direction: Literal["asc", "desc"] | Omit = omit, + max_updated_at: Union[str, datetime] | Omit = omit, + min_updated_at: Union[str, datetime] | Omit = omit, + order: Literal["created", "updated", "match_count", "name", "vendor", "type", "origin", "severity"] + | Omit = omit, + origins: List[Literal["custom", "system"]] | Omit = omit, page: int | Omit = omit, per_page: int | Omit = omit, + quarantined: bool | Omit = omit, search: str | Omit = omit, + severities: List[Literal["critical", "high", "medium", "low"]] | Omit = omit, + types: List[Literal["Content", "Posture"]] | Omit = omit, vendors: List[ Literal[ "ANTHROPIC", @@ -229,7 +794,6 @@ def list( "GOOGLE_WORKSPACE", "JIRA", "MICROSOFT", - "MICROSOFT_INTERNAL", "OPENAI", "SALESFORCE", "SERVICENOW", @@ -249,12 +813,38 @@ def list( List all available finding types with pagination support. Args: + direction: Sort direction for the primary field. Defaults to 'desc'. Ties are resolved by + case-insensitive name, then ID, both ascending regardless of direction. + + max_updated_at: Return only finding types updated at or before this RFC 3339 timestamp + (inclusive). + + min_updated_at: Return only finding types updated at or after this RFC 3339 timestamp + (inclusive). + + order: Field to sort by (case-insensitive). Defaults to 'created'. Name and vendor + sorting is case-insensitive; vendor uses friendly provider names. Ascending + order: type Content then Posture; origin custom then system; severity Low, + Medium, High, Critical. + + origins: Filter finding types by origin. Supports multiple comma-separated, + case-insensitive values. + page: A page number within the paginated result set. per_page: Number of results to return per page. + quarantined: When true, return only quarantined finding types; when false, return only + non-quarantined finding types. Omit to return both. + search: Filter finding types by name or ID (case-insensitive substring match). + severities: Filter finding types by severity. Supports multiple comma-separated, + case-insensitive values. + + types: Filter finding types by category type. Supports multiple comma-separated, + case-insensitive values. + vendors: Filter finding types by vendor. Supports multiple comma-separated values. Each value may be either the vendor enum (GOOGLE_WORKSPACE) or the friendly name returned by the read routes (Google Workspace). @@ -279,9 +869,17 @@ def list( timeout=timeout, query=maybe_transform( { + "direction": direction, + "max_updated_at": max_updated_at, + "min_updated_at": min_updated_at, + "order": order, + "origins": origins, "page": page, "per_page": per_page, + "quarantined": quarantined, "search": search, + "severities": severities, + "types": types, "vendors": vendors, }, finding_type_list_params.FindingTypeListParams, @@ -290,6 +888,49 @@ def list( model=FindingTypeListResponse, ) + async def delete( + self, + finding_type_id: str, + *, + account_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> None: + """ + Delete an existing custom finding type. + + **Security**: Only custom finding types (not system-managed) can be deleted. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not finding_type_id: + raise ValueError(f"Expected a non-empty value for `finding_type_id` but received {finding_type_id!r}") + extra_headers = {"Accept": "*/*", **(extra_headers or {})} + return await self._delete( + path_template( + "/accounts/{account_id}/data-security/posture/finding_types/{finding_type_id}", + account_id=account_id, + finding_type_id=finding_type_id, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=NoneType, + ) + async def get( self, finding_type_id: str, @@ -334,17 +975,137 @@ async def get( cast_to=cast(Type[Optional[FindingTypeGetResponse]], ResultWrapper[FindingTypeGetResponse]), ) + async def validate( + self, + *, + account_id: str, + applies_to_all_integrations: bool, + asset_class: str, + asset_vendor: Literal[ + "ANTHROPIC", + "AWS", + "BITBUCKET", + "BOX", + "CONFLUENCE", + "DROPBOX", + "GITHUB", + "GOOGLE_CLOUD_PLATFORM", + "GOOGLE_WORKSPACE", + "JIRA", + "MICROSOFT", + "OPENAI", + "SALESFORCE", + "SERVICENOW", + "SLACK", + "ZOOM", + ], + description: str, + expression: str, + name: str, + severity: Literal["Critical", "High", "Medium", "Low"], + integration_ids: SequenceNotStr[str] | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> Optional[FindingTypeValidateResponse]: + """ + Check a candidate custom finding type without creating it, so problems can be + corrected before publishing. The request body is the same shape as + `CreateFindingType`, and the candidate is checked against the same rules, so a + valid result means the definition itself is sound. It is not a reservation: a + create can still be rejected for a reason that does not belong to the + definition, such as the account already holding the maximum number of custom + finding types. + + A candidate that fails validation is still a **200** with `result.valid: false` + and one entry in `result.errors` per problem — that is the answer this endpoint + exists to give. `4xx` is reserved for a request that could not be processed at + all, such as a body that will not parse. + + Args: + applies_to_all_integrations: When true, this finding type applies to every current and future integration of + the vendor. + + asset_class: Asset class this finding type applies to (PascalCase, e.g. GoogleWorkspaceFile) + + asset_vendor: Canonical vendor enum for the platform whose assets this finding type evaluates. + + description: Human-readable description of the finding type. Cannot be empty. Maximum 4096 + characters. + + expression: Rego expression body for the policy. `package cloudflare.casb.custom` and + `import rego.v1` are added automatically. Do not include package or import + declarations. This field cannot be changed after creation. Maximum 4096 + characters. + + name: Human-readable name for the finding type. Maximum 256 characters. + + severity: Default severity used when no integration-specific severity override exists. + + integration_ids: Required and non-empty when applies_to_all_integrations is false; omit when it + is true. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + return await self._post( + path_template("/accounts/{account_id}/data-security/posture/finding_types/validate", account_id=account_id), + body=await async_maybe_transform( + { + "applies_to_all_integrations": applies_to_all_integrations, + "asset_class": asset_class, + "asset_vendor": asset_vendor, + "description": description, + "expression": expression, + "name": name, + "severity": severity, + "integration_ids": integration_ids, + }, + finding_type_validate_params.FindingTypeValidateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Optional[FindingTypeValidateResponse]]._unwrapper, + ), + cast_to=cast(Type[Optional[FindingTypeValidateResponse]], ResultWrapper[FindingTypeValidateResponse]), + ) + class FindingTypesResourceWithRawResponse: def __init__(self, finding_types: FindingTypesResource) -> None: self._finding_types = finding_types + self.create = to_raw_response_wrapper( + finding_types.create, + ) + self.update = to_raw_response_wrapper( + finding_types.update, + ) self.list = to_raw_response_wrapper( finding_types.list, ) + self.delete = to_raw_response_wrapper( + finding_types.delete, + ) self.get = to_raw_response_wrapper( finding_types.get, ) + self.validate = to_raw_response_wrapper( + finding_types.validate, + ) @cached_property def remediation_types(self) -> RemediationTypesResourceWithRawResponse: @@ -355,12 +1116,24 @@ class AsyncFindingTypesResourceWithRawResponse: def __init__(self, finding_types: AsyncFindingTypesResource) -> None: self._finding_types = finding_types + self.create = async_to_raw_response_wrapper( + finding_types.create, + ) + self.update = async_to_raw_response_wrapper( + finding_types.update, + ) self.list = async_to_raw_response_wrapper( finding_types.list, ) + self.delete = async_to_raw_response_wrapper( + finding_types.delete, + ) self.get = async_to_raw_response_wrapper( finding_types.get, ) + self.validate = async_to_raw_response_wrapper( + finding_types.validate, + ) @cached_property def remediation_types(self) -> AsyncRemediationTypesResourceWithRawResponse: @@ -371,12 +1144,24 @@ class FindingTypesResourceWithStreamingResponse: def __init__(self, finding_types: FindingTypesResource) -> None: self._finding_types = finding_types + self.create = to_streamed_response_wrapper( + finding_types.create, + ) + self.update = to_streamed_response_wrapper( + finding_types.update, + ) self.list = to_streamed_response_wrapper( finding_types.list, ) + self.delete = to_streamed_response_wrapper( + finding_types.delete, + ) self.get = to_streamed_response_wrapper( finding_types.get, ) + self.validate = to_streamed_response_wrapper( + finding_types.validate, + ) @cached_property def remediation_types(self) -> RemediationTypesResourceWithStreamingResponse: @@ -387,12 +1172,24 @@ class AsyncFindingTypesResourceWithStreamingResponse: def __init__(self, finding_types: AsyncFindingTypesResource) -> None: self._finding_types = finding_types + self.create = async_to_streamed_response_wrapper( + finding_types.create, + ) + self.update = async_to_streamed_response_wrapper( + finding_types.update, + ) self.list = async_to_streamed_response_wrapper( finding_types.list, ) + self.delete = async_to_streamed_response_wrapper( + finding_types.delete, + ) self.get = async_to_streamed_response_wrapper( finding_types.get, ) + self.validate = async_to_streamed_response_wrapper( + finding_types.validate, + ) @cached_property def remediation_types(self) -> AsyncRemediationTypesResourceWithStreamingResponse: diff --git a/src/cloudflare/resources/zero_trust/casb/posture/findings/findings.py b/src/cloudflare/resources/zero_trust/casb/posture/findings/findings.py index a5c37ab2cb2..8d022ff053d 100644 --- a/src/cloudflare/resources/zero_trust/casb/posture/findings/findings.py +++ b/src/cloudflare/resources/zero_trust/casb/posture/findings/findings.py @@ -221,7 +221,7 @@ def export( max_affliction_date: Union[str, datetime] | Omit = omit, min_affliction_date: Union[str, datetime] | Omit = omit, orders: Iterable[finding_export_params.Order] | Omit = omit, - product: Optional[Literal["SaaS", "Cloud"]] | Omit = omit, + product: Literal["SaaS", "Cloud"] | Omit = omit, search: str | Omit = omit, severities: List[Literal["CRITICAL", "HIGH", "MEDIUM", "LOW"]] | Omit = omit, vendors: List[ @@ -706,7 +706,7 @@ async def export( max_affliction_date: Union[str, datetime] | Omit = omit, min_affliction_date: Union[str, datetime] | Omit = omit, orders: Iterable[finding_export_params.Order] | Omit = omit, - product: Optional[Literal["SaaS", "Cloud"]] | Omit = omit, + product: Literal["SaaS", "Cloud"] | Omit = omit, search: str | Omit = omit, severities: List[Literal["CRITICAL", "HIGH", "MEDIUM", "LOW"]] | Omit = omit, vendors: List[ diff --git a/src/cloudflare/resources/zero_trust/casb/posture/posture.py b/src/cloudflare/resources/zero_trust/casb/posture/posture.py index 0b454d56688..c720439a1d3 100644 --- a/src/cloudflare/resources/zero_trust/casb/posture/posture.py +++ b/src/cloudflare/resources/zero_trust/casb/posture/posture.py @@ -28,6 +28,14 @@ ) from ....._compat import cached_property from ....._resource import SyncAPIResource, AsyncAPIResource +from .asset_schemas import ( + AssetSchemasResource, + AsyncAssetSchemasResource, + AssetSchemasResourceWithRawResponse, + AsyncAssetSchemasResourceWithRawResponse, + AssetSchemasResourceWithStreamingResponse, + AsyncAssetSchemasResourceWithStreamingResponse, +) from .findings.findings import ( FindingsResource, AsyncFindingsResource, @@ -77,6 +85,10 @@ def exports(self) -> ExportsResource: def finding_types(self) -> FindingTypesResource: return FindingTypesResource(self._client) + @cached_property + def asset_schemas(self) -> AssetSchemasResource: + return AssetSchemasResource(self._client) + @cached_property def content(self) -> ContentResource: return ContentResource(self._client) @@ -126,6 +138,10 @@ def exports(self) -> AsyncExportsResource: def finding_types(self) -> AsyncFindingTypesResource: return AsyncFindingTypesResource(self._client) + @cached_property + def asset_schemas(self) -> AsyncAssetSchemasResource: + return AsyncAssetSchemasResource(self._client) + @cached_property def content(self) -> AsyncContentResource: return AsyncContentResource(self._client) @@ -178,6 +194,10 @@ def exports(self) -> ExportsResourceWithRawResponse: def finding_types(self) -> FindingTypesResourceWithRawResponse: return FindingTypesResourceWithRawResponse(self._posture.finding_types) + @cached_property + def asset_schemas(self) -> AssetSchemasResourceWithRawResponse: + return AssetSchemasResourceWithRawResponse(self._posture.asset_schemas) + @cached_property def content(self) -> ContentResourceWithRawResponse: return ContentResourceWithRawResponse(self._posture.content) @@ -211,6 +231,10 @@ def exports(self) -> AsyncExportsResourceWithRawResponse: def finding_types(self) -> AsyncFindingTypesResourceWithRawResponse: return AsyncFindingTypesResourceWithRawResponse(self._posture.finding_types) + @cached_property + def asset_schemas(self) -> AsyncAssetSchemasResourceWithRawResponse: + return AsyncAssetSchemasResourceWithRawResponse(self._posture.asset_schemas) + @cached_property def content(self) -> AsyncContentResourceWithRawResponse: return AsyncContentResourceWithRawResponse(self._posture.content) @@ -244,6 +268,10 @@ def exports(self) -> ExportsResourceWithStreamingResponse: def finding_types(self) -> FindingTypesResourceWithStreamingResponse: return FindingTypesResourceWithStreamingResponse(self._posture.finding_types) + @cached_property + def asset_schemas(self) -> AssetSchemasResourceWithStreamingResponse: + return AssetSchemasResourceWithStreamingResponse(self._posture.asset_schemas) + @cached_property def content(self) -> ContentResourceWithStreamingResponse: return ContentResourceWithStreamingResponse(self._posture.content) @@ -277,6 +305,10 @@ def exports(self) -> AsyncExportsResourceWithStreamingResponse: def finding_types(self) -> AsyncFindingTypesResourceWithStreamingResponse: return AsyncFindingTypesResourceWithStreamingResponse(self._posture.finding_types) + @cached_property + def asset_schemas(self) -> AsyncAssetSchemasResourceWithStreamingResponse: + return AsyncAssetSchemasResourceWithStreamingResponse(self._posture.asset_schemas) + @cached_property def content(self) -> AsyncContentResourceWithStreamingResponse: return AsyncContentResourceWithStreamingResponse(self._posture.content) diff --git a/src/cloudflare/resources/zero_trust/cws/__init__.py b/src/cloudflare/resources/zero_trust/cws/__init__.py new file mode 100644 index 00000000000..aa9286a13da --- /dev/null +++ b/src/cloudflare/resources/zero_trust/cws/__init__.py @@ -0,0 +1,145 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from .cws import ( + CWSResource, + AsyncCWSResource, + CWSResourceWithRawResponse, + AsyncCWSResourceWithRawResponse, + CWSResourceWithStreamingResponse, + AsyncCWSResourceWithStreamingResponse, +) +from .policies import ( + PoliciesResource, + AsyncPoliciesResource, + PoliciesResourceWithRawResponse, + AsyncPoliciesResourceWithRawResponse, + PoliciesResourceWithStreamingResponse, + AsyncPoliciesResourceWithStreamingResponse, +) +from .workloads import ( + WorkloadsResource, + AsyncWorkloadsResource, + WorkloadsResourceWithRawResponse, + AsyncWorkloadsResourceWithRawResponse, + WorkloadsResourceWithStreamingResponse, + AsyncWorkloadsResourceWithStreamingResponse, +) +from .deployments import ( + DeploymentsResource, + AsyncDeploymentsResource, + DeploymentsResourceWithRawResponse, + AsyncDeploymentsResourceWithRawResponse, + DeploymentsResourceWithStreamingResponse, + AsyncDeploymentsResourceWithStreamingResponse, +) +from .domain_acls import ( + DomainACLsResource, + AsyncDomainACLsResource, + DomainACLsResourceWithRawResponse, + AsyncDomainACLsResourceWithRawResponse, + DomainACLsResourceWithStreamingResponse, + AsyncDomainACLsResourceWithStreamingResponse, +) +from .policy_sets import ( + PolicySetsResource, + AsyncPolicySetsResource, + PolicySetsResourceWithRawResponse, + AsyncPolicySetsResourceWithRawResponse, + PolicySetsResourceWithStreamingResponse, + AsyncPolicySetsResourceWithStreamingResponse, +) +from .rego_modules import ( + RegoModulesResource, + AsyncRegoModulesResource, + RegoModulesResourceWithRawResponse, + AsyncRegoModulesResourceWithRawResponse, + RegoModulesResourceWithStreamingResponse, + AsyncRegoModulesResourceWithStreamingResponse, +) +from .rego_metadata import ( + RegoMetadataResource, + AsyncRegoMetadataResource, + RegoMetadataResourceWithRawResponse, + AsyncRegoMetadataResourceWithRawResponse, + RegoMetadataResourceWithStreamingResponse, + AsyncRegoMetadataResourceWithStreamingResponse, +) +from .tenant_structures import ( + TenantStructuresResource, + AsyncTenantStructuresResource, + TenantStructuresResourceWithRawResponse, + AsyncTenantStructuresResourceWithRawResponse, + TenantStructuresResourceWithStreamingResponse, + AsyncTenantStructuresResourceWithStreamingResponse, +) +from .basic_auth_credentials import ( + BasicAuthCredentialsResource, + AsyncBasicAuthCredentialsResource, + BasicAuthCredentialsResourceWithRawResponse, + AsyncBasicAuthCredentialsResourceWithRawResponse, + BasicAuthCredentialsResourceWithStreamingResponse, + AsyncBasicAuthCredentialsResourceWithStreamingResponse, +) + +__all__ = [ + "BasicAuthCredentialsResource", + "AsyncBasicAuthCredentialsResource", + "BasicAuthCredentialsResourceWithRawResponse", + "AsyncBasicAuthCredentialsResourceWithRawResponse", + "BasicAuthCredentialsResourceWithStreamingResponse", + "AsyncBasicAuthCredentialsResourceWithStreamingResponse", + "DeploymentsResource", + "AsyncDeploymentsResource", + "DeploymentsResourceWithRawResponse", + "AsyncDeploymentsResourceWithRawResponse", + "DeploymentsResourceWithStreamingResponse", + "AsyncDeploymentsResourceWithStreamingResponse", + "DomainACLsResource", + "AsyncDomainACLsResource", + "DomainACLsResourceWithRawResponse", + "AsyncDomainACLsResourceWithRawResponse", + "DomainACLsResourceWithStreamingResponse", + "AsyncDomainACLsResourceWithStreamingResponse", + "PoliciesResource", + "AsyncPoliciesResource", + "PoliciesResourceWithRawResponse", + "AsyncPoliciesResourceWithRawResponse", + "PoliciesResourceWithStreamingResponse", + "AsyncPoliciesResourceWithStreamingResponse", + "PolicySetsResource", + "AsyncPolicySetsResource", + "PolicySetsResourceWithRawResponse", + "AsyncPolicySetsResourceWithRawResponse", + "PolicySetsResourceWithStreamingResponse", + "AsyncPolicySetsResourceWithStreamingResponse", + "RegoMetadataResource", + "AsyncRegoMetadataResource", + "RegoMetadataResourceWithRawResponse", + "AsyncRegoMetadataResourceWithRawResponse", + "RegoMetadataResourceWithStreamingResponse", + "AsyncRegoMetadataResourceWithStreamingResponse", + "RegoModulesResource", + "AsyncRegoModulesResource", + "RegoModulesResourceWithRawResponse", + "AsyncRegoModulesResourceWithRawResponse", + "RegoModulesResourceWithStreamingResponse", + "AsyncRegoModulesResourceWithStreamingResponse", + "TenantStructuresResource", + "AsyncTenantStructuresResource", + "TenantStructuresResourceWithRawResponse", + "AsyncTenantStructuresResourceWithRawResponse", + "TenantStructuresResourceWithStreamingResponse", + "AsyncTenantStructuresResourceWithStreamingResponse", + "WorkloadsResource", + "AsyncWorkloadsResource", + "WorkloadsResourceWithRawResponse", + "AsyncWorkloadsResourceWithRawResponse", + "WorkloadsResourceWithStreamingResponse", + "AsyncWorkloadsResourceWithStreamingResponse", + "CWSResource", + "AsyncCWSResource", + "CWSResourceWithRawResponse", + "AsyncCWSResourceWithRawResponse", + "CWSResourceWithStreamingResponse", + "AsyncCWSResourceWithStreamingResponse", +] diff --git a/src/cloudflare/resources/zero_trust/cws/basic_auth_credentials/__init__.py b/src/cloudflare/resources/zero_trust/cws/basic_auth_credentials/__init__.py new file mode 100644 index 00000000000..9118d0b4de3 --- /dev/null +++ b/src/cloudflare/resources/zero_trust/cws/basic_auth_credentials/__init__.py @@ -0,0 +1,33 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from .secrets import ( + SecretsResource, + AsyncSecretsResource, + SecretsResourceWithRawResponse, + AsyncSecretsResourceWithRawResponse, + SecretsResourceWithStreamingResponse, + AsyncSecretsResourceWithStreamingResponse, +) +from .basic_auth_credentials import ( + BasicAuthCredentialsResource, + AsyncBasicAuthCredentialsResource, + BasicAuthCredentialsResourceWithRawResponse, + AsyncBasicAuthCredentialsResourceWithRawResponse, + BasicAuthCredentialsResourceWithStreamingResponse, + AsyncBasicAuthCredentialsResourceWithStreamingResponse, +) + +__all__ = [ + "SecretsResource", + "AsyncSecretsResource", + "SecretsResourceWithRawResponse", + "AsyncSecretsResourceWithRawResponse", + "SecretsResourceWithStreamingResponse", + "AsyncSecretsResourceWithStreamingResponse", + "BasicAuthCredentialsResource", + "AsyncBasicAuthCredentialsResource", + "BasicAuthCredentialsResourceWithRawResponse", + "AsyncBasicAuthCredentialsResourceWithRawResponse", + "BasicAuthCredentialsResourceWithStreamingResponse", + "AsyncBasicAuthCredentialsResourceWithStreamingResponse", +] diff --git a/src/cloudflare/resources/zero_trust/cws/basic_auth_credentials/basic_auth_credentials.py b/src/cloudflare/resources/zero_trust/cws/basic_auth_credentials/basic_auth_credentials.py new file mode 100644 index 00000000000..2b7d254233b --- /dev/null +++ b/src/cloudflare/resources/zero_trust/cws/basic_auth_credentials/basic_auth_credentials.py @@ -0,0 +1,591 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Type, cast +from typing_extensions import Literal + +import httpx + +from .secrets import ( + SecretsResource, + AsyncSecretsResource, + SecretsResourceWithRawResponse, + AsyncSecretsResourceWithRawResponse, + SecretsResourceWithStreamingResponse, + AsyncSecretsResourceWithStreamingResponse, +) +from ....._types import Body, Omit, Query, Headers, NotGiven, omit, not_given +from ....._utils import path_template, maybe_transform, async_maybe_transform +from ....._compat import cached_property +from ....._resource import SyncAPIResource, AsyncAPIResource +from ....._response import ( + to_raw_response_wrapper, + to_streamed_response_wrapper, + async_to_raw_response_wrapper, + async_to_streamed_response_wrapper, +) +from ....._wrappers import ResultWrapper +from .....pagination import SyncCursorPagination, AsyncCursorPagination +from ....._base_client import AsyncPaginator, make_request_options +from .....types.zero_trust.cws import basic_auth_credential_list_params, basic_auth_credential_create_params +from .....types.zero_trust.cws.basic_auth_credential import BasicAuthCredential +from .....types.zero_trust.cws.basic_auth_credential_delete_response import BasicAuthCredentialDeleteResponse + +__all__ = ["BasicAuthCredentialsResource", "AsyncBasicAuthCredentialsResource"] + + +class BasicAuthCredentialsResource(SyncAPIResource): + @cached_property + def secrets(self) -> SecretsResource: + return SecretsResource(self._client) + + @cached_property + def with_raw_response(self) -> BasicAuthCredentialsResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers + """ + return BasicAuthCredentialsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> BasicAuthCredentialsResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response + """ + return BasicAuthCredentialsResourceWithStreamingResponse(self) + + def create( + self, + *, + account_id: str, + username: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> BasicAuthCredential: + """ + Creates a basic-auth credential with the specified username. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + username: Login presented by the client. Printable ASCII only, excluding space and colon. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + return self._post( + path_template("/accounts/{account_id}/cws/basic-auth-credentials", account_id=account_id), + body=maybe_transform( + {"username": username}, basic_auth_credential_create_params.BasicAuthCredentialCreateParams + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[BasicAuthCredential]._unwrapper, + ), + cast_to=cast(Type[BasicAuthCredential], ResultWrapper[BasicAuthCredential]), + ) + + def list( + self, + *, + account_id: str, + cursor: str | Omit = omit, + deployment_id: str | Omit = omit, + direction: Literal["asc", "desc"] | Omit = omit, + order: Literal["username", "created_at", "updated_at"] | Omit = omit, + per_page: int | Omit = omit, + username: str | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> SyncCursorPagination[BasicAuthCredential]: + """ + Returns a paginated list of basic-auth credentials in the account. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + cursor: Pagination cursor from previous response + + deployment_id: Filter to credentials attached to this deployment + + direction: Sort direction (default: asc) + + order: Field to order results by (default: created_at) + + per_page: Number of items per page (1-100, default 20) + + username: Filter by username (case-insensitive substring match) + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + return self._get_api_list( + path_template("/accounts/{account_id}/cws/basic-auth-credentials", account_id=account_id), + page=SyncCursorPagination[BasicAuthCredential], + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "cursor": cursor, + "deployment_id": deployment_id, + "direction": direction, + "order": order, + "per_page": per_page, + "username": username, + }, + basic_auth_credential_list_params.BasicAuthCredentialListParams, + ), + ), + model=BasicAuthCredential, + ) + + def delete( + self, + credential_id: str, + *, + account_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> BasicAuthCredentialDeleteResponse: + """ + Deletes the credential and its secrets if it is not attached to a deployment. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + credential_id: ID of the credential to delete + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not credential_id: + raise ValueError(f"Expected a non-empty value for `credential_id` but received {credential_id!r}") + return self._delete( + path_template( + "/accounts/{account_id}/cws/basic-auth-credentials/{credential_id}", + account_id=account_id, + credential_id=credential_id, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[BasicAuthCredentialDeleteResponse]._unwrapper, + ), + cast_to=cast(Type[BasicAuthCredentialDeleteResponse], ResultWrapper[BasicAuthCredentialDeleteResponse]), + ) + + def get( + self, + credential_id: str, + *, + account_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> BasicAuthCredential: + """ + Returns the basic-auth credential with the specified ID. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + credential_id: ID of the credential to retrieve + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not credential_id: + raise ValueError(f"Expected a non-empty value for `credential_id` but received {credential_id!r}") + return self._get( + path_template( + "/accounts/{account_id}/cws/basic-auth-credentials/{credential_id}", + account_id=account_id, + credential_id=credential_id, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[BasicAuthCredential]._unwrapper, + ), + cast_to=cast(Type[BasicAuthCredential], ResultWrapper[BasicAuthCredential]), + ) + + +class AsyncBasicAuthCredentialsResource(AsyncAPIResource): + @cached_property + def secrets(self) -> AsyncSecretsResource: + return AsyncSecretsResource(self._client) + + @cached_property + def with_raw_response(self) -> AsyncBasicAuthCredentialsResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers + """ + return AsyncBasicAuthCredentialsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncBasicAuthCredentialsResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response + """ + return AsyncBasicAuthCredentialsResourceWithStreamingResponse(self) + + async def create( + self, + *, + account_id: str, + username: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> BasicAuthCredential: + """ + Creates a basic-auth credential with the specified username. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + username: Login presented by the client. Printable ASCII only, excluding space and colon. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + return await self._post( + path_template("/accounts/{account_id}/cws/basic-auth-credentials", account_id=account_id), + body=await async_maybe_transform( + {"username": username}, basic_auth_credential_create_params.BasicAuthCredentialCreateParams + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[BasicAuthCredential]._unwrapper, + ), + cast_to=cast(Type[BasicAuthCredential], ResultWrapper[BasicAuthCredential]), + ) + + def list( + self, + *, + account_id: str, + cursor: str | Omit = omit, + deployment_id: str | Omit = omit, + direction: Literal["asc", "desc"] | Omit = omit, + order: Literal["username", "created_at", "updated_at"] | Omit = omit, + per_page: int | Omit = omit, + username: str | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> AsyncPaginator[BasicAuthCredential, AsyncCursorPagination[BasicAuthCredential]]: + """ + Returns a paginated list of basic-auth credentials in the account. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + cursor: Pagination cursor from previous response + + deployment_id: Filter to credentials attached to this deployment + + direction: Sort direction (default: asc) + + order: Field to order results by (default: created_at) + + per_page: Number of items per page (1-100, default 20) + + username: Filter by username (case-insensitive substring match) + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + return self._get_api_list( + path_template("/accounts/{account_id}/cws/basic-auth-credentials", account_id=account_id), + page=AsyncCursorPagination[BasicAuthCredential], + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "cursor": cursor, + "deployment_id": deployment_id, + "direction": direction, + "order": order, + "per_page": per_page, + "username": username, + }, + basic_auth_credential_list_params.BasicAuthCredentialListParams, + ), + ), + model=BasicAuthCredential, + ) + + async def delete( + self, + credential_id: str, + *, + account_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> BasicAuthCredentialDeleteResponse: + """ + Deletes the credential and its secrets if it is not attached to a deployment. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + credential_id: ID of the credential to delete + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not credential_id: + raise ValueError(f"Expected a non-empty value for `credential_id` but received {credential_id!r}") + return await self._delete( + path_template( + "/accounts/{account_id}/cws/basic-auth-credentials/{credential_id}", + account_id=account_id, + credential_id=credential_id, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[BasicAuthCredentialDeleteResponse]._unwrapper, + ), + cast_to=cast(Type[BasicAuthCredentialDeleteResponse], ResultWrapper[BasicAuthCredentialDeleteResponse]), + ) + + async def get( + self, + credential_id: str, + *, + account_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> BasicAuthCredential: + """ + Returns the basic-auth credential with the specified ID. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + credential_id: ID of the credential to retrieve + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not credential_id: + raise ValueError(f"Expected a non-empty value for `credential_id` but received {credential_id!r}") + return await self._get( + path_template( + "/accounts/{account_id}/cws/basic-auth-credentials/{credential_id}", + account_id=account_id, + credential_id=credential_id, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[BasicAuthCredential]._unwrapper, + ), + cast_to=cast(Type[BasicAuthCredential], ResultWrapper[BasicAuthCredential]), + ) + + +class BasicAuthCredentialsResourceWithRawResponse: + def __init__(self, basic_auth_credentials: BasicAuthCredentialsResource) -> None: + self._basic_auth_credentials = basic_auth_credentials + + self.create = to_raw_response_wrapper( + basic_auth_credentials.create, + ) + self.list = to_raw_response_wrapper( + basic_auth_credentials.list, + ) + self.delete = to_raw_response_wrapper( + basic_auth_credentials.delete, + ) + self.get = to_raw_response_wrapper( + basic_auth_credentials.get, + ) + + @cached_property + def secrets(self) -> SecretsResourceWithRawResponse: + return SecretsResourceWithRawResponse(self._basic_auth_credentials.secrets) + + +class AsyncBasicAuthCredentialsResourceWithRawResponse: + def __init__(self, basic_auth_credentials: AsyncBasicAuthCredentialsResource) -> None: + self._basic_auth_credentials = basic_auth_credentials + + self.create = async_to_raw_response_wrapper( + basic_auth_credentials.create, + ) + self.list = async_to_raw_response_wrapper( + basic_auth_credentials.list, + ) + self.delete = async_to_raw_response_wrapper( + basic_auth_credentials.delete, + ) + self.get = async_to_raw_response_wrapper( + basic_auth_credentials.get, + ) + + @cached_property + def secrets(self) -> AsyncSecretsResourceWithRawResponse: + return AsyncSecretsResourceWithRawResponse(self._basic_auth_credentials.secrets) + + +class BasicAuthCredentialsResourceWithStreamingResponse: + def __init__(self, basic_auth_credentials: BasicAuthCredentialsResource) -> None: + self._basic_auth_credentials = basic_auth_credentials + + self.create = to_streamed_response_wrapper( + basic_auth_credentials.create, + ) + self.list = to_streamed_response_wrapper( + basic_auth_credentials.list, + ) + self.delete = to_streamed_response_wrapper( + basic_auth_credentials.delete, + ) + self.get = to_streamed_response_wrapper( + basic_auth_credentials.get, + ) + + @cached_property + def secrets(self) -> SecretsResourceWithStreamingResponse: + return SecretsResourceWithStreamingResponse(self._basic_auth_credentials.secrets) + + +class AsyncBasicAuthCredentialsResourceWithStreamingResponse: + def __init__(self, basic_auth_credentials: AsyncBasicAuthCredentialsResource) -> None: + self._basic_auth_credentials = basic_auth_credentials + + self.create = async_to_streamed_response_wrapper( + basic_auth_credentials.create, + ) + self.list = async_to_streamed_response_wrapper( + basic_auth_credentials.list, + ) + self.delete = async_to_streamed_response_wrapper( + basic_auth_credentials.delete, + ) + self.get = async_to_streamed_response_wrapper( + basic_auth_credentials.get, + ) + + @cached_property + def secrets(self) -> AsyncSecretsResourceWithStreamingResponse: + return AsyncSecretsResourceWithStreamingResponse(self._basic_auth_credentials.secrets) diff --git a/src/cloudflare/resources/zero_trust/cws/basic_auth_credentials/secrets.py b/src/cloudflare/resources/zero_trust/cws/basic_auth_credentials/secrets.py new file mode 100644 index 00000000000..8804d9cc63a --- /dev/null +++ b/src/cloudflare/resources/zero_trust/cws/basic_auth_credentials/secrets.py @@ -0,0 +1,620 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Type, Union, cast +from datetime import datetime +from typing_extensions import Literal + +import httpx + +from ....._types import Body, Omit, Query, Headers, NotGiven, omit, not_given +from ....._utils import path_template, maybe_transform, async_maybe_transform +from ....._compat import cached_property +from ....._resource import SyncAPIResource, AsyncAPIResource +from ....._response import ( + to_raw_response_wrapper, + to_streamed_response_wrapper, + async_to_raw_response_wrapper, + async_to_streamed_response_wrapper, +) +from ....._wrappers import ResultWrapper +from .....pagination import SyncCursorPagination, AsyncCursorPagination +from ....._base_client import AsyncPaginator, make_request_options +from .....types.zero_trust.cws.basic_auth_credentials import secret_list_params, secret_create_params +from .....types.zero_trust.cws.basic_auth_credentials.basic_auth_secret import BasicAuthSecret +from .....types.zero_trust.cws.basic_auth_credentials.secret_delete_response import SecretDeleteResponse + +__all__ = ["SecretsResource", "AsyncSecretsResource"] + + +class SecretsResource(SyncAPIResource): + @cached_property + def with_raw_response(self) -> SecretsResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers + """ + return SecretsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> SecretsResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response + """ + return SecretsResourceWithStreamingResponse(self) + + def create( + self, + credential_id: str, + *, + account_id: str, + password: str, + expires_at: Union[str, datetime, None] | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> BasicAuthSecret: + """ + Adds a password secret to the credential. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + credential_id: ID of the parent credential + + password: Password stored only as a one-way hash and never returned. Maximum 72 UTF-8 + bytes. + + expires_at: Optional deactivation deadline (RFC 3339). Omit or null for no expiry. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not credential_id: + raise ValueError(f"Expected a non-empty value for `credential_id` but received {credential_id!r}") + return self._post( + path_template( + "/accounts/{account_id}/cws/basic-auth-credentials/{credential_id}/secrets", + account_id=account_id, + credential_id=credential_id, + ), + body=maybe_transform( + { + "password": password, + "expires_at": expires_at, + }, + secret_create_params.SecretCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[BasicAuthSecret]._unwrapper, + ), + cast_to=cast(Type[BasicAuthSecret], ResultWrapper[BasicAuthSecret]), + ) + + def list( + self, + credential_id: str, + *, + account_id: str, + cursor: str | Omit = omit, + direction: Literal["asc", "desc"] | Omit = omit, + order: Literal["created_at"] | Omit = omit, + per_page: int | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> SyncCursorPagination[BasicAuthSecret]: + """ + Returns a paginated list of secrets belonging to the credential. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + credential_id: ID of the parent credential + + cursor: Pagination cursor from previous response + + direction: Sort direction (default: asc) + + order: Field to order results by (default: created_at) + + per_page: Number of items per page (1-100, default 20) + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not credential_id: + raise ValueError(f"Expected a non-empty value for `credential_id` but received {credential_id!r}") + return self._get_api_list( + path_template( + "/accounts/{account_id}/cws/basic-auth-credentials/{credential_id}/secrets", + account_id=account_id, + credential_id=credential_id, + ), + page=SyncCursorPagination[BasicAuthSecret], + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "cursor": cursor, + "direction": direction, + "order": order, + "per_page": per_page, + }, + secret_list_params.SecretListParams, + ), + ), + model=BasicAuthSecret, + ) + + def delete( + self, + secret_id: str, + *, + account_id: str, + credential_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> SecretDeleteResponse: + """ + Deletes the specified secret from the credential. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + credential_id: ID of the parent credential + + secret_id: ID of the secret to delete + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not credential_id: + raise ValueError(f"Expected a non-empty value for `credential_id` but received {credential_id!r}") + if not secret_id: + raise ValueError(f"Expected a non-empty value for `secret_id` but received {secret_id!r}") + return self._delete( + path_template( + "/accounts/{account_id}/cws/basic-auth-credentials/{credential_id}/secrets/{secret_id}", + account_id=account_id, + credential_id=credential_id, + secret_id=secret_id, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[SecretDeleteResponse]._unwrapper, + ), + cast_to=cast(Type[SecretDeleteResponse], ResultWrapper[SecretDeleteResponse]), + ) + + def get( + self, + secret_id: str, + *, + account_id: str, + credential_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> BasicAuthSecret: + """ + Returns the specified secret's metadata without exposing its password or hash. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + credential_id: ID of the parent credential + + secret_id: ID of the secret to retrieve + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not credential_id: + raise ValueError(f"Expected a non-empty value for `credential_id` but received {credential_id!r}") + if not secret_id: + raise ValueError(f"Expected a non-empty value for `secret_id` but received {secret_id!r}") + return self._get( + path_template( + "/accounts/{account_id}/cws/basic-auth-credentials/{credential_id}/secrets/{secret_id}", + account_id=account_id, + credential_id=credential_id, + secret_id=secret_id, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[BasicAuthSecret]._unwrapper, + ), + cast_to=cast(Type[BasicAuthSecret], ResultWrapper[BasicAuthSecret]), + ) + + +class AsyncSecretsResource(AsyncAPIResource): + @cached_property + def with_raw_response(self) -> AsyncSecretsResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers + """ + return AsyncSecretsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncSecretsResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response + """ + return AsyncSecretsResourceWithStreamingResponse(self) + + async def create( + self, + credential_id: str, + *, + account_id: str, + password: str, + expires_at: Union[str, datetime, None] | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> BasicAuthSecret: + """ + Adds a password secret to the credential. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + credential_id: ID of the parent credential + + password: Password stored only as a one-way hash and never returned. Maximum 72 UTF-8 + bytes. + + expires_at: Optional deactivation deadline (RFC 3339). Omit or null for no expiry. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not credential_id: + raise ValueError(f"Expected a non-empty value for `credential_id` but received {credential_id!r}") + return await self._post( + path_template( + "/accounts/{account_id}/cws/basic-auth-credentials/{credential_id}/secrets", + account_id=account_id, + credential_id=credential_id, + ), + body=await async_maybe_transform( + { + "password": password, + "expires_at": expires_at, + }, + secret_create_params.SecretCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[BasicAuthSecret]._unwrapper, + ), + cast_to=cast(Type[BasicAuthSecret], ResultWrapper[BasicAuthSecret]), + ) + + def list( + self, + credential_id: str, + *, + account_id: str, + cursor: str | Omit = omit, + direction: Literal["asc", "desc"] | Omit = omit, + order: Literal["created_at"] | Omit = omit, + per_page: int | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> AsyncPaginator[BasicAuthSecret, AsyncCursorPagination[BasicAuthSecret]]: + """ + Returns a paginated list of secrets belonging to the credential. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + credential_id: ID of the parent credential + + cursor: Pagination cursor from previous response + + direction: Sort direction (default: asc) + + order: Field to order results by (default: created_at) + + per_page: Number of items per page (1-100, default 20) + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not credential_id: + raise ValueError(f"Expected a non-empty value for `credential_id` but received {credential_id!r}") + return self._get_api_list( + path_template( + "/accounts/{account_id}/cws/basic-auth-credentials/{credential_id}/secrets", + account_id=account_id, + credential_id=credential_id, + ), + page=AsyncCursorPagination[BasicAuthSecret], + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "cursor": cursor, + "direction": direction, + "order": order, + "per_page": per_page, + }, + secret_list_params.SecretListParams, + ), + ), + model=BasicAuthSecret, + ) + + async def delete( + self, + secret_id: str, + *, + account_id: str, + credential_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> SecretDeleteResponse: + """ + Deletes the specified secret from the credential. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + credential_id: ID of the parent credential + + secret_id: ID of the secret to delete + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not credential_id: + raise ValueError(f"Expected a non-empty value for `credential_id` but received {credential_id!r}") + if not secret_id: + raise ValueError(f"Expected a non-empty value for `secret_id` but received {secret_id!r}") + return await self._delete( + path_template( + "/accounts/{account_id}/cws/basic-auth-credentials/{credential_id}/secrets/{secret_id}", + account_id=account_id, + credential_id=credential_id, + secret_id=secret_id, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[SecretDeleteResponse]._unwrapper, + ), + cast_to=cast(Type[SecretDeleteResponse], ResultWrapper[SecretDeleteResponse]), + ) + + async def get( + self, + secret_id: str, + *, + account_id: str, + credential_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> BasicAuthSecret: + """ + Returns the specified secret's metadata without exposing its password or hash. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + credential_id: ID of the parent credential + + secret_id: ID of the secret to retrieve + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not credential_id: + raise ValueError(f"Expected a non-empty value for `credential_id` but received {credential_id!r}") + if not secret_id: + raise ValueError(f"Expected a non-empty value for `secret_id` but received {secret_id!r}") + return await self._get( + path_template( + "/accounts/{account_id}/cws/basic-auth-credentials/{credential_id}/secrets/{secret_id}", + account_id=account_id, + credential_id=credential_id, + secret_id=secret_id, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[BasicAuthSecret]._unwrapper, + ), + cast_to=cast(Type[BasicAuthSecret], ResultWrapper[BasicAuthSecret]), + ) + + +class SecretsResourceWithRawResponse: + def __init__(self, secrets: SecretsResource) -> None: + self._secrets = secrets + + self.create = to_raw_response_wrapper( + secrets.create, + ) + self.list = to_raw_response_wrapper( + secrets.list, + ) + self.delete = to_raw_response_wrapper( + secrets.delete, + ) + self.get = to_raw_response_wrapper( + secrets.get, + ) + + +class AsyncSecretsResourceWithRawResponse: + def __init__(self, secrets: AsyncSecretsResource) -> None: + self._secrets = secrets + + self.create = async_to_raw_response_wrapper( + secrets.create, + ) + self.list = async_to_raw_response_wrapper( + secrets.list, + ) + self.delete = async_to_raw_response_wrapper( + secrets.delete, + ) + self.get = async_to_raw_response_wrapper( + secrets.get, + ) + + +class SecretsResourceWithStreamingResponse: + def __init__(self, secrets: SecretsResource) -> None: + self._secrets = secrets + + self.create = to_streamed_response_wrapper( + secrets.create, + ) + self.list = to_streamed_response_wrapper( + secrets.list, + ) + self.delete = to_streamed_response_wrapper( + secrets.delete, + ) + self.get = to_streamed_response_wrapper( + secrets.get, + ) + + +class AsyncSecretsResourceWithStreamingResponse: + def __init__(self, secrets: AsyncSecretsResource) -> None: + self._secrets = secrets + + self.create = async_to_streamed_response_wrapper( + secrets.create, + ) + self.list = async_to_streamed_response_wrapper( + secrets.list, + ) + self.delete = async_to_streamed_response_wrapper( + secrets.delete, + ) + self.get = async_to_streamed_response_wrapper( + secrets.get, + ) diff --git a/src/cloudflare/resources/zero_trust/cws/cws.py b/src/cloudflare/resources/zero_trust/cws/cws.py new file mode 100644 index 00000000000..a7a5cbb25d8 --- /dev/null +++ b/src/cloudflare/resources/zero_trust/cws/cws.py @@ -0,0 +1,358 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from .policies import ( + PoliciesResource, + AsyncPoliciesResource, + PoliciesResourceWithRawResponse, + AsyncPoliciesResourceWithRawResponse, + PoliciesResourceWithStreamingResponse, + AsyncPoliciesResourceWithStreamingResponse, +) +from .workloads import ( + WorkloadsResource, + AsyncWorkloadsResource, + WorkloadsResourceWithRawResponse, + AsyncWorkloadsResourceWithRawResponse, + WorkloadsResourceWithStreamingResponse, + AsyncWorkloadsResourceWithStreamingResponse, +) +from ...._compat import cached_property +from .deployments import ( + DeploymentsResource, + AsyncDeploymentsResource, + DeploymentsResourceWithRawResponse, + AsyncDeploymentsResourceWithRawResponse, + DeploymentsResourceWithStreamingResponse, + AsyncDeploymentsResourceWithStreamingResponse, +) +from .domain_acls import ( + DomainACLsResource, + AsyncDomainACLsResource, + DomainACLsResourceWithRawResponse, + AsyncDomainACLsResourceWithRawResponse, + DomainACLsResourceWithStreamingResponse, + AsyncDomainACLsResourceWithStreamingResponse, +) +from .policy_sets import ( + PolicySetsResource, + AsyncPolicySetsResource, + PolicySetsResourceWithRawResponse, + AsyncPolicySetsResourceWithRawResponse, + PolicySetsResourceWithStreamingResponse, + AsyncPolicySetsResourceWithStreamingResponse, +) +from ...._resource import SyncAPIResource, AsyncAPIResource +from .rego_modules import ( + RegoModulesResource, + AsyncRegoModulesResource, + RegoModulesResourceWithRawResponse, + AsyncRegoModulesResourceWithRawResponse, + RegoModulesResourceWithStreamingResponse, + AsyncRegoModulesResourceWithStreamingResponse, +) +from .rego_metadata import ( + RegoMetadataResource, + AsyncRegoMetadataResource, + RegoMetadataResourceWithRawResponse, + AsyncRegoMetadataResourceWithRawResponse, + RegoMetadataResourceWithStreamingResponse, + AsyncRegoMetadataResourceWithStreamingResponse, +) +from .tenant_structures.tenant_structures import ( + TenantStructuresResource, + AsyncTenantStructuresResource, + TenantStructuresResourceWithRawResponse, + AsyncTenantStructuresResourceWithRawResponse, + TenantStructuresResourceWithStreamingResponse, + AsyncTenantStructuresResourceWithStreamingResponse, +) +from .basic_auth_credentials.basic_auth_credentials import ( + BasicAuthCredentialsResource, + AsyncBasicAuthCredentialsResource, + BasicAuthCredentialsResourceWithRawResponse, + AsyncBasicAuthCredentialsResourceWithRawResponse, + BasicAuthCredentialsResourceWithStreamingResponse, + AsyncBasicAuthCredentialsResourceWithStreamingResponse, +) + +__all__ = ["CWSResource", "AsyncCWSResource"] + + +class CWSResource(SyncAPIResource): + @cached_property + def basic_auth_credentials(self) -> BasicAuthCredentialsResource: + return BasicAuthCredentialsResource(self._client) + + @cached_property + def deployments(self) -> DeploymentsResource: + return DeploymentsResource(self._client) + + @cached_property + def domain_acls(self) -> DomainACLsResource: + return DomainACLsResource(self._client) + + @cached_property + def policies(self) -> PoliciesResource: + return PoliciesResource(self._client) + + @cached_property + def policy_sets(self) -> PolicySetsResource: + return PolicySetsResource(self._client) + + @cached_property + def rego_metadata(self) -> RegoMetadataResource: + return RegoMetadataResource(self._client) + + @cached_property + def rego_modules(self) -> RegoModulesResource: + return RegoModulesResource(self._client) + + @cached_property + def tenant_structures(self) -> TenantStructuresResource: + return TenantStructuresResource(self._client) + + @cached_property + def workloads(self) -> WorkloadsResource: + return WorkloadsResource(self._client) + + @cached_property + def with_raw_response(self) -> CWSResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers + """ + return CWSResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> CWSResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response + """ + return CWSResourceWithStreamingResponse(self) + + +class AsyncCWSResource(AsyncAPIResource): + @cached_property + def basic_auth_credentials(self) -> AsyncBasicAuthCredentialsResource: + return AsyncBasicAuthCredentialsResource(self._client) + + @cached_property + def deployments(self) -> AsyncDeploymentsResource: + return AsyncDeploymentsResource(self._client) + + @cached_property + def domain_acls(self) -> AsyncDomainACLsResource: + return AsyncDomainACLsResource(self._client) + + @cached_property + def policies(self) -> AsyncPoliciesResource: + return AsyncPoliciesResource(self._client) + + @cached_property + def policy_sets(self) -> AsyncPolicySetsResource: + return AsyncPolicySetsResource(self._client) + + @cached_property + def rego_metadata(self) -> AsyncRegoMetadataResource: + return AsyncRegoMetadataResource(self._client) + + @cached_property + def rego_modules(self) -> AsyncRegoModulesResource: + return AsyncRegoModulesResource(self._client) + + @cached_property + def tenant_structures(self) -> AsyncTenantStructuresResource: + return AsyncTenantStructuresResource(self._client) + + @cached_property + def workloads(self) -> AsyncWorkloadsResource: + return AsyncWorkloadsResource(self._client) + + @cached_property + def with_raw_response(self) -> AsyncCWSResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers + """ + return AsyncCWSResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncCWSResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response + """ + return AsyncCWSResourceWithStreamingResponse(self) + + +class CWSResourceWithRawResponse: + def __init__(self, cws: CWSResource) -> None: + self._cws = cws + + @cached_property + def basic_auth_credentials(self) -> BasicAuthCredentialsResourceWithRawResponse: + return BasicAuthCredentialsResourceWithRawResponse(self._cws.basic_auth_credentials) + + @cached_property + def deployments(self) -> DeploymentsResourceWithRawResponse: + return DeploymentsResourceWithRawResponse(self._cws.deployments) + + @cached_property + def domain_acls(self) -> DomainACLsResourceWithRawResponse: + return DomainACLsResourceWithRawResponse(self._cws.domain_acls) + + @cached_property + def policies(self) -> PoliciesResourceWithRawResponse: + return PoliciesResourceWithRawResponse(self._cws.policies) + + @cached_property + def policy_sets(self) -> PolicySetsResourceWithRawResponse: + return PolicySetsResourceWithRawResponse(self._cws.policy_sets) + + @cached_property + def rego_metadata(self) -> RegoMetadataResourceWithRawResponse: + return RegoMetadataResourceWithRawResponse(self._cws.rego_metadata) + + @cached_property + def rego_modules(self) -> RegoModulesResourceWithRawResponse: + return RegoModulesResourceWithRawResponse(self._cws.rego_modules) + + @cached_property + def tenant_structures(self) -> TenantStructuresResourceWithRawResponse: + return TenantStructuresResourceWithRawResponse(self._cws.tenant_structures) + + @cached_property + def workloads(self) -> WorkloadsResourceWithRawResponse: + return WorkloadsResourceWithRawResponse(self._cws.workloads) + + +class AsyncCWSResourceWithRawResponse: + def __init__(self, cws: AsyncCWSResource) -> None: + self._cws = cws + + @cached_property + def basic_auth_credentials(self) -> AsyncBasicAuthCredentialsResourceWithRawResponse: + return AsyncBasicAuthCredentialsResourceWithRawResponse(self._cws.basic_auth_credentials) + + @cached_property + def deployments(self) -> AsyncDeploymentsResourceWithRawResponse: + return AsyncDeploymentsResourceWithRawResponse(self._cws.deployments) + + @cached_property + def domain_acls(self) -> AsyncDomainACLsResourceWithRawResponse: + return AsyncDomainACLsResourceWithRawResponse(self._cws.domain_acls) + + @cached_property + def policies(self) -> AsyncPoliciesResourceWithRawResponse: + return AsyncPoliciesResourceWithRawResponse(self._cws.policies) + + @cached_property + def policy_sets(self) -> AsyncPolicySetsResourceWithRawResponse: + return AsyncPolicySetsResourceWithRawResponse(self._cws.policy_sets) + + @cached_property + def rego_metadata(self) -> AsyncRegoMetadataResourceWithRawResponse: + return AsyncRegoMetadataResourceWithRawResponse(self._cws.rego_metadata) + + @cached_property + def rego_modules(self) -> AsyncRegoModulesResourceWithRawResponse: + return AsyncRegoModulesResourceWithRawResponse(self._cws.rego_modules) + + @cached_property + def tenant_structures(self) -> AsyncTenantStructuresResourceWithRawResponse: + return AsyncTenantStructuresResourceWithRawResponse(self._cws.tenant_structures) + + @cached_property + def workloads(self) -> AsyncWorkloadsResourceWithRawResponse: + return AsyncWorkloadsResourceWithRawResponse(self._cws.workloads) + + +class CWSResourceWithStreamingResponse: + def __init__(self, cws: CWSResource) -> None: + self._cws = cws + + @cached_property + def basic_auth_credentials(self) -> BasicAuthCredentialsResourceWithStreamingResponse: + return BasicAuthCredentialsResourceWithStreamingResponse(self._cws.basic_auth_credentials) + + @cached_property + def deployments(self) -> DeploymentsResourceWithStreamingResponse: + return DeploymentsResourceWithStreamingResponse(self._cws.deployments) + + @cached_property + def domain_acls(self) -> DomainACLsResourceWithStreamingResponse: + return DomainACLsResourceWithStreamingResponse(self._cws.domain_acls) + + @cached_property + def policies(self) -> PoliciesResourceWithStreamingResponse: + return PoliciesResourceWithStreamingResponse(self._cws.policies) + + @cached_property + def policy_sets(self) -> PolicySetsResourceWithStreamingResponse: + return PolicySetsResourceWithStreamingResponse(self._cws.policy_sets) + + @cached_property + def rego_metadata(self) -> RegoMetadataResourceWithStreamingResponse: + return RegoMetadataResourceWithStreamingResponse(self._cws.rego_metadata) + + @cached_property + def rego_modules(self) -> RegoModulesResourceWithStreamingResponse: + return RegoModulesResourceWithStreamingResponse(self._cws.rego_modules) + + @cached_property + def tenant_structures(self) -> TenantStructuresResourceWithStreamingResponse: + return TenantStructuresResourceWithStreamingResponse(self._cws.tenant_structures) + + @cached_property + def workloads(self) -> WorkloadsResourceWithStreamingResponse: + return WorkloadsResourceWithStreamingResponse(self._cws.workloads) + + +class AsyncCWSResourceWithStreamingResponse: + def __init__(self, cws: AsyncCWSResource) -> None: + self._cws = cws + + @cached_property + def basic_auth_credentials(self) -> AsyncBasicAuthCredentialsResourceWithStreamingResponse: + return AsyncBasicAuthCredentialsResourceWithStreamingResponse(self._cws.basic_auth_credentials) + + @cached_property + def deployments(self) -> AsyncDeploymentsResourceWithStreamingResponse: + return AsyncDeploymentsResourceWithStreamingResponse(self._cws.deployments) + + @cached_property + def domain_acls(self) -> AsyncDomainACLsResourceWithStreamingResponse: + return AsyncDomainACLsResourceWithStreamingResponse(self._cws.domain_acls) + + @cached_property + def policies(self) -> AsyncPoliciesResourceWithStreamingResponse: + return AsyncPoliciesResourceWithStreamingResponse(self._cws.policies) + + @cached_property + def policy_sets(self) -> AsyncPolicySetsResourceWithStreamingResponse: + return AsyncPolicySetsResourceWithStreamingResponse(self._cws.policy_sets) + + @cached_property + def rego_metadata(self) -> AsyncRegoMetadataResourceWithStreamingResponse: + return AsyncRegoMetadataResourceWithStreamingResponse(self._cws.rego_metadata) + + @cached_property + def rego_modules(self) -> AsyncRegoModulesResourceWithStreamingResponse: + return AsyncRegoModulesResourceWithStreamingResponse(self._cws.rego_modules) + + @cached_property + def tenant_structures(self) -> AsyncTenantStructuresResourceWithStreamingResponse: + return AsyncTenantStructuresResourceWithStreamingResponse(self._cws.tenant_structures) + + @cached_property + def workloads(self) -> AsyncWorkloadsResourceWithStreamingResponse: + return AsyncWorkloadsResourceWithStreamingResponse(self._cws.workloads) diff --git a/src/cloudflare/resources/zero_trust/cws/deployments.py b/src/cloudflare/resources/zero_trust/cws/deployments.py new file mode 100644 index 00000000000..8f7df7ea40f --- /dev/null +++ b/src/cloudflare/resources/zero_trust/cws/deployments.py @@ -0,0 +1,825 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Dict, Type, Optional, cast +from typing_extensions import Literal + +import httpx + +from ...._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given +from ...._utils import path_template, maybe_transform, async_maybe_transform +from ...._compat import cached_property +from ...._resource import SyncAPIResource, AsyncAPIResource +from ...._response import ( + to_raw_response_wrapper, + to_streamed_response_wrapper, + async_to_raw_response_wrapper, + async_to_streamed_response_wrapper, +) +from ...._wrappers import ResultWrapper +from ....pagination import SyncCursorPagination, AsyncCursorPagination +from ...._base_client import AsyncPaginator, make_request_options +from ....types.zero_trust.cws import deployment_list_params, deployment_create_params, deployment_update_params +from ....types.zero_trust.cws.deployment import Deployment +from ....types.zero_trust.cws.deployment_delete_response import DeploymentDeleteResponse + +__all__ = ["DeploymentsResource", "AsyncDeploymentsResource"] + + +class DeploymentsResource(SyncAPIResource): + @cached_property + def with_raw_response(self) -> DeploymentsResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers + """ + return DeploymentsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> DeploymentsResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response + """ + return DeploymentsResourceWithStreamingResponse(self) + + def create( + self, + *, + account_id: str, + basic_auth_credential_ids: Optional[SequenceNotStr[str]], + default_mode: Literal["ALLOW", "BLOCK"], + name: str, + policy_set_ids: Optional[SequenceNotStr[str]], + description: str | Omit = omit, + domain_acl_id: Optional[str] | Omit = omit, + on_error_action: Literal["BLOCK", "SKIP"] | Omit = omit, + rego_raise_error: bool | Omit = omit, + tags: Dict[str, str] | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> Deployment: + """ + Creates a deployment with the specified policy sets, domain ACL, and basic-auth + credentials. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + basic_auth_credential_ids: IDs of basic-auth credentials to attach + + default_mode: Default traffic mode: ALLOW or BLOCK + + name: Name of the deployment + + policy_set_ids: IDs of policy sets to attach + + description: Optional free-form description. + + domain_acl_id: ID of the domain ACL to attach (omit or null for none) + + on_error_action: Action for runtime Rego errors. Omit to use BLOCK. + + rego_raise_error: Whether OPA builtin failures are raised as runtime evaluation errors. Omit to + use the default true value. + + tags: Tags to attach. Keys are limited to 256 UTF-8 bytes and values to 1024 UTF-8 + bytes. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + return self._post( + path_template("/accounts/{account_id}/cws/deployments", account_id=account_id), + body=maybe_transform( + { + "basic_auth_credential_ids": basic_auth_credential_ids, + "default_mode": default_mode, + "name": name, + "policy_set_ids": policy_set_ids, + "description": description, + "domain_acl_id": domain_acl_id, + "on_error_action": on_error_action, + "rego_raise_error": rego_raise_error, + "tags": tags, + }, + deployment_create_params.DeploymentCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Deployment]._unwrapper, + ), + cast_to=cast(Type[Deployment], ResultWrapper[Deployment]), + ) + + def update( + self, + deployment_id: str, + *, + account_id: str, + basic_auth_credential_ids: Optional[SequenceNotStr[str]], + default_mode: Literal["ALLOW", "BLOCK"], + name: str, + policy_set_ids: Optional[SequenceNotStr[str]], + description: str | Omit = omit, + domain_acl_id: Optional[str] | Omit = omit, + on_error_action: Literal["BLOCK", "SKIP"] | Omit = omit, + rego_raise_error: bool | Omit = omit, + tags: Dict[str, str] | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> Deployment: + """ + Replaces the deployment's mutable configuration and resource attachments. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + deployment_id: ID of the deployment to update + + basic_auth_credential_ids: Replacement set of basic-auth credential IDs + + default_mode: Default traffic mode: ALLOW or BLOCK + + name: Name of the deployment + + policy_set_ids: Replacement set of policy set IDs + + description: Optional free-form description. + + domain_acl_id: ID of the domain ACL to attach (omit or null to clear) + + on_error_action: Action for runtime Rego errors. Omit to reset to BLOCK. + + rego_raise_error: Whether OPA builtin failures are raised as runtime evaluation errors. Omit to + reset to true. + + tags: Replacement tag set. Omit or use {} to clear. Keys are limited to 256 UTF-8 + bytes and values to 1024 UTF-8 bytes. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not deployment_id: + raise ValueError(f"Expected a non-empty value for `deployment_id` but received {deployment_id!r}") + return self._put( + path_template( + "/accounts/{account_id}/cws/deployments/{deployment_id}", + account_id=account_id, + deployment_id=deployment_id, + ), + body=maybe_transform( + { + "basic_auth_credential_ids": basic_auth_credential_ids, + "default_mode": default_mode, + "name": name, + "policy_set_ids": policy_set_ids, + "description": description, + "domain_acl_id": domain_acl_id, + "on_error_action": on_error_action, + "rego_raise_error": rego_raise_error, + "tags": tags, + }, + deployment_update_params.DeploymentUpdateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Deployment]._unwrapper, + ), + cast_to=cast(Type[Deployment], ResultWrapper[Deployment]), + ) + + def list( + self, + *, + account_id: str, + cursor: str | Omit = omit, + direction: Literal["asc", "desc"] | Omit = omit, + name: str | Omit = omit, + order: Literal["name", "created_at", "updated_at"] | Omit = omit, + per_page: int | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> SyncCursorPagination[Deployment]: + """ + Returns a paginated list of deployments in the account. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + cursor: Pagination cursor from previous response + + direction: Sort direction (default: asc) + + name: Filter by deployment name (case-insensitive substring match) + + order: Field to order results by (default: created_at) + + per_page: Number of items per page (1-100, default 20) + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + return self._get_api_list( + path_template("/accounts/{account_id}/cws/deployments", account_id=account_id), + page=SyncCursorPagination[Deployment], + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "cursor": cursor, + "direction": direction, + "name": name, + "order": order, + "per_page": per_page, + }, + deployment_list_params.DeploymentListParams, + ), + ), + model=Deployment, + ) + + def delete( + self, + deployment_id: str, + *, + account_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> DeploymentDeleteResponse: + """Deletes the deployment and detaches its associated resources. + + The resources are + not deleted. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + deployment_id: ID of the deployment to delete + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not deployment_id: + raise ValueError(f"Expected a non-empty value for `deployment_id` but received {deployment_id!r}") + return self._delete( + path_template( + "/accounts/{account_id}/cws/deployments/{deployment_id}", + account_id=account_id, + deployment_id=deployment_id, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[DeploymentDeleteResponse]._unwrapper, + ), + cast_to=cast(Type[DeploymentDeleteResponse], ResultWrapper[DeploymentDeleteResponse]), + ) + + def get( + self, + deployment_id: str, + *, + account_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> Deployment: + """ + Returns the deployment with the specified ID. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + deployment_id: ID of the deployment to retrieve + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not deployment_id: + raise ValueError(f"Expected a non-empty value for `deployment_id` but received {deployment_id!r}") + return self._get( + path_template( + "/accounts/{account_id}/cws/deployments/{deployment_id}", + account_id=account_id, + deployment_id=deployment_id, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Deployment]._unwrapper, + ), + cast_to=cast(Type[Deployment], ResultWrapper[Deployment]), + ) + + +class AsyncDeploymentsResource(AsyncAPIResource): + @cached_property + def with_raw_response(self) -> AsyncDeploymentsResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers + """ + return AsyncDeploymentsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncDeploymentsResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response + """ + return AsyncDeploymentsResourceWithStreamingResponse(self) + + async def create( + self, + *, + account_id: str, + basic_auth_credential_ids: Optional[SequenceNotStr[str]], + default_mode: Literal["ALLOW", "BLOCK"], + name: str, + policy_set_ids: Optional[SequenceNotStr[str]], + description: str | Omit = omit, + domain_acl_id: Optional[str] | Omit = omit, + on_error_action: Literal["BLOCK", "SKIP"] | Omit = omit, + rego_raise_error: bool | Omit = omit, + tags: Dict[str, str] | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> Deployment: + """ + Creates a deployment with the specified policy sets, domain ACL, and basic-auth + credentials. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + basic_auth_credential_ids: IDs of basic-auth credentials to attach + + default_mode: Default traffic mode: ALLOW or BLOCK + + name: Name of the deployment + + policy_set_ids: IDs of policy sets to attach + + description: Optional free-form description. + + domain_acl_id: ID of the domain ACL to attach (omit or null for none) + + on_error_action: Action for runtime Rego errors. Omit to use BLOCK. + + rego_raise_error: Whether OPA builtin failures are raised as runtime evaluation errors. Omit to + use the default true value. + + tags: Tags to attach. Keys are limited to 256 UTF-8 bytes and values to 1024 UTF-8 + bytes. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + return await self._post( + path_template("/accounts/{account_id}/cws/deployments", account_id=account_id), + body=await async_maybe_transform( + { + "basic_auth_credential_ids": basic_auth_credential_ids, + "default_mode": default_mode, + "name": name, + "policy_set_ids": policy_set_ids, + "description": description, + "domain_acl_id": domain_acl_id, + "on_error_action": on_error_action, + "rego_raise_error": rego_raise_error, + "tags": tags, + }, + deployment_create_params.DeploymentCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Deployment]._unwrapper, + ), + cast_to=cast(Type[Deployment], ResultWrapper[Deployment]), + ) + + async def update( + self, + deployment_id: str, + *, + account_id: str, + basic_auth_credential_ids: Optional[SequenceNotStr[str]], + default_mode: Literal["ALLOW", "BLOCK"], + name: str, + policy_set_ids: Optional[SequenceNotStr[str]], + description: str | Omit = omit, + domain_acl_id: Optional[str] | Omit = omit, + on_error_action: Literal["BLOCK", "SKIP"] | Omit = omit, + rego_raise_error: bool | Omit = omit, + tags: Dict[str, str] | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> Deployment: + """ + Replaces the deployment's mutable configuration and resource attachments. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + deployment_id: ID of the deployment to update + + basic_auth_credential_ids: Replacement set of basic-auth credential IDs + + default_mode: Default traffic mode: ALLOW or BLOCK + + name: Name of the deployment + + policy_set_ids: Replacement set of policy set IDs + + description: Optional free-form description. + + domain_acl_id: ID of the domain ACL to attach (omit or null to clear) + + on_error_action: Action for runtime Rego errors. Omit to reset to BLOCK. + + rego_raise_error: Whether OPA builtin failures are raised as runtime evaluation errors. Omit to + reset to true. + + tags: Replacement tag set. Omit or use {} to clear. Keys are limited to 256 UTF-8 + bytes and values to 1024 UTF-8 bytes. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not deployment_id: + raise ValueError(f"Expected a non-empty value for `deployment_id` but received {deployment_id!r}") + return await self._put( + path_template( + "/accounts/{account_id}/cws/deployments/{deployment_id}", + account_id=account_id, + deployment_id=deployment_id, + ), + body=await async_maybe_transform( + { + "basic_auth_credential_ids": basic_auth_credential_ids, + "default_mode": default_mode, + "name": name, + "policy_set_ids": policy_set_ids, + "description": description, + "domain_acl_id": domain_acl_id, + "on_error_action": on_error_action, + "rego_raise_error": rego_raise_error, + "tags": tags, + }, + deployment_update_params.DeploymentUpdateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Deployment]._unwrapper, + ), + cast_to=cast(Type[Deployment], ResultWrapper[Deployment]), + ) + + def list( + self, + *, + account_id: str, + cursor: str | Omit = omit, + direction: Literal["asc", "desc"] | Omit = omit, + name: str | Omit = omit, + order: Literal["name", "created_at", "updated_at"] | Omit = omit, + per_page: int | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> AsyncPaginator[Deployment, AsyncCursorPagination[Deployment]]: + """ + Returns a paginated list of deployments in the account. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + cursor: Pagination cursor from previous response + + direction: Sort direction (default: asc) + + name: Filter by deployment name (case-insensitive substring match) + + order: Field to order results by (default: created_at) + + per_page: Number of items per page (1-100, default 20) + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + return self._get_api_list( + path_template("/accounts/{account_id}/cws/deployments", account_id=account_id), + page=AsyncCursorPagination[Deployment], + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "cursor": cursor, + "direction": direction, + "name": name, + "order": order, + "per_page": per_page, + }, + deployment_list_params.DeploymentListParams, + ), + ), + model=Deployment, + ) + + async def delete( + self, + deployment_id: str, + *, + account_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> DeploymentDeleteResponse: + """Deletes the deployment and detaches its associated resources. + + The resources are + not deleted. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + deployment_id: ID of the deployment to delete + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not deployment_id: + raise ValueError(f"Expected a non-empty value for `deployment_id` but received {deployment_id!r}") + return await self._delete( + path_template( + "/accounts/{account_id}/cws/deployments/{deployment_id}", + account_id=account_id, + deployment_id=deployment_id, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[DeploymentDeleteResponse]._unwrapper, + ), + cast_to=cast(Type[DeploymentDeleteResponse], ResultWrapper[DeploymentDeleteResponse]), + ) + + async def get( + self, + deployment_id: str, + *, + account_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> Deployment: + """ + Returns the deployment with the specified ID. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + deployment_id: ID of the deployment to retrieve + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not deployment_id: + raise ValueError(f"Expected a non-empty value for `deployment_id` but received {deployment_id!r}") + return await self._get( + path_template( + "/accounts/{account_id}/cws/deployments/{deployment_id}", + account_id=account_id, + deployment_id=deployment_id, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Deployment]._unwrapper, + ), + cast_to=cast(Type[Deployment], ResultWrapper[Deployment]), + ) + + +class DeploymentsResourceWithRawResponse: + def __init__(self, deployments: DeploymentsResource) -> None: + self._deployments = deployments + + self.create = to_raw_response_wrapper( + deployments.create, + ) + self.update = to_raw_response_wrapper( + deployments.update, + ) + self.list = to_raw_response_wrapper( + deployments.list, + ) + self.delete = to_raw_response_wrapper( + deployments.delete, + ) + self.get = to_raw_response_wrapper( + deployments.get, + ) + + +class AsyncDeploymentsResourceWithRawResponse: + def __init__(self, deployments: AsyncDeploymentsResource) -> None: + self._deployments = deployments + + self.create = async_to_raw_response_wrapper( + deployments.create, + ) + self.update = async_to_raw_response_wrapper( + deployments.update, + ) + self.list = async_to_raw_response_wrapper( + deployments.list, + ) + self.delete = async_to_raw_response_wrapper( + deployments.delete, + ) + self.get = async_to_raw_response_wrapper( + deployments.get, + ) + + +class DeploymentsResourceWithStreamingResponse: + def __init__(self, deployments: DeploymentsResource) -> None: + self._deployments = deployments + + self.create = to_streamed_response_wrapper( + deployments.create, + ) + self.update = to_streamed_response_wrapper( + deployments.update, + ) + self.list = to_streamed_response_wrapper( + deployments.list, + ) + self.delete = to_streamed_response_wrapper( + deployments.delete, + ) + self.get = to_streamed_response_wrapper( + deployments.get, + ) + + +class AsyncDeploymentsResourceWithStreamingResponse: + def __init__(self, deployments: AsyncDeploymentsResource) -> None: + self._deployments = deployments + + self.create = async_to_streamed_response_wrapper( + deployments.create, + ) + self.update = async_to_streamed_response_wrapper( + deployments.update, + ) + self.list = async_to_streamed_response_wrapper( + deployments.list, + ) + self.delete = async_to_streamed_response_wrapper( + deployments.delete, + ) + self.get = async_to_streamed_response_wrapper( + deployments.get, + ) diff --git a/src/cloudflare/resources/zero_trust/cws/domain_acls.py b/src/cloudflare/resources/zero_trust/cws/domain_acls.py new file mode 100644 index 00000000000..ae6e31eb1d1 --- /dev/null +++ b/src/cloudflare/resources/zero_trust/cws/domain_acls.py @@ -0,0 +1,723 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Type, Iterable, Optional, cast +from typing_extensions import Literal + +import httpx + +from ...._types import Body, Omit, Query, Headers, NotGiven, omit, not_given +from ...._utils import path_template, maybe_transform, async_maybe_transform +from ...._compat import cached_property +from ...._resource import SyncAPIResource, AsyncAPIResource +from ...._response import ( + to_raw_response_wrapper, + to_streamed_response_wrapper, + async_to_raw_response_wrapper, + async_to_streamed_response_wrapper, +) +from ...._wrappers import ResultWrapper +from ....pagination import SyncCursorPagination, AsyncCursorPagination +from ...._base_client import AsyncPaginator, make_request_options +from ....types.zero_trust.cws import domain_acl_list_params, domain_acl_create_params, domain_acl_update_params +from ....types.zero_trust.cws.domain_acl import DomainACL +from ....types.zero_trust.cws.domain_acl_delete_response import DomainACLDeleteResponse + +__all__ = ["DomainACLsResource", "AsyncDomainACLsResource"] + + +class DomainACLsResource(SyncAPIResource): + @cached_property + def with_raw_response(self) -> DomainACLsResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers + """ + return DomainACLsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> DomainACLsResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response + """ + return DomainACLsResourceWithStreamingResponse(self) + + def create( + self, + *, + account_id: str, + default_action: Literal["ALLOW", "BLOCK"], + entries: Optional[Iterable[domain_acl_create_params.Entry]], + name: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> DomainACL: + """ + Creates a domain access control list with its default action and entries. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + default_action: Default action when no entry matches + + entries: Domain entries for this ACL. Each domain must appear at most once. + + name: Name of the domain ACL + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + return self._post( + path_template("/accounts/{account_id}/cws/domain-acls", account_id=account_id), + body=maybe_transform( + { + "default_action": default_action, + "entries": entries, + "name": name, + }, + domain_acl_create_params.DomainACLCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[DomainACL]._unwrapper, + ), + cast_to=cast(Type[DomainACL], ResultWrapper[DomainACL]), + ) + + def update( + self, + domain_acl_id: str, + *, + account_id: str, + default_action: Literal["ALLOW", "BLOCK"], + entries: Optional[Iterable[domain_acl_update_params.Entry]], + name: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> DomainACL: + """ + Replaces the domain access control list's name, default action, and entries. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + domain_acl_id: ID of the domain ACL to update + + default_action: Default action when no entry matches + + entries: Replacement set of domain entries. Each domain must appear at most once. + + name: Name of the domain ACL + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not domain_acl_id: + raise ValueError(f"Expected a non-empty value for `domain_acl_id` but received {domain_acl_id!r}") + return self._put( + path_template( + "/accounts/{account_id}/cws/domain-acls/{domain_acl_id}", + account_id=account_id, + domain_acl_id=domain_acl_id, + ), + body=maybe_transform( + { + "default_action": default_action, + "entries": entries, + "name": name, + }, + domain_acl_update_params.DomainACLUpdateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[DomainACL]._unwrapper, + ), + cast_to=cast(Type[DomainACL], ResultWrapper[DomainACL]), + ) + + def list( + self, + *, + account_id: str, + cursor: str | Omit = omit, + deployment_id: str | Omit = omit, + direction: Literal["asc", "desc"] | Omit = omit, + name: str | Omit = omit, + order: Literal["name", "created_at", "updated_at"] | Omit = omit, + per_page: int | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> SyncCursorPagination[DomainACL]: + """ + Returns a paginated list of domain access control lists in the account. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + cursor: Pagination cursor from previous response + + deployment_id: Filter to domain ACLs attached to this deployment + + direction: Sort direction (default: asc) + + name: Filter by domain ACL name (case-insensitive substring match) + + order: Field to order results by (default: created_at) + + per_page: Number of items per page (1-100, default 20) + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + return self._get_api_list( + path_template("/accounts/{account_id}/cws/domain-acls", account_id=account_id), + page=SyncCursorPagination[DomainACL], + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "cursor": cursor, + "deployment_id": deployment_id, + "direction": direction, + "name": name, + "order": order, + "per_page": per_page, + }, + domain_acl_list_params.DomainACLListParams, + ), + ), + model=DomainACL, + ) + + def delete( + self, + domain_acl_id: str, + *, + account_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> DomainACLDeleteResponse: + """ + Deletes the domain ACL if it is not attached to a deployment. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + domain_acl_id: ID of the domain ACL to delete + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not domain_acl_id: + raise ValueError(f"Expected a non-empty value for `domain_acl_id` but received {domain_acl_id!r}") + return self._delete( + path_template( + "/accounts/{account_id}/cws/domain-acls/{domain_acl_id}", + account_id=account_id, + domain_acl_id=domain_acl_id, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[DomainACLDeleteResponse]._unwrapper, + ), + cast_to=cast(Type[DomainACLDeleteResponse], ResultWrapper[DomainACLDeleteResponse]), + ) + + def get( + self, + domain_acl_id: str, + *, + account_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> DomainACL: + """ + Returns the domain access control list with the specified ID. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + domain_acl_id: ID of the domain ACL to retrieve + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not domain_acl_id: + raise ValueError(f"Expected a non-empty value for `domain_acl_id` but received {domain_acl_id!r}") + return self._get( + path_template( + "/accounts/{account_id}/cws/domain-acls/{domain_acl_id}", + account_id=account_id, + domain_acl_id=domain_acl_id, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[DomainACL]._unwrapper, + ), + cast_to=cast(Type[DomainACL], ResultWrapper[DomainACL]), + ) + + +class AsyncDomainACLsResource(AsyncAPIResource): + @cached_property + def with_raw_response(self) -> AsyncDomainACLsResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers + """ + return AsyncDomainACLsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncDomainACLsResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response + """ + return AsyncDomainACLsResourceWithStreamingResponse(self) + + async def create( + self, + *, + account_id: str, + default_action: Literal["ALLOW", "BLOCK"], + entries: Optional[Iterable[domain_acl_create_params.Entry]], + name: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> DomainACL: + """ + Creates a domain access control list with its default action and entries. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + default_action: Default action when no entry matches + + entries: Domain entries for this ACL. Each domain must appear at most once. + + name: Name of the domain ACL + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + return await self._post( + path_template("/accounts/{account_id}/cws/domain-acls", account_id=account_id), + body=await async_maybe_transform( + { + "default_action": default_action, + "entries": entries, + "name": name, + }, + domain_acl_create_params.DomainACLCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[DomainACL]._unwrapper, + ), + cast_to=cast(Type[DomainACL], ResultWrapper[DomainACL]), + ) + + async def update( + self, + domain_acl_id: str, + *, + account_id: str, + default_action: Literal["ALLOW", "BLOCK"], + entries: Optional[Iterable[domain_acl_update_params.Entry]], + name: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> DomainACL: + """ + Replaces the domain access control list's name, default action, and entries. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + domain_acl_id: ID of the domain ACL to update + + default_action: Default action when no entry matches + + entries: Replacement set of domain entries. Each domain must appear at most once. + + name: Name of the domain ACL + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not domain_acl_id: + raise ValueError(f"Expected a non-empty value for `domain_acl_id` but received {domain_acl_id!r}") + return await self._put( + path_template( + "/accounts/{account_id}/cws/domain-acls/{domain_acl_id}", + account_id=account_id, + domain_acl_id=domain_acl_id, + ), + body=await async_maybe_transform( + { + "default_action": default_action, + "entries": entries, + "name": name, + }, + domain_acl_update_params.DomainACLUpdateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[DomainACL]._unwrapper, + ), + cast_to=cast(Type[DomainACL], ResultWrapper[DomainACL]), + ) + + def list( + self, + *, + account_id: str, + cursor: str | Omit = omit, + deployment_id: str | Omit = omit, + direction: Literal["asc", "desc"] | Omit = omit, + name: str | Omit = omit, + order: Literal["name", "created_at", "updated_at"] | Omit = omit, + per_page: int | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> AsyncPaginator[DomainACL, AsyncCursorPagination[DomainACL]]: + """ + Returns a paginated list of domain access control lists in the account. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + cursor: Pagination cursor from previous response + + deployment_id: Filter to domain ACLs attached to this deployment + + direction: Sort direction (default: asc) + + name: Filter by domain ACL name (case-insensitive substring match) + + order: Field to order results by (default: created_at) + + per_page: Number of items per page (1-100, default 20) + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + return self._get_api_list( + path_template("/accounts/{account_id}/cws/domain-acls", account_id=account_id), + page=AsyncCursorPagination[DomainACL], + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "cursor": cursor, + "deployment_id": deployment_id, + "direction": direction, + "name": name, + "order": order, + "per_page": per_page, + }, + domain_acl_list_params.DomainACLListParams, + ), + ), + model=DomainACL, + ) + + async def delete( + self, + domain_acl_id: str, + *, + account_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> DomainACLDeleteResponse: + """ + Deletes the domain ACL if it is not attached to a deployment. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + domain_acl_id: ID of the domain ACL to delete + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not domain_acl_id: + raise ValueError(f"Expected a non-empty value for `domain_acl_id` but received {domain_acl_id!r}") + return await self._delete( + path_template( + "/accounts/{account_id}/cws/domain-acls/{domain_acl_id}", + account_id=account_id, + domain_acl_id=domain_acl_id, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[DomainACLDeleteResponse]._unwrapper, + ), + cast_to=cast(Type[DomainACLDeleteResponse], ResultWrapper[DomainACLDeleteResponse]), + ) + + async def get( + self, + domain_acl_id: str, + *, + account_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> DomainACL: + """ + Returns the domain access control list with the specified ID. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + domain_acl_id: ID of the domain ACL to retrieve + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not domain_acl_id: + raise ValueError(f"Expected a non-empty value for `domain_acl_id` but received {domain_acl_id!r}") + return await self._get( + path_template( + "/accounts/{account_id}/cws/domain-acls/{domain_acl_id}", + account_id=account_id, + domain_acl_id=domain_acl_id, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[DomainACL]._unwrapper, + ), + cast_to=cast(Type[DomainACL], ResultWrapper[DomainACL]), + ) + + +class DomainACLsResourceWithRawResponse: + def __init__(self, domain_acls: DomainACLsResource) -> None: + self._domain_acls = domain_acls + + self.create = to_raw_response_wrapper( + domain_acls.create, + ) + self.update = to_raw_response_wrapper( + domain_acls.update, + ) + self.list = to_raw_response_wrapper( + domain_acls.list, + ) + self.delete = to_raw_response_wrapper( + domain_acls.delete, + ) + self.get = to_raw_response_wrapper( + domain_acls.get, + ) + + +class AsyncDomainACLsResourceWithRawResponse: + def __init__(self, domain_acls: AsyncDomainACLsResource) -> None: + self._domain_acls = domain_acls + + self.create = async_to_raw_response_wrapper( + domain_acls.create, + ) + self.update = async_to_raw_response_wrapper( + domain_acls.update, + ) + self.list = async_to_raw_response_wrapper( + domain_acls.list, + ) + self.delete = async_to_raw_response_wrapper( + domain_acls.delete, + ) + self.get = async_to_raw_response_wrapper( + domain_acls.get, + ) + + +class DomainACLsResourceWithStreamingResponse: + def __init__(self, domain_acls: DomainACLsResource) -> None: + self._domain_acls = domain_acls + + self.create = to_streamed_response_wrapper( + domain_acls.create, + ) + self.update = to_streamed_response_wrapper( + domain_acls.update, + ) + self.list = to_streamed_response_wrapper( + domain_acls.list, + ) + self.delete = to_streamed_response_wrapper( + domain_acls.delete, + ) + self.get = to_streamed_response_wrapper( + domain_acls.get, + ) + + +class AsyncDomainACLsResourceWithStreamingResponse: + def __init__(self, domain_acls: AsyncDomainACLsResource) -> None: + self._domain_acls = domain_acls + + self.create = async_to_streamed_response_wrapper( + domain_acls.create, + ) + self.update = async_to_streamed_response_wrapper( + domain_acls.update, + ) + self.list = async_to_streamed_response_wrapper( + domain_acls.list, + ) + self.delete = async_to_streamed_response_wrapper( + domain_acls.delete, + ) + self.get = async_to_streamed_response_wrapper( + domain_acls.get, + ) diff --git a/src/cloudflare/resources/zero_trust/cws/policies.py b/src/cloudflare/resources/zero_trust/cws/policies.py new file mode 100644 index 00000000000..d4dda353f96 --- /dev/null +++ b/src/cloudflare/resources/zero_trust/cws/policies.py @@ -0,0 +1,791 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Dict, Type, cast +from typing_extensions import Literal + +import httpx + +from ...._types import Body, Omit, Query, Headers, NotGiven, omit, not_given +from ...._utils import path_template, maybe_transform, async_maybe_transform +from ...._compat import cached_property +from ...._resource import SyncAPIResource, AsyncAPIResource +from ...._response import ( + to_raw_response_wrapper, + to_streamed_response_wrapper, + async_to_raw_response_wrapper, + async_to_streamed_response_wrapper, +) +from ...._wrappers import ResultWrapper +from ....pagination import SyncCursorPagination, AsyncCursorPagination +from ...._base_client import AsyncPaginator, make_request_options +from ....types.zero_trust.cws import policy_list_params, policy_create_params, policy_update_params +from ....types.zero_trust.cws.policy import Policy +from ....types.zero_trust.cws.policy_delete_response import PolicyDeleteResponse + +__all__ = ["PoliciesResource", "AsyncPoliciesResource"] + + +class PoliciesResource(SyncAPIResource): + @cached_property + def with_raw_response(self) -> PoliciesResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers + """ + return PoliciesResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> PoliciesResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response + """ + return PoliciesResourceWithStreamingResponse(self) + + def create( + self, + *, + account_id: str, + entrypoint: str, + filter: str, + name: str, + rego_source: str, + description: str | Omit = omit, + tags: Dict[str, str] | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> Policy: + """ + Creates a policy from inline Rego source, an entrypoint, and a filter + expression. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + entrypoint: Non-function rule declared in rego_source. Evaluation uses + data... + + filter: Filter expression that determines whether this policy applies. Maximum 4096 + UTF-8 bytes. + + name: Name of the policy + + rego_source: Inline Rego source with a package beginning with "policy." Maximum 16384 UTF-8 + bytes. + + description: Optional free-form description. + + tags: Tags to attach. Keys are limited to 256 UTF-8 bytes and values to 1024 UTF-8 + bytes. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + return self._post( + path_template("/accounts/{account_id}/cws/policies", account_id=account_id), + body=maybe_transform( + { + "entrypoint": entrypoint, + "filter": filter, + "name": name, + "rego_source": rego_source, + "description": description, + "tags": tags, + }, + policy_create_params.PolicyCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Policy]._unwrapper, + ), + cast_to=cast(Type[Policy], ResultWrapper[Policy]), + ) + + def update( + self, + policy_id: str, + *, + account_id: str, + entrypoint: str, + filter: str, + name: str, + rego_source: str, + description: str | Omit = omit, + tags: Dict[str, str] | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> Policy: + """Replaces the policy's configuration. + + Omit tags or use {} to clear them. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + policy_id: ID of the policy to update + + entrypoint: Non-function rule declared in rego_source. Evaluation uses + data... + + filter: Filter expression that determines whether this policy applies. Maximum 4096 + UTF-8 bytes. + + name: Name of the policy + + rego_source: Inline Rego source with a package beginning with "policy." Maximum 16384 UTF-8 + bytes. + + description: Optional free-form description. + + tags: Replacement tag set. Omit or use {} to clear. Keys are limited to 256 UTF-8 + bytes and values to 1024 UTF-8 bytes. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not policy_id: + raise ValueError(f"Expected a non-empty value for `policy_id` but received {policy_id!r}") + return self._put( + path_template( + "/accounts/{account_id}/cws/policies/{policy_id}", account_id=account_id, policy_id=policy_id + ), + body=maybe_transform( + { + "entrypoint": entrypoint, + "filter": filter, + "name": name, + "rego_source": rego_source, + "description": description, + "tags": tags, + }, + policy_update_params.PolicyUpdateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Policy]._unwrapper, + ), + cast_to=cast(Type[Policy], ResultWrapper[Policy]), + ) + + def list( + self, + *, + account_id: str, + cursor: str | Omit = omit, + direction: Literal["asc", "desc"] | Omit = omit, + name: str | Omit = omit, + order: Literal["name", "created_at", "updated_at"] | Omit = omit, + package_path: str | Omit = omit, + per_page: int | Omit = omit, + policy_set_id: str | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> SyncCursorPagination[Policy]: + """ + Returns a paginated list of policies in the account. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + cursor: Pagination cursor from previous response + + direction: Sort direction (default: asc) + + name: Filter by policy name (case-insensitive substring match) + + order: Field to order results by (default: created_at) + + package_path: Filter by package path (case-sensitive literal substring match) + + per_page: Number of items per page (1-100, default 20) + + policy_set_id: Filter to policies attached to (members of) this policy set + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + return self._get_api_list( + path_template("/accounts/{account_id}/cws/policies", account_id=account_id), + page=SyncCursorPagination[Policy], + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "cursor": cursor, + "direction": direction, + "name": name, + "order": order, + "package_path": package_path, + "per_page": per_page, + "policy_set_id": policy_set_id, + }, + policy_list_params.PolicyListParams, + ), + ), + model=Policy, + ) + + def delete( + self, + policy_id: str, + *, + account_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> PolicyDeleteResponse: + """Deletes the policy and cascades its policy-set membership rows. + + The policy sets + remain. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + policy_id: ID of the policy to delete + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not policy_id: + raise ValueError(f"Expected a non-empty value for `policy_id` but received {policy_id!r}") + return self._delete( + path_template( + "/accounts/{account_id}/cws/policies/{policy_id}", account_id=account_id, policy_id=policy_id + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[PolicyDeleteResponse]._unwrapper, + ), + cast_to=cast(Type[PolicyDeleteResponse], ResultWrapper[PolicyDeleteResponse]), + ) + + def get( + self, + policy_id: str, + *, + account_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> Policy: + """ + Returns the policy with the specified ID. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + policy_id: ID of the policy to retrieve + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not policy_id: + raise ValueError(f"Expected a non-empty value for `policy_id` but received {policy_id!r}") + return self._get( + path_template( + "/accounts/{account_id}/cws/policies/{policy_id}", account_id=account_id, policy_id=policy_id + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Policy]._unwrapper, + ), + cast_to=cast(Type[Policy], ResultWrapper[Policy]), + ) + + +class AsyncPoliciesResource(AsyncAPIResource): + @cached_property + def with_raw_response(self) -> AsyncPoliciesResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers + """ + return AsyncPoliciesResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncPoliciesResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response + """ + return AsyncPoliciesResourceWithStreamingResponse(self) + + async def create( + self, + *, + account_id: str, + entrypoint: str, + filter: str, + name: str, + rego_source: str, + description: str | Omit = omit, + tags: Dict[str, str] | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> Policy: + """ + Creates a policy from inline Rego source, an entrypoint, and a filter + expression. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + entrypoint: Non-function rule declared in rego_source. Evaluation uses + data... + + filter: Filter expression that determines whether this policy applies. Maximum 4096 + UTF-8 bytes. + + name: Name of the policy + + rego_source: Inline Rego source with a package beginning with "policy." Maximum 16384 UTF-8 + bytes. + + description: Optional free-form description. + + tags: Tags to attach. Keys are limited to 256 UTF-8 bytes and values to 1024 UTF-8 + bytes. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + return await self._post( + path_template("/accounts/{account_id}/cws/policies", account_id=account_id), + body=await async_maybe_transform( + { + "entrypoint": entrypoint, + "filter": filter, + "name": name, + "rego_source": rego_source, + "description": description, + "tags": tags, + }, + policy_create_params.PolicyCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Policy]._unwrapper, + ), + cast_to=cast(Type[Policy], ResultWrapper[Policy]), + ) + + async def update( + self, + policy_id: str, + *, + account_id: str, + entrypoint: str, + filter: str, + name: str, + rego_source: str, + description: str | Omit = omit, + tags: Dict[str, str] | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> Policy: + """Replaces the policy's configuration. + + Omit tags or use {} to clear them. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + policy_id: ID of the policy to update + + entrypoint: Non-function rule declared in rego_source. Evaluation uses + data... + + filter: Filter expression that determines whether this policy applies. Maximum 4096 + UTF-8 bytes. + + name: Name of the policy + + rego_source: Inline Rego source with a package beginning with "policy." Maximum 16384 UTF-8 + bytes. + + description: Optional free-form description. + + tags: Replacement tag set. Omit or use {} to clear. Keys are limited to 256 UTF-8 + bytes and values to 1024 UTF-8 bytes. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not policy_id: + raise ValueError(f"Expected a non-empty value for `policy_id` but received {policy_id!r}") + return await self._put( + path_template( + "/accounts/{account_id}/cws/policies/{policy_id}", account_id=account_id, policy_id=policy_id + ), + body=await async_maybe_transform( + { + "entrypoint": entrypoint, + "filter": filter, + "name": name, + "rego_source": rego_source, + "description": description, + "tags": tags, + }, + policy_update_params.PolicyUpdateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Policy]._unwrapper, + ), + cast_to=cast(Type[Policy], ResultWrapper[Policy]), + ) + + def list( + self, + *, + account_id: str, + cursor: str | Omit = omit, + direction: Literal["asc", "desc"] | Omit = omit, + name: str | Omit = omit, + order: Literal["name", "created_at", "updated_at"] | Omit = omit, + package_path: str | Omit = omit, + per_page: int | Omit = omit, + policy_set_id: str | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> AsyncPaginator[Policy, AsyncCursorPagination[Policy]]: + """ + Returns a paginated list of policies in the account. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + cursor: Pagination cursor from previous response + + direction: Sort direction (default: asc) + + name: Filter by policy name (case-insensitive substring match) + + order: Field to order results by (default: created_at) + + package_path: Filter by package path (case-sensitive literal substring match) + + per_page: Number of items per page (1-100, default 20) + + policy_set_id: Filter to policies attached to (members of) this policy set + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + return self._get_api_list( + path_template("/accounts/{account_id}/cws/policies", account_id=account_id), + page=AsyncCursorPagination[Policy], + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "cursor": cursor, + "direction": direction, + "name": name, + "order": order, + "package_path": package_path, + "per_page": per_page, + "policy_set_id": policy_set_id, + }, + policy_list_params.PolicyListParams, + ), + ), + model=Policy, + ) + + async def delete( + self, + policy_id: str, + *, + account_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> PolicyDeleteResponse: + """Deletes the policy and cascades its policy-set membership rows. + + The policy sets + remain. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + policy_id: ID of the policy to delete + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not policy_id: + raise ValueError(f"Expected a non-empty value for `policy_id` but received {policy_id!r}") + return await self._delete( + path_template( + "/accounts/{account_id}/cws/policies/{policy_id}", account_id=account_id, policy_id=policy_id + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[PolicyDeleteResponse]._unwrapper, + ), + cast_to=cast(Type[PolicyDeleteResponse], ResultWrapper[PolicyDeleteResponse]), + ) + + async def get( + self, + policy_id: str, + *, + account_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> Policy: + """ + Returns the policy with the specified ID. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + policy_id: ID of the policy to retrieve + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not policy_id: + raise ValueError(f"Expected a non-empty value for `policy_id` but received {policy_id!r}") + return await self._get( + path_template( + "/accounts/{account_id}/cws/policies/{policy_id}", account_id=account_id, policy_id=policy_id + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Policy]._unwrapper, + ), + cast_to=cast(Type[Policy], ResultWrapper[Policy]), + ) + + +class PoliciesResourceWithRawResponse: + def __init__(self, policies: PoliciesResource) -> None: + self._policies = policies + + self.create = to_raw_response_wrapper( + policies.create, + ) + self.update = to_raw_response_wrapper( + policies.update, + ) + self.list = to_raw_response_wrapper( + policies.list, + ) + self.delete = to_raw_response_wrapper( + policies.delete, + ) + self.get = to_raw_response_wrapper( + policies.get, + ) + + +class AsyncPoliciesResourceWithRawResponse: + def __init__(self, policies: AsyncPoliciesResource) -> None: + self._policies = policies + + self.create = async_to_raw_response_wrapper( + policies.create, + ) + self.update = async_to_raw_response_wrapper( + policies.update, + ) + self.list = async_to_raw_response_wrapper( + policies.list, + ) + self.delete = async_to_raw_response_wrapper( + policies.delete, + ) + self.get = async_to_raw_response_wrapper( + policies.get, + ) + + +class PoliciesResourceWithStreamingResponse: + def __init__(self, policies: PoliciesResource) -> None: + self._policies = policies + + self.create = to_streamed_response_wrapper( + policies.create, + ) + self.update = to_streamed_response_wrapper( + policies.update, + ) + self.list = to_streamed_response_wrapper( + policies.list, + ) + self.delete = to_streamed_response_wrapper( + policies.delete, + ) + self.get = to_streamed_response_wrapper( + policies.get, + ) + + +class AsyncPoliciesResourceWithStreamingResponse: + def __init__(self, policies: AsyncPoliciesResource) -> None: + self._policies = policies + + self.create = async_to_streamed_response_wrapper( + policies.create, + ) + self.update = async_to_streamed_response_wrapper( + policies.update, + ) + self.list = async_to_streamed_response_wrapper( + policies.list, + ) + self.delete = async_to_streamed_response_wrapper( + policies.delete, + ) + self.get = async_to_streamed_response_wrapper( + policies.get, + ) diff --git a/src/cloudflare/resources/zero_trust/cws/policy_sets.py b/src/cloudflare/resources/zero_trust/cws/policy_sets.py new file mode 100644 index 00000000000..8668d4ac495 --- /dev/null +++ b/src/cloudflare/resources/zero_trust/cws/policy_sets.py @@ -0,0 +1,785 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Dict, Type, Iterable, Optional, cast +from typing_extensions import Literal + +import httpx + +from ...._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given +from ...._utils import path_template, maybe_transform, async_maybe_transform +from ...._compat import cached_property +from ...._resource import SyncAPIResource, AsyncAPIResource +from ...._response import ( + to_raw_response_wrapper, + to_streamed_response_wrapper, + async_to_raw_response_wrapper, + async_to_streamed_response_wrapper, +) +from ...._wrappers import ResultWrapper +from ....pagination import SyncCursorPagination, AsyncCursorPagination +from ...._base_client import AsyncPaginator, make_request_options +from ....types.zero_trust.cws import policy_set_list_params, policy_set_create_params, policy_set_update_params +from ....types.zero_trust.cws.policy_set import PolicySet +from ....types.zero_trust.cws.policy_set_delete_response import PolicySetDeleteResponse + +__all__ = ["PolicySetsResource", "AsyncPolicySetsResource"] + + +class PolicySetsResource(SyncAPIResource): + @cached_property + def with_raw_response(self) -> PolicySetsResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers + """ + return PolicySetsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> PolicySetsResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response + """ + return PolicySetsResourceWithStreamingResponse(self) + + def create( + self, + *, + account_id: str, + name: str, + policies: Optional[Iterable[policy_set_create_params.Policy]], + description: str | Omit = omit, + exclude_workload_ids: Optional[SequenceNotStr[str]] | Omit = omit, + include_workload_ids: Optional[SequenceNotStr[str]] | Omit = omit, + tags: Dict[str, str] | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> PolicySet: + """ + Creates a policy set containing the specified policies and workload targets. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + name: Name of the policy set + + policies: Policies to include with per-membership enforcement mode + + description: Optional free-form description. + + exclude_workload_ids: Workload IDs that exclude matching requests. Exclusions take precedence. + + include_workload_ids: Workload IDs that include matching requests. Empty or omitted includes all + requests before exclusions. + + tags: Tags to attach. Keys are limited to 256 UTF-8 bytes and values to 1024 UTF-8 + bytes. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + return self._post( + path_template("/accounts/{account_id}/cws/policy-sets", account_id=account_id), + body=maybe_transform( + { + "name": name, + "policies": policies, + "description": description, + "exclude_workload_ids": exclude_workload_ids, + "include_workload_ids": include_workload_ids, + "tags": tags, + }, + policy_set_create_params.PolicySetCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[PolicySet]._unwrapper, + ), + cast_to=cast(Type[PolicySet], ResultWrapper[PolicySet]), + ) + + def update( + self, + policy_set_id: str, + *, + account_id: str, + name: str, + policies: Optional[Iterable[policy_set_update_params.Policy]], + description: str | Omit = omit, + exclude_workload_ids: Optional[SequenceNotStr[str]] | Omit = omit, + include_workload_ids: Optional[SequenceNotStr[str]] | Omit = omit, + tags: Dict[str, str] | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> PolicySet: + """Replaces the policy set's configuration. + + Omit tags or use {} to clear them. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + policy_set_id: ID of the policy set to update + + name: Name of the policy set + + policies: Replacement set of policies with per-membership enforcement mode + + description: Optional free-form description. + + exclude_workload_ids: Replacement set of excluded workload IDs. Exclusions take precedence. + + include_workload_ids: Replacement set of included workload IDs. Empty or omitted includes all requests + before exclusions. + + tags: Replacement tag set. Omit or use {} to clear. Keys are limited to 256 UTF-8 + bytes and values to 1024 UTF-8 bytes. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not policy_set_id: + raise ValueError(f"Expected a non-empty value for `policy_set_id` but received {policy_set_id!r}") + return self._put( + path_template( + "/accounts/{account_id}/cws/policy-sets/{policy_set_id}", + account_id=account_id, + policy_set_id=policy_set_id, + ), + body=maybe_transform( + { + "name": name, + "policies": policies, + "description": description, + "exclude_workload_ids": exclude_workload_ids, + "include_workload_ids": include_workload_ids, + "tags": tags, + }, + policy_set_update_params.PolicySetUpdateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[PolicySet]._unwrapper, + ), + cast_to=cast(Type[PolicySet], ResultWrapper[PolicySet]), + ) + + def list( + self, + *, + account_id: str, + cursor: str | Omit = omit, + deployment_id: str | Omit = omit, + direction: Literal["asc", "desc"] | Omit = omit, + name: str | Omit = omit, + order: Literal["name", "created_at", "updated_at"] | Omit = omit, + per_page: int | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> SyncCursorPagination[PolicySet]: + """ + Returns a paginated list of policy sets in the account. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + cursor: Pagination cursor from previous response + + deployment_id: Filter to policy sets attached to this deployment + + direction: Sort direction (default: asc) + + name: Filter by policy set name (case-insensitive substring match) + + order: Field to order results by (default: created_at) + + per_page: Number of items per page (1-100, default 20) + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + return self._get_api_list( + path_template("/accounts/{account_id}/cws/policy-sets", account_id=account_id), + page=SyncCursorPagination[PolicySet], + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "cursor": cursor, + "deployment_id": deployment_id, + "direction": direction, + "name": name, + "order": order, + "per_page": per_page, + }, + policy_set_list_params.PolicySetListParams, + ), + ), + model=PolicySet, + ) + + def delete( + self, + policy_set_id: str, + *, + account_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> PolicySetDeleteResponse: + """ + Deletes the policy set and cascades its deployment attachment and policy and + workload membership rows. The referenced deployments, policies, and workloads + remain. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + policy_set_id: ID of the policy set to delete + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not policy_set_id: + raise ValueError(f"Expected a non-empty value for `policy_set_id` but received {policy_set_id!r}") + return self._delete( + path_template( + "/accounts/{account_id}/cws/policy-sets/{policy_set_id}", + account_id=account_id, + policy_set_id=policy_set_id, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[PolicySetDeleteResponse]._unwrapper, + ), + cast_to=cast(Type[PolicySetDeleteResponse], ResultWrapper[PolicySetDeleteResponse]), + ) + + def get( + self, + policy_set_id: str, + *, + account_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> PolicySet: + """ + Returns the policy set with the specified ID. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + policy_set_id: ID of the policy set to retrieve + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not policy_set_id: + raise ValueError(f"Expected a non-empty value for `policy_set_id` but received {policy_set_id!r}") + return self._get( + path_template( + "/accounts/{account_id}/cws/policy-sets/{policy_set_id}", + account_id=account_id, + policy_set_id=policy_set_id, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[PolicySet]._unwrapper, + ), + cast_to=cast(Type[PolicySet], ResultWrapper[PolicySet]), + ) + + +class AsyncPolicySetsResource(AsyncAPIResource): + @cached_property + def with_raw_response(self) -> AsyncPolicySetsResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers + """ + return AsyncPolicySetsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncPolicySetsResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response + """ + return AsyncPolicySetsResourceWithStreamingResponse(self) + + async def create( + self, + *, + account_id: str, + name: str, + policies: Optional[Iterable[policy_set_create_params.Policy]], + description: str | Omit = omit, + exclude_workload_ids: Optional[SequenceNotStr[str]] | Omit = omit, + include_workload_ids: Optional[SequenceNotStr[str]] | Omit = omit, + tags: Dict[str, str] | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> PolicySet: + """ + Creates a policy set containing the specified policies and workload targets. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + name: Name of the policy set + + policies: Policies to include with per-membership enforcement mode + + description: Optional free-form description. + + exclude_workload_ids: Workload IDs that exclude matching requests. Exclusions take precedence. + + include_workload_ids: Workload IDs that include matching requests. Empty or omitted includes all + requests before exclusions. + + tags: Tags to attach. Keys are limited to 256 UTF-8 bytes and values to 1024 UTF-8 + bytes. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + return await self._post( + path_template("/accounts/{account_id}/cws/policy-sets", account_id=account_id), + body=await async_maybe_transform( + { + "name": name, + "policies": policies, + "description": description, + "exclude_workload_ids": exclude_workload_ids, + "include_workload_ids": include_workload_ids, + "tags": tags, + }, + policy_set_create_params.PolicySetCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[PolicySet]._unwrapper, + ), + cast_to=cast(Type[PolicySet], ResultWrapper[PolicySet]), + ) + + async def update( + self, + policy_set_id: str, + *, + account_id: str, + name: str, + policies: Optional[Iterable[policy_set_update_params.Policy]], + description: str | Omit = omit, + exclude_workload_ids: Optional[SequenceNotStr[str]] | Omit = omit, + include_workload_ids: Optional[SequenceNotStr[str]] | Omit = omit, + tags: Dict[str, str] | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> PolicySet: + """Replaces the policy set's configuration. + + Omit tags or use {} to clear them. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + policy_set_id: ID of the policy set to update + + name: Name of the policy set + + policies: Replacement set of policies with per-membership enforcement mode + + description: Optional free-form description. + + exclude_workload_ids: Replacement set of excluded workload IDs. Exclusions take precedence. + + include_workload_ids: Replacement set of included workload IDs. Empty or omitted includes all requests + before exclusions. + + tags: Replacement tag set. Omit or use {} to clear. Keys are limited to 256 UTF-8 + bytes and values to 1024 UTF-8 bytes. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not policy_set_id: + raise ValueError(f"Expected a non-empty value for `policy_set_id` but received {policy_set_id!r}") + return await self._put( + path_template( + "/accounts/{account_id}/cws/policy-sets/{policy_set_id}", + account_id=account_id, + policy_set_id=policy_set_id, + ), + body=await async_maybe_transform( + { + "name": name, + "policies": policies, + "description": description, + "exclude_workload_ids": exclude_workload_ids, + "include_workload_ids": include_workload_ids, + "tags": tags, + }, + policy_set_update_params.PolicySetUpdateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[PolicySet]._unwrapper, + ), + cast_to=cast(Type[PolicySet], ResultWrapper[PolicySet]), + ) + + def list( + self, + *, + account_id: str, + cursor: str | Omit = omit, + deployment_id: str | Omit = omit, + direction: Literal["asc", "desc"] | Omit = omit, + name: str | Omit = omit, + order: Literal["name", "created_at", "updated_at"] | Omit = omit, + per_page: int | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> AsyncPaginator[PolicySet, AsyncCursorPagination[PolicySet]]: + """ + Returns a paginated list of policy sets in the account. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + cursor: Pagination cursor from previous response + + deployment_id: Filter to policy sets attached to this deployment + + direction: Sort direction (default: asc) + + name: Filter by policy set name (case-insensitive substring match) + + order: Field to order results by (default: created_at) + + per_page: Number of items per page (1-100, default 20) + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + return self._get_api_list( + path_template("/accounts/{account_id}/cws/policy-sets", account_id=account_id), + page=AsyncCursorPagination[PolicySet], + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "cursor": cursor, + "deployment_id": deployment_id, + "direction": direction, + "name": name, + "order": order, + "per_page": per_page, + }, + policy_set_list_params.PolicySetListParams, + ), + ), + model=PolicySet, + ) + + async def delete( + self, + policy_set_id: str, + *, + account_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> PolicySetDeleteResponse: + """ + Deletes the policy set and cascades its deployment attachment and policy and + workload membership rows. The referenced deployments, policies, and workloads + remain. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + policy_set_id: ID of the policy set to delete + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not policy_set_id: + raise ValueError(f"Expected a non-empty value for `policy_set_id` but received {policy_set_id!r}") + return await self._delete( + path_template( + "/accounts/{account_id}/cws/policy-sets/{policy_set_id}", + account_id=account_id, + policy_set_id=policy_set_id, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[PolicySetDeleteResponse]._unwrapper, + ), + cast_to=cast(Type[PolicySetDeleteResponse], ResultWrapper[PolicySetDeleteResponse]), + ) + + async def get( + self, + policy_set_id: str, + *, + account_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> PolicySet: + """ + Returns the policy set with the specified ID. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + policy_set_id: ID of the policy set to retrieve + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not policy_set_id: + raise ValueError(f"Expected a non-empty value for `policy_set_id` but received {policy_set_id!r}") + return await self._get( + path_template( + "/accounts/{account_id}/cws/policy-sets/{policy_set_id}", + account_id=account_id, + policy_set_id=policy_set_id, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[PolicySet]._unwrapper, + ), + cast_to=cast(Type[PolicySet], ResultWrapper[PolicySet]), + ) + + +class PolicySetsResourceWithRawResponse: + def __init__(self, policy_sets: PolicySetsResource) -> None: + self._policy_sets = policy_sets + + self.create = to_raw_response_wrapper( + policy_sets.create, + ) + self.update = to_raw_response_wrapper( + policy_sets.update, + ) + self.list = to_raw_response_wrapper( + policy_sets.list, + ) + self.delete = to_raw_response_wrapper( + policy_sets.delete, + ) + self.get = to_raw_response_wrapper( + policy_sets.get, + ) + + +class AsyncPolicySetsResourceWithRawResponse: + def __init__(self, policy_sets: AsyncPolicySetsResource) -> None: + self._policy_sets = policy_sets + + self.create = async_to_raw_response_wrapper( + policy_sets.create, + ) + self.update = async_to_raw_response_wrapper( + policy_sets.update, + ) + self.list = async_to_raw_response_wrapper( + policy_sets.list, + ) + self.delete = async_to_raw_response_wrapper( + policy_sets.delete, + ) + self.get = async_to_raw_response_wrapper( + policy_sets.get, + ) + + +class PolicySetsResourceWithStreamingResponse: + def __init__(self, policy_sets: PolicySetsResource) -> None: + self._policy_sets = policy_sets + + self.create = to_streamed_response_wrapper( + policy_sets.create, + ) + self.update = to_streamed_response_wrapper( + policy_sets.update, + ) + self.list = to_streamed_response_wrapper( + policy_sets.list, + ) + self.delete = to_streamed_response_wrapper( + policy_sets.delete, + ) + self.get = to_streamed_response_wrapper( + policy_sets.get, + ) + + +class AsyncPolicySetsResourceWithStreamingResponse: + def __init__(self, policy_sets: AsyncPolicySetsResource) -> None: + self._policy_sets = policy_sets + + self.create = async_to_streamed_response_wrapper( + policy_sets.create, + ) + self.update = async_to_streamed_response_wrapper( + policy_sets.update, + ) + self.list = async_to_streamed_response_wrapper( + policy_sets.list, + ) + self.delete = async_to_streamed_response_wrapper( + policy_sets.delete, + ) + self.get = async_to_streamed_response_wrapper( + policy_sets.get, + ) diff --git a/src/cloudflare/resources/zero_trust/cws/rego_metadata.py b/src/cloudflare/resources/zero_trust/cws/rego_metadata.py new file mode 100644 index 00000000000..758fbf811d7 --- /dev/null +++ b/src/cloudflare/resources/zero_trust/cws/rego_metadata.py @@ -0,0 +1,719 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Type, cast +from typing_extensions import Literal + +import httpx + +from ...._types import Body, Omit, Query, Headers, NotGiven, omit, not_given +from ...._utils import path_template, maybe_transform, async_maybe_transform +from ...._compat import cached_property +from ...._resource import SyncAPIResource, AsyncAPIResource +from ...._response import ( + to_raw_response_wrapper, + to_streamed_response_wrapper, + async_to_raw_response_wrapper, + async_to_streamed_response_wrapper, +) +from ...._wrappers import ResultWrapper +from ....pagination import SyncCursorPagination, AsyncCursorPagination +from ...._base_client import AsyncPaginator, make_request_options +from ....types.zero_trust.cws import rego_metadata_list_params, rego_metadata_create_params, rego_metadata_update_params +from ....types.zero_trust.cws.rego_metadata import RegoMetadata +from ....types.zero_trust.cws.rego_metadata_delete_response import RegoMetadataDeleteResponse + +__all__ = ["RegoMetadataResource", "AsyncRegoMetadataResource"] + + +class RegoMetadataResource(SyncAPIResource): + @cached_property + def with_raw_response(self) -> RegoMetadataResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers + """ + return RegoMetadataResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> RegoMetadataResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response + """ + return RegoMetadataResourceWithStreamingResponse(self) + + def create( + self, + *, + account_id: str, + data: object, + import_path: str, + name: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> RegoMetadata: + """ + Creates a JSON document that Rego can access through its import path. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + import_path: Unique Rego import path in the form metadata., with one alphanumeric or + underscore segment. Reference it as data.. + + name: Name of the rego metadata document (unique per account) + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + return self._post( + path_template("/accounts/{account_id}/cws/rego-metadata", account_id=account_id), + body=maybe_transform( + { + "data": data, + "import_path": import_path, + "name": name, + }, + rego_metadata_create_params.RegoMetadataCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[RegoMetadata]._unwrapper, + ), + cast_to=cast(Type[RegoMetadata], ResultWrapper[RegoMetadata]), + ) + + def update( + self, + rego_metadata_id: str, + *, + account_id: str, + data: object, + import_path: str, + name: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> RegoMetadata: + """ + Replaces the metadata document's name, import path, and JSON data. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + rego_metadata_id: ID of the rego metadata document to update + + import_path: Unique Rego import path in the form metadata., with one alphanumeric or + underscore segment. Reference it as data.. + + name: Name of the rego metadata document (unique per account) + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not rego_metadata_id: + raise ValueError(f"Expected a non-empty value for `rego_metadata_id` but received {rego_metadata_id!r}") + return self._put( + path_template( + "/accounts/{account_id}/cws/rego-metadata/{rego_metadata_id}", + account_id=account_id, + rego_metadata_id=rego_metadata_id, + ), + body=maybe_transform( + { + "data": data, + "import_path": import_path, + "name": name, + }, + rego_metadata_update_params.RegoMetadataUpdateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[RegoMetadata]._unwrapper, + ), + cast_to=cast(Type[RegoMetadata], ResultWrapper[RegoMetadata]), + ) + + def list( + self, + *, + account_id: str, + cursor: str | Omit = omit, + direction: Literal["asc", "desc"] | Omit = omit, + import_path: str | Omit = omit, + name: str | Omit = omit, + order: Literal["name", "created_at", "updated_at"] | Omit = omit, + per_page: int | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> SyncCursorPagination[RegoMetadata]: + """ + Returns a paginated list of Rego metadata documents in the account. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + cursor: Pagination cursor from previous response + + direction: Sort direction (default: asc) + + import_path: Filter by import path (case-sensitive literal substring match) + + name: Filter by rego metadata name (case-insensitive substring match) + + order: Field to order results by (default: created_at) + + per_page: Number of items per page (1-100, default 20) + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + return self._get_api_list( + path_template("/accounts/{account_id}/cws/rego-metadata", account_id=account_id), + page=SyncCursorPagination[RegoMetadata], + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "cursor": cursor, + "direction": direction, + "import_path": import_path, + "name": name, + "order": order, + "per_page": per_page, + }, + rego_metadata_list_params.RegoMetadataListParams, + ), + ), + model=RegoMetadata, + ) + + def delete( + self, + rego_metadata_id: str, + *, + account_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> RegoMetadataDeleteResponse: + """ + Deletes the specified Rego metadata document. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + rego_metadata_id: ID of the rego metadata document to delete + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not rego_metadata_id: + raise ValueError(f"Expected a non-empty value for `rego_metadata_id` but received {rego_metadata_id!r}") + return self._delete( + path_template( + "/accounts/{account_id}/cws/rego-metadata/{rego_metadata_id}", + account_id=account_id, + rego_metadata_id=rego_metadata_id, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[RegoMetadataDeleteResponse]._unwrapper, + ), + cast_to=cast(Type[RegoMetadataDeleteResponse], ResultWrapper[RegoMetadataDeleteResponse]), + ) + + def get( + self, + rego_metadata_id: str, + *, + account_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> RegoMetadata: + """ + Returns the Rego metadata document with the specified ID. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + rego_metadata_id: ID of the rego metadata document to retrieve + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not rego_metadata_id: + raise ValueError(f"Expected a non-empty value for `rego_metadata_id` but received {rego_metadata_id!r}") + return self._get( + path_template( + "/accounts/{account_id}/cws/rego-metadata/{rego_metadata_id}", + account_id=account_id, + rego_metadata_id=rego_metadata_id, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[RegoMetadata]._unwrapper, + ), + cast_to=cast(Type[RegoMetadata], ResultWrapper[RegoMetadata]), + ) + + +class AsyncRegoMetadataResource(AsyncAPIResource): + @cached_property + def with_raw_response(self) -> AsyncRegoMetadataResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers + """ + return AsyncRegoMetadataResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncRegoMetadataResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response + """ + return AsyncRegoMetadataResourceWithStreamingResponse(self) + + async def create( + self, + *, + account_id: str, + data: object, + import_path: str, + name: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> RegoMetadata: + """ + Creates a JSON document that Rego can access through its import path. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + import_path: Unique Rego import path in the form metadata., with one alphanumeric or + underscore segment. Reference it as data.. + + name: Name of the rego metadata document (unique per account) + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + return await self._post( + path_template("/accounts/{account_id}/cws/rego-metadata", account_id=account_id), + body=await async_maybe_transform( + { + "data": data, + "import_path": import_path, + "name": name, + }, + rego_metadata_create_params.RegoMetadataCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[RegoMetadata]._unwrapper, + ), + cast_to=cast(Type[RegoMetadata], ResultWrapper[RegoMetadata]), + ) + + async def update( + self, + rego_metadata_id: str, + *, + account_id: str, + data: object, + import_path: str, + name: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> RegoMetadata: + """ + Replaces the metadata document's name, import path, and JSON data. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + rego_metadata_id: ID of the rego metadata document to update + + import_path: Unique Rego import path in the form metadata., with one alphanumeric or + underscore segment. Reference it as data.. + + name: Name of the rego metadata document (unique per account) + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not rego_metadata_id: + raise ValueError(f"Expected a non-empty value for `rego_metadata_id` but received {rego_metadata_id!r}") + return await self._put( + path_template( + "/accounts/{account_id}/cws/rego-metadata/{rego_metadata_id}", + account_id=account_id, + rego_metadata_id=rego_metadata_id, + ), + body=await async_maybe_transform( + { + "data": data, + "import_path": import_path, + "name": name, + }, + rego_metadata_update_params.RegoMetadataUpdateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[RegoMetadata]._unwrapper, + ), + cast_to=cast(Type[RegoMetadata], ResultWrapper[RegoMetadata]), + ) + + def list( + self, + *, + account_id: str, + cursor: str | Omit = omit, + direction: Literal["asc", "desc"] | Omit = omit, + import_path: str | Omit = omit, + name: str | Omit = omit, + order: Literal["name", "created_at", "updated_at"] | Omit = omit, + per_page: int | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> AsyncPaginator[RegoMetadata, AsyncCursorPagination[RegoMetadata]]: + """ + Returns a paginated list of Rego metadata documents in the account. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + cursor: Pagination cursor from previous response + + direction: Sort direction (default: asc) + + import_path: Filter by import path (case-sensitive literal substring match) + + name: Filter by rego metadata name (case-insensitive substring match) + + order: Field to order results by (default: created_at) + + per_page: Number of items per page (1-100, default 20) + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + return self._get_api_list( + path_template("/accounts/{account_id}/cws/rego-metadata", account_id=account_id), + page=AsyncCursorPagination[RegoMetadata], + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "cursor": cursor, + "direction": direction, + "import_path": import_path, + "name": name, + "order": order, + "per_page": per_page, + }, + rego_metadata_list_params.RegoMetadataListParams, + ), + ), + model=RegoMetadata, + ) + + async def delete( + self, + rego_metadata_id: str, + *, + account_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> RegoMetadataDeleteResponse: + """ + Deletes the specified Rego metadata document. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + rego_metadata_id: ID of the rego metadata document to delete + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not rego_metadata_id: + raise ValueError(f"Expected a non-empty value for `rego_metadata_id` but received {rego_metadata_id!r}") + return await self._delete( + path_template( + "/accounts/{account_id}/cws/rego-metadata/{rego_metadata_id}", + account_id=account_id, + rego_metadata_id=rego_metadata_id, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[RegoMetadataDeleteResponse]._unwrapper, + ), + cast_to=cast(Type[RegoMetadataDeleteResponse], ResultWrapper[RegoMetadataDeleteResponse]), + ) + + async def get( + self, + rego_metadata_id: str, + *, + account_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> RegoMetadata: + """ + Returns the Rego metadata document with the specified ID. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + rego_metadata_id: ID of the rego metadata document to retrieve + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not rego_metadata_id: + raise ValueError(f"Expected a non-empty value for `rego_metadata_id` but received {rego_metadata_id!r}") + return await self._get( + path_template( + "/accounts/{account_id}/cws/rego-metadata/{rego_metadata_id}", + account_id=account_id, + rego_metadata_id=rego_metadata_id, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[RegoMetadata]._unwrapper, + ), + cast_to=cast(Type[RegoMetadata], ResultWrapper[RegoMetadata]), + ) + + +class RegoMetadataResourceWithRawResponse: + def __init__(self, rego_metadata: RegoMetadataResource) -> None: + self._rego_metadata = rego_metadata + + self.create = to_raw_response_wrapper( + rego_metadata.create, + ) + self.update = to_raw_response_wrapper( + rego_metadata.update, + ) + self.list = to_raw_response_wrapper( + rego_metadata.list, + ) + self.delete = to_raw_response_wrapper( + rego_metadata.delete, + ) + self.get = to_raw_response_wrapper( + rego_metadata.get, + ) + + +class AsyncRegoMetadataResourceWithRawResponse: + def __init__(self, rego_metadata: AsyncRegoMetadataResource) -> None: + self._rego_metadata = rego_metadata + + self.create = async_to_raw_response_wrapper( + rego_metadata.create, + ) + self.update = async_to_raw_response_wrapper( + rego_metadata.update, + ) + self.list = async_to_raw_response_wrapper( + rego_metadata.list, + ) + self.delete = async_to_raw_response_wrapper( + rego_metadata.delete, + ) + self.get = async_to_raw_response_wrapper( + rego_metadata.get, + ) + + +class RegoMetadataResourceWithStreamingResponse: + def __init__(self, rego_metadata: RegoMetadataResource) -> None: + self._rego_metadata = rego_metadata + + self.create = to_streamed_response_wrapper( + rego_metadata.create, + ) + self.update = to_streamed_response_wrapper( + rego_metadata.update, + ) + self.list = to_streamed_response_wrapper( + rego_metadata.list, + ) + self.delete = to_streamed_response_wrapper( + rego_metadata.delete, + ) + self.get = to_streamed_response_wrapper( + rego_metadata.get, + ) + + +class AsyncRegoMetadataResourceWithStreamingResponse: + def __init__(self, rego_metadata: AsyncRegoMetadataResource) -> None: + self._rego_metadata = rego_metadata + + self.create = async_to_streamed_response_wrapper( + rego_metadata.create, + ) + self.update = async_to_streamed_response_wrapper( + rego_metadata.update, + ) + self.list = async_to_streamed_response_wrapper( + rego_metadata.list, + ) + self.delete = async_to_streamed_response_wrapper( + rego_metadata.delete, + ) + self.get = async_to_streamed_response_wrapper( + rego_metadata.get, + ) diff --git a/src/cloudflare/resources/zero_trust/cws/rego_modules.py b/src/cloudflare/resources/zero_trust/cws/rego_modules.py new file mode 100644 index 00000000000..f70044c5f9f --- /dev/null +++ b/src/cloudflare/resources/zero_trust/cws/rego_modules.py @@ -0,0 +1,711 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Type, cast +from typing_extensions import Literal + +import httpx + +from ...._types import Body, Omit, Query, Headers, NotGiven, omit, not_given +from ...._utils import path_template, maybe_transform, async_maybe_transform +from ...._compat import cached_property +from ...._resource import SyncAPIResource, AsyncAPIResource +from ...._response import ( + to_raw_response_wrapper, + to_streamed_response_wrapper, + async_to_raw_response_wrapper, + async_to_streamed_response_wrapper, +) +from ...._wrappers import ResultWrapper +from ....pagination import SyncCursorPagination, AsyncCursorPagination +from ...._base_client import AsyncPaginator, make_request_options +from ....types.zero_trust.cws import rego_module_list_params, rego_module_create_params, rego_module_update_params +from ....types.zero_trust.cws.rego_module import RegoModule +from ....types.zero_trust.cws.rego_module_delete_response import RegoModuleDeleteResponse + +__all__ = ["RegoModulesResource", "AsyncRegoModulesResource"] + + +class RegoModulesResource(SyncAPIResource): + @cached_property + def with_raw_response(self) -> RegoModulesResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers + """ + return RegoModulesResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> RegoModulesResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response + """ + return RegoModulesResourceWithStreamingResponse(self) + + def create( + self, + *, + account_id: str, + name: str, + rego_source: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> RegoModule: + """ + Creates a library Rego module and derives its package path from the source. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + name: Name of the Rego module (unique per account) + + rego_source: Library Rego source with a package beginning with "lib." Maximum 16384 UTF-8 + bytes. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + return self._post( + path_template("/accounts/{account_id}/cws/rego-modules", account_id=account_id), + body=maybe_transform( + { + "name": name, + "rego_source": rego_source, + }, + rego_module_create_params.RegoModuleCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[RegoModule]._unwrapper, + ), + cast_to=cast(Type[RegoModule], ResultWrapper[RegoModule]), + ) + + def update( + self, + rego_module_id: str, + *, + account_id: str, + name: str, + rego_source: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> RegoModule: + """ + Replaces the module and validates policies and libraries that depend on it. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + rego_module_id: ID of the Rego module to update + + name: Name of the Rego module (unique per account) + + rego_source: Library Rego source with a package beginning with "lib." Maximum 16384 UTF-8 + bytes. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not rego_module_id: + raise ValueError(f"Expected a non-empty value for `rego_module_id` but received {rego_module_id!r}") + return self._put( + path_template( + "/accounts/{account_id}/cws/rego-modules/{rego_module_id}", + account_id=account_id, + rego_module_id=rego_module_id, + ), + body=maybe_transform( + { + "name": name, + "rego_source": rego_source, + }, + rego_module_update_params.RegoModuleUpdateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[RegoModule]._unwrapper, + ), + cast_to=cast(Type[RegoModule], ResultWrapper[RegoModule]), + ) + + def list( + self, + *, + account_id: str, + cursor: str | Omit = omit, + direction: Literal["asc", "desc"] | Omit = omit, + name: str | Omit = omit, + order: Literal["name", "created_at", "updated_at"] | Omit = omit, + package_path: str | Omit = omit, + per_page: int | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> SyncCursorPagination[RegoModule]: + """ + Returns a paginated list of library Rego modules in the account. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + cursor: Pagination cursor from previous response + + direction: Sort direction (default: asc) + + name: Filter by Rego module name (case-insensitive substring match) + + order: Field to order results by (default: created_at) + + package_path: Filter by package path (case-sensitive literal substring match) + + per_page: Number of items per page (1-100, default 20) + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + return self._get_api_list( + path_template("/accounts/{account_id}/cws/rego-modules", account_id=account_id), + page=SyncCursorPagination[RegoModule], + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "cursor": cursor, + "direction": direction, + "name": name, + "order": order, + "package_path": package_path, + "per_page": per_page, + }, + rego_module_list_params.RegoModuleListParams, + ), + ), + model=RegoModule, + ) + + def delete( + self, + rego_module_id: str, + *, + account_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> RegoModuleDeleteResponse: + """ + Deletes the module if no policy or library references its rules. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + rego_module_id: ID of the Rego module to delete + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not rego_module_id: + raise ValueError(f"Expected a non-empty value for `rego_module_id` but received {rego_module_id!r}") + return self._delete( + path_template( + "/accounts/{account_id}/cws/rego-modules/{rego_module_id}", + account_id=account_id, + rego_module_id=rego_module_id, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[RegoModuleDeleteResponse]._unwrapper, + ), + cast_to=cast(Type[RegoModuleDeleteResponse], ResultWrapper[RegoModuleDeleteResponse]), + ) + + def get( + self, + rego_module_id: str, + *, + account_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> RegoModule: + """ + Returns the library Rego module with the specified ID. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + rego_module_id: ID of the Rego module to retrieve + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not rego_module_id: + raise ValueError(f"Expected a non-empty value for `rego_module_id` but received {rego_module_id!r}") + return self._get( + path_template( + "/accounts/{account_id}/cws/rego-modules/{rego_module_id}", + account_id=account_id, + rego_module_id=rego_module_id, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[RegoModule]._unwrapper, + ), + cast_to=cast(Type[RegoModule], ResultWrapper[RegoModule]), + ) + + +class AsyncRegoModulesResource(AsyncAPIResource): + @cached_property + def with_raw_response(self) -> AsyncRegoModulesResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers + """ + return AsyncRegoModulesResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncRegoModulesResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response + """ + return AsyncRegoModulesResourceWithStreamingResponse(self) + + async def create( + self, + *, + account_id: str, + name: str, + rego_source: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> RegoModule: + """ + Creates a library Rego module and derives its package path from the source. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + name: Name of the Rego module (unique per account) + + rego_source: Library Rego source with a package beginning with "lib." Maximum 16384 UTF-8 + bytes. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + return await self._post( + path_template("/accounts/{account_id}/cws/rego-modules", account_id=account_id), + body=await async_maybe_transform( + { + "name": name, + "rego_source": rego_source, + }, + rego_module_create_params.RegoModuleCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[RegoModule]._unwrapper, + ), + cast_to=cast(Type[RegoModule], ResultWrapper[RegoModule]), + ) + + async def update( + self, + rego_module_id: str, + *, + account_id: str, + name: str, + rego_source: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> RegoModule: + """ + Replaces the module and validates policies and libraries that depend on it. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + rego_module_id: ID of the Rego module to update + + name: Name of the Rego module (unique per account) + + rego_source: Library Rego source with a package beginning with "lib." Maximum 16384 UTF-8 + bytes. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not rego_module_id: + raise ValueError(f"Expected a non-empty value for `rego_module_id` but received {rego_module_id!r}") + return await self._put( + path_template( + "/accounts/{account_id}/cws/rego-modules/{rego_module_id}", + account_id=account_id, + rego_module_id=rego_module_id, + ), + body=await async_maybe_transform( + { + "name": name, + "rego_source": rego_source, + }, + rego_module_update_params.RegoModuleUpdateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[RegoModule]._unwrapper, + ), + cast_to=cast(Type[RegoModule], ResultWrapper[RegoModule]), + ) + + def list( + self, + *, + account_id: str, + cursor: str | Omit = omit, + direction: Literal["asc", "desc"] | Omit = omit, + name: str | Omit = omit, + order: Literal["name", "created_at", "updated_at"] | Omit = omit, + package_path: str | Omit = omit, + per_page: int | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> AsyncPaginator[RegoModule, AsyncCursorPagination[RegoModule]]: + """ + Returns a paginated list of library Rego modules in the account. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + cursor: Pagination cursor from previous response + + direction: Sort direction (default: asc) + + name: Filter by Rego module name (case-insensitive substring match) + + order: Field to order results by (default: created_at) + + package_path: Filter by package path (case-sensitive literal substring match) + + per_page: Number of items per page (1-100, default 20) + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + return self._get_api_list( + path_template("/accounts/{account_id}/cws/rego-modules", account_id=account_id), + page=AsyncCursorPagination[RegoModule], + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "cursor": cursor, + "direction": direction, + "name": name, + "order": order, + "package_path": package_path, + "per_page": per_page, + }, + rego_module_list_params.RegoModuleListParams, + ), + ), + model=RegoModule, + ) + + async def delete( + self, + rego_module_id: str, + *, + account_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> RegoModuleDeleteResponse: + """ + Deletes the module if no policy or library references its rules. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + rego_module_id: ID of the Rego module to delete + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not rego_module_id: + raise ValueError(f"Expected a non-empty value for `rego_module_id` but received {rego_module_id!r}") + return await self._delete( + path_template( + "/accounts/{account_id}/cws/rego-modules/{rego_module_id}", + account_id=account_id, + rego_module_id=rego_module_id, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[RegoModuleDeleteResponse]._unwrapper, + ), + cast_to=cast(Type[RegoModuleDeleteResponse], ResultWrapper[RegoModuleDeleteResponse]), + ) + + async def get( + self, + rego_module_id: str, + *, + account_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> RegoModule: + """ + Returns the library Rego module with the specified ID. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + rego_module_id: ID of the Rego module to retrieve + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not rego_module_id: + raise ValueError(f"Expected a non-empty value for `rego_module_id` but received {rego_module_id!r}") + return await self._get( + path_template( + "/accounts/{account_id}/cws/rego-modules/{rego_module_id}", + account_id=account_id, + rego_module_id=rego_module_id, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[RegoModule]._unwrapper, + ), + cast_to=cast(Type[RegoModule], ResultWrapper[RegoModule]), + ) + + +class RegoModulesResourceWithRawResponse: + def __init__(self, rego_modules: RegoModulesResource) -> None: + self._rego_modules = rego_modules + + self.create = to_raw_response_wrapper( + rego_modules.create, + ) + self.update = to_raw_response_wrapper( + rego_modules.update, + ) + self.list = to_raw_response_wrapper( + rego_modules.list, + ) + self.delete = to_raw_response_wrapper( + rego_modules.delete, + ) + self.get = to_raw_response_wrapper( + rego_modules.get, + ) + + +class AsyncRegoModulesResourceWithRawResponse: + def __init__(self, rego_modules: AsyncRegoModulesResource) -> None: + self._rego_modules = rego_modules + + self.create = async_to_raw_response_wrapper( + rego_modules.create, + ) + self.update = async_to_raw_response_wrapper( + rego_modules.update, + ) + self.list = async_to_raw_response_wrapper( + rego_modules.list, + ) + self.delete = async_to_raw_response_wrapper( + rego_modules.delete, + ) + self.get = async_to_raw_response_wrapper( + rego_modules.get, + ) + + +class RegoModulesResourceWithStreamingResponse: + def __init__(self, rego_modules: RegoModulesResource) -> None: + self._rego_modules = rego_modules + + self.create = to_streamed_response_wrapper( + rego_modules.create, + ) + self.update = to_streamed_response_wrapper( + rego_modules.update, + ) + self.list = to_streamed_response_wrapper( + rego_modules.list, + ) + self.delete = to_streamed_response_wrapper( + rego_modules.delete, + ) + self.get = to_streamed_response_wrapper( + rego_modules.get, + ) + + +class AsyncRegoModulesResourceWithStreamingResponse: + def __init__(self, rego_modules: AsyncRegoModulesResource) -> None: + self._rego_modules = rego_modules + + self.create = async_to_streamed_response_wrapper( + rego_modules.create, + ) + self.update = async_to_streamed_response_wrapper( + rego_modules.update, + ) + self.list = async_to_streamed_response_wrapper( + rego_modules.list, + ) + self.delete = async_to_streamed_response_wrapper( + rego_modules.delete, + ) + self.get = async_to_streamed_response_wrapper( + rego_modules.get, + ) diff --git a/src/cloudflare/resources/zero_trust/cws/tenant_structures/__init__.py b/src/cloudflare/resources/zero_trust/cws/tenant_structures/__init__.py new file mode 100644 index 00000000000..d5c110e8753 --- /dev/null +++ b/src/cloudflare/resources/zero_trust/cws/tenant_structures/__init__.py @@ -0,0 +1,33 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from .nodes import ( + NodesResource, + AsyncNodesResource, + NodesResourceWithRawResponse, + AsyncNodesResourceWithRawResponse, + NodesResourceWithStreamingResponse, + AsyncNodesResourceWithStreamingResponse, +) +from .tenant_structures import ( + TenantStructuresResource, + AsyncTenantStructuresResource, + TenantStructuresResourceWithRawResponse, + AsyncTenantStructuresResourceWithRawResponse, + TenantStructuresResourceWithStreamingResponse, + AsyncTenantStructuresResourceWithStreamingResponse, +) + +__all__ = [ + "NodesResource", + "AsyncNodesResource", + "NodesResourceWithRawResponse", + "AsyncNodesResourceWithRawResponse", + "NodesResourceWithStreamingResponse", + "AsyncNodesResourceWithStreamingResponse", + "TenantStructuresResource", + "AsyncTenantStructuresResource", + "TenantStructuresResourceWithRawResponse", + "AsyncTenantStructuresResourceWithRawResponse", + "TenantStructuresResourceWithStreamingResponse", + "AsyncTenantStructuresResourceWithStreamingResponse", +] diff --git a/src/cloudflare/resources/zero_trust/cws/tenant_structures/nodes.py b/src/cloudflare/resources/zero_trust/cws/tenant_structures/nodes.py new file mode 100644 index 00000000000..d3373efa1b1 --- /dev/null +++ b/src/cloudflare/resources/zero_trust/cws/tenant_structures/nodes.py @@ -0,0 +1,1013 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Type, Iterable, cast +from typing_extensions import Literal + +import httpx + +from ....._types import Body, Omit, Query, Headers, NotGiven, omit, not_given +from ....._utils import path_template, maybe_transform, async_maybe_transform +from ....._compat import cached_property +from ....._resource import SyncAPIResource, AsyncAPIResource +from ....._response import ( + to_raw_response_wrapper, + to_streamed_response_wrapper, + async_to_raw_response_wrapper, + async_to_streamed_response_wrapper, +) +from ....._wrappers import ResultWrapper +from .....pagination import SyncCursorPagination, AsyncCursorPagination +from ....._base_client import AsyncPaginator, make_request_options +from .....types.zero_trust.cws.tenant_structures import ( + node_list_params, + node_batch_params, + node_create_params, + node_update_params, +) +from .....types.zero_trust.cws.tenant_structures.node_batch_response import NodeBatchResponse +from .....types.zero_trust.cws.tenant_structures.node_delete_response import NodeDeleteResponse +from .....types.zero_trust.cws.tenant_structures.tenant_structure_node import TenantStructureNode + +__all__ = ["NodesResource", "AsyncNodesResource"] + + +class NodesResource(SyncAPIResource): + @cached_property + def with_raw_response(self) -> NodesResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers + """ + return NodesResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> NodesResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response + """ + return NodesResourceWithStreamingResponse(self) + + def create( + self, + structure_id: str, + *, + account_id: str, + native_id: str, + node_kind: str, + name: str | Omit = omit, + parent: str | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> TenantStructureNode: + """ + Adds a validated cloud-native node to the tenant hierarchy. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + structure_id: ID of the parent tenant structure + + native_id: Cloud-native identifier of this node, unique within the structure; the + parent-reference target. Shape depends on the structure's application. Immutable + after create. + + node_kind: + Position in the tree. Legal values depend on the structure's application (aws: + root/ou/account; cloudflare: org/account/zone). At most one root per structure. + Immutable after create. + + name: Display name (e.g. an OU or account name), mutable. Optional; empty by default. + + parent: Native ID of this node's parent. Required for non-root nodes and omitted for the + root. The parent must be in the same structure and able to contain this node + kind. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not structure_id: + raise ValueError(f"Expected a non-empty value for `structure_id` but received {structure_id!r}") + return self._post( + path_template( + "/accounts/{account_id}/cws/tenant-structures/{structure_id}/nodes", + account_id=account_id, + structure_id=structure_id, + ), + body=maybe_transform( + { + "native_id": native_id, + "node_kind": node_kind, + "name": name, + "parent": parent, + }, + node_create_params.NodeCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[TenantStructureNode]._unwrapper, + ), + cast_to=cast(Type[TenantStructureNode], ResultWrapper[TenantStructureNode]), + ) + + def update( + self, + node_id: str, + *, + account_id: str, + structure_id: str, + native_id: str, + node_kind: str, + name: str | Omit = omit, + parent: str | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> TenantStructureNode: + """ + Updates the node's display name or parent while preserving its immutable + identity fields. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + structure_id: ID of the parent tenant structure + + node_id: ID of the node to update + + native_id: Cloud-native identifier of this node, unique within the structure; the + parent-reference target. Shape depends on the structure's application. Immutable + after create. + + node_kind: + Position in the tree. Legal values depend on the structure's application (aws: + root/ou/account; cloudflare: org/account/zone). At most one root per structure. + Immutable after create. + + name: Display name (e.g. an OU or account name), mutable. Optional; empty by default. + + parent: Native ID of this node's parent. Required for non-root nodes and omitted for the + root. The parent must be in the same structure and able to contain this node + kind. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not structure_id: + raise ValueError(f"Expected a non-empty value for `structure_id` but received {structure_id!r}") + if not node_id: + raise ValueError(f"Expected a non-empty value for `node_id` but received {node_id!r}") + return self._put( + path_template( + "/accounts/{account_id}/cws/tenant-structures/{structure_id}/nodes/{node_id}", + account_id=account_id, + structure_id=structure_id, + node_id=node_id, + ), + body=maybe_transform( + { + "native_id": native_id, + "node_kind": node_kind, + "name": name, + "parent": parent, + }, + node_update_params.NodeUpdateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[TenantStructureNode]._unwrapper, + ), + cast_to=cast(Type[TenantStructureNode], ResultWrapper[TenantStructureNode]), + ) + + def list( + self, + structure_id: str, + *, + account_id: str, + cursor: str | Omit = omit, + direction: Literal["asc", "desc"] | Omit = omit, + name: str | Omit = omit, + native_id: str | Omit = omit, + node_kind: str | Omit = omit, + order: Literal["name", "created_at", "updated_at"] | Omit = omit, + parent: str | Omit = omit, + per_page: int | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> SyncCursorPagination[TenantStructureNode]: + """ + Returns a paginated list of nodes in the tenant structure. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + structure_id: ID of the parent tenant structure + + cursor: Pagination cursor from previous response + + direction: Sort direction (default: asc) + + name: Filter by node name (case-insensitive substring match) + + native_id: Filter by exact cloud-native identifier + + node_kind: Filter by exact node kind + + order: Field to order results by (default: created_at) + + parent: Filter by exact parent native ID + + per_page: Number of items per page (1-100, default 20) + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not structure_id: + raise ValueError(f"Expected a non-empty value for `structure_id` but received {structure_id!r}") + return self._get_api_list( + path_template( + "/accounts/{account_id}/cws/tenant-structures/{structure_id}/nodes", + account_id=account_id, + structure_id=structure_id, + ), + page=SyncCursorPagination[TenantStructureNode], + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "cursor": cursor, + "direction": direction, + "name": name, + "native_id": native_id, + "node_kind": node_kind, + "order": order, + "parent": parent, + "per_page": per_page, + }, + node_list_params.NodeListParams, + ), + ), + model=TenantStructureNode, + ) + + def delete( + self, + node_id: str, + *, + account_id: str, + structure_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> NodeDeleteResponse: + """ + Deletes a childless node from the tenant hierarchy. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + structure_id: ID of the parent tenant structure + + node_id: ID of the node to delete + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not structure_id: + raise ValueError(f"Expected a non-empty value for `structure_id` but received {structure_id!r}") + if not node_id: + raise ValueError(f"Expected a non-empty value for `node_id` but received {node_id!r}") + return self._delete( + path_template( + "/accounts/{account_id}/cws/tenant-structures/{structure_id}/nodes/{node_id}", + account_id=account_id, + structure_id=structure_id, + node_id=node_id, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[NodeDeleteResponse]._unwrapper, + ), + cast_to=cast(Type[NodeDeleteResponse], ResultWrapper[NodeDeleteResponse]), + ) + + def batch( + self, + structure_id: str, + *, + account_id: str, + creates: Iterable[node_batch_params.Create], + deletes: Iterable[node_batch_params.Delete], + updates: Iterable[node_batch_params.Update], + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> NodeBatchResponse: + """Atomically validates and applies 1 to 500 unordered node operations. + + Creates may + reference new parents but cannot reuse a native_id deleted in the same batch. + Maximum body size: 1 MiB. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + structure_id: ID of the parent tenant structure + + creates: Nodes to create; parents may be created elsewhere in this request + + deletes: Nodes to delete; every descendant that will not be reparented must also be + deleted + + updates: Nodes whose mutable fields should be fully replaced + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not structure_id: + raise ValueError(f"Expected a non-empty value for `structure_id` but received {structure_id!r}") + return self._post( + path_template( + "/accounts/{account_id}/cws/tenant-structures/{structure_id}/nodes/batch", + account_id=account_id, + structure_id=structure_id, + ), + body=maybe_transform( + { + "creates": creates, + "deletes": deletes, + "updates": updates, + }, + node_batch_params.NodeBatchParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[NodeBatchResponse]._unwrapper, + ), + cast_to=cast(Type[NodeBatchResponse], ResultWrapper[NodeBatchResponse]), + ) + + def get( + self, + node_id: str, + *, + account_id: str, + structure_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> TenantStructureNode: + """ + Returns the tenant node with the specified ID. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + structure_id: ID of the parent tenant structure + + node_id: ID of the node to retrieve + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not structure_id: + raise ValueError(f"Expected a non-empty value for `structure_id` but received {structure_id!r}") + if not node_id: + raise ValueError(f"Expected a non-empty value for `node_id` but received {node_id!r}") + return self._get( + path_template( + "/accounts/{account_id}/cws/tenant-structures/{structure_id}/nodes/{node_id}", + account_id=account_id, + structure_id=structure_id, + node_id=node_id, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[TenantStructureNode]._unwrapper, + ), + cast_to=cast(Type[TenantStructureNode], ResultWrapper[TenantStructureNode]), + ) + + +class AsyncNodesResource(AsyncAPIResource): + @cached_property + def with_raw_response(self) -> AsyncNodesResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers + """ + return AsyncNodesResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncNodesResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response + """ + return AsyncNodesResourceWithStreamingResponse(self) + + async def create( + self, + structure_id: str, + *, + account_id: str, + native_id: str, + node_kind: str, + name: str | Omit = omit, + parent: str | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> TenantStructureNode: + """ + Adds a validated cloud-native node to the tenant hierarchy. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + structure_id: ID of the parent tenant structure + + native_id: Cloud-native identifier of this node, unique within the structure; the + parent-reference target. Shape depends on the structure's application. Immutable + after create. + + node_kind: + Position in the tree. Legal values depend on the structure's application (aws: + root/ou/account; cloudflare: org/account/zone). At most one root per structure. + Immutable after create. + + name: Display name (e.g. an OU or account name), mutable. Optional; empty by default. + + parent: Native ID of this node's parent. Required for non-root nodes and omitted for the + root. The parent must be in the same structure and able to contain this node + kind. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not structure_id: + raise ValueError(f"Expected a non-empty value for `structure_id` but received {structure_id!r}") + return await self._post( + path_template( + "/accounts/{account_id}/cws/tenant-structures/{structure_id}/nodes", + account_id=account_id, + structure_id=structure_id, + ), + body=await async_maybe_transform( + { + "native_id": native_id, + "node_kind": node_kind, + "name": name, + "parent": parent, + }, + node_create_params.NodeCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[TenantStructureNode]._unwrapper, + ), + cast_to=cast(Type[TenantStructureNode], ResultWrapper[TenantStructureNode]), + ) + + async def update( + self, + node_id: str, + *, + account_id: str, + structure_id: str, + native_id: str, + node_kind: str, + name: str | Omit = omit, + parent: str | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> TenantStructureNode: + """ + Updates the node's display name or parent while preserving its immutable + identity fields. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + structure_id: ID of the parent tenant structure + + node_id: ID of the node to update + + native_id: Cloud-native identifier of this node, unique within the structure; the + parent-reference target. Shape depends on the structure's application. Immutable + after create. + + node_kind: + Position in the tree. Legal values depend on the structure's application (aws: + root/ou/account; cloudflare: org/account/zone). At most one root per structure. + Immutable after create. + + name: Display name (e.g. an OU or account name), mutable. Optional; empty by default. + + parent: Native ID of this node's parent. Required for non-root nodes and omitted for the + root. The parent must be in the same structure and able to contain this node + kind. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not structure_id: + raise ValueError(f"Expected a non-empty value for `structure_id` but received {structure_id!r}") + if not node_id: + raise ValueError(f"Expected a non-empty value for `node_id` but received {node_id!r}") + return await self._put( + path_template( + "/accounts/{account_id}/cws/tenant-structures/{structure_id}/nodes/{node_id}", + account_id=account_id, + structure_id=structure_id, + node_id=node_id, + ), + body=await async_maybe_transform( + { + "native_id": native_id, + "node_kind": node_kind, + "name": name, + "parent": parent, + }, + node_update_params.NodeUpdateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[TenantStructureNode]._unwrapper, + ), + cast_to=cast(Type[TenantStructureNode], ResultWrapper[TenantStructureNode]), + ) + + def list( + self, + structure_id: str, + *, + account_id: str, + cursor: str | Omit = omit, + direction: Literal["asc", "desc"] | Omit = omit, + name: str | Omit = omit, + native_id: str | Omit = omit, + node_kind: str | Omit = omit, + order: Literal["name", "created_at", "updated_at"] | Omit = omit, + parent: str | Omit = omit, + per_page: int | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> AsyncPaginator[TenantStructureNode, AsyncCursorPagination[TenantStructureNode]]: + """ + Returns a paginated list of nodes in the tenant structure. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + structure_id: ID of the parent tenant structure + + cursor: Pagination cursor from previous response + + direction: Sort direction (default: asc) + + name: Filter by node name (case-insensitive substring match) + + native_id: Filter by exact cloud-native identifier + + node_kind: Filter by exact node kind + + order: Field to order results by (default: created_at) + + parent: Filter by exact parent native ID + + per_page: Number of items per page (1-100, default 20) + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not structure_id: + raise ValueError(f"Expected a non-empty value for `structure_id` but received {structure_id!r}") + return self._get_api_list( + path_template( + "/accounts/{account_id}/cws/tenant-structures/{structure_id}/nodes", + account_id=account_id, + structure_id=structure_id, + ), + page=AsyncCursorPagination[TenantStructureNode], + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "cursor": cursor, + "direction": direction, + "name": name, + "native_id": native_id, + "node_kind": node_kind, + "order": order, + "parent": parent, + "per_page": per_page, + }, + node_list_params.NodeListParams, + ), + ), + model=TenantStructureNode, + ) + + async def delete( + self, + node_id: str, + *, + account_id: str, + structure_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> NodeDeleteResponse: + """ + Deletes a childless node from the tenant hierarchy. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + structure_id: ID of the parent tenant structure + + node_id: ID of the node to delete + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not structure_id: + raise ValueError(f"Expected a non-empty value for `structure_id` but received {structure_id!r}") + if not node_id: + raise ValueError(f"Expected a non-empty value for `node_id` but received {node_id!r}") + return await self._delete( + path_template( + "/accounts/{account_id}/cws/tenant-structures/{structure_id}/nodes/{node_id}", + account_id=account_id, + structure_id=structure_id, + node_id=node_id, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[NodeDeleteResponse]._unwrapper, + ), + cast_to=cast(Type[NodeDeleteResponse], ResultWrapper[NodeDeleteResponse]), + ) + + async def batch( + self, + structure_id: str, + *, + account_id: str, + creates: Iterable[node_batch_params.Create], + deletes: Iterable[node_batch_params.Delete], + updates: Iterable[node_batch_params.Update], + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> NodeBatchResponse: + """Atomically validates and applies 1 to 500 unordered node operations. + + Creates may + reference new parents but cannot reuse a native_id deleted in the same batch. + Maximum body size: 1 MiB. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + structure_id: ID of the parent tenant structure + + creates: Nodes to create; parents may be created elsewhere in this request + + deletes: Nodes to delete; every descendant that will not be reparented must also be + deleted + + updates: Nodes whose mutable fields should be fully replaced + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not structure_id: + raise ValueError(f"Expected a non-empty value for `structure_id` but received {structure_id!r}") + return await self._post( + path_template( + "/accounts/{account_id}/cws/tenant-structures/{structure_id}/nodes/batch", + account_id=account_id, + structure_id=structure_id, + ), + body=await async_maybe_transform( + { + "creates": creates, + "deletes": deletes, + "updates": updates, + }, + node_batch_params.NodeBatchParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[NodeBatchResponse]._unwrapper, + ), + cast_to=cast(Type[NodeBatchResponse], ResultWrapper[NodeBatchResponse]), + ) + + async def get( + self, + node_id: str, + *, + account_id: str, + structure_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> TenantStructureNode: + """ + Returns the tenant node with the specified ID. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + structure_id: ID of the parent tenant structure + + node_id: ID of the node to retrieve + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not structure_id: + raise ValueError(f"Expected a non-empty value for `structure_id` but received {structure_id!r}") + if not node_id: + raise ValueError(f"Expected a non-empty value for `node_id` but received {node_id!r}") + return await self._get( + path_template( + "/accounts/{account_id}/cws/tenant-structures/{structure_id}/nodes/{node_id}", + account_id=account_id, + structure_id=structure_id, + node_id=node_id, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[TenantStructureNode]._unwrapper, + ), + cast_to=cast(Type[TenantStructureNode], ResultWrapper[TenantStructureNode]), + ) + + +class NodesResourceWithRawResponse: + def __init__(self, nodes: NodesResource) -> None: + self._nodes = nodes + + self.create = to_raw_response_wrapper( + nodes.create, + ) + self.update = to_raw_response_wrapper( + nodes.update, + ) + self.list = to_raw_response_wrapper( + nodes.list, + ) + self.delete = to_raw_response_wrapper( + nodes.delete, + ) + self.batch = to_raw_response_wrapper( + nodes.batch, + ) + self.get = to_raw_response_wrapper( + nodes.get, + ) + + +class AsyncNodesResourceWithRawResponse: + def __init__(self, nodes: AsyncNodesResource) -> None: + self._nodes = nodes + + self.create = async_to_raw_response_wrapper( + nodes.create, + ) + self.update = async_to_raw_response_wrapper( + nodes.update, + ) + self.list = async_to_raw_response_wrapper( + nodes.list, + ) + self.delete = async_to_raw_response_wrapper( + nodes.delete, + ) + self.batch = async_to_raw_response_wrapper( + nodes.batch, + ) + self.get = async_to_raw_response_wrapper( + nodes.get, + ) + + +class NodesResourceWithStreamingResponse: + def __init__(self, nodes: NodesResource) -> None: + self._nodes = nodes + + self.create = to_streamed_response_wrapper( + nodes.create, + ) + self.update = to_streamed_response_wrapper( + nodes.update, + ) + self.list = to_streamed_response_wrapper( + nodes.list, + ) + self.delete = to_streamed_response_wrapper( + nodes.delete, + ) + self.batch = to_streamed_response_wrapper( + nodes.batch, + ) + self.get = to_streamed_response_wrapper( + nodes.get, + ) + + +class AsyncNodesResourceWithStreamingResponse: + def __init__(self, nodes: AsyncNodesResource) -> None: + self._nodes = nodes + + self.create = async_to_streamed_response_wrapper( + nodes.create, + ) + self.update = async_to_streamed_response_wrapper( + nodes.update, + ) + self.list = async_to_streamed_response_wrapper( + nodes.list, + ) + self.delete = async_to_streamed_response_wrapper( + nodes.delete, + ) + self.batch = async_to_streamed_response_wrapper( + nodes.batch, + ) + self.get = async_to_streamed_response_wrapper( + nodes.get, + ) diff --git a/src/cloudflare/resources/zero_trust/cws/tenant_structures/tenant_structures.py b/src/cloudflare/resources/zero_trust/cws/tenant_structures/tenant_structures.py new file mode 100644 index 00000000000..613a35a3175 --- /dev/null +++ b/src/cloudflare/resources/zero_trust/cws/tenant_structures/tenant_structures.py @@ -0,0 +1,765 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Type, cast +from typing_extensions import Literal + +import httpx + +from .nodes import ( + NodesResource, + AsyncNodesResource, + NodesResourceWithRawResponse, + AsyncNodesResourceWithRawResponse, + NodesResourceWithStreamingResponse, + AsyncNodesResourceWithStreamingResponse, +) +from ....._types import Body, Omit, Query, Headers, NotGiven, omit, not_given +from ....._utils import path_template, maybe_transform, async_maybe_transform +from ....._compat import cached_property +from ....._resource import SyncAPIResource, AsyncAPIResource +from ....._response import ( + to_raw_response_wrapper, + to_streamed_response_wrapper, + async_to_raw_response_wrapper, + async_to_streamed_response_wrapper, +) +from ....._wrappers import ResultWrapper +from .....pagination import SyncCursorPagination, AsyncCursorPagination +from ....._base_client import AsyncPaginator, make_request_options +from .....types.zero_trust.cws import ( + tenant_structure_list_params, + tenant_structure_create_params, + tenant_structure_update_params, +) +from .....types.zero_trust.cws.tenant_structure import TenantStructure +from .....types.zero_trust.cws.tenant_structure_delete_response import TenantStructureDeleteResponse + +__all__ = ["TenantStructuresResource", "AsyncTenantStructuresResource"] + + +class TenantStructuresResource(SyncAPIResource): + @cached_property + def nodes(self) -> NodesResource: + return NodesResource(self._client) + + @cached_property + def with_raw_response(self) -> TenantStructuresResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers + """ + return TenantStructuresResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> TenantStructuresResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response + """ + return TenantStructuresResourceWithStreamingResponse(self) + + def create( + self, + *, + account_id: str, + application: Literal["aws", "cloudflare"], + name: str, + import_path: str | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> TenantStructure: + """ + Creates an empty tenant hierarchy for the selected cloud application. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + application: Platform this structure models. Immutable after creation. + + name: Human-readable name; unique per account + + import_path: Optional unique Rego mount path in the form tenant..; + application must match. Omit to leave unmounted. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + return self._post( + path_template("/accounts/{account_id}/cws/tenant-structures", account_id=account_id), + body=maybe_transform( + { + "application": application, + "name": name, + "import_path": import_path, + }, + tenant_structure_create_params.TenantStructureCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[TenantStructure]._unwrapper, + ), + cast_to=cast(Type[TenantStructure], ResultWrapper[TenantStructure]), + ) + + def update( + self, + structure_id: str, + *, + account_id: str, + application: Literal["aws", "cloudflare"], + name: str, + import_path: str | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> TenantStructure: + """ + Updates the tenant structure's name and import path; its application remains + immutable. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + structure_id: ID of the tenant structure to update + + application: Platform this structure models. Must match the existing value. + + name: Human-readable name; unique per account + + import_path: Optional unique Rego mount path in the form tenant..; + application must match. Omit to clear. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not structure_id: + raise ValueError(f"Expected a non-empty value for `structure_id` but received {structure_id!r}") + return self._put( + path_template( + "/accounts/{account_id}/cws/tenant-structures/{structure_id}", + account_id=account_id, + structure_id=structure_id, + ), + body=maybe_transform( + { + "application": application, + "name": name, + "import_path": import_path, + }, + tenant_structure_update_params.TenantStructureUpdateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[TenantStructure]._unwrapper, + ), + cast_to=cast(Type[TenantStructure], ResultWrapper[TenantStructure]), + ) + + def list( + self, + *, + account_id: str, + cursor: str | Omit = omit, + direction: Literal["asc", "desc"] | Omit = omit, + import_path: str | Omit = omit, + name: str | Omit = omit, + order: Literal["name", "created_at", "updated_at"] | Omit = omit, + per_page: int | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> SyncCursorPagination[TenantStructure]: + """ + Returns a paginated list of tenant structures in the account. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + cursor: Pagination cursor from previous response + + direction: Sort direction (default: asc) + + import_path: Filter by import path (case-sensitive literal substring match) + + name: Filter by tenant structure name (case-insensitive substring match) + + order: Field to order results by (default: created_at) + + per_page: Number of items per page (1-100, default 20) + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + return self._get_api_list( + path_template("/accounts/{account_id}/cws/tenant-structures", account_id=account_id), + page=SyncCursorPagination[TenantStructure], + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "cursor": cursor, + "direction": direction, + "import_path": import_path, + "name": name, + "order": order, + "per_page": per_page, + }, + tenant_structure_list_params.TenantStructureListParams, + ), + ), + model=TenantStructure, + ) + + def delete( + self, + structure_id: str, + *, + account_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> TenantStructureDeleteResponse: + """ + Deletes the tenant structure and all nodes in its hierarchy. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + structure_id: ID of the tenant structure to delete + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not structure_id: + raise ValueError(f"Expected a non-empty value for `structure_id` but received {structure_id!r}") + return self._delete( + path_template( + "/accounts/{account_id}/cws/tenant-structures/{structure_id}", + account_id=account_id, + structure_id=structure_id, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[TenantStructureDeleteResponse]._unwrapper, + ), + cast_to=cast(Type[TenantStructureDeleteResponse], ResultWrapper[TenantStructureDeleteResponse]), + ) + + def get( + self, + structure_id: str, + *, + account_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> TenantStructure: + """ + Returns the tenant structure with the specified ID. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + structure_id: ID of the tenant structure to retrieve + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not structure_id: + raise ValueError(f"Expected a non-empty value for `structure_id` but received {structure_id!r}") + return self._get( + path_template( + "/accounts/{account_id}/cws/tenant-structures/{structure_id}", + account_id=account_id, + structure_id=structure_id, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[TenantStructure]._unwrapper, + ), + cast_to=cast(Type[TenantStructure], ResultWrapper[TenantStructure]), + ) + + +class AsyncTenantStructuresResource(AsyncAPIResource): + @cached_property + def nodes(self) -> AsyncNodesResource: + return AsyncNodesResource(self._client) + + @cached_property + def with_raw_response(self) -> AsyncTenantStructuresResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers + """ + return AsyncTenantStructuresResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncTenantStructuresResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response + """ + return AsyncTenantStructuresResourceWithStreamingResponse(self) + + async def create( + self, + *, + account_id: str, + application: Literal["aws", "cloudflare"], + name: str, + import_path: str | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> TenantStructure: + """ + Creates an empty tenant hierarchy for the selected cloud application. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + application: Platform this structure models. Immutable after creation. + + name: Human-readable name; unique per account + + import_path: Optional unique Rego mount path in the form tenant..; + application must match. Omit to leave unmounted. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + return await self._post( + path_template("/accounts/{account_id}/cws/tenant-structures", account_id=account_id), + body=await async_maybe_transform( + { + "application": application, + "name": name, + "import_path": import_path, + }, + tenant_structure_create_params.TenantStructureCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[TenantStructure]._unwrapper, + ), + cast_to=cast(Type[TenantStructure], ResultWrapper[TenantStructure]), + ) + + async def update( + self, + structure_id: str, + *, + account_id: str, + application: Literal["aws", "cloudflare"], + name: str, + import_path: str | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> TenantStructure: + """ + Updates the tenant structure's name and import path; its application remains + immutable. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + structure_id: ID of the tenant structure to update + + application: Platform this structure models. Must match the existing value. + + name: Human-readable name; unique per account + + import_path: Optional unique Rego mount path in the form tenant..; + application must match. Omit to clear. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not structure_id: + raise ValueError(f"Expected a non-empty value for `structure_id` but received {structure_id!r}") + return await self._put( + path_template( + "/accounts/{account_id}/cws/tenant-structures/{structure_id}", + account_id=account_id, + structure_id=structure_id, + ), + body=await async_maybe_transform( + { + "application": application, + "name": name, + "import_path": import_path, + }, + tenant_structure_update_params.TenantStructureUpdateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[TenantStructure]._unwrapper, + ), + cast_to=cast(Type[TenantStructure], ResultWrapper[TenantStructure]), + ) + + def list( + self, + *, + account_id: str, + cursor: str | Omit = omit, + direction: Literal["asc", "desc"] | Omit = omit, + import_path: str | Omit = omit, + name: str | Omit = omit, + order: Literal["name", "created_at", "updated_at"] | Omit = omit, + per_page: int | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> AsyncPaginator[TenantStructure, AsyncCursorPagination[TenantStructure]]: + """ + Returns a paginated list of tenant structures in the account. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + cursor: Pagination cursor from previous response + + direction: Sort direction (default: asc) + + import_path: Filter by import path (case-sensitive literal substring match) + + name: Filter by tenant structure name (case-insensitive substring match) + + order: Field to order results by (default: created_at) + + per_page: Number of items per page (1-100, default 20) + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + return self._get_api_list( + path_template("/accounts/{account_id}/cws/tenant-structures", account_id=account_id), + page=AsyncCursorPagination[TenantStructure], + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "cursor": cursor, + "direction": direction, + "import_path": import_path, + "name": name, + "order": order, + "per_page": per_page, + }, + tenant_structure_list_params.TenantStructureListParams, + ), + ), + model=TenantStructure, + ) + + async def delete( + self, + structure_id: str, + *, + account_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> TenantStructureDeleteResponse: + """ + Deletes the tenant structure and all nodes in its hierarchy. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + structure_id: ID of the tenant structure to delete + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not structure_id: + raise ValueError(f"Expected a non-empty value for `structure_id` but received {structure_id!r}") + return await self._delete( + path_template( + "/accounts/{account_id}/cws/tenant-structures/{structure_id}", + account_id=account_id, + structure_id=structure_id, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[TenantStructureDeleteResponse]._unwrapper, + ), + cast_to=cast(Type[TenantStructureDeleteResponse], ResultWrapper[TenantStructureDeleteResponse]), + ) + + async def get( + self, + structure_id: str, + *, + account_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> TenantStructure: + """ + Returns the tenant structure with the specified ID. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + structure_id: ID of the tenant structure to retrieve + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not structure_id: + raise ValueError(f"Expected a non-empty value for `structure_id` but received {structure_id!r}") + return await self._get( + path_template( + "/accounts/{account_id}/cws/tenant-structures/{structure_id}", + account_id=account_id, + structure_id=structure_id, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[TenantStructure]._unwrapper, + ), + cast_to=cast(Type[TenantStructure], ResultWrapper[TenantStructure]), + ) + + +class TenantStructuresResourceWithRawResponse: + def __init__(self, tenant_structures: TenantStructuresResource) -> None: + self._tenant_structures = tenant_structures + + self.create = to_raw_response_wrapper( + tenant_structures.create, + ) + self.update = to_raw_response_wrapper( + tenant_structures.update, + ) + self.list = to_raw_response_wrapper( + tenant_structures.list, + ) + self.delete = to_raw_response_wrapper( + tenant_structures.delete, + ) + self.get = to_raw_response_wrapper( + tenant_structures.get, + ) + + @cached_property + def nodes(self) -> NodesResourceWithRawResponse: + return NodesResourceWithRawResponse(self._tenant_structures.nodes) + + +class AsyncTenantStructuresResourceWithRawResponse: + def __init__(self, tenant_structures: AsyncTenantStructuresResource) -> None: + self._tenant_structures = tenant_structures + + self.create = async_to_raw_response_wrapper( + tenant_structures.create, + ) + self.update = async_to_raw_response_wrapper( + tenant_structures.update, + ) + self.list = async_to_raw_response_wrapper( + tenant_structures.list, + ) + self.delete = async_to_raw_response_wrapper( + tenant_structures.delete, + ) + self.get = async_to_raw_response_wrapper( + tenant_structures.get, + ) + + @cached_property + def nodes(self) -> AsyncNodesResourceWithRawResponse: + return AsyncNodesResourceWithRawResponse(self._tenant_structures.nodes) + + +class TenantStructuresResourceWithStreamingResponse: + def __init__(self, tenant_structures: TenantStructuresResource) -> None: + self._tenant_structures = tenant_structures + + self.create = to_streamed_response_wrapper( + tenant_structures.create, + ) + self.update = to_streamed_response_wrapper( + tenant_structures.update, + ) + self.list = to_streamed_response_wrapper( + tenant_structures.list, + ) + self.delete = to_streamed_response_wrapper( + tenant_structures.delete, + ) + self.get = to_streamed_response_wrapper( + tenant_structures.get, + ) + + @cached_property + def nodes(self) -> NodesResourceWithStreamingResponse: + return NodesResourceWithStreamingResponse(self._tenant_structures.nodes) + + +class AsyncTenantStructuresResourceWithStreamingResponse: + def __init__(self, tenant_structures: AsyncTenantStructuresResource) -> None: + self._tenant_structures = tenant_structures + + self.create = async_to_streamed_response_wrapper( + tenant_structures.create, + ) + self.update = async_to_streamed_response_wrapper( + tenant_structures.update, + ) + self.list = async_to_streamed_response_wrapper( + tenant_structures.list, + ) + self.delete = async_to_streamed_response_wrapper( + tenant_structures.delete, + ) + self.get = async_to_streamed_response_wrapper( + tenant_structures.get, + ) + + @cached_property + def nodes(self) -> AsyncNodesResourceWithStreamingResponse: + return AsyncNodesResourceWithStreamingResponse(self._tenant_structures.nodes) diff --git a/src/cloudflare/resources/zero_trust/cws/workloads.py b/src/cloudflare/resources/zero_trust/cws/workloads.py new file mode 100644 index 00000000000..e60bc3e7f09 --- /dev/null +++ b/src/cloudflare/resources/zero_trust/cws/workloads.py @@ -0,0 +1,737 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Dict, Type, cast +from typing_extensions import Literal + +import httpx + +from ...._types import Body, Omit, Query, Headers, NotGiven, omit, not_given +from ...._utils import path_template, maybe_transform, async_maybe_transform +from ...._compat import cached_property +from ...._resource import SyncAPIResource, AsyncAPIResource +from ...._response import ( + to_raw_response_wrapper, + to_streamed_response_wrapper, + async_to_raw_response_wrapper, + async_to_streamed_response_wrapper, +) +from ...._wrappers import ResultWrapper +from ....pagination import SyncCursorPagination, AsyncCursorPagination +from ...._base_client import AsyncPaginator, make_request_options +from ....types.zero_trust.cws import workload_list_params, workload_create_params, workload_update_params +from ....types.zero_trust.cws.workload import Workload +from ....types.zero_trust.cws.workload_delete_response import WorkloadDeleteResponse + +__all__ = ["WorkloadsResource", "AsyncWorkloadsResource"] + + +class WorkloadsResource(SyncAPIResource): + @cached_property + def with_raw_response(self) -> WorkloadsResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers + """ + return WorkloadsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> WorkloadsResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response + """ + return WorkloadsResourceWithStreamingResponse(self) + + def create( + self, + *, + account_id: str, + filter: str, + name: str, + description: str | Omit = omit, + tags: Dict[str, str] | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> Workload: + """ + Creates a reusable workload selector from a filter expression. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + filter: Filter expression selecting the requests this workload matches. Maximum 4096 + UTF-8 bytes. + + name: Human-readable handle; unique per account. + + description: Optional free-form description. + + tags: Tags to attach. Keys are limited to 256 UTF-8 bytes and values to 1024 UTF-8 + bytes. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + return self._post( + path_template("/accounts/{account_id}/cws/workloads", account_id=account_id), + body=maybe_transform( + { + "filter": filter, + "name": name, + "description": description, + "tags": tags, + }, + workload_create_params.WorkloadCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Workload]._unwrapper, + ), + cast_to=cast(Type[Workload], ResultWrapper[Workload]), + ) + + def update( + self, + workload_id: str, + *, + account_id: str, + filter: str, + name: str, + description: str | Omit = omit, + tags: Dict[str, str] | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> Workload: + """Replaces the workload's configuration. + + Omit tags or use {} to clear them. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + workload_id: ID of the workload to update + + filter: Filter expression selecting the requests this workload matches. Maximum 4096 + UTF-8 bytes. + + name: Human-readable handle; unique per account. + + description: Optional free-form description. + + tags: Replacement tag set. Omit or use {} to clear. Keys are limited to 256 UTF-8 + bytes and values to 1024 UTF-8 bytes. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not workload_id: + raise ValueError(f"Expected a non-empty value for `workload_id` but received {workload_id!r}") + return self._put( + path_template( + "/accounts/{account_id}/cws/workloads/{workload_id}", account_id=account_id, workload_id=workload_id + ), + body=maybe_transform( + { + "filter": filter, + "name": name, + "description": description, + "tags": tags, + }, + workload_update_params.WorkloadUpdateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Workload]._unwrapper, + ), + cast_to=cast(Type[Workload], ResultWrapper[Workload]), + ) + + def list( + self, + *, + account_id: str, + cursor: str | Omit = omit, + direction: Literal["asc", "desc"] | Omit = omit, + name: str | Omit = omit, + order: Literal["name", "created_at", "updated_at"] | Omit = omit, + per_page: int | Omit = omit, + policy_set_id: str | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> SyncCursorPagination[Workload]: + """ + Returns a paginated list of workloads in the account. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + cursor: Pagination cursor from previous response + + direction: Sort direction (default: asc) + + name: Filter by workload name (case-insensitive substring match) + + order: Field to order results by (default: created_at) + + per_page: Number of items per page (1-100, default 20) + + policy_set_id: Filter to workloads attached to this policy set + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + return self._get_api_list( + path_template("/accounts/{account_id}/cws/workloads", account_id=account_id), + page=SyncCursorPagination[Workload], + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "cursor": cursor, + "direction": direction, + "name": name, + "order": order, + "per_page": per_page, + "policy_set_id": policy_set_id, + }, + workload_list_params.WorkloadListParams, + ), + ), + model=Workload, + ) + + def delete( + self, + workload_id: str, + *, + account_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> WorkloadDeleteResponse: + """ + Deletes the workload if it is not targeted by a policy set. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + workload_id: ID of the workload to delete + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not workload_id: + raise ValueError(f"Expected a non-empty value for `workload_id` but received {workload_id!r}") + return self._delete( + path_template( + "/accounts/{account_id}/cws/workloads/{workload_id}", account_id=account_id, workload_id=workload_id + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[WorkloadDeleteResponse]._unwrapper, + ), + cast_to=cast(Type[WorkloadDeleteResponse], ResultWrapper[WorkloadDeleteResponse]), + ) + + def get( + self, + workload_id: str, + *, + account_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> Workload: + """ + Returns the workload with the specified ID. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + workload_id: ID of the workload to retrieve + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not workload_id: + raise ValueError(f"Expected a non-empty value for `workload_id` but received {workload_id!r}") + return self._get( + path_template( + "/accounts/{account_id}/cws/workloads/{workload_id}", account_id=account_id, workload_id=workload_id + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Workload]._unwrapper, + ), + cast_to=cast(Type[Workload], ResultWrapper[Workload]), + ) + + +class AsyncWorkloadsResource(AsyncAPIResource): + @cached_property + def with_raw_response(self) -> AsyncWorkloadsResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers + """ + return AsyncWorkloadsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncWorkloadsResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response + """ + return AsyncWorkloadsResourceWithStreamingResponse(self) + + async def create( + self, + *, + account_id: str, + filter: str, + name: str, + description: str | Omit = omit, + tags: Dict[str, str] | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> Workload: + """ + Creates a reusable workload selector from a filter expression. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + filter: Filter expression selecting the requests this workload matches. Maximum 4096 + UTF-8 bytes. + + name: Human-readable handle; unique per account. + + description: Optional free-form description. + + tags: Tags to attach. Keys are limited to 256 UTF-8 bytes and values to 1024 UTF-8 + bytes. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + return await self._post( + path_template("/accounts/{account_id}/cws/workloads", account_id=account_id), + body=await async_maybe_transform( + { + "filter": filter, + "name": name, + "description": description, + "tags": tags, + }, + workload_create_params.WorkloadCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Workload]._unwrapper, + ), + cast_to=cast(Type[Workload], ResultWrapper[Workload]), + ) + + async def update( + self, + workload_id: str, + *, + account_id: str, + filter: str, + name: str, + description: str | Omit = omit, + tags: Dict[str, str] | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> Workload: + """Replaces the workload's configuration. + + Omit tags or use {} to clear them. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + workload_id: ID of the workload to update + + filter: Filter expression selecting the requests this workload matches. Maximum 4096 + UTF-8 bytes. + + name: Human-readable handle; unique per account. + + description: Optional free-form description. + + tags: Replacement tag set. Omit or use {} to clear. Keys are limited to 256 UTF-8 + bytes and values to 1024 UTF-8 bytes. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not workload_id: + raise ValueError(f"Expected a non-empty value for `workload_id` but received {workload_id!r}") + return await self._put( + path_template( + "/accounts/{account_id}/cws/workloads/{workload_id}", account_id=account_id, workload_id=workload_id + ), + body=await async_maybe_transform( + { + "filter": filter, + "name": name, + "description": description, + "tags": tags, + }, + workload_update_params.WorkloadUpdateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Workload]._unwrapper, + ), + cast_to=cast(Type[Workload], ResultWrapper[Workload]), + ) + + def list( + self, + *, + account_id: str, + cursor: str | Omit = omit, + direction: Literal["asc", "desc"] | Omit = omit, + name: str | Omit = omit, + order: Literal["name", "created_at", "updated_at"] | Omit = omit, + per_page: int | Omit = omit, + policy_set_id: str | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> AsyncPaginator[Workload, AsyncCursorPagination[Workload]]: + """ + Returns a paginated list of workloads in the account. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + cursor: Pagination cursor from previous response + + direction: Sort direction (default: asc) + + name: Filter by workload name (case-insensitive substring match) + + order: Field to order results by (default: created_at) + + per_page: Number of items per page (1-100, default 20) + + policy_set_id: Filter to workloads attached to this policy set + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + return self._get_api_list( + path_template("/accounts/{account_id}/cws/workloads", account_id=account_id), + page=AsyncCursorPagination[Workload], + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "cursor": cursor, + "direction": direction, + "name": name, + "order": order, + "per_page": per_page, + "policy_set_id": policy_set_id, + }, + workload_list_params.WorkloadListParams, + ), + ), + model=Workload, + ) + + async def delete( + self, + workload_id: str, + *, + account_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> WorkloadDeleteResponse: + """ + Deletes the workload if it is not targeted by a policy set. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + workload_id: ID of the workload to delete + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not workload_id: + raise ValueError(f"Expected a non-empty value for `workload_id` but received {workload_id!r}") + return await self._delete( + path_template( + "/accounts/{account_id}/cws/workloads/{workload_id}", account_id=account_id, workload_id=workload_id + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[WorkloadDeleteResponse]._unwrapper, + ), + cast_to=cast(Type[WorkloadDeleteResponse], ResultWrapper[WorkloadDeleteResponse]), + ) + + async def get( + self, + workload_id: str, + *, + account_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> Workload: + """ + Returns the workload with the specified ID. + + Args: + account_id: Cloudflare account ID (32-character hexadecimal string) + + workload_id: ID of the workload to retrieve + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not workload_id: + raise ValueError(f"Expected a non-empty value for `workload_id` but received {workload_id!r}") + return await self._get( + path_template( + "/accounts/{account_id}/cws/workloads/{workload_id}", account_id=account_id, workload_id=workload_id + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Workload]._unwrapper, + ), + cast_to=cast(Type[Workload], ResultWrapper[Workload]), + ) + + +class WorkloadsResourceWithRawResponse: + def __init__(self, workloads: WorkloadsResource) -> None: + self._workloads = workloads + + self.create = to_raw_response_wrapper( + workloads.create, + ) + self.update = to_raw_response_wrapper( + workloads.update, + ) + self.list = to_raw_response_wrapper( + workloads.list, + ) + self.delete = to_raw_response_wrapper( + workloads.delete, + ) + self.get = to_raw_response_wrapper( + workloads.get, + ) + + +class AsyncWorkloadsResourceWithRawResponse: + def __init__(self, workloads: AsyncWorkloadsResource) -> None: + self._workloads = workloads + + self.create = async_to_raw_response_wrapper( + workloads.create, + ) + self.update = async_to_raw_response_wrapper( + workloads.update, + ) + self.list = async_to_raw_response_wrapper( + workloads.list, + ) + self.delete = async_to_raw_response_wrapper( + workloads.delete, + ) + self.get = async_to_raw_response_wrapper( + workloads.get, + ) + + +class WorkloadsResourceWithStreamingResponse: + def __init__(self, workloads: WorkloadsResource) -> None: + self._workloads = workloads + + self.create = to_streamed_response_wrapper( + workloads.create, + ) + self.update = to_streamed_response_wrapper( + workloads.update, + ) + self.list = to_streamed_response_wrapper( + workloads.list, + ) + self.delete = to_streamed_response_wrapper( + workloads.delete, + ) + self.get = to_streamed_response_wrapper( + workloads.get, + ) + + +class AsyncWorkloadsResourceWithStreamingResponse: + def __init__(self, workloads: AsyncWorkloadsResource) -> None: + self._workloads = workloads + + self.create = async_to_streamed_response_wrapper( + workloads.create, + ) + self.update = async_to_streamed_response_wrapper( + workloads.update, + ) + self.list = async_to_streamed_response_wrapper( + workloads.list, + ) + self.delete = async_to_streamed_response_wrapper( + workloads.delete, + ) + self.get = async_to_streamed_response_wrapper( + workloads.get, + ) diff --git a/src/cloudflare/resources/zero_trust/devices/policies/custom/custom.py b/src/cloudflare/resources/zero_trust/devices/policies/custom/custom.py index 55b1b254fdf..c5cf199ad36 100644 --- a/src/cloudflare/resources/zero_trust/devices/policies/custom/custom.py +++ b/src/cloudflare/resources/zero_trust/devices/policies/custom/custom.py @@ -99,6 +99,7 @@ def create( description: str | Omit = omit, disable_auto_fallback: bool | Omit = omit, dns_search_suffixes: Iterable[custom_create_params.DNSSearchSuffix] | Omit = omit, + enable_device_credential_authentication: bool | Omit = omit, enabled: bool | Omit = omit, exclude: Iterable[SplitTunnelExcludeParam] | Omit = omit, exclude_office_ips: bool | Omit = omit, @@ -157,6 +158,10 @@ def create( dns_search_suffixes: List of DNS search suffixes to apply to clients. Suffixes are evaluated in order. Use an empty array to clear. + enable_device_credential_authentication: Determines whether the WARP client can silently reauthenticate the user with + device credentials (Microsoft Entra) instead of prompting for browser-based + reauthentication. + enabled: Whether the policy will be applied to matching devices. exclude: List of routes excluded in the WARP client's tunnel. Both 'exclude' and @@ -183,7 +188,7 @@ def create( match: The wirefilter expression to match devices. Available values: "identity.email", "identity.groups.id", "identity.groups.name", "identity.groups.email", "identity.service_token_uuid", "identity.saml_attributes", "network", "os.name", - "os.version". + "os.version", "device.tags". precedence: The precedence of the policy. Lower values indicate higher precedence. Policies will be evaluated in ascending order of this field. @@ -233,6 +238,7 @@ def create( "description": description, "disable_auto_fallback": disable_auto_fallback, "dns_search_suffixes": dns_search_suffixes, + "enable_device_credential_authentication": enable_device_credential_authentication, "enabled": enabled, "exclude": exclude, "exclude_office_ips": exclude_office_ips, @@ -361,6 +367,7 @@ def edit( description: str | Omit = omit, disable_auto_fallback: bool | Omit = omit, dns_search_suffixes: Iterable[custom_edit_params.DNSSearchSuffix] | Omit = omit, + enable_device_credential_authentication: bool | Omit = omit, enabled: bool | Omit = omit, exclude: Iterable[SplitTunnelExcludeParam] | Omit = omit, exclude_office_ips: bool | Omit = omit, @@ -416,6 +423,10 @@ def edit( dns_search_suffixes: List of DNS search suffixes to apply to clients. Suffixes are evaluated in order. Use an empty array to clear. + enable_device_credential_authentication: Determines whether the WARP client can silently reauthenticate the user with + device credentials (Microsoft Entra) instead of prompting for browser-based + reauthentication. + enabled: Whether the policy will be applied to matching devices. exclude: List of routes excluded in the WARP client's tunnel. Both 'exclude' and @@ -442,7 +453,7 @@ def edit( match: The wirefilter expression to match devices. Available values: "identity.email", "identity.groups.id", "identity.groups.name", "identity.groups.email", "identity.service_token_uuid", "identity.saml_attributes", "network", "os.name", - "os.version". + "os.version", "device.tags". name: The name of the device settings profile. @@ -494,6 +505,7 @@ def edit( "description": description, "disable_auto_fallback": disable_auto_fallback, "dns_search_suffixes": dns_search_suffixes, + "enable_device_credential_authentication": enable_device_credential_authentication, "enabled": enabled, "exclude": exclude, "exclude_office_ips": exclude_office_ips, @@ -615,6 +627,7 @@ async def create( description: str | Omit = omit, disable_auto_fallback: bool | Omit = omit, dns_search_suffixes: Iterable[custom_create_params.DNSSearchSuffix] | Omit = omit, + enable_device_credential_authentication: bool | Omit = omit, enabled: bool | Omit = omit, exclude: Iterable[SplitTunnelExcludeParam] | Omit = omit, exclude_office_ips: bool | Omit = omit, @@ -673,6 +686,10 @@ async def create( dns_search_suffixes: List of DNS search suffixes to apply to clients. Suffixes are evaluated in order. Use an empty array to clear. + enable_device_credential_authentication: Determines whether the WARP client can silently reauthenticate the user with + device credentials (Microsoft Entra) instead of prompting for browser-based + reauthentication. + enabled: Whether the policy will be applied to matching devices. exclude: List of routes excluded in the WARP client's tunnel. Both 'exclude' and @@ -699,7 +716,7 @@ async def create( match: The wirefilter expression to match devices. Available values: "identity.email", "identity.groups.id", "identity.groups.name", "identity.groups.email", "identity.service_token_uuid", "identity.saml_attributes", "network", "os.name", - "os.version". + "os.version", "device.tags". precedence: The precedence of the policy. Lower values indicate higher precedence. Policies will be evaluated in ascending order of this field. @@ -749,6 +766,7 @@ async def create( "description": description, "disable_auto_fallback": disable_auto_fallback, "dns_search_suffixes": dns_search_suffixes, + "enable_device_credential_authentication": enable_device_credential_authentication, "enabled": enabled, "exclude": exclude, "exclude_office_ips": exclude_office_ips, @@ -877,6 +895,7 @@ async def edit( description: str | Omit = omit, disable_auto_fallback: bool | Omit = omit, dns_search_suffixes: Iterable[custom_edit_params.DNSSearchSuffix] | Omit = omit, + enable_device_credential_authentication: bool | Omit = omit, enabled: bool | Omit = omit, exclude: Iterable[SplitTunnelExcludeParam] | Omit = omit, exclude_office_ips: bool | Omit = omit, @@ -932,6 +951,10 @@ async def edit( dns_search_suffixes: List of DNS search suffixes to apply to clients. Suffixes are evaluated in order. Use an empty array to clear. + enable_device_credential_authentication: Determines whether the WARP client can silently reauthenticate the user with + device credentials (Microsoft Entra) instead of prompting for browser-based + reauthentication. + enabled: Whether the policy will be applied to matching devices. exclude: List of routes excluded in the WARP client's tunnel. Both 'exclude' and @@ -958,7 +981,7 @@ async def edit( match: The wirefilter expression to match devices. Available values: "identity.email", "identity.groups.id", "identity.groups.name", "identity.groups.email", "identity.service_token_uuid", "identity.saml_attributes", "network", "os.name", - "os.version". + "os.version", "device.tags". name: The name of the device settings profile. @@ -1010,6 +1033,7 @@ async def edit( "description": description, "disable_auto_fallback": disable_auto_fallback, "dns_search_suffixes": dns_search_suffixes, + "enable_device_credential_authentication": enable_device_credential_authentication, "enabled": enabled, "exclude": exclude, "exclude_office_ips": exclude_office_ips, diff --git a/src/cloudflare/resources/zero_trust/devices/policies/default/default.py b/src/cloudflare/resources/zero_trust/devices/policies/default/default.py index 54325efe276..d1f180d01d0 100644 --- a/src/cloudflare/resources/zero_trust/devices/policies/default/default.py +++ b/src/cloudflare/resources/zero_trust/devices/policies/default/default.py @@ -106,6 +106,7 @@ def edit( captive_portal: float | Omit = omit, disable_auto_fallback: bool | Omit = omit, dns_search_suffixes: Iterable[default_edit_params.DNSSearchSuffix] | Omit = omit, + enable_device_credential_authentication: bool | Omit = omit, exclude: Iterable[SplitTunnelExcludeParam] | Omit = omit, exclude_office_ips: bool | Omit = omit, global_acceleration: Optional[default_edit_params.GlobalAcceleration] | Omit = omit, @@ -149,6 +150,10 @@ def edit( dns_search_suffixes: List of DNS search suffixes to apply to clients. Suffixes are evaluated in order. Use an empty array to clear. + enable_device_credential_authentication: Determines whether the WARP client can silently reauthenticate the user with + device credentials (Microsoft Entra) instead of prompting for browser-based + reauthentication. + exclude: List of routes excluded in the WARP client's tunnel. Both 'exclude' and 'include' cannot be set in the same request. @@ -208,6 +213,7 @@ def edit( "captive_portal": captive_portal, "disable_auto_fallback": disable_auto_fallback, "dns_search_suffixes": dns_search_suffixes, + "enable_device_credential_authentication": enable_device_credential_authentication, "exclude": exclude, "exclude_office_ips": exclude_office_ips, "global_acceleration": global_acceleration, @@ -320,6 +326,7 @@ async def edit( captive_portal: float | Omit = omit, disable_auto_fallback: bool | Omit = omit, dns_search_suffixes: Iterable[default_edit_params.DNSSearchSuffix] | Omit = omit, + enable_device_credential_authentication: bool | Omit = omit, exclude: Iterable[SplitTunnelExcludeParam] | Omit = omit, exclude_office_ips: bool | Omit = omit, global_acceleration: Optional[default_edit_params.GlobalAcceleration] | Omit = omit, @@ -363,6 +370,10 @@ async def edit( dns_search_suffixes: List of DNS search suffixes to apply to clients. Suffixes are evaluated in order. Use an empty array to clear. + enable_device_credential_authentication: Determines whether the WARP client can silently reauthenticate the user with + device credentials (Microsoft Entra) instead of prompting for browser-based + reauthentication. + exclude: List of routes excluded in the WARP client's tunnel. Both 'exclude' and 'include' cannot be set in the same request. @@ -422,6 +433,7 @@ async def edit( "captive_portal": captive_portal, "disable_auto_fallback": disable_auto_fallback, "dns_search_suffixes": dns_search_suffixes, + "enable_device_credential_authentication": enable_device_credential_authentication, "exclude": exclude, "exclude_office_ips": exclude_office_ips, "global_acceleration": global_acceleration, diff --git a/src/cloudflare/resources/zero_trust/dlp/__init__.py b/src/cloudflare/resources/zero_trust/dlp/__init__.py index 480c8c50ccd..b876ec1b29a 100644 --- a/src/cloudflare/resources/zero_trust/dlp/__init__.py +++ b/src/cloudflare/resources/zero_trust/dlp/__init__.py @@ -64,6 +64,14 @@ SettingsResourceWithStreamingResponse, AsyncSettingsResourceWithStreamingResponse, ) +from .validators import ( + ValidatorsResource, + AsyncValidatorsResource, + ValidatorsResourceWithRawResponse, + AsyncValidatorsResourceWithRawResponse, + ValidatorsResourceWithStreamingResponse, + AsyncValidatorsResourceWithStreamingResponse, +) from .data_classes import ( DataClassesResource, AsyncDataClassesResource, @@ -160,6 +168,12 @@ "AsyncEntriesResourceWithRawResponse", "EntriesResourceWithStreamingResponse", "AsyncEntriesResourceWithStreamingResponse", + "ValidatorsResource", + "AsyncValidatorsResource", + "ValidatorsResourceWithRawResponse", + "AsyncValidatorsResourceWithRawResponse", + "ValidatorsResourceWithStreamingResponse", + "AsyncValidatorsResourceWithStreamingResponse", "SensitivityGroupsResource", "AsyncSensitivityGroupsResource", "SensitivityGroupsResourceWithRawResponse", diff --git a/src/cloudflare/resources/zero_trust/dlp/dlp.py b/src/cloudflare/resources/zero_trust/dlp/dlp.py index 06cc451c89b..cef343a29c7 100644 --- a/src/cloudflare/resources/zero_trust/dlp/dlp.py +++ b/src/cloudflare/resources/zero_trust/dlp/dlp.py @@ -84,6 +84,14 @@ CustomPromptTopicsResourceWithStreamingResponse, AsyncCustomPromptTopicsResourceWithStreamingResponse, ) +from .validators.validators import ( + ValidatorsResource, + AsyncValidatorsResource, + ValidatorsResourceWithRawResponse, + AsyncValidatorsResourceWithRawResponse, + ValidatorsResourceWithStreamingResponse, + AsyncValidatorsResourceWithStreamingResponse, +) from .sensitivity_groups.sensitivity_groups import ( SensitivityGroupsResource, AsyncSensitivityGroupsResource, @@ -141,6 +149,10 @@ def limits(self) -> LimitsResource: def entries(self) -> EntriesResource: return EntriesResource(self._client) + @cached_property + def validators(self) -> ValidatorsResource: + return ValidatorsResource(self._client) + @cached_property def sensitivity_groups(self) -> SensitivityGroupsResource: return SensitivityGroupsResource(self._client) @@ -210,6 +222,10 @@ def limits(self) -> AsyncLimitsResource: def entries(self) -> AsyncEntriesResource: return AsyncEntriesResource(self._client) + @cached_property + def validators(self) -> AsyncValidatorsResource: + return AsyncValidatorsResource(self._client) + @cached_property def sensitivity_groups(self) -> AsyncSensitivityGroupsResource: return AsyncSensitivityGroupsResource(self._client) @@ -282,6 +298,10 @@ def limits(self) -> LimitsResourceWithRawResponse: def entries(self) -> EntriesResourceWithRawResponse: return EntriesResourceWithRawResponse(self._dlp.entries) + @cached_property + def validators(self) -> ValidatorsResourceWithRawResponse: + return ValidatorsResourceWithRawResponse(self._dlp.validators) + @cached_property def sensitivity_groups(self) -> SensitivityGroupsResourceWithRawResponse: return SensitivityGroupsResourceWithRawResponse(self._dlp.sensitivity_groups) @@ -335,6 +355,10 @@ def limits(self) -> AsyncLimitsResourceWithRawResponse: def entries(self) -> AsyncEntriesResourceWithRawResponse: return AsyncEntriesResourceWithRawResponse(self._dlp.entries) + @cached_property + def validators(self) -> AsyncValidatorsResourceWithRawResponse: + return AsyncValidatorsResourceWithRawResponse(self._dlp.validators) + @cached_property def sensitivity_groups(self) -> AsyncSensitivityGroupsResourceWithRawResponse: return AsyncSensitivityGroupsResourceWithRawResponse(self._dlp.sensitivity_groups) @@ -388,6 +412,10 @@ def limits(self) -> LimitsResourceWithStreamingResponse: def entries(self) -> EntriesResourceWithStreamingResponse: return EntriesResourceWithStreamingResponse(self._dlp.entries) + @cached_property + def validators(self) -> ValidatorsResourceWithStreamingResponse: + return ValidatorsResourceWithStreamingResponse(self._dlp.validators) + @cached_property def sensitivity_groups(self) -> SensitivityGroupsResourceWithStreamingResponse: return SensitivityGroupsResourceWithStreamingResponse(self._dlp.sensitivity_groups) @@ -441,6 +469,10 @@ def limits(self) -> AsyncLimitsResourceWithStreamingResponse: def entries(self) -> AsyncEntriesResourceWithStreamingResponse: return AsyncEntriesResourceWithStreamingResponse(self._dlp.entries) + @cached_property + def validators(self) -> AsyncValidatorsResourceWithStreamingResponse: + return AsyncValidatorsResourceWithStreamingResponse(self._dlp.validators) + @cached_property def sensitivity_groups(self) -> AsyncSensitivityGroupsResourceWithStreamingResponse: return AsyncSensitivityGroupsResourceWithStreamingResponse(self._dlp.sensitivity_groups) diff --git a/src/cloudflare/resources/zero_trust/dlp/entries/custom.py b/src/cloudflare/resources/zero_trust/dlp/entries/custom.py index 301ffac8f67..03d4e858dbe 100644 --- a/src/cloudflare/resources/zero_trust/dlp/entries/custom.py +++ b/src/cloudflare/resources/zero_trust/dlp/entries/custom.py @@ -6,7 +6,7 @@ import httpx -from ....._types import Body, Omit, Query, Headers, NotGiven, omit, not_given +from ....._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given from ....._utils import path_template, maybe_transform, async_maybe_transform from ....._compat import cached_property from ....._resource import SyncAPIResource, AsyncAPIResource @@ -58,6 +58,7 @@ def create( pattern: PatternParam, description: Optional[str] | Omit = omit, profile_id: str | Omit = omit, + validator_ids: SequenceNotStr[str] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -69,6 +70,8 @@ def create( Creates a DLP custom entry. Args: + validator_ids: Validators the new entry should reference, by id, at most 10. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -88,6 +91,7 @@ def create( "pattern": pattern, "description": description, "profile_id": profile_id, + "validator_ids": validator_ids, }, custom_create_params.CustomCreateParams, ), @@ -110,6 +114,7 @@ def update( name: str, pattern: PatternParam, description: Optional[str] | Omit = omit, + validator_ids: SequenceNotStr[str] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -121,6 +126,13 @@ def update( Updates a DLP custom entry. Args: + validator_ids: Validators this entry should reference, by id, at most 10. Replaces the current + set. + + Optional, unlike the rest of this body: omitting it leaves the current + attachments alone, so a client that predates validators cannot detach them by + accident. Send `[]` to detach. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -143,6 +155,7 @@ def update( "name": name, "pattern": pattern, "description": description, + "validator_ids": validator_ids, }, custom_update_params.CustomUpdateParams, ), @@ -307,6 +320,7 @@ async def create( pattern: PatternParam, description: Optional[str] | Omit = omit, profile_id: str | Omit = omit, + validator_ids: SequenceNotStr[str] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -318,6 +332,8 @@ async def create( Creates a DLP custom entry. Args: + validator_ids: Validators the new entry should reference, by id, at most 10. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -337,6 +353,7 @@ async def create( "pattern": pattern, "description": description, "profile_id": profile_id, + "validator_ids": validator_ids, }, custom_create_params.CustomCreateParams, ), @@ -359,6 +376,7 @@ async def update( name: str, pattern: PatternParam, description: Optional[str] | Omit = omit, + validator_ids: SequenceNotStr[str] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -370,6 +388,13 @@ async def update( Updates a DLP custom entry. Args: + validator_ids: Validators this entry should reference, by id, at most 10. Replaces the current + set. + + Optional, unlike the rest of this body: omitting it leaves the current + attachments alone, so a client that predates validators cannot detach them by + accident. Send `[]` to detach. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -392,6 +417,7 @@ async def update( "name": name, "pattern": pattern, "description": description, + "validator_ids": validator_ids, }, custom_update_params.CustomUpdateParams, ), diff --git a/src/cloudflare/resources/zero_trust/dlp/entries/entries.py b/src/cloudflare/resources/zero_trust/dlp/entries/entries.py index 2ad42170335..3b369980ad2 100644 --- a/src/cloudflare/resources/zero_trust/dlp/entries/entries.py +++ b/src/cloudflare/resources/zero_trust/dlp/entries/entries.py @@ -15,7 +15,7 @@ CustomResourceWithStreamingResponse, AsyncCustomResourceWithStreamingResponse, ) -from ....._types import Body, Omit, Query, Headers, NotGiven, omit, not_given +from ....._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given from ....._utils import path_template, required_args, maybe_transform, async_maybe_transform from .predefined import ( PredefinedResource, @@ -95,6 +95,7 @@ def create( pattern: PatternParam, description: Optional[str] | Omit = omit, profile_id: str | Omit = omit, + validator_ids: SequenceNotStr[str] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -106,6 +107,8 @@ def create( Creates a DLP custom entry. Args: + validator_ids: Validators the new entry should reference, by id, at most 10. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -125,6 +128,7 @@ def create( "pattern": pattern, "description": description, "profile_id": profile_id, + "validator_ids": validator_ids, }, entry_create_params.EntryCreateParams, ), @@ -149,6 +153,7 @@ def update( type: Literal["custom"], description: Optional[str] | Omit = omit, enabled: bool | Omit = omit, + validator_ids: SequenceNotStr[str] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -160,6 +165,13 @@ def update( Updates a DLP entry. Args: + validator_ids: Validators this entry should reference, by id, at most 10. Replaces the current + set. + + Optional, unlike the rest of this body: omitting it leaves the current + attachments alone, so a client that predates validators cannot detach them by + accident. Send `[]` to detach. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -239,6 +251,7 @@ def update( type: Literal["custom"] | Literal["predefined"] | Literal["integration"], description: Optional[str] | Omit = omit, enabled: bool | Omit = omit, + validator_ids: SequenceNotStr[str] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -263,6 +276,7 @@ def update( "type": type, "description": description, "enabled": enabled, + "validator_ids": validator_ids, }, entry_update_params.EntryUpdateParams, ), @@ -442,6 +456,7 @@ async def create( pattern: PatternParam, description: Optional[str] | Omit = omit, profile_id: str | Omit = omit, + validator_ids: SequenceNotStr[str] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -453,6 +468,8 @@ async def create( Creates a DLP custom entry. Args: + validator_ids: Validators the new entry should reference, by id, at most 10. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -472,6 +489,7 @@ async def create( "pattern": pattern, "description": description, "profile_id": profile_id, + "validator_ids": validator_ids, }, entry_create_params.EntryCreateParams, ), @@ -496,6 +514,7 @@ async def update( type: Literal["custom"], description: Optional[str] | Omit = omit, enabled: bool | Omit = omit, + validator_ids: SequenceNotStr[str] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -507,6 +526,13 @@ async def update( Updates a DLP entry. Args: + validator_ids: Validators this entry should reference, by id, at most 10. Replaces the current + set. + + Optional, unlike the rest of this body: omitting it leaves the current + attachments alone, so a client that predates validators cannot detach them by + accident. Send `[]` to detach. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -586,6 +612,7 @@ async def update( type: Literal["custom"] | Literal["predefined"] | Literal["integration"], description: Optional[str] | Omit = omit, enabled: bool | Omit = omit, + validator_ids: SequenceNotStr[str] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -610,6 +637,7 @@ async def update( "type": type, "description": description, "enabled": enabled, + "validator_ids": validator_ids, }, entry_update_params.EntryUpdateParams, ), diff --git a/src/cloudflare/resources/zero_trust/dlp/validators/__init__.py b/src/cloudflare/resources/zero_trust/dlp/validators/__init__.py new file mode 100644 index 00000000000..20ca4286151 --- /dev/null +++ b/src/cloudflare/resources/zero_trust/dlp/validators/__init__.py @@ -0,0 +1,33 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from .validators import ( + ValidatorsResource, + AsyncValidatorsResource, + ValidatorsResourceWithRawResponse, + AsyncValidatorsResourceWithRawResponse, + ValidatorsResourceWithStreamingResponse, + AsyncValidatorsResourceWithStreamingResponse, +) +from .proximity_words import ( + ProximityWordsResource, + AsyncProximityWordsResource, + ProximityWordsResourceWithRawResponse, + AsyncProximityWordsResourceWithRawResponse, + ProximityWordsResourceWithStreamingResponse, + AsyncProximityWordsResourceWithStreamingResponse, +) + +__all__ = [ + "ProximityWordsResource", + "AsyncProximityWordsResource", + "ProximityWordsResourceWithRawResponse", + "AsyncProximityWordsResourceWithRawResponse", + "ProximityWordsResourceWithStreamingResponse", + "AsyncProximityWordsResourceWithStreamingResponse", + "ValidatorsResource", + "AsyncValidatorsResource", + "ValidatorsResourceWithRawResponse", + "AsyncValidatorsResourceWithRawResponse", + "ValidatorsResourceWithStreamingResponse", + "AsyncValidatorsResourceWithStreamingResponse", +] diff --git a/src/cloudflare/resources/zero_trust/dlp/validators/proximity_words.py b/src/cloudflare/resources/zero_trust/dlp/validators/proximity_words.py new file mode 100644 index 00000000000..a05661f35a1 --- /dev/null +++ b/src/cloudflare/resources/zero_trust/dlp/validators/proximity_words.py @@ -0,0 +1,642 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Type, Iterable, Optional, cast + +import httpx + +from ....._types import Body, Query, Headers, NotGiven, not_given +from ....._utils import path_template, maybe_transform, async_maybe_transform +from ....._compat import cached_property +from ....._resource import SyncAPIResource, AsyncAPIResource +from ....._response import ( + to_raw_response_wrapper, + to_streamed_response_wrapper, + async_to_raw_response_wrapper, + async_to_streamed_response_wrapper, +) +from ....._wrappers import ResultWrapper +from .....pagination import SyncSinglePage, AsyncSinglePage +from ....._base_client import AsyncPaginator, make_request_options +from .....types.zero_trust.dlp.validators import proximity_word_create_params, proximity_word_update_params +from .....types.zero_trust.dlp.validators.word_param import WordParam +from .....types.zero_trust.dlp.validators.proximity_word_validator import ProximityWordValidator + +__all__ = ["ProximityWordsResource", "AsyncProximityWordsResource"] + + +class ProximityWordsResource(SyncAPIResource): + @cached_property + def with_raw_response(self) -> ProximityWordsResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers + """ + return ProximityWordsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> ProximityWordsResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response + """ + return ProximityWordsResourceWithStreamingResponse(self) + + def create( + self, + *, + account_id: str, + name: str, + words: Iterable[WordParam], + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> Optional[ProximityWordValidator]: + """ + Creates a reusable list of weighted words that detection entries can attach to + in order to refine their matches. An account may own at most 100 validators + across all kinds. + + Args: + name: A name for this validator, at most 50 characters. + + words: The words that raise confidence when found near a match, at most 100 per + validator. Matching ignores case, so the list may not contain the same word + twice with different capitalisation. Words are stored as sent. + + For example, a validator for medical record numbers might use + `[{"word": "patient", "weight": "strong"}, {"word": "diagnosis", "weight": "moderate"}, {"word": "mrn", "weight": "weak"}]`. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + return self._post( + path_template("/accounts/{account_id}/dlp/validators/proximity_words", account_id=account_id), + body=maybe_transform( + { + "name": name, + "words": words, + }, + proximity_word_create_params.ProximityWordCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Optional[ProximityWordValidator]]._unwrapper, + ), + cast_to=cast(Type[Optional[ProximityWordValidator]], ResultWrapper[ProximityWordValidator]), + ) + + def update( + self, + validator_id: str, + *, + account_id: str, + name: str, + words: Iterable[WordParam], + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> Optional[ProximityWordValidator]: + """Replaces the name and word list of a `proximity_words` validator. + + Attachments to + detection entries are owned from the entry side and are not affected. + + Args: + name: A name for this validator, at most 50 characters. + + words: The words that raise confidence when found near a match, at most 100 per + validator. Matching ignores case, so the list may not contain the same word + twice with different capitalisation. Words are stored as sent. + + For example, a validator for medical record numbers might use + `[{"word": "patient", "weight": "strong"}, {"word": "diagnosis", "weight": "moderate"}, {"word": "mrn", "weight": "weak"}]`. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not validator_id: + raise ValueError(f"Expected a non-empty value for `validator_id` but received {validator_id!r}") + return self._put( + path_template( + "/accounts/{account_id}/dlp/validators/proximity_words/{validator_id}", + account_id=account_id, + validator_id=validator_id, + ), + body=maybe_transform( + { + "name": name, + "words": words, + }, + proximity_word_update_params.ProximityWordUpdateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Optional[ProximityWordValidator]]._unwrapper, + ), + cast_to=cast(Type[Optional[ProximityWordValidator]], ResultWrapper[ProximityWordValidator]), + ) + + def list( + self, + *, + account_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> SyncSinglePage[ProximityWordValidator]: + """ + Lists the `proximity_words` validators configured for the account. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + return self._get_api_list( + path_template("/accounts/{account_id}/dlp/validators/proximity_words", account_id=account_id), + page=SyncSinglePage[ProximityWordValidator], + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + model=ProximityWordValidator, + ) + + def delete( + self, + validator_id: str, + *, + account_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> object: + """Deletes a `proximity_words` validator. + + Fails with `409` while any detection + entry is still attached to it; detach it from those entries first. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not validator_id: + raise ValueError(f"Expected a non-empty value for `validator_id` but received {validator_id!r}") + return self._delete( + path_template( + "/accounts/{account_id}/dlp/validators/proximity_words/{validator_id}", + account_id=account_id, + validator_id=validator_id, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Optional[object]]._unwrapper, + ), + cast_to=cast(Type[object], ResultWrapper[object]), + ) + + def get( + self, + validator_id: str, + *, + account_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> Optional[ProximityWordValidator]: + """ + Fetches a `proximity_words` validator by ID. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not validator_id: + raise ValueError(f"Expected a non-empty value for `validator_id` but received {validator_id!r}") + return self._get( + path_template( + "/accounts/{account_id}/dlp/validators/proximity_words/{validator_id}", + account_id=account_id, + validator_id=validator_id, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Optional[ProximityWordValidator]]._unwrapper, + ), + cast_to=cast(Type[Optional[ProximityWordValidator]], ResultWrapper[ProximityWordValidator]), + ) + + +class AsyncProximityWordsResource(AsyncAPIResource): + @cached_property + def with_raw_response(self) -> AsyncProximityWordsResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers + """ + return AsyncProximityWordsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncProximityWordsResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response + """ + return AsyncProximityWordsResourceWithStreamingResponse(self) + + async def create( + self, + *, + account_id: str, + name: str, + words: Iterable[WordParam], + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> Optional[ProximityWordValidator]: + """ + Creates a reusable list of weighted words that detection entries can attach to + in order to refine their matches. An account may own at most 100 validators + across all kinds. + + Args: + name: A name for this validator, at most 50 characters. + + words: The words that raise confidence when found near a match, at most 100 per + validator. Matching ignores case, so the list may not contain the same word + twice with different capitalisation. Words are stored as sent. + + For example, a validator for medical record numbers might use + `[{"word": "patient", "weight": "strong"}, {"word": "diagnosis", "weight": "moderate"}, {"word": "mrn", "weight": "weak"}]`. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + return await self._post( + path_template("/accounts/{account_id}/dlp/validators/proximity_words", account_id=account_id), + body=await async_maybe_transform( + { + "name": name, + "words": words, + }, + proximity_word_create_params.ProximityWordCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Optional[ProximityWordValidator]]._unwrapper, + ), + cast_to=cast(Type[Optional[ProximityWordValidator]], ResultWrapper[ProximityWordValidator]), + ) + + async def update( + self, + validator_id: str, + *, + account_id: str, + name: str, + words: Iterable[WordParam], + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> Optional[ProximityWordValidator]: + """Replaces the name and word list of a `proximity_words` validator. + + Attachments to + detection entries are owned from the entry side and are not affected. + + Args: + name: A name for this validator, at most 50 characters. + + words: The words that raise confidence when found near a match, at most 100 per + validator. Matching ignores case, so the list may not contain the same word + twice with different capitalisation. Words are stored as sent. + + For example, a validator for medical record numbers might use + `[{"word": "patient", "weight": "strong"}, {"word": "diagnosis", "weight": "moderate"}, {"word": "mrn", "weight": "weak"}]`. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not validator_id: + raise ValueError(f"Expected a non-empty value for `validator_id` but received {validator_id!r}") + return await self._put( + path_template( + "/accounts/{account_id}/dlp/validators/proximity_words/{validator_id}", + account_id=account_id, + validator_id=validator_id, + ), + body=await async_maybe_transform( + { + "name": name, + "words": words, + }, + proximity_word_update_params.ProximityWordUpdateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Optional[ProximityWordValidator]]._unwrapper, + ), + cast_to=cast(Type[Optional[ProximityWordValidator]], ResultWrapper[ProximityWordValidator]), + ) + + def list( + self, + *, + account_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> AsyncPaginator[ProximityWordValidator, AsyncSinglePage[ProximityWordValidator]]: + """ + Lists the `proximity_words` validators configured for the account. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + return self._get_api_list( + path_template("/accounts/{account_id}/dlp/validators/proximity_words", account_id=account_id), + page=AsyncSinglePage[ProximityWordValidator], + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + model=ProximityWordValidator, + ) + + async def delete( + self, + validator_id: str, + *, + account_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> object: + """Deletes a `proximity_words` validator. + + Fails with `409` while any detection + entry is still attached to it; detach it from those entries first. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not validator_id: + raise ValueError(f"Expected a non-empty value for `validator_id` but received {validator_id!r}") + return await self._delete( + path_template( + "/accounts/{account_id}/dlp/validators/proximity_words/{validator_id}", + account_id=account_id, + validator_id=validator_id, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Optional[object]]._unwrapper, + ), + cast_to=cast(Type[object], ResultWrapper[object]), + ) + + async def get( + self, + validator_id: str, + *, + account_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> Optional[ProximityWordValidator]: + """ + Fetches a `proximity_words` validator by ID. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not validator_id: + raise ValueError(f"Expected a non-empty value for `validator_id` but received {validator_id!r}") + return await self._get( + path_template( + "/accounts/{account_id}/dlp/validators/proximity_words/{validator_id}", + account_id=account_id, + validator_id=validator_id, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Optional[ProximityWordValidator]]._unwrapper, + ), + cast_to=cast(Type[Optional[ProximityWordValidator]], ResultWrapper[ProximityWordValidator]), + ) + + +class ProximityWordsResourceWithRawResponse: + def __init__(self, proximity_words: ProximityWordsResource) -> None: + self._proximity_words = proximity_words + + self.create = to_raw_response_wrapper( + proximity_words.create, + ) + self.update = to_raw_response_wrapper( + proximity_words.update, + ) + self.list = to_raw_response_wrapper( + proximity_words.list, + ) + self.delete = to_raw_response_wrapper( + proximity_words.delete, + ) + self.get = to_raw_response_wrapper( + proximity_words.get, + ) + + +class AsyncProximityWordsResourceWithRawResponse: + def __init__(self, proximity_words: AsyncProximityWordsResource) -> None: + self._proximity_words = proximity_words + + self.create = async_to_raw_response_wrapper( + proximity_words.create, + ) + self.update = async_to_raw_response_wrapper( + proximity_words.update, + ) + self.list = async_to_raw_response_wrapper( + proximity_words.list, + ) + self.delete = async_to_raw_response_wrapper( + proximity_words.delete, + ) + self.get = async_to_raw_response_wrapper( + proximity_words.get, + ) + + +class ProximityWordsResourceWithStreamingResponse: + def __init__(self, proximity_words: ProximityWordsResource) -> None: + self._proximity_words = proximity_words + + self.create = to_streamed_response_wrapper( + proximity_words.create, + ) + self.update = to_streamed_response_wrapper( + proximity_words.update, + ) + self.list = to_streamed_response_wrapper( + proximity_words.list, + ) + self.delete = to_streamed_response_wrapper( + proximity_words.delete, + ) + self.get = to_streamed_response_wrapper( + proximity_words.get, + ) + + +class AsyncProximityWordsResourceWithStreamingResponse: + def __init__(self, proximity_words: AsyncProximityWordsResource) -> None: + self._proximity_words = proximity_words + + self.create = async_to_streamed_response_wrapper( + proximity_words.create, + ) + self.update = async_to_streamed_response_wrapper( + proximity_words.update, + ) + self.list = async_to_streamed_response_wrapper( + proximity_words.list, + ) + self.delete = async_to_streamed_response_wrapper( + proximity_words.delete, + ) + self.get = async_to_streamed_response_wrapper( + proximity_words.get, + ) diff --git a/src/cloudflare/resources/zero_trust/dlp/validators/validators.py b/src/cloudflare/resources/zero_trust/dlp/validators/validators.py new file mode 100644 index 00000000000..5818392659f --- /dev/null +++ b/src/cloudflare/resources/zero_trust/dlp/validators/validators.py @@ -0,0 +1,328 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Any, Optional, cast +from typing_extensions import Literal + +import httpx + +from ....._types import Body, Omit, Query, Headers, NotGiven, omit, not_given +from ....._utils import path_template, maybe_transform +from ....._compat import cached_property +from ....._resource import SyncAPIResource, AsyncAPIResource +from ....._response import ( + to_raw_response_wrapper, + to_streamed_response_wrapper, + async_to_raw_response_wrapper, + async_to_streamed_response_wrapper, +) +from ....._wrappers import ResultWrapper +from .....pagination import SyncSinglePage, AsyncSinglePage +from .proximity_words import ( + ProximityWordsResource, + AsyncProximityWordsResource, + ProximityWordsResourceWithRawResponse, + AsyncProximityWordsResourceWithRawResponse, + ProximityWordsResourceWithStreamingResponse, + AsyncProximityWordsResourceWithStreamingResponse, +) +from ....._base_client import AsyncPaginator, make_request_options +from .....types.zero_trust.dlp import validator_list_params +from .....types.zero_trust.dlp.validator import Validator + +__all__ = ["ValidatorsResource", "AsyncValidatorsResource"] + + +class ValidatorsResource(SyncAPIResource): + @cached_property + def proximity_words(self) -> ProximityWordsResource: + return ProximityWordsResource(self._client) + + @cached_property + def with_raw_response(self) -> ValidatorsResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers + """ + return ValidatorsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> ValidatorsResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response + """ + return ValidatorsResourceWithStreamingResponse(self) + + def list( + self, + *, + account_id: str, + kind: Optional[Literal["proximity_words", "worker"]] | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> SyncSinglePage[Validator]: + """ + Lists the validators configured for the account, of every kind. + + Args: + kind: Only return validators of this kind. Omit to return every kind. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + return self._get_api_list( + path_template("/accounts/{account_id}/dlp/validators", account_id=account_id), + page=SyncSinglePage[Validator], + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform({"kind": kind}, validator_list_params.ValidatorListParams), + ), + model=cast(Any, Validator), # Union types cannot be passed in as arguments in the type system + ) + + def get( + self, + validator_id: str, + *, + account_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> Optional[Validator]: + """ + Fetches a validator of any kind by ID. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not validator_id: + raise ValueError(f"Expected a non-empty value for `validator_id` but received {validator_id!r}") + return cast( + Optional[Validator], + self._get( + path_template( + "/accounts/{account_id}/dlp/validators/{validator_id}", + account_id=account_id, + validator_id=validator_id, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Optional[Validator]]._unwrapper, + ), + cast_to=cast( + Any, ResultWrapper[Validator] + ), # Union types cannot be passed in as arguments in the type system + ), + ) + + +class AsyncValidatorsResource(AsyncAPIResource): + @cached_property + def proximity_words(self) -> AsyncProximityWordsResource: + return AsyncProximityWordsResource(self._client) + + @cached_property + def with_raw_response(self) -> AsyncValidatorsResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers + """ + return AsyncValidatorsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncValidatorsResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response + """ + return AsyncValidatorsResourceWithStreamingResponse(self) + + def list( + self, + *, + account_id: str, + kind: Optional[Literal["proximity_words", "worker"]] | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> AsyncPaginator[Validator, AsyncSinglePage[Validator]]: + """ + Lists the validators configured for the account, of every kind. + + Args: + kind: Only return validators of this kind. Omit to return every kind. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + return self._get_api_list( + path_template("/accounts/{account_id}/dlp/validators", account_id=account_id), + page=AsyncSinglePage[Validator], + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform({"kind": kind}, validator_list_params.ValidatorListParams), + ), + model=cast(Any, Validator), # Union types cannot be passed in as arguments in the type system + ) + + async def get( + self, + validator_id: str, + *, + account_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> Optional[Validator]: + """ + Fetches a validator of any kind by ID. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not validator_id: + raise ValueError(f"Expected a non-empty value for `validator_id` but received {validator_id!r}") + return cast( + Optional[Validator], + await self._get( + path_template( + "/accounts/{account_id}/dlp/validators/{validator_id}", + account_id=account_id, + validator_id=validator_id, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Optional[Validator]]._unwrapper, + ), + cast_to=cast( + Any, ResultWrapper[Validator] + ), # Union types cannot be passed in as arguments in the type system + ), + ) + + +class ValidatorsResourceWithRawResponse: + def __init__(self, validators: ValidatorsResource) -> None: + self._validators = validators + + self.list = to_raw_response_wrapper( + validators.list, + ) + self.get = to_raw_response_wrapper( + validators.get, + ) + + @cached_property + def proximity_words(self) -> ProximityWordsResourceWithRawResponse: + return ProximityWordsResourceWithRawResponse(self._validators.proximity_words) + + +class AsyncValidatorsResourceWithRawResponse: + def __init__(self, validators: AsyncValidatorsResource) -> None: + self._validators = validators + + self.list = async_to_raw_response_wrapper( + validators.list, + ) + self.get = async_to_raw_response_wrapper( + validators.get, + ) + + @cached_property + def proximity_words(self) -> AsyncProximityWordsResourceWithRawResponse: + return AsyncProximityWordsResourceWithRawResponse(self._validators.proximity_words) + + +class ValidatorsResourceWithStreamingResponse: + def __init__(self, validators: ValidatorsResource) -> None: + self._validators = validators + + self.list = to_streamed_response_wrapper( + validators.list, + ) + self.get = to_streamed_response_wrapper( + validators.get, + ) + + @cached_property + def proximity_words(self) -> ProximityWordsResourceWithStreamingResponse: + return ProximityWordsResourceWithStreamingResponse(self._validators.proximity_words) + + +class AsyncValidatorsResourceWithStreamingResponse: + def __init__(self, validators: AsyncValidatorsResource) -> None: + self._validators = validators + + self.list = async_to_streamed_response_wrapper( + validators.list, + ) + self.get = async_to_streamed_response_wrapper( + validators.get, + ) + + @cached_property + def proximity_words(self) -> AsyncProximityWordsResourceWithStreamingResponse: + return AsyncProximityWordsResourceWithStreamingResponse(self._validators.proximity_words) diff --git a/src/cloudflare/resources/zero_trust/gateway/__init__.py b/src/cloudflare/resources/zero_trust/gateway/__init__.py index 070241ac482..e779233429a 100644 --- a/src/cloudflare/resources/zero_trust/gateway/__init__.py +++ b/src/cloudflare/resources/zero_trust/gateway/__init__.py @@ -96,6 +96,14 @@ AuditSSHSettingsResourceWithStreamingResponse, AsyncAuditSSHSettingsResourceWithStreamingResponse, ) +from .dns_destination_ips import ( + DNSDestinationIPsResource, + AsyncDNSDestinationIPsResource, + DNSDestinationIPsResourceWithRawResponse, + AsyncDNSDestinationIPsResourceWithRawResponse, + DNSDestinationIPsResourceWithStreamingResponse, + AsyncDNSDestinationIPsResourceWithStreamingResponse, +) __all__ = [ "AuditSSHSettingsResource", @@ -164,6 +172,12 @@ "AsyncPacfilesResourceWithRawResponse", "PacfilesResourceWithStreamingResponse", "AsyncPacfilesResourceWithStreamingResponse", + "DNSDestinationIPsResource", + "AsyncDNSDestinationIPsResource", + "DNSDestinationIPsResourceWithRawResponse", + "AsyncDNSDestinationIPsResourceWithRawResponse", + "DNSDestinationIPsResourceWithStreamingResponse", + "AsyncDNSDestinationIPsResourceWithStreamingResponse", "GatewayResource", "AsyncGatewayResource", "GatewayResourceWithRawResponse", diff --git a/src/cloudflare/resources/zero_trust/gateway/audit_ssh_settings.py b/src/cloudflare/resources/zero_trust/gateway/audit_ssh_settings.py index 7f6a4763837..a79423f062b 100644 --- a/src/cloudflare/resources/zero_trust/gateway/audit_ssh_settings.py +++ b/src/cloudflare/resources/zero_trust/gateway/audit_ssh_settings.py @@ -57,8 +57,7 @@ def update( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Optional[GatewaySettings]: """ - Update Zero Trust Audit SSH and SSH with Access for Infrastructure settings for - an account. + Update SSH with Access for Infrastructure settings for an account. Args: account_id: Specify the Cloudflare account identifier. @@ -103,8 +102,7 @@ def get( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Optional[GatewaySettings]: """ - Retrieve all Zero Trust Audit SSH and SSH with Access for Infrastructure - settings for an account. + Retrieve SSH with Access for Infrastructure settings for an account. Args: account_id: Specify the Cloudflare account identifier. @@ -205,8 +203,7 @@ async def update( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Optional[GatewaySettings]: """ - Update Zero Trust Audit SSH and SSH with Access for Infrastructure settings for - an account. + Update SSH with Access for Infrastructure settings for an account. Args: account_id: Specify the Cloudflare account identifier. @@ -251,8 +248,7 @@ async def get( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Optional[GatewaySettings]: """ - Retrieve all Zero Trust Audit SSH and SSH with Access for Infrastructure - settings for an account. + Retrieve SSH with Access for Infrastructure settings for an account. Args: account_id: Specify the Cloudflare account identifier. diff --git a/src/cloudflare/resources/tenants/account_types.py b/src/cloudflare/resources/zero_trust/gateway/dns_destination_ips.py similarity index 52% rename from src/cloudflare/resources/tenants/account_types.py rename to src/cloudflare/resources/zero_trust/gateway/dns_destination_ips.py index f952899df3e..0d4d4ea3067 100644 --- a/src/cloudflare/resources/tenants/account_types.py +++ b/src/cloudflare/resources/zero_trust/gateway/dns_destination_ips.py @@ -4,58 +4,60 @@ import httpx -from ..._types import Body, Query, Headers, NotGiven, not_given -from ..._utils import path_template -from ..._compat import cached_property -from ..._resource import SyncAPIResource, AsyncAPIResource -from ..._response import ( +from ...._types import Body, Query, Headers, NotGiven, not_given +from ...._utils import path_template +from ...._compat import cached_property +from ...._resource import SyncAPIResource, AsyncAPIResource +from ...._response import ( to_raw_response_wrapper, to_streamed_response_wrapper, async_to_raw_response_wrapper, async_to_streamed_response_wrapper, ) -from ...pagination import SyncSinglePage, AsyncSinglePage -from ..._base_client import AsyncPaginator, make_request_options -from ...types.tenants.account_type_list_response import AccountTypeListResponse +from ....pagination import SyncSinglePage, AsyncSinglePage +from ...._base_client import AsyncPaginator, make_request_options +from ....types.zero_trust.gateway.dns_destination_ip_list_response import DNSDestinationIPListResponse -__all__ = ["AccountTypesResource", "AsyncAccountTypesResource"] +__all__ = ["DNSDestinationIPsResource", "AsyncDNSDestinationIPsResource"] -class AccountTypesResource(SyncAPIResource): +class DNSDestinationIPsResource(SyncAPIResource): @cached_property - def with_raw_response(self) -> AccountTypesResourceWithRawResponse: + def with_raw_response(self) -> DNSDestinationIPsResourceWithRawResponse: """ This property can be used as a prefix for any HTTP method call to return the raw response object instead of the parsed content. For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers """ - return AccountTypesResourceWithRawResponse(self) + return DNSDestinationIPsResourceWithRawResponse(self) @cached_property - def with_streaming_response(self) -> AccountTypesResourceWithStreamingResponse: + def with_streaming_response(self) -> DNSDestinationIPsResourceWithStreamingResponse: """ An alternative to `.with_raw_response` that doesn't eagerly read the response body. For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response """ - return AccountTypesResourceWithStreamingResponse(self) + return DNSDestinationIPsResourceWithStreamingResponse(self) def list( self, - tenant_id: str, *, + account_id: str, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> SyncSinglePage[AccountTypeListResponse]: + ) -> SyncSinglePage[DNSDestinationIPListResponse]: """ - Lists the account types this tenant is allowed to provision. + List Zero Trust Gateway IPv4 address pairs for an account. Args: + account_id: Specify the Cloudflare account identifier. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -64,53 +66,55 @@ def list( timeout: Override the client-level default timeout for this request, in seconds """ - if not tenant_id: - raise ValueError(f"Expected a non-empty value for `tenant_id` but received {tenant_id!r}") + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") return self._get_api_list( - path_template("/tenants/{tenant_id}/account_types", tenant_id=tenant_id), - page=SyncSinglePage[AccountTypeListResponse], + path_template("/accounts/{account_id}/gateway/dns_destination_ips", account_id=account_id), + page=SyncSinglePage[DNSDestinationIPListResponse], options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), - model=str, + model=DNSDestinationIPListResponse, ) -class AsyncAccountTypesResource(AsyncAPIResource): +class AsyncDNSDestinationIPsResource(AsyncAPIResource): @cached_property - def with_raw_response(self) -> AsyncAccountTypesResourceWithRawResponse: + def with_raw_response(self) -> AsyncDNSDestinationIPsResourceWithRawResponse: """ This property can be used as a prefix for any HTTP method call to return the raw response object instead of the parsed content. For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers """ - return AsyncAccountTypesResourceWithRawResponse(self) + return AsyncDNSDestinationIPsResourceWithRawResponse(self) @cached_property - def with_streaming_response(self) -> AsyncAccountTypesResourceWithStreamingResponse: + def with_streaming_response(self) -> AsyncDNSDestinationIPsResourceWithStreamingResponse: """ An alternative to `.with_raw_response` that doesn't eagerly read the response body. For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response """ - return AsyncAccountTypesResourceWithStreamingResponse(self) + return AsyncDNSDestinationIPsResourceWithStreamingResponse(self) def list( self, - tenant_id: str, *, + account_id: str, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> AsyncPaginator[AccountTypeListResponse, AsyncSinglePage[AccountTypeListResponse]]: + ) -> AsyncPaginator[DNSDestinationIPListResponse, AsyncSinglePage[DNSDestinationIPListResponse]]: """ - Lists the account types this tenant is allowed to provision. + List Zero Trust Gateway IPv4 address pairs for an account. Args: + account_id: Specify the Cloudflare account identifier. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -119,49 +123,49 @@ def list( timeout: Override the client-level default timeout for this request, in seconds """ - if not tenant_id: - raise ValueError(f"Expected a non-empty value for `tenant_id` but received {tenant_id!r}") + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") return self._get_api_list( - path_template("/tenants/{tenant_id}/account_types", tenant_id=tenant_id), - page=AsyncSinglePage[AccountTypeListResponse], + path_template("/accounts/{account_id}/gateway/dns_destination_ips", account_id=account_id), + page=AsyncSinglePage[DNSDestinationIPListResponse], options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), - model=str, + model=DNSDestinationIPListResponse, ) -class AccountTypesResourceWithRawResponse: - def __init__(self, account_types: AccountTypesResource) -> None: - self._account_types = account_types +class DNSDestinationIPsResourceWithRawResponse: + def __init__(self, dns_destination_ips: DNSDestinationIPsResource) -> None: + self._dns_destination_ips = dns_destination_ips self.list = to_raw_response_wrapper( - account_types.list, + dns_destination_ips.list, ) -class AsyncAccountTypesResourceWithRawResponse: - def __init__(self, account_types: AsyncAccountTypesResource) -> None: - self._account_types = account_types +class AsyncDNSDestinationIPsResourceWithRawResponse: + def __init__(self, dns_destination_ips: AsyncDNSDestinationIPsResource) -> None: + self._dns_destination_ips = dns_destination_ips self.list = async_to_raw_response_wrapper( - account_types.list, + dns_destination_ips.list, ) -class AccountTypesResourceWithStreamingResponse: - def __init__(self, account_types: AccountTypesResource) -> None: - self._account_types = account_types +class DNSDestinationIPsResourceWithStreamingResponse: + def __init__(self, dns_destination_ips: DNSDestinationIPsResource) -> None: + self._dns_destination_ips = dns_destination_ips self.list = to_streamed_response_wrapper( - account_types.list, + dns_destination_ips.list, ) -class AsyncAccountTypesResourceWithStreamingResponse: - def __init__(self, account_types: AsyncAccountTypesResource) -> None: - self._account_types = account_types +class AsyncDNSDestinationIPsResourceWithStreamingResponse: + def __init__(self, dns_destination_ips: AsyncDNSDestinationIPsResource) -> None: + self._dns_destination_ips = dns_destination_ips self.list = async_to_streamed_response_wrapper( - account_types.list, + dns_destination_ips.list, ) diff --git a/src/cloudflare/resources/zero_trust/gateway/gateway.py b/src/cloudflare/resources/zero_trust/gateway/gateway.py index 46f9ac6cd47..07a30036645 100644 --- a/src/cloudflare/resources/zero_trust/gateway/gateway.py +++ b/src/cloudflare/resources/zero_trust/gateway/gateway.py @@ -98,6 +98,14 @@ AuditSSHSettingsResourceWithStreamingResponse, AsyncAuditSSHSettingsResourceWithStreamingResponse, ) +from .dns_destination_ips import ( + DNSDestinationIPsResource, + AsyncDNSDestinationIPsResource, + DNSDestinationIPsResourceWithRawResponse, + AsyncDNSDestinationIPsResourceWithRawResponse, + DNSDestinationIPsResourceWithStreamingResponse, + AsyncDNSDestinationIPsResourceWithStreamingResponse, +) from .configurations.configurations import ( ConfigurationsResource, AsyncConfigurationsResource, @@ -157,6 +165,10 @@ def certificates(self) -> CertificatesResource: def pacfiles(self) -> PacfilesResource: return PacfilesResource(self._client) + @cached_property + def dns_destination_ips(self) -> DNSDestinationIPsResource: + return DNSDestinationIPsResource(self._client) + @cached_property def with_raw_response(self) -> GatewayResourceWithRawResponse: """ @@ -300,6 +312,10 @@ def certificates(self) -> AsyncCertificatesResource: def pacfiles(self) -> AsyncPacfilesResource: return AsyncPacfilesResource(self._client) + @cached_property + def dns_destination_ips(self) -> AsyncDNSDestinationIPsResource: + return AsyncDNSDestinationIPsResource(self._client) + @cached_property def with_raw_response(self) -> AsyncGatewayResourceWithRawResponse: """ @@ -453,6 +469,10 @@ def certificates(self) -> CertificatesResourceWithRawResponse: def pacfiles(self) -> PacfilesResourceWithRawResponse: return PacfilesResourceWithRawResponse(self._gateway.pacfiles) + @cached_property + def dns_destination_ips(self) -> DNSDestinationIPsResourceWithRawResponse: + return DNSDestinationIPsResourceWithRawResponse(self._gateway.dns_destination_ips) + class AsyncGatewayResourceWithRawResponse: def __init__(self, gateway: AsyncGatewayResource) -> None: @@ -509,6 +529,10 @@ def certificates(self) -> AsyncCertificatesResourceWithRawResponse: def pacfiles(self) -> AsyncPacfilesResourceWithRawResponse: return AsyncPacfilesResourceWithRawResponse(self._gateway.pacfiles) + @cached_property + def dns_destination_ips(self) -> AsyncDNSDestinationIPsResourceWithRawResponse: + return AsyncDNSDestinationIPsResourceWithRawResponse(self._gateway.dns_destination_ips) + class GatewayResourceWithStreamingResponse: def __init__(self, gateway: GatewayResource) -> None: @@ -565,6 +589,10 @@ def certificates(self) -> CertificatesResourceWithStreamingResponse: def pacfiles(self) -> PacfilesResourceWithStreamingResponse: return PacfilesResourceWithStreamingResponse(self._gateway.pacfiles) + @cached_property + def dns_destination_ips(self) -> DNSDestinationIPsResourceWithStreamingResponse: + return DNSDestinationIPsResourceWithStreamingResponse(self._gateway.dns_destination_ips) + class AsyncGatewayResourceWithStreamingResponse: def __init__(self, gateway: AsyncGatewayResource) -> None: @@ -620,3 +648,7 @@ def certificates(self) -> AsyncCertificatesResourceWithStreamingResponse: @cached_property def pacfiles(self) -> AsyncPacfilesResourceWithStreamingResponse: return AsyncPacfilesResourceWithStreamingResponse(self._gateway.pacfiles) + + @cached_property + def dns_destination_ips(self) -> AsyncDNSDestinationIPsResourceWithStreamingResponse: + return AsyncDNSDestinationIPsResourceWithStreamingResponse(self._gateway.dns_destination_ips) diff --git a/src/cloudflare/resources/zero_trust/gateway/locations.py b/src/cloudflare/resources/zero_trust/gateway/locations.py index 824a0093df4..1453053315f 100644 --- a/src/cloudflare/resources/zero_trust/gateway/locations.py +++ b/src/cloudflare/resources/zero_trust/gateway/locations.py @@ -54,6 +54,7 @@ def create( name: str, client_default: bool | Omit = omit, dns_destination_ips_id: str | Omit = omit, + dns64_enabled: bool | Omit = omit, ecs_support: bool | Omit = omit, endpoints: Optional[EndpointParam] | Omit = omit, max_ttl: Optional[location_create_params.MaxTTL] | Omit = omit, @@ -81,6 +82,9 @@ def create( When updating a location, if this field is absent or set to null, the pre-assigned pair remains unchanged. + dns64_enabled: Enable DNS64 synthesis for DNS queries matched to this location. When updating a + location, omitting this field resets it to false. + ecs_support: Indicate whether the location must resolve EDNS queries. endpoints: Configure the destination endpoints for this location. @@ -110,6 +114,7 @@ def create( "name": name, "client_default": client_default, "dns_destination_ips_id": dns_destination_ips_id, + "dns64_enabled": dns64_enabled, "ecs_support": ecs_support, "endpoints": endpoints, "max_ttl": max_ttl, @@ -135,6 +140,7 @@ def update( name: str, client_default: bool | Omit = omit, dns_destination_ips_id: str | Omit = omit, + dns64_enabled: bool | Omit = omit, ecs_support: bool | Omit = omit, endpoints: Optional[EndpointParam] | Omit = omit, max_ttl: Optional[location_update_params.MaxTTL] | Omit = omit, @@ -162,6 +168,9 @@ def update( When updating a location, if this field is absent or set to null, the pre-assigned pair remains unchanged. + dns64_enabled: Enable DNS64 synthesis for DNS queries matched to this location. When updating a + location, omitting this field resets it to false. + ecs_support: Indicate whether the location must resolve EDNS queries. endpoints: Configure the destination endpoints for this location. @@ -195,6 +204,7 @@ def update( "name": name, "client_default": client_default, "dns_destination_ips_id": dns_destination_ips_id, + "dns64_enabled": dns64_enabled, "ecs_support": ecs_support, "endpoints": endpoints, "max_ttl": max_ttl, @@ -416,6 +426,7 @@ async def create( name: str, client_default: bool | Omit = omit, dns_destination_ips_id: str | Omit = omit, + dns64_enabled: bool | Omit = omit, ecs_support: bool | Omit = omit, endpoints: Optional[EndpointParam] | Omit = omit, max_ttl: Optional[location_create_params.MaxTTL] | Omit = omit, @@ -443,6 +454,9 @@ async def create( When updating a location, if this field is absent or set to null, the pre-assigned pair remains unchanged. + dns64_enabled: Enable DNS64 synthesis for DNS queries matched to this location. When updating a + location, omitting this field resets it to false. + ecs_support: Indicate whether the location must resolve EDNS queries. endpoints: Configure the destination endpoints for this location. @@ -472,6 +486,7 @@ async def create( "name": name, "client_default": client_default, "dns_destination_ips_id": dns_destination_ips_id, + "dns64_enabled": dns64_enabled, "ecs_support": ecs_support, "endpoints": endpoints, "max_ttl": max_ttl, @@ -497,6 +512,7 @@ async def update( name: str, client_default: bool | Omit = omit, dns_destination_ips_id: str | Omit = omit, + dns64_enabled: bool | Omit = omit, ecs_support: bool | Omit = omit, endpoints: Optional[EndpointParam] | Omit = omit, max_ttl: Optional[location_update_params.MaxTTL] | Omit = omit, @@ -524,6 +540,9 @@ async def update( When updating a location, if this field is absent or set to null, the pre-assigned pair remains unchanged. + dns64_enabled: Enable DNS64 synthesis for DNS queries matched to this location. When updating a + location, omitting this field resets it to false. + ecs_support: Indicate whether the location must resolve EDNS queries. endpoints: Configure the destination endpoints for this location. @@ -557,6 +576,7 @@ async def update( "name": name, "client_default": client_default, "dns_destination_ips_id": dns_destination_ips_id, + "dns64_enabled": dns64_enabled, "ecs_support": ecs_support, "endpoints": endpoints, "max_ttl": max_ttl, diff --git a/src/cloudflare/resources/zero_trust/gateway/rules.py b/src/cloudflare/resources/zero_trust/gateway/rules.py index 5cdf9738f36..7c4178b556a 100644 --- a/src/cloudflare/resources/zero_trust/gateway/rules.py +++ b/src/cloudflare/resources/zero_trust/gateway/rules.py @@ -70,6 +70,7 @@ def create( "resolve", "quarantine", "redirect", + "forward", ], name: str, description: str | Omit = omit, @@ -201,6 +202,7 @@ def update( "resolve", "quarantine", "redirect", + "forward", ], name: str, description: str | Omit = omit, @@ -602,6 +604,7 @@ async def create( "resolve", "quarantine", "redirect", + "forward", ], name: str, description: str | Omit = omit, @@ -733,6 +736,7 @@ async def update( "resolve", "quarantine", "redirect", + "forward", ], name: str, description: str | Omit = omit, diff --git a/src/cloudflare/resources/zero_trust/identity_providers/identity_providers.py b/src/cloudflare/resources/zero_trust/identity_providers/identity_providers.py index 05bb58a0661..f3c5931a403 100644 --- a/src/cloudflare/resources/zero_trust/identity_providers/identity_providers.py +++ b/src/cloudflare/resources/zero_trust/identity_providers/identity_providers.py @@ -512,6 +512,60 @@ def create( """ ... + @overload + def create( + self, + *, + config: identity_provider_create_params.AccessDuoConfig, + name: str, + type: IdentityProviderType, + account_id: str | Omit = omit, + zone_id: str | Omit = omit, + saml_certificate_set_id: str | Omit = omit, + scim_config: IdentityProviderSCIMConfigParam | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> Optional[IdentityProvider]: + """ + Adds a new identity provider to Access. + + Args: + config: The configuration parameters for the identity provider. To view the required + parameters for a specific provider, refer to our + [developer documentation](https://developers.cloudflare.com/cloudflare-one/identity/idp-integration/). + + name: The name of the identity provider, shown to users on the login page. + + type: The type of identity provider. To determine the value for a specific provider, + refer to our + [developer documentation](https://developers.cloudflare.com/cloudflare-one/identity/idp-integration/). + + account_id: The Account ID to use for this endpoint. Mutually exclusive with the Zone ID. + + zone_id: The Zone ID to use for this endpoint. Mutually exclusive with the Account ID. + + saml_certificate_set_id: The UID of the SAML encryption certificate set assigned to this Identity + Provider. Only present for SAML identity providers with encryption configured. + Create a certificate set via POST to + `/identity_providers/{id}/saml_certificate`. + + scim_config: The configuration settings for enabling a System for Cross-Domain Identity + Management (SCIM) with the identity provider. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + ... + @overload def create( self, @@ -890,6 +944,60 @@ def create( """ ... + @overload + def create( + self, + *, + config: identity_provider_create_params.AccessPasskeysConfig, + name: str, + type: IdentityProviderType, + account_id: str | Omit = omit, + zone_id: str | Omit = omit, + saml_certificate_set_id: str | Omit = omit, + scim_config: IdentityProviderSCIMConfigParam | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> Optional[IdentityProvider]: + """ + Adds a new identity provider to Access. + + Args: + config: The configuration parameters for the identity provider. To view the required + parameters for a specific provider, refer to our + [developer documentation](https://developers.cloudflare.com/cloudflare-one/identity/idp-integration/). + + name: The name of the identity provider, shown to users on the login page. + + type: The type of identity provider. To determine the value for a specific provider, + refer to our + [developer documentation](https://developers.cloudflare.com/cloudflare-one/identity/idp-integration/). + + account_id: The Account ID to use for this endpoint. Mutually exclusive with the Zone ID. + + zone_id: The Zone ID to use for this endpoint. Mutually exclusive with the Account ID. + + saml_certificate_set_id: The UID of the SAML encryption certificate set assigned to this Identity + Provider. Only present for SAML identity providers with encryption configured. + Create a certificate set via POST to + `/identity_providers/{id}/saml_certificate`. + + scim_config: The configuration settings for enabling a System for Cross-Domain Identity + Management (SCIM) with the identity provider. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + ... + @required_args(["config", "name", "type"]) def create( self, @@ -900,12 +1008,14 @@ def create( | identity_provider_create_params.AccessGoogleConfig | identity_provider_create_params.AccessGoogleAppsConfig | identity_provider_create_params.AccessOIDCConfig + | identity_provider_create_params.AccessDuoConfig | identity_provider_create_params.AccessOktaConfig | identity_provider_create_params.AccessOneloginConfig | identity_provider_create_params.AccessPingoneConfig | identity_provider_create_params.AccessSAMLConfig | identity_provider_create_params.AccessOnetimepinConfig - | identity_provider_create_params.AccessCloudflareConfig, + | identity_provider_create_params.AccessCloudflareConfig + | identity_provider_create_params.AccessPasskeysConfig, name: str, type: IdentityProviderType, account_id: str | Omit = omit, @@ -1418,6 +1528,63 @@ def update( """ ... + @overload + def update( + self, + identity_provider_id: str, + *, + config: identity_provider_update_params.AccessDuoConfig, + name: str, + type: IdentityProviderType, + account_id: str | Omit = omit, + zone_id: str | Omit = omit, + saml_certificate_set_id: str | Omit = omit, + scim_config: IdentityProviderSCIMConfigParam | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> Optional[IdentityProvider]: + """ + Updates a configured identity provider. + + Args: + identity_provider_id: UUID. + + config: The configuration parameters for the identity provider. To view the required + parameters for a specific provider, refer to our + [developer documentation](https://developers.cloudflare.com/cloudflare-one/identity/idp-integration/). + + name: The name of the identity provider, shown to users on the login page. + + type: The type of identity provider. To determine the value for a specific provider, + refer to our + [developer documentation](https://developers.cloudflare.com/cloudflare-one/identity/idp-integration/). + + account_id: The Account ID to use for this endpoint. Mutually exclusive with the Zone ID. + + zone_id: The Zone ID to use for this endpoint. Mutually exclusive with the Account ID. + + saml_certificate_set_id: The UID of the SAML encryption certificate set assigned to this Identity + Provider. Only present for SAML identity providers with encryption configured. + Create a certificate set via POST to + `/identity_providers/{id}/saml_certificate`. + + scim_config: The configuration settings for enabling a System for Cross-Domain Identity + Management (SCIM) with the identity provider. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + ... + @overload def update( self, @@ -1817,6 +1984,63 @@ def update( """ ... + @overload + def update( + self, + identity_provider_id: str, + *, + config: identity_provider_update_params.AccessPasskeysConfig, + name: str, + type: IdentityProviderType, + account_id: str | Omit = omit, + zone_id: str | Omit = omit, + saml_certificate_set_id: str | Omit = omit, + scim_config: IdentityProviderSCIMConfigParam | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> Optional[IdentityProvider]: + """ + Updates a configured identity provider. + + Args: + identity_provider_id: UUID. + + config: The configuration parameters for the identity provider. To view the required + parameters for a specific provider, refer to our + [developer documentation](https://developers.cloudflare.com/cloudflare-one/identity/idp-integration/). + + name: The name of the identity provider, shown to users on the login page. + + type: The type of identity provider. To determine the value for a specific provider, + refer to our + [developer documentation](https://developers.cloudflare.com/cloudflare-one/identity/idp-integration/). + + account_id: The Account ID to use for this endpoint. Mutually exclusive with the Zone ID. + + zone_id: The Zone ID to use for this endpoint. Mutually exclusive with the Account ID. + + saml_certificate_set_id: The UID of the SAML encryption certificate set assigned to this Identity + Provider. Only present for SAML identity providers with encryption configured. + Create a certificate set via POST to + `/identity_providers/{id}/saml_certificate`. + + scim_config: The configuration settings for enabling a System for Cross-Domain Identity + Management (SCIM) with the identity provider. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + ... + @required_args(["config", "name", "type"]) def update( self, @@ -1828,12 +2052,14 @@ def update( | identity_provider_update_params.AccessGoogleConfig | identity_provider_update_params.AccessGoogleAppsConfig | identity_provider_update_params.AccessOIDCConfig + | identity_provider_update_params.AccessDuoConfig | identity_provider_update_params.AccessOktaConfig | identity_provider_update_params.AccessOneloginConfig | identity_provider_update_params.AccessPingoneConfig | identity_provider_update_params.AccessSAMLConfig | identity_provider_update_params.AccessOnetimepinConfig - | identity_provider_update_params.AccessCloudflareConfig, + | identity_provider_update_params.AccessCloudflareConfig + | identity_provider_update_params.AccessPasskeysConfig, name: str, type: IdentityProviderType, account_id: str | Omit = omit, @@ -2565,6 +2791,60 @@ async def create( """ ... + @overload + async def create( + self, + *, + config: identity_provider_create_params.AccessDuoConfig, + name: str, + type: IdentityProviderType, + account_id: str | Omit = omit, + zone_id: str | Omit = omit, + saml_certificate_set_id: str | Omit = omit, + scim_config: IdentityProviderSCIMConfigParam | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> Optional[IdentityProvider]: + """ + Adds a new identity provider to Access. + + Args: + config: The configuration parameters for the identity provider. To view the required + parameters for a specific provider, refer to our + [developer documentation](https://developers.cloudflare.com/cloudflare-one/identity/idp-integration/). + + name: The name of the identity provider, shown to users on the login page. + + type: The type of identity provider. To determine the value for a specific provider, + refer to our + [developer documentation](https://developers.cloudflare.com/cloudflare-one/identity/idp-integration/). + + account_id: The Account ID to use for this endpoint. Mutually exclusive with the Zone ID. + + zone_id: The Zone ID to use for this endpoint. Mutually exclusive with the Account ID. + + saml_certificate_set_id: The UID of the SAML encryption certificate set assigned to this Identity + Provider. Only present for SAML identity providers with encryption configured. + Create a certificate set via POST to + `/identity_providers/{id}/saml_certificate`. + + scim_config: The configuration settings for enabling a System for Cross-Domain Identity + Management (SCIM) with the identity provider. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + ... + @overload async def create( self, @@ -2943,6 +3223,60 @@ async def create( """ ... + @overload + async def create( + self, + *, + config: identity_provider_create_params.AccessPasskeysConfig, + name: str, + type: IdentityProviderType, + account_id: str | Omit = omit, + zone_id: str | Omit = omit, + saml_certificate_set_id: str | Omit = omit, + scim_config: IdentityProviderSCIMConfigParam | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> Optional[IdentityProvider]: + """ + Adds a new identity provider to Access. + + Args: + config: The configuration parameters for the identity provider. To view the required + parameters for a specific provider, refer to our + [developer documentation](https://developers.cloudflare.com/cloudflare-one/identity/idp-integration/). + + name: The name of the identity provider, shown to users on the login page. + + type: The type of identity provider. To determine the value for a specific provider, + refer to our + [developer documentation](https://developers.cloudflare.com/cloudflare-one/identity/idp-integration/). + + account_id: The Account ID to use for this endpoint. Mutually exclusive with the Zone ID. + + zone_id: The Zone ID to use for this endpoint. Mutually exclusive with the Account ID. + + saml_certificate_set_id: The UID of the SAML encryption certificate set assigned to this Identity + Provider. Only present for SAML identity providers with encryption configured. + Create a certificate set via POST to + `/identity_providers/{id}/saml_certificate`. + + scim_config: The configuration settings for enabling a System for Cross-Domain Identity + Management (SCIM) with the identity provider. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + ... + @required_args(["config", "name", "type"]) async def create( self, @@ -2953,12 +3287,14 @@ async def create( | identity_provider_create_params.AccessGoogleConfig | identity_provider_create_params.AccessGoogleAppsConfig | identity_provider_create_params.AccessOIDCConfig + | identity_provider_create_params.AccessDuoConfig | identity_provider_create_params.AccessOktaConfig | identity_provider_create_params.AccessOneloginConfig | identity_provider_create_params.AccessPingoneConfig | identity_provider_create_params.AccessSAMLConfig | identity_provider_create_params.AccessOnetimepinConfig - | identity_provider_create_params.AccessCloudflareConfig, + | identity_provider_create_params.AccessCloudflareConfig + | identity_provider_create_params.AccessPasskeysConfig, name: str, type: IdentityProviderType, account_id: str | Omit = omit, @@ -3471,6 +3807,63 @@ async def update( """ ... + @overload + async def update( + self, + identity_provider_id: str, + *, + config: identity_provider_update_params.AccessDuoConfig, + name: str, + type: IdentityProviderType, + account_id: str | Omit = omit, + zone_id: str | Omit = omit, + saml_certificate_set_id: str | Omit = omit, + scim_config: IdentityProviderSCIMConfigParam | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> Optional[IdentityProvider]: + """ + Updates a configured identity provider. + + Args: + identity_provider_id: UUID. + + config: The configuration parameters for the identity provider. To view the required + parameters for a specific provider, refer to our + [developer documentation](https://developers.cloudflare.com/cloudflare-one/identity/idp-integration/). + + name: The name of the identity provider, shown to users on the login page. + + type: The type of identity provider. To determine the value for a specific provider, + refer to our + [developer documentation](https://developers.cloudflare.com/cloudflare-one/identity/idp-integration/). + + account_id: The Account ID to use for this endpoint. Mutually exclusive with the Zone ID. + + zone_id: The Zone ID to use for this endpoint. Mutually exclusive with the Account ID. + + saml_certificate_set_id: The UID of the SAML encryption certificate set assigned to this Identity + Provider. Only present for SAML identity providers with encryption configured. + Create a certificate set via POST to + `/identity_providers/{id}/saml_certificate`. + + scim_config: The configuration settings for enabling a System for Cross-Domain Identity + Management (SCIM) with the identity provider. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + ... + @overload async def update( self, @@ -3870,6 +4263,63 @@ async def update( """ ... + @overload + async def update( + self, + identity_provider_id: str, + *, + config: identity_provider_update_params.AccessPasskeysConfig, + name: str, + type: IdentityProviderType, + account_id: str | Omit = omit, + zone_id: str | Omit = omit, + saml_certificate_set_id: str | Omit = omit, + scim_config: IdentityProviderSCIMConfigParam | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> Optional[IdentityProvider]: + """ + Updates a configured identity provider. + + Args: + identity_provider_id: UUID. + + config: The configuration parameters for the identity provider. To view the required + parameters for a specific provider, refer to our + [developer documentation](https://developers.cloudflare.com/cloudflare-one/identity/idp-integration/). + + name: The name of the identity provider, shown to users on the login page. + + type: The type of identity provider. To determine the value for a specific provider, + refer to our + [developer documentation](https://developers.cloudflare.com/cloudflare-one/identity/idp-integration/). + + account_id: The Account ID to use for this endpoint. Mutually exclusive with the Zone ID. + + zone_id: The Zone ID to use for this endpoint. Mutually exclusive with the Account ID. + + saml_certificate_set_id: The UID of the SAML encryption certificate set assigned to this Identity + Provider. Only present for SAML identity providers with encryption configured. + Create a certificate set via POST to + `/identity_providers/{id}/saml_certificate`. + + scim_config: The configuration settings for enabling a System for Cross-Domain Identity + Management (SCIM) with the identity provider. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + ... + @required_args(["config", "name", "type"]) async def update( self, @@ -3881,12 +4331,14 @@ async def update( | identity_provider_update_params.AccessGoogleConfig | identity_provider_update_params.AccessGoogleAppsConfig | identity_provider_update_params.AccessOIDCConfig + | identity_provider_update_params.AccessDuoConfig | identity_provider_update_params.AccessOktaConfig | identity_provider_update_params.AccessOneloginConfig | identity_provider_update_params.AccessPingoneConfig | identity_provider_update_params.AccessSAMLConfig | identity_provider_update_params.AccessOnetimepinConfig - | identity_provider_update_params.AccessCloudflareConfig, + | identity_provider_update_params.AccessCloudflareConfig + | identity_provider_update_params.AccessPasskeysConfig, name: str, type: IdentityProviderType, account_id: str | Omit = omit, diff --git a/src/cloudflare/resources/zero_trust/identity_providers/scim/groups.py b/src/cloudflare/resources/zero_trust/identity_providers/scim/groups.py index 7bc9fa1f7d6..5fe98c2fbcc 100644 --- a/src/cloudflare/resources/zero_trust/identity_providers/scim/groups.py +++ b/src/cloudflare/resources/zero_trust/identity_providers/scim/groups.py @@ -2,9 +2,11 @@ from __future__ import annotations +from typing import Type, Optional, cast + import httpx -from ....._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given +from ....._types import Body, Omit, Query, Headers, NoneType, NotGiven, SequenceNotStr, omit, not_given from ....._utils import path_template, maybe_transform from ....._compat import cached_property from ....._resource import SyncAPIResource, AsyncAPIResource @@ -14,10 +16,12 @@ async_to_raw_response_wrapper, async_to_streamed_response_wrapper, ) +from ....._wrappers import ResultWrapper from .....pagination import SyncV4PagePaginationArray, AsyncV4PagePaginationArray from ....._base_client import AsyncPaginator, make_request_options from .....types.zero_trust.access.zero_trust_group import ZeroTrustGroup from .....types.zero_trust.identity_providers.scim import group_list_params +from .....types.zero_trust.identity_providers.scim.group_get_response import GroupGetResponse __all__ = ["GroupsResource", "AsyncGroupsResource"] @@ -126,6 +130,116 @@ def list( model=ZeroTrustGroup, ) + def delete( + self, + group_id: str, + *, + account_id: str, + identity_provider_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> None: + """ + Deletes a SCIM Group resource from the identity provider's SCIM population. + + Args: + account_id: Identifier. + + identity_provider_id: UUID. + + group_id: Identifier. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not identity_provider_id: + raise ValueError( + f"Expected a non-empty value for `identity_provider_id` but received {identity_provider_id!r}" + ) + if not group_id: + raise ValueError(f"Expected a non-empty value for `group_id` but received {group_id!r}") + extra_headers = {"Accept": "*/*", **(extra_headers or {})} + return self._delete( + path_template( + "/accounts/{account_id}/access/identity_providers/{identity_provider_id}/scim/groups/{group_id}", + account_id=account_id, + identity_provider_id=identity_provider_id, + group_id=group_id, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=NoneType, + ) + + def get( + self, + group_id: str, + *, + account_id: str, + identity_provider_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> Optional[GroupGetResponse]: + """ + Returns a SCIM Group resource, including its direct members, synced to + Cloudflare via the System for Cross-domain Identity Management (SCIM). + + Args: + account_id: Identifier. + + identity_provider_id: UUID. + + group_id: Identifier. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not identity_provider_id: + raise ValueError( + f"Expected a non-empty value for `identity_provider_id` but received {identity_provider_id!r}" + ) + if not group_id: + raise ValueError(f"Expected a non-empty value for `group_id` but received {group_id!r}") + return self._get( + path_template( + "/accounts/{account_id}/access/identity_providers/{identity_provider_id}/scim/groups/{group_id}", + account_id=account_id, + identity_provider_id=identity_provider_id, + group_id=group_id, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Optional[GroupGetResponse]]._unwrapper, + ), + cast_to=cast(Type[Optional[GroupGetResponse]], ResultWrapper[GroupGetResponse]), + ) + class AsyncGroupsResource(AsyncAPIResource): @cached_property @@ -231,6 +345,116 @@ def list( model=ZeroTrustGroup, ) + async def delete( + self, + group_id: str, + *, + account_id: str, + identity_provider_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> None: + """ + Deletes a SCIM Group resource from the identity provider's SCIM population. + + Args: + account_id: Identifier. + + identity_provider_id: UUID. + + group_id: Identifier. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not identity_provider_id: + raise ValueError( + f"Expected a non-empty value for `identity_provider_id` but received {identity_provider_id!r}" + ) + if not group_id: + raise ValueError(f"Expected a non-empty value for `group_id` but received {group_id!r}") + extra_headers = {"Accept": "*/*", **(extra_headers or {})} + return await self._delete( + path_template( + "/accounts/{account_id}/access/identity_providers/{identity_provider_id}/scim/groups/{group_id}", + account_id=account_id, + identity_provider_id=identity_provider_id, + group_id=group_id, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=NoneType, + ) + + async def get( + self, + group_id: str, + *, + account_id: str, + identity_provider_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> Optional[GroupGetResponse]: + """ + Returns a SCIM Group resource, including its direct members, synced to + Cloudflare via the System for Cross-domain Identity Management (SCIM). + + Args: + account_id: Identifier. + + identity_provider_id: UUID. + + group_id: Identifier. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not identity_provider_id: + raise ValueError( + f"Expected a non-empty value for `identity_provider_id` but received {identity_provider_id!r}" + ) + if not group_id: + raise ValueError(f"Expected a non-empty value for `group_id` but received {group_id!r}") + return await self._get( + path_template( + "/accounts/{account_id}/access/identity_providers/{identity_provider_id}/scim/groups/{group_id}", + account_id=account_id, + identity_provider_id=identity_provider_id, + group_id=group_id, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Optional[GroupGetResponse]]._unwrapper, + ), + cast_to=cast(Type[Optional[GroupGetResponse]], ResultWrapper[GroupGetResponse]), + ) + class GroupsResourceWithRawResponse: def __init__(self, groups: GroupsResource) -> None: @@ -239,6 +463,12 @@ def __init__(self, groups: GroupsResource) -> None: self.list = to_raw_response_wrapper( groups.list, ) + self.delete = to_raw_response_wrapper( + groups.delete, + ) + self.get = to_raw_response_wrapper( + groups.get, + ) class AsyncGroupsResourceWithRawResponse: @@ -248,6 +478,12 @@ def __init__(self, groups: AsyncGroupsResource) -> None: self.list = async_to_raw_response_wrapper( groups.list, ) + self.delete = async_to_raw_response_wrapper( + groups.delete, + ) + self.get = async_to_raw_response_wrapper( + groups.get, + ) class GroupsResourceWithStreamingResponse: @@ -257,6 +493,12 @@ def __init__(self, groups: GroupsResource) -> None: self.list = to_streamed_response_wrapper( groups.list, ) + self.delete = to_streamed_response_wrapper( + groups.delete, + ) + self.get = to_streamed_response_wrapper( + groups.get, + ) class AsyncGroupsResourceWithStreamingResponse: @@ -266,3 +508,9 @@ def __init__(self, groups: AsyncGroupsResource) -> None: self.list = async_to_streamed_response_wrapper( groups.list, ) + self.delete = async_to_streamed_response_wrapper( + groups.delete, + ) + self.get = async_to_streamed_response_wrapper( + groups.get, + ) diff --git a/src/cloudflare/resources/zero_trust/identity_providers/scim/users.py b/src/cloudflare/resources/zero_trust/identity_providers/scim/users.py index e2f59069361..7bf08187369 100644 --- a/src/cloudflare/resources/zero_trust/identity_providers/scim/users.py +++ b/src/cloudflare/resources/zero_trust/identity_providers/scim/users.py @@ -2,9 +2,11 @@ from __future__ import annotations +from typing import Type, Optional, cast + import httpx -from ....._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given +from ....._types import Body, Omit, Query, Headers, NoneType, NotGiven, SequenceNotStr, omit, not_given from ....._utils import path_template, maybe_transform from ....._compat import cached_property from ....._resource import SyncAPIResource, AsyncAPIResource @@ -14,6 +16,7 @@ async_to_raw_response_wrapper, async_to_streamed_response_wrapper, ) +from ....._wrappers import ResultWrapper from .....pagination import SyncV4PagePaginationArray, AsyncV4PagePaginationArray from ....._base_client import AsyncPaginator, make_request_options from .....types.zero_trust.access.access_user import AccessUser @@ -134,6 +137,116 @@ def list( model=AccessUser, ) + def delete( + self, + user_id: str, + *, + account_id: str, + identity_provider_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> None: + """ + Deletes a SCIM User resource from the identity provider's SCIM population. + + Args: + account_id: Identifier. + + identity_provider_id: UUID. + + user_id: Identifier. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not identity_provider_id: + raise ValueError( + f"Expected a non-empty value for `identity_provider_id` but received {identity_provider_id!r}" + ) + if not user_id: + raise ValueError(f"Expected a non-empty value for `user_id` but received {user_id!r}") + extra_headers = {"Accept": "*/*", **(extra_headers or {})} + return self._delete( + path_template( + "/accounts/{account_id}/access/identity_providers/{identity_provider_id}/scim/users/{user_id}", + account_id=account_id, + identity_provider_id=identity_provider_id, + user_id=user_id, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=NoneType, + ) + + def get( + self, + user_id: str, + *, + account_id: str, + identity_provider_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> Optional[AccessUser]: + """ + Returns a SCIM User resource synced to Cloudflare via the System for + Cross-domain Identity Management (SCIM). + + Args: + account_id: Identifier. + + identity_provider_id: UUID. + + user_id: Identifier. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not identity_provider_id: + raise ValueError( + f"Expected a non-empty value for `identity_provider_id` but received {identity_provider_id!r}" + ) + if not user_id: + raise ValueError(f"Expected a non-empty value for `user_id` but received {user_id!r}") + return self._get( + path_template( + "/accounts/{account_id}/access/identity_providers/{identity_provider_id}/scim/users/{user_id}", + account_id=account_id, + identity_provider_id=identity_provider_id, + user_id=user_id, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Optional[AccessUser]]._unwrapper, + ), + cast_to=cast(Type[Optional[AccessUser]], ResultWrapper[AccessUser]), + ) + class AsyncUsersResource(AsyncAPIResource): @cached_property @@ -247,6 +360,116 @@ def list( model=AccessUser, ) + async def delete( + self, + user_id: str, + *, + account_id: str, + identity_provider_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> None: + """ + Deletes a SCIM User resource from the identity provider's SCIM population. + + Args: + account_id: Identifier. + + identity_provider_id: UUID. + + user_id: Identifier. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not identity_provider_id: + raise ValueError( + f"Expected a non-empty value for `identity_provider_id` but received {identity_provider_id!r}" + ) + if not user_id: + raise ValueError(f"Expected a non-empty value for `user_id` but received {user_id!r}") + extra_headers = {"Accept": "*/*", **(extra_headers or {})} + return await self._delete( + path_template( + "/accounts/{account_id}/access/identity_providers/{identity_provider_id}/scim/users/{user_id}", + account_id=account_id, + identity_provider_id=identity_provider_id, + user_id=user_id, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=NoneType, + ) + + async def get( + self, + user_id: str, + *, + account_id: str, + identity_provider_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> Optional[AccessUser]: + """ + Returns a SCIM User resource synced to Cloudflare via the System for + Cross-domain Identity Management (SCIM). + + Args: + account_id: Identifier. + + identity_provider_id: UUID. + + user_id: Identifier. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + if not identity_provider_id: + raise ValueError( + f"Expected a non-empty value for `identity_provider_id` but received {identity_provider_id!r}" + ) + if not user_id: + raise ValueError(f"Expected a non-empty value for `user_id` but received {user_id!r}") + return await self._get( + path_template( + "/accounts/{account_id}/access/identity_providers/{identity_provider_id}/scim/users/{user_id}", + account_id=account_id, + identity_provider_id=identity_provider_id, + user_id=user_id, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Optional[AccessUser]]._unwrapper, + ), + cast_to=cast(Type[Optional[AccessUser]], ResultWrapper[AccessUser]), + ) + class UsersResourceWithRawResponse: def __init__(self, users: UsersResource) -> None: @@ -255,6 +478,12 @@ def __init__(self, users: UsersResource) -> None: self.list = to_raw_response_wrapper( users.list, ) + self.delete = to_raw_response_wrapper( + users.delete, + ) + self.get = to_raw_response_wrapper( + users.get, + ) class AsyncUsersResourceWithRawResponse: @@ -264,6 +493,12 @@ def __init__(self, users: AsyncUsersResource) -> None: self.list = async_to_raw_response_wrapper( users.list, ) + self.delete = async_to_raw_response_wrapper( + users.delete, + ) + self.get = async_to_raw_response_wrapper( + users.get, + ) class UsersResourceWithStreamingResponse: @@ -273,6 +508,12 @@ def __init__(self, users: UsersResource) -> None: self.list = to_streamed_response_wrapper( users.list, ) + self.delete = to_streamed_response_wrapper( + users.delete, + ) + self.get = to_streamed_response_wrapper( + users.get, + ) class AsyncUsersResourceWithStreamingResponse: @@ -282,3 +523,9 @@ def __init__(self, users: AsyncUsersResource) -> None: self.list = async_to_streamed_response_wrapper( users.list, ) + self.delete = async_to_streamed_response_wrapper( + users.delete, + ) + self.get = async_to_streamed_response_wrapper( + users.get, + ) diff --git a/src/cloudflare/resources/zero_trust/organizations/organizations.py b/src/cloudflare/resources/zero_trust/organizations/organizations.py index 769de7061bd..14ba18605a2 100644 --- a/src/cloudflare/resources/zero_trust/organizations/organizations.py +++ b/src/cloudflare/resources/zero_trust/organizations/organizations.py @@ -66,19 +66,20 @@ def with_streaming_response(self) -> OrganizationsResourceWithStreamingResponse: def create( self, *, - auth_domain: str, - name: str, account_id: str | Omit = omit, zone_id: str | Omit = omit, allow_authenticate_via_warp: bool | Omit = omit, + auth_domain: str | Omit = omit, auto_redirect_to_identity: bool | Omit = omit, deny_unmatched_requests: bool | Omit = omit, deny_unmatched_requests_exempted_zone_names: SequenceNotStr[str] | Omit = omit, + disable_end_user_app_creation: bool | Omit = omit, is_ui_read_only: bool | Omit = omit, login_design: LoginDesignParam | Omit = omit, mfa_config: organization_create_params.MfaConfig | Omit = omit, mfa_piv_key_requirements: organization_create_params.MfaPivKeyRequirements | Omit = omit, mfa_required_for_all_apps: bool | Omit = omit, + name: str | Omit = omit, service_token_inactivity: organization_create_params.ServiceTokenInactivity | Omit = omit, session_duration: str | Omit = omit, strict_service_token_auth: bool | Omit = omit, @@ -97,10 +98,6 @@ def create( Sets up a Zero Trust organization for your account or zone. Args: - auth_domain: The unique subdomain assigned to your Zero Trust organization. - - name: The name of your Zero Trust organization. - account_id: The Account ID to use for this endpoint. Mutually exclusive with the Zone ID. zone_id: The Zone ID to use for this endpoint. Mutually exclusive with the Account ID. @@ -108,6 +105,10 @@ def create( allow_authenticate_via_warp: When set to true, users can authenticate via WARP for any application in your organization. Application settings will take precedence over this value. + auth_domain: The unique subdomain assigned to your Zero Trust organization. If omitted on + creation, a unique subdomain is auto-generated in the format + `adjective-noun-hex4` (e.g. `frosty-moon-7a3b.cloudflareaccess.com`). + auto_redirect_to_identity: When set to `true`, users skip the identity provider selection step during login. @@ -122,6 +123,8 @@ def create( by default if there is a configured Access application and policy that matches the request. + disable_end_user_app_creation: Whether creation of end user applications is disabled for this organization. + is_ui_read_only: Lock all settings as Read-Only in the Dashboard, regardless of user permission. Updates may only be made via the API or Terraform for this account when enabled. @@ -135,6 +138,10 @@ def create( the infrastructure SSH authenticators ('piv_key' and 'ssh_fido2_key') if the organization has any non-infrastructure applications. + name: The name of your Zero Trust organization. When omitted on creation, defaults to + the provided auth_domain; when both are omitted, defaults to the auto-generated + subdomain slug (e.g. frosty-moon-7a3b). + service_token_inactivity: Configures automatic enforcement for inactive service tokens. A service token is inactive if no policy references it, and it has not successfully authenticated with an Access application during the selected inactivity period. This setting @@ -193,17 +200,18 @@ def create( ), body=maybe_transform( { - "auth_domain": auth_domain, - "name": name, "allow_authenticate_via_warp": allow_authenticate_via_warp, + "auth_domain": auth_domain, "auto_redirect_to_identity": auto_redirect_to_identity, "deny_unmatched_requests": deny_unmatched_requests, "deny_unmatched_requests_exempted_zone_names": deny_unmatched_requests_exempted_zone_names, + "disable_end_user_app_creation": disable_end_user_app_creation, "is_ui_read_only": is_ui_read_only, "login_design": login_design, "mfa_config": mfa_config, "mfa_piv_key_requirements": mfa_piv_key_requirements, "mfa_required_for_all_apps": mfa_required_for_all_apps, + "name": name, "service_token_inactivity": service_token_inactivity, "session_duration": session_duration, "strict_service_token_auth": strict_service_token_auth, @@ -235,6 +243,7 @@ def update( custom_pages: organization_update_params.CustomPages | Omit = omit, deny_unmatched_requests: bool | Omit = omit, deny_unmatched_requests_exempted_zone_names: SequenceNotStr[str] | Omit = omit, + disable_end_user_app_creation: bool | Omit = omit, is_ui_read_only: bool | Omit = omit, login_design: LoginDesignParam | Omit = omit, mfa_config: organization_update_params.MfaConfig | Omit = omit, @@ -266,7 +275,9 @@ def update( allow_authenticate_via_warp: When set to true, users can authenticate via WARP for any application in your organization. Application settings will take precedence over this value. - auth_domain: The unique subdomain assigned to your Zero Trust organization. + auth_domain: The unique subdomain assigned to your Zero Trust organization. If omitted on + creation, a unique subdomain is auto-generated in the format + `adjective-noun-hex4` (e.g. `frosty-moon-7a3b.cloudflareaccess.com`). auto_redirect_to_identity: When set to `true`, users skip the identity provider selection step during login. @@ -282,6 +293,8 @@ def update( by default if there is a configured Access application and policy that matches the request. + disable_end_user_app_creation: Whether creation of end user applications is disabled for this organization. + is_ui_read_only: Lock all settings as Read-Only in the Dashboard, regardless of user permission. Updates may only be made via the API or Terraform for this account when enabled. @@ -295,7 +308,9 @@ def update( the infrastructure SSH authenticators ('piv_key' and 'ssh_fido2_key') if the organization has any non-infrastructure applications. - name: The name of your Zero Trust organization. + name: The name of your Zero Trust organization. When omitted on creation, defaults to + the provided auth_domain; when both are omitted, defaults to the auto-generated + subdomain slug (e.g. frosty-moon-7a3b). service_token_inactivity: Configures automatic enforcement for inactive service tokens. A service token is inactive if no policy references it, and it has not successfully authenticated @@ -361,6 +376,7 @@ def update( "custom_pages": custom_pages, "deny_unmatched_requests": deny_unmatched_requests, "deny_unmatched_requests_exempted_zone_names": deny_unmatched_requests_exempted_zone_names, + "disable_end_user_app_creation": disable_end_user_app_creation, "is_ui_read_only": is_ui_read_only, "login_design": login_design, "mfa_config": mfa_config, @@ -558,19 +574,20 @@ def with_streaming_response(self) -> AsyncOrganizationsResourceWithStreamingResp async def create( self, *, - auth_domain: str, - name: str, account_id: str | Omit = omit, zone_id: str | Omit = omit, allow_authenticate_via_warp: bool | Omit = omit, + auth_domain: str | Omit = omit, auto_redirect_to_identity: bool | Omit = omit, deny_unmatched_requests: bool | Omit = omit, deny_unmatched_requests_exempted_zone_names: SequenceNotStr[str] | Omit = omit, + disable_end_user_app_creation: bool | Omit = omit, is_ui_read_only: bool | Omit = omit, login_design: LoginDesignParam | Omit = omit, mfa_config: organization_create_params.MfaConfig | Omit = omit, mfa_piv_key_requirements: organization_create_params.MfaPivKeyRequirements | Omit = omit, mfa_required_for_all_apps: bool | Omit = omit, + name: str | Omit = omit, service_token_inactivity: organization_create_params.ServiceTokenInactivity | Omit = omit, session_duration: str | Omit = omit, strict_service_token_auth: bool | Omit = omit, @@ -589,10 +606,6 @@ async def create( Sets up a Zero Trust organization for your account or zone. Args: - auth_domain: The unique subdomain assigned to your Zero Trust organization. - - name: The name of your Zero Trust organization. - account_id: The Account ID to use for this endpoint. Mutually exclusive with the Zone ID. zone_id: The Zone ID to use for this endpoint. Mutually exclusive with the Account ID. @@ -600,6 +613,10 @@ async def create( allow_authenticate_via_warp: When set to true, users can authenticate via WARP for any application in your organization. Application settings will take precedence over this value. + auth_domain: The unique subdomain assigned to your Zero Trust organization. If omitted on + creation, a unique subdomain is auto-generated in the format + `adjective-noun-hex4` (e.g. `frosty-moon-7a3b.cloudflareaccess.com`). + auto_redirect_to_identity: When set to `true`, users skip the identity provider selection step during login. @@ -614,6 +631,8 @@ async def create( by default if there is a configured Access application and policy that matches the request. + disable_end_user_app_creation: Whether creation of end user applications is disabled for this organization. + is_ui_read_only: Lock all settings as Read-Only in the Dashboard, regardless of user permission. Updates may only be made via the API or Terraform for this account when enabled. @@ -627,6 +646,10 @@ async def create( the infrastructure SSH authenticators ('piv_key' and 'ssh_fido2_key') if the organization has any non-infrastructure applications. + name: The name of your Zero Trust organization. When omitted on creation, defaults to + the provided auth_domain; when both are omitted, defaults to the auto-generated + subdomain slug (e.g. frosty-moon-7a3b). + service_token_inactivity: Configures automatic enforcement for inactive service tokens. A service token is inactive if no policy references it, and it has not successfully authenticated with an Access application during the selected inactivity period. This setting @@ -685,17 +708,18 @@ async def create( ), body=await async_maybe_transform( { - "auth_domain": auth_domain, - "name": name, "allow_authenticate_via_warp": allow_authenticate_via_warp, + "auth_domain": auth_domain, "auto_redirect_to_identity": auto_redirect_to_identity, "deny_unmatched_requests": deny_unmatched_requests, "deny_unmatched_requests_exempted_zone_names": deny_unmatched_requests_exempted_zone_names, + "disable_end_user_app_creation": disable_end_user_app_creation, "is_ui_read_only": is_ui_read_only, "login_design": login_design, "mfa_config": mfa_config, "mfa_piv_key_requirements": mfa_piv_key_requirements, "mfa_required_for_all_apps": mfa_required_for_all_apps, + "name": name, "service_token_inactivity": service_token_inactivity, "session_duration": session_duration, "strict_service_token_auth": strict_service_token_auth, @@ -727,6 +751,7 @@ async def update( custom_pages: organization_update_params.CustomPages | Omit = omit, deny_unmatched_requests: bool | Omit = omit, deny_unmatched_requests_exempted_zone_names: SequenceNotStr[str] | Omit = omit, + disable_end_user_app_creation: bool | Omit = omit, is_ui_read_only: bool | Omit = omit, login_design: LoginDesignParam | Omit = omit, mfa_config: organization_update_params.MfaConfig | Omit = omit, @@ -758,7 +783,9 @@ async def update( allow_authenticate_via_warp: When set to true, users can authenticate via WARP for any application in your organization. Application settings will take precedence over this value. - auth_domain: The unique subdomain assigned to your Zero Trust organization. + auth_domain: The unique subdomain assigned to your Zero Trust organization. If omitted on + creation, a unique subdomain is auto-generated in the format + `adjective-noun-hex4` (e.g. `frosty-moon-7a3b.cloudflareaccess.com`). auto_redirect_to_identity: When set to `true`, users skip the identity provider selection step during login. @@ -774,6 +801,8 @@ async def update( by default if there is a configured Access application and policy that matches the request. + disable_end_user_app_creation: Whether creation of end user applications is disabled for this organization. + is_ui_read_only: Lock all settings as Read-Only in the Dashboard, regardless of user permission. Updates may only be made via the API or Terraform for this account when enabled. @@ -787,7 +816,9 @@ async def update( the infrastructure SSH authenticators ('piv_key' and 'ssh_fido2_key') if the organization has any non-infrastructure applications. - name: The name of your Zero Trust organization. + name: The name of your Zero Trust organization. When omitted on creation, defaults to + the provided auth_domain; when both are omitted, defaults to the auto-generated + subdomain slug (e.g. frosty-moon-7a3b). service_token_inactivity: Configures automatic enforcement for inactive service tokens. A service token is inactive if no policy references it, and it has not successfully authenticated @@ -853,6 +884,7 @@ async def update( "custom_pages": custom_pages, "deny_unmatched_requests": deny_unmatched_requests, "deny_unmatched_requests_exempted_zone_names": deny_unmatched_requests_exempted_zone_names, + "disable_end_user_app_creation": disable_end_user_app_creation, "is_ui_read_only": is_ui_read_only, "login_design": login_design, "mfa_config": mfa_config, diff --git a/src/cloudflare/resources/zero_trust/resource_library/applications.py b/src/cloudflare/resources/zero_trust/resource_library/applications.py index bed518ddbb3..402973cd62d 100644 --- a/src/cloudflare/resources/zero_trust/resource_library/applications.py +++ b/src/cloudflare/resources/zero_trust/resource_library/applications.py @@ -18,7 +18,7 @@ async_to_streamed_response_wrapper, ) from ...._wrappers import ResultWrapper -from ....pagination import SyncSinglePage, AsyncSinglePage +from ....pagination import SyncCursorPaginationAfter, AsyncCursorPaginationAfter from ...._base_client import AsyncPaginator, make_request_options from ....types.zero_trust.resource_library import ( application_list_params, @@ -73,22 +73,25 @@ def create( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Optional[ApplicationCreateResponse]: """ - Create a custom application for an account. + Create a custom application for an account from a name, category, and optional + network matchers. Args: hostnames: Hostnames matched by the application. - category_id: Returns the category ID. + category_id: Numeric identifier for an application category. - human_id: Returns the human readable ID. + human_id: Human-readable identifier for the application. ip_subnets: IP subnets for this application. Custom application create and update requests accept IPv4 prefix lengths /8 through /32 and IPv6 prefix lengths /32 through /128. - name: Returns the application name. + name: Application name. - port_protocols: Port and protocol pairs matched by the application. + port_protocols: Ports matched by the application, in `protocol/port` or inclusive + `protocol/start-end` format (for example, `tcp/443` or `udp/10000-20000`). TCP + and UDP ports must be between 0 and 65535. support_domains: Support domains matched by the application. @@ -122,22 +125,25 @@ def create( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Optional[ApplicationCreateResponse]: """ - Create a custom application for an account. + Create a custom application for an account from a name, category, and optional + network matchers. Args: ip_subnets: IP subnets for this application. Custom application create and update requests accept IPv4 prefix lengths /8 through /32 and IPv6 prefix lengths /32 through /128. - category_id: Returns the category ID. + category_id: Numeric identifier for an application category. hostnames: Hostnames matched by the application. - human_id: Returns the human readable ID. + human_id: Human-readable identifier for the application. - name: Returns the application name. + name: Application name. - port_protocols: Port and protocol pairs matched by the application. + port_protocols: Ports matched by the application, in `protocol/port` or inclusive + `protocol/start-end` format (for example, `tcp/443` or `udp/10000-20000`). TCP + and UDP ports must be between 0 and 65535. support_domains: Support domains matched by the application. @@ -213,10 +219,12 @@ def update( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Optional[ApplicationUpdateResponse]: """ - Replace the network matchers for a custom application and create a new version. + Replace the supplied network matchers for a custom application and create a new + version. Omitted matcher lists remain unchanged; send an empty list to clear a + matcher type. Args: - id: Returns the application ID. + id: Numeric identifier for the application. hostnames: Hostnames matched by the application. @@ -224,7 +232,9 @@ def update( accept IPv4 prefix lengths /8 through /32 and IPv6 prefix lengths /32 through /128. - port_protocols: Port and protocol pairs matched by the application. + port_protocols: Ports matched by the application, in `protocol/port` or inclusive + `protocol/start-end` format (for example, `tcp/443` or `udp/10000-20000`). TCP + and UDP ports must be between 0 and 65535. support_domains: Support domains matched by the application. @@ -263,9 +273,11 @@ def list( self, *, account_id: str, + cursor: str | Omit = omit, fields: str | Omit = omit, filter: str | Omit = omit, limit: int | Omit = omit, + lookup: str | Omit = omit, offset: int | Omit = omit, order_by: str | Omit = omit, search: str | Omit = omit, @@ -275,24 +287,40 @@ def list( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> SyncSinglePage[ApplicationListResponse]: + ) -> SyncCursorPaginationAfter[ApplicationListResponse]: """ List the applications available to an account, both the applications Cloudflare curates and the custom applications the account has defined. - Results are paginated. Use `filter` and `search` to narrow the list, `order_by` - to sort it, and `fields` to reduce each result to only the properties you need. + Results are paginated. Page with `cursor` so that applications added or removed + between requests do not make other results repeat or go missing; `offset` paging + can repeat or miss results when the list changes between requests. Use `filter` + and `search` to narrow the list, `order_by` to sort it, and `fields` to reduce + each result to only the properties you need. Use `lookup` to find complete + application names mentioned in a rule sentence, ignoring case. Lookup does not + correct misspellings. It ranks matches by relevance and uses the same filters, + fields, and pagination as listing. `lookup` cannot be combined with `search`. + + Invalid UTF-8 or a NUL character (U+0000) in any query parameter name or value + returns `400`. The authenticated principal must have access to the account identified by `account_id`. Args: + cursor: Opaque value from `result_info.cursor` of the previous response. Returns the + results that follow it. Send the same `filter`, `search`, `lookup`, and + `order_by` values as the request that returned it; `limit` and `fields` may + change. An empty value is the same as no cursor. A modified cursor, or one used + with different values, returns `400`. + fields: Return only the listed properties on each application, as a comma-separated list. Use this to keep responses small when you only need part of each - application — for example populating a picker with `fields=id,name` instead of + application, for example populating a picker with `fields=id,name` instead of downloading every hostname and IP subnet. - Omit this parameter to receive the full application object. + Omit this parameter to receive the full application object, including when + lookup is used. `id` is always returned. @@ -303,32 +331,42 @@ def list( Unknown or empty property names return `400`. filter: - Filter applications using key:value format. Supported filter keys: - - - name: Filter by application name (e.g., name:HR) - - id: Filter by application ID (e.g., id:498) - - human_id: Filter by human-readable ID (e.g., human_id:HR) - - hostname: Filter by hostname or support domain (e.g., - hostname:portal.example.com) - - source: Filter by application source name (e.g., source:cloudflare) - - ip_subnet: Filter by IP subnet using CIDR containment — returns applications - where any stored subnet contains the search value (e.g., ip_subnet:10.0.1.5/32 - matches apps with 10.0.0.0/16) - - category_id: Filter by category ID (e.g., category_id:12). - - category_name: Filter by category name (e.g., category_name:HR). - - supported: Filter by supported Cloudflare product (e.g., supported:ACCESS). - Values: GATEWAY, ACCESS, CASB. - - review_status: Filter by the account's Gateway review status. Values: - approved, unapproved, in_review, unreviewed. . - - limit: Limit of number of results to return (max 250). - - offset: Offset of results to return. + Filter applications using `key:value` format. Supported filter keys: + + - `name`: application name (for example, `name:HR`). + - `id`: application ID (for example, `id:498`). + - `human_id`: human-readable ID (for example, `human_id:HR`). + - `hostname`: hostname or support domain (for example, + `hostname:portal.example.com`). + - `source`: application source name (for example, `source:cloudflare`). + - `ip_subnet`: CIDR containment; returns applications where a stored subnet + contains the search value (for example, `ip_subnet:10.0.1.5/32` matches + `10.0.0.0/16`). + - `category_id`: category ID (for example, `category_id:12`). + - `category_name`: category name (for example, `category_name:HR`). + - `supported`: supported Cloudflare product. Values: `GATEWAY`, `ACCESS`, + `CASB`. + - `review_status`: account-specific Gateway review status. Values: `approved`, + `unapproved`, `in_review`, `unreviewed`. + + limit: Number of results to return. Defaults to 25; values are clamped to 1–250. + + lookup: Find complete, case-insensitive application name mentions in a phrase or rule + sentence. Misspelled names do not match. Returns matching applications ranked by + relevance. Must be between 2 and 1000 characters, with no control characters + other than tab and line breaks. Uses the same filters, fields, and pagination as + listing. `search` cannot be combined with lookup. Results are ranked by + relevance, so `order_by` is ignored. To keep the text out of URLs, send it to + `POST .../applications/lookup` instead. + + offset: Number of results to skip. Defaults to 0; negative values are clamped to 0. + Ignored when `cursor` is provided. order_by: Order results using field:direction format. Supported fields are name, id, human_id, category_id, application_type, application_confidence_score, and gen_ai_score. Supported directions are asc and desc. Ignored when search is - provided; results are ranked by relevance instead. + provided; results are ranked by relevance instead. Also ignored when lookup is + provided. search: Fuzzy search across application name and hostnames. Results are ranked by relevance. Must be between 2 and 200 characters. Can be combined with filter @@ -346,7 +384,7 @@ def list( raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") return self._get_api_list( path_template("/accounts/{account_id}/resource-library/applications", account_id=account_id), - page=SyncSinglePage[ApplicationListResponse], + page=SyncCursorPaginationAfter[ApplicationListResponse], options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, @@ -354,9 +392,11 @@ def list( timeout=timeout, query=maybe_transform( { + "cursor": cursor, "fields": fields, "filter": filter, "limit": limit, + "lookup": lookup, "offset": offset, "order_by": order_by, "search": search, @@ -385,7 +425,7 @@ def delete( other resources reference the application. Args: - id: Returns the application ID. + id: Numeric identifier for the application. extra_headers: Send extra headers @@ -422,10 +462,10 @@ def get( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Optional[ApplicationGetResponse]: """ - Get application by ID. + Retrieve an application available to the account by its numeric application ID. Args: - id: Returns the application ID. + id: Numeric identifier for the application. extra_headers: Send extra headers @@ -490,22 +530,25 @@ async def create( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Optional[ApplicationCreateResponse]: """ - Create a custom application for an account. + Create a custom application for an account from a name, category, and optional + network matchers. Args: hostnames: Hostnames matched by the application. - category_id: Returns the category ID. + category_id: Numeric identifier for an application category. - human_id: Returns the human readable ID. + human_id: Human-readable identifier for the application. ip_subnets: IP subnets for this application. Custom application create and update requests accept IPv4 prefix lengths /8 through /32 and IPv6 prefix lengths /32 through /128. - name: Returns the application name. + name: Application name. - port_protocols: Port and protocol pairs matched by the application. + port_protocols: Ports matched by the application, in `protocol/port` or inclusive + `protocol/start-end` format (for example, `tcp/443` or `udp/10000-20000`). TCP + and UDP ports must be between 0 and 65535. support_domains: Support domains matched by the application. @@ -539,22 +582,25 @@ async def create( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Optional[ApplicationCreateResponse]: """ - Create a custom application for an account. + Create a custom application for an account from a name, category, and optional + network matchers. Args: ip_subnets: IP subnets for this application. Custom application create and update requests accept IPv4 prefix lengths /8 through /32 and IPv6 prefix lengths /32 through /128. - category_id: Returns the category ID. + category_id: Numeric identifier for an application category. hostnames: Hostnames matched by the application. - human_id: Returns the human readable ID. + human_id: Human-readable identifier for the application. - name: Returns the application name. + name: Application name. - port_protocols: Port and protocol pairs matched by the application. + port_protocols: Ports matched by the application, in `protocol/port` or inclusive + `protocol/start-end` format (for example, `tcp/443` or `udp/10000-20000`). TCP + and UDP ports must be between 0 and 65535. support_domains: Support domains matched by the application. @@ -630,10 +676,12 @@ async def update( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Optional[ApplicationUpdateResponse]: """ - Replace the network matchers for a custom application and create a new version. + Replace the supplied network matchers for a custom application and create a new + version. Omitted matcher lists remain unchanged; send an empty list to clear a + matcher type. Args: - id: Returns the application ID. + id: Numeric identifier for the application. hostnames: Hostnames matched by the application. @@ -641,7 +689,9 @@ async def update( accept IPv4 prefix lengths /8 through /32 and IPv6 prefix lengths /32 through /128. - port_protocols: Port and protocol pairs matched by the application. + port_protocols: Ports matched by the application, in `protocol/port` or inclusive + `protocol/start-end` format (for example, `tcp/443` or `udp/10000-20000`). TCP + and UDP ports must be between 0 and 65535. support_domains: Support domains matched by the application. @@ -680,9 +730,11 @@ def list( self, *, account_id: str, + cursor: str | Omit = omit, fields: str | Omit = omit, filter: str | Omit = omit, limit: int | Omit = omit, + lookup: str | Omit = omit, offset: int | Omit = omit, order_by: str | Omit = omit, search: str | Omit = omit, @@ -692,24 +744,40 @@ def list( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> AsyncPaginator[ApplicationListResponse, AsyncSinglePage[ApplicationListResponse]]: + ) -> AsyncPaginator[ApplicationListResponse, AsyncCursorPaginationAfter[ApplicationListResponse]]: """ List the applications available to an account, both the applications Cloudflare curates and the custom applications the account has defined. - Results are paginated. Use `filter` and `search` to narrow the list, `order_by` - to sort it, and `fields` to reduce each result to only the properties you need. + Results are paginated. Page with `cursor` so that applications added or removed + between requests do not make other results repeat or go missing; `offset` paging + can repeat or miss results when the list changes between requests. Use `filter` + and `search` to narrow the list, `order_by` to sort it, and `fields` to reduce + each result to only the properties you need. Use `lookup` to find complete + application names mentioned in a rule sentence, ignoring case. Lookup does not + correct misspellings. It ranks matches by relevance and uses the same filters, + fields, and pagination as listing. `lookup` cannot be combined with `search`. + + Invalid UTF-8 or a NUL character (U+0000) in any query parameter name or value + returns `400`. The authenticated principal must have access to the account identified by `account_id`. Args: + cursor: Opaque value from `result_info.cursor` of the previous response. Returns the + results that follow it. Send the same `filter`, `search`, `lookup`, and + `order_by` values as the request that returned it; `limit` and `fields` may + change. An empty value is the same as no cursor. A modified cursor, or one used + with different values, returns `400`. + fields: Return only the listed properties on each application, as a comma-separated list. Use this to keep responses small when you only need part of each - application — for example populating a picker with `fields=id,name` instead of + application, for example populating a picker with `fields=id,name` instead of downloading every hostname and IP subnet. - Omit this parameter to receive the full application object. + Omit this parameter to receive the full application object, including when + lookup is used. `id` is always returned. @@ -720,32 +788,42 @@ def list( Unknown or empty property names return `400`. filter: - Filter applications using key:value format. Supported filter keys: - - - name: Filter by application name (e.g., name:HR) - - id: Filter by application ID (e.g., id:498) - - human_id: Filter by human-readable ID (e.g., human_id:HR) - - hostname: Filter by hostname or support domain (e.g., - hostname:portal.example.com) - - source: Filter by application source name (e.g., source:cloudflare) - - ip_subnet: Filter by IP subnet using CIDR containment — returns applications - where any stored subnet contains the search value (e.g., ip_subnet:10.0.1.5/32 - matches apps with 10.0.0.0/16) - - category_id: Filter by category ID (e.g., category_id:12). - - category_name: Filter by category name (e.g., category_name:HR). - - supported: Filter by supported Cloudflare product (e.g., supported:ACCESS). - Values: GATEWAY, ACCESS, CASB. - - review_status: Filter by the account's Gateway review status. Values: - approved, unapproved, in_review, unreviewed. . - - limit: Limit of number of results to return (max 250). - - offset: Offset of results to return. + Filter applications using `key:value` format. Supported filter keys: + + - `name`: application name (for example, `name:HR`). + - `id`: application ID (for example, `id:498`). + - `human_id`: human-readable ID (for example, `human_id:HR`). + - `hostname`: hostname or support domain (for example, + `hostname:portal.example.com`). + - `source`: application source name (for example, `source:cloudflare`). + - `ip_subnet`: CIDR containment; returns applications where a stored subnet + contains the search value (for example, `ip_subnet:10.0.1.5/32` matches + `10.0.0.0/16`). + - `category_id`: category ID (for example, `category_id:12`). + - `category_name`: category name (for example, `category_name:HR`). + - `supported`: supported Cloudflare product. Values: `GATEWAY`, `ACCESS`, + `CASB`. + - `review_status`: account-specific Gateway review status. Values: `approved`, + `unapproved`, `in_review`, `unreviewed`. + + limit: Number of results to return. Defaults to 25; values are clamped to 1–250. + + lookup: Find complete, case-insensitive application name mentions in a phrase or rule + sentence. Misspelled names do not match. Returns matching applications ranked by + relevance. Must be between 2 and 1000 characters, with no control characters + other than tab and line breaks. Uses the same filters, fields, and pagination as + listing. `search` cannot be combined with lookup. Results are ranked by + relevance, so `order_by` is ignored. To keep the text out of URLs, send it to + `POST .../applications/lookup` instead. + + offset: Number of results to skip. Defaults to 0; negative values are clamped to 0. + Ignored when `cursor` is provided. order_by: Order results using field:direction format. Supported fields are name, id, human_id, category_id, application_type, application_confidence_score, and gen_ai_score. Supported directions are asc and desc. Ignored when search is - provided; results are ranked by relevance instead. + provided; results are ranked by relevance instead. Also ignored when lookup is + provided. search: Fuzzy search across application name and hostnames. Results are ranked by relevance. Must be between 2 and 200 characters. Can be combined with filter @@ -763,7 +841,7 @@ def list( raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") return self._get_api_list( path_template("/accounts/{account_id}/resource-library/applications", account_id=account_id), - page=AsyncSinglePage[ApplicationListResponse], + page=AsyncCursorPaginationAfter[ApplicationListResponse], options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, @@ -771,9 +849,11 @@ def list( timeout=timeout, query=maybe_transform( { + "cursor": cursor, "fields": fields, "filter": filter, "limit": limit, + "lookup": lookup, "offset": offset, "order_by": order_by, "search": search, @@ -802,7 +882,7 @@ async def delete( other resources reference the application. Args: - id: Returns the application ID. + id: Numeric identifier for the application. extra_headers: Send extra headers @@ -839,10 +919,10 @@ async def get( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Optional[ApplicationGetResponse]: """ - Get application by ID. + Retrieve an application available to the account by its numeric application ID. Args: - id: Returns the application ID. + id: Numeric identifier for the application. extra_headers: Send extra headers diff --git a/src/cloudflare/resources/zero_trust/resource_library/categories.py b/src/cloudflare/resources/zero_trust/resource_library/categories.py index b26545e1d5c..0a7c3e4c11c 100644 --- a/src/cloudflare/resources/zero_trust/resource_library/categories.py +++ b/src/cloudflare/resources/zero_trust/resource_library/categories.py @@ -17,7 +17,7 @@ async_to_streamed_response_wrapper, ) from ...._wrappers import ResultWrapper -from ....pagination import SyncSinglePage, AsyncSinglePage +from ....pagination import SyncCursorPaginationAfter, AsyncCursorPaginationAfter from ...._base_client import AsyncPaginator, make_request_options from ....types.zero_trust.resource_library import category_list_params from ....types.zero_trust.resource_library.category_get_response import CategoryGetResponse @@ -50,6 +50,7 @@ def list( self, *, account_id: str, + cursor: str | Omit = omit, limit: int | Omit = omit, offset: int | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -58,14 +59,21 @@ def list( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> SyncSinglePage[CategoryListResponse]: + ) -> SyncCursorPaginationAfter[CategoryListResponse]: """ - List application categories. + List the categories available for classifying applications, ordered by name. + Results are paginated by `offset` or `cursor`. Args: - limit: Limit of number of results to return. + cursor: Opaque value from `result_info.cursor` of the previous response. Returns the + categories that follow it. `limit` may change between requests. An empty value + is the same as no cursor. A modified cursor, or one returned by a different + list, returns `400`. - offset: Offset of results to return. + limit: Number of results to return. Defaults to 25; values are clamped to 1–250. + + offset: Number of results to skip. Defaults to 0; negative values are clamped to 0. + Ignored when `cursor` is provided. extra_headers: Send extra headers @@ -79,7 +87,7 @@ def list( raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") return self._get_api_list( path_template("/accounts/{account_id}/resource-library/categories", account_id=account_id), - page=SyncSinglePage[CategoryListResponse], + page=SyncCursorPaginationAfter[CategoryListResponse], options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, @@ -87,6 +95,7 @@ def list( timeout=timeout, query=maybe_transform( { + "cursor": cursor, "limit": limit, "offset": offset, }, @@ -109,10 +118,10 @@ def get( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Optional[CategoryGetResponse]: """ - Get application category by ID. + Retrieve an application category by its numeric ID. Args: - id: Returns the category ID. + id: Numeric identifier for an application category. extra_headers: Send extra headers @@ -161,6 +170,7 @@ def list( self, *, account_id: str, + cursor: str | Omit = omit, limit: int | Omit = omit, offset: int | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -169,14 +179,21 @@ def list( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> AsyncPaginator[CategoryListResponse, AsyncSinglePage[CategoryListResponse]]: + ) -> AsyncPaginator[CategoryListResponse, AsyncCursorPaginationAfter[CategoryListResponse]]: """ - List application categories. + List the categories available for classifying applications, ordered by name. + Results are paginated by `offset` or `cursor`. Args: - limit: Limit of number of results to return. + cursor: Opaque value from `result_info.cursor` of the previous response. Returns the + categories that follow it. `limit` may change between requests. An empty value + is the same as no cursor. A modified cursor, or one returned by a different + list, returns `400`. + + limit: Number of results to return. Defaults to 25; values are clamped to 1–250. - offset: Offset of results to return. + offset: Number of results to skip. Defaults to 0; negative values are clamped to 0. + Ignored when `cursor` is provided. extra_headers: Send extra headers @@ -190,7 +207,7 @@ def list( raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") return self._get_api_list( path_template("/accounts/{account_id}/resource-library/categories", account_id=account_id), - page=AsyncSinglePage[CategoryListResponse], + page=AsyncCursorPaginationAfter[CategoryListResponse], options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, @@ -198,6 +215,7 @@ def list( timeout=timeout, query=maybe_transform( { + "cursor": cursor, "limit": limit, "offset": offset, }, @@ -220,10 +238,10 @@ async def get( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Optional[CategoryGetResponse]: """ - Get application category by ID. + Retrieve an application category by its numeric ID. Args: - id: Returns the category ID. + id: Numeric identifier for an application category. extra_headers: Send extra headers diff --git a/src/cloudflare/resources/zero_trust/tunnels/warp_connector/configurations.py b/src/cloudflare/resources/zero_trust/tunnels/warp_connector/configurations.py index ca3c763cf2a..d450b197b3e 100644 --- a/src/cloudflare/resources/zero_trust/tunnels/warp_connector/configurations.py +++ b/src/cloudflare/resources/zero_trust/tunnels/warp_connector/configurations.py @@ -61,17 +61,17 @@ def update( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Optional[ConfigurationUpdateResponse]: """ - Adds or updates the high-availability configuration for a WARP Connector tunnel. + Adds or updates the high-availability configuration for a Mesh node. Args: account_id: Identifier. tunnel_id: UUID of the tunnel. - ha_mode: High-availability mode for the WARP Connector tunnel. `none` means HA is enabled - but no provider is configured yet (newly created tunnels default to this). - `disabled` means HA is explicitly turned off. `aws` uses AWS ENI move for - failover. `local` uses virtual IPs (VIPs) on the local interface. + ha_mode: High-availability mode for the Mesh node. `none` means HA is enabled but no + provider is configured yet (newly created nodes default to this). `disabled` + means HA is explicitly turned off. `aws` uses AWS ENI move for failover. `local` + uses virtual IPs (VIPs) on the local interface. config: Provider-specific configuration. Required shape depends on ha_mode. For `aws`, must contain `fnr_id`. For `local`, must contain `vips`. For `none` and @@ -125,7 +125,7 @@ def get( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Optional[ConfigurationGetResponse]: """ - Gets the high-availability configuration for a WARP Connector tunnel. + Gets the high-availability configuration for a Mesh node. Args: account_id: Identifier. @@ -196,17 +196,17 @@ async def update( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Optional[ConfigurationUpdateResponse]: """ - Adds or updates the high-availability configuration for a WARP Connector tunnel. + Adds or updates the high-availability configuration for a Mesh node. Args: account_id: Identifier. tunnel_id: UUID of the tunnel. - ha_mode: High-availability mode for the WARP Connector tunnel. `none` means HA is enabled - but no provider is configured yet (newly created tunnels default to this). - `disabled` means HA is explicitly turned off. `aws` uses AWS ENI move for - failover. `local` uses virtual IPs (VIPs) on the local interface. + ha_mode: High-availability mode for the Mesh node. `none` means HA is enabled but no + provider is configured yet (newly created nodes default to this). `disabled` + means HA is explicitly turned off. `aws` uses AWS ENI move for failover. `local` + uses virtual IPs (VIPs) on the local interface. config: Provider-specific configuration. Required shape depends on ha_mode. For `aws`, must contain `fnr_id`. For `local`, must contain `vips`. For `none` and @@ -260,7 +260,7 @@ async def get( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Optional[ConfigurationGetResponse]: """ - Gets the high-availability configuration for a WARP Connector tunnel. + Gets the high-availability configuration for a Mesh node. Args: account_id: Identifier. diff --git a/src/cloudflare/resources/zero_trust/tunnels/warp_connector/connections.py b/src/cloudflare/resources/zero_trust/tunnels/warp_connector/connections.py index 11716e5ceac..4421de49c6d 100644 --- a/src/cloudflare/resources/zero_trust/tunnels/warp_connector/connections.py +++ b/src/cloudflare/resources/zero_trust/tunnels/warp_connector/connections.py @@ -54,7 +54,7 @@ def get( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> SyncSinglePage[ConnectionGetResponse]: """ - Fetches connection details for a WARP Connector Tunnel. + Lists connection details for a Mesh node. Args: account_id: Cloudflare account ID @@ -120,7 +120,7 @@ def get( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> AsyncPaginator[ConnectionGetResponse, AsyncSinglePage[ConnectionGetResponse]]: """ - Fetches connection details for a WARP Connector Tunnel. + Lists connection details for a Mesh node. Args: account_id: Cloudflare account ID diff --git a/src/cloudflare/resources/zero_trust/tunnels/warp_connector/connectors.py b/src/cloudflare/resources/zero_trust/tunnels/warp_connector/connectors.py index 27b2db82fd3..315509e2c4b 100644 --- a/src/cloudflare/resources/zero_trust/tunnels/warp_connector/connectors.py +++ b/src/cloudflare/resources/zero_trust/tunnels/warp_connector/connectors.py @@ -57,7 +57,7 @@ def get( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> ConnectorGetResponse: """ - Fetches connector and connection details for a WARP Connector Tunnel. + Fetches connector and connection details for a Mesh node. Args: account_id: Cloudflare account ID @@ -132,7 +132,7 @@ async def get( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> ConnectorGetResponse: """ - Fetches connector and connection details for a WARP Connector Tunnel. + Fetches connector and connection details for a Mesh node. Args: account_id: Cloudflare account ID diff --git a/src/cloudflare/resources/zero_trust/tunnels/warp_connector/failover.py b/src/cloudflare/resources/zero_trust/tunnels/warp_connector/failover.py index 5aaf1805ce8..7af8a8ac60b 100644 --- a/src/cloudflare/resources/zero_trust/tunnels/warp_connector/failover.py +++ b/src/cloudflare/resources/zero_trust/tunnels/warp_connector/failover.py @@ -57,8 +57,8 @@ def update( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> object: """ - Triggers a manual failover for a specific WARP Connector Tunnel, setting the - specified client as the active connector. The tunnel must be configured for high + Triggers a manual failover for a specific Mesh node, setting the specified + client as the active connector. The tunnel must be configured for high availability (HA) and the client must be linked to the tunnel. Args: @@ -130,8 +130,8 @@ async def update( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> object: """ - Triggers a manual failover for a specific WARP Connector Tunnel, setting the - specified client as the active connector. The tunnel must be configured for high + Triggers a manual failover for a specific Mesh node, setting the specified + client as the active connector. The tunnel must be configured for high availability (HA) and the client must be linked to the tunnel. Args: diff --git a/src/cloudflare/resources/zero_trust/tunnels/warp_connector/token.py b/src/cloudflare/resources/zero_trust/tunnels/warp_connector/token.py index 1d5fb558c88..155fda4bb47 100644 --- a/src/cloudflare/resources/zero_trust/tunnels/warp_connector/token.py +++ b/src/cloudflare/resources/zero_trust/tunnels/warp_connector/token.py @@ -56,8 +56,7 @@ def get( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> str: """ - Gets the token used to associate warp device with a specific Warp Connector - tunnel. + Gets the token used to associate a WARP device with a specific Mesh node. Args: account_id: Cloudflare account ID @@ -124,8 +123,7 @@ async def get( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> str: """ - Gets the token used to associate warp device with a specific Warp Connector - tunnel. + Gets the token used to associate a WARP device with a specific Mesh node. Args: account_id: Cloudflare account ID diff --git a/src/cloudflare/resources/zero_trust/tunnels/warp_connector/warp_connector.py b/src/cloudflare/resources/zero_trust/tunnels/warp_connector/warp_connector.py index d6f5d4609b5..e0707305566 100644 --- a/src/cloudflare/resources/zero_trust/tunnels/warp_connector/warp_connector.py +++ b/src/cloudflare/resources/zero_trust/tunnels/warp_connector/warp_connector.py @@ -129,7 +129,7 @@ def create( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> WARPConnectorCreateResponse: """ - Creates a new Warp Connector Tunnel in an account. + Creates a new Mesh node in an account. Args: account_id: Cloudflare account ID @@ -191,7 +191,7 @@ def list( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> SyncV4PagePaginationArray[WARPConnectorListResponse]: """ - Lists and filters Warp Connector Tunnels in an account. + Lists and filters Mesh nodes in an account. Args: account_id: Cloudflare account ID @@ -266,7 +266,7 @@ def delete( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> WARPConnectorDeleteResponse: """ - Deletes a Warp Connector Tunnel from an account. + Deletes a Mesh node from an account. Args: account_id: Cloudflare account ID @@ -314,7 +314,7 @@ def edit( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> WARPConnectorEditResponse: """ - Updates an existing Warp Connector Tunnel. + Updates an existing Mesh node. Args: account_id: Cloudflare account ID @@ -372,7 +372,7 @@ def get( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> WARPConnectorGetResponse: """ - Fetches a single Warp Connector Tunnel. + Fetches a single Mesh node. Args: account_id: Cloudflare account ID @@ -460,7 +460,7 @@ async def create( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> WARPConnectorCreateResponse: """ - Creates a new Warp Connector Tunnel in an account. + Creates a new Mesh node in an account. Args: account_id: Cloudflare account ID @@ -522,7 +522,7 @@ def list( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> AsyncPaginator[WARPConnectorListResponse, AsyncV4PagePaginationArray[WARPConnectorListResponse]]: """ - Lists and filters Warp Connector Tunnels in an account. + Lists and filters Mesh nodes in an account. Args: account_id: Cloudflare account ID @@ -597,7 +597,7 @@ async def delete( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> WARPConnectorDeleteResponse: """ - Deletes a Warp Connector Tunnel from an account. + Deletes a Mesh node from an account. Args: account_id: Cloudflare account ID @@ -645,7 +645,7 @@ async def edit( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> WARPConnectorEditResponse: """ - Updates an existing Warp Connector Tunnel. + Updates an existing Mesh node. Args: account_id: Cloudflare account ID @@ -703,7 +703,7 @@ async def get( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> WARPConnectorGetResponse: """ - Fetches a single Warp Connector Tunnel. + Fetches a single Mesh node. Args: account_id: Cloudflare account ID diff --git a/src/cloudflare/resources/zero_trust/zero_trust.py b/src/cloudflare/resources/zero_trust/zero_trust.py index 8e3d695b129..09fd458a048 100644 --- a/src/cloudflare/resources/zero_trust/zero_trust.py +++ b/src/cloudflare/resources/zero_trust/zero_trust.py @@ -10,6 +10,14 @@ SeatsResourceWithStreamingResponse, AsyncSeatsResourceWithStreamingResponse, ) +from .cws.cws import ( + CWSResource, + AsyncCWSResource, + CWSResourceWithRawResponse, + AsyncCWSResourceWithRawResponse, + CWSResourceWithStreamingResponse, + AsyncCWSResourceWithStreamingResponse, +) from .dex.dex import ( DEXResource, AsyncDEXResource, @@ -121,6 +129,10 @@ class ZeroTrustResource(SyncAPIResource): + @cached_property + def cws(self) -> CWSResource: + return CWSResource(self._client) + @cached_property def devices(self) -> DevicesResource: return DevicesResource(self._client) @@ -198,6 +210,10 @@ def with_streaming_response(self) -> ZeroTrustResourceWithStreamingResponse: class AsyncZeroTrustResource(AsyncAPIResource): + @cached_property + def cws(self) -> AsyncCWSResource: + return AsyncCWSResource(self._client) + @cached_property def devices(self) -> AsyncDevicesResource: return AsyncDevicesResource(self._client) @@ -278,6 +294,10 @@ class ZeroTrustResourceWithRawResponse: def __init__(self, zero_trust: ZeroTrustResource) -> None: self._zero_trust = zero_trust + @cached_property + def cws(self) -> CWSResourceWithRawResponse: + return CWSResourceWithRawResponse(self._zero_trust.cws) + @cached_property def devices(self) -> DevicesResourceWithRawResponse: return DevicesResourceWithRawResponse(self._zero_trust.devices) @@ -339,6 +359,10 @@ class AsyncZeroTrustResourceWithRawResponse: def __init__(self, zero_trust: AsyncZeroTrustResource) -> None: self._zero_trust = zero_trust + @cached_property + def cws(self) -> AsyncCWSResourceWithRawResponse: + return AsyncCWSResourceWithRawResponse(self._zero_trust.cws) + @cached_property def devices(self) -> AsyncDevicesResourceWithRawResponse: return AsyncDevicesResourceWithRawResponse(self._zero_trust.devices) @@ -400,6 +424,10 @@ class ZeroTrustResourceWithStreamingResponse: def __init__(self, zero_trust: ZeroTrustResource) -> None: self._zero_trust = zero_trust + @cached_property + def cws(self) -> CWSResourceWithStreamingResponse: + return CWSResourceWithStreamingResponse(self._zero_trust.cws) + @cached_property def devices(self) -> DevicesResourceWithStreamingResponse: return DevicesResourceWithStreamingResponse(self._zero_trust.devices) @@ -461,6 +489,10 @@ class AsyncZeroTrustResourceWithStreamingResponse: def __init__(self, zero_trust: AsyncZeroTrustResource) -> None: self._zero_trust = zero_trust + @cached_property + def cws(self) -> AsyncCWSResourceWithStreamingResponse: + return AsyncCWSResourceWithStreamingResponse(self._zero_trust.cws) + @cached_property def devices(self) -> AsyncDevicesResourceWithStreamingResponse: return AsyncDevicesResourceWithStreamingResponse(self._zero_trust.devices) diff --git a/src/cloudflare/types/__init__.py b/src/cloudflare/types/__init__.py index 4bd930b6415..0e826dc95dd 100644 --- a/src/cloudflare/types/__init__.py +++ b/src/cloudflare/types/__init__.py @@ -23,7 +23,6 @@ PermissionGrant as PermissionGrant, CloudflareTunnel as CloudflareTunnel, SubscriptionZone as SubscriptionZone, - LoadBalancerPreview as LoadBalancerPreview, SubscriptionComponent as SubscriptionComponent, CertificateRequestType as CertificateRequestType, TokenConditionCIDRList as TokenConditionCIDRList, diff --git a/src/cloudflare/types/abuse_reports/abuse_report_create_params.py b/src/cloudflare/types/abuse_reports/abuse_report_create_params.py index 69e21aeea82..078aec019d5 100644 --- a/src/cloudflare/types/abuse_reports/abuse_report_create_params.py +++ b/src/cloudflare/types/abuse_reports/abuse_report_create_params.py @@ -69,6 +69,8 @@ class AbuseReportsDmcaReport(TypedDict, total=False): host_notification: Required[Literal["send"]] """Notification type based on the abuse type. + For delegated reports, the report—including contact information and + comments—will be forwarded to the customer in full regardless of this value. NOTE: Copyright (DMCA) and Trademark reports cannot be anonymous. """ @@ -89,6 +91,8 @@ class AbuseReportsDmcaReport(TypedDict, total=False): owner_notification: Required[Literal["send"]] """Notification type based on the abuse type. + For delegated reports, the report—including contact information and + comments—will be forwarded to the customer in full regardless of this value. NOTE: Copyright (DMCA) and Trademark reports cannot be anonymous. """ @@ -115,7 +119,12 @@ class AbuseReportsDmcaReport(TypedDict, total=False): """ comments: str - """Any additional comments about the infringement not exceeding 2000 characters""" + """Any additional comments about the infringement not exceeding 2000 characters. + + Comments are kept internal to Cloudflare and not shared with the host or + customer as part of regular processing. For delegated reports, comments may be + shared in full. + """ company: str """Text not exceeding 100 characters. @@ -160,6 +169,8 @@ class AbuseReportsTrademarkReport(TypedDict, total=False): host_notification: Required[Literal["send"]] """Notification type based on the abuse type. + For delegated reports, the report—including contact information and + comments—will be forwarded to the customer in full regardless of this value. NOTE: Copyright (DMCA) and Trademark reports cannot be anonymous. """ @@ -180,6 +191,8 @@ class AbuseReportsTrademarkReport(TypedDict, total=False): owner_notification: Required[Literal["send"]] """Notification type based on the abuse type. + For delegated reports, the report—including contact information and + comments—will be forwarded to the customer in full regardless of this value. NOTE: Copyright (DMCA) and Trademark reports cannot be anonymous. """ @@ -201,7 +214,12 @@ class AbuseReportsTrademarkReport(TypedDict, total=False): """ comments: str - """Any additional comments about the infringement not exceeding 2000 characters""" + """Any additional comments about the infringement not exceeding 2000 characters. + + Comments are kept internal to Cloudflare and not shared with the host or + customer as part of regular processing. For delegated reports, comments may be + shared in full. + """ company: str """Text not exceeding 100 characters. @@ -246,6 +264,8 @@ class AbuseReportsGeneralReport(TypedDict, total=False): host_notification: Required[Literal["send", "send-anon"]] """Notification type based on the abuse type. + For delegated reports, the report—including contact information and + comments—will be forwarded to the customer in full regardless of this value. NOTE: Copyright (DMCA) and Trademark reports cannot be anonymous. """ @@ -266,6 +286,8 @@ class AbuseReportsGeneralReport(TypedDict, total=False): owner_notification: Required[Literal["send", "send-anon"]] """Notification type based on the abuse type. + For delegated reports, the report—including contact information and + comments—will be forwarded to the customer in full regardless of this value. NOTE: Copyright (DMCA) and Trademark reports cannot be anonymous. """ @@ -278,7 +300,12 @@ class AbuseReportsGeneralReport(TypedDict, total=False): """ comments: str - """Any additional comments about the infringement not exceeding 2000 characters""" + """Any additional comments about the infringement not exceeding 2000 characters. + + Comments are kept internal to Cloudflare and not shared with the host or + customer as part of regular processing. For delegated reports, comments may be + shared in full. + """ company: str """Text not exceeding 100 characters. @@ -345,6 +372,8 @@ class AbuseReportsPhishingReport(TypedDict, total=False): host_notification: Required[Literal["send", "send-anon"]] """Notification type based on the abuse type. + For delegated reports, the report—including contact information and + comments—will be forwarded to the customer in full regardless of this value. NOTE: Copyright (DMCA) and Trademark reports cannot be anonymous. """ @@ -365,6 +394,8 @@ class AbuseReportsPhishingReport(TypedDict, total=False): owner_notification: Required[Literal["send", "send-anon"]] """Notification type based on the abuse type. + For delegated reports, the report—including contact information and + comments—will be forwarded to the customer in full regardless of this value. NOTE: Copyright (DMCA) and Trademark reports cannot be anonymous. """ @@ -377,7 +408,12 @@ class AbuseReportsPhishingReport(TypedDict, total=False): """ comments: str - """Any additional comments about the infringement not exceeding 2000 characters""" + """Any additional comments about the infringement not exceeding 2000 characters. + + Comments are kept internal to Cloudflare and not shared with the host or + customer as part of regular processing. For delegated reports, comments may be + shared in full. + """ company: str """Text not exceeding 100 characters. @@ -429,6 +465,8 @@ class AbuseReportsCsamReport(TypedDict, total=False): host_notification: Required[Literal["send", "send-anon"]] """Notification type based on the abuse type. + For delegated reports, the report—including contact information and + comments—will be forwarded to the customer in full regardless of this value. NOTE: Copyright (DMCA) and Trademark reports cannot be anonymous. """ @@ -455,6 +493,8 @@ class AbuseReportsCsamReport(TypedDict, total=False): owner_notification: Required[Literal["send", "send-anon", "none"]] """Notification type based on the abuse type. + For delegated reports, the report—including contact information and + comments—will be forwarded to the customer in full regardless of this value. NOTE: Copyright (DMCA) and Trademark reports cannot be anonymous. """ @@ -467,7 +507,12 @@ class AbuseReportsCsamReport(TypedDict, total=False): """ comments: str - """Any additional comments about the infringement not exceeding 2000 characters""" + """Any additional comments about the infringement not exceeding 2000 characters. + + Comments are kept internal to Cloudflare and not shared with the host or + customer as part of regular processing. For delegated reports, comments may be + shared in full. + """ company: str """Text not exceeding 100 characters. @@ -519,6 +564,8 @@ class AbuseReportsThreatReport(TypedDict, total=False): host_notification: Required[Literal["send", "send-anon"]] """Notification type based on the abuse type. + For delegated reports, the report—including contact information and + comments—will be forwarded to the customer in full regardless of this value. NOTE: Copyright (DMCA) and Trademark reports cannot be anonymous. """ @@ -539,6 +586,8 @@ class AbuseReportsThreatReport(TypedDict, total=False): owner_notification: Required[Literal["send", "send-anon"]] """Notification type based on the abuse type. + For delegated reports, the report—including contact information and + comments—will be forwarded to the customer in full regardless of this value. NOTE: Copyright (DMCA) and Trademark reports cannot be anonymous. """ @@ -551,7 +600,12 @@ class AbuseReportsThreatReport(TypedDict, total=False): """ comments: str - """Any additional comments about the infringement not exceeding 2000 characters""" + """Any additional comments about the infringement not exceeding 2000 characters. + + Comments are kept internal to Cloudflare and not shared with the host or + customer as part of regular processing. For delegated reports, comments may be + shared in full. + """ company: str """Text not exceeding 100 characters. @@ -603,6 +657,8 @@ class AbuseReportsRegistrarWhoisReport(TypedDict, total=False): owner_notification: Required[Literal["send", "send-anon", "none"]] """Notification type based on the abuse type. + For delegated reports, the report—including contact information and + comments—will be forwarded to the customer in full regardless of this value. NOTE: Copyright (DMCA) and Trademark reports cannot be anonymous. """ @@ -615,7 +671,12 @@ class AbuseReportsRegistrarWhoisReport(TypedDict, total=False): """ comments: str - """Any additional comments about the infringement not exceeding 2000 characters""" + """Any additional comments about the infringement not exceeding 2000 characters. + + Comments are kept internal to Cloudflare and not shared with the host or + customer as part of regular processing. For delegated reports, comments may be + shared in full. + """ company: str """Text not exceeding 100 characters. @@ -719,6 +780,8 @@ class AbuseReportsNcseiReport(TypedDict, total=False): host_notification: Required[Literal["send", "send-anon"]] """Notification type based on the abuse type. + For delegated reports, the report—including contact information and + comments—will be forwarded to the customer in full regardless of this value. NOTE: Copyright (DMCA) and Trademark reports cannot be anonymous. """ @@ -735,6 +798,8 @@ class AbuseReportsNcseiReport(TypedDict, total=False): owner_notification: Required[Literal["send", "send-anon", "none"]] """Notification type based on the abuse type. + For delegated reports, the report—including contact information and + comments—will be forwarded to the customer in full regardless of this value. NOTE: Copyright (DMCA) and Trademark reports cannot be anonymous. """ @@ -747,7 +812,12 @@ class AbuseReportsNcseiReport(TypedDict, total=False): """ comments: str - """Any additional comments about the infringement not exceeding 2000 characters""" + """Any additional comments about the infringement not exceeding 2000 characters. + + Comments are kept internal to Cloudflare and not shared with the host or + customer as part of regular processing. For delegated reports, comments may be + shared in full. + """ company: str """Text not exceeding 100 characters. diff --git a/src/cloudflare/types/abuse_reports/abuse_report_get_response.py b/src/cloudflare/types/abuse_reports/abuse_report_get_response.py index 3cbe3920820..12741306a0e 100644 --- a/src/cloudflare/types/abuse_reports/abuse_report_get_response.py +++ b/src/cloudflare/types/abuse_reports/abuse_report_get_response.py @@ -61,6 +61,12 @@ class AbuseReportGetResponse(BaseModel): type: Literal["PHISH", "GEN", "THREAT", "DMCA", "EMER", "TM", "REG_WHO", "NCSEI", "NETWORK"] """The abuse report type""" + has_pending_notice: Optional[bool] = None + """ + Whether the report is in an open Notice and Takedown notice period: no + mitigation is placed yet, but one will take effect when the period ends. + """ + justification: Optional[str] = None """Justification for the report.""" diff --git a/src/cloudflare/types/abuse_reports/abuse_report_list_params.py b/src/cloudflare/types/abuse_reports/abuse_report_list_params.py index 94ececff967..e434b736b2a 100644 --- a/src/cloudflare/types/abuse_reports/abuse_report_list_params.py +++ b/src/cloudflare/types/abuse_reports/abuse_report_list_params.py @@ -25,9 +25,24 @@ class AbuseReportListParams(TypedDict, total=False): page: int """Where in pagination to start listing abuse reports""" + pending_notice: bool + """Also include reports in an open Notice and Takedown notice period. + + Combined with mitigation_status using OR, e.g. + ?mitigation_status=active&pending_notice=true. + """ + per_page: int """How many abuse reports per page to list""" + search: str + """Free-text search. + + Returns reports whose report ID starts with the term or whose domain contains + the term, both case-insensitively. Surrounding whitespace is ignored, and an + empty value is treated as absent. Combined with the other filters using AND. + """ + sort: str """A property to sort by, followed by the order (id, cdate, domain, type, status)""" diff --git a/src/cloudflare/types/abuse_reports/abuse_report_list_response.py b/src/cloudflare/types/abuse_reports/abuse_report_list_response.py index 2bdeacfb26f..24312fec73d 100644 --- a/src/cloudflare/types/abuse_reports/abuse_report_list_response.py +++ b/src/cloudflare/types/abuse_reports/abuse_report_list_response.py @@ -61,6 +61,12 @@ class Report(BaseModel): type: Literal["PHISH", "GEN", "THREAT", "DMCA", "EMER", "TM", "REG_WHO", "NCSEI", "NETWORK"] """The abuse report type""" + has_pending_notice: Optional[bool] = None + """ + Whether the report is in an open Notice and Takedown notice period: no + mitigation is placed yet, but one will take effect when the period ends. + """ + justification: Optional[str] = None """Justification for the report.""" diff --git a/src/cloudflare/types/abuse_reports/mitigation_review_params.py b/src/cloudflare/types/abuse_reports/mitigation_review_params.py index c9abe38b750..29196330816 100644 --- a/src/cloudflare/types/abuse_reports/mitigation_review_params.py +++ b/src/cloudflare/types/abuse_reports/mitigation_review_params.py @@ -19,6 +19,12 @@ class MitigationReviewParams(TypedDict, total=False): data: Data """Counter-notice details supporting an appeal.""" + explanation: str + """ + Optional explanation for a "content_removed" appeal, such as how the content was + removed. Not accepted for other appeal types. + """ + type: Literal["counter_notice", "content_removed"] """The type of appeal being submitted.""" diff --git a/src/cloudflare/types/accounts/__init__.py b/src/cloudflare/types/accounts/__init__.py index edbff0594c2..b7ae87fd040 100644 --- a/src/cloudflare/types/accounts/__init__.py +++ b/src/cloudflare/types/accounts/__init__.py @@ -24,13 +24,11 @@ from .account_delete_response import AccountDeleteResponse as AccountDeleteResponse from .entitlement_list_response import EntitlementListResponse as EntitlementListResponse from .pay_invoice_create_params import PayInvoiceCreateParams as PayInvoiceCreateParams -from .pay_bad_debt_create_params import PayBadDebtCreateParams as PayBadDebtCreateParams from .payment_method_list_params import PaymentMethodListParams as PaymentMethodListParams from .subscription_create_params import SubscriptionCreateParams as SubscriptionCreateParams from .subscription_update_params import SubscriptionUpdateParams as SubscriptionUpdateParams from .pay_invoice_create_response import PayInvoiceCreateResponse as PayInvoiceCreateResponse from .payment_method_get_response import PaymentMethodGetResponse as PaymentMethodGetResponse -from .pay_bad_debt_create_response import PayBadDebtCreateResponse as PayBadDebtCreateResponse from .payment_method_create_params import PaymentMethodCreateParams as PaymentMethodCreateParams from .payment_method_list_response import PaymentMethodListResponse as PaymentMethodListResponse from .payment_method_update_params import PaymentMethodUpdateParams as PaymentMethodUpdateParams diff --git a/src/cloudflare/types/accounts/account.py b/src/cloudflare/types/accounts/account.py index 80d79581a44..d74da212f33 100644 --- a/src/cloudflare/types/accounts/account.py +++ b/src/cloudflare/types/accounts/account.py @@ -6,7 +6,36 @@ from ..._models import BaseModel -__all__ = ["Account", "ManagedBy", "Settings"] +__all__ = ["Account", "LegacyFlags", "LegacyFlagsEnterpriseZoneQuota", "ManagedBy", "Settings"] + + +class LegacyFlagsEnterpriseZoneQuota(BaseModel): + """Enterprise zone quota for standard and enterprise accounts. + + Accounts without a quota have a maximum of 0. + """ + + available: Optional[int] = None + """Number of additional Enterprise zones available. + + Returns 0 if the quota is not allocated or is exhausted. + """ + + current: Optional[int] = None + """Current number of Enterprise zones.""" + + maximum: Optional[int] = None + """Maximum number of Enterprise zones allowed.""" + + +class LegacyFlags(BaseModel): + """Legacy account flags.""" + + enterprise_zone_quota: Optional[LegacyFlagsEnterpriseZoneQuota] = None + """Enterprise zone quota for standard and enterprise accounts. + + Accounts without a quota have a maximum of 0. + """ class ManagedBy(BaseModel): @@ -18,6 +47,12 @@ class ManagedBy(BaseModel): parent_org_name: Optional[str] = None """Name of the parent Organization, if one exists""" + root_org_id: Optional[str] = None + """ID of the root Organization, if one exists""" + + should_display_parent_orgs: Optional[bool] = None + """Indicates whether the parent Organization hierarchy should be displayed""" + class Settings(BaseModel): """Account settings""" @@ -44,6 +79,9 @@ class Account(BaseModel): created_on: Optional[datetime] = None """Timestamp for the creation of the account""" + legacy_flags: Optional[LegacyFlags] = None + """Legacy account flags.""" + managed_by: Optional[ManagedBy] = None """Parent container details""" diff --git a/src/cloudflare/types/accounts/account_create_params.py b/src/cloudflare/types/accounts/account_create_params.py index 165710c9159..1632e2bd10d 100644 --- a/src/cloudflare/types/accounts/account_create_params.py +++ b/src/cloudflare/types/accounts/account_create_params.py @@ -11,7 +11,7 @@ class AccountCreateParams(TypedDict, total=False): name: Required[str] - """Account name""" + """Account name, limited to 65 UTF-8 bytes.""" standalone: Literal[True] """Set to `true` and omit `unit` to create a standalone Free Account. @@ -20,6 +20,11 @@ class AccountCreateParams(TypedDict, total=False): """ type: Literal["standard", "enterprise"] + """the type of account being created. + + For self-serve customers, use standard. for enterprise customers, use + enterprise. + """ unit: Unit """Information related to the tenant unit. diff --git a/src/cloudflare/types/accounts/account_update_params.py b/src/cloudflare/types/accounts/account_update_params.py index d0cb3859d99..42aeedae9f6 100644 --- a/src/cloudflare/types/accounts/account_update_params.py +++ b/src/cloudflare/types/accounts/account_update_params.py @@ -15,7 +15,7 @@ class AccountUpdateParams(TypedDict, total=False): """Identifier""" name: Required[str] - """Account name""" + """Account name, limited to 65 UTF-8 bytes.""" type: Required[Literal["standard", "enterprise"]] diff --git a/src/cloudflare/types/accounts/pay_bad_debt_create_params.py b/src/cloudflare/types/accounts/pay_bad_debt_create_params.py deleted file mode 100644 index 3a0958a8cf2..00000000000 --- a/src/cloudflare/types/accounts/pay_bad_debt_create_params.py +++ /dev/null @@ -1,15 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing_extensions import Required, TypedDict - -__all__ = ["PayBadDebtCreateParams"] - - -class PayBadDebtCreateParams(TypedDict, total=False): - account_id: Required[str] - """Identifier""" - - payment_method_id: str - """The payment method to use. If omitted, the default payment method is used.""" diff --git a/src/cloudflare/types/accounts/pay_bad_debt_create_response.py b/src/cloudflare/types/accounts/pay_bad_debt_create_response.py deleted file mode 100644 index d403f6eaf15..00000000000 --- a/src/cloudflare/types/accounts/pay_bad_debt_create_response.py +++ /dev/null @@ -1,12 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from typing import Optional - -from ..._models import BaseModel - -__all__ = ["PayBadDebtCreateResponse"] - - -class PayBadDebtCreateResponse(BaseModel): - client_secret: Optional[str] = None - """The Stripe client secret for frontend payment confirmation.""" diff --git a/src/cloudflare/types/accounts/subscriptions/bulk_create_response.py b/src/cloudflare/types/accounts/subscriptions/bulk_create_response.py index 5d2ef46c71e..34fb31d51d0 100644 --- a/src/cloudflare/types/accounts/subscriptions/bulk_create_response.py +++ b/src/cloudflare/types/accounts/subscriptions/bulk_create_response.py @@ -1,8 +1,14 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import List -from typing_extensions import TypeAlias +from typing import List, Optional + +from ...._models import BaseModel +from ...shared.subscription import Subscription __all__ = ["BulkCreateResponse"] -BulkCreateResponse: TypeAlias = List[object] + +class BulkCreateResponse(BaseModel): + client_secrets: Optional[List[str]] = None + + subscriptions: Optional[List[Subscription]] = None diff --git a/src/cloudflare/types/accounts/token_create_response.py b/src/cloudflare/types/accounts/token_create_response.py index 36357223476..3ca3f8d9d40 100644 --- a/src/cloudflare/types/accounts/token_create_response.py +++ b/src/cloudflare/types/accounts/token_create_response.py @@ -81,5 +81,19 @@ class TokenCreateResponse(BaseModel): status: Optional[Literal["active", "disabled", "expired"]] = None """Status of the token.""" + token_prefix: Optional[str] = None + """The prefix of the token value, before the first underscore. + + Use it with `token_suffix` to identify a token. Only present for tokens created + or rolled after this field was added. + """ + + token_suffix: Optional[str] = None + """The last 4 characters of the token value. + + Use it with `token_prefix` to identify a token. It is not unique. Only present + for tokens created or rolled after this field was added. + """ + value: Optional[TokenValue] = None """The token value.""" diff --git a/src/cloudflare/types/ai_gateway/ai_gateway_create_params.py b/src/cloudflare/types/ai_gateway/ai_gateway_create_params.py index 44259a477fe..1fedeaf73e3 100644 --- a/src/cloudflare/types/ai_gateway/ai_gateway_create_params.py +++ b/src/cloudflare/types/ai_gateway/ai_gateway_create_params.py @@ -47,6 +47,11 @@ class AIGatewayCreateParams(TypedDict, total=False): rate_limiting_limit: Required[Optional[int]] authentication: bool + """Require authentication for gateway access. + + New gateways must have authentication enabled. Once enabled, authentication + cannot be disabled. + """ byok_only: bool """ @@ -84,6 +89,11 @@ class AIGatewayCreateParams(TypedDict, total=False): spend_limits: Optional[SpendLimits] store_id: Optional[str] + """Secrets Store used by this gateway. + + Omit on update to keep the current store. Cannot be cleared while stored keys or + secret references depend on it. + """ stripe: Optional[Stripe] @@ -140,6 +150,8 @@ class GuardrailsPrompt(TypedDict, total=False): s13: Annotated[Literal["FLAG", "BLOCK"], PropertyInfo(alias="S13")] + s14: Annotated[Literal["FLAG", "BLOCK"], PropertyInfo(alias="S14")] + s2: Annotated[Literal["FLAG", "BLOCK"], PropertyInfo(alias="S2")] s3: Annotated[Literal["FLAG", "BLOCK"], PropertyInfo(alias="S3")] @@ -170,6 +182,8 @@ class GuardrailsResponse(TypedDict, total=False): s13: Annotated[Literal["FLAG", "BLOCK"], PropertyInfo(alias="S13")] + s14: Annotated[Literal["FLAG", "BLOCK"], PropertyInfo(alias="S14")] + s2: Annotated[Literal["FLAG", "BLOCK"], PropertyInfo(alias="S2")] s3: Annotated[Literal["FLAG", "BLOCK"], PropertyInfo(alias="S3")] diff --git a/src/cloudflare/types/ai_gateway/ai_gateway_create_response.py b/src/cloudflare/types/ai_gateway/ai_gateway_create_response.py index 452c29fcf14..87a4e83de68 100644 --- a/src/cloudflare/types/ai_gateway/ai_gateway_create_response.py +++ b/src/cloudflare/types/ai_gateway/ai_gateway_create_response.py @@ -72,6 +72,8 @@ class GuardrailsPrompt(BaseModel): s13: Optional[Literal["FLAG", "BLOCK"]] = FieldInfo(alias="S13", default=None) + s14: Optional[Literal["FLAG", "BLOCK"]] = FieldInfo(alias="S14", default=None) + s2: Optional[Literal["FLAG", "BLOCK"]] = FieldInfo(alias="S2", default=None) s3: Optional[Literal["FLAG", "BLOCK"]] = FieldInfo(alias="S3", default=None) @@ -102,6 +104,8 @@ class GuardrailsResponse(BaseModel): s13: Optional[Literal["FLAG", "BLOCK"]] = FieldInfo(alias="S13", default=None) + s14: Optional[Literal["FLAG", "BLOCK"]] = FieldInfo(alias="S14", default=None) + s2: Optional[Literal["FLAG", "BLOCK"]] = FieldInfo(alias="S2", default=None) s3: Optional[Literal["FLAG", "BLOCK"]] = FieldInfo(alias="S3", default=None) @@ -215,6 +219,11 @@ class AIGatewayCreateResponse(BaseModel): rate_limiting_limit: Optional[int] = None authentication: Optional[bool] = None + """Require authentication for gateway access. + + New gateways must have authentication enabled. Once enabled, authentication + cannot be disabled. + """ byok_only: Optional[bool] = None """ @@ -224,6 +233,16 @@ class AIGatewayCreateResponse(BaseModel): dlp: Optional[DLP] = None + fedramp_level: Optional[Literal["fedramp-medium", "fedramp-high"]] = None + """FedRAMP compliance level: fedramp-medium or fedramp-high.""" + + fedramp_mode: Optional[Literal["prefer", "require"]] = None + """FedRAMP enforcement mode. + + "prefer" prioritizes compliant connectors but allows fallback. "require" + strictly filters. + """ + guardrails: Optional[Guardrails] = None is_default: Optional[bool] = None @@ -254,6 +273,11 @@ class AIGatewayCreateResponse(BaseModel): spend_limits: Optional[SpendLimits] = None store_id: Optional[str] = None + """Secrets Store used by this gateway. + + Omit on update to keep the current store. Cannot be cleared while stored keys or + secret references depend on it. + """ stripe: Optional[Stripe] = None diff --git a/src/cloudflare/types/ai_gateway/ai_gateway_delete_response.py b/src/cloudflare/types/ai_gateway/ai_gateway_delete_response.py index af17f64f7b6..7fdd5cd7035 100644 --- a/src/cloudflare/types/ai_gateway/ai_gateway_delete_response.py +++ b/src/cloudflare/types/ai_gateway/ai_gateway_delete_response.py @@ -72,6 +72,8 @@ class GuardrailsPrompt(BaseModel): s13: Optional[Literal["FLAG", "BLOCK"]] = FieldInfo(alias="S13", default=None) + s14: Optional[Literal["FLAG", "BLOCK"]] = FieldInfo(alias="S14", default=None) + s2: Optional[Literal["FLAG", "BLOCK"]] = FieldInfo(alias="S2", default=None) s3: Optional[Literal["FLAG", "BLOCK"]] = FieldInfo(alias="S3", default=None) @@ -102,6 +104,8 @@ class GuardrailsResponse(BaseModel): s13: Optional[Literal["FLAG", "BLOCK"]] = FieldInfo(alias="S13", default=None) + s14: Optional[Literal["FLAG", "BLOCK"]] = FieldInfo(alias="S14", default=None) + s2: Optional[Literal["FLAG", "BLOCK"]] = FieldInfo(alias="S2", default=None) s3: Optional[Literal["FLAG", "BLOCK"]] = FieldInfo(alias="S3", default=None) @@ -215,6 +219,11 @@ class AIGatewayDeleteResponse(BaseModel): rate_limiting_limit: Optional[int] = None authentication: Optional[bool] = None + """Require authentication for gateway access. + + New gateways must have authentication enabled. Once enabled, authentication + cannot be disabled. + """ byok_only: Optional[bool] = None """ @@ -224,6 +233,16 @@ class AIGatewayDeleteResponse(BaseModel): dlp: Optional[DLP] = None + fedramp_level: Optional[Literal["fedramp-medium", "fedramp-high"]] = None + """FedRAMP compliance level: fedramp-medium or fedramp-high.""" + + fedramp_mode: Optional[Literal["prefer", "require"]] = None + """FedRAMP enforcement mode. + + "prefer" prioritizes compliant connectors but allows fallback. "require" + strictly filters. + """ + guardrails: Optional[Guardrails] = None is_default: Optional[bool] = None @@ -254,6 +273,11 @@ class AIGatewayDeleteResponse(BaseModel): spend_limits: Optional[SpendLimits] = None store_id: Optional[str] = None + """Secrets Store used by this gateway. + + Omit on update to keep the current store. Cannot be cleared while stored keys or + secret references depend on it. + """ stripe: Optional[Stripe] = None diff --git a/src/cloudflare/types/ai_gateway/ai_gateway_get_response.py b/src/cloudflare/types/ai_gateway/ai_gateway_get_response.py index ab833f60c42..f242a090648 100644 --- a/src/cloudflare/types/ai_gateway/ai_gateway_get_response.py +++ b/src/cloudflare/types/ai_gateway/ai_gateway_get_response.py @@ -72,6 +72,8 @@ class GuardrailsPrompt(BaseModel): s13: Optional[Literal["FLAG", "BLOCK"]] = FieldInfo(alias="S13", default=None) + s14: Optional[Literal["FLAG", "BLOCK"]] = FieldInfo(alias="S14", default=None) + s2: Optional[Literal["FLAG", "BLOCK"]] = FieldInfo(alias="S2", default=None) s3: Optional[Literal["FLAG", "BLOCK"]] = FieldInfo(alias="S3", default=None) @@ -102,6 +104,8 @@ class GuardrailsResponse(BaseModel): s13: Optional[Literal["FLAG", "BLOCK"]] = FieldInfo(alias="S13", default=None) + s14: Optional[Literal["FLAG", "BLOCK"]] = FieldInfo(alias="S14", default=None) + s2: Optional[Literal["FLAG", "BLOCK"]] = FieldInfo(alias="S2", default=None) s3: Optional[Literal["FLAG", "BLOCK"]] = FieldInfo(alias="S3", default=None) @@ -215,6 +219,11 @@ class AIGatewayGetResponse(BaseModel): rate_limiting_limit: Optional[int] = None authentication: Optional[bool] = None + """Require authentication for gateway access. + + New gateways must have authentication enabled. Once enabled, authentication + cannot be disabled. + """ byok_only: Optional[bool] = None """ @@ -224,6 +233,16 @@ class AIGatewayGetResponse(BaseModel): dlp: Optional[DLP] = None + fedramp_level: Optional[Literal["fedramp-medium", "fedramp-high"]] = None + """FedRAMP compliance level: fedramp-medium or fedramp-high.""" + + fedramp_mode: Optional[Literal["prefer", "require"]] = None + """FedRAMP enforcement mode. + + "prefer" prioritizes compliant connectors but allows fallback. "require" + strictly filters. + """ + guardrails: Optional[Guardrails] = None is_default: Optional[bool] = None @@ -254,6 +273,11 @@ class AIGatewayGetResponse(BaseModel): spend_limits: Optional[SpendLimits] = None store_id: Optional[str] = None + """Secrets Store used by this gateway. + + Omit on update to keep the current store. Cannot be cleared while stored keys or + secret references depend on it. + """ stripe: Optional[Stripe] = None diff --git a/src/cloudflare/types/ai_gateway/ai_gateway_list_response.py b/src/cloudflare/types/ai_gateway/ai_gateway_list_response.py index f57983ce085..e7fe9bace97 100644 --- a/src/cloudflare/types/ai_gateway/ai_gateway_list_response.py +++ b/src/cloudflare/types/ai_gateway/ai_gateway_list_response.py @@ -72,6 +72,8 @@ class GuardrailsPrompt(BaseModel): s13: Optional[Literal["FLAG", "BLOCK"]] = FieldInfo(alias="S13", default=None) + s14: Optional[Literal["FLAG", "BLOCK"]] = FieldInfo(alias="S14", default=None) + s2: Optional[Literal["FLAG", "BLOCK"]] = FieldInfo(alias="S2", default=None) s3: Optional[Literal["FLAG", "BLOCK"]] = FieldInfo(alias="S3", default=None) @@ -102,6 +104,8 @@ class GuardrailsResponse(BaseModel): s13: Optional[Literal["FLAG", "BLOCK"]] = FieldInfo(alias="S13", default=None) + s14: Optional[Literal["FLAG", "BLOCK"]] = FieldInfo(alias="S14", default=None) + s2: Optional[Literal["FLAG", "BLOCK"]] = FieldInfo(alias="S2", default=None) s3: Optional[Literal["FLAG", "BLOCK"]] = FieldInfo(alias="S3", default=None) @@ -215,6 +219,11 @@ class AIGatewayListResponse(BaseModel): rate_limiting_limit: Optional[int] = None authentication: Optional[bool] = None + """Require authentication for gateway access. + + New gateways must have authentication enabled. Once enabled, authentication + cannot be disabled. + """ byok_only: Optional[bool] = None """ @@ -224,6 +233,16 @@ class AIGatewayListResponse(BaseModel): dlp: Optional[DLP] = None + fedramp_level: Optional[Literal["fedramp-medium", "fedramp-high"]] = None + """FedRAMP compliance level: fedramp-medium or fedramp-high.""" + + fedramp_mode: Optional[Literal["prefer", "require"]] = None + """FedRAMP enforcement mode. + + "prefer" prioritizes compliant connectors but allows fallback. "require" + strictly filters. + """ + guardrails: Optional[Guardrails] = None is_default: Optional[bool] = None @@ -254,6 +273,11 @@ class AIGatewayListResponse(BaseModel): spend_limits: Optional[SpendLimits] = None store_id: Optional[str] = None + """Secrets Store used by this gateway. + + Omit on update to keep the current store. Cannot be cleared while stored keys or + secret references depend on it. + """ stripe: Optional[Stripe] = None diff --git a/src/cloudflare/types/ai_gateway/ai_gateway_update_params.py b/src/cloudflare/types/ai_gateway/ai_gateway_update_params.py index 8713a17191e..7416494c232 100644 --- a/src/cloudflare/types/ai_gateway/ai_gateway_update_params.py +++ b/src/cloudflare/types/ai_gateway/ai_gateway_update_params.py @@ -44,6 +44,11 @@ class AIGatewayUpdateParams(TypedDict, total=False): rate_limiting_limit: Required[Optional[int]] authentication: bool + """Require authentication for gateway access. + + New gateways must have authentication enabled. Once enabled, authentication + cannot be disabled. + """ byok_only: bool """ @@ -81,6 +86,11 @@ class AIGatewayUpdateParams(TypedDict, total=False): spend_limits: Optional[SpendLimits] store_id: Optional[str] + """Secrets Store used by this gateway. + + Omit on update to keep the current store. Cannot be cleared while stored keys or + secret references depend on it. + """ stripe: Optional[Stripe] @@ -137,6 +147,8 @@ class GuardrailsPrompt(TypedDict, total=False): s13: Annotated[Literal["FLAG", "BLOCK"], PropertyInfo(alias="S13")] + s14: Annotated[Literal["FLAG", "BLOCK"], PropertyInfo(alias="S14")] + s2: Annotated[Literal["FLAG", "BLOCK"], PropertyInfo(alias="S2")] s3: Annotated[Literal["FLAG", "BLOCK"], PropertyInfo(alias="S3")] @@ -167,6 +179,8 @@ class GuardrailsResponse(TypedDict, total=False): s13: Annotated[Literal["FLAG", "BLOCK"], PropertyInfo(alias="S13")] + s14: Annotated[Literal["FLAG", "BLOCK"], PropertyInfo(alias="S14")] + s2: Annotated[Literal["FLAG", "BLOCK"], PropertyInfo(alias="S2")] s3: Annotated[Literal["FLAG", "BLOCK"], PropertyInfo(alias="S3")] diff --git a/src/cloudflare/types/ai_gateway/ai_gateway_update_response.py b/src/cloudflare/types/ai_gateway/ai_gateway_update_response.py index 2b56695dfbe..fd72eb1fcc5 100644 --- a/src/cloudflare/types/ai_gateway/ai_gateway_update_response.py +++ b/src/cloudflare/types/ai_gateway/ai_gateway_update_response.py @@ -72,6 +72,8 @@ class GuardrailsPrompt(BaseModel): s13: Optional[Literal["FLAG", "BLOCK"]] = FieldInfo(alias="S13", default=None) + s14: Optional[Literal["FLAG", "BLOCK"]] = FieldInfo(alias="S14", default=None) + s2: Optional[Literal["FLAG", "BLOCK"]] = FieldInfo(alias="S2", default=None) s3: Optional[Literal["FLAG", "BLOCK"]] = FieldInfo(alias="S3", default=None) @@ -102,6 +104,8 @@ class GuardrailsResponse(BaseModel): s13: Optional[Literal["FLAG", "BLOCK"]] = FieldInfo(alias="S13", default=None) + s14: Optional[Literal["FLAG", "BLOCK"]] = FieldInfo(alias="S14", default=None) + s2: Optional[Literal["FLAG", "BLOCK"]] = FieldInfo(alias="S2", default=None) s3: Optional[Literal["FLAG", "BLOCK"]] = FieldInfo(alias="S3", default=None) @@ -215,6 +219,11 @@ class AIGatewayUpdateResponse(BaseModel): rate_limiting_limit: Optional[int] = None authentication: Optional[bool] = None + """Require authentication for gateway access. + + New gateways must have authentication enabled. Once enabled, authentication + cannot be disabled. + """ byok_only: Optional[bool] = None """ @@ -224,6 +233,16 @@ class AIGatewayUpdateResponse(BaseModel): dlp: Optional[DLP] = None + fedramp_level: Optional[Literal["fedramp-medium", "fedramp-high"]] = None + """FedRAMP compliance level: fedramp-medium or fedramp-high.""" + + fedramp_mode: Optional[Literal["prefer", "require"]] = None + """FedRAMP enforcement mode. + + "prefer" prioritizes compliant connectors but allows fallback. "require" + strictly filters. + """ + guardrails: Optional[Guardrails] = None is_default: Optional[bool] = None @@ -254,6 +273,11 @@ class AIGatewayUpdateResponse(BaseModel): spend_limits: Optional[SpendLimits] = None store_id: Optional[str] = None + """Secrets Store used by this gateway. + + Omit on update to keep the current store. Cannot be cleared while stored keys or + secret references depend on it. + """ stripe: Optional[Stripe] = None diff --git a/src/cloudflare/types/ai_gateway/billing/topup/config_create_params.py b/src/cloudflare/types/ai_gateway/billing/topup/config_create_params.py index 8ca59302fae..bbbebb1b0d0 100644 --- a/src/cloudflare/types/ai_gateway/billing/topup/config_create_params.py +++ b/src/cloudflare/types/ai_gateway/billing/topup/config_create_params.py @@ -2,12 +2,13 @@ from __future__ import annotations -from typing_extensions import Required, TypedDict +from typing import Union +from typing_extensions import Required, TypeAlias, TypedDict -__all__ = ["ConfigCreateParams"] +__all__ = ["ConfigCreateParams", "Variant0", "Variant1"] -class ConfigCreateParams(TypedDict, total=False): +class Variant0(TypedDict, total=False): account_id: Required[str] amount: Required[int] @@ -15,3 +16,28 @@ class ConfigCreateParams(TypedDict, total=False): threshold: Required[int] """Balance threshold in cents that triggers auto top-up (min 500).""" + + +class Variant1(TypedDict, total=False): + account_id: Required[str] + + amount: Required[int] + """Auto top-up amount in cents (min 1000).""" + + consent_version: Required[str] + """Version of the off-session auto-top-up consent accepted by the user.""" + + payment_method_id: Required[str] + """Card to authenticate for future automatic top-ups.""" + + setup_idempotency_key: Required[str] + """Client-generated UUID that makes payment-method setup safe to retry.""" + + threshold: Required[int] + """Balance threshold in cents that triggers auto top-up (min 500).""" + + setup_intent_id: str + """Successfully confirmed payment-method setup identifier.""" + + +ConfigCreateParams: TypeAlias = Union[Variant0, Variant1] diff --git a/src/cloudflare/types/ai_gateway/billing/topup/config_create_response.py b/src/cloudflare/types/ai_gateway/billing/topup/config_create_response.py index b21c7baebfb..25d0678c195 100644 --- a/src/cloudflare/types/ai_gateway/billing/topup/config_create_response.py +++ b/src/cloudflare/types/ai_gateway/billing/topup/config_create_response.py @@ -1,11 +1,37 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. +from typing import Union +from typing_extensions import Literal, TypeAlias + from ....._models import BaseModel -__all__ = ["ConfigCreateResponse"] +__all__ = ["ConfigCreateResponse", "UnionMember0", "UnionMember1", "UnionMember2"] -class ConfigCreateResponse(BaseModel): +class UnionMember0(BaseModel): amount: float threshold: float + + +class UnionMember1(BaseModel): + amount: float + + status: Literal["configured"] + + threshold: float + + +class UnionMember2(BaseModel): + amount: float + + client_secret: str + + setup_intent_id: str + + status: Literal["requires_action"] + + threshold: float + + +ConfigCreateResponse: TypeAlias = Union[UnionMember0, UnionMember1, UnionMember2] diff --git a/src/cloudflare/types/ai_gateway/billing/topup_create_params.py b/src/cloudflare/types/ai_gateway/billing/topup_create_params.py index f273bdf02a6..06628074880 100644 --- a/src/cloudflare/types/ai_gateway/billing/topup_create_params.py +++ b/src/cloudflare/types/ai_gateway/billing/topup_create_params.py @@ -14,6 +14,4 @@ class TopupCreateParams(TypedDict, total=False): """Top-up amount in cents (min 1000).""" payment_method_id: str - """ - Stripe PaymentMethod to charge instead of the customer's default payment method. - """ + """Payment method to charge instead of the customer's default payment method.""" diff --git a/src/cloudflare/types/ai_gateway/billing/topup_create_response.py b/src/cloudflare/types/ai_gateway/billing/topup_create_response.py index 61241bf6075..9901912a134 100644 --- a/src/cloudflare/types/ai_gateway/billing/topup_create_response.py +++ b/src/cloudflare/types/ai_gateway/billing/topup_create_response.py @@ -9,13 +9,13 @@ class TopupCreateResponse(BaseModel): client_secret: Optional[str] = None - """Stripe PaymentIntent client secret.""" + """Client secret used to complete payment authentication.""" onboarding: bool """Whether the user was already onboarded.""" payment_intent_id: str - """Stripe invoice ID.""" + """Top-up payment identifier.""" brand: Optional[str] = None """Card brand (visa, mastercard, etc.).""" diff --git a/src/cloudflare/types/ai_gateway/billing/topup_status_params.py b/src/cloudflare/types/ai_gateway/billing/topup_status_params.py index 12bb967898c..4c32c4bf464 100644 --- a/src/cloudflare/types/ai_gateway/billing/topup_status_params.py +++ b/src/cloudflare/types/ai_gateway/billing/topup_status_params.py @@ -11,4 +11,4 @@ class TopupStatusParams(TypedDict, total=False): account_id: Required[str] payment_intent_id: Required[str] - """Stripe invoice ID to check status for.""" + """Top-up identifier to check status for.""" diff --git a/src/cloudflare/types/ai_gateway/billing_usage_history_response.py b/src/cloudflare/types/ai_gateway/billing_usage_history_response.py index e54aae19e14..8076ed280da 100644 --- a/src/cloudflare/types/ai_gateway/billing_usage_history_response.py +++ b/src/cloudflare/types/ai_gateway/billing_usage_history_response.py @@ -11,6 +11,7 @@ class History(BaseModel): id: str aggregated_value: float + """AI Gateway usage cost in the window, in US dollars.""" end_time: float diff --git a/src/cloudflare/types/ai_gateway/provider_config_create_response.py b/src/cloudflare/types/ai_gateway/provider_config_create_response.py index 37fe02808e6..c8cf2aa9609 100644 --- a/src/cloudflare/types/ai_gateway/provider_config_create_response.py +++ b/src/cloudflare/types/ai_gateway/provider_config_create_response.py @@ -1,7 +1,7 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import Optional -from datetime import datetime +from datetime import date, datetime from ..._models import BaseModel @@ -26,6 +26,14 @@ class ProviderConfigCreateResponse(BaseModel): secret_preview: str + last_used_at: Optional[date] = None + """ + UTC date (YYYY-MM-DD) the gateway last selected this key to authenticate a + request to the provider, whether or not the request succeeded. Updated at most + once a day. Null if the gateway has not used the key since this field was + introduced. + """ + rate_limit: Optional[float] = None rate_limit_period: Optional[float] = None diff --git a/src/cloudflare/types/ai_gateway/provider_config_list_response.py b/src/cloudflare/types/ai_gateway/provider_config_list_response.py index 6214cd3e790..fc40342c282 100644 --- a/src/cloudflare/types/ai_gateway/provider_config_list_response.py +++ b/src/cloudflare/types/ai_gateway/provider_config_list_response.py @@ -1,7 +1,7 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import Optional -from datetime import datetime +from datetime import date, datetime from ..._models import BaseModel @@ -26,6 +26,14 @@ class ProviderConfigListResponse(BaseModel): secret_preview: str + last_used_at: Optional[date] = None + """ + UTC date (YYYY-MM-DD) the gateway last selected this key to authenticate a + request to the provider, whether or not the request succeeded. Updated at most + once a day. Null if the gateway has not used the key since this field was + introduced. + """ + rate_limit: Optional[float] = None rate_limit_period: Optional[float] = None diff --git a/src/cloudflare/types/ai_security/custom_topic_get_response.py b/src/cloudflare/types/ai_security/custom_topic_get_response.py index e220024dcd1..8d0d36710fd 100644 --- a/src/cloudflare/types/ai_security/custom_topic_get_response.py +++ b/src/cloudflare/types/ai_security/custom_topic_get_response.py @@ -17,7 +17,9 @@ class Topic(BaseModel): topic: str """Description of the topic category. - Must contain only printable ASCII characters. + Must contain 2–50 UTF-8 bytes. Text in any language is supported, including + spaces, numbers, punctuation, and symbols. Tabs, line breaks, invalid text, and + invisible formatting characters are not allowed. """ diff --git a/src/cloudflare/types/ai_security/custom_topic_update_params.py b/src/cloudflare/types/ai_security/custom_topic_update_params.py index 32a94b87cc0..6a0b573125b 100644 --- a/src/cloudflare/types/ai_security/custom_topic_update_params.py +++ b/src/cloudflare/types/ai_security/custom_topic_update_params.py @@ -26,5 +26,7 @@ class Topic(TypedDict, total=False): topic: Required[str] """Description of the topic category. - Must contain only printable ASCII characters. + Must contain 2–50 UTF-8 bytes. Text in any language is supported, including + spaces, numbers, punctuation, and symbols. Tabs, line breaks, invalid text, and + invisible formatting characters are not allowed. """ diff --git a/src/cloudflare/types/ai_security/custom_topic_update_response.py b/src/cloudflare/types/ai_security/custom_topic_update_response.py index 8298805e54c..66f65ce3b63 100644 --- a/src/cloudflare/types/ai_security/custom_topic_update_response.py +++ b/src/cloudflare/types/ai_security/custom_topic_update_response.py @@ -17,7 +17,9 @@ class Topic(BaseModel): topic: str """Description of the topic category. - Must contain only printable ASCII characters. + Must contain 2–50 UTF-8 bytes. Text in any language is supported, including + spaces, numbers, punctuation, and symbols. Tabs, line breaks, invalid text, and + invisible formatting characters are not allowed. """ diff --git a/src/cloudflare/types/aisearch/instance_chat_completions_params.py b/src/cloudflare/types/aisearch/instance_chat_completions_params.py index bafa5b53df3..1a87a91dc3e 100644 --- a/src/cloudflare/types/aisearch/instance_chat_completions_params.py +++ b/src/cloudflare/types/aisearch/instance_chat_completions_params.py @@ -149,17 +149,25 @@ class AISearchOptionsRetrieval(TypedDict, total=False): fusion_method: Literal["max", "rrf"] keyword_match_mode: Literal["and", "or"] - """Controls which documents are candidates for BM25 scoring. + """Controls which documents become candidates for BM25 scoring. 'and' restricts candidates to documents containing all query terms; 'or' - includes any document containing at least one term, ranked by BM25 relevance. - When omitted, falls back to the instance-level + includes any document containing at least one term and ranks results according + to BM25 relevance. When omitted, falls back to the instance-level retrieval_options.keyword_match_mode, then to 'and'. """ match_threshold: float + """Minimum similarity score a chunk must reach to be returned. + + When omitted, falls back to the instance-level score_threshold, then to 0.4. + """ max_num_results: int + """Maximum number of results to return. + + When omitted, falls back to the instance-level max_num_results, then to 10. + """ retrieval_type: Literal["vector", "keyword", "hybrid"] @@ -170,10 +178,10 @@ class AISearchOptions(TypedDict, total=False): cache: AISearchOptionsCache custom_metadata: Dict[str, Union[str, float, bool]] - """Metadata added to AI Gateway logs for requests triggered by this operation. + """Metadata added to AI Gateway logs for requests this operation triggers. - Accepts up to 2 string, number, or boolean entries. Keys 'ai-search', 'task', - 'origin', and keys beginning with 'cf.' are reserved. + Accepts up to 2 string, number, or boolean entries. Reserved keys: 'ai-search', + 'task', 'origin', and any key beginning with 'cf.'. """ query_rewrite: AISearchOptionsQueryRewrite diff --git a/src/cloudflare/types/aisearch/instance_chat_completions_response.py b/src/cloudflare/types/aisearch/instance_chat_completions_response.py index fcfd2ea32f7..763f160f298 100644 --- a/src/cloudflare/types/aisearch/instance_chat_completions_response.py +++ b/src/cloudflare/types/aisearch/instance_chat_completions_response.py @@ -118,8 +118,30 @@ class Chunk(BaseModel): item: Optional[ChunkItem] = None + media_end_ms: Optional[int] = None + """ + Audio/video transcript chunks only: end, in milliseconds from the start of the + media (whole seconds), of the last transcript section the matched chunk covers. + Describes the matched chunk before any context expansion, not the expanded + `text`. + """ + + media_start_ms: Optional[int] = None + """ + Audio/video transcript chunks only: start, in milliseconds from the start of the + media (whole seconds), of the transcript section the matched chunk begins in. + Describes the matched chunk before any context expansion, not the expanded + `text`. + """ + scoring_details: Optional[ChunkScoringDetails] = None + source_media_type: Optional[Literal["audio", "video"]] = None + """Audio/video transcript chunks only: type of the source media file. + + Omitted for all other chunks. + """ + class InstanceChatCompletionsResponse(BaseModel): choices: List[Choice] diff --git a/src/cloudflare/types/aisearch/instance_create_params.py b/src/cloudflare/types/aisearch/instance_create_params.py index 8724ff75c0d..c3fe0d1d521 100644 --- a/src/cloudflare/types/aisearch/instance_create_params.py +++ b/src/cloudflare/types/aisearch/instance_create_params.py @@ -14,6 +14,7 @@ "IndexMethod", "IndexingOptions", "Metadata", + "MetadataCreatedFromEmdashPlugin", "PublicEndpointParams", "PublicEndpointParamsChatCompletionsEndpoint", "PublicEndpointParamsMcp", @@ -73,9 +74,10 @@ class InstanceCreateParams(TypedDict, total=False): """ index_method: IndexMethod - """Controls which storage backends are used during indexing. + """Controls which storage backends indexing uses. - Defaults to vector and keyword indexing for new instances. + Defaults to vector and keyword indexing for new instances. When set, both vector + and keyword are required. """ indexing_options: Optional[IndexingOptions] @@ -101,6 +103,7 @@ class InstanceCreateParams(TypedDict, total=False): rewrite_query: bool score_threshold: float + """Minimum similarity score a chunk must reach to be returned. Defaults to 0.4.""" source: Optional[str] @@ -110,7 +113,7 @@ class InstanceCreateParams(TypedDict, total=False): """Interval between automatic syncs, in seconds. Allowed values: 900 (15min), 1800 (30min), 3600 (1h), 7200 (2h), 14400 (4h), - 21600 (6h), 43200 (12h), 86400 (24h). + 21600 (6h), 43200 (12h), 86400 (24h). Defaults to 86400 (24h). """ token_id: str @@ -131,9 +134,9 @@ class CustomMetadata(TypedDict, total=False): class IndexMethod(TypedDict, total=False): - """Controls which storage backends are used during indexing. + """Controls which storage backends indexing uses. - Defaults to vector and keyword indexing for new instances. + Defaults to vector and keyword indexing for new instances. When set, both vector and keyword are required. """ keyword: Required[bool] @@ -160,22 +163,34 @@ class IndexingOptions(TypedDict, total=False): """ +class MetadataCreatedFromEmdashPlugin( # type: ignore[call-arg] + TypedDict, + total=False, + extra_items=object, # pyright: ignore[reportGeneralTypeIssues] +): + type: Required[Literal["native", "rest"]] + + version: Required[str] + + class Metadata(TypedDict, total=False): created_from_aisearch_wizard: bool + created_from_emdash_plugin: MetadataCreatedFromEmdashPlugin + worker_domain: str class PublicEndpointParamsChatCompletionsEndpoint(TypedDict, total=False): disabled: bool - """Disable chat completions endpoint for this public endpoint""" + """Disable chat completions endpoint for this public endpoint.""" class PublicEndpointParamsMcp(TypedDict, total=False): description: str disabled: bool - """Disable MCP endpoint for this public endpoint""" + """Disable MCP endpoint for this public endpoint.""" class PublicEndpointParamsRateLimit(TypedDict, total=False): @@ -188,7 +203,7 @@ class PublicEndpointParamsRateLimit(TypedDict, total=False): class PublicEndpointParamsSearchEndpoint(TypedDict, total=False): disabled: bool - """Disable search endpoint for this public endpoint""" + """Disable search endpoint for this public endpoint.""" class PublicEndpointParams(TypedDict, total=False): @@ -251,18 +266,18 @@ class RetrievalOptions(TypedDict, total=False): """ keyword_match_mode: Literal["and", "or"] - """Controls which documents are candidates for BM25 scoring. + """Controls which documents become candidates for BM25 scoring. 'and' restricts candidates to documents containing all query terms; 'or' - includes any document containing at least one term, ranked by BM25 relevance. - When omitted on an update, the existing stored value is preserved; when never - set, search falls back to 'and'. + includes any document containing at least one term and ranks results according + to BM25 relevance. When omitted on an update, the existing stored value stays + unchanged; when never set, search falls back to 'and'. """ class SourceParamsWebCrawlerDiscoverOptions(TypedDict, total=False): """ - Options for parse_type 'discover', where Browser Run discovers URLs by link following and sitemaps. Ignored for 'sitemap'. + Options for parse_type 'discover', where Browser Run discovers URLs through link following and sitemaps. Ignored for 'sitemap'. """ depth: float @@ -271,7 +286,7 @@ class SourceParamsWebCrawlerDiscoverOptions(TypedDict, total=False): include_external_links: bool """Follow links that point outside the source domain. - Must stay `false` — discover crawls are restricted to the zone you own. + Must stay `false` because discover crawls only cover the zone you own. """ include_subdomains: bool @@ -301,9 +316,9 @@ class SourceParamsWebCrawlerParseOptionsContentSelector(TypedDict, total=False): selector: Required[str] """CSS selector to extract content from pages matching the path pattern. - Must not contain disallowed characters (;, `, $, {, }, \\)). Must target a single - element; if multiple elements match, the selector is ignored and the full page - is used. + Disallowed characters: ;, `, $, {, }, \\.. Must target a single element; if + multiple elements match, the crawler ignores the selector and uses the full + page. """ @@ -312,15 +327,16 @@ class SourceParamsWebCrawlerParseOptions(TypedDict, total=False): """ List of path-to-selector mappings for extracting specific content from crawled pages. Each entry pairs a URL glob pattern with a CSS selector. The first - matching path wins. Only the matched HTML fragment is stored and indexed. Omit - the field to disable content selection — empty arrays are rejected. + matching path wins. The crawler stores and indexes only the matched HTML + fragment. Omit the field to disable content selection; the API rejects empty + arrays. """ include_headers: Dict[str, str] """Up to 5 custom HTTP headers sent with each crawl request. - Names must be RFC-7230 token characters (no spaces, colons, or control - characters); values must be HTAB + printable ASCII (no CR/LF). + Names must use RFC-7230 token characters, excluding spaces, colons, and control + characters. Values must use HTAB and printable ASCII only, excluding CR and LF. """ include_images: bool @@ -337,17 +353,17 @@ class SourceParamsWebCrawlerParseOptions(TypedDict, total=False): class SourceParamsWebCrawler(TypedDict, total=False): discover_options: SourceParamsWebCrawlerDiscoverOptions """ - Options for parse_type 'discover', where Browser Run discovers URLs by link + Options for parse_type 'discover', where Browser Run discovers URLs through link following and sitemaps. Ignored for 'sitemap'. """ parse_options: SourceParamsWebCrawlerParseOptions parse_type: Literal["sitemap", "discover"] - """How URLs are discovered. + """How the crawler finds URLs. 'sitemap' reads XML sitemaps; 'discover' follows links recursively and requires - the source to be a Verified zone on this account. + the source to belong to a Verified zone on this account. """ @@ -357,7 +373,7 @@ class SourceParams(TypedDict, total=False): Uses micromatch glob syntax: \\** matches within a path segment, ** matches across path segments (e.g., /admin/** matches /admin/users and - /admin/settings/advanced). Most accounts are limited to 10 rules; contact + /admin/settings/advanced). Most accounts have a limit of 10 rules; contact support to raise it. """ @@ -366,7 +382,7 @@ class SourceParams(TypedDict, total=False): Uses micromatch glob syntax: \\** matches within a path segment, ** matches across path segments (e.g., /blog/** matches /blog/post and /blog/2024/post). Most - accounts are limited to 10 rules; contact support to raise it. + accounts have a limit of 10 rules; contact support to raise it. """ prefix: str diff --git a/src/cloudflare/types/aisearch/instance_create_response.py b/src/cloudflare/types/aisearch/instance_create_response.py index 2556547eb75..a635d6b980a 100644 --- a/src/cloudflare/types/aisearch/instance_create_response.py +++ b/src/cloudflare/types/aisearch/instance_create_response.py @@ -1,6 +1,6 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import Dict, List, Optional +from typing import TYPE_CHECKING, Dict, List, Optional from datetime import datetime from typing_extensions import Literal @@ -14,6 +14,7 @@ "IndexMethod", "IndexingOptions", "Metadata", + "MetadataCreatedFromEmdashPlugin", "PublicEndpointParams", "PublicEndpointParamsChatCompletionsEndpoint", "PublicEndpointParamsMcp", @@ -36,9 +37,9 @@ class CustomMetadata(BaseModel): class IndexMethod(BaseModel): - """Controls which storage backends are used during indexing. + """Controls which storage backends indexing uses. - Defaults to vector and keyword indexing for new instances. + Defaults to vector and keyword indexing for new instances. When set, both vector and keyword are required. """ keyword: bool @@ -65,22 +66,42 @@ class IndexingOptions(BaseModel): """ +class MetadataCreatedFromEmdashPlugin(BaseModel): + type: Literal["native", "rest"] + + version: str + + if TYPE_CHECKING: + # Some versions of Pydantic <2.8.0 have a bug and don’t allow assigning a + # value to this field, so for compatibility we avoid doing it at runtime. + __pydantic_extra__: Dict[str, object] = FieldInfo(init=False) # pyright: ignore[reportIncompatibleVariableOverride] + + # Stub to indicate that arbitrary properties are accepted. + # To access properties that are not valid identifiers you can use `getattr`, e.g. + # `getattr(obj, '$type')` + def __getattr__(self, attr: str) -> object: ... + else: + __pydantic_extra__: Dict[str, object] + + class Metadata(BaseModel): created_from_aisearch_wizard: Optional[bool] = None + created_from_emdash_plugin: Optional[MetadataCreatedFromEmdashPlugin] = None + worker_domain: Optional[str] = None class PublicEndpointParamsChatCompletionsEndpoint(BaseModel): disabled: Optional[bool] = None - """Disable chat completions endpoint for this public endpoint""" + """Disable chat completions endpoint for this public endpoint.""" class PublicEndpointParamsMcp(BaseModel): description: Optional[str] = None disabled: Optional[bool] = None - """Disable MCP endpoint for this public endpoint""" + """Disable MCP endpoint for this public endpoint.""" class PublicEndpointParamsRateLimit(BaseModel): @@ -93,7 +114,7 @@ class PublicEndpointParamsRateLimit(BaseModel): class PublicEndpointParamsSearchEndpoint(BaseModel): disabled: Optional[bool] = None - """Disable search endpoint for this public endpoint""" + """Disable search endpoint for this public endpoint.""" class PublicEndpointParams(BaseModel): @@ -156,18 +177,18 @@ class RetrievalOptions(BaseModel): """ keyword_match_mode: Optional[Literal["and", "or"]] = None - """Controls which documents are candidates for BM25 scoring. + """Controls which documents become candidates for BM25 scoring. 'and' restricts candidates to documents containing all query terms; 'or' - includes any document containing at least one term, ranked by BM25 relevance. - When omitted on an update, the existing stored value is preserved; when never - set, search falls back to 'and'. + includes any document containing at least one term and ranks results according + to BM25 relevance. When omitted on an update, the existing stored value stays + unchanged; when never set, search falls back to 'and'. """ class SourceParamsWebCrawlerDiscoverOptions(BaseModel): """ - Options for parse_type 'discover', where Browser Run discovers URLs by link following and sitemaps. Ignored for 'sitemap'. + Options for parse_type 'discover', where Browser Run discovers URLs through link following and sitemaps. Ignored for 'sitemap'. """ depth: Optional[float] = None @@ -176,7 +197,7 @@ class SourceParamsWebCrawlerDiscoverOptions(BaseModel): include_external_links: Optional[bool] = None """Follow links that point outside the source domain. - Must stay `false` — discover crawls are restricted to the zone you own. + Must stay `false` because discover crawls only cover the zone you own. """ include_subdomains: Optional[bool] = None @@ -206,9 +227,9 @@ class SourceParamsWebCrawlerParseOptionsContentSelector(BaseModel): selector: str """CSS selector to extract content from pages matching the path pattern. - Must not contain disallowed characters (;, `, $, {, }, \\)). Must target a single - element; if multiple elements match, the selector is ignored and the full page - is used. + Disallowed characters: ;, `, $, {, }, \\.. Must target a single element; if + multiple elements match, the crawler ignores the selector and uses the full + page. """ @@ -217,15 +238,16 @@ class SourceParamsWebCrawlerParseOptions(BaseModel): """ List of path-to-selector mappings for extracting specific content from crawled pages. Each entry pairs a URL glob pattern with a CSS selector. The first - matching path wins. Only the matched HTML fragment is stored and indexed. Omit - the field to disable content selection — empty arrays are rejected. + matching path wins. The crawler stores and indexes only the matched HTML + fragment. Omit the field to disable content selection; the API rejects empty + arrays. """ include_headers: Optional[Dict[str, str]] = None """Up to 5 custom HTTP headers sent with each crawl request. - Names must be RFC-7230 token characters (no spaces, colons, or control - characters); values must be HTAB + printable ASCII (no CR/LF). + Names must use RFC-7230 token characters, excluding spaces, colons, and control + characters. Values must use HTAB and printable ASCII only, excluding CR and LF. """ include_images: Optional[bool] = None @@ -242,17 +264,17 @@ class SourceParamsWebCrawlerParseOptions(BaseModel): class SourceParamsWebCrawler(BaseModel): discover_options: Optional[SourceParamsWebCrawlerDiscoverOptions] = None """ - Options for parse_type 'discover', where Browser Run discovers URLs by link + Options for parse_type 'discover', where Browser Run discovers URLs through link following and sitemaps. Ignored for 'sitemap'. """ parse_options: Optional[SourceParamsWebCrawlerParseOptions] = None parse_type: Optional[Literal["sitemap", "discover"]] = None - """How URLs are discovered. + """How the crawler finds URLs. 'sitemap' reads XML sitemaps; 'discover' follows links recursively and requires - the source to be a Verified zone on this account. + the source to belong to a Verified zone on this account. """ @@ -262,7 +284,7 @@ class SourceParams(BaseModel): Uses micromatch glob syntax: \\** matches within a path segment, ** matches across path segments (e.g., /admin/** matches /admin/users and - /admin/settings/advanced). Most accounts are limited to 10 rules; contact + /admin/settings/advanced). Most accounts have a limit of 10 rules; contact support to raise it. """ @@ -271,7 +293,7 @@ class SourceParams(BaseModel): Uses micromatch glob syntax: \\** matches within a path segment, ** matches across path segments (e.g., /blog/** matches /blog/post and /blog/2024/post). Most - accounts are limited to 10 rules; contact support to raise it. + accounts have a limit of 10 rules; contact support to raise it. """ prefix: Optional[str] = None @@ -331,9 +353,10 @@ class InstanceCreateResponse(BaseModel): """ index_method: Optional[IndexMethod] = None - """Controls which storage backends are used during indexing. + """Controls which storage backends indexing uses. - Defaults to vector and keyword indexing for new instances. + Defaults to vector and keyword indexing for new instances. When set, both vector + and keyword are required. """ indexing_options: Optional[IndexingOptions] = None @@ -369,6 +392,7 @@ class InstanceCreateResponse(BaseModel): rewrite_query: Optional[bool] = None score_threshold: Optional[float] = None + """Minimum similarity score a chunk must reach to be returned. Defaults to 0.4.""" source: Optional[str] = None @@ -380,7 +404,7 @@ class InstanceCreateResponse(BaseModel): """Interval between automatic syncs, in seconds. Allowed values: 900 (15min), 1800 (30min), 3600 (1h), 7200 (2h), 14400 (4h), - 21600 (6h), 43200 (12h), 86400 (24h). + 21600 (6h), 43200 (12h), 86400 (24h). Defaults to 86400 (24h). """ token_id: Optional[str] = None diff --git a/src/cloudflare/types/aisearch/instance_delete_response.py b/src/cloudflare/types/aisearch/instance_delete_response.py index b3856422932..060a4a26859 100644 --- a/src/cloudflare/types/aisearch/instance_delete_response.py +++ b/src/cloudflare/types/aisearch/instance_delete_response.py @@ -1,6 +1,6 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import Dict, List, Optional +from typing import TYPE_CHECKING, Dict, List, Optional from datetime import datetime from typing_extensions import Literal @@ -14,6 +14,7 @@ "IndexMethod", "IndexingOptions", "Metadata", + "MetadataCreatedFromEmdashPlugin", "PublicEndpointParams", "PublicEndpointParamsChatCompletionsEndpoint", "PublicEndpointParamsMcp", @@ -36,9 +37,9 @@ class CustomMetadata(BaseModel): class IndexMethod(BaseModel): - """Controls which storage backends are used during indexing. + """Controls which storage backends indexing uses. - Defaults to vector and keyword indexing for new instances. + Defaults to vector and keyword indexing for new instances. When set, both vector and keyword are required. """ keyword: bool @@ -65,22 +66,42 @@ class IndexingOptions(BaseModel): """ +class MetadataCreatedFromEmdashPlugin(BaseModel): + type: Literal["native", "rest"] + + version: str + + if TYPE_CHECKING: + # Some versions of Pydantic <2.8.0 have a bug and don’t allow assigning a + # value to this field, so for compatibility we avoid doing it at runtime. + __pydantic_extra__: Dict[str, object] = FieldInfo(init=False) # pyright: ignore[reportIncompatibleVariableOverride] + + # Stub to indicate that arbitrary properties are accepted. + # To access properties that are not valid identifiers you can use `getattr`, e.g. + # `getattr(obj, '$type')` + def __getattr__(self, attr: str) -> object: ... + else: + __pydantic_extra__: Dict[str, object] + + class Metadata(BaseModel): created_from_aisearch_wizard: Optional[bool] = None + created_from_emdash_plugin: Optional[MetadataCreatedFromEmdashPlugin] = None + worker_domain: Optional[str] = None class PublicEndpointParamsChatCompletionsEndpoint(BaseModel): disabled: Optional[bool] = None - """Disable chat completions endpoint for this public endpoint""" + """Disable chat completions endpoint for this public endpoint.""" class PublicEndpointParamsMcp(BaseModel): description: Optional[str] = None disabled: Optional[bool] = None - """Disable MCP endpoint for this public endpoint""" + """Disable MCP endpoint for this public endpoint.""" class PublicEndpointParamsRateLimit(BaseModel): @@ -93,7 +114,7 @@ class PublicEndpointParamsRateLimit(BaseModel): class PublicEndpointParamsSearchEndpoint(BaseModel): disabled: Optional[bool] = None - """Disable search endpoint for this public endpoint""" + """Disable search endpoint for this public endpoint.""" class PublicEndpointParams(BaseModel): @@ -156,18 +177,18 @@ class RetrievalOptions(BaseModel): """ keyword_match_mode: Optional[Literal["and", "or"]] = None - """Controls which documents are candidates for BM25 scoring. + """Controls which documents become candidates for BM25 scoring. 'and' restricts candidates to documents containing all query terms; 'or' - includes any document containing at least one term, ranked by BM25 relevance. - When omitted on an update, the existing stored value is preserved; when never - set, search falls back to 'and'. + includes any document containing at least one term and ranks results according + to BM25 relevance. When omitted on an update, the existing stored value stays + unchanged; when never set, search falls back to 'and'. """ class SourceParamsWebCrawlerDiscoverOptions(BaseModel): """ - Options for parse_type 'discover', where Browser Run discovers URLs by link following and sitemaps. Ignored for 'sitemap'. + Options for parse_type 'discover', where Browser Run discovers URLs through link following and sitemaps. Ignored for 'sitemap'. """ depth: Optional[float] = None @@ -176,7 +197,7 @@ class SourceParamsWebCrawlerDiscoverOptions(BaseModel): include_external_links: Optional[bool] = None """Follow links that point outside the source domain. - Must stay `false` — discover crawls are restricted to the zone you own. + Must stay `false` because discover crawls only cover the zone you own. """ include_subdomains: Optional[bool] = None @@ -206,9 +227,9 @@ class SourceParamsWebCrawlerParseOptionsContentSelector(BaseModel): selector: str """CSS selector to extract content from pages matching the path pattern. - Must not contain disallowed characters (;, `, $, {, }, \\)). Must target a single - element; if multiple elements match, the selector is ignored and the full page - is used. + Disallowed characters: ;, `, $, {, }, \\.. Must target a single element; if + multiple elements match, the crawler ignores the selector and uses the full + page. """ @@ -217,15 +238,16 @@ class SourceParamsWebCrawlerParseOptions(BaseModel): """ List of path-to-selector mappings for extracting specific content from crawled pages. Each entry pairs a URL glob pattern with a CSS selector. The first - matching path wins. Only the matched HTML fragment is stored and indexed. Omit - the field to disable content selection — empty arrays are rejected. + matching path wins. The crawler stores and indexes only the matched HTML + fragment. Omit the field to disable content selection; the API rejects empty + arrays. """ include_headers: Optional[Dict[str, str]] = None """Up to 5 custom HTTP headers sent with each crawl request. - Names must be RFC-7230 token characters (no spaces, colons, or control - characters); values must be HTAB + printable ASCII (no CR/LF). + Names must use RFC-7230 token characters, excluding spaces, colons, and control + characters. Values must use HTAB and printable ASCII only, excluding CR and LF. """ include_images: Optional[bool] = None @@ -242,17 +264,17 @@ class SourceParamsWebCrawlerParseOptions(BaseModel): class SourceParamsWebCrawler(BaseModel): discover_options: Optional[SourceParamsWebCrawlerDiscoverOptions] = None """ - Options for parse_type 'discover', where Browser Run discovers URLs by link + Options for parse_type 'discover', where Browser Run discovers URLs through link following and sitemaps. Ignored for 'sitemap'. """ parse_options: Optional[SourceParamsWebCrawlerParseOptions] = None parse_type: Optional[Literal["sitemap", "discover"]] = None - """How URLs are discovered. + """How the crawler finds URLs. 'sitemap' reads XML sitemaps; 'discover' follows links recursively and requires - the source to be a Verified zone on this account. + the source to belong to a Verified zone on this account. """ @@ -262,7 +284,7 @@ class SourceParams(BaseModel): Uses micromatch glob syntax: \\** matches within a path segment, ** matches across path segments (e.g., /admin/** matches /admin/users and - /admin/settings/advanced). Most accounts are limited to 10 rules; contact + /admin/settings/advanced). Most accounts have a limit of 10 rules; contact support to raise it. """ @@ -271,7 +293,7 @@ class SourceParams(BaseModel): Uses micromatch glob syntax: \\** matches within a path segment, ** matches across path segments (e.g., /blog/** matches /blog/post and /blog/2024/post). Most - accounts are limited to 10 rules; contact support to raise it. + accounts have a limit of 10 rules; contact support to raise it. """ prefix: Optional[str] = None @@ -331,9 +353,10 @@ class InstanceDeleteResponse(BaseModel): """ index_method: Optional[IndexMethod] = None - """Controls which storage backends are used during indexing. + """Controls which storage backends indexing uses. - Defaults to vector and keyword indexing for new instances. + Defaults to vector and keyword indexing for new instances. When set, both vector + and keyword are required. """ indexing_options: Optional[IndexingOptions] = None @@ -369,6 +392,7 @@ class InstanceDeleteResponse(BaseModel): rewrite_query: Optional[bool] = None score_threshold: Optional[float] = None + """Minimum similarity score a chunk must reach to be returned. Defaults to 0.4.""" source: Optional[str] = None @@ -380,7 +404,7 @@ class InstanceDeleteResponse(BaseModel): """Interval between automatic syncs, in seconds. Allowed values: 900 (15min), 1800 (30min), 3600 (1h), 7200 (2h), 14400 (4h), - 21600 (6h), 43200 (12h), 86400 (24h). + 21600 (6h), 43200 (12h), 86400 (24h). Defaults to 86400 (24h). """ token_id: Optional[str] = None diff --git a/src/cloudflare/types/aisearch/instance_list_params.py b/src/cloudflare/types/aisearch/instance_list_params.py index 2dfe9258ac4..bbbbbe9a1e3 100644 --- a/src/cloudflare/types/aisearch/instance_list_params.py +++ b/src/cloudflare/types/aisearch/instance_list_params.py @@ -11,10 +11,13 @@ class InstanceListParams(TypedDict, total=False): account_id: Required[str] hostname: str - """Filter by exact Search for Agents hostname (case-insensitive).""" + """ + Return only instances with this exact Search for Agents hostname + (case-insensitive). + """ namespace: str - """Filter by namespace.""" + """Return only instances in this namespace.""" order_by: Literal["created_at"] """Field to order results by.""" diff --git a/src/cloudflare/types/aisearch/instance_list_response.py b/src/cloudflare/types/aisearch/instance_list_response.py index dcd67a4006b..561a6db9130 100644 --- a/src/cloudflare/types/aisearch/instance_list_response.py +++ b/src/cloudflare/types/aisearch/instance_list_response.py @@ -14,6 +14,7 @@ "IndexMethod", "IndexingOptions", "Metadata", + "MetadataCreatedFromEmdashPlugin", "PublicEndpointParams", "PublicEndpointParamsChatCompletionsEndpoint", "PublicEndpointParamsMcp", @@ -71,9 +72,29 @@ def __getattr__(self, attr: str) -> object: ... __pydantic_extra__: Dict[str, object] +class MetadataCreatedFromEmdashPlugin(BaseModel): + type: Literal["native", "rest"] + + version: str + + if TYPE_CHECKING: + # Some versions of Pydantic <2.8.0 have a bug and don’t allow assigning a + # value to this field, so for compatibility we avoid doing it at runtime. + __pydantic_extra__: Dict[str, object] = FieldInfo(init=False) # pyright: ignore[reportIncompatibleVariableOverride] + + # Stub to indicate that arbitrary properties are accepted. + # To access properties that are not valid identifiers you can use `getattr`, e.g. + # `getattr(obj, '$type')` + def __getattr__(self, attr: str) -> object: ... + else: + __pydantic_extra__: Dict[str, object] + + class Metadata(BaseModel): created_from_aisearch_wizard: Optional[bool] = None + created_from_emdash_plugin: Optional[MetadataCreatedFromEmdashPlugin] = None + worker_domain: Optional[str] = None if TYPE_CHECKING: @@ -237,8 +258,8 @@ class SourceParamsWebCrawlerDiscoverOptions(BaseModel): limit: Optional[float] = None """Maximum number of pages to crawl. - New values are capped at 100000; instances configured before that cap may report - a higher stored value, which the crawler clamps at run time. + New values have a maximum of 100000; instances configured before that cap may + report a higher stored value, which the crawler clamps at run time. """ max_age: Optional[float] = None diff --git a/src/cloudflare/types/aisearch/instance_read_response.py b/src/cloudflare/types/aisearch/instance_read_response.py index fb8e648d7a1..ac0c00bbb55 100644 --- a/src/cloudflare/types/aisearch/instance_read_response.py +++ b/src/cloudflare/types/aisearch/instance_read_response.py @@ -1,6 +1,6 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import Dict, List, Optional +from typing import TYPE_CHECKING, Dict, List, Optional from datetime import datetime from typing_extensions import Literal @@ -14,6 +14,7 @@ "IndexMethod", "IndexingOptions", "Metadata", + "MetadataCreatedFromEmdashPlugin", "PublicEndpointParams", "PublicEndpointParamsChatCompletionsEndpoint", "PublicEndpointParamsMcp", @@ -36,9 +37,9 @@ class CustomMetadata(BaseModel): class IndexMethod(BaseModel): - """Controls which storage backends are used during indexing. + """Controls which storage backends indexing uses. - Defaults to vector and keyword indexing for new instances. + Defaults to vector and keyword indexing for new instances. When set, both vector and keyword are required. """ keyword: bool @@ -65,22 +66,42 @@ class IndexingOptions(BaseModel): """ +class MetadataCreatedFromEmdashPlugin(BaseModel): + type: Literal["native", "rest"] + + version: str + + if TYPE_CHECKING: + # Some versions of Pydantic <2.8.0 have a bug and don’t allow assigning a + # value to this field, so for compatibility we avoid doing it at runtime. + __pydantic_extra__: Dict[str, object] = FieldInfo(init=False) # pyright: ignore[reportIncompatibleVariableOverride] + + # Stub to indicate that arbitrary properties are accepted. + # To access properties that are not valid identifiers you can use `getattr`, e.g. + # `getattr(obj, '$type')` + def __getattr__(self, attr: str) -> object: ... + else: + __pydantic_extra__: Dict[str, object] + + class Metadata(BaseModel): created_from_aisearch_wizard: Optional[bool] = None + created_from_emdash_plugin: Optional[MetadataCreatedFromEmdashPlugin] = None + worker_domain: Optional[str] = None class PublicEndpointParamsChatCompletionsEndpoint(BaseModel): disabled: Optional[bool] = None - """Disable chat completions endpoint for this public endpoint""" + """Disable chat completions endpoint for this public endpoint.""" class PublicEndpointParamsMcp(BaseModel): description: Optional[str] = None disabled: Optional[bool] = None - """Disable MCP endpoint for this public endpoint""" + """Disable MCP endpoint for this public endpoint.""" class PublicEndpointParamsRateLimit(BaseModel): @@ -93,7 +114,7 @@ class PublicEndpointParamsRateLimit(BaseModel): class PublicEndpointParamsSearchEndpoint(BaseModel): disabled: Optional[bool] = None - """Disable search endpoint for this public endpoint""" + """Disable search endpoint for this public endpoint.""" class PublicEndpointParams(BaseModel): @@ -156,18 +177,18 @@ class RetrievalOptions(BaseModel): """ keyword_match_mode: Optional[Literal["and", "or"]] = None - """Controls which documents are candidates for BM25 scoring. + """Controls which documents become candidates for BM25 scoring. 'and' restricts candidates to documents containing all query terms; 'or' - includes any document containing at least one term, ranked by BM25 relevance. - When omitted on an update, the existing stored value is preserved; when never - set, search falls back to 'and'. + includes any document containing at least one term and ranks results according + to BM25 relevance. When omitted on an update, the existing stored value stays + unchanged; when never set, search falls back to 'and'. """ class SourceParamsWebCrawlerDiscoverOptions(BaseModel): """ - Options for parse_type 'discover', where Browser Run discovers URLs by link following and sitemaps. Ignored for 'sitemap'. + Options for parse_type 'discover', where Browser Run discovers URLs through link following and sitemaps. Ignored for 'sitemap'. """ depth: Optional[float] = None @@ -176,7 +197,7 @@ class SourceParamsWebCrawlerDiscoverOptions(BaseModel): include_external_links: Optional[bool] = None """Follow links that point outside the source domain. - Must stay `false` — discover crawls are restricted to the zone you own. + Must stay `false` because discover crawls only cover the zone you own. """ include_subdomains: Optional[bool] = None @@ -206,9 +227,9 @@ class SourceParamsWebCrawlerParseOptionsContentSelector(BaseModel): selector: str """CSS selector to extract content from pages matching the path pattern. - Must not contain disallowed characters (;, `, $, {, }, \\)). Must target a single - element; if multiple elements match, the selector is ignored and the full page - is used. + Disallowed characters: ;, `, $, {, }, \\.. Must target a single element; if + multiple elements match, the crawler ignores the selector and uses the full + page. """ @@ -217,15 +238,16 @@ class SourceParamsWebCrawlerParseOptions(BaseModel): """ List of path-to-selector mappings for extracting specific content from crawled pages. Each entry pairs a URL glob pattern with a CSS selector. The first - matching path wins. Only the matched HTML fragment is stored and indexed. Omit - the field to disable content selection — empty arrays are rejected. + matching path wins. The crawler stores and indexes only the matched HTML + fragment. Omit the field to disable content selection; the API rejects empty + arrays. """ include_headers: Optional[Dict[str, str]] = None """Up to 5 custom HTTP headers sent with each crawl request. - Names must be RFC-7230 token characters (no spaces, colons, or control - characters); values must be HTAB + printable ASCII (no CR/LF). + Names must use RFC-7230 token characters, excluding spaces, colons, and control + characters. Values must use HTAB and printable ASCII only, excluding CR and LF. """ include_images: Optional[bool] = None @@ -242,17 +264,17 @@ class SourceParamsWebCrawlerParseOptions(BaseModel): class SourceParamsWebCrawler(BaseModel): discover_options: Optional[SourceParamsWebCrawlerDiscoverOptions] = None """ - Options for parse_type 'discover', where Browser Run discovers URLs by link + Options for parse_type 'discover', where Browser Run discovers URLs through link following and sitemaps. Ignored for 'sitemap'. """ parse_options: Optional[SourceParamsWebCrawlerParseOptions] = None parse_type: Optional[Literal["sitemap", "discover"]] = None - """How URLs are discovered. + """How the crawler finds URLs. 'sitemap' reads XML sitemaps; 'discover' follows links recursively and requires - the source to be a Verified zone on this account. + the source to belong to a Verified zone on this account. """ @@ -262,7 +284,7 @@ class SourceParams(BaseModel): Uses micromatch glob syntax: \\** matches within a path segment, ** matches across path segments (e.g., /admin/** matches /admin/users and - /admin/settings/advanced). Most accounts are limited to 10 rules; contact + /admin/settings/advanced). Most accounts have a limit of 10 rules; contact support to raise it. """ @@ -271,7 +293,7 @@ class SourceParams(BaseModel): Uses micromatch glob syntax: \\** matches within a path segment, ** matches across path segments (e.g., /blog/** matches /blog/post and /blog/2024/post). Most - accounts are limited to 10 rules; contact support to raise it. + accounts have a limit of 10 rules; contact support to raise it. """ prefix: Optional[str] = None @@ -331,9 +353,10 @@ class InstanceReadResponse(BaseModel): """ index_method: Optional[IndexMethod] = None - """Controls which storage backends are used during indexing. + """Controls which storage backends indexing uses. - Defaults to vector and keyword indexing for new instances. + Defaults to vector and keyword indexing for new instances. When set, both vector + and keyword are required. """ indexing_options: Optional[IndexingOptions] = None @@ -369,6 +392,7 @@ class InstanceReadResponse(BaseModel): rewrite_query: Optional[bool] = None score_threshold: Optional[float] = None + """Minimum similarity score a chunk must reach to be returned. Defaults to 0.4.""" source: Optional[str] = None @@ -380,7 +404,7 @@ class InstanceReadResponse(BaseModel): """Interval between automatic syncs, in seconds. Allowed values: 900 (15min), 1800 (30min), 3600 (1h), 7200 (2h), 14400 (4h), - 21600 (6h), 43200 (12h), 86400 (24h). + 21600 (6h), 43200 (12h), 86400 (24h). Defaults to 86400 (24h). """ token_id: Optional[str] = None diff --git a/src/cloudflare/types/aisearch/instance_search_params.py b/src/cloudflare/types/aisearch/instance_search_params.py index 5e985d8d3d3..77772381d8d 100644 --- a/src/cloudflare/types/aisearch/instance_search_params.py +++ b/src/cloudflare/types/aisearch/instance_search_params.py @@ -108,17 +108,25 @@ class AISearchOptionsRetrieval(TypedDict, total=False): fusion_method: Literal["max", "rrf"] keyword_match_mode: Literal["and", "or"] - """Controls which documents are candidates for BM25 scoring. + """Controls which documents become candidates for BM25 scoring. 'and' restricts candidates to documents containing all query terms; 'or' - includes any document containing at least one term, ranked by BM25 relevance. - When omitted, falls back to the instance-level + includes any document containing at least one term and ranks results according + to BM25 relevance. When omitted, falls back to the instance-level retrieval_options.keyword_match_mode, then to 'and'. """ match_threshold: float + """Minimum similarity score a chunk must reach to be returned. + + When omitted, falls back to the instance-level score_threshold, then to 0.4. + """ max_num_results: int + """Maximum number of results to return. + + When omitted, falls back to the instance-level max_num_results, then to 10. + """ retrieval_type: Literal["vector", "keyword", "hybrid"] @@ -129,10 +137,10 @@ class AISearchOptions(TypedDict, total=False): cache: AISearchOptionsCache custom_metadata: Dict[str, Union[str, float, bool]] - """Metadata added to AI Gateway logs for requests triggered by this operation. + """Metadata added to AI Gateway logs for requests this operation triggers. - Accepts up to 2 string, number, or boolean entries. Keys 'ai-search', 'task', - 'origin', and keys beginning with 'cf.' are reserved. + Accepts up to 2 string, number, or boolean entries. Reserved keys: 'ai-search', + 'task', 'origin', and any key beginning with 'cf.'. """ query_rewrite: AISearchOptionsQueryRewrite diff --git a/src/cloudflare/types/aisearch/instance_search_response.py b/src/cloudflare/types/aisearch/instance_search_response.py index c75a4deb87c..9753d65d628 100644 --- a/src/cloudflare/types/aisearch/instance_search_response.py +++ b/src/cloudflare/types/aisearch/instance_search_response.py @@ -41,8 +41,30 @@ class Chunk(BaseModel): item: Optional[ChunkItem] = None + media_end_ms: Optional[int] = None + """ + Audio/video transcript chunks only: end, in milliseconds from the start of the + media (whole seconds), of the last transcript section the matched chunk covers. + Describes the matched chunk before any context expansion, not the expanded + `text`. + """ + + media_start_ms: Optional[int] = None + """ + Audio/video transcript chunks only: start, in milliseconds from the start of the + media (whole seconds), of the transcript section the matched chunk begins in. + Describes the matched chunk before any context expansion, not the expanded + `text`. + """ + scoring_details: Optional[ChunkScoringDetails] = None + source_media_type: Optional[Literal["audio", "video"]] = None + """Audio/video transcript chunks only: type of the source media file. + + Omitted for all other chunks. + """ + class InstanceSearchResponse(BaseModel): chunks: List[Chunk] diff --git a/src/cloudflare/types/aisearch/instance_stats_response.py b/src/cloudflare/types/aisearch/instance_stats_response.py index 8dcc0d1166a..354315d0a5f 100644 --- a/src/cloudflare/types/aisearch/instance_stats_response.py +++ b/src/cloudflare/types/aisearch/instance_stats_response.py @@ -42,10 +42,10 @@ class InstanceStatsResponse(BaseModel): completed: Optional[int] = None degraded: Optional[bool] = None - """True when status counts are unavailable (e.g. + """True when the API cannot compute status counts (e.g. - legacy stats query exceeded D1 statement-size limit). Counts are omitted in this - case. + the legacy stats query exceeded the D1 statement-size limit). The response omits + counts in this case. """ engine: Optional[Engine] = None diff --git a/src/cloudflare/types/aisearch/instance_update_params.py b/src/cloudflare/types/aisearch/instance_update_params.py index 23ce0a1412b..0ed3691b1c8 100644 --- a/src/cloudflare/types/aisearch/instance_update_params.py +++ b/src/cloudflare/types/aisearch/instance_update_params.py @@ -14,6 +14,7 @@ "IndexMethod", "IndexingOptions", "Metadata", + "MetadataCreatedFromEmdashPlugin", "PublicEndpointParams", "PublicEndpointParamsChatCompletionsEndpoint", "PublicEndpointParamsMcp", @@ -64,9 +65,10 @@ class InstanceUpdateParams(TypedDict, total=False): fusion_method: Literal["max", "rrf"] index_method: IndexMethod - """Controls which storage backends are used during indexing. + """Controls which storage backends indexing uses. - Defaults to vector and keyword indexing for new instances. + Defaults to vector and keyword indexing for new instances. When set, both vector + and keyword are required. """ indexing_options: Optional[IndexingOptions] @@ -94,6 +96,7 @@ class InstanceUpdateParams(TypedDict, total=False): rewrite_query: bool score_threshold: float + """Minimum similarity score a chunk must reach to be returned. Defaults to 0.4.""" source: Optional[str] @@ -107,7 +110,7 @@ class InstanceUpdateParams(TypedDict, total=False): """Interval between automatic syncs, in seconds. Allowed values: 900 (15min), 1800 (30min), 3600 (1h), 7200 (2h), 14400 (4h), - 21600 (6h), 43200 (12h), 86400 (24h). + 21600 (6h), 43200 (12h), 86400 (24h). Defaults to 86400 (24h). """ system_prompt_aisearch: Annotated[Optional[str], PropertyInfo(alias="system_prompt_ai_search")] @@ -126,9 +129,9 @@ class CustomMetadata(TypedDict, total=False): class IndexMethod(TypedDict, total=False): - """Controls which storage backends are used during indexing. + """Controls which storage backends indexing uses. - Defaults to vector and keyword indexing for new instances. + Defaults to vector and keyword indexing for new instances. When set, both vector and keyword are required. """ keyword: Required[bool] @@ -155,22 +158,34 @@ class IndexingOptions(TypedDict, total=False): """ +class MetadataCreatedFromEmdashPlugin( # type: ignore[call-arg] + TypedDict, + total=False, + extra_items=object, # pyright: ignore[reportGeneralTypeIssues] +): + type: Required[Literal["native", "rest"]] + + version: Required[str] + + class Metadata(TypedDict, total=False): created_from_aisearch_wizard: bool + created_from_emdash_plugin: MetadataCreatedFromEmdashPlugin + worker_domain: str class PublicEndpointParamsChatCompletionsEndpoint(TypedDict, total=False): disabled: bool - """Disable chat completions endpoint for this public endpoint""" + """Disable chat completions endpoint for this public endpoint.""" class PublicEndpointParamsMcp(TypedDict, total=False): description: str disabled: bool - """Disable MCP endpoint for this public endpoint""" + """Disable MCP endpoint for this public endpoint.""" class PublicEndpointParamsRateLimit(TypedDict, total=False): @@ -183,7 +198,7 @@ class PublicEndpointParamsRateLimit(TypedDict, total=False): class PublicEndpointParamsSearchEndpoint(TypedDict, total=False): disabled: bool - """Disable search endpoint for this public endpoint""" + """Disable search endpoint for this public endpoint.""" class PublicEndpointParams(TypedDict, total=False): @@ -246,18 +261,18 @@ class RetrievalOptions(TypedDict, total=False): """ keyword_match_mode: Literal["and", "or"] - """Controls which documents are candidates for BM25 scoring. + """Controls which documents become candidates for BM25 scoring. 'and' restricts candidates to documents containing all query terms; 'or' - includes any document containing at least one term, ranked by BM25 relevance. - When omitted on an update, the existing stored value is preserved; when never - set, search falls back to 'and'. + includes any document containing at least one term and ranks results according + to BM25 relevance. When omitted on an update, the existing stored value stays + unchanged; when never set, search falls back to 'and'. """ class SourceParamsWebCrawlerDiscoverOptions(TypedDict, total=False): """ - Options for parse_type 'discover', where Browser Run discovers URLs by link following and sitemaps. Ignored for 'sitemap'. + Options for parse_type 'discover', where Browser Run discovers URLs through link following and sitemaps. Ignored for 'sitemap'. """ depth: float @@ -266,7 +281,7 @@ class SourceParamsWebCrawlerDiscoverOptions(TypedDict, total=False): include_external_links: bool """Follow links that point outside the source domain. - Must stay `false` — discover crawls are restricted to the zone you own. + Must stay `false` because discover crawls only cover the zone you own. """ include_subdomains: bool @@ -296,9 +311,9 @@ class SourceParamsWebCrawlerParseOptionsContentSelector(TypedDict, total=False): selector: Required[str] """CSS selector to extract content from pages matching the path pattern. - Must not contain disallowed characters (;, `, $, {, }, \\)). Must target a single - element; if multiple elements match, the selector is ignored and the full page - is used. + Disallowed characters: ;, `, $, {, }, \\.. Must target a single element; if + multiple elements match, the crawler ignores the selector and uses the full + page. """ @@ -307,15 +322,16 @@ class SourceParamsWebCrawlerParseOptions(TypedDict, total=False): """ List of path-to-selector mappings for extracting specific content from crawled pages. Each entry pairs a URL glob pattern with a CSS selector. The first - matching path wins. Only the matched HTML fragment is stored and indexed. Omit - the field to disable content selection — empty arrays are rejected. + matching path wins. The crawler stores and indexes only the matched HTML + fragment. Omit the field to disable content selection; the API rejects empty + arrays. """ include_headers: Dict[str, str] """Up to 5 custom HTTP headers sent with each crawl request. - Names must be RFC-7230 token characters (no spaces, colons, or control - characters); values must be HTAB + printable ASCII (no CR/LF). + Names must use RFC-7230 token characters, excluding spaces, colons, and control + characters. Values must use HTAB and printable ASCII only, excluding CR and LF. """ include_images: bool @@ -332,17 +348,17 @@ class SourceParamsWebCrawlerParseOptions(TypedDict, total=False): class SourceParamsWebCrawler(TypedDict, total=False): discover_options: SourceParamsWebCrawlerDiscoverOptions """ - Options for parse_type 'discover', where Browser Run discovers URLs by link + Options for parse_type 'discover', where Browser Run discovers URLs through link following and sitemaps. Ignored for 'sitemap'. """ parse_options: SourceParamsWebCrawlerParseOptions parse_type: Literal["sitemap", "discover"] - """How URLs are discovered. + """How the crawler finds URLs. 'sitemap' reads XML sitemaps; 'discover' follows links recursively and requires - the source to be a Verified zone on this account. + the source to belong to a Verified zone on this account. """ @@ -352,7 +368,7 @@ class SourceParams(TypedDict, total=False): Uses micromatch glob syntax: \\** matches within a path segment, ** matches across path segments (e.g., /admin/** matches /admin/users and - /admin/settings/advanced). Most accounts are limited to 10 rules; contact + /admin/settings/advanced). Most accounts have a limit of 10 rules; contact support to raise it. """ @@ -361,7 +377,7 @@ class SourceParams(TypedDict, total=False): Uses micromatch glob syntax: \\** matches within a path segment, ** matches across path segments (e.g., /blog/** matches /blog/post and /blog/2024/post). Most - accounts are limited to 10 rules; contact support to raise it. + accounts have a limit of 10 rules; contact support to raise it. """ prefix: str diff --git a/src/cloudflare/types/aisearch/instance_update_response.py b/src/cloudflare/types/aisearch/instance_update_response.py index cdedb30ca91..256921959a3 100644 --- a/src/cloudflare/types/aisearch/instance_update_response.py +++ b/src/cloudflare/types/aisearch/instance_update_response.py @@ -1,6 +1,6 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import Dict, List, Optional +from typing import TYPE_CHECKING, Dict, List, Optional from datetime import datetime from typing_extensions import Literal @@ -14,6 +14,7 @@ "IndexMethod", "IndexingOptions", "Metadata", + "MetadataCreatedFromEmdashPlugin", "PublicEndpointParams", "PublicEndpointParamsChatCompletionsEndpoint", "PublicEndpointParamsMcp", @@ -36,9 +37,9 @@ class CustomMetadata(BaseModel): class IndexMethod(BaseModel): - """Controls which storage backends are used during indexing. + """Controls which storage backends indexing uses. - Defaults to vector and keyword indexing for new instances. + Defaults to vector and keyword indexing for new instances. When set, both vector and keyword are required. """ keyword: bool @@ -65,22 +66,42 @@ class IndexingOptions(BaseModel): """ +class MetadataCreatedFromEmdashPlugin(BaseModel): + type: Literal["native", "rest"] + + version: str + + if TYPE_CHECKING: + # Some versions of Pydantic <2.8.0 have a bug and don’t allow assigning a + # value to this field, so for compatibility we avoid doing it at runtime. + __pydantic_extra__: Dict[str, object] = FieldInfo(init=False) # pyright: ignore[reportIncompatibleVariableOverride] + + # Stub to indicate that arbitrary properties are accepted. + # To access properties that are not valid identifiers you can use `getattr`, e.g. + # `getattr(obj, '$type')` + def __getattr__(self, attr: str) -> object: ... + else: + __pydantic_extra__: Dict[str, object] + + class Metadata(BaseModel): created_from_aisearch_wizard: Optional[bool] = None + created_from_emdash_plugin: Optional[MetadataCreatedFromEmdashPlugin] = None + worker_domain: Optional[str] = None class PublicEndpointParamsChatCompletionsEndpoint(BaseModel): disabled: Optional[bool] = None - """Disable chat completions endpoint for this public endpoint""" + """Disable chat completions endpoint for this public endpoint.""" class PublicEndpointParamsMcp(BaseModel): description: Optional[str] = None disabled: Optional[bool] = None - """Disable MCP endpoint for this public endpoint""" + """Disable MCP endpoint for this public endpoint.""" class PublicEndpointParamsRateLimit(BaseModel): @@ -93,7 +114,7 @@ class PublicEndpointParamsRateLimit(BaseModel): class PublicEndpointParamsSearchEndpoint(BaseModel): disabled: Optional[bool] = None - """Disable search endpoint for this public endpoint""" + """Disable search endpoint for this public endpoint.""" class PublicEndpointParams(BaseModel): @@ -156,18 +177,18 @@ class RetrievalOptions(BaseModel): """ keyword_match_mode: Optional[Literal["and", "or"]] = None - """Controls which documents are candidates for BM25 scoring. + """Controls which documents become candidates for BM25 scoring. 'and' restricts candidates to documents containing all query terms; 'or' - includes any document containing at least one term, ranked by BM25 relevance. - When omitted on an update, the existing stored value is preserved; when never - set, search falls back to 'and'. + includes any document containing at least one term and ranks results according + to BM25 relevance. When omitted on an update, the existing stored value stays + unchanged; when never set, search falls back to 'and'. """ class SourceParamsWebCrawlerDiscoverOptions(BaseModel): """ - Options for parse_type 'discover', where Browser Run discovers URLs by link following and sitemaps. Ignored for 'sitemap'. + Options for parse_type 'discover', where Browser Run discovers URLs through link following and sitemaps. Ignored for 'sitemap'. """ depth: Optional[float] = None @@ -176,7 +197,7 @@ class SourceParamsWebCrawlerDiscoverOptions(BaseModel): include_external_links: Optional[bool] = None """Follow links that point outside the source domain. - Must stay `false` — discover crawls are restricted to the zone you own. + Must stay `false` because discover crawls only cover the zone you own. """ include_subdomains: Optional[bool] = None @@ -206,9 +227,9 @@ class SourceParamsWebCrawlerParseOptionsContentSelector(BaseModel): selector: str """CSS selector to extract content from pages matching the path pattern. - Must not contain disallowed characters (;, `, $, {, }, \\)). Must target a single - element; if multiple elements match, the selector is ignored and the full page - is used. + Disallowed characters: ;, `, $, {, }, \\.. Must target a single element; if + multiple elements match, the crawler ignores the selector and uses the full + page. """ @@ -217,15 +238,16 @@ class SourceParamsWebCrawlerParseOptions(BaseModel): """ List of path-to-selector mappings for extracting specific content from crawled pages. Each entry pairs a URL glob pattern with a CSS selector. The first - matching path wins. Only the matched HTML fragment is stored and indexed. Omit - the field to disable content selection — empty arrays are rejected. + matching path wins. The crawler stores and indexes only the matched HTML + fragment. Omit the field to disable content selection; the API rejects empty + arrays. """ include_headers: Optional[Dict[str, str]] = None """Up to 5 custom HTTP headers sent with each crawl request. - Names must be RFC-7230 token characters (no spaces, colons, or control - characters); values must be HTAB + printable ASCII (no CR/LF). + Names must use RFC-7230 token characters, excluding spaces, colons, and control + characters. Values must use HTAB and printable ASCII only, excluding CR and LF. """ include_images: Optional[bool] = None @@ -242,17 +264,17 @@ class SourceParamsWebCrawlerParseOptions(BaseModel): class SourceParamsWebCrawler(BaseModel): discover_options: Optional[SourceParamsWebCrawlerDiscoverOptions] = None """ - Options for parse_type 'discover', where Browser Run discovers URLs by link + Options for parse_type 'discover', where Browser Run discovers URLs through link following and sitemaps. Ignored for 'sitemap'. """ parse_options: Optional[SourceParamsWebCrawlerParseOptions] = None parse_type: Optional[Literal["sitemap", "discover"]] = None - """How URLs are discovered. + """How the crawler finds URLs. 'sitemap' reads XML sitemaps; 'discover' follows links recursively and requires - the source to be a Verified zone on this account. + the source to belong to a Verified zone on this account. """ @@ -262,7 +284,7 @@ class SourceParams(BaseModel): Uses micromatch glob syntax: \\** matches within a path segment, ** matches across path segments (e.g., /admin/** matches /admin/users and - /admin/settings/advanced). Most accounts are limited to 10 rules; contact + /admin/settings/advanced). Most accounts have a limit of 10 rules; contact support to raise it. """ @@ -271,7 +293,7 @@ class SourceParams(BaseModel): Uses micromatch glob syntax: \\** matches within a path segment, ** matches across path segments (e.g., /blog/** matches /blog/post and /blog/2024/post). Most - accounts are limited to 10 rules; contact support to raise it. + accounts have a limit of 10 rules; contact support to raise it. """ prefix: Optional[str] = None @@ -331,9 +353,10 @@ class InstanceUpdateResponse(BaseModel): """ index_method: Optional[IndexMethod] = None - """Controls which storage backends are used during indexing. + """Controls which storage backends indexing uses. - Defaults to vector and keyword indexing for new instances. + Defaults to vector and keyword indexing for new instances. When set, both vector + and keyword are required. """ indexing_options: Optional[IndexingOptions] = None @@ -369,6 +392,7 @@ class InstanceUpdateResponse(BaseModel): rewrite_query: Optional[bool] = None score_threshold: Optional[float] = None + """Minimum similarity score a chunk must reach to be returned. Defaults to 0.4.""" source: Optional[str] = None @@ -380,7 +404,7 @@ class InstanceUpdateResponse(BaseModel): """Interval between automatic syncs, in seconds. Allowed values: 900 (15min), 1800 (30min), 3600 (1h), 7200 (2h), 14400 (4h), - 21600 (6h), 43200 (12h), 86400 (24h). + 21600 (6h), 43200 (12h), 86400 (24h). Defaults to 86400 (24h). """ token_id: Optional[str] = None diff --git a/src/cloudflare/types/aisearch/namespace_chat_completions_params.py b/src/cloudflare/types/aisearch/namespace_chat_completions_params.py index 609e6d0b410..350f1ca0b76 100644 --- a/src/cloudflare/types/aisearch/namespace_chat_completions_params.py +++ b/src/cloudflare/types/aisearch/namespace_chat_completions_params.py @@ -103,17 +103,27 @@ class AISearchOptionsRetrieval(TypedDict, total=False): fusion_method: Literal["max", "rrf"] keyword_match_mode: Literal["and", "or"] - """Controls which documents are candidates for BM25 scoring. + """Controls which documents become candidates for BM25 scoring. 'and' restricts candidates to documents containing all query terms; 'or' - includes any document containing at least one term, ranked by BM25 relevance. - When omitted, falls back to the instance-level + includes any document containing at least one term and ranks results according + to BM25 relevance. When omitted, falls back to the instance-level retrieval_options.keyword_match_mode, then to 'and'. """ match_threshold: float + """Minimum score a chunk must reach to be returned. + + When omitted, each instance's chunks are filtered by that instance's + score_threshold, capped at the lower of the first instance's score_threshold and + 0.4. + """ max_num_results: int + """Maximum number of merged results to return. + + When omitted, defaults to the first instance's max_num_results, then 10. + """ retrieval_type: Literal["vector", "keyword", "hybrid"] @@ -126,10 +136,10 @@ class AISearchOptions(TypedDict, total=False): cache: AISearchOptionsCache custom_metadata: Dict[str, Union[str, float, bool]] - """Metadata added to AI Gateway logs for requests triggered by this operation. + """Metadata added to AI Gateway logs for requests this operation triggers. - Accepts up to 2 string, number, or boolean entries. Keys 'ai-search', 'task', - 'origin', and keys beginning with 'cf.' are reserved. + Accepts up to 2 string, number, or boolean entries. Reserved keys: 'ai-search', + 'task', 'origin', and any key beginning with 'cf.'. """ query_rewrite: AISearchOptionsQueryRewrite diff --git a/src/cloudflare/types/aisearch/namespace_chat_completions_response.py b/src/cloudflare/types/aisearch/namespace_chat_completions_response.py index 22c12815c88..926432eff63 100644 --- a/src/cloudflare/types/aisearch/namespace_chat_completions_response.py +++ b/src/cloudflare/types/aisearch/namespace_chat_completions_response.py @@ -121,8 +121,30 @@ class Chunk(BaseModel): item: Optional[ChunkItem] = None + media_end_ms: Optional[int] = None + """ + Audio/video transcript chunks only: end, in milliseconds from the start of the + media (whole seconds), of the last transcript section the matched chunk covers. + Describes the matched chunk before any context expansion, not the expanded + `text`. + """ + + media_start_ms: Optional[int] = None + """ + Audio/video transcript chunks only: start, in milliseconds from the start of the + media (whole seconds), of the transcript section the matched chunk begins in. + Describes the matched chunk before any context expansion, not the expanded + `text`. + """ + scoring_details: Optional[ChunkScoringDetails] = None + source_media_type: Optional[Literal["audio", "video"]] = None + """Audio/video transcript chunks only: type of the source media file. + + Omitted for all other chunks. + """ + class Error(BaseModel): instance_id: str diff --git a/src/cloudflare/types/aisearch/namespace_create_params.py b/src/cloudflare/types/aisearch/namespace_create_params.py index 1f9f9c16bbb..c8895f9a085 100644 --- a/src/cloudflare/types/aisearch/namespace_create_params.py +++ b/src/cloudflare/types/aisearch/namespace_create_params.py @@ -30,14 +30,14 @@ class NamespaceCreateParams(TypedDict, total=False): class PublicEndpointParamsChatCompletionsEndpoint(TypedDict, total=False): disabled: bool - """Disable chat completions endpoint for this public endpoint""" + """Disable chat completions endpoint for this public endpoint.""" class PublicEndpointParamsMcp(TypedDict, total=False): description: str disabled: bool - """Disable MCP endpoint for this public endpoint""" + """Disable MCP endpoint for this public endpoint.""" class PublicEndpointParamsRateLimit(TypedDict, total=False): @@ -50,7 +50,7 @@ class PublicEndpointParamsRateLimit(TypedDict, total=False): class PublicEndpointParamsSearchEndpoint(TypedDict, total=False): disabled: bool - """Disable search endpoint for this public endpoint""" + """Disable search endpoint for this public endpoint.""" class PublicEndpointParams(TypedDict, total=False): @@ -80,8 +80,9 @@ class PublicEndpointParams(TypedDict, total=False): instances_allowed: SequenceNotStr[str] """Instance IDs exposed through the namespace public endpoint. - Empty means nothing is searchable. Every ID must be an existing instance in this - namespace, and the list cannot exceed the account's multi-instance search limit. + Empty means nothing is searchable. Every ID must reference an existing instance + in this namespace, and the list must stay within the account's multi-instance + search limit. """ mcp: PublicEndpointParamsMcp diff --git a/src/cloudflare/types/aisearch/namespace_create_response.py b/src/cloudflare/types/aisearch/namespace_create_response.py index 7ffa1172e99..c0cd1f3bc4f 100644 --- a/src/cloudflare/types/aisearch/namespace_create_response.py +++ b/src/cloudflare/types/aisearch/namespace_create_response.py @@ -18,14 +18,14 @@ class PublicEndpointParamsChatCompletionsEndpoint(BaseModel): disabled: Optional[bool] = None - """Disable chat completions endpoint for this public endpoint""" + """Disable chat completions endpoint for this public endpoint.""" class PublicEndpointParamsMcp(BaseModel): description: Optional[str] = None disabled: Optional[bool] = None - """Disable MCP endpoint for this public endpoint""" + """Disable MCP endpoint for this public endpoint.""" class PublicEndpointParamsRateLimit(BaseModel): @@ -38,7 +38,7 @@ class PublicEndpointParamsRateLimit(BaseModel): class PublicEndpointParamsSearchEndpoint(BaseModel): disabled: Optional[bool] = None - """Disable search endpoint for this public endpoint""" + """Disable search endpoint for this public endpoint.""" class PublicEndpointParams(BaseModel): @@ -68,8 +68,9 @@ class PublicEndpointParams(BaseModel): instances_allowed: Optional[List[str]] = None """Instance IDs exposed through the namespace public endpoint. - Empty means nothing is searchable. Every ID must be an existing instance in this - namespace, and the list cannot exceed the account's multi-instance search limit. + Empty means nothing is searchable. Every ID must reference an existing instance + in this namespace, and the list must stay within the account's multi-instance + search limit. """ mcp: Optional[PublicEndpointParamsMcp] = None diff --git a/src/cloudflare/types/aisearch/namespace_list_response.py b/src/cloudflare/types/aisearch/namespace_list_response.py index 39a4182320a..54678a8c0a5 100644 --- a/src/cloudflare/types/aisearch/namespace_list_response.py +++ b/src/cloudflare/types/aisearch/namespace_list_response.py @@ -18,14 +18,14 @@ class PublicEndpointParamsChatCompletionsEndpoint(BaseModel): disabled: Optional[bool] = None - """Disable chat completions endpoint for this public endpoint""" + """Disable chat completions endpoint for this public endpoint.""" class PublicEndpointParamsMcp(BaseModel): description: Optional[str] = None disabled: Optional[bool] = None - """Disable MCP endpoint for this public endpoint""" + """Disable MCP endpoint for this public endpoint.""" class PublicEndpointParamsRateLimit(BaseModel): @@ -38,7 +38,7 @@ class PublicEndpointParamsRateLimit(BaseModel): class PublicEndpointParamsSearchEndpoint(BaseModel): disabled: Optional[bool] = None - """Disable search endpoint for this public endpoint""" + """Disable search endpoint for this public endpoint.""" class PublicEndpointParams(BaseModel): @@ -68,8 +68,9 @@ class PublicEndpointParams(BaseModel): instances_allowed: Optional[List[str]] = None """Instance IDs exposed through the namespace public endpoint. - Empty means nothing is searchable. Every ID must be an existing instance in this - namespace, and the list cannot exceed the account's multi-instance search limit. + Empty means nothing is searchable. Every ID must reference an existing instance + in this namespace, and the list must stay within the account's multi-instance + search limit. """ mcp: Optional[PublicEndpointParamsMcp] = None diff --git a/src/cloudflare/types/aisearch/namespace_read_response.py b/src/cloudflare/types/aisearch/namespace_read_response.py index ab2074d0e98..ea91daa51eb 100644 --- a/src/cloudflare/types/aisearch/namespace_read_response.py +++ b/src/cloudflare/types/aisearch/namespace_read_response.py @@ -18,14 +18,14 @@ class PublicEndpointParamsChatCompletionsEndpoint(BaseModel): disabled: Optional[bool] = None - """Disable chat completions endpoint for this public endpoint""" + """Disable chat completions endpoint for this public endpoint.""" class PublicEndpointParamsMcp(BaseModel): description: Optional[str] = None disabled: Optional[bool] = None - """Disable MCP endpoint for this public endpoint""" + """Disable MCP endpoint for this public endpoint.""" class PublicEndpointParamsRateLimit(BaseModel): @@ -38,7 +38,7 @@ class PublicEndpointParamsRateLimit(BaseModel): class PublicEndpointParamsSearchEndpoint(BaseModel): disabled: Optional[bool] = None - """Disable search endpoint for this public endpoint""" + """Disable search endpoint for this public endpoint.""" class PublicEndpointParams(BaseModel): @@ -68,8 +68,9 @@ class PublicEndpointParams(BaseModel): instances_allowed: Optional[List[str]] = None """Instance IDs exposed through the namespace public endpoint. - Empty means nothing is searchable. Every ID must be an existing instance in this - namespace, and the list cannot exceed the account's multi-instance search limit. + Empty means nothing is searchable. Every ID must reference an existing instance + in this namespace, and the list must stay within the account's multi-instance + search limit. """ mcp: Optional[PublicEndpointParamsMcp] = None diff --git a/src/cloudflare/types/aisearch/namespace_search_params.py b/src/cloudflare/types/aisearch/namespace_search_params.py index 0fcc8f9c484..dddb6659d06 100644 --- a/src/cloudflare/types/aisearch/namespace_search_params.py +++ b/src/cloudflare/types/aisearch/namespace_search_params.py @@ -109,17 +109,27 @@ class AISearchOptionsRetrieval(TypedDict, total=False): fusion_method: Literal["max", "rrf"] keyword_match_mode: Literal["and", "or"] - """Controls which documents are candidates for BM25 scoring. + """Controls which documents become candidates for BM25 scoring. 'and' restricts candidates to documents containing all query terms; 'or' - includes any document containing at least one term, ranked by BM25 relevance. - When omitted, falls back to the instance-level + includes any document containing at least one term and ranks results according + to BM25 relevance. When omitted, falls back to the instance-level retrieval_options.keyword_match_mode, then to 'and'. """ match_threshold: float + """Minimum score a chunk must reach to be returned. + + When omitted, each instance's chunks are filtered by that instance's + score_threshold, capped at 0.4. + """ max_num_results: int + """Maximum number of merged results to return. + + When omitted, defaults to the sum of the searched instances' max_num_results + (each falling back to 10), up to 50. + """ retrieval_type: Literal["vector", "keyword", "hybrid"] @@ -132,10 +142,10 @@ class AISearchOptions(TypedDict, total=False): cache: AISearchOptionsCache custom_metadata: Dict[str, Union[str, float, bool]] - """Metadata added to AI Gateway logs for requests triggered by this operation. + """Metadata added to AI Gateway logs for requests this operation triggers. - Accepts up to 2 string, number, or boolean entries. Keys 'ai-search', 'task', - 'origin', and keys beginning with 'cf.' are reserved. + Accepts up to 2 string, number, or boolean entries. Reserved keys: 'ai-search', + 'task', 'origin', and any key beginning with 'cf.'. """ query_rewrite: AISearchOptionsQueryRewrite diff --git a/src/cloudflare/types/aisearch/namespace_search_response.py b/src/cloudflare/types/aisearch/namespace_search_response.py index 94422ac55c6..d2fa804d331 100644 --- a/src/cloudflare/types/aisearch/namespace_search_response.py +++ b/src/cloudflare/types/aisearch/namespace_search_response.py @@ -43,8 +43,30 @@ class Chunk(BaseModel): item: Optional[ChunkItem] = None + media_end_ms: Optional[int] = None + """ + Audio/video transcript chunks only: end, in milliseconds from the start of the + media (whole seconds), of the last transcript section the matched chunk covers. + Describes the matched chunk before any context expansion, not the expanded + `text`. + """ + + media_start_ms: Optional[int] = None + """ + Audio/video transcript chunks only: start, in milliseconds from the start of the + media (whole seconds), of the transcript section the matched chunk begins in. + Describes the matched chunk before any context expansion, not the expanded + `text`. + """ + scoring_details: Optional[ChunkScoringDetails] = None + source_media_type: Optional[Literal["audio", "video"]] = None + """Audio/video transcript chunks only: type of the source media file. + + Omitted for all other chunks. + """ + class Error(BaseModel): instance_id: str diff --git a/src/cloudflare/types/aisearch/namespace_update_params.py b/src/cloudflare/types/aisearch/namespace_update_params.py index 05df8acde25..66669d30743 100644 --- a/src/cloudflare/types/aisearch/namespace_update_params.py +++ b/src/cloudflare/types/aisearch/namespace_update_params.py @@ -28,14 +28,14 @@ class NamespaceUpdateParams(TypedDict, total=False): class PublicEndpointParamsChatCompletionsEndpoint(TypedDict, total=False): disabled: bool - """Disable chat completions endpoint for this public endpoint""" + """Disable chat completions endpoint for this public endpoint.""" class PublicEndpointParamsMcp(TypedDict, total=False): description: str disabled: bool - """Disable MCP endpoint for this public endpoint""" + """Disable MCP endpoint for this public endpoint.""" class PublicEndpointParamsRateLimit(TypedDict, total=False): @@ -48,7 +48,7 @@ class PublicEndpointParamsRateLimit(TypedDict, total=False): class PublicEndpointParamsSearchEndpoint(TypedDict, total=False): disabled: bool - """Disable search endpoint for this public endpoint""" + """Disable search endpoint for this public endpoint.""" class PublicEndpointParams(TypedDict, total=False): @@ -78,8 +78,9 @@ class PublicEndpointParams(TypedDict, total=False): instances_allowed: SequenceNotStr[str] """Instance IDs exposed through the namespace public endpoint. - Empty means nothing is searchable. Every ID must be an existing instance in this - namespace, and the list cannot exceed the account's multi-instance search limit. + Empty means nothing is searchable. Every ID must reference an existing instance + in this namespace, and the list must stay within the account's multi-instance + search limit. """ mcp: PublicEndpointParamsMcp diff --git a/src/cloudflare/types/aisearch/namespace_update_response.py b/src/cloudflare/types/aisearch/namespace_update_response.py index 8e631332dbb..9272445a3e8 100644 --- a/src/cloudflare/types/aisearch/namespace_update_response.py +++ b/src/cloudflare/types/aisearch/namespace_update_response.py @@ -18,14 +18,14 @@ class PublicEndpointParamsChatCompletionsEndpoint(BaseModel): disabled: Optional[bool] = None - """Disable chat completions endpoint for this public endpoint""" + """Disable chat completions endpoint for this public endpoint.""" class PublicEndpointParamsMcp(BaseModel): description: Optional[str] = None disabled: Optional[bool] = None - """Disable MCP endpoint for this public endpoint""" + """Disable MCP endpoint for this public endpoint.""" class PublicEndpointParamsRateLimit(BaseModel): @@ -38,7 +38,7 @@ class PublicEndpointParamsRateLimit(BaseModel): class PublicEndpointParamsSearchEndpoint(BaseModel): disabled: Optional[bool] = None - """Disable search endpoint for this public endpoint""" + """Disable search endpoint for this public endpoint.""" class PublicEndpointParams(BaseModel): @@ -68,8 +68,9 @@ class PublicEndpointParams(BaseModel): instances_allowed: Optional[List[str]] = None """Instance IDs exposed through the namespace public endpoint. - Empty means nothing is searchable. Every ID must be an existing instance in this - namespace, and the list cannot exceed the account's multi-instance search limit. + Empty means nothing is searchable. Every ID must reference an existing instance + in this namespace, and the list must stay within the account's multi-instance + search limit. """ mcp: Optional[PublicEndpointParamsMcp] = None diff --git a/src/cloudflare/types/aisearch/namespaces/__init__.py b/src/cloudflare/types/aisearch/namespaces/__init__.py index d1d45a063a0..88757d8ed6f 100644 --- a/src/cloudflare/types/aisearch/namespaces/__init__.py +++ b/src/cloudflare/types/aisearch/namespaces/__init__.py @@ -3,6 +3,7 @@ from __future__ import annotations from .instance_list_params import InstanceListParams as InstanceListParams +from .instance_move_params import InstanceMoveParams as InstanceMoveParams from .instance_create_params import InstanceCreateParams as InstanceCreateParams from .instance_list_response import InstanceListResponse as InstanceListResponse from .instance_read_response import InstanceReadResponse as InstanceReadResponse diff --git a/src/cloudflare/types/aisearch/namespaces/instance_chat_completions_params.py b/src/cloudflare/types/aisearch/namespaces/instance_chat_completions_params.py index 4eae6f1d0fc..d170135543e 100644 --- a/src/cloudflare/types/aisearch/namespaces/instance_chat_completions_params.py +++ b/src/cloudflare/types/aisearch/namespaces/instance_chat_completions_params.py @@ -28,7 +28,7 @@ class InstanceChatCompletionsParams(TypedDict, total=False): account_id: Required[str] - name: Required[str] + namespace: Required[str] messages: Required[Iterable[Message]] @@ -151,17 +151,25 @@ class AISearchOptionsRetrieval(TypedDict, total=False): fusion_method: Literal["max", "rrf"] keyword_match_mode: Literal["and", "or"] - """Controls which documents are candidates for BM25 scoring. + """Controls which documents become candidates for BM25 scoring. 'and' restricts candidates to documents containing all query terms; 'or' - includes any document containing at least one term, ranked by BM25 relevance. - When omitted, falls back to the instance-level + includes any document containing at least one term and ranks results according + to BM25 relevance. When omitted, falls back to the instance-level retrieval_options.keyword_match_mode, then to 'and'. """ match_threshold: float + """Minimum similarity score a chunk must reach to be returned. + + When omitted, falls back to the instance-level score_threshold, then to 0.4. + """ max_num_results: int + """Maximum number of results to return. + + When omitted, falls back to the instance-level max_num_results, then to 10. + """ retrieval_type: Literal["vector", "keyword", "hybrid"] @@ -172,10 +180,10 @@ class AISearchOptions(TypedDict, total=False): cache: AISearchOptionsCache custom_metadata: Dict[str, Union[str, float, bool]] - """Metadata added to AI Gateway logs for requests triggered by this operation. + """Metadata added to AI Gateway logs for requests this operation triggers. - Accepts up to 2 string, number, or boolean entries. Keys 'ai-search', 'task', - 'origin', and keys beginning with 'cf.' are reserved. + Accepts up to 2 string, number, or boolean entries. Reserved keys: 'ai-search', + 'task', 'origin', and any key beginning with 'cf.'. """ query_rewrite: AISearchOptionsQueryRewrite diff --git a/src/cloudflare/types/aisearch/namespaces/instance_chat_completions_response.py b/src/cloudflare/types/aisearch/namespaces/instance_chat_completions_response.py index 68dc19c3349..28fe876398c 100644 --- a/src/cloudflare/types/aisearch/namespaces/instance_chat_completions_response.py +++ b/src/cloudflare/types/aisearch/namespaces/instance_chat_completions_response.py @@ -118,8 +118,30 @@ class Chunk(BaseModel): item: Optional[ChunkItem] = None + media_end_ms: Optional[int] = None + """ + Audio/video transcript chunks only: end, in milliseconds from the start of the + media (whole seconds), of the last transcript section the matched chunk covers. + Describes the matched chunk before any context expansion, not the expanded + `text`. + """ + + media_start_ms: Optional[int] = None + """ + Audio/video transcript chunks only: start, in milliseconds from the start of the + media (whole seconds), of the transcript section the matched chunk begins in. + Describes the matched chunk before any context expansion, not the expanded + `text`. + """ + scoring_details: Optional[ChunkScoringDetails] = None + source_media_type: Optional[Literal["audio", "video"]] = None + """Audio/video transcript chunks only: type of the source media file. + + Omitted for all other chunks. + """ + class InstanceChatCompletionsResponse(BaseModel): choices: List[Choice] diff --git a/src/cloudflare/types/aisearch/namespaces/instance_create_params.py b/src/cloudflare/types/aisearch/namespaces/instance_create_params.py index 3051b0ad8a7..483e9f80356 100644 --- a/src/cloudflare/types/aisearch/namespaces/instance_create_params.py +++ b/src/cloudflare/types/aisearch/namespaces/instance_create_params.py @@ -14,6 +14,7 @@ "IndexMethod", "IndexingOptions", "Metadata", + "MetadataCreatedFromEmdashPlugin", "PublicEndpointParams", "PublicEndpointParamsChatCompletionsEndpoint", "PublicEndpointParamsMcp", @@ -73,9 +74,10 @@ class InstanceCreateParams(TypedDict, total=False): """ index_method: IndexMethod - """Controls which storage backends are used during indexing. + """Controls which storage backends indexing uses. - Defaults to vector and keyword indexing for new instances. + Defaults to vector and keyword indexing for new instances. When set, both vector + and keyword are required. """ indexing_options: Optional[IndexingOptions] @@ -101,6 +103,7 @@ class InstanceCreateParams(TypedDict, total=False): rewrite_query: bool score_threshold: float + """Minimum similarity score a chunk must reach to be returned. Defaults to 0.4.""" source: Optional[str] @@ -110,7 +113,7 @@ class InstanceCreateParams(TypedDict, total=False): """Interval between automatic syncs, in seconds. Allowed values: 900 (15min), 1800 (30min), 3600 (1h), 7200 (2h), 14400 (4h), - 21600 (6h), 43200 (12h), 86400 (24h). + 21600 (6h), 43200 (12h), 86400 (24h). Defaults to 86400 (24h). """ token_id: str @@ -131,9 +134,9 @@ class CustomMetadata(TypedDict, total=False): class IndexMethod(TypedDict, total=False): - """Controls which storage backends are used during indexing. + """Controls which storage backends indexing uses. - Defaults to vector and keyword indexing for new instances. + Defaults to vector and keyword indexing for new instances. When set, both vector and keyword are required. """ keyword: Required[bool] @@ -160,22 +163,34 @@ class IndexingOptions(TypedDict, total=False): """ +class MetadataCreatedFromEmdashPlugin( # type: ignore[call-arg] + TypedDict, + total=False, + extra_items=object, # pyright: ignore[reportGeneralTypeIssues] +): + type: Required[Literal["native", "rest"]] + + version: Required[str] + + class Metadata(TypedDict, total=False): created_from_aisearch_wizard: bool + created_from_emdash_plugin: MetadataCreatedFromEmdashPlugin + worker_domain: str class PublicEndpointParamsChatCompletionsEndpoint(TypedDict, total=False): disabled: bool - """Disable chat completions endpoint for this public endpoint""" + """Disable chat completions endpoint for this public endpoint.""" class PublicEndpointParamsMcp(TypedDict, total=False): description: str disabled: bool - """Disable MCP endpoint for this public endpoint""" + """Disable MCP endpoint for this public endpoint.""" class PublicEndpointParamsRateLimit(TypedDict, total=False): @@ -188,7 +203,7 @@ class PublicEndpointParamsRateLimit(TypedDict, total=False): class PublicEndpointParamsSearchEndpoint(TypedDict, total=False): disabled: bool - """Disable search endpoint for this public endpoint""" + """Disable search endpoint for this public endpoint.""" class PublicEndpointParams(TypedDict, total=False): @@ -251,18 +266,18 @@ class RetrievalOptions(TypedDict, total=False): """ keyword_match_mode: Literal["and", "or"] - """Controls which documents are candidates for BM25 scoring. + """Controls which documents become candidates for BM25 scoring. 'and' restricts candidates to documents containing all query terms; 'or' - includes any document containing at least one term, ranked by BM25 relevance. - When omitted on an update, the existing stored value is preserved; when never - set, search falls back to 'and'. + includes any document containing at least one term and ranks results according + to BM25 relevance. When omitted on an update, the existing stored value stays + unchanged; when never set, search falls back to 'and'. """ class SourceParamsWebCrawlerDiscoverOptions(TypedDict, total=False): """ - Options for parse_type 'discover', where Browser Run discovers URLs by link following and sitemaps. Ignored for 'sitemap'. + Options for parse_type 'discover', where Browser Run discovers URLs through link following and sitemaps. Ignored for 'sitemap'. """ depth: float @@ -271,7 +286,7 @@ class SourceParamsWebCrawlerDiscoverOptions(TypedDict, total=False): include_external_links: bool """Follow links that point outside the source domain. - Must stay `false` — discover crawls are restricted to the zone you own. + Must stay `false` because discover crawls only cover the zone you own. """ include_subdomains: bool @@ -301,9 +316,9 @@ class SourceParamsWebCrawlerParseOptionsContentSelector(TypedDict, total=False): selector: Required[str] """CSS selector to extract content from pages matching the path pattern. - Must not contain disallowed characters (;, `, $, {, }, \\)). Must target a single - element; if multiple elements match, the selector is ignored and the full page - is used. + Disallowed characters: ;, `, $, {, }, \\.. Must target a single element; if + multiple elements match, the crawler ignores the selector and uses the full + page. """ @@ -312,15 +327,16 @@ class SourceParamsWebCrawlerParseOptions(TypedDict, total=False): """ List of path-to-selector mappings for extracting specific content from crawled pages. Each entry pairs a URL glob pattern with a CSS selector. The first - matching path wins. Only the matched HTML fragment is stored and indexed. Omit - the field to disable content selection — empty arrays are rejected. + matching path wins. The crawler stores and indexes only the matched HTML + fragment. Omit the field to disable content selection; the API rejects empty + arrays. """ include_headers: Dict[str, str] """Up to 5 custom HTTP headers sent with each crawl request. - Names must be RFC-7230 token characters (no spaces, colons, or control - characters); values must be HTAB + printable ASCII (no CR/LF). + Names must use RFC-7230 token characters, excluding spaces, colons, and control + characters. Values must use HTAB and printable ASCII only, excluding CR and LF. """ include_images: bool @@ -337,17 +353,17 @@ class SourceParamsWebCrawlerParseOptions(TypedDict, total=False): class SourceParamsWebCrawler(TypedDict, total=False): discover_options: SourceParamsWebCrawlerDiscoverOptions """ - Options for parse_type 'discover', where Browser Run discovers URLs by link + Options for parse_type 'discover', where Browser Run discovers URLs through link following and sitemaps. Ignored for 'sitemap'. """ parse_options: SourceParamsWebCrawlerParseOptions parse_type: Literal["sitemap", "discover"] - """How URLs are discovered. + """How the crawler finds URLs. 'sitemap' reads XML sitemaps; 'discover' follows links recursively and requires - the source to be a Verified zone on this account. + the source to belong to a Verified zone on this account. """ @@ -357,7 +373,7 @@ class SourceParams(TypedDict, total=False): Uses micromatch glob syntax: \\** matches within a path segment, ** matches across path segments (e.g., /admin/** matches /admin/users and - /admin/settings/advanced). Most accounts are limited to 10 rules; contact + /admin/settings/advanced). Most accounts have a limit of 10 rules; contact support to raise it. """ @@ -366,7 +382,7 @@ class SourceParams(TypedDict, total=False): Uses micromatch glob syntax: \\** matches within a path segment, ** matches across path segments (e.g., /blog/** matches /blog/post and /blog/2024/post). Most - accounts are limited to 10 rules; contact support to raise it. + accounts have a limit of 10 rules; contact support to raise it. """ prefix: str diff --git a/src/cloudflare/types/aisearch/namespaces/instance_create_response.py b/src/cloudflare/types/aisearch/namespaces/instance_create_response.py index bde6638aa9d..ae6ccccd507 100644 --- a/src/cloudflare/types/aisearch/namespaces/instance_create_response.py +++ b/src/cloudflare/types/aisearch/namespaces/instance_create_response.py @@ -1,6 +1,6 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import Dict, List, Optional +from typing import TYPE_CHECKING, Dict, List, Optional from datetime import datetime from typing_extensions import Literal @@ -14,6 +14,7 @@ "IndexMethod", "IndexingOptions", "Metadata", + "MetadataCreatedFromEmdashPlugin", "PublicEndpointParams", "PublicEndpointParamsChatCompletionsEndpoint", "PublicEndpointParamsMcp", @@ -36,9 +37,9 @@ class CustomMetadata(BaseModel): class IndexMethod(BaseModel): - """Controls which storage backends are used during indexing. + """Controls which storage backends indexing uses. - Defaults to vector and keyword indexing for new instances. + Defaults to vector and keyword indexing for new instances. When set, both vector and keyword are required. """ keyword: bool @@ -65,22 +66,42 @@ class IndexingOptions(BaseModel): """ +class MetadataCreatedFromEmdashPlugin(BaseModel): + type: Literal["native", "rest"] + + version: str + + if TYPE_CHECKING: + # Some versions of Pydantic <2.8.0 have a bug and don’t allow assigning a + # value to this field, so for compatibility we avoid doing it at runtime. + __pydantic_extra__: Dict[str, object] = FieldInfo(init=False) # pyright: ignore[reportIncompatibleVariableOverride] + + # Stub to indicate that arbitrary properties are accepted. + # To access properties that are not valid identifiers you can use `getattr`, e.g. + # `getattr(obj, '$type')` + def __getattr__(self, attr: str) -> object: ... + else: + __pydantic_extra__: Dict[str, object] + + class Metadata(BaseModel): created_from_aisearch_wizard: Optional[bool] = None + created_from_emdash_plugin: Optional[MetadataCreatedFromEmdashPlugin] = None + worker_domain: Optional[str] = None class PublicEndpointParamsChatCompletionsEndpoint(BaseModel): disabled: Optional[bool] = None - """Disable chat completions endpoint for this public endpoint""" + """Disable chat completions endpoint for this public endpoint.""" class PublicEndpointParamsMcp(BaseModel): description: Optional[str] = None disabled: Optional[bool] = None - """Disable MCP endpoint for this public endpoint""" + """Disable MCP endpoint for this public endpoint.""" class PublicEndpointParamsRateLimit(BaseModel): @@ -93,7 +114,7 @@ class PublicEndpointParamsRateLimit(BaseModel): class PublicEndpointParamsSearchEndpoint(BaseModel): disabled: Optional[bool] = None - """Disable search endpoint for this public endpoint""" + """Disable search endpoint for this public endpoint.""" class PublicEndpointParams(BaseModel): @@ -156,18 +177,18 @@ class RetrievalOptions(BaseModel): """ keyword_match_mode: Optional[Literal["and", "or"]] = None - """Controls which documents are candidates for BM25 scoring. + """Controls which documents become candidates for BM25 scoring. 'and' restricts candidates to documents containing all query terms; 'or' - includes any document containing at least one term, ranked by BM25 relevance. - When omitted on an update, the existing stored value is preserved; when never - set, search falls back to 'and'. + includes any document containing at least one term and ranks results according + to BM25 relevance. When omitted on an update, the existing stored value stays + unchanged; when never set, search falls back to 'and'. """ class SourceParamsWebCrawlerDiscoverOptions(BaseModel): """ - Options for parse_type 'discover', where Browser Run discovers URLs by link following and sitemaps. Ignored for 'sitemap'. + Options for parse_type 'discover', where Browser Run discovers URLs through link following and sitemaps. Ignored for 'sitemap'. """ depth: Optional[float] = None @@ -176,7 +197,7 @@ class SourceParamsWebCrawlerDiscoverOptions(BaseModel): include_external_links: Optional[bool] = None """Follow links that point outside the source domain. - Must stay `false` — discover crawls are restricted to the zone you own. + Must stay `false` because discover crawls only cover the zone you own. """ include_subdomains: Optional[bool] = None @@ -206,9 +227,9 @@ class SourceParamsWebCrawlerParseOptionsContentSelector(BaseModel): selector: str """CSS selector to extract content from pages matching the path pattern. - Must not contain disallowed characters (;, `, $, {, }, \\)). Must target a single - element; if multiple elements match, the selector is ignored and the full page - is used. + Disallowed characters: ;, `, $, {, }, \\.. Must target a single element; if + multiple elements match, the crawler ignores the selector and uses the full + page. """ @@ -217,15 +238,16 @@ class SourceParamsWebCrawlerParseOptions(BaseModel): """ List of path-to-selector mappings for extracting specific content from crawled pages. Each entry pairs a URL glob pattern with a CSS selector. The first - matching path wins. Only the matched HTML fragment is stored and indexed. Omit - the field to disable content selection — empty arrays are rejected. + matching path wins. The crawler stores and indexes only the matched HTML + fragment. Omit the field to disable content selection; the API rejects empty + arrays. """ include_headers: Optional[Dict[str, str]] = None """Up to 5 custom HTTP headers sent with each crawl request. - Names must be RFC-7230 token characters (no spaces, colons, or control - characters); values must be HTAB + printable ASCII (no CR/LF). + Names must use RFC-7230 token characters, excluding spaces, colons, and control + characters. Values must use HTAB and printable ASCII only, excluding CR and LF. """ include_images: Optional[bool] = None @@ -242,17 +264,17 @@ class SourceParamsWebCrawlerParseOptions(BaseModel): class SourceParamsWebCrawler(BaseModel): discover_options: Optional[SourceParamsWebCrawlerDiscoverOptions] = None """ - Options for parse_type 'discover', where Browser Run discovers URLs by link + Options for parse_type 'discover', where Browser Run discovers URLs through link following and sitemaps. Ignored for 'sitemap'. """ parse_options: Optional[SourceParamsWebCrawlerParseOptions] = None parse_type: Optional[Literal["sitemap", "discover"]] = None - """How URLs are discovered. + """How the crawler finds URLs. 'sitemap' reads XML sitemaps; 'discover' follows links recursively and requires - the source to be a Verified zone on this account. + the source to belong to a Verified zone on this account. """ @@ -262,7 +284,7 @@ class SourceParams(BaseModel): Uses micromatch glob syntax: \\** matches within a path segment, ** matches across path segments (e.g., /admin/** matches /admin/users and - /admin/settings/advanced). Most accounts are limited to 10 rules; contact + /admin/settings/advanced). Most accounts have a limit of 10 rules; contact support to raise it. """ @@ -271,7 +293,7 @@ class SourceParams(BaseModel): Uses micromatch glob syntax: \\** matches within a path segment, ** matches across path segments (e.g., /blog/** matches /blog/post and /blog/2024/post). Most - accounts are limited to 10 rules; contact support to raise it. + accounts have a limit of 10 rules; contact support to raise it. """ prefix: Optional[str] = None @@ -331,9 +353,10 @@ class InstanceCreateResponse(BaseModel): """ index_method: Optional[IndexMethod] = None - """Controls which storage backends are used during indexing. + """Controls which storage backends indexing uses. - Defaults to vector and keyword indexing for new instances. + Defaults to vector and keyword indexing for new instances. When set, both vector + and keyword are required. """ indexing_options: Optional[IndexingOptions] = None @@ -369,6 +392,7 @@ class InstanceCreateResponse(BaseModel): rewrite_query: Optional[bool] = None score_threshold: Optional[float] = None + """Minimum similarity score a chunk must reach to be returned. Defaults to 0.4.""" source: Optional[str] = None @@ -380,7 +404,7 @@ class InstanceCreateResponse(BaseModel): """Interval between automatic syncs, in seconds. Allowed values: 900 (15min), 1800 (30min), 3600 (1h), 7200 (2h), 14400 (4h), - 21600 (6h), 43200 (12h), 86400 (24h). + 21600 (6h), 43200 (12h), 86400 (24h). Defaults to 86400 (24h). """ token_id: Optional[str] = None diff --git a/src/cloudflare/types/aisearch/namespaces/instance_delete_response.py b/src/cloudflare/types/aisearch/namespaces/instance_delete_response.py index 984afdab4b6..05a0858cc66 100644 --- a/src/cloudflare/types/aisearch/namespaces/instance_delete_response.py +++ b/src/cloudflare/types/aisearch/namespaces/instance_delete_response.py @@ -1,6 +1,6 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import Dict, List, Optional +from typing import TYPE_CHECKING, Dict, List, Optional from datetime import datetime from typing_extensions import Literal @@ -14,6 +14,7 @@ "IndexMethod", "IndexingOptions", "Metadata", + "MetadataCreatedFromEmdashPlugin", "PublicEndpointParams", "PublicEndpointParamsChatCompletionsEndpoint", "PublicEndpointParamsMcp", @@ -36,9 +37,9 @@ class CustomMetadata(BaseModel): class IndexMethod(BaseModel): - """Controls which storage backends are used during indexing. + """Controls which storage backends indexing uses. - Defaults to vector and keyword indexing for new instances. + Defaults to vector and keyword indexing for new instances. When set, both vector and keyword are required. """ keyword: bool @@ -65,22 +66,42 @@ class IndexingOptions(BaseModel): """ +class MetadataCreatedFromEmdashPlugin(BaseModel): + type: Literal["native", "rest"] + + version: str + + if TYPE_CHECKING: + # Some versions of Pydantic <2.8.0 have a bug and don’t allow assigning a + # value to this field, so for compatibility we avoid doing it at runtime. + __pydantic_extra__: Dict[str, object] = FieldInfo(init=False) # pyright: ignore[reportIncompatibleVariableOverride] + + # Stub to indicate that arbitrary properties are accepted. + # To access properties that are not valid identifiers you can use `getattr`, e.g. + # `getattr(obj, '$type')` + def __getattr__(self, attr: str) -> object: ... + else: + __pydantic_extra__: Dict[str, object] + + class Metadata(BaseModel): created_from_aisearch_wizard: Optional[bool] = None + created_from_emdash_plugin: Optional[MetadataCreatedFromEmdashPlugin] = None + worker_domain: Optional[str] = None class PublicEndpointParamsChatCompletionsEndpoint(BaseModel): disabled: Optional[bool] = None - """Disable chat completions endpoint for this public endpoint""" + """Disable chat completions endpoint for this public endpoint.""" class PublicEndpointParamsMcp(BaseModel): description: Optional[str] = None disabled: Optional[bool] = None - """Disable MCP endpoint for this public endpoint""" + """Disable MCP endpoint for this public endpoint.""" class PublicEndpointParamsRateLimit(BaseModel): @@ -93,7 +114,7 @@ class PublicEndpointParamsRateLimit(BaseModel): class PublicEndpointParamsSearchEndpoint(BaseModel): disabled: Optional[bool] = None - """Disable search endpoint for this public endpoint""" + """Disable search endpoint for this public endpoint.""" class PublicEndpointParams(BaseModel): @@ -156,18 +177,18 @@ class RetrievalOptions(BaseModel): """ keyword_match_mode: Optional[Literal["and", "or"]] = None - """Controls which documents are candidates for BM25 scoring. + """Controls which documents become candidates for BM25 scoring. 'and' restricts candidates to documents containing all query terms; 'or' - includes any document containing at least one term, ranked by BM25 relevance. - When omitted on an update, the existing stored value is preserved; when never - set, search falls back to 'and'. + includes any document containing at least one term and ranks results according + to BM25 relevance. When omitted on an update, the existing stored value stays + unchanged; when never set, search falls back to 'and'. """ class SourceParamsWebCrawlerDiscoverOptions(BaseModel): """ - Options for parse_type 'discover', where Browser Run discovers URLs by link following and sitemaps. Ignored for 'sitemap'. + Options for parse_type 'discover', where Browser Run discovers URLs through link following and sitemaps. Ignored for 'sitemap'. """ depth: Optional[float] = None @@ -176,7 +197,7 @@ class SourceParamsWebCrawlerDiscoverOptions(BaseModel): include_external_links: Optional[bool] = None """Follow links that point outside the source domain. - Must stay `false` — discover crawls are restricted to the zone you own. + Must stay `false` because discover crawls only cover the zone you own. """ include_subdomains: Optional[bool] = None @@ -206,9 +227,9 @@ class SourceParamsWebCrawlerParseOptionsContentSelector(BaseModel): selector: str """CSS selector to extract content from pages matching the path pattern. - Must not contain disallowed characters (;, `, $, {, }, \\)). Must target a single - element; if multiple elements match, the selector is ignored and the full page - is used. + Disallowed characters: ;, `, $, {, }, \\.. Must target a single element; if + multiple elements match, the crawler ignores the selector and uses the full + page. """ @@ -217,15 +238,16 @@ class SourceParamsWebCrawlerParseOptions(BaseModel): """ List of path-to-selector mappings for extracting specific content from crawled pages. Each entry pairs a URL glob pattern with a CSS selector. The first - matching path wins. Only the matched HTML fragment is stored and indexed. Omit - the field to disable content selection — empty arrays are rejected. + matching path wins. The crawler stores and indexes only the matched HTML + fragment. Omit the field to disable content selection; the API rejects empty + arrays. """ include_headers: Optional[Dict[str, str]] = None """Up to 5 custom HTTP headers sent with each crawl request. - Names must be RFC-7230 token characters (no spaces, colons, or control - characters); values must be HTAB + printable ASCII (no CR/LF). + Names must use RFC-7230 token characters, excluding spaces, colons, and control + characters. Values must use HTAB and printable ASCII only, excluding CR and LF. """ include_images: Optional[bool] = None @@ -242,17 +264,17 @@ class SourceParamsWebCrawlerParseOptions(BaseModel): class SourceParamsWebCrawler(BaseModel): discover_options: Optional[SourceParamsWebCrawlerDiscoverOptions] = None """ - Options for parse_type 'discover', where Browser Run discovers URLs by link + Options for parse_type 'discover', where Browser Run discovers URLs through link following and sitemaps. Ignored for 'sitemap'. """ parse_options: Optional[SourceParamsWebCrawlerParseOptions] = None parse_type: Optional[Literal["sitemap", "discover"]] = None - """How URLs are discovered. + """How the crawler finds URLs. 'sitemap' reads XML sitemaps; 'discover' follows links recursively and requires - the source to be a Verified zone on this account. + the source to belong to a Verified zone on this account. """ @@ -262,7 +284,7 @@ class SourceParams(BaseModel): Uses micromatch glob syntax: \\** matches within a path segment, ** matches across path segments (e.g., /admin/** matches /admin/users and - /admin/settings/advanced). Most accounts are limited to 10 rules; contact + /admin/settings/advanced). Most accounts have a limit of 10 rules; contact support to raise it. """ @@ -271,7 +293,7 @@ class SourceParams(BaseModel): Uses micromatch glob syntax: \\** matches within a path segment, ** matches across path segments (e.g., /blog/** matches /blog/post and /blog/2024/post). Most - accounts are limited to 10 rules; contact support to raise it. + accounts have a limit of 10 rules; contact support to raise it. """ prefix: Optional[str] = None @@ -331,9 +353,10 @@ class InstanceDeleteResponse(BaseModel): """ index_method: Optional[IndexMethod] = None - """Controls which storage backends are used during indexing. + """Controls which storage backends indexing uses. - Defaults to vector and keyword indexing for new instances. + Defaults to vector and keyword indexing for new instances. When set, both vector + and keyword are required. """ indexing_options: Optional[IndexingOptions] = None @@ -369,6 +392,7 @@ class InstanceDeleteResponse(BaseModel): rewrite_query: Optional[bool] = None score_threshold: Optional[float] = None + """Minimum similarity score a chunk must reach to be returned. Defaults to 0.4.""" source: Optional[str] = None @@ -380,7 +404,7 @@ class InstanceDeleteResponse(BaseModel): """Interval between automatic syncs, in seconds. Allowed values: 900 (15min), 1800 (30min), 3600 (1h), 7200 (2h), 14400 (4h), - 21600 (6h), 43200 (12h), 86400 (24h). + 21600 (6h), 43200 (12h), 86400 (24h). Defaults to 86400 (24h). """ token_id: Optional[str] = None diff --git a/src/cloudflare/types/aisearch/namespaces/instance_list_params.py b/src/cloudflare/types/aisearch/namespaces/instance_list_params.py index 2dfe9258ac4..f88addd1845 100644 --- a/src/cloudflare/types/aisearch/namespaces/instance_list_params.py +++ b/src/cloudflare/types/aisearch/namespaces/instance_list_params.py @@ -11,10 +11,10 @@ class InstanceListParams(TypedDict, total=False): account_id: Required[str] hostname: str - """Filter by exact Search for Agents hostname (case-insensitive).""" - - namespace: str - """Filter by namespace.""" + """ + Return only instances with this exact Search for Agents hostname + (case-insensitive). + """ order_by: Literal["created_at"] """Field to order results by.""" diff --git a/src/cloudflare/types/aisearch/namespaces/instance_list_response.py b/src/cloudflare/types/aisearch/namespaces/instance_list_response.py index 803ad3bcdfe..bf6fb2ddb2f 100644 --- a/src/cloudflare/types/aisearch/namespaces/instance_list_response.py +++ b/src/cloudflare/types/aisearch/namespaces/instance_list_response.py @@ -14,6 +14,7 @@ "IndexMethod", "IndexingOptions", "Metadata", + "MetadataCreatedFromEmdashPlugin", "PublicEndpointParams", "PublicEndpointParamsChatCompletionsEndpoint", "PublicEndpointParamsMcp", @@ -71,9 +72,29 @@ def __getattr__(self, attr: str) -> object: ... __pydantic_extra__: Dict[str, object] +class MetadataCreatedFromEmdashPlugin(BaseModel): + type: Literal["native", "rest"] + + version: str + + if TYPE_CHECKING: + # Some versions of Pydantic <2.8.0 have a bug and don’t allow assigning a + # value to this field, so for compatibility we avoid doing it at runtime. + __pydantic_extra__: Dict[str, object] = FieldInfo(init=False) # pyright: ignore[reportIncompatibleVariableOverride] + + # Stub to indicate that arbitrary properties are accepted. + # To access properties that are not valid identifiers you can use `getattr`, e.g. + # `getattr(obj, '$type')` + def __getattr__(self, attr: str) -> object: ... + else: + __pydantic_extra__: Dict[str, object] + + class Metadata(BaseModel): created_from_aisearch_wizard: Optional[bool] = None + created_from_emdash_plugin: Optional[MetadataCreatedFromEmdashPlugin] = None + worker_domain: Optional[str] = None if TYPE_CHECKING: @@ -237,8 +258,8 @@ class SourceParamsWebCrawlerDiscoverOptions(BaseModel): limit: Optional[float] = None """Maximum number of pages to crawl. - New values are capped at 100000; instances configured before that cap may report - a higher stored value, which the crawler clamps at run time. + New values have a maximum of 100000; instances configured before that cap may + report a higher stored value, which the crawler clamps at run time. """ max_age: Optional[float] = None diff --git a/src/cloudflare/types/aisearch/namespaces/instance_move_params.py b/src/cloudflare/types/aisearch/namespaces/instance_move_params.py new file mode 100644 index 00000000000..a73a06911d2 --- /dev/null +++ b/src/cloudflare/types/aisearch/namespaces/instance_move_params.py @@ -0,0 +1,17 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Required, TypedDict + +__all__ = ["InstanceMoveParams"] + + +class InstanceMoveParams(TypedDict, total=False): + account_id: Required[str] + + namespace: Required[str] + """Current namespace of the instance.""" + + new_namespace: Required[str] + """Target namespace to move the instance into.""" diff --git a/src/cloudflare/types/aisearch/namespaces/instance_read_response.py b/src/cloudflare/types/aisearch/namespaces/instance_read_response.py index 9f2e2fbffe7..a3a7ee70d68 100644 --- a/src/cloudflare/types/aisearch/namespaces/instance_read_response.py +++ b/src/cloudflare/types/aisearch/namespaces/instance_read_response.py @@ -1,6 +1,6 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import Dict, List, Optional +from typing import TYPE_CHECKING, Dict, List, Optional from datetime import datetime from typing_extensions import Literal @@ -14,6 +14,7 @@ "IndexMethod", "IndexingOptions", "Metadata", + "MetadataCreatedFromEmdashPlugin", "PublicEndpointParams", "PublicEndpointParamsChatCompletionsEndpoint", "PublicEndpointParamsMcp", @@ -36,9 +37,9 @@ class CustomMetadata(BaseModel): class IndexMethod(BaseModel): - """Controls which storage backends are used during indexing. + """Controls which storage backends indexing uses. - Defaults to vector and keyword indexing for new instances. + Defaults to vector and keyword indexing for new instances. When set, both vector and keyword are required. """ keyword: bool @@ -65,22 +66,42 @@ class IndexingOptions(BaseModel): """ +class MetadataCreatedFromEmdashPlugin(BaseModel): + type: Literal["native", "rest"] + + version: str + + if TYPE_CHECKING: + # Some versions of Pydantic <2.8.0 have a bug and don’t allow assigning a + # value to this field, so for compatibility we avoid doing it at runtime. + __pydantic_extra__: Dict[str, object] = FieldInfo(init=False) # pyright: ignore[reportIncompatibleVariableOverride] + + # Stub to indicate that arbitrary properties are accepted. + # To access properties that are not valid identifiers you can use `getattr`, e.g. + # `getattr(obj, '$type')` + def __getattr__(self, attr: str) -> object: ... + else: + __pydantic_extra__: Dict[str, object] + + class Metadata(BaseModel): created_from_aisearch_wizard: Optional[bool] = None + created_from_emdash_plugin: Optional[MetadataCreatedFromEmdashPlugin] = None + worker_domain: Optional[str] = None class PublicEndpointParamsChatCompletionsEndpoint(BaseModel): disabled: Optional[bool] = None - """Disable chat completions endpoint for this public endpoint""" + """Disable chat completions endpoint for this public endpoint.""" class PublicEndpointParamsMcp(BaseModel): description: Optional[str] = None disabled: Optional[bool] = None - """Disable MCP endpoint for this public endpoint""" + """Disable MCP endpoint for this public endpoint.""" class PublicEndpointParamsRateLimit(BaseModel): @@ -93,7 +114,7 @@ class PublicEndpointParamsRateLimit(BaseModel): class PublicEndpointParamsSearchEndpoint(BaseModel): disabled: Optional[bool] = None - """Disable search endpoint for this public endpoint""" + """Disable search endpoint for this public endpoint.""" class PublicEndpointParams(BaseModel): @@ -156,18 +177,18 @@ class RetrievalOptions(BaseModel): """ keyword_match_mode: Optional[Literal["and", "or"]] = None - """Controls which documents are candidates for BM25 scoring. + """Controls which documents become candidates for BM25 scoring. 'and' restricts candidates to documents containing all query terms; 'or' - includes any document containing at least one term, ranked by BM25 relevance. - When omitted on an update, the existing stored value is preserved; when never - set, search falls back to 'and'. + includes any document containing at least one term and ranks results according + to BM25 relevance. When omitted on an update, the existing stored value stays + unchanged; when never set, search falls back to 'and'. """ class SourceParamsWebCrawlerDiscoverOptions(BaseModel): """ - Options for parse_type 'discover', where Browser Run discovers URLs by link following and sitemaps. Ignored for 'sitemap'. + Options for parse_type 'discover', where Browser Run discovers URLs through link following and sitemaps. Ignored for 'sitemap'. """ depth: Optional[float] = None @@ -176,7 +197,7 @@ class SourceParamsWebCrawlerDiscoverOptions(BaseModel): include_external_links: Optional[bool] = None """Follow links that point outside the source domain. - Must stay `false` — discover crawls are restricted to the zone you own. + Must stay `false` because discover crawls only cover the zone you own. """ include_subdomains: Optional[bool] = None @@ -206,9 +227,9 @@ class SourceParamsWebCrawlerParseOptionsContentSelector(BaseModel): selector: str """CSS selector to extract content from pages matching the path pattern. - Must not contain disallowed characters (;, `, $, {, }, \\)). Must target a single - element; if multiple elements match, the selector is ignored and the full page - is used. + Disallowed characters: ;, `, $, {, }, \\.. Must target a single element; if + multiple elements match, the crawler ignores the selector and uses the full + page. """ @@ -217,15 +238,16 @@ class SourceParamsWebCrawlerParseOptions(BaseModel): """ List of path-to-selector mappings for extracting specific content from crawled pages. Each entry pairs a URL glob pattern with a CSS selector. The first - matching path wins. Only the matched HTML fragment is stored and indexed. Omit - the field to disable content selection — empty arrays are rejected. + matching path wins. The crawler stores and indexes only the matched HTML + fragment. Omit the field to disable content selection; the API rejects empty + arrays. """ include_headers: Optional[Dict[str, str]] = None """Up to 5 custom HTTP headers sent with each crawl request. - Names must be RFC-7230 token characters (no spaces, colons, or control - characters); values must be HTAB + printable ASCII (no CR/LF). + Names must use RFC-7230 token characters, excluding spaces, colons, and control + characters. Values must use HTAB and printable ASCII only, excluding CR and LF. """ include_images: Optional[bool] = None @@ -242,17 +264,17 @@ class SourceParamsWebCrawlerParseOptions(BaseModel): class SourceParamsWebCrawler(BaseModel): discover_options: Optional[SourceParamsWebCrawlerDiscoverOptions] = None """ - Options for parse_type 'discover', where Browser Run discovers URLs by link + Options for parse_type 'discover', where Browser Run discovers URLs through link following and sitemaps. Ignored for 'sitemap'. """ parse_options: Optional[SourceParamsWebCrawlerParseOptions] = None parse_type: Optional[Literal["sitemap", "discover"]] = None - """How URLs are discovered. + """How the crawler finds URLs. 'sitemap' reads XML sitemaps; 'discover' follows links recursively and requires - the source to be a Verified zone on this account. + the source to belong to a Verified zone on this account. """ @@ -262,7 +284,7 @@ class SourceParams(BaseModel): Uses micromatch glob syntax: \\** matches within a path segment, ** matches across path segments (e.g., /admin/** matches /admin/users and - /admin/settings/advanced). Most accounts are limited to 10 rules; contact + /admin/settings/advanced). Most accounts have a limit of 10 rules; contact support to raise it. """ @@ -271,7 +293,7 @@ class SourceParams(BaseModel): Uses micromatch glob syntax: \\** matches within a path segment, ** matches across path segments (e.g., /blog/** matches /blog/post and /blog/2024/post). Most - accounts are limited to 10 rules; contact support to raise it. + accounts have a limit of 10 rules; contact support to raise it. """ prefix: Optional[str] = None @@ -331,9 +353,10 @@ class InstanceReadResponse(BaseModel): """ index_method: Optional[IndexMethod] = None - """Controls which storage backends are used during indexing. + """Controls which storage backends indexing uses. - Defaults to vector and keyword indexing for new instances. + Defaults to vector and keyword indexing for new instances. When set, both vector + and keyword are required. """ indexing_options: Optional[IndexingOptions] = None @@ -369,6 +392,7 @@ class InstanceReadResponse(BaseModel): rewrite_query: Optional[bool] = None score_threshold: Optional[float] = None + """Minimum similarity score a chunk must reach to be returned. Defaults to 0.4.""" source: Optional[str] = None @@ -380,7 +404,7 @@ class InstanceReadResponse(BaseModel): """Interval between automatic syncs, in seconds. Allowed values: 900 (15min), 1800 (30min), 3600 (1h), 7200 (2h), 14400 (4h), - 21600 (6h), 43200 (12h), 86400 (24h). + 21600 (6h), 43200 (12h), 86400 (24h). Defaults to 86400 (24h). """ token_id: Optional[str] = None diff --git a/src/cloudflare/types/aisearch/namespaces/instance_search_params.py b/src/cloudflare/types/aisearch/namespaces/instance_search_params.py index fee7cce207f..239a5915553 100644 --- a/src/cloudflare/types/aisearch/namespaces/instance_search_params.py +++ b/src/cloudflare/types/aisearch/namespaces/instance_search_params.py @@ -28,7 +28,7 @@ class InstanceSearchParams(TypedDict, total=False): account_id: Required[str] - name: Required[str] + namespace: Required[str] aisearch_options: Annotated[AISearchOptions, PropertyInfo(alias="ai_search_options")] @@ -110,17 +110,25 @@ class AISearchOptionsRetrieval(TypedDict, total=False): fusion_method: Literal["max", "rrf"] keyword_match_mode: Literal["and", "or"] - """Controls which documents are candidates for BM25 scoring. + """Controls which documents become candidates for BM25 scoring. 'and' restricts candidates to documents containing all query terms; 'or' - includes any document containing at least one term, ranked by BM25 relevance. - When omitted, falls back to the instance-level + includes any document containing at least one term and ranks results according + to BM25 relevance. When omitted, falls back to the instance-level retrieval_options.keyword_match_mode, then to 'and'. """ match_threshold: float + """Minimum similarity score a chunk must reach to be returned. + + When omitted, falls back to the instance-level score_threshold, then to 0.4. + """ max_num_results: int + """Maximum number of results to return. + + When omitted, falls back to the instance-level max_num_results, then to 10. + """ retrieval_type: Literal["vector", "keyword", "hybrid"] @@ -131,10 +139,10 @@ class AISearchOptions(TypedDict, total=False): cache: AISearchOptionsCache custom_metadata: Dict[str, Union[str, float, bool]] - """Metadata added to AI Gateway logs for requests triggered by this operation. + """Metadata added to AI Gateway logs for requests this operation triggers. - Accepts up to 2 string, number, or boolean entries. Keys 'ai-search', 'task', - 'origin', and keys beginning with 'cf.' are reserved. + Accepts up to 2 string, number, or boolean entries. Reserved keys: 'ai-search', + 'task', 'origin', and any key beginning with 'cf.'. """ query_rewrite: AISearchOptionsQueryRewrite diff --git a/src/cloudflare/types/aisearch/namespaces/instance_search_response.py b/src/cloudflare/types/aisearch/namespaces/instance_search_response.py index 7f325544195..165cf0ae590 100644 --- a/src/cloudflare/types/aisearch/namespaces/instance_search_response.py +++ b/src/cloudflare/types/aisearch/namespaces/instance_search_response.py @@ -41,8 +41,30 @@ class Chunk(BaseModel): item: Optional[ChunkItem] = None + media_end_ms: Optional[int] = None + """ + Audio/video transcript chunks only: end, in milliseconds from the start of the + media (whole seconds), of the last transcript section the matched chunk covers. + Describes the matched chunk before any context expansion, not the expanded + `text`. + """ + + media_start_ms: Optional[int] = None + """ + Audio/video transcript chunks only: start, in milliseconds from the start of the + media (whole seconds), of the transcript section the matched chunk begins in. + Describes the matched chunk before any context expansion, not the expanded + `text`. + """ + scoring_details: Optional[ChunkScoringDetails] = None + source_media_type: Optional[Literal["audio", "video"]] = None + """Audio/video transcript chunks only: type of the source media file. + + Omitted for all other chunks. + """ + class InstanceSearchResponse(BaseModel): chunks: List[Chunk] diff --git a/src/cloudflare/types/aisearch/namespaces/instance_stats_response.py b/src/cloudflare/types/aisearch/namespaces/instance_stats_response.py index 2a398343b7f..7a32a883f65 100644 --- a/src/cloudflare/types/aisearch/namespaces/instance_stats_response.py +++ b/src/cloudflare/types/aisearch/namespaces/instance_stats_response.py @@ -42,10 +42,10 @@ class InstanceStatsResponse(BaseModel): completed: Optional[int] = None degraded: Optional[bool] = None - """True when status counts are unavailable (e.g. + """True when the API cannot compute status counts (e.g. - legacy stats query exceeded D1 statement-size limit). Counts are omitted in this - case. + the legacy stats query exceeded the D1 statement-size limit). The response omits + counts in this case. """ engine: Optional[Engine] = None diff --git a/src/cloudflare/types/aisearch/namespaces/instance_update_params.py b/src/cloudflare/types/aisearch/namespaces/instance_update_params.py index 0c589ea76ca..ba4619f2768 100644 --- a/src/cloudflare/types/aisearch/namespaces/instance_update_params.py +++ b/src/cloudflare/types/aisearch/namespaces/instance_update_params.py @@ -14,6 +14,7 @@ "IndexMethod", "IndexingOptions", "Metadata", + "MetadataCreatedFromEmdashPlugin", "PublicEndpointParams", "PublicEndpointParamsChatCompletionsEndpoint", "PublicEndpointParamsMcp", @@ -32,7 +33,7 @@ class InstanceUpdateParams(TypedDict, total=False): account_id: Required[str] - name: Required[str] + namespace: Required[str] ai_gateway_id: Optional[str] @@ -66,9 +67,10 @@ class InstanceUpdateParams(TypedDict, total=False): fusion_method: Literal["max", "rrf"] index_method: IndexMethod - """Controls which storage backends are used during indexing. + """Controls which storage backends indexing uses. - Defaults to vector and keyword indexing for new instances. + Defaults to vector and keyword indexing for new instances. When set, both vector + and keyword are required. """ indexing_options: Optional[IndexingOptions] @@ -96,6 +98,7 @@ class InstanceUpdateParams(TypedDict, total=False): rewrite_query: bool score_threshold: float + """Minimum similarity score a chunk must reach to be returned. Defaults to 0.4.""" source: Optional[str] @@ -109,7 +112,7 @@ class InstanceUpdateParams(TypedDict, total=False): """Interval between automatic syncs, in seconds. Allowed values: 900 (15min), 1800 (30min), 3600 (1h), 7200 (2h), 14400 (4h), - 21600 (6h), 43200 (12h), 86400 (24h). + 21600 (6h), 43200 (12h), 86400 (24h). Defaults to 86400 (24h). """ system_prompt_aisearch: Annotated[Optional[str], PropertyInfo(alias="system_prompt_ai_search")] @@ -128,9 +131,9 @@ class CustomMetadata(TypedDict, total=False): class IndexMethod(TypedDict, total=False): - """Controls which storage backends are used during indexing. + """Controls which storage backends indexing uses. - Defaults to vector and keyword indexing for new instances. + Defaults to vector and keyword indexing for new instances. When set, both vector and keyword are required. """ keyword: Required[bool] @@ -157,22 +160,34 @@ class IndexingOptions(TypedDict, total=False): """ +class MetadataCreatedFromEmdashPlugin( # type: ignore[call-arg] + TypedDict, + total=False, + extra_items=object, # pyright: ignore[reportGeneralTypeIssues] +): + type: Required[Literal["native", "rest"]] + + version: Required[str] + + class Metadata(TypedDict, total=False): created_from_aisearch_wizard: bool + created_from_emdash_plugin: MetadataCreatedFromEmdashPlugin + worker_domain: str class PublicEndpointParamsChatCompletionsEndpoint(TypedDict, total=False): disabled: bool - """Disable chat completions endpoint for this public endpoint""" + """Disable chat completions endpoint for this public endpoint.""" class PublicEndpointParamsMcp(TypedDict, total=False): description: str disabled: bool - """Disable MCP endpoint for this public endpoint""" + """Disable MCP endpoint for this public endpoint.""" class PublicEndpointParamsRateLimit(TypedDict, total=False): @@ -185,7 +200,7 @@ class PublicEndpointParamsRateLimit(TypedDict, total=False): class PublicEndpointParamsSearchEndpoint(TypedDict, total=False): disabled: bool - """Disable search endpoint for this public endpoint""" + """Disable search endpoint for this public endpoint.""" class PublicEndpointParams(TypedDict, total=False): @@ -248,18 +263,18 @@ class RetrievalOptions(TypedDict, total=False): """ keyword_match_mode: Literal["and", "or"] - """Controls which documents are candidates for BM25 scoring. + """Controls which documents become candidates for BM25 scoring. 'and' restricts candidates to documents containing all query terms; 'or' - includes any document containing at least one term, ranked by BM25 relevance. - When omitted on an update, the existing stored value is preserved; when never - set, search falls back to 'and'. + includes any document containing at least one term and ranks results according + to BM25 relevance. When omitted on an update, the existing stored value stays + unchanged; when never set, search falls back to 'and'. """ class SourceParamsWebCrawlerDiscoverOptions(TypedDict, total=False): """ - Options for parse_type 'discover', where Browser Run discovers URLs by link following and sitemaps. Ignored for 'sitemap'. + Options for parse_type 'discover', where Browser Run discovers URLs through link following and sitemaps. Ignored for 'sitemap'. """ depth: float @@ -268,7 +283,7 @@ class SourceParamsWebCrawlerDiscoverOptions(TypedDict, total=False): include_external_links: bool """Follow links that point outside the source domain. - Must stay `false` — discover crawls are restricted to the zone you own. + Must stay `false` because discover crawls only cover the zone you own. """ include_subdomains: bool @@ -298,9 +313,9 @@ class SourceParamsWebCrawlerParseOptionsContentSelector(TypedDict, total=False): selector: Required[str] """CSS selector to extract content from pages matching the path pattern. - Must not contain disallowed characters (;, `, $, {, }, \\)). Must target a single - element; if multiple elements match, the selector is ignored and the full page - is used. + Disallowed characters: ;, `, $, {, }, \\.. Must target a single element; if + multiple elements match, the crawler ignores the selector and uses the full + page. """ @@ -309,15 +324,16 @@ class SourceParamsWebCrawlerParseOptions(TypedDict, total=False): """ List of path-to-selector mappings for extracting specific content from crawled pages. Each entry pairs a URL glob pattern with a CSS selector. The first - matching path wins. Only the matched HTML fragment is stored and indexed. Omit - the field to disable content selection — empty arrays are rejected. + matching path wins. The crawler stores and indexes only the matched HTML + fragment. Omit the field to disable content selection; the API rejects empty + arrays. """ include_headers: Dict[str, str] """Up to 5 custom HTTP headers sent with each crawl request. - Names must be RFC-7230 token characters (no spaces, colons, or control - characters); values must be HTAB + printable ASCII (no CR/LF). + Names must use RFC-7230 token characters, excluding spaces, colons, and control + characters. Values must use HTAB and printable ASCII only, excluding CR and LF. """ include_images: bool @@ -334,17 +350,17 @@ class SourceParamsWebCrawlerParseOptions(TypedDict, total=False): class SourceParamsWebCrawler(TypedDict, total=False): discover_options: SourceParamsWebCrawlerDiscoverOptions """ - Options for parse_type 'discover', where Browser Run discovers URLs by link + Options for parse_type 'discover', where Browser Run discovers URLs through link following and sitemaps. Ignored for 'sitemap'. """ parse_options: SourceParamsWebCrawlerParseOptions parse_type: Literal["sitemap", "discover"] - """How URLs are discovered. + """How the crawler finds URLs. 'sitemap' reads XML sitemaps; 'discover' follows links recursively and requires - the source to be a Verified zone on this account. + the source to belong to a Verified zone on this account. """ @@ -354,7 +370,7 @@ class SourceParams(TypedDict, total=False): Uses micromatch glob syntax: \\** matches within a path segment, ** matches across path segments (e.g., /admin/** matches /admin/users and - /admin/settings/advanced). Most accounts are limited to 10 rules; contact + /admin/settings/advanced). Most accounts have a limit of 10 rules; contact support to raise it. """ @@ -363,7 +379,7 @@ class SourceParams(TypedDict, total=False): Uses micromatch glob syntax: \\** matches within a path segment, ** matches across path segments (e.g., /blog/** matches /blog/post and /blog/2024/post). Most - accounts are limited to 10 rules; contact support to raise it. + accounts have a limit of 10 rules; contact support to raise it. """ prefix: str diff --git a/src/cloudflare/types/aisearch/namespaces/instance_update_response.py b/src/cloudflare/types/aisearch/namespaces/instance_update_response.py index 3242e838684..160cae72b5b 100644 --- a/src/cloudflare/types/aisearch/namespaces/instance_update_response.py +++ b/src/cloudflare/types/aisearch/namespaces/instance_update_response.py @@ -1,6 +1,6 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import Dict, List, Optional +from typing import TYPE_CHECKING, Dict, List, Optional from datetime import datetime from typing_extensions import Literal @@ -14,6 +14,7 @@ "IndexMethod", "IndexingOptions", "Metadata", + "MetadataCreatedFromEmdashPlugin", "PublicEndpointParams", "PublicEndpointParamsChatCompletionsEndpoint", "PublicEndpointParamsMcp", @@ -36,9 +37,9 @@ class CustomMetadata(BaseModel): class IndexMethod(BaseModel): - """Controls which storage backends are used during indexing. + """Controls which storage backends indexing uses. - Defaults to vector and keyword indexing for new instances. + Defaults to vector and keyword indexing for new instances. When set, both vector and keyword are required. """ keyword: bool @@ -65,22 +66,42 @@ class IndexingOptions(BaseModel): """ +class MetadataCreatedFromEmdashPlugin(BaseModel): + type: Literal["native", "rest"] + + version: str + + if TYPE_CHECKING: + # Some versions of Pydantic <2.8.0 have a bug and don’t allow assigning a + # value to this field, so for compatibility we avoid doing it at runtime. + __pydantic_extra__: Dict[str, object] = FieldInfo(init=False) # pyright: ignore[reportIncompatibleVariableOverride] + + # Stub to indicate that arbitrary properties are accepted. + # To access properties that are not valid identifiers you can use `getattr`, e.g. + # `getattr(obj, '$type')` + def __getattr__(self, attr: str) -> object: ... + else: + __pydantic_extra__: Dict[str, object] + + class Metadata(BaseModel): created_from_aisearch_wizard: Optional[bool] = None + created_from_emdash_plugin: Optional[MetadataCreatedFromEmdashPlugin] = None + worker_domain: Optional[str] = None class PublicEndpointParamsChatCompletionsEndpoint(BaseModel): disabled: Optional[bool] = None - """Disable chat completions endpoint for this public endpoint""" + """Disable chat completions endpoint for this public endpoint.""" class PublicEndpointParamsMcp(BaseModel): description: Optional[str] = None disabled: Optional[bool] = None - """Disable MCP endpoint for this public endpoint""" + """Disable MCP endpoint for this public endpoint.""" class PublicEndpointParamsRateLimit(BaseModel): @@ -93,7 +114,7 @@ class PublicEndpointParamsRateLimit(BaseModel): class PublicEndpointParamsSearchEndpoint(BaseModel): disabled: Optional[bool] = None - """Disable search endpoint for this public endpoint""" + """Disable search endpoint for this public endpoint.""" class PublicEndpointParams(BaseModel): @@ -156,18 +177,18 @@ class RetrievalOptions(BaseModel): """ keyword_match_mode: Optional[Literal["and", "or"]] = None - """Controls which documents are candidates for BM25 scoring. + """Controls which documents become candidates for BM25 scoring. 'and' restricts candidates to documents containing all query terms; 'or' - includes any document containing at least one term, ranked by BM25 relevance. - When omitted on an update, the existing stored value is preserved; when never - set, search falls back to 'and'. + includes any document containing at least one term and ranks results according + to BM25 relevance. When omitted on an update, the existing stored value stays + unchanged; when never set, search falls back to 'and'. """ class SourceParamsWebCrawlerDiscoverOptions(BaseModel): """ - Options for parse_type 'discover', where Browser Run discovers URLs by link following and sitemaps. Ignored for 'sitemap'. + Options for parse_type 'discover', where Browser Run discovers URLs through link following and sitemaps. Ignored for 'sitemap'. """ depth: Optional[float] = None @@ -176,7 +197,7 @@ class SourceParamsWebCrawlerDiscoverOptions(BaseModel): include_external_links: Optional[bool] = None """Follow links that point outside the source domain. - Must stay `false` — discover crawls are restricted to the zone you own. + Must stay `false` because discover crawls only cover the zone you own. """ include_subdomains: Optional[bool] = None @@ -206,9 +227,9 @@ class SourceParamsWebCrawlerParseOptionsContentSelector(BaseModel): selector: str """CSS selector to extract content from pages matching the path pattern. - Must not contain disallowed characters (;, `, $, {, }, \\)). Must target a single - element; if multiple elements match, the selector is ignored and the full page - is used. + Disallowed characters: ;, `, $, {, }, \\.. Must target a single element; if + multiple elements match, the crawler ignores the selector and uses the full + page. """ @@ -217,15 +238,16 @@ class SourceParamsWebCrawlerParseOptions(BaseModel): """ List of path-to-selector mappings for extracting specific content from crawled pages. Each entry pairs a URL glob pattern with a CSS selector. The first - matching path wins. Only the matched HTML fragment is stored and indexed. Omit - the field to disable content selection — empty arrays are rejected. + matching path wins. The crawler stores and indexes only the matched HTML + fragment. Omit the field to disable content selection; the API rejects empty + arrays. """ include_headers: Optional[Dict[str, str]] = None """Up to 5 custom HTTP headers sent with each crawl request. - Names must be RFC-7230 token characters (no spaces, colons, or control - characters); values must be HTAB + printable ASCII (no CR/LF). + Names must use RFC-7230 token characters, excluding spaces, colons, and control + characters. Values must use HTAB and printable ASCII only, excluding CR and LF. """ include_images: Optional[bool] = None @@ -242,17 +264,17 @@ class SourceParamsWebCrawlerParseOptions(BaseModel): class SourceParamsWebCrawler(BaseModel): discover_options: Optional[SourceParamsWebCrawlerDiscoverOptions] = None """ - Options for parse_type 'discover', where Browser Run discovers URLs by link + Options for parse_type 'discover', where Browser Run discovers URLs through link following and sitemaps. Ignored for 'sitemap'. """ parse_options: Optional[SourceParamsWebCrawlerParseOptions] = None parse_type: Optional[Literal["sitemap", "discover"]] = None - """How URLs are discovered. + """How the crawler finds URLs. 'sitemap' reads XML sitemaps; 'discover' follows links recursively and requires - the source to be a Verified zone on this account. + the source to belong to a Verified zone on this account. """ @@ -262,7 +284,7 @@ class SourceParams(BaseModel): Uses micromatch glob syntax: \\** matches within a path segment, ** matches across path segments (e.g., /admin/** matches /admin/users and - /admin/settings/advanced). Most accounts are limited to 10 rules; contact + /admin/settings/advanced). Most accounts have a limit of 10 rules; contact support to raise it. """ @@ -271,7 +293,7 @@ class SourceParams(BaseModel): Uses micromatch glob syntax: \\** matches within a path segment, ** matches across path segments (e.g., /blog/** matches /blog/post and /blog/2024/post). Most - accounts are limited to 10 rules; contact support to raise it. + accounts have a limit of 10 rules; contact support to raise it. """ prefix: Optional[str] = None @@ -331,9 +353,10 @@ class InstanceUpdateResponse(BaseModel): """ index_method: Optional[IndexMethod] = None - """Controls which storage backends are used during indexing. + """Controls which storage backends indexing uses. - Defaults to vector and keyword indexing for new instances. + Defaults to vector and keyword indexing for new instances. When set, both vector + and keyword are required. """ indexing_options: Optional[IndexingOptions] = None @@ -369,6 +392,7 @@ class InstanceUpdateResponse(BaseModel): rewrite_query: Optional[bool] = None score_threshold: Optional[float] = None + """Minimum similarity score a chunk must reach to be returned. Defaults to 0.4.""" source: Optional[str] = None @@ -380,7 +404,7 @@ class InstanceUpdateResponse(BaseModel): """Interval between automatic syncs, in seconds. Allowed values: 900 (15min), 1800 (30min), 3600 (1h), 7200 (2h), 14400 (4h), - 21600 (6h), 43200 (12h), 86400 (24h). + 21600 (6h), 43200 (12h), 86400 (24h). Defaults to 86400 (24h). """ token_id: Optional[str] = None diff --git a/src/cloudflare/types/aisearch/namespaces/instances/item_chunks_params.py b/src/cloudflare/types/aisearch/namespaces/instances/item_chunks_params.py index 3275c830099..3dd9c635d9e 100644 --- a/src/cloudflare/types/aisearch/namespaces/instances/item_chunks_params.py +++ b/src/cloudflare/types/aisearch/namespaces/instances/item_chunks_params.py @@ -10,7 +10,7 @@ class ItemChunksParams(TypedDict, total=False): account_id: Required[str] - name: Required[str] + namespace: Required[str] id: Required[str] """AI Search instance ID. Lowercase alphanumeric, hyphens, and underscores.""" diff --git a/src/cloudflare/types/aisearch/namespaces/instances/item_chunks_response.py b/src/cloudflare/types/aisearch/namespaces/instances/item_chunks_response.py index 8adb7ad1060..1f31066a62f 100644 --- a/src/cloudflare/types/aisearch/namespaces/instances/item_chunks_response.py +++ b/src/cloudflare/types/aisearch/namespaces/instances/item_chunks_response.py @@ -1,7 +1,7 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import Dict, List, Optional -from typing_extensions import TypeAlias +from typing_extensions import Literal, TypeAlias from ....._models import BaseModel @@ -25,6 +25,24 @@ class ItemChunksResponseItem(BaseModel): end_byte: Optional[float] = None + media_end_ms: Optional[int] = None + """ + Audio/video transcript chunks only: end, in milliseconds from the start of the + media (whole seconds), of the last transcript section the chunk covers. + """ + + media_start_ms: Optional[int] = None + """ + Audio/video transcript chunks only: start, in milliseconds from the start of the + media (whole seconds), of the transcript section the chunk begins in. + """ + + source_media_type: Optional[Literal["audio", "video"]] = None + """Audio/video transcript chunks only: type of the source media file. + + Omitted for all other chunks. + """ + start_byte: Optional[float] = None diff --git a/src/cloudflare/types/aisearch/namespaces/instances/item_create_or_update_params.py b/src/cloudflare/types/aisearch/namespaces/instances/item_create_or_update_params.py index 237cc3acaf5..24e9daade9b 100644 --- a/src/cloudflare/types/aisearch/namespaces/instances/item_create_or_update_params.py +++ b/src/cloudflare/types/aisearch/namespaces/instances/item_create_or_update_params.py @@ -10,7 +10,7 @@ class ItemCreateOrUpdateParams(TypedDict, total=False): account_id: Required[str] - name: Required[str] + namespace: Required[str] key: Required[str] """Item key / filename. Must not exceed 128 characters.""" @@ -18,10 +18,10 @@ class ItemCreateOrUpdateParams(TypedDict, total=False): next_action: Required[Literal["INDEX"]] wait_for_completion: bool - """Wait for indexing to fully complete before responding. + """Wait for indexing before responding. - On RAGs with vector indexing enabled, this additionally waits for Vectorize - ingestion confirmation (up to 40s) so the returned item reflects a queryable - state. On timeout the item is returned in `running` state and the background - alarm continues polling. Defaults to false. + After processing, vector-indexed instances use any time remaining in a 25s wait + budget to confirm Vectorize ingestion. Processing itself continues uninterrupted + and can exceed that budget. If confirmation times out, the response returns the + current item state and background indexing continues. Defaults to false. """ diff --git a/src/cloudflare/types/aisearch/namespaces/instances/item_list_params.py b/src/cloudflare/types/aisearch/namespaces/instances/item_list_params.py index dc6ad2992e6..78f169e0ad1 100644 --- a/src/cloudflare/types/aisearch/namespaces/instances/item_list_params.py +++ b/src/cloudflare/types/aisearch/namespaces/instances/item_list_params.py @@ -10,23 +10,23 @@ class ItemListParams(TypedDict, total=False): account_id: Required[str] - name: Required[str] + namespace: Required[str] item_id: str - """Filter items by their unique ID. Returns at most one item.""" + """Return only the item with this unique ID. Returns at most one item.""" key: str - """Filter items by their exact key (object key / filename). + """Return only items with this exact key (object key / filename). - Keys are unique per source, so combine with `source` to disambiguate across data - sources. + Each key is unique within a source, so combine with `source` to disambiguate + across data sources. """ metadata_filter: str """JSON-encoded metadata filter using Vectorize filter syntax. Examples: {"folder":"reports/"}, - {"timestamp":{"$gte":1700000000000}}, {"folder":{"$in":["docs/","reports/"]}} + {"timestamp":{"$gte":1700000000000}}, {"folder":{"$in":["docs/","reports/"]}}. """ page: int @@ -38,12 +38,13 @@ class ItemListParams(TypedDict, total=False): sort_by: Literal["status", "modified_at"] """Sort order for items. - "status" (default) sorts by status priority then last_seen_at. "modified_at" - sorts by file modification time (most recent first), falling back to created_at. + "status" (default) sorts items according to status priority, then last_seen_at. + "modified_at" sorts items according to file modification time (most recent + first), falling back to created_at. """ source: str - """Filter items by source_id. + """Return only items with this source_id. Use "builtin" for uploaded files, or a source identifier like "web-crawler:https://example.com". diff --git a/src/cloudflare/types/aisearch/namespaces/instances/item_logs_params.py b/src/cloudflare/types/aisearch/namespaces/instances/item_logs_params.py index 3f4ac7414e7..3153923ee9c 100644 --- a/src/cloudflare/types/aisearch/namespaces/instances/item_logs_params.py +++ b/src/cloudflare/types/aisearch/namespaces/instances/item_logs_params.py @@ -10,7 +10,7 @@ class ItemLogsParams(TypedDict, total=False): account_id: Required[str] - name: Required[str] + namespace: Required[str] id: Required[str] """AI Search instance ID. Lowercase alphanumeric, hyphens, and underscores.""" diff --git a/src/cloudflare/types/aisearch/namespaces/instances/item_sync_params.py b/src/cloudflare/types/aisearch/namespaces/instances/item_sync_params.py index 6fa679fe3b6..a698bb1e902 100644 --- a/src/cloudflare/types/aisearch/namespaces/instances/item_sync_params.py +++ b/src/cloudflare/types/aisearch/namespaces/instances/item_sync_params.py @@ -10,7 +10,7 @@ class ItemSyncParams(TypedDict, total=False): account_id: Required[str] - name: Required[str] + namespace: Required[str] id: Required[str] """AI Search instance ID. Lowercase alphanumeric, hyphens, and underscores.""" @@ -18,10 +18,10 @@ class ItemSyncParams(TypedDict, total=False): next_action: Required[Literal["INDEX"]] wait_for_completion: bool - """Wait for indexing to fully complete before responding. + """Wait for indexing before responding. - On RAGs with vector indexing enabled, this additionally waits for Vectorize - ingestion confirmation (up to 40s) so the returned item reflects a queryable - state. On timeout the item is returned in `running` state and the background - alarm continues polling. Defaults to false. + After processing, vector-indexed instances use any time remaining in a 25s wait + budget to confirm Vectorize ingestion. Processing itself continues uninterrupted + and can exceed that budget. If confirmation times out, the response returns the + current item state and background indexing continues. Defaults to false. """ diff --git a/src/cloudflare/types/aisearch/namespaces/instances/item_upload_params.py b/src/cloudflare/types/aisearch/namespaces/instances/item_upload_params.py index 1978a300898..5f03bef8dfe 100644 --- a/src/cloudflare/types/aisearch/namespaces/instances/item_upload_params.py +++ b/src/cloudflare/types/aisearch/namespaces/instances/item_upload_params.py @@ -12,7 +12,7 @@ class ItemUploadParams(TypedDict, total=False): account_id: Required[str] - name: Required[str] + namespace: Required[str] file: Required[File] @@ -25,10 +25,10 @@ class File(TypedDict, total=False): """JSON string of custom metadata key-value pairs.""" wait_for_completion: bool - """Wait for indexing to fully complete before responding. + """Wait for indexing before responding. - On RAGs with vector indexing enabled, this additionally waits for Vectorize - ingestion confirmation (up to 40s) so the returned item reflects a queryable - state. On timeout the item is returned in `running` state and the background - alarm continues polling. Defaults to false. + After processing, vector-indexed instances use any time remaining in a 25s wait + budget to confirm Vectorize ingestion. Processing itself continues uninterrupted + and can exceed that budget. If confirmation times out, the response returns the + current item state and background indexing continues. Defaults to false. """ diff --git a/src/cloudflare/types/aisearch/namespaces/instances/job_create_params.py b/src/cloudflare/types/aisearch/namespaces/instances/job_create_params.py index b84f5b1e3ce..7ec22a4df27 100644 --- a/src/cloudflare/types/aisearch/namespaces/instances/job_create_params.py +++ b/src/cloudflare/types/aisearch/namespaces/instances/job_create_params.py @@ -10,6 +10,6 @@ class JobCreateParams(TypedDict, total=False): account_id: Required[str] - name: Required[str] + namespace: Required[str] description: str diff --git a/src/cloudflare/types/aisearch/namespaces/instances/job_list_params.py b/src/cloudflare/types/aisearch/namespaces/instances/job_list_params.py index 0b4154a1d55..0ddb050a91a 100644 --- a/src/cloudflare/types/aisearch/namespaces/instances/job_list_params.py +++ b/src/cloudflare/types/aisearch/namespaces/instances/job_list_params.py @@ -10,7 +10,7 @@ class JobListParams(TypedDict, total=False): account_id: Required[str] - name: Required[str] + namespace: Required[str] page: int diff --git a/src/cloudflare/types/aisearch/namespaces/instances/job_logs_params.py b/src/cloudflare/types/aisearch/namespaces/instances/job_logs_params.py index cac6f72546e..6c1d9d424cc 100644 --- a/src/cloudflare/types/aisearch/namespaces/instances/job_logs_params.py +++ b/src/cloudflare/types/aisearch/namespaces/instances/job_logs_params.py @@ -10,7 +10,7 @@ class JobLogsParams(TypedDict, total=False): account_id: Required[str] - name: Required[str] + namespace: Required[str] id: Required[str] """AI Search instance ID. Lowercase alphanumeric, hyphens, and underscores.""" diff --git a/src/cloudflare/types/aisearch/namespaces/instances/job_update_params.py b/src/cloudflare/types/aisearch/namespaces/instances/job_update_params.py index ebf1cea00cd..d05d5c76ae1 100644 --- a/src/cloudflare/types/aisearch/namespaces/instances/job_update_params.py +++ b/src/cloudflare/types/aisearch/namespaces/instances/job_update_params.py @@ -10,7 +10,7 @@ class JobUpdateParams(TypedDict, total=False): account_id: Required[str] - name: Required[str] + namespace: Required[str] id: Required[str] """AI Search instance ID. Lowercase alphanumeric, hyphens, and underscores.""" diff --git a/src/cloudflare/types/api_gateway/discovery/__init__.py b/src/cloudflare/types/api_gateway/discovery/__init__.py index 6a6a83a8989..40378bcab0c 100644 --- a/src/cloudflare/types/api_gateway/discovery/__init__.py +++ b/src/cloudflare/types/api_gateway/discovery/__init__.py @@ -2,6 +2,8 @@ from __future__ import annotations +from .operation_edit_params import OperationEditParams as OperationEditParams from .operation_list_params import OperationListParams as OperationListParams +from .operation_edit_response import OperationEditResponse as OperationEditResponse from .operation_bulk_edit_params import OperationBulkEditParams as OperationBulkEditParams from .operation_bulk_edit_response import OperationBulkEditResponse as OperationBulkEditResponse diff --git a/src/cloudflare/types/api_gateway/discovery/operation_edit_params.py b/src/cloudflare/types/api_gateway/discovery/operation_edit_params.py new file mode 100644 index 00000000000..8431ce868d8 --- /dev/null +++ b/src/cloudflare/types/api_gateway/discovery/operation_edit_params.py @@ -0,0 +1,19 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal, Required, TypedDict + +__all__ = ["OperationEditParams"] + + +class OperationEditParams(TypedDict, total=False): + zone_id: Required[str] + """Identifier.""" + + state: Literal["review", "ignored"] + """Mark state of operation in API Discovery + + - `review` - Mark operation as for review + - `ignored` - Mark operation as ignored + """ diff --git a/src/cloudflare/types/api_gateway/discovery/operation_edit_response.py b/src/cloudflare/types/api_gateway/discovery/operation_edit_response.py new file mode 100644 index 00000000000..ff7f58a5efc --- /dev/null +++ b/src/cloudflare/types/api_gateway/discovery/operation_edit_response.py @@ -0,0 +1,18 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional +from typing_extensions import Literal + +from ...._models import BaseModel + +__all__ = ["OperationEditResponse"] + + +class OperationEditResponse(BaseModel): + state: Optional[Literal["review", "saved", "ignored"]] = None + """State of operation in API Discovery + + - `review` - Operation is not saved into API Shield Endpoint Management + - `saved` - Operation is saved into API Shield Endpoint Management + - `ignored` - Operation is marked as ignored + """ diff --git a/src/cloudflare/types/argo/tiered_caching_edit_params.py b/src/cloudflare/types/argo/tiered_caching_edit_params.py index 1a1702873c2..8399d4ae182 100644 --- a/src/cloudflare/types/argo/tiered_caching_edit_params.py +++ b/src/cloudflare/types/argo/tiered_caching_edit_params.py @@ -12,4 +12,4 @@ class TieredCachingEditParams(TypedDict, total=False): """Identifier.""" value: Required[Literal["on", "off"]] - """Enables Tiered Caching.""" + """Enables or disables Tiered Cache.""" diff --git a/src/cloudflare/types/basin_catalog/__init__.py b/src/cloudflare/types/basin_catalog/__init__.py index cf998b4ed66..c5c888db69c 100644 --- a/src/cloudflare/types/basin_catalog/__init__.py +++ b/src/cloudflare/types/basin_catalog/__init__.py @@ -7,6 +7,7 @@ from .credential_create_params import CredentialCreateParams as CredentialCreateParams from .basin_catalog_get_response import BasinCatalogGetResponse as BasinCatalogGetResponse from .basin_catalog_delete_params import BasinCatalogDeleteParams as BasinCatalogDeleteParams +from .basin_catalog_enable_params import BasinCatalogEnableParams as BasinCatalogEnableParams from .basin_catalog_list_response import BasinCatalogListResponse as BasinCatalogListResponse from .basin_catalog_enable_response import BasinCatalogEnableResponse as BasinCatalogEnableResponse from .maintenance_config_get_response import MaintenanceConfigGetResponse as MaintenanceConfigGetResponse diff --git a/src/cloudflare/types/basin_catalog/basin_catalog_enable_params.py b/src/cloudflare/types/basin_catalog/basin_catalog_enable_params.py new file mode 100644 index 00000000000..7e60bbcadc1 --- /dev/null +++ b/src/cloudflare/types/basin_catalog/basin_catalog_enable_params.py @@ -0,0 +1,22 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Required, TypedDict + +__all__ = ["BasinCatalogEnableParams", "Credential"] + + +class BasinCatalogEnableParams(TypedDict, total=False): + account_id: Required[str] + """Use this to identify the account.""" + + credential: Credential + """Contains request to store catalog credentials.""" + + +class Credential(TypedDict, total=False): + """Contains request to store catalog credentials.""" + + token: Required[str] + """Provides the Cloudflare API token for accessing R2.""" diff --git a/src/cloudflare/types/basin_catalog/basin_catalog_get_response.py b/src/cloudflare/types/basin_catalog/basin_catalog_get_response.py index c1a73e17d6f..a403f218047 100644 --- a/src/cloudflare/types/basin_catalog/basin_catalog_get_response.py +++ b/src/cloudflare/types/basin_catalog/basin_catalog_get_response.py @@ -55,7 +55,7 @@ class MaintenanceConfig(BaseModel): class BasinCatalogGetResponse(BaseModel): - """Contains R2 Data Catalog information.""" + """Contains catalog information.""" id: str """Use this to uniquely identify the catalog.""" @@ -72,5 +72,11 @@ class BasinCatalogGetResponse(BaseModel): credential_status: Optional[Literal["present", "absent"]] = None """Shows the credential configuration status.""" + jurisdiction: Optional[str] = None + """Specifies the data-locality jurisdiction of the catalog. + + The first enable sets it, and it cannot change. Currently always `default`. + """ + maintenance_config: Optional[MaintenanceConfig] = None """Configures maintenance for the catalog.""" diff --git a/src/cloudflare/types/basin_catalog/basin_catalog_list_response.py b/src/cloudflare/types/basin_catalog/basin_catalog_list_response.py index da466dc3858..81c97a3031a 100644 --- a/src/cloudflare/types/basin_catalog/basin_catalog_list_response.py +++ b/src/cloudflare/types/basin_catalog/basin_catalog_list_response.py @@ -56,7 +56,7 @@ class WarehouseMaintenanceConfig(BaseModel): class Warehouse(BaseModel): - """Contains R2 Data Catalog information.""" + """Contains catalog information.""" id: str """Use this to uniquely identify the catalog.""" @@ -73,6 +73,12 @@ class Warehouse(BaseModel): credential_status: Optional[Literal["present", "absent"]] = None """Shows the credential configuration status.""" + jurisdiction: Optional[str] = None + """Specifies the data-locality jurisdiction of the catalog. + + The first enable sets it, and it cannot change. Currently always `default`. + """ + maintenance_config: Optional[WarehouseMaintenanceConfig] = None """Configures maintenance for the catalog.""" diff --git a/src/cloudflare/types/billing/__init__.py b/src/cloudflare/types/billing/__init__.py index 7144c423928..cf6a7574319 100644 --- a/src/cloudflare/types/billing/__init__.py +++ b/src/cloudflare/types/billing/__init__.py @@ -16,8 +16,15 @@ from .rate_plan_get_response import RatePlanGetResponse as RatePlanGetResponse from .profile_create_response import ProfileCreateResponse as ProfileCreateResponse from .profile_update_response import ProfileUpdateResponse as ProfileUpdateResponse +from .spend_policy_get_response import SpendPolicyGetResponse as SpendPolicyGetResponse from .usage_paygo_info_response import UsagePaygoInfoResponse as UsagePaygoInfoResponse +from .spend_policy_create_params import SpendPolicyCreateParams as SpendPolicyCreateParams +from .spend_policy_list_response import SpendPolicyListResponse as SpendPolicyListResponse +from .spend_policy_update_params import SpendPolicyUpdateParams as SpendPolicyUpdateParams from .unpaid_invoice_get_response import UnpaidInvoiceGetResponse as UnpaidInvoiceGetResponse +from .spend_policy_create_response import SpendPolicyCreateResponse as SpendPolicyCreateResponse +from .spend_policy_delete_response import SpendPolicyDeleteResponse as SpendPolicyDeleteResponse +from .spend_policy_update_response import SpendPolicyUpdateResponse as SpendPolicyUpdateResponse from .billing_address_validation_params import BillingAddressValidationParams as BillingAddressValidationParams from .usage_get_account_usage_v1_params import UsageGetAccountUsageV1Params as UsageGetAccountUsageV1Params from .usage_get_account_usage_v2_params import UsageGetAccountUsageV2Params as UsageGetAccountUsageV2Params diff --git a/src/cloudflare/types/billing/spend_policies/__init__.py b/src/cloudflare/types/billing/spend_policies/__init__.py new file mode 100644 index 00000000000..7d9325c0f28 --- /dev/null +++ b/src/cloudflare/types/billing/spend_policies/__init__.py @@ -0,0 +1,8 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from .audit_list_params import AuditListParams as AuditListParams +from .audit_list_response import AuditListResponse as AuditListResponse +from .activity_list_params import ActivityListParams as ActivityListParams +from .activity_list_response import ActivityListResponse as ActivityListResponse diff --git a/src/cloudflare/types/billing/spend_policies/activity_list_params.py b/src/cloudflare/types/billing/spend_policies/activity_list_params.py new file mode 100644 index 00000000000..c01d359be5e --- /dev/null +++ b/src/cloudflare/types/billing/spend_policies/activity_list_params.py @@ -0,0 +1,27 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal, Required, TypedDict + +__all__ = ["ActivityListParams"] + + +class ActivityListParams(TypedDict, total=False): + account_id: Required[str] + """Represents a Cloudflare resource identifier tag.""" + + cursor: str + """Opaque token from the preceding response's result_info.cursor. + + Pass it unchanged to retrieve older entries. + """ + + limit: int + """Maximum number of audit entries to return. + + Defaults to 50. Values above 100 are capped at 100 rather than rejected. + """ + + period: Literal["current_billing_cycle", "all"] + """Select current subscription billing-cycle history or history across all cycles.""" diff --git a/src/cloudflare/types/billing/spend_policies/activity_list_response.py b/src/cloudflare/types/billing/spend_policies/activity_list_response.py new file mode 100644 index 00000000000..5540d014a05 --- /dev/null +++ b/src/cloudflare/types/billing/spend_policies/activity_list_response.py @@ -0,0 +1,260 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional +from datetime import datetime +from typing_extensions import Literal + +from ...._models import BaseModel + +__all__ = [ + "ActivityListResponse", + "Details", + "DetailsAfter", + "DetailsAfterCurrentState", + "DetailsAfterCurrentStateEnforcement", + "DetailsBefore", + "DetailsBeforeCurrentState", + "DetailsBeforeCurrentStateEnforcement", +] + + +class DetailsAfterCurrentStateEnforcement(BaseModel): + """ + Durable desired cap and delivery bookkeeping for this policy, or null if no owned effect exists. Separate from threshold evaluation: pending/leased/retry can lag the new billing period. Succeeded with equal generations means delivery completed, not an EWC readback. + """ + + applied_generation: int + + delivery_status: Literal["pending", "leased", "retry", "succeeded"] + + desired_generation: int + + desired_state: Literal["active", "inactive"] + + expires_at: Optional[datetime] = None + + +class DetailsAfterCurrentState(BaseModel): + """ + Read-only state on list/get responses, evaluated from the latest owning projector snapshot at request time, independently of the API replica. Configuration enabled/version/ETag do not change when a cycle rolls over. Audit history remains unchanged. Missing during a rolling upgrade or on mutation responses; clients must treat missing state as unavailable. Balances are asynchronous estimates, not a synchronous usage read. + """ + + balance_cents: Optional[int] = None + + billing_period_end: Optional[datetime] = None + + billing_period_start: Optional[datetime] = None + + enforcement: Optional[DetailsAfterCurrentStateEnforcement] = None + """ + Durable desired cap and delivery bookkeeping for this policy, or null if no + owned effect exists. Separate from threshold evaluation: pending/leased/retry + can lag the new billing period. Succeeded with equal generations means delivery + completed, not an EWC readback. + """ + + evaluated_at: datetime + """Evaluation time; not the timestamp of the latest usage event.""" + + status: Literal["disabled", "no_current_period", "unavailable", "below_limit", "limit_reached"] + """Threshold evaluation, not proof of an edge cap. + + No current active period yields no_current_period for enabled policies; failed + aggregate reads yield unavailable for enabled policies. Disabled policies report + disabled. Neither no_current_period nor unavailable implies a zero balance or + below-limit state. Operators may disable current-state reads, in which case + current_state is omitted. + """ + + +class DetailsAfter(BaseModel): + """A spend policy.""" + + id: str + """The unique identifier of the spend policy.""" + + account_id: int + """Internal numeric ID of the account that owns the policy. + + This is not the account tag used in the path. + """ + + action: Literal["notification", "usage_block"] + """The action taken when the threshold is reached. + + `notification` sends an email to `notification_email`. `usage_block` blocks + further usage of the product until the end of the billing period. Raising the + threshold above the current balance, disabling the policy, or deleting it lifts + the block early. + """ + + enabled: bool + """Whether the policy is evaluated.""" + + name: str + """Display name of the policy.""" + + notification_email: str + """Email address that receives notifications. An empty string when none is set.""" + + product_id: Literal["workers", "durable_objects"] + """The product the policy applies to: `workers` or `durable_objects`. + + Each product's balance and policies are separate. Both products support + `notification` and `usage_block` policies on create and update. + """ + + threshold_cents: int + """The spend threshold for the current billing period, in US cents.""" + + version: int + """Optimistic-concurrency version. + + It starts at 1 and goes up by one on every update or delete. This value is also + returned in `ETag`. + """ + + current_state: Optional[DetailsAfterCurrentState] = None + """ + Read-only state on list/get responses, evaluated from the latest owning + projector snapshot at request time, independently of the API replica. + Configuration enabled/version/ETag do not change when a cycle rolls over. Audit + history remains unchanged. Missing during a rolling upgrade or on mutation + responses; clients must treat missing state as unavailable. Balances are + asynchronous estimates, not a synchronous usage read. + """ + + +class DetailsBeforeCurrentStateEnforcement(BaseModel): + """ + Durable desired cap and delivery bookkeeping for this policy, or null if no owned effect exists. Separate from threshold evaluation: pending/leased/retry can lag the new billing period. Succeeded with equal generations means delivery completed, not an EWC readback. + """ + + applied_generation: int + + delivery_status: Literal["pending", "leased", "retry", "succeeded"] + + desired_generation: int + + desired_state: Literal["active", "inactive"] + + expires_at: Optional[datetime] = None + + +class DetailsBeforeCurrentState(BaseModel): + """ + Read-only state on list/get responses, evaluated from the latest owning projector snapshot at request time, independently of the API replica. Configuration enabled/version/ETag do not change when a cycle rolls over. Audit history remains unchanged. Missing during a rolling upgrade or on mutation responses; clients must treat missing state as unavailable. Balances are asynchronous estimates, not a synchronous usage read. + """ + + balance_cents: Optional[int] = None + + billing_period_end: Optional[datetime] = None + + billing_period_start: Optional[datetime] = None + + enforcement: Optional[DetailsBeforeCurrentStateEnforcement] = None + """ + Durable desired cap and delivery bookkeeping for this policy, or null if no + owned effect exists. Separate from threshold evaluation: pending/leased/retry + can lag the new billing period. Succeeded with equal generations means delivery + completed, not an EWC readback. + """ + + evaluated_at: datetime + """Evaluation time; not the timestamp of the latest usage event.""" + + status: Literal["disabled", "no_current_period", "unavailable", "below_limit", "limit_reached"] + """Threshold evaluation, not proof of an edge cap. + + No current active period yields no_current_period for enabled policies; failed + aggregate reads yield unavailable for enabled policies. Disabled policies report + disabled. Neither no_current_period nor unavailable implies a zero balance or + below-limit state. Operators may disable current-state reads, in which case + current_state is omitted. + """ + + +class DetailsBefore(BaseModel): + """Prior configuration; null on creation or if a previous revision is unavailable.""" + + id: str + """The unique identifier of the spend policy.""" + + account_id: int + """Internal numeric ID of the account that owns the policy. + + This is not the account tag used in the path. + """ + + action: Literal["notification", "usage_block"] + """The action taken when the threshold is reached. + + `notification` sends an email to `notification_email`. `usage_block` blocks + further usage of the product until the end of the billing period. Raising the + threshold above the current balance, disabling the policy, or deleting it lifts + the block early. + """ + + enabled: bool + """Whether the policy is evaluated.""" + + name: str + """Display name of the policy.""" + + notification_email: str + """Email address that receives notifications. An empty string when none is set.""" + + product_id: Literal["workers", "durable_objects"] + """The product the policy applies to: `workers` or `durable_objects`. + + Each product's balance and policies are separate. Both products support + `notification` and `usage_block` policies on create and update. + """ + + threshold_cents: int + """The spend threshold for the current billing period, in US cents.""" + + version: int + """Optimistic-concurrency version. + + It starts at 1 and goes up by one on every update or delete. This value is also + returned in `ETag`. + """ + + current_state: Optional[DetailsBeforeCurrentState] = None + """ + Read-only state on list/get responses, evaluated from the latest owning + projector snapshot at request time, independently of the API replica. + Configuration enabled/version/ETag do not change when a cycle rolls over. Audit + history remains unchanged. Missing during a rolling upgrade or on mutation + responses; clients must treat missing state as unavailable. Balances are + asynchronous estimates, not a synchronous usage read. + """ + + +class Details(BaseModel): + after: Optional[DetailsAfter] = None + """A spend policy.""" + + before: Optional[DetailsBefore] = None + """Prior configuration; null on creation or if a previous revision is unavailable.""" + + +class ActivityListResponse(BaseModel): + id: str + + action: Literal["created", "updated", "enabled", "disabled", "deleted"] + + actor: str + """Verified actor identifier, unknown when absent, or trusted internal actor.""" + + details: Details + + occurred_at: datetime + + policy_id: str + """The unique identifier of the spend policy.""" + + policy_version: int + + product_id: str diff --git a/src/cloudflare/types/billing/spend_policies/audit_list_params.py b/src/cloudflare/types/billing/spend_policies/audit_list_params.py new file mode 100644 index 00000000000..f2871e120ca --- /dev/null +++ b/src/cloudflare/types/billing/spend_policies/audit_list_params.py @@ -0,0 +1,21 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal, Required, TypedDict + +__all__ = ["AuditListParams"] + + +class AuditListParams(TypedDict, total=False): + account_id: Required[str] + """Represents a Cloudflare resource identifier tag.""" + + limit: int + """Maximum number of audit entries to return. + + Defaults to 50. Values above 100 are capped at 100 rather than rejected. + """ + + period: Literal["current_billing_cycle", "all"] + """Select current subscription billing-cycle history or history across all cycles.""" diff --git a/src/cloudflare/types/billing/spend_policies/audit_list_response.py b/src/cloudflare/types/billing/spend_policies/audit_list_response.py new file mode 100644 index 00000000000..acc2221a304 --- /dev/null +++ b/src/cloudflare/types/billing/spend_policies/audit_list_response.py @@ -0,0 +1,57 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from datetime import datetime +from typing_extensions import Literal + +from ...._models import BaseModel + +__all__ = ["AuditListResponse"] + + +class AuditListResponse(BaseModel): + """ + A state transition recorded when the policy was evaluated against the account's balance. + """ + + action: Literal["notification", "usage_block"] + """The action taken when the threshold is reached. + + `notification` sends an email to `notification_email`. `usage_block` blocks + further usage of the product until the end of the billing period. Raising the + threshold above the current balance, disabling the policy, or deleting it lifts + the block early. + """ + + balance_cents: int + """The account's balance for the product at evaluation time, in US cents.""" + + billing_period_end: datetime + """Exclusive end of the billing period that was evaluated.""" + + billing_period_start: datetime + """Inclusive start of the billing period that was evaluated.""" + + created_at: datetime + """When the entry was recorded.""" + + policy_version: int + """The policy `version` that was evaluated.""" + + reason: str + """A human-readable explanation of the trigger.""" + + source: Literal["kafka", "policy_revision"] + """What caused the evaluation. + + `kafka` means a balance update. `policy_revision` means a change to the policy. + """ + + threshold_cents: int + """The policy threshold at evaluation time, in US cents.""" + + trigger: str + """The trigger recorded at evaluation time. + + New evaluations record `limit_reached` when the balance reaches or exceeds the + configured threshold. Earlier entries retain their recorded trigger. + """ diff --git a/src/cloudflare/types/billing/spend_policy_create_params.py b/src/cloudflare/types/billing/spend_policy_create_params.py new file mode 100644 index 00000000000..b1d78b9bd4e --- /dev/null +++ b/src/cloudflare/types/billing/spend_policy_create_params.py @@ -0,0 +1,52 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal, Required, TypedDict + +__all__ = ["SpendPolicyCreateParams"] + + +class SpendPolicyCreateParams(TypedDict, total=False): + account_id: Required[str] + """Represents a Cloudflare resource identifier tag.""" + + action: Required[Literal["notification", "usage_block"]] + """The action taken when the threshold is reached. + + `notification` sends an email to `notification_email`. `usage_block` blocks + further usage of the product until the end of the billing period. Raising the + threshold above the current balance, disabling the policy, or deleting it lifts + the block early. + """ + + enabled: Required[bool] + """Whether the policy is evaluated.""" + + name: Required[str] + """Display name of the policy. + + After surrounding whitespace is trimmed, it must be 1 to 200 bytes long. The + value is stored as sent, untrimmed. + """ + + product_id: Required[Literal["workers", "durable_objects"]] + """The product the policy applies to: `workers` or `durable_objects`. + + Each product's balance and policies are separate. Both products support + `notification` and `usage_block` policies on create and update. + """ + + threshold_cents: Required[int] + """The spend threshold for the current billing period, in US cents. + + Must be greater than zero. + """ + + notification_email: str + """Email address that receives notifications. + + Required when `action` is `notification`. When set, it must be a bare address + (`user@example.com`); display-name forms such as `Name ` are + rejected. + """ diff --git a/src/cloudflare/types/billing/spend_policy_create_response.py b/src/cloudflare/types/billing/spend_policy_create_response.py new file mode 100644 index 00000000000..bd4485a402c --- /dev/null +++ b/src/cloudflare/types/billing/spend_policy_create_response.py @@ -0,0 +1,116 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional +from datetime import datetime +from typing_extensions import Literal + +from ..._models import BaseModel + +__all__ = ["SpendPolicyCreateResponse", "CurrentState", "CurrentStateEnforcement"] + + +class CurrentStateEnforcement(BaseModel): + """ + Durable desired cap and delivery bookkeeping for this policy, or null if no owned effect exists. Separate from threshold evaluation: pending/leased/retry can lag the new billing period. Succeeded with equal generations means delivery completed, not an EWC readback. + """ + + applied_generation: int + + delivery_status: Literal["pending", "leased", "retry", "succeeded"] + + desired_generation: int + + desired_state: Literal["active", "inactive"] + + expires_at: Optional[datetime] = None + + +class CurrentState(BaseModel): + """ + Read-only state on list/get responses, evaluated from the latest owning projector snapshot at request time, independently of the API replica. Configuration enabled/version/ETag do not change when a cycle rolls over. Audit history remains unchanged. Missing during a rolling upgrade or on mutation responses; clients must treat missing state as unavailable. Balances are asynchronous estimates, not a synchronous usage read. + """ + + balance_cents: Optional[int] = None + + billing_period_end: Optional[datetime] = None + + billing_period_start: Optional[datetime] = None + + enforcement: Optional[CurrentStateEnforcement] = None + """ + Durable desired cap and delivery bookkeeping for this policy, or null if no + owned effect exists. Separate from threshold evaluation: pending/leased/retry + can lag the new billing period. Succeeded with equal generations means delivery + completed, not an EWC readback. + """ + + evaluated_at: datetime + """Evaluation time; not the timestamp of the latest usage event.""" + + status: Literal["disabled", "no_current_period", "unavailable", "below_limit", "limit_reached"] + """Threshold evaluation, not proof of an edge cap. + + No current active period yields no_current_period for enabled policies; failed + aggregate reads yield unavailable for enabled policies. Disabled policies report + disabled. Neither no_current_period nor unavailable implies a zero balance or + below-limit state. Operators may disable current-state reads, in which case + current_state is omitted. + """ + + +class SpendPolicyCreateResponse(BaseModel): + """A spend policy.""" + + id: str + """The unique identifier of the spend policy.""" + + account_id: int + """Internal numeric ID of the account that owns the policy. + + This is not the account tag used in the path. + """ + + action: Literal["notification", "usage_block"] + """The action taken when the threshold is reached. + + `notification` sends an email to `notification_email`. `usage_block` blocks + further usage of the product until the end of the billing period. Raising the + threshold above the current balance, disabling the policy, or deleting it lifts + the block early. + """ + + enabled: bool + """Whether the policy is evaluated.""" + + name: str + """Display name of the policy.""" + + notification_email: str + """Email address that receives notifications. An empty string when none is set.""" + + product_id: Literal["workers", "durable_objects"] + """The product the policy applies to: `workers` or `durable_objects`. + + Each product's balance and policies are separate. Both products support + `notification` and `usage_block` policies on create and update. + """ + + threshold_cents: int + """The spend threshold for the current billing period, in US cents.""" + + version: int + """Optimistic-concurrency version. + + It starts at 1 and goes up by one on every update or delete. This value is also + returned in `ETag`. + """ + + current_state: Optional[CurrentState] = None + """ + Read-only state on list/get responses, evaluated from the latest owning + projector snapshot at request time, independently of the API replica. + Configuration enabled/version/ETag do not change when a cycle rolls over. Audit + history remains unchanged. Missing during a rolling upgrade or on mutation + responses; clients must treat missing state as unavailable. Balances are + asynchronous estimates, not a synchronous usage read. + """ diff --git a/src/cloudflare/types/billing/spend_policy_delete_response.py b/src/cloudflare/types/billing/spend_policy_delete_response.py new file mode 100644 index 00000000000..e238287fb36 --- /dev/null +++ b/src/cloudflare/types/billing/spend_policy_delete_response.py @@ -0,0 +1,10 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from ..._models import BaseModel + +__all__ = ["SpendPolicyDeleteResponse"] + + +class SpendPolicyDeleteResponse(BaseModel): + id: str + """The unique identifier of the spend policy.""" diff --git a/src/cloudflare/types/billing/spend_policy_get_response.py b/src/cloudflare/types/billing/spend_policy_get_response.py new file mode 100644 index 00000000000..e9438f766d7 --- /dev/null +++ b/src/cloudflare/types/billing/spend_policy_get_response.py @@ -0,0 +1,116 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional +from datetime import datetime +from typing_extensions import Literal + +from ..._models import BaseModel + +__all__ = ["SpendPolicyGetResponse", "CurrentState", "CurrentStateEnforcement"] + + +class CurrentStateEnforcement(BaseModel): + """ + Durable desired cap and delivery bookkeeping for this policy, or null if no owned effect exists. Separate from threshold evaluation: pending/leased/retry can lag the new billing period. Succeeded with equal generations means delivery completed, not an EWC readback. + """ + + applied_generation: int + + delivery_status: Literal["pending", "leased", "retry", "succeeded"] + + desired_generation: int + + desired_state: Literal["active", "inactive"] + + expires_at: Optional[datetime] = None + + +class CurrentState(BaseModel): + """ + Read-only state on list/get responses, evaluated from the latest owning projector snapshot at request time, independently of the API replica. Configuration enabled/version/ETag do not change when a cycle rolls over. Audit history remains unchanged. Missing during a rolling upgrade or on mutation responses; clients must treat missing state as unavailable. Balances are asynchronous estimates, not a synchronous usage read. + """ + + balance_cents: Optional[int] = None + + billing_period_end: Optional[datetime] = None + + billing_period_start: Optional[datetime] = None + + enforcement: Optional[CurrentStateEnforcement] = None + """ + Durable desired cap and delivery bookkeeping for this policy, or null if no + owned effect exists. Separate from threshold evaluation: pending/leased/retry + can lag the new billing period. Succeeded with equal generations means delivery + completed, not an EWC readback. + """ + + evaluated_at: datetime + """Evaluation time; not the timestamp of the latest usage event.""" + + status: Literal["disabled", "no_current_period", "unavailable", "below_limit", "limit_reached"] + """Threshold evaluation, not proof of an edge cap. + + No current active period yields no_current_period for enabled policies; failed + aggregate reads yield unavailable for enabled policies. Disabled policies report + disabled. Neither no_current_period nor unavailable implies a zero balance or + below-limit state. Operators may disable current-state reads, in which case + current_state is omitted. + """ + + +class SpendPolicyGetResponse(BaseModel): + """A spend policy.""" + + id: str + """The unique identifier of the spend policy.""" + + account_id: int + """Internal numeric ID of the account that owns the policy. + + This is not the account tag used in the path. + """ + + action: Literal["notification", "usage_block"] + """The action taken when the threshold is reached. + + `notification` sends an email to `notification_email`. `usage_block` blocks + further usage of the product until the end of the billing period. Raising the + threshold above the current balance, disabling the policy, or deleting it lifts + the block early. + """ + + enabled: bool + """Whether the policy is evaluated.""" + + name: str + """Display name of the policy.""" + + notification_email: str + """Email address that receives notifications. An empty string when none is set.""" + + product_id: Literal["workers", "durable_objects"] + """The product the policy applies to: `workers` or `durable_objects`. + + Each product's balance and policies are separate. Both products support + `notification` and `usage_block` policies on create and update. + """ + + threshold_cents: int + """The spend threshold for the current billing period, in US cents.""" + + version: int + """Optimistic-concurrency version. + + It starts at 1 and goes up by one on every update or delete. This value is also + returned in `ETag`. + """ + + current_state: Optional[CurrentState] = None + """ + Read-only state on list/get responses, evaluated from the latest owning + projector snapshot at request time, independently of the API replica. + Configuration enabled/version/ETag do not change when a cycle rolls over. Audit + history remains unchanged. Missing during a rolling upgrade or on mutation + responses; clients must treat missing state as unavailable. Balances are + asynchronous estimates, not a synchronous usage read. + """ diff --git a/src/cloudflare/types/billing/spend_policy_list_response.py b/src/cloudflare/types/billing/spend_policy_list_response.py new file mode 100644 index 00000000000..96a109f77e2 --- /dev/null +++ b/src/cloudflare/types/billing/spend_policy_list_response.py @@ -0,0 +1,116 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional +from datetime import datetime +from typing_extensions import Literal + +from ..._models import BaseModel + +__all__ = ["SpendPolicyListResponse", "CurrentState", "CurrentStateEnforcement"] + + +class CurrentStateEnforcement(BaseModel): + """ + Durable desired cap and delivery bookkeeping for this policy, or null if no owned effect exists. Separate from threshold evaluation: pending/leased/retry can lag the new billing period. Succeeded with equal generations means delivery completed, not an EWC readback. + """ + + applied_generation: int + + delivery_status: Literal["pending", "leased", "retry", "succeeded"] + + desired_generation: int + + desired_state: Literal["active", "inactive"] + + expires_at: Optional[datetime] = None + + +class CurrentState(BaseModel): + """ + Read-only state on list/get responses, evaluated from the latest owning projector snapshot at request time, independently of the API replica. Configuration enabled/version/ETag do not change when a cycle rolls over. Audit history remains unchanged. Missing during a rolling upgrade or on mutation responses; clients must treat missing state as unavailable. Balances are asynchronous estimates, not a synchronous usage read. + """ + + balance_cents: Optional[int] = None + + billing_period_end: Optional[datetime] = None + + billing_period_start: Optional[datetime] = None + + enforcement: Optional[CurrentStateEnforcement] = None + """ + Durable desired cap and delivery bookkeeping for this policy, or null if no + owned effect exists. Separate from threshold evaluation: pending/leased/retry + can lag the new billing period. Succeeded with equal generations means delivery + completed, not an EWC readback. + """ + + evaluated_at: datetime + """Evaluation time; not the timestamp of the latest usage event.""" + + status: Literal["disabled", "no_current_period", "unavailable", "below_limit", "limit_reached"] + """Threshold evaluation, not proof of an edge cap. + + No current active period yields no_current_period for enabled policies; failed + aggregate reads yield unavailable for enabled policies. Disabled policies report + disabled. Neither no_current_period nor unavailable implies a zero balance or + below-limit state. Operators may disable current-state reads, in which case + current_state is omitted. + """ + + +class SpendPolicyListResponse(BaseModel): + """A spend policy.""" + + id: str + """The unique identifier of the spend policy.""" + + account_id: int + """Internal numeric ID of the account that owns the policy. + + This is not the account tag used in the path. + """ + + action: Literal["notification", "usage_block"] + """The action taken when the threshold is reached. + + `notification` sends an email to `notification_email`. `usage_block` blocks + further usage of the product until the end of the billing period. Raising the + threshold above the current balance, disabling the policy, or deleting it lifts + the block early. + """ + + enabled: bool + """Whether the policy is evaluated.""" + + name: str + """Display name of the policy.""" + + notification_email: str + """Email address that receives notifications. An empty string when none is set.""" + + product_id: Literal["workers", "durable_objects"] + """The product the policy applies to: `workers` or `durable_objects`. + + Each product's balance and policies are separate. Both products support + `notification` and `usage_block` policies on create and update. + """ + + threshold_cents: int + """The spend threshold for the current billing period, in US cents.""" + + version: int + """Optimistic-concurrency version. + + It starts at 1 and goes up by one on every update or delete. This value is also + returned in `ETag`. + """ + + current_state: Optional[CurrentState] = None + """ + Read-only state on list/get responses, evaluated from the latest owning + projector snapshot at request time, independently of the API replica. + Configuration enabled/version/ETag do not change when a cycle rolls over. Audit + history remains unchanged. Missing during a rolling upgrade or on mutation + responses; clients must treat missing state as unavailable. Balances are + asynchronous estimates, not a synchronous usage read. + """ diff --git a/src/cloudflare/types/billing/spend_policy_update_params.py b/src/cloudflare/types/billing/spend_policy_update_params.py new file mode 100644 index 00000000000..6d90121366d --- /dev/null +++ b/src/cloudflare/types/billing/spend_policy_update_params.py @@ -0,0 +1,56 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal, Required, Annotated, TypedDict + +from ..._utils import PropertyInfo + +__all__ = ["SpendPolicyUpdateParams"] + + +class SpendPolicyUpdateParams(TypedDict, total=False): + account_id: Required[str] + """Represents a Cloudflare resource identifier tag.""" + + action: Required[Literal["notification", "usage_block"]] + """The action taken when the threshold is reached. + + `notification` sends an email to `notification_email`. `usage_block` blocks + further usage of the product until the end of the billing period. Raising the + threshold above the current balance, disabling the policy, or deleting it lifts + the block early. + """ + + enabled: Required[bool] + """Whether the policy is evaluated.""" + + name: Required[str] + """Display name of the policy. + + After surrounding whitespace is trimmed, it must be 1 to 200 bytes long. The + value is stored as sent, untrimmed. + """ + + product_id: Required[Literal["workers", "durable_objects"]] + """The product the policy applies to: `workers` or `durable_objects`. + + Each product's balance and policies are separate. Both products support + `notification` and `usage_block` policies on create and update. + """ + + threshold_cents: Required[int] + """The spend threshold for the current billing period, in US cents. + + Must be greater than zero. + """ + + if_match: Required[Annotated[str, PropertyInfo(alias="If-Match")]] + + notification_email: str + """Email address that receives notifications. + + Required when `action` is `notification`. When set, it must be a bare address + (`user@example.com`); display-name forms such as `Name ` are + rejected. + """ diff --git a/src/cloudflare/types/billing/spend_policy_update_response.py b/src/cloudflare/types/billing/spend_policy_update_response.py new file mode 100644 index 00000000000..106a301e033 --- /dev/null +++ b/src/cloudflare/types/billing/spend_policy_update_response.py @@ -0,0 +1,116 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional +from datetime import datetime +from typing_extensions import Literal + +from ..._models import BaseModel + +__all__ = ["SpendPolicyUpdateResponse", "CurrentState", "CurrentStateEnforcement"] + + +class CurrentStateEnforcement(BaseModel): + """ + Durable desired cap and delivery bookkeeping for this policy, or null if no owned effect exists. Separate from threshold evaluation: pending/leased/retry can lag the new billing period. Succeeded with equal generations means delivery completed, not an EWC readback. + """ + + applied_generation: int + + delivery_status: Literal["pending", "leased", "retry", "succeeded"] + + desired_generation: int + + desired_state: Literal["active", "inactive"] + + expires_at: Optional[datetime] = None + + +class CurrentState(BaseModel): + """ + Read-only state on list/get responses, evaluated from the latest owning projector snapshot at request time, independently of the API replica. Configuration enabled/version/ETag do not change when a cycle rolls over. Audit history remains unchanged. Missing during a rolling upgrade or on mutation responses; clients must treat missing state as unavailable. Balances are asynchronous estimates, not a synchronous usage read. + """ + + balance_cents: Optional[int] = None + + billing_period_end: Optional[datetime] = None + + billing_period_start: Optional[datetime] = None + + enforcement: Optional[CurrentStateEnforcement] = None + """ + Durable desired cap and delivery bookkeeping for this policy, or null if no + owned effect exists. Separate from threshold evaluation: pending/leased/retry + can lag the new billing period. Succeeded with equal generations means delivery + completed, not an EWC readback. + """ + + evaluated_at: datetime + """Evaluation time; not the timestamp of the latest usage event.""" + + status: Literal["disabled", "no_current_period", "unavailable", "below_limit", "limit_reached"] + """Threshold evaluation, not proof of an edge cap. + + No current active period yields no_current_period for enabled policies; failed + aggregate reads yield unavailable for enabled policies. Disabled policies report + disabled. Neither no_current_period nor unavailable implies a zero balance or + below-limit state. Operators may disable current-state reads, in which case + current_state is omitted. + """ + + +class SpendPolicyUpdateResponse(BaseModel): + """A spend policy.""" + + id: str + """The unique identifier of the spend policy.""" + + account_id: int + """Internal numeric ID of the account that owns the policy. + + This is not the account tag used in the path. + """ + + action: Literal["notification", "usage_block"] + """The action taken when the threshold is reached. + + `notification` sends an email to `notification_email`. `usage_block` blocks + further usage of the product until the end of the billing period. Raising the + threshold above the current balance, disabling the policy, or deleting it lifts + the block early. + """ + + enabled: bool + """Whether the policy is evaluated.""" + + name: str + """Display name of the policy.""" + + notification_email: str + """Email address that receives notifications. An empty string when none is set.""" + + product_id: Literal["workers", "durable_objects"] + """The product the policy applies to: `workers` or `durable_objects`. + + Each product's balance and policies are separate. Both products support + `notification` and `usage_block` policies on create and update. + """ + + threshold_cents: int + """The spend threshold for the current billing period, in US cents.""" + + version: int + """Optimistic-concurrency version. + + It starts at 1 and goes up by one on every update or delete. This value is also + returned in `ETag`. + """ + + current_state: Optional[CurrentState] = None + """ + Read-only state on list/get responses, evaluated from the latest owning + projector snapshot at request time, independently of the API replica. + Configuration enabled/version/ETag do not change when a cycle rolls over. Audit + history remains unchanged. Missing during a rolling upgrade or on mutation + responses; clients must treat missing state as unavailable. Balances are + asynchronous estimates, not a synchronous usage read. + """ diff --git a/src/cloudflare/types/billing/usage_get_account_usage_v2_response.py b/src/cloudflare/types/billing/usage_get_account_usage_v2_response.py index 9bb89d27790..1ecf7f60008 100644 --- a/src/cloudflare/types/billing/usage_get_account_usage_v2_response.py +++ b/src/cloudflare/types/billing/usage_get_account_usage_v2_response.py @@ -34,12 +34,6 @@ class UsageGetAccountUsageV2ResponseItem(BaseModel): charge_period_start: datetime = FieldInfo(alias="ChargePeriodStart") """Inclusive start of the time interval during which the usage was consumed.""" - consumed_quantity: float = FieldInfo(alias="ConsumedQuantity") - """Measured usage amount within the charge period. - - Reflects raw metered consumption before pricing transformations. - """ - consumed_unit: str = FieldInfo(alias="ConsumedUnit") """ Unit of measure for the consumed quantity (e.g., "GB", "Requests", @@ -98,6 +92,12 @@ class UsageGetAccountUsageV2ResponseItem(BaseModel): invoiced in a previous billing period. """ + consumed_quantity: Optional[float] = FieldInfo(alias="ConsumedQuantity", default=None) + """Measured usage amount within the charge period. + + Reflects raw metered consumption before pricing transformations. + """ + contracted_cost: Optional[float] = FieldInfo(alias="ContractedCost", default=None) """ Cost calculated by multiplying ContractedUnitPrice and the corresponding diff --git a/src/cloudflare/types/billing/usage_get_response.py b/src/cloudflare/types/billing/usage_get_response.py index c4ee9c3439b..bf00735bd72 100644 --- a/src/cloudflare/types/billing/usage_get_response.py +++ b/src/cloudflare/types/billing/usage_get_response.py @@ -34,12 +34,6 @@ class UsageGetResponseItem(BaseModel): charge_period_start: datetime = FieldInfo(alias="ChargePeriodStart") """Inclusive start of the time interval during which the usage was consumed.""" - consumed_quantity: float = FieldInfo(alias="ConsumedQuantity") - """Measured usage amount within the charge period. - - Reflects raw metered consumption before pricing transformations. - """ - consumed_unit: str = FieldInfo(alias="ConsumedUnit") """ Unit of measure for the consumed quantity (e.g., "GB", "Requests", @@ -98,6 +92,12 @@ class UsageGetResponseItem(BaseModel): invoiced in a previous billing period. """ + consumed_quantity: Optional[float] = FieldInfo(alias="ConsumedQuantity", default=None) + """Measured usage amount within the charge period. + + Reflects raw metered consumption before pricing transformations. + """ + contracted_cost: Optional[float] = FieldInfo(alias="ContractedCost", default=None) """ Cost calculated by multiplying ContractedUnitPrice and the corresponding diff --git a/src/cloudflare/types/bot_management/bot_fight_mode_configuration.py b/src/cloudflare/types/bot_management/bot_fight_mode_configuration.py index ae9ffef292d..fdee3b30499 100644 --- a/src/cloudflare/types/bot_management/bot_fight_mode_configuration.py +++ b/src/cloudflare/types/bot_management/bot_fight_mode_configuration.py @@ -7,7 +7,26 @@ from ..._models import BaseModel -__all__ = ["BotFightModeConfiguration", "StaleZoneConfiguration"] +__all__ = ["BotFightModeConfiguration", "AIAgents", "StaleZoneConfiguration"] + + +class AIAgents(BaseModel): + """Configure blocking behavior for supported personal AI agents.""" + + anthropic_agent: Optional[Literal["disabled", "block", "only_on_ad_pages"]] = None + """Action to apply to one supported personal AI agent.""" + + google_agent: Optional[Literal["disabled", "block", "only_on_ad_pages"]] = None + """Action to apply to one supported personal AI agent.""" + + instinct: Optional[Literal["disabled", "block", "only_on_ad_pages"]] = None + """Action to apply to one supported personal AI agent.""" + + muse: Optional[Literal["disabled", "block", "only_on_ad_pages"]] = None + """Action to apply to one supported personal AI agent.""" + + openai_agent: Optional[Literal["disabled", "block", "only_on_ad_pages"]] = None + """Action to apply to one supported personal AI agent.""" class StaleZoneConfiguration(BaseModel): @@ -41,6 +60,9 @@ class StaleZoneConfiguration(BaseModel): class BotFightModeConfiguration(BaseModel): + ai_agents: Optional[AIAgents] = None + """Configure blocking behavior for supported personal AI agents.""" + ai_bots_migration_opt_out: Optional[bool] = None """ Temporary migration flag tracking zones opted out of AI bots managed-rule diff --git a/src/cloudflare/types/bot_management/bot_fight_mode_configuration_param.py b/src/cloudflare/types/bot_management/bot_fight_mode_configuration_param.py index 32fc7baf6df..2b7a2335866 100644 --- a/src/cloudflare/types/bot_management/bot_fight_mode_configuration_param.py +++ b/src/cloudflare/types/bot_management/bot_fight_mode_configuration_param.py @@ -6,10 +6,32 @@ from ..._utils import PropertyInfo -__all__ = ["BotFightModeConfigurationParam"] +__all__ = ["BotFightModeConfigurationParam", "AIAgents"] + + +class AIAgents(TypedDict, total=False): + """Configure blocking behavior for supported personal AI agents.""" + + anthropic_agent: Literal["disabled", "block", "only_on_ad_pages"] + """Action to apply to one supported personal AI agent.""" + + google_agent: Literal["disabled", "block", "only_on_ad_pages"] + """Action to apply to one supported personal AI agent.""" + + instinct: Literal["disabled", "block", "only_on_ad_pages"] + """Action to apply to one supported personal AI agent.""" + + muse: Literal["disabled", "block", "only_on_ad_pages"] + """Action to apply to one supported personal AI agent.""" + + openai_agent: Literal["disabled", "block", "only_on_ad_pages"] + """Action to apply to one supported personal AI agent.""" class BotFightModeConfigurationParam(TypedDict, total=False): + ai_agents: AIAgents + """Configure blocking behavior for supported personal AI agents.""" + ai_bots_migration_opt_out: bool """ Temporary migration flag tracking zones opted out of AI bots managed-rule diff --git a/src/cloudflare/types/bot_management/bot_management_update_params.py b/src/cloudflare/types/bot_management/bot_management_update_params.py index 6ca9cde9cea..e66fe9ed7f5 100644 --- a/src/cloudflare/types/bot_management/bot_management_update_params.py +++ b/src/cloudflare/types/bot_management/bot_management_update_params.py @@ -10,9 +10,13 @@ __all__ = [ "BotManagementUpdateParams", "BotFightModeConfiguration", + "BotFightModeConfigurationAIAgents", "SuperBotFightModeDefinitelyConfiguration", + "SuperBotFightModeDefinitelyConfigurationAIAgents", "SuperBotFightModeLikelyConfiguration", + "SuperBotFightModeLikelyConfigurationAIAgents", "SubscriptionConfiguration", + "SubscriptionConfigurationAIAgents", ] @@ -20,6 +24,9 @@ class BotFightModeConfiguration(TypedDict, total=False): zone_id: Required[str] """Identifier.""" + ai_agents: BotFightModeConfigurationAIAgents + """Configure blocking behavior for supported personal AI agents.""" + ai_bots_migration_opt_out: bool """ Temporary migration flag tracking zones opted out of AI bots managed-rule @@ -81,10 +88,32 @@ class BotFightModeConfiguration(TypedDict, total=False): """ +class BotFightModeConfigurationAIAgents(TypedDict, total=False): + """Configure blocking behavior for supported personal AI agents.""" + + anthropic_agent: Literal["disabled", "block", "only_on_ad_pages"] + """Action to apply to one supported personal AI agent.""" + + google_agent: Literal["disabled", "block", "only_on_ad_pages"] + """Action to apply to one supported personal AI agent.""" + + instinct: Literal["disabled", "block", "only_on_ad_pages"] + """Action to apply to one supported personal AI agent.""" + + muse: Literal["disabled", "block", "only_on_ad_pages"] + """Action to apply to one supported personal AI agent.""" + + openai_agent: Literal["disabled", "block", "only_on_ad_pages"] + """Action to apply to one supported personal AI agent.""" + + class SuperBotFightModeDefinitelyConfiguration(TypedDict, total=False): zone_id: Required[str] """Identifier.""" + ai_agents: SuperBotFightModeDefinitelyConfigurationAIAgents + """Configure blocking behavior for supported personal AI agents.""" + ai_bots_migration_opt_out: bool """ Temporary migration flag tracking zones opted out of AI bots managed-rule @@ -159,10 +188,32 @@ class SuperBotFightModeDefinitelyConfiguration(TypedDict, total=False): """Super Bot Fight Mode (SBFM) action to take on verified bots requests.""" +class SuperBotFightModeDefinitelyConfigurationAIAgents(TypedDict, total=False): + """Configure blocking behavior for supported personal AI agents.""" + + anthropic_agent: Literal["disabled", "block", "only_on_ad_pages"] + """Action to apply to one supported personal AI agent.""" + + google_agent: Literal["disabled", "block", "only_on_ad_pages"] + """Action to apply to one supported personal AI agent.""" + + instinct: Literal["disabled", "block", "only_on_ad_pages"] + """Action to apply to one supported personal AI agent.""" + + muse: Literal["disabled", "block", "only_on_ad_pages"] + """Action to apply to one supported personal AI agent.""" + + openai_agent: Literal["disabled", "block", "only_on_ad_pages"] + """Action to apply to one supported personal AI agent.""" + + class SuperBotFightModeLikelyConfiguration(TypedDict, total=False): zone_id: Required[str] """Identifier.""" + ai_agents: SuperBotFightModeLikelyConfigurationAIAgents + """Configure blocking behavior for supported personal AI agents.""" + ai_bots_migration_opt_out: bool """ Temporary migration flag tracking zones opted out of AI bots managed-rule @@ -240,10 +291,32 @@ class SuperBotFightModeLikelyConfiguration(TypedDict, total=False): """Super Bot Fight Mode (SBFM) action to take on verified bots requests.""" +class SuperBotFightModeLikelyConfigurationAIAgents(TypedDict, total=False): + """Configure blocking behavior for supported personal AI agents.""" + + anthropic_agent: Literal["disabled", "block", "only_on_ad_pages"] + """Action to apply to one supported personal AI agent.""" + + google_agent: Literal["disabled", "block", "only_on_ad_pages"] + """Action to apply to one supported personal AI agent.""" + + instinct: Literal["disabled", "block", "only_on_ad_pages"] + """Action to apply to one supported personal AI agent.""" + + muse: Literal["disabled", "block", "only_on_ad_pages"] + """Action to apply to one supported personal AI agent.""" + + openai_agent: Literal["disabled", "block", "only_on_ad_pages"] + """Action to apply to one supported personal AI agent.""" + + class SubscriptionConfiguration(TypedDict, total=False): zone_id: Required[str] """Identifier.""" + ai_agents: SubscriptionConfigurationAIAgents + """Configure blocking behavior for supported personal AI agents.""" + ai_bots_migration_opt_out: bool """ Temporary migration flag tracking zones opted out of AI bots managed-rule @@ -321,6 +394,25 @@ class SubscriptionConfiguration(TypedDict, total=False): """ +class SubscriptionConfigurationAIAgents(TypedDict, total=False): + """Configure blocking behavior for supported personal AI agents.""" + + anthropic_agent: Literal["disabled", "block", "only_on_ad_pages"] + """Action to apply to one supported personal AI agent.""" + + google_agent: Literal["disabled", "block", "only_on_ad_pages"] + """Action to apply to one supported personal AI agent.""" + + instinct: Literal["disabled", "block", "only_on_ad_pages"] + """Action to apply to one supported personal AI agent.""" + + muse: Literal["disabled", "block", "only_on_ad_pages"] + """Action to apply to one supported personal AI agent.""" + + openai_agent: Literal["disabled", "block", "only_on_ad_pages"] + """Action to apply to one supported personal AI agent.""" + + BotManagementUpdateParams: TypeAlias = Union[ BotFightModeConfiguration, SuperBotFightModeDefinitelyConfiguration, diff --git a/src/cloudflare/types/bot_management/subscription_configuration.py b/src/cloudflare/types/bot_management/subscription_configuration.py index f7a45e0bc18..05debd7e35d 100644 --- a/src/cloudflare/types/bot_management/subscription_configuration.py +++ b/src/cloudflare/types/bot_management/subscription_configuration.py @@ -7,7 +7,26 @@ from ..._models import BaseModel -__all__ = ["SubscriptionConfiguration", "StaleZoneConfiguration"] +__all__ = ["SubscriptionConfiguration", "AIAgents", "StaleZoneConfiguration"] + + +class AIAgents(BaseModel): + """Configure blocking behavior for supported personal AI agents.""" + + anthropic_agent: Optional[Literal["disabled", "block", "only_on_ad_pages"]] = None + """Action to apply to one supported personal AI agent.""" + + google_agent: Optional[Literal["disabled", "block", "only_on_ad_pages"]] = None + """Action to apply to one supported personal AI agent.""" + + instinct: Optional[Literal["disabled", "block", "only_on_ad_pages"]] = None + """Action to apply to one supported personal AI agent.""" + + muse: Optional[Literal["disabled", "block", "only_on_ad_pages"]] = None + """Action to apply to one supported personal AI agent.""" + + openai_agent: Optional[Literal["disabled", "block", "only_on_ad_pages"]] = None + """Action to apply to one supported personal AI agent.""" class StaleZoneConfiguration(BaseModel): @@ -41,6 +60,9 @@ class StaleZoneConfiguration(BaseModel): class SubscriptionConfiguration(BaseModel): + ai_agents: Optional[AIAgents] = None + """Configure blocking behavior for supported personal AI agents.""" + ai_bots_migration_opt_out: Optional[bool] = None """ Temporary migration flag tracking zones opted out of AI bots managed-rule diff --git a/src/cloudflare/types/bot_management/subscription_configuration_param.py b/src/cloudflare/types/bot_management/subscription_configuration_param.py index 37fb3da660f..7423dde7114 100644 --- a/src/cloudflare/types/bot_management/subscription_configuration_param.py +++ b/src/cloudflare/types/bot_management/subscription_configuration_param.py @@ -6,10 +6,32 @@ from ..._utils import PropertyInfo -__all__ = ["SubscriptionConfigurationParam"] +__all__ = ["SubscriptionConfigurationParam", "AIAgents"] + + +class AIAgents(TypedDict, total=False): + """Configure blocking behavior for supported personal AI agents.""" + + anthropic_agent: Literal["disabled", "block", "only_on_ad_pages"] + """Action to apply to one supported personal AI agent.""" + + google_agent: Literal["disabled", "block", "only_on_ad_pages"] + """Action to apply to one supported personal AI agent.""" + + instinct: Literal["disabled", "block", "only_on_ad_pages"] + """Action to apply to one supported personal AI agent.""" + + muse: Literal["disabled", "block", "only_on_ad_pages"] + """Action to apply to one supported personal AI agent.""" + + openai_agent: Literal["disabled", "block", "only_on_ad_pages"] + """Action to apply to one supported personal AI agent.""" class SubscriptionConfigurationParam(TypedDict, total=False): + ai_agents: AIAgents + """Configure blocking behavior for supported personal AI agents.""" + ai_bots_migration_opt_out: bool """ Temporary migration flag tracking zones opted out of AI bots managed-rule diff --git a/src/cloudflare/types/bot_management/super_bot_fight_mode_definitely_configuration.py b/src/cloudflare/types/bot_management/super_bot_fight_mode_definitely_configuration.py index 8bf6d8fc0f6..d1dd3e2e708 100644 --- a/src/cloudflare/types/bot_management/super_bot_fight_mode_definitely_configuration.py +++ b/src/cloudflare/types/bot_management/super_bot_fight_mode_definitely_configuration.py @@ -7,7 +7,26 @@ from ..._models import BaseModel -__all__ = ["SuperBotFightModeDefinitelyConfiguration", "StaleZoneConfiguration"] +__all__ = ["SuperBotFightModeDefinitelyConfiguration", "AIAgents", "StaleZoneConfiguration"] + + +class AIAgents(BaseModel): + """Configure blocking behavior for supported personal AI agents.""" + + anthropic_agent: Optional[Literal["disabled", "block", "only_on_ad_pages"]] = None + """Action to apply to one supported personal AI agent.""" + + google_agent: Optional[Literal["disabled", "block", "only_on_ad_pages"]] = None + """Action to apply to one supported personal AI agent.""" + + instinct: Optional[Literal["disabled", "block", "only_on_ad_pages"]] = None + """Action to apply to one supported personal AI agent.""" + + muse: Optional[Literal["disabled", "block", "only_on_ad_pages"]] = None + """Action to apply to one supported personal AI agent.""" + + openai_agent: Optional[Literal["disabled", "block", "only_on_ad_pages"]] = None + """Action to apply to one supported personal AI agent.""" class StaleZoneConfiguration(BaseModel): @@ -26,6 +45,9 @@ class StaleZoneConfiguration(BaseModel): class SuperBotFightModeDefinitelyConfiguration(BaseModel): + ai_agents: Optional[AIAgents] = None + """Configure blocking behavior for supported personal AI agents.""" + ai_bots_migration_opt_out: Optional[bool] = None """ Temporary migration flag tracking zones opted out of AI bots managed-rule diff --git a/src/cloudflare/types/bot_management/super_bot_fight_mode_definitely_configuration_param.py b/src/cloudflare/types/bot_management/super_bot_fight_mode_definitely_configuration_param.py index 5c2931c11b3..8e985acf0e0 100644 --- a/src/cloudflare/types/bot_management/super_bot_fight_mode_definitely_configuration_param.py +++ b/src/cloudflare/types/bot_management/super_bot_fight_mode_definitely_configuration_param.py @@ -6,10 +6,32 @@ from ..._utils import PropertyInfo -__all__ = ["SuperBotFightModeDefinitelyConfigurationParam"] +__all__ = ["SuperBotFightModeDefinitelyConfigurationParam", "AIAgents"] + + +class AIAgents(TypedDict, total=False): + """Configure blocking behavior for supported personal AI agents.""" + + anthropic_agent: Literal["disabled", "block", "only_on_ad_pages"] + """Action to apply to one supported personal AI agent.""" + + google_agent: Literal["disabled", "block", "only_on_ad_pages"] + """Action to apply to one supported personal AI agent.""" + + instinct: Literal["disabled", "block", "only_on_ad_pages"] + """Action to apply to one supported personal AI agent.""" + + muse: Literal["disabled", "block", "only_on_ad_pages"] + """Action to apply to one supported personal AI agent.""" + + openai_agent: Literal["disabled", "block", "only_on_ad_pages"] + """Action to apply to one supported personal AI agent.""" class SuperBotFightModeDefinitelyConfigurationParam(TypedDict, total=False): + ai_agents: AIAgents + """Configure blocking behavior for supported personal AI agents.""" + ai_bots_migration_opt_out: bool """ Temporary migration flag tracking zones opted out of AI bots managed-rule diff --git a/src/cloudflare/types/bot_management/super_bot_fight_mode_likely_configuration.py b/src/cloudflare/types/bot_management/super_bot_fight_mode_likely_configuration.py index f8b715d15e2..19c2a15d620 100644 --- a/src/cloudflare/types/bot_management/super_bot_fight_mode_likely_configuration.py +++ b/src/cloudflare/types/bot_management/super_bot_fight_mode_likely_configuration.py @@ -7,7 +7,26 @@ from ..._models import BaseModel -__all__ = ["SuperBotFightModeLikelyConfiguration", "StaleZoneConfiguration"] +__all__ = ["SuperBotFightModeLikelyConfiguration", "AIAgents", "StaleZoneConfiguration"] + + +class AIAgents(BaseModel): + """Configure blocking behavior for supported personal AI agents.""" + + anthropic_agent: Optional[Literal["disabled", "block", "only_on_ad_pages"]] = None + """Action to apply to one supported personal AI agent.""" + + google_agent: Optional[Literal["disabled", "block", "only_on_ad_pages"]] = None + """Action to apply to one supported personal AI agent.""" + + instinct: Optional[Literal["disabled", "block", "only_on_ad_pages"]] = None + """Action to apply to one supported personal AI agent.""" + + muse: Optional[Literal["disabled", "block", "only_on_ad_pages"]] = None + """Action to apply to one supported personal AI agent.""" + + openai_agent: Optional[Literal["disabled", "block", "only_on_ad_pages"]] = None + """Action to apply to one supported personal AI agent.""" class StaleZoneConfiguration(BaseModel): @@ -20,6 +39,9 @@ class StaleZoneConfiguration(BaseModel): class SuperBotFightModeLikelyConfiguration(BaseModel): + ai_agents: Optional[AIAgents] = None + """Configure blocking behavior for supported personal AI agents.""" + ai_bots_migration_opt_out: Optional[bool] = None """ Temporary migration flag tracking zones opted out of AI bots managed-rule diff --git a/src/cloudflare/types/bot_management/super_bot_fight_mode_likely_configuration_param.py b/src/cloudflare/types/bot_management/super_bot_fight_mode_likely_configuration_param.py index d8d682de2f5..f51cc2402bb 100644 --- a/src/cloudflare/types/bot_management/super_bot_fight_mode_likely_configuration_param.py +++ b/src/cloudflare/types/bot_management/super_bot_fight_mode_likely_configuration_param.py @@ -6,10 +6,32 @@ from ..._utils import PropertyInfo -__all__ = ["SuperBotFightModeLikelyConfigurationParam"] +__all__ = ["SuperBotFightModeLikelyConfigurationParam", "AIAgents"] + + +class AIAgents(TypedDict, total=False): + """Configure blocking behavior for supported personal AI agents.""" + + anthropic_agent: Literal["disabled", "block", "only_on_ad_pages"] + """Action to apply to one supported personal AI agent.""" + + google_agent: Literal["disabled", "block", "only_on_ad_pages"] + """Action to apply to one supported personal AI agent.""" + + instinct: Literal["disabled", "block", "only_on_ad_pages"] + """Action to apply to one supported personal AI agent.""" + + muse: Literal["disabled", "block", "only_on_ad_pages"] + """Action to apply to one supported personal AI agent.""" + + openai_agent: Literal["disabled", "block", "only_on_ad_pages"] + """Action to apply to one supported personal AI agent.""" class SuperBotFightModeLikelyConfigurationParam(TypedDict, total=False): + ai_agents: AIAgents + """Configure blocking behavior for supported personal AI agents.""" + ai_bots_migration_opt_out: bool """ Temporary migration flag tracking zones opted out of AI bots managed-rule diff --git a/src/cloudflare/types/brand_protection/query_create_params.py b/src/cloudflare/types/brand_protection/query_create_params.py index 543c7bbbc71..ef688e98e05 100644 --- a/src/cloudflare/types/brand_protection/query_create_params.py +++ b/src/cloudflare/types/brand_protection/query_create_params.py @@ -2,13 +2,13 @@ from __future__ import annotations -from typing import Union +from typing import Union, Iterable from datetime import datetime from typing_extensions import Required, Annotated, TypedDict from ..._utils import PropertyInfo -__all__ = ["QueryCreateParams"] +__all__ = ["QueryCreateParams", "StringMatch"] class QueryCreateParams(TypedDict, total=False): @@ -26,6 +26,12 @@ class QueryCreateParams(TypedDict, total=False): body_scan: Annotated[bool, PropertyInfo(alias="scan")] - string_matches: object + string_matches: Iterable[StringMatch] body_tag: Annotated[str, PropertyInfo(alias="tag")] + + +class StringMatch(TypedDict, total=False): + pattern: Required[str] + + max_edit_distance: float diff --git a/src/cloudflare/types/browser_rendering/accessibility_tree_create_params.py b/src/cloudflare/types/browser_rendering/accessibility_tree_create_params.py index 1f293e20c4f..fcafa9e09c9 100644 --- a/src/cloudflare/types/browser_rendering/accessibility_tree_create_params.py +++ b/src/cloudflare/types/browser_rendering/accessibility_tree_create_params.py @@ -35,6 +35,9 @@ class Variant0(TypedDict, total=False): url: Required[str] + browser: Literal["kitesurf"] + """Rendering backend. Set to `kitesurf` to use Kitesurf (beta).""" + cache_ttl: Annotated[float, PropertyInfo(alias="cacheTTL")] """Cache TTL default is 5s. Set to 0 to disable.""" @@ -275,6 +278,9 @@ class Variant1(TypedDict, total=False): html: Required[str] + browser: Literal["kitesurf"] + """Rendering backend. Set to `kitesurf` to use Kitesurf (beta).""" + cache_ttl: Annotated[float, PropertyInfo(alias="cacheTTL")] """Cache TTL default is 5s. Set to 0 to disable.""" diff --git a/src/cloudflare/types/browser_rendering/content_create_params.py b/src/cloudflare/types/browser_rendering/content_create_params.py index c0fd589efee..67b41386ddd 100644 --- a/src/cloudflare/types/browser_rendering/content_create_params.py +++ b/src/cloudflare/types/browser_rendering/content_create_params.py @@ -35,6 +35,9 @@ class Variant0(TypedDict, total=False): url: Required[str] + browser: Literal["kitesurf"] + """Rendering backend. Set to `kitesurf` to use Kitesurf (beta).""" + cache_ttl: Annotated[float, PropertyInfo(alias="cacheTTL")] """Cache TTL default is 5s. Set to 0 to disable.""" @@ -271,6 +274,9 @@ class Variant1(TypedDict, total=False): html: Required[str] + browser: Literal["kitesurf"] + """Rendering backend. Set to `kitesurf` to use Kitesurf (beta).""" + cache_ttl: Annotated[float, PropertyInfo(alias="cacheTTL")] """Cache TTL default is 5s. Set to 0 to disable.""" diff --git a/src/cloudflare/types/browser_rendering/crawl_get_response.py b/src/cloudflare/types/browser_rendering/crawl_get_response.py index b4ad524a420..f3127c20a4f 100644 --- a/src/cloudflare/types/browser_rendering/crawl_get_response.py +++ b/src/cloudflare/types/browser_rendering/crawl_get_response.py @@ -7,7 +7,7 @@ from ..._models import BaseModel -__all__ = ["CrawlGetResponse", "Record", "RecordMetadata"] +__all__ = ["CrawlGetResponse", "Record", "RecordMetadata", "Robot"] class RecordMetadata(BaseModel): @@ -19,6 +19,24 @@ class RecordMetadata(BaseModel): url: str """Final URL of the crawled page.""" + last_modified: Optional[str] = FieldInfo(alias="lastModified", default=None) + """Value of the Last-Modified response header, when provided by the origin.""" + + og_description: Optional[str] = FieldInfo(alias="og:description", default=None) + """Open Graph description of the crawled page.""" + + og_image: Optional[str] = FieldInfo(alias="og:image", default=None) + """Open Graph image of the crawled page.""" + + og_site_name: Optional[str] = FieldInfo(alias="og:site_name", default=None) + """Open Graph site name of the crawled page.""" + + og_title: Optional[str] = FieldInfo(alias="og:title", default=None) + """Open Graph title of the crawled page.""" + + og_type: Optional[str] = FieldInfo(alias="og:type", default=None) + """Open Graph type of the crawled page.""" + title: Optional[str] = None """Title of the crawled page.""" @@ -42,6 +60,38 @@ class Record(BaseModel): metadata: Optional[RecordMetadata] = None """Absent for urls that never reached a fetch.""" + outcome: Optional[ + Literal[ + "success", + "robots_disallowed", + "crawl_purpose_disallowed", + "content_use_disallowed", + "connection_error", + "timeout", + "browser_unavailable", + "format_generation_error", + "unsupported_content_type", + "unclassified_error", + "page_error", + "too_large", + ] + ] = None + """Result of processing the URL. Absent for older records.""" + + +class Robot(BaseModel): + origin: str + """Origin whose robots.txt was checked.""" + + state: Literal["available", "absent", "fetch_failed"] + """Whether usable robots.txt rules were available.""" + + status: Optional[float] = None + """HTTP status that established the current robots.txt state. + + Absent when no HTTP response was received. + """ + class CrawlGetResponse(BaseModel): id: str @@ -56,6 +106,9 @@ class CrawlGetResponse(BaseModel): records: List[Record] """List of crawl job records.""" + robots: List[Robot] + """Robots.txt state for the first 50 origins encountered by the crawl.""" + skipped: float """Total number of URLs that were skipped due to include/exclude/subdomain filters. diff --git a/src/cloudflare/types/browser_rendering/devtools/__init__.py b/src/cloudflare/types/browser_rendering/devtools/__init__.py index 4b15ed1a9cd..09bf1d17f54 100644 --- a/src/cloudflare/types/browser_rendering/devtools/__init__.py +++ b/src/cloudflare/types/browser_rendering/devtools/__init__.py @@ -5,9 +5,7 @@ from .session_list_params import SessionListParams as SessionListParams from .session_get_response import SessionGetResponse as SessionGetResponse from .browser_create_params import BrowserCreateParams as BrowserCreateParams -from .browser_launch_params import BrowserLaunchParams as BrowserLaunchParams from .session_list_response import SessionListResponse as SessionListResponse -from .browser_connect_params import BrowserConnectParams as BrowserConnectParams from .browser_create_response import BrowserCreateResponse as BrowserCreateResponse from .browser_delete_response import BrowserDeleteResponse as BrowserDeleteResponse from .browser_version_response import BrowserVersionResponse as BrowserVersionResponse diff --git a/src/cloudflare/types/browser_rendering/devtools/browser_connect_params.py b/src/cloudflare/types/browser_rendering/devtools/browser_connect_params.py deleted file mode 100644 index e7d1d2fd4ca..00000000000 --- a/src/cloudflare/types/browser_rendering/devtools/browser_connect_params.py +++ /dev/null @@ -1,25 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing_extensions import Required, Annotated, TypedDict - -from ...._utils import PropertyInfo - -__all__ = ["BrowserConnectParams"] - - -class BrowserConnectParams(TypedDict, total=False): - account_id: Required[str] - """Account ID.""" - - keep_alive: float - """Keep-alive time in ms (only valid when acquiring new session).""" - - lab: bool - """Use experimental browser.""" - - recording: bool - - cf_brapi_guardrails: Annotated[str, PropertyInfo(alias="cf-brapi-guardrails")] - """Optional base64url-encoded JSON connection guardrails (mode)""" diff --git a/src/cloudflare/types/browser_rendering/devtools/browser_launch_params.py b/src/cloudflare/types/browser_rendering/devtools/browser_launch_params.py deleted file mode 100644 index d7396e1959e..00000000000 --- a/src/cloudflare/types/browser_rendering/devtools/browser_launch_params.py +++ /dev/null @@ -1,28 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing_extensions import Required, Annotated, TypedDict - -from ...._utils import PropertyInfo - -__all__ = ["BrowserLaunchParams"] - - -class BrowserLaunchParams(TypedDict, total=False): - account_id: Required[str] - """Account ID.""" - - keep_alive: float - """Keep-alive time in ms (only valid when acquiring new session).""" - - lab: bool - """Use experimental browser.""" - - recording: bool - - cf_brapi_guardrails: Annotated[str, PropertyInfo(alias="cf-brapi-guardrails")] - """ - Optional base64url-encoded JSON session guardrails (allowedDomains and - allowedDomainSets) - """ diff --git a/src/cloudflare/types/browser_rendering/json_create_params.py b/src/cloudflare/types/browser_rendering/json_create_params.py index 51b9d3f6e35..da8c3d66073 100644 --- a/src/cloudflare/types/browser_rendering/json_create_params.py +++ b/src/cloudflare/types/browser_rendering/json_create_params.py @@ -39,6 +39,9 @@ class Variant0(TypedDict, total=False): url: Required[str] + browser: Literal["kitesurf"] + """Rendering backend. Set to `kitesurf` to use Kitesurf (beta).""" + cache_ttl: Annotated[float, PropertyInfo(alias="cacheTTL")] """Cache TTL default is 5s. Set to 0 to disable.""" @@ -311,6 +314,9 @@ class Variant1(TypedDict, total=False): html: Required[str] + browser: Literal["kitesurf"] + """Rendering backend. Set to `kitesurf` to use Kitesurf (beta).""" + cache_ttl: Annotated[float, PropertyInfo(alias="cacheTTL")] """Cache TTL default is 5s. Set to 0 to disable.""" diff --git a/src/cloudflare/types/browser_rendering/link_create_params.py b/src/cloudflare/types/browser_rendering/link_create_params.py index 0b3395b1a83..badeaa81cb1 100644 --- a/src/cloudflare/types/browser_rendering/link_create_params.py +++ b/src/cloudflare/types/browser_rendering/link_create_params.py @@ -35,6 +35,9 @@ class Variant0(TypedDict, total=False): url: Required[str] + browser: Literal["kitesurf"] + """Rendering backend. Set to `kitesurf` to use Kitesurf (beta).""" + cache_ttl: Annotated[float, PropertyInfo(alias="cacheTTL")] """Cache TTL default is 5s. Set to 0 to disable.""" @@ -275,6 +278,9 @@ class Variant1(TypedDict, total=False): html: Required[str] + browser: Literal["kitesurf"] + """Rendering backend. Set to `kitesurf` to use Kitesurf (beta).""" + cache_ttl: Annotated[float, PropertyInfo(alias="cacheTTL")] """Cache TTL default is 5s. Set to 0 to disable.""" diff --git a/src/cloudflare/types/browser_rendering/markdown_create_params.py b/src/cloudflare/types/browser_rendering/markdown_create_params.py index e33919dab13..e0148b1e45b 100644 --- a/src/cloudflare/types/browser_rendering/markdown_create_params.py +++ b/src/cloudflare/types/browser_rendering/markdown_create_params.py @@ -35,6 +35,9 @@ class Variant0(TypedDict, total=False): url: Required[str] + browser: Literal["kitesurf"] + """Rendering backend. Set to `kitesurf` to use Kitesurf (beta).""" + cache_ttl: Annotated[float, PropertyInfo(alias="cacheTTL")] """Cache TTL default is 5s. Set to 0 to disable.""" @@ -271,6 +274,9 @@ class Variant1(TypedDict, total=False): html: Required[str] + browser: Literal["kitesurf"] + """Rendering backend. Set to `kitesurf` to use Kitesurf (beta).""" + cache_ttl: Annotated[float, PropertyInfo(alias="cacheTTL")] """Cache TTL default is 5s. Set to 0 to disable.""" diff --git a/src/cloudflare/types/browser_rendering/pdf_create_params.py b/src/cloudflare/types/browser_rendering/pdf_create_params.py index 93f17e4fdbe..1a9b132c860 100644 --- a/src/cloudflare/types/browser_rendering/pdf_create_params.py +++ b/src/cloudflare/types/browser_rendering/pdf_create_params.py @@ -39,6 +39,9 @@ class Variant0(TypedDict, total=False): url: Required[str] + browser: Literal["kitesurf"] + """Rendering backend. Set to `kitesurf` to use Kitesurf (beta).""" + cache_ttl: Annotated[float, PropertyInfo(alias="cacheTTL")] """Cache TTL default is 5s. Set to 0 to disable.""" @@ -342,6 +345,9 @@ class Variant1(TypedDict, total=False): html: Required[str] + browser: Literal["kitesurf"] + """Rendering backend. Set to `kitesurf` to use Kitesurf (beta).""" + cache_ttl: Annotated[float, PropertyInfo(alias="cacheTTL")] """Cache TTL default is 5s. Set to 0 to disable.""" diff --git a/src/cloudflare/types/browser_rendering/scrape_create_params.py b/src/cloudflare/types/browser_rendering/scrape_create_params.py index 3fe8e02fd6e..edd3cb62cce 100644 --- a/src/cloudflare/types/browser_rendering/scrape_create_params.py +++ b/src/cloudflare/types/browser_rendering/scrape_create_params.py @@ -37,6 +37,9 @@ class Variant0(TypedDict, total=False): url: Required[str] + browser: Literal["kitesurf"] + """Rendering backend. Set to `kitesurf` to use Kitesurf (beta).""" + cache_ttl: Annotated[float, PropertyInfo(alias="cacheTTL")] """Cache TTL default is 5s. Set to 0 to disable.""" @@ -279,6 +282,9 @@ class Variant1(TypedDict, total=False): html: Required[str] + browser: Literal["kitesurf"] + """Rendering backend. Set to `kitesurf` to use Kitesurf (beta).""" + cache_ttl: Annotated[float, PropertyInfo(alias="cacheTTL")] """Cache TTL default is 5s. Set to 0 to disable.""" diff --git a/src/cloudflare/types/browser_rendering/screenshot_create_params.py b/src/cloudflare/types/browser_rendering/screenshot_create_params.py index e9cab5ec241..2e3a142d3d6 100644 --- a/src/cloudflare/types/browser_rendering/screenshot_create_params.py +++ b/src/cloudflare/types/browser_rendering/screenshot_create_params.py @@ -39,6 +39,9 @@ class Variant0(TypedDict, total=False): url: Required[str] + browser: Literal["kitesurf"] + """Rendering backend. Set to `kitesurf` to use Kitesurf (beta).""" + cache_ttl: Annotated[float, PropertyInfo(alias="cacheTTL")] """Cache TTL default is 5s. Set to 0 to disable.""" @@ -316,6 +319,9 @@ class Variant1(TypedDict, total=False): html: Required[str] + browser: Literal["kitesurf"] + """Rendering backend. Set to `kitesurf` to use Kitesurf (beta).""" + cache_ttl: Annotated[float, PropertyInfo(alias="cacheTTL")] """Cache TTL default is 5s. Set to 0 to disable.""" diff --git a/src/cloudflare/types/browser_rendering/snapshot_create_params.py b/src/cloudflare/types/browser_rendering/snapshot_create_params.py index 9750da40c04..d03d40aa8c3 100644 --- a/src/cloudflare/types/browser_rendering/snapshot_create_params.py +++ b/src/cloudflare/types/browser_rendering/snapshot_create_params.py @@ -39,6 +39,9 @@ class Variant0(TypedDict, total=False): url: Required[str] + browser: Literal["kitesurf"] + """Rendering backend. Set to `kitesurf` to use Kitesurf (beta).""" + cache_ttl: Annotated[float, PropertyInfo(alias="cacheTTL")] """Cache TTL default is 5s. Set to 0 to disable.""" @@ -309,6 +312,9 @@ class Variant1(TypedDict, total=False): html: Required[str] + browser: Literal["kitesurf"] + """Rendering backend. Set to `kitesurf` to use Kitesurf (beta).""" + cache_ttl: Annotated[float, PropertyInfo(alias="cacheTTL")] """Cache TTL default is 5s. Set to 0 to disable.""" diff --git a/src/cloudflare/types/cloudforce_one/threat_event_list_params.py b/src/cloudflare/types/cloudforce_one/threat_event_list_params.py index 05cb8b27f3f..b14e5e37537 100644 --- a/src/cloudflare/types/cloudforce_one/threat_event_list_params.py +++ b/src/cloudflare/types/cloudforce_one/threat_event_list_params.py @@ -17,6 +17,13 @@ "SearchUnionMember3", "SearchUnionMember4", "SearchUnionMember5", + "SearchBranch", + "SearchBranchUnionMember0", + "SearchBranchUnionMember1", + "SearchBranchUnionMember2", + "SearchBranchUnionMember3", + "SearchBranchUnionMember4", + "SearchBranchUnionMember5", ] @@ -42,10 +49,10 @@ class ThreatEventListParams(TypedDict, total=False): dataset_id: Annotated[SequenceNotStr[str], PropertyInfo(alias="datasetId")] """ - Dataset UUIDs to query, or one standalone scope value: 'all'/'\\**' for the legacy - all-datasets behavior, 'analytics' for isAnalytics=true datasets, or - 'operational' for isAnalytics=false datasets. If not provided, uses the default - dataset. + Dataset UUIDs to query, or one standalone scope value: 'all'/'\\**' or + 'operational' for readable intelligence datasets (isAnalytics=false), or + 'analytics' for readable analytics datasets (isAnalytics=true). Scope values + query at most 50 datasets. If not provided, uses the default dataset. """ force_refresh: Annotated[bool, PropertyInfo(alias="forceRefresh")] @@ -68,6 +75,17 @@ class ThreatEventListParams(TypedDict, total=False): search: Iterable[Search] + search_branches: Annotated[Iterable[Iterable[SearchBranch]], PropertyInfo(alias="searchBranches")] + """JSON-encoded. + + OR branches of structured search filters. Filters within a branch are AND'd, + branches are OR'd, and the result is AND'd with `search`: + `AND(search) AND OR(AND(branch 1), ...)`. Max 8 branches of 1-10 conditions + each. Not supported for analytics datasets, and `indicator` filters are not yet + supported inside branches. Cursor pages carry the original branches, so do not + resend them with `cursor`. + """ + class SearchUnionMember0(TypedDict, total=False): field: Required[ @@ -163,3 +181,99 @@ class SearchUnionMember5(TypedDict, total=False): SearchUnionMember4, SearchUnionMember5, ] + + +class SearchBranchUnionMember0(TypedDict, total=False): + field: Required[ + Literal[ + "attacker", + "attackerCountry", + "category", + "createdAt", + "date", + "event", + "indicator", + "indicatorType", + "mitreAttack", + "mitreCapec", + "tags", + "targetCountry", + "targetIndustry", + "tlp", + "uuid", + ] + ] + + op: Required[ + Literal["equals", "not", "gt", "gte", "lt", "lte", "like", "contains", "startsWith", "endsWith", "find"] + ] + + value: Required[str] + + +class SearchBranchUnionMember1(TypedDict, total=False): + field: Required[ + Literal[ + "attacker", + "attackerCountry", + "category", + "createdAt", + "date", + "event", + "indicator", + "indicatorType", + "mitreAttack", + "mitreCapec", + "tags", + "targetCountry", + "targetIndustry", + "tlp", + "uuid", + ] + ] + + op: Required[Literal["in"]] + + value: Required[SequenceNotStr[str]] + + +class SearchBranchUnionMember2(TypedDict, total=False): + field: Required[Literal["killChain"]] + + op: Required[Literal["equals", "not", "gt", "gte", "lt", "lte"]] + + value: Required[Union[float, str]] + + +class SearchBranchUnionMember3(TypedDict, total=False): + field: Required[Literal["killChain"]] + + op: Required[Literal["in"]] + + value: Required[SequenceNotStr[Union[float, str]]] + + +class SearchBranchUnionMember4(TypedDict, total=False): + field: Required[Literal["hasChildren"]] + + op: Required[Literal["equals", "not", "gt", "gte", "lt", "lte"]] + + value: Required[Union[bool, object]] + + +class SearchBranchUnionMember5(TypedDict, total=False): + field: Required[Literal["hasChildren"]] + + op: Required[Literal["in"]] + + value: Required[Iterable[Union[bool, object]]] + + +SearchBranch: TypeAlias = Union[ + SearchBranchUnionMember0, + SearchBranchUnionMember1, + SearchBranchUnionMember2, + SearchBranchUnionMember3, + SearchBranchUnionMember4, + SearchBranchUnionMember5, +] diff --git a/src/cloudflare/types/cloudforce_one/threat_events/aggregate_list_params.py b/src/cloudflare/types/cloudforce_one/threat_events/aggregate_list_params.py index 0ac46817620..e2a4cf81a03 100644 --- a/src/cloudflare/types/cloudforce_one/threat_events/aggregate_list_params.py +++ b/src/cloudflare/types/cloudforce_one/threat_events/aggregate_list_params.py @@ -17,15 +17,18 @@ class AggregateListParams(TypedDict, total=False): aggregate_by: Required[Annotated[str, PropertyInfo(alias="aggregateBy")]] """ Column(s) to aggregate by - single column or comma-separated list (e.g., - 'attacker', 'targetIndustry', 'attacker,targetIndustry') + 'attacker', 'targetIndustry', 'attacker,targetIndustry'). With `tags`, an event + counts once for each of its tags, in the bucket counts and in `total`, and + events without tags count as `Unknown`; `tags` is not supported for analytics + datasets. """ dataset_id: Annotated[SequenceNotStr[str], PropertyInfo(alias="datasetId")] """ - Dataset UUIDs to filter by, or one standalone scope value: 'all'/'\\**' for all - accessible non-analytics event datasets (analytics datasets are silently - excluded), 'analytics' for isAnalytics=true datasets, or 'operational' for - isAnalytics=false datasets. If not provided, uses the default dataset. + Dataset UUIDs to filter by, or one standalone scope value: 'all'/'\\**' or + 'operational' for readable intelligence datasets (isAnalytics=false), or + 'analytics' for readable analytics datasets (isAnalytics=true). Scope values + query at most 50 datasets. If not provided, uses the default dataset. """ end_date: Annotated[str, PropertyInfo(alias="endDate")] diff --git a/src/cloudflare/types/cloudforce_one/threat_events/graph_list_params.py b/src/cloudflare/types/cloudforce_one/threat_events/graph_list_params.py index fb4ca6b31bb..b55a76597c5 100644 --- a/src/cloudflare/types/cloudforce_one/threat_events/graph_list_params.py +++ b/src/cloudflare/types/cloudforce_one/threat_events/graph_list_params.py @@ -23,8 +23,11 @@ class GraphListParams(TypedDict, total=False): dataset_ids: Annotated[SequenceNotStr[str], PropertyInfo(alias="datasetIds")] """ Comma-separated dataset UUIDs to restrict neighbor scope, or one standalone - scope value: 'all'/'\\**', 'analytics' for isAnalytics=true datasets, or - 'operational' for isAnalytics=false datasets. Intersected with access grants. + scope value: 'operational' for readable intelligence datasets + (isAnalytics=false), 'analytics' for readable analytics datasets + (isAnalytics=true), or 'all'/'\\**' for every readable dataset including analytics + datasets (the graph reads analytics relationships from R2). Intersected with + access grants. """ direction: str diff --git a/src/cloudflare/types/cloudforce_one/threat_events/indicator_list_params.py b/src/cloudflare/types/cloudforce_one/threat_events/indicator_list_params.py index 74339cc323a..13c3aee62ae 100644 --- a/src/cloudflare/types/cloudforce_one/threat_events/indicator_list_params.py +++ b/src/cloudflare/types/cloudforce_one/threat_events/indicator_list_params.py @@ -50,10 +50,10 @@ class IndicatorListParams(TypedDict, total=False): dataset_ids: Annotated[SequenceNotStr[str], PropertyInfo(alias="datasetIds")] """ - Dataset UUIDs to query, or one standalone scope value: 'all'/'\\**' for legacy - all-datasets behavior, 'analytics' for isAnalytics=true datasets, or - 'operational' for isAnalytics=false datasets. If not provided, uses the default - dataset. + Dataset UUIDs to query, or one standalone scope value: 'all'/'\\**' or + 'operational' for readable intelligence datasets (isAnalytics=false), or + 'analytics' for readable analytics datasets (isAnalytics=true). If not provided, + uses the default dataset. """ format: Literal["json", "stix2", "taxii"] diff --git a/src/cloudflare/types/cloudforce_one/threat_events/indicators/aggregate_list_params.py b/src/cloudflare/types/cloudforce_one/threat_events/indicators/aggregate_list_params.py index 2b048f8c247..e39c32dfc53 100644 --- a/src/cloudflare/types/cloudforce_one/threat_events/indicators/aggregate_list_params.py +++ b/src/cloudflare/types/cloudforce_one/threat_events/indicators/aggregate_list_params.py @@ -36,10 +36,11 @@ class AggregateListParams(TypedDict, total=False): dataset_ids: Annotated[SequenceNotStr[str], PropertyInfo(alias="datasetIds")] """ - Dataset UUIDs to filter by, or one standalone scope value: 'all'/'\\**' for all - accessible datasets, 'analytics' for isAnalytics=true datasets, or 'operational' - for isAnalytics=false datasets. If not provided, aggregates across all - accessible datasets. + Dataset UUIDs to filter by, or one standalone scope value: 'operational' for + readable intelligence datasets (isAnalytics=false), 'analytics' for readable + analytics datasets (isAnalytics=true), or 'all'/'\\**' for every readable dataset + including analytics datasets. If not provided, aggregates across all accessible + datasets, including analytics datasets. """ event_date_after: Annotated[str, PropertyInfo(alias="eventDateAfter")] diff --git a/src/cloudflare/types/cloudforce_one/threat_events/indicators/type_list_params.py b/src/cloudflare/types/cloudforce_one/threat_events/indicators/type_list_params.py index 3e05cfb98ac..6e1422e8cc5 100644 --- a/src/cloudflare/types/cloudforce_one/threat_events/indicators/type_list_params.py +++ b/src/cloudflare/types/cloudforce_one/threat_events/indicators/type_list_params.py @@ -16,7 +16,9 @@ class TypeListParams(TypedDict, total=False): dataset_ids: Annotated[SequenceNotStr[str], PropertyInfo(alias="datasetIds")] """ - Dataset UUIDs to query, or one standalone scope value: 'all'/'\\**', 'analytics' - for isAnalytics=true datasets, or 'operational' for isAnalytics=false datasets. - If not provided, queries all accessible datasets. + Dataset UUIDs to query, or one standalone scope value: 'operational' for + readable intelligence datasets (isAnalytics=false), 'analytics' for readable + analytics datasets (isAnalytics=true), or 'all'/'\\**' for every readable dataset + including analytics datasets. If not provided, queries all accessible datasets, + including analytics datasets. """ diff --git a/src/cloudflare/types/cloudforce_one/threat_events/query_create_params.py b/src/cloudflare/types/cloudforce_one/threat_events/query_create_params.py index d85e94de4ca..4e396c9d071 100644 --- a/src/cloudflare/types/cloudforce_one/threat_events/query_create_params.py +++ b/src/cloudflare/types/cloudforce_one/threat_events/query_create_params.py @@ -11,20 +11,20 @@ class QueryCreateParams(TypedDict, total=False): account_id: Required[str] """Account ID.""" - alert_enabled: Required[bool] - """Enable alerts for this query""" - - alert_rollup_enabled: Required[bool] - """Enable alert rollup for this query""" - name: Required[str] """Unique name for the saved query""" query_json: Required[str] """JSON string containing the query parameters""" - rule_enabled: Required[bool] - """Enable rule for this query""" + alert_enabled: bool + """Deprecated and ignored: saved-query alerting and rules were removed.""" + + alert_rollup_enabled: bool + """Deprecated and ignored: saved-query alerting and rules were removed.""" + + rule_enabled: bool + """Deprecated and ignored: saved-query alerting and rules were removed.""" rule_scope: str - """Scope for the rule""" + """Deprecated and ignored: saved-query alerting and rules were removed.""" diff --git a/src/cloudflare/types/cloudforce_one/threat_events/query_create_response.py b/src/cloudflare/types/cloudforce_one/threat_events/query_create_response.py index 383ec4e53a4..aa86dbdce6a 100644 --- a/src/cloudflare/types/cloudforce_one/threat_events/query_create_response.py +++ b/src/cloudflare/types/cloudforce_one/threat_events/query_create_response.py @@ -15,10 +15,10 @@ class QueryCreateResponse(BaseModel): """Account ID""" alert_enabled: bool - """Whether alerts are enabled""" + """Deprecated: saved-query alerting and rules were removed. Always false.""" alert_rollup_enabled: bool - """Whether alert rollup is enabled""" + """Deprecated: saved-query alerting and rules were removed. Always false.""" created_at: str """Creation timestamp""" @@ -30,7 +30,7 @@ class QueryCreateResponse(BaseModel): """JSON string containing the query parameters""" rule_enabled: bool - """Whether rule is enabled""" + """Deprecated: saved-query alerting and rules were removed. Always false.""" updated_at: str """Last update timestamp""" @@ -39,10 +39,10 @@ class QueryCreateResponse(BaseModel): """Email of the user who created the query""" custom_threat_feed_id: Optional[int] = None - """Intel Indicator Feed ID (numeric)""" + """Deprecated: saved-query alerting and rules were removed. Always null.""" rule_list_id: Optional[str] = None - """WAF rules list ID for blocking""" + """Deprecated: saved-query alerting and rules were removed. Always null.""" rule_scope: Optional[str] = None - """Scope for the rule""" + """Deprecated: saved-query alerting and rules were removed. Always null.""" diff --git a/src/cloudflare/types/cloudforce_one/threat_events/query_edit_params.py b/src/cloudflare/types/cloudforce_one/threat_events/query_edit_params.py index 2578b62acf1..ddbae316cce 100644 --- a/src/cloudflare/types/cloudforce_one/threat_events/query_edit_params.py +++ b/src/cloudflare/types/cloudforce_one/threat_events/query_edit_params.py @@ -12,10 +12,10 @@ class QueryEditParams(TypedDict, total=False): """Account ID.""" alert_enabled: bool - """Enable alerts for this query""" + """Deprecated and ignored: saved-query alerting and rules were removed.""" alert_rollup_enabled: bool - """Enable alert rollup for this query""" + """Deprecated and ignored: saved-query alerting and rules were removed.""" name: str """Unique name for the saved query""" @@ -24,7 +24,7 @@ class QueryEditParams(TypedDict, total=False): """JSON string containing the query parameters""" rule_enabled: bool - """Enable rule for this query""" + """Deprecated and ignored: saved-query alerting and rules were removed.""" rule_scope: str - """Scope for the rule""" + """Deprecated and ignored: saved-query alerting and rules were removed.""" diff --git a/src/cloudflare/types/cloudforce_one/threat_events/query_edit_response.py b/src/cloudflare/types/cloudforce_one/threat_events/query_edit_response.py index 4c460ff7676..586c8c826b5 100644 --- a/src/cloudflare/types/cloudforce_one/threat_events/query_edit_response.py +++ b/src/cloudflare/types/cloudforce_one/threat_events/query_edit_response.py @@ -15,10 +15,10 @@ class QueryEditResponse(BaseModel): """Account ID""" alert_enabled: bool - """Whether alerts are enabled""" + """Deprecated: saved-query alerting and rules were removed. Always false.""" alert_rollup_enabled: bool - """Whether alert rollup is enabled""" + """Deprecated: saved-query alerting and rules were removed. Always false.""" created_at: str """Creation timestamp""" @@ -30,7 +30,7 @@ class QueryEditResponse(BaseModel): """JSON string containing the query parameters""" rule_enabled: bool - """Whether rule is enabled""" + """Deprecated: saved-query alerting and rules were removed. Always false.""" updated_at: str """Last update timestamp""" @@ -39,10 +39,10 @@ class QueryEditResponse(BaseModel): """Email of the user who created the query""" custom_threat_feed_id: Optional[int] = None - """Intel Indicator Feed ID (numeric)""" + """Deprecated: saved-query alerting and rules were removed. Always null.""" rule_list_id: Optional[str] = None - """WAF rules list ID for blocking""" + """Deprecated: saved-query alerting and rules were removed. Always null.""" rule_scope: Optional[str] = None - """Scope for the rule""" + """Deprecated: saved-query alerting and rules were removed. Always null.""" diff --git a/src/cloudflare/types/cloudforce_one/threat_events/query_get_response.py b/src/cloudflare/types/cloudforce_one/threat_events/query_get_response.py index 3dd5737ffb8..a32ba4e752a 100644 --- a/src/cloudflare/types/cloudforce_one/threat_events/query_get_response.py +++ b/src/cloudflare/types/cloudforce_one/threat_events/query_get_response.py @@ -15,10 +15,10 @@ class QueryGetResponse(BaseModel): """Account ID""" alert_enabled: bool - """Whether alerts are enabled""" + """Deprecated: saved-query alerting and rules were removed. Always false.""" alert_rollup_enabled: bool - """Whether alert rollup is enabled""" + """Deprecated: saved-query alerting and rules were removed. Always false.""" created_at: str """Creation timestamp""" @@ -30,7 +30,7 @@ class QueryGetResponse(BaseModel): """JSON string containing the query parameters""" rule_enabled: bool - """Whether rule is enabled""" + """Deprecated: saved-query alerting and rules were removed. Always false.""" updated_at: str """Last update timestamp""" @@ -39,10 +39,10 @@ class QueryGetResponse(BaseModel): """Email of the user who created the query""" custom_threat_feed_id: Optional[int] = None - """Intel Indicator Feed ID (numeric)""" + """Deprecated: saved-query alerting and rules were removed. Always null.""" rule_list_id: Optional[str] = None - """WAF rules list ID for blocking""" + """Deprecated: saved-query alerting and rules were removed. Always null.""" rule_scope: Optional[str] = None - """Scope for the rule""" + """Deprecated: saved-query alerting and rules were removed. Always null.""" diff --git a/src/cloudflare/types/cloudforce_one/threat_events/query_list_response.py b/src/cloudflare/types/cloudforce_one/threat_events/query_list_response.py index 251966f048a..ceb89531e58 100644 --- a/src/cloudflare/types/cloudforce_one/threat_events/query_list_response.py +++ b/src/cloudflare/types/cloudforce_one/threat_events/query_list_response.py @@ -16,10 +16,10 @@ class QueryListResponseItem(BaseModel): """Account ID""" alert_enabled: bool - """Whether alerts are enabled""" + """Deprecated: saved-query alerting and rules were removed. Always false.""" alert_rollup_enabled: bool - """Whether alert rollup is enabled""" + """Deprecated: saved-query alerting and rules were removed. Always false.""" created_at: str """Creation timestamp""" @@ -31,7 +31,7 @@ class QueryListResponseItem(BaseModel): """JSON string containing the query parameters""" rule_enabled: bool - """Whether rule is enabled""" + """Deprecated: saved-query alerting and rules were removed. Always false.""" updated_at: str """Last update timestamp""" @@ -40,13 +40,13 @@ class QueryListResponseItem(BaseModel): """Email of the user who created the query""" custom_threat_feed_id: Optional[int] = None - """Intel Indicator Feed ID (numeric)""" + """Deprecated: saved-query alerting and rules were removed. Always null.""" rule_list_id: Optional[str] = None - """WAF rules list ID for blocking""" + """Deprecated: saved-query alerting and rules were removed. Always null.""" rule_scope: Optional[str] = None - """Scope for the rule""" + """Deprecated: saved-query alerting and rules were removed. Always null.""" QueryListResponse: TypeAlias = List[QueryListResponseItem] diff --git a/src/cloudflare/types/cloudforce_one/threat_events/tags/indicator_list_params.py b/src/cloudflare/types/cloudforce_one/threat_events/tags/indicator_list_params.py index b57f76e91e5..2b48ea90b68 100644 --- a/src/cloudflare/types/cloudforce_one/threat_events/tags/indicator_list_params.py +++ b/src/cloudflare/types/cloudforce_one/threat_events/tags/indicator_list_params.py @@ -18,10 +18,10 @@ class IndicatorListParams(TypedDict, total=False): dataset_ids: Annotated[SequenceNotStr[str], PropertyInfo(alias="datasetIds")] """ Dataset UUIDs to scope to (repeat the param for multiple), or one standalone - scope: 'all'/'\\**', 'analytics' for isAnalytics=true datasets, or 'operational' - for isAnalytics=false datasets. Analytics datasets do not expose tag - associations, so 'analytics' returns an empty result. Omit to search all - readable datasets. + scope value: 'all'/'\\**' or 'operational' for readable intelligence datasets + (isAnalytics=false), or 'analytics' for readable analytics datasets + (isAnalytics=true). Analytics datasets do not expose tag associations, so + 'analytics' returns an empty result. Omit for 'all'. """ indicator_type: Annotated[str, PropertyInfo(alias="indicatorType")] diff --git a/src/cloudflare/types/cloudforce_one/threat_signals/article_bulk_edit_params.py b/src/cloudflare/types/cloudforce_one/threat_signals/article_bulk_edit_params.py index 25419321f36..49c178911ca 100644 --- a/src/cloudflare/types/cloudforce_one/threat_signals/article_bulk_edit_params.py +++ b/src/cloudflare/types/cloudforce_one/threat_signals/article_bulk_edit_params.py @@ -13,5 +13,7 @@ class ArticleBulkEditParams(TypedDict, total=False): account_id: Required[str] article_ids: Required[SequenceNotStr[str]] + """Array of article UUIDs to mark (1-50).""" read: Required[bool] + """True to mark read, false to mark unread.""" diff --git a/src/cloudflare/types/cloudforce_one/threat_signals/article_edit_params.py b/src/cloudflare/types/cloudforce_one/threat_signals/article_edit_params.py index bd0e1d4b73e..28e9bd882de 100644 --- a/src/cloudflare/types/cloudforce_one/threat_signals/article_edit_params.py +++ b/src/cloudflare/types/cloudforce_one/threat_signals/article_edit_params.py @@ -11,3 +11,4 @@ class ArticleEditParams(TypedDict, total=False): account_id: Required[str] read: Required[bool] + """True to mark the article read, false to mark unread.""" diff --git a/src/cloudflare/types/cloudforce_one/threat_signals/article_edit_response.py b/src/cloudflare/types/cloudforce_one/threat_signals/article_edit_response.py index 76d79979e27..40b0e3f1d22 100644 --- a/src/cloudflare/types/cloudforce_one/threat_signals/article_edit_response.py +++ b/src/cloudflare/types/cloudforce_one/threat_signals/article_edit_response.py @@ -57,6 +57,15 @@ class ArticleEditResponse(BaseModel): read_at: Optional[str] = None + severity: Optional[Literal["informational", "low", "medium", "high", "critical"]] = None + """Beta. + + Intrinsic article severity band, from informational to critical, independent of + any organisation or Priority Intelligence Requirement. Null when the account has + no active Priority Intelligence Requirements, scoring has not completed, or a + historic article has not entered an automatic rescore window. + """ + source_count: float summary: Optional[str] = None diff --git a/src/cloudflare/types/cloudforce_one/threat_signals/article_get_response.py b/src/cloudflare/types/cloudforce_one/threat_signals/article_get_response.py index 0d87ec25617..feed6c86773 100644 --- a/src/cloudflare/types/cloudforce_one/threat_signals/article_get_response.py +++ b/src/cloudflare/types/cloudforce_one/threat_signals/article_get_response.py @@ -7,7 +7,7 @@ from ...._models import BaseModel -__all__ = ["ArticleGetResponse", "BulletPoints", "Tag"] +__all__ = ["ArticleGetResponse", "BulletPoints", "Relevance", "RelevancePir", "Tag"] class BulletPoints(BaseModel): @@ -18,6 +18,47 @@ class BulletPoints(BaseModel): who_affected: str +class RelevancePir(BaseModel): + band: Literal["low", "medium", "high"] + """Beta. + + How relevant the article is to a Priority Intelligence Requirement: high, + medium, or low. Cloudflare may change the scores behind each band as relevance + scoring is calibrated. + """ + + pir_id: str + + +class Relevance(BaseModel): + """Beta. + + The article's relevance to the account's active Priority Intelligence Requirements. Null when the article has not been scored against them, including when the account has no active PIRs, or has not been scored against the requested pir_id. + """ + + band: Literal["low", "medium", "high"] + """Beta. + + How relevant the article is to a Priority Intelligence Requirement: high, + medium, or low. Cloudflare may change the scores behind each band as relevance + scoring is calibrated. + """ + + pir_id: str + """Beta. + + The pir_id requested from the article list, or otherwise the account's most + relevant active PIR for this article. + """ + + pirs: List[RelevancePir] + """Beta. + + Every active PIR the article was scored against, most relevant first. Draft and + deleted PIRs are excluded. + """ + + class Tag(BaseModel): applied_by: Literal["ai", "analyst", "system"] @@ -57,6 +98,24 @@ class ArticleGetResponse(BaseModel): read_at: Optional[str] = None + relevance: Optional[Relevance] = None + """Beta. + + The article's relevance to the account's active Priority Intelligence + Requirements. Null when the article has not been scored against them, including + when the account has no active PIRs, or has not been scored against the + requested pir_id. + """ + + severity: Optional[Literal["informational", "low", "medium", "high", "critical"]] = None + """Beta. + + Intrinsic article severity band, from informational to critical, independent of + any organisation or Priority Intelligence Requirement. Null when the account has + no active Priority Intelligence Requirements, scoring has not completed, or a + historic article has not entered an automatic rescore window. + """ + source_count: float summary: Optional[str] = None diff --git a/src/cloudflare/types/cloudforce_one/threat_signals/article_list_params.py b/src/cloudflare/types/cloudforce_one/threat_signals/article_list_params.py index 0e41e4792f9..4e81293f028 100644 --- a/src/cloudflare/types/cloudforce_one/threat_signals/article_list_params.py +++ b/src/cloudflare/types/cloudforce_one/threat_signals/article_list_params.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing import Union +from typing import List, Union from datetime import datetime from typing_extensions import Literal, Required, Annotated, TypedDict @@ -31,28 +31,90 @@ class ArticleListParams(TypedDict, total=False): """ feed_category: str + """Exact feed-category filter after trimming. Omit to include every category.""" feed_id: str + """Feed UUID filter. Omit to include articles from every account feed.""" fetched_after: Annotated[Union[str, datetime], PropertyInfo(format="iso8601")] + """ + Include articles fetched at or after this ISO 8601 date-time with Z or a numeric + UTC offset; normalized to UTC. + """ fetched_before: Annotated[Union[str, datetime], PropertyInfo(format="iso8601")] + """ + Include articles fetched at or before this ISO 8601 date-time with Z or a + numeric UTC offset; normalized to UTC. + """ include_total: bool + """When true on the first page, count matching articles and return an exact total. + + Defaults to false; cursor pages do not recalculate totals. + """ + + min_relevance: Literal["low", "medium", "high"] + """Beta. + + Return only articles at or above this relevance band for pir_id, or for any + active PIR when pir_id is omitted. Excludes articles that have not been scored. + """ per_page: int + """Number of articles per cursor page, from 1 to 100. Defaults to 20.""" + + pir_id: str + """Beta. + + Active Priority Intelligence Requirement to report, filter, and sort relevance + by. Omit to use each article's most relevant active PIR. Returns a 400 error + unless the PIR is active. + """ published_after: Annotated[Union[str, datetime], PropertyInfo(format="iso8601")] + """ + Include articles published at or after this ISO 8601 date-time with Z or a + numeric UTC offset; normalized to UTC. + """ published_before: Annotated[Union[str, datetime], PropertyInfo(format="iso8601")] + """ + Include articles published at or before this ISO 8601 date-time with Z or a + numeric UTC offset; normalized to UTC. + """ read: bool + """Filter by read state. + + Accepts true, false, 1, or 0; omit to include read and unread articles. + """ search: str + """ + NFC-normalized, trimmed literal substring filter on article titles; ASCII + case-insensitive, from 1 to 500 characters. + """ + + severity: List[Literal["informational", "low", "medium", "high", "critical"]] + """Beta. + + Repeatable intrinsic severity band filter. An article matches any selected band, + the band reported as its severity. Excludes articles without a severity. Like + the severity field, severity is reported only while the account has an active + Priority Intelligence Requirement; otherwise no articles match. + """ sort: str + """Sort by fetched_at, published_at, title, or relevance (beta). + + Prefix the field with - for descending order; defaults to -fetched_at. + -relevance lists the most relevant articles first, by pir_id or by each + article's most relevant active PIR, with unscored articles last. + """ source_type: Literal["curated", "custom"] + """Filter by curated or custom feed source. Omit to include both source types.""" tag: str """Legacy human-readable tag-value filter. diff --git a/src/cloudflare/types/cloudforce_one/threat_signals/article_list_response.py b/src/cloudflare/types/cloudforce_one/threat_signals/article_list_response.py index b79e7c41b3e..4daa4cf533e 100644 --- a/src/cloudflare/types/cloudforce_one/threat_signals/article_list_response.py +++ b/src/cloudflare/types/cloudforce_one/threat_signals/article_list_response.py @@ -7,7 +7,48 @@ from ...._models import BaseModel -__all__ = ["ArticleListResponse", "Article", "ArticleTag"] +__all__ = ["ArticleListResponse", "Article", "ArticleRelevance", "ArticleRelevancePir", "ArticleTag"] + + +class ArticleRelevancePir(BaseModel): + band: Literal["low", "medium", "high"] + """Beta. + + How relevant the article is to a Priority Intelligence Requirement: high, + medium, or low. Cloudflare may change the scores behind each band as relevance + scoring is calibrated. + """ + + pir_id: str + + +class ArticleRelevance(BaseModel): + """Beta. + + The article's relevance to the account's active Priority Intelligence Requirements. Null when the article has not been scored against them, including when the account has no active PIRs, or has not been scored against the requested pir_id. + """ + + band: Literal["low", "medium", "high"] + """Beta. + + How relevant the article is to a Priority Intelligence Requirement: high, + medium, or low. Cloudflare may change the scores behind each band as relevance + scoring is calibrated. + """ + + pir_id: str + """Beta. + + The pir_id requested from the article list, or otherwise the account's most + relevant active PIR for this article. + """ + + pirs: List[ArticleRelevancePir] + """Beta. + + Every active PIR the article was scored against, most relevant first. Draft and + deleted PIRs are excluded. + """ class ArticleTag(BaseModel): @@ -49,6 +90,24 @@ class Article(BaseModel): read_at: Optional[str] = None + relevance: Optional[ArticleRelevance] = None + """Beta. + + The article's relevance to the account's active Priority Intelligence + Requirements. Null when the article has not been scored against them, including + when the account has no active PIRs, or has not been scored against the + requested pir_id. + """ + + severity: Optional[Literal["informational", "low", "medium", "high", "critical"]] = None + """Beta. + + Intrinsic article severity band, from informational to critical, independent of + any organisation or Priority Intelligence Requirement. Null when the account has + no active Priority Intelligence Requirements, scoring has not completed, or a + historic article has not entered an automatic rescore window. + """ + summary: Optional[str] = None """Persisted enrichment summary. Null until enrichment produces a summary.""" diff --git a/src/cloudflare/types/cloudforce_one/threat_signals/articles/content_get_params.py b/src/cloudflare/types/cloudforce_one/threat_signals/articles/content_get_params.py index e0cb929606b..0481ee45f01 100644 --- a/src/cloudflare/types/cloudforce_one/threat_signals/articles/content_get_params.py +++ b/src/cloudflare/types/cloudforce_one/threat_signals/articles/content_get_params.py @@ -11,3 +11,7 @@ class ContentGetParams(TypedDict, total=False): account_id: Required[str] format: Literal["text", "html"] + """Response Content-Type: text (the default) for text/plain or html for text/html. + + Neither value converts the content. html is deprecated; use text. + """ diff --git a/src/cloudflare/types/cloudforce_one/threat_signals/articles/skill_output_get_response.py b/src/cloudflare/types/cloudforce_one/threat_signals/articles/skill_output_get_response.py index 833301364e7..cfb8debdd94 100644 --- a/src/cloudflare/types/cloudforce_one/threat_signals/articles/skill_output_get_response.py +++ b/src/cloudflare/types/cloudforce_one/threat_signals/articles/skill_output_get_response.py @@ -1,6 +1,7 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import Optional +from typing import Dict, List, Union, Optional +from typing_extensions import Literal from ....._models import BaseModel @@ -9,16 +10,31 @@ class SkillOutputGetResponse(BaseModel): article_id: str + """Article UUID that received the skill output.""" - custom_skill_version: Optional[str] = None + custom_output: Union[str, float, bool, Dict[str, object], List[Union[str, float, bool, Dict[str, object]]]] + """ + Untrusted model output: parsed JSON when the stored completion text is valid + JSON, otherwise raw text. Consumers must safely render or escape it. + """ - output_schema: Optional[str] = None - """JSON-encoded output schema of the skill. Null when the skill no longer exists.""" + custom_output_parse_status: Literal["parsed", "invalid_json"] + """Whether custom_output was parsed from the stored completion text.""" - skill_id: str + custom_output_validation_status: Literal["valid", "invalid_json", "schema_invalid", "unknown"] + """Non-blocking validation classification for untrusted model output. + + `unknown` is retained only for historical rows. + """ - custom_output: Optional[object] = None - """Skill output. + custom_skill_version: Optional[str] = None + """Custom Skill version that produced the output. - Parsed JSON when the stored output is valid JSON, otherwise the raw string. + Null when historical metadata is unavailable. """ + + output_schema: Optional[str] = None + """JSON-encoded output schema. Null when historical skill metadata is unavailable.""" + + skill_id: str + """Custom Skill UUID that produced the output.""" diff --git a/src/cloudflare/types/cloudforce_one/threat_signals/articles/tag_create_params.py b/src/cloudflare/types/cloudforce_one/threat_signals/articles/tag_create_params.py index b97a027ad1d..3550dba0036 100644 --- a/src/cloudflare/types/cloudforce_one/threat_signals/articles/tag_create_params.py +++ b/src/cloudflare/types/cloudforce_one/threat_signals/articles/tag_create_params.py @@ -11,3 +11,4 @@ class TagCreateParams(TypedDict, total=False): account_id: Required[str] tag_id: Required[str] + """UUID of a tag from the account's catalog to apply to the article.""" diff --git a/src/cloudflare/types/cloudforce_one/threat_signals/feed_create_params.py b/src/cloudflare/types/cloudforce_one/threat_signals/feed_create_params.py index c88ce6d5adf..df06dc23fe5 100644 --- a/src/cloudflare/types/cloudforce_one/threat_signals/feed_create_params.py +++ b/src/cloudflare/types/cloudforce_one/threat_signals/feed_create_params.py @@ -29,13 +29,33 @@ class FeedCreateParams(TypedDict, total=False): """ curated_feed_id: str + """UUID of a curated feed to subscribe to. + + Provide exactly one of url or curated_feed_id. The account must have feed + creation entitlement and not exceed feed allowance. + """ display_name: Optional[str] + """Override the feed's display name. + + Null clears it; omit to keep existing or derived value. + """ enabled: bool + """Whether to actively poll the feed. Default true.""" poll_interval_s: int + """Polling interval in seconds (60-86400). Default 300s (5 minutes).""" title: Optional[str] + """Override the feed's title. + + Null clears it; omit to keep existing or derived value. + """ url: str + """HTTPS RSS feed URL. + + Provide exactly one of url or curated_feed_id. The account must have feed + creation entitlement and not exceed feed allowance. + """ diff --git a/src/cloudflare/types/cloudforce_one/threat_signals/feed_edit_params.py b/src/cloudflare/types/cloudforce_one/threat_signals/feed_edit_params.py index c8194e6520f..0512000cb31 100644 --- a/src/cloudflare/types/cloudforce_one/threat_signals/feed_edit_params.py +++ b/src/cloudflare/types/cloudforce_one/threat_signals/feed_edit_params.py @@ -29,9 +29,19 @@ class FeedEditParams(TypedDict, total=False): """ display_name: Optional[str] + """Override the feed's display name. + + Null clears it; omit to keep existing or derived value. + """ enabled: bool + """Whether to actively poll the feed. Omit to keep current value.""" poll_interval_s: int + """New polling interval in seconds (60-86400). Omit to keep current value.""" title: Optional[str] + """Override the feed's title. + + Null clears it; omit to keep existing or derived value. + """ diff --git a/src/cloudflare/types/cloudforce_one/threat_signals/feed_list_params.py b/src/cloudflare/types/cloudforce_one/threat_signals/feed_list_params.py index 48b3ae6b287..072ed79bb5d 100644 --- a/src/cloudflare/types/cloudforce_one/threat_signals/feed_list_params.py +++ b/src/cloudflare/types/cloudforce_one/threat_signals/feed_list_params.py @@ -11,17 +11,37 @@ class FeedListParams(TypedDict, total=False): account_id: Required[str] category: str + """Exact feed-category filter, up to 100 characters. + + Omit to include all categories. + """ enabled: bool + """Filter by enabled state. + + Accepts true, false, 1, or 0; omit to include enabled and disabled feeds. + """ limit: int + """Optional 1–100 alias for per_page. When provided, limit takes precedence.""" page: int + """1-based page number. Minimum 1; defaults to 1.""" per_page: int + """Number of feeds per page, from 1 to 100. Defaults to 20.""" sort: str + """Sort by created_at, title, category, or url. + + Prefix the field with - for descending order; defaults to -created_at. + """ source_type: Literal["curated", "custom"] + """Filter by curated or custom feed source. Omit to include both source types.""" status: str + """Exact stored polling-status filter, such as active or error. + + Omit to include every status. + """ diff --git a/src/cloudflare/types/cloudforce_one/threat_signals/feed_list_response.py b/src/cloudflare/types/cloudforce_one/threat_signals/feed_list_response.py index 045de0dbcbe..45e17e17e38 100644 --- a/src/cloudflare/types/cloudforce_one/threat_signals/feed_list_response.py +++ b/src/cloudflare/types/cloudforce_one/threat_signals/feed_list_response.py @@ -48,6 +48,12 @@ class FeedListResponse(BaseModel): count: int """Number of feeds on this page.""" + custom_feed_count: int + """The current count of custom feeds for the account.""" + + custom_feed_limit: int + """The resolved custom feed limit for the account.""" + feeds: List[Feed] page: int diff --git a/src/cloudflare/types/cloudforce_one/threat_signals/feed_poll_params.py b/src/cloudflare/types/cloudforce_one/threat_signals/feed_poll_params.py index f149a61b14b..48a4bd96d39 100644 --- a/src/cloudflare/types/cloudforce_one/threat_signals/feed_poll_params.py +++ b/src/cloudflare/types/cloudforce_one/threat_signals/feed_poll_params.py @@ -12,3 +12,7 @@ class FeedPollParams(TypedDict, total=False): account_id: Required[str] feed_id: Union[str, Literal["all"]] + """UUID of a specific feed to poll, or "all" to poll all feeds. + + Omit or pass "all" for all feeds. + """ diff --git a/src/cloudflare/types/cloudforce_one/threat_signals/feeds/raw_get_params.py b/src/cloudflare/types/cloudforce_one/threat_signals/feeds/raw_get_params.py index bdfa9be3e49..bab91a31faf 100644 --- a/src/cloudflare/types/cloudforce_one/threat_signals/feeds/raw_get_params.py +++ b/src/cloudflare/types/cloudforce_one/threat_signals/feeds/raw_get_params.py @@ -11,3 +11,7 @@ class RawGetParams(TypedDict, total=False): account_id: Required[str] format: Literal["xml"] + """Response format. + + Use xml for application/xml; omit it for the default text/plain response. + """ diff --git a/src/cloudflare/types/cloudforce_one/threat_signals/feeds/skill_update_params.py b/src/cloudflare/types/cloudforce_one/threat_signals/feeds/skill_update_params.py index d7b19da8941..b90a1089252 100644 --- a/src/cloudflare/types/cloudforce_one/threat_signals/feeds/skill_update_params.py +++ b/src/cloudflare/types/cloudforce_one/threat_signals/feeds/skill_update_params.py @@ -13,3 +13,8 @@ class SkillUpdateParams(TypedDict, total=False): account_id: Required[str] skill_ids: Required[SequenceNotStr[str]] + """Ordered array of Custom Skill UUIDs (max 20). + + Replaces the feed's custom skill assignments. Free accounts cannot assign custom + skills. Managed default skills are unaffected. + """ diff --git a/src/cloudflare/types/cloudforce_one/threat_signals/indicator_list_params.py b/src/cloudflare/types/cloudforce_one/threat_signals/indicator_list_params.py index 465debc8c0c..5e94e88bc79 100644 --- a/src/cloudflare/types/cloudforce_one/threat_signals/indicator_list_params.py +++ b/src/cloudflare/types/cloudforce_one/threat_signals/indicator_list_params.py @@ -11,14 +11,28 @@ class IndicatorListParams(TypedDict, total=False): account_id: Required[str] article_id: str + """Article UUID filter. Omit to include indicators from every article.""" cursor: str + """Opaque cursor from the previous response's `pagination.cursor`. + + When provided, page size, ordering, and filters come from the cursor. Sending + `per_page`, `sort`, `include_total`, `feed_id`, `article_id`, or `search` + alongside it returns a 400 `CursorFilterConflictError`. + """ feed_id: str + """Feed UUID filter. Omit to include indicators from every account feed.""" include_total: bool + """When true on the first page, count matching indicators and return an exact + total. + + Defaults to false; cursor pages do not recalculate totals. + """ per_page: int + """Number of indicators per cursor page, from 1 to 100. Defaults to 20.""" search: str """ @@ -29,3 +43,4 @@ class IndicatorListParams(TypedDict, total=False): """ sort: str + """Sort by id. Use id for ascending or -id for descending order; defaults to id.""" diff --git a/src/cloudflare/types/cloudforce_one/threat_signals/search_search_params.py b/src/cloudflare/types/cloudforce_one/threat_signals/search_search_params.py index ceb906cde3f..76437442e4a 100644 --- a/src/cloudflare/types/cloudforce_one/threat_signals/search_search_params.py +++ b/src/cloudflare/types/cloudforce_one/threat_signals/search_search_params.py @@ -12,7 +12,14 @@ class SearchSearchParams(TypedDict, total=False): account_id: Required[str] query: Required[str] + """Keyword and semantic article-search text, from 1 to 1000 characters.""" feed_id: str + """Optional feed UUID that restricts results to articles from that feed.""" max_results: Union[Literal[""], str] + """Maximum search matches to request, an integer from 1 to 50. + + Defaults to 20 when omitted or empty; multiple matches from one article can + produce fewer returned articles. + """ diff --git a/src/cloudflare/types/cloudforce_one/threat_signals/skill_create_params.py b/src/cloudflare/types/cloudforce_one/threat_signals/skill_create_params.py index 35521228077..6166ea32bb6 100644 --- a/src/cloudflare/types/cloudforce_one/threat_signals/skill_create_params.py +++ b/src/cloudflare/types/cloudforce_one/threat_signals/skill_create_params.py @@ -11,9 +11,13 @@ class SkillCreateParams(TypedDict, total=False): account_id: Required[str] name: Required[str] + """Custom Skill name (1–100 characters).""" output_schema: Required[str] + """JSON Schema serialized as a string (max 4096 characters).""" prompt: Required[str] + """AI prompt (1–4000 characters) defining the skill's instructions.""" - type: Required[Literal["summary", "tags"]] + type: Literal["summary", "tags"] + """Optional label; does not affect execution. Defaults to "summary".""" diff --git a/src/cloudflare/types/cloudforce_one/threat_signals/skill_edit_params.py b/src/cloudflare/types/cloudforce_one/threat_signals/skill_edit_params.py index 7a8493f9e53..8468dffb271 100644 --- a/src/cloudflare/types/cloudforce_one/threat_signals/skill_edit_params.py +++ b/src/cloudflare/types/cloudforce_one/threat_signals/skill_edit_params.py @@ -11,11 +11,16 @@ class SkillEditParams(TypedDict, total=False): account_id: Required[str] config: str + """Optional skill configuration (stored but not currently interpreted).""" is_active: bool + """Whether the skill is active and eligible for feed assignment.""" name: str + """Custom Skill name (1–100 characters).""" output_schema: str + """JSON Schema serialized as a string (max 4096 characters).""" prompt: str + """AI prompt (1–4000 characters) defining the skill's instructions.""" diff --git a/src/cloudflare/types/cloudforce_one/threat_signals/skill_list_params.py b/src/cloudflare/types/cloudforce_one/threat_signals/skill_list_params.py index 5a25d02d4ed..5a61614ec46 100644 --- a/src/cloudflare/types/cloudforce_one/threat_signals/skill_list_params.py +++ b/src/cloudflare/types/cloudforce_one/threat_signals/skill_list_params.py @@ -11,5 +11,7 @@ class SkillListParams(TypedDict, total=False): account_id: Required[str] page: int + """Page number (≥ 1, default 1).""" per_page: int + """Results per page (1–100, default 20).""" diff --git a/src/cloudflare/types/cloudforce_one/threat_signals/skill_list_response.py b/src/cloudflare/types/cloudforce_one/threat_signals/skill_list_response.py index 0cf370c3963..974190d8e0e 100644 --- a/src/cloudflare/types/cloudforce_one/threat_signals/skill_list_response.py +++ b/src/cloudflare/types/cloudforce_one/threat_signals/skill_list_response.py @@ -42,11 +42,10 @@ class SkillListResponse(BaseModel): """Number of skills on this page.""" custom_skills_available: bool - """ - Whether the authenticated account may access custom-skill capabilities under - Stakeout's Threat Signals access-mode policy. This is a policy availability - indicator, not a row-existence indicator. False for threat_signals_only mode; - true for entitled, allowlisted, cfone_internal, and service modes. + """Whether Custom Skills are available to the account. + + False for Free Threat Signals accounts, which receive managed default skills + only. """ page: int diff --git a/src/cloudflare/types/cloudforce_one/threat_signals/skills/tag_category_update_params.py b/src/cloudflare/types/cloudforce_one/threat_signals/skills/tag_category_update_params.py index 71b5b51821d..108faf0f4e3 100644 --- a/src/cloudflare/types/cloudforce_one/threat_signals/skills/tag_category_update_params.py +++ b/src/cloudflare/types/cloudforce_one/threat_signals/skills/tag_category_update_params.py @@ -13,3 +13,7 @@ class TagCategoryUpdateParams(TypedDict, total=False): account_id: Required[str] category_uuids: Required[SequenceNotStr[str]] + """ + Up to 100 unique tag category UUIDs that the managed default tagging skill may + select tags from. + """ diff --git a/src/cloudflare/types/connectivity/directory/service_create_params.py b/src/cloudflare/types/connectivity/directory/service_create_params.py index ec11d783cc7..1dd51fdc730 100644 --- a/src/cloudflare/types/connectivity/directory/service_create_params.py +++ b/src/cloudflare/types/connectivity/directory/service_create_params.py @@ -49,10 +49,7 @@ class InfraHTTPServiceConfig(TypedDict, total=False): https_port: Optional[int] tls_settings: Optional[InfraHTTPServiceConfigTLSSettings] - """TLS settings for a connectivity service. - - If omitted, the default mode (`verify_full`) is used. - """ + """TLS settings for a connectivity service.""" class InfraHTTPServiceConfigHostInfraIPv4HostNetwork(TypedDict, total=False): @@ -108,10 +105,7 @@ class InfraHTTPServiceConfigHostInfraHostnameHost(TypedDict, total=False): class InfraHTTPServiceConfigTLSSettings(TypedDict, total=False): - """TLS settings for a connectivity service. - - If omitted, the default mode (`verify_full`) is used. - """ + """TLS settings for a connectivity service.""" cert_verification_mode: Required[str] """TLS certificate verification mode for the connection to the origin. @@ -119,8 +113,17 @@ class InfraHTTPServiceConfigTLSSettings(TypedDict, total=False): - `"verify_full"` — verify certificate chain and hostname (default) - `"verify_ca"` — verify certificate chain only, skip hostname check - `"disabled"` — do not verify the server certificate at all + + `disabled` cannot be combined with `certificate_authority`: a custom CA is only + used to verify the server certificate. """ + certificate_authority: Optional[str] + """UUID of the custom CA certificate or chain.""" + + client_certificate: Optional[str] + """UUID of the mTLS client certificate and private key.""" + class InfraTCPServiceConfig(TypedDict, total=False): account_id: Required[str] @@ -137,10 +140,7 @@ class InfraTCPServiceConfig(TypedDict, total=False): tcp_port: Optional[int] tls_settings: Optional[InfraTCPServiceConfigTLSSettings] - """TLS settings for a connectivity service. - - If omitted, the default mode (`verify_full`) is used. - """ + """TLS settings for a connectivity service.""" class InfraTCPServiceConfigHostInfraIPv4HostNetwork(TypedDict, total=False): @@ -196,10 +196,7 @@ class InfraTCPServiceConfigHostInfraHostnameHost(TypedDict, total=False): class InfraTCPServiceConfigTLSSettings(TypedDict, total=False): - """TLS settings for a connectivity service. - - If omitted, the default mode (`verify_full`) is used. - """ + """TLS settings for a connectivity service.""" cert_verification_mode: Required[str] """TLS certificate verification mode for the connection to the origin. @@ -207,7 +204,16 @@ class InfraTCPServiceConfigTLSSettings(TypedDict, total=False): - `"verify_full"` — verify certificate chain and hostname (default) - `"verify_ca"` — verify certificate chain only, skip hostname check - `"disabled"` — do not verify the server certificate at all + + `disabled` cannot be combined with `certificate_authority`: a custom CA is only + used to verify the server certificate. """ + certificate_authority: Optional[str] + """UUID of the custom CA certificate or chain.""" + + client_certificate: Optional[str] + """UUID of the mTLS client certificate and private key.""" + ServiceCreateParams: TypeAlias = Union[InfraHTTPServiceConfig, InfraTCPServiceConfig] diff --git a/src/cloudflare/types/connectivity/directory/service_create_response.py b/src/cloudflare/types/connectivity/directory/service_create_response.py index 51e2bfcb426..66a9bdc0a86 100644 --- a/src/cloudflare/types/connectivity/directory/service_create_response.py +++ b/src/cloudflare/types/connectivity/directory/service_create_response.py @@ -86,10 +86,7 @@ class InfraHTTPServiceConfigHostInfraHostnameHost(BaseModel): class InfraHTTPServiceConfigTLSSettings(BaseModel): - """TLS settings for a connectivity service. - - If omitted, the default mode (`verify_full`) is used. - """ + """TLS settings for a connectivity service.""" cert_verification_mode: str """TLS certificate verification mode for the connection to the origin. @@ -97,8 +94,17 @@ class InfraHTTPServiceConfigTLSSettings(BaseModel): - `"verify_full"` — verify certificate chain and hostname (default) - `"verify_ca"` — verify certificate chain only, skip hostname check - `"disabled"` — do not verify the server certificate at all + + `disabled` cannot be combined with `certificate_authority`: a custom CA is only + used to verify the server certificate. """ + certificate_authority: Optional[str] = None + """UUID of the custom CA certificate or chain.""" + + client_certificate: Optional[str] = None + """UUID of the mTLS client certificate and private key.""" + class InfraHTTPServiceConfig(BaseModel): host: InfraHTTPServiceConfigHost @@ -116,10 +122,7 @@ class InfraHTTPServiceConfig(BaseModel): service_id: Optional[str] = None tls_settings: Optional[InfraHTTPServiceConfigTLSSettings] = None - """TLS settings for a connectivity service. - - If omitted, the default mode (`verify_full`) is used. - """ + """TLS settings for a connectivity service.""" updated_at: Optional[datetime] = None @@ -177,10 +180,7 @@ class InfraTCPServiceConfigHostInfraHostnameHost(BaseModel): class InfraTCPServiceConfigTLSSettings(BaseModel): - """TLS settings for a connectivity service. - - If omitted, the default mode (`verify_full`) is used. - """ + """TLS settings for a connectivity service.""" cert_verification_mode: str """TLS certificate verification mode for the connection to the origin. @@ -188,8 +188,17 @@ class InfraTCPServiceConfigTLSSettings(BaseModel): - `"verify_full"` — verify certificate chain and hostname (default) - `"verify_ca"` — verify certificate chain only, skip hostname check - `"disabled"` — do not verify the server certificate at all + + `disabled` cannot be combined with `certificate_authority`: a custom CA is only + used to verify the server certificate. """ + certificate_authority: Optional[str] = None + """UUID of the custom CA certificate or chain.""" + + client_certificate: Optional[str] = None + """UUID of the mTLS client certificate and private key.""" + class InfraTCPServiceConfig(BaseModel): host: InfraTCPServiceConfigHost @@ -207,10 +216,7 @@ class InfraTCPServiceConfig(BaseModel): tcp_port: Optional[int] = None tls_settings: Optional[InfraTCPServiceConfigTLSSettings] = None - """TLS settings for a connectivity service. - - If omitted, the default mode (`verify_full`) is used. - """ + """TLS settings for a connectivity service.""" updated_at: Optional[datetime] = None diff --git a/src/cloudflare/types/connectivity/directory/service_get_response.py b/src/cloudflare/types/connectivity/directory/service_get_response.py index 924ac1b47fb..eefc22c72fe 100644 --- a/src/cloudflare/types/connectivity/directory/service_get_response.py +++ b/src/cloudflare/types/connectivity/directory/service_get_response.py @@ -86,10 +86,7 @@ class InfraHTTPServiceConfigHostInfraHostnameHost(BaseModel): class InfraHTTPServiceConfigTLSSettings(BaseModel): - """TLS settings for a connectivity service. - - If omitted, the default mode (`verify_full`) is used. - """ + """TLS settings for a connectivity service.""" cert_verification_mode: str """TLS certificate verification mode for the connection to the origin. @@ -97,8 +94,17 @@ class InfraHTTPServiceConfigTLSSettings(BaseModel): - `"verify_full"` — verify certificate chain and hostname (default) - `"verify_ca"` — verify certificate chain only, skip hostname check - `"disabled"` — do not verify the server certificate at all + + `disabled` cannot be combined with `certificate_authority`: a custom CA is only + used to verify the server certificate. """ + certificate_authority: Optional[str] = None + """UUID of the custom CA certificate or chain.""" + + client_certificate: Optional[str] = None + """UUID of the mTLS client certificate and private key.""" + class InfraHTTPServiceConfig(BaseModel): host: InfraHTTPServiceConfigHost @@ -116,10 +122,7 @@ class InfraHTTPServiceConfig(BaseModel): service_id: Optional[str] = None tls_settings: Optional[InfraHTTPServiceConfigTLSSettings] = None - """TLS settings for a connectivity service. - - If omitted, the default mode (`verify_full`) is used. - """ + """TLS settings for a connectivity service.""" updated_at: Optional[datetime] = None @@ -177,10 +180,7 @@ class InfraTCPServiceConfigHostInfraHostnameHost(BaseModel): class InfraTCPServiceConfigTLSSettings(BaseModel): - """TLS settings for a connectivity service. - - If omitted, the default mode (`verify_full`) is used. - """ + """TLS settings for a connectivity service.""" cert_verification_mode: str """TLS certificate verification mode for the connection to the origin. @@ -188,8 +188,17 @@ class InfraTCPServiceConfigTLSSettings(BaseModel): - `"verify_full"` — verify certificate chain and hostname (default) - `"verify_ca"` — verify certificate chain only, skip hostname check - `"disabled"` — do not verify the server certificate at all + + `disabled` cannot be combined with `certificate_authority`: a custom CA is only + used to verify the server certificate. """ + certificate_authority: Optional[str] = None + """UUID of the custom CA certificate or chain.""" + + client_certificate: Optional[str] = None + """UUID of the mTLS client certificate and private key.""" + class InfraTCPServiceConfig(BaseModel): host: InfraTCPServiceConfigHost @@ -207,10 +216,7 @@ class InfraTCPServiceConfig(BaseModel): tcp_port: Optional[int] = None tls_settings: Optional[InfraTCPServiceConfigTLSSettings] = None - """TLS settings for a connectivity service. - - If omitted, the default mode (`verify_full`) is used. - """ + """TLS settings for a connectivity service.""" updated_at: Optional[datetime] = None diff --git a/src/cloudflare/types/connectivity/directory/service_list_response.py b/src/cloudflare/types/connectivity/directory/service_list_response.py index d7fb719b586..5624a354adb 100644 --- a/src/cloudflare/types/connectivity/directory/service_list_response.py +++ b/src/cloudflare/types/connectivity/directory/service_list_response.py @@ -86,10 +86,7 @@ class InfraHTTPServiceConfigHostInfraHostnameHost(BaseModel): class InfraHTTPServiceConfigTLSSettings(BaseModel): - """TLS settings for a connectivity service. - - If omitted, the default mode (`verify_full`) is used. - """ + """TLS settings for a connectivity service.""" cert_verification_mode: str """TLS certificate verification mode for the connection to the origin. @@ -97,8 +94,17 @@ class InfraHTTPServiceConfigTLSSettings(BaseModel): - `"verify_full"` — verify certificate chain and hostname (default) - `"verify_ca"` — verify certificate chain only, skip hostname check - `"disabled"` — do not verify the server certificate at all + + `disabled` cannot be combined with `certificate_authority`: a custom CA is only + used to verify the server certificate. """ + certificate_authority: Optional[str] = None + """UUID of the custom CA certificate or chain.""" + + client_certificate: Optional[str] = None + """UUID of the mTLS client certificate and private key.""" + class InfraHTTPServiceConfig(BaseModel): host: InfraHTTPServiceConfigHost @@ -116,10 +122,7 @@ class InfraHTTPServiceConfig(BaseModel): service_id: Optional[str] = None tls_settings: Optional[InfraHTTPServiceConfigTLSSettings] = None - """TLS settings for a connectivity service. - - If omitted, the default mode (`verify_full`) is used. - """ + """TLS settings for a connectivity service.""" updated_at: Optional[datetime] = None @@ -177,10 +180,7 @@ class InfraTCPServiceConfigHostInfraHostnameHost(BaseModel): class InfraTCPServiceConfigTLSSettings(BaseModel): - """TLS settings for a connectivity service. - - If omitted, the default mode (`verify_full`) is used. - """ + """TLS settings for a connectivity service.""" cert_verification_mode: str """TLS certificate verification mode for the connection to the origin. @@ -188,8 +188,17 @@ class InfraTCPServiceConfigTLSSettings(BaseModel): - `"verify_full"` — verify certificate chain and hostname (default) - `"verify_ca"` — verify certificate chain only, skip hostname check - `"disabled"` — do not verify the server certificate at all + + `disabled` cannot be combined with `certificate_authority`: a custom CA is only + used to verify the server certificate. """ + certificate_authority: Optional[str] = None + """UUID of the custom CA certificate or chain.""" + + client_certificate: Optional[str] = None + """UUID of the mTLS client certificate and private key.""" + class InfraTCPServiceConfig(BaseModel): host: InfraTCPServiceConfigHost @@ -207,10 +216,7 @@ class InfraTCPServiceConfig(BaseModel): tcp_port: Optional[int] = None tls_settings: Optional[InfraTCPServiceConfigTLSSettings] = None - """TLS settings for a connectivity service. - - If omitted, the default mode (`verify_full`) is used. - """ + """TLS settings for a connectivity service.""" updated_at: Optional[datetime] = None diff --git a/src/cloudflare/types/connectivity/directory/service_update_params.py b/src/cloudflare/types/connectivity/directory/service_update_params.py index b53bbdf393e..5cedd48334b 100644 --- a/src/cloudflare/types/connectivity/directory/service_update_params.py +++ b/src/cloudflare/types/connectivity/directory/service_update_params.py @@ -48,10 +48,7 @@ class InfraHTTPServiceConfig(TypedDict, total=False): https_port: Optional[int] tls_settings: Optional[InfraHTTPServiceConfigTLSSettings] - """TLS settings for a connectivity service. - - If omitted, the default mode (`verify_full`) is used. - """ + """TLS settings for a connectivity service.""" class InfraHTTPServiceConfigHostInfraIPv4HostNetwork(TypedDict, total=False): @@ -107,10 +104,7 @@ class InfraHTTPServiceConfigHostInfraHostnameHost(TypedDict, total=False): class InfraHTTPServiceConfigTLSSettings(TypedDict, total=False): - """TLS settings for a connectivity service. - - If omitted, the default mode (`verify_full`) is used. - """ + """TLS settings for a connectivity service.""" cert_verification_mode: Required[str] """TLS certificate verification mode for the connection to the origin. @@ -118,8 +112,17 @@ class InfraHTTPServiceConfigTLSSettings(TypedDict, total=False): - `"verify_full"` — verify certificate chain and hostname (default) - `"verify_ca"` — verify certificate chain only, skip hostname check - `"disabled"` — do not verify the server certificate at all + + `disabled` cannot be combined with `certificate_authority`: a custom CA is only + used to verify the server certificate. """ + certificate_authority: Optional[str] + """UUID of the custom CA certificate or chain.""" + + client_certificate: Optional[str] + """UUID of the mTLS client certificate and private key.""" + class InfraTCPServiceConfig(TypedDict, total=False): account_id: Required[str] @@ -135,10 +138,7 @@ class InfraTCPServiceConfig(TypedDict, total=False): tcp_port: Optional[int] tls_settings: Optional[InfraTCPServiceConfigTLSSettings] - """TLS settings for a connectivity service. - - If omitted, the default mode (`verify_full`) is used. - """ + """TLS settings for a connectivity service.""" class InfraTCPServiceConfigHostInfraIPv4HostNetwork(TypedDict, total=False): @@ -194,10 +194,7 @@ class InfraTCPServiceConfigHostInfraHostnameHost(TypedDict, total=False): class InfraTCPServiceConfigTLSSettings(TypedDict, total=False): - """TLS settings for a connectivity service. - - If omitted, the default mode (`verify_full`) is used. - """ + """TLS settings for a connectivity service.""" cert_verification_mode: Required[str] """TLS certificate verification mode for the connection to the origin. @@ -205,7 +202,16 @@ class InfraTCPServiceConfigTLSSettings(TypedDict, total=False): - `"verify_full"` — verify certificate chain and hostname (default) - `"verify_ca"` — verify certificate chain only, skip hostname check - `"disabled"` — do not verify the server certificate at all + + `disabled` cannot be combined with `certificate_authority`: a custom CA is only + used to verify the server certificate. """ + certificate_authority: Optional[str] + """UUID of the custom CA certificate or chain.""" + + client_certificate: Optional[str] + """UUID of the mTLS client certificate and private key.""" + ServiceUpdateParams: TypeAlias = Union[InfraHTTPServiceConfig, InfraTCPServiceConfig] diff --git a/src/cloudflare/types/connectivity/directory/service_update_response.py b/src/cloudflare/types/connectivity/directory/service_update_response.py index 35234c6a9af..3f6a4a1f8be 100644 --- a/src/cloudflare/types/connectivity/directory/service_update_response.py +++ b/src/cloudflare/types/connectivity/directory/service_update_response.py @@ -86,10 +86,7 @@ class InfraHTTPServiceConfigHostInfraHostnameHost(BaseModel): class InfraHTTPServiceConfigTLSSettings(BaseModel): - """TLS settings for a connectivity service. - - If omitted, the default mode (`verify_full`) is used. - """ + """TLS settings for a connectivity service.""" cert_verification_mode: str """TLS certificate verification mode for the connection to the origin. @@ -97,8 +94,17 @@ class InfraHTTPServiceConfigTLSSettings(BaseModel): - `"verify_full"` — verify certificate chain and hostname (default) - `"verify_ca"` — verify certificate chain only, skip hostname check - `"disabled"` — do not verify the server certificate at all + + `disabled` cannot be combined with `certificate_authority`: a custom CA is only + used to verify the server certificate. """ + certificate_authority: Optional[str] = None + """UUID of the custom CA certificate or chain.""" + + client_certificate: Optional[str] = None + """UUID of the mTLS client certificate and private key.""" + class InfraHTTPServiceConfig(BaseModel): host: InfraHTTPServiceConfigHost @@ -116,10 +122,7 @@ class InfraHTTPServiceConfig(BaseModel): service_id: Optional[str] = None tls_settings: Optional[InfraHTTPServiceConfigTLSSettings] = None - """TLS settings for a connectivity service. - - If omitted, the default mode (`verify_full`) is used. - """ + """TLS settings for a connectivity service.""" updated_at: Optional[datetime] = None @@ -177,10 +180,7 @@ class InfraTCPServiceConfigHostInfraHostnameHost(BaseModel): class InfraTCPServiceConfigTLSSettings(BaseModel): - """TLS settings for a connectivity service. - - If omitted, the default mode (`verify_full`) is used. - """ + """TLS settings for a connectivity service.""" cert_verification_mode: str """TLS certificate verification mode for the connection to the origin. @@ -188,8 +188,17 @@ class InfraTCPServiceConfigTLSSettings(BaseModel): - `"verify_full"` — verify certificate chain and hostname (default) - `"verify_ca"` — verify certificate chain only, skip hostname check - `"disabled"` — do not verify the server certificate at all + + `disabled` cannot be combined with `certificate_authority`: a custom CA is only + used to verify the server certificate. """ + certificate_authority: Optional[str] = None + """UUID of the custom CA certificate or chain.""" + + client_certificate: Optional[str] = None + """UUID of the mTLS client certificate and private key.""" + class InfraTCPServiceConfig(BaseModel): host: InfraTCPServiceConfigHost @@ -207,10 +216,7 @@ class InfraTCPServiceConfig(BaseModel): tcp_port: Optional[int] = None tls_settings: Optional[InfraTCPServiceConfigTLSSettings] = None - """TLS settings for a connectivity service. - - If omitted, the default mode (`verify_full`) is used. - """ + """TLS settings for a connectivity service.""" updated_at: Optional[datetime] = None diff --git a/src/cloudflare/types/containers/application_create_params.py b/src/cloudflare/types/containers/application_create_params.py index 9692d15c68c..3efcfc2c2df 100644 --- a/src/cloudflare/types/containers/application_create_params.py +++ b/src/cloudflare/types/containers/application_create_params.py @@ -28,6 +28,7 @@ "CcContainersCreateDurableObjectApplicationRequestConfiguration", "CcContainersCreateDurableObjectApplicationRequestConfigurationAuthorizedKey", "CcContainersCreateDurableObjectApplicationRequestConfigurationWranglerSSH", + "CcContainersCreateDurableObjectApplicationRequestConstraints", "CcContainersCreateDurableObjectApplicationRequestObservability", "CcContainersCreateDurableObjectApplicationRequestObservabilityLogs", ] @@ -229,6 +230,13 @@ class CcContainersCreateDurableObjectApplicationRequest(TypedDict, total=False): configuration: CcContainersCreateDurableObjectApplicationRequestConfiguration """Configuration for a Durable Object-managed application.""" + constraints: CcContainersCreateDurableObjectApplicationRequestConstraints + """ + The jurisdiction of a Durable Object-managed application's primary control-plane + object. Set this when creating the application; it cannot be changed afterwards. + Other placement constraints are not supported by this scheduling policy. + """ + observability: CcContainersCreateDurableObjectApplicationRequestObservability """ Application-wide logging settings for a Durable Object-managed application. The @@ -291,6 +299,16 @@ class CcContainersCreateDurableObjectApplicationRequestConfiguration(TypedDict, """Configuration properties for connecting with SSH to a container using Wrangler.""" +class CcContainersCreateDurableObjectApplicationRequestConstraints(TypedDict, total=False): + """ + The jurisdiction of a Durable Object-managed application's primary control-plane object. + Set this when creating the application; it cannot be changed afterwards. + Other placement constraints are not supported by this scheduling policy. + """ + + jurisdiction: Required[Literal["eu", "fedramp", "us"]] + + class CcContainersCreateDurableObjectApplicationRequestObservabilityLogs(TypedDict, total=False): """Application-wide logging settings.""" diff --git a/src/cloudflare/types/containers/application_create_response.py b/src/cloudflare/types/containers/application_create_response.py index 316081cf402..12022ebea98 100644 --- a/src/cloudflare/types/containers/application_create_response.py +++ b/src/cloudflare/types/containers/application_create_response.py @@ -28,6 +28,7 @@ "CcDurableObjectApplicationConfiguration", "CcDurableObjectApplicationConfigurationAuthorizedKey", "CcDurableObjectApplicationConfigurationWranglerSSH", + "CcDurableObjectApplicationConstraints", "CcDurableObjectApplicationHealth", "CcDurableObjectApplicationHealthInstances", "CcDurableObjectApplicationObservability", @@ -362,6 +363,16 @@ class CcDurableObjectApplicationConfiguration(BaseModel): """Configuration properties for connecting with SSH to a container using Wrangler.""" +class CcDurableObjectApplicationConstraints(BaseModel): + """ + The jurisdiction of a Durable Object-managed application's primary control-plane object. + Set this when creating the application; it cannot be changed afterwards. + Other placement constraints are not supported by this scheduling policy. + """ + + jurisdiction: Literal["eu", "fedramp", "us"] + + class CcDurableObjectApplicationHealthInstances(BaseModel): """Counts of observed non-terminal instances.""" @@ -439,6 +450,13 @@ class CcDurableObjectApplication(BaseModel): configuration: Optional[CcDurableObjectApplicationConfiguration] = None """Application-wide settings for a Durable Object-managed application.""" + constraints: Optional[CcDurableObjectApplicationConstraints] = None + """ + The jurisdiction of a Durable Object-managed application's primary control-plane + object. Set this when creating the application; it cannot be changed afterwards. + Other placement constraints are not supported by this scheduling policy. + """ + health: Optional[CcDurableObjectApplicationHealth] = None """ Aggregate current activity for the latest observed placement of each instance. diff --git a/src/cloudflare/types/containers/application_edit_response.py b/src/cloudflare/types/containers/application_edit_response.py index bd13ca73be1..fd7f704887a 100644 --- a/src/cloudflare/types/containers/application_edit_response.py +++ b/src/cloudflare/types/containers/application_edit_response.py @@ -28,6 +28,7 @@ "CcDurableObjectApplicationConfiguration", "CcDurableObjectApplicationConfigurationAuthorizedKey", "CcDurableObjectApplicationConfigurationWranglerSSH", + "CcDurableObjectApplicationConstraints", "CcDurableObjectApplicationHealth", "CcDurableObjectApplicationHealthInstances", "CcDurableObjectApplicationObservability", @@ -362,6 +363,16 @@ class CcDurableObjectApplicationConfiguration(BaseModel): """Configuration properties for connecting with SSH to a container using Wrangler.""" +class CcDurableObjectApplicationConstraints(BaseModel): + """ + The jurisdiction of a Durable Object-managed application's primary control-plane object. + Set this when creating the application; it cannot be changed afterwards. + Other placement constraints are not supported by this scheduling policy. + """ + + jurisdiction: Literal["eu", "fedramp", "us"] + + class CcDurableObjectApplicationHealthInstances(BaseModel): """Counts of observed non-terminal instances.""" @@ -439,6 +450,13 @@ class CcDurableObjectApplication(BaseModel): configuration: Optional[CcDurableObjectApplicationConfiguration] = None """Application-wide settings for a Durable Object-managed application.""" + constraints: Optional[CcDurableObjectApplicationConstraints] = None + """ + The jurisdiction of a Durable Object-managed application's primary control-plane + object. Set this when creating the application; it cannot be changed afterwards. + Other placement constraints are not supported by this scheduling policy. + """ + health: Optional[CcDurableObjectApplicationHealth] = None """ Aggregate current activity for the latest observed placement of each instance. diff --git a/src/cloudflare/types/containers/application_get_response.py b/src/cloudflare/types/containers/application_get_response.py index 32be4befb8d..2f95f02341f 100644 --- a/src/cloudflare/types/containers/application_get_response.py +++ b/src/cloudflare/types/containers/application_get_response.py @@ -28,6 +28,7 @@ "CcDurableObjectApplicationConfiguration", "CcDurableObjectApplicationConfigurationAuthorizedKey", "CcDurableObjectApplicationConfigurationWranglerSSH", + "CcDurableObjectApplicationConstraints", "CcDurableObjectApplicationHealth", "CcDurableObjectApplicationHealthInstances", "CcDurableObjectApplicationObservability", @@ -362,6 +363,16 @@ class CcDurableObjectApplicationConfiguration(BaseModel): """Configuration properties for connecting with SSH to a container using Wrangler.""" +class CcDurableObjectApplicationConstraints(BaseModel): + """ + The jurisdiction of a Durable Object-managed application's primary control-plane object. + Set this when creating the application; it cannot be changed afterwards. + Other placement constraints are not supported by this scheduling policy. + """ + + jurisdiction: Literal["eu", "fedramp", "us"] + + class CcDurableObjectApplicationHealthInstances(BaseModel): """Counts of observed non-terminal instances.""" @@ -439,6 +450,13 @@ class CcDurableObjectApplication(BaseModel): configuration: Optional[CcDurableObjectApplicationConfiguration] = None """Application-wide settings for a Durable Object-managed application.""" + constraints: Optional[CcDurableObjectApplicationConstraints] = None + """ + The jurisdiction of a Durable Object-managed application's primary control-plane + object. Set this when creating the application; it cannot be changed afterwards. + Other placement constraints are not supported by this scheduling policy. + """ + health: Optional[CcDurableObjectApplicationHealth] = None """ Aggregate current activity for the latest observed placement of each instance. diff --git a/src/cloudflare/types/containers/application_list_response.py b/src/cloudflare/types/containers/application_list_response.py index bb2bddafd6b..892544c48c7 100644 --- a/src/cloudflare/types/containers/application_list_response.py +++ b/src/cloudflare/types/containers/application_list_response.py @@ -28,6 +28,7 @@ "CcDurableObjectApplicationConfiguration", "CcDurableObjectApplicationConfigurationAuthorizedKey", "CcDurableObjectApplicationConfigurationWranglerSSH", + "CcDurableObjectApplicationConstraints", "CcDurableObjectApplicationHealth", "CcDurableObjectApplicationHealthInstances", "CcDurableObjectApplicationObservability", @@ -362,6 +363,16 @@ class CcDurableObjectApplicationConfiguration(BaseModel): """Configuration properties for connecting with SSH to a container using Wrangler.""" +class CcDurableObjectApplicationConstraints(BaseModel): + """ + The jurisdiction of a Durable Object-managed application's primary control-plane object. + Set this when creating the application; it cannot be changed afterwards. + Other placement constraints are not supported by this scheduling policy. + """ + + jurisdiction: Literal["eu", "fedramp", "us"] + + class CcDurableObjectApplicationHealthInstances(BaseModel): """Counts of observed non-terminal instances.""" @@ -439,6 +450,13 @@ class CcDurableObjectApplication(BaseModel): configuration: Optional[CcDurableObjectApplicationConfiguration] = None """Application-wide settings for a Durable Object-managed application.""" + constraints: Optional[CcDurableObjectApplicationConstraints] = None + """ + The jurisdiction of a Durable Object-managed application's primary control-plane + object. Set this when creating the application; it cannot be changed afterwards. + Other placement constraints are not supported by this scheduling policy. + """ + health: Optional[CcDurableObjectApplicationHealth] = None """ Aggregate current activity for the latest observed placement of each instance. diff --git a/src/cloudflare/types/d1/__init__.py b/src/cloudflare/types/d1/__init__.py index 1d5002ba295..c2f442fcfd2 100644 --- a/src/cloudflare/types/d1/__init__.py +++ b/src/cloudflare/types/d1/__init__.py @@ -17,3 +17,4 @@ from .database_update_params import DatabaseUpdateParams as DatabaseUpdateParams from .database_export_response import DatabaseExportResponse as DatabaseExportResponse from .database_import_response import DatabaseImportResponse as DatabaseImportResponse +from .database_undelete_params import DatabaseUndeleteParams as DatabaseUndeleteParams diff --git a/src/cloudflare/types/d1/database_export_params.py b/src/cloudflare/types/d1/database_export_params.py index cfe21f17154..83c6fe2f924 100644 --- a/src/cloudflare/types/d1/database_export_params.py +++ b/src/cloudflare/types/d1/database_export_params.py @@ -26,6 +26,14 @@ class DatabaseExportParams(TypedDict, total=False): class DumpOptions(TypedDict, total=False): + compatibility: Literal["d1", "sqlite3_cli_only"] + """Dump format. + + `d1` (the default) gives a dump that D1 can import. `sqlite3_cli_only` matches + the output of the `sqlite3 .dump` command, including virtual tables such as FTS5 + or R\\**Tree tables, but cannot be imported back into D1. + """ + no_data: bool """Export only the table definitions, not their contents""" diff --git a/src/cloudflare/types/d1/database_undelete_params.py b/src/cloudflare/types/d1/database_undelete_params.py new file mode 100644 index 00000000000..c6fd3963096 --- /dev/null +++ b/src/cloudflare/types/d1/database_undelete_params.py @@ -0,0 +1,18 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Required, TypedDict + +__all__ = ["DatabaseUndeleteParams"] + + +class DatabaseUndeleteParams(TypedDict, total=False): + account_id: Required[str] + """Account identifier tag.""" + + new_name: str + """ + Restore the database with this name instead of the name it had when it was + deleted. Required if another database in the account already uses that name. + """ diff --git a/src/cloudflare/types/dls/regional_services/prefix_binding_delete_response.py b/src/cloudflare/types/dls/regional_services/prefix_binding_delete_response.py index 240528ac347..8f2d202359f 100644 --- a/src/cloudflare/types/dls/regional_services/prefix_binding_delete_response.py +++ b/src/cloudflare/types/dls/regional_services/prefix_binding_delete_response.py @@ -3,14 +3,37 @@ from typing import List, Optional from ...._models import BaseModel -from ...shared.response_info import ResponseInfo -__all__ = ["PrefixBindingDeleteResponse"] +__all__ = ["PrefixBindingDeleteResponse", "Message", "Error"] + + +class Message(BaseModel): + code: int + + message: str + + error_chain: Optional[List[object]] = None + """ + Optional upstream error context for APIv4 errors that wrap downstream service + failures. + """ + + +class Error(BaseModel): + code: int + + message: str + + error_chain: Optional[List[object]] = None + """ + Optional upstream error context for APIv4 errors that wrap downstream service + failures. + """ class PrefixBindingDeleteResponse(BaseModel): - messages: List[ResponseInfo] + messages: List[Message] success: bool - errors: Optional[List[ResponseInfo]] = None + errors: Optional[List[Error]] = None diff --git a/src/cloudflare/types/dns/record_list_params.py b/src/cloudflare/types/dns/record_list_params.py index 0e6b1489f11..885b11cc5f0 100644 --- a/src/cloudflare/types/dns/record_list_params.py +++ b/src/cloudflare/types/dns/record_list_params.py @@ -62,11 +62,12 @@ class RecordListParams(TypedDict, total=False): """ shadowed_by_name: str - """ - Filters to records at or below the given NS delegation name, excluding the NS - records that form the delegation itself. The value must be a subdomain of the - zone; the zone apex is not accepted. Requires `include_shadow_metadata=true`. - See + """Filters the response to records at or below the specified NS delegation name. + + NS, DS, and NSEC records at the delegation name are excluded because they are + not shadowed by that delegation. Those record types are included only when they + exist below the delegation. The value must be a non-apex subdomain of the zone. + Requires `include_shadow_metadata=true`. See [Shadowed records](https://developers.cloudflare.com/dns/manage-dns-records/reference/shadowed-records). """ diff --git a/src/cloudflare/types/dns/settings/account/__init__.py b/src/cloudflare/types/dns/settings/account/__init__.py index f0f5e0851cc..a544086cdd9 100644 --- a/src/cloudflare/types/dns/settings/account/__init__.py +++ b/src/cloudflare/types/dns/settings/account/__init__.py @@ -10,3 +10,9 @@ from .view_list_response import ViewListResponse as ViewListResponse from .view_create_response import ViewCreateResponse as ViewCreateResponse from .view_delete_response import ViewDeleteResponse as ViewDeleteResponse +from .nameserver_set_list_params import NameserverSetListParams as NameserverSetListParams +from .nameserver_set_get_response import NameserverSetGetResponse as NameserverSetGetResponse +from .nameserver_set_create_params import NameserverSetCreateParams as NameserverSetCreateParams +from .nameserver_set_list_response import NameserverSetListResponse as NameserverSetListResponse +from .nameserver_set_create_response import NameserverSetCreateResponse as NameserverSetCreateResponse +from .nameserver_set_delete_response import NameserverSetDeleteResponse as NameserverSetDeleteResponse diff --git a/src/cloudflare/types/dns/settings/account/nameserver_set_create_params.py b/src/cloudflare/types/dns/settings/account/nameserver_set_create_params.py new file mode 100644 index 00000000000..8f48f91e5bd --- /dev/null +++ b/src/cloudflare/types/dns/settings/account/nameserver_set_create_params.py @@ -0,0 +1,50 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Iterable +from typing_extensions import Required, TypedDict + +__all__ = ["NameserverSetCreateParams", "Nameserver"] + + +class NameserverSetCreateParams(TypedDict, total=False): + account_id: Required[str] + """Identifier.""" + + name: Required[str] + """ + Customer-defined name, unique within the account by exact string equality + (case-sensitive, with no Unicode normalization). Must be valid UTF-8 and at most + 255 UTF-8 bytes, not 255 characters. Only graphical Unicode characters are + allowed; leading or trailing whitespace is rejected. The name can be changed + without changing the set's nameservers or addresses. + """ + + nameservers: Required[Iterable[Nameserver]] + """Lists each nameserver and the number of addresses to allocate to it. + + Requires a unique name for each entry in the set. + """ + + advanced: bool + """Whether to allocate the nameservers from distinct Advanced anycast groups.""" + + ip_set: int + """Selects the account-specific IP set that supplies the nameserver addresses. + + Nameserver sets with the same `ip_set` and `advanced` value may reuse addresses; + otherwise, they use disjoint address groups. + """ + + +class Nameserver(TypedDict, total=False): + name: Required[str] + """A unique lowercase Punycode nameserver name within the set.""" + + ip_count: int + """ + Number of IPv4 addresses and number of IPv6 addresses to allocate to this + nameserver. All nameservers in an Advanced nameserver set must use the same + value. + """ diff --git a/src/cloudflare/types/dns/settings/account/nameserver_set_create_response.py b/src/cloudflare/types/dns/settings/account/nameserver_set_create_response.py new file mode 100644 index 00000000000..ca5abd5903c --- /dev/null +++ b/src/cloudflare/types/dns/settings/account/nameserver_set_create_response.py @@ -0,0 +1,112 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Union +from datetime import datetime +from typing_extensions import Literal, TypeAlias + +from ....._models import BaseModel + +__all__ = [ + "NameserverSetCreateResponse", + "DNSSettingsNameserverSetStandardResponse", + "DNSSettingsNameserverSetStandardResponseNameserver", + "DNSSettingsNameserverSetAdvancedResponse", + "DNSSettingsNameserverSetAdvancedResponseNameserver", +] + + +class DNSSettingsNameserverSetStandardResponseNameserver(BaseModel): + ipv4: List[str] + """IPv4 addresses assigned to the nameserver.""" + + ipv6: List[str] + """IPv6 addresses assigned to the nameserver.""" + + name: str + """A unique lowercase Punycode nameserver name within the set.""" + + +class DNSSettingsNameserverSetStandardResponse(BaseModel): + id: str + """Identifier for a nameserver set.""" + + advanced: Literal[False] + """Whether the nameserver set uses Advanced anycast groups.""" + + created_on: datetime + """When the nameserver set was created.""" + + ip_set: int + """Selects the account-specific IP set that supplies the nameserver addresses. + + Nameserver sets with the same `ip_set` and `advanced` value may reuse addresses; + otherwise, they use disjoint address groups. + """ + + name: str + """ + Customer-defined name, unique within the account by exact string equality + (case-sensitive, with no Unicode normalization). Must be valid UTF-8 and at most + 255 UTF-8 bytes, not 255 characters. Only graphical Unicode characters are + allowed; leading or trailing whitespace is rejected. The name can be changed + without changing the set's nameservers or addresses. + """ + + nameservers: List[DNSSettingsNameserverSetStandardResponseNameserver] + + +class DNSSettingsNameserverSetAdvancedResponseNameserver(BaseModel): + ipv4: List[str] + """IPv4 addresses assigned to the nameserver.""" + + ipv4_groups: List[Literal["a", "b", "c"]] + """Advanced anycast group for each address in the corresponding address array. + + Entries have the same order as, and correspond one-to-one with, the addresses. + """ + + ipv6: List[str] + """IPv6 addresses assigned to the nameserver.""" + + ipv6_groups: List[Literal["a", "b", "c"]] + """Advanced anycast group for each address in the corresponding address array. + + Entries have the same order as, and correspond one-to-one with, the addresses. + """ + + name: str + """A unique lowercase Punycode nameserver name within the set.""" + + +class DNSSettingsNameserverSetAdvancedResponse(BaseModel): + id: str + """Identifier for a nameserver set.""" + + advanced: Literal[True] + """Whether the nameserver set uses Advanced anycast groups.""" + + created_on: datetime + """When the nameserver set was created.""" + + ip_set: int + """Selects the account-specific IP set that supplies the nameserver addresses. + + Nameserver sets with the same `ip_set` and `advanced` value may reuse addresses; + otherwise, they use disjoint address groups. + """ + + name: str + """ + Customer-defined name, unique within the account by exact string equality + (case-sensitive, with no Unicode normalization). Must be valid UTF-8 and at most + 255 UTF-8 bytes, not 255 characters. Only graphical Unicode characters are + allowed; leading or trailing whitespace is rejected. The name can be changed + without changing the set's nameservers or addresses. + """ + + nameservers: List[DNSSettingsNameserverSetAdvancedResponseNameserver] + + +NameserverSetCreateResponse: TypeAlias = Union[ + DNSSettingsNameserverSetStandardResponse, DNSSettingsNameserverSetAdvancedResponse +] diff --git a/src/cloudflare/types/dns/settings/account/nameserver_set_delete_response.py b/src/cloudflare/types/dns/settings/account/nameserver_set_delete_response.py new file mode 100644 index 00000000000..d8269d207bd --- /dev/null +++ b/src/cloudflare/types/dns/settings/account/nameserver_set_delete_response.py @@ -0,0 +1,10 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from ....._models import BaseModel + +__all__ = ["NameserverSetDeleteResponse"] + + +class NameserverSetDeleteResponse(BaseModel): + id: str + """Identifier for a nameserver set.""" diff --git a/src/cloudflare/types/dns/settings/account/nameserver_set_get_response.py b/src/cloudflare/types/dns/settings/account/nameserver_set_get_response.py new file mode 100644 index 00000000000..9c3e6e96bde --- /dev/null +++ b/src/cloudflare/types/dns/settings/account/nameserver_set_get_response.py @@ -0,0 +1,112 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Union +from datetime import datetime +from typing_extensions import Literal, TypeAlias + +from ....._models import BaseModel + +__all__ = [ + "NameserverSetGetResponse", + "DNSSettingsNameserverSetStandardResponse", + "DNSSettingsNameserverSetStandardResponseNameserver", + "DNSSettingsNameserverSetAdvancedResponse", + "DNSSettingsNameserverSetAdvancedResponseNameserver", +] + + +class DNSSettingsNameserverSetStandardResponseNameserver(BaseModel): + ipv4: List[str] + """IPv4 addresses assigned to the nameserver.""" + + ipv6: List[str] + """IPv6 addresses assigned to the nameserver.""" + + name: str + """A unique lowercase Punycode nameserver name within the set.""" + + +class DNSSettingsNameserverSetStandardResponse(BaseModel): + id: str + """Identifier for a nameserver set.""" + + advanced: Literal[False] + """Whether the nameserver set uses Advanced anycast groups.""" + + created_on: datetime + """When the nameserver set was created.""" + + ip_set: int + """Selects the account-specific IP set that supplies the nameserver addresses. + + Nameserver sets with the same `ip_set` and `advanced` value may reuse addresses; + otherwise, they use disjoint address groups. + """ + + name: str + """ + Customer-defined name, unique within the account by exact string equality + (case-sensitive, with no Unicode normalization). Must be valid UTF-8 and at most + 255 UTF-8 bytes, not 255 characters. Only graphical Unicode characters are + allowed; leading or trailing whitespace is rejected. The name can be changed + without changing the set's nameservers or addresses. + """ + + nameservers: List[DNSSettingsNameserverSetStandardResponseNameserver] + + +class DNSSettingsNameserverSetAdvancedResponseNameserver(BaseModel): + ipv4: List[str] + """IPv4 addresses assigned to the nameserver.""" + + ipv4_groups: List[Literal["a", "b", "c"]] + """Advanced anycast group for each address in the corresponding address array. + + Entries have the same order as, and correspond one-to-one with, the addresses. + """ + + ipv6: List[str] + """IPv6 addresses assigned to the nameserver.""" + + ipv6_groups: List[Literal["a", "b", "c"]] + """Advanced anycast group for each address in the corresponding address array. + + Entries have the same order as, and correspond one-to-one with, the addresses. + """ + + name: str + """A unique lowercase Punycode nameserver name within the set.""" + + +class DNSSettingsNameserverSetAdvancedResponse(BaseModel): + id: str + """Identifier for a nameserver set.""" + + advanced: Literal[True] + """Whether the nameserver set uses Advanced anycast groups.""" + + created_on: datetime + """When the nameserver set was created.""" + + ip_set: int + """Selects the account-specific IP set that supplies the nameserver addresses. + + Nameserver sets with the same `ip_set` and `advanced` value may reuse addresses; + otherwise, they use disjoint address groups. + """ + + name: str + """ + Customer-defined name, unique within the account by exact string equality + (case-sensitive, with no Unicode normalization). Must be valid UTF-8 and at most + 255 UTF-8 bytes, not 255 characters. Only graphical Unicode characters are + allowed; leading or trailing whitespace is rejected. The name can be changed + without changing the set's nameservers or addresses. + """ + + nameservers: List[DNSSettingsNameserverSetAdvancedResponseNameserver] + + +NameserverSetGetResponse: TypeAlias = Union[ + DNSSettingsNameserverSetStandardResponse, DNSSettingsNameserverSetAdvancedResponse +] diff --git a/src/cloudflare/types/dns/settings/account/nameserver_set_list_params.py b/src/cloudflare/types/dns/settings/account/nameserver_set_list_params.py new file mode 100644 index 00000000000..f870832f148 --- /dev/null +++ b/src/cloudflare/types/dns/settings/account/nameserver_set_list_params.py @@ -0,0 +1,18 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Required, TypedDict + +__all__ = ["NameserverSetListParams"] + + +class NameserverSetListParams(TypedDict, total=False): + account_id: Required[str] + """Identifier.""" + + page: int + """Page number of paginated results.""" + + per_page: int + """Number of results per page.""" diff --git a/src/cloudflare/types/dns/settings/account/nameserver_set_list_response.py b/src/cloudflare/types/dns/settings/account/nameserver_set_list_response.py new file mode 100644 index 00000000000..524c14c5700 --- /dev/null +++ b/src/cloudflare/types/dns/settings/account/nameserver_set_list_response.py @@ -0,0 +1,112 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Union +from datetime import datetime +from typing_extensions import Literal, TypeAlias + +from ....._models import BaseModel + +__all__ = [ + "NameserverSetListResponse", + "DNSSettingsNameserverSetStandardResponse", + "DNSSettingsNameserverSetStandardResponseNameserver", + "DNSSettingsNameserverSetAdvancedResponse", + "DNSSettingsNameserverSetAdvancedResponseNameserver", +] + + +class DNSSettingsNameserverSetStandardResponseNameserver(BaseModel): + ipv4: List[str] + """IPv4 addresses assigned to the nameserver.""" + + ipv6: List[str] + """IPv6 addresses assigned to the nameserver.""" + + name: str + """A unique lowercase Punycode nameserver name within the set.""" + + +class DNSSettingsNameserverSetStandardResponse(BaseModel): + id: str + """Identifier for a nameserver set.""" + + advanced: Literal[False] + """Whether the nameserver set uses Advanced anycast groups.""" + + created_on: datetime + """When the nameserver set was created.""" + + ip_set: int + """Selects the account-specific IP set that supplies the nameserver addresses. + + Nameserver sets with the same `ip_set` and `advanced` value may reuse addresses; + otherwise, they use disjoint address groups. + """ + + name: str + """ + Customer-defined name, unique within the account by exact string equality + (case-sensitive, with no Unicode normalization). Must be valid UTF-8 and at most + 255 UTF-8 bytes, not 255 characters. Only graphical Unicode characters are + allowed; leading or trailing whitespace is rejected. The name can be changed + without changing the set's nameservers or addresses. + """ + + nameservers: List[DNSSettingsNameserverSetStandardResponseNameserver] + + +class DNSSettingsNameserverSetAdvancedResponseNameserver(BaseModel): + ipv4: List[str] + """IPv4 addresses assigned to the nameserver.""" + + ipv4_groups: List[Literal["a", "b", "c"]] + """Advanced anycast group for each address in the corresponding address array. + + Entries have the same order as, and correspond one-to-one with, the addresses. + """ + + ipv6: List[str] + """IPv6 addresses assigned to the nameserver.""" + + ipv6_groups: List[Literal["a", "b", "c"]] + """Advanced anycast group for each address in the corresponding address array. + + Entries have the same order as, and correspond one-to-one with, the addresses. + """ + + name: str + """A unique lowercase Punycode nameserver name within the set.""" + + +class DNSSettingsNameserverSetAdvancedResponse(BaseModel): + id: str + """Identifier for a nameserver set.""" + + advanced: Literal[True] + """Whether the nameserver set uses Advanced anycast groups.""" + + created_on: datetime + """When the nameserver set was created.""" + + ip_set: int + """Selects the account-specific IP set that supplies the nameserver addresses. + + Nameserver sets with the same `ip_set` and `advanced` value may reuse addresses; + otherwise, they use disjoint address groups. + """ + + name: str + """ + Customer-defined name, unique within the account by exact string equality + (case-sensitive, with no Unicode normalization). Must be valid UTF-8 and at most + 255 UTF-8 bytes, not 255 characters. Only graphical Unicode characters are + allowed; leading or trailing whitespace is rejected. The name can be changed + without changing the set's nameservers or addresses. + """ + + nameservers: List[DNSSettingsNameserverSetAdvancedResponseNameserver] + + +NameserverSetListResponse: TypeAlias = Union[ + DNSSettingsNameserverSetStandardResponse, DNSSettingsNameserverSetAdvancedResponse +] diff --git a/src/cloudflare/types/email_security/investigate/bulk/message_list_response.py b/src/cloudflare/types/email_security/investigate/bulk/message_list_response.py index f6188b9aef4..932c27b3aa2 100644 --- a/src/cloudflare/types/email_security/investigate/bulk/message_list_response.py +++ b/src/cloudflare/types/email_security/investigate/bulk/message_list_response.py @@ -20,6 +20,7 @@ "MessageProperties", "MessageFinding", "MessageValidation", + "MessageValidationEmailSecurityValidation", ] @@ -159,7 +160,7 @@ class MessageFinding(BaseModel): value: Optional[str] = None -class MessageValidation(BaseModel): +class MessageValidationEmailSecurityValidation(BaseModel): comment: Optional[str] = None dkim: Optional[Literal["pass", "neutral", "fail", "error", "none"]] = None @@ -169,6 +170,9 @@ class MessageValidation(BaseModel): spf: Optional[Literal["pass", "neutral", "fail", "error", "none"]] = None +MessageValidation: TypeAlias = Union[MessageValidationEmailSecurityValidation, Optional[object]] + + class Message(BaseModel): id: str """Unique identifier for a message retrieved from investigation.""" diff --git a/src/cloudflare/types/email_security/investigate_get_response.py b/src/cloudflare/types/email_security/investigate_get_response.py index bd7974bd8f1..9f1663a43d9 100644 --- a/src/cloudflare/types/email_security/investigate_get_response.py +++ b/src/cloudflare/types/email_security/investigate_get_response.py @@ -1,14 +1,22 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import List, Optional +from typing import List, Union, Optional from datetime import datetime -from typing_extensions import Literal +from typing_extensions import Literal, TypeAlias from pydantic import Field as FieldInfo from ..._models import BaseModel -__all__ = ["InvestigateGetResponse", "ActionLog", "ActionLogProperties", "Properties", "Finding", "Validation"] +__all__ = [ + "InvestigateGetResponse", + "ActionLog", + "ActionLogProperties", + "Properties", + "Finding", + "Validation", + "ValidationEmailSecurityValidation", +] class ActionLogProperties(BaseModel): @@ -113,7 +121,7 @@ class Finding(BaseModel): value: Optional[str] = None -class Validation(BaseModel): +class ValidationEmailSecurityValidation(BaseModel): comment: Optional[str] = None dkim: Optional[Literal["pass", "neutral", "fail", "error", "none"]] = None @@ -123,6 +131,9 @@ class Validation(BaseModel): spf: Optional[Literal["pass", "neutral", "fail", "error", "none"]] = None +Validation: TypeAlias = Union[ValidationEmailSecurityValidation, Optional[object]] + + class InvestigateGetResponse(BaseModel): id: str """Unique identifier for a message retrieved from investigation.""" diff --git a/src/cloudflare/types/email_security/investigate_list_response.py b/src/cloudflare/types/email_security/investigate_list_response.py index 1a85bde31ae..75f15fc055f 100644 --- a/src/cloudflare/types/email_security/investigate_list_response.py +++ b/src/cloudflare/types/email_security/investigate_list_response.py @@ -1,14 +1,22 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import List, Optional +from typing import List, Union, Optional from datetime import datetime -from typing_extensions import Literal +from typing_extensions import Literal, TypeAlias from pydantic import Field as FieldInfo from ..._models import BaseModel -__all__ = ["InvestigateListResponse", "ActionLog", "ActionLogProperties", "Properties", "Finding", "Validation"] +__all__ = [ + "InvestigateListResponse", + "ActionLog", + "ActionLogProperties", + "Properties", + "Finding", + "Validation", + "ValidationEmailSecurityValidation", +] class ActionLogProperties(BaseModel): @@ -113,7 +121,7 @@ class Finding(BaseModel): value: Optional[str] = None -class Validation(BaseModel): +class ValidationEmailSecurityValidation(BaseModel): comment: Optional[str] = None dkim: Optional[Literal["pass", "neutral", "fail", "error", "none"]] = None @@ -123,6 +131,9 @@ class Validation(BaseModel): spf: Optional[Literal["pass", "neutral", "fail", "error", "none"]] = None +Validation: TypeAlias = Union[ValidationEmailSecurityValidation, Optional[object]] + + class InvestigateListResponse(BaseModel): id: str """Unique identifier for a message retrieved from investigation.""" diff --git a/src/cloudflare/types/email_security/settings/allow_policy_batch_params.py b/src/cloudflare/types/email_security/settings/allow_policy_batch_params.py index 6a992aa33cc..a37b5b04466 100644 --- a/src/cloudflare/types/email_security/settings/allow_policy_batch_params.py +++ b/src/cloudflare/types/email_security/settings/allow_policy_batch_params.py @@ -2,8 +2,11 @@ from __future__ import annotations -from typing import Iterable, Optional -from typing_extensions import Literal, Required, TypedDict +from typing import Union, Iterable, Optional +from datetime import datetime +from typing_extensions import Literal, Required, Annotated, TypedDict + +from ...._utils import PropertyInfo __all__ = ["AllowPolicyBatchParams", "Delete", "Patch", "Post", "Put"] @@ -41,6 +44,13 @@ class Patch(TypedDict, total=False): comments: Optional[str] + expires_at: Annotated[Union[str, datetime, None], PropertyInfo(format="iso8601")] + """Timestamp at which the policy expires. + + After this time, Email Security ignores the policy. The value must lie in the + future. Send `null` to clear the expiration. + """ + is_acceptable_sender: bool """ Exempts messages from this sender from Spam, Spoof and Bulk dispositions only; @@ -81,7 +91,8 @@ class Patch(TypedDict, total=False): plain IPv4 or IPv6 address or CIDR block for IP (e.g. `1.2.3.4`, `1.2.3.0/24`, `2606:4700:4700::1111`, or `2606:4700:4700::/48`); the API rejects private or unique-local, loopback, link-local, unspecified, and IPv4 broadcast addresses, - including their IPv4-mapped IPv6 equivalents. + including their IPv4-mapped IPv6 equivalents. The API also rejects a pattern + that equals a domain onboarded to the account, ignoring case. """ pattern_type: Literal["EMAIL", "DOMAIN", "IP", "UNKNOWN"] @@ -130,7 +141,8 @@ class Post(TypedDict, total=False): plain IPv4 or IPv6 address or CIDR block for IP (e.g. `1.2.3.4`, `1.2.3.0/24`, `2606:4700:4700::1111`, or `2606:4700:4700::/48`); the API rejects private or unique-local, loopback, link-local, unspecified, and IPv4 broadcast addresses, - including their IPv4-mapped IPv6 equivalents. + including their IPv4-mapped IPv6 equivalents. The API also rejects a pattern + that equals a domain onboarded to the account, ignoring case. """ pattern_type: Required[Literal["EMAIL", "DOMAIN", "IP", "UNKNOWN"]] @@ -155,6 +167,13 @@ class Post(TypedDict, total=False): comments: Optional[str] + expires_at: Annotated[Union[str, datetime, None], PropertyInfo(format="iso8601")] + """Timestamp at which the policy expires. + + After this time, Email Security ignores the policy. The value must lie in the + future. Send `null` to clear the expiration. + """ + is_recipient: bool """Deprecated as of July 1, 2025. @@ -179,6 +198,13 @@ class Put(TypedDict, total=False): comments: Optional[str] + expires_at: Annotated[Union[str, datetime, None], PropertyInfo(format="iso8601")] + """Timestamp at which the policy expires. + + After this time, Email Security ignores the policy. The value must lie in the + future. Send `null` to clear the expiration. + """ + is_acceptable_sender: bool """ Exempts messages from this sender from Spam, Spoof and Bulk dispositions only; @@ -219,7 +245,8 @@ class Put(TypedDict, total=False): plain IPv4 or IPv6 address or CIDR block for IP (e.g. `1.2.3.4`, `1.2.3.0/24`, `2606:4700:4700::1111`, or `2606:4700:4700::/48`); the API rejects private or unique-local, loopback, link-local, unspecified, and IPv4 broadcast addresses, - including their IPv4-mapped IPv6 equivalents. + including their IPv4-mapped IPv6 equivalents. The API also rejects a pattern + that equals a domain onboarded to the account, ignoring case. """ pattern_type: Literal["EMAIL", "DOMAIN", "IP", "UNKNOWN"] diff --git a/src/cloudflare/types/email_security/settings/allow_policy_batch_response.py b/src/cloudflare/types/email_security/settings/allow_policy_batch_response.py index 5e910952166..a1dd5e4e0ed 100644 --- a/src/cloudflare/types/email_security/settings/allow_policy_batch_response.py +++ b/src/cloudflare/types/email_security/settings/allow_policy_batch_response.py @@ -27,6 +27,13 @@ class Patch(BaseModel): comments: Optional[str] = None + expires_at: Optional[datetime] = None + """Timestamp at which the policy expires. + + After this time, Email Security ignores the policy. The value must lie in the + future. Send `null` to clear the expiration. + """ + is_acceptable_sender: Optional[bool] = None """ Exempts messages from this sender from Spam, Spoof and Bulk dispositions only; @@ -69,7 +76,8 @@ class Patch(BaseModel): plain IPv4 or IPv6 address or CIDR block for IP (e.g. `1.2.3.4`, `1.2.3.0/24`, `2606:4700:4700::1111`, or `2606:4700:4700::/48`); the API rejects private or unique-local, loopback, link-local, unspecified, and IPv4 broadcast addresses, - including their IPv4-mapped IPv6 equivalents. + including their IPv4-mapped IPv6 equivalents. The API also rejects a pattern + that equals a domain onboarded to the account, ignoring case. """ pattern_type: Optional[Literal["EMAIL", "DOMAIN", "IP", "UNKNOWN"]] = None @@ -106,6 +114,13 @@ class Post(BaseModel): comments: Optional[str] = None + expires_at: Optional[datetime] = None + """Timestamp at which the policy expires. + + After this time, Email Security ignores the policy. The value must lie in the + future. Send `null` to clear the expiration. + """ + is_acceptable_sender: Optional[bool] = None """ Exempts messages from this sender from Spam, Spoof and Bulk dispositions only; @@ -148,7 +163,8 @@ class Post(BaseModel): plain IPv4 or IPv6 address or CIDR block for IP (e.g. `1.2.3.4`, `1.2.3.0/24`, `2606:4700:4700::1111`, or `2606:4700:4700::/48`); the API rejects private or unique-local, loopback, link-local, unspecified, and IPv4 broadcast addresses, - including their IPv4-mapped IPv6 equivalents. + including their IPv4-mapped IPv6 equivalents. The API also rejects a pattern + that equals a domain onboarded to the account, ignoring case. """ pattern_type: Optional[Literal["EMAIL", "DOMAIN", "IP", "UNKNOWN"]] = None @@ -185,6 +201,13 @@ class Put(BaseModel): comments: Optional[str] = None + expires_at: Optional[datetime] = None + """Timestamp at which the policy expires. + + After this time, Email Security ignores the policy. The value must lie in the + future. Send `null` to clear the expiration. + """ + is_acceptable_sender: Optional[bool] = None """ Exempts messages from this sender from Spam, Spoof and Bulk dispositions only; @@ -227,7 +250,8 @@ class Put(BaseModel): plain IPv4 or IPv6 address or CIDR block for IP (e.g. `1.2.3.4`, `1.2.3.0/24`, `2606:4700:4700::1111`, or `2606:4700:4700::/48`); the API rejects private or unique-local, loopback, link-local, unspecified, and IPv4 broadcast addresses, - including their IPv4-mapped IPv6 equivalents. + including their IPv4-mapped IPv6 equivalents. The API also rejects a pattern + that equals a domain onboarded to the account, ignoring case. """ pattern_type: Optional[Literal["EMAIL", "DOMAIN", "IP", "UNKNOWN"]] = None diff --git a/src/cloudflare/types/email_security/settings/allow_policy_create_params.py b/src/cloudflare/types/email_security/settings/allow_policy_create_params.py index 724e9120d6d..a9ed65ac781 100644 --- a/src/cloudflare/types/email_security/settings/allow_policy_create_params.py +++ b/src/cloudflare/types/email_security/settings/allow_policy_create_params.py @@ -2,8 +2,11 @@ from __future__ import annotations -from typing import Optional -from typing_extensions import Literal, Required, TypedDict +from typing import Union, Optional +from datetime import datetime +from typing_extensions import Literal, Required, Annotated, TypedDict + +from ...._utils import PropertyInfo __all__ = ["AllowPolicyCreateParams"] @@ -34,7 +37,8 @@ class AllowPolicyCreateParams(TypedDict, total=False): plain IPv4 or IPv6 address or CIDR block for IP (e.g. `1.2.3.4`, `1.2.3.0/24`, `2606:4700:4700::1111`, or `2606:4700:4700::/48`); the API rejects private or unique-local, loopback, link-local, unspecified, and IPv4 broadcast addresses, - including their IPv4-mapped IPv6 equivalents. + including their IPv4-mapped IPv6 equivalents. The API also rejects a pattern + that equals a domain onboarded to the account, ignoring case. """ pattern_type: Required[Literal["EMAIL", "DOMAIN", "IP", "UNKNOWN"]] @@ -59,6 +63,13 @@ class AllowPolicyCreateParams(TypedDict, total=False): comments: Optional[str] + expires_at: Annotated[Union[str, datetime, None], PropertyInfo(format="iso8601")] + """Timestamp at which the policy expires. + + After this time, Email Security ignores the policy. The value must lie in the + future. Send `null` to clear the expiration. + """ + is_recipient: bool """Deprecated as of July 1, 2025. diff --git a/src/cloudflare/types/email_security/settings/allow_policy_create_response.py b/src/cloudflare/types/email_security/settings/allow_policy_create_response.py index 265dfeda4ec..97387cc964b 100644 --- a/src/cloudflare/types/email_security/settings/allow_policy_create_response.py +++ b/src/cloudflare/types/email_security/settings/allow_policy_create_response.py @@ -22,6 +22,13 @@ class AllowPolicyCreateResponse(BaseModel): comments: Optional[str] = None + expires_at: Optional[datetime] = None + """Timestamp at which the policy expires. + + After this time, Email Security ignores the policy. The value must lie in the + future. Send `null` to clear the expiration. + """ + is_acceptable_sender: Optional[bool] = None """ Exempts messages from this sender from Spam, Spoof and Bulk dispositions only; @@ -64,7 +71,8 @@ class AllowPolicyCreateResponse(BaseModel): plain IPv4 or IPv6 address or CIDR block for IP (e.g. `1.2.3.4`, `1.2.3.0/24`, `2606:4700:4700::1111`, or `2606:4700:4700::/48`); the API rejects private or unique-local, loopback, link-local, unspecified, and IPv4 broadcast addresses, - including their IPv4-mapped IPv6 equivalents. + including their IPv4-mapped IPv6 equivalents. The API also rejects a pattern + that equals a domain onboarded to the account, ignoring case. """ pattern_type: Optional[Literal["EMAIL", "DOMAIN", "IP", "UNKNOWN"]] = None diff --git a/src/cloudflare/types/email_security/settings/allow_policy_edit_params.py b/src/cloudflare/types/email_security/settings/allow_policy_edit_params.py index 48bc2de8118..55b84d61a3f 100644 --- a/src/cloudflare/types/email_security/settings/allow_policy_edit_params.py +++ b/src/cloudflare/types/email_security/settings/allow_policy_edit_params.py @@ -2,8 +2,11 @@ from __future__ import annotations -from typing import Optional -from typing_extensions import Literal, Required, TypedDict +from typing import Union, Optional +from datetime import datetime +from typing_extensions import Literal, Required, Annotated, TypedDict + +from ...._utils import PropertyInfo __all__ = ["AllowPolicyEditParams"] @@ -14,6 +17,13 @@ class AllowPolicyEditParams(TypedDict, total=False): comments: Optional[str] + expires_at: Annotated[Union[str, datetime, None], PropertyInfo(format="iso8601")] + """Timestamp at which the policy expires. + + After this time, Email Security ignores the policy. The value must lie in the + future. Send `null` to clear the expiration. + """ + is_acceptable_sender: bool """ Exempts messages from this sender from Spam, Spoof and Bulk dispositions only; @@ -54,7 +64,8 @@ class AllowPolicyEditParams(TypedDict, total=False): plain IPv4 or IPv6 address or CIDR block for IP (e.g. `1.2.3.4`, `1.2.3.0/24`, `2606:4700:4700::1111`, or `2606:4700:4700::/48`); the API rejects private or unique-local, loopback, link-local, unspecified, and IPv4 broadcast addresses, - including their IPv4-mapped IPv6 equivalents. + including their IPv4-mapped IPv6 equivalents. The API also rejects a pattern + that equals a domain onboarded to the account, ignoring case. """ pattern_type: Literal["EMAIL", "DOMAIN", "IP", "UNKNOWN"] diff --git a/src/cloudflare/types/email_security/settings/allow_policy_edit_response.py b/src/cloudflare/types/email_security/settings/allow_policy_edit_response.py index a3951640f11..82667bbd06b 100644 --- a/src/cloudflare/types/email_security/settings/allow_policy_edit_response.py +++ b/src/cloudflare/types/email_security/settings/allow_policy_edit_response.py @@ -22,6 +22,13 @@ class AllowPolicyEditResponse(BaseModel): comments: Optional[str] = None + expires_at: Optional[datetime] = None + """Timestamp at which the policy expires. + + After this time, Email Security ignores the policy. The value must lie in the + future. Send `null` to clear the expiration. + """ + is_acceptable_sender: Optional[bool] = None """ Exempts messages from this sender from Spam, Spoof and Bulk dispositions only; @@ -64,7 +71,8 @@ class AllowPolicyEditResponse(BaseModel): plain IPv4 or IPv6 address or CIDR block for IP (e.g. `1.2.3.4`, `1.2.3.0/24`, `2606:4700:4700::1111`, or `2606:4700:4700::/48`); the API rejects private or unique-local, loopback, link-local, unspecified, and IPv4 broadcast addresses, - including their IPv4-mapped IPv6 equivalents. + including their IPv4-mapped IPv6 equivalents. The API also rejects a pattern + that equals a domain onboarded to the account, ignoring case. """ pattern_type: Optional[Literal["EMAIL", "DOMAIN", "IP", "UNKNOWN"]] = None diff --git a/src/cloudflare/types/email_security/settings/allow_policy_get_response.py b/src/cloudflare/types/email_security/settings/allow_policy_get_response.py index 5adfe71aecf..01000499f69 100644 --- a/src/cloudflare/types/email_security/settings/allow_policy_get_response.py +++ b/src/cloudflare/types/email_security/settings/allow_policy_get_response.py @@ -22,6 +22,13 @@ class AllowPolicyGetResponse(BaseModel): comments: Optional[str] = None + expires_at: Optional[datetime] = None + """Timestamp at which the policy expires. + + After this time, Email Security ignores the policy. The value must lie in the + future. Send `null` to clear the expiration. + """ + is_acceptable_sender: Optional[bool] = None """ Exempts messages from this sender from Spam, Spoof and Bulk dispositions only; @@ -64,7 +71,8 @@ class AllowPolicyGetResponse(BaseModel): plain IPv4 or IPv6 address or CIDR block for IP (e.g. `1.2.3.4`, `1.2.3.0/24`, `2606:4700:4700::1111`, or `2606:4700:4700::/48`); the API rejects private or unique-local, loopback, link-local, unspecified, and IPv4 broadcast addresses, - including their IPv4-mapped IPv6 equivalents. + including their IPv4-mapped IPv6 equivalents. The API also rejects a pattern + that equals a domain onboarded to the account, ignoring case. """ pattern_type: Optional[Literal["EMAIL", "DOMAIN", "IP", "UNKNOWN"]] = None diff --git a/src/cloudflare/types/email_security/settings/allow_policy_list_params.py b/src/cloudflare/types/email_security/settings/allow_policy_list_params.py index 1e9eb6350fd..80f148c31b1 100644 --- a/src/cloudflare/types/email_security/settings/allow_policy_list_params.py +++ b/src/cloudflare/types/email_security/settings/allow_policy_list_params.py @@ -14,6 +14,12 @@ class AllowPolicyListParams(TypedDict, total=False): direction: Literal["asc", "desc"] """The sorting direction.""" + expired: bool + """ + Filter to return only expired policies (`true`) or only policies that still + apply (`false`). Omit to return both. + """ + is_acceptable_sender: bool """ Filter to show only policies where messages from the sender are exempted from diff --git a/src/cloudflare/types/email_security/settings/allow_policy_list_response.py b/src/cloudflare/types/email_security/settings/allow_policy_list_response.py index 63d3cc42c82..369ccdaa6f0 100644 --- a/src/cloudflare/types/email_security/settings/allow_policy_list_response.py +++ b/src/cloudflare/types/email_security/settings/allow_policy_list_response.py @@ -22,6 +22,13 @@ class AllowPolicyListResponse(BaseModel): comments: Optional[str] = None + expires_at: Optional[datetime] = None + """Timestamp at which the policy expires. + + After this time, Email Security ignores the policy. The value must lie in the + future. Send `null` to clear the expiration. + """ + is_acceptable_sender: Optional[bool] = None """ Exempts messages from this sender from Spam, Spoof and Bulk dispositions only; @@ -64,7 +71,8 @@ class AllowPolicyListResponse(BaseModel): plain IPv4 or IPv6 address or CIDR block for IP (e.g. `1.2.3.4`, `1.2.3.0/24`, `2606:4700:4700::1111`, or `2606:4700:4700::/48`); the API rejects private or unique-local, loopback, link-local, unspecified, and IPv4 broadcast addresses, - including their IPv4-mapped IPv6 equivalents. + including their IPv4-mapped IPv6 equivalents. The API also rejects a pattern + that equals a domain onboarded to the account, ignoring case. """ pattern_type: Optional[Literal["EMAIL", "DOMAIN", "IP", "UNKNOWN"]] = None diff --git a/src/cloudflare/types/email_security/settings/block_sender_batch_params.py b/src/cloudflare/types/email_security/settings/block_sender_batch_params.py index 9e37cf5c2cb..f63f69c363b 100644 --- a/src/cloudflare/types/email_security/settings/block_sender_batch_params.py +++ b/src/cloudflare/types/email_security/settings/block_sender_batch_params.py @@ -2,8 +2,11 @@ from __future__ import annotations -from typing import Iterable, Optional -from typing_extensions import Literal, Required, TypedDict +from typing import Union, Iterable, Optional +from datetime import datetime +from typing_extensions import Literal, Required, Annotated, TypedDict + +from ...._utils import PropertyInfo __all__ = ["BlockSenderBatchParams", "Delete", "Patch", "Post", "Put"] @@ -41,6 +44,13 @@ class Patch(TypedDict, total=False): comments: Optional[str] + expires_at: Annotated[Union[str, datetime, None], PropertyInfo(format="iso8601")] + """Timestamp at which the pattern expires. + + After this time, Email Security ignores the pattern. The value must lie in the + future. Send `null` to clear the expiration. + """ + is_regex: bool """Whether `pattern` is a regular expression instead of a literal value.""" @@ -103,6 +113,13 @@ class Post(TypedDict, total=False): comments: Optional[str] + expires_at: Annotated[Union[str, datetime, None], PropertyInfo(format="iso8601")] + """Timestamp at which the pattern expires. + + After this time, Email Security ignores the pattern. The value must lie in the + future. Send `null` to clear the expiration. + """ + class Put(TypedDict, total=False): """A blocked sender pattern.""" @@ -136,3 +153,10 @@ class Put(TypedDict, total=False): """ comments: Optional[str] + + expires_at: Annotated[Union[str, datetime, None], PropertyInfo(format="iso8601")] + """Timestamp at which the pattern expires. + + After this time, Email Security ignores the pattern. The value must lie in the + future. Send `null` to clear the expiration. + """ diff --git a/src/cloudflare/types/email_security/settings/block_sender_batch_response.py b/src/cloudflare/types/email_security/settings/block_sender_batch_response.py index 4376ab845ed..9b09521604b 100644 --- a/src/cloudflare/types/email_security/settings/block_sender_batch_response.py +++ b/src/cloudflare/types/email_security/settings/block_sender_batch_response.py @@ -24,6 +24,13 @@ class Patch(BaseModel): created_at: Optional[datetime] = None + expires_at: Optional[datetime] = None + """Timestamp at which the pattern expires. + + After this time, Email Security ignores the pattern. The value must lie in the + future. Send `null` to clear the expiration. + """ + is_regex: Optional[bool] = None """Whether `pattern` is a regular expression instead of a literal value.""" @@ -68,6 +75,13 @@ class Post(BaseModel): created_at: Optional[datetime] = None + expires_at: Optional[datetime] = None + """Timestamp at which the pattern expires. + + After this time, Email Security ignores the pattern. The value must lie in the + future. Send `null` to clear the expiration. + """ + is_regex: Optional[bool] = None """Whether `pattern` is a regular expression instead of a literal value.""" @@ -112,6 +126,13 @@ class Put(BaseModel): created_at: Optional[datetime] = None + expires_at: Optional[datetime] = None + """Timestamp at which the pattern expires. + + After this time, Email Security ignores the pattern. The value must lie in the + future. Send `null` to clear the expiration. + """ + is_regex: Optional[bool] = None """Whether `pattern` is a regular expression instead of a literal value.""" diff --git a/src/cloudflare/types/email_security/settings/block_sender_create_params.py b/src/cloudflare/types/email_security/settings/block_sender_create_params.py index c0881a87443..b75f15f2fff 100644 --- a/src/cloudflare/types/email_security/settings/block_sender_create_params.py +++ b/src/cloudflare/types/email_security/settings/block_sender_create_params.py @@ -2,8 +2,11 @@ from __future__ import annotations -from typing import Optional -from typing_extensions import Literal, Required, TypedDict +from typing import Union, Optional +from datetime import datetime +from typing_extensions import Literal, Required, Annotated, TypedDict + +from ...._utils import PropertyInfo __all__ = ["BlockSenderCreateParams"] @@ -41,3 +44,10 @@ class BlockSenderCreateParams(TypedDict, total=False): """ comments: Optional[str] + + expires_at: Annotated[Union[str, datetime, None], PropertyInfo(format="iso8601")] + """Timestamp at which the pattern expires. + + After this time, Email Security ignores the pattern. The value must lie in the + future. Send `null` to clear the expiration. + """ diff --git a/src/cloudflare/types/email_security/settings/block_sender_create_response.py b/src/cloudflare/types/email_security/settings/block_sender_create_response.py index 65aa88e502d..02993cd2968 100644 --- a/src/cloudflare/types/email_security/settings/block_sender_create_response.py +++ b/src/cloudflare/types/email_security/settings/block_sender_create_response.py @@ -19,6 +19,13 @@ class BlockSenderCreateResponse(BaseModel): created_at: Optional[datetime] = None + expires_at: Optional[datetime] = None + """Timestamp at which the pattern expires. + + After this time, Email Security ignores the pattern. The value must lie in the + future. Send `null` to clear the expiration. + """ + is_regex: Optional[bool] = None """Whether `pattern` is a regular expression instead of a literal value.""" diff --git a/src/cloudflare/types/email_security/settings/block_sender_edit_params.py b/src/cloudflare/types/email_security/settings/block_sender_edit_params.py index 7306bfab2b4..21056228fb2 100644 --- a/src/cloudflare/types/email_security/settings/block_sender_edit_params.py +++ b/src/cloudflare/types/email_security/settings/block_sender_edit_params.py @@ -2,8 +2,11 @@ from __future__ import annotations -from typing import Optional -from typing_extensions import Literal, Required, TypedDict +from typing import Union, Optional +from datetime import datetime +from typing_extensions import Literal, Required, Annotated, TypedDict + +from ...._utils import PropertyInfo __all__ = ["BlockSenderEditParams"] @@ -14,6 +17,13 @@ class BlockSenderEditParams(TypedDict, total=False): comments: Optional[str] + expires_at: Annotated[Union[str, datetime, None], PropertyInfo(format="iso8601")] + """Timestamp at which the pattern expires. + + After this time, Email Security ignores the pattern. The value must lie in the + future. Send `null` to clear the expiration. + """ + is_regex: bool """Whether `pattern` is a regular expression instead of a literal value.""" diff --git a/src/cloudflare/types/email_security/settings/block_sender_edit_response.py b/src/cloudflare/types/email_security/settings/block_sender_edit_response.py index 791dbd3c5aa..426e4d92397 100644 --- a/src/cloudflare/types/email_security/settings/block_sender_edit_response.py +++ b/src/cloudflare/types/email_security/settings/block_sender_edit_response.py @@ -19,6 +19,13 @@ class BlockSenderEditResponse(BaseModel): created_at: Optional[datetime] = None + expires_at: Optional[datetime] = None + """Timestamp at which the pattern expires. + + After this time, Email Security ignores the pattern. The value must lie in the + future. Send `null` to clear the expiration. + """ + is_regex: Optional[bool] = None """Whether `pattern` is a regular expression instead of a literal value.""" diff --git a/src/cloudflare/types/email_security/settings/block_sender_get_response.py b/src/cloudflare/types/email_security/settings/block_sender_get_response.py index 0ce916e3085..550f996af9f 100644 --- a/src/cloudflare/types/email_security/settings/block_sender_get_response.py +++ b/src/cloudflare/types/email_security/settings/block_sender_get_response.py @@ -19,6 +19,13 @@ class BlockSenderGetResponse(BaseModel): created_at: Optional[datetime] = None + expires_at: Optional[datetime] = None + """Timestamp at which the pattern expires. + + After this time, Email Security ignores the pattern. The value must lie in the + future. Send `null` to clear the expiration. + """ + is_regex: Optional[bool] = None """Whether `pattern` is a regular expression instead of a literal value.""" diff --git a/src/cloudflare/types/email_security/settings/block_sender_list_params.py b/src/cloudflare/types/email_security/settings/block_sender_list_params.py index 9c1fe7b8850..c1f7f4bd647 100644 --- a/src/cloudflare/types/email_security/settings/block_sender_list_params.py +++ b/src/cloudflare/types/email_security/settings/block_sender_list_params.py @@ -14,6 +14,12 @@ class BlockSenderListParams(TypedDict, total=False): direction: Literal["asc", "desc"] """The sorting direction.""" + expired: bool + """ + Filter to return only expired patterns (`true`) or only patterns that still + apply (`false`). Omit to return both. + """ + order: Literal["pattern", "created_at"] """Field to sort by.""" diff --git a/src/cloudflare/types/email_security/settings/block_sender_list_response.py b/src/cloudflare/types/email_security/settings/block_sender_list_response.py index 2c14dcb9c79..3744c9593eb 100644 --- a/src/cloudflare/types/email_security/settings/block_sender_list_response.py +++ b/src/cloudflare/types/email_security/settings/block_sender_list_response.py @@ -19,6 +19,13 @@ class BlockSenderListResponse(BaseModel): created_at: Optional[datetime] = None + expires_at: Optional[datetime] = None + """Timestamp at which the pattern expires. + + After this time, Email Security ignores the pattern. The value must lie in the + future. Send `null` to clear the expiration. + """ + is_regex: Optional[bool] = None """Whether `pattern` is a regular expression instead of a literal value.""" diff --git a/src/cloudflare/types/email_security/settings/content_policy_batch_params.py b/src/cloudflare/types/email_security/settings/content_policy_batch_params.py index ec5ad96a22d..cece75c761f 100644 --- a/src/cloudflare/types/email_security/settings/content_policy_batch_params.py +++ b/src/cloudflare/types/email_security/settings/content_policy_batch_params.py @@ -2,8 +2,11 @@ from __future__ import annotations -from typing import List, Iterable, Optional -from typing_extensions import Literal, Required, TypedDict +from typing import List, Union, Iterable, Optional +from datetime import datetime +from typing_extensions import Literal, Required, Annotated, TypedDict + +from ...._utils import PropertyInfo __all__ = ["ContentPolicyBatchParams", "Delete", "Patch", "Post", "Put"] @@ -42,6 +45,13 @@ class Patch(TypedDict, total=False): enabled: bool """Whether the policy is active.""" + expires_at: Annotated[Union[str, datetime, None], PropertyInfo(format="iso8601")] + """Timestamp at which the policy expires. + + After this time, Email Security ignores the policy. The value must lie in the + future. Send `null` to clear the expiration. + """ + name: str """Human-readable name of the policy.""" @@ -70,6 +80,13 @@ class Post(TypedDict, total=False): targets: Required[List[Literal["SUBJECT", "BODY"]]] """Parts of the email the pattern is matched against.""" + expires_at: Annotated[Union[str, datetime, None], PropertyInfo(format="iso8601")] + """Timestamp at which the policy expires. + + After this time, Email Security ignores the policy. The value must lie in the + future. Send `null` to clear the expiration. + """ + notes: Optional[str] """Optional note describing the purpose of the policy.""" @@ -89,5 +106,12 @@ class Put(TypedDict, total=False): targets: Required[List[Literal["SUBJECT", "BODY"]]] """Parts of the email the pattern is matched against.""" + expires_at: Annotated[Union[str, datetime, None], PropertyInfo(format="iso8601")] + """Timestamp at which the policy expires. + + After this time, Email Security ignores the policy. The value must lie in the + future. Send `null` to clear the expiration. + """ + notes: Optional[str] """Optional note describing the purpose of the policy.""" diff --git a/src/cloudflare/types/email_security/settings/content_policy_batch_response.py b/src/cloudflare/types/email_security/settings/content_policy_batch_response.py index 20b731dec16..90df8b2344e 100644 --- a/src/cloudflare/types/email_security/settings/content_policy_batch_response.py +++ b/src/cloudflare/types/email_security/settings/content_policy_batch_response.py @@ -25,6 +25,13 @@ class Patch(BaseModel): enabled: Optional[bool] = None """Whether the policy is active.""" + expires_at: Optional[datetime] = None + """Timestamp at which the policy expires. + + After this time, Email Security ignores the policy. The value must lie in the + future. Send `null` to clear the expiration. + """ + modified_at: Optional[datetime] = None name: Optional[str] = None @@ -51,6 +58,13 @@ class Post(BaseModel): enabled: Optional[bool] = None """Whether the policy is active.""" + expires_at: Optional[datetime] = None + """Timestamp at which the policy expires. + + After this time, Email Security ignores the policy. The value must lie in the + future. Send `null` to clear the expiration. + """ + modified_at: Optional[datetime] = None name: Optional[str] = None @@ -77,6 +91,13 @@ class Put(BaseModel): enabled: Optional[bool] = None """Whether the policy is active.""" + expires_at: Optional[datetime] = None + """Timestamp at which the policy expires. + + After this time, Email Security ignores the policy. The value must lie in the + future. Send `null` to clear the expiration. + """ + modified_at: Optional[datetime] = None name: Optional[str] = None diff --git a/src/cloudflare/types/email_security/settings/content_policy_create_params.py b/src/cloudflare/types/email_security/settings/content_policy_create_params.py index 9006c451853..d4978bf01ae 100644 --- a/src/cloudflare/types/email_security/settings/content_policy_create_params.py +++ b/src/cloudflare/types/email_security/settings/content_policy_create_params.py @@ -2,8 +2,11 @@ from __future__ import annotations -from typing import List, Optional -from typing_extensions import Literal, Required, TypedDict +from typing import List, Union, Optional +from datetime import datetime +from typing_extensions import Literal, Required, Annotated, TypedDict + +from ...._utils import PropertyInfo __all__ = ["ContentPolicyCreateParams"] @@ -24,5 +27,12 @@ class ContentPolicyCreateParams(TypedDict, total=False): targets: Required[List[Literal["SUBJECT", "BODY"]]] """Parts of the email the pattern is matched against.""" + expires_at: Annotated[Union[str, datetime, None], PropertyInfo(format="iso8601")] + """Timestamp at which the policy expires. + + After this time, Email Security ignores the policy. The value must lie in the + future. Send `null` to clear the expiration. + """ + notes: Optional[str] """Optional note describing the purpose of the policy.""" diff --git a/src/cloudflare/types/email_security/settings/content_policy_create_response.py b/src/cloudflare/types/email_security/settings/content_policy_create_response.py index c9e348b7d72..4c81b218a53 100644 --- a/src/cloudflare/types/email_security/settings/content_policy_create_response.py +++ b/src/cloudflare/types/email_security/settings/content_policy_create_response.py @@ -20,6 +20,13 @@ class ContentPolicyCreateResponse(BaseModel): enabled: Optional[bool] = None """Whether the policy is active.""" + expires_at: Optional[datetime] = None + """Timestamp at which the policy expires. + + After this time, Email Security ignores the policy. The value must lie in the + future. Send `null` to clear the expiration. + """ + modified_at: Optional[datetime] = None name: Optional[str] = None diff --git a/src/cloudflare/types/email_security/settings/content_policy_edit_params.py b/src/cloudflare/types/email_security/settings/content_policy_edit_params.py index c9d77dec9dd..c44c0481149 100644 --- a/src/cloudflare/types/email_security/settings/content_policy_edit_params.py +++ b/src/cloudflare/types/email_security/settings/content_policy_edit_params.py @@ -2,8 +2,11 @@ from __future__ import annotations -from typing import List, Optional -from typing_extensions import Literal, Required, TypedDict +from typing import List, Union, Optional +from datetime import datetime +from typing_extensions import Literal, Required, Annotated, TypedDict + +from ...._utils import PropertyInfo __all__ = ["ContentPolicyEditParams"] @@ -15,6 +18,13 @@ class ContentPolicyEditParams(TypedDict, total=False): enabled: bool """Whether the policy is active.""" + expires_at: Annotated[Union[str, datetime, None], PropertyInfo(format="iso8601")] + """Timestamp at which the policy expires. + + After this time, Email Security ignores the policy. The value must lie in the + future. Send `null` to clear the expiration. + """ + name: str """Human-readable name of the policy.""" diff --git a/src/cloudflare/types/email_security/settings/content_policy_edit_response.py b/src/cloudflare/types/email_security/settings/content_policy_edit_response.py index 5a1d6f258df..0768bad8e01 100644 --- a/src/cloudflare/types/email_security/settings/content_policy_edit_response.py +++ b/src/cloudflare/types/email_security/settings/content_policy_edit_response.py @@ -20,6 +20,13 @@ class ContentPolicyEditResponse(BaseModel): enabled: Optional[bool] = None """Whether the policy is active.""" + expires_at: Optional[datetime] = None + """Timestamp at which the policy expires. + + After this time, Email Security ignores the policy. The value must lie in the + future. Send `null` to clear the expiration. + """ + modified_at: Optional[datetime] = None name: Optional[str] = None diff --git a/src/cloudflare/types/email_security/settings/content_policy_get_response.py b/src/cloudflare/types/email_security/settings/content_policy_get_response.py index 7652c1735f8..08a23fb5775 100644 --- a/src/cloudflare/types/email_security/settings/content_policy_get_response.py +++ b/src/cloudflare/types/email_security/settings/content_policy_get_response.py @@ -20,6 +20,13 @@ class ContentPolicyGetResponse(BaseModel): enabled: Optional[bool] = None """Whether the policy is active.""" + expires_at: Optional[datetime] = None + """Timestamp at which the policy expires. + + After this time, Email Security ignores the policy. The value must lie in the + future. Send `null` to clear the expiration. + """ + modified_at: Optional[datetime] = None name: Optional[str] = None diff --git a/src/cloudflare/types/email_security/settings/content_policy_list_params.py b/src/cloudflare/types/email_security/settings/content_policy_list_params.py index 38ba488148e..d0bf835b9c6 100644 --- a/src/cloudflare/types/email_security/settings/content_policy_list_params.py +++ b/src/cloudflare/types/email_security/settings/content_policy_list_params.py @@ -17,6 +17,12 @@ class ContentPolicyListParams(TypedDict, total=False): enabled: bool """Filter by enabled status.""" + expired: bool + """ + Filter to return only expired policies (`true`) or only policies that still + apply (`false`). Omit to return both. + """ + name: str """Filter by exact policy name.""" diff --git a/src/cloudflare/types/email_security/settings/content_policy_list_response.py b/src/cloudflare/types/email_security/settings/content_policy_list_response.py index 87246733c39..bec548e0c7c 100644 --- a/src/cloudflare/types/email_security/settings/content_policy_list_response.py +++ b/src/cloudflare/types/email_security/settings/content_policy_list_response.py @@ -20,6 +20,13 @@ class ContentPolicyListResponse(BaseModel): enabled: Optional[bool] = None """Whether the policy is active.""" + expires_at: Optional[datetime] = None + """Timestamp at which the policy expires. + + After this time, Email Security ignores the policy. The value must lie in the + future. Send `null` to clear the expiration. + """ + modified_at: Optional[datetime] = None name: Optional[str] = None diff --git a/src/cloudflare/types/email_sending/subdomain_create_params.py b/src/cloudflare/types/email_sending/subdomain_create_params.py index 0b7304f4d7d..a485106a4c1 100644 --- a/src/cloudflare/types/email_sending/subdomain_create_params.py +++ b/src/cloudflare/types/email_sending/subdomain_create_params.py @@ -15,5 +15,7 @@ class SubdomainCreateParams(TypedDict, total=False): """The domain name within the zone. A wildcard is allowed only as the complete leftmost label (`*.example.com`) and - requires the account wildcard Email Sending entitlement. + requires the account wildcard Email Sending entitlement. The derived Return-Path + hostname, including its bounce prefix, must be at most 201 characters after + ASCII conversion; wildcards use the base hostname. """ diff --git a/src/cloudflare/types/flagship/apps/evaluate_get_response.py b/src/cloudflare/types/flagship/apps/evaluate_get_response.py index 9d9774a487e..186823e4578 100644 --- a/src/cloudflare/types/flagship/apps/evaluate_get_response.py +++ b/src/cloudflare/types/flagship/apps/evaluate_get_response.py @@ -20,4 +20,10 @@ class EvaluateGetResponse(BaseModel): variant: str """Name of the variation that supplied the resolved value.""" + metadata: Optional[Dict[str, Union[bool, str, float]]] = None + """Key-value metadata associated with the flag. + + Returned only when the flag has metadata. + """ + value: Union[Optional[str], float, bool, Dict[str, object], List[object], None] = None diff --git a/src/cloudflare/types/flagship/apps/flag_create_params.py b/src/cloudflare/types/flagship/apps/flag_create_params.py index 6fdb3def6f1..214625f72c0 100644 --- a/src/cloudflare/types/flagship/apps/flag_create_params.py +++ b/src/cloudflare/types/flagship/apps/flag_create_params.py @@ -5,29 +5,25 @@ from typing import Dict, Union, Iterable, Optional from typing_extensions import Literal, Required, TypeAlias, TypedDict -from ...._types import SequenceNotStr - __all__ = [ "FlagCreateParams", "Rule", "RuleCondition", - "RuleConditionUnionMember0", - "RuleConditionUnionMember1", - "RuleConditionUnionMember1Clause", - "RuleConditionUnionMember1ClauseUnionMember0", - "RuleConditionUnionMember1ClauseUnionMember1", - "RuleConditionUnionMember1ClauseUnionMember1Clause", - "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember0", - "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1", - "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1Clause", - "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0", - "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1", - "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause", - "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0", - "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1", - "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause", - "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0", - "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1", + "RuleConditionFlagshipBaseCondition", + "RuleConditionFlagshipLogicalCondition", + "RuleConditionFlagshipLogicalConditionClause", + "RuleConditionFlagshipLogicalConditionClauseFlagshipBaseCondition", + "RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1", + "RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1Clause", + "RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipBaseCondition", + "RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2", + "RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2Clause", + "RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipBaseCondition", + "RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3", + "RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3Clause", + "RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3ClauseFlagshipBaseCondition", + "RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3ClauseFlagshipLogicalCondition4", + "RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3ClauseFlagshipLogicalCondition4Clause", "RuleRollout", ] @@ -67,6 +63,13 @@ class FlagCreateParams(TypedDict, total=False): description: Optional[str] """Optional operator-facing description. It does not affect flag evaluation.""" + metadata: Optional[Dict[str, Union[bool, str, float]]] + """Key-value metadata associated with the flag. + + `null` or an empty object clears existing metadata; omission semantics depend on + the endpoint (PUT clears it, PATCH preserves it). + """ + type: Literal["boolean", "string", "number", "json"] """Deprecated compatibility field. @@ -75,7 +78,7 @@ class FlagCreateParams(TypedDict, total=False): """ -class RuleConditionUnionMember0(TypedDict, total=False): +class RuleConditionFlagshipBaseCondition(TypedDict, total=False): attribute: Required[str] operator: Required[ @@ -99,7 +102,7 @@ class RuleConditionUnionMember0(TypedDict, total=False): value: Required[Union[Optional[str], float, bool, Dict[str, object], Iterable[object]]] -class RuleConditionUnionMember1ClauseUnionMember0(TypedDict, total=False): +class RuleConditionFlagshipLogicalConditionClauseFlagshipBaseCondition(TypedDict, total=False): attribute: Required[str] operator: Required[ @@ -123,7 +126,9 @@ class RuleConditionUnionMember1ClauseUnionMember0(TypedDict, total=False): value: Required[Union[Optional[str], float, bool, Dict[str, object], Iterable[object]]] -class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember0(TypedDict, total=False): +class RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipBaseCondition( + TypedDict, total=False +): attribute: Required[str] operator: Required[ @@ -147,7 +152,9 @@ class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember0(TypedDict, t value: Required[Union[Optional[str], float, bool, Dict[str, object], Iterable[object]]] -class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0(TypedDict, total=False): +class RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipBaseCondition( + TypedDict, total=False +): attribute: Required[str] operator: Required[ @@ -171,7 +178,7 @@ class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMe value: Required[Union[Optional[str], float, bool, Dict[str, object], Iterable[object]]] -class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0( +class RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3ClauseFlagshipBaseCondition( TypedDict, total=False ): attribute: Required[str] @@ -197,7 +204,7 @@ class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMe value: Required[Union[Optional[str], float, bool, Dict[str, object], Iterable[object]]] -class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0( +class RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3ClauseFlagshipLogicalCondition4Clause( TypedDict, total=False ): attribute: Required[str] @@ -223,80 +230,79 @@ class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMe value: Required[Union[Optional[str], float, bool, Dict[str, object], Iterable[object]]] -class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1( +class RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3ClauseFlagshipLogicalCondition4( TypedDict, total=False ): - clauses: Required[SequenceNotStr[Union[Optional[str], float, bool, Dict[str, object], Iterable[object]]]] + clauses: Required[ + Iterable[ + RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3ClauseFlagshipLogicalCondition4Clause + ] + ] logical_operator: Required[Literal["AND", "OR"]] -RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause: TypeAlias = Union[ - RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0, - RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1, +RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3Clause: TypeAlias = Union[ + RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3ClauseFlagshipBaseCondition, + RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3ClauseFlagshipLogicalCondition4, ] -class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1( +class RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3( TypedDict, total=False ): clauses: Required[ Iterable[ - RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause + RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3Clause ] ] logical_operator: Required[Literal["AND", "OR"]] -RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause: TypeAlias = Union[ - RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0, - RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1, +RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2Clause: TypeAlias = Union[ + RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipBaseCondition, + RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3, ] -class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1(TypedDict, total=False): - clauses: Required[Iterable[RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause]] - - logical_operator: Required[Literal["AND", "OR"]] - - -RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1Clause: TypeAlias = Union[ - RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0, - RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1, -] - - -class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1(TypedDict, total=False): - clauses: Required[Iterable[RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1Clause]] +class RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2( + TypedDict, total=False +): + clauses: Required[ + Iterable[ + RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2Clause + ] + ] logical_operator: Required[Literal["AND", "OR"]] -RuleConditionUnionMember1ClauseUnionMember1Clause: TypeAlias = Union[ - RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember0, - RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1, +RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1Clause: TypeAlias = Union[ + RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipBaseCondition, + RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2, ] -class RuleConditionUnionMember1ClauseUnionMember1(TypedDict, total=False): - clauses: Required[Iterable[RuleConditionUnionMember1ClauseUnionMember1Clause]] +class RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1(TypedDict, total=False): + clauses: Required[Iterable[RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1Clause]] logical_operator: Required[Literal["AND", "OR"]] -RuleConditionUnionMember1Clause: TypeAlias = Union[ - RuleConditionUnionMember1ClauseUnionMember0, RuleConditionUnionMember1ClauseUnionMember1 +RuleConditionFlagshipLogicalConditionClause: TypeAlias = Union[ + RuleConditionFlagshipLogicalConditionClauseFlagshipBaseCondition, + RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1, ] -class RuleConditionUnionMember1(TypedDict, total=False): - clauses: Required[Iterable[RuleConditionUnionMember1Clause]] +class RuleConditionFlagshipLogicalCondition(TypedDict, total=False): + clauses: Required[Iterable[RuleConditionFlagshipLogicalConditionClause]] logical_operator: Required[Literal["AND", "OR"]] -RuleCondition: TypeAlias = Union[RuleConditionUnionMember0, RuleConditionUnionMember1] +RuleCondition: TypeAlias = Union[RuleConditionFlagshipBaseCondition, RuleConditionFlagshipLogicalCondition] class RuleRollout(TypedDict, total=False): diff --git a/src/cloudflare/types/flagship/apps/flag_create_response.py b/src/cloudflare/types/flagship/apps/flag_create_response.py index ae3a4b13667..864f38edf24 100644 --- a/src/cloudflare/types/flagship/apps/flag_create_response.py +++ b/src/cloudflare/types/flagship/apps/flag_create_response.py @@ -9,28 +9,26 @@ "FlagCreateResponse", "Rule", "RuleCondition", - "RuleConditionUnionMember0", - "RuleConditionUnionMember1", - "RuleConditionUnionMember1Clause", - "RuleConditionUnionMember1ClauseUnionMember0", - "RuleConditionUnionMember1ClauseUnionMember1", - "RuleConditionUnionMember1ClauseUnionMember1Clause", - "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember0", - "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1", - "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1Clause", - "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0", - "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1", - "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause", - "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0", - "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1", - "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause", - "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0", - "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1", + "RuleConditionFlagshipBaseCondition", + "RuleConditionFlagshipLogicalCondition", + "RuleConditionFlagshipLogicalConditionClause", + "RuleConditionFlagshipLogicalConditionClauseFlagshipBaseCondition", + "RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1", + "RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1Clause", + "RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipBaseCondition", + "RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2", + "RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2Clause", + "RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipBaseCondition", + "RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3", + "RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3Clause", + "RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3ClauseFlagshipBaseCondition", + "RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3ClauseFlagshipLogicalCondition4", + "RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3ClauseFlagshipLogicalCondition4Clause", "RuleRollout", ] -class RuleConditionUnionMember0(BaseModel): +class RuleConditionFlagshipBaseCondition(BaseModel): attribute: str operator: Literal[ @@ -52,7 +50,7 @@ class RuleConditionUnionMember0(BaseModel): value: Union[Optional[str], float, bool, Dict[str, object], List[object]] -class RuleConditionUnionMember1ClauseUnionMember0(BaseModel): +class RuleConditionFlagshipLogicalConditionClauseFlagshipBaseCondition(BaseModel): attribute: str operator: Literal[ @@ -74,7 +72,7 @@ class RuleConditionUnionMember1ClauseUnionMember0(BaseModel): value: Union[Optional[str], float, bool, Dict[str, object], List[object]] -class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember0(BaseModel): +class RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipBaseCondition(BaseModel): attribute: str operator: Literal[ @@ -96,7 +94,9 @@ class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember0(BaseModel): value: Union[Optional[str], float, bool, Dict[str, object], List[object]] -class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0(BaseModel): +class RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipBaseCondition( + BaseModel +): attribute: str operator: Literal[ @@ -118,7 +118,9 @@ class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMe value: Union[Optional[str], float, bool, Dict[str, object], List[object]] -class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0(BaseModel): +class RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3ClauseFlagshipBaseCondition( + BaseModel +): attribute: str operator: Literal[ @@ -140,7 +142,7 @@ class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMe value: Union[Optional[str], float, bool, Dict[str, object], List[object]] -class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0( +class RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3ClauseFlagshipLogicalCondition4Clause( BaseModel ): attribute: str @@ -164,76 +166,71 @@ class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMe value: Union[Optional[str], float, bool, Dict[str, object], List[object]] -class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1( +class RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3ClauseFlagshipLogicalCondition4( BaseModel ): - clauses: List[Union[Optional[str], float, bool, Dict[str, object], List[object]]] - - logical_operator: Literal["AND", "OR"] - - -RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause: TypeAlias = Union[ - RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0, - RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1, -] - - -class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1(BaseModel): clauses: List[ - RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause + RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3ClauseFlagshipLogicalCondition4Clause ] logical_operator: Literal["AND", "OR"] -RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause: TypeAlias = Union[ - RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0, - RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1, +RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3Clause: TypeAlias = Union[ + RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3ClauseFlagshipBaseCondition, + RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3ClauseFlagshipLogicalCondition4, ] -class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1(BaseModel): - clauses: List[RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause] +class RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3( + BaseModel +): + clauses: List[ + RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3Clause + ] logical_operator: Literal["AND", "OR"] -RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1Clause: TypeAlias = Union[ - RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0, - RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1, +RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2Clause: TypeAlias = Union[ + RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipBaseCondition, + RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3, ] -class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1(BaseModel): - clauses: List[RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1Clause] +class RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2(BaseModel): + clauses: List[ + RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2Clause + ] logical_operator: Literal["AND", "OR"] -RuleConditionUnionMember1ClauseUnionMember1Clause: TypeAlias = Union[ - RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember0, - RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1, +RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1Clause: TypeAlias = Union[ + RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipBaseCondition, + RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2, ] -class RuleConditionUnionMember1ClauseUnionMember1(BaseModel): - clauses: List[RuleConditionUnionMember1ClauseUnionMember1Clause] +class RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1(BaseModel): + clauses: List[RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1Clause] logical_operator: Literal["AND", "OR"] -RuleConditionUnionMember1Clause: TypeAlias = Union[ - RuleConditionUnionMember1ClauseUnionMember0, RuleConditionUnionMember1ClauseUnionMember1 +RuleConditionFlagshipLogicalConditionClause: TypeAlias = Union[ + RuleConditionFlagshipLogicalConditionClauseFlagshipBaseCondition, + RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1, ] -class RuleConditionUnionMember1(BaseModel): - clauses: List[RuleConditionUnionMember1Clause] +class RuleConditionFlagshipLogicalCondition(BaseModel): + clauses: List[RuleConditionFlagshipLogicalConditionClause] logical_operator: Literal["AND", "OR"] -RuleCondition: TypeAlias = Union[RuleConditionUnionMember0, RuleConditionUnionMember1] +RuleCondition: TypeAlias = Union[RuleConditionFlagshipBaseCondition, RuleConditionFlagshipLogicalCondition] class RuleRollout(BaseModel): @@ -306,6 +303,12 @@ class FlagCreateResponse(BaseModel): description: Optional[str] = None """Optional operator-facing description. It does not affect flag evaluation.""" + metadata: Optional[Dict[str, Union[bool, str, float]]] = None + """Key-value metadata associated with the flag. + + Returned only when the flag has metadata. + """ + updated_at: Optional[str] = None updated_by: Optional[str] = None diff --git a/src/cloudflare/types/flagship/apps/flag_get_response.py b/src/cloudflare/types/flagship/apps/flag_get_response.py index 94397e9abcf..22ca6ebaddb 100644 --- a/src/cloudflare/types/flagship/apps/flag_get_response.py +++ b/src/cloudflare/types/flagship/apps/flag_get_response.py @@ -9,28 +9,26 @@ "FlagGetResponse", "Rule", "RuleCondition", - "RuleConditionUnionMember0", - "RuleConditionUnionMember1", - "RuleConditionUnionMember1Clause", - "RuleConditionUnionMember1ClauseUnionMember0", - "RuleConditionUnionMember1ClauseUnionMember1", - "RuleConditionUnionMember1ClauseUnionMember1Clause", - "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember0", - "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1", - "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1Clause", - "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0", - "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1", - "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause", - "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0", - "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1", - "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause", - "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0", - "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1", + "RuleConditionFlagshipBaseCondition", + "RuleConditionFlagshipLogicalCondition", + "RuleConditionFlagshipLogicalConditionClause", + "RuleConditionFlagshipLogicalConditionClauseFlagshipBaseCondition", + "RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1", + "RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1Clause", + "RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipBaseCondition", + "RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2", + "RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2Clause", + "RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipBaseCondition", + "RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3", + "RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3Clause", + "RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3ClauseFlagshipBaseCondition", + "RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3ClauseFlagshipLogicalCondition4", + "RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3ClauseFlagshipLogicalCondition4Clause", "RuleRollout", ] -class RuleConditionUnionMember0(BaseModel): +class RuleConditionFlagshipBaseCondition(BaseModel): attribute: str operator: Literal[ @@ -52,7 +50,7 @@ class RuleConditionUnionMember0(BaseModel): value: Union[Optional[str], float, bool, Dict[str, object], List[object]] -class RuleConditionUnionMember1ClauseUnionMember0(BaseModel): +class RuleConditionFlagshipLogicalConditionClauseFlagshipBaseCondition(BaseModel): attribute: str operator: Literal[ @@ -74,7 +72,7 @@ class RuleConditionUnionMember1ClauseUnionMember0(BaseModel): value: Union[Optional[str], float, bool, Dict[str, object], List[object]] -class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember0(BaseModel): +class RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipBaseCondition(BaseModel): attribute: str operator: Literal[ @@ -96,7 +94,9 @@ class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember0(BaseModel): value: Union[Optional[str], float, bool, Dict[str, object], List[object]] -class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0(BaseModel): +class RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipBaseCondition( + BaseModel +): attribute: str operator: Literal[ @@ -118,7 +118,9 @@ class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMe value: Union[Optional[str], float, bool, Dict[str, object], List[object]] -class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0(BaseModel): +class RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3ClauseFlagshipBaseCondition( + BaseModel +): attribute: str operator: Literal[ @@ -140,7 +142,7 @@ class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMe value: Union[Optional[str], float, bool, Dict[str, object], List[object]] -class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0( +class RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3ClauseFlagshipLogicalCondition4Clause( BaseModel ): attribute: str @@ -164,76 +166,71 @@ class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMe value: Union[Optional[str], float, bool, Dict[str, object], List[object]] -class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1( +class RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3ClauseFlagshipLogicalCondition4( BaseModel ): - clauses: List[Union[Optional[str], float, bool, Dict[str, object], List[object]]] - - logical_operator: Literal["AND", "OR"] - - -RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause: TypeAlias = Union[ - RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0, - RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1, -] - - -class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1(BaseModel): clauses: List[ - RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause + RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3ClauseFlagshipLogicalCondition4Clause ] logical_operator: Literal["AND", "OR"] -RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause: TypeAlias = Union[ - RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0, - RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1, +RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3Clause: TypeAlias = Union[ + RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3ClauseFlagshipBaseCondition, + RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3ClauseFlagshipLogicalCondition4, ] -class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1(BaseModel): - clauses: List[RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause] +class RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3( + BaseModel +): + clauses: List[ + RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3Clause + ] logical_operator: Literal["AND", "OR"] -RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1Clause: TypeAlias = Union[ - RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0, - RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1, +RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2Clause: TypeAlias = Union[ + RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipBaseCondition, + RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3, ] -class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1(BaseModel): - clauses: List[RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1Clause] +class RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2(BaseModel): + clauses: List[ + RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2Clause + ] logical_operator: Literal["AND", "OR"] -RuleConditionUnionMember1ClauseUnionMember1Clause: TypeAlias = Union[ - RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember0, - RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1, +RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1Clause: TypeAlias = Union[ + RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipBaseCondition, + RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2, ] -class RuleConditionUnionMember1ClauseUnionMember1(BaseModel): - clauses: List[RuleConditionUnionMember1ClauseUnionMember1Clause] +class RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1(BaseModel): + clauses: List[RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1Clause] logical_operator: Literal["AND", "OR"] -RuleConditionUnionMember1Clause: TypeAlias = Union[ - RuleConditionUnionMember1ClauseUnionMember0, RuleConditionUnionMember1ClauseUnionMember1 +RuleConditionFlagshipLogicalConditionClause: TypeAlias = Union[ + RuleConditionFlagshipLogicalConditionClauseFlagshipBaseCondition, + RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1, ] -class RuleConditionUnionMember1(BaseModel): - clauses: List[RuleConditionUnionMember1Clause] +class RuleConditionFlagshipLogicalCondition(BaseModel): + clauses: List[RuleConditionFlagshipLogicalConditionClause] logical_operator: Literal["AND", "OR"] -RuleCondition: TypeAlias = Union[RuleConditionUnionMember0, RuleConditionUnionMember1] +RuleCondition: TypeAlias = Union[RuleConditionFlagshipBaseCondition, RuleConditionFlagshipLogicalCondition] class RuleRollout(BaseModel): @@ -306,6 +303,12 @@ class FlagGetResponse(BaseModel): description: Optional[str] = None """Optional operator-facing description. It does not affect flag evaluation.""" + metadata: Optional[Dict[str, Union[bool, str, float]]] = None + """Key-value metadata associated with the flag. + + Returned only when the flag has metadata. + """ + updated_at: Optional[str] = None updated_by: Optional[str] = None diff --git a/src/cloudflare/types/flagship/apps/flag_list_response.py b/src/cloudflare/types/flagship/apps/flag_list_response.py index d59f5a113e4..8b81c99242d 100644 --- a/src/cloudflare/types/flagship/apps/flag_list_response.py +++ b/src/cloudflare/types/flagship/apps/flag_list_response.py @@ -9,28 +9,26 @@ "FlagListResponse", "Rule", "RuleCondition", - "RuleConditionUnionMember0", - "RuleConditionUnionMember1", - "RuleConditionUnionMember1Clause", - "RuleConditionUnionMember1ClauseUnionMember0", - "RuleConditionUnionMember1ClauseUnionMember1", - "RuleConditionUnionMember1ClauseUnionMember1Clause", - "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember0", - "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1", - "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1Clause", - "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0", - "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1", - "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause", - "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0", - "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1", - "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause", - "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0", - "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1", + "RuleConditionFlagshipBaseCondition", + "RuleConditionFlagshipLogicalCondition", + "RuleConditionFlagshipLogicalConditionClause", + "RuleConditionFlagshipLogicalConditionClauseFlagshipBaseCondition", + "RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1", + "RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1Clause", + "RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipBaseCondition", + "RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2", + "RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2Clause", + "RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipBaseCondition", + "RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3", + "RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3Clause", + "RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3ClauseFlagshipBaseCondition", + "RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3ClauseFlagshipLogicalCondition4", + "RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3ClauseFlagshipLogicalCondition4Clause", "RuleRollout", ] -class RuleConditionUnionMember0(BaseModel): +class RuleConditionFlagshipBaseCondition(BaseModel): attribute: str operator: Literal[ @@ -52,7 +50,7 @@ class RuleConditionUnionMember0(BaseModel): value: Union[Optional[str], float, bool, Dict[str, object], List[object]] -class RuleConditionUnionMember1ClauseUnionMember0(BaseModel): +class RuleConditionFlagshipLogicalConditionClauseFlagshipBaseCondition(BaseModel): attribute: str operator: Literal[ @@ -74,7 +72,7 @@ class RuleConditionUnionMember1ClauseUnionMember0(BaseModel): value: Union[Optional[str], float, bool, Dict[str, object], List[object]] -class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember0(BaseModel): +class RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipBaseCondition(BaseModel): attribute: str operator: Literal[ @@ -96,7 +94,9 @@ class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember0(BaseModel): value: Union[Optional[str], float, bool, Dict[str, object], List[object]] -class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0(BaseModel): +class RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipBaseCondition( + BaseModel +): attribute: str operator: Literal[ @@ -118,7 +118,9 @@ class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMe value: Union[Optional[str], float, bool, Dict[str, object], List[object]] -class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0(BaseModel): +class RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3ClauseFlagshipBaseCondition( + BaseModel +): attribute: str operator: Literal[ @@ -140,7 +142,7 @@ class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMe value: Union[Optional[str], float, bool, Dict[str, object], List[object]] -class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0( +class RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3ClauseFlagshipLogicalCondition4Clause( BaseModel ): attribute: str @@ -164,76 +166,71 @@ class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMe value: Union[Optional[str], float, bool, Dict[str, object], List[object]] -class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1( +class RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3ClauseFlagshipLogicalCondition4( BaseModel ): - clauses: List[Union[Optional[str], float, bool, Dict[str, object], List[object]]] - - logical_operator: Literal["AND", "OR"] - - -RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause: TypeAlias = Union[ - RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0, - RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1, -] - - -class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1(BaseModel): clauses: List[ - RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause + RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3ClauseFlagshipLogicalCondition4Clause ] logical_operator: Literal["AND", "OR"] -RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause: TypeAlias = Union[ - RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0, - RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1, +RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3Clause: TypeAlias = Union[ + RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3ClauseFlagshipBaseCondition, + RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3ClauseFlagshipLogicalCondition4, ] -class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1(BaseModel): - clauses: List[RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause] +class RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3( + BaseModel +): + clauses: List[ + RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3Clause + ] logical_operator: Literal["AND", "OR"] -RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1Clause: TypeAlias = Union[ - RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0, - RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1, +RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2Clause: TypeAlias = Union[ + RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipBaseCondition, + RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3, ] -class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1(BaseModel): - clauses: List[RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1Clause] +class RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2(BaseModel): + clauses: List[ + RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2Clause + ] logical_operator: Literal["AND", "OR"] -RuleConditionUnionMember1ClauseUnionMember1Clause: TypeAlias = Union[ - RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember0, - RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1, +RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1Clause: TypeAlias = Union[ + RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipBaseCondition, + RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2, ] -class RuleConditionUnionMember1ClauseUnionMember1(BaseModel): - clauses: List[RuleConditionUnionMember1ClauseUnionMember1Clause] +class RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1(BaseModel): + clauses: List[RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1Clause] logical_operator: Literal["AND", "OR"] -RuleConditionUnionMember1Clause: TypeAlias = Union[ - RuleConditionUnionMember1ClauseUnionMember0, RuleConditionUnionMember1ClauseUnionMember1 +RuleConditionFlagshipLogicalConditionClause: TypeAlias = Union[ + RuleConditionFlagshipLogicalConditionClauseFlagshipBaseCondition, + RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1, ] -class RuleConditionUnionMember1(BaseModel): - clauses: List[RuleConditionUnionMember1Clause] +class RuleConditionFlagshipLogicalCondition(BaseModel): + clauses: List[RuleConditionFlagshipLogicalConditionClause] logical_operator: Literal["AND", "OR"] -RuleCondition: TypeAlias = Union[RuleConditionUnionMember0, RuleConditionUnionMember1] +RuleCondition: TypeAlias = Union[RuleConditionFlagshipBaseCondition, RuleConditionFlagshipLogicalCondition] class RuleRollout(BaseModel): @@ -306,6 +303,12 @@ class FlagListResponse(BaseModel): description: Optional[str] = None """Optional operator-facing description. It does not affect flag evaluation.""" + metadata: Optional[Dict[str, Union[bool, str, float]]] = None + """Key-value metadata associated with the flag. + + Returned only when the flag has metadata. + """ + updated_at: Optional[str] = None updated_by: Optional[str] = None diff --git a/src/cloudflare/types/flagship/apps/flag_update_params.py b/src/cloudflare/types/flagship/apps/flag_update_params.py index 2fb8a967d40..377b5893e22 100644 --- a/src/cloudflare/types/flagship/apps/flag_update_params.py +++ b/src/cloudflare/types/flagship/apps/flag_update_params.py @@ -5,29 +5,25 @@ from typing import Dict, Union, Iterable, Optional from typing_extensions import Literal, Required, TypeAlias, TypedDict -from ...._types import SequenceNotStr - __all__ = [ "FlagUpdateParams", "Rule", "RuleCondition", - "RuleConditionUnionMember0", - "RuleConditionUnionMember1", - "RuleConditionUnionMember1Clause", - "RuleConditionUnionMember1ClauseUnionMember0", - "RuleConditionUnionMember1ClauseUnionMember1", - "RuleConditionUnionMember1ClauseUnionMember1Clause", - "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember0", - "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1", - "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1Clause", - "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0", - "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1", - "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause", - "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0", - "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1", - "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause", - "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0", - "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1", + "RuleConditionFlagshipBaseCondition", + "RuleConditionFlagshipLogicalCondition", + "RuleConditionFlagshipLogicalConditionClause", + "RuleConditionFlagshipLogicalConditionClauseFlagshipBaseCondition", + "RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1", + "RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1Clause", + "RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipBaseCondition", + "RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2", + "RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2Clause", + "RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipBaseCondition", + "RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3", + "RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3Clause", + "RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3ClauseFlagshipBaseCondition", + "RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3ClauseFlagshipLogicalCondition4", + "RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3ClauseFlagshipLogicalCondition4Clause", "RuleRollout", ] @@ -70,6 +66,13 @@ class FlagUpdateParams(TypedDict, total=False): description: Optional[str] """Optional operator-facing description. It does not affect flag evaluation.""" + metadata: Optional[Dict[str, Union[bool, str, float]]] + """Key-value metadata associated with the flag. + + `null` or an empty object clears existing metadata; omission semantics depend on + the endpoint (PUT clears it, PATCH preserves it). + """ + type: Literal["boolean", "string", "number", "json"] """Deprecated compatibility field. @@ -78,7 +81,7 @@ class FlagUpdateParams(TypedDict, total=False): """ -class RuleConditionUnionMember0(TypedDict, total=False): +class RuleConditionFlagshipBaseCondition(TypedDict, total=False): attribute: Required[str] operator: Required[ @@ -102,7 +105,7 @@ class RuleConditionUnionMember0(TypedDict, total=False): value: Required[Union[Optional[str], float, bool, Dict[str, object], Iterable[object]]] -class RuleConditionUnionMember1ClauseUnionMember0(TypedDict, total=False): +class RuleConditionFlagshipLogicalConditionClauseFlagshipBaseCondition(TypedDict, total=False): attribute: Required[str] operator: Required[ @@ -126,7 +129,9 @@ class RuleConditionUnionMember1ClauseUnionMember0(TypedDict, total=False): value: Required[Union[Optional[str], float, bool, Dict[str, object], Iterable[object]]] -class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember0(TypedDict, total=False): +class RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipBaseCondition( + TypedDict, total=False +): attribute: Required[str] operator: Required[ @@ -150,7 +155,9 @@ class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember0(TypedDict, t value: Required[Union[Optional[str], float, bool, Dict[str, object], Iterable[object]]] -class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0(TypedDict, total=False): +class RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipBaseCondition( + TypedDict, total=False +): attribute: Required[str] operator: Required[ @@ -174,7 +181,7 @@ class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMe value: Required[Union[Optional[str], float, bool, Dict[str, object], Iterable[object]]] -class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0( +class RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3ClauseFlagshipBaseCondition( TypedDict, total=False ): attribute: Required[str] @@ -200,7 +207,7 @@ class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMe value: Required[Union[Optional[str], float, bool, Dict[str, object], Iterable[object]]] -class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0( +class RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3ClauseFlagshipLogicalCondition4Clause( TypedDict, total=False ): attribute: Required[str] @@ -226,80 +233,79 @@ class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMe value: Required[Union[Optional[str], float, bool, Dict[str, object], Iterable[object]]] -class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1( +class RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3ClauseFlagshipLogicalCondition4( TypedDict, total=False ): - clauses: Required[SequenceNotStr[Union[Optional[str], float, bool, Dict[str, object], Iterable[object]]]] + clauses: Required[ + Iterable[ + RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3ClauseFlagshipLogicalCondition4Clause + ] + ] logical_operator: Required[Literal["AND", "OR"]] -RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause: TypeAlias = Union[ - RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0, - RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1, +RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3Clause: TypeAlias = Union[ + RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3ClauseFlagshipBaseCondition, + RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3ClauseFlagshipLogicalCondition4, ] -class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1( +class RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3( TypedDict, total=False ): clauses: Required[ Iterable[ - RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause + RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3Clause ] ] logical_operator: Required[Literal["AND", "OR"]] -RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause: TypeAlias = Union[ - RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0, - RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1, +RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2Clause: TypeAlias = Union[ + RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipBaseCondition, + RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3, ] -class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1(TypedDict, total=False): - clauses: Required[Iterable[RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause]] - - logical_operator: Required[Literal["AND", "OR"]] - - -RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1Clause: TypeAlias = Union[ - RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0, - RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1, -] - - -class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1(TypedDict, total=False): - clauses: Required[Iterable[RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1Clause]] +class RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2( + TypedDict, total=False +): + clauses: Required[ + Iterable[ + RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2Clause + ] + ] logical_operator: Required[Literal["AND", "OR"]] -RuleConditionUnionMember1ClauseUnionMember1Clause: TypeAlias = Union[ - RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember0, - RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1, +RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1Clause: TypeAlias = Union[ + RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipBaseCondition, + RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2, ] -class RuleConditionUnionMember1ClauseUnionMember1(TypedDict, total=False): - clauses: Required[Iterable[RuleConditionUnionMember1ClauseUnionMember1Clause]] +class RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1(TypedDict, total=False): + clauses: Required[Iterable[RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1Clause]] logical_operator: Required[Literal["AND", "OR"]] -RuleConditionUnionMember1Clause: TypeAlias = Union[ - RuleConditionUnionMember1ClauseUnionMember0, RuleConditionUnionMember1ClauseUnionMember1 +RuleConditionFlagshipLogicalConditionClause: TypeAlias = Union[ + RuleConditionFlagshipLogicalConditionClauseFlagshipBaseCondition, + RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1, ] -class RuleConditionUnionMember1(TypedDict, total=False): - clauses: Required[Iterable[RuleConditionUnionMember1Clause]] +class RuleConditionFlagshipLogicalCondition(TypedDict, total=False): + clauses: Required[Iterable[RuleConditionFlagshipLogicalConditionClause]] logical_operator: Required[Literal["AND", "OR"]] -RuleCondition: TypeAlias = Union[RuleConditionUnionMember0, RuleConditionUnionMember1] +RuleCondition: TypeAlias = Union[RuleConditionFlagshipBaseCondition, RuleConditionFlagshipLogicalCondition] class RuleRollout(TypedDict, total=False): diff --git a/src/cloudflare/types/flagship/apps/flag_update_response.py b/src/cloudflare/types/flagship/apps/flag_update_response.py index 56c300f3c90..3ba7050851a 100644 --- a/src/cloudflare/types/flagship/apps/flag_update_response.py +++ b/src/cloudflare/types/flagship/apps/flag_update_response.py @@ -9,28 +9,26 @@ "FlagUpdateResponse", "Rule", "RuleCondition", - "RuleConditionUnionMember0", - "RuleConditionUnionMember1", - "RuleConditionUnionMember1Clause", - "RuleConditionUnionMember1ClauseUnionMember0", - "RuleConditionUnionMember1ClauseUnionMember1", - "RuleConditionUnionMember1ClauseUnionMember1Clause", - "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember0", - "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1", - "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1Clause", - "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0", - "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1", - "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause", - "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0", - "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1", - "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause", - "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0", - "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1", + "RuleConditionFlagshipBaseCondition", + "RuleConditionFlagshipLogicalCondition", + "RuleConditionFlagshipLogicalConditionClause", + "RuleConditionFlagshipLogicalConditionClauseFlagshipBaseCondition", + "RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1", + "RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1Clause", + "RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipBaseCondition", + "RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2", + "RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2Clause", + "RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipBaseCondition", + "RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3", + "RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3Clause", + "RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3ClauseFlagshipBaseCondition", + "RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3ClauseFlagshipLogicalCondition4", + "RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3ClauseFlagshipLogicalCondition4Clause", "RuleRollout", ] -class RuleConditionUnionMember0(BaseModel): +class RuleConditionFlagshipBaseCondition(BaseModel): attribute: str operator: Literal[ @@ -52,7 +50,7 @@ class RuleConditionUnionMember0(BaseModel): value: Union[Optional[str], float, bool, Dict[str, object], List[object]] -class RuleConditionUnionMember1ClauseUnionMember0(BaseModel): +class RuleConditionFlagshipLogicalConditionClauseFlagshipBaseCondition(BaseModel): attribute: str operator: Literal[ @@ -74,7 +72,7 @@ class RuleConditionUnionMember1ClauseUnionMember0(BaseModel): value: Union[Optional[str], float, bool, Dict[str, object], List[object]] -class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember0(BaseModel): +class RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipBaseCondition(BaseModel): attribute: str operator: Literal[ @@ -96,7 +94,9 @@ class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember0(BaseModel): value: Union[Optional[str], float, bool, Dict[str, object], List[object]] -class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0(BaseModel): +class RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipBaseCondition( + BaseModel +): attribute: str operator: Literal[ @@ -118,7 +118,9 @@ class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMe value: Union[Optional[str], float, bool, Dict[str, object], List[object]] -class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0(BaseModel): +class RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3ClauseFlagshipBaseCondition( + BaseModel +): attribute: str operator: Literal[ @@ -140,7 +142,7 @@ class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMe value: Union[Optional[str], float, bool, Dict[str, object], List[object]] -class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0( +class RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3ClauseFlagshipLogicalCondition4Clause( BaseModel ): attribute: str @@ -164,76 +166,71 @@ class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMe value: Union[Optional[str], float, bool, Dict[str, object], List[object]] -class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1( +class RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3ClauseFlagshipLogicalCondition4( BaseModel ): - clauses: List[Union[Optional[str], float, bool, Dict[str, object], List[object]]] - - logical_operator: Literal["AND", "OR"] - - -RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause: TypeAlias = Union[ - RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0, - RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1, -] - - -class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1(BaseModel): clauses: List[ - RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause + RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3ClauseFlagshipLogicalCondition4Clause ] logical_operator: Literal["AND", "OR"] -RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause: TypeAlias = Union[ - RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0, - RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1, +RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3Clause: TypeAlias = Union[ + RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3ClauseFlagshipBaseCondition, + RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3ClauseFlagshipLogicalCondition4, ] -class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1(BaseModel): - clauses: List[RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause] +class RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3( + BaseModel +): + clauses: List[ + RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3Clause + ] logical_operator: Literal["AND", "OR"] -RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1Clause: TypeAlias = Union[ - RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0, - RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1, +RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2Clause: TypeAlias = Union[ + RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipBaseCondition, + RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3, ] -class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1(BaseModel): - clauses: List[RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1Clause] +class RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2(BaseModel): + clauses: List[ + RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2Clause + ] logical_operator: Literal["AND", "OR"] -RuleConditionUnionMember1ClauseUnionMember1Clause: TypeAlias = Union[ - RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember0, - RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1, +RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1Clause: TypeAlias = Union[ + RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipBaseCondition, + RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2, ] -class RuleConditionUnionMember1ClauseUnionMember1(BaseModel): - clauses: List[RuleConditionUnionMember1ClauseUnionMember1Clause] +class RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1(BaseModel): + clauses: List[RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1Clause] logical_operator: Literal["AND", "OR"] -RuleConditionUnionMember1Clause: TypeAlias = Union[ - RuleConditionUnionMember1ClauseUnionMember0, RuleConditionUnionMember1ClauseUnionMember1 +RuleConditionFlagshipLogicalConditionClause: TypeAlias = Union[ + RuleConditionFlagshipLogicalConditionClauseFlagshipBaseCondition, + RuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1, ] -class RuleConditionUnionMember1(BaseModel): - clauses: List[RuleConditionUnionMember1Clause] +class RuleConditionFlagshipLogicalCondition(BaseModel): + clauses: List[RuleConditionFlagshipLogicalConditionClause] logical_operator: Literal["AND", "OR"] -RuleCondition: TypeAlias = Union[RuleConditionUnionMember0, RuleConditionUnionMember1] +RuleCondition: TypeAlias = Union[RuleConditionFlagshipBaseCondition, RuleConditionFlagshipLogicalCondition] class RuleRollout(BaseModel): @@ -306,6 +303,12 @@ class FlagUpdateResponse(BaseModel): description: Optional[str] = None """Optional operator-facing description. It does not affect flag evaluation.""" + metadata: Optional[Dict[str, Union[bool, str, float]]] = None + """Key-value metadata associated with the flag. + + Returned only when the flag has metadata. + """ + updated_at: Optional[str] = None updated_by: Optional[str] = None diff --git a/src/cloudflare/types/flagship/apps/flags/changelog_list_response.py b/src/cloudflare/types/flagship/apps/flags/changelog_list_response.py index 79437c518a9..2cfc2147f81 100644 --- a/src/cloudflare/types/flagship/apps/flags/changelog_list_response.py +++ b/src/cloudflare/types/flagship/apps/flags/changelog_list_response.py @@ -13,73 +13,67 @@ "UnionMember0After", "UnionMember0AfterRule", "UnionMember0AfterRuleCondition", - "UnionMember0AfterRuleConditionUnionMember0", - "UnionMember0AfterRuleConditionUnionMember1", - "UnionMember0AfterRuleConditionUnionMember1Clause", - "UnionMember0AfterRuleConditionUnionMember1ClauseUnionMember0", - "UnionMember0AfterRuleConditionUnionMember1ClauseUnionMember1", - "UnionMember0AfterRuleConditionUnionMember1ClauseUnionMember1Clause", - "UnionMember0AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember0", - "UnionMember0AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1", - "UnionMember0AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1Clause", - "UnionMember0AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0", - "UnionMember0AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1", - "UnionMember0AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause", - "UnionMember0AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0", - "UnionMember0AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1", - "UnionMember0AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause", - "UnionMember0AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0", - "UnionMember0AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1", + "UnionMember0AfterRuleConditionFlagshipBaseCondition", + "UnionMember0AfterRuleConditionFlagshipLogicalCondition", + "UnionMember0AfterRuleConditionFlagshipLogicalConditionClause", + "UnionMember0AfterRuleConditionFlagshipLogicalConditionClauseFlagshipBaseCondition", + "UnionMember0AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1", + "UnionMember0AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1Clause", + "UnionMember0AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipBaseCondition", + "UnionMember0AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2", + "UnionMember0AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2Clause", + "UnionMember0AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipBaseCondition", + "UnionMember0AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3", + "UnionMember0AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3Clause", + "UnionMember0AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3ClauseFlagshipBaseCondition", + "UnionMember0AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3ClauseFlagshipLogicalCondition4", + "UnionMember0AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3ClauseFlagshipLogicalCondition4Clause", "UnionMember0AfterRuleRollout", "UnionMember1", "UnionMember1After", "UnionMember1AfterRule", "UnionMember1AfterRuleCondition", - "UnionMember1AfterRuleConditionUnionMember0", - "UnionMember1AfterRuleConditionUnionMember1", - "UnionMember1AfterRuleConditionUnionMember1Clause", - "UnionMember1AfterRuleConditionUnionMember1ClauseUnionMember0", - "UnionMember1AfterRuleConditionUnionMember1ClauseUnionMember1", - "UnionMember1AfterRuleConditionUnionMember1ClauseUnionMember1Clause", - "UnionMember1AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember0", - "UnionMember1AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1", - "UnionMember1AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1Clause", - "UnionMember1AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0", - "UnionMember1AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1", - "UnionMember1AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause", - "UnionMember1AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0", - "UnionMember1AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1", - "UnionMember1AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause", - "UnionMember1AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0", - "UnionMember1AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1", + "UnionMember1AfterRuleConditionFlagshipBaseCondition", + "UnionMember1AfterRuleConditionFlagshipLogicalCondition", + "UnionMember1AfterRuleConditionFlagshipLogicalConditionClause", + "UnionMember1AfterRuleConditionFlagshipLogicalConditionClauseFlagshipBaseCondition", + "UnionMember1AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1", + "UnionMember1AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1Clause", + "UnionMember1AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipBaseCondition", + "UnionMember1AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2", + "UnionMember1AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2Clause", + "UnionMember1AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipBaseCondition", + "UnionMember1AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3", + "UnionMember1AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3Clause", + "UnionMember1AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3ClauseFlagshipBaseCondition", + "UnionMember1AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3ClauseFlagshipLogicalCondition4", + "UnionMember1AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3ClauseFlagshipLogicalCondition4Clause", "UnionMember1AfterRuleRollout", "UnionMember2", "UnionMember2After", "UnionMember2AfterRule", "UnionMember2AfterRuleCondition", - "UnionMember2AfterRuleConditionUnionMember0", - "UnionMember2AfterRuleConditionUnionMember1", - "UnionMember2AfterRuleConditionUnionMember1Clause", - "UnionMember2AfterRuleConditionUnionMember1ClauseUnionMember0", - "UnionMember2AfterRuleConditionUnionMember1ClauseUnionMember1", - "UnionMember2AfterRuleConditionUnionMember1ClauseUnionMember1Clause", - "UnionMember2AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember0", - "UnionMember2AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1", - "UnionMember2AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1Clause", - "UnionMember2AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0", - "UnionMember2AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1", - "UnionMember2AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause", - "UnionMember2AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0", - "UnionMember2AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1", - "UnionMember2AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause", - "UnionMember2AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0", - "UnionMember2AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1", + "UnionMember2AfterRuleConditionFlagshipBaseCondition", + "UnionMember2AfterRuleConditionFlagshipLogicalCondition", + "UnionMember2AfterRuleConditionFlagshipLogicalConditionClause", + "UnionMember2AfterRuleConditionFlagshipLogicalConditionClauseFlagshipBaseCondition", + "UnionMember2AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1", + "UnionMember2AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1Clause", + "UnionMember2AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipBaseCondition", + "UnionMember2AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2", + "UnionMember2AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2Clause", + "UnionMember2AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipBaseCondition", + "UnionMember2AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3", + "UnionMember2AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3Clause", + "UnionMember2AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3ClauseFlagshipBaseCondition", + "UnionMember2AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3ClauseFlagshipLogicalCondition4", + "UnionMember2AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3ClauseFlagshipLogicalCondition4Clause", "UnionMember2AfterRuleRollout", "UnionMember2Diff", ] -class UnionMember0AfterRuleConditionUnionMember0(BaseModel): +class UnionMember0AfterRuleConditionFlagshipBaseCondition(BaseModel): attribute: str operator: Literal[ @@ -101,7 +95,7 @@ class UnionMember0AfterRuleConditionUnionMember0(BaseModel): value: Union[Optional[str], float, bool, Dict[str, object], List[object]] -class UnionMember0AfterRuleConditionUnionMember1ClauseUnionMember0(BaseModel): +class UnionMember0AfterRuleConditionFlagshipLogicalConditionClauseFlagshipBaseCondition(BaseModel): attribute: str operator: Literal[ @@ -123,7 +117,9 @@ class UnionMember0AfterRuleConditionUnionMember1ClauseUnionMember0(BaseModel): value: Union[Optional[str], float, bool, Dict[str, object], List[object]] -class UnionMember0AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember0(BaseModel): +class UnionMember0AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipBaseCondition( + BaseModel +): attribute: str operator: Literal[ @@ -145,7 +141,9 @@ class UnionMember0AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMem value: Union[Optional[str], float, bool, Dict[str, object], List[object]] -class UnionMember0AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0(BaseModel): +class UnionMember0AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipBaseCondition( + BaseModel +): attribute: str operator: Literal[ @@ -167,7 +165,7 @@ class UnionMember0AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMem value: Union[Optional[str], float, bool, Dict[str, object], List[object]] -class UnionMember0AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0( +class UnionMember0AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3ClauseFlagshipBaseCondition( BaseModel ): attribute: str @@ -191,7 +189,7 @@ class UnionMember0AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMem value: Union[Optional[str], float, bool, Dict[str, object], List[object]] -class UnionMember0AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0( +class UnionMember0AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3ClauseFlagshipLogicalCondition4Clause( BaseModel ): attribute: str @@ -215,82 +213,74 @@ class UnionMember0AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMem value: Union[Optional[str], float, bool, Dict[str, object], List[object]] -class UnionMember0AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1( +class UnionMember0AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3ClauseFlagshipLogicalCondition4( BaseModel ): - clauses: List[Union[Optional[str], float, bool, Dict[str, object], List[object]]] + clauses: List[ + UnionMember0AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3ClauseFlagshipLogicalCondition4Clause + ] logical_operator: Literal["AND", "OR"] -UnionMember0AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause: TypeAlias = Union[ - UnionMember0AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0, - UnionMember0AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1, +UnionMember0AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3Clause: TypeAlias = Union[ + UnionMember0AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3ClauseFlagshipBaseCondition, + UnionMember0AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3ClauseFlagshipLogicalCondition4, ] -class UnionMember0AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1( +class UnionMember0AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3( BaseModel ): clauses: List[ - UnionMember0AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause + UnionMember0AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3Clause ] logical_operator: Literal["AND", "OR"] -UnionMember0AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause: TypeAlias = Union[ - UnionMember0AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0, - UnionMember0AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1, +UnionMember0AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2Clause: TypeAlias = Union[ + UnionMember0AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipBaseCondition, + UnionMember0AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3, ] -class UnionMember0AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1(BaseModel): +class UnionMember0AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2( + BaseModel +): clauses: List[ - UnionMember0AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause + UnionMember0AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2Clause ] logical_operator: Literal["AND", "OR"] -UnionMember0AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1Clause: TypeAlias = Union[ - UnionMember0AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0, - UnionMember0AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1, +UnionMember0AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1Clause: TypeAlias = Union[ + UnionMember0AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipBaseCondition, + UnionMember0AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2, ] -class UnionMember0AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1(BaseModel): - clauses: List[UnionMember0AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1Clause] +class UnionMember0AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1(BaseModel): + clauses: List[UnionMember0AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1Clause] logical_operator: Literal["AND", "OR"] -UnionMember0AfterRuleConditionUnionMember1ClauseUnionMember1Clause: TypeAlias = Union[ - UnionMember0AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember0, - UnionMember0AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1, +UnionMember0AfterRuleConditionFlagshipLogicalConditionClause: TypeAlias = Union[ + UnionMember0AfterRuleConditionFlagshipLogicalConditionClauseFlagshipBaseCondition, + UnionMember0AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1, ] -class UnionMember0AfterRuleConditionUnionMember1ClauseUnionMember1(BaseModel): - clauses: List[UnionMember0AfterRuleConditionUnionMember1ClauseUnionMember1Clause] - - logical_operator: Literal["AND", "OR"] - - -UnionMember0AfterRuleConditionUnionMember1Clause: TypeAlias = Union[ - UnionMember0AfterRuleConditionUnionMember1ClauseUnionMember0, - UnionMember0AfterRuleConditionUnionMember1ClauseUnionMember1, -] - - -class UnionMember0AfterRuleConditionUnionMember1(BaseModel): - clauses: List[UnionMember0AfterRuleConditionUnionMember1Clause] +class UnionMember0AfterRuleConditionFlagshipLogicalCondition(BaseModel): + clauses: List[UnionMember0AfterRuleConditionFlagshipLogicalConditionClause] logical_operator: Literal["AND", "OR"] UnionMember0AfterRuleCondition: TypeAlias = Union[ - UnionMember0AfterRuleConditionUnionMember0, UnionMember0AfterRuleConditionUnionMember1 + UnionMember0AfterRuleConditionFlagshipBaseCondition, UnionMember0AfterRuleConditionFlagshipLogicalCondition ] @@ -364,6 +354,12 @@ class UnionMember0After(BaseModel): description: Optional[str] = None """Optional operator-facing description. It does not affect flag evaluation.""" + metadata: Optional[Dict[str, Union[bool, str, float]]] = None + """Key-value metadata associated with the flag. + + Returned only when the flag has metadata. + """ + updated_at: Optional[str] = None updated_by: Optional[str] = None @@ -377,7 +373,7 @@ class UnionMember0(BaseModel): flag_key: str -class UnionMember1AfterRuleConditionUnionMember0(BaseModel): +class UnionMember1AfterRuleConditionFlagshipBaseCondition(BaseModel): attribute: str operator: Literal[ @@ -399,7 +395,7 @@ class UnionMember1AfterRuleConditionUnionMember0(BaseModel): value: Union[Optional[str], float, bool, Dict[str, object], List[object]] -class UnionMember1AfterRuleConditionUnionMember1ClauseUnionMember0(BaseModel): +class UnionMember1AfterRuleConditionFlagshipLogicalConditionClauseFlagshipBaseCondition(BaseModel): attribute: str operator: Literal[ @@ -421,7 +417,9 @@ class UnionMember1AfterRuleConditionUnionMember1ClauseUnionMember0(BaseModel): value: Union[Optional[str], float, bool, Dict[str, object], List[object]] -class UnionMember1AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember0(BaseModel): +class UnionMember1AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipBaseCondition( + BaseModel +): attribute: str operator: Literal[ @@ -443,7 +441,9 @@ class UnionMember1AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMem value: Union[Optional[str], float, bool, Dict[str, object], List[object]] -class UnionMember1AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0(BaseModel): +class UnionMember1AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipBaseCondition( + BaseModel +): attribute: str operator: Literal[ @@ -465,7 +465,7 @@ class UnionMember1AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMem value: Union[Optional[str], float, bool, Dict[str, object], List[object]] -class UnionMember1AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0( +class UnionMember1AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3ClauseFlagshipBaseCondition( BaseModel ): attribute: str @@ -489,7 +489,7 @@ class UnionMember1AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMem value: Union[Optional[str], float, bool, Dict[str, object], List[object]] -class UnionMember1AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0( +class UnionMember1AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3ClauseFlagshipLogicalCondition4Clause( BaseModel ): attribute: str @@ -513,82 +513,74 @@ class UnionMember1AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMem value: Union[Optional[str], float, bool, Dict[str, object], List[object]] -class UnionMember1AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1( +class UnionMember1AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3ClauseFlagshipLogicalCondition4( BaseModel ): - clauses: List[Union[Optional[str], float, bool, Dict[str, object], List[object]]] + clauses: List[ + UnionMember1AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3ClauseFlagshipLogicalCondition4Clause + ] logical_operator: Literal["AND", "OR"] -UnionMember1AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause: TypeAlias = Union[ - UnionMember1AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0, - UnionMember1AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1, +UnionMember1AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3Clause: TypeAlias = Union[ + UnionMember1AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3ClauseFlagshipBaseCondition, + UnionMember1AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3ClauseFlagshipLogicalCondition4, ] -class UnionMember1AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1( +class UnionMember1AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3( BaseModel ): clauses: List[ - UnionMember1AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause + UnionMember1AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3Clause ] logical_operator: Literal["AND", "OR"] -UnionMember1AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause: TypeAlias = Union[ - UnionMember1AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0, - UnionMember1AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1, +UnionMember1AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2Clause: TypeAlias = Union[ + UnionMember1AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipBaseCondition, + UnionMember1AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3, ] -class UnionMember1AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1(BaseModel): +class UnionMember1AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2( + BaseModel +): clauses: List[ - UnionMember1AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause + UnionMember1AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2Clause ] logical_operator: Literal["AND", "OR"] -UnionMember1AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1Clause: TypeAlias = Union[ - UnionMember1AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0, - UnionMember1AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1, -] - - -class UnionMember1AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1(BaseModel): - clauses: List[UnionMember1AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1Clause] - - logical_operator: Literal["AND", "OR"] - - -UnionMember1AfterRuleConditionUnionMember1ClauseUnionMember1Clause: TypeAlias = Union[ - UnionMember1AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember0, - UnionMember1AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1, +UnionMember1AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1Clause: TypeAlias = Union[ + UnionMember1AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipBaseCondition, + UnionMember1AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2, ] -class UnionMember1AfterRuleConditionUnionMember1ClauseUnionMember1(BaseModel): - clauses: List[UnionMember1AfterRuleConditionUnionMember1ClauseUnionMember1Clause] +class UnionMember1AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1(BaseModel): + clauses: List[UnionMember1AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1Clause] logical_operator: Literal["AND", "OR"] -UnionMember1AfterRuleConditionUnionMember1Clause: TypeAlias = Union[ - UnionMember1AfterRuleConditionUnionMember1ClauseUnionMember0, - UnionMember1AfterRuleConditionUnionMember1ClauseUnionMember1, +UnionMember1AfterRuleConditionFlagshipLogicalConditionClause: TypeAlias = Union[ + UnionMember1AfterRuleConditionFlagshipLogicalConditionClauseFlagshipBaseCondition, + UnionMember1AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1, ] -class UnionMember1AfterRuleConditionUnionMember1(BaseModel): - clauses: List[UnionMember1AfterRuleConditionUnionMember1Clause] +class UnionMember1AfterRuleConditionFlagshipLogicalCondition(BaseModel): + clauses: List[UnionMember1AfterRuleConditionFlagshipLogicalConditionClause] logical_operator: Literal["AND", "OR"] UnionMember1AfterRuleCondition: TypeAlias = Union[ - UnionMember1AfterRuleConditionUnionMember0, UnionMember1AfterRuleConditionUnionMember1 + UnionMember1AfterRuleConditionFlagshipBaseCondition, UnionMember1AfterRuleConditionFlagshipLogicalCondition ] @@ -662,6 +654,12 @@ class UnionMember1After(BaseModel): description: Optional[str] = None """Optional operator-facing description. It does not affect flag evaluation.""" + metadata: Optional[Dict[str, Union[bool, str, float]]] = None + """Key-value metadata associated with the flag. + + Returned only when the flag has metadata. + """ + updated_at: Optional[str] = None updated_by: Optional[str] = None @@ -675,7 +673,7 @@ class UnionMember1(BaseModel): flag_key: str -class UnionMember2AfterRuleConditionUnionMember0(BaseModel): +class UnionMember2AfterRuleConditionFlagshipBaseCondition(BaseModel): attribute: str operator: Literal[ @@ -697,7 +695,7 @@ class UnionMember2AfterRuleConditionUnionMember0(BaseModel): value: Union[Optional[str], float, bool, Dict[str, object], List[object]] -class UnionMember2AfterRuleConditionUnionMember1ClauseUnionMember0(BaseModel): +class UnionMember2AfterRuleConditionFlagshipLogicalConditionClauseFlagshipBaseCondition(BaseModel): attribute: str operator: Literal[ @@ -719,7 +717,9 @@ class UnionMember2AfterRuleConditionUnionMember1ClauseUnionMember0(BaseModel): value: Union[Optional[str], float, bool, Dict[str, object], List[object]] -class UnionMember2AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember0(BaseModel): +class UnionMember2AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipBaseCondition( + BaseModel +): attribute: str operator: Literal[ @@ -741,7 +741,9 @@ class UnionMember2AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMem value: Union[Optional[str], float, bool, Dict[str, object], List[object]] -class UnionMember2AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0(BaseModel): +class UnionMember2AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipBaseCondition( + BaseModel +): attribute: str operator: Literal[ @@ -763,7 +765,7 @@ class UnionMember2AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMem value: Union[Optional[str], float, bool, Dict[str, object], List[object]] -class UnionMember2AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0( +class UnionMember2AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3ClauseFlagshipBaseCondition( BaseModel ): attribute: str @@ -787,7 +789,7 @@ class UnionMember2AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMem value: Union[Optional[str], float, bool, Dict[str, object], List[object]] -class UnionMember2AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0( +class UnionMember2AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3ClauseFlagshipLogicalCondition4Clause( BaseModel ): attribute: str @@ -811,82 +813,74 @@ class UnionMember2AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMem value: Union[Optional[str], float, bool, Dict[str, object], List[object]] -class UnionMember2AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1( +class UnionMember2AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3ClauseFlagshipLogicalCondition4( BaseModel ): - clauses: List[Union[Optional[str], float, bool, Dict[str, object], List[object]]] + clauses: List[ + UnionMember2AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3ClauseFlagshipLogicalCondition4Clause + ] logical_operator: Literal["AND", "OR"] -UnionMember2AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause: TypeAlias = Union[ - UnionMember2AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0, - UnionMember2AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1, +UnionMember2AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3Clause: TypeAlias = Union[ + UnionMember2AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3ClauseFlagshipBaseCondition, + UnionMember2AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3ClauseFlagshipLogicalCondition4, ] -class UnionMember2AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1( +class UnionMember2AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3( BaseModel ): clauses: List[ - UnionMember2AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause + UnionMember2AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3Clause ] logical_operator: Literal["AND", "OR"] -UnionMember2AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause: TypeAlias = Union[ - UnionMember2AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0, - UnionMember2AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1, +UnionMember2AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2Clause: TypeAlias = Union[ + UnionMember2AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipBaseCondition, + UnionMember2AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2ClauseFlagshipLogicalCondition3, ] -class UnionMember2AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1(BaseModel): +class UnionMember2AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2( + BaseModel +): clauses: List[ - UnionMember2AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause + UnionMember2AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2Clause ] logical_operator: Literal["AND", "OR"] -UnionMember2AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1Clause: TypeAlias = Union[ - UnionMember2AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0, - UnionMember2AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1, +UnionMember2AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1Clause: TypeAlias = Union[ + UnionMember2AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipBaseCondition, + UnionMember2AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1ClauseFlagshipLogicalCondition2, ] -class UnionMember2AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1(BaseModel): - clauses: List[UnionMember2AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1Clause] +class UnionMember2AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1(BaseModel): + clauses: List[UnionMember2AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1Clause] logical_operator: Literal["AND", "OR"] -UnionMember2AfterRuleConditionUnionMember1ClauseUnionMember1Clause: TypeAlias = Union[ - UnionMember2AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember0, - UnionMember2AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1, +UnionMember2AfterRuleConditionFlagshipLogicalConditionClause: TypeAlias = Union[ + UnionMember2AfterRuleConditionFlagshipLogicalConditionClauseFlagshipBaseCondition, + UnionMember2AfterRuleConditionFlagshipLogicalConditionClauseFlagshipLogicalCondition1, ] -class UnionMember2AfterRuleConditionUnionMember1ClauseUnionMember1(BaseModel): - clauses: List[UnionMember2AfterRuleConditionUnionMember1ClauseUnionMember1Clause] - - logical_operator: Literal["AND", "OR"] - - -UnionMember2AfterRuleConditionUnionMember1Clause: TypeAlias = Union[ - UnionMember2AfterRuleConditionUnionMember1ClauseUnionMember0, - UnionMember2AfterRuleConditionUnionMember1ClauseUnionMember1, -] - - -class UnionMember2AfterRuleConditionUnionMember1(BaseModel): - clauses: List[UnionMember2AfterRuleConditionUnionMember1Clause] +class UnionMember2AfterRuleConditionFlagshipLogicalCondition(BaseModel): + clauses: List[UnionMember2AfterRuleConditionFlagshipLogicalConditionClause] logical_operator: Literal["AND", "OR"] UnionMember2AfterRuleCondition: TypeAlias = Union[ - UnionMember2AfterRuleConditionUnionMember0, UnionMember2AfterRuleConditionUnionMember1 + UnionMember2AfterRuleConditionFlagshipBaseCondition, UnionMember2AfterRuleConditionFlagshipLogicalCondition ] @@ -960,6 +954,12 @@ class UnionMember2After(BaseModel): description: Optional[str] = None """Optional operator-facing description. It does not affect flag evaluation.""" + metadata: Optional[Dict[str, Union[bool, str, float]]] = None + """Key-value metadata associated with the flag. + + Returned only when the flag has metadata. + """ + updated_at: Optional[str] = None updated_by: Optional[str] = None diff --git a/src/cloudflare/types/hyperdrive/config_create_params.py b/src/cloudflare/types/hyperdrive/config_create_params.py index 08cac86c880..bbf62b03177 100644 --- a/src/cloudflare/types/hyperdrive/config_create_params.py +++ b/src/cloudflare/types/hyperdrive/config_create_params.py @@ -214,10 +214,11 @@ class HyperdriveHyperdriveConfigCreateWithIntegration(TypedDict, total=False): """Define configurations using a unique string identifier.""" integration: Required[HyperdriveHyperdriveConfigCreateWithIntegrationIntegration] - """Connects to a PlanetScale database using credentials managed by Cloudflare. - - The Cloudflare account must already be linked to PlanetScale in the Hyperdrive - dashboard. + """ + Selects a PlanetScale database and provisions credentials managed by Cloudflare + when creating a Hyperdrive configuration. The Cloudflare account must already be + linked to PlanetScale in the Hyperdrive dashboard. The selection is returned as + read-only metadata and cannot be changed with replace or update operations. """ name: Required[str] @@ -249,9 +250,8 @@ class HyperdriveHyperdriveConfigCreateWithIntegration(TypedDict, total=False): class HyperdriveHyperdriveConfigCreateWithIntegrationIntegration(TypedDict, total=False): - """Connects to a PlanetScale database using credentials managed by Cloudflare. - - The Cloudflare account must already be linked to PlanetScale in the Hyperdrive dashboard. + """ + Selects a PlanetScale database and provisions credentials managed by Cloudflare when creating a Hyperdrive configuration. The Cloudflare account must already be linked to PlanetScale in the Hyperdrive dashboard. The selection is returned as read-only metadata and cannot be changed with replace or update operations. """ database_branch_name: Required[str] diff --git a/src/cloudflare/types/hyperdrive/config_create_response.py b/src/cloudflare/types/hyperdrive/config_create_response.py index 8f56b5f697a..a13b80957af 100644 --- a/src/cloudflare/types/hyperdrive/config_create_response.py +++ b/src/cloudflare/types/hyperdrive/config_create_response.py @@ -96,9 +96,8 @@ class OriginDatabaseReachableThroughAWorkersVPC(BaseModel): class Integration(BaseModel): - """Connects to a PlanetScale database using credentials managed by Cloudflare. - - The Cloudflare account must already be linked to PlanetScale in the Hyperdrive dashboard. + """ + Selects a PlanetScale database and provisions credentials managed by Cloudflare when creating a Hyperdrive configuration. The Cloudflare account must already be linked to PlanetScale in the Hyperdrive dashboard. The selection is returned as read-only metadata and cannot be changed with replace or update operations. """ database_branch_name: str @@ -165,10 +164,11 @@ class ConfigCreateResponse(BaseModel): """Defines the creation time of the Hyperdrive configuration.""" integration: Optional[Integration] = None - """Connects to a PlanetScale database using credentials managed by Cloudflare. - - The Cloudflare account must already be linked to PlanetScale in the Hyperdrive - dashboard. + """ + Selects a PlanetScale database and provisions credentials managed by Cloudflare + when creating a Hyperdrive configuration. The Cloudflare account must already be + linked to PlanetScale in the Hyperdrive dashboard. The selection is returned as + read-only metadata and cannot be changed with replace or update operations. """ modified_on: Optional[datetime] = None diff --git a/src/cloudflare/types/hyperdrive/config_edit_response.py b/src/cloudflare/types/hyperdrive/config_edit_response.py index 0d39d6b2a84..cdb6ff5dd30 100644 --- a/src/cloudflare/types/hyperdrive/config_edit_response.py +++ b/src/cloudflare/types/hyperdrive/config_edit_response.py @@ -96,9 +96,8 @@ class OriginDatabaseReachableThroughAWorkersVPC(BaseModel): class Integration(BaseModel): - """Connects to a PlanetScale database using credentials managed by Cloudflare. - - The Cloudflare account must already be linked to PlanetScale in the Hyperdrive dashboard. + """ + Selects a PlanetScale database and provisions credentials managed by Cloudflare when creating a Hyperdrive configuration. The Cloudflare account must already be linked to PlanetScale in the Hyperdrive dashboard. The selection is returned as read-only metadata and cannot be changed with replace or update operations. """ database_branch_name: str @@ -165,10 +164,11 @@ class ConfigEditResponse(BaseModel): """Defines the creation time of the Hyperdrive configuration.""" integration: Optional[Integration] = None - """Connects to a PlanetScale database using credentials managed by Cloudflare. - - The Cloudflare account must already be linked to PlanetScale in the Hyperdrive - dashboard. + """ + Selects a PlanetScale database and provisions credentials managed by Cloudflare + when creating a Hyperdrive configuration. The Cloudflare account must already be + linked to PlanetScale in the Hyperdrive dashboard. The selection is returned as + read-only metadata and cannot be changed with replace or update operations. """ modified_on: Optional[datetime] = None diff --git a/src/cloudflare/types/hyperdrive/config_get_response.py b/src/cloudflare/types/hyperdrive/config_get_response.py index 5748b048dfa..9271a02d312 100644 --- a/src/cloudflare/types/hyperdrive/config_get_response.py +++ b/src/cloudflare/types/hyperdrive/config_get_response.py @@ -96,9 +96,8 @@ class OriginDatabaseReachableThroughAWorkersVPC(BaseModel): class Integration(BaseModel): - """Connects to a PlanetScale database using credentials managed by Cloudflare. - - The Cloudflare account must already be linked to PlanetScale in the Hyperdrive dashboard. + """ + Selects a PlanetScale database and provisions credentials managed by Cloudflare when creating a Hyperdrive configuration. The Cloudflare account must already be linked to PlanetScale in the Hyperdrive dashboard. The selection is returned as read-only metadata and cannot be changed with replace or update operations. """ database_branch_name: str @@ -165,10 +164,11 @@ class ConfigGetResponse(BaseModel): """Defines the creation time of the Hyperdrive configuration.""" integration: Optional[Integration] = None - """Connects to a PlanetScale database using credentials managed by Cloudflare. - - The Cloudflare account must already be linked to PlanetScale in the Hyperdrive - dashboard. + """ + Selects a PlanetScale database and provisions credentials managed by Cloudflare + when creating a Hyperdrive configuration. The Cloudflare account must already be + linked to PlanetScale in the Hyperdrive dashboard. The selection is returned as + read-only metadata and cannot be changed with replace or update operations. """ modified_on: Optional[datetime] = None diff --git a/src/cloudflare/types/hyperdrive/config_list_response.py b/src/cloudflare/types/hyperdrive/config_list_response.py index a40749f802c..8a2b0307ef4 100644 --- a/src/cloudflare/types/hyperdrive/config_list_response.py +++ b/src/cloudflare/types/hyperdrive/config_list_response.py @@ -96,9 +96,8 @@ class OriginDatabaseReachableThroughAWorkersVPC(BaseModel): class Integration(BaseModel): - """Connects to a PlanetScale database using credentials managed by Cloudflare. - - The Cloudflare account must already be linked to PlanetScale in the Hyperdrive dashboard. + """ + Selects a PlanetScale database and provisions credentials managed by Cloudflare when creating a Hyperdrive configuration. The Cloudflare account must already be linked to PlanetScale in the Hyperdrive dashboard. The selection is returned as read-only metadata and cannot be changed with replace or update operations. """ database_branch_name: str @@ -165,10 +164,11 @@ class ConfigListResponse(BaseModel): """Defines the creation time of the Hyperdrive configuration.""" integration: Optional[Integration] = None - """Connects to a PlanetScale database using credentials managed by Cloudflare. - - The Cloudflare account must already be linked to PlanetScale in the Hyperdrive - dashboard. + """ + Selects a PlanetScale database and provisions credentials managed by Cloudflare + when creating a Hyperdrive configuration. The Cloudflare account must already be + linked to PlanetScale in the Hyperdrive dashboard. The selection is returned as + read-only metadata and cannot be changed with replace or update operations. """ modified_on: Optional[datetime] = None diff --git a/src/cloudflare/types/hyperdrive/config_restart_response.py b/src/cloudflare/types/hyperdrive/config_restart_response.py index e7a6c01087f..4ec27a35151 100644 --- a/src/cloudflare/types/hyperdrive/config_restart_response.py +++ b/src/cloudflare/types/hyperdrive/config_restart_response.py @@ -96,9 +96,8 @@ class OriginDatabaseReachableThroughAWorkersVPC(BaseModel): class Integration(BaseModel): - """Connects to a PlanetScale database using credentials managed by Cloudflare. - - The Cloudflare account must already be linked to PlanetScale in the Hyperdrive dashboard. + """ + Selects a PlanetScale database and provisions credentials managed by Cloudflare when creating a Hyperdrive configuration. The Cloudflare account must already be linked to PlanetScale in the Hyperdrive dashboard. The selection is returned as read-only metadata and cannot be changed with replace or update operations. """ database_branch_name: str @@ -165,10 +164,11 @@ class ConfigRestartResponse(BaseModel): """Defines the creation time of the Hyperdrive configuration.""" integration: Optional[Integration] = None - """Connects to a PlanetScale database using credentials managed by Cloudflare. - - The Cloudflare account must already be linked to PlanetScale in the Hyperdrive - dashboard. + """ + Selects a PlanetScale database and provisions credentials managed by Cloudflare + when creating a Hyperdrive configuration. The Cloudflare account must already be + linked to PlanetScale in the Hyperdrive dashboard. The selection is returned as + read-only metadata and cannot be changed with replace or update operations. """ modified_on: Optional[datetime] = None diff --git a/src/cloudflare/types/hyperdrive/config_update_response.py b/src/cloudflare/types/hyperdrive/config_update_response.py index ea341e0403b..639825be9e5 100644 --- a/src/cloudflare/types/hyperdrive/config_update_response.py +++ b/src/cloudflare/types/hyperdrive/config_update_response.py @@ -96,9 +96,8 @@ class OriginDatabaseReachableThroughAWorkersVPC(BaseModel): class Integration(BaseModel): - """Connects to a PlanetScale database using credentials managed by Cloudflare. - - The Cloudflare account must already be linked to PlanetScale in the Hyperdrive dashboard. + """ + Selects a PlanetScale database and provisions credentials managed by Cloudflare when creating a Hyperdrive configuration. The Cloudflare account must already be linked to PlanetScale in the Hyperdrive dashboard. The selection is returned as read-only metadata and cannot be changed with replace or update operations. """ database_branch_name: str @@ -165,10 +164,11 @@ class ConfigUpdateResponse(BaseModel): """Defines the creation time of the Hyperdrive configuration.""" integration: Optional[Integration] = None - """Connects to a PlanetScale database using credentials managed by Cloudflare. - - The Cloudflare account must already be linked to PlanetScale in the Hyperdrive - dashboard. + """ + Selects a PlanetScale database and provisions credentials managed by Cloudflare + when creating a Hyperdrive configuration. The Cloudflare account must already be + linked to PlanetScale in the Hyperdrive dashboard. The selection is returned as + read-only metadata and cannot be changed with replace or update operations. """ modified_on: Optional[datetime] = None diff --git a/src/cloudflare/types/iam/resource_group_create_params.py b/src/cloudflare/types/iam/resource_group_create_params.py index f732c8d93d1..e9e835697a8 100644 --- a/src/cloudflare/types/iam/resource_group_create_params.py +++ b/src/cloudflare/types/iam/resource_group_create_params.py @@ -16,7 +16,7 @@ class ResourceGroupCreateParams(TypedDict, total=False): """Name of the resource group""" scope: Required[Scope] - """A scope is a combination of scope objects which provides additional context.""" + """The scope associated to the resource group""" class ScopeObject(TypedDict, total=False): @@ -32,7 +32,7 @@ class ScopeObject(TypedDict, total=False): class Scope(TypedDict, total=False): - """A scope is a combination of scope objects which provides additional context.""" + """The scope associated to the resource group""" key: Required[str] """ diff --git a/src/cloudflare/types/iam/resource_group_create_response.py b/src/cloudflare/types/iam/resource_group_create_response.py index 763acbcb9c2..46882e55604 100644 --- a/src/cloudflare/types/iam/resource_group_create_response.py +++ b/src/cloudflare/types/iam/resource_group_create_response.py @@ -20,7 +20,7 @@ class ScopeObject(BaseModel): class Scope(BaseModel): - """A scope is a combination of scope objects which provides additional context.""" + """The scope associated to the resource group""" key: str """ @@ -47,7 +47,7 @@ class ResourceGroupCreateResponse(BaseModel): """Identifier of the resource group.""" scope: Scope - """A scope is a combination of scope objects which provides additional context.""" + """The scope associated to the resource group""" meta: Optional[Meta] = None """Attributes associated to the resource group.""" diff --git a/src/cloudflare/types/iam/resource_group_get_response.py b/src/cloudflare/types/iam/resource_group_get_response.py index a7239cf8511..e7a57b1ddc8 100644 --- a/src/cloudflare/types/iam/resource_group_get_response.py +++ b/src/cloudflare/types/iam/resource_group_get_response.py @@ -20,7 +20,7 @@ class ScopeObject(BaseModel): class Scope(BaseModel): - """A scope is a combination of scope objects which provides additional context.""" + """The scope associated to the resource group""" key: str """ @@ -47,7 +47,7 @@ class ResourceGroupGetResponse(BaseModel): """Identifier of the resource group.""" scope: Scope - """A scope is a combination of scope objects which provides additional context.""" + """The scope associated to the resource group""" meta: Optional[Meta] = None """Attributes associated to the resource group.""" diff --git a/src/cloudflare/types/iam/resource_group_list_response.py b/src/cloudflare/types/iam/resource_group_list_response.py index 624700c6f34..c91b16c3d46 100644 --- a/src/cloudflare/types/iam/resource_group_list_response.py +++ b/src/cloudflare/types/iam/resource_group_list_response.py @@ -20,7 +20,7 @@ class ScopeObject(BaseModel): class Scope(BaseModel): - """A scope is a combination of scope objects which provides additional context.""" + """The scope associated to the resource group""" key: str """ @@ -47,7 +47,7 @@ class ResourceGroupListResponse(BaseModel): """Identifier of the resource group.""" scope: Scope - """A scope is a combination of scope objects which provides additional context.""" + """The scope associated to the resource group""" meta: Optional[Meta] = None """Attributes associated to the resource group.""" diff --git a/src/cloudflare/types/iam/resource_group_update_params.py b/src/cloudflare/types/iam/resource_group_update_params.py index 14274c889a0..13c0de52636 100644 --- a/src/cloudflare/types/iam/resource_group_update_params.py +++ b/src/cloudflare/types/iam/resource_group_update_params.py @@ -16,7 +16,7 @@ class ResourceGroupUpdateParams(TypedDict, total=False): """Name of the resource group""" scope: Scope - """A scope is a combination of scope objects which provides additional context.""" + """The scope associated to the resource group""" class ScopeObject(TypedDict, total=False): @@ -32,7 +32,7 @@ class ScopeObject(TypedDict, total=False): class Scope(TypedDict, total=False): - """A scope is a combination of scope objects which provides additional context.""" + """The scope associated to the resource group""" key: Required[str] """ diff --git a/src/cloudflare/types/iam/resource_group_update_response.py b/src/cloudflare/types/iam/resource_group_update_response.py index acaabe862fd..3b9f8eff221 100644 --- a/src/cloudflare/types/iam/resource_group_update_response.py +++ b/src/cloudflare/types/iam/resource_group_update_response.py @@ -20,7 +20,7 @@ class ScopeObject(BaseModel): class Scope(BaseModel): - """A scope is a combination of scope objects which provides additional context.""" + """The scope associated to the resource group""" key: str """ @@ -47,7 +47,7 @@ class ResourceGroupUpdateResponse(BaseModel): """Identifier of the resource group.""" scope: Scope - """A scope is a combination of scope objects which provides additional context.""" + """The scope associated to the resource group""" meta: Optional[Meta] = None """Attributes associated to the resource group.""" diff --git a/src/cloudflare/types/iam/user_group_create_response.py b/src/cloudflare/types/iam/user_group_create_response.py index dc0b08952b0..b826092b9a7 100644 --- a/src/cloudflare/types/iam/user_group_create_response.py +++ b/src/cloudflare/types/iam/user_group_create_response.py @@ -74,7 +74,7 @@ class PolicyResourceGroupScopeObject(BaseModel): class PolicyResourceGroupScope(BaseModel): - """A scope is a combination of scope objects which provides additional context.""" + """The scope associated to the resource group""" key: str """ @@ -101,7 +101,7 @@ class PolicyResourceGroup(BaseModel): """Identifier of the resource group.""" scope: PolicyResourceGroupScope - """A scope is a combination of scope objects which provides additional context.""" + """The scope associated to the resource group""" meta: Optional[PolicyResourceGroupMeta] = None """Attributes associated to the resource group.""" @@ -130,7 +130,7 @@ class UserGroupCreateResponse(BaseModel): """A group of policies resources.""" id: str - """User Group identifier tag.""" + """Identifier of the user group.""" created_on: datetime """Timestamp for the creation of the user group""" diff --git a/src/cloudflare/types/iam/user_group_get_response.py b/src/cloudflare/types/iam/user_group_get_response.py index 2dd234c9502..04e5cc2e03a 100644 --- a/src/cloudflare/types/iam/user_group_get_response.py +++ b/src/cloudflare/types/iam/user_group_get_response.py @@ -74,7 +74,7 @@ class PolicyResourceGroupScopeObject(BaseModel): class PolicyResourceGroupScope(BaseModel): - """A scope is a combination of scope objects which provides additional context.""" + """The scope associated to the resource group""" key: str """ @@ -101,7 +101,7 @@ class PolicyResourceGroup(BaseModel): """Identifier of the resource group.""" scope: PolicyResourceGroupScope - """A scope is a combination of scope objects which provides additional context.""" + """The scope associated to the resource group""" meta: Optional[PolicyResourceGroupMeta] = None """Attributes associated to the resource group.""" @@ -130,7 +130,7 @@ class UserGroupGetResponse(BaseModel): """A group of policies resources.""" id: str - """User Group identifier tag.""" + """Identifier of the user group.""" created_on: datetime """Timestamp for the creation of the user group""" diff --git a/src/cloudflare/types/iam/user_group_list_response.py b/src/cloudflare/types/iam/user_group_list_response.py index b65d6737ec3..734539c86f4 100644 --- a/src/cloudflare/types/iam/user_group_list_response.py +++ b/src/cloudflare/types/iam/user_group_list_response.py @@ -74,7 +74,7 @@ class PolicyResourceGroupScopeObject(BaseModel): class PolicyResourceGroupScope(BaseModel): - """A scope is a combination of scope objects which provides additional context.""" + """The scope associated to the resource group""" key: str """ @@ -101,7 +101,7 @@ class PolicyResourceGroup(BaseModel): """Identifier of the resource group.""" scope: PolicyResourceGroupScope - """A scope is a combination of scope objects which provides additional context.""" + """The scope associated to the resource group""" meta: Optional[PolicyResourceGroupMeta] = None """Attributes associated to the resource group.""" @@ -130,7 +130,7 @@ class UserGroupListResponse(BaseModel): """A group of policies resources.""" id: str - """User Group identifier tag.""" + """Identifier of the user group.""" created_on: datetime """Timestamp for the creation of the user group""" diff --git a/src/cloudflare/types/iam/user_group_update_response.py b/src/cloudflare/types/iam/user_group_update_response.py index 35c4529ffa0..274f294dfba 100644 --- a/src/cloudflare/types/iam/user_group_update_response.py +++ b/src/cloudflare/types/iam/user_group_update_response.py @@ -74,7 +74,7 @@ class PolicyResourceGroupScopeObject(BaseModel): class PolicyResourceGroupScope(BaseModel): - """A scope is a combination of scope objects which provides additional context.""" + """The scope associated to the resource group""" key: str """ @@ -101,7 +101,7 @@ class PolicyResourceGroup(BaseModel): """Identifier of the resource group.""" scope: PolicyResourceGroupScope - """A scope is a combination of scope objects which provides additional context.""" + """The scope associated to the resource group""" meta: Optional[PolicyResourceGroupMeta] = None """Attributes associated to the resource group.""" @@ -130,7 +130,7 @@ class UserGroupUpdateResponse(BaseModel): """A group of policies resources.""" id: str - """User Group identifier tag.""" + """Identifier of the user group.""" created_on: datetime """Timestamp for the creation of the user group""" diff --git a/src/cloudflare/types/intel/attack_surface_report/issue_list_response.py b/src/cloudflare/types/intel/attack_surface_report/issue_list_response.py index aa6e71b4378..0e3b572bf2d 100644 --- a/src/cloudflare/types/intel/attack_surface_report/issue_list_response.py +++ b/src/cloudflare/types/intel/attack_surface_report/issue_list_response.py @@ -42,6 +42,12 @@ class Issue(BaseModel): since: Optional[datetime] = None + source: Optional[Literal["cloudflare", "riskrecon"]] = None + """Who generated the insight. + + `cloudflare` for Cloudflare-generated insights, otherwise the partner. + """ + status: Optional[Literal["active", "resolved"]] = None """The current status of the insight.""" diff --git a/src/cloudflare/types/intel/whois.py b/src/cloudflare/types/intel/whois.py deleted file mode 100644 index f852e72a745..00000000000 --- a/src/cloudflare/types/intel/whois.py +++ /dev/null @@ -1,28 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from typing import List, Optional -from datetime import date - -from ..._models import BaseModel - -__all__ = ["Whois"] - - -class Whois(BaseModel): - created_date: Optional[date] = None - - domain: Optional[str] = None - - nameservers: Optional[List[str]] = None - - registrant: Optional[str] = None - - registrant_country: Optional[str] = None - - registrant_email: Optional[str] = None - - registrant_org: Optional[str] = None - - registrar: Optional[str] = None - - updated_date: Optional[date] = None diff --git a/src/cloudflare/types/k2/__init__.py b/src/cloudflare/types/k2/__init__.py new file mode 100644 index 00000000000..8603f224b7c --- /dev/null +++ b/src/cloudflare/types/k2/__init__.py @@ -0,0 +1,11 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from .stream_list_params import StreamListParams as StreamListParams +from .stream_get_response import StreamGetResponse as StreamGetResponse +from .stream_create_params import StreamCreateParams as StreamCreateParams +from .stream_list_response import StreamListResponse as StreamListResponse +from .stream_update_params import StreamUpdateParams as StreamUpdateParams +from .stream_create_response import StreamCreateResponse as StreamCreateResponse +from .stream_update_response import StreamUpdateResponse as StreamUpdateResponse diff --git a/src/cloudflare/types/k2/stream_create_params.py b/src/cloudflare/types/k2/stream_create_params.py new file mode 100644 index 00000000000..0529b54adb0 --- /dev/null +++ b/src/cloudflare/types/k2/stream_create_params.py @@ -0,0 +1,66 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Required, TypedDict + +from ..._types import SequenceNotStr + +__all__ = ["StreamCreateParams", "HTTP", "HTTPCORS", "WorkerBinding"] + + +class StreamCreateParams(TypedDict, total=False): + account_id: Required[str] + """Specifies the public ID of the account.""" + + name: Required[str] + """Specifies the name of the K2 stream.""" + + http: HTTP + """Configures the HTTP endpoint. + + Disabling HTTP keeps `authentication` and `cors`, so enabling it again restores + them. + """ + + retention_seconds: int + """ + Sets the record retention period from 1 hour (3600 seconds) to 30 days (2592000 + seconds), inclusive. + """ + + worker_binding: WorkerBinding + + +class HTTPCORS(TypedDict, total=False): + origins: SequenceNotStr[str] + """Allows browser requests from these HTTP or HTTPS origins. + + Use a wildcard only as the sole origin. An empty list blocks cross-origin + browser requests. Defaults to `['*']` when HTTP is enabled without stored + origins. + """ + + +class HTTP(TypedDict, total=False): + """Configures the HTTP endpoint. + + Disabling HTTP keeps `authentication` and `cors`, so enabling it again restores them. + """ + + enabled: Required[bool] + """Indicates whether the HTTP endpoint accepts records.""" + + authentication: bool + """ + Indicates whether the HTTP endpoint requires an API token with K2 produce + permission. When false, the endpoint accepts unauthenticated records. Defaults + to true when HTTP is enabled without a stored value. + """ + + cors: HTTPCORS + + +class WorkerBinding(TypedDict, total=False): + enabled: Required[bool] + """Indicates whether Workers bindings can produce records to the stream.""" diff --git a/src/cloudflare/types/k2/stream_create_response.py b/src/cloudflare/types/k2/stream_create_response.py new file mode 100644 index 00000000000..23ed4636693 --- /dev/null +++ b/src/cloudflare/types/k2/stream_create_response.py @@ -0,0 +1,72 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional +from datetime import datetime + +from ..._models import BaseModel + +__all__ = ["StreamCreateResponse", "HTTP", "HTTPCORS", "WorkerBinding"] + + +class HTTPCORS(BaseModel): + origins: Optional[List[str]] = None + """Allows browser requests from these HTTP or HTTPS origins. + + Use a wildcard only as the sole origin. An empty list blocks cross-origin + browser requests. Defaults to `['*']` when HTTP is enabled without stored + origins. + """ + + +class HTTP(BaseModel): + """Configures the HTTP endpoint. + + Disabling HTTP keeps `authentication` and `cors`, so enabling it again restores them. + """ + + enabled: bool + """Indicates whether the HTTP endpoint accepts records.""" + + authentication: Optional[bool] = None + """ + Indicates whether the HTTP endpoint requires an API token with K2 produce + permission. When false, the endpoint accepts unauthenticated records. Defaults + to true when HTTP is enabled without a stored value. + """ + + cors: Optional[HTTPCORS] = None + + +class WorkerBinding(BaseModel): + enabled: bool + """Indicates whether Workers bindings can produce records to the stream.""" + + +class StreamCreateResponse(BaseModel): + id: str + """Specifies the public ID of the K2 stream.""" + + created_at: datetime + + endpoint: str + """Indicates the base HTTP endpoint for producing and consuming records.""" + + http: HTTP + """Configures the HTTP endpoint. + + Disabling HTTP keeps `authentication` and `cors`, so enabling it again restores + them. + """ + + modified_at: datetime + + name: str + """Indicates the name of the K2 stream.""" + + retention_seconds: int + """ + Shows the configured record retention period from 1 hour (3600 seconds) to 30 + days (2592000 seconds), inclusive. + """ + + worker_binding: WorkerBinding diff --git a/src/cloudflare/types/k2/stream_get_response.py b/src/cloudflare/types/k2/stream_get_response.py new file mode 100644 index 00000000000..4320fe43d90 --- /dev/null +++ b/src/cloudflare/types/k2/stream_get_response.py @@ -0,0 +1,72 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional +from datetime import datetime + +from ..._models import BaseModel + +__all__ = ["StreamGetResponse", "HTTP", "HTTPCORS", "WorkerBinding"] + + +class HTTPCORS(BaseModel): + origins: Optional[List[str]] = None + """Allows browser requests from these HTTP or HTTPS origins. + + Use a wildcard only as the sole origin. An empty list blocks cross-origin + browser requests. Defaults to `['*']` when HTTP is enabled without stored + origins. + """ + + +class HTTP(BaseModel): + """Configures the HTTP endpoint. + + Disabling HTTP keeps `authentication` and `cors`, so enabling it again restores them. + """ + + enabled: bool + """Indicates whether the HTTP endpoint accepts records.""" + + authentication: Optional[bool] = None + """ + Indicates whether the HTTP endpoint requires an API token with K2 produce + permission. When false, the endpoint accepts unauthenticated records. Defaults + to true when HTTP is enabled without a stored value. + """ + + cors: Optional[HTTPCORS] = None + + +class WorkerBinding(BaseModel): + enabled: bool + """Indicates whether Workers bindings can produce records to the stream.""" + + +class StreamGetResponse(BaseModel): + id: str + """Specifies the public ID of the K2 stream.""" + + created_at: datetime + + endpoint: str + """Indicates the base HTTP endpoint for producing and consuming records.""" + + http: HTTP + """Configures the HTTP endpoint. + + Disabling HTTP keeps `authentication` and `cors`, so enabling it again restores + them. + """ + + modified_at: datetime + + name: str + """Indicates the name of the K2 stream.""" + + retention_seconds: int + """ + Shows the configured record retention period from 1 hour (3600 seconds) to 30 + days (2592000 seconds), inclusive. + """ + + worker_binding: WorkerBinding diff --git a/src/cloudflare/types/k2/stream_list_params.py b/src/cloudflare/types/k2/stream_list_params.py new file mode 100644 index 00000000000..42dc5dd3b4f --- /dev/null +++ b/src/cloudflare/types/k2/stream_list_params.py @@ -0,0 +1,19 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Required, TypedDict + +__all__ = ["StreamListParams"] + + +class StreamListParams(TypedDict, total=False): + account_id: Required[str] + """Specifies the public ID of the account.""" + + name: str + """Filters K2 streams by name using a case-insensitive substring.""" + + page: int + + per_page: int diff --git a/src/cloudflare/types/k2/stream_list_response.py b/src/cloudflare/types/k2/stream_list_response.py new file mode 100644 index 00000000000..d8fedb0821b --- /dev/null +++ b/src/cloudflare/types/k2/stream_list_response.py @@ -0,0 +1,72 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional +from datetime import datetime + +from ..._models import BaseModel + +__all__ = ["StreamListResponse", "HTTP", "HTTPCORS", "WorkerBinding"] + + +class HTTPCORS(BaseModel): + origins: Optional[List[str]] = None + """Allows browser requests from these HTTP or HTTPS origins. + + Use a wildcard only as the sole origin. An empty list blocks cross-origin + browser requests. Defaults to `['*']` when HTTP is enabled without stored + origins. + """ + + +class HTTP(BaseModel): + """Configures the HTTP endpoint. + + Disabling HTTP keeps `authentication` and `cors`, so enabling it again restores them. + """ + + enabled: bool + """Indicates whether the HTTP endpoint accepts records.""" + + authentication: Optional[bool] = None + """ + Indicates whether the HTTP endpoint requires an API token with K2 produce + permission. When false, the endpoint accepts unauthenticated records. Defaults + to true when HTTP is enabled without a stored value. + """ + + cors: Optional[HTTPCORS] = None + + +class WorkerBinding(BaseModel): + enabled: bool + """Indicates whether Workers bindings can produce records to the stream.""" + + +class StreamListResponse(BaseModel): + id: str + """Specifies the public ID of the K2 stream.""" + + created_at: datetime + + endpoint: str + """Indicates the base HTTP endpoint for producing and consuming records.""" + + http: HTTP + """Configures the HTTP endpoint. + + Disabling HTTP keeps `authentication` and `cors`, so enabling it again restores + them. + """ + + modified_at: datetime + + name: str + """Indicates the name of the K2 stream.""" + + retention_seconds: int + """ + Shows the configured record retention period from 1 hour (3600 seconds) to 30 + days (2592000 seconds), inclusive. + """ + + worker_binding: WorkerBinding diff --git a/src/cloudflare/types/k2/stream_update_params.py b/src/cloudflare/types/k2/stream_update_params.py new file mode 100644 index 00000000000..6432f1e521e --- /dev/null +++ b/src/cloudflare/types/k2/stream_update_params.py @@ -0,0 +1,63 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Required, TypedDict + +from ..._types import SequenceNotStr + +__all__ = ["StreamUpdateParams", "HTTP", "HTTPCORS", "WorkerBinding"] + + +class StreamUpdateParams(TypedDict, total=False): + account_id: Required[str] + """Specifies the public ID of the account.""" + + http: HTTP + """Configures the HTTP endpoint. + + Disabling HTTP keeps `authentication` and `cors`, so enabling it again restores + them. + """ + + retention_seconds: int + """ + Sets the record retention period from 1 hour (3600 seconds) to 30 days (2592000 + seconds), inclusive. + """ + + worker_binding: WorkerBinding + + +class HTTPCORS(TypedDict, total=False): + origins: SequenceNotStr[str] + """Allows browser requests from these HTTP or HTTPS origins. + + Use a wildcard only as the sole origin. An empty list blocks cross-origin + browser requests. Defaults to `['*']` when HTTP is enabled without stored + origins. + """ + + +class HTTP(TypedDict, total=False): + """Configures the HTTP endpoint. + + Disabling HTTP keeps `authentication` and `cors`, so enabling it again restores them. + """ + + enabled: Required[bool] + """Indicates whether the HTTP endpoint accepts records.""" + + authentication: bool + """ + Indicates whether the HTTP endpoint requires an API token with K2 produce + permission. When false, the endpoint accepts unauthenticated records. Defaults + to true when HTTP is enabled without a stored value. + """ + + cors: HTTPCORS + + +class WorkerBinding(TypedDict, total=False): + enabled: Required[bool] + """Indicates whether Workers bindings can produce records to the stream.""" diff --git a/src/cloudflare/types/k2/stream_update_response.py b/src/cloudflare/types/k2/stream_update_response.py new file mode 100644 index 00000000000..b310c055250 --- /dev/null +++ b/src/cloudflare/types/k2/stream_update_response.py @@ -0,0 +1,72 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional +from datetime import datetime + +from ..._models import BaseModel + +__all__ = ["StreamUpdateResponse", "HTTP", "HTTPCORS", "WorkerBinding"] + + +class HTTPCORS(BaseModel): + origins: Optional[List[str]] = None + """Allows browser requests from these HTTP or HTTPS origins. + + Use a wildcard only as the sole origin. An empty list blocks cross-origin + browser requests. Defaults to `['*']` when HTTP is enabled without stored + origins. + """ + + +class HTTP(BaseModel): + """Configures the HTTP endpoint. + + Disabling HTTP keeps `authentication` and `cors`, so enabling it again restores them. + """ + + enabled: bool + """Indicates whether the HTTP endpoint accepts records.""" + + authentication: Optional[bool] = None + """ + Indicates whether the HTTP endpoint requires an API token with K2 produce + permission. When false, the endpoint accepts unauthenticated records. Defaults + to true when HTTP is enabled without a stored value. + """ + + cors: Optional[HTTPCORS] = None + + +class WorkerBinding(BaseModel): + enabled: bool + """Indicates whether Workers bindings can produce records to the stream.""" + + +class StreamUpdateResponse(BaseModel): + id: str + """Specifies the public ID of the K2 stream.""" + + created_at: datetime + + endpoint: str + """Indicates the base HTTP endpoint for producing and consuming records.""" + + http: HTTP + """Configures the HTTP endpoint. + + Disabling HTTP keeps `authentication` and `cors`, so enabling it again restores + them. + """ + + modified_at: datetime + + name: str + """Indicates the name of the K2 stream.""" + + retention_seconds: int + """ + Shows the configured record retention period from 1 hour (3600 seconds) to 30 + days (2592000 seconds), inclusive. + """ + + worker_binding: WorkerBinding diff --git a/src/cloudflare/types/k2/streams/__init__.py b/src/cloudflare/types/k2/streams/__init__.py new file mode 100644 index 00000000000..e071adc9546 --- /dev/null +++ b/src/cloudflare/types/k2/streams/__init__.py @@ -0,0 +1,5 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from .subscription_list_response import SubscriptionListResponse as SubscriptionListResponse diff --git a/src/cloudflare/types/k2/streams/subscription_list_response.py b/src/cloudflare/types/k2/streams/subscription_list_response.py new file mode 100644 index 00000000000..827e88714e9 --- /dev/null +++ b/src/cloudflare/types/k2/streams/subscription_list_response.py @@ -0,0 +1,43 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional +from datetime import datetime +from typing_extensions import Literal + +from ...._models import BaseModel + +__all__ = ["SubscriptionListResponse", "Lag", "StartAt"] + + +class Lag(BaseModel): + records: Optional[str] = None + """ + Decimal-string distance from the subscription's committed position to the + observed exclusive stream tail, in records. Includes in-flight records and may + include expired records or records acknowledged beyond an earlier gap. Null + unless status is available. + """ + + status: Literal["available", "unsupported", "unavailable"] + """ + Unsupported means the subscription or stream topology cannot be measured; + unavailable means a required observation failed or was inconsistent. + """ + + +class StartAt(BaseModel): + type: Literal["earliest", "latest"] + + +class SubscriptionListResponse(BaseModel): + id: str + + created_at: datetime + + lag: Lag + + modified_at: datetime + + name: str + + start_at: StartAt diff --git a/src/cloudflare/types/kv/namespace.py b/src/cloudflare/types/kv/namespace.py index 609a5e40cf1..a6abd1e301f 100644 --- a/src/cloudflare/types/kv/namespace.py +++ b/src/cloudflare/types/kv/namespace.py @@ -21,6 +21,14 @@ class Namespace(BaseModel): within. Can only be set at namespace creation time. """ + mode: Optional[Literal["instant"]] = None + """The mode of the Workers KV namespace. + + Specify `instant` when creating a namespace to create a KV Instant namespace. + Omit this field when creating a namespace to create a classic namespace. + Currently, `instant` is the only supported explicit value. + """ + supports_url_encoding: Optional[bool] = None """True if keys written on the URL will be URL-decoded before storing. diff --git a/src/cloudflare/types/kv/namespace_create_params.py b/src/cloudflare/types/kv/namespace_create_params.py index c807614ca3a..bc82c2c11cc 100644 --- a/src/cloudflare/types/kv/namespace_create_params.py +++ b/src/cloudflare/types/kv/namespace_create_params.py @@ -19,3 +19,11 @@ class NamespaceCreateParams(TypedDict, total=False): Specify the jurisdiction to restrict the KV namespace to durably store data within. Can only be set at namespace creation time. """ + + mode: Literal["instant"] + """The mode of the Workers KV namespace. + + Specify `instant` when creating a namespace to create a KV Instant namespace. + Omit this field when creating a namespace to create a classic namespace. + Currently, `instant` is the only supported explicit value. + """ diff --git a/src/cloudflare/types/load_balancers/load_balancer_create_params.py b/src/cloudflare/types/load_balancers/load_balancer_create_params.py index 7e5ee400380..48c518f3c2b 100644 --- a/src/cloudflare/types/load_balancers/load_balancer_create_params.py +++ b/src/cloudflare/types/load_balancers/load_balancer_create_params.py @@ -15,7 +15,14 @@ from .location_strategy_param import LocationStrategyParam from .session_affinity_attributes_param import SessionAffinityAttributesParam -__all__ = ["LoadBalancerCreateParams"] +__all__ = [ + "LoadBalancerCreateParams", + "PoolSet", + "PoolSetFixedResponse", + "PoolSetMatch", + "PoolSetMatchTopology", + "PoolSetOverrides", +] class LoadBalancerCreateParams(TypedDict, total=False): @@ -75,6 +82,16 @@ class LoadBalancerCreateParams(TypedDict, total=False): networks: SequenceNotStr[str] """List of networks where Load Balancer or Pool is enabled.""" + pool_sets: Iterable[PoolSet] + """An optional list of pool sets, evaluated in array order with first match wins. + + Pool sets are independent from the standard steering fields (`region_pools` / + `country_pools` / `pop_pools` / `default_pools` / `steering_policy` / + `random_steering` / `fallback_pool` / `rules`). On a PATCH, an empty array + (`pool_sets: []`) clears all pool sets, while omitting the field leaves existing + pool sets unchanged. + """ + pop_pools: Dict[str, SequenceNotStr[str]] """ Enterprise only: A mapping of Cloudflare PoP identifiers to a list of pool IDs @@ -180,3 +197,153 @@ class LoadBalancerCreateParams(TypedDict, total=False): Time to live (TTL) of the DNS entry for the IP address returned by this load balancer. This only applies to gray-clouded (unproxied) load balancers. """ + + +class PoolSetFixedResponse(TypedDict, total=False): + """ + A collection of fields used to directly respond to the client instead of routing to a pool. When supplied on a rule, that rule stops further rule evaluation. + """ + + content_type: str + """The http 'Content-Type' header to include in the response.""" + + location: str + """The http 'Location' header to include in the response.""" + + message_body: str + """Text to include as the http body.""" + + status_code: int + """The http status code to respond with.""" + + +class PoolSetMatchTopology(TypedDict, total=False): + """Matches requests by location. + + Set any combination of `pops`, `countries`, and `regions` (at least one is required); a request matches when its value appears in any populated list (e.g. `regions: ["WNAM"]` with `countries: ["US"]` matches a request in either WNAM or the US). + """ + + countries: SequenceNotStr[str] + """A list of ISO 3166-1 alpha-2 country codes. + + Matches when the request's country is in this list. + """ + + pops: SequenceNotStr[str] + """A list of Cloudflare PoP codes. Matches when the request's PoP is in this list.""" + + regions: SequenceNotStr[str] + """A list of Cloudflare region codes (e.g. + + `WNAM`, `ENAM`, `WEU`). Matches when the request's region is in this list. + """ + + +class PoolSetMatch(TypedDict, total=False): + """Determines which requests a pool set applies to. + + Set `topology` to match by location or `default: true` to match all requests; the two are mutually exclusive. A pool set with no `match` matches all requests. + """ + + default: bool + """When true, matches every request. Cannot be combined with `topology`.""" + + topology: PoolSetMatchTopology + """Matches requests by location. + + Set any combination of `pops`, `countries`, and `regions` (at least one is + required); a request matches when its value appears in any populated list (e.g. + `regions: ["WNAM"]` with `countries: ["US"]` matches a request in either WNAM or + the US). + """ + + +class PoolSetOverrides(TypedDict, total=False): + """The behavior a pool set applies when its `match` succeeds. + + A strict subset of a rule's `overrides`: a pool set replaces the topology wholesale with a flat pool list (`pools`), so only the declarative pool-routing fields plus `fallback_pool` and `steering_policy` are settable. All fields are optional. + """ + + fallback_pool: str + """The pool ID to use when all other pools are detected as unhealthy.""" + + pool_default_weight: float + """The default weight for pools not listed in `pool_weights`. + + The declarative alternative to `random_steering.default_weight`; mutually + exclusive with `random_steering`. + """ + + pool_weights: Dict[str, float] + """A mapping of pool IDs to custom weights, relative to the other pools. + + The declarative alternative to `random_steering.pool_weights`; mutually + exclusive with `random_steering`. + """ + + pools: SequenceNotStr[str] + """A flat, ordered list of pool IDs to route the matched audience to. + + Replaces the resolved topology with exactly these pools. Mutually exclusive with + `fixed_response`. + """ + + steering_policy: SteeringPolicy + """Steering Policy for this load balancer. + + - `"off"`: Use `default_pools`. + - `"geo"`: Use `region_pools`/`country_pools`/`pop_pools`. For non-proxied + requests, the country for `country_pools` is determined by + `location_strategy`. + - `"random"`: Select a pool randomly. + - `"dynamic_latency"`: Use round trip time to select the closest pool in + default_pools (requires pool health checks). + - `"proximity"`: Use the pools' latitude and longitude to select the closest + pool using the Cloudflare PoP location for proxied requests or the location + determined by `location_strategy` for non-proxied requests. + - `"least_outstanding_requests"`: Select a pool by taking into consideration + `random_steering` weights, as well as each pool's number of outstanding + requests. Pools with more pending requests are weighted proportionately less + relative to others. + - `"least_connections"`: Select a pool by taking into consideration + `random_steering` weights, as well as each pool's number of open connections. + Pools with more open connections are weighted proportionately less relative to + others. Supported for HTTP/1 and HTTP/2 connections. + - `""`: Will map to `"geo"` if you use + `region_pools`/`country_pools`/`pop_pools` otherwise `"off"`. + """ + + +class PoolSet(TypedDict, total=False): + """One entry in a load balancer's `pool_sets`. + + Pool sets are evaluated in array order; the first whose `match` succeeds applies its `overrides` (or `fixed_response`), and evaluation stops there. + """ + + disabled: bool + """Disable this specific pool set. It will no longer be evaluated.""" + + fixed_response: PoolSetFixedResponse + """ + A collection of fields used to directly respond to the client instead of routing + to a pool. When supplied on a rule, that rule stops further rule evaluation. + """ + + match: PoolSetMatch + """Determines which requests a pool set applies to. + + Set `topology` to match by location or `default: true` to match all requests; + the two are mutually exclusive. A pool set with no `match` matches all requests. + """ + + name: str + """A human-readable name for this pool set.""" + + overrides: PoolSetOverrides + """The behavior a pool set applies when its `match` succeeds. + + A strict subset of a rule's `overrides`: a pool set replaces the topology + wholesale with a flat pool list (`pools`), so only the declarative pool-routing + fields plus `fallback_pool` and `steering_policy` are settable. All fields are + optional. + """ diff --git a/src/cloudflare/types/load_balancers/load_balancer_edit_params.py b/src/cloudflare/types/load_balancers/load_balancer_edit_params.py index d3dcd32ebbe..2cf50cfa582 100644 --- a/src/cloudflare/types/load_balancers/load_balancer_edit_params.py +++ b/src/cloudflare/types/load_balancers/load_balancer_edit_params.py @@ -15,7 +15,14 @@ from .location_strategy_param import LocationStrategyParam from .session_affinity_attributes_param import SessionAffinityAttributesParam -__all__ = ["LoadBalancerEditParams"] +__all__ = [ + "LoadBalancerEditParams", + "PoolSet", + "PoolSetFixedResponse", + "PoolSetMatch", + "PoolSetMatchTopology", + "PoolSetOverrides", +] class LoadBalancerEditParams(TypedDict, total=False): @@ -75,6 +82,16 @@ class LoadBalancerEditParams(TypedDict, total=False): networks: SequenceNotStr[str] """List of networks where Load Balancer or Pool is enabled.""" + pool_sets: Iterable[PoolSet] + """An optional list of pool sets, evaluated in array order with first match wins. + + Pool sets are independent from the standard steering fields (`region_pools` / + `country_pools` / `pop_pools` / `default_pools` / `steering_policy` / + `random_steering` / `fallback_pool` / `rules`). On a PATCH, an empty array + (`pool_sets: []`) clears all pool sets, while omitting the field leaves existing + pool sets unchanged. + """ + pop_pools: Dict[str, SequenceNotStr[str]] """ Enterprise only: A mapping of Cloudflare PoP identifiers to a list of pool IDs @@ -180,3 +197,153 @@ class LoadBalancerEditParams(TypedDict, total=False): Time to live (TTL) of the DNS entry for the IP address returned by this load balancer. This only applies to gray-clouded (unproxied) load balancers. """ + + +class PoolSetFixedResponse(TypedDict, total=False): + """ + A collection of fields used to directly respond to the client instead of routing to a pool. When supplied on a rule, that rule stops further rule evaluation. + """ + + content_type: str + """The http 'Content-Type' header to include in the response.""" + + location: str + """The http 'Location' header to include in the response.""" + + message_body: str + """Text to include as the http body.""" + + status_code: int + """The http status code to respond with.""" + + +class PoolSetMatchTopology(TypedDict, total=False): + """Matches requests by location. + + Set any combination of `pops`, `countries`, and `regions` (at least one is required); a request matches when its value appears in any populated list (e.g. `regions: ["WNAM"]` with `countries: ["US"]` matches a request in either WNAM or the US). + """ + + countries: SequenceNotStr[str] + """A list of ISO 3166-1 alpha-2 country codes. + + Matches when the request's country is in this list. + """ + + pops: SequenceNotStr[str] + """A list of Cloudflare PoP codes. Matches when the request's PoP is in this list.""" + + regions: SequenceNotStr[str] + """A list of Cloudflare region codes (e.g. + + `WNAM`, `ENAM`, `WEU`). Matches when the request's region is in this list. + """ + + +class PoolSetMatch(TypedDict, total=False): + """Determines which requests a pool set applies to. + + Set `topology` to match by location or `default: true` to match all requests; the two are mutually exclusive. A pool set with no `match` matches all requests. + """ + + default: bool + """When true, matches every request. Cannot be combined with `topology`.""" + + topology: PoolSetMatchTopology + """Matches requests by location. + + Set any combination of `pops`, `countries`, and `regions` (at least one is + required); a request matches when its value appears in any populated list (e.g. + `regions: ["WNAM"]` with `countries: ["US"]` matches a request in either WNAM or + the US). + """ + + +class PoolSetOverrides(TypedDict, total=False): + """The behavior a pool set applies when its `match` succeeds. + + A strict subset of a rule's `overrides`: a pool set replaces the topology wholesale with a flat pool list (`pools`), so only the declarative pool-routing fields plus `fallback_pool` and `steering_policy` are settable. All fields are optional. + """ + + fallback_pool: str + """The pool ID to use when all other pools are detected as unhealthy.""" + + pool_default_weight: float + """The default weight for pools not listed in `pool_weights`. + + The declarative alternative to `random_steering.default_weight`; mutually + exclusive with `random_steering`. + """ + + pool_weights: Dict[str, float] + """A mapping of pool IDs to custom weights, relative to the other pools. + + The declarative alternative to `random_steering.pool_weights`; mutually + exclusive with `random_steering`. + """ + + pools: SequenceNotStr[str] + """A flat, ordered list of pool IDs to route the matched audience to. + + Replaces the resolved topology with exactly these pools. Mutually exclusive with + `fixed_response`. + """ + + steering_policy: SteeringPolicy + """Steering Policy for this load balancer. + + - `"off"`: Use `default_pools`. + - `"geo"`: Use `region_pools`/`country_pools`/`pop_pools`. For non-proxied + requests, the country for `country_pools` is determined by + `location_strategy`. + - `"random"`: Select a pool randomly. + - `"dynamic_latency"`: Use round trip time to select the closest pool in + default_pools (requires pool health checks). + - `"proximity"`: Use the pools' latitude and longitude to select the closest + pool using the Cloudflare PoP location for proxied requests or the location + determined by `location_strategy` for non-proxied requests. + - `"least_outstanding_requests"`: Select a pool by taking into consideration + `random_steering` weights, as well as each pool's number of outstanding + requests. Pools with more pending requests are weighted proportionately less + relative to others. + - `"least_connections"`: Select a pool by taking into consideration + `random_steering` weights, as well as each pool's number of open connections. + Pools with more open connections are weighted proportionately less relative to + others. Supported for HTTP/1 and HTTP/2 connections. + - `""`: Will map to `"geo"` if you use + `region_pools`/`country_pools`/`pop_pools` otherwise `"off"`. + """ + + +class PoolSet(TypedDict, total=False): + """One entry in a load balancer's `pool_sets`. + + Pool sets are evaluated in array order; the first whose `match` succeeds applies its `overrides` (or `fixed_response`), and evaluation stops there. + """ + + disabled: bool + """Disable this specific pool set. It will no longer be evaluated.""" + + fixed_response: PoolSetFixedResponse + """ + A collection of fields used to directly respond to the client instead of routing + to a pool. When supplied on a rule, that rule stops further rule evaluation. + """ + + match: PoolSetMatch + """Determines which requests a pool set applies to. + + Set `topology` to match by location or `default: true` to match all requests; + the two are mutually exclusive. A pool set with no `match` matches all requests. + """ + + name: str + """A human-readable name for this pool set.""" + + overrides: PoolSetOverrides + """The behavior a pool set applies when its `match` succeeds. + + A strict subset of a rule's `overrides`: a pool set replaces the topology + wholesale with a flat pool list (`pools`), so only the declarative pool-routing + fields plus `fallback_pool` and `steering_policy` are settable. All fields are + optional. + """ diff --git a/src/cloudflare/types/load_balancers/load_balancer_update_params.py b/src/cloudflare/types/load_balancers/load_balancer_update_params.py index 444b94f366e..3b6447c8880 100644 --- a/src/cloudflare/types/load_balancers/load_balancer_update_params.py +++ b/src/cloudflare/types/load_balancers/load_balancer_update_params.py @@ -15,7 +15,14 @@ from .location_strategy_param import LocationStrategyParam from .session_affinity_attributes_param import SessionAffinityAttributesParam -__all__ = ["LoadBalancerUpdateParams"] +__all__ = [ + "LoadBalancerUpdateParams", + "PoolSet", + "PoolSetFixedResponse", + "PoolSetMatch", + "PoolSetMatchTopology", + "PoolSetOverrides", +] class LoadBalancerUpdateParams(TypedDict, total=False): @@ -75,6 +82,16 @@ class LoadBalancerUpdateParams(TypedDict, total=False): networks: SequenceNotStr[str] """List of networks where Load Balancer or Pool is enabled.""" + pool_sets: Iterable[PoolSet] + """An optional list of pool sets, evaluated in array order with first match wins. + + Pool sets are independent from the standard steering fields (`region_pools` / + `country_pools` / `pop_pools` / `default_pools` / `steering_policy` / + `random_steering` / `fallback_pool` / `rules`). On a PATCH, an empty array + (`pool_sets: []`) clears all pool sets, while omitting the field leaves existing + pool sets unchanged. + """ + pop_pools: Dict[str, SequenceNotStr[str]] """ Enterprise only: A mapping of Cloudflare PoP identifiers to a list of pool IDs @@ -180,3 +197,153 @@ class LoadBalancerUpdateParams(TypedDict, total=False): Time to live (TTL) of the DNS entry for the IP address returned by this load balancer. This only applies to gray-clouded (unproxied) load balancers. """ + + +class PoolSetFixedResponse(TypedDict, total=False): + """ + A collection of fields used to directly respond to the client instead of routing to a pool. When supplied on a rule, that rule stops further rule evaluation. + """ + + content_type: str + """The http 'Content-Type' header to include in the response.""" + + location: str + """The http 'Location' header to include in the response.""" + + message_body: str + """Text to include as the http body.""" + + status_code: int + """The http status code to respond with.""" + + +class PoolSetMatchTopology(TypedDict, total=False): + """Matches requests by location. + + Set any combination of `pops`, `countries`, and `regions` (at least one is required); a request matches when its value appears in any populated list (e.g. `regions: ["WNAM"]` with `countries: ["US"]` matches a request in either WNAM or the US). + """ + + countries: SequenceNotStr[str] + """A list of ISO 3166-1 alpha-2 country codes. + + Matches when the request's country is in this list. + """ + + pops: SequenceNotStr[str] + """A list of Cloudflare PoP codes. Matches when the request's PoP is in this list.""" + + regions: SequenceNotStr[str] + """A list of Cloudflare region codes (e.g. + + `WNAM`, `ENAM`, `WEU`). Matches when the request's region is in this list. + """ + + +class PoolSetMatch(TypedDict, total=False): + """Determines which requests a pool set applies to. + + Set `topology` to match by location or `default: true` to match all requests; the two are mutually exclusive. A pool set with no `match` matches all requests. + """ + + default: bool + """When true, matches every request. Cannot be combined with `topology`.""" + + topology: PoolSetMatchTopology + """Matches requests by location. + + Set any combination of `pops`, `countries`, and `regions` (at least one is + required); a request matches when its value appears in any populated list (e.g. + `regions: ["WNAM"]` with `countries: ["US"]` matches a request in either WNAM or + the US). + """ + + +class PoolSetOverrides(TypedDict, total=False): + """The behavior a pool set applies when its `match` succeeds. + + A strict subset of a rule's `overrides`: a pool set replaces the topology wholesale with a flat pool list (`pools`), so only the declarative pool-routing fields plus `fallback_pool` and `steering_policy` are settable. All fields are optional. + """ + + fallback_pool: str + """The pool ID to use when all other pools are detected as unhealthy.""" + + pool_default_weight: float + """The default weight for pools not listed in `pool_weights`. + + The declarative alternative to `random_steering.default_weight`; mutually + exclusive with `random_steering`. + """ + + pool_weights: Dict[str, float] + """A mapping of pool IDs to custom weights, relative to the other pools. + + The declarative alternative to `random_steering.pool_weights`; mutually + exclusive with `random_steering`. + """ + + pools: SequenceNotStr[str] + """A flat, ordered list of pool IDs to route the matched audience to. + + Replaces the resolved topology with exactly these pools. Mutually exclusive with + `fixed_response`. + """ + + steering_policy: SteeringPolicy + """Steering Policy for this load balancer. + + - `"off"`: Use `default_pools`. + - `"geo"`: Use `region_pools`/`country_pools`/`pop_pools`. For non-proxied + requests, the country for `country_pools` is determined by + `location_strategy`. + - `"random"`: Select a pool randomly. + - `"dynamic_latency"`: Use round trip time to select the closest pool in + default_pools (requires pool health checks). + - `"proximity"`: Use the pools' latitude and longitude to select the closest + pool using the Cloudflare PoP location for proxied requests or the location + determined by `location_strategy` for non-proxied requests. + - `"least_outstanding_requests"`: Select a pool by taking into consideration + `random_steering` weights, as well as each pool's number of outstanding + requests. Pools with more pending requests are weighted proportionately less + relative to others. + - `"least_connections"`: Select a pool by taking into consideration + `random_steering` weights, as well as each pool's number of open connections. + Pools with more open connections are weighted proportionately less relative to + others. Supported for HTTP/1 and HTTP/2 connections. + - `""`: Will map to `"geo"` if you use + `region_pools`/`country_pools`/`pop_pools` otherwise `"off"`. + """ + + +class PoolSet(TypedDict, total=False): + """One entry in a load balancer's `pool_sets`. + + Pool sets are evaluated in array order; the first whose `match` succeeds applies its `overrides` (or `fixed_response`), and evaluation stops there. + """ + + disabled: bool + """Disable this specific pool set. It will no longer be evaluated.""" + + fixed_response: PoolSetFixedResponse + """ + A collection of fields used to directly respond to the client instead of routing + to a pool. When supplied on a rule, that rule stops further rule evaluation. + """ + + match: PoolSetMatch + """Determines which requests a pool set applies to. + + Set `topology` to match by location or `default: true` to match all requests; + the two are mutually exclusive. A pool set with no `match` matches all requests. + """ + + name: str + """A human-readable name for this pool set.""" + + overrides: PoolSetOverrides + """The behavior a pool set applies when its `match` succeeds. + + A strict subset of a rule's `overrides`: a pool set replaces the topology + wholesale with a flat pool list (`pools`), so only the declarative pool-routing + fields plus `fallback_pool` and `steering_policy` are settable. All fields are + optional. + """ diff --git a/src/cloudflare/types/load_balancers/pool_create_params.py b/src/cloudflare/types/load_balancers/pool_create_params.py index 08779830381..2f80eff773e 100644 --- a/src/cloudflare/types/load_balancers/pool_create_params.py +++ b/src/cloudflare/types/load_balancers/pool_create_params.py @@ -2,9 +2,11 @@ from __future__ import annotations -from typing import Iterable, Optional -from typing_extensions import Required, TypedDict +from typing import List, Iterable, Optional +from typing_extensions import Literal, Required, TypedDict +from ..._types import SequenceNotStr +from .check_region import CheckRegion from .origin_param import OriginParam from .load_shedding_param import LoadSheddingParam from .origin_steering_param import OriginSteeringParam @@ -30,6 +32,12 @@ class PoolCreateParams(TypedDict, total=False): provided the pool itself is healthy. """ + check_regions: Optional[List[CheckRegion]] + """A list of regions from which to run health checks. + + Null means every Cloudflare data center. + """ + description: str """A human-readable description of the pool.""" @@ -41,6 +49,18 @@ class PoolCreateParams(TypedDict, total=False): pool (if any). """ + health_sources: Optional[List[Literal["local", "regional", "global"]]] + """ + A list of health sources, ordered from highest to lowest priority, used to + evaluate individual origin health and overall pool health. The load balancer + uses the first source that has data and falls back to the next. Currently + accepted values are null or the exact array ["regional", "global"]; any other + combination is rejected. Null (the default) behaves like ["local", "global"]. + ["regional", "global"] makes each region steer on its own health, falling back + to the global decision when a region has no fresh data. Setting regional + requires at least one region in check_regions. + """ + latitude: float """ The latitude of the data center containing the origins used in this pool in @@ -75,6 +95,9 @@ class PoolCreateParams(TypedDict, total=False): this pool. """ + networks: SequenceNotStr[str] + """List of networks where Load Balancer or Pool is enabled.""" + notification_email: str """This field is now deprecated. diff --git a/src/cloudflare/types/load_balancers/pool_edit_params.py b/src/cloudflare/types/load_balancers/pool_edit_params.py index c13a6340306..0a02764b5ec 100644 --- a/src/cloudflare/types/load_balancers/pool_edit_params.py +++ b/src/cloudflare/types/load_balancers/pool_edit_params.py @@ -5,6 +5,7 @@ from typing import List, Iterable, Optional from typing_extensions import Literal, Required, TypedDict +from ..._types import SequenceNotStr from .check_region import CheckRegion from .origin_param import OriginParam from .load_shedding_param import LoadSheddingParam @@ -87,6 +88,9 @@ class PoolEditParams(TypedDict, total=False): Only alphanumeric characters, hyphens, and underscores are allowed. """ + networks: SequenceNotStr[str] + """List of networks where Load Balancer or Pool is enabled.""" + notification_email: str """This field is now deprecated. diff --git a/src/cloudflare/types/load_balancers/pool_update_params.py b/src/cloudflare/types/load_balancers/pool_update_params.py index 16f8fc18e02..2a4fa5d0aaf 100644 --- a/src/cloudflare/types/load_balancers/pool_update_params.py +++ b/src/cloudflare/types/load_balancers/pool_update_params.py @@ -5,6 +5,7 @@ from typing import List, Iterable, Optional from typing_extensions import Literal, Required, TypedDict +from ..._types import SequenceNotStr from .check_region import CheckRegion from .origin_param import OriginParam from .load_shedding_param import LoadSheddingParam @@ -94,6 +95,9 @@ class PoolUpdateParams(TypedDict, total=False): this pool. """ + networks: SequenceNotStr[str] + """List of networks where Load Balancer or Pool is enabled.""" + notification_email: str """This field is now deprecated. diff --git a/src/cloudflare/types/load_balancers/rules.py b/src/cloudflare/types/load_balancers/rules.py index e09709a31a6..5edd8626852 100644 --- a/src/cloudflare/types/load_balancers/rules.py +++ b/src/cloudflare/types/load_balancers/rules.py @@ -4,14 +4,13 @@ from ..._models import BaseModel from .default_pools import DefaultPools -from .random_steering import RandomSteering from .steering_policy import SteeringPolicy from .adaptive_routing import AdaptiveRouting from .session_affinity import SessionAffinity from .location_strategy import LocationStrategy from .session_affinity_attributes import SessionAffinityAttributes -__all__ = ["Rules", "FixedResponse", "Overrides"] +__all__ = ["Rules", "FixedResponse", "Overrides", "OverridesRandomSteering"] class FixedResponse(BaseModel): @@ -32,6 +31,28 @@ class FixedResponse(BaseModel): """The http status code to respond with.""" +class OverridesRandomSteering(BaseModel): + """Configures pool weights for a rule override. + + An omitted default_weight inherits the load balancer's default weight. + - `steering_policy="random"`: A random pool is selected with probability proportional to pool weights. + - `steering_policy="least_outstanding_requests"`: Use pool weights to scale each pool's outstanding requests. + - `steering_policy="least_connections"`: Use pool weights to scale each pool's open connections. + """ + + default_weight: Optional[float] = None + """ + The default weight for pools in the load balancer that are not specified in the + pool_weights map. An omitted value inherits the load balancer's default weight. + """ + + pool_weights: Optional[Dict[str, float]] = None + """A mapping of pool IDs to custom weights. + + The weight is relative to other pools in the load balancer. + """ + + class Overrides(BaseModel): """ A collection of overrides to apply when this rule's condition (or a pool set's `match`) is true. All fields are optional. @@ -100,8 +121,10 @@ class Overrides(BaseModel): region_pool mapping if it exists else to default_pools. """ - random_steering: Optional[RandomSteering] = None - """Configures pool weights. + random_steering: Optional[OverridesRandomSteering] = None + """Configures pool weights for a rule override. + + An omitted default_weight inherits the load balancer's default weight. - `steering_policy="random"`: A random pool is selected with probability proportional to pool weights. @@ -228,9 +251,9 @@ class Rules(BaseModel): priority: Optional[int] = None """The order in which rules should be executed in relation to each other. - Lower values are executed first. Values do not need to be sequential. If no - value is provided for any rule the array order of the rules field will be used - to assign a priority. + Lower values are executed first. Values do not need to be sequential. If all + priorities are omitted or zero, the API assigns priorities based on the array + order of the rules field. """ terminates: Optional[bool] = None diff --git a/src/cloudflare/types/load_balancers/rules_param.py b/src/cloudflare/types/load_balancers/rules_param.py index 5f2f93304bb..eeb08efaa58 100644 --- a/src/cloudflare/types/load_balancers/rules_param.py +++ b/src/cloudflare/types/load_balancers/rules_param.py @@ -9,12 +9,11 @@ from .default_pools import DefaultPools from .steering_policy import SteeringPolicy from .session_affinity import SessionAffinity -from .random_steering_param import RandomSteeringParam from .adaptive_routing_param import AdaptiveRoutingParam from .location_strategy_param import LocationStrategyParam from .session_affinity_attributes_param import SessionAffinityAttributesParam -__all__ = ["RulesParam", "FixedResponse", "Overrides"] +__all__ = ["RulesParam", "FixedResponse", "Overrides", "OverridesRandomSteering"] class FixedResponse(TypedDict, total=False): @@ -35,6 +34,28 @@ class FixedResponse(TypedDict, total=False): """The http status code to respond with.""" +class OverridesRandomSteering(TypedDict, total=False): + """Configures pool weights for a rule override. + + An omitted default_weight inherits the load balancer's default weight. + - `steering_policy="random"`: A random pool is selected with probability proportional to pool weights. + - `steering_policy="least_outstanding_requests"`: Use pool weights to scale each pool's outstanding requests. + - `steering_policy="least_connections"`: Use pool weights to scale each pool's open connections. + """ + + default_weight: float + """ + The default weight for pools in the load balancer that are not specified in the + pool_weights map. An omitted value inherits the load balancer's default weight. + """ + + pool_weights: Dict[str, float] + """A mapping of pool IDs to custom weights. + + The weight is relative to other pools in the load balancer. + """ + + class Overrides(TypedDict, total=False): """ A collection of overrides to apply when this rule's condition (or a pool set's `match`) is true. All fields are optional. @@ -103,8 +124,10 @@ class Overrides(TypedDict, total=False): region_pool mapping if it exists else to default_pools. """ - random_steering: RandomSteeringParam - """Configures pool weights. + random_steering: OverridesRandomSteering + """Configures pool weights for a rule override. + + An omitted default_weight inherits the load balancer's default weight. - `steering_policy="random"`: A random pool is selected with probability proportional to pool weights. @@ -231,9 +254,9 @@ class RulesParam(TypedDict, total=False): priority: int """The order in which rules should be executed in relation to each other. - Lower values are executed first. Values do not need to be sequential. If no - value is provided for any rule the array order of the rules field will be used - to assign a priority. + Lower values are executed first. Values do not need to be sequential. If all + priorities are omitted or zero, the API assigns priorities based on the array + order of the rules field. """ terminates: bool diff --git a/src/cloudflare/types/logpush/job_create_params.py b/src/cloudflare/types/logpush/job_create_params.py index eb10dec0aa6..ced42f55603 100644 --- a/src/cloudflare/types/logpush/job_create_params.py +++ b/src/cloudflare/types/logpush/job_create_params.py @@ -28,6 +28,7 @@ class JobCreateParams(TypedDict, total=False): Literal[ "access_requests", "account_abuse_protection_events", + "ai_gateway_events", "audit_logs", "audit_logs_v2", "biso_user_actions", diff --git a/src/cloudflare/types/logpush/logpush_job.py b/src/cloudflare/types/logpush/logpush_job.py index b3f3fe7c8eb..b2709c4046d 100644 --- a/src/cloudflare/types/logpush/logpush_job.py +++ b/src/cloudflare/types/logpush/logpush_job.py @@ -18,6 +18,7 @@ class LogpushJob(BaseModel): Literal[ "access_requests", "account_abuse_protection_events", + "ai_gateway_events", "audit_logs", "audit_logs_v2", "biso_user_actions", diff --git a/src/cloudflare/types/logpush/output_options.py b/src/cloudflare/types/logpush/output_options.py index ea7cdac8417..3029829d208 100644 --- a/src/cloudflare/types/logpush/output_options.py +++ b/src/cloudflare/types/logpush/output_options.py @@ -41,8 +41,7 @@ class OutputOptions(BaseModel): merge_subrequests: Optional[bool] = None """If set to true, subrequests will be merged into the parent request. - Only supported for the `http_requests` dataset. Not supported for account-scoped - jobs. + Only supported for the `http_requests` dataset. """ output_type: Optional[Literal["ndjson", "csv"]] = None diff --git a/src/cloudflare/types/logpush/output_options_param.py b/src/cloudflare/types/logpush/output_options_param.py index 6fa621c4ed0..e376dd2fe5f 100644 --- a/src/cloudflare/types/logpush/output_options_param.py +++ b/src/cloudflare/types/logpush/output_options_param.py @@ -42,8 +42,7 @@ class OutputOptionsParam(TypedDict, total=False): merge_subrequests: Optional[bool] """If set to true, subrequests will be merged into the parent request. - Only supported for the `http_requests` dataset. Not supported for account-scoped - jobs. + Only supported for the `http_requests` dataset. """ output_type: Literal["ndjson", "csv"] diff --git a/src/cloudflare/types/magic_cloud_networking/__init__.py b/src/cloudflare/types/magic_cloud_networking/__init__.py deleted file mode 100644 index ebb3e55754e..00000000000 --- a/src/cloudflare/types/magic_cloud_networking/__init__.py +++ /dev/null @@ -1,55 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from .on_ramp_get_params import OnRampGetParams as OnRampGetParams -from .on_ramp_edit_params import OnRampEditParams as OnRampEditParams -from .on_ramp_list_params import OnRampListParams as OnRampListParams -from .resource_get_params import ResourceGetParams as ResourceGetParams -from .on_ramp_get_response import OnRampGetResponse as OnRampGetResponse -from .resource_list_params import ResourceListParams as ResourceListParams -from .on_ramp_create_params import OnRampCreateParams as OnRampCreateParams -from .on_ramp_delete_params import OnRampDeleteParams as OnRampDeleteParams -from .on_ramp_edit_response import OnRampEditResponse as OnRampEditResponse -from .on_ramp_list_response import OnRampListResponse as OnRampListResponse -from .on_ramp_plan_response import OnRampPlanResponse as OnRampPlanResponse -from .on_ramp_update_params import OnRampUpdateParams as OnRampUpdateParams -from .resource_get_response import ResourceGetResponse as ResourceGetResponse -from .on_ramp_apply_response import OnRampApplyResponse as OnRampApplyResponse -from .resource_export_params import ResourceExportParams as ResourceExportParams -from .resource_list_response import ResourceListResponse as ResourceListResponse -from .on_ramp_create_response import OnRampCreateResponse as OnRampCreateResponse -from .on_ramp_delete_response import OnRampDeleteResponse as OnRampDeleteResponse -from .on_ramp_update_response import OnRampUpdateResponse as OnRampUpdateResponse -from .catalog_sync_edit_params import CatalogSyncEditParams as CatalogSyncEditParams -from .catalog_sync_get_response import CatalogSyncGetResponse as CatalogSyncGetResponse -from .catalog_sync_create_params import CatalogSyncCreateParams as CatalogSyncCreateParams -from .catalog_sync_delete_params import CatalogSyncDeleteParams as CatalogSyncDeleteParams -from .catalog_sync_edit_response import CatalogSyncEditResponse as CatalogSyncEditResponse -from .catalog_sync_list_response import CatalogSyncListResponse as CatalogSyncListResponse -from .catalog_sync_update_params import CatalogSyncUpdateParams as CatalogSyncUpdateParams -from .catalog_sync_create_response import CatalogSyncCreateResponse as CatalogSyncCreateResponse -from .catalog_sync_delete_response import CatalogSyncDeleteResponse as CatalogSyncDeleteResponse -from .catalog_sync_update_response import CatalogSyncUpdateResponse as CatalogSyncUpdateResponse -from .cloud_integration_get_params import CloudIntegrationGetParams as CloudIntegrationGetParams -from .catalog_sync_refresh_response import CatalogSyncRefreshResponse as CatalogSyncRefreshResponse -from .cloud_integration_edit_params import CloudIntegrationEditParams as CloudIntegrationEditParams -from .cloud_integration_list_params import CloudIntegrationListParams as CloudIntegrationListParams -from .cloud_integration_get_response import CloudIntegrationGetResponse as CloudIntegrationGetResponse -from .resource_policy_preview_params import ResourcePolicyPreviewParams as ResourcePolicyPreviewParams -from .cloud_integration_create_params import CloudIntegrationCreateParams as CloudIntegrationCreateParams -from .cloud_integration_edit_response import CloudIntegrationEditResponse as CloudIntegrationEditResponse -from .cloud_integration_list_response import CloudIntegrationListResponse as CloudIntegrationListResponse -from .cloud_integration_update_params import CloudIntegrationUpdateParams as CloudIntegrationUpdateParams -from .resource_policy_preview_response import ResourcePolicyPreviewResponse as ResourcePolicyPreviewResponse -from .cloud_integration_create_response import CloudIntegrationCreateResponse as CloudIntegrationCreateResponse -from .cloud_integration_delete_response import CloudIntegrationDeleteResponse as CloudIntegrationDeleteResponse -from .cloud_integration_discover_params import CloudIntegrationDiscoverParams as CloudIntegrationDiscoverParams -from .cloud_integration_update_response import CloudIntegrationUpdateResponse as CloudIntegrationUpdateResponse -from .cloud_integration_discover_response import CloudIntegrationDiscoverResponse as CloudIntegrationDiscoverResponse -from .cloud_integration_discover_all_response import ( - CloudIntegrationDiscoverAllResponse as CloudIntegrationDiscoverAllResponse, -) -from .cloud_integration_initial_setup_response import ( - CloudIntegrationInitialSetupResponse as CloudIntegrationInitialSetupResponse, -) diff --git a/src/cloudflare/types/magic_cloud_networking/catalog_sync_create_params.py b/src/cloudflare/types/magic_cloud_networking/catalog_sync_create_params.py deleted file mode 100644 index 18c8dd7a081..00000000000 --- a/src/cloudflare/types/magic_cloud_networking/catalog_sync_create_params.py +++ /dev/null @@ -1,23 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing_extensions import Literal, Required, TypedDict - -__all__ = ["CatalogSyncCreateParams"] - - -class CatalogSyncCreateParams(TypedDict, total=False): - account_id: Required[str] - - destination_type: Required[Literal["NONE", "ZERO_TRUST_LIST"]] - - name: Required[str] - - update_mode: Required[Literal["AUTO", "MANUAL"]] - - description: str - - policy: str - - forwarded: str diff --git a/src/cloudflare/types/magic_cloud_networking/catalog_sync_create_response.py b/src/cloudflare/types/magic_cloud_networking/catalog_sync_create_response.py deleted file mode 100644 index 845ddada455..00000000000 --- a/src/cloudflare/types/magic_cloud_networking/catalog_sync_create_response.py +++ /dev/null @@ -1,220 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from typing import Dict, Optional -from typing_extensions import Literal - -from ..._models import BaseModel - -__all__ = ["CatalogSyncCreateResponse", "Errors", "ErrorsMeta", "ErrorsSource"] - - -class ErrorsMeta(BaseModel): - l10n_key: Optional[str] = None - - loggable_error: Optional[str] = None - - template_data: Optional[object] = None - - trace_id: Optional[str] = None - - -class ErrorsSource(BaseModel): - parameter: Optional[str] = None - - parameter_value_index: Optional[int] = None - - pointer: Optional[str] = None - - -class Errors(BaseModel): - code: Literal[ - 1001, - 1002, - 1003, - 1004, - 1005, - 1006, - 1007, - 1008, - 1009, - 1010, - 1011, - 1012, - 1013, - 1014, - 1015, - 1016, - 1017, - 1018, - 2001, - 2002, - 2003, - 2004, - 2005, - 2006, - 2007, - 2008, - 2009, - 2010, - 2011, - 2012, - 2013, - 2014, - 2015, - 2016, - 2017, - 2018, - 2019, - 2020, - 2021, - 2022, - 3001, - 3002, - 3003, - 3004, - 3005, - 3006, - 3007, - 4001, - 4002, - 4003, - 4004, - 4005, - 4006, - 4007, - 4008, - 4009, - 4010, - 4011, - 4012, - 4013, - 4014, - 4015, - 4016, - 4017, - 4018, - 4019, - 4020, - 4021, - 4022, - 4023, - 5001, - 5002, - 5003, - 5004, - 102000, - 102001, - 102002, - 102003, - 102004, - 102005, - 102006, - 102007, - 102008, - 102009, - 102010, - 102011, - 102012, - 102013, - 102014, - 102015, - 102016, - 102017, - 102018, - 102019, - 102020, - 102021, - 102022, - 102023, - 102024, - 102025, - 102026, - 102027, - 102028, - 102029, - 102030, - 102031, - 102032, - 102033, - 102034, - 102035, - 102036, - 102037, - 102038, - 102039, - 102040, - 102041, - 102042, - 102043, - 102044, - 102045, - 102046, - 102047, - 102048, - 102049, - 102050, - 102051, - 102052, - 102053, - 102054, - 102055, - 102056, - 102057, - 102058, - 102059, - 102060, - 102061, - 102062, - 102063, - 102064, - 102065, - 102066, - 102067, - 102068, - 102069, - 102070, - 102071, - 102072, - 103001, - 103002, - 103003, - 103004, - 103005, - 103006, - 103007, - 103008, - ] - - message: str - - documentation_url: Optional[str] = None - - meta: Optional[ErrorsMeta] = None - - source: Optional[ErrorsSource] = None - - -class CatalogSyncCreateResponse(BaseModel): - id: str - - description: str - - destination_id: str - - destination_type: Literal["NONE", "ZERO_TRUST_LIST"] - - last_user_update_at: str - - name: str - - policy: str - - update_mode: Literal["AUTO", "MANUAL"] - - errors: Optional[Dict[str, Errors]] = None - - includes_discoveries_until: Optional[str] = None - - last_attempted_update_at: Optional[str] = None - - last_successful_update_at: Optional[str] = None diff --git a/src/cloudflare/types/magic_cloud_networking/catalog_sync_delete_params.py b/src/cloudflare/types/magic_cloud_networking/catalog_sync_delete_params.py deleted file mode 100644 index b8422d6eef9..00000000000 --- a/src/cloudflare/types/magic_cloud_networking/catalog_sync_delete_params.py +++ /dev/null @@ -1,13 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing_extensions import Required, TypedDict - -__all__ = ["CatalogSyncDeleteParams"] - - -class CatalogSyncDeleteParams(TypedDict, total=False): - account_id: Required[str] - - delete_destination: bool diff --git a/src/cloudflare/types/magic_cloud_networking/catalog_sync_delete_response.py b/src/cloudflare/types/magic_cloud_networking/catalog_sync_delete_response.py deleted file mode 100644 index 0d982cf9640..00000000000 --- a/src/cloudflare/types/magic_cloud_networking/catalog_sync_delete_response.py +++ /dev/null @@ -1,9 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from ..._models import BaseModel - -__all__ = ["CatalogSyncDeleteResponse"] - - -class CatalogSyncDeleteResponse(BaseModel): - id: str diff --git a/src/cloudflare/types/magic_cloud_networking/catalog_sync_edit_params.py b/src/cloudflare/types/magic_cloud_networking/catalog_sync_edit_params.py deleted file mode 100644 index 4d4c617d89a..00000000000 --- a/src/cloudflare/types/magic_cloud_networking/catalog_sync_edit_params.py +++ /dev/null @@ -1,19 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing_extensions import Literal, Required, TypedDict - -__all__ = ["CatalogSyncEditParams"] - - -class CatalogSyncEditParams(TypedDict, total=False): - account_id: Required[str] - - description: str - - name: str - - policy: str - - update_mode: Literal["AUTO", "MANUAL"] diff --git a/src/cloudflare/types/magic_cloud_networking/catalog_sync_edit_response.py b/src/cloudflare/types/magic_cloud_networking/catalog_sync_edit_response.py deleted file mode 100644 index fe1abbc965f..00000000000 --- a/src/cloudflare/types/magic_cloud_networking/catalog_sync_edit_response.py +++ /dev/null @@ -1,220 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from typing import Dict, Optional -from typing_extensions import Literal - -from ..._models import BaseModel - -__all__ = ["CatalogSyncEditResponse", "Errors", "ErrorsMeta", "ErrorsSource"] - - -class ErrorsMeta(BaseModel): - l10n_key: Optional[str] = None - - loggable_error: Optional[str] = None - - template_data: Optional[object] = None - - trace_id: Optional[str] = None - - -class ErrorsSource(BaseModel): - parameter: Optional[str] = None - - parameter_value_index: Optional[int] = None - - pointer: Optional[str] = None - - -class Errors(BaseModel): - code: Literal[ - 1001, - 1002, - 1003, - 1004, - 1005, - 1006, - 1007, - 1008, - 1009, - 1010, - 1011, - 1012, - 1013, - 1014, - 1015, - 1016, - 1017, - 1018, - 2001, - 2002, - 2003, - 2004, - 2005, - 2006, - 2007, - 2008, - 2009, - 2010, - 2011, - 2012, - 2013, - 2014, - 2015, - 2016, - 2017, - 2018, - 2019, - 2020, - 2021, - 2022, - 3001, - 3002, - 3003, - 3004, - 3005, - 3006, - 3007, - 4001, - 4002, - 4003, - 4004, - 4005, - 4006, - 4007, - 4008, - 4009, - 4010, - 4011, - 4012, - 4013, - 4014, - 4015, - 4016, - 4017, - 4018, - 4019, - 4020, - 4021, - 4022, - 4023, - 5001, - 5002, - 5003, - 5004, - 102000, - 102001, - 102002, - 102003, - 102004, - 102005, - 102006, - 102007, - 102008, - 102009, - 102010, - 102011, - 102012, - 102013, - 102014, - 102015, - 102016, - 102017, - 102018, - 102019, - 102020, - 102021, - 102022, - 102023, - 102024, - 102025, - 102026, - 102027, - 102028, - 102029, - 102030, - 102031, - 102032, - 102033, - 102034, - 102035, - 102036, - 102037, - 102038, - 102039, - 102040, - 102041, - 102042, - 102043, - 102044, - 102045, - 102046, - 102047, - 102048, - 102049, - 102050, - 102051, - 102052, - 102053, - 102054, - 102055, - 102056, - 102057, - 102058, - 102059, - 102060, - 102061, - 102062, - 102063, - 102064, - 102065, - 102066, - 102067, - 102068, - 102069, - 102070, - 102071, - 102072, - 103001, - 103002, - 103003, - 103004, - 103005, - 103006, - 103007, - 103008, - ] - - message: str - - documentation_url: Optional[str] = None - - meta: Optional[ErrorsMeta] = None - - source: Optional[ErrorsSource] = None - - -class CatalogSyncEditResponse(BaseModel): - id: str - - description: str - - destination_id: str - - destination_type: Literal["NONE", "ZERO_TRUST_LIST"] - - last_user_update_at: str - - name: str - - policy: str - - update_mode: Literal["AUTO", "MANUAL"] - - errors: Optional[Dict[str, Errors]] = None - - includes_discoveries_until: Optional[str] = None - - last_attempted_update_at: Optional[str] = None - - last_successful_update_at: Optional[str] = None diff --git a/src/cloudflare/types/magic_cloud_networking/catalog_sync_get_response.py b/src/cloudflare/types/magic_cloud_networking/catalog_sync_get_response.py deleted file mode 100644 index b8dcdebfed4..00000000000 --- a/src/cloudflare/types/magic_cloud_networking/catalog_sync_get_response.py +++ /dev/null @@ -1,220 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from typing import Dict, Optional -from typing_extensions import Literal - -from ..._models import BaseModel - -__all__ = ["CatalogSyncGetResponse", "Errors", "ErrorsMeta", "ErrorsSource"] - - -class ErrorsMeta(BaseModel): - l10n_key: Optional[str] = None - - loggable_error: Optional[str] = None - - template_data: Optional[object] = None - - trace_id: Optional[str] = None - - -class ErrorsSource(BaseModel): - parameter: Optional[str] = None - - parameter_value_index: Optional[int] = None - - pointer: Optional[str] = None - - -class Errors(BaseModel): - code: Literal[ - 1001, - 1002, - 1003, - 1004, - 1005, - 1006, - 1007, - 1008, - 1009, - 1010, - 1011, - 1012, - 1013, - 1014, - 1015, - 1016, - 1017, - 1018, - 2001, - 2002, - 2003, - 2004, - 2005, - 2006, - 2007, - 2008, - 2009, - 2010, - 2011, - 2012, - 2013, - 2014, - 2015, - 2016, - 2017, - 2018, - 2019, - 2020, - 2021, - 2022, - 3001, - 3002, - 3003, - 3004, - 3005, - 3006, - 3007, - 4001, - 4002, - 4003, - 4004, - 4005, - 4006, - 4007, - 4008, - 4009, - 4010, - 4011, - 4012, - 4013, - 4014, - 4015, - 4016, - 4017, - 4018, - 4019, - 4020, - 4021, - 4022, - 4023, - 5001, - 5002, - 5003, - 5004, - 102000, - 102001, - 102002, - 102003, - 102004, - 102005, - 102006, - 102007, - 102008, - 102009, - 102010, - 102011, - 102012, - 102013, - 102014, - 102015, - 102016, - 102017, - 102018, - 102019, - 102020, - 102021, - 102022, - 102023, - 102024, - 102025, - 102026, - 102027, - 102028, - 102029, - 102030, - 102031, - 102032, - 102033, - 102034, - 102035, - 102036, - 102037, - 102038, - 102039, - 102040, - 102041, - 102042, - 102043, - 102044, - 102045, - 102046, - 102047, - 102048, - 102049, - 102050, - 102051, - 102052, - 102053, - 102054, - 102055, - 102056, - 102057, - 102058, - 102059, - 102060, - 102061, - 102062, - 102063, - 102064, - 102065, - 102066, - 102067, - 102068, - 102069, - 102070, - 102071, - 102072, - 103001, - 103002, - 103003, - 103004, - 103005, - 103006, - 103007, - 103008, - ] - - message: str - - documentation_url: Optional[str] = None - - meta: Optional[ErrorsMeta] = None - - source: Optional[ErrorsSource] = None - - -class CatalogSyncGetResponse(BaseModel): - id: str - - description: str - - destination_id: str - - destination_type: Literal["NONE", "ZERO_TRUST_LIST"] - - last_user_update_at: str - - name: str - - policy: str - - update_mode: Literal["AUTO", "MANUAL"] - - errors: Optional[Dict[str, Errors]] = None - - includes_discoveries_until: Optional[str] = None - - last_attempted_update_at: Optional[str] = None - - last_successful_update_at: Optional[str] = None diff --git a/src/cloudflare/types/magic_cloud_networking/catalog_sync_list_response.py b/src/cloudflare/types/magic_cloud_networking/catalog_sync_list_response.py deleted file mode 100644 index 75f04b5f4ce..00000000000 --- a/src/cloudflare/types/magic_cloud_networking/catalog_sync_list_response.py +++ /dev/null @@ -1,220 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from typing import Dict, Optional -from typing_extensions import Literal - -from ..._models import BaseModel - -__all__ = ["CatalogSyncListResponse", "Errors", "ErrorsMeta", "ErrorsSource"] - - -class ErrorsMeta(BaseModel): - l10n_key: Optional[str] = None - - loggable_error: Optional[str] = None - - template_data: Optional[object] = None - - trace_id: Optional[str] = None - - -class ErrorsSource(BaseModel): - parameter: Optional[str] = None - - parameter_value_index: Optional[int] = None - - pointer: Optional[str] = None - - -class Errors(BaseModel): - code: Literal[ - 1001, - 1002, - 1003, - 1004, - 1005, - 1006, - 1007, - 1008, - 1009, - 1010, - 1011, - 1012, - 1013, - 1014, - 1015, - 1016, - 1017, - 1018, - 2001, - 2002, - 2003, - 2004, - 2005, - 2006, - 2007, - 2008, - 2009, - 2010, - 2011, - 2012, - 2013, - 2014, - 2015, - 2016, - 2017, - 2018, - 2019, - 2020, - 2021, - 2022, - 3001, - 3002, - 3003, - 3004, - 3005, - 3006, - 3007, - 4001, - 4002, - 4003, - 4004, - 4005, - 4006, - 4007, - 4008, - 4009, - 4010, - 4011, - 4012, - 4013, - 4014, - 4015, - 4016, - 4017, - 4018, - 4019, - 4020, - 4021, - 4022, - 4023, - 5001, - 5002, - 5003, - 5004, - 102000, - 102001, - 102002, - 102003, - 102004, - 102005, - 102006, - 102007, - 102008, - 102009, - 102010, - 102011, - 102012, - 102013, - 102014, - 102015, - 102016, - 102017, - 102018, - 102019, - 102020, - 102021, - 102022, - 102023, - 102024, - 102025, - 102026, - 102027, - 102028, - 102029, - 102030, - 102031, - 102032, - 102033, - 102034, - 102035, - 102036, - 102037, - 102038, - 102039, - 102040, - 102041, - 102042, - 102043, - 102044, - 102045, - 102046, - 102047, - 102048, - 102049, - 102050, - 102051, - 102052, - 102053, - 102054, - 102055, - 102056, - 102057, - 102058, - 102059, - 102060, - 102061, - 102062, - 102063, - 102064, - 102065, - 102066, - 102067, - 102068, - 102069, - 102070, - 102071, - 102072, - 103001, - 103002, - 103003, - 103004, - 103005, - 103006, - 103007, - 103008, - ] - - message: str - - documentation_url: Optional[str] = None - - meta: Optional[ErrorsMeta] = None - - source: Optional[ErrorsSource] = None - - -class CatalogSyncListResponse(BaseModel): - id: str - - description: str - - destination_id: str - - destination_type: Literal["NONE", "ZERO_TRUST_LIST"] - - last_user_update_at: str - - name: str - - policy: str - - update_mode: Literal["AUTO", "MANUAL"] - - errors: Optional[Dict[str, Errors]] = None - - includes_discoveries_until: Optional[str] = None - - last_attempted_update_at: Optional[str] = None - - last_successful_update_at: Optional[str] = None diff --git a/src/cloudflare/types/magic_cloud_networking/catalog_sync_refresh_response.py b/src/cloudflare/types/magic_cloud_networking/catalog_sync_refresh_response.py deleted file mode 100644 index 2a04a2d1f5c..00000000000 --- a/src/cloudflare/types/magic_cloud_networking/catalog_sync_refresh_response.py +++ /dev/null @@ -1,7 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from typing_extensions import TypeAlias - -__all__ = ["CatalogSyncRefreshResponse"] - -CatalogSyncRefreshResponse: TypeAlias = str diff --git a/src/cloudflare/types/magic_cloud_networking/catalog_sync_update_params.py b/src/cloudflare/types/magic_cloud_networking/catalog_sync_update_params.py deleted file mode 100644 index b3503d5f411..00000000000 --- a/src/cloudflare/types/magic_cloud_networking/catalog_sync_update_params.py +++ /dev/null @@ -1,19 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing_extensions import Literal, Required, TypedDict - -__all__ = ["CatalogSyncUpdateParams"] - - -class CatalogSyncUpdateParams(TypedDict, total=False): - account_id: Required[str] - - description: str - - name: str - - policy: str - - update_mode: Literal["AUTO", "MANUAL"] diff --git a/src/cloudflare/types/magic_cloud_networking/catalog_sync_update_response.py b/src/cloudflare/types/magic_cloud_networking/catalog_sync_update_response.py deleted file mode 100644 index 0d4ca7aa5cb..00000000000 --- a/src/cloudflare/types/magic_cloud_networking/catalog_sync_update_response.py +++ /dev/null @@ -1,220 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from typing import Dict, Optional -from typing_extensions import Literal - -from ..._models import BaseModel - -__all__ = ["CatalogSyncUpdateResponse", "Errors", "ErrorsMeta", "ErrorsSource"] - - -class ErrorsMeta(BaseModel): - l10n_key: Optional[str] = None - - loggable_error: Optional[str] = None - - template_data: Optional[object] = None - - trace_id: Optional[str] = None - - -class ErrorsSource(BaseModel): - parameter: Optional[str] = None - - parameter_value_index: Optional[int] = None - - pointer: Optional[str] = None - - -class Errors(BaseModel): - code: Literal[ - 1001, - 1002, - 1003, - 1004, - 1005, - 1006, - 1007, - 1008, - 1009, - 1010, - 1011, - 1012, - 1013, - 1014, - 1015, - 1016, - 1017, - 1018, - 2001, - 2002, - 2003, - 2004, - 2005, - 2006, - 2007, - 2008, - 2009, - 2010, - 2011, - 2012, - 2013, - 2014, - 2015, - 2016, - 2017, - 2018, - 2019, - 2020, - 2021, - 2022, - 3001, - 3002, - 3003, - 3004, - 3005, - 3006, - 3007, - 4001, - 4002, - 4003, - 4004, - 4005, - 4006, - 4007, - 4008, - 4009, - 4010, - 4011, - 4012, - 4013, - 4014, - 4015, - 4016, - 4017, - 4018, - 4019, - 4020, - 4021, - 4022, - 4023, - 5001, - 5002, - 5003, - 5004, - 102000, - 102001, - 102002, - 102003, - 102004, - 102005, - 102006, - 102007, - 102008, - 102009, - 102010, - 102011, - 102012, - 102013, - 102014, - 102015, - 102016, - 102017, - 102018, - 102019, - 102020, - 102021, - 102022, - 102023, - 102024, - 102025, - 102026, - 102027, - 102028, - 102029, - 102030, - 102031, - 102032, - 102033, - 102034, - 102035, - 102036, - 102037, - 102038, - 102039, - 102040, - 102041, - 102042, - 102043, - 102044, - 102045, - 102046, - 102047, - 102048, - 102049, - 102050, - 102051, - 102052, - 102053, - 102054, - 102055, - 102056, - 102057, - 102058, - 102059, - 102060, - 102061, - 102062, - 102063, - 102064, - 102065, - 102066, - 102067, - 102068, - 102069, - 102070, - 102071, - 102072, - 103001, - 103002, - 103003, - 103004, - 103005, - 103006, - 103007, - 103008, - ] - - message: str - - documentation_url: Optional[str] = None - - meta: Optional[ErrorsMeta] = None - - source: Optional[ErrorsSource] = None - - -class CatalogSyncUpdateResponse(BaseModel): - id: str - - description: str - - destination_id: str - - destination_type: Literal["NONE", "ZERO_TRUST_LIST"] - - last_user_update_at: str - - name: str - - policy: str - - update_mode: Literal["AUTO", "MANUAL"] - - errors: Optional[Dict[str, Errors]] = None - - includes_discoveries_until: Optional[str] = None - - last_attempted_update_at: Optional[str] = None - - last_successful_update_at: Optional[str] = None diff --git a/src/cloudflare/types/magic_cloud_networking/catalog_syncs/__init__.py b/src/cloudflare/types/magic_cloud_networking/catalog_syncs/__init__.py deleted file mode 100644 index 87a6478946d..00000000000 --- a/src/cloudflare/types/magic_cloud_networking/catalog_syncs/__init__.py +++ /dev/null @@ -1,6 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from .prebuilt_policy_list_params import PrebuiltPolicyListParams as PrebuiltPolicyListParams -from .prebuilt_policy_list_response import PrebuiltPolicyListResponse as PrebuiltPolicyListResponse diff --git a/src/cloudflare/types/magic_cloud_networking/catalog_syncs/prebuilt_policy_list_params.py b/src/cloudflare/types/magic_cloud_networking/catalog_syncs/prebuilt_policy_list_params.py deleted file mode 100644 index d13cde44409..00000000000 --- a/src/cloudflare/types/magic_cloud_networking/catalog_syncs/prebuilt_policy_list_params.py +++ /dev/null @@ -1,14 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing_extensions import Literal, Required, TypedDict - -__all__ = ["PrebuiltPolicyListParams"] - - -class PrebuiltPolicyListParams(TypedDict, total=False): - account_id: Required[str] - - destination_type: Literal["NONE", "ZERO_TRUST_LIST"] - """Specify type of destination, omit to return all.""" diff --git a/src/cloudflare/types/magic_cloud_networking/catalog_syncs/prebuilt_policy_list_response.py b/src/cloudflare/types/magic_cloud_networking/catalog_syncs/prebuilt_policy_list_response.py deleted file mode 100644 index f15faa8c685..00000000000 --- a/src/cloudflare/types/magic_cloud_networking/catalog_syncs/prebuilt_policy_list_response.py +++ /dev/null @@ -1,18 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from typing import List -from typing_extensions import Literal - -from ...._models import BaseModel - -__all__ = ["PrebuiltPolicyListResponse"] - - -class PrebuiltPolicyListResponse(BaseModel): - applicable_destinations: List[Literal["NONE", "ZERO_TRUST_LIST"]] - - policy_description: str - - policy_name: str - - policy_string: str diff --git a/src/cloudflare/types/magic_cloud_networking/cloud_integration_create_params.py b/src/cloudflare/types/magic_cloud_networking/cloud_integration_create_params.py deleted file mode 100644 index 066d1a6d3bd..00000000000 --- a/src/cloudflare/types/magic_cloud_networking/cloud_integration_create_params.py +++ /dev/null @@ -1,19 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing_extensions import Literal, Required, TypedDict - -__all__ = ["CloudIntegrationCreateParams"] - - -class CloudIntegrationCreateParams(TypedDict, total=False): - account_id: Required[str] - - cloud_type: Required[Literal["AWS", "AZURE", "GOOGLE", "CLOUDFLARE"]] - - friendly_name: Required[str] - - description: str - - forwarded: str diff --git a/src/cloudflare/types/magic_cloud_networking/cloud_integration_create_response.py b/src/cloudflare/types/magic_cloud_networking/cloud_integration_create_response.py deleted file mode 100644 index ffaadd9ae06..00000000000 --- a/src/cloudflare/types/magic_cloud_networking/cloud_integration_create_response.py +++ /dev/null @@ -1,102 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from typing import List, Optional -from typing_extensions import Literal - -from ..._models import BaseModel - -__all__ = [ - "CloudIntegrationCreateResponse", - "Status", - "StatusDiscoveryProgress", - "StatusDiscoveryProgressV2", - "StatusInUseBy", -] - - -class StatusDiscoveryProgress(BaseModel): - done: int - - total: int - - unit: str - - -class StatusDiscoveryProgressV2(BaseModel): - done: int - - total: int - - unit: str - - -class StatusInUseBy(BaseModel): - id: str - - client_type: Literal["MAGIC_WAN_CLOUD_ONRAMP"] - - name: str - - -class Status(BaseModel): - discovery_progress: StatusDiscoveryProgress - - discovery_progress_v2: StatusDiscoveryProgressV2 - - last_discovery_status: Literal["UNSPECIFIED", "PENDING", "DISCOVERING", "FAILED", "SUCCEEDED"] - - last_discovery_status_v2: Literal["UNSPECIFIED", "PENDING", "DISCOVERING", "FAILED", "SUCCEEDED"] - - regions: List[str] - - credentials_good_since: Optional[str] = None - - credentials_missing_since: Optional[str] = None - - credentials_rejected_since: Optional[str] = None - - discovery_message: Optional[str] = None - - discovery_message_v2: Optional[str] = None - - in_use_by: Optional[List[StatusInUseBy]] = None - - last_discovery_completed_at: Optional[str] = None - - last_discovery_completed_at_v2: Optional[str] = None - - last_discovery_started_at: Optional[str] = None - - last_discovery_started_at_v2: Optional[str] = None - - last_updated: Optional[str] = None - - -class CloudIntegrationCreateResponse(BaseModel): - id: str - - cloud_type: Literal["AWS", "AZURE", "GOOGLE", "CLOUDFLARE"] - - friendly_name: str - - last_updated: str - - lifecycle_state: Literal["ACTIVE", "PENDING_SETUP", "RETIRED"] - - state: Literal["UNSPECIFIED", "PENDING", "DISCOVERING", "FAILED", "SUCCEEDED"] - - state_v2: Literal["UNSPECIFIED", "PENDING", "DISCOVERING", "FAILED", "SUCCEEDED"] - - aws_arn: Optional[str] = None - - azure_subscription_id: Optional[str] = None - - azure_tenant_id: Optional[str] = None - - description: Optional[str] = None - - gcp_project_id: Optional[str] = None - - gcp_service_account_email: Optional[str] = None - - status: Optional[Status] = None diff --git a/src/cloudflare/types/magic_cloud_networking/cloud_integration_delete_response.py b/src/cloudflare/types/magic_cloud_networking/cloud_integration_delete_response.py deleted file mode 100644 index b84445359c2..00000000000 --- a/src/cloudflare/types/magic_cloud_networking/cloud_integration_delete_response.py +++ /dev/null @@ -1,9 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from ..._models import BaseModel - -__all__ = ["CloudIntegrationDeleteResponse"] - - -class CloudIntegrationDeleteResponse(BaseModel): - id: str diff --git a/src/cloudflare/types/magic_cloud_networking/cloud_integration_discover_all_response.py b/src/cloudflare/types/magic_cloud_networking/cloud_integration_discover_all_response.py deleted file mode 100644 index 8a543eaa169..00000000000 --- a/src/cloudflare/types/magic_cloud_networking/cloud_integration_discover_all_response.py +++ /dev/null @@ -1,396 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from typing import List, Optional -from typing_extensions import Literal - -from ..._models import BaseModel - -__all__ = [ - "CloudIntegrationDiscoverAllResponse", - "Error", - "ErrorMeta", - "ErrorSource", - "Message", - "MessageMeta", - "MessageSource", -] - - -class ErrorMeta(BaseModel): - l10n_key: Optional[str] = None - - loggable_error: Optional[str] = None - - template_data: Optional[object] = None - - trace_id: Optional[str] = None - - -class ErrorSource(BaseModel): - parameter: Optional[str] = None - - parameter_value_index: Optional[int] = None - - pointer: Optional[str] = None - - -class Error(BaseModel): - code: Literal[ - 1001, - 1002, - 1003, - 1004, - 1005, - 1006, - 1007, - 1008, - 1009, - 1010, - 1011, - 1012, - 1013, - 1014, - 1015, - 1016, - 1017, - 1018, - 2001, - 2002, - 2003, - 2004, - 2005, - 2006, - 2007, - 2008, - 2009, - 2010, - 2011, - 2012, - 2013, - 2014, - 2015, - 2016, - 2017, - 2018, - 2019, - 2020, - 2021, - 2022, - 3001, - 3002, - 3003, - 3004, - 3005, - 3006, - 3007, - 4001, - 4002, - 4003, - 4004, - 4005, - 4006, - 4007, - 4008, - 4009, - 4010, - 4011, - 4012, - 4013, - 4014, - 4015, - 4016, - 4017, - 4018, - 4019, - 4020, - 4021, - 4022, - 4023, - 5001, - 5002, - 5003, - 5004, - 102000, - 102001, - 102002, - 102003, - 102004, - 102005, - 102006, - 102007, - 102008, - 102009, - 102010, - 102011, - 102012, - 102013, - 102014, - 102015, - 102016, - 102017, - 102018, - 102019, - 102020, - 102021, - 102022, - 102023, - 102024, - 102025, - 102026, - 102027, - 102028, - 102029, - 102030, - 102031, - 102032, - 102033, - 102034, - 102035, - 102036, - 102037, - 102038, - 102039, - 102040, - 102041, - 102042, - 102043, - 102044, - 102045, - 102046, - 102047, - 102048, - 102049, - 102050, - 102051, - 102052, - 102053, - 102054, - 102055, - 102056, - 102057, - 102058, - 102059, - 102060, - 102061, - 102062, - 102063, - 102064, - 102065, - 102066, - 102067, - 102068, - 102069, - 102070, - 102071, - 102072, - 103001, - 103002, - 103003, - 103004, - 103005, - 103006, - 103007, - 103008, - ] - - message: str - - documentation_url: Optional[str] = None - - meta: Optional[ErrorMeta] = None - - source: Optional[ErrorSource] = None - - -class MessageMeta(BaseModel): - l10n_key: Optional[str] = None - - loggable_error: Optional[str] = None - - template_data: Optional[object] = None - - trace_id: Optional[str] = None - - -class MessageSource(BaseModel): - parameter: Optional[str] = None - - parameter_value_index: Optional[int] = None - - pointer: Optional[str] = None - - -class Message(BaseModel): - code: Literal[ - 1001, - 1002, - 1003, - 1004, - 1005, - 1006, - 1007, - 1008, - 1009, - 1010, - 1011, - 1012, - 1013, - 1014, - 1015, - 1016, - 1017, - 1018, - 2001, - 2002, - 2003, - 2004, - 2005, - 2006, - 2007, - 2008, - 2009, - 2010, - 2011, - 2012, - 2013, - 2014, - 2015, - 2016, - 2017, - 2018, - 2019, - 2020, - 2021, - 2022, - 3001, - 3002, - 3003, - 3004, - 3005, - 3006, - 3007, - 4001, - 4002, - 4003, - 4004, - 4005, - 4006, - 4007, - 4008, - 4009, - 4010, - 4011, - 4012, - 4013, - 4014, - 4015, - 4016, - 4017, - 4018, - 4019, - 4020, - 4021, - 4022, - 4023, - 5001, - 5002, - 5003, - 5004, - 102000, - 102001, - 102002, - 102003, - 102004, - 102005, - 102006, - 102007, - 102008, - 102009, - 102010, - 102011, - 102012, - 102013, - 102014, - 102015, - 102016, - 102017, - 102018, - 102019, - 102020, - 102021, - 102022, - 102023, - 102024, - 102025, - 102026, - 102027, - 102028, - 102029, - 102030, - 102031, - 102032, - 102033, - 102034, - 102035, - 102036, - 102037, - 102038, - 102039, - 102040, - 102041, - 102042, - 102043, - 102044, - 102045, - 102046, - 102047, - 102048, - 102049, - 102050, - 102051, - 102052, - 102053, - 102054, - 102055, - 102056, - 102057, - 102058, - 102059, - 102060, - 102061, - 102062, - 102063, - 102064, - 102065, - 102066, - 102067, - 102068, - 102069, - 102070, - 102071, - 102072, - 103001, - 103002, - 103003, - 103004, - 103005, - 103006, - 103007, - 103008, - ] - - message: str - - documentation_url: Optional[str] = None - - meta: Optional[MessageMeta] = None - - source: Optional[MessageSource] = None - - -class CloudIntegrationDiscoverAllResponse(BaseModel): - errors: List[Error] - - messages: List[Message] - - success: bool diff --git a/src/cloudflare/types/magic_cloud_networking/cloud_integration_discover_params.py b/src/cloudflare/types/magic_cloud_networking/cloud_integration_discover_params.py deleted file mode 100644 index f54258bfcbe..00000000000 --- a/src/cloudflare/types/magic_cloud_networking/cloud_integration_discover_params.py +++ /dev/null @@ -1,13 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing_extensions import Required, TypedDict - -__all__ = ["CloudIntegrationDiscoverParams"] - - -class CloudIntegrationDiscoverParams(TypedDict, total=False): - account_id: Required[str] - - v2: bool diff --git a/src/cloudflare/types/magic_cloud_networking/cloud_integration_discover_response.py b/src/cloudflare/types/magic_cloud_networking/cloud_integration_discover_response.py deleted file mode 100644 index 9e817b739b2..00000000000 --- a/src/cloudflare/types/magic_cloud_networking/cloud_integration_discover_response.py +++ /dev/null @@ -1,396 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from typing import List, Optional -from typing_extensions import Literal - -from ..._models import BaseModel - -__all__ = [ - "CloudIntegrationDiscoverResponse", - "Error", - "ErrorMeta", - "ErrorSource", - "Message", - "MessageMeta", - "MessageSource", -] - - -class ErrorMeta(BaseModel): - l10n_key: Optional[str] = None - - loggable_error: Optional[str] = None - - template_data: Optional[object] = None - - trace_id: Optional[str] = None - - -class ErrorSource(BaseModel): - parameter: Optional[str] = None - - parameter_value_index: Optional[int] = None - - pointer: Optional[str] = None - - -class Error(BaseModel): - code: Literal[ - 1001, - 1002, - 1003, - 1004, - 1005, - 1006, - 1007, - 1008, - 1009, - 1010, - 1011, - 1012, - 1013, - 1014, - 1015, - 1016, - 1017, - 1018, - 2001, - 2002, - 2003, - 2004, - 2005, - 2006, - 2007, - 2008, - 2009, - 2010, - 2011, - 2012, - 2013, - 2014, - 2015, - 2016, - 2017, - 2018, - 2019, - 2020, - 2021, - 2022, - 3001, - 3002, - 3003, - 3004, - 3005, - 3006, - 3007, - 4001, - 4002, - 4003, - 4004, - 4005, - 4006, - 4007, - 4008, - 4009, - 4010, - 4011, - 4012, - 4013, - 4014, - 4015, - 4016, - 4017, - 4018, - 4019, - 4020, - 4021, - 4022, - 4023, - 5001, - 5002, - 5003, - 5004, - 102000, - 102001, - 102002, - 102003, - 102004, - 102005, - 102006, - 102007, - 102008, - 102009, - 102010, - 102011, - 102012, - 102013, - 102014, - 102015, - 102016, - 102017, - 102018, - 102019, - 102020, - 102021, - 102022, - 102023, - 102024, - 102025, - 102026, - 102027, - 102028, - 102029, - 102030, - 102031, - 102032, - 102033, - 102034, - 102035, - 102036, - 102037, - 102038, - 102039, - 102040, - 102041, - 102042, - 102043, - 102044, - 102045, - 102046, - 102047, - 102048, - 102049, - 102050, - 102051, - 102052, - 102053, - 102054, - 102055, - 102056, - 102057, - 102058, - 102059, - 102060, - 102061, - 102062, - 102063, - 102064, - 102065, - 102066, - 102067, - 102068, - 102069, - 102070, - 102071, - 102072, - 103001, - 103002, - 103003, - 103004, - 103005, - 103006, - 103007, - 103008, - ] - - message: str - - documentation_url: Optional[str] = None - - meta: Optional[ErrorMeta] = None - - source: Optional[ErrorSource] = None - - -class MessageMeta(BaseModel): - l10n_key: Optional[str] = None - - loggable_error: Optional[str] = None - - template_data: Optional[object] = None - - trace_id: Optional[str] = None - - -class MessageSource(BaseModel): - parameter: Optional[str] = None - - parameter_value_index: Optional[int] = None - - pointer: Optional[str] = None - - -class Message(BaseModel): - code: Literal[ - 1001, - 1002, - 1003, - 1004, - 1005, - 1006, - 1007, - 1008, - 1009, - 1010, - 1011, - 1012, - 1013, - 1014, - 1015, - 1016, - 1017, - 1018, - 2001, - 2002, - 2003, - 2004, - 2005, - 2006, - 2007, - 2008, - 2009, - 2010, - 2011, - 2012, - 2013, - 2014, - 2015, - 2016, - 2017, - 2018, - 2019, - 2020, - 2021, - 2022, - 3001, - 3002, - 3003, - 3004, - 3005, - 3006, - 3007, - 4001, - 4002, - 4003, - 4004, - 4005, - 4006, - 4007, - 4008, - 4009, - 4010, - 4011, - 4012, - 4013, - 4014, - 4015, - 4016, - 4017, - 4018, - 4019, - 4020, - 4021, - 4022, - 4023, - 5001, - 5002, - 5003, - 5004, - 102000, - 102001, - 102002, - 102003, - 102004, - 102005, - 102006, - 102007, - 102008, - 102009, - 102010, - 102011, - 102012, - 102013, - 102014, - 102015, - 102016, - 102017, - 102018, - 102019, - 102020, - 102021, - 102022, - 102023, - 102024, - 102025, - 102026, - 102027, - 102028, - 102029, - 102030, - 102031, - 102032, - 102033, - 102034, - 102035, - 102036, - 102037, - 102038, - 102039, - 102040, - 102041, - 102042, - 102043, - 102044, - 102045, - 102046, - 102047, - 102048, - 102049, - 102050, - 102051, - 102052, - 102053, - 102054, - 102055, - 102056, - 102057, - 102058, - 102059, - 102060, - 102061, - 102062, - 102063, - 102064, - 102065, - 102066, - 102067, - 102068, - 102069, - 102070, - 102071, - 102072, - 103001, - 103002, - 103003, - 103004, - 103005, - 103006, - 103007, - 103008, - ] - - message: str - - documentation_url: Optional[str] = None - - meta: Optional[MessageMeta] = None - - source: Optional[MessageSource] = None - - -class CloudIntegrationDiscoverResponse(BaseModel): - errors: List[Error] - - messages: List[Message] - - success: bool diff --git a/src/cloudflare/types/magic_cloud_networking/cloud_integration_edit_params.py b/src/cloudflare/types/magic_cloud_networking/cloud_integration_edit_params.py deleted file mode 100644 index e069ee25408..00000000000 --- a/src/cloudflare/types/magic_cloud_networking/cloud_integration_edit_params.py +++ /dev/null @@ -1,25 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing_extensions import Required, TypedDict - -__all__ = ["CloudIntegrationEditParams"] - - -class CloudIntegrationEditParams(TypedDict, total=False): - account_id: Required[str] - - aws_arn: str - - azure_subscription_id: str - - azure_tenant_id: str - - description: str - - friendly_name: str - - gcp_project_id: str - - gcp_service_account_email: str diff --git a/src/cloudflare/types/magic_cloud_networking/cloud_integration_edit_response.py b/src/cloudflare/types/magic_cloud_networking/cloud_integration_edit_response.py deleted file mode 100644 index c558b193ffe..00000000000 --- a/src/cloudflare/types/magic_cloud_networking/cloud_integration_edit_response.py +++ /dev/null @@ -1,102 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from typing import List, Optional -from typing_extensions import Literal - -from ..._models import BaseModel - -__all__ = [ - "CloudIntegrationEditResponse", - "Status", - "StatusDiscoveryProgress", - "StatusDiscoveryProgressV2", - "StatusInUseBy", -] - - -class StatusDiscoveryProgress(BaseModel): - done: int - - total: int - - unit: str - - -class StatusDiscoveryProgressV2(BaseModel): - done: int - - total: int - - unit: str - - -class StatusInUseBy(BaseModel): - id: str - - client_type: Literal["MAGIC_WAN_CLOUD_ONRAMP"] - - name: str - - -class Status(BaseModel): - discovery_progress: StatusDiscoveryProgress - - discovery_progress_v2: StatusDiscoveryProgressV2 - - last_discovery_status: Literal["UNSPECIFIED", "PENDING", "DISCOVERING", "FAILED", "SUCCEEDED"] - - last_discovery_status_v2: Literal["UNSPECIFIED", "PENDING", "DISCOVERING", "FAILED", "SUCCEEDED"] - - regions: List[str] - - credentials_good_since: Optional[str] = None - - credentials_missing_since: Optional[str] = None - - credentials_rejected_since: Optional[str] = None - - discovery_message: Optional[str] = None - - discovery_message_v2: Optional[str] = None - - in_use_by: Optional[List[StatusInUseBy]] = None - - last_discovery_completed_at: Optional[str] = None - - last_discovery_completed_at_v2: Optional[str] = None - - last_discovery_started_at: Optional[str] = None - - last_discovery_started_at_v2: Optional[str] = None - - last_updated: Optional[str] = None - - -class CloudIntegrationEditResponse(BaseModel): - id: str - - cloud_type: Literal["AWS", "AZURE", "GOOGLE", "CLOUDFLARE"] - - friendly_name: str - - last_updated: str - - lifecycle_state: Literal["ACTIVE", "PENDING_SETUP", "RETIRED"] - - state: Literal["UNSPECIFIED", "PENDING", "DISCOVERING", "FAILED", "SUCCEEDED"] - - state_v2: Literal["UNSPECIFIED", "PENDING", "DISCOVERING", "FAILED", "SUCCEEDED"] - - aws_arn: Optional[str] = None - - azure_subscription_id: Optional[str] = None - - azure_tenant_id: Optional[str] = None - - description: Optional[str] = None - - gcp_project_id: Optional[str] = None - - gcp_service_account_email: Optional[str] = None - - status: Optional[Status] = None diff --git a/src/cloudflare/types/magic_cloud_networking/cloud_integration_get_params.py b/src/cloudflare/types/magic_cloud_networking/cloud_integration_get_params.py deleted file mode 100644 index 4a26230bc6f..00000000000 --- a/src/cloudflare/types/magic_cloud_networking/cloud_integration_get_params.py +++ /dev/null @@ -1,13 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing_extensions import Required, TypedDict - -__all__ = ["CloudIntegrationGetParams"] - - -class CloudIntegrationGetParams(TypedDict, total=False): - account_id: Required[str] - - status: bool diff --git a/src/cloudflare/types/magic_cloud_networking/cloud_integration_get_response.py b/src/cloudflare/types/magic_cloud_networking/cloud_integration_get_response.py deleted file mode 100644 index 5774ec5c2e6..00000000000 --- a/src/cloudflare/types/magic_cloud_networking/cloud_integration_get_response.py +++ /dev/null @@ -1,102 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from typing import List, Optional -from typing_extensions import Literal - -from ..._models import BaseModel - -__all__ = [ - "CloudIntegrationGetResponse", - "Status", - "StatusDiscoveryProgress", - "StatusDiscoveryProgressV2", - "StatusInUseBy", -] - - -class StatusDiscoveryProgress(BaseModel): - done: int - - total: int - - unit: str - - -class StatusDiscoveryProgressV2(BaseModel): - done: int - - total: int - - unit: str - - -class StatusInUseBy(BaseModel): - id: str - - client_type: Literal["MAGIC_WAN_CLOUD_ONRAMP"] - - name: str - - -class Status(BaseModel): - discovery_progress: StatusDiscoveryProgress - - discovery_progress_v2: StatusDiscoveryProgressV2 - - last_discovery_status: Literal["UNSPECIFIED", "PENDING", "DISCOVERING", "FAILED", "SUCCEEDED"] - - last_discovery_status_v2: Literal["UNSPECIFIED", "PENDING", "DISCOVERING", "FAILED", "SUCCEEDED"] - - regions: List[str] - - credentials_good_since: Optional[str] = None - - credentials_missing_since: Optional[str] = None - - credentials_rejected_since: Optional[str] = None - - discovery_message: Optional[str] = None - - discovery_message_v2: Optional[str] = None - - in_use_by: Optional[List[StatusInUseBy]] = None - - last_discovery_completed_at: Optional[str] = None - - last_discovery_completed_at_v2: Optional[str] = None - - last_discovery_started_at: Optional[str] = None - - last_discovery_started_at_v2: Optional[str] = None - - last_updated: Optional[str] = None - - -class CloudIntegrationGetResponse(BaseModel): - id: str - - cloud_type: Literal["AWS", "AZURE", "GOOGLE", "CLOUDFLARE"] - - friendly_name: str - - last_updated: str - - lifecycle_state: Literal["ACTIVE", "PENDING_SETUP", "RETIRED"] - - state: Literal["UNSPECIFIED", "PENDING", "DISCOVERING", "FAILED", "SUCCEEDED"] - - state_v2: Literal["UNSPECIFIED", "PENDING", "DISCOVERING", "FAILED", "SUCCEEDED"] - - aws_arn: Optional[str] = None - - azure_subscription_id: Optional[str] = None - - azure_tenant_id: Optional[str] = None - - description: Optional[str] = None - - gcp_project_id: Optional[str] = None - - gcp_service_account_email: Optional[str] = None - - status: Optional[Status] = None diff --git a/src/cloudflare/types/magic_cloud_networking/cloud_integration_initial_setup_response.py b/src/cloudflare/types/magic_cloud_networking/cloud_integration_initial_setup_response.py deleted file mode 100644 index 0f5e59ac598..00000000000 --- a/src/cloudflare/types/magic_cloud_networking/cloud_integration_initial_setup_response.py +++ /dev/null @@ -1,38 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from typing import Union -from typing_extensions import Annotated, TypeAlias - -from ..._utils import PropertyInfo -from ..._models import BaseModel - -__all__ = ["CloudIntegrationInitialSetupResponse", "McnAwsTrustPolicy", "McnAzureSetup", "McnGcpSetup"] - - -class McnAwsTrustPolicy(BaseModel): - aws_trust_policy: str - - item_type: str - - -class McnAzureSetup(BaseModel): - azure_consent_url: str - - integration_identity_tag: str - - item_type: str - - tag_cli_command: str - - -class McnGcpSetup(BaseModel): - integration_identity_tag: str - - item_type: str - - tag_cli_command: str - - -CloudIntegrationInitialSetupResponse: TypeAlias = Annotated[ - Union[McnAwsTrustPolicy, McnAzureSetup, McnGcpSetup], PropertyInfo(discriminator="item_type") -] diff --git a/src/cloudflare/types/magic_cloud_networking/cloud_integration_list_params.py b/src/cloudflare/types/magic_cloud_networking/cloud_integration_list_params.py deleted file mode 100644 index 94bead9742a..00000000000 --- a/src/cloudflare/types/magic_cloud_networking/cloud_integration_list_params.py +++ /dev/null @@ -1,20 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing_extensions import Required, TypedDict - -__all__ = ["CloudIntegrationListParams"] - - -class CloudIntegrationListParams(TypedDict, total=False): - account_id: Required[str] - - cloudflare: bool - - desc: bool - - order_by: str - """One of ["updated_at", "id", "cloud_type", "name"].""" - - status: bool diff --git a/src/cloudflare/types/magic_cloud_networking/cloud_integration_list_response.py b/src/cloudflare/types/magic_cloud_networking/cloud_integration_list_response.py deleted file mode 100644 index 7fa27eeeb38..00000000000 --- a/src/cloudflare/types/magic_cloud_networking/cloud_integration_list_response.py +++ /dev/null @@ -1,102 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from typing import List, Optional -from typing_extensions import Literal - -from ..._models import BaseModel - -__all__ = [ - "CloudIntegrationListResponse", - "Status", - "StatusDiscoveryProgress", - "StatusDiscoveryProgressV2", - "StatusInUseBy", -] - - -class StatusDiscoveryProgress(BaseModel): - done: int - - total: int - - unit: str - - -class StatusDiscoveryProgressV2(BaseModel): - done: int - - total: int - - unit: str - - -class StatusInUseBy(BaseModel): - id: str - - client_type: Literal["MAGIC_WAN_CLOUD_ONRAMP"] - - name: str - - -class Status(BaseModel): - discovery_progress: StatusDiscoveryProgress - - discovery_progress_v2: StatusDiscoveryProgressV2 - - last_discovery_status: Literal["UNSPECIFIED", "PENDING", "DISCOVERING", "FAILED", "SUCCEEDED"] - - last_discovery_status_v2: Literal["UNSPECIFIED", "PENDING", "DISCOVERING", "FAILED", "SUCCEEDED"] - - regions: List[str] - - credentials_good_since: Optional[str] = None - - credentials_missing_since: Optional[str] = None - - credentials_rejected_since: Optional[str] = None - - discovery_message: Optional[str] = None - - discovery_message_v2: Optional[str] = None - - in_use_by: Optional[List[StatusInUseBy]] = None - - last_discovery_completed_at: Optional[str] = None - - last_discovery_completed_at_v2: Optional[str] = None - - last_discovery_started_at: Optional[str] = None - - last_discovery_started_at_v2: Optional[str] = None - - last_updated: Optional[str] = None - - -class CloudIntegrationListResponse(BaseModel): - id: str - - cloud_type: Literal["AWS", "AZURE", "GOOGLE", "CLOUDFLARE"] - - friendly_name: str - - last_updated: str - - lifecycle_state: Literal["ACTIVE", "PENDING_SETUP", "RETIRED"] - - state: Literal["UNSPECIFIED", "PENDING", "DISCOVERING", "FAILED", "SUCCEEDED"] - - state_v2: Literal["UNSPECIFIED", "PENDING", "DISCOVERING", "FAILED", "SUCCEEDED"] - - aws_arn: Optional[str] = None - - azure_subscription_id: Optional[str] = None - - azure_tenant_id: Optional[str] = None - - description: Optional[str] = None - - gcp_project_id: Optional[str] = None - - gcp_service_account_email: Optional[str] = None - - status: Optional[Status] = None diff --git a/src/cloudflare/types/magic_cloud_networking/cloud_integration_update_params.py b/src/cloudflare/types/magic_cloud_networking/cloud_integration_update_params.py deleted file mode 100644 index 9321e19b5d8..00000000000 --- a/src/cloudflare/types/magic_cloud_networking/cloud_integration_update_params.py +++ /dev/null @@ -1,25 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing_extensions import Required, TypedDict - -__all__ = ["CloudIntegrationUpdateParams"] - - -class CloudIntegrationUpdateParams(TypedDict, total=False): - account_id: Required[str] - - aws_arn: str - - azure_subscription_id: str - - azure_tenant_id: str - - description: str - - friendly_name: str - - gcp_project_id: str - - gcp_service_account_email: str diff --git a/src/cloudflare/types/magic_cloud_networking/cloud_integration_update_response.py b/src/cloudflare/types/magic_cloud_networking/cloud_integration_update_response.py deleted file mode 100644 index 80182a46e99..00000000000 --- a/src/cloudflare/types/magic_cloud_networking/cloud_integration_update_response.py +++ /dev/null @@ -1,102 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from typing import List, Optional -from typing_extensions import Literal - -from ..._models import BaseModel - -__all__ = [ - "CloudIntegrationUpdateResponse", - "Status", - "StatusDiscoveryProgress", - "StatusDiscoveryProgressV2", - "StatusInUseBy", -] - - -class StatusDiscoveryProgress(BaseModel): - done: int - - total: int - - unit: str - - -class StatusDiscoveryProgressV2(BaseModel): - done: int - - total: int - - unit: str - - -class StatusInUseBy(BaseModel): - id: str - - client_type: Literal["MAGIC_WAN_CLOUD_ONRAMP"] - - name: str - - -class Status(BaseModel): - discovery_progress: StatusDiscoveryProgress - - discovery_progress_v2: StatusDiscoveryProgressV2 - - last_discovery_status: Literal["UNSPECIFIED", "PENDING", "DISCOVERING", "FAILED", "SUCCEEDED"] - - last_discovery_status_v2: Literal["UNSPECIFIED", "PENDING", "DISCOVERING", "FAILED", "SUCCEEDED"] - - regions: List[str] - - credentials_good_since: Optional[str] = None - - credentials_missing_since: Optional[str] = None - - credentials_rejected_since: Optional[str] = None - - discovery_message: Optional[str] = None - - discovery_message_v2: Optional[str] = None - - in_use_by: Optional[List[StatusInUseBy]] = None - - last_discovery_completed_at: Optional[str] = None - - last_discovery_completed_at_v2: Optional[str] = None - - last_discovery_started_at: Optional[str] = None - - last_discovery_started_at_v2: Optional[str] = None - - last_updated: Optional[str] = None - - -class CloudIntegrationUpdateResponse(BaseModel): - id: str - - cloud_type: Literal["AWS", "AZURE", "GOOGLE", "CLOUDFLARE"] - - friendly_name: str - - last_updated: str - - lifecycle_state: Literal["ACTIVE", "PENDING_SETUP", "RETIRED"] - - state: Literal["UNSPECIFIED", "PENDING", "DISCOVERING", "FAILED", "SUCCEEDED"] - - state_v2: Literal["UNSPECIFIED", "PENDING", "DISCOVERING", "FAILED", "SUCCEEDED"] - - aws_arn: Optional[str] = None - - azure_subscription_id: Optional[str] = None - - azure_tenant_id: Optional[str] = None - - description: Optional[str] = None - - gcp_project_id: Optional[str] = None - - gcp_service_account_email: Optional[str] = None - - status: Optional[Status] = None diff --git a/src/cloudflare/types/magic_cloud_networking/on_ramp_apply_response.py b/src/cloudflare/types/magic_cloud_networking/on_ramp_apply_response.py deleted file mode 100644 index a2681f95e45..00000000000 --- a/src/cloudflare/types/magic_cloud_networking/on_ramp_apply_response.py +++ /dev/null @@ -1,388 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from typing import List, Optional -from typing_extensions import Literal - -from ..._models import BaseModel - -__all__ = ["OnRampApplyResponse", "Error", "ErrorMeta", "ErrorSource", "Message", "MessageMeta", "MessageSource"] - - -class ErrorMeta(BaseModel): - l10n_key: Optional[str] = None - - loggable_error: Optional[str] = None - - template_data: Optional[object] = None - - trace_id: Optional[str] = None - - -class ErrorSource(BaseModel): - parameter: Optional[str] = None - - parameter_value_index: Optional[int] = None - - pointer: Optional[str] = None - - -class Error(BaseModel): - code: Literal[ - 1001, - 1002, - 1003, - 1004, - 1005, - 1006, - 1007, - 1008, - 1009, - 1010, - 1011, - 1012, - 1013, - 1014, - 1015, - 1016, - 1017, - 1018, - 2001, - 2002, - 2003, - 2004, - 2005, - 2006, - 2007, - 2008, - 2009, - 2010, - 2011, - 2012, - 2013, - 2014, - 2015, - 2016, - 2017, - 2018, - 2019, - 2020, - 2021, - 2022, - 3001, - 3002, - 3003, - 3004, - 3005, - 3006, - 3007, - 4001, - 4002, - 4003, - 4004, - 4005, - 4006, - 4007, - 4008, - 4009, - 4010, - 4011, - 4012, - 4013, - 4014, - 4015, - 4016, - 4017, - 4018, - 4019, - 4020, - 4021, - 4022, - 4023, - 5001, - 5002, - 5003, - 5004, - 102000, - 102001, - 102002, - 102003, - 102004, - 102005, - 102006, - 102007, - 102008, - 102009, - 102010, - 102011, - 102012, - 102013, - 102014, - 102015, - 102016, - 102017, - 102018, - 102019, - 102020, - 102021, - 102022, - 102023, - 102024, - 102025, - 102026, - 102027, - 102028, - 102029, - 102030, - 102031, - 102032, - 102033, - 102034, - 102035, - 102036, - 102037, - 102038, - 102039, - 102040, - 102041, - 102042, - 102043, - 102044, - 102045, - 102046, - 102047, - 102048, - 102049, - 102050, - 102051, - 102052, - 102053, - 102054, - 102055, - 102056, - 102057, - 102058, - 102059, - 102060, - 102061, - 102062, - 102063, - 102064, - 102065, - 102066, - 102067, - 102068, - 102069, - 102070, - 102071, - 102072, - 103001, - 103002, - 103003, - 103004, - 103005, - 103006, - 103007, - 103008, - ] - - message: str - - documentation_url: Optional[str] = None - - meta: Optional[ErrorMeta] = None - - source: Optional[ErrorSource] = None - - -class MessageMeta(BaseModel): - l10n_key: Optional[str] = None - - loggable_error: Optional[str] = None - - template_data: Optional[object] = None - - trace_id: Optional[str] = None - - -class MessageSource(BaseModel): - parameter: Optional[str] = None - - parameter_value_index: Optional[int] = None - - pointer: Optional[str] = None - - -class Message(BaseModel): - code: Literal[ - 1001, - 1002, - 1003, - 1004, - 1005, - 1006, - 1007, - 1008, - 1009, - 1010, - 1011, - 1012, - 1013, - 1014, - 1015, - 1016, - 1017, - 1018, - 2001, - 2002, - 2003, - 2004, - 2005, - 2006, - 2007, - 2008, - 2009, - 2010, - 2011, - 2012, - 2013, - 2014, - 2015, - 2016, - 2017, - 2018, - 2019, - 2020, - 2021, - 2022, - 3001, - 3002, - 3003, - 3004, - 3005, - 3006, - 3007, - 4001, - 4002, - 4003, - 4004, - 4005, - 4006, - 4007, - 4008, - 4009, - 4010, - 4011, - 4012, - 4013, - 4014, - 4015, - 4016, - 4017, - 4018, - 4019, - 4020, - 4021, - 4022, - 4023, - 5001, - 5002, - 5003, - 5004, - 102000, - 102001, - 102002, - 102003, - 102004, - 102005, - 102006, - 102007, - 102008, - 102009, - 102010, - 102011, - 102012, - 102013, - 102014, - 102015, - 102016, - 102017, - 102018, - 102019, - 102020, - 102021, - 102022, - 102023, - 102024, - 102025, - 102026, - 102027, - 102028, - 102029, - 102030, - 102031, - 102032, - 102033, - 102034, - 102035, - 102036, - 102037, - 102038, - 102039, - 102040, - 102041, - 102042, - 102043, - 102044, - 102045, - 102046, - 102047, - 102048, - 102049, - 102050, - 102051, - 102052, - 102053, - 102054, - 102055, - 102056, - 102057, - 102058, - 102059, - 102060, - 102061, - 102062, - 102063, - 102064, - 102065, - 102066, - 102067, - 102068, - 102069, - 102070, - 102071, - 102072, - 103001, - 103002, - 103003, - 103004, - 103005, - 103006, - 103007, - 103008, - ] - - message: str - - documentation_url: Optional[str] = None - - meta: Optional[MessageMeta] = None - - source: Optional[MessageSource] = None - - -class OnRampApplyResponse(BaseModel): - errors: List[Error] - - messages: List[Message] - - success: bool diff --git a/src/cloudflare/types/magic_cloud_networking/on_ramp_create_params.py b/src/cloudflare/types/magic_cloud_networking/on_ramp_create_params.py deleted file mode 100644 index 2893b07cfec..00000000000 --- a/src/cloudflare/types/magic_cloud_networking/on_ramp_create_params.py +++ /dev/null @@ -1,56 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing_extensions import Literal, Required, TypedDict - -from ..._types import SequenceNotStr - -__all__ = ["OnRampCreateParams"] - - -class OnRampCreateParams(TypedDict, total=False): - account_id: Required[str] - - cloud_type: Required[Literal["AWS", "AZURE", "GOOGLE"]] - - dynamic_routing: Required[bool] - """Enables BGP routing. - - When enabling this feature, set both install_routes_in_cloud and - install_routes_in_magic_wan to false. - """ - - install_routes_in_cloud: Required[bool] - - install_routes_in_magic_wan: Required[bool] - - name: Required[str] - - type: Required[Literal["OnrampTypeSingle", "OnrampTypeHub"]] - - adopted_hub_id: str - - attached_hubs: SequenceNotStr[str] - - attached_vpcs: SequenceNotStr[str] - - cloud_asn: int - """Sets the cloud-side ASN. - - If unset or zero, the cloud's default ASN takes effect. - """ - - description: str - - hub_provider_id: str - - manage_hub_to_hub_attachments: bool - - manage_vpc_to_hub_attachments: bool - - region: str - - vpc: str - - forwarded: str diff --git a/src/cloudflare/types/magic_cloud_networking/on_ramp_create_response.py b/src/cloudflare/types/magic_cloud_networking/on_ramp_create_response.py deleted file mode 100644 index c7c00da4cdd..00000000000 --- a/src/cloudflare/types/magic_cloud_networking/on_ramp_create_response.py +++ /dev/null @@ -1,1675 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from typing import Dict, List, Union, Optional -from typing_extensions import Literal, Annotated, TypeAlias - -from pydantic import Field as FieldInfo - -from ..._utils import PropertyInfo -from ..._models import BaseModel - -__all__ = [ - "OnRampCreateResponse", - "PlannedMonthlyCostEstimate", - "PlannedResource", - "PlannedResourceDiff", - "PlannedResourceMonthlyCostEstimateDiff", - "PlannedResourceResource", - "PostApplyMonthlyCostEstimate", - "PostApplyResources", - "PostApplyResourcesMonthlyCostEstimate", - "PostApplyResourcesObservations", - "PostApplyResourcesSection", - "PostApplyResourcesSectionHiddenItem", - "PostApplyResourcesSectionHiddenItemValue", - "PostApplyResourcesSectionHiddenItemValueMcnStringItem", - "PostApplyResourcesSectionHiddenItemValueMcnYamlItem", - "PostApplyResourcesSectionHiddenItemValueMcnYamlDiffItem", - "PostApplyResourcesSectionHiddenItemValueMcnYamlDiffItemYamlDiff", - "PostApplyResourcesSectionHiddenItemValueMcnResourcePreviewItem", - "PostApplyResourcesSectionHiddenItemValueMcnResourcePreviewItemResourcePreview", - "PostApplyResourcesSectionHiddenItemValueMcnListItem", - "PostApplyResourcesSectionHiddenItemValueMcnListItemList", - "PostApplyResourcesSectionHiddenItemValueMcnListItemListMcnStringItem", - "PostApplyResourcesSectionHiddenItemValueMcnListItemListMcnResourcePreviewItem", - "PostApplyResourcesSectionHiddenItemValueMcnListItemListMcnResourcePreviewItemResourcePreview", - "PostApplyResourcesSectionVisibleItem", - "PostApplyResourcesSectionVisibleItemValue", - "PostApplyResourcesSectionVisibleItemValueMcnStringItem", - "PostApplyResourcesSectionVisibleItemValueMcnYamlItem", - "PostApplyResourcesSectionVisibleItemValueMcnYamlDiffItem", - "PostApplyResourcesSectionVisibleItemValueMcnYamlDiffItemYamlDiff", - "PostApplyResourcesSectionVisibleItemValueMcnResourcePreviewItem", - "PostApplyResourcesSectionVisibleItemValueMcnResourcePreviewItemResourcePreview", - "PostApplyResourcesSectionVisibleItemValueMcnListItem", - "PostApplyResourcesSectionVisibleItemValueMcnListItemList", - "PostApplyResourcesSectionVisibleItemValueMcnListItemListMcnStringItem", - "PostApplyResourcesSectionVisibleItemValueMcnListItemListMcnResourcePreviewItem", - "PostApplyResourcesSectionVisibleItemValueMcnListItemListMcnResourcePreviewItemResourcePreview", - "PostApplyResourcesManagedBy", - "Status", - "StatusApplyProgress", - "StatusPlanProgress", - "StatusLifecycleErrors", - "StatusLifecycleErrorsMeta", - "StatusLifecycleErrorsSource", - "VPCsByID", - "VPCsByIDMonthlyCostEstimate", - "VPCsByIDObservations", - "VPCsByIDSection", - "VPCsByIDSectionHiddenItem", - "VPCsByIDSectionHiddenItemValue", - "VPCsByIDSectionHiddenItemValueMcnStringItem", - "VPCsByIDSectionHiddenItemValueMcnYamlItem", - "VPCsByIDSectionHiddenItemValueMcnYamlDiffItem", - "VPCsByIDSectionHiddenItemValueMcnYamlDiffItemYamlDiff", - "VPCsByIDSectionHiddenItemValueMcnResourcePreviewItem", - "VPCsByIDSectionHiddenItemValueMcnResourcePreviewItemResourcePreview", - "VPCsByIDSectionHiddenItemValueMcnListItem", - "VPCsByIDSectionHiddenItemValueMcnListItemList", - "VPCsByIDSectionHiddenItemValueMcnListItemListMcnStringItem", - "VPCsByIDSectionHiddenItemValueMcnListItemListMcnResourcePreviewItem", - "VPCsByIDSectionHiddenItemValueMcnListItemListMcnResourcePreviewItemResourcePreview", - "VPCsByIDSectionVisibleItem", - "VPCsByIDSectionVisibleItemValue", - "VPCsByIDSectionVisibleItemValueMcnStringItem", - "VPCsByIDSectionVisibleItemValueMcnYamlItem", - "VPCsByIDSectionVisibleItemValueMcnYamlDiffItem", - "VPCsByIDSectionVisibleItemValueMcnYamlDiffItemYamlDiff", - "VPCsByIDSectionVisibleItemValueMcnResourcePreviewItem", - "VPCsByIDSectionVisibleItemValueMcnResourcePreviewItemResourcePreview", - "VPCsByIDSectionVisibleItemValueMcnListItem", - "VPCsByIDSectionVisibleItemValueMcnListItemList", - "VPCsByIDSectionVisibleItemValueMcnListItemListMcnStringItem", - "VPCsByIDSectionVisibleItemValueMcnListItemListMcnResourcePreviewItem", - "VPCsByIDSectionVisibleItemValueMcnListItemListMcnResourcePreviewItemResourcePreview", - "VPCsByIDManagedBy", -] - - -class PlannedMonthlyCostEstimate(BaseModel): - currency: str - - current_monthly_cost: float - - diff: float - - proposed_monthly_cost: float - - -class PlannedResourceDiff(BaseModel): - diff: str - - left_description: str - - left_yaml: str - - right_description: str - - right_yaml: str - - -class PlannedResourceMonthlyCostEstimateDiff(BaseModel): - currency: str - - current_monthly_cost: float - - diff: float - - proposed_monthly_cost: float - - -class PlannedResourceResource(BaseModel): - id: str - - cloud_type: Literal["AWS", "AZURE", "GOOGLE", "CLOUDFLARE"] - - detail: str - - name: str - - resource_type: Literal[ - "aws_customer_gateway", - "aws_egress_only_internet_gateway", - "aws_internet_gateway", - "aws_instance", - "aws_network_interface", - "aws_route", - "aws_route_table", - "aws_route_table_association", - "aws_subnet", - "aws_vpc", - "aws_vpc_ipv4_cidr_block_association", - "aws_vpn_connection", - "aws_vpn_connection_route", - "aws_vpn_gateway", - "aws_security_group", - "aws_vpc_security_group_ingress_rule", - "aws_vpc_security_group_egress_rule", - "aws_ec2_managed_prefix_list", - "aws_ec2_transit_gateway", - "aws_ec2_transit_gateway_prefix_list_reference", - "aws_ec2_transit_gateway_vpc_attachment", - "azurerm_application_security_group", - "azurerm_lb", - "azurerm_lb_backend_address_pool", - "azurerm_lb_nat_pool", - "azurerm_lb_nat_rule", - "azurerm_lb_rule", - "azurerm_local_network_gateway", - "azurerm_network_interface", - "azurerm_network_interface_application_security_group_association", - "azurerm_network_interface_backend_address_pool_association", - "azurerm_network_interface_security_group_association", - "azurerm_network_security_group", - "azurerm_public_ip", - "azurerm_route", - "azurerm_route_table", - "azurerm_subnet", - "azurerm_subnet_route_table_association", - "azurerm_virtual_machine", - "azurerm_virtual_network_gateway_connection", - "azurerm_virtual_network", - "azurerm_virtual_network_gateway", - "google_compute_network", - "google_compute_subnetwork", - "google_compute_vpn_gateway", - "google_compute_vpn_tunnel", - "google_compute_route", - "google_compute_address", - "google_compute_global_address", - "google_compute_router", - "google_compute_interconnect_attachment", - "google_compute_ha_vpn_gateway", - "google_compute_forwarding_rule", - "google_compute_network_firewall_policy", - "google_compute_network_firewall_policy_rule", - "cloudflare_static_route", - "cloudflare_ipsec_tunnel", - ] - - title: str - - -class PlannedResource(BaseModel): - diff: PlannedResourceDiff - - keys_require_replace: List[str] - - monthly_cost_estimate_diff: PlannedResourceMonthlyCostEstimateDiff - - planned_action: Literal["no_op", "create", "update", "replace", "destroy"] - - resource: PlannedResourceResource - - -class PostApplyMonthlyCostEstimate(BaseModel): - currency: str - - monthly_cost: float - - -class PostApplyResourcesMonthlyCostEstimate(BaseModel): - currency: str - - monthly_cost: float - - -class PostApplyResourcesObservations(BaseModel): - first_observed_at: str - - last_observed_at: str - - provider_id: str - - resource_id: str - - -class PostApplyResourcesSectionHiddenItemValueMcnStringItem(BaseModel): - item_type: str - - string: str - - -class PostApplyResourcesSectionHiddenItemValueMcnYamlItem(BaseModel): - item_type: str - - yaml: str - - -class PostApplyResourcesSectionHiddenItemValueMcnYamlDiffItemYamlDiff(BaseModel): - diff: str - - left_description: str - - left_yaml: str - - right_description: str - - right_yaml: str - - -class PostApplyResourcesSectionHiddenItemValueMcnYamlDiffItem(BaseModel): - item_type: str - - yaml_diff: PostApplyResourcesSectionHiddenItemValueMcnYamlDiffItemYamlDiff - - -class PostApplyResourcesSectionHiddenItemValueMcnResourcePreviewItemResourcePreview(BaseModel): - id: str - - cloud_type: Literal["AWS", "AZURE", "GOOGLE", "CLOUDFLARE"] - - detail: str - - name: str - - resource_type: Literal[ - "aws_customer_gateway", - "aws_egress_only_internet_gateway", - "aws_internet_gateway", - "aws_instance", - "aws_network_interface", - "aws_route", - "aws_route_table", - "aws_route_table_association", - "aws_subnet", - "aws_vpc", - "aws_vpc_ipv4_cidr_block_association", - "aws_vpn_connection", - "aws_vpn_connection_route", - "aws_vpn_gateway", - "aws_security_group", - "aws_vpc_security_group_ingress_rule", - "aws_vpc_security_group_egress_rule", - "aws_ec2_managed_prefix_list", - "aws_ec2_transit_gateway", - "aws_ec2_transit_gateway_prefix_list_reference", - "aws_ec2_transit_gateway_vpc_attachment", - "azurerm_application_security_group", - "azurerm_lb", - "azurerm_lb_backend_address_pool", - "azurerm_lb_nat_pool", - "azurerm_lb_nat_rule", - "azurerm_lb_rule", - "azurerm_local_network_gateway", - "azurerm_network_interface", - "azurerm_network_interface_application_security_group_association", - "azurerm_network_interface_backend_address_pool_association", - "azurerm_network_interface_security_group_association", - "azurerm_network_security_group", - "azurerm_public_ip", - "azurerm_route", - "azurerm_route_table", - "azurerm_subnet", - "azurerm_subnet_route_table_association", - "azurerm_virtual_machine", - "azurerm_virtual_network_gateway_connection", - "azurerm_virtual_network", - "azurerm_virtual_network_gateway", - "google_compute_network", - "google_compute_subnetwork", - "google_compute_vpn_gateway", - "google_compute_vpn_tunnel", - "google_compute_route", - "google_compute_address", - "google_compute_global_address", - "google_compute_router", - "google_compute_interconnect_attachment", - "google_compute_ha_vpn_gateway", - "google_compute_forwarding_rule", - "google_compute_network_firewall_policy", - "google_compute_network_firewall_policy_rule", - "cloudflare_static_route", - "cloudflare_ipsec_tunnel", - ] - - title: str - - -class PostApplyResourcesSectionHiddenItemValueMcnResourcePreviewItem(BaseModel): - item_type: str - - resource_preview: PostApplyResourcesSectionHiddenItemValueMcnResourcePreviewItemResourcePreview - - -class PostApplyResourcesSectionHiddenItemValueMcnListItemListMcnStringItem(BaseModel): - item_type: str - - string: str - - -class PostApplyResourcesSectionHiddenItemValueMcnListItemListMcnResourcePreviewItemResourcePreview(BaseModel): - id: str - - cloud_type: Literal["AWS", "AZURE", "GOOGLE", "CLOUDFLARE"] - - detail: str - - name: str - - resource_type: Literal[ - "aws_customer_gateway", - "aws_egress_only_internet_gateway", - "aws_internet_gateway", - "aws_instance", - "aws_network_interface", - "aws_route", - "aws_route_table", - "aws_route_table_association", - "aws_subnet", - "aws_vpc", - "aws_vpc_ipv4_cidr_block_association", - "aws_vpn_connection", - "aws_vpn_connection_route", - "aws_vpn_gateway", - "aws_security_group", - "aws_vpc_security_group_ingress_rule", - "aws_vpc_security_group_egress_rule", - "aws_ec2_managed_prefix_list", - "aws_ec2_transit_gateway", - "aws_ec2_transit_gateway_prefix_list_reference", - "aws_ec2_transit_gateway_vpc_attachment", - "azurerm_application_security_group", - "azurerm_lb", - "azurerm_lb_backend_address_pool", - "azurerm_lb_nat_pool", - "azurerm_lb_nat_rule", - "azurerm_lb_rule", - "azurerm_local_network_gateway", - "azurerm_network_interface", - "azurerm_network_interface_application_security_group_association", - "azurerm_network_interface_backend_address_pool_association", - "azurerm_network_interface_security_group_association", - "azurerm_network_security_group", - "azurerm_public_ip", - "azurerm_route", - "azurerm_route_table", - "azurerm_subnet", - "azurerm_subnet_route_table_association", - "azurerm_virtual_machine", - "azurerm_virtual_network_gateway_connection", - "azurerm_virtual_network", - "azurerm_virtual_network_gateway", - "google_compute_network", - "google_compute_subnetwork", - "google_compute_vpn_gateway", - "google_compute_vpn_tunnel", - "google_compute_route", - "google_compute_address", - "google_compute_global_address", - "google_compute_router", - "google_compute_interconnect_attachment", - "google_compute_ha_vpn_gateway", - "google_compute_forwarding_rule", - "google_compute_network_firewall_policy", - "google_compute_network_firewall_policy_rule", - "cloudflare_static_route", - "cloudflare_ipsec_tunnel", - ] - - title: str - - -class PostApplyResourcesSectionHiddenItemValueMcnListItemListMcnResourcePreviewItem(BaseModel): - item_type: str - - resource_preview: PostApplyResourcesSectionHiddenItemValueMcnListItemListMcnResourcePreviewItemResourcePreview - - -PostApplyResourcesSectionHiddenItemValueMcnListItemList: TypeAlias = Annotated[ - Union[ - PostApplyResourcesSectionHiddenItemValueMcnListItemListMcnStringItem, - PostApplyResourcesSectionHiddenItemValueMcnListItemListMcnResourcePreviewItem, - ], - PropertyInfo(discriminator="item_type"), -] - - -class PostApplyResourcesSectionHiddenItemValueMcnListItem(BaseModel): - item_type: str - - rule_list: List[PostApplyResourcesSectionHiddenItemValueMcnListItemList] = FieldInfo(alias="list") - - -PostApplyResourcesSectionHiddenItemValue: TypeAlias = Annotated[ - Union[ - PostApplyResourcesSectionHiddenItemValueMcnStringItem, - PostApplyResourcesSectionHiddenItemValueMcnYamlItem, - PostApplyResourcesSectionHiddenItemValueMcnYamlDiffItem, - PostApplyResourcesSectionHiddenItemValueMcnResourcePreviewItem, - PostApplyResourcesSectionHiddenItemValueMcnListItem, - ], - PropertyInfo(discriminator="item_type"), -] - - -class PostApplyResourcesSectionHiddenItem(BaseModel): - help_text: Optional[str] = FieldInfo(alias="helpText", default=None) - - name: Optional[str] = None - - value: Optional[PostApplyResourcesSectionHiddenItemValue] = None - - -class PostApplyResourcesSectionVisibleItemValueMcnStringItem(BaseModel): - item_type: str - - string: str - - -class PostApplyResourcesSectionVisibleItemValueMcnYamlItem(BaseModel): - item_type: str - - yaml: str - - -class PostApplyResourcesSectionVisibleItemValueMcnYamlDiffItemYamlDiff(BaseModel): - diff: str - - left_description: str - - left_yaml: str - - right_description: str - - right_yaml: str - - -class PostApplyResourcesSectionVisibleItemValueMcnYamlDiffItem(BaseModel): - item_type: str - - yaml_diff: PostApplyResourcesSectionVisibleItemValueMcnYamlDiffItemYamlDiff - - -class PostApplyResourcesSectionVisibleItemValueMcnResourcePreviewItemResourcePreview(BaseModel): - id: str - - cloud_type: Literal["AWS", "AZURE", "GOOGLE", "CLOUDFLARE"] - - detail: str - - name: str - - resource_type: Literal[ - "aws_customer_gateway", - "aws_egress_only_internet_gateway", - "aws_internet_gateway", - "aws_instance", - "aws_network_interface", - "aws_route", - "aws_route_table", - "aws_route_table_association", - "aws_subnet", - "aws_vpc", - "aws_vpc_ipv4_cidr_block_association", - "aws_vpn_connection", - "aws_vpn_connection_route", - "aws_vpn_gateway", - "aws_security_group", - "aws_vpc_security_group_ingress_rule", - "aws_vpc_security_group_egress_rule", - "aws_ec2_managed_prefix_list", - "aws_ec2_transit_gateway", - "aws_ec2_transit_gateway_prefix_list_reference", - "aws_ec2_transit_gateway_vpc_attachment", - "azurerm_application_security_group", - "azurerm_lb", - "azurerm_lb_backend_address_pool", - "azurerm_lb_nat_pool", - "azurerm_lb_nat_rule", - "azurerm_lb_rule", - "azurerm_local_network_gateway", - "azurerm_network_interface", - "azurerm_network_interface_application_security_group_association", - "azurerm_network_interface_backend_address_pool_association", - "azurerm_network_interface_security_group_association", - "azurerm_network_security_group", - "azurerm_public_ip", - "azurerm_route", - "azurerm_route_table", - "azurerm_subnet", - "azurerm_subnet_route_table_association", - "azurerm_virtual_machine", - "azurerm_virtual_network_gateway_connection", - "azurerm_virtual_network", - "azurerm_virtual_network_gateway", - "google_compute_network", - "google_compute_subnetwork", - "google_compute_vpn_gateway", - "google_compute_vpn_tunnel", - "google_compute_route", - "google_compute_address", - "google_compute_global_address", - "google_compute_router", - "google_compute_interconnect_attachment", - "google_compute_ha_vpn_gateway", - "google_compute_forwarding_rule", - "google_compute_network_firewall_policy", - "google_compute_network_firewall_policy_rule", - "cloudflare_static_route", - "cloudflare_ipsec_tunnel", - ] - - title: str - - -class PostApplyResourcesSectionVisibleItemValueMcnResourcePreviewItem(BaseModel): - item_type: str - - resource_preview: PostApplyResourcesSectionVisibleItemValueMcnResourcePreviewItemResourcePreview - - -class PostApplyResourcesSectionVisibleItemValueMcnListItemListMcnStringItem(BaseModel): - item_type: str - - string: str - - -class PostApplyResourcesSectionVisibleItemValueMcnListItemListMcnResourcePreviewItemResourcePreview(BaseModel): - id: str - - cloud_type: Literal["AWS", "AZURE", "GOOGLE", "CLOUDFLARE"] - - detail: str - - name: str - - resource_type: Literal[ - "aws_customer_gateway", - "aws_egress_only_internet_gateway", - "aws_internet_gateway", - "aws_instance", - "aws_network_interface", - "aws_route", - "aws_route_table", - "aws_route_table_association", - "aws_subnet", - "aws_vpc", - "aws_vpc_ipv4_cidr_block_association", - "aws_vpn_connection", - "aws_vpn_connection_route", - "aws_vpn_gateway", - "aws_security_group", - "aws_vpc_security_group_ingress_rule", - "aws_vpc_security_group_egress_rule", - "aws_ec2_managed_prefix_list", - "aws_ec2_transit_gateway", - "aws_ec2_transit_gateway_prefix_list_reference", - "aws_ec2_transit_gateway_vpc_attachment", - "azurerm_application_security_group", - "azurerm_lb", - "azurerm_lb_backend_address_pool", - "azurerm_lb_nat_pool", - "azurerm_lb_nat_rule", - "azurerm_lb_rule", - "azurerm_local_network_gateway", - "azurerm_network_interface", - "azurerm_network_interface_application_security_group_association", - "azurerm_network_interface_backend_address_pool_association", - "azurerm_network_interface_security_group_association", - "azurerm_network_security_group", - "azurerm_public_ip", - "azurerm_route", - "azurerm_route_table", - "azurerm_subnet", - "azurerm_subnet_route_table_association", - "azurerm_virtual_machine", - "azurerm_virtual_network_gateway_connection", - "azurerm_virtual_network", - "azurerm_virtual_network_gateway", - "google_compute_network", - "google_compute_subnetwork", - "google_compute_vpn_gateway", - "google_compute_vpn_tunnel", - "google_compute_route", - "google_compute_address", - "google_compute_global_address", - "google_compute_router", - "google_compute_interconnect_attachment", - "google_compute_ha_vpn_gateway", - "google_compute_forwarding_rule", - "google_compute_network_firewall_policy", - "google_compute_network_firewall_policy_rule", - "cloudflare_static_route", - "cloudflare_ipsec_tunnel", - ] - - title: str - - -class PostApplyResourcesSectionVisibleItemValueMcnListItemListMcnResourcePreviewItem(BaseModel): - item_type: str - - resource_preview: PostApplyResourcesSectionVisibleItemValueMcnListItemListMcnResourcePreviewItemResourcePreview - - -PostApplyResourcesSectionVisibleItemValueMcnListItemList: TypeAlias = Annotated[ - Union[ - PostApplyResourcesSectionVisibleItemValueMcnListItemListMcnStringItem, - PostApplyResourcesSectionVisibleItemValueMcnListItemListMcnResourcePreviewItem, - ], - PropertyInfo(discriminator="item_type"), -] - - -class PostApplyResourcesSectionVisibleItemValueMcnListItem(BaseModel): - item_type: str - - rule_list: List[PostApplyResourcesSectionVisibleItemValueMcnListItemList] = FieldInfo(alias="list") - - -PostApplyResourcesSectionVisibleItemValue: TypeAlias = Annotated[ - Union[ - PostApplyResourcesSectionVisibleItemValueMcnStringItem, - PostApplyResourcesSectionVisibleItemValueMcnYamlItem, - PostApplyResourcesSectionVisibleItemValueMcnYamlDiffItem, - PostApplyResourcesSectionVisibleItemValueMcnResourcePreviewItem, - PostApplyResourcesSectionVisibleItemValueMcnListItem, - ], - PropertyInfo(discriminator="item_type"), -] - - -class PostApplyResourcesSectionVisibleItem(BaseModel): - help_text: Optional[str] = FieldInfo(alias="helpText", default=None) - - name: Optional[str] = None - - value: Optional[PostApplyResourcesSectionVisibleItemValue] = None - - -class PostApplyResourcesSection(BaseModel): - hidden_items: List[PostApplyResourcesSectionHiddenItem] - - name: str - - visible_items: List[PostApplyResourcesSectionVisibleItem] - - help_text: Optional[str] = None - - -class PostApplyResourcesManagedBy(BaseModel): - id: str - - client_type: Literal["MAGIC_WAN_CLOUD_ONRAMP"] - - name: str - - -class PostApplyResources(BaseModel): - id: str - - account_id: str - - cloud_type: Literal["AWS", "AZURE", "GOOGLE", "CLOUDFLARE"] - - config: Dict[str, object] - - deployment_provider: str - - managed: bool - - monthly_cost_estimate: PostApplyResourcesMonthlyCostEstimate - - name: str - - native_id: str - - observations: Dict[str, PostApplyResourcesObservations] - - provider_ids: List[str] - - provider_names_by_id: Dict[str, str] - - region: str - - resource_group: str - - resource_type: Literal[ - "aws_customer_gateway", - "aws_egress_only_internet_gateway", - "aws_internet_gateway", - "aws_instance", - "aws_network_interface", - "aws_route", - "aws_route_table", - "aws_route_table_association", - "aws_subnet", - "aws_vpc", - "aws_vpc_ipv4_cidr_block_association", - "aws_vpn_connection", - "aws_vpn_connection_route", - "aws_vpn_gateway", - "aws_security_group", - "aws_vpc_security_group_ingress_rule", - "aws_vpc_security_group_egress_rule", - "aws_ec2_managed_prefix_list", - "aws_ec2_transit_gateway", - "aws_ec2_transit_gateway_prefix_list_reference", - "aws_ec2_transit_gateway_vpc_attachment", - "azurerm_application_security_group", - "azurerm_lb", - "azurerm_lb_backend_address_pool", - "azurerm_lb_nat_pool", - "azurerm_lb_nat_rule", - "azurerm_lb_rule", - "azurerm_local_network_gateway", - "azurerm_network_interface", - "azurerm_network_interface_application_security_group_association", - "azurerm_network_interface_backend_address_pool_association", - "azurerm_network_interface_security_group_association", - "azurerm_network_security_group", - "azurerm_public_ip", - "azurerm_route", - "azurerm_route_table", - "azurerm_subnet", - "azurerm_subnet_route_table_association", - "azurerm_virtual_machine", - "azurerm_virtual_network_gateway_connection", - "azurerm_virtual_network", - "azurerm_virtual_network_gateway", - "google_compute_network", - "google_compute_subnetwork", - "google_compute_vpn_gateway", - "google_compute_vpn_tunnel", - "google_compute_route", - "google_compute_address", - "google_compute_global_address", - "google_compute_router", - "google_compute_interconnect_attachment", - "google_compute_ha_vpn_gateway", - "google_compute_forwarding_rule", - "google_compute_network_firewall_policy", - "google_compute_network_firewall_policy_rule", - "cloudflare_static_route", - "cloudflare_ipsec_tunnel", - ] - - sections: List[PostApplyResourcesSection] - - state: Dict[str, object] - - tags: Dict[str, str] - - updated_at: str - - url: str - - managed_by: Optional[List[PostApplyResourcesManagedBy]] = None - - -class StatusApplyProgress(BaseModel): - done: int - - total: int - - -class StatusPlanProgress(BaseModel): - done: int - - total: int - - -class StatusLifecycleErrorsMeta(BaseModel): - l10n_key: Optional[str] = None - - loggable_error: Optional[str] = None - - template_data: Optional[object] = None - - trace_id: Optional[str] = None - - -class StatusLifecycleErrorsSource(BaseModel): - parameter: Optional[str] = None - - parameter_value_index: Optional[int] = None - - pointer: Optional[str] = None - - -class StatusLifecycleErrors(BaseModel): - code: Literal[ - 1001, - 1002, - 1003, - 1004, - 1005, - 1006, - 1007, - 1008, - 1009, - 1010, - 1011, - 1012, - 1013, - 1014, - 1015, - 1016, - 1017, - 1018, - 2001, - 2002, - 2003, - 2004, - 2005, - 2006, - 2007, - 2008, - 2009, - 2010, - 2011, - 2012, - 2013, - 2014, - 2015, - 2016, - 2017, - 2018, - 2019, - 2020, - 2021, - 2022, - 3001, - 3002, - 3003, - 3004, - 3005, - 3006, - 3007, - 4001, - 4002, - 4003, - 4004, - 4005, - 4006, - 4007, - 4008, - 4009, - 4010, - 4011, - 4012, - 4013, - 4014, - 4015, - 4016, - 4017, - 4018, - 4019, - 4020, - 4021, - 4022, - 4023, - 5001, - 5002, - 5003, - 5004, - 102000, - 102001, - 102002, - 102003, - 102004, - 102005, - 102006, - 102007, - 102008, - 102009, - 102010, - 102011, - 102012, - 102013, - 102014, - 102015, - 102016, - 102017, - 102018, - 102019, - 102020, - 102021, - 102022, - 102023, - 102024, - 102025, - 102026, - 102027, - 102028, - 102029, - 102030, - 102031, - 102032, - 102033, - 102034, - 102035, - 102036, - 102037, - 102038, - 102039, - 102040, - 102041, - 102042, - 102043, - 102044, - 102045, - 102046, - 102047, - 102048, - 102049, - 102050, - 102051, - 102052, - 102053, - 102054, - 102055, - 102056, - 102057, - 102058, - 102059, - 102060, - 102061, - 102062, - 102063, - 102064, - 102065, - 102066, - 102067, - 102068, - 102069, - 102070, - 102071, - 102072, - 103001, - 103002, - 103003, - 103004, - 103005, - 103006, - 103007, - 103008, - ] - - message: str - - documentation_url: Optional[str] = None - - meta: Optional[StatusLifecycleErrorsMeta] = None - - source: Optional[StatusLifecycleErrorsSource] = None - - -class Status(BaseModel): - apply_progress: StatusApplyProgress - - lifecycle_state: Literal[ - "OnrampNeedsApply", - "OnrampPendingPlan", - "OnrampPlanning", - "OnrampPlanFailed", - "OnrampPendingApproval", - "OnrampPendingApply", - "OnrampApplying", - "OnrampApplyFailed", - "OnrampActive", - "OnrampPendingDestroy", - "OnrampDestroying", - "OnrampDestroyFailed", - ] - - plan_progress: StatusPlanProgress - - routes: List[str] - - tunnels: List[str] - - lifecycle_errors: Optional[Dict[str, StatusLifecycleErrors]] = None - - -class VPCsByIDMonthlyCostEstimate(BaseModel): - currency: str - - monthly_cost: float - - -class VPCsByIDObservations(BaseModel): - first_observed_at: str - - last_observed_at: str - - provider_id: str - - resource_id: str - - -class VPCsByIDSectionHiddenItemValueMcnStringItem(BaseModel): - item_type: str - - string: str - - -class VPCsByIDSectionHiddenItemValueMcnYamlItem(BaseModel): - item_type: str - - yaml: str - - -class VPCsByIDSectionHiddenItemValueMcnYamlDiffItemYamlDiff(BaseModel): - diff: str - - left_description: str - - left_yaml: str - - right_description: str - - right_yaml: str - - -class VPCsByIDSectionHiddenItemValueMcnYamlDiffItem(BaseModel): - item_type: str - - yaml_diff: VPCsByIDSectionHiddenItemValueMcnYamlDiffItemYamlDiff - - -class VPCsByIDSectionHiddenItemValueMcnResourcePreviewItemResourcePreview(BaseModel): - id: str - - cloud_type: Literal["AWS", "AZURE", "GOOGLE", "CLOUDFLARE"] - - detail: str - - name: str - - resource_type: Literal[ - "aws_customer_gateway", - "aws_egress_only_internet_gateway", - "aws_internet_gateway", - "aws_instance", - "aws_network_interface", - "aws_route", - "aws_route_table", - "aws_route_table_association", - "aws_subnet", - "aws_vpc", - "aws_vpc_ipv4_cidr_block_association", - "aws_vpn_connection", - "aws_vpn_connection_route", - "aws_vpn_gateway", - "aws_security_group", - "aws_vpc_security_group_ingress_rule", - "aws_vpc_security_group_egress_rule", - "aws_ec2_managed_prefix_list", - "aws_ec2_transit_gateway", - "aws_ec2_transit_gateway_prefix_list_reference", - "aws_ec2_transit_gateway_vpc_attachment", - "azurerm_application_security_group", - "azurerm_lb", - "azurerm_lb_backend_address_pool", - "azurerm_lb_nat_pool", - "azurerm_lb_nat_rule", - "azurerm_lb_rule", - "azurerm_local_network_gateway", - "azurerm_network_interface", - "azurerm_network_interface_application_security_group_association", - "azurerm_network_interface_backend_address_pool_association", - "azurerm_network_interface_security_group_association", - "azurerm_network_security_group", - "azurerm_public_ip", - "azurerm_route", - "azurerm_route_table", - "azurerm_subnet", - "azurerm_subnet_route_table_association", - "azurerm_virtual_machine", - "azurerm_virtual_network_gateway_connection", - "azurerm_virtual_network", - "azurerm_virtual_network_gateway", - "google_compute_network", - "google_compute_subnetwork", - "google_compute_vpn_gateway", - "google_compute_vpn_tunnel", - "google_compute_route", - "google_compute_address", - "google_compute_global_address", - "google_compute_router", - "google_compute_interconnect_attachment", - "google_compute_ha_vpn_gateway", - "google_compute_forwarding_rule", - "google_compute_network_firewall_policy", - "google_compute_network_firewall_policy_rule", - "cloudflare_static_route", - "cloudflare_ipsec_tunnel", - ] - - title: str - - -class VPCsByIDSectionHiddenItemValueMcnResourcePreviewItem(BaseModel): - item_type: str - - resource_preview: VPCsByIDSectionHiddenItemValueMcnResourcePreviewItemResourcePreview - - -class VPCsByIDSectionHiddenItemValueMcnListItemListMcnStringItem(BaseModel): - item_type: str - - string: str - - -class VPCsByIDSectionHiddenItemValueMcnListItemListMcnResourcePreviewItemResourcePreview(BaseModel): - id: str - - cloud_type: Literal["AWS", "AZURE", "GOOGLE", "CLOUDFLARE"] - - detail: str - - name: str - - resource_type: Literal[ - "aws_customer_gateway", - "aws_egress_only_internet_gateway", - "aws_internet_gateway", - "aws_instance", - "aws_network_interface", - "aws_route", - "aws_route_table", - "aws_route_table_association", - "aws_subnet", - "aws_vpc", - "aws_vpc_ipv4_cidr_block_association", - "aws_vpn_connection", - "aws_vpn_connection_route", - "aws_vpn_gateway", - "aws_security_group", - "aws_vpc_security_group_ingress_rule", - "aws_vpc_security_group_egress_rule", - "aws_ec2_managed_prefix_list", - "aws_ec2_transit_gateway", - "aws_ec2_transit_gateway_prefix_list_reference", - "aws_ec2_transit_gateway_vpc_attachment", - "azurerm_application_security_group", - "azurerm_lb", - "azurerm_lb_backend_address_pool", - "azurerm_lb_nat_pool", - "azurerm_lb_nat_rule", - "azurerm_lb_rule", - "azurerm_local_network_gateway", - "azurerm_network_interface", - "azurerm_network_interface_application_security_group_association", - "azurerm_network_interface_backend_address_pool_association", - "azurerm_network_interface_security_group_association", - "azurerm_network_security_group", - "azurerm_public_ip", - "azurerm_route", - "azurerm_route_table", - "azurerm_subnet", - "azurerm_subnet_route_table_association", - "azurerm_virtual_machine", - "azurerm_virtual_network_gateway_connection", - "azurerm_virtual_network", - "azurerm_virtual_network_gateway", - "google_compute_network", - "google_compute_subnetwork", - "google_compute_vpn_gateway", - "google_compute_vpn_tunnel", - "google_compute_route", - "google_compute_address", - "google_compute_global_address", - "google_compute_router", - "google_compute_interconnect_attachment", - "google_compute_ha_vpn_gateway", - "google_compute_forwarding_rule", - "google_compute_network_firewall_policy", - "google_compute_network_firewall_policy_rule", - "cloudflare_static_route", - "cloudflare_ipsec_tunnel", - ] - - title: str - - -class VPCsByIDSectionHiddenItemValueMcnListItemListMcnResourcePreviewItem(BaseModel): - item_type: str - - resource_preview: VPCsByIDSectionHiddenItemValueMcnListItemListMcnResourcePreviewItemResourcePreview - - -VPCsByIDSectionHiddenItemValueMcnListItemList: TypeAlias = Annotated[ - Union[ - VPCsByIDSectionHiddenItemValueMcnListItemListMcnStringItem, - VPCsByIDSectionHiddenItemValueMcnListItemListMcnResourcePreviewItem, - ], - PropertyInfo(discriminator="item_type"), -] - - -class VPCsByIDSectionHiddenItemValueMcnListItem(BaseModel): - item_type: str - - rule_list: List[VPCsByIDSectionHiddenItemValueMcnListItemList] = FieldInfo(alias="list") - - -VPCsByIDSectionHiddenItemValue: TypeAlias = Annotated[ - Union[ - VPCsByIDSectionHiddenItemValueMcnStringItem, - VPCsByIDSectionHiddenItemValueMcnYamlItem, - VPCsByIDSectionHiddenItemValueMcnYamlDiffItem, - VPCsByIDSectionHiddenItemValueMcnResourcePreviewItem, - VPCsByIDSectionHiddenItemValueMcnListItem, - ], - PropertyInfo(discriminator="item_type"), -] - - -class VPCsByIDSectionHiddenItem(BaseModel): - help_text: Optional[str] = FieldInfo(alias="helpText", default=None) - - name: Optional[str] = None - - value: Optional[VPCsByIDSectionHiddenItemValue] = None - - -class VPCsByIDSectionVisibleItemValueMcnStringItem(BaseModel): - item_type: str - - string: str - - -class VPCsByIDSectionVisibleItemValueMcnYamlItem(BaseModel): - item_type: str - - yaml: str - - -class VPCsByIDSectionVisibleItemValueMcnYamlDiffItemYamlDiff(BaseModel): - diff: str - - left_description: str - - left_yaml: str - - right_description: str - - right_yaml: str - - -class VPCsByIDSectionVisibleItemValueMcnYamlDiffItem(BaseModel): - item_type: str - - yaml_diff: VPCsByIDSectionVisibleItemValueMcnYamlDiffItemYamlDiff - - -class VPCsByIDSectionVisibleItemValueMcnResourcePreviewItemResourcePreview(BaseModel): - id: str - - cloud_type: Literal["AWS", "AZURE", "GOOGLE", "CLOUDFLARE"] - - detail: str - - name: str - - resource_type: Literal[ - "aws_customer_gateway", - "aws_egress_only_internet_gateway", - "aws_internet_gateway", - "aws_instance", - "aws_network_interface", - "aws_route", - "aws_route_table", - "aws_route_table_association", - "aws_subnet", - "aws_vpc", - "aws_vpc_ipv4_cidr_block_association", - "aws_vpn_connection", - "aws_vpn_connection_route", - "aws_vpn_gateway", - "aws_security_group", - "aws_vpc_security_group_ingress_rule", - "aws_vpc_security_group_egress_rule", - "aws_ec2_managed_prefix_list", - "aws_ec2_transit_gateway", - "aws_ec2_transit_gateway_prefix_list_reference", - "aws_ec2_transit_gateway_vpc_attachment", - "azurerm_application_security_group", - "azurerm_lb", - "azurerm_lb_backend_address_pool", - "azurerm_lb_nat_pool", - "azurerm_lb_nat_rule", - "azurerm_lb_rule", - "azurerm_local_network_gateway", - "azurerm_network_interface", - "azurerm_network_interface_application_security_group_association", - "azurerm_network_interface_backend_address_pool_association", - "azurerm_network_interface_security_group_association", - "azurerm_network_security_group", - "azurerm_public_ip", - "azurerm_route", - "azurerm_route_table", - "azurerm_subnet", - "azurerm_subnet_route_table_association", - "azurerm_virtual_machine", - "azurerm_virtual_network_gateway_connection", - "azurerm_virtual_network", - "azurerm_virtual_network_gateway", - "google_compute_network", - "google_compute_subnetwork", - "google_compute_vpn_gateway", - "google_compute_vpn_tunnel", - "google_compute_route", - "google_compute_address", - "google_compute_global_address", - "google_compute_router", - "google_compute_interconnect_attachment", - "google_compute_ha_vpn_gateway", - "google_compute_forwarding_rule", - "google_compute_network_firewall_policy", - "google_compute_network_firewall_policy_rule", - "cloudflare_static_route", - "cloudflare_ipsec_tunnel", - ] - - title: str - - -class VPCsByIDSectionVisibleItemValueMcnResourcePreviewItem(BaseModel): - item_type: str - - resource_preview: VPCsByIDSectionVisibleItemValueMcnResourcePreviewItemResourcePreview - - -class VPCsByIDSectionVisibleItemValueMcnListItemListMcnStringItem(BaseModel): - item_type: str - - string: str - - -class VPCsByIDSectionVisibleItemValueMcnListItemListMcnResourcePreviewItemResourcePreview(BaseModel): - id: str - - cloud_type: Literal["AWS", "AZURE", "GOOGLE", "CLOUDFLARE"] - - detail: str - - name: str - - resource_type: Literal[ - "aws_customer_gateway", - "aws_egress_only_internet_gateway", - "aws_internet_gateway", - "aws_instance", - "aws_network_interface", - "aws_route", - "aws_route_table", - "aws_route_table_association", - "aws_subnet", - "aws_vpc", - "aws_vpc_ipv4_cidr_block_association", - "aws_vpn_connection", - "aws_vpn_connection_route", - "aws_vpn_gateway", - "aws_security_group", - "aws_vpc_security_group_ingress_rule", - "aws_vpc_security_group_egress_rule", - "aws_ec2_managed_prefix_list", - "aws_ec2_transit_gateway", - "aws_ec2_transit_gateway_prefix_list_reference", - "aws_ec2_transit_gateway_vpc_attachment", - "azurerm_application_security_group", - "azurerm_lb", - "azurerm_lb_backend_address_pool", - "azurerm_lb_nat_pool", - "azurerm_lb_nat_rule", - "azurerm_lb_rule", - "azurerm_local_network_gateway", - "azurerm_network_interface", - "azurerm_network_interface_application_security_group_association", - "azurerm_network_interface_backend_address_pool_association", - "azurerm_network_interface_security_group_association", - "azurerm_network_security_group", - "azurerm_public_ip", - "azurerm_route", - "azurerm_route_table", - "azurerm_subnet", - "azurerm_subnet_route_table_association", - "azurerm_virtual_machine", - "azurerm_virtual_network_gateway_connection", - "azurerm_virtual_network", - "azurerm_virtual_network_gateway", - "google_compute_network", - "google_compute_subnetwork", - "google_compute_vpn_gateway", - "google_compute_vpn_tunnel", - "google_compute_route", - "google_compute_address", - "google_compute_global_address", - "google_compute_router", - "google_compute_interconnect_attachment", - "google_compute_ha_vpn_gateway", - "google_compute_forwarding_rule", - "google_compute_network_firewall_policy", - "google_compute_network_firewall_policy_rule", - "cloudflare_static_route", - "cloudflare_ipsec_tunnel", - ] - - title: str - - -class VPCsByIDSectionVisibleItemValueMcnListItemListMcnResourcePreviewItem(BaseModel): - item_type: str - - resource_preview: VPCsByIDSectionVisibleItemValueMcnListItemListMcnResourcePreviewItemResourcePreview - - -VPCsByIDSectionVisibleItemValueMcnListItemList: TypeAlias = Annotated[ - Union[ - VPCsByIDSectionVisibleItemValueMcnListItemListMcnStringItem, - VPCsByIDSectionVisibleItemValueMcnListItemListMcnResourcePreviewItem, - ], - PropertyInfo(discriminator="item_type"), -] - - -class VPCsByIDSectionVisibleItemValueMcnListItem(BaseModel): - item_type: str - - rule_list: List[VPCsByIDSectionVisibleItemValueMcnListItemList] = FieldInfo(alias="list") - - -VPCsByIDSectionVisibleItemValue: TypeAlias = Annotated[ - Union[ - VPCsByIDSectionVisibleItemValueMcnStringItem, - VPCsByIDSectionVisibleItemValueMcnYamlItem, - VPCsByIDSectionVisibleItemValueMcnYamlDiffItem, - VPCsByIDSectionVisibleItemValueMcnResourcePreviewItem, - VPCsByIDSectionVisibleItemValueMcnListItem, - ], - PropertyInfo(discriminator="item_type"), -] - - -class VPCsByIDSectionVisibleItem(BaseModel): - help_text: Optional[str] = FieldInfo(alias="helpText", default=None) - - name: Optional[str] = None - - value: Optional[VPCsByIDSectionVisibleItemValue] = None - - -class VPCsByIDSection(BaseModel): - hidden_items: List[VPCsByIDSectionHiddenItem] - - name: str - - visible_items: List[VPCsByIDSectionVisibleItem] - - help_text: Optional[str] = None - - -class VPCsByIDManagedBy(BaseModel): - id: str - - client_type: Literal["MAGIC_WAN_CLOUD_ONRAMP"] - - name: str - - -class VPCsByID(BaseModel): - id: str - - account_id: str - - cloud_type: Literal["AWS", "AZURE", "GOOGLE", "CLOUDFLARE"] - - config: Dict[str, object] - - deployment_provider: str - - managed: bool - - monthly_cost_estimate: VPCsByIDMonthlyCostEstimate - - name: str - - native_id: str - - observations: Dict[str, VPCsByIDObservations] - - provider_ids: List[str] - - provider_names_by_id: Dict[str, str] - - region: str - - resource_group: str - - resource_type: Literal[ - "aws_customer_gateway", - "aws_egress_only_internet_gateway", - "aws_internet_gateway", - "aws_instance", - "aws_network_interface", - "aws_route", - "aws_route_table", - "aws_route_table_association", - "aws_subnet", - "aws_vpc", - "aws_vpc_ipv4_cidr_block_association", - "aws_vpn_connection", - "aws_vpn_connection_route", - "aws_vpn_gateway", - "aws_security_group", - "aws_vpc_security_group_ingress_rule", - "aws_vpc_security_group_egress_rule", - "aws_ec2_managed_prefix_list", - "aws_ec2_transit_gateway", - "aws_ec2_transit_gateway_prefix_list_reference", - "aws_ec2_transit_gateway_vpc_attachment", - "azurerm_application_security_group", - "azurerm_lb", - "azurerm_lb_backend_address_pool", - "azurerm_lb_nat_pool", - "azurerm_lb_nat_rule", - "azurerm_lb_rule", - "azurerm_local_network_gateway", - "azurerm_network_interface", - "azurerm_network_interface_application_security_group_association", - "azurerm_network_interface_backend_address_pool_association", - "azurerm_network_interface_security_group_association", - "azurerm_network_security_group", - "azurerm_public_ip", - "azurerm_route", - "azurerm_route_table", - "azurerm_subnet", - "azurerm_subnet_route_table_association", - "azurerm_virtual_machine", - "azurerm_virtual_network_gateway_connection", - "azurerm_virtual_network", - "azurerm_virtual_network_gateway", - "google_compute_network", - "google_compute_subnetwork", - "google_compute_vpn_gateway", - "google_compute_vpn_tunnel", - "google_compute_route", - "google_compute_address", - "google_compute_global_address", - "google_compute_router", - "google_compute_interconnect_attachment", - "google_compute_ha_vpn_gateway", - "google_compute_forwarding_rule", - "google_compute_network_firewall_policy", - "google_compute_network_firewall_policy_rule", - "cloudflare_static_route", - "cloudflare_ipsec_tunnel", - ] - - sections: List[VPCsByIDSection] - - state: Dict[str, object] - - tags: Dict[str, str] - - updated_at: str - - url: str - - managed_by: Optional[List[VPCsByIDManagedBy]] = None - - -class OnRampCreateResponse(BaseModel): - id: str - - cloud_type: Literal["AWS", "AZURE", "GOOGLE"] - - dynamic_routing: bool - - install_routes_in_cloud: bool - - install_routes_in_magic_wan: bool - - name: str - - type: Literal["OnrampTypeSingle", "OnrampTypeHub"] - - updated_at: str - - attached_hubs: Optional[List[str]] = None - - attached_vpcs: Optional[List[str]] = None - - cloud_asn: Optional[int] = None - - description: Optional[str] = None - - hub: Optional[str] = None - - last_applied_at: Optional[str] = None - - last_exported_at: Optional[str] = None - - last_planned_at: Optional[str] = None - - manage_hub_to_hub_attachments: Optional[bool] = None - - manage_vpc_to_hub_attachments: Optional[bool] = None - - planned_monthly_cost_estimate: Optional[PlannedMonthlyCostEstimate] = None - - planned_resources: Optional[List[PlannedResource]] = None - - planned_resources_unavailable: Optional[bool] = None - - post_apply_monthly_cost_estimate: Optional[PostApplyMonthlyCostEstimate] = None - - post_apply_resources: Optional[Dict[str, PostApplyResources]] = None - - post_apply_resources_unavailable: Optional[bool] = None - - region: Optional[str] = None - - status: Optional[Status] = None - - vpc: Optional[str] = None - - vpcs_by_id: Optional[Dict[str, VPCsByID]] = None - - vpcs_by_id_unavailable: Optional[List[str]] = None - """The list of vpc IDs for which resource details failed to generate.""" diff --git a/src/cloudflare/types/magic_cloud_networking/on_ramp_delete_params.py b/src/cloudflare/types/magic_cloud_networking/on_ramp_delete_params.py deleted file mode 100644 index 6ace6d226de..00000000000 --- a/src/cloudflare/types/magic_cloud_networking/on_ramp_delete_params.py +++ /dev/null @@ -1,15 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing_extensions import Required, TypedDict - -__all__ = ["OnRampDeleteParams"] - - -class OnRampDeleteParams(TypedDict, total=False): - account_id: Required[str] - - destroy: bool - - force: bool diff --git a/src/cloudflare/types/magic_cloud_networking/on_ramp_delete_response.py b/src/cloudflare/types/magic_cloud_networking/on_ramp_delete_response.py deleted file mode 100644 index 5ff6f58fdc0..00000000000 --- a/src/cloudflare/types/magic_cloud_networking/on_ramp_delete_response.py +++ /dev/null @@ -1,9 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from ..._models import BaseModel - -__all__ = ["OnRampDeleteResponse"] - - -class OnRampDeleteResponse(BaseModel): - id: str diff --git a/src/cloudflare/types/magic_cloud_networking/on_ramp_edit_params.py b/src/cloudflare/types/magic_cloud_networking/on_ramp_edit_params.py deleted file mode 100644 index 04cb0a141e5..00000000000 --- a/src/cloudflare/types/magic_cloud_networking/on_ramp_edit_params.py +++ /dev/null @@ -1,31 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing_extensions import Required, TypedDict - -from ..._types import SequenceNotStr - -__all__ = ["OnRampEditParams"] - - -class OnRampEditParams(TypedDict, total=False): - account_id: Required[str] - - attached_hubs: SequenceNotStr[str] - - attached_vpcs: SequenceNotStr[str] - - description: str - - install_routes_in_cloud: bool - - install_routes_in_magic_wan: bool - - manage_hub_to_hub_attachments: bool - - manage_vpc_to_hub_attachments: bool - - name: str - - vpc: str diff --git a/src/cloudflare/types/magic_cloud_networking/on_ramp_edit_response.py b/src/cloudflare/types/magic_cloud_networking/on_ramp_edit_response.py deleted file mode 100644 index 0925c0b18dd..00000000000 --- a/src/cloudflare/types/magic_cloud_networking/on_ramp_edit_response.py +++ /dev/null @@ -1,1675 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from typing import Dict, List, Union, Optional -from typing_extensions import Literal, Annotated, TypeAlias - -from pydantic import Field as FieldInfo - -from ..._utils import PropertyInfo -from ..._models import BaseModel - -__all__ = [ - "OnRampEditResponse", - "PlannedMonthlyCostEstimate", - "PlannedResource", - "PlannedResourceDiff", - "PlannedResourceMonthlyCostEstimateDiff", - "PlannedResourceResource", - "PostApplyMonthlyCostEstimate", - "PostApplyResources", - "PostApplyResourcesMonthlyCostEstimate", - "PostApplyResourcesObservations", - "PostApplyResourcesSection", - "PostApplyResourcesSectionHiddenItem", - "PostApplyResourcesSectionHiddenItemValue", - "PostApplyResourcesSectionHiddenItemValueMcnStringItem", - "PostApplyResourcesSectionHiddenItemValueMcnYamlItem", - "PostApplyResourcesSectionHiddenItemValueMcnYamlDiffItem", - "PostApplyResourcesSectionHiddenItemValueMcnYamlDiffItemYamlDiff", - "PostApplyResourcesSectionHiddenItemValueMcnResourcePreviewItem", - "PostApplyResourcesSectionHiddenItemValueMcnResourcePreviewItemResourcePreview", - "PostApplyResourcesSectionHiddenItemValueMcnListItem", - "PostApplyResourcesSectionHiddenItemValueMcnListItemList", - "PostApplyResourcesSectionHiddenItemValueMcnListItemListMcnStringItem", - "PostApplyResourcesSectionHiddenItemValueMcnListItemListMcnResourcePreviewItem", - "PostApplyResourcesSectionHiddenItemValueMcnListItemListMcnResourcePreviewItemResourcePreview", - "PostApplyResourcesSectionVisibleItem", - "PostApplyResourcesSectionVisibleItemValue", - "PostApplyResourcesSectionVisibleItemValueMcnStringItem", - "PostApplyResourcesSectionVisibleItemValueMcnYamlItem", - "PostApplyResourcesSectionVisibleItemValueMcnYamlDiffItem", - "PostApplyResourcesSectionVisibleItemValueMcnYamlDiffItemYamlDiff", - "PostApplyResourcesSectionVisibleItemValueMcnResourcePreviewItem", - "PostApplyResourcesSectionVisibleItemValueMcnResourcePreviewItemResourcePreview", - "PostApplyResourcesSectionVisibleItemValueMcnListItem", - "PostApplyResourcesSectionVisibleItemValueMcnListItemList", - "PostApplyResourcesSectionVisibleItemValueMcnListItemListMcnStringItem", - "PostApplyResourcesSectionVisibleItemValueMcnListItemListMcnResourcePreviewItem", - "PostApplyResourcesSectionVisibleItemValueMcnListItemListMcnResourcePreviewItemResourcePreview", - "PostApplyResourcesManagedBy", - "Status", - "StatusApplyProgress", - "StatusPlanProgress", - "StatusLifecycleErrors", - "StatusLifecycleErrorsMeta", - "StatusLifecycleErrorsSource", - "VPCsByID", - "VPCsByIDMonthlyCostEstimate", - "VPCsByIDObservations", - "VPCsByIDSection", - "VPCsByIDSectionHiddenItem", - "VPCsByIDSectionHiddenItemValue", - "VPCsByIDSectionHiddenItemValueMcnStringItem", - "VPCsByIDSectionHiddenItemValueMcnYamlItem", - "VPCsByIDSectionHiddenItemValueMcnYamlDiffItem", - "VPCsByIDSectionHiddenItemValueMcnYamlDiffItemYamlDiff", - "VPCsByIDSectionHiddenItemValueMcnResourcePreviewItem", - "VPCsByIDSectionHiddenItemValueMcnResourcePreviewItemResourcePreview", - "VPCsByIDSectionHiddenItemValueMcnListItem", - "VPCsByIDSectionHiddenItemValueMcnListItemList", - "VPCsByIDSectionHiddenItemValueMcnListItemListMcnStringItem", - "VPCsByIDSectionHiddenItemValueMcnListItemListMcnResourcePreviewItem", - "VPCsByIDSectionHiddenItemValueMcnListItemListMcnResourcePreviewItemResourcePreview", - "VPCsByIDSectionVisibleItem", - "VPCsByIDSectionVisibleItemValue", - "VPCsByIDSectionVisibleItemValueMcnStringItem", - "VPCsByIDSectionVisibleItemValueMcnYamlItem", - "VPCsByIDSectionVisibleItemValueMcnYamlDiffItem", - "VPCsByIDSectionVisibleItemValueMcnYamlDiffItemYamlDiff", - "VPCsByIDSectionVisibleItemValueMcnResourcePreviewItem", - "VPCsByIDSectionVisibleItemValueMcnResourcePreviewItemResourcePreview", - "VPCsByIDSectionVisibleItemValueMcnListItem", - "VPCsByIDSectionVisibleItemValueMcnListItemList", - "VPCsByIDSectionVisibleItemValueMcnListItemListMcnStringItem", - "VPCsByIDSectionVisibleItemValueMcnListItemListMcnResourcePreviewItem", - "VPCsByIDSectionVisibleItemValueMcnListItemListMcnResourcePreviewItemResourcePreview", - "VPCsByIDManagedBy", -] - - -class PlannedMonthlyCostEstimate(BaseModel): - currency: str - - current_monthly_cost: float - - diff: float - - proposed_monthly_cost: float - - -class PlannedResourceDiff(BaseModel): - diff: str - - left_description: str - - left_yaml: str - - right_description: str - - right_yaml: str - - -class PlannedResourceMonthlyCostEstimateDiff(BaseModel): - currency: str - - current_monthly_cost: float - - diff: float - - proposed_monthly_cost: float - - -class PlannedResourceResource(BaseModel): - id: str - - cloud_type: Literal["AWS", "AZURE", "GOOGLE", "CLOUDFLARE"] - - detail: str - - name: str - - resource_type: Literal[ - "aws_customer_gateway", - "aws_egress_only_internet_gateway", - "aws_internet_gateway", - "aws_instance", - "aws_network_interface", - "aws_route", - "aws_route_table", - "aws_route_table_association", - "aws_subnet", - "aws_vpc", - "aws_vpc_ipv4_cidr_block_association", - "aws_vpn_connection", - "aws_vpn_connection_route", - "aws_vpn_gateway", - "aws_security_group", - "aws_vpc_security_group_ingress_rule", - "aws_vpc_security_group_egress_rule", - "aws_ec2_managed_prefix_list", - "aws_ec2_transit_gateway", - "aws_ec2_transit_gateway_prefix_list_reference", - "aws_ec2_transit_gateway_vpc_attachment", - "azurerm_application_security_group", - "azurerm_lb", - "azurerm_lb_backend_address_pool", - "azurerm_lb_nat_pool", - "azurerm_lb_nat_rule", - "azurerm_lb_rule", - "azurerm_local_network_gateway", - "azurerm_network_interface", - "azurerm_network_interface_application_security_group_association", - "azurerm_network_interface_backend_address_pool_association", - "azurerm_network_interface_security_group_association", - "azurerm_network_security_group", - "azurerm_public_ip", - "azurerm_route", - "azurerm_route_table", - "azurerm_subnet", - "azurerm_subnet_route_table_association", - "azurerm_virtual_machine", - "azurerm_virtual_network_gateway_connection", - "azurerm_virtual_network", - "azurerm_virtual_network_gateway", - "google_compute_network", - "google_compute_subnetwork", - "google_compute_vpn_gateway", - "google_compute_vpn_tunnel", - "google_compute_route", - "google_compute_address", - "google_compute_global_address", - "google_compute_router", - "google_compute_interconnect_attachment", - "google_compute_ha_vpn_gateway", - "google_compute_forwarding_rule", - "google_compute_network_firewall_policy", - "google_compute_network_firewall_policy_rule", - "cloudflare_static_route", - "cloudflare_ipsec_tunnel", - ] - - title: str - - -class PlannedResource(BaseModel): - diff: PlannedResourceDiff - - keys_require_replace: List[str] - - monthly_cost_estimate_diff: PlannedResourceMonthlyCostEstimateDiff - - planned_action: Literal["no_op", "create", "update", "replace", "destroy"] - - resource: PlannedResourceResource - - -class PostApplyMonthlyCostEstimate(BaseModel): - currency: str - - monthly_cost: float - - -class PostApplyResourcesMonthlyCostEstimate(BaseModel): - currency: str - - monthly_cost: float - - -class PostApplyResourcesObservations(BaseModel): - first_observed_at: str - - last_observed_at: str - - provider_id: str - - resource_id: str - - -class PostApplyResourcesSectionHiddenItemValueMcnStringItem(BaseModel): - item_type: str - - string: str - - -class PostApplyResourcesSectionHiddenItemValueMcnYamlItem(BaseModel): - item_type: str - - yaml: str - - -class PostApplyResourcesSectionHiddenItemValueMcnYamlDiffItemYamlDiff(BaseModel): - diff: str - - left_description: str - - left_yaml: str - - right_description: str - - right_yaml: str - - -class PostApplyResourcesSectionHiddenItemValueMcnYamlDiffItem(BaseModel): - item_type: str - - yaml_diff: PostApplyResourcesSectionHiddenItemValueMcnYamlDiffItemYamlDiff - - -class PostApplyResourcesSectionHiddenItemValueMcnResourcePreviewItemResourcePreview(BaseModel): - id: str - - cloud_type: Literal["AWS", "AZURE", "GOOGLE", "CLOUDFLARE"] - - detail: str - - name: str - - resource_type: Literal[ - "aws_customer_gateway", - "aws_egress_only_internet_gateway", - "aws_internet_gateway", - "aws_instance", - "aws_network_interface", - "aws_route", - "aws_route_table", - "aws_route_table_association", - "aws_subnet", - "aws_vpc", - "aws_vpc_ipv4_cidr_block_association", - "aws_vpn_connection", - "aws_vpn_connection_route", - "aws_vpn_gateway", - "aws_security_group", - "aws_vpc_security_group_ingress_rule", - "aws_vpc_security_group_egress_rule", - "aws_ec2_managed_prefix_list", - "aws_ec2_transit_gateway", - "aws_ec2_transit_gateway_prefix_list_reference", - "aws_ec2_transit_gateway_vpc_attachment", - "azurerm_application_security_group", - "azurerm_lb", - "azurerm_lb_backend_address_pool", - "azurerm_lb_nat_pool", - "azurerm_lb_nat_rule", - "azurerm_lb_rule", - "azurerm_local_network_gateway", - "azurerm_network_interface", - "azurerm_network_interface_application_security_group_association", - "azurerm_network_interface_backend_address_pool_association", - "azurerm_network_interface_security_group_association", - "azurerm_network_security_group", - "azurerm_public_ip", - "azurerm_route", - "azurerm_route_table", - "azurerm_subnet", - "azurerm_subnet_route_table_association", - "azurerm_virtual_machine", - "azurerm_virtual_network_gateway_connection", - "azurerm_virtual_network", - "azurerm_virtual_network_gateway", - "google_compute_network", - "google_compute_subnetwork", - "google_compute_vpn_gateway", - "google_compute_vpn_tunnel", - "google_compute_route", - "google_compute_address", - "google_compute_global_address", - "google_compute_router", - "google_compute_interconnect_attachment", - "google_compute_ha_vpn_gateway", - "google_compute_forwarding_rule", - "google_compute_network_firewall_policy", - "google_compute_network_firewall_policy_rule", - "cloudflare_static_route", - "cloudflare_ipsec_tunnel", - ] - - title: str - - -class PostApplyResourcesSectionHiddenItemValueMcnResourcePreviewItem(BaseModel): - item_type: str - - resource_preview: PostApplyResourcesSectionHiddenItemValueMcnResourcePreviewItemResourcePreview - - -class PostApplyResourcesSectionHiddenItemValueMcnListItemListMcnStringItem(BaseModel): - item_type: str - - string: str - - -class PostApplyResourcesSectionHiddenItemValueMcnListItemListMcnResourcePreviewItemResourcePreview(BaseModel): - id: str - - cloud_type: Literal["AWS", "AZURE", "GOOGLE", "CLOUDFLARE"] - - detail: str - - name: str - - resource_type: Literal[ - "aws_customer_gateway", - "aws_egress_only_internet_gateway", - "aws_internet_gateway", - "aws_instance", - "aws_network_interface", - "aws_route", - "aws_route_table", - "aws_route_table_association", - "aws_subnet", - "aws_vpc", - "aws_vpc_ipv4_cidr_block_association", - "aws_vpn_connection", - "aws_vpn_connection_route", - "aws_vpn_gateway", - "aws_security_group", - "aws_vpc_security_group_ingress_rule", - "aws_vpc_security_group_egress_rule", - "aws_ec2_managed_prefix_list", - "aws_ec2_transit_gateway", - "aws_ec2_transit_gateway_prefix_list_reference", - "aws_ec2_transit_gateway_vpc_attachment", - "azurerm_application_security_group", - "azurerm_lb", - "azurerm_lb_backend_address_pool", - "azurerm_lb_nat_pool", - "azurerm_lb_nat_rule", - "azurerm_lb_rule", - "azurerm_local_network_gateway", - "azurerm_network_interface", - "azurerm_network_interface_application_security_group_association", - "azurerm_network_interface_backend_address_pool_association", - "azurerm_network_interface_security_group_association", - "azurerm_network_security_group", - "azurerm_public_ip", - "azurerm_route", - "azurerm_route_table", - "azurerm_subnet", - "azurerm_subnet_route_table_association", - "azurerm_virtual_machine", - "azurerm_virtual_network_gateway_connection", - "azurerm_virtual_network", - "azurerm_virtual_network_gateway", - "google_compute_network", - "google_compute_subnetwork", - "google_compute_vpn_gateway", - "google_compute_vpn_tunnel", - "google_compute_route", - "google_compute_address", - "google_compute_global_address", - "google_compute_router", - "google_compute_interconnect_attachment", - "google_compute_ha_vpn_gateway", - "google_compute_forwarding_rule", - "google_compute_network_firewall_policy", - "google_compute_network_firewall_policy_rule", - "cloudflare_static_route", - "cloudflare_ipsec_tunnel", - ] - - title: str - - -class PostApplyResourcesSectionHiddenItemValueMcnListItemListMcnResourcePreviewItem(BaseModel): - item_type: str - - resource_preview: PostApplyResourcesSectionHiddenItemValueMcnListItemListMcnResourcePreviewItemResourcePreview - - -PostApplyResourcesSectionHiddenItemValueMcnListItemList: TypeAlias = Annotated[ - Union[ - PostApplyResourcesSectionHiddenItemValueMcnListItemListMcnStringItem, - PostApplyResourcesSectionHiddenItemValueMcnListItemListMcnResourcePreviewItem, - ], - PropertyInfo(discriminator="item_type"), -] - - -class PostApplyResourcesSectionHiddenItemValueMcnListItem(BaseModel): - item_type: str - - rule_list: List[PostApplyResourcesSectionHiddenItemValueMcnListItemList] = FieldInfo(alias="list") - - -PostApplyResourcesSectionHiddenItemValue: TypeAlias = Annotated[ - Union[ - PostApplyResourcesSectionHiddenItemValueMcnStringItem, - PostApplyResourcesSectionHiddenItemValueMcnYamlItem, - PostApplyResourcesSectionHiddenItemValueMcnYamlDiffItem, - PostApplyResourcesSectionHiddenItemValueMcnResourcePreviewItem, - PostApplyResourcesSectionHiddenItemValueMcnListItem, - ], - PropertyInfo(discriminator="item_type"), -] - - -class PostApplyResourcesSectionHiddenItem(BaseModel): - help_text: Optional[str] = FieldInfo(alias="helpText", default=None) - - name: Optional[str] = None - - value: Optional[PostApplyResourcesSectionHiddenItemValue] = None - - -class PostApplyResourcesSectionVisibleItemValueMcnStringItem(BaseModel): - item_type: str - - string: str - - -class PostApplyResourcesSectionVisibleItemValueMcnYamlItem(BaseModel): - item_type: str - - yaml: str - - -class PostApplyResourcesSectionVisibleItemValueMcnYamlDiffItemYamlDiff(BaseModel): - diff: str - - left_description: str - - left_yaml: str - - right_description: str - - right_yaml: str - - -class PostApplyResourcesSectionVisibleItemValueMcnYamlDiffItem(BaseModel): - item_type: str - - yaml_diff: PostApplyResourcesSectionVisibleItemValueMcnYamlDiffItemYamlDiff - - -class PostApplyResourcesSectionVisibleItemValueMcnResourcePreviewItemResourcePreview(BaseModel): - id: str - - cloud_type: Literal["AWS", "AZURE", "GOOGLE", "CLOUDFLARE"] - - detail: str - - name: str - - resource_type: Literal[ - "aws_customer_gateway", - "aws_egress_only_internet_gateway", - "aws_internet_gateway", - "aws_instance", - "aws_network_interface", - "aws_route", - "aws_route_table", - "aws_route_table_association", - "aws_subnet", - "aws_vpc", - "aws_vpc_ipv4_cidr_block_association", - "aws_vpn_connection", - "aws_vpn_connection_route", - "aws_vpn_gateway", - "aws_security_group", - "aws_vpc_security_group_ingress_rule", - "aws_vpc_security_group_egress_rule", - "aws_ec2_managed_prefix_list", - "aws_ec2_transit_gateway", - "aws_ec2_transit_gateway_prefix_list_reference", - "aws_ec2_transit_gateway_vpc_attachment", - "azurerm_application_security_group", - "azurerm_lb", - "azurerm_lb_backend_address_pool", - "azurerm_lb_nat_pool", - "azurerm_lb_nat_rule", - "azurerm_lb_rule", - "azurerm_local_network_gateway", - "azurerm_network_interface", - "azurerm_network_interface_application_security_group_association", - "azurerm_network_interface_backend_address_pool_association", - "azurerm_network_interface_security_group_association", - "azurerm_network_security_group", - "azurerm_public_ip", - "azurerm_route", - "azurerm_route_table", - "azurerm_subnet", - "azurerm_subnet_route_table_association", - "azurerm_virtual_machine", - "azurerm_virtual_network_gateway_connection", - "azurerm_virtual_network", - "azurerm_virtual_network_gateway", - "google_compute_network", - "google_compute_subnetwork", - "google_compute_vpn_gateway", - "google_compute_vpn_tunnel", - "google_compute_route", - "google_compute_address", - "google_compute_global_address", - "google_compute_router", - "google_compute_interconnect_attachment", - "google_compute_ha_vpn_gateway", - "google_compute_forwarding_rule", - "google_compute_network_firewall_policy", - "google_compute_network_firewall_policy_rule", - "cloudflare_static_route", - "cloudflare_ipsec_tunnel", - ] - - title: str - - -class PostApplyResourcesSectionVisibleItemValueMcnResourcePreviewItem(BaseModel): - item_type: str - - resource_preview: PostApplyResourcesSectionVisibleItemValueMcnResourcePreviewItemResourcePreview - - -class PostApplyResourcesSectionVisibleItemValueMcnListItemListMcnStringItem(BaseModel): - item_type: str - - string: str - - -class PostApplyResourcesSectionVisibleItemValueMcnListItemListMcnResourcePreviewItemResourcePreview(BaseModel): - id: str - - cloud_type: Literal["AWS", "AZURE", "GOOGLE", "CLOUDFLARE"] - - detail: str - - name: str - - resource_type: Literal[ - "aws_customer_gateway", - "aws_egress_only_internet_gateway", - "aws_internet_gateway", - "aws_instance", - "aws_network_interface", - "aws_route", - "aws_route_table", - "aws_route_table_association", - "aws_subnet", - "aws_vpc", - "aws_vpc_ipv4_cidr_block_association", - "aws_vpn_connection", - "aws_vpn_connection_route", - "aws_vpn_gateway", - "aws_security_group", - "aws_vpc_security_group_ingress_rule", - "aws_vpc_security_group_egress_rule", - "aws_ec2_managed_prefix_list", - "aws_ec2_transit_gateway", - "aws_ec2_transit_gateway_prefix_list_reference", - "aws_ec2_transit_gateway_vpc_attachment", - "azurerm_application_security_group", - "azurerm_lb", - "azurerm_lb_backend_address_pool", - "azurerm_lb_nat_pool", - "azurerm_lb_nat_rule", - "azurerm_lb_rule", - "azurerm_local_network_gateway", - "azurerm_network_interface", - "azurerm_network_interface_application_security_group_association", - "azurerm_network_interface_backend_address_pool_association", - "azurerm_network_interface_security_group_association", - "azurerm_network_security_group", - "azurerm_public_ip", - "azurerm_route", - "azurerm_route_table", - "azurerm_subnet", - "azurerm_subnet_route_table_association", - "azurerm_virtual_machine", - "azurerm_virtual_network_gateway_connection", - "azurerm_virtual_network", - "azurerm_virtual_network_gateway", - "google_compute_network", - "google_compute_subnetwork", - "google_compute_vpn_gateway", - "google_compute_vpn_tunnel", - "google_compute_route", - "google_compute_address", - "google_compute_global_address", - "google_compute_router", - "google_compute_interconnect_attachment", - "google_compute_ha_vpn_gateway", - "google_compute_forwarding_rule", - "google_compute_network_firewall_policy", - "google_compute_network_firewall_policy_rule", - "cloudflare_static_route", - "cloudflare_ipsec_tunnel", - ] - - title: str - - -class PostApplyResourcesSectionVisibleItemValueMcnListItemListMcnResourcePreviewItem(BaseModel): - item_type: str - - resource_preview: PostApplyResourcesSectionVisibleItemValueMcnListItemListMcnResourcePreviewItemResourcePreview - - -PostApplyResourcesSectionVisibleItemValueMcnListItemList: TypeAlias = Annotated[ - Union[ - PostApplyResourcesSectionVisibleItemValueMcnListItemListMcnStringItem, - PostApplyResourcesSectionVisibleItemValueMcnListItemListMcnResourcePreviewItem, - ], - PropertyInfo(discriminator="item_type"), -] - - -class PostApplyResourcesSectionVisibleItemValueMcnListItem(BaseModel): - item_type: str - - rule_list: List[PostApplyResourcesSectionVisibleItemValueMcnListItemList] = FieldInfo(alias="list") - - -PostApplyResourcesSectionVisibleItemValue: TypeAlias = Annotated[ - Union[ - PostApplyResourcesSectionVisibleItemValueMcnStringItem, - PostApplyResourcesSectionVisibleItemValueMcnYamlItem, - PostApplyResourcesSectionVisibleItemValueMcnYamlDiffItem, - PostApplyResourcesSectionVisibleItemValueMcnResourcePreviewItem, - PostApplyResourcesSectionVisibleItemValueMcnListItem, - ], - PropertyInfo(discriminator="item_type"), -] - - -class PostApplyResourcesSectionVisibleItem(BaseModel): - help_text: Optional[str] = FieldInfo(alias="helpText", default=None) - - name: Optional[str] = None - - value: Optional[PostApplyResourcesSectionVisibleItemValue] = None - - -class PostApplyResourcesSection(BaseModel): - hidden_items: List[PostApplyResourcesSectionHiddenItem] - - name: str - - visible_items: List[PostApplyResourcesSectionVisibleItem] - - help_text: Optional[str] = None - - -class PostApplyResourcesManagedBy(BaseModel): - id: str - - client_type: Literal["MAGIC_WAN_CLOUD_ONRAMP"] - - name: str - - -class PostApplyResources(BaseModel): - id: str - - account_id: str - - cloud_type: Literal["AWS", "AZURE", "GOOGLE", "CLOUDFLARE"] - - config: Dict[str, object] - - deployment_provider: str - - managed: bool - - monthly_cost_estimate: PostApplyResourcesMonthlyCostEstimate - - name: str - - native_id: str - - observations: Dict[str, PostApplyResourcesObservations] - - provider_ids: List[str] - - provider_names_by_id: Dict[str, str] - - region: str - - resource_group: str - - resource_type: Literal[ - "aws_customer_gateway", - "aws_egress_only_internet_gateway", - "aws_internet_gateway", - "aws_instance", - "aws_network_interface", - "aws_route", - "aws_route_table", - "aws_route_table_association", - "aws_subnet", - "aws_vpc", - "aws_vpc_ipv4_cidr_block_association", - "aws_vpn_connection", - "aws_vpn_connection_route", - "aws_vpn_gateway", - "aws_security_group", - "aws_vpc_security_group_ingress_rule", - "aws_vpc_security_group_egress_rule", - "aws_ec2_managed_prefix_list", - "aws_ec2_transit_gateway", - "aws_ec2_transit_gateway_prefix_list_reference", - "aws_ec2_transit_gateway_vpc_attachment", - "azurerm_application_security_group", - "azurerm_lb", - "azurerm_lb_backend_address_pool", - "azurerm_lb_nat_pool", - "azurerm_lb_nat_rule", - "azurerm_lb_rule", - "azurerm_local_network_gateway", - "azurerm_network_interface", - "azurerm_network_interface_application_security_group_association", - "azurerm_network_interface_backend_address_pool_association", - "azurerm_network_interface_security_group_association", - "azurerm_network_security_group", - "azurerm_public_ip", - "azurerm_route", - "azurerm_route_table", - "azurerm_subnet", - "azurerm_subnet_route_table_association", - "azurerm_virtual_machine", - "azurerm_virtual_network_gateway_connection", - "azurerm_virtual_network", - "azurerm_virtual_network_gateway", - "google_compute_network", - "google_compute_subnetwork", - "google_compute_vpn_gateway", - "google_compute_vpn_tunnel", - "google_compute_route", - "google_compute_address", - "google_compute_global_address", - "google_compute_router", - "google_compute_interconnect_attachment", - "google_compute_ha_vpn_gateway", - "google_compute_forwarding_rule", - "google_compute_network_firewall_policy", - "google_compute_network_firewall_policy_rule", - "cloudflare_static_route", - "cloudflare_ipsec_tunnel", - ] - - sections: List[PostApplyResourcesSection] - - state: Dict[str, object] - - tags: Dict[str, str] - - updated_at: str - - url: str - - managed_by: Optional[List[PostApplyResourcesManagedBy]] = None - - -class StatusApplyProgress(BaseModel): - done: int - - total: int - - -class StatusPlanProgress(BaseModel): - done: int - - total: int - - -class StatusLifecycleErrorsMeta(BaseModel): - l10n_key: Optional[str] = None - - loggable_error: Optional[str] = None - - template_data: Optional[object] = None - - trace_id: Optional[str] = None - - -class StatusLifecycleErrorsSource(BaseModel): - parameter: Optional[str] = None - - parameter_value_index: Optional[int] = None - - pointer: Optional[str] = None - - -class StatusLifecycleErrors(BaseModel): - code: Literal[ - 1001, - 1002, - 1003, - 1004, - 1005, - 1006, - 1007, - 1008, - 1009, - 1010, - 1011, - 1012, - 1013, - 1014, - 1015, - 1016, - 1017, - 1018, - 2001, - 2002, - 2003, - 2004, - 2005, - 2006, - 2007, - 2008, - 2009, - 2010, - 2011, - 2012, - 2013, - 2014, - 2015, - 2016, - 2017, - 2018, - 2019, - 2020, - 2021, - 2022, - 3001, - 3002, - 3003, - 3004, - 3005, - 3006, - 3007, - 4001, - 4002, - 4003, - 4004, - 4005, - 4006, - 4007, - 4008, - 4009, - 4010, - 4011, - 4012, - 4013, - 4014, - 4015, - 4016, - 4017, - 4018, - 4019, - 4020, - 4021, - 4022, - 4023, - 5001, - 5002, - 5003, - 5004, - 102000, - 102001, - 102002, - 102003, - 102004, - 102005, - 102006, - 102007, - 102008, - 102009, - 102010, - 102011, - 102012, - 102013, - 102014, - 102015, - 102016, - 102017, - 102018, - 102019, - 102020, - 102021, - 102022, - 102023, - 102024, - 102025, - 102026, - 102027, - 102028, - 102029, - 102030, - 102031, - 102032, - 102033, - 102034, - 102035, - 102036, - 102037, - 102038, - 102039, - 102040, - 102041, - 102042, - 102043, - 102044, - 102045, - 102046, - 102047, - 102048, - 102049, - 102050, - 102051, - 102052, - 102053, - 102054, - 102055, - 102056, - 102057, - 102058, - 102059, - 102060, - 102061, - 102062, - 102063, - 102064, - 102065, - 102066, - 102067, - 102068, - 102069, - 102070, - 102071, - 102072, - 103001, - 103002, - 103003, - 103004, - 103005, - 103006, - 103007, - 103008, - ] - - message: str - - documentation_url: Optional[str] = None - - meta: Optional[StatusLifecycleErrorsMeta] = None - - source: Optional[StatusLifecycleErrorsSource] = None - - -class Status(BaseModel): - apply_progress: StatusApplyProgress - - lifecycle_state: Literal[ - "OnrampNeedsApply", - "OnrampPendingPlan", - "OnrampPlanning", - "OnrampPlanFailed", - "OnrampPendingApproval", - "OnrampPendingApply", - "OnrampApplying", - "OnrampApplyFailed", - "OnrampActive", - "OnrampPendingDestroy", - "OnrampDestroying", - "OnrampDestroyFailed", - ] - - plan_progress: StatusPlanProgress - - routes: List[str] - - tunnels: List[str] - - lifecycle_errors: Optional[Dict[str, StatusLifecycleErrors]] = None - - -class VPCsByIDMonthlyCostEstimate(BaseModel): - currency: str - - monthly_cost: float - - -class VPCsByIDObservations(BaseModel): - first_observed_at: str - - last_observed_at: str - - provider_id: str - - resource_id: str - - -class VPCsByIDSectionHiddenItemValueMcnStringItem(BaseModel): - item_type: str - - string: str - - -class VPCsByIDSectionHiddenItemValueMcnYamlItem(BaseModel): - item_type: str - - yaml: str - - -class VPCsByIDSectionHiddenItemValueMcnYamlDiffItemYamlDiff(BaseModel): - diff: str - - left_description: str - - left_yaml: str - - right_description: str - - right_yaml: str - - -class VPCsByIDSectionHiddenItemValueMcnYamlDiffItem(BaseModel): - item_type: str - - yaml_diff: VPCsByIDSectionHiddenItemValueMcnYamlDiffItemYamlDiff - - -class VPCsByIDSectionHiddenItemValueMcnResourcePreviewItemResourcePreview(BaseModel): - id: str - - cloud_type: Literal["AWS", "AZURE", "GOOGLE", "CLOUDFLARE"] - - detail: str - - name: str - - resource_type: Literal[ - "aws_customer_gateway", - "aws_egress_only_internet_gateway", - "aws_internet_gateway", - "aws_instance", - "aws_network_interface", - "aws_route", - "aws_route_table", - "aws_route_table_association", - "aws_subnet", - "aws_vpc", - "aws_vpc_ipv4_cidr_block_association", - "aws_vpn_connection", - "aws_vpn_connection_route", - "aws_vpn_gateway", - "aws_security_group", - "aws_vpc_security_group_ingress_rule", - "aws_vpc_security_group_egress_rule", - "aws_ec2_managed_prefix_list", - "aws_ec2_transit_gateway", - "aws_ec2_transit_gateway_prefix_list_reference", - "aws_ec2_transit_gateway_vpc_attachment", - "azurerm_application_security_group", - "azurerm_lb", - "azurerm_lb_backend_address_pool", - "azurerm_lb_nat_pool", - "azurerm_lb_nat_rule", - "azurerm_lb_rule", - "azurerm_local_network_gateway", - "azurerm_network_interface", - "azurerm_network_interface_application_security_group_association", - "azurerm_network_interface_backend_address_pool_association", - "azurerm_network_interface_security_group_association", - "azurerm_network_security_group", - "azurerm_public_ip", - "azurerm_route", - "azurerm_route_table", - "azurerm_subnet", - "azurerm_subnet_route_table_association", - "azurerm_virtual_machine", - "azurerm_virtual_network_gateway_connection", - "azurerm_virtual_network", - "azurerm_virtual_network_gateway", - "google_compute_network", - "google_compute_subnetwork", - "google_compute_vpn_gateway", - "google_compute_vpn_tunnel", - "google_compute_route", - "google_compute_address", - "google_compute_global_address", - "google_compute_router", - "google_compute_interconnect_attachment", - "google_compute_ha_vpn_gateway", - "google_compute_forwarding_rule", - "google_compute_network_firewall_policy", - "google_compute_network_firewall_policy_rule", - "cloudflare_static_route", - "cloudflare_ipsec_tunnel", - ] - - title: str - - -class VPCsByIDSectionHiddenItemValueMcnResourcePreviewItem(BaseModel): - item_type: str - - resource_preview: VPCsByIDSectionHiddenItemValueMcnResourcePreviewItemResourcePreview - - -class VPCsByIDSectionHiddenItemValueMcnListItemListMcnStringItem(BaseModel): - item_type: str - - string: str - - -class VPCsByIDSectionHiddenItemValueMcnListItemListMcnResourcePreviewItemResourcePreview(BaseModel): - id: str - - cloud_type: Literal["AWS", "AZURE", "GOOGLE", "CLOUDFLARE"] - - detail: str - - name: str - - resource_type: Literal[ - "aws_customer_gateway", - "aws_egress_only_internet_gateway", - "aws_internet_gateway", - "aws_instance", - "aws_network_interface", - "aws_route", - "aws_route_table", - "aws_route_table_association", - "aws_subnet", - "aws_vpc", - "aws_vpc_ipv4_cidr_block_association", - "aws_vpn_connection", - "aws_vpn_connection_route", - "aws_vpn_gateway", - "aws_security_group", - "aws_vpc_security_group_ingress_rule", - "aws_vpc_security_group_egress_rule", - "aws_ec2_managed_prefix_list", - "aws_ec2_transit_gateway", - "aws_ec2_transit_gateway_prefix_list_reference", - "aws_ec2_transit_gateway_vpc_attachment", - "azurerm_application_security_group", - "azurerm_lb", - "azurerm_lb_backend_address_pool", - "azurerm_lb_nat_pool", - "azurerm_lb_nat_rule", - "azurerm_lb_rule", - "azurerm_local_network_gateway", - "azurerm_network_interface", - "azurerm_network_interface_application_security_group_association", - "azurerm_network_interface_backend_address_pool_association", - "azurerm_network_interface_security_group_association", - "azurerm_network_security_group", - "azurerm_public_ip", - "azurerm_route", - "azurerm_route_table", - "azurerm_subnet", - "azurerm_subnet_route_table_association", - "azurerm_virtual_machine", - "azurerm_virtual_network_gateway_connection", - "azurerm_virtual_network", - "azurerm_virtual_network_gateway", - "google_compute_network", - "google_compute_subnetwork", - "google_compute_vpn_gateway", - "google_compute_vpn_tunnel", - "google_compute_route", - "google_compute_address", - "google_compute_global_address", - "google_compute_router", - "google_compute_interconnect_attachment", - "google_compute_ha_vpn_gateway", - "google_compute_forwarding_rule", - "google_compute_network_firewall_policy", - "google_compute_network_firewall_policy_rule", - "cloudflare_static_route", - "cloudflare_ipsec_tunnel", - ] - - title: str - - -class VPCsByIDSectionHiddenItemValueMcnListItemListMcnResourcePreviewItem(BaseModel): - item_type: str - - resource_preview: VPCsByIDSectionHiddenItemValueMcnListItemListMcnResourcePreviewItemResourcePreview - - -VPCsByIDSectionHiddenItemValueMcnListItemList: TypeAlias = Annotated[ - Union[ - VPCsByIDSectionHiddenItemValueMcnListItemListMcnStringItem, - VPCsByIDSectionHiddenItemValueMcnListItemListMcnResourcePreviewItem, - ], - PropertyInfo(discriminator="item_type"), -] - - -class VPCsByIDSectionHiddenItemValueMcnListItem(BaseModel): - item_type: str - - rule_list: List[VPCsByIDSectionHiddenItemValueMcnListItemList] = FieldInfo(alias="list") - - -VPCsByIDSectionHiddenItemValue: TypeAlias = Annotated[ - Union[ - VPCsByIDSectionHiddenItemValueMcnStringItem, - VPCsByIDSectionHiddenItemValueMcnYamlItem, - VPCsByIDSectionHiddenItemValueMcnYamlDiffItem, - VPCsByIDSectionHiddenItemValueMcnResourcePreviewItem, - VPCsByIDSectionHiddenItemValueMcnListItem, - ], - PropertyInfo(discriminator="item_type"), -] - - -class VPCsByIDSectionHiddenItem(BaseModel): - help_text: Optional[str] = FieldInfo(alias="helpText", default=None) - - name: Optional[str] = None - - value: Optional[VPCsByIDSectionHiddenItemValue] = None - - -class VPCsByIDSectionVisibleItemValueMcnStringItem(BaseModel): - item_type: str - - string: str - - -class VPCsByIDSectionVisibleItemValueMcnYamlItem(BaseModel): - item_type: str - - yaml: str - - -class VPCsByIDSectionVisibleItemValueMcnYamlDiffItemYamlDiff(BaseModel): - diff: str - - left_description: str - - left_yaml: str - - right_description: str - - right_yaml: str - - -class VPCsByIDSectionVisibleItemValueMcnYamlDiffItem(BaseModel): - item_type: str - - yaml_diff: VPCsByIDSectionVisibleItemValueMcnYamlDiffItemYamlDiff - - -class VPCsByIDSectionVisibleItemValueMcnResourcePreviewItemResourcePreview(BaseModel): - id: str - - cloud_type: Literal["AWS", "AZURE", "GOOGLE", "CLOUDFLARE"] - - detail: str - - name: str - - resource_type: Literal[ - "aws_customer_gateway", - "aws_egress_only_internet_gateway", - "aws_internet_gateway", - "aws_instance", - "aws_network_interface", - "aws_route", - "aws_route_table", - "aws_route_table_association", - "aws_subnet", - "aws_vpc", - "aws_vpc_ipv4_cidr_block_association", - "aws_vpn_connection", - "aws_vpn_connection_route", - "aws_vpn_gateway", - "aws_security_group", - "aws_vpc_security_group_ingress_rule", - "aws_vpc_security_group_egress_rule", - "aws_ec2_managed_prefix_list", - "aws_ec2_transit_gateway", - "aws_ec2_transit_gateway_prefix_list_reference", - "aws_ec2_transit_gateway_vpc_attachment", - "azurerm_application_security_group", - "azurerm_lb", - "azurerm_lb_backend_address_pool", - "azurerm_lb_nat_pool", - "azurerm_lb_nat_rule", - "azurerm_lb_rule", - "azurerm_local_network_gateway", - "azurerm_network_interface", - "azurerm_network_interface_application_security_group_association", - "azurerm_network_interface_backend_address_pool_association", - "azurerm_network_interface_security_group_association", - "azurerm_network_security_group", - "azurerm_public_ip", - "azurerm_route", - "azurerm_route_table", - "azurerm_subnet", - "azurerm_subnet_route_table_association", - "azurerm_virtual_machine", - "azurerm_virtual_network_gateway_connection", - "azurerm_virtual_network", - "azurerm_virtual_network_gateway", - "google_compute_network", - "google_compute_subnetwork", - "google_compute_vpn_gateway", - "google_compute_vpn_tunnel", - "google_compute_route", - "google_compute_address", - "google_compute_global_address", - "google_compute_router", - "google_compute_interconnect_attachment", - "google_compute_ha_vpn_gateway", - "google_compute_forwarding_rule", - "google_compute_network_firewall_policy", - "google_compute_network_firewall_policy_rule", - "cloudflare_static_route", - "cloudflare_ipsec_tunnel", - ] - - title: str - - -class VPCsByIDSectionVisibleItemValueMcnResourcePreviewItem(BaseModel): - item_type: str - - resource_preview: VPCsByIDSectionVisibleItemValueMcnResourcePreviewItemResourcePreview - - -class VPCsByIDSectionVisibleItemValueMcnListItemListMcnStringItem(BaseModel): - item_type: str - - string: str - - -class VPCsByIDSectionVisibleItemValueMcnListItemListMcnResourcePreviewItemResourcePreview(BaseModel): - id: str - - cloud_type: Literal["AWS", "AZURE", "GOOGLE", "CLOUDFLARE"] - - detail: str - - name: str - - resource_type: Literal[ - "aws_customer_gateway", - "aws_egress_only_internet_gateway", - "aws_internet_gateway", - "aws_instance", - "aws_network_interface", - "aws_route", - "aws_route_table", - "aws_route_table_association", - "aws_subnet", - "aws_vpc", - "aws_vpc_ipv4_cidr_block_association", - "aws_vpn_connection", - "aws_vpn_connection_route", - "aws_vpn_gateway", - "aws_security_group", - "aws_vpc_security_group_ingress_rule", - "aws_vpc_security_group_egress_rule", - "aws_ec2_managed_prefix_list", - "aws_ec2_transit_gateway", - "aws_ec2_transit_gateway_prefix_list_reference", - "aws_ec2_transit_gateway_vpc_attachment", - "azurerm_application_security_group", - "azurerm_lb", - "azurerm_lb_backend_address_pool", - "azurerm_lb_nat_pool", - "azurerm_lb_nat_rule", - "azurerm_lb_rule", - "azurerm_local_network_gateway", - "azurerm_network_interface", - "azurerm_network_interface_application_security_group_association", - "azurerm_network_interface_backend_address_pool_association", - "azurerm_network_interface_security_group_association", - "azurerm_network_security_group", - "azurerm_public_ip", - "azurerm_route", - "azurerm_route_table", - "azurerm_subnet", - "azurerm_subnet_route_table_association", - "azurerm_virtual_machine", - "azurerm_virtual_network_gateway_connection", - "azurerm_virtual_network", - "azurerm_virtual_network_gateway", - "google_compute_network", - "google_compute_subnetwork", - "google_compute_vpn_gateway", - "google_compute_vpn_tunnel", - "google_compute_route", - "google_compute_address", - "google_compute_global_address", - "google_compute_router", - "google_compute_interconnect_attachment", - "google_compute_ha_vpn_gateway", - "google_compute_forwarding_rule", - "google_compute_network_firewall_policy", - "google_compute_network_firewall_policy_rule", - "cloudflare_static_route", - "cloudflare_ipsec_tunnel", - ] - - title: str - - -class VPCsByIDSectionVisibleItemValueMcnListItemListMcnResourcePreviewItem(BaseModel): - item_type: str - - resource_preview: VPCsByIDSectionVisibleItemValueMcnListItemListMcnResourcePreviewItemResourcePreview - - -VPCsByIDSectionVisibleItemValueMcnListItemList: TypeAlias = Annotated[ - Union[ - VPCsByIDSectionVisibleItemValueMcnListItemListMcnStringItem, - VPCsByIDSectionVisibleItemValueMcnListItemListMcnResourcePreviewItem, - ], - PropertyInfo(discriminator="item_type"), -] - - -class VPCsByIDSectionVisibleItemValueMcnListItem(BaseModel): - item_type: str - - rule_list: List[VPCsByIDSectionVisibleItemValueMcnListItemList] = FieldInfo(alias="list") - - -VPCsByIDSectionVisibleItemValue: TypeAlias = Annotated[ - Union[ - VPCsByIDSectionVisibleItemValueMcnStringItem, - VPCsByIDSectionVisibleItemValueMcnYamlItem, - VPCsByIDSectionVisibleItemValueMcnYamlDiffItem, - VPCsByIDSectionVisibleItemValueMcnResourcePreviewItem, - VPCsByIDSectionVisibleItemValueMcnListItem, - ], - PropertyInfo(discriminator="item_type"), -] - - -class VPCsByIDSectionVisibleItem(BaseModel): - help_text: Optional[str] = FieldInfo(alias="helpText", default=None) - - name: Optional[str] = None - - value: Optional[VPCsByIDSectionVisibleItemValue] = None - - -class VPCsByIDSection(BaseModel): - hidden_items: List[VPCsByIDSectionHiddenItem] - - name: str - - visible_items: List[VPCsByIDSectionVisibleItem] - - help_text: Optional[str] = None - - -class VPCsByIDManagedBy(BaseModel): - id: str - - client_type: Literal["MAGIC_WAN_CLOUD_ONRAMP"] - - name: str - - -class VPCsByID(BaseModel): - id: str - - account_id: str - - cloud_type: Literal["AWS", "AZURE", "GOOGLE", "CLOUDFLARE"] - - config: Dict[str, object] - - deployment_provider: str - - managed: bool - - monthly_cost_estimate: VPCsByIDMonthlyCostEstimate - - name: str - - native_id: str - - observations: Dict[str, VPCsByIDObservations] - - provider_ids: List[str] - - provider_names_by_id: Dict[str, str] - - region: str - - resource_group: str - - resource_type: Literal[ - "aws_customer_gateway", - "aws_egress_only_internet_gateway", - "aws_internet_gateway", - "aws_instance", - "aws_network_interface", - "aws_route", - "aws_route_table", - "aws_route_table_association", - "aws_subnet", - "aws_vpc", - "aws_vpc_ipv4_cidr_block_association", - "aws_vpn_connection", - "aws_vpn_connection_route", - "aws_vpn_gateway", - "aws_security_group", - "aws_vpc_security_group_ingress_rule", - "aws_vpc_security_group_egress_rule", - "aws_ec2_managed_prefix_list", - "aws_ec2_transit_gateway", - "aws_ec2_transit_gateway_prefix_list_reference", - "aws_ec2_transit_gateway_vpc_attachment", - "azurerm_application_security_group", - "azurerm_lb", - "azurerm_lb_backend_address_pool", - "azurerm_lb_nat_pool", - "azurerm_lb_nat_rule", - "azurerm_lb_rule", - "azurerm_local_network_gateway", - "azurerm_network_interface", - "azurerm_network_interface_application_security_group_association", - "azurerm_network_interface_backend_address_pool_association", - "azurerm_network_interface_security_group_association", - "azurerm_network_security_group", - "azurerm_public_ip", - "azurerm_route", - "azurerm_route_table", - "azurerm_subnet", - "azurerm_subnet_route_table_association", - "azurerm_virtual_machine", - "azurerm_virtual_network_gateway_connection", - "azurerm_virtual_network", - "azurerm_virtual_network_gateway", - "google_compute_network", - "google_compute_subnetwork", - "google_compute_vpn_gateway", - "google_compute_vpn_tunnel", - "google_compute_route", - "google_compute_address", - "google_compute_global_address", - "google_compute_router", - "google_compute_interconnect_attachment", - "google_compute_ha_vpn_gateway", - "google_compute_forwarding_rule", - "google_compute_network_firewall_policy", - "google_compute_network_firewall_policy_rule", - "cloudflare_static_route", - "cloudflare_ipsec_tunnel", - ] - - sections: List[VPCsByIDSection] - - state: Dict[str, object] - - tags: Dict[str, str] - - updated_at: str - - url: str - - managed_by: Optional[List[VPCsByIDManagedBy]] = None - - -class OnRampEditResponse(BaseModel): - id: str - - cloud_type: Literal["AWS", "AZURE", "GOOGLE"] - - dynamic_routing: bool - - install_routes_in_cloud: bool - - install_routes_in_magic_wan: bool - - name: str - - type: Literal["OnrampTypeSingle", "OnrampTypeHub"] - - updated_at: str - - attached_hubs: Optional[List[str]] = None - - attached_vpcs: Optional[List[str]] = None - - cloud_asn: Optional[int] = None - - description: Optional[str] = None - - hub: Optional[str] = None - - last_applied_at: Optional[str] = None - - last_exported_at: Optional[str] = None - - last_planned_at: Optional[str] = None - - manage_hub_to_hub_attachments: Optional[bool] = None - - manage_vpc_to_hub_attachments: Optional[bool] = None - - planned_monthly_cost_estimate: Optional[PlannedMonthlyCostEstimate] = None - - planned_resources: Optional[List[PlannedResource]] = None - - planned_resources_unavailable: Optional[bool] = None - - post_apply_monthly_cost_estimate: Optional[PostApplyMonthlyCostEstimate] = None - - post_apply_resources: Optional[Dict[str, PostApplyResources]] = None - - post_apply_resources_unavailable: Optional[bool] = None - - region: Optional[str] = None - - status: Optional[Status] = None - - vpc: Optional[str] = None - - vpcs_by_id: Optional[Dict[str, VPCsByID]] = None - - vpcs_by_id_unavailable: Optional[List[str]] = None - """The list of vpc IDs for which resource details failed to generate.""" diff --git a/src/cloudflare/types/magic_cloud_networking/on_ramp_get_params.py b/src/cloudflare/types/magic_cloud_networking/on_ramp_get_params.py deleted file mode 100644 index b3c8a9df5a2..00000000000 --- a/src/cloudflare/types/magic_cloud_networking/on_ramp_get_params.py +++ /dev/null @@ -1,19 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing_extensions import Required, TypedDict - -__all__ = ["OnRampGetParams"] - - -class OnRampGetParams(TypedDict, total=False): - account_id: Required[str] - - planned_resources: bool - - post_apply_resources: bool - - status: bool - - vpcs: bool diff --git a/src/cloudflare/types/magic_cloud_networking/on_ramp_get_response.py b/src/cloudflare/types/magic_cloud_networking/on_ramp_get_response.py deleted file mode 100644 index 70f48a4e22a..00000000000 --- a/src/cloudflare/types/magic_cloud_networking/on_ramp_get_response.py +++ /dev/null @@ -1,1675 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from typing import Dict, List, Union, Optional -from typing_extensions import Literal, Annotated, TypeAlias - -from pydantic import Field as FieldInfo - -from ..._utils import PropertyInfo -from ..._models import BaseModel - -__all__ = [ - "OnRampGetResponse", - "PlannedMonthlyCostEstimate", - "PlannedResource", - "PlannedResourceDiff", - "PlannedResourceMonthlyCostEstimateDiff", - "PlannedResourceResource", - "PostApplyMonthlyCostEstimate", - "PostApplyResources", - "PostApplyResourcesMonthlyCostEstimate", - "PostApplyResourcesObservations", - "PostApplyResourcesSection", - "PostApplyResourcesSectionHiddenItem", - "PostApplyResourcesSectionHiddenItemValue", - "PostApplyResourcesSectionHiddenItemValueMcnStringItem", - "PostApplyResourcesSectionHiddenItemValueMcnYamlItem", - "PostApplyResourcesSectionHiddenItemValueMcnYamlDiffItem", - "PostApplyResourcesSectionHiddenItemValueMcnYamlDiffItemYamlDiff", - "PostApplyResourcesSectionHiddenItemValueMcnResourcePreviewItem", - "PostApplyResourcesSectionHiddenItemValueMcnResourcePreviewItemResourcePreview", - "PostApplyResourcesSectionHiddenItemValueMcnListItem", - "PostApplyResourcesSectionHiddenItemValueMcnListItemList", - "PostApplyResourcesSectionHiddenItemValueMcnListItemListMcnStringItem", - "PostApplyResourcesSectionHiddenItemValueMcnListItemListMcnResourcePreviewItem", - "PostApplyResourcesSectionHiddenItemValueMcnListItemListMcnResourcePreviewItemResourcePreview", - "PostApplyResourcesSectionVisibleItem", - "PostApplyResourcesSectionVisibleItemValue", - "PostApplyResourcesSectionVisibleItemValueMcnStringItem", - "PostApplyResourcesSectionVisibleItemValueMcnYamlItem", - "PostApplyResourcesSectionVisibleItemValueMcnYamlDiffItem", - "PostApplyResourcesSectionVisibleItemValueMcnYamlDiffItemYamlDiff", - "PostApplyResourcesSectionVisibleItemValueMcnResourcePreviewItem", - "PostApplyResourcesSectionVisibleItemValueMcnResourcePreviewItemResourcePreview", - "PostApplyResourcesSectionVisibleItemValueMcnListItem", - "PostApplyResourcesSectionVisibleItemValueMcnListItemList", - "PostApplyResourcesSectionVisibleItemValueMcnListItemListMcnStringItem", - "PostApplyResourcesSectionVisibleItemValueMcnListItemListMcnResourcePreviewItem", - "PostApplyResourcesSectionVisibleItemValueMcnListItemListMcnResourcePreviewItemResourcePreview", - "PostApplyResourcesManagedBy", - "Status", - "StatusApplyProgress", - "StatusPlanProgress", - "StatusLifecycleErrors", - "StatusLifecycleErrorsMeta", - "StatusLifecycleErrorsSource", - "VPCsByID", - "VPCsByIDMonthlyCostEstimate", - "VPCsByIDObservations", - "VPCsByIDSection", - "VPCsByIDSectionHiddenItem", - "VPCsByIDSectionHiddenItemValue", - "VPCsByIDSectionHiddenItemValueMcnStringItem", - "VPCsByIDSectionHiddenItemValueMcnYamlItem", - "VPCsByIDSectionHiddenItemValueMcnYamlDiffItem", - "VPCsByIDSectionHiddenItemValueMcnYamlDiffItemYamlDiff", - "VPCsByIDSectionHiddenItemValueMcnResourcePreviewItem", - "VPCsByIDSectionHiddenItemValueMcnResourcePreviewItemResourcePreview", - "VPCsByIDSectionHiddenItemValueMcnListItem", - "VPCsByIDSectionHiddenItemValueMcnListItemList", - "VPCsByIDSectionHiddenItemValueMcnListItemListMcnStringItem", - "VPCsByIDSectionHiddenItemValueMcnListItemListMcnResourcePreviewItem", - "VPCsByIDSectionHiddenItemValueMcnListItemListMcnResourcePreviewItemResourcePreview", - "VPCsByIDSectionVisibleItem", - "VPCsByIDSectionVisibleItemValue", - "VPCsByIDSectionVisibleItemValueMcnStringItem", - "VPCsByIDSectionVisibleItemValueMcnYamlItem", - "VPCsByIDSectionVisibleItemValueMcnYamlDiffItem", - "VPCsByIDSectionVisibleItemValueMcnYamlDiffItemYamlDiff", - "VPCsByIDSectionVisibleItemValueMcnResourcePreviewItem", - "VPCsByIDSectionVisibleItemValueMcnResourcePreviewItemResourcePreview", - "VPCsByIDSectionVisibleItemValueMcnListItem", - "VPCsByIDSectionVisibleItemValueMcnListItemList", - "VPCsByIDSectionVisibleItemValueMcnListItemListMcnStringItem", - "VPCsByIDSectionVisibleItemValueMcnListItemListMcnResourcePreviewItem", - "VPCsByIDSectionVisibleItemValueMcnListItemListMcnResourcePreviewItemResourcePreview", - "VPCsByIDManagedBy", -] - - -class PlannedMonthlyCostEstimate(BaseModel): - currency: str - - current_monthly_cost: float - - diff: float - - proposed_monthly_cost: float - - -class PlannedResourceDiff(BaseModel): - diff: str - - left_description: str - - left_yaml: str - - right_description: str - - right_yaml: str - - -class PlannedResourceMonthlyCostEstimateDiff(BaseModel): - currency: str - - current_monthly_cost: float - - diff: float - - proposed_monthly_cost: float - - -class PlannedResourceResource(BaseModel): - id: str - - cloud_type: Literal["AWS", "AZURE", "GOOGLE", "CLOUDFLARE"] - - detail: str - - name: str - - resource_type: Literal[ - "aws_customer_gateway", - "aws_egress_only_internet_gateway", - "aws_internet_gateway", - "aws_instance", - "aws_network_interface", - "aws_route", - "aws_route_table", - "aws_route_table_association", - "aws_subnet", - "aws_vpc", - "aws_vpc_ipv4_cidr_block_association", - "aws_vpn_connection", - "aws_vpn_connection_route", - "aws_vpn_gateway", - "aws_security_group", - "aws_vpc_security_group_ingress_rule", - "aws_vpc_security_group_egress_rule", - "aws_ec2_managed_prefix_list", - "aws_ec2_transit_gateway", - "aws_ec2_transit_gateway_prefix_list_reference", - "aws_ec2_transit_gateway_vpc_attachment", - "azurerm_application_security_group", - "azurerm_lb", - "azurerm_lb_backend_address_pool", - "azurerm_lb_nat_pool", - "azurerm_lb_nat_rule", - "azurerm_lb_rule", - "azurerm_local_network_gateway", - "azurerm_network_interface", - "azurerm_network_interface_application_security_group_association", - "azurerm_network_interface_backend_address_pool_association", - "azurerm_network_interface_security_group_association", - "azurerm_network_security_group", - "azurerm_public_ip", - "azurerm_route", - "azurerm_route_table", - "azurerm_subnet", - "azurerm_subnet_route_table_association", - "azurerm_virtual_machine", - "azurerm_virtual_network_gateway_connection", - "azurerm_virtual_network", - "azurerm_virtual_network_gateway", - "google_compute_network", - "google_compute_subnetwork", - "google_compute_vpn_gateway", - "google_compute_vpn_tunnel", - "google_compute_route", - "google_compute_address", - "google_compute_global_address", - "google_compute_router", - "google_compute_interconnect_attachment", - "google_compute_ha_vpn_gateway", - "google_compute_forwarding_rule", - "google_compute_network_firewall_policy", - "google_compute_network_firewall_policy_rule", - "cloudflare_static_route", - "cloudflare_ipsec_tunnel", - ] - - title: str - - -class PlannedResource(BaseModel): - diff: PlannedResourceDiff - - keys_require_replace: List[str] - - monthly_cost_estimate_diff: PlannedResourceMonthlyCostEstimateDiff - - planned_action: Literal["no_op", "create", "update", "replace", "destroy"] - - resource: PlannedResourceResource - - -class PostApplyMonthlyCostEstimate(BaseModel): - currency: str - - monthly_cost: float - - -class PostApplyResourcesMonthlyCostEstimate(BaseModel): - currency: str - - monthly_cost: float - - -class PostApplyResourcesObservations(BaseModel): - first_observed_at: str - - last_observed_at: str - - provider_id: str - - resource_id: str - - -class PostApplyResourcesSectionHiddenItemValueMcnStringItem(BaseModel): - item_type: str - - string: str - - -class PostApplyResourcesSectionHiddenItemValueMcnYamlItem(BaseModel): - item_type: str - - yaml: str - - -class PostApplyResourcesSectionHiddenItemValueMcnYamlDiffItemYamlDiff(BaseModel): - diff: str - - left_description: str - - left_yaml: str - - right_description: str - - right_yaml: str - - -class PostApplyResourcesSectionHiddenItemValueMcnYamlDiffItem(BaseModel): - item_type: str - - yaml_diff: PostApplyResourcesSectionHiddenItemValueMcnYamlDiffItemYamlDiff - - -class PostApplyResourcesSectionHiddenItemValueMcnResourcePreviewItemResourcePreview(BaseModel): - id: str - - cloud_type: Literal["AWS", "AZURE", "GOOGLE", "CLOUDFLARE"] - - detail: str - - name: str - - resource_type: Literal[ - "aws_customer_gateway", - "aws_egress_only_internet_gateway", - "aws_internet_gateway", - "aws_instance", - "aws_network_interface", - "aws_route", - "aws_route_table", - "aws_route_table_association", - "aws_subnet", - "aws_vpc", - "aws_vpc_ipv4_cidr_block_association", - "aws_vpn_connection", - "aws_vpn_connection_route", - "aws_vpn_gateway", - "aws_security_group", - "aws_vpc_security_group_ingress_rule", - "aws_vpc_security_group_egress_rule", - "aws_ec2_managed_prefix_list", - "aws_ec2_transit_gateway", - "aws_ec2_transit_gateway_prefix_list_reference", - "aws_ec2_transit_gateway_vpc_attachment", - "azurerm_application_security_group", - "azurerm_lb", - "azurerm_lb_backend_address_pool", - "azurerm_lb_nat_pool", - "azurerm_lb_nat_rule", - "azurerm_lb_rule", - "azurerm_local_network_gateway", - "azurerm_network_interface", - "azurerm_network_interface_application_security_group_association", - "azurerm_network_interface_backend_address_pool_association", - "azurerm_network_interface_security_group_association", - "azurerm_network_security_group", - "azurerm_public_ip", - "azurerm_route", - "azurerm_route_table", - "azurerm_subnet", - "azurerm_subnet_route_table_association", - "azurerm_virtual_machine", - "azurerm_virtual_network_gateway_connection", - "azurerm_virtual_network", - "azurerm_virtual_network_gateway", - "google_compute_network", - "google_compute_subnetwork", - "google_compute_vpn_gateway", - "google_compute_vpn_tunnel", - "google_compute_route", - "google_compute_address", - "google_compute_global_address", - "google_compute_router", - "google_compute_interconnect_attachment", - "google_compute_ha_vpn_gateway", - "google_compute_forwarding_rule", - "google_compute_network_firewall_policy", - "google_compute_network_firewall_policy_rule", - "cloudflare_static_route", - "cloudflare_ipsec_tunnel", - ] - - title: str - - -class PostApplyResourcesSectionHiddenItemValueMcnResourcePreviewItem(BaseModel): - item_type: str - - resource_preview: PostApplyResourcesSectionHiddenItemValueMcnResourcePreviewItemResourcePreview - - -class PostApplyResourcesSectionHiddenItemValueMcnListItemListMcnStringItem(BaseModel): - item_type: str - - string: str - - -class PostApplyResourcesSectionHiddenItemValueMcnListItemListMcnResourcePreviewItemResourcePreview(BaseModel): - id: str - - cloud_type: Literal["AWS", "AZURE", "GOOGLE", "CLOUDFLARE"] - - detail: str - - name: str - - resource_type: Literal[ - "aws_customer_gateway", - "aws_egress_only_internet_gateway", - "aws_internet_gateway", - "aws_instance", - "aws_network_interface", - "aws_route", - "aws_route_table", - "aws_route_table_association", - "aws_subnet", - "aws_vpc", - "aws_vpc_ipv4_cidr_block_association", - "aws_vpn_connection", - "aws_vpn_connection_route", - "aws_vpn_gateway", - "aws_security_group", - "aws_vpc_security_group_ingress_rule", - "aws_vpc_security_group_egress_rule", - "aws_ec2_managed_prefix_list", - "aws_ec2_transit_gateway", - "aws_ec2_transit_gateway_prefix_list_reference", - "aws_ec2_transit_gateway_vpc_attachment", - "azurerm_application_security_group", - "azurerm_lb", - "azurerm_lb_backend_address_pool", - "azurerm_lb_nat_pool", - "azurerm_lb_nat_rule", - "azurerm_lb_rule", - "azurerm_local_network_gateway", - "azurerm_network_interface", - "azurerm_network_interface_application_security_group_association", - "azurerm_network_interface_backend_address_pool_association", - "azurerm_network_interface_security_group_association", - "azurerm_network_security_group", - "azurerm_public_ip", - "azurerm_route", - "azurerm_route_table", - "azurerm_subnet", - "azurerm_subnet_route_table_association", - "azurerm_virtual_machine", - "azurerm_virtual_network_gateway_connection", - "azurerm_virtual_network", - "azurerm_virtual_network_gateway", - "google_compute_network", - "google_compute_subnetwork", - "google_compute_vpn_gateway", - "google_compute_vpn_tunnel", - "google_compute_route", - "google_compute_address", - "google_compute_global_address", - "google_compute_router", - "google_compute_interconnect_attachment", - "google_compute_ha_vpn_gateway", - "google_compute_forwarding_rule", - "google_compute_network_firewall_policy", - "google_compute_network_firewall_policy_rule", - "cloudflare_static_route", - "cloudflare_ipsec_tunnel", - ] - - title: str - - -class PostApplyResourcesSectionHiddenItemValueMcnListItemListMcnResourcePreviewItem(BaseModel): - item_type: str - - resource_preview: PostApplyResourcesSectionHiddenItemValueMcnListItemListMcnResourcePreviewItemResourcePreview - - -PostApplyResourcesSectionHiddenItemValueMcnListItemList: TypeAlias = Annotated[ - Union[ - PostApplyResourcesSectionHiddenItemValueMcnListItemListMcnStringItem, - PostApplyResourcesSectionHiddenItemValueMcnListItemListMcnResourcePreviewItem, - ], - PropertyInfo(discriminator="item_type"), -] - - -class PostApplyResourcesSectionHiddenItemValueMcnListItem(BaseModel): - item_type: str - - rule_list: List[PostApplyResourcesSectionHiddenItemValueMcnListItemList] = FieldInfo(alias="list") - - -PostApplyResourcesSectionHiddenItemValue: TypeAlias = Annotated[ - Union[ - PostApplyResourcesSectionHiddenItemValueMcnStringItem, - PostApplyResourcesSectionHiddenItemValueMcnYamlItem, - PostApplyResourcesSectionHiddenItemValueMcnYamlDiffItem, - PostApplyResourcesSectionHiddenItemValueMcnResourcePreviewItem, - PostApplyResourcesSectionHiddenItemValueMcnListItem, - ], - PropertyInfo(discriminator="item_type"), -] - - -class PostApplyResourcesSectionHiddenItem(BaseModel): - help_text: Optional[str] = FieldInfo(alias="helpText", default=None) - - name: Optional[str] = None - - value: Optional[PostApplyResourcesSectionHiddenItemValue] = None - - -class PostApplyResourcesSectionVisibleItemValueMcnStringItem(BaseModel): - item_type: str - - string: str - - -class PostApplyResourcesSectionVisibleItemValueMcnYamlItem(BaseModel): - item_type: str - - yaml: str - - -class PostApplyResourcesSectionVisibleItemValueMcnYamlDiffItemYamlDiff(BaseModel): - diff: str - - left_description: str - - left_yaml: str - - right_description: str - - right_yaml: str - - -class PostApplyResourcesSectionVisibleItemValueMcnYamlDiffItem(BaseModel): - item_type: str - - yaml_diff: PostApplyResourcesSectionVisibleItemValueMcnYamlDiffItemYamlDiff - - -class PostApplyResourcesSectionVisibleItemValueMcnResourcePreviewItemResourcePreview(BaseModel): - id: str - - cloud_type: Literal["AWS", "AZURE", "GOOGLE", "CLOUDFLARE"] - - detail: str - - name: str - - resource_type: Literal[ - "aws_customer_gateway", - "aws_egress_only_internet_gateway", - "aws_internet_gateway", - "aws_instance", - "aws_network_interface", - "aws_route", - "aws_route_table", - "aws_route_table_association", - "aws_subnet", - "aws_vpc", - "aws_vpc_ipv4_cidr_block_association", - "aws_vpn_connection", - "aws_vpn_connection_route", - "aws_vpn_gateway", - "aws_security_group", - "aws_vpc_security_group_ingress_rule", - "aws_vpc_security_group_egress_rule", - "aws_ec2_managed_prefix_list", - "aws_ec2_transit_gateway", - "aws_ec2_transit_gateway_prefix_list_reference", - "aws_ec2_transit_gateway_vpc_attachment", - "azurerm_application_security_group", - "azurerm_lb", - "azurerm_lb_backend_address_pool", - "azurerm_lb_nat_pool", - "azurerm_lb_nat_rule", - "azurerm_lb_rule", - "azurerm_local_network_gateway", - "azurerm_network_interface", - "azurerm_network_interface_application_security_group_association", - "azurerm_network_interface_backend_address_pool_association", - "azurerm_network_interface_security_group_association", - "azurerm_network_security_group", - "azurerm_public_ip", - "azurerm_route", - "azurerm_route_table", - "azurerm_subnet", - "azurerm_subnet_route_table_association", - "azurerm_virtual_machine", - "azurerm_virtual_network_gateway_connection", - "azurerm_virtual_network", - "azurerm_virtual_network_gateway", - "google_compute_network", - "google_compute_subnetwork", - "google_compute_vpn_gateway", - "google_compute_vpn_tunnel", - "google_compute_route", - "google_compute_address", - "google_compute_global_address", - "google_compute_router", - "google_compute_interconnect_attachment", - "google_compute_ha_vpn_gateway", - "google_compute_forwarding_rule", - "google_compute_network_firewall_policy", - "google_compute_network_firewall_policy_rule", - "cloudflare_static_route", - "cloudflare_ipsec_tunnel", - ] - - title: str - - -class PostApplyResourcesSectionVisibleItemValueMcnResourcePreviewItem(BaseModel): - item_type: str - - resource_preview: PostApplyResourcesSectionVisibleItemValueMcnResourcePreviewItemResourcePreview - - -class PostApplyResourcesSectionVisibleItemValueMcnListItemListMcnStringItem(BaseModel): - item_type: str - - string: str - - -class PostApplyResourcesSectionVisibleItemValueMcnListItemListMcnResourcePreviewItemResourcePreview(BaseModel): - id: str - - cloud_type: Literal["AWS", "AZURE", "GOOGLE", "CLOUDFLARE"] - - detail: str - - name: str - - resource_type: Literal[ - "aws_customer_gateway", - "aws_egress_only_internet_gateway", - "aws_internet_gateway", - "aws_instance", - "aws_network_interface", - "aws_route", - "aws_route_table", - "aws_route_table_association", - "aws_subnet", - "aws_vpc", - "aws_vpc_ipv4_cidr_block_association", - "aws_vpn_connection", - "aws_vpn_connection_route", - "aws_vpn_gateway", - "aws_security_group", - "aws_vpc_security_group_ingress_rule", - "aws_vpc_security_group_egress_rule", - "aws_ec2_managed_prefix_list", - "aws_ec2_transit_gateway", - "aws_ec2_transit_gateway_prefix_list_reference", - "aws_ec2_transit_gateway_vpc_attachment", - "azurerm_application_security_group", - "azurerm_lb", - "azurerm_lb_backend_address_pool", - "azurerm_lb_nat_pool", - "azurerm_lb_nat_rule", - "azurerm_lb_rule", - "azurerm_local_network_gateway", - "azurerm_network_interface", - "azurerm_network_interface_application_security_group_association", - "azurerm_network_interface_backend_address_pool_association", - "azurerm_network_interface_security_group_association", - "azurerm_network_security_group", - "azurerm_public_ip", - "azurerm_route", - "azurerm_route_table", - "azurerm_subnet", - "azurerm_subnet_route_table_association", - "azurerm_virtual_machine", - "azurerm_virtual_network_gateway_connection", - "azurerm_virtual_network", - "azurerm_virtual_network_gateway", - "google_compute_network", - "google_compute_subnetwork", - "google_compute_vpn_gateway", - "google_compute_vpn_tunnel", - "google_compute_route", - "google_compute_address", - "google_compute_global_address", - "google_compute_router", - "google_compute_interconnect_attachment", - "google_compute_ha_vpn_gateway", - "google_compute_forwarding_rule", - "google_compute_network_firewall_policy", - "google_compute_network_firewall_policy_rule", - "cloudflare_static_route", - "cloudflare_ipsec_tunnel", - ] - - title: str - - -class PostApplyResourcesSectionVisibleItemValueMcnListItemListMcnResourcePreviewItem(BaseModel): - item_type: str - - resource_preview: PostApplyResourcesSectionVisibleItemValueMcnListItemListMcnResourcePreviewItemResourcePreview - - -PostApplyResourcesSectionVisibleItemValueMcnListItemList: TypeAlias = Annotated[ - Union[ - PostApplyResourcesSectionVisibleItemValueMcnListItemListMcnStringItem, - PostApplyResourcesSectionVisibleItemValueMcnListItemListMcnResourcePreviewItem, - ], - PropertyInfo(discriminator="item_type"), -] - - -class PostApplyResourcesSectionVisibleItemValueMcnListItem(BaseModel): - item_type: str - - rule_list: List[PostApplyResourcesSectionVisibleItemValueMcnListItemList] = FieldInfo(alias="list") - - -PostApplyResourcesSectionVisibleItemValue: TypeAlias = Annotated[ - Union[ - PostApplyResourcesSectionVisibleItemValueMcnStringItem, - PostApplyResourcesSectionVisibleItemValueMcnYamlItem, - PostApplyResourcesSectionVisibleItemValueMcnYamlDiffItem, - PostApplyResourcesSectionVisibleItemValueMcnResourcePreviewItem, - PostApplyResourcesSectionVisibleItemValueMcnListItem, - ], - PropertyInfo(discriminator="item_type"), -] - - -class PostApplyResourcesSectionVisibleItem(BaseModel): - help_text: Optional[str] = FieldInfo(alias="helpText", default=None) - - name: Optional[str] = None - - value: Optional[PostApplyResourcesSectionVisibleItemValue] = None - - -class PostApplyResourcesSection(BaseModel): - hidden_items: List[PostApplyResourcesSectionHiddenItem] - - name: str - - visible_items: List[PostApplyResourcesSectionVisibleItem] - - help_text: Optional[str] = None - - -class PostApplyResourcesManagedBy(BaseModel): - id: str - - client_type: Literal["MAGIC_WAN_CLOUD_ONRAMP"] - - name: str - - -class PostApplyResources(BaseModel): - id: str - - account_id: str - - cloud_type: Literal["AWS", "AZURE", "GOOGLE", "CLOUDFLARE"] - - config: Dict[str, object] - - deployment_provider: str - - managed: bool - - monthly_cost_estimate: PostApplyResourcesMonthlyCostEstimate - - name: str - - native_id: str - - observations: Dict[str, PostApplyResourcesObservations] - - provider_ids: List[str] - - provider_names_by_id: Dict[str, str] - - region: str - - resource_group: str - - resource_type: Literal[ - "aws_customer_gateway", - "aws_egress_only_internet_gateway", - "aws_internet_gateway", - "aws_instance", - "aws_network_interface", - "aws_route", - "aws_route_table", - "aws_route_table_association", - "aws_subnet", - "aws_vpc", - "aws_vpc_ipv4_cidr_block_association", - "aws_vpn_connection", - "aws_vpn_connection_route", - "aws_vpn_gateway", - "aws_security_group", - "aws_vpc_security_group_ingress_rule", - "aws_vpc_security_group_egress_rule", - "aws_ec2_managed_prefix_list", - "aws_ec2_transit_gateway", - "aws_ec2_transit_gateway_prefix_list_reference", - "aws_ec2_transit_gateway_vpc_attachment", - "azurerm_application_security_group", - "azurerm_lb", - "azurerm_lb_backend_address_pool", - "azurerm_lb_nat_pool", - "azurerm_lb_nat_rule", - "azurerm_lb_rule", - "azurerm_local_network_gateway", - "azurerm_network_interface", - "azurerm_network_interface_application_security_group_association", - "azurerm_network_interface_backend_address_pool_association", - "azurerm_network_interface_security_group_association", - "azurerm_network_security_group", - "azurerm_public_ip", - "azurerm_route", - "azurerm_route_table", - "azurerm_subnet", - "azurerm_subnet_route_table_association", - "azurerm_virtual_machine", - "azurerm_virtual_network_gateway_connection", - "azurerm_virtual_network", - "azurerm_virtual_network_gateway", - "google_compute_network", - "google_compute_subnetwork", - "google_compute_vpn_gateway", - "google_compute_vpn_tunnel", - "google_compute_route", - "google_compute_address", - "google_compute_global_address", - "google_compute_router", - "google_compute_interconnect_attachment", - "google_compute_ha_vpn_gateway", - "google_compute_forwarding_rule", - "google_compute_network_firewall_policy", - "google_compute_network_firewall_policy_rule", - "cloudflare_static_route", - "cloudflare_ipsec_tunnel", - ] - - sections: List[PostApplyResourcesSection] - - state: Dict[str, object] - - tags: Dict[str, str] - - updated_at: str - - url: str - - managed_by: Optional[List[PostApplyResourcesManagedBy]] = None - - -class StatusApplyProgress(BaseModel): - done: int - - total: int - - -class StatusPlanProgress(BaseModel): - done: int - - total: int - - -class StatusLifecycleErrorsMeta(BaseModel): - l10n_key: Optional[str] = None - - loggable_error: Optional[str] = None - - template_data: Optional[object] = None - - trace_id: Optional[str] = None - - -class StatusLifecycleErrorsSource(BaseModel): - parameter: Optional[str] = None - - parameter_value_index: Optional[int] = None - - pointer: Optional[str] = None - - -class StatusLifecycleErrors(BaseModel): - code: Literal[ - 1001, - 1002, - 1003, - 1004, - 1005, - 1006, - 1007, - 1008, - 1009, - 1010, - 1011, - 1012, - 1013, - 1014, - 1015, - 1016, - 1017, - 1018, - 2001, - 2002, - 2003, - 2004, - 2005, - 2006, - 2007, - 2008, - 2009, - 2010, - 2011, - 2012, - 2013, - 2014, - 2015, - 2016, - 2017, - 2018, - 2019, - 2020, - 2021, - 2022, - 3001, - 3002, - 3003, - 3004, - 3005, - 3006, - 3007, - 4001, - 4002, - 4003, - 4004, - 4005, - 4006, - 4007, - 4008, - 4009, - 4010, - 4011, - 4012, - 4013, - 4014, - 4015, - 4016, - 4017, - 4018, - 4019, - 4020, - 4021, - 4022, - 4023, - 5001, - 5002, - 5003, - 5004, - 102000, - 102001, - 102002, - 102003, - 102004, - 102005, - 102006, - 102007, - 102008, - 102009, - 102010, - 102011, - 102012, - 102013, - 102014, - 102015, - 102016, - 102017, - 102018, - 102019, - 102020, - 102021, - 102022, - 102023, - 102024, - 102025, - 102026, - 102027, - 102028, - 102029, - 102030, - 102031, - 102032, - 102033, - 102034, - 102035, - 102036, - 102037, - 102038, - 102039, - 102040, - 102041, - 102042, - 102043, - 102044, - 102045, - 102046, - 102047, - 102048, - 102049, - 102050, - 102051, - 102052, - 102053, - 102054, - 102055, - 102056, - 102057, - 102058, - 102059, - 102060, - 102061, - 102062, - 102063, - 102064, - 102065, - 102066, - 102067, - 102068, - 102069, - 102070, - 102071, - 102072, - 103001, - 103002, - 103003, - 103004, - 103005, - 103006, - 103007, - 103008, - ] - - message: str - - documentation_url: Optional[str] = None - - meta: Optional[StatusLifecycleErrorsMeta] = None - - source: Optional[StatusLifecycleErrorsSource] = None - - -class Status(BaseModel): - apply_progress: StatusApplyProgress - - lifecycle_state: Literal[ - "OnrampNeedsApply", - "OnrampPendingPlan", - "OnrampPlanning", - "OnrampPlanFailed", - "OnrampPendingApproval", - "OnrampPendingApply", - "OnrampApplying", - "OnrampApplyFailed", - "OnrampActive", - "OnrampPendingDestroy", - "OnrampDestroying", - "OnrampDestroyFailed", - ] - - plan_progress: StatusPlanProgress - - routes: List[str] - - tunnels: List[str] - - lifecycle_errors: Optional[Dict[str, StatusLifecycleErrors]] = None - - -class VPCsByIDMonthlyCostEstimate(BaseModel): - currency: str - - monthly_cost: float - - -class VPCsByIDObservations(BaseModel): - first_observed_at: str - - last_observed_at: str - - provider_id: str - - resource_id: str - - -class VPCsByIDSectionHiddenItemValueMcnStringItem(BaseModel): - item_type: str - - string: str - - -class VPCsByIDSectionHiddenItemValueMcnYamlItem(BaseModel): - item_type: str - - yaml: str - - -class VPCsByIDSectionHiddenItemValueMcnYamlDiffItemYamlDiff(BaseModel): - diff: str - - left_description: str - - left_yaml: str - - right_description: str - - right_yaml: str - - -class VPCsByIDSectionHiddenItemValueMcnYamlDiffItem(BaseModel): - item_type: str - - yaml_diff: VPCsByIDSectionHiddenItemValueMcnYamlDiffItemYamlDiff - - -class VPCsByIDSectionHiddenItemValueMcnResourcePreviewItemResourcePreview(BaseModel): - id: str - - cloud_type: Literal["AWS", "AZURE", "GOOGLE", "CLOUDFLARE"] - - detail: str - - name: str - - resource_type: Literal[ - "aws_customer_gateway", - "aws_egress_only_internet_gateway", - "aws_internet_gateway", - "aws_instance", - "aws_network_interface", - "aws_route", - "aws_route_table", - "aws_route_table_association", - "aws_subnet", - "aws_vpc", - "aws_vpc_ipv4_cidr_block_association", - "aws_vpn_connection", - "aws_vpn_connection_route", - "aws_vpn_gateway", - "aws_security_group", - "aws_vpc_security_group_ingress_rule", - "aws_vpc_security_group_egress_rule", - "aws_ec2_managed_prefix_list", - "aws_ec2_transit_gateway", - "aws_ec2_transit_gateway_prefix_list_reference", - "aws_ec2_transit_gateway_vpc_attachment", - "azurerm_application_security_group", - "azurerm_lb", - "azurerm_lb_backend_address_pool", - "azurerm_lb_nat_pool", - "azurerm_lb_nat_rule", - "azurerm_lb_rule", - "azurerm_local_network_gateway", - "azurerm_network_interface", - "azurerm_network_interface_application_security_group_association", - "azurerm_network_interface_backend_address_pool_association", - "azurerm_network_interface_security_group_association", - "azurerm_network_security_group", - "azurerm_public_ip", - "azurerm_route", - "azurerm_route_table", - "azurerm_subnet", - "azurerm_subnet_route_table_association", - "azurerm_virtual_machine", - "azurerm_virtual_network_gateway_connection", - "azurerm_virtual_network", - "azurerm_virtual_network_gateway", - "google_compute_network", - "google_compute_subnetwork", - "google_compute_vpn_gateway", - "google_compute_vpn_tunnel", - "google_compute_route", - "google_compute_address", - "google_compute_global_address", - "google_compute_router", - "google_compute_interconnect_attachment", - "google_compute_ha_vpn_gateway", - "google_compute_forwarding_rule", - "google_compute_network_firewall_policy", - "google_compute_network_firewall_policy_rule", - "cloudflare_static_route", - "cloudflare_ipsec_tunnel", - ] - - title: str - - -class VPCsByIDSectionHiddenItemValueMcnResourcePreviewItem(BaseModel): - item_type: str - - resource_preview: VPCsByIDSectionHiddenItemValueMcnResourcePreviewItemResourcePreview - - -class VPCsByIDSectionHiddenItemValueMcnListItemListMcnStringItem(BaseModel): - item_type: str - - string: str - - -class VPCsByIDSectionHiddenItemValueMcnListItemListMcnResourcePreviewItemResourcePreview(BaseModel): - id: str - - cloud_type: Literal["AWS", "AZURE", "GOOGLE", "CLOUDFLARE"] - - detail: str - - name: str - - resource_type: Literal[ - "aws_customer_gateway", - "aws_egress_only_internet_gateway", - "aws_internet_gateway", - "aws_instance", - "aws_network_interface", - "aws_route", - "aws_route_table", - "aws_route_table_association", - "aws_subnet", - "aws_vpc", - "aws_vpc_ipv4_cidr_block_association", - "aws_vpn_connection", - "aws_vpn_connection_route", - "aws_vpn_gateway", - "aws_security_group", - "aws_vpc_security_group_ingress_rule", - "aws_vpc_security_group_egress_rule", - "aws_ec2_managed_prefix_list", - "aws_ec2_transit_gateway", - "aws_ec2_transit_gateway_prefix_list_reference", - "aws_ec2_transit_gateway_vpc_attachment", - "azurerm_application_security_group", - "azurerm_lb", - "azurerm_lb_backend_address_pool", - "azurerm_lb_nat_pool", - "azurerm_lb_nat_rule", - "azurerm_lb_rule", - "azurerm_local_network_gateway", - "azurerm_network_interface", - "azurerm_network_interface_application_security_group_association", - "azurerm_network_interface_backend_address_pool_association", - "azurerm_network_interface_security_group_association", - "azurerm_network_security_group", - "azurerm_public_ip", - "azurerm_route", - "azurerm_route_table", - "azurerm_subnet", - "azurerm_subnet_route_table_association", - "azurerm_virtual_machine", - "azurerm_virtual_network_gateway_connection", - "azurerm_virtual_network", - "azurerm_virtual_network_gateway", - "google_compute_network", - "google_compute_subnetwork", - "google_compute_vpn_gateway", - "google_compute_vpn_tunnel", - "google_compute_route", - "google_compute_address", - "google_compute_global_address", - "google_compute_router", - "google_compute_interconnect_attachment", - "google_compute_ha_vpn_gateway", - "google_compute_forwarding_rule", - "google_compute_network_firewall_policy", - "google_compute_network_firewall_policy_rule", - "cloudflare_static_route", - "cloudflare_ipsec_tunnel", - ] - - title: str - - -class VPCsByIDSectionHiddenItemValueMcnListItemListMcnResourcePreviewItem(BaseModel): - item_type: str - - resource_preview: VPCsByIDSectionHiddenItemValueMcnListItemListMcnResourcePreviewItemResourcePreview - - -VPCsByIDSectionHiddenItemValueMcnListItemList: TypeAlias = Annotated[ - Union[ - VPCsByIDSectionHiddenItemValueMcnListItemListMcnStringItem, - VPCsByIDSectionHiddenItemValueMcnListItemListMcnResourcePreviewItem, - ], - PropertyInfo(discriminator="item_type"), -] - - -class VPCsByIDSectionHiddenItemValueMcnListItem(BaseModel): - item_type: str - - rule_list: List[VPCsByIDSectionHiddenItemValueMcnListItemList] = FieldInfo(alias="list") - - -VPCsByIDSectionHiddenItemValue: TypeAlias = Annotated[ - Union[ - VPCsByIDSectionHiddenItemValueMcnStringItem, - VPCsByIDSectionHiddenItemValueMcnYamlItem, - VPCsByIDSectionHiddenItemValueMcnYamlDiffItem, - VPCsByIDSectionHiddenItemValueMcnResourcePreviewItem, - VPCsByIDSectionHiddenItemValueMcnListItem, - ], - PropertyInfo(discriminator="item_type"), -] - - -class VPCsByIDSectionHiddenItem(BaseModel): - help_text: Optional[str] = FieldInfo(alias="helpText", default=None) - - name: Optional[str] = None - - value: Optional[VPCsByIDSectionHiddenItemValue] = None - - -class VPCsByIDSectionVisibleItemValueMcnStringItem(BaseModel): - item_type: str - - string: str - - -class VPCsByIDSectionVisibleItemValueMcnYamlItem(BaseModel): - item_type: str - - yaml: str - - -class VPCsByIDSectionVisibleItemValueMcnYamlDiffItemYamlDiff(BaseModel): - diff: str - - left_description: str - - left_yaml: str - - right_description: str - - right_yaml: str - - -class VPCsByIDSectionVisibleItemValueMcnYamlDiffItem(BaseModel): - item_type: str - - yaml_diff: VPCsByIDSectionVisibleItemValueMcnYamlDiffItemYamlDiff - - -class VPCsByIDSectionVisibleItemValueMcnResourcePreviewItemResourcePreview(BaseModel): - id: str - - cloud_type: Literal["AWS", "AZURE", "GOOGLE", "CLOUDFLARE"] - - detail: str - - name: str - - resource_type: Literal[ - "aws_customer_gateway", - "aws_egress_only_internet_gateway", - "aws_internet_gateway", - "aws_instance", - "aws_network_interface", - "aws_route", - "aws_route_table", - "aws_route_table_association", - "aws_subnet", - "aws_vpc", - "aws_vpc_ipv4_cidr_block_association", - "aws_vpn_connection", - "aws_vpn_connection_route", - "aws_vpn_gateway", - "aws_security_group", - "aws_vpc_security_group_ingress_rule", - "aws_vpc_security_group_egress_rule", - "aws_ec2_managed_prefix_list", - "aws_ec2_transit_gateway", - "aws_ec2_transit_gateway_prefix_list_reference", - "aws_ec2_transit_gateway_vpc_attachment", - "azurerm_application_security_group", - "azurerm_lb", - "azurerm_lb_backend_address_pool", - "azurerm_lb_nat_pool", - "azurerm_lb_nat_rule", - "azurerm_lb_rule", - "azurerm_local_network_gateway", - "azurerm_network_interface", - "azurerm_network_interface_application_security_group_association", - "azurerm_network_interface_backend_address_pool_association", - "azurerm_network_interface_security_group_association", - "azurerm_network_security_group", - "azurerm_public_ip", - "azurerm_route", - "azurerm_route_table", - "azurerm_subnet", - "azurerm_subnet_route_table_association", - "azurerm_virtual_machine", - "azurerm_virtual_network_gateway_connection", - "azurerm_virtual_network", - "azurerm_virtual_network_gateway", - "google_compute_network", - "google_compute_subnetwork", - "google_compute_vpn_gateway", - "google_compute_vpn_tunnel", - "google_compute_route", - "google_compute_address", - "google_compute_global_address", - "google_compute_router", - "google_compute_interconnect_attachment", - "google_compute_ha_vpn_gateway", - "google_compute_forwarding_rule", - "google_compute_network_firewall_policy", - "google_compute_network_firewall_policy_rule", - "cloudflare_static_route", - "cloudflare_ipsec_tunnel", - ] - - title: str - - -class VPCsByIDSectionVisibleItemValueMcnResourcePreviewItem(BaseModel): - item_type: str - - resource_preview: VPCsByIDSectionVisibleItemValueMcnResourcePreviewItemResourcePreview - - -class VPCsByIDSectionVisibleItemValueMcnListItemListMcnStringItem(BaseModel): - item_type: str - - string: str - - -class VPCsByIDSectionVisibleItemValueMcnListItemListMcnResourcePreviewItemResourcePreview(BaseModel): - id: str - - cloud_type: Literal["AWS", "AZURE", "GOOGLE", "CLOUDFLARE"] - - detail: str - - name: str - - resource_type: Literal[ - "aws_customer_gateway", - "aws_egress_only_internet_gateway", - "aws_internet_gateway", - "aws_instance", - "aws_network_interface", - "aws_route", - "aws_route_table", - "aws_route_table_association", - "aws_subnet", - "aws_vpc", - "aws_vpc_ipv4_cidr_block_association", - "aws_vpn_connection", - "aws_vpn_connection_route", - "aws_vpn_gateway", - "aws_security_group", - "aws_vpc_security_group_ingress_rule", - "aws_vpc_security_group_egress_rule", - "aws_ec2_managed_prefix_list", - "aws_ec2_transit_gateway", - "aws_ec2_transit_gateway_prefix_list_reference", - "aws_ec2_transit_gateway_vpc_attachment", - "azurerm_application_security_group", - "azurerm_lb", - "azurerm_lb_backend_address_pool", - "azurerm_lb_nat_pool", - "azurerm_lb_nat_rule", - "azurerm_lb_rule", - "azurerm_local_network_gateway", - "azurerm_network_interface", - "azurerm_network_interface_application_security_group_association", - "azurerm_network_interface_backend_address_pool_association", - "azurerm_network_interface_security_group_association", - "azurerm_network_security_group", - "azurerm_public_ip", - "azurerm_route", - "azurerm_route_table", - "azurerm_subnet", - "azurerm_subnet_route_table_association", - "azurerm_virtual_machine", - "azurerm_virtual_network_gateway_connection", - "azurerm_virtual_network", - "azurerm_virtual_network_gateway", - "google_compute_network", - "google_compute_subnetwork", - "google_compute_vpn_gateway", - "google_compute_vpn_tunnel", - "google_compute_route", - "google_compute_address", - "google_compute_global_address", - "google_compute_router", - "google_compute_interconnect_attachment", - "google_compute_ha_vpn_gateway", - "google_compute_forwarding_rule", - "google_compute_network_firewall_policy", - "google_compute_network_firewall_policy_rule", - "cloudflare_static_route", - "cloudflare_ipsec_tunnel", - ] - - title: str - - -class VPCsByIDSectionVisibleItemValueMcnListItemListMcnResourcePreviewItem(BaseModel): - item_type: str - - resource_preview: VPCsByIDSectionVisibleItemValueMcnListItemListMcnResourcePreviewItemResourcePreview - - -VPCsByIDSectionVisibleItemValueMcnListItemList: TypeAlias = Annotated[ - Union[ - VPCsByIDSectionVisibleItemValueMcnListItemListMcnStringItem, - VPCsByIDSectionVisibleItemValueMcnListItemListMcnResourcePreviewItem, - ], - PropertyInfo(discriminator="item_type"), -] - - -class VPCsByIDSectionVisibleItemValueMcnListItem(BaseModel): - item_type: str - - rule_list: List[VPCsByIDSectionVisibleItemValueMcnListItemList] = FieldInfo(alias="list") - - -VPCsByIDSectionVisibleItemValue: TypeAlias = Annotated[ - Union[ - VPCsByIDSectionVisibleItemValueMcnStringItem, - VPCsByIDSectionVisibleItemValueMcnYamlItem, - VPCsByIDSectionVisibleItemValueMcnYamlDiffItem, - VPCsByIDSectionVisibleItemValueMcnResourcePreviewItem, - VPCsByIDSectionVisibleItemValueMcnListItem, - ], - PropertyInfo(discriminator="item_type"), -] - - -class VPCsByIDSectionVisibleItem(BaseModel): - help_text: Optional[str] = FieldInfo(alias="helpText", default=None) - - name: Optional[str] = None - - value: Optional[VPCsByIDSectionVisibleItemValue] = None - - -class VPCsByIDSection(BaseModel): - hidden_items: List[VPCsByIDSectionHiddenItem] - - name: str - - visible_items: List[VPCsByIDSectionVisibleItem] - - help_text: Optional[str] = None - - -class VPCsByIDManagedBy(BaseModel): - id: str - - client_type: Literal["MAGIC_WAN_CLOUD_ONRAMP"] - - name: str - - -class VPCsByID(BaseModel): - id: str - - account_id: str - - cloud_type: Literal["AWS", "AZURE", "GOOGLE", "CLOUDFLARE"] - - config: Dict[str, object] - - deployment_provider: str - - managed: bool - - monthly_cost_estimate: VPCsByIDMonthlyCostEstimate - - name: str - - native_id: str - - observations: Dict[str, VPCsByIDObservations] - - provider_ids: List[str] - - provider_names_by_id: Dict[str, str] - - region: str - - resource_group: str - - resource_type: Literal[ - "aws_customer_gateway", - "aws_egress_only_internet_gateway", - "aws_internet_gateway", - "aws_instance", - "aws_network_interface", - "aws_route", - "aws_route_table", - "aws_route_table_association", - "aws_subnet", - "aws_vpc", - "aws_vpc_ipv4_cidr_block_association", - "aws_vpn_connection", - "aws_vpn_connection_route", - "aws_vpn_gateway", - "aws_security_group", - "aws_vpc_security_group_ingress_rule", - "aws_vpc_security_group_egress_rule", - "aws_ec2_managed_prefix_list", - "aws_ec2_transit_gateway", - "aws_ec2_transit_gateway_prefix_list_reference", - "aws_ec2_transit_gateway_vpc_attachment", - "azurerm_application_security_group", - "azurerm_lb", - "azurerm_lb_backend_address_pool", - "azurerm_lb_nat_pool", - "azurerm_lb_nat_rule", - "azurerm_lb_rule", - "azurerm_local_network_gateway", - "azurerm_network_interface", - "azurerm_network_interface_application_security_group_association", - "azurerm_network_interface_backend_address_pool_association", - "azurerm_network_interface_security_group_association", - "azurerm_network_security_group", - "azurerm_public_ip", - "azurerm_route", - "azurerm_route_table", - "azurerm_subnet", - "azurerm_subnet_route_table_association", - "azurerm_virtual_machine", - "azurerm_virtual_network_gateway_connection", - "azurerm_virtual_network", - "azurerm_virtual_network_gateway", - "google_compute_network", - "google_compute_subnetwork", - "google_compute_vpn_gateway", - "google_compute_vpn_tunnel", - "google_compute_route", - "google_compute_address", - "google_compute_global_address", - "google_compute_router", - "google_compute_interconnect_attachment", - "google_compute_ha_vpn_gateway", - "google_compute_forwarding_rule", - "google_compute_network_firewall_policy", - "google_compute_network_firewall_policy_rule", - "cloudflare_static_route", - "cloudflare_ipsec_tunnel", - ] - - sections: List[VPCsByIDSection] - - state: Dict[str, object] - - tags: Dict[str, str] - - updated_at: str - - url: str - - managed_by: Optional[List[VPCsByIDManagedBy]] = None - - -class OnRampGetResponse(BaseModel): - id: str - - cloud_type: Literal["AWS", "AZURE", "GOOGLE"] - - dynamic_routing: bool - - install_routes_in_cloud: bool - - install_routes_in_magic_wan: bool - - name: str - - type: Literal["OnrampTypeSingle", "OnrampTypeHub"] - - updated_at: str - - attached_hubs: Optional[List[str]] = None - - attached_vpcs: Optional[List[str]] = None - - cloud_asn: Optional[int] = None - - description: Optional[str] = None - - hub: Optional[str] = None - - last_applied_at: Optional[str] = None - - last_exported_at: Optional[str] = None - - last_planned_at: Optional[str] = None - - manage_hub_to_hub_attachments: Optional[bool] = None - - manage_vpc_to_hub_attachments: Optional[bool] = None - - planned_monthly_cost_estimate: Optional[PlannedMonthlyCostEstimate] = None - - planned_resources: Optional[List[PlannedResource]] = None - - planned_resources_unavailable: Optional[bool] = None - - post_apply_monthly_cost_estimate: Optional[PostApplyMonthlyCostEstimate] = None - - post_apply_resources: Optional[Dict[str, PostApplyResources]] = None - - post_apply_resources_unavailable: Optional[bool] = None - - region: Optional[str] = None - - status: Optional[Status] = None - - vpc: Optional[str] = None - - vpcs_by_id: Optional[Dict[str, VPCsByID]] = None - - vpcs_by_id_unavailable: Optional[List[str]] = None - """The list of vpc IDs for which resource details failed to generate.""" diff --git a/src/cloudflare/types/magic_cloud_networking/on_ramp_list_params.py b/src/cloudflare/types/magic_cloud_networking/on_ramp_list_params.py deleted file mode 100644 index b7c660ad5c4..00000000000 --- a/src/cloudflare/types/magic_cloud_networking/on_ramp_list_params.py +++ /dev/null @@ -1,20 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing_extensions import Required, TypedDict - -__all__ = ["OnRampListParams"] - - -class OnRampListParams(TypedDict, total=False): - account_id: Required[str] - - desc: bool - - order_by: str - """One of ["updated_at", "id", "cloud_type", "name"].""" - - status: bool - - vpcs: bool diff --git a/src/cloudflare/types/magic_cloud_networking/on_ramp_list_response.py b/src/cloudflare/types/magic_cloud_networking/on_ramp_list_response.py deleted file mode 100644 index 6135947f34a..00000000000 --- a/src/cloudflare/types/magic_cloud_networking/on_ramp_list_response.py +++ /dev/null @@ -1,1675 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from typing import Dict, List, Union, Optional -from typing_extensions import Literal, Annotated, TypeAlias - -from pydantic import Field as FieldInfo - -from ..._utils import PropertyInfo -from ..._models import BaseModel - -__all__ = [ - "OnRampListResponse", - "PlannedMonthlyCostEstimate", - "PlannedResource", - "PlannedResourceDiff", - "PlannedResourceMonthlyCostEstimateDiff", - "PlannedResourceResource", - "PostApplyMonthlyCostEstimate", - "PostApplyResources", - "PostApplyResourcesMonthlyCostEstimate", - "PostApplyResourcesObservations", - "PostApplyResourcesSection", - "PostApplyResourcesSectionHiddenItem", - "PostApplyResourcesSectionHiddenItemValue", - "PostApplyResourcesSectionHiddenItemValueMcnStringItem", - "PostApplyResourcesSectionHiddenItemValueMcnYamlItem", - "PostApplyResourcesSectionHiddenItemValueMcnYamlDiffItem", - "PostApplyResourcesSectionHiddenItemValueMcnYamlDiffItemYamlDiff", - "PostApplyResourcesSectionHiddenItemValueMcnResourcePreviewItem", - "PostApplyResourcesSectionHiddenItemValueMcnResourcePreviewItemResourcePreview", - "PostApplyResourcesSectionHiddenItemValueMcnListItem", - "PostApplyResourcesSectionHiddenItemValueMcnListItemList", - "PostApplyResourcesSectionHiddenItemValueMcnListItemListMcnStringItem", - "PostApplyResourcesSectionHiddenItemValueMcnListItemListMcnResourcePreviewItem", - "PostApplyResourcesSectionHiddenItemValueMcnListItemListMcnResourcePreviewItemResourcePreview", - "PostApplyResourcesSectionVisibleItem", - "PostApplyResourcesSectionVisibleItemValue", - "PostApplyResourcesSectionVisibleItemValueMcnStringItem", - "PostApplyResourcesSectionVisibleItemValueMcnYamlItem", - "PostApplyResourcesSectionVisibleItemValueMcnYamlDiffItem", - "PostApplyResourcesSectionVisibleItemValueMcnYamlDiffItemYamlDiff", - "PostApplyResourcesSectionVisibleItemValueMcnResourcePreviewItem", - "PostApplyResourcesSectionVisibleItemValueMcnResourcePreviewItemResourcePreview", - "PostApplyResourcesSectionVisibleItemValueMcnListItem", - "PostApplyResourcesSectionVisibleItemValueMcnListItemList", - "PostApplyResourcesSectionVisibleItemValueMcnListItemListMcnStringItem", - "PostApplyResourcesSectionVisibleItemValueMcnListItemListMcnResourcePreviewItem", - "PostApplyResourcesSectionVisibleItemValueMcnListItemListMcnResourcePreviewItemResourcePreview", - "PostApplyResourcesManagedBy", - "Status", - "StatusApplyProgress", - "StatusPlanProgress", - "StatusLifecycleErrors", - "StatusLifecycleErrorsMeta", - "StatusLifecycleErrorsSource", - "VPCsByID", - "VPCsByIDMonthlyCostEstimate", - "VPCsByIDObservations", - "VPCsByIDSection", - "VPCsByIDSectionHiddenItem", - "VPCsByIDSectionHiddenItemValue", - "VPCsByIDSectionHiddenItemValueMcnStringItem", - "VPCsByIDSectionHiddenItemValueMcnYamlItem", - "VPCsByIDSectionHiddenItemValueMcnYamlDiffItem", - "VPCsByIDSectionHiddenItemValueMcnYamlDiffItemYamlDiff", - "VPCsByIDSectionHiddenItemValueMcnResourcePreviewItem", - "VPCsByIDSectionHiddenItemValueMcnResourcePreviewItemResourcePreview", - "VPCsByIDSectionHiddenItemValueMcnListItem", - "VPCsByIDSectionHiddenItemValueMcnListItemList", - "VPCsByIDSectionHiddenItemValueMcnListItemListMcnStringItem", - "VPCsByIDSectionHiddenItemValueMcnListItemListMcnResourcePreviewItem", - "VPCsByIDSectionHiddenItemValueMcnListItemListMcnResourcePreviewItemResourcePreview", - "VPCsByIDSectionVisibleItem", - "VPCsByIDSectionVisibleItemValue", - "VPCsByIDSectionVisibleItemValueMcnStringItem", - "VPCsByIDSectionVisibleItemValueMcnYamlItem", - "VPCsByIDSectionVisibleItemValueMcnYamlDiffItem", - "VPCsByIDSectionVisibleItemValueMcnYamlDiffItemYamlDiff", - "VPCsByIDSectionVisibleItemValueMcnResourcePreviewItem", - "VPCsByIDSectionVisibleItemValueMcnResourcePreviewItemResourcePreview", - "VPCsByIDSectionVisibleItemValueMcnListItem", - "VPCsByIDSectionVisibleItemValueMcnListItemList", - "VPCsByIDSectionVisibleItemValueMcnListItemListMcnStringItem", - "VPCsByIDSectionVisibleItemValueMcnListItemListMcnResourcePreviewItem", - "VPCsByIDSectionVisibleItemValueMcnListItemListMcnResourcePreviewItemResourcePreview", - "VPCsByIDManagedBy", -] - - -class PlannedMonthlyCostEstimate(BaseModel): - currency: str - - current_monthly_cost: float - - diff: float - - proposed_monthly_cost: float - - -class PlannedResourceDiff(BaseModel): - diff: str - - left_description: str - - left_yaml: str - - right_description: str - - right_yaml: str - - -class PlannedResourceMonthlyCostEstimateDiff(BaseModel): - currency: str - - current_monthly_cost: float - - diff: float - - proposed_monthly_cost: float - - -class PlannedResourceResource(BaseModel): - id: str - - cloud_type: Literal["AWS", "AZURE", "GOOGLE", "CLOUDFLARE"] - - detail: str - - name: str - - resource_type: Literal[ - "aws_customer_gateway", - "aws_egress_only_internet_gateway", - "aws_internet_gateway", - "aws_instance", - "aws_network_interface", - "aws_route", - "aws_route_table", - "aws_route_table_association", - "aws_subnet", - "aws_vpc", - "aws_vpc_ipv4_cidr_block_association", - "aws_vpn_connection", - "aws_vpn_connection_route", - "aws_vpn_gateway", - "aws_security_group", - "aws_vpc_security_group_ingress_rule", - "aws_vpc_security_group_egress_rule", - "aws_ec2_managed_prefix_list", - "aws_ec2_transit_gateway", - "aws_ec2_transit_gateway_prefix_list_reference", - "aws_ec2_transit_gateway_vpc_attachment", - "azurerm_application_security_group", - "azurerm_lb", - "azurerm_lb_backend_address_pool", - "azurerm_lb_nat_pool", - "azurerm_lb_nat_rule", - "azurerm_lb_rule", - "azurerm_local_network_gateway", - "azurerm_network_interface", - "azurerm_network_interface_application_security_group_association", - "azurerm_network_interface_backend_address_pool_association", - "azurerm_network_interface_security_group_association", - "azurerm_network_security_group", - "azurerm_public_ip", - "azurerm_route", - "azurerm_route_table", - "azurerm_subnet", - "azurerm_subnet_route_table_association", - "azurerm_virtual_machine", - "azurerm_virtual_network_gateway_connection", - "azurerm_virtual_network", - "azurerm_virtual_network_gateway", - "google_compute_network", - "google_compute_subnetwork", - "google_compute_vpn_gateway", - "google_compute_vpn_tunnel", - "google_compute_route", - "google_compute_address", - "google_compute_global_address", - "google_compute_router", - "google_compute_interconnect_attachment", - "google_compute_ha_vpn_gateway", - "google_compute_forwarding_rule", - "google_compute_network_firewall_policy", - "google_compute_network_firewall_policy_rule", - "cloudflare_static_route", - "cloudflare_ipsec_tunnel", - ] - - title: str - - -class PlannedResource(BaseModel): - diff: PlannedResourceDiff - - keys_require_replace: List[str] - - monthly_cost_estimate_diff: PlannedResourceMonthlyCostEstimateDiff - - planned_action: Literal["no_op", "create", "update", "replace", "destroy"] - - resource: PlannedResourceResource - - -class PostApplyMonthlyCostEstimate(BaseModel): - currency: str - - monthly_cost: float - - -class PostApplyResourcesMonthlyCostEstimate(BaseModel): - currency: str - - monthly_cost: float - - -class PostApplyResourcesObservations(BaseModel): - first_observed_at: str - - last_observed_at: str - - provider_id: str - - resource_id: str - - -class PostApplyResourcesSectionHiddenItemValueMcnStringItem(BaseModel): - item_type: str - - string: str - - -class PostApplyResourcesSectionHiddenItemValueMcnYamlItem(BaseModel): - item_type: str - - yaml: str - - -class PostApplyResourcesSectionHiddenItemValueMcnYamlDiffItemYamlDiff(BaseModel): - diff: str - - left_description: str - - left_yaml: str - - right_description: str - - right_yaml: str - - -class PostApplyResourcesSectionHiddenItemValueMcnYamlDiffItem(BaseModel): - item_type: str - - yaml_diff: PostApplyResourcesSectionHiddenItemValueMcnYamlDiffItemYamlDiff - - -class PostApplyResourcesSectionHiddenItemValueMcnResourcePreviewItemResourcePreview(BaseModel): - id: str - - cloud_type: Literal["AWS", "AZURE", "GOOGLE", "CLOUDFLARE"] - - detail: str - - name: str - - resource_type: Literal[ - "aws_customer_gateway", - "aws_egress_only_internet_gateway", - "aws_internet_gateway", - "aws_instance", - "aws_network_interface", - "aws_route", - "aws_route_table", - "aws_route_table_association", - "aws_subnet", - "aws_vpc", - "aws_vpc_ipv4_cidr_block_association", - "aws_vpn_connection", - "aws_vpn_connection_route", - "aws_vpn_gateway", - "aws_security_group", - "aws_vpc_security_group_ingress_rule", - "aws_vpc_security_group_egress_rule", - "aws_ec2_managed_prefix_list", - "aws_ec2_transit_gateway", - "aws_ec2_transit_gateway_prefix_list_reference", - "aws_ec2_transit_gateway_vpc_attachment", - "azurerm_application_security_group", - "azurerm_lb", - "azurerm_lb_backend_address_pool", - "azurerm_lb_nat_pool", - "azurerm_lb_nat_rule", - "azurerm_lb_rule", - "azurerm_local_network_gateway", - "azurerm_network_interface", - "azurerm_network_interface_application_security_group_association", - "azurerm_network_interface_backend_address_pool_association", - "azurerm_network_interface_security_group_association", - "azurerm_network_security_group", - "azurerm_public_ip", - "azurerm_route", - "azurerm_route_table", - "azurerm_subnet", - "azurerm_subnet_route_table_association", - "azurerm_virtual_machine", - "azurerm_virtual_network_gateway_connection", - "azurerm_virtual_network", - "azurerm_virtual_network_gateway", - "google_compute_network", - "google_compute_subnetwork", - "google_compute_vpn_gateway", - "google_compute_vpn_tunnel", - "google_compute_route", - "google_compute_address", - "google_compute_global_address", - "google_compute_router", - "google_compute_interconnect_attachment", - "google_compute_ha_vpn_gateway", - "google_compute_forwarding_rule", - "google_compute_network_firewall_policy", - "google_compute_network_firewall_policy_rule", - "cloudflare_static_route", - "cloudflare_ipsec_tunnel", - ] - - title: str - - -class PostApplyResourcesSectionHiddenItemValueMcnResourcePreviewItem(BaseModel): - item_type: str - - resource_preview: PostApplyResourcesSectionHiddenItemValueMcnResourcePreviewItemResourcePreview - - -class PostApplyResourcesSectionHiddenItemValueMcnListItemListMcnStringItem(BaseModel): - item_type: str - - string: str - - -class PostApplyResourcesSectionHiddenItemValueMcnListItemListMcnResourcePreviewItemResourcePreview(BaseModel): - id: str - - cloud_type: Literal["AWS", "AZURE", "GOOGLE", "CLOUDFLARE"] - - detail: str - - name: str - - resource_type: Literal[ - "aws_customer_gateway", - "aws_egress_only_internet_gateway", - "aws_internet_gateway", - "aws_instance", - "aws_network_interface", - "aws_route", - "aws_route_table", - "aws_route_table_association", - "aws_subnet", - "aws_vpc", - "aws_vpc_ipv4_cidr_block_association", - "aws_vpn_connection", - "aws_vpn_connection_route", - "aws_vpn_gateway", - "aws_security_group", - "aws_vpc_security_group_ingress_rule", - "aws_vpc_security_group_egress_rule", - "aws_ec2_managed_prefix_list", - "aws_ec2_transit_gateway", - "aws_ec2_transit_gateway_prefix_list_reference", - "aws_ec2_transit_gateway_vpc_attachment", - "azurerm_application_security_group", - "azurerm_lb", - "azurerm_lb_backend_address_pool", - "azurerm_lb_nat_pool", - "azurerm_lb_nat_rule", - "azurerm_lb_rule", - "azurerm_local_network_gateway", - "azurerm_network_interface", - "azurerm_network_interface_application_security_group_association", - "azurerm_network_interface_backend_address_pool_association", - "azurerm_network_interface_security_group_association", - "azurerm_network_security_group", - "azurerm_public_ip", - "azurerm_route", - "azurerm_route_table", - "azurerm_subnet", - "azurerm_subnet_route_table_association", - "azurerm_virtual_machine", - "azurerm_virtual_network_gateway_connection", - "azurerm_virtual_network", - "azurerm_virtual_network_gateway", - "google_compute_network", - "google_compute_subnetwork", - "google_compute_vpn_gateway", - "google_compute_vpn_tunnel", - "google_compute_route", - "google_compute_address", - "google_compute_global_address", - "google_compute_router", - "google_compute_interconnect_attachment", - "google_compute_ha_vpn_gateway", - "google_compute_forwarding_rule", - "google_compute_network_firewall_policy", - "google_compute_network_firewall_policy_rule", - "cloudflare_static_route", - "cloudflare_ipsec_tunnel", - ] - - title: str - - -class PostApplyResourcesSectionHiddenItemValueMcnListItemListMcnResourcePreviewItem(BaseModel): - item_type: str - - resource_preview: PostApplyResourcesSectionHiddenItemValueMcnListItemListMcnResourcePreviewItemResourcePreview - - -PostApplyResourcesSectionHiddenItemValueMcnListItemList: TypeAlias = Annotated[ - Union[ - PostApplyResourcesSectionHiddenItemValueMcnListItemListMcnStringItem, - PostApplyResourcesSectionHiddenItemValueMcnListItemListMcnResourcePreviewItem, - ], - PropertyInfo(discriminator="item_type"), -] - - -class PostApplyResourcesSectionHiddenItemValueMcnListItem(BaseModel): - item_type: str - - rule_list: List[PostApplyResourcesSectionHiddenItemValueMcnListItemList] = FieldInfo(alias="list") - - -PostApplyResourcesSectionHiddenItemValue: TypeAlias = Annotated[ - Union[ - PostApplyResourcesSectionHiddenItemValueMcnStringItem, - PostApplyResourcesSectionHiddenItemValueMcnYamlItem, - PostApplyResourcesSectionHiddenItemValueMcnYamlDiffItem, - PostApplyResourcesSectionHiddenItemValueMcnResourcePreviewItem, - PostApplyResourcesSectionHiddenItemValueMcnListItem, - ], - PropertyInfo(discriminator="item_type"), -] - - -class PostApplyResourcesSectionHiddenItem(BaseModel): - help_text: Optional[str] = FieldInfo(alias="helpText", default=None) - - name: Optional[str] = None - - value: Optional[PostApplyResourcesSectionHiddenItemValue] = None - - -class PostApplyResourcesSectionVisibleItemValueMcnStringItem(BaseModel): - item_type: str - - string: str - - -class PostApplyResourcesSectionVisibleItemValueMcnYamlItem(BaseModel): - item_type: str - - yaml: str - - -class PostApplyResourcesSectionVisibleItemValueMcnYamlDiffItemYamlDiff(BaseModel): - diff: str - - left_description: str - - left_yaml: str - - right_description: str - - right_yaml: str - - -class PostApplyResourcesSectionVisibleItemValueMcnYamlDiffItem(BaseModel): - item_type: str - - yaml_diff: PostApplyResourcesSectionVisibleItemValueMcnYamlDiffItemYamlDiff - - -class PostApplyResourcesSectionVisibleItemValueMcnResourcePreviewItemResourcePreview(BaseModel): - id: str - - cloud_type: Literal["AWS", "AZURE", "GOOGLE", "CLOUDFLARE"] - - detail: str - - name: str - - resource_type: Literal[ - "aws_customer_gateway", - "aws_egress_only_internet_gateway", - "aws_internet_gateway", - "aws_instance", - "aws_network_interface", - "aws_route", - "aws_route_table", - "aws_route_table_association", - "aws_subnet", - "aws_vpc", - "aws_vpc_ipv4_cidr_block_association", - "aws_vpn_connection", - "aws_vpn_connection_route", - "aws_vpn_gateway", - "aws_security_group", - "aws_vpc_security_group_ingress_rule", - "aws_vpc_security_group_egress_rule", - "aws_ec2_managed_prefix_list", - "aws_ec2_transit_gateway", - "aws_ec2_transit_gateway_prefix_list_reference", - "aws_ec2_transit_gateway_vpc_attachment", - "azurerm_application_security_group", - "azurerm_lb", - "azurerm_lb_backend_address_pool", - "azurerm_lb_nat_pool", - "azurerm_lb_nat_rule", - "azurerm_lb_rule", - "azurerm_local_network_gateway", - "azurerm_network_interface", - "azurerm_network_interface_application_security_group_association", - "azurerm_network_interface_backend_address_pool_association", - "azurerm_network_interface_security_group_association", - "azurerm_network_security_group", - "azurerm_public_ip", - "azurerm_route", - "azurerm_route_table", - "azurerm_subnet", - "azurerm_subnet_route_table_association", - "azurerm_virtual_machine", - "azurerm_virtual_network_gateway_connection", - "azurerm_virtual_network", - "azurerm_virtual_network_gateway", - "google_compute_network", - "google_compute_subnetwork", - "google_compute_vpn_gateway", - "google_compute_vpn_tunnel", - "google_compute_route", - "google_compute_address", - "google_compute_global_address", - "google_compute_router", - "google_compute_interconnect_attachment", - "google_compute_ha_vpn_gateway", - "google_compute_forwarding_rule", - "google_compute_network_firewall_policy", - "google_compute_network_firewall_policy_rule", - "cloudflare_static_route", - "cloudflare_ipsec_tunnel", - ] - - title: str - - -class PostApplyResourcesSectionVisibleItemValueMcnResourcePreviewItem(BaseModel): - item_type: str - - resource_preview: PostApplyResourcesSectionVisibleItemValueMcnResourcePreviewItemResourcePreview - - -class PostApplyResourcesSectionVisibleItemValueMcnListItemListMcnStringItem(BaseModel): - item_type: str - - string: str - - -class PostApplyResourcesSectionVisibleItemValueMcnListItemListMcnResourcePreviewItemResourcePreview(BaseModel): - id: str - - cloud_type: Literal["AWS", "AZURE", "GOOGLE", "CLOUDFLARE"] - - detail: str - - name: str - - resource_type: Literal[ - "aws_customer_gateway", - "aws_egress_only_internet_gateway", - "aws_internet_gateway", - "aws_instance", - "aws_network_interface", - "aws_route", - "aws_route_table", - "aws_route_table_association", - "aws_subnet", - "aws_vpc", - "aws_vpc_ipv4_cidr_block_association", - "aws_vpn_connection", - "aws_vpn_connection_route", - "aws_vpn_gateway", - "aws_security_group", - "aws_vpc_security_group_ingress_rule", - "aws_vpc_security_group_egress_rule", - "aws_ec2_managed_prefix_list", - "aws_ec2_transit_gateway", - "aws_ec2_transit_gateway_prefix_list_reference", - "aws_ec2_transit_gateway_vpc_attachment", - "azurerm_application_security_group", - "azurerm_lb", - "azurerm_lb_backend_address_pool", - "azurerm_lb_nat_pool", - "azurerm_lb_nat_rule", - "azurerm_lb_rule", - "azurerm_local_network_gateway", - "azurerm_network_interface", - "azurerm_network_interface_application_security_group_association", - "azurerm_network_interface_backend_address_pool_association", - "azurerm_network_interface_security_group_association", - "azurerm_network_security_group", - "azurerm_public_ip", - "azurerm_route", - "azurerm_route_table", - "azurerm_subnet", - "azurerm_subnet_route_table_association", - "azurerm_virtual_machine", - "azurerm_virtual_network_gateway_connection", - "azurerm_virtual_network", - "azurerm_virtual_network_gateway", - "google_compute_network", - "google_compute_subnetwork", - "google_compute_vpn_gateway", - "google_compute_vpn_tunnel", - "google_compute_route", - "google_compute_address", - "google_compute_global_address", - "google_compute_router", - "google_compute_interconnect_attachment", - "google_compute_ha_vpn_gateway", - "google_compute_forwarding_rule", - "google_compute_network_firewall_policy", - "google_compute_network_firewall_policy_rule", - "cloudflare_static_route", - "cloudflare_ipsec_tunnel", - ] - - title: str - - -class PostApplyResourcesSectionVisibleItemValueMcnListItemListMcnResourcePreviewItem(BaseModel): - item_type: str - - resource_preview: PostApplyResourcesSectionVisibleItemValueMcnListItemListMcnResourcePreviewItemResourcePreview - - -PostApplyResourcesSectionVisibleItemValueMcnListItemList: TypeAlias = Annotated[ - Union[ - PostApplyResourcesSectionVisibleItemValueMcnListItemListMcnStringItem, - PostApplyResourcesSectionVisibleItemValueMcnListItemListMcnResourcePreviewItem, - ], - PropertyInfo(discriminator="item_type"), -] - - -class PostApplyResourcesSectionVisibleItemValueMcnListItem(BaseModel): - item_type: str - - rule_list: List[PostApplyResourcesSectionVisibleItemValueMcnListItemList] = FieldInfo(alias="list") - - -PostApplyResourcesSectionVisibleItemValue: TypeAlias = Annotated[ - Union[ - PostApplyResourcesSectionVisibleItemValueMcnStringItem, - PostApplyResourcesSectionVisibleItemValueMcnYamlItem, - PostApplyResourcesSectionVisibleItemValueMcnYamlDiffItem, - PostApplyResourcesSectionVisibleItemValueMcnResourcePreviewItem, - PostApplyResourcesSectionVisibleItemValueMcnListItem, - ], - PropertyInfo(discriminator="item_type"), -] - - -class PostApplyResourcesSectionVisibleItem(BaseModel): - help_text: Optional[str] = FieldInfo(alias="helpText", default=None) - - name: Optional[str] = None - - value: Optional[PostApplyResourcesSectionVisibleItemValue] = None - - -class PostApplyResourcesSection(BaseModel): - hidden_items: List[PostApplyResourcesSectionHiddenItem] - - name: str - - visible_items: List[PostApplyResourcesSectionVisibleItem] - - help_text: Optional[str] = None - - -class PostApplyResourcesManagedBy(BaseModel): - id: str - - client_type: Literal["MAGIC_WAN_CLOUD_ONRAMP"] - - name: str - - -class PostApplyResources(BaseModel): - id: str - - account_id: str - - cloud_type: Literal["AWS", "AZURE", "GOOGLE", "CLOUDFLARE"] - - config: Dict[str, object] - - deployment_provider: str - - managed: bool - - monthly_cost_estimate: PostApplyResourcesMonthlyCostEstimate - - name: str - - native_id: str - - observations: Dict[str, PostApplyResourcesObservations] - - provider_ids: List[str] - - provider_names_by_id: Dict[str, str] - - region: str - - resource_group: str - - resource_type: Literal[ - "aws_customer_gateway", - "aws_egress_only_internet_gateway", - "aws_internet_gateway", - "aws_instance", - "aws_network_interface", - "aws_route", - "aws_route_table", - "aws_route_table_association", - "aws_subnet", - "aws_vpc", - "aws_vpc_ipv4_cidr_block_association", - "aws_vpn_connection", - "aws_vpn_connection_route", - "aws_vpn_gateway", - "aws_security_group", - "aws_vpc_security_group_ingress_rule", - "aws_vpc_security_group_egress_rule", - "aws_ec2_managed_prefix_list", - "aws_ec2_transit_gateway", - "aws_ec2_transit_gateway_prefix_list_reference", - "aws_ec2_transit_gateway_vpc_attachment", - "azurerm_application_security_group", - "azurerm_lb", - "azurerm_lb_backend_address_pool", - "azurerm_lb_nat_pool", - "azurerm_lb_nat_rule", - "azurerm_lb_rule", - "azurerm_local_network_gateway", - "azurerm_network_interface", - "azurerm_network_interface_application_security_group_association", - "azurerm_network_interface_backend_address_pool_association", - "azurerm_network_interface_security_group_association", - "azurerm_network_security_group", - "azurerm_public_ip", - "azurerm_route", - "azurerm_route_table", - "azurerm_subnet", - "azurerm_subnet_route_table_association", - "azurerm_virtual_machine", - "azurerm_virtual_network_gateway_connection", - "azurerm_virtual_network", - "azurerm_virtual_network_gateway", - "google_compute_network", - "google_compute_subnetwork", - "google_compute_vpn_gateway", - "google_compute_vpn_tunnel", - "google_compute_route", - "google_compute_address", - "google_compute_global_address", - "google_compute_router", - "google_compute_interconnect_attachment", - "google_compute_ha_vpn_gateway", - "google_compute_forwarding_rule", - "google_compute_network_firewall_policy", - "google_compute_network_firewall_policy_rule", - "cloudflare_static_route", - "cloudflare_ipsec_tunnel", - ] - - sections: List[PostApplyResourcesSection] - - state: Dict[str, object] - - tags: Dict[str, str] - - updated_at: str - - url: str - - managed_by: Optional[List[PostApplyResourcesManagedBy]] = None - - -class StatusApplyProgress(BaseModel): - done: int - - total: int - - -class StatusPlanProgress(BaseModel): - done: int - - total: int - - -class StatusLifecycleErrorsMeta(BaseModel): - l10n_key: Optional[str] = None - - loggable_error: Optional[str] = None - - template_data: Optional[object] = None - - trace_id: Optional[str] = None - - -class StatusLifecycleErrorsSource(BaseModel): - parameter: Optional[str] = None - - parameter_value_index: Optional[int] = None - - pointer: Optional[str] = None - - -class StatusLifecycleErrors(BaseModel): - code: Literal[ - 1001, - 1002, - 1003, - 1004, - 1005, - 1006, - 1007, - 1008, - 1009, - 1010, - 1011, - 1012, - 1013, - 1014, - 1015, - 1016, - 1017, - 1018, - 2001, - 2002, - 2003, - 2004, - 2005, - 2006, - 2007, - 2008, - 2009, - 2010, - 2011, - 2012, - 2013, - 2014, - 2015, - 2016, - 2017, - 2018, - 2019, - 2020, - 2021, - 2022, - 3001, - 3002, - 3003, - 3004, - 3005, - 3006, - 3007, - 4001, - 4002, - 4003, - 4004, - 4005, - 4006, - 4007, - 4008, - 4009, - 4010, - 4011, - 4012, - 4013, - 4014, - 4015, - 4016, - 4017, - 4018, - 4019, - 4020, - 4021, - 4022, - 4023, - 5001, - 5002, - 5003, - 5004, - 102000, - 102001, - 102002, - 102003, - 102004, - 102005, - 102006, - 102007, - 102008, - 102009, - 102010, - 102011, - 102012, - 102013, - 102014, - 102015, - 102016, - 102017, - 102018, - 102019, - 102020, - 102021, - 102022, - 102023, - 102024, - 102025, - 102026, - 102027, - 102028, - 102029, - 102030, - 102031, - 102032, - 102033, - 102034, - 102035, - 102036, - 102037, - 102038, - 102039, - 102040, - 102041, - 102042, - 102043, - 102044, - 102045, - 102046, - 102047, - 102048, - 102049, - 102050, - 102051, - 102052, - 102053, - 102054, - 102055, - 102056, - 102057, - 102058, - 102059, - 102060, - 102061, - 102062, - 102063, - 102064, - 102065, - 102066, - 102067, - 102068, - 102069, - 102070, - 102071, - 102072, - 103001, - 103002, - 103003, - 103004, - 103005, - 103006, - 103007, - 103008, - ] - - message: str - - documentation_url: Optional[str] = None - - meta: Optional[StatusLifecycleErrorsMeta] = None - - source: Optional[StatusLifecycleErrorsSource] = None - - -class Status(BaseModel): - apply_progress: StatusApplyProgress - - lifecycle_state: Literal[ - "OnrampNeedsApply", - "OnrampPendingPlan", - "OnrampPlanning", - "OnrampPlanFailed", - "OnrampPendingApproval", - "OnrampPendingApply", - "OnrampApplying", - "OnrampApplyFailed", - "OnrampActive", - "OnrampPendingDestroy", - "OnrampDestroying", - "OnrampDestroyFailed", - ] - - plan_progress: StatusPlanProgress - - routes: List[str] - - tunnels: List[str] - - lifecycle_errors: Optional[Dict[str, StatusLifecycleErrors]] = None - - -class VPCsByIDMonthlyCostEstimate(BaseModel): - currency: str - - monthly_cost: float - - -class VPCsByIDObservations(BaseModel): - first_observed_at: str - - last_observed_at: str - - provider_id: str - - resource_id: str - - -class VPCsByIDSectionHiddenItemValueMcnStringItem(BaseModel): - item_type: str - - string: str - - -class VPCsByIDSectionHiddenItemValueMcnYamlItem(BaseModel): - item_type: str - - yaml: str - - -class VPCsByIDSectionHiddenItemValueMcnYamlDiffItemYamlDiff(BaseModel): - diff: str - - left_description: str - - left_yaml: str - - right_description: str - - right_yaml: str - - -class VPCsByIDSectionHiddenItemValueMcnYamlDiffItem(BaseModel): - item_type: str - - yaml_diff: VPCsByIDSectionHiddenItemValueMcnYamlDiffItemYamlDiff - - -class VPCsByIDSectionHiddenItemValueMcnResourcePreviewItemResourcePreview(BaseModel): - id: str - - cloud_type: Literal["AWS", "AZURE", "GOOGLE", "CLOUDFLARE"] - - detail: str - - name: str - - resource_type: Literal[ - "aws_customer_gateway", - "aws_egress_only_internet_gateway", - "aws_internet_gateway", - "aws_instance", - "aws_network_interface", - "aws_route", - "aws_route_table", - "aws_route_table_association", - "aws_subnet", - "aws_vpc", - "aws_vpc_ipv4_cidr_block_association", - "aws_vpn_connection", - "aws_vpn_connection_route", - "aws_vpn_gateway", - "aws_security_group", - "aws_vpc_security_group_ingress_rule", - "aws_vpc_security_group_egress_rule", - "aws_ec2_managed_prefix_list", - "aws_ec2_transit_gateway", - "aws_ec2_transit_gateway_prefix_list_reference", - "aws_ec2_transit_gateway_vpc_attachment", - "azurerm_application_security_group", - "azurerm_lb", - "azurerm_lb_backend_address_pool", - "azurerm_lb_nat_pool", - "azurerm_lb_nat_rule", - "azurerm_lb_rule", - "azurerm_local_network_gateway", - "azurerm_network_interface", - "azurerm_network_interface_application_security_group_association", - "azurerm_network_interface_backend_address_pool_association", - "azurerm_network_interface_security_group_association", - "azurerm_network_security_group", - "azurerm_public_ip", - "azurerm_route", - "azurerm_route_table", - "azurerm_subnet", - "azurerm_subnet_route_table_association", - "azurerm_virtual_machine", - "azurerm_virtual_network_gateway_connection", - "azurerm_virtual_network", - "azurerm_virtual_network_gateway", - "google_compute_network", - "google_compute_subnetwork", - "google_compute_vpn_gateway", - "google_compute_vpn_tunnel", - "google_compute_route", - "google_compute_address", - "google_compute_global_address", - "google_compute_router", - "google_compute_interconnect_attachment", - "google_compute_ha_vpn_gateway", - "google_compute_forwarding_rule", - "google_compute_network_firewall_policy", - "google_compute_network_firewall_policy_rule", - "cloudflare_static_route", - "cloudflare_ipsec_tunnel", - ] - - title: str - - -class VPCsByIDSectionHiddenItemValueMcnResourcePreviewItem(BaseModel): - item_type: str - - resource_preview: VPCsByIDSectionHiddenItemValueMcnResourcePreviewItemResourcePreview - - -class VPCsByIDSectionHiddenItemValueMcnListItemListMcnStringItem(BaseModel): - item_type: str - - string: str - - -class VPCsByIDSectionHiddenItemValueMcnListItemListMcnResourcePreviewItemResourcePreview(BaseModel): - id: str - - cloud_type: Literal["AWS", "AZURE", "GOOGLE", "CLOUDFLARE"] - - detail: str - - name: str - - resource_type: Literal[ - "aws_customer_gateway", - "aws_egress_only_internet_gateway", - "aws_internet_gateway", - "aws_instance", - "aws_network_interface", - "aws_route", - "aws_route_table", - "aws_route_table_association", - "aws_subnet", - "aws_vpc", - "aws_vpc_ipv4_cidr_block_association", - "aws_vpn_connection", - "aws_vpn_connection_route", - "aws_vpn_gateway", - "aws_security_group", - "aws_vpc_security_group_ingress_rule", - "aws_vpc_security_group_egress_rule", - "aws_ec2_managed_prefix_list", - "aws_ec2_transit_gateway", - "aws_ec2_transit_gateway_prefix_list_reference", - "aws_ec2_transit_gateway_vpc_attachment", - "azurerm_application_security_group", - "azurerm_lb", - "azurerm_lb_backend_address_pool", - "azurerm_lb_nat_pool", - "azurerm_lb_nat_rule", - "azurerm_lb_rule", - "azurerm_local_network_gateway", - "azurerm_network_interface", - "azurerm_network_interface_application_security_group_association", - "azurerm_network_interface_backend_address_pool_association", - "azurerm_network_interface_security_group_association", - "azurerm_network_security_group", - "azurerm_public_ip", - "azurerm_route", - "azurerm_route_table", - "azurerm_subnet", - "azurerm_subnet_route_table_association", - "azurerm_virtual_machine", - "azurerm_virtual_network_gateway_connection", - "azurerm_virtual_network", - "azurerm_virtual_network_gateway", - "google_compute_network", - "google_compute_subnetwork", - "google_compute_vpn_gateway", - "google_compute_vpn_tunnel", - "google_compute_route", - "google_compute_address", - "google_compute_global_address", - "google_compute_router", - "google_compute_interconnect_attachment", - "google_compute_ha_vpn_gateway", - "google_compute_forwarding_rule", - "google_compute_network_firewall_policy", - "google_compute_network_firewall_policy_rule", - "cloudflare_static_route", - "cloudflare_ipsec_tunnel", - ] - - title: str - - -class VPCsByIDSectionHiddenItemValueMcnListItemListMcnResourcePreviewItem(BaseModel): - item_type: str - - resource_preview: VPCsByIDSectionHiddenItemValueMcnListItemListMcnResourcePreviewItemResourcePreview - - -VPCsByIDSectionHiddenItemValueMcnListItemList: TypeAlias = Annotated[ - Union[ - VPCsByIDSectionHiddenItemValueMcnListItemListMcnStringItem, - VPCsByIDSectionHiddenItemValueMcnListItemListMcnResourcePreviewItem, - ], - PropertyInfo(discriminator="item_type"), -] - - -class VPCsByIDSectionHiddenItemValueMcnListItem(BaseModel): - item_type: str - - rule_list: List[VPCsByIDSectionHiddenItemValueMcnListItemList] = FieldInfo(alias="list") - - -VPCsByIDSectionHiddenItemValue: TypeAlias = Annotated[ - Union[ - VPCsByIDSectionHiddenItemValueMcnStringItem, - VPCsByIDSectionHiddenItemValueMcnYamlItem, - VPCsByIDSectionHiddenItemValueMcnYamlDiffItem, - VPCsByIDSectionHiddenItemValueMcnResourcePreviewItem, - VPCsByIDSectionHiddenItemValueMcnListItem, - ], - PropertyInfo(discriminator="item_type"), -] - - -class VPCsByIDSectionHiddenItem(BaseModel): - help_text: Optional[str] = FieldInfo(alias="helpText", default=None) - - name: Optional[str] = None - - value: Optional[VPCsByIDSectionHiddenItemValue] = None - - -class VPCsByIDSectionVisibleItemValueMcnStringItem(BaseModel): - item_type: str - - string: str - - -class VPCsByIDSectionVisibleItemValueMcnYamlItem(BaseModel): - item_type: str - - yaml: str - - -class VPCsByIDSectionVisibleItemValueMcnYamlDiffItemYamlDiff(BaseModel): - diff: str - - left_description: str - - left_yaml: str - - right_description: str - - right_yaml: str - - -class VPCsByIDSectionVisibleItemValueMcnYamlDiffItem(BaseModel): - item_type: str - - yaml_diff: VPCsByIDSectionVisibleItemValueMcnYamlDiffItemYamlDiff - - -class VPCsByIDSectionVisibleItemValueMcnResourcePreviewItemResourcePreview(BaseModel): - id: str - - cloud_type: Literal["AWS", "AZURE", "GOOGLE", "CLOUDFLARE"] - - detail: str - - name: str - - resource_type: Literal[ - "aws_customer_gateway", - "aws_egress_only_internet_gateway", - "aws_internet_gateway", - "aws_instance", - "aws_network_interface", - "aws_route", - "aws_route_table", - "aws_route_table_association", - "aws_subnet", - "aws_vpc", - "aws_vpc_ipv4_cidr_block_association", - "aws_vpn_connection", - "aws_vpn_connection_route", - "aws_vpn_gateway", - "aws_security_group", - "aws_vpc_security_group_ingress_rule", - "aws_vpc_security_group_egress_rule", - "aws_ec2_managed_prefix_list", - "aws_ec2_transit_gateway", - "aws_ec2_transit_gateway_prefix_list_reference", - "aws_ec2_transit_gateway_vpc_attachment", - "azurerm_application_security_group", - "azurerm_lb", - "azurerm_lb_backend_address_pool", - "azurerm_lb_nat_pool", - "azurerm_lb_nat_rule", - "azurerm_lb_rule", - "azurerm_local_network_gateway", - "azurerm_network_interface", - "azurerm_network_interface_application_security_group_association", - "azurerm_network_interface_backend_address_pool_association", - "azurerm_network_interface_security_group_association", - "azurerm_network_security_group", - "azurerm_public_ip", - "azurerm_route", - "azurerm_route_table", - "azurerm_subnet", - "azurerm_subnet_route_table_association", - "azurerm_virtual_machine", - "azurerm_virtual_network_gateway_connection", - "azurerm_virtual_network", - "azurerm_virtual_network_gateway", - "google_compute_network", - "google_compute_subnetwork", - "google_compute_vpn_gateway", - "google_compute_vpn_tunnel", - "google_compute_route", - "google_compute_address", - "google_compute_global_address", - "google_compute_router", - "google_compute_interconnect_attachment", - "google_compute_ha_vpn_gateway", - "google_compute_forwarding_rule", - "google_compute_network_firewall_policy", - "google_compute_network_firewall_policy_rule", - "cloudflare_static_route", - "cloudflare_ipsec_tunnel", - ] - - title: str - - -class VPCsByIDSectionVisibleItemValueMcnResourcePreviewItem(BaseModel): - item_type: str - - resource_preview: VPCsByIDSectionVisibleItemValueMcnResourcePreviewItemResourcePreview - - -class VPCsByIDSectionVisibleItemValueMcnListItemListMcnStringItem(BaseModel): - item_type: str - - string: str - - -class VPCsByIDSectionVisibleItemValueMcnListItemListMcnResourcePreviewItemResourcePreview(BaseModel): - id: str - - cloud_type: Literal["AWS", "AZURE", "GOOGLE", "CLOUDFLARE"] - - detail: str - - name: str - - resource_type: Literal[ - "aws_customer_gateway", - "aws_egress_only_internet_gateway", - "aws_internet_gateway", - "aws_instance", - "aws_network_interface", - "aws_route", - "aws_route_table", - "aws_route_table_association", - "aws_subnet", - "aws_vpc", - "aws_vpc_ipv4_cidr_block_association", - "aws_vpn_connection", - "aws_vpn_connection_route", - "aws_vpn_gateway", - "aws_security_group", - "aws_vpc_security_group_ingress_rule", - "aws_vpc_security_group_egress_rule", - "aws_ec2_managed_prefix_list", - "aws_ec2_transit_gateway", - "aws_ec2_transit_gateway_prefix_list_reference", - "aws_ec2_transit_gateway_vpc_attachment", - "azurerm_application_security_group", - "azurerm_lb", - "azurerm_lb_backend_address_pool", - "azurerm_lb_nat_pool", - "azurerm_lb_nat_rule", - "azurerm_lb_rule", - "azurerm_local_network_gateway", - "azurerm_network_interface", - "azurerm_network_interface_application_security_group_association", - "azurerm_network_interface_backend_address_pool_association", - "azurerm_network_interface_security_group_association", - "azurerm_network_security_group", - "azurerm_public_ip", - "azurerm_route", - "azurerm_route_table", - "azurerm_subnet", - "azurerm_subnet_route_table_association", - "azurerm_virtual_machine", - "azurerm_virtual_network_gateway_connection", - "azurerm_virtual_network", - "azurerm_virtual_network_gateway", - "google_compute_network", - "google_compute_subnetwork", - "google_compute_vpn_gateway", - "google_compute_vpn_tunnel", - "google_compute_route", - "google_compute_address", - "google_compute_global_address", - "google_compute_router", - "google_compute_interconnect_attachment", - "google_compute_ha_vpn_gateway", - "google_compute_forwarding_rule", - "google_compute_network_firewall_policy", - "google_compute_network_firewall_policy_rule", - "cloudflare_static_route", - "cloudflare_ipsec_tunnel", - ] - - title: str - - -class VPCsByIDSectionVisibleItemValueMcnListItemListMcnResourcePreviewItem(BaseModel): - item_type: str - - resource_preview: VPCsByIDSectionVisibleItemValueMcnListItemListMcnResourcePreviewItemResourcePreview - - -VPCsByIDSectionVisibleItemValueMcnListItemList: TypeAlias = Annotated[ - Union[ - VPCsByIDSectionVisibleItemValueMcnListItemListMcnStringItem, - VPCsByIDSectionVisibleItemValueMcnListItemListMcnResourcePreviewItem, - ], - PropertyInfo(discriminator="item_type"), -] - - -class VPCsByIDSectionVisibleItemValueMcnListItem(BaseModel): - item_type: str - - rule_list: List[VPCsByIDSectionVisibleItemValueMcnListItemList] = FieldInfo(alias="list") - - -VPCsByIDSectionVisibleItemValue: TypeAlias = Annotated[ - Union[ - VPCsByIDSectionVisibleItemValueMcnStringItem, - VPCsByIDSectionVisibleItemValueMcnYamlItem, - VPCsByIDSectionVisibleItemValueMcnYamlDiffItem, - VPCsByIDSectionVisibleItemValueMcnResourcePreviewItem, - VPCsByIDSectionVisibleItemValueMcnListItem, - ], - PropertyInfo(discriminator="item_type"), -] - - -class VPCsByIDSectionVisibleItem(BaseModel): - help_text: Optional[str] = FieldInfo(alias="helpText", default=None) - - name: Optional[str] = None - - value: Optional[VPCsByIDSectionVisibleItemValue] = None - - -class VPCsByIDSection(BaseModel): - hidden_items: List[VPCsByIDSectionHiddenItem] - - name: str - - visible_items: List[VPCsByIDSectionVisibleItem] - - help_text: Optional[str] = None - - -class VPCsByIDManagedBy(BaseModel): - id: str - - client_type: Literal["MAGIC_WAN_CLOUD_ONRAMP"] - - name: str - - -class VPCsByID(BaseModel): - id: str - - account_id: str - - cloud_type: Literal["AWS", "AZURE", "GOOGLE", "CLOUDFLARE"] - - config: Dict[str, object] - - deployment_provider: str - - managed: bool - - monthly_cost_estimate: VPCsByIDMonthlyCostEstimate - - name: str - - native_id: str - - observations: Dict[str, VPCsByIDObservations] - - provider_ids: List[str] - - provider_names_by_id: Dict[str, str] - - region: str - - resource_group: str - - resource_type: Literal[ - "aws_customer_gateway", - "aws_egress_only_internet_gateway", - "aws_internet_gateway", - "aws_instance", - "aws_network_interface", - "aws_route", - "aws_route_table", - "aws_route_table_association", - "aws_subnet", - "aws_vpc", - "aws_vpc_ipv4_cidr_block_association", - "aws_vpn_connection", - "aws_vpn_connection_route", - "aws_vpn_gateway", - "aws_security_group", - "aws_vpc_security_group_ingress_rule", - "aws_vpc_security_group_egress_rule", - "aws_ec2_managed_prefix_list", - "aws_ec2_transit_gateway", - "aws_ec2_transit_gateway_prefix_list_reference", - "aws_ec2_transit_gateway_vpc_attachment", - "azurerm_application_security_group", - "azurerm_lb", - "azurerm_lb_backend_address_pool", - "azurerm_lb_nat_pool", - "azurerm_lb_nat_rule", - "azurerm_lb_rule", - "azurerm_local_network_gateway", - "azurerm_network_interface", - "azurerm_network_interface_application_security_group_association", - "azurerm_network_interface_backend_address_pool_association", - "azurerm_network_interface_security_group_association", - "azurerm_network_security_group", - "azurerm_public_ip", - "azurerm_route", - "azurerm_route_table", - "azurerm_subnet", - "azurerm_subnet_route_table_association", - "azurerm_virtual_machine", - "azurerm_virtual_network_gateway_connection", - "azurerm_virtual_network", - "azurerm_virtual_network_gateway", - "google_compute_network", - "google_compute_subnetwork", - "google_compute_vpn_gateway", - "google_compute_vpn_tunnel", - "google_compute_route", - "google_compute_address", - "google_compute_global_address", - "google_compute_router", - "google_compute_interconnect_attachment", - "google_compute_ha_vpn_gateway", - "google_compute_forwarding_rule", - "google_compute_network_firewall_policy", - "google_compute_network_firewall_policy_rule", - "cloudflare_static_route", - "cloudflare_ipsec_tunnel", - ] - - sections: List[VPCsByIDSection] - - state: Dict[str, object] - - tags: Dict[str, str] - - updated_at: str - - url: str - - managed_by: Optional[List[VPCsByIDManagedBy]] = None - - -class OnRampListResponse(BaseModel): - id: str - - cloud_type: Literal["AWS", "AZURE", "GOOGLE"] - - dynamic_routing: bool - - install_routes_in_cloud: bool - - install_routes_in_magic_wan: bool - - name: str - - type: Literal["OnrampTypeSingle", "OnrampTypeHub"] - - updated_at: str - - attached_hubs: Optional[List[str]] = None - - attached_vpcs: Optional[List[str]] = None - - cloud_asn: Optional[int] = None - - description: Optional[str] = None - - hub: Optional[str] = None - - last_applied_at: Optional[str] = None - - last_exported_at: Optional[str] = None - - last_planned_at: Optional[str] = None - - manage_hub_to_hub_attachments: Optional[bool] = None - - manage_vpc_to_hub_attachments: Optional[bool] = None - - planned_monthly_cost_estimate: Optional[PlannedMonthlyCostEstimate] = None - - planned_resources: Optional[List[PlannedResource]] = None - - planned_resources_unavailable: Optional[bool] = None - - post_apply_monthly_cost_estimate: Optional[PostApplyMonthlyCostEstimate] = None - - post_apply_resources: Optional[Dict[str, PostApplyResources]] = None - - post_apply_resources_unavailable: Optional[bool] = None - - region: Optional[str] = None - - status: Optional[Status] = None - - vpc: Optional[str] = None - - vpcs_by_id: Optional[Dict[str, VPCsByID]] = None - - vpcs_by_id_unavailable: Optional[List[str]] = None - """The list of vpc IDs for which resource details failed to generate.""" diff --git a/src/cloudflare/types/magic_cloud_networking/on_ramp_plan_response.py b/src/cloudflare/types/magic_cloud_networking/on_ramp_plan_response.py deleted file mode 100644 index 8828c3fb18c..00000000000 --- a/src/cloudflare/types/magic_cloud_networking/on_ramp_plan_response.py +++ /dev/null @@ -1,388 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from typing import List, Optional -from typing_extensions import Literal - -from ..._models import BaseModel - -__all__ = ["OnRampPlanResponse", "Error", "ErrorMeta", "ErrorSource", "Message", "MessageMeta", "MessageSource"] - - -class ErrorMeta(BaseModel): - l10n_key: Optional[str] = None - - loggable_error: Optional[str] = None - - template_data: Optional[object] = None - - trace_id: Optional[str] = None - - -class ErrorSource(BaseModel): - parameter: Optional[str] = None - - parameter_value_index: Optional[int] = None - - pointer: Optional[str] = None - - -class Error(BaseModel): - code: Literal[ - 1001, - 1002, - 1003, - 1004, - 1005, - 1006, - 1007, - 1008, - 1009, - 1010, - 1011, - 1012, - 1013, - 1014, - 1015, - 1016, - 1017, - 1018, - 2001, - 2002, - 2003, - 2004, - 2005, - 2006, - 2007, - 2008, - 2009, - 2010, - 2011, - 2012, - 2013, - 2014, - 2015, - 2016, - 2017, - 2018, - 2019, - 2020, - 2021, - 2022, - 3001, - 3002, - 3003, - 3004, - 3005, - 3006, - 3007, - 4001, - 4002, - 4003, - 4004, - 4005, - 4006, - 4007, - 4008, - 4009, - 4010, - 4011, - 4012, - 4013, - 4014, - 4015, - 4016, - 4017, - 4018, - 4019, - 4020, - 4021, - 4022, - 4023, - 5001, - 5002, - 5003, - 5004, - 102000, - 102001, - 102002, - 102003, - 102004, - 102005, - 102006, - 102007, - 102008, - 102009, - 102010, - 102011, - 102012, - 102013, - 102014, - 102015, - 102016, - 102017, - 102018, - 102019, - 102020, - 102021, - 102022, - 102023, - 102024, - 102025, - 102026, - 102027, - 102028, - 102029, - 102030, - 102031, - 102032, - 102033, - 102034, - 102035, - 102036, - 102037, - 102038, - 102039, - 102040, - 102041, - 102042, - 102043, - 102044, - 102045, - 102046, - 102047, - 102048, - 102049, - 102050, - 102051, - 102052, - 102053, - 102054, - 102055, - 102056, - 102057, - 102058, - 102059, - 102060, - 102061, - 102062, - 102063, - 102064, - 102065, - 102066, - 102067, - 102068, - 102069, - 102070, - 102071, - 102072, - 103001, - 103002, - 103003, - 103004, - 103005, - 103006, - 103007, - 103008, - ] - - message: str - - documentation_url: Optional[str] = None - - meta: Optional[ErrorMeta] = None - - source: Optional[ErrorSource] = None - - -class MessageMeta(BaseModel): - l10n_key: Optional[str] = None - - loggable_error: Optional[str] = None - - template_data: Optional[object] = None - - trace_id: Optional[str] = None - - -class MessageSource(BaseModel): - parameter: Optional[str] = None - - parameter_value_index: Optional[int] = None - - pointer: Optional[str] = None - - -class Message(BaseModel): - code: Literal[ - 1001, - 1002, - 1003, - 1004, - 1005, - 1006, - 1007, - 1008, - 1009, - 1010, - 1011, - 1012, - 1013, - 1014, - 1015, - 1016, - 1017, - 1018, - 2001, - 2002, - 2003, - 2004, - 2005, - 2006, - 2007, - 2008, - 2009, - 2010, - 2011, - 2012, - 2013, - 2014, - 2015, - 2016, - 2017, - 2018, - 2019, - 2020, - 2021, - 2022, - 3001, - 3002, - 3003, - 3004, - 3005, - 3006, - 3007, - 4001, - 4002, - 4003, - 4004, - 4005, - 4006, - 4007, - 4008, - 4009, - 4010, - 4011, - 4012, - 4013, - 4014, - 4015, - 4016, - 4017, - 4018, - 4019, - 4020, - 4021, - 4022, - 4023, - 5001, - 5002, - 5003, - 5004, - 102000, - 102001, - 102002, - 102003, - 102004, - 102005, - 102006, - 102007, - 102008, - 102009, - 102010, - 102011, - 102012, - 102013, - 102014, - 102015, - 102016, - 102017, - 102018, - 102019, - 102020, - 102021, - 102022, - 102023, - 102024, - 102025, - 102026, - 102027, - 102028, - 102029, - 102030, - 102031, - 102032, - 102033, - 102034, - 102035, - 102036, - 102037, - 102038, - 102039, - 102040, - 102041, - 102042, - 102043, - 102044, - 102045, - 102046, - 102047, - 102048, - 102049, - 102050, - 102051, - 102052, - 102053, - 102054, - 102055, - 102056, - 102057, - 102058, - 102059, - 102060, - 102061, - 102062, - 102063, - 102064, - 102065, - 102066, - 102067, - 102068, - 102069, - 102070, - 102071, - 102072, - 103001, - 103002, - 103003, - 103004, - 103005, - 103006, - 103007, - 103008, - ] - - message: str - - documentation_url: Optional[str] = None - - meta: Optional[MessageMeta] = None - - source: Optional[MessageSource] = None - - -class OnRampPlanResponse(BaseModel): - errors: List[Error] - - messages: List[Message] - - success: bool diff --git a/src/cloudflare/types/magic_cloud_networking/on_ramp_update_params.py b/src/cloudflare/types/magic_cloud_networking/on_ramp_update_params.py deleted file mode 100644 index bbcd6aae218..00000000000 --- a/src/cloudflare/types/magic_cloud_networking/on_ramp_update_params.py +++ /dev/null @@ -1,31 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing_extensions import Required, TypedDict - -from ..._types import SequenceNotStr - -__all__ = ["OnRampUpdateParams"] - - -class OnRampUpdateParams(TypedDict, total=False): - account_id: Required[str] - - attached_hubs: SequenceNotStr[str] - - attached_vpcs: SequenceNotStr[str] - - description: str - - install_routes_in_cloud: bool - - install_routes_in_magic_wan: bool - - manage_hub_to_hub_attachments: bool - - manage_vpc_to_hub_attachments: bool - - name: str - - vpc: str diff --git a/src/cloudflare/types/magic_cloud_networking/on_ramp_update_response.py b/src/cloudflare/types/magic_cloud_networking/on_ramp_update_response.py deleted file mode 100644 index ea145da1dde..00000000000 --- a/src/cloudflare/types/magic_cloud_networking/on_ramp_update_response.py +++ /dev/null @@ -1,1675 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from typing import Dict, List, Union, Optional -from typing_extensions import Literal, Annotated, TypeAlias - -from pydantic import Field as FieldInfo - -from ..._utils import PropertyInfo -from ..._models import BaseModel - -__all__ = [ - "OnRampUpdateResponse", - "PlannedMonthlyCostEstimate", - "PlannedResource", - "PlannedResourceDiff", - "PlannedResourceMonthlyCostEstimateDiff", - "PlannedResourceResource", - "PostApplyMonthlyCostEstimate", - "PostApplyResources", - "PostApplyResourcesMonthlyCostEstimate", - "PostApplyResourcesObservations", - "PostApplyResourcesSection", - "PostApplyResourcesSectionHiddenItem", - "PostApplyResourcesSectionHiddenItemValue", - "PostApplyResourcesSectionHiddenItemValueMcnStringItem", - "PostApplyResourcesSectionHiddenItemValueMcnYamlItem", - "PostApplyResourcesSectionHiddenItemValueMcnYamlDiffItem", - "PostApplyResourcesSectionHiddenItemValueMcnYamlDiffItemYamlDiff", - "PostApplyResourcesSectionHiddenItemValueMcnResourcePreviewItem", - "PostApplyResourcesSectionHiddenItemValueMcnResourcePreviewItemResourcePreview", - "PostApplyResourcesSectionHiddenItemValueMcnListItem", - "PostApplyResourcesSectionHiddenItemValueMcnListItemList", - "PostApplyResourcesSectionHiddenItemValueMcnListItemListMcnStringItem", - "PostApplyResourcesSectionHiddenItemValueMcnListItemListMcnResourcePreviewItem", - "PostApplyResourcesSectionHiddenItemValueMcnListItemListMcnResourcePreviewItemResourcePreview", - "PostApplyResourcesSectionVisibleItem", - "PostApplyResourcesSectionVisibleItemValue", - "PostApplyResourcesSectionVisibleItemValueMcnStringItem", - "PostApplyResourcesSectionVisibleItemValueMcnYamlItem", - "PostApplyResourcesSectionVisibleItemValueMcnYamlDiffItem", - "PostApplyResourcesSectionVisibleItemValueMcnYamlDiffItemYamlDiff", - "PostApplyResourcesSectionVisibleItemValueMcnResourcePreviewItem", - "PostApplyResourcesSectionVisibleItemValueMcnResourcePreviewItemResourcePreview", - "PostApplyResourcesSectionVisibleItemValueMcnListItem", - "PostApplyResourcesSectionVisibleItemValueMcnListItemList", - "PostApplyResourcesSectionVisibleItemValueMcnListItemListMcnStringItem", - "PostApplyResourcesSectionVisibleItemValueMcnListItemListMcnResourcePreviewItem", - "PostApplyResourcesSectionVisibleItemValueMcnListItemListMcnResourcePreviewItemResourcePreview", - "PostApplyResourcesManagedBy", - "Status", - "StatusApplyProgress", - "StatusPlanProgress", - "StatusLifecycleErrors", - "StatusLifecycleErrorsMeta", - "StatusLifecycleErrorsSource", - "VPCsByID", - "VPCsByIDMonthlyCostEstimate", - "VPCsByIDObservations", - "VPCsByIDSection", - "VPCsByIDSectionHiddenItem", - "VPCsByIDSectionHiddenItemValue", - "VPCsByIDSectionHiddenItemValueMcnStringItem", - "VPCsByIDSectionHiddenItemValueMcnYamlItem", - "VPCsByIDSectionHiddenItemValueMcnYamlDiffItem", - "VPCsByIDSectionHiddenItemValueMcnYamlDiffItemYamlDiff", - "VPCsByIDSectionHiddenItemValueMcnResourcePreviewItem", - "VPCsByIDSectionHiddenItemValueMcnResourcePreviewItemResourcePreview", - "VPCsByIDSectionHiddenItemValueMcnListItem", - "VPCsByIDSectionHiddenItemValueMcnListItemList", - "VPCsByIDSectionHiddenItemValueMcnListItemListMcnStringItem", - "VPCsByIDSectionHiddenItemValueMcnListItemListMcnResourcePreviewItem", - "VPCsByIDSectionHiddenItemValueMcnListItemListMcnResourcePreviewItemResourcePreview", - "VPCsByIDSectionVisibleItem", - "VPCsByIDSectionVisibleItemValue", - "VPCsByIDSectionVisibleItemValueMcnStringItem", - "VPCsByIDSectionVisibleItemValueMcnYamlItem", - "VPCsByIDSectionVisibleItemValueMcnYamlDiffItem", - "VPCsByIDSectionVisibleItemValueMcnYamlDiffItemYamlDiff", - "VPCsByIDSectionVisibleItemValueMcnResourcePreviewItem", - "VPCsByIDSectionVisibleItemValueMcnResourcePreviewItemResourcePreview", - "VPCsByIDSectionVisibleItemValueMcnListItem", - "VPCsByIDSectionVisibleItemValueMcnListItemList", - "VPCsByIDSectionVisibleItemValueMcnListItemListMcnStringItem", - "VPCsByIDSectionVisibleItemValueMcnListItemListMcnResourcePreviewItem", - "VPCsByIDSectionVisibleItemValueMcnListItemListMcnResourcePreviewItemResourcePreview", - "VPCsByIDManagedBy", -] - - -class PlannedMonthlyCostEstimate(BaseModel): - currency: str - - current_monthly_cost: float - - diff: float - - proposed_monthly_cost: float - - -class PlannedResourceDiff(BaseModel): - diff: str - - left_description: str - - left_yaml: str - - right_description: str - - right_yaml: str - - -class PlannedResourceMonthlyCostEstimateDiff(BaseModel): - currency: str - - current_monthly_cost: float - - diff: float - - proposed_monthly_cost: float - - -class PlannedResourceResource(BaseModel): - id: str - - cloud_type: Literal["AWS", "AZURE", "GOOGLE", "CLOUDFLARE"] - - detail: str - - name: str - - resource_type: Literal[ - "aws_customer_gateway", - "aws_egress_only_internet_gateway", - "aws_internet_gateway", - "aws_instance", - "aws_network_interface", - "aws_route", - "aws_route_table", - "aws_route_table_association", - "aws_subnet", - "aws_vpc", - "aws_vpc_ipv4_cidr_block_association", - "aws_vpn_connection", - "aws_vpn_connection_route", - "aws_vpn_gateway", - "aws_security_group", - "aws_vpc_security_group_ingress_rule", - "aws_vpc_security_group_egress_rule", - "aws_ec2_managed_prefix_list", - "aws_ec2_transit_gateway", - "aws_ec2_transit_gateway_prefix_list_reference", - "aws_ec2_transit_gateway_vpc_attachment", - "azurerm_application_security_group", - "azurerm_lb", - "azurerm_lb_backend_address_pool", - "azurerm_lb_nat_pool", - "azurerm_lb_nat_rule", - "azurerm_lb_rule", - "azurerm_local_network_gateway", - "azurerm_network_interface", - "azurerm_network_interface_application_security_group_association", - "azurerm_network_interface_backend_address_pool_association", - "azurerm_network_interface_security_group_association", - "azurerm_network_security_group", - "azurerm_public_ip", - "azurerm_route", - "azurerm_route_table", - "azurerm_subnet", - "azurerm_subnet_route_table_association", - "azurerm_virtual_machine", - "azurerm_virtual_network_gateway_connection", - "azurerm_virtual_network", - "azurerm_virtual_network_gateway", - "google_compute_network", - "google_compute_subnetwork", - "google_compute_vpn_gateway", - "google_compute_vpn_tunnel", - "google_compute_route", - "google_compute_address", - "google_compute_global_address", - "google_compute_router", - "google_compute_interconnect_attachment", - "google_compute_ha_vpn_gateway", - "google_compute_forwarding_rule", - "google_compute_network_firewall_policy", - "google_compute_network_firewall_policy_rule", - "cloudflare_static_route", - "cloudflare_ipsec_tunnel", - ] - - title: str - - -class PlannedResource(BaseModel): - diff: PlannedResourceDiff - - keys_require_replace: List[str] - - monthly_cost_estimate_diff: PlannedResourceMonthlyCostEstimateDiff - - planned_action: Literal["no_op", "create", "update", "replace", "destroy"] - - resource: PlannedResourceResource - - -class PostApplyMonthlyCostEstimate(BaseModel): - currency: str - - monthly_cost: float - - -class PostApplyResourcesMonthlyCostEstimate(BaseModel): - currency: str - - monthly_cost: float - - -class PostApplyResourcesObservations(BaseModel): - first_observed_at: str - - last_observed_at: str - - provider_id: str - - resource_id: str - - -class PostApplyResourcesSectionHiddenItemValueMcnStringItem(BaseModel): - item_type: str - - string: str - - -class PostApplyResourcesSectionHiddenItemValueMcnYamlItem(BaseModel): - item_type: str - - yaml: str - - -class PostApplyResourcesSectionHiddenItemValueMcnYamlDiffItemYamlDiff(BaseModel): - diff: str - - left_description: str - - left_yaml: str - - right_description: str - - right_yaml: str - - -class PostApplyResourcesSectionHiddenItemValueMcnYamlDiffItem(BaseModel): - item_type: str - - yaml_diff: PostApplyResourcesSectionHiddenItemValueMcnYamlDiffItemYamlDiff - - -class PostApplyResourcesSectionHiddenItemValueMcnResourcePreviewItemResourcePreview(BaseModel): - id: str - - cloud_type: Literal["AWS", "AZURE", "GOOGLE", "CLOUDFLARE"] - - detail: str - - name: str - - resource_type: Literal[ - "aws_customer_gateway", - "aws_egress_only_internet_gateway", - "aws_internet_gateway", - "aws_instance", - "aws_network_interface", - "aws_route", - "aws_route_table", - "aws_route_table_association", - "aws_subnet", - "aws_vpc", - "aws_vpc_ipv4_cidr_block_association", - "aws_vpn_connection", - "aws_vpn_connection_route", - "aws_vpn_gateway", - "aws_security_group", - "aws_vpc_security_group_ingress_rule", - "aws_vpc_security_group_egress_rule", - "aws_ec2_managed_prefix_list", - "aws_ec2_transit_gateway", - "aws_ec2_transit_gateway_prefix_list_reference", - "aws_ec2_transit_gateway_vpc_attachment", - "azurerm_application_security_group", - "azurerm_lb", - "azurerm_lb_backend_address_pool", - "azurerm_lb_nat_pool", - "azurerm_lb_nat_rule", - "azurerm_lb_rule", - "azurerm_local_network_gateway", - "azurerm_network_interface", - "azurerm_network_interface_application_security_group_association", - "azurerm_network_interface_backend_address_pool_association", - "azurerm_network_interface_security_group_association", - "azurerm_network_security_group", - "azurerm_public_ip", - "azurerm_route", - "azurerm_route_table", - "azurerm_subnet", - "azurerm_subnet_route_table_association", - "azurerm_virtual_machine", - "azurerm_virtual_network_gateway_connection", - "azurerm_virtual_network", - "azurerm_virtual_network_gateway", - "google_compute_network", - "google_compute_subnetwork", - "google_compute_vpn_gateway", - "google_compute_vpn_tunnel", - "google_compute_route", - "google_compute_address", - "google_compute_global_address", - "google_compute_router", - "google_compute_interconnect_attachment", - "google_compute_ha_vpn_gateway", - "google_compute_forwarding_rule", - "google_compute_network_firewall_policy", - "google_compute_network_firewall_policy_rule", - "cloudflare_static_route", - "cloudflare_ipsec_tunnel", - ] - - title: str - - -class PostApplyResourcesSectionHiddenItemValueMcnResourcePreviewItem(BaseModel): - item_type: str - - resource_preview: PostApplyResourcesSectionHiddenItemValueMcnResourcePreviewItemResourcePreview - - -class PostApplyResourcesSectionHiddenItemValueMcnListItemListMcnStringItem(BaseModel): - item_type: str - - string: str - - -class PostApplyResourcesSectionHiddenItemValueMcnListItemListMcnResourcePreviewItemResourcePreview(BaseModel): - id: str - - cloud_type: Literal["AWS", "AZURE", "GOOGLE", "CLOUDFLARE"] - - detail: str - - name: str - - resource_type: Literal[ - "aws_customer_gateway", - "aws_egress_only_internet_gateway", - "aws_internet_gateway", - "aws_instance", - "aws_network_interface", - "aws_route", - "aws_route_table", - "aws_route_table_association", - "aws_subnet", - "aws_vpc", - "aws_vpc_ipv4_cidr_block_association", - "aws_vpn_connection", - "aws_vpn_connection_route", - "aws_vpn_gateway", - "aws_security_group", - "aws_vpc_security_group_ingress_rule", - "aws_vpc_security_group_egress_rule", - "aws_ec2_managed_prefix_list", - "aws_ec2_transit_gateway", - "aws_ec2_transit_gateway_prefix_list_reference", - "aws_ec2_transit_gateway_vpc_attachment", - "azurerm_application_security_group", - "azurerm_lb", - "azurerm_lb_backend_address_pool", - "azurerm_lb_nat_pool", - "azurerm_lb_nat_rule", - "azurerm_lb_rule", - "azurerm_local_network_gateway", - "azurerm_network_interface", - "azurerm_network_interface_application_security_group_association", - "azurerm_network_interface_backend_address_pool_association", - "azurerm_network_interface_security_group_association", - "azurerm_network_security_group", - "azurerm_public_ip", - "azurerm_route", - "azurerm_route_table", - "azurerm_subnet", - "azurerm_subnet_route_table_association", - "azurerm_virtual_machine", - "azurerm_virtual_network_gateway_connection", - "azurerm_virtual_network", - "azurerm_virtual_network_gateway", - "google_compute_network", - "google_compute_subnetwork", - "google_compute_vpn_gateway", - "google_compute_vpn_tunnel", - "google_compute_route", - "google_compute_address", - "google_compute_global_address", - "google_compute_router", - "google_compute_interconnect_attachment", - "google_compute_ha_vpn_gateway", - "google_compute_forwarding_rule", - "google_compute_network_firewall_policy", - "google_compute_network_firewall_policy_rule", - "cloudflare_static_route", - "cloudflare_ipsec_tunnel", - ] - - title: str - - -class PostApplyResourcesSectionHiddenItemValueMcnListItemListMcnResourcePreviewItem(BaseModel): - item_type: str - - resource_preview: PostApplyResourcesSectionHiddenItemValueMcnListItemListMcnResourcePreviewItemResourcePreview - - -PostApplyResourcesSectionHiddenItemValueMcnListItemList: TypeAlias = Annotated[ - Union[ - PostApplyResourcesSectionHiddenItemValueMcnListItemListMcnStringItem, - PostApplyResourcesSectionHiddenItemValueMcnListItemListMcnResourcePreviewItem, - ], - PropertyInfo(discriminator="item_type"), -] - - -class PostApplyResourcesSectionHiddenItemValueMcnListItem(BaseModel): - item_type: str - - rule_list: List[PostApplyResourcesSectionHiddenItemValueMcnListItemList] = FieldInfo(alias="list") - - -PostApplyResourcesSectionHiddenItemValue: TypeAlias = Annotated[ - Union[ - PostApplyResourcesSectionHiddenItemValueMcnStringItem, - PostApplyResourcesSectionHiddenItemValueMcnYamlItem, - PostApplyResourcesSectionHiddenItemValueMcnYamlDiffItem, - PostApplyResourcesSectionHiddenItemValueMcnResourcePreviewItem, - PostApplyResourcesSectionHiddenItemValueMcnListItem, - ], - PropertyInfo(discriminator="item_type"), -] - - -class PostApplyResourcesSectionHiddenItem(BaseModel): - help_text: Optional[str] = FieldInfo(alias="helpText", default=None) - - name: Optional[str] = None - - value: Optional[PostApplyResourcesSectionHiddenItemValue] = None - - -class PostApplyResourcesSectionVisibleItemValueMcnStringItem(BaseModel): - item_type: str - - string: str - - -class PostApplyResourcesSectionVisibleItemValueMcnYamlItem(BaseModel): - item_type: str - - yaml: str - - -class PostApplyResourcesSectionVisibleItemValueMcnYamlDiffItemYamlDiff(BaseModel): - diff: str - - left_description: str - - left_yaml: str - - right_description: str - - right_yaml: str - - -class PostApplyResourcesSectionVisibleItemValueMcnYamlDiffItem(BaseModel): - item_type: str - - yaml_diff: PostApplyResourcesSectionVisibleItemValueMcnYamlDiffItemYamlDiff - - -class PostApplyResourcesSectionVisibleItemValueMcnResourcePreviewItemResourcePreview(BaseModel): - id: str - - cloud_type: Literal["AWS", "AZURE", "GOOGLE", "CLOUDFLARE"] - - detail: str - - name: str - - resource_type: Literal[ - "aws_customer_gateway", - "aws_egress_only_internet_gateway", - "aws_internet_gateway", - "aws_instance", - "aws_network_interface", - "aws_route", - "aws_route_table", - "aws_route_table_association", - "aws_subnet", - "aws_vpc", - "aws_vpc_ipv4_cidr_block_association", - "aws_vpn_connection", - "aws_vpn_connection_route", - "aws_vpn_gateway", - "aws_security_group", - "aws_vpc_security_group_ingress_rule", - "aws_vpc_security_group_egress_rule", - "aws_ec2_managed_prefix_list", - "aws_ec2_transit_gateway", - "aws_ec2_transit_gateway_prefix_list_reference", - "aws_ec2_transit_gateway_vpc_attachment", - "azurerm_application_security_group", - "azurerm_lb", - "azurerm_lb_backend_address_pool", - "azurerm_lb_nat_pool", - "azurerm_lb_nat_rule", - "azurerm_lb_rule", - "azurerm_local_network_gateway", - "azurerm_network_interface", - "azurerm_network_interface_application_security_group_association", - "azurerm_network_interface_backend_address_pool_association", - "azurerm_network_interface_security_group_association", - "azurerm_network_security_group", - "azurerm_public_ip", - "azurerm_route", - "azurerm_route_table", - "azurerm_subnet", - "azurerm_subnet_route_table_association", - "azurerm_virtual_machine", - "azurerm_virtual_network_gateway_connection", - "azurerm_virtual_network", - "azurerm_virtual_network_gateway", - "google_compute_network", - "google_compute_subnetwork", - "google_compute_vpn_gateway", - "google_compute_vpn_tunnel", - "google_compute_route", - "google_compute_address", - "google_compute_global_address", - "google_compute_router", - "google_compute_interconnect_attachment", - "google_compute_ha_vpn_gateway", - "google_compute_forwarding_rule", - "google_compute_network_firewall_policy", - "google_compute_network_firewall_policy_rule", - "cloudflare_static_route", - "cloudflare_ipsec_tunnel", - ] - - title: str - - -class PostApplyResourcesSectionVisibleItemValueMcnResourcePreviewItem(BaseModel): - item_type: str - - resource_preview: PostApplyResourcesSectionVisibleItemValueMcnResourcePreviewItemResourcePreview - - -class PostApplyResourcesSectionVisibleItemValueMcnListItemListMcnStringItem(BaseModel): - item_type: str - - string: str - - -class PostApplyResourcesSectionVisibleItemValueMcnListItemListMcnResourcePreviewItemResourcePreview(BaseModel): - id: str - - cloud_type: Literal["AWS", "AZURE", "GOOGLE", "CLOUDFLARE"] - - detail: str - - name: str - - resource_type: Literal[ - "aws_customer_gateway", - "aws_egress_only_internet_gateway", - "aws_internet_gateway", - "aws_instance", - "aws_network_interface", - "aws_route", - "aws_route_table", - "aws_route_table_association", - "aws_subnet", - "aws_vpc", - "aws_vpc_ipv4_cidr_block_association", - "aws_vpn_connection", - "aws_vpn_connection_route", - "aws_vpn_gateway", - "aws_security_group", - "aws_vpc_security_group_ingress_rule", - "aws_vpc_security_group_egress_rule", - "aws_ec2_managed_prefix_list", - "aws_ec2_transit_gateway", - "aws_ec2_transit_gateway_prefix_list_reference", - "aws_ec2_transit_gateway_vpc_attachment", - "azurerm_application_security_group", - "azurerm_lb", - "azurerm_lb_backend_address_pool", - "azurerm_lb_nat_pool", - "azurerm_lb_nat_rule", - "azurerm_lb_rule", - "azurerm_local_network_gateway", - "azurerm_network_interface", - "azurerm_network_interface_application_security_group_association", - "azurerm_network_interface_backend_address_pool_association", - "azurerm_network_interface_security_group_association", - "azurerm_network_security_group", - "azurerm_public_ip", - "azurerm_route", - "azurerm_route_table", - "azurerm_subnet", - "azurerm_subnet_route_table_association", - "azurerm_virtual_machine", - "azurerm_virtual_network_gateway_connection", - "azurerm_virtual_network", - "azurerm_virtual_network_gateway", - "google_compute_network", - "google_compute_subnetwork", - "google_compute_vpn_gateway", - "google_compute_vpn_tunnel", - "google_compute_route", - "google_compute_address", - "google_compute_global_address", - "google_compute_router", - "google_compute_interconnect_attachment", - "google_compute_ha_vpn_gateway", - "google_compute_forwarding_rule", - "google_compute_network_firewall_policy", - "google_compute_network_firewall_policy_rule", - "cloudflare_static_route", - "cloudflare_ipsec_tunnel", - ] - - title: str - - -class PostApplyResourcesSectionVisibleItemValueMcnListItemListMcnResourcePreviewItem(BaseModel): - item_type: str - - resource_preview: PostApplyResourcesSectionVisibleItemValueMcnListItemListMcnResourcePreviewItemResourcePreview - - -PostApplyResourcesSectionVisibleItemValueMcnListItemList: TypeAlias = Annotated[ - Union[ - PostApplyResourcesSectionVisibleItemValueMcnListItemListMcnStringItem, - PostApplyResourcesSectionVisibleItemValueMcnListItemListMcnResourcePreviewItem, - ], - PropertyInfo(discriminator="item_type"), -] - - -class PostApplyResourcesSectionVisibleItemValueMcnListItem(BaseModel): - item_type: str - - rule_list: List[PostApplyResourcesSectionVisibleItemValueMcnListItemList] = FieldInfo(alias="list") - - -PostApplyResourcesSectionVisibleItemValue: TypeAlias = Annotated[ - Union[ - PostApplyResourcesSectionVisibleItemValueMcnStringItem, - PostApplyResourcesSectionVisibleItemValueMcnYamlItem, - PostApplyResourcesSectionVisibleItemValueMcnYamlDiffItem, - PostApplyResourcesSectionVisibleItemValueMcnResourcePreviewItem, - PostApplyResourcesSectionVisibleItemValueMcnListItem, - ], - PropertyInfo(discriminator="item_type"), -] - - -class PostApplyResourcesSectionVisibleItem(BaseModel): - help_text: Optional[str] = FieldInfo(alias="helpText", default=None) - - name: Optional[str] = None - - value: Optional[PostApplyResourcesSectionVisibleItemValue] = None - - -class PostApplyResourcesSection(BaseModel): - hidden_items: List[PostApplyResourcesSectionHiddenItem] - - name: str - - visible_items: List[PostApplyResourcesSectionVisibleItem] - - help_text: Optional[str] = None - - -class PostApplyResourcesManagedBy(BaseModel): - id: str - - client_type: Literal["MAGIC_WAN_CLOUD_ONRAMP"] - - name: str - - -class PostApplyResources(BaseModel): - id: str - - account_id: str - - cloud_type: Literal["AWS", "AZURE", "GOOGLE", "CLOUDFLARE"] - - config: Dict[str, object] - - deployment_provider: str - - managed: bool - - monthly_cost_estimate: PostApplyResourcesMonthlyCostEstimate - - name: str - - native_id: str - - observations: Dict[str, PostApplyResourcesObservations] - - provider_ids: List[str] - - provider_names_by_id: Dict[str, str] - - region: str - - resource_group: str - - resource_type: Literal[ - "aws_customer_gateway", - "aws_egress_only_internet_gateway", - "aws_internet_gateway", - "aws_instance", - "aws_network_interface", - "aws_route", - "aws_route_table", - "aws_route_table_association", - "aws_subnet", - "aws_vpc", - "aws_vpc_ipv4_cidr_block_association", - "aws_vpn_connection", - "aws_vpn_connection_route", - "aws_vpn_gateway", - "aws_security_group", - "aws_vpc_security_group_ingress_rule", - "aws_vpc_security_group_egress_rule", - "aws_ec2_managed_prefix_list", - "aws_ec2_transit_gateway", - "aws_ec2_transit_gateway_prefix_list_reference", - "aws_ec2_transit_gateway_vpc_attachment", - "azurerm_application_security_group", - "azurerm_lb", - "azurerm_lb_backend_address_pool", - "azurerm_lb_nat_pool", - "azurerm_lb_nat_rule", - "azurerm_lb_rule", - "azurerm_local_network_gateway", - "azurerm_network_interface", - "azurerm_network_interface_application_security_group_association", - "azurerm_network_interface_backend_address_pool_association", - "azurerm_network_interface_security_group_association", - "azurerm_network_security_group", - "azurerm_public_ip", - "azurerm_route", - "azurerm_route_table", - "azurerm_subnet", - "azurerm_subnet_route_table_association", - "azurerm_virtual_machine", - "azurerm_virtual_network_gateway_connection", - "azurerm_virtual_network", - "azurerm_virtual_network_gateway", - "google_compute_network", - "google_compute_subnetwork", - "google_compute_vpn_gateway", - "google_compute_vpn_tunnel", - "google_compute_route", - "google_compute_address", - "google_compute_global_address", - "google_compute_router", - "google_compute_interconnect_attachment", - "google_compute_ha_vpn_gateway", - "google_compute_forwarding_rule", - "google_compute_network_firewall_policy", - "google_compute_network_firewall_policy_rule", - "cloudflare_static_route", - "cloudflare_ipsec_tunnel", - ] - - sections: List[PostApplyResourcesSection] - - state: Dict[str, object] - - tags: Dict[str, str] - - updated_at: str - - url: str - - managed_by: Optional[List[PostApplyResourcesManagedBy]] = None - - -class StatusApplyProgress(BaseModel): - done: int - - total: int - - -class StatusPlanProgress(BaseModel): - done: int - - total: int - - -class StatusLifecycleErrorsMeta(BaseModel): - l10n_key: Optional[str] = None - - loggable_error: Optional[str] = None - - template_data: Optional[object] = None - - trace_id: Optional[str] = None - - -class StatusLifecycleErrorsSource(BaseModel): - parameter: Optional[str] = None - - parameter_value_index: Optional[int] = None - - pointer: Optional[str] = None - - -class StatusLifecycleErrors(BaseModel): - code: Literal[ - 1001, - 1002, - 1003, - 1004, - 1005, - 1006, - 1007, - 1008, - 1009, - 1010, - 1011, - 1012, - 1013, - 1014, - 1015, - 1016, - 1017, - 1018, - 2001, - 2002, - 2003, - 2004, - 2005, - 2006, - 2007, - 2008, - 2009, - 2010, - 2011, - 2012, - 2013, - 2014, - 2015, - 2016, - 2017, - 2018, - 2019, - 2020, - 2021, - 2022, - 3001, - 3002, - 3003, - 3004, - 3005, - 3006, - 3007, - 4001, - 4002, - 4003, - 4004, - 4005, - 4006, - 4007, - 4008, - 4009, - 4010, - 4011, - 4012, - 4013, - 4014, - 4015, - 4016, - 4017, - 4018, - 4019, - 4020, - 4021, - 4022, - 4023, - 5001, - 5002, - 5003, - 5004, - 102000, - 102001, - 102002, - 102003, - 102004, - 102005, - 102006, - 102007, - 102008, - 102009, - 102010, - 102011, - 102012, - 102013, - 102014, - 102015, - 102016, - 102017, - 102018, - 102019, - 102020, - 102021, - 102022, - 102023, - 102024, - 102025, - 102026, - 102027, - 102028, - 102029, - 102030, - 102031, - 102032, - 102033, - 102034, - 102035, - 102036, - 102037, - 102038, - 102039, - 102040, - 102041, - 102042, - 102043, - 102044, - 102045, - 102046, - 102047, - 102048, - 102049, - 102050, - 102051, - 102052, - 102053, - 102054, - 102055, - 102056, - 102057, - 102058, - 102059, - 102060, - 102061, - 102062, - 102063, - 102064, - 102065, - 102066, - 102067, - 102068, - 102069, - 102070, - 102071, - 102072, - 103001, - 103002, - 103003, - 103004, - 103005, - 103006, - 103007, - 103008, - ] - - message: str - - documentation_url: Optional[str] = None - - meta: Optional[StatusLifecycleErrorsMeta] = None - - source: Optional[StatusLifecycleErrorsSource] = None - - -class Status(BaseModel): - apply_progress: StatusApplyProgress - - lifecycle_state: Literal[ - "OnrampNeedsApply", - "OnrampPendingPlan", - "OnrampPlanning", - "OnrampPlanFailed", - "OnrampPendingApproval", - "OnrampPendingApply", - "OnrampApplying", - "OnrampApplyFailed", - "OnrampActive", - "OnrampPendingDestroy", - "OnrampDestroying", - "OnrampDestroyFailed", - ] - - plan_progress: StatusPlanProgress - - routes: List[str] - - tunnels: List[str] - - lifecycle_errors: Optional[Dict[str, StatusLifecycleErrors]] = None - - -class VPCsByIDMonthlyCostEstimate(BaseModel): - currency: str - - monthly_cost: float - - -class VPCsByIDObservations(BaseModel): - first_observed_at: str - - last_observed_at: str - - provider_id: str - - resource_id: str - - -class VPCsByIDSectionHiddenItemValueMcnStringItem(BaseModel): - item_type: str - - string: str - - -class VPCsByIDSectionHiddenItemValueMcnYamlItem(BaseModel): - item_type: str - - yaml: str - - -class VPCsByIDSectionHiddenItemValueMcnYamlDiffItemYamlDiff(BaseModel): - diff: str - - left_description: str - - left_yaml: str - - right_description: str - - right_yaml: str - - -class VPCsByIDSectionHiddenItemValueMcnYamlDiffItem(BaseModel): - item_type: str - - yaml_diff: VPCsByIDSectionHiddenItemValueMcnYamlDiffItemYamlDiff - - -class VPCsByIDSectionHiddenItemValueMcnResourcePreviewItemResourcePreview(BaseModel): - id: str - - cloud_type: Literal["AWS", "AZURE", "GOOGLE", "CLOUDFLARE"] - - detail: str - - name: str - - resource_type: Literal[ - "aws_customer_gateway", - "aws_egress_only_internet_gateway", - "aws_internet_gateway", - "aws_instance", - "aws_network_interface", - "aws_route", - "aws_route_table", - "aws_route_table_association", - "aws_subnet", - "aws_vpc", - "aws_vpc_ipv4_cidr_block_association", - "aws_vpn_connection", - "aws_vpn_connection_route", - "aws_vpn_gateway", - "aws_security_group", - "aws_vpc_security_group_ingress_rule", - "aws_vpc_security_group_egress_rule", - "aws_ec2_managed_prefix_list", - "aws_ec2_transit_gateway", - "aws_ec2_transit_gateway_prefix_list_reference", - "aws_ec2_transit_gateway_vpc_attachment", - "azurerm_application_security_group", - "azurerm_lb", - "azurerm_lb_backend_address_pool", - "azurerm_lb_nat_pool", - "azurerm_lb_nat_rule", - "azurerm_lb_rule", - "azurerm_local_network_gateway", - "azurerm_network_interface", - "azurerm_network_interface_application_security_group_association", - "azurerm_network_interface_backend_address_pool_association", - "azurerm_network_interface_security_group_association", - "azurerm_network_security_group", - "azurerm_public_ip", - "azurerm_route", - "azurerm_route_table", - "azurerm_subnet", - "azurerm_subnet_route_table_association", - "azurerm_virtual_machine", - "azurerm_virtual_network_gateway_connection", - "azurerm_virtual_network", - "azurerm_virtual_network_gateway", - "google_compute_network", - "google_compute_subnetwork", - "google_compute_vpn_gateway", - "google_compute_vpn_tunnel", - "google_compute_route", - "google_compute_address", - "google_compute_global_address", - "google_compute_router", - "google_compute_interconnect_attachment", - "google_compute_ha_vpn_gateway", - "google_compute_forwarding_rule", - "google_compute_network_firewall_policy", - "google_compute_network_firewall_policy_rule", - "cloudflare_static_route", - "cloudflare_ipsec_tunnel", - ] - - title: str - - -class VPCsByIDSectionHiddenItemValueMcnResourcePreviewItem(BaseModel): - item_type: str - - resource_preview: VPCsByIDSectionHiddenItemValueMcnResourcePreviewItemResourcePreview - - -class VPCsByIDSectionHiddenItemValueMcnListItemListMcnStringItem(BaseModel): - item_type: str - - string: str - - -class VPCsByIDSectionHiddenItemValueMcnListItemListMcnResourcePreviewItemResourcePreview(BaseModel): - id: str - - cloud_type: Literal["AWS", "AZURE", "GOOGLE", "CLOUDFLARE"] - - detail: str - - name: str - - resource_type: Literal[ - "aws_customer_gateway", - "aws_egress_only_internet_gateway", - "aws_internet_gateway", - "aws_instance", - "aws_network_interface", - "aws_route", - "aws_route_table", - "aws_route_table_association", - "aws_subnet", - "aws_vpc", - "aws_vpc_ipv4_cidr_block_association", - "aws_vpn_connection", - "aws_vpn_connection_route", - "aws_vpn_gateway", - "aws_security_group", - "aws_vpc_security_group_ingress_rule", - "aws_vpc_security_group_egress_rule", - "aws_ec2_managed_prefix_list", - "aws_ec2_transit_gateway", - "aws_ec2_transit_gateway_prefix_list_reference", - "aws_ec2_transit_gateway_vpc_attachment", - "azurerm_application_security_group", - "azurerm_lb", - "azurerm_lb_backend_address_pool", - "azurerm_lb_nat_pool", - "azurerm_lb_nat_rule", - "azurerm_lb_rule", - "azurerm_local_network_gateway", - "azurerm_network_interface", - "azurerm_network_interface_application_security_group_association", - "azurerm_network_interface_backend_address_pool_association", - "azurerm_network_interface_security_group_association", - "azurerm_network_security_group", - "azurerm_public_ip", - "azurerm_route", - "azurerm_route_table", - "azurerm_subnet", - "azurerm_subnet_route_table_association", - "azurerm_virtual_machine", - "azurerm_virtual_network_gateway_connection", - "azurerm_virtual_network", - "azurerm_virtual_network_gateway", - "google_compute_network", - "google_compute_subnetwork", - "google_compute_vpn_gateway", - "google_compute_vpn_tunnel", - "google_compute_route", - "google_compute_address", - "google_compute_global_address", - "google_compute_router", - "google_compute_interconnect_attachment", - "google_compute_ha_vpn_gateway", - "google_compute_forwarding_rule", - "google_compute_network_firewall_policy", - "google_compute_network_firewall_policy_rule", - "cloudflare_static_route", - "cloudflare_ipsec_tunnel", - ] - - title: str - - -class VPCsByIDSectionHiddenItemValueMcnListItemListMcnResourcePreviewItem(BaseModel): - item_type: str - - resource_preview: VPCsByIDSectionHiddenItemValueMcnListItemListMcnResourcePreviewItemResourcePreview - - -VPCsByIDSectionHiddenItemValueMcnListItemList: TypeAlias = Annotated[ - Union[ - VPCsByIDSectionHiddenItemValueMcnListItemListMcnStringItem, - VPCsByIDSectionHiddenItemValueMcnListItemListMcnResourcePreviewItem, - ], - PropertyInfo(discriminator="item_type"), -] - - -class VPCsByIDSectionHiddenItemValueMcnListItem(BaseModel): - item_type: str - - rule_list: List[VPCsByIDSectionHiddenItemValueMcnListItemList] = FieldInfo(alias="list") - - -VPCsByIDSectionHiddenItemValue: TypeAlias = Annotated[ - Union[ - VPCsByIDSectionHiddenItemValueMcnStringItem, - VPCsByIDSectionHiddenItemValueMcnYamlItem, - VPCsByIDSectionHiddenItemValueMcnYamlDiffItem, - VPCsByIDSectionHiddenItemValueMcnResourcePreviewItem, - VPCsByIDSectionHiddenItemValueMcnListItem, - ], - PropertyInfo(discriminator="item_type"), -] - - -class VPCsByIDSectionHiddenItem(BaseModel): - help_text: Optional[str] = FieldInfo(alias="helpText", default=None) - - name: Optional[str] = None - - value: Optional[VPCsByIDSectionHiddenItemValue] = None - - -class VPCsByIDSectionVisibleItemValueMcnStringItem(BaseModel): - item_type: str - - string: str - - -class VPCsByIDSectionVisibleItemValueMcnYamlItem(BaseModel): - item_type: str - - yaml: str - - -class VPCsByIDSectionVisibleItemValueMcnYamlDiffItemYamlDiff(BaseModel): - diff: str - - left_description: str - - left_yaml: str - - right_description: str - - right_yaml: str - - -class VPCsByIDSectionVisibleItemValueMcnYamlDiffItem(BaseModel): - item_type: str - - yaml_diff: VPCsByIDSectionVisibleItemValueMcnYamlDiffItemYamlDiff - - -class VPCsByIDSectionVisibleItemValueMcnResourcePreviewItemResourcePreview(BaseModel): - id: str - - cloud_type: Literal["AWS", "AZURE", "GOOGLE", "CLOUDFLARE"] - - detail: str - - name: str - - resource_type: Literal[ - "aws_customer_gateway", - "aws_egress_only_internet_gateway", - "aws_internet_gateway", - "aws_instance", - "aws_network_interface", - "aws_route", - "aws_route_table", - "aws_route_table_association", - "aws_subnet", - "aws_vpc", - "aws_vpc_ipv4_cidr_block_association", - "aws_vpn_connection", - "aws_vpn_connection_route", - "aws_vpn_gateway", - "aws_security_group", - "aws_vpc_security_group_ingress_rule", - "aws_vpc_security_group_egress_rule", - "aws_ec2_managed_prefix_list", - "aws_ec2_transit_gateway", - "aws_ec2_transit_gateway_prefix_list_reference", - "aws_ec2_transit_gateway_vpc_attachment", - "azurerm_application_security_group", - "azurerm_lb", - "azurerm_lb_backend_address_pool", - "azurerm_lb_nat_pool", - "azurerm_lb_nat_rule", - "azurerm_lb_rule", - "azurerm_local_network_gateway", - "azurerm_network_interface", - "azurerm_network_interface_application_security_group_association", - "azurerm_network_interface_backend_address_pool_association", - "azurerm_network_interface_security_group_association", - "azurerm_network_security_group", - "azurerm_public_ip", - "azurerm_route", - "azurerm_route_table", - "azurerm_subnet", - "azurerm_subnet_route_table_association", - "azurerm_virtual_machine", - "azurerm_virtual_network_gateway_connection", - "azurerm_virtual_network", - "azurerm_virtual_network_gateway", - "google_compute_network", - "google_compute_subnetwork", - "google_compute_vpn_gateway", - "google_compute_vpn_tunnel", - "google_compute_route", - "google_compute_address", - "google_compute_global_address", - "google_compute_router", - "google_compute_interconnect_attachment", - "google_compute_ha_vpn_gateway", - "google_compute_forwarding_rule", - "google_compute_network_firewall_policy", - "google_compute_network_firewall_policy_rule", - "cloudflare_static_route", - "cloudflare_ipsec_tunnel", - ] - - title: str - - -class VPCsByIDSectionVisibleItemValueMcnResourcePreviewItem(BaseModel): - item_type: str - - resource_preview: VPCsByIDSectionVisibleItemValueMcnResourcePreviewItemResourcePreview - - -class VPCsByIDSectionVisibleItemValueMcnListItemListMcnStringItem(BaseModel): - item_type: str - - string: str - - -class VPCsByIDSectionVisibleItemValueMcnListItemListMcnResourcePreviewItemResourcePreview(BaseModel): - id: str - - cloud_type: Literal["AWS", "AZURE", "GOOGLE", "CLOUDFLARE"] - - detail: str - - name: str - - resource_type: Literal[ - "aws_customer_gateway", - "aws_egress_only_internet_gateway", - "aws_internet_gateway", - "aws_instance", - "aws_network_interface", - "aws_route", - "aws_route_table", - "aws_route_table_association", - "aws_subnet", - "aws_vpc", - "aws_vpc_ipv4_cidr_block_association", - "aws_vpn_connection", - "aws_vpn_connection_route", - "aws_vpn_gateway", - "aws_security_group", - "aws_vpc_security_group_ingress_rule", - "aws_vpc_security_group_egress_rule", - "aws_ec2_managed_prefix_list", - "aws_ec2_transit_gateway", - "aws_ec2_transit_gateway_prefix_list_reference", - "aws_ec2_transit_gateway_vpc_attachment", - "azurerm_application_security_group", - "azurerm_lb", - "azurerm_lb_backend_address_pool", - "azurerm_lb_nat_pool", - "azurerm_lb_nat_rule", - "azurerm_lb_rule", - "azurerm_local_network_gateway", - "azurerm_network_interface", - "azurerm_network_interface_application_security_group_association", - "azurerm_network_interface_backend_address_pool_association", - "azurerm_network_interface_security_group_association", - "azurerm_network_security_group", - "azurerm_public_ip", - "azurerm_route", - "azurerm_route_table", - "azurerm_subnet", - "azurerm_subnet_route_table_association", - "azurerm_virtual_machine", - "azurerm_virtual_network_gateway_connection", - "azurerm_virtual_network", - "azurerm_virtual_network_gateway", - "google_compute_network", - "google_compute_subnetwork", - "google_compute_vpn_gateway", - "google_compute_vpn_tunnel", - "google_compute_route", - "google_compute_address", - "google_compute_global_address", - "google_compute_router", - "google_compute_interconnect_attachment", - "google_compute_ha_vpn_gateway", - "google_compute_forwarding_rule", - "google_compute_network_firewall_policy", - "google_compute_network_firewall_policy_rule", - "cloudflare_static_route", - "cloudflare_ipsec_tunnel", - ] - - title: str - - -class VPCsByIDSectionVisibleItemValueMcnListItemListMcnResourcePreviewItem(BaseModel): - item_type: str - - resource_preview: VPCsByIDSectionVisibleItemValueMcnListItemListMcnResourcePreviewItemResourcePreview - - -VPCsByIDSectionVisibleItemValueMcnListItemList: TypeAlias = Annotated[ - Union[ - VPCsByIDSectionVisibleItemValueMcnListItemListMcnStringItem, - VPCsByIDSectionVisibleItemValueMcnListItemListMcnResourcePreviewItem, - ], - PropertyInfo(discriminator="item_type"), -] - - -class VPCsByIDSectionVisibleItemValueMcnListItem(BaseModel): - item_type: str - - rule_list: List[VPCsByIDSectionVisibleItemValueMcnListItemList] = FieldInfo(alias="list") - - -VPCsByIDSectionVisibleItemValue: TypeAlias = Annotated[ - Union[ - VPCsByIDSectionVisibleItemValueMcnStringItem, - VPCsByIDSectionVisibleItemValueMcnYamlItem, - VPCsByIDSectionVisibleItemValueMcnYamlDiffItem, - VPCsByIDSectionVisibleItemValueMcnResourcePreviewItem, - VPCsByIDSectionVisibleItemValueMcnListItem, - ], - PropertyInfo(discriminator="item_type"), -] - - -class VPCsByIDSectionVisibleItem(BaseModel): - help_text: Optional[str] = FieldInfo(alias="helpText", default=None) - - name: Optional[str] = None - - value: Optional[VPCsByIDSectionVisibleItemValue] = None - - -class VPCsByIDSection(BaseModel): - hidden_items: List[VPCsByIDSectionHiddenItem] - - name: str - - visible_items: List[VPCsByIDSectionVisibleItem] - - help_text: Optional[str] = None - - -class VPCsByIDManagedBy(BaseModel): - id: str - - client_type: Literal["MAGIC_WAN_CLOUD_ONRAMP"] - - name: str - - -class VPCsByID(BaseModel): - id: str - - account_id: str - - cloud_type: Literal["AWS", "AZURE", "GOOGLE", "CLOUDFLARE"] - - config: Dict[str, object] - - deployment_provider: str - - managed: bool - - monthly_cost_estimate: VPCsByIDMonthlyCostEstimate - - name: str - - native_id: str - - observations: Dict[str, VPCsByIDObservations] - - provider_ids: List[str] - - provider_names_by_id: Dict[str, str] - - region: str - - resource_group: str - - resource_type: Literal[ - "aws_customer_gateway", - "aws_egress_only_internet_gateway", - "aws_internet_gateway", - "aws_instance", - "aws_network_interface", - "aws_route", - "aws_route_table", - "aws_route_table_association", - "aws_subnet", - "aws_vpc", - "aws_vpc_ipv4_cidr_block_association", - "aws_vpn_connection", - "aws_vpn_connection_route", - "aws_vpn_gateway", - "aws_security_group", - "aws_vpc_security_group_ingress_rule", - "aws_vpc_security_group_egress_rule", - "aws_ec2_managed_prefix_list", - "aws_ec2_transit_gateway", - "aws_ec2_transit_gateway_prefix_list_reference", - "aws_ec2_transit_gateway_vpc_attachment", - "azurerm_application_security_group", - "azurerm_lb", - "azurerm_lb_backend_address_pool", - "azurerm_lb_nat_pool", - "azurerm_lb_nat_rule", - "azurerm_lb_rule", - "azurerm_local_network_gateway", - "azurerm_network_interface", - "azurerm_network_interface_application_security_group_association", - "azurerm_network_interface_backend_address_pool_association", - "azurerm_network_interface_security_group_association", - "azurerm_network_security_group", - "azurerm_public_ip", - "azurerm_route", - "azurerm_route_table", - "azurerm_subnet", - "azurerm_subnet_route_table_association", - "azurerm_virtual_machine", - "azurerm_virtual_network_gateway_connection", - "azurerm_virtual_network", - "azurerm_virtual_network_gateway", - "google_compute_network", - "google_compute_subnetwork", - "google_compute_vpn_gateway", - "google_compute_vpn_tunnel", - "google_compute_route", - "google_compute_address", - "google_compute_global_address", - "google_compute_router", - "google_compute_interconnect_attachment", - "google_compute_ha_vpn_gateway", - "google_compute_forwarding_rule", - "google_compute_network_firewall_policy", - "google_compute_network_firewall_policy_rule", - "cloudflare_static_route", - "cloudflare_ipsec_tunnel", - ] - - sections: List[VPCsByIDSection] - - state: Dict[str, object] - - tags: Dict[str, str] - - updated_at: str - - url: str - - managed_by: Optional[List[VPCsByIDManagedBy]] = None - - -class OnRampUpdateResponse(BaseModel): - id: str - - cloud_type: Literal["AWS", "AZURE", "GOOGLE"] - - dynamic_routing: bool - - install_routes_in_cloud: bool - - install_routes_in_magic_wan: bool - - name: str - - type: Literal["OnrampTypeSingle", "OnrampTypeHub"] - - updated_at: str - - attached_hubs: Optional[List[str]] = None - - attached_vpcs: Optional[List[str]] = None - - cloud_asn: Optional[int] = None - - description: Optional[str] = None - - hub: Optional[str] = None - - last_applied_at: Optional[str] = None - - last_exported_at: Optional[str] = None - - last_planned_at: Optional[str] = None - - manage_hub_to_hub_attachments: Optional[bool] = None - - manage_vpc_to_hub_attachments: Optional[bool] = None - - planned_monthly_cost_estimate: Optional[PlannedMonthlyCostEstimate] = None - - planned_resources: Optional[List[PlannedResource]] = None - - planned_resources_unavailable: Optional[bool] = None - - post_apply_monthly_cost_estimate: Optional[PostApplyMonthlyCostEstimate] = None - - post_apply_resources: Optional[Dict[str, PostApplyResources]] = None - - post_apply_resources_unavailable: Optional[bool] = None - - region: Optional[str] = None - - status: Optional[Status] = None - - vpc: Optional[str] = None - - vpcs_by_id: Optional[Dict[str, VPCsByID]] = None - - vpcs_by_id_unavailable: Optional[List[str]] = None - """The list of vpc IDs for which resource details failed to generate.""" diff --git a/src/cloudflare/types/magic_cloud_networking/on_ramps/__init__.py b/src/cloudflare/types/magic_cloud_networking/on_ramps/__init__.py deleted file mode 100644 index 08b228458d1..00000000000 --- a/src/cloudflare/types/magic_cloud_networking/on_ramps/__init__.py +++ /dev/null @@ -1,9 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from .address_space_edit_params import AddressSpaceEditParams as AddressSpaceEditParams -from .address_space_edit_response import AddressSpaceEditResponse as AddressSpaceEditResponse -from .address_space_list_response import AddressSpaceListResponse as AddressSpaceListResponse -from .address_space_update_params import AddressSpaceUpdateParams as AddressSpaceUpdateParams -from .address_space_update_response import AddressSpaceUpdateResponse as AddressSpaceUpdateResponse diff --git a/src/cloudflare/types/magic_cloud_networking/on_ramps/address_space_edit_params.py b/src/cloudflare/types/magic_cloud_networking/on_ramps/address_space_edit_params.py deleted file mode 100644 index 09fc69ad5fa..00000000000 --- a/src/cloudflare/types/magic_cloud_networking/on_ramps/address_space_edit_params.py +++ /dev/null @@ -1,15 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing_extensions import Required, TypedDict - -from ...._types import SequenceNotStr - -__all__ = ["AddressSpaceEditParams"] - - -class AddressSpaceEditParams(TypedDict, total=False): - account_id: Required[str] - - prefixes: Required[SequenceNotStr[str]] diff --git a/src/cloudflare/types/magic_cloud_networking/on_ramps/address_space_edit_response.py b/src/cloudflare/types/magic_cloud_networking/on_ramps/address_space_edit_response.py deleted file mode 100644 index 636524b2790..00000000000 --- a/src/cloudflare/types/magic_cloud_networking/on_ramps/address_space_edit_response.py +++ /dev/null @@ -1,11 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from typing import List - -from ...._models import BaseModel - -__all__ = ["AddressSpaceEditResponse"] - - -class AddressSpaceEditResponse(BaseModel): - prefixes: List[str] diff --git a/src/cloudflare/types/magic_cloud_networking/on_ramps/address_space_list_response.py b/src/cloudflare/types/magic_cloud_networking/on_ramps/address_space_list_response.py deleted file mode 100644 index 31912818236..00000000000 --- a/src/cloudflare/types/magic_cloud_networking/on_ramps/address_space_list_response.py +++ /dev/null @@ -1,11 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from typing import List - -from ...._models import BaseModel - -__all__ = ["AddressSpaceListResponse"] - - -class AddressSpaceListResponse(BaseModel): - prefixes: List[str] diff --git a/src/cloudflare/types/magic_cloud_networking/on_ramps/address_space_update_params.py b/src/cloudflare/types/magic_cloud_networking/on_ramps/address_space_update_params.py deleted file mode 100644 index ed1ef67b196..00000000000 --- a/src/cloudflare/types/magic_cloud_networking/on_ramps/address_space_update_params.py +++ /dev/null @@ -1,15 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing_extensions import Required, TypedDict - -from ...._types import SequenceNotStr - -__all__ = ["AddressSpaceUpdateParams"] - - -class AddressSpaceUpdateParams(TypedDict, total=False): - account_id: Required[str] - - prefixes: Required[SequenceNotStr[str]] diff --git a/src/cloudflare/types/magic_cloud_networking/on_ramps/address_space_update_response.py b/src/cloudflare/types/magic_cloud_networking/on_ramps/address_space_update_response.py deleted file mode 100644 index b6277529be4..00000000000 --- a/src/cloudflare/types/magic_cloud_networking/on_ramps/address_space_update_response.py +++ /dev/null @@ -1,11 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from typing import List - -from ...._models import BaseModel - -__all__ = ["AddressSpaceUpdateResponse"] - - -class AddressSpaceUpdateResponse(BaseModel): - prefixes: List[str] diff --git a/src/cloudflare/types/magic_cloud_networking/resource_export_params.py b/src/cloudflare/types/magic_cloud_networking/resource_export_params.py deleted file mode 100644 index 73d6753fcc2..00000000000 --- a/src/cloudflare/types/magic_cloud_networking/resource_export_params.py +++ /dev/null @@ -1,93 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing import List -from typing_extensions import Literal, Required, TypedDict - -from ..._types import SequenceNotStr - -__all__ = ["ResourceExportParams"] - - -class ResourceExportParams(TypedDict, total=False): - account_id: Required[str] - - desc: bool - - order_by: str - """One of ["id", "resource_type", "region"].""" - - provider_id: str - - region: str - - resource_group: str - - resource_id: SequenceNotStr[str] - - resource_type: List[ - Literal[ - "aws_customer_gateway", - "aws_egress_only_internet_gateway", - "aws_internet_gateway", - "aws_instance", - "aws_network_interface", - "aws_route", - "aws_route_table", - "aws_route_table_association", - "aws_subnet", - "aws_vpc", - "aws_vpc_ipv4_cidr_block_association", - "aws_vpn_connection", - "aws_vpn_connection_route", - "aws_vpn_gateway", - "aws_security_group", - "aws_vpc_security_group_ingress_rule", - "aws_vpc_security_group_egress_rule", - "aws_ec2_managed_prefix_list", - "aws_ec2_transit_gateway", - "aws_ec2_transit_gateway_prefix_list_reference", - "aws_ec2_transit_gateway_vpc_attachment", - "azurerm_application_security_group", - "azurerm_lb", - "azurerm_lb_backend_address_pool", - "azurerm_lb_nat_pool", - "azurerm_lb_nat_rule", - "azurerm_lb_rule", - "azurerm_local_network_gateway", - "azurerm_network_interface", - "azurerm_network_interface_application_security_group_association", - "azurerm_network_interface_backend_address_pool_association", - "azurerm_network_interface_security_group_association", - "azurerm_network_security_group", - "azurerm_public_ip", - "azurerm_route", - "azurerm_route_table", - "azurerm_subnet", - "azurerm_subnet_route_table_association", - "azurerm_virtual_machine", - "azurerm_virtual_network_gateway_connection", - "azurerm_virtual_network", - "azurerm_virtual_network_gateway", - "google_compute_network", - "google_compute_subnetwork", - "google_compute_vpn_gateway", - "google_compute_vpn_tunnel", - "google_compute_route", - "google_compute_address", - "google_compute_global_address", - "google_compute_router", - "google_compute_interconnect_attachment", - "google_compute_ha_vpn_gateway", - "google_compute_forwarding_rule", - "google_compute_network_firewall_policy", - "google_compute_network_firewall_policy_rule", - "cloudflare_static_route", - "cloudflare_ipsec_tunnel", - ] - ] - - search: SequenceNotStr[str] - - v2: bool diff --git a/src/cloudflare/types/magic_cloud_networking/resource_get_params.py b/src/cloudflare/types/magic_cloud_networking/resource_get_params.py deleted file mode 100644 index e3f392e392a..00000000000 --- a/src/cloudflare/types/magic_cloud_networking/resource_get_params.py +++ /dev/null @@ -1,13 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing_extensions import Required, TypedDict - -__all__ = ["ResourceGetParams"] - - -class ResourceGetParams(TypedDict, total=False): - account_id: Required[str] - - v2: bool diff --git a/src/cloudflare/types/magic_cloud_networking/resource_get_response.py b/src/cloudflare/types/magic_cloud_networking/resource_get_response.py deleted file mode 100644 index 54f68907fca..00000000000 --- a/src/cloudflare/types/magic_cloud_networking/resource_get_response.py +++ /dev/null @@ -1,632 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from typing import Dict, List, Union, Optional -from typing_extensions import Literal, Annotated, TypeAlias - -from pydantic import Field as FieldInfo - -from ..._utils import PropertyInfo -from ..._models import BaseModel - -__all__ = [ - "ResourceGetResponse", - "MonthlyCostEstimate", - "Observations", - "Section", - "SectionHiddenItem", - "SectionHiddenItemValue", - "SectionHiddenItemValueMcnStringItem", - "SectionHiddenItemValueMcnYamlItem", - "SectionHiddenItemValueMcnYamlDiffItem", - "SectionHiddenItemValueMcnYamlDiffItemYamlDiff", - "SectionHiddenItemValueMcnResourcePreviewItem", - "SectionHiddenItemValueMcnResourcePreviewItemResourcePreview", - "SectionHiddenItemValueMcnListItem", - "SectionHiddenItemValueMcnListItemList", - "SectionHiddenItemValueMcnListItemListMcnStringItem", - "SectionHiddenItemValueMcnListItemListMcnResourcePreviewItem", - "SectionHiddenItemValueMcnListItemListMcnResourcePreviewItemResourcePreview", - "SectionVisibleItem", - "SectionVisibleItemValue", - "SectionVisibleItemValueMcnStringItem", - "SectionVisibleItemValueMcnYamlItem", - "SectionVisibleItemValueMcnYamlDiffItem", - "SectionVisibleItemValueMcnYamlDiffItemYamlDiff", - "SectionVisibleItemValueMcnResourcePreviewItem", - "SectionVisibleItemValueMcnResourcePreviewItemResourcePreview", - "SectionVisibleItemValueMcnListItem", - "SectionVisibleItemValueMcnListItemList", - "SectionVisibleItemValueMcnListItemListMcnStringItem", - "SectionVisibleItemValueMcnListItemListMcnResourcePreviewItem", - "SectionVisibleItemValueMcnListItemListMcnResourcePreviewItemResourcePreview", - "ManagedBy", -] - - -class MonthlyCostEstimate(BaseModel): - currency: str - - monthly_cost: float - - -class Observations(BaseModel): - first_observed_at: str - - last_observed_at: str - - provider_id: str - - resource_id: str - - -class SectionHiddenItemValueMcnStringItem(BaseModel): - item_type: str - - string: str - - -class SectionHiddenItemValueMcnYamlItem(BaseModel): - item_type: str - - yaml: str - - -class SectionHiddenItemValueMcnYamlDiffItemYamlDiff(BaseModel): - diff: str - - left_description: str - - left_yaml: str - - right_description: str - - right_yaml: str - - -class SectionHiddenItemValueMcnYamlDiffItem(BaseModel): - item_type: str - - yaml_diff: SectionHiddenItemValueMcnYamlDiffItemYamlDiff - - -class SectionHiddenItemValueMcnResourcePreviewItemResourcePreview(BaseModel): - id: str - - cloud_type: Literal["AWS", "AZURE", "GOOGLE", "CLOUDFLARE"] - - detail: str - - name: str - - resource_type: Literal[ - "aws_customer_gateway", - "aws_egress_only_internet_gateway", - "aws_internet_gateway", - "aws_instance", - "aws_network_interface", - "aws_route", - "aws_route_table", - "aws_route_table_association", - "aws_subnet", - "aws_vpc", - "aws_vpc_ipv4_cidr_block_association", - "aws_vpn_connection", - "aws_vpn_connection_route", - "aws_vpn_gateway", - "aws_security_group", - "aws_vpc_security_group_ingress_rule", - "aws_vpc_security_group_egress_rule", - "aws_ec2_managed_prefix_list", - "aws_ec2_transit_gateway", - "aws_ec2_transit_gateway_prefix_list_reference", - "aws_ec2_transit_gateway_vpc_attachment", - "azurerm_application_security_group", - "azurerm_lb", - "azurerm_lb_backend_address_pool", - "azurerm_lb_nat_pool", - "azurerm_lb_nat_rule", - "azurerm_lb_rule", - "azurerm_local_network_gateway", - "azurerm_network_interface", - "azurerm_network_interface_application_security_group_association", - "azurerm_network_interface_backend_address_pool_association", - "azurerm_network_interface_security_group_association", - "azurerm_network_security_group", - "azurerm_public_ip", - "azurerm_route", - "azurerm_route_table", - "azurerm_subnet", - "azurerm_subnet_route_table_association", - "azurerm_virtual_machine", - "azurerm_virtual_network_gateway_connection", - "azurerm_virtual_network", - "azurerm_virtual_network_gateway", - "google_compute_network", - "google_compute_subnetwork", - "google_compute_vpn_gateway", - "google_compute_vpn_tunnel", - "google_compute_route", - "google_compute_address", - "google_compute_global_address", - "google_compute_router", - "google_compute_interconnect_attachment", - "google_compute_ha_vpn_gateway", - "google_compute_forwarding_rule", - "google_compute_network_firewall_policy", - "google_compute_network_firewall_policy_rule", - "cloudflare_static_route", - "cloudflare_ipsec_tunnel", - ] - - title: str - - -class SectionHiddenItemValueMcnResourcePreviewItem(BaseModel): - item_type: str - - resource_preview: SectionHiddenItemValueMcnResourcePreviewItemResourcePreview - - -class SectionHiddenItemValueMcnListItemListMcnStringItem(BaseModel): - item_type: str - - string: str - - -class SectionHiddenItemValueMcnListItemListMcnResourcePreviewItemResourcePreview(BaseModel): - id: str - - cloud_type: Literal["AWS", "AZURE", "GOOGLE", "CLOUDFLARE"] - - detail: str - - name: str - - resource_type: Literal[ - "aws_customer_gateway", - "aws_egress_only_internet_gateway", - "aws_internet_gateway", - "aws_instance", - "aws_network_interface", - "aws_route", - "aws_route_table", - "aws_route_table_association", - "aws_subnet", - "aws_vpc", - "aws_vpc_ipv4_cidr_block_association", - "aws_vpn_connection", - "aws_vpn_connection_route", - "aws_vpn_gateway", - "aws_security_group", - "aws_vpc_security_group_ingress_rule", - "aws_vpc_security_group_egress_rule", - "aws_ec2_managed_prefix_list", - "aws_ec2_transit_gateway", - "aws_ec2_transit_gateway_prefix_list_reference", - "aws_ec2_transit_gateway_vpc_attachment", - "azurerm_application_security_group", - "azurerm_lb", - "azurerm_lb_backend_address_pool", - "azurerm_lb_nat_pool", - "azurerm_lb_nat_rule", - "azurerm_lb_rule", - "azurerm_local_network_gateway", - "azurerm_network_interface", - "azurerm_network_interface_application_security_group_association", - "azurerm_network_interface_backend_address_pool_association", - "azurerm_network_interface_security_group_association", - "azurerm_network_security_group", - "azurerm_public_ip", - "azurerm_route", - "azurerm_route_table", - "azurerm_subnet", - "azurerm_subnet_route_table_association", - "azurerm_virtual_machine", - "azurerm_virtual_network_gateway_connection", - "azurerm_virtual_network", - "azurerm_virtual_network_gateway", - "google_compute_network", - "google_compute_subnetwork", - "google_compute_vpn_gateway", - "google_compute_vpn_tunnel", - "google_compute_route", - "google_compute_address", - "google_compute_global_address", - "google_compute_router", - "google_compute_interconnect_attachment", - "google_compute_ha_vpn_gateway", - "google_compute_forwarding_rule", - "google_compute_network_firewall_policy", - "google_compute_network_firewall_policy_rule", - "cloudflare_static_route", - "cloudflare_ipsec_tunnel", - ] - - title: str - - -class SectionHiddenItemValueMcnListItemListMcnResourcePreviewItem(BaseModel): - item_type: str - - resource_preview: SectionHiddenItemValueMcnListItemListMcnResourcePreviewItemResourcePreview - - -SectionHiddenItemValueMcnListItemList: TypeAlias = Annotated[ - Union[ - SectionHiddenItemValueMcnListItemListMcnStringItem, SectionHiddenItemValueMcnListItemListMcnResourcePreviewItem - ], - PropertyInfo(discriminator="item_type"), -] - - -class SectionHiddenItemValueMcnListItem(BaseModel): - item_type: str - - rule_list: List[SectionHiddenItemValueMcnListItemList] = FieldInfo(alias="list") - - -SectionHiddenItemValue: TypeAlias = Annotated[ - Union[ - SectionHiddenItemValueMcnStringItem, - SectionHiddenItemValueMcnYamlItem, - SectionHiddenItemValueMcnYamlDiffItem, - SectionHiddenItemValueMcnResourcePreviewItem, - SectionHiddenItemValueMcnListItem, - ], - PropertyInfo(discriminator="item_type"), -] - - -class SectionHiddenItem(BaseModel): - help_text: Optional[str] = FieldInfo(alias="helpText", default=None) - - name: Optional[str] = None - - value: Optional[SectionHiddenItemValue] = None - - -class SectionVisibleItemValueMcnStringItem(BaseModel): - item_type: str - - string: str - - -class SectionVisibleItemValueMcnYamlItem(BaseModel): - item_type: str - - yaml: str - - -class SectionVisibleItemValueMcnYamlDiffItemYamlDiff(BaseModel): - diff: str - - left_description: str - - left_yaml: str - - right_description: str - - right_yaml: str - - -class SectionVisibleItemValueMcnYamlDiffItem(BaseModel): - item_type: str - - yaml_diff: SectionVisibleItemValueMcnYamlDiffItemYamlDiff - - -class SectionVisibleItemValueMcnResourcePreviewItemResourcePreview(BaseModel): - id: str - - cloud_type: Literal["AWS", "AZURE", "GOOGLE", "CLOUDFLARE"] - - detail: str - - name: str - - resource_type: Literal[ - "aws_customer_gateway", - "aws_egress_only_internet_gateway", - "aws_internet_gateway", - "aws_instance", - "aws_network_interface", - "aws_route", - "aws_route_table", - "aws_route_table_association", - "aws_subnet", - "aws_vpc", - "aws_vpc_ipv4_cidr_block_association", - "aws_vpn_connection", - "aws_vpn_connection_route", - "aws_vpn_gateway", - "aws_security_group", - "aws_vpc_security_group_ingress_rule", - "aws_vpc_security_group_egress_rule", - "aws_ec2_managed_prefix_list", - "aws_ec2_transit_gateway", - "aws_ec2_transit_gateway_prefix_list_reference", - "aws_ec2_transit_gateway_vpc_attachment", - "azurerm_application_security_group", - "azurerm_lb", - "azurerm_lb_backend_address_pool", - "azurerm_lb_nat_pool", - "azurerm_lb_nat_rule", - "azurerm_lb_rule", - "azurerm_local_network_gateway", - "azurerm_network_interface", - "azurerm_network_interface_application_security_group_association", - "azurerm_network_interface_backend_address_pool_association", - "azurerm_network_interface_security_group_association", - "azurerm_network_security_group", - "azurerm_public_ip", - "azurerm_route", - "azurerm_route_table", - "azurerm_subnet", - "azurerm_subnet_route_table_association", - "azurerm_virtual_machine", - "azurerm_virtual_network_gateway_connection", - "azurerm_virtual_network", - "azurerm_virtual_network_gateway", - "google_compute_network", - "google_compute_subnetwork", - "google_compute_vpn_gateway", - "google_compute_vpn_tunnel", - "google_compute_route", - "google_compute_address", - "google_compute_global_address", - "google_compute_router", - "google_compute_interconnect_attachment", - "google_compute_ha_vpn_gateway", - "google_compute_forwarding_rule", - "google_compute_network_firewall_policy", - "google_compute_network_firewall_policy_rule", - "cloudflare_static_route", - "cloudflare_ipsec_tunnel", - ] - - title: str - - -class SectionVisibleItemValueMcnResourcePreviewItem(BaseModel): - item_type: str - - resource_preview: SectionVisibleItemValueMcnResourcePreviewItemResourcePreview - - -class SectionVisibleItemValueMcnListItemListMcnStringItem(BaseModel): - item_type: str - - string: str - - -class SectionVisibleItemValueMcnListItemListMcnResourcePreviewItemResourcePreview(BaseModel): - id: str - - cloud_type: Literal["AWS", "AZURE", "GOOGLE", "CLOUDFLARE"] - - detail: str - - name: str - - resource_type: Literal[ - "aws_customer_gateway", - "aws_egress_only_internet_gateway", - "aws_internet_gateway", - "aws_instance", - "aws_network_interface", - "aws_route", - "aws_route_table", - "aws_route_table_association", - "aws_subnet", - "aws_vpc", - "aws_vpc_ipv4_cidr_block_association", - "aws_vpn_connection", - "aws_vpn_connection_route", - "aws_vpn_gateway", - "aws_security_group", - "aws_vpc_security_group_ingress_rule", - "aws_vpc_security_group_egress_rule", - "aws_ec2_managed_prefix_list", - "aws_ec2_transit_gateway", - "aws_ec2_transit_gateway_prefix_list_reference", - "aws_ec2_transit_gateway_vpc_attachment", - "azurerm_application_security_group", - "azurerm_lb", - "azurerm_lb_backend_address_pool", - "azurerm_lb_nat_pool", - "azurerm_lb_nat_rule", - "azurerm_lb_rule", - "azurerm_local_network_gateway", - "azurerm_network_interface", - "azurerm_network_interface_application_security_group_association", - "azurerm_network_interface_backend_address_pool_association", - "azurerm_network_interface_security_group_association", - "azurerm_network_security_group", - "azurerm_public_ip", - "azurerm_route", - "azurerm_route_table", - "azurerm_subnet", - "azurerm_subnet_route_table_association", - "azurerm_virtual_machine", - "azurerm_virtual_network_gateway_connection", - "azurerm_virtual_network", - "azurerm_virtual_network_gateway", - "google_compute_network", - "google_compute_subnetwork", - "google_compute_vpn_gateway", - "google_compute_vpn_tunnel", - "google_compute_route", - "google_compute_address", - "google_compute_global_address", - "google_compute_router", - "google_compute_interconnect_attachment", - "google_compute_ha_vpn_gateway", - "google_compute_forwarding_rule", - "google_compute_network_firewall_policy", - "google_compute_network_firewall_policy_rule", - "cloudflare_static_route", - "cloudflare_ipsec_tunnel", - ] - - title: str - - -class SectionVisibleItemValueMcnListItemListMcnResourcePreviewItem(BaseModel): - item_type: str - - resource_preview: SectionVisibleItemValueMcnListItemListMcnResourcePreviewItemResourcePreview - - -SectionVisibleItemValueMcnListItemList: TypeAlias = Annotated[ - Union[ - SectionVisibleItemValueMcnListItemListMcnStringItem, - SectionVisibleItemValueMcnListItemListMcnResourcePreviewItem, - ], - PropertyInfo(discriminator="item_type"), -] - - -class SectionVisibleItemValueMcnListItem(BaseModel): - item_type: str - - rule_list: List[SectionVisibleItemValueMcnListItemList] = FieldInfo(alias="list") - - -SectionVisibleItemValue: TypeAlias = Annotated[ - Union[ - SectionVisibleItemValueMcnStringItem, - SectionVisibleItemValueMcnYamlItem, - SectionVisibleItemValueMcnYamlDiffItem, - SectionVisibleItemValueMcnResourcePreviewItem, - SectionVisibleItemValueMcnListItem, - ], - PropertyInfo(discriminator="item_type"), -] - - -class SectionVisibleItem(BaseModel): - help_text: Optional[str] = FieldInfo(alias="helpText", default=None) - - name: Optional[str] = None - - value: Optional[SectionVisibleItemValue] = None - - -class Section(BaseModel): - hidden_items: List[SectionHiddenItem] - - name: str - - visible_items: List[SectionVisibleItem] - - help_text: Optional[str] = None - - -class ManagedBy(BaseModel): - id: str - - client_type: Literal["MAGIC_WAN_CLOUD_ONRAMP"] - - name: str - - -class ResourceGetResponse(BaseModel): - id: str - - account_id: str - - cloud_type: Literal["AWS", "AZURE", "GOOGLE", "CLOUDFLARE"] - - config: Dict[str, object] - - deployment_provider: str - - managed: bool - - monthly_cost_estimate: MonthlyCostEstimate - - name: str - - native_id: str - - observations: Dict[str, Observations] - - provider_ids: List[str] - - provider_names_by_id: Dict[str, str] - - region: str - - resource_group: str - - resource_type: Literal[ - "aws_customer_gateway", - "aws_egress_only_internet_gateway", - "aws_internet_gateway", - "aws_instance", - "aws_network_interface", - "aws_route", - "aws_route_table", - "aws_route_table_association", - "aws_subnet", - "aws_vpc", - "aws_vpc_ipv4_cidr_block_association", - "aws_vpn_connection", - "aws_vpn_connection_route", - "aws_vpn_gateway", - "aws_security_group", - "aws_vpc_security_group_ingress_rule", - "aws_vpc_security_group_egress_rule", - "aws_ec2_managed_prefix_list", - "aws_ec2_transit_gateway", - "aws_ec2_transit_gateway_prefix_list_reference", - "aws_ec2_transit_gateway_vpc_attachment", - "azurerm_application_security_group", - "azurerm_lb", - "azurerm_lb_backend_address_pool", - "azurerm_lb_nat_pool", - "azurerm_lb_nat_rule", - "azurerm_lb_rule", - "azurerm_local_network_gateway", - "azurerm_network_interface", - "azurerm_network_interface_application_security_group_association", - "azurerm_network_interface_backend_address_pool_association", - "azurerm_network_interface_security_group_association", - "azurerm_network_security_group", - "azurerm_public_ip", - "azurerm_route", - "azurerm_route_table", - "azurerm_subnet", - "azurerm_subnet_route_table_association", - "azurerm_virtual_machine", - "azurerm_virtual_network_gateway_connection", - "azurerm_virtual_network", - "azurerm_virtual_network_gateway", - "google_compute_network", - "google_compute_subnetwork", - "google_compute_vpn_gateway", - "google_compute_vpn_tunnel", - "google_compute_route", - "google_compute_address", - "google_compute_global_address", - "google_compute_router", - "google_compute_interconnect_attachment", - "google_compute_ha_vpn_gateway", - "google_compute_forwarding_rule", - "google_compute_network_firewall_policy", - "google_compute_network_firewall_policy_rule", - "cloudflare_static_route", - "cloudflare_ipsec_tunnel", - ] - - sections: List[Section] - - state: Dict[str, object] - - tags: Dict[str, str] - - updated_at: str - - url: str - - managed_by: Optional[List[ManagedBy]] = None diff --git a/src/cloudflare/types/magic_cloud_networking/resource_list_params.py b/src/cloudflare/types/magic_cloud_networking/resource_list_params.py deleted file mode 100644 index d48313a1b22..00000000000 --- a/src/cloudflare/types/magic_cloud_networking/resource_list_params.py +++ /dev/null @@ -1,101 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing import List -from typing_extensions import Literal, Required, TypedDict - -from ..._types import SequenceNotStr - -__all__ = ["ResourceListParams"] - - -class ResourceListParams(TypedDict, total=False): - account_id: Required[str] - - cloudflare: bool - - desc: bool - - managed: bool - - order_by: str - """One of ["id", "resource_type", "region"].""" - - page: int - - per_page: int - - provider_id: str - - region: str - - resource_group: str - - resource_id: SequenceNotStr[str] - - resource_type: List[ - Literal[ - "aws_customer_gateway", - "aws_egress_only_internet_gateway", - "aws_internet_gateway", - "aws_instance", - "aws_network_interface", - "aws_route", - "aws_route_table", - "aws_route_table_association", - "aws_subnet", - "aws_vpc", - "aws_vpc_ipv4_cidr_block_association", - "aws_vpn_connection", - "aws_vpn_connection_route", - "aws_vpn_gateway", - "aws_security_group", - "aws_vpc_security_group_ingress_rule", - "aws_vpc_security_group_egress_rule", - "aws_ec2_managed_prefix_list", - "aws_ec2_transit_gateway", - "aws_ec2_transit_gateway_prefix_list_reference", - "aws_ec2_transit_gateway_vpc_attachment", - "azurerm_application_security_group", - "azurerm_lb", - "azurerm_lb_backend_address_pool", - "azurerm_lb_nat_pool", - "azurerm_lb_nat_rule", - "azurerm_lb_rule", - "azurerm_local_network_gateway", - "azurerm_network_interface", - "azurerm_network_interface_application_security_group_association", - "azurerm_network_interface_backend_address_pool_association", - "azurerm_network_interface_security_group_association", - "azurerm_network_security_group", - "azurerm_public_ip", - "azurerm_route", - "azurerm_route_table", - "azurerm_subnet", - "azurerm_subnet_route_table_association", - "azurerm_virtual_machine", - "azurerm_virtual_network_gateway_connection", - "azurerm_virtual_network", - "azurerm_virtual_network_gateway", - "google_compute_network", - "google_compute_subnetwork", - "google_compute_vpn_gateway", - "google_compute_vpn_tunnel", - "google_compute_route", - "google_compute_address", - "google_compute_global_address", - "google_compute_router", - "google_compute_interconnect_attachment", - "google_compute_ha_vpn_gateway", - "google_compute_forwarding_rule", - "google_compute_network_firewall_policy", - "google_compute_network_firewall_policy_rule", - "cloudflare_static_route", - "cloudflare_ipsec_tunnel", - ] - ] - - search: SequenceNotStr[str] - - v2: bool diff --git a/src/cloudflare/types/magic_cloud_networking/resource_list_response.py b/src/cloudflare/types/magic_cloud_networking/resource_list_response.py deleted file mode 100644 index ad52c983732..00000000000 --- a/src/cloudflare/types/magic_cloud_networking/resource_list_response.py +++ /dev/null @@ -1,632 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from typing import Dict, List, Union, Optional -from typing_extensions import Literal, Annotated, TypeAlias - -from pydantic import Field as FieldInfo - -from ..._utils import PropertyInfo -from ..._models import BaseModel - -__all__ = [ - "ResourceListResponse", - "MonthlyCostEstimate", - "Observations", - "Section", - "SectionHiddenItem", - "SectionHiddenItemValue", - "SectionHiddenItemValueMcnStringItem", - "SectionHiddenItemValueMcnYamlItem", - "SectionHiddenItemValueMcnYamlDiffItem", - "SectionHiddenItemValueMcnYamlDiffItemYamlDiff", - "SectionHiddenItemValueMcnResourcePreviewItem", - "SectionHiddenItemValueMcnResourcePreviewItemResourcePreview", - "SectionHiddenItemValueMcnListItem", - "SectionHiddenItemValueMcnListItemList", - "SectionHiddenItemValueMcnListItemListMcnStringItem", - "SectionHiddenItemValueMcnListItemListMcnResourcePreviewItem", - "SectionHiddenItemValueMcnListItemListMcnResourcePreviewItemResourcePreview", - "SectionVisibleItem", - "SectionVisibleItemValue", - "SectionVisibleItemValueMcnStringItem", - "SectionVisibleItemValueMcnYamlItem", - "SectionVisibleItemValueMcnYamlDiffItem", - "SectionVisibleItemValueMcnYamlDiffItemYamlDiff", - "SectionVisibleItemValueMcnResourcePreviewItem", - "SectionVisibleItemValueMcnResourcePreviewItemResourcePreview", - "SectionVisibleItemValueMcnListItem", - "SectionVisibleItemValueMcnListItemList", - "SectionVisibleItemValueMcnListItemListMcnStringItem", - "SectionVisibleItemValueMcnListItemListMcnResourcePreviewItem", - "SectionVisibleItemValueMcnListItemListMcnResourcePreviewItemResourcePreview", - "ManagedBy", -] - - -class MonthlyCostEstimate(BaseModel): - currency: str - - monthly_cost: float - - -class Observations(BaseModel): - first_observed_at: str - - last_observed_at: str - - provider_id: str - - resource_id: str - - -class SectionHiddenItemValueMcnStringItem(BaseModel): - item_type: str - - string: str - - -class SectionHiddenItemValueMcnYamlItem(BaseModel): - item_type: str - - yaml: str - - -class SectionHiddenItemValueMcnYamlDiffItemYamlDiff(BaseModel): - diff: str - - left_description: str - - left_yaml: str - - right_description: str - - right_yaml: str - - -class SectionHiddenItemValueMcnYamlDiffItem(BaseModel): - item_type: str - - yaml_diff: SectionHiddenItemValueMcnYamlDiffItemYamlDiff - - -class SectionHiddenItemValueMcnResourcePreviewItemResourcePreview(BaseModel): - id: str - - cloud_type: Literal["AWS", "AZURE", "GOOGLE", "CLOUDFLARE"] - - detail: str - - name: str - - resource_type: Literal[ - "aws_customer_gateway", - "aws_egress_only_internet_gateway", - "aws_internet_gateway", - "aws_instance", - "aws_network_interface", - "aws_route", - "aws_route_table", - "aws_route_table_association", - "aws_subnet", - "aws_vpc", - "aws_vpc_ipv4_cidr_block_association", - "aws_vpn_connection", - "aws_vpn_connection_route", - "aws_vpn_gateway", - "aws_security_group", - "aws_vpc_security_group_ingress_rule", - "aws_vpc_security_group_egress_rule", - "aws_ec2_managed_prefix_list", - "aws_ec2_transit_gateway", - "aws_ec2_transit_gateway_prefix_list_reference", - "aws_ec2_transit_gateway_vpc_attachment", - "azurerm_application_security_group", - "azurerm_lb", - "azurerm_lb_backend_address_pool", - "azurerm_lb_nat_pool", - "azurerm_lb_nat_rule", - "azurerm_lb_rule", - "azurerm_local_network_gateway", - "azurerm_network_interface", - "azurerm_network_interface_application_security_group_association", - "azurerm_network_interface_backend_address_pool_association", - "azurerm_network_interface_security_group_association", - "azurerm_network_security_group", - "azurerm_public_ip", - "azurerm_route", - "azurerm_route_table", - "azurerm_subnet", - "azurerm_subnet_route_table_association", - "azurerm_virtual_machine", - "azurerm_virtual_network_gateway_connection", - "azurerm_virtual_network", - "azurerm_virtual_network_gateway", - "google_compute_network", - "google_compute_subnetwork", - "google_compute_vpn_gateway", - "google_compute_vpn_tunnel", - "google_compute_route", - "google_compute_address", - "google_compute_global_address", - "google_compute_router", - "google_compute_interconnect_attachment", - "google_compute_ha_vpn_gateway", - "google_compute_forwarding_rule", - "google_compute_network_firewall_policy", - "google_compute_network_firewall_policy_rule", - "cloudflare_static_route", - "cloudflare_ipsec_tunnel", - ] - - title: str - - -class SectionHiddenItemValueMcnResourcePreviewItem(BaseModel): - item_type: str - - resource_preview: SectionHiddenItemValueMcnResourcePreviewItemResourcePreview - - -class SectionHiddenItemValueMcnListItemListMcnStringItem(BaseModel): - item_type: str - - string: str - - -class SectionHiddenItemValueMcnListItemListMcnResourcePreviewItemResourcePreview(BaseModel): - id: str - - cloud_type: Literal["AWS", "AZURE", "GOOGLE", "CLOUDFLARE"] - - detail: str - - name: str - - resource_type: Literal[ - "aws_customer_gateway", - "aws_egress_only_internet_gateway", - "aws_internet_gateway", - "aws_instance", - "aws_network_interface", - "aws_route", - "aws_route_table", - "aws_route_table_association", - "aws_subnet", - "aws_vpc", - "aws_vpc_ipv4_cidr_block_association", - "aws_vpn_connection", - "aws_vpn_connection_route", - "aws_vpn_gateway", - "aws_security_group", - "aws_vpc_security_group_ingress_rule", - "aws_vpc_security_group_egress_rule", - "aws_ec2_managed_prefix_list", - "aws_ec2_transit_gateway", - "aws_ec2_transit_gateway_prefix_list_reference", - "aws_ec2_transit_gateway_vpc_attachment", - "azurerm_application_security_group", - "azurerm_lb", - "azurerm_lb_backend_address_pool", - "azurerm_lb_nat_pool", - "azurerm_lb_nat_rule", - "azurerm_lb_rule", - "azurerm_local_network_gateway", - "azurerm_network_interface", - "azurerm_network_interface_application_security_group_association", - "azurerm_network_interface_backend_address_pool_association", - "azurerm_network_interface_security_group_association", - "azurerm_network_security_group", - "azurerm_public_ip", - "azurerm_route", - "azurerm_route_table", - "azurerm_subnet", - "azurerm_subnet_route_table_association", - "azurerm_virtual_machine", - "azurerm_virtual_network_gateway_connection", - "azurerm_virtual_network", - "azurerm_virtual_network_gateway", - "google_compute_network", - "google_compute_subnetwork", - "google_compute_vpn_gateway", - "google_compute_vpn_tunnel", - "google_compute_route", - "google_compute_address", - "google_compute_global_address", - "google_compute_router", - "google_compute_interconnect_attachment", - "google_compute_ha_vpn_gateway", - "google_compute_forwarding_rule", - "google_compute_network_firewall_policy", - "google_compute_network_firewall_policy_rule", - "cloudflare_static_route", - "cloudflare_ipsec_tunnel", - ] - - title: str - - -class SectionHiddenItemValueMcnListItemListMcnResourcePreviewItem(BaseModel): - item_type: str - - resource_preview: SectionHiddenItemValueMcnListItemListMcnResourcePreviewItemResourcePreview - - -SectionHiddenItemValueMcnListItemList: TypeAlias = Annotated[ - Union[ - SectionHiddenItemValueMcnListItemListMcnStringItem, SectionHiddenItemValueMcnListItemListMcnResourcePreviewItem - ], - PropertyInfo(discriminator="item_type"), -] - - -class SectionHiddenItemValueMcnListItem(BaseModel): - item_type: str - - rule_list: List[SectionHiddenItemValueMcnListItemList] = FieldInfo(alias="list") - - -SectionHiddenItemValue: TypeAlias = Annotated[ - Union[ - SectionHiddenItemValueMcnStringItem, - SectionHiddenItemValueMcnYamlItem, - SectionHiddenItemValueMcnYamlDiffItem, - SectionHiddenItemValueMcnResourcePreviewItem, - SectionHiddenItemValueMcnListItem, - ], - PropertyInfo(discriminator="item_type"), -] - - -class SectionHiddenItem(BaseModel): - help_text: Optional[str] = FieldInfo(alias="helpText", default=None) - - name: Optional[str] = None - - value: Optional[SectionHiddenItemValue] = None - - -class SectionVisibleItemValueMcnStringItem(BaseModel): - item_type: str - - string: str - - -class SectionVisibleItemValueMcnYamlItem(BaseModel): - item_type: str - - yaml: str - - -class SectionVisibleItemValueMcnYamlDiffItemYamlDiff(BaseModel): - diff: str - - left_description: str - - left_yaml: str - - right_description: str - - right_yaml: str - - -class SectionVisibleItemValueMcnYamlDiffItem(BaseModel): - item_type: str - - yaml_diff: SectionVisibleItemValueMcnYamlDiffItemYamlDiff - - -class SectionVisibleItemValueMcnResourcePreviewItemResourcePreview(BaseModel): - id: str - - cloud_type: Literal["AWS", "AZURE", "GOOGLE", "CLOUDFLARE"] - - detail: str - - name: str - - resource_type: Literal[ - "aws_customer_gateway", - "aws_egress_only_internet_gateway", - "aws_internet_gateway", - "aws_instance", - "aws_network_interface", - "aws_route", - "aws_route_table", - "aws_route_table_association", - "aws_subnet", - "aws_vpc", - "aws_vpc_ipv4_cidr_block_association", - "aws_vpn_connection", - "aws_vpn_connection_route", - "aws_vpn_gateway", - "aws_security_group", - "aws_vpc_security_group_ingress_rule", - "aws_vpc_security_group_egress_rule", - "aws_ec2_managed_prefix_list", - "aws_ec2_transit_gateway", - "aws_ec2_transit_gateway_prefix_list_reference", - "aws_ec2_transit_gateway_vpc_attachment", - "azurerm_application_security_group", - "azurerm_lb", - "azurerm_lb_backend_address_pool", - "azurerm_lb_nat_pool", - "azurerm_lb_nat_rule", - "azurerm_lb_rule", - "azurerm_local_network_gateway", - "azurerm_network_interface", - "azurerm_network_interface_application_security_group_association", - "azurerm_network_interface_backend_address_pool_association", - "azurerm_network_interface_security_group_association", - "azurerm_network_security_group", - "azurerm_public_ip", - "azurerm_route", - "azurerm_route_table", - "azurerm_subnet", - "azurerm_subnet_route_table_association", - "azurerm_virtual_machine", - "azurerm_virtual_network_gateway_connection", - "azurerm_virtual_network", - "azurerm_virtual_network_gateway", - "google_compute_network", - "google_compute_subnetwork", - "google_compute_vpn_gateway", - "google_compute_vpn_tunnel", - "google_compute_route", - "google_compute_address", - "google_compute_global_address", - "google_compute_router", - "google_compute_interconnect_attachment", - "google_compute_ha_vpn_gateway", - "google_compute_forwarding_rule", - "google_compute_network_firewall_policy", - "google_compute_network_firewall_policy_rule", - "cloudflare_static_route", - "cloudflare_ipsec_tunnel", - ] - - title: str - - -class SectionVisibleItemValueMcnResourcePreviewItem(BaseModel): - item_type: str - - resource_preview: SectionVisibleItemValueMcnResourcePreviewItemResourcePreview - - -class SectionVisibleItemValueMcnListItemListMcnStringItem(BaseModel): - item_type: str - - string: str - - -class SectionVisibleItemValueMcnListItemListMcnResourcePreviewItemResourcePreview(BaseModel): - id: str - - cloud_type: Literal["AWS", "AZURE", "GOOGLE", "CLOUDFLARE"] - - detail: str - - name: str - - resource_type: Literal[ - "aws_customer_gateway", - "aws_egress_only_internet_gateway", - "aws_internet_gateway", - "aws_instance", - "aws_network_interface", - "aws_route", - "aws_route_table", - "aws_route_table_association", - "aws_subnet", - "aws_vpc", - "aws_vpc_ipv4_cidr_block_association", - "aws_vpn_connection", - "aws_vpn_connection_route", - "aws_vpn_gateway", - "aws_security_group", - "aws_vpc_security_group_ingress_rule", - "aws_vpc_security_group_egress_rule", - "aws_ec2_managed_prefix_list", - "aws_ec2_transit_gateway", - "aws_ec2_transit_gateway_prefix_list_reference", - "aws_ec2_transit_gateway_vpc_attachment", - "azurerm_application_security_group", - "azurerm_lb", - "azurerm_lb_backend_address_pool", - "azurerm_lb_nat_pool", - "azurerm_lb_nat_rule", - "azurerm_lb_rule", - "azurerm_local_network_gateway", - "azurerm_network_interface", - "azurerm_network_interface_application_security_group_association", - "azurerm_network_interface_backend_address_pool_association", - "azurerm_network_interface_security_group_association", - "azurerm_network_security_group", - "azurerm_public_ip", - "azurerm_route", - "azurerm_route_table", - "azurerm_subnet", - "azurerm_subnet_route_table_association", - "azurerm_virtual_machine", - "azurerm_virtual_network_gateway_connection", - "azurerm_virtual_network", - "azurerm_virtual_network_gateway", - "google_compute_network", - "google_compute_subnetwork", - "google_compute_vpn_gateway", - "google_compute_vpn_tunnel", - "google_compute_route", - "google_compute_address", - "google_compute_global_address", - "google_compute_router", - "google_compute_interconnect_attachment", - "google_compute_ha_vpn_gateway", - "google_compute_forwarding_rule", - "google_compute_network_firewall_policy", - "google_compute_network_firewall_policy_rule", - "cloudflare_static_route", - "cloudflare_ipsec_tunnel", - ] - - title: str - - -class SectionVisibleItemValueMcnListItemListMcnResourcePreviewItem(BaseModel): - item_type: str - - resource_preview: SectionVisibleItemValueMcnListItemListMcnResourcePreviewItemResourcePreview - - -SectionVisibleItemValueMcnListItemList: TypeAlias = Annotated[ - Union[ - SectionVisibleItemValueMcnListItemListMcnStringItem, - SectionVisibleItemValueMcnListItemListMcnResourcePreviewItem, - ], - PropertyInfo(discriminator="item_type"), -] - - -class SectionVisibleItemValueMcnListItem(BaseModel): - item_type: str - - rule_list: List[SectionVisibleItemValueMcnListItemList] = FieldInfo(alias="list") - - -SectionVisibleItemValue: TypeAlias = Annotated[ - Union[ - SectionVisibleItemValueMcnStringItem, - SectionVisibleItemValueMcnYamlItem, - SectionVisibleItemValueMcnYamlDiffItem, - SectionVisibleItemValueMcnResourcePreviewItem, - SectionVisibleItemValueMcnListItem, - ], - PropertyInfo(discriminator="item_type"), -] - - -class SectionVisibleItem(BaseModel): - help_text: Optional[str] = FieldInfo(alias="helpText", default=None) - - name: Optional[str] = None - - value: Optional[SectionVisibleItemValue] = None - - -class Section(BaseModel): - hidden_items: List[SectionHiddenItem] - - name: str - - visible_items: List[SectionVisibleItem] - - help_text: Optional[str] = None - - -class ManagedBy(BaseModel): - id: str - - client_type: Literal["MAGIC_WAN_CLOUD_ONRAMP"] - - name: str - - -class ResourceListResponse(BaseModel): - id: str - - account_id: str - - cloud_type: Literal["AWS", "AZURE", "GOOGLE", "CLOUDFLARE"] - - config: Dict[str, object] - - deployment_provider: str - - managed: bool - - monthly_cost_estimate: MonthlyCostEstimate - - name: str - - native_id: str - - observations: Dict[str, Observations] - - provider_ids: List[str] - - provider_names_by_id: Dict[str, str] - - region: str - - resource_group: str - - resource_type: Literal[ - "aws_customer_gateway", - "aws_egress_only_internet_gateway", - "aws_internet_gateway", - "aws_instance", - "aws_network_interface", - "aws_route", - "aws_route_table", - "aws_route_table_association", - "aws_subnet", - "aws_vpc", - "aws_vpc_ipv4_cidr_block_association", - "aws_vpn_connection", - "aws_vpn_connection_route", - "aws_vpn_gateway", - "aws_security_group", - "aws_vpc_security_group_ingress_rule", - "aws_vpc_security_group_egress_rule", - "aws_ec2_managed_prefix_list", - "aws_ec2_transit_gateway", - "aws_ec2_transit_gateway_prefix_list_reference", - "aws_ec2_transit_gateway_vpc_attachment", - "azurerm_application_security_group", - "azurerm_lb", - "azurerm_lb_backend_address_pool", - "azurerm_lb_nat_pool", - "azurerm_lb_nat_rule", - "azurerm_lb_rule", - "azurerm_local_network_gateway", - "azurerm_network_interface", - "azurerm_network_interface_application_security_group_association", - "azurerm_network_interface_backend_address_pool_association", - "azurerm_network_interface_security_group_association", - "azurerm_network_security_group", - "azurerm_public_ip", - "azurerm_route", - "azurerm_route_table", - "azurerm_subnet", - "azurerm_subnet_route_table_association", - "azurerm_virtual_machine", - "azurerm_virtual_network_gateway_connection", - "azurerm_virtual_network", - "azurerm_virtual_network_gateway", - "google_compute_network", - "google_compute_subnetwork", - "google_compute_vpn_gateway", - "google_compute_vpn_tunnel", - "google_compute_route", - "google_compute_address", - "google_compute_global_address", - "google_compute_router", - "google_compute_interconnect_attachment", - "google_compute_ha_vpn_gateway", - "google_compute_forwarding_rule", - "google_compute_network_firewall_policy", - "google_compute_network_firewall_policy_rule", - "cloudflare_static_route", - "cloudflare_ipsec_tunnel", - ] - - sections: List[Section] - - state: Dict[str, object] - - tags: Dict[str, str] - - updated_at: str - - url: str - - managed_by: Optional[List[ManagedBy]] = None diff --git a/src/cloudflare/types/magic_cloud_networking/resource_policy_preview_params.py b/src/cloudflare/types/magic_cloud_networking/resource_policy_preview_params.py deleted file mode 100644 index 81c74c2fef6..00000000000 --- a/src/cloudflare/types/magic_cloud_networking/resource_policy_preview_params.py +++ /dev/null @@ -1,13 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing_extensions import Required, TypedDict - -__all__ = ["ResourcePolicyPreviewParams"] - - -class ResourcePolicyPreviewParams(TypedDict, total=False): - account_id: Required[str] - - policy: Required[str] diff --git a/src/cloudflare/types/magic_cloud_networking/resource_policy_preview_response.py b/src/cloudflare/types/magic_cloud_networking/resource_policy_preview_response.py deleted file mode 100644 index cb86b584190..00000000000 --- a/src/cloudflare/types/magic_cloud_networking/resource_policy_preview_response.py +++ /dev/null @@ -1,7 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from typing_extensions import TypeAlias - -__all__ = ["ResourcePolicyPreviewResponse"] - -ResourcePolicyPreviewResponse: TypeAlias = str diff --git a/src/cloudflare/types/magic_network_monitoring/rules/__init__.py b/src/cloudflare/types/magic_network_monitoring/rules/__init__.py index 776662f22d8..51f2f956105 100644 --- a/src/cloudflare/types/magic_network_monitoring/rules/__init__.py +++ b/src/cloudflare/types/magic_network_monitoring/rules/__init__.py @@ -3,4 +3,3 @@ from __future__ import annotations from .advertisement import Advertisement as Advertisement -from .advertisement_edit_params import AdvertisementEditParams as AdvertisementEditParams diff --git a/src/cloudflare/types/magic_network_monitoring/rules/advertisement_edit_params.py b/src/cloudflare/types/magic_network_monitoring/rules/advertisement_edit_params.py deleted file mode 100644 index ece6f001327..00000000000 --- a/src/cloudflare/types/magic_network_monitoring/rules/advertisement_edit_params.py +++ /dev/null @@ -1,13 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing_extensions import Required, TypedDict - -__all__ = ["AdvertisementEditParams"] - - -class AdvertisementEditParams(TypedDict, total=False): - account_id: Required[str] - - body: Required[object] diff --git a/src/cloudflare/types/magic_transit/cf_interconnect_bulk_update_response.py b/src/cloudflare/types/magic_transit/cf_interconnect_bulk_update_response.py index f9ff04552ab..7a74a95df25 100644 --- a/src/cloudflare/types/magic_transit/cf_interconnect_bulk_update_response.py +++ b/src/cloudflare/types/magic_transit/cf_interconnect_bulk_update_response.py @@ -37,8 +37,10 @@ class ModifiedInterconnectBGP(BaseModel): extra_prefixes: Optional[List[str]] = None """ - Prefixes in this list will be advertised to the customer device, in addition to - the routes in the Magic routing table. + IPv4 prefixes in this list will be advertised to the customer device, in + addition to the routes in the Magic routing table. Each entry must be a network + address in CIDR notation with no host bits set (for example `192.0.2.0/24`, not + `192.0.2.1/24`) and must not repeat another entry. """ import_filter_id: Optional[str] = None diff --git a/src/cloudflare/types/magic_transit/cf_interconnect_get_response.py b/src/cloudflare/types/magic_transit/cf_interconnect_get_response.py index bfb40ad1042..1b6529cb52a 100644 --- a/src/cloudflare/types/magic_transit/cf_interconnect_get_response.py +++ b/src/cloudflare/types/magic_transit/cf_interconnect_get_response.py @@ -37,8 +37,10 @@ class InterconnectBGP(BaseModel): extra_prefixes: Optional[List[str]] = None """ - Prefixes in this list will be advertised to the customer device, in addition to - the routes in the Magic routing table. + IPv4 prefixes in this list will be advertised to the customer device, in + addition to the routes in the Magic routing table. Each entry must be a network + address in CIDR notation with no host bits set (for example `192.0.2.0/24`, not + `192.0.2.1/24`) and must not repeat another entry. """ import_filter_id: Optional[str] = None diff --git a/src/cloudflare/types/magic_transit/cf_interconnect_list_response.py b/src/cloudflare/types/magic_transit/cf_interconnect_list_response.py index b173c3bd3db..462daccc744 100644 --- a/src/cloudflare/types/magic_transit/cf_interconnect_list_response.py +++ b/src/cloudflare/types/magic_transit/cf_interconnect_list_response.py @@ -37,8 +37,10 @@ class InterconnectBGP(BaseModel): extra_prefixes: Optional[List[str]] = None """ - Prefixes in this list will be advertised to the customer device, in addition to - the routes in the Magic routing table. + IPv4 prefixes in this list will be advertised to the customer device, in + addition to the routes in the Magic routing table. Each entry must be a network + address in CIDR notation with no host bits set (for example `192.0.2.0/24`, not + `192.0.2.1/24`) and must not repeat another entry. """ import_filter_id: Optional[str] = None diff --git a/src/cloudflare/types/magic_transit/cf_interconnect_update_params.py b/src/cloudflare/types/magic_transit/cf_interconnect_update_params.py index 60e5978f8b8..052f63c740c 100644 --- a/src/cloudflare/types/magic_transit/cf_interconnect_update_params.py +++ b/src/cloudflare/types/magic_transit/cf_interconnect_update_params.py @@ -88,8 +88,10 @@ class BGP(TypedDict, total=False): extra_prefixes: SequenceNotStr[str] """ - Prefixes in this list will be advertised to the customer device, in addition to - the routes in the Magic routing table. + IPv4 prefixes in this list will be advertised to the customer device, in + addition to the routes in the Magic routing table. Each entry must be a network + address in CIDR notation with no host bits set (for example `192.0.2.0/24`, not + `192.0.2.1/24`) and must not repeat another entry. """ import_filter_id: str diff --git a/src/cloudflare/types/magic_transit/cf_interconnect_update_response.py b/src/cloudflare/types/magic_transit/cf_interconnect_update_response.py index bb581cbad7e..a40231a9f57 100644 --- a/src/cloudflare/types/magic_transit/cf_interconnect_update_response.py +++ b/src/cloudflare/types/magic_transit/cf_interconnect_update_response.py @@ -37,8 +37,10 @@ class ModifiedInterconnectBGP(BaseModel): extra_prefixes: Optional[List[str]] = None """ - Prefixes in this list will be advertised to the customer device, in addition to - the routes in the Magic routing table. + IPv4 prefixes in this list will be advertised to the customer device, in + addition to the routes in the Magic routing table. Each entry must be a network + address in CIDR notation with no host bits set (for example `192.0.2.0/24`, not + `192.0.2.1/24`) and must not repeat another entry. """ import_filter_id: Optional[str] = None diff --git a/src/cloudflare/types/magic_transit/gre_tunnel_bulk_update_response.py b/src/cloudflare/types/magic_transit/gre_tunnel_bulk_update_response.py index 924cb5b6907..748555eb97e 100644 --- a/src/cloudflare/types/magic_transit/gre_tunnel_bulk_update_response.py +++ b/src/cloudflare/types/magic_transit/gre_tunnel_bulk_update_response.py @@ -29,7 +29,10 @@ class ModifiedGRETunnelBGP(BaseModel): extra_prefixes: Optional[List[str]] = None """ Prefixes in this list will be advertised to the customer device, in addition to - the routes in the Magic routing table. + the routes in the Magic routing table. Each entry must be a network address in + CIDR notation with no host bits set (for example `192.0.2.0/24`, not + `192.0.2.1/24`) and must not repeat another entry. IPv6 prefixes are accepted + only when the tunnel has an `interface_address6`. """ import_filter_id: Optional[str] = None diff --git a/src/cloudflare/types/magic_transit/gre_tunnel_create_params.py b/src/cloudflare/types/magic_transit/gre_tunnel_create_params.py index 2c45cd93e3b..2e85322c04f 100644 --- a/src/cloudflare/types/magic_transit/gre_tunnel_create_params.py +++ b/src/cloudflare/types/magic_transit/gre_tunnel_create_params.py @@ -87,7 +87,10 @@ class BGP(TypedDict, total=False): extra_prefixes: SequenceNotStr[str] """ Prefixes in this list will be advertised to the customer device, in addition to - the routes in the Magic routing table. + the routes in the Magic routing table. Each entry must be a network address in + CIDR notation with no host bits set (for example `192.0.2.0/24`, not + `192.0.2.1/24`) and must not repeat another entry. IPv6 prefixes are accepted + only when the tunnel has an `interface_address6`. """ import_filter_id: str diff --git a/src/cloudflare/types/magic_transit/gre_tunnel_create_response.py b/src/cloudflare/types/magic_transit/gre_tunnel_create_response.py index 3ae3d7d2282..fee77671fce 100644 --- a/src/cloudflare/types/magic_transit/gre_tunnel_create_response.py +++ b/src/cloudflare/types/magic_transit/gre_tunnel_create_response.py @@ -28,7 +28,10 @@ class BGP(BaseModel): extra_prefixes: Optional[List[str]] = None """ Prefixes in this list will be advertised to the customer device, in addition to - the routes in the Magic routing table. + the routes in the Magic routing table. Each entry must be a network address in + CIDR notation with no host bits set (for example `192.0.2.0/24`, not + `192.0.2.1/24`) and must not repeat another entry. IPv6 prefixes are accepted + only when the tunnel has an `interface_address6`. """ import_filter_id: Optional[str] = None diff --git a/src/cloudflare/types/magic_transit/gre_tunnel_delete_response.py b/src/cloudflare/types/magic_transit/gre_tunnel_delete_response.py index dc494813de7..c185523a84e 100644 --- a/src/cloudflare/types/magic_transit/gre_tunnel_delete_response.py +++ b/src/cloudflare/types/magic_transit/gre_tunnel_delete_response.py @@ -29,7 +29,10 @@ class DeletedGRETunnelBGP(BaseModel): extra_prefixes: Optional[List[str]] = None """ Prefixes in this list will be advertised to the customer device, in addition to - the routes in the Magic routing table. + the routes in the Magic routing table. Each entry must be a network address in + CIDR notation with no host bits set (for example `192.0.2.0/24`, not + `192.0.2.1/24`) and must not repeat another entry. IPv6 prefixes are accepted + only when the tunnel has an `interface_address6`. """ import_filter_id: Optional[str] = None diff --git a/src/cloudflare/types/magic_transit/gre_tunnel_get_response.py b/src/cloudflare/types/magic_transit/gre_tunnel_get_response.py index 32fd9527373..11dcc1f4c03 100644 --- a/src/cloudflare/types/magic_transit/gre_tunnel_get_response.py +++ b/src/cloudflare/types/magic_transit/gre_tunnel_get_response.py @@ -29,7 +29,10 @@ class GRETunnelBGP(BaseModel): extra_prefixes: Optional[List[str]] = None """ Prefixes in this list will be advertised to the customer device, in addition to - the routes in the Magic routing table. + the routes in the Magic routing table. Each entry must be a network address in + CIDR notation with no host bits set (for example `192.0.2.0/24`, not + `192.0.2.1/24`) and must not repeat another entry. IPv6 prefixes are accepted + only when the tunnel has an `interface_address6`. """ import_filter_id: Optional[str] = None diff --git a/src/cloudflare/types/magic_transit/gre_tunnel_list_response.py b/src/cloudflare/types/magic_transit/gre_tunnel_list_response.py index 88c54249db2..8bd81341912 100644 --- a/src/cloudflare/types/magic_transit/gre_tunnel_list_response.py +++ b/src/cloudflare/types/magic_transit/gre_tunnel_list_response.py @@ -29,7 +29,10 @@ class GRETunnelBGP(BaseModel): extra_prefixes: Optional[List[str]] = None """ Prefixes in this list will be advertised to the customer device, in addition to - the routes in the Magic routing table. + the routes in the Magic routing table. Each entry must be a network address in + CIDR notation with no host bits set (for example `192.0.2.0/24`, not + `192.0.2.1/24`) and must not repeat another entry. IPv6 prefixes are accepted + only when the tunnel has an `interface_address6`. """ import_filter_id: Optional[str] = None diff --git a/src/cloudflare/types/magic_transit/gre_tunnel_update_response.py b/src/cloudflare/types/magic_transit/gre_tunnel_update_response.py index 28ca8a99198..aa014f0b02a 100644 --- a/src/cloudflare/types/magic_transit/gre_tunnel_update_response.py +++ b/src/cloudflare/types/magic_transit/gre_tunnel_update_response.py @@ -29,7 +29,10 @@ class ModifiedGRETunnelBGP(BaseModel): extra_prefixes: Optional[List[str]] = None """ Prefixes in this list will be advertised to the customer device, in addition to - the routes in the Magic routing table. + the routes in the Magic routing table. Each entry must be a network address in + CIDR notation with no host bits set (for example `192.0.2.0/24`, not + `192.0.2.1/24`) and must not repeat another entry. IPv6 prefixes are accepted + only when the tunnel has an `interface_address6`. """ import_filter_id: Optional[str] = None diff --git a/src/cloudflare/types/magic_transit/ipsec_tunnel_bulk_update_response.py b/src/cloudflare/types/magic_transit/ipsec_tunnel_bulk_update_response.py index 2bd26657b61..ead5a009331 100644 --- a/src/cloudflare/types/magic_transit/ipsec_tunnel_bulk_update_response.py +++ b/src/cloudflare/types/magic_transit/ipsec_tunnel_bulk_update_response.py @@ -31,7 +31,10 @@ class ModifiedIPSECTunnelBGP(BaseModel): extra_prefixes: Optional[List[str]] = None """ Prefixes in this list will be advertised to the customer device, in addition to - the routes in the Magic routing table. + the routes in the Magic routing table. Each entry must be a network address in + CIDR notation with no host bits set (for example `192.0.2.0/24`, not + `192.0.2.1/24`) and must not repeat another entry. IPv6 prefixes are accepted + only when the tunnel has an `interface_address6`. """ import_filter_id: Optional[str] = None diff --git a/src/cloudflare/types/magic_transit/ipsec_tunnel_create_params.py b/src/cloudflare/types/magic_transit/ipsec_tunnel_create_params.py index 42ad6c4cd85..e380edbe566 100644 --- a/src/cloudflare/types/magic_transit/ipsec_tunnel_create_params.py +++ b/src/cloudflare/types/magic_transit/ipsec_tunnel_create_params.py @@ -89,7 +89,10 @@ class BGP(TypedDict, total=False): extra_prefixes: SequenceNotStr[str] """ Prefixes in this list will be advertised to the customer device, in addition to - the routes in the Magic routing table. + the routes in the Magic routing table. Each entry must be a network address in + CIDR notation with no host bits set (for example `192.0.2.0/24`, not + `192.0.2.1/24`) and must not repeat another entry. IPv6 prefixes are accepted + only when the tunnel has an `interface_address6`. """ import_filter_id: str diff --git a/src/cloudflare/types/magic_transit/ipsec_tunnel_create_response.py b/src/cloudflare/types/magic_transit/ipsec_tunnel_create_response.py index 3e415ceebb6..1b12552ebd7 100644 --- a/src/cloudflare/types/magic_transit/ipsec_tunnel_create_response.py +++ b/src/cloudflare/types/magic_transit/ipsec_tunnel_create_response.py @@ -30,7 +30,10 @@ class BGP(BaseModel): extra_prefixes: Optional[List[str]] = None """ Prefixes in this list will be advertised to the customer device, in addition to - the routes in the Magic routing table. + the routes in the Magic routing table. Each entry must be a network address in + CIDR notation with no host bits set (for example `192.0.2.0/24`, not + `192.0.2.1/24`) and must not repeat another entry. IPv6 prefixes are accepted + only when the tunnel has an `interface_address6`. """ import_filter_id: Optional[str] = None diff --git a/src/cloudflare/types/magic_transit/ipsec_tunnel_delete_response.py b/src/cloudflare/types/magic_transit/ipsec_tunnel_delete_response.py index 2b266a603ef..41515c21d61 100644 --- a/src/cloudflare/types/magic_transit/ipsec_tunnel_delete_response.py +++ b/src/cloudflare/types/magic_transit/ipsec_tunnel_delete_response.py @@ -31,7 +31,10 @@ class DeletedIPSECTunnelBGP(BaseModel): extra_prefixes: Optional[List[str]] = None """ Prefixes in this list will be advertised to the customer device, in addition to - the routes in the Magic routing table. + the routes in the Magic routing table. Each entry must be a network address in + CIDR notation with no host bits set (for example `192.0.2.0/24`, not + `192.0.2.1/24`) and must not repeat another entry. IPv6 prefixes are accepted + only when the tunnel has an `interface_address6`. """ import_filter_id: Optional[str] = None diff --git a/src/cloudflare/types/magic_transit/ipsec_tunnel_get_response.py b/src/cloudflare/types/magic_transit/ipsec_tunnel_get_response.py index 62e830f64ce..ee8e1a8e11c 100644 --- a/src/cloudflare/types/magic_transit/ipsec_tunnel_get_response.py +++ b/src/cloudflare/types/magic_transit/ipsec_tunnel_get_response.py @@ -31,7 +31,10 @@ class IPSECTunnelBGP(BaseModel): extra_prefixes: Optional[List[str]] = None """ Prefixes in this list will be advertised to the customer device, in addition to - the routes in the Magic routing table. + the routes in the Magic routing table. Each entry must be a network address in + CIDR notation with no host bits set (for example `192.0.2.0/24`, not + `192.0.2.1/24`) and must not repeat another entry. IPv6 prefixes are accepted + only when the tunnel has an `interface_address6`. """ import_filter_id: Optional[str] = None diff --git a/src/cloudflare/types/magic_transit/ipsec_tunnel_list_response.py b/src/cloudflare/types/magic_transit/ipsec_tunnel_list_response.py index 5245477a780..6aa91f14eca 100644 --- a/src/cloudflare/types/magic_transit/ipsec_tunnel_list_response.py +++ b/src/cloudflare/types/magic_transit/ipsec_tunnel_list_response.py @@ -31,7 +31,10 @@ class IPSECTunnelBGP(BaseModel): extra_prefixes: Optional[List[str]] = None """ Prefixes in this list will be advertised to the customer device, in addition to - the routes in the Magic routing table. + the routes in the Magic routing table. Each entry must be a network address in + CIDR notation with no host bits set (for example `192.0.2.0/24`, not + `192.0.2.1/24`) and must not repeat another entry. IPv6 prefixes are accepted + only when the tunnel has an `interface_address6`. """ import_filter_id: Optional[str] = None diff --git a/src/cloudflare/types/magic_transit/ipsec_tunnel_update_params.py b/src/cloudflare/types/magic_transit/ipsec_tunnel_update_params.py index c4d9e5b9bf4..9e842697327 100644 --- a/src/cloudflare/types/magic_transit/ipsec_tunnel_update_params.py +++ b/src/cloudflare/types/magic_transit/ipsec_tunnel_update_params.py @@ -89,7 +89,10 @@ class BGP(TypedDict, total=False): extra_prefixes: SequenceNotStr[str] """ Prefixes in this list will be advertised to the customer device, in addition to - the routes in the Magic routing table. + the routes in the Magic routing table. Each entry must be a network address in + CIDR notation with no host bits set (for example `192.0.2.0/24`, not + `192.0.2.1/24`) and must not repeat another entry. IPv6 prefixes are accepted + only when the tunnel has an `interface_address6`. """ import_filter_id: str diff --git a/src/cloudflare/types/magic_transit/ipsec_tunnel_update_response.py b/src/cloudflare/types/magic_transit/ipsec_tunnel_update_response.py index 217447332b4..82dc7069796 100644 --- a/src/cloudflare/types/magic_transit/ipsec_tunnel_update_response.py +++ b/src/cloudflare/types/magic_transit/ipsec_tunnel_update_response.py @@ -31,7 +31,10 @@ class ModifiedIPSECTunnelBGP(BaseModel): extra_prefixes: Optional[List[str]] = None """ Prefixes in this list will be advertised to the customer device, in addition to - the routes in the Magic routing table. + the routes in the Magic routing table. Each entry must be a network address in + CIDR notation with no host bits set (for example `192.0.2.0/24`, not + `192.0.2.1/24`) and must not repeat another entry. IPv6 prefixes are accepted + only when the tunnel has an `interface_address6`. """ import_filter_id: Optional[str] = None diff --git a/src/cloudflare/types/magic_transit/sites/__init__.py b/src/cloudflare/types/magic_transit/sites/__init__.py index cdf0ff32712..b77b818eba2 100644 --- a/src/cloudflare/types/magic_transit/sites/__init__.py +++ b/src/cloudflare/types/magic_transit/sites/__init__.py @@ -29,4 +29,3 @@ from .wan_static_addressing import WANStaticAddressing as WANStaticAddressing from .acl_configuration_param import ACLConfigurationParam as ACLConfigurationParam from .lan_static_addressing_param import LANStaticAddressingParam as LANStaticAddressingParam -from .wan_static_addressing_param import WANStaticAddressingParam as WANStaticAddressingParam diff --git a/src/cloudflare/types/magic_transit/sites/lan.py b/src/cloudflare/types/magic_transit/sites/lan.py index f9e0e821a2c..25c475c78cc 100644 --- a/src/cloudflare/types/magic_transit/sites/lan.py +++ b/src/cloudflare/types/magic_transit/sites/lan.py @@ -7,7 +7,19 @@ from .routed_subnet import RoutedSubnet from .lan_static_addressing import LANStaticAddressing -__all__ = ["LAN"] +__all__ = ["LAN", "RemoteSubnet"] + + +class RemoteSubnet(BaseModel): + """ + A remote subnet reachable through Cloudflare that is addressed from this LAN by a local alias prefix of the same size. The local alias prefix must not overlap other subnets on the LAN, and the remote prefix must not overlap other remote prefixes on the LAN. + """ + + local_alias_prefix: str + """A valid CIDR notation representing an IP range.""" + + remote_prefix: str + """A valid CIDR notation representing an IP range.""" class LAN(BaseModel): @@ -34,6 +46,8 @@ class LAN(BaseModel): physport: Optional[int] = None + remote_subnets: Optional[List[RemoteSubnet]] = None + routed_subnets: Optional[List[RoutedSubnet]] = None site_id: Optional[str] = None diff --git a/src/cloudflare/types/magic_transit/sites/lan_create_params.py b/src/cloudflare/types/magic_transit/sites/lan_create_params.py index ba7ea87f1a4..ee6c0853bd2 100644 --- a/src/cloudflare/types/magic_transit/sites/lan_create_params.py +++ b/src/cloudflare/types/magic_transit/sites/lan_create_params.py @@ -9,7 +9,7 @@ from .routed_subnet_param import RoutedSubnetParam from .lan_static_addressing_param import LANStaticAddressingParam -__all__ = ["LANCreateParams"] +__all__ = ["LANCreateParams", "RemoteSubnet"] class LANCreateParams(TypedDict, total=False): @@ -36,6 +36,8 @@ class LANCreateParams(TypedDict, total=False): physport: int + remote_subnets: Iterable[RemoteSubnet] + routed_subnets: Iterable[RoutedSubnetParam] static_addressing: LANStaticAddressingParam @@ -47,3 +49,15 @@ class LANCreateParams(TypedDict, total=False): vlan_tag: int """VLAN ID. Use zero for untagged.""" + + +class RemoteSubnet(TypedDict, total=False): + """ + A remote subnet reachable through Cloudflare that is addressed from this LAN by a local alias prefix of the same size. The local alias prefix must not overlap other subnets on the LAN, and the remote prefix must not overlap other remote prefixes on the LAN. + """ + + local_alias_prefix: Required[str] + """A valid CIDR notation representing an IP range.""" + + remote_prefix: Required[str] + """A valid CIDR notation representing an IP range.""" diff --git a/src/cloudflare/types/magic_transit/sites/lan_edit_params.py b/src/cloudflare/types/magic_transit/sites/lan_edit_params.py index 601e6464be0..2b6aa59c683 100644 --- a/src/cloudflare/types/magic_transit/sites/lan_edit_params.py +++ b/src/cloudflare/types/magic_transit/sites/lan_edit_params.py @@ -9,7 +9,7 @@ from .routed_subnet_param import RoutedSubnetParam from .lan_static_addressing_param import LANStaticAddressingParam -__all__ = ["LANEditParams"] +__all__ = ["LANEditParams", "RemoteSubnet"] class LANEditParams(TypedDict, total=False): @@ -39,6 +39,8 @@ class LANEditParams(TypedDict, total=False): physport: int + remote_subnets: Iterable[RemoteSubnet] + routed_subnets: Iterable[RoutedSubnetParam] static_addressing: LANStaticAddressingParam @@ -50,3 +52,15 @@ class LANEditParams(TypedDict, total=False): vlan_tag: int """VLAN ID. Use zero for untagged.""" + + +class RemoteSubnet(TypedDict, total=False): + """ + A remote subnet reachable through Cloudflare that is addressed from this LAN by a local alias prefix of the same size. The local alias prefix must not overlap other subnets on the LAN, and the remote prefix must not overlap other remote prefixes on the LAN. + """ + + local_alias_prefix: Required[str] + """A valid CIDR notation representing an IP range.""" + + remote_prefix: Required[str] + """A valid CIDR notation representing an IP range.""" diff --git a/src/cloudflare/types/magic_transit/sites/lan_update_params.py b/src/cloudflare/types/magic_transit/sites/lan_update_params.py index ffcce7c5ac5..76661ff765d 100644 --- a/src/cloudflare/types/magic_transit/sites/lan_update_params.py +++ b/src/cloudflare/types/magic_transit/sites/lan_update_params.py @@ -9,7 +9,7 @@ from .routed_subnet_param import RoutedSubnetParam from .lan_static_addressing_param import LANStaticAddressingParam -__all__ = ["LANUpdateParams"] +__all__ = ["LANUpdateParams", "RemoteSubnet"] class LANUpdateParams(TypedDict, total=False): @@ -39,6 +39,8 @@ class LANUpdateParams(TypedDict, total=False): physport: int + remote_subnets: Iterable[RemoteSubnet] + routed_subnets: Iterable[RoutedSubnetParam] static_addressing: LANStaticAddressingParam @@ -50,3 +52,15 @@ class LANUpdateParams(TypedDict, total=False): vlan_tag: int """VLAN ID. Use zero for untagged.""" + + +class RemoteSubnet(TypedDict, total=False): + """ + A remote subnet reachable through Cloudflare that is addressed from this LAN by a local alias prefix of the same size. The local alias prefix must not overlap other subnets on the LAN, and the remote prefix must not overlap other remote prefixes on the LAN. + """ + + local_alias_prefix: Required[str] + """A valid CIDR notation representing an IP range.""" + + remote_prefix: Required[str] + """A valid CIDR notation representing an IP range.""" diff --git a/src/cloudflare/types/magic_transit/sites/wan.py b/src/cloudflare/types/magic_transit/sites/wan.py index f01162e756c..4642a527695 100644 --- a/src/cloudflare/types/magic_transit/sites/wan.py +++ b/src/cloudflare/types/magic_transit/sites/wan.py @@ -28,6 +28,12 @@ class WAN(BaseModel): priority: Optional[int] = None """Priority of WAN for traffic loadbalancing.""" + provisioned_download_kbps: Optional[int] = None + """Provisioned download rate of the WAN circuit in kilobits per second.""" + + provisioned_upload_kbps: Optional[int] = None + """Provisioned upload rate of the WAN circuit in kilobits per second.""" + site_id: Optional[str] = None """Identifier""" diff --git a/src/cloudflare/types/magic_transit/sites/wan_create_params.py b/src/cloudflare/types/magic_transit/sites/wan_create_params.py index 41027eecb26..86f7511ed85 100644 --- a/src/cloudflare/types/magic_transit/sites/wan_create_params.py +++ b/src/cloudflare/types/magic_transit/sites/wan_create_params.py @@ -4,9 +4,7 @@ from typing_extensions import Literal, Required, TypedDict -from .wan_static_addressing_param import WANStaticAddressingParam - -__all__ = ["WANCreateParams"] +__all__ = ["WANCreateParams", "StaticAddressing"] class WANCreateParams(TypedDict, total=False): @@ -27,11 +25,37 @@ class WANCreateParams(TypedDict, total=False): priority: int - static_addressing: WANStaticAddressingParam - """(optional) if omitted, use DHCP. + provisioned_download_kbps: int + """Provisioned download rate of the WAN circuit in kilobits per second.""" + + provisioned_upload_kbps: int + """Provisioned upload rate of the WAN circuit in kilobits per second.""" + + static_addressing: StaticAddressing + """Static addressing configuration for a WAN. - Submit secondary_address when site is in high availability mode. + Omit to use DHCP. Submit secondary_address when the site is in high availability + mode. """ vlan_tag: int """VLAN ID. Use zero for untagged.""" + + +class StaticAddressing(TypedDict, total=False): + """Static addressing configuration for a WAN. + + Omit to use DHCP. Submit secondary_address when the site is in high availability mode. + """ + + address: Required[str] + """A valid CIDR notation representing an IP range.""" + + gateway_address: Required[str] + """A valid IPv4 address.""" + + secondary_address: str + """A valid CIDR notation representing an IP range.""" + + secondary_gateway_address: str + """Gateway address for the secondary connector of a high availability site.""" diff --git a/src/cloudflare/types/magic_transit/sites/wan_edit_params.py b/src/cloudflare/types/magic_transit/sites/wan_edit_params.py index 6a785190114..69b86e9f5bc 100644 --- a/src/cloudflare/types/magic_transit/sites/wan_edit_params.py +++ b/src/cloudflare/types/magic_transit/sites/wan_edit_params.py @@ -5,9 +5,7 @@ from typing import Optional from typing_extensions import Literal, Required, TypedDict -from .wan_static_addressing_param import WANStaticAddressingParam - -__all__ = ["WANEditParams"] +__all__ = ["WANEditParams", "StaticAddressing"] class WANEditParams(TypedDict, total=False): @@ -28,11 +26,45 @@ class WANEditParams(TypedDict, total=False): priority: int - static_addressing: WANStaticAddressingParam - """(optional) if omitted, use DHCP. + provisioned_download_kbps: Optional[int] + """Provisioned download rate of the WAN circuit in kilobits per second. - Submit secondary_address when site is in high availability mode. + Set to null to remove it. + """ + + provisioned_upload_kbps: Optional[int] + """Provisioned upload rate of the WAN circuit in kilobits per second. + + Set to null to remove it. + """ + + static_addressing: StaticAddressing + """Static addressing configuration. + + PATCH updates only the fields provided, and PUT replaces the configuration. """ vlan_tag: int """VLAN ID. Use zero for untagged.""" + + +class StaticAddressing(TypedDict, total=False): + """Static addressing configuration. + + PATCH updates only the fields provided, and PUT replaces the configuration. + """ + + address: str + """A valid CIDR notation representing an IP range.""" + + gateway_address: str + """A valid IPv4 address.""" + + secondary_address: str + """A valid CIDR notation representing an IP range.""" + + secondary_gateway_address: Optional[str] + """Gateway address for the secondary connector of a high availability site. + + Set to null to remove it. + """ diff --git a/src/cloudflare/types/magic_transit/sites/wan_static_addressing.py b/src/cloudflare/types/magic_transit/sites/wan_static_addressing.py index 67c518474c3..de5c15f60b2 100644 --- a/src/cloudflare/types/magic_transit/sites/wan_static_addressing.py +++ b/src/cloudflare/types/magic_transit/sites/wan_static_addressing.py @@ -21,3 +21,6 @@ class WANStaticAddressing(BaseModel): secondary_address: Optional[str] = None """A valid CIDR notation representing an IP range.""" + + secondary_gateway_address: Optional[str] = None + """Gateway address for the secondary connector of a high availability site.""" diff --git a/src/cloudflare/types/magic_transit/sites/wan_static_addressing_param.py b/src/cloudflare/types/magic_transit/sites/wan_static_addressing_param.py deleted file mode 100644 index c3b550d3264..00000000000 --- a/src/cloudflare/types/magic_transit/sites/wan_static_addressing_param.py +++ /dev/null @@ -1,23 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing_extensions import Required, TypedDict - -__all__ = ["WANStaticAddressingParam"] - - -class WANStaticAddressingParam(TypedDict, total=False): - """(optional) if omitted, use DHCP. - - Submit secondary_address when site is in high availability mode. - """ - - address: Required[str] - """A valid CIDR notation representing an IP range.""" - - gateway_address: Required[str] - """A valid IPv4 address.""" - - secondary_address: str - """A valid CIDR notation representing an IP range.""" diff --git a/src/cloudflare/types/magic_transit/sites/wan_update_params.py b/src/cloudflare/types/magic_transit/sites/wan_update_params.py index 307fb22708f..35f5625e3ab 100644 --- a/src/cloudflare/types/magic_transit/sites/wan_update_params.py +++ b/src/cloudflare/types/magic_transit/sites/wan_update_params.py @@ -5,9 +5,7 @@ from typing import Optional from typing_extensions import Literal, Required, TypedDict -from .wan_static_addressing_param import WANStaticAddressingParam - -__all__ = ["WANUpdateParams"] +__all__ = ["WANUpdateParams", "StaticAddressing"] class WANUpdateParams(TypedDict, total=False): @@ -28,11 +26,45 @@ class WANUpdateParams(TypedDict, total=False): priority: int - static_addressing: WANStaticAddressingParam - """(optional) if omitted, use DHCP. + provisioned_download_kbps: Optional[int] + """Provisioned download rate of the WAN circuit in kilobits per second. - Submit secondary_address when site is in high availability mode. + Set to null to remove it. + """ + + provisioned_upload_kbps: Optional[int] + """Provisioned upload rate of the WAN circuit in kilobits per second. + + Set to null to remove it. + """ + + static_addressing: StaticAddressing + """Static addressing configuration. + + PATCH updates only the fields provided, and PUT replaces the configuration. """ vlan_tag: int """VLAN ID. Use zero for untagged.""" + + +class StaticAddressing(TypedDict, total=False): + """Static addressing configuration. + + PATCH updates only the fields provided, and PUT replaces the configuration. + """ + + address: str + """A valid CIDR notation representing an IP range.""" + + gateway_address: str + """A valid IPv4 address.""" + + secondary_address: str + """A valid CIDR notation representing an IP range.""" + + secondary_gateway_address: Optional[str] + """Gateway address for the secondary connector of a high availability site. + + Set to null to remove it. + """ diff --git a/src/cloudflare/types/managed_defense/vulnerability_discovery/report_get_response.py b/src/cloudflare/types/managed_defense/vulnerability_discovery/report_get_response.py index 64b52699854..eee706a18a0 100644 --- a/src/cloudflare/types/managed_defense/vulnerability_discovery/report_get_response.py +++ b/src/cloudflare/types/managed_defense/vulnerability_discovery/report_get_response.py @@ -84,6 +84,13 @@ class ReportFindingTrace(BaseModel): why: str + repo: Optional[str] = None + """ + Repository the step is in, present only when it is not the finding's repository + (a library or consumer of the same report). `path` is then relative to that + repository. + """ + class ReportFindingWAFRulesBroad(BaseModel): action: Literal["block", "managed_challenge", "js_challenge", "log"] @@ -168,6 +175,12 @@ class ReportFinding(BaseModel): external_links: Optional[List[ReportFindingExternalLink]] = None + impact_ids: Optional[List[str]] = None + """Accepted settled impact-charter premises cited by the finding. + + Optional on legacy report revisions. + """ + open_question: Optional[str] = None """One bounded unresolved proof question. Optional on legacy report revisions.""" @@ -181,6 +194,12 @@ class ReportFinding(BaseModel): ] = None """Current proof lifecycle state. Optional on legacy report revisions.""" + threat_ids: Optional[List[str]] = None + """Accepted settled threat-model premises cited by the finding. + + Optional on legacy report revisions. + """ + class ReportTrafficContextHTTPErrorPath(BaseModel): id: str diff --git a/src/cloudflare/types/managed_defense/vulnerability_discovery/repository_create_response.py b/src/cloudflare/types/managed_defense/vulnerability_discovery/repository_create_response.py index 57207ff7945..fcb86de8686 100644 --- a/src/cloudflare/types/managed_defense/vulnerability_discovery/repository_create_response.py +++ b/src/cloudflare/types/managed_defense/vulnerability_discovery/repository_create_response.py @@ -29,6 +29,12 @@ class UnionMember0Repository(BaseModel): name: str readiness: Literal["awaiting_source", "processing", "ready", "failed"] + """Source state. + + `awaiting_source`: the upload repository's default branch has no commits yet. + `processing`: an import is in progress. `ready`: source is available. `failed`: + the Worker import failed or could not be verified. + """ source: Literal["upload", "worker"] @@ -61,6 +67,12 @@ class RepositoryRepository(BaseModel): name: str readiness: Literal["awaiting_source", "processing", "ready", "failed"] + """Source state. + + `awaiting_source`: the upload repository's default branch has no commits yet. + `processing`: an import is in progress. `ready`: source is available. `failed`: + the Worker import failed or could not be verified. + """ source: Literal["upload", "worker"] diff --git a/src/cloudflare/types/managed_defense/vulnerability_discovery/repository_get_response.py b/src/cloudflare/types/managed_defense/vulnerability_discovery/repository_get_response.py index 9ba03663861..f417c9e7a36 100644 --- a/src/cloudflare/types/managed_defense/vulnerability_discovery/repository_get_response.py +++ b/src/cloudflare/types/managed_defense/vulnerability_discovery/repository_get_response.py @@ -30,6 +30,12 @@ class Repository(BaseModel): name: str readiness: Literal["awaiting_source", "processing", "ready", "failed"] + """Source state. + + `awaiting_source`: the upload repository's default branch has no commits yet. + `processing`: an import is in progress. `ready`: source is available. `failed`: + the Worker import failed or could not be verified. + """ source: Literal["upload", "worker"] diff --git a/src/cloudflare/types/managed_defense/vulnerability_discovery/repository_list_response.py b/src/cloudflare/types/managed_defense/vulnerability_discovery/repository_list_response.py index d076cd9c73c..931bd017563 100644 --- a/src/cloudflare/types/managed_defense/vulnerability_discovery/repository_list_response.py +++ b/src/cloudflare/types/managed_defense/vulnerability_discovery/repository_list_response.py @@ -23,6 +23,12 @@ class RepositoryListResponse(BaseModel): name: str readiness: Literal["awaiting_source", "processing", "ready", "failed"] + """Source state. + + `awaiting_source`: the upload repository's default branch has no commits yet. + `processing`: an import is in progress. `ready`: source is available. `failed`: + the Worker import failed or could not be verified. + """ source: Literal["upload", "worker"] diff --git a/src/cloudflare/types/managed_defense/vulnerability_discovery/scan_create_params.py b/src/cloudflare/types/managed_defense/vulnerability_discovery/scan_create_params.py index 3790763dd4d..861ea5c3c43 100644 --- a/src/cloudflare/types/managed_defense/vulnerability_discovery/scan_create_params.py +++ b/src/cloudflare/types/managed_defense/vulnerability_discovery/scan_create_params.py @@ -2,27 +2,21 @@ from __future__ import annotations -from typing import Dict, Union +from typing import Union, Iterable from datetime import datetime from typing_extensions import Required, Annotated, TypedDict from ...._types import SequenceNotStr from ...._utils import PropertyInfo -__all__ = ["ScanCreateParams", "TelemetryWindow"] +__all__ = ["ScanCreateParams", "Repo", "TelemetryWindow"] class ScanCreateParams(TypedDict, total=False): account_id: Required[str] - repos: Required[SequenceNotStr[str]] - - repo_hosts: Dict[str, SequenceNotStr[str]] - """Explicit hostname scopes. - - Every hostname must be authorized for its repository before review admission; - rejected scopes return 422 and do not persist a scan request. - """ + repos: Required[Iterable[Repo]] + """Repository names must be unique within a request.""" telemetry_window: TelemetryWindow """UTC ISO-8601 interval. @@ -34,6 +28,20 @@ class ScanCreateParams(TypedDict, total=False): idempotency_key: Annotated[str, PropertyInfo(alias="Idempotency-Key")] +class Repo(TypedDict, total=False): + name: Required[str] + + branch: str + """Branch to scan. Defaults to the repository's default branch.""" + + hosts: SequenceNotStr[str] + """Explicit hostname scopes. + + Every hostname must be authorized for this repository before review admission; + rejected scopes return 422 and do not persist a scan request. + """ + + class TelemetryWindow(TypedDict, total=False): """UTC ISO-8601 interval. diff --git a/src/cloudflare/types/managed_defense/vulnerability_discovery/scan_get_report_response.py b/src/cloudflare/types/managed_defense/vulnerability_discovery/scan_get_report_response.py index d16c9e8adc9..4c47f571bc2 100644 --- a/src/cloudflare/types/managed_defense/vulnerability_discovery/scan_get_report_response.py +++ b/src/cloudflare/types/managed_defense/vulnerability_discovery/scan_get_report_response.py @@ -86,6 +86,13 @@ class ReportRepositoryFindingTrace(BaseModel): why: str + repo: Optional[str] = None + """ + Repository the step is in, present only when it is not the finding's repository + (a library or consumer of the same report). `path` is then relative to that + repository. + """ + class ReportRepositoryFindingWAFRulesBroad(BaseModel): action: Literal["block", "managed_challenge", "js_challenge", "log"] @@ -170,6 +177,12 @@ class ReportRepositoryFinding(BaseModel): external_links: Optional[List[ReportRepositoryFindingExternalLink]] = None + impact_ids: Optional[List[str]] = None + """Accepted settled impact-charter premises cited by the finding. + + Optional on legacy report revisions. + """ + open_question: Optional[str] = None """One bounded unresolved proof question. Optional on legacy report revisions.""" @@ -183,6 +196,12 @@ class ReportRepositoryFinding(BaseModel): ] = None """Current proof lifecycle state. Optional on legacy report revisions.""" + threat_ids: Optional[List[str]] = None + """Accepted settled threat-model premises cited by the finding. + + Optional on legacy report revisions. + """ + class ReportRepositoryTrafficContextHTTPErrorPath(BaseModel): id: str diff --git a/src/cloudflare/types/managed_transforms/managed_transform_edit_response.py b/src/cloudflare/types/managed_transforms/managed_transform_edit_response.py index e9b6200bbb2..c0e6e244a52 100644 --- a/src/cloudflare/types/managed_transforms/managed_transform_edit_response.py +++ b/src/cloudflare/types/managed_transforms/managed_transform_edit_response.py @@ -1,13 +1,31 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import List, Optional +from typing import List, Union, Optional +from typing_extensions import TypeAlias from ..._models import BaseModel -__all__ = ["ManagedTransformEditResponse", "ManagedRequestHeader", "ManagedResponseHeader"] +__all__ = [ + "ManagedTransformEditResponse", + "UnionMember0", + "UnionMember0ManagedRequestHeader", + "UnionMember0ManagedResponseHeader", + "UnionMember1", + "UnionMember1ManagedRequestHeader", + "UnionMember1ManagedResponseHeader", + "UnionMember2", + "UnionMember2ManagedRequestHeader", + "UnionMember2ManagedResponseHeader", + "UnionMember3", + "UnionMember3ManagedRequestHeader", + "UnionMember3ManagedResponseHeader", + "UnionMember4", + "UnionMember4ManagedRequestHeader", + "UnionMember4ManagedResponseHeader", +] -class ManagedRequestHeader(BaseModel): +class UnionMember0ManagedRequestHeader(BaseModel): """A Managed Transform object.""" id: str @@ -26,7 +44,7 @@ class ManagedRequestHeader(BaseModel): """The Managed Transforms that this Managed Transform conflicts with.""" -class ManagedResponseHeader(BaseModel): +class UnionMember0ManagedResponseHeader(BaseModel): """A Managed Transform object.""" id: str @@ -45,11 +63,198 @@ class ManagedResponseHeader(BaseModel): """The Managed Transforms that this Managed Transform conflicts with.""" -class ManagedTransformEditResponse(BaseModel): - """A result.""" +class UnionMember0(BaseModel): + managed_request_headers: Optional[List[UnionMember0ManagedRequestHeader]] = None + """The list of Managed Request Transforms.""" + + managed_response_headers: Optional[List[UnionMember0ManagedResponseHeader]] = None + """The list of Managed Response Transforms.""" + + +class UnionMember1ManagedRequestHeader(BaseModel): + """A Managed Transform object.""" + + id: str + """The human-readable identifier of the Managed Transform.""" + + enabled: bool + """Whether the Managed Transform is enabled.""" + + has_conflict: bool + """ + Whether the Managed Transform conflicts with the currently-enabled Managed + Transforms. + """ + + conflicts_with: Optional[List[str]] = None + """The Managed Transforms that this Managed Transform conflicts with.""" - managed_request_headers: List[ManagedRequestHeader] + +class UnionMember1ManagedResponseHeader(BaseModel): + """A Managed Transform object.""" + + id: str + """The human-readable identifier of the Managed Transform.""" + + enabled: bool + """Whether the Managed Transform is enabled.""" + + has_conflict: bool + """ + Whether the Managed Transform conflicts with the currently-enabled Managed + Transforms. + """ + + conflicts_with: Optional[List[str]] = None + """The Managed Transforms that this Managed Transform conflicts with.""" + + +class UnionMember1(BaseModel): + managed_request_headers: Optional[List[UnionMember1ManagedRequestHeader]] = None """The list of Managed Request Transforms.""" - managed_response_headers: List[ManagedResponseHeader] + managed_response_headers: Optional[List[UnionMember1ManagedResponseHeader]] = None """The list of Managed Response Transforms.""" + + +class UnionMember2ManagedRequestHeader(BaseModel): + """A Managed Transform object.""" + + id: str + """The human-readable identifier of the Managed Transform.""" + + enabled: bool + """Whether the Managed Transform is enabled.""" + + has_conflict: bool + """ + Whether the Managed Transform conflicts with the currently-enabled Managed + Transforms. + """ + + conflicts_with: Optional[List[str]] = None + """The Managed Transforms that this Managed Transform conflicts with.""" + + +class UnionMember2ManagedResponseHeader(BaseModel): + """A Managed Transform object.""" + + id: str + """The human-readable identifier of the Managed Transform.""" + + enabled: bool + """Whether the Managed Transform is enabled.""" + + has_conflict: bool + """ + Whether the Managed Transform conflicts with the currently-enabled Managed + Transforms. + """ + + conflicts_with: Optional[List[str]] = None + """The Managed Transforms that this Managed Transform conflicts with.""" + + +class UnionMember2(BaseModel): + managed_request_headers: Optional[List[UnionMember2ManagedRequestHeader]] = None + """The list of Managed Request Transforms.""" + + managed_response_headers: Optional[List[UnionMember2ManagedResponseHeader]] = None + """The list of Managed Response Transforms.""" + + +class UnionMember3ManagedRequestHeader(BaseModel): + """A Managed Transform object.""" + + id: str + """The human-readable identifier of the Managed Transform.""" + + enabled: bool + """Whether the Managed Transform is enabled.""" + + has_conflict: bool + """ + Whether the Managed Transform conflicts with the currently-enabled Managed + Transforms. + """ + + conflicts_with: Optional[List[str]] = None + """The Managed Transforms that this Managed Transform conflicts with.""" + + +class UnionMember3ManagedResponseHeader(BaseModel): + """A Managed Transform object.""" + + id: str + """The human-readable identifier of the Managed Transform.""" + + enabled: bool + """Whether the Managed Transform is enabled.""" + + has_conflict: bool + """ + Whether the Managed Transform conflicts with the currently-enabled Managed + Transforms. + """ + + conflicts_with: Optional[List[str]] = None + """The Managed Transforms that this Managed Transform conflicts with.""" + + +class UnionMember3(BaseModel): + managed_request_headers: Optional[List[UnionMember3ManagedRequestHeader]] = None + """The list of Managed Request Transforms.""" + + managed_response_headers: Optional[List[UnionMember3ManagedResponseHeader]] = None + """The list of Managed Response Transforms.""" + + +class UnionMember4ManagedRequestHeader(BaseModel): + """A Managed Transform object.""" + + id: str + """The human-readable identifier of the Managed Transform.""" + + enabled: bool + """Whether the Managed Transform is enabled.""" + + has_conflict: bool + """ + Whether the Managed Transform conflicts with the currently-enabled Managed + Transforms. + """ + + conflicts_with: Optional[List[str]] = None + """The Managed Transforms that this Managed Transform conflicts with.""" + + +class UnionMember4ManagedResponseHeader(BaseModel): + """A Managed Transform object.""" + + id: str + """The human-readable identifier of the Managed Transform.""" + + enabled: bool + """Whether the Managed Transform is enabled.""" + + has_conflict: bool + """ + Whether the Managed Transform conflicts with the currently-enabled Managed + Transforms. + """ + + conflicts_with: Optional[List[str]] = None + """The Managed Transforms that this Managed Transform conflicts with.""" + + +class UnionMember4(BaseModel): + managed_request_headers: Optional[List[UnionMember4ManagedRequestHeader]] = None + """The list of Managed Request Transforms.""" + + managed_response_headers: Optional[List[UnionMember4ManagedResponseHeader]] = None + """The list of Managed Response Transforms.""" + + +ManagedTransformEditResponse: TypeAlias = Union[ + Optional[UnionMember0], UnionMember1, UnionMember2, UnionMember3, UnionMember4 +] diff --git a/src/cloudflare/types/managed_transforms/managed_transform_list_response.py b/src/cloudflare/types/managed_transforms/managed_transform_list_response.py index 4f246ffb75d..b1750b6a822 100644 --- a/src/cloudflare/types/managed_transforms/managed_transform_list_response.py +++ b/src/cloudflare/types/managed_transforms/managed_transform_list_response.py @@ -1,13 +1,31 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import List, Optional +from typing import List, Union, Optional +from typing_extensions import TypeAlias from ..._models import BaseModel -__all__ = ["ManagedTransformListResponse", "ManagedRequestHeader", "ManagedResponseHeader"] +__all__ = [ + "ManagedTransformListResponse", + "UnionMember0", + "UnionMember0ManagedRequestHeader", + "UnionMember0ManagedResponseHeader", + "UnionMember1", + "UnionMember1ManagedRequestHeader", + "UnionMember1ManagedResponseHeader", + "UnionMember2", + "UnionMember2ManagedRequestHeader", + "UnionMember2ManagedResponseHeader", + "UnionMember3", + "UnionMember3ManagedRequestHeader", + "UnionMember3ManagedResponseHeader", + "UnionMember4", + "UnionMember4ManagedRequestHeader", + "UnionMember4ManagedResponseHeader", +] -class ManagedRequestHeader(BaseModel): +class UnionMember0ManagedRequestHeader(BaseModel): """A Managed Transform object.""" id: str @@ -26,7 +44,7 @@ class ManagedRequestHeader(BaseModel): """The Managed Transforms that this Managed Transform conflicts with.""" -class ManagedResponseHeader(BaseModel): +class UnionMember0ManagedResponseHeader(BaseModel): """A Managed Transform object.""" id: str @@ -45,11 +63,198 @@ class ManagedResponseHeader(BaseModel): """The Managed Transforms that this Managed Transform conflicts with.""" -class ManagedTransformListResponse(BaseModel): - """A result.""" +class UnionMember0(BaseModel): + managed_request_headers: Optional[List[UnionMember0ManagedRequestHeader]] = None + """The list of Managed Request Transforms.""" + + managed_response_headers: Optional[List[UnionMember0ManagedResponseHeader]] = None + """The list of Managed Response Transforms.""" + + +class UnionMember1ManagedRequestHeader(BaseModel): + """A Managed Transform object.""" + + id: str + """The human-readable identifier of the Managed Transform.""" + + enabled: bool + """Whether the Managed Transform is enabled.""" + + has_conflict: bool + """ + Whether the Managed Transform conflicts with the currently-enabled Managed + Transforms. + """ + + conflicts_with: Optional[List[str]] = None + """The Managed Transforms that this Managed Transform conflicts with.""" - managed_request_headers: List[ManagedRequestHeader] + +class UnionMember1ManagedResponseHeader(BaseModel): + """A Managed Transform object.""" + + id: str + """The human-readable identifier of the Managed Transform.""" + + enabled: bool + """Whether the Managed Transform is enabled.""" + + has_conflict: bool + """ + Whether the Managed Transform conflicts with the currently-enabled Managed + Transforms. + """ + + conflicts_with: Optional[List[str]] = None + """The Managed Transforms that this Managed Transform conflicts with.""" + + +class UnionMember1(BaseModel): + managed_request_headers: Optional[List[UnionMember1ManagedRequestHeader]] = None """The list of Managed Request Transforms.""" - managed_response_headers: List[ManagedResponseHeader] + managed_response_headers: Optional[List[UnionMember1ManagedResponseHeader]] = None """The list of Managed Response Transforms.""" + + +class UnionMember2ManagedRequestHeader(BaseModel): + """A Managed Transform object.""" + + id: str + """The human-readable identifier of the Managed Transform.""" + + enabled: bool + """Whether the Managed Transform is enabled.""" + + has_conflict: bool + """ + Whether the Managed Transform conflicts with the currently-enabled Managed + Transforms. + """ + + conflicts_with: Optional[List[str]] = None + """The Managed Transforms that this Managed Transform conflicts with.""" + + +class UnionMember2ManagedResponseHeader(BaseModel): + """A Managed Transform object.""" + + id: str + """The human-readable identifier of the Managed Transform.""" + + enabled: bool + """Whether the Managed Transform is enabled.""" + + has_conflict: bool + """ + Whether the Managed Transform conflicts with the currently-enabled Managed + Transforms. + """ + + conflicts_with: Optional[List[str]] = None + """The Managed Transforms that this Managed Transform conflicts with.""" + + +class UnionMember2(BaseModel): + managed_request_headers: Optional[List[UnionMember2ManagedRequestHeader]] = None + """The list of Managed Request Transforms.""" + + managed_response_headers: Optional[List[UnionMember2ManagedResponseHeader]] = None + """The list of Managed Response Transforms.""" + + +class UnionMember3ManagedRequestHeader(BaseModel): + """A Managed Transform object.""" + + id: str + """The human-readable identifier of the Managed Transform.""" + + enabled: bool + """Whether the Managed Transform is enabled.""" + + has_conflict: bool + """ + Whether the Managed Transform conflicts with the currently-enabled Managed + Transforms. + """ + + conflicts_with: Optional[List[str]] = None + """The Managed Transforms that this Managed Transform conflicts with.""" + + +class UnionMember3ManagedResponseHeader(BaseModel): + """A Managed Transform object.""" + + id: str + """The human-readable identifier of the Managed Transform.""" + + enabled: bool + """Whether the Managed Transform is enabled.""" + + has_conflict: bool + """ + Whether the Managed Transform conflicts with the currently-enabled Managed + Transforms. + """ + + conflicts_with: Optional[List[str]] = None + """The Managed Transforms that this Managed Transform conflicts with.""" + + +class UnionMember3(BaseModel): + managed_request_headers: Optional[List[UnionMember3ManagedRequestHeader]] = None + """The list of Managed Request Transforms.""" + + managed_response_headers: Optional[List[UnionMember3ManagedResponseHeader]] = None + """The list of Managed Response Transforms.""" + + +class UnionMember4ManagedRequestHeader(BaseModel): + """A Managed Transform object.""" + + id: str + """The human-readable identifier of the Managed Transform.""" + + enabled: bool + """Whether the Managed Transform is enabled.""" + + has_conflict: bool + """ + Whether the Managed Transform conflicts with the currently-enabled Managed + Transforms. + """ + + conflicts_with: Optional[List[str]] = None + """The Managed Transforms that this Managed Transform conflicts with.""" + + +class UnionMember4ManagedResponseHeader(BaseModel): + """A Managed Transform object.""" + + id: str + """The human-readable identifier of the Managed Transform.""" + + enabled: bool + """Whether the Managed Transform is enabled.""" + + has_conflict: bool + """ + Whether the Managed Transform conflicts with the currently-enabled Managed + Transforms. + """ + + conflicts_with: Optional[List[str]] = None + """The Managed Transforms that this Managed Transform conflicts with.""" + + +class UnionMember4(BaseModel): + managed_request_headers: Optional[List[UnionMember4ManagedRequestHeader]] = None + """The list of Managed Request Transforms.""" + + managed_response_headers: Optional[List[UnionMember4ManagedResponseHeader]] = None + """The list of Managed Response Transforms.""" + + +ManagedTransformListResponse: TypeAlias = Union[ + Optional[UnionMember0], UnionMember1, UnionMember2, UnionMember3, UnionMember4 +] diff --git a/src/cloudflare/types/memberships/membership_get_response.py b/src/cloudflare/types/memberships/membership_get_response.py index e09312a5589..030d7d36295 100644 --- a/src/cloudflare/types/memberships/membership_get_response.py +++ b/src/cloudflare/types/memberships/membership_get_response.py @@ -105,7 +105,7 @@ class PolicyResourceGroupScopeObject(BaseModel): class PolicyResourceGroupScope(BaseModel): - """A scope is a combination of scope objects which provides additional context.""" + """The scope associated to the resource group""" key: str """ @@ -132,7 +132,7 @@ class PolicyResourceGroup(BaseModel): """Identifier of the resource group.""" scope: PolicyResourceGroupScope - """A scope is a combination of scope objects which provides additional context.""" + """The scope associated to the resource group""" meta: Optional[PolicyResourceGroupMeta] = None """Attributes associated to the resource group.""" diff --git a/src/cloudflare/types/memberships/membership_update_response.py b/src/cloudflare/types/memberships/membership_update_response.py index 8db7439cbb1..445e4c05825 100644 --- a/src/cloudflare/types/memberships/membership_update_response.py +++ b/src/cloudflare/types/memberships/membership_update_response.py @@ -105,7 +105,7 @@ class PolicyResourceGroupScopeObject(BaseModel): class PolicyResourceGroupScope(BaseModel): - """A scope is a combination of scope objects which provides additional context.""" + """The scope associated to the resource group""" key: str """ @@ -132,7 +132,7 @@ class PolicyResourceGroup(BaseModel): """Identifier of the resource group.""" scope: PolicyResourceGroupScope - """A scope is a combination of scope objects which provides additional context.""" + """The scope associated to the resource group""" meta: Optional[PolicyResourceGroupMeta] = None """Attributes associated to the resource group.""" diff --git a/src/cloudflare/types/monetization/__init__.py b/src/cloudflare/types/monetization/__init__.py new file mode 100644 index 00000000000..f76e4c29d2e --- /dev/null +++ b/src/cloudflare/types/monetization/__init__.py @@ -0,0 +1,19 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from .monetization_rule import MonetizationRule as MonetizationRule +from .rule_update_params import RuleUpdateParams as RuleUpdateParams +from .rule_edit_rule_params import RuleEditRuleParams as RuleEditRuleParams +from .monetization_rule_collection import MonetizationRuleCollection as MonetizationRuleCollection +from .monetization_rule_input_param import MonetizationRuleInputParam as MonetizationRuleInputParam +from .monetization_rule_input_fixed_price import MonetizationRuleInputFixedPrice as MonetizationRuleInputFixedPrice +from .monetization_rule_input_fixed_price_param import ( + MonetizationRuleInputFixedPriceParam as MonetizationRuleInputFixedPriceParam, +) +from .monetization_rule_input_origin_controlled import ( + MonetizationRuleInputOriginControlled as MonetizationRuleInputOriginControlled, +) +from .monetization_rule_input_origin_controlled_param import ( + MonetizationRuleInputOriginControlledParam as MonetizationRuleInputOriginControlledParam, +) diff --git a/src/cloudflare/types/monetization/monetization_rule.py b/src/cloudflare/types/monetization/monetization_rule.py new file mode 100644 index 00000000000..dc94f2a20cf --- /dev/null +++ b/src/cloudflare/types/monetization/monetization_rule.py @@ -0,0 +1,41 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Union +from typing_extensions import TypeAlias + +from .monetization_rule_input_fixed_price import MonetizationRuleInputFixedPrice +from .monetization_rule_input_origin_controlled import MonetizationRuleInputOriginControlled + +__all__ = [ + "MonetizationRule", + "MonetizationRulesMonetizationRuleInputFixedPrice", + "MonetizationRulesMonetizationRuleInputOriginControlled", +] + + +class MonetizationRulesMonetizationRuleInputFixedPrice(MonetizationRuleInputFixedPrice): + """Payment rule with a fixed price set at configuration time.""" + + id: str # type: ignore + """The server-assigned unique ID of the payment rule. + + Stable across full-ruleset replacements. + """ + + +class MonetizationRulesMonetizationRuleInputOriginControlled(MonetizationRuleInputOriginControlled): + """Payment rule whose price the origin server sets dynamically. + + The rule carries no price and the price field must be omitted — any provided value, including "0", is rejected because it would not be enforced. + """ + + id: str # type: ignore + """The server-assigned unique ID of the payment rule. + + Stable across full-ruleset replacements. + """ + + +MonetizationRule: TypeAlias = Union[ + MonetizationRulesMonetizationRuleInputFixedPrice, MonetizationRulesMonetizationRuleInputOriginControlled +] diff --git a/src/cloudflare/types/monetization/monetization_rule_collection.py b/src/cloudflare/types/monetization/monetization_rule_collection.py new file mode 100644 index 00000000000..9d31ca5aaf8 --- /dev/null +++ b/src/cloudflare/types/monetization/monetization_rule_collection.py @@ -0,0 +1,21 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List + +from ..._models import BaseModel +from .monetization_rule import MonetizationRule + +__all__ = ["MonetizationRuleCollection"] + + +class MonetizationRuleCollection(BaseModel): + """The zone's payment rules. + + Mirrors the shape of the ruleset submitted to the deploy endpoint, so the response can be read back as the desired state. + """ + + rules: List[MonetizationRule] + """The zone's payment rules, in the order they are evaluated. + + Empty when the zone has no payment rules. + """ diff --git a/src/cloudflare/types/monetization/monetization_rule_input_fixed_price.py b/src/cloudflare/types/monetization/monetization_rule_input_fixed_price.py new file mode 100644 index 00000000000..9acaa164e18 --- /dev/null +++ b/src/cloudflare/types/monetization/monetization_rule_input_fixed_price.py @@ -0,0 +1,61 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional +from typing_extensions import Literal + +from ..._models import BaseModel + +__all__ = ["MonetizationRuleInputFixedPrice"] + + +class MonetizationRuleInputFixedPrice(BaseModel): + """Payment rule with a fixed price set at configuration time.""" + + address: str + """0x-prefixed 20-byte hexadecimal Ethereum address. + + Mixed-case addresses must carry a valid EIP-55 checksum; all-lowercase or + all-uppercase addresses are also accepted. The address must pass wallet + screening whenever its rule is deployed or patched. + """ + + expression: str + """Wirefilter expression identifying the requests that require payment. + + Forwarded verbatim to the Rulesets API, which validates its syntax. + """ + + price: str + """ + Price in the smallest indivisible unit of the configured payment token, encoded + as a decimal string. Must be a canonical decimal integer in [1000, 100000000]: + no leading zeros, and a bare JSON number is rejected. The price is required for + the fixed-price schemes ("exact" and "upto") and must be at least 1000, the + smallest amount the payment facilitator can settle ($0.001 for a 6-decimal token + such as USDC), and at most 100000000 ($100 for a 6-decimal token). When the + scheme is "origin_controlled" the origin server sets pricing dynamically and the + rule carries no price: the field must be omitted — any provided value, including + "0", is rejected because it would not be enforced. Responses always encode this + as a string and omit it for "origin_controlled" rules; the pattern matches + exactly the set of values the server accepts. + """ + + scheme: Literal["exact", "upto"] + """X402 payment scheme. + + "exact" requires the specified payment amount; "upto" permits a payment up to + the specified amount. Both fixed-price schemes require the price field. + """ + + id: Optional[str] = None + """Optional on input. + + Include the ID of an existing payment rule to update it in place, preserving its + stable identity across the full-ruleset replacement; omit it to create a new + rule. An ID that does not match an existing payment rule in the zone is + rejected. Rules omitted from the request are deleted. + """ + + description: Optional[str] = None + + enabled: Optional[bool] = None diff --git a/src/cloudflare/types/monetization/monetization_rule_input_fixed_price_param.py b/src/cloudflare/types/monetization/monetization_rule_input_fixed_price_param.py new file mode 100644 index 00000000000..bdd01296de0 --- /dev/null +++ b/src/cloudflare/types/monetization/monetization_rule_input_fixed_price_param.py @@ -0,0 +1,60 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal, Required, TypedDict + +__all__ = ["MonetizationRuleInputFixedPriceParam"] + + +class MonetizationRuleInputFixedPriceParam(TypedDict, total=False): + """Payment rule with a fixed price set at configuration time.""" + + address: Required[str] + """0x-prefixed 20-byte hexadecimal Ethereum address. + + Mixed-case addresses must carry a valid EIP-55 checksum; all-lowercase or + all-uppercase addresses are also accepted. The address must pass wallet + screening whenever its rule is deployed or patched. + """ + + expression: Required[str] + """Wirefilter expression identifying the requests that require payment. + + Forwarded verbatim to the Rulesets API, which validates its syntax. + """ + + price: Required[str] + """ + Price in the smallest indivisible unit of the configured payment token, encoded + as a decimal string. Must be a canonical decimal integer in [1000, 100000000]: + no leading zeros, and a bare JSON number is rejected. The price is required for + the fixed-price schemes ("exact" and "upto") and must be at least 1000, the + smallest amount the payment facilitator can settle ($0.001 for a 6-decimal token + such as USDC), and at most 100000000 ($100 for a 6-decimal token). When the + scheme is "origin_controlled" the origin server sets pricing dynamically and the + rule carries no price: the field must be omitted — any provided value, including + "0", is rejected because it would not be enforced. Responses always encode this + as a string and omit it for "origin_controlled" rules; the pattern matches + exactly the set of values the server accepts. + """ + + scheme: Required[Literal["exact", "upto"]] + """X402 payment scheme. + + "exact" requires the specified payment amount; "upto" permits a payment up to + the specified amount. Both fixed-price schemes require the price field. + """ + + id: str + """Optional on input. + + Include the ID of an existing payment rule to update it in place, preserving its + stable identity across the full-ruleset replacement; omit it to create a new + rule. An ID that does not match an existing payment rule in the zone is + rejected. Rules omitted from the request are deleted. + """ + + description: str + + enabled: bool diff --git a/src/cloudflare/types/monetization/monetization_rule_input_origin_controlled.py b/src/cloudflare/types/monetization/monetization_rule_input_origin_controlled.py new file mode 100644 index 00000000000..a1cde9e15fa --- /dev/null +++ b/src/cloudflare/types/monetization/monetization_rule_input_origin_controlled.py @@ -0,0 +1,49 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional +from typing_extensions import Literal + +from ..._models import BaseModel + +__all__ = ["MonetizationRuleInputOriginControlled"] + + +class MonetizationRuleInputOriginControlled(BaseModel): + """Payment rule whose price the origin server sets dynamically. + + The rule carries no price and the price field must be omitted — any provided value, including "0", is rejected because it would not be enforced. + """ + + address: str + """0x-prefixed 20-byte hexadecimal Ethereum address. + + Mixed-case addresses must carry a valid EIP-55 checksum; all-lowercase or + all-uppercase addresses are also accepted. The address must pass wallet + screening whenever its rule is deployed or patched. + """ + + expression: str + """Wirefilter expression identifying the requests that require payment. + + Forwarded verbatim to the Rulesets API, which validates its syntax. + """ + + scheme: Literal["origin_controlled"] + """X402 payment scheme. + + "origin_controlled" lets the origin server set pricing dynamically; the rule + carries no price and the price field must be omitted. + """ + + id: Optional[str] = None + """Optional on input. + + Include the ID of an existing payment rule to update it in place, preserving its + stable identity across the full-ruleset replacement; omit it to create a new + rule. An ID that does not match an existing payment rule in the zone is + rejected. Rules omitted from the request are deleted. + """ + + description: Optional[str] = None + + enabled: Optional[bool] = None diff --git a/src/cloudflare/types/monetization/monetization_rule_input_origin_controlled_param.py b/src/cloudflare/types/monetization/monetization_rule_input_origin_controlled_param.py new file mode 100644 index 00000000000..3f46f6289c6 --- /dev/null +++ b/src/cloudflare/types/monetization/monetization_rule_input_origin_controlled_param.py @@ -0,0 +1,48 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal, Required, TypedDict + +__all__ = ["MonetizationRuleInputOriginControlledParam"] + + +class MonetizationRuleInputOriginControlledParam(TypedDict, total=False): + """Payment rule whose price the origin server sets dynamically. + + The rule carries no price and the price field must be omitted — any provided value, including "0", is rejected because it would not be enforced. + """ + + address: Required[str] + """0x-prefixed 20-byte hexadecimal Ethereum address. + + Mixed-case addresses must carry a valid EIP-55 checksum; all-lowercase or + all-uppercase addresses are also accepted. The address must pass wallet + screening whenever its rule is deployed or patched. + """ + + expression: Required[str] + """Wirefilter expression identifying the requests that require payment. + + Forwarded verbatim to the Rulesets API, which validates its syntax. + """ + + scheme: Required[Literal["origin_controlled"]] + """X402 payment scheme. + + "origin_controlled" lets the origin server set pricing dynamically; the rule + carries no price and the price field must be omitted. + """ + + id: str + """Optional on input. + + Include the ID of an existing payment rule to update it in place, preserving its + stable identity across the full-ruleset replacement; omit it to create a new + rule. An ID that does not match an existing payment rule in the zone is + rejected. Rules omitted from the request are deleted. + """ + + description: str + + enabled: bool diff --git a/src/cloudflare/types/monetization/monetization_rule_input_param.py b/src/cloudflare/types/monetization/monetization_rule_input_param.py new file mode 100644 index 00000000000..a1cad7f8805 --- /dev/null +++ b/src/cloudflare/types/monetization/monetization_rule_input_param.py @@ -0,0 +1,15 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Union +from typing_extensions import TypeAlias + +from .monetization_rule_input_fixed_price_param import MonetizationRuleInputFixedPriceParam +from .monetization_rule_input_origin_controlled_param import MonetizationRuleInputOriginControlledParam + +__all__ = ["MonetizationRuleInputParam"] + +MonetizationRuleInputParam: TypeAlias = Union[ + MonetizationRuleInputFixedPriceParam, MonetizationRuleInputOriginControlledParam +] diff --git a/src/cloudflare/types/monetization/rule_edit_rule_params.py b/src/cloudflare/types/monetization/rule_edit_rule_params.py new file mode 100644 index 00000000000..af067bc3cc2 --- /dev/null +++ b/src/cloudflare/types/monetization/rule_edit_rule_params.py @@ -0,0 +1,54 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal, Required, TypedDict + +__all__ = ["RuleEditRuleParams"] + + +class RuleEditRuleParams(TypedDict, total=False): + zone_id: Required[str] + """The unique ID of the zone.""" + + address: str + """0x-prefixed 20-byte hexadecimal Ethereum address. + + Mixed-case addresses must carry a valid EIP-55 checksum; all-lowercase or + all-uppercase addresses are also accepted. The effective address must pass + wallet screening whenever the rule is patched. + """ + + description: str + + enabled: bool + + expression: str + """Wirefilter expression identifying the requests that require payment. + + Forwarded verbatim to the Rulesets API, which validates its syntax. + """ + + price: str + """ + Price in the smallest indivisible unit of the configured payment token, encoded + as a decimal string. Must be a canonical decimal integer in [1000, 100000000]: + no leading zeros, and a bare JSON number is rejected. The price is required for + the fixed-price schemes ("exact" and "upto") and must be at least 1000, the + smallest amount the payment facilitator can settle ($0.001 for a 6-decimal token + such as USDC), and at most 100000000 ($100 for a 6-decimal token). When the + scheme is "origin_controlled" the origin server sets pricing dynamically and the + rule carries no price: the field must be omitted — any provided value, including + "0", is rejected because it would not be enforced. Responses always encode this + as a string and omit it for "origin_controlled" rules; the pattern matches + exactly the set of values the server accepts. + """ + + scheme: Literal["exact", "upto", "origin_controlled"] + """X402 payment scheme. + + "exact" requires the specified payment amount; "upto" permits a payment up to + the specified amount; "origin_controlled" lets the origin server set pricing + dynamically, in which case the rule carries no price and the price field must be + omitted. + """ diff --git a/src/cloudflare/types/monetization/rule_update_params.py b/src/cloudflare/types/monetization/rule_update_params.py new file mode 100644 index 00000000000..fea3f0acdd7 --- /dev/null +++ b/src/cloudflare/types/monetization/rule_update_params.py @@ -0,0 +1,23 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Iterable +from typing_extensions import Required, TypedDict + +from .monetization_rule_input_param import MonetizationRuleInputParam + +__all__ = ["RuleUpdateParams"] + + +class RuleUpdateParams(TypedDict, total=False): + zone_id: Required[str] + """The unique ID of the zone.""" + + rules: Required[Iterable[MonetizationRuleInputParam]] + """Full desired Payment Required ruleset. + + An empty array clears all payment rules. The ruleset may contain at most 40 + unique wallet addresses; address comparison is case-insensitive. Every address + must pass wallet screening before deployment. + """ diff --git a/src/cloudflare/types/moq/relay_create_response.py b/src/cloudflare/types/moq/relay_create_response.py index 316951c91a4..ebcb3dec2d9 100644 --- a/src/cloudflare/types/moq/relay_create_response.py +++ b/src/cloudflare/types/moq/relay_create_response.py @@ -45,6 +45,12 @@ class ConfigUpstreams(BaseModel): class Config(BaseModel): + """Relay configuration. + + All sub-objects use whole-object replacement when + present; omitted sub-objects preserve the existing value. + """ + upstreams: Optional[ConfigUpstreams] = None """ Upstreams are external MOQT server publishers that a relay falls back to when it @@ -98,6 +104,11 @@ class RelayCreateResponse(BaseModel): """ config: Config + """Relay configuration. + + All sub-objects use whole-object replacement when present; omitted sub-objects + preserve the existing value. + """ created: datetime diff --git a/src/cloudflare/types/moq/relay_get_response.py b/src/cloudflare/types/moq/relay_get_response.py index 8e21e4ef6ed..685d3c44ca4 100644 --- a/src/cloudflare/types/moq/relay_get_response.py +++ b/src/cloudflare/types/moq/relay_get_response.py @@ -38,6 +38,12 @@ class ConfigUpstreams(BaseModel): class Config(BaseModel): + """Relay configuration. + + All sub-objects use whole-object replacement when + present; omitted sub-objects preserve the existing value. + """ + upstreams: Optional[ConfigUpstreams] = None """ Upstreams are external MOQT server publishers that a relay falls back to when it @@ -49,6 +55,11 @@ class RelayGetResponse(BaseModel): """Full relay details (no tokens).""" config: Config + """Relay configuration. + + All sub-objects use whole-object replacement when present; omitted sub-objects + preserve the existing value. + """ created: datetime diff --git a/src/cloudflare/types/moq/relay_update_params.py b/src/cloudflare/types/moq/relay_update_params.py index 043d4517228..ad077d23f87 100644 --- a/src/cloudflare/types/moq/relay_update_params.py +++ b/src/cloudflare/types/moq/relay_update_params.py @@ -13,6 +13,11 @@ class RelayUpdateParams(TypedDict, total=False): """Cloudflare account identifier.""" config: Config + """Relay configuration. + + All sub-objects use whole-object replacement when present; omitted sub-objects + preserve the existing value. + """ name: str @@ -46,6 +51,12 @@ class ConfigUpstreams(TypedDict, total=False): class Config(TypedDict, total=False): + """Relay configuration. + + All sub-objects use whole-object replacement when + present; omitted sub-objects preserve the existing value. + """ + upstreams: ConfigUpstreams """ Upstreams are external MOQT server publishers that a relay falls back to when it diff --git a/src/cloudflare/types/moq/relay_update_response.py b/src/cloudflare/types/moq/relay_update_response.py index 6dbaa7e2f6b..4835151cf55 100644 --- a/src/cloudflare/types/moq/relay_update_response.py +++ b/src/cloudflare/types/moq/relay_update_response.py @@ -38,6 +38,12 @@ class ConfigUpstreams(BaseModel): class Config(BaseModel): + """Relay configuration. + + All sub-objects use whole-object replacement when + present; omitted sub-objects preserve the existing value. + """ + upstreams: Optional[ConfigUpstreams] = None """ Upstreams are external MOQT server publishers that a relay falls back to when it @@ -49,6 +55,11 @@ class RelayUpdateResponse(BaseModel): """Full relay details (no tokens).""" config: Config + """Relay configuration. + + All sub-objects use whole-object replacement when present; omitted sub-objects + preserve the existing value. + """ created: datetime diff --git a/src/cloudflare/types/network_interconnects/cni_create_params.py b/src/cloudflare/types/network_interconnects/cni_create_params.py index 22518f602cf..d6f6b7a9482 100644 --- a/src/cloudflare/types/network_interconnects/cni_create_params.py +++ b/src/cloudflare/types/network_interconnects/cni_create_params.py @@ -37,7 +37,11 @@ class BGP(TypedDict, total=False): """ASN used on the customer end of the BGP session""" extra_prefixes: Required[SequenceNotStr[str]] - """Extra set of static prefixes to advertise to the customer's end of the session""" + """ + Extra set of static prefixes to advertise to the customer's end of the session + Prefixes containing host bits will be normalized to contain network bits only. + Duplicates are not allowed. + """ md5_key: Optional[str] """MD5 key to use for session authentication. diff --git a/src/cloudflare/types/network_interconnects/cni_create_response.py b/src/cloudflare/types/network_interconnects/cni_create_response.py index 95edb94e877..f50d80683f8 100644 --- a/src/cloudflare/types/network_interconnects/cni_create_response.py +++ b/src/cloudflare/types/network_interconnects/cni_create_response.py @@ -21,7 +21,11 @@ class BGP(BaseModel): """ASN used on the customer end of the BGP session""" extra_prefixes: List[str] - """Extra set of static prefixes to advertise to the customer's end of the session""" + """ + Extra set of static prefixes to advertise to the customer's end of the session + Prefixes containing host bits will be normalized to contain network bits only. + Duplicates are not allowed. + """ md5_key: Optional[str] = None """MD5 key to use for session authentication. @@ -68,12 +72,8 @@ class CNICreateResponse(BaseModel): bgp: Optional[BGP] = None bgp_mode: Optional[Literal["dynamic_route_exchange", "advertise_only"]] = None - """The BGP mode for a CNI. - - Controls the customer-facing data path: + """The BGP mode for a CNI. One of the following: - - `DynamicRouteExchange` — Full BGP: routes flow through to conduit via CRE / - bgp-bridge / bgp-bridge-receiver. - - `AdvertiseOnly` — static advertisement via taserver, no routes exchanged with - Conduit + - `dynamic_route_exchange` + - `advertise_only` """ diff --git a/src/cloudflare/types/network_interconnects/cni_get_response.py b/src/cloudflare/types/network_interconnects/cni_get_response.py index 873fd156182..dc81502619c 100644 --- a/src/cloudflare/types/network_interconnects/cni_get_response.py +++ b/src/cloudflare/types/network_interconnects/cni_get_response.py @@ -21,7 +21,11 @@ class BGP(BaseModel): """ASN used on the customer end of the BGP session""" extra_prefixes: List[str] - """Extra set of static prefixes to advertise to the customer's end of the session""" + """ + Extra set of static prefixes to advertise to the customer's end of the session + Prefixes containing host bits will be normalized to contain network bits only. + Duplicates are not allowed. + """ md5_key: Optional[str] = None """MD5 key to use for session authentication. @@ -68,12 +72,8 @@ class CNIGetResponse(BaseModel): bgp: Optional[BGP] = None bgp_mode: Optional[Literal["dynamic_route_exchange", "advertise_only"]] = None - """The BGP mode for a CNI. - - Controls the customer-facing data path: + """The BGP mode for a CNI. One of the following: - - `DynamicRouteExchange` — Full BGP: routes flow through to conduit via CRE / - bgp-bridge / bgp-bridge-receiver. - - `AdvertiseOnly` — static advertisement via taserver, no routes exchanged with - Conduit + - `dynamic_route_exchange` + - `advertise_only` """ diff --git a/src/cloudflare/types/network_interconnects/cni_list_response.py b/src/cloudflare/types/network_interconnects/cni_list_response.py index 0da7cffa5a3..72dc090f934 100644 --- a/src/cloudflare/types/network_interconnects/cni_list_response.py +++ b/src/cloudflare/types/network_interconnects/cni_list_response.py @@ -21,7 +21,11 @@ class ItemBGP(BaseModel): """ASN used on the customer end of the BGP session""" extra_prefixes: List[str] - """Extra set of static prefixes to advertise to the customer's end of the session""" + """ + Extra set of static prefixes to advertise to the customer's end of the session + Prefixes containing host bits will be normalized to contain network bits only. + Duplicates are not allowed. + """ md5_key: Optional[str] = None """MD5 key to use for session authentication. @@ -68,14 +72,10 @@ class Item(BaseModel): bgp: Optional[ItemBGP] = None bgp_mode: Optional[Literal["dynamic_route_exchange", "advertise_only"]] = None - """The BGP mode for a CNI. - - Controls the customer-facing data path: + """The BGP mode for a CNI. One of the following: - - `DynamicRouteExchange` — Full BGP: routes flow through to conduit via CRE / - bgp-bridge / bgp-bridge-receiver. - - `AdvertiseOnly` — static advertisement via taserver, no routes exchanged with - Conduit + - `dynamic_route_exchange` + - `advertise_only` """ diff --git a/src/cloudflare/types/network_interconnects/cni_update_params.py b/src/cloudflare/types/network_interconnects/cni_update_params.py index 603f326ef79..4343714e028 100644 --- a/src/cloudflare/types/network_interconnects/cni_update_params.py +++ b/src/cloudflare/types/network_interconnects/cni_update_params.py @@ -36,14 +36,10 @@ class CNIUpdateParams(TypedDict, total=False): bgp: BGP bgp_mode: Literal["dynamic_route_exchange", "advertise_only"] - """The BGP mode for a CNI. + """The BGP mode for a CNI. One of the following: - Controls the customer-facing data path: - - - `DynamicRouteExchange` — Full BGP: routes flow through to conduit via CRE / - bgp-bridge / bgp-bridge-receiver. - - `AdvertiseOnly` — static advertisement via taserver, no routes exchanged with - Conduit + - `dynamic_route_exchange` + - `advertise_only` """ @@ -60,7 +56,11 @@ class BGP(TypedDict, total=False): """ASN used on the customer end of the BGP session""" extra_prefixes: Required[SequenceNotStr[str]] - """Extra set of static prefixes to advertise to the customer's end of the session""" + """ + Extra set of static prefixes to advertise to the customer's end of the session + Prefixes containing host bits will be normalized to contain network bits only. + Duplicates are not allowed. + """ md5_key: Optional[str] """MD5 key to use for session authentication. diff --git a/src/cloudflare/types/network_interconnects/cni_update_response.py b/src/cloudflare/types/network_interconnects/cni_update_response.py index e6defccbe94..09ddd7d7262 100644 --- a/src/cloudflare/types/network_interconnects/cni_update_response.py +++ b/src/cloudflare/types/network_interconnects/cni_update_response.py @@ -21,7 +21,11 @@ class BGP(BaseModel): """ASN used on the customer end of the BGP session""" extra_prefixes: List[str] - """Extra set of static prefixes to advertise to the customer's end of the session""" + """ + Extra set of static prefixes to advertise to the customer's end of the session + Prefixes containing host bits will be normalized to contain network bits only. + Duplicates are not allowed. + """ md5_key: Optional[str] = None """MD5 key to use for session authentication. @@ -68,12 +72,8 @@ class CNIUpdateResponse(BaseModel): bgp: Optional[BGP] = None bgp_mode: Optional[Literal["dynamic_route_exchange", "advertise_only"]] = None - """The BGP mode for a CNI. - - Controls the customer-facing data path: + """The BGP mode for a CNI. One of the following: - - `DynamicRouteExchange` — Full BGP: routes flow through to conduit via CRE / - bgp-bridge / bgp-bridge-receiver. - - `AdvertiseOnly` — static advertisement via taserver, no routes exchanged with - Conduit + - `dynamic_route_exchange` + - `advertise_only` """ diff --git a/src/cloudflare/types/organizations/__init__.py b/src/cloudflare/types/organizations/__init__.py index cef118fbcce..af7b2fd5f68 100644 --- a/src/cloudflare/types/organizations/__init__.py +++ b/src/cloudflare/types/organizations/__init__.py @@ -6,7 +6,6 @@ from .organization_profile import OrganizationProfile as OrganizationProfile from .organization_list_params import OrganizationListParams as OrganizationListParams from .organization_create_params import OrganizationCreateParams as OrganizationCreateParams -from .organization_profile_param import OrganizationProfileParam as OrganizationProfileParam from .organization_update_params import OrganizationUpdateParams as OrganizationUpdateParams from .organization_delete_response import OrganizationDeleteResponse as OrganizationDeleteResponse from .organization_profile_update_params import OrganizationProfileUpdateParams as OrganizationProfileUpdateParams diff --git a/src/cloudflare/types/organizations/billing/usage_get_response.py b/src/cloudflare/types/organizations/billing/usage_get_response.py index 2ddba857f87..6ab3aa3a5bd 100644 --- a/src/cloudflare/types/organizations/billing/usage_get_response.py +++ b/src/cloudflare/types/organizations/billing/usage_get_response.py @@ -34,12 +34,6 @@ class UsageGetResponseItem(BaseModel): charge_period_start: datetime = FieldInfo(alias="ChargePeriodStart") """Inclusive start of the time interval during which the usage was consumed.""" - consumed_quantity: float = FieldInfo(alias="ConsumedQuantity") - """Measured usage amount within the charge period. - - Reflects raw metered consumption before pricing transformations. - """ - consumed_unit: str = FieldInfo(alias="ConsumedUnit") """ Unit of measure for the consumed quantity (e.g., "GB", "Requests", @@ -98,6 +92,12 @@ class UsageGetResponseItem(BaseModel): invoiced in a previous billing period. """ + consumed_quantity: Optional[float] = FieldInfo(alias="ConsumedQuantity", default=None) + """Measured usage amount within the charge period. + + Reflects raw metered consumption before pricing transformations. + """ + contracted_cost: Optional[float] = FieldInfo(alias="ContractedCost", default=None) """ Cost calculated by multiplying ContractedUnitPrice and the corresponding diff --git a/src/cloudflare/types/organizations/organization.py b/src/cloudflare/types/organizations/organization.py index 0a1beb82da4..3c61026bc5c 100644 --- a/src/cloudflare/types/organizations/organization.py +++ b/src/cloudflare/types/organizations/organization.py @@ -32,6 +32,8 @@ class MetaTenantFlags(BaseModel): class Meta(BaseModel): + are_child_accounts_accessible_by_org_members: Optional[bool] = None + hierarchy_tags: Optional[List[str]] = None """ Ordered chain of organization tags from the root organization down to (and @@ -46,6 +48,8 @@ class Meta(BaseModel): tenant_flags: Optional[MetaTenantFlags] = None """Enable features for Organizations.""" + tenant_type: Optional[str] = None + if TYPE_CHECKING: # Some versions of Pydantic <2.8.0 have a bug and don’t allow assigning a # value to this field, so for compatibility we avoid doing it at runtime. diff --git a/src/cloudflare/types/organizations/organization_create_params.py b/src/cloudflare/types/organizations/organization_create_params.py index 111a6446acc..2e11c3f24e5 100644 --- a/src/cloudflare/types/organizations/organization_create_params.py +++ b/src/cloudflare/types/organizations/organization_create_params.py @@ -4,18 +4,38 @@ from typing_extensions import Required, TypedDict -from .organization_profile_param import OrganizationProfileParam - -__all__ = ["OrganizationCreateParams", "Parent"] +__all__ = ["OrganizationCreateParams", "Parent", "Profile"] class OrganizationCreateParams(TypedDict, total=False): name: Required[str] + """The Organization name, limited to 65 UTF-8 bytes.""" parent: Parent - profile: OrganizationProfileParam + profile: Profile + """Optional profile fields, each limited to 1,000 UTF-8 bytes. + + An empty profile is ignored. + """ class Parent(TypedDict, total=False): id: Required[str] + + +class Profile(TypedDict, total=False): + """Optional profile fields, each limited to 1,000 UTF-8 bytes. + + An empty profile is ignored. + """ + + business_address: str + + business_email: str + + business_name: str + + business_phone: str + + external_metadata: str diff --git a/src/cloudflare/types/organizations/organization_list_params.py b/src/cloudflare/types/organizations/organization_list_params.py index 1567d6b973f..eb3999fb77e 100644 --- a/src/cloudflare/types/organizations/organization_list_params.py +++ b/src/cloudflare/types/organizations/organization_list_params.py @@ -8,7 +8,7 @@ from ..._types import SequenceNotStr from ..._utils import PropertyInfo -__all__ = ["OrganizationListParams", "Containing", "Name", "Parent"] +__all__ = ["OrganizationListParams", "Containing", "Member", "Name", "Parent"] class OrganizationListParams(TypedDict, total=False): @@ -20,8 +20,23 @@ class OrganizationListParams(TypedDict, total=False): containing: Containing + direction: Literal["asc", "desc"] + """Sort direction for the `order_by` field. + + Defaults to `asc` when `order_by` is specified. + """ + + member: Member + name: Name + order_by: Literal["name"] + """Field to order results by. + + Currently supported values: `name`. When not specified, results are ordered by + hierarchy. + """ + page_size: int """The amount of items to return. Defaults to 10.""" @@ -60,6 +75,15 @@ class Containing(TypedDict, total=False): """ +class Member(TypedDict, total=False): + email: str + """ + Filter organizations to those where the given user, by email, is an active + member of that exact organization. This does not include hierarchy-derived + access. + """ + + class Name(TypedDict, total=False): contains: str """ diff --git a/src/cloudflare/types/organizations/organization_profile_param.py b/src/cloudflare/types/organizations/organization_profile_param.py deleted file mode 100644 index 5de4427d1a9..00000000000 --- a/src/cloudflare/types/organizations/organization_profile_param.py +++ /dev/null @@ -1,19 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing_extensions import Required, TypedDict - -__all__ = ["OrganizationProfileParam"] - - -class OrganizationProfileParam(TypedDict, total=False): - business_address: Required[str] - - business_email: Required[str] - - business_name: Required[str] - - business_phone: Required[str] - - external_metadata: Required[str] diff --git a/src/cloudflare/types/organizations/organization_profile_update_params.py b/src/cloudflare/types/organizations/organization_profile_update_params.py index 6bd3a7f3bff..e2d101183fd 100644 --- a/src/cloudflare/types/organizations/organization_profile_update_params.py +++ b/src/cloudflare/types/organizations/organization_profile_update_params.py @@ -2,18 +2,19 @@ from __future__ import annotations -from typing_extensions import Required, TypedDict +from typing import Optional +from typing_extensions import TypedDict __all__ = ["OrganizationProfileUpdateParams"] class OrganizationProfileUpdateParams(TypedDict, total=False): - business_address: Required[str] + business_address: Optional[str] - business_email: Required[str] + business_email: Optional[str] - business_name: Required[str] + business_name: Optional[str] - business_phone: Required[str] + business_phone: Optional[str] - external_metadata: Required[str] + external_metadata: Optional[str] diff --git a/src/cloudflare/types/organizations/organization_update_params.py b/src/cloudflare/types/organizations/organization_update_params.py index 59eb21a280c..6d529687382 100644 --- a/src/cloudflare/types/organizations/organization_update_params.py +++ b/src/cloudflare/types/organizations/organization_update_params.py @@ -2,20 +2,20 @@ from __future__ import annotations -from typing_extensions import Required, TypedDict +from typing_extensions import TypedDict -from .organization_profile_param import OrganizationProfileParam - -__all__ = ["OrganizationUpdateParams", "Parent"] +__all__ = ["OrganizationUpdateParams"] class OrganizationUpdateParams(TypedDict, total=False): - name: Required[str] - - parent: Parent + name: str + """The Organization's display name, limited to 65 UTF-8 bytes. - profile: OrganizationProfileParam + An omitted, empty, or unchanged value is a no-op. + """ + parent_id: str + """The current parent Organization ID. -class Parent(TypedDict, total=False): - id: Required[str] + A different value is rejected; this endpoint cannot move an Organization. + """ diff --git a/src/cloudflare/types/pages/project.py b/src/cloudflare/types/pages/project.py index fc245ecf6a7..a785632e3eb 100644 --- a/src/cloudflare/types/pages/project.py +++ b/src/cloudflare/types/pages/project.py @@ -48,6 +48,7 @@ "DeploymentConfigsProductionServices", "DeploymentConfigsProductionVectorizeBindings", "BuildConfig", + "BuildImageAutoUpgrade", "Source", "SourceConfig", ] @@ -190,7 +191,12 @@ class DeploymentConfigsPreview(BaseModel): """Whether to always use the latest compatibility date for Pages Functions.""" build_image_major_version: int - """The major version of the build image to use for Pages Functions.""" + """The major version of the build image to use for Pages Functions. + + Version 1 is retired and its projects are moved to version 3. Once a project's + builds have been moved, this is the version the builds run on and + `build_image_auto_upgrade` is set on the project. + """ compatibility_date: str """Compatibility date used for Pages Functions.""" @@ -390,7 +396,12 @@ class DeploymentConfigsProduction(BaseModel): """Whether to always use the latest compatibility date for Pages Functions.""" build_image_major_version: int - """The major version of the build image to use for Pages Functions.""" + """The major version of the build image to use for Pages Functions. + + Version 1 is retired and its projects are moved to version 3. Once a project's + builds have been moved, this is the version the builds run on and + `build_image_auto_upgrade` is set on the project. + """ compatibility_date: str """Compatibility date used for Pages Functions.""" @@ -485,6 +496,18 @@ class BuildConfig(BaseModel): """Directory to run the command.""" +class BuildImageAutoUpgrade(BaseModel): + """ + Present when the project is set to a retired build image major version and its builds have been moved to a newer one. `build_image_major_version` in `deployment_configs` then reports the version the builds run on. + """ + + from_version: int + """The retired build image major version the project is set to.""" + + to_version: int + """The build image major version the project's builds run on.""" + + class SourceConfig(BaseModel): deployments_enabled: bool """ @@ -597,6 +620,13 @@ class Project(BaseModel): build_config: Optional[BuildConfig] = None """Configs for the project build process.""" + build_image_auto_upgrade: Optional[BuildImageAutoUpgrade] = None + """ + Present when the project is set to a retired build image major version and its + builds have been moved to a newer one. `build_image_major_version` in + `deployment_configs` then reports the version the builds run on. + """ + domains: Optional[List[str]] = None """A list of associated custom domains for the project.""" diff --git a/src/cloudflare/types/pages/project_create_params.py b/src/cloudflare/types/pages/project_create_params.py index f65d3f072ad..e86a0127d6b 100644 --- a/src/cloudflare/types/pages/project_create_params.py +++ b/src/cloudflare/types/pages/project_create_params.py @@ -240,7 +240,11 @@ class DeploymentConfigsPreview(TypedDict, total=False): """Browser bindings used for Pages Functions.""" build_image_major_version: int - """The major version of the build image to use for Pages Functions.""" + """The major version of the build image to use for Pages Functions. + + Version 1 is retired and its projects are moved to version 3. Once a project's + builds have been moved, a request that sets version 1 is rejected. + """ compatibility_date: str """Compatibility date used for Pages Functions.""" @@ -436,7 +440,11 @@ class DeploymentConfigsProduction(TypedDict, total=False): """Browser bindings used for Pages Functions.""" build_image_major_version: int - """The major version of the build image to use for Pages Functions.""" + """The major version of the build image to use for Pages Functions. + + Version 1 is retired and its projects are moved to version 3. Once a project's + builds have been moved, a request that sets version 1 is rejected. + """ compatibility_date: str """Compatibility date used for Pages Functions.""" diff --git a/src/cloudflare/types/pages/project_edit_params.py b/src/cloudflare/types/pages/project_edit_params.py index 13ecfb802b9..96a39c75d62 100644 --- a/src/cloudflare/types/pages/project_edit_params.py +++ b/src/cloudflare/types/pages/project_edit_params.py @@ -240,7 +240,11 @@ class DeploymentConfigsPreview(TypedDict, total=False): """Browser bindings used for Pages Functions.""" build_image_major_version: int - """The major version of the build image to use for Pages Functions.""" + """The major version of the build image to use for Pages Functions. + + Version 1 is retired and its projects are moved to version 3. Once a project's + builds have been moved, a request that sets version 1 is rejected. + """ compatibility_date: str """Compatibility date used for Pages Functions.""" @@ -436,7 +440,11 @@ class DeploymentConfigsProduction(TypedDict, total=False): """Browser bindings used for Pages Functions.""" build_image_major_version: int - """The major version of the build image to use for Pages Functions.""" + """The major version of the build image to use for Pages Functions. + + Version 1 is retired and its projects are moved to version 3. Once a project's + builds have been moved, a request that sets version 1 is rejected. + """ compatibility_date: str """Compatibility date used for Pages Functions.""" diff --git a/src/cloudflare/types/pipelines/sink_list_params.py b/src/cloudflare/types/pipelines/sink_list_params.py index 30d3df07320..987adf1841f 100644 --- a/src/cloudflare/types/pipelines/sink_list_params.py +++ b/src/cloudflare/types/pipelines/sink_list_params.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing_extensions import Required, TypedDict +from typing_extensions import Literal, Required, TypedDict __all__ = ["SinkListParams"] @@ -11,9 +11,15 @@ class SinkListParams(TypedDict, total=False): account_id: Required[str] """Specifies the public ID of the account.""" + direction: Literal["asc", "desc"] + """Sort direction.""" + name: str """Filters sinks by name (case-insensitive substring).""" + order_by: Literal["name", "created_at"] + """Sorts sinks by this field. Defaults to `created_at`.""" + page: float per_page: float diff --git a/src/cloudflare/types/pipelines/stream_list_params.py b/src/cloudflare/types/pipelines/stream_list_params.py index dd019be9f7f..a85e3b8f96b 100644 --- a/src/cloudflare/types/pipelines/stream_list_params.py +++ b/src/cloudflare/types/pipelines/stream_list_params.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing_extensions import Required, TypedDict +from typing_extensions import Literal, Required, TypedDict __all__ = ["StreamListParams"] @@ -11,9 +11,15 @@ class StreamListParams(TypedDict, total=False): account_id: Required[str] """Specifies the public ID of the account.""" + direction: Literal["asc", "desc"] + """Sort direction.""" + name: str """Filters streams by name (case-insensitive substring).""" + order_by: Literal["name", "created_at"] + """Sorts streams by this field. Defaults to `created_at`.""" + page: float per_page: float diff --git a/src/cloudflare/types/precursor/__init__.py b/src/cloudflare/types/precursor/__init__.py index 1ea054333b7..4d4bca9bf14 100644 --- a/src/cloudflare/types/precursor/__init__.py +++ b/src/cloudflare/types/precursor/__init__.py @@ -2,7 +2,5 @@ from __future__ import annotations -from .enforcement_rule import EnforcementRule as EnforcementRule from .precursor_config import PrecursorConfig as PrecursorConfig -from .enforcement_rule_param import EnforcementRuleParam as EnforcementRuleParam from .precursor_update_params import PrecursorUpdateParams as PrecursorUpdateParams diff --git a/src/cloudflare/types/precursor/enforcement_rule.py b/src/cloudflare/types/precursor/enforcement_rule.py deleted file mode 100644 index b70c3b7807a..00000000000 --- a/src/cloudflare/types/precursor/enforcement_rule.py +++ /dev/null @@ -1,28 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from typing import Optional -from typing_extensions import Literal - -from ..._models import BaseModel - -__all__ = ["EnforcementRule"] - - -class EnforcementRule(BaseModel): - expression: str - """The filter expression that determines which requests the rule matches.""" - - mode: Literal["min-friction", "max-security"] - """The override mode Precursor applies to requests matching an enforcement rule. - - Unlike `default_mode`, this cannot be `off`. - """ - - id: Optional[str] = None - """The read-only identifier that Cloudflare assigns to the rule.""" - - description: Optional[str] = None - """An informative description of the rule.""" - - enabled: Optional[bool] = None - """Whether the rule is active.""" diff --git a/src/cloudflare/types/precursor/enforcement_rule_param.py b/src/cloudflare/types/precursor/enforcement_rule_param.py deleted file mode 100644 index 36b33ff5ed5..00000000000 --- a/src/cloudflare/types/precursor/enforcement_rule_param.py +++ /dev/null @@ -1,24 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing_extensions import Literal, Required, TypedDict - -__all__ = ["EnforcementRuleParam"] - - -class EnforcementRuleParam(TypedDict, total=False): - expression: Required[str] - """The filter expression that determines which requests the rule matches.""" - - mode: Required[Literal["min-friction", "max-security"]] - """The override mode Precursor applies to requests matching an enforcement rule. - - Unlike `default_mode`, this cannot be `off`. - """ - - description: str - """An informative description of the rule.""" - - enabled: bool - """Whether the rule is active.""" diff --git a/src/cloudflare/types/precursor/precursor_config.py b/src/cloudflare/types/precursor/precursor_config.py index 5d9241987c0..95f7856804d 100644 --- a/src/cloudflare/types/precursor/precursor_config.py +++ b/src/cloudflare/types/precursor/precursor_config.py @@ -4,17 +4,37 @@ from typing_extensions import Literal from ..._models import BaseModel -from .enforcement_rule import EnforcementRule -__all__ = ["PrecursorConfig"] +__all__ = ["PrecursorConfig", "Rule"] + + +class Rule(BaseModel): + expression: str + """The filter expression that determines which requests the rule matches.""" + + show_interstitial: bool + """Whether Precursor shows an interstitial when it takes action on a request.""" + + id: Optional[str] = None + """The read-only identifier that Cloudflare assigns to the rule.""" + + description: Optional[str] = None + """An informative description of the rule.""" + + enabled: Optional[bool] = None + """Whether the rule is active.""" class PrecursorConfig(BaseModel): - default_mode: Optional[Literal["off", "min-friction", "max-security"]] = None - """ - The zone-level Precursor enforcement mode applied to requests that do not match - a more specific enforcement rule. + mode: Optional[Literal["off", "monitor", "arm"]] = None + """Controls Precursor detection for the zone. + + `off` disables detection, `monitor` records detections without affecting bot + scores, and `arm` allows detections to affect bot scores. """ - enforcement_rules: Optional[List[EnforcementRule]] = None - """The ordered list of enforcement rules for the zone.""" + rules: Optional[List[Rule]] = None + """The ordered list of Precursor rules for the zone.""" + + show_interstitial: Optional[bool] = None + """Whether Precursor shows an interstitial when it takes action on a request.""" diff --git a/src/cloudflare/types/precursor/precursor_update_params.py b/src/cloudflare/types/precursor/precursor_update_params.py index c47de4b4972..9fe1c11c5fa 100644 --- a/src/cloudflare/types/precursor/precursor_update_params.py +++ b/src/cloudflare/types/precursor/precursor_update_params.py @@ -3,22 +3,42 @@ from __future__ import annotations from typing import Iterable -from typing_extensions import Literal, Required, TypedDict +from typing_extensions import Literal, Required, Annotated, TypedDict -from .enforcement_rule_param import EnforcementRuleParam +from ..._utils import PropertyInfo -__all__ = ["PrecursorUpdateParams"] +__all__ = ["PrecursorUpdateParams", "Rule"] class PrecursorUpdateParams(TypedDict, total=False): zone_id: Required[str] """Identifier.""" - default_mode: Literal["off", "min-friction", "max-security"] - """ - The zone-level Precursor enforcement mode applied to requests that do not match - a more specific enforcement rule. + cloudflare_version: Annotated[Literal["1.0"], PropertyInfo(alias="Cloudflare-Version")] + + mode: Literal["off", "monitor", "arm"] + """Controls Precursor detection for the zone. + + `off` disables detection, `monitor` records detections without affecting bot + scores, and `arm` allows detections to affect bot scores. """ - enforcement_rules: Iterable[EnforcementRuleParam] - """The ordered list of enforcement rules for the zone.""" + rules: Iterable[Rule] + """The ordered list of Precursor rules for the zone.""" + + show_interstitial: bool + """Whether Precursor shows an interstitial when it takes action on a request.""" + + +class Rule(TypedDict, total=False): + expression: Required[str] + """The filter expression that determines which requests the rule matches.""" + + show_interstitial: Required[bool] + """Whether Precursor shows an interstitial when it takes action on a request.""" + + description: str + """An informative description of the rule.""" + + enabled: bool + """Whether the rule is active.""" diff --git a/src/cloudflare/types/r2/bucket_list_response.py b/src/cloudflare/types/r2/bucket_list_response.py index a52999502b5..7fb368f265f 100644 --- a/src/cloudflare/types/r2/bucket_list_response.py +++ b/src/cloudflare/types/r2/bucket_list_response.py @@ -1,6 +1,6 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import List, Optional +from typing import List from .bucket import Bucket from ..._models import BaseModel @@ -9,4 +9,4 @@ class BucketListResponse(BaseModel): - buckets: Optional[List[Bucket]] = None + buckets: List[Bucket] diff --git a/src/cloudflare/types/r2/buckets/__init__.py b/src/cloudflare/types/r2/buckets/__init__.py index a948b9e11b8..aabb5140bf8 100644 --- a/src/cloudflare/types/r2/buckets/__init__.py +++ b/src/cloudflare/types/r2/buckets/__init__.py @@ -4,11 +4,16 @@ from .sippy import Sippy as Sippy from .provider import Provider as Provider +from .job_list_params import JobListParams as JobListParams +from .job_get_response import JobGetResponse as JobGetResponse from .cors_get_response import CORSGetResponse as CORSGetResponse +from .job_create_params import JobCreateParams as JobCreateParams +from .job_list_response import JobListResponse as JobListResponse from .lock_get_response import LockGetResponse as LockGetResponse from .cors_update_params import CORSUpdateParams as CORSUpdateParams from .lock_update_params import LockUpdateParams as LockUpdateParams from .object_list_params import ObjectListParams as ObjectListParams +from .job_create_response import JobCreateResponse as JobCreateResponse from .sippy_update_params import SippyUpdateParams as SippyUpdateParams from .metric_list_response import MetricListResponse as MetricListResponse from .object_list_response import ObjectListResponse as ObjectListResponse diff --git a/src/cloudflare/types/r2/buckets/job_create_params.py b/src/cloudflare/types/r2/buckets/job_create_params.py new file mode 100644 index 00000000000..dbca176fc19 --- /dev/null +++ b/src/cloudflare/types/r2/buckets/job_create_params.py @@ -0,0 +1,51 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Union +from typing_extensions import Literal, Required, Annotated, TypeAlias, TypedDict + +from ...._utils import PropertyInfo + +__all__ = ["JobCreateParams", "R2CreatePrefixDeleteJobRequest", "R2CreateStorageClassMigrationJobRequest"] + + +class R2CreatePrefixDeleteJobRequest(TypedDict, total=False): + account_id: Required[str] + """Cloudflare account ID that owns the R2 resource.""" + + job_type: Required[Annotated[Literal["prefixDelete"], PropertyInfo(alias="jobType")]] + + prefix: Required[str] + """Prefix matched against object keys. + + A non-empty value must end in `/`. An empty string empties the entire bucket. + """ + + cf_r2_data_catalog_check: Annotated[str, PropertyInfo(alias="cf-r2-data-catalog-check")] + + cf_r2_jurisdiction: Annotated[ + Literal["default", "eu", "us", "fedramp", "fedramp-high"], PropertyInfo(alias="cf-r2-jurisdiction") + ] + + +class R2CreateStorageClassMigrationJobRequest(TypedDict, total=False): + account_id: Required[str] + """Cloudflare account ID that owns the R2 resource.""" + + job_type: Required[Annotated[Literal["storageClassMigration"], PropertyInfo(alias="jobType")]] + + destination_storage_class: Annotated[ + Literal["Standard", "InfrequentAccess"], PropertyInfo(alias="destinationStorageClass") + ] + + source_storage_class: Annotated[Literal["Standard", "InfrequentAccess"], PropertyInfo(alias="sourceStorageClass")] + + cf_r2_data_catalog_check: Annotated[str, PropertyInfo(alias="cf-r2-data-catalog-check")] + + cf_r2_jurisdiction: Annotated[ + Literal["default", "eu", "us", "fedramp", "fedramp-high"], PropertyInfo(alias="cf-r2-jurisdiction") + ] + + +JobCreateParams: TypeAlias = Union[R2CreatePrefixDeleteJobRequest, R2CreateStorageClassMigrationJobRequest] diff --git a/src/cloudflare/types/r2/buckets/job_create_response.py b/src/cloudflare/types/r2/buckets/job_create_response.py new file mode 100644 index 00000000000..7a31073334e --- /dev/null +++ b/src/cloudflare/types/r2/buckets/job_create_response.py @@ -0,0 +1,122 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Union, Optional +from datetime import datetime +from typing_extensions import Literal, Annotated, TypeAlias + +from pydantic import Field as FieldInfo + +from ...._utils import PropertyInfo +from ...._models import BaseModel + +__all__ = [ + "JobCreateResponse", + "R2PrefixDeleteJob", + "R2PrefixDeleteJobPrefixDelete", + "R2StorageClassMigrationJob", + "R2StorageClassMigrationJobStorageClassMigration", +] + + +class R2PrefixDeleteJobPrefixDelete(BaseModel): + """Details specific to the prefix-delete job.""" + + deleted_objects: int = FieldInfo(alias="deletedObjects") + """Number of objects deleted by the job so far.""" + + prefix: str + """The prefix matched against object keys. + + An empty string means the entire bucket. + """ + + is_bucket_clear: Optional[bool] = FieldInfo(alias="isBucketClear", default=None) + """True when the job was created to clear the entire bucket. + + This field can be absent on jobs created before Empty Bucket job tracking was + introduced. + """ + + +class R2PrefixDeleteJob(BaseModel): + """Descriptor of a prefix-delete job. + + An empty prefix indicates a job that empties the + whole bucket. + """ + + id: str + """Unique identifier used to poll the job.""" + + job_type: Literal["prefixDelete"] = FieldInfo(alias="jobType") + """The job kind.""" + + prefix_delete: R2PrefixDeleteJobPrefixDelete = FieldInfo(alias="prefixDelete") + """Details specific to the prefix-delete job.""" + + start_time: datetime = FieldInfo(alias="startTime") + """When the job was created.""" + + status: Literal["ENQUEUED", "RUNNING", "COMPLETED", "FAILED", "CANCELLED"] + """Lifecycle status of a bucket background job.""" + + end_time: Optional[datetime] = FieldInfo(alias="endTime", default=None) + """When the job finished. Absent while the job is still `ENQUEUED` or `RUNNING`.""" + + +class R2StorageClassMigrationJobStorageClassMigration(BaseModel): + destination_storage_class: Literal["Standard", "InfrequentAccess"] = FieldInfo(alias="destinationStorageClass") + """The storage class objects are migrated to. + + The source and destination storage classes always differ. + """ + + migrated_objects: int = FieldInfo(alias="migratedObjects") + """Number of object versions migrated successfully.""" + + source_storage_class: Literal["Standard", "InfrequentAccess"] = FieldInfo(alias="sourceStorageClass") + """The storage class objects are migrated from.""" + + failed_bytes: Optional[int] = FieldInfo(alias="failedBytes", default=None) + """Payload bytes belonging to failed object versions.""" + + failed_objects: Optional[int] = FieldInfo(alias="failedObjects", default=None) + """Number of object versions that failed migration.""" + + migrated_bytes: Optional[int] = FieldInfo(alias="migratedBytes", default=None) + """Object payload bytes migrated successfully. Present for Metadata Worker jobs.""" + + migrated_metadata_bytes: Optional[int] = FieldInfo(alias="migratedMetadataBytes", default=None) + """Object metadata bytes migrated successfully. Present for Metadata Worker jobs.""" + + skipped_bytes: Optional[int] = FieldInfo(alias="skippedBytes", default=None) + """Payload bytes belonging to skipped object versions.""" + + skipped_objects: Optional[int] = FieldInfo(alias="skippedObjects", default=None) + """Number of object versions skipped.""" + + +class R2StorageClassMigrationJob(BaseModel): + """Descriptor of a bucket-wide storage-class migration job.""" + + id: str + """Unique identifier used to poll the job.""" + + job_type: Literal["storageClassMigration"] = FieldInfo(alias="jobType") + """The job kind.""" + + start_time: datetime = FieldInfo(alias="startTime") + """When the job was created.""" + + status: Literal["ENQUEUED", "RUNNING", "COMPLETED", "FAILED", "CANCELLED"] + """Lifecycle status of a bucket background job.""" + + storage_class_migration: R2StorageClassMigrationJobStorageClassMigration = FieldInfo(alias="storageClassMigration") + + end_time: Optional[datetime] = FieldInfo(alias="endTime", default=None) + """When the job finished. Absent while the job is still `ENQUEUED` or `RUNNING`.""" + + +JobCreateResponse: TypeAlias = Annotated[ + Union[R2PrefixDeleteJob, R2StorageClassMigrationJob], PropertyInfo(discriminator="job_type") +] diff --git a/src/cloudflare/types/r2/buckets/job_get_response.py b/src/cloudflare/types/r2/buckets/job_get_response.py new file mode 100644 index 00000000000..38a3b49ccfe --- /dev/null +++ b/src/cloudflare/types/r2/buckets/job_get_response.py @@ -0,0 +1,122 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Union, Optional +from datetime import datetime +from typing_extensions import Literal, Annotated, TypeAlias + +from pydantic import Field as FieldInfo + +from ...._utils import PropertyInfo +from ...._models import BaseModel + +__all__ = [ + "JobGetResponse", + "R2PrefixDeleteJob", + "R2PrefixDeleteJobPrefixDelete", + "R2StorageClassMigrationJob", + "R2StorageClassMigrationJobStorageClassMigration", +] + + +class R2PrefixDeleteJobPrefixDelete(BaseModel): + """Details specific to the prefix-delete job.""" + + deleted_objects: int = FieldInfo(alias="deletedObjects") + """Number of objects deleted by the job so far.""" + + prefix: str + """The prefix matched against object keys. + + An empty string means the entire bucket. + """ + + is_bucket_clear: Optional[bool] = FieldInfo(alias="isBucketClear", default=None) + """True when the job was created to clear the entire bucket. + + This field can be absent on jobs created before Empty Bucket job tracking was + introduced. + """ + + +class R2PrefixDeleteJob(BaseModel): + """Descriptor of a prefix-delete job. + + An empty prefix indicates a job that empties the + whole bucket. + """ + + id: str + """Unique identifier used to poll the job.""" + + job_type: Literal["prefixDelete"] = FieldInfo(alias="jobType") + """The job kind.""" + + prefix_delete: R2PrefixDeleteJobPrefixDelete = FieldInfo(alias="prefixDelete") + """Details specific to the prefix-delete job.""" + + start_time: datetime = FieldInfo(alias="startTime") + """When the job was created.""" + + status: Literal["ENQUEUED", "RUNNING", "COMPLETED", "FAILED", "CANCELLED"] + """Lifecycle status of a bucket background job.""" + + end_time: Optional[datetime] = FieldInfo(alias="endTime", default=None) + """When the job finished. Absent while the job is still `ENQUEUED` or `RUNNING`.""" + + +class R2StorageClassMigrationJobStorageClassMigration(BaseModel): + destination_storage_class: Literal["Standard", "InfrequentAccess"] = FieldInfo(alias="destinationStorageClass") + """The storage class objects are migrated to. + + The source and destination storage classes always differ. + """ + + migrated_objects: int = FieldInfo(alias="migratedObjects") + """Number of object versions migrated successfully.""" + + source_storage_class: Literal["Standard", "InfrequentAccess"] = FieldInfo(alias="sourceStorageClass") + """The storage class objects are migrated from.""" + + failed_bytes: Optional[int] = FieldInfo(alias="failedBytes", default=None) + """Payload bytes belonging to failed object versions.""" + + failed_objects: Optional[int] = FieldInfo(alias="failedObjects", default=None) + """Number of object versions that failed migration.""" + + migrated_bytes: Optional[int] = FieldInfo(alias="migratedBytes", default=None) + """Object payload bytes migrated successfully. Present for Metadata Worker jobs.""" + + migrated_metadata_bytes: Optional[int] = FieldInfo(alias="migratedMetadataBytes", default=None) + """Object metadata bytes migrated successfully. Present for Metadata Worker jobs.""" + + skipped_bytes: Optional[int] = FieldInfo(alias="skippedBytes", default=None) + """Payload bytes belonging to skipped object versions.""" + + skipped_objects: Optional[int] = FieldInfo(alias="skippedObjects", default=None) + """Number of object versions skipped.""" + + +class R2StorageClassMigrationJob(BaseModel): + """Descriptor of a bucket-wide storage-class migration job.""" + + id: str + """Unique identifier used to poll the job.""" + + job_type: Literal["storageClassMigration"] = FieldInfo(alias="jobType") + """The job kind.""" + + start_time: datetime = FieldInfo(alias="startTime") + """When the job was created.""" + + status: Literal["ENQUEUED", "RUNNING", "COMPLETED", "FAILED", "CANCELLED"] + """Lifecycle status of a bucket background job.""" + + storage_class_migration: R2StorageClassMigrationJobStorageClassMigration = FieldInfo(alias="storageClassMigration") + + end_time: Optional[datetime] = FieldInfo(alias="endTime", default=None) + """When the job finished. Absent while the job is still `ENQUEUED` or `RUNNING`.""" + + +JobGetResponse: TypeAlias = Annotated[ + Union[R2PrefixDeleteJob, R2StorageClassMigrationJob], PropertyInfo(discriminator="job_type") +] diff --git a/src/cloudflare/types/r2/buckets/job_list_params.py b/src/cloudflare/types/r2/buckets/job_list_params.py new file mode 100644 index 00000000000..21877db0a1e --- /dev/null +++ b/src/cloudflare/types/r2/buckets/job_list_params.py @@ -0,0 +1,33 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal, Required, Annotated, TypedDict + +from ...._utils import PropertyInfo + +__all__ = ["JobListParams"] + + +class JobListParams(TypedDict, total=False): + account_id: Required[str] + """Cloudflare account ID that owns the R2 resource.""" + + continuation_token: Annotated[str, PropertyInfo(alias="continuationToken")] + """Pagination token received as `nextContinuationToken` in the previous response.""" + + job_type: Annotated[Literal["prefixDelete", "storageClassMigration"], PropertyInfo(alias="jobType")] + """Restricts results to jobs of the specified type.""" + + max_keys: Annotated[int, PropertyInfo(alias="maxKeys")] + """Maximum number of jobs to return.""" + + status: Literal["ENQUEUED", "RUNNING", "COMPLETED", "FAILED", "CANCELLED"] + """Restricts results to jobs with the specified status. + + `jobType` is required when this parameter is provided. + """ + + cf_r2_jurisdiction: Annotated[ + Literal["default", "eu", "us", "fedramp", "fedramp-high"], PropertyInfo(alias="cf-r2-jurisdiction") + ] diff --git a/src/cloudflare/types/r2/buckets/job_list_response.py b/src/cloudflare/types/r2/buckets/job_list_response.py new file mode 100644 index 00000000000..5617403c6b1 --- /dev/null +++ b/src/cloudflare/types/r2/buckets/job_list_response.py @@ -0,0 +1,133 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Union, Optional +from datetime import datetime +from typing_extensions import Literal, Annotated, TypeAlias + +from pydantic import Field as FieldInfo + +from ...._utils import PropertyInfo +from ...._models import BaseModel + +__all__ = [ + "JobListResponse", + "Job", + "JobR2PrefixDeleteJob", + "JobR2PrefixDeleteJobPrefixDelete", + "JobR2StorageClassMigrationJob", + "JobR2StorageClassMigrationJobStorageClassMigration", +] + + +class JobR2PrefixDeleteJobPrefixDelete(BaseModel): + """Details specific to the prefix-delete job.""" + + deleted_objects: int = FieldInfo(alias="deletedObjects") + """Number of objects deleted by the job so far.""" + + prefix: str + """The prefix matched against object keys. + + An empty string means the entire bucket. + """ + + is_bucket_clear: Optional[bool] = FieldInfo(alias="isBucketClear", default=None) + """True when the job was created to clear the entire bucket. + + This field can be absent on jobs created before Empty Bucket job tracking was + introduced. + """ + + +class JobR2PrefixDeleteJob(BaseModel): + """Descriptor of a prefix-delete job. + + An empty prefix indicates a job that empties the + whole bucket. + """ + + id: str + """Unique identifier used to poll the job.""" + + job_type: Literal["prefixDelete"] = FieldInfo(alias="jobType") + """The job kind.""" + + prefix_delete: JobR2PrefixDeleteJobPrefixDelete = FieldInfo(alias="prefixDelete") + """Details specific to the prefix-delete job.""" + + start_time: datetime = FieldInfo(alias="startTime") + """When the job was created.""" + + status: Literal["ENQUEUED", "RUNNING", "COMPLETED", "FAILED", "CANCELLED"] + """Lifecycle status of a bucket background job.""" + + end_time: Optional[datetime] = FieldInfo(alias="endTime", default=None) + """When the job finished. Absent while the job is still `ENQUEUED` or `RUNNING`.""" + + +class JobR2StorageClassMigrationJobStorageClassMigration(BaseModel): + destination_storage_class: Literal["Standard", "InfrequentAccess"] = FieldInfo(alias="destinationStorageClass") + """The storage class objects are migrated to. + + The source and destination storage classes always differ. + """ + + migrated_objects: int = FieldInfo(alias="migratedObjects") + """Number of object versions migrated successfully.""" + + source_storage_class: Literal["Standard", "InfrequentAccess"] = FieldInfo(alias="sourceStorageClass") + """The storage class objects are migrated from.""" + + failed_bytes: Optional[int] = FieldInfo(alias="failedBytes", default=None) + """Payload bytes belonging to failed object versions.""" + + failed_objects: Optional[int] = FieldInfo(alias="failedObjects", default=None) + """Number of object versions that failed migration.""" + + migrated_bytes: Optional[int] = FieldInfo(alias="migratedBytes", default=None) + """Object payload bytes migrated successfully. Present for Metadata Worker jobs.""" + + migrated_metadata_bytes: Optional[int] = FieldInfo(alias="migratedMetadataBytes", default=None) + """Object metadata bytes migrated successfully. Present for Metadata Worker jobs.""" + + skipped_bytes: Optional[int] = FieldInfo(alias="skippedBytes", default=None) + """Payload bytes belonging to skipped object versions.""" + + skipped_objects: Optional[int] = FieldInfo(alias="skippedObjects", default=None) + """Number of object versions skipped.""" + + +class JobR2StorageClassMigrationJob(BaseModel): + """Descriptor of a bucket-wide storage-class migration job.""" + + id: str + """Unique identifier used to poll the job.""" + + job_type: Literal["storageClassMigration"] = FieldInfo(alias="jobType") + """The job kind.""" + + start_time: datetime = FieldInfo(alias="startTime") + """When the job was created.""" + + status: Literal["ENQUEUED", "RUNNING", "COMPLETED", "FAILED", "CANCELLED"] + """Lifecycle status of a bucket background job.""" + + storage_class_migration: JobR2StorageClassMigrationJobStorageClassMigration = FieldInfo( + alias="storageClassMigration" + ) + + end_time: Optional[datetime] = FieldInfo(alias="endTime", default=None) + """When the job finished. Absent while the job is still `ENQUEUED` or `RUNNING`.""" + + +Job: TypeAlias = Annotated[ + Union[JobR2PrefixDeleteJob, JobR2StorageClassMigrationJob], PropertyInfo(discriminator="job_type") +] + + +class JobListResponse(BaseModel): + jobs: List[Job] + """Bucket jobs in the current page.""" + + next_continuation_token: Optional[str] = FieldInfo(alias="nextContinuationToken", default=None) + """Token to pass as `continuationToken` to retrieve the next page.""" diff --git a/src/cloudflare/types/r2_data_catalog/__init__.py b/src/cloudflare/types/r2_data_catalog/__init__.py index 6245944cdf2..9ec0f107cbf 100644 --- a/src/cloudflare/types/r2_data_catalog/__init__.py +++ b/src/cloudflare/types/r2_data_catalog/__init__.py @@ -7,6 +7,7 @@ from .credential_create_params import CredentialCreateParams as CredentialCreateParams from .r2_data_catalog_get_response import R2DataCatalogGetResponse as R2DataCatalogGetResponse from .r2_data_catalog_delete_params import R2DataCatalogDeleteParams as R2DataCatalogDeleteParams +from .r2_data_catalog_enable_params import R2DataCatalogEnableParams as R2DataCatalogEnableParams from .r2_data_catalog_list_response import R2DataCatalogListResponse as R2DataCatalogListResponse from .maintenance_config_get_response import MaintenanceConfigGetResponse as MaintenanceConfigGetResponse from .r2_data_catalog_enable_response import R2DataCatalogEnableResponse as R2DataCatalogEnableResponse diff --git a/src/cloudflare/types/r2_data_catalog/r2_data_catalog_enable_params.py b/src/cloudflare/types/r2_data_catalog/r2_data_catalog_enable_params.py new file mode 100644 index 00000000000..fa3d3df9d21 --- /dev/null +++ b/src/cloudflare/types/r2_data_catalog/r2_data_catalog_enable_params.py @@ -0,0 +1,22 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Required, TypedDict + +__all__ = ["R2DataCatalogEnableParams", "Credential"] + + +class R2DataCatalogEnableParams(TypedDict, total=False): + account_id: Required[str] + """Use this to identify the account.""" + + credential: Credential + """Contains request to store catalog credentials.""" + + +class Credential(TypedDict, total=False): + """Contains request to store catalog credentials.""" + + token: Required[str] + """Provides the Cloudflare API token for accessing R2.""" diff --git a/src/cloudflare/types/r2_data_catalog/r2_data_catalog_get_response.py b/src/cloudflare/types/r2_data_catalog/r2_data_catalog_get_response.py index 23ada9faaaa..afd3ecb0a9d 100644 --- a/src/cloudflare/types/r2_data_catalog/r2_data_catalog_get_response.py +++ b/src/cloudflare/types/r2_data_catalog/r2_data_catalog_get_response.py @@ -55,7 +55,7 @@ class MaintenanceConfig(BaseModel): class R2DataCatalogGetResponse(BaseModel): - """Contains R2 Data Catalog information.""" + """Contains catalog information.""" id: str """Use this to uniquely identify the catalog.""" @@ -72,5 +72,11 @@ class R2DataCatalogGetResponse(BaseModel): credential_status: Optional[Literal["present", "absent"]] = None """Shows the credential configuration status.""" + jurisdiction: Optional[str] = None + """Specifies the data-locality jurisdiction of the catalog. + + The first enable sets it, and it cannot change. Currently always `default`. + """ + maintenance_config: Optional[MaintenanceConfig] = None """Configures maintenance for the catalog.""" diff --git a/src/cloudflare/types/r2_data_catalog/r2_data_catalog_list_response.py b/src/cloudflare/types/r2_data_catalog/r2_data_catalog_list_response.py index 1aad8b37deb..d36f95145ea 100644 --- a/src/cloudflare/types/r2_data_catalog/r2_data_catalog_list_response.py +++ b/src/cloudflare/types/r2_data_catalog/r2_data_catalog_list_response.py @@ -56,7 +56,7 @@ class WarehouseMaintenanceConfig(BaseModel): class Warehouse(BaseModel): - """Contains R2 Data Catalog information.""" + """Contains catalog information.""" id: str """Use this to uniquely identify the catalog.""" @@ -73,6 +73,12 @@ class Warehouse(BaseModel): credential_status: Optional[Literal["present", "absent"]] = None """Shows the credential configuration status.""" + jurisdiction: Optional[str] = None + """Specifies the data-locality jurisdiction of the catalog. + + The first enable sets it, and it cannot change. Currently always `default`. + """ + maintenance_config: Optional[WarehouseMaintenanceConfig] = None """Configures maintenance for the catalog.""" diff --git a/src/cloudflare/types/radar/annotation_list_response.py b/src/cloudflare/types/radar/annotation_list_response.py index 02a5eca9bb9..7f480caf2a6 100644 --- a/src/cloudflare/types/radar/annotation_list_response.py +++ b/src/cloudflare/types/radar/annotation_list_response.py @@ -33,6 +33,12 @@ class AnnotationASNsDetail(BaseModel): class AnnotationEntity(BaseModel): + entity_location: Optional[str] = FieldInfo(alias="entityLocation", default=None) + """ + Alpha-2 code of the country the entity belongs to (GEOLOCATION and AS entities + only). + """ + entity_name: Optional[str] = FieldInfo(alias="entityName", default=None) entity_type: str = FieldInfo(alias="entityType") diff --git a/src/cloudflare/types/radar/annotations/outage_get_response.py b/src/cloudflare/types/radar/annotations/outage_get_response.py index 904a7adc40a..3b6b64d1b76 100644 --- a/src/cloudflare/types/radar/annotations/outage_get_response.py +++ b/src/cloudflare/types/radar/annotations/outage_get_response.py @@ -34,6 +34,12 @@ class AnnotationASNsDetail(BaseModel): class AnnotationEntity(BaseModel): + entity_location: Optional[str] = FieldInfo(alias="entityLocation", default=None) + """ + Alpha-2 code of the country the entity belongs to (GEOLOCATION and AS entities + only). + """ + entity_name: Optional[str] = FieldInfo(alias="entityName", default=None) entity_type: str = FieldInfo(alias="entityType") diff --git a/src/cloudflare/types/radar/traffic_anomaly_get_response.py b/src/cloudflare/types/radar/traffic_anomaly_get_response.py index de94730c6e6..717a41de2e0 100644 --- a/src/cloudflare/types/radar/traffic_anomaly_get_response.py +++ b/src/cloudflare/types/radar/traffic_anomaly_get_response.py @@ -52,9 +52,17 @@ class TrafficAnomaly(BaseModel): origin_details: Optional[TrafficAnomalyOriginDetails] = FieldInfo(alias="originDetails", default=None) + outage_id: Optional[str] = FieldInfo(alias="outageId", default=None) + """ID of the published outage this anomaly was confirmed as, if any.""" + start_date: datetime = FieldInfo(alias="startDate") status: str + """ + Verification status: UNVERIFIED (automatically detected, not yet validated by + Radar), TP (verified by Radar) or VERIFIED (verified by Radar and a third-party + source). + """ type: str diff --git a/src/cloudflare/types/realtime_kit/__init__.py b/src/cloudflare/types/realtime_kit/__init__.py index cbc1b408d44..66002a6a380 100644 --- a/src/cloudflare/types/realtime_kit/__init__.py +++ b/src/cloudflare/types/realtime_kit/__init__.py @@ -84,6 +84,9 @@ from .meeting_get_meeting_participant_response import ( MeetingGetMeetingParticipantResponse as MeetingGetMeetingParticipantResponse, ) +from .meeting_refresh_participant_token_params import ( + MeetingRefreshParticipantTokenParams as MeetingRefreshParticipantTokenParams, +) from .recording_get_active_recordings_response import ( RecordingGetActiveRecordingsResponse as RecordingGetActiveRecordingsResponse, ) diff --git a/src/cloudflare/types/realtime_kit/livestream_get_active_livestreams_for_livestream_id_response.py b/src/cloudflare/types/realtime_kit/livestream_get_active_livestreams_for_livestream_id_response.py index facb7c18daf..a651cc099b2 100644 --- a/src/cloudflare/types/realtime_kit/livestream_get_active_livestreams_for_livestream_id_response.py +++ b/src/cloudflare/types/realtime_kit/livestream_get_active_livestreams_for_livestream_id_response.py @@ -10,71 +10,82 @@ class DataLivestream(BaseModel): - id: Optional[str] = None + id: str + """ID of the livestream.""" - created_at: Optional[datetime] = None - """Timestamp the object was created at. The time is returned in ISO format.""" + created_at: datetime + """Timestamp the livestream was created at, in ISO format.""" - disabled: Optional[str] = None - """Specifies if the livestream was disabled.""" + disabled: bool + """Specifies if the livestream is disabled.""" - ingest_server: Optional[str] = None + external_id: str + """ID of the underlying Cloudflare Stream live input.""" + + ingest_server: str """The server URL to which the RTMP encoder sends the video and audio data.""" + manual_ingest: bool + """Specifies if the livestream is ingested manually by an RTMP encoder.""" + meeting_id: Optional[str] = None - """ID of the meeting.""" + """ID of the meeting being livestreamed, if any.""" name: Optional[str] = None """Name of the livestream.""" - playback_url: Optional[str] = None + playback_url: str """The web address that viewers can use to watch the livestream.""" - status: Optional[Literal["LIVE", "IDLE", "ERRORED", "INVOKED"]] = None + status: Literal["LIVE", "IDLE", "ERRORED", "INVOKED", "METRICS_READY"] + """Status of the livestream.""" - stream_key: Optional[str] = None - """Unique key for accessing each livestream.""" + stream_key: str + """Unique key for accessing each livestream. Empty if the livestream is disabled.""" - updated_at: Optional[datetime] = None - """Timestamp the object was updated at. The time is returned in ISO format.""" + updated_at: datetime + """Timestamp the livestream was last updated at, in ISO format.""" class DataSession(BaseModel): - id: Optional[str] = None + id: str + """ID of the livestream session.""" - created_at: Optional[datetime] = None - """Timestamp the object was created at. The time is returned in ISO format.""" + created_at: datetime + """Timestamp the livestream session was created at, in ISO format.""" err_message: Optional[str] = None + """Error message, if the livestream session failed.""" - ingest_seconds: Optional[str] = None + ingest_seconds: float """The time duration for which the input was given or the meeting was streamed.""" invoked_time: Optional[datetime] = None - """Timestamp the object was invoked. The time is returned in ISO format.""" + """Timestamp the livestream session was invoked at, in ISO format.""" - livestream_id: Optional[str] = None + livestream_id: str + """ID of the livestream.""" started_time: Optional[datetime] = None - """Timestamp the object was started. The time is returned in ISO format.""" + """Timestamp the livestream session started at, in ISO format.""" stopped_time: Optional[datetime] = None - """Timestamp the object was stopped. The time is returned in ISO format.""" + """Timestamp the livestream session stopped at, in ISO format.""" - updated_at: Optional[datetime] = None - """Timestamp the object was updated at. The time is returned in ISO format.""" + updated_at: datetime + """Timestamp the livestream session was last updated at, in ISO format.""" - viewer_seconds: Optional[str] = None + viewer_seconds: float """The total view time for which the viewers watched the stream.""" class Data(BaseModel): - livestream: Optional[DataLivestream] = None + livestream: DataLivestream - session: Optional[DataSession] = None + session: DataSession class LivestreamGetActiveLivestreamsForLivestreamIDResponse(BaseModel): - data: Optional[Data] = None + data: Data - success: Optional[bool] = None + success: bool diff --git a/src/cloudflare/types/realtime_kit/livestream_get_all_livestreams_response.py b/src/cloudflare/types/realtime_kit/livestream_get_all_livestreams_response.py index 0ad5351d655..d7fbd16e18d 100644 --- a/src/cloudflare/types/realtime_kit/livestream_get_all_livestreams_response.py +++ b/src/cloudflare/types/realtime_kit/livestream_get_all_livestreams_response.py @@ -1,56 +1,63 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import Optional +from typing import List, Optional from datetime import datetime from typing_extensions import Literal from ..._models import BaseModel -__all__ = ["LivestreamGetAllLivestreamsResponse", "Data", "DataPaging"] - - -class DataPaging(BaseModel): - end_offset: Optional[int] = None - - start_offset: Optional[int] = None - - total_count: Optional[int] = None +__all__ = ["LivestreamGetAllLivestreamsResponse", "Data", "Paging"] class Data(BaseModel): - id: Optional[str] = None - """The ID of the livestream.""" + id: str + """ID of the livestream.""" + + created_at: datetime + """Timestamp the livestream was created at, in ISO format.""" - created_at: Optional[datetime] = None - """Timestamp the object was created at. The time is returned in ISO format.""" + disabled: bool + """Specifies if the livestream is disabled.""" - disabled: Optional[str] = None - """Specifies if the livestream was disabled.""" + external_id: str + """ID of the underlying Cloudflare Stream live input.""" - ingest_server: Optional[str] = None + ingest_server: str """The server URL to which the RTMP encoder sends the video and audio data.""" + manual_ingest: bool + """Specifies if the livestream is ingested manually by an RTMP encoder.""" + meeting_id: Optional[str] = None - """ID of the meeting.""" + """ID of the meeting being livestreamed, if any.""" name: Optional[str] = None """Name of the livestream.""" - paging: Optional[DataPaging] = None - - playback_url: Optional[str] = None + playback_url: str """The web address that viewers can use to watch the livestream.""" - status: Optional[Literal["LIVE", "IDLE", "ERRORED", "INVOKED"]] = None + status: Literal["LIVE", "IDLE", "ERRORED", "INVOKED", "METRICS_READY"] + """Status of the livestream.""" + + stream_key: str + """Unique key for accessing each livestream. Empty if the livestream is disabled.""" + + updated_at: datetime + """Timestamp the livestream was last updated at, in ISO format.""" - stream_key: Optional[str] = None - """Unique key for accessing each livestream.""" - updated_at: Optional[datetime] = None - """Timestamp the object was updated at. The time is returned in ISO format.""" +class Paging(BaseModel): + end_offset: float + + start_offset: float + + total_count: float class LivestreamGetAllLivestreamsResponse(BaseModel): - data: Optional[Data] = None + data: List[Data] + + paging: Paging - success: Optional[bool] = None + success: bool diff --git a/src/cloudflare/types/realtime_kit/livestream_get_livestream_analytics_complete_response.py b/src/cloudflare/types/realtime_kit/livestream_get_livestream_analytics_complete_response.py index 6d1f075e225..0d6c7ed81ab 100644 --- a/src/cloudflare/types/realtime_kit/livestream_get_livestream_analytics_complete_response.py +++ b/src/cloudflare/types/realtime_kit/livestream_get_livestream_analytics_complete_response.py @@ -11,10 +11,10 @@ class Data(BaseModel): count: Optional[int] = None """Count of total livestreams.""" - total_ingest_seconds: Optional[int] = None + total_ingest_seconds: Optional[float] = None """Total time duration for which the input was given or the meeting was streamed.""" - total_viewer_seconds: Optional[int] = None + total_viewer_seconds: Optional[float] = None """Total view time for which the viewers watched the stream.""" diff --git a/src/cloudflare/types/realtime_kit/livestream_get_livestream_analytics_daywise_response.py b/src/cloudflare/types/realtime_kit/livestream_get_livestream_analytics_daywise_response.py index 08482b3ec78..517aa086684 100644 --- a/src/cloudflare/types/realtime_kit/livestream_get_livestream_analytics_daywise_response.py +++ b/src/cloudflare/types/realtime_kit/livestream_get_livestream_analytics_daywise_response.py @@ -14,10 +14,10 @@ class Data(BaseModel): date: Optional[str] = None """Analytics date.""" - total_ingest_seconds: Optional[int] = None + total_ingest_seconds: Optional[float] = None """Total time duration for which the input was given or the meeting was streamed.""" - total_viewer_seconds: Optional[int] = None + total_viewer_seconds: Optional[float] = None """Total view time for which the viewers watched the stream.""" diff --git a/src/cloudflare/types/realtime_kit/livestream_get_livestream_session_details_for_session_id_response.py b/src/cloudflare/types/realtime_kit/livestream_get_livestream_session_details_for_session_id_response.py index 905735b6428..b6405d0c8e1 100644 --- a/src/cloudflare/types/realtime_kit/livestream_get_livestream_session_details_for_session_id_response.py +++ b/src/cloudflare/types/realtime_kit/livestream_get_livestream_session_details_for_session_id_response.py @@ -9,34 +9,38 @@ class Data(BaseModel): - id: Optional[str] = None - """The livestream ID.""" + id: str + """ID of the livestream session.""" - created_at: Optional[datetime] = None - """Timestamp the object was created at. The time is returned in ISO format.""" + created_at: datetime + """Timestamp the livestream session was created at, in ISO format.""" err_message: Optional[str] = None - """The server URL to which the RTMP encoder sends the video and audio data.""" + """Error message, if the livestream session failed.""" - ingest_seconds: Optional[int] = None - """Name of the livestream.""" + ingest_seconds: float + """The time duration for which the input was given or the meeting was streamed.""" - livestream_id: Optional[str] = None + invoked_time: Optional[datetime] = None + """Timestamp the livestream session was invoked at, in ISO format.""" - started_time: Optional[str] = None - """Unique key for accessing each livestream.""" + livestream_id: str + """ID of the livestream.""" - stopped_time: Optional[str] = None - """The web address that viewers can use to watch the livestream.""" + started_time: Optional[datetime] = None + """Timestamp the livestream session started at, in ISO format.""" - updated_at: Optional[str] = None - """Timestamp the object was updated at. The time is returned in ISO format.""" + stopped_time: Optional[datetime] = None + """Timestamp the livestream session stopped at, in ISO format.""" - viewer_seconds: Optional[int] = None - """Specifies if the livestream was disabled.""" + updated_at: datetime + """Timestamp the livestream session was last updated at, in ISO format.""" + + viewer_seconds: float + """The total view time for which the viewers watched the stream.""" class LivestreamGetLivestreamSessionDetailsForSessionIDResponse(BaseModel): - data: Optional[Data] = None + data: Data - success: Optional[bool] = None + success: bool diff --git a/src/cloudflare/types/realtime_kit/livestream_get_livestream_session_for_livestream_id_response.py b/src/cloudflare/types/realtime_kit/livestream_get_livestream_session_for_livestream_id_response.py index 76018eb6795..e188747ef24 100644 --- a/src/cloudflare/types/realtime_kit/livestream_get_livestream_session_for_livestream_id_response.py +++ b/src/cloudflare/types/realtime_kit/livestream_get_livestream_session_for_livestream_id_response.py @@ -1,98 +1,101 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import Optional +from typing import List, Optional from datetime import datetime from typing_extensions import Literal from ..._models import BaseModel -__all__ = [ - "LivestreamGetLivestreamSessionForLivestreamIDResponse", - "Data", - "DataLivestream", - "DataPaging", - "DataSession", -] +__all__ = ["LivestreamGetLivestreamSessionForLivestreamIDResponse", "Data", "DataLivestream", "DataSession", "Paging"] class DataLivestream(BaseModel): - id: Optional[str] = None + id: str """ID of the livestream.""" - created_at: Optional[str] = None - """Timestamp the object was created at. The time is returned in ISO format.""" + created_at: datetime + """Timestamp the livestream was created at, in ISO format.""" - disabled: Optional[str] = None - """Specifies if the livestream was disabled.""" + disabled: bool + """Specifies if the livestream is disabled.""" - ingest_server: Optional[str] = None + external_id: str + """ID of the underlying Cloudflare Stream live input.""" + + ingest_server: str """The server URL to which the RTMP encoder sends the video and audio data.""" + manual_ingest: bool + """Specifies if the livestream is ingested manually by an RTMP encoder.""" + meeting_id: Optional[str] = None - """The ID of the meeting.""" + """ID of the meeting being livestreamed, if any.""" name: Optional[str] = None """Name of the livestream.""" - playback_url: Optional[str] = None + playback_url: str """The web address that viewers can use to watch the livestream.""" - status: Optional[Literal["LIVE", "IDLE", "ERRORED", "INVOKED"]] = None - - stream_key: Optional[str] = None - """Unique key for accessing each livestream.""" - - updated_at: Optional[str] = None - """Timestamp the object was updated at. The time is returned in ISO format.""" - - -class DataPaging(BaseModel): - end_offset: Optional[int] = None + status: Literal["LIVE", "IDLE", "ERRORED", "INVOKED", "METRICS_READY"] + """Status of the livestream.""" - start_offset: Optional[int] = None + stream_key: str + """Unique key for accessing each livestream. Empty if the livestream is disabled.""" - total_count: Optional[int] = None + updated_at: datetime + """Timestamp the livestream was last updated at, in ISO format.""" class DataSession(BaseModel): - id: Optional[str] = None - """ID of the session.""" + id: str + """ID of the livestream session.""" - created_at: Optional[datetime] = None - """Timestamp the object was created at. The time is returned in ISO format.""" + created_at: datetime + """Timestamp the livestream session was created at, in ISO format.""" err_message: Optional[str] = None + """Error message, if the livestream session failed.""" - ingest_seconds: Optional[float] = None + ingest_seconds: float """The time duration for which the input was given or the meeting was streamed.""" invoked_time: Optional[datetime] = None - """Timestamp the object was invoked. The time is returned in ISO format.""" + """Timestamp the livestream session was invoked at, in ISO format.""" - livestream_id: Optional[str] = None + livestream_id: str + """ID of the livestream.""" started_time: Optional[datetime] = None - """Timestamp the object was started. The time is returned in ISO format.""" + """Timestamp the livestream session started at, in ISO format.""" stopped_time: Optional[datetime] = None - """Timestamp the object was stopped. The time is returned in ISO format.""" + """Timestamp the livestream session stopped at, in ISO format.""" - updated_at: Optional[datetime] = None - """Timestamp the object was updated at. The time is returned in ISO format.""" + updated_at: datetime + """Timestamp the livestream session was last updated at, in ISO format.""" - viewer_seconds: Optional[float] = None + viewer_seconds: float """The total view time for which the viewers watched the stream.""" class Data(BaseModel): - livestream: Optional[DataLivestream] = None + livestream: DataLivestream + + sessions: List[DataSession] + - paging: Optional[DataPaging] = None +class Paging(BaseModel): + end_offset: float - session: Optional[DataSession] = None + start_offset: float + + total_count: float class LivestreamGetLivestreamSessionForLivestreamIDResponse(BaseModel): - data: Optional[Data] = None + data: Data + + paging: Paging - success: Optional[bool] = None + success: bool diff --git a/src/cloudflare/types/realtime_kit/livestream_get_meeting_active_livestreams_response.py b/src/cloudflare/types/realtime_kit/livestream_get_meeting_active_livestreams_response.py index dbeec9a6161..d808fa59bca 100644 --- a/src/cloudflare/types/realtime_kit/livestream_get_meeting_active_livestreams_response.py +++ b/src/cloudflare/types/realtime_kit/livestream_get_meeting_active_livestreams_response.py @@ -10,36 +10,44 @@ class Data(BaseModel): - id: Optional[str] = None - """The livestream ID.""" + id: str + """ID of the livestream.""" - created_at: Optional[datetime] = None - """Timestamp the object was created at. The time is returned in ISO format.""" + created_at: datetime + """Timestamp the livestream was created at, in ISO format.""" - disabled: Optional[str] = None - """Specifies if the livestream was disabled.""" + disabled: bool + """Specifies if the livestream is disabled.""" - ingest_server: Optional[str] = None + external_id: str + """ID of the underlying Cloudflare Stream live input.""" + + ingest_server: str """The server URL to which the RTMP encoder sends the video and audio data.""" + manual_ingest: bool + """Specifies if the livestream is ingested manually by an RTMP encoder.""" + meeting_id: Optional[str] = None + """ID of the meeting being livestreamed, if any.""" name: Optional[str] = None """Name of the livestream.""" - playback_url: Optional[str] = None + playback_url: str """The web address that viewers can use to watch the livestream.""" - status: Optional[Literal["LIVE", "IDLE", "ERRORED", "INVOKED"]] = None + status: Literal["LIVE", "IDLE", "ERRORED", "INVOKED", "METRICS_READY"] + """Status of the livestream.""" - stream_key: Optional[str] = None - """Unique key for accessing each livestream.""" + stream_key: str + """Unique key for accessing each livestream. Empty if the livestream is disabled.""" - updated_at: Optional[datetime] = None - """Timestamp the object was updated at. The time is returned in ISO format.""" + updated_at: datetime + """Timestamp the livestream was last updated at, in ISO format.""" class LivestreamGetMeetingActiveLivestreamsResponse(BaseModel): - data: Optional[Data] = None + data: Data - success: Optional[bool] = None + success: bool diff --git a/src/cloudflare/types/realtime_kit/livestream_start_livestreaming_a_meeting_response.py b/src/cloudflare/types/realtime_kit/livestream_start_livestreaming_a_meeting_response.py index c28cc784585..23b3c682fa0 100644 --- a/src/cloudflare/types/realtime_kit/livestream_start_livestreaming_a_meeting_response.py +++ b/src/cloudflare/types/realtime_kit/livestream_start_livestreaming_a_meeting_response.py @@ -9,22 +9,29 @@ class Data(BaseModel): - id: Optional[str] = None - """The livestream ID.""" + id: str + """ID of the livestream.""" - ingest_server: Optional[str] = None + ingest_server: str """The server URL to which the RTMP encoder sends the video and audio data.""" - playback_url: Optional[str] = None + meeting_id: Optional[str] = None + """ID of the meeting being livestreamed, if any.""" + + name: Optional[str] = None + """Name of the livestream.""" + + playback_url: str """The web address that viewers can use to watch the livestream.""" - status: Optional[Literal["LIVE", "IDLE", "ERRORED", "INVOKED"]] = None + status: Literal["LIVE", "IDLE", "ERRORED", "INVOKED", "METRICS_READY"] + """Status of the livestream.""" - stream_key: Optional[str] = None - """Unique key for accessing each livestream.""" + stream_key: str + """Unique key for accessing each livestream. Empty if the livestream is disabled.""" class LivestreamStartLivestreamingAMeetingResponse(BaseModel): - data: Optional[Data] = None + data: Data - success: Optional[bool] = None + success: bool diff --git a/src/cloudflare/types/realtime_kit/meeting_add_participant_params.py b/src/cloudflare/types/realtime_kit/meeting_add_participant_params.py index 111b281d294..0f12fe3d136 100644 --- a/src/cloudflare/types/realtime_kit/meeting_add_participant_params.py +++ b/src/cloudflare/types/realtime_kit/meeting_add_participant_params.py @@ -2,10 +2,13 @@ from __future__ import annotations -from typing import Optional -from typing_extensions import Required, TypedDict +from typing import Union, Optional +from datetime import datetime +from typing_extensions import Required, Annotated, TypedDict -__all__ = ["MeetingAddParticipantParams"] +from ..._utils import PropertyInfo + +__all__ = ["MeetingAddParticipantParams", "Token"] class MeetingAddParticipantParams(TypedDict, total=False): @@ -25,8 +28,34 @@ class MeetingAddParticipantParams(TypedDict, total=False): preset_name: Required[str] """Name of the preset to apply to this participant.""" + token: Token + """Validity window of the participant authentication token. + + The window is [not_before, expires_on) and cannot be longer than 100 days. + Defaults to a token valid from now for 100 days. + """ + name: Optional[str] """(Optional) Name of the participant.""" picture: Optional[str] """(Optional) A URL to a picture to be used for the participant.""" + + +class Token(TypedDict, total=False): + """Validity window of the participant authentication token. + + The window is [not_before, expires_on) and cannot be longer than 100 days. Defaults to a token valid from now for 100 days. + """ + + expires_on: Annotated[Union[str, datetime], PropertyInfo(format="iso8601")] + """RFC 3339 timestamp with a timezone at or after which the token cannot be used. + + Must be in the future. Defaults to not_before plus 100 days. + """ + + not_before: Annotated[Union[str, datetime], PropertyInfo(format="iso8601")] + """RFC 3339 timestamp with a timezone before which the token cannot be used. + + Defaults to the current time. May be in the past. + """ diff --git a/src/cloudflare/types/realtime_kit/meeting_add_participant_response.py b/src/cloudflare/types/realtime_kit/meeting_add_participant_response.py index 9ea59e5585d..e095e946342 100644 --- a/src/cloudflare/types/realtime_kit/meeting_add_participant_response.py +++ b/src/cloudflare/types/realtime_kit/meeting_add_participant_response.py @@ -32,9 +32,18 @@ class Data(BaseModel): updated_at: datetime """When this object was updated. The time is returned in ISO format.""" + expires_on: Optional[datetime] = None + """Time at which the token stops being valid, in UTC. + + Returned when adding a participant. + """ + name: Optional[str] = None """Name of the participant.""" + not_before: Optional[datetime] = None + """Time from which the token is valid, in UTC. Returned when adding a participant.""" + picture: Optional[str] = None """URL to a picture of the participant.""" diff --git a/src/cloudflare/types/realtime_kit/meeting_create_params.py b/src/cloudflare/types/realtime_kit/meeting_create_params.py index 2460a22febf..90c20327e15 100644 --- a/src/cloudflare/types/realtime_kit/meeting_create_params.py +++ b/src/cloudflare/types/realtime_kit/meeting_create_params.py @@ -109,7 +109,11 @@ class AIConfigTranscription(TypedDict, total=False): """Adds specific terms to improve accurate detection during transcription.""" language: Literal["en-US", "en-IN", "de", "hi", "sv", "ru", "pl", "el", "fr", "nl"] - """Specifies the language code for transcription to ensure accurate results.""" + """Specifies the language code for transcription to ensure accurate results. + + If omitted, the language is auto-detected for post-meeting (Whisper) + transcription. + """ profanity_filter: bool """Control the inclusion of offensive language in transcriptions.""" diff --git a/src/cloudflare/types/realtime_kit/meeting_create_response.py b/src/cloudflare/types/realtime_kit/meeting_create_response.py index d5bd72c8e17..9049601ae0b 100644 --- a/src/cloudflare/types/realtime_kit/meeting_create_response.py +++ b/src/cloudflare/types/realtime_kit/meeting_create_response.py @@ -59,7 +59,11 @@ class DataAIConfigTranscription(BaseModel): """Adds specific terms to improve accurate detection during transcription.""" language: Optional[Literal["en-US", "en-IN", "de", "hi", "sv", "ru", "pl", "el", "fr", "nl"]] = None - """Specifies the language code for transcription to ensure accurate results.""" + """Specifies the language code for transcription to ensure accurate results. + + If omitted, the language is auto-detected for post-meeting (Whisper) + transcription. + """ profanity_filter: Optional[bool] = None """Control the inclusion of offensive language in transcriptions.""" diff --git a/src/cloudflare/types/realtime_kit/meeting_edit_participant_response.py b/src/cloudflare/types/realtime_kit/meeting_edit_participant_response.py index f32a3bae56d..cca789d2a69 100644 --- a/src/cloudflare/types/realtime_kit/meeting_edit_participant_response.py +++ b/src/cloudflare/types/realtime_kit/meeting_edit_participant_response.py @@ -32,9 +32,18 @@ class Data(BaseModel): updated_at: datetime """When this object was updated. The time is returned in ISO format.""" + expires_on: Optional[datetime] = None + """Time at which the token stops being valid, in UTC. + + Returned when adding a participant. + """ + name: Optional[str] = None """Name of the participant.""" + not_before: Optional[datetime] = None + """Time from which the token is valid, in UTC. Returned when adding a participant.""" + picture: Optional[str] = None """URL to a picture of the participant.""" diff --git a/src/cloudflare/types/realtime_kit/meeting_get_meeting_by_id_response.py b/src/cloudflare/types/realtime_kit/meeting_get_meeting_by_id_response.py index ef960ef3168..6b858636a1f 100644 --- a/src/cloudflare/types/realtime_kit/meeting_get_meeting_by_id_response.py +++ b/src/cloudflare/types/realtime_kit/meeting_get_meeting_by_id_response.py @@ -59,7 +59,11 @@ class DataAIConfigTranscription(BaseModel): """Adds specific terms to improve accurate detection during transcription.""" language: Optional[Literal["en-US", "en-IN", "de", "hi", "sv", "ru", "pl", "el", "fr", "nl"]] = None - """Specifies the language code for transcription to ensure accurate results.""" + """Specifies the language code for transcription to ensure accurate results. + + If omitted, the language is auto-detected for post-meeting (Whisper) + transcription. + """ profanity_filter: Optional[bool] = None """Control the inclusion of offensive language in transcriptions.""" diff --git a/src/cloudflare/types/realtime_kit/meeting_refresh_participant_token_params.py b/src/cloudflare/types/realtime_kit/meeting_refresh_participant_token_params.py new file mode 100644 index 00000000000..14af9ec99ec --- /dev/null +++ b/src/cloudflare/types/realtime_kit/meeting_refresh_participant_token_params.py @@ -0,0 +1,33 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Union +from datetime import datetime +from typing_extensions import Required, Annotated, TypedDict + +from ..._utils import PropertyInfo + +__all__ = ["MeetingRefreshParticipantTokenParams"] + + +class MeetingRefreshParticipantTokenParams(TypedDict, total=False): + account_id: Required[str] + """The account identifier tag.""" + + app_id: Required[str] + """The app identifier tag.""" + + meeting_id: Required[str] + + expires_on: Annotated[Union[str, datetime], PropertyInfo(format="iso8601")] + """RFC 3339 timestamp with a timezone at or after which the token cannot be used. + + Must be in the future. Defaults to not_before plus 100 days. + """ + + not_before: Annotated[Union[str, datetime], PropertyInfo(format="iso8601")] + """RFC 3339 timestamp with a timezone before which the token cannot be used. + + Defaults to the current time. May be in the past. + """ diff --git a/src/cloudflare/types/realtime_kit/meeting_refresh_participant_token_response.py b/src/cloudflare/types/realtime_kit/meeting_refresh_participant_token_response.py index a1658fb5f1a..cb6c635e20f 100644 --- a/src/cloudflare/types/realtime_kit/meeting_refresh_participant_token_response.py +++ b/src/cloudflare/types/realtime_kit/meeting_refresh_participant_token_response.py @@ -1,5 +1,7 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. +from datetime import datetime + from ..._models import BaseModel __all__ = ["MeetingRefreshParticipantTokenResponse", "Data"] @@ -11,6 +13,12 @@ class Data(BaseModel): token: str """Regenerated participant's authentication token.""" + expires_on: datetime + """Time at which the token stops being valid, in UTC.""" + + not_before: datetime + """Time from which the token is valid, in UTC.""" + class MeetingRefreshParticipantTokenResponse(BaseModel): data: Data diff --git a/src/cloudflare/types/realtime_kit/meeting_replace_meeting_by_id_params.py b/src/cloudflare/types/realtime_kit/meeting_replace_meeting_by_id_params.py index 4cfb92f59cd..1b47db27a32 100644 --- a/src/cloudflare/types/realtime_kit/meeting_replace_meeting_by_id_params.py +++ b/src/cloudflare/types/realtime_kit/meeting_replace_meeting_by_id_params.py @@ -112,7 +112,11 @@ class AIConfigTranscription(TypedDict, total=False): """Adds specific terms to improve accurate detection during transcription.""" language: Literal["en-US", "en-IN", "de", "hi", "sv", "ru", "pl", "el", "fr", "nl"] - """Specifies the language code for transcription to ensure accurate results.""" + """Specifies the language code for transcription to ensure accurate results. + + If omitted, the language is auto-detected for post-meeting (Whisper) + transcription. + """ profanity_filter: bool """Control the inclusion of offensive language in transcriptions.""" diff --git a/src/cloudflare/types/realtime_kit/meeting_replace_meeting_by_id_response.py b/src/cloudflare/types/realtime_kit/meeting_replace_meeting_by_id_response.py index f45224e181f..d76c6be18af 100644 --- a/src/cloudflare/types/realtime_kit/meeting_replace_meeting_by_id_response.py +++ b/src/cloudflare/types/realtime_kit/meeting_replace_meeting_by_id_response.py @@ -59,7 +59,11 @@ class DataAIConfigTranscription(BaseModel): """Adds specific terms to improve accurate detection during transcription.""" language: Optional[Literal["en-US", "en-IN", "de", "hi", "sv", "ru", "pl", "el", "fr", "nl"]] = None - """Specifies the language code for transcription to ensure accurate results.""" + """Specifies the language code for transcription to ensure accurate results. + + If omitted, the language is auto-detected for post-meeting (Whisper) + transcription. + """ profanity_filter: Optional[bool] = None """Control the inclusion of offensive language in transcriptions.""" diff --git a/src/cloudflare/types/realtime_kit/meeting_update_meeting_by_id_params.py b/src/cloudflare/types/realtime_kit/meeting_update_meeting_by_id_params.py index 1c292e999df..16b32fd5d92 100644 --- a/src/cloudflare/types/realtime_kit/meeting_update_meeting_by_id_params.py +++ b/src/cloudflare/types/realtime_kit/meeting_update_meeting_by_id_params.py @@ -118,7 +118,11 @@ class AIConfigTranscription(TypedDict, total=False): """Adds specific terms to improve accurate detection during transcription.""" language: Literal["en-US", "en-IN", "de", "hi", "sv", "ru", "pl", "el", "fr", "nl"] - """Specifies the language code for transcription to ensure accurate results.""" + """Specifies the language code for transcription to ensure accurate results. + + If omitted, the language is auto-detected for post-meeting (Whisper) + transcription. + """ profanity_filter: bool """Control the inclusion of offensive language in transcriptions.""" diff --git a/src/cloudflare/types/realtime_kit/meeting_update_meeting_by_id_response.py b/src/cloudflare/types/realtime_kit/meeting_update_meeting_by_id_response.py index f0b15746513..87511f17e65 100644 --- a/src/cloudflare/types/realtime_kit/meeting_update_meeting_by_id_response.py +++ b/src/cloudflare/types/realtime_kit/meeting_update_meeting_by_id_response.py @@ -59,7 +59,11 @@ class DataAIConfigTranscription(BaseModel): """Adds specific terms to improve accurate detection during transcription.""" language: Optional[Literal["en-US", "en-IN", "de", "hi", "sv", "ru", "pl", "el", "fr", "nl"]] = None - """Specifies the language code for transcription to ensure accurate results.""" + """Specifies the language code for transcription to ensure accurate results. + + If omitted, the language is auto-detected for post-meeting (Whisper) + transcription. + """ profanity_filter: Optional[bool] = None """Control the inclusion of offensive language in transcriptions.""" diff --git a/src/cloudflare/types/registrar/__init__.py b/src/cloudflare/types/registrar/__init__.py index 17a105ce42d..6aa26ed509c 100644 --- a/src/cloudflare/types/registrar/__init__.py +++ b/src/cloudflare/types/registrar/__init__.py @@ -2,10 +2,8 @@ from __future__ import annotations -from .domain import Domain as Domain from .registration import Registration as Registration from .workflow_status import WorkflowStatus as WorkflowStatus -from .domain_update_params import DomainUpdateParams as DomainUpdateParams from .extension_list_params import ExtensionListParams as ExtensionListParams from .extension_get_response import ExtensionGetResponse as ExtensionGetResponse from .registrar_check_params import RegistrarCheckParams as RegistrarCheckParams diff --git a/src/cloudflare/types/registrar/domain.py b/src/cloudflare/types/registrar/domain.py deleted file mode 100644 index 29af0543fc4..00000000000 --- a/src/cloudflare/types/registrar/domain.py +++ /dev/null @@ -1,121 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from typing import Optional -from datetime import datetime -from typing_extensions import Literal - -from ..._models import BaseModel - -__all__ = ["Domain", "RegistrantContact", "TransferIn"] - - -class RegistrantContact(BaseModel): - """Shows contact information for domain registrant.""" - - address: str - """Address.""" - - city: str - """City.""" - - country: Optional[str] = None - """The country in which the user lives.""" - - first_name: Optional[str] = None - """User's first name.""" - - last_name: Optional[str] = None - """User's last name.""" - - organization: str - """Name of organization.""" - - phone: Optional[str] = None - """User's telephone number.""" - - state: str - """State.""" - - zip: Optional[str] = None - """The zipcode or postal code where the user lives.""" - - id: Optional[str] = None - """Contact Identifier.""" - - address2: Optional[str] = None - """Optional address line for unit, floor, suite, etc.""" - - email: Optional[str] = None - """The contact email address of the user.""" - - fax: Optional[str] = None - """Contact fax number.""" - - -class TransferIn(BaseModel): - """Statuses for domain transfers into Cloudflare Registrar.""" - - accept_foa: Optional[Literal["needed", "ok"]] = None - """Status of the registrant authorization step.""" - - approve_transfer: Optional[Literal["needed", "ok", "pending", "trying", "rejected", "unknown"]] = None - """Status of the registry transfer-approval step.""" - - can_cancel_transfer: Optional[bool] = None - """Indicates if cancellation is still possible.""" - - disable_privacy: Optional[Literal["needed", "ok", "unknown"]] = None - """Status of the privacy-guard disabling step at the foreign registrar.""" - - enter_auth_code: Optional[Literal["needed", "ok", "pending", "trying", "rejected"]] = None - """Status of the auth-code entry and verification step.""" - - unlock_domain: Optional[Literal["needed", "ok", "pending", "trying", "unknown"]] = None - """Status of the domain-unlock step at the foreign registrar.""" - - -class Domain(BaseModel): - id: Optional[str] = None - """Domain identifier.""" - - available: Optional[bool] = None - """Shows if a domain is available for transferring into Cloudflare Registrar.""" - - can_register: Optional[bool] = None - """Indicates eligibility to register the domain as a new domain.""" - - created_at: Optional[datetime] = None - """Shows time of creation.""" - - current_registrar: Optional[str] = None - """Shows name of current registrar.""" - - expires_at: Optional[datetime] = None - """Shows when domain name registration expires.""" - - locked: Optional[bool] = None - """Shows whether a registrar lock is in place for a domain.""" - - registrant_contact: Optional[RegistrantContact] = None - """Shows contact information for domain registrant.""" - - registry_statuses: Optional[str] = None - """A comma-separated list of registry status codes. - - Refer to - [EPP Status Codes](https://www.icann.org/resources/pages/epp-status-codes-2014-06-16-en) - for the full list. - """ - - supported_tld: Optional[bool] = None - """Indicates whether Cloudflare Registrar currently supports a particular TLD. - - Refer to [TLD Policies](https://www.cloudflare.com/tld-policies/) for a list of - supported TLDs. - """ - - transfer_in: Optional[TransferIn] = None - """Statuses for domain transfers into Cloudflare Registrar.""" - - updated_at: Optional[datetime] = None - """Last updated.""" diff --git a/src/cloudflare/types/registrar/domain_update_params.py b/src/cloudflare/types/registrar/domain_update_params.py deleted file mode 100644 index a1c54724482..00000000000 --- a/src/cloudflare/types/registrar/domain_update_params.py +++ /dev/null @@ -1,24 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing_extensions import Required, TypedDict - -__all__ = ["DomainUpdateParams"] - - -class DomainUpdateParams(TypedDict, total=False): - account_id: Required[str] - """Identifier.""" - - auto_renew: bool - """ - Auto-renew controls whether subscription is automatically renewed upon domain - expiration. - """ - - locked: bool - """Shows whether a registrar lock is in place for a domain.""" - - privacy: bool - """Privacy option controls redacting WHOIS information.""" diff --git a/src/cloudflare/types/resource_sharing/recipient_create_params.py b/src/cloudflare/types/resource_sharing/recipient_create_params.py index 44deec4971c..f65f20565d5 100644 --- a/src/cloudflare/types/resource_sharing/recipient_create_params.py +++ b/src/cloudflare/types/resource_sharing/recipient_create_params.py @@ -22,8 +22,5 @@ class RecipientCreateParams(TypedDict, total=False): names will continue to be accepted until 2027-05-26 (see `x-sunset`). """ - organization_id: str - """Organization identifier.""" - recipient_account_id: str """The account that will receive the share.""" diff --git a/src/cloudflare/types/resource_sharing/recipient_create_response.py b/src/cloudflare/types/resource_sharing/recipient_create_response.py index 1150732498c..7f6ee13bad8 100644 --- a/src/cloudflare/types/resource_sharing/recipient_create_response.py +++ b/src/cloudflare/types/resource_sharing/recipient_create_response.py @@ -11,15 +11,18 @@ class Resource(BaseModel): error: str - """Share Recipient error message.""" + """Error from the most recent attempt to apply the resource to the recipient. + + Empty string when no error has been recorded. + """ resource_id: str - """Share Resource identifier.""" + """Identifier assigned by the service that owns the shared resource.""" - resource_version: int - """Resource Version.""" + resource_version: Optional[int] = None + """Resource version applied to the recipient, if reconciliation has occurred.""" - terminal: bool + terminal: Optional[bool] = None """Whether the error is terminal or will be continually retried.""" @@ -56,9 +59,9 @@ class RecipientCreateResponse(BaseModel): """ created: datetime - """When the share was created.""" + """When the object was created.""" modified: datetime - """When the share was modified.""" + """When the object was last modified.""" resources: Optional[List[Resource]] = None diff --git a/src/cloudflare/types/resource_sharing/recipient_delete_response.py b/src/cloudflare/types/resource_sharing/recipient_delete_response.py index cc0535c9880..af90314ccf6 100644 --- a/src/cloudflare/types/resource_sharing/recipient_delete_response.py +++ b/src/cloudflare/types/resource_sharing/recipient_delete_response.py @@ -11,15 +11,18 @@ class Resource(BaseModel): error: str - """Share Recipient error message.""" + """Error from the most recent attempt to apply the resource to the recipient. + + Empty string when no error has been recorded. + """ resource_id: str - """Share Resource identifier.""" + """Identifier assigned by the service that owns the shared resource.""" - resource_version: int - """Resource Version.""" + resource_version: Optional[int] = None + """Resource version applied to the recipient, if reconciliation has occurred.""" - terminal: bool + terminal: Optional[bool] = None """Whether the error is terminal or will be continually retried.""" @@ -56,9 +59,9 @@ class RecipientDeleteResponse(BaseModel): """ created: datetime - """When the share was created.""" + """When the object was created.""" modified: datetime - """When the share was modified.""" + """When the object was last modified.""" resources: Optional[List[Resource]] = None diff --git a/src/cloudflare/types/resource_sharing/recipient_get_response.py b/src/cloudflare/types/resource_sharing/recipient_get_response.py index bef0b6837bd..6546e36c401 100644 --- a/src/cloudflare/types/resource_sharing/recipient_get_response.py +++ b/src/cloudflare/types/resource_sharing/recipient_get_response.py @@ -11,15 +11,18 @@ class Resource(BaseModel): error: str - """Share Recipient error message.""" + """Error from the most recent attempt to apply the resource to the recipient. + + Empty string when no error has been recorded. + """ resource_id: str - """Share Resource identifier.""" + """Identifier assigned by the service that owns the shared resource.""" - resource_version: int - """Resource Version.""" + resource_version: Optional[int] = None + """Resource version applied to the recipient, if reconciliation has occurred.""" - terminal: bool + terminal: Optional[bool] = None """Whether the error is terminal or will be continually retried.""" @@ -56,9 +59,9 @@ class RecipientGetResponse(BaseModel): """ created: datetime - """When the share was created.""" + """When the object was created.""" modified: datetime - """When the share was modified.""" + """When the object was last modified.""" resources: Optional[List[Resource]] = None diff --git a/src/cloudflare/types/resource_sharing/recipient_list_params.py b/src/cloudflare/types/resource_sharing/recipient_list_params.py index 3d7280462e9..d227f875afa 100644 --- a/src/cloudflare/types/resource_sharing/recipient_list_params.py +++ b/src/cloudflare/types/resource_sharing/recipient_list_params.py @@ -15,15 +15,7 @@ class RecipientListParams(TypedDict, total=False): """Include resources in the response.""" page: int - """Page number. - - Defaults to `1` when `per_page` is supplied without `page`. May be omitted - entirely along with `per_page` to receive a non-paginated response. - """ + """Page number. Defaults to `1` when omitted.""" per_page: int - """Number of objects to return per page. - - Defaults to `20` when `page` is supplied without `per_page`. May be omitted - entirely along with `page` to receive a non-paginated response. - """ + """Number of objects to return per page. Defaults to `20` when omitted.""" diff --git a/src/cloudflare/types/resource_sharing/recipient_list_response.py b/src/cloudflare/types/resource_sharing/recipient_list_response.py index 15c1545ebe6..31487192556 100644 --- a/src/cloudflare/types/resource_sharing/recipient_list_response.py +++ b/src/cloudflare/types/resource_sharing/recipient_list_response.py @@ -11,15 +11,18 @@ class Resource(BaseModel): error: str - """Share Recipient error message.""" + """Error from the most recent attempt to apply the resource to the recipient. + + Empty string when no error has been recorded. + """ resource_id: str - """Share Resource identifier.""" + """Identifier assigned by the service that owns the shared resource.""" - resource_version: int - """Resource Version.""" + resource_version: Optional[int] = None + """Resource version applied to the recipient, if reconciliation has occurred.""" - terminal: bool + terminal: Optional[bool] = None """Whether the error is terminal or will be continually retried.""" @@ -56,9 +59,9 @@ class RecipientListResponse(BaseModel): """ created: datetime - """When the share was created.""" + """When the object was created.""" modified: datetime - """When the share was modified.""" + """When the object was last modified.""" resources: Optional[List[Resource]] = None diff --git a/src/cloudflare/types/resource_sharing/resource_create_params.py b/src/cloudflare/types/resource_sharing/resource_create_params.py index a341b51f722..2a63014275f 100644 --- a/src/cloudflare/types/resource_sharing/resource_create_params.py +++ b/src/cloudflare/types/resource_sharing/resource_create_params.py @@ -15,10 +15,10 @@ class ResourceCreateParams(TypedDict, total=False): """Resource Metadata.""" resource_account_id: Required[str] - """Account identifier.""" + """The account that owns the resource. Must match the `account_id` in the path.""" resource_id: Required[str] - """Share Resource identifier.""" + """Identifier assigned by the service that owns the shared resource.""" resource_type: Required[ Literal[ diff --git a/src/cloudflare/types/resource_sharing/resource_create_response.py b/src/cloudflare/types/resource_sharing/resource_create_response.py index e60c68b1d4e..8e0ab085b1d 100644 --- a/src/cloudflare/types/resource_sharing/resource_create_response.py +++ b/src/cloudflare/types/resource_sharing/resource_create_response.py @@ -13,19 +13,19 @@ class ResourceCreateResponse(BaseModel): """Share Resource identifier.""" created: datetime - """When the share was created.""" + """When the object was created.""" meta: object """Resource Metadata.""" modified: datetime - """When the share was modified.""" + """When the object was last modified.""" resource_account_id: str """Account identifier.""" resource_id: str - """Share Resource identifier.""" + """Identifier assigned by the service that owns the shared resource.""" resource_type: Literal[ "custom-ruleset", diff --git a/src/cloudflare/types/resource_sharing/resource_delete_response.py b/src/cloudflare/types/resource_sharing/resource_delete_response.py index cd46446b526..e817cd4ce26 100644 --- a/src/cloudflare/types/resource_sharing/resource_delete_response.py +++ b/src/cloudflare/types/resource_sharing/resource_delete_response.py @@ -13,19 +13,19 @@ class ResourceDeleteResponse(BaseModel): """Share Resource identifier.""" created: datetime - """When the share was created.""" + """When the object was created.""" meta: object """Resource Metadata.""" modified: datetime - """When the share was modified.""" + """When the object was last modified.""" resource_account_id: str """Account identifier.""" resource_id: str - """Share Resource identifier.""" + """Identifier assigned by the service that owns the shared resource.""" resource_type: Literal[ "custom-ruleset", diff --git a/src/cloudflare/types/resource_sharing/resource_get_response.py b/src/cloudflare/types/resource_sharing/resource_get_response.py index 3d995774ad4..b87915f0f8a 100644 --- a/src/cloudflare/types/resource_sharing/resource_get_response.py +++ b/src/cloudflare/types/resource_sharing/resource_get_response.py @@ -13,19 +13,19 @@ class ResourceGetResponse(BaseModel): """Share Resource identifier.""" created: datetime - """When the share was created.""" + """When the object was created.""" meta: object """Resource Metadata.""" modified: datetime - """When the share was modified.""" + """When the object was last modified.""" resource_account_id: str """Account identifier.""" resource_id: str - """Share Resource identifier.""" + """Identifier assigned by the service that owns the shared resource.""" resource_type: Literal[ "custom-ruleset", diff --git a/src/cloudflare/types/resource_sharing/resource_list_params.py b/src/cloudflare/types/resource_sharing/resource_list_params.py index fdf99e95e88..9b695237c94 100644 --- a/src/cloudflare/types/resource_sharing/resource_list_params.py +++ b/src/cloudflare/types/resource_sharing/resource_list_params.py @@ -12,18 +12,10 @@ class ResourceListParams(TypedDict, total=False): """Account identifier.""" page: int - """Page number. - - Defaults to `1` when `per_page` is supplied without `page`. May be omitted - entirely along with `per_page` to receive a non-paginated response. - """ + """Page number. Defaults to `1` when omitted.""" per_page: int - """Number of objects to return per page. - - Defaults to `20` when `page` is supplied without `per_page`. May be omitted - entirely along with `page` to receive a non-paginated response. - """ + """Number of objects to return per page. Defaults to `20` when omitted.""" resource_type: Literal[ "custom-ruleset", diff --git a/src/cloudflare/types/resource_sharing/resource_list_response.py b/src/cloudflare/types/resource_sharing/resource_list_response.py index 987164bf83e..ad49e67c090 100644 --- a/src/cloudflare/types/resource_sharing/resource_list_response.py +++ b/src/cloudflare/types/resource_sharing/resource_list_response.py @@ -13,19 +13,19 @@ class ResourceListResponse(BaseModel): """Share Resource identifier.""" created: datetime - """When the share was created.""" + """When the object was created.""" meta: object """Resource Metadata.""" modified: datetime - """When the share was modified.""" + """When the object was last modified.""" resource_account_id: str """Account identifier.""" resource_id: str - """Share Resource identifier.""" + """Identifier assigned by the service that owns the shared resource.""" resource_type: Literal[ "custom-ruleset", diff --git a/src/cloudflare/types/resource_sharing/resource_sharing_create_params.py b/src/cloudflare/types/resource_sharing/resource_sharing_create_params.py index 3b02509d5e6..615627c99e1 100644 --- a/src/cloudflare/types/resource_sharing/resource_sharing_create_params.py +++ b/src/cloudflare/types/resource_sharing/resource_sharing_create_params.py @@ -2,10 +2,10 @@ from __future__ import annotations -from typing import Iterable +from typing import Dict, Iterable from typing_extensions import Literal, Required, TypedDict -__all__ = ["ResourceSharingCreateParams", "Recipient", "Resource"] +__all__ = ["ResourceSharingCreateParams", "ExcludedRecipient", "Recipient", "Resource"] class ResourceSharingCreateParams(TypedDict, total=False): @@ -15,9 +15,24 @@ class ResourceSharingCreateParams(TypedDict, total=False): name: Required[str] """The name of the share.""" - recipients: Required[Iterable[Recipient]] + excluded_recipients: Iterable[ExcludedRecipient] + """Accounts to exclude from an organization-targeted share. - resources: Required[Iterable[Resource]] + Only allowed when `recipients` contains no account entries. The share owner + cannot be excluded. Duplicate entries are ignored. + """ + + recipients: Iterable[Recipient] + + resources: Iterable[Resource] + + tags: Dict[str, str] + """Tags associated with the share.""" + + +class ExcludedRecipient(TypedDict, total=False): + account_id: Required[str] + """The account to exclude from the organization-targeted share.""" class Recipient(TypedDict, total=False): @@ -47,10 +62,10 @@ class Resource(TypedDict, total=False): """Resource Metadata.""" resource_account_id: Required[str] - """Account identifier.""" + """The account that owns the resource. Must match the `account_id` in the path.""" resource_id: Required[str] - """Share Resource identifier.""" + """Identifier assigned by the service that owns the shared resource.""" resource_type: Required[ Literal[ diff --git a/src/cloudflare/types/resource_sharing/resource_sharing_create_response.py b/src/cloudflare/types/resource_sharing/resource_sharing_create_response.py index 9b31df5071c..ebe9c1f7e14 100644 --- a/src/cloudflare/types/resource_sharing/resource_sharing_create_response.py +++ b/src/cloudflare/types/resource_sharing/resource_sharing_create_response.py @@ -1,6 +1,6 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import List, Optional +from typing import Dict, List, Optional from datetime import datetime from typing_extensions import Literal @@ -14,19 +14,19 @@ class Resource(BaseModel): """Share Resource identifier.""" created: datetime - """When the share was created.""" + """When the object was created.""" meta: object """Resource Metadata.""" modified: datetime - """When the share was modified.""" + """When the object was last modified.""" resource_account_id: str """Account identifier.""" resource_id: str - """Share Resource identifier.""" + """Identifier assigned by the service that owns the shared resource.""" resource_type: Literal[ "custom-ruleset", @@ -57,10 +57,10 @@ class ResourceSharingCreateResponse(BaseModel): """The display name of an account.""" created: datetime - """When the share was created.""" + """When the object was created.""" modified: datetime - """When the share was modified.""" + """When the object was last modified.""" name: str """The name of the share.""" @@ -108,3 +108,10 @@ class ResourceSharingCreateResponse(BaseModel): This field is only included when requested via the 'include_resources' parameter. """ + + tags: Optional[Dict[str, str]] = None + """Tags associated with the share. + + Included in create and update responses when tags are supplied, and in read + responses when the `include_tags_from` parameter is set. + """ diff --git a/src/cloudflare/types/resource_sharing/resource_sharing_delete_response.py b/src/cloudflare/types/resource_sharing/resource_sharing_delete_response.py index 4be92cc83c3..05a3785d1b7 100644 --- a/src/cloudflare/types/resource_sharing/resource_sharing_delete_response.py +++ b/src/cloudflare/types/resource_sharing/resource_sharing_delete_response.py @@ -1,6 +1,6 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import List, Optional +from typing import Dict, List, Optional from datetime import datetime from typing_extensions import Literal @@ -14,19 +14,19 @@ class Resource(BaseModel): """Share Resource identifier.""" created: datetime - """When the share was created.""" + """When the object was created.""" meta: object """Resource Metadata.""" modified: datetime - """When the share was modified.""" + """When the object was last modified.""" resource_account_id: str """Account identifier.""" resource_id: str - """Share Resource identifier.""" + """Identifier assigned by the service that owns the shared resource.""" resource_type: Literal[ "custom-ruleset", @@ -57,10 +57,10 @@ class ResourceSharingDeleteResponse(BaseModel): """The display name of an account.""" created: datetime - """When the share was created.""" + """When the object was created.""" modified: datetime - """When the share was modified.""" + """When the object was last modified.""" name: str """The name of the share.""" @@ -108,3 +108,10 @@ class ResourceSharingDeleteResponse(BaseModel): This field is only included when requested via the 'include_resources' parameter. """ + + tags: Optional[Dict[str, str]] = None + """Tags associated with the share. + + Included in create and update responses when tags are supplied, and in read + responses when the `include_tags_from` parameter is set. + """ diff --git a/src/cloudflare/types/resource_sharing/resource_sharing_get_params.py b/src/cloudflare/types/resource_sharing/resource_sharing_get_params.py index a84c94c5892..1fe6bae6656 100644 --- a/src/cloudflare/types/resource_sharing/resource_sharing_get_params.py +++ b/src/cloudflare/types/resource_sharing/resource_sharing_get_params.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing_extensions import Required, TypedDict +from typing_extensions import Literal, Required, TypedDict __all__ = ["ResourceSharingGetParams"] @@ -16,3 +16,10 @@ class ResourceSharingGetParams(TypedDict, total=False): include_resources: bool """Include resources in the response.""" + + include_tags_from: Literal["api", "mirror"] + """Include share tags in the response. + + `api` reads tags from the tag service; `mirror` reads a local, eventually + consistent replica. If the tag lookup fails, the response omits `tags`. + """ diff --git a/src/cloudflare/types/resource_sharing/resource_sharing_get_response.py b/src/cloudflare/types/resource_sharing/resource_sharing_get_response.py index e0933618385..227593e5129 100644 --- a/src/cloudflare/types/resource_sharing/resource_sharing_get_response.py +++ b/src/cloudflare/types/resource_sharing/resource_sharing_get_response.py @@ -1,6 +1,6 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import List, Optional +from typing import Dict, List, Optional from datetime import datetime from typing_extensions import Literal @@ -14,19 +14,19 @@ class Resource(BaseModel): """Share Resource identifier.""" created: datetime - """When the share was created.""" + """When the object was created.""" meta: object """Resource Metadata.""" modified: datetime - """When the share was modified.""" + """When the object was last modified.""" resource_account_id: str """Account identifier.""" resource_id: str - """Share Resource identifier.""" + """Identifier assigned by the service that owns the shared resource.""" resource_type: Literal[ "custom-ruleset", @@ -57,10 +57,10 @@ class ResourceSharingGetResponse(BaseModel): """The display name of an account.""" created: datetime - """When the share was created.""" + """When the object was created.""" modified: datetime - """When the share was modified.""" + """When the object was last modified.""" name: str """The name of the share.""" @@ -108,3 +108,10 @@ class ResourceSharingGetResponse(BaseModel): This field is only included when requested via the 'include_resources' parameter. """ + + tags: Optional[Dict[str, str]] = None + """Tags associated with the share. + + Included in create and update responses when tags are supplied, and in read + responses when the `include_tags_from` parameter is set. + """ diff --git a/src/cloudflare/types/resource_sharing/resource_sharing_list_params.py b/src/cloudflare/types/resource_sharing/resource_sharing_list_params.py index 8bf7014d153..ed93a440410 100644 --- a/src/cloudflare/types/resource_sharing/resource_sharing_list_params.py +++ b/src/cloudflare/types/resource_sharing/resource_sharing_list_params.py @@ -23,6 +23,13 @@ class ResourceSharingListParams(TypedDict, total=False): include_resources: bool """Include resources in the response.""" + include_tags_from: Literal["api", "mirror"] + """Include share tags in the response. + + `api` reads tags from the tag service; `mirror` reads a local, eventually + consistent replica. If the tag lookup fails, the response omits `tags`. + """ + kind: Literal["sent", "received"] """Filter shares by kind.""" @@ -30,18 +37,10 @@ class ResourceSharingListParams(TypedDict, total=False): """Order shares by values in the given field.""" page: int - """Page number. - - Defaults to `1` when `per_page` is supplied without `page`. May be omitted - entirely along with `per_page` to receive a non-paginated response. - """ + """Page number. Defaults to `1` when omitted.""" per_page: int - """Number of objects to return per page. - - Defaults to `20` when `page` is supplied without `per_page`. May be omitted - entirely along with `page` to receive a non-paginated response. - """ + """Number of objects to return per page. Defaults to `20` when omitted.""" resource_types: List[ Literal[ diff --git a/src/cloudflare/types/resource_sharing/resource_sharing_list_response.py b/src/cloudflare/types/resource_sharing/resource_sharing_list_response.py index 7ad574a24a3..c9520b02c58 100644 --- a/src/cloudflare/types/resource_sharing/resource_sharing_list_response.py +++ b/src/cloudflare/types/resource_sharing/resource_sharing_list_response.py @@ -1,6 +1,6 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import List, Optional +from typing import Dict, List, Optional from datetime import datetime from typing_extensions import Literal @@ -14,19 +14,19 @@ class Resource(BaseModel): """Share Resource identifier.""" created: datetime - """When the share was created.""" + """When the object was created.""" meta: object """Resource Metadata.""" modified: datetime - """When the share was modified.""" + """When the object was last modified.""" resource_account_id: str """Account identifier.""" resource_id: str - """Share Resource identifier.""" + """Identifier assigned by the service that owns the shared resource.""" resource_type: Literal[ "custom-ruleset", @@ -57,10 +57,10 @@ class ResourceSharingListResponse(BaseModel): """The display name of an account.""" created: datetime - """When the share was created.""" + """When the object was created.""" modified: datetime - """When the share was modified.""" + """When the object was last modified.""" name: str """The name of the share.""" @@ -108,3 +108,10 @@ class ResourceSharingListResponse(BaseModel): This field is only included when requested via the 'include_resources' parameter. """ + + tags: Optional[Dict[str, str]] = None + """Tags associated with the share. + + Included in create and update responses when tags are supplied, and in read + responses when the `include_tags_from` parameter is set. + """ diff --git a/src/cloudflare/types/resource_sharing/resource_sharing_update_params.py b/src/cloudflare/types/resource_sharing/resource_sharing_update_params.py index 6d796532f5a..30c18befcc5 100644 --- a/src/cloudflare/types/resource_sharing/resource_sharing_update_params.py +++ b/src/cloudflare/types/resource_sharing/resource_sharing_update_params.py @@ -2,6 +2,7 @@ from __future__ import annotations +from typing import Dict from typing_extensions import Required, TypedDict __all__ = ["ResourceSharingUpdateParams"] @@ -13,3 +14,6 @@ class ResourceSharingUpdateParams(TypedDict, total=False): name: Required[str] """The name of the share.""" + + tags: Dict[str, str] + """Tags associated with the share.""" diff --git a/src/cloudflare/types/resource_sharing/resource_sharing_update_response.py b/src/cloudflare/types/resource_sharing/resource_sharing_update_response.py index 630a2fdbb56..c1b0032ebef 100644 --- a/src/cloudflare/types/resource_sharing/resource_sharing_update_response.py +++ b/src/cloudflare/types/resource_sharing/resource_sharing_update_response.py @@ -1,6 +1,6 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import List, Optional +from typing import Dict, List, Optional from datetime import datetime from typing_extensions import Literal @@ -14,19 +14,19 @@ class Resource(BaseModel): """Share Resource identifier.""" created: datetime - """When the share was created.""" + """When the object was created.""" meta: object """Resource Metadata.""" modified: datetime - """When the share was modified.""" + """When the object was last modified.""" resource_account_id: str """Account identifier.""" resource_id: str - """Share Resource identifier.""" + """Identifier assigned by the service that owns the shared resource.""" resource_type: Literal[ "custom-ruleset", @@ -57,10 +57,10 @@ class ResourceSharingUpdateResponse(BaseModel): """The display name of an account.""" created: datetime - """When the share was created.""" + """When the object was created.""" modified: datetime - """When the share was modified.""" + """When the object was last modified.""" name: str """The name of the share.""" @@ -108,3 +108,10 @@ class ResourceSharingUpdateResponse(BaseModel): This field is only included when requested via the 'include_resources' parameter. """ + + tags: Optional[Dict[str, str]] = None + """Tags associated with the share. + + Included in create and update responses when tags are supplied, and in read + responses when the `include_tags_from` parameter is set. + """ diff --git a/src/cloudflare/types/resource_sharing/resource_update_response.py b/src/cloudflare/types/resource_sharing/resource_update_response.py index 78ed3f40f66..aed7ddcdc0c 100644 --- a/src/cloudflare/types/resource_sharing/resource_update_response.py +++ b/src/cloudflare/types/resource_sharing/resource_update_response.py @@ -13,19 +13,19 @@ class ResourceUpdateResponse(BaseModel): """Share Resource identifier.""" created: datetime - """When the share was created.""" + """When the object was created.""" meta: object """Resource Metadata.""" modified: datetime - """When the share was modified.""" + """When the object was last modified.""" resource_account_id: str """Account identifier.""" resource_id: str - """Share Resource identifier.""" + """Identifier assigned by the service that owns the shared resource.""" resource_type: Literal[ "custom-ruleset", diff --git a/src/cloudflare/types/resource_tagging/account_tag_get_params.py b/src/cloudflare/types/resource_tagging/account_tag_get_params.py index ab4ea705d45..61f9d43eb23 100644 --- a/src/cloudflare/types/resource_tagging/account_tag_get_params.py +++ b/src/cloudflare/types/resource_tagging/account_tag_get_params.py @@ -18,9 +18,12 @@ class AccountTagGetParams(TypedDict, total=False): Literal[ "access_application", "access_group", + "access_service_token", "account", "account_ruleset", "ai_gateway", + "ai_search_instance", + "ai_search_namespace", "alerting_policy", "alerting_webhook", "cloudflared_tunnel", @@ -29,6 +32,7 @@ class AccountTagGetParams(TypedDict, total=False): "cws_policy_set", "cws_workload", "d1_database", + "device", "durable_object_namespace", "gateway_list", "gateway_rule", @@ -37,6 +41,7 @@ class AccountTagGetParams(TypedDict, total=False): "kv_namespace", "load_balancer_monitor", "load_balancer_pool", + "namespace_worker", "pages_project", "queue", "r2_bucket", diff --git a/src/cloudflare/types/resource_tagging/account_tag_get_response.py b/src/cloudflare/types/resource_tagging/account_tag_get_response.py index 3975686def3..c61239a7a77 100644 --- a/src/cloudflare/types/resource_tagging/account_tag_get_response.py +++ b/src/cloudflare/types/resource_tagging/account_tag_get_response.py @@ -12,20 +12,24 @@ "ResourceTaggingTaggedResourceObjectAccessApplication", "ResourceTaggingTaggedResourceObjectAccessApplicationPolicy", "ResourceTaggingTaggedResourceObjectAccessGroup", + "ResourceTaggingTaggedResourceObjectAccessServiceToken", "ResourceTaggingTaggedResourceObjectAccount", "ResourceTaggingTaggedResourceObjectAccountRuleset", "ResourceTaggingTaggedResourceObjectAIGateway", + "ResourceTaggingTaggedResourceObjectAISearchInstance", + "ResourceTaggingTaggedResourceObjectAISearchNamespace", "ResourceTaggingTaggedResourceObjectAlertingPolicy", "ResourceTaggingTaggedResourceObjectAlertingWebhook", "ResourceTaggingTaggedResourceObjectAPIGatewayOperation", "ResourceTaggingTaggedResourceObjectCloudflaredTunnel", "ResourceTaggingTaggedResourceObjectCustomCertificate", "ResourceTaggingTaggedResourceObjectCustomHostname", - "ResourceTaggingTaggedResourceObjectCwsDeployment", - "ResourceTaggingTaggedResourceObjectCwsPolicy", - "ResourceTaggingTaggedResourceObjectCwsPolicySet", - "ResourceTaggingTaggedResourceObjectCwsWorkload", + "ResourceTaggingTaggedResourceObjectCWSDeployment", + "ResourceTaggingTaggedResourceObjectCWSPolicy", + "ResourceTaggingTaggedResourceObjectCWSPolicySet", + "ResourceTaggingTaggedResourceObjectCWSWorkload", "ResourceTaggingTaggedResourceObjectD1Database", + "ResourceTaggingTaggedResourceObjectDevice", "ResourceTaggingTaggedResourceObjectDNSRecord", "ResourceTaggingTaggedResourceObjectDurableObjectNamespace", "ResourceTaggingTaggedResourceObjectGatewayList", @@ -38,6 +42,8 @@ "ResourceTaggingTaggedResourceObjectLoadBalancerMonitor", "ResourceTaggingTaggedResourceObjectLoadBalancerPool", "ResourceTaggingTaggedResourceObjectManagedClientCertificate", + "ResourceTaggingTaggedResourceObjectNamespaceWorker", + "ResourceTaggingTaggedResourceObjectNamespaceWorkerNavigation", "ResourceTaggingTaggedResourceObjectPagesProject", "ResourceTaggingTaggedResourceObjectQueue", "ResourceTaggingTaggedResourceObjectR2Bucket", @@ -176,6 +182,45 @@ class ResourceTaggingTaggedResourceObjectAccessGroup(BaseModel): """ +class ResourceTaggingTaggedResourceObjectAccessServiceToken(BaseModel): + """Response for access_service_token resources""" + + id: str + """Identifies the unique resource.""" + + etag: str + """ETag identifier for optimistic concurrency control. + + Formatted as "v1:" where the hash is the base64url-encoded SHA-256 + (truncated to 128 bits) of the tags map canonicalized using RFC 8785 (JSON + Canonicalization Scheme). Clients should treat ETags as opaque strings and pass + them back via the If-Match header on write operations. + """ + + name: str + """Human-readable name of the resource.""" + + tags: Dict[str, str] + """Contains key-value pairs of tags. + + Keys may contain at most 256 characters. Values may contain at most 1024 + characters and may be empty for key-only tags. + """ + + type: Literal["access_service_token"] + + tags_updated_at: Optional[datetime] = None + """ + Monotonic version of the resource's tags: the timestamp assigned when the tags + were last written. Returned by read endpoints, by 2PC prepare (the version that + will be assigned on commit, unless a concurrent write lands first, in which case + a newer version is assigned), and by 2PC commit (the authoritative committed + version). Omitted for untagged resources and delete commits: a deleted resource + has no current version, and deletions are ordered by event order rather than by + version. + """ + + class ResourceTaggingTaggedResourceObjectAccount(BaseModel): """Response for account resources""" @@ -293,6 +338,84 @@ class ResourceTaggingTaggedResourceObjectAIGateway(BaseModel): """ +class ResourceTaggingTaggedResourceObjectAISearchInstance(BaseModel): + """Response for ai_search_instance resources""" + + id: str + """Identifies the unique resource.""" + + etag: str + """ETag identifier for optimistic concurrency control. + + Formatted as "v1:" where the hash is the base64url-encoded SHA-256 + (truncated to 128 bits) of the tags map canonicalized using RFC 8785 (JSON + Canonicalization Scheme). Clients should treat ETags as opaque strings and pass + them back via the If-Match header on write operations. + """ + + name: str + """Human-readable name of the resource.""" + + tags: Dict[str, str] + """Contains key-value pairs of tags. + + Keys may contain at most 256 characters. Values may contain at most 1024 + characters and may be empty for key-only tags. + """ + + type: Literal["ai_search_instance"] + + tags_updated_at: Optional[datetime] = None + """ + Monotonic version of the resource's tags: the timestamp assigned when the tags + were last written. Returned by read endpoints, by 2PC prepare (the version that + will be assigned on commit, unless a concurrent write lands first, in which case + a newer version is assigned), and by 2PC commit (the authoritative committed + version). Omitted for untagged resources and delete commits: a deleted resource + has no current version, and deletions are ordered by event order rather than by + version. + """ + + +class ResourceTaggingTaggedResourceObjectAISearchNamespace(BaseModel): + """Response for ai_search_namespace resources""" + + id: str + """Identifies the unique resource.""" + + etag: str + """ETag identifier for optimistic concurrency control. + + Formatted as "v1:" where the hash is the base64url-encoded SHA-256 + (truncated to 128 bits) of the tags map canonicalized using RFC 8785 (JSON + Canonicalization Scheme). Clients should treat ETags as opaque strings and pass + them back via the If-Match header on write operations. + """ + + name: str + """Human-readable name of the resource.""" + + tags: Dict[str, str] + """Contains key-value pairs of tags. + + Keys may contain at most 256 characters. Values may contain at most 1024 + characters and may be empty for key-only tags. + """ + + type: Literal["ai_search_namespace"] + + tags_updated_at: Optional[datetime] = None + """ + Monotonic version of the resource's tags: the timestamp assigned when the tags + were last written. Returned by read endpoints, by 2PC prepare (the version that + will be assigned on commit, unless a concurrent write lands first, in which case + a newer version is assigned), and by 2PC commit (the authoritative committed + version). Omitted for untagged resources and delete commits: a deleted resource + has no current version, and deletions are ordered by event order rather than by + version. + """ + + class ResourceTaggingTaggedResourceObjectAlertingPolicy(BaseModel): """Response for alerting_policy resources""" @@ -536,7 +659,7 @@ class ResourceTaggingTaggedResourceObjectCustomHostname(BaseModel): """ -class ResourceTaggingTaggedResourceObjectCwsDeployment(BaseModel): +class ResourceTaggingTaggedResourceObjectCWSDeployment(BaseModel): """Response for cws_deployment resources""" id: str @@ -575,7 +698,7 @@ class ResourceTaggingTaggedResourceObjectCwsDeployment(BaseModel): """ -class ResourceTaggingTaggedResourceObjectCwsPolicy(BaseModel): +class ResourceTaggingTaggedResourceObjectCWSPolicy(BaseModel): """Response for cws_policy resources""" id: str @@ -614,7 +737,7 @@ class ResourceTaggingTaggedResourceObjectCwsPolicy(BaseModel): """ -class ResourceTaggingTaggedResourceObjectCwsPolicySet(BaseModel): +class ResourceTaggingTaggedResourceObjectCWSPolicySet(BaseModel): """Response for cws_policy_set resources""" id: str @@ -653,7 +776,7 @@ class ResourceTaggingTaggedResourceObjectCwsPolicySet(BaseModel): """ -class ResourceTaggingTaggedResourceObjectCwsWorkload(BaseModel): +class ResourceTaggingTaggedResourceObjectCWSWorkload(BaseModel): """Response for cws_workload resources""" id: str @@ -731,6 +854,45 @@ class ResourceTaggingTaggedResourceObjectD1Database(BaseModel): """ +class ResourceTaggingTaggedResourceObjectDevice(BaseModel): + """Response for device resources""" + + id: str + """Identifies the unique resource.""" + + etag: str + """ETag identifier for optimistic concurrency control. + + Formatted as "v1:" where the hash is the base64url-encoded SHA-256 + (truncated to 128 bits) of the tags map canonicalized using RFC 8785 (JSON + Canonicalization Scheme). Clients should treat ETags as opaque strings and pass + them back via the If-Match header on write operations. + """ + + name: str + """Human-readable name of the resource.""" + + tags: Dict[str, str] + """Contains key-value pairs of tags. + + Keys may contain at most 256 characters. Values may contain at most 1024 + characters and may be empty for key-only tags. + """ + + type: Literal["device"] + + tags_updated_at: Optional[datetime] = None + """ + Monotonic version of the resource's tags: the timestamp assigned when the tags + were last written. Returned by read endpoints, by 2PC prepare (the version that + will be assigned on commit, unless a concurrent write lands first, in which case + a newer version is assigned), and by 2PC commit (the authoritative committed + version). Omitted for untagged resources and delete commits: a deleted resource + has no current version, and deletions are ordered by event order rather than by + version. + """ + + class ResourceTaggingTaggedResourceObjectDNSRecord(BaseModel): """Response for dns_record resources""" @@ -1211,6 +1373,68 @@ class ResourceTaggingTaggedResourceObjectManagedClientCertificate(BaseModel): """ +class ResourceTaggingTaggedResourceObjectNamespaceWorkerNavigation(BaseModel): + """ + Read-only routing metadata resolved from EWC using the account and immutable + namespace Worker ID. Returned only by tagged-resource lists requested with + include_navigation=true. Omitted when lookup is unavailable or the child + has been deleted. Never supplied on tag writes or stored as extra_data. + """ + + namespace_id: str + + namespace_name: str + + script_name: str + + +class ResourceTaggingTaggedResourceObjectNamespaceWorker(BaseModel): + """Response for namespace_worker resources""" + + id: str + """Identifies the unique resource.""" + + etag: str + """ETag identifier for optimistic concurrency control. + + Formatted as "v1:" where the hash is the base64url-encoded SHA-256 + (truncated to 128 bits) of the tags map canonicalized using RFC 8785 (JSON + Canonicalization Scheme). Clients should treat ETags as opaque strings and pass + them back via the If-Match header on write operations. + """ + + name: str + """Human-readable name of the resource.""" + + tags: Dict[str, str] + """Contains key-value pairs of tags. + + Keys may contain at most 256 characters. Values may contain at most 1024 + characters and may be empty for key-only tags. + """ + + type: Literal["namespace_worker"] + + navigation: Optional[ResourceTaggingTaggedResourceObjectNamespaceWorkerNavigation] = None + """ + Read-only routing metadata resolved from EWC using the account and immutable + namespace Worker ID. Returned only by tagged-resource lists requested with + include_navigation=true. Omitted when lookup is unavailable or the child has + been deleted. Never supplied on tag writes or stored as extra_data. + """ + + tags_updated_at: Optional[datetime] = None + """ + Monotonic version of the resource's tags: the timestamp assigned when the tags + were last written. Returned by read endpoints, by 2PC prepare (the version that + will be assigned on commit, unless a concurrent write lands first, in which case + a newer version is assigned), and by 2PC commit (the authoritative committed + version). Omitted for untagged resources and delete commits: a deleted resource + has no current version, and deletions are ordered by event order rather than by + version. + """ + + class ResourceTaggingTaggedResourceObjectPagesProject(BaseModel): """Response for pages_project resources""" @@ -1696,20 +1920,24 @@ class ResourceTaggingTaggedResourceObjectZoneRuleset(BaseModel): ResourceTaggingTaggedResourceObjectAccessApplication, ResourceTaggingTaggedResourceObjectAccessApplicationPolicy, ResourceTaggingTaggedResourceObjectAccessGroup, + ResourceTaggingTaggedResourceObjectAccessServiceToken, ResourceTaggingTaggedResourceObjectAccount, ResourceTaggingTaggedResourceObjectAccountRuleset, ResourceTaggingTaggedResourceObjectAIGateway, + ResourceTaggingTaggedResourceObjectAISearchInstance, + ResourceTaggingTaggedResourceObjectAISearchNamespace, ResourceTaggingTaggedResourceObjectAlertingPolicy, ResourceTaggingTaggedResourceObjectAlertingWebhook, ResourceTaggingTaggedResourceObjectAPIGatewayOperation, ResourceTaggingTaggedResourceObjectCloudflaredTunnel, ResourceTaggingTaggedResourceObjectCustomCertificate, ResourceTaggingTaggedResourceObjectCustomHostname, - ResourceTaggingTaggedResourceObjectCwsDeployment, - ResourceTaggingTaggedResourceObjectCwsPolicy, - ResourceTaggingTaggedResourceObjectCwsPolicySet, - ResourceTaggingTaggedResourceObjectCwsWorkload, + ResourceTaggingTaggedResourceObjectCWSDeployment, + ResourceTaggingTaggedResourceObjectCWSPolicy, + ResourceTaggingTaggedResourceObjectCWSPolicySet, + ResourceTaggingTaggedResourceObjectCWSWorkload, ResourceTaggingTaggedResourceObjectD1Database, + ResourceTaggingTaggedResourceObjectDevice, ResourceTaggingTaggedResourceObjectDNSRecord, ResourceTaggingTaggedResourceObjectDurableObjectNamespace, ResourceTaggingTaggedResourceObjectGatewayList, @@ -1722,6 +1950,7 @@ class ResourceTaggingTaggedResourceObjectZoneRuleset(BaseModel): ResourceTaggingTaggedResourceObjectLoadBalancerMonitor, ResourceTaggingTaggedResourceObjectLoadBalancerPool, ResourceTaggingTaggedResourceObjectManagedClientCertificate, + ResourceTaggingTaggedResourceObjectNamespaceWorker, ResourceTaggingTaggedResourceObjectPagesProject, ResourceTaggingTaggedResourceObjectQueue, ResourceTaggingTaggedResourceObjectR2Bucket, diff --git a/src/cloudflare/types/resource_tagging/account_tag_update_params.py b/src/cloudflare/types/resource_tagging/account_tag_update_params.py index 5d1ae74e56e..9a13509ce81 100644 --- a/src/cloudflare/types/resource_tagging/account_tag_update_params.py +++ b/src/cloudflare/types/resource_tagging/account_tag_update_params.py @@ -48,9 +48,12 @@ class ResourceTaggingSetTagsRequestAccountLevelBase(TypedDict, total=False): Literal[ "access_application", "access_group", + "access_service_token", "account", "account_ruleset", "ai_gateway", + "ai_search_instance", + "ai_search_namespace", "alerting_policy", "alerting_webhook", "cloudflared_tunnel", @@ -59,6 +62,7 @@ class ResourceTaggingSetTagsRequestAccountLevelBase(TypedDict, total=False): "cws_policy_set", "cws_workload", "d1_database", + "device", "durable_object_namespace", "gateway_list", "gateway_rule", @@ -67,6 +71,7 @@ class ResourceTaggingSetTagsRequestAccountLevelBase(TypedDict, total=False): "kv_namespace", "load_balancer_monitor", "load_balancer_pool", + "namespace_worker", "pages_project", "queue", "r2_bucket", diff --git a/src/cloudflare/types/resource_tagging/account_tag_update_response.py b/src/cloudflare/types/resource_tagging/account_tag_update_response.py index 969b577d4ad..f25ff1b4948 100644 --- a/src/cloudflare/types/resource_tagging/account_tag_update_response.py +++ b/src/cloudflare/types/resource_tagging/account_tag_update_response.py @@ -12,20 +12,24 @@ "ResourceTaggingTaggedResourceObjectAccessApplication", "ResourceTaggingTaggedResourceObjectAccessApplicationPolicy", "ResourceTaggingTaggedResourceObjectAccessGroup", + "ResourceTaggingTaggedResourceObjectAccessServiceToken", "ResourceTaggingTaggedResourceObjectAccount", "ResourceTaggingTaggedResourceObjectAccountRuleset", "ResourceTaggingTaggedResourceObjectAIGateway", + "ResourceTaggingTaggedResourceObjectAISearchInstance", + "ResourceTaggingTaggedResourceObjectAISearchNamespace", "ResourceTaggingTaggedResourceObjectAlertingPolicy", "ResourceTaggingTaggedResourceObjectAlertingWebhook", "ResourceTaggingTaggedResourceObjectAPIGatewayOperation", "ResourceTaggingTaggedResourceObjectCloudflaredTunnel", "ResourceTaggingTaggedResourceObjectCustomCertificate", "ResourceTaggingTaggedResourceObjectCustomHostname", - "ResourceTaggingTaggedResourceObjectCwsDeployment", - "ResourceTaggingTaggedResourceObjectCwsPolicy", - "ResourceTaggingTaggedResourceObjectCwsPolicySet", - "ResourceTaggingTaggedResourceObjectCwsWorkload", + "ResourceTaggingTaggedResourceObjectCWSDeployment", + "ResourceTaggingTaggedResourceObjectCWSPolicy", + "ResourceTaggingTaggedResourceObjectCWSPolicySet", + "ResourceTaggingTaggedResourceObjectCWSWorkload", "ResourceTaggingTaggedResourceObjectD1Database", + "ResourceTaggingTaggedResourceObjectDevice", "ResourceTaggingTaggedResourceObjectDNSRecord", "ResourceTaggingTaggedResourceObjectDurableObjectNamespace", "ResourceTaggingTaggedResourceObjectGatewayList", @@ -38,6 +42,8 @@ "ResourceTaggingTaggedResourceObjectLoadBalancerMonitor", "ResourceTaggingTaggedResourceObjectLoadBalancerPool", "ResourceTaggingTaggedResourceObjectManagedClientCertificate", + "ResourceTaggingTaggedResourceObjectNamespaceWorker", + "ResourceTaggingTaggedResourceObjectNamespaceWorkerNavigation", "ResourceTaggingTaggedResourceObjectPagesProject", "ResourceTaggingTaggedResourceObjectQueue", "ResourceTaggingTaggedResourceObjectR2Bucket", @@ -176,6 +182,45 @@ class ResourceTaggingTaggedResourceObjectAccessGroup(BaseModel): """ +class ResourceTaggingTaggedResourceObjectAccessServiceToken(BaseModel): + """Response for access_service_token resources""" + + id: str + """Identifies the unique resource.""" + + etag: str + """ETag identifier for optimistic concurrency control. + + Formatted as "v1:" where the hash is the base64url-encoded SHA-256 + (truncated to 128 bits) of the tags map canonicalized using RFC 8785 (JSON + Canonicalization Scheme). Clients should treat ETags as opaque strings and pass + them back via the If-Match header on write operations. + """ + + name: str + """Human-readable name of the resource.""" + + tags: Dict[str, str] + """Contains key-value pairs of tags. + + Keys may contain at most 256 characters. Values may contain at most 1024 + characters and may be empty for key-only tags. + """ + + type: Literal["access_service_token"] + + tags_updated_at: Optional[datetime] = None + """ + Monotonic version of the resource's tags: the timestamp assigned when the tags + were last written. Returned by read endpoints, by 2PC prepare (the version that + will be assigned on commit, unless a concurrent write lands first, in which case + a newer version is assigned), and by 2PC commit (the authoritative committed + version). Omitted for untagged resources and delete commits: a deleted resource + has no current version, and deletions are ordered by event order rather than by + version. + """ + + class ResourceTaggingTaggedResourceObjectAccount(BaseModel): """Response for account resources""" @@ -293,6 +338,84 @@ class ResourceTaggingTaggedResourceObjectAIGateway(BaseModel): """ +class ResourceTaggingTaggedResourceObjectAISearchInstance(BaseModel): + """Response for ai_search_instance resources""" + + id: str + """Identifies the unique resource.""" + + etag: str + """ETag identifier for optimistic concurrency control. + + Formatted as "v1:" where the hash is the base64url-encoded SHA-256 + (truncated to 128 bits) of the tags map canonicalized using RFC 8785 (JSON + Canonicalization Scheme). Clients should treat ETags as opaque strings and pass + them back via the If-Match header on write operations. + """ + + name: str + """Human-readable name of the resource.""" + + tags: Dict[str, str] + """Contains key-value pairs of tags. + + Keys may contain at most 256 characters. Values may contain at most 1024 + characters and may be empty for key-only tags. + """ + + type: Literal["ai_search_instance"] + + tags_updated_at: Optional[datetime] = None + """ + Monotonic version of the resource's tags: the timestamp assigned when the tags + were last written. Returned by read endpoints, by 2PC prepare (the version that + will be assigned on commit, unless a concurrent write lands first, in which case + a newer version is assigned), and by 2PC commit (the authoritative committed + version). Omitted for untagged resources and delete commits: a deleted resource + has no current version, and deletions are ordered by event order rather than by + version. + """ + + +class ResourceTaggingTaggedResourceObjectAISearchNamespace(BaseModel): + """Response for ai_search_namespace resources""" + + id: str + """Identifies the unique resource.""" + + etag: str + """ETag identifier for optimistic concurrency control. + + Formatted as "v1:" where the hash is the base64url-encoded SHA-256 + (truncated to 128 bits) of the tags map canonicalized using RFC 8785 (JSON + Canonicalization Scheme). Clients should treat ETags as opaque strings and pass + them back via the If-Match header on write operations. + """ + + name: str + """Human-readable name of the resource.""" + + tags: Dict[str, str] + """Contains key-value pairs of tags. + + Keys may contain at most 256 characters. Values may contain at most 1024 + characters and may be empty for key-only tags. + """ + + type: Literal["ai_search_namespace"] + + tags_updated_at: Optional[datetime] = None + """ + Monotonic version of the resource's tags: the timestamp assigned when the tags + were last written. Returned by read endpoints, by 2PC prepare (the version that + will be assigned on commit, unless a concurrent write lands first, in which case + a newer version is assigned), and by 2PC commit (the authoritative committed + version). Omitted for untagged resources and delete commits: a deleted resource + has no current version, and deletions are ordered by event order rather than by + version. + """ + + class ResourceTaggingTaggedResourceObjectAlertingPolicy(BaseModel): """Response for alerting_policy resources""" @@ -536,7 +659,7 @@ class ResourceTaggingTaggedResourceObjectCustomHostname(BaseModel): """ -class ResourceTaggingTaggedResourceObjectCwsDeployment(BaseModel): +class ResourceTaggingTaggedResourceObjectCWSDeployment(BaseModel): """Response for cws_deployment resources""" id: str @@ -575,7 +698,7 @@ class ResourceTaggingTaggedResourceObjectCwsDeployment(BaseModel): """ -class ResourceTaggingTaggedResourceObjectCwsPolicy(BaseModel): +class ResourceTaggingTaggedResourceObjectCWSPolicy(BaseModel): """Response for cws_policy resources""" id: str @@ -614,7 +737,7 @@ class ResourceTaggingTaggedResourceObjectCwsPolicy(BaseModel): """ -class ResourceTaggingTaggedResourceObjectCwsPolicySet(BaseModel): +class ResourceTaggingTaggedResourceObjectCWSPolicySet(BaseModel): """Response for cws_policy_set resources""" id: str @@ -653,7 +776,7 @@ class ResourceTaggingTaggedResourceObjectCwsPolicySet(BaseModel): """ -class ResourceTaggingTaggedResourceObjectCwsWorkload(BaseModel): +class ResourceTaggingTaggedResourceObjectCWSWorkload(BaseModel): """Response for cws_workload resources""" id: str @@ -731,6 +854,45 @@ class ResourceTaggingTaggedResourceObjectD1Database(BaseModel): """ +class ResourceTaggingTaggedResourceObjectDevice(BaseModel): + """Response for device resources""" + + id: str + """Identifies the unique resource.""" + + etag: str + """ETag identifier for optimistic concurrency control. + + Formatted as "v1:" where the hash is the base64url-encoded SHA-256 + (truncated to 128 bits) of the tags map canonicalized using RFC 8785 (JSON + Canonicalization Scheme). Clients should treat ETags as opaque strings and pass + them back via the If-Match header on write operations. + """ + + name: str + """Human-readable name of the resource.""" + + tags: Dict[str, str] + """Contains key-value pairs of tags. + + Keys may contain at most 256 characters. Values may contain at most 1024 + characters and may be empty for key-only tags. + """ + + type: Literal["device"] + + tags_updated_at: Optional[datetime] = None + """ + Monotonic version of the resource's tags: the timestamp assigned when the tags + were last written. Returned by read endpoints, by 2PC prepare (the version that + will be assigned on commit, unless a concurrent write lands first, in which case + a newer version is assigned), and by 2PC commit (the authoritative committed + version). Omitted for untagged resources and delete commits: a deleted resource + has no current version, and deletions are ordered by event order rather than by + version. + """ + + class ResourceTaggingTaggedResourceObjectDNSRecord(BaseModel): """Response for dns_record resources""" @@ -1211,6 +1373,68 @@ class ResourceTaggingTaggedResourceObjectManagedClientCertificate(BaseModel): """ +class ResourceTaggingTaggedResourceObjectNamespaceWorkerNavigation(BaseModel): + """ + Read-only routing metadata resolved from EWC using the account and immutable + namespace Worker ID. Returned only by tagged-resource lists requested with + include_navigation=true. Omitted when lookup is unavailable or the child + has been deleted. Never supplied on tag writes or stored as extra_data. + """ + + namespace_id: str + + namespace_name: str + + script_name: str + + +class ResourceTaggingTaggedResourceObjectNamespaceWorker(BaseModel): + """Response for namespace_worker resources""" + + id: str + """Identifies the unique resource.""" + + etag: str + """ETag identifier for optimistic concurrency control. + + Formatted as "v1:" where the hash is the base64url-encoded SHA-256 + (truncated to 128 bits) of the tags map canonicalized using RFC 8785 (JSON + Canonicalization Scheme). Clients should treat ETags as opaque strings and pass + them back via the If-Match header on write operations. + """ + + name: str + """Human-readable name of the resource.""" + + tags: Dict[str, str] + """Contains key-value pairs of tags. + + Keys may contain at most 256 characters. Values may contain at most 1024 + characters and may be empty for key-only tags. + """ + + type: Literal["namespace_worker"] + + navigation: Optional[ResourceTaggingTaggedResourceObjectNamespaceWorkerNavigation] = None + """ + Read-only routing metadata resolved from EWC using the account and immutable + namespace Worker ID. Returned only by tagged-resource lists requested with + include_navigation=true. Omitted when lookup is unavailable or the child has + been deleted. Never supplied on tag writes or stored as extra_data. + """ + + tags_updated_at: Optional[datetime] = None + """ + Monotonic version of the resource's tags: the timestamp assigned when the tags + were last written. Returned by read endpoints, by 2PC prepare (the version that + will be assigned on commit, unless a concurrent write lands first, in which case + a newer version is assigned), and by 2PC commit (the authoritative committed + version). Omitted for untagged resources and delete commits: a deleted resource + has no current version, and deletions are ordered by event order rather than by + version. + """ + + class ResourceTaggingTaggedResourceObjectPagesProject(BaseModel): """Response for pages_project resources""" @@ -1696,20 +1920,24 @@ class ResourceTaggingTaggedResourceObjectZoneRuleset(BaseModel): ResourceTaggingTaggedResourceObjectAccessApplication, ResourceTaggingTaggedResourceObjectAccessApplicationPolicy, ResourceTaggingTaggedResourceObjectAccessGroup, + ResourceTaggingTaggedResourceObjectAccessServiceToken, ResourceTaggingTaggedResourceObjectAccount, ResourceTaggingTaggedResourceObjectAccountRuleset, ResourceTaggingTaggedResourceObjectAIGateway, + ResourceTaggingTaggedResourceObjectAISearchInstance, + ResourceTaggingTaggedResourceObjectAISearchNamespace, ResourceTaggingTaggedResourceObjectAlertingPolicy, ResourceTaggingTaggedResourceObjectAlertingWebhook, ResourceTaggingTaggedResourceObjectAPIGatewayOperation, ResourceTaggingTaggedResourceObjectCloudflaredTunnel, ResourceTaggingTaggedResourceObjectCustomCertificate, ResourceTaggingTaggedResourceObjectCustomHostname, - ResourceTaggingTaggedResourceObjectCwsDeployment, - ResourceTaggingTaggedResourceObjectCwsPolicy, - ResourceTaggingTaggedResourceObjectCwsPolicySet, - ResourceTaggingTaggedResourceObjectCwsWorkload, + ResourceTaggingTaggedResourceObjectCWSDeployment, + ResourceTaggingTaggedResourceObjectCWSPolicy, + ResourceTaggingTaggedResourceObjectCWSPolicySet, + ResourceTaggingTaggedResourceObjectCWSWorkload, ResourceTaggingTaggedResourceObjectD1Database, + ResourceTaggingTaggedResourceObjectDevice, ResourceTaggingTaggedResourceObjectDNSRecord, ResourceTaggingTaggedResourceObjectDurableObjectNamespace, ResourceTaggingTaggedResourceObjectGatewayList, @@ -1722,6 +1950,7 @@ class ResourceTaggingTaggedResourceObjectZoneRuleset(BaseModel): ResourceTaggingTaggedResourceObjectLoadBalancerMonitor, ResourceTaggingTaggedResourceObjectLoadBalancerPool, ResourceTaggingTaggedResourceObjectManagedClientCertificate, + ResourceTaggingTaggedResourceObjectNamespaceWorker, ResourceTaggingTaggedResourceObjectPagesProject, ResourceTaggingTaggedResourceObjectQueue, ResourceTaggingTaggedResourceObjectR2Bucket, diff --git a/src/cloudflare/types/resource_tagging/resource_tagging_list_params.py b/src/cloudflare/types/resource_tagging/resource_tagging_list_params.py index 0106fe7fe32..ce9ef63c05b 100644 --- a/src/cloudflare/types/resource_tagging/resource_tagging_list_params.py +++ b/src/cloudflare/types/resource_tagging/resource_tagging_list_params.py @@ -31,6 +31,15 @@ class ResourceTaggingListParams(TypedDict, total=False): cursor: str """Cursor for pagination.""" + include_navigation: bool + """Resolve current namespace Worker navigation by immutable child tag. + + Optional read-only navigation is omitted for deleted or unresolved children. + Lookups are limited to this page, at most five concurrently, with a shared + two-second budget. Tag identity, ETag, filters and pagination are unchanged; + name filtering still uses the stored resource name. Defaults to false. + """ + name: str """Filter by resource name. @@ -64,9 +73,12 @@ class ResourceTaggingListParams(TypedDict, total=False): "access_application", "access_application_policy", "access_group", + "access_service_token", "account", "account_ruleset", "ai_gateway", + "ai_search_instance", + "ai_search_namespace", "alerting_policy", "alerting_webhook", "api_gateway_operation", @@ -78,6 +90,7 @@ class ResourceTaggingListParams(TypedDict, total=False): "cws_policy_set", "cws_workload", "d1_database", + "device", "dns_record", "durable_object_namespace", "gateway_list", @@ -90,6 +103,7 @@ class ResourceTaggingListParams(TypedDict, total=False): "load_balancer_monitor", "load_balancer_pool", "managed_client_certificate", + "namespace_worker", "pages_project", "queue", "r2_bucket", diff --git a/src/cloudflare/types/resource_tagging/resource_tagging_list_response.py b/src/cloudflare/types/resource_tagging/resource_tagging_list_response.py index b712fed30a4..beb75813b10 100644 --- a/src/cloudflare/types/resource_tagging/resource_tagging_list_response.py +++ b/src/cloudflare/types/resource_tagging/resource_tagging_list_response.py @@ -12,20 +12,24 @@ "ResourceTaggingTaggedResourceObjectAccessApplication", "ResourceTaggingTaggedResourceObjectAccessApplicationPolicy", "ResourceTaggingTaggedResourceObjectAccessGroup", + "ResourceTaggingTaggedResourceObjectAccessServiceToken", "ResourceTaggingTaggedResourceObjectAccount", "ResourceTaggingTaggedResourceObjectAccountRuleset", "ResourceTaggingTaggedResourceObjectAIGateway", + "ResourceTaggingTaggedResourceObjectAISearchInstance", + "ResourceTaggingTaggedResourceObjectAISearchNamespace", "ResourceTaggingTaggedResourceObjectAlertingPolicy", "ResourceTaggingTaggedResourceObjectAlertingWebhook", "ResourceTaggingTaggedResourceObjectAPIGatewayOperation", "ResourceTaggingTaggedResourceObjectCloudflaredTunnel", "ResourceTaggingTaggedResourceObjectCustomCertificate", "ResourceTaggingTaggedResourceObjectCustomHostname", - "ResourceTaggingTaggedResourceObjectCwsDeployment", - "ResourceTaggingTaggedResourceObjectCwsPolicy", - "ResourceTaggingTaggedResourceObjectCwsPolicySet", - "ResourceTaggingTaggedResourceObjectCwsWorkload", + "ResourceTaggingTaggedResourceObjectCWSDeployment", + "ResourceTaggingTaggedResourceObjectCWSPolicy", + "ResourceTaggingTaggedResourceObjectCWSPolicySet", + "ResourceTaggingTaggedResourceObjectCWSWorkload", "ResourceTaggingTaggedResourceObjectD1Database", + "ResourceTaggingTaggedResourceObjectDevice", "ResourceTaggingTaggedResourceObjectDNSRecord", "ResourceTaggingTaggedResourceObjectDurableObjectNamespace", "ResourceTaggingTaggedResourceObjectGatewayList", @@ -38,6 +42,8 @@ "ResourceTaggingTaggedResourceObjectLoadBalancerMonitor", "ResourceTaggingTaggedResourceObjectLoadBalancerPool", "ResourceTaggingTaggedResourceObjectManagedClientCertificate", + "ResourceTaggingTaggedResourceObjectNamespaceWorker", + "ResourceTaggingTaggedResourceObjectNamespaceWorkerNavigation", "ResourceTaggingTaggedResourceObjectPagesProject", "ResourceTaggingTaggedResourceObjectQueue", "ResourceTaggingTaggedResourceObjectR2Bucket", @@ -176,6 +182,45 @@ class ResourceTaggingTaggedResourceObjectAccessGroup(BaseModel): """ +class ResourceTaggingTaggedResourceObjectAccessServiceToken(BaseModel): + """Response for access_service_token resources""" + + id: str + """Identifies the unique resource.""" + + etag: str + """ETag identifier for optimistic concurrency control. + + Formatted as "v1:" where the hash is the base64url-encoded SHA-256 + (truncated to 128 bits) of the tags map canonicalized using RFC 8785 (JSON + Canonicalization Scheme). Clients should treat ETags as opaque strings and pass + them back via the If-Match header on write operations. + """ + + name: str + """Human-readable name of the resource.""" + + tags: Dict[str, str] + """Contains key-value pairs of tags. + + Keys may contain at most 256 characters. Values may contain at most 1024 + characters and may be empty for key-only tags. + """ + + type: Literal["access_service_token"] + + tags_updated_at: Optional[datetime] = None + """ + Monotonic version of the resource's tags: the timestamp assigned when the tags + were last written. Returned by read endpoints, by 2PC prepare (the version that + will be assigned on commit, unless a concurrent write lands first, in which case + a newer version is assigned), and by 2PC commit (the authoritative committed + version). Omitted for untagged resources and delete commits: a deleted resource + has no current version, and deletions are ordered by event order rather than by + version. + """ + + class ResourceTaggingTaggedResourceObjectAccount(BaseModel): """Response for account resources""" @@ -293,6 +338,84 @@ class ResourceTaggingTaggedResourceObjectAIGateway(BaseModel): """ +class ResourceTaggingTaggedResourceObjectAISearchInstance(BaseModel): + """Response for ai_search_instance resources""" + + id: str + """Identifies the unique resource.""" + + etag: str + """ETag identifier for optimistic concurrency control. + + Formatted as "v1:" where the hash is the base64url-encoded SHA-256 + (truncated to 128 bits) of the tags map canonicalized using RFC 8785 (JSON + Canonicalization Scheme). Clients should treat ETags as opaque strings and pass + them back via the If-Match header on write operations. + """ + + name: str + """Human-readable name of the resource.""" + + tags: Dict[str, str] + """Contains key-value pairs of tags. + + Keys may contain at most 256 characters. Values may contain at most 1024 + characters and may be empty for key-only tags. + """ + + type: Literal["ai_search_instance"] + + tags_updated_at: Optional[datetime] = None + """ + Monotonic version of the resource's tags: the timestamp assigned when the tags + were last written. Returned by read endpoints, by 2PC prepare (the version that + will be assigned on commit, unless a concurrent write lands first, in which case + a newer version is assigned), and by 2PC commit (the authoritative committed + version). Omitted for untagged resources and delete commits: a deleted resource + has no current version, and deletions are ordered by event order rather than by + version. + """ + + +class ResourceTaggingTaggedResourceObjectAISearchNamespace(BaseModel): + """Response for ai_search_namespace resources""" + + id: str + """Identifies the unique resource.""" + + etag: str + """ETag identifier for optimistic concurrency control. + + Formatted as "v1:" where the hash is the base64url-encoded SHA-256 + (truncated to 128 bits) of the tags map canonicalized using RFC 8785 (JSON + Canonicalization Scheme). Clients should treat ETags as opaque strings and pass + them back via the If-Match header on write operations. + """ + + name: str + """Human-readable name of the resource.""" + + tags: Dict[str, str] + """Contains key-value pairs of tags. + + Keys may contain at most 256 characters. Values may contain at most 1024 + characters and may be empty for key-only tags. + """ + + type: Literal["ai_search_namespace"] + + tags_updated_at: Optional[datetime] = None + """ + Monotonic version of the resource's tags: the timestamp assigned when the tags + were last written. Returned by read endpoints, by 2PC prepare (the version that + will be assigned on commit, unless a concurrent write lands first, in which case + a newer version is assigned), and by 2PC commit (the authoritative committed + version). Omitted for untagged resources and delete commits: a deleted resource + has no current version, and deletions are ordered by event order rather than by + version. + """ + + class ResourceTaggingTaggedResourceObjectAlertingPolicy(BaseModel): """Response for alerting_policy resources""" @@ -536,7 +659,7 @@ class ResourceTaggingTaggedResourceObjectCustomHostname(BaseModel): """ -class ResourceTaggingTaggedResourceObjectCwsDeployment(BaseModel): +class ResourceTaggingTaggedResourceObjectCWSDeployment(BaseModel): """Response for cws_deployment resources""" id: str @@ -575,7 +698,7 @@ class ResourceTaggingTaggedResourceObjectCwsDeployment(BaseModel): """ -class ResourceTaggingTaggedResourceObjectCwsPolicy(BaseModel): +class ResourceTaggingTaggedResourceObjectCWSPolicy(BaseModel): """Response for cws_policy resources""" id: str @@ -614,7 +737,7 @@ class ResourceTaggingTaggedResourceObjectCwsPolicy(BaseModel): """ -class ResourceTaggingTaggedResourceObjectCwsPolicySet(BaseModel): +class ResourceTaggingTaggedResourceObjectCWSPolicySet(BaseModel): """Response for cws_policy_set resources""" id: str @@ -653,7 +776,7 @@ class ResourceTaggingTaggedResourceObjectCwsPolicySet(BaseModel): """ -class ResourceTaggingTaggedResourceObjectCwsWorkload(BaseModel): +class ResourceTaggingTaggedResourceObjectCWSWorkload(BaseModel): """Response for cws_workload resources""" id: str @@ -731,6 +854,45 @@ class ResourceTaggingTaggedResourceObjectD1Database(BaseModel): """ +class ResourceTaggingTaggedResourceObjectDevice(BaseModel): + """Response for device resources""" + + id: str + """Identifies the unique resource.""" + + etag: str + """ETag identifier for optimistic concurrency control. + + Formatted as "v1:" where the hash is the base64url-encoded SHA-256 + (truncated to 128 bits) of the tags map canonicalized using RFC 8785 (JSON + Canonicalization Scheme). Clients should treat ETags as opaque strings and pass + them back via the If-Match header on write operations. + """ + + name: str + """Human-readable name of the resource.""" + + tags: Dict[str, str] + """Contains key-value pairs of tags. + + Keys may contain at most 256 characters. Values may contain at most 1024 + characters and may be empty for key-only tags. + """ + + type: Literal["device"] + + tags_updated_at: Optional[datetime] = None + """ + Monotonic version of the resource's tags: the timestamp assigned when the tags + were last written. Returned by read endpoints, by 2PC prepare (the version that + will be assigned on commit, unless a concurrent write lands first, in which case + a newer version is assigned), and by 2PC commit (the authoritative committed + version). Omitted for untagged resources and delete commits: a deleted resource + has no current version, and deletions are ordered by event order rather than by + version. + """ + + class ResourceTaggingTaggedResourceObjectDNSRecord(BaseModel): """Response for dns_record resources""" @@ -1211,6 +1373,68 @@ class ResourceTaggingTaggedResourceObjectManagedClientCertificate(BaseModel): """ +class ResourceTaggingTaggedResourceObjectNamespaceWorkerNavigation(BaseModel): + """ + Read-only routing metadata resolved from EWC using the account and immutable + namespace Worker ID. Returned only by tagged-resource lists requested with + include_navigation=true. Omitted when lookup is unavailable or the child + has been deleted. Never supplied on tag writes or stored as extra_data. + """ + + namespace_id: str + + namespace_name: str + + script_name: str + + +class ResourceTaggingTaggedResourceObjectNamespaceWorker(BaseModel): + """Response for namespace_worker resources""" + + id: str + """Identifies the unique resource.""" + + etag: str + """ETag identifier for optimistic concurrency control. + + Formatted as "v1:" where the hash is the base64url-encoded SHA-256 + (truncated to 128 bits) of the tags map canonicalized using RFC 8785 (JSON + Canonicalization Scheme). Clients should treat ETags as opaque strings and pass + them back via the If-Match header on write operations. + """ + + name: str + """Human-readable name of the resource.""" + + tags: Dict[str, str] + """Contains key-value pairs of tags. + + Keys may contain at most 256 characters. Values may contain at most 1024 + characters and may be empty for key-only tags. + """ + + type: Literal["namespace_worker"] + + navigation: Optional[ResourceTaggingTaggedResourceObjectNamespaceWorkerNavigation] = None + """ + Read-only routing metadata resolved from EWC using the account and immutable + namespace Worker ID. Returned only by tagged-resource lists requested with + include_navigation=true. Omitted when lookup is unavailable or the child has + been deleted. Never supplied on tag writes or stored as extra_data. + """ + + tags_updated_at: Optional[datetime] = None + """ + Monotonic version of the resource's tags: the timestamp assigned when the tags + were last written. Returned by read endpoints, by 2PC prepare (the version that + will be assigned on commit, unless a concurrent write lands first, in which case + a newer version is assigned), and by 2PC commit (the authoritative committed + version). Omitted for untagged resources and delete commits: a deleted resource + has no current version, and deletions are ordered by event order rather than by + version. + """ + + class ResourceTaggingTaggedResourceObjectPagesProject(BaseModel): """Response for pages_project resources""" @@ -1696,20 +1920,24 @@ class ResourceTaggingTaggedResourceObjectZoneRuleset(BaseModel): ResourceTaggingTaggedResourceObjectAccessApplication, ResourceTaggingTaggedResourceObjectAccessApplicationPolicy, ResourceTaggingTaggedResourceObjectAccessGroup, + ResourceTaggingTaggedResourceObjectAccessServiceToken, ResourceTaggingTaggedResourceObjectAccount, ResourceTaggingTaggedResourceObjectAccountRuleset, ResourceTaggingTaggedResourceObjectAIGateway, + ResourceTaggingTaggedResourceObjectAISearchInstance, + ResourceTaggingTaggedResourceObjectAISearchNamespace, ResourceTaggingTaggedResourceObjectAlertingPolicy, ResourceTaggingTaggedResourceObjectAlertingWebhook, ResourceTaggingTaggedResourceObjectAPIGatewayOperation, ResourceTaggingTaggedResourceObjectCloudflaredTunnel, ResourceTaggingTaggedResourceObjectCustomCertificate, ResourceTaggingTaggedResourceObjectCustomHostname, - ResourceTaggingTaggedResourceObjectCwsDeployment, - ResourceTaggingTaggedResourceObjectCwsPolicy, - ResourceTaggingTaggedResourceObjectCwsPolicySet, - ResourceTaggingTaggedResourceObjectCwsWorkload, + ResourceTaggingTaggedResourceObjectCWSDeployment, + ResourceTaggingTaggedResourceObjectCWSPolicy, + ResourceTaggingTaggedResourceObjectCWSPolicySet, + ResourceTaggingTaggedResourceObjectCWSWorkload, ResourceTaggingTaggedResourceObjectD1Database, + ResourceTaggingTaggedResourceObjectDevice, ResourceTaggingTaggedResourceObjectDNSRecord, ResourceTaggingTaggedResourceObjectDurableObjectNamespace, ResourceTaggingTaggedResourceObjectGatewayList, @@ -1722,6 +1950,7 @@ class ResourceTaggingTaggedResourceObjectZoneRuleset(BaseModel): ResourceTaggingTaggedResourceObjectLoadBalancerMonitor, ResourceTaggingTaggedResourceObjectLoadBalancerPool, ResourceTaggingTaggedResourceObjectManagedClientCertificate, + ResourceTaggingTaggedResourceObjectNamespaceWorker, ResourceTaggingTaggedResourceObjectPagesProject, ResourceTaggingTaggedResourceObjectQueue, ResourceTaggingTaggedResourceObjectR2Bucket, diff --git a/src/cloudflare/types/resource_tagging/value_list_params.py b/src/cloudflare/types/resource_tagging/value_list_params.py index 4b58835994a..392fa4520b7 100644 --- a/src/cloudflare/types/resource_tagging/value_list_params.py +++ b/src/cloudflare/types/resource_tagging/value_list_params.py @@ -18,9 +18,12 @@ class ValueListParams(TypedDict, total=False): "access_application", "access_application_policy", "access_group", + "access_service_token", "account", "account_ruleset", "ai_gateway", + "ai_search_instance", + "ai_search_namespace", "alerting_policy", "alerting_webhook", "api_gateway_operation", @@ -32,6 +35,7 @@ class ValueListParams(TypedDict, total=False): "cws_policy_set", "cws_workload", "d1_database", + "device", "dns_record", "durable_object_namespace", "gateway_list", @@ -44,6 +48,7 @@ class ValueListParams(TypedDict, total=False): "load_balancer_monitor", "load_balancer_pool", "managed_client_certificate", + "namespace_worker", "pages_project", "queue", "r2_bucket", diff --git a/src/cloudflare/types/resource_tagging/zone_tag_get_response.py b/src/cloudflare/types/resource_tagging/zone_tag_get_response.py index c100fcdf43c..04fc159f4fb 100644 --- a/src/cloudflare/types/resource_tagging/zone_tag_get_response.py +++ b/src/cloudflare/types/resource_tagging/zone_tag_get_response.py @@ -12,20 +12,24 @@ "ResourceTaggingTaggedResourceObjectAccessApplication", "ResourceTaggingTaggedResourceObjectAccessApplicationPolicy", "ResourceTaggingTaggedResourceObjectAccessGroup", + "ResourceTaggingTaggedResourceObjectAccessServiceToken", "ResourceTaggingTaggedResourceObjectAccount", "ResourceTaggingTaggedResourceObjectAccountRuleset", "ResourceTaggingTaggedResourceObjectAIGateway", + "ResourceTaggingTaggedResourceObjectAISearchInstance", + "ResourceTaggingTaggedResourceObjectAISearchNamespace", "ResourceTaggingTaggedResourceObjectAlertingPolicy", "ResourceTaggingTaggedResourceObjectAlertingWebhook", "ResourceTaggingTaggedResourceObjectAPIGatewayOperation", "ResourceTaggingTaggedResourceObjectCloudflaredTunnel", "ResourceTaggingTaggedResourceObjectCustomCertificate", "ResourceTaggingTaggedResourceObjectCustomHostname", - "ResourceTaggingTaggedResourceObjectCwsDeployment", - "ResourceTaggingTaggedResourceObjectCwsPolicy", - "ResourceTaggingTaggedResourceObjectCwsPolicySet", - "ResourceTaggingTaggedResourceObjectCwsWorkload", + "ResourceTaggingTaggedResourceObjectCWSDeployment", + "ResourceTaggingTaggedResourceObjectCWSPolicy", + "ResourceTaggingTaggedResourceObjectCWSPolicySet", + "ResourceTaggingTaggedResourceObjectCWSWorkload", "ResourceTaggingTaggedResourceObjectD1Database", + "ResourceTaggingTaggedResourceObjectDevice", "ResourceTaggingTaggedResourceObjectDNSRecord", "ResourceTaggingTaggedResourceObjectDurableObjectNamespace", "ResourceTaggingTaggedResourceObjectGatewayList", @@ -38,6 +42,8 @@ "ResourceTaggingTaggedResourceObjectLoadBalancerMonitor", "ResourceTaggingTaggedResourceObjectLoadBalancerPool", "ResourceTaggingTaggedResourceObjectManagedClientCertificate", + "ResourceTaggingTaggedResourceObjectNamespaceWorker", + "ResourceTaggingTaggedResourceObjectNamespaceWorkerNavigation", "ResourceTaggingTaggedResourceObjectPagesProject", "ResourceTaggingTaggedResourceObjectQueue", "ResourceTaggingTaggedResourceObjectR2Bucket", @@ -176,6 +182,45 @@ class ResourceTaggingTaggedResourceObjectAccessGroup(BaseModel): """ +class ResourceTaggingTaggedResourceObjectAccessServiceToken(BaseModel): + """Response for access_service_token resources""" + + id: str + """Identifies the unique resource.""" + + etag: str + """ETag identifier for optimistic concurrency control. + + Formatted as "v1:" where the hash is the base64url-encoded SHA-256 + (truncated to 128 bits) of the tags map canonicalized using RFC 8785 (JSON + Canonicalization Scheme). Clients should treat ETags as opaque strings and pass + them back via the If-Match header on write operations. + """ + + name: str + """Human-readable name of the resource.""" + + tags: Dict[str, str] + """Contains key-value pairs of tags. + + Keys may contain at most 256 characters. Values may contain at most 1024 + characters and may be empty for key-only tags. + """ + + type: Literal["access_service_token"] + + tags_updated_at: Optional[datetime] = None + """ + Monotonic version of the resource's tags: the timestamp assigned when the tags + were last written. Returned by read endpoints, by 2PC prepare (the version that + will be assigned on commit, unless a concurrent write lands first, in which case + a newer version is assigned), and by 2PC commit (the authoritative committed + version). Omitted for untagged resources and delete commits: a deleted resource + has no current version, and deletions are ordered by event order rather than by + version. + """ + + class ResourceTaggingTaggedResourceObjectAccount(BaseModel): """Response for account resources""" @@ -293,6 +338,84 @@ class ResourceTaggingTaggedResourceObjectAIGateway(BaseModel): """ +class ResourceTaggingTaggedResourceObjectAISearchInstance(BaseModel): + """Response for ai_search_instance resources""" + + id: str + """Identifies the unique resource.""" + + etag: str + """ETag identifier for optimistic concurrency control. + + Formatted as "v1:" where the hash is the base64url-encoded SHA-256 + (truncated to 128 bits) of the tags map canonicalized using RFC 8785 (JSON + Canonicalization Scheme). Clients should treat ETags as opaque strings and pass + them back via the If-Match header on write operations. + """ + + name: str + """Human-readable name of the resource.""" + + tags: Dict[str, str] + """Contains key-value pairs of tags. + + Keys may contain at most 256 characters. Values may contain at most 1024 + characters and may be empty for key-only tags. + """ + + type: Literal["ai_search_instance"] + + tags_updated_at: Optional[datetime] = None + """ + Monotonic version of the resource's tags: the timestamp assigned when the tags + were last written. Returned by read endpoints, by 2PC prepare (the version that + will be assigned on commit, unless a concurrent write lands first, in which case + a newer version is assigned), and by 2PC commit (the authoritative committed + version). Omitted for untagged resources and delete commits: a deleted resource + has no current version, and deletions are ordered by event order rather than by + version. + """ + + +class ResourceTaggingTaggedResourceObjectAISearchNamespace(BaseModel): + """Response for ai_search_namespace resources""" + + id: str + """Identifies the unique resource.""" + + etag: str + """ETag identifier for optimistic concurrency control. + + Formatted as "v1:" where the hash is the base64url-encoded SHA-256 + (truncated to 128 bits) of the tags map canonicalized using RFC 8785 (JSON + Canonicalization Scheme). Clients should treat ETags as opaque strings and pass + them back via the If-Match header on write operations. + """ + + name: str + """Human-readable name of the resource.""" + + tags: Dict[str, str] + """Contains key-value pairs of tags. + + Keys may contain at most 256 characters. Values may contain at most 1024 + characters and may be empty for key-only tags. + """ + + type: Literal["ai_search_namespace"] + + tags_updated_at: Optional[datetime] = None + """ + Monotonic version of the resource's tags: the timestamp assigned when the tags + were last written. Returned by read endpoints, by 2PC prepare (the version that + will be assigned on commit, unless a concurrent write lands first, in which case + a newer version is assigned), and by 2PC commit (the authoritative committed + version). Omitted for untagged resources and delete commits: a deleted resource + has no current version, and deletions are ordered by event order rather than by + version. + """ + + class ResourceTaggingTaggedResourceObjectAlertingPolicy(BaseModel): """Response for alerting_policy resources""" @@ -536,7 +659,7 @@ class ResourceTaggingTaggedResourceObjectCustomHostname(BaseModel): """ -class ResourceTaggingTaggedResourceObjectCwsDeployment(BaseModel): +class ResourceTaggingTaggedResourceObjectCWSDeployment(BaseModel): """Response for cws_deployment resources""" id: str @@ -575,7 +698,7 @@ class ResourceTaggingTaggedResourceObjectCwsDeployment(BaseModel): """ -class ResourceTaggingTaggedResourceObjectCwsPolicy(BaseModel): +class ResourceTaggingTaggedResourceObjectCWSPolicy(BaseModel): """Response for cws_policy resources""" id: str @@ -614,7 +737,7 @@ class ResourceTaggingTaggedResourceObjectCwsPolicy(BaseModel): """ -class ResourceTaggingTaggedResourceObjectCwsPolicySet(BaseModel): +class ResourceTaggingTaggedResourceObjectCWSPolicySet(BaseModel): """Response for cws_policy_set resources""" id: str @@ -653,7 +776,7 @@ class ResourceTaggingTaggedResourceObjectCwsPolicySet(BaseModel): """ -class ResourceTaggingTaggedResourceObjectCwsWorkload(BaseModel): +class ResourceTaggingTaggedResourceObjectCWSWorkload(BaseModel): """Response for cws_workload resources""" id: str @@ -731,6 +854,45 @@ class ResourceTaggingTaggedResourceObjectD1Database(BaseModel): """ +class ResourceTaggingTaggedResourceObjectDevice(BaseModel): + """Response for device resources""" + + id: str + """Identifies the unique resource.""" + + etag: str + """ETag identifier for optimistic concurrency control. + + Formatted as "v1:" where the hash is the base64url-encoded SHA-256 + (truncated to 128 bits) of the tags map canonicalized using RFC 8785 (JSON + Canonicalization Scheme). Clients should treat ETags as opaque strings and pass + them back via the If-Match header on write operations. + """ + + name: str + """Human-readable name of the resource.""" + + tags: Dict[str, str] + """Contains key-value pairs of tags. + + Keys may contain at most 256 characters. Values may contain at most 1024 + characters and may be empty for key-only tags. + """ + + type: Literal["device"] + + tags_updated_at: Optional[datetime] = None + """ + Monotonic version of the resource's tags: the timestamp assigned when the tags + were last written. Returned by read endpoints, by 2PC prepare (the version that + will be assigned on commit, unless a concurrent write lands first, in which case + a newer version is assigned), and by 2PC commit (the authoritative committed + version). Omitted for untagged resources and delete commits: a deleted resource + has no current version, and deletions are ordered by event order rather than by + version. + """ + + class ResourceTaggingTaggedResourceObjectDNSRecord(BaseModel): """Response for dns_record resources""" @@ -1211,6 +1373,68 @@ class ResourceTaggingTaggedResourceObjectManagedClientCertificate(BaseModel): """ +class ResourceTaggingTaggedResourceObjectNamespaceWorkerNavigation(BaseModel): + """ + Read-only routing metadata resolved from EWC using the account and immutable + namespace Worker ID. Returned only by tagged-resource lists requested with + include_navigation=true. Omitted when lookup is unavailable or the child + has been deleted. Never supplied on tag writes or stored as extra_data. + """ + + namespace_id: str + + namespace_name: str + + script_name: str + + +class ResourceTaggingTaggedResourceObjectNamespaceWorker(BaseModel): + """Response for namespace_worker resources""" + + id: str + """Identifies the unique resource.""" + + etag: str + """ETag identifier for optimistic concurrency control. + + Formatted as "v1:" where the hash is the base64url-encoded SHA-256 + (truncated to 128 bits) of the tags map canonicalized using RFC 8785 (JSON + Canonicalization Scheme). Clients should treat ETags as opaque strings and pass + them back via the If-Match header on write operations. + """ + + name: str + """Human-readable name of the resource.""" + + tags: Dict[str, str] + """Contains key-value pairs of tags. + + Keys may contain at most 256 characters. Values may contain at most 1024 + characters and may be empty for key-only tags. + """ + + type: Literal["namespace_worker"] + + navigation: Optional[ResourceTaggingTaggedResourceObjectNamespaceWorkerNavigation] = None + """ + Read-only routing metadata resolved from EWC using the account and immutable + namespace Worker ID. Returned only by tagged-resource lists requested with + include_navigation=true. Omitted when lookup is unavailable or the child has + been deleted. Never supplied on tag writes or stored as extra_data. + """ + + tags_updated_at: Optional[datetime] = None + """ + Monotonic version of the resource's tags: the timestamp assigned when the tags + were last written. Returned by read endpoints, by 2PC prepare (the version that + will be assigned on commit, unless a concurrent write lands first, in which case + a newer version is assigned), and by 2PC commit (the authoritative committed + version). Omitted for untagged resources and delete commits: a deleted resource + has no current version, and deletions are ordered by event order rather than by + version. + """ + + class ResourceTaggingTaggedResourceObjectPagesProject(BaseModel): """Response for pages_project resources""" @@ -1696,20 +1920,24 @@ class ResourceTaggingTaggedResourceObjectZoneRuleset(BaseModel): ResourceTaggingTaggedResourceObjectAccessApplication, ResourceTaggingTaggedResourceObjectAccessApplicationPolicy, ResourceTaggingTaggedResourceObjectAccessGroup, + ResourceTaggingTaggedResourceObjectAccessServiceToken, ResourceTaggingTaggedResourceObjectAccount, ResourceTaggingTaggedResourceObjectAccountRuleset, ResourceTaggingTaggedResourceObjectAIGateway, + ResourceTaggingTaggedResourceObjectAISearchInstance, + ResourceTaggingTaggedResourceObjectAISearchNamespace, ResourceTaggingTaggedResourceObjectAlertingPolicy, ResourceTaggingTaggedResourceObjectAlertingWebhook, ResourceTaggingTaggedResourceObjectAPIGatewayOperation, ResourceTaggingTaggedResourceObjectCloudflaredTunnel, ResourceTaggingTaggedResourceObjectCustomCertificate, ResourceTaggingTaggedResourceObjectCustomHostname, - ResourceTaggingTaggedResourceObjectCwsDeployment, - ResourceTaggingTaggedResourceObjectCwsPolicy, - ResourceTaggingTaggedResourceObjectCwsPolicySet, - ResourceTaggingTaggedResourceObjectCwsWorkload, + ResourceTaggingTaggedResourceObjectCWSDeployment, + ResourceTaggingTaggedResourceObjectCWSPolicy, + ResourceTaggingTaggedResourceObjectCWSPolicySet, + ResourceTaggingTaggedResourceObjectCWSWorkload, ResourceTaggingTaggedResourceObjectD1Database, + ResourceTaggingTaggedResourceObjectDevice, ResourceTaggingTaggedResourceObjectDNSRecord, ResourceTaggingTaggedResourceObjectDurableObjectNamespace, ResourceTaggingTaggedResourceObjectGatewayList, @@ -1722,6 +1950,7 @@ class ResourceTaggingTaggedResourceObjectZoneRuleset(BaseModel): ResourceTaggingTaggedResourceObjectLoadBalancerMonitor, ResourceTaggingTaggedResourceObjectLoadBalancerPool, ResourceTaggingTaggedResourceObjectManagedClientCertificate, + ResourceTaggingTaggedResourceObjectNamespaceWorker, ResourceTaggingTaggedResourceObjectPagesProject, ResourceTaggingTaggedResourceObjectQueue, ResourceTaggingTaggedResourceObjectR2Bucket, diff --git a/src/cloudflare/types/resource_tagging/zone_tag_update_response.py b/src/cloudflare/types/resource_tagging/zone_tag_update_response.py index fafa7c9b715..6fa252365fc 100644 --- a/src/cloudflare/types/resource_tagging/zone_tag_update_response.py +++ b/src/cloudflare/types/resource_tagging/zone_tag_update_response.py @@ -12,20 +12,24 @@ "ResourceTaggingTaggedResourceObjectAccessApplication", "ResourceTaggingTaggedResourceObjectAccessApplicationPolicy", "ResourceTaggingTaggedResourceObjectAccessGroup", + "ResourceTaggingTaggedResourceObjectAccessServiceToken", "ResourceTaggingTaggedResourceObjectAccount", "ResourceTaggingTaggedResourceObjectAccountRuleset", "ResourceTaggingTaggedResourceObjectAIGateway", + "ResourceTaggingTaggedResourceObjectAISearchInstance", + "ResourceTaggingTaggedResourceObjectAISearchNamespace", "ResourceTaggingTaggedResourceObjectAlertingPolicy", "ResourceTaggingTaggedResourceObjectAlertingWebhook", "ResourceTaggingTaggedResourceObjectAPIGatewayOperation", "ResourceTaggingTaggedResourceObjectCloudflaredTunnel", "ResourceTaggingTaggedResourceObjectCustomCertificate", "ResourceTaggingTaggedResourceObjectCustomHostname", - "ResourceTaggingTaggedResourceObjectCwsDeployment", - "ResourceTaggingTaggedResourceObjectCwsPolicy", - "ResourceTaggingTaggedResourceObjectCwsPolicySet", - "ResourceTaggingTaggedResourceObjectCwsWorkload", + "ResourceTaggingTaggedResourceObjectCWSDeployment", + "ResourceTaggingTaggedResourceObjectCWSPolicy", + "ResourceTaggingTaggedResourceObjectCWSPolicySet", + "ResourceTaggingTaggedResourceObjectCWSWorkload", "ResourceTaggingTaggedResourceObjectD1Database", + "ResourceTaggingTaggedResourceObjectDevice", "ResourceTaggingTaggedResourceObjectDNSRecord", "ResourceTaggingTaggedResourceObjectDurableObjectNamespace", "ResourceTaggingTaggedResourceObjectGatewayList", @@ -38,6 +42,8 @@ "ResourceTaggingTaggedResourceObjectLoadBalancerMonitor", "ResourceTaggingTaggedResourceObjectLoadBalancerPool", "ResourceTaggingTaggedResourceObjectManagedClientCertificate", + "ResourceTaggingTaggedResourceObjectNamespaceWorker", + "ResourceTaggingTaggedResourceObjectNamespaceWorkerNavigation", "ResourceTaggingTaggedResourceObjectPagesProject", "ResourceTaggingTaggedResourceObjectQueue", "ResourceTaggingTaggedResourceObjectR2Bucket", @@ -176,6 +182,45 @@ class ResourceTaggingTaggedResourceObjectAccessGroup(BaseModel): """ +class ResourceTaggingTaggedResourceObjectAccessServiceToken(BaseModel): + """Response for access_service_token resources""" + + id: str + """Identifies the unique resource.""" + + etag: str + """ETag identifier for optimistic concurrency control. + + Formatted as "v1:" where the hash is the base64url-encoded SHA-256 + (truncated to 128 bits) of the tags map canonicalized using RFC 8785 (JSON + Canonicalization Scheme). Clients should treat ETags as opaque strings and pass + them back via the If-Match header on write operations. + """ + + name: str + """Human-readable name of the resource.""" + + tags: Dict[str, str] + """Contains key-value pairs of tags. + + Keys may contain at most 256 characters. Values may contain at most 1024 + characters and may be empty for key-only tags. + """ + + type: Literal["access_service_token"] + + tags_updated_at: Optional[datetime] = None + """ + Monotonic version of the resource's tags: the timestamp assigned when the tags + were last written. Returned by read endpoints, by 2PC prepare (the version that + will be assigned on commit, unless a concurrent write lands first, in which case + a newer version is assigned), and by 2PC commit (the authoritative committed + version). Omitted for untagged resources and delete commits: a deleted resource + has no current version, and deletions are ordered by event order rather than by + version. + """ + + class ResourceTaggingTaggedResourceObjectAccount(BaseModel): """Response for account resources""" @@ -293,6 +338,84 @@ class ResourceTaggingTaggedResourceObjectAIGateway(BaseModel): """ +class ResourceTaggingTaggedResourceObjectAISearchInstance(BaseModel): + """Response for ai_search_instance resources""" + + id: str + """Identifies the unique resource.""" + + etag: str + """ETag identifier for optimistic concurrency control. + + Formatted as "v1:" where the hash is the base64url-encoded SHA-256 + (truncated to 128 bits) of the tags map canonicalized using RFC 8785 (JSON + Canonicalization Scheme). Clients should treat ETags as opaque strings and pass + them back via the If-Match header on write operations. + """ + + name: str + """Human-readable name of the resource.""" + + tags: Dict[str, str] + """Contains key-value pairs of tags. + + Keys may contain at most 256 characters. Values may contain at most 1024 + characters and may be empty for key-only tags. + """ + + type: Literal["ai_search_instance"] + + tags_updated_at: Optional[datetime] = None + """ + Monotonic version of the resource's tags: the timestamp assigned when the tags + were last written. Returned by read endpoints, by 2PC prepare (the version that + will be assigned on commit, unless a concurrent write lands first, in which case + a newer version is assigned), and by 2PC commit (the authoritative committed + version). Omitted for untagged resources and delete commits: a deleted resource + has no current version, and deletions are ordered by event order rather than by + version. + """ + + +class ResourceTaggingTaggedResourceObjectAISearchNamespace(BaseModel): + """Response for ai_search_namespace resources""" + + id: str + """Identifies the unique resource.""" + + etag: str + """ETag identifier for optimistic concurrency control. + + Formatted as "v1:" where the hash is the base64url-encoded SHA-256 + (truncated to 128 bits) of the tags map canonicalized using RFC 8785 (JSON + Canonicalization Scheme). Clients should treat ETags as opaque strings and pass + them back via the If-Match header on write operations. + """ + + name: str + """Human-readable name of the resource.""" + + tags: Dict[str, str] + """Contains key-value pairs of tags. + + Keys may contain at most 256 characters. Values may contain at most 1024 + characters and may be empty for key-only tags. + """ + + type: Literal["ai_search_namespace"] + + tags_updated_at: Optional[datetime] = None + """ + Monotonic version of the resource's tags: the timestamp assigned when the tags + were last written. Returned by read endpoints, by 2PC prepare (the version that + will be assigned on commit, unless a concurrent write lands first, in which case + a newer version is assigned), and by 2PC commit (the authoritative committed + version). Omitted for untagged resources and delete commits: a deleted resource + has no current version, and deletions are ordered by event order rather than by + version. + """ + + class ResourceTaggingTaggedResourceObjectAlertingPolicy(BaseModel): """Response for alerting_policy resources""" @@ -536,7 +659,7 @@ class ResourceTaggingTaggedResourceObjectCustomHostname(BaseModel): """ -class ResourceTaggingTaggedResourceObjectCwsDeployment(BaseModel): +class ResourceTaggingTaggedResourceObjectCWSDeployment(BaseModel): """Response for cws_deployment resources""" id: str @@ -575,7 +698,7 @@ class ResourceTaggingTaggedResourceObjectCwsDeployment(BaseModel): """ -class ResourceTaggingTaggedResourceObjectCwsPolicy(BaseModel): +class ResourceTaggingTaggedResourceObjectCWSPolicy(BaseModel): """Response for cws_policy resources""" id: str @@ -614,7 +737,7 @@ class ResourceTaggingTaggedResourceObjectCwsPolicy(BaseModel): """ -class ResourceTaggingTaggedResourceObjectCwsPolicySet(BaseModel): +class ResourceTaggingTaggedResourceObjectCWSPolicySet(BaseModel): """Response for cws_policy_set resources""" id: str @@ -653,7 +776,7 @@ class ResourceTaggingTaggedResourceObjectCwsPolicySet(BaseModel): """ -class ResourceTaggingTaggedResourceObjectCwsWorkload(BaseModel): +class ResourceTaggingTaggedResourceObjectCWSWorkload(BaseModel): """Response for cws_workload resources""" id: str @@ -731,6 +854,45 @@ class ResourceTaggingTaggedResourceObjectD1Database(BaseModel): """ +class ResourceTaggingTaggedResourceObjectDevice(BaseModel): + """Response for device resources""" + + id: str + """Identifies the unique resource.""" + + etag: str + """ETag identifier for optimistic concurrency control. + + Formatted as "v1:" where the hash is the base64url-encoded SHA-256 + (truncated to 128 bits) of the tags map canonicalized using RFC 8785 (JSON + Canonicalization Scheme). Clients should treat ETags as opaque strings and pass + them back via the If-Match header on write operations. + """ + + name: str + """Human-readable name of the resource.""" + + tags: Dict[str, str] + """Contains key-value pairs of tags. + + Keys may contain at most 256 characters. Values may contain at most 1024 + characters and may be empty for key-only tags. + """ + + type: Literal["device"] + + tags_updated_at: Optional[datetime] = None + """ + Monotonic version of the resource's tags: the timestamp assigned when the tags + were last written. Returned by read endpoints, by 2PC prepare (the version that + will be assigned on commit, unless a concurrent write lands first, in which case + a newer version is assigned), and by 2PC commit (the authoritative committed + version). Omitted for untagged resources and delete commits: a deleted resource + has no current version, and deletions are ordered by event order rather than by + version. + """ + + class ResourceTaggingTaggedResourceObjectDNSRecord(BaseModel): """Response for dns_record resources""" @@ -1211,6 +1373,68 @@ class ResourceTaggingTaggedResourceObjectManagedClientCertificate(BaseModel): """ +class ResourceTaggingTaggedResourceObjectNamespaceWorkerNavigation(BaseModel): + """ + Read-only routing metadata resolved from EWC using the account and immutable + namespace Worker ID. Returned only by tagged-resource lists requested with + include_navigation=true. Omitted when lookup is unavailable or the child + has been deleted. Never supplied on tag writes or stored as extra_data. + """ + + namespace_id: str + + namespace_name: str + + script_name: str + + +class ResourceTaggingTaggedResourceObjectNamespaceWorker(BaseModel): + """Response for namespace_worker resources""" + + id: str + """Identifies the unique resource.""" + + etag: str + """ETag identifier for optimistic concurrency control. + + Formatted as "v1:" where the hash is the base64url-encoded SHA-256 + (truncated to 128 bits) of the tags map canonicalized using RFC 8785 (JSON + Canonicalization Scheme). Clients should treat ETags as opaque strings and pass + them back via the If-Match header on write operations. + """ + + name: str + """Human-readable name of the resource.""" + + tags: Dict[str, str] + """Contains key-value pairs of tags. + + Keys may contain at most 256 characters. Values may contain at most 1024 + characters and may be empty for key-only tags. + """ + + type: Literal["namespace_worker"] + + navigation: Optional[ResourceTaggingTaggedResourceObjectNamespaceWorkerNavigation] = None + """ + Read-only routing metadata resolved from EWC using the account and immutable + namespace Worker ID. Returned only by tagged-resource lists requested with + include_navigation=true. Omitted when lookup is unavailable or the child has + been deleted. Never supplied on tag writes or stored as extra_data. + """ + + tags_updated_at: Optional[datetime] = None + """ + Monotonic version of the resource's tags: the timestamp assigned when the tags + were last written. Returned by read endpoints, by 2PC prepare (the version that + will be assigned on commit, unless a concurrent write lands first, in which case + a newer version is assigned), and by 2PC commit (the authoritative committed + version). Omitted for untagged resources and delete commits: a deleted resource + has no current version, and deletions are ordered by event order rather than by + version. + """ + + class ResourceTaggingTaggedResourceObjectPagesProject(BaseModel): """Response for pages_project resources""" @@ -1696,20 +1920,24 @@ class ResourceTaggingTaggedResourceObjectZoneRuleset(BaseModel): ResourceTaggingTaggedResourceObjectAccessApplication, ResourceTaggingTaggedResourceObjectAccessApplicationPolicy, ResourceTaggingTaggedResourceObjectAccessGroup, + ResourceTaggingTaggedResourceObjectAccessServiceToken, ResourceTaggingTaggedResourceObjectAccount, ResourceTaggingTaggedResourceObjectAccountRuleset, ResourceTaggingTaggedResourceObjectAIGateway, + ResourceTaggingTaggedResourceObjectAISearchInstance, + ResourceTaggingTaggedResourceObjectAISearchNamespace, ResourceTaggingTaggedResourceObjectAlertingPolicy, ResourceTaggingTaggedResourceObjectAlertingWebhook, ResourceTaggingTaggedResourceObjectAPIGatewayOperation, ResourceTaggingTaggedResourceObjectCloudflaredTunnel, ResourceTaggingTaggedResourceObjectCustomCertificate, ResourceTaggingTaggedResourceObjectCustomHostname, - ResourceTaggingTaggedResourceObjectCwsDeployment, - ResourceTaggingTaggedResourceObjectCwsPolicy, - ResourceTaggingTaggedResourceObjectCwsPolicySet, - ResourceTaggingTaggedResourceObjectCwsWorkload, + ResourceTaggingTaggedResourceObjectCWSDeployment, + ResourceTaggingTaggedResourceObjectCWSPolicy, + ResourceTaggingTaggedResourceObjectCWSPolicySet, + ResourceTaggingTaggedResourceObjectCWSWorkload, ResourceTaggingTaggedResourceObjectD1Database, + ResourceTaggingTaggedResourceObjectDevice, ResourceTaggingTaggedResourceObjectDNSRecord, ResourceTaggingTaggedResourceObjectDurableObjectNamespace, ResourceTaggingTaggedResourceObjectGatewayList, @@ -1722,6 +1950,7 @@ class ResourceTaggingTaggedResourceObjectZoneRuleset(BaseModel): ResourceTaggingTaggedResourceObjectLoadBalancerMonitor, ResourceTaggingTaggedResourceObjectLoadBalancerPool, ResourceTaggingTaggedResourceObjectManagedClientCertificate, + ResourceTaggingTaggedResourceObjectNamespaceWorker, ResourceTaggingTaggedResourceObjectPagesProject, ResourceTaggingTaggedResourceObjectQueue, ResourceTaggingTaggedResourceObjectR2Bucket, diff --git a/src/cloudflare/types/rulesets/phase.py b/src/cloudflare/types/rulesets/phase.py index 7993a770ba1..e809000dd9b 100644 --- a/src/cloudflare/types/rulesets/phase.py +++ b/src/cloudflare/types/rulesets/phase.py @@ -23,6 +23,7 @@ "http_request_transform", "http_response_cache_settings", "http_response_compression", + "http_response_firewall_custom", "http_response_firewall_managed", "http_response_headers_transform", "magic_transit", diff --git a/src/cloudflare/types/rulesets/phase_get_response.py b/src/cloudflare/types/rulesets/phase_get_response.py index f8f6bf3499f..326478dc59e 100644 --- a/src/cloudflare/types/rulesets/phase_get_response.py +++ b/src/cloudflare/types/rulesets/phase_get_response.py @@ -29,102 +29,427 @@ __all__ = [ "PhaseGetResponse", - "Rule", - "RuleBlockRule", - "RuleChallengeRule", - "RuleChallengeRuleExposedCredentialCheck", - "RuleChallengeRuleRatelimit", - "RuleResponseCompressionRule", - "RuleDDoSDynamicRule", - "RuleExecuteRule", - "RuleForceConnectionCloseRule", - "RuleJavaScriptChallengeRule", - "RuleJavaScriptChallengeRuleExposedCredentialCheck", - "RuleJavaScriptChallengeRuleRatelimit", - "RuleLogRule", - "RuleLogCustomFieldRule", - "RuleManagedChallengeRule", - "RuleRedirectRule", - "RuleRewriteRule", - "RuleRouteRule", - "RuleScoreRule", - "RuleServeErrorRule", - "RuleSetCacheControlRule", - "RuleSetCacheControlRuleActionParameters", - "RuleSetCacheControlRuleActionParametersImmutable", - "RuleSetCacheControlRuleActionParametersImmutableSetDirective", - "RuleSetCacheControlRuleActionParametersImmutableRemoveDirective", - "RuleSetCacheControlRuleActionParametersMaxAge", - "RuleSetCacheControlRuleActionParametersMaxAgeSetDirective", - "RuleSetCacheControlRuleActionParametersMaxAgeRemoveDirective", - "RuleSetCacheControlRuleActionParametersMustRevalidate", - "RuleSetCacheControlRuleActionParametersMustRevalidateSetDirective", - "RuleSetCacheControlRuleActionParametersMustRevalidateRemoveDirective", - "RuleSetCacheControlRuleActionParametersMustUnderstand", - "RuleSetCacheControlRuleActionParametersMustUnderstandSetDirective", - "RuleSetCacheControlRuleActionParametersMustUnderstandRemoveDirective", - "RuleSetCacheControlRuleActionParametersNoCache", - "RuleSetCacheControlRuleActionParametersNoCacheSetDirective", - "RuleSetCacheControlRuleActionParametersNoCacheRemoveDirective", - "RuleSetCacheControlRuleActionParametersNoStore", - "RuleSetCacheControlRuleActionParametersNoStoreSetDirective", - "RuleSetCacheControlRuleActionParametersNoStoreRemoveDirective", - "RuleSetCacheControlRuleActionParametersNoTransform", - "RuleSetCacheControlRuleActionParametersNoTransformSetDirective", - "RuleSetCacheControlRuleActionParametersNoTransformRemoveDirective", - "RuleSetCacheControlRuleActionParametersPrivate", - "RuleSetCacheControlRuleActionParametersPrivateSetDirective", - "RuleSetCacheControlRuleActionParametersPrivateRemoveDirective", - "RuleSetCacheControlRuleActionParametersProxyRevalidate", - "RuleSetCacheControlRuleActionParametersProxyRevalidateSetDirective", - "RuleSetCacheControlRuleActionParametersProxyRevalidateRemoveDirective", - "RuleSetCacheControlRuleActionParametersPublic", - "RuleSetCacheControlRuleActionParametersPublicSetDirective", - "RuleSetCacheControlRuleActionParametersPublicRemoveDirective", - "RuleSetCacheControlRuleActionParametersSMaxage", - "RuleSetCacheControlRuleActionParametersSMaxageSetDirective", - "RuleSetCacheControlRuleActionParametersSMaxageRemoveDirective", - "RuleSetCacheControlRuleActionParametersStaleIfError", - "RuleSetCacheControlRuleActionParametersStaleIfErrorSetDirective", - "RuleSetCacheControlRuleActionParametersStaleIfErrorRemoveDirective", - "RuleSetCacheControlRuleActionParametersStaleWhileRevalidate", - "RuleSetCacheControlRuleActionParametersStaleWhileRevalidateSetDirective", - "RuleSetCacheControlRuleActionParametersStaleWhileRevalidateRemoveDirective", - "RuleSetCacheControlRuleExposedCredentialCheck", - "RuleSetCacheControlRuleRatelimit", - "RuleSetCacheSettingsRule", - "RuleSetCacheTagsRule", - "RuleSetCacheTagsRuleActionParameters", - "RuleSetCacheTagsRuleActionParametersAddCacheTagsValues", - "RuleSetCacheTagsRuleActionParametersAddCacheTagsExpression", - "RuleSetCacheTagsRuleActionParametersRemoveCacheTagsValues", - "RuleSetCacheTagsRuleActionParametersRemoveCacheTagsExpression", - "RuleSetCacheTagsRuleActionParametersSetCacheTagsValues", - "RuleSetCacheTagsRuleActionParametersSetCacheTagsExpression", - "RuleSetCacheTagsRuleExposedCredentialCheck", - "RuleSetCacheTagsRuleRatelimit", - "RuleSetConfigurationRule", - "RuleSkipRule", - "RuleTransformResponseHTMLRule", - "RuleTransformResponseHTMLRuleActionParameters", - "RuleTransformResponseHTMLRuleExposedCredentialCheck", - "RuleTransformResponseHTMLRuleRatelimit", -] - - -class RuleBlockRule(BlockRule): - id: str # type: ignore - - action: str # type: ignore - - enabled: bool # type: ignore - - expression: str # type: ignore - - ref: str # type: ignore - - -class RuleChallengeRuleExposedCredentialCheck(BaseModel): + "UnionMember0", + "UnionMember0Rule", + "UnionMember0RuleBlockRule", + "UnionMember0RuleChallengeRule", + "UnionMember0RuleChallengeRuleExposedCredentialCheck", + "UnionMember0RuleChallengeRuleRatelimit", + "UnionMember0RuleResponseCompressionRule", + "UnionMember0RuleDDoSDynamicRule", + "UnionMember0RuleExecuteRule", + "UnionMember0RuleForceConnectionCloseRule", + "UnionMember0RuleJavaScriptChallengeRule", + "UnionMember0RuleJavaScriptChallengeRuleExposedCredentialCheck", + "UnionMember0RuleJavaScriptChallengeRuleRatelimit", + "UnionMember0RuleLogRule", + "UnionMember0RuleLogCustomFieldRule", + "UnionMember0RuleManagedChallengeRule", + "UnionMember0RuleRedirectRule", + "UnionMember0RuleRewriteRule", + "UnionMember0RuleRouteRule", + "UnionMember0RuleScoreRule", + "UnionMember0RuleServeErrorRule", + "UnionMember0RuleSetCacheControlRule", + "UnionMember0RuleSetCacheControlRuleActionParameters", + "UnionMember0RuleSetCacheControlRuleActionParametersImmutable", + "UnionMember0RuleSetCacheControlRuleActionParametersImmutableSetDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersImmutableRemoveDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersMaxAge", + "UnionMember0RuleSetCacheControlRuleActionParametersMaxAgeSetDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersMaxAgeRemoveDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersMustRevalidate", + "UnionMember0RuleSetCacheControlRuleActionParametersMustRevalidateSetDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersMustRevalidateRemoveDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersMustUnderstand", + "UnionMember0RuleSetCacheControlRuleActionParametersMustUnderstandSetDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersMustUnderstandRemoveDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersNoCache", + "UnionMember0RuleSetCacheControlRuleActionParametersNoCacheSetDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersNoCacheRemoveDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersNoStore", + "UnionMember0RuleSetCacheControlRuleActionParametersNoStoreSetDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersNoStoreRemoveDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersNoTransform", + "UnionMember0RuleSetCacheControlRuleActionParametersNoTransformSetDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersNoTransformRemoveDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersPrivate", + "UnionMember0RuleSetCacheControlRuleActionParametersPrivateSetDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersPrivateRemoveDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersProxyRevalidate", + "UnionMember0RuleSetCacheControlRuleActionParametersProxyRevalidateSetDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersProxyRevalidateRemoveDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersPublic", + "UnionMember0RuleSetCacheControlRuleActionParametersPublicSetDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersPublicRemoveDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersSMaxage", + "UnionMember0RuleSetCacheControlRuleActionParametersSMaxageSetDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersSMaxageRemoveDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersStaleIfError", + "UnionMember0RuleSetCacheControlRuleActionParametersStaleIfErrorSetDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersStaleIfErrorRemoveDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersStaleWhileRevalidate", + "UnionMember0RuleSetCacheControlRuleActionParametersStaleWhileRevalidateSetDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersStaleWhileRevalidateRemoveDirective", + "UnionMember0RuleSetCacheControlRuleExposedCredentialCheck", + "UnionMember0RuleSetCacheControlRuleRatelimit", + "UnionMember0RuleSetCacheSettingsRule", + "UnionMember0RuleSetCacheTagsRule", + "UnionMember0RuleSetCacheTagsRuleActionParameters", + "UnionMember0RuleSetCacheTagsRuleActionParametersAddCacheTagsValues", + "UnionMember0RuleSetCacheTagsRuleActionParametersAddCacheTagsExpression", + "UnionMember0RuleSetCacheTagsRuleActionParametersRemoveCacheTagsValues", + "UnionMember0RuleSetCacheTagsRuleActionParametersRemoveCacheTagsExpression", + "UnionMember0RuleSetCacheTagsRuleActionParametersSetCacheTagsValues", + "UnionMember0RuleSetCacheTagsRuleActionParametersSetCacheTagsExpression", + "UnionMember0RuleSetCacheTagsRuleExposedCredentialCheck", + "UnionMember0RuleSetCacheTagsRuleRatelimit", + "UnionMember0RuleSetConfigurationRule", + "UnionMember0RuleSkipRule", + "UnionMember0RuleTransformResponseHTMLRule", + "UnionMember0RuleTransformResponseHTMLRuleActionParameters", + "UnionMember0RuleTransformResponseHTMLRuleExposedCredentialCheck", + "UnionMember0RuleTransformResponseHTMLRuleRatelimit", + "UnionMember1", + "UnionMember1Rule", + "UnionMember1RuleBlockRule", + "UnionMember1RuleChallengeRule", + "UnionMember1RuleChallengeRuleExposedCredentialCheck", + "UnionMember1RuleChallengeRuleRatelimit", + "UnionMember1RuleResponseCompressionRule", + "UnionMember1RuleDDoSDynamicRule", + "UnionMember1RuleExecuteRule", + "UnionMember1RuleForceConnectionCloseRule", + "UnionMember1RuleJavaScriptChallengeRule", + "UnionMember1RuleJavaScriptChallengeRuleExposedCredentialCheck", + "UnionMember1RuleJavaScriptChallengeRuleRatelimit", + "UnionMember1RuleLogRule", + "UnionMember1RuleLogCustomFieldRule", + "UnionMember1RuleManagedChallengeRule", + "UnionMember1RuleRedirectRule", + "UnionMember1RuleRewriteRule", + "UnionMember1RuleRouteRule", + "UnionMember1RuleScoreRule", + "UnionMember1RuleServeErrorRule", + "UnionMember1RuleSetCacheControlRule", + "UnionMember1RuleSetCacheControlRuleActionParameters", + "UnionMember1RuleSetCacheControlRuleActionParametersImmutable", + "UnionMember1RuleSetCacheControlRuleActionParametersImmutableSetDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersImmutableRemoveDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersMaxAge", + "UnionMember1RuleSetCacheControlRuleActionParametersMaxAgeSetDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersMaxAgeRemoveDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersMustRevalidate", + "UnionMember1RuleSetCacheControlRuleActionParametersMustRevalidateSetDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersMustRevalidateRemoveDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersMustUnderstand", + "UnionMember1RuleSetCacheControlRuleActionParametersMustUnderstandSetDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersMustUnderstandRemoveDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersNoCache", + "UnionMember1RuleSetCacheControlRuleActionParametersNoCacheSetDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersNoCacheRemoveDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersNoStore", + "UnionMember1RuleSetCacheControlRuleActionParametersNoStoreSetDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersNoStoreRemoveDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersNoTransform", + "UnionMember1RuleSetCacheControlRuleActionParametersNoTransformSetDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersNoTransformRemoveDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersPrivate", + "UnionMember1RuleSetCacheControlRuleActionParametersPrivateSetDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersPrivateRemoveDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersProxyRevalidate", + "UnionMember1RuleSetCacheControlRuleActionParametersProxyRevalidateSetDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersProxyRevalidateRemoveDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersPublic", + "UnionMember1RuleSetCacheControlRuleActionParametersPublicSetDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersPublicRemoveDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersSMaxage", + "UnionMember1RuleSetCacheControlRuleActionParametersSMaxageSetDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersSMaxageRemoveDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersStaleIfError", + "UnionMember1RuleSetCacheControlRuleActionParametersStaleIfErrorSetDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersStaleIfErrorRemoveDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersStaleWhileRevalidate", + "UnionMember1RuleSetCacheControlRuleActionParametersStaleWhileRevalidateSetDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersStaleWhileRevalidateRemoveDirective", + "UnionMember1RuleSetCacheControlRuleExposedCredentialCheck", + "UnionMember1RuleSetCacheControlRuleRatelimit", + "UnionMember1RuleSetCacheSettingsRule", + "UnionMember1RuleSetCacheTagsRule", + "UnionMember1RuleSetCacheTagsRuleActionParameters", + "UnionMember1RuleSetCacheTagsRuleActionParametersAddCacheTagsValues", + "UnionMember1RuleSetCacheTagsRuleActionParametersAddCacheTagsExpression", + "UnionMember1RuleSetCacheTagsRuleActionParametersRemoveCacheTagsValues", + "UnionMember1RuleSetCacheTagsRuleActionParametersRemoveCacheTagsExpression", + "UnionMember1RuleSetCacheTagsRuleActionParametersSetCacheTagsValues", + "UnionMember1RuleSetCacheTagsRuleActionParametersSetCacheTagsExpression", + "UnionMember1RuleSetCacheTagsRuleExposedCredentialCheck", + "UnionMember1RuleSetCacheTagsRuleRatelimit", + "UnionMember1RuleSetConfigurationRule", + "UnionMember1RuleSkipRule", + "UnionMember1RuleTransformResponseHTMLRule", + "UnionMember1RuleTransformResponseHTMLRuleActionParameters", + "UnionMember1RuleTransformResponseHTMLRuleExposedCredentialCheck", + "UnionMember1RuleTransformResponseHTMLRuleRatelimit", + "UnionMember2", + "UnionMember2Rule", + "UnionMember2RuleBlockRule", + "UnionMember2RuleChallengeRule", + "UnionMember2RuleChallengeRuleExposedCredentialCheck", + "UnionMember2RuleChallengeRuleRatelimit", + "UnionMember2RuleResponseCompressionRule", + "UnionMember2RuleDDoSDynamicRule", + "UnionMember2RuleExecuteRule", + "UnionMember2RuleForceConnectionCloseRule", + "UnionMember2RuleJavaScriptChallengeRule", + "UnionMember2RuleJavaScriptChallengeRuleExposedCredentialCheck", + "UnionMember2RuleJavaScriptChallengeRuleRatelimit", + "UnionMember2RuleLogRule", + "UnionMember2RuleLogCustomFieldRule", + "UnionMember2RuleManagedChallengeRule", + "UnionMember2RuleRedirectRule", + "UnionMember2RuleRewriteRule", + "UnionMember2RuleRouteRule", + "UnionMember2RuleScoreRule", + "UnionMember2RuleServeErrorRule", + "UnionMember2RuleSetCacheControlRule", + "UnionMember2RuleSetCacheControlRuleActionParameters", + "UnionMember2RuleSetCacheControlRuleActionParametersImmutable", + "UnionMember2RuleSetCacheControlRuleActionParametersImmutableSetDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersImmutableRemoveDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersMaxAge", + "UnionMember2RuleSetCacheControlRuleActionParametersMaxAgeSetDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersMaxAgeRemoveDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersMustRevalidate", + "UnionMember2RuleSetCacheControlRuleActionParametersMustRevalidateSetDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersMustRevalidateRemoveDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersMustUnderstand", + "UnionMember2RuleSetCacheControlRuleActionParametersMustUnderstandSetDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersMustUnderstandRemoveDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersNoCache", + "UnionMember2RuleSetCacheControlRuleActionParametersNoCacheSetDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersNoCacheRemoveDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersNoStore", + "UnionMember2RuleSetCacheControlRuleActionParametersNoStoreSetDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersNoStoreRemoveDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersNoTransform", + "UnionMember2RuleSetCacheControlRuleActionParametersNoTransformSetDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersNoTransformRemoveDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersPrivate", + "UnionMember2RuleSetCacheControlRuleActionParametersPrivateSetDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersPrivateRemoveDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersProxyRevalidate", + "UnionMember2RuleSetCacheControlRuleActionParametersProxyRevalidateSetDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersProxyRevalidateRemoveDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersPublic", + "UnionMember2RuleSetCacheControlRuleActionParametersPublicSetDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersPublicRemoveDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersSMaxage", + "UnionMember2RuleSetCacheControlRuleActionParametersSMaxageSetDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersSMaxageRemoveDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersStaleIfError", + "UnionMember2RuleSetCacheControlRuleActionParametersStaleIfErrorSetDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersStaleIfErrorRemoveDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersStaleWhileRevalidate", + "UnionMember2RuleSetCacheControlRuleActionParametersStaleWhileRevalidateSetDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersStaleWhileRevalidateRemoveDirective", + "UnionMember2RuleSetCacheControlRuleExposedCredentialCheck", + "UnionMember2RuleSetCacheControlRuleRatelimit", + "UnionMember2RuleSetCacheSettingsRule", + "UnionMember2RuleSetCacheTagsRule", + "UnionMember2RuleSetCacheTagsRuleActionParameters", + "UnionMember2RuleSetCacheTagsRuleActionParametersAddCacheTagsValues", + "UnionMember2RuleSetCacheTagsRuleActionParametersAddCacheTagsExpression", + "UnionMember2RuleSetCacheTagsRuleActionParametersRemoveCacheTagsValues", + "UnionMember2RuleSetCacheTagsRuleActionParametersRemoveCacheTagsExpression", + "UnionMember2RuleSetCacheTagsRuleActionParametersSetCacheTagsValues", + "UnionMember2RuleSetCacheTagsRuleActionParametersSetCacheTagsExpression", + "UnionMember2RuleSetCacheTagsRuleExposedCredentialCheck", + "UnionMember2RuleSetCacheTagsRuleRatelimit", + "UnionMember2RuleSetConfigurationRule", + "UnionMember2RuleSkipRule", + "UnionMember2RuleTransformResponseHTMLRule", + "UnionMember2RuleTransformResponseHTMLRuleActionParameters", + "UnionMember2RuleTransformResponseHTMLRuleExposedCredentialCheck", + "UnionMember2RuleTransformResponseHTMLRuleRatelimit", + "UnionMember3", + "UnionMember3Rule", + "UnionMember3RuleBlockRule", + "UnionMember3RuleChallengeRule", + "UnionMember3RuleChallengeRuleExposedCredentialCheck", + "UnionMember3RuleChallengeRuleRatelimit", + "UnionMember3RuleResponseCompressionRule", + "UnionMember3RuleDDoSDynamicRule", + "UnionMember3RuleExecuteRule", + "UnionMember3RuleForceConnectionCloseRule", + "UnionMember3RuleJavaScriptChallengeRule", + "UnionMember3RuleJavaScriptChallengeRuleExposedCredentialCheck", + "UnionMember3RuleJavaScriptChallengeRuleRatelimit", + "UnionMember3RuleLogRule", + "UnionMember3RuleLogCustomFieldRule", + "UnionMember3RuleManagedChallengeRule", + "UnionMember3RuleRedirectRule", + "UnionMember3RuleRewriteRule", + "UnionMember3RuleRouteRule", + "UnionMember3RuleScoreRule", + "UnionMember3RuleServeErrorRule", + "UnionMember3RuleSetCacheControlRule", + "UnionMember3RuleSetCacheControlRuleActionParameters", + "UnionMember3RuleSetCacheControlRuleActionParametersImmutable", + "UnionMember3RuleSetCacheControlRuleActionParametersImmutableSetDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersImmutableRemoveDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersMaxAge", + "UnionMember3RuleSetCacheControlRuleActionParametersMaxAgeSetDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersMaxAgeRemoveDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersMustRevalidate", + "UnionMember3RuleSetCacheControlRuleActionParametersMustRevalidateSetDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersMustRevalidateRemoveDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersMustUnderstand", + "UnionMember3RuleSetCacheControlRuleActionParametersMustUnderstandSetDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersMustUnderstandRemoveDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersNoCache", + "UnionMember3RuleSetCacheControlRuleActionParametersNoCacheSetDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersNoCacheRemoveDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersNoStore", + "UnionMember3RuleSetCacheControlRuleActionParametersNoStoreSetDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersNoStoreRemoveDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersNoTransform", + "UnionMember3RuleSetCacheControlRuleActionParametersNoTransformSetDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersNoTransformRemoveDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersPrivate", + "UnionMember3RuleSetCacheControlRuleActionParametersPrivateSetDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersPrivateRemoveDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersProxyRevalidate", + "UnionMember3RuleSetCacheControlRuleActionParametersProxyRevalidateSetDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersProxyRevalidateRemoveDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersPublic", + "UnionMember3RuleSetCacheControlRuleActionParametersPublicSetDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersPublicRemoveDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersSMaxage", + "UnionMember3RuleSetCacheControlRuleActionParametersSMaxageSetDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersSMaxageRemoveDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersStaleIfError", + "UnionMember3RuleSetCacheControlRuleActionParametersStaleIfErrorSetDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersStaleIfErrorRemoveDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersStaleWhileRevalidate", + "UnionMember3RuleSetCacheControlRuleActionParametersStaleWhileRevalidateSetDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersStaleWhileRevalidateRemoveDirective", + "UnionMember3RuleSetCacheControlRuleExposedCredentialCheck", + "UnionMember3RuleSetCacheControlRuleRatelimit", + "UnionMember3RuleSetCacheSettingsRule", + "UnionMember3RuleSetCacheTagsRule", + "UnionMember3RuleSetCacheTagsRuleActionParameters", + "UnionMember3RuleSetCacheTagsRuleActionParametersAddCacheTagsValues", + "UnionMember3RuleSetCacheTagsRuleActionParametersAddCacheTagsExpression", + "UnionMember3RuleSetCacheTagsRuleActionParametersRemoveCacheTagsValues", + "UnionMember3RuleSetCacheTagsRuleActionParametersRemoveCacheTagsExpression", + "UnionMember3RuleSetCacheTagsRuleActionParametersSetCacheTagsValues", + "UnionMember3RuleSetCacheTagsRuleActionParametersSetCacheTagsExpression", + "UnionMember3RuleSetCacheTagsRuleExposedCredentialCheck", + "UnionMember3RuleSetCacheTagsRuleRatelimit", + "UnionMember3RuleSetConfigurationRule", + "UnionMember3RuleSkipRule", + "UnionMember3RuleTransformResponseHTMLRule", + "UnionMember3RuleTransformResponseHTMLRuleActionParameters", + "UnionMember3RuleTransformResponseHTMLRuleExposedCredentialCheck", + "UnionMember3RuleTransformResponseHTMLRuleRatelimit", + "UnionMember4", + "UnionMember4Rule", + "UnionMember4RuleBlockRule", + "UnionMember4RuleChallengeRule", + "UnionMember4RuleChallengeRuleExposedCredentialCheck", + "UnionMember4RuleChallengeRuleRatelimit", + "UnionMember4RuleResponseCompressionRule", + "UnionMember4RuleDDoSDynamicRule", + "UnionMember4RuleExecuteRule", + "UnionMember4RuleForceConnectionCloseRule", + "UnionMember4RuleJavaScriptChallengeRule", + "UnionMember4RuleJavaScriptChallengeRuleExposedCredentialCheck", + "UnionMember4RuleJavaScriptChallengeRuleRatelimit", + "UnionMember4RuleLogRule", + "UnionMember4RuleLogCustomFieldRule", + "UnionMember4RuleManagedChallengeRule", + "UnionMember4RuleRedirectRule", + "UnionMember4RuleRewriteRule", + "UnionMember4RuleRouteRule", + "UnionMember4RuleScoreRule", + "UnionMember4RuleServeErrorRule", + "UnionMember4RuleSetCacheControlRule", + "UnionMember4RuleSetCacheControlRuleActionParameters", + "UnionMember4RuleSetCacheControlRuleActionParametersImmutable", + "UnionMember4RuleSetCacheControlRuleActionParametersImmutableSetDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersImmutableRemoveDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersMaxAge", + "UnionMember4RuleSetCacheControlRuleActionParametersMaxAgeSetDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersMaxAgeRemoveDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersMustRevalidate", + "UnionMember4RuleSetCacheControlRuleActionParametersMustRevalidateSetDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersMustRevalidateRemoveDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersMustUnderstand", + "UnionMember4RuleSetCacheControlRuleActionParametersMustUnderstandSetDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersMustUnderstandRemoveDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersNoCache", + "UnionMember4RuleSetCacheControlRuleActionParametersNoCacheSetDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersNoCacheRemoveDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersNoStore", + "UnionMember4RuleSetCacheControlRuleActionParametersNoStoreSetDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersNoStoreRemoveDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersNoTransform", + "UnionMember4RuleSetCacheControlRuleActionParametersNoTransformSetDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersNoTransformRemoveDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersPrivate", + "UnionMember4RuleSetCacheControlRuleActionParametersPrivateSetDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersPrivateRemoveDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersProxyRevalidate", + "UnionMember4RuleSetCacheControlRuleActionParametersProxyRevalidateSetDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersProxyRevalidateRemoveDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersPublic", + "UnionMember4RuleSetCacheControlRuleActionParametersPublicSetDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersPublicRemoveDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersSMaxage", + "UnionMember4RuleSetCacheControlRuleActionParametersSMaxageSetDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersSMaxageRemoveDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersStaleIfError", + "UnionMember4RuleSetCacheControlRuleActionParametersStaleIfErrorSetDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersStaleIfErrorRemoveDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersStaleWhileRevalidate", + "UnionMember4RuleSetCacheControlRuleActionParametersStaleWhileRevalidateSetDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersStaleWhileRevalidateRemoveDirective", + "UnionMember4RuleSetCacheControlRuleExposedCredentialCheck", + "UnionMember4RuleSetCacheControlRuleRatelimit", + "UnionMember4RuleSetCacheSettingsRule", + "UnionMember4RuleSetCacheTagsRule", + "UnionMember4RuleSetCacheTagsRuleActionParameters", + "UnionMember4RuleSetCacheTagsRuleActionParametersAddCacheTagsValues", + "UnionMember4RuleSetCacheTagsRuleActionParametersAddCacheTagsExpression", + "UnionMember4RuleSetCacheTagsRuleActionParametersRemoveCacheTagsValues", + "UnionMember4RuleSetCacheTagsRuleActionParametersRemoveCacheTagsExpression", + "UnionMember4RuleSetCacheTagsRuleActionParametersSetCacheTagsValues", + "UnionMember4RuleSetCacheTagsRuleActionParametersSetCacheTagsExpression", + "UnionMember4RuleSetCacheTagsRuleExposedCredentialCheck", + "UnionMember4RuleSetCacheTagsRuleRatelimit", + "UnionMember4RuleSetConfigurationRule", + "UnionMember4RuleSkipRule", + "UnionMember4RuleTransformResponseHTMLRule", + "UnionMember4RuleTransformResponseHTMLRuleActionParameters", + "UnionMember4RuleTransformResponseHTMLRuleExposedCredentialCheck", + "UnionMember4RuleTransformResponseHTMLRuleRatelimit", +] + + +class UnionMember0RuleBlockRule(BlockRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember0RuleChallengeRuleExposedCredentialCheck(BaseModel): """Configuration for exposed credential checking.""" password_expression: str @@ -134,7 +459,7 @@ class RuleChallengeRuleExposedCredentialCheck(BaseModel): """An expression that selects the user ID used in the credentials check.""" -class RuleChallengeRuleRatelimit(BaseModel): +class UnionMember0RuleChallengeRuleRatelimit(BaseModel): """An object configuring the rule's rate limit behavior.""" characteristics: List[str] @@ -180,7 +505,7 @@ class RuleChallengeRuleRatelimit(BaseModel): """ -class RuleChallengeRule(BaseModel): +class UnionMember0RuleChallengeRule(BaseModel): id: str """The unique ID of the rule.""" @@ -211,17 +536,17 @@ class RuleChallengeRule(BaseModel): description: Optional[str] = None """An informative description of the rule.""" - exposed_credential_check: Optional[RuleChallengeRuleExposedCredentialCheck] = None + exposed_credential_check: Optional[UnionMember0RuleChallengeRuleExposedCredentialCheck] = None """Configuration for exposed credential checking.""" logging: Optional[Logging] = None """An object configuring the rule's logging behavior.""" - ratelimit: Optional[RuleChallengeRuleRatelimit] = None + ratelimit: Optional[UnionMember0RuleChallengeRuleRatelimit] = None """An object configuring the rule's rate limit behavior.""" -class RuleResponseCompressionRule(CompressResponseRule): +class UnionMember0RuleResponseCompressionRule(CompressResponseRule): id: str # type: ignore action: str # type: ignore @@ -233,7 +558,7 @@ class RuleResponseCompressionRule(CompressResponseRule): ref: str # type: ignore -class RuleDDoSDynamicRule(DDoSDynamicRule): +class UnionMember0RuleDDoSDynamicRule(DDoSDynamicRule): id: str # type: ignore action: str # type: ignore @@ -245,7 +570,7 @@ class RuleDDoSDynamicRule(DDoSDynamicRule): ref: str # type: ignore -class RuleExecuteRule(ExecuteRule): +class UnionMember0RuleExecuteRule(ExecuteRule): id: str # type: ignore action: str # type: ignore @@ -257,7 +582,7 @@ class RuleExecuteRule(ExecuteRule): ref: str # type: ignore -class RuleForceConnectionCloseRule(ForceConnectionCloseRule): +class UnionMember0RuleForceConnectionCloseRule(ForceConnectionCloseRule): id: str # type: ignore action: str # type: ignore @@ -269,7 +594,7 @@ class RuleForceConnectionCloseRule(ForceConnectionCloseRule): ref: str # type: ignore -class RuleJavaScriptChallengeRuleExposedCredentialCheck(BaseModel): +class UnionMember0RuleJavaScriptChallengeRuleExposedCredentialCheck(BaseModel): """Configuration for exposed credential checking.""" password_expression: str @@ -279,7 +604,7 @@ class RuleJavaScriptChallengeRuleExposedCredentialCheck(BaseModel): """An expression that selects the user ID used in the credentials check.""" -class RuleJavaScriptChallengeRuleRatelimit(BaseModel): +class UnionMember0RuleJavaScriptChallengeRuleRatelimit(BaseModel): """An object configuring the rule's rate limit behavior.""" characteristics: List[str] @@ -325,7 +650,7 @@ class RuleJavaScriptChallengeRuleRatelimit(BaseModel): """ -class RuleJavaScriptChallengeRule(BaseModel): +class UnionMember0RuleJavaScriptChallengeRule(BaseModel): id: str """The unique ID of the rule.""" @@ -356,17 +681,17 @@ class RuleJavaScriptChallengeRule(BaseModel): description: Optional[str] = None """An informative description of the rule.""" - exposed_credential_check: Optional[RuleJavaScriptChallengeRuleExposedCredentialCheck] = None + exposed_credential_check: Optional[UnionMember0RuleJavaScriptChallengeRuleExposedCredentialCheck] = None """Configuration for exposed credential checking.""" logging: Optional[Logging] = None """An object configuring the rule's logging behavior.""" - ratelimit: Optional[RuleJavaScriptChallengeRuleRatelimit] = None + ratelimit: Optional[UnionMember0RuleJavaScriptChallengeRuleRatelimit] = None """An object configuring the rule's rate limit behavior.""" -class RuleLogRule(LogRule): +class UnionMember0RuleLogRule(LogRule): id: str # type: ignore action: str # type: ignore @@ -378,7 +703,7 @@ class RuleLogRule(LogRule): ref: str # type: ignore -class RuleLogCustomFieldRule(LogCustomFieldRule): +class UnionMember0RuleLogCustomFieldRule(LogCustomFieldRule): id: str # type: ignore action: str # type: ignore @@ -390,7 +715,7 @@ class RuleLogCustomFieldRule(LogCustomFieldRule): ref: str # type: ignore -class RuleManagedChallengeRule(ManagedChallengeRule): +class UnionMember0RuleManagedChallengeRule(ManagedChallengeRule): id: str # type: ignore action: str # type: ignore @@ -402,7 +727,7 @@ class RuleManagedChallengeRule(ManagedChallengeRule): ref: str # type: ignore -class RuleRedirectRule(RedirectRule): +class UnionMember0RuleRedirectRule(RedirectRule): id: str # type: ignore action: str # type: ignore @@ -414,7 +739,7 @@ class RuleRedirectRule(RedirectRule): ref: str # type: ignore -class RuleRewriteRule(RewriteRule): +class UnionMember0RuleRewriteRule(RewriteRule): id: str # type: ignore action: str # type: ignore @@ -426,7 +751,7 @@ class RuleRewriteRule(RewriteRule): ref: str # type: ignore -class RuleRouteRule(RouteRule): +class UnionMember0RuleRouteRule(RouteRule): id: str # type: ignore action: str # type: ignore @@ -438,7 +763,7 @@ class RuleRouteRule(RouteRule): ref: str # type: ignore -class RuleScoreRule(ScoreRule): +class UnionMember0RuleScoreRule(ScoreRule): id: str # type: ignore action: str # type: ignore @@ -450,7 +775,7 @@ class RuleScoreRule(ScoreRule): ref: str # type: ignore -class RuleServeErrorRule(ServeErrorRule): +class UnionMember0RuleServeErrorRule(ServeErrorRule): id: str # type: ignore action: str # type: ignore @@ -462,7 +787,7 @@ class RuleServeErrorRule(ServeErrorRule): ref: str # type: ignore -class RuleSetCacheControlRuleActionParametersImmutableSetDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersImmutableSetDirective(BaseModel): """Set the directive.""" operation: Literal["set", "remove"] @@ -472,7 +797,7 @@ class RuleSetCacheControlRuleActionParametersImmutableSetDirective(BaseModel): """Whether the directive should only be applied to the Cloudflare CDN cache.""" -class RuleSetCacheControlRuleActionParametersImmutableRemoveDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersImmutableRemoveDirective(BaseModel): """Remove the directive.""" operation: Literal["set", "remove"] @@ -482,13 +807,13 @@ class RuleSetCacheControlRuleActionParametersImmutableRemoveDirective(BaseModel) """Whether the directive should only be applied to the Cloudflare CDN cache.""" -RuleSetCacheControlRuleActionParametersImmutable: TypeAlias = Union[ - RuleSetCacheControlRuleActionParametersImmutableSetDirective, - RuleSetCacheControlRuleActionParametersImmutableRemoveDirective, +UnionMember0RuleSetCacheControlRuleActionParametersImmutable: TypeAlias = Union[ + UnionMember0RuleSetCacheControlRuleActionParametersImmutableSetDirective, + UnionMember0RuleSetCacheControlRuleActionParametersImmutableRemoveDirective, ] -class RuleSetCacheControlRuleActionParametersMaxAgeSetDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersMaxAgeSetDirective(BaseModel): """Set the directive with a duration value in seconds.""" operation: Literal["set", "remove"] @@ -501,7 +826,7 @@ class RuleSetCacheControlRuleActionParametersMaxAgeSetDirective(BaseModel): """Whether the directive should only be applied to the Cloudflare CDN cache.""" -class RuleSetCacheControlRuleActionParametersMaxAgeRemoveDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersMaxAgeRemoveDirective(BaseModel): """Remove the directive.""" operation: Literal["set", "remove"] @@ -511,13 +836,13 @@ class RuleSetCacheControlRuleActionParametersMaxAgeRemoveDirective(BaseModel): """Whether the directive should only be applied to the Cloudflare CDN cache.""" -RuleSetCacheControlRuleActionParametersMaxAge: TypeAlias = Union[ - RuleSetCacheControlRuleActionParametersMaxAgeSetDirective, - RuleSetCacheControlRuleActionParametersMaxAgeRemoveDirective, +UnionMember0RuleSetCacheControlRuleActionParametersMaxAge: TypeAlias = Union[ + UnionMember0RuleSetCacheControlRuleActionParametersMaxAgeSetDirective, + UnionMember0RuleSetCacheControlRuleActionParametersMaxAgeRemoveDirective, ] -class RuleSetCacheControlRuleActionParametersMustRevalidateSetDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersMustRevalidateSetDirective(BaseModel): """Set the directive.""" operation: Literal["set", "remove"] @@ -527,7 +852,7 @@ class RuleSetCacheControlRuleActionParametersMustRevalidateSetDirective(BaseMode """Whether the directive should only be applied to the Cloudflare CDN cache.""" -class RuleSetCacheControlRuleActionParametersMustRevalidateRemoveDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersMustRevalidateRemoveDirective(BaseModel): """Remove the directive.""" operation: Literal["set", "remove"] @@ -537,13 +862,13 @@ class RuleSetCacheControlRuleActionParametersMustRevalidateRemoveDirective(BaseM """Whether the directive should only be applied to the Cloudflare CDN cache.""" -RuleSetCacheControlRuleActionParametersMustRevalidate: TypeAlias = Union[ - RuleSetCacheControlRuleActionParametersMustRevalidateSetDirective, - RuleSetCacheControlRuleActionParametersMustRevalidateRemoveDirective, +UnionMember0RuleSetCacheControlRuleActionParametersMustRevalidate: TypeAlias = Union[ + UnionMember0RuleSetCacheControlRuleActionParametersMustRevalidateSetDirective, + UnionMember0RuleSetCacheControlRuleActionParametersMustRevalidateRemoveDirective, ] -class RuleSetCacheControlRuleActionParametersMustUnderstandSetDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersMustUnderstandSetDirective(BaseModel): """Set the directive.""" operation: Literal["set", "remove"] @@ -553,7 +878,7 @@ class RuleSetCacheControlRuleActionParametersMustUnderstandSetDirective(BaseMode """Whether the directive should only be applied to the Cloudflare CDN cache.""" -class RuleSetCacheControlRuleActionParametersMustUnderstandRemoveDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersMustUnderstandRemoveDirective(BaseModel): """Remove the directive.""" operation: Literal["set", "remove"] @@ -563,13 +888,13 @@ class RuleSetCacheControlRuleActionParametersMustUnderstandRemoveDirective(BaseM """Whether the directive should only be applied to the Cloudflare CDN cache.""" -RuleSetCacheControlRuleActionParametersMustUnderstand: TypeAlias = Union[ - RuleSetCacheControlRuleActionParametersMustUnderstandSetDirective, - RuleSetCacheControlRuleActionParametersMustUnderstandRemoveDirective, +UnionMember0RuleSetCacheControlRuleActionParametersMustUnderstand: TypeAlias = Union[ + UnionMember0RuleSetCacheControlRuleActionParametersMustUnderstandSetDirective, + UnionMember0RuleSetCacheControlRuleActionParametersMustUnderstandRemoveDirective, ] -class RuleSetCacheControlRuleActionParametersNoCacheSetDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersNoCacheSetDirective(BaseModel): """Set the directive with optional qualifiers.""" operation: Literal["set", "remove"] @@ -585,7 +910,7 @@ class RuleSetCacheControlRuleActionParametersNoCacheSetDirective(BaseModel): """ -class RuleSetCacheControlRuleActionParametersNoCacheRemoveDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersNoCacheRemoveDirective(BaseModel): """Remove the directive.""" operation: Literal["set", "remove"] @@ -595,13 +920,13 @@ class RuleSetCacheControlRuleActionParametersNoCacheRemoveDirective(BaseModel): """Whether the directive should only be applied to the Cloudflare CDN cache.""" -RuleSetCacheControlRuleActionParametersNoCache: TypeAlias = Union[ - RuleSetCacheControlRuleActionParametersNoCacheSetDirective, - RuleSetCacheControlRuleActionParametersNoCacheRemoveDirective, +UnionMember0RuleSetCacheControlRuleActionParametersNoCache: TypeAlias = Union[ + UnionMember0RuleSetCacheControlRuleActionParametersNoCacheSetDirective, + UnionMember0RuleSetCacheControlRuleActionParametersNoCacheRemoveDirective, ] -class RuleSetCacheControlRuleActionParametersNoStoreSetDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersNoStoreSetDirective(BaseModel): """Set the directive.""" operation: Literal["set", "remove"] @@ -611,7 +936,7 @@ class RuleSetCacheControlRuleActionParametersNoStoreSetDirective(BaseModel): """Whether the directive should only be applied to the Cloudflare CDN cache.""" -class RuleSetCacheControlRuleActionParametersNoStoreRemoveDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersNoStoreRemoveDirective(BaseModel): """Remove the directive.""" operation: Literal["set", "remove"] @@ -621,13 +946,13 @@ class RuleSetCacheControlRuleActionParametersNoStoreRemoveDirective(BaseModel): """Whether the directive should only be applied to the Cloudflare CDN cache.""" -RuleSetCacheControlRuleActionParametersNoStore: TypeAlias = Union[ - RuleSetCacheControlRuleActionParametersNoStoreSetDirective, - RuleSetCacheControlRuleActionParametersNoStoreRemoveDirective, +UnionMember0RuleSetCacheControlRuleActionParametersNoStore: TypeAlias = Union[ + UnionMember0RuleSetCacheControlRuleActionParametersNoStoreSetDirective, + UnionMember0RuleSetCacheControlRuleActionParametersNoStoreRemoveDirective, ] -class RuleSetCacheControlRuleActionParametersNoTransformSetDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersNoTransformSetDirective(BaseModel): """Set the directive.""" operation: Literal["set", "remove"] @@ -637,7 +962,7 @@ class RuleSetCacheControlRuleActionParametersNoTransformSetDirective(BaseModel): """Whether the directive should only be applied to the Cloudflare CDN cache.""" -class RuleSetCacheControlRuleActionParametersNoTransformRemoveDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersNoTransformRemoveDirective(BaseModel): """Remove the directive.""" operation: Literal["set", "remove"] @@ -647,13 +972,13 @@ class RuleSetCacheControlRuleActionParametersNoTransformRemoveDirective(BaseMode """Whether the directive should only be applied to the Cloudflare CDN cache.""" -RuleSetCacheControlRuleActionParametersNoTransform: TypeAlias = Union[ - RuleSetCacheControlRuleActionParametersNoTransformSetDirective, - RuleSetCacheControlRuleActionParametersNoTransformRemoveDirective, +UnionMember0RuleSetCacheControlRuleActionParametersNoTransform: TypeAlias = Union[ + UnionMember0RuleSetCacheControlRuleActionParametersNoTransformSetDirective, + UnionMember0RuleSetCacheControlRuleActionParametersNoTransformRemoveDirective, ] -class RuleSetCacheControlRuleActionParametersPrivateSetDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersPrivateSetDirective(BaseModel): """Set the directive with optional qualifiers.""" operation: Literal["set", "remove"] @@ -669,7 +994,7 @@ class RuleSetCacheControlRuleActionParametersPrivateSetDirective(BaseModel): """ -class RuleSetCacheControlRuleActionParametersPrivateRemoveDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersPrivateRemoveDirective(BaseModel): """Remove the directive.""" operation: Literal["set", "remove"] @@ -679,13 +1004,13 @@ class RuleSetCacheControlRuleActionParametersPrivateRemoveDirective(BaseModel): """Whether the directive should only be applied to the Cloudflare CDN cache.""" -RuleSetCacheControlRuleActionParametersPrivate: TypeAlias = Union[ - RuleSetCacheControlRuleActionParametersPrivateSetDirective, - RuleSetCacheControlRuleActionParametersPrivateRemoveDirective, +UnionMember0RuleSetCacheControlRuleActionParametersPrivate: TypeAlias = Union[ + UnionMember0RuleSetCacheControlRuleActionParametersPrivateSetDirective, + UnionMember0RuleSetCacheControlRuleActionParametersPrivateRemoveDirective, ] -class RuleSetCacheControlRuleActionParametersProxyRevalidateSetDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersProxyRevalidateSetDirective(BaseModel): """Set the directive.""" operation: Literal["set", "remove"] @@ -695,7 +1020,7 @@ class RuleSetCacheControlRuleActionParametersProxyRevalidateSetDirective(BaseMod """Whether the directive should only be applied to the Cloudflare CDN cache.""" -class RuleSetCacheControlRuleActionParametersProxyRevalidateRemoveDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersProxyRevalidateRemoveDirective(BaseModel): """Remove the directive.""" operation: Literal["set", "remove"] @@ -705,13 +1030,13 @@ class RuleSetCacheControlRuleActionParametersProxyRevalidateRemoveDirective(Base """Whether the directive should only be applied to the Cloudflare CDN cache.""" -RuleSetCacheControlRuleActionParametersProxyRevalidate: TypeAlias = Union[ - RuleSetCacheControlRuleActionParametersProxyRevalidateSetDirective, - RuleSetCacheControlRuleActionParametersProxyRevalidateRemoveDirective, +UnionMember0RuleSetCacheControlRuleActionParametersProxyRevalidate: TypeAlias = Union[ + UnionMember0RuleSetCacheControlRuleActionParametersProxyRevalidateSetDirective, + UnionMember0RuleSetCacheControlRuleActionParametersProxyRevalidateRemoveDirective, ] -class RuleSetCacheControlRuleActionParametersPublicSetDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersPublicSetDirective(BaseModel): """Set the directive.""" operation: Literal["set", "remove"] @@ -721,7 +1046,7 @@ class RuleSetCacheControlRuleActionParametersPublicSetDirective(BaseModel): """Whether the directive should only be applied to the Cloudflare CDN cache.""" -class RuleSetCacheControlRuleActionParametersPublicRemoveDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersPublicRemoveDirective(BaseModel): """Remove the directive.""" operation: Literal["set", "remove"] @@ -731,13 +1056,13 @@ class RuleSetCacheControlRuleActionParametersPublicRemoveDirective(BaseModel): """Whether the directive should only be applied to the Cloudflare CDN cache.""" -RuleSetCacheControlRuleActionParametersPublic: TypeAlias = Union[ - RuleSetCacheControlRuleActionParametersPublicSetDirective, - RuleSetCacheControlRuleActionParametersPublicRemoveDirective, +UnionMember0RuleSetCacheControlRuleActionParametersPublic: TypeAlias = Union[ + UnionMember0RuleSetCacheControlRuleActionParametersPublicSetDirective, + UnionMember0RuleSetCacheControlRuleActionParametersPublicRemoveDirective, ] -class RuleSetCacheControlRuleActionParametersSMaxageSetDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersSMaxageSetDirective(BaseModel): """Set the directive with a duration value in seconds.""" operation: Literal["set", "remove"] @@ -750,7 +1075,7 @@ class RuleSetCacheControlRuleActionParametersSMaxageSetDirective(BaseModel): """Whether the directive should only be applied to the Cloudflare CDN cache.""" -class RuleSetCacheControlRuleActionParametersSMaxageRemoveDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersSMaxageRemoveDirective(BaseModel): """Remove the directive.""" operation: Literal["set", "remove"] @@ -760,13 +1085,13 @@ class RuleSetCacheControlRuleActionParametersSMaxageRemoveDirective(BaseModel): """Whether the directive should only be applied to the Cloudflare CDN cache.""" -RuleSetCacheControlRuleActionParametersSMaxage: TypeAlias = Union[ - RuleSetCacheControlRuleActionParametersSMaxageSetDirective, - RuleSetCacheControlRuleActionParametersSMaxageRemoveDirective, +UnionMember0RuleSetCacheControlRuleActionParametersSMaxage: TypeAlias = Union[ + UnionMember0RuleSetCacheControlRuleActionParametersSMaxageSetDirective, + UnionMember0RuleSetCacheControlRuleActionParametersSMaxageRemoveDirective, ] -class RuleSetCacheControlRuleActionParametersStaleIfErrorSetDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersStaleIfErrorSetDirective(BaseModel): """Set the directive with a duration value in seconds.""" operation: Literal["set", "remove"] @@ -779,7 +1104,7 @@ class RuleSetCacheControlRuleActionParametersStaleIfErrorSetDirective(BaseModel) """Whether the directive should only be applied to the Cloudflare CDN cache.""" -class RuleSetCacheControlRuleActionParametersStaleIfErrorRemoveDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersStaleIfErrorRemoveDirective(BaseModel): """Remove the directive.""" operation: Literal["set", "remove"] @@ -789,13 +1114,13 @@ class RuleSetCacheControlRuleActionParametersStaleIfErrorRemoveDirective(BaseMod """Whether the directive should only be applied to the Cloudflare CDN cache.""" -RuleSetCacheControlRuleActionParametersStaleIfError: TypeAlias = Union[ - RuleSetCacheControlRuleActionParametersStaleIfErrorSetDirective, - RuleSetCacheControlRuleActionParametersStaleIfErrorRemoveDirective, +UnionMember0RuleSetCacheControlRuleActionParametersStaleIfError: TypeAlias = Union[ + UnionMember0RuleSetCacheControlRuleActionParametersStaleIfErrorSetDirective, + UnionMember0RuleSetCacheControlRuleActionParametersStaleIfErrorRemoveDirective, ] -class RuleSetCacheControlRuleActionParametersStaleWhileRevalidateSetDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersStaleWhileRevalidateSetDirective(BaseModel): """Set the directive with a duration value in seconds.""" operation: Literal["set", "remove"] @@ -808,7 +1133,7 @@ class RuleSetCacheControlRuleActionParametersStaleWhileRevalidateSetDirective(Ba """Whether the directive should only be applied to the Cloudflare CDN cache.""" -class RuleSetCacheControlRuleActionParametersStaleWhileRevalidateRemoveDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersStaleWhileRevalidateRemoveDirective(BaseModel): """Remove the directive.""" operation: Literal["set", "remove"] @@ -818,69 +1143,77 @@ class RuleSetCacheControlRuleActionParametersStaleWhileRevalidateRemoveDirective """Whether the directive should only be applied to the Cloudflare CDN cache.""" -RuleSetCacheControlRuleActionParametersStaleWhileRevalidate: TypeAlias = Union[ - RuleSetCacheControlRuleActionParametersStaleWhileRevalidateSetDirective, - RuleSetCacheControlRuleActionParametersStaleWhileRevalidateRemoveDirective, +UnionMember0RuleSetCacheControlRuleActionParametersStaleWhileRevalidate: TypeAlias = Union[ + UnionMember0RuleSetCacheControlRuleActionParametersStaleWhileRevalidateSetDirective, + UnionMember0RuleSetCacheControlRuleActionParametersStaleWhileRevalidateRemoveDirective, ] -class RuleSetCacheControlRuleActionParameters(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParameters(BaseModel): """The parameters configuring the rule's action.""" - immutable: Optional[RuleSetCacheControlRuleActionParametersImmutable] = None + immutable: Optional[UnionMember0RuleSetCacheControlRuleActionParametersImmutable] = None """A cache-control directive configuration.""" - max_age: Optional[RuleSetCacheControlRuleActionParametersMaxAge] = FieldInfo(alias="max-age", default=None) + max_age: Optional[UnionMember0RuleSetCacheControlRuleActionParametersMaxAge] = FieldInfo( + alias="max-age", default=None + ) """ A cache-control directive configuration that accepts a duration value in seconds. """ - must_revalidate: Optional[RuleSetCacheControlRuleActionParametersMustRevalidate] = FieldInfo( + must_revalidate: Optional[UnionMember0RuleSetCacheControlRuleActionParametersMustRevalidate] = FieldInfo( alias="must-revalidate", default=None ) """A cache-control directive configuration.""" - must_understand: Optional[RuleSetCacheControlRuleActionParametersMustUnderstand] = FieldInfo( + must_understand: Optional[UnionMember0RuleSetCacheControlRuleActionParametersMustUnderstand] = FieldInfo( alias="must-understand", default=None ) """A cache-control directive configuration.""" - no_cache: Optional[RuleSetCacheControlRuleActionParametersNoCache] = FieldInfo(alias="no-cache", default=None) + no_cache: Optional[UnionMember0RuleSetCacheControlRuleActionParametersNoCache] = FieldInfo( + alias="no-cache", default=None + ) """ A cache-control directive configuration that accepts optional qualifiers (header names). """ - no_store: Optional[RuleSetCacheControlRuleActionParametersNoStore] = FieldInfo(alias="no-store", default=None) + no_store: Optional[UnionMember0RuleSetCacheControlRuleActionParametersNoStore] = FieldInfo( + alias="no-store", default=None + ) """A cache-control directive configuration.""" - no_transform: Optional[RuleSetCacheControlRuleActionParametersNoTransform] = FieldInfo( + no_transform: Optional[UnionMember0RuleSetCacheControlRuleActionParametersNoTransform] = FieldInfo( alias="no-transform", default=None ) """A cache-control directive configuration.""" - private: Optional[RuleSetCacheControlRuleActionParametersPrivate] = None + private: Optional[UnionMember0RuleSetCacheControlRuleActionParametersPrivate] = None """ A cache-control directive configuration that accepts optional qualifiers (header names). """ - proxy_revalidate: Optional[RuleSetCacheControlRuleActionParametersProxyRevalidate] = FieldInfo( + proxy_revalidate: Optional[UnionMember0RuleSetCacheControlRuleActionParametersProxyRevalidate] = FieldInfo( alias="proxy-revalidate", default=None ) """A cache-control directive configuration.""" - public: Optional[RuleSetCacheControlRuleActionParametersPublic] = None + public: Optional[UnionMember0RuleSetCacheControlRuleActionParametersPublic] = None """A cache-control directive configuration.""" - s_maxage: Optional[RuleSetCacheControlRuleActionParametersSMaxage] = FieldInfo(alias="s-maxage", default=None) + s_maxage: Optional[UnionMember0RuleSetCacheControlRuleActionParametersSMaxage] = FieldInfo( + alias="s-maxage", default=None + ) """ A cache-control directive configuration that accepts a duration value in seconds. """ - stale_if_error: Optional[RuleSetCacheControlRuleActionParametersStaleIfError] = FieldInfo( + stale_if_error: Optional[UnionMember0RuleSetCacheControlRuleActionParametersStaleIfError] = FieldInfo( alias="stale-if-error", default=None ) """ @@ -888,8 +1221,8 @@ class RuleSetCacheControlRuleActionParameters(BaseModel): seconds. """ - stale_while_revalidate: Optional[RuleSetCacheControlRuleActionParametersStaleWhileRevalidate] = FieldInfo( - alias="stale-while-revalidate", default=None + stale_while_revalidate: Optional[UnionMember0RuleSetCacheControlRuleActionParametersStaleWhileRevalidate] = ( + FieldInfo(alias="stale-while-revalidate", default=None) ) """ A cache-control directive configuration that accepts a duration value in @@ -897,7 +1230,7 @@ class RuleSetCacheControlRuleActionParameters(BaseModel): """ -class RuleSetCacheControlRuleExposedCredentialCheck(BaseModel): +class UnionMember0RuleSetCacheControlRuleExposedCredentialCheck(BaseModel): """Configuration for exposed credential checking.""" password_expression: str @@ -907,7 +1240,7 @@ class RuleSetCacheControlRuleExposedCredentialCheck(BaseModel): """An expression that selects the user ID used in the credentials check.""" -class RuleSetCacheControlRuleRatelimit(BaseModel): +class UnionMember0RuleSetCacheControlRuleRatelimit(BaseModel): """An object configuring the rule's rate limit behavior.""" characteristics: List[str] @@ -953,7 +1286,7 @@ class RuleSetCacheControlRuleRatelimit(BaseModel): """ -class RuleSetCacheControlRule(BaseModel): +class UnionMember0RuleSetCacheControlRule(BaseModel): id: str """The unique ID of the rule.""" @@ -974,7 +1307,7 @@ class RuleSetCacheControlRule(BaseModel): version: str """The version of the rule.""" - action_parameters: Optional[RuleSetCacheControlRuleActionParameters] = None + action_parameters: Optional[UnionMember0RuleSetCacheControlRuleActionParameters] = None """The parameters configuring the rule's action.""" categories: Optional[List[str]] = None @@ -983,17 +1316,17 @@ class RuleSetCacheControlRule(BaseModel): description: Optional[str] = None """An informative description of the rule.""" - exposed_credential_check: Optional[RuleSetCacheControlRuleExposedCredentialCheck] = None + exposed_credential_check: Optional[UnionMember0RuleSetCacheControlRuleExposedCredentialCheck] = None """Configuration for exposed credential checking.""" logging: Optional[Logging] = None """An object configuring the rule's logging behavior.""" - ratelimit: Optional[RuleSetCacheControlRuleRatelimit] = None + ratelimit: Optional[UnionMember0RuleSetCacheControlRuleRatelimit] = None """An object configuring the rule's rate limit behavior.""" -class RuleSetCacheSettingsRule(SetCacheSettingsRule): +class UnionMember0RuleSetCacheSettingsRule(SetCacheSettingsRule): id: str # type: ignore action: str # type: ignore @@ -1005,7 +1338,7 @@ class RuleSetCacheSettingsRule(SetCacheSettingsRule): ref: str # type: ignore -class RuleSetCacheTagsRuleActionParametersAddCacheTagsValues(BaseModel): +class UnionMember0RuleSetCacheTagsRuleActionParametersAddCacheTagsValues(BaseModel): """Add cache tags using a list of values.""" operation: Literal["add", "remove", "set"] @@ -1015,7 +1348,7 @@ class RuleSetCacheTagsRuleActionParametersAddCacheTagsValues(BaseModel): """A list of cache tag values.""" -class RuleSetCacheTagsRuleActionParametersAddCacheTagsExpression(BaseModel): +class UnionMember0RuleSetCacheTagsRuleActionParametersAddCacheTagsExpression(BaseModel): """Add cache tags using an expression.""" expression: str @@ -1025,7 +1358,7 @@ class RuleSetCacheTagsRuleActionParametersAddCacheTagsExpression(BaseModel): """The operation to perform on the cache tags.""" -class RuleSetCacheTagsRuleActionParametersRemoveCacheTagsValues(BaseModel): +class UnionMember0RuleSetCacheTagsRuleActionParametersRemoveCacheTagsValues(BaseModel): """Remove cache tags using a list of values.""" operation: Literal["add", "remove", "set"] @@ -1035,7 +1368,7 @@ class RuleSetCacheTagsRuleActionParametersRemoveCacheTagsValues(BaseModel): """A list of cache tag values.""" -class RuleSetCacheTagsRuleActionParametersRemoveCacheTagsExpression(BaseModel): +class UnionMember0RuleSetCacheTagsRuleActionParametersRemoveCacheTagsExpression(BaseModel): """Remove cache tags using an expression.""" expression: str @@ -1045,7 +1378,7 @@ class RuleSetCacheTagsRuleActionParametersRemoveCacheTagsExpression(BaseModel): """The operation to perform on the cache tags.""" -class RuleSetCacheTagsRuleActionParametersSetCacheTagsValues(BaseModel): +class UnionMember0RuleSetCacheTagsRuleActionParametersSetCacheTagsValues(BaseModel): """Set cache tags using a list of values.""" operation: Literal["add", "remove", "set"] @@ -1055,7 +1388,7 @@ class RuleSetCacheTagsRuleActionParametersSetCacheTagsValues(BaseModel): """A list of cache tag values.""" -class RuleSetCacheTagsRuleActionParametersSetCacheTagsExpression(BaseModel): +class UnionMember0RuleSetCacheTagsRuleActionParametersSetCacheTagsExpression(BaseModel): """Set cache tags using an expression.""" expression: str @@ -1065,17 +1398,17 @@ class RuleSetCacheTagsRuleActionParametersSetCacheTagsExpression(BaseModel): """The operation to perform on the cache tags.""" -RuleSetCacheTagsRuleActionParameters: TypeAlias = Union[ - RuleSetCacheTagsRuleActionParametersAddCacheTagsValues, - RuleSetCacheTagsRuleActionParametersAddCacheTagsExpression, - RuleSetCacheTagsRuleActionParametersRemoveCacheTagsValues, - RuleSetCacheTagsRuleActionParametersRemoveCacheTagsExpression, - RuleSetCacheTagsRuleActionParametersSetCacheTagsValues, - RuleSetCacheTagsRuleActionParametersSetCacheTagsExpression, +UnionMember0RuleSetCacheTagsRuleActionParameters: TypeAlias = Union[ + UnionMember0RuleSetCacheTagsRuleActionParametersAddCacheTagsValues, + UnionMember0RuleSetCacheTagsRuleActionParametersAddCacheTagsExpression, + UnionMember0RuleSetCacheTagsRuleActionParametersRemoveCacheTagsValues, + UnionMember0RuleSetCacheTagsRuleActionParametersRemoveCacheTagsExpression, + UnionMember0RuleSetCacheTagsRuleActionParametersSetCacheTagsValues, + UnionMember0RuleSetCacheTagsRuleActionParametersSetCacheTagsExpression, ] -class RuleSetCacheTagsRuleExposedCredentialCheck(BaseModel): +class UnionMember0RuleSetCacheTagsRuleExposedCredentialCheck(BaseModel): """Configuration for exposed credential checking.""" password_expression: str @@ -1085,7 +1418,7 @@ class RuleSetCacheTagsRuleExposedCredentialCheck(BaseModel): """An expression that selects the user ID used in the credentials check.""" -class RuleSetCacheTagsRuleRatelimit(BaseModel): +class UnionMember0RuleSetCacheTagsRuleRatelimit(BaseModel): """An object configuring the rule's rate limit behavior.""" characteristics: List[str] @@ -1131,7 +1464,7 @@ class RuleSetCacheTagsRuleRatelimit(BaseModel): """ -class RuleSetCacheTagsRule(BaseModel): +class UnionMember0RuleSetCacheTagsRule(BaseModel): id: str """The unique ID of the rule.""" @@ -1152,7 +1485,7 @@ class RuleSetCacheTagsRule(BaseModel): version: str """The version of the rule.""" - action_parameters: Optional[RuleSetCacheTagsRuleActionParameters] = None + action_parameters: Optional[UnionMember0RuleSetCacheTagsRuleActionParameters] = None """The parameters configuring the rule's action.""" categories: Optional[List[str]] = None @@ -1161,17 +1494,17 @@ class RuleSetCacheTagsRule(BaseModel): description: Optional[str] = None """An informative description of the rule.""" - exposed_credential_check: Optional[RuleSetCacheTagsRuleExposedCredentialCheck] = None + exposed_credential_check: Optional[UnionMember0RuleSetCacheTagsRuleExposedCredentialCheck] = None """Configuration for exposed credential checking.""" logging: Optional[Logging] = None """An object configuring the rule's logging behavior.""" - ratelimit: Optional[RuleSetCacheTagsRuleRatelimit] = None + ratelimit: Optional[UnionMember0RuleSetCacheTagsRuleRatelimit] = None """An object configuring the rule's rate limit behavior.""" -class RuleSetConfigurationRule(SetConfigRule): +class UnionMember0RuleSetConfigurationRule(SetConfigRule): id: str # type: ignore action: str # type: ignore @@ -1183,7 +1516,7 @@ class RuleSetConfigurationRule(SetConfigRule): ref: str # type: ignore -class RuleSkipRule(SkipRule): +class UnionMember0RuleSkipRule(SkipRule): id: str # type: ignore action: str # type: ignore @@ -1195,14 +1528,14 @@ class RuleSkipRule(SkipRule): ref: str # type: ignore -class RuleTransformResponseHTMLRuleActionParameters(BaseModel): +class UnionMember0RuleTransformResponseHTMLRuleActionParameters(BaseModel): """The parameters configuring the rule's action.""" link_maze: object """Enables the link maze transformation on the response.""" -class RuleTransformResponseHTMLRuleExposedCredentialCheck(BaseModel): +class UnionMember0RuleTransformResponseHTMLRuleExposedCredentialCheck(BaseModel): """Configuration for exposed credential checking.""" password_expression: str @@ -1212,7 +1545,7 @@ class RuleTransformResponseHTMLRuleExposedCredentialCheck(BaseModel): """An expression that selects the user ID used in the credentials check.""" -class RuleTransformResponseHTMLRuleRatelimit(BaseModel): +class UnionMember0RuleTransformResponseHTMLRuleRatelimit(BaseModel): """An object configuring the rule's rate limit behavior.""" characteristics: List[str] @@ -1258,7 +1591,7 @@ class RuleTransformResponseHTMLRuleRatelimit(BaseModel): """ -class RuleTransformResponseHTMLRule(BaseModel): +class UnionMember0RuleTransformResponseHTMLRule(BaseModel): id: str """The unique ID of the rule.""" @@ -1279,7 +1612,7 @@ class RuleTransformResponseHTMLRule(BaseModel): version: str """The version of the rule.""" - action_parameters: Optional[RuleTransformResponseHTMLRuleActionParameters] = None + action_parameters: Optional[UnionMember0RuleTransformResponseHTMLRuleActionParameters] = None """The parameters configuring the rule's action.""" categories: Optional[List[str]] = None @@ -1288,64 +1621,5045 @@ class RuleTransformResponseHTMLRule(BaseModel): description: Optional[str] = None """An informative description of the rule.""" - exposed_credential_check: Optional[RuleTransformResponseHTMLRuleExposedCredentialCheck] = None + exposed_credential_check: Optional[UnionMember0RuleTransformResponseHTMLRuleExposedCredentialCheck] = None """Configuration for exposed credential checking.""" logging: Optional[Logging] = None """An object configuring the rule's logging behavior.""" - ratelimit: Optional[RuleTransformResponseHTMLRuleRatelimit] = None + ratelimit: Optional[UnionMember0RuleTransformResponseHTMLRuleRatelimit] = None """An object configuring the rule's rate limit behavior.""" -Rule: TypeAlias = Union[ - RuleBlockRule, - RuleChallengeRule, - RuleResponseCompressionRule, - RuleDDoSDynamicRule, - RuleExecuteRule, - RuleForceConnectionCloseRule, - RuleJavaScriptChallengeRule, - RuleLogRule, - RuleLogCustomFieldRule, - RuleManagedChallengeRule, - RuleRedirectRule, - RuleRewriteRule, - RuleRouteRule, - RuleScoreRule, - RuleServeErrorRule, - RuleSetCacheControlRule, - RuleSetCacheSettingsRule, - RuleSetCacheTagsRule, - RuleSetConfigurationRule, - RuleSkipRule, - RuleTransformResponseHTMLRule, -] - - -class PhaseGetResponse(BaseModel): - """A ruleset object.""" +UnionMember0Rule: TypeAlias = Union[ + UnionMember0RuleBlockRule, + UnionMember0RuleChallengeRule, + UnionMember0RuleResponseCompressionRule, + UnionMember0RuleDDoSDynamicRule, + UnionMember0RuleExecuteRule, + UnionMember0RuleForceConnectionCloseRule, + UnionMember0RuleJavaScriptChallengeRule, + UnionMember0RuleLogRule, + UnionMember0RuleLogCustomFieldRule, + UnionMember0RuleManagedChallengeRule, + UnionMember0RuleRedirectRule, + UnionMember0RuleRewriteRule, + UnionMember0RuleRouteRule, + UnionMember0RuleScoreRule, + UnionMember0RuleServeErrorRule, + UnionMember0RuleSetCacheControlRule, + UnionMember0RuleSetCacheSettingsRule, + UnionMember0RuleSetCacheTagsRule, + UnionMember0RuleSetConfigurationRule, + UnionMember0RuleSkipRule, + UnionMember0RuleTransformResponseHTMLRule, +] - id: str + +class UnionMember0(BaseModel): + id: Optional[str] = None """The unique ID of the ruleset.""" - kind: Kind + description: Optional[str] = None + """An informative description of the ruleset.""" + + kind: Optional[Kind] = None """The kind of the ruleset.""" - last_updated: datetime + last_updated: Optional[datetime] = None """The timestamp of when the ruleset was last modified.""" - name: str + name: Optional[str] = None """The human-readable name of the ruleset.""" - phase: Phase + phase: Optional[Phase] = None """The phase of the ruleset.""" - rules: List[Rule] + rules: Optional[List[UnionMember0Rule]] = None """The list of rules in the ruleset.""" - version: str + version: Optional[str] = None """The version of the ruleset.""" + +class UnionMember1RuleBlockRule(BlockRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember1RuleChallengeRuleExposedCredentialCheck(BaseModel): + """Configuration for exposed credential checking.""" + + password_expression: str + """An expression that selects the password used in the credentials check.""" + + username_expression: str + """An expression that selects the user ID used in the credentials check.""" + + +class UnionMember1RuleChallengeRuleRatelimit(BaseModel): + """An object configuring the rule's rate limit behavior.""" + + characteristics: List[str] + """ + Characteristics of the request on which the rate limit counter will be + incremented. + """ + + period: int + """Period in seconds over which the counter is being incremented.""" + + counting_expression: Optional[str] = None + """An expression that defines when the rate limit counter should be incremented. + + It defaults to the same as the rule's expression. + """ + + mitigation_timeout: Optional[int] = None + """ + Period of time in seconds after which the action will be disabled following its + first execution. + """ + + requests_per_period: Optional[int] = None + """ + The threshold of requests per period after which the action will be executed for + the first time. + """ + + requests_to_origin: Optional[bool] = None + """Whether counting is only performed when an origin is reached.""" + + score_per_period: Optional[int] = None + """ + The score threshold per period for which the action will be executed the first + time. + """ + + score_response_header_name: Optional[str] = None + """ + A response header name provided by the origin, which contains the score to + increment rate limit counter with. + """ + + +class UnionMember1RuleChallengeRule(BaseModel): + id: str + """The unique ID of the rule.""" + + action: Literal["challenge"] + """The action to perform when the rule matches.""" + + enabled: bool + """Whether the rule should be executed.""" + + expression: str + """The expression defining which traffic will match the rule.""" + + last_updated: datetime + """The timestamp of when the rule was last modified.""" + + ref: str + """The reference of the rule (the rule's ID by default).""" + + version: str + """The version of the rule.""" + + action_parameters: Optional[object] = None + """The parameters configuring the rule's action.""" + + categories: Optional[List[str]] = None + """The categories of the rule.""" + description: Optional[str] = None - """An informative description of the ruleset.""" + """An informative description of the rule.""" + + exposed_credential_check: Optional[UnionMember1RuleChallengeRuleExposedCredentialCheck] = None + """Configuration for exposed credential checking.""" + + logging: Optional[Logging] = None + """An object configuring the rule's logging behavior.""" + + ratelimit: Optional[UnionMember1RuleChallengeRuleRatelimit] = None + """An object configuring the rule's rate limit behavior.""" + + +class UnionMember1RuleResponseCompressionRule(CompressResponseRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember1RuleDDoSDynamicRule(DDoSDynamicRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember1RuleExecuteRule(ExecuteRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember1RuleForceConnectionCloseRule(ForceConnectionCloseRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember1RuleJavaScriptChallengeRuleExposedCredentialCheck(BaseModel): + """Configuration for exposed credential checking.""" + + password_expression: str + """An expression that selects the password used in the credentials check.""" + + username_expression: str + """An expression that selects the user ID used in the credentials check.""" + + +class UnionMember1RuleJavaScriptChallengeRuleRatelimit(BaseModel): + """An object configuring the rule's rate limit behavior.""" + + characteristics: List[str] + """ + Characteristics of the request on which the rate limit counter will be + incremented. + """ + + period: int + """Period in seconds over which the counter is being incremented.""" + + counting_expression: Optional[str] = None + """An expression that defines when the rate limit counter should be incremented. + + It defaults to the same as the rule's expression. + """ + + mitigation_timeout: Optional[int] = None + """ + Period of time in seconds after which the action will be disabled following its + first execution. + """ + + requests_per_period: Optional[int] = None + """ + The threshold of requests per period after which the action will be executed for + the first time. + """ + + requests_to_origin: Optional[bool] = None + """Whether counting is only performed when an origin is reached.""" + + score_per_period: Optional[int] = None + """ + The score threshold per period for which the action will be executed the first + time. + """ + + score_response_header_name: Optional[str] = None + """ + A response header name provided by the origin, which contains the score to + increment rate limit counter with. + """ + + +class UnionMember1RuleJavaScriptChallengeRule(BaseModel): + id: str + """The unique ID of the rule.""" + + action: Literal["js_challenge"] + """The action to perform when the rule matches.""" + + enabled: bool + """Whether the rule should be executed.""" + + expression: str + """The expression defining which traffic will match the rule.""" + + last_updated: datetime + """The timestamp of when the rule was last modified.""" + + ref: str + """The reference of the rule (the rule's ID by default).""" + + version: str + """The version of the rule.""" + + action_parameters: Optional[object] = None + """The parameters configuring the rule's action.""" + + categories: Optional[List[str]] = None + """The categories of the rule.""" + + description: Optional[str] = None + """An informative description of the rule.""" + + exposed_credential_check: Optional[UnionMember1RuleJavaScriptChallengeRuleExposedCredentialCheck] = None + """Configuration for exposed credential checking.""" + + logging: Optional[Logging] = None + """An object configuring the rule's logging behavior.""" + + ratelimit: Optional[UnionMember1RuleJavaScriptChallengeRuleRatelimit] = None + """An object configuring the rule's rate limit behavior.""" + + +class UnionMember1RuleLogRule(LogRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember1RuleLogCustomFieldRule(LogCustomFieldRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember1RuleManagedChallengeRule(ManagedChallengeRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember1RuleRedirectRule(RedirectRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember1RuleRewriteRule(RewriteRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember1RuleRouteRule(RouteRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember1RuleScoreRule(ScoreRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember1RuleServeErrorRule(ServeErrorRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember1RuleSetCacheControlRuleActionParametersImmutableSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember1RuleSetCacheControlRuleActionParametersImmutableRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember1RuleSetCacheControlRuleActionParametersImmutable: TypeAlias = Union[ + UnionMember1RuleSetCacheControlRuleActionParametersImmutableSetDirective, + UnionMember1RuleSetCacheControlRuleActionParametersImmutableRemoveDirective, +] + + +class UnionMember1RuleSetCacheControlRuleActionParametersMaxAgeSetDirective(BaseModel): + """Set the directive with a duration value in seconds.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + value: int + """The duration value in seconds for the directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember1RuleSetCacheControlRuleActionParametersMaxAgeRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember1RuleSetCacheControlRuleActionParametersMaxAge: TypeAlias = Union[ + UnionMember1RuleSetCacheControlRuleActionParametersMaxAgeSetDirective, + UnionMember1RuleSetCacheControlRuleActionParametersMaxAgeRemoveDirective, +] + + +class UnionMember1RuleSetCacheControlRuleActionParametersMustRevalidateSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember1RuleSetCacheControlRuleActionParametersMustRevalidateRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember1RuleSetCacheControlRuleActionParametersMustRevalidate: TypeAlias = Union[ + UnionMember1RuleSetCacheControlRuleActionParametersMustRevalidateSetDirective, + UnionMember1RuleSetCacheControlRuleActionParametersMustRevalidateRemoveDirective, +] + + +class UnionMember1RuleSetCacheControlRuleActionParametersMustUnderstandSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember1RuleSetCacheControlRuleActionParametersMustUnderstandRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember1RuleSetCacheControlRuleActionParametersMustUnderstand: TypeAlias = Union[ + UnionMember1RuleSetCacheControlRuleActionParametersMustUnderstandSetDirective, + UnionMember1RuleSetCacheControlRuleActionParametersMustUnderstandRemoveDirective, +] + + +class UnionMember1RuleSetCacheControlRuleActionParametersNoCacheSetDirective(BaseModel): + """Set the directive with optional qualifiers.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + qualifiers: Optional[List[str]] = None + """ + Optional list of header names to qualify the directive (e.g., for "private" or + "no-cache" directives). + """ + + +class UnionMember1RuleSetCacheControlRuleActionParametersNoCacheRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember1RuleSetCacheControlRuleActionParametersNoCache: TypeAlias = Union[ + UnionMember1RuleSetCacheControlRuleActionParametersNoCacheSetDirective, + UnionMember1RuleSetCacheControlRuleActionParametersNoCacheRemoveDirective, +] + + +class UnionMember1RuleSetCacheControlRuleActionParametersNoStoreSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember1RuleSetCacheControlRuleActionParametersNoStoreRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember1RuleSetCacheControlRuleActionParametersNoStore: TypeAlias = Union[ + UnionMember1RuleSetCacheControlRuleActionParametersNoStoreSetDirective, + UnionMember1RuleSetCacheControlRuleActionParametersNoStoreRemoveDirective, +] + + +class UnionMember1RuleSetCacheControlRuleActionParametersNoTransformSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember1RuleSetCacheControlRuleActionParametersNoTransformRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember1RuleSetCacheControlRuleActionParametersNoTransform: TypeAlias = Union[ + UnionMember1RuleSetCacheControlRuleActionParametersNoTransformSetDirective, + UnionMember1RuleSetCacheControlRuleActionParametersNoTransformRemoveDirective, +] + + +class UnionMember1RuleSetCacheControlRuleActionParametersPrivateSetDirective(BaseModel): + """Set the directive with optional qualifiers.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + qualifiers: Optional[List[str]] = None + """ + Optional list of header names to qualify the directive (e.g., for "private" or + "no-cache" directives). + """ + + +class UnionMember1RuleSetCacheControlRuleActionParametersPrivateRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember1RuleSetCacheControlRuleActionParametersPrivate: TypeAlias = Union[ + UnionMember1RuleSetCacheControlRuleActionParametersPrivateSetDirective, + UnionMember1RuleSetCacheControlRuleActionParametersPrivateRemoveDirective, +] + + +class UnionMember1RuleSetCacheControlRuleActionParametersProxyRevalidateSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember1RuleSetCacheControlRuleActionParametersProxyRevalidateRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember1RuleSetCacheControlRuleActionParametersProxyRevalidate: TypeAlias = Union[ + UnionMember1RuleSetCacheControlRuleActionParametersProxyRevalidateSetDirective, + UnionMember1RuleSetCacheControlRuleActionParametersProxyRevalidateRemoveDirective, +] + + +class UnionMember1RuleSetCacheControlRuleActionParametersPublicSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember1RuleSetCacheControlRuleActionParametersPublicRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember1RuleSetCacheControlRuleActionParametersPublic: TypeAlias = Union[ + UnionMember1RuleSetCacheControlRuleActionParametersPublicSetDirective, + UnionMember1RuleSetCacheControlRuleActionParametersPublicRemoveDirective, +] + + +class UnionMember1RuleSetCacheControlRuleActionParametersSMaxageSetDirective(BaseModel): + """Set the directive with a duration value in seconds.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + value: int + """The duration value in seconds for the directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember1RuleSetCacheControlRuleActionParametersSMaxageRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember1RuleSetCacheControlRuleActionParametersSMaxage: TypeAlias = Union[ + UnionMember1RuleSetCacheControlRuleActionParametersSMaxageSetDirective, + UnionMember1RuleSetCacheControlRuleActionParametersSMaxageRemoveDirective, +] + + +class UnionMember1RuleSetCacheControlRuleActionParametersStaleIfErrorSetDirective(BaseModel): + """Set the directive with a duration value in seconds.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + value: int + """The duration value in seconds for the directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember1RuleSetCacheControlRuleActionParametersStaleIfErrorRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember1RuleSetCacheControlRuleActionParametersStaleIfError: TypeAlias = Union[ + UnionMember1RuleSetCacheControlRuleActionParametersStaleIfErrorSetDirective, + UnionMember1RuleSetCacheControlRuleActionParametersStaleIfErrorRemoveDirective, +] + + +class UnionMember1RuleSetCacheControlRuleActionParametersStaleWhileRevalidateSetDirective(BaseModel): + """Set the directive with a duration value in seconds.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + value: int + """The duration value in seconds for the directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember1RuleSetCacheControlRuleActionParametersStaleWhileRevalidateRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember1RuleSetCacheControlRuleActionParametersStaleWhileRevalidate: TypeAlias = Union[ + UnionMember1RuleSetCacheControlRuleActionParametersStaleWhileRevalidateSetDirective, + UnionMember1RuleSetCacheControlRuleActionParametersStaleWhileRevalidateRemoveDirective, +] + + +class UnionMember1RuleSetCacheControlRuleActionParameters(BaseModel): + """The parameters configuring the rule's action.""" + + immutable: Optional[UnionMember1RuleSetCacheControlRuleActionParametersImmutable] = None + """A cache-control directive configuration.""" + + max_age: Optional[UnionMember1RuleSetCacheControlRuleActionParametersMaxAge] = FieldInfo( + alias="max-age", default=None + ) + """ + A cache-control directive configuration that accepts a duration value in + seconds. + """ + + must_revalidate: Optional[UnionMember1RuleSetCacheControlRuleActionParametersMustRevalidate] = FieldInfo( + alias="must-revalidate", default=None + ) + """A cache-control directive configuration.""" + + must_understand: Optional[UnionMember1RuleSetCacheControlRuleActionParametersMustUnderstand] = FieldInfo( + alias="must-understand", default=None + ) + """A cache-control directive configuration.""" + + no_cache: Optional[UnionMember1RuleSetCacheControlRuleActionParametersNoCache] = FieldInfo( + alias="no-cache", default=None + ) + """ + A cache-control directive configuration that accepts optional qualifiers (header + names). + """ + + no_store: Optional[UnionMember1RuleSetCacheControlRuleActionParametersNoStore] = FieldInfo( + alias="no-store", default=None + ) + """A cache-control directive configuration.""" + + no_transform: Optional[UnionMember1RuleSetCacheControlRuleActionParametersNoTransform] = FieldInfo( + alias="no-transform", default=None + ) + """A cache-control directive configuration.""" + + private: Optional[UnionMember1RuleSetCacheControlRuleActionParametersPrivate] = None + """ + A cache-control directive configuration that accepts optional qualifiers (header + names). + """ + + proxy_revalidate: Optional[UnionMember1RuleSetCacheControlRuleActionParametersProxyRevalidate] = FieldInfo( + alias="proxy-revalidate", default=None + ) + """A cache-control directive configuration.""" + + public: Optional[UnionMember1RuleSetCacheControlRuleActionParametersPublic] = None + """A cache-control directive configuration.""" + + s_maxage: Optional[UnionMember1RuleSetCacheControlRuleActionParametersSMaxage] = FieldInfo( + alias="s-maxage", default=None + ) + """ + A cache-control directive configuration that accepts a duration value in + seconds. + """ + + stale_if_error: Optional[UnionMember1RuleSetCacheControlRuleActionParametersStaleIfError] = FieldInfo( + alias="stale-if-error", default=None + ) + """ + A cache-control directive configuration that accepts a duration value in + seconds. + """ + + stale_while_revalidate: Optional[UnionMember1RuleSetCacheControlRuleActionParametersStaleWhileRevalidate] = ( + FieldInfo(alias="stale-while-revalidate", default=None) + ) + """ + A cache-control directive configuration that accepts a duration value in + seconds. + """ + + +class UnionMember1RuleSetCacheControlRuleExposedCredentialCheck(BaseModel): + """Configuration for exposed credential checking.""" + + password_expression: str + """An expression that selects the password used in the credentials check.""" + + username_expression: str + """An expression that selects the user ID used in the credentials check.""" + + +class UnionMember1RuleSetCacheControlRuleRatelimit(BaseModel): + """An object configuring the rule's rate limit behavior.""" + + characteristics: List[str] + """ + Characteristics of the request on which the rate limit counter will be + incremented. + """ + + period: int + """Period in seconds over which the counter is being incremented.""" + + counting_expression: Optional[str] = None + """An expression that defines when the rate limit counter should be incremented. + + It defaults to the same as the rule's expression. + """ + + mitigation_timeout: Optional[int] = None + """ + Period of time in seconds after which the action will be disabled following its + first execution. + """ + + requests_per_period: Optional[int] = None + """ + The threshold of requests per period after which the action will be executed for + the first time. + """ + + requests_to_origin: Optional[bool] = None + """Whether counting is only performed when an origin is reached.""" + + score_per_period: Optional[int] = None + """ + The score threshold per period for which the action will be executed the first + time. + """ + + score_response_header_name: Optional[str] = None + """ + A response header name provided by the origin, which contains the score to + increment rate limit counter with. + """ + + +class UnionMember1RuleSetCacheControlRule(BaseModel): + id: str + """The unique ID of the rule.""" + + action: Literal["set_cache_control"] + """The action to perform when the rule matches.""" + + enabled: bool + + expression: str + """The expression defining which traffic will match the rule.""" + + last_updated: datetime + """The timestamp of when the rule was last modified.""" + + ref: str + """The reference of the rule (the rule's ID by default).""" + + version: str + """The version of the rule.""" + + action_parameters: Optional[UnionMember1RuleSetCacheControlRuleActionParameters] = None + """The parameters configuring the rule's action.""" + + categories: Optional[List[str]] = None + """The categories of the rule.""" + + description: Optional[str] = None + """An informative description of the rule.""" + + exposed_credential_check: Optional[UnionMember1RuleSetCacheControlRuleExposedCredentialCheck] = None + """Configuration for exposed credential checking.""" + + logging: Optional[Logging] = None + """An object configuring the rule's logging behavior.""" + + ratelimit: Optional[UnionMember1RuleSetCacheControlRuleRatelimit] = None + """An object configuring the rule's rate limit behavior.""" + + +class UnionMember1RuleSetCacheSettingsRule(SetCacheSettingsRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember1RuleSetCacheTagsRuleActionParametersAddCacheTagsValues(BaseModel): + """Add cache tags using a list of values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + values: List[str] + """A list of cache tag values.""" + + +class UnionMember1RuleSetCacheTagsRuleActionParametersAddCacheTagsExpression(BaseModel): + """Add cache tags using an expression.""" + + expression: str + """An expression that evaluates to an array of cache tag values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + +class UnionMember1RuleSetCacheTagsRuleActionParametersRemoveCacheTagsValues(BaseModel): + """Remove cache tags using a list of values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + values: List[str] + """A list of cache tag values.""" + + +class UnionMember1RuleSetCacheTagsRuleActionParametersRemoveCacheTagsExpression(BaseModel): + """Remove cache tags using an expression.""" + + expression: str + """An expression that evaluates to an array of cache tag values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + +class UnionMember1RuleSetCacheTagsRuleActionParametersSetCacheTagsValues(BaseModel): + """Set cache tags using a list of values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + values: List[str] + """A list of cache tag values.""" + + +class UnionMember1RuleSetCacheTagsRuleActionParametersSetCacheTagsExpression(BaseModel): + """Set cache tags using an expression.""" + + expression: str + """An expression that evaluates to an array of cache tag values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + +UnionMember1RuleSetCacheTagsRuleActionParameters: TypeAlias = Union[ + UnionMember1RuleSetCacheTagsRuleActionParametersAddCacheTagsValues, + UnionMember1RuleSetCacheTagsRuleActionParametersAddCacheTagsExpression, + UnionMember1RuleSetCacheTagsRuleActionParametersRemoveCacheTagsValues, + UnionMember1RuleSetCacheTagsRuleActionParametersRemoveCacheTagsExpression, + UnionMember1RuleSetCacheTagsRuleActionParametersSetCacheTagsValues, + UnionMember1RuleSetCacheTagsRuleActionParametersSetCacheTagsExpression, +] + + +class UnionMember1RuleSetCacheTagsRuleExposedCredentialCheck(BaseModel): + """Configuration for exposed credential checking.""" + + password_expression: str + """An expression that selects the password used in the credentials check.""" + + username_expression: str + """An expression that selects the user ID used in the credentials check.""" + + +class UnionMember1RuleSetCacheTagsRuleRatelimit(BaseModel): + """An object configuring the rule's rate limit behavior.""" + + characteristics: List[str] + """ + Characteristics of the request on which the rate limit counter will be + incremented. + """ + + period: int + """Period in seconds over which the counter is being incremented.""" + + counting_expression: Optional[str] = None + """An expression that defines when the rate limit counter should be incremented. + + It defaults to the same as the rule's expression. + """ + + mitigation_timeout: Optional[int] = None + """ + Period of time in seconds after which the action will be disabled following its + first execution. + """ + + requests_per_period: Optional[int] = None + """ + The threshold of requests per period after which the action will be executed for + the first time. + """ + + requests_to_origin: Optional[bool] = None + """Whether counting is only performed when an origin is reached.""" + + score_per_period: Optional[int] = None + """ + The score threshold per period for which the action will be executed the first + time. + """ + + score_response_header_name: Optional[str] = None + """ + A response header name provided by the origin, which contains the score to + increment rate limit counter with. + """ + + +class UnionMember1RuleSetCacheTagsRule(BaseModel): + id: str + """The unique ID of the rule.""" + + action: Literal["set_cache_tags"] + """The action to perform when the rule matches.""" + + enabled: bool + + expression: str + """The expression defining which traffic will match the rule.""" + + last_updated: datetime + """The timestamp of when the rule was last modified.""" + + ref: str + """The reference of the rule (the rule's ID by default).""" + + version: str + """The version of the rule.""" + + action_parameters: Optional[UnionMember1RuleSetCacheTagsRuleActionParameters] = None + """The parameters configuring the rule's action.""" + + categories: Optional[List[str]] = None + """The categories of the rule.""" + + description: Optional[str] = None + """An informative description of the rule.""" + + exposed_credential_check: Optional[UnionMember1RuleSetCacheTagsRuleExposedCredentialCheck] = None + """Configuration for exposed credential checking.""" + + logging: Optional[Logging] = None + """An object configuring the rule's logging behavior.""" + + ratelimit: Optional[UnionMember1RuleSetCacheTagsRuleRatelimit] = None + """An object configuring the rule's rate limit behavior.""" + + +class UnionMember1RuleSetConfigurationRule(SetConfigRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember1RuleSkipRule(SkipRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember1RuleTransformResponseHTMLRuleActionParameters(BaseModel): + """The parameters configuring the rule's action.""" + + link_maze: object + """Enables the link maze transformation on the response.""" + + +class UnionMember1RuleTransformResponseHTMLRuleExposedCredentialCheck(BaseModel): + """Configuration for exposed credential checking.""" + + password_expression: str + """An expression that selects the password used in the credentials check.""" + + username_expression: str + """An expression that selects the user ID used in the credentials check.""" + + +class UnionMember1RuleTransformResponseHTMLRuleRatelimit(BaseModel): + """An object configuring the rule's rate limit behavior.""" + + characteristics: List[str] + """ + Characteristics of the request on which the rate limit counter will be + incremented. + """ + + period: int + """Period in seconds over which the counter is being incremented.""" + + counting_expression: Optional[str] = None + """An expression that defines when the rate limit counter should be incremented. + + It defaults to the same as the rule's expression. + """ + + mitigation_timeout: Optional[int] = None + """ + Period of time in seconds after which the action will be disabled following its + first execution. + """ + + requests_per_period: Optional[int] = None + """ + The threshold of requests per period after which the action will be executed for + the first time. + """ + + requests_to_origin: Optional[bool] = None + """Whether counting is only performed when an origin is reached.""" + + score_per_period: Optional[int] = None + """ + The score threshold per period for which the action will be executed the first + time. + """ + + score_response_header_name: Optional[str] = None + """ + A response header name provided by the origin, which contains the score to + increment rate limit counter with. + """ + + +class UnionMember1RuleTransformResponseHTMLRule(BaseModel): + id: str + """The unique ID of the rule.""" + + action: Literal["transform_response_html"] + """The action to perform when the rule matches.""" + + enabled: bool + + expression: str + """The expression defining which traffic will match the rule.""" + + last_updated: datetime + """The timestamp of when the rule was last modified.""" + + ref: str + """The reference of the rule (the rule's ID by default).""" + + version: str + """The version of the rule.""" + + action_parameters: Optional[UnionMember1RuleTransformResponseHTMLRuleActionParameters] = None + """The parameters configuring the rule's action.""" + + categories: Optional[List[str]] = None + """The categories of the rule.""" + + description: Optional[str] = None + """An informative description of the rule.""" + + exposed_credential_check: Optional[UnionMember1RuleTransformResponseHTMLRuleExposedCredentialCheck] = None + """Configuration for exposed credential checking.""" + + logging: Optional[Logging] = None + """An object configuring the rule's logging behavior.""" + + ratelimit: Optional[UnionMember1RuleTransformResponseHTMLRuleRatelimit] = None + """An object configuring the rule's rate limit behavior.""" + + +UnionMember1Rule: TypeAlias = Union[ + UnionMember1RuleBlockRule, + UnionMember1RuleChallengeRule, + UnionMember1RuleResponseCompressionRule, + UnionMember1RuleDDoSDynamicRule, + UnionMember1RuleExecuteRule, + UnionMember1RuleForceConnectionCloseRule, + UnionMember1RuleJavaScriptChallengeRule, + UnionMember1RuleLogRule, + UnionMember1RuleLogCustomFieldRule, + UnionMember1RuleManagedChallengeRule, + UnionMember1RuleRedirectRule, + UnionMember1RuleRewriteRule, + UnionMember1RuleRouteRule, + UnionMember1RuleScoreRule, + UnionMember1RuleServeErrorRule, + UnionMember1RuleSetCacheControlRule, + UnionMember1RuleSetCacheSettingsRule, + UnionMember1RuleSetCacheTagsRule, + UnionMember1RuleSetConfigurationRule, + UnionMember1RuleSkipRule, + UnionMember1RuleTransformResponseHTMLRule, +] + + +class UnionMember1(BaseModel): + id: Optional[str] = None + """The unique ID of the ruleset.""" + + description: Optional[str] = None + """An informative description of the ruleset.""" + + kind: Optional[Kind] = None + """The kind of the ruleset.""" + + last_updated: Optional[datetime] = None + """The timestamp of when the ruleset was last modified.""" + + name: Optional[str] = None + """The human-readable name of the ruleset.""" + + phase: Optional[Phase] = None + """The phase of the ruleset.""" + + rules: Optional[List[UnionMember1Rule]] = None + """The list of rules in the ruleset.""" + + version: Optional[str] = None + """The version of the ruleset.""" + + +class UnionMember2RuleBlockRule(BlockRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember2RuleChallengeRuleExposedCredentialCheck(BaseModel): + """Configuration for exposed credential checking.""" + + password_expression: str + """An expression that selects the password used in the credentials check.""" + + username_expression: str + """An expression that selects the user ID used in the credentials check.""" + + +class UnionMember2RuleChallengeRuleRatelimit(BaseModel): + """An object configuring the rule's rate limit behavior.""" + + characteristics: List[str] + """ + Characteristics of the request on which the rate limit counter will be + incremented. + """ + + period: int + """Period in seconds over which the counter is being incremented.""" + + counting_expression: Optional[str] = None + """An expression that defines when the rate limit counter should be incremented. + + It defaults to the same as the rule's expression. + """ + + mitigation_timeout: Optional[int] = None + """ + Period of time in seconds after which the action will be disabled following its + first execution. + """ + + requests_per_period: Optional[int] = None + """ + The threshold of requests per period after which the action will be executed for + the first time. + """ + + requests_to_origin: Optional[bool] = None + """Whether counting is only performed when an origin is reached.""" + + score_per_period: Optional[int] = None + """ + The score threshold per period for which the action will be executed the first + time. + """ + + score_response_header_name: Optional[str] = None + """ + A response header name provided by the origin, which contains the score to + increment rate limit counter with. + """ + + +class UnionMember2RuleChallengeRule(BaseModel): + id: str + """The unique ID of the rule.""" + + action: Literal["challenge"] + """The action to perform when the rule matches.""" + + enabled: bool + """Whether the rule should be executed.""" + + expression: str + """The expression defining which traffic will match the rule.""" + + last_updated: datetime + """The timestamp of when the rule was last modified.""" + + ref: str + """The reference of the rule (the rule's ID by default).""" + + version: str + """The version of the rule.""" + + action_parameters: Optional[object] = None + """The parameters configuring the rule's action.""" + + categories: Optional[List[str]] = None + """The categories of the rule.""" + + description: Optional[str] = None + """An informative description of the rule.""" + + exposed_credential_check: Optional[UnionMember2RuleChallengeRuleExposedCredentialCheck] = None + """Configuration for exposed credential checking.""" + + logging: Optional[Logging] = None + """An object configuring the rule's logging behavior.""" + + ratelimit: Optional[UnionMember2RuleChallengeRuleRatelimit] = None + """An object configuring the rule's rate limit behavior.""" + + +class UnionMember2RuleResponseCompressionRule(CompressResponseRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember2RuleDDoSDynamicRule(DDoSDynamicRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember2RuleExecuteRule(ExecuteRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember2RuleForceConnectionCloseRule(ForceConnectionCloseRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember2RuleJavaScriptChallengeRuleExposedCredentialCheck(BaseModel): + """Configuration for exposed credential checking.""" + + password_expression: str + """An expression that selects the password used in the credentials check.""" + + username_expression: str + """An expression that selects the user ID used in the credentials check.""" + + +class UnionMember2RuleJavaScriptChallengeRuleRatelimit(BaseModel): + """An object configuring the rule's rate limit behavior.""" + + characteristics: List[str] + """ + Characteristics of the request on which the rate limit counter will be + incremented. + """ + + period: int + """Period in seconds over which the counter is being incremented.""" + + counting_expression: Optional[str] = None + """An expression that defines when the rate limit counter should be incremented. + + It defaults to the same as the rule's expression. + """ + + mitigation_timeout: Optional[int] = None + """ + Period of time in seconds after which the action will be disabled following its + first execution. + """ + + requests_per_period: Optional[int] = None + """ + The threshold of requests per period after which the action will be executed for + the first time. + """ + + requests_to_origin: Optional[bool] = None + """Whether counting is only performed when an origin is reached.""" + + score_per_period: Optional[int] = None + """ + The score threshold per period for which the action will be executed the first + time. + """ + + score_response_header_name: Optional[str] = None + """ + A response header name provided by the origin, which contains the score to + increment rate limit counter with. + """ + + +class UnionMember2RuleJavaScriptChallengeRule(BaseModel): + id: str + """The unique ID of the rule.""" + + action: Literal["js_challenge"] + """The action to perform when the rule matches.""" + + enabled: bool + """Whether the rule should be executed.""" + + expression: str + """The expression defining which traffic will match the rule.""" + + last_updated: datetime + """The timestamp of when the rule was last modified.""" + + ref: str + """The reference of the rule (the rule's ID by default).""" + + version: str + """The version of the rule.""" + + action_parameters: Optional[object] = None + """The parameters configuring the rule's action.""" + + categories: Optional[List[str]] = None + """The categories of the rule.""" + + description: Optional[str] = None + """An informative description of the rule.""" + + exposed_credential_check: Optional[UnionMember2RuleJavaScriptChallengeRuleExposedCredentialCheck] = None + """Configuration for exposed credential checking.""" + + logging: Optional[Logging] = None + """An object configuring the rule's logging behavior.""" + + ratelimit: Optional[UnionMember2RuleJavaScriptChallengeRuleRatelimit] = None + """An object configuring the rule's rate limit behavior.""" + + +class UnionMember2RuleLogRule(LogRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember2RuleLogCustomFieldRule(LogCustomFieldRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember2RuleManagedChallengeRule(ManagedChallengeRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember2RuleRedirectRule(RedirectRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember2RuleRewriteRule(RewriteRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember2RuleRouteRule(RouteRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember2RuleScoreRule(ScoreRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember2RuleServeErrorRule(ServeErrorRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember2RuleSetCacheControlRuleActionParametersImmutableSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember2RuleSetCacheControlRuleActionParametersImmutableRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember2RuleSetCacheControlRuleActionParametersImmutable: TypeAlias = Union[ + UnionMember2RuleSetCacheControlRuleActionParametersImmutableSetDirective, + UnionMember2RuleSetCacheControlRuleActionParametersImmutableRemoveDirective, +] + + +class UnionMember2RuleSetCacheControlRuleActionParametersMaxAgeSetDirective(BaseModel): + """Set the directive with a duration value in seconds.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + value: int + """The duration value in seconds for the directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember2RuleSetCacheControlRuleActionParametersMaxAgeRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember2RuleSetCacheControlRuleActionParametersMaxAge: TypeAlias = Union[ + UnionMember2RuleSetCacheControlRuleActionParametersMaxAgeSetDirective, + UnionMember2RuleSetCacheControlRuleActionParametersMaxAgeRemoveDirective, +] + + +class UnionMember2RuleSetCacheControlRuleActionParametersMustRevalidateSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember2RuleSetCacheControlRuleActionParametersMustRevalidateRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember2RuleSetCacheControlRuleActionParametersMustRevalidate: TypeAlias = Union[ + UnionMember2RuleSetCacheControlRuleActionParametersMustRevalidateSetDirective, + UnionMember2RuleSetCacheControlRuleActionParametersMustRevalidateRemoveDirective, +] + + +class UnionMember2RuleSetCacheControlRuleActionParametersMustUnderstandSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember2RuleSetCacheControlRuleActionParametersMustUnderstandRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember2RuleSetCacheControlRuleActionParametersMustUnderstand: TypeAlias = Union[ + UnionMember2RuleSetCacheControlRuleActionParametersMustUnderstandSetDirective, + UnionMember2RuleSetCacheControlRuleActionParametersMustUnderstandRemoveDirective, +] + + +class UnionMember2RuleSetCacheControlRuleActionParametersNoCacheSetDirective(BaseModel): + """Set the directive with optional qualifiers.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + qualifiers: Optional[List[str]] = None + """ + Optional list of header names to qualify the directive (e.g., for "private" or + "no-cache" directives). + """ + + +class UnionMember2RuleSetCacheControlRuleActionParametersNoCacheRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember2RuleSetCacheControlRuleActionParametersNoCache: TypeAlias = Union[ + UnionMember2RuleSetCacheControlRuleActionParametersNoCacheSetDirective, + UnionMember2RuleSetCacheControlRuleActionParametersNoCacheRemoveDirective, +] + + +class UnionMember2RuleSetCacheControlRuleActionParametersNoStoreSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember2RuleSetCacheControlRuleActionParametersNoStoreRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember2RuleSetCacheControlRuleActionParametersNoStore: TypeAlias = Union[ + UnionMember2RuleSetCacheControlRuleActionParametersNoStoreSetDirective, + UnionMember2RuleSetCacheControlRuleActionParametersNoStoreRemoveDirective, +] + + +class UnionMember2RuleSetCacheControlRuleActionParametersNoTransformSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember2RuleSetCacheControlRuleActionParametersNoTransformRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember2RuleSetCacheControlRuleActionParametersNoTransform: TypeAlias = Union[ + UnionMember2RuleSetCacheControlRuleActionParametersNoTransformSetDirective, + UnionMember2RuleSetCacheControlRuleActionParametersNoTransformRemoveDirective, +] + + +class UnionMember2RuleSetCacheControlRuleActionParametersPrivateSetDirective(BaseModel): + """Set the directive with optional qualifiers.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + qualifiers: Optional[List[str]] = None + """ + Optional list of header names to qualify the directive (e.g., for "private" or + "no-cache" directives). + """ + + +class UnionMember2RuleSetCacheControlRuleActionParametersPrivateRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember2RuleSetCacheControlRuleActionParametersPrivate: TypeAlias = Union[ + UnionMember2RuleSetCacheControlRuleActionParametersPrivateSetDirective, + UnionMember2RuleSetCacheControlRuleActionParametersPrivateRemoveDirective, +] + + +class UnionMember2RuleSetCacheControlRuleActionParametersProxyRevalidateSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember2RuleSetCacheControlRuleActionParametersProxyRevalidateRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember2RuleSetCacheControlRuleActionParametersProxyRevalidate: TypeAlias = Union[ + UnionMember2RuleSetCacheControlRuleActionParametersProxyRevalidateSetDirective, + UnionMember2RuleSetCacheControlRuleActionParametersProxyRevalidateRemoveDirective, +] + + +class UnionMember2RuleSetCacheControlRuleActionParametersPublicSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember2RuleSetCacheControlRuleActionParametersPublicRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember2RuleSetCacheControlRuleActionParametersPublic: TypeAlias = Union[ + UnionMember2RuleSetCacheControlRuleActionParametersPublicSetDirective, + UnionMember2RuleSetCacheControlRuleActionParametersPublicRemoveDirective, +] + + +class UnionMember2RuleSetCacheControlRuleActionParametersSMaxageSetDirective(BaseModel): + """Set the directive with a duration value in seconds.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + value: int + """The duration value in seconds for the directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember2RuleSetCacheControlRuleActionParametersSMaxageRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember2RuleSetCacheControlRuleActionParametersSMaxage: TypeAlias = Union[ + UnionMember2RuleSetCacheControlRuleActionParametersSMaxageSetDirective, + UnionMember2RuleSetCacheControlRuleActionParametersSMaxageRemoveDirective, +] + + +class UnionMember2RuleSetCacheControlRuleActionParametersStaleIfErrorSetDirective(BaseModel): + """Set the directive with a duration value in seconds.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + value: int + """The duration value in seconds for the directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember2RuleSetCacheControlRuleActionParametersStaleIfErrorRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember2RuleSetCacheControlRuleActionParametersStaleIfError: TypeAlias = Union[ + UnionMember2RuleSetCacheControlRuleActionParametersStaleIfErrorSetDirective, + UnionMember2RuleSetCacheControlRuleActionParametersStaleIfErrorRemoveDirective, +] + + +class UnionMember2RuleSetCacheControlRuleActionParametersStaleWhileRevalidateSetDirective(BaseModel): + """Set the directive with a duration value in seconds.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + value: int + """The duration value in seconds for the directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember2RuleSetCacheControlRuleActionParametersStaleWhileRevalidateRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember2RuleSetCacheControlRuleActionParametersStaleWhileRevalidate: TypeAlias = Union[ + UnionMember2RuleSetCacheControlRuleActionParametersStaleWhileRevalidateSetDirective, + UnionMember2RuleSetCacheControlRuleActionParametersStaleWhileRevalidateRemoveDirective, +] + + +class UnionMember2RuleSetCacheControlRuleActionParameters(BaseModel): + """The parameters configuring the rule's action.""" + + immutable: Optional[UnionMember2RuleSetCacheControlRuleActionParametersImmutable] = None + """A cache-control directive configuration.""" + + max_age: Optional[UnionMember2RuleSetCacheControlRuleActionParametersMaxAge] = FieldInfo( + alias="max-age", default=None + ) + """ + A cache-control directive configuration that accepts a duration value in + seconds. + """ + + must_revalidate: Optional[UnionMember2RuleSetCacheControlRuleActionParametersMustRevalidate] = FieldInfo( + alias="must-revalidate", default=None + ) + """A cache-control directive configuration.""" + + must_understand: Optional[UnionMember2RuleSetCacheControlRuleActionParametersMustUnderstand] = FieldInfo( + alias="must-understand", default=None + ) + """A cache-control directive configuration.""" + + no_cache: Optional[UnionMember2RuleSetCacheControlRuleActionParametersNoCache] = FieldInfo( + alias="no-cache", default=None + ) + """ + A cache-control directive configuration that accepts optional qualifiers (header + names). + """ + + no_store: Optional[UnionMember2RuleSetCacheControlRuleActionParametersNoStore] = FieldInfo( + alias="no-store", default=None + ) + """A cache-control directive configuration.""" + + no_transform: Optional[UnionMember2RuleSetCacheControlRuleActionParametersNoTransform] = FieldInfo( + alias="no-transform", default=None + ) + """A cache-control directive configuration.""" + + private: Optional[UnionMember2RuleSetCacheControlRuleActionParametersPrivate] = None + """ + A cache-control directive configuration that accepts optional qualifiers (header + names). + """ + + proxy_revalidate: Optional[UnionMember2RuleSetCacheControlRuleActionParametersProxyRevalidate] = FieldInfo( + alias="proxy-revalidate", default=None + ) + """A cache-control directive configuration.""" + + public: Optional[UnionMember2RuleSetCacheControlRuleActionParametersPublic] = None + """A cache-control directive configuration.""" + + s_maxage: Optional[UnionMember2RuleSetCacheControlRuleActionParametersSMaxage] = FieldInfo( + alias="s-maxage", default=None + ) + """ + A cache-control directive configuration that accepts a duration value in + seconds. + """ + + stale_if_error: Optional[UnionMember2RuleSetCacheControlRuleActionParametersStaleIfError] = FieldInfo( + alias="stale-if-error", default=None + ) + """ + A cache-control directive configuration that accepts a duration value in + seconds. + """ + + stale_while_revalidate: Optional[UnionMember2RuleSetCacheControlRuleActionParametersStaleWhileRevalidate] = ( + FieldInfo(alias="stale-while-revalidate", default=None) + ) + """ + A cache-control directive configuration that accepts a duration value in + seconds. + """ + + +class UnionMember2RuleSetCacheControlRuleExposedCredentialCheck(BaseModel): + """Configuration for exposed credential checking.""" + + password_expression: str + """An expression that selects the password used in the credentials check.""" + + username_expression: str + """An expression that selects the user ID used in the credentials check.""" + + +class UnionMember2RuleSetCacheControlRuleRatelimit(BaseModel): + """An object configuring the rule's rate limit behavior.""" + + characteristics: List[str] + """ + Characteristics of the request on which the rate limit counter will be + incremented. + """ + + period: int + """Period in seconds over which the counter is being incremented.""" + + counting_expression: Optional[str] = None + """An expression that defines when the rate limit counter should be incremented. + + It defaults to the same as the rule's expression. + """ + + mitigation_timeout: Optional[int] = None + """ + Period of time in seconds after which the action will be disabled following its + first execution. + """ + + requests_per_period: Optional[int] = None + """ + The threshold of requests per period after which the action will be executed for + the first time. + """ + + requests_to_origin: Optional[bool] = None + """Whether counting is only performed when an origin is reached.""" + + score_per_period: Optional[int] = None + """ + The score threshold per period for which the action will be executed the first + time. + """ + + score_response_header_name: Optional[str] = None + """ + A response header name provided by the origin, which contains the score to + increment rate limit counter with. + """ + + +class UnionMember2RuleSetCacheControlRule(BaseModel): + id: str + """The unique ID of the rule.""" + + action: Literal["set_cache_control"] + """The action to perform when the rule matches.""" + + enabled: bool + + expression: str + """The expression defining which traffic will match the rule.""" + + last_updated: datetime + """The timestamp of when the rule was last modified.""" + + ref: str + """The reference of the rule (the rule's ID by default).""" + + version: str + """The version of the rule.""" + + action_parameters: Optional[UnionMember2RuleSetCacheControlRuleActionParameters] = None + """The parameters configuring the rule's action.""" + + categories: Optional[List[str]] = None + """The categories of the rule.""" + + description: Optional[str] = None + """An informative description of the rule.""" + + exposed_credential_check: Optional[UnionMember2RuleSetCacheControlRuleExposedCredentialCheck] = None + """Configuration for exposed credential checking.""" + + logging: Optional[Logging] = None + """An object configuring the rule's logging behavior.""" + + ratelimit: Optional[UnionMember2RuleSetCacheControlRuleRatelimit] = None + """An object configuring the rule's rate limit behavior.""" + + +class UnionMember2RuleSetCacheSettingsRule(SetCacheSettingsRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember2RuleSetCacheTagsRuleActionParametersAddCacheTagsValues(BaseModel): + """Add cache tags using a list of values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + values: List[str] + """A list of cache tag values.""" + + +class UnionMember2RuleSetCacheTagsRuleActionParametersAddCacheTagsExpression(BaseModel): + """Add cache tags using an expression.""" + + expression: str + """An expression that evaluates to an array of cache tag values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + +class UnionMember2RuleSetCacheTagsRuleActionParametersRemoveCacheTagsValues(BaseModel): + """Remove cache tags using a list of values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + values: List[str] + """A list of cache tag values.""" + + +class UnionMember2RuleSetCacheTagsRuleActionParametersRemoveCacheTagsExpression(BaseModel): + """Remove cache tags using an expression.""" + + expression: str + """An expression that evaluates to an array of cache tag values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + +class UnionMember2RuleSetCacheTagsRuleActionParametersSetCacheTagsValues(BaseModel): + """Set cache tags using a list of values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + values: List[str] + """A list of cache tag values.""" + + +class UnionMember2RuleSetCacheTagsRuleActionParametersSetCacheTagsExpression(BaseModel): + """Set cache tags using an expression.""" + + expression: str + """An expression that evaluates to an array of cache tag values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + +UnionMember2RuleSetCacheTagsRuleActionParameters: TypeAlias = Union[ + UnionMember2RuleSetCacheTagsRuleActionParametersAddCacheTagsValues, + UnionMember2RuleSetCacheTagsRuleActionParametersAddCacheTagsExpression, + UnionMember2RuleSetCacheTagsRuleActionParametersRemoveCacheTagsValues, + UnionMember2RuleSetCacheTagsRuleActionParametersRemoveCacheTagsExpression, + UnionMember2RuleSetCacheTagsRuleActionParametersSetCacheTagsValues, + UnionMember2RuleSetCacheTagsRuleActionParametersSetCacheTagsExpression, +] + + +class UnionMember2RuleSetCacheTagsRuleExposedCredentialCheck(BaseModel): + """Configuration for exposed credential checking.""" + + password_expression: str + """An expression that selects the password used in the credentials check.""" + + username_expression: str + """An expression that selects the user ID used in the credentials check.""" + + +class UnionMember2RuleSetCacheTagsRuleRatelimit(BaseModel): + """An object configuring the rule's rate limit behavior.""" + + characteristics: List[str] + """ + Characteristics of the request on which the rate limit counter will be + incremented. + """ + + period: int + """Period in seconds over which the counter is being incremented.""" + + counting_expression: Optional[str] = None + """An expression that defines when the rate limit counter should be incremented. + + It defaults to the same as the rule's expression. + """ + + mitigation_timeout: Optional[int] = None + """ + Period of time in seconds after which the action will be disabled following its + first execution. + """ + + requests_per_period: Optional[int] = None + """ + The threshold of requests per period after which the action will be executed for + the first time. + """ + + requests_to_origin: Optional[bool] = None + """Whether counting is only performed when an origin is reached.""" + + score_per_period: Optional[int] = None + """ + The score threshold per period for which the action will be executed the first + time. + """ + + score_response_header_name: Optional[str] = None + """ + A response header name provided by the origin, which contains the score to + increment rate limit counter with. + """ + + +class UnionMember2RuleSetCacheTagsRule(BaseModel): + id: str + """The unique ID of the rule.""" + + action: Literal["set_cache_tags"] + """The action to perform when the rule matches.""" + + enabled: bool + + expression: str + """The expression defining which traffic will match the rule.""" + + last_updated: datetime + """The timestamp of when the rule was last modified.""" + + ref: str + """The reference of the rule (the rule's ID by default).""" + + version: str + """The version of the rule.""" + + action_parameters: Optional[UnionMember2RuleSetCacheTagsRuleActionParameters] = None + """The parameters configuring the rule's action.""" + + categories: Optional[List[str]] = None + """The categories of the rule.""" + + description: Optional[str] = None + """An informative description of the rule.""" + + exposed_credential_check: Optional[UnionMember2RuleSetCacheTagsRuleExposedCredentialCheck] = None + """Configuration for exposed credential checking.""" + + logging: Optional[Logging] = None + """An object configuring the rule's logging behavior.""" + + ratelimit: Optional[UnionMember2RuleSetCacheTagsRuleRatelimit] = None + """An object configuring the rule's rate limit behavior.""" + + +class UnionMember2RuleSetConfigurationRule(SetConfigRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember2RuleSkipRule(SkipRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember2RuleTransformResponseHTMLRuleActionParameters(BaseModel): + """The parameters configuring the rule's action.""" + + link_maze: object + """Enables the link maze transformation on the response.""" + + +class UnionMember2RuleTransformResponseHTMLRuleExposedCredentialCheck(BaseModel): + """Configuration for exposed credential checking.""" + + password_expression: str + """An expression that selects the password used in the credentials check.""" + + username_expression: str + """An expression that selects the user ID used in the credentials check.""" + + +class UnionMember2RuleTransformResponseHTMLRuleRatelimit(BaseModel): + """An object configuring the rule's rate limit behavior.""" + + characteristics: List[str] + """ + Characteristics of the request on which the rate limit counter will be + incremented. + """ + + period: int + """Period in seconds over which the counter is being incremented.""" + + counting_expression: Optional[str] = None + """An expression that defines when the rate limit counter should be incremented. + + It defaults to the same as the rule's expression. + """ + + mitigation_timeout: Optional[int] = None + """ + Period of time in seconds after which the action will be disabled following its + first execution. + """ + + requests_per_period: Optional[int] = None + """ + The threshold of requests per period after which the action will be executed for + the first time. + """ + + requests_to_origin: Optional[bool] = None + """Whether counting is only performed when an origin is reached.""" + + score_per_period: Optional[int] = None + """ + The score threshold per period for which the action will be executed the first + time. + """ + + score_response_header_name: Optional[str] = None + """ + A response header name provided by the origin, which contains the score to + increment rate limit counter with. + """ + + +class UnionMember2RuleTransformResponseHTMLRule(BaseModel): + id: str + """The unique ID of the rule.""" + + action: Literal["transform_response_html"] + """The action to perform when the rule matches.""" + + enabled: bool + + expression: str + """The expression defining which traffic will match the rule.""" + + last_updated: datetime + """The timestamp of when the rule was last modified.""" + + ref: str + """The reference of the rule (the rule's ID by default).""" + + version: str + """The version of the rule.""" + + action_parameters: Optional[UnionMember2RuleTransformResponseHTMLRuleActionParameters] = None + """The parameters configuring the rule's action.""" + + categories: Optional[List[str]] = None + """The categories of the rule.""" + + description: Optional[str] = None + """An informative description of the rule.""" + + exposed_credential_check: Optional[UnionMember2RuleTransformResponseHTMLRuleExposedCredentialCheck] = None + """Configuration for exposed credential checking.""" + + logging: Optional[Logging] = None + """An object configuring the rule's logging behavior.""" + + ratelimit: Optional[UnionMember2RuleTransformResponseHTMLRuleRatelimit] = None + """An object configuring the rule's rate limit behavior.""" + + +UnionMember2Rule: TypeAlias = Union[ + UnionMember2RuleBlockRule, + UnionMember2RuleChallengeRule, + UnionMember2RuleResponseCompressionRule, + UnionMember2RuleDDoSDynamicRule, + UnionMember2RuleExecuteRule, + UnionMember2RuleForceConnectionCloseRule, + UnionMember2RuleJavaScriptChallengeRule, + UnionMember2RuleLogRule, + UnionMember2RuleLogCustomFieldRule, + UnionMember2RuleManagedChallengeRule, + UnionMember2RuleRedirectRule, + UnionMember2RuleRewriteRule, + UnionMember2RuleRouteRule, + UnionMember2RuleScoreRule, + UnionMember2RuleServeErrorRule, + UnionMember2RuleSetCacheControlRule, + UnionMember2RuleSetCacheSettingsRule, + UnionMember2RuleSetCacheTagsRule, + UnionMember2RuleSetConfigurationRule, + UnionMember2RuleSkipRule, + UnionMember2RuleTransformResponseHTMLRule, +] + + +class UnionMember2(BaseModel): + id: Optional[str] = None + """The unique ID of the ruleset.""" + + description: Optional[str] = None + """An informative description of the ruleset.""" + + kind: Optional[Kind] = None + """The kind of the ruleset.""" + + last_updated: Optional[datetime] = None + """The timestamp of when the ruleset was last modified.""" + + name: Optional[str] = None + """The human-readable name of the ruleset.""" + + phase: Optional[Phase] = None + """The phase of the ruleset.""" + + rules: Optional[List[UnionMember2Rule]] = None + """The list of rules in the ruleset.""" + + version: Optional[str] = None + """The version of the ruleset.""" + + +class UnionMember3RuleBlockRule(BlockRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember3RuleChallengeRuleExposedCredentialCheck(BaseModel): + """Configuration for exposed credential checking.""" + + password_expression: str + """An expression that selects the password used in the credentials check.""" + + username_expression: str + """An expression that selects the user ID used in the credentials check.""" + + +class UnionMember3RuleChallengeRuleRatelimit(BaseModel): + """An object configuring the rule's rate limit behavior.""" + + characteristics: List[str] + """ + Characteristics of the request on which the rate limit counter will be + incremented. + """ + + period: int + """Period in seconds over which the counter is being incremented.""" + + counting_expression: Optional[str] = None + """An expression that defines when the rate limit counter should be incremented. + + It defaults to the same as the rule's expression. + """ + + mitigation_timeout: Optional[int] = None + """ + Period of time in seconds after which the action will be disabled following its + first execution. + """ + + requests_per_period: Optional[int] = None + """ + The threshold of requests per period after which the action will be executed for + the first time. + """ + + requests_to_origin: Optional[bool] = None + """Whether counting is only performed when an origin is reached.""" + + score_per_period: Optional[int] = None + """ + The score threshold per period for which the action will be executed the first + time. + """ + + score_response_header_name: Optional[str] = None + """ + A response header name provided by the origin, which contains the score to + increment rate limit counter with. + """ + + +class UnionMember3RuleChallengeRule(BaseModel): + id: str + """The unique ID of the rule.""" + + action: Literal["challenge"] + """The action to perform when the rule matches.""" + + enabled: bool + """Whether the rule should be executed.""" + + expression: str + """The expression defining which traffic will match the rule.""" + + last_updated: datetime + """The timestamp of when the rule was last modified.""" + + ref: str + """The reference of the rule (the rule's ID by default).""" + + version: str + """The version of the rule.""" + + action_parameters: Optional[object] = None + """The parameters configuring the rule's action.""" + + categories: Optional[List[str]] = None + """The categories of the rule.""" + + description: Optional[str] = None + """An informative description of the rule.""" + + exposed_credential_check: Optional[UnionMember3RuleChallengeRuleExposedCredentialCheck] = None + """Configuration for exposed credential checking.""" + + logging: Optional[Logging] = None + """An object configuring the rule's logging behavior.""" + + ratelimit: Optional[UnionMember3RuleChallengeRuleRatelimit] = None + """An object configuring the rule's rate limit behavior.""" + + +class UnionMember3RuleResponseCompressionRule(CompressResponseRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember3RuleDDoSDynamicRule(DDoSDynamicRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember3RuleExecuteRule(ExecuteRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember3RuleForceConnectionCloseRule(ForceConnectionCloseRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember3RuleJavaScriptChallengeRuleExposedCredentialCheck(BaseModel): + """Configuration for exposed credential checking.""" + + password_expression: str + """An expression that selects the password used in the credentials check.""" + + username_expression: str + """An expression that selects the user ID used in the credentials check.""" + + +class UnionMember3RuleJavaScriptChallengeRuleRatelimit(BaseModel): + """An object configuring the rule's rate limit behavior.""" + + characteristics: List[str] + """ + Characteristics of the request on which the rate limit counter will be + incremented. + """ + + period: int + """Period in seconds over which the counter is being incremented.""" + + counting_expression: Optional[str] = None + """An expression that defines when the rate limit counter should be incremented. + + It defaults to the same as the rule's expression. + """ + + mitigation_timeout: Optional[int] = None + """ + Period of time in seconds after which the action will be disabled following its + first execution. + """ + + requests_per_period: Optional[int] = None + """ + The threshold of requests per period after which the action will be executed for + the first time. + """ + + requests_to_origin: Optional[bool] = None + """Whether counting is only performed when an origin is reached.""" + + score_per_period: Optional[int] = None + """ + The score threshold per period for which the action will be executed the first + time. + """ + + score_response_header_name: Optional[str] = None + """ + A response header name provided by the origin, which contains the score to + increment rate limit counter with. + """ + + +class UnionMember3RuleJavaScriptChallengeRule(BaseModel): + id: str + """The unique ID of the rule.""" + + action: Literal["js_challenge"] + """The action to perform when the rule matches.""" + + enabled: bool + """Whether the rule should be executed.""" + + expression: str + """The expression defining which traffic will match the rule.""" + + last_updated: datetime + """The timestamp of when the rule was last modified.""" + + ref: str + """The reference of the rule (the rule's ID by default).""" + + version: str + """The version of the rule.""" + + action_parameters: Optional[object] = None + """The parameters configuring the rule's action.""" + + categories: Optional[List[str]] = None + """The categories of the rule.""" + + description: Optional[str] = None + """An informative description of the rule.""" + + exposed_credential_check: Optional[UnionMember3RuleJavaScriptChallengeRuleExposedCredentialCheck] = None + """Configuration for exposed credential checking.""" + + logging: Optional[Logging] = None + """An object configuring the rule's logging behavior.""" + + ratelimit: Optional[UnionMember3RuleJavaScriptChallengeRuleRatelimit] = None + """An object configuring the rule's rate limit behavior.""" + + +class UnionMember3RuleLogRule(LogRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember3RuleLogCustomFieldRule(LogCustomFieldRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember3RuleManagedChallengeRule(ManagedChallengeRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember3RuleRedirectRule(RedirectRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember3RuleRewriteRule(RewriteRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember3RuleRouteRule(RouteRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember3RuleScoreRule(ScoreRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember3RuleServeErrorRule(ServeErrorRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember3RuleSetCacheControlRuleActionParametersImmutableSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember3RuleSetCacheControlRuleActionParametersImmutableRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember3RuleSetCacheControlRuleActionParametersImmutable: TypeAlias = Union[ + UnionMember3RuleSetCacheControlRuleActionParametersImmutableSetDirective, + UnionMember3RuleSetCacheControlRuleActionParametersImmutableRemoveDirective, +] + + +class UnionMember3RuleSetCacheControlRuleActionParametersMaxAgeSetDirective(BaseModel): + """Set the directive with a duration value in seconds.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + value: int + """The duration value in seconds for the directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember3RuleSetCacheControlRuleActionParametersMaxAgeRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember3RuleSetCacheControlRuleActionParametersMaxAge: TypeAlias = Union[ + UnionMember3RuleSetCacheControlRuleActionParametersMaxAgeSetDirective, + UnionMember3RuleSetCacheControlRuleActionParametersMaxAgeRemoveDirective, +] + + +class UnionMember3RuleSetCacheControlRuleActionParametersMustRevalidateSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember3RuleSetCacheControlRuleActionParametersMustRevalidateRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember3RuleSetCacheControlRuleActionParametersMustRevalidate: TypeAlias = Union[ + UnionMember3RuleSetCacheControlRuleActionParametersMustRevalidateSetDirective, + UnionMember3RuleSetCacheControlRuleActionParametersMustRevalidateRemoveDirective, +] + + +class UnionMember3RuleSetCacheControlRuleActionParametersMustUnderstandSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember3RuleSetCacheControlRuleActionParametersMustUnderstandRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember3RuleSetCacheControlRuleActionParametersMustUnderstand: TypeAlias = Union[ + UnionMember3RuleSetCacheControlRuleActionParametersMustUnderstandSetDirective, + UnionMember3RuleSetCacheControlRuleActionParametersMustUnderstandRemoveDirective, +] + + +class UnionMember3RuleSetCacheControlRuleActionParametersNoCacheSetDirective(BaseModel): + """Set the directive with optional qualifiers.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + qualifiers: Optional[List[str]] = None + """ + Optional list of header names to qualify the directive (e.g., for "private" or + "no-cache" directives). + """ + + +class UnionMember3RuleSetCacheControlRuleActionParametersNoCacheRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember3RuleSetCacheControlRuleActionParametersNoCache: TypeAlias = Union[ + UnionMember3RuleSetCacheControlRuleActionParametersNoCacheSetDirective, + UnionMember3RuleSetCacheControlRuleActionParametersNoCacheRemoveDirective, +] + + +class UnionMember3RuleSetCacheControlRuleActionParametersNoStoreSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember3RuleSetCacheControlRuleActionParametersNoStoreRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember3RuleSetCacheControlRuleActionParametersNoStore: TypeAlias = Union[ + UnionMember3RuleSetCacheControlRuleActionParametersNoStoreSetDirective, + UnionMember3RuleSetCacheControlRuleActionParametersNoStoreRemoveDirective, +] + + +class UnionMember3RuleSetCacheControlRuleActionParametersNoTransformSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember3RuleSetCacheControlRuleActionParametersNoTransformRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember3RuleSetCacheControlRuleActionParametersNoTransform: TypeAlias = Union[ + UnionMember3RuleSetCacheControlRuleActionParametersNoTransformSetDirective, + UnionMember3RuleSetCacheControlRuleActionParametersNoTransformRemoveDirective, +] + + +class UnionMember3RuleSetCacheControlRuleActionParametersPrivateSetDirective(BaseModel): + """Set the directive with optional qualifiers.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + qualifiers: Optional[List[str]] = None + """ + Optional list of header names to qualify the directive (e.g., for "private" or + "no-cache" directives). + """ + + +class UnionMember3RuleSetCacheControlRuleActionParametersPrivateRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember3RuleSetCacheControlRuleActionParametersPrivate: TypeAlias = Union[ + UnionMember3RuleSetCacheControlRuleActionParametersPrivateSetDirective, + UnionMember3RuleSetCacheControlRuleActionParametersPrivateRemoveDirective, +] + + +class UnionMember3RuleSetCacheControlRuleActionParametersProxyRevalidateSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember3RuleSetCacheControlRuleActionParametersProxyRevalidateRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember3RuleSetCacheControlRuleActionParametersProxyRevalidate: TypeAlias = Union[ + UnionMember3RuleSetCacheControlRuleActionParametersProxyRevalidateSetDirective, + UnionMember3RuleSetCacheControlRuleActionParametersProxyRevalidateRemoveDirective, +] + + +class UnionMember3RuleSetCacheControlRuleActionParametersPublicSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember3RuleSetCacheControlRuleActionParametersPublicRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember3RuleSetCacheControlRuleActionParametersPublic: TypeAlias = Union[ + UnionMember3RuleSetCacheControlRuleActionParametersPublicSetDirective, + UnionMember3RuleSetCacheControlRuleActionParametersPublicRemoveDirective, +] + + +class UnionMember3RuleSetCacheControlRuleActionParametersSMaxageSetDirective(BaseModel): + """Set the directive with a duration value in seconds.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + value: int + """The duration value in seconds for the directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember3RuleSetCacheControlRuleActionParametersSMaxageRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember3RuleSetCacheControlRuleActionParametersSMaxage: TypeAlias = Union[ + UnionMember3RuleSetCacheControlRuleActionParametersSMaxageSetDirective, + UnionMember3RuleSetCacheControlRuleActionParametersSMaxageRemoveDirective, +] + + +class UnionMember3RuleSetCacheControlRuleActionParametersStaleIfErrorSetDirective(BaseModel): + """Set the directive with a duration value in seconds.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + value: int + """The duration value in seconds for the directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember3RuleSetCacheControlRuleActionParametersStaleIfErrorRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember3RuleSetCacheControlRuleActionParametersStaleIfError: TypeAlias = Union[ + UnionMember3RuleSetCacheControlRuleActionParametersStaleIfErrorSetDirective, + UnionMember3RuleSetCacheControlRuleActionParametersStaleIfErrorRemoveDirective, +] + + +class UnionMember3RuleSetCacheControlRuleActionParametersStaleWhileRevalidateSetDirective(BaseModel): + """Set the directive with a duration value in seconds.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + value: int + """The duration value in seconds for the directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember3RuleSetCacheControlRuleActionParametersStaleWhileRevalidateRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember3RuleSetCacheControlRuleActionParametersStaleWhileRevalidate: TypeAlias = Union[ + UnionMember3RuleSetCacheControlRuleActionParametersStaleWhileRevalidateSetDirective, + UnionMember3RuleSetCacheControlRuleActionParametersStaleWhileRevalidateRemoveDirective, +] + + +class UnionMember3RuleSetCacheControlRuleActionParameters(BaseModel): + """The parameters configuring the rule's action.""" + + immutable: Optional[UnionMember3RuleSetCacheControlRuleActionParametersImmutable] = None + """A cache-control directive configuration.""" + + max_age: Optional[UnionMember3RuleSetCacheControlRuleActionParametersMaxAge] = FieldInfo( + alias="max-age", default=None + ) + """ + A cache-control directive configuration that accepts a duration value in + seconds. + """ + + must_revalidate: Optional[UnionMember3RuleSetCacheControlRuleActionParametersMustRevalidate] = FieldInfo( + alias="must-revalidate", default=None + ) + """A cache-control directive configuration.""" + + must_understand: Optional[UnionMember3RuleSetCacheControlRuleActionParametersMustUnderstand] = FieldInfo( + alias="must-understand", default=None + ) + """A cache-control directive configuration.""" + + no_cache: Optional[UnionMember3RuleSetCacheControlRuleActionParametersNoCache] = FieldInfo( + alias="no-cache", default=None + ) + """ + A cache-control directive configuration that accepts optional qualifiers (header + names). + """ + + no_store: Optional[UnionMember3RuleSetCacheControlRuleActionParametersNoStore] = FieldInfo( + alias="no-store", default=None + ) + """A cache-control directive configuration.""" + + no_transform: Optional[UnionMember3RuleSetCacheControlRuleActionParametersNoTransform] = FieldInfo( + alias="no-transform", default=None + ) + """A cache-control directive configuration.""" + + private: Optional[UnionMember3RuleSetCacheControlRuleActionParametersPrivate] = None + """ + A cache-control directive configuration that accepts optional qualifiers (header + names). + """ + + proxy_revalidate: Optional[UnionMember3RuleSetCacheControlRuleActionParametersProxyRevalidate] = FieldInfo( + alias="proxy-revalidate", default=None + ) + """A cache-control directive configuration.""" + + public: Optional[UnionMember3RuleSetCacheControlRuleActionParametersPublic] = None + """A cache-control directive configuration.""" + + s_maxage: Optional[UnionMember3RuleSetCacheControlRuleActionParametersSMaxage] = FieldInfo( + alias="s-maxage", default=None + ) + """ + A cache-control directive configuration that accepts a duration value in + seconds. + """ + + stale_if_error: Optional[UnionMember3RuleSetCacheControlRuleActionParametersStaleIfError] = FieldInfo( + alias="stale-if-error", default=None + ) + """ + A cache-control directive configuration that accepts a duration value in + seconds. + """ + + stale_while_revalidate: Optional[UnionMember3RuleSetCacheControlRuleActionParametersStaleWhileRevalidate] = ( + FieldInfo(alias="stale-while-revalidate", default=None) + ) + """ + A cache-control directive configuration that accepts a duration value in + seconds. + """ + + +class UnionMember3RuleSetCacheControlRuleExposedCredentialCheck(BaseModel): + """Configuration for exposed credential checking.""" + + password_expression: str + """An expression that selects the password used in the credentials check.""" + + username_expression: str + """An expression that selects the user ID used in the credentials check.""" + + +class UnionMember3RuleSetCacheControlRuleRatelimit(BaseModel): + """An object configuring the rule's rate limit behavior.""" + + characteristics: List[str] + """ + Characteristics of the request on which the rate limit counter will be + incremented. + """ + + period: int + """Period in seconds over which the counter is being incremented.""" + + counting_expression: Optional[str] = None + """An expression that defines when the rate limit counter should be incremented. + + It defaults to the same as the rule's expression. + """ + + mitigation_timeout: Optional[int] = None + """ + Period of time in seconds after which the action will be disabled following its + first execution. + """ + + requests_per_period: Optional[int] = None + """ + The threshold of requests per period after which the action will be executed for + the first time. + """ + + requests_to_origin: Optional[bool] = None + """Whether counting is only performed when an origin is reached.""" + + score_per_period: Optional[int] = None + """ + The score threshold per period for which the action will be executed the first + time. + """ + + score_response_header_name: Optional[str] = None + """ + A response header name provided by the origin, which contains the score to + increment rate limit counter with. + """ + + +class UnionMember3RuleSetCacheControlRule(BaseModel): + id: str + """The unique ID of the rule.""" + + action: Literal["set_cache_control"] + """The action to perform when the rule matches.""" + + enabled: bool + + expression: str + """The expression defining which traffic will match the rule.""" + + last_updated: datetime + """The timestamp of when the rule was last modified.""" + + ref: str + """The reference of the rule (the rule's ID by default).""" + + version: str + """The version of the rule.""" + + action_parameters: Optional[UnionMember3RuleSetCacheControlRuleActionParameters] = None + """The parameters configuring the rule's action.""" + + categories: Optional[List[str]] = None + """The categories of the rule.""" + + description: Optional[str] = None + """An informative description of the rule.""" + + exposed_credential_check: Optional[UnionMember3RuleSetCacheControlRuleExposedCredentialCheck] = None + """Configuration for exposed credential checking.""" + + logging: Optional[Logging] = None + """An object configuring the rule's logging behavior.""" + + ratelimit: Optional[UnionMember3RuleSetCacheControlRuleRatelimit] = None + """An object configuring the rule's rate limit behavior.""" + + +class UnionMember3RuleSetCacheSettingsRule(SetCacheSettingsRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember3RuleSetCacheTagsRuleActionParametersAddCacheTagsValues(BaseModel): + """Add cache tags using a list of values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + values: List[str] + """A list of cache tag values.""" + + +class UnionMember3RuleSetCacheTagsRuleActionParametersAddCacheTagsExpression(BaseModel): + """Add cache tags using an expression.""" + + expression: str + """An expression that evaluates to an array of cache tag values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + +class UnionMember3RuleSetCacheTagsRuleActionParametersRemoveCacheTagsValues(BaseModel): + """Remove cache tags using a list of values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + values: List[str] + """A list of cache tag values.""" + + +class UnionMember3RuleSetCacheTagsRuleActionParametersRemoveCacheTagsExpression(BaseModel): + """Remove cache tags using an expression.""" + + expression: str + """An expression that evaluates to an array of cache tag values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + +class UnionMember3RuleSetCacheTagsRuleActionParametersSetCacheTagsValues(BaseModel): + """Set cache tags using a list of values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + values: List[str] + """A list of cache tag values.""" + + +class UnionMember3RuleSetCacheTagsRuleActionParametersSetCacheTagsExpression(BaseModel): + """Set cache tags using an expression.""" + + expression: str + """An expression that evaluates to an array of cache tag values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + +UnionMember3RuleSetCacheTagsRuleActionParameters: TypeAlias = Union[ + UnionMember3RuleSetCacheTagsRuleActionParametersAddCacheTagsValues, + UnionMember3RuleSetCacheTagsRuleActionParametersAddCacheTagsExpression, + UnionMember3RuleSetCacheTagsRuleActionParametersRemoveCacheTagsValues, + UnionMember3RuleSetCacheTagsRuleActionParametersRemoveCacheTagsExpression, + UnionMember3RuleSetCacheTagsRuleActionParametersSetCacheTagsValues, + UnionMember3RuleSetCacheTagsRuleActionParametersSetCacheTagsExpression, +] + + +class UnionMember3RuleSetCacheTagsRuleExposedCredentialCheck(BaseModel): + """Configuration for exposed credential checking.""" + + password_expression: str + """An expression that selects the password used in the credentials check.""" + + username_expression: str + """An expression that selects the user ID used in the credentials check.""" + + +class UnionMember3RuleSetCacheTagsRuleRatelimit(BaseModel): + """An object configuring the rule's rate limit behavior.""" + + characteristics: List[str] + """ + Characteristics of the request on which the rate limit counter will be + incremented. + """ + + period: int + """Period in seconds over which the counter is being incremented.""" + + counting_expression: Optional[str] = None + """An expression that defines when the rate limit counter should be incremented. + + It defaults to the same as the rule's expression. + """ + + mitigation_timeout: Optional[int] = None + """ + Period of time in seconds after which the action will be disabled following its + first execution. + """ + + requests_per_period: Optional[int] = None + """ + The threshold of requests per period after which the action will be executed for + the first time. + """ + + requests_to_origin: Optional[bool] = None + """Whether counting is only performed when an origin is reached.""" + + score_per_period: Optional[int] = None + """ + The score threshold per period for which the action will be executed the first + time. + """ + + score_response_header_name: Optional[str] = None + """ + A response header name provided by the origin, which contains the score to + increment rate limit counter with. + """ + + +class UnionMember3RuleSetCacheTagsRule(BaseModel): + id: str + """The unique ID of the rule.""" + + action: Literal["set_cache_tags"] + """The action to perform when the rule matches.""" + + enabled: bool + + expression: str + """The expression defining which traffic will match the rule.""" + + last_updated: datetime + """The timestamp of when the rule was last modified.""" + + ref: str + """The reference of the rule (the rule's ID by default).""" + + version: str + """The version of the rule.""" + + action_parameters: Optional[UnionMember3RuleSetCacheTagsRuleActionParameters] = None + """The parameters configuring the rule's action.""" + + categories: Optional[List[str]] = None + """The categories of the rule.""" + + description: Optional[str] = None + """An informative description of the rule.""" + + exposed_credential_check: Optional[UnionMember3RuleSetCacheTagsRuleExposedCredentialCheck] = None + """Configuration for exposed credential checking.""" + + logging: Optional[Logging] = None + """An object configuring the rule's logging behavior.""" + + ratelimit: Optional[UnionMember3RuleSetCacheTagsRuleRatelimit] = None + """An object configuring the rule's rate limit behavior.""" + + +class UnionMember3RuleSetConfigurationRule(SetConfigRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember3RuleSkipRule(SkipRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember3RuleTransformResponseHTMLRuleActionParameters(BaseModel): + """The parameters configuring the rule's action.""" + + link_maze: object + """Enables the link maze transformation on the response.""" + + +class UnionMember3RuleTransformResponseHTMLRuleExposedCredentialCheck(BaseModel): + """Configuration for exposed credential checking.""" + + password_expression: str + """An expression that selects the password used in the credentials check.""" + + username_expression: str + """An expression that selects the user ID used in the credentials check.""" + + +class UnionMember3RuleTransformResponseHTMLRuleRatelimit(BaseModel): + """An object configuring the rule's rate limit behavior.""" + + characteristics: List[str] + """ + Characteristics of the request on which the rate limit counter will be + incremented. + """ + + period: int + """Period in seconds over which the counter is being incremented.""" + + counting_expression: Optional[str] = None + """An expression that defines when the rate limit counter should be incremented. + + It defaults to the same as the rule's expression. + """ + + mitigation_timeout: Optional[int] = None + """ + Period of time in seconds after which the action will be disabled following its + first execution. + """ + + requests_per_period: Optional[int] = None + """ + The threshold of requests per period after which the action will be executed for + the first time. + """ + + requests_to_origin: Optional[bool] = None + """Whether counting is only performed when an origin is reached.""" + + score_per_period: Optional[int] = None + """ + The score threshold per period for which the action will be executed the first + time. + """ + + score_response_header_name: Optional[str] = None + """ + A response header name provided by the origin, which contains the score to + increment rate limit counter with. + """ + + +class UnionMember3RuleTransformResponseHTMLRule(BaseModel): + id: str + """The unique ID of the rule.""" + + action: Literal["transform_response_html"] + """The action to perform when the rule matches.""" + + enabled: bool + + expression: str + """The expression defining which traffic will match the rule.""" + + last_updated: datetime + """The timestamp of when the rule was last modified.""" + + ref: str + """The reference of the rule (the rule's ID by default).""" + + version: str + """The version of the rule.""" + + action_parameters: Optional[UnionMember3RuleTransformResponseHTMLRuleActionParameters] = None + """The parameters configuring the rule's action.""" + + categories: Optional[List[str]] = None + """The categories of the rule.""" + + description: Optional[str] = None + """An informative description of the rule.""" + + exposed_credential_check: Optional[UnionMember3RuleTransformResponseHTMLRuleExposedCredentialCheck] = None + """Configuration for exposed credential checking.""" + + logging: Optional[Logging] = None + """An object configuring the rule's logging behavior.""" + + ratelimit: Optional[UnionMember3RuleTransformResponseHTMLRuleRatelimit] = None + """An object configuring the rule's rate limit behavior.""" + + +UnionMember3Rule: TypeAlias = Union[ + UnionMember3RuleBlockRule, + UnionMember3RuleChallengeRule, + UnionMember3RuleResponseCompressionRule, + UnionMember3RuleDDoSDynamicRule, + UnionMember3RuleExecuteRule, + UnionMember3RuleForceConnectionCloseRule, + UnionMember3RuleJavaScriptChallengeRule, + UnionMember3RuleLogRule, + UnionMember3RuleLogCustomFieldRule, + UnionMember3RuleManagedChallengeRule, + UnionMember3RuleRedirectRule, + UnionMember3RuleRewriteRule, + UnionMember3RuleRouteRule, + UnionMember3RuleScoreRule, + UnionMember3RuleServeErrorRule, + UnionMember3RuleSetCacheControlRule, + UnionMember3RuleSetCacheSettingsRule, + UnionMember3RuleSetCacheTagsRule, + UnionMember3RuleSetConfigurationRule, + UnionMember3RuleSkipRule, + UnionMember3RuleTransformResponseHTMLRule, +] + + +class UnionMember3(BaseModel): + id: Optional[str] = None + """The unique ID of the ruleset.""" + + description: Optional[str] = None + """An informative description of the ruleset.""" + + kind: Optional[Kind] = None + """The kind of the ruleset.""" + + last_updated: Optional[datetime] = None + """The timestamp of when the ruleset was last modified.""" + + name: Optional[str] = None + """The human-readable name of the ruleset.""" + + phase: Optional[Phase] = None + """The phase of the ruleset.""" + + rules: Optional[List[UnionMember3Rule]] = None + """The list of rules in the ruleset.""" + + version: Optional[str] = None + """The version of the ruleset.""" + + +class UnionMember4RuleBlockRule(BlockRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember4RuleChallengeRuleExposedCredentialCheck(BaseModel): + """Configuration for exposed credential checking.""" + + password_expression: str + """An expression that selects the password used in the credentials check.""" + + username_expression: str + """An expression that selects the user ID used in the credentials check.""" + + +class UnionMember4RuleChallengeRuleRatelimit(BaseModel): + """An object configuring the rule's rate limit behavior.""" + + characteristics: List[str] + """ + Characteristics of the request on which the rate limit counter will be + incremented. + """ + + period: int + """Period in seconds over which the counter is being incremented.""" + + counting_expression: Optional[str] = None + """An expression that defines when the rate limit counter should be incremented. + + It defaults to the same as the rule's expression. + """ + + mitigation_timeout: Optional[int] = None + """ + Period of time in seconds after which the action will be disabled following its + first execution. + """ + + requests_per_period: Optional[int] = None + """ + The threshold of requests per period after which the action will be executed for + the first time. + """ + + requests_to_origin: Optional[bool] = None + """Whether counting is only performed when an origin is reached.""" + + score_per_period: Optional[int] = None + """ + The score threshold per period for which the action will be executed the first + time. + """ + + score_response_header_name: Optional[str] = None + """ + A response header name provided by the origin, which contains the score to + increment rate limit counter with. + """ + + +class UnionMember4RuleChallengeRule(BaseModel): + id: str + """The unique ID of the rule.""" + + action: Literal["challenge"] + """The action to perform when the rule matches.""" + + enabled: bool + """Whether the rule should be executed.""" + + expression: str + """The expression defining which traffic will match the rule.""" + + last_updated: datetime + """The timestamp of when the rule was last modified.""" + + ref: str + """The reference of the rule (the rule's ID by default).""" + + version: str + """The version of the rule.""" + + action_parameters: Optional[object] = None + """The parameters configuring the rule's action.""" + + categories: Optional[List[str]] = None + """The categories of the rule.""" + + description: Optional[str] = None + """An informative description of the rule.""" + + exposed_credential_check: Optional[UnionMember4RuleChallengeRuleExposedCredentialCheck] = None + """Configuration for exposed credential checking.""" + + logging: Optional[Logging] = None + """An object configuring the rule's logging behavior.""" + + ratelimit: Optional[UnionMember4RuleChallengeRuleRatelimit] = None + """An object configuring the rule's rate limit behavior.""" + + +class UnionMember4RuleResponseCompressionRule(CompressResponseRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember4RuleDDoSDynamicRule(DDoSDynamicRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember4RuleExecuteRule(ExecuteRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember4RuleForceConnectionCloseRule(ForceConnectionCloseRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember4RuleJavaScriptChallengeRuleExposedCredentialCheck(BaseModel): + """Configuration for exposed credential checking.""" + + password_expression: str + """An expression that selects the password used in the credentials check.""" + + username_expression: str + """An expression that selects the user ID used in the credentials check.""" + + +class UnionMember4RuleJavaScriptChallengeRuleRatelimit(BaseModel): + """An object configuring the rule's rate limit behavior.""" + + characteristics: List[str] + """ + Characteristics of the request on which the rate limit counter will be + incremented. + """ + + period: int + """Period in seconds over which the counter is being incremented.""" + + counting_expression: Optional[str] = None + """An expression that defines when the rate limit counter should be incremented. + + It defaults to the same as the rule's expression. + """ + + mitigation_timeout: Optional[int] = None + """ + Period of time in seconds after which the action will be disabled following its + first execution. + """ + + requests_per_period: Optional[int] = None + """ + The threshold of requests per period after which the action will be executed for + the first time. + """ + + requests_to_origin: Optional[bool] = None + """Whether counting is only performed when an origin is reached.""" + + score_per_period: Optional[int] = None + """ + The score threshold per period for which the action will be executed the first + time. + """ + + score_response_header_name: Optional[str] = None + """ + A response header name provided by the origin, which contains the score to + increment rate limit counter with. + """ + + +class UnionMember4RuleJavaScriptChallengeRule(BaseModel): + id: str + """The unique ID of the rule.""" + + action: Literal["js_challenge"] + """The action to perform when the rule matches.""" + + enabled: bool + """Whether the rule should be executed.""" + + expression: str + """The expression defining which traffic will match the rule.""" + + last_updated: datetime + """The timestamp of when the rule was last modified.""" + + ref: str + """The reference of the rule (the rule's ID by default).""" + + version: str + """The version of the rule.""" + + action_parameters: Optional[object] = None + """The parameters configuring the rule's action.""" + + categories: Optional[List[str]] = None + """The categories of the rule.""" + + description: Optional[str] = None + """An informative description of the rule.""" + + exposed_credential_check: Optional[UnionMember4RuleJavaScriptChallengeRuleExposedCredentialCheck] = None + """Configuration for exposed credential checking.""" + + logging: Optional[Logging] = None + """An object configuring the rule's logging behavior.""" + + ratelimit: Optional[UnionMember4RuleJavaScriptChallengeRuleRatelimit] = None + """An object configuring the rule's rate limit behavior.""" + + +class UnionMember4RuleLogRule(LogRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember4RuleLogCustomFieldRule(LogCustomFieldRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember4RuleManagedChallengeRule(ManagedChallengeRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember4RuleRedirectRule(RedirectRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember4RuleRewriteRule(RewriteRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember4RuleRouteRule(RouteRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember4RuleScoreRule(ScoreRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember4RuleServeErrorRule(ServeErrorRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember4RuleSetCacheControlRuleActionParametersImmutableSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember4RuleSetCacheControlRuleActionParametersImmutableRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember4RuleSetCacheControlRuleActionParametersImmutable: TypeAlias = Union[ + UnionMember4RuleSetCacheControlRuleActionParametersImmutableSetDirective, + UnionMember4RuleSetCacheControlRuleActionParametersImmutableRemoveDirective, +] + + +class UnionMember4RuleSetCacheControlRuleActionParametersMaxAgeSetDirective(BaseModel): + """Set the directive with a duration value in seconds.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + value: int + """The duration value in seconds for the directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember4RuleSetCacheControlRuleActionParametersMaxAgeRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember4RuleSetCacheControlRuleActionParametersMaxAge: TypeAlias = Union[ + UnionMember4RuleSetCacheControlRuleActionParametersMaxAgeSetDirective, + UnionMember4RuleSetCacheControlRuleActionParametersMaxAgeRemoveDirective, +] + + +class UnionMember4RuleSetCacheControlRuleActionParametersMustRevalidateSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember4RuleSetCacheControlRuleActionParametersMustRevalidateRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember4RuleSetCacheControlRuleActionParametersMustRevalidate: TypeAlias = Union[ + UnionMember4RuleSetCacheControlRuleActionParametersMustRevalidateSetDirective, + UnionMember4RuleSetCacheControlRuleActionParametersMustRevalidateRemoveDirective, +] + + +class UnionMember4RuleSetCacheControlRuleActionParametersMustUnderstandSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember4RuleSetCacheControlRuleActionParametersMustUnderstandRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember4RuleSetCacheControlRuleActionParametersMustUnderstand: TypeAlias = Union[ + UnionMember4RuleSetCacheControlRuleActionParametersMustUnderstandSetDirective, + UnionMember4RuleSetCacheControlRuleActionParametersMustUnderstandRemoveDirective, +] + + +class UnionMember4RuleSetCacheControlRuleActionParametersNoCacheSetDirective(BaseModel): + """Set the directive with optional qualifiers.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + qualifiers: Optional[List[str]] = None + """ + Optional list of header names to qualify the directive (e.g., for "private" or + "no-cache" directives). + """ + + +class UnionMember4RuleSetCacheControlRuleActionParametersNoCacheRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember4RuleSetCacheControlRuleActionParametersNoCache: TypeAlias = Union[ + UnionMember4RuleSetCacheControlRuleActionParametersNoCacheSetDirective, + UnionMember4RuleSetCacheControlRuleActionParametersNoCacheRemoveDirective, +] + + +class UnionMember4RuleSetCacheControlRuleActionParametersNoStoreSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember4RuleSetCacheControlRuleActionParametersNoStoreRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember4RuleSetCacheControlRuleActionParametersNoStore: TypeAlias = Union[ + UnionMember4RuleSetCacheControlRuleActionParametersNoStoreSetDirective, + UnionMember4RuleSetCacheControlRuleActionParametersNoStoreRemoveDirective, +] + + +class UnionMember4RuleSetCacheControlRuleActionParametersNoTransformSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember4RuleSetCacheControlRuleActionParametersNoTransformRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember4RuleSetCacheControlRuleActionParametersNoTransform: TypeAlias = Union[ + UnionMember4RuleSetCacheControlRuleActionParametersNoTransformSetDirective, + UnionMember4RuleSetCacheControlRuleActionParametersNoTransformRemoveDirective, +] + + +class UnionMember4RuleSetCacheControlRuleActionParametersPrivateSetDirective(BaseModel): + """Set the directive with optional qualifiers.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + qualifiers: Optional[List[str]] = None + """ + Optional list of header names to qualify the directive (e.g., for "private" or + "no-cache" directives). + """ + + +class UnionMember4RuleSetCacheControlRuleActionParametersPrivateRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember4RuleSetCacheControlRuleActionParametersPrivate: TypeAlias = Union[ + UnionMember4RuleSetCacheControlRuleActionParametersPrivateSetDirective, + UnionMember4RuleSetCacheControlRuleActionParametersPrivateRemoveDirective, +] + + +class UnionMember4RuleSetCacheControlRuleActionParametersProxyRevalidateSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember4RuleSetCacheControlRuleActionParametersProxyRevalidateRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember4RuleSetCacheControlRuleActionParametersProxyRevalidate: TypeAlias = Union[ + UnionMember4RuleSetCacheControlRuleActionParametersProxyRevalidateSetDirective, + UnionMember4RuleSetCacheControlRuleActionParametersProxyRevalidateRemoveDirective, +] + + +class UnionMember4RuleSetCacheControlRuleActionParametersPublicSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember4RuleSetCacheControlRuleActionParametersPublicRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember4RuleSetCacheControlRuleActionParametersPublic: TypeAlias = Union[ + UnionMember4RuleSetCacheControlRuleActionParametersPublicSetDirective, + UnionMember4RuleSetCacheControlRuleActionParametersPublicRemoveDirective, +] + + +class UnionMember4RuleSetCacheControlRuleActionParametersSMaxageSetDirective(BaseModel): + """Set the directive with a duration value in seconds.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + value: int + """The duration value in seconds for the directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember4RuleSetCacheControlRuleActionParametersSMaxageRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember4RuleSetCacheControlRuleActionParametersSMaxage: TypeAlias = Union[ + UnionMember4RuleSetCacheControlRuleActionParametersSMaxageSetDirective, + UnionMember4RuleSetCacheControlRuleActionParametersSMaxageRemoveDirective, +] + + +class UnionMember4RuleSetCacheControlRuleActionParametersStaleIfErrorSetDirective(BaseModel): + """Set the directive with a duration value in seconds.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + value: int + """The duration value in seconds for the directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember4RuleSetCacheControlRuleActionParametersStaleIfErrorRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember4RuleSetCacheControlRuleActionParametersStaleIfError: TypeAlias = Union[ + UnionMember4RuleSetCacheControlRuleActionParametersStaleIfErrorSetDirective, + UnionMember4RuleSetCacheControlRuleActionParametersStaleIfErrorRemoveDirective, +] + + +class UnionMember4RuleSetCacheControlRuleActionParametersStaleWhileRevalidateSetDirective(BaseModel): + """Set the directive with a duration value in seconds.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + value: int + """The duration value in seconds for the directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember4RuleSetCacheControlRuleActionParametersStaleWhileRevalidateRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember4RuleSetCacheControlRuleActionParametersStaleWhileRevalidate: TypeAlias = Union[ + UnionMember4RuleSetCacheControlRuleActionParametersStaleWhileRevalidateSetDirective, + UnionMember4RuleSetCacheControlRuleActionParametersStaleWhileRevalidateRemoveDirective, +] + + +class UnionMember4RuleSetCacheControlRuleActionParameters(BaseModel): + """The parameters configuring the rule's action.""" + + immutable: Optional[UnionMember4RuleSetCacheControlRuleActionParametersImmutable] = None + """A cache-control directive configuration.""" + + max_age: Optional[UnionMember4RuleSetCacheControlRuleActionParametersMaxAge] = FieldInfo( + alias="max-age", default=None + ) + """ + A cache-control directive configuration that accepts a duration value in + seconds. + """ + + must_revalidate: Optional[UnionMember4RuleSetCacheControlRuleActionParametersMustRevalidate] = FieldInfo( + alias="must-revalidate", default=None + ) + """A cache-control directive configuration.""" + + must_understand: Optional[UnionMember4RuleSetCacheControlRuleActionParametersMustUnderstand] = FieldInfo( + alias="must-understand", default=None + ) + """A cache-control directive configuration.""" + + no_cache: Optional[UnionMember4RuleSetCacheControlRuleActionParametersNoCache] = FieldInfo( + alias="no-cache", default=None + ) + """ + A cache-control directive configuration that accepts optional qualifiers (header + names). + """ + + no_store: Optional[UnionMember4RuleSetCacheControlRuleActionParametersNoStore] = FieldInfo( + alias="no-store", default=None + ) + """A cache-control directive configuration.""" + + no_transform: Optional[UnionMember4RuleSetCacheControlRuleActionParametersNoTransform] = FieldInfo( + alias="no-transform", default=None + ) + """A cache-control directive configuration.""" + + private: Optional[UnionMember4RuleSetCacheControlRuleActionParametersPrivate] = None + """ + A cache-control directive configuration that accepts optional qualifiers (header + names). + """ + + proxy_revalidate: Optional[UnionMember4RuleSetCacheControlRuleActionParametersProxyRevalidate] = FieldInfo( + alias="proxy-revalidate", default=None + ) + """A cache-control directive configuration.""" + + public: Optional[UnionMember4RuleSetCacheControlRuleActionParametersPublic] = None + """A cache-control directive configuration.""" + + s_maxage: Optional[UnionMember4RuleSetCacheControlRuleActionParametersSMaxage] = FieldInfo( + alias="s-maxage", default=None + ) + """ + A cache-control directive configuration that accepts a duration value in + seconds. + """ + + stale_if_error: Optional[UnionMember4RuleSetCacheControlRuleActionParametersStaleIfError] = FieldInfo( + alias="stale-if-error", default=None + ) + """ + A cache-control directive configuration that accepts a duration value in + seconds. + """ + + stale_while_revalidate: Optional[UnionMember4RuleSetCacheControlRuleActionParametersStaleWhileRevalidate] = ( + FieldInfo(alias="stale-while-revalidate", default=None) + ) + """ + A cache-control directive configuration that accepts a duration value in + seconds. + """ + + +class UnionMember4RuleSetCacheControlRuleExposedCredentialCheck(BaseModel): + """Configuration for exposed credential checking.""" + + password_expression: str + """An expression that selects the password used in the credentials check.""" + + username_expression: str + """An expression that selects the user ID used in the credentials check.""" + + +class UnionMember4RuleSetCacheControlRuleRatelimit(BaseModel): + """An object configuring the rule's rate limit behavior.""" + + characteristics: List[str] + """ + Characteristics of the request on which the rate limit counter will be + incremented. + """ + + period: int + """Period in seconds over which the counter is being incremented.""" + + counting_expression: Optional[str] = None + """An expression that defines when the rate limit counter should be incremented. + + It defaults to the same as the rule's expression. + """ + + mitigation_timeout: Optional[int] = None + """ + Period of time in seconds after which the action will be disabled following its + first execution. + """ + + requests_per_period: Optional[int] = None + """ + The threshold of requests per period after which the action will be executed for + the first time. + """ + + requests_to_origin: Optional[bool] = None + """Whether counting is only performed when an origin is reached.""" + + score_per_period: Optional[int] = None + """ + The score threshold per period for which the action will be executed the first + time. + """ + + score_response_header_name: Optional[str] = None + """ + A response header name provided by the origin, which contains the score to + increment rate limit counter with. + """ + + +class UnionMember4RuleSetCacheControlRule(BaseModel): + id: str + """The unique ID of the rule.""" + + action: Literal["set_cache_control"] + """The action to perform when the rule matches.""" + + enabled: bool + + expression: str + """The expression defining which traffic will match the rule.""" + + last_updated: datetime + """The timestamp of when the rule was last modified.""" + + ref: str + """The reference of the rule (the rule's ID by default).""" + + version: str + """The version of the rule.""" + + action_parameters: Optional[UnionMember4RuleSetCacheControlRuleActionParameters] = None + """The parameters configuring the rule's action.""" + + categories: Optional[List[str]] = None + """The categories of the rule.""" + + description: Optional[str] = None + """An informative description of the rule.""" + + exposed_credential_check: Optional[UnionMember4RuleSetCacheControlRuleExposedCredentialCheck] = None + """Configuration for exposed credential checking.""" + + logging: Optional[Logging] = None + """An object configuring the rule's logging behavior.""" + + ratelimit: Optional[UnionMember4RuleSetCacheControlRuleRatelimit] = None + """An object configuring the rule's rate limit behavior.""" + + +class UnionMember4RuleSetCacheSettingsRule(SetCacheSettingsRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember4RuleSetCacheTagsRuleActionParametersAddCacheTagsValues(BaseModel): + """Add cache tags using a list of values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + values: List[str] + """A list of cache tag values.""" + + +class UnionMember4RuleSetCacheTagsRuleActionParametersAddCacheTagsExpression(BaseModel): + """Add cache tags using an expression.""" + + expression: str + """An expression that evaluates to an array of cache tag values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + +class UnionMember4RuleSetCacheTagsRuleActionParametersRemoveCacheTagsValues(BaseModel): + """Remove cache tags using a list of values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + values: List[str] + """A list of cache tag values.""" + + +class UnionMember4RuleSetCacheTagsRuleActionParametersRemoveCacheTagsExpression(BaseModel): + """Remove cache tags using an expression.""" + + expression: str + """An expression that evaluates to an array of cache tag values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + +class UnionMember4RuleSetCacheTagsRuleActionParametersSetCacheTagsValues(BaseModel): + """Set cache tags using a list of values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + values: List[str] + """A list of cache tag values.""" + + +class UnionMember4RuleSetCacheTagsRuleActionParametersSetCacheTagsExpression(BaseModel): + """Set cache tags using an expression.""" + + expression: str + """An expression that evaluates to an array of cache tag values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + +UnionMember4RuleSetCacheTagsRuleActionParameters: TypeAlias = Union[ + UnionMember4RuleSetCacheTagsRuleActionParametersAddCacheTagsValues, + UnionMember4RuleSetCacheTagsRuleActionParametersAddCacheTagsExpression, + UnionMember4RuleSetCacheTagsRuleActionParametersRemoveCacheTagsValues, + UnionMember4RuleSetCacheTagsRuleActionParametersRemoveCacheTagsExpression, + UnionMember4RuleSetCacheTagsRuleActionParametersSetCacheTagsValues, + UnionMember4RuleSetCacheTagsRuleActionParametersSetCacheTagsExpression, +] + + +class UnionMember4RuleSetCacheTagsRuleExposedCredentialCheck(BaseModel): + """Configuration for exposed credential checking.""" + + password_expression: str + """An expression that selects the password used in the credentials check.""" + + username_expression: str + """An expression that selects the user ID used in the credentials check.""" + + +class UnionMember4RuleSetCacheTagsRuleRatelimit(BaseModel): + """An object configuring the rule's rate limit behavior.""" + + characteristics: List[str] + """ + Characteristics of the request on which the rate limit counter will be + incremented. + """ + + period: int + """Period in seconds over which the counter is being incremented.""" + + counting_expression: Optional[str] = None + """An expression that defines when the rate limit counter should be incremented. + + It defaults to the same as the rule's expression. + """ + + mitigation_timeout: Optional[int] = None + """ + Period of time in seconds after which the action will be disabled following its + first execution. + """ + + requests_per_period: Optional[int] = None + """ + The threshold of requests per period after which the action will be executed for + the first time. + """ + + requests_to_origin: Optional[bool] = None + """Whether counting is only performed when an origin is reached.""" + + score_per_period: Optional[int] = None + """ + The score threshold per period for which the action will be executed the first + time. + """ + + score_response_header_name: Optional[str] = None + """ + A response header name provided by the origin, which contains the score to + increment rate limit counter with. + """ + + +class UnionMember4RuleSetCacheTagsRule(BaseModel): + id: str + """The unique ID of the rule.""" + + action: Literal["set_cache_tags"] + """The action to perform when the rule matches.""" + + enabled: bool + + expression: str + """The expression defining which traffic will match the rule.""" + + last_updated: datetime + """The timestamp of when the rule was last modified.""" + + ref: str + """The reference of the rule (the rule's ID by default).""" + + version: str + """The version of the rule.""" + + action_parameters: Optional[UnionMember4RuleSetCacheTagsRuleActionParameters] = None + """The parameters configuring the rule's action.""" + + categories: Optional[List[str]] = None + """The categories of the rule.""" + + description: Optional[str] = None + """An informative description of the rule.""" + + exposed_credential_check: Optional[UnionMember4RuleSetCacheTagsRuleExposedCredentialCheck] = None + """Configuration for exposed credential checking.""" + + logging: Optional[Logging] = None + """An object configuring the rule's logging behavior.""" + + ratelimit: Optional[UnionMember4RuleSetCacheTagsRuleRatelimit] = None + """An object configuring the rule's rate limit behavior.""" + + +class UnionMember4RuleSetConfigurationRule(SetConfigRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember4RuleSkipRule(SkipRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember4RuleTransformResponseHTMLRuleActionParameters(BaseModel): + """The parameters configuring the rule's action.""" + + link_maze: object + """Enables the link maze transformation on the response.""" + + +class UnionMember4RuleTransformResponseHTMLRuleExposedCredentialCheck(BaseModel): + """Configuration for exposed credential checking.""" + + password_expression: str + """An expression that selects the password used in the credentials check.""" + + username_expression: str + """An expression that selects the user ID used in the credentials check.""" + + +class UnionMember4RuleTransformResponseHTMLRuleRatelimit(BaseModel): + """An object configuring the rule's rate limit behavior.""" + + characteristics: List[str] + """ + Characteristics of the request on which the rate limit counter will be + incremented. + """ + + period: int + """Period in seconds over which the counter is being incremented.""" + + counting_expression: Optional[str] = None + """An expression that defines when the rate limit counter should be incremented. + + It defaults to the same as the rule's expression. + """ + + mitigation_timeout: Optional[int] = None + """ + Period of time in seconds after which the action will be disabled following its + first execution. + """ + + requests_per_period: Optional[int] = None + """ + The threshold of requests per period after which the action will be executed for + the first time. + """ + + requests_to_origin: Optional[bool] = None + """Whether counting is only performed when an origin is reached.""" + + score_per_period: Optional[int] = None + """ + The score threshold per period for which the action will be executed the first + time. + """ + + score_response_header_name: Optional[str] = None + """ + A response header name provided by the origin, which contains the score to + increment rate limit counter with. + """ + + +class UnionMember4RuleTransformResponseHTMLRule(BaseModel): + id: str + """The unique ID of the rule.""" + + action: Literal["transform_response_html"] + """The action to perform when the rule matches.""" + + enabled: bool + + expression: str + """The expression defining which traffic will match the rule.""" + + last_updated: datetime + """The timestamp of when the rule was last modified.""" + + ref: str + """The reference of the rule (the rule's ID by default).""" + + version: str + """The version of the rule.""" + + action_parameters: Optional[UnionMember4RuleTransformResponseHTMLRuleActionParameters] = None + """The parameters configuring the rule's action.""" + + categories: Optional[List[str]] = None + """The categories of the rule.""" + + description: Optional[str] = None + """An informative description of the rule.""" + + exposed_credential_check: Optional[UnionMember4RuleTransformResponseHTMLRuleExposedCredentialCheck] = None + """Configuration for exposed credential checking.""" + + logging: Optional[Logging] = None + """An object configuring the rule's logging behavior.""" + + ratelimit: Optional[UnionMember4RuleTransformResponseHTMLRuleRatelimit] = None + """An object configuring the rule's rate limit behavior.""" + + +UnionMember4Rule: TypeAlias = Union[ + UnionMember4RuleBlockRule, + UnionMember4RuleChallengeRule, + UnionMember4RuleResponseCompressionRule, + UnionMember4RuleDDoSDynamicRule, + UnionMember4RuleExecuteRule, + UnionMember4RuleForceConnectionCloseRule, + UnionMember4RuleJavaScriptChallengeRule, + UnionMember4RuleLogRule, + UnionMember4RuleLogCustomFieldRule, + UnionMember4RuleManagedChallengeRule, + UnionMember4RuleRedirectRule, + UnionMember4RuleRewriteRule, + UnionMember4RuleRouteRule, + UnionMember4RuleScoreRule, + UnionMember4RuleServeErrorRule, + UnionMember4RuleSetCacheControlRule, + UnionMember4RuleSetCacheSettingsRule, + UnionMember4RuleSetCacheTagsRule, + UnionMember4RuleSetConfigurationRule, + UnionMember4RuleSkipRule, + UnionMember4RuleTransformResponseHTMLRule, +] + + +class UnionMember4(BaseModel): + id: Optional[str] = None + """The unique ID of the ruleset.""" + + description: Optional[str] = None + """An informative description of the ruleset.""" + + kind: Optional[Kind] = None + """The kind of the ruleset.""" + + last_updated: Optional[datetime] = None + """The timestamp of when the ruleset was last modified.""" + + name: Optional[str] = None + """The human-readable name of the ruleset.""" + + phase: Optional[Phase] = None + """The phase of the ruleset.""" + + rules: Optional[List[UnionMember4Rule]] = None + """The list of rules in the ruleset.""" + + version: Optional[str] = None + """The version of the ruleset.""" + + +PhaseGetResponse: TypeAlias = Union[Optional[UnionMember0], UnionMember1, UnionMember2, UnionMember3, UnionMember4] diff --git a/src/cloudflare/types/rulesets/phase_update_response.py b/src/cloudflare/types/rulesets/phase_update_response.py index 45f4b9b81a7..6856ff2c42c 100644 --- a/src/cloudflare/types/rulesets/phase_update_response.py +++ b/src/cloudflare/types/rulesets/phase_update_response.py @@ -1358,4 +1358,4 @@ class Ruleset(BaseModel): """An informative description of the ruleset.""" -PhaseUpdateResponse: TypeAlias = Union[Ruleset, Optional[object]] +PhaseUpdateResponse: TypeAlias = Union[List[object], str, float, bool, Ruleset, Optional[object], Optional[object]] diff --git a/src/cloudflare/types/rulesets/phases/version_get_response.py b/src/cloudflare/types/rulesets/phases/version_get_response.py index 9603fd29dc0..d999f3b08f2 100644 --- a/src/cloudflare/types/rulesets/phases/version_get_response.py +++ b/src/cloudflare/types/rulesets/phases/version_get_response.py @@ -29,102 +29,427 @@ __all__ = [ "VersionGetResponse", - "Rule", - "RuleBlockRule", - "RuleChallengeRule", - "RuleChallengeRuleExposedCredentialCheck", - "RuleChallengeRuleRatelimit", - "RuleResponseCompressionRule", - "RuleDDoSDynamicRule", - "RuleExecuteRule", - "RuleForceConnectionCloseRule", - "RuleJavaScriptChallengeRule", - "RuleJavaScriptChallengeRuleExposedCredentialCheck", - "RuleJavaScriptChallengeRuleRatelimit", - "RuleLogRule", - "RuleLogCustomFieldRule", - "RuleManagedChallengeRule", - "RuleRedirectRule", - "RuleRewriteRule", - "RuleRouteRule", - "RuleScoreRule", - "RuleServeErrorRule", - "RuleSetCacheControlRule", - "RuleSetCacheControlRuleActionParameters", - "RuleSetCacheControlRuleActionParametersImmutable", - "RuleSetCacheControlRuleActionParametersImmutableSetDirective", - "RuleSetCacheControlRuleActionParametersImmutableRemoveDirective", - "RuleSetCacheControlRuleActionParametersMaxAge", - "RuleSetCacheControlRuleActionParametersMaxAgeSetDirective", - "RuleSetCacheControlRuleActionParametersMaxAgeRemoveDirective", - "RuleSetCacheControlRuleActionParametersMustRevalidate", - "RuleSetCacheControlRuleActionParametersMustRevalidateSetDirective", - "RuleSetCacheControlRuleActionParametersMustRevalidateRemoveDirective", - "RuleSetCacheControlRuleActionParametersMustUnderstand", - "RuleSetCacheControlRuleActionParametersMustUnderstandSetDirective", - "RuleSetCacheControlRuleActionParametersMustUnderstandRemoveDirective", - "RuleSetCacheControlRuleActionParametersNoCache", - "RuleSetCacheControlRuleActionParametersNoCacheSetDirective", - "RuleSetCacheControlRuleActionParametersNoCacheRemoveDirective", - "RuleSetCacheControlRuleActionParametersNoStore", - "RuleSetCacheControlRuleActionParametersNoStoreSetDirective", - "RuleSetCacheControlRuleActionParametersNoStoreRemoveDirective", - "RuleSetCacheControlRuleActionParametersNoTransform", - "RuleSetCacheControlRuleActionParametersNoTransformSetDirective", - "RuleSetCacheControlRuleActionParametersNoTransformRemoveDirective", - "RuleSetCacheControlRuleActionParametersPrivate", - "RuleSetCacheControlRuleActionParametersPrivateSetDirective", - "RuleSetCacheControlRuleActionParametersPrivateRemoveDirective", - "RuleSetCacheControlRuleActionParametersProxyRevalidate", - "RuleSetCacheControlRuleActionParametersProxyRevalidateSetDirective", - "RuleSetCacheControlRuleActionParametersProxyRevalidateRemoveDirective", - "RuleSetCacheControlRuleActionParametersPublic", - "RuleSetCacheControlRuleActionParametersPublicSetDirective", - "RuleSetCacheControlRuleActionParametersPublicRemoveDirective", - "RuleSetCacheControlRuleActionParametersSMaxage", - "RuleSetCacheControlRuleActionParametersSMaxageSetDirective", - "RuleSetCacheControlRuleActionParametersSMaxageRemoveDirective", - "RuleSetCacheControlRuleActionParametersStaleIfError", - "RuleSetCacheControlRuleActionParametersStaleIfErrorSetDirective", - "RuleSetCacheControlRuleActionParametersStaleIfErrorRemoveDirective", - "RuleSetCacheControlRuleActionParametersStaleWhileRevalidate", - "RuleSetCacheControlRuleActionParametersStaleWhileRevalidateSetDirective", - "RuleSetCacheControlRuleActionParametersStaleWhileRevalidateRemoveDirective", - "RuleSetCacheControlRuleExposedCredentialCheck", - "RuleSetCacheControlRuleRatelimit", - "RuleSetCacheSettingsRule", - "RuleSetCacheTagsRule", - "RuleSetCacheTagsRuleActionParameters", - "RuleSetCacheTagsRuleActionParametersAddCacheTagsValues", - "RuleSetCacheTagsRuleActionParametersAddCacheTagsExpression", - "RuleSetCacheTagsRuleActionParametersRemoveCacheTagsValues", - "RuleSetCacheTagsRuleActionParametersRemoveCacheTagsExpression", - "RuleSetCacheTagsRuleActionParametersSetCacheTagsValues", - "RuleSetCacheTagsRuleActionParametersSetCacheTagsExpression", - "RuleSetCacheTagsRuleExposedCredentialCheck", - "RuleSetCacheTagsRuleRatelimit", - "RuleSetConfigurationRule", - "RuleSkipRule", - "RuleTransformResponseHTMLRule", - "RuleTransformResponseHTMLRuleActionParameters", - "RuleTransformResponseHTMLRuleExposedCredentialCheck", - "RuleTransformResponseHTMLRuleRatelimit", -] - - -class RuleBlockRule(BlockRule): - id: str # type: ignore - - action: str # type: ignore - - enabled: bool # type: ignore - - expression: str # type: ignore - - ref: str # type: ignore - - -class RuleChallengeRuleExposedCredentialCheck(BaseModel): + "UnionMember0", + "UnionMember0Rule", + "UnionMember0RuleBlockRule", + "UnionMember0RuleChallengeRule", + "UnionMember0RuleChallengeRuleExposedCredentialCheck", + "UnionMember0RuleChallengeRuleRatelimit", + "UnionMember0RuleResponseCompressionRule", + "UnionMember0RuleDDoSDynamicRule", + "UnionMember0RuleExecuteRule", + "UnionMember0RuleForceConnectionCloseRule", + "UnionMember0RuleJavaScriptChallengeRule", + "UnionMember0RuleJavaScriptChallengeRuleExposedCredentialCheck", + "UnionMember0RuleJavaScriptChallengeRuleRatelimit", + "UnionMember0RuleLogRule", + "UnionMember0RuleLogCustomFieldRule", + "UnionMember0RuleManagedChallengeRule", + "UnionMember0RuleRedirectRule", + "UnionMember0RuleRewriteRule", + "UnionMember0RuleRouteRule", + "UnionMember0RuleScoreRule", + "UnionMember0RuleServeErrorRule", + "UnionMember0RuleSetCacheControlRule", + "UnionMember0RuleSetCacheControlRuleActionParameters", + "UnionMember0RuleSetCacheControlRuleActionParametersImmutable", + "UnionMember0RuleSetCacheControlRuleActionParametersImmutableSetDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersImmutableRemoveDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersMaxAge", + "UnionMember0RuleSetCacheControlRuleActionParametersMaxAgeSetDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersMaxAgeRemoveDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersMustRevalidate", + "UnionMember0RuleSetCacheControlRuleActionParametersMustRevalidateSetDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersMustRevalidateRemoveDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersMustUnderstand", + "UnionMember0RuleSetCacheControlRuleActionParametersMustUnderstandSetDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersMustUnderstandRemoveDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersNoCache", + "UnionMember0RuleSetCacheControlRuleActionParametersNoCacheSetDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersNoCacheRemoveDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersNoStore", + "UnionMember0RuleSetCacheControlRuleActionParametersNoStoreSetDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersNoStoreRemoveDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersNoTransform", + "UnionMember0RuleSetCacheControlRuleActionParametersNoTransformSetDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersNoTransformRemoveDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersPrivate", + "UnionMember0RuleSetCacheControlRuleActionParametersPrivateSetDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersPrivateRemoveDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersProxyRevalidate", + "UnionMember0RuleSetCacheControlRuleActionParametersProxyRevalidateSetDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersProxyRevalidateRemoveDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersPublic", + "UnionMember0RuleSetCacheControlRuleActionParametersPublicSetDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersPublicRemoveDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersSMaxage", + "UnionMember0RuleSetCacheControlRuleActionParametersSMaxageSetDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersSMaxageRemoveDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersStaleIfError", + "UnionMember0RuleSetCacheControlRuleActionParametersStaleIfErrorSetDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersStaleIfErrorRemoveDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersStaleWhileRevalidate", + "UnionMember0RuleSetCacheControlRuleActionParametersStaleWhileRevalidateSetDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersStaleWhileRevalidateRemoveDirective", + "UnionMember0RuleSetCacheControlRuleExposedCredentialCheck", + "UnionMember0RuleSetCacheControlRuleRatelimit", + "UnionMember0RuleSetCacheSettingsRule", + "UnionMember0RuleSetCacheTagsRule", + "UnionMember0RuleSetCacheTagsRuleActionParameters", + "UnionMember0RuleSetCacheTagsRuleActionParametersAddCacheTagsValues", + "UnionMember0RuleSetCacheTagsRuleActionParametersAddCacheTagsExpression", + "UnionMember0RuleSetCacheTagsRuleActionParametersRemoveCacheTagsValues", + "UnionMember0RuleSetCacheTagsRuleActionParametersRemoveCacheTagsExpression", + "UnionMember0RuleSetCacheTagsRuleActionParametersSetCacheTagsValues", + "UnionMember0RuleSetCacheTagsRuleActionParametersSetCacheTagsExpression", + "UnionMember0RuleSetCacheTagsRuleExposedCredentialCheck", + "UnionMember0RuleSetCacheTagsRuleRatelimit", + "UnionMember0RuleSetConfigurationRule", + "UnionMember0RuleSkipRule", + "UnionMember0RuleTransformResponseHTMLRule", + "UnionMember0RuleTransformResponseHTMLRuleActionParameters", + "UnionMember0RuleTransformResponseHTMLRuleExposedCredentialCheck", + "UnionMember0RuleTransformResponseHTMLRuleRatelimit", + "UnionMember1", + "UnionMember1Rule", + "UnionMember1RuleBlockRule", + "UnionMember1RuleChallengeRule", + "UnionMember1RuleChallengeRuleExposedCredentialCheck", + "UnionMember1RuleChallengeRuleRatelimit", + "UnionMember1RuleResponseCompressionRule", + "UnionMember1RuleDDoSDynamicRule", + "UnionMember1RuleExecuteRule", + "UnionMember1RuleForceConnectionCloseRule", + "UnionMember1RuleJavaScriptChallengeRule", + "UnionMember1RuleJavaScriptChallengeRuleExposedCredentialCheck", + "UnionMember1RuleJavaScriptChallengeRuleRatelimit", + "UnionMember1RuleLogRule", + "UnionMember1RuleLogCustomFieldRule", + "UnionMember1RuleManagedChallengeRule", + "UnionMember1RuleRedirectRule", + "UnionMember1RuleRewriteRule", + "UnionMember1RuleRouteRule", + "UnionMember1RuleScoreRule", + "UnionMember1RuleServeErrorRule", + "UnionMember1RuleSetCacheControlRule", + "UnionMember1RuleSetCacheControlRuleActionParameters", + "UnionMember1RuleSetCacheControlRuleActionParametersImmutable", + "UnionMember1RuleSetCacheControlRuleActionParametersImmutableSetDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersImmutableRemoveDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersMaxAge", + "UnionMember1RuleSetCacheControlRuleActionParametersMaxAgeSetDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersMaxAgeRemoveDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersMustRevalidate", + "UnionMember1RuleSetCacheControlRuleActionParametersMustRevalidateSetDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersMustRevalidateRemoveDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersMustUnderstand", + "UnionMember1RuleSetCacheControlRuleActionParametersMustUnderstandSetDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersMustUnderstandRemoveDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersNoCache", + "UnionMember1RuleSetCacheControlRuleActionParametersNoCacheSetDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersNoCacheRemoveDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersNoStore", + "UnionMember1RuleSetCacheControlRuleActionParametersNoStoreSetDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersNoStoreRemoveDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersNoTransform", + "UnionMember1RuleSetCacheControlRuleActionParametersNoTransformSetDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersNoTransformRemoveDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersPrivate", + "UnionMember1RuleSetCacheControlRuleActionParametersPrivateSetDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersPrivateRemoveDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersProxyRevalidate", + "UnionMember1RuleSetCacheControlRuleActionParametersProxyRevalidateSetDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersProxyRevalidateRemoveDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersPublic", + "UnionMember1RuleSetCacheControlRuleActionParametersPublicSetDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersPublicRemoveDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersSMaxage", + "UnionMember1RuleSetCacheControlRuleActionParametersSMaxageSetDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersSMaxageRemoveDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersStaleIfError", + "UnionMember1RuleSetCacheControlRuleActionParametersStaleIfErrorSetDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersStaleIfErrorRemoveDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersStaleWhileRevalidate", + "UnionMember1RuleSetCacheControlRuleActionParametersStaleWhileRevalidateSetDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersStaleWhileRevalidateRemoveDirective", + "UnionMember1RuleSetCacheControlRuleExposedCredentialCheck", + "UnionMember1RuleSetCacheControlRuleRatelimit", + "UnionMember1RuleSetCacheSettingsRule", + "UnionMember1RuleSetCacheTagsRule", + "UnionMember1RuleSetCacheTagsRuleActionParameters", + "UnionMember1RuleSetCacheTagsRuleActionParametersAddCacheTagsValues", + "UnionMember1RuleSetCacheTagsRuleActionParametersAddCacheTagsExpression", + "UnionMember1RuleSetCacheTagsRuleActionParametersRemoveCacheTagsValues", + "UnionMember1RuleSetCacheTagsRuleActionParametersRemoveCacheTagsExpression", + "UnionMember1RuleSetCacheTagsRuleActionParametersSetCacheTagsValues", + "UnionMember1RuleSetCacheTagsRuleActionParametersSetCacheTagsExpression", + "UnionMember1RuleSetCacheTagsRuleExposedCredentialCheck", + "UnionMember1RuleSetCacheTagsRuleRatelimit", + "UnionMember1RuleSetConfigurationRule", + "UnionMember1RuleSkipRule", + "UnionMember1RuleTransformResponseHTMLRule", + "UnionMember1RuleTransformResponseHTMLRuleActionParameters", + "UnionMember1RuleTransformResponseHTMLRuleExposedCredentialCheck", + "UnionMember1RuleTransformResponseHTMLRuleRatelimit", + "UnionMember2", + "UnionMember2Rule", + "UnionMember2RuleBlockRule", + "UnionMember2RuleChallengeRule", + "UnionMember2RuleChallengeRuleExposedCredentialCheck", + "UnionMember2RuleChallengeRuleRatelimit", + "UnionMember2RuleResponseCompressionRule", + "UnionMember2RuleDDoSDynamicRule", + "UnionMember2RuleExecuteRule", + "UnionMember2RuleForceConnectionCloseRule", + "UnionMember2RuleJavaScriptChallengeRule", + "UnionMember2RuleJavaScriptChallengeRuleExposedCredentialCheck", + "UnionMember2RuleJavaScriptChallengeRuleRatelimit", + "UnionMember2RuleLogRule", + "UnionMember2RuleLogCustomFieldRule", + "UnionMember2RuleManagedChallengeRule", + "UnionMember2RuleRedirectRule", + "UnionMember2RuleRewriteRule", + "UnionMember2RuleRouteRule", + "UnionMember2RuleScoreRule", + "UnionMember2RuleServeErrorRule", + "UnionMember2RuleSetCacheControlRule", + "UnionMember2RuleSetCacheControlRuleActionParameters", + "UnionMember2RuleSetCacheControlRuleActionParametersImmutable", + "UnionMember2RuleSetCacheControlRuleActionParametersImmutableSetDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersImmutableRemoveDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersMaxAge", + "UnionMember2RuleSetCacheControlRuleActionParametersMaxAgeSetDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersMaxAgeRemoveDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersMustRevalidate", + "UnionMember2RuleSetCacheControlRuleActionParametersMustRevalidateSetDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersMustRevalidateRemoveDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersMustUnderstand", + "UnionMember2RuleSetCacheControlRuleActionParametersMustUnderstandSetDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersMustUnderstandRemoveDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersNoCache", + "UnionMember2RuleSetCacheControlRuleActionParametersNoCacheSetDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersNoCacheRemoveDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersNoStore", + "UnionMember2RuleSetCacheControlRuleActionParametersNoStoreSetDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersNoStoreRemoveDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersNoTransform", + "UnionMember2RuleSetCacheControlRuleActionParametersNoTransformSetDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersNoTransformRemoveDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersPrivate", + "UnionMember2RuleSetCacheControlRuleActionParametersPrivateSetDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersPrivateRemoveDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersProxyRevalidate", + "UnionMember2RuleSetCacheControlRuleActionParametersProxyRevalidateSetDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersProxyRevalidateRemoveDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersPublic", + "UnionMember2RuleSetCacheControlRuleActionParametersPublicSetDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersPublicRemoveDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersSMaxage", + "UnionMember2RuleSetCacheControlRuleActionParametersSMaxageSetDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersSMaxageRemoveDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersStaleIfError", + "UnionMember2RuleSetCacheControlRuleActionParametersStaleIfErrorSetDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersStaleIfErrorRemoveDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersStaleWhileRevalidate", + "UnionMember2RuleSetCacheControlRuleActionParametersStaleWhileRevalidateSetDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersStaleWhileRevalidateRemoveDirective", + "UnionMember2RuleSetCacheControlRuleExposedCredentialCheck", + "UnionMember2RuleSetCacheControlRuleRatelimit", + "UnionMember2RuleSetCacheSettingsRule", + "UnionMember2RuleSetCacheTagsRule", + "UnionMember2RuleSetCacheTagsRuleActionParameters", + "UnionMember2RuleSetCacheTagsRuleActionParametersAddCacheTagsValues", + "UnionMember2RuleSetCacheTagsRuleActionParametersAddCacheTagsExpression", + "UnionMember2RuleSetCacheTagsRuleActionParametersRemoveCacheTagsValues", + "UnionMember2RuleSetCacheTagsRuleActionParametersRemoveCacheTagsExpression", + "UnionMember2RuleSetCacheTagsRuleActionParametersSetCacheTagsValues", + "UnionMember2RuleSetCacheTagsRuleActionParametersSetCacheTagsExpression", + "UnionMember2RuleSetCacheTagsRuleExposedCredentialCheck", + "UnionMember2RuleSetCacheTagsRuleRatelimit", + "UnionMember2RuleSetConfigurationRule", + "UnionMember2RuleSkipRule", + "UnionMember2RuleTransformResponseHTMLRule", + "UnionMember2RuleTransformResponseHTMLRuleActionParameters", + "UnionMember2RuleTransformResponseHTMLRuleExposedCredentialCheck", + "UnionMember2RuleTransformResponseHTMLRuleRatelimit", + "UnionMember3", + "UnionMember3Rule", + "UnionMember3RuleBlockRule", + "UnionMember3RuleChallengeRule", + "UnionMember3RuleChallengeRuleExposedCredentialCheck", + "UnionMember3RuleChallengeRuleRatelimit", + "UnionMember3RuleResponseCompressionRule", + "UnionMember3RuleDDoSDynamicRule", + "UnionMember3RuleExecuteRule", + "UnionMember3RuleForceConnectionCloseRule", + "UnionMember3RuleJavaScriptChallengeRule", + "UnionMember3RuleJavaScriptChallengeRuleExposedCredentialCheck", + "UnionMember3RuleJavaScriptChallengeRuleRatelimit", + "UnionMember3RuleLogRule", + "UnionMember3RuleLogCustomFieldRule", + "UnionMember3RuleManagedChallengeRule", + "UnionMember3RuleRedirectRule", + "UnionMember3RuleRewriteRule", + "UnionMember3RuleRouteRule", + "UnionMember3RuleScoreRule", + "UnionMember3RuleServeErrorRule", + "UnionMember3RuleSetCacheControlRule", + "UnionMember3RuleSetCacheControlRuleActionParameters", + "UnionMember3RuleSetCacheControlRuleActionParametersImmutable", + "UnionMember3RuleSetCacheControlRuleActionParametersImmutableSetDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersImmutableRemoveDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersMaxAge", + "UnionMember3RuleSetCacheControlRuleActionParametersMaxAgeSetDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersMaxAgeRemoveDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersMustRevalidate", + "UnionMember3RuleSetCacheControlRuleActionParametersMustRevalidateSetDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersMustRevalidateRemoveDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersMustUnderstand", + "UnionMember3RuleSetCacheControlRuleActionParametersMustUnderstandSetDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersMustUnderstandRemoveDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersNoCache", + "UnionMember3RuleSetCacheControlRuleActionParametersNoCacheSetDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersNoCacheRemoveDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersNoStore", + "UnionMember3RuleSetCacheControlRuleActionParametersNoStoreSetDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersNoStoreRemoveDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersNoTransform", + "UnionMember3RuleSetCacheControlRuleActionParametersNoTransformSetDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersNoTransformRemoveDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersPrivate", + "UnionMember3RuleSetCacheControlRuleActionParametersPrivateSetDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersPrivateRemoveDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersProxyRevalidate", + "UnionMember3RuleSetCacheControlRuleActionParametersProxyRevalidateSetDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersProxyRevalidateRemoveDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersPublic", + "UnionMember3RuleSetCacheControlRuleActionParametersPublicSetDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersPublicRemoveDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersSMaxage", + "UnionMember3RuleSetCacheControlRuleActionParametersSMaxageSetDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersSMaxageRemoveDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersStaleIfError", + "UnionMember3RuleSetCacheControlRuleActionParametersStaleIfErrorSetDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersStaleIfErrorRemoveDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersStaleWhileRevalidate", + "UnionMember3RuleSetCacheControlRuleActionParametersStaleWhileRevalidateSetDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersStaleWhileRevalidateRemoveDirective", + "UnionMember3RuleSetCacheControlRuleExposedCredentialCheck", + "UnionMember3RuleSetCacheControlRuleRatelimit", + "UnionMember3RuleSetCacheSettingsRule", + "UnionMember3RuleSetCacheTagsRule", + "UnionMember3RuleSetCacheTagsRuleActionParameters", + "UnionMember3RuleSetCacheTagsRuleActionParametersAddCacheTagsValues", + "UnionMember3RuleSetCacheTagsRuleActionParametersAddCacheTagsExpression", + "UnionMember3RuleSetCacheTagsRuleActionParametersRemoveCacheTagsValues", + "UnionMember3RuleSetCacheTagsRuleActionParametersRemoveCacheTagsExpression", + "UnionMember3RuleSetCacheTagsRuleActionParametersSetCacheTagsValues", + "UnionMember3RuleSetCacheTagsRuleActionParametersSetCacheTagsExpression", + "UnionMember3RuleSetCacheTagsRuleExposedCredentialCheck", + "UnionMember3RuleSetCacheTagsRuleRatelimit", + "UnionMember3RuleSetConfigurationRule", + "UnionMember3RuleSkipRule", + "UnionMember3RuleTransformResponseHTMLRule", + "UnionMember3RuleTransformResponseHTMLRuleActionParameters", + "UnionMember3RuleTransformResponseHTMLRuleExposedCredentialCheck", + "UnionMember3RuleTransformResponseHTMLRuleRatelimit", + "UnionMember4", + "UnionMember4Rule", + "UnionMember4RuleBlockRule", + "UnionMember4RuleChallengeRule", + "UnionMember4RuleChallengeRuleExposedCredentialCheck", + "UnionMember4RuleChallengeRuleRatelimit", + "UnionMember4RuleResponseCompressionRule", + "UnionMember4RuleDDoSDynamicRule", + "UnionMember4RuleExecuteRule", + "UnionMember4RuleForceConnectionCloseRule", + "UnionMember4RuleJavaScriptChallengeRule", + "UnionMember4RuleJavaScriptChallengeRuleExposedCredentialCheck", + "UnionMember4RuleJavaScriptChallengeRuleRatelimit", + "UnionMember4RuleLogRule", + "UnionMember4RuleLogCustomFieldRule", + "UnionMember4RuleManagedChallengeRule", + "UnionMember4RuleRedirectRule", + "UnionMember4RuleRewriteRule", + "UnionMember4RuleRouteRule", + "UnionMember4RuleScoreRule", + "UnionMember4RuleServeErrorRule", + "UnionMember4RuleSetCacheControlRule", + "UnionMember4RuleSetCacheControlRuleActionParameters", + "UnionMember4RuleSetCacheControlRuleActionParametersImmutable", + "UnionMember4RuleSetCacheControlRuleActionParametersImmutableSetDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersImmutableRemoveDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersMaxAge", + "UnionMember4RuleSetCacheControlRuleActionParametersMaxAgeSetDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersMaxAgeRemoveDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersMustRevalidate", + "UnionMember4RuleSetCacheControlRuleActionParametersMustRevalidateSetDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersMustRevalidateRemoveDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersMustUnderstand", + "UnionMember4RuleSetCacheControlRuleActionParametersMustUnderstandSetDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersMustUnderstandRemoveDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersNoCache", + "UnionMember4RuleSetCacheControlRuleActionParametersNoCacheSetDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersNoCacheRemoveDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersNoStore", + "UnionMember4RuleSetCacheControlRuleActionParametersNoStoreSetDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersNoStoreRemoveDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersNoTransform", + "UnionMember4RuleSetCacheControlRuleActionParametersNoTransformSetDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersNoTransformRemoveDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersPrivate", + "UnionMember4RuleSetCacheControlRuleActionParametersPrivateSetDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersPrivateRemoveDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersProxyRevalidate", + "UnionMember4RuleSetCacheControlRuleActionParametersProxyRevalidateSetDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersProxyRevalidateRemoveDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersPublic", + "UnionMember4RuleSetCacheControlRuleActionParametersPublicSetDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersPublicRemoveDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersSMaxage", + "UnionMember4RuleSetCacheControlRuleActionParametersSMaxageSetDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersSMaxageRemoveDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersStaleIfError", + "UnionMember4RuleSetCacheControlRuleActionParametersStaleIfErrorSetDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersStaleIfErrorRemoveDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersStaleWhileRevalidate", + "UnionMember4RuleSetCacheControlRuleActionParametersStaleWhileRevalidateSetDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersStaleWhileRevalidateRemoveDirective", + "UnionMember4RuleSetCacheControlRuleExposedCredentialCheck", + "UnionMember4RuleSetCacheControlRuleRatelimit", + "UnionMember4RuleSetCacheSettingsRule", + "UnionMember4RuleSetCacheTagsRule", + "UnionMember4RuleSetCacheTagsRuleActionParameters", + "UnionMember4RuleSetCacheTagsRuleActionParametersAddCacheTagsValues", + "UnionMember4RuleSetCacheTagsRuleActionParametersAddCacheTagsExpression", + "UnionMember4RuleSetCacheTagsRuleActionParametersRemoveCacheTagsValues", + "UnionMember4RuleSetCacheTagsRuleActionParametersRemoveCacheTagsExpression", + "UnionMember4RuleSetCacheTagsRuleActionParametersSetCacheTagsValues", + "UnionMember4RuleSetCacheTagsRuleActionParametersSetCacheTagsExpression", + "UnionMember4RuleSetCacheTagsRuleExposedCredentialCheck", + "UnionMember4RuleSetCacheTagsRuleRatelimit", + "UnionMember4RuleSetConfigurationRule", + "UnionMember4RuleSkipRule", + "UnionMember4RuleTransformResponseHTMLRule", + "UnionMember4RuleTransformResponseHTMLRuleActionParameters", + "UnionMember4RuleTransformResponseHTMLRuleExposedCredentialCheck", + "UnionMember4RuleTransformResponseHTMLRuleRatelimit", +] + + +class UnionMember0RuleBlockRule(BlockRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember0RuleChallengeRuleExposedCredentialCheck(BaseModel): """Configuration for exposed credential checking.""" password_expression: str @@ -134,7 +459,7 @@ class RuleChallengeRuleExposedCredentialCheck(BaseModel): """An expression that selects the user ID used in the credentials check.""" -class RuleChallengeRuleRatelimit(BaseModel): +class UnionMember0RuleChallengeRuleRatelimit(BaseModel): """An object configuring the rule's rate limit behavior.""" characteristics: List[str] @@ -180,7 +505,7 @@ class RuleChallengeRuleRatelimit(BaseModel): """ -class RuleChallengeRule(BaseModel): +class UnionMember0RuleChallengeRule(BaseModel): id: str """The unique ID of the rule.""" @@ -211,17 +536,17 @@ class RuleChallengeRule(BaseModel): description: Optional[str] = None """An informative description of the rule.""" - exposed_credential_check: Optional[RuleChallengeRuleExposedCredentialCheck] = None + exposed_credential_check: Optional[UnionMember0RuleChallengeRuleExposedCredentialCheck] = None """Configuration for exposed credential checking.""" logging: Optional[Logging] = None """An object configuring the rule's logging behavior.""" - ratelimit: Optional[RuleChallengeRuleRatelimit] = None + ratelimit: Optional[UnionMember0RuleChallengeRuleRatelimit] = None """An object configuring the rule's rate limit behavior.""" -class RuleResponseCompressionRule(CompressResponseRule): +class UnionMember0RuleResponseCompressionRule(CompressResponseRule): id: str # type: ignore action: str # type: ignore @@ -233,7 +558,7 @@ class RuleResponseCompressionRule(CompressResponseRule): ref: str # type: ignore -class RuleDDoSDynamicRule(DDoSDynamicRule): +class UnionMember0RuleDDoSDynamicRule(DDoSDynamicRule): id: str # type: ignore action: str # type: ignore @@ -245,7 +570,7 @@ class RuleDDoSDynamicRule(DDoSDynamicRule): ref: str # type: ignore -class RuleExecuteRule(ExecuteRule): +class UnionMember0RuleExecuteRule(ExecuteRule): id: str # type: ignore action: str # type: ignore @@ -257,7 +582,7 @@ class RuleExecuteRule(ExecuteRule): ref: str # type: ignore -class RuleForceConnectionCloseRule(ForceConnectionCloseRule): +class UnionMember0RuleForceConnectionCloseRule(ForceConnectionCloseRule): id: str # type: ignore action: str # type: ignore @@ -269,7 +594,7 @@ class RuleForceConnectionCloseRule(ForceConnectionCloseRule): ref: str # type: ignore -class RuleJavaScriptChallengeRuleExposedCredentialCheck(BaseModel): +class UnionMember0RuleJavaScriptChallengeRuleExposedCredentialCheck(BaseModel): """Configuration for exposed credential checking.""" password_expression: str @@ -279,7 +604,7 @@ class RuleJavaScriptChallengeRuleExposedCredentialCheck(BaseModel): """An expression that selects the user ID used in the credentials check.""" -class RuleJavaScriptChallengeRuleRatelimit(BaseModel): +class UnionMember0RuleJavaScriptChallengeRuleRatelimit(BaseModel): """An object configuring the rule's rate limit behavior.""" characteristics: List[str] @@ -325,7 +650,7 @@ class RuleJavaScriptChallengeRuleRatelimit(BaseModel): """ -class RuleJavaScriptChallengeRule(BaseModel): +class UnionMember0RuleJavaScriptChallengeRule(BaseModel): id: str """The unique ID of the rule.""" @@ -356,17 +681,17 @@ class RuleJavaScriptChallengeRule(BaseModel): description: Optional[str] = None """An informative description of the rule.""" - exposed_credential_check: Optional[RuleJavaScriptChallengeRuleExposedCredentialCheck] = None + exposed_credential_check: Optional[UnionMember0RuleJavaScriptChallengeRuleExposedCredentialCheck] = None """Configuration for exposed credential checking.""" logging: Optional[Logging] = None """An object configuring the rule's logging behavior.""" - ratelimit: Optional[RuleJavaScriptChallengeRuleRatelimit] = None + ratelimit: Optional[UnionMember0RuleJavaScriptChallengeRuleRatelimit] = None """An object configuring the rule's rate limit behavior.""" -class RuleLogRule(LogRule): +class UnionMember0RuleLogRule(LogRule): id: str # type: ignore action: str # type: ignore @@ -378,7 +703,7 @@ class RuleLogRule(LogRule): ref: str # type: ignore -class RuleLogCustomFieldRule(LogCustomFieldRule): +class UnionMember0RuleLogCustomFieldRule(LogCustomFieldRule): id: str # type: ignore action: str # type: ignore @@ -390,7 +715,7 @@ class RuleLogCustomFieldRule(LogCustomFieldRule): ref: str # type: ignore -class RuleManagedChallengeRule(ManagedChallengeRule): +class UnionMember0RuleManagedChallengeRule(ManagedChallengeRule): id: str # type: ignore action: str # type: ignore @@ -402,7 +727,7 @@ class RuleManagedChallengeRule(ManagedChallengeRule): ref: str # type: ignore -class RuleRedirectRule(RedirectRule): +class UnionMember0RuleRedirectRule(RedirectRule): id: str # type: ignore action: str # type: ignore @@ -414,7 +739,7 @@ class RuleRedirectRule(RedirectRule): ref: str # type: ignore -class RuleRewriteRule(RewriteRule): +class UnionMember0RuleRewriteRule(RewriteRule): id: str # type: ignore action: str # type: ignore @@ -426,7 +751,7 @@ class RuleRewriteRule(RewriteRule): ref: str # type: ignore -class RuleRouteRule(RouteRule): +class UnionMember0RuleRouteRule(RouteRule): id: str # type: ignore action: str # type: ignore @@ -438,7 +763,7 @@ class RuleRouteRule(RouteRule): ref: str # type: ignore -class RuleScoreRule(ScoreRule): +class UnionMember0RuleScoreRule(ScoreRule): id: str # type: ignore action: str # type: ignore @@ -450,7 +775,7 @@ class RuleScoreRule(ScoreRule): ref: str # type: ignore -class RuleServeErrorRule(ServeErrorRule): +class UnionMember0RuleServeErrorRule(ServeErrorRule): id: str # type: ignore action: str # type: ignore @@ -462,7 +787,7 @@ class RuleServeErrorRule(ServeErrorRule): ref: str # type: ignore -class RuleSetCacheControlRuleActionParametersImmutableSetDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersImmutableSetDirective(BaseModel): """Set the directive.""" operation: Literal["set", "remove"] @@ -472,7 +797,7 @@ class RuleSetCacheControlRuleActionParametersImmutableSetDirective(BaseModel): """Whether the directive should only be applied to the Cloudflare CDN cache.""" -class RuleSetCacheControlRuleActionParametersImmutableRemoveDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersImmutableRemoveDirective(BaseModel): """Remove the directive.""" operation: Literal["set", "remove"] @@ -482,13 +807,13 @@ class RuleSetCacheControlRuleActionParametersImmutableRemoveDirective(BaseModel) """Whether the directive should only be applied to the Cloudflare CDN cache.""" -RuleSetCacheControlRuleActionParametersImmutable: TypeAlias = Union[ - RuleSetCacheControlRuleActionParametersImmutableSetDirective, - RuleSetCacheControlRuleActionParametersImmutableRemoveDirective, +UnionMember0RuleSetCacheControlRuleActionParametersImmutable: TypeAlias = Union[ + UnionMember0RuleSetCacheControlRuleActionParametersImmutableSetDirective, + UnionMember0RuleSetCacheControlRuleActionParametersImmutableRemoveDirective, ] -class RuleSetCacheControlRuleActionParametersMaxAgeSetDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersMaxAgeSetDirective(BaseModel): """Set the directive with a duration value in seconds.""" operation: Literal["set", "remove"] @@ -501,7 +826,7 @@ class RuleSetCacheControlRuleActionParametersMaxAgeSetDirective(BaseModel): """Whether the directive should only be applied to the Cloudflare CDN cache.""" -class RuleSetCacheControlRuleActionParametersMaxAgeRemoveDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersMaxAgeRemoveDirective(BaseModel): """Remove the directive.""" operation: Literal["set", "remove"] @@ -511,13 +836,13 @@ class RuleSetCacheControlRuleActionParametersMaxAgeRemoveDirective(BaseModel): """Whether the directive should only be applied to the Cloudflare CDN cache.""" -RuleSetCacheControlRuleActionParametersMaxAge: TypeAlias = Union[ - RuleSetCacheControlRuleActionParametersMaxAgeSetDirective, - RuleSetCacheControlRuleActionParametersMaxAgeRemoveDirective, +UnionMember0RuleSetCacheControlRuleActionParametersMaxAge: TypeAlias = Union[ + UnionMember0RuleSetCacheControlRuleActionParametersMaxAgeSetDirective, + UnionMember0RuleSetCacheControlRuleActionParametersMaxAgeRemoveDirective, ] -class RuleSetCacheControlRuleActionParametersMustRevalidateSetDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersMustRevalidateSetDirective(BaseModel): """Set the directive.""" operation: Literal["set", "remove"] @@ -527,7 +852,7 @@ class RuleSetCacheControlRuleActionParametersMustRevalidateSetDirective(BaseMode """Whether the directive should only be applied to the Cloudflare CDN cache.""" -class RuleSetCacheControlRuleActionParametersMustRevalidateRemoveDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersMustRevalidateRemoveDirective(BaseModel): """Remove the directive.""" operation: Literal["set", "remove"] @@ -537,13 +862,13 @@ class RuleSetCacheControlRuleActionParametersMustRevalidateRemoveDirective(BaseM """Whether the directive should only be applied to the Cloudflare CDN cache.""" -RuleSetCacheControlRuleActionParametersMustRevalidate: TypeAlias = Union[ - RuleSetCacheControlRuleActionParametersMustRevalidateSetDirective, - RuleSetCacheControlRuleActionParametersMustRevalidateRemoveDirective, +UnionMember0RuleSetCacheControlRuleActionParametersMustRevalidate: TypeAlias = Union[ + UnionMember0RuleSetCacheControlRuleActionParametersMustRevalidateSetDirective, + UnionMember0RuleSetCacheControlRuleActionParametersMustRevalidateRemoveDirective, ] -class RuleSetCacheControlRuleActionParametersMustUnderstandSetDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersMustUnderstandSetDirective(BaseModel): """Set the directive.""" operation: Literal["set", "remove"] @@ -553,7 +878,7 @@ class RuleSetCacheControlRuleActionParametersMustUnderstandSetDirective(BaseMode """Whether the directive should only be applied to the Cloudflare CDN cache.""" -class RuleSetCacheControlRuleActionParametersMustUnderstandRemoveDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersMustUnderstandRemoveDirective(BaseModel): """Remove the directive.""" operation: Literal["set", "remove"] @@ -563,13 +888,13 @@ class RuleSetCacheControlRuleActionParametersMustUnderstandRemoveDirective(BaseM """Whether the directive should only be applied to the Cloudflare CDN cache.""" -RuleSetCacheControlRuleActionParametersMustUnderstand: TypeAlias = Union[ - RuleSetCacheControlRuleActionParametersMustUnderstandSetDirective, - RuleSetCacheControlRuleActionParametersMustUnderstandRemoveDirective, +UnionMember0RuleSetCacheControlRuleActionParametersMustUnderstand: TypeAlias = Union[ + UnionMember0RuleSetCacheControlRuleActionParametersMustUnderstandSetDirective, + UnionMember0RuleSetCacheControlRuleActionParametersMustUnderstandRemoveDirective, ] -class RuleSetCacheControlRuleActionParametersNoCacheSetDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersNoCacheSetDirective(BaseModel): """Set the directive with optional qualifiers.""" operation: Literal["set", "remove"] @@ -585,7 +910,7 @@ class RuleSetCacheControlRuleActionParametersNoCacheSetDirective(BaseModel): """ -class RuleSetCacheControlRuleActionParametersNoCacheRemoveDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersNoCacheRemoveDirective(BaseModel): """Remove the directive.""" operation: Literal["set", "remove"] @@ -595,13 +920,13 @@ class RuleSetCacheControlRuleActionParametersNoCacheRemoveDirective(BaseModel): """Whether the directive should only be applied to the Cloudflare CDN cache.""" -RuleSetCacheControlRuleActionParametersNoCache: TypeAlias = Union[ - RuleSetCacheControlRuleActionParametersNoCacheSetDirective, - RuleSetCacheControlRuleActionParametersNoCacheRemoveDirective, +UnionMember0RuleSetCacheControlRuleActionParametersNoCache: TypeAlias = Union[ + UnionMember0RuleSetCacheControlRuleActionParametersNoCacheSetDirective, + UnionMember0RuleSetCacheControlRuleActionParametersNoCacheRemoveDirective, ] -class RuleSetCacheControlRuleActionParametersNoStoreSetDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersNoStoreSetDirective(BaseModel): """Set the directive.""" operation: Literal["set", "remove"] @@ -611,7 +936,7 @@ class RuleSetCacheControlRuleActionParametersNoStoreSetDirective(BaseModel): """Whether the directive should only be applied to the Cloudflare CDN cache.""" -class RuleSetCacheControlRuleActionParametersNoStoreRemoveDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersNoStoreRemoveDirective(BaseModel): """Remove the directive.""" operation: Literal["set", "remove"] @@ -621,13 +946,13 @@ class RuleSetCacheControlRuleActionParametersNoStoreRemoveDirective(BaseModel): """Whether the directive should only be applied to the Cloudflare CDN cache.""" -RuleSetCacheControlRuleActionParametersNoStore: TypeAlias = Union[ - RuleSetCacheControlRuleActionParametersNoStoreSetDirective, - RuleSetCacheControlRuleActionParametersNoStoreRemoveDirective, +UnionMember0RuleSetCacheControlRuleActionParametersNoStore: TypeAlias = Union[ + UnionMember0RuleSetCacheControlRuleActionParametersNoStoreSetDirective, + UnionMember0RuleSetCacheControlRuleActionParametersNoStoreRemoveDirective, ] -class RuleSetCacheControlRuleActionParametersNoTransformSetDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersNoTransformSetDirective(BaseModel): """Set the directive.""" operation: Literal["set", "remove"] @@ -637,7 +962,7 @@ class RuleSetCacheControlRuleActionParametersNoTransformSetDirective(BaseModel): """Whether the directive should only be applied to the Cloudflare CDN cache.""" -class RuleSetCacheControlRuleActionParametersNoTransformRemoveDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersNoTransformRemoveDirective(BaseModel): """Remove the directive.""" operation: Literal["set", "remove"] @@ -647,13 +972,13 @@ class RuleSetCacheControlRuleActionParametersNoTransformRemoveDirective(BaseMode """Whether the directive should only be applied to the Cloudflare CDN cache.""" -RuleSetCacheControlRuleActionParametersNoTransform: TypeAlias = Union[ - RuleSetCacheControlRuleActionParametersNoTransformSetDirective, - RuleSetCacheControlRuleActionParametersNoTransformRemoveDirective, +UnionMember0RuleSetCacheControlRuleActionParametersNoTransform: TypeAlias = Union[ + UnionMember0RuleSetCacheControlRuleActionParametersNoTransformSetDirective, + UnionMember0RuleSetCacheControlRuleActionParametersNoTransformRemoveDirective, ] -class RuleSetCacheControlRuleActionParametersPrivateSetDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersPrivateSetDirective(BaseModel): """Set the directive with optional qualifiers.""" operation: Literal["set", "remove"] @@ -669,7 +994,7 @@ class RuleSetCacheControlRuleActionParametersPrivateSetDirective(BaseModel): """ -class RuleSetCacheControlRuleActionParametersPrivateRemoveDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersPrivateRemoveDirective(BaseModel): """Remove the directive.""" operation: Literal["set", "remove"] @@ -679,13 +1004,13 @@ class RuleSetCacheControlRuleActionParametersPrivateRemoveDirective(BaseModel): """Whether the directive should only be applied to the Cloudflare CDN cache.""" -RuleSetCacheControlRuleActionParametersPrivate: TypeAlias = Union[ - RuleSetCacheControlRuleActionParametersPrivateSetDirective, - RuleSetCacheControlRuleActionParametersPrivateRemoveDirective, +UnionMember0RuleSetCacheControlRuleActionParametersPrivate: TypeAlias = Union[ + UnionMember0RuleSetCacheControlRuleActionParametersPrivateSetDirective, + UnionMember0RuleSetCacheControlRuleActionParametersPrivateRemoveDirective, ] -class RuleSetCacheControlRuleActionParametersProxyRevalidateSetDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersProxyRevalidateSetDirective(BaseModel): """Set the directive.""" operation: Literal["set", "remove"] @@ -695,7 +1020,7 @@ class RuleSetCacheControlRuleActionParametersProxyRevalidateSetDirective(BaseMod """Whether the directive should only be applied to the Cloudflare CDN cache.""" -class RuleSetCacheControlRuleActionParametersProxyRevalidateRemoveDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersProxyRevalidateRemoveDirective(BaseModel): """Remove the directive.""" operation: Literal["set", "remove"] @@ -705,13 +1030,13 @@ class RuleSetCacheControlRuleActionParametersProxyRevalidateRemoveDirective(Base """Whether the directive should only be applied to the Cloudflare CDN cache.""" -RuleSetCacheControlRuleActionParametersProxyRevalidate: TypeAlias = Union[ - RuleSetCacheControlRuleActionParametersProxyRevalidateSetDirective, - RuleSetCacheControlRuleActionParametersProxyRevalidateRemoveDirective, +UnionMember0RuleSetCacheControlRuleActionParametersProxyRevalidate: TypeAlias = Union[ + UnionMember0RuleSetCacheControlRuleActionParametersProxyRevalidateSetDirective, + UnionMember0RuleSetCacheControlRuleActionParametersProxyRevalidateRemoveDirective, ] -class RuleSetCacheControlRuleActionParametersPublicSetDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersPublicSetDirective(BaseModel): """Set the directive.""" operation: Literal["set", "remove"] @@ -721,7 +1046,7 @@ class RuleSetCacheControlRuleActionParametersPublicSetDirective(BaseModel): """Whether the directive should only be applied to the Cloudflare CDN cache.""" -class RuleSetCacheControlRuleActionParametersPublicRemoveDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersPublicRemoveDirective(BaseModel): """Remove the directive.""" operation: Literal["set", "remove"] @@ -731,13 +1056,13 @@ class RuleSetCacheControlRuleActionParametersPublicRemoveDirective(BaseModel): """Whether the directive should only be applied to the Cloudflare CDN cache.""" -RuleSetCacheControlRuleActionParametersPublic: TypeAlias = Union[ - RuleSetCacheControlRuleActionParametersPublicSetDirective, - RuleSetCacheControlRuleActionParametersPublicRemoveDirective, +UnionMember0RuleSetCacheControlRuleActionParametersPublic: TypeAlias = Union[ + UnionMember0RuleSetCacheControlRuleActionParametersPublicSetDirective, + UnionMember0RuleSetCacheControlRuleActionParametersPublicRemoveDirective, ] -class RuleSetCacheControlRuleActionParametersSMaxageSetDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersSMaxageSetDirective(BaseModel): """Set the directive with a duration value in seconds.""" operation: Literal["set", "remove"] @@ -750,7 +1075,7 @@ class RuleSetCacheControlRuleActionParametersSMaxageSetDirective(BaseModel): """Whether the directive should only be applied to the Cloudflare CDN cache.""" -class RuleSetCacheControlRuleActionParametersSMaxageRemoveDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersSMaxageRemoveDirective(BaseModel): """Remove the directive.""" operation: Literal["set", "remove"] @@ -760,13 +1085,13 @@ class RuleSetCacheControlRuleActionParametersSMaxageRemoveDirective(BaseModel): """Whether the directive should only be applied to the Cloudflare CDN cache.""" -RuleSetCacheControlRuleActionParametersSMaxage: TypeAlias = Union[ - RuleSetCacheControlRuleActionParametersSMaxageSetDirective, - RuleSetCacheControlRuleActionParametersSMaxageRemoveDirective, +UnionMember0RuleSetCacheControlRuleActionParametersSMaxage: TypeAlias = Union[ + UnionMember0RuleSetCacheControlRuleActionParametersSMaxageSetDirective, + UnionMember0RuleSetCacheControlRuleActionParametersSMaxageRemoveDirective, ] -class RuleSetCacheControlRuleActionParametersStaleIfErrorSetDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersStaleIfErrorSetDirective(BaseModel): """Set the directive with a duration value in seconds.""" operation: Literal["set", "remove"] @@ -779,7 +1104,7 @@ class RuleSetCacheControlRuleActionParametersStaleIfErrorSetDirective(BaseModel) """Whether the directive should only be applied to the Cloudflare CDN cache.""" -class RuleSetCacheControlRuleActionParametersStaleIfErrorRemoveDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersStaleIfErrorRemoveDirective(BaseModel): """Remove the directive.""" operation: Literal["set", "remove"] @@ -789,13 +1114,13 @@ class RuleSetCacheControlRuleActionParametersStaleIfErrorRemoveDirective(BaseMod """Whether the directive should only be applied to the Cloudflare CDN cache.""" -RuleSetCacheControlRuleActionParametersStaleIfError: TypeAlias = Union[ - RuleSetCacheControlRuleActionParametersStaleIfErrorSetDirective, - RuleSetCacheControlRuleActionParametersStaleIfErrorRemoveDirective, +UnionMember0RuleSetCacheControlRuleActionParametersStaleIfError: TypeAlias = Union[ + UnionMember0RuleSetCacheControlRuleActionParametersStaleIfErrorSetDirective, + UnionMember0RuleSetCacheControlRuleActionParametersStaleIfErrorRemoveDirective, ] -class RuleSetCacheControlRuleActionParametersStaleWhileRevalidateSetDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersStaleWhileRevalidateSetDirective(BaseModel): """Set the directive with a duration value in seconds.""" operation: Literal["set", "remove"] @@ -808,7 +1133,7 @@ class RuleSetCacheControlRuleActionParametersStaleWhileRevalidateSetDirective(Ba """Whether the directive should only be applied to the Cloudflare CDN cache.""" -class RuleSetCacheControlRuleActionParametersStaleWhileRevalidateRemoveDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersStaleWhileRevalidateRemoveDirective(BaseModel): """Remove the directive.""" operation: Literal["set", "remove"] @@ -818,69 +1143,77 @@ class RuleSetCacheControlRuleActionParametersStaleWhileRevalidateRemoveDirective """Whether the directive should only be applied to the Cloudflare CDN cache.""" -RuleSetCacheControlRuleActionParametersStaleWhileRevalidate: TypeAlias = Union[ - RuleSetCacheControlRuleActionParametersStaleWhileRevalidateSetDirective, - RuleSetCacheControlRuleActionParametersStaleWhileRevalidateRemoveDirective, +UnionMember0RuleSetCacheControlRuleActionParametersStaleWhileRevalidate: TypeAlias = Union[ + UnionMember0RuleSetCacheControlRuleActionParametersStaleWhileRevalidateSetDirective, + UnionMember0RuleSetCacheControlRuleActionParametersStaleWhileRevalidateRemoveDirective, ] -class RuleSetCacheControlRuleActionParameters(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParameters(BaseModel): """The parameters configuring the rule's action.""" - immutable: Optional[RuleSetCacheControlRuleActionParametersImmutable] = None + immutable: Optional[UnionMember0RuleSetCacheControlRuleActionParametersImmutable] = None """A cache-control directive configuration.""" - max_age: Optional[RuleSetCacheControlRuleActionParametersMaxAge] = FieldInfo(alias="max-age", default=None) + max_age: Optional[UnionMember0RuleSetCacheControlRuleActionParametersMaxAge] = FieldInfo( + alias="max-age", default=None + ) """ A cache-control directive configuration that accepts a duration value in seconds. """ - must_revalidate: Optional[RuleSetCacheControlRuleActionParametersMustRevalidate] = FieldInfo( + must_revalidate: Optional[UnionMember0RuleSetCacheControlRuleActionParametersMustRevalidate] = FieldInfo( alias="must-revalidate", default=None ) """A cache-control directive configuration.""" - must_understand: Optional[RuleSetCacheControlRuleActionParametersMustUnderstand] = FieldInfo( + must_understand: Optional[UnionMember0RuleSetCacheControlRuleActionParametersMustUnderstand] = FieldInfo( alias="must-understand", default=None ) """A cache-control directive configuration.""" - no_cache: Optional[RuleSetCacheControlRuleActionParametersNoCache] = FieldInfo(alias="no-cache", default=None) + no_cache: Optional[UnionMember0RuleSetCacheControlRuleActionParametersNoCache] = FieldInfo( + alias="no-cache", default=None + ) """ A cache-control directive configuration that accepts optional qualifiers (header names). """ - no_store: Optional[RuleSetCacheControlRuleActionParametersNoStore] = FieldInfo(alias="no-store", default=None) + no_store: Optional[UnionMember0RuleSetCacheControlRuleActionParametersNoStore] = FieldInfo( + alias="no-store", default=None + ) """A cache-control directive configuration.""" - no_transform: Optional[RuleSetCacheControlRuleActionParametersNoTransform] = FieldInfo( + no_transform: Optional[UnionMember0RuleSetCacheControlRuleActionParametersNoTransform] = FieldInfo( alias="no-transform", default=None ) """A cache-control directive configuration.""" - private: Optional[RuleSetCacheControlRuleActionParametersPrivate] = None + private: Optional[UnionMember0RuleSetCacheControlRuleActionParametersPrivate] = None """ A cache-control directive configuration that accepts optional qualifiers (header names). """ - proxy_revalidate: Optional[RuleSetCacheControlRuleActionParametersProxyRevalidate] = FieldInfo( + proxy_revalidate: Optional[UnionMember0RuleSetCacheControlRuleActionParametersProxyRevalidate] = FieldInfo( alias="proxy-revalidate", default=None ) """A cache-control directive configuration.""" - public: Optional[RuleSetCacheControlRuleActionParametersPublic] = None + public: Optional[UnionMember0RuleSetCacheControlRuleActionParametersPublic] = None """A cache-control directive configuration.""" - s_maxage: Optional[RuleSetCacheControlRuleActionParametersSMaxage] = FieldInfo(alias="s-maxage", default=None) + s_maxage: Optional[UnionMember0RuleSetCacheControlRuleActionParametersSMaxage] = FieldInfo( + alias="s-maxage", default=None + ) """ A cache-control directive configuration that accepts a duration value in seconds. """ - stale_if_error: Optional[RuleSetCacheControlRuleActionParametersStaleIfError] = FieldInfo( + stale_if_error: Optional[UnionMember0RuleSetCacheControlRuleActionParametersStaleIfError] = FieldInfo( alias="stale-if-error", default=None ) """ @@ -888,8 +1221,8 @@ class RuleSetCacheControlRuleActionParameters(BaseModel): seconds. """ - stale_while_revalidate: Optional[RuleSetCacheControlRuleActionParametersStaleWhileRevalidate] = FieldInfo( - alias="stale-while-revalidate", default=None + stale_while_revalidate: Optional[UnionMember0RuleSetCacheControlRuleActionParametersStaleWhileRevalidate] = ( + FieldInfo(alias="stale-while-revalidate", default=None) ) """ A cache-control directive configuration that accepts a duration value in @@ -897,7 +1230,7 @@ class RuleSetCacheControlRuleActionParameters(BaseModel): """ -class RuleSetCacheControlRuleExposedCredentialCheck(BaseModel): +class UnionMember0RuleSetCacheControlRuleExposedCredentialCheck(BaseModel): """Configuration for exposed credential checking.""" password_expression: str @@ -907,7 +1240,7 @@ class RuleSetCacheControlRuleExposedCredentialCheck(BaseModel): """An expression that selects the user ID used in the credentials check.""" -class RuleSetCacheControlRuleRatelimit(BaseModel): +class UnionMember0RuleSetCacheControlRuleRatelimit(BaseModel): """An object configuring the rule's rate limit behavior.""" characteristics: List[str] @@ -953,7 +1286,7 @@ class RuleSetCacheControlRuleRatelimit(BaseModel): """ -class RuleSetCacheControlRule(BaseModel): +class UnionMember0RuleSetCacheControlRule(BaseModel): id: str """The unique ID of the rule.""" @@ -974,7 +1307,7 @@ class RuleSetCacheControlRule(BaseModel): version: str """The version of the rule.""" - action_parameters: Optional[RuleSetCacheControlRuleActionParameters] = None + action_parameters: Optional[UnionMember0RuleSetCacheControlRuleActionParameters] = None """The parameters configuring the rule's action.""" categories: Optional[List[str]] = None @@ -983,17 +1316,17 @@ class RuleSetCacheControlRule(BaseModel): description: Optional[str] = None """An informative description of the rule.""" - exposed_credential_check: Optional[RuleSetCacheControlRuleExposedCredentialCheck] = None + exposed_credential_check: Optional[UnionMember0RuleSetCacheControlRuleExposedCredentialCheck] = None """Configuration for exposed credential checking.""" logging: Optional[Logging] = None """An object configuring the rule's logging behavior.""" - ratelimit: Optional[RuleSetCacheControlRuleRatelimit] = None + ratelimit: Optional[UnionMember0RuleSetCacheControlRuleRatelimit] = None """An object configuring the rule's rate limit behavior.""" -class RuleSetCacheSettingsRule(SetCacheSettingsRule): +class UnionMember0RuleSetCacheSettingsRule(SetCacheSettingsRule): id: str # type: ignore action: str # type: ignore @@ -1005,7 +1338,7 @@ class RuleSetCacheSettingsRule(SetCacheSettingsRule): ref: str # type: ignore -class RuleSetCacheTagsRuleActionParametersAddCacheTagsValues(BaseModel): +class UnionMember0RuleSetCacheTagsRuleActionParametersAddCacheTagsValues(BaseModel): """Add cache tags using a list of values.""" operation: Literal["add", "remove", "set"] @@ -1015,7 +1348,7 @@ class RuleSetCacheTagsRuleActionParametersAddCacheTagsValues(BaseModel): """A list of cache tag values.""" -class RuleSetCacheTagsRuleActionParametersAddCacheTagsExpression(BaseModel): +class UnionMember0RuleSetCacheTagsRuleActionParametersAddCacheTagsExpression(BaseModel): """Add cache tags using an expression.""" expression: str @@ -1025,7 +1358,7 @@ class RuleSetCacheTagsRuleActionParametersAddCacheTagsExpression(BaseModel): """The operation to perform on the cache tags.""" -class RuleSetCacheTagsRuleActionParametersRemoveCacheTagsValues(BaseModel): +class UnionMember0RuleSetCacheTagsRuleActionParametersRemoveCacheTagsValues(BaseModel): """Remove cache tags using a list of values.""" operation: Literal["add", "remove", "set"] @@ -1035,7 +1368,7 @@ class RuleSetCacheTagsRuleActionParametersRemoveCacheTagsValues(BaseModel): """A list of cache tag values.""" -class RuleSetCacheTagsRuleActionParametersRemoveCacheTagsExpression(BaseModel): +class UnionMember0RuleSetCacheTagsRuleActionParametersRemoveCacheTagsExpression(BaseModel): """Remove cache tags using an expression.""" expression: str @@ -1045,7 +1378,7 @@ class RuleSetCacheTagsRuleActionParametersRemoveCacheTagsExpression(BaseModel): """The operation to perform on the cache tags.""" -class RuleSetCacheTagsRuleActionParametersSetCacheTagsValues(BaseModel): +class UnionMember0RuleSetCacheTagsRuleActionParametersSetCacheTagsValues(BaseModel): """Set cache tags using a list of values.""" operation: Literal["add", "remove", "set"] @@ -1055,7 +1388,7 @@ class RuleSetCacheTagsRuleActionParametersSetCacheTagsValues(BaseModel): """A list of cache tag values.""" -class RuleSetCacheTagsRuleActionParametersSetCacheTagsExpression(BaseModel): +class UnionMember0RuleSetCacheTagsRuleActionParametersSetCacheTagsExpression(BaseModel): """Set cache tags using an expression.""" expression: str @@ -1065,17 +1398,17 @@ class RuleSetCacheTagsRuleActionParametersSetCacheTagsExpression(BaseModel): """The operation to perform on the cache tags.""" -RuleSetCacheTagsRuleActionParameters: TypeAlias = Union[ - RuleSetCacheTagsRuleActionParametersAddCacheTagsValues, - RuleSetCacheTagsRuleActionParametersAddCacheTagsExpression, - RuleSetCacheTagsRuleActionParametersRemoveCacheTagsValues, - RuleSetCacheTagsRuleActionParametersRemoveCacheTagsExpression, - RuleSetCacheTagsRuleActionParametersSetCacheTagsValues, - RuleSetCacheTagsRuleActionParametersSetCacheTagsExpression, +UnionMember0RuleSetCacheTagsRuleActionParameters: TypeAlias = Union[ + UnionMember0RuleSetCacheTagsRuleActionParametersAddCacheTagsValues, + UnionMember0RuleSetCacheTagsRuleActionParametersAddCacheTagsExpression, + UnionMember0RuleSetCacheTagsRuleActionParametersRemoveCacheTagsValues, + UnionMember0RuleSetCacheTagsRuleActionParametersRemoveCacheTagsExpression, + UnionMember0RuleSetCacheTagsRuleActionParametersSetCacheTagsValues, + UnionMember0RuleSetCacheTagsRuleActionParametersSetCacheTagsExpression, ] -class RuleSetCacheTagsRuleExposedCredentialCheck(BaseModel): +class UnionMember0RuleSetCacheTagsRuleExposedCredentialCheck(BaseModel): """Configuration for exposed credential checking.""" password_expression: str @@ -1085,7 +1418,7 @@ class RuleSetCacheTagsRuleExposedCredentialCheck(BaseModel): """An expression that selects the user ID used in the credentials check.""" -class RuleSetCacheTagsRuleRatelimit(BaseModel): +class UnionMember0RuleSetCacheTagsRuleRatelimit(BaseModel): """An object configuring the rule's rate limit behavior.""" characteristics: List[str] @@ -1131,7 +1464,7 @@ class RuleSetCacheTagsRuleRatelimit(BaseModel): """ -class RuleSetCacheTagsRule(BaseModel): +class UnionMember0RuleSetCacheTagsRule(BaseModel): id: str """The unique ID of the rule.""" @@ -1152,7 +1485,7 @@ class RuleSetCacheTagsRule(BaseModel): version: str """The version of the rule.""" - action_parameters: Optional[RuleSetCacheTagsRuleActionParameters] = None + action_parameters: Optional[UnionMember0RuleSetCacheTagsRuleActionParameters] = None """The parameters configuring the rule's action.""" categories: Optional[List[str]] = None @@ -1161,17 +1494,17 @@ class RuleSetCacheTagsRule(BaseModel): description: Optional[str] = None """An informative description of the rule.""" - exposed_credential_check: Optional[RuleSetCacheTagsRuleExposedCredentialCheck] = None + exposed_credential_check: Optional[UnionMember0RuleSetCacheTagsRuleExposedCredentialCheck] = None """Configuration for exposed credential checking.""" logging: Optional[Logging] = None """An object configuring the rule's logging behavior.""" - ratelimit: Optional[RuleSetCacheTagsRuleRatelimit] = None + ratelimit: Optional[UnionMember0RuleSetCacheTagsRuleRatelimit] = None """An object configuring the rule's rate limit behavior.""" -class RuleSetConfigurationRule(SetConfigRule): +class UnionMember0RuleSetConfigurationRule(SetConfigRule): id: str # type: ignore action: str # type: ignore @@ -1183,7 +1516,7 @@ class RuleSetConfigurationRule(SetConfigRule): ref: str # type: ignore -class RuleSkipRule(SkipRule): +class UnionMember0RuleSkipRule(SkipRule): id: str # type: ignore action: str # type: ignore @@ -1195,14 +1528,14 @@ class RuleSkipRule(SkipRule): ref: str # type: ignore -class RuleTransformResponseHTMLRuleActionParameters(BaseModel): +class UnionMember0RuleTransformResponseHTMLRuleActionParameters(BaseModel): """The parameters configuring the rule's action.""" link_maze: object """Enables the link maze transformation on the response.""" -class RuleTransformResponseHTMLRuleExposedCredentialCheck(BaseModel): +class UnionMember0RuleTransformResponseHTMLRuleExposedCredentialCheck(BaseModel): """Configuration for exposed credential checking.""" password_expression: str @@ -1212,7 +1545,7 @@ class RuleTransformResponseHTMLRuleExposedCredentialCheck(BaseModel): """An expression that selects the user ID used in the credentials check.""" -class RuleTransformResponseHTMLRuleRatelimit(BaseModel): +class UnionMember0RuleTransformResponseHTMLRuleRatelimit(BaseModel): """An object configuring the rule's rate limit behavior.""" characteristics: List[str] @@ -1258,7 +1591,7 @@ class RuleTransformResponseHTMLRuleRatelimit(BaseModel): """ -class RuleTransformResponseHTMLRule(BaseModel): +class UnionMember0RuleTransformResponseHTMLRule(BaseModel): id: str """The unique ID of the rule.""" @@ -1279,7 +1612,7 @@ class RuleTransformResponseHTMLRule(BaseModel): version: str """The version of the rule.""" - action_parameters: Optional[RuleTransformResponseHTMLRuleActionParameters] = None + action_parameters: Optional[UnionMember0RuleTransformResponseHTMLRuleActionParameters] = None """The parameters configuring the rule's action.""" categories: Optional[List[str]] = None @@ -1288,64 +1621,5045 @@ class RuleTransformResponseHTMLRule(BaseModel): description: Optional[str] = None """An informative description of the rule.""" - exposed_credential_check: Optional[RuleTransformResponseHTMLRuleExposedCredentialCheck] = None + exposed_credential_check: Optional[UnionMember0RuleTransformResponseHTMLRuleExposedCredentialCheck] = None """Configuration for exposed credential checking.""" logging: Optional[Logging] = None """An object configuring the rule's logging behavior.""" - ratelimit: Optional[RuleTransformResponseHTMLRuleRatelimit] = None + ratelimit: Optional[UnionMember0RuleTransformResponseHTMLRuleRatelimit] = None """An object configuring the rule's rate limit behavior.""" -Rule: TypeAlias = Union[ - RuleBlockRule, - RuleChallengeRule, - RuleResponseCompressionRule, - RuleDDoSDynamicRule, - RuleExecuteRule, - RuleForceConnectionCloseRule, - RuleJavaScriptChallengeRule, - RuleLogRule, - RuleLogCustomFieldRule, - RuleManagedChallengeRule, - RuleRedirectRule, - RuleRewriteRule, - RuleRouteRule, - RuleScoreRule, - RuleServeErrorRule, - RuleSetCacheControlRule, - RuleSetCacheSettingsRule, - RuleSetCacheTagsRule, - RuleSetConfigurationRule, - RuleSkipRule, - RuleTransformResponseHTMLRule, -] - - -class VersionGetResponse(BaseModel): - """A ruleset object.""" +UnionMember0Rule: TypeAlias = Union[ + UnionMember0RuleBlockRule, + UnionMember0RuleChallengeRule, + UnionMember0RuleResponseCompressionRule, + UnionMember0RuleDDoSDynamicRule, + UnionMember0RuleExecuteRule, + UnionMember0RuleForceConnectionCloseRule, + UnionMember0RuleJavaScriptChallengeRule, + UnionMember0RuleLogRule, + UnionMember0RuleLogCustomFieldRule, + UnionMember0RuleManagedChallengeRule, + UnionMember0RuleRedirectRule, + UnionMember0RuleRewriteRule, + UnionMember0RuleRouteRule, + UnionMember0RuleScoreRule, + UnionMember0RuleServeErrorRule, + UnionMember0RuleSetCacheControlRule, + UnionMember0RuleSetCacheSettingsRule, + UnionMember0RuleSetCacheTagsRule, + UnionMember0RuleSetConfigurationRule, + UnionMember0RuleSkipRule, + UnionMember0RuleTransformResponseHTMLRule, +] - id: str + +class UnionMember0(BaseModel): + id: Optional[str] = None """The unique ID of the ruleset.""" - kind: Kind + description: Optional[str] = None + """An informative description of the ruleset.""" + + kind: Optional[Kind] = None """The kind of the ruleset.""" - last_updated: datetime + last_updated: Optional[datetime] = None """The timestamp of when the ruleset was last modified.""" - name: str + name: Optional[str] = None """The human-readable name of the ruleset.""" - phase: Phase + phase: Optional[Phase] = None """The phase of the ruleset.""" - rules: List[Rule] + rules: Optional[List[UnionMember0Rule]] = None """The list of rules in the ruleset.""" - version: str + version: Optional[str] = None """The version of the ruleset.""" + +class UnionMember1RuleBlockRule(BlockRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember1RuleChallengeRuleExposedCredentialCheck(BaseModel): + """Configuration for exposed credential checking.""" + + password_expression: str + """An expression that selects the password used in the credentials check.""" + + username_expression: str + """An expression that selects the user ID used in the credentials check.""" + + +class UnionMember1RuleChallengeRuleRatelimit(BaseModel): + """An object configuring the rule's rate limit behavior.""" + + characteristics: List[str] + """ + Characteristics of the request on which the rate limit counter will be + incremented. + """ + + period: int + """Period in seconds over which the counter is being incremented.""" + + counting_expression: Optional[str] = None + """An expression that defines when the rate limit counter should be incremented. + + It defaults to the same as the rule's expression. + """ + + mitigation_timeout: Optional[int] = None + """ + Period of time in seconds after which the action will be disabled following its + first execution. + """ + + requests_per_period: Optional[int] = None + """ + The threshold of requests per period after which the action will be executed for + the first time. + """ + + requests_to_origin: Optional[bool] = None + """Whether counting is only performed when an origin is reached.""" + + score_per_period: Optional[int] = None + """ + The score threshold per period for which the action will be executed the first + time. + """ + + score_response_header_name: Optional[str] = None + """ + A response header name provided by the origin, which contains the score to + increment rate limit counter with. + """ + + +class UnionMember1RuleChallengeRule(BaseModel): + id: str + """The unique ID of the rule.""" + + action: Literal["challenge"] + """The action to perform when the rule matches.""" + + enabled: bool + """Whether the rule should be executed.""" + + expression: str + """The expression defining which traffic will match the rule.""" + + last_updated: datetime + """The timestamp of when the rule was last modified.""" + + ref: str + """The reference of the rule (the rule's ID by default).""" + + version: str + """The version of the rule.""" + + action_parameters: Optional[object] = None + """The parameters configuring the rule's action.""" + + categories: Optional[List[str]] = None + """The categories of the rule.""" + description: Optional[str] = None - """An informative description of the ruleset.""" + """An informative description of the rule.""" + + exposed_credential_check: Optional[UnionMember1RuleChallengeRuleExposedCredentialCheck] = None + """Configuration for exposed credential checking.""" + + logging: Optional[Logging] = None + """An object configuring the rule's logging behavior.""" + + ratelimit: Optional[UnionMember1RuleChallengeRuleRatelimit] = None + """An object configuring the rule's rate limit behavior.""" + + +class UnionMember1RuleResponseCompressionRule(CompressResponseRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember1RuleDDoSDynamicRule(DDoSDynamicRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember1RuleExecuteRule(ExecuteRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember1RuleForceConnectionCloseRule(ForceConnectionCloseRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember1RuleJavaScriptChallengeRuleExposedCredentialCheck(BaseModel): + """Configuration for exposed credential checking.""" + + password_expression: str + """An expression that selects the password used in the credentials check.""" + + username_expression: str + """An expression that selects the user ID used in the credentials check.""" + + +class UnionMember1RuleJavaScriptChallengeRuleRatelimit(BaseModel): + """An object configuring the rule's rate limit behavior.""" + + characteristics: List[str] + """ + Characteristics of the request on which the rate limit counter will be + incremented. + """ + + period: int + """Period in seconds over which the counter is being incremented.""" + + counting_expression: Optional[str] = None + """An expression that defines when the rate limit counter should be incremented. + + It defaults to the same as the rule's expression. + """ + + mitigation_timeout: Optional[int] = None + """ + Period of time in seconds after which the action will be disabled following its + first execution. + """ + + requests_per_period: Optional[int] = None + """ + The threshold of requests per period after which the action will be executed for + the first time. + """ + + requests_to_origin: Optional[bool] = None + """Whether counting is only performed when an origin is reached.""" + + score_per_period: Optional[int] = None + """ + The score threshold per period for which the action will be executed the first + time. + """ + + score_response_header_name: Optional[str] = None + """ + A response header name provided by the origin, which contains the score to + increment rate limit counter with. + """ + + +class UnionMember1RuleJavaScriptChallengeRule(BaseModel): + id: str + """The unique ID of the rule.""" + + action: Literal["js_challenge"] + """The action to perform when the rule matches.""" + + enabled: bool + """Whether the rule should be executed.""" + + expression: str + """The expression defining which traffic will match the rule.""" + + last_updated: datetime + """The timestamp of when the rule was last modified.""" + + ref: str + """The reference of the rule (the rule's ID by default).""" + + version: str + """The version of the rule.""" + + action_parameters: Optional[object] = None + """The parameters configuring the rule's action.""" + + categories: Optional[List[str]] = None + """The categories of the rule.""" + + description: Optional[str] = None + """An informative description of the rule.""" + + exposed_credential_check: Optional[UnionMember1RuleJavaScriptChallengeRuleExposedCredentialCheck] = None + """Configuration for exposed credential checking.""" + + logging: Optional[Logging] = None + """An object configuring the rule's logging behavior.""" + + ratelimit: Optional[UnionMember1RuleJavaScriptChallengeRuleRatelimit] = None + """An object configuring the rule's rate limit behavior.""" + + +class UnionMember1RuleLogRule(LogRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember1RuleLogCustomFieldRule(LogCustomFieldRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember1RuleManagedChallengeRule(ManagedChallengeRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember1RuleRedirectRule(RedirectRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember1RuleRewriteRule(RewriteRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember1RuleRouteRule(RouteRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember1RuleScoreRule(ScoreRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember1RuleServeErrorRule(ServeErrorRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember1RuleSetCacheControlRuleActionParametersImmutableSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember1RuleSetCacheControlRuleActionParametersImmutableRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember1RuleSetCacheControlRuleActionParametersImmutable: TypeAlias = Union[ + UnionMember1RuleSetCacheControlRuleActionParametersImmutableSetDirective, + UnionMember1RuleSetCacheControlRuleActionParametersImmutableRemoveDirective, +] + + +class UnionMember1RuleSetCacheControlRuleActionParametersMaxAgeSetDirective(BaseModel): + """Set the directive with a duration value in seconds.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + value: int + """The duration value in seconds for the directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember1RuleSetCacheControlRuleActionParametersMaxAgeRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember1RuleSetCacheControlRuleActionParametersMaxAge: TypeAlias = Union[ + UnionMember1RuleSetCacheControlRuleActionParametersMaxAgeSetDirective, + UnionMember1RuleSetCacheControlRuleActionParametersMaxAgeRemoveDirective, +] + + +class UnionMember1RuleSetCacheControlRuleActionParametersMustRevalidateSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember1RuleSetCacheControlRuleActionParametersMustRevalidateRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember1RuleSetCacheControlRuleActionParametersMustRevalidate: TypeAlias = Union[ + UnionMember1RuleSetCacheControlRuleActionParametersMustRevalidateSetDirective, + UnionMember1RuleSetCacheControlRuleActionParametersMustRevalidateRemoveDirective, +] + + +class UnionMember1RuleSetCacheControlRuleActionParametersMustUnderstandSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember1RuleSetCacheControlRuleActionParametersMustUnderstandRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember1RuleSetCacheControlRuleActionParametersMustUnderstand: TypeAlias = Union[ + UnionMember1RuleSetCacheControlRuleActionParametersMustUnderstandSetDirective, + UnionMember1RuleSetCacheControlRuleActionParametersMustUnderstandRemoveDirective, +] + + +class UnionMember1RuleSetCacheControlRuleActionParametersNoCacheSetDirective(BaseModel): + """Set the directive with optional qualifiers.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + qualifiers: Optional[List[str]] = None + """ + Optional list of header names to qualify the directive (e.g., for "private" or + "no-cache" directives). + """ + + +class UnionMember1RuleSetCacheControlRuleActionParametersNoCacheRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember1RuleSetCacheControlRuleActionParametersNoCache: TypeAlias = Union[ + UnionMember1RuleSetCacheControlRuleActionParametersNoCacheSetDirective, + UnionMember1RuleSetCacheControlRuleActionParametersNoCacheRemoveDirective, +] + + +class UnionMember1RuleSetCacheControlRuleActionParametersNoStoreSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember1RuleSetCacheControlRuleActionParametersNoStoreRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember1RuleSetCacheControlRuleActionParametersNoStore: TypeAlias = Union[ + UnionMember1RuleSetCacheControlRuleActionParametersNoStoreSetDirective, + UnionMember1RuleSetCacheControlRuleActionParametersNoStoreRemoveDirective, +] + + +class UnionMember1RuleSetCacheControlRuleActionParametersNoTransformSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember1RuleSetCacheControlRuleActionParametersNoTransformRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember1RuleSetCacheControlRuleActionParametersNoTransform: TypeAlias = Union[ + UnionMember1RuleSetCacheControlRuleActionParametersNoTransformSetDirective, + UnionMember1RuleSetCacheControlRuleActionParametersNoTransformRemoveDirective, +] + + +class UnionMember1RuleSetCacheControlRuleActionParametersPrivateSetDirective(BaseModel): + """Set the directive with optional qualifiers.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + qualifiers: Optional[List[str]] = None + """ + Optional list of header names to qualify the directive (e.g., for "private" or + "no-cache" directives). + """ + + +class UnionMember1RuleSetCacheControlRuleActionParametersPrivateRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember1RuleSetCacheControlRuleActionParametersPrivate: TypeAlias = Union[ + UnionMember1RuleSetCacheControlRuleActionParametersPrivateSetDirective, + UnionMember1RuleSetCacheControlRuleActionParametersPrivateRemoveDirective, +] + + +class UnionMember1RuleSetCacheControlRuleActionParametersProxyRevalidateSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember1RuleSetCacheControlRuleActionParametersProxyRevalidateRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember1RuleSetCacheControlRuleActionParametersProxyRevalidate: TypeAlias = Union[ + UnionMember1RuleSetCacheControlRuleActionParametersProxyRevalidateSetDirective, + UnionMember1RuleSetCacheControlRuleActionParametersProxyRevalidateRemoveDirective, +] + + +class UnionMember1RuleSetCacheControlRuleActionParametersPublicSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember1RuleSetCacheControlRuleActionParametersPublicRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember1RuleSetCacheControlRuleActionParametersPublic: TypeAlias = Union[ + UnionMember1RuleSetCacheControlRuleActionParametersPublicSetDirective, + UnionMember1RuleSetCacheControlRuleActionParametersPublicRemoveDirective, +] + + +class UnionMember1RuleSetCacheControlRuleActionParametersSMaxageSetDirective(BaseModel): + """Set the directive with a duration value in seconds.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + value: int + """The duration value in seconds for the directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember1RuleSetCacheControlRuleActionParametersSMaxageRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember1RuleSetCacheControlRuleActionParametersSMaxage: TypeAlias = Union[ + UnionMember1RuleSetCacheControlRuleActionParametersSMaxageSetDirective, + UnionMember1RuleSetCacheControlRuleActionParametersSMaxageRemoveDirective, +] + + +class UnionMember1RuleSetCacheControlRuleActionParametersStaleIfErrorSetDirective(BaseModel): + """Set the directive with a duration value in seconds.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + value: int + """The duration value in seconds for the directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember1RuleSetCacheControlRuleActionParametersStaleIfErrorRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember1RuleSetCacheControlRuleActionParametersStaleIfError: TypeAlias = Union[ + UnionMember1RuleSetCacheControlRuleActionParametersStaleIfErrorSetDirective, + UnionMember1RuleSetCacheControlRuleActionParametersStaleIfErrorRemoveDirective, +] + + +class UnionMember1RuleSetCacheControlRuleActionParametersStaleWhileRevalidateSetDirective(BaseModel): + """Set the directive with a duration value in seconds.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + value: int + """The duration value in seconds for the directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember1RuleSetCacheControlRuleActionParametersStaleWhileRevalidateRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember1RuleSetCacheControlRuleActionParametersStaleWhileRevalidate: TypeAlias = Union[ + UnionMember1RuleSetCacheControlRuleActionParametersStaleWhileRevalidateSetDirective, + UnionMember1RuleSetCacheControlRuleActionParametersStaleWhileRevalidateRemoveDirective, +] + + +class UnionMember1RuleSetCacheControlRuleActionParameters(BaseModel): + """The parameters configuring the rule's action.""" + + immutable: Optional[UnionMember1RuleSetCacheControlRuleActionParametersImmutable] = None + """A cache-control directive configuration.""" + + max_age: Optional[UnionMember1RuleSetCacheControlRuleActionParametersMaxAge] = FieldInfo( + alias="max-age", default=None + ) + """ + A cache-control directive configuration that accepts a duration value in + seconds. + """ + + must_revalidate: Optional[UnionMember1RuleSetCacheControlRuleActionParametersMustRevalidate] = FieldInfo( + alias="must-revalidate", default=None + ) + """A cache-control directive configuration.""" + + must_understand: Optional[UnionMember1RuleSetCacheControlRuleActionParametersMustUnderstand] = FieldInfo( + alias="must-understand", default=None + ) + """A cache-control directive configuration.""" + + no_cache: Optional[UnionMember1RuleSetCacheControlRuleActionParametersNoCache] = FieldInfo( + alias="no-cache", default=None + ) + """ + A cache-control directive configuration that accepts optional qualifiers (header + names). + """ + + no_store: Optional[UnionMember1RuleSetCacheControlRuleActionParametersNoStore] = FieldInfo( + alias="no-store", default=None + ) + """A cache-control directive configuration.""" + + no_transform: Optional[UnionMember1RuleSetCacheControlRuleActionParametersNoTransform] = FieldInfo( + alias="no-transform", default=None + ) + """A cache-control directive configuration.""" + + private: Optional[UnionMember1RuleSetCacheControlRuleActionParametersPrivate] = None + """ + A cache-control directive configuration that accepts optional qualifiers (header + names). + """ + + proxy_revalidate: Optional[UnionMember1RuleSetCacheControlRuleActionParametersProxyRevalidate] = FieldInfo( + alias="proxy-revalidate", default=None + ) + """A cache-control directive configuration.""" + + public: Optional[UnionMember1RuleSetCacheControlRuleActionParametersPublic] = None + """A cache-control directive configuration.""" + + s_maxage: Optional[UnionMember1RuleSetCacheControlRuleActionParametersSMaxage] = FieldInfo( + alias="s-maxage", default=None + ) + """ + A cache-control directive configuration that accepts a duration value in + seconds. + """ + + stale_if_error: Optional[UnionMember1RuleSetCacheControlRuleActionParametersStaleIfError] = FieldInfo( + alias="stale-if-error", default=None + ) + """ + A cache-control directive configuration that accepts a duration value in + seconds. + """ + + stale_while_revalidate: Optional[UnionMember1RuleSetCacheControlRuleActionParametersStaleWhileRevalidate] = ( + FieldInfo(alias="stale-while-revalidate", default=None) + ) + """ + A cache-control directive configuration that accepts a duration value in + seconds. + """ + + +class UnionMember1RuleSetCacheControlRuleExposedCredentialCheck(BaseModel): + """Configuration for exposed credential checking.""" + + password_expression: str + """An expression that selects the password used in the credentials check.""" + + username_expression: str + """An expression that selects the user ID used in the credentials check.""" + + +class UnionMember1RuleSetCacheControlRuleRatelimit(BaseModel): + """An object configuring the rule's rate limit behavior.""" + + characteristics: List[str] + """ + Characteristics of the request on which the rate limit counter will be + incremented. + """ + + period: int + """Period in seconds over which the counter is being incremented.""" + + counting_expression: Optional[str] = None + """An expression that defines when the rate limit counter should be incremented. + + It defaults to the same as the rule's expression. + """ + + mitigation_timeout: Optional[int] = None + """ + Period of time in seconds after which the action will be disabled following its + first execution. + """ + + requests_per_period: Optional[int] = None + """ + The threshold of requests per period after which the action will be executed for + the first time. + """ + + requests_to_origin: Optional[bool] = None + """Whether counting is only performed when an origin is reached.""" + + score_per_period: Optional[int] = None + """ + The score threshold per period for which the action will be executed the first + time. + """ + + score_response_header_name: Optional[str] = None + """ + A response header name provided by the origin, which contains the score to + increment rate limit counter with. + """ + + +class UnionMember1RuleSetCacheControlRule(BaseModel): + id: str + """The unique ID of the rule.""" + + action: Literal["set_cache_control"] + """The action to perform when the rule matches.""" + + enabled: bool + + expression: str + """The expression defining which traffic will match the rule.""" + + last_updated: datetime + """The timestamp of when the rule was last modified.""" + + ref: str + """The reference of the rule (the rule's ID by default).""" + + version: str + """The version of the rule.""" + + action_parameters: Optional[UnionMember1RuleSetCacheControlRuleActionParameters] = None + """The parameters configuring the rule's action.""" + + categories: Optional[List[str]] = None + """The categories of the rule.""" + + description: Optional[str] = None + """An informative description of the rule.""" + + exposed_credential_check: Optional[UnionMember1RuleSetCacheControlRuleExposedCredentialCheck] = None + """Configuration for exposed credential checking.""" + + logging: Optional[Logging] = None + """An object configuring the rule's logging behavior.""" + + ratelimit: Optional[UnionMember1RuleSetCacheControlRuleRatelimit] = None + """An object configuring the rule's rate limit behavior.""" + + +class UnionMember1RuleSetCacheSettingsRule(SetCacheSettingsRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember1RuleSetCacheTagsRuleActionParametersAddCacheTagsValues(BaseModel): + """Add cache tags using a list of values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + values: List[str] + """A list of cache tag values.""" + + +class UnionMember1RuleSetCacheTagsRuleActionParametersAddCacheTagsExpression(BaseModel): + """Add cache tags using an expression.""" + + expression: str + """An expression that evaluates to an array of cache tag values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + +class UnionMember1RuleSetCacheTagsRuleActionParametersRemoveCacheTagsValues(BaseModel): + """Remove cache tags using a list of values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + values: List[str] + """A list of cache tag values.""" + + +class UnionMember1RuleSetCacheTagsRuleActionParametersRemoveCacheTagsExpression(BaseModel): + """Remove cache tags using an expression.""" + + expression: str + """An expression that evaluates to an array of cache tag values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + +class UnionMember1RuleSetCacheTagsRuleActionParametersSetCacheTagsValues(BaseModel): + """Set cache tags using a list of values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + values: List[str] + """A list of cache tag values.""" + + +class UnionMember1RuleSetCacheTagsRuleActionParametersSetCacheTagsExpression(BaseModel): + """Set cache tags using an expression.""" + + expression: str + """An expression that evaluates to an array of cache tag values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + +UnionMember1RuleSetCacheTagsRuleActionParameters: TypeAlias = Union[ + UnionMember1RuleSetCacheTagsRuleActionParametersAddCacheTagsValues, + UnionMember1RuleSetCacheTagsRuleActionParametersAddCacheTagsExpression, + UnionMember1RuleSetCacheTagsRuleActionParametersRemoveCacheTagsValues, + UnionMember1RuleSetCacheTagsRuleActionParametersRemoveCacheTagsExpression, + UnionMember1RuleSetCacheTagsRuleActionParametersSetCacheTagsValues, + UnionMember1RuleSetCacheTagsRuleActionParametersSetCacheTagsExpression, +] + + +class UnionMember1RuleSetCacheTagsRuleExposedCredentialCheck(BaseModel): + """Configuration for exposed credential checking.""" + + password_expression: str + """An expression that selects the password used in the credentials check.""" + + username_expression: str + """An expression that selects the user ID used in the credentials check.""" + + +class UnionMember1RuleSetCacheTagsRuleRatelimit(BaseModel): + """An object configuring the rule's rate limit behavior.""" + + characteristics: List[str] + """ + Characteristics of the request on which the rate limit counter will be + incremented. + """ + + period: int + """Period in seconds over which the counter is being incremented.""" + + counting_expression: Optional[str] = None + """An expression that defines when the rate limit counter should be incremented. + + It defaults to the same as the rule's expression. + """ + + mitigation_timeout: Optional[int] = None + """ + Period of time in seconds after which the action will be disabled following its + first execution. + """ + + requests_per_period: Optional[int] = None + """ + The threshold of requests per period after which the action will be executed for + the first time. + """ + + requests_to_origin: Optional[bool] = None + """Whether counting is only performed when an origin is reached.""" + + score_per_period: Optional[int] = None + """ + The score threshold per period for which the action will be executed the first + time. + """ + + score_response_header_name: Optional[str] = None + """ + A response header name provided by the origin, which contains the score to + increment rate limit counter with. + """ + + +class UnionMember1RuleSetCacheTagsRule(BaseModel): + id: str + """The unique ID of the rule.""" + + action: Literal["set_cache_tags"] + """The action to perform when the rule matches.""" + + enabled: bool + + expression: str + """The expression defining which traffic will match the rule.""" + + last_updated: datetime + """The timestamp of when the rule was last modified.""" + + ref: str + """The reference of the rule (the rule's ID by default).""" + + version: str + """The version of the rule.""" + + action_parameters: Optional[UnionMember1RuleSetCacheTagsRuleActionParameters] = None + """The parameters configuring the rule's action.""" + + categories: Optional[List[str]] = None + """The categories of the rule.""" + + description: Optional[str] = None + """An informative description of the rule.""" + + exposed_credential_check: Optional[UnionMember1RuleSetCacheTagsRuleExposedCredentialCheck] = None + """Configuration for exposed credential checking.""" + + logging: Optional[Logging] = None + """An object configuring the rule's logging behavior.""" + + ratelimit: Optional[UnionMember1RuleSetCacheTagsRuleRatelimit] = None + """An object configuring the rule's rate limit behavior.""" + + +class UnionMember1RuleSetConfigurationRule(SetConfigRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember1RuleSkipRule(SkipRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember1RuleTransformResponseHTMLRuleActionParameters(BaseModel): + """The parameters configuring the rule's action.""" + + link_maze: object + """Enables the link maze transformation on the response.""" + + +class UnionMember1RuleTransformResponseHTMLRuleExposedCredentialCheck(BaseModel): + """Configuration for exposed credential checking.""" + + password_expression: str + """An expression that selects the password used in the credentials check.""" + + username_expression: str + """An expression that selects the user ID used in the credentials check.""" + + +class UnionMember1RuleTransformResponseHTMLRuleRatelimit(BaseModel): + """An object configuring the rule's rate limit behavior.""" + + characteristics: List[str] + """ + Characteristics of the request on which the rate limit counter will be + incremented. + """ + + period: int + """Period in seconds over which the counter is being incremented.""" + + counting_expression: Optional[str] = None + """An expression that defines when the rate limit counter should be incremented. + + It defaults to the same as the rule's expression. + """ + + mitigation_timeout: Optional[int] = None + """ + Period of time in seconds after which the action will be disabled following its + first execution. + """ + + requests_per_period: Optional[int] = None + """ + The threshold of requests per period after which the action will be executed for + the first time. + """ + + requests_to_origin: Optional[bool] = None + """Whether counting is only performed when an origin is reached.""" + + score_per_period: Optional[int] = None + """ + The score threshold per period for which the action will be executed the first + time. + """ + + score_response_header_name: Optional[str] = None + """ + A response header name provided by the origin, which contains the score to + increment rate limit counter with. + """ + + +class UnionMember1RuleTransformResponseHTMLRule(BaseModel): + id: str + """The unique ID of the rule.""" + + action: Literal["transform_response_html"] + """The action to perform when the rule matches.""" + + enabled: bool + + expression: str + """The expression defining which traffic will match the rule.""" + + last_updated: datetime + """The timestamp of when the rule was last modified.""" + + ref: str + """The reference of the rule (the rule's ID by default).""" + + version: str + """The version of the rule.""" + + action_parameters: Optional[UnionMember1RuleTransformResponseHTMLRuleActionParameters] = None + """The parameters configuring the rule's action.""" + + categories: Optional[List[str]] = None + """The categories of the rule.""" + + description: Optional[str] = None + """An informative description of the rule.""" + + exposed_credential_check: Optional[UnionMember1RuleTransformResponseHTMLRuleExposedCredentialCheck] = None + """Configuration for exposed credential checking.""" + + logging: Optional[Logging] = None + """An object configuring the rule's logging behavior.""" + + ratelimit: Optional[UnionMember1RuleTransformResponseHTMLRuleRatelimit] = None + """An object configuring the rule's rate limit behavior.""" + + +UnionMember1Rule: TypeAlias = Union[ + UnionMember1RuleBlockRule, + UnionMember1RuleChallengeRule, + UnionMember1RuleResponseCompressionRule, + UnionMember1RuleDDoSDynamicRule, + UnionMember1RuleExecuteRule, + UnionMember1RuleForceConnectionCloseRule, + UnionMember1RuleJavaScriptChallengeRule, + UnionMember1RuleLogRule, + UnionMember1RuleLogCustomFieldRule, + UnionMember1RuleManagedChallengeRule, + UnionMember1RuleRedirectRule, + UnionMember1RuleRewriteRule, + UnionMember1RuleRouteRule, + UnionMember1RuleScoreRule, + UnionMember1RuleServeErrorRule, + UnionMember1RuleSetCacheControlRule, + UnionMember1RuleSetCacheSettingsRule, + UnionMember1RuleSetCacheTagsRule, + UnionMember1RuleSetConfigurationRule, + UnionMember1RuleSkipRule, + UnionMember1RuleTransformResponseHTMLRule, +] + + +class UnionMember1(BaseModel): + id: Optional[str] = None + """The unique ID of the ruleset.""" + + description: Optional[str] = None + """An informative description of the ruleset.""" + + kind: Optional[Kind] = None + """The kind of the ruleset.""" + + last_updated: Optional[datetime] = None + """The timestamp of when the ruleset was last modified.""" + + name: Optional[str] = None + """The human-readable name of the ruleset.""" + + phase: Optional[Phase] = None + """The phase of the ruleset.""" + + rules: Optional[List[UnionMember1Rule]] = None + """The list of rules in the ruleset.""" + + version: Optional[str] = None + """The version of the ruleset.""" + + +class UnionMember2RuleBlockRule(BlockRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember2RuleChallengeRuleExposedCredentialCheck(BaseModel): + """Configuration for exposed credential checking.""" + + password_expression: str + """An expression that selects the password used in the credentials check.""" + + username_expression: str + """An expression that selects the user ID used in the credentials check.""" + + +class UnionMember2RuleChallengeRuleRatelimit(BaseModel): + """An object configuring the rule's rate limit behavior.""" + + characteristics: List[str] + """ + Characteristics of the request on which the rate limit counter will be + incremented. + """ + + period: int + """Period in seconds over which the counter is being incremented.""" + + counting_expression: Optional[str] = None + """An expression that defines when the rate limit counter should be incremented. + + It defaults to the same as the rule's expression. + """ + + mitigation_timeout: Optional[int] = None + """ + Period of time in seconds after which the action will be disabled following its + first execution. + """ + + requests_per_period: Optional[int] = None + """ + The threshold of requests per period after which the action will be executed for + the first time. + """ + + requests_to_origin: Optional[bool] = None + """Whether counting is only performed when an origin is reached.""" + + score_per_period: Optional[int] = None + """ + The score threshold per period for which the action will be executed the first + time. + """ + + score_response_header_name: Optional[str] = None + """ + A response header name provided by the origin, which contains the score to + increment rate limit counter with. + """ + + +class UnionMember2RuleChallengeRule(BaseModel): + id: str + """The unique ID of the rule.""" + + action: Literal["challenge"] + """The action to perform when the rule matches.""" + + enabled: bool + """Whether the rule should be executed.""" + + expression: str + """The expression defining which traffic will match the rule.""" + + last_updated: datetime + """The timestamp of when the rule was last modified.""" + + ref: str + """The reference of the rule (the rule's ID by default).""" + + version: str + """The version of the rule.""" + + action_parameters: Optional[object] = None + """The parameters configuring the rule's action.""" + + categories: Optional[List[str]] = None + """The categories of the rule.""" + + description: Optional[str] = None + """An informative description of the rule.""" + + exposed_credential_check: Optional[UnionMember2RuleChallengeRuleExposedCredentialCheck] = None + """Configuration for exposed credential checking.""" + + logging: Optional[Logging] = None + """An object configuring the rule's logging behavior.""" + + ratelimit: Optional[UnionMember2RuleChallengeRuleRatelimit] = None + """An object configuring the rule's rate limit behavior.""" + + +class UnionMember2RuleResponseCompressionRule(CompressResponseRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember2RuleDDoSDynamicRule(DDoSDynamicRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember2RuleExecuteRule(ExecuteRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember2RuleForceConnectionCloseRule(ForceConnectionCloseRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember2RuleJavaScriptChallengeRuleExposedCredentialCheck(BaseModel): + """Configuration for exposed credential checking.""" + + password_expression: str + """An expression that selects the password used in the credentials check.""" + + username_expression: str + """An expression that selects the user ID used in the credentials check.""" + + +class UnionMember2RuleJavaScriptChallengeRuleRatelimit(BaseModel): + """An object configuring the rule's rate limit behavior.""" + + characteristics: List[str] + """ + Characteristics of the request on which the rate limit counter will be + incremented. + """ + + period: int + """Period in seconds over which the counter is being incremented.""" + + counting_expression: Optional[str] = None + """An expression that defines when the rate limit counter should be incremented. + + It defaults to the same as the rule's expression. + """ + + mitigation_timeout: Optional[int] = None + """ + Period of time in seconds after which the action will be disabled following its + first execution. + """ + + requests_per_period: Optional[int] = None + """ + The threshold of requests per period after which the action will be executed for + the first time. + """ + + requests_to_origin: Optional[bool] = None + """Whether counting is only performed when an origin is reached.""" + + score_per_period: Optional[int] = None + """ + The score threshold per period for which the action will be executed the first + time. + """ + + score_response_header_name: Optional[str] = None + """ + A response header name provided by the origin, which contains the score to + increment rate limit counter with. + """ + + +class UnionMember2RuleJavaScriptChallengeRule(BaseModel): + id: str + """The unique ID of the rule.""" + + action: Literal["js_challenge"] + """The action to perform when the rule matches.""" + + enabled: bool + """Whether the rule should be executed.""" + + expression: str + """The expression defining which traffic will match the rule.""" + + last_updated: datetime + """The timestamp of when the rule was last modified.""" + + ref: str + """The reference of the rule (the rule's ID by default).""" + + version: str + """The version of the rule.""" + + action_parameters: Optional[object] = None + """The parameters configuring the rule's action.""" + + categories: Optional[List[str]] = None + """The categories of the rule.""" + + description: Optional[str] = None + """An informative description of the rule.""" + + exposed_credential_check: Optional[UnionMember2RuleJavaScriptChallengeRuleExposedCredentialCheck] = None + """Configuration for exposed credential checking.""" + + logging: Optional[Logging] = None + """An object configuring the rule's logging behavior.""" + + ratelimit: Optional[UnionMember2RuleJavaScriptChallengeRuleRatelimit] = None + """An object configuring the rule's rate limit behavior.""" + + +class UnionMember2RuleLogRule(LogRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember2RuleLogCustomFieldRule(LogCustomFieldRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember2RuleManagedChallengeRule(ManagedChallengeRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember2RuleRedirectRule(RedirectRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember2RuleRewriteRule(RewriteRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember2RuleRouteRule(RouteRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember2RuleScoreRule(ScoreRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember2RuleServeErrorRule(ServeErrorRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember2RuleSetCacheControlRuleActionParametersImmutableSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember2RuleSetCacheControlRuleActionParametersImmutableRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember2RuleSetCacheControlRuleActionParametersImmutable: TypeAlias = Union[ + UnionMember2RuleSetCacheControlRuleActionParametersImmutableSetDirective, + UnionMember2RuleSetCacheControlRuleActionParametersImmutableRemoveDirective, +] + + +class UnionMember2RuleSetCacheControlRuleActionParametersMaxAgeSetDirective(BaseModel): + """Set the directive with a duration value in seconds.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + value: int + """The duration value in seconds for the directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember2RuleSetCacheControlRuleActionParametersMaxAgeRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember2RuleSetCacheControlRuleActionParametersMaxAge: TypeAlias = Union[ + UnionMember2RuleSetCacheControlRuleActionParametersMaxAgeSetDirective, + UnionMember2RuleSetCacheControlRuleActionParametersMaxAgeRemoveDirective, +] + + +class UnionMember2RuleSetCacheControlRuleActionParametersMustRevalidateSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember2RuleSetCacheControlRuleActionParametersMustRevalidateRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember2RuleSetCacheControlRuleActionParametersMustRevalidate: TypeAlias = Union[ + UnionMember2RuleSetCacheControlRuleActionParametersMustRevalidateSetDirective, + UnionMember2RuleSetCacheControlRuleActionParametersMustRevalidateRemoveDirective, +] + + +class UnionMember2RuleSetCacheControlRuleActionParametersMustUnderstandSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember2RuleSetCacheControlRuleActionParametersMustUnderstandRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember2RuleSetCacheControlRuleActionParametersMustUnderstand: TypeAlias = Union[ + UnionMember2RuleSetCacheControlRuleActionParametersMustUnderstandSetDirective, + UnionMember2RuleSetCacheControlRuleActionParametersMustUnderstandRemoveDirective, +] + + +class UnionMember2RuleSetCacheControlRuleActionParametersNoCacheSetDirective(BaseModel): + """Set the directive with optional qualifiers.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + qualifiers: Optional[List[str]] = None + """ + Optional list of header names to qualify the directive (e.g., for "private" or + "no-cache" directives). + """ + + +class UnionMember2RuleSetCacheControlRuleActionParametersNoCacheRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember2RuleSetCacheControlRuleActionParametersNoCache: TypeAlias = Union[ + UnionMember2RuleSetCacheControlRuleActionParametersNoCacheSetDirective, + UnionMember2RuleSetCacheControlRuleActionParametersNoCacheRemoveDirective, +] + + +class UnionMember2RuleSetCacheControlRuleActionParametersNoStoreSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember2RuleSetCacheControlRuleActionParametersNoStoreRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember2RuleSetCacheControlRuleActionParametersNoStore: TypeAlias = Union[ + UnionMember2RuleSetCacheControlRuleActionParametersNoStoreSetDirective, + UnionMember2RuleSetCacheControlRuleActionParametersNoStoreRemoveDirective, +] + + +class UnionMember2RuleSetCacheControlRuleActionParametersNoTransformSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember2RuleSetCacheControlRuleActionParametersNoTransformRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember2RuleSetCacheControlRuleActionParametersNoTransform: TypeAlias = Union[ + UnionMember2RuleSetCacheControlRuleActionParametersNoTransformSetDirective, + UnionMember2RuleSetCacheControlRuleActionParametersNoTransformRemoveDirective, +] + + +class UnionMember2RuleSetCacheControlRuleActionParametersPrivateSetDirective(BaseModel): + """Set the directive with optional qualifiers.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + qualifiers: Optional[List[str]] = None + """ + Optional list of header names to qualify the directive (e.g., for "private" or + "no-cache" directives). + """ + + +class UnionMember2RuleSetCacheControlRuleActionParametersPrivateRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember2RuleSetCacheControlRuleActionParametersPrivate: TypeAlias = Union[ + UnionMember2RuleSetCacheControlRuleActionParametersPrivateSetDirective, + UnionMember2RuleSetCacheControlRuleActionParametersPrivateRemoveDirective, +] + + +class UnionMember2RuleSetCacheControlRuleActionParametersProxyRevalidateSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember2RuleSetCacheControlRuleActionParametersProxyRevalidateRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember2RuleSetCacheControlRuleActionParametersProxyRevalidate: TypeAlias = Union[ + UnionMember2RuleSetCacheControlRuleActionParametersProxyRevalidateSetDirective, + UnionMember2RuleSetCacheControlRuleActionParametersProxyRevalidateRemoveDirective, +] + + +class UnionMember2RuleSetCacheControlRuleActionParametersPublicSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember2RuleSetCacheControlRuleActionParametersPublicRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember2RuleSetCacheControlRuleActionParametersPublic: TypeAlias = Union[ + UnionMember2RuleSetCacheControlRuleActionParametersPublicSetDirective, + UnionMember2RuleSetCacheControlRuleActionParametersPublicRemoveDirective, +] + + +class UnionMember2RuleSetCacheControlRuleActionParametersSMaxageSetDirective(BaseModel): + """Set the directive with a duration value in seconds.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + value: int + """The duration value in seconds for the directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember2RuleSetCacheControlRuleActionParametersSMaxageRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember2RuleSetCacheControlRuleActionParametersSMaxage: TypeAlias = Union[ + UnionMember2RuleSetCacheControlRuleActionParametersSMaxageSetDirective, + UnionMember2RuleSetCacheControlRuleActionParametersSMaxageRemoveDirective, +] + + +class UnionMember2RuleSetCacheControlRuleActionParametersStaleIfErrorSetDirective(BaseModel): + """Set the directive with a duration value in seconds.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + value: int + """The duration value in seconds for the directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember2RuleSetCacheControlRuleActionParametersStaleIfErrorRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember2RuleSetCacheControlRuleActionParametersStaleIfError: TypeAlias = Union[ + UnionMember2RuleSetCacheControlRuleActionParametersStaleIfErrorSetDirective, + UnionMember2RuleSetCacheControlRuleActionParametersStaleIfErrorRemoveDirective, +] + + +class UnionMember2RuleSetCacheControlRuleActionParametersStaleWhileRevalidateSetDirective(BaseModel): + """Set the directive with a duration value in seconds.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + value: int + """The duration value in seconds for the directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember2RuleSetCacheControlRuleActionParametersStaleWhileRevalidateRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember2RuleSetCacheControlRuleActionParametersStaleWhileRevalidate: TypeAlias = Union[ + UnionMember2RuleSetCacheControlRuleActionParametersStaleWhileRevalidateSetDirective, + UnionMember2RuleSetCacheControlRuleActionParametersStaleWhileRevalidateRemoveDirective, +] + + +class UnionMember2RuleSetCacheControlRuleActionParameters(BaseModel): + """The parameters configuring the rule's action.""" + + immutable: Optional[UnionMember2RuleSetCacheControlRuleActionParametersImmutable] = None + """A cache-control directive configuration.""" + + max_age: Optional[UnionMember2RuleSetCacheControlRuleActionParametersMaxAge] = FieldInfo( + alias="max-age", default=None + ) + """ + A cache-control directive configuration that accepts a duration value in + seconds. + """ + + must_revalidate: Optional[UnionMember2RuleSetCacheControlRuleActionParametersMustRevalidate] = FieldInfo( + alias="must-revalidate", default=None + ) + """A cache-control directive configuration.""" + + must_understand: Optional[UnionMember2RuleSetCacheControlRuleActionParametersMustUnderstand] = FieldInfo( + alias="must-understand", default=None + ) + """A cache-control directive configuration.""" + + no_cache: Optional[UnionMember2RuleSetCacheControlRuleActionParametersNoCache] = FieldInfo( + alias="no-cache", default=None + ) + """ + A cache-control directive configuration that accepts optional qualifiers (header + names). + """ + + no_store: Optional[UnionMember2RuleSetCacheControlRuleActionParametersNoStore] = FieldInfo( + alias="no-store", default=None + ) + """A cache-control directive configuration.""" + + no_transform: Optional[UnionMember2RuleSetCacheControlRuleActionParametersNoTransform] = FieldInfo( + alias="no-transform", default=None + ) + """A cache-control directive configuration.""" + + private: Optional[UnionMember2RuleSetCacheControlRuleActionParametersPrivate] = None + """ + A cache-control directive configuration that accepts optional qualifiers (header + names). + """ + + proxy_revalidate: Optional[UnionMember2RuleSetCacheControlRuleActionParametersProxyRevalidate] = FieldInfo( + alias="proxy-revalidate", default=None + ) + """A cache-control directive configuration.""" + + public: Optional[UnionMember2RuleSetCacheControlRuleActionParametersPublic] = None + """A cache-control directive configuration.""" + + s_maxage: Optional[UnionMember2RuleSetCacheControlRuleActionParametersSMaxage] = FieldInfo( + alias="s-maxage", default=None + ) + """ + A cache-control directive configuration that accepts a duration value in + seconds. + """ + + stale_if_error: Optional[UnionMember2RuleSetCacheControlRuleActionParametersStaleIfError] = FieldInfo( + alias="stale-if-error", default=None + ) + """ + A cache-control directive configuration that accepts a duration value in + seconds. + """ + + stale_while_revalidate: Optional[UnionMember2RuleSetCacheControlRuleActionParametersStaleWhileRevalidate] = ( + FieldInfo(alias="stale-while-revalidate", default=None) + ) + """ + A cache-control directive configuration that accepts a duration value in + seconds. + """ + + +class UnionMember2RuleSetCacheControlRuleExposedCredentialCheck(BaseModel): + """Configuration for exposed credential checking.""" + + password_expression: str + """An expression that selects the password used in the credentials check.""" + + username_expression: str + """An expression that selects the user ID used in the credentials check.""" + + +class UnionMember2RuleSetCacheControlRuleRatelimit(BaseModel): + """An object configuring the rule's rate limit behavior.""" + + characteristics: List[str] + """ + Characteristics of the request on which the rate limit counter will be + incremented. + """ + + period: int + """Period in seconds over which the counter is being incremented.""" + + counting_expression: Optional[str] = None + """An expression that defines when the rate limit counter should be incremented. + + It defaults to the same as the rule's expression. + """ + + mitigation_timeout: Optional[int] = None + """ + Period of time in seconds after which the action will be disabled following its + first execution. + """ + + requests_per_period: Optional[int] = None + """ + The threshold of requests per period after which the action will be executed for + the first time. + """ + + requests_to_origin: Optional[bool] = None + """Whether counting is only performed when an origin is reached.""" + + score_per_period: Optional[int] = None + """ + The score threshold per period for which the action will be executed the first + time. + """ + + score_response_header_name: Optional[str] = None + """ + A response header name provided by the origin, which contains the score to + increment rate limit counter with. + """ + + +class UnionMember2RuleSetCacheControlRule(BaseModel): + id: str + """The unique ID of the rule.""" + + action: Literal["set_cache_control"] + """The action to perform when the rule matches.""" + + enabled: bool + + expression: str + """The expression defining which traffic will match the rule.""" + + last_updated: datetime + """The timestamp of when the rule was last modified.""" + + ref: str + """The reference of the rule (the rule's ID by default).""" + + version: str + """The version of the rule.""" + + action_parameters: Optional[UnionMember2RuleSetCacheControlRuleActionParameters] = None + """The parameters configuring the rule's action.""" + + categories: Optional[List[str]] = None + """The categories of the rule.""" + + description: Optional[str] = None + """An informative description of the rule.""" + + exposed_credential_check: Optional[UnionMember2RuleSetCacheControlRuleExposedCredentialCheck] = None + """Configuration for exposed credential checking.""" + + logging: Optional[Logging] = None + """An object configuring the rule's logging behavior.""" + + ratelimit: Optional[UnionMember2RuleSetCacheControlRuleRatelimit] = None + """An object configuring the rule's rate limit behavior.""" + + +class UnionMember2RuleSetCacheSettingsRule(SetCacheSettingsRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember2RuleSetCacheTagsRuleActionParametersAddCacheTagsValues(BaseModel): + """Add cache tags using a list of values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + values: List[str] + """A list of cache tag values.""" + + +class UnionMember2RuleSetCacheTagsRuleActionParametersAddCacheTagsExpression(BaseModel): + """Add cache tags using an expression.""" + + expression: str + """An expression that evaluates to an array of cache tag values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + +class UnionMember2RuleSetCacheTagsRuleActionParametersRemoveCacheTagsValues(BaseModel): + """Remove cache tags using a list of values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + values: List[str] + """A list of cache tag values.""" + + +class UnionMember2RuleSetCacheTagsRuleActionParametersRemoveCacheTagsExpression(BaseModel): + """Remove cache tags using an expression.""" + + expression: str + """An expression that evaluates to an array of cache tag values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + +class UnionMember2RuleSetCacheTagsRuleActionParametersSetCacheTagsValues(BaseModel): + """Set cache tags using a list of values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + values: List[str] + """A list of cache tag values.""" + + +class UnionMember2RuleSetCacheTagsRuleActionParametersSetCacheTagsExpression(BaseModel): + """Set cache tags using an expression.""" + + expression: str + """An expression that evaluates to an array of cache tag values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + +UnionMember2RuleSetCacheTagsRuleActionParameters: TypeAlias = Union[ + UnionMember2RuleSetCacheTagsRuleActionParametersAddCacheTagsValues, + UnionMember2RuleSetCacheTagsRuleActionParametersAddCacheTagsExpression, + UnionMember2RuleSetCacheTagsRuleActionParametersRemoveCacheTagsValues, + UnionMember2RuleSetCacheTagsRuleActionParametersRemoveCacheTagsExpression, + UnionMember2RuleSetCacheTagsRuleActionParametersSetCacheTagsValues, + UnionMember2RuleSetCacheTagsRuleActionParametersSetCacheTagsExpression, +] + + +class UnionMember2RuleSetCacheTagsRuleExposedCredentialCheck(BaseModel): + """Configuration for exposed credential checking.""" + + password_expression: str + """An expression that selects the password used in the credentials check.""" + + username_expression: str + """An expression that selects the user ID used in the credentials check.""" + + +class UnionMember2RuleSetCacheTagsRuleRatelimit(BaseModel): + """An object configuring the rule's rate limit behavior.""" + + characteristics: List[str] + """ + Characteristics of the request on which the rate limit counter will be + incremented. + """ + + period: int + """Period in seconds over which the counter is being incremented.""" + + counting_expression: Optional[str] = None + """An expression that defines when the rate limit counter should be incremented. + + It defaults to the same as the rule's expression. + """ + + mitigation_timeout: Optional[int] = None + """ + Period of time in seconds after which the action will be disabled following its + first execution. + """ + + requests_per_period: Optional[int] = None + """ + The threshold of requests per period after which the action will be executed for + the first time. + """ + + requests_to_origin: Optional[bool] = None + """Whether counting is only performed when an origin is reached.""" + + score_per_period: Optional[int] = None + """ + The score threshold per period for which the action will be executed the first + time. + """ + + score_response_header_name: Optional[str] = None + """ + A response header name provided by the origin, which contains the score to + increment rate limit counter with. + """ + + +class UnionMember2RuleSetCacheTagsRule(BaseModel): + id: str + """The unique ID of the rule.""" + + action: Literal["set_cache_tags"] + """The action to perform when the rule matches.""" + + enabled: bool + + expression: str + """The expression defining which traffic will match the rule.""" + + last_updated: datetime + """The timestamp of when the rule was last modified.""" + + ref: str + """The reference of the rule (the rule's ID by default).""" + + version: str + """The version of the rule.""" + + action_parameters: Optional[UnionMember2RuleSetCacheTagsRuleActionParameters] = None + """The parameters configuring the rule's action.""" + + categories: Optional[List[str]] = None + """The categories of the rule.""" + + description: Optional[str] = None + """An informative description of the rule.""" + + exposed_credential_check: Optional[UnionMember2RuleSetCacheTagsRuleExposedCredentialCheck] = None + """Configuration for exposed credential checking.""" + + logging: Optional[Logging] = None + """An object configuring the rule's logging behavior.""" + + ratelimit: Optional[UnionMember2RuleSetCacheTagsRuleRatelimit] = None + """An object configuring the rule's rate limit behavior.""" + + +class UnionMember2RuleSetConfigurationRule(SetConfigRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember2RuleSkipRule(SkipRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember2RuleTransformResponseHTMLRuleActionParameters(BaseModel): + """The parameters configuring the rule's action.""" + + link_maze: object + """Enables the link maze transformation on the response.""" + + +class UnionMember2RuleTransformResponseHTMLRuleExposedCredentialCheck(BaseModel): + """Configuration for exposed credential checking.""" + + password_expression: str + """An expression that selects the password used in the credentials check.""" + + username_expression: str + """An expression that selects the user ID used in the credentials check.""" + + +class UnionMember2RuleTransformResponseHTMLRuleRatelimit(BaseModel): + """An object configuring the rule's rate limit behavior.""" + + characteristics: List[str] + """ + Characteristics of the request on which the rate limit counter will be + incremented. + """ + + period: int + """Period in seconds over which the counter is being incremented.""" + + counting_expression: Optional[str] = None + """An expression that defines when the rate limit counter should be incremented. + + It defaults to the same as the rule's expression. + """ + + mitigation_timeout: Optional[int] = None + """ + Period of time in seconds after which the action will be disabled following its + first execution. + """ + + requests_per_period: Optional[int] = None + """ + The threshold of requests per period after which the action will be executed for + the first time. + """ + + requests_to_origin: Optional[bool] = None + """Whether counting is only performed when an origin is reached.""" + + score_per_period: Optional[int] = None + """ + The score threshold per period for which the action will be executed the first + time. + """ + + score_response_header_name: Optional[str] = None + """ + A response header name provided by the origin, which contains the score to + increment rate limit counter with. + """ + + +class UnionMember2RuleTransformResponseHTMLRule(BaseModel): + id: str + """The unique ID of the rule.""" + + action: Literal["transform_response_html"] + """The action to perform when the rule matches.""" + + enabled: bool + + expression: str + """The expression defining which traffic will match the rule.""" + + last_updated: datetime + """The timestamp of when the rule was last modified.""" + + ref: str + """The reference of the rule (the rule's ID by default).""" + + version: str + """The version of the rule.""" + + action_parameters: Optional[UnionMember2RuleTransformResponseHTMLRuleActionParameters] = None + """The parameters configuring the rule's action.""" + + categories: Optional[List[str]] = None + """The categories of the rule.""" + + description: Optional[str] = None + """An informative description of the rule.""" + + exposed_credential_check: Optional[UnionMember2RuleTransformResponseHTMLRuleExposedCredentialCheck] = None + """Configuration for exposed credential checking.""" + + logging: Optional[Logging] = None + """An object configuring the rule's logging behavior.""" + + ratelimit: Optional[UnionMember2RuleTransformResponseHTMLRuleRatelimit] = None + """An object configuring the rule's rate limit behavior.""" + + +UnionMember2Rule: TypeAlias = Union[ + UnionMember2RuleBlockRule, + UnionMember2RuleChallengeRule, + UnionMember2RuleResponseCompressionRule, + UnionMember2RuleDDoSDynamicRule, + UnionMember2RuleExecuteRule, + UnionMember2RuleForceConnectionCloseRule, + UnionMember2RuleJavaScriptChallengeRule, + UnionMember2RuleLogRule, + UnionMember2RuleLogCustomFieldRule, + UnionMember2RuleManagedChallengeRule, + UnionMember2RuleRedirectRule, + UnionMember2RuleRewriteRule, + UnionMember2RuleRouteRule, + UnionMember2RuleScoreRule, + UnionMember2RuleServeErrorRule, + UnionMember2RuleSetCacheControlRule, + UnionMember2RuleSetCacheSettingsRule, + UnionMember2RuleSetCacheTagsRule, + UnionMember2RuleSetConfigurationRule, + UnionMember2RuleSkipRule, + UnionMember2RuleTransformResponseHTMLRule, +] + + +class UnionMember2(BaseModel): + id: Optional[str] = None + """The unique ID of the ruleset.""" + + description: Optional[str] = None + """An informative description of the ruleset.""" + + kind: Optional[Kind] = None + """The kind of the ruleset.""" + + last_updated: Optional[datetime] = None + """The timestamp of when the ruleset was last modified.""" + + name: Optional[str] = None + """The human-readable name of the ruleset.""" + + phase: Optional[Phase] = None + """The phase of the ruleset.""" + + rules: Optional[List[UnionMember2Rule]] = None + """The list of rules in the ruleset.""" + + version: Optional[str] = None + """The version of the ruleset.""" + + +class UnionMember3RuleBlockRule(BlockRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember3RuleChallengeRuleExposedCredentialCheck(BaseModel): + """Configuration for exposed credential checking.""" + + password_expression: str + """An expression that selects the password used in the credentials check.""" + + username_expression: str + """An expression that selects the user ID used in the credentials check.""" + + +class UnionMember3RuleChallengeRuleRatelimit(BaseModel): + """An object configuring the rule's rate limit behavior.""" + + characteristics: List[str] + """ + Characteristics of the request on which the rate limit counter will be + incremented. + """ + + period: int + """Period in seconds over which the counter is being incremented.""" + + counting_expression: Optional[str] = None + """An expression that defines when the rate limit counter should be incremented. + + It defaults to the same as the rule's expression. + """ + + mitigation_timeout: Optional[int] = None + """ + Period of time in seconds after which the action will be disabled following its + first execution. + """ + + requests_per_period: Optional[int] = None + """ + The threshold of requests per period after which the action will be executed for + the first time. + """ + + requests_to_origin: Optional[bool] = None + """Whether counting is only performed when an origin is reached.""" + + score_per_period: Optional[int] = None + """ + The score threshold per period for which the action will be executed the first + time. + """ + + score_response_header_name: Optional[str] = None + """ + A response header name provided by the origin, which contains the score to + increment rate limit counter with. + """ + + +class UnionMember3RuleChallengeRule(BaseModel): + id: str + """The unique ID of the rule.""" + + action: Literal["challenge"] + """The action to perform when the rule matches.""" + + enabled: bool + """Whether the rule should be executed.""" + + expression: str + """The expression defining which traffic will match the rule.""" + + last_updated: datetime + """The timestamp of when the rule was last modified.""" + + ref: str + """The reference of the rule (the rule's ID by default).""" + + version: str + """The version of the rule.""" + + action_parameters: Optional[object] = None + """The parameters configuring the rule's action.""" + + categories: Optional[List[str]] = None + """The categories of the rule.""" + + description: Optional[str] = None + """An informative description of the rule.""" + + exposed_credential_check: Optional[UnionMember3RuleChallengeRuleExposedCredentialCheck] = None + """Configuration for exposed credential checking.""" + + logging: Optional[Logging] = None + """An object configuring the rule's logging behavior.""" + + ratelimit: Optional[UnionMember3RuleChallengeRuleRatelimit] = None + """An object configuring the rule's rate limit behavior.""" + + +class UnionMember3RuleResponseCompressionRule(CompressResponseRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember3RuleDDoSDynamicRule(DDoSDynamicRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember3RuleExecuteRule(ExecuteRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember3RuleForceConnectionCloseRule(ForceConnectionCloseRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember3RuleJavaScriptChallengeRuleExposedCredentialCheck(BaseModel): + """Configuration for exposed credential checking.""" + + password_expression: str + """An expression that selects the password used in the credentials check.""" + + username_expression: str + """An expression that selects the user ID used in the credentials check.""" + + +class UnionMember3RuleJavaScriptChallengeRuleRatelimit(BaseModel): + """An object configuring the rule's rate limit behavior.""" + + characteristics: List[str] + """ + Characteristics of the request on which the rate limit counter will be + incremented. + """ + + period: int + """Period in seconds over which the counter is being incremented.""" + + counting_expression: Optional[str] = None + """An expression that defines when the rate limit counter should be incremented. + + It defaults to the same as the rule's expression. + """ + + mitigation_timeout: Optional[int] = None + """ + Period of time in seconds after which the action will be disabled following its + first execution. + """ + + requests_per_period: Optional[int] = None + """ + The threshold of requests per period after which the action will be executed for + the first time. + """ + + requests_to_origin: Optional[bool] = None + """Whether counting is only performed when an origin is reached.""" + + score_per_period: Optional[int] = None + """ + The score threshold per period for which the action will be executed the first + time. + """ + + score_response_header_name: Optional[str] = None + """ + A response header name provided by the origin, which contains the score to + increment rate limit counter with. + """ + + +class UnionMember3RuleJavaScriptChallengeRule(BaseModel): + id: str + """The unique ID of the rule.""" + + action: Literal["js_challenge"] + """The action to perform when the rule matches.""" + + enabled: bool + """Whether the rule should be executed.""" + + expression: str + """The expression defining which traffic will match the rule.""" + + last_updated: datetime + """The timestamp of when the rule was last modified.""" + + ref: str + """The reference of the rule (the rule's ID by default).""" + + version: str + """The version of the rule.""" + + action_parameters: Optional[object] = None + """The parameters configuring the rule's action.""" + + categories: Optional[List[str]] = None + """The categories of the rule.""" + + description: Optional[str] = None + """An informative description of the rule.""" + + exposed_credential_check: Optional[UnionMember3RuleJavaScriptChallengeRuleExposedCredentialCheck] = None + """Configuration for exposed credential checking.""" + + logging: Optional[Logging] = None + """An object configuring the rule's logging behavior.""" + + ratelimit: Optional[UnionMember3RuleJavaScriptChallengeRuleRatelimit] = None + """An object configuring the rule's rate limit behavior.""" + + +class UnionMember3RuleLogRule(LogRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember3RuleLogCustomFieldRule(LogCustomFieldRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember3RuleManagedChallengeRule(ManagedChallengeRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember3RuleRedirectRule(RedirectRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember3RuleRewriteRule(RewriteRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember3RuleRouteRule(RouteRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember3RuleScoreRule(ScoreRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember3RuleServeErrorRule(ServeErrorRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember3RuleSetCacheControlRuleActionParametersImmutableSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember3RuleSetCacheControlRuleActionParametersImmutableRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember3RuleSetCacheControlRuleActionParametersImmutable: TypeAlias = Union[ + UnionMember3RuleSetCacheControlRuleActionParametersImmutableSetDirective, + UnionMember3RuleSetCacheControlRuleActionParametersImmutableRemoveDirective, +] + + +class UnionMember3RuleSetCacheControlRuleActionParametersMaxAgeSetDirective(BaseModel): + """Set the directive with a duration value in seconds.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + value: int + """The duration value in seconds for the directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember3RuleSetCacheControlRuleActionParametersMaxAgeRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember3RuleSetCacheControlRuleActionParametersMaxAge: TypeAlias = Union[ + UnionMember3RuleSetCacheControlRuleActionParametersMaxAgeSetDirective, + UnionMember3RuleSetCacheControlRuleActionParametersMaxAgeRemoveDirective, +] + + +class UnionMember3RuleSetCacheControlRuleActionParametersMustRevalidateSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember3RuleSetCacheControlRuleActionParametersMustRevalidateRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember3RuleSetCacheControlRuleActionParametersMustRevalidate: TypeAlias = Union[ + UnionMember3RuleSetCacheControlRuleActionParametersMustRevalidateSetDirective, + UnionMember3RuleSetCacheControlRuleActionParametersMustRevalidateRemoveDirective, +] + + +class UnionMember3RuleSetCacheControlRuleActionParametersMustUnderstandSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember3RuleSetCacheControlRuleActionParametersMustUnderstandRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember3RuleSetCacheControlRuleActionParametersMustUnderstand: TypeAlias = Union[ + UnionMember3RuleSetCacheControlRuleActionParametersMustUnderstandSetDirective, + UnionMember3RuleSetCacheControlRuleActionParametersMustUnderstandRemoveDirective, +] + + +class UnionMember3RuleSetCacheControlRuleActionParametersNoCacheSetDirective(BaseModel): + """Set the directive with optional qualifiers.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + qualifiers: Optional[List[str]] = None + """ + Optional list of header names to qualify the directive (e.g., for "private" or + "no-cache" directives). + """ + + +class UnionMember3RuleSetCacheControlRuleActionParametersNoCacheRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember3RuleSetCacheControlRuleActionParametersNoCache: TypeAlias = Union[ + UnionMember3RuleSetCacheControlRuleActionParametersNoCacheSetDirective, + UnionMember3RuleSetCacheControlRuleActionParametersNoCacheRemoveDirective, +] + + +class UnionMember3RuleSetCacheControlRuleActionParametersNoStoreSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember3RuleSetCacheControlRuleActionParametersNoStoreRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember3RuleSetCacheControlRuleActionParametersNoStore: TypeAlias = Union[ + UnionMember3RuleSetCacheControlRuleActionParametersNoStoreSetDirective, + UnionMember3RuleSetCacheControlRuleActionParametersNoStoreRemoveDirective, +] + + +class UnionMember3RuleSetCacheControlRuleActionParametersNoTransformSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember3RuleSetCacheControlRuleActionParametersNoTransformRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember3RuleSetCacheControlRuleActionParametersNoTransform: TypeAlias = Union[ + UnionMember3RuleSetCacheControlRuleActionParametersNoTransformSetDirective, + UnionMember3RuleSetCacheControlRuleActionParametersNoTransformRemoveDirective, +] + + +class UnionMember3RuleSetCacheControlRuleActionParametersPrivateSetDirective(BaseModel): + """Set the directive with optional qualifiers.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + qualifiers: Optional[List[str]] = None + """ + Optional list of header names to qualify the directive (e.g., for "private" or + "no-cache" directives). + """ + + +class UnionMember3RuleSetCacheControlRuleActionParametersPrivateRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember3RuleSetCacheControlRuleActionParametersPrivate: TypeAlias = Union[ + UnionMember3RuleSetCacheControlRuleActionParametersPrivateSetDirective, + UnionMember3RuleSetCacheControlRuleActionParametersPrivateRemoveDirective, +] + + +class UnionMember3RuleSetCacheControlRuleActionParametersProxyRevalidateSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember3RuleSetCacheControlRuleActionParametersProxyRevalidateRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember3RuleSetCacheControlRuleActionParametersProxyRevalidate: TypeAlias = Union[ + UnionMember3RuleSetCacheControlRuleActionParametersProxyRevalidateSetDirective, + UnionMember3RuleSetCacheControlRuleActionParametersProxyRevalidateRemoveDirective, +] + + +class UnionMember3RuleSetCacheControlRuleActionParametersPublicSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember3RuleSetCacheControlRuleActionParametersPublicRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember3RuleSetCacheControlRuleActionParametersPublic: TypeAlias = Union[ + UnionMember3RuleSetCacheControlRuleActionParametersPublicSetDirective, + UnionMember3RuleSetCacheControlRuleActionParametersPublicRemoveDirective, +] + + +class UnionMember3RuleSetCacheControlRuleActionParametersSMaxageSetDirective(BaseModel): + """Set the directive with a duration value in seconds.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + value: int + """The duration value in seconds for the directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember3RuleSetCacheControlRuleActionParametersSMaxageRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember3RuleSetCacheControlRuleActionParametersSMaxage: TypeAlias = Union[ + UnionMember3RuleSetCacheControlRuleActionParametersSMaxageSetDirective, + UnionMember3RuleSetCacheControlRuleActionParametersSMaxageRemoveDirective, +] + + +class UnionMember3RuleSetCacheControlRuleActionParametersStaleIfErrorSetDirective(BaseModel): + """Set the directive with a duration value in seconds.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + value: int + """The duration value in seconds for the directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember3RuleSetCacheControlRuleActionParametersStaleIfErrorRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember3RuleSetCacheControlRuleActionParametersStaleIfError: TypeAlias = Union[ + UnionMember3RuleSetCacheControlRuleActionParametersStaleIfErrorSetDirective, + UnionMember3RuleSetCacheControlRuleActionParametersStaleIfErrorRemoveDirective, +] + + +class UnionMember3RuleSetCacheControlRuleActionParametersStaleWhileRevalidateSetDirective(BaseModel): + """Set the directive with a duration value in seconds.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + value: int + """The duration value in seconds for the directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember3RuleSetCacheControlRuleActionParametersStaleWhileRevalidateRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember3RuleSetCacheControlRuleActionParametersStaleWhileRevalidate: TypeAlias = Union[ + UnionMember3RuleSetCacheControlRuleActionParametersStaleWhileRevalidateSetDirective, + UnionMember3RuleSetCacheControlRuleActionParametersStaleWhileRevalidateRemoveDirective, +] + + +class UnionMember3RuleSetCacheControlRuleActionParameters(BaseModel): + """The parameters configuring the rule's action.""" + + immutable: Optional[UnionMember3RuleSetCacheControlRuleActionParametersImmutable] = None + """A cache-control directive configuration.""" + + max_age: Optional[UnionMember3RuleSetCacheControlRuleActionParametersMaxAge] = FieldInfo( + alias="max-age", default=None + ) + """ + A cache-control directive configuration that accepts a duration value in + seconds. + """ + + must_revalidate: Optional[UnionMember3RuleSetCacheControlRuleActionParametersMustRevalidate] = FieldInfo( + alias="must-revalidate", default=None + ) + """A cache-control directive configuration.""" + + must_understand: Optional[UnionMember3RuleSetCacheControlRuleActionParametersMustUnderstand] = FieldInfo( + alias="must-understand", default=None + ) + """A cache-control directive configuration.""" + + no_cache: Optional[UnionMember3RuleSetCacheControlRuleActionParametersNoCache] = FieldInfo( + alias="no-cache", default=None + ) + """ + A cache-control directive configuration that accepts optional qualifiers (header + names). + """ + + no_store: Optional[UnionMember3RuleSetCacheControlRuleActionParametersNoStore] = FieldInfo( + alias="no-store", default=None + ) + """A cache-control directive configuration.""" + + no_transform: Optional[UnionMember3RuleSetCacheControlRuleActionParametersNoTransform] = FieldInfo( + alias="no-transform", default=None + ) + """A cache-control directive configuration.""" + + private: Optional[UnionMember3RuleSetCacheControlRuleActionParametersPrivate] = None + """ + A cache-control directive configuration that accepts optional qualifiers (header + names). + """ + + proxy_revalidate: Optional[UnionMember3RuleSetCacheControlRuleActionParametersProxyRevalidate] = FieldInfo( + alias="proxy-revalidate", default=None + ) + """A cache-control directive configuration.""" + + public: Optional[UnionMember3RuleSetCacheControlRuleActionParametersPublic] = None + """A cache-control directive configuration.""" + + s_maxage: Optional[UnionMember3RuleSetCacheControlRuleActionParametersSMaxage] = FieldInfo( + alias="s-maxage", default=None + ) + """ + A cache-control directive configuration that accepts a duration value in + seconds. + """ + + stale_if_error: Optional[UnionMember3RuleSetCacheControlRuleActionParametersStaleIfError] = FieldInfo( + alias="stale-if-error", default=None + ) + """ + A cache-control directive configuration that accepts a duration value in + seconds. + """ + + stale_while_revalidate: Optional[UnionMember3RuleSetCacheControlRuleActionParametersStaleWhileRevalidate] = ( + FieldInfo(alias="stale-while-revalidate", default=None) + ) + """ + A cache-control directive configuration that accepts a duration value in + seconds. + """ + + +class UnionMember3RuleSetCacheControlRuleExposedCredentialCheck(BaseModel): + """Configuration for exposed credential checking.""" + + password_expression: str + """An expression that selects the password used in the credentials check.""" + + username_expression: str + """An expression that selects the user ID used in the credentials check.""" + + +class UnionMember3RuleSetCacheControlRuleRatelimit(BaseModel): + """An object configuring the rule's rate limit behavior.""" + + characteristics: List[str] + """ + Characteristics of the request on which the rate limit counter will be + incremented. + """ + + period: int + """Period in seconds over which the counter is being incremented.""" + + counting_expression: Optional[str] = None + """An expression that defines when the rate limit counter should be incremented. + + It defaults to the same as the rule's expression. + """ + + mitigation_timeout: Optional[int] = None + """ + Period of time in seconds after which the action will be disabled following its + first execution. + """ + + requests_per_period: Optional[int] = None + """ + The threshold of requests per period after which the action will be executed for + the first time. + """ + + requests_to_origin: Optional[bool] = None + """Whether counting is only performed when an origin is reached.""" + + score_per_period: Optional[int] = None + """ + The score threshold per period for which the action will be executed the first + time. + """ + + score_response_header_name: Optional[str] = None + """ + A response header name provided by the origin, which contains the score to + increment rate limit counter with. + """ + + +class UnionMember3RuleSetCacheControlRule(BaseModel): + id: str + """The unique ID of the rule.""" + + action: Literal["set_cache_control"] + """The action to perform when the rule matches.""" + + enabled: bool + + expression: str + """The expression defining which traffic will match the rule.""" + + last_updated: datetime + """The timestamp of when the rule was last modified.""" + + ref: str + """The reference of the rule (the rule's ID by default).""" + + version: str + """The version of the rule.""" + + action_parameters: Optional[UnionMember3RuleSetCacheControlRuleActionParameters] = None + """The parameters configuring the rule's action.""" + + categories: Optional[List[str]] = None + """The categories of the rule.""" + + description: Optional[str] = None + """An informative description of the rule.""" + + exposed_credential_check: Optional[UnionMember3RuleSetCacheControlRuleExposedCredentialCheck] = None + """Configuration for exposed credential checking.""" + + logging: Optional[Logging] = None + """An object configuring the rule's logging behavior.""" + + ratelimit: Optional[UnionMember3RuleSetCacheControlRuleRatelimit] = None + """An object configuring the rule's rate limit behavior.""" + + +class UnionMember3RuleSetCacheSettingsRule(SetCacheSettingsRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember3RuleSetCacheTagsRuleActionParametersAddCacheTagsValues(BaseModel): + """Add cache tags using a list of values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + values: List[str] + """A list of cache tag values.""" + + +class UnionMember3RuleSetCacheTagsRuleActionParametersAddCacheTagsExpression(BaseModel): + """Add cache tags using an expression.""" + + expression: str + """An expression that evaluates to an array of cache tag values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + +class UnionMember3RuleSetCacheTagsRuleActionParametersRemoveCacheTagsValues(BaseModel): + """Remove cache tags using a list of values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + values: List[str] + """A list of cache tag values.""" + + +class UnionMember3RuleSetCacheTagsRuleActionParametersRemoveCacheTagsExpression(BaseModel): + """Remove cache tags using an expression.""" + + expression: str + """An expression that evaluates to an array of cache tag values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + +class UnionMember3RuleSetCacheTagsRuleActionParametersSetCacheTagsValues(BaseModel): + """Set cache tags using a list of values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + values: List[str] + """A list of cache tag values.""" + + +class UnionMember3RuleSetCacheTagsRuleActionParametersSetCacheTagsExpression(BaseModel): + """Set cache tags using an expression.""" + + expression: str + """An expression that evaluates to an array of cache tag values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + +UnionMember3RuleSetCacheTagsRuleActionParameters: TypeAlias = Union[ + UnionMember3RuleSetCacheTagsRuleActionParametersAddCacheTagsValues, + UnionMember3RuleSetCacheTagsRuleActionParametersAddCacheTagsExpression, + UnionMember3RuleSetCacheTagsRuleActionParametersRemoveCacheTagsValues, + UnionMember3RuleSetCacheTagsRuleActionParametersRemoveCacheTagsExpression, + UnionMember3RuleSetCacheTagsRuleActionParametersSetCacheTagsValues, + UnionMember3RuleSetCacheTagsRuleActionParametersSetCacheTagsExpression, +] + + +class UnionMember3RuleSetCacheTagsRuleExposedCredentialCheck(BaseModel): + """Configuration for exposed credential checking.""" + + password_expression: str + """An expression that selects the password used in the credentials check.""" + + username_expression: str + """An expression that selects the user ID used in the credentials check.""" + + +class UnionMember3RuleSetCacheTagsRuleRatelimit(BaseModel): + """An object configuring the rule's rate limit behavior.""" + + characteristics: List[str] + """ + Characteristics of the request on which the rate limit counter will be + incremented. + """ + + period: int + """Period in seconds over which the counter is being incremented.""" + + counting_expression: Optional[str] = None + """An expression that defines when the rate limit counter should be incremented. + + It defaults to the same as the rule's expression. + """ + + mitigation_timeout: Optional[int] = None + """ + Period of time in seconds after which the action will be disabled following its + first execution. + """ + + requests_per_period: Optional[int] = None + """ + The threshold of requests per period after which the action will be executed for + the first time. + """ + + requests_to_origin: Optional[bool] = None + """Whether counting is only performed when an origin is reached.""" + + score_per_period: Optional[int] = None + """ + The score threshold per period for which the action will be executed the first + time. + """ + + score_response_header_name: Optional[str] = None + """ + A response header name provided by the origin, which contains the score to + increment rate limit counter with. + """ + + +class UnionMember3RuleSetCacheTagsRule(BaseModel): + id: str + """The unique ID of the rule.""" + + action: Literal["set_cache_tags"] + """The action to perform when the rule matches.""" + + enabled: bool + + expression: str + """The expression defining which traffic will match the rule.""" + + last_updated: datetime + """The timestamp of when the rule was last modified.""" + + ref: str + """The reference of the rule (the rule's ID by default).""" + + version: str + """The version of the rule.""" + + action_parameters: Optional[UnionMember3RuleSetCacheTagsRuleActionParameters] = None + """The parameters configuring the rule's action.""" + + categories: Optional[List[str]] = None + """The categories of the rule.""" + + description: Optional[str] = None + """An informative description of the rule.""" + + exposed_credential_check: Optional[UnionMember3RuleSetCacheTagsRuleExposedCredentialCheck] = None + """Configuration for exposed credential checking.""" + + logging: Optional[Logging] = None + """An object configuring the rule's logging behavior.""" + + ratelimit: Optional[UnionMember3RuleSetCacheTagsRuleRatelimit] = None + """An object configuring the rule's rate limit behavior.""" + + +class UnionMember3RuleSetConfigurationRule(SetConfigRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember3RuleSkipRule(SkipRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember3RuleTransformResponseHTMLRuleActionParameters(BaseModel): + """The parameters configuring the rule's action.""" + + link_maze: object + """Enables the link maze transformation on the response.""" + + +class UnionMember3RuleTransformResponseHTMLRuleExposedCredentialCheck(BaseModel): + """Configuration for exposed credential checking.""" + + password_expression: str + """An expression that selects the password used in the credentials check.""" + + username_expression: str + """An expression that selects the user ID used in the credentials check.""" + + +class UnionMember3RuleTransformResponseHTMLRuleRatelimit(BaseModel): + """An object configuring the rule's rate limit behavior.""" + + characteristics: List[str] + """ + Characteristics of the request on which the rate limit counter will be + incremented. + """ + + period: int + """Period in seconds over which the counter is being incremented.""" + + counting_expression: Optional[str] = None + """An expression that defines when the rate limit counter should be incremented. + + It defaults to the same as the rule's expression. + """ + + mitigation_timeout: Optional[int] = None + """ + Period of time in seconds after which the action will be disabled following its + first execution. + """ + + requests_per_period: Optional[int] = None + """ + The threshold of requests per period after which the action will be executed for + the first time. + """ + + requests_to_origin: Optional[bool] = None + """Whether counting is only performed when an origin is reached.""" + + score_per_period: Optional[int] = None + """ + The score threshold per period for which the action will be executed the first + time. + """ + + score_response_header_name: Optional[str] = None + """ + A response header name provided by the origin, which contains the score to + increment rate limit counter with. + """ + + +class UnionMember3RuleTransformResponseHTMLRule(BaseModel): + id: str + """The unique ID of the rule.""" + + action: Literal["transform_response_html"] + """The action to perform when the rule matches.""" + + enabled: bool + + expression: str + """The expression defining which traffic will match the rule.""" + + last_updated: datetime + """The timestamp of when the rule was last modified.""" + + ref: str + """The reference of the rule (the rule's ID by default).""" + + version: str + """The version of the rule.""" + + action_parameters: Optional[UnionMember3RuleTransformResponseHTMLRuleActionParameters] = None + """The parameters configuring the rule's action.""" + + categories: Optional[List[str]] = None + """The categories of the rule.""" + + description: Optional[str] = None + """An informative description of the rule.""" + + exposed_credential_check: Optional[UnionMember3RuleTransformResponseHTMLRuleExposedCredentialCheck] = None + """Configuration for exposed credential checking.""" + + logging: Optional[Logging] = None + """An object configuring the rule's logging behavior.""" + + ratelimit: Optional[UnionMember3RuleTransformResponseHTMLRuleRatelimit] = None + """An object configuring the rule's rate limit behavior.""" + + +UnionMember3Rule: TypeAlias = Union[ + UnionMember3RuleBlockRule, + UnionMember3RuleChallengeRule, + UnionMember3RuleResponseCompressionRule, + UnionMember3RuleDDoSDynamicRule, + UnionMember3RuleExecuteRule, + UnionMember3RuleForceConnectionCloseRule, + UnionMember3RuleJavaScriptChallengeRule, + UnionMember3RuleLogRule, + UnionMember3RuleLogCustomFieldRule, + UnionMember3RuleManagedChallengeRule, + UnionMember3RuleRedirectRule, + UnionMember3RuleRewriteRule, + UnionMember3RuleRouteRule, + UnionMember3RuleScoreRule, + UnionMember3RuleServeErrorRule, + UnionMember3RuleSetCacheControlRule, + UnionMember3RuleSetCacheSettingsRule, + UnionMember3RuleSetCacheTagsRule, + UnionMember3RuleSetConfigurationRule, + UnionMember3RuleSkipRule, + UnionMember3RuleTransformResponseHTMLRule, +] + + +class UnionMember3(BaseModel): + id: Optional[str] = None + """The unique ID of the ruleset.""" + + description: Optional[str] = None + """An informative description of the ruleset.""" + + kind: Optional[Kind] = None + """The kind of the ruleset.""" + + last_updated: Optional[datetime] = None + """The timestamp of when the ruleset was last modified.""" + + name: Optional[str] = None + """The human-readable name of the ruleset.""" + + phase: Optional[Phase] = None + """The phase of the ruleset.""" + + rules: Optional[List[UnionMember3Rule]] = None + """The list of rules in the ruleset.""" + + version: Optional[str] = None + """The version of the ruleset.""" + + +class UnionMember4RuleBlockRule(BlockRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember4RuleChallengeRuleExposedCredentialCheck(BaseModel): + """Configuration for exposed credential checking.""" + + password_expression: str + """An expression that selects the password used in the credentials check.""" + + username_expression: str + """An expression that selects the user ID used in the credentials check.""" + + +class UnionMember4RuleChallengeRuleRatelimit(BaseModel): + """An object configuring the rule's rate limit behavior.""" + + characteristics: List[str] + """ + Characteristics of the request on which the rate limit counter will be + incremented. + """ + + period: int + """Period in seconds over which the counter is being incremented.""" + + counting_expression: Optional[str] = None + """An expression that defines when the rate limit counter should be incremented. + + It defaults to the same as the rule's expression. + """ + + mitigation_timeout: Optional[int] = None + """ + Period of time in seconds after which the action will be disabled following its + first execution. + """ + + requests_per_period: Optional[int] = None + """ + The threshold of requests per period after which the action will be executed for + the first time. + """ + + requests_to_origin: Optional[bool] = None + """Whether counting is only performed when an origin is reached.""" + + score_per_period: Optional[int] = None + """ + The score threshold per period for which the action will be executed the first + time. + """ + + score_response_header_name: Optional[str] = None + """ + A response header name provided by the origin, which contains the score to + increment rate limit counter with. + """ + + +class UnionMember4RuleChallengeRule(BaseModel): + id: str + """The unique ID of the rule.""" + + action: Literal["challenge"] + """The action to perform when the rule matches.""" + + enabled: bool + """Whether the rule should be executed.""" + + expression: str + """The expression defining which traffic will match the rule.""" + + last_updated: datetime + """The timestamp of when the rule was last modified.""" + + ref: str + """The reference of the rule (the rule's ID by default).""" + + version: str + """The version of the rule.""" + + action_parameters: Optional[object] = None + """The parameters configuring the rule's action.""" + + categories: Optional[List[str]] = None + """The categories of the rule.""" + + description: Optional[str] = None + """An informative description of the rule.""" + + exposed_credential_check: Optional[UnionMember4RuleChallengeRuleExposedCredentialCheck] = None + """Configuration for exposed credential checking.""" + + logging: Optional[Logging] = None + """An object configuring the rule's logging behavior.""" + + ratelimit: Optional[UnionMember4RuleChallengeRuleRatelimit] = None + """An object configuring the rule's rate limit behavior.""" + + +class UnionMember4RuleResponseCompressionRule(CompressResponseRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember4RuleDDoSDynamicRule(DDoSDynamicRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember4RuleExecuteRule(ExecuteRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember4RuleForceConnectionCloseRule(ForceConnectionCloseRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember4RuleJavaScriptChallengeRuleExposedCredentialCheck(BaseModel): + """Configuration for exposed credential checking.""" + + password_expression: str + """An expression that selects the password used in the credentials check.""" + + username_expression: str + """An expression that selects the user ID used in the credentials check.""" + + +class UnionMember4RuleJavaScriptChallengeRuleRatelimit(BaseModel): + """An object configuring the rule's rate limit behavior.""" + + characteristics: List[str] + """ + Characteristics of the request on which the rate limit counter will be + incremented. + """ + + period: int + """Period in seconds over which the counter is being incremented.""" + + counting_expression: Optional[str] = None + """An expression that defines when the rate limit counter should be incremented. + + It defaults to the same as the rule's expression. + """ + + mitigation_timeout: Optional[int] = None + """ + Period of time in seconds after which the action will be disabled following its + first execution. + """ + + requests_per_period: Optional[int] = None + """ + The threshold of requests per period after which the action will be executed for + the first time. + """ + + requests_to_origin: Optional[bool] = None + """Whether counting is only performed when an origin is reached.""" + + score_per_period: Optional[int] = None + """ + The score threshold per period for which the action will be executed the first + time. + """ + + score_response_header_name: Optional[str] = None + """ + A response header name provided by the origin, which contains the score to + increment rate limit counter with. + """ + + +class UnionMember4RuleJavaScriptChallengeRule(BaseModel): + id: str + """The unique ID of the rule.""" + + action: Literal["js_challenge"] + """The action to perform when the rule matches.""" + + enabled: bool + """Whether the rule should be executed.""" + + expression: str + """The expression defining which traffic will match the rule.""" + + last_updated: datetime + """The timestamp of when the rule was last modified.""" + + ref: str + """The reference of the rule (the rule's ID by default).""" + + version: str + """The version of the rule.""" + + action_parameters: Optional[object] = None + """The parameters configuring the rule's action.""" + + categories: Optional[List[str]] = None + """The categories of the rule.""" + + description: Optional[str] = None + """An informative description of the rule.""" + + exposed_credential_check: Optional[UnionMember4RuleJavaScriptChallengeRuleExposedCredentialCheck] = None + """Configuration for exposed credential checking.""" + + logging: Optional[Logging] = None + """An object configuring the rule's logging behavior.""" + + ratelimit: Optional[UnionMember4RuleJavaScriptChallengeRuleRatelimit] = None + """An object configuring the rule's rate limit behavior.""" + + +class UnionMember4RuleLogRule(LogRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember4RuleLogCustomFieldRule(LogCustomFieldRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember4RuleManagedChallengeRule(ManagedChallengeRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember4RuleRedirectRule(RedirectRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember4RuleRewriteRule(RewriteRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember4RuleRouteRule(RouteRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember4RuleScoreRule(ScoreRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember4RuleServeErrorRule(ServeErrorRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember4RuleSetCacheControlRuleActionParametersImmutableSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember4RuleSetCacheControlRuleActionParametersImmutableRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember4RuleSetCacheControlRuleActionParametersImmutable: TypeAlias = Union[ + UnionMember4RuleSetCacheControlRuleActionParametersImmutableSetDirective, + UnionMember4RuleSetCacheControlRuleActionParametersImmutableRemoveDirective, +] + + +class UnionMember4RuleSetCacheControlRuleActionParametersMaxAgeSetDirective(BaseModel): + """Set the directive with a duration value in seconds.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + value: int + """The duration value in seconds for the directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember4RuleSetCacheControlRuleActionParametersMaxAgeRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember4RuleSetCacheControlRuleActionParametersMaxAge: TypeAlias = Union[ + UnionMember4RuleSetCacheControlRuleActionParametersMaxAgeSetDirective, + UnionMember4RuleSetCacheControlRuleActionParametersMaxAgeRemoveDirective, +] + + +class UnionMember4RuleSetCacheControlRuleActionParametersMustRevalidateSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember4RuleSetCacheControlRuleActionParametersMustRevalidateRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember4RuleSetCacheControlRuleActionParametersMustRevalidate: TypeAlias = Union[ + UnionMember4RuleSetCacheControlRuleActionParametersMustRevalidateSetDirective, + UnionMember4RuleSetCacheControlRuleActionParametersMustRevalidateRemoveDirective, +] + + +class UnionMember4RuleSetCacheControlRuleActionParametersMustUnderstandSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember4RuleSetCacheControlRuleActionParametersMustUnderstandRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember4RuleSetCacheControlRuleActionParametersMustUnderstand: TypeAlias = Union[ + UnionMember4RuleSetCacheControlRuleActionParametersMustUnderstandSetDirective, + UnionMember4RuleSetCacheControlRuleActionParametersMustUnderstandRemoveDirective, +] + + +class UnionMember4RuleSetCacheControlRuleActionParametersNoCacheSetDirective(BaseModel): + """Set the directive with optional qualifiers.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + qualifiers: Optional[List[str]] = None + """ + Optional list of header names to qualify the directive (e.g., for "private" or + "no-cache" directives). + """ + + +class UnionMember4RuleSetCacheControlRuleActionParametersNoCacheRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember4RuleSetCacheControlRuleActionParametersNoCache: TypeAlias = Union[ + UnionMember4RuleSetCacheControlRuleActionParametersNoCacheSetDirective, + UnionMember4RuleSetCacheControlRuleActionParametersNoCacheRemoveDirective, +] + + +class UnionMember4RuleSetCacheControlRuleActionParametersNoStoreSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember4RuleSetCacheControlRuleActionParametersNoStoreRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember4RuleSetCacheControlRuleActionParametersNoStore: TypeAlias = Union[ + UnionMember4RuleSetCacheControlRuleActionParametersNoStoreSetDirective, + UnionMember4RuleSetCacheControlRuleActionParametersNoStoreRemoveDirective, +] + + +class UnionMember4RuleSetCacheControlRuleActionParametersNoTransformSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember4RuleSetCacheControlRuleActionParametersNoTransformRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember4RuleSetCacheControlRuleActionParametersNoTransform: TypeAlias = Union[ + UnionMember4RuleSetCacheControlRuleActionParametersNoTransformSetDirective, + UnionMember4RuleSetCacheControlRuleActionParametersNoTransformRemoveDirective, +] + + +class UnionMember4RuleSetCacheControlRuleActionParametersPrivateSetDirective(BaseModel): + """Set the directive with optional qualifiers.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + qualifiers: Optional[List[str]] = None + """ + Optional list of header names to qualify the directive (e.g., for "private" or + "no-cache" directives). + """ + + +class UnionMember4RuleSetCacheControlRuleActionParametersPrivateRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember4RuleSetCacheControlRuleActionParametersPrivate: TypeAlias = Union[ + UnionMember4RuleSetCacheControlRuleActionParametersPrivateSetDirective, + UnionMember4RuleSetCacheControlRuleActionParametersPrivateRemoveDirective, +] + + +class UnionMember4RuleSetCacheControlRuleActionParametersProxyRevalidateSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember4RuleSetCacheControlRuleActionParametersProxyRevalidateRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember4RuleSetCacheControlRuleActionParametersProxyRevalidate: TypeAlias = Union[ + UnionMember4RuleSetCacheControlRuleActionParametersProxyRevalidateSetDirective, + UnionMember4RuleSetCacheControlRuleActionParametersProxyRevalidateRemoveDirective, +] + + +class UnionMember4RuleSetCacheControlRuleActionParametersPublicSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember4RuleSetCacheControlRuleActionParametersPublicRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember4RuleSetCacheControlRuleActionParametersPublic: TypeAlias = Union[ + UnionMember4RuleSetCacheControlRuleActionParametersPublicSetDirective, + UnionMember4RuleSetCacheControlRuleActionParametersPublicRemoveDirective, +] + + +class UnionMember4RuleSetCacheControlRuleActionParametersSMaxageSetDirective(BaseModel): + """Set the directive with a duration value in seconds.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + value: int + """The duration value in seconds for the directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember4RuleSetCacheControlRuleActionParametersSMaxageRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember4RuleSetCacheControlRuleActionParametersSMaxage: TypeAlias = Union[ + UnionMember4RuleSetCacheControlRuleActionParametersSMaxageSetDirective, + UnionMember4RuleSetCacheControlRuleActionParametersSMaxageRemoveDirective, +] + + +class UnionMember4RuleSetCacheControlRuleActionParametersStaleIfErrorSetDirective(BaseModel): + """Set the directive with a duration value in seconds.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + value: int + """The duration value in seconds for the directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember4RuleSetCacheControlRuleActionParametersStaleIfErrorRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember4RuleSetCacheControlRuleActionParametersStaleIfError: TypeAlias = Union[ + UnionMember4RuleSetCacheControlRuleActionParametersStaleIfErrorSetDirective, + UnionMember4RuleSetCacheControlRuleActionParametersStaleIfErrorRemoveDirective, +] + + +class UnionMember4RuleSetCacheControlRuleActionParametersStaleWhileRevalidateSetDirective(BaseModel): + """Set the directive with a duration value in seconds.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + value: int + """The duration value in seconds for the directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember4RuleSetCacheControlRuleActionParametersStaleWhileRevalidateRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember4RuleSetCacheControlRuleActionParametersStaleWhileRevalidate: TypeAlias = Union[ + UnionMember4RuleSetCacheControlRuleActionParametersStaleWhileRevalidateSetDirective, + UnionMember4RuleSetCacheControlRuleActionParametersStaleWhileRevalidateRemoveDirective, +] + + +class UnionMember4RuleSetCacheControlRuleActionParameters(BaseModel): + """The parameters configuring the rule's action.""" + + immutable: Optional[UnionMember4RuleSetCacheControlRuleActionParametersImmutable] = None + """A cache-control directive configuration.""" + + max_age: Optional[UnionMember4RuleSetCacheControlRuleActionParametersMaxAge] = FieldInfo( + alias="max-age", default=None + ) + """ + A cache-control directive configuration that accepts a duration value in + seconds. + """ + + must_revalidate: Optional[UnionMember4RuleSetCacheControlRuleActionParametersMustRevalidate] = FieldInfo( + alias="must-revalidate", default=None + ) + """A cache-control directive configuration.""" + + must_understand: Optional[UnionMember4RuleSetCacheControlRuleActionParametersMustUnderstand] = FieldInfo( + alias="must-understand", default=None + ) + """A cache-control directive configuration.""" + + no_cache: Optional[UnionMember4RuleSetCacheControlRuleActionParametersNoCache] = FieldInfo( + alias="no-cache", default=None + ) + """ + A cache-control directive configuration that accepts optional qualifiers (header + names). + """ + + no_store: Optional[UnionMember4RuleSetCacheControlRuleActionParametersNoStore] = FieldInfo( + alias="no-store", default=None + ) + """A cache-control directive configuration.""" + + no_transform: Optional[UnionMember4RuleSetCacheControlRuleActionParametersNoTransform] = FieldInfo( + alias="no-transform", default=None + ) + """A cache-control directive configuration.""" + + private: Optional[UnionMember4RuleSetCacheControlRuleActionParametersPrivate] = None + """ + A cache-control directive configuration that accepts optional qualifiers (header + names). + """ + + proxy_revalidate: Optional[UnionMember4RuleSetCacheControlRuleActionParametersProxyRevalidate] = FieldInfo( + alias="proxy-revalidate", default=None + ) + """A cache-control directive configuration.""" + + public: Optional[UnionMember4RuleSetCacheControlRuleActionParametersPublic] = None + """A cache-control directive configuration.""" + + s_maxage: Optional[UnionMember4RuleSetCacheControlRuleActionParametersSMaxage] = FieldInfo( + alias="s-maxage", default=None + ) + """ + A cache-control directive configuration that accepts a duration value in + seconds. + """ + + stale_if_error: Optional[UnionMember4RuleSetCacheControlRuleActionParametersStaleIfError] = FieldInfo( + alias="stale-if-error", default=None + ) + """ + A cache-control directive configuration that accepts a duration value in + seconds. + """ + + stale_while_revalidate: Optional[UnionMember4RuleSetCacheControlRuleActionParametersStaleWhileRevalidate] = ( + FieldInfo(alias="stale-while-revalidate", default=None) + ) + """ + A cache-control directive configuration that accepts a duration value in + seconds. + """ + + +class UnionMember4RuleSetCacheControlRuleExposedCredentialCheck(BaseModel): + """Configuration for exposed credential checking.""" + + password_expression: str + """An expression that selects the password used in the credentials check.""" + + username_expression: str + """An expression that selects the user ID used in the credentials check.""" + + +class UnionMember4RuleSetCacheControlRuleRatelimit(BaseModel): + """An object configuring the rule's rate limit behavior.""" + + characteristics: List[str] + """ + Characteristics of the request on which the rate limit counter will be + incremented. + """ + + period: int + """Period in seconds over which the counter is being incremented.""" + + counting_expression: Optional[str] = None + """An expression that defines when the rate limit counter should be incremented. + + It defaults to the same as the rule's expression. + """ + + mitigation_timeout: Optional[int] = None + """ + Period of time in seconds after which the action will be disabled following its + first execution. + """ + + requests_per_period: Optional[int] = None + """ + The threshold of requests per period after which the action will be executed for + the first time. + """ + + requests_to_origin: Optional[bool] = None + """Whether counting is only performed when an origin is reached.""" + + score_per_period: Optional[int] = None + """ + The score threshold per period for which the action will be executed the first + time. + """ + + score_response_header_name: Optional[str] = None + """ + A response header name provided by the origin, which contains the score to + increment rate limit counter with. + """ + + +class UnionMember4RuleSetCacheControlRule(BaseModel): + id: str + """The unique ID of the rule.""" + + action: Literal["set_cache_control"] + """The action to perform when the rule matches.""" + + enabled: bool + + expression: str + """The expression defining which traffic will match the rule.""" + + last_updated: datetime + """The timestamp of when the rule was last modified.""" + + ref: str + """The reference of the rule (the rule's ID by default).""" + + version: str + """The version of the rule.""" + + action_parameters: Optional[UnionMember4RuleSetCacheControlRuleActionParameters] = None + """The parameters configuring the rule's action.""" + + categories: Optional[List[str]] = None + """The categories of the rule.""" + + description: Optional[str] = None + """An informative description of the rule.""" + + exposed_credential_check: Optional[UnionMember4RuleSetCacheControlRuleExposedCredentialCheck] = None + """Configuration for exposed credential checking.""" + + logging: Optional[Logging] = None + """An object configuring the rule's logging behavior.""" + + ratelimit: Optional[UnionMember4RuleSetCacheControlRuleRatelimit] = None + """An object configuring the rule's rate limit behavior.""" + + +class UnionMember4RuleSetCacheSettingsRule(SetCacheSettingsRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember4RuleSetCacheTagsRuleActionParametersAddCacheTagsValues(BaseModel): + """Add cache tags using a list of values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + values: List[str] + """A list of cache tag values.""" + + +class UnionMember4RuleSetCacheTagsRuleActionParametersAddCacheTagsExpression(BaseModel): + """Add cache tags using an expression.""" + + expression: str + """An expression that evaluates to an array of cache tag values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + +class UnionMember4RuleSetCacheTagsRuleActionParametersRemoveCacheTagsValues(BaseModel): + """Remove cache tags using a list of values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + values: List[str] + """A list of cache tag values.""" + + +class UnionMember4RuleSetCacheTagsRuleActionParametersRemoveCacheTagsExpression(BaseModel): + """Remove cache tags using an expression.""" + + expression: str + """An expression that evaluates to an array of cache tag values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + +class UnionMember4RuleSetCacheTagsRuleActionParametersSetCacheTagsValues(BaseModel): + """Set cache tags using a list of values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + values: List[str] + """A list of cache tag values.""" + + +class UnionMember4RuleSetCacheTagsRuleActionParametersSetCacheTagsExpression(BaseModel): + """Set cache tags using an expression.""" + + expression: str + """An expression that evaluates to an array of cache tag values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + +UnionMember4RuleSetCacheTagsRuleActionParameters: TypeAlias = Union[ + UnionMember4RuleSetCacheTagsRuleActionParametersAddCacheTagsValues, + UnionMember4RuleSetCacheTagsRuleActionParametersAddCacheTagsExpression, + UnionMember4RuleSetCacheTagsRuleActionParametersRemoveCacheTagsValues, + UnionMember4RuleSetCacheTagsRuleActionParametersRemoveCacheTagsExpression, + UnionMember4RuleSetCacheTagsRuleActionParametersSetCacheTagsValues, + UnionMember4RuleSetCacheTagsRuleActionParametersSetCacheTagsExpression, +] + + +class UnionMember4RuleSetCacheTagsRuleExposedCredentialCheck(BaseModel): + """Configuration for exposed credential checking.""" + + password_expression: str + """An expression that selects the password used in the credentials check.""" + + username_expression: str + """An expression that selects the user ID used in the credentials check.""" + + +class UnionMember4RuleSetCacheTagsRuleRatelimit(BaseModel): + """An object configuring the rule's rate limit behavior.""" + + characteristics: List[str] + """ + Characteristics of the request on which the rate limit counter will be + incremented. + """ + + period: int + """Period in seconds over which the counter is being incremented.""" + + counting_expression: Optional[str] = None + """An expression that defines when the rate limit counter should be incremented. + + It defaults to the same as the rule's expression. + """ + + mitigation_timeout: Optional[int] = None + """ + Period of time in seconds after which the action will be disabled following its + first execution. + """ + + requests_per_period: Optional[int] = None + """ + The threshold of requests per period after which the action will be executed for + the first time. + """ + + requests_to_origin: Optional[bool] = None + """Whether counting is only performed when an origin is reached.""" + + score_per_period: Optional[int] = None + """ + The score threshold per period for which the action will be executed the first + time. + """ + + score_response_header_name: Optional[str] = None + """ + A response header name provided by the origin, which contains the score to + increment rate limit counter with. + """ + + +class UnionMember4RuleSetCacheTagsRule(BaseModel): + id: str + """The unique ID of the rule.""" + + action: Literal["set_cache_tags"] + """The action to perform when the rule matches.""" + + enabled: bool + + expression: str + """The expression defining which traffic will match the rule.""" + + last_updated: datetime + """The timestamp of when the rule was last modified.""" + + ref: str + """The reference of the rule (the rule's ID by default).""" + + version: str + """The version of the rule.""" + + action_parameters: Optional[UnionMember4RuleSetCacheTagsRuleActionParameters] = None + """The parameters configuring the rule's action.""" + + categories: Optional[List[str]] = None + """The categories of the rule.""" + + description: Optional[str] = None + """An informative description of the rule.""" + + exposed_credential_check: Optional[UnionMember4RuleSetCacheTagsRuleExposedCredentialCheck] = None + """Configuration for exposed credential checking.""" + + logging: Optional[Logging] = None + """An object configuring the rule's logging behavior.""" + + ratelimit: Optional[UnionMember4RuleSetCacheTagsRuleRatelimit] = None + """An object configuring the rule's rate limit behavior.""" + + +class UnionMember4RuleSetConfigurationRule(SetConfigRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember4RuleSkipRule(SkipRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember4RuleTransformResponseHTMLRuleActionParameters(BaseModel): + """The parameters configuring the rule's action.""" + + link_maze: object + """Enables the link maze transformation on the response.""" + + +class UnionMember4RuleTransformResponseHTMLRuleExposedCredentialCheck(BaseModel): + """Configuration for exposed credential checking.""" + + password_expression: str + """An expression that selects the password used in the credentials check.""" + + username_expression: str + """An expression that selects the user ID used in the credentials check.""" + + +class UnionMember4RuleTransformResponseHTMLRuleRatelimit(BaseModel): + """An object configuring the rule's rate limit behavior.""" + + characteristics: List[str] + """ + Characteristics of the request on which the rate limit counter will be + incremented. + """ + + period: int + """Period in seconds over which the counter is being incremented.""" + + counting_expression: Optional[str] = None + """An expression that defines when the rate limit counter should be incremented. + + It defaults to the same as the rule's expression. + """ + + mitigation_timeout: Optional[int] = None + """ + Period of time in seconds after which the action will be disabled following its + first execution. + """ + + requests_per_period: Optional[int] = None + """ + The threshold of requests per period after which the action will be executed for + the first time. + """ + + requests_to_origin: Optional[bool] = None + """Whether counting is only performed when an origin is reached.""" + + score_per_period: Optional[int] = None + """ + The score threshold per period for which the action will be executed the first + time. + """ + + score_response_header_name: Optional[str] = None + """ + A response header name provided by the origin, which contains the score to + increment rate limit counter with. + """ + + +class UnionMember4RuleTransformResponseHTMLRule(BaseModel): + id: str + """The unique ID of the rule.""" + + action: Literal["transform_response_html"] + """The action to perform when the rule matches.""" + + enabled: bool + + expression: str + """The expression defining which traffic will match the rule.""" + + last_updated: datetime + """The timestamp of when the rule was last modified.""" + + ref: str + """The reference of the rule (the rule's ID by default).""" + + version: str + """The version of the rule.""" + + action_parameters: Optional[UnionMember4RuleTransformResponseHTMLRuleActionParameters] = None + """The parameters configuring the rule's action.""" + + categories: Optional[List[str]] = None + """The categories of the rule.""" + + description: Optional[str] = None + """An informative description of the rule.""" + + exposed_credential_check: Optional[UnionMember4RuleTransformResponseHTMLRuleExposedCredentialCheck] = None + """Configuration for exposed credential checking.""" + + logging: Optional[Logging] = None + """An object configuring the rule's logging behavior.""" + + ratelimit: Optional[UnionMember4RuleTransformResponseHTMLRuleRatelimit] = None + """An object configuring the rule's rate limit behavior.""" + + +UnionMember4Rule: TypeAlias = Union[ + UnionMember4RuleBlockRule, + UnionMember4RuleChallengeRule, + UnionMember4RuleResponseCompressionRule, + UnionMember4RuleDDoSDynamicRule, + UnionMember4RuleExecuteRule, + UnionMember4RuleForceConnectionCloseRule, + UnionMember4RuleJavaScriptChallengeRule, + UnionMember4RuleLogRule, + UnionMember4RuleLogCustomFieldRule, + UnionMember4RuleManagedChallengeRule, + UnionMember4RuleRedirectRule, + UnionMember4RuleRewriteRule, + UnionMember4RuleRouteRule, + UnionMember4RuleScoreRule, + UnionMember4RuleServeErrorRule, + UnionMember4RuleSetCacheControlRule, + UnionMember4RuleSetCacheSettingsRule, + UnionMember4RuleSetCacheTagsRule, + UnionMember4RuleSetConfigurationRule, + UnionMember4RuleSkipRule, + UnionMember4RuleTransformResponseHTMLRule, +] + + +class UnionMember4(BaseModel): + id: Optional[str] = None + """The unique ID of the ruleset.""" + + description: Optional[str] = None + """An informative description of the ruleset.""" + + kind: Optional[Kind] = None + """The kind of the ruleset.""" + + last_updated: Optional[datetime] = None + """The timestamp of when the ruleset was last modified.""" + + name: Optional[str] = None + """The human-readable name of the ruleset.""" + + phase: Optional[Phase] = None + """The phase of the ruleset.""" + + rules: Optional[List[UnionMember4Rule]] = None + """The list of rules in the ruleset.""" + + version: Optional[str] = None + """The version of the ruleset.""" + + +VersionGetResponse: TypeAlias = Union[Optional[UnionMember0], UnionMember1, UnionMember2, UnionMember3, UnionMember4] diff --git a/src/cloudflare/types/rulesets/phases/version_list_response.py b/src/cloudflare/types/rulesets/phases/version_list_response.py index fbdd2b8b4cf..ed4be2242d5 100644 --- a/src/cloudflare/types/rulesets/phases/version_list_response.py +++ b/src/cloudflare/types/rulesets/phases/version_list_response.py @@ -1,35 +1,8 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import Optional -from datetime import datetime - -from ..kind import Kind -from ..phase import Phase -from ...._models import BaseModel +from typing import List, Union, Optional +from typing_extensions import TypeAlias __all__ = ["VersionListResponse"] - -class VersionListResponse(BaseModel): - """A ruleset object.""" - - id: str - """The unique ID of the ruleset.""" - - kind: Kind - """The kind of the ruleset.""" - - last_updated: datetime - """The timestamp of when the ruleset was last modified.""" - - name: str - """The human-readable name of the ruleset.""" - - phase: Phase - """The phase of the ruleset.""" - - version: str - """The version of the ruleset.""" - - description: Optional[str] = None - """An informative description of the ruleset.""" +VersionListResponse: TypeAlias = Union[List[object], str, float, bool, Optional[object]] diff --git a/src/cloudflare/types/rulesets/rule_create_params.py b/src/cloudflare/types/rulesets/rule_create_params.py index cdcc2b7bf43..21815d292d5 100644 --- a/src/cloudflare/types/rulesets/rule_create_params.py +++ b/src/cloudflare/types/rulesets/rule_create_params.py @@ -4134,8 +4134,7 @@ class SetConfigurationRuleActionParameters(TypedDict, total=False): """Bundled WebMCP tool packs to activate for matching requests. An empty array disables all packs. Omitting this parameter leaves the pack - selection unchanged. Does not enable the WebMCP bridge itself. Non-empty - selections require the WebMCP Configuration Rules entitlement. + selection unchanged. Does not enable the WebMCP bridge itself. """ diff --git a/src/cloudflare/types/rulesets/rule_create_response.py b/src/cloudflare/types/rulesets/rule_create_response.py index f2bdd68be68..1ea25fc28f2 100644 --- a/src/cloudflare/types/rulesets/rule_create_response.py +++ b/src/cloudflare/types/rulesets/rule_create_response.py @@ -1358,4 +1358,4 @@ class Ruleset(BaseModel): """An informative description of the ruleset.""" -RuleCreateResponse: TypeAlias = Union[Ruleset, Optional[object]] +RuleCreateResponse: TypeAlias = Union[List[object], str, float, bool, Ruleset, Optional[object], Optional[object]] diff --git a/src/cloudflare/types/rulesets/rule_delete_response.py b/src/cloudflare/types/rulesets/rule_delete_response.py index a8f3983ece3..5ae02a797da 100644 --- a/src/cloudflare/types/rulesets/rule_delete_response.py +++ b/src/cloudflare/types/rulesets/rule_delete_response.py @@ -1358,4 +1358,4 @@ class Ruleset(BaseModel): """An informative description of the ruleset.""" -RuleDeleteResponse: TypeAlias = Union[Ruleset, Optional[object]] +RuleDeleteResponse: TypeAlias = Union[List[object], str, float, bool, Ruleset, Optional[object], Optional[object]] diff --git a/src/cloudflare/types/rulesets/rule_edit_params.py b/src/cloudflare/types/rulesets/rule_edit_params.py index f9597d1f498..808674f7d0c 100644 --- a/src/cloudflare/types/rulesets/rule_edit_params.py +++ b/src/cloudflare/types/rulesets/rule_edit_params.py @@ -4191,8 +4191,7 @@ class SetConfigurationRuleActionParameters(TypedDict, total=False): """Bundled WebMCP tool packs to activate for matching requests. An empty array disables all packs. Omitting this parameter leaves the pack - selection unchanged. Does not enable the WebMCP bridge itself. Non-empty - selections require the WebMCP Configuration Rules entitlement. + selection unchanged. Does not enable the WebMCP bridge itself. """ diff --git a/src/cloudflare/types/rulesets/rule_edit_response.py b/src/cloudflare/types/rulesets/rule_edit_response.py index 0c730898004..478044fe746 100644 --- a/src/cloudflare/types/rulesets/rule_edit_response.py +++ b/src/cloudflare/types/rulesets/rule_edit_response.py @@ -1358,4 +1358,4 @@ class Ruleset(BaseModel): """An informative description of the ruleset.""" -RuleEditResponse: TypeAlias = Union[Ruleset, Optional[object]] +RuleEditResponse: TypeAlias = Union[List[object], str, float, bool, Ruleset, Optional[object], Optional[object]] diff --git a/src/cloudflare/types/rulesets/ruleset_create_response.py b/src/cloudflare/types/rulesets/ruleset_create_response.py index 8d280e41dab..ec1408da8dc 100644 --- a/src/cloudflare/types/rulesets/ruleset_create_response.py +++ b/src/cloudflare/types/rulesets/ruleset_create_response.py @@ -1358,4 +1358,4 @@ class Ruleset(BaseModel): """An informative description of the ruleset.""" -RulesetCreateResponse: TypeAlias = Union[Ruleset, Optional[object]] +RulesetCreateResponse: TypeAlias = Union[List[object], str, float, bool, Ruleset, Optional[object], Optional[object]] diff --git a/src/cloudflare/types/rulesets/ruleset_get_response.py b/src/cloudflare/types/rulesets/ruleset_get_response.py index 1f0571346cf..d25c0790d22 100644 --- a/src/cloudflare/types/rulesets/ruleset_get_response.py +++ b/src/cloudflare/types/rulesets/ruleset_get_response.py @@ -29,102 +29,427 @@ __all__ = [ "RulesetGetResponse", - "Rule", - "RuleBlockRule", - "RuleChallengeRule", - "RuleChallengeRuleExposedCredentialCheck", - "RuleChallengeRuleRatelimit", - "RuleResponseCompressionRule", - "RuleDDoSDynamicRule", - "RuleExecuteRule", - "RuleForceConnectionCloseRule", - "RuleJavaScriptChallengeRule", - "RuleJavaScriptChallengeRuleExposedCredentialCheck", - "RuleJavaScriptChallengeRuleRatelimit", - "RuleLogRule", - "RuleLogCustomFieldRule", - "RuleManagedChallengeRule", - "RuleRedirectRule", - "RuleRewriteRule", - "RuleRouteRule", - "RuleScoreRule", - "RuleServeErrorRule", - "RuleSetCacheControlRule", - "RuleSetCacheControlRuleActionParameters", - "RuleSetCacheControlRuleActionParametersImmutable", - "RuleSetCacheControlRuleActionParametersImmutableSetDirective", - "RuleSetCacheControlRuleActionParametersImmutableRemoveDirective", - "RuleSetCacheControlRuleActionParametersMaxAge", - "RuleSetCacheControlRuleActionParametersMaxAgeSetDirective", - "RuleSetCacheControlRuleActionParametersMaxAgeRemoveDirective", - "RuleSetCacheControlRuleActionParametersMustRevalidate", - "RuleSetCacheControlRuleActionParametersMustRevalidateSetDirective", - "RuleSetCacheControlRuleActionParametersMustRevalidateRemoveDirective", - "RuleSetCacheControlRuleActionParametersMustUnderstand", - "RuleSetCacheControlRuleActionParametersMustUnderstandSetDirective", - "RuleSetCacheControlRuleActionParametersMustUnderstandRemoveDirective", - "RuleSetCacheControlRuleActionParametersNoCache", - "RuleSetCacheControlRuleActionParametersNoCacheSetDirective", - "RuleSetCacheControlRuleActionParametersNoCacheRemoveDirective", - "RuleSetCacheControlRuleActionParametersNoStore", - "RuleSetCacheControlRuleActionParametersNoStoreSetDirective", - "RuleSetCacheControlRuleActionParametersNoStoreRemoveDirective", - "RuleSetCacheControlRuleActionParametersNoTransform", - "RuleSetCacheControlRuleActionParametersNoTransformSetDirective", - "RuleSetCacheControlRuleActionParametersNoTransformRemoveDirective", - "RuleSetCacheControlRuleActionParametersPrivate", - "RuleSetCacheControlRuleActionParametersPrivateSetDirective", - "RuleSetCacheControlRuleActionParametersPrivateRemoveDirective", - "RuleSetCacheControlRuleActionParametersProxyRevalidate", - "RuleSetCacheControlRuleActionParametersProxyRevalidateSetDirective", - "RuleSetCacheControlRuleActionParametersProxyRevalidateRemoveDirective", - "RuleSetCacheControlRuleActionParametersPublic", - "RuleSetCacheControlRuleActionParametersPublicSetDirective", - "RuleSetCacheControlRuleActionParametersPublicRemoveDirective", - "RuleSetCacheControlRuleActionParametersSMaxage", - "RuleSetCacheControlRuleActionParametersSMaxageSetDirective", - "RuleSetCacheControlRuleActionParametersSMaxageRemoveDirective", - "RuleSetCacheControlRuleActionParametersStaleIfError", - "RuleSetCacheControlRuleActionParametersStaleIfErrorSetDirective", - "RuleSetCacheControlRuleActionParametersStaleIfErrorRemoveDirective", - "RuleSetCacheControlRuleActionParametersStaleWhileRevalidate", - "RuleSetCacheControlRuleActionParametersStaleWhileRevalidateSetDirective", - "RuleSetCacheControlRuleActionParametersStaleWhileRevalidateRemoveDirective", - "RuleSetCacheControlRuleExposedCredentialCheck", - "RuleSetCacheControlRuleRatelimit", - "RuleSetCacheSettingsRule", - "RuleSetCacheTagsRule", - "RuleSetCacheTagsRuleActionParameters", - "RuleSetCacheTagsRuleActionParametersAddCacheTagsValues", - "RuleSetCacheTagsRuleActionParametersAddCacheTagsExpression", - "RuleSetCacheTagsRuleActionParametersRemoveCacheTagsValues", - "RuleSetCacheTagsRuleActionParametersRemoveCacheTagsExpression", - "RuleSetCacheTagsRuleActionParametersSetCacheTagsValues", - "RuleSetCacheTagsRuleActionParametersSetCacheTagsExpression", - "RuleSetCacheTagsRuleExposedCredentialCheck", - "RuleSetCacheTagsRuleRatelimit", - "RuleSetConfigurationRule", - "RuleSkipRule", - "RuleTransformResponseHTMLRule", - "RuleTransformResponseHTMLRuleActionParameters", - "RuleTransformResponseHTMLRuleExposedCredentialCheck", - "RuleTransformResponseHTMLRuleRatelimit", -] - - -class RuleBlockRule(BlockRule): - id: str # type: ignore - - action: str # type: ignore - - enabled: bool # type: ignore - - expression: str # type: ignore - - ref: str # type: ignore - - -class RuleChallengeRuleExposedCredentialCheck(BaseModel): + "UnionMember0", + "UnionMember0Rule", + "UnionMember0RuleBlockRule", + "UnionMember0RuleChallengeRule", + "UnionMember0RuleChallengeRuleExposedCredentialCheck", + "UnionMember0RuleChallengeRuleRatelimit", + "UnionMember0RuleResponseCompressionRule", + "UnionMember0RuleDDoSDynamicRule", + "UnionMember0RuleExecuteRule", + "UnionMember0RuleForceConnectionCloseRule", + "UnionMember0RuleJavaScriptChallengeRule", + "UnionMember0RuleJavaScriptChallengeRuleExposedCredentialCheck", + "UnionMember0RuleJavaScriptChallengeRuleRatelimit", + "UnionMember0RuleLogRule", + "UnionMember0RuleLogCustomFieldRule", + "UnionMember0RuleManagedChallengeRule", + "UnionMember0RuleRedirectRule", + "UnionMember0RuleRewriteRule", + "UnionMember0RuleRouteRule", + "UnionMember0RuleScoreRule", + "UnionMember0RuleServeErrorRule", + "UnionMember0RuleSetCacheControlRule", + "UnionMember0RuleSetCacheControlRuleActionParameters", + "UnionMember0RuleSetCacheControlRuleActionParametersImmutable", + "UnionMember0RuleSetCacheControlRuleActionParametersImmutableSetDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersImmutableRemoveDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersMaxAge", + "UnionMember0RuleSetCacheControlRuleActionParametersMaxAgeSetDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersMaxAgeRemoveDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersMustRevalidate", + "UnionMember0RuleSetCacheControlRuleActionParametersMustRevalidateSetDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersMustRevalidateRemoveDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersMustUnderstand", + "UnionMember0RuleSetCacheControlRuleActionParametersMustUnderstandSetDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersMustUnderstandRemoveDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersNoCache", + "UnionMember0RuleSetCacheControlRuleActionParametersNoCacheSetDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersNoCacheRemoveDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersNoStore", + "UnionMember0RuleSetCacheControlRuleActionParametersNoStoreSetDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersNoStoreRemoveDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersNoTransform", + "UnionMember0RuleSetCacheControlRuleActionParametersNoTransformSetDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersNoTransformRemoveDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersPrivate", + "UnionMember0RuleSetCacheControlRuleActionParametersPrivateSetDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersPrivateRemoveDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersProxyRevalidate", + "UnionMember0RuleSetCacheControlRuleActionParametersProxyRevalidateSetDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersProxyRevalidateRemoveDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersPublic", + "UnionMember0RuleSetCacheControlRuleActionParametersPublicSetDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersPublicRemoveDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersSMaxage", + "UnionMember0RuleSetCacheControlRuleActionParametersSMaxageSetDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersSMaxageRemoveDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersStaleIfError", + "UnionMember0RuleSetCacheControlRuleActionParametersStaleIfErrorSetDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersStaleIfErrorRemoveDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersStaleWhileRevalidate", + "UnionMember0RuleSetCacheControlRuleActionParametersStaleWhileRevalidateSetDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersStaleWhileRevalidateRemoveDirective", + "UnionMember0RuleSetCacheControlRuleExposedCredentialCheck", + "UnionMember0RuleSetCacheControlRuleRatelimit", + "UnionMember0RuleSetCacheSettingsRule", + "UnionMember0RuleSetCacheTagsRule", + "UnionMember0RuleSetCacheTagsRuleActionParameters", + "UnionMember0RuleSetCacheTagsRuleActionParametersAddCacheTagsValues", + "UnionMember0RuleSetCacheTagsRuleActionParametersAddCacheTagsExpression", + "UnionMember0RuleSetCacheTagsRuleActionParametersRemoveCacheTagsValues", + "UnionMember0RuleSetCacheTagsRuleActionParametersRemoveCacheTagsExpression", + "UnionMember0RuleSetCacheTagsRuleActionParametersSetCacheTagsValues", + "UnionMember0RuleSetCacheTagsRuleActionParametersSetCacheTagsExpression", + "UnionMember0RuleSetCacheTagsRuleExposedCredentialCheck", + "UnionMember0RuleSetCacheTagsRuleRatelimit", + "UnionMember0RuleSetConfigurationRule", + "UnionMember0RuleSkipRule", + "UnionMember0RuleTransformResponseHTMLRule", + "UnionMember0RuleTransformResponseHTMLRuleActionParameters", + "UnionMember0RuleTransformResponseHTMLRuleExposedCredentialCheck", + "UnionMember0RuleTransformResponseHTMLRuleRatelimit", + "UnionMember1", + "UnionMember1Rule", + "UnionMember1RuleBlockRule", + "UnionMember1RuleChallengeRule", + "UnionMember1RuleChallengeRuleExposedCredentialCheck", + "UnionMember1RuleChallengeRuleRatelimit", + "UnionMember1RuleResponseCompressionRule", + "UnionMember1RuleDDoSDynamicRule", + "UnionMember1RuleExecuteRule", + "UnionMember1RuleForceConnectionCloseRule", + "UnionMember1RuleJavaScriptChallengeRule", + "UnionMember1RuleJavaScriptChallengeRuleExposedCredentialCheck", + "UnionMember1RuleJavaScriptChallengeRuleRatelimit", + "UnionMember1RuleLogRule", + "UnionMember1RuleLogCustomFieldRule", + "UnionMember1RuleManagedChallengeRule", + "UnionMember1RuleRedirectRule", + "UnionMember1RuleRewriteRule", + "UnionMember1RuleRouteRule", + "UnionMember1RuleScoreRule", + "UnionMember1RuleServeErrorRule", + "UnionMember1RuleSetCacheControlRule", + "UnionMember1RuleSetCacheControlRuleActionParameters", + "UnionMember1RuleSetCacheControlRuleActionParametersImmutable", + "UnionMember1RuleSetCacheControlRuleActionParametersImmutableSetDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersImmutableRemoveDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersMaxAge", + "UnionMember1RuleSetCacheControlRuleActionParametersMaxAgeSetDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersMaxAgeRemoveDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersMustRevalidate", + "UnionMember1RuleSetCacheControlRuleActionParametersMustRevalidateSetDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersMustRevalidateRemoveDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersMustUnderstand", + "UnionMember1RuleSetCacheControlRuleActionParametersMustUnderstandSetDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersMustUnderstandRemoveDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersNoCache", + "UnionMember1RuleSetCacheControlRuleActionParametersNoCacheSetDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersNoCacheRemoveDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersNoStore", + "UnionMember1RuleSetCacheControlRuleActionParametersNoStoreSetDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersNoStoreRemoveDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersNoTransform", + "UnionMember1RuleSetCacheControlRuleActionParametersNoTransformSetDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersNoTransformRemoveDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersPrivate", + "UnionMember1RuleSetCacheControlRuleActionParametersPrivateSetDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersPrivateRemoveDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersProxyRevalidate", + "UnionMember1RuleSetCacheControlRuleActionParametersProxyRevalidateSetDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersProxyRevalidateRemoveDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersPublic", + "UnionMember1RuleSetCacheControlRuleActionParametersPublicSetDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersPublicRemoveDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersSMaxage", + "UnionMember1RuleSetCacheControlRuleActionParametersSMaxageSetDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersSMaxageRemoveDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersStaleIfError", + "UnionMember1RuleSetCacheControlRuleActionParametersStaleIfErrorSetDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersStaleIfErrorRemoveDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersStaleWhileRevalidate", + "UnionMember1RuleSetCacheControlRuleActionParametersStaleWhileRevalidateSetDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersStaleWhileRevalidateRemoveDirective", + "UnionMember1RuleSetCacheControlRuleExposedCredentialCheck", + "UnionMember1RuleSetCacheControlRuleRatelimit", + "UnionMember1RuleSetCacheSettingsRule", + "UnionMember1RuleSetCacheTagsRule", + "UnionMember1RuleSetCacheTagsRuleActionParameters", + "UnionMember1RuleSetCacheTagsRuleActionParametersAddCacheTagsValues", + "UnionMember1RuleSetCacheTagsRuleActionParametersAddCacheTagsExpression", + "UnionMember1RuleSetCacheTagsRuleActionParametersRemoveCacheTagsValues", + "UnionMember1RuleSetCacheTagsRuleActionParametersRemoveCacheTagsExpression", + "UnionMember1RuleSetCacheTagsRuleActionParametersSetCacheTagsValues", + "UnionMember1RuleSetCacheTagsRuleActionParametersSetCacheTagsExpression", + "UnionMember1RuleSetCacheTagsRuleExposedCredentialCheck", + "UnionMember1RuleSetCacheTagsRuleRatelimit", + "UnionMember1RuleSetConfigurationRule", + "UnionMember1RuleSkipRule", + "UnionMember1RuleTransformResponseHTMLRule", + "UnionMember1RuleTransformResponseHTMLRuleActionParameters", + "UnionMember1RuleTransformResponseHTMLRuleExposedCredentialCheck", + "UnionMember1RuleTransformResponseHTMLRuleRatelimit", + "UnionMember2", + "UnionMember2Rule", + "UnionMember2RuleBlockRule", + "UnionMember2RuleChallengeRule", + "UnionMember2RuleChallengeRuleExposedCredentialCheck", + "UnionMember2RuleChallengeRuleRatelimit", + "UnionMember2RuleResponseCompressionRule", + "UnionMember2RuleDDoSDynamicRule", + "UnionMember2RuleExecuteRule", + "UnionMember2RuleForceConnectionCloseRule", + "UnionMember2RuleJavaScriptChallengeRule", + "UnionMember2RuleJavaScriptChallengeRuleExposedCredentialCheck", + "UnionMember2RuleJavaScriptChallengeRuleRatelimit", + "UnionMember2RuleLogRule", + "UnionMember2RuleLogCustomFieldRule", + "UnionMember2RuleManagedChallengeRule", + "UnionMember2RuleRedirectRule", + "UnionMember2RuleRewriteRule", + "UnionMember2RuleRouteRule", + "UnionMember2RuleScoreRule", + "UnionMember2RuleServeErrorRule", + "UnionMember2RuleSetCacheControlRule", + "UnionMember2RuleSetCacheControlRuleActionParameters", + "UnionMember2RuleSetCacheControlRuleActionParametersImmutable", + "UnionMember2RuleSetCacheControlRuleActionParametersImmutableSetDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersImmutableRemoveDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersMaxAge", + "UnionMember2RuleSetCacheControlRuleActionParametersMaxAgeSetDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersMaxAgeRemoveDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersMustRevalidate", + "UnionMember2RuleSetCacheControlRuleActionParametersMustRevalidateSetDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersMustRevalidateRemoveDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersMustUnderstand", + "UnionMember2RuleSetCacheControlRuleActionParametersMustUnderstandSetDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersMustUnderstandRemoveDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersNoCache", + "UnionMember2RuleSetCacheControlRuleActionParametersNoCacheSetDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersNoCacheRemoveDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersNoStore", + "UnionMember2RuleSetCacheControlRuleActionParametersNoStoreSetDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersNoStoreRemoveDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersNoTransform", + "UnionMember2RuleSetCacheControlRuleActionParametersNoTransformSetDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersNoTransformRemoveDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersPrivate", + "UnionMember2RuleSetCacheControlRuleActionParametersPrivateSetDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersPrivateRemoveDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersProxyRevalidate", + "UnionMember2RuleSetCacheControlRuleActionParametersProxyRevalidateSetDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersProxyRevalidateRemoveDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersPublic", + "UnionMember2RuleSetCacheControlRuleActionParametersPublicSetDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersPublicRemoveDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersSMaxage", + "UnionMember2RuleSetCacheControlRuleActionParametersSMaxageSetDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersSMaxageRemoveDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersStaleIfError", + "UnionMember2RuleSetCacheControlRuleActionParametersStaleIfErrorSetDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersStaleIfErrorRemoveDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersStaleWhileRevalidate", + "UnionMember2RuleSetCacheControlRuleActionParametersStaleWhileRevalidateSetDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersStaleWhileRevalidateRemoveDirective", + "UnionMember2RuleSetCacheControlRuleExposedCredentialCheck", + "UnionMember2RuleSetCacheControlRuleRatelimit", + "UnionMember2RuleSetCacheSettingsRule", + "UnionMember2RuleSetCacheTagsRule", + "UnionMember2RuleSetCacheTagsRuleActionParameters", + "UnionMember2RuleSetCacheTagsRuleActionParametersAddCacheTagsValues", + "UnionMember2RuleSetCacheTagsRuleActionParametersAddCacheTagsExpression", + "UnionMember2RuleSetCacheTagsRuleActionParametersRemoveCacheTagsValues", + "UnionMember2RuleSetCacheTagsRuleActionParametersRemoveCacheTagsExpression", + "UnionMember2RuleSetCacheTagsRuleActionParametersSetCacheTagsValues", + "UnionMember2RuleSetCacheTagsRuleActionParametersSetCacheTagsExpression", + "UnionMember2RuleSetCacheTagsRuleExposedCredentialCheck", + "UnionMember2RuleSetCacheTagsRuleRatelimit", + "UnionMember2RuleSetConfigurationRule", + "UnionMember2RuleSkipRule", + "UnionMember2RuleTransformResponseHTMLRule", + "UnionMember2RuleTransformResponseHTMLRuleActionParameters", + "UnionMember2RuleTransformResponseHTMLRuleExposedCredentialCheck", + "UnionMember2RuleTransformResponseHTMLRuleRatelimit", + "UnionMember3", + "UnionMember3Rule", + "UnionMember3RuleBlockRule", + "UnionMember3RuleChallengeRule", + "UnionMember3RuleChallengeRuleExposedCredentialCheck", + "UnionMember3RuleChallengeRuleRatelimit", + "UnionMember3RuleResponseCompressionRule", + "UnionMember3RuleDDoSDynamicRule", + "UnionMember3RuleExecuteRule", + "UnionMember3RuleForceConnectionCloseRule", + "UnionMember3RuleJavaScriptChallengeRule", + "UnionMember3RuleJavaScriptChallengeRuleExposedCredentialCheck", + "UnionMember3RuleJavaScriptChallengeRuleRatelimit", + "UnionMember3RuleLogRule", + "UnionMember3RuleLogCustomFieldRule", + "UnionMember3RuleManagedChallengeRule", + "UnionMember3RuleRedirectRule", + "UnionMember3RuleRewriteRule", + "UnionMember3RuleRouteRule", + "UnionMember3RuleScoreRule", + "UnionMember3RuleServeErrorRule", + "UnionMember3RuleSetCacheControlRule", + "UnionMember3RuleSetCacheControlRuleActionParameters", + "UnionMember3RuleSetCacheControlRuleActionParametersImmutable", + "UnionMember3RuleSetCacheControlRuleActionParametersImmutableSetDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersImmutableRemoveDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersMaxAge", + "UnionMember3RuleSetCacheControlRuleActionParametersMaxAgeSetDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersMaxAgeRemoveDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersMustRevalidate", + "UnionMember3RuleSetCacheControlRuleActionParametersMustRevalidateSetDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersMustRevalidateRemoveDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersMustUnderstand", + "UnionMember3RuleSetCacheControlRuleActionParametersMustUnderstandSetDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersMustUnderstandRemoveDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersNoCache", + "UnionMember3RuleSetCacheControlRuleActionParametersNoCacheSetDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersNoCacheRemoveDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersNoStore", + "UnionMember3RuleSetCacheControlRuleActionParametersNoStoreSetDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersNoStoreRemoveDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersNoTransform", + "UnionMember3RuleSetCacheControlRuleActionParametersNoTransformSetDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersNoTransformRemoveDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersPrivate", + "UnionMember3RuleSetCacheControlRuleActionParametersPrivateSetDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersPrivateRemoveDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersProxyRevalidate", + "UnionMember3RuleSetCacheControlRuleActionParametersProxyRevalidateSetDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersProxyRevalidateRemoveDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersPublic", + "UnionMember3RuleSetCacheControlRuleActionParametersPublicSetDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersPublicRemoveDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersSMaxage", + "UnionMember3RuleSetCacheControlRuleActionParametersSMaxageSetDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersSMaxageRemoveDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersStaleIfError", + "UnionMember3RuleSetCacheControlRuleActionParametersStaleIfErrorSetDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersStaleIfErrorRemoveDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersStaleWhileRevalidate", + "UnionMember3RuleSetCacheControlRuleActionParametersStaleWhileRevalidateSetDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersStaleWhileRevalidateRemoveDirective", + "UnionMember3RuleSetCacheControlRuleExposedCredentialCheck", + "UnionMember3RuleSetCacheControlRuleRatelimit", + "UnionMember3RuleSetCacheSettingsRule", + "UnionMember3RuleSetCacheTagsRule", + "UnionMember3RuleSetCacheTagsRuleActionParameters", + "UnionMember3RuleSetCacheTagsRuleActionParametersAddCacheTagsValues", + "UnionMember3RuleSetCacheTagsRuleActionParametersAddCacheTagsExpression", + "UnionMember3RuleSetCacheTagsRuleActionParametersRemoveCacheTagsValues", + "UnionMember3RuleSetCacheTagsRuleActionParametersRemoveCacheTagsExpression", + "UnionMember3RuleSetCacheTagsRuleActionParametersSetCacheTagsValues", + "UnionMember3RuleSetCacheTagsRuleActionParametersSetCacheTagsExpression", + "UnionMember3RuleSetCacheTagsRuleExposedCredentialCheck", + "UnionMember3RuleSetCacheTagsRuleRatelimit", + "UnionMember3RuleSetConfigurationRule", + "UnionMember3RuleSkipRule", + "UnionMember3RuleTransformResponseHTMLRule", + "UnionMember3RuleTransformResponseHTMLRuleActionParameters", + "UnionMember3RuleTransformResponseHTMLRuleExposedCredentialCheck", + "UnionMember3RuleTransformResponseHTMLRuleRatelimit", + "UnionMember4", + "UnionMember4Rule", + "UnionMember4RuleBlockRule", + "UnionMember4RuleChallengeRule", + "UnionMember4RuleChallengeRuleExposedCredentialCheck", + "UnionMember4RuleChallengeRuleRatelimit", + "UnionMember4RuleResponseCompressionRule", + "UnionMember4RuleDDoSDynamicRule", + "UnionMember4RuleExecuteRule", + "UnionMember4RuleForceConnectionCloseRule", + "UnionMember4RuleJavaScriptChallengeRule", + "UnionMember4RuleJavaScriptChallengeRuleExposedCredentialCheck", + "UnionMember4RuleJavaScriptChallengeRuleRatelimit", + "UnionMember4RuleLogRule", + "UnionMember4RuleLogCustomFieldRule", + "UnionMember4RuleManagedChallengeRule", + "UnionMember4RuleRedirectRule", + "UnionMember4RuleRewriteRule", + "UnionMember4RuleRouteRule", + "UnionMember4RuleScoreRule", + "UnionMember4RuleServeErrorRule", + "UnionMember4RuleSetCacheControlRule", + "UnionMember4RuleSetCacheControlRuleActionParameters", + "UnionMember4RuleSetCacheControlRuleActionParametersImmutable", + "UnionMember4RuleSetCacheControlRuleActionParametersImmutableSetDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersImmutableRemoveDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersMaxAge", + "UnionMember4RuleSetCacheControlRuleActionParametersMaxAgeSetDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersMaxAgeRemoveDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersMustRevalidate", + "UnionMember4RuleSetCacheControlRuleActionParametersMustRevalidateSetDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersMustRevalidateRemoveDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersMustUnderstand", + "UnionMember4RuleSetCacheControlRuleActionParametersMustUnderstandSetDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersMustUnderstandRemoveDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersNoCache", + "UnionMember4RuleSetCacheControlRuleActionParametersNoCacheSetDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersNoCacheRemoveDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersNoStore", + "UnionMember4RuleSetCacheControlRuleActionParametersNoStoreSetDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersNoStoreRemoveDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersNoTransform", + "UnionMember4RuleSetCacheControlRuleActionParametersNoTransformSetDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersNoTransformRemoveDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersPrivate", + "UnionMember4RuleSetCacheControlRuleActionParametersPrivateSetDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersPrivateRemoveDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersProxyRevalidate", + "UnionMember4RuleSetCacheControlRuleActionParametersProxyRevalidateSetDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersProxyRevalidateRemoveDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersPublic", + "UnionMember4RuleSetCacheControlRuleActionParametersPublicSetDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersPublicRemoveDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersSMaxage", + "UnionMember4RuleSetCacheControlRuleActionParametersSMaxageSetDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersSMaxageRemoveDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersStaleIfError", + "UnionMember4RuleSetCacheControlRuleActionParametersStaleIfErrorSetDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersStaleIfErrorRemoveDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersStaleWhileRevalidate", + "UnionMember4RuleSetCacheControlRuleActionParametersStaleWhileRevalidateSetDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersStaleWhileRevalidateRemoveDirective", + "UnionMember4RuleSetCacheControlRuleExposedCredentialCheck", + "UnionMember4RuleSetCacheControlRuleRatelimit", + "UnionMember4RuleSetCacheSettingsRule", + "UnionMember4RuleSetCacheTagsRule", + "UnionMember4RuleSetCacheTagsRuleActionParameters", + "UnionMember4RuleSetCacheTagsRuleActionParametersAddCacheTagsValues", + "UnionMember4RuleSetCacheTagsRuleActionParametersAddCacheTagsExpression", + "UnionMember4RuleSetCacheTagsRuleActionParametersRemoveCacheTagsValues", + "UnionMember4RuleSetCacheTagsRuleActionParametersRemoveCacheTagsExpression", + "UnionMember4RuleSetCacheTagsRuleActionParametersSetCacheTagsValues", + "UnionMember4RuleSetCacheTagsRuleActionParametersSetCacheTagsExpression", + "UnionMember4RuleSetCacheTagsRuleExposedCredentialCheck", + "UnionMember4RuleSetCacheTagsRuleRatelimit", + "UnionMember4RuleSetConfigurationRule", + "UnionMember4RuleSkipRule", + "UnionMember4RuleTransformResponseHTMLRule", + "UnionMember4RuleTransformResponseHTMLRuleActionParameters", + "UnionMember4RuleTransformResponseHTMLRuleExposedCredentialCheck", + "UnionMember4RuleTransformResponseHTMLRuleRatelimit", +] + + +class UnionMember0RuleBlockRule(BlockRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember0RuleChallengeRuleExposedCredentialCheck(BaseModel): """Configuration for exposed credential checking.""" password_expression: str @@ -134,7 +459,7 @@ class RuleChallengeRuleExposedCredentialCheck(BaseModel): """An expression that selects the user ID used in the credentials check.""" -class RuleChallengeRuleRatelimit(BaseModel): +class UnionMember0RuleChallengeRuleRatelimit(BaseModel): """An object configuring the rule's rate limit behavior.""" characteristics: List[str] @@ -180,7 +505,7 @@ class RuleChallengeRuleRatelimit(BaseModel): """ -class RuleChallengeRule(BaseModel): +class UnionMember0RuleChallengeRule(BaseModel): id: str """The unique ID of the rule.""" @@ -211,17 +536,17 @@ class RuleChallengeRule(BaseModel): description: Optional[str] = None """An informative description of the rule.""" - exposed_credential_check: Optional[RuleChallengeRuleExposedCredentialCheck] = None + exposed_credential_check: Optional[UnionMember0RuleChallengeRuleExposedCredentialCheck] = None """Configuration for exposed credential checking.""" logging: Optional[Logging] = None """An object configuring the rule's logging behavior.""" - ratelimit: Optional[RuleChallengeRuleRatelimit] = None + ratelimit: Optional[UnionMember0RuleChallengeRuleRatelimit] = None """An object configuring the rule's rate limit behavior.""" -class RuleResponseCompressionRule(CompressResponseRule): +class UnionMember0RuleResponseCompressionRule(CompressResponseRule): id: str # type: ignore action: str # type: ignore @@ -233,7 +558,7 @@ class RuleResponseCompressionRule(CompressResponseRule): ref: str # type: ignore -class RuleDDoSDynamicRule(DDoSDynamicRule): +class UnionMember0RuleDDoSDynamicRule(DDoSDynamicRule): id: str # type: ignore action: str # type: ignore @@ -245,7 +570,7 @@ class RuleDDoSDynamicRule(DDoSDynamicRule): ref: str # type: ignore -class RuleExecuteRule(ExecuteRule): +class UnionMember0RuleExecuteRule(ExecuteRule): id: str # type: ignore action: str # type: ignore @@ -257,7 +582,7 @@ class RuleExecuteRule(ExecuteRule): ref: str # type: ignore -class RuleForceConnectionCloseRule(ForceConnectionCloseRule): +class UnionMember0RuleForceConnectionCloseRule(ForceConnectionCloseRule): id: str # type: ignore action: str # type: ignore @@ -269,7 +594,7 @@ class RuleForceConnectionCloseRule(ForceConnectionCloseRule): ref: str # type: ignore -class RuleJavaScriptChallengeRuleExposedCredentialCheck(BaseModel): +class UnionMember0RuleJavaScriptChallengeRuleExposedCredentialCheck(BaseModel): """Configuration for exposed credential checking.""" password_expression: str @@ -279,7 +604,7 @@ class RuleJavaScriptChallengeRuleExposedCredentialCheck(BaseModel): """An expression that selects the user ID used in the credentials check.""" -class RuleJavaScriptChallengeRuleRatelimit(BaseModel): +class UnionMember0RuleJavaScriptChallengeRuleRatelimit(BaseModel): """An object configuring the rule's rate limit behavior.""" characteristics: List[str] @@ -325,7 +650,7 @@ class RuleJavaScriptChallengeRuleRatelimit(BaseModel): """ -class RuleJavaScriptChallengeRule(BaseModel): +class UnionMember0RuleJavaScriptChallengeRule(BaseModel): id: str """The unique ID of the rule.""" @@ -356,17 +681,17 @@ class RuleJavaScriptChallengeRule(BaseModel): description: Optional[str] = None """An informative description of the rule.""" - exposed_credential_check: Optional[RuleJavaScriptChallengeRuleExposedCredentialCheck] = None + exposed_credential_check: Optional[UnionMember0RuleJavaScriptChallengeRuleExposedCredentialCheck] = None """Configuration for exposed credential checking.""" logging: Optional[Logging] = None """An object configuring the rule's logging behavior.""" - ratelimit: Optional[RuleJavaScriptChallengeRuleRatelimit] = None + ratelimit: Optional[UnionMember0RuleJavaScriptChallengeRuleRatelimit] = None """An object configuring the rule's rate limit behavior.""" -class RuleLogRule(LogRule): +class UnionMember0RuleLogRule(LogRule): id: str # type: ignore action: str # type: ignore @@ -378,7 +703,7 @@ class RuleLogRule(LogRule): ref: str # type: ignore -class RuleLogCustomFieldRule(LogCustomFieldRule): +class UnionMember0RuleLogCustomFieldRule(LogCustomFieldRule): id: str # type: ignore action: str # type: ignore @@ -390,7 +715,7 @@ class RuleLogCustomFieldRule(LogCustomFieldRule): ref: str # type: ignore -class RuleManagedChallengeRule(ManagedChallengeRule): +class UnionMember0RuleManagedChallengeRule(ManagedChallengeRule): id: str # type: ignore action: str # type: ignore @@ -402,7 +727,7 @@ class RuleManagedChallengeRule(ManagedChallengeRule): ref: str # type: ignore -class RuleRedirectRule(RedirectRule): +class UnionMember0RuleRedirectRule(RedirectRule): id: str # type: ignore action: str # type: ignore @@ -414,7 +739,7 @@ class RuleRedirectRule(RedirectRule): ref: str # type: ignore -class RuleRewriteRule(RewriteRule): +class UnionMember0RuleRewriteRule(RewriteRule): id: str # type: ignore action: str # type: ignore @@ -426,7 +751,7 @@ class RuleRewriteRule(RewriteRule): ref: str # type: ignore -class RuleRouteRule(RouteRule): +class UnionMember0RuleRouteRule(RouteRule): id: str # type: ignore action: str # type: ignore @@ -438,7 +763,7 @@ class RuleRouteRule(RouteRule): ref: str # type: ignore -class RuleScoreRule(ScoreRule): +class UnionMember0RuleScoreRule(ScoreRule): id: str # type: ignore action: str # type: ignore @@ -450,7 +775,7 @@ class RuleScoreRule(ScoreRule): ref: str # type: ignore -class RuleServeErrorRule(ServeErrorRule): +class UnionMember0RuleServeErrorRule(ServeErrorRule): id: str # type: ignore action: str # type: ignore @@ -462,7 +787,7 @@ class RuleServeErrorRule(ServeErrorRule): ref: str # type: ignore -class RuleSetCacheControlRuleActionParametersImmutableSetDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersImmutableSetDirective(BaseModel): """Set the directive.""" operation: Literal["set", "remove"] @@ -472,7 +797,7 @@ class RuleSetCacheControlRuleActionParametersImmutableSetDirective(BaseModel): """Whether the directive should only be applied to the Cloudflare CDN cache.""" -class RuleSetCacheControlRuleActionParametersImmutableRemoveDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersImmutableRemoveDirective(BaseModel): """Remove the directive.""" operation: Literal["set", "remove"] @@ -482,13 +807,13 @@ class RuleSetCacheControlRuleActionParametersImmutableRemoveDirective(BaseModel) """Whether the directive should only be applied to the Cloudflare CDN cache.""" -RuleSetCacheControlRuleActionParametersImmutable: TypeAlias = Union[ - RuleSetCacheControlRuleActionParametersImmutableSetDirective, - RuleSetCacheControlRuleActionParametersImmutableRemoveDirective, +UnionMember0RuleSetCacheControlRuleActionParametersImmutable: TypeAlias = Union[ + UnionMember0RuleSetCacheControlRuleActionParametersImmutableSetDirective, + UnionMember0RuleSetCacheControlRuleActionParametersImmutableRemoveDirective, ] -class RuleSetCacheControlRuleActionParametersMaxAgeSetDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersMaxAgeSetDirective(BaseModel): """Set the directive with a duration value in seconds.""" operation: Literal["set", "remove"] @@ -501,7 +826,7 @@ class RuleSetCacheControlRuleActionParametersMaxAgeSetDirective(BaseModel): """Whether the directive should only be applied to the Cloudflare CDN cache.""" -class RuleSetCacheControlRuleActionParametersMaxAgeRemoveDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersMaxAgeRemoveDirective(BaseModel): """Remove the directive.""" operation: Literal["set", "remove"] @@ -511,13 +836,13 @@ class RuleSetCacheControlRuleActionParametersMaxAgeRemoveDirective(BaseModel): """Whether the directive should only be applied to the Cloudflare CDN cache.""" -RuleSetCacheControlRuleActionParametersMaxAge: TypeAlias = Union[ - RuleSetCacheControlRuleActionParametersMaxAgeSetDirective, - RuleSetCacheControlRuleActionParametersMaxAgeRemoveDirective, +UnionMember0RuleSetCacheControlRuleActionParametersMaxAge: TypeAlias = Union[ + UnionMember0RuleSetCacheControlRuleActionParametersMaxAgeSetDirective, + UnionMember0RuleSetCacheControlRuleActionParametersMaxAgeRemoveDirective, ] -class RuleSetCacheControlRuleActionParametersMustRevalidateSetDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersMustRevalidateSetDirective(BaseModel): """Set the directive.""" operation: Literal["set", "remove"] @@ -527,7 +852,7 @@ class RuleSetCacheControlRuleActionParametersMustRevalidateSetDirective(BaseMode """Whether the directive should only be applied to the Cloudflare CDN cache.""" -class RuleSetCacheControlRuleActionParametersMustRevalidateRemoveDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersMustRevalidateRemoveDirective(BaseModel): """Remove the directive.""" operation: Literal["set", "remove"] @@ -537,13 +862,13 @@ class RuleSetCacheControlRuleActionParametersMustRevalidateRemoveDirective(BaseM """Whether the directive should only be applied to the Cloudflare CDN cache.""" -RuleSetCacheControlRuleActionParametersMustRevalidate: TypeAlias = Union[ - RuleSetCacheControlRuleActionParametersMustRevalidateSetDirective, - RuleSetCacheControlRuleActionParametersMustRevalidateRemoveDirective, +UnionMember0RuleSetCacheControlRuleActionParametersMustRevalidate: TypeAlias = Union[ + UnionMember0RuleSetCacheControlRuleActionParametersMustRevalidateSetDirective, + UnionMember0RuleSetCacheControlRuleActionParametersMustRevalidateRemoveDirective, ] -class RuleSetCacheControlRuleActionParametersMustUnderstandSetDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersMustUnderstandSetDirective(BaseModel): """Set the directive.""" operation: Literal["set", "remove"] @@ -553,7 +878,7 @@ class RuleSetCacheControlRuleActionParametersMustUnderstandSetDirective(BaseMode """Whether the directive should only be applied to the Cloudflare CDN cache.""" -class RuleSetCacheControlRuleActionParametersMustUnderstandRemoveDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersMustUnderstandRemoveDirective(BaseModel): """Remove the directive.""" operation: Literal["set", "remove"] @@ -563,13 +888,13 @@ class RuleSetCacheControlRuleActionParametersMustUnderstandRemoveDirective(BaseM """Whether the directive should only be applied to the Cloudflare CDN cache.""" -RuleSetCacheControlRuleActionParametersMustUnderstand: TypeAlias = Union[ - RuleSetCacheControlRuleActionParametersMustUnderstandSetDirective, - RuleSetCacheControlRuleActionParametersMustUnderstandRemoveDirective, +UnionMember0RuleSetCacheControlRuleActionParametersMustUnderstand: TypeAlias = Union[ + UnionMember0RuleSetCacheControlRuleActionParametersMustUnderstandSetDirective, + UnionMember0RuleSetCacheControlRuleActionParametersMustUnderstandRemoveDirective, ] -class RuleSetCacheControlRuleActionParametersNoCacheSetDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersNoCacheSetDirective(BaseModel): """Set the directive with optional qualifiers.""" operation: Literal["set", "remove"] @@ -585,7 +910,7 @@ class RuleSetCacheControlRuleActionParametersNoCacheSetDirective(BaseModel): """ -class RuleSetCacheControlRuleActionParametersNoCacheRemoveDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersNoCacheRemoveDirective(BaseModel): """Remove the directive.""" operation: Literal["set", "remove"] @@ -595,13 +920,13 @@ class RuleSetCacheControlRuleActionParametersNoCacheRemoveDirective(BaseModel): """Whether the directive should only be applied to the Cloudflare CDN cache.""" -RuleSetCacheControlRuleActionParametersNoCache: TypeAlias = Union[ - RuleSetCacheControlRuleActionParametersNoCacheSetDirective, - RuleSetCacheControlRuleActionParametersNoCacheRemoveDirective, +UnionMember0RuleSetCacheControlRuleActionParametersNoCache: TypeAlias = Union[ + UnionMember0RuleSetCacheControlRuleActionParametersNoCacheSetDirective, + UnionMember0RuleSetCacheControlRuleActionParametersNoCacheRemoveDirective, ] -class RuleSetCacheControlRuleActionParametersNoStoreSetDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersNoStoreSetDirective(BaseModel): """Set the directive.""" operation: Literal["set", "remove"] @@ -611,7 +936,7 @@ class RuleSetCacheControlRuleActionParametersNoStoreSetDirective(BaseModel): """Whether the directive should only be applied to the Cloudflare CDN cache.""" -class RuleSetCacheControlRuleActionParametersNoStoreRemoveDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersNoStoreRemoveDirective(BaseModel): """Remove the directive.""" operation: Literal["set", "remove"] @@ -621,13 +946,13 @@ class RuleSetCacheControlRuleActionParametersNoStoreRemoveDirective(BaseModel): """Whether the directive should only be applied to the Cloudflare CDN cache.""" -RuleSetCacheControlRuleActionParametersNoStore: TypeAlias = Union[ - RuleSetCacheControlRuleActionParametersNoStoreSetDirective, - RuleSetCacheControlRuleActionParametersNoStoreRemoveDirective, +UnionMember0RuleSetCacheControlRuleActionParametersNoStore: TypeAlias = Union[ + UnionMember0RuleSetCacheControlRuleActionParametersNoStoreSetDirective, + UnionMember0RuleSetCacheControlRuleActionParametersNoStoreRemoveDirective, ] -class RuleSetCacheControlRuleActionParametersNoTransformSetDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersNoTransformSetDirective(BaseModel): """Set the directive.""" operation: Literal["set", "remove"] @@ -637,7 +962,7 @@ class RuleSetCacheControlRuleActionParametersNoTransformSetDirective(BaseModel): """Whether the directive should only be applied to the Cloudflare CDN cache.""" -class RuleSetCacheControlRuleActionParametersNoTransformRemoveDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersNoTransformRemoveDirective(BaseModel): """Remove the directive.""" operation: Literal["set", "remove"] @@ -647,13 +972,13 @@ class RuleSetCacheControlRuleActionParametersNoTransformRemoveDirective(BaseMode """Whether the directive should only be applied to the Cloudflare CDN cache.""" -RuleSetCacheControlRuleActionParametersNoTransform: TypeAlias = Union[ - RuleSetCacheControlRuleActionParametersNoTransformSetDirective, - RuleSetCacheControlRuleActionParametersNoTransformRemoveDirective, +UnionMember0RuleSetCacheControlRuleActionParametersNoTransform: TypeAlias = Union[ + UnionMember0RuleSetCacheControlRuleActionParametersNoTransformSetDirective, + UnionMember0RuleSetCacheControlRuleActionParametersNoTransformRemoveDirective, ] -class RuleSetCacheControlRuleActionParametersPrivateSetDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersPrivateSetDirective(BaseModel): """Set the directive with optional qualifiers.""" operation: Literal["set", "remove"] @@ -669,7 +994,7 @@ class RuleSetCacheControlRuleActionParametersPrivateSetDirective(BaseModel): """ -class RuleSetCacheControlRuleActionParametersPrivateRemoveDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersPrivateRemoveDirective(BaseModel): """Remove the directive.""" operation: Literal["set", "remove"] @@ -679,13 +1004,13 @@ class RuleSetCacheControlRuleActionParametersPrivateRemoveDirective(BaseModel): """Whether the directive should only be applied to the Cloudflare CDN cache.""" -RuleSetCacheControlRuleActionParametersPrivate: TypeAlias = Union[ - RuleSetCacheControlRuleActionParametersPrivateSetDirective, - RuleSetCacheControlRuleActionParametersPrivateRemoveDirective, +UnionMember0RuleSetCacheControlRuleActionParametersPrivate: TypeAlias = Union[ + UnionMember0RuleSetCacheControlRuleActionParametersPrivateSetDirective, + UnionMember0RuleSetCacheControlRuleActionParametersPrivateRemoveDirective, ] -class RuleSetCacheControlRuleActionParametersProxyRevalidateSetDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersProxyRevalidateSetDirective(BaseModel): """Set the directive.""" operation: Literal["set", "remove"] @@ -695,7 +1020,7 @@ class RuleSetCacheControlRuleActionParametersProxyRevalidateSetDirective(BaseMod """Whether the directive should only be applied to the Cloudflare CDN cache.""" -class RuleSetCacheControlRuleActionParametersProxyRevalidateRemoveDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersProxyRevalidateRemoveDirective(BaseModel): """Remove the directive.""" operation: Literal["set", "remove"] @@ -705,13 +1030,13 @@ class RuleSetCacheControlRuleActionParametersProxyRevalidateRemoveDirective(Base """Whether the directive should only be applied to the Cloudflare CDN cache.""" -RuleSetCacheControlRuleActionParametersProxyRevalidate: TypeAlias = Union[ - RuleSetCacheControlRuleActionParametersProxyRevalidateSetDirective, - RuleSetCacheControlRuleActionParametersProxyRevalidateRemoveDirective, +UnionMember0RuleSetCacheControlRuleActionParametersProxyRevalidate: TypeAlias = Union[ + UnionMember0RuleSetCacheControlRuleActionParametersProxyRevalidateSetDirective, + UnionMember0RuleSetCacheControlRuleActionParametersProxyRevalidateRemoveDirective, ] -class RuleSetCacheControlRuleActionParametersPublicSetDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersPublicSetDirective(BaseModel): """Set the directive.""" operation: Literal["set", "remove"] @@ -721,7 +1046,7 @@ class RuleSetCacheControlRuleActionParametersPublicSetDirective(BaseModel): """Whether the directive should only be applied to the Cloudflare CDN cache.""" -class RuleSetCacheControlRuleActionParametersPublicRemoveDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersPublicRemoveDirective(BaseModel): """Remove the directive.""" operation: Literal["set", "remove"] @@ -731,13 +1056,13 @@ class RuleSetCacheControlRuleActionParametersPublicRemoveDirective(BaseModel): """Whether the directive should only be applied to the Cloudflare CDN cache.""" -RuleSetCacheControlRuleActionParametersPublic: TypeAlias = Union[ - RuleSetCacheControlRuleActionParametersPublicSetDirective, - RuleSetCacheControlRuleActionParametersPublicRemoveDirective, +UnionMember0RuleSetCacheControlRuleActionParametersPublic: TypeAlias = Union[ + UnionMember0RuleSetCacheControlRuleActionParametersPublicSetDirective, + UnionMember0RuleSetCacheControlRuleActionParametersPublicRemoveDirective, ] -class RuleSetCacheControlRuleActionParametersSMaxageSetDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersSMaxageSetDirective(BaseModel): """Set the directive with a duration value in seconds.""" operation: Literal["set", "remove"] @@ -750,7 +1075,7 @@ class RuleSetCacheControlRuleActionParametersSMaxageSetDirective(BaseModel): """Whether the directive should only be applied to the Cloudflare CDN cache.""" -class RuleSetCacheControlRuleActionParametersSMaxageRemoveDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersSMaxageRemoveDirective(BaseModel): """Remove the directive.""" operation: Literal["set", "remove"] @@ -760,13 +1085,13 @@ class RuleSetCacheControlRuleActionParametersSMaxageRemoveDirective(BaseModel): """Whether the directive should only be applied to the Cloudflare CDN cache.""" -RuleSetCacheControlRuleActionParametersSMaxage: TypeAlias = Union[ - RuleSetCacheControlRuleActionParametersSMaxageSetDirective, - RuleSetCacheControlRuleActionParametersSMaxageRemoveDirective, +UnionMember0RuleSetCacheControlRuleActionParametersSMaxage: TypeAlias = Union[ + UnionMember0RuleSetCacheControlRuleActionParametersSMaxageSetDirective, + UnionMember0RuleSetCacheControlRuleActionParametersSMaxageRemoveDirective, ] -class RuleSetCacheControlRuleActionParametersStaleIfErrorSetDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersStaleIfErrorSetDirective(BaseModel): """Set the directive with a duration value in seconds.""" operation: Literal["set", "remove"] @@ -779,7 +1104,7 @@ class RuleSetCacheControlRuleActionParametersStaleIfErrorSetDirective(BaseModel) """Whether the directive should only be applied to the Cloudflare CDN cache.""" -class RuleSetCacheControlRuleActionParametersStaleIfErrorRemoveDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersStaleIfErrorRemoveDirective(BaseModel): """Remove the directive.""" operation: Literal["set", "remove"] @@ -789,13 +1114,13 @@ class RuleSetCacheControlRuleActionParametersStaleIfErrorRemoveDirective(BaseMod """Whether the directive should only be applied to the Cloudflare CDN cache.""" -RuleSetCacheControlRuleActionParametersStaleIfError: TypeAlias = Union[ - RuleSetCacheControlRuleActionParametersStaleIfErrorSetDirective, - RuleSetCacheControlRuleActionParametersStaleIfErrorRemoveDirective, +UnionMember0RuleSetCacheControlRuleActionParametersStaleIfError: TypeAlias = Union[ + UnionMember0RuleSetCacheControlRuleActionParametersStaleIfErrorSetDirective, + UnionMember0RuleSetCacheControlRuleActionParametersStaleIfErrorRemoveDirective, ] -class RuleSetCacheControlRuleActionParametersStaleWhileRevalidateSetDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersStaleWhileRevalidateSetDirective(BaseModel): """Set the directive with a duration value in seconds.""" operation: Literal["set", "remove"] @@ -808,7 +1133,7 @@ class RuleSetCacheControlRuleActionParametersStaleWhileRevalidateSetDirective(Ba """Whether the directive should only be applied to the Cloudflare CDN cache.""" -class RuleSetCacheControlRuleActionParametersStaleWhileRevalidateRemoveDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersStaleWhileRevalidateRemoveDirective(BaseModel): """Remove the directive.""" operation: Literal["set", "remove"] @@ -818,69 +1143,77 @@ class RuleSetCacheControlRuleActionParametersStaleWhileRevalidateRemoveDirective """Whether the directive should only be applied to the Cloudflare CDN cache.""" -RuleSetCacheControlRuleActionParametersStaleWhileRevalidate: TypeAlias = Union[ - RuleSetCacheControlRuleActionParametersStaleWhileRevalidateSetDirective, - RuleSetCacheControlRuleActionParametersStaleWhileRevalidateRemoveDirective, +UnionMember0RuleSetCacheControlRuleActionParametersStaleWhileRevalidate: TypeAlias = Union[ + UnionMember0RuleSetCacheControlRuleActionParametersStaleWhileRevalidateSetDirective, + UnionMember0RuleSetCacheControlRuleActionParametersStaleWhileRevalidateRemoveDirective, ] -class RuleSetCacheControlRuleActionParameters(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParameters(BaseModel): """The parameters configuring the rule's action.""" - immutable: Optional[RuleSetCacheControlRuleActionParametersImmutable] = None + immutable: Optional[UnionMember0RuleSetCacheControlRuleActionParametersImmutable] = None """A cache-control directive configuration.""" - max_age: Optional[RuleSetCacheControlRuleActionParametersMaxAge] = FieldInfo(alias="max-age", default=None) + max_age: Optional[UnionMember0RuleSetCacheControlRuleActionParametersMaxAge] = FieldInfo( + alias="max-age", default=None + ) """ A cache-control directive configuration that accepts a duration value in seconds. """ - must_revalidate: Optional[RuleSetCacheControlRuleActionParametersMustRevalidate] = FieldInfo( + must_revalidate: Optional[UnionMember0RuleSetCacheControlRuleActionParametersMustRevalidate] = FieldInfo( alias="must-revalidate", default=None ) """A cache-control directive configuration.""" - must_understand: Optional[RuleSetCacheControlRuleActionParametersMustUnderstand] = FieldInfo( + must_understand: Optional[UnionMember0RuleSetCacheControlRuleActionParametersMustUnderstand] = FieldInfo( alias="must-understand", default=None ) """A cache-control directive configuration.""" - no_cache: Optional[RuleSetCacheControlRuleActionParametersNoCache] = FieldInfo(alias="no-cache", default=None) + no_cache: Optional[UnionMember0RuleSetCacheControlRuleActionParametersNoCache] = FieldInfo( + alias="no-cache", default=None + ) """ A cache-control directive configuration that accepts optional qualifiers (header names). """ - no_store: Optional[RuleSetCacheControlRuleActionParametersNoStore] = FieldInfo(alias="no-store", default=None) + no_store: Optional[UnionMember0RuleSetCacheControlRuleActionParametersNoStore] = FieldInfo( + alias="no-store", default=None + ) """A cache-control directive configuration.""" - no_transform: Optional[RuleSetCacheControlRuleActionParametersNoTransform] = FieldInfo( + no_transform: Optional[UnionMember0RuleSetCacheControlRuleActionParametersNoTransform] = FieldInfo( alias="no-transform", default=None ) """A cache-control directive configuration.""" - private: Optional[RuleSetCacheControlRuleActionParametersPrivate] = None + private: Optional[UnionMember0RuleSetCacheControlRuleActionParametersPrivate] = None """ A cache-control directive configuration that accepts optional qualifiers (header names). """ - proxy_revalidate: Optional[RuleSetCacheControlRuleActionParametersProxyRevalidate] = FieldInfo( + proxy_revalidate: Optional[UnionMember0RuleSetCacheControlRuleActionParametersProxyRevalidate] = FieldInfo( alias="proxy-revalidate", default=None ) """A cache-control directive configuration.""" - public: Optional[RuleSetCacheControlRuleActionParametersPublic] = None + public: Optional[UnionMember0RuleSetCacheControlRuleActionParametersPublic] = None """A cache-control directive configuration.""" - s_maxage: Optional[RuleSetCacheControlRuleActionParametersSMaxage] = FieldInfo(alias="s-maxage", default=None) + s_maxage: Optional[UnionMember0RuleSetCacheControlRuleActionParametersSMaxage] = FieldInfo( + alias="s-maxage", default=None + ) """ A cache-control directive configuration that accepts a duration value in seconds. """ - stale_if_error: Optional[RuleSetCacheControlRuleActionParametersStaleIfError] = FieldInfo( + stale_if_error: Optional[UnionMember0RuleSetCacheControlRuleActionParametersStaleIfError] = FieldInfo( alias="stale-if-error", default=None ) """ @@ -888,8 +1221,8 @@ class RuleSetCacheControlRuleActionParameters(BaseModel): seconds. """ - stale_while_revalidate: Optional[RuleSetCacheControlRuleActionParametersStaleWhileRevalidate] = FieldInfo( - alias="stale-while-revalidate", default=None + stale_while_revalidate: Optional[UnionMember0RuleSetCacheControlRuleActionParametersStaleWhileRevalidate] = ( + FieldInfo(alias="stale-while-revalidate", default=None) ) """ A cache-control directive configuration that accepts a duration value in @@ -897,7 +1230,7 @@ class RuleSetCacheControlRuleActionParameters(BaseModel): """ -class RuleSetCacheControlRuleExposedCredentialCheck(BaseModel): +class UnionMember0RuleSetCacheControlRuleExposedCredentialCheck(BaseModel): """Configuration for exposed credential checking.""" password_expression: str @@ -907,7 +1240,7 @@ class RuleSetCacheControlRuleExposedCredentialCheck(BaseModel): """An expression that selects the user ID used in the credentials check.""" -class RuleSetCacheControlRuleRatelimit(BaseModel): +class UnionMember0RuleSetCacheControlRuleRatelimit(BaseModel): """An object configuring the rule's rate limit behavior.""" characteristics: List[str] @@ -953,7 +1286,7 @@ class RuleSetCacheControlRuleRatelimit(BaseModel): """ -class RuleSetCacheControlRule(BaseModel): +class UnionMember0RuleSetCacheControlRule(BaseModel): id: str """The unique ID of the rule.""" @@ -974,7 +1307,7 @@ class RuleSetCacheControlRule(BaseModel): version: str """The version of the rule.""" - action_parameters: Optional[RuleSetCacheControlRuleActionParameters] = None + action_parameters: Optional[UnionMember0RuleSetCacheControlRuleActionParameters] = None """The parameters configuring the rule's action.""" categories: Optional[List[str]] = None @@ -983,17 +1316,17 @@ class RuleSetCacheControlRule(BaseModel): description: Optional[str] = None """An informative description of the rule.""" - exposed_credential_check: Optional[RuleSetCacheControlRuleExposedCredentialCheck] = None + exposed_credential_check: Optional[UnionMember0RuleSetCacheControlRuleExposedCredentialCheck] = None """Configuration for exposed credential checking.""" logging: Optional[Logging] = None """An object configuring the rule's logging behavior.""" - ratelimit: Optional[RuleSetCacheControlRuleRatelimit] = None + ratelimit: Optional[UnionMember0RuleSetCacheControlRuleRatelimit] = None """An object configuring the rule's rate limit behavior.""" -class RuleSetCacheSettingsRule(SetCacheSettingsRule): +class UnionMember0RuleSetCacheSettingsRule(SetCacheSettingsRule): id: str # type: ignore action: str # type: ignore @@ -1005,7 +1338,7 @@ class RuleSetCacheSettingsRule(SetCacheSettingsRule): ref: str # type: ignore -class RuleSetCacheTagsRuleActionParametersAddCacheTagsValues(BaseModel): +class UnionMember0RuleSetCacheTagsRuleActionParametersAddCacheTagsValues(BaseModel): """Add cache tags using a list of values.""" operation: Literal["add", "remove", "set"] @@ -1015,7 +1348,7 @@ class RuleSetCacheTagsRuleActionParametersAddCacheTagsValues(BaseModel): """A list of cache tag values.""" -class RuleSetCacheTagsRuleActionParametersAddCacheTagsExpression(BaseModel): +class UnionMember0RuleSetCacheTagsRuleActionParametersAddCacheTagsExpression(BaseModel): """Add cache tags using an expression.""" expression: str @@ -1025,7 +1358,7 @@ class RuleSetCacheTagsRuleActionParametersAddCacheTagsExpression(BaseModel): """The operation to perform on the cache tags.""" -class RuleSetCacheTagsRuleActionParametersRemoveCacheTagsValues(BaseModel): +class UnionMember0RuleSetCacheTagsRuleActionParametersRemoveCacheTagsValues(BaseModel): """Remove cache tags using a list of values.""" operation: Literal["add", "remove", "set"] @@ -1035,7 +1368,7 @@ class RuleSetCacheTagsRuleActionParametersRemoveCacheTagsValues(BaseModel): """A list of cache tag values.""" -class RuleSetCacheTagsRuleActionParametersRemoveCacheTagsExpression(BaseModel): +class UnionMember0RuleSetCacheTagsRuleActionParametersRemoveCacheTagsExpression(BaseModel): """Remove cache tags using an expression.""" expression: str @@ -1045,7 +1378,7 @@ class RuleSetCacheTagsRuleActionParametersRemoveCacheTagsExpression(BaseModel): """The operation to perform on the cache tags.""" -class RuleSetCacheTagsRuleActionParametersSetCacheTagsValues(BaseModel): +class UnionMember0RuleSetCacheTagsRuleActionParametersSetCacheTagsValues(BaseModel): """Set cache tags using a list of values.""" operation: Literal["add", "remove", "set"] @@ -1055,7 +1388,7 @@ class RuleSetCacheTagsRuleActionParametersSetCacheTagsValues(BaseModel): """A list of cache tag values.""" -class RuleSetCacheTagsRuleActionParametersSetCacheTagsExpression(BaseModel): +class UnionMember0RuleSetCacheTagsRuleActionParametersSetCacheTagsExpression(BaseModel): """Set cache tags using an expression.""" expression: str @@ -1065,17 +1398,17 @@ class RuleSetCacheTagsRuleActionParametersSetCacheTagsExpression(BaseModel): """The operation to perform on the cache tags.""" -RuleSetCacheTagsRuleActionParameters: TypeAlias = Union[ - RuleSetCacheTagsRuleActionParametersAddCacheTagsValues, - RuleSetCacheTagsRuleActionParametersAddCacheTagsExpression, - RuleSetCacheTagsRuleActionParametersRemoveCacheTagsValues, - RuleSetCacheTagsRuleActionParametersRemoveCacheTagsExpression, - RuleSetCacheTagsRuleActionParametersSetCacheTagsValues, - RuleSetCacheTagsRuleActionParametersSetCacheTagsExpression, +UnionMember0RuleSetCacheTagsRuleActionParameters: TypeAlias = Union[ + UnionMember0RuleSetCacheTagsRuleActionParametersAddCacheTagsValues, + UnionMember0RuleSetCacheTagsRuleActionParametersAddCacheTagsExpression, + UnionMember0RuleSetCacheTagsRuleActionParametersRemoveCacheTagsValues, + UnionMember0RuleSetCacheTagsRuleActionParametersRemoveCacheTagsExpression, + UnionMember0RuleSetCacheTagsRuleActionParametersSetCacheTagsValues, + UnionMember0RuleSetCacheTagsRuleActionParametersSetCacheTagsExpression, ] -class RuleSetCacheTagsRuleExposedCredentialCheck(BaseModel): +class UnionMember0RuleSetCacheTagsRuleExposedCredentialCheck(BaseModel): """Configuration for exposed credential checking.""" password_expression: str @@ -1085,7 +1418,7 @@ class RuleSetCacheTagsRuleExposedCredentialCheck(BaseModel): """An expression that selects the user ID used in the credentials check.""" -class RuleSetCacheTagsRuleRatelimit(BaseModel): +class UnionMember0RuleSetCacheTagsRuleRatelimit(BaseModel): """An object configuring the rule's rate limit behavior.""" characteristics: List[str] @@ -1131,7 +1464,7 @@ class RuleSetCacheTagsRuleRatelimit(BaseModel): """ -class RuleSetCacheTagsRule(BaseModel): +class UnionMember0RuleSetCacheTagsRule(BaseModel): id: str """The unique ID of the rule.""" @@ -1152,7 +1485,7 @@ class RuleSetCacheTagsRule(BaseModel): version: str """The version of the rule.""" - action_parameters: Optional[RuleSetCacheTagsRuleActionParameters] = None + action_parameters: Optional[UnionMember0RuleSetCacheTagsRuleActionParameters] = None """The parameters configuring the rule's action.""" categories: Optional[List[str]] = None @@ -1161,17 +1494,17 @@ class RuleSetCacheTagsRule(BaseModel): description: Optional[str] = None """An informative description of the rule.""" - exposed_credential_check: Optional[RuleSetCacheTagsRuleExposedCredentialCheck] = None + exposed_credential_check: Optional[UnionMember0RuleSetCacheTagsRuleExposedCredentialCheck] = None """Configuration for exposed credential checking.""" logging: Optional[Logging] = None """An object configuring the rule's logging behavior.""" - ratelimit: Optional[RuleSetCacheTagsRuleRatelimit] = None + ratelimit: Optional[UnionMember0RuleSetCacheTagsRuleRatelimit] = None """An object configuring the rule's rate limit behavior.""" -class RuleSetConfigurationRule(SetConfigRule): +class UnionMember0RuleSetConfigurationRule(SetConfigRule): id: str # type: ignore action: str # type: ignore @@ -1183,7 +1516,7 @@ class RuleSetConfigurationRule(SetConfigRule): ref: str # type: ignore -class RuleSkipRule(SkipRule): +class UnionMember0RuleSkipRule(SkipRule): id: str # type: ignore action: str # type: ignore @@ -1195,14 +1528,14 @@ class RuleSkipRule(SkipRule): ref: str # type: ignore -class RuleTransformResponseHTMLRuleActionParameters(BaseModel): +class UnionMember0RuleTransformResponseHTMLRuleActionParameters(BaseModel): """The parameters configuring the rule's action.""" link_maze: object """Enables the link maze transformation on the response.""" -class RuleTransformResponseHTMLRuleExposedCredentialCheck(BaseModel): +class UnionMember0RuleTransformResponseHTMLRuleExposedCredentialCheck(BaseModel): """Configuration for exposed credential checking.""" password_expression: str @@ -1212,7 +1545,7 @@ class RuleTransformResponseHTMLRuleExposedCredentialCheck(BaseModel): """An expression that selects the user ID used in the credentials check.""" -class RuleTransformResponseHTMLRuleRatelimit(BaseModel): +class UnionMember0RuleTransformResponseHTMLRuleRatelimit(BaseModel): """An object configuring the rule's rate limit behavior.""" characteristics: List[str] @@ -1258,7 +1591,7 @@ class RuleTransformResponseHTMLRuleRatelimit(BaseModel): """ -class RuleTransformResponseHTMLRule(BaseModel): +class UnionMember0RuleTransformResponseHTMLRule(BaseModel): id: str """The unique ID of the rule.""" @@ -1279,7 +1612,7 @@ class RuleTransformResponseHTMLRule(BaseModel): version: str """The version of the rule.""" - action_parameters: Optional[RuleTransformResponseHTMLRuleActionParameters] = None + action_parameters: Optional[UnionMember0RuleTransformResponseHTMLRuleActionParameters] = None """The parameters configuring the rule's action.""" categories: Optional[List[str]] = None @@ -1288,64 +1621,5045 @@ class RuleTransformResponseHTMLRule(BaseModel): description: Optional[str] = None """An informative description of the rule.""" - exposed_credential_check: Optional[RuleTransformResponseHTMLRuleExposedCredentialCheck] = None + exposed_credential_check: Optional[UnionMember0RuleTransformResponseHTMLRuleExposedCredentialCheck] = None """Configuration for exposed credential checking.""" logging: Optional[Logging] = None """An object configuring the rule's logging behavior.""" - ratelimit: Optional[RuleTransformResponseHTMLRuleRatelimit] = None + ratelimit: Optional[UnionMember0RuleTransformResponseHTMLRuleRatelimit] = None """An object configuring the rule's rate limit behavior.""" -Rule: TypeAlias = Union[ - RuleBlockRule, - RuleChallengeRule, - RuleResponseCompressionRule, - RuleDDoSDynamicRule, - RuleExecuteRule, - RuleForceConnectionCloseRule, - RuleJavaScriptChallengeRule, - RuleLogRule, - RuleLogCustomFieldRule, - RuleManagedChallengeRule, - RuleRedirectRule, - RuleRewriteRule, - RuleRouteRule, - RuleScoreRule, - RuleServeErrorRule, - RuleSetCacheControlRule, - RuleSetCacheSettingsRule, - RuleSetCacheTagsRule, - RuleSetConfigurationRule, - RuleSkipRule, - RuleTransformResponseHTMLRule, -] - - -class RulesetGetResponse(BaseModel): - """A ruleset object.""" +UnionMember0Rule: TypeAlias = Union[ + UnionMember0RuleBlockRule, + UnionMember0RuleChallengeRule, + UnionMember0RuleResponseCompressionRule, + UnionMember0RuleDDoSDynamicRule, + UnionMember0RuleExecuteRule, + UnionMember0RuleForceConnectionCloseRule, + UnionMember0RuleJavaScriptChallengeRule, + UnionMember0RuleLogRule, + UnionMember0RuleLogCustomFieldRule, + UnionMember0RuleManagedChallengeRule, + UnionMember0RuleRedirectRule, + UnionMember0RuleRewriteRule, + UnionMember0RuleRouteRule, + UnionMember0RuleScoreRule, + UnionMember0RuleServeErrorRule, + UnionMember0RuleSetCacheControlRule, + UnionMember0RuleSetCacheSettingsRule, + UnionMember0RuleSetCacheTagsRule, + UnionMember0RuleSetConfigurationRule, + UnionMember0RuleSkipRule, + UnionMember0RuleTransformResponseHTMLRule, +] - id: str + +class UnionMember0(BaseModel): + id: Optional[str] = None """The unique ID of the ruleset.""" - kind: Kind + description: Optional[str] = None + """An informative description of the ruleset.""" + + kind: Optional[Kind] = None """The kind of the ruleset.""" - last_updated: datetime + last_updated: Optional[datetime] = None """The timestamp of when the ruleset was last modified.""" - name: str + name: Optional[str] = None """The human-readable name of the ruleset.""" - phase: Phase + phase: Optional[Phase] = None """The phase of the ruleset.""" - rules: List[Rule] + rules: Optional[List[UnionMember0Rule]] = None """The list of rules in the ruleset.""" - version: str + version: Optional[str] = None """The version of the ruleset.""" + +class UnionMember1RuleBlockRule(BlockRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember1RuleChallengeRuleExposedCredentialCheck(BaseModel): + """Configuration for exposed credential checking.""" + + password_expression: str + """An expression that selects the password used in the credentials check.""" + + username_expression: str + """An expression that selects the user ID used in the credentials check.""" + + +class UnionMember1RuleChallengeRuleRatelimit(BaseModel): + """An object configuring the rule's rate limit behavior.""" + + characteristics: List[str] + """ + Characteristics of the request on which the rate limit counter will be + incremented. + """ + + period: int + """Period in seconds over which the counter is being incremented.""" + + counting_expression: Optional[str] = None + """An expression that defines when the rate limit counter should be incremented. + + It defaults to the same as the rule's expression. + """ + + mitigation_timeout: Optional[int] = None + """ + Period of time in seconds after which the action will be disabled following its + first execution. + """ + + requests_per_period: Optional[int] = None + """ + The threshold of requests per period after which the action will be executed for + the first time. + """ + + requests_to_origin: Optional[bool] = None + """Whether counting is only performed when an origin is reached.""" + + score_per_period: Optional[int] = None + """ + The score threshold per period for which the action will be executed the first + time. + """ + + score_response_header_name: Optional[str] = None + """ + A response header name provided by the origin, which contains the score to + increment rate limit counter with. + """ + + +class UnionMember1RuleChallengeRule(BaseModel): + id: str + """The unique ID of the rule.""" + + action: Literal["challenge"] + """The action to perform when the rule matches.""" + + enabled: bool + """Whether the rule should be executed.""" + + expression: str + """The expression defining which traffic will match the rule.""" + + last_updated: datetime + """The timestamp of when the rule was last modified.""" + + ref: str + """The reference of the rule (the rule's ID by default).""" + + version: str + """The version of the rule.""" + + action_parameters: Optional[object] = None + """The parameters configuring the rule's action.""" + + categories: Optional[List[str]] = None + """The categories of the rule.""" + description: Optional[str] = None - """An informative description of the ruleset.""" + """An informative description of the rule.""" + + exposed_credential_check: Optional[UnionMember1RuleChallengeRuleExposedCredentialCheck] = None + """Configuration for exposed credential checking.""" + + logging: Optional[Logging] = None + """An object configuring the rule's logging behavior.""" + + ratelimit: Optional[UnionMember1RuleChallengeRuleRatelimit] = None + """An object configuring the rule's rate limit behavior.""" + + +class UnionMember1RuleResponseCompressionRule(CompressResponseRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember1RuleDDoSDynamicRule(DDoSDynamicRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember1RuleExecuteRule(ExecuteRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember1RuleForceConnectionCloseRule(ForceConnectionCloseRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember1RuleJavaScriptChallengeRuleExposedCredentialCheck(BaseModel): + """Configuration for exposed credential checking.""" + + password_expression: str + """An expression that selects the password used in the credentials check.""" + + username_expression: str + """An expression that selects the user ID used in the credentials check.""" + + +class UnionMember1RuleJavaScriptChallengeRuleRatelimit(BaseModel): + """An object configuring the rule's rate limit behavior.""" + + characteristics: List[str] + """ + Characteristics of the request on which the rate limit counter will be + incremented. + """ + + period: int + """Period in seconds over which the counter is being incremented.""" + + counting_expression: Optional[str] = None + """An expression that defines when the rate limit counter should be incremented. + + It defaults to the same as the rule's expression. + """ + + mitigation_timeout: Optional[int] = None + """ + Period of time in seconds after which the action will be disabled following its + first execution. + """ + + requests_per_period: Optional[int] = None + """ + The threshold of requests per period after which the action will be executed for + the first time. + """ + + requests_to_origin: Optional[bool] = None + """Whether counting is only performed when an origin is reached.""" + + score_per_period: Optional[int] = None + """ + The score threshold per period for which the action will be executed the first + time. + """ + + score_response_header_name: Optional[str] = None + """ + A response header name provided by the origin, which contains the score to + increment rate limit counter with. + """ + + +class UnionMember1RuleJavaScriptChallengeRule(BaseModel): + id: str + """The unique ID of the rule.""" + + action: Literal["js_challenge"] + """The action to perform when the rule matches.""" + + enabled: bool + """Whether the rule should be executed.""" + + expression: str + """The expression defining which traffic will match the rule.""" + + last_updated: datetime + """The timestamp of when the rule was last modified.""" + + ref: str + """The reference of the rule (the rule's ID by default).""" + + version: str + """The version of the rule.""" + + action_parameters: Optional[object] = None + """The parameters configuring the rule's action.""" + + categories: Optional[List[str]] = None + """The categories of the rule.""" + + description: Optional[str] = None + """An informative description of the rule.""" + + exposed_credential_check: Optional[UnionMember1RuleJavaScriptChallengeRuleExposedCredentialCheck] = None + """Configuration for exposed credential checking.""" + + logging: Optional[Logging] = None + """An object configuring the rule's logging behavior.""" + + ratelimit: Optional[UnionMember1RuleJavaScriptChallengeRuleRatelimit] = None + """An object configuring the rule's rate limit behavior.""" + + +class UnionMember1RuleLogRule(LogRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember1RuleLogCustomFieldRule(LogCustomFieldRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember1RuleManagedChallengeRule(ManagedChallengeRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember1RuleRedirectRule(RedirectRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember1RuleRewriteRule(RewriteRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember1RuleRouteRule(RouteRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember1RuleScoreRule(ScoreRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember1RuleServeErrorRule(ServeErrorRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember1RuleSetCacheControlRuleActionParametersImmutableSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember1RuleSetCacheControlRuleActionParametersImmutableRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember1RuleSetCacheControlRuleActionParametersImmutable: TypeAlias = Union[ + UnionMember1RuleSetCacheControlRuleActionParametersImmutableSetDirective, + UnionMember1RuleSetCacheControlRuleActionParametersImmutableRemoveDirective, +] + + +class UnionMember1RuleSetCacheControlRuleActionParametersMaxAgeSetDirective(BaseModel): + """Set the directive with a duration value in seconds.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + value: int + """The duration value in seconds for the directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember1RuleSetCacheControlRuleActionParametersMaxAgeRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember1RuleSetCacheControlRuleActionParametersMaxAge: TypeAlias = Union[ + UnionMember1RuleSetCacheControlRuleActionParametersMaxAgeSetDirective, + UnionMember1RuleSetCacheControlRuleActionParametersMaxAgeRemoveDirective, +] + + +class UnionMember1RuleSetCacheControlRuleActionParametersMustRevalidateSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember1RuleSetCacheControlRuleActionParametersMustRevalidateRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember1RuleSetCacheControlRuleActionParametersMustRevalidate: TypeAlias = Union[ + UnionMember1RuleSetCacheControlRuleActionParametersMustRevalidateSetDirective, + UnionMember1RuleSetCacheControlRuleActionParametersMustRevalidateRemoveDirective, +] + + +class UnionMember1RuleSetCacheControlRuleActionParametersMustUnderstandSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember1RuleSetCacheControlRuleActionParametersMustUnderstandRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember1RuleSetCacheControlRuleActionParametersMustUnderstand: TypeAlias = Union[ + UnionMember1RuleSetCacheControlRuleActionParametersMustUnderstandSetDirective, + UnionMember1RuleSetCacheControlRuleActionParametersMustUnderstandRemoveDirective, +] + + +class UnionMember1RuleSetCacheControlRuleActionParametersNoCacheSetDirective(BaseModel): + """Set the directive with optional qualifiers.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + qualifiers: Optional[List[str]] = None + """ + Optional list of header names to qualify the directive (e.g., for "private" or + "no-cache" directives). + """ + + +class UnionMember1RuleSetCacheControlRuleActionParametersNoCacheRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember1RuleSetCacheControlRuleActionParametersNoCache: TypeAlias = Union[ + UnionMember1RuleSetCacheControlRuleActionParametersNoCacheSetDirective, + UnionMember1RuleSetCacheControlRuleActionParametersNoCacheRemoveDirective, +] + + +class UnionMember1RuleSetCacheControlRuleActionParametersNoStoreSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember1RuleSetCacheControlRuleActionParametersNoStoreRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember1RuleSetCacheControlRuleActionParametersNoStore: TypeAlias = Union[ + UnionMember1RuleSetCacheControlRuleActionParametersNoStoreSetDirective, + UnionMember1RuleSetCacheControlRuleActionParametersNoStoreRemoveDirective, +] + + +class UnionMember1RuleSetCacheControlRuleActionParametersNoTransformSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember1RuleSetCacheControlRuleActionParametersNoTransformRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember1RuleSetCacheControlRuleActionParametersNoTransform: TypeAlias = Union[ + UnionMember1RuleSetCacheControlRuleActionParametersNoTransformSetDirective, + UnionMember1RuleSetCacheControlRuleActionParametersNoTransformRemoveDirective, +] + + +class UnionMember1RuleSetCacheControlRuleActionParametersPrivateSetDirective(BaseModel): + """Set the directive with optional qualifiers.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + qualifiers: Optional[List[str]] = None + """ + Optional list of header names to qualify the directive (e.g., for "private" or + "no-cache" directives). + """ + + +class UnionMember1RuleSetCacheControlRuleActionParametersPrivateRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember1RuleSetCacheControlRuleActionParametersPrivate: TypeAlias = Union[ + UnionMember1RuleSetCacheControlRuleActionParametersPrivateSetDirective, + UnionMember1RuleSetCacheControlRuleActionParametersPrivateRemoveDirective, +] + + +class UnionMember1RuleSetCacheControlRuleActionParametersProxyRevalidateSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember1RuleSetCacheControlRuleActionParametersProxyRevalidateRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember1RuleSetCacheControlRuleActionParametersProxyRevalidate: TypeAlias = Union[ + UnionMember1RuleSetCacheControlRuleActionParametersProxyRevalidateSetDirective, + UnionMember1RuleSetCacheControlRuleActionParametersProxyRevalidateRemoveDirective, +] + + +class UnionMember1RuleSetCacheControlRuleActionParametersPublicSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember1RuleSetCacheControlRuleActionParametersPublicRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember1RuleSetCacheControlRuleActionParametersPublic: TypeAlias = Union[ + UnionMember1RuleSetCacheControlRuleActionParametersPublicSetDirective, + UnionMember1RuleSetCacheControlRuleActionParametersPublicRemoveDirective, +] + + +class UnionMember1RuleSetCacheControlRuleActionParametersSMaxageSetDirective(BaseModel): + """Set the directive with a duration value in seconds.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + value: int + """The duration value in seconds for the directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember1RuleSetCacheControlRuleActionParametersSMaxageRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember1RuleSetCacheControlRuleActionParametersSMaxage: TypeAlias = Union[ + UnionMember1RuleSetCacheControlRuleActionParametersSMaxageSetDirective, + UnionMember1RuleSetCacheControlRuleActionParametersSMaxageRemoveDirective, +] + + +class UnionMember1RuleSetCacheControlRuleActionParametersStaleIfErrorSetDirective(BaseModel): + """Set the directive with a duration value in seconds.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + value: int + """The duration value in seconds for the directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember1RuleSetCacheControlRuleActionParametersStaleIfErrorRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember1RuleSetCacheControlRuleActionParametersStaleIfError: TypeAlias = Union[ + UnionMember1RuleSetCacheControlRuleActionParametersStaleIfErrorSetDirective, + UnionMember1RuleSetCacheControlRuleActionParametersStaleIfErrorRemoveDirective, +] + + +class UnionMember1RuleSetCacheControlRuleActionParametersStaleWhileRevalidateSetDirective(BaseModel): + """Set the directive with a duration value in seconds.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + value: int + """The duration value in seconds for the directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember1RuleSetCacheControlRuleActionParametersStaleWhileRevalidateRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember1RuleSetCacheControlRuleActionParametersStaleWhileRevalidate: TypeAlias = Union[ + UnionMember1RuleSetCacheControlRuleActionParametersStaleWhileRevalidateSetDirective, + UnionMember1RuleSetCacheControlRuleActionParametersStaleWhileRevalidateRemoveDirective, +] + + +class UnionMember1RuleSetCacheControlRuleActionParameters(BaseModel): + """The parameters configuring the rule's action.""" + + immutable: Optional[UnionMember1RuleSetCacheControlRuleActionParametersImmutable] = None + """A cache-control directive configuration.""" + + max_age: Optional[UnionMember1RuleSetCacheControlRuleActionParametersMaxAge] = FieldInfo( + alias="max-age", default=None + ) + """ + A cache-control directive configuration that accepts a duration value in + seconds. + """ + + must_revalidate: Optional[UnionMember1RuleSetCacheControlRuleActionParametersMustRevalidate] = FieldInfo( + alias="must-revalidate", default=None + ) + """A cache-control directive configuration.""" + + must_understand: Optional[UnionMember1RuleSetCacheControlRuleActionParametersMustUnderstand] = FieldInfo( + alias="must-understand", default=None + ) + """A cache-control directive configuration.""" + + no_cache: Optional[UnionMember1RuleSetCacheControlRuleActionParametersNoCache] = FieldInfo( + alias="no-cache", default=None + ) + """ + A cache-control directive configuration that accepts optional qualifiers (header + names). + """ + + no_store: Optional[UnionMember1RuleSetCacheControlRuleActionParametersNoStore] = FieldInfo( + alias="no-store", default=None + ) + """A cache-control directive configuration.""" + + no_transform: Optional[UnionMember1RuleSetCacheControlRuleActionParametersNoTransform] = FieldInfo( + alias="no-transform", default=None + ) + """A cache-control directive configuration.""" + + private: Optional[UnionMember1RuleSetCacheControlRuleActionParametersPrivate] = None + """ + A cache-control directive configuration that accepts optional qualifiers (header + names). + """ + + proxy_revalidate: Optional[UnionMember1RuleSetCacheControlRuleActionParametersProxyRevalidate] = FieldInfo( + alias="proxy-revalidate", default=None + ) + """A cache-control directive configuration.""" + + public: Optional[UnionMember1RuleSetCacheControlRuleActionParametersPublic] = None + """A cache-control directive configuration.""" + + s_maxage: Optional[UnionMember1RuleSetCacheControlRuleActionParametersSMaxage] = FieldInfo( + alias="s-maxage", default=None + ) + """ + A cache-control directive configuration that accepts a duration value in + seconds. + """ + + stale_if_error: Optional[UnionMember1RuleSetCacheControlRuleActionParametersStaleIfError] = FieldInfo( + alias="stale-if-error", default=None + ) + """ + A cache-control directive configuration that accepts a duration value in + seconds. + """ + + stale_while_revalidate: Optional[UnionMember1RuleSetCacheControlRuleActionParametersStaleWhileRevalidate] = ( + FieldInfo(alias="stale-while-revalidate", default=None) + ) + """ + A cache-control directive configuration that accepts a duration value in + seconds. + """ + + +class UnionMember1RuleSetCacheControlRuleExposedCredentialCheck(BaseModel): + """Configuration for exposed credential checking.""" + + password_expression: str + """An expression that selects the password used in the credentials check.""" + + username_expression: str + """An expression that selects the user ID used in the credentials check.""" + + +class UnionMember1RuleSetCacheControlRuleRatelimit(BaseModel): + """An object configuring the rule's rate limit behavior.""" + + characteristics: List[str] + """ + Characteristics of the request on which the rate limit counter will be + incremented. + """ + + period: int + """Period in seconds over which the counter is being incremented.""" + + counting_expression: Optional[str] = None + """An expression that defines when the rate limit counter should be incremented. + + It defaults to the same as the rule's expression. + """ + + mitigation_timeout: Optional[int] = None + """ + Period of time in seconds after which the action will be disabled following its + first execution. + """ + + requests_per_period: Optional[int] = None + """ + The threshold of requests per period after which the action will be executed for + the first time. + """ + + requests_to_origin: Optional[bool] = None + """Whether counting is only performed when an origin is reached.""" + + score_per_period: Optional[int] = None + """ + The score threshold per period for which the action will be executed the first + time. + """ + + score_response_header_name: Optional[str] = None + """ + A response header name provided by the origin, which contains the score to + increment rate limit counter with. + """ + + +class UnionMember1RuleSetCacheControlRule(BaseModel): + id: str + """The unique ID of the rule.""" + + action: Literal["set_cache_control"] + """The action to perform when the rule matches.""" + + enabled: bool + + expression: str + """The expression defining which traffic will match the rule.""" + + last_updated: datetime + """The timestamp of when the rule was last modified.""" + + ref: str + """The reference of the rule (the rule's ID by default).""" + + version: str + """The version of the rule.""" + + action_parameters: Optional[UnionMember1RuleSetCacheControlRuleActionParameters] = None + """The parameters configuring the rule's action.""" + + categories: Optional[List[str]] = None + """The categories of the rule.""" + + description: Optional[str] = None + """An informative description of the rule.""" + + exposed_credential_check: Optional[UnionMember1RuleSetCacheControlRuleExposedCredentialCheck] = None + """Configuration for exposed credential checking.""" + + logging: Optional[Logging] = None + """An object configuring the rule's logging behavior.""" + + ratelimit: Optional[UnionMember1RuleSetCacheControlRuleRatelimit] = None + """An object configuring the rule's rate limit behavior.""" + + +class UnionMember1RuleSetCacheSettingsRule(SetCacheSettingsRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember1RuleSetCacheTagsRuleActionParametersAddCacheTagsValues(BaseModel): + """Add cache tags using a list of values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + values: List[str] + """A list of cache tag values.""" + + +class UnionMember1RuleSetCacheTagsRuleActionParametersAddCacheTagsExpression(BaseModel): + """Add cache tags using an expression.""" + + expression: str + """An expression that evaluates to an array of cache tag values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + +class UnionMember1RuleSetCacheTagsRuleActionParametersRemoveCacheTagsValues(BaseModel): + """Remove cache tags using a list of values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + values: List[str] + """A list of cache tag values.""" + + +class UnionMember1RuleSetCacheTagsRuleActionParametersRemoveCacheTagsExpression(BaseModel): + """Remove cache tags using an expression.""" + + expression: str + """An expression that evaluates to an array of cache tag values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + +class UnionMember1RuleSetCacheTagsRuleActionParametersSetCacheTagsValues(BaseModel): + """Set cache tags using a list of values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + values: List[str] + """A list of cache tag values.""" + + +class UnionMember1RuleSetCacheTagsRuleActionParametersSetCacheTagsExpression(BaseModel): + """Set cache tags using an expression.""" + + expression: str + """An expression that evaluates to an array of cache tag values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + +UnionMember1RuleSetCacheTagsRuleActionParameters: TypeAlias = Union[ + UnionMember1RuleSetCacheTagsRuleActionParametersAddCacheTagsValues, + UnionMember1RuleSetCacheTagsRuleActionParametersAddCacheTagsExpression, + UnionMember1RuleSetCacheTagsRuleActionParametersRemoveCacheTagsValues, + UnionMember1RuleSetCacheTagsRuleActionParametersRemoveCacheTagsExpression, + UnionMember1RuleSetCacheTagsRuleActionParametersSetCacheTagsValues, + UnionMember1RuleSetCacheTagsRuleActionParametersSetCacheTagsExpression, +] + + +class UnionMember1RuleSetCacheTagsRuleExposedCredentialCheck(BaseModel): + """Configuration for exposed credential checking.""" + + password_expression: str + """An expression that selects the password used in the credentials check.""" + + username_expression: str + """An expression that selects the user ID used in the credentials check.""" + + +class UnionMember1RuleSetCacheTagsRuleRatelimit(BaseModel): + """An object configuring the rule's rate limit behavior.""" + + characteristics: List[str] + """ + Characteristics of the request on which the rate limit counter will be + incremented. + """ + + period: int + """Period in seconds over which the counter is being incremented.""" + + counting_expression: Optional[str] = None + """An expression that defines when the rate limit counter should be incremented. + + It defaults to the same as the rule's expression. + """ + + mitigation_timeout: Optional[int] = None + """ + Period of time in seconds after which the action will be disabled following its + first execution. + """ + + requests_per_period: Optional[int] = None + """ + The threshold of requests per period after which the action will be executed for + the first time. + """ + + requests_to_origin: Optional[bool] = None + """Whether counting is only performed when an origin is reached.""" + + score_per_period: Optional[int] = None + """ + The score threshold per period for which the action will be executed the first + time. + """ + + score_response_header_name: Optional[str] = None + """ + A response header name provided by the origin, which contains the score to + increment rate limit counter with. + """ + + +class UnionMember1RuleSetCacheTagsRule(BaseModel): + id: str + """The unique ID of the rule.""" + + action: Literal["set_cache_tags"] + """The action to perform when the rule matches.""" + + enabled: bool + + expression: str + """The expression defining which traffic will match the rule.""" + + last_updated: datetime + """The timestamp of when the rule was last modified.""" + + ref: str + """The reference of the rule (the rule's ID by default).""" + + version: str + """The version of the rule.""" + + action_parameters: Optional[UnionMember1RuleSetCacheTagsRuleActionParameters] = None + """The parameters configuring the rule's action.""" + + categories: Optional[List[str]] = None + """The categories of the rule.""" + + description: Optional[str] = None + """An informative description of the rule.""" + + exposed_credential_check: Optional[UnionMember1RuleSetCacheTagsRuleExposedCredentialCheck] = None + """Configuration for exposed credential checking.""" + + logging: Optional[Logging] = None + """An object configuring the rule's logging behavior.""" + + ratelimit: Optional[UnionMember1RuleSetCacheTagsRuleRatelimit] = None + """An object configuring the rule's rate limit behavior.""" + + +class UnionMember1RuleSetConfigurationRule(SetConfigRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember1RuleSkipRule(SkipRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember1RuleTransformResponseHTMLRuleActionParameters(BaseModel): + """The parameters configuring the rule's action.""" + + link_maze: object + """Enables the link maze transformation on the response.""" + + +class UnionMember1RuleTransformResponseHTMLRuleExposedCredentialCheck(BaseModel): + """Configuration for exposed credential checking.""" + + password_expression: str + """An expression that selects the password used in the credentials check.""" + + username_expression: str + """An expression that selects the user ID used in the credentials check.""" + + +class UnionMember1RuleTransformResponseHTMLRuleRatelimit(BaseModel): + """An object configuring the rule's rate limit behavior.""" + + characteristics: List[str] + """ + Characteristics of the request on which the rate limit counter will be + incremented. + """ + + period: int + """Period in seconds over which the counter is being incremented.""" + + counting_expression: Optional[str] = None + """An expression that defines when the rate limit counter should be incremented. + + It defaults to the same as the rule's expression. + """ + + mitigation_timeout: Optional[int] = None + """ + Period of time in seconds after which the action will be disabled following its + first execution. + """ + + requests_per_period: Optional[int] = None + """ + The threshold of requests per period after which the action will be executed for + the first time. + """ + + requests_to_origin: Optional[bool] = None + """Whether counting is only performed when an origin is reached.""" + + score_per_period: Optional[int] = None + """ + The score threshold per period for which the action will be executed the first + time. + """ + + score_response_header_name: Optional[str] = None + """ + A response header name provided by the origin, which contains the score to + increment rate limit counter with. + """ + + +class UnionMember1RuleTransformResponseHTMLRule(BaseModel): + id: str + """The unique ID of the rule.""" + + action: Literal["transform_response_html"] + """The action to perform when the rule matches.""" + + enabled: bool + + expression: str + """The expression defining which traffic will match the rule.""" + + last_updated: datetime + """The timestamp of when the rule was last modified.""" + + ref: str + """The reference of the rule (the rule's ID by default).""" + + version: str + """The version of the rule.""" + + action_parameters: Optional[UnionMember1RuleTransformResponseHTMLRuleActionParameters] = None + """The parameters configuring the rule's action.""" + + categories: Optional[List[str]] = None + """The categories of the rule.""" + + description: Optional[str] = None + """An informative description of the rule.""" + + exposed_credential_check: Optional[UnionMember1RuleTransformResponseHTMLRuleExposedCredentialCheck] = None + """Configuration for exposed credential checking.""" + + logging: Optional[Logging] = None + """An object configuring the rule's logging behavior.""" + + ratelimit: Optional[UnionMember1RuleTransformResponseHTMLRuleRatelimit] = None + """An object configuring the rule's rate limit behavior.""" + + +UnionMember1Rule: TypeAlias = Union[ + UnionMember1RuleBlockRule, + UnionMember1RuleChallengeRule, + UnionMember1RuleResponseCompressionRule, + UnionMember1RuleDDoSDynamicRule, + UnionMember1RuleExecuteRule, + UnionMember1RuleForceConnectionCloseRule, + UnionMember1RuleJavaScriptChallengeRule, + UnionMember1RuleLogRule, + UnionMember1RuleLogCustomFieldRule, + UnionMember1RuleManagedChallengeRule, + UnionMember1RuleRedirectRule, + UnionMember1RuleRewriteRule, + UnionMember1RuleRouteRule, + UnionMember1RuleScoreRule, + UnionMember1RuleServeErrorRule, + UnionMember1RuleSetCacheControlRule, + UnionMember1RuleSetCacheSettingsRule, + UnionMember1RuleSetCacheTagsRule, + UnionMember1RuleSetConfigurationRule, + UnionMember1RuleSkipRule, + UnionMember1RuleTransformResponseHTMLRule, +] + + +class UnionMember1(BaseModel): + id: Optional[str] = None + """The unique ID of the ruleset.""" + + description: Optional[str] = None + """An informative description of the ruleset.""" + + kind: Optional[Kind] = None + """The kind of the ruleset.""" + + last_updated: Optional[datetime] = None + """The timestamp of when the ruleset was last modified.""" + + name: Optional[str] = None + """The human-readable name of the ruleset.""" + + phase: Optional[Phase] = None + """The phase of the ruleset.""" + + rules: Optional[List[UnionMember1Rule]] = None + """The list of rules in the ruleset.""" + + version: Optional[str] = None + """The version of the ruleset.""" + + +class UnionMember2RuleBlockRule(BlockRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember2RuleChallengeRuleExposedCredentialCheck(BaseModel): + """Configuration for exposed credential checking.""" + + password_expression: str + """An expression that selects the password used in the credentials check.""" + + username_expression: str + """An expression that selects the user ID used in the credentials check.""" + + +class UnionMember2RuleChallengeRuleRatelimit(BaseModel): + """An object configuring the rule's rate limit behavior.""" + + characteristics: List[str] + """ + Characteristics of the request on which the rate limit counter will be + incremented. + """ + + period: int + """Period in seconds over which the counter is being incremented.""" + + counting_expression: Optional[str] = None + """An expression that defines when the rate limit counter should be incremented. + + It defaults to the same as the rule's expression. + """ + + mitigation_timeout: Optional[int] = None + """ + Period of time in seconds after which the action will be disabled following its + first execution. + """ + + requests_per_period: Optional[int] = None + """ + The threshold of requests per period after which the action will be executed for + the first time. + """ + + requests_to_origin: Optional[bool] = None + """Whether counting is only performed when an origin is reached.""" + + score_per_period: Optional[int] = None + """ + The score threshold per period for which the action will be executed the first + time. + """ + + score_response_header_name: Optional[str] = None + """ + A response header name provided by the origin, which contains the score to + increment rate limit counter with. + """ + + +class UnionMember2RuleChallengeRule(BaseModel): + id: str + """The unique ID of the rule.""" + + action: Literal["challenge"] + """The action to perform when the rule matches.""" + + enabled: bool + """Whether the rule should be executed.""" + + expression: str + """The expression defining which traffic will match the rule.""" + + last_updated: datetime + """The timestamp of when the rule was last modified.""" + + ref: str + """The reference of the rule (the rule's ID by default).""" + + version: str + """The version of the rule.""" + + action_parameters: Optional[object] = None + """The parameters configuring the rule's action.""" + + categories: Optional[List[str]] = None + """The categories of the rule.""" + + description: Optional[str] = None + """An informative description of the rule.""" + + exposed_credential_check: Optional[UnionMember2RuleChallengeRuleExposedCredentialCheck] = None + """Configuration for exposed credential checking.""" + + logging: Optional[Logging] = None + """An object configuring the rule's logging behavior.""" + + ratelimit: Optional[UnionMember2RuleChallengeRuleRatelimit] = None + """An object configuring the rule's rate limit behavior.""" + + +class UnionMember2RuleResponseCompressionRule(CompressResponseRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember2RuleDDoSDynamicRule(DDoSDynamicRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember2RuleExecuteRule(ExecuteRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember2RuleForceConnectionCloseRule(ForceConnectionCloseRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember2RuleJavaScriptChallengeRuleExposedCredentialCheck(BaseModel): + """Configuration for exposed credential checking.""" + + password_expression: str + """An expression that selects the password used in the credentials check.""" + + username_expression: str + """An expression that selects the user ID used in the credentials check.""" + + +class UnionMember2RuleJavaScriptChallengeRuleRatelimit(BaseModel): + """An object configuring the rule's rate limit behavior.""" + + characteristics: List[str] + """ + Characteristics of the request on which the rate limit counter will be + incremented. + """ + + period: int + """Period in seconds over which the counter is being incremented.""" + + counting_expression: Optional[str] = None + """An expression that defines when the rate limit counter should be incremented. + + It defaults to the same as the rule's expression. + """ + + mitigation_timeout: Optional[int] = None + """ + Period of time in seconds after which the action will be disabled following its + first execution. + """ + + requests_per_period: Optional[int] = None + """ + The threshold of requests per period after which the action will be executed for + the first time. + """ + + requests_to_origin: Optional[bool] = None + """Whether counting is only performed when an origin is reached.""" + + score_per_period: Optional[int] = None + """ + The score threshold per period for which the action will be executed the first + time. + """ + + score_response_header_name: Optional[str] = None + """ + A response header name provided by the origin, which contains the score to + increment rate limit counter with. + """ + + +class UnionMember2RuleJavaScriptChallengeRule(BaseModel): + id: str + """The unique ID of the rule.""" + + action: Literal["js_challenge"] + """The action to perform when the rule matches.""" + + enabled: bool + """Whether the rule should be executed.""" + + expression: str + """The expression defining which traffic will match the rule.""" + + last_updated: datetime + """The timestamp of when the rule was last modified.""" + + ref: str + """The reference of the rule (the rule's ID by default).""" + + version: str + """The version of the rule.""" + + action_parameters: Optional[object] = None + """The parameters configuring the rule's action.""" + + categories: Optional[List[str]] = None + """The categories of the rule.""" + + description: Optional[str] = None + """An informative description of the rule.""" + + exposed_credential_check: Optional[UnionMember2RuleJavaScriptChallengeRuleExposedCredentialCheck] = None + """Configuration for exposed credential checking.""" + + logging: Optional[Logging] = None + """An object configuring the rule's logging behavior.""" + + ratelimit: Optional[UnionMember2RuleJavaScriptChallengeRuleRatelimit] = None + """An object configuring the rule's rate limit behavior.""" + + +class UnionMember2RuleLogRule(LogRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember2RuleLogCustomFieldRule(LogCustomFieldRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember2RuleManagedChallengeRule(ManagedChallengeRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember2RuleRedirectRule(RedirectRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember2RuleRewriteRule(RewriteRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember2RuleRouteRule(RouteRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember2RuleScoreRule(ScoreRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember2RuleServeErrorRule(ServeErrorRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember2RuleSetCacheControlRuleActionParametersImmutableSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember2RuleSetCacheControlRuleActionParametersImmutableRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember2RuleSetCacheControlRuleActionParametersImmutable: TypeAlias = Union[ + UnionMember2RuleSetCacheControlRuleActionParametersImmutableSetDirective, + UnionMember2RuleSetCacheControlRuleActionParametersImmutableRemoveDirective, +] + + +class UnionMember2RuleSetCacheControlRuleActionParametersMaxAgeSetDirective(BaseModel): + """Set the directive with a duration value in seconds.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + value: int + """The duration value in seconds for the directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember2RuleSetCacheControlRuleActionParametersMaxAgeRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember2RuleSetCacheControlRuleActionParametersMaxAge: TypeAlias = Union[ + UnionMember2RuleSetCacheControlRuleActionParametersMaxAgeSetDirective, + UnionMember2RuleSetCacheControlRuleActionParametersMaxAgeRemoveDirective, +] + + +class UnionMember2RuleSetCacheControlRuleActionParametersMustRevalidateSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember2RuleSetCacheControlRuleActionParametersMustRevalidateRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember2RuleSetCacheControlRuleActionParametersMustRevalidate: TypeAlias = Union[ + UnionMember2RuleSetCacheControlRuleActionParametersMustRevalidateSetDirective, + UnionMember2RuleSetCacheControlRuleActionParametersMustRevalidateRemoveDirective, +] + + +class UnionMember2RuleSetCacheControlRuleActionParametersMustUnderstandSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember2RuleSetCacheControlRuleActionParametersMustUnderstandRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember2RuleSetCacheControlRuleActionParametersMustUnderstand: TypeAlias = Union[ + UnionMember2RuleSetCacheControlRuleActionParametersMustUnderstandSetDirective, + UnionMember2RuleSetCacheControlRuleActionParametersMustUnderstandRemoveDirective, +] + + +class UnionMember2RuleSetCacheControlRuleActionParametersNoCacheSetDirective(BaseModel): + """Set the directive with optional qualifiers.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + qualifiers: Optional[List[str]] = None + """ + Optional list of header names to qualify the directive (e.g., for "private" or + "no-cache" directives). + """ + + +class UnionMember2RuleSetCacheControlRuleActionParametersNoCacheRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember2RuleSetCacheControlRuleActionParametersNoCache: TypeAlias = Union[ + UnionMember2RuleSetCacheControlRuleActionParametersNoCacheSetDirective, + UnionMember2RuleSetCacheControlRuleActionParametersNoCacheRemoveDirective, +] + + +class UnionMember2RuleSetCacheControlRuleActionParametersNoStoreSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember2RuleSetCacheControlRuleActionParametersNoStoreRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember2RuleSetCacheControlRuleActionParametersNoStore: TypeAlias = Union[ + UnionMember2RuleSetCacheControlRuleActionParametersNoStoreSetDirective, + UnionMember2RuleSetCacheControlRuleActionParametersNoStoreRemoveDirective, +] + + +class UnionMember2RuleSetCacheControlRuleActionParametersNoTransformSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember2RuleSetCacheControlRuleActionParametersNoTransformRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember2RuleSetCacheControlRuleActionParametersNoTransform: TypeAlias = Union[ + UnionMember2RuleSetCacheControlRuleActionParametersNoTransformSetDirective, + UnionMember2RuleSetCacheControlRuleActionParametersNoTransformRemoveDirective, +] + + +class UnionMember2RuleSetCacheControlRuleActionParametersPrivateSetDirective(BaseModel): + """Set the directive with optional qualifiers.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + qualifiers: Optional[List[str]] = None + """ + Optional list of header names to qualify the directive (e.g., for "private" or + "no-cache" directives). + """ + + +class UnionMember2RuleSetCacheControlRuleActionParametersPrivateRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember2RuleSetCacheControlRuleActionParametersPrivate: TypeAlias = Union[ + UnionMember2RuleSetCacheControlRuleActionParametersPrivateSetDirective, + UnionMember2RuleSetCacheControlRuleActionParametersPrivateRemoveDirective, +] + + +class UnionMember2RuleSetCacheControlRuleActionParametersProxyRevalidateSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember2RuleSetCacheControlRuleActionParametersProxyRevalidateRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember2RuleSetCacheControlRuleActionParametersProxyRevalidate: TypeAlias = Union[ + UnionMember2RuleSetCacheControlRuleActionParametersProxyRevalidateSetDirective, + UnionMember2RuleSetCacheControlRuleActionParametersProxyRevalidateRemoveDirective, +] + + +class UnionMember2RuleSetCacheControlRuleActionParametersPublicSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember2RuleSetCacheControlRuleActionParametersPublicRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember2RuleSetCacheControlRuleActionParametersPublic: TypeAlias = Union[ + UnionMember2RuleSetCacheControlRuleActionParametersPublicSetDirective, + UnionMember2RuleSetCacheControlRuleActionParametersPublicRemoveDirective, +] + + +class UnionMember2RuleSetCacheControlRuleActionParametersSMaxageSetDirective(BaseModel): + """Set the directive with a duration value in seconds.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + value: int + """The duration value in seconds for the directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember2RuleSetCacheControlRuleActionParametersSMaxageRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember2RuleSetCacheControlRuleActionParametersSMaxage: TypeAlias = Union[ + UnionMember2RuleSetCacheControlRuleActionParametersSMaxageSetDirective, + UnionMember2RuleSetCacheControlRuleActionParametersSMaxageRemoveDirective, +] + + +class UnionMember2RuleSetCacheControlRuleActionParametersStaleIfErrorSetDirective(BaseModel): + """Set the directive with a duration value in seconds.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + value: int + """The duration value in seconds for the directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember2RuleSetCacheControlRuleActionParametersStaleIfErrorRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember2RuleSetCacheControlRuleActionParametersStaleIfError: TypeAlias = Union[ + UnionMember2RuleSetCacheControlRuleActionParametersStaleIfErrorSetDirective, + UnionMember2RuleSetCacheControlRuleActionParametersStaleIfErrorRemoveDirective, +] + + +class UnionMember2RuleSetCacheControlRuleActionParametersStaleWhileRevalidateSetDirective(BaseModel): + """Set the directive with a duration value in seconds.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + value: int + """The duration value in seconds for the directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember2RuleSetCacheControlRuleActionParametersStaleWhileRevalidateRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember2RuleSetCacheControlRuleActionParametersStaleWhileRevalidate: TypeAlias = Union[ + UnionMember2RuleSetCacheControlRuleActionParametersStaleWhileRevalidateSetDirective, + UnionMember2RuleSetCacheControlRuleActionParametersStaleWhileRevalidateRemoveDirective, +] + + +class UnionMember2RuleSetCacheControlRuleActionParameters(BaseModel): + """The parameters configuring the rule's action.""" + + immutable: Optional[UnionMember2RuleSetCacheControlRuleActionParametersImmutable] = None + """A cache-control directive configuration.""" + + max_age: Optional[UnionMember2RuleSetCacheControlRuleActionParametersMaxAge] = FieldInfo( + alias="max-age", default=None + ) + """ + A cache-control directive configuration that accepts a duration value in + seconds. + """ + + must_revalidate: Optional[UnionMember2RuleSetCacheControlRuleActionParametersMustRevalidate] = FieldInfo( + alias="must-revalidate", default=None + ) + """A cache-control directive configuration.""" + + must_understand: Optional[UnionMember2RuleSetCacheControlRuleActionParametersMustUnderstand] = FieldInfo( + alias="must-understand", default=None + ) + """A cache-control directive configuration.""" + + no_cache: Optional[UnionMember2RuleSetCacheControlRuleActionParametersNoCache] = FieldInfo( + alias="no-cache", default=None + ) + """ + A cache-control directive configuration that accepts optional qualifiers (header + names). + """ + + no_store: Optional[UnionMember2RuleSetCacheControlRuleActionParametersNoStore] = FieldInfo( + alias="no-store", default=None + ) + """A cache-control directive configuration.""" + + no_transform: Optional[UnionMember2RuleSetCacheControlRuleActionParametersNoTransform] = FieldInfo( + alias="no-transform", default=None + ) + """A cache-control directive configuration.""" + + private: Optional[UnionMember2RuleSetCacheControlRuleActionParametersPrivate] = None + """ + A cache-control directive configuration that accepts optional qualifiers (header + names). + """ + + proxy_revalidate: Optional[UnionMember2RuleSetCacheControlRuleActionParametersProxyRevalidate] = FieldInfo( + alias="proxy-revalidate", default=None + ) + """A cache-control directive configuration.""" + + public: Optional[UnionMember2RuleSetCacheControlRuleActionParametersPublic] = None + """A cache-control directive configuration.""" + + s_maxage: Optional[UnionMember2RuleSetCacheControlRuleActionParametersSMaxage] = FieldInfo( + alias="s-maxage", default=None + ) + """ + A cache-control directive configuration that accepts a duration value in + seconds. + """ + + stale_if_error: Optional[UnionMember2RuleSetCacheControlRuleActionParametersStaleIfError] = FieldInfo( + alias="stale-if-error", default=None + ) + """ + A cache-control directive configuration that accepts a duration value in + seconds. + """ + + stale_while_revalidate: Optional[UnionMember2RuleSetCacheControlRuleActionParametersStaleWhileRevalidate] = ( + FieldInfo(alias="stale-while-revalidate", default=None) + ) + """ + A cache-control directive configuration that accepts a duration value in + seconds. + """ + + +class UnionMember2RuleSetCacheControlRuleExposedCredentialCheck(BaseModel): + """Configuration for exposed credential checking.""" + + password_expression: str + """An expression that selects the password used in the credentials check.""" + + username_expression: str + """An expression that selects the user ID used in the credentials check.""" + + +class UnionMember2RuleSetCacheControlRuleRatelimit(BaseModel): + """An object configuring the rule's rate limit behavior.""" + + characteristics: List[str] + """ + Characteristics of the request on which the rate limit counter will be + incremented. + """ + + period: int + """Period in seconds over which the counter is being incremented.""" + + counting_expression: Optional[str] = None + """An expression that defines when the rate limit counter should be incremented. + + It defaults to the same as the rule's expression. + """ + + mitigation_timeout: Optional[int] = None + """ + Period of time in seconds after which the action will be disabled following its + first execution. + """ + + requests_per_period: Optional[int] = None + """ + The threshold of requests per period after which the action will be executed for + the first time. + """ + + requests_to_origin: Optional[bool] = None + """Whether counting is only performed when an origin is reached.""" + + score_per_period: Optional[int] = None + """ + The score threshold per period for which the action will be executed the first + time. + """ + + score_response_header_name: Optional[str] = None + """ + A response header name provided by the origin, which contains the score to + increment rate limit counter with. + """ + + +class UnionMember2RuleSetCacheControlRule(BaseModel): + id: str + """The unique ID of the rule.""" + + action: Literal["set_cache_control"] + """The action to perform when the rule matches.""" + + enabled: bool + + expression: str + """The expression defining which traffic will match the rule.""" + + last_updated: datetime + """The timestamp of when the rule was last modified.""" + + ref: str + """The reference of the rule (the rule's ID by default).""" + + version: str + """The version of the rule.""" + + action_parameters: Optional[UnionMember2RuleSetCacheControlRuleActionParameters] = None + """The parameters configuring the rule's action.""" + + categories: Optional[List[str]] = None + """The categories of the rule.""" + + description: Optional[str] = None + """An informative description of the rule.""" + + exposed_credential_check: Optional[UnionMember2RuleSetCacheControlRuleExposedCredentialCheck] = None + """Configuration for exposed credential checking.""" + + logging: Optional[Logging] = None + """An object configuring the rule's logging behavior.""" + + ratelimit: Optional[UnionMember2RuleSetCacheControlRuleRatelimit] = None + """An object configuring the rule's rate limit behavior.""" + + +class UnionMember2RuleSetCacheSettingsRule(SetCacheSettingsRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember2RuleSetCacheTagsRuleActionParametersAddCacheTagsValues(BaseModel): + """Add cache tags using a list of values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + values: List[str] + """A list of cache tag values.""" + + +class UnionMember2RuleSetCacheTagsRuleActionParametersAddCacheTagsExpression(BaseModel): + """Add cache tags using an expression.""" + + expression: str + """An expression that evaluates to an array of cache tag values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + +class UnionMember2RuleSetCacheTagsRuleActionParametersRemoveCacheTagsValues(BaseModel): + """Remove cache tags using a list of values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + values: List[str] + """A list of cache tag values.""" + + +class UnionMember2RuleSetCacheTagsRuleActionParametersRemoveCacheTagsExpression(BaseModel): + """Remove cache tags using an expression.""" + + expression: str + """An expression that evaluates to an array of cache tag values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + +class UnionMember2RuleSetCacheTagsRuleActionParametersSetCacheTagsValues(BaseModel): + """Set cache tags using a list of values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + values: List[str] + """A list of cache tag values.""" + + +class UnionMember2RuleSetCacheTagsRuleActionParametersSetCacheTagsExpression(BaseModel): + """Set cache tags using an expression.""" + + expression: str + """An expression that evaluates to an array of cache tag values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + +UnionMember2RuleSetCacheTagsRuleActionParameters: TypeAlias = Union[ + UnionMember2RuleSetCacheTagsRuleActionParametersAddCacheTagsValues, + UnionMember2RuleSetCacheTagsRuleActionParametersAddCacheTagsExpression, + UnionMember2RuleSetCacheTagsRuleActionParametersRemoveCacheTagsValues, + UnionMember2RuleSetCacheTagsRuleActionParametersRemoveCacheTagsExpression, + UnionMember2RuleSetCacheTagsRuleActionParametersSetCacheTagsValues, + UnionMember2RuleSetCacheTagsRuleActionParametersSetCacheTagsExpression, +] + + +class UnionMember2RuleSetCacheTagsRuleExposedCredentialCheck(BaseModel): + """Configuration for exposed credential checking.""" + + password_expression: str + """An expression that selects the password used in the credentials check.""" + + username_expression: str + """An expression that selects the user ID used in the credentials check.""" + + +class UnionMember2RuleSetCacheTagsRuleRatelimit(BaseModel): + """An object configuring the rule's rate limit behavior.""" + + characteristics: List[str] + """ + Characteristics of the request on which the rate limit counter will be + incremented. + """ + + period: int + """Period in seconds over which the counter is being incremented.""" + + counting_expression: Optional[str] = None + """An expression that defines when the rate limit counter should be incremented. + + It defaults to the same as the rule's expression. + """ + + mitigation_timeout: Optional[int] = None + """ + Period of time in seconds after which the action will be disabled following its + first execution. + """ + + requests_per_period: Optional[int] = None + """ + The threshold of requests per period after which the action will be executed for + the first time. + """ + + requests_to_origin: Optional[bool] = None + """Whether counting is only performed when an origin is reached.""" + + score_per_period: Optional[int] = None + """ + The score threshold per period for which the action will be executed the first + time. + """ + + score_response_header_name: Optional[str] = None + """ + A response header name provided by the origin, which contains the score to + increment rate limit counter with. + """ + + +class UnionMember2RuleSetCacheTagsRule(BaseModel): + id: str + """The unique ID of the rule.""" + + action: Literal["set_cache_tags"] + """The action to perform when the rule matches.""" + + enabled: bool + + expression: str + """The expression defining which traffic will match the rule.""" + + last_updated: datetime + """The timestamp of when the rule was last modified.""" + + ref: str + """The reference of the rule (the rule's ID by default).""" + + version: str + """The version of the rule.""" + + action_parameters: Optional[UnionMember2RuleSetCacheTagsRuleActionParameters] = None + """The parameters configuring the rule's action.""" + + categories: Optional[List[str]] = None + """The categories of the rule.""" + + description: Optional[str] = None + """An informative description of the rule.""" + + exposed_credential_check: Optional[UnionMember2RuleSetCacheTagsRuleExposedCredentialCheck] = None + """Configuration for exposed credential checking.""" + + logging: Optional[Logging] = None + """An object configuring the rule's logging behavior.""" + + ratelimit: Optional[UnionMember2RuleSetCacheTagsRuleRatelimit] = None + """An object configuring the rule's rate limit behavior.""" + + +class UnionMember2RuleSetConfigurationRule(SetConfigRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember2RuleSkipRule(SkipRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember2RuleTransformResponseHTMLRuleActionParameters(BaseModel): + """The parameters configuring the rule's action.""" + + link_maze: object + """Enables the link maze transformation on the response.""" + + +class UnionMember2RuleTransformResponseHTMLRuleExposedCredentialCheck(BaseModel): + """Configuration for exposed credential checking.""" + + password_expression: str + """An expression that selects the password used in the credentials check.""" + + username_expression: str + """An expression that selects the user ID used in the credentials check.""" + + +class UnionMember2RuleTransformResponseHTMLRuleRatelimit(BaseModel): + """An object configuring the rule's rate limit behavior.""" + + characteristics: List[str] + """ + Characteristics of the request on which the rate limit counter will be + incremented. + """ + + period: int + """Period in seconds over which the counter is being incremented.""" + + counting_expression: Optional[str] = None + """An expression that defines when the rate limit counter should be incremented. + + It defaults to the same as the rule's expression. + """ + + mitigation_timeout: Optional[int] = None + """ + Period of time in seconds after which the action will be disabled following its + first execution. + """ + + requests_per_period: Optional[int] = None + """ + The threshold of requests per period after which the action will be executed for + the first time. + """ + + requests_to_origin: Optional[bool] = None + """Whether counting is only performed when an origin is reached.""" + + score_per_period: Optional[int] = None + """ + The score threshold per period for which the action will be executed the first + time. + """ + + score_response_header_name: Optional[str] = None + """ + A response header name provided by the origin, which contains the score to + increment rate limit counter with. + """ + + +class UnionMember2RuleTransformResponseHTMLRule(BaseModel): + id: str + """The unique ID of the rule.""" + + action: Literal["transform_response_html"] + """The action to perform when the rule matches.""" + + enabled: bool + + expression: str + """The expression defining which traffic will match the rule.""" + + last_updated: datetime + """The timestamp of when the rule was last modified.""" + + ref: str + """The reference of the rule (the rule's ID by default).""" + + version: str + """The version of the rule.""" + + action_parameters: Optional[UnionMember2RuleTransformResponseHTMLRuleActionParameters] = None + """The parameters configuring the rule's action.""" + + categories: Optional[List[str]] = None + """The categories of the rule.""" + + description: Optional[str] = None + """An informative description of the rule.""" + + exposed_credential_check: Optional[UnionMember2RuleTransformResponseHTMLRuleExposedCredentialCheck] = None + """Configuration for exposed credential checking.""" + + logging: Optional[Logging] = None + """An object configuring the rule's logging behavior.""" + + ratelimit: Optional[UnionMember2RuleTransformResponseHTMLRuleRatelimit] = None + """An object configuring the rule's rate limit behavior.""" + + +UnionMember2Rule: TypeAlias = Union[ + UnionMember2RuleBlockRule, + UnionMember2RuleChallengeRule, + UnionMember2RuleResponseCompressionRule, + UnionMember2RuleDDoSDynamicRule, + UnionMember2RuleExecuteRule, + UnionMember2RuleForceConnectionCloseRule, + UnionMember2RuleJavaScriptChallengeRule, + UnionMember2RuleLogRule, + UnionMember2RuleLogCustomFieldRule, + UnionMember2RuleManagedChallengeRule, + UnionMember2RuleRedirectRule, + UnionMember2RuleRewriteRule, + UnionMember2RuleRouteRule, + UnionMember2RuleScoreRule, + UnionMember2RuleServeErrorRule, + UnionMember2RuleSetCacheControlRule, + UnionMember2RuleSetCacheSettingsRule, + UnionMember2RuleSetCacheTagsRule, + UnionMember2RuleSetConfigurationRule, + UnionMember2RuleSkipRule, + UnionMember2RuleTransformResponseHTMLRule, +] + + +class UnionMember2(BaseModel): + id: Optional[str] = None + """The unique ID of the ruleset.""" + + description: Optional[str] = None + """An informative description of the ruleset.""" + + kind: Optional[Kind] = None + """The kind of the ruleset.""" + + last_updated: Optional[datetime] = None + """The timestamp of when the ruleset was last modified.""" + + name: Optional[str] = None + """The human-readable name of the ruleset.""" + + phase: Optional[Phase] = None + """The phase of the ruleset.""" + + rules: Optional[List[UnionMember2Rule]] = None + """The list of rules in the ruleset.""" + + version: Optional[str] = None + """The version of the ruleset.""" + + +class UnionMember3RuleBlockRule(BlockRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember3RuleChallengeRuleExposedCredentialCheck(BaseModel): + """Configuration for exposed credential checking.""" + + password_expression: str + """An expression that selects the password used in the credentials check.""" + + username_expression: str + """An expression that selects the user ID used in the credentials check.""" + + +class UnionMember3RuleChallengeRuleRatelimit(BaseModel): + """An object configuring the rule's rate limit behavior.""" + + characteristics: List[str] + """ + Characteristics of the request on which the rate limit counter will be + incremented. + """ + + period: int + """Period in seconds over which the counter is being incremented.""" + + counting_expression: Optional[str] = None + """An expression that defines when the rate limit counter should be incremented. + + It defaults to the same as the rule's expression. + """ + + mitigation_timeout: Optional[int] = None + """ + Period of time in seconds after which the action will be disabled following its + first execution. + """ + + requests_per_period: Optional[int] = None + """ + The threshold of requests per period after which the action will be executed for + the first time. + """ + + requests_to_origin: Optional[bool] = None + """Whether counting is only performed when an origin is reached.""" + + score_per_period: Optional[int] = None + """ + The score threshold per period for which the action will be executed the first + time. + """ + + score_response_header_name: Optional[str] = None + """ + A response header name provided by the origin, which contains the score to + increment rate limit counter with. + """ + + +class UnionMember3RuleChallengeRule(BaseModel): + id: str + """The unique ID of the rule.""" + + action: Literal["challenge"] + """The action to perform when the rule matches.""" + + enabled: bool + """Whether the rule should be executed.""" + + expression: str + """The expression defining which traffic will match the rule.""" + + last_updated: datetime + """The timestamp of when the rule was last modified.""" + + ref: str + """The reference of the rule (the rule's ID by default).""" + + version: str + """The version of the rule.""" + + action_parameters: Optional[object] = None + """The parameters configuring the rule's action.""" + + categories: Optional[List[str]] = None + """The categories of the rule.""" + + description: Optional[str] = None + """An informative description of the rule.""" + + exposed_credential_check: Optional[UnionMember3RuleChallengeRuleExposedCredentialCheck] = None + """Configuration for exposed credential checking.""" + + logging: Optional[Logging] = None + """An object configuring the rule's logging behavior.""" + + ratelimit: Optional[UnionMember3RuleChallengeRuleRatelimit] = None + """An object configuring the rule's rate limit behavior.""" + + +class UnionMember3RuleResponseCompressionRule(CompressResponseRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember3RuleDDoSDynamicRule(DDoSDynamicRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember3RuleExecuteRule(ExecuteRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember3RuleForceConnectionCloseRule(ForceConnectionCloseRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember3RuleJavaScriptChallengeRuleExposedCredentialCheck(BaseModel): + """Configuration for exposed credential checking.""" + + password_expression: str + """An expression that selects the password used in the credentials check.""" + + username_expression: str + """An expression that selects the user ID used in the credentials check.""" + + +class UnionMember3RuleJavaScriptChallengeRuleRatelimit(BaseModel): + """An object configuring the rule's rate limit behavior.""" + + characteristics: List[str] + """ + Characteristics of the request on which the rate limit counter will be + incremented. + """ + + period: int + """Period in seconds over which the counter is being incremented.""" + + counting_expression: Optional[str] = None + """An expression that defines when the rate limit counter should be incremented. + + It defaults to the same as the rule's expression. + """ + + mitigation_timeout: Optional[int] = None + """ + Period of time in seconds after which the action will be disabled following its + first execution. + """ + + requests_per_period: Optional[int] = None + """ + The threshold of requests per period after which the action will be executed for + the first time. + """ + + requests_to_origin: Optional[bool] = None + """Whether counting is only performed when an origin is reached.""" + + score_per_period: Optional[int] = None + """ + The score threshold per period for which the action will be executed the first + time. + """ + + score_response_header_name: Optional[str] = None + """ + A response header name provided by the origin, which contains the score to + increment rate limit counter with. + """ + + +class UnionMember3RuleJavaScriptChallengeRule(BaseModel): + id: str + """The unique ID of the rule.""" + + action: Literal["js_challenge"] + """The action to perform when the rule matches.""" + + enabled: bool + """Whether the rule should be executed.""" + + expression: str + """The expression defining which traffic will match the rule.""" + + last_updated: datetime + """The timestamp of when the rule was last modified.""" + + ref: str + """The reference of the rule (the rule's ID by default).""" + + version: str + """The version of the rule.""" + + action_parameters: Optional[object] = None + """The parameters configuring the rule's action.""" + + categories: Optional[List[str]] = None + """The categories of the rule.""" + + description: Optional[str] = None + """An informative description of the rule.""" + + exposed_credential_check: Optional[UnionMember3RuleJavaScriptChallengeRuleExposedCredentialCheck] = None + """Configuration for exposed credential checking.""" + + logging: Optional[Logging] = None + """An object configuring the rule's logging behavior.""" + + ratelimit: Optional[UnionMember3RuleJavaScriptChallengeRuleRatelimit] = None + """An object configuring the rule's rate limit behavior.""" + + +class UnionMember3RuleLogRule(LogRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember3RuleLogCustomFieldRule(LogCustomFieldRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember3RuleManagedChallengeRule(ManagedChallengeRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember3RuleRedirectRule(RedirectRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember3RuleRewriteRule(RewriteRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember3RuleRouteRule(RouteRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember3RuleScoreRule(ScoreRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember3RuleServeErrorRule(ServeErrorRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember3RuleSetCacheControlRuleActionParametersImmutableSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember3RuleSetCacheControlRuleActionParametersImmutableRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember3RuleSetCacheControlRuleActionParametersImmutable: TypeAlias = Union[ + UnionMember3RuleSetCacheControlRuleActionParametersImmutableSetDirective, + UnionMember3RuleSetCacheControlRuleActionParametersImmutableRemoveDirective, +] + + +class UnionMember3RuleSetCacheControlRuleActionParametersMaxAgeSetDirective(BaseModel): + """Set the directive with a duration value in seconds.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + value: int + """The duration value in seconds for the directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember3RuleSetCacheControlRuleActionParametersMaxAgeRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember3RuleSetCacheControlRuleActionParametersMaxAge: TypeAlias = Union[ + UnionMember3RuleSetCacheControlRuleActionParametersMaxAgeSetDirective, + UnionMember3RuleSetCacheControlRuleActionParametersMaxAgeRemoveDirective, +] + + +class UnionMember3RuleSetCacheControlRuleActionParametersMustRevalidateSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember3RuleSetCacheControlRuleActionParametersMustRevalidateRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember3RuleSetCacheControlRuleActionParametersMustRevalidate: TypeAlias = Union[ + UnionMember3RuleSetCacheControlRuleActionParametersMustRevalidateSetDirective, + UnionMember3RuleSetCacheControlRuleActionParametersMustRevalidateRemoveDirective, +] + + +class UnionMember3RuleSetCacheControlRuleActionParametersMustUnderstandSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember3RuleSetCacheControlRuleActionParametersMustUnderstandRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember3RuleSetCacheControlRuleActionParametersMustUnderstand: TypeAlias = Union[ + UnionMember3RuleSetCacheControlRuleActionParametersMustUnderstandSetDirective, + UnionMember3RuleSetCacheControlRuleActionParametersMustUnderstandRemoveDirective, +] + + +class UnionMember3RuleSetCacheControlRuleActionParametersNoCacheSetDirective(BaseModel): + """Set the directive with optional qualifiers.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + qualifiers: Optional[List[str]] = None + """ + Optional list of header names to qualify the directive (e.g., for "private" or + "no-cache" directives). + """ + + +class UnionMember3RuleSetCacheControlRuleActionParametersNoCacheRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember3RuleSetCacheControlRuleActionParametersNoCache: TypeAlias = Union[ + UnionMember3RuleSetCacheControlRuleActionParametersNoCacheSetDirective, + UnionMember3RuleSetCacheControlRuleActionParametersNoCacheRemoveDirective, +] + + +class UnionMember3RuleSetCacheControlRuleActionParametersNoStoreSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember3RuleSetCacheControlRuleActionParametersNoStoreRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember3RuleSetCacheControlRuleActionParametersNoStore: TypeAlias = Union[ + UnionMember3RuleSetCacheControlRuleActionParametersNoStoreSetDirective, + UnionMember3RuleSetCacheControlRuleActionParametersNoStoreRemoveDirective, +] + + +class UnionMember3RuleSetCacheControlRuleActionParametersNoTransformSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember3RuleSetCacheControlRuleActionParametersNoTransformRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember3RuleSetCacheControlRuleActionParametersNoTransform: TypeAlias = Union[ + UnionMember3RuleSetCacheControlRuleActionParametersNoTransformSetDirective, + UnionMember3RuleSetCacheControlRuleActionParametersNoTransformRemoveDirective, +] + + +class UnionMember3RuleSetCacheControlRuleActionParametersPrivateSetDirective(BaseModel): + """Set the directive with optional qualifiers.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + qualifiers: Optional[List[str]] = None + """ + Optional list of header names to qualify the directive (e.g., for "private" or + "no-cache" directives). + """ + + +class UnionMember3RuleSetCacheControlRuleActionParametersPrivateRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember3RuleSetCacheControlRuleActionParametersPrivate: TypeAlias = Union[ + UnionMember3RuleSetCacheControlRuleActionParametersPrivateSetDirective, + UnionMember3RuleSetCacheControlRuleActionParametersPrivateRemoveDirective, +] + + +class UnionMember3RuleSetCacheControlRuleActionParametersProxyRevalidateSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember3RuleSetCacheControlRuleActionParametersProxyRevalidateRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember3RuleSetCacheControlRuleActionParametersProxyRevalidate: TypeAlias = Union[ + UnionMember3RuleSetCacheControlRuleActionParametersProxyRevalidateSetDirective, + UnionMember3RuleSetCacheControlRuleActionParametersProxyRevalidateRemoveDirective, +] + + +class UnionMember3RuleSetCacheControlRuleActionParametersPublicSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember3RuleSetCacheControlRuleActionParametersPublicRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember3RuleSetCacheControlRuleActionParametersPublic: TypeAlias = Union[ + UnionMember3RuleSetCacheControlRuleActionParametersPublicSetDirective, + UnionMember3RuleSetCacheControlRuleActionParametersPublicRemoveDirective, +] + + +class UnionMember3RuleSetCacheControlRuleActionParametersSMaxageSetDirective(BaseModel): + """Set the directive with a duration value in seconds.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + value: int + """The duration value in seconds for the directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember3RuleSetCacheControlRuleActionParametersSMaxageRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember3RuleSetCacheControlRuleActionParametersSMaxage: TypeAlias = Union[ + UnionMember3RuleSetCacheControlRuleActionParametersSMaxageSetDirective, + UnionMember3RuleSetCacheControlRuleActionParametersSMaxageRemoveDirective, +] + + +class UnionMember3RuleSetCacheControlRuleActionParametersStaleIfErrorSetDirective(BaseModel): + """Set the directive with a duration value in seconds.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + value: int + """The duration value in seconds for the directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember3RuleSetCacheControlRuleActionParametersStaleIfErrorRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember3RuleSetCacheControlRuleActionParametersStaleIfError: TypeAlias = Union[ + UnionMember3RuleSetCacheControlRuleActionParametersStaleIfErrorSetDirective, + UnionMember3RuleSetCacheControlRuleActionParametersStaleIfErrorRemoveDirective, +] + + +class UnionMember3RuleSetCacheControlRuleActionParametersStaleWhileRevalidateSetDirective(BaseModel): + """Set the directive with a duration value in seconds.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + value: int + """The duration value in seconds for the directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember3RuleSetCacheControlRuleActionParametersStaleWhileRevalidateRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember3RuleSetCacheControlRuleActionParametersStaleWhileRevalidate: TypeAlias = Union[ + UnionMember3RuleSetCacheControlRuleActionParametersStaleWhileRevalidateSetDirective, + UnionMember3RuleSetCacheControlRuleActionParametersStaleWhileRevalidateRemoveDirective, +] + + +class UnionMember3RuleSetCacheControlRuleActionParameters(BaseModel): + """The parameters configuring the rule's action.""" + + immutable: Optional[UnionMember3RuleSetCacheControlRuleActionParametersImmutable] = None + """A cache-control directive configuration.""" + + max_age: Optional[UnionMember3RuleSetCacheControlRuleActionParametersMaxAge] = FieldInfo( + alias="max-age", default=None + ) + """ + A cache-control directive configuration that accepts a duration value in + seconds. + """ + + must_revalidate: Optional[UnionMember3RuleSetCacheControlRuleActionParametersMustRevalidate] = FieldInfo( + alias="must-revalidate", default=None + ) + """A cache-control directive configuration.""" + + must_understand: Optional[UnionMember3RuleSetCacheControlRuleActionParametersMustUnderstand] = FieldInfo( + alias="must-understand", default=None + ) + """A cache-control directive configuration.""" + + no_cache: Optional[UnionMember3RuleSetCacheControlRuleActionParametersNoCache] = FieldInfo( + alias="no-cache", default=None + ) + """ + A cache-control directive configuration that accepts optional qualifiers (header + names). + """ + + no_store: Optional[UnionMember3RuleSetCacheControlRuleActionParametersNoStore] = FieldInfo( + alias="no-store", default=None + ) + """A cache-control directive configuration.""" + + no_transform: Optional[UnionMember3RuleSetCacheControlRuleActionParametersNoTransform] = FieldInfo( + alias="no-transform", default=None + ) + """A cache-control directive configuration.""" + + private: Optional[UnionMember3RuleSetCacheControlRuleActionParametersPrivate] = None + """ + A cache-control directive configuration that accepts optional qualifiers (header + names). + """ + + proxy_revalidate: Optional[UnionMember3RuleSetCacheControlRuleActionParametersProxyRevalidate] = FieldInfo( + alias="proxy-revalidate", default=None + ) + """A cache-control directive configuration.""" + + public: Optional[UnionMember3RuleSetCacheControlRuleActionParametersPublic] = None + """A cache-control directive configuration.""" + + s_maxage: Optional[UnionMember3RuleSetCacheControlRuleActionParametersSMaxage] = FieldInfo( + alias="s-maxage", default=None + ) + """ + A cache-control directive configuration that accepts a duration value in + seconds. + """ + + stale_if_error: Optional[UnionMember3RuleSetCacheControlRuleActionParametersStaleIfError] = FieldInfo( + alias="stale-if-error", default=None + ) + """ + A cache-control directive configuration that accepts a duration value in + seconds. + """ + + stale_while_revalidate: Optional[UnionMember3RuleSetCacheControlRuleActionParametersStaleWhileRevalidate] = ( + FieldInfo(alias="stale-while-revalidate", default=None) + ) + """ + A cache-control directive configuration that accepts a duration value in + seconds. + """ + + +class UnionMember3RuleSetCacheControlRuleExposedCredentialCheck(BaseModel): + """Configuration for exposed credential checking.""" + + password_expression: str + """An expression that selects the password used in the credentials check.""" + + username_expression: str + """An expression that selects the user ID used in the credentials check.""" + + +class UnionMember3RuleSetCacheControlRuleRatelimit(BaseModel): + """An object configuring the rule's rate limit behavior.""" + + characteristics: List[str] + """ + Characteristics of the request on which the rate limit counter will be + incremented. + """ + + period: int + """Period in seconds over which the counter is being incremented.""" + + counting_expression: Optional[str] = None + """An expression that defines when the rate limit counter should be incremented. + + It defaults to the same as the rule's expression. + """ + + mitigation_timeout: Optional[int] = None + """ + Period of time in seconds after which the action will be disabled following its + first execution. + """ + + requests_per_period: Optional[int] = None + """ + The threshold of requests per period after which the action will be executed for + the first time. + """ + + requests_to_origin: Optional[bool] = None + """Whether counting is only performed when an origin is reached.""" + + score_per_period: Optional[int] = None + """ + The score threshold per period for which the action will be executed the first + time. + """ + + score_response_header_name: Optional[str] = None + """ + A response header name provided by the origin, which contains the score to + increment rate limit counter with. + """ + + +class UnionMember3RuleSetCacheControlRule(BaseModel): + id: str + """The unique ID of the rule.""" + + action: Literal["set_cache_control"] + """The action to perform when the rule matches.""" + + enabled: bool + + expression: str + """The expression defining which traffic will match the rule.""" + + last_updated: datetime + """The timestamp of when the rule was last modified.""" + + ref: str + """The reference of the rule (the rule's ID by default).""" + + version: str + """The version of the rule.""" + + action_parameters: Optional[UnionMember3RuleSetCacheControlRuleActionParameters] = None + """The parameters configuring the rule's action.""" + + categories: Optional[List[str]] = None + """The categories of the rule.""" + + description: Optional[str] = None + """An informative description of the rule.""" + + exposed_credential_check: Optional[UnionMember3RuleSetCacheControlRuleExposedCredentialCheck] = None + """Configuration for exposed credential checking.""" + + logging: Optional[Logging] = None + """An object configuring the rule's logging behavior.""" + + ratelimit: Optional[UnionMember3RuleSetCacheControlRuleRatelimit] = None + """An object configuring the rule's rate limit behavior.""" + + +class UnionMember3RuleSetCacheSettingsRule(SetCacheSettingsRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember3RuleSetCacheTagsRuleActionParametersAddCacheTagsValues(BaseModel): + """Add cache tags using a list of values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + values: List[str] + """A list of cache tag values.""" + + +class UnionMember3RuleSetCacheTagsRuleActionParametersAddCacheTagsExpression(BaseModel): + """Add cache tags using an expression.""" + + expression: str + """An expression that evaluates to an array of cache tag values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + +class UnionMember3RuleSetCacheTagsRuleActionParametersRemoveCacheTagsValues(BaseModel): + """Remove cache tags using a list of values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + values: List[str] + """A list of cache tag values.""" + + +class UnionMember3RuleSetCacheTagsRuleActionParametersRemoveCacheTagsExpression(BaseModel): + """Remove cache tags using an expression.""" + + expression: str + """An expression that evaluates to an array of cache tag values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + +class UnionMember3RuleSetCacheTagsRuleActionParametersSetCacheTagsValues(BaseModel): + """Set cache tags using a list of values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + values: List[str] + """A list of cache tag values.""" + + +class UnionMember3RuleSetCacheTagsRuleActionParametersSetCacheTagsExpression(BaseModel): + """Set cache tags using an expression.""" + + expression: str + """An expression that evaluates to an array of cache tag values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + +UnionMember3RuleSetCacheTagsRuleActionParameters: TypeAlias = Union[ + UnionMember3RuleSetCacheTagsRuleActionParametersAddCacheTagsValues, + UnionMember3RuleSetCacheTagsRuleActionParametersAddCacheTagsExpression, + UnionMember3RuleSetCacheTagsRuleActionParametersRemoveCacheTagsValues, + UnionMember3RuleSetCacheTagsRuleActionParametersRemoveCacheTagsExpression, + UnionMember3RuleSetCacheTagsRuleActionParametersSetCacheTagsValues, + UnionMember3RuleSetCacheTagsRuleActionParametersSetCacheTagsExpression, +] + + +class UnionMember3RuleSetCacheTagsRuleExposedCredentialCheck(BaseModel): + """Configuration for exposed credential checking.""" + + password_expression: str + """An expression that selects the password used in the credentials check.""" + + username_expression: str + """An expression that selects the user ID used in the credentials check.""" + + +class UnionMember3RuleSetCacheTagsRuleRatelimit(BaseModel): + """An object configuring the rule's rate limit behavior.""" + + characteristics: List[str] + """ + Characteristics of the request on which the rate limit counter will be + incremented. + """ + + period: int + """Period in seconds over which the counter is being incremented.""" + + counting_expression: Optional[str] = None + """An expression that defines when the rate limit counter should be incremented. + + It defaults to the same as the rule's expression. + """ + + mitigation_timeout: Optional[int] = None + """ + Period of time in seconds after which the action will be disabled following its + first execution. + """ + + requests_per_period: Optional[int] = None + """ + The threshold of requests per period after which the action will be executed for + the first time. + """ + + requests_to_origin: Optional[bool] = None + """Whether counting is only performed when an origin is reached.""" + + score_per_period: Optional[int] = None + """ + The score threshold per period for which the action will be executed the first + time. + """ + + score_response_header_name: Optional[str] = None + """ + A response header name provided by the origin, which contains the score to + increment rate limit counter with. + """ + + +class UnionMember3RuleSetCacheTagsRule(BaseModel): + id: str + """The unique ID of the rule.""" + + action: Literal["set_cache_tags"] + """The action to perform when the rule matches.""" + + enabled: bool + + expression: str + """The expression defining which traffic will match the rule.""" + + last_updated: datetime + """The timestamp of when the rule was last modified.""" + + ref: str + """The reference of the rule (the rule's ID by default).""" + + version: str + """The version of the rule.""" + + action_parameters: Optional[UnionMember3RuleSetCacheTagsRuleActionParameters] = None + """The parameters configuring the rule's action.""" + + categories: Optional[List[str]] = None + """The categories of the rule.""" + + description: Optional[str] = None + """An informative description of the rule.""" + + exposed_credential_check: Optional[UnionMember3RuleSetCacheTagsRuleExposedCredentialCheck] = None + """Configuration for exposed credential checking.""" + + logging: Optional[Logging] = None + """An object configuring the rule's logging behavior.""" + + ratelimit: Optional[UnionMember3RuleSetCacheTagsRuleRatelimit] = None + """An object configuring the rule's rate limit behavior.""" + + +class UnionMember3RuleSetConfigurationRule(SetConfigRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember3RuleSkipRule(SkipRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember3RuleTransformResponseHTMLRuleActionParameters(BaseModel): + """The parameters configuring the rule's action.""" + + link_maze: object + """Enables the link maze transformation on the response.""" + + +class UnionMember3RuleTransformResponseHTMLRuleExposedCredentialCheck(BaseModel): + """Configuration for exposed credential checking.""" + + password_expression: str + """An expression that selects the password used in the credentials check.""" + + username_expression: str + """An expression that selects the user ID used in the credentials check.""" + + +class UnionMember3RuleTransformResponseHTMLRuleRatelimit(BaseModel): + """An object configuring the rule's rate limit behavior.""" + + characteristics: List[str] + """ + Characteristics of the request on which the rate limit counter will be + incremented. + """ + + period: int + """Period in seconds over which the counter is being incremented.""" + + counting_expression: Optional[str] = None + """An expression that defines when the rate limit counter should be incremented. + + It defaults to the same as the rule's expression. + """ + + mitigation_timeout: Optional[int] = None + """ + Period of time in seconds after which the action will be disabled following its + first execution. + """ + + requests_per_period: Optional[int] = None + """ + The threshold of requests per period after which the action will be executed for + the first time. + """ + + requests_to_origin: Optional[bool] = None + """Whether counting is only performed when an origin is reached.""" + + score_per_period: Optional[int] = None + """ + The score threshold per period for which the action will be executed the first + time. + """ + + score_response_header_name: Optional[str] = None + """ + A response header name provided by the origin, which contains the score to + increment rate limit counter with. + """ + + +class UnionMember3RuleTransformResponseHTMLRule(BaseModel): + id: str + """The unique ID of the rule.""" + + action: Literal["transform_response_html"] + """The action to perform when the rule matches.""" + + enabled: bool + + expression: str + """The expression defining which traffic will match the rule.""" + + last_updated: datetime + """The timestamp of when the rule was last modified.""" + + ref: str + """The reference of the rule (the rule's ID by default).""" + + version: str + """The version of the rule.""" + + action_parameters: Optional[UnionMember3RuleTransformResponseHTMLRuleActionParameters] = None + """The parameters configuring the rule's action.""" + + categories: Optional[List[str]] = None + """The categories of the rule.""" + + description: Optional[str] = None + """An informative description of the rule.""" + + exposed_credential_check: Optional[UnionMember3RuleTransformResponseHTMLRuleExposedCredentialCheck] = None + """Configuration for exposed credential checking.""" + + logging: Optional[Logging] = None + """An object configuring the rule's logging behavior.""" + + ratelimit: Optional[UnionMember3RuleTransformResponseHTMLRuleRatelimit] = None + """An object configuring the rule's rate limit behavior.""" + + +UnionMember3Rule: TypeAlias = Union[ + UnionMember3RuleBlockRule, + UnionMember3RuleChallengeRule, + UnionMember3RuleResponseCompressionRule, + UnionMember3RuleDDoSDynamicRule, + UnionMember3RuleExecuteRule, + UnionMember3RuleForceConnectionCloseRule, + UnionMember3RuleJavaScriptChallengeRule, + UnionMember3RuleLogRule, + UnionMember3RuleLogCustomFieldRule, + UnionMember3RuleManagedChallengeRule, + UnionMember3RuleRedirectRule, + UnionMember3RuleRewriteRule, + UnionMember3RuleRouteRule, + UnionMember3RuleScoreRule, + UnionMember3RuleServeErrorRule, + UnionMember3RuleSetCacheControlRule, + UnionMember3RuleSetCacheSettingsRule, + UnionMember3RuleSetCacheTagsRule, + UnionMember3RuleSetConfigurationRule, + UnionMember3RuleSkipRule, + UnionMember3RuleTransformResponseHTMLRule, +] + + +class UnionMember3(BaseModel): + id: Optional[str] = None + """The unique ID of the ruleset.""" + + description: Optional[str] = None + """An informative description of the ruleset.""" + + kind: Optional[Kind] = None + """The kind of the ruleset.""" + + last_updated: Optional[datetime] = None + """The timestamp of when the ruleset was last modified.""" + + name: Optional[str] = None + """The human-readable name of the ruleset.""" + + phase: Optional[Phase] = None + """The phase of the ruleset.""" + + rules: Optional[List[UnionMember3Rule]] = None + """The list of rules in the ruleset.""" + + version: Optional[str] = None + """The version of the ruleset.""" + + +class UnionMember4RuleBlockRule(BlockRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember4RuleChallengeRuleExposedCredentialCheck(BaseModel): + """Configuration for exposed credential checking.""" + + password_expression: str + """An expression that selects the password used in the credentials check.""" + + username_expression: str + """An expression that selects the user ID used in the credentials check.""" + + +class UnionMember4RuleChallengeRuleRatelimit(BaseModel): + """An object configuring the rule's rate limit behavior.""" + + characteristics: List[str] + """ + Characteristics of the request on which the rate limit counter will be + incremented. + """ + + period: int + """Period in seconds over which the counter is being incremented.""" + + counting_expression: Optional[str] = None + """An expression that defines when the rate limit counter should be incremented. + + It defaults to the same as the rule's expression. + """ + + mitigation_timeout: Optional[int] = None + """ + Period of time in seconds after which the action will be disabled following its + first execution. + """ + + requests_per_period: Optional[int] = None + """ + The threshold of requests per period after which the action will be executed for + the first time. + """ + + requests_to_origin: Optional[bool] = None + """Whether counting is only performed when an origin is reached.""" + + score_per_period: Optional[int] = None + """ + The score threshold per period for which the action will be executed the first + time. + """ + + score_response_header_name: Optional[str] = None + """ + A response header name provided by the origin, which contains the score to + increment rate limit counter with. + """ + + +class UnionMember4RuleChallengeRule(BaseModel): + id: str + """The unique ID of the rule.""" + + action: Literal["challenge"] + """The action to perform when the rule matches.""" + + enabled: bool + """Whether the rule should be executed.""" + + expression: str + """The expression defining which traffic will match the rule.""" + + last_updated: datetime + """The timestamp of when the rule was last modified.""" + + ref: str + """The reference of the rule (the rule's ID by default).""" + + version: str + """The version of the rule.""" + + action_parameters: Optional[object] = None + """The parameters configuring the rule's action.""" + + categories: Optional[List[str]] = None + """The categories of the rule.""" + + description: Optional[str] = None + """An informative description of the rule.""" + + exposed_credential_check: Optional[UnionMember4RuleChallengeRuleExposedCredentialCheck] = None + """Configuration for exposed credential checking.""" + + logging: Optional[Logging] = None + """An object configuring the rule's logging behavior.""" + + ratelimit: Optional[UnionMember4RuleChallengeRuleRatelimit] = None + """An object configuring the rule's rate limit behavior.""" + + +class UnionMember4RuleResponseCompressionRule(CompressResponseRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember4RuleDDoSDynamicRule(DDoSDynamicRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember4RuleExecuteRule(ExecuteRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember4RuleForceConnectionCloseRule(ForceConnectionCloseRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember4RuleJavaScriptChallengeRuleExposedCredentialCheck(BaseModel): + """Configuration for exposed credential checking.""" + + password_expression: str + """An expression that selects the password used in the credentials check.""" + + username_expression: str + """An expression that selects the user ID used in the credentials check.""" + + +class UnionMember4RuleJavaScriptChallengeRuleRatelimit(BaseModel): + """An object configuring the rule's rate limit behavior.""" + + characteristics: List[str] + """ + Characteristics of the request on which the rate limit counter will be + incremented. + """ + + period: int + """Period in seconds over which the counter is being incremented.""" + + counting_expression: Optional[str] = None + """An expression that defines when the rate limit counter should be incremented. + + It defaults to the same as the rule's expression. + """ + + mitigation_timeout: Optional[int] = None + """ + Period of time in seconds after which the action will be disabled following its + first execution. + """ + + requests_per_period: Optional[int] = None + """ + The threshold of requests per period after which the action will be executed for + the first time. + """ + + requests_to_origin: Optional[bool] = None + """Whether counting is only performed when an origin is reached.""" + + score_per_period: Optional[int] = None + """ + The score threshold per period for which the action will be executed the first + time. + """ + + score_response_header_name: Optional[str] = None + """ + A response header name provided by the origin, which contains the score to + increment rate limit counter with. + """ + + +class UnionMember4RuleJavaScriptChallengeRule(BaseModel): + id: str + """The unique ID of the rule.""" + + action: Literal["js_challenge"] + """The action to perform when the rule matches.""" + + enabled: bool + """Whether the rule should be executed.""" + + expression: str + """The expression defining which traffic will match the rule.""" + + last_updated: datetime + """The timestamp of when the rule was last modified.""" + + ref: str + """The reference of the rule (the rule's ID by default).""" + + version: str + """The version of the rule.""" + + action_parameters: Optional[object] = None + """The parameters configuring the rule's action.""" + + categories: Optional[List[str]] = None + """The categories of the rule.""" + + description: Optional[str] = None + """An informative description of the rule.""" + + exposed_credential_check: Optional[UnionMember4RuleJavaScriptChallengeRuleExposedCredentialCheck] = None + """Configuration for exposed credential checking.""" + + logging: Optional[Logging] = None + """An object configuring the rule's logging behavior.""" + + ratelimit: Optional[UnionMember4RuleJavaScriptChallengeRuleRatelimit] = None + """An object configuring the rule's rate limit behavior.""" + + +class UnionMember4RuleLogRule(LogRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember4RuleLogCustomFieldRule(LogCustomFieldRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember4RuleManagedChallengeRule(ManagedChallengeRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember4RuleRedirectRule(RedirectRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember4RuleRewriteRule(RewriteRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember4RuleRouteRule(RouteRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember4RuleScoreRule(ScoreRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember4RuleServeErrorRule(ServeErrorRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember4RuleSetCacheControlRuleActionParametersImmutableSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember4RuleSetCacheControlRuleActionParametersImmutableRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember4RuleSetCacheControlRuleActionParametersImmutable: TypeAlias = Union[ + UnionMember4RuleSetCacheControlRuleActionParametersImmutableSetDirective, + UnionMember4RuleSetCacheControlRuleActionParametersImmutableRemoveDirective, +] + + +class UnionMember4RuleSetCacheControlRuleActionParametersMaxAgeSetDirective(BaseModel): + """Set the directive with a duration value in seconds.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + value: int + """The duration value in seconds for the directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember4RuleSetCacheControlRuleActionParametersMaxAgeRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember4RuleSetCacheControlRuleActionParametersMaxAge: TypeAlias = Union[ + UnionMember4RuleSetCacheControlRuleActionParametersMaxAgeSetDirective, + UnionMember4RuleSetCacheControlRuleActionParametersMaxAgeRemoveDirective, +] + + +class UnionMember4RuleSetCacheControlRuleActionParametersMustRevalidateSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember4RuleSetCacheControlRuleActionParametersMustRevalidateRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember4RuleSetCacheControlRuleActionParametersMustRevalidate: TypeAlias = Union[ + UnionMember4RuleSetCacheControlRuleActionParametersMustRevalidateSetDirective, + UnionMember4RuleSetCacheControlRuleActionParametersMustRevalidateRemoveDirective, +] + + +class UnionMember4RuleSetCacheControlRuleActionParametersMustUnderstandSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember4RuleSetCacheControlRuleActionParametersMustUnderstandRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember4RuleSetCacheControlRuleActionParametersMustUnderstand: TypeAlias = Union[ + UnionMember4RuleSetCacheControlRuleActionParametersMustUnderstandSetDirective, + UnionMember4RuleSetCacheControlRuleActionParametersMustUnderstandRemoveDirective, +] + + +class UnionMember4RuleSetCacheControlRuleActionParametersNoCacheSetDirective(BaseModel): + """Set the directive with optional qualifiers.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + qualifiers: Optional[List[str]] = None + """ + Optional list of header names to qualify the directive (e.g., for "private" or + "no-cache" directives). + """ + + +class UnionMember4RuleSetCacheControlRuleActionParametersNoCacheRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember4RuleSetCacheControlRuleActionParametersNoCache: TypeAlias = Union[ + UnionMember4RuleSetCacheControlRuleActionParametersNoCacheSetDirective, + UnionMember4RuleSetCacheControlRuleActionParametersNoCacheRemoveDirective, +] + + +class UnionMember4RuleSetCacheControlRuleActionParametersNoStoreSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember4RuleSetCacheControlRuleActionParametersNoStoreRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember4RuleSetCacheControlRuleActionParametersNoStore: TypeAlias = Union[ + UnionMember4RuleSetCacheControlRuleActionParametersNoStoreSetDirective, + UnionMember4RuleSetCacheControlRuleActionParametersNoStoreRemoveDirective, +] + + +class UnionMember4RuleSetCacheControlRuleActionParametersNoTransformSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember4RuleSetCacheControlRuleActionParametersNoTransformRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember4RuleSetCacheControlRuleActionParametersNoTransform: TypeAlias = Union[ + UnionMember4RuleSetCacheControlRuleActionParametersNoTransformSetDirective, + UnionMember4RuleSetCacheControlRuleActionParametersNoTransformRemoveDirective, +] + + +class UnionMember4RuleSetCacheControlRuleActionParametersPrivateSetDirective(BaseModel): + """Set the directive with optional qualifiers.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + qualifiers: Optional[List[str]] = None + """ + Optional list of header names to qualify the directive (e.g., for "private" or + "no-cache" directives). + """ + + +class UnionMember4RuleSetCacheControlRuleActionParametersPrivateRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember4RuleSetCacheControlRuleActionParametersPrivate: TypeAlias = Union[ + UnionMember4RuleSetCacheControlRuleActionParametersPrivateSetDirective, + UnionMember4RuleSetCacheControlRuleActionParametersPrivateRemoveDirective, +] + + +class UnionMember4RuleSetCacheControlRuleActionParametersProxyRevalidateSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember4RuleSetCacheControlRuleActionParametersProxyRevalidateRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember4RuleSetCacheControlRuleActionParametersProxyRevalidate: TypeAlias = Union[ + UnionMember4RuleSetCacheControlRuleActionParametersProxyRevalidateSetDirective, + UnionMember4RuleSetCacheControlRuleActionParametersProxyRevalidateRemoveDirective, +] + + +class UnionMember4RuleSetCacheControlRuleActionParametersPublicSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember4RuleSetCacheControlRuleActionParametersPublicRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember4RuleSetCacheControlRuleActionParametersPublic: TypeAlias = Union[ + UnionMember4RuleSetCacheControlRuleActionParametersPublicSetDirective, + UnionMember4RuleSetCacheControlRuleActionParametersPublicRemoveDirective, +] + + +class UnionMember4RuleSetCacheControlRuleActionParametersSMaxageSetDirective(BaseModel): + """Set the directive with a duration value in seconds.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + value: int + """The duration value in seconds for the directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember4RuleSetCacheControlRuleActionParametersSMaxageRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember4RuleSetCacheControlRuleActionParametersSMaxage: TypeAlias = Union[ + UnionMember4RuleSetCacheControlRuleActionParametersSMaxageSetDirective, + UnionMember4RuleSetCacheControlRuleActionParametersSMaxageRemoveDirective, +] + + +class UnionMember4RuleSetCacheControlRuleActionParametersStaleIfErrorSetDirective(BaseModel): + """Set the directive with a duration value in seconds.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + value: int + """The duration value in seconds for the directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember4RuleSetCacheControlRuleActionParametersStaleIfErrorRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember4RuleSetCacheControlRuleActionParametersStaleIfError: TypeAlias = Union[ + UnionMember4RuleSetCacheControlRuleActionParametersStaleIfErrorSetDirective, + UnionMember4RuleSetCacheControlRuleActionParametersStaleIfErrorRemoveDirective, +] + + +class UnionMember4RuleSetCacheControlRuleActionParametersStaleWhileRevalidateSetDirective(BaseModel): + """Set the directive with a duration value in seconds.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + value: int + """The duration value in seconds for the directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember4RuleSetCacheControlRuleActionParametersStaleWhileRevalidateRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember4RuleSetCacheControlRuleActionParametersStaleWhileRevalidate: TypeAlias = Union[ + UnionMember4RuleSetCacheControlRuleActionParametersStaleWhileRevalidateSetDirective, + UnionMember4RuleSetCacheControlRuleActionParametersStaleWhileRevalidateRemoveDirective, +] + + +class UnionMember4RuleSetCacheControlRuleActionParameters(BaseModel): + """The parameters configuring the rule's action.""" + + immutable: Optional[UnionMember4RuleSetCacheControlRuleActionParametersImmutable] = None + """A cache-control directive configuration.""" + + max_age: Optional[UnionMember4RuleSetCacheControlRuleActionParametersMaxAge] = FieldInfo( + alias="max-age", default=None + ) + """ + A cache-control directive configuration that accepts a duration value in + seconds. + """ + + must_revalidate: Optional[UnionMember4RuleSetCacheControlRuleActionParametersMustRevalidate] = FieldInfo( + alias="must-revalidate", default=None + ) + """A cache-control directive configuration.""" + + must_understand: Optional[UnionMember4RuleSetCacheControlRuleActionParametersMustUnderstand] = FieldInfo( + alias="must-understand", default=None + ) + """A cache-control directive configuration.""" + + no_cache: Optional[UnionMember4RuleSetCacheControlRuleActionParametersNoCache] = FieldInfo( + alias="no-cache", default=None + ) + """ + A cache-control directive configuration that accepts optional qualifiers (header + names). + """ + + no_store: Optional[UnionMember4RuleSetCacheControlRuleActionParametersNoStore] = FieldInfo( + alias="no-store", default=None + ) + """A cache-control directive configuration.""" + + no_transform: Optional[UnionMember4RuleSetCacheControlRuleActionParametersNoTransform] = FieldInfo( + alias="no-transform", default=None + ) + """A cache-control directive configuration.""" + + private: Optional[UnionMember4RuleSetCacheControlRuleActionParametersPrivate] = None + """ + A cache-control directive configuration that accepts optional qualifiers (header + names). + """ + + proxy_revalidate: Optional[UnionMember4RuleSetCacheControlRuleActionParametersProxyRevalidate] = FieldInfo( + alias="proxy-revalidate", default=None + ) + """A cache-control directive configuration.""" + + public: Optional[UnionMember4RuleSetCacheControlRuleActionParametersPublic] = None + """A cache-control directive configuration.""" + + s_maxage: Optional[UnionMember4RuleSetCacheControlRuleActionParametersSMaxage] = FieldInfo( + alias="s-maxage", default=None + ) + """ + A cache-control directive configuration that accepts a duration value in + seconds. + """ + + stale_if_error: Optional[UnionMember4RuleSetCacheControlRuleActionParametersStaleIfError] = FieldInfo( + alias="stale-if-error", default=None + ) + """ + A cache-control directive configuration that accepts a duration value in + seconds. + """ + + stale_while_revalidate: Optional[UnionMember4RuleSetCacheControlRuleActionParametersStaleWhileRevalidate] = ( + FieldInfo(alias="stale-while-revalidate", default=None) + ) + """ + A cache-control directive configuration that accepts a duration value in + seconds. + """ + + +class UnionMember4RuleSetCacheControlRuleExposedCredentialCheck(BaseModel): + """Configuration for exposed credential checking.""" + + password_expression: str + """An expression that selects the password used in the credentials check.""" + + username_expression: str + """An expression that selects the user ID used in the credentials check.""" + + +class UnionMember4RuleSetCacheControlRuleRatelimit(BaseModel): + """An object configuring the rule's rate limit behavior.""" + + characteristics: List[str] + """ + Characteristics of the request on which the rate limit counter will be + incremented. + """ + + period: int + """Period in seconds over which the counter is being incremented.""" + + counting_expression: Optional[str] = None + """An expression that defines when the rate limit counter should be incremented. + + It defaults to the same as the rule's expression. + """ + + mitigation_timeout: Optional[int] = None + """ + Period of time in seconds after which the action will be disabled following its + first execution. + """ + + requests_per_period: Optional[int] = None + """ + The threshold of requests per period after which the action will be executed for + the first time. + """ + + requests_to_origin: Optional[bool] = None + """Whether counting is only performed when an origin is reached.""" + + score_per_period: Optional[int] = None + """ + The score threshold per period for which the action will be executed the first + time. + """ + + score_response_header_name: Optional[str] = None + """ + A response header name provided by the origin, which contains the score to + increment rate limit counter with. + """ + + +class UnionMember4RuleSetCacheControlRule(BaseModel): + id: str + """The unique ID of the rule.""" + + action: Literal["set_cache_control"] + """The action to perform when the rule matches.""" + + enabled: bool + + expression: str + """The expression defining which traffic will match the rule.""" + + last_updated: datetime + """The timestamp of when the rule was last modified.""" + + ref: str + """The reference of the rule (the rule's ID by default).""" + + version: str + """The version of the rule.""" + + action_parameters: Optional[UnionMember4RuleSetCacheControlRuleActionParameters] = None + """The parameters configuring the rule's action.""" + + categories: Optional[List[str]] = None + """The categories of the rule.""" + + description: Optional[str] = None + """An informative description of the rule.""" + + exposed_credential_check: Optional[UnionMember4RuleSetCacheControlRuleExposedCredentialCheck] = None + """Configuration for exposed credential checking.""" + + logging: Optional[Logging] = None + """An object configuring the rule's logging behavior.""" + + ratelimit: Optional[UnionMember4RuleSetCacheControlRuleRatelimit] = None + """An object configuring the rule's rate limit behavior.""" + + +class UnionMember4RuleSetCacheSettingsRule(SetCacheSettingsRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember4RuleSetCacheTagsRuleActionParametersAddCacheTagsValues(BaseModel): + """Add cache tags using a list of values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + values: List[str] + """A list of cache tag values.""" + + +class UnionMember4RuleSetCacheTagsRuleActionParametersAddCacheTagsExpression(BaseModel): + """Add cache tags using an expression.""" + + expression: str + """An expression that evaluates to an array of cache tag values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + +class UnionMember4RuleSetCacheTagsRuleActionParametersRemoveCacheTagsValues(BaseModel): + """Remove cache tags using a list of values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + values: List[str] + """A list of cache tag values.""" + + +class UnionMember4RuleSetCacheTagsRuleActionParametersRemoveCacheTagsExpression(BaseModel): + """Remove cache tags using an expression.""" + + expression: str + """An expression that evaluates to an array of cache tag values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + +class UnionMember4RuleSetCacheTagsRuleActionParametersSetCacheTagsValues(BaseModel): + """Set cache tags using a list of values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + values: List[str] + """A list of cache tag values.""" + + +class UnionMember4RuleSetCacheTagsRuleActionParametersSetCacheTagsExpression(BaseModel): + """Set cache tags using an expression.""" + + expression: str + """An expression that evaluates to an array of cache tag values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + +UnionMember4RuleSetCacheTagsRuleActionParameters: TypeAlias = Union[ + UnionMember4RuleSetCacheTagsRuleActionParametersAddCacheTagsValues, + UnionMember4RuleSetCacheTagsRuleActionParametersAddCacheTagsExpression, + UnionMember4RuleSetCacheTagsRuleActionParametersRemoveCacheTagsValues, + UnionMember4RuleSetCacheTagsRuleActionParametersRemoveCacheTagsExpression, + UnionMember4RuleSetCacheTagsRuleActionParametersSetCacheTagsValues, + UnionMember4RuleSetCacheTagsRuleActionParametersSetCacheTagsExpression, +] + + +class UnionMember4RuleSetCacheTagsRuleExposedCredentialCheck(BaseModel): + """Configuration for exposed credential checking.""" + + password_expression: str + """An expression that selects the password used in the credentials check.""" + + username_expression: str + """An expression that selects the user ID used in the credentials check.""" + + +class UnionMember4RuleSetCacheTagsRuleRatelimit(BaseModel): + """An object configuring the rule's rate limit behavior.""" + + characteristics: List[str] + """ + Characteristics of the request on which the rate limit counter will be + incremented. + """ + + period: int + """Period in seconds over which the counter is being incremented.""" + + counting_expression: Optional[str] = None + """An expression that defines when the rate limit counter should be incremented. + + It defaults to the same as the rule's expression. + """ + + mitigation_timeout: Optional[int] = None + """ + Period of time in seconds after which the action will be disabled following its + first execution. + """ + + requests_per_period: Optional[int] = None + """ + The threshold of requests per period after which the action will be executed for + the first time. + """ + + requests_to_origin: Optional[bool] = None + """Whether counting is only performed when an origin is reached.""" + + score_per_period: Optional[int] = None + """ + The score threshold per period for which the action will be executed the first + time. + """ + + score_response_header_name: Optional[str] = None + """ + A response header name provided by the origin, which contains the score to + increment rate limit counter with. + """ + + +class UnionMember4RuleSetCacheTagsRule(BaseModel): + id: str + """The unique ID of the rule.""" + + action: Literal["set_cache_tags"] + """The action to perform when the rule matches.""" + + enabled: bool + + expression: str + """The expression defining which traffic will match the rule.""" + + last_updated: datetime + """The timestamp of when the rule was last modified.""" + + ref: str + """The reference of the rule (the rule's ID by default).""" + + version: str + """The version of the rule.""" + + action_parameters: Optional[UnionMember4RuleSetCacheTagsRuleActionParameters] = None + """The parameters configuring the rule's action.""" + + categories: Optional[List[str]] = None + """The categories of the rule.""" + + description: Optional[str] = None + """An informative description of the rule.""" + + exposed_credential_check: Optional[UnionMember4RuleSetCacheTagsRuleExposedCredentialCheck] = None + """Configuration for exposed credential checking.""" + + logging: Optional[Logging] = None + """An object configuring the rule's logging behavior.""" + + ratelimit: Optional[UnionMember4RuleSetCacheTagsRuleRatelimit] = None + """An object configuring the rule's rate limit behavior.""" + + +class UnionMember4RuleSetConfigurationRule(SetConfigRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember4RuleSkipRule(SkipRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember4RuleTransformResponseHTMLRuleActionParameters(BaseModel): + """The parameters configuring the rule's action.""" + + link_maze: object + """Enables the link maze transformation on the response.""" + + +class UnionMember4RuleTransformResponseHTMLRuleExposedCredentialCheck(BaseModel): + """Configuration for exposed credential checking.""" + + password_expression: str + """An expression that selects the password used in the credentials check.""" + + username_expression: str + """An expression that selects the user ID used in the credentials check.""" + + +class UnionMember4RuleTransformResponseHTMLRuleRatelimit(BaseModel): + """An object configuring the rule's rate limit behavior.""" + + characteristics: List[str] + """ + Characteristics of the request on which the rate limit counter will be + incremented. + """ + + period: int + """Period in seconds over which the counter is being incremented.""" + + counting_expression: Optional[str] = None + """An expression that defines when the rate limit counter should be incremented. + + It defaults to the same as the rule's expression. + """ + + mitigation_timeout: Optional[int] = None + """ + Period of time in seconds after which the action will be disabled following its + first execution. + """ + + requests_per_period: Optional[int] = None + """ + The threshold of requests per period after which the action will be executed for + the first time. + """ + + requests_to_origin: Optional[bool] = None + """Whether counting is only performed when an origin is reached.""" + + score_per_period: Optional[int] = None + """ + The score threshold per period for which the action will be executed the first + time. + """ + + score_response_header_name: Optional[str] = None + """ + A response header name provided by the origin, which contains the score to + increment rate limit counter with. + """ + + +class UnionMember4RuleTransformResponseHTMLRule(BaseModel): + id: str + """The unique ID of the rule.""" + + action: Literal["transform_response_html"] + """The action to perform when the rule matches.""" + + enabled: bool + + expression: str + """The expression defining which traffic will match the rule.""" + + last_updated: datetime + """The timestamp of when the rule was last modified.""" + + ref: str + """The reference of the rule (the rule's ID by default).""" + + version: str + """The version of the rule.""" + + action_parameters: Optional[UnionMember4RuleTransformResponseHTMLRuleActionParameters] = None + """The parameters configuring the rule's action.""" + + categories: Optional[List[str]] = None + """The categories of the rule.""" + + description: Optional[str] = None + """An informative description of the rule.""" + + exposed_credential_check: Optional[UnionMember4RuleTransformResponseHTMLRuleExposedCredentialCheck] = None + """Configuration for exposed credential checking.""" + + logging: Optional[Logging] = None + """An object configuring the rule's logging behavior.""" + + ratelimit: Optional[UnionMember4RuleTransformResponseHTMLRuleRatelimit] = None + """An object configuring the rule's rate limit behavior.""" + + +UnionMember4Rule: TypeAlias = Union[ + UnionMember4RuleBlockRule, + UnionMember4RuleChallengeRule, + UnionMember4RuleResponseCompressionRule, + UnionMember4RuleDDoSDynamicRule, + UnionMember4RuleExecuteRule, + UnionMember4RuleForceConnectionCloseRule, + UnionMember4RuleJavaScriptChallengeRule, + UnionMember4RuleLogRule, + UnionMember4RuleLogCustomFieldRule, + UnionMember4RuleManagedChallengeRule, + UnionMember4RuleRedirectRule, + UnionMember4RuleRewriteRule, + UnionMember4RuleRouteRule, + UnionMember4RuleScoreRule, + UnionMember4RuleServeErrorRule, + UnionMember4RuleSetCacheControlRule, + UnionMember4RuleSetCacheSettingsRule, + UnionMember4RuleSetCacheTagsRule, + UnionMember4RuleSetConfigurationRule, + UnionMember4RuleSkipRule, + UnionMember4RuleTransformResponseHTMLRule, +] + + +class UnionMember4(BaseModel): + id: Optional[str] = None + """The unique ID of the ruleset.""" + + description: Optional[str] = None + """An informative description of the ruleset.""" + + kind: Optional[Kind] = None + """The kind of the ruleset.""" + + last_updated: Optional[datetime] = None + """The timestamp of when the ruleset was last modified.""" + + name: Optional[str] = None + """The human-readable name of the ruleset.""" + + phase: Optional[Phase] = None + """The phase of the ruleset.""" + + rules: Optional[List[UnionMember4Rule]] = None + """The list of rules in the ruleset.""" + + version: Optional[str] = None + """The version of the ruleset.""" + + +RulesetGetResponse: TypeAlias = Union[Optional[UnionMember0], UnionMember1, UnionMember2, UnionMember3, UnionMember4] diff --git a/src/cloudflare/types/rulesets/ruleset_list_response.py b/src/cloudflare/types/rulesets/ruleset_list_response.py index c892b62467f..97a7ccc6438 100644 --- a/src/cloudflare/types/rulesets/ruleset_list_response.py +++ b/src/cloudflare/types/rulesets/ruleset_list_response.py @@ -1,35 +1,8 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import Optional -from datetime import datetime - -from .kind import Kind -from .phase import Phase -from ..._models import BaseModel +from typing import List, Union, Optional +from typing_extensions import TypeAlias __all__ = ["RulesetListResponse"] - -class RulesetListResponse(BaseModel): - """A ruleset object.""" - - id: str - """The unique ID of the ruleset.""" - - kind: Kind - """The kind of the ruleset.""" - - last_updated: datetime - """The timestamp of when the ruleset was last modified.""" - - name: str - """The human-readable name of the ruleset.""" - - phase: Phase - """The phase of the ruleset.""" - - version: str - """The version of the ruleset.""" - - description: Optional[str] = None - """An informative description of the ruleset.""" +RulesetListResponse: TypeAlias = Union[List[object], str, float, bool, Optional[object]] diff --git a/src/cloudflare/types/rulesets/ruleset_update_response.py b/src/cloudflare/types/rulesets/ruleset_update_response.py index cdd6f788b92..16b1c8dd851 100644 --- a/src/cloudflare/types/rulesets/ruleset_update_response.py +++ b/src/cloudflare/types/rulesets/ruleset_update_response.py @@ -1358,4 +1358,4 @@ class Ruleset(BaseModel): """An informative description of the ruleset.""" -RulesetUpdateResponse: TypeAlias = Union[Ruleset, Optional[object]] +RulesetUpdateResponse: TypeAlias = Union[List[object], str, float, bool, Ruleset, Optional[object], Optional[object]] diff --git a/src/cloudflare/types/rulesets/set_config_rule.py b/src/cloudflare/types/rulesets/set_config_rule.py index f7b8650e59b..37ef19f4c63 100644 --- a/src/cloudflare/types/rulesets/set_config_rule.py +++ b/src/cloudflare/types/rulesets/set_config_rule.py @@ -105,8 +105,7 @@ class ActionParameters(BaseModel): """Bundled WebMCP tool packs to activate for matching requests. An empty array disables all packs. Omitting this parameter leaves the pack - selection unchanged. Does not enable the WebMCP bridge itself. Non-empty - selections require the WebMCP Configuration Rules entitlement. + selection unchanged. Does not enable the WebMCP bridge itself. """ diff --git a/src/cloudflare/types/rulesets/set_config_rule_param.py b/src/cloudflare/types/rulesets/set_config_rule_param.py index 873beb141e6..e6580895a69 100644 --- a/src/cloudflare/types/rulesets/set_config_rule_param.py +++ b/src/cloudflare/types/rulesets/set_config_rule_param.py @@ -111,8 +111,7 @@ class ActionParameters(TypedDict, total=False): """Bundled WebMCP tool packs to activate for matching requests. An empty array disables all packs. Omitting this parameter leaves the pack - selection unchanged. Does not enable the WebMCP bridge itself. Non-empty - selections require the WebMCP Configuration Rules entitlement. + selection unchanged. Does not enable the WebMCP bridge itself. """ diff --git a/src/cloudflare/types/rulesets/version_get_response.py b/src/cloudflare/types/rulesets/version_get_response.py index 66f849dc82d..3a13772c9a1 100644 --- a/src/cloudflare/types/rulesets/version_get_response.py +++ b/src/cloudflare/types/rulesets/version_get_response.py @@ -29,102 +29,427 @@ __all__ = [ "VersionGetResponse", - "Rule", - "RuleBlockRule", - "RuleChallengeRule", - "RuleChallengeRuleExposedCredentialCheck", - "RuleChallengeRuleRatelimit", - "RuleResponseCompressionRule", - "RuleDDoSDynamicRule", - "RuleExecuteRule", - "RuleForceConnectionCloseRule", - "RuleJavaScriptChallengeRule", - "RuleJavaScriptChallengeRuleExposedCredentialCheck", - "RuleJavaScriptChallengeRuleRatelimit", - "RuleLogRule", - "RuleLogCustomFieldRule", - "RuleManagedChallengeRule", - "RuleRedirectRule", - "RuleRewriteRule", - "RuleRouteRule", - "RuleScoreRule", - "RuleServeErrorRule", - "RuleSetCacheControlRule", - "RuleSetCacheControlRuleActionParameters", - "RuleSetCacheControlRuleActionParametersImmutable", - "RuleSetCacheControlRuleActionParametersImmutableSetDirective", - "RuleSetCacheControlRuleActionParametersImmutableRemoveDirective", - "RuleSetCacheControlRuleActionParametersMaxAge", - "RuleSetCacheControlRuleActionParametersMaxAgeSetDirective", - "RuleSetCacheControlRuleActionParametersMaxAgeRemoveDirective", - "RuleSetCacheControlRuleActionParametersMustRevalidate", - "RuleSetCacheControlRuleActionParametersMustRevalidateSetDirective", - "RuleSetCacheControlRuleActionParametersMustRevalidateRemoveDirective", - "RuleSetCacheControlRuleActionParametersMustUnderstand", - "RuleSetCacheControlRuleActionParametersMustUnderstandSetDirective", - "RuleSetCacheControlRuleActionParametersMustUnderstandRemoveDirective", - "RuleSetCacheControlRuleActionParametersNoCache", - "RuleSetCacheControlRuleActionParametersNoCacheSetDirective", - "RuleSetCacheControlRuleActionParametersNoCacheRemoveDirective", - "RuleSetCacheControlRuleActionParametersNoStore", - "RuleSetCacheControlRuleActionParametersNoStoreSetDirective", - "RuleSetCacheControlRuleActionParametersNoStoreRemoveDirective", - "RuleSetCacheControlRuleActionParametersNoTransform", - "RuleSetCacheControlRuleActionParametersNoTransformSetDirective", - "RuleSetCacheControlRuleActionParametersNoTransformRemoveDirective", - "RuleSetCacheControlRuleActionParametersPrivate", - "RuleSetCacheControlRuleActionParametersPrivateSetDirective", - "RuleSetCacheControlRuleActionParametersPrivateRemoveDirective", - "RuleSetCacheControlRuleActionParametersProxyRevalidate", - "RuleSetCacheControlRuleActionParametersProxyRevalidateSetDirective", - "RuleSetCacheControlRuleActionParametersProxyRevalidateRemoveDirective", - "RuleSetCacheControlRuleActionParametersPublic", - "RuleSetCacheControlRuleActionParametersPublicSetDirective", - "RuleSetCacheControlRuleActionParametersPublicRemoveDirective", - "RuleSetCacheControlRuleActionParametersSMaxage", - "RuleSetCacheControlRuleActionParametersSMaxageSetDirective", - "RuleSetCacheControlRuleActionParametersSMaxageRemoveDirective", - "RuleSetCacheControlRuleActionParametersStaleIfError", - "RuleSetCacheControlRuleActionParametersStaleIfErrorSetDirective", - "RuleSetCacheControlRuleActionParametersStaleIfErrorRemoveDirective", - "RuleSetCacheControlRuleActionParametersStaleWhileRevalidate", - "RuleSetCacheControlRuleActionParametersStaleWhileRevalidateSetDirective", - "RuleSetCacheControlRuleActionParametersStaleWhileRevalidateRemoveDirective", - "RuleSetCacheControlRuleExposedCredentialCheck", - "RuleSetCacheControlRuleRatelimit", - "RuleSetCacheSettingsRule", - "RuleSetCacheTagsRule", - "RuleSetCacheTagsRuleActionParameters", - "RuleSetCacheTagsRuleActionParametersAddCacheTagsValues", - "RuleSetCacheTagsRuleActionParametersAddCacheTagsExpression", - "RuleSetCacheTagsRuleActionParametersRemoveCacheTagsValues", - "RuleSetCacheTagsRuleActionParametersRemoveCacheTagsExpression", - "RuleSetCacheTagsRuleActionParametersSetCacheTagsValues", - "RuleSetCacheTagsRuleActionParametersSetCacheTagsExpression", - "RuleSetCacheTagsRuleExposedCredentialCheck", - "RuleSetCacheTagsRuleRatelimit", - "RuleSetConfigurationRule", - "RuleSkipRule", - "RuleTransformResponseHTMLRule", - "RuleTransformResponseHTMLRuleActionParameters", - "RuleTransformResponseHTMLRuleExposedCredentialCheck", - "RuleTransformResponseHTMLRuleRatelimit", -] - - -class RuleBlockRule(BlockRule): - id: str # type: ignore - - action: str # type: ignore - - enabled: bool # type: ignore - - expression: str # type: ignore - - ref: str # type: ignore - - -class RuleChallengeRuleExposedCredentialCheck(BaseModel): + "UnionMember0", + "UnionMember0Rule", + "UnionMember0RuleBlockRule", + "UnionMember0RuleChallengeRule", + "UnionMember0RuleChallengeRuleExposedCredentialCheck", + "UnionMember0RuleChallengeRuleRatelimit", + "UnionMember0RuleResponseCompressionRule", + "UnionMember0RuleDDoSDynamicRule", + "UnionMember0RuleExecuteRule", + "UnionMember0RuleForceConnectionCloseRule", + "UnionMember0RuleJavaScriptChallengeRule", + "UnionMember0RuleJavaScriptChallengeRuleExposedCredentialCheck", + "UnionMember0RuleJavaScriptChallengeRuleRatelimit", + "UnionMember0RuleLogRule", + "UnionMember0RuleLogCustomFieldRule", + "UnionMember0RuleManagedChallengeRule", + "UnionMember0RuleRedirectRule", + "UnionMember0RuleRewriteRule", + "UnionMember0RuleRouteRule", + "UnionMember0RuleScoreRule", + "UnionMember0RuleServeErrorRule", + "UnionMember0RuleSetCacheControlRule", + "UnionMember0RuleSetCacheControlRuleActionParameters", + "UnionMember0RuleSetCacheControlRuleActionParametersImmutable", + "UnionMember0RuleSetCacheControlRuleActionParametersImmutableSetDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersImmutableRemoveDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersMaxAge", + "UnionMember0RuleSetCacheControlRuleActionParametersMaxAgeSetDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersMaxAgeRemoveDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersMustRevalidate", + "UnionMember0RuleSetCacheControlRuleActionParametersMustRevalidateSetDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersMustRevalidateRemoveDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersMustUnderstand", + "UnionMember0RuleSetCacheControlRuleActionParametersMustUnderstandSetDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersMustUnderstandRemoveDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersNoCache", + "UnionMember0RuleSetCacheControlRuleActionParametersNoCacheSetDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersNoCacheRemoveDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersNoStore", + "UnionMember0RuleSetCacheControlRuleActionParametersNoStoreSetDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersNoStoreRemoveDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersNoTransform", + "UnionMember0RuleSetCacheControlRuleActionParametersNoTransformSetDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersNoTransformRemoveDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersPrivate", + "UnionMember0RuleSetCacheControlRuleActionParametersPrivateSetDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersPrivateRemoveDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersProxyRevalidate", + "UnionMember0RuleSetCacheControlRuleActionParametersProxyRevalidateSetDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersProxyRevalidateRemoveDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersPublic", + "UnionMember0RuleSetCacheControlRuleActionParametersPublicSetDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersPublicRemoveDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersSMaxage", + "UnionMember0RuleSetCacheControlRuleActionParametersSMaxageSetDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersSMaxageRemoveDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersStaleIfError", + "UnionMember0RuleSetCacheControlRuleActionParametersStaleIfErrorSetDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersStaleIfErrorRemoveDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersStaleWhileRevalidate", + "UnionMember0RuleSetCacheControlRuleActionParametersStaleWhileRevalidateSetDirective", + "UnionMember0RuleSetCacheControlRuleActionParametersStaleWhileRevalidateRemoveDirective", + "UnionMember0RuleSetCacheControlRuleExposedCredentialCheck", + "UnionMember0RuleSetCacheControlRuleRatelimit", + "UnionMember0RuleSetCacheSettingsRule", + "UnionMember0RuleSetCacheTagsRule", + "UnionMember0RuleSetCacheTagsRuleActionParameters", + "UnionMember0RuleSetCacheTagsRuleActionParametersAddCacheTagsValues", + "UnionMember0RuleSetCacheTagsRuleActionParametersAddCacheTagsExpression", + "UnionMember0RuleSetCacheTagsRuleActionParametersRemoveCacheTagsValues", + "UnionMember0RuleSetCacheTagsRuleActionParametersRemoveCacheTagsExpression", + "UnionMember0RuleSetCacheTagsRuleActionParametersSetCacheTagsValues", + "UnionMember0RuleSetCacheTagsRuleActionParametersSetCacheTagsExpression", + "UnionMember0RuleSetCacheTagsRuleExposedCredentialCheck", + "UnionMember0RuleSetCacheTagsRuleRatelimit", + "UnionMember0RuleSetConfigurationRule", + "UnionMember0RuleSkipRule", + "UnionMember0RuleTransformResponseHTMLRule", + "UnionMember0RuleTransformResponseHTMLRuleActionParameters", + "UnionMember0RuleTransformResponseHTMLRuleExposedCredentialCheck", + "UnionMember0RuleTransformResponseHTMLRuleRatelimit", + "UnionMember1", + "UnionMember1Rule", + "UnionMember1RuleBlockRule", + "UnionMember1RuleChallengeRule", + "UnionMember1RuleChallengeRuleExposedCredentialCheck", + "UnionMember1RuleChallengeRuleRatelimit", + "UnionMember1RuleResponseCompressionRule", + "UnionMember1RuleDDoSDynamicRule", + "UnionMember1RuleExecuteRule", + "UnionMember1RuleForceConnectionCloseRule", + "UnionMember1RuleJavaScriptChallengeRule", + "UnionMember1RuleJavaScriptChallengeRuleExposedCredentialCheck", + "UnionMember1RuleJavaScriptChallengeRuleRatelimit", + "UnionMember1RuleLogRule", + "UnionMember1RuleLogCustomFieldRule", + "UnionMember1RuleManagedChallengeRule", + "UnionMember1RuleRedirectRule", + "UnionMember1RuleRewriteRule", + "UnionMember1RuleRouteRule", + "UnionMember1RuleScoreRule", + "UnionMember1RuleServeErrorRule", + "UnionMember1RuleSetCacheControlRule", + "UnionMember1RuleSetCacheControlRuleActionParameters", + "UnionMember1RuleSetCacheControlRuleActionParametersImmutable", + "UnionMember1RuleSetCacheControlRuleActionParametersImmutableSetDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersImmutableRemoveDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersMaxAge", + "UnionMember1RuleSetCacheControlRuleActionParametersMaxAgeSetDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersMaxAgeRemoveDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersMustRevalidate", + "UnionMember1RuleSetCacheControlRuleActionParametersMustRevalidateSetDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersMustRevalidateRemoveDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersMustUnderstand", + "UnionMember1RuleSetCacheControlRuleActionParametersMustUnderstandSetDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersMustUnderstandRemoveDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersNoCache", + "UnionMember1RuleSetCacheControlRuleActionParametersNoCacheSetDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersNoCacheRemoveDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersNoStore", + "UnionMember1RuleSetCacheControlRuleActionParametersNoStoreSetDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersNoStoreRemoveDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersNoTransform", + "UnionMember1RuleSetCacheControlRuleActionParametersNoTransformSetDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersNoTransformRemoveDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersPrivate", + "UnionMember1RuleSetCacheControlRuleActionParametersPrivateSetDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersPrivateRemoveDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersProxyRevalidate", + "UnionMember1RuleSetCacheControlRuleActionParametersProxyRevalidateSetDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersProxyRevalidateRemoveDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersPublic", + "UnionMember1RuleSetCacheControlRuleActionParametersPublicSetDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersPublicRemoveDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersSMaxage", + "UnionMember1RuleSetCacheControlRuleActionParametersSMaxageSetDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersSMaxageRemoveDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersStaleIfError", + "UnionMember1RuleSetCacheControlRuleActionParametersStaleIfErrorSetDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersStaleIfErrorRemoveDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersStaleWhileRevalidate", + "UnionMember1RuleSetCacheControlRuleActionParametersStaleWhileRevalidateSetDirective", + "UnionMember1RuleSetCacheControlRuleActionParametersStaleWhileRevalidateRemoveDirective", + "UnionMember1RuleSetCacheControlRuleExposedCredentialCheck", + "UnionMember1RuleSetCacheControlRuleRatelimit", + "UnionMember1RuleSetCacheSettingsRule", + "UnionMember1RuleSetCacheTagsRule", + "UnionMember1RuleSetCacheTagsRuleActionParameters", + "UnionMember1RuleSetCacheTagsRuleActionParametersAddCacheTagsValues", + "UnionMember1RuleSetCacheTagsRuleActionParametersAddCacheTagsExpression", + "UnionMember1RuleSetCacheTagsRuleActionParametersRemoveCacheTagsValues", + "UnionMember1RuleSetCacheTagsRuleActionParametersRemoveCacheTagsExpression", + "UnionMember1RuleSetCacheTagsRuleActionParametersSetCacheTagsValues", + "UnionMember1RuleSetCacheTagsRuleActionParametersSetCacheTagsExpression", + "UnionMember1RuleSetCacheTagsRuleExposedCredentialCheck", + "UnionMember1RuleSetCacheTagsRuleRatelimit", + "UnionMember1RuleSetConfigurationRule", + "UnionMember1RuleSkipRule", + "UnionMember1RuleTransformResponseHTMLRule", + "UnionMember1RuleTransformResponseHTMLRuleActionParameters", + "UnionMember1RuleTransformResponseHTMLRuleExposedCredentialCheck", + "UnionMember1RuleTransformResponseHTMLRuleRatelimit", + "UnionMember2", + "UnionMember2Rule", + "UnionMember2RuleBlockRule", + "UnionMember2RuleChallengeRule", + "UnionMember2RuleChallengeRuleExposedCredentialCheck", + "UnionMember2RuleChallengeRuleRatelimit", + "UnionMember2RuleResponseCompressionRule", + "UnionMember2RuleDDoSDynamicRule", + "UnionMember2RuleExecuteRule", + "UnionMember2RuleForceConnectionCloseRule", + "UnionMember2RuleJavaScriptChallengeRule", + "UnionMember2RuleJavaScriptChallengeRuleExposedCredentialCheck", + "UnionMember2RuleJavaScriptChallengeRuleRatelimit", + "UnionMember2RuleLogRule", + "UnionMember2RuleLogCustomFieldRule", + "UnionMember2RuleManagedChallengeRule", + "UnionMember2RuleRedirectRule", + "UnionMember2RuleRewriteRule", + "UnionMember2RuleRouteRule", + "UnionMember2RuleScoreRule", + "UnionMember2RuleServeErrorRule", + "UnionMember2RuleSetCacheControlRule", + "UnionMember2RuleSetCacheControlRuleActionParameters", + "UnionMember2RuleSetCacheControlRuleActionParametersImmutable", + "UnionMember2RuleSetCacheControlRuleActionParametersImmutableSetDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersImmutableRemoveDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersMaxAge", + "UnionMember2RuleSetCacheControlRuleActionParametersMaxAgeSetDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersMaxAgeRemoveDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersMustRevalidate", + "UnionMember2RuleSetCacheControlRuleActionParametersMustRevalidateSetDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersMustRevalidateRemoveDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersMustUnderstand", + "UnionMember2RuleSetCacheControlRuleActionParametersMustUnderstandSetDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersMustUnderstandRemoveDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersNoCache", + "UnionMember2RuleSetCacheControlRuleActionParametersNoCacheSetDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersNoCacheRemoveDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersNoStore", + "UnionMember2RuleSetCacheControlRuleActionParametersNoStoreSetDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersNoStoreRemoveDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersNoTransform", + "UnionMember2RuleSetCacheControlRuleActionParametersNoTransformSetDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersNoTransformRemoveDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersPrivate", + "UnionMember2RuleSetCacheControlRuleActionParametersPrivateSetDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersPrivateRemoveDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersProxyRevalidate", + "UnionMember2RuleSetCacheControlRuleActionParametersProxyRevalidateSetDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersProxyRevalidateRemoveDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersPublic", + "UnionMember2RuleSetCacheControlRuleActionParametersPublicSetDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersPublicRemoveDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersSMaxage", + "UnionMember2RuleSetCacheControlRuleActionParametersSMaxageSetDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersSMaxageRemoveDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersStaleIfError", + "UnionMember2RuleSetCacheControlRuleActionParametersStaleIfErrorSetDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersStaleIfErrorRemoveDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersStaleWhileRevalidate", + "UnionMember2RuleSetCacheControlRuleActionParametersStaleWhileRevalidateSetDirective", + "UnionMember2RuleSetCacheControlRuleActionParametersStaleWhileRevalidateRemoveDirective", + "UnionMember2RuleSetCacheControlRuleExposedCredentialCheck", + "UnionMember2RuleSetCacheControlRuleRatelimit", + "UnionMember2RuleSetCacheSettingsRule", + "UnionMember2RuleSetCacheTagsRule", + "UnionMember2RuleSetCacheTagsRuleActionParameters", + "UnionMember2RuleSetCacheTagsRuleActionParametersAddCacheTagsValues", + "UnionMember2RuleSetCacheTagsRuleActionParametersAddCacheTagsExpression", + "UnionMember2RuleSetCacheTagsRuleActionParametersRemoveCacheTagsValues", + "UnionMember2RuleSetCacheTagsRuleActionParametersRemoveCacheTagsExpression", + "UnionMember2RuleSetCacheTagsRuleActionParametersSetCacheTagsValues", + "UnionMember2RuleSetCacheTagsRuleActionParametersSetCacheTagsExpression", + "UnionMember2RuleSetCacheTagsRuleExposedCredentialCheck", + "UnionMember2RuleSetCacheTagsRuleRatelimit", + "UnionMember2RuleSetConfigurationRule", + "UnionMember2RuleSkipRule", + "UnionMember2RuleTransformResponseHTMLRule", + "UnionMember2RuleTransformResponseHTMLRuleActionParameters", + "UnionMember2RuleTransformResponseHTMLRuleExposedCredentialCheck", + "UnionMember2RuleTransformResponseHTMLRuleRatelimit", + "UnionMember3", + "UnionMember3Rule", + "UnionMember3RuleBlockRule", + "UnionMember3RuleChallengeRule", + "UnionMember3RuleChallengeRuleExposedCredentialCheck", + "UnionMember3RuleChallengeRuleRatelimit", + "UnionMember3RuleResponseCompressionRule", + "UnionMember3RuleDDoSDynamicRule", + "UnionMember3RuleExecuteRule", + "UnionMember3RuleForceConnectionCloseRule", + "UnionMember3RuleJavaScriptChallengeRule", + "UnionMember3RuleJavaScriptChallengeRuleExposedCredentialCheck", + "UnionMember3RuleJavaScriptChallengeRuleRatelimit", + "UnionMember3RuleLogRule", + "UnionMember3RuleLogCustomFieldRule", + "UnionMember3RuleManagedChallengeRule", + "UnionMember3RuleRedirectRule", + "UnionMember3RuleRewriteRule", + "UnionMember3RuleRouteRule", + "UnionMember3RuleScoreRule", + "UnionMember3RuleServeErrorRule", + "UnionMember3RuleSetCacheControlRule", + "UnionMember3RuleSetCacheControlRuleActionParameters", + "UnionMember3RuleSetCacheControlRuleActionParametersImmutable", + "UnionMember3RuleSetCacheControlRuleActionParametersImmutableSetDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersImmutableRemoveDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersMaxAge", + "UnionMember3RuleSetCacheControlRuleActionParametersMaxAgeSetDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersMaxAgeRemoveDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersMustRevalidate", + "UnionMember3RuleSetCacheControlRuleActionParametersMustRevalidateSetDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersMustRevalidateRemoveDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersMustUnderstand", + "UnionMember3RuleSetCacheControlRuleActionParametersMustUnderstandSetDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersMustUnderstandRemoveDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersNoCache", + "UnionMember3RuleSetCacheControlRuleActionParametersNoCacheSetDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersNoCacheRemoveDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersNoStore", + "UnionMember3RuleSetCacheControlRuleActionParametersNoStoreSetDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersNoStoreRemoveDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersNoTransform", + "UnionMember3RuleSetCacheControlRuleActionParametersNoTransformSetDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersNoTransformRemoveDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersPrivate", + "UnionMember3RuleSetCacheControlRuleActionParametersPrivateSetDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersPrivateRemoveDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersProxyRevalidate", + "UnionMember3RuleSetCacheControlRuleActionParametersProxyRevalidateSetDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersProxyRevalidateRemoveDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersPublic", + "UnionMember3RuleSetCacheControlRuleActionParametersPublicSetDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersPublicRemoveDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersSMaxage", + "UnionMember3RuleSetCacheControlRuleActionParametersSMaxageSetDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersSMaxageRemoveDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersStaleIfError", + "UnionMember3RuleSetCacheControlRuleActionParametersStaleIfErrorSetDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersStaleIfErrorRemoveDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersStaleWhileRevalidate", + "UnionMember3RuleSetCacheControlRuleActionParametersStaleWhileRevalidateSetDirective", + "UnionMember3RuleSetCacheControlRuleActionParametersStaleWhileRevalidateRemoveDirective", + "UnionMember3RuleSetCacheControlRuleExposedCredentialCheck", + "UnionMember3RuleSetCacheControlRuleRatelimit", + "UnionMember3RuleSetCacheSettingsRule", + "UnionMember3RuleSetCacheTagsRule", + "UnionMember3RuleSetCacheTagsRuleActionParameters", + "UnionMember3RuleSetCacheTagsRuleActionParametersAddCacheTagsValues", + "UnionMember3RuleSetCacheTagsRuleActionParametersAddCacheTagsExpression", + "UnionMember3RuleSetCacheTagsRuleActionParametersRemoveCacheTagsValues", + "UnionMember3RuleSetCacheTagsRuleActionParametersRemoveCacheTagsExpression", + "UnionMember3RuleSetCacheTagsRuleActionParametersSetCacheTagsValues", + "UnionMember3RuleSetCacheTagsRuleActionParametersSetCacheTagsExpression", + "UnionMember3RuleSetCacheTagsRuleExposedCredentialCheck", + "UnionMember3RuleSetCacheTagsRuleRatelimit", + "UnionMember3RuleSetConfigurationRule", + "UnionMember3RuleSkipRule", + "UnionMember3RuleTransformResponseHTMLRule", + "UnionMember3RuleTransformResponseHTMLRuleActionParameters", + "UnionMember3RuleTransformResponseHTMLRuleExposedCredentialCheck", + "UnionMember3RuleTransformResponseHTMLRuleRatelimit", + "UnionMember4", + "UnionMember4Rule", + "UnionMember4RuleBlockRule", + "UnionMember4RuleChallengeRule", + "UnionMember4RuleChallengeRuleExposedCredentialCheck", + "UnionMember4RuleChallengeRuleRatelimit", + "UnionMember4RuleResponseCompressionRule", + "UnionMember4RuleDDoSDynamicRule", + "UnionMember4RuleExecuteRule", + "UnionMember4RuleForceConnectionCloseRule", + "UnionMember4RuleJavaScriptChallengeRule", + "UnionMember4RuleJavaScriptChallengeRuleExposedCredentialCheck", + "UnionMember4RuleJavaScriptChallengeRuleRatelimit", + "UnionMember4RuleLogRule", + "UnionMember4RuleLogCustomFieldRule", + "UnionMember4RuleManagedChallengeRule", + "UnionMember4RuleRedirectRule", + "UnionMember4RuleRewriteRule", + "UnionMember4RuleRouteRule", + "UnionMember4RuleScoreRule", + "UnionMember4RuleServeErrorRule", + "UnionMember4RuleSetCacheControlRule", + "UnionMember4RuleSetCacheControlRuleActionParameters", + "UnionMember4RuleSetCacheControlRuleActionParametersImmutable", + "UnionMember4RuleSetCacheControlRuleActionParametersImmutableSetDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersImmutableRemoveDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersMaxAge", + "UnionMember4RuleSetCacheControlRuleActionParametersMaxAgeSetDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersMaxAgeRemoveDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersMustRevalidate", + "UnionMember4RuleSetCacheControlRuleActionParametersMustRevalidateSetDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersMustRevalidateRemoveDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersMustUnderstand", + "UnionMember4RuleSetCacheControlRuleActionParametersMustUnderstandSetDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersMustUnderstandRemoveDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersNoCache", + "UnionMember4RuleSetCacheControlRuleActionParametersNoCacheSetDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersNoCacheRemoveDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersNoStore", + "UnionMember4RuleSetCacheControlRuleActionParametersNoStoreSetDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersNoStoreRemoveDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersNoTransform", + "UnionMember4RuleSetCacheControlRuleActionParametersNoTransformSetDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersNoTransformRemoveDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersPrivate", + "UnionMember4RuleSetCacheControlRuleActionParametersPrivateSetDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersPrivateRemoveDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersProxyRevalidate", + "UnionMember4RuleSetCacheControlRuleActionParametersProxyRevalidateSetDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersProxyRevalidateRemoveDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersPublic", + "UnionMember4RuleSetCacheControlRuleActionParametersPublicSetDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersPublicRemoveDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersSMaxage", + "UnionMember4RuleSetCacheControlRuleActionParametersSMaxageSetDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersSMaxageRemoveDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersStaleIfError", + "UnionMember4RuleSetCacheControlRuleActionParametersStaleIfErrorSetDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersStaleIfErrorRemoveDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersStaleWhileRevalidate", + "UnionMember4RuleSetCacheControlRuleActionParametersStaleWhileRevalidateSetDirective", + "UnionMember4RuleSetCacheControlRuleActionParametersStaleWhileRevalidateRemoveDirective", + "UnionMember4RuleSetCacheControlRuleExposedCredentialCheck", + "UnionMember4RuleSetCacheControlRuleRatelimit", + "UnionMember4RuleSetCacheSettingsRule", + "UnionMember4RuleSetCacheTagsRule", + "UnionMember4RuleSetCacheTagsRuleActionParameters", + "UnionMember4RuleSetCacheTagsRuleActionParametersAddCacheTagsValues", + "UnionMember4RuleSetCacheTagsRuleActionParametersAddCacheTagsExpression", + "UnionMember4RuleSetCacheTagsRuleActionParametersRemoveCacheTagsValues", + "UnionMember4RuleSetCacheTagsRuleActionParametersRemoveCacheTagsExpression", + "UnionMember4RuleSetCacheTagsRuleActionParametersSetCacheTagsValues", + "UnionMember4RuleSetCacheTagsRuleActionParametersSetCacheTagsExpression", + "UnionMember4RuleSetCacheTagsRuleExposedCredentialCheck", + "UnionMember4RuleSetCacheTagsRuleRatelimit", + "UnionMember4RuleSetConfigurationRule", + "UnionMember4RuleSkipRule", + "UnionMember4RuleTransformResponseHTMLRule", + "UnionMember4RuleTransformResponseHTMLRuleActionParameters", + "UnionMember4RuleTransformResponseHTMLRuleExposedCredentialCheck", + "UnionMember4RuleTransformResponseHTMLRuleRatelimit", +] + + +class UnionMember0RuleBlockRule(BlockRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember0RuleChallengeRuleExposedCredentialCheck(BaseModel): """Configuration for exposed credential checking.""" password_expression: str @@ -134,7 +459,7 @@ class RuleChallengeRuleExposedCredentialCheck(BaseModel): """An expression that selects the user ID used in the credentials check.""" -class RuleChallengeRuleRatelimit(BaseModel): +class UnionMember0RuleChallengeRuleRatelimit(BaseModel): """An object configuring the rule's rate limit behavior.""" characteristics: List[str] @@ -180,7 +505,7 @@ class RuleChallengeRuleRatelimit(BaseModel): """ -class RuleChallengeRule(BaseModel): +class UnionMember0RuleChallengeRule(BaseModel): id: str """The unique ID of the rule.""" @@ -211,17 +536,17 @@ class RuleChallengeRule(BaseModel): description: Optional[str] = None """An informative description of the rule.""" - exposed_credential_check: Optional[RuleChallengeRuleExposedCredentialCheck] = None + exposed_credential_check: Optional[UnionMember0RuleChallengeRuleExposedCredentialCheck] = None """Configuration for exposed credential checking.""" logging: Optional[Logging] = None """An object configuring the rule's logging behavior.""" - ratelimit: Optional[RuleChallengeRuleRatelimit] = None + ratelimit: Optional[UnionMember0RuleChallengeRuleRatelimit] = None """An object configuring the rule's rate limit behavior.""" -class RuleResponseCompressionRule(CompressResponseRule): +class UnionMember0RuleResponseCompressionRule(CompressResponseRule): id: str # type: ignore action: str # type: ignore @@ -233,7 +558,7 @@ class RuleResponseCompressionRule(CompressResponseRule): ref: str # type: ignore -class RuleDDoSDynamicRule(DDoSDynamicRule): +class UnionMember0RuleDDoSDynamicRule(DDoSDynamicRule): id: str # type: ignore action: str # type: ignore @@ -245,7 +570,7 @@ class RuleDDoSDynamicRule(DDoSDynamicRule): ref: str # type: ignore -class RuleExecuteRule(ExecuteRule): +class UnionMember0RuleExecuteRule(ExecuteRule): id: str # type: ignore action: str # type: ignore @@ -257,7 +582,7 @@ class RuleExecuteRule(ExecuteRule): ref: str # type: ignore -class RuleForceConnectionCloseRule(ForceConnectionCloseRule): +class UnionMember0RuleForceConnectionCloseRule(ForceConnectionCloseRule): id: str # type: ignore action: str # type: ignore @@ -269,7 +594,7 @@ class RuleForceConnectionCloseRule(ForceConnectionCloseRule): ref: str # type: ignore -class RuleJavaScriptChallengeRuleExposedCredentialCheck(BaseModel): +class UnionMember0RuleJavaScriptChallengeRuleExposedCredentialCheck(BaseModel): """Configuration for exposed credential checking.""" password_expression: str @@ -279,7 +604,7 @@ class RuleJavaScriptChallengeRuleExposedCredentialCheck(BaseModel): """An expression that selects the user ID used in the credentials check.""" -class RuleJavaScriptChallengeRuleRatelimit(BaseModel): +class UnionMember0RuleJavaScriptChallengeRuleRatelimit(BaseModel): """An object configuring the rule's rate limit behavior.""" characteristics: List[str] @@ -325,7 +650,7 @@ class RuleJavaScriptChallengeRuleRatelimit(BaseModel): """ -class RuleJavaScriptChallengeRule(BaseModel): +class UnionMember0RuleJavaScriptChallengeRule(BaseModel): id: str """The unique ID of the rule.""" @@ -356,17 +681,17 @@ class RuleJavaScriptChallengeRule(BaseModel): description: Optional[str] = None """An informative description of the rule.""" - exposed_credential_check: Optional[RuleJavaScriptChallengeRuleExposedCredentialCheck] = None + exposed_credential_check: Optional[UnionMember0RuleJavaScriptChallengeRuleExposedCredentialCheck] = None """Configuration for exposed credential checking.""" logging: Optional[Logging] = None """An object configuring the rule's logging behavior.""" - ratelimit: Optional[RuleJavaScriptChallengeRuleRatelimit] = None + ratelimit: Optional[UnionMember0RuleJavaScriptChallengeRuleRatelimit] = None """An object configuring the rule's rate limit behavior.""" -class RuleLogRule(LogRule): +class UnionMember0RuleLogRule(LogRule): id: str # type: ignore action: str # type: ignore @@ -378,7 +703,7 @@ class RuleLogRule(LogRule): ref: str # type: ignore -class RuleLogCustomFieldRule(LogCustomFieldRule): +class UnionMember0RuleLogCustomFieldRule(LogCustomFieldRule): id: str # type: ignore action: str # type: ignore @@ -390,7 +715,7 @@ class RuleLogCustomFieldRule(LogCustomFieldRule): ref: str # type: ignore -class RuleManagedChallengeRule(ManagedChallengeRule): +class UnionMember0RuleManagedChallengeRule(ManagedChallengeRule): id: str # type: ignore action: str # type: ignore @@ -402,7 +727,7 @@ class RuleManagedChallengeRule(ManagedChallengeRule): ref: str # type: ignore -class RuleRedirectRule(RedirectRule): +class UnionMember0RuleRedirectRule(RedirectRule): id: str # type: ignore action: str # type: ignore @@ -414,7 +739,7 @@ class RuleRedirectRule(RedirectRule): ref: str # type: ignore -class RuleRewriteRule(RewriteRule): +class UnionMember0RuleRewriteRule(RewriteRule): id: str # type: ignore action: str # type: ignore @@ -426,7 +751,7 @@ class RuleRewriteRule(RewriteRule): ref: str # type: ignore -class RuleRouteRule(RouteRule): +class UnionMember0RuleRouteRule(RouteRule): id: str # type: ignore action: str # type: ignore @@ -438,7 +763,7 @@ class RuleRouteRule(RouteRule): ref: str # type: ignore -class RuleScoreRule(ScoreRule): +class UnionMember0RuleScoreRule(ScoreRule): id: str # type: ignore action: str # type: ignore @@ -450,7 +775,7 @@ class RuleScoreRule(ScoreRule): ref: str # type: ignore -class RuleServeErrorRule(ServeErrorRule): +class UnionMember0RuleServeErrorRule(ServeErrorRule): id: str # type: ignore action: str # type: ignore @@ -462,7 +787,7 @@ class RuleServeErrorRule(ServeErrorRule): ref: str # type: ignore -class RuleSetCacheControlRuleActionParametersImmutableSetDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersImmutableSetDirective(BaseModel): """Set the directive.""" operation: Literal["set", "remove"] @@ -472,7 +797,7 @@ class RuleSetCacheControlRuleActionParametersImmutableSetDirective(BaseModel): """Whether the directive should only be applied to the Cloudflare CDN cache.""" -class RuleSetCacheControlRuleActionParametersImmutableRemoveDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersImmutableRemoveDirective(BaseModel): """Remove the directive.""" operation: Literal["set", "remove"] @@ -482,13 +807,13 @@ class RuleSetCacheControlRuleActionParametersImmutableRemoveDirective(BaseModel) """Whether the directive should only be applied to the Cloudflare CDN cache.""" -RuleSetCacheControlRuleActionParametersImmutable: TypeAlias = Union[ - RuleSetCacheControlRuleActionParametersImmutableSetDirective, - RuleSetCacheControlRuleActionParametersImmutableRemoveDirective, +UnionMember0RuleSetCacheControlRuleActionParametersImmutable: TypeAlias = Union[ + UnionMember0RuleSetCacheControlRuleActionParametersImmutableSetDirective, + UnionMember0RuleSetCacheControlRuleActionParametersImmutableRemoveDirective, ] -class RuleSetCacheControlRuleActionParametersMaxAgeSetDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersMaxAgeSetDirective(BaseModel): """Set the directive with a duration value in seconds.""" operation: Literal["set", "remove"] @@ -501,7 +826,7 @@ class RuleSetCacheControlRuleActionParametersMaxAgeSetDirective(BaseModel): """Whether the directive should only be applied to the Cloudflare CDN cache.""" -class RuleSetCacheControlRuleActionParametersMaxAgeRemoveDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersMaxAgeRemoveDirective(BaseModel): """Remove the directive.""" operation: Literal["set", "remove"] @@ -511,13 +836,13 @@ class RuleSetCacheControlRuleActionParametersMaxAgeRemoveDirective(BaseModel): """Whether the directive should only be applied to the Cloudflare CDN cache.""" -RuleSetCacheControlRuleActionParametersMaxAge: TypeAlias = Union[ - RuleSetCacheControlRuleActionParametersMaxAgeSetDirective, - RuleSetCacheControlRuleActionParametersMaxAgeRemoveDirective, +UnionMember0RuleSetCacheControlRuleActionParametersMaxAge: TypeAlias = Union[ + UnionMember0RuleSetCacheControlRuleActionParametersMaxAgeSetDirective, + UnionMember0RuleSetCacheControlRuleActionParametersMaxAgeRemoveDirective, ] -class RuleSetCacheControlRuleActionParametersMustRevalidateSetDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersMustRevalidateSetDirective(BaseModel): """Set the directive.""" operation: Literal["set", "remove"] @@ -527,7 +852,7 @@ class RuleSetCacheControlRuleActionParametersMustRevalidateSetDirective(BaseMode """Whether the directive should only be applied to the Cloudflare CDN cache.""" -class RuleSetCacheControlRuleActionParametersMustRevalidateRemoveDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersMustRevalidateRemoveDirective(BaseModel): """Remove the directive.""" operation: Literal["set", "remove"] @@ -537,13 +862,13 @@ class RuleSetCacheControlRuleActionParametersMustRevalidateRemoveDirective(BaseM """Whether the directive should only be applied to the Cloudflare CDN cache.""" -RuleSetCacheControlRuleActionParametersMustRevalidate: TypeAlias = Union[ - RuleSetCacheControlRuleActionParametersMustRevalidateSetDirective, - RuleSetCacheControlRuleActionParametersMustRevalidateRemoveDirective, +UnionMember0RuleSetCacheControlRuleActionParametersMustRevalidate: TypeAlias = Union[ + UnionMember0RuleSetCacheControlRuleActionParametersMustRevalidateSetDirective, + UnionMember0RuleSetCacheControlRuleActionParametersMustRevalidateRemoveDirective, ] -class RuleSetCacheControlRuleActionParametersMustUnderstandSetDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersMustUnderstandSetDirective(BaseModel): """Set the directive.""" operation: Literal["set", "remove"] @@ -553,7 +878,7 @@ class RuleSetCacheControlRuleActionParametersMustUnderstandSetDirective(BaseMode """Whether the directive should only be applied to the Cloudflare CDN cache.""" -class RuleSetCacheControlRuleActionParametersMustUnderstandRemoveDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersMustUnderstandRemoveDirective(BaseModel): """Remove the directive.""" operation: Literal["set", "remove"] @@ -563,13 +888,13 @@ class RuleSetCacheControlRuleActionParametersMustUnderstandRemoveDirective(BaseM """Whether the directive should only be applied to the Cloudflare CDN cache.""" -RuleSetCacheControlRuleActionParametersMustUnderstand: TypeAlias = Union[ - RuleSetCacheControlRuleActionParametersMustUnderstandSetDirective, - RuleSetCacheControlRuleActionParametersMustUnderstandRemoveDirective, +UnionMember0RuleSetCacheControlRuleActionParametersMustUnderstand: TypeAlias = Union[ + UnionMember0RuleSetCacheControlRuleActionParametersMustUnderstandSetDirective, + UnionMember0RuleSetCacheControlRuleActionParametersMustUnderstandRemoveDirective, ] -class RuleSetCacheControlRuleActionParametersNoCacheSetDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersNoCacheSetDirective(BaseModel): """Set the directive with optional qualifiers.""" operation: Literal["set", "remove"] @@ -585,7 +910,7 @@ class RuleSetCacheControlRuleActionParametersNoCacheSetDirective(BaseModel): """ -class RuleSetCacheControlRuleActionParametersNoCacheRemoveDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersNoCacheRemoveDirective(BaseModel): """Remove the directive.""" operation: Literal["set", "remove"] @@ -595,13 +920,13 @@ class RuleSetCacheControlRuleActionParametersNoCacheRemoveDirective(BaseModel): """Whether the directive should only be applied to the Cloudflare CDN cache.""" -RuleSetCacheControlRuleActionParametersNoCache: TypeAlias = Union[ - RuleSetCacheControlRuleActionParametersNoCacheSetDirective, - RuleSetCacheControlRuleActionParametersNoCacheRemoveDirective, +UnionMember0RuleSetCacheControlRuleActionParametersNoCache: TypeAlias = Union[ + UnionMember0RuleSetCacheControlRuleActionParametersNoCacheSetDirective, + UnionMember0RuleSetCacheControlRuleActionParametersNoCacheRemoveDirective, ] -class RuleSetCacheControlRuleActionParametersNoStoreSetDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersNoStoreSetDirective(BaseModel): """Set the directive.""" operation: Literal["set", "remove"] @@ -611,7 +936,7 @@ class RuleSetCacheControlRuleActionParametersNoStoreSetDirective(BaseModel): """Whether the directive should only be applied to the Cloudflare CDN cache.""" -class RuleSetCacheControlRuleActionParametersNoStoreRemoveDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersNoStoreRemoveDirective(BaseModel): """Remove the directive.""" operation: Literal["set", "remove"] @@ -621,13 +946,13 @@ class RuleSetCacheControlRuleActionParametersNoStoreRemoveDirective(BaseModel): """Whether the directive should only be applied to the Cloudflare CDN cache.""" -RuleSetCacheControlRuleActionParametersNoStore: TypeAlias = Union[ - RuleSetCacheControlRuleActionParametersNoStoreSetDirective, - RuleSetCacheControlRuleActionParametersNoStoreRemoveDirective, +UnionMember0RuleSetCacheControlRuleActionParametersNoStore: TypeAlias = Union[ + UnionMember0RuleSetCacheControlRuleActionParametersNoStoreSetDirective, + UnionMember0RuleSetCacheControlRuleActionParametersNoStoreRemoveDirective, ] -class RuleSetCacheControlRuleActionParametersNoTransformSetDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersNoTransformSetDirective(BaseModel): """Set the directive.""" operation: Literal["set", "remove"] @@ -637,7 +962,7 @@ class RuleSetCacheControlRuleActionParametersNoTransformSetDirective(BaseModel): """Whether the directive should only be applied to the Cloudflare CDN cache.""" -class RuleSetCacheControlRuleActionParametersNoTransformRemoveDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersNoTransformRemoveDirective(BaseModel): """Remove the directive.""" operation: Literal["set", "remove"] @@ -647,13 +972,13 @@ class RuleSetCacheControlRuleActionParametersNoTransformRemoveDirective(BaseMode """Whether the directive should only be applied to the Cloudflare CDN cache.""" -RuleSetCacheControlRuleActionParametersNoTransform: TypeAlias = Union[ - RuleSetCacheControlRuleActionParametersNoTransformSetDirective, - RuleSetCacheControlRuleActionParametersNoTransformRemoveDirective, +UnionMember0RuleSetCacheControlRuleActionParametersNoTransform: TypeAlias = Union[ + UnionMember0RuleSetCacheControlRuleActionParametersNoTransformSetDirective, + UnionMember0RuleSetCacheControlRuleActionParametersNoTransformRemoveDirective, ] -class RuleSetCacheControlRuleActionParametersPrivateSetDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersPrivateSetDirective(BaseModel): """Set the directive with optional qualifiers.""" operation: Literal["set", "remove"] @@ -669,7 +994,7 @@ class RuleSetCacheControlRuleActionParametersPrivateSetDirective(BaseModel): """ -class RuleSetCacheControlRuleActionParametersPrivateRemoveDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersPrivateRemoveDirective(BaseModel): """Remove the directive.""" operation: Literal["set", "remove"] @@ -679,13 +1004,13 @@ class RuleSetCacheControlRuleActionParametersPrivateRemoveDirective(BaseModel): """Whether the directive should only be applied to the Cloudflare CDN cache.""" -RuleSetCacheControlRuleActionParametersPrivate: TypeAlias = Union[ - RuleSetCacheControlRuleActionParametersPrivateSetDirective, - RuleSetCacheControlRuleActionParametersPrivateRemoveDirective, +UnionMember0RuleSetCacheControlRuleActionParametersPrivate: TypeAlias = Union[ + UnionMember0RuleSetCacheControlRuleActionParametersPrivateSetDirective, + UnionMember0RuleSetCacheControlRuleActionParametersPrivateRemoveDirective, ] -class RuleSetCacheControlRuleActionParametersProxyRevalidateSetDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersProxyRevalidateSetDirective(BaseModel): """Set the directive.""" operation: Literal["set", "remove"] @@ -695,7 +1020,7 @@ class RuleSetCacheControlRuleActionParametersProxyRevalidateSetDirective(BaseMod """Whether the directive should only be applied to the Cloudflare CDN cache.""" -class RuleSetCacheControlRuleActionParametersProxyRevalidateRemoveDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersProxyRevalidateRemoveDirective(BaseModel): """Remove the directive.""" operation: Literal["set", "remove"] @@ -705,13 +1030,13 @@ class RuleSetCacheControlRuleActionParametersProxyRevalidateRemoveDirective(Base """Whether the directive should only be applied to the Cloudflare CDN cache.""" -RuleSetCacheControlRuleActionParametersProxyRevalidate: TypeAlias = Union[ - RuleSetCacheControlRuleActionParametersProxyRevalidateSetDirective, - RuleSetCacheControlRuleActionParametersProxyRevalidateRemoveDirective, +UnionMember0RuleSetCacheControlRuleActionParametersProxyRevalidate: TypeAlias = Union[ + UnionMember0RuleSetCacheControlRuleActionParametersProxyRevalidateSetDirective, + UnionMember0RuleSetCacheControlRuleActionParametersProxyRevalidateRemoveDirective, ] -class RuleSetCacheControlRuleActionParametersPublicSetDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersPublicSetDirective(BaseModel): """Set the directive.""" operation: Literal["set", "remove"] @@ -721,7 +1046,7 @@ class RuleSetCacheControlRuleActionParametersPublicSetDirective(BaseModel): """Whether the directive should only be applied to the Cloudflare CDN cache.""" -class RuleSetCacheControlRuleActionParametersPublicRemoveDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersPublicRemoveDirective(BaseModel): """Remove the directive.""" operation: Literal["set", "remove"] @@ -731,13 +1056,13 @@ class RuleSetCacheControlRuleActionParametersPublicRemoveDirective(BaseModel): """Whether the directive should only be applied to the Cloudflare CDN cache.""" -RuleSetCacheControlRuleActionParametersPublic: TypeAlias = Union[ - RuleSetCacheControlRuleActionParametersPublicSetDirective, - RuleSetCacheControlRuleActionParametersPublicRemoveDirective, +UnionMember0RuleSetCacheControlRuleActionParametersPublic: TypeAlias = Union[ + UnionMember0RuleSetCacheControlRuleActionParametersPublicSetDirective, + UnionMember0RuleSetCacheControlRuleActionParametersPublicRemoveDirective, ] -class RuleSetCacheControlRuleActionParametersSMaxageSetDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersSMaxageSetDirective(BaseModel): """Set the directive with a duration value in seconds.""" operation: Literal["set", "remove"] @@ -750,7 +1075,7 @@ class RuleSetCacheControlRuleActionParametersSMaxageSetDirective(BaseModel): """Whether the directive should only be applied to the Cloudflare CDN cache.""" -class RuleSetCacheControlRuleActionParametersSMaxageRemoveDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersSMaxageRemoveDirective(BaseModel): """Remove the directive.""" operation: Literal["set", "remove"] @@ -760,13 +1085,13 @@ class RuleSetCacheControlRuleActionParametersSMaxageRemoveDirective(BaseModel): """Whether the directive should only be applied to the Cloudflare CDN cache.""" -RuleSetCacheControlRuleActionParametersSMaxage: TypeAlias = Union[ - RuleSetCacheControlRuleActionParametersSMaxageSetDirective, - RuleSetCacheControlRuleActionParametersSMaxageRemoveDirective, +UnionMember0RuleSetCacheControlRuleActionParametersSMaxage: TypeAlias = Union[ + UnionMember0RuleSetCacheControlRuleActionParametersSMaxageSetDirective, + UnionMember0RuleSetCacheControlRuleActionParametersSMaxageRemoveDirective, ] -class RuleSetCacheControlRuleActionParametersStaleIfErrorSetDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersStaleIfErrorSetDirective(BaseModel): """Set the directive with a duration value in seconds.""" operation: Literal["set", "remove"] @@ -779,7 +1104,7 @@ class RuleSetCacheControlRuleActionParametersStaleIfErrorSetDirective(BaseModel) """Whether the directive should only be applied to the Cloudflare CDN cache.""" -class RuleSetCacheControlRuleActionParametersStaleIfErrorRemoveDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersStaleIfErrorRemoveDirective(BaseModel): """Remove the directive.""" operation: Literal["set", "remove"] @@ -789,13 +1114,13 @@ class RuleSetCacheControlRuleActionParametersStaleIfErrorRemoveDirective(BaseMod """Whether the directive should only be applied to the Cloudflare CDN cache.""" -RuleSetCacheControlRuleActionParametersStaleIfError: TypeAlias = Union[ - RuleSetCacheControlRuleActionParametersStaleIfErrorSetDirective, - RuleSetCacheControlRuleActionParametersStaleIfErrorRemoveDirective, +UnionMember0RuleSetCacheControlRuleActionParametersStaleIfError: TypeAlias = Union[ + UnionMember0RuleSetCacheControlRuleActionParametersStaleIfErrorSetDirective, + UnionMember0RuleSetCacheControlRuleActionParametersStaleIfErrorRemoveDirective, ] -class RuleSetCacheControlRuleActionParametersStaleWhileRevalidateSetDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersStaleWhileRevalidateSetDirective(BaseModel): """Set the directive with a duration value in seconds.""" operation: Literal["set", "remove"] @@ -808,7 +1133,7 @@ class RuleSetCacheControlRuleActionParametersStaleWhileRevalidateSetDirective(Ba """Whether the directive should only be applied to the Cloudflare CDN cache.""" -class RuleSetCacheControlRuleActionParametersStaleWhileRevalidateRemoveDirective(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParametersStaleWhileRevalidateRemoveDirective(BaseModel): """Remove the directive.""" operation: Literal["set", "remove"] @@ -818,69 +1143,77 @@ class RuleSetCacheControlRuleActionParametersStaleWhileRevalidateRemoveDirective """Whether the directive should only be applied to the Cloudflare CDN cache.""" -RuleSetCacheControlRuleActionParametersStaleWhileRevalidate: TypeAlias = Union[ - RuleSetCacheControlRuleActionParametersStaleWhileRevalidateSetDirective, - RuleSetCacheControlRuleActionParametersStaleWhileRevalidateRemoveDirective, +UnionMember0RuleSetCacheControlRuleActionParametersStaleWhileRevalidate: TypeAlias = Union[ + UnionMember0RuleSetCacheControlRuleActionParametersStaleWhileRevalidateSetDirective, + UnionMember0RuleSetCacheControlRuleActionParametersStaleWhileRevalidateRemoveDirective, ] -class RuleSetCacheControlRuleActionParameters(BaseModel): +class UnionMember0RuleSetCacheControlRuleActionParameters(BaseModel): """The parameters configuring the rule's action.""" - immutable: Optional[RuleSetCacheControlRuleActionParametersImmutable] = None + immutable: Optional[UnionMember0RuleSetCacheControlRuleActionParametersImmutable] = None """A cache-control directive configuration.""" - max_age: Optional[RuleSetCacheControlRuleActionParametersMaxAge] = FieldInfo(alias="max-age", default=None) + max_age: Optional[UnionMember0RuleSetCacheControlRuleActionParametersMaxAge] = FieldInfo( + alias="max-age", default=None + ) """ A cache-control directive configuration that accepts a duration value in seconds. """ - must_revalidate: Optional[RuleSetCacheControlRuleActionParametersMustRevalidate] = FieldInfo( + must_revalidate: Optional[UnionMember0RuleSetCacheControlRuleActionParametersMustRevalidate] = FieldInfo( alias="must-revalidate", default=None ) """A cache-control directive configuration.""" - must_understand: Optional[RuleSetCacheControlRuleActionParametersMustUnderstand] = FieldInfo( + must_understand: Optional[UnionMember0RuleSetCacheControlRuleActionParametersMustUnderstand] = FieldInfo( alias="must-understand", default=None ) """A cache-control directive configuration.""" - no_cache: Optional[RuleSetCacheControlRuleActionParametersNoCache] = FieldInfo(alias="no-cache", default=None) + no_cache: Optional[UnionMember0RuleSetCacheControlRuleActionParametersNoCache] = FieldInfo( + alias="no-cache", default=None + ) """ A cache-control directive configuration that accepts optional qualifiers (header names). """ - no_store: Optional[RuleSetCacheControlRuleActionParametersNoStore] = FieldInfo(alias="no-store", default=None) + no_store: Optional[UnionMember0RuleSetCacheControlRuleActionParametersNoStore] = FieldInfo( + alias="no-store", default=None + ) """A cache-control directive configuration.""" - no_transform: Optional[RuleSetCacheControlRuleActionParametersNoTransform] = FieldInfo( + no_transform: Optional[UnionMember0RuleSetCacheControlRuleActionParametersNoTransform] = FieldInfo( alias="no-transform", default=None ) """A cache-control directive configuration.""" - private: Optional[RuleSetCacheControlRuleActionParametersPrivate] = None + private: Optional[UnionMember0RuleSetCacheControlRuleActionParametersPrivate] = None """ A cache-control directive configuration that accepts optional qualifiers (header names). """ - proxy_revalidate: Optional[RuleSetCacheControlRuleActionParametersProxyRevalidate] = FieldInfo( + proxy_revalidate: Optional[UnionMember0RuleSetCacheControlRuleActionParametersProxyRevalidate] = FieldInfo( alias="proxy-revalidate", default=None ) """A cache-control directive configuration.""" - public: Optional[RuleSetCacheControlRuleActionParametersPublic] = None + public: Optional[UnionMember0RuleSetCacheControlRuleActionParametersPublic] = None """A cache-control directive configuration.""" - s_maxage: Optional[RuleSetCacheControlRuleActionParametersSMaxage] = FieldInfo(alias="s-maxage", default=None) + s_maxage: Optional[UnionMember0RuleSetCacheControlRuleActionParametersSMaxage] = FieldInfo( + alias="s-maxage", default=None + ) """ A cache-control directive configuration that accepts a duration value in seconds. """ - stale_if_error: Optional[RuleSetCacheControlRuleActionParametersStaleIfError] = FieldInfo( + stale_if_error: Optional[UnionMember0RuleSetCacheControlRuleActionParametersStaleIfError] = FieldInfo( alias="stale-if-error", default=None ) """ @@ -888,8 +1221,8 @@ class RuleSetCacheControlRuleActionParameters(BaseModel): seconds. """ - stale_while_revalidate: Optional[RuleSetCacheControlRuleActionParametersStaleWhileRevalidate] = FieldInfo( - alias="stale-while-revalidate", default=None + stale_while_revalidate: Optional[UnionMember0RuleSetCacheControlRuleActionParametersStaleWhileRevalidate] = ( + FieldInfo(alias="stale-while-revalidate", default=None) ) """ A cache-control directive configuration that accepts a duration value in @@ -897,7 +1230,7 @@ class RuleSetCacheControlRuleActionParameters(BaseModel): """ -class RuleSetCacheControlRuleExposedCredentialCheck(BaseModel): +class UnionMember0RuleSetCacheControlRuleExposedCredentialCheck(BaseModel): """Configuration for exposed credential checking.""" password_expression: str @@ -907,7 +1240,7 @@ class RuleSetCacheControlRuleExposedCredentialCheck(BaseModel): """An expression that selects the user ID used in the credentials check.""" -class RuleSetCacheControlRuleRatelimit(BaseModel): +class UnionMember0RuleSetCacheControlRuleRatelimit(BaseModel): """An object configuring the rule's rate limit behavior.""" characteristics: List[str] @@ -953,7 +1286,7 @@ class RuleSetCacheControlRuleRatelimit(BaseModel): """ -class RuleSetCacheControlRule(BaseModel): +class UnionMember0RuleSetCacheControlRule(BaseModel): id: str """The unique ID of the rule.""" @@ -974,7 +1307,7 @@ class RuleSetCacheControlRule(BaseModel): version: str """The version of the rule.""" - action_parameters: Optional[RuleSetCacheControlRuleActionParameters] = None + action_parameters: Optional[UnionMember0RuleSetCacheControlRuleActionParameters] = None """The parameters configuring the rule's action.""" categories: Optional[List[str]] = None @@ -983,17 +1316,17 @@ class RuleSetCacheControlRule(BaseModel): description: Optional[str] = None """An informative description of the rule.""" - exposed_credential_check: Optional[RuleSetCacheControlRuleExposedCredentialCheck] = None + exposed_credential_check: Optional[UnionMember0RuleSetCacheControlRuleExposedCredentialCheck] = None """Configuration for exposed credential checking.""" logging: Optional[Logging] = None """An object configuring the rule's logging behavior.""" - ratelimit: Optional[RuleSetCacheControlRuleRatelimit] = None + ratelimit: Optional[UnionMember0RuleSetCacheControlRuleRatelimit] = None """An object configuring the rule's rate limit behavior.""" -class RuleSetCacheSettingsRule(SetCacheSettingsRule): +class UnionMember0RuleSetCacheSettingsRule(SetCacheSettingsRule): id: str # type: ignore action: str # type: ignore @@ -1005,7 +1338,7 @@ class RuleSetCacheSettingsRule(SetCacheSettingsRule): ref: str # type: ignore -class RuleSetCacheTagsRuleActionParametersAddCacheTagsValues(BaseModel): +class UnionMember0RuleSetCacheTagsRuleActionParametersAddCacheTagsValues(BaseModel): """Add cache tags using a list of values.""" operation: Literal["add", "remove", "set"] @@ -1015,7 +1348,7 @@ class RuleSetCacheTagsRuleActionParametersAddCacheTagsValues(BaseModel): """A list of cache tag values.""" -class RuleSetCacheTagsRuleActionParametersAddCacheTagsExpression(BaseModel): +class UnionMember0RuleSetCacheTagsRuleActionParametersAddCacheTagsExpression(BaseModel): """Add cache tags using an expression.""" expression: str @@ -1025,7 +1358,7 @@ class RuleSetCacheTagsRuleActionParametersAddCacheTagsExpression(BaseModel): """The operation to perform on the cache tags.""" -class RuleSetCacheTagsRuleActionParametersRemoveCacheTagsValues(BaseModel): +class UnionMember0RuleSetCacheTagsRuleActionParametersRemoveCacheTagsValues(BaseModel): """Remove cache tags using a list of values.""" operation: Literal["add", "remove", "set"] @@ -1035,7 +1368,7 @@ class RuleSetCacheTagsRuleActionParametersRemoveCacheTagsValues(BaseModel): """A list of cache tag values.""" -class RuleSetCacheTagsRuleActionParametersRemoveCacheTagsExpression(BaseModel): +class UnionMember0RuleSetCacheTagsRuleActionParametersRemoveCacheTagsExpression(BaseModel): """Remove cache tags using an expression.""" expression: str @@ -1045,7 +1378,7 @@ class RuleSetCacheTagsRuleActionParametersRemoveCacheTagsExpression(BaseModel): """The operation to perform on the cache tags.""" -class RuleSetCacheTagsRuleActionParametersSetCacheTagsValues(BaseModel): +class UnionMember0RuleSetCacheTagsRuleActionParametersSetCacheTagsValues(BaseModel): """Set cache tags using a list of values.""" operation: Literal["add", "remove", "set"] @@ -1055,7 +1388,7 @@ class RuleSetCacheTagsRuleActionParametersSetCacheTagsValues(BaseModel): """A list of cache tag values.""" -class RuleSetCacheTagsRuleActionParametersSetCacheTagsExpression(BaseModel): +class UnionMember0RuleSetCacheTagsRuleActionParametersSetCacheTagsExpression(BaseModel): """Set cache tags using an expression.""" expression: str @@ -1065,17 +1398,17 @@ class RuleSetCacheTagsRuleActionParametersSetCacheTagsExpression(BaseModel): """The operation to perform on the cache tags.""" -RuleSetCacheTagsRuleActionParameters: TypeAlias = Union[ - RuleSetCacheTagsRuleActionParametersAddCacheTagsValues, - RuleSetCacheTagsRuleActionParametersAddCacheTagsExpression, - RuleSetCacheTagsRuleActionParametersRemoveCacheTagsValues, - RuleSetCacheTagsRuleActionParametersRemoveCacheTagsExpression, - RuleSetCacheTagsRuleActionParametersSetCacheTagsValues, - RuleSetCacheTagsRuleActionParametersSetCacheTagsExpression, +UnionMember0RuleSetCacheTagsRuleActionParameters: TypeAlias = Union[ + UnionMember0RuleSetCacheTagsRuleActionParametersAddCacheTagsValues, + UnionMember0RuleSetCacheTagsRuleActionParametersAddCacheTagsExpression, + UnionMember0RuleSetCacheTagsRuleActionParametersRemoveCacheTagsValues, + UnionMember0RuleSetCacheTagsRuleActionParametersRemoveCacheTagsExpression, + UnionMember0RuleSetCacheTagsRuleActionParametersSetCacheTagsValues, + UnionMember0RuleSetCacheTagsRuleActionParametersSetCacheTagsExpression, ] -class RuleSetCacheTagsRuleExposedCredentialCheck(BaseModel): +class UnionMember0RuleSetCacheTagsRuleExposedCredentialCheck(BaseModel): """Configuration for exposed credential checking.""" password_expression: str @@ -1085,7 +1418,7 @@ class RuleSetCacheTagsRuleExposedCredentialCheck(BaseModel): """An expression that selects the user ID used in the credentials check.""" -class RuleSetCacheTagsRuleRatelimit(BaseModel): +class UnionMember0RuleSetCacheTagsRuleRatelimit(BaseModel): """An object configuring the rule's rate limit behavior.""" characteristics: List[str] @@ -1131,7 +1464,7 @@ class RuleSetCacheTagsRuleRatelimit(BaseModel): """ -class RuleSetCacheTagsRule(BaseModel): +class UnionMember0RuleSetCacheTagsRule(BaseModel): id: str """The unique ID of the rule.""" @@ -1152,7 +1485,7 @@ class RuleSetCacheTagsRule(BaseModel): version: str """The version of the rule.""" - action_parameters: Optional[RuleSetCacheTagsRuleActionParameters] = None + action_parameters: Optional[UnionMember0RuleSetCacheTagsRuleActionParameters] = None """The parameters configuring the rule's action.""" categories: Optional[List[str]] = None @@ -1161,17 +1494,17 @@ class RuleSetCacheTagsRule(BaseModel): description: Optional[str] = None """An informative description of the rule.""" - exposed_credential_check: Optional[RuleSetCacheTagsRuleExposedCredentialCheck] = None + exposed_credential_check: Optional[UnionMember0RuleSetCacheTagsRuleExposedCredentialCheck] = None """Configuration for exposed credential checking.""" logging: Optional[Logging] = None """An object configuring the rule's logging behavior.""" - ratelimit: Optional[RuleSetCacheTagsRuleRatelimit] = None + ratelimit: Optional[UnionMember0RuleSetCacheTagsRuleRatelimit] = None """An object configuring the rule's rate limit behavior.""" -class RuleSetConfigurationRule(SetConfigRule): +class UnionMember0RuleSetConfigurationRule(SetConfigRule): id: str # type: ignore action: str # type: ignore @@ -1183,7 +1516,7 @@ class RuleSetConfigurationRule(SetConfigRule): ref: str # type: ignore -class RuleSkipRule(SkipRule): +class UnionMember0RuleSkipRule(SkipRule): id: str # type: ignore action: str # type: ignore @@ -1195,14 +1528,14 @@ class RuleSkipRule(SkipRule): ref: str # type: ignore -class RuleTransformResponseHTMLRuleActionParameters(BaseModel): +class UnionMember0RuleTransformResponseHTMLRuleActionParameters(BaseModel): """The parameters configuring the rule's action.""" link_maze: object """Enables the link maze transformation on the response.""" -class RuleTransformResponseHTMLRuleExposedCredentialCheck(BaseModel): +class UnionMember0RuleTransformResponseHTMLRuleExposedCredentialCheck(BaseModel): """Configuration for exposed credential checking.""" password_expression: str @@ -1212,7 +1545,7 @@ class RuleTransformResponseHTMLRuleExposedCredentialCheck(BaseModel): """An expression that selects the user ID used in the credentials check.""" -class RuleTransformResponseHTMLRuleRatelimit(BaseModel): +class UnionMember0RuleTransformResponseHTMLRuleRatelimit(BaseModel): """An object configuring the rule's rate limit behavior.""" characteristics: List[str] @@ -1258,7 +1591,7 @@ class RuleTransformResponseHTMLRuleRatelimit(BaseModel): """ -class RuleTransformResponseHTMLRule(BaseModel): +class UnionMember0RuleTransformResponseHTMLRule(BaseModel): id: str """The unique ID of the rule.""" @@ -1279,7 +1612,7 @@ class RuleTransformResponseHTMLRule(BaseModel): version: str """The version of the rule.""" - action_parameters: Optional[RuleTransformResponseHTMLRuleActionParameters] = None + action_parameters: Optional[UnionMember0RuleTransformResponseHTMLRuleActionParameters] = None """The parameters configuring the rule's action.""" categories: Optional[List[str]] = None @@ -1288,64 +1621,5045 @@ class RuleTransformResponseHTMLRule(BaseModel): description: Optional[str] = None """An informative description of the rule.""" - exposed_credential_check: Optional[RuleTransformResponseHTMLRuleExposedCredentialCheck] = None + exposed_credential_check: Optional[UnionMember0RuleTransformResponseHTMLRuleExposedCredentialCheck] = None """Configuration for exposed credential checking.""" logging: Optional[Logging] = None """An object configuring the rule's logging behavior.""" - ratelimit: Optional[RuleTransformResponseHTMLRuleRatelimit] = None + ratelimit: Optional[UnionMember0RuleTransformResponseHTMLRuleRatelimit] = None """An object configuring the rule's rate limit behavior.""" -Rule: TypeAlias = Union[ - RuleBlockRule, - RuleChallengeRule, - RuleResponseCompressionRule, - RuleDDoSDynamicRule, - RuleExecuteRule, - RuleForceConnectionCloseRule, - RuleJavaScriptChallengeRule, - RuleLogRule, - RuleLogCustomFieldRule, - RuleManagedChallengeRule, - RuleRedirectRule, - RuleRewriteRule, - RuleRouteRule, - RuleScoreRule, - RuleServeErrorRule, - RuleSetCacheControlRule, - RuleSetCacheSettingsRule, - RuleSetCacheTagsRule, - RuleSetConfigurationRule, - RuleSkipRule, - RuleTransformResponseHTMLRule, -] - - -class VersionGetResponse(BaseModel): - """A ruleset object.""" +UnionMember0Rule: TypeAlias = Union[ + UnionMember0RuleBlockRule, + UnionMember0RuleChallengeRule, + UnionMember0RuleResponseCompressionRule, + UnionMember0RuleDDoSDynamicRule, + UnionMember0RuleExecuteRule, + UnionMember0RuleForceConnectionCloseRule, + UnionMember0RuleJavaScriptChallengeRule, + UnionMember0RuleLogRule, + UnionMember0RuleLogCustomFieldRule, + UnionMember0RuleManagedChallengeRule, + UnionMember0RuleRedirectRule, + UnionMember0RuleRewriteRule, + UnionMember0RuleRouteRule, + UnionMember0RuleScoreRule, + UnionMember0RuleServeErrorRule, + UnionMember0RuleSetCacheControlRule, + UnionMember0RuleSetCacheSettingsRule, + UnionMember0RuleSetCacheTagsRule, + UnionMember0RuleSetConfigurationRule, + UnionMember0RuleSkipRule, + UnionMember0RuleTransformResponseHTMLRule, +] - id: str + +class UnionMember0(BaseModel): + id: Optional[str] = None """The unique ID of the ruleset.""" - kind: Kind + description: Optional[str] = None + """An informative description of the ruleset.""" + + kind: Optional[Kind] = None """The kind of the ruleset.""" - last_updated: datetime + last_updated: Optional[datetime] = None """The timestamp of when the ruleset was last modified.""" - name: str + name: Optional[str] = None """The human-readable name of the ruleset.""" - phase: Phase + phase: Optional[Phase] = None """The phase of the ruleset.""" - rules: List[Rule] + rules: Optional[List[UnionMember0Rule]] = None """The list of rules in the ruleset.""" - version: str + version: Optional[str] = None """The version of the ruleset.""" + +class UnionMember1RuleBlockRule(BlockRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember1RuleChallengeRuleExposedCredentialCheck(BaseModel): + """Configuration for exposed credential checking.""" + + password_expression: str + """An expression that selects the password used in the credentials check.""" + + username_expression: str + """An expression that selects the user ID used in the credentials check.""" + + +class UnionMember1RuleChallengeRuleRatelimit(BaseModel): + """An object configuring the rule's rate limit behavior.""" + + characteristics: List[str] + """ + Characteristics of the request on which the rate limit counter will be + incremented. + """ + + period: int + """Period in seconds over which the counter is being incremented.""" + + counting_expression: Optional[str] = None + """An expression that defines when the rate limit counter should be incremented. + + It defaults to the same as the rule's expression. + """ + + mitigation_timeout: Optional[int] = None + """ + Period of time in seconds after which the action will be disabled following its + first execution. + """ + + requests_per_period: Optional[int] = None + """ + The threshold of requests per period after which the action will be executed for + the first time. + """ + + requests_to_origin: Optional[bool] = None + """Whether counting is only performed when an origin is reached.""" + + score_per_period: Optional[int] = None + """ + The score threshold per period for which the action will be executed the first + time. + """ + + score_response_header_name: Optional[str] = None + """ + A response header name provided by the origin, which contains the score to + increment rate limit counter with. + """ + + +class UnionMember1RuleChallengeRule(BaseModel): + id: str + """The unique ID of the rule.""" + + action: Literal["challenge"] + """The action to perform when the rule matches.""" + + enabled: bool + """Whether the rule should be executed.""" + + expression: str + """The expression defining which traffic will match the rule.""" + + last_updated: datetime + """The timestamp of when the rule was last modified.""" + + ref: str + """The reference of the rule (the rule's ID by default).""" + + version: str + """The version of the rule.""" + + action_parameters: Optional[object] = None + """The parameters configuring the rule's action.""" + + categories: Optional[List[str]] = None + """The categories of the rule.""" + description: Optional[str] = None - """An informative description of the ruleset.""" + """An informative description of the rule.""" + + exposed_credential_check: Optional[UnionMember1RuleChallengeRuleExposedCredentialCheck] = None + """Configuration for exposed credential checking.""" + + logging: Optional[Logging] = None + """An object configuring the rule's logging behavior.""" + + ratelimit: Optional[UnionMember1RuleChallengeRuleRatelimit] = None + """An object configuring the rule's rate limit behavior.""" + + +class UnionMember1RuleResponseCompressionRule(CompressResponseRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember1RuleDDoSDynamicRule(DDoSDynamicRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember1RuleExecuteRule(ExecuteRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember1RuleForceConnectionCloseRule(ForceConnectionCloseRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember1RuleJavaScriptChallengeRuleExposedCredentialCheck(BaseModel): + """Configuration for exposed credential checking.""" + + password_expression: str + """An expression that selects the password used in the credentials check.""" + + username_expression: str + """An expression that selects the user ID used in the credentials check.""" + + +class UnionMember1RuleJavaScriptChallengeRuleRatelimit(BaseModel): + """An object configuring the rule's rate limit behavior.""" + + characteristics: List[str] + """ + Characteristics of the request on which the rate limit counter will be + incremented. + """ + + period: int + """Period in seconds over which the counter is being incremented.""" + + counting_expression: Optional[str] = None + """An expression that defines when the rate limit counter should be incremented. + + It defaults to the same as the rule's expression. + """ + + mitigation_timeout: Optional[int] = None + """ + Period of time in seconds after which the action will be disabled following its + first execution. + """ + + requests_per_period: Optional[int] = None + """ + The threshold of requests per period after which the action will be executed for + the first time. + """ + + requests_to_origin: Optional[bool] = None + """Whether counting is only performed when an origin is reached.""" + + score_per_period: Optional[int] = None + """ + The score threshold per period for which the action will be executed the first + time. + """ + + score_response_header_name: Optional[str] = None + """ + A response header name provided by the origin, which contains the score to + increment rate limit counter with. + """ + + +class UnionMember1RuleJavaScriptChallengeRule(BaseModel): + id: str + """The unique ID of the rule.""" + + action: Literal["js_challenge"] + """The action to perform when the rule matches.""" + + enabled: bool + """Whether the rule should be executed.""" + + expression: str + """The expression defining which traffic will match the rule.""" + + last_updated: datetime + """The timestamp of when the rule was last modified.""" + + ref: str + """The reference of the rule (the rule's ID by default).""" + + version: str + """The version of the rule.""" + + action_parameters: Optional[object] = None + """The parameters configuring the rule's action.""" + + categories: Optional[List[str]] = None + """The categories of the rule.""" + + description: Optional[str] = None + """An informative description of the rule.""" + + exposed_credential_check: Optional[UnionMember1RuleJavaScriptChallengeRuleExposedCredentialCheck] = None + """Configuration for exposed credential checking.""" + + logging: Optional[Logging] = None + """An object configuring the rule's logging behavior.""" + + ratelimit: Optional[UnionMember1RuleJavaScriptChallengeRuleRatelimit] = None + """An object configuring the rule's rate limit behavior.""" + + +class UnionMember1RuleLogRule(LogRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember1RuleLogCustomFieldRule(LogCustomFieldRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember1RuleManagedChallengeRule(ManagedChallengeRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember1RuleRedirectRule(RedirectRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember1RuleRewriteRule(RewriteRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember1RuleRouteRule(RouteRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember1RuleScoreRule(ScoreRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember1RuleServeErrorRule(ServeErrorRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember1RuleSetCacheControlRuleActionParametersImmutableSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember1RuleSetCacheControlRuleActionParametersImmutableRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember1RuleSetCacheControlRuleActionParametersImmutable: TypeAlias = Union[ + UnionMember1RuleSetCacheControlRuleActionParametersImmutableSetDirective, + UnionMember1RuleSetCacheControlRuleActionParametersImmutableRemoveDirective, +] + + +class UnionMember1RuleSetCacheControlRuleActionParametersMaxAgeSetDirective(BaseModel): + """Set the directive with a duration value in seconds.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + value: int + """The duration value in seconds for the directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember1RuleSetCacheControlRuleActionParametersMaxAgeRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember1RuleSetCacheControlRuleActionParametersMaxAge: TypeAlias = Union[ + UnionMember1RuleSetCacheControlRuleActionParametersMaxAgeSetDirective, + UnionMember1RuleSetCacheControlRuleActionParametersMaxAgeRemoveDirective, +] + + +class UnionMember1RuleSetCacheControlRuleActionParametersMustRevalidateSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember1RuleSetCacheControlRuleActionParametersMustRevalidateRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember1RuleSetCacheControlRuleActionParametersMustRevalidate: TypeAlias = Union[ + UnionMember1RuleSetCacheControlRuleActionParametersMustRevalidateSetDirective, + UnionMember1RuleSetCacheControlRuleActionParametersMustRevalidateRemoveDirective, +] + + +class UnionMember1RuleSetCacheControlRuleActionParametersMustUnderstandSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember1RuleSetCacheControlRuleActionParametersMustUnderstandRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember1RuleSetCacheControlRuleActionParametersMustUnderstand: TypeAlias = Union[ + UnionMember1RuleSetCacheControlRuleActionParametersMustUnderstandSetDirective, + UnionMember1RuleSetCacheControlRuleActionParametersMustUnderstandRemoveDirective, +] + + +class UnionMember1RuleSetCacheControlRuleActionParametersNoCacheSetDirective(BaseModel): + """Set the directive with optional qualifiers.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + qualifiers: Optional[List[str]] = None + """ + Optional list of header names to qualify the directive (e.g., for "private" or + "no-cache" directives). + """ + + +class UnionMember1RuleSetCacheControlRuleActionParametersNoCacheRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember1RuleSetCacheControlRuleActionParametersNoCache: TypeAlias = Union[ + UnionMember1RuleSetCacheControlRuleActionParametersNoCacheSetDirective, + UnionMember1RuleSetCacheControlRuleActionParametersNoCacheRemoveDirective, +] + + +class UnionMember1RuleSetCacheControlRuleActionParametersNoStoreSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember1RuleSetCacheControlRuleActionParametersNoStoreRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember1RuleSetCacheControlRuleActionParametersNoStore: TypeAlias = Union[ + UnionMember1RuleSetCacheControlRuleActionParametersNoStoreSetDirective, + UnionMember1RuleSetCacheControlRuleActionParametersNoStoreRemoveDirective, +] + + +class UnionMember1RuleSetCacheControlRuleActionParametersNoTransformSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember1RuleSetCacheControlRuleActionParametersNoTransformRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember1RuleSetCacheControlRuleActionParametersNoTransform: TypeAlias = Union[ + UnionMember1RuleSetCacheControlRuleActionParametersNoTransformSetDirective, + UnionMember1RuleSetCacheControlRuleActionParametersNoTransformRemoveDirective, +] + + +class UnionMember1RuleSetCacheControlRuleActionParametersPrivateSetDirective(BaseModel): + """Set the directive with optional qualifiers.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + qualifiers: Optional[List[str]] = None + """ + Optional list of header names to qualify the directive (e.g., for "private" or + "no-cache" directives). + """ + + +class UnionMember1RuleSetCacheControlRuleActionParametersPrivateRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember1RuleSetCacheControlRuleActionParametersPrivate: TypeAlias = Union[ + UnionMember1RuleSetCacheControlRuleActionParametersPrivateSetDirective, + UnionMember1RuleSetCacheControlRuleActionParametersPrivateRemoveDirective, +] + + +class UnionMember1RuleSetCacheControlRuleActionParametersProxyRevalidateSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember1RuleSetCacheControlRuleActionParametersProxyRevalidateRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember1RuleSetCacheControlRuleActionParametersProxyRevalidate: TypeAlias = Union[ + UnionMember1RuleSetCacheControlRuleActionParametersProxyRevalidateSetDirective, + UnionMember1RuleSetCacheControlRuleActionParametersProxyRevalidateRemoveDirective, +] + + +class UnionMember1RuleSetCacheControlRuleActionParametersPublicSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember1RuleSetCacheControlRuleActionParametersPublicRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember1RuleSetCacheControlRuleActionParametersPublic: TypeAlias = Union[ + UnionMember1RuleSetCacheControlRuleActionParametersPublicSetDirective, + UnionMember1RuleSetCacheControlRuleActionParametersPublicRemoveDirective, +] + + +class UnionMember1RuleSetCacheControlRuleActionParametersSMaxageSetDirective(BaseModel): + """Set the directive with a duration value in seconds.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + value: int + """The duration value in seconds for the directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember1RuleSetCacheControlRuleActionParametersSMaxageRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember1RuleSetCacheControlRuleActionParametersSMaxage: TypeAlias = Union[ + UnionMember1RuleSetCacheControlRuleActionParametersSMaxageSetDirective, + UnionMember1RuleSetCacheControlRuleActionParametersSMaxageRemoveDirective, +] + + +class UnionMember1RuleSetCacheControlRuleActionParametersStaleIfErrorSetDirective(BaseModel): + """Set the directive with a duration value in seconds.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + value: int + """The duration value in seconds for the directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember1RuleSetCacheControlRuleActionParametersStaleIfErrorRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember1RuleSetCacheControlRuleActionParametersStaleIfError: TypeAlias = Union[ + UnionMember1RuleSetCacheControlRuleActionParametersStaleIfErrorSetDirective, + UnionMember1RuleSetCacheControlRuleActionParametersStaleIfErrorRemoveDirective, +] + + +class UnionMember1RuleSetCacheControlRuleActionParametersStaleWhileRevalidateSetDirective(BaseModel): + """Set the directive with a duration value in seconds.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + value: int + """The duration value in seconds for the directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember1RuleSetCacheControlRuleActionParametersStaleWhileRevalidateRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember1RuleSetCacheControlRuleActionParametersStaleWhileRevalidate: TypeAlias = Union[ + UnionMember1RuleSetCacheControlRuleActionParametersStaleWhileRevalidateSetDirective, + UnionMember1RuleSetCacheControlRuleActionParametersStaleWhileRevalidateRemoveDirective, +] + + +class UnionMember1RuleSetCacheControlRuleActionParameters(BaseModel): + """The parameters configuring the rule's action.""" + + immutable: Optional[UnionMember1RuleSetCacheControlRuleActionParametersImmutable] = None + """A cache-control directive configuration.""" + + max_age: Optional[UnionMember1RuleSetCacheControlRuleActionParametersMaxAge] = FieldInfo( + alias="max-age", default=None + ) + """ + A cache-control directive configuration that accepts a duration value in + seconds. + """ + + must_revalidate: Optional[UnionMember1RuleSetCacheControlRuleActionParametersMustRevalidate] = FieldInfo( + alias="must-revalidate", default=None + ) + """A cache-control directive configuration.""" + + must_understand: Optional[UnionMember1RuleSetCacheControlRuleActionParametersMustUnderstand] = FieldInfo( + alias="must-understand", default=None + ) + """A cache-control directive configuration.""" + + no_cache: Optional[UnionMember1RuleSetCacheControlRuleActionParametersNoCache] = FieldInfo( + alias="no-cache", default=None + ) + """ + A cache-control directive configuration that accepts optional qualifiers (header + names). + """ + + no_store: Optional[UnionMember1RuleSetCacheControlRuleActionParametersNoStore] = FieldInfo( + alias="no-store", default=None + ) + """A cache-control directive configuration.""" + + no_transform: Optional[UnionMember1RuleSetCacheControlRuleActionParametersNoTransform] = FieldInfo( + alias="no-transform", default=None + ) + """A cache-control directive configuration.""" + + private: Optional[UnionMember1RuleSetCacheControlRuleActionParametersPrivate] = None + """ + A cache-control directive configuration that accepts optional qualifiers (header + names). + """ + + proxy_revalidate: Optional[UnionMember1RuleSetCacheControlRuleActionParametersProxyRevalidate] = FieldInfo( + alias="proxy-revalidate", default=None + ) + """A cache-control directive configuration.""" + + public: Optional[UnionMember1RuleSetCacheControlRuleActionParametersPublic] = None + """A cache-control directive configuration.""" + + s_maxage: Optional[UnionMember1RuleSetCacheControlRuleActionParametersSMaxage] = FieldInfo( + alias="s-maxage", default=None + ) + """ + A cache-control directive configuration that accepts a duration value in + seconds. + """ + + stale_if_error: Optional[UnionMember1RuleSetCacheControlRuleActionParametersStaleIfError] = FieldInfo( + alias="stale-if-error", default=None + ) + """ + A cache-control directive configuration that accepts a duration value in + seconds. + """ + + stale_while_revalidate: Optional[UnionMember1RuleSetCacheControlRuleActionParametersStaleWhileRevalidate] = ( + FieldInfo(alias="stale-while-revalidate", default=None) + ) + """ + A cache-control directive configuration that accepts a duration value in + seconds. + """ + + +class UnionMember1RuleSetCacheControlRuleExposedCredentialCheck(BaseModel): + """Configuration for exposed credential checking.""" + + password_expression: str + """An expression that selects the password used in the credentials check.""" + + username_expression: str + """An expression that selects the user ID used in the credentials check.""" + + +class UnionMember1RuleSetCacheControlRuleRatelimit(BaseModel): + """An object configuring the rule's rate limit behavior.""" + + characteristics: List[str] + """ + Characteristics of the request on which the rate limit counter will be + incremented. + """ + + period: int + """Period in seconds over which the counter is being incremented.""" + + counting_expression: Optional[str] = None + """An expression that defines when the rate limit counter should be incremented. + + It defaults to the same as the rule's expression. + """ + + mitigation_timeout: Optional[int] = None + """ + Period of time in seconds after which the action will be disabled following its + first execution. + """ + + requests_per_period: Optional[int] = None + """ + The threshold of requests per period after which the action will be executed for + the first time. + """ + + requests_to_origin: Optional[bool] = None + """Whether counting is only performed when an origin is reached.""" + + score_per_period: Optional[int] = None + """ + The score threshold per period for which the action will be executed the first + time. + """ + + score_response_header_name: Optional[str] = None + """ + A response header name provided by the origin, which contains the score to + increment rate limit counter with. + """ + + +class UnionMember1RuleSetCacheControlRule(BaseModel): + id: str + """The unique ID of the rule.""" + + action: Literal["set_cache_control"] + """The action to perform when the rule matches.""" + + enabled: bool + + expression: str + """The expression defining which traffic will match the rule.""" + + last_updated: datetime + """The timestamp of when the rule was last modified.""" + + ref: str + """The reference of the rule (the rule's ID by default).""" + + version: str + """The version of the rule.""" + + action_parameters: Optional[UnionMember1RuleSetCacheControlRuleActionParameters] = None + """The parameters configuring the rule's action.""" + + categories: Optional[List[str]] = None + """The categories of the rule.""" + + description: Optional[str] = None + """An informative description of the rule.""" + + exposed_credential_check: Optional[UnionMember1RuleSetCacheControlRuleExposedCredentialCheck] = None + """Configuration for exposed credential checking.""" + + logging: Optional[Logging] = None + """An object configuring the rule's logging behavior.""" + + ratelimit: Optional[UnionMember1RuleSetCacheControlRuleRatelimit] = None + """An object configuring the rule's rate limit behavior.""" + + +class UnionMember1RuleSetCacheSettingsRule(SetCacheSettingsRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember1RuleSetCacheTagsRuleActionParametersAddCacheTagsValues(BaseModel): + """Add cache tags using a list of values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + values: List[str] + """A list of cache tag values.""" + + +class UnionMember1RuleSetCacheTagsRuleActionParametersAddCacheTagsExpression(BaseModel): + """Add cache tags using an expression.""" + + expression: str + """An expression that evaluates to an array of cache tag values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + +class UnionMember1RuleSetCacheTagsRuleActionParametersRemoveCacheTagsValues(BaseModel): + """Remove cache tags using a list of values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + values: List[str] + """A list of cache tag values.""" + + +class UnionMember1RuleSetCacheTagsRuleActionParametersRemoveCacheTagsExpression(BaseModel): + """Remove cache tags using an expression.""" + + expression: str + """An expression that evaluates to an array of cache tag values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + +class UnionMember1RuleSetCacheTagsRuleActionParametersSetCacheTagsValues(BaseModel): + """Set cache tags using a list of values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + values: List[str] + """A list of cache tag values.""" + + +class UnionMember1RuleSetCacheTagsRuleActionParametersSetCacheTagsExpression(BaseModel): + """Set cache tags using an expression.""" + + expression: str + """An expression that evaluates to an array of cache tag values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + +UnionMember1RuleSetCacheTagsRuleActionParameters: TypeAlias = Union[ + UnionMember1RuleSetCacheTagsRuleActionParametersAddCacheTagsValues, + UnionMember1RuleSetCacheTagsRuleActionParametersAddCacheTagsExpression, + UnionMember1RuleSetCacheTagsRuleActionParametersRemoveCacheTagsValues, + UnionMember1RuleSetCacheTagsRuleActionParametersRemoveCacheTagsExpression, + UnionMember1RuleSetCacheTagsRuleActionParametersSetCacheTagsValues, + UnionMember1RuleSetCacheTagsRuleActionParametersSetCacheTagsExpression, +] + + +class UnionMember1RuleSetCacheTagsRuleExposedCredentialCheck(BaseModel): + """Configuration for exposed credential checking.""" + + password_expression: str + """An expression that selects the password used in the credentials check.""" + + username_expression: str + """An expression that selects the user ID used in the credentials check.""" + + +class UnionMember1RuleSetCacheTagsRuleRatelimit(BaseModel): + """An object configuring the rule's rate limit behavior.""" + + characteristics: List[str] + """ + Characteristics of the request on which the rate limit counter will be + incremented. + """ + + period: int + """Period in seconds over which the counter is being incremented.""" + + counting_expression: Optional[str] = None + """An expression that defines when the rate limit counter should be incremented. + + It defaults to the same as the rule's expression. + """ + + mitigation_timeout: Optional[int] = None + """ + Period of time in seconds after which the action will be disabled following its + first execution. + """ + + requests_per_period: Optional[int] = None + """ + The threshold of requests per period after which the action will be executed for + the first time. + """ + + requests_to_origin: Optional[bool] = None + """Whether counting is only performed when an origin is reached.""" + + score_per_period: Optional[int] = None + """ + The score threshold per period for which the action will be executed the first + time. + """ + + score_response_header_name: Optional[str] = None + """ + A response header name provided by the origin, which contains the score to + increment rate limit counter with. + """ + + +class UnionMember1RuleSetCacheTagsRule(BaseModel): + id: str + """The unique ID of the rule.""" + + action: Literal["set_cache_tags"] + """The action to perform when the rule matches.""" + + enabled: bool + + expression: str + """The expression defining which traffic will match the rule.""" + + last_updated: datetime + """The timestamp of when the rule was last modified.""" + + ref: str + """The reference of the rule (the rule's ID by default).""" + + version: str + """The version of the rule.""" + + action_parameters: Optional[UnionMember1RuleSetCacheTagsRuleActionParameters] = None + """The parameters configuring the rule's action.""" + + categories: Optional[List[str]] = None + """The categories of the rule.""" + + description: Optional[str] = None + """An informative description of the rule.""" + + exposed_credential_check: Optional[UnionMember1RuleSetCacheTagsRuleExposedCredentialCheck] = None + """Configuration for exposed credential checking.""" + + logging: Optional[Logging] = None + """An object configuring the rule's logging behavior.""" + + ratelimit: Optional[UnionMember1RuleSetCacheTagsRuleRatelimit] = None + """An object configuring the rule's rate limit behavior.""" + + +class UnionMember1RuleSetConfigurationRule(SetConfigRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember1RuleSkipRule(SkipRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember1RuleTransformResponseHTMLRuleActionParameters(BaseModel): + """The parameters configuring the rule's action.""" + + link_maze: object + """Enables the link maze transformation on the response.""" + + +class UnionMember1RuleTransformResponseHTMLRuleExposedCredentialCheck(BaseModel): + """Configuration for exposed credential checking.""" + + password_expression: str + """An expression that selects the password used in the credentials check.""" + + username_expression: str + """An expression that selects the user ID used in the credentials check.""" + + +class UnionMember1RuleTransformResponseHTMLRuleRatelimit(BaseModel): + """An object configuring the rule's rate limit behavior.""" + + characteristics: List[str] + """ + Characteristics of the request on which the rate limit counter will be + incremented. + """ + + period: int + """Period in seconds over which the counter is being incremented.""" + + counting_expression: Optional[str] = None + """An expression that defines when the rate limit counter should be incremented. + + It defaults to the same as the rule's expression. + """ + + mitigation_timeout: Optional[int] = None + """ + Period of time in seconds after which the action will be disabled following its + first execution. + """ + + requests_per_period: Optional[int] = None + """ + The threshold of requests per period after which the action will be executed for + the first time. + """ + + requests_to_origin: Optional[bool] = None + """Whether counting is only performed when an origin is reached.""" + + score_per_period: Optional[int] = None + """ + The score threshold per period for which the action will be executed the first + time. + """ + + score_response_header_name: Optional[str] = None + """ + A response header name provided by the origin, which contains the score to + increment rate limit counter with. + """ + + +class UnionMember1RuleTransformResponseHTMLRule(BaseModel): + id: str + """The unique ID of the rule.""" + + action: Literal["transform_response_html"] + """The action to perform when the rule matches.""" + + enabled: bool + + expression: str + """The expression defining which traffic will match the rule.""" + + last_updated: datetime + """The timestamp of when the rule was last modified.""" + + ref: str + """The reference of the rule (the rule's ID by default).""" + + version: str + """The version of the rule.""" + + action_parameters: Optional[UnionMember1RuleTransformResponseHTMLRuleActionParameters] = None + """The parameters configuring the rule's action.""" + + categories: Optional[List[str]] = None + """The categories of the rule.""" + + description: Optional[str] = None + """An informative description of the rule.""" + + exposed_credential_check: Optional[UnionMember1RuleTransformResponseHTMLRuleExposedCredentialCheck] = None + """Configuration for exposed credential checking.""" + + logging: Optional[Logging] = None + """An object configuring the rule's logging behavior.""" + + ratelimit: Optional[UnionMember1RuleTransformResponseHTMLRuleRatelimit] = None + """An object configuring the rule's rate limit behavior.""" + + +UnionMember1Rule: TypeAlias = Union[ + UnionMember1RuleBlockRule, + UnionMember1RuleChallengeRule, + UnionMember1RuleResponseCompressionRule, + UnionMember1RuleDDoSDynamicRule, + UnionMember1RuleExecuteRule, + UnionMember1RuleForceConnectionCloseRule, + UnionMember1RuleJavaScriptChallengeRule, + UnionMember1RuleLogRule, + UnionMember1RuleLogCustomFieldRule, + UnionMember1RuleManagedChallengeRule, + UnionMember1RuleRedirectRule, + UnionMember1RuleRewriteRule, + UnionMember1RuleRouteRule, + UnionMember1RuleScoreRule, + UnionMember1RuleServeErrorRule, + UnionMember1RuleSetCacheControlRule, + UnionMember1RuleSetCacheSettingsRule, + UnionMember1RuleSetCacheTagsRule, + UnionMember1RuleSetConfigurationRule, + UnionMember1RuleSkipRule, + UnionMember1RuleTransformResponseHTMLRule, +] + + +class UnionMember1(BaseModel): + id: Optional[str] = None + """The unique ID of the ruleset.""" + + description: Optional[str] = None + """An informative description of the ruleset.""" + + kind: Optional[Kind] = None + """The kind of the ruleset.""" + + last_updated: Optional[datetime] = None + """The timestamp of when the ruleset was last modified.""" + + name: Optional[str] = None + """The human-readable name of the ruleset.""" + + phase: Optional[Phase] = None + """The phase of the ruleset.""" + + rules: Optional[List[UnionMember1Rule]] = None + """The list of rules in the ruleset.""" + + version: Optional[str] = None + """The version of the ruleset.""" + + +class UnionMember2RuleBlockRule(BlockRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember2RuleChallengeRuleExposedCredentialCheck(BaseModel): + """Configuration for exposed credential checking.""" + + password_expression: str + """An expression that selects the password used in the credentials check.""" + + username_expression: str + """An expression that selects the user ID used in the credentials check.""" + + +class UnionMember2RuleChallengeRuleRatelimit(BaseModel): + """An object configuring the rule's rate limit behavior.""" + + characteristics: List[str] + """ + Characteristics of the request on which the rate limit counter will be + incremented. + """ + + period: int + """Period in seconds over which the counter is being incremented.""" + + counting_expression: Optional[str] = None + """An expression that defines when the rate limit counter should be incremented. + + It defaults to the same as the rule's expression. + """ + + mitigation_timeout: Optional[int] = None + """ + Period of time in seconds after which the action will be disabled following its + first execution. + """ + + requests_per_period: Optional[int] = None + """ + The threshold of requests per period after which the action will be executed for + the first time. + """ + + requests_to_origin: Optional[bool] = None + """Whether counting is only performed when an origin is reached.""" + + score_per_period: Optional[int] = None + """ + The score threshold per period for which the action will be executed the first + time. + """ + + score_response_header_name: Optional[str] = None + """ + A response header name provided by the origin, which contains the score to + increment rate limit counter with. + """ + + +class UnionMember2RuleChallengeRule(BaseModel): + id: str + """The unique ID of the rule.""" + + action: Literal["challenge"] + """The action to perform when the rule matches.""" + + enabled: bool + """Whether the rule should be executed.""" + + expression: str + """The expression defining which traffic will match the rule.""" + + last_updated: datetime + """The timestamp of when the rule was last modified.""" + + ref: str + """The reference of the rule (the rule's ID by default).""" + + version: str + """The version of the rule.""" + + action_parameters: Optional[object] = None + """The parameters configuring the rule's action.""" + + categories: Optional[List[str]] = None + """The categories of the rule.""" + + description: Optional[str] = None + """An informative description of the rule.""" + + exposed_credential_check: Optional[UnionMember2RuleChallengeRuleExposedCredentialCheck] = None + """Configuration for exposed credential checking.""" + + logging: Optional[Logging] = None + """An object configuring the rule's logging behavior.""" + + ratelimit: Optional[UnionMember2RuleChallengeRuleRatelimit] = None + """An object configuring the rule's rate limit behavior.""" + + +class UnionMember2RuleResponseCompressionRule(CompressResponseRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember2RuleDDoSDynamicRule(DDoSDynamicRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember2RuleExecuteRule(ExecuteRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember2RuleForceConnectionCloseRule(ForceConnectionCloseRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember2RuleJavaScriptChallengeRuleExposedCredentialCheck(BaseModel): + """Configuration for exposed credential checking.""" + + password_expression: str + """An expression that selects the password used in the credentials check.""" + + username_expression: str + """An expression that selects the user ID used in the credentials check.""" + + +class UnionMember2RuleJavaScriptChallengeRuleRatelimit(BaseModel): + """An object configuring the rule's rate limit behavior.""" + + characteristics: List[str] + """ + Characteristics of the request on which the rate limit counter will be + incremented. + """ + + period: int + """Period in seconds over which the counter is being incremented.""" + + counting_expression: Optional[str] = None + """An expression that defines when the rate limit counter should be incremented. + + It defaults to the same as the rule's expression. + """ + + mitigation_timeout: Optional[int] = None + """ + Period of time in seconds after which the action will be disabled following its + first execution. + """ + + requests_per_period: Optional[int] = None + """ + The threshold of requests per period after which the action will be executed for + the first time. + """ + + requests_to_origin: Optional[bool] = None + """Whether counting is only performed when an origin is reached.""" + + score_per_period: Optional[int] = None + """ + The score threshold per period for which the action will be executed the first + time. + """ + + score_response_header_name: Optional[str] = None + """ + A response header name provided by the origin, which contains the score to + increment rate limit counter with. + """ + + +class UnionMember2RuleJavaScriptChallengeRule(BaseModel): + id: str + """The unique ID of the rule.""" + + action: Literal["js_challenge"] + """The action to perform when the rule matches.""" + + enabled: bool + """Whether the rule should be executed.""" + + expression: str + """The expression defining which traffic will match the rule.""" + + last_updated: datetime + """The timestamp of when the rule was last modified.""" + + ref: str + """The reference of the rule (the rule's ID by default).""" + + version: str + """The version of the rule.""" + + action_parameters: Optional[object] = None + """The parameters configuring the rule's action.""" + + categories: Optional[List[str]] = None + """The categories of the rule.""" + + description: Optional[str] = None + """An informative description of the rule.""" + + exposed_credential_check: Optional[UnionMember2RuleJavaScriptChallengeRuleExposedCredentialCheck] = None + """Configuration for exposed credential checking.""" + + logging: Optional[Logging] = None + """An object configuring the rule's logging behavior.""" + + ratelimit: Optional[UnionMember2RuleJavaScriptChallengeRuleRatelimit] = None + """An object configuring the rule's rate limit behavior.""" + + +class UnionMember2RuleLogRule(LogRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember2RuleLogCustomFieldRule(LogCustomFieldRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember2RuleManagedChallengeRule(ManagedChallengeRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember2RuleRedirectRule(RedirectRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember2RuleRewriteRule(RewriteRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember2RuleRouteRule(RouteRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember2RuleScoreRule(ScoreRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember2RuleServeErrorRule(ServeErrorRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember2RuleSetCacheControlRuleActionParametersImmutableSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember2RuleSetCacheControlRuleActionParametersImmutableRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember2RuleSetCacheControlRuleActionParametersImmutable: TypeAlias = Union[ + UnionMember2RuleSetCacheControlRuleActionParametersImmutableSetDirective, + UnionMember2RuleSetCacheControlRuleActionParametersImmutableRemoveDirective, +] + + +class UnionMember2RuleSetCacheControlRuleActionParametersMaxAgeSetDirective(BaseModel): + """Set the directive with a duration value in seconds.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + value: int + """The duration value in seconds for the directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember2RuleSetCacheControlRuleActionParametersMaxAgeRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember2RuleSetCacheControlRuleActionParametersMaxAge: TypeAlias = Union[ + UnionMember2RuleSetCacheControlRuleActionParametersMaxAgeSetDirective, + UnionMember2RuleSetCacheControlRuleActionParametersMaxAgeRemoveDirective, +] + + +class UnionMember2RuleSetCacheControlRuleActionParametersMustRevalidateSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember2RuleSetCacheControlRuleActionParametersMustRevalidateRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember2RuleSetCacheControlRuleActionParametersMustRevalidate: TypeAlias = Union[ + UnionMember2RuleSetCacheControlRuleActionParametersMustRevalidateSetDirective, + UnionMember2RuleSetCacheControlRuleActionParametersMustRevalidateRemoveDirective, +] + + +class UnionMember2RuleSetCacheControlRuleActionParametersMustUnderstandSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember2RuleSetCacheControlRuleActionParametersMustUnderstandRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember2RuleSetCacheControlRuleActionParametersMustUnderstand: TypeAlias = Union[ + UnionMember2RuleSetCacheControlRuleActionParametersMustUnderstandSetDirective, + UnionMember2RuleSetCacheControlRuleActionParametersMustUnderstandRemoveDirective, +] + + +class UnionMember2RuleSetCacheControlRuleActionParametersNoCacheSetDirective(BaseModel): + """Set the directive with optional qualifiers.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + qualifiers: Optional[List[str]] = None + """ + Optional list of header names to qualify the directive (e.g., for "private" or + "no-cache" directives). + """ + + +class UnionMember2RuleSetCacheControlRuleActionParametersNoCacheRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember2RuleSetCacheControlRuleActionParametersNoCache: TypeAlias = Union[ + UnionMember2RuleSetCacheControlRuleActionParametersNoCacheSetDirective, + UnionMember2RuleSetCacheControlRuleActionParametersNoCacheRemoveDirective, +] + + +class UnionMember2RuleSetCacheControlRuleActionParametersNoStoreSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember2RuleSetCacheControlRuleActionParametersNoStoreRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember2RuleSetCacheControlRuleActionParametersNoStore: TypeAlias = Union[ + UnionMember2RuleSetCacheControlRuleActionParametersNoStoreSetDirective, + UnionMember2RuleSetCacheControlRuleActionParametersNoStoreRemoveDirective, +] + + +class UnionMember2RuleSetCacheControlRuleActionParametersNoTransformSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember2RuleSetCacheControlRuleActionParametersNoTransformRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember2RuleSetCacheControlRuleActionParametersNoTransform: TypeAlias = Union[ + UnionMember2RuleSetCacheControlRuleActionParametersNoTransformSetDirective, + UnionMember2RuleSetCacheControlRuleActionParametersNoTransformRemoveDirective, +] + + +class UnionMember2RuleSetCacheControlRuleActionParametersPrivateSetDirective(BaseModel): + """Set the directive with optional qualifiers.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + qualifiers: Optional[List[str]] = None + """ + Optional list of header names to qualify the directive (e.g., for "private" or + "no-cache" directives). + """ + + +class UnionMember2RuleSetCacheControlRuleActionParametersPrivateRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember2RuleSetCacheControlRuleActionParametersPrivate: TypeAlias = Union[ + UnionMember2RuleSetCacheControlRuleActionParametersPrivateSetDirective, + UnionMember2RuleSetCacheControlRuleActionParametersPrivateRemoveDirective, +] + + +class UnionMember2RuleSetCacheControlRuleActionParametersProxyRevalidateSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember2RuleSetCacheControlRuleActionParametersProxyRevalidateRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember2RuleSetCacheControlRuleActionParametersProxyRevalidate: TypeAlias = Union[ + UnionMember2RuleSetCacheControlRuleActionParametersProxyRevalidateSetDirective, + UnionMember2RuleSetCacheControlRuleActionParametersProxyRevalidateRemoveDirective, +] + + +class UnionMember2RuleSetCacheControlRuleActionParametersPublicSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember2RuleSetCacheControlRuleActionParametersPublicRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember2RuleSetCacheControlRuleActionParametersPublic: TypeAlias = Union[ + UnionMember2RuleSetCacheControlRuleActionParametersPublicSetDirective, + UnionMember2RuleSetCacheControlRuleActionParametersPublicRemoveDirective, +] + + +class UnionMember2RuleSetCacheControlRuleActionParametersSMaxageSetDirective(BaseModel): + """Set the directive with a duration value in seconds.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + value: int + """The duration value in seconds for the directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember2RuleSetCacheControlRuleActionParametersSMaxageRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember2RuleSetCacheControlRuleActionParametersSMaxage: TypeAlias = Union[ + UnionMember2RuleSetCacheControlRuleActionParametersSMaxageSetDirective, + UnionMember2RuleSetCacheControlRuleActionParametersSMaxageRemoveDirective, +] + + +class UnionMember2RuleSetCacheControlRuleActionParametersStaleIfErrorSetDirective(BaseModel): + """Set the directive with a duration value in seconds.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + value: int + """The duration value in seconds for the directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember2RuleSetCacheControlRuleActionParametersStaleIfErrorRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember2RuleSetCacheControlRuleActionParametersStaleIfError: TypeAlias = Union[ + UnionMember2RuleSetCacheControlRuleActionParametersStaleIfErrorSetDirective, + UnionMember2RuleSetCacheControlRuleActionParametersStaleIfErrorRemoveDirective, +] + + +class UnionMember2RuleSetCacheControlRuleActionParametersStaleWhileRevalidateSetDirective(BaseModel): + """Set the directive with a duration value in seconds.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + value: int + """The duration value in seconds for the directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember2RuleSetCacheControlRuleActionParametersStaleWhileRevalidateRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember2RuleSetCacheControlRuleActionParametersStaleWhileRevalidate: TypeAlias = Union[ + UnionMember2RuleSetCacheControlRuleActionParametersStaleWhileRevalidateSetDirective, + UnionMember2RuleSetCacheControlRuleActionParametersStaleWhileRevalidateRemoveDirective, +] + + +class UnionMember2RuleSetCacheControlRuleActionParameters(BaseModel): + """The parameters configuring the rule's action.""" + + immutable: Optional[UnionMember2RuleSetCacheControlRuleActionParametersImmutable] = None + """A cache-control directive configuration.""" + + max_age: Optional[UnionMember2RuleSetCacheControlRuleActionParametersMaxAge] = FieldInfo( + alias="max-age", default=None + ) + """ + A cache-control directive configuration that accepts a duration value in + seconds. + """ + + must_revalidate: Optional[UnionMember2RuleSetCacheControlRuleActionParametersMustRevalidate] = FieldInfo( + alias="must-revalidate", default=None + ) + """A cache-control directive configuration.""" + + must_understand: Optional[UnionMember2RuleSetCacheControlRuleActionParametersMustUnderstand] = FieldInfo( + alias="must-understand", default=None + ) + """A cache-control directive configuration.""" + + no_cache: Optional[UnionMember2RuleSetCacheControlRuleActionParametersNoCache] = FieldInfo( + alias="no-cache", default=None + ) + """ + A cache-control directive configuration that accepts optional qualifiers (header + names). + """ + + no_store: Optional[UnionMember2RuleSetCacheControlRuleActionParametersNoStore] = FieldInfo( + alias="no-store", default=None + ) + """A cache-control directive configuration.""" + + no_transform: Optional[UnionMember2RuleSetCacheControlRuleActionParametersNoTransform] = FieldInfo( + alias="no-transform", default=None + ) + """A cache-control directive configuration.""" + + private: Optional[UnionMember2RuleSetCacheControlRuleActionParametersPrivate] = None + """ + A cache-control directive configuration that accepts optional qualifiers (header + names). + """ + + proxy_revalidate: Optional[UnionMember2RuleSetCacheControlRuleActionParametersProxyRevalidate] = FieldInfo( + alias="proxy-revalidate", default=None + ) + """A cache-control directive configuration.""" + + public: Optional[UnionMember2RuleSetCacheControlRuleActionParametersPublic] = None + """A cache-control directive configuration.""" + + s_maxage: Optional[UnionMember2RuleSetCacheControlRuleActionParametersSMaxage] = FieldInfo( + alias="s-maxage", default=None + ) + """ + A cache-control directive configuration that accepts a duration value in + seconds. + """ + + stale_if_error: Optional[UnionMember2RuleSetCacheControlRuleActionParametersStaleIfError] = FieldInfo( + alias="stale-if-error", default=None + ) + """ + A cache-control directive configuration that accepts a duration value in + seconds. + """ + + stale_while_revalidate: Optional[UnionMember2RuleSetCacheControlRuleActionParametersStaleWhileRevalidate] = ( + FieldInfo(alias="stale-while-revalidate", default=None) + ) + """ + A cache-control directive configuration that accepts a duration value in + seconds. + """ + + +class UnionMember2RuleSetCacheControlRuleExposedCredentialCheck(BaseModel): + """Configuration for exposed credential checking.""" + + password_expression: str + """An expression that selects the password used in the credentials check.""" + + username_expression: str + """An expression that selects the user ID used in the credentials check.""" + + +class UnionMember2RuleSetCacheControlRuleRatelimit(BaseModel): + """An object configuring the rule's rate limit behavior.""" + + characteristics: List[str] + """ + Characteristics of the request on which the rate limit counter will be + incremented. + """ + + period: int + """Period in seconds over which the counter is being incremented.""" + + counting_expression: Optional[str] = None + """An expression that defines when the rate limit counter should be incremented. + + It defaults to the same as the rule's expression. + """ + + mitigation_timeout: Optional[int] = None + """ + Period of time in seconds after which the action will be disabled following its + first execution. + """ + + requests_per_period: Optional[int] = None + """ + The threshold of requests per period after which the action will be executed for + the first time. + """ + + requests_to_origin: Optional[bool] = None + """Whether counting is only performed when an origin is reached.""" + + score_per_period: Optional[int] = None + """ + The score threshold per period for which the action will be executed the first + time. + """ + + score_response_header_name: Optional[str] = None + """ + A response header name provided by the origin, which contains the score to + increment rate limit counter with. + """ + + +class UnionMember2RuleSetCacheControlRule(BaseModel): + id: str + """The unique ID of the rule.""" + + action: Literal["set_cache_control"] + """The action to perform when the rule matches.""" + + enabled: bool + + expression: str + """The expression defining which traffic will match the rule.""" + + last_updated: datetime + """The timestamp of when the rule was last modified.""" + + ref: str + """The reference of the rule (the rule's ID by default).""" + + version: str + """The version of the rule.""" + + action_parameters: Optional[UnionMember2RuleSetCacheControlRuleActionParameters] = None + """The parameters configuring the rule's action.""" + + categories: Optional[List[str]] = None + """The categories of the rule.""" + + description: Optional[str] = None + """An informative description of the rule.""" + + exposed_credential_check: Optional[UnionMember2RuleSetCacheControlRuleExposedCredentialCheck] = None + """Configuration for exposed credential checking.""" + + logging: Optional[Logging] = None + """An object configuring the rule's logging behavior.""" + + ratelimit: Optional[UnionMember2RuleSetCacheControlRuleRatelimit] = None + """An object configuring the rule's rate limit behavior.""" + + +class UnionMember2RuleSetCacheSettingsRule(SetCacheSettingsRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember2RuleSetCacheTagsRuleActionParametersAddCacheTagsValues(BaseModel): + """Add cache tags using a list of values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + values: List[str] + """A list of cache tag values.""" + + +class UnionMember2RuleSetCacheTagsRuleActionParametersAddCacheTagsExpression(BaseModel): + """Add cache tags using an expression.""" + + expression: str + """An expression that evaluates to an array of cache tag values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + +class UnionMember2RuleSetCacheTagsRuleActionParametersRemoveCacheTagsValues(BaseModel): + """Remove cache tags using a list of values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + values: List[str] + """A list of cache tag values.""" + + +class UnionMember2RuleSetCacheTagsRuleActionParametersRemoveCacheTagsExpression(BaseModel): + """Remove cache tags using an expression.""" + + expression: str + """An expression that evaluates to an array of cache tag values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + +class UnionMember2RuleSetCacheTagsRuleActionParametersSetCacheTagsValues(BaseModel): + """Set cache tags using a list of values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + values: List[str] + """A list of cache tag values.""" + + +class UnionMember2RuleSetCacheTagsRuleActionParametersSetCacheTagsExpression(BaseModel): + """Set cache tags using an expression.""" + + expression: str + """An expression that evaluates to an array of cache tag values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + +UnionMember2RuleSetCacheTagsRuleActionParameters: TypeAlias = Union[ + UnionMember2RuleSetCacheTagsRuleActionParametersAddCacheTagsValues, + UnionMember2RuleSetCacheTagsRuleActionParametersAddCacheTagsExpression, + UnionMember2RuleSetCacheTagsRuleActionParametersRemoveCacheTagsValues, + UnionMember2RuleSetCacheTagsRuleActionParametersRemoveCacheTagsExpression, + UnionMember2RuleSetCacheTagsRuleActionParametersSetCacheTagsValues, + UnionMember2RuleSetCacheTagsRuleActionParametersSetCacheTagsExpression, +] + + +class UnionMember2RuleSetCacheTagsRuleExposedCredentialCheck(BaseModel): + """Configuration for exposed credential checking.""" + + password_expression: str + """An expression that selects the password used in the credentials check.""" + + username_expression: str + """An expression that selects the user ID used in the credentials check.""" + + +class UnionMember2RuleSetCacheTagsRuleRatelimit(BaseModel): + """An object configuring the rule's rate limit behavior.""" + + characteristics: List[str] + """ + Characteristics of the request on which the rate limit counter will be + incremented. + """ + + period: int + """Period in seconds over which the counter is being incremented.""" + + counting_expression: Optional[str] = None + """An expression that defines when the rate limit counter should be incremented. + + It defaults to the same as the rule's expression. + """ + + mitigation_timeout: Optional[int] = None + """ + Period of time in seconds after which the action will be disabled following its + first execution. + """ + + requests_per_period: Optional[int] = None + """ + The threshold of requests per period after which the action will be executed for + the first time. + """ + + requests_to_origin: Optional[bool] = None + """Whether counting is only performed when an origin is reached.""" + + score_per_period: Optional[int] = None + """ + The score threshold per period for which the action will be executed the first + time. + """ + + score_response_header_name: Optional[str] = None + """ + A response header name provided by the origin, which contains the score to + increment rate limit counter with. + """ + + +class UnionMember2RuleSetCacheTagsRule(BaseModel): + id: str + """The unique ID of the rule.""" + + action: Literal["set_cache_tags"] + """The action to perform when the rule matches.""" + + enabled: bool + + expression: str + """The expression defining which traffic will match the rule.""" + + last_updated: datetime + """The timestamp of when the rule was last modified.""" + + ref: str + """The reference of the rule (the rule's ID by default).""" + + version: str + """The version of the rule.""" + + action_parameters: Optional[UnionMember2RuleSetCacheTagsRuleActionParameters] = None + """The parameters configuring the rule's action.""" + + categories: Optional[List[str]] = None + """The categories of the rule.""" + + description: Optional[str] = None + """An informative description of the rule.""" + + exposed_credential_check: Optional[UnionMember2RuleSetCacheTagsRuleExposedCredentialCheck] = None + """Configuration for exposed credential checking.""" + + logging: Optional[Logging] = None + """An object configuring the rule's logging behavior.""" + + ratelimit: Optional[UnionMember2RuleSetCacheTagsRuleRatelimit] = None + """An object configuring the rule's rate limit behavior.""" + + +class UnionMember2RuleSetConfigurationRule(SetConfigRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember2RuleSkipRule(SkipRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember2RuleTransformResponseHTMLRuleActionParameters(BaseModel): + """The parameters configuring the rule's action.""" + + link_maze: object + """Enables the link maze transformation on the response.""" + + +class UnionMember2RuleTransformResponseHTMLRuleExposedCredentialCheck(BaseModel): + """Configuration for exposed credential checking.""" + + password_expression: str + """An expression that selects the password used in the credentials check.""" + + username_expression: str + """An expression that selects the user ID used in the credentials check.""" + + +class UnionMember2RuleTransformResponseHTMLRuleRatelimit(BaseModel): + """An object configuring the rule's rate limit behavior.""" + + characteristics: List[str] + """ + Characteristics of the request on which the rate limit counter will be + incremented. + """ + + period: int + """Period in seconds over which the counter is being incremented.""" + + counting_expression: Optional[str] = None + """An expression that defines when the rate limit counter should be incremented. + + It defaults to the same as the rule's expression. + """ + + mitigation_timeout: Optional[int] = None + """ + Period of time in seconds after which the action will be disabled following its + first execution. + """ + + requests_per_period: Optional[int] = None + """ + The threshold of requests per period after which the action will be executed for + the first time. + """ + + requests_to_origin: Optional[bool] = None + """Whether counting is only performed when an origin is reached.""" + + score_per_period: Optional[int] = None + """ + The score threshold per period for which the action will be executed the first + time. + """ + + score_response_header_name: Optional[str] = None + """ + A response header name provided by the origin, which contains the score to + increment rate limit counter with. + """ + + +class UnionMember2RuleTransformResponseHTMLRule(BaseModel): + id: str + """The unique ID of the rule.""" + + action: Literal["transform_response_html"] + """The action to perform when the rule matches.""" + + enabled: bool + + expression: str + """The expression defining which traffic will match the rule.""" + + last_updated: datetime + """The timestamp of when the rule was last modified.""" + + ref: str + """The reference of the rule (the rule's ID by default).""" + + version: str + """The version of the rule.""" + + action_parameters: Optional[UnionMember2RuleTransformResponseHTMLRuleActionParameters] = None + """The parameters configuring the rule's action.""" + + categories: Optional[List[str]] = None + """The categories of the rule.""" + + description: Optional[str] = None + """An informative description of the rule.""" + + exposed_credential_check: Optional[UnionMember2RuleTransformResponseHTMLRuleExposedCredentialCheck] = None + """Configuration for exposed credential checking.""" + + logging: Optional[Logging] = None + """An object configuring the rule's logging behavior.""" + + ratelimit: Optional[UnionMember2RuleTransformResponseHTMLRuleRatelimit] = None + """An object configuring the rule's rate limit behavior.""" + + +UnionMember2Rule: TypeAlias = Union[ + UnionMember2RuleBlockRule, + UnionMember2RuleChallengeRule, + UnionMember2RuleResponseCompressionRule, + UnionMember2RuleDDoSDynamicRule, + UnionMember2RuleExecuteRule, + UnionMember2RuleForceConnectionCloseRule, + UnionMember2RuleJavaScriptChallengeRule, + UnionMember2RuleLogRule, + UnionMember2RuleLogCustomFieldRule, + UnionMember2RuleManagedChallengeRule, + UnionMember2RuleRedirectRule, + UnionMember2RuleRewriteRule, + UnionMember2RuleRouteRule, + UnionMember2RuleScoreRule, + UnionMember2RuleServeErrorRule, + UnionMember2RuleSetCacheControlRule, + UnionMember2RuleSetCacheSettingsRule, + UnionMember2RuleSetCacheTagsRule, + UnionMember2RuleSetConfigurationRule, + UnionMember2RuleSkipRule, + UnionMember2RuleTransformResponseHTMLRule, +] + + +class UnionMember2(BaseModel): + id: Optional[str] = None + """The unique ID of the ruleset.""" + + description: Optional[str] = None + """An informative description of the ruleset.""" + + kind: Optional[Kind] = None + """The kind of the ruleset.""" + + last_updated: Optional[datetime] = None + """The timestamp of when the ruleset was last modified.""" + + name: Optional[str] = None + """The human-readable name of the ruleset.""" + + phase: Optional[Phase] = None + """The phase of the ruleset.""" + + rules: Optional[List[UnionMember2Rule]] = None + """The list of rules in the ruleset.""" + + version: Optional[str] = None + """The version of the ruleset.""" + + +class UnionMember3RuleBlockRule(BlockRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember3RuleChallengeRuleExposedCredentialCheck(BaseModel): + """Configuration for exposed credential checking.""" + + password_expression: str + """An expression that selects the password used in the credentials check.""" + + username_expression: str + """An expression that selects the user ID used in the credentials check.""" + + +class UnionMember3RuleChallengeRuleRatelimit(BaseModel): + """An object configuring the rule's rate limit behavior.""" + + characteristics: List[str] + """ + Characteristics of the request on which the rate limit counter will be + incremented. + """ + + period: int + """Period in seconds over which the counter is being incremented.""" + + counting_expression: Optional[str] = None + """An expression that defines when the rate limit counter should be incremented. + + It defaults to the same as the rule's expression. + """ + + mitigation_timeout: Optional[int] = None + """ + Period of time in seconds after which the action will be disabled following its + first execution. + """ + + requests_per_period: Optional[int] = None + """ + The threshold of requests per period after which the action will be executed for + the first time. + """ + + requests_to_origin: Optional[bool] = None + """Whether counting is only performed when an origin is reached.""" + + score_per_period: Optional[int] = None + """ + The score threshold per period for which the action will be executed the first + time. + """ + + score_response_header_name: Optional[str] = None + """ + A response header name provided by the origin, which contains the score to + increment rate limit counter with. + """ + + +class UnionMember3RuleChallengeRule(BaseModel): + id: str + """The unique ID of the rule.""" + + action: Literal["challenge"] + """The action to perform when the rule matches.""" + + enabled: bool + """Whether the rule should be executed.""" + + expression: str + """The expression defining which traffic will match the rule.""" + + last_updated: datetime + """The timestamp of when the rule was last modified.""" + + ref: str + """The reference of the rule (the rule's ID by default).""" + + version: str + """The version of the rule.""" + + action_parameters: Optional[object] = None + """The parameters configuring the rule's action.""" + + categories: Optional[List[str]] = None + """The categories of the rule.""" + + description: Optional[str] = None + """An informative description of the rule.""" + + exposed_credential_check: Optional[UnionMember3RuleChallengeRuleExposedCredentialCheck] = None + """Configuration for exposed credential checking.""" + + logging: Optional[Logging] = None + """An object configuring the rule's logging behavior.""" + + ratelimit: Optional[UnionMember3RuleChallengeRuleRatelimit] = None + """An object configuring the rule's rate limit behavior.""" + + +class UnionMember3RuleResponseCompressionRule(CompressResponseRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember3RuleDDoSDynamicRule(DDoSDynamicRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember3RuleExecuteRule(ExecuteRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember3RuleForceConnectionCloseRule(ForceConnectionCloseRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember3RuleJavaScriptChallengeRuleExposedCredentialCheck(BaseModel): + """Configuration for exposed credential checking.""" + + password_expression: str + """An expression that selects the password used in the credentials check.""" + + username_expression: str + """An expression that selects the user ID used in the credentials check.""" + + +class UnionMember3RuleJavaScriptChallengeRuleRatelimit(BaseModel): + """An object configuring the rule's rate limit behavior.""" + + characteristics: List[str] + """ + Characteristics of the request on which the rate limit counter will be + incremented. + """ + + period: int + """Period in seconds over which the counter is being incremented.""" + + counting_expression: Optional[str] = None + """An expression that defines when the rate limit counter should be incremented. + + It defaults to the same as the rule's expression. + """ + + mitigation_timeout: Optional[int] = None + """ + Period of time in seconds after which the action will be disabled following its + first execution. + """ + + requests_per_period: Optional[int] = None + """ + The threshold of requests per period after which the action will be executed for + the first time. + """ + + requests_to_origin: Optional[bool] = None + """Whether counting is only performed when an origin is reached.""" + + score_per_period: Optional[int] = None + """ + The score threshold per period for which the action will be executed the first + time. + """ + + score_response_header_name: Optional[str] = None + """ + A response header name provided by the origin, which contains the score to + increment rate limit counter with. + """ + + +class UnionMember3RuleJavaScriptChallengeRule(BaseModel): + id: str + """The unique ID of the rule.""" + + action: Literal["js_challenge"] + """The action to perform when the rule matches.""" + + enabled: bool + """Whether the rule should be executed.""" + + expression: str + """The expression defining which traffic will match the rule.""" + + last_updated: datetime + """The timestamp of when the rule was last modified.""" + + ref: str + """The reference of the rule (the rule's ID by default).""" + + version: str + """The version of the rule.""" + + action_parameters: Optional[object] = None + """The parameters configuring the rule's action.""" + + categories: Optional[List[str]] = None + """The categories of the rule.""" + + description: Optional[str] = None + """An informative description of the rule.""" + + exposed_credential_check: Optional[UnionMember3RuleJavaScriptChallengeRuleExposedCredentialCheck] = None + """Configuration for exposed credential checking.""" + + logging: Optional[Logging] = None + """An object configuring the rule's logging behavior.""" + + ratelimit: Optional[UnionMember3RuleJavaScriptChallengeRuleRatelimit] = None + """An object configuring the rule's rate limit behavior.""" + + +class UnionMember3RuleLogRule(LogRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember3RuleLogCustomFieldRule(LogCustomFieldRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember3RuleManagedChallengeRule(ManagedChallengeRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember3RuleRedirectRule(RedirectRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember3RuleRewriteRule(RewriteRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember3RuleRouteRule(RouteRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember3RuleScoreRule(ScoreRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember3RuleServeErrorRule(ServeErrorRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember3RuleSetCacheControlRuleActionParametersImmutableSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember3RuleSetCacheControlRuleActionParametersImmutableRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember3RuleSetCacheControlRuleActionParametersImmutable: TypeAlias = Union[ + UnionMember3RuleSetCacheControlRuleActionParametersImmutableSetDirective, + UnionMember3RuleSetCacheControlRuleActionParametersImmutableRemoveDirective, +] + + +class UnionMember3RuleSetCacheControlRuleActionParametersMaxAgeSetDirective(BaseModel): + """Set the directive with a duration value in seconds.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + value: int + """The duration value in seconds for the directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember3RuleSetCacheControlRuleActionParametersMaxAgeRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember3RuleSetCacheControlRuleActionParametersMaxAge: TypeAlias = Union[ + UnionMember3RuleSetCacheControlRuleActionParametersMaxAgeSetDirective, + UnionMember3RuleSetCacheControlRuleActionParametersMaxAgeRemoveDirective, +] + + +class UnionMember3RuleSetCacheControlRuleActionParametersMustRevalidateSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember3RuleSetCacheControlRuleActionParametersMustRevalidateRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember3RuleSetCacheControlRuleActionParametersMustRevalidate: TypeAlias = Union[ + UnionMember3RuleSetCacheControlRuleActionParametersMustRevalidateSetDirective, + UnionMember3RuleSetCacheControlRuleActionParametersMustRevalidateRemoveDirective, +] + + +class UnionMember3RuleSetCacheControlRuleActionParametersMustUnderstandSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember3RuleSetCacheControlRuleActionParametersMustUnderstandRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember3RuleSetCacheControlRuleActionParametersMustUnderstand: TypeAlias = Union[ + UnionMember3RuleSetCacheControlRuleActionParametersMustUnderstandSetDirective, + UnionMember3RuleSetCacheControlRuleActionParametersMustUnderstandRemoveDirective, +] + + +class UnionMember3RuleSetCacheControlRuleActionParametersNoCacheSetDirective(BaseModel): + """Set the directive with optional qualifiers.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + qualifiers: Optional[List[str]] = None + """ + Optional list of header names to qualify the directive (e.g., for "private" or + "no-cache" directives). + """ + + +class UnionMember3RuleSetCacheControlRuleActionParametersNoCacheRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember3RuleSetCacheControlRuleActionParametersNoCache: TypeAlias = Union[ + UnionMember3RuleSetCacheControlRuleActionParametersNoCacheSetDirective, + UnionMember3RuleSetCacheControlRuleActionParametersNoCacheRemoveDirective, +] + + +class UnionMember3RuleSetCacheControlRuleActionParametersNoStoreSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember3RuleSetCacheControlRuleActionParametersNoStoreRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember3RuleSetCacheControlRuleActionParametersNoStore: TypeAlias = Union[ + UnionMember3RuleSetCacheControlRuleActionParametersNoStoreSetDirective, + UnionMember3RuleSetCacheControlRuleActionParametersNoStoreRemoveDirective, +] + + +class UnionMember3RuleSetCacheControlRuleActionParametersNoTransformSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember3RuleSetCacheControlRuleActionParametersNoTransformRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember3RuleSetCacheControlRuleActionParametersNoTransform: TypeAlias = Union[ + UnionMember3RuleSetCacheControlRuleActionParametersNoTransformSetDirective, + UnionMember3RuleSetCacheControlRuleActionParametersNoTransformRemoveDirective, +] + + +class UnionMember3RuleSetCacheControlRuleActionParametersPrivateSetDirective(BaseModel): + """Set the directive with optional qualifiers.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + qualifiers: Optional[List[str]] = None + """ + Optional list of header names to qualify the directive (e.g., for "private" or + "no-cache" directives). + """ + + +class UnionMember3RuleSetCacheControlRuleActionParametersPrivateRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember3RuleSetCacheControlRuleActionParametersPrivate: TypeAlias = Union[ + UnionMember3RuleSetCacheControlRuleActionParametersPrivateSetDirective, + UnionMember3RuleSetCacheControlRuleActionParametersPrivateRemoveDirective, +] + + +class UnionMember3RuleSetCacheControlRuleActionParametersProxyRevalidateSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember3RuleSetCacheControlRuleActionParametersProxyRevalidateRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember3RuleSetCacheControlRuleActionParametersProxyRevalidate: TypeAlias = Union[ + UnionMember3RuleSetCacheControlRuleActionParametersProxyRevalidateSetDirective, + UnionMember3RuleSetCacheControlRuleActionParametersProxyRevalidateRemoveDirective, +] + + +class UnionMember3RuleSetCacheControlRuleActionParametersPublicSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember3RuleSetCacheControlRuleActionParametersPublicRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember3RuleSetCacheControlRuleActionParametersPublic: TypeAlias = Union[ + UnionMember3RuleSetCacheControlRuleActionParametersPublicSetDirective, + UnionMember3RuleSetCacheControlRuleActionParametersPublicRemoveDirective, +] + + +class UnionMember3RuleSetCacheControlRuleActionParametersSMaxageSetDirective(BaseModel): + """Set the directive with a duration value in seconds.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + value: int + """The duration value in seconds for the directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember3RuleSetCacheControlRuleActionParametersSMaxageRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember3RuleSetCacheControlRuleActionParametersSMaxage: TypeAlias = Union[ + UnionMember3RuleSetCacheControlRuleActionParametersSMaxageSetDirective, + UnionMember3RuleSetCacheControlRuleActionParametersSMaxageRemoveDirective, +] + + +class UnionMember3RuleSetCacheControlRuleActionParametersStaleIfErrorSetDirective(BaseModel): + """Set the directive with a duration value in seconds.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + value: int + """The duration value in seconds for the directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember3RuleSetCacheControlRuleActionParametersStaleIfErrorRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember3RuleSetCacheControlRuleActionParametersStaleIfError: TypeAlias = Union[ + UnionMember3RuleSetCacheControlRuleActionParametersStaleIfErrorSetDirective, + UnionMember3RuleSetCacheControlRuleActionParametersStaleIfErrorRemoveDirective, +] + + +class UnionMember3RuleSetCacheControlRuleActionParametersStaleWhileRevalidateSetDirective(BaseModel): + """Set the directive with a duration value in seconds.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + value: int + """The duration value in seconds for the directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember3RuleSetCacheControlRuleActionParametersStaleWhileRevalidateRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember3RuleSetCacheControlRuleActionParametersStaleWhileRevalidate: TypeAlias = Union[ + UnionMember3RuleSetCacheControlRuleActionParametersStaleWhileRevalidateSetDirective, + UnionMember3RuleSetCacheControlRuleActionParametersStaleWhileRevalidateRemoveDirective, +] + + +class UnionMember3RuleSetCacheControlRuleActionParameters(BaseModel): + """The parameters configuring the rule's action.""" + + immutable: Optional[UnionMember3RuleSetCacheControlRuleActionParametersImmutable] = None + """A cache-control directive configuration.""" + + max_age: Optional[UnionMember3RuleSetCacheControlRuleActionParametersMaxAge] = FieldInfo( + alias="max-age", default=None + ) + """ + A cache-control directive configuration that accepts a duration value in + seconds. + """ + + must_revalidate: Optional[UnionMember3RuleSetCacheControlRuleActionParametersMustRevalidate] = FieldInfo( + alias="must-revalidate", default=None + ) + """A cache-control directive configuration.""" + + must_understand: Optional[UnionMember3RuleSetCacheControlRuleActionParametersMustUnderstand] = FieldInfo( + alias="must-understand", default=None + ) + """A cache-control directive configuration.""" + + no_cache: Optional[UnionMember3RuleSetCacheControlRuleActionParametersNoCache] = FieldInfo( + alias="no-cache", default=None + ) + """ + A cache-control directive configuration that accepts optional qualifiers (header + names). + """ + + no_store: Optional[UnionMember3RuleSetCacheControlRuleActionParametersNoStore] = FieldInfo( + alias="no-store", default=None + ) + """A cache-control directive configuration.""" + + no_transform: Optional[UnionMember3RuleSetCacheControlRuleActionParametersNoTransform] = FieldInfo( + alias="no-transform", default=None + ) + """A cache-control directive configuration.""" + + private: Optional[UnionMember3RuleSetCacheControlRuleActionParametersPrivate] = None + """ + A cache-control directive configuration that accepts optional qualifiers (header + names). + """ + + proxy_revalidate: Optional[UnionMember3RuleSetCacheControlRuleActionParametersProxyRevalidate] = FieldInfo( + alias="proxy-revalidate", default=None + ) + """A cache-control directive configuration.""" + + public: Optional[UnionMember3RuleSetCacheControlRuleActionParametersPublic] = None + """A cache-control directive configuration.""" + + s_maxage: Optional[UnionMember3RuleSetCacheControlRuleActionParametersSMaxage] = FieldInfo( + alias="s-maxage", default=None + ) + """ + A cache-control directive configuration that accepts a duration value in + seconds. + """ + + stale_if_error: Optional[UnionMember3RuleSetCacheControlRuleActionParametersStaleIfError] = FieldInfo( + alias="stale-if-error", default=None + ) + """ + A cache-control directive configuration that accepts a duration value in + seconds. + """ + + stale_while_revalidate: Optional[UnionMember3RuleSetCacheControlRuleActionParametersStaleWhileRevalidate] = ( + FieldInfo(alias="stale-while-revalidate", default=None) + ) + """ + A cache-control directive configuration that accepts a duration value in + seconds. + """ + + +class UnionMember3RuleSetCacheControlRuleExposedCredentialCheck(BaseModel): + """Configuration for exposed credential checking.""" + + password_expression: str + """An expression that selects the password used in the credentials check.""" + + username_expression: str + """An expression that selects the user ID used in the credentials check.""" + + +class UnionMember3RuleSetCacheControlRuleRatelimit(BaseModel): + """An object configuring the rule's rate limit behavior.""" + + characteristics: List[str] + """ + Characteristics of the request on which the rate limit counter will be + incremented. + """ + + period: int + """Period in seconds over which the counter is being incremented.""" + + counting_expression: Optional[str] = None + """An expression that defines when the rate limit counter should be incremented. + + It defaults to the same as the rule's expression. + """ + + mitigation_timeout: Optional[int] = None + """ + Period of time in seconds after which the action will be disabled following its + first execution. + """ + + requests_per_period: Optional[int] = None + """ + The threshold of requests per period after which the action will be executed for + the first time. + """ + + requests_to_origin: Optional[bool] = None + """Whether counting is only performed when an origin is reached.""" + + score_per_period: Optional[int] = None + """ + The score threshold per period for which the action will be executed the first + time. + """ + + score_response_header_name: Optional[str] = None + """ + A response header name provided by the origin, which contains the score to + increment rate limit counter with. + """ + + +class UnionMember3RuleSetCacheControlRule(BaseModel): + id: str + """The unique ID of the rule.""" + + action: Literal["set_cache_control"] + """The action to perform when the rule matches.""" + + enabled: bool + + expression: str + """The expression defining which traffic will match the rule.""" + + last_updated: datetime + """The timestamp of when the rule was last modified.""" + + ref: str + """The reference of the rule (the rule's ID by default).""" + + version: str + """The version of the rule.""" + + action_parameters: Optional[UnionMember3RuleSetCacheControlRuleActionParameters] = None + """The parameters configuring the rule's action.""" + + categories: Optional[List[str]] = None + """The categories of the rule.""" + + description: Optional[str] = None + """An informative description of the rule.""" + + exposed_credential_check: Optional[UnionMember3RuleSetCacheControlRuleExposedCredentialCheck] = None + """Configuration for exposed credential checking.""" + + logging: Optional[Logging] = None + """An object configuring the rule's logging behavior.""" + + ratelimit: Optional[UnionMember3RuleSetCacheControlRuleRatelimit] = None + """An object configuring the rule's rate limit behavior.""" + + +class UnionMember3RuleSetCacheSettingsRule(SetCacheSettingsRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember3RuleSetCacheTagsRuleActionParametersAddCacheTagsValues(BaseModel): + """Add cache tags using a list of values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + values: List[str] + """A list of cache tag values.""" + + +class UnionMember3RuleSetCacheTagsRuleActionParametersAddCacheTagsExpression(BaseModel): + """Add cache tags using an expression.""" + + expression: str + """An expression that evaluates to an array of cache tag values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + +class UnionMember3RuleSetCacheTagsRuleActionParametersRemoveCacheTagsValues(BaseModel): + """Remove cache tags using a list of values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + values: List[str] + """A list of cache tag values.""" + + +class UnionMember3RuleSetCacheTagsRuleActionParametersRemoveCacheTagsExpression(BaseModel): + """Remove cache tags using an expression.""" + + expression: str + """An expression that evaluates to an array of cache tag values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + +class UnionMember3RuleSetCacheTagsRuleActionParametersSetCacheTagsValues(BaseModel): + """Set cache tags using a list of values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + values: List[str] + """A list of cache tag values.""" + + +class UnionMember3RuleSetCacheTagsRuleActionParametersSetCacheTagsExpression(BaseModel): + """Set cache tags using an expression.""" + + expression: str + """An expression that evaluates to an array of cache tag values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + +UnionMember3RuleSetCacheTagsRuleActionParameters: TypeAlias = Union[ + UnionMember3RuleSetCacheTagsRuleActionParametersAddCacheTagsValues, + UnionMember3RuleSetCacheTagsRuleActionParametersAddCacheTagsExpression, + UnionMember3RuleSetCacheTagsRuleActionParametersRemoveCacheTagsValues, + UnionMember3RuleSetCacheTagsRuleActionParametersRemoveCacheTagsExpression, + UnionMember3RuleSetCacheTagsRuleActionParametersSetCacheTagsValues, + UnionMember3RuleSetCacheTagsRuleActionParametersSetCacheTagsExpression, +] + + +class UnionMember3RuleSetCacheTagsRuleExposedCredentialCheck(BaseModel): + """Configuration for exposed credential checking.""" + + password_expression: str + """An expression that selects the password used in the credentials check.""" + + username_expression: str + """An expression that selects the user ID used in the credentials check.""" + + +class UnionMember3RuleSetCacheTagsRuleRatelimit(BaseModel): + """An object configuring the rule's rate limit behavior.""" + + characteristics: List[str] + """ + Characteristics of the request on which the rate limit counter will be + incremented. + """ + + period: int + """Period in seconds over which the counter is being incremented.""" + + counting_expression: Optional[str] = None + """An expression that defines when the rate limit counter should be incremented. + + It defaults to the same as the rule's expression. + """ + + mitigation_timeout: Optional[int] = None + """ + Period of time in seconds after which the action will be disabled following its + first execution. + """ + + requests_per_period: Optional[int] = None + """ + The threshold of requests per period after which the action will be executed for + the first time. + """ + + requests_to_origin: Optional[bool] = None + """Whether counting is only performed when an origin is reached.""" + + score_per_period: Optional[int] = None + """ + The score threshold per period for which the action will be executed the first + time. + """ + + score_response_header_name: Optional[str] = None + """ + A response header name provided by the origin, which contains the score to + increment rate limit counter with. + """ + + +class UnionMember3RuleSetCacheTagsRule(BaseModel): + id: str + """The unique ID of the rule.""" + + action: Literal["set_cache_tags"] + """The action to perform when the rule matches.""" + + enabled: bool + + expression: str + """The expression defining which traffic will match the rule.""" + + last_updated: datetime + """The timestamp of when the rule was last modified.""" + + ref: str + """The reference of the rule (the rule's ID by default).""" + + version: str + """The version of the rule.""" + + action_parameters: Optional[UnionMember3RuleSetCacheTagsRuleActionParameters] = None + """The parameters configuring the rule's action.""" + + categories: Optional[List[str]] = None + """The categories of the rule.""" + + description: Optional[str] = None + """An informative description of the rule.""" + + exposed_credential_check: Optional[UnionMember3RuleSetCacheTagsRuleExposedCredentialCheck] = None + """Configuration for exposed credential checking.""" + + logging: Optional[Logging] = None + """An object configuring the rule's logging behavior.""" + + ratelimit: Optional[UnionMember3RuleSetCacheTagsRuleRatelimit] = None + """An object configuring the rule's rate limit behavior.""" + + +class UnionMember3RuleSetConfigurationRule(SetConfigRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember3RuleSkipRule(SkipRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember3RuleTransformResponseHTMLRuleActionParameters(BaseModel): + """The parameters configuring the rule's action.""" + + link_maze: object + """Enables the link maze transformation on the response.""" + + +class UnionMember3RuleTransformResponseHTMLRuleExposedCredentialCheck(BaseModel): + """Configuration for exposed credential checking.""" + + password_expression: str + """An expression that selects the password used in the credentials check.""" + + username_expression: str + """An expression that selects the user ID used in the credentials check.""" + + +class UnionMember3RuleTransformResponseHTMLRuleRatelimit(BaseModel): + """An object configuring the rule's rate limit behavior.""" + + characteristics: List[str] + """ + Characteristics of the request on which the rate limit counter will be + incremented. + """ + + period: int + """Period in seconds over which the counter is being incremented.""" + + counting_expression: Optional[str] = None + """An expression that defines when the rate limit counter should be incremented. + + It defaults to the same as the rule's expression. + """ + + mitigation_timeout: Optional[int] = None + """ + Period of time in seconds after which the action will be disabled following its + first execution. + """ + + requests_per_period: Optional[int] = None + """ + The threshold of requests per period after which the action will be executed for + the first time. + """ + + requests_to_origin: Optional[bool] = None + """Whether counting is only performed when an origin is reached.""" + + score_per_period: Optional[int] = None + """ + The score threshold per period for which the action will be executed the first + time. + """ + + score_response_header_name: Optional[str] = None + """ + A response header name provided by the origin, which contains the score to + increment rate limit counter with. + """ + + +class UnionMember3RuleTransformResponseHTMLRule(BaseModel): + id: str + """The unique ID of the rule.""" + + action: Literal["transform_response_html"] + """The action to perform when the rule matches.""" + + enabled: bool + + expression: str + """The expression defining which traffic will match the rule.""" + + last_updated: datetime + """The timestamp of when the rule was last modified.""" + + ref: str + """The reference of the rule (the rule's ID by default).""" + + version: str + """The version of the rule.""" + + action_parameters: Optional[UnionMember3RuleTransformResponseHTMLRuleActionParameters] = None + """The parameters configuring the rule's action.""" + + categories: Optional[List[str]] = None + """The categories of the rule.""" + + description: Optional[str] = None + """An informative description of the rule.""" + + exposed_credential_check: Optional[UnionMember3RuleTransformResponseHTMLRuleExposedCredentialCheck] = None + """Configuration for exposed credential checking.""" + + logging: Optional[Logging] = None + """An object configuring the rule's logging behavior.""" + + ratelimit: Optional[UnionMember3RuleTransformResponseHTMLRuleRatelimit] = None + """An object configuring the rule's rate limit behavior.""" + + +UnionMember3Rule: TypeAlias = Union[ + UnionMember3RuleBlockRule, + UnionMember3RuleChallengeRule, + UnionMember3RuleResponseCompressionRule, + UnionMember3RuleDDoSDynamicRule, + UnionMember3RuleExecuteRule, + UnionMember3RuleForceConnectionCloseRule, + UnionMember3RuleJavaScriptChallengeRule, + UnionMember3RuleLogRule, + UnionMember3RuleLogCustomFieldRule, + UnionMember3RuleManagedChallengeRule, + UnionMember3RuleRedirectRule, + UnionMember3RuleRewriteRule, + UnionMember3RuleRouteRule, + UnionMember3RuleScoreRule, + UnionMember3RuleServeErrorRule, + UnionMember3RuleSetCacheControlRule, + UnionMember3RuleSetCacheSettingsRule, + UnionMember3RuleSetCacheTagsRule, + UnionMember3RuleSetConfigurationRule, + UnionMember3RuleSkipRule, + UnionMember3RuleTransformResponseHTMLRule, +] + + +class UnionMember3(BaseModel): + id: Optional[str] = None + """The unique ID of the ruleset.""" + + description: Optional[str] = None + """An informative description of the ruleset.""" + + kind: Optional[Kind] = None + """The kind of the ruleset.""" + + last_updated: Optional[datetime] = None + """The timestamp of when the ruleset was last modified.""" + + name: Optional[str] = None + """The human-readable name of the ruleset.""" + + phase: Optional[Phase] = None + """The phase of the ruleset.""" + + rules: Optional[List[UnionMember3Rule]] = None + """The list of rules in the ruleset.""" + + version: Optional[str] = None + """The version of the ruleset.""" + + +class UnionMember4RuleBlockRule(BlockRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember4RuleChallengeRuleExposedCredentialCheck(BaseModel): + """Configuration for exposed credential checking.""" + + password_expression: str + """An expression that selects the password used in the credentials check.""" + + username_expression: str + """An expression that selects the user ID used in the credentials check.""" + + +class UnionMember4RuleChallengeRuleRatelimit(BaseModel): + """An object configuring the rule's rate limit behavior.""" + + characteristics: List[str] + """ + Characteristics of the request on which the rate limit counter will be + incremented. + """ + + period: int + """Period in seconds over which the counter is being incremented.""" + + counting_expression: Optional[str] = None + """An expression that defines when the rate limit counter should be incremented. + + It defaults to the same as the rule's expression. + """ + + mitigation_timeout: Optional[int] = None + """ + Period of time in seconds after which the action will be disabled following its + first execution. + """ + + requests_per_period: Optional[int] = None + """ + The threshold of requests per period after which the action will be executed for + the first time. + """ + + requests_to_origin: Optional[bool] = None + """Whether counting is only performed when an origin is reached.""" + + score_per_period: Optional[int] = None + """ + The score threshold per period for which the action will be executed the first + time. + """ + + score_response_header_name: Optional[str] = None + """ + A response header name provided by the origin, which contains the score to + increment rate limit counter with. + """ + + +class UnionMember4RuleChallengeRule(BaseModel): + id: str + """The unique ID of the rule.""" + + action: Literal["challenge"] + """The action to perform when the rule matches.""" + + enabled: bool + """Whether the rule should be executed.""" + + expression: str + """The expression defining which traffic will match the rule.""" + + last_updated: datetime + """The timestamp of when the rule was last modified.""" + + ref: str + """The reference of the rule (the rule's ID by default).""" + + version: str + """The version of the rule.""" + + action_parameters: Optional[object] = None + """The parameters configuring the rule's action.""" + + categories: Optional[List[str]] = None + """The categories of the rule.""" + + description: Optional[str] = None + """An informative description of the rule.""" + + exposed_credential_check: Optional[UnionMember4RuleChallengeRuleExposedCredentialCheck] = None + """Configuration for exposed credential checking.""" + + logging: Optional[Logging] = None + """An object configuring the rule's logging behavior.""" + + ratelimit: Optional[UnionMember4RuleChallengeRuleRatelimit] = None + """An object configuring the rule's rate limit behavior.""" + + +class UnionMember4RuleResponseCompressionRule(CompressResponseRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember4RuleDDoSDynamicRule(DDoSDynamicRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember4RuleExecuteRule(ExecuteRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember4RuleForceConnectionCloseRule(ForceConnectionCloseRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember4RuleJavaScriptChallengeRuleExposedCredentialCheck(BaseModel): + """Configuration for exposed credential checking.""" + + password_expression: str + """An expression that selects the password used in the credentials check.""" + + username_expression: str + """An expression that selects the user ID used in the credentials check.""" + + +class UnionMember4RuleJavaScriptChallengeRuleRatelimit(BaseModel): + """An object configuring the rule's rate limit behavior.""" + + characteristics: List[str] + """ + Characteristics of the request on which the rate limit counter will be + incremented. + """ + + period: int + """Period in seconds over which the counter is being incremented.""" + + counting_expression: Optional[str] = None + """An expression that defines when the rate limit counter should be incremented. + + It defaults to the same as the rule's expression. + """ + + mitigation_timeout: Optional[int] = None + """ + Period of time in seconds after which the action will be disabled following its + first execution. + """ + + requests_per_period: Optional[int] = None + """ + The threshold of requests per period after which the action will be executed for + the first time. + """ + + requests_to_origin: Optional[bool] = None + """Whether counting is only performed when an origin is reached.""" + + score_per_period: Optional[int] = None + """ + The score threshold per period for which the action will be executed the first + time. + """ + + score_response_header_name: Optional[str] = None + """ + A response header name provided by the origin, which contains the score to + increment rate limit counter with. + """ + + +class UnionMember4RuleJavaScriptChallengeRule(BaseModel): + id: str + """The unique ID of the rule.""" + + action: Literal["js_challenge"] + """The action to perform when the rule matches.""" + + enabled: bool + """Whether the rule should be executed.""" + + expression: str + """The expression defining which traffic will match the rule.""" + + last_updated: datetime + """The timestamp of when the rule was last modified.""" + + ref: str + """The reference of the rule (the rule's ID by default).""" + + version: str + """The version of the rule.""" + + action_parameters: Optional[object] = None + """The parameters configuring the rule's action.""" + + categories: Optional[List[str]] = None + """The categories of the rule.""" + + description: Optional[str] = None + """An informative description of the rule.""" + + exposed_credential_check: Optional[UnionMember4RuleJavaScriptChallengeRuleExposedCredentialCheck] = None + """Configuration for exposed credential checking.""" + + logging: Optional[Logging] = None + """An object configuring the rule's logging behavior.""" + + ratelimit: Optional[UnionMember4RuleJavaScriptChallengeRuleRatelimit] = None + """An object configuring the rule's rate limit behavior.""" + + +class UnionMember4RuleLogRule(LogRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember4RuleLogCustomFieldRule(LogCustomFieldRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember4RuleManagedChallengeRule(ManagedChallengeRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember4RuleRedirectRule(RedirectRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember4RuleRewriteRule(RewriteRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember4RuleRouteRule(RouteRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember4RuleScoreRule(ScoreRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember4RuleServeErrorRule(ServeErrorRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember4RuleSetCacheControlRuleActionParametersImmutableSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember4RuleSetCacheControlRuleActionParametersImmutableRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember4RuleSetCacheControlRuleActionParametersImmutable: TypeAlias = Union[ + UnionMember4RuleSetCacheControlRuleActionParametersImmutableSetDirective, + UnionMember4RuleSetCacheControlRuleActionParametersImmutableRemoveDirective, +] + + +class UnionMember4RuleSetCacheControlRuleActionParametersMaxAgeSetDirective(BaseModel): + """Set the directive with a duration value in seconds.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + value: int + """The duration value in seconds for the directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember4RuleSetCacheControlRuleActionParametersMaxAgeRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember4RuleSetCacheControlRuleActionParametersMaxAge: TypeAlias = Union[ + UnionMember4RuleSetCacheControlRuleActionParametersMaxAgeSetDirective, + UnionMember4RuleSetCacheControlRuleActionParametersMaxAgeRemoveDirective, +] + + +class UnionMember4RuleSetCacheControlRuleActionParametersMustRevalidateSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember4RuleSetCacheControlRuleActionParametersMustRevalidateRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember4RuleSetCacheControlRuleActionParametersMustRevalidate: TypeAlias = Union[ + UnionMember4RuleSetCacheControlRuleActionParametersMustRevalidateSetDirective, + UnionMember4RuleSetCacheControlRuleActionParametersMustRevalidateRemoveDirective, +] + + +class UnionMember4RuleSetCacheControlRuleActionParametersMustUnderstandSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember4RuleSetCacheControlRuleActionParametersMustUnderstandRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember4RuleSetCacheControlRuleActionParametersMustUnderstand: TypeAlias = Union[ + UnionMember4RuleSetCacheControlRuleActionParametersMustUnderstandSetDirective, + UnionMember4RuleSetCacheControlRuleActionParametersMustUnderstandRemoveDirective, +] + + +class UnionMember4RuleSetCacheControlRuleActionParametersNoCacheSetDirective(BaseModel): + """Set the directive with optional qualifiers.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + qualifiers: Optional[List[str]] = None + """ + Optional list of header names to qualify the directive (e.g., for "private" or + "no-cache" directives). + """ + + +class UnionMember4RuleSetCacheControlRuleActionParametersNoCacheRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember4RuleSetCacheControlRuleActionParametersNoCache: TypeAlias = Union[ + UnionMember4RuleSetCacheControlRuleActionParametersNoCacheSetDirective, + UnionMember4RuleSetCacheControlRuleActionParametersNoCacheRemoveDirective, +] + + +class UnionMember4RuleSetCacheControlRuleActionParametersNoStoreSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember4RuleSetCacheControlRuleActionParametersNoStoreRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember4RuleSetCacheControlRuleActionParametersNoStore: TypeAlias = Union[ + UnionMember4RuleSetCacheControlRuleActionParametersNoStoreSetDirective, + UnionMember4RuleSetCacheControlRuleActionParametersNoStoreRemoveDirective, +] + + +class UnionMember4RuleSetCacheControlRuleActionParametersNoTransformSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember4RuleSetCacheControlRuleActionParametersNoTransformRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember4RuleSetCacheControlRuleActionParametersNoTransform: TypeAlias = Union[ + UnionMember4RuleSetCacheControlRuleActionParametersNoTransformSetDirective, + UnionMember4RuleSetCacheControlRuleActionParametersNoTransformRemoveDirective, +] + + +class UnionMember4RuleSetCacheControlRuleActionParametersPrivateSetDirective(BaseModel): + """Set the directive with optional qualifiers.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + qualifiers: Optional[List[str]] = None + """ + Optional list of header names to qualify the directive (e.g., for "private" or + "no-cache" directives). + """ + + +class UnionMember4RuleSetCacheControlRuleActionParametersPrivateRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember4RuleSetCacheControlRuleActionParametersPrivate: TypeAlias = Union[ + UnionMember4RuleSetCacheControlRuleActionParametersPrivateSetDirective, + UnionMember4RuleSetCacheControlRuleActionParametersPrivateRemoveDirective, +] + + +class UnionMember4RuleSetCacheControlRuleActionParametersProxyRevalidateSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember4RuleSetCacheControlRuleActionParametersProxyRevalidateRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember4RuleSetCacheControlRuleActionParametersProxyRevalidate: TypeAlias = Union[ + UnionMember4RuleSetCacheControlRuleActionParametersProxyRevalidateSetDirective, + UnionMember4RuleSetCacheControlRuleActionParametersProxyRevalidateRemoveDirective, +] + + +class UnionMember4RuleSetCacheControlRuleActionParametersPublicSetDirective(BaseModel): + """Set the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember4RuleSetCacheControlRuleActionParametersPublicRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember4RuleSetCacheControlRuleActionParametersPublic: TypeAlias = Union[ + UnionMember4RuleSetCacheControlRuleActionParametersPublicSetDirective, + UnionMember4RuleSetCacheControlRuleActionParametersPublicRemoveDirective, +] + + +class UnionMember4RuleSetCacheControlRuleActionParametersSMaxageSetDirective(BaseModel): + """Set the directive with a duration value in seconds.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + value: int + """The duration value in seconds for the directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember4RuleSetCacheControlRuleActionParametersSMaxageRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember4RuleSetCacheControlRuleActionParametersSMaxage: TypeAlias = Union[ + UnionMember4RuleSetCacheControlRuleActionParametersSMaxageSetDirective, + UnionMember4RuleSetCacheControlRuleActionParametersSMaxageRemoveDirective, +] + + +class UnionMember4RuleSetCacheControlRuleActionParametersStaleIfErrorSetDirective(BaseModel): + """Set the directive with a duration value in seconds.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + value: int + """The duration value in seconds for the directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember4RuleSetCacheControlRuleActionParametersStaleIfErrorRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember4RuleSetCacheControlRuleActionParametersStaleIfError: TypeAlias = Union[ + UnionMember4RuleSetCacheControlRuleActionParametersStaleIfErrorSetDirective, + UnionMember4RuleSetCacheControlRuleActionParametersStaleIfErrorRemoveDirective, +] + + +class UnionMember4RuleSetCacheControlRuleActionParametersStaleWhileRevalidateSetDirective(BaseModel): + """Set the directive with a duration value in seconds.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + value: int + """The duration value in seconds for the directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +class UnionMember4RuleSetCacheControlRuleActionParametersStaleWhileRevalidateRemoveDirective(BaseModel): + """Remove the directive.""" + + operation: Literal["set", "remove"] + """The operation to perform on the cache-control directive.""" + + cloudflare_only: Optional[bool] = None + """Whether the directive should only be applied to the Cloudflare CDN cache.""" + + +UnionMember4RuleSetCacheControlRuleActionParametersStaleWhileRevalidate: TypeAlias = Union[ + UnionMember4RuleSetCacheControlRuleActionParametersStaleWhileRevalidateSetDirective, + UnionMember4RuleSetCacheControlRuleActionParametersStaleWhileRevalidateRemoveDirective, +] + + +class UnionMember4RuleSetCacheControlRuleActionParameters(BaseModel): + """The parameters configuring the rule's action.""" + + immutable: Optional[UnionMember4RuleSetCacheControlRuleActionParametersImmutable] = None + """A cache-control directive configuration.""" + + max_age: Optional[UnionMember4RuleSetCacheControlRuleActionParametersMaxAge] = FieldInfo( + alias="max-age", default=None + ) + """ + A cache-control directive configuration that accepts a duration value in + seconds. + """ + + must_revalidate: Optional[UnionMember4RuleSetCacheControlRuleActionParametersMustRevalidate] = FieldInfo( + alias="must-revalidate", default=None + ) + """A cache-control directive configuration.""" + + must_understand: Optional[UnionMember4RuleSetCacheControlRuleActionParametersMustUnderstand] = FieldInfo( + alias="must-understand", default=None + ) + """A cache-control directive configuration.""" + + no_cache: Optional[UnionMember4RuleSetCacheControlRuleActionParametersNoCache] = FieldInfo( + alias="no-cache", default=None + ) + """ + A cache-control directive configuration that accepts optional qualifiers (header + names). + """ + + no_store: Optional[UnionMember4RuleSetCacheControlRuleActionParametersNoStore] = FieldInfo( + alias="no-store", default=None + ) + """A cache-control directive configuration.""" + + no_transform: Optional[UnionMember4RuleSetCacheControlRuleActionParametersNoTransform] = FieldInfo( + alias="no-transform", default=None + ) + """A cache-control directive configuration.""" + + private: Optional[UnionMember4RuleSetCacheControlRuleActionParametersPrivate] = None + """ + A cache-control directive configuration that accepts optional qualifiers (header + names). + """ + + proxy_revalidate: Optional[UnionMember4RuleSetCacheControlRuleActionParametersProxyRevalidate] = FieldInfo( + alias="proxy-revalidate", default=None + ) + """A cache-control directive configuration.""" + + public: Optional[UnionMember4RuleSetCacheControlRuleActionParametersPublic] = None + """A cache-control directive configuration.""" + + s_maxage: Optional[UnionMember4RuleSetCacheControlRuleActionParametersSMaxage] = FieldInfo( + alias="s-maxage", default=None + ) + """ + A cache-control directive configuration that accepts a duration value in + seconds. + """ + + stale_if_error: Optional[UnionMember4RuleSetCacheControlRuleActionParametersStaleIfError] = FieldInfo( + alias="stale-if-error", default=None + ) + """ + A cache-control directive configuration that accepts a duration value in + seconds. + """ + + stale_while_revalidate: Optional[UnionMember4RuleSetCacheControlRuleActionParametersStaleWhileRevalidate] = ( + FieldInfo(alias="stale-while-revalidate", default=None) + ) + """ + A cache-control directive configuration that accepts a duration value in + seconds. + """ + + +class UnionMember4RuleSetCacheControlRuleExposedCredentialCheck(BaseModel): + """Configuration for exposed credential checking.""" + + password_expression: str + """An expression that selects the password used in the credentials check.""" + + username_expression: str + """An expression that selects the user ID used in the credentials check.""" + + +class UnionMember4RuleSetCacheControlRuleRatelimit(BaseModel): + """An object configuring the rule's rate limit behavior.""" + + characteristics: List[str] + """ + Characteristics of the request on which the rate limit counter will be + incremented. + """ + + period: int + """Period in seconds over which the counter is being incremented.""" + + counting_expression: Optional[str] = None + """An expression that defines when the rate limit counter should be incremented. + + It defaults to the same as the rule's expression. + """ + + mitigation_timeout: Optional[int] = None + """ + Period of time in seconds after which the action will be disabled following its + first execution. + """ + + requests_per_period: Optional[int] = None + """ + The threshold of requests per period after which the action will be executed for + the first time. + """ + + requests_to_origin: Optional[bool] = None + """Whether counting is only performed when an origin is reached.""" + + score_per_period: Optional[int] = None + """ + The score threshold per period for which the action will be executed the first + time. + """ + + score_response_header_name: Optional[str] = None + """ + A response header name provided by the origin, which contains the score to + increment rate limit counter with. + """ + + +class UnionMember4RuleSetCacheControlRule(BaseModel): + id: str + """The unique ID of the rule.""" + + action: Literal["set_cache_control"] + """The action to perform when the rule matches.""" + + enabled: bool + + expression: str + """The expression defining which traffic will match the rule.""" + + last_updated: datetime + """The timestamp of when the rule was last modified.""" + + ref: str + """The reference of the rule (the rule's ID by default).""" + + version: str + """The version of the rule.""" + + action_parameters: Optional[UnionMember4RuleSetCacheControlRuleActionParameters] = None + """The parameters configuring the rule's action.""" + + categories: Optional[List[str]] = None + """The categories of the rule.""" + + description: Optional[str] = None + """An informative description of the rule.""" + + exposed_credential_check: Optional[UnionMember4RuleSetCacheControlRuleExposedCredentialCheck] = None + """Configuration for exposed credential checking.""" + + logging: Optional[Logging] = None + """An object configuring the rule's logging behavior.""" + + ratelimit: Optional[UnionMember4RuleSetCacheControlRuleRatelimit] = None + """An object configuring the rule's rate limit behavior.""" + + +class UnionMember4RuleSetCacheSettingsRule(SetCacheSettingsRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember4RuleSetCacheTagsRuleActionParametersAddCacheTagsValues(BaseModel): + """Add cache tags using a list of values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + values: List[str] + """A list of cache tag values.""" + + +class UnionMember4RuleSetCacheTagsRuleActionParametersAddCacheTagsExpression(BaseModel): + """Add cache tags using an expression.""" + + expression: str + """An expression that evaluates to an array of cache tag values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + +class UnionMember4RuleSetCacheTagsRuleActionParametersRemoveCacheTagsValues(BaseModel): + """Remove cache tags using a list of values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + values: List[str] + """A list of cache tag values.""" + + +class UnionMember4RuleSetCacheTagsRuleActionParametersRemoveCacheTagsExpression(BaseModel): + """Remove cache tags using an expression.""" + + expression: str + """An expression that evaluates to an array of cache tag values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + +class UnionMember4RuleSetCacheTagsRuleActionParametersSetCacheTagsValues(BaseModel): + """Set cache tags using a list of values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + values: List[str] + """A list of cache tag values.""" + + +class UnionMember4RuleSetCacheTagsRuleActionParametersSetCacheTagsExpression(BaseModel): + """Set cache tags using an expression.""" + + expression: str + """An expression that evaluates to an array of cache tag values.""" + + operation: Literal["add", "remove", "set"] + """The operation to perform on the cache tags.""" + + +UnionMember4RuleSetCacheTagsRuleActionParameters: TypeAlias = Union[ + UnionMember4RuleSetCacheTagsRuleActionParametersAddCacheTagsValues, + UnionMember4RuleSetCacheTagsRuleActionParametersAddCacheTagsExpression, + UnionMember4RuleSetCacheTagsRuleActionParametersRemoveCacheTagsValues, + UnionMember4RuleSetCacheTagsRuleActionParametersRemoveCacheTagsExpression, + UnionMember4RuleSetCacheTagsRuleActionParametersSetCacheTagsValues, + UnionMember4RuleSetCacheTagsRuleActionParametersSetCacheTagsExpression, +] + + +class UnionMember4RuleSetCacheTagsRuleExposedCredentialCheck(BaseModel): + """Configuration for exposed credential checking.""" + + password_expression: str + """An expression that selects the password used in the credentials check.""" + + username_expression: str + """An expression that selects the user ID used in the credentials check.""" + + +class UnionMember4RuleSetCacheTagsRuleRatelimit(BaseModel): + """An object configuring the rule's rate limit behavior.""" + + characteristics: List[str] + """ + Characteristics of the request on which the rate limit counter will be + incremented. + """ + + period: int + """Period in seconds over which the counter is being incremented.""" + + counting_expression: Optional[str] = None + """An expression that defines when the rate limit counter should be incremented. + + It defaults to the same as the rule's expression. + """ + + mitigation_timeout: Optional[int] = None + """ + Period of time in seconds after which the action will be disabled following its + first execution. + """ + + requests_per_period: Optional[int] = None + """ + The threshold of requests per period after which the action will be executed for + the first time. + """ + + requests_to_origin: Optional[bool] = None + """Whether counting is only performed when an origin is reached.""" + + score_per_period: Optional[int] = None + """ + The score threshold per period for which the action will be executed the first + time. + """ + + score_response_header_name: Optional[str] = None + """ + A response header name provided by the origin, which contains the score to + increment rate limit counter with. + """ + + +class UnionMember4RuleSetCacheTagsRule(BaseModel): + id: str + """The unique ID of the rule.""" + + action: Literal["set_cache_tags"] + """The action to perform when the rule matches.""" + + enabled: bool + + expression: str + """The expression defining which traffic will match the rule.""" + + last_updated: datetime + """The timestamp of when the rule was last modified.""" + + ref: str + """The reference of the rule (the rule's ID by default).""" + + version: str + """The version of the rule.""" + + action_parameters: Optional[UnionMember4RuleSetCacheTagsRuleActionParameters] = None + """The parameters configuring the rule's action.""" + + categories: Optional[List[str]] = None + """The categories of the rule.""" + + description: Optional[str] = None + """An informative description of the rule.""" + + exposed_credential_check: Optional[UnionMember4RuleSetCacheTagsRuleExposedCredentialCheck] = None + """Configuration for exposed credential checking.""" + + logging: Optional[Logging] = None + """An object configuring the rule's logging behavior.""" + + ratelimit: Optional[UnionMember4RuleSetCacheTagsRuleRatelimit] = None + """An object configuring the rule's rate limit behavior.""" + + +class UnionMember4RuleSetConfigurationRule(SetConfigRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember4RuleSkipRule(SkipRule): + id: str # type: ignore + + action: str # type: ignore + + enabled: bool # type: ignore + + expression: str # type: ignore + + ref: str # type: ignore + + +class UnionMember4RuleTransformResponseHTMLRuleActionParameters(BaseModel): + """The parameters configuring the rule's action.""" + + link_maze: object + """Enables the link maze transformation on the response.""" + + +class UnionMember4RuleTransformResponseHTMLRuleExposedCredentialCheck(BaseModel): + """Configuration for exposed credential checking.""" + + password_expression: str + """An expression that selects the password used in the credentials check.""" + + username_expression: str + """An expression that selects the user ID used in the credentials check.""" + + +class UnionMember4RuleTransformResponseHTMLRuleRatelimit(BaseModel): + """An object configuring the rule's rate limit behavior.""" + + characteristics: List[str] + """ + Characteristics of the request on which the rate limit counter will be + incremented. + """ + + period: int + """Period in seconds over which the counter is being incremented.""" + + counting_expression: Optional[str] = None + """An expression that defines when the rate limit counter should be incremented. + + It defaults to the same as the rule's expression. + """ + + mitigation_timeout: Optional[int] = None + """ + Period of time in seconds after which the action will be disabled following its + first execution. + """ + + requests_per_period: Optional[int] = None + """ + The threshold of requests per period after which the action will be executed for + the first time. + """ + + requests_to_origin: Optional[bool] = None + """Whether counting is only performed when an origin is reached.""" + + score_per_period: Optional[int] = None + """ + The score threshold per period for which the action will be executed the first + time. + """ + + score_response_header_name: Optional[str] = None + """ + A response header name provided by the origin, which contains the score to + increment rate limit counter with. + """ + + +class UnionMember4RuleTransformResponseHTMLRule(BaseModel): + id: str + """The unique ID of the rule.""" + + action: Literal["transform_response_html"] + """The action to perform when the rule matches.""" + + enabled: bool + + expression: str + """The expression defining which traffic will match the rule.""" + + last_updated: datetime + """The timestamp of when the rule was last modified.""" + + ref: str + """The reference of the rule (the rule's ID by default).""" + + version: str + """The version of the rule.""" + + action_parameters: Optional[UnionMember4RuleTransformResponseHTMLRuleActionParameters] = None + """The parameters configuring the rule's action.""" + + categories: Optional[List[str]] = None + """The categories of the rule.""" + + description: Optional[str] = None + """An informative description of the rule.""" + + exposed_credential_check: Optional[UnionMember4RuleTransformResponseHTMLRuleExposedCredentialCheck] = None + """Configuration for exposed credential checking.""" + + logging: Optional[Logging] = None + """An object configuring the rule's logging behavior.""" + + ratelimit: Optional[UnionMember4RuleTransformResponseHTMLRuleRatelimit] = None + """An object configuring the rule's rate limit behavior.""" + + +UnionMember4Rule: TypeAlias = Union[ + UnionMember4RuleBlockRule, + UnionMember4RuleChallengeRule, + UnionMember4RuleResponseCompressionRule, + UnionMember4RuleDDoSDynamicRule, + UnionMember4RuleExecuteRule, + UnionMember4RuleForceConnectionCloseRule, + UnionMember4RuleJavaScriptChallengeRule, + UnionMember4RuleLogRule, + UnionMember4RuleLogCustomFieldRule, + UnionMember4RuleManagedChallengeRule, + UnionMember4RuleRedirectRule, + UnionMember4RuleRewriteRule, + UnionMember4RuleRouteRule, + UnionMember4RuleScoreRule, + UnionMember4RuleServeErrorRule, + UnionMember4RuleSetCacheControlRule, + UnionMember4RuleSetCacheSettingsRule, + UnionMember4RuleSetCacheTagsRule, + UnionMember4RuleSetConfigurationRule, + UnionMember4RuleSkipRule, + UnionMember4RuleTransformResponseHTMLRule, +] + + +class UnionMember4(BaseModel): + id: Optional[str] = None + """The unique ID of the ruleset.""" + + description: Optional[str] = None + """An informative description of the ruleset.""" + + kind: Optional[Kind] = None + """The kind of the ruleset.""" + + last_updated: Optional[datetime] = None + """The timestamp of when the ruleset was last modified.""" + + name: Optional[str] = None + """The human-readable name of the ruleset.""" + + phase: Optional[Phase] = None + """The phase of the ruleset.""" + + rules: Optional[List[UnionMember4Rule]] = None + """The list of rules in the ruleset.""" + + version: Optional[str] = None + """The version of the ruleset.""" + + +VersionGetResponse: TypeAlias = Union[Optional[UnionMember0], UnionMember1, UnionMember2, UnionMember3, UnionMember4] diff --git a/src/cloudflare/types/rulesets/version_list_response.py b/src/cloudflare/types/rulesets/version_list_response.py index 48c9c312b83..ed4be2242d5 100644 --- a/src/cloudflare/types/rulesets/version_list_response.py +++ b/src/cloudflare/types/rulesets/version_list_response.py @@ -1,35 +1,8 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import Optional -from datetime import datetime - -from .kind import Kind -from .phase import Phase -from ..._models import BaseModel +from typing import List, Union, Optional +from typing_extensions import TypeAlias __all__ = ["VersionListResponse"] - -class VersionListResponse(BaseModel): - """A ruleset object.""" - - id: str - """The unique ID of the ruleset.""" - - kind: Kind - """The kind of the ruleset.""" - - last_updated: datetime - """The timestamp of when the ruleset was last modified.""" - - name: str - """The human-readable name of the ruleset.""" - - phase: Phase - """The phase of the ruleset.""" - - version: str - """The version of the ruleset.""" - - description: Optional[str] = None - """An informative description of the ruleset.""" +VersionListResponse: TypeAlias = Union[List[object], str, float, bool, Optional[object]] diff --git a/src/cloudflare/types/secrets_store/stores/secret_create_params.py b/src/cloudflare/types/secrets_store/stores/secret_create_params.py index 99ae191e979..0b19229b905 100644 --- a/src/cloudflare/types/secrets_store/stores/secret_create_params.py +++ b/src/cloudflare/types/secrets_store/stores/secret_create_params.py @@ -18,9 +18,6 @@ class Body(TypedDict, total=False): name: Required[str] """The name of the secret.""" - scopes: Required[List[Literal["workers", "ai_gateway", "dex", "access", "containers", "websearch"]]] - """The list of services that can use this secret.""" - value: Required[str] """The value of the secret. @@ -30,3 +27,10 @@ class Body(TypedDict, total=False): comment: str """Freeform text describing the secret.""" + + scopes: List[Literal["workers", "ai_gateway", "dex", "access", "containers", "websearch"]] + """The list of services that can use this secret. + + Omit it on create or duplicate to inherit the store's scopes. An empty list lets + no service use the secret. + """ diff --git a/src/cloudflare/types/secrets_store/stores/secret_create_response.py b/src/cloudflare/types/secrets_store/stores/secret_create_response.py index 22867917be7..121bfb404fc 100644 --- a/src/cloudflare/types/secrets_store/stores/secret_create_response.py +++ b/src/cloudflare/types/secrets_store/stores/secret_create_response.py @@ -31,4 +31,8 @@ class SecretCreateResponse(BaseModel): """Freeform text describing the secret.""" scopes: Optional[List[Literal["workers", "ai_gateway", "dex", "access", "containers", "websearch"]]] = None - """The list of services that can use this secret.""" + """ + The list of services that can use this secret, or null when the secret inherits + its store's scopes. Set it to null in a patch to inherit again. An empty list + lets no service use the secret. + """ diff --git a/src/cloudflare/types/secrets_store/stores/secret_duplicate_params.py b/src/cloudflare/types/secrets_store/stores/secret_duplicate_params.py index 3b192d24e65..810e205184c 100644 --- a/src/cloudflare/types/secrets_store/stores/secret_duplicate_params.py +++ b/src/cloudflare/types/secrets_store/stores/secret_duplicate_params.py @@ -16,8 +16,12 @@ class SecretDuplicateParams(TypedDict, total=False): name: Required[str] """The name of the secret.""" - scopes: Required[List[Literal["workers", "ai_gateway", "dex", "access", "containers", "websearch"]]] - """The list of services that can use this secret.""" - comment: str """Freeform text describing the secret.""" + + scopes: List[Literal["workers", "ai_gateway", "dex", "access", "containers", "websearch"]] + """The list of services that can use this secret. + + Omit it on create or duplicate to inherit the store's scopes. An empty list lets + no service use the secret. + """ diff --git a/src/cloudflare/types/secrets_store/stores/secret_duplicate_response.py b/src/cloudflare/types/secrets_store/stores/secret_duplicate_response.py index 57ac895dbbe..791d8cc9dab 100644 --- a/src/cloudflare/types/secrets_store/stores/secret_duplicate_response.py +++ b/src/cloudflare/types/secrets_store/stores/secret_duplicate_response.py @@ -31,4 +31,8 @@ class SecretDuplicateResponse(BaseModel): """Freeform text describing the secret.""" scopes: Optional[List[Literal["workers", "ai_gateway", "dex", "access", "containers", "websearch"]]] = None - """The list of services that can use this secret.""" + """ + The list of services that can use this secret, or null when the secret inherits + its store's scopes. Set it to null in a patch to inherit again. An empty list + lets no service use the secret. + """ diff --git a/src/cloudflare/types/secrets_store/stores/secret_edit_params.py b/src/cloudflare/types/secrets_store/stores/secret_edit_params.py index 57ee53858fe..eff18b5ca90 100644 --- a/src/cloudflare/types/secrets_store/stores/secret_edit_params.py +++ b/src/cloudflare/types/secrets_store/stores/secret_edit_params.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing import List +from typing import List, Optional from typing_extensions import Literal, Required, TypedDict __all__ = ["SecretEditParams"] @@ -16,8 +16,12 @@ class SecretEditParams(TypedDict, total=False): comment: str """Freeform text describing the secret.""" - scopes: List[Literal["workers", "ai_gateway", "dex", "access", "containers", "websearch"]] - """The list of services that can use this secret.""" + scopes: Optional[List[Literal["workers", "ai_gateway", "dex", "access", "containers", "websearch"]]] + """ + The list of services that can use this secret, or null when the secret inherits + its store's scopes. Set it to null in a patch to inherit again. An empty list + lets no service use the secret. + """ value: str """The value of the secret. diff --git a/src/cloudflare/types/secrets_store/stores/secret_edit_response.py b/src/cloudflare/types/secrets_store/stores/secret_edit_response.py index 07af9cf4982..179e2a834c9 100644 --- a/src/cloudflare/types/secrets_store/stores/secret_edit_response.py +++ b/src/cloudflare/types/secrets_store/stores/secret_edit_response.py @@ -31,4 +31,8 @@ class SecretEditResponse(BaseModel): """Freeform text describing the secret.""" scopes: Optional[List[Literal["workers", "ai_gateway", "dex", "access", "containers", "websearch"]]] = None - """The list of services that can use this secret.""" + """ + The list of services that can use this secret, or null when the secret inherits + its store's scopes. Set it to null in a patch to inherit again. An empty list + lets no service use the secret. + """ diff --git a/src/cloudflare/types/secrets_store/stores/secret_get_response.py b/src/cloudflare/types/secrets_store/stores/secret_get_response.py index 0fdc4867252..f084a1dbea3 100644 --- a/src/cloudflare/types/secrets_store/stores/secret_get_response.py +++ b/src/cloudflare/types/secrets_store/stores/secret_get_response.py @@ -31,4 +31,8 @@ class SecretGetResponse(BaseModel): """Freeform text describing the secret.""" scopes: Optional[List[Literal["workers", "ai_gateway", "dex", "access", "containers", "websearch"]]] = None - """The list of services that can use this secret.""" + """ + The list of services that can use this secret, or null when the secret inherits + its store's scopes. Set it to null in a patch to inherit again. An empty list + lets no service use the secret. + """ diff --git a/src/cloudflare/types/secrets_store/stores/secret_list_response.py b/src/cloudflare/types/secrets_store/stores/secret_list_response.py index 65ec0afc64a..cc8c860dc94 100644 --- a/src/cloudflare/types/secrets_store/stores/secret_list_response.py +++ b/src/cloudflare/types/secrets_store/stores/secret_list_response.py @@ -31,4 +31,8 @@ class SecretListResponse(BaseModel): """Freeform text describing the secret.""" scopes: Optional[List[Literal["workers", "ai_gateway", "dex", "access", "containers", "websearch"]]] = None - """The list of services that can use this secret.""" + """ + The list of services that can use this secret, or null when the secret inherits + its store's scopes. Set it to null in a patch to inherit again. An empty list + lets no service use the secret. + """ diff --git a/src/cloudflare/types/security_center/insight_list_response.py b/src/cloudflare/types/security_center/insight_list_response.py index bbe0b207151..c98c3b4add4 100644 --- a/src/cloudflare/types/security_center/insight_list_response.py +++ b/src/cloudflare/types/security_center/insight_list_response.py @@ -42,6 +42,12 @@ class Issue(BaseModel): since: Optional[datetime] = None + source: Optional[Literal["cloudflare", "riskrecon"]] = None + """Who generated the insight. + + `cloudflare` for Cloudflare-generated insights, otherwise the partner. + """ + status: Optional[Literal["active", "resolved"]] = None """The current status of the insight.""" diff --git a/src/cloudflare/types/shared/__init__.py b/src/cloudflare/types/shared/__init__.py index 7f78af40f62..70ba5b01c03 100644 --- a/src/cloudflare/types/shared/__init__.py +++ b/src/cloudflare/types/shared/__init__.py @@ -20,7 +20,6 @@ from .permission_grant import PermissionGrant as PermissionGrant from .cloudflare_tunnel import CloudflareTunnel as CloudflareTunnel from .subscription_zone import SubscriptionZone as SubscriptionZone -from .load_balancer_preview import LoadBalancerPreview as LoadBalancerPreview from .subscription_component import SubscriptionComponent as SubscriptionComponent from .certificate_request_type import CertificateRequestType as CertificateRequestType from .token_condition_cidr_list import TokenConditionCIDRList as TokenConditionCIDRList diff --git a/src/cloudflare/types/shared/load_balancer_preview.py b/src/cloudflare/types/shared/load_balancer_preview.py deleted file mode 100644 index e57784aa9b5..00000000000 --- a/src/cloudflare/types/shared/load_balancer_preview.py +++ /dev/null @@ -1,14 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from typing import Dict, Optional - -from ..._models import BaseModel - -__all__ = ["LoadBalancerPreview"] - - -class LoadBalancerPreview(BaseModel): - pools: Optional[Dict[str, str]] = None - """Monitored pool IDs mapped to their respective names.""" - - preview_id: Optional[str] = None diff --git a/src/cloudflare/types/shared/member.py b/src/cloudflare/types/shared/member.py index 8a0ddbdeb5d..f5044cccdef 100644 --- a/src/cloudflare/types/shared/member.py +++ b/src/cloudflare/types/shared/member.py @@ -76,7 +76,7 @@ class PolicyResourceGroupScopeObject(BaseModel): class PolicyResourceGroupScope(BaseModel): - """A scope is a combination of scope objects which provides additional context.""" + """The scope associated to the resource group""" key: str """ @@ -103,7 +103,7 @@ class PolicyResourceGroup(BaseModel): """Identifier of the resource group.""" scope: PolicyResourceGroupScope - """A scope is a combination of scope objects which provides additional context.""" + """The scope associated to the resource group""" meta: Optional[PolicyResourceGroupMeta] = None """Attributes associated to the resource group.""" diff --git a/src/cloudflare/types/shared/token.py b/src/cloudflare/types/shared/token.py index 242a0ec7ebf..1dac624fdbc 100644 --- a/src/cloudflare/types/shared/token.py +++ b/src/cloudflare/types/shared/token.py @@ -79,3 +79,17 @@ class Token(BaseModel): status: Optional[Literal["active", "disabled", "expired"]] = None """Status of the token.""" + + token_prefix: Optional[str] = None + """The prefix of the token value, before the first underscore. + + Use it with `token_suffix` to identify a token. Only present for tokens created + or rolled after this field was added. + """ + + token_suffix: Optional[str] = None + """The last 4 characters of the token value. + + Use it with `token_prefix` to identify a token. It is not unique. Only present + for tokens created or rolled after this field was added. + """ diff --git a/src/cloudflare/types/spectrum/app_create_response.py b/src/cloudflare/types/spectrum/app_create_response.py index 3b2646bbd00..63de0027a73 100644 --- a/src/cloudflare/types/spectrum/app_create_response.py +++ b/src/cloudflare/types/spectrum/app_create_response.py @@ -86,6 +86,19 @@ class SpectrumConfigAppConfig(BaseModel): argo_smart_routing. tls may only be "off" or "flexible". """ + origin_worker_name: Optional[str] = None + """Name of the Worker origin. + + Omitted when the Worker is not found or its name cannot be resolved. + """ + + origin_worker_status: Optional[Literal["available", "not_found", "unknown"]] = None + """Lookup status of the Worker origin. + + Unknown indicates that its name could not be resolved. Only returned for Worker + origins. + """ + proxy_protocol: Optional[Literal["off", "v1", "v2", "simple"]] = None """Enables Proxy Protocol to the origin. diff --git a/src/cloudflare/types/spectrum/app_get_response.py b/src/cloudflare/types/spectrum/app_get_response.py index 73b11c0c4b4..4860bfada65 100644 --- a/src/cloudflare/types/spectrum/app_get_response.py +++ b/src/cloudflare/types/spectrum/app_get_response.py @@ -86,6 +86,19 @@ class SpectrumConfigAppConfig(BaseModel): argo_smart_routing. tls may only be "off" or "flexible". """ + origin_worker_name: Optional[str] = None + """Name of the Worker origin. + + Omitted when the Worker is not found or its name cannot be resolved. + """ + + origin_worker_status: Optional[Literal["available", "not_found", "unknown"]] = None + """Lookup status of the Worker origin. + + Unknown indicates that its name could not be resolved. Only returned for Worker + origins. + """ + proxy_protocol: Optional[Literal["off", "v1", "v2", "simple"]] = None """Enables Proxy Protocol to the origin. diff --git a/src/cloudflare/types/spectrum/app_list_response.py b/src/cloudflare/types/spectrum/app_list_response.py index 553143f3442..262a44cf512 100644 --- a/src/cloudflare/types/spectrum/app_list_response.py +++ b/src/cloudflare/types/spectrum/app_list_response.py @@ -86,6 +86,19 @@ class SpectrumConfigAppConfig(BaseModel): argo_smart_routing. tls may only be "off" or "flexible". """ + origin_worker_name: Optional[str] = None + """Name of the Worker origin. + + Omitted when the Worker is not found or its name cannot be resolved. + """ + + origin_worker_status: Optional[Literal["available", "not_found", "unknown"]] = None + """Lookup status of the Worker origin. + + Unknown indicates that its name could not be resolved. Only returned for Worker + origins. + """ + proxy_protocol: Optional[Literal["off", "v1", "v2", "simple"]] = None """Enables Proxy Protocol to the origin. diff --git a/src/cloudflare/types/spectrum/app_update_response.py b/src/cloudflare/types/spectrum/app_update_response.py index 970dd49cd06..b38fb6228e7 100644 --- a/src/cloudflare/types/spectrum/app_update_response.py +++ b/src/cloudflare/types/spectrum/app_update_response.py @@ -86,6 +86,19 @@ class SpectrumConfigAppConfig(BaseModel): argo_smart_routing. tls may only be "off" or "flexible". """ + origin_worker_name: Optional[str] = None + """Name of the Worker origin. + + Omitted when the Worker is not found or its name cannot be resolved. + """ + + origin_worker_status: Optional[Literal["available", "not_found", "unknown"]] = None + """Lookup status of the Worker origin. + + Unknown indicates that its name could not be resolved. Only returned for Worker + origins. + """ + proxy_protocol: Optional[Literal["off", "v1", "v2", "simple"]] = None """Enables Proxy Protocol to the origin. diff --git a/src/cloudflare/types/tenant_custom_nameservers/__init__.py b/src/cloudflare/types/tenant_custom_nameservers/__init__.py index 3c23e5cb89e..f8ee8b14b1c 100644 --- a/src/cloudflare/types/tenant_custom_nameservers/__init__.py +++ b/src/cloudflare/types/tenant_custom_nameservers/__init__.py @@ -1,16 +1,3 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations - -from .tenant_custom_nameserver_get_response import ( - TenantCustomNameserverGetResponse as TenantCustomNameserverGetResponse, -) -from .tenant_custom_nameserver_create_params import ( - TenantCustomNameserverCreateParams as TenantCustomNameserverCreateParams, -) -from .tenant_custom_nameserver_create_response import ( - TenantCustomNameserverCreateResponse as TenantCustomNameserverCreateResponse, -) -from .tenant_custom_nameserver_delete_response import ( - TenantCustomNameserverDeleteResponse as TenantCustomNameserverDeleteResponse, -) diff --git a/src/cloudflare/types/tenant_custom_nameservers/tenant_custom_nameserver_create_params.py b/src/cloudflare/types/tenant_custom_nameservers/tenant_custom_nameserver_create_params.py deleted file mode 100644 index 3769e05520c..00000000000 --- a/src/cloudflare/types/tenant_custom_nameservers/tenant_custom_nameserver_create_params.py +++ /dev/null @@ -1,15 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing_extensions import Required, TypedDict - -__all__ = ["TenantCustomNameserverCreateParams"] - - -class TenantCustomNameserverCreateParams(TypedDict, total=False): - ns_name: Required[str] - """The FQDN of the name server.""" - - ns_set: float - """The number of the set that this name server belongs to.""" diff --git a/src/cloudflare/types/tenant_custom_nameservers/tenant_custom_nameserver_create_response.py b/src/cloudflare/types/tenant_custom_nameservers/tenant_custom_nameserver_create_response.py deleted file mode 100644 index 4d7ff349fc2..00000000000 --- a/src/cloudflare/types/tenant_custom_nameservers/tenant_custom_nameserver_create_response.py +++ /dev/null @@ -1,35 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from typing import List, Optional -from typing_extensions import Literal - -from ..._models import BaseModel - -__all__ = ["TenantCustomNameserverCreateResponse", "DNSRecord"] - - -class DNSRecord(BaseModel): - type: Optional[Literal["A", "AAAA"]] = None - """DNS record type.""" - - value: Optional[str] = None - """DNS record contents (an IPv4 or IPv6 address).""" - - -class TenantCustomNameserverCreateResponse(BaseModel): - """A single tenant custom nameserver.""" - - dns_records: List[DNSRecord] - """A and AAAA records associated with the nameserver.""" - - ns_name: str - """The FQDN of the name server.""" - - status: Literal["moved", "pending", "verified"] - """Verification status of the nameserver.""" - - zone_tag: str - """Identifier.""" - - ns_set: Optional[float] = None - """The number of the set that this name server belongs to.""" diff --git a/src/cloudflare/types/tenant_custom_nameservers/tenant_custom_nameserver_delete_response.py b/src/cloudflare/types/tenant_custom_nameservers/tenant_custom_nameserver_delete_response.py deleted file mode 100644 index 9465c20be8a..00000000000 --- a/src/cloudflare/types/tenant_custom_nameservers/tenant_custom_nameserver_delete_response.py +++ /dev/null @@ -1,7 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from typing_extensions import TypeAlias - -__all__ = ["TenantCustomNameserverDeleteResponse"] - -TenantCustomNameserverDeleteResponse: TypeAlias = str diff --git a/src/cloudflare/types/tenant_custom_nameservers/tenant_custom_nameserver_get_response.py b/src/cloudflare/types/tenant_custom_nameservers/tenant_custom_nameserver_get_response.py deleted file mode 100644 index 65b95217b18..00000000000 --- a/src/cloudflare/types/tenant_custom_nameservers/tenant_custom_nameserver_get_response.py +++ /dev/null @@ -1,35 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from typing import List, Optional -from typing_extensions import Literal - -from ..._models import BaseModel - -__all__ = ["TenantCustomNameserverGetResponse", "DNSRecord"] - - -class DNSRecord(BaseModel): - type: Optional[Literal["A", "AAAA"]] = None - """DNS record type.""" - - value: Optional[str] = None - """DNS record contents (an IPv4 or IPv6 address).""" - - -class TenantCustomNameserverGetResponse(BaseModel): - """A single tenant custom nameserver.""" - - dns_records: List[DNSRecord] - """A and AAAA records associated with the nameserver.""" - - ns_name: str - """The FQDN of the name server.""" - - status: Literal["moved", "pending", "verified"] - """Verification status of the nameserver.""" - - zone_tag: str - """Identifier.""" - - ns_set: Optional[float] = None - """The number of the set that this name server belongs to.""" diff --git a/src/cloudflare/types/tenants/__init__.py b/src/cloudflare/types/tenants/__init__.py index bcce8ccb6f5..d1c0c3f7ace 100644 --- a/src/cloudflare/types/tenants/__init__.py +++ b/src/cloudflare/types/tenants/__init__.py @@ -2,8 +2,5 @@ from __future__ import annotations -from .tenant import Tenant as Tenant -from .tenant_account import TenantAccount as TenantAccount -from .tenant_membership import TenantMembership as TenantMembership -from .tenant_entitlements import TenantEntitlements as TenantEntitlements -from .account_type_list_response import AccountTypeListResponse as AccountTypeListResponse +from .account_list_params import AccountListParams as AccountListParams +from .account_list_response import AccountListResponse as AccountListResponse diff --git a/src/cloudflare/types/tenants/account_list_params.py b/src/cloudflare/types/tenants/account_list_params.py new file mode 100644 index 00000000000..0e641f358bb --- /dev/null +++ b/src/cloudflare/types/tenants/account_list_params.py @@ -0,0 +1,101 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal, Annotated, TypedDict + +from ..._utils import PropertyInfo + +__all__ = ["AccountListParams", "AccountPubname", "Name"] + + +class AccountListParams(TypedDict, total=False): + account_pubname: AccountPubname + + direction: Literal["asc", "desc"] + """Sort direction for the order_by field. + + Valid values: `asc`, `desc`. Defaults to `asc` when order_by is specified. + """ + + include_total: bool + """ + Whether to calculate and return the exact `result_info.total_size` for cursor + pagination. Defaults to true. When false, `total_size` is omitted. Legacy + `page`/`per_page` requests always calculate `total_count`. + """ + + name: Name + + order_by: Literal["account_name"] + """Field to order results by. Currently supported values: `account_name`.""" + + page: int + """Legacy offset page number. + + Must be provided with `per_page`. Values below 1 are treated as + + 1. Cursor pagination takes precedence when requested. + """ + + page_size: int + """The amount of items to return. Defaults to 10.""" + + page_token: str + """ + An opaque token returned from the last list response that when provided will + retrieve the next page. + + Parameters used to filter the retrieved list must remain in subsequent requests + with a page token. + """ + + per_page: int + """Legacy offset page size. + + Must be provided with `page`. Values are clamped to the range 1-100. Cursor + pagination takes precedence when requested. + """ + + status: Literal["active", "deleted"] + """Filter accounts by lifecycle status. Defaults to `active`.""" + + +class AccountPubname(TypedDict, total=False): + contains: str + """ + (case-insensitive) Filter the list of accounts to where the account_pubname + contains a particular string. + """ + + ends_with: Annotated[str, PropertyInfo(alias="endsWith")] + """ + (case-insensitive) Filter the list of accounts to where the account_pubname ends + with a particular string. + """ + + starts_with: Annotated[str, PropertyInfo(alias="startsWith")] + """ + (case-insensitive) Filter the list of accounts to where the account_pubname + starts with a particular string. + """ + + +class Name(TypedDict, total=False): + contains: str + """ + (case-insensitive) Filter the list of accounts to where the name contains a + particular string. + """ + + ends_with: Annotated[str, PropertyInfo(alias="endsWith")] + """ + (case-insensitive) Filter the list of accounts to where the name ends with a + particular string. + """ + + starts_with: Annotated[str, PropertyInfo(alias="startsWith")] + """ + (case-insensitive) Filter the list of accounts to where the name starts with a + particular string. + """ diff --git a/src/cloudflare/types/tenants/account_list_response.py b/src/cloudflare/types/tenants/account_list_response.py new file mode 100644 index 00000000000..42c3de3446e --- /dev/null +++ b/src/cloudflare/types/tenants/account_list_response.py @@ -0,0 +1,31 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional +from datetime import datetime +from typing_extensions import Literal + +from ..._models import BaseModel + +__all__ = ["AccountListResponse", "Settings"] + + +class Settings(BaseModel): + access_approval_expiry: Optional[datetime] = None + + api_access_enabled: bool + + enforce_two_factor: bool + + use_account_custom_ns_by_default: bool + + +class AccountListResponse(BaseModel): + account_pubname: Optional[str] = None + + account_tag: str + + account_type: Literal["standard", "enterprise"] + + created_on: datetime + + settings: Settings diff --git a/src/cloudflare/types/tenants/tenant.py b/src/cloudflare/types/tenants/tenant.py deleted file mode 100644 index 8d8fb67b791..00000000000 --- a/src/cloudflare/types/tenants/tenant.py +++ /dev/null @@ -1,66 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from typing import List, Optional -from datetime import datetime - -from ..._models import BaseModel - -__all__ = ["Tenant", "TenantContacts", "TenantMetadata", "TenantMetadataDNS", "TenantMetadataDNSNSPool", "TenantUnit"] - - -class TenantContacts(BaseModel): - email: Optional[str] = None - - website: Optional[str] = None - - -class TenantMetadataDNSNSPool(BaseModel): - primary: Optional[str] = None - - secondary: Optional[str] = None - - -class TenantMetadataDNS(BaseModel): - ns_pool: TenantMetadataDNSNSPool - - -class TenantMetadata(BaseModel): - dns: Optional[TenantMetadataDNS] = None - - -class TenantUnit(BaseModel): - unit_memberships: List[object] - - unit_metadata: object - - unit_name: str - - unit_status: str - - unit_tag: str - - -class Tenant(BaseModel): - cdate: datetime - - edate: datetime - - tenant_contacts: TenantContacts - - tenant_labels: List[str] - - tenant_metadata: TenantMetadata - - tenant_name: str - - tenant_network: object - - tenant_status: str - - tenant_tag: str - - tenant_type: str - - tenant_units: List[TenantUnit] - - customer_id: Optional[str] = None diff --git a/src/cloudflare/types/tenants/tenant_account.py b/src/cloudflare/types/tenants/tenant_account.py deleted file mode 100644 index b67b0ccb076..00000000000 --- a/src/cloudflare/types/tenants/tenant_account.py +++ /dev/null @@ -1,48 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from typing import Dict, Optional -from datetime import datetime -from typing_extensions import Literal - -from ..._models import BaseModel - -__all__ = ["TenantAccount", "Settings"] - - -class Settings(BaseModel): - abuse_contact_email: Optional[str] = None - - access_approval_expiry: Optional[datetime] = None - - api_access_enabled: Optional[bool] = None - - default_nameservers: Optional[str] = None - """ - Use - [DNS Settings](https://developers.cloudflare.com/api/operations/dns-settings-for-an-account-list-dns-settings) - instead. Deprecated. - """ - - enforce_twofactor: Optional[bool] = None - - use_account_custom_ns_by_default: Optional[bool] = None - """ - Use - [DNS Settings](https://developers.cloudflare.com/api/operations/dns-settings-for-an-account-list-dns-settings) - instead. Deprecated. - """ - - -class TenantAccount(BaseModel): - id: str - - created_on: datetime - - name: Optional[str] = None - - settings: Settings - - type: Literal["standard", "enterprise"] - - tags: Optional[Dict[str, str]] = None - """Account tags, present only when `include_tags=true` is requested.""" diff --git a/src/cloudflare/types/tenants/tenant_entitlements.py b/src/cloudflare/types/tenants/tenant_entitlements.py deleted file mode 100644 index a404e4e34b1..00000000000 --- a/src/cloudflare/types/tenants/tenant_entitlements.py +++ /dev/null @@ -1,100 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from typing import List, Union, Optional -from typing_extensions import Literal, TypeAlias - -from ..._models import BaseModel - -__all__ = [ - "TenantEntitlements", - "AllowAddSubdomain", - "AllowAutoAcceptInvites", - "CNAMESetupAllowed", - "CustomEntitlement", - "CustomEntitlementAllocation", - "CustomEntitlementAllocationOrganizationsAPIMaxCountAllocation", - "CustomEntitlementAllocationOrganizationsAPIBoolAllocation", - "CustomEntitlementAllocationOrganizationsAPINullAllocation", - "CustomEntitlementFeature", - "MhsCertificateCount", - "PartialSetupAllowed", -] - - -class AllowAddSubdomain(BaseModel): - type: Literal["bool"] - - value: bool - - -class AllowAutoAcceptInvites(BaseModel): - type: Literal["bool"] - - value: bool - - -class CNAMESetupAllowed(BaseModel): - type: Literal["bool"] - - value: bool - - -class CustomEntitlementAllocationOrganizationsAPIMaxCountAllocation(BaseModel): - type: Literal["max_count"] - - value: int - - -class CustomEntitlementAllocationOrganizationsAPIBoolAllocation(BaseModel): - type: Literal["bool"] - - value: bool - - -class CustomEntitlementAllocationOrganizationsAPINullAllocation(BaseModel): - type: Literal[""] - - value: Optional[object] = None - - -CustomEntitlementAllocation: TypeAlias = Union[ - CustomEntitlementAllocationOrganizationsAPIMaxCountAllocation, - CustomEntitlementAllocationOrganizationsAPIBoolAllocation, - CustomEntitlementAllocationOrganizationsAPINullAllocation, -] - - -class CustomEntitlementFeature(BaseModel): - key: str - - -class CustomEntitlement(BaseModel): - allocation: CustomEntitlementAllocation - - feature: CustomEntitlementFeature - - -class MhsCertificateCount(BaseModel): - type: Literal["max_count"] - - value: int - - -class PartialSetupAllowed(BaseModel): - type: Literal["bool"] - - value: bool - - -class TenantEntitlements(BaseModel): - allow_add_subdomain: AllowAddSubdomain - - allow_auto_accept_invites: AllowAutoAcceptInvites - - cname_setup_allowed: CNAMESetupAllowed - - custom_entitlements: Optional[List[CustomEntitlement]] = None - - mhs_certificate_count: MhsCertificateCount - - partial_setup_allowed: PartialSetupAllowed diff --git a/src/cloudflare/types/tenants/tenant_membership.py b/src/cloudflare/types/tenants/tenant_membership.py deleted file mode 100644 index 45ca42966e3..00000000000 --- a/src/cloudflare/types/tenants/tenant_membership.py +++ /dev/null @@ -1,13 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from ..._models import BaseModel - -__all__ = ["TenantMembership"] - - -class TenantMembership(BaseModel): - user_email: str - - user_name: str - - user_tag: str diff --git a/src/cloudflare/types/url_normalization/url_normalization_get_response.py b/src/cloudflare/types/url_normalization/url_normalization_get_response.py index 88bda09951c..126b7f3afe3 100644 --- a/src/cloudflare/types/url_normalization/url_normalization_get_response.py +++ b/src/cloudflare/types/url_normalization/url_normalization_get_response.py @@ -1,17 +1,60 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing_extensions import Literal +from typing import Union, Optional +from typing_extensions import Literal, TypeAlias from ..._models import BaseModel -__all__ = ["URLNormalizationGetResponse"] +__all__ = [ + "URLNormalizationGetResponse", + "UnionMember0", + "UnionMember1", + "UnionMember2", + "UnionMember3", + "UnionMember4", +] -class URLNormalizationGetResponse(BaseModel): - """A result.""" +class UnionMember0(BaseModel): + scope: Optional[Literal["incoming", "both", "none"]] = None + """The scope of the URL normalization.""" + + type: Optional[Literal["cloudflare", "rfc3986"]] = None + """The type of URL normalization performed by Cloudflare.""" - scope: Literal["incoming", "both", "none"] + +class UnionMember1(BaseModel): + scope: Optional[Literal["incoming", "both", "none"]] = None """The scope of the URL normalization.""" - type: Literal["cloudflare", "rfc3986"] + type: Optional[Literal["cloudflare", "rfc3986"]] = None """The type of URL normalization performed by Cloudflare.""" + + +class UnionMember2(BaseModel): + scope: Optional[Literal["incoming", "both", "none"]] = None + """The scope of the URL normalization.""" + + type: Optional[Literal["cloudflare", "rfc3986"]] = None + """The type of URL normalization performed by Cloudflare.""" + + +class UnionMember3(BaseModel): + scope: Optional[Literal["incoming", "both", "none"]] = None + """The scope of the URL normalization.""" + + type: Optional[Literal["cloudflare", "rfc3986"]] = None + """The type of URL normalization performed by Cloudflare.""" + + +class UnionMember4(BaseModel): + scope: Optional[Literal["incoming", "both", "none"]] = None + """The scope of the URL normalization.""" + + type: Optional[Literal["cloudflare", "rfc3986"]] = None + """The type of URL normalization performed by Cloudflare.""" + + +URLNormalizationGetResponse: TypeAlias = Union[ + Optional[UnionMember0], UnionMember1, UnionMember2, UnionMember3, UnionMember4 +] diff --git a/src/cloudflare/types/url_normalization/url_normalization_update_response.py b/src/cloudflare/types/url_normalization/url_normalization_update_response.py index d1c1fd7a88c..99ef5003ba4 100644 --- a/src/cloudflare/types/url_normalization/url_normalization_update_response.py +++ b/src/cloudflare/types/url_normalization/url_normalization_update_response.py @@ -1,17 +1,60 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing_extensions import Literal +from typing import Union, Optional +from typing_extensions import Literal, TypeAlias from ..._models import BaseModel -__all__ = ["URLNormalizationUpdateResponse"] +__all__ = [ + "URLNormalizationUpdateResponse", + "UnionMember0", + "UnionMember1", + "UnionMember2", + "UnionMember3", + "UnionMember4", +] -class URLNormalizationUpdateResponse(BaseModel): - """A result.""" +class UnionMember0(BaseModel): + scope: Optional[Literal["incoming", "both", "none"]] = None + """The scope of the URL normalization.""" + + type: Optional[Literal["cloudflare", "rfc3986"]] = None + """The type of URL normalization performed by Cloudflare.""" - scope: Literal["incoming", "both", "none"] + +class UnionMember1(BaseModel): + scope: Optional[Literal["incoming", "both", "none"]] = None """The scope of the URL normalization.""" - type: Literal["cloudflare", "rfc3986"] + type: Optional[Literal["cloudflare", "rfc3986"]] = None """The type of URL normalization performed by Cloudflare.""" + + +class UnionMember2(BaseModel): + scope: Optional[Literal["incoming", "both", "none"]] = None + """The scope of the URL normalization.""" + + type: Optional[Literal["cloudflare", "rfc3986"]] = None + """The type of URL normalization performed by Cloudflare.""" + + +class UnionMember3(BaseModel): + scope: Optional[Literal["incoming", "both", "none"]] = None + """The scope of the URL normalization.""" + + type: Optional[Literal["cloudflare", "rfc3986"]] = None + """The type of URL normalization performed by Cloudflare.""" + + +class UnionMember4(BaseModel): + scope: Optional[Literal["incoming", "both", "none"]] = None + """The scope of the URL normalization.""" + + type: Optional[Literal["cloudflare", "rfc3986"]] = None + """The type of URL normalization performed by Cloudflare.""" + + +URLNormalizationUpdateResponse: TypeAlias = Union[ + Optional[UnionMember0], UnionMember1, UnionMember2, UnionMember3, UnionMember4 +] diff --git a/src/cloudflare/types/url_scanner/scan_create_params.py b/src/cloudflare/types/url_scanner/scan_create_params.py index f991bf2dd71..ddac8838cba 100644 --- a/src/cloudflare/types/url_scanner/scan_create_params.py +++ b/src/cloudflare/types/url_scanner/scan_create_params.py @@ -20,199 +20,144 @@ class ScanCreateParams(TypedDict, total=False): """Enable agent readiness checks.""" country: Literal[ - "AF", + "AE", "AL", - "DZ", - "AD", + "AM", "AO", - "AG", "AR", - "AM", - "AU", "AT", + "AU", "AZ", - "BH", - "BD", "BB", - "BY", + "BD", "BE", - "BZ", - "BJ", - "BM", - "BT", + "BF", + "BG", + "BH", + "BN", "BO", - "BA", - "BW", "BR", - "BN", - "BG", - "BF", - "BI", - "KH", - "CM", + "BT", + "BW", + "BY", "CA", - "CV", - "KY", - "CF", - "TD", + "CD", + "CH", + "CI", "CL", - "CN", + "CM", "CO", - "KM", - "CG", "CR", - "CI", - "HR", - "CU", + "CW", "CY", "CZ", - "CD", - "DK", + "DE", "DJ", - "DM", + "DK", "DO", + "DZ", "EC", - "EG", - "SV", - "GQ", - "ER", "EE", - "SZ", + "EG", + "ES", "ET", - "FJ", "FI", + "FJ", "FR", - "GA", + "GB", + "GD", "GE", - "DE", "GH", "GR", - "GL", - "GD", "GT", - "GN", - "GW", + "GU", "GY", - "HT", + "HK", "HN", + "HR", + "HT", "HU", - "IS", - "IN", "ID", - "IR", - "IQ", "IE", "IL", + "IN", + "IQ", + "IS", "IT", "JM", - "JP", "JO", - "KZ", + "JP", "KE", - "KI", - "KW", "KG", + "KH", + "KR", + "KW", + "KZ", "LA", - "LV", "LB", - "LS", + "LK", "LR", - "LY", - "LI", "LT", "LU", - "MO", + "LV", + "MA", + "MD", "MG", - "MW", - "MY", - "MV", - "ML", - "MR", + "MK", + "MM", + "MN", + "MO", + "MT", "MU", + "MV", + "MW", "MX", - "FM", - "MD", - "MC", - "MN", - "MS", - "MA", + "MY", "MZ", - "MM", "NA", - "NR", - "NP", - "NL", - "NZ", - "NI", - "NE", + "NC", "NG", - "KP", - "MK", + "NL", "NO", + "NP", + "NZ", "OM", - "PK", - "PS", "PA", - "PG", - "PY", "PE", + "PF", "PH", + "PK", "PL", + "PR", + "PS", "PT", + "PY", "QA", + "RE", "RO", + "RS", "RU", "RW", - "SH", - "KN", - "LC", - "VC", - "WS", - "SM", - "ST", "SA", - "SN", - "RS", - "SC", - "SL", - "SK", + "SE", + "SG", "SI", - "SB", - "SO", - "ZA", - "KR", - "SS", - "ES", - "LK", - "SD", + "SK", + "SN", "SR", - "SE", - "CH", - "SY", - "TW", - "TJ", - "TZ", "TH", - "BS", - "GM", - "TL", - "TG", - "TO", - "TT", + "TJ", "TN", "TR", - "TM", - "UG", + "TT", + "TW", + "TZ", "UA", - "AE", - "GB", + "UG", "US", - "UY", "UZ", - "VU", - "VE", "VN", - "YE", + "ZA", "ZM", "ZW", ] diff --git a/src/cloudflare/types/url_scanner/scan_get_response.py b/src/cloudflare/types/url_scanner/scan_get_response.py index 12a1e95fe55..379dfebd73c 100644 --- a/src/cloudflare/types/url_scanner/scan_get_response.py +++ b/src/cloudflare/types/url_scanner/scan_get_response.py @@ -55,115 +55,143 @@ "MetaProcessorsAgentReadinessChecksBotAccessControlContentSignalsEvidenceFinding", "MetaProcessorsAgentReadinessChecksBotAccessControlContentSignalsEvidenceRequest", "MetaProcessorsAgentReadinessChecksBotAccessControlContentSignalsEvidenceResponse", + "MetaProcessorsAgentReadinessChecksBotAccessControlContentSignalsMessageRef", "MetaProcessorsAgentReadinessChecksBotAccessControlRobotsTXTAIRules", "MetaProcessorsAgentReadinessChecksBotAccessControlRobotsTxtaiRulesEvidence", "MetaProcessorsAgentReadinessChecksBotAccessControlRobotsTxtaiRulesEvidenceFinding", "MetaProcessorsAgentReadinessChecksBotAccessControlRobotsTxtaiRulesEvidenceRequest", "MetaProcessorsAgentReadinessChecksBotAccessControlRobotsTxtaiRulesEvidenceResponse", + "MetaProcessorsAgentReadinessChecksBotAccessControlRobotsTXTAIRulesMessageRef", "MetaProcessorsAgentReadinessChecksBotAccessControlWebBotAuth", "MetaProcessorsAgentReadinessChecksBotAccessControlWebBotAuthEvidence", "MetaProcessorsAgentReadinessChecksBotAccessControlWebBotAuthEvidenceFinding", "MetaProcessorsAgentReadinessChecksBotAccessControlWebBotAuthEvidenceRequest", "MetaProcessorsAgentReadinessChecksBotAccessControlWebBotAuthEvidenceResponse", + "MetaProcessorsAgentReadinessChecksBotAccessControlWebBotAuthMessageRef", "MetaProcessorsAgentReadinessChecksCommerce", "MetaProcessorsAgentReadinessChecksCommerceAcp", "MetaProcessorsAgentReadinessChecksCommerceAcpEvidence", "MetaProcessorsAgentReadinessChecksCommerceAcpEvidenceFinding", "MetaProcessorsAgentReadinessChecksCommerceAcpEvidenceRequest", "MetaProcessorsAgentReadinessChecksCommerceAcpEvidenceResponse", + "MetaProcessorsAgentReadinessChecksCommerceAcpMessageRef", "MetaProcessorsAgentReadinessChecksCommerceAp2", "MetaProcessorsAgentReadinessChecksCommerceAp2Evidence", "MetaProcessorsAgentReadinessChecksCommerceAp2EvidenceFinding", "MetaProcessorsAgentReadinessChecksCommerceAp2EvidenceRequest", "MetaProcessorsAgentReadinessChecksCommerceAp2EvidenceResponse", + "MetaProcessorsAgentReadinessChecksCommerceAp2MessageRef", "MetaProcessorsAgentReadinessChecksCommerceMpp", "MetaProcessorsAgentReadinessChecksCommerceMppEvidence", "MetaProcessorsAgentReadinessChecksCommerceMppEvidenceFinding", "MetaProcessorsAgentReadinessChecksCommerceMppEvidenceRequest", "MetaProcessorsAgentReadinessChecksCommerceMppEvidenceResponse", + "MetaProcessorsAgentReadinessChecksCommerceMppMessageRef", "MetaProcessorsAgentReadinessChecksCommerceUcp", "MetaProcessorsAgentReadinessChecksCommerceUcpEvidence", "MetaProcessorsAgentReadinessChecksCommerceUcpEvidenceFinding", "MetaProcessorsAgentReadinessChecksCommerceUcpEvidenceRequest", "MetaProcessorsAgentReadinessChecksCommerceUcpEvidenceResponse", + "MetaProcessorsAgentReadinessChecksCommerceUcpMessageRef", "MetaProcessorsAgentReadinessChecksCommerceX402", "MetaProcessorsAgentReadinessChecksCommerceX402Evidence", "MetaProcessorsAgentReadinessChecksCommerceX402EvidenceFinding", "MetaProcessorsAgentReadinessChecksCommerceX402EvidenceRequest", "MetaProcessorsAgentReadinessChecksCommerceX402EvidenceResponse", + "MetaProcessorsAgentReadinessChecksCommerceX402MessageRef", "MetaProcessorsAgentReadinessChecksContentAccessibility", "MetaProcessorsAgentReadinessChecksContentAccessibilityMarkdownNegotiation", "MetaProcessorsAgentReadinessChecksContentAccessibilityMarkdownNegotiationEvidence", "MetaProcessorsAgentReadinessChecksContentAccessibilityMarkdownNegotiationEvidenceFinding", "MetaProcessorsAgentReadinessChecksContentAccessibilityMarkdownNegotiationEvidenceRequest", "MetaProcessorsAgentReadinessChecksContentAccessibilityMarkdownNegotiationEvidenceResponse", + "MetaProcessorsAgentReadinessChecksContentAccessibilityMarkdownNegotiationMessageRef", "MetaProcessorsAgentReadinessChecksDiscoverability", "MetaProcessorsAgentReadinessChecksDiscoverabilityDNSAid", "MetaProcessorsAgentReadinessChecksDiscoverabilityDNSAidEvidence", "MetaProcessorsAgentReadinessChecksDiscoverabilityDNSAidEvidenceFinding", "MetaProcessorsAgentReadinessChecksDiscoverabilityDNSAidEvidenceRequest", "MetaProcessorsAgentReadinessChecksDiscoverabilityDNSAidEvidenceResponse", + "MetaProcessorsAgentReadinessChecksDiscoverabilityDNSAidMessageRef", "MetaProcessorsAgentReadinessChecksDiscoverabilityLinkHeaders", "MetaProcessorsAgentReadinessChecksDiscoverabilityLinkHeadersEvidence", "MetaProcessorsAgentReadinessChecksDiscoverabilityLinkHeadersEvidenceFinding", "MetaProcessorsAgentReadinessChecksDiscoverabilityLinkHeadersEvidenceRequest", "MetaProcessorsAgentReadinessChecksDiscoverabilityLinkHeadersEvidenceResponse", + "MetaProcessorsAgentReadinessChecksDiscoverabilityLinkHeadersMessageRef", "MetaProcessorsAgentReadinessChecksDiscoverabilityRobotsTXT", "MetaProcessorsAgentReadinessChecksDiscoverabilityRobotsTXTEvidence", "MetaProcessorsAgentReadinessChecksDiscoverabilityRobotsTXTEvidenceFinding", "MetaProcessorsAgentReadinessChecksDiscoverabilityRobotsTXTEvidenceRequest", "MetaProcessorsAgentReadinessChecksDiscoverabilityRobotsTXTEvidenceResponse", + "MetaProcessorsAgentReadinessChecksDiscoverabilityRobotsTXTMessageRef", "MetaProcessorsAgentReadinessChecksDiscoverabilitySitemap", "MetaProcessorsAgentReadinessChecksDiscoverabilitySitemapEvidence", "MetaProcessorsAgentReadinessChecksDiscoverabilitySitemapEvidenceFinding", "MetaProcessorsAgentReadinessChecksDiscoverabilitySitemapEvidenceRequest", "MetaProcessorsAgentReadinessChecksDiscoverabilitySitemapEvidenceResponse", + "MetaProcessorsAgentReadinessChecksDiscoverabilitySitemapMessageRef", "MetaProcessorsAgentReadinessChecksDiscovery", "MetaProcessorsAgentReadinessChecksDiscoveryA2aAgentCard", "MetaProcessorsAgentReadinessChecksDiscoveryA2aAgentCardEvidence", "MetaProcessorsAgentReadinessChecksDiscoveryA2aAgentCardEvidenceFinding", "MetaProcessorsAgentReadinessChecksDiscoveryA2aAgentCardEvidenceRequest", "MetaProcessorsAgentReadinessChecksDiscoveryA2aAgentCardEvidenceResponse", + "MetaProcessorsAgentReadinessChecksDiscoveryA2aAgentCardMessageRef", "MetaProcessorsAgentReadinessChecksDiscoveryAgentSkills", "MetaProcessorsAgentReadinessChecksDiscoveryAgentSkillsEvidence", "MetaProcessorsAgentReadinessChecksDiscoveryAgentSkillsEvidenceFinding", "MetaProcessorsAgentReadinessChecksDiscoveryAgentSkillsEvidenceRequest", "MetaProcessorsAgentReadinessChecksDiscoveryAgentSkillsEvidenceResponse", + "MetaProcessorsAgentReadinessChecksDiscoveryAgentSkillsMessageRef", "MetaProcessorsAgentReadinessChecksDiscoveryAPICatalog", "MetaProcessorsAgentReadinessChecksDiscoveryAPICatalogEvidence", "MetaProcessorsAgentReadinessChecksDiscoveryAPICatalogEvidenceFinding", "MetaProcessorsAgentReadinessChecksDiscoveryAPICatalogEvidenceRequest", "MetaProcessorsAgentReadinessChecksDiscoveryAPICatalogEvidenceResponse", + "MetaProcessorsAgentReadinessChecksDiscoveryAPICatalogMessageRef", "MetaProcessorsAgentReadinessChecksDiscoveryArd", "MetaProcessorsAgentReadinessChecksDiscoveryArdEvidence", "MetaProcessorsAgentReadinessChecksDiscoveryArdEvidenceFinding", "MetaProcessorsAgentReadinessChecksDiscoveryArdEvidenceRequest", "MetaProcessorsAgentReadinessChecksDiscoveryArdEvidenceResponse", + "MetaProcessorsAgentReadinessChecksDiscoveryArdMessageRef", "MetaProcessorsAgentReadinessChecksDiscoveryAuthMd", "MetaProcessorsAgentReadinessChecksDiscoveryAuthMdEvidence", "MetaProcessorsAgentReadinessChecksDiscoveryAuthMdEvidenceFinding", "MetaProcessorsAgentReadinessChecksDiscoveryAuthMdEvidenceRequest", "MetaProcessorsAgentReadinessChecksDiscoveryAuthMdEvidenceResponse", + "MetaProcessorsAgentReadinessChecksDiscoveryAuthMdMessageRef", "MetaProcessorsAgentReadinessChecksDiscoveryMcpServerCard", "MetaProcessorsAgentReadinessChecksDiscoveryMcpServerCardEvidence", "MetaProcessorsAgentReadinessChecksDiscoveryMcpServerCardEvidenceFinding", "MetaProcessorsAgentReadinessChecksDiscoveryMcpServerCardEvidenceRequest", "MetaProcessorsAgentReadinessChecksDiscoveryMcpServerCardEvidenceResponse", + "MetaProcessorsAgentReadinessChecksDiscoveryMcpServerCardMessageRef", "MetaProcessorsAgentReadinessChecksDiscoveryOAuthDiscovery", "MetaProcessorsAgentReadinessChecksDiscoveryOAuthDiscoveryEvidence", "MetaProcessorsAgentReadinessChecksDiscoveryOAuthDiscoveryEvidenceFinding", "MetaProcessorsAgentReadinessChecksDiscoveryOAuthDiscoveryEvidenceRequest", "MetaProcessorsAgentReadinessChecksDiscoveryOAuthDiscoveryEvidenceResponse", + "MetaProcessorsAgentReadinessChecksDiscoveryOAuthDiscoveryMessageRef", "MetaProcessorsAgentReadinessChecksDiscoveryOAuthProtectedResource", "MetaProcessorsAgentReadinessChecksDiscoveryOAuthProtectedResourceEvidence", "MetaProcessorsAgentReadinessChecksDiscoveryOAuthProtectedResourceEvidenceFinding", "MetaProcessorsAgentReadinessChecksDiscoveryOAuthProtectedResourceEvidenceRequest", "MetaProcessorsAgentReadinessChecksDiscoveryOAuthProtectedResourceEvidenceResponse", + "MetaProcessorsAgentReadinessChecksDiscoveryOAuthProtectedResourceMessageRef", + "MetaProcessorsAgentReadinessChecksDiscoveryPersonalAgentProtocol", + "MetaProcessorsAgentReadinessChecksDiscoveryPersonalAgentProtocolEvidence", + "MetaProcessorsAgentReadinessChecksDiscoveryPersonalAgentProtocolEvidenceFinding", + "MetaProcessorsAgentReadinessChecksDiscoveryPersonalAgentProtocolEvidenceRequest", + "MetaProcessorsAgentReadinessChecksDiscoveryPersonalAgentProtocolEvidenceResponse", + "MetaProcessorsAgentReadinessChecksDiscoveryPersonalAgentProtocolMessageRef", "MetaProcessorsAgentReadinessChecksDiscoveryWebMcp", "MetaProcessorsAgentReadinessChecksDiscoveryWebMcpEvidence", "MetaProcessorsAgentReadinessChecksDiscoveryWebMcpEvidenceFinding", "MetaProcessorsAgentReadinessChecksDiscoveryWebMcpEvidenceRequest", "MetaProcessorsAgentReadinessChecksDiscoveryWebMcpEvidenceResponse", + "MetaProcessorsAgentReadinessChecksDiscoveryWebMcpMessageRef", "MetaProcessorsAgentReadinessNextLevel", "MetaProcessorsAgentReadinessNextLevelRequirement", "MetaProcessorsPhishingV2", @@ -662,6 +690,13 @@ class MetaProcessorsAgentReadinessChecksBotAccessControlContentSignalsEvidence(B response: Optional[MetaProcessorsAgentReadinessChecksBotAccessControlContentSignalsEvidenceResponse] = None +class MetaProcessorsAgentReadinessChecksBotAccessControlContentSignalsMessageRef(BaseModel): + code: str + """Stable, translatable message code.""" + + params: Optional[object] = None + + class MetaProcessorsAgentReadinessChecksBotAccessControlContentSignals(BaseModel): status: str @@ -673,6 +708,10 @@ class MetaProcessorsAgentReadinessChecksBotAccessControlContentSignals(BaseModel message: Optional[str] = None + message_ref: Optional[MetaProcessorsAgentReadinessChecksBotAccessControlContentSignalsMessageRef] = FieldInfo( + alias="messageRef", default=None + ) + class MetaProcessorsAgentReadinessChecksBotAccessControlRobotsTxtaiRulesEvidenceFinding(BaseModel): outcome: str @@ -714,6 +753,13 @@ class MetaProcessorsAgentReadinessChecksBotAccessControlRobotsTxtaiRulesEvidence response: Optional[MetaProcessorsAgentReadinessChecksBotAccessControlRobotsTxtaiRulesEvidenceResponse] = None +class MetaProcessorsAgentReadinessChecksBotAccessControlRobotsTXTAIRulesMessageRef(BaseModel): + code: str + """Stable, translatable message code.""" + + params: Optional[object] = None + + class MetaProcessorsAgentReadinessChecksBotAccessControlRobotsTXTAIRules(BaseModel): status: str @@ -725,6 +771,10 @@ class MetaProcessorsAgentReadinessChecksBotAccessControlRobotsTXTAIRules(BaseMod message: Optional[str] = None + message_ref: Optional[MetaProcessorsAgentReadinessChecksBotAccessControlRobotsTXTAIRulesMessageRef] = FieldInfo( + alias="messageRef", default=None + ) + class MetaProcessorsAgentReadinessChecksBotAccessControlWebBotAuthEvidenceFinding(BaseModel): outcome: str @@ -766,6 +816,13 @@ class MetaProcessorsAgentReadinessChecksBotAccessControlWebBotAuthEvidence(BaseM response: Optional[MetaProcessorsAgentReadinessChecksBotAccessControlWebBotAuthEvidenceResponse] = None +class MetaProcessorsAgentReadinessChecksBotAccessControlWebBotAuthMessageRef(BaseModel): + code: str + """Stable, translatable message code.""" + + params: Optional[object] = None + + class MetaProcessorsAgentReadinessChecksBotAccessControlWebBotAuth(BaseModel): status: str @@ -777,6 +834,10 @@ class MetaProcessorsAgentReadinessChecksBotAccessControlWebBotAuth(BaseModel): message: Optional[str] = None + message_ref: Optional[MetaProcessorsAgentReadinessChecksBotAccessControlWebBotAuthMessageRef] = FieldInfo( + alias="messageRef", default=None + ) + class MetaProcessorsAgentReadinessChecksBotAccessControl(BaseModel): content_signals: MetaProcessorsAgentReadinessChecksBotAccessControlContentSignals = FieldInfo( @@ -830,6 +891,13 @@ class MetaProcessorsAgentReadinessChecksCommerceAcpEvidence(BaseModel): response: Optional[MetaProcessorsAgentReadinessChecksCommerceAcpEvidenceResponse] = None +class MetaProcessorsAgentReadinessChecksCommerceAcpMessageRef(BaseModel): + code: str + """Stable, translatable message code.""" + + params: Optional[object] = None + + class MetaProcessorsAgentReadinessChecksCommerceAcp(BaseModel): status: str @@ -841,6 +909,10 @@ class MetaProcessorsAgentReadinessChecksCommerceAcp(BaseModel): message: Optional[str] = None + message_ref: Optional[MetaProcessorsAgentReadinessChecksCommerceAcpMessageRef] = FieldInfo( + alias="messageRef", default=None + ) + class MetaProcessorsAgentReadinessChecksCommerceAp2EvidenceFinding(BaseModel): outcome: str @@ -882,6 +954,13 @@ class MetaProcessorsAgentReadinessChecksCommerceAp2Evidence(BaseModel): response: Optional[MetaProcessorsAgentReadinessChecksCommerceAp2EvidenceResponse] = None +class MetaProcessorsAgentReadinessChecksCommerceAp2MessageRef(BaseModel): + code: str + """Stable, translatable message code.""" + + params: Optional[object] = None + + class MetaProcessorsAgentReadinessChecksCommerceAp2(BaseModel): status: str @@ -893,6 +972,10 @@ class MetaProcessorsAgentReadinessChecksCommerceAp2(BaseModel): message: Optional[str] = None + message_ref: Optional[MetaProcessorsAgentReadinessChecksCommerceAp2MessageRef] = FieldInfo( + alias="messageRef", default=None + ) + class MetaProcessorsAgentReadinessChecksCommerceMppEvidenceFinding(BaseModel): outcome: str @@ -934,6 +1017,13 @@ class MetaProcessorsAgentReadinessChecksCommerceMppEvidence(BaseModel): response: Optional[MetaProcessorsAgentReadinessChecksCommerceMppEvidenceResponse] = None +class MetaProcessorsAgentReadinessChecksCommerceMppMessageRef(BaseModel): + code: str + """Stable, translatable message code.""" + + params: Optional[object] = None + + class MetaProcessorsAgentReadinessChecksCommerceMpp(BaseModel): status: str @@ -945,6 +1035,10 @@ class MetaProcessorsAgentReadinessChecksCommerceMpp(BaseModel): message: Optional[str] = None + message_ref: Optional[MetaProcessorsAgentReadinessChecksCommerceMppMessageRef] = FieldInfo( + alias="messageRef", default=None + ) + class MetaProcessorsAgentReadinessChecksCommerceUcpEvidenceFinding(BaseModel): outcome: str @@ -986,6 +1080,13 @@ class MetaProcessorsAgentReadinessChecksCommerceUcpEvidence(BaseModel): response: Optional[MetaProcessorsAgentReadinessChecksCommerceUcpEvidenceResponse] = None +class MetaProcessorsAgentReadinessChecksCommerceUcpMessageRef(BaseModel): + code: str + """Stable, translatable message code.""" + + params: Optional[object] = None + + class MetaProcessorsAgentReadinessChecksCommerceUcp(BaseModel): status: str @@ -997,6 +1098,10 @@ class MetaProcessorsAgentReadinessChecksCommerceUcp(BaseModel): message: Optional[str] = None + message_ref: Optional[MetaProcessorsAgentReadinessChecksCommerceUcpMessageRef] = FieldInfo( + alias="messageRef", default=None + ) + class MetaProcessorsAgentReadinessChecksCommerceX402EvidenceFinding(BaseModel): outcome: str @@ -1038,6 +1143,13 @@ class MetaProcessorsAgentReadinessChecksCommerceX402Evidence(BaseModel): response: Optional[MetaProcessorsAgentReadinessChecksCommerceX402EvidenceResponse] = None +class MetaProcessorsAgentReadinessChecksCommerceX402MessageRef(BaseModel): + code: str + """Stable, translatable message code.""" + + params: Optional[object] = None + + class MetaProcessorsAgentReadinessChecksCommerceX402(BaseModel): status: str @@ -1049,6 +1161,10 @@ class MetaProcessorsAgentReadinessChecksCommerceX402(BaseModel): message: Optional[str] = None + message_ref: Optional[MetaProcessorsAgentReadinessChecksCommerceX402MessageRef] = FieldInfo( + alias="messageRef", default=None + ) + class MetaProcessorsAgentReadinessChecksCommerce(BaseModel): acp: MetaProcessorsAgentReadinessChecksCommerceAcp @@ -1102,6 +1218,13 @@ class MetaProcessorsAgentReadinessChecksContentAccessibilityMarkdownNegotiationE response: Optional[MetaProcessorsAgentReadinessChecksContentAccessibilityMarkdownNegotiationEvidenceResponse] = None +class MetaProcessorsAgentReadinessChecksContentAccessibilityMarkdownNegotiationMessageRef(BaseModel): + code: str + """Stable, translatable message code.""" + + params: Optional[object] = None + + class MetaProcessorsAgentReadinessChecksContentAccessibilityMarkdownNegotiation(BaseModel): status: str @@ -1113,6 +1236,10 @@ class MetaProcessorsAgentReadinessChecksContentAccessibilityMarkdownNegotiation( message: Optional[str] = None + message_ref: Optional[MetaProcessorsAgentReadinessChecksContentAccessibilityMarkdownNegotiationMessageRef] = ( + FieldInfo(alias="messageRef", default=None) + ) + class MetaProcessorsAgentReadinessChecksContentAccessibility(BaseModel): markdown_negotiation: MetaProcessorsAgentReadinessChecksContentAccessibilityMarkdownNegotiation = FieldInfo( @@ -1160,6 +1287,13 @@ class MetaProcessorsAgentReadinessChecksDiscoverabilityDNSAidEvidence(BaseModel) response: Optional[MetaProcessorsAgentReadinessChecksDiscoverabilityDNSAidEvidenceResponse] = None +class MetaProcessorsAgentReadinessChecksDiscoverabilityDNSAidMessageRef(BaseModel): + code: str + """Stable, translatable message code.""" + + params: Optional[object] = None + + class MetaProcessorsAgentReadinessChecksDiscoverabilityDNSAid(BaseModel): status: str @@ -1171,6 +1305,10 @@ class MetaProcessorsAgentReadinessChecksDiscoverabilityDNSAid(BaseModel): message: Optional[str] = None + message_ref: Optional[MetaProcessorsAgentReadinessChecksDiscoverabilityDNSAidMessageRef] = FieldInfo( + alias="messageRef", default=None + ) + class MetaProcessorsAgentReadinessChecksDiscoverabilityLinkHeadersEvidenceFinding(BaseModel): outcome: str @@ -1212,6 +1350,13 @@ class MetaProcessorsAgentReadinessChecksDiscoverabilityLinkHeadersEvidence(BaseM response: Optional[MetaProcessorsAgentReadinessChecksDiscoverabilityLinkHeadersEvidenceResponse] = None +class MetaProcessorsAgentReadinessChecksDiscoverabilityLinkHeadersMessageRef(BaseModel): + code: str + """Stable, translatable message code.""" + + params: Optional[object] = None + + class MetaProcessorsAgentReadinessChecksDiscoverabilityLinkHeaders(BaseModel): status: str @@ -1223,6 +1368,10 @@ class MetaProcessorsAgentReadinessChecksDiscoverabilityLinkHeaders(BaseModel): message: Optional[str] = None + message_ref: Optional[MetaProcessorsAgentReadinessChecksDiscoverabilityLinkHeadersMessageRef] = FieldInfo( + alias="messageRef", default=None + ) + class MetaProcessorsAgentReadinessChecksDiscoverabilityRobotsTXTEvidenceFinding(BaseModel): outcome: str @@ -1264,6 +1413,13 @@ class MetaProcessorsAgentReadinessChecksDiscoverabilityRobotsTXTEvidence(BaseMod response: Optional[MetaProcessorsAgentReadinessChecksDiscoverabilityRobotsTXTEvidenceResponse] = None +class MetaProcessorsAgentReadinessChecksDiscoverabilityRobotsTXTMessageRef(BaseModel): + code: str + """Stable, translatable message code.""" + + params: Optional[object] = None + + class MetaProcessorsAgentReadinessChecksDiscoverabilityRobotsTXT(BaseModel): status: str @@ -1275,6 +1431,10 @@ class MetaProcessorsAgentReadinessChecksDiscoverabilityRobotsTXT(BaseModel): message: Optional[str] = None + message_ref: Optional[MetaProcessorsAgentReadinessChecksDiscoverabilityRobotsTXTMessageRef] = FieldInfo( + alias="messageRef", default=None + ) + class MetaProcessorsAgentReadinessChecksDiscoverabilitySitemapEvidenceFinding(BaseModel): outcome: str @@ -1316,6 +1476,13 @@ class MetaProcessorsAgentReadinessChecksDiscoverabilitySitemapEvidence(BaseModel response: Optional[MetaProcessorsAgentReadinessChecksDiscoverabilitySitemapEvidenceResponse] = None +class MetaProcessorsAgentReadinessChecksDiscoverabilitySitemapMessageRef(BaseModel): + code: str + """Stable, translatable message code.""" + + params: Optional[object] = None + + class MetaProcessorsAgentReadinessChecksDiscoverabilitySitemap(BaseModel): status: str @@ -1327,6 +1494,10 @@ class MetaProcessorsAgentReadinessChecksDiscoverabilitySitemap(BaseModel): message: Optional[str] = None + message_ref: Optional[MetaProcessorsAgentReadinessChecksDiscoverabilitySitemapMessageRef] = FieldInfo( + alias="messageRef", default=None + ) + class MetaProcessorsAgentReadinessChecksDiscoverability(BaseModel): dns_aid: MetaProcessorsAgentReadinessChecksDiscoverabilityDNSAid = FieldInfo(alias="dnsAid") @@ -1378,6 +1549,13 @@ class MetaProcessorsAgentReadinessChecksDiscoveryA2aAgentCardEvidence(BaseModel) response: Optional[MetaProcessorsAgentReadinessChecksDiscoveryA2aAgentCardEvidenceResponse] = None +class MetaProcessorsAgentReadinessChecksDiscoveryA2aAgentCardMessageRef(BaseModel): + code: str + """Stable, translatable message code.""" + + params: Optional[object] = None + + class MetaProcessorsAgentReadinessChecksDiscoveryA2aAgentCard(BaseModel): status: str @@ -1389,6 +1567,10 @@ class MetaProcessorsAgentReadinessChecksDiscoveryA2aAgentCard(BaseModel): message: Optional[str] = None + message_ref: Optional[MetaProcessorsAgentReadinessChecksDiscoveryA2aAgentCardMessageRef] = FieldInfo( + alias="messageRef", default=None + ) + class MetaProcessorsAgentReadinessChecksDiscoveryAgentSkillsEvidenceFinding(BaseModel): outcome: str @@ -1430,6 +1612,13 @@ class MetaProcessorsAgentReadinessChecksDiscoveryAgentSkillsEvidence(BaseModel): response: Optional[MetaProcessorsAgentReadinessChecksDiscoveryAgentSkillsEvidenceResponse] = None +class MetaProcessorsAgentReadinessChecksDiscoveryAgentSkillsMessageRef(BaseModel): + code: str + """Stable, translatable message code.""" + + params: Optional[object] = None + + class MetaProcessorsAgentReadinessChecksDiscoveryAgentSkills(BaseModel): status: str @@ -1441,6 +1630,10 @@ class MetaProcessorsAgentReadinessChecksDiscoveryAgentSkills(BaseModel): message: Optional[str] = None + message_ref: Optional[MetaProcessorsAgentReadinessChecksDiscoveryAgentSkillsMessageRef] = FieldInfo( + alias="messageRef", default=None + ) + class MetaProcessorsAgentReadinessChecksDiscoveryAPICatalogEvidenceFinding(BaseModel): outcome: str @@ -1482,6 +1675,13 @@ class MetaProcessorsAgentReadinessChecksDiscoveryAPICatalogEvidence(BaseModel): response: Optional[MetaProcessorsAgentReadinessChecksDiscoveryAPICatalogEvidenceResponse] = None +class MetaProcessorsAgentReadinessChecksDiscoveryAPICatalogMessageRef(BaseModel): + code: str + """Stable, translatable message code.""" + + params: Optional[object] = None + + class MetaProcessorsAgentReadinessChecksDiscoveryAPICatalog(BaseModel): status: str @@ -1493,6 +1693,10 @@ class MetaProcessorsAgentReadinessChecksDiscoveryAPICatalog(BaseModel): message: Optional[str] = None + message_ref: Optional[MetaProcessorsAgentReadinessChecksDiscoveryAPICatalogMessageRef] = FieldInfo( + alias="messageRef", default=None + ) + class MetaProcessorsAgentReadinessChecksDiscoveryArdEvidenceFinding(BaseModel): outcome: str @@ -1534,6 +1738,13 @@ class MetaProcessorsAgentReadinessChecksDiscoveryArdEvidence(BaseModel): response: Optional[MetaProcessorsAgentReadinessChecksDiscoveryArdEvidenceResponse] = None +class MetaProcessorsAgentReadinessChecksDiscoveryArdMessageRef(BaseModel): + code: str + """Stable, translatable message code.""" + + params: Optional[object] = None + + class MetaProcessorsAgentReadinessChecksDiscoveryArd(BaseModel): status: str @@ -1545,6 +1756,10 @@ class MetaProcessorsAgentReadinessChecksDiscoveryArd(BaseModel): message: Optional[str] = None + message_ref: Optional[MetaProcessorsAgentReadinessChecksDiscoveryArdMessageRef] = FieldInfo( + alias="messageRef", default=None + ) + class MetaProcessorsAgentReadinessChecksDiscoveryAuthMdEvidenceFinding(BaseModel): outcome: str @@ -1586,6 +1801,13 @@ class MetaProcessorsAgentReadinessChecksDiscoveryAuthMdEvidence(BaseModel): response: Optional[MetaProcessorsAgentReadinessChecksDiscoveryAuthMdEvidenceResponse] = None +class MetaProcessorsAgentReadinessChecksDiscoveryAuthMdMessageRef(BaseModel): + code: str + """Stable, translatable message code.""" + + params: Optional[object] = None + + class MetaProcessorsAgentReadinessChecksDiscoveryAuthMd(BaseModel): status: str @@ -1597,6 +1819,10 @@ class MetaProcessorsAgentReadinessChecksDiscoveryAuthMd(BaseModel): message: Optional[str] = None + message_ref: Optional[MetaProcessorsAgentReadinessChecksDiscoveryAuthMdMessageRef] = FieldInfo( + alias="messageRef", default=None + ) + class MetaProcessorsAgentReadinessChecksDiscoveryMcpServerCardEvidenceFinding(BaseModel): outcome: str @@ -1638,6 +1864,13 @@ class MetaProcessorsAgentReadinessChecksDiscoveryMcpServerCardEvidence(BaseModel response: Optional[MetaProcessorsAgentReadinessChecksDiscoveryMcpServerCardEvidenceResponse] = None +class MetaProcessorsAgentReadinessChecksDiscoveryMcpServerCardMessageRef(BaseModel): + code: str + """Stable, translatable message code.""" + + params: Optional[object] = None + + class MetaProcessorsAgentReadinessChecksDiscoveryMcpServerCard(BaseModel): status: str @@ -1649,6 +1882,10 @@ class MetaProcessorsAgentReadinessChecksDiscoveryMcpServerCard(BaseModel): message: Optional[str] = None + message_ref: Optional[MetaProcessorsAgentReadinessChecksDiscoveryMcpServerCardMessageRef] = FieldInfo( + alias="messageRef", default=None + ) + class MetaProcessorsAgentReadinessChecksDiscoveryOAuthDiscoveryEvidenceFinding(BaseModel): outcome: str @@ -1690,6 +1927,13 @@ class MetaProcessorsAgentReadinessChecksDiscoveryOAuthDiscoveryEvidence(BaseMode response: Optional[MetaProcessorsAgentReadinessChecksDiscoveryOAuthDiscoveryEvidenceResponse] = None +class MetaProcessorsAgentReadinessChecksDiscoveryOAuthDiscoveryMessageRef(BaseModel): + code: str + """Stable, translatable message code.""" + + params: Optional[object] = None + + class MetaProcessorsAgentReadinessChecksDiscoveryOAuthDiscovery(BaseModel): status: str @@ -1701,6 +1945,10 @@ class MetaProcessorsAgentReadinessChecksDiscoveryOAuthDiscovery(BaseModel): message: Optional[str] = None + message_ref: Optional[MetaProcessorsAgentReadinessChecksDiscoveryOAuthDiscoveryMessageRef] = FieldInfo( + alias="messageRef", default=None + ) + class MetaProcessorsAgentReadinessChecksDiscoveryOAuthProtectedResourceEvidenceFinding(BaseModel): outcome: str @@ -1742,6 +1990,13 @@ class MetaProcessorsAgentReadinessChecksDiscoveryOAuthProtectedResourceEvidence( response: Optional[MetaProcessorsAgentReadinessChecksDiscoveryOAuthProtectedResourceEvidenceResponse] = None +class MetaProcessorsAgentReadinessChecksDiscoveryOAuthProtectedResourceMessageRef(BaseModel): + code: str + """Stable, translatable message code.""" + + params: Optional[object] = None + + class MetaProcessorsAgentReadinessChecksDiscoveryOAuthProtectedResource(BaseModel): status: str @@ -1753,6 +2008,73 @@ class MetaProcessorsAgentReadinessChecksDiscoveryOAuthProtectedResource(BaseMode message: Optional[str] = None + message_ref: Optional[MetaProcessorsAgentReadinessChecksDiscoveryOAuthProtectedResourceMessageRef] = FieldInfo( + alias="messageRef", default=None + ) + + +class MetaProcessorsAgentReadinessChecksDiscoveryPersonalAgentProtocolEvidenceFinding(BaseModel): + outcome: str + + summary: str + + +class MetaProcessorsAgentReadinessChecksDiscoveryPersonalAgentProtocolEvidenceRequest(BaseModel): + method: str + + url: str + + headers: Optional[object] = None + + +class MetaProcessorsAgentReadinessChecksDiscoveryPersonalAgentProtocolEvidenceResponse(BaseModel): + status: int + + status_text: str = FieldInfo(alias="statusText") + + body_preview: Optional[str] = FieldInfo(alias="bodyPreview", default=None) + + body_size: Optional[int] = FieldInfo(alias="bodySize", default=None) + + headers: Optional[object] = None + + redirected_to: Optional[str] = FieldInfo(alias="redirectedTo", default=None) + + +class MetaProcessorsAgentReadinessChecksDiscoveryPersonalAgentProtocolEvidence(BaseModel): + action: str + + label: str + + finding: Optional[MetaProcessorsAgentReadinessChecksDiscoveryPersonalAgentProtocolEvidenceFinding] = None + + request: Optional[MetaProcessorsAgentReadinessChecksDiscoveryPersonalAgentProtocolEvidenceRequest] = None + + response: Optional[MetaProcessorsAgentReadinessChecksDiscoveryPersonalAgentProtocolEvidenceResponse] = None + + +class MetaProcessorsAgentReadinessChecksDiscoveryPersonalAgentProtocolMessageRef(BaseModel): + code: str + """Stable, translatable message code.""" + + params: Optional[object] = None + + +class MetaProcessorsAgentReadinessChecksDiscoveryPersonalAgentProtocol(BaseModel): + status: str + + details: Optional[object] = None + + duration_ms: Optional[float] = FieldInfo(alias="durationMs", default=None) + + evidence: Optional[List[MetaProcessorsAgentReadinessChecksDiscoveryPersonalAgentProtocolEvidence]] = None + + message: Optional[str] = None + + message_ref: Optional[MetaProcessorsAgentReadinessChecksDiscoveryPersonalAgentProtocolMessageRef] = FieldInfo( + alias="messageRef", default=None + ) + class MetaProcessorsAgentReadinessChecksDiscoveryWebMcpEvidenceFinding(BaseModel): outcome: str @@ -1794,6 +2116,13 @@ class MetaProcessorsAgentReadinessChecksDiscoveryWebMcpEvidence(BaseModel): response: Optional[MetaProcessorsAgentReadinessChecksDiscoveryWebMcpEvidenceResponse] = None +class MetaProcessorsAgentReadinessChecksDiscoveryWebMcpMessageRef(BaseModel): + code: str + """Stable, translatable message code.""" + + params: Optional[object] = None + + class MetaProcessorsAgentReadinessChecksDiscoveryWebMcp(BaseModel): status: str @@ -1805,6 +2134,10 @@ class MetaProcessorsAgentReadinessChecksDiscoveryWebMcp(BaseModel): message: Optional[str] = None + message_ref: Optional[MetaProcessorsAgentReadinessChecksDiscoveryWebMcpMessageRef] = FieldInfo( + alias="messageRef", default=None + ) + class MetaProcessorsAgentReadinessChecksDiscovery(BaseModel): a2a_agent_card: MetaProcessorsAgentReadinessChecksDiscoveryA2aAgentCard = FieldInfo(alias="a2aAgentCard") @@ -1825,6 +2158,10 @@ class MetaProcessorsAgentReadinessChecksDiscovery(BaseModel): alias="oauthProtectedResource" ) + personal_agent_protocol: MetaProcessorsAgentReadinessChecksDiscoveryPersonalAgentProtocol = FieldInfo( + alias="personalAgentProtocol" + ) + web_mcp: MetaProcessorsAgentReadinessChecksDiscoveryWebMcp = FieldInfo(alias="webMcp") diff --git a/src/cloudflare/types/user/__init__.py b/src/cloudflare/types/user/__init__.py index 315f9a5d47b..8b1c0f046ec 100644 --- a/src/cloudflare/types/user/__init__.py +++ b/src/cloudflare/types/user/__init__.py @@ -11,6 +11,7 @@ from .user_edit_response import UserEditResponse as UserEditResponse from .token_create_params import TokenCreateParams as TokenCreateParams from .token_update_params import TokenUpdateParams as TokenUpdateParams +from .tenant_list_response import TenantListResponse as TenantListResponse from .audit_log_list_params import AuditLogListParams as AuditLogListParams from .token_create_response import TokenCreateResponse as TokenCreateResponse from .token_delete_response import TokenDeleteResponse as TokenDeleteResponse diff --git a/src/cloudflare/types/user/tenant_list_response.py b/src/cloudflare/types/user/tenant_list_response.py new file mode 100644 index 00000000000..eb853ea2c3a --- /dev/null +++ b/src/cloudflare/types/user/tenant_list_response.py @@ -0,0 +1,156 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Dict, List, Union, Optional +from datetime import datetime + +from ..._models import BaseModel + +__all__ = [ + "TenantListResponse", + "TenantContacts", + "TenantMetadata", + "TenantMetadataDNS", + "TenantMetadataDNSNSPool", + "TenantMetadataInnateAccountEntitlement", + "TenantMetadataInnateAccountEntitlementAllocation", + "TenantMetadataInnateAccountEntitlementFeature", + "TenantMetadataTenantEntitlement", + "TenantMetadataTenantEntitlementAllocation", + "TenantMetadataTenantEntitlementFeature", + "TenantNetwork", + "TenantUnit", + "TenantUnitUnitMembership", + "UIFlags", +] + + +class TenantContacts(BaseModel): + email: Optional[str] = None + + website: Optional[str] = None + + +class TenantMetadataDNSNSPool(BaseModel): + primary: Optional[str] = None + + secondary: Optional[str] = None + + +class TenantMetadataDNS(BaseModel): + ns_pool: TenantMetadataDNSNSPool + + +class TenantMetadataInnateAccountEntitlementAllocation(BaseModel): + type: str + + value: Union[bool, float, str, Optional[Dict[str, object]], List[object]] + + +class TenantMetadataInnateAccountEntitlementFeature(BaseModel): + key: str + + +class TenantMetadataInnateAccountEntitlement(BaseModel): + allocation: TenantMetadataInnateAccountEntitlementAllocation + + feature: TenantMetadataInnateAccountEntitlementFeature + + +class TenantMetadataTenantEntitlementAllocation(BaseModel): + type: str + + value: Union[bool, float, str, Optional[Dict[str, object]], List[object]] + + +class TenantMetadataTenantEntitlementFeature(BaseModel): + key: str + + +class TenantMetadataTenantEntitlement(BaseModel): + allocation: TenantMetadataTenantEntitlementAllocation + + feature: TenantMetadataTenantEntitlementFeature + + +class TenantMetadata(BaseModel): + billing_account_type: Optional[str] = None + + configuration_account: Optional[str] = None + + created_by: Optional[str] = None + + dns: Optional[TenantMetadataDNS] = None + + flags: Optional[Dict[str, str]] = None + + innate_account_entitlements: Optional[List[TenantMetadataInnateAccountEntitlement]] = None + + tenant_entitlements: Optional[List[TenantMetadataTenantEntitlement]] = None + + +class TenantNetwork(BaseModel): + choices: Optional[Dict[str, object]] = None + + +class TenantUnitUnitMembership(BaseModel): + member_metadata: object + + member_status: str + + member_tag: str + + +class TenantUnit(BaseModel): + unit_memberships: Optional[List[TenantUnitUnitMembership]] = None + + unit_metadata: object + + unit_name: str + + unit_status: str + + unit_tag: str + + +class UIFlags(BaseModel): + """ + Which top-level dashboard experiences to render for this tenant; both may be true. + """ + + show_orgs_ui: bool + """Render the Organizations experience for this tenant.""" + + show_tenants_ui: bool + """Render the legacy Tenants experience for this tenant.""" + + +class TenantListResponse(BaseModel): + cdate: datetime + + customer_id: Optional[str] = None + + edate: datetime + + tenant_contacts: TenantContacts + + tenant_labels: Optional[List[str]] = None + + tenant_metadata: TenantMetadata + + tenant_name: str + + tenant_network: TenantNetwork + + tenant_status: str + + tenant_tag: str + + tenant_type: str + + tenant_units: Optional[List[TenantUnit]] = None + + ui_flags: UIFlags + """ + Which top-level dashboard experiences to render for this tenant; both may be + true. + """ diff --git a/src/cloudflare/types/user/token_create_response.py b/src/cloudflare/types/user/token_create_response.py index 36357223476..3ca3f8d9d40 100644 --- a/src/cloudflare/types/user/token_create_response.py +++ b/src/cloudflare/types/user/token_create_response.py @@ -81,5 +81,19 @@ class TokenCreateResponse(BaseModel): status: Optional[Literal["active", "disabled", "expired"]] = None """Status of the token.""" + token_prefix: Optional[str] = None + """The prefix of the token value, before the first underscore. + + Use it with `token_suffix` to identify a token. Only present for tokens created + or rolled after this field was added. + """ + + token_suffix: Optional[str] = None + """The last 4 characters of the token value. + + Use it with `token_prefix` to identify a token. It is not unique. Only present + for tokens created or rolled after this field was added. + """ + value: Optional[TokenValue] = None """The token value.""" diff --git a/src/cloudflare/types/vectorize/__init__.py b/src/cloudflare/types/vectorize/__init__.py index ac02a5249ba..a4a36b6a852 100644 --- a/src/cloudflare/types/vectorize/__init__.py +++ b/src/cloudflare/types/vectorize/__init__.py @@ -13,6 +13,7 @@ from .index_insert_response import IndexInsertResponse as IndexInsertResponse from .index_upsert_response import IndexUpsertResponse as IndexUpsertResponse from .index_get_by_ids_params import IndexGetByIDsParams as IndexGetByIDsParams +from .index_get_by_ids_response import IndexGetByIDsResponse as IndexGetByIDsResponse from .index_list_vectors_params import IndexListVectorsParams as IndexListVectorsParams from .index_delete_by_ids_params import IndexDeleteByIDsParams as IndexDeleteByIDsParams from .index_list_vectors_response import IndexListVectorsResponse as IndexListVectorsResponse diff --git a/src/cloudflare/types/vectorize/index_get_by_ids_response.py b/src/cloudflare/types/vectorize/index_get_by_ids_response.py new file mode 100644 index 00000000000..fb4c8887aa2 --- /dev/null +++ b/src/cloudflare/types/vectorize/index_get_by_ids_response.py @@ -0,0 +1,18 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional + +from ..._models import BaseModel + +__all__ = ["IndexGetByIDsResponse"] + + +class IndexGetByIDsResponse(BaseModel): + id: Optional[str] = None + """Identifier for a Vector""" + + metadata: Optional[object] = None + + namespace: Optional[str] = None + + values: Optional[List[float]] = None diff --git a/src/cloudflare/types/workers/beta/workers/__init__.py b/src/cloudflare/types/workers/beta/workers/__init__.py index b8520d99e05..e1e8c7854cb 100644 --- a/src/cloudflare/types/workers/beta/workers/__init__.py +++ b/src/cloudflare/types/workers/beta/workers/__init__.py @@ -6,4 +6,5 @@ from .version_get_params import VersionGetParams as VersionGetParams from .version_list_params import VersionListParams as VersionListParams from .version_create_params import VersionCreateParams as VersionCreateParams +from .version_profile_params import VersionProfileParams as VersionProfileParams from .version_delete_response import VersionDeleteResponse as VersionDeleteResponse diff --git a/src/cloudflare/types/workers/beta/workers/version.py b/src/cloudflare/types/workers/beta/workers/version.py index 986a7594673..da1551ca76b 100644 --- a/src/cloudflare/types/workers/beta/workers/version.py +++ b/src/cloudflare/types/workers/beta/workers/version.py @@ -380,10 +380,14 @@ class BindingWorkersBindingKindInherit(BaseModel): """ version_id: Optional[str] = None - """ - Identifier for the version to inherit the binding from, which can be the version - ID or the literal "latest" to inherit from the latest version. Defaults to - inheriting the binding from the latest version. + """Identifier for the version to inherit the binding from. + + This can be a version ID, or the literal "latest" to inherit from the most + recently uploaded version, which may not be the deployed version. Defaults to + "latest". Only the Workers API version endpoints under + `/accounts/{account_id}/workers/workers/{worker_id}/versions` accept a version + ID. Other endpoints, including script upload and script version upload, accept + only "latest" and reject a version ID with error 10057. """ @@ -715,13 +719,16 @@ class BindingWorkersBindingKindVPCNetwork(BaseModel): identity: Optional[Literal["runtime-email-alpha"]] = None """Enables Gateway identity for the binding. - Requires network_id to be "cf1:network" and cannot be combined with tunnel_id. + Requires network_id to be "cf1:network" and cannot be combined with tunnel_id or + an explicit "cf1:vnet:" network_id. """ network_id: Optional[str] = None """Identifier of the network to bind to. - Only "cf1:network" is currently supported. Mutually exclusive with tunnel_id. + Use "cf1:network" to select the account's default virtual network at runtime, or + "cf1:vnet:" to select an explicit virtual network in the Worker's account. + Mutually exclusive with tunnel_id. """ tunnel_id: Optional[str] = None diff --git a/src/cloudflare/types/workers/beta/workers/version_create_params.py b/src/cloudflare/types/workers/beta/workers/version_create_params.py index cf36e784224..e9caa665c6b 100644 --- a/src/cloudflare/types/workers/beta/workers/version_create_params.py +++ b/src/cloudflare/types/workers/beta/workers/version_create_params.py @@ -482,10 +482,14 @@ class BindingWorkersBindingKindInherit(TypedDict, total=False): """ version_id: str - """ - Identifier for the version to inherit the binding from, which can be the version - ID or the literal "latest" to inherit from the latest version. Defaults to - inheriting the binding from the latest version. + """Identifier for the version to inherit the binding from. + + This can be a version ID, or the literal "latest" to inherit from the most + recently uploaded version, which may not be the deployed version. Defaults to + "latest". Only the Workers API version endpoints under + `/accounts/{account_id}/workers/workers/{worker_id}/versions` accept a version + ID. Other endpoints, including script upload and script version upload, accept + only "latest" and reject a version ID with error 10057. """ @@ -832,13 +836,16 @@ class BindingWorkersBindingKindVPCNetwork(TypedDict, total=False): identity: Literal["runtime-email-alpha"] """Enables Gateway identity for the binding. - Requires network_id to be "cf1:network" and cannot be combined with tunnel_id. + Requires network_id to be "cf1:network" and cannot be combined with tunnel_id or + an explicit "cf1:vnet:" network_id. """ network_id: str """Identifier of the network to bind to. - Only "cf1:network" is currently supported. Mutually exclusive with tunnel_id. + Use "cf1:network" to select the account's default virtual network at runtime, or + "cf1:vnet:" to select an explicit virtual network in the Worker's account. + Mutually exclusive with tunnel_id. """ tunnel_id: str diff --git a/src/cloudflare/types/workers/beta/workers/version_profile_params.py b/src/cloudflare/types/workers/beta/workers/version_profile_params.py new file mode 100644 index 00000000000..f70d255dfd8 --- /dev/null +++ b/src/cloudflare/types/workers/beta/workers/version_profile_params.py @@ -0,0 +1,33 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal, Required, TypedDict + +__all__ = ["VersionProfileParams"] + + +class VersionProfileParams(TypedDict, total=False): + account_id: Required[str] + """Identifier.""" + + worker_id: Required[str] + """Identifies the Worker by ID or name.""" + + duration_ms: Required[int] + """Profile duration in milliseconds.""" + + actor_id: str + """Identifies the exact Durable Object actor to profile. + + Must be specified together with namespace_id. The actor must currently be active + and running the requested version. + """ + + namespace_id: str + """Identifies the Durable Object namespace containing the actor to profile. + + Must be specified together with actor_id. + """ + + profile_type: Literal["cpu", "heap"] diff --git a/src/cloudflare/types/workers/domain_get_response.py b/src/cloudflare/types/workers/domain_get_response.py index e5624ed9e05..e308e1e3790 100644 --- a/src/cloudflare/types/workers/domain_get_response.py +++ b/src/cloudflare/types/workers/domain_get_response.py @@ -12,6 +12,14 @@ class DomainGetResponse(BaseModel): cert_id: str """ID of the TLS certificate issued for the domain.""" + enabled: bool + """Whether the configured hostname is routable for the domain. + + If disabled, then requests to the configured hostname will not be routed to the + configured Worker. If disabled, then preview routing must be enabled, and only + subdomains of the configured hostname will be routable. + """ + environment: str """Worker environment associated with the domain.""" @@ -22,6 +30,16 @@ class DomainGetResponse(BaseModel): hostname will be routed to the configured Worker. """ + previews_enabled: bool + """Whether previews are routable for the domain. + + If enabled, previews will be routable as subdomains of the configured hostname. + For example, if the configured hostname is `app.example.com`, then requests to + `my-feature.app.example.com` will be routed to the preview with slug + `my-feature`, if such a preview exists. If preview routing is disabled, then + hostname routing must be enabled. + """ + service: str """Name of the Worker associated with the domain. diff --git a/src/cloudflare/types/workers/domain_list_params.py b/src/cloudflare/types/workers/domain_list_params.py index f3b4793f17d..ef81c00db07 100644 --- a/src/cloudflare/types/workers/domain_list_params.py +++ b/src/cloudflare/types/workers/domain_list_params.py @@ -11,12 +11,18 @@ class DomainListParams(TypedDict, total=False): account_id: Required[str] """Identifier.""" + enabled: bool + """Whether the configured hostname is routable for the domain.""" + environment: str """Worker environment associated with the domain.""" hostname: str """Hostname of the domain.""" + previews_enabled: bool + """Whether previews are routable for the domain.""" + service: str """Name of the Worker associated with the domain.""" diff --git a/src/cloudflare/types/workers/domain_list_response.py b/src/cloudflare/types/workers/domain_list_response.py index 93237710d3f..bf862a71ca4 100644 --- a/src/cloudflare/types/workers/domain_list_response.py +++ b/src/cloudflare/types/workers/domain_list_response.py @@ -12,6 +12,14 @@ class DomainListResponse(BaseModel): cert_id: str """ID of the TLS certificate issued for the domain.""" + enabled: bool + """Whether the configured hostname is routable for the domain. + + If disabled, then requests to the configured hostname will not be routed to the + configured Worker. If disabled, then preview routing must be enabled, and only + subdomains of the configured hostname will be routable. + """ + environment: str """Worker environment associated with the domain.""" @@ -22,6 +30,16 @@ class DomainListResponse(BaseModel): hostname will be routed to the configured Worker. """ + previews_enabled: bool + """Whether previews are routable for the domain. + + If enabled, previews will be routable as subdomains of the configured hostname. + For example, if the configured hostname is `app.example.com`, then requests to + `my-feature.app.example.com` will be routed to the preview with slug + `my-feature`, if such a preview exists. If preview routing is disabled, then + hostname routing must be enabled. + """ + service: str """Name of the Worker associated with the domain. diff --git a/src/cloudflare/types/workers/domain_update_params.py b/src/cloudflare/types/workers/domain_update_params.py index 8e31a17047c..03717c3c835 100644 --- a/src/cloudflare/types/workers/domain_update_params.py +++ b/src/cloudflare/types/workers/domain_update_params.py @@ -24,6 +24,24 @@ class DomainUpdateParams(TypedDict, total=False): Requests to the configured hostname will be routed to this Worker. """ + enabled: bool + """Whether the configured hostname is routable for the domain. + + If disabled, then requests to the configured hostname will not be routed to the + configured Worker. If disabled, then preview routing must be enabled, and only + subdomains of the configured hostname will be routable. + """ + + previews_enabled: bool + """Whether previews are routable for the domain. + + If enabled, previews will be routable as subdomains of the configured hostname. + For example, if the configured hostname is `app.example.com`, then requests to + `my-feature.app.example.com` will be routed to the preview with slug + `my-feature`, if such a preview exists. If preview routing is disabled, then + hostname routing must be enabled. + """ + zone_id: str """ID of the zone containing the domain hostname.""" diff --git a/src/cloudflare/types/workers/domain_update_response.py b/src/cloudflare/types/workers/domain_update_response.py index 261bfb5d4e6..154b7a0f818 100644 --- a/src/cloudflare/types/workers/domain_update_response.py +++ b/src/cloudflare/types/workers/domain_update_response.py @@ -12,6 +12,14 @@ class DomainUpdateResponse(BaseModel): cert_id: str """ID of the TLS certificate issued for the domain.""" + enabled: bool + """Whether the configured hostname is routable for the domain. + + If disabled, then requests to the configured hostname will not be routed to the + configured Worker. If disabled, then preview routing must be enabled, and only + subdomains of the configured hostname will be routable. + """ + environment: str """Worker environment associated with the domain.""" @@ -22,6 +30,16 @@ class DomainUpdateResponse(BaseModel): hostname will be routed to the configured Worker. """ + previews_enabled: bool + """Whether previews are routable for the domain. + + If enabled, previews will be routable as subdomains of the configured hostname. + For example, if the configured hostname is `app.example.com`, then requests to + `my-feature.app.example.com` will be routed to the preview with slug + `my-feature`, if such a preview exists. If preview routing is disabled, then + hostname routing must be enabled. + """ + service: str """Name of the Worker associated with the domain. diff --git a/src/cloudflare/types/workers/observability/destination_create_response.py b/src/cloudflare/types/workers/observability/destination_create_response.py index 73adc29b027..13a37f3a460 100644 --- a/src/cloudflare/types/workers/observability/destination_create_response.py +++ b/src/cloudflare/types/workers/observability/destination_create_response.py @@ -1,24 +1,32 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import List +from typing import Dict, List, Optional from typing_extensions import Literal from pydantic import Field as FieldInfo from ...._models import BaseModel -__all__ = ["DestinationCreateResponse", "Configuration"] +__all__ = ["DestinationCreateResponse", "Configuration", "ConfigurationJobStatus"] + + +class ConfigurationJobStatus(BaseModel): + error_message: str + + last_complete: str + + last_error: str class Configuration(BaseModel): - destination_conf: str + headers: Dict[str, Optional[str]] + + job_status: ConfigurationJobStatus = FieldInfo(alias="jobStatus") logpush_dataset: Literal["opentelemetry-traces", "opentelemetry-logs", "opentelemetry-metrics"] = FieldInfo( alias="logpushDataset" ) - logpush_job: float = FieldInfo(alias="logpushJob") - type: Literal["logpush"] url: str diff --git a/src/cloudflare/types/workers/observability/destination_delete_response.py b/src/cloudflare/types/workers/observability/destination_delete_response.py index 69451bafbc3..b91e58f7832 100644 --- a/src/cloudflare/types/workers/observability/destination_delete_response.py +++ b/src/cloudflare/types/workers/observability/destination_delete_response.py @@ -1,24 +1,32 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import List +from typing import Dict, List, Optional from typing_extensions import Literal from pydantic import Field as FieldInfo from ...._models import BaseModel -__all__ = ["DestinationDeleteResponse", "Configuration"] +__all__ = ["DestinationDeleteResponse", "Configuration", "ConfigurationJobStatus"] + + +class ConfigurationJobStatus(BaseModel): + error_message: str + + last_complete: str + + last_error: str class Configuration(BaseModel): - destination_conf: str + headers: Dict[str, Optional[str]] + + job_status: ConfigurationJobStatus = FieldInfo(alias="jobStatus") logpush_dataset: Literal["opentelemetry-traces", "opentelemetry-logs", "opentelemetry-metrics"] = FieldInfo( alias="logpushDataset" ) - logpush_job: float = FieldInfo(alias="logpushJob") - type: Literal["logpush"] url: str diff --git a/src/cloudflare/types/workers/observability/destination_list_response.py b/src/cloudflare/types/workers/observability/destination_list_response.py index 24e590a4b5e..cb0cc537fd9 100644 --- a/src/cloudflare/types/workers/observability/destination_list_response.py +++ b/src/cloudflare/types/workers/observability/destination_list_response.py @@ -1,6 +1,6 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import Dict, List +from typing import Dict, List, Optional from typing_extensions import Literal from pydantic import Field as FieldInfo @@ -19,9 +19,7 @@ class ConfigurationJobStatus(BaseModel): class Configuration(BaseModel): - destination_conf: str - - headers: Dict[str, str] + headers: Dict[str, Optional[str]] job_status: ConfigurationJobStatus = FieldInfo(alias="jobStatus") diff --git a/src/cloudflare/types/workers/observability/destination_update_params.py b/src/cloudflare/types/workers/observability/destination_update_params.py index a6c2d729053..2c3529b132c 100644 --- a/src/cloudflare/types/workers/observability/destination_update_params.py +++ b/src/cloudflare/types/workers/observability/destination_update_params.py @@ -2,8 +2,10 @@ from __future__ import annotations -from typing import Dict -from typing_extensions import Literal, Required, TypedDict +from typing import Dict, Optional +from typing_extensions import Literal, Required, Annotated, TypedDict + +from ...._utils import PropertyInfo __all__ = ["DestinationUpdateParams", "Configuration"] @@ -11,14 +13,16 @@ class DestinationUpdateParams(TypedDict, total=False): account_id: Required[str] - configuration: Required[Configuration] - enabled: Required[bool] + configuration: Configuration + class Configuration(TypedDict, total=False): - headers: Required[Dict[str, str]] + headers: Required[Dict[str, Optional[str]]] type: Required[Literal["logpush"]] url: Required[str] + + replace_headers: Annotated[bool, PropertyInfo(alias="replaceHeaders")] diff --git a/src/cloudflare/types/workers/observability/destination_update_response.py b/src/cloudflare/types/workers/observability/destination_update_response.py index 925bf7abe56..93d382c7eae 100644 --- a/src/cloudflare/types/workers/observability/destination_update_response.py +++ b/src/cloudflare/types/workers/observability/destination_update_response.py @@ -1,24 +1,32 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import List +from typing import Dict, List, Optional from typing_extensions import Literal from pydantic import Field as FieldInfo from ...._models import BaseModel -__all__ = ["DestinationUpdateResponse", "Configuration"] +__all__ = ["DestinationUpdateResponse", "Configuration", "ConfigurationJobStatus"] + + +class ConfigurationJobStatus(BaseModel): + error_message: str + + last_complete: str + + last_error: str class Configuration(BaseModel): - destination_conf: str + headers: Dict[str, Optional[str]] + + job_status: ConfigurationJobStatus = FieldInfo(alias="jobStatus") logpush_dataset: Literal["opentelemetry-traces", "opentelemetry-logs", "opentelemetry-metrics"] = FieldInfo( alias="logpushDataset" ) - logpush_job: float = FieldInfo(alias="logpushJob") - type: Literal["logpush"] url: str diff --git a/src/cloudflare/types/workers/observability/shared_query_get_response.py b/src/cloudflare/types/workers/observability/shared_query_get_response.py index edcdf0f886d..4bc7c5e9876 100644 --- a/src/cloudflare/types/workers/observability/shared_query_get_response.py +++ b/src/cloudflare/types/workers/observability/shared_query_get_response.py @@ -735,12 +735,18 @@ class EventsEventMetadata(BaseModel): end_time: Optional[int] = FieldInfo(alias="endTime", default=None) """Span end time as a Unix epoch in milliseconds.""" + end_time_ns: Optional[str] = FieldInfo(alias="endTimeNs", default=None) + """Span end time as a Unix epoch in nanoseconds.""" + error: Optional[str] = None """Error message, present when the log represents an error.""" error_template: Optional[str] = FieldInfo(alias="errorTemplate", default=None) """Templatized version of the error message used for grouping similar errors.""" + event_size: Optional[int] = FieldInfo(alias="eventSize", default=None) + """Size of the stored telemetry event in bytes.""" + fingerprint: Optional[str] = None """Content-based fingerprint used to group similar events.""" @@ -786,15 +792,34 @@ class EventsEventMetadata(BaseModel): span_name: Optional[str] = FieldInfo(alias="spanName", default=None) """Human-readable name for this span.""" + span_status: Optional[Literal["unset", "ok", "error"]] = FieldInfo(alias="spanStatus", default=None) + """OpenTelemetry span status. + + Present only on spans. `unset` when the span did not set a status, including + spans recorded before status was captured. + """ + + span_status_message: Optional[str] = FieldInfo(alias="spanStatusMessage", default=None) + """OpenTelemetry span status message. + + Present only on spans when the status is `error` and a message was set. + """ + stack_id: Optional[str] = FieldInfo(alias="stackId", default=None) """Stack / deployment identifier.""" start_time: Optional[int] = FieldInfo(alias="startTime", default=None) """Span start time as a Unix epoch in milliseconds.""" + start_time_ns: Optional[str] = FieldInfo(alias="startTimeNs", default=None) + """Span start time as a Unix epoch in nanoseconds.""" + status_code: Optional[int] = FieldInfo(alias="statusCode", default=None) """HTTP response status code returned by the Worker.""" + timestamp_ns: Optional[str] = FieldInfo(alias="timestampNs", default=None) + """Event time as a Unix epoch in nanoseconds.""" + trace_duration: Optional[int] = FieldInfo(alias="traceDuration", default=None) """Total duration of the entire trace in milliseconds.""" @@ -1097,12 +1122,18 @@ class InvocationMetadata(BaseModel): end_time: Optional[int] = FieldInfo(alias="endTime", default=None) """Span end time as a Unix epoch in milliseconds.""" + end_time_ns: Optional[str] = FieldInfo(alias="endTimeNs", default=None) + """Span end time as a Unix epoch in nanoseconds.""" + error: Optional[str] = None """Error message, present when the log represents an error.""" error_template: Optional[str] = FieldInfo(alias="errorTemplate", default=None) """Templatized version of the error message used for grouping similar errors.""" + event_size: Optional[int] = FieldInfo(alias="eventSize", default=None) + """Size of the stored telemetry event in bytes.""" + fingerprint: Optional[str] = None """Content-based fingerprint used to group similar events.""" @@ -1148,15 +1179,34 @@ class InvocationMetadata(BaseModel): span_name: Optional[str] = FieldInfo(alias="spanName", default=None) """Human-readable name for this span.""" + span_status: Optional[Literal["unset", "ok", "error"]] = FieldInfo(alias="spanStatus", default=None) + """OpenTelemetry span status. + + Present only on spans. `unset` when the span did not set a status, including + spans recorded before status was captured. + """ + + span_status_message: Optional[str] = FieldInfo(alias="spanStatusMessage", default=None) + """OpenTelemetry span status message. + + Present only on spans when the status is `error` and a message was set. + """ + stack_id: Optional[str] = FieldInfo(alias="stackId", default=None) """Stack / deployment identifier.""" start_time: Optional[int] = FieldInfo(alias="startTime", default=None) """Span start time as a Unix epoch in milliseconds.""" + start_time_ns: Optional[str] = FieldInfo(alias="startTimeNs", default=None) + """Span start time as a Unix epoch in nanoseconds.""" + status_code: Optional[int] = FieldInfo(alias="statusCode", default=None) """HTTP response status code returned by the Worker.""" + timestamp_ns: Optional[str] = FieldInfo(alias="timestampNs", default=None) + """Event time as a Unix epoch in nanoseconds.""" + trace_duration: Optional[int] = FieldInfo(alias="traceDuration", default=None) """Total duration of the entire trace in milliseconds.""" diff --git a/src/cloudflare/types/workers/observability/telemetry_query_response.py b/src/cloudflare/types/workers/observability/telemetry_query_response.py index 9fb48bb160e..f3ed22388ab 100644 --- a/src/cloudflare/types/workers/observability/telemetry_query_response.py +++ b/src/cloudflare/types/workers/observability/telemetry_query_response.py @@ -735,12 +735,18 @@ class EventsEventMetadata(BaseModel): end_time: Optional[int] = FieldInfo(alias="endTime", default=None) """Span end time as a Unix epoch in milliseconds.""" + end_time_ns: Optional[str] = FieldInfo(alias="endTimeNs", default=None) + """Span end time as a Unix epoch in nanoseconds.""" + error: Optional[str] = None """Error message, present when the log represents an error.""" error_template: Optional[str] = FieldInfo(alias="errorTemplate", default=None) """Templatized version of the error message used for grouping similar errors.""" + event_size: Optional[int] = FieldInfo(alias="eventSize", default=None) + """Size of the stored telemetry event in bytes.""" + fingerprint: Optional[str] = None """Content-based fingerprint used to group similar events.""" @@ -786,15 +792,34 @@ class EventsEventMetadata(BaseModel): span_name: Optional[str] = FieldInfo(alias="spanName", default=None) """Human-readable name for this span.""" + span_status: Optional[Literal["unset", "ok", "error"]] = FieldInfo(alias="spanStatus", default=None) + """OpenTelemetry span status. + + Present only on spans. `unset` when the span did not set a status, including + spans recorded before status was captured. + """ + + span_status_message: Optional[str] = FieldInfo(alias="spanStatusMessage", default=None) + """OpenTelemetry span status message. + + Present only on spans when the status is `error` and a message was set. + """ + stack_id: Optional[str] = FieldInfo(alias="stackId", default=None) """Stack / deployment identifier.""" start_time: Optional[int] = FieldInfo(alias="startTime", default=None) """Span start time as a Unix epoch in milliseconds.""" + start_time_ns: Optional[str] = FieldInfo(alias="startTimeNs", default=None) + """Span start time as a Unix epoch in nanoseconds.""" + status_code: Optional[int] = FieldInfo(alias="statusCode", default=None) """HTTP response status code returned by the Worker.""" + timestamp_ns: Optional[str] = FieldInfo(alias="timestampNs", default=None) + """Event time as a Unix epoch in nanoseconds.""" + trace_duration: Optional[int] = FieldInfo(alias="traceDuration", default=None) """Total duration of the entire trace in milliseconds.""" @@ -1097,12 +1122,18 @@ class InvocationMetadata(BaseModel): end_time: Optional[int] = FieldInfo(alias="endTime", default=None) """Span end time as a Unix epoch in milliseconds.""" + end_time_ns: Optional[str] = FieldInfo(alias="endTimeNs", default=None) + """Span end time as a Unix epoch in nanoseconds.""" + error: Optional[str] = None """Error message, present when the log represents an error.""" error_template: Optional[str] = FieldInfo(alias="errorTemplate", default=None) """Templatized version of the error message used for grouping similar errors.""" + event_size: Optional[int] = FieldInfo(alias="eventSize", default=None) + """Size of the stored telemetry event in bytes.""" + fingerprint: Optional[str] = None """Content-based fingerprint used to group similar events.""" @@ -1148,15 +1179,34 @@ class InvocationMetadata(BaseModel): span_name: Optional[str] = FieldInfo(alias="spanName", default=None) """Human-readable name for this span.""" + span_status: Optional[Literal["unset", "ok", "error"]] = FieldInfo(alias="spanStatus", default=None) + """OpenTelemetry span status. + + Present only on spans. `unset` when the span did not set a status, including + spans recorded before status was captured. + """ + + span_status_message: Optional[str] = FieldInfo(alias="spanStatusMessage", default=None) + """OpenTelemetry span status message. + + Present only on spans when the status is `error` and a message was set. + """ + stack_id: Optional[str] = FieldInfo(alias="stackId", default=None) """Stack / deployment identifier.""" start_time: Optional[int] = FieldInfo(alias="startTime", default=None) """Span start time as a Unix epoch in milliseconds.""" + start_time_ns: Optional[str] = FieldInfo(alias="startTimeNs", default=None) + """Span start time as a Unix epoch in nanoseconds.""" + status_code: Optional[int] = FieldInfo(alias="statusCode", default=None) """HTTP response status code returned by the Worker.""" + timestamp_ns: Optional[str] = FieldInfo(alias="timestampNs", default=None) + """Event time as a Unix epoch in nanoseconds.""" + trace_duration: Optional[int] = FieldInfo(alias="traceDuration", default=None) """Total duration of the entire trace in milliseconds.""" diff --git a/src/cloudflare/types/workers/script_update_params.py b/src/cloudflare/types/workers/script_update_params.py index 86a2f562852..6dd0fda3d0c 100644 --- a/src/cloudflare/types/workers/script_update_params.py +++ b/src/cloudflare/types/workers/script_update_params.py @@ -61,6 +61,9 @@ "MetadataBindingWorkersBindingKindVPCService", "MetadataBindingWorkersBindingKindVPCNetwork", "MetadataCacheOptions", + "MetadataCodeUpdateStrategy", + "MetadataCodeUpdateStrategyMode", + "MetadataCodeUpdateStrategyUnionMember1", "MetadataExports", "MetadataExportsWorkersWorkerExport", "MetadataExportsWorkersWorkerExportCache", @@ -102,9 +105,10 @@ class ScriptUpdateParams(TypedDict, total=False): bindings_inherit: Literal["strict"] """ - When set to "strict", the upload will fail if any `inherit` type bindings cannot - be resolved against the previous version of the Worker. Without this, - unresolvable inherit bindings are silently dropped. + When set to "strict", the upload will fail with error 10057 if any `inherit` + type bindings cannot be resolved against the latest uploaded version of the + Worker, which may not be the deployed version. Without this, unresolvable + inherit bindings are silently dropped. """ files: SequenceNotStr[FileTypes] @@ -413,10 +417,14 @@ class MetadataBindingWorkersBindingKindInherit(TypedDict, total=False): """ version_id: str - """ - Identifier for the version to inherit the binding from, which can be the version - ID or the literal "latest" to inherit from the latest version. Defaults to - inheriting the binding from the latest version. + """Identifier for the version to inherit the binding from. + + This can be a version ID, or the literal "latest" to inherit from the most + recently uploaded version, which may not be the deployed version. Defaults to + "latest". Only the Workers API version endpoints under + `/accounts/{account_id}/workers/workers/{worker_id}/versions` accept a version + ID. Other endpoints, including script upload and script version upload, accept + only "latest" and reject a version ID with error 10057. """ @@ -763,13 +771,16 @@ class MetadataBindingWorkersBindingKindVPCNetwork(TypedDict, total=False): identity: Literal["runtime-email-alpha"] """Enables Gateway identity for the binding. - Requires network_id to be "cf1:network" and cannot be combined with tunnel_id. + Requires network_id to be "cf1:network" and cannot be combined with tunnel_id or + an explicit "cf1:vnet:" network_id. """ network_id: str """Identifier of the network to bind to. - Only "cf1:network" is currently supported. Mutually exclusive with tunnel_id. + Use "cf1:network" to select the account's default virtual network at runtime, or + "cf1:vnet:" to select an explicit virtual network in the Worker's account. + Mutually exclusive with tunnel_id. """ tunnel_id: str @@ -838,6 +849,27 @@ class MetadataCacheOptions(TypedDict, total=False): """ +class MetadataCodeUpdateStrategyMode(TypedDict, total=False): + mode: Required[Literal["immediate"]] + """Apply Durable Object code updates immediately.""" + + +class MetadataCodeUpdateStrategyUnionMember1(TypedDict, total=False): + mode: Required[Literal["deferred"]] + """Allow active Durable Objects to hibernate before updating their code.""" + + max_delay: Optional[float] + """Set the maximum number of seconds to wait before forcing the update. + + When omitted, the default maximum delay applies. + """ + + +MetadataCodeUpdateStrategy: TypeAlias = Union[ + MetadataCodeUpdateStrategyMode, MetadataCodeUpdateStrategyUnionMember1, Optional[object] +] + + class MetadataExportsWorkersWorkerExportCache(TypedDict, total=False): """Cache override for this entrypoint. @@ -1257,6 +1289,12 @@ class Metadata(TypedDict, total=False): a single entrypoint. """ + code_update_strategy: MetadataCodeUpdateStrategy + """Choose whether to apply Durable Object code updates immediately or defer them. + + When omitted, the default strategy applies. + """ + compatibility_date: str """Date indicating targeted support in the Workers runtime. diff --git a/src/cloudflare/types/workers/scripts/deployment.py b/src/cloudflare/types/workers/scripts/deployment.py index 497063a28c1..1cb70835943 100644 --- a/src/cloudflare/types/workers/scripts/deployment.py +++ b/src/cloudflare/types/workers/scripts/deployment.py @@ -1,14 +1,21 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import List, Optional +from typing import List, Union, Optional from datetime import datetime -from typing_extensions import Literal +from typing_extensions import Literal, TypeAlias from pydantic import Field as FieldInfo from ...._models import BaseModel -__all__ = ["Deployment", "Version", "Annotations"] +__all__ = [ + "Deployment", + "Version", + "Annotations", + "CodeUpdateStrategy", + "CodeUpdateStrategyMode", + "CodeUpdateStrategyUnionMember1", +] class Version(BaseModel): @@ -20,6 +27,8 @@ class Version(BaseModel): class Annotations(BaseModel): + """Metadata attached to the deployment.""" + workers_message: Optional[str] = FieldInfo(alias="workers/message", default=None) """Human-readable message about the deployment. Truncated to 1000 bytes if longer.""" @@ -27,6 +36,25 @@ class Annotations(BaseModel): """Operation that triggered the creation of the deployment.""" +class CodeUpdateStrategyMode(BaseModel): + mode: Literal["immediate"] + """Apply Durable Object code updates immediately.""" + + +class CodeUpdateStrategyUnionMember1(BaseModel): + mode: Literal["deferred"] + """Allow active Durable Objects to hibernate before updating their code.""" + + max_delay: Optional[float] = None + """Set the maximum number of seconds to wait before forcing the update. + + When omitted, the default maximum delay applies. + """ + + +CodeUpdateStrategy: TypeAlias = Union[CodeUpdateStrategyMode, CodeUpdateStrategyUnionMember1, Optional[object]] + + class Deployment(BaseModel): id: str @@ -35,6 +63,10 @@ class Deployment(BaseModel): source: str strategy: Literal["percentage"] + """Strategy for routing traffic across the listed versions. + + `percentage` splits traffic according to each version's `percentage`. + """ versions: List[Version] """Worker versions included in this deployment. @@ -47,5 +79,6 @@ class Deployment(BaseModel): """ annotations: Optional[Annotations] = None + """Metadata attached to the deployment.""" author_email: Optional[str] = None diff --git a/src/cloudflare/types/workers/scripts/deployment_create_params.py b/src/cloudflare/types/workers/scripts/deployment_create_params.py index 0dfb040c3d8..a7993701b8a 100644 --- a/src/cloudflare/types/workers/scripts/deployment_create_params.py +++ b/src/cloudflare/types/workers/scripts/deployment_create_params.py @@ -2,12 +2,19 @@ from __future__ import annotations -from typing import Iterable -from typing_extensions import Literal, Required, Annotated, TypedDict +from typing import Union, Iterable, Optional +from typing_extensions import Literal, Required, Annotated, TypeAlias, TypedDict from ...._utils import PropertyInfo -__all__ = ["DeploymentCreateParams", "Version", "Annotations"] +__all__ = [ + "DeploymentCreateParams", + "Version", + "Annotations", + "CodeUpdateStrategy", + "CodeUpdateStrategyMode", + "CodeUpdateStrategyUnionMember1", +] class DeploymentCreateParams(TypedDict, total=False): @@ -15,6 +22,10 @@ class DeploymentCreateParams(TypedDict, total=False): """Identifier.""" strategy: Required[Literal["percentage"]] + """Strategy for routing traffic across the listed versions. + + `percentage` splits traffic according to each version's `percentage`. + """ versions: Required[Iterable[Version]] """Worker versions included in this deployment. @@ -33,6 +44,13 @@ class DeploymentCreateParams(TypedDict, total=False): """ annotations: Annotations + """Metadata attached to the deployment.""" + + code_update_strategy: CodeUpdateStrategy + """Choose whether to apply Durable Object code updates immediately or defer them. + + When omitted, the default strategy applies. + """ class Version(TypedDict, total=False): @@ -44,5 +62,26 @@ class Version(TypedDict, total=False): class Annotations(TypedDict, total=False): + """Metadata attached to the deployment.""" + workers_message: Annotated[str, PropertyInfo(alias="workers/message")] """Human-readable message about the deployment. Truncated to 1000 bytes if longer.""" + + +class CodeUpdateStrategyMode(TypedDict, total=False): + mode: Required[Literal["immediate"]] + """Apply Durable Object code updates immediately.""" + + +class CodeUpdateStrategyUnionMember1(TypedDict, total=False): + mode: Required[Literal["deferred"]] + """Allow active Durable Objects to hibernate before updating their code.""" + + max_delay: Optional[float] + """Set the maximum number of seconds to wait before forcing the update. + + When omitted, the default maximum delay applies. + """ + + +CodeUpdateStrategy: TypeAlias = Union[CodeUpdateStrategyMode, CodeUpdateStrategyUnionMember1, Optional[object]] diff --git a/src/cloudflare/types/workers/scripts/script_and_version_setting_edit_params.py b/src/cloudflare/types/workers/scripts/script_and_version_setting_edit_params.py index b5e276073f7..a5e0f6ac788 100644 --- a/src/cloudflare/types/workers/scripts/script_and_version_setting_edit_params.py +++ b/src/cloudflare/types/workers/scripts/script_and_version_setting_edit_params.py @@ -336,10 +336,14 @@ class SettingsBindingWorkersBindingKindInherit(TypedDict, total=False): """ version_id: str - """ - Identifier for the version to inherit the binding from, which can be the version - ID or the literal "latest" to inherit from the latest version. Defaults to - inheriting the binding from the latest version. + """Identifier for the version to inherit the binding from. + + This can be a version ID, or the literal "latest" to inherit from the most + recently uploaded version, which may not be the deployed version. Defaults to + "latest". Only the Workers API version endpoints under + `/accounts/{account_id}/workers/workers/{worker_id}/versions` accept a version + ID. Other endpoints, including script upload and script version upload, accept + only "latest" and reject a version ID with error 10057. """ @@ -686,13 +690,16 @@ class SettingsBindingWorkersBindingKindVPCNetwork(TypedDict, total=False): identity: Literal["runtime-email-alpha"] """Enables Gateway identity for the binding. - Requires network_id to be "cf1:network" and cannot be combined with tunnel_id. + Requires network_id to be "cf1:network" and cannot be combined with tunnel_id or + an explicit "cf1:vnet:" network_id. """ network_id: str """Identifier of the network to bind to. - Only "cf1:network" is currently supported. Mutually exclusive with tunnel_id. + Use "cf1:network" to select the account's default virtual network at runtime, or + "cf1:vnet:" to select an explicit virtual network in the Worker's account. + Mutually exclusive with tunnel_id. """ tunnel_id: str diff --git a/src/cloudflare/types/workers/scripts/script_and_version_setting_edit_response.py b/src/cloudflare/types/workers/scripts/script_and_version_setting_edit_response.py index 0597486ba78..055a6c62eec 100644 --- a/src/cloudflare/types/workers/scripts/script_and_version_setting_edit_response.py +++ b/src/cloudflare/types/workers/scripts/script_and_version_setting_edit_response.py @@ -339,10 +339,14 @@ class BindingWorkersBindingKindInherit(BaseModel): """ version_id: Optional[str] = None - """ - Identifier for the version to inherit the binding from, which can be the version - ID or the literal "latest" to inherit from the latest version. Defaults to - inheriting the binding from the latest version. + """Identifier for the version to inherit the binding from. + + This can be a version ID, or the literal "latest" to inherit from the most + recently uploaded version, which may not be the deployed version. Defaults to + "latest". Only the Workers API version endpoints under + `/accounts/{account_id}/workers/workers/{worker_id}/versions` accept a version + ID. Other endpoints, including script upload and script version upload, accept + only "latest" and reject a version ID with error 10057. """ @@ -674,13 +678,16 @@ class BindingWorkersBindingKindVPCNetwork(BaseModel): identity: Optional[Literal["runtime-email-alpha"]] = None """Enables Gateway identity for the binding. - Requires network_id to be "cf1:network" and cannot be combined with tunnel_id. + Requires network_id to be "cf1:network" and cannot be combined with tunnel_id or + an explicit "cf1:vnet:" network_id. """ network_id: Optional[str] = None """Identifier of the network to bind to. - Only "cf1:network" is currently supported. Mutually exclusive with tunnel_id. + Use "cf1:network" to select the account's default virtual network at runtime, or + "cf1:vnet:" to select an explicit virtual network in the Worker's account. + Mutually exclusive with tunnel_id. """ tunnel_id: Optional[str] = None diff --git a/src/cloudflare/types/workers/scripts/script_and_version_setting_get_response.py b/src/cloudflare/types/workers/scripts/script_and_version_setting_get_response.py index 54045bff5f9..5ecccbb4365 100644 --- a/src/cloudflare/types/workers/scripts/script_and_version_setting_get_response.py +++ b/src/cloudflare/types/workers/scripts/script_and_version_setting_get_response.py @@ -339,10 +339,14 @@ class BindingWorkersBindingKindInherit(BaseModel): """ version_id: Optional[str] = None - """ - Identifier for the version to inherit the binding from, which can be the version - ID or the literal "latest" to inherit from the latest version. Defaults to - inheriting the binding from the latest version. + """Identifier for the version to inherit the binding from. + + This can be a version ID, or the literal "latest" to inherit from the most + recently uploaded version, which may not be the deployed version. Defaults to + "latest". Only the Workers API version endpoints under + `/accounts/{account_id}/workers/workers/{worker_id}/versions` accept a version + ID. Other endpoints, including script upload and script version upload, accept + only "latest" and reject a version ID with error 10057. """ @@ -674,13 +678,16 @@ class BindingWorkersBindingKindVPCNetwork(BaseModel): identity: Optional[Literal["runtime-email-alpha"]] = None """Enables Gateway identity for the binding. - Requires network_id to be "cf1:network" and cannot be combined with tunnel_id. + Requires network_id to be "cf1:network" and cannot be combined with tunnel_id or + an explicit "cf1:vnet:" network_id. """ network_id: Optional[str] = None """Identifier of the network to bind to. - Only "cf1:network" is currently supported. Mutually exclusive with tunnel_id. + Use "cf1:network" to select the account's default virtual network at runtime, or + "cf1:vnet:" to select an explicit virtual network in the Worker's account. + Mutually exclusive with tunnel_id. """ tunnel_id: Optional[str] = None diff --git a/src/cloudflare/types/workers/scripts/version_create_params.py b/src/cloudflare/types/workers/scripts/version_create_params.py index dfbf7d3c5c4..71f69e7373b 100644 --- a/src/cloudflare/types/workers/scripts/version_create_params.py +++ b/src/cloudflare/types/workers/scripts/version_create_params.py @@ -77,9 +77,10 @@ class VersionCreateParams(TypedDict, total=False): bindings_inherit: Literal["strict"] """ - When set to "strict", the upload will fail if any `inherit` type bindings cannot - be resolved against the previous version of the Worker. Without this, - unresolvable inherit bindings are silently dropped. + When set to "strict", the upload will fail with error 10057 if any `inherit` + type bindings cannot be resolved against the latest uploaded version of the + Worker, which may not be the deployed version. Without this, unresolvable + inherit bindings are silently dropped. """ files: SequenceNotStr[FileTypes] @@ -361,10 +362,14 @@ class MetadataBindingWorkersBindingKindInherit(TypedDict, total=False): """ version_id: str - """ - Identifier for the version to inherit the binding from, which can be the version - ID or the literal "latest" to inherit from the latest version. Defaults to - inheriting the binding from the latest version. + """Identifier for the version to inherit the binding from. + + This can be a version ID, or the literal "latest" to inherit from the most + recently uploaded version, which may not be the deployed version. Defaults to + "latest". Only the Workers API version endpoints under + `/accounts/{account_id}/workers/workers/{worker_id}/versions` accept a version + ID. Other endpoints, including script upload and script version upload, accept + only "latest" and reject a version ID with error 10057. """ @@ -711,13 +716,16 @@ class MetadataBindingWorkersBindingKindVPCNetwork(TypedDict, total=False): identity: Literal["runtime-email-alpha"] """Enables Gateway identity for the binding. - Requires network_id to be "cf1:network" and cannot be combined with tunnel_id. + Requires network_id to be "cf1:network" and cannot be combined with tunnel_id or + an explicit "cf1:vnet:" network_id. """ network_id: str """Identifier of the network to bind to. - Only "cf1:network" is currently supported. Mutually exclusive with tunnel_id. + Use "cf1:network" to select the account's default virtual network at runtime, or + "cf1:vnet:" to select an explicit virtual network in the Worker's account. + Mutually exclusive with tunnel_id. """ tunnel_id: str diff --git a/src/cloudflare/types/workers_for_platforms/dispatch/namespaces/script_update_params.py b/src/cloudflare/types/workers_for_platforms/dispatch/namespaces/script_update_params.py index ea24cea1d1a..e2aa9f3d69d 100644 --- a/src/cloudflare/types/workers_for_platforms/dispatch/namespaces/script_update_params.py +++ b/src/cloudflare/types/workers_for_platforms/dispatch/namespaces/script_update_params.py @@ -60,6 +60,9 @@ "MetadataBindingWorkersBindingKindVPCService", "MetadataBindingWorkersBindingKindVPCNetwork", "MetadataCacheOptions", + "MetadataCodeUpdateStrategy", + "MetadataCodeUpdateStrategyMode", + "MetadataCodeUpdateStrategyUnionMember1", "MetadataExports", "MetadataExportsWorkersWorkerExport", "MetadataExportsWorkersWorkerExportCache", @@ -104,9 +107,10 @@ class ScriptUpdateParams(TypedDict, total=False): bindings_inherit: Literal["strict"] """ - When set to "strict", the upload will fail if any `inherit` type bindings cannot - be resolved against the previous version of the script. Without this, - unresolvable inherit bindings are silently dropped. + When set to "strict", the upload will fail with error 10057 if any `inherit` + type bindings cannot be resolved against the latest uploaded version of the + script, which may not be the deployed version. Without this, unresolvable + inherit bindings are silently dropped. """ files: SequenceNotStr[FileTypes] @@ -405,10 +409,14 @@ class MetadataBindingWorkersBindingKindInherit(TypedDict, total=False): """ version_id: str - """ - Identifier for the version to inherit the binding from, which can be the version - ID or the literal "latest" to inherit from the latest version. Defaults to - inheriting the binding from the latest version. + """Identifier for the version to inherit the binding from. + + This can be a version ID, or the literal "latest" to inherit from the most + recently uploaded version, which may not be the deployed version. Defaults to + "latest". Only the Workers API version endpoints under + `/accounts/{account_id}/workers/workers/{worker_id}/versions` accept a version + ID. Other endpoints, including script upload and script version upload, accept + only "latest" and reject a version ID with error 10057. """ @@ -755,13 +763,16 @@ class MetadataBindingWorkersBindingKindVPCNetwork(TypedDict, total=False): identity: Literal["runtime-email-alpha"] """Enables Gateway identity for the binding. - Requires network_id to be "cf1:network" and cannot be combined with tunnel_id. + Requires network_id to be "cf1:network" and cannot be combined with tunnel_id or + an explicit "cf1:vnet:" network_id. """ network_id: str """Identifier of the network to bind to. - Only "cf1:network" is currently supported. Mutually exclusive with tunnel_id. + Use "cf1:network" to select the account's default virtual network at runtime, or + "cf1:vnet:" to select an explicit virtual network in the Worker's account. + Mutually exclusive with tunnel_id. """ tunnel_id: str @@ -830,6 +841,27 @@ class MetadataCacheOptions(TypedDict, total=False): """ +class MetadataCodeUpdateStrategyMode(TypedDict, total=False): + mode: Required[Literal["immediate"]] + """Apply Durable Object code updates immediately.""" + + +class MetadataCodeUpdateStrategyUnionMember1(TypedDict, total=False): + mode: Required[Literal["deferred"]] + """Allow active Durable Objects to hibernate before updating their code.""" + + max_delay: Optional[float] + """Set the maximum number of seconds to wait before forcing the update. + + When omitted, the default maximum delay applies. + """ + + +MetadataCodeUpdateStrategy: TypeAlias = Union[ + MetadataCodeUpdateStrategyMode, MetadataCodeUpdateStrategyUnionMember1, Optional[object] +] + + class MetadataExportsWorkersWorkerExportCache(TypedDict, total=False): """Cache override for this entrypoint. @@ -1246,6 +1278,12 @@ class Metadata(TypedDict, total=False): a single entrypoint. """ + code_update_strategy: MetadataCodeUpdateStrategy + """Choose whether to apply Durable Object code updates immediately or defer them. + + When omitted, the default strategy applies. + """ + compatibility_date: str """Date indicating targeted support in the Workers runtime. diff --git a/src/cloudflare/types/workers_for_platforms/dispatch/namespaces/scripts/__init__.py b/src/cloudflare/types/workers_for_platforms/dispatch/namespaces/scripts/__init__.py index ce05402dedf..711e571143b 100644 --- a/src/cloudflare/types/workers_for_platforms/dispatch/namespaces/scripts/__init__.py +++ b/src/cloudflare/types/workers_for_platforms/dispatch/namespaces/scripts/__init__.py @@ -7,6 +7,7 @@ from .tag_update_params import TagUpdateParams as TagUpdateParams from .secret_get_response import SecretGetResponse as SecretGetResponse from .setting_edit_params import SettingEditParams as SettingEditParams +from .tag_delete_response import TagDeleteResponse as TagDeleteResponse from .tag_update_response import TagUpdateResponse as TagUpdateResponse from .binding_get_response import BindingGetResponse as BindingGetResponse from .secret_delete_params import SecretDeleteParams as SecretDeleteParams diff --git a/src/cloudflare/types/workers_for_platforms/dispatch/namespaces/scripts/binding_get_response.py b/src/cloudflare/types/workers_for_platforms/dispatch/namespaces/scripts/binding_get_response.py index 2558131219b..685679030a3 100644 --- a/src/cloudflare/types/workers_for_platforms/dispatch/namespaces/scripts/binding_get_response.py +++ b/src/cloudflare/types/workers_for_platforms/dispatch/namespaces/scripts/binding_get_response.py @@ -281,10 +281,14 @@ class WorkersBindingKindInherit(BaseModel): """ version_id: Optional[str] = None - """ - Identifier for the version to inherit the binding from, which can be the version - ID or the literal "latest" to inherit from the latest version. Defaults to - inheriting the binding from the latest version. + """Identifier for the version to inherit the binding from. + + This can be a version ID, or the literal "latest" to inherit from the most + recently uploaded version, which may not be the deployed version. Defaults to + "latest". Only the Workers API version endpoints under + `/accounts/{account_id}/workers/workers/{worker_id}/versions` accept a version + ID. Other endpoints, including script upload and script version upload, accept + only "latest" and reject a version ID with error 10057. """ @@ -616,13 +620,16 @@ class WorkersBindingKindVPCNetwork(BaseModel): identity: Optional[Literal["runtime-email-alpha"]] = None """Enables Gateway identity for the binding. - Requires network_id to be "cf1:network" and cannot be combined with tunnel_id. + Requires network_id to be "cf1:network" and cannot be combined with tunnel_id or + an explicit "cf1:vnet:" network_id. """ network_id: Optional[str] = None """Identifier of the network to bind to. - Only "cf1:network" is currently supported. Mutually exclusive with tunnel_id. + Use "cf1:network" to select the account's default virtual network at runtime, or + "cf1:vnet:" to select an explicit virtual network in the Worker's account. + Mutually exclusive with tunnel_id. """ tunnel_id: Optional[str] = None diff --git a/src/cloudflare/types/workers_for_platforms/dispatch/namespaces/scripts/setting_edit_params.py b/src/cloudflare/types/workers_for_platforms/dispatch/namespaces/scripts/setting_edit_params.py index 25faa4d372d..3d2b6ab1b0b 100644 --- a/src/cloudflare/types/workers_for_platforms/dispatch/namespaces/scripts/setting_edit_params.py +++ b/src/cloudflare/types/workers_for_platforms/dispatch/namespaces/scripts/setting_edit_params.py @@ -329,10 +329,14 @@ class SettingsBindingWorkersBindingKindInherit(TypedDict, total=False): """ version_id: str - """ - Identifier for the version to inherit the binding from, which can be the version - ID or the literal "latest" to inherit from the latest version. Defaults to - inheriting the binding from the latest version. + """Identifier for the version to inherit the binding from. + + This can be a version ID, or the literal "latest" to inherit from the most + recently uploaded version, which may not be the deployed version. Defaults to + "latest". Only the Workers API version endpoints under + `/accounts/{account_id}/workers/workers/{worker_id}/versions` accept a version + ID. Other endpoints, including script upload and script version upload, accept + only "latest" and reject a version ID with error 10057. """ @@ -679,13 +683,16 @@ class SettingsBindingWorkersBindingKindVPCNetwork(TypedDict, total=False): identity: Literal["runtime-email-alpha"] """Enables Gateway identity for the binding. - Requires network_id to be "cf1:network" and cannot be combined with tunnel_id. + Requires network_id to be "cf1:network" and cannot be combined with tunnel_id or + an explicit "cf1:vnet:" network_id. """ network_id: str """Identifier of the network to bind to. - Only "cf1:network" is currently supported. Mutually exclusive with tunnel_id. + Use "cf1:network" to select the account's default virtual network at runtime, or + "cf1:vnet:" to select an explicit virtual network in the Worker's account. + Mutually exclusive with tunnel_id. """ tunnel_id: str diff --git a/src/cloudflare/types/workers_for_platforms/dispatch/namespaces/scripts/setting_edit_response.py b/src/cloudflare/types/workers_for_platforms/dispatch/namespaces/scripts/setting_edit_response.py index a3fe9e887b9..c94c9bed2a6 100644 --- a/src/cloudflare/types/workers_for_platforms/dispatch/namespaces/scripts/setting_edit_response.py +++ b/src/cloudflare/types/workers_for_platforms/dispatch/namespaces/scripts/setting_edit_response.py @@ -319,10 +319,14 @@ class BindingWorkersBindingKindInherit(BaseModel): """ version_id: Optional[str] = None - """ - Identifier for the version to inherit the binding from, which can be the version - ID or the literal "latest" to inherit from the latest version. Defaults to - inheriting the binding from the latest version. + """Identifier for the version to inherit the binding from. + + This can be a version ID, or the literal "latest" to inherit from the most + recently uploaded version, which may not be the deployed version. Defaults to + "latest". Only the Workers API version endpoints under + `/accounts/{account_id}/workers/workers/{worker_id}/versions` accept a version + ID. Other endpoints, including script upload and script version upload, accept + only "latest" and reject a version ID with error 10057. """ @@ -654,13 +658,16 @@ class BindingWorkersBindingKindVPCNetwork(BaseModel): identity: Optional[Literal["runtime-email-alpha"]] = None """Enables Gateway identity for the binding. - Requires network_id to be "cf1:network" and cannot be combined with tunnel_id. + Requires network_id to be "cf1:network" and cannot be combined with tunnel_id or + an explicit "cf1:vnet:" network_id. """ network_id: Optional[str] = None """Identifier of the network to bind to. - Only "cf1:network" is currently supported. Mutually exclusive with tunnel_id. + Use "cf1:network" to select the account's default virtual network at runtime, or + "cf1:vnet:" to select an explicit virtual network in the Worker's account. + Mutually exclusive with tunnel_id. """ tunnel_id: Optional[str] = None diff --git a/src/cloudflare/types/workers_for_platforms/dispatch/namespaces/scripts/setting_get_response.py b/src/cloudflare/types/workers_for_platforms/dispatch/namespaces/scripts/setting_get_response.py index 247980a2e7c..d0f17fb094d 100644 --- a/src/cloudflare/types/workers_for_platforms/dispatch/namespaces/scripts/setting_get_response.py +++ b/src/cloudflare/types/workers_for_platforms/dispatch/namespaces/scripts/setting_get_response.py @@ -319,10 +319,14 @@ class BindingWorkersBindingKindInherit(BaseModel): """ version_id: Optional[str] = None - """ - Identifier for the version to inherit the binding from, which can be the version - ID or the literal "latest" to inherit from the latest version. Defaults to - inheriting the binding from the latest version. + """Identifier for the version to inherit the binding from. + + This can be a version ID, or the literal "latest" to inherit from the most + recently uploaded version, which may not be the deployed version. Defaults to + "latest". Only the Workers API version endpoints under + `/accounts/{account_id}/workers/workers/{worker_id}/versions` accept a version + ID. Other endpoints, including script upload and script version upload, accept + only "latest" and reject a version ID with error 10057. """ @@ -654,13 +658,16 @@ class BindingWorkersBindingKindVPCNetwork(BaseModel): identity: Optional[Literal["runtime-email-alpha"]] = None """Enables Gateway identity for the binding. - Requires network_id to be "cf1:network" and cannot be combined with tunnel_id. + Requires network_id to be "cf1:network" and cannot be combined with tunnel_id or + an explicit "cf1:vnet:" network_id. """ network_id: Optional[str] = None """Identifier of the network to bind to. - Only "cf1:network" is currently supported. Mutually exclusive with tunnel_id. + Use "cf1:network" to select the account's default virtual network at runtime, or + "cf1:vnet:" to select an explicit virtual network in the Worker's account. + Mutually exclusive with tunnel_id. """ tunnel_id: Optional[str] = None diff --git a/src/cloudflare/types/workers_for_platforms/dispatch/namespaces/scripts/tag_delete_response.py b/src/cloudflare/types/workers_for_platforms/dispatch/namespaces/scripts/tag_delete_response.py new file mode 100644 index 00000000000..caecf57b350 --- /dev/null +++ b/src/cloudflare/types/workers_for_platforms/dispatch/namespaces/scripts/tag_delete_response.py @@ -0,0 +1,106 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Dict, List, Union, Optional +from typing_extensions import Literal, TypeAlias + +from ......_models import BaseModel + +__all__ = [ + "TagDeleteResponse", + "WorkersTagsKVResponse", + "WorkersTagsKVResponseError", + "WorkersTagsKVResponseErrorSource", + "WorkersTagsKVResponseMessage", + "WorkersTagsKVResponseMessageSource", + "WorkersAPIResponseNullResult", + "WorkersAPIResponseNullResultError", + "WorkersAPIResponseNullResultErrorSource", + "WorkersAPIResponseNullResultMessage", + "WorkersAPIResponseNullResultMessageSource", +] + + +class WorkersTagsKVResponseErrorSource(BaseModel): + pointer: Optional[str] = None + + +class WorkersTagsKVResponseError(BaseModel): + code: int + + message: str + + documentation_url: Optional[str] = None + + source: Optional[WorkersTagsKVResponseErrorSource] = None + + +class WorkersTagsKVResponseMessageSource(BaseModel): + pointer: Optional[str] = None + + +class WorkersTagsKVResponseMessage(BaseModel): + code: int + + message: str + + documentation_url: Optional[str] = None + + source: Optional[WorkersTagsKVResponseMessageSource] = None + + +class WorkersTagsKVResponse(BaseModel): + errors: List[WorkersTagsKVResponseError] + + messages: List[WorkersTagsKVResponseMessage] + + result: Dict[str, str] + """Tags associated with the Worker, as a key/value object. + + Each complete UTF-8 encoded tag (the key plus `=` and the value when the value + is non-empty) must not exceed 1024 bytes. + """ + + success: Literal[True] + """Whether the API call was successful.""" + + +class WorkersAPIResponseNullResultErrorSource(BaseModel): + pointer: Optional[str] = None + + +class WorkersAPIResponseNullResultError(BaseModel): + code: int + + message: str + + documentation_url: Optional[str] = None + + source: Optional[WorkersAPIResponseNullResultErrorSource] = None + + +class WorkersAPIResponseNullResultMessageSource(BaseModel): + pointer: Optional[str] = None + + +class WorkersAPIResponseNullResultMessage(BaseModel): + code: int + + message: str + + documentation_url: Optional[str] = None + + source: Optional[WorkersAPIResponseNullResultMessageSource] = None + + +class WorkersAPIResponseNullResult(BaseModel): + errors: List[WorkersAPIResponseNullResultError] + + messages: List[WorkersAPIResponseNullResultMessage] + + success: Literal[True] + """Whether the API call was successful.""" + + result: Optional[object] = None + + +TagDeleteResponse: TypeAlias = Union[WorkersTagsKVResponse, WorkersAPIResponseNullResult] diff --git a/src/cloudflare/types/workflows/workflow_get_response.py b/src/cloudflare/types/workflows/workflow_get_response.py index c222d82853b..fc441cc3fcc 100644 --- a/src/cloudflare/types/workflows/workflow_get_response.py +++ b/src/cloudflare/types/workflows/workflow_get_response.py @@ -2,6 +2,7 @@ from typing import Dict, List, Optional from datetime import datetime +from typing_extensions import Literal from ..._models import BaseModel @@ -31,6 +32,12 @@ class WorkflowGetResponse(BaseModel): triggered_on: Optional[datetime] = None + jurisdiction: Optional[Literal["eu", "fedramp", "us"]] = None + """Jurisdiction where instances of this workflow run and store data. + + Set when the workflow is created and cannot be changed. + """ + schedules: Optional[List[Schedule]] = None script_deleted: Optional[bool] = None diff --git a/src/cloudflare/types/workflows/workflow_list_response.py b/src/cloudflare/types/workflows/workflow_list_response.py index 6da85ad4bb0..5cbcc492099 100644 --- a/src/cloudflare/types/workflows/workflow_list_response.py +++ b/src/cloudflare/types/workflows/workflow_list_response.py @@ -2,6 +2,7 @@ from typing import Dict, List, Optional from datetime import datetime +from typing_extensions import Literal from ..._models import BaseModel @@ -31,6 +32,12 @@ class WorkflowListResponse(BaseModel): triggered_on: Optional[datetime] = None + jurisdiction: Optional[Literal["eu", "fedramp", "us"]] = None + """Jurisdiction where instances of this workflow run and store data. + + Set when the workflow is created and cannot be changed. + """ + schedules: Optional[List[Schedule]] = None script_deleted: Optional[bool] = None diff --git a/src/cloudflare/types/workflows/workflow_update_params.py b/src/cloudflare/types/workflows/workflow_update_params.py index 9dbc12f9f9a..85ad0839afc 100644 --- a/src/cloudflare/types/workflows/workflow_update_params.py +++ b/src/cloudflare/types/workflows/workflow_update_params.py @@ -3,7 +3,7 @@ from __future__ import annotations from typing import Union, Iterable -from typing_extensions import Required, TypedDict +from typing_extensions import Literal, Required, TypedDict __all__ = ["WorkflowUpdateParams", "Concurrency", "DefaultRetention", "Limits", "Schedule"] @@ -23,6 +23,13 @@ class WorkflowUpdateParams(TypedDict, total=False): their own retention. """ + jurisdiction: Literal["eu", "fedramp", "us"] + """Jurisdiction where instances of this workflow run and store data. + + Can only be set when the workflow is created and cannot be changed afterwards; + omit it to keep the existing jurisdiction. + """ + limits: Limits schedules: Iterable[Schedule] diff --git a/src/cloudflare/types/workflows/workflow_update_response.py b/src/cloudflare/types/workflows/workflow_update_response.py index efbe8df575a..7bc12eed73f 100644 --- a/src/cloudflare/types/workflows/workflow_update_response.py +++ b/src/cloudflare/types/workflows/workflow_update_response.py @@ -2,6 +2,7 @@ from typing import Optional from datetime import datetime +from typing_extensions import Literal from ..._models import BaseModel @@ -28,3 +29,9 @@ class WorkflowUpdateResponse(BaseModel): triggered_on: Optional[datetime] = None version_id: str + + jurisdiction: Optional[Literal["eu", "fedramp", "us"]] = None + """Jurisdiction where instances of this workflow run and store data. + + Set when the workflow is created and cannot be changed. + """ diff --git a/src/cloudflare/types/zero_trust/access/__init__.py b/src/cloudflare/types/zero_trust/access/__init__.py index 64c6d5a4eee..02a32fefc8d 100644 --- a/src/cloudflare/types/zero_trust/access/__init__.py +++ b/src/cloudflare/types/zero_trust/access/__init__.py @@ -47,6 +47,7 @@ from .tag_delete_response import TagDeleteResponse as TagDeleteResponse from .approval_group_param import ApprovalGroupParam as ApprovalGroupParam from .associated_hostnames import AssociatedHostnames as AssociatedHostnames +from .destination_override import DestinationOverride as DestinationOverride from .idp_federation_grant import IdPFederationGrant as IdPFederationGrant from .policy_create_params import PolicyCreateParams as PolicyCreateParams from .policy_list_response import PolicyListResponse as PolicyListResponse @@ -76,6 +77,7 @@ from .custom_page_update_params import CustomPageUpdateParams as CustomPageUpdateParams from .scim_config_mapping_param import SCIMConfigMappingParam as SCIMConfigMappingParam from .service_token_list_params import ServiceTokenListParams as ServiceTokenListParams +from .destination_override_param import DestinationOverrideParam as DestinationOverrideParam from .gateway_ca_create_response import GatewayCACreateResponse as GatewayCACreateResponse from .gateway_ca_delete_response import GatewayCADeleteResponse as GatewayCADeleteResponse from .application_create_response import ApplicationCreateResponse as ApplicationCreateResponse @@ -83,14 +85,24 @@ from .application_update_response import ApplicationUpdateResponse as ApplicationUpdateResponse from .certificate_delete_response import CertificateDeleteResponse as CertificateDeleteResponse from .custom_page_delete_response import CustomPageDeleteResponse as CustomPageDeleteResponse +from .custom_page_validate_params import CustomPageValidateParams as CustomPageValidateParams from .service_token_create_params import ServiceTokenCreateParams as ServiceTokenCreateParams from .service_token_rotate_params import ServiceTokenRotateParams as ServiceTokenRotateParams from .service_token_update_params import ServiceTokenUpdateParams as ServiceTokenUpdateParams +from .user_population_list_params import UserPopulationListParams as UserPopulationListParams from .saml_certificate_list_params import SAMLCertificateListParams as SAMLCertificateListParams +from .user_population_get_response import UserPopulationGetResponse as UserPopulationGetResponse +from .custom_page_validate_response import CustomPageValidateResponse as CustomPageValidateResponse from .saml_certificate_get_response import SAMLCertificateGetResponse as SAMLCertificateGetResponse from .service_token_create_response import ServiceTokenCreateResponse as ServiceTokenCreateResponse from .service_token_rotate_response import ServiceTokenRotateResponse as ServiceTokenRotateResponse +from .user_population_create_params import UserPopulationCreateParams as UserPopulationCreateParams +from .user_population_list_response import UserPopulationListResponse as UserPopulationListResponse +from .user_population_update_params import UserPopulationUpdateParams as UserPopulationUpdateParams from .saml_certificate_list_response import SAMLCertificateListResponse as SAMLCertificateListResponse +from .user_population_create_response import UserPopulationCreateResponse as UserPopulationCreateResponse +from .user_population_delete_response import UserPopulationDeleteResponse as UserPopulationDeleteResponse +from .user_population_update_response import UserPopulationUpdateResponse as UserPopulationUpdateResponse from .saml_certificate_rotate_response import SAMLCertificateRotateResponse as SAMLCertificateRotateResponse from .scim_config_authentication_oauth2 import SCIMConfigAuthenticationOauth2 as SCIMConfigAuthenticationOauth2 from .idp_federation_grant_create_params import IdPFederationGrantCreateParams as IdPFederationGrantCreateParams diff --git a/src/cloudflare/types/zero_trust/access/ai_controls/mcp/portal_create_response.py b/src/cloudflare/types/zero_trust/access/ai_controls/mcp/portal_create_response.py index bc2053fc23b..671fc837c62 100644 --- a/src/cloudflare/types/zero_trust/access/ai_controls/mcp/portal_create_response.py +++ b/src/cloudflare/types/zero_trust/access/ai_controls/mcp/portal_create_response.py @@ -157,10 +157,10 @@ class Server(BaseModel): is_shared_oauth_callback_enabled: Optional[bool] = None """ - When true, the gateway worker uses the shared Cloudflare-owned OAuth callback - endpoint as the redirect_uri for upstream on-behalf OAuth, instead of the - customer portal hostname. Defaults to false (off); opt in per server by setting - true. + When true, per-user authorization uses the shared Cloudflare callback URL as the + 'redirect_uri' instead of the portal callback URL. The default is false. Set + 'is_shared_oauth_callback_enabled' to true to enable the shared Cloudflare + callback URL for this MCP server. """ last_successful_sync: Optional[datetime] = None @@ -173,6 +173,9 @@ class Server(BaseModel): on_behalf: Optional[bool] = None + registered_at: Optional[datetime] = None + """Timestamp of the most recent successful admin OAuth registration.""" + secure_web_gateway: Optional[bool] = None """ Route outbound traffic to this MCP server through Zero Trust Secure Web Gateway. diff --git a/src/cloudflare/types/zero_trust/access/ai_controls/mcp/portal_list_response.py b/src/cloudflare/types/zero_trust/access/ai_controls/mcp/portal_list_response.py index d8d9f6c7ed5..e5186a1aa86 100644 --- a/src/cloudflare/types/zero_trust/access/ai_controls/mcp/portal_list_response.py +++ b/src/cloudflare/types/zero_trust/access/ai_controls/mcp/portal_list_response.py @@ -157,10 +157,10 @@ class Server(BaseModel): is_shared_oauth_callback_enabled: Optional[bool] = None """ - When true, the gateway worker uses the shared Cloudflare-owned OAuth callback - endpoint as the redirect_uri for upstream on-behalf OAuth, instead of the - customer portal hostname. Defaults to false (off); opt in per server by setting - true. + When true, per-user authorization uses the shared Cloudflare callback URL as the + 'redirect_uri' instead of the portal callback URL. The default is false. Set + 'is_shared_oauth_callback_enabled' to true to enable the shared Cloudflare + callback URL for this MCP server. """ last_successful_sync: Optional[datetime] = None @@ -173,6 +173,9 @@ class Server(BaseModel): on_behalf: Optional[bool] = None + registered_at: Optional[datetime] = None + """Timestamp of the most recent successful admin OAuth registration.""" + secure_web_gateway: Optional[bool] = None """ Route outbound traffic to this MCP server through Zero Trust Secure Web Gateway. diff --git a/src/cloudflare/types/zero_trust/access/ai_controls/mcp/portal_read_response.py b/src/cloudflare/types/zero_trust/access/ai_controls/mcp/portal_read_response.py index fb2f35c43d7..0285813794d 100644 --- a/src/cloudflare/types/zero_trust/access/ai_controls/mcp/portal_read_response.py +++ b/src/cloudflare/types/zero_trust/access/ai_controls/mcp/portal_read_response.py @@ -157,10 +157,10 @@ class Server(BaseModel): is_shared_oauth_callback_enabled: Optional[bool] = None """ - When true, the gateway worker uses the shared Cloudflare-owned OAuth callback - endpoint as the redirect_uri for upstream on-behalf OAuth, instead of the - customer portal hostname. Defaults to false (off); opt in per server by setting - true. + When true, per-user authorization uses the shared Cloudflare callback URL as the + 'redirect_uri' instead of the portal callback URL. The default is false. Set + 'is_shared_oauth_callback_enabled' to true to enable the shared Cloudflare + callback URL for this MCP server. """ last_successful_sync: Optional[datetime] = None @@ -173,6 +173,9 @@ class Server(BaseModel): on_behalf: Optional[bool] = None + registered_at: Optional[datetime] = None + """Timestamp of the most recent successful admin OAuth registration.""" + secure_web_gateway: Optional[bool] = None """ Route outbound traffic to this MCP server through Zero Trust Secure Web Gateway. diff --git a/src/cloudflare/types/zero_trust/access/ai_controls/mcp/portal_update_response.py b/src/cloudflare/types/zero_trust/access/ai_controls/mcp/portal_update_response.py index 596b294bd9a..499755da1b1 100644 --- a/src/cloudflare/types/zero_trust/access/ai_controls/mcp/portal_update_response.py +++ b/src/cloudflare/types/zero_trust/access/ai_controls/mcp/portal_update_response.py @@ -157,10 +157,10 @@ class Server(BaseModel): is_shared_oauth_callback_enabled: Optional[bool] = None """ - When true, the gateway worker uses the shared Cloudflare-owned OAuth callback - endpoint as the redirect_uri for upstream on-behalf OAuth, instead of the - customer portal hostname. Defaults to false (off); opt in per server by setting - true. + When true, per-user authorization uses the shared Cloudflare callback URL as the + 'redirect_uri' instead of the portal callback URL. The default is false. Set + 'is_shared_oauth_callback_enabled' to true to enable the shared Cloudflare + callback URL for this MCP server. """ last_successful_sync: Optional[datetime] = None @@ -173,6 +173,9 @@ class Server(BaseModel): on_behalf: Optional[bool] = None + registered_at: Optional[datetime] = None + """Timestamp of the most recent successful admin OAuth registration.""" + secure_web_gateway: Optional[bool] = None """ Route outbound traffic to this MCP server through Zero Trust Secure Web Gateway. diff --git a/src/cloudflare/types/zero_trust/access/ai_controls/mcp/server_create_params.py b/src/cloudflare/types/zero_trust/access/ai_controls/mcp/server_create_params.py index 85c362dc5de..89a48ca6137 100644 --- a/src/cloudflare/types/zero_trust/access/ai_controls/mcp/server_create_params.py +++ b/src/cloudflare/types/zero_trust/access/ai_controls/mcp/server_create_params.py @@ -24,21 +24,32 @@ class ServerCreateParams(TypedDict, total=False): """Display name for the MCP server.""" auth_credentials: str - """Static credential for the upstream MCP server. + """Credential configuration for the upstream MCP server. For auth_type "bearer", either a raw token string (e.g. "sk-abc123"), which is wrapped server-side as `Authorization: Bearer `, or a JSON-encoded object of the form `{"headers":{"Header-Name":"value",...}}` for custom or multiple static headers (e.g. Cloudflare Access service tokens: `{"headers":{"cf-access-client-id":"...","cf-access-client-secret":"..."}}`). + For auth_type "oauth" with a pre-registered client, send a JSON-encoded object + containing `auth_mode:"manual"`, `config.authorization_endpoint`, + `config.token_endpoint`, and `registration_info.client_id`. Also provide + `registration_info.redirect_uris` unless `is_shared_oauth_callback_enabled` is + true. Optional fields include `config.issuer`, `config.revocation_endpoint`, + `registration_info.scope`, and `registration_info.token_endpoint_auth_method`. + Send the client secret in the separate `client_secret` field. Omit + `auth_credentials` on update to preserve the existing configuration. """ client_secret: str - """Pre-registered OAuth client_secret. - - Write-only - accepted on create/update when auth_credentials.auth_mode is - 'manual'. Stored AES-GCM-encrypted in server_oauth_secrets; never returned by - read endpoints. + """Provides 'client_secret' for a pre-registered OAuth client. + + This field is accepted on create or update only when + 'auth_credentials.auth_mode' is 'manual'. It is required when creating an MCP + server with manual OAuth credentials or changing an existing server to use + manual OAuth credentials. Omit 'client_secret' on update to preserve the + existing secret. Provide a new 'client_secret' to rotate the secret. The secret + is never returned by read, create, or update requests. """ description: Optional[str] @@ -46,10 +57,10 @@ class ServerCreateParams(TypedDict, total=False): is_shared_oauth_callback_enabled: bool """ - When true, the gateway worker uses the shared Cloudflare-owned OAuth callback - endpoint as the redirect_uri for upstream on-behalf OAuth, instead of the - customer portal hostname. Defaults to false (off); opt in per server by setting - true. + When true, per-user authorization uses the shared Cloudflare callback URL as the + 'redirect_uri' instead of the portal callback URL. The default is false. Set + 'is_shared_oauth_callback_enabled' to true to enable the shared Cloudflare + callback URL for this MCP server. """ secure_web_gateway: bool diff --git a/src/cloudflare/types/zero_trust/access/ai_controls/mcp/server_create_response.py b/src/cloudflare/types/zero_trust/access/ai_controls/mcp/server_create_response.py index 1f1465eb539..b1df066c758 100644 --- a/src/cloudflare/types/zero_trust/access/ai_controls/mcp/server_create_response.py +++ b/src/cloudflare/types/zero_trust/access/ai_controls/mcp/server_create_response.py @@ -146,10 +146,10 @@ class ServerCreateResponse(BaseModel): is_shared_oauth_callback_enabled: Optional[bool] = None """ - When true, the gateway worker uses the shared Cloudflare-owned OAuth callback - endpoint as the redirect_uri for upstream on-behalf OAuth, instead of the - customer portal hostname. Defaults to false (off); opt in per server by setting - true. + When true, per-user authorization uses the shared Cloudflare callback URL as the + 'redirect_uri' instead of the portal callback URL. The default is false. Set + 'is_shared_oauth_callback_enabled' to true to enable the shared Cloudflare + callback URL for this MCP server. """ last_successful_sync: Optional[datetime] = None @@ -160,6 +160,9 @@ class ServerCreateResponse(BaseModel): modified_by: Optional[str] = None + registered_at: Optional[datetime] = None + """Timestamp of the most recent successful admin OAuth registration.""" + secure_web_gateway: Optional[bool] = None """ Route outbound traffic to this MCP server through Zero Trust Secure Web Gateway. diff --git a/src/cloudflare/types/zero_trust/access/ai_controls/mcp/server_delete_response.py b/src/cloudflare/types/zero_trust/access/ai_controls/mcp/server_delete_response.py index 773b0c03c32..6ea166e4710 100644 --- a/src/cloudflare/types/zero_trust/access/ai_controls/mcp/server_delete_response.py +++ b/src/cloudflare/types/zero_trust/access/ai_controls/mcp/server_delete_response.py @@ -146,10 +146,10 @@ class ServerDeleteResponse(BaseModel): is_shared_oauth_callback_enabled: Optional[bool] = None """ - When true, the gateway worker uses the shared Cloudflare-owned OAuth callback - endpoint as the redirect_uri for upstream on-behalf OAuth, instead of the - customer portal hostname. Defaults to false (off); opt in per server by setting - true. + When true, per-user authorization uses the shared Cloudflare callback URL as the + 'redirect_uri' instead of the portal callback URL. The default is false. Set + 'is_shared_oauth_callback_enabled' to true to enable the shared Cloudflare + callback URL for this MCP server. """ last_successful_sync: Optional[datetime] = None @@ -160,6 +160,9 @@ class ServerDeleteResponse(BaseModel): modified_by: Optional[str] = None + registered_at: Optional[datetime] = None + """Timestamp of the most recent successful admin OAuth registration.""" + secure_web_gateway: Optional[bool] = None """ Route outbound traffic to this MCP server through Zero Trust Secure Web Gateway. diff --git a/src/cloudflare/types/zero_trust/access/ai_controls/mcp/server_list_response.py b/src/cloudflare/types/zero_trust/access/ai_controls/mcp/server_list_response.py index cb059f8cc63..dba196e346e 100644 --- a/src/cloudflare/types/zero_trust/access/ai_controls/mcp/server_list_response.py +++ b/src/cloudflare/types/zero_trust/access/ai_controls/mcp/server_list_response.py @@ -146,10 +146,10 @@ class ServerListResponse(BaseModel): is_shared_oauth_callback_enabled: Optional[bool] = None """ - When true, the gateway worker uses the shared Cloudflare-owned OAuth callback - endpoint as the redirect_uri for upstream on-behalf OAuth, instead of the - customer portal hostname. Defaults to false (off); opt in per server by setting - true. + When true, per-user authorization uses the shared Cloudflare callback URL as the + 'redirect_uri' instead of the portal callback URL. The default is false. Set + 'is_shared_oauth_callback_enabled' to true to enable the shared Cloudflare + callback URL for this MCP server. """ last_successful_sync: Optional[datetime] = None @@ -160,6 +160,9 @@ class ServerListResponse(BaseModel): modified_by: Optional[str] = None + registered_at: Optional[datetime] = None + """Timestamp of the most recent successful admin OAuth registration.""" + secure_web_gateway: Optional[bool] = None """ Route outbound traffic to this MCP server through Zero Trust Secure Web Gateway. diff --git a/src/cloudflare/types/zero_trust/access/ai_controls/mcp/server_read_response.py b/src/cloudflare/types/zero_trust/access/ai_controls/mcp/server_read_response.py index 56ca204299d..afea11ddfef 100644 --- a/src/cloudflare/types/zero_trust/access/ai_controls/mcp/server_read_response.py +++ b/src/cloudflare/types/zero_trust/access/ai_controls/mcp/server_read_response.py @@ -146,10 +146,10 @@ class ServerReadResponse(BaseModel): is_shared_oauth_callback_enabled: Optional[bool] = None """ - When true, the gateway worker uses the shared Cloudflare-owned OAuth callback - endpoint as the redirect_uri for upstream on-behalf OAuth, instead of the - customer portal hostname. Defaults to false (off); opt in per server by setting - true. + When true, per-user authorization uses the shared Cloudflare callback URL as the + 'redirect_uri' instead of the portal callback URL. The default is false. Set + 'is_shared_oauth_callback_enabled' to true to enable the shared Cloudflare + callback URL for this MCP server. """ last_successful_sync: Optional[datetime] = None @@ -160,6 +160,9 @@ class ServerReadResponse(BaseModel): modified_by: Optional[str] = None + registered_at: Optional[datetime] = None + """Timestamp of the most recent successful admin OAuth registration.""" + secure_web_gateway: Optional[bool] = None """ Route outbound traffic to this MCP server through Zero Trust Secure Web Gateway. diff --git a/src/cloudflare/types/zero_trust/access/ai_controls/mcp/server_update_params.py b/src/cloudflare/types/zero_trust/access/ai_controls/mcp/server_update_params.py index 6b1bc67437c..38b7e23bb33 100644 --- a/src/cloudflare/types/zero_trust/access/ai_controls/mcp/server_update_params.py +++ b/src/cloudflare/types/zero_trust/access/ai_controls/mcp/server_update_params.py @@ -12,21 +12,32 @@ class ServerUpdateParams(TypedDict, total=False): account_id: Required[str] auth_credentials: str - """Static credential for the upstream MCP server. + """Credential configuration for the upstream MCP server. For auth_type "bearer", either a raw token string (e.g. "sk-abc123"), which is wrapped server-side as `Authorization: Bearer `, or a JSON-encoded object of the form `{"headers":{"Header-Name":"value",...}}` for custom or multiple static headers (e.g. Cloudflare Access service tokens: `{"headers":{"cf-access-client-id":"...","cf-access-client-secret":"..."}}`). + For auth_type "oauth" with a pre-registered client, send a JSON-encoded object + containing `auth_mode:"manual"`, `config.authorization_endpoint`, + `config.token_endpoint`, and `registration_info.client_id`. Also provide + `registration_info.redirect_uris` unless `is_shared_oauth_callback_enabled` is + true. Optional fields include `config.issuer`, `config.revocation_endpoint`, + `registration_info.scope`, and `registration_info.token_endpoint_auth_method`. + Send the client secret in the separate `client_secret` field. Omit + `auth_credentials` on update to preserve the existing configuration. """ client_secret: str - """Pre-registered OAuth client_secret. - - Write-only - accepted on create/update when auth_credentials.auth_mode is - 'manual'. Stored AES-GCM-encrypted in server_oauth_secrets; never returned by - read endpoints. + """Provides 'client_secret' for a pre-registered OAuth client. + + This field is accepted on create or update only when + 'auth_credentials.auth_mode' is 'manual'. It is required when creating an MCP + server with manual OAuth credentials or changing an existing server to use + manual OAuth credentials. Omit 'client_secret' on update to preserve the + existing secret. Provide a new 'client_secret' to rotate the secret. The secret + is never returned by read, create, or update requests. """ description: Optional[str] @@ -34,10 +45,10 @@ class ServerUpdateParams(TypedDict, total=False): is_shared_oauth_callback_enabled: bool """ - When true, the gateway worker uses the shared Cloudflare-owned OAuth callback - endpoint as the redirect_uri for upstream on-behalf OAuth, instead of the - customer portal hostname. Defaults to false (off); opt in per server by setting - true. + When true, per-user authorization uses the shared Cloudflare callback URL as the + 'redirect_uri' instead of the portal callback URL. The default is false. Set + 'is_shared_oauth_callback_enabled' to true to enable the shared Cloudflare + callback URL for this MCP server. """ name: str diff --git a/src/cloudflare/types/zero_trust/access/ai_controls/mcp/server_update_response.py b/src/cloudflare/types/zero_trust/access/ai_controls/mcp/server_update_response.py index b8df2810246..465db766479 100644 --- a/src/cloudflare/types/zero_trust/access/ai_controls/mcp/server_update_response.py +++ b/src/cloudflare/types/zero_trust/access/ai_controls/mcp/server_update_response.py @@ -146,10 +146,10 @@ class ServerUpdateResponse(BaseModel): is_shared_oauth_callback_enabled: Optional[bool] = None """ - When true, the gateway worker uses the shared Cloudflare-owned OAuth callback - endpoint as the redirect_uri for upstream on-behalf OAuth, instead of the - customer portal hostname. Defaults to false (off); opt in per server by setting - true. + When true, per-user authorization uses the shared Cloudflare callback URL as the + 'redirect_uri' instead of the portal callback URL. The default is false. Set + 'is_shared_oauth_callback_enabled' to true to enable the shared Cloudflare + callback URL for this MCP server. """ last_successful_sync: Optional[datetime] = None @@ -160,6 +160,9 @@ class ServerUpdateResponse(BaseModel): modified_by: Optional[str] = None + registered_at: Optional[datetime] = None + """Timestamp of the most recent successful admin OAuth registration.""" + secure_web_gateway: Optional[bool] = None """ Route outbound traffic to this MCP server through Zero Trust Secure Web Gateway. diff --git a/src/cloudflare/types/zero_trust/access/application_create_params.py b/src/cloudflare/types/zero_trust/access/application_create_params.py index fc8affceaac..88db8e80e8a 100644 --- a/src/cloudflare/types/zero_trust/access/application_create_params.py +++ b/src/cloudflare/types/zero_trust/access/application_create_params.py @@ -15,6 +15,7 @@ from .self_hosted_domains import SelfHostedDomains from .approval_group_param import ApprovalGroupParam from .scim_config_mapping_param import SCIMConfigMappingParam +from .destination_override_param import DestinationOverrideParam from .applications.access_rule_param import AccessRuleParam from .scim_config_authentication_oauth2_param import SCIMConfigAuthenticationOauth2Param from .scim_config_authentication_http_basic_param import SCIMConfigAuthenticationHTTPBasicParam @@ -22,20 +23,25 @@ __all__ = [ "ApplicationCreateParams", + "AccessEndUserProps", + "AccessEndUserPropsOAuthConfiguration", + "AccessEndUserPropsOAuthConfigurationDynamicClientRegistration", + "AccessEndUserPropsOAuthConfigurationGrant", + "AccessEndUserPropsDestination", + "AccessEndUserPropsDestinationAccessEndUserPublicDestination", + "AccessEndUserPropsDestinationAccessEndUserWorkerDestination", + "AccessEndUserPropsDestinationAccessEndUserPreviewWorkerDestination", + "AccessEndUserPropsDestinationAccessEndUserAllWorkersDestination", + "AccessEndUserPropsDestinationAccessEndUserAllPreviewWorkersDestination", "SelfHostedApplication", "SelfHostedApplicationDestination", "SelfHostedApplicationDestinationPublicDestination", - "SelfHostedApplicationDestinationPublicDestinationOverride", "SelfHostedApplicationDestinationPrivateDestination", "SelfHostedApplicationDestinationViaMcpServerPortalDestination", "SelfHostedApplicationDestinationWorkerDestination", - "SelfHostedApplicationDestinationWorkerDestinationOverride", "SelfHostedApplicationDestinationPreviewWorkerDestination", - "SelfHostedApplicationDestinationPreviewWorkerDestinationOverride", "SelfHostedApplicationDestinationAllWorkersDestination", - "SelfHostedApplicationDestinationAllWorkersDestinationOverride", "SelfHostedApplicationDestinationAllPreviewWorkersDestination", - "SelfHostedApplicationDestinationAllPreviewWorkersDestinationOverride", "SelfHostedApplicationMfaConfig", "SelfHostedApplicationOAuthConfiguration", "SelfHostedApplicationOAuthConfigurationDynamicClientRegistration", @@ -67,17 +73,12 @@ "BrowserSSHApplication", "BrowserSSHApplicationDestination", "BrowserSSHApplicationDestinationPublicDestination", - "BrowserSSHApplicationDestinationPublicDestinationOverride", "BrowserSSHApplicationDestinationPrivateDestination", "BrowserSSHApplicationDestinationViaMcpServerPortalDestination", "BrowserSSHApplicationDestinationWorkerDestination", - "BrowserSSHApplicationDestinationWorkerDestinationOverride", "BrowserSSHApplicationDestinationPreviewWorkerDestination", - "BrowserSSHApplicationDestinationPreviewWorkerDestinationOverride", "BrowserSSHApplicationDestinationAllWorkersDestination", - "BrowserSSHApplicationDestinationAllWorkersDestinationOverride", "BrowserSSHApplicationDestinationAllPreviewWorkersDestination", - "BrowserSSHApplicationDestinationAllPreviewWorkersDestinationOverride", "BrowserSSHApplicationMfaConfig", "BrowserSSHApplicationOAuthConfiguration", "BrowserSSHApplicationOAuthConfigurationDynamicClientRegistration", @@ -96,17 +97,12 @@ "BrowserVNCApplication", "BrowserVNCApplicationDestination", "BrowserVNCApplicationDestinationPublicDestination", - "BrowserVNCApplicationDestinationPublicDestinationOverride", "BrowserVNCApplicationDestinationPrivateDestination", "BrowserVNCApplicationDestinationViaMcpServerPortalDestination", "BrowserVNCApplicationDestinationWorkerDestination", - "BrowserVNCApplicationDestinationWorkerDestinationOverride", "BrowserVNCApplicationDestinationPreviewWorkerDestination", - "BrowserVNCApplicationDestinationPreviewWorkerDestinationOverride", "BrowserVNCApplicationDestinationAllWorkersDestination", - "BrowserVNCApplicationDestinationAllWorkersDestinationOverride", "BrowserVNCApplicationDestinationAllPreviewWorkersDestination", - "BrowserVNCApplicationDestinationAllPreviewWorkersDestinationOverride", "BrowserVNCApplicationMfaConfig", "BrowserVNCApplicationOAuthConfiguration", "BrowserVNCApplicationOAuthConfigurationDynamicClientRegistration", @@ -182,17 +178,12 @@ "BrowserRDPApplicationTargetCriterionRequireTargetAttributes", "BrowserRDPApplicationDestination", "BrowserRDPApplicationDestinationPublicDestination", - "BrowserRDPApplicationDestinationPublicDestinationOverride", "BrowserRDPApplicationDestinationPrivateDestination", "BrowserRDPApplicationDestinationViaMcpServerPortalDestination", "BrowserRDPApplicationDestinationWorkerDestination", - "BrowserRDPApplicationDestinationWorkerDestinationOverride", "BrowserRDPApplicationDestinationPreviewWorkerDestination", - "BrowserRDPApplicationDestinationPreviewWorkerDestinationOverride", "BrowserRDPApplicationDestinationAllWorkersDestination", - "BrowserRDPApplicationDestinationAllWorkersDestinationOverride", "BrowserRDPApplicationDestinationAllPreviewWorkersDestination", - "BrowserRDPApplicationDestinationAllPreviewWorkersDestinationOverride", "BrowserRDPApplicationMfaConfig", "BrowserRDPApplicationOAuthConfiguration", "BrowserRDPApplicationOAuthConfigurationDynamicClientRegistration", @@ -211,17 +202,12 @@ "McpServerApplication", "McpServerApplicationDestination", "McpServerApplicationDestinationPublicDestination", - "McpServerApplicationDestinationPublicDestinationOverride", "McpServerApplicationDestinationPrivateDestination", "McpServerApplicationDestinationViaMcpServerPortalDestination", "McpServerApplicationDestinationWorkerDestination", - "McpServerApplicationDestinationWorkerDestinationOverride", "McpServerApplicationDestinationPreviewWorkerDestination", - "McpServerApplicationDestinationPreviewWorkerDestinationOverride", "McpServerApplicationDestinationAllWorkersDestination", - "McpServerApplicationDestinationAllWorkersDestinationOverride", "McpServerApplicationDestinationAllPreviewWorkersDestination", - "McpServerApplicationDestinationAllPreviewWorkersDestinationOverride", "McpServerApplicationOAuthConfiguration", "McpServerApplicationOAuthConfigurationDynamicClientRegistration", "McpServerApplicationOAuthConfigurationGrant", @@ -239,17 +225,12 @@ "McpServerPortalApplication", "McpServerPortalApplicationDestination", "McpServerPortalApplicationDestinationPublicDestination", - "McpServerPortalApplicationDestinationPublicDestinationOverride", "McpServerPortalApplicationDestinationPrivateDestination", "McpServerPortalApplicationDestinationViaMcpServerPortalDestination", "McpServerPortalApplicationDestinationWorkerDestination", - "McpServerPortalApplicationDestinationWorkerDestinationOverride", "McpServerPortalApplicationDestinationPreviewWorkerDestination", - "McpServerPortalApplicationDestinationPreviewWorkerDestinationOverride", "McpServerPortalApplicationDestinationAllWorkersDestination", - "McpServerPortalApplicationDestinationAllWorkersDestinationOverride", "McpServerPortalApplicationDestinationAllPreviewWorkersDestination", - "McpServerPortalApplicationDestinationAllPreviewWorkersDestinationOverride", "McpServerPortalApplicationOAuthConfiguration", "McpServerPortalApplicationOAuthConfigurationDynamicClientRegistration", "McpServerPortalApplicationOAuthConfigurationGrant", @@ -267,6 +248,200 @@ ] +class AccessEndUserProps(TypedDict, total=False): + oauth_configuration: Required[AccessEndUserPropsOAuthConfiguration] + """ + **Beta:** Optional configuration for managing an OAuth authorization flow + controlled by Access. When set, Access will act as the OAuth authorization + server for this application. Only compatible with OAuth clients that support + [RFC 8707](https://datatracker.ietf.org/doc/html/rfc8707) (Resource Indicators + for OAuth 2.0). This feature is currently in beta. + """ + + type: Required[ + Literal[ + "self_hosted", + "end_user", + "saas", + "ssh", + "vnc", + "app_launcher", + "warp", + "biso", + "bookmark", + "dash_sso", + "infrastructure", + "rdp", + "mcp", + "mcp_portal", + "proxy_endpoint", + ] + ] + """The application type.""" + + user_populations: Required[SequenceNotStr[str]] + """The single user population associated with this application.""" + + account_id: str + """The Account ID to use for this endpoint. Mutually exclusive with the Zone ID.""" + + zone_id: str + """The Zone ID to use for this endpoint. Mutually exclusive with the Account ID.""" + + allowed_idps: SequenceNotStr[AllowedIdPs] + """The identity providers your users can select when connecting to this + application. + + Defaults to all IdPs configured in your account. + """ + + destinations: Iterable[AccessEndUserPropsDestination] + """Public hostname and Workers destinations secured by Access.""" + + domain: str + """The primary hostname and path secured by Access. + + This domain will be displayed if the app is visible in the App Launcher. + """ + + name: str + """The name of the application.""" + + self_hosted_domains: SequenceNotStr[SelfHostedDomains] + """List of public domains that Access will secure. + + This field is deprecated in favor of `destinations` and will be supported until + **November 21, 2025.** If `destinations` are provided, then + `self_hosted_domains` will be ignored. + """ + + +class AccessEndUserPropsOAuthConfigurationDynamicClientRegistration(TypedDict, total=False): + """Settings for OAuth dynamic client registration.""" + + allow_any_on_localhost: bool + """Allows any client with redirect URIs on localhost.""" + + allow_any_on_loopback: bool + """Allows any client with redirect URIs on 127.0.0.1.""" + + allowed_uris: SequenceNotStr[str] + """The URIs that are allowed as redirect URIs for dynamically registered clients. + + HTTP and HTTPS paths may end in `/*` to match all sub-paths. Custom-scheme URIs + must be explicitly configured and match exactly. + """ + + enabled: bool + """Whether dynamic client registration is enabled.""" + + +class AccessEndUserPropsOAuthConfigurationGrant(TypedDict, total=False): + """Settings for OAuth grant behavior.""" + + access_token_lifetime: str + """The lifetime of the access token. + + Must be in the format `300ms` or `2h45m`. Valid time units are ns, us (or µs), + ms, s, m, h. + """ + + session_duration: str + """The duration of the OAuth session. + + Must be in the format `300ms` or `2h45m`. Valid time units are ns, us (or µs), + ms, s, m, h. + """ + + +class AccessEndUserPropsOAuthConfiguration(TypedDict, total=False): + """ + **Beta:** Optional configuration for managing an OAuth authorization flow controlled by Access. When set, Access will act as the OAuth authorization server for this application. Only compatible with OAuth clients that support [RFC 8707](https://datatracker.ietf.org/doc/html/rfc8707) (Resource Indicators for OAuth 2.0). This feature is currently in beta. + """ + + dynamic_client_registration: AccessEndUserPropsOAuthConfigurationDynamicClientRegistration + """Settings for OAuth dynamic client registration.""" + + enabled: Literal[True] + """Managed OAuth is required for end user applications and cannot be disabled.""" + + grant: AccessEndUserPropsOAuthConfigurationGrant + """Settings for OAuth grant behavior.""" + + +class AccessEndUserPropsDestinationAccessEndUserPublicDestination(TypedDict, total=False): + uri: Required[str] + """The public hostname and optional path to secure.""" + + overrides: Iterable[DestinationOverrideParam] + """Rules that override how Access handles requests to this destination. + + Each rule can make a matching path public, bypassing Access authentication. + Overrides are supported for public destinations and Worker destinations. + """ + + type: Literal["public"] + + +class AccessEndUserPropsDestinationAccessEndUserWorkerDestination(TypedDict, total=False): + type: Required[Literal["worker"]] + + worker_id: Required[str] + """The ID of the Cloudflare Worker to secure.""" + + overrides: Iterable[DestinationOverrideParam] + """Rules that override how Access handles requests to this destination. + + Each rule can make a matching path public, bypassing Access authentication. + Overrides are supported for public destinations and Worker destinations. + """ + + +class AccessEndUserPropsDestinationAccessEndUserPreviewWorkerDestination(TypedDict, total=False): + type: Required[Literal["preview_worker"]] + + worker_id: Required[str] + """The ID of the Cloudflare Worker whose previews to secure.""" + + overrides: Iterable[DestinationOverrideParam] + """Rules that override how Access handles requests to this destination. + + Each rule can make a matching path public, bypassing Access authentication. + Overrides are supported for public destinations and Worker destinations. + """ + + +class AccessEndUserPropsDestinationAccessEndUserAllWorkersDestination(TypedDict, total=False): + type: Required[Literal["all_workers"]] + + overrides: Iterable[DestinationOverrideParam] + """Rules that override how Access handles requests to this destination. + + Each rule can make a matching path public, bypassing Access authentication. + Overrides are supported for public destinations and Worker destinations. + """ + + +class AccessEndUserPropsDestinationAccessEndUserAllPreviewWorkersDestination(TypedDict, total=False): + type: Required[Literal["all_preview_workers"]] + + overrides: Iterable[DestinationOverrideParam] + """Rules that override how Access handles requests to this destination. + + Each rule can make a matching path public, bypassing Access authentication. + Overrides are supported for public destinations and Worker destinations. + """ + + +AccessEndUserPropsDestination: TypeAlias = Union[ + AccessEndUserPropsDestinationAccessEndUserPublicDestination, + AccessEndUserPropsDestinationAccessEndUserWorkerDestination, + AccessEndUserPropsDestinationAccessEndUserPreviewWorkerDestination, + AccessEndUserPropsDestinationAccessEndUserAllWorkersDestination, + AccessEndUserPropsDestinationAccessEndUserAllPreviewWorkersDestination, +] + + class SelfHostedApplication(TypedDict, total=False): domain: Required[str] """The primary hostname and path secured by Access. @@ -438,7 +613,7 @@ class SelfHostedApplication(TypedDict, total=False): """The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), - ms, s, m, h. Note: unsupported for infrastructure type applications. + ms, s, m, h. """ skip_interstitial: bool @@ -459,26 +634,13 @@ class SelfHostedApplication(TypedDict, total=False): """ -class SelfHostedApplicationDestinationPublicDestinationOverride(TypedDict, total=False): - behavior: Required[Literal["public"]] - """The behavior to apply to matching requests.""" - - path_pattern: Required[str] - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class SelfHostedApplicationDestinationPublicDestination(TypedDict, total=False): """A public hostname that Access will secure. Public destinations support sub-domain and path. Wildcard '*' can be used in the definition. """ - overrides: Iterable[SelfHostedApplicationDestinationPublicDestinationOverride] + overrides: Iterable[DestinationOverrideParam] """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -532,19 +694,6 @@ class SelfHostedApplicationDestinationViaMcpServerPortalDestination(TypedDict, t type: Literal["via_mcp_server_portal"] -class SelfHostedApplicationDestinationWorkerDestinationOverride(TypedDict, total=False): - behavior: Required[Literal["public"]] - """The behavior to apply to matching requests.""" - - path_pattern: Required[str] - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class SelfHostedApplicationDestinationWorkerDestination(TypedDict, total=False): """A specific Cloudflare Worker that Access will secure. @@ -556,7 +705,7 @@ class SelfHostedApplicationDestinationWorkerDestination(TypedDict, total=False): worker_id: Required[str] """The ID of the Cloudflare Worker to protect with Access.""" - overrides: Iterable[SelfHostedApplicationDestinationWorkerDestinationOverride] + overrides: Iterable[DestinationOverrideParam] """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -564,19 +713,6 @@ class SelfHostedApplicationDestinationWorkerDestination(TypedDict, total=False): """ -class SelfHostedApplicationDestinationPreviewWorkerDestinationOverride(TypedDict, total=False): - behavior: Required[Literal["public"]] - """The behavior to apply to matching requests.""" - - path_pattern: Required[str] - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class SelfHostedApplicationDestinationPreviewWorkerDestination(TypedDict, total=False): """A specific Cloudflare Worker whose preview deployments Access will secure. @@ -591,7 +727,7 @@ class SelfHostedApplicationDestinationPreviewWorkerDestination(TypedDict, total= Access. """ - overrides: Iterable[SelfHostedApplicationDestinationPreviewWorkerDestinationOverride] + overrides: Iterable[DestinationOverrideParam] """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -599,19 +735,6 @@ class SelfHostedApplicationDestinationPreviewWorkerDestination(TypedDict, total= """ -class SelfHostedApplicationDestinationAllWorkersDestinationOverride(TypedDict, total=False): - behavior: Required[Literal["public"]] - """The behavior to apply to matching requests.""" - - path_pattern: Required[str] - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class SelfHostedApplicationDestinationAllWorkersDestination(TypedDict, total=False): """ Protects all Cloudflare Workers on the account with Access, including their preview deployments. At most one destination of this type can exist per account. The `worker`, `preview_worker`, `all_preview_workers`, and `public` destination types take precedence, so you can create separate applications to override the policies for specific Workers, their previews, or specific paths. @@ -619,7 +742,7 @@ class SelfHostedApplicationDestinationAllWorkersDestination(TypedDict, total=Fal type: Required[Literal["all_workers"]] - overrides: Iterable[SelfHostedApplicationDestinationAllWorkersDestinationOverride] + overrides: Iterable[DestinationOverrideParam] """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -627,19 +750,6 @@ class SelfHostedApplicationDestinationAllWorkersDestination(TypedDict, total=Fal """ -class SelfHostedApplicationDestinationAllPreviewWorkersDestinationOverride(TypedDict, total=False): - behavior: Required[Literal["public"]] - """The behavior to apply to matching requests.""" - - path_pattern: Required[str] - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class SelfHostedApplicationDestinationAllPreviewWorkersDestination(TypedDict, total=False): """ Protects the preview deployments of all Cloudflare Workers on the account with Access. At most one destination of this type can exist per account. The `worker`, `preview_worker`, and `public` destination types take precedence, so you can create separate applications to override the policies for specific Workers, their previews, or specific paths. @@ -647,7 +757,7 @@ class SelfHostedApplicationDestinationAllPreviewWorkersDestination(TypedDict, to type: Required[Literal["all_preview_workers"]] - overrides: Iterable[SelfHostedApplicationDestinationAllPreviewWorkersDestinationOverride] + overrides: Iterable[DestinationOverrideParam] """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -1238,6 +1348,7 @@ class BrowserSSHApplication(TypedDict, total=False): type: Required[ Literal[ "self_hosted", + "end_user", "saas", "ssh", "vnc", @@ -1416,7 +1527,7 @@ class BrowserSSHApplication(TypedDict, total=False): """The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), - ms, s, m, h. Note: unsupported for infrastructure type applications. + ms, s, m, h. """ skip_interstitial: bool @@ -1437,26 +1548,13 @@ class BrowserSSHApplication(TypedDict, total=False): """ -class BrowserSSHApplicationDestinationPublicDestinationOverride(TypedDict, total=False): - behavior: Required[Literal["public"]] - """The behavior to apply to matching requests.""" - - path_pattern: Required[str] - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class BrowserSSHApplicationDestinationPublicDestination(TypedDict, total=False): """A public hostname that Access will secure. Public destinations support sub-domain and path. Wildcard '*' can be used in the definition. """ - overrides: Iterable[BrowserSSHApplicationDestinationPublicDestinationOverride] + overrides: Iterable[DestinationOverrideParam] """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -1510,19 +1608,6 @@ class BrowserSSHApplicationDestinationViaMcpServerPortalDestination(TypedDict, t type: Literal["via_mcp_server_portal"] -class BrowserSSHApplicationDestinationWorkerDestinationOverride(TypedDict, total=False): - behavior: Required[Literal["public"]] - """The behavior to apply to matching requests.""" - - path_pattern: Required[str] - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class BrowserSSHApplicationDestinationWorkerDestination(TypedDict, total=False): """A specific Cloudflare Worker that Access will secure. @@ -1534,7 +1619,7 @@ class BrowserSSHApplicationDestinationWorkerDestination(TypedDict, total=False): worker_id: Required[str] """The ID of the Cloudflare Worker to protect with Access.""" - overrides: Iterable[BrowserSSHApplicationDestinationWorkerDestinationOverride] + overrides: Iterable[DestinationOverrideParam] """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -1542,19 +1627,6 @@ class BrowserSSHApplicationDestinationWorkerDestination(TypedDict, total=False): """ -class BrowserSSHApplicationDestinationPreviewWorkerDestinationOverride(TypedDict, total=False): - behavior: Required[Literal["public"]] - """The behavior to apply to matching requests.""" - - path_pattern: Required[str] - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class BrowserSSHApplicationDestinationPreviewWorkerDestination(TypedDict, total=False): """A specific Cloudflare Worker whose preview deployments Access will secure. @@ -1569,7 +1641,7 @@ class BrowserSSHApplicationDestinationPreviewWorkerDestination(TypedDict, total= Access. """ - overrides: Iterable[BrowserSSHApplicationDestinationPreviewWorkerDestinationOverride] + overrides: Iterable[DestinationOverrideParam] """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -1577,19 +1649,6 @@ class BrowserSSHApplicationDestinationPreviewWorkerDestination(TypedDict, total= """ -class BrowserSSHApplicationDestinationAllWorkersDestinationOverride(TypedDict, total=False): - behavior: Required[Literal["public"]] - """The behavior to apply to matching requests.""" - - path_pattern: Required[str] - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class BrowserSSHApplicationDestinationAllWorkersDestination(TypedDict, total=False): """ Protects all Cloudflare Workers on the account with Access, including their preview deployments. At most one destination of this type can exist per account. The `worker`, `preview_worker`, `all_preview_workers`, and `public` destination types take precedence, so you can create separate applications to override the policies for specific Workers, their previews, or specific paths. @@ -1597,7 +1656,7 @@ class BrowserSSHApplicationDestinationAllWorkersDestination(TypedDict, total=Fal type: Required[Literal["all_workers"]] - overrides: Iterable[BrowserSSHApplicationDestinationAllWorkersDestinationOverride] + overrides: Iterable[DestinationOverrideParam] """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -1605,19 +1664,6 @@ class BrowserSSHApplicationDestinationAllWorkersDestination(TypedDict, total=Fal """ -class BrowserSSHApplicationDestinationAllPreviewWorkersDestinationOverride(TypedDict, total=False): - behavior: Required[Literal["public"]] - """The behavior to apply to matching requests.""" - - path_pattern: Required[str] - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class BrowserSSHApplicationDestinationAllPreviewWorkersDestination(TypedDict, total=False): """ Protects the preview deployments of all Cloudflare Workers on the account with Access. At most one destination of this type can exist per account. The `worker`, `preview_worker`, and `public` destination types take precedence, so you can create separate applications to override the policies for specific Workers, their previews, or specific paths. @@ -1625,7 +1671,7 @@ class BrowserSSHApplicationDestinationAllPreviewWorkersDestination(TypedDict, to type: Required[Literal["all_preview_workers"]] - overrides: Iterable[BrowserSSHApplicationDestinationAllPreviewWorkersDestinationOverride] + overrides: Iterable[DestinationOverrideParam] """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -1944,6 +1990,7 @@ class BrowserVNCApplication(TypedDict, total=False): type: Required[ Literal[ "self_hosted", + "end_user", "saas", "ssh", "vnc", @@ -2122,7 +2169,7 @@ class BrowserVNCApplication(TypedDict, total=False): """The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), - ms, s, m, h. Note: unsupported for infrastructure type applications. + ms, s, m, h. """ skip_interstitial: bool @@ -2143,26 +2190,13 @@ class BrowserVNCApplication(TypedDict, total=False): """ -class BrowserVNCApplicationDestinationPublicDestinationOverride(TypedDict, total=False): - behavior: Required[Literal["public"]] - """The behavior to apply to matching requests.""" - - path_pattern: Required[str] - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class BrowserVNCApplicationDestinationPublicDestination(TypedDict, total=False): """A public hostname that Access will secure. Public destinations support sub-domain and path. Wildcard '*' can be used in the definition. """ - overrides: Iterable[BrowserVNCApplicationDestinationPublicDestinationOverride] + overrides: Iterable[DestinationOverrideParam] """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -2216,19 +2250,6 @@ class BrowserVNCApplicationDestinationViaMcpServerPortalDestination(TypedDict, t type: Literal["via_mcp_server_portal"] -class BrowserVNCApplicationDestinationWorkerDestinationOverride(TypedDict, total=False): - behavior: Required[Literal["public"]] - """The behavior to apply to matching requests.""" - - path_pattern: Required[str] - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class BrowserVNCApplicationDestinationWorkerDestination(TypedDict, total=False): """A specific Cloudflare Worker that Access will secure. @@ -2240,7 +2261,7 @@ class BrowserVNCApplicationDestinationWorkerDestination(TypedDict, total=False): worker_id: Required[str] """The ID of the Cloudflare Worker to protect with Access.""" - overrides: Iterable[BrowserVNCApplicationDestinationWorkerDestinationOverride] + overrides: Iterable[DestinationOverrideParam] """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -2248,19 +2269,6 @@ class BrowserVNCApplicationDestinationWorkerDestination(TypedDict, total=False): """ -class BrowserVNCApplicationDestinationPreviewWorkerDestinationOverride(TypedDict, total=False): - behavior: Required[Literal["public"]] - """The behavior to apply to matching requests.""" - - path_pattern: Required[str] - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class BrowserVNCApplicationDestinationPreviewWorkerDestination(TypedDict, total=False): """A specific Cloudflare Worker whose preview deployments Access will secure. @@ -2275,7 +2283,7 @@ class BrowserVNCApplicationDestinationPreviewWorkerDestination(TypedDict, total= Access. """ - overrides: Iterable[BrowserVNCApplicationDestinationPreviewWorkerDestinationOverride] + overrides: Iterable[DestinationOverrideParam] """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -2283,19 +2291,6 @@ class BrowserVNCApplicationDestinationPreviewWorkerDestination(TypedDict, total= """ -class BrowserVNCApplicationDestinationAllWorkersDestinationOverride(TypedDict, total=False): - behavior: Required[Literal["public"]] - """The behavior to apply to matching requests.""" - - path_pattern: Required[str] - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class BrowserVNCApplicationDestinationAllWorkersDestination(TypedDict, total=False): """ Protects all Cloudflare Workers on the account with Access, including their preview deployments. At most one destination of this type can exist per account. The `worker`, `preview_worker`, `all_preview_workers`, and `public` destination types take precedence, so you can create separate applications to override the policies for specific Workers, their previews, or specific paths. @@ -2303,7 +2298,7 @@ class BrowserVNCApplicationDestinationAllWorkersDestination(TypedDict, total=Fal type: Required[Literal["all_workers"]] - overrides: Iterable[BrowserVNCApplicationDestinationAllWorkersDestinationOverride] + overrides: Iterable[DestinationOverrideParam] """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -2311,19 +2306,6 @@ class BrowserVNCApplicationDestinationAllWorkersDestination(TypedDict, total=Fal """ -class BrowserVNCApplicationDestinationAllPreviewWorkersDestinationOverride(TypedDict, total=False): - behavior: Required[Literal["public"]] - """The behavior to apply to matching requests.""" - - path_pattern: Required[str] - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class BrowserVNCApplicationDestinationAllPreviewWorkersDestination(TypedDict, total=False): """ Protects the preview deployments of all Cloudflare Workers on the account with Access. At most one destination of this type can exist per account. The `worker`, `preview_worker`, and `public` destination types take precedence, so you can create separate applications to override the policies for specific Workers, their previews, or specific paths. @@ -2331,7 +2313,7 @@ class BrowserVNCApplicationDestinationAllPreviewWorkersDestination(TypedDict, to type: Required[Literal["all_preview_workers"]] - overrides: Iterable[BrowserVNCApplicationDestinationAllPreviewWorkersDestinationOverride] + overrides: Iterable[DestinationOverrideParam] """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -2644,6 +2626,7 @@ class AppLauncherApplication(TypedDict, total=False): type: Required[ Literal[ "self_hosted", + "end_user", "saas", "ssh", "vnc", @@ -2723,7 +2706,7 @@ class AppLauncherApplication(TypedDict, total=False): """The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), - ms, s, m, h. Note: unsupported for infrastructure type applications. + ms, s, m, h. """ skip_app_launcher_login_page: bool @@ -2921,7 +2904,7 @@ class DeviceEnrollmentPermissionsApplication(TypedDict, total=False): """The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), - ms, s, m, h. Note: unsupported for infrastructure type applications. + ms, s, m, h. """ @@ -3091,7 +3074,7 @@ class BrowserIsolationPermissionsApplication(TypedDict, total=False): """The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), - ms, s, m, h. Note: unsupported for infrastructure type applications. + ms, s, m, h. """ @@ -3270,7 +3253,7 @@ class GatewayIdentityProxyEndpointApplication(TypedDict, total=False): """The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), - ms, s, m, h. Note: unsupported for infrastructure type applications. + ms, s, m, h. """ @@ -3563,6 +3546,13 @@ class InfrastructureApplication(TypedDict, total=False): policies: Iterable[InfrastructureApplicationPolicy] """The policies that Access applies to the application.""" + session_duration: str + """The maximum duration of a connection to this application's targets. + + Connections are terminated once it elapses. Must be in the format `30m` or + `2h45m`, in whole seconds. Valid time units are: s, m, h. + """ + class InfrastructureApplicationTargetCriterionExcludeTargetAttributes(TypedDict, total=False): """Hostname selector map for include, require, or exclude rules. @@ -3771,6 +3761,13 @@ class InfrastructureApplicationPolicy(TypedDict, total=False): applications. """ + policy_resolution_account_id: str + """ + The account ID used to resolve policy resources and identity for cross-account + WARP authentication. The account must be trusted by the account that owns this + policy. + """ + require: Iterable[AccessRuleParam] """Rules evaluated with an AND logical operator. @@ -3951,7 +3948,7 @@ class BrowserRDPApplication(TypedDict, total=False): """The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), - ms, s, m, h. Note: unsupported for infrastructure type applications. + ms, s, m, h. """ skip_interstitial: bool @@ -4069,26 +4066,13 @@ class BrowserRDPApplicationTargetCriterion(TypedDict, total=False): """Contains a map of target attribute keys to target attribute values.""" -class BrowserRDPApplicationDestinationPublicDestinationOverride(TypedDict, total=False): - behavior: Required[Literal["public"]] - """The behavior to apply to matching requests.""" - - path_pattern: Required[str] - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class BrowserRDPApplicationDestinationPublicDestination(TypedDict, total=False): """A public hostname that Access will secure. Public destinations support sub-domain and path. Wildcard '*' can be used in the definition. """ - overrides: Iterable[BrowserRDPApplicationDestinationPublicDestinationOverride] + overrides: Iterable[DestinationOverrideParam] """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -4142,19 +4126,6 @@ class BrowserRDPApplicationDestinationViaMcpServerPortalDestination(TypedDict, t type: Literal["via_mcp_server_portal"] -class BrowserRDPApplicationDestinationWorkerDestinationOverride(TypedDict, total=False): - behavior: Required[Literal["public"]] - """The behavior to apply to matching requests.""" - - path_pattern: Required[str] - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class BrowserRDPApplicationDestinationWorkerDestination(TypedDict, total=False): """A specific Cloudflare Worker that Access will secure. @@ -4166,7 +4137,7 @@ class BrowserRDPApplicationDestinationWorkerDestination(TypedDict, total=False): worker_id: Required[str] """The ID of the Cloudflare Worker to protect with Access.""" - overrides: Iterable[BrowserRDPApplicationDestinationWorkerDestinationOverride] + overrides: Iterable[DestinationOverrideParam] """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -4174,19 +4145,6 @@ class BrowserRDPApplicationDestinationWorkerDestination(TypedDict, total=False): """ -class BrowserRDPApplicationDestinationPreviewWorkerDestinationOverride(TypedDict, total=False): - behavior: Required[Literal["public"]] - """The behavior to apply to matching requests.""" - - path_pattern: Required[str] - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class BrowserRDPApplicationDestinationPreviewWorkerDestination(TypedDict, total=False): """A specific Cloudflare Worker whose preview deployments Access will secure. @@ -4201,7 +4159,7 @@ class BrowserRDPApplicationDestinationPreviewWorkerDestination(TypedDict, total= Access. """ - overrides: Iterable[BrowserRDPApplicationDestinationPreviewWorkerDestinationOverride] + overrides: Iterable[DestinationOverrideParam] """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -4209,19 +4167,6 @@ class BrowserRDPApplicationDestinationPreviewWorkerDestination(TypedDict, total= """ -class BrowserRDPApplicationDestinationAllWorkersDestinationOverride(TypedDict, total=False): - behavior: Required[Literal["public"]] - """The behavior to apply to matching requests.""" - - path_pattern: Required[str] - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class BrowserRDPApplicationDestinationAllWorkersDestination(TypedDict, total=False): """ Protects all Cloudflare Workers on the account with Access, including their preview deployments. At most one destination of this type can exist per account. The `worker`, `preview_worker`, `all_preview_workers`, and `public` destination types take precedence, so you can create separate applications to override the policies for specific Workers, their previews, or specific paths. @@ -4229,7 +4174,7 @@ class BrowserRDPApplicationDestinationAllWorkersDestination(TypedDict, total=Fal type: Required[Literal["all_workers"]] - overrides: Iterable[BrowserRDPApplicationDestinationAllWorkersDestinationOverride] + overrides: Iterable[DestinationOverrideParam] """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -4237,19 +4182,6 @@ class BrowserRDPApplicationDestinationAllWorkersDestination(TypedDict, total=Fal """ -class BrowserRDPApplicationDestinationAllPreviewWorkersDestinationOverride(TypedDict, total=False): - behavior: Required[Literal["public"]] - """The behavior to apply to matching requests.""" - - path_pattern: Required[str] - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class BrowserRDPApplicationDestinationAllPreviewWorkersDestination(TypedDict, total=False): """ Protects the preview deployments of all Cloudflare Workers on the account with Access. At most one destination of this type can exist per account. The `worker`, `preview_worker`, and `public` destination types take precedence, so you can create separate applications to override the policies for specific Workers, their previews, or specific paths. @@ -4257,7 +4189,7 @@ class BrowserRDPApplicationDestinationAllPreviewWorkersDestination(TypedDict, to type: Required[Literal["all_preview_workers"]] - overrides: Iterable[BrowserRDPApplicationDestinationAllPreviewWorkersDestinationOverride] + overrides: Iterable[DestinationOverrideParam] """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -4678,7 +4610,7 @@ class McpServerApplication(TypedDict, total=False): """The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), - ms, s, m, h. Note: unsupported for infrastructure type applications. + ms, s, m, h. """ tags: SequenceNotStr[str] @@ -4688,26 +4620,13 @@ class McpServerApplication(TypedDict, total=False): """ -class McpServerApplicationDestinationPublicDestinationOverride(TypedDict, total=False): - behavior: Required[Literal["public"]] - """The behavior to apply to matching requests.""" - - path_pattern: Required[str] - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class McpServerApplicationDestinationPublicDestination(TypedDict, total=False): """A public hostname that Access will secure. Public destinations support sub-domain and path. Wildcard '*' can be used in the definition. """ - overrides: Iterable[McpServerApplicationDestinationPublicDestinationOverride] + overrides: Iterable[DestinationOverrideParam] """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -4761,19 +4680,6 @@ class McpServerApplicationDestinationViaMcpServerPortalDestination(TypedDict, to type: Literal["via_mcp_server_portal"] -class McpServerApplicationDestinationWorkerDestinationOverride(TypedDict, total=False): - behavior: Required[Literal["public"]] - """The behavior to apply to matching requests.""" - - path_pattern: Required[str] - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class McpServerApplicationDestinationWorkerDestination(TypedDict, total=False): """A specific Cloudflare Worker that Access will secure. @@ -4785,7 +4691,7 @@ class McpServerApplicationDestinationWorkerDestination(TypedDict, total=False): worker_id: Required[str] """The ID of the Cloudflare Worker to protect with Access.""" - overrides: Iterable[McpServerApplicationDestinationWorkerDestinationOverride] + overrides: Iterable[DestinationOverrideParam] """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -4793,19 +4699,6 @@ class McpServerApplicationDestinationWorkerDestination(TypedDict, total=False): """ -class McpServerApplicationDestinationPreviewWorkerDestinationOverride(TypedDict, total=False): - behavior: Required[Literal["public"]] - """The behavior to apply to matching requests.""" - - path_pattern: Required[str] - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class McpServerApplicationDestinationPreviewWorkerDestination(TypedDict, total=False): """A specific Cloudflare Worker whose preview deployments Access will secure. @@ -4820,7 +4713,7 @@ class McpServerApplicationDestinationPreviewWorkerDestination(TypedDict, total=F Access. """ - overrides: Iterable[McpServerApplicationDestinationPreviewWorkerDestinationOverride] + overrides: Iterable[DestinationOverrideParam] """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -4828,19 +4721,6 @@ class McpServerApplicationDestinationPreviewWorkerDestination(TypedDict, total=F """ -class McpServerApplicationDestinationAllWorkersDestinationOverride(TypedDict, total=False): - behavior: Required[Literal["public"]] - """The behavior to apply to matching requests.""" - - path_pattern: Required[str] - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class McpServerApplicationDestinationAllWorkersDestination(TypedDict, total=False): """ Protects all Cloudflare Workers on the account with Access, including their preview deployments. At most one destination of this type can exist per account. The `worker`, `preview_worker`, `all_preview_workers`, and `public` destination types take precedence, so you can create separate applications to override the policies for specific Workers, their previews, or specific paths. @@ -4848,7 +4728,7 @@ class McpServerApplicationDestinationAllWorkersDestination(TypedDict, total=Fals type: Required[Literal["all_workers"]] - overrides: Iterable[McpServerApplicationDestinationAllWorkersDestinationOverride] + overrides: Iterable[DestinationOverrideParam] """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -4856,19 +4736,6 @@ class McpServerApplicationDestinationAllWorkersDestination(TypedDict, total=Fals """ -class McpServerApplicationDestinationAllPreviewWorkersDestinationOverride(TypedDict, total=False): - behavior: Required[Literal["public"]] - """The behavior to apply to matching requests.""" - - path_pattern: Required[str] - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class McpServerApplicationDestinationAllPreviewWorkersDestination(TypedDict, total=False): """ Protects the preview deployments of all Cloudflare Workers on the account with Access. At most one destination of this type can exist per account. The `worker`, `preview_worker`, and `public` destination types take precedence, so you can create separate applications to override the policies for specific Workers, their previews, or specific paths. @@ -4876,7 +4743,7 @@ class McpServerApplicationDestinationAllPreviewWorkersDestination(TypedDict, tot type: Required[Literal["all_preview_workers"]] - overrides: Iterable[McpServerApplicationDestinationAllPreviewWorkersDestinationOverride] + overrides: Iterable[DestinationOverrideParam] """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -5283,7 +5150,7 @@ class McpServerPortalApplication(TypedDict, total=False): """The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), - ms, s, m, h. Note: unsupported for infrastructure type applications. + ms, s, m, h. """ tags: SequenceNotStr[str] @@ -5293,26 +5160,13 @@ class McpServerPortalApplication(TypedDict, total=False): """ -class McpServerPortalApplicationDestinationPublicDestinationOverride(TypedDict, total=False): - behavior: Required[Literal["public"]] - """The behavior to apply to matching requests.""" - - path_pattern: Required[str] - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class McpServerPortalApplicationDestinationPublicDestination(TypedDict, total=False): """A public hostname that Access will secure. Public destinations support sub-domain and path. Wildcard '*' can be used in the definition. """ - overrides: Iterable[McpServerPortalApplicationDestinationPublicDestinationOverride] + overrides: Iterable[DestinationOverrideParam] """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -5366,19 +5220,6 @@ class McpServerPortalApplicationDestinationViaMcpServerPortalDestination(TypedDi type: Literal["via_mcp_server_portal"] -class McpServerPortalApplicationDestinationWorkerDestinationOverride(TypedDict, total=False): - behavior: Required[Literal["public"]] - """The behavior to apply to matching requests.""" - - path_pattern: Required[str] - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class McpServerPortalApplicationDestinationWorkerDestination(TypedDict, total=False): """A specific Cloudflare Worker that Access will secure. @@ -5390,7 +5231,7 @@ class McpServerPortalApplicationDestinationWorkerDestination(TypedDict, total=Fa worker_id: Required[str] """The ID of the Cloudflare Worker to protect with Access.""" - overrides: Iterable[McpServerPortalApplicationDestinationWorkerDestinationOverride] + overrides: Iterable[DestinationOverrideParam] """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -5398,19 +5239,6 @@ class McpServerPortalApplicationDestinationWorkerDestination(TypedDict, total=Fa """ -class McpServerPortalApplicationDestinationPreviewWorkerDestinationOverride(TypedDict, total=False): - behavior: Required[Literal["public"]] - """The behavior to apply to matching requests.""" - - path_pattern: Required[str] - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class McpServerPortalApplicationDestinationPreviewWorkerDestination(TypedDict, total=False): """A specific Cloudflare Worker whose preview deployments Access will secure. @@ -5425,7 +5253,7 @@ class McpServerPortalApplicationDestinationPreviewWorkerDestination(TypedDict, t Access. """ - overrides: Iterable[McpServerPortalApplicationDestinationPreviewWorkerDestinationOverride] + overrides: Iterable[DestinationOverrideParam] """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -5433,19 +5261,6 @@ class McpServerPortalApplicationDestinationPreviewWorkerDestination(TypedDict, t """ -class McpServerPortalApplicationDestinationAllWorkersDestinationOverride(TypedDict, total=False): - behavior: Required[Literal["public"]] - """The behavior to apply to matching requests.""" - - path_pattern: Required[str] - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class McpServerPortalApplicationDestinationAllWorkersDestination(TypedDict, total=False): """ Protects all Cloudflare Workers on the account with Access, including their preview deployments. At most one destination of this type can exist per account. The `worker`, `preview_worker`, `all_preview_workers`, and `public` destination types take precedence, so you can create separate applications to override the policies for specific Workers, their previews, or specific paths. @@ -5453,7 +5268,7 @@ class McpServerPortalApplicationDestinationAllWorkersDestination(TypedDict, tota type: Required[Literal["all_workers"]] - overrides: Iterable[McpServerPortalApplicationDestinationAllWorkersDestinationOverride] + overrides: Iterable[DestinationOverrideParam] """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -5461,19 +5276,6 @@ class McpServerPortalApplicationDestinationAllWorkersDestination(TypedDict, tota """ -class McpServerPortalApplicationDestinationAllPreviewWorkersDestinationOverride(TypedDict, total=False): - behavior: Required[Literal["public"]] - """The behavior to apply to matching requests.""" - - path_pattern: Required[str] - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class McpServerPortalApplicationDestinationAllPreviewWorkersDestination(TypedDict, total=False): """ Protects the preview deployments of all Cloudflare Workers on the account with Access. At most one destination of this type can exist per account. The `worker`, `preview_worker`, and `public` destination types take precedence, so you can create separate applications to override the policies for specific Workers, their previews, or specific paths. @@ -5481,7 +5283,7 @@ class McpServerPortalApplicationDestinationAllPreviewWorkersDestination(TypedDic type: Required[Literal["all_preview_workers"]] - overrides: Iterable[McpServerPortalApplicationDestinationAllPreviewWorkersDestinationOverride] + overrides: Iterable[DestinationOverrideParam] """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -5771,6 +5573,7 @@ class McpServerPortalApplicationSCIMConfig(TypedDict, total=False): ApplicationCreateParams: TypeAlias = Union[ + AccessEndUserProps, SelfHostedApplication, SaaSApplication, BrowserSSHApplication, diff --git a/src/cloudflare/types/zero_trust/access/application_create_response.py b/src/cloudflare/types/zero_trust/access/application_create_response.py index 6a9602dae46..dfe2d280d10 100644 --- a/src/cloudflare/types/zero_trust/access/application_create_response.py +++ b/src/cloudflare/types/zero_trust/access/application_create_response.py @@ -14,6 +14,7 @@ from .application_type import ApplicationType from .scim_config_mapping import SCIMConfigMapping from .self_hosted_domains import SelfHostedDomains +from .destination_override import DestinationOverride from .applications.access_rule import AccessRule from .scim_config_authentication_oauth2 import SCIMConfigAuthenticationOauth2 from .scim_config_authentication_http_basic import SCIMConfigAuthenticationHTTPBasic @@ -21,20 +22,25 @@ __all__ = [ "ApplicationCreateResponse", + "EndUserApplication", + "EndUserApplicationOAuthConfiguration", + "EndUserApplicationOAuthConfigurationDynamicClientRegistration", + "EndUserApplicationOAuthConfigurationGrant", + "EndUserApplicationDestination", + "EndUserApplicationDestinationAccessEndUserPublicDestination", + "EndUserApplicationDestinationAccessEndUserWorkerDestination", + "EndUserApplicationDestinationAccessEndUserPreviewWorkerDestination", + "EndUserApplicationDestinationAccessEndUserAllWorkersDestination", + "EndUserApplicationDestinationAccessEndUserAllPreviewWorkersDestination", "SelfHostedApplication", "SelfHostedApplicationDestination", "SelfHostedApplicationDestinationPublicDestination", - "SelfHostedApplicationDestinationPublicDestinationOverride", "SelfHostedApplicationDestinationPrivateDestination", "SelfHostedApplicationDestinationViaMcpServerPortalDestination", "SelfHostedApplicationDestinationWorkerDestination", - "SelfHostedApplicationDestinationWorkerDestinationOverride", "SelfHostedApplicationDestinationPreviewWorkerDestination", - "SelfHostedApplicationDestinationPreviewWorkerDestinationOverride", "SelfHostedApplicationDestinationAllWorkersDestination", - "SelfHostedApplicationDestinationAllWorkersDestinationOverride", "SelfHostedApplicationDestinationAllPreviewWorkersDestination", - "SelfHostedApplicationDestinationAllPreviewWorkersDestinationOverride", "SelfHostedApplicationMfaConfig", "SelfHostedApplicationOAuthConfiguration", "SelfHostedApplicationOAuthConfigurationDynamicClientRegistration", @@ -62,17 +68,12 @@ "BrowserSSHApplication", "BrowserSSHApplicationDestination", "BrowserSSHApplicationDestinationPublicDestination", - "BrowserSSHApplicationDestinationPublicDestinationOverride", "BrowserSSHApplicationDestinationPrivateDestination", "BrowserSSHApplicationDestinationViaMcpServerPortalDestination", "BrowserSSHApplicationDestinationWorkerDestination", - "BrowserSSHApplicationDestinationWorkerDestinationOverride", "BrowserSSHApplicationDestinationPreviewWorkerDestination", - "BrowserSSHApplicationDestinationPreviewWorkerDestinationOverride", "BrowserSSHApplicationDestinationAllWorkersDestination", - "BrowserSSHApplicationDestinationAllWorkersDestinationOverride", "BrowserSSHApplicationDestinationAllPreviewWorkersDestination", - "BrowserSSHApplicationDestinationAllPreviewWorkersDestinationOverride", "BrowserSSHApplicationMfaConfig", "BrowserSSHApplicationOAuthConfiguration", "BrowserSSHApplicationOAuthConfigurationDynamicClientRegistration", @@ -89,17 +90,12 @@ "BrowserVNCApplication", "BrowserVNCApplicationDestination", "BrowserVNCApplicationDestinationPublicDestination", - "BrowserVNCApplicationDestinationPublicDestinationOverride", "BrowserVNCApplicationDestinationPrivateDestination", "BrowserVNCApplicationDestinationViaMcpServerPortalDestination", "BrowserVNCApplicationDestinationWorkerDestination", - "BrowserVNCApplicationDestinationWorkerDestinationOverride", "BrowserVNCApplicationDestinationPreviewWorkerDestination", - "BrowserVNCApplicationDestinationPreviewWorkerDestinationOverride", "BrowserVNCApplicationDestinationAllWorkersDestination", - "BrowserVNCApplicationDestinationAllWorkersDestinationOverride", "BrowserVNCApplicationDestinationAllPreviewWorkersDestination", - "BrowserVNCApplicationDestinationAllPreviewWorkersDestinationOverride", "BrowserVNCApplicationMfaConfig", "BrowserVNCApplicationOAuthConfiguration", "BrowserVNCApplicationOAuthConfigurationDynamicClientRegistration", @@ -163,17 +159,12 @@ "BrowserRDPApplicationTargetCriterionRequireTargetAttributes", "BrowserRDPApplicationDestination", "BrowserRDPApplicationDestinationPublicDestination", - "BrowserRDPApplicationDestinationPublicDestinationOverride", "BrowserRDPApplicationDestinationPrivateDestination", "BrowserRDPApplicationDestinationViaMcpServerPortalDestination", "BrowserRDPApplicationDestinationWorkerDestination", - "BrowserRDPApplicationDestinationWorkerDestinationOverride", "BrowserRDPApplicationDestinationPreviewWorkerDestination", - "BrowserRDPApplicationDestinationPreviewWorkerDestinationOverride", "BrowserRDPApplicationDestinationAllWorkersDestination", - "BrowserRDPApplicationDestinationAllWorkersDestinationOverride", "BrowserRDPApplicationDestinationAllPreviewWorkersDestination", - "BrowserRDPApplicationDestinationAllPreviewWorkersDestinationOverride", "BrowserRDPApplicationMfaConfig", "BrowserRDPApplicationOAuthConfiguration", "BrowserRDPApplicationOAuthConfigurationDynamicClientRegistration", @@ -190,17 +181,12 @@ "McpServerApplication", "McpServerApplicationDestination", "McpServerApplicationDestinationPublicDestination", - "McpServerApplicationDestinationPublicDestinationOverride", "McpServerApplicationDestinationPrivateDestination", "McpServerApplicationDestinationViaMcpServerPortalDestination", "McpServerApplicationDestinationWorkerDestination", - "McpServerApplicationDestinationWorkerDestinationOverride", "McpServerApplicationDestinationPreviewWorkerDestination", - "McpServerApplicationDestinationPreviewWorkerDestinationOverride", "McpServerApplicationDestinationAllWorkersDestination", - "McpServerApplicationDestinationAllWorkersDestinationOverride", "McpServerApplicationDestinationAllPreviewWorkersDestination", - "McpServerApplicationDestinationAllPreviewWorkersDestinationOverride", "McpServerApplicationOAuthConfiguration", "McpServerApplicationOAuthConfigurationDynamicClientRegistration", "McpServerApplicationOAuthConfigurationGrant", @@ -216,17 +202,12 @@ "McpServerPortalApplication", "McpServerPortalApplicationDestination", "McpServerPortalApplicationDestinationPublicDestination", - "McpServerPortalApplicationDestinationPublicDestinationOverride", "McpServerPortalApplicationDestinationPrivateDestination", "McpServerPortalApplicationDestinationViaMcpServerPortalDestination", "McpServerPortalApplicationDestinationWorkerDestination", - "McpServerPortalApplicationDestinationWorkerDestinationOverride", "McpServerPortalApplicationDestinationPreviewWorkerDestination", - "McpServerPortalApplicationDestinationPreviewWorkerDestinationOverride", "McpServerPortalApplicationDestinationAllWorkersDestination", - "McpServerPortalApplicationDestinationAllWorkersDestinationOverride", "McpServerPortalApplicationDestinationAllPreviewWorkersDestination", - "McpServerPortalApplicationDestinationAllPreviewWorkersDestinationOverride", "McpServerPortalApplicationOAuthConfiguration", "McpServerPortalApplicationOAuthConfigurationDynamicClientRegistration", "McpServerPortalApplicationOAuthConfigurationGrant", @@ -242,16 +223,195 @@ ] -class SelfHostedApplicationDestinationPublicDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" +class EndUserApplicationOAuthConfigurationDynamicClientRegistration(BaseModel): + """Settings for OAuth dynamic client registration.""" + + allow_any_on_localhost: Optional[bool] = None + """Allows any client with redirect URIs on localhost.""" + + allow_any_on_loopback: Optional[bool] = None + """Allows any client with redirect URIs on 127.0.0.1.""" + + allowed_uris: Optional[List[str]] = None + """The URIs that are allowed as redirect URIs for dynamically registered clients. + + HTTP and HTTPS paths may end in `/*` to match all sub-paths. Custom-scheme URIs + must be explicitly configured and match exactly. + """ + + enabled: Optional[bool] = None + """Whether dynamic client registration is enabled.""" + + +class EndUserApplicationOAuthConfigurationGrant(BaseModel): + """Settings for OAuth grant behavior.""" + + access_token_lifetime: Optional[str] = None + """The lifetime of the access token. + + Must be in the format `300ms` or `2h45m`. Valid time units are ns, us (or µs), + ms, s, m, h. + """ + + session_duration: Optional[str] = None + """The duration of the OAuth session. + + Must be in the format `300ms` or `2h45m`. Valid time units are ns, us (or µs), + ms, s, m, h. + """ + + +class EndUserApplicationOAuthConfiguration(BaseModel): + """ + **Beta:** Optional configuration for managing an OAuth authorization flow controlled by Access. When set, Access will act as the OAuth authorization server for this application. Only compatible with OAuth clients that support [RFC 8707](https://datatracker.ietf.org/doc/html/rfc8707) (Resource Indicators for OAuth 2.0). This feature is currently in beta. + """ + + dynamic_client_registration: Optional[EndUserApplicationOAuthConfigurationDynamicClientRegistration] = None + """Settings for OAuth dynamic client registration.""" + + enabled: Optional[Literal[True]] = None + """Managed OAuth is required for end user applications and cannot be disabled.""" + + grant: Optional[EndUserApplicationOAuthConfigurationGrant] = None + """Settings for OAuth grant behavior.""" + + +class EndUserApplicationDestinationAccessEndUserPublicDestination(BaseModel): + uri: str + """The public hostname and optional path to secure.""" + + overrides: Optional[List[DestinationOverride]] = None + """Rules that override how Access handles requests to this destination. + + Each rule can make a matching path public, bypassing Access authentication. + Overrides are supported for public destinations and Worker destinations. + """ + + type: Optional[Literal["public"]] = None + + +class EndUserApplicationDestinationAccessEndUserWorkerDestination(BaseModel): + type: Literal["worker"] + + worker_id: str + """The ID of the Cloudflare Worker to secure.""" + + overrides: Optional[List[DestinationOverride]] = None + """Rules that override how Access handles requests to this destination. + + Each rule can make a matching path public, bypassing Access authentication. + Overrides are supported for public destinations and Worker destinations. + """ + + +class EndUserApplicationDestinationAccessEndUserPreviewWorkerDestination(BaseModel): + type: Literal["preview_worker"] + + worker_id: str + """The ID of the Cloudflare Worker whose previews to secure.""" + + overrides: Optional[List[DestinationOverride]] = None + """Rules that override how Access handles requests to this destination. + + Each rule can make a matching path public, bypassing Access authentication. + Overrides are supported for public destinations and Worker destinations. + """ + + +class EndUserApplicationDestinationAccessEndUserAllWorkersDestination(BaseModel): + type: Literal["all_workers"] + + overrides: Optional[List[DestinationOverride]] = None + """Rules that override how Access handles requests to this destination. + + Each rule can make a matching path public, bypassing Access authentication. + Overrides are supported for public destinations and Worker destinations. + """ + + +class EndUserApplicationDestinationAccessEndUserAllPreviewWorkersDestination(BaseModel): + type: Literal["all_preview_workers"] - path_pattern: str - """The request path pattern to match. + overrides: Optional[List[DestinationOverride]] = None + """Rules that override how Access handles requests to this destination. + + Each rule can make a matching path public, bypassing Access authentication. + Overrides are supported for public destinations and Worker destinations. + """ + + +EndUserApplicationDestination: TypeAlias = Union[ + EndUserApplicationDestinationAccessEndUserPublicDestination, + EndUserApplicationDestinationAccessEndUserWorkerDestination, + EndUserApplicationDestinationAccessEndUserPreviewWorkerDestination, + EndUserApplicationDestinationAccessEndUserAllWorkersDestination, + EndUserApplicationDestinationAccessEndUserAllPreviewWorkersDestination, +] + + +class EndUserApplication(BaseModel): + oauth_configuration: EndUserApplicationOAuthConfiguration + """ + **Beta:** Optional configuration for managing an OAuth authorization flow + controlled by Access. When set, Access will act as the OAuth authorization + server for this application. Only compatible with OAuth clients that support + [RFC 8707](https://datatracker.ietf.org/doc/html/rfc8707) (Resource Indicators + for OAuth 2.0). This feature is currently in beta. + """ + + type: Literal[ + "self_hosted", + "end_user", + "saas", + "ssh", + "vnc", + "app_launcher", + "warp", + "biso", + "bookmark", + "dash_sso", + "infrastructure", + "rdp", + "mcp", + "mcp_portal", + "proxy_endpoint", + ] + """The application type.""" + + user_populations: List[str] + """The single user population associated with this application.""" + + id: Optional[str] = None + """UUID.""" + + allowed_idps: Optional[List[AllowedIdPs]] = None + """The identity providers your users can select when connecting to this + application. + + Defaults to all IdPs configured in your account. + """ + + aud: Optional[str] = None + """Audience tag.""" + + destinations: Optional[List[EndUserApplicationDestination]] = None + """Public hostname and Workers destinations secured by Access.""" + + domain: Optional[str] = None + """The primary hostname and path secured by Access. + + This domain will be displayed if the app is visible in the App Launcher. + """ + + name: Optional[str] = None + """The name of the application.""" - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. + self_hosted_domains: Optional[List[SelfHostedDomains]] = None + """List of public domains that Access will secure. + + This field is deprecated in favor of `destinations` and will be supported until + **November 21, 2025.** If `destinations` are provided, then + `self_hosted_domains` will be ignored. """ @@ -261,7 +421,7 @@ class SelfHostedApplicationDestinationPublicDestination(BaseModel): Public destinations support sub-domain and path. Wildcard '*' can be used in the definition. """ - overrides: Optional[List[SelfHostedApplicationDestinationPublicDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -315,19 +475,6 @@ class SelfHostedApplicationDestinationViaMcpServerPortalDestination(BaseModel): type: Optional[Literal["via_mcp_server_portal"]] = None -class SelfHostedApplicationDestinationWorkerDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class SelfHostedApplicationDestinationWorkerDestination(BaseModel): """A specific Cloudflare Worker that Access will secure. @@ -339,7 +486,7 @@ class SelfHostedApplicationDestinationWorkerDestination(BaseModel): worker_id: str """The ID of the Cloudflare Worker to protect with Access.""" - overrides: Optional[List[SelfHostedApplicationDestinationWorkerDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -347,19 +494,6 @@ class SelfHostedApplicationDestinationWorkerDestination(BaseModel): """ -class SelfHostedApplicationDestinationPreviewWorkerDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class SelfHostedApplicationDestinationPreviewWorkerDestination(BaseModel): """A specific Cloudflare Worker whose preview deployments Access will secure. @@ -374,7 +508,7 @@ class SelfHostedApplicationDestinationPreviewWorkerDestination(BaseModel): Access. """ - overrides: Optional[List[SelfHostedApplicationDestinationPreviewWorkerDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -382,19 +516,6 @@ class SelfHostedApplicationDestinationPreviewWorkerDestination(BaseModel): """ -class SelfHostedApplicationDestinationAllWorkersDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class SelfHostedApplicationDestinationAllWorkersDestination(BaseModel): """ Protects all Cloudflare Workers on the account with Access, including their preview deployments. At most one destination of this type can exist per account. The `worker`, `preview_worker`, `all_preview_workers`, and `public` destination types take precedence, so you can create separate applications to override the policies for specific Workers, their previews, or specific paths. @@ -402,7 +523,7 @@ class SelfHostedApplicationDestinationAllWorkersDestination(BaseModel): type: Literal["all_workers"] - overrides: Optional[List[SelfHostedApplicationDestinationAllWorkersDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -410,19 +531,6 @@ class SelfHostedApplicationDestinationAllWorkersDestination(BaseModel): """ -class SelfHostedApplicationDestinationAllPreviewWorkersDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class SelfHostedApplicationDestinationAllPreviewWorkersDestination(BaseModel): """ Protects the preview deployments of all Cloudflare Workers on the account with Access. At most one destination of this type can exist per account. The `worker`, `preview_worker`, and `public` destination types take precedence, so you can create separate applications to override the policies for specific Workers, their previews, or specific paths. @@ -430,7 +538,7 @@ class SelfHostedApplicationDestinationAllPreviewWorkersDestination(BaseModel): type: Literal["all_preview_workers"] - overrides: Optional[List[SelfHostedApplicationDestinationAllPreviewWorkersDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -624,6 +732,13 @@ class SelfHostedApplicationPolicy(BaseModel): name: Optional[str] = None """The name of the Access policy.""" + policy_resolution_account_id: Optional[str] = None + """ + The account ID used to resolve policy resources and identity for cross-account + WARP authentication. The account must be trusted by the account that owns this + policy. + """ + precedence: Optional[int] = None """The order of execution for this policy. @@ -915,7 +1030,7 @@ class SelfHostedApplication(BaseModel): """The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), - ms, s, m, h. Note: unsupported for infrastructure type applications. + ms, s, m, h. """ skip_interstitial: Optional[bool] = None @@ -1034,6 +1149,13 @@ class SaaSApplicationPolicy(BaseModel): name: Optional[str] = None """The name of the Access policy.""" + policy_resolution_account_id: Optional[str] = None + """ + The account ID used to resolve policy resources and identity for cross-account + WARP authentication. The account must be trusted by the account that owns this + policy. + """ + precedence: Optional[int] = None """The order of execution for this policy. @@ -1216,26 +1338,13 @@ class SaaSApplication(BaseModel): """The application type.""" -class BrowserSSHApplicationDestinationPublicDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class BrowserSSHApplicationDestinationPublicDestination(BaseModel): """A public hostname that Access will secure. Public destinations support sub-domain and path. Wildcard '*' can be used in the definition. """ - overrides: Optional[List[BrowserSSHApplicationDestinationPublicDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -1289,19 +1398,6 @@ class BrowserSSHApplicationDestinationViaMcpServerPortalDestination(BaseModel): type: Optional[Literal["via_mcp_server_portal"]] = None -class BrowserSSHApplicationDestinationWorkerDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class BrowserSSHApplicationDestinationWorkerDestination(BaseModel): """A specific Cloudflare Worker that Access will secure. @@ -1313,7 +1409,7 @@ class BrowserSSHApplicationDestinationWorkerDestination(BaseModel): worker_id: str """The ID of the Cloudflare Worker to protect with Access.""" - overrides: Optional[List[BrowserSSHApplicationDestinationWorkerDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -1321,19 +1417,6 @@ class BrowserSSHApplicationDestinationWorkerDestination(BaseModel): """ -class BrowserSSHApplicationDestinationPreviewWorkerDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class BrowserSSHApplicationDestinationPreviewWorkerDestination(BaseModel): """A specific Cloudflare Worker whose preview deployments Access will secure. @@ -1348,7 +1431,7 @@ class BrowserSSHApplicationDestinationPreviewWorkerDestination(BaseModel): Access. """ - overrides: Optional[List[BrowserSSHApplicationDestinationPreviewWorkerDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -1356,19 +1439,6 @@ class BrowserSSHApplicationDestinationPreviewWorkerDestination(BaseModel): """ -class BrowserSSHApplicationDestinationAllWorkersDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class BrowserSSHApplicationDestinationAllWorkersDestination(BaseModel): """ Protects all Cloudflare Workers on the account with Access, including their preview deployments. At most one destination of this type can exist per account. The `worker`, `preview_worker`, `all_preview_workers`, and `public` destination types take precedence, so you can create separate applications to override the policies for specific Workers, their previews, or specific paths. @@ -1376,7 +1446,7 @@ class BrowserSSHApplicationDestinationAllWorkersDestination(BaseModel): type: Literal["all_workers"] - overrides: Optional[List[BrowserSSHApplicationDestinationAllWorkersDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -1384,19 +1454,6 @@ class BrowserSSHApplicationDestinationAllWorkersDestination(BaseModel): """ -class BrowserSSHApplicationDestinationAllPreviewWorkersDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class BrowserSSHApplicationDestinationAllPreviewWorkersDestination(BaseModel): """ Protects the preview deployments of all Cloudflare Workers on the account with Access. At most one destination of this type can exist per account. The `worker`, `preview_worker`, and `public` destination types take precedence, so you can create separate applications to override the policies for specific Workers, their previews, or specific paths. @@ -1404,7 +1461,7 @@ class BrowserSSHApplicationDestinationAllPreviewWorkersDestination(BaseModel): type: Literal["all_preview_workers"] - overrides: Optional[List[BrowserSSHApplicationDestinationAllPreviewWorkersDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -1598,6 +1655,13 @@ class BrowserSSHApplicationPolicy(BaseModel): name: Optional[str] = None """The name of the Access policy.""" + policy_resolution_account_id: Optional[str] = None + """ + The account ID used to resolve policy resources and identity for cross-account + WARP authentication. The account must be trusted by the account that owns this + policy. + """ + precedence: Optional[int] = None """The order of execution for this policy. @@ -1733,6 +1797,7 @@ class BrowserSSHApplication(BaseModel): type: Literal[ "self_hosted", + "end_user", "saas", "ssh", "vnc", @@ -1904,7 +1969,7 @@ class BrowserSSHApplication(BaseModel): """The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), - ms, s, m, h. Note: unsupported for infrastructure type applications. + ms, s, m, h. """ skip_interstitial: Optional[bool] = None @@ -1925,26 +1990,13 @@ class BrowserSSHApplication(BaseModel): """ -class BrowserVNCApplicationDestinationPublicDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class BrowserVNCApplicationDestinationPublicDestination(BaseModel): """A public hostname that Access will secure. Public destinations support sub-domain and path. Wildcard '*' can be used in the definition. """ - overrides: Optional[List[BrowserVNCApplicationDestinationPublicDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -1998,19 +2050,6 @@ class BrowserVNCApplicationDestinationViaMcpServerPortalDestination(BaseModel): type: Optional[Literal["via_mcp_server_portal"]] = None -class BrowserVNCApplicationDestinationWorkerDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class BrowserVNCApplicationDestinationWorkerDestination(BaseModel): """A specific Cloudflare Worker that Access will secure. @@ -2022,7 +2061,7 @@ class BrowserVNCApplicationDestinationWorkerDestination(BaseModel): worker_id: str """The ID of the Cloudflare Worker to protect with Access.""" - overrides: Optional[List[BrowserVNCApplicationDestinationWorkerDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -2030,19 +2069,6 @@ class BrowserVNCApplicationDestinationWorkerDestination(BaseModel): """ -class BrowserVNCApplicationDestinationPreviewWorkerDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class BrowserVNCApplicationDestinationPreviewWorkerDestination(BaseModel): """A specific Cloudflare Worker whose preview deployments Access will secure. @@ -2057,7 +2083,7 @@ class BrowserVNCApplicationDestinationPreviewWorkerDestination(BaseModel): Access. """ - overrides: Optional[List[BrowserVNCApplicationDestinationPreviewWorkerDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -2065,19 +2091,6 @@ class BrowserVNCApplicationDestinationPreviewWorkerDestination(BaseModel): """ -class BrowserVNCApplicationDestinationAllWorkersDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class BrowserVNCApplicationDestinationAllWorkersDestination(BaseModel): """ Protects all Cloudflare Workers on the account with Access, including their preview deployments. At most one destination of this type can exist per account. The `worker`, `preview_worker`, `all_preview_workers`, and `public` destination types take precedence, so you can create separate applications to override the policies for specific Workers, their previews, or specific paths. @@ -2085,7 +2098,7 @@ class BrowserVNCApplicationDestinationAllWorkersDestination(BaseModel): type: Literal["all_workers"] - overrides: Optional[List[BrowserVNCApplicationDestinationAllWorkersDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -2093,19 +2106,6 @@ class BrowserVNCApplicationDestinationAllWorkersDestination(BaseModel): """ -class BrowserVNCApplicationDestinationAllPreviewWorkersDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class BrowserVNCApplicationDestinationAllPreviewWorkersDestination(BaseModel): """ Protects the preview deployments of all Cloudflare Workers on the account with Access. At most one destination of this type can exist per account. The `worker`, `preview_worker`, and `public` destination types take precedence, so you can create separate applications to override the policies for specific Workers, their previews, or specific paths. @@ -2113,7 +2113,7 @@ class BrowserVNCApplicationDestinationAllPreviewWorkersDestination(BaseModel): type: Literal["all_preview_workers"] - overrides: Optional[List[BrowserVNCApplicationDestinationAllPreviewWorkersDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -2307,6 +2307,13 @@ class BrowserVNCApplicationPolicy(BaseModel): name: Optional[str] = None """The name of the Access policy.""" + policy_resolution_account_id: Optional[str] = None + """ + The account ID used to resolve policy resources and identity for cross-account + WARP authentication. The account must be trusted by the account that owns this + policy. + """ + precedence: Optional[int] = None """The order of execution for this policy. @@ -2442,6 +2449,7 @@ class BrowserVNCApplication(BaseModel): type: Literal[ "self_hosted", + "end_user", "saas", "ssh", "vnc", @@ -2613,7 +2621,7 @@ class BrowserVNCApplication(BaseModel): """The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), - ms, s, m, h. Note: unsupported for infrastructure type applications. + ms, s, m, h. """ skip_interstitial: Optional[bool] = None @@ -2759,6 +2767,13 @@ class AppLauncherApplicationPolicy(BaseModel): name: Optional[str] = None """The name of the Access policy.""" + policy_resolution_account_id: Optional[str] = None + """ + The account ID used to resolve policy resources and identity for cross-account + WARP authentication. The account must be trusted by the account that owns this + policy. + """ + precedence: Optional[int] = None """The order of execution for this policy. @@ -2790,6 +2805,7 @@ class AppLauncherApplicationPolicy(BaseModel): class AppLauncherApplication(BaseModel): type: Literal[ "self_hosted", + "end_user", "saas", "ssh", "vnc", @@ -2871,7 +2887,7 @@ class AppLauncherApplication(BaseModel): """The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), - ms, s, m, h. Note: unsupported for infrastructure type applications. + ms, s, m, h. """ skip_app_launcher_login_page: Optional[bool] = None @@ -2976,6 +2992,13 @@ class DeviceEnrollmentPermissionsApplicationPolicy(BaseModel): name: Optional[str] = None """The name of the Access policy.""" + policy_resolution_account_id: Optional[str] = None + """ + The account ID used to resolve policy resources and identity for cross-account + WARP authentication. The account must be trusted by the account that owns this + policy. + """ + precedence: Optional[int] = None """The order of execution for this policy. @@ -3058,7 +3081,7 @@ class DeviceEnrollmentPermissionsApplication(BaseModel): """The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), - ms, s, m, h. Note: unsupported for infrastructure type applications. + ms, s, m, h. """ @@ -3160,6 +3183,13 @@ class BrowserIsolationPermissionsApplicationPolicy(BaseModel): name: Optional[str] = None """The name of the Access policy.""" + policy_resolution_account_id: Optional[str] = None + """ + The account ID used to resolve policy resources and identity for cross-account + WARP authentication. The account must be trusted by the account that owns this + policy. + """ + precedence: Optional[int] = None """The order of execution for this policy. @@ -3242,7 +3272,7 @@ class BrowserIsolationPermissionsApplication(BaseModel): """The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), - ms, s, m, h. Note: unsupported for infrastructure type applications. + ms, s, m, h. """ @@ -3344,6 +3374,13 @@ class GatewayIdentityProxyEndpointApplicationPolicy(BaseModel): name: Optional[str] = None """The name of the Access policy.""" + policy_resolution_account_id: Optional[str] = None + """ + The account ID used to resolve policy resources and identity for cross-account + WARP authentication. The account must be trusted by the account that owns this + policy. + """ + precedence: Optional[int] = None """The order of execution for this policy. @@ -3426,7 +3463,7 @@ class GatewayIdentityProxyEndpointApplication(BaseModel): """The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), - ms, s, m, h. Note: unsupported for infrastructure type applications. + ms, s, m, h. """ @@ -3528,6 +3565,13 @@ class BookmarkApplicationPolicy(BaseModel): name: Optional[str] = None """The name of the Access policy.""" + policy_resolution_account_id: Optional[str] = None + """ + The account ID used to resolve policy resources and identity for cross-account + WARP authentication. The account must be trusted by the account that owns this + policy. + """ + precedence: Optional[int] = None """The order of execution for this policy. @@ -3799,6 +3843,13 @@ class InfrastructureApplicationPolicy(BaseModel): name: Optional[str] = None """The name of the Access policy.""" + policy_resolution_account_id: Optional[str] = None + """ + The account ID used to resolve policy resources and identity for cross-account + WARP authentication. The account must be trusted by the account that owns this + policy. + """ + require: Optional[List[AccessRule]] = None """Rules evaluated with an AND logical operator. @@ -3831,6 +3882,13 @@ class InfrastructureApplication(BaseModel): policies: Optional[List[InfrastructureApplicationPolicy]] = None + session_duration: Optional[str] = None + """The maximum duration of a connection to this application's targets. + + Connections are terminated once it elapses. Must be in the format `30m` or + `2h45m`, in whole seconds. Valid time units are: s, m, h. + """ + class BrowserRDPApplicationTargetCriterionExcludeTargetAttributes(BaseModel): """Hostname selector map for include, require, or exclude rules. @@ -3929,26 +3987,13 @@ class BrowserRDPApplicationTargetCriterion(BaseModel): """Contains a map of target attribute keys to target attribute values.""" -class BrowserRDPApplicationDestinationPublicDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class BrowserRDPApplicationDestinationPublicDestination(BaseModel): """A public hostname that Access will secure. Public destinations support sub-domain and path. Wildcard '*' can be used in the definition. """ - overrides: Optional[List[BrowserRDPApplicationDestinationPublicDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -4002,19 +4047,6 @@ class BrowserRDPApplicationDestinationViaMcpServerPortalDestination(BaseModel): type: Optional[Literal["via_mcp_server_portal"]] = None -class BrowserRDPApplicationDestinationWorkerDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class BrowserRDPApplicationDestinationWorkerDestination(BaseModel): """A specific Cloudflare Worker that Access will secure. @@ -4026,7 +4058,7 @@ class BrowserRDPApplicationDestinationWorkerDestination(BaseModel): worker_id: str """The ID of the Cloudflare Worker to protect with Access.""" - overrides: Optional[List[BrowserRDPApplicationDestinationWorkerDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -4034,19 +4066,6 @@ class BrowserRDPApplicationDestinationWorkerDestination(BaseModel): """ -class BrowserRDPApplicationDestinationPreviewWorkerDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class BrowserRDPApplicationDestinationPreviewWorkerDestination(BaseModel): """A specific Cloudflare Worker whose preview deployments Access will secure. @@ -4061,7 +4080,7 @@ class BrowserRDPApplicationDestinationPreviewWorkerDestination(BaseModel): Access. """ - overrides: Optional[List[BrowserRDPApplicationDestinationPreviewWorkerDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -4069,19 +4088,6 @@ class BrowserRDPApplicationDestinationPreviewWorkerDestination(BaseModel): """ -class BrowserRDPApplicationDestinationAllWorkersDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class BrowserRDPApplicationDestinationAllWorkersDestination(BaseModel): """ Protects all Cloudflare Workers on the account with Access, including their preview deployments. At most one destination of this type can exist per account. The `worker`, `preview_worker`, `all_preview_workers`, and `public` destination types take precedence, so you can create separate applications to override the policies for specific Workers, their previews, or specific paths. @@ -4089,7 +4095,7 @@ class BrowserRDPApplicationDestinationAllWorkersDestination(BaseModel): type: Literal["all_workers"] - overrides: Optional[List[BrowserRDPApplicationDestinationAllWorkersDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -4097,19 +4103,6 @@ class BrowserRDPApplicationDestinationAllWorkersDestination(BaseModel): """ -class BrowserRDPApplicationDestinationAllPreviewWorkersDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class BrowserRDPApplicationDestinationAllPreviewWorkersDestination(BaseModel): """ Protects the preview deployments of all Cloudflare Workers on the account with Access. At most one destination of this type can exist per account. The `worker`, `preview_worker`, and `public` destination types take precedence, so you can create separate applications to override the policies for specific Workers, their previews, or specific paths. @@ -4117,7 +4110,7 @@ class BrowserRDPApplicationDestinationAllPreviewWorkersDestination(BaseModel): type: Literal["all_preview_workers"] - overrides: Optional[List[BrowserRDPApplicationDestinationAllPreviewWorkersDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -4311,6 +4304,13 @@ class BrowserRDPApplicationPolicy(BaseModel): name: Optional[str] = None """The name of the Access policy.""" + policy_resolution_account_id: Optional[str] = None + """ + The account ID used to resolve policy resources and identity for cross-account + WARP authentication. The account must be trusted by the account that owns this + policy. + """ + precedence: Optional[int] = None """The order of execution for this policy. @@ -4604,7 +4604,7 @@ class BrowserRDPApplication(BaseModel): """The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), - ms, s, m, h. Note: unsupported for infrastructure type applications. + ms, s, m, h. """ skip_interstitial: Optional[bool] = None @@ -4625,26 +4625,13 @@ class BrowserRDPApplication(BaseModel): """ -class McpServerApplicationDestinationPublicDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class McpServerApplicationDestinationPublicDestination(BaseModel): """A public hostname that Access will secure. Public destinations support sub-domain and path. Wildcard '*' can be used in the definition. """ - overrides: Optional[List[McpServerApplicationDestinationPublicDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -4698,19 +4685,6 @@ class McpServerApplicationDestinationViaMcpServerPortalDestination(BaseModel): type: Optional[Literal["via_mcp_server_portal"]] = None -class McpServerApplicationDestinationWorkerDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class McpServerApplicationDestinationWorkerDestination(BaseModel): """A specific Cloudflare Worker that Access will secure. @@ -4722,7 +4696,7 @@ class McpServerApplicationDestinationWorkerDestination(BaseModel): worker_id: str """The ID of the Cloudflare Worker to protect with Access.""" - overrides: Optional[List[McpServerApplicationDestinationWorkerDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -4730,19 +4704,6 @@ class McpServerApplicationDestinationWorkerDestination(BaseModel): """ -class McpServerApplicationDestinationPreviewWorkerDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class McpServerApplicationDestinationPreviewWorkerDestination(BaseModel): """A specific Cloudflare Worker whose preview deployments Access will secure. @@ -4757,7 +4718,7 @@ class McpServerApplicationDestinationPreviewWorkerDestination(BaseModel): Access. """ - overrides: Optional[List[McpServerApplicationDestinationPreviewWorkerDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -4765,19 +4726,6 @@ class McpServerApplicationDestinationPreviewWorkerDestination(BaseModel): """ -class McpServerApplicationDestinationAllWorkersDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class McpServerApplicationDestinationAllWorkersDestination(BaseModel): """ Protects all Cloudflare Workers on the account with Access, including their preview deployments. At most one destination of this type can exist per account. The `worker`, `preview_worker`, `all_preview_workers`, and `public` destination types take precedence, so you can create separate applications to override the policies for specific Workers, their previews, or specific paths. @@ -4785,7 +4733,7 @@ class McpServerApplicationDestinationAllWorkersDestination(BaseModel): type: Literal["all_workers"] - overrides: Optional[List[McpServerApplicationDestinationAllWorkersDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -4793,19 +4741,6 @@ class McpServerApplicationDestinationAllWorkersDestination(BaseModel): """ -class McpServerApplicationDestinationAllPreviewWorkersDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class McpServerApplicationDestinationAllPreviewWorkersDestination(BaseModel): """ Protects the preview deployments of all Cloudflare Workers on the account with Access. At most one destination of this type can exist per account. The `worker`, `preview_worker`, and `public` destination types take precedence, so you can create separate applications to override the policies for specific Workers, their previews, or specific paths. @@ -4813,7 +4748,7 @@ class McpServerApplicationDestinationAllPreviewWorkersDestination(BaseModel): type: Literal["all_preview_workers"] - overrides: Optional[List[McpServerApplicationDestinationAllPreviewWorkersDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -4987,6 +4922,13 @@ class McpServerApplicationPolicy(BaseModel): name: Optional[str] = None """The name of the Access policy.""" + policy_resolution_account_id: Optional[str] = None + """ + The account ID used to resolve policy resources and identity for cross-account + WARP authentication. The account must be trusted by the account that owns this + policy. + """ + precedence: Optional[int] = None """The order of execution for this policy. @@ -5219,7 +5161,7 @@ class McpServerApplication(BaseModel): """The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), - ms, s, m, h. Note: unsupported for infrastructure type applications. + ms, s, m, h. """ tags: Optional[List[str]] = None @@ -5229,26 +5171,13 @@ class McpServerApplication(BaseModel): """ -class McpServerPortalApplicationDestinationPublicDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class McpServerPortalApplicationDestinationPublicDestination(BaseModel): """A public hostname that Access will secure. Public destinations support sub-domain and path. Wildcard '*' can be used in the definition. """ - overrides: Optional[List[McpServerPortalApplicationDestinationPublicDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -5302,19 +5231,6 @@ class McpServerPortalApplicationDestinationViaMcpServerPortalDestination(BaseMod type: Optional[Literal["via_mcp_server_portal"]] = None -class McpServerPortalApplicationDestinationWorkerDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class McpServerPortalApplicationDestinationWorkerDestination(BaseModel): """A specific Cloudflare Worker that Access will secure. @@ -5326,7 +5242,7 @@ class McpServerPortalApplicationDestinationWorkerDestination(BaseModel): worker_id: str """The ID of the Cloudflare Worker to protect with Access.""" - overrides: Optional[List[McpServerPortalApplicationDestinationWorkerDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -5334,19 +5250,6 @@ class McpServerPortalApplicationDestinationWorkerDestination(BaseModel): """ -class McpServerPortalApplicationDestinationPreviewWorkerDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class McpServerPortalApplicationDestinationPreviewWorkerDestination(BaseModel): """A specific Cloudflare Worker whose preview deployments Access will secure. @@ -5361,7 +5264,7 @@ class McpServerPortalApplicationDestinationPreviewWorkerDestination(BaseModel): Access. """ - overrides: Optional[List[McpServerPortalApplicationDestinationPreviewWorkerDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -5369,19 +5272,6 @@ class McpServerPortalApplicationDestinationPreviewWorkerDestination(BaseModel): """ -class McpServerPortalApplicationDestinationAllWorkersDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class McpServerPortalApplicationDestinationAllWorkersDestination(BaseModel): """ Protects all Cloudflare Workers on the account with Access, including their preview deployments. At most one destination of this type can exist per account. The `worker`, `preview_worker`, `all_preview_workers`, and `public` destination types take precedence, so you can create separate applications to override the policies for specific Workers, their previews, or specific paths. @@ -5389,7 +5279,7 @@ class McpServerPortalApplicationDestinationAllWorkersDestination(BaseModel): type: Literal["all_workers"] - overrides: Optional[List[McpServerPortalApplicationDestinationAllWorkersDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -5397,19 +5287,6 @@ class McpServerPortalApplicationDestinationAllWorkersDestination(BaseModel): """ -class McpServerPortalApplicationDestinationAllPreviewWorkersDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class McpServerPortalApplicationDestinationAllPreviewWorkersDestination(BaseModel): """ Protects the preview deployments of all Cloudflare Workers on the account with Access. At most one destination of this type can exist per account. The `worker`, `preview_worker`, and `public` destination types take precedence, so you can create separate applications to override the policies for specific Workers, their previews, or specific paths. @@ -5417,7 +5294,7 @@ class McpServerPortalApplicationDestinationAllPreviewWorkersDestination(BaseMode type: Literal["all_preview_workers"] - overrides: Optional[List[McpServerPortalApplicationDestinationAllPreviewWorkersDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -5591,6 +5468,13 @@ class McpServerPortalApplicationPolicy(BaseModel): name: Optional[str] = None """The name of the Access policy.""" + policy_resolution_account_id: Optional[str] = None + """ + The account ID used to resolve policy resources and identity for cross-account + WARP authentication. The account must be trusted by the account that owns this + policy. + """ + precedence: Optional[int] = None """The order of execution for this policy. @@ -5829,7 +5713,7 @@ class McpServerPortalApplication(BaseModel): """The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), - ms, s, m, h. Note: unsupported for infrastructure type applications. + ms, s, m, h. """ tags: Optional[List[str]] = None @@ -5840,6 +5724,7 @@ class McpServerPortalApplication(BaseModel): ApplicationCreateResponse: TypeAlias = Union[ + EndUserApplication, SelfHostedApplication, SaaSApplication, BrowserSSHApplication, diff --git a/src/cloudflare/types/zero_trust/access/application_get_response.py b/src/cloudflare/types/zero_trust/access/application_get_response.py index 2c36743b5b7..25bcdbdc19c 100644 --- a/src/cloudflare/types/zero_trust/access/application_get_response.py +++ b/src/cloudflare/types/zero_trust/access/application_get_response.py @@ -14,6 +14,7 @@ from .application_type import ApplicationType from .scim_config_mapping import SCIMConfigMapping from .self_hosted_domains import SelfHostedDomains +from .destination_override import DestinationOverride from .applications.access_rule import AccessRule from .scim_config_authentication_oauth2 import SCIMConfigAuthenticationOauth2 from .scim_config_authentication_http_basic import SCIMConfigAuthenticationHTTPBasic @@ -21,20 +22,25 @@ __all__ = [ "ApplicationGetResponse", + "EndUserApplication", + "EndUserApplicationOAuthConfiguration", + "EndUserApplicationOAuthConfigurationDynamicClientRegistration", + "EndUserApplicationOAuthConfigurationGrant", + "EndUserApplicationDestination", + "EndUserApplicationDestinationAccessEndUserPublicDestination", + "EndUserApplicationDestinationAccessEndUserWorkerDestination", + "EndUserApplicationDestinationAccessEndUserPreviewWorkerDestination", + "EndUserApplicationDestinationAccessEndUserAllWorkersDestination", + "EndUserApplicationDestinationAccessEndUserAllPreviewWorkersDestination", "SelfHostedApplication", "SelfHostedApplicationDestination", "SelfHostedApplicationDestinationPublicDestination", - "SelfHostedApplicationDestinationPublicDestinationOverride", "SelfHostedApplicationDestinationPrivateDestination", "SelfHostedApplicationDestinationViaMcpServerPortalDestination", "SelfHostedApplicationDestinationWorkerDestination", - "SelfHostedApplicationDestinationWorkerDestinationOverride", "SelfHostedApplicationDestinationPreviewWorkerDestination", - "SelfHostedApplicationDestinationPreviewWorkerDestinationOverride", "SelfHostedApplicationDestinationAllWorkersDestination", - "SelfHostedApplicationDestinationAllWorkersDestinationOverride", "SelfHostedApplicationDestinationAllPreviewWorkersDestination", - "SelfHostedApplicationDestinationAllPreviewWorkersDestinationOverride", "SelfHostedApplicationMfaConfig", "SelfHostedApplicationOAuthConfiguration", "SelfHostedApplicationOAuthConfigurationDynamicClientRegistration", @@ -62,17 +68,12 @@ "BrowserSSHApplication", "BrowserSSHApplicationDestination", "BrowserSSHApplicationDestinationPublicDestination", - "BrowserSSHApplicationDestinationPublicDestinationOverride", "BrowserSSHApplicationDestinationPrivateDestination", "BrowserSSHApplicationDestinationViaMcpServerPortalDestination", "BrowserSSHApplicationDestinationWorkerDestination", - "BrowserSSHApplicationDestinationWorkerDestinationOverride", "BrowserSSHApplicationDestinationPreviewWorkerDestination", - "BrowserSSHApplicationDestinationPreviewWorkerDestinationOverride", "BrowserSSHApplicationDestinationAllWorkersDestination", - "BrowserSSHApplicationDestinationAllWorkersDestinationOverride", "BrowserSSHApplicationDestinationAllPreviewWorkersDestination", - "BrowserSSHApplicationDestinationAllPreviewWorkersDestinationOverride", "BrowserSSHApplicationMfaConfig", "BrowserSSHApplicationOAuthConfiguration", "BrowserSSHApplicationOAuthConfigurationDynamicClientRegistration", @@ -89,17 +90,12 @@ "BrowserVNCApplication", "BrowserVNCApplicationDestination", "BrowserVNCApplicationDestinationPublicDestination", - "BrowserVNCApplicationDestinationPublicDestinationOverride", "BrowserVNCApplicationDestinationPrivateDestination", "BrowserVNCApplicationDestinationViaMcpServerPortalDestination", "BrowserVNCApplicationDestinationWorkerDestination", - "BrowserVNCApplicationDestinationWorkerDestinationOverride", "BrowserVNCApplicationDestinationPreviewWorkerDestination", - "BrowserVNCApplicationDestinationPreviewWorkerDestinationOverride", "BrowserVNCApplicationDestinationAllWorkersDestination", - "BrowserVNCApplicationDestinationAllWorkersDestinationOverride", "BrowserVNCApplicationDestinationAllPreviewWorkersDestination", - "BrowserVNCApplicationDestinationAllPreviewWorkersDestinationOverride", "BrowserVNCApplicationMfaConfig", "BrowserVNCApplicationOAuthConfiguration", "BrowserVNCApplicationOAuthConfigurationDynamicClientRegistration", @@ -163,17 +159,12 @@ "BrowserRDPApplicationTargetCriterionRequireTargetAttributes", "BrowserRDPApplicationDestination", "BrowserRDPApplicationDestinationPublicDestination", - "BrowserRDPApplicationDestinationPublicDestinationOverride", "BrowserRDPApplicationDestinationPrivateDestination", "BrowserRDPApplicationDestinationViaMcpServerPortalDestination", "BrowserRDPApplicationDestinationWorkerDestination", - "BrowserRDPApplicationDestinationWorkerDestinationOverride", "BrowserRDPApplicationDestinationPreviewWorkerDestination", - "BrowserRDPApplicationDestinationPreviewWorkerDestinationOverride", "BrowserRDPApplicationDestinationAllWorkersDestination", - "BrowserRDPApplicationDestinationAllWorkersDestinationOverride", "BrowserRDPApplicationDestinationAllPreviewWorkersDestination", - "BrowserRDPApplicationDestinationAllPreviewWorkersDestinationOverride", "BrowserRDPApplicationMfaConfig", "BrowserRDPApplicationOAuthConfiguration", "BrowserRDPApplicationOAuthConfigurationDynamicClientRegistration", @@ -190,17 +181,12 @@ "McpServerApplication", "McpServerApplicationDestination", "McpServerApplicationDestinationPublicDestination", - "McpServerApplicationDestinationPublicDestinationOverride", "McpServerApplicationDestinationPrivateDestination", "McpServerApplicationDestinationViaMcpServerPortalDestination", "McpServerApplicationDestinationWorkerDestination", - "McpServerApplicationDestinationWorkerDestinationOverride", "McpServerApplicationDestinationPreviewWorkerDestination", - "McpServerApplicationDestinationPreviewWorkerDestinationOverride", "McpServerApplicationDestinationAllWorkersDestination", - "McpServerApplicationDestinationAllWorkersDestinationOverride", "McpServerApplicationDestinationAllPreviewWorkersDestination", - "McpServerApplicationDestinationAllPreviewWorkersDestinationOverride", "McpServerApplicationOAuthConfiguration", "McpServerApplicationOAuthConfigurationDynamicClientRegistration", "McpServerApplicationOAuthConfigurationGrant", @@ -216,17 +202,12 @@ "McpServerPortalApplication", "McpServerPortalApplicationDestination", "McpServerPortalApplicationDestinationPublicDestination", - "McpServerPortalApplicationDestinationPublicDestinationOverride", "McpServerPortalApplicationDestinationPrivateDestination", "McpServerPortalApplicationDestinationViaMcpServerPortalDestination", "McpServerPortalApplicationDestinationWorkerDestination", - "McpServerPortalApplicationDestinationWorkerDestinationOverride", "McpServerPortalApplicationDestinationPreviewWorkerDestination", - "McpServerPortalApplicationDestinationPreviewWorkerDestinationOverride", "McpServerPortalApplicationDestinationAllWorkersDestination", - "McpServerPortalApplicationDestinationAllWorkersDestinationOverride", "McpServerPortalApplicationDestinationAllPreviewWorkersDestination", - "McpServerPortalApplicationDestinationAllPreviewWorkersDestinationOverride", "McpServerPortalApplicationOAuthConfiguration", "McpServerPortalApplicationOAuthConfigurationDynamicClientRegistration", "McpServerPortalApplicationOAuthConfigurationGrant", @@ -242,16 +223,195 @@ ] -class SelfHostedApplicationDestinationPublicDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" +class EndUserApplicationOAuthConfigurationDynamicClientRegistration(BaseModel): + """Settings for OAuth dynamic client registration.""" + + allow_any_on_localhost: Optional[bool] = None + """Allows any client with redirect URIs on localhost.""" + + allow_any_on_loopback: Optional[bool] = None + """Allows any client with redirect URIs on 127.0.0.1.""" + + allowed_uris: Optional[List[str]] = None + """The URIs that are allowed as redirect URIs for dynamically registered clients. + + HTTP and HTTPS paths may end in `/*` to match all sub-paths. Custom-scheme URIs + must be explicitly configured and match exactly. + """ + + enabled: Optional[bool] = None + """Whether dynamic client registration is enabled.""" + + +class EndUserApplicationOAuthConfigurationGrant(BaseModel): + """Settings for OAuth grant behavior.""" + + access_token_lifetime: Optional[str] = None + """The lifetime of the access token. + + Must be in the format `300ms` or `2h45m`. Valid time units are ns, us (or µs), + ms, s, m, h. + """ + + session_duration: Optional[str] = None + """The duration of the OAuth session. + + Must be in the format `300ms` or `2h45m`. Valid time units are ns, us (or µs), + ms, s, m, h. + """ + + +class EndUserApplicationOAuthConfiguration(BaseModel): + """ + **Beta:** Optional configuration for managing an OAuth authorization flow controlled by Access. When set, Access will act as the OAuth authorization server for this application. Only compatible with OAuth clients that support [RFC 8707](https://datatracker.ietf.org/doc/html/rfc8707) (Resource Indicators for OAuth 2.0). This feature is currently in beta. + """ + + dynamic_client_registration: Optional[EndUserApplicationOAuthConfigurationDynamicClientRegistration] = None + """Settings for OAuth dynamic client registration.""" + + enabled: Optional[Literal[True]] = None + """Managed OAuth is required for end user applications and cannot be disabled.""" + + grant: Optional[EndUserApplicationOAuthConfigurationGrant] = None + """Settings for OAuth grant behavior.""" + + +class EndUserApplicationDestinationAccessEndUserPublicDestination(BaseModel): + uri: str + """The public hostname and optional path to secure.""" + + overrides: Optional[List[DestinationOverride]] = None + """Rules that override how Access handles requests to this destination. + + Each rule can make a matching path public, bypassing Access authentication. + Overrides are supported for public destinations and Worker destinations. + """ + + type: Optional[Literal["public"]] = None + + +class EndUserApplicationDestinationAccessEndUserWorkerDestination(BaseModel): + type: Literal["worker"] + + worker_id: str + """The ID of the Cloudflare Worker to secure.""" + + overrides: Optional[List[DestinationOverride]] = None + """Rules that override how Access handles requests to this destination. + + Each rule can make a matching path public, bypassing Access authentication. + Overrides are supported for public destinations and Worker destinations. + """ + + +class EndUserApplicationDestinationAccessEndUserPreviewWorkerDestination(BaseModel): + type: Literal["preview_worker"] + + worker_id: str + """The ID of the Cloudflare Worker whose previews to secure.""" + + overrides: Optional[List[DestinationOverride]] = None + """Rules that override how Access handles requests to this destination. + + Each rule can make a matching path public, bypassing Access authentication. + Overrides are supported for public destinations and Worker destinations. + """ + + +class EndUserApplicationDestinationAccessEndUserAllWorkersDestination(BaseModel): + type: Literal["all_workers"] + + overrides: Optional[List[DestinationOverride]] = None + """Rules that override how Access handles requests to this destination. + + Each rule can make a matching path public, bypassing Access authentication. + Overrides are supported for public destinations and Worker destinations. + """ + + +class EndUserApplicationDestinationAccessEndUserAllPreviewWorkersDestination(BaseModel): + type: Literal["all_preview_workers"] - path_pattern: str - """The request path pattern to match. + overrides: Optional[List[DestinationOverride]] = None + """Rules that override how Access handles requests to this destination. + + Each rule can make a matching path public, bypassing Access authentication. + Overrides are supported for public destinations and Worker destinations. + """ + + +EndUserApplicationDestination: TypeAlias = Union[ + EndUserApplicationDestinationAccessEndUserPublicDestination, + EndUserApplicationDestinationAccessEndUserWorkerDestination, + EndUserApplicationDestinationAccessEndUserPreviewWorkerDestination, + EndUserApplicationDestinationAccessEndUserAllWorkersDestination, + EndUserApplicationDestinationAccessEndUserAllPreviewWorkersDestination, +] + + +class EndUserApplication(BaseModel): + oauth_configuration: EndUserApplicationOAuthConfiguration + """ + **Beta:** Optional configuration for managing an OAuth authorization flow + controlled by Access. When set, Access will act as the OAuth authorization + server for this application. Only compatible with OAuth clients that support + [RFC 8707](https://datatracker.ietf.org/doc/html/rfc8707) (Resource Indicators + for OAuth 2.0). This feature is currently in beta. + """ + + type: Literal[ + "self_hosted", + "end_user", + "saas", + "ssh", + "vnc", + "app_launcher", + "warp", + "biso", + "bookmark", + "dash_sso", + "infrastructure", + "rdp", + "mcp", + "mcp_portal", + "proxy_endpoint", + ] + """The application type.""" + + user_populations: List[str] + """The single user population associated with this application.""" + + id: Optional[str] = None + """UUID.""" + + allowed_idps: Optional[List[AllowedIdPs]] = None + """The identity providers your users can select when connecting to this + application. + + Defaults to all IdPs configured in your account. + """ + + aud: Optional[str] = None + """Audience tag.""" + + destinations: Optional[List[EndUserApplicationDestination]] = None + """Public hostname and Workers destinations secured by Access.""" + + domain: Optional[str] = None + """The primary hostname and path secured by Access. + + This domain will be displayed if the app is visible in the App Launcher. + """ + + name: Optional[str] = None + """The name of the application.""" - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. + self_hosted_domains: Optional[List[SelfHostedDomains]] = None + """List of public domains that Access will secure. + + This field is deprecated in favor of `destinations` and will be supported until + **November 21, 2025.** If `destinations` are provided, then + `self_hosted_domains` will be ignored. """ @@ -261,7 +421,7 @@ class SelfHostedApplicationDestinationPublicDestination(BaseModel): Public destinations support sub-domain and path. Wildcard '*' can be used in the definition. """ - overrides: Optional[List[SelfHostedApplicationDestinationPublicDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -315,19 +475,6 @@ class SelfHostedApplicationDestinationViaMcpServerPortalDestination(BaseModel): type: Optional[Literal["via_mcp_server_portal"]] = None -class SelfHostedApplicationDestinationWorkerDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class SelfHostedApplicationDestinationWorkerDestination(BaseModel): """A specific Cloudflare Worker that Access will secure. @@ -339,7 +486,7 @@ class SelfHostedApplicationDestinationWorkerDestination(BaseModel): worker_id: str """The ID of the Cloudflare Worker to protect with Access.""" - overrides: Optional[List[SelfHostedApplicationDestinationWorkerDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -347,19 +494,6 @@ class SelfHostedApplicationDestinationWorkerDestination(BaseModel): """ -class SelfHostedApplicationDestinationPreviewWorkerDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class SelfHostedApplicationDestinationPreviewWorkerDestination(BaseModel): """A specific Cloudflare Worker whose preview deployments Access will secure. @@ -374,7 +508,7 @@ class SelfHostedApplicationDestinationPreviewWorkerDestination(BaseModel): Access. """ - overrides: Optional[List[SelfHostedApplicationDestinationPreviewWorkerDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -382,19 +516,6 @@ class SelfHostedApplicationDestinationPreviewWorkerDestination(BaseModel): """ -class SelfHostedApplicationDestinationAllWorkersDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class SelfHostedApplicationDestinationAllWorkersDestination(BaseModel): """ Protects all Cloudflare Workers on the account with Access, including their preview deployments. At most one destination of this type can exist per account. The `worker`, `preview_worker`, `all_preview_workers`, and `public` destination types take precedence, so you can create separate applications to override the policies for specific Workers, their previews, or specific paths. @@ -402,7 +523,7 @@ class SelfHostedApplicationDestinationAllWorkersDestination(BaseModel): type: Literal["all_workers"] - overrides: Optional[List[SelfHostedApplicationDestinationAllWorkersDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -410,19 +531,6 @@ class SelfHostedApplicationDestinationAllWorkersDestination(BaseModel): """ -class SelfHostedApplicationDestinationAllPreviewWorkersDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class SelfHostedApplicationDestinationAllPreviewWorkersDestination(BaseModel): """ Protects the preview deployments of all Cloudflare Workers on the account with Access. At most one destination of this type can exist per account. The `worker`, `preview_worker`, and `public` destination types take precedence, so you can create separate applications to override the policies for specific Workers, their previews, or specific paths. @@ -430,7 +538,7 @@ class SelfHostedApplicationDestinationAllPreviewWorkersDestination(BaseModel): type: Literal["all_preview_workers"] - overrides: Optional[List[SelfHostedApplicationDestinationAllPreviewWorkersDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -624,6 +732,13 @@ class SelfHostedApplicationPolicy(BaseModel): name: Optional[str] = None """The name of the Access policy.""" + policy_resolution_account_id: Optional[str] = None + """ + The account ID used to resolve policy resources and identity for cross-account + WARP authentication. The account must be trusted by the account that owns this + policy. + """ + precedence: Optional[int] = None """The order of execution for this policy. @@ -915,7 +1030,7 @@ class SelfHostedApplication(BaseModel): """The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), - ms, s, m, h. Note: unsupported for infrastructure type applications. + ms, s, m, h. """ skip_interstitial: Optional[bool] = None @@ -1034,6 +1149,13 @@ class SaaSApplicationPolicy(BaseModel): name: Optional[str] = None """The name of the Access policy.""" + policy_resolution_account_id: Optional[str] = None + """ + The account ID used to resolve policy resources and identity for cross-account + WARP authentication. The account must be trusted by the account that owns this + policy. + """ + precedence: Optional[int] = None """The order of execution for this policy. @@ -1216,26 +1338,13 @@ class SaaSApplication(BaseModel): """The application type.""" -class BrowserSSHApplicationDestinationPublicDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class BrowserSSHApplicationDestinationPublicDestination(BaseModel): """A public hostname that Access will secure. Public destinations support sub-domain and path. Wildcard '*' can be used in the definition. """ - overrides: Optional[List[BrowserSSHApplicationDestinationPublicDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -1289,19 +1398,6 @@ class BrowserSSHApplicationDestinationViaMcpServerPortalDestination(BaseModel): type: Optional[Literal["via_mcp_server_portal"]] = None -class BrowserSSHApplicationDestinationWorkerDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class BrowserSSHApplicationDestinationWorkerDestination(BaseModel): """A specific Cloudflare Worker that Access will secure. @@ -1313,7 +1409,7 @@ class BrowserSSHApplicationDestinationWorkerDestination(BaseModel): worker_id: str """The ID of the Cloudflare Worker to protect with Access.""" - overrides: Optional[List[BrowserSSHApplicationDestinationWorkerDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -1321,19 +1417,6 @@ class BrowserSSHApplicationDestinationWorkerDestination(BaseModel): """ -class BrowserSSHApplicationDestinationPreviewWorkerDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class BrowserSSHApplicationDestinationPreviewWorkerDestination(BaseModel): """A specific Cloudflare Worker whose preview deployments Access will secure. @@ -1348,7 +1431,7 @@ class BrowserSSHApplicationDestinationPreviewWorkerDestination(BaseModel): Access. """ - overrides: Optional[List[BrowserSSHApplicationDestinationPreviewWorkerDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -1356,19 +1439,6 @@ class BrowserSSHApplicationDestinationPreviewWorkerDestination(BaseModel): """ -class BrowserSSHApplicationDestinationAllWorkersDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class BrowserSSHApplicationDestinationAllWorkersDestination(BaseModel): """ Protects all Cloudflare Workers on the account with Access, including their preview deployments. At most one destination of this type can exist per account. The `worker`, `preview_worker`, `all_preview_workers`, and `public` destination types take precedence, so you can create separate applications to override the policies for specific Workers, their previews, or specific paths. @@ -1376,7 +1446,7 @@ class BrowserSSHApplicationDestinationAllWorkersDestination(BaseModel): type: Literal["all_workers"] - overrides: Optional[List[BrowserSSHApplicationDestinationAllWorkersDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -1384,19 +1454,6 @@ class BrowserSSHApplicationDestinationAllWorkersDestination(BaseModel): """ -class BrowserSSHApplicationDestinationAllPreviewWorkersDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class BrowserSSHApplicationDestinationAllPreviewWorkersDestination(BaseModel): """ Protects the preview deployments of all Cloudflare Workers on the account with Access. At most one destination of this type can exist per account. The `worker`, `preview_worker`, and `public` destination types take precedence, so you can create separate applications to override the policies for specific Workers, their previews, or specific paths. @@ -1404,7 +1461,7 @@ class BrowserSSHApplicationDestinationAllPreviewWorkersDestination(BaseModel): type: Literal["all_preview_workers"] - overrides: Optional[List[BrowserSSHApplicationDestinationAllPreviewWorkersDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -1598,6 +1655,13 @@ class BrowserSSHApplicationPolicy(BaseModel): name: Optional[str] = None """The name of the Access policy.""" + policy_resolution_account_id: Optional[str] = None + """ + The account ID used to resolve policy resources and identity for cross-account + WARP authentication. The account must be trusted by the account that owns this + policy. + """ + precedence: Optional[int] = None """The order of execution for this policy. @@ -1733,6 +1797,7 @@ class BrowserSSHApplication(BaseModel): type: Literal[ "self_hosted", + "end_user", "saas", "ssh", "vnc", @@ -1904,7 +1969,7 @@ class BrowserSSHApplication(BaseModel): """The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), - ms, s, m, h. Note: unsupported for infrastructure type applications. + ms, s, m, h. """ skip_interstitial: Optional[bool] = None @@ -1925,26 +1990,13 @@ class BrowserSSHApplication(BaseModel): """ -class BrowserVNCApplicationDestinationPublicDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class BrowserVNCApplicationDestinationPublicDestination(BaseModel): """A public hostname that Access will secure. Public destinations support sub-domain and path. Wildcard '*' can be used in the definition. """ - overrides: Optional[List[BrowserVNCApplicationDestinationPublicDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -1998,19 +2050,6 @@ class BrowserVNCApplicationDestinationViaMcpServerPortalDestination(BaseModel): type: Optional[Literal["via_mcp_server_portal"]] = None -class BrowserVNCApplicationDestinationWorkerDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class BrowserVNCApplicationDestinationWorkerDestination(BaseModel): """A specific Cloudflare Worker that Access will secure. @@ -2022,7 +2061,7 @@ class BrowserVNCApplicationDestinationWorkerDestination(BaseModel): worker_id: str """The ID of the Cloudflare Worker to protect with Access.""" - overrides: Optional[List[BrowserVNCApplicationDestinationWorkerDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -2030,19 +2069,6 @@ class BrowserVNCApplicationDestinationWorkerDestination(BaseModel): """ -class BrowserVNCApplicationDestinationPreviewWorkerDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class BrowserVNCApplicationDestinationPreviewWorkerDestination(BaseModel): """A specific Cloudflare Worker whose preview deployments Access will secure. @@ -2057,7 +2083,7 @@ class BrowserVNCApplicationDestinationPreviewWorkerDestination(BaseModel): Access. """ - overrides: Optional[List[BrowserVNCApplicationDestinationPreviewWorkerDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -2065,19 +2091,6 @@ class BrowserVNCApplicationDestinationPreviewWorkerDestination(BaseModel): """ -class BrowserVNCApplicationDestinationAllWorkersDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class BrowserVNCApplicationDestinationAllWorkersDestination(BaseModel): """ Protects all Cloudflare Workers on the account with Access, including their preview deployments. At most one destination of this type can exist per account. The `worker`, `preview_worker`, `all_preview_workers`, and `public` destination types take precedence, so you can create separate applications to override the policies for specific Workers, their previews, or specific paths. @@ -2085,7 +2098,7 @@ class BrowserVNCApplicationDestinationAllWorkersDestination(BaseModel): type: Literal["all_workers"] - overrides: Optional[List[BrowserVNCApplicationDestinationAllWorkersDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -2093,19 +2106,6 @@ class BrowserVNCApplicationDestinationAllWorkersDestination(BaseModel): """ -class BrowserVNCApplicationDestinationAllPreviewWorkersDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class BrowserVNCApplicationDestinationAllPreviewWorkersDestination(BaseModel): """ Protects the preview deployments of all Cloudflare Workers on the account with Access. At most one destination of this type can exist per account. The `worker`, `preview_worker`, and `public` destination types take precedence, so you can create separate applications to override the policies for specific Workers, their previews, or specific paths. @@ -2113,7 +2113,7 @@ class BrowserVNCApplicationDestinationAllPreviewWorkersDestination(BaseModel): type: Literal["all_preview_workers"] - overrides: Optional[List[BrowserVNCApplicationDestinationAllPreviewWorkersDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -2307,6 +2307,13 @@ class BrowserVNCApplicationPolicy(BaseModel): name: Optional[str] = None """The name of the Access policy.""" + policy_resolution_account_id: Optional[str] = None + """ + The account ID used to resolve policy resources and identity for cross-account + WARP authentication. The account must be trusted by the account that owns this + policy. + """ + precedence: Optional[int] = None """The order of execution for this policy. @@ -2442,6 +2449,7 @@ class BrowserVNCApplication(BaseModel): type: Literal[ "self_hosted", + "end_user", "saas", "ssh", "vnc", @@ -2613,7 +2621,7 @@ class BrowserVNCApplication(BaseModel): """The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), - ms, s, m, h. Note: unsupported for infrastructure type applications. + ms, s, m, h. """ skip_interstitial: Optional[bool] = None @@ -2759,6 +2767,13 @@ class AppLauncherApplicationPolicy(BaseModel): name: Optional[str] = None """The name of the Access policy.""" + policy_resolution_account_id: Optional[str] = None + """ + The account ID used to resolve policy resources and identity for cross-account + WARP authentication. The account must be trusted by the account that owns this + policy. + """ + precedence: Optional[int] = None """The order of execution for this policy. @@ -2790,6 +2805,7 @@ class AppLauncherApplicationPolicy(BaseModel): class AppLauncherApplication(BaseModel): type: Literal[ "self_hosted", + "end_user", "saas", "ssh", "vnc", @@ -2871,7 +2887,7 @@ class AppLauncherApplication(BaseModel): """The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), - ms, s, m, h. Note: unsupported for infrastructure type applications. + ms, s, m, h. """ skip_app_launcher_login_page: Optional[bool] = None @@ -2976,6 +2992,13 @@ class DeviceEnrollmentPermissionsApplicationPolicy(BaseModel): name: Optional[str] = None """The name of the Access policy.""" + policy_resolution_account_id: Optional[str] = None + """ + The account ID used to resolve policy resources and identity for cross-account + WARP authentication. The account must be trusted by the account that owns this + policy. + """ + precedence: Optional[int] = None """The order of execution for this policy. @@ -3058,7 +3081,7 @@ class DeviceEnrollmentPermissionsApplication(BaseModel): """The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), - ms, s, m, h. Note: unsupported for infrastructure type applications. + ms, s, m, h. """ @@ -3160,6 +3183,13 @@ class BrowserIsolationPermissionsApplicationPolicy(BaseModel): name: Optional[str] = None """The name of the Access policy.""" + policy_resolution_account_id: Optional[str] = None + """ + The account ID used to resolve policy resources and identity for cross-account + WARP authentication. The account must be trusted by the account that owns this + policy. + """ + precedence: Optional[int] = None """The order of execution for this policy. @@ -3242,7 +3272,7 @@ class BrowserIsolationPermissionsApplication(BaseModel): """The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), - ms, s, m, h. Note: unsupported for infrastructure type applications. + ms, s, m, h. """ @@ -3344,6 +3374,13 @@ class GatewayIdentityProxyEndpointApplicationPolicy(BaseModel): name: Optional[str] = None """The name of the Access policy.""" + policy_resolution_account_id: Optional[str] = None + """ + The account ID used to resolve policy resources and identity for cross-account + WARP authentication. The account must be trusted by the account that owns this + policy. + """ + precedence: Optional[int] = None """The order of execution for this policy. @@ -3426,7 +3463,7 @@ class GatewayIdentityProxyEndpointApplication(BaseModel): """The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), - ms, s, m, h. Note: unsupported for infrastructure type applications. + ms, s, m, h. """ @@ -3528,6 +3565,13 @@ class BookmarkApplicationPolicy(BaseModel): name: Optional[str] = None """The name of the Access policy.""" + policy_resolution_account_id: Optional[str] = None + """ + The account ID used to resolve policy resources and identity for cross-account + WARP authentication. The account must be trusted by the account that owns this + policy. + """ + precedence: Optional[int] = None """The order of execution for this policy. @@ -3799,6 +3843,13 @@ class InfrastructureApplicationPolicy(BaseModel): name: Optional[str] = None """The name of the Access policy.""" + policy_resolution_account_id: Optional[str] = None + """ + The account ID used to resolve policy resources and identity for cross-account + WARP authentication. The account must be trusted by the account that owns this + policy. + """ + require: Optional[List[AccessRule]] = None """Rules evaluated with an AND logical operator. @@ -3831,6 +3882,13 @@ class InfrastructureApplication(BaseModel): policies: Optional[List[InfrastructureApplicationPolicy]] = None + session_duration: Optional[str] = None + """The maximum duration of a connection to this application's targets. + + Connections are terminated once it elapses. Must be in the format `30m` or + `2h45m`, in whole seconds. Valid time units are: s, m, h. + """ + class BrowserRDPApplicationTargetCriterionExcludeTargetAttributes(BaseModel): """Hostname selector map for include, require, or exclude rules. @@ -3929,26 +3987,13 @@ class BrowserRDPApplicationTargetCriterion(BaseModel): """Contains a map of target attribute keys to target attribute values.""" -class BrowserRDPApplicationDestinationPublicDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class BrowserRDPApplicationDestinationPublicDestination(BaseModel): """A public hostname that Access will secure. Public destinations support sub-domain and path. Wildcard '*' can be used in the definition. """ - overrides: Optional[List[BrowserRDPApplicationDestinationPublicDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -4002,19 +4047,6 @@ class BrowserRDPApplicationDestinationViaMcpServerPortalDestination(BaseModel): type: Optional[Literal["via_mcp_server_portal"]] = None -class BrowserRDPApplicationDestinationWorkerDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class BrowserRDPApplicationDestinationWorkerDestination(BaseModel): """A specific Cloudflare Worker that Access will secure. @@ -4026,7 +4058,7 @@ class BrowserRDPApplicationDestinationWorkerDestination(BaseModel): worker_id: str """The ID of the Cloudflare Worker to protect with Access.""" - overrides: Optional[List[BrowserRDPApplicationDestinationWorkerDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -4034,19 +4066,6 @@ class BrowserRDPApplicationDestinationWorkerDestination(BaseModel): """ -class BrowserRDPApplicationDestinationPreviewWorkerDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class BrowserRDPApplicationDestinationPreviewWorkerDestination(BaseModel): """A specific Cloudflare Worker whose preview deployments Access will secure. @@ -4061,7 +4080,7 @@ class BrowserRDPApplicationDestinationPreviewWorkerDestination(BaseModel): Access. """ - overrides: Optional[List[BrowserRDPApplicationDestinationPreviewWorkerDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -4069,19 +4088,6 @@ class BrowserRDPApplicationDestinationPreviewWorkerDestination(BaseModel): """ -class BrowserRDPApplicationDestinationAllWorkersDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class BrowserRDPApplicationDestinationAllWorkersDestination(BaseModel): """ Protects all Cloudflare Workers on the account with Access, including their preview deployments. At most one destination of this type can exist per account. The `worker`, `preview_worker`, `all_preview_workers`, and `public` destination types take precedence, so you can create separate applications to override the policies for specific Workers, their previews, or specific paths. @@ -4089,7 +4095,7 @@ class BrowserRDPApplicationDestinationAllWorkersDestination(BaseModel): type: Literal["all_workers"] - overrides: Optional[List[BrowserRDPApplicationDestinationAllWorkersDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -4097,19 +4103,6 @@ class BrowserRDPApplicationDestinationAllWorkersDestination(BaseModel): """ -class BrowserRDPApplicationDestinationAllPreviewWorkersDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class BrowserRDPApplicationDestinationAllPreviewWorkersDestination(BaseModel): """ Protects the preview deployments of all Cloudflare Workers on the account with Access. At most one destination of this type can exist per account. The `worker`, `preview_worker`, and `public` destination types take precedence, so you can create separate applications to override the policies for specific Workers, their previews, or specific paths. @@ -4117,7 +4110,7 @@ class BrowserRDPApplicationDestinationAllPreviewWorkersDestination(BaseModel): type: Literal["all_preview_workers"] - overrides: Optional[List[BrowserRDPApplicationDestinationAllPreviewWorkersDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -4311,6 +4304,13 @@ class BrowserRDPApplicationPolicy(BaseModel): name: Optional[str] = None """The name of the Access policy.""" + policy_resolution_account_id: Optional[str] = None + """ + The account ID used to resolve policy resources and identity for cross-account + WARP authentication. The account must be trusted by the account that owns this + policy. + """ + precedence: Optional[int] = None """The order of execution for this policy. @@ -4604,7 +4604,7 @@ class BrowserRDPApplication(BaseModel): """The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), - ms, s, m, h. Note: unsupported for infrastructure type applications. + ms, s, m, h. """ skip_interstitial: Optional[bool] = None @@ -4625,26 +4625,13 @@ class BrowserRDPApplication(BaseModel): """ -class McpServerApplicationDestinationPublicDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class McpServerApplicationDestinationPublicDestination(BaseModel): """A public hostname that Access will secure. Public destinations support sub-domain and path. Wildcard '*' can be used in the definition. """ - overrides: Optional[List[McpServerApplicationDestinationPublicDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -4698,19 +4685,6 @@ class McpServerApplicationDestinationViaMcpServerPortalDestination(BaseModel): type: Optional[Literal["via_mcp_server_portal"]] = None -class McpServerApplicationDestinationWorkerDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class McpServerApplicationDestinationWorkerDestination(BaseModel): """A specific Cloudflare Worker that Access will secure. @@ -4722,7 +4696,7 @@ class McpServerApplicationDestinationWorkerDestination(BaseModel): worker_id: str """The ID of the Cloudflare Worker to protect with Access.""" - overrides: Optional[List[McpServerApplicationDestinationWorkerDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -4730,19 +4704,6 @@ class McpServerApplicationDestinationWorkerDestination(BaseModel): """ -class McpServerApplicationDestinationPreviewWorkerDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class McpServerApplicationDestinationPreviewWorkerDestination(BaseModel): """A specific Cloudflare Worker whose preview deployments Access will secure. @@ -4757,7 +4718,7 @@ class McpServerApplicationDestinationPreviewWorkerDestination(BaseModel): Access. """ - overrides: Optional[List[McpServerApplicationDestinationPreviewWorkerDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -4765,19 +4726,6 @@ class McpServerApplicationDestinationPreviewWorkerDestination(BaseModel): """ -class McpServerApplicationDestinationAllWorkersDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class McpServerApplicationDestinationAllWorkersDestination(BaseModel): """ Protects all Cloudflare Workers on the account with Access, including their preview deployments. At most one destination of this type can exist per account. The `worker`, `preview_worker`, `all_preview_workers`, and `public` destination types take precedence, so you can create separate applications to override the policies for specific Workers, their previews, or specific paths. @@ -4785,7 +4733,7 @@ class McpServerApplicationDestinationAllWorkersDestination(BaseModel): type: Literal["all_workers"] - overrides: Optional[List[McpServerApplicationDestinationAllWorkersDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -4793,19 +4741,6 @@ class McpServerApplicationDestinationAllWorkersDestination(BaseModel): """ -class McpServerApplicationDestinationAllPreviewWorkersDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class McpServerApplicationDestinationAllPreviewWorkersDestination(BaseModel): """ Protects the preview deployments of all Cloudflare Workers on the account with Access. At most one destination of this type can exist per account. The `worker`, `preview_worker`, and `public` destination types take precedence, so you can create separate applications to override the policies for specific Workers, their previews, or specific paths. @@ -4813,7 +4748,7 @@ class McpServerApplicationDestinationAllPreviewWorkersDestination(BaseModel): type: Literal["all_preview_workers"] - overrides: Optional[List[McpServerApplicationDestinationAllPreviewWorkersDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -4987,6 +4922,13 @@ class McpServerApplicationPolicy(BaseModel): name: Optional[str] = None """The name of the Access policy.""" + policy_resolution_account_id: Optional[str] = None + """ + The account ID used to resolve policy resources and identity for cross-account + WARP authentication. The account must be trusted by the account that owns this + policy. + """ + precedence: Optional[int] = None """The order of execution for this policy. @@ -5219,7 +5161,7 @@ class McpServerApplication(BaseModel): """The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), - ms, s, m, h. Note: unsupported for infrastructure type applications. + ms, s, m, h. """ tags: Optional[List[str]] = None @@ -5229,26 +5171,13 @@ class McpServerApplication(BaseModel): """ -class McpServerPortalApplicationDestinationPublicDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class McpServerPortalApplicationDestinationPublicDestination(BaseModel): """A public hostname that Access will secure. Public destinations support sub-domain and path. Wildcard '*' can be used in the definition. """ - overrides: Optional[List[McpServerPortalApplicationDestinationPublicDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -5302,19 +5231,6 @@ class McpServerPortalApplicationDestinationViaMcpServerPortalDestination(BaseMod type: Optional[Literal["via_mcp_server_portal"]] = None -class McpServerPortalApplicationDestinationWorkerDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class McpServerPortalApplicationDestinationWorkerDestination(BaseModel): """A specific Cloudflare Worker that Access will secure. @@ -5326,7 +5242,7 @@ class McpServerPortalApplicationDestinationWorkerDestination(BaseModel): worker_id: str """The ID of the Cloudflare Worker to protect with Access.""" - overrides: Optional[List[McpServerPortalApplicationDestinationWorkerDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -5334,19 +5250,6 @@ class McpServerPortalApplicationDestinationWorkerDestination(BaseModel): """ -class McpServerPortalApplicationDestinationPreviewWorkerDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class McpServerPortalApplicationDestinationPreviewWorkerDestination(BaseModel): """A specific Cloudflare Worker whose preview deployments Access will secure. @@ -5361,7 +5264,7 @@ class McpServerPortalApplicationDestinationPreviewWorkerDestination(BaseModel): Access. """ - overrides: Optional[List[McpServerPortalApplicationDestinationPreviewWorkerDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -5369,19 +5272,6 @@ class McpServerPortalApplicationDestinationPreviewWorkerDestination(BaseModel): """ -class McpServerPortalApplicationDestinationAllWorkersDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class McpServerPortalApplicationDestinationAllWorkersDestination(BaseModel): """ Protects all Cloudflare Workers on the account with Access, including their preview deployments. At most one destination of this type can exist per account. The `worker`, `preview_worker`, `all_preview_workers`, and `public` destination types take precedence, so you can create separate applications to override the policies for specific Workers, their previews, or specific paths. @@ -5389,7 +5279,7 @@ class McpServerPortalApplicationDestinationAllWorkersDestination(BaseModel): type: Literal["all_workers"] - overrides: Optional[List[McpServerPortalApplicationDestinationAllWorkersDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -5397,19 +5287,6 @@ class McpServerPortalApplicationDestinationAllWorkersDestination(BaseModel): """ -class McpServerPortalApplicationDestinationAllPreviewWorkersDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class McpServerPortalApplicationDestinationAllPreviewWorkersDestination(BaseModel): """ Protects the preview deployments of all Cloudflare Workers on the account with Access. At most one destination of this type can exist per account. The `worker`, `preview_worker`, and `public` destination types take precedence, so you can create separate applications to override the policies for specific Workers, their previews, or specific paths. @@ -5417,7 +5294,7 @@ class McpServerPortalApplicationDestinationAllPreviewWorkersDestination(BaseMode type: Literal["all_preview_workers"] - overrides: Optional[List[McpServerPortalApplicationDestinationAllPreviewWorkersDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -5591,6 +5468,13 @@ class McpServerPortalApplicationPolicy(BaseModel): name: Optional[str] = None """The name of the Access policy.""" + policy_resolution_account_id: Optional[str] = None + """ + The account ID used to resolve policy resources and identity for cross-account + WARP authentication. The account must be trusted by the account that owns this + policy. + """ + precedence: Optional[int] = None """The order of execution for this policy. @@ -5829,7 +5713,7 @@ class McpServerPortalApplication(BaseModel): """The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), - ms, s, m, h. Note: unsupported for infrastructure type applications. + ms, s, m, h. """ tags: Optional[List[str]] = None @@ -5840,6 +5724,7 @@ class McpServerPortalApplication(BaseModel): ApplicationGetResponse: TypeAlias = Union[ + EndUserApplication, SelfHostedApplication, SaaSApplication, BrowserSSHApplication, diff --git a/src/cloudflare/types/zero_trust/access/application_list_response.py b/src/cloudflare/types/zero_trust/access/application_list_response.py index 9b7636b491d..abb360b5e25 100644 --- a/src/cloudflare/types/zero_trust/access/application_list_response.py +++ b/src/cloudflare/types/zero_trust/access/application_list_response.py @@ -14,6 +14,7 @@ from .application_type import ApplicationType from .scim_config_mapping import SCIMConfigMapping from .self_hosted_domains import SelfHostedDomains +from .destination_override import DestinationOverride from .applications.access_rule import AccessRule from .scim_config_authentication_oauth2 import SCIMConfigAuthenticationOauth2 from .scim_config_authentication_http_basic import SCIMConfigAuthenticationHTTPBasic @@ -21,20 +22,25 @@ __all__ = [ "ApplicationListResponse", + "EndUserApplication", + "EndUserApplicationOAuthConfiguration", + "EndUserApplicationOAuthConfigurationDynamicClientRegistration", + "EndUserApplicationOAuthConfigurationGrant", + "EndUserApplicationDestination", + "EndUserApplicationDestinationAccessEndUserPublicDestination", + "EndUserApplicationDestinationAccessEndUserWorkerDestination", + "EndUserApplicationDestinationAccessEndUserPreviewWorkerDestination", + "EndUserApplicationDestinationAccessEndUserAllWorkersDestination", + "EndUserApplicationDestinationAccessEndUserAllPreviewWorkersDestination", "SelfHostedApplication", "SelfHostedApplicationDestination", "SelfHostedApplicationDestinationPublicDestination", - "SelfHostedApplicationDestinationPublicDestinationOverride", "SelfHostedApplicationDestinationPrivateDestination", "SelfHostedApplicationDestinationViaMcpServerPortalDestination", "SelfHostedApplicationDestinationWorkerDestination", - "SelfHostedApplicationDestinationWorkerDestinationOverride", "SelfHostedApplicationDestinationPreviewWorkerDestination", - "SelfHostedApplicationDestinationPreviewWorkerDestinationOverride", "SelfHostedApplicationDestinationAllWorkersDestination", - "SelfHostedApplicationDestinationAllWorkersDestinationOverride", "SelfHostedApplicationDestinationAllPreviewWorkersDestination", - "SelfHostedApplicationDestinationAllPreviewWorkersDestinationOverride", "SelfHostedApplicationMfaConfig", "SelfHostedApplicationOAuthConfiguration", "SelfHostedApplicationOAuthConfigurationDynamicClientRegistration", @@ -62,17 +68,12 @@ "BrowserSSHApplication", "BrowserSSHApplicationDestination", "BrowserSSHApplicationDestinationPublicDestination", - "BrowserSSHApplicationDestinationPublicDestinationOverride", "BrowserSSHApplicationDestinationPrivateDestination", "BrowserSSHApplicationDestinationViaMcpServerPortalDestination", "BrowserSSHApplicationDestinationWorkerDestination", - "BrowserSSHApplicationDestinationWorkerDestinationOverride", "BrowserSSHApplicationDestinationPreviewWorkerDestination", - "BrowserSSHApplicationDestinationPreviewWorkerDestinationOverride", "BrowserSSHApplicationDestinationAllWorkersDestination", - "BrowserSSHApplicationDestinationAllWorkersDestinationOverride", "BrowserSSHApplicationDestinationAllPreviewWorkersDestination", - "BrowserSSHApplicationDestinationAllPreviewWorkersDestinationOverride", "BrowserSSHApplicationMfaConfig", "BrowserSSHApplicationOAuthConfiguration", "BrowserSSHApplicationOAuthConfigurationDynamicClientRegistration", @@ -89,17 +90,12 @@ "BrowserVNCApplication", "BrowserVNCApplicationDestination", "BrowserVNCApplicationDestinationPublicDestination", - "BrowserVNCApplicationDestinationPublicDestinationOverride", "BrowserVNCApplicationDestinationPrivateDestination", "BrowserVNCApplicationDestinationViaMcpServerPortalDestination", "BrowserVNCApplicationDestinationWorkerDestination", - "BrowserVNCApplicationDestinationWorkerDestinationOverride", "BrowserVNCApplicationDestinationPreviewWorkerDestination", - "BrowserVNCApplicationDestinationPreviewWorkerDestinationOverride", "BrowserVNCApplicationDestinationAllWorkersDestination", - "BrowserVNCApplicationDestinationAllWorkersDestinationOverride", "BrowserVNCApplicationDestinationAllPreviewWorkersDestination", - "BrowserVNCApplicationDestinationAllPreviewWorkersDestinationOverride", "BrowserVNCApplicationMfaConfig", "BrowserVNCApplicationOAuthConfiguration", "BrowserVNCApplicationOAuthConfigurationDynamicClientRegistration", @@ -163,17 +159,12 @@ "BrowserRDPApplicationTargetCriterionRequireTargetAttributes", "BrowserRDPApplicationDestination", "BrowserRDPApplicationDestinationPublicDestination", - "BrowserRDPApplicationDestinationPublicDestinationOverride", "BrowserRDPApplicationDestinationPrivateDestination", "BrowserRDPApplicationDestinationViaMcpServerPortalDestination", "BrowserRDPApplicationDestinationWorkerDestination", - "BrowserRDPApplicationDestinationWorkerDestinationOverride", "BrowserRDPApplicationDestinationPreviewWorkerDestination", - "BrowserRDPApplicationDestinationPreviewWorkerDestinationOverride", "BrowserRDPApplicationDestinationAllWorkersDestination", - "BrowserRDPApplicationDestinationAllWorkersDestinationOverride", "BrowserRDPApplicationDestinationAllPreviewWorkersDestination", - "BrowserRDPApplicationDestinationAllPreviewWorkersDestinationOverride", "BrowserRDPApplicationMfaConfig", "BrowserRDPApplicationOAuthConfiguration", "BrowserRDPApplicationOAuthConfigurationDynamicClientRegistration", @@ -190,17 +181,12 @@ "McpServerApplication", "McpServerApplicationDestination", "McpServerApplicationDestinationPublicDestination", - "McpServerApplicationDestinationPublicDestinationOverride", "McpServerApplicationDestinationPrivateDestination", "McpServerApplicationDestinationViaMcpServerPortalDestination", "McpServerApplicationDestinationWorkerDestination", - "McpServerApplicationDestinationWorkerDestinationOverride", "McpServerApplicationDestinationPreviewWorkerDestination", - "McpServerApplicationDestinationPreviewWorkerDestinationOverride", "McpServerApplicationDestinationAllWorkersDestination", - "McpServerApplicationDestinationAllWorkersDestinationOverride", "McpServerApplicationDestinationAllPreviewWorkersDestination", - "McpServerApplicationDestinationAllPreviewWorkersDestinationOverride", "McpServerApplicationOAuthConfiguration", "McpServerApplicationOAuthConfigurationDynamicClientRegistration", "McpServerApplicationOAuthConfigurationGrant", @@ -216,17 +202,12 @@ "McpServerPortalApplication", "McpServerPortalApplicationDestination", "McpServerPortalApplicationDestinationPublicDestination", - "McpServerPortalApplicationDestinationPublicDestinationOverride", "McpServerPortalApplicationDestinationPrivateDestination", "McpServerPortalApplicationDestinationViaMcpServerPortalDestination", "McpServerPortalApplicationDestinationWorkerDestination", - "McpServerPortalApplicationDestinationWorkerDestinationOverride", "McpServerPortalApplicationDestinationPreviewWorkerDestination", - "McpServerPortalApplicationDestinationPreviewWorkerDestinationOverride", "McpServerPortalApplicationDestinationAllWorkersDestination", - "McpServerPortalApplicationDestinationAllWorkersDestinationOverride", "McpServerPortalApplicationDestinationAllPreviewWorkersDestination", - "McpServerPortalApplicationDestinationAllPreviewWorkersDestinationOverride", "McpServerPortalApplicationOAuthConfiguration", "McpServerPortalApplicationOAuthConfigurationDynamicClientRegistration", "McpServerPortalApplicationOAuthConfigurationGrant", @@ -242,16 +223,195 @@ ] -class SelfHostedApplicationDestinationPublicDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" +class EndUserApplicationOAuthConfigurationDynamicClientRegistration(BaseModel): + """Settings for OAuth dynamic client registration.""" + + allow_any_on_localhost: Optional[bool] = None + """Allows any client with redirect URIs on localhost.""" + + allow_any_on_loopback: Optional[bool] = None + """Allows any client with redirect URIs on 127.0.0.1.""" + + allowed_uris: Optional[List[str]] = None + """The URIs that are allowed as redirect URIs for dynamically registered clients. + + HTTP and HTTPS paths may end in `/*` to match all sub-paths. Custom-scheme URIs + must be explicitly configured and match exactly. + """ + + enabled: Optional[bool] = None + """Whether dynamic client registration is enabled.""" + + +class EndUserApplicationOAuthConfigurationGrant(BaseModel): + """Settings for OAuth grant behavior.""" + + access_token_lifetime: Optional[str] = None + """The lifetime of the access token. + + Must be in the format `300ms` or `2h45m`. Valid time units are ns, us (or µs), + ms, s, m, h. + """ + + session_duration: Optional[str] = None + """The duration of the OAuth session. + + Must be in the format `300ms` or `2h45m`. Valid time units are ns, us (or µs), + ms, s, m, h. + """ + + +class EndUserApplicationOAuthConfiguration(BaseModel): + """ + **Beta:** Optional configuration for managing an OAuth authorization flow controlled by Access. When set, Access will act as the OAuth authorization server for this application. Only compatible with OAuth clients that support [RFC 8707](https://datatracker.ietf.org/doc/html/rfc8707) (Resource Indicators for OAuth 2.0). This feature is currently in beta. + """ + + dynamic_client_registration: Optional[EndUserApplicationOAuthConfigurationDynamicClientRegistration] = None + """Settings for OAuth dynamic client registration.""" + + enabled: Optional[Literal[True]] = None + """Managed OAuth is required for end user applications and cannot be disabled.""" + + grant: Optional[EndUserApplicationOAuthConfigurationGrant] = None + """Settings for OAuth grant behavior.""" + + +class EndUserApplicationDestinationAccessEndUserPublicDestination(BaseModel): + uri: str + """The public hostname and optional path to secure.""" + + overrides: Optional[List[DestinationOverride]] = None + """Rules that override how Access handles requests to this destination. + + Each rule can make a matching path public, bypassing Access authentication. + Overrides are supported for public destinations and Worker destinations. + """ + + type: Optional[Literal["public"]] = None + + +class EndUserApplicationDestinationAccessEndUserWorkerDestination(BaseModel): + type: Literal["worker"] + + worker_id: str + """The ID of the Cloudflare Worker to secure.""" + + overrides: Optional[List[DestinationOverride]] = None + """Rules that override how Access handles requests to this destination. + + Each rule can make a matching path public, bypassing Access authentication. + Overrides are supported for public destinations and Worker destinations. + """ + + +class EndUserApplicationDestinationAccessEndUserPreviewWorkerDestination(BaseModel): + type: Literal["preview_worker"] + + worker_id: str + """The ID of the Cloudflare Worker whose previews to secure.""" + + overrides: Optional[List[DestinationOverride]] = None + """Rules that override how Access handles requests to this destination. + + Each rule can make a matching path public, bypassing Access authentication. + Overrides are supported for public destinations and Worker destinations. + """ + + +class EndUserApplicationDestinationAccessEndUserAllWorkersDestination(BaseModel): + type: Literal["all_workers"] + + overrides: Optional[List[DestinationOverride]] = None + """Rules that override how Access handles requests to this destination. + + Each rule can make a matching path public, bypassing Access authentication. + Overrides are supported for public destinations and Worker destinations. + """ + + +class EndUserApplicationDestinationAccessEndUserAllPreviewWorkersDestination(BaseModel): + type: Literal["all_preview_workers"] - path_pattern: str - """The request path pattern to match. + overrides: Optional[List[DestinationOverride]] = None + """Rules that override how Access handles requests to this destination. + + Each rule can make a matching path public, bypassing Access authentication. + Overrides are supported for public destinations and Worker destinations. + """ + + +EndUserApplicationDestination: TypeAlias = Union[ + EndUserApplicationDestinationAccessEndUserPublicDestination, + EndUserApplicationDestinationAccessEndUserWorkerDestination, + EndUserApplicationDestinationAccessEndUserPreviewWorkerDestination, + EndUserApplicationDestinationAccessEndUserAllWorkersDestination, + EndUserApplicationDestinationAccessEndUserAllPreviewWorkersDestination, +] + + +class EndUserApplication(BaseModel): + oauth_configuration: EndUserApplicationOAuthConfiguration + """ + **Beta:** Optional configuration for managing an OAuth authorization flow + controlled by Access. When set, Access will act as the OAuth authorization + server for this application. Only compatible with OAuth clients that support + [RFC 8707](https://datatracker.ietf.org/doc/html/rfc8707) (Resource Indicators + for OAuth 2.0). This feature is currently in beta. + """ + + type: Literal[ + "self_hosted", + "end_user", + "saas", + "ssh", + "vnc", + "app_launcher", + "warp", + "biso", + "bookmark", + "dash_sso", + "infrastructure", + "rdp", + "mcp", + "mcp_portal", + "proxy_endpoint", + ] + """The application type.""" + + user_populations: List[str] + """The single user population associated with this application.""" + + id: Optional[str] = None + """UUID.""" + + allowed_idps: Optional[List[AllowedIdPs]] = None + """The identity providers your users can select when connecting to this + application. + + Defaults to all IdPs configured in your account. + """ + + aud: Optional[str] = None + """Audience tag.""" + + destinations: Optional[List[EndUserApplicationDestination]] = None + """Public hostname and Workers destinations secured by Access.""" + + domain: Optional[str] = None + """The primary hostname and path secured by Access. + + This domain will be displayed if the app is visible in the App Launcher. + """ + + name: Optional[str] = None + """The name of the application.""" - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. + self_hosted_domains: Optional[List[SelfHostedDomains]] = None + """List of public domains that Access will secure. + + This field is deprecated in favor of `destinations` and will be supported until + **November 21, 2025.** If `destinations` are provided, then + `self_hosted_domains` will be ignored. """ @@ -261,7 +421,7 @@ class SelfHostedApplicationDestinationPublicDestination(BaseModel): Public destinations support sub-domain and path. Wildcard '*' can be used in the definition. """ - overrides: Optional[List[SelfHostedApplicationDestinationPublicDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -315,19 +475,6 @@ class SelfHostedApplicationDestinationViaMcpServerPortalDestination(BaseModel): type: Optional[Literal["via_mcp_server_portal"]] = None -class SelfHostedApplicationDestinationWorkerDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class SelfHostedApplicationDestinationWorkerDestination(BaseModel): """A specific Cloudflare Worker that Access will secure. @@ -339,7 +486,7 @@ class SelfHostedApplicationDestinationWorkerDestination(BaseModel): worker_id: str """The ID of the Cloudflare Worker to protect with Access.""" - overrides: Optional[List[SelfHostedApplicationDestinationWorkerDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -347,19 +494,6 @@ class SelfHostedApplicationDestinationWorkerDestination(BaseModel): """ -class SelfHostedApplicationDestinationPreviewWorkerDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class SelfHostedApplicationDestinationPreviewWorkerDestination(BaseModel): """A specific Cloudflare Worker whose preview deployments Access will secure. @@ -374,7 +508,7 @@ class SelfHostedApplicationDestinationPreviewWorkerDestination(BaseModel): Access. """ - overrides: Optional[List[SelfHostedApplicationDestinationPreviewWorkerDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -382,19 +516,6 @@ class SelfHostedApplicationDestinationPreviewWorkerDestination(BaseModel): """ -class SelfHostedApplicationDestinationAllWorkersDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class SelfHostedApplicationDestinationAllWorkersDestination(BaseModel): """ Protects all Cloudflare Workers on the account with Access, including their preview deployments. At most one destination of this type can exist per account. The `worker`, `preview_worker`, `all_preview_workers`, and `public` destination types take precedence, so you can create separate applications to override the policies for specific Workers, their previews, or specific paths. @@ -402,7 +523,7 @@ class SelfHostedApplicationDestinationAllWorkersDestination(BaseModel): type: Literal["all_workers"] - overrides: Optional[List[SelfHostedApplicationDestinationAllWorkersDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -410,19 +531,6 @@ class SelfHostedApplicationDestinationAllWorkersDestination(BaseModel): """ -class SelfHostedApplicationDestinationAllPreviewWorkersDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class SelfHostedApplicationDestinationAllPreviewWorkersDestination(BaseModel): """ Protects the preview deployments of all Cloudflare Workers on the account with Access. At most one destination of this type can exist per account. The `worker`, `preview_worker`, and `public` destination types take precedence, so you can create separate applications to override the policies for specific Workers, their previews, or specific paths. @@ -430,7 +538,7 @@ class SelfHostedApplicationDestinationAllPreviewWorkersDestination(BaseModel): type: Literal["all_preview_workers"] - overrides: Optional[List[SelfHostedApplicationDestinationAllPreviewWorkersDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -624,6 +732,13 @@ class SelfHostedApplicationPolicy(BaseModel): name: Optional[str] = None """The name of the Access policy.""" + policy_resolution_account_id: Optional[str] = None + """ + The account ID used to resolve policy resources and identity for cross-account + WARP authentication. The account must be trusted by the account that owns this + policy. + """ + precedence: Optional[int] = None """The order of execution for this policy. @@ -915,7 +1030,7 @@ class SelfHostedApplication(BaseModel): """The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), - ms, s, m, h. Note: unsupported for infrastructure type applications. + ms, s, m, h. """ skip_interstitial: Optional[bool] = None @@ -1034,6 +1149,13 @@ class SaaSApplicationPolicy(BaseModel): name: Optional[str] = None """The name of the Access policy.""" + policy_resolution_account_id: Optional[str] = None + """ + The account ID used to resolve policy resources and identity for cross-account + WARP authentication. The account must be trusted by the account that owns this + policy. + """ + precedence: Optional[int] = None """The order of execution for this policy. @@ -1216,26 +1338,13 @@ class SaaSApplication(BaseModel): """The application type.""" -class BrowserSSHApplicationDestinationPublicDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class BrowserSSHApplicationDestinationPublicDestination(BaseModel): """A public hostname that Access will secure. Public destinations support sub-domain and path. Wildcard '*' can be used in the definition. """ - overrides: Optional[List[BrowserSSHApplicationDestinationPublicDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -1289,19 +1398,6 @@ class BrowserSSHApplicationDestinationViaMcpServerPortalDestination(BaseModel): type: Optional[Literal["via_mcp_server_portal"]] = None -class BrowserSSHApplicationDestinationWorkerDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class BrowserSSHApplicationDestinationWorkerDestination(BaseModel): """A specific Cloudflare Worker that Access will secure. @@ -1313,7 +1409,7 @@ class BrowserSSHApplicationDestinationWorkerDestination(BaseModel): worker_id: str """The ID of the Cloudflare Worker to protect with Access.""" - overrides: Optional[List[BrowserSSHApplicationDestinationWorkerDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -1321,19 +1417,6 @@ class BrowserSSHApplicationDestinationWorkerDestination(BaseModel): """ -class BrowserSSHApplicationDestinationPreviewWorkerDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class BrowserSSHApplicationDestinationPreviewWorkerDestination(BaseModel): """A specific Cloudflare Worker whose preview deployments Access will secure. @@ -1348,7 +1431,7 @@ class BrowserSSHApplicationDestinationPreviewWorkerDestination(BaseModel): Access. """ - overrides: Optional[List[BrowserSSHApplicationDestinationPreviewWorkerDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -1356,19 +1439,6 @@ class BrowserSSHApplicationDestinationPreviewWorkerDestination(BaseModel): """ -class BrowserSSHApplicationDestinationAllWorkersDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class BrowserSSHApplicationDestinationAllWorkersDestination(BaseModel): """ Protects all Cloudflare Workers on the account with Access, including their preview deployments. At most one destination of this type can exist per account. The `worker`, `preview_worker`, `all_preview_workers`, and `public` destination types take precedence, so you can create separate applications to override the policies for specific Workers, their previews, or specific paths. @@ -1376,7 +1446,7 @@ class BrowserSSHApplicationDestinationAllWorkersDestination(BaseModel): type: Literal["all_workers"] - overrides: Optional[List[BrowserSSHApplicationDestinationAllWorkersDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -1384,19 +1454,6 @@ class BrowserSSHApplicationDestinationAllWorkersDestination(BaseModel): """ -class BrowserSSHApplicationDestinationAllPreviewWorkersDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class BrowserSSHApplicationDestinationAllPreviewWorkersDestination(BaseModel): """ Protects the preview deployments of all Cloudflare Workers on the account with Access. At most one destination of this type can exist per account. The `worker`, `preview_worker`, and `public` destination types take precedence, so you can create separate applications to override the policies for specific Workers, their previews, or specific paths. @@ -1404,7 +1461,7 @@ class BrowserSSHApplicationDestinationAllPreviewWorkersDestination(BaseModel): type: Literal["all_preview_workers"] - overrides: Optional[List[BrowserSSHApplicationDestinationAllPreviewWorkersDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -1598,6 +1655,13 @@ class BrowserSSHApplicationPolicy(BaseModel): name: Optional[str] = None """The name of the Access policy.""" + policy_resolution_account_id: Optional[str] = None + """ + The account ID used to resolve policy resources and identity for cross-account + WARP authentication. The account must be trusted by the account that owns this + policy. + """ + precedence: Optional[int] = None """The order of execution for this policy. @@ -1733,6 +1797,7 @@ class BrowserSSHApplication(BaseModel): type: Literal[ "self_hosted", + "end_user", "saas", "ssh", "vnc", @@ -1904,7 +1969,7 @@ class BrowserSSHApplication(BaseModel): """The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), - ms, s, m, h. Note: unsupported for infrastructure type applications. + ms, s, m, h. """ skip_interstitial: Optional[bool] = None @@ -1925,26 +1990,13 @@ class BrowserSSHApplication(BaseModel): """ -class BrowserVNCApplicationDestinationPublicDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class BrowserVNCApplicationDestinationPublicDestination(BaseModel): """A public hostname that Access will secure. Public destinations support sub-domain and path. Wildcard '*' can be used in the definition. """ - overrides: Optional[List[BrowserVNCApplicationDestinationPublicDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -1998,19 +2050,6 @@ class BrowserVNCApplicationDestinationViaMcpServerPortalDestination(BaseModel): type: Optional[Literal["via_mcp_server_portal"]] = None -class BrowserVNCApplicationDestinationWorkerDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class BrowserVNCApplicationDestinationWorkerDestination(BaseModel): """A specific Cloudflare Worker that Access will secure. @@ -2022,7 +2061,7 @@ class BrowserVNCApplicationDestinationWorkerDestination(BaseModel): worker_id: str """The ID of the Cloudflare Worker to protect with Access.""" - overrides: Optional[List[BrowserVNCApplicationDestinationWorkerDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -2030,19 +2069,6 @@ class BrowserVNCApplicationDestinationWorkerDestination(BaseModel): """ -class BrowserVNCApplicationDestinationPreviewWorkerDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class BrowserVNCApplicationDestinationPreviewWorkerDestination(BaseModel): """A specific Cloudflare Worker whose preview deployments Access will secure. @@ -2057,7 +2083,7 @@ class BrowserVNCApplicationDestinationPreviewWorkerDestination(BaseModel): Access. """ - overrides: Optional[List[BrowserVNCApplicationDestinationPreviewWorkerDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -2065,19 +2091,6 @@ class BrowserVNCApplicationDestinationPreviewWorkerDestination(BaseModel): """ -class BrowserVNCApplicationDestinationAllWorkersDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class BrowserVNCApplicationDestinationAllWorkersDestination(BaseModel): """ Protects all Cloudflare Workers on the account with Access, including their preview deployments. At most one destination of this type can exist per account. The `worker`, `preview_worker`, `all_preview_workers`, and `public` destination types take precedence, so you can create separate applications to override the policies for specific Workers, their previews, or specific paths. @@ -2085,7 +2098,7 @@ class BrowserVNCApplicationDestinationAllWorkersDestination(BaseModel): type: Literal["all_workers"] - overrides: Optional[List[BrowserVNCApplicationDestinationAllWorkersDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -2093,19 +2106,6 @@ class BrowserVNCApplicationDestinationAllWorkersDestination(BaseModel): """ -class BrowserVNCApplicationDestinationAllPreviewWorkersDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class BrowserVNCApplicationDestinationAllPreviewWorkersDestination(BaseModel): """ Protects the preview deployments of all Cloudflare Workers on the account with Access. At most one destination of this type can exist per account. The `worker`, `preview_worker`, and `public` destination types take precedence, so you can create separate applications to override the policies for specific Workers, their previews, or specific paths. @@ -2113,7 +2113,7 @@ class BrowserVNCApplicationDestinationAllPreviewWorkersDestination(BaseModel): type: Literal["all_preview_workers"] - overrides: Optional[List[BrowserVNCApplicationDestinationAllPreviewWorkersDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -2307,6 +2307,13 @@ class BrowserVNCApplicationPolicy(BaseModel): name: Optional[str] = None """The name of the Access policy.""" + policy_resolution_account_id: Optional[str] = None + """ + The account ID used to resolve policy resources and identity for cross-account + WARP authentication. The account must be trusted by the account that owns this + policy. + """ + precedence: Optional[int] = None """The order of execution for this policy. @@ -2442,6 +2449,7 @@ class BrowserVNCApplication(BaseModel): type: Literal[ "self_hosted", + "end_user", "saas", "ssh", "vnc", @@ -2613,7 +2621,7 @@ class BrowserVNCApplication(BaseModel): """The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), - ms, s, m, h. Note: unsupported for infrastructure type applications. + ms, s, m, h. """ skip_interstitial: Optional[bool] = None @@ -2759,6 +2767,13 @@ class AppLauncherApplicationPolicy(BaseModel): name: Optional[str] = None """The name of the Access policy.""" + policy_resolution_account_id: Optional[str] = None + """ + The account ID used to resolve policy resources and identity for cross-account + WARP authentication. The account must be trusted by the account that owns this + policy. + """ + precedence: Optional[int] = None """The order of execution for this policy. @@ -2790,6 +2805,7 @@ class AppLauncherApplicationPolicy(BaseModel): class AppLauncherApplication(BaseModel): type: Literal[ "self_hosted", + "end_user", "saas", "ssh", "vnc", @@ -2871,7 +2887,7 @@ class AppLauncherApplication(BaseModel): """The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), - ms, s, m, h. Note: unsupported for infrastructure type applications. + ms, s, m, h. """ skip_app_launcher_login_page: Optional[bool] = None @@ -2976,6 +2992,13 @@ class DeviceEnrollmentPermissionsApplicationPolicy(BaseModel): name: Optional[str] = None """The name of the Access policy.""" + policy_resolution_account_id: Optional[str] = None + """ + The account ID used to resolve policy resources and identity for cross-account + WARP authentication. The account must be trusted by the account that owns this + policy. + """ + precedence: Optional[int] = None """The order of execution for this policy. @@ -3058,7 +3081,7 @@ class DeviceEnrollmentPermissionsApplication(BaseModel): """The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), - ms, s, m, h. Note: unsupported for infrastructure type applications. + ms, s, m, h. """ @@ -3160,6 +3183,13 @@ class BrowserIsolationPermissionsApplicationPolicy(BaseModel): name: Optional[str] = None """The name of the Access policy.""" + policy_resolution_account_id: Optional[str] = None + """ + The account ID used to resolve policy resources and identity for cross-account + WARP authentication. The account must be trusted by the account that owns this + policy. + """ + precedence: Optional[int] = None """The order of execution for this policy. @@ -3242,7 +3272,7 @@ class BrowserIsolationPermissionsApplication(BaseModel): """The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), - ms, s, m, h. Note: unsupported for infrastructure type applications. + ms, s, m, h. """ @@ -3344,6 +3374,13 @@ class GatewayIdentityProxyEndpointApplicationPolicy(BaseModel): name: Optional[str] = None """The name of the Access policy.""" + policy_resolution_account_id: Optional[str] = None + """ + The account ID used to resolve policy resources and identity for cross-account + WARP authentication. The account must be trusted by the account that owns this + policy. + """ + precedence: Optional[int] = None """The order of execution for this policy. @@ -3426,7 +3463,7 @@ class GatewayIdentityProxyEndpointApplication(BaseModel): """The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), - ms, s, m, h. Note: unsupported for infrastructure type applications. + ms, s, m, h. """ @@ -3528,6 +3565,13 @@ class BookmarkApplicationPolicy(BaseModel): name: Optional[str] = None """The name of the Access policy.""" + policy_resolution_account_id: Optional[str] = None + """ + The account ID used to resolve policy resources and identity for cross-account + WARP authentication. The account must be trusted by the account that owns this + policy. + """ + precedence: Optional[int] = None """The order of execution for this policy. @@ -3799,6 +3843,13 @@ class InfrastructureApplicationPolicy(BaseModel): name: Optional[str] = None """The name of the Access policy.""" + policy_resolution_account_id: Optional[str] = None + """ + The account ID used to resolve policy resources and identity for cross-account + WARP authentication. The account must be trusted by the account that owns this + policy. + """ + require: Optional[List[AccessRule]] = None """Rules evaluated with an AND logical operator. @@ -3831,6 +3882,13 @@ class InfrastructureApplication(BaseModel): policies: Optional[List[InfrastructureApplicationPolicy]] = None + session_duration: Optional[str] = None + """The maximum duration of a connection to this application's targets. + + Connections are terminated once it elapses. Must be in the format `30m` or + `2h45m`, in whole seconds. Valid time units are: s, m, h. + """ + class BrowserRDPApplicationTargetCriterionExcludeTargetAttributes(BaseModel): """Hostname selector map for include, require, or exclude rules. @@ -3929,26 +3987,13 @@ class BrowserRDPApplicationTargetCriterion(BaseModel): """Contains a map of target attribute keys to target attribute values.""" -class BrowserRDPApplicationDestinationPublicDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class BrowserRDPApplicationDestinationPublicDestination(BaseModel): """A public hostname that Access will secure. Public destinations support sub-domain and path. Wildcard '*' can be used in the definition. """ - overrides: Optional[List[BrowserRDPApplicationDestinationPublicDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -4002,19 +4047,6 @@ class BrowserRDPApplicationDestinationViaMcpServerPortalDestination(BaseModel): type: Optional[Literal["via_mcp_server_portal"]] = None -class BrowserRDPApplicationDestinationWorkerDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class BrowserRDPApplicationDestinationWorkerDestination(BaseModel): """A specific Cloudflare Worker that Access will secure. @@ -4026,7 +4058,7 @@ class BrowserRDPApplicationDestinationWorkerDestination(BaseModel): worker_id: str """The ID of the Cloudflare Worker to protect with Access.""" - overrides: Optional[List[BrowserRDPApplicationDestinationWorkerDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -4034,19 +4066,6 @@ class BrowserRDPApplicationDestinationWorkerDestination(BaseModel): """ -class BrowserRDPApplicationDestinationPreviewWorkerDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class BrowserRDPApplicationDestinationPreviewWorkerDestination(BaseModel): """A specific Cloudflare Worker whose preview deployments Access will secure. @@ -4061,7 +4080,7 @@ class BrowserRDPApplicationDestinationPreviewWorkerDestination(BaseModel): Access. """ - overrides: Optional[List[BrowserRDPApplicationDestinationPreviewWorkerDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -4069,19 +4088,6 @@ class BrowserRDPApplicationDestinationPreviewWorkerDestination(BaseModel): """ -class BrowserRDPApplicationDestinationAllWorkersDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class BrowserRDPApplicationDestinationAllWorkersDestination(BaseModel): """ Protects all Cloudflare Workers on the account with Access, including their preview deployments. At most one destination of this type can exist per account. The `worker`, `preview_worker`, `all_preview_workers`, and `public` destination types take precedence, so you can create separate applications to override the policies for specific Workers, their previews, or specific paths. @@ -4089,7 +4095,7 @@ class BrowserRDPApplicationDestinationAllWorkersDestination(BaseModel): type: Literal["all_workers"] - overrides: Optional[List[BrowserRDPApplicationDestinationAllWorkersDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -4097,19 +4103,6 @@ class BrowserRDPApplicationDestinationAllWorkersDestination(BaseModel): """ -class BrowserRDPApplicationDestinationAllPreviewWorkersDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class BrowserRDPApplicationDestinationAllPreviewWorkersDestination(BaseModel): """ Protects the preview deployments of all Cloudflare Workers on the account with Access. At most one destination of this type can exist per account. The `worker`, `preview_worker`, and `public` destination types take precedence, so you can create separate applications to override the policies for specific Workers, their previews, or specific paths. @@ -4117,7 +4110,7 @@ class BrowserRDPApplicationDestinationAllPreviewWorkersDestination(BaseModel): type: Literal["all_preview_workers"] - overrides: Optional[List[BrowserRDPApplicationDestinationAllPreviewWorkersDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -4311,6 +4304,13 @@ class BrowserRDPApplicationPolicy(BaseModel): name: Optional[str] = None """The name of the Access policy.""" + policy_resolution_account_id: Optional[str] = None + """ + The account ID used to resolve policy resources and identity for cross-account + WARP authentication. The account must be trusted by the account that owns this + policy. + """ + precedence: Optional[int] = None """The order of execution for this policy. @@ -4604,7 +4604,7 @@ class BrowserRDPApplication(BaseModel): """The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), - ms, s, m, h. Note: unsupported for infrastructure type applications. + ms, s, m, h. """ skip_interstitial: Optional[bool] = None @@ -4625,26 +4625,13 @@ class BrowserRDPApplication(BaseModel): """ -class McpServerApplicationDestinationPublicDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class McpServerApplicationDestinationPublicDestination(BaseModel): """A public hostname that Access will secure. Public destinations support sub-domain and path. Wildcard '*' can be used in the definition. """ - overrides: Optional[List[McpServerApplicationDestinationPublicDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -4698,19 +4685,6 @@ class McpServerApplicationDestinationViaMcpServerPortalDestination(BaseModel): type: Optional[Literal["via_mcp_server_portal"]] = None -class McpServerApplicationDestinationWorkerDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class McpServerApplicationDestinationWorkerDestination(BaseModel): """A specific Cloudflare Worker that Access will secure. @@ -4722,7 +4696,7 @@ class McpServerApplicationDestinationWorkerDestination(BaseModel): worker_id: str """The ID of the Cloudflare Worker to protect with Access.""" - overrides: Optional[List[McpServerApplicationDestinationWorkerDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -4730,19 +4704,6 @@ class McpServerApplicationDestinationWorkerDestination(BaseModel): """ -class McpServerApplicationDestinationPreviewWorkerDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class McpServerApplicationDestinationPreviewWorkerDestination(BaseModel): """A specific Cloudflare Worker whose preview deployments Access will secure. @@ -4757,7 +4718,7 @@ class McpServerApplicationDestinationPreviewWorkerDestination(BaseModel): Access. """ - overrides: Optional[List[McpServerApplicationDestinationPreviewWorkerDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -4765,19 +4726,6 @@ class McpServerApplicationDestinationPreviewWorkerDestination(BaseModel): """ -class McpServerApplicationDestinationAllWorkersDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class McpServerApplicationDestinationAllWorkersDestination(BaseModel): """ Protects all Cloudflare Workers on the account with Access, including their preview deployments. At most one destination of this type can exist per account. The `worker`, `preview_worker`, `all_preview_workers`, and `public` destination types take precedence, so you can create separate applications to override the policies for specific Workers, their previews, or specific paths. @@ -4785,7 +4733,7 @@ class McpServerApplicationDestinationAllWorkersDestination(BaseModel): type: Literal["all_workers"] - overrides: Optional[List[McpServerApplicationDestinationAllWorkersDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -4793,19 +4741,6 @@ class McpServerApplicationDestinationAllWorkersDestination(BaseModel): """ -class McpServerApplicationDestinationAllPreviewWorkersDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class McpServerApplicationDestinationAllPreviewWorkersDestination(BaseModel): """ Protects the preview deployments of all Cloudflare Workers on the account with Access. At most one destination of this type can exist per account. The `worker`, `preview_worker`, and `public` destination types take precedence, so you can create separate applications to override the policies for specific Workers, their previews, or specific paths. @@ -4813,7 +4748,7 @@ class McpServerApplicationDestinationAllPreviewWorkersDestination(BaseModel): type: Literal["all_preview_workers"] - overrides: Optional[List[McpServerApplicationDestinationAllPreviewWorkersDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -4987,6 +4922,13 @@ class McpServerApplicationPolicy(BaseModel): name: Optional[str] = None """The name of the Access policy.""" + policy_resolution_account_id: Optional[str] = None + """ + The account ID used to resolve policy resources and identity for cross-account + WARP authentication. The account must be trusted by the account that owns this + policy. + """ + precedence: Optional[int] = None """The order of execution for this policy. @@ -5219,7 +5161,7 @@ class McpServerApplication(BaseModel): """The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), - ms, s, m, h. Note: unsupported for infrastructure type applications. + ms, s, m, h. """ tags: Optional[List[str]] = None @@ -5229,26 +5171,13 @@ class McpServerApplication(BaseModel): """ -class McpServerPortalApplicationDestinationPublicDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class McpServerPortalApplicationDestinationPublicDestination(BaseModel): """A public hostname that Access will secure. Public destinations support sub-domain and path. Wildcard '*' can be used in the definition. """ - overrides: Optional[List[McpServerPortalApplicationDestinationPublicDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -5302,19 +5231,6 @@ class McpServerPortalApplicationDestinationViaMcpServerPortalDestination(BaseMod type: Optional[Literal["via_mcp_server_portal"]] = None -class McpServerPortalApplicationDestinationWorkerDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class McpServerPortalApplicationDestinationWorkerDestination(BaseModel): """A specific Cloudflare Worker that Access will secure. @@ -5326,7 +5242,7 @@ class McpServerPortalApplicationDestinationWorkerDestination(BaseModel): worker_id: str """The ID of the Cloudflare Worker to protect with Access.""" - overrides: Optional[List[McpServerPortalApplicationDestinationWorkerDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -5334,19 +5250,6 @@ class McpServerPortalApplicationDestinationWorkerDestination(BaseModel): """ -class McpServerPortalApplicationDestinationPreviewWorkerDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class McpServerPortalApplicationDestinationPreviewWorkerDestination(BaseModel): """A specific Cloudflare Worker whose preview deployments Access will secure. @@ -5361,7 +5264,7 @@ class McpServerPortalApplicationDestinationPreviewWorkerDestination(BaseModel): Access. """ - overrides: Optional[List[McpServerPortalApplicationDestinationPreviewWorkerDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -5369,19 +5272,6 @@ class McpServerPortalApplicationDestinationPreviewWorkerDestination(BaseModel): """ -class McpServerPortalApplicationDestinationAllWorkersDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class McpServerPortalApplicationDestinationAllWorkersDestination(BaseModel): """ Protects all Cloudflare Workers on the account with Access, including their preview deployments. At most one destination of this type can exist per account. The `worker`, `preview_worker`, `all_preview_workers`, and `public` destination types take precedence, so you can create separate applications to override the policies for specific Workers, their previews, or specific paths. @@ -5389,7 +5279,7 @@ class McpServerPortalApplicationDestinationAllWorkersDestination(BaseModel): type: Literal["all_workers"] - overrides: Optional[List[McpServerPortalApplicationDestinationAllWorkersDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -5397,19 +5287,6 @@ class McpServerPortalApplicationDestinationAllWorkersDestination(BaseModel): """ -class McpServerPortalApplicationDestinationAllPreviewWorkersDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class McpServerPortalApplicationDestinationAllPreviewWorkersDestination(BaseModel): """ Protects the preview deployments of all Cloudflare Workers on the account with Access. At most one destination of this type can exist per account. The `worker`, `preview_worker`, and `public` destination types take precedence, so you can create separate applications to override the policies for specific Workers, their previews, or specific paths. @@ -5417,7 +5294,7 @@ class McpServerPortalApplicationDestinationAllPreviewWorkersDestination(BaseMode type: Literal["all_preview_workers"] - overrides: Optional[List[McpServerPortalApplicationDestinationAllPreviewWorkersDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -5591,6 +5468,13 @@ class McpServerPortalApplicationPolicy(BaseModel): name: Optional[str] = None """The name of the Access policy.""" + policy_resolution_account_id: Optional[str] = None + """ + The account ID used to resolve policy resources and identity for cross-account + WARP authentication. The account must be trusted by the account that owns this + policy. + """ + precedence: Optional[int] = None """The order of execution for this policy. @@ -5829,7 +5713,7 @@ class McpServerPortalApplication(BaseModel): """The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), - ms, s, m, h. Note: unsupported for infrastructure type applications. + ms, s, m, h. """ tags: Optional[List[str]] = None @@ -5840,6 +5724,7 @@ class McpServerPortalApplication(BaseModel): ApplicationListResponse: TypeAlias = Union[ + EndUserApplication, SelfHostedApplication, SaaSApplication, BrowserSSHApplication, diff --git a/src/cloudflare/types/zero_trust/access/application_type.py b/src/cloudflare/types/zero_trust/access/application_type.py index bacee5f7300..a43f8e9bc86 100644 --- a/src/cloudflare/types/zero_trust/access/application_type.py +++ b/src/cloudflare/types/zero_trust/access/application_type.py @@ -6,6 +6,7 @@ ApplicationType: TypeAlias = Literal[ "self_hosted", + "end_user", "saas", "ssh", "vnc", diff --git a/src/cloudflare/types/zero_trust/access/application_update_params.py b/src/cloudflare/types/zero_trust/access/application_update_params.py index c1950c9baa7..f7f4d3d43c7 100644 --- a/src/cloudflare/types/zero_trust/access/application_update_params.py +++ b/src/cloudflare/types/zero_trust/access/application_update_params.py @@ -15,6 +15,7 @@ from .self_hosted_domains import SelfHostedDomains from .approval_group_param import ApprovalGroupParam from .scim_config_mapping_param import SCIMConfigMappingParam +from .destination_override_param import DestinationOverrideParam from .applications.access_rule_param import AccessRuleParam from .scim_config_authentication_oauth2_param import SCIMConfigAuthenticationOauth2Param from .scim_config_authentication_http_basic_param import SCIMConfigAuthenticationHTTPBasicParam @@ -22,20 +23,25 @@ __all__ = [ "ApplicationUpdateParams", + "AccessEndUserProps", + "AccessEndUserPropsOAuthConfiguration", + "AccessEndUserPropsOAuthConfigurationDynamicClientRegistration", + "AccessEndUserPropsOAuthConfigurationGrant", + "AccessEndUserPropsDestination", + "AccessEndUserPropsDestinationAccessEndUserPublicDestination", + "AccessEndUserPropsDestinationAccessEndUserWorkerDestination", + "AccessEndUserPropsDestinationAccessEndUserPreviewWorkerDestination", + "AccessEndUserPropsDestinationAccessEndUserAllWorkersDestination", + "AccessEndUserPropsDestinationAccessEndUserAllPreviewWorkersDestination", "SelfHostedApplication", "SelfHostedApplicationDestination", "SelfHostedApplicationDestinationPublicDestination", - "SelfHostedApplicationDestinationPublicDestinationOverride", "SelfHostedApplicationDestinationPrivateDestination", "SelfHostedApplicationDestinationViaMcpServerPortalDestination", "SelfHostedApplicationDestinationWorkerDestination", - "SelfHostedApplicationDestinationWorkerDestinationOverride", "SelfHostedApplicationDestinationPreviewWorkerDestination", - "SelfHostedApplicationDestinationPreviewWorkerDestinationOverride", "SelfHostedApplicationDestinationAllWorkersDestination", - "SelfHostedApplicationDestinationAllWorkersDestinationOverride", "SelfHostedApplicationDestinationAllPreviewWorkersDestination", - "SelfHostedApplicationDestinationAllPreviewWorkersDestinationOverride", "SelfHostedApplicationMfaConfig", "SelfHostedApplicationOAuthConfiguration", "SelfHostedApplicationOAuthConfigurationDynamicClientRegistration", @@ -67,17 +73,12 @@ "BrowserSSHApplication", "BrowserSSHApplicationDestination", "BrowserSSHApplicationDestinationPublicDestination", - "BrowserSSHApplicationDestinationPublicDestinationOverride", "BrowserSSHApplicationDestinationPrivateDestination", "BrowserSSHApplicationDestinationViaMcpServerPortalDestination", "BrowserSSHApplicationDestinationWorkerDestination", - "BrowserSSHApplicationDestinationWorkerDestinationOverride", "BrowserSSHApplicationDestinationPreviewWorkerDestination", - "BrowserSSHApplicationDestinationPreviewWorkerDestinationOverride", "BrowserSSHApplicationDestinationAllWorkersDestination", - "BrowserSSHApplicationDestinationAllWorkersDestinationOverride", "BrowserSSHApplicationDestinationAllPreviewWorkersDestination", - "BrowserSSHApplicationDestinationAllPreviewWorkersDestinationOverride", "BrowserSSHApplicationMfaConfig", "BrowserSSHApplicationOAuthConfiguration", "BrowserSSHApplicationOAuthConfigurationDynamicClientRegistration", @@ -96,17 +97,12 @@ "BrowserVNCApplication", "BrowserVNCApplicationDestination", "BrowserVNCApplicationDestinationPublicDestination", - "BrowserVNCApplicationDestinationPublicDestinationOverride", "BrowserVNCApplicationDestinationPrivateDestination", "BrowserVNCApplicationDestinationViaMcpServerPortalDestination", "BrowserVNCApplicationDestinationWorkerDestination", - "BrowserVNCApplicationDestinationWorkerDestinationOverride", "BrowserVNCApplicationDestinationPreviewWorkerDestination", - "BrowserVNCApplicationDestinationPreviewWorkerDestinationOverride", "BrowserVNCApplicationDestinationAllWorkersDestination", - "BrowserVNCApplicationDestinationAllWorkersDestinationOverride", "BrowserVNCApplicationDestinationAllPreviewWorkersDestination", - "BrowserVNCApplicationDestinationAllPreviewWorkersDestinationOverride", "BrowserVNCApplicationMfaConfig", "BrowserVNCApplicationOAuthConfiguration", "BrowserVNCApplicationOAuthConfigurationDynamicClientRegistration", @@ -182,17 +178,12 @@ "BrowserRDPApplicationTargetCriterionRequireTargetAttributes", "BrowserRDPApplicationDestination", "BrowserRDPApplicationDestinationPublicDestination", - "BrowserRDPApplicationDestinationPublicDestinationOverride", "BrowserRDPApplicationDestinationPrivateDestination", "BrowserRDPApplicationDestinationViaMcpServerPortalDestination", "BrowserRDPApplicationDestinationWorkerDestination", - "BrowserRDPApplicationDestinationWorkerDestinationOverride", "BrowserRDPApplicationDestinationPreviewWorkerDestination", - "BrowserRDPApplicationDestinationPreviewWorkerDestinationOverride", "BrowserRDPApplicationDestinationAllWorkersDestination", - "BrowserRDPApplicationDestinationAllWorkersDestinationOverride", "BrowserRDPApplicationDestinationAllPreviewWorkersDestination", - "BrowserRDPApplicationDestinationAllPreviewWorkersDestinationOverride", "BrowserRDPApplicationMfaConfig", "BrowserRDPApplicationOAuthConfiguration", "BrowserRDPApplicationOAuthConfigurationDynamicClientRegistration", @@ -211,17 +202,12 @@ "McpServerApplication", "McpServerApplicationDestination", "McpServerApplicationDestinationPublicDestination", - "McpServerApplicationDestinationPublicDestinationOverride", "McpServerApplicationDestinationPrivateDestination", "McpServerApplicationDestinationViaMcpServerPortalDestination", "McpServerApplicationDestinationWorkerDestination", - "McpServerApplicationDestinationWorkerDestinationOverride", "McpServerApplicationDestinationPreviewWorkerDestination", - "McpServerApplicationDestinationPreviewWorkerDestinationOverride", "McpServerApplicationDestinationAllWorkersDestination", - "McpServerApplicationDestinationAllWorkersDestinationOverride", "McpServerApplicationDestinationAllPreviewWorkersDestination", - "McpServerApplicationDestinationAllPreviewWorkersDestinationOverride", "McpServerApplicationOAuthConfiguration", "McpServerApplicationOAuthConfigurationDynamicClientRegistration", "McpServerApplicationOAuthConfigurationGrant", @@ -239,17 +225,12 @@ "McpServerPortalApplication", "McpServerPortalApplicationDestination", "McpServerPortalApplicationDestinationPublicDestination", - "McpServerPortalApplicationDestinationPublicDestinationOverride", "McpServerPortalApplicationDestinationPrivateDestination", "McpServerPortalApplicationDestinationViaMcpServerPortalDestination", "McpServerPortalApplicationDestinationWorkerDestination", - "McpServerPortalApplicationDestinationWorkerDestinationOverride", "McpServerPortalApplicationDestinationPreviewWorkerDestination", - "McpServerPortalApplicationDestinationPreviewWorkerDestinationOverride", "McpServerPortalApplicationDestinationAllWorkersDestination", - "McpServerPortalApplicationDestinationAllWorkersDestinationOverride", "McpServerPortalApplicationDestinationAllPreviewWorkersDestination", - "McpServerPortalApplicationDestinationAllPreviewWorkersDestinationOverride", "McpServerPortalApplicationOAuthConfiguration", "McpServerPortalApplicationOAuthConfigurationDynamicClientRegistration", "McpServerPortalApplicationOAuthConfigurationGrant", @@ -267,6 +248,200 @@ ] +class AccessEndUserProps(TypedDict, total=False): + oauth_configuration: Required[AccessEndUserPropsOAuthConfiguration] + """ + **Beta:** Optional configuration for managing an OAuth authorization flow + controlled by Access. When set, Access will act as the OAuth authorization + server for this application. Only compatible with OAuth clients that support + [RFC 8707](https://datatracker.ietf.org/doc/html/rfc8707) (Resource Indicators + for OAuth 2.0). This feature is currently in beta. + """ + + type: Required[ + Literal[ + "self_hosted", + "end_user", + "saas", + "ssh", + "vnc", + "app_launcher", + "warp", + "biso", + "bookmark", + "dash_sso", + "infrastructure", + "rdp", + "mcp", + "mcp_portal", + "proxy_endpoint", + ] + ] + """The application type.""" + + user_populations: Required[SequenceNotStr[str]] + """The single user population associated with this application.""" + + account_id: str + """The Account ID to use for this endpoint. Mutually exclusive with the Zone ID.""" + + zone_id: str + """The Zone ID to use for this endpoint. Mutually exclusive with the Account ID.""" + + allowed_idps: SequenceNotStr[AllowedIdPs] + """The identity providers your users can select when connecting to this + application. + + Defaults to all IdPs configured in your account. + """ + + destinations: Iterable[AccessEndUserPropsDestination] + """Public hostname and Workers destinations secured by Access.""" + + domain: str + """The primary hostname and path secured by Access. + + This domain will be displayed if the app is visible in the App Launcher. + """ + + name: str + """The name of the application.""" + + self_hosted_domains: SequenceNotStr[SelfHostedDomains] + """List of public domains that Access will secure. + + This field is deprecated in favor of `destinations` and will be supported until + **November 21, 2025.** If `destinations` are provided, then + `self_hosted_domains` will be ignored. + """ + + +class AccessEndUserPropsOAuthConfigurationDynamicClientRegistration(TypedDict, total=False): + """Settings for OAuth dynamic client registration.""" + + allow_any_on_localhost: bool + """Allows any client with redirect URIs on localhost.""" + + allow_any_on_loopback: bool + """Allows any client with redirect URIs on 127.0.0.1.""" + + allowed_uris: SequenceNotStr[str] + """The URIs that are allowed as redirect URIs for dynamically registered clients. + + HTTP and HTTPS paths may end in `/*` to match all sub-paths. Custom-scheme URIs + must be explicitly configured and match exactly. + """ + + enabled: bool + """Whether dynamic client registration is enabled.""" + + +class AccessEndUserPropsOAuthConfigurationGrant(TypedDict, total=False): + """Settings for OAuth grant behavior.""" + + access_token_lifetime: str + """The lifetime of the access token. + + Must be in the format `300ms` or `2h45m`. Valid time units are ns, us (or µs), + ms, s, m, h. + """ + + session_duration: str + """The duration of the OAuth session. + + Must be in the format `300ms` or `2h45m`. Valid time units are ns, us (or µs), + ms, s, m, h. + """ + + +class AccessEndUserPropsOAuthConfiguration(TypedDict, total=False): + """ + **Beta:** Optional configuration for managing an OAuth authorization flow controlled by Access. When set, Access will act as the OAuth authorization server for this application. Only compatible with OAuth clients that support [RFC 8707](https://datatracker.ietf.org/doc/html/rfc8707) (Resource Indicators for OAuth 2.0). This feature is currently in beta. + """ + + dynamic_client_registration: AccessEndUserPropsOAuthConfigurationDynamicClientRegistration + """Settings for OAuth dynamic client registration.""" + + enabled: Literal[True] + """Managed OAuth is required for end user applications and cannot be disabled.""" + + grant: AccessEndUserPropsOAuthConfigurationGrant + """Settings for OAuth grant behavior.""" + + +class AccessEndUserPropsDestinationAccessEndUserPublicDestination(TypedDict, total=False): + uri: Required[str] + """The public hostname and optional path to secure.""" + + overrides: Iterable[DestinationOverrideParam] + """Rules that override how Access handles requests to this destination. + + Each rule can make a matching path public, bypassing Access authentication. + Overrides are supported for public destinations and Worker destinations. + """ + + type: Literal["public"] + + +class AccessEndUserPropsDestinationAccessEndUserWorkerDestination(TypedDict, total=False): + type: Required[Literal["worker"]] + + worker_id: Required[str] + """The ID of the Cloudflare Worker to secure.""" + + overrides: Iterable[DestinationOverrideParam] + """Rules that override how Access handles requests to this destination. + + Each rule can make a matching path public, bypassing Access authentication. + Overrides are supported for public destinations and Worker destinations. + """ + + +class AccessEndUserPropsDestinationAccessEndUserPreviewWorkerDestination(TypedDict, total=False): + type: Required[Literal["preview_worker"]] + + worker_id: Required[str] + """The ID of the Cloudflare Worker whose previews to secure.""" + + overrides: Iterable[DestinationOverrideParam] + """Rules that override how Access handles requests to this destination. + + Each rule can make a matching path public, bypassing Access authentication. + Overrides are supported for public destinations and Worker destinations. + """ + + +class AccessEndUserPropsDestinationAccessEndUserAllWorkersDestination(TypedDict, total=False): + type: Required[Literal["all_workers"]] + + overrides: Iterable[DestinationOverrideParam] + """Rules that override how Access handles requests to this destination. + + Each rule can make a matching path public, bypassing Access authentication. + Overrides are supported for public destinations and Worker destinations. + """ + + +class AccessEndUserPropsDestinationAccessEndUserAllPreviewWorkersDestination(TypedDict, total=False): + type: Required[Literal["all_preview_workers"]] + + overrides: Iterable[DestinationOverrideParam] + """Rules that override how Access handles requests to this destination. + + Each rule can make a matching path public, bypassing Access authentication. + Overrides are supported for public destinations and Worker destinations. + """ + + +AccessEndUserPropsDestination: TypeAlias = Union[ + AccessEndUserPropsDestinationAccessEndUserPublicDestination, + AccessEndUserPropsDestinationAccessEndUserWorkerDestination, + AccessEndUserPropsDestinationAccessEndUserPreviewWorkerDestination, + AccessEndUserPropsDestinationAccessEndUserAllWorkersDestination, + AccessEndUserPropsDestinationAccessEndUserAllPreviewWorkersDestination, +] + + class SelfHostedApplication(TypedDict, total=False): domain: Required[str] """The primary hostname and path secured by Access. @@ -438,7 +613,7 @@ class SelfHostedApplication(TypedDict, total=False): """The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), - ms, s, m, h. Note: unsupported for infrastructure type applications. + ms, s, m, h. """ skip_interstitial: bool @@ -459,26 +634,13 @@ class SelfHostedApplication(TypedDict, total=False): """ -class SelfHostedApplicationDestinationPublicDestinationOverride(TypedDict, total=False): - behavior: Required[Literal["public"]] - """The behavior to apply to matching requests.""" - - path_pattern: Required[str] - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class SelfHostedApplicationDestinationPublicDestination(TypedDict, total=False): """A public hostname that Access will secure. Public destinations support sub-domain and path. Wildcard '*' can be used in the definition. """ - overrides: Iterable[SelfHostedApplicationDestinationPublicDestinationOverride] + overrides: Iterable[DestinationOverrideParam] """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -532,19 +694,6 @@ class SelfHostedApplicationDestinationViaMcpServerPortalDestination(TypedDict, t type: Literal["via_mcp_server_portal"] -class SelfHostedApplicationDestinationWorkerDestinationOverride(TypedDict, total=False): - behavior: Required[Literal["public"]] - """The behavior to apply to matching requests.""" - - path_pattern: Required[str] - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class SelfHostedApplicationDestinationWorkerDestination(TypedDict, total=False): """A specific Cloudflare Worker that Access will secure. @@ -556,7 +705,7 @@ class SelfHostedApplicationDestinationWorkerDestination(TypedDict, total=False): worker_id: Required[str] """The ID of the Cloudflare Worker to protect with Access.""" - overrides: Iterable[SelfHostedApplicationDestinationWorkerDestinationOverride] + overrides: Iterable[DestinationOverrideParam] """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -564,19 +713,6 @@ class SelfHostedApplicationDestinationWorkerDestination(TypedDict, total=False): """ -class SelfHostedApplicationDestinationPreviewWorkerDestinationOverride(TypedDict, total=False): - behavior: Required[Literal["public"]] - """The behavior to apply to matching requests.""" - - path_pattern: Required[str] - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class SelfHostedApplicationDestinationPreviewWorkerDestination(TypedDict, total=False): """A specific Cloudflare Worker whose preview deployments Access will secure. @@ -591,7 +727,7 @@ class SelfHostedApplicationDestinationPreviewWorkerDestination(TypedDict, total= Access. """ - overrides: Iterable[SelfHostedApplicationDestinationPreviewWorkerDestinationOverride] + overrides: Iterable[DestinationOverrideParam] """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -599,19 +735,6 @@ class SelfHostedApplicationDestinationPreviewWorkerDestination(TypedDict, total= """ -class SelfHostedApplicationDestinationAllWorkersDestinationOverride(TypedDict, total=False): - behavior: Required[Literal["public"]] - """The behavior to apply to matching requests.""" - - path_pattern: Required[str] - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class SelfHostedApplicationDestinationAllWorkersDestination(TypedDict, total=False): """ Protects all Cloudflare Workers on the account with Access, including their preview deployments. At most one destination of this type can exist per account. The `worker`, `preview_worker`, `all_preview_workers`, and `public` destination types take precedence, so you can create separate applications to override the policies for specific Workers, their previews, or specific paths. @@ -619,7 +742,7 @@ class SelfHostedApplicationDestinationAllWorkersDestination(TypedDict, total=Fal type: Required[Literal["all_workers"]] - overrides: Iterable[SelfHostedApplicationDestinationAllWorkersDestinationOverride] + overrides: Iterable[DestinationOverrideParam] """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -627,19 +750,6 @@ class SelfHostedApplicationDestinationAllWorkersDestination(TypedDict, total=Fal """ -class SelfHostedApplicationDestinationAllPreviewWorkersDestinationOverride(TypedDict, total=False): - behavior: Required[Literal["public"]] - """The behavior to apply to matching requests.""" - - path_pattern: Required[str] - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class SelfHostedApplicationDestinationAllPreviewWorkersDestination(TypedDict, total=False): """ Protects the preview deployments of all Cloudflare Workers on the account with Access. At most one destination of this type can exist per account. The `worker`, `preview_worker`, and `public` destination types take precedence, so you can create separate applications to override the policies for specific Workers, their previews, or specific paths. @@ -647,7 +757,7 @@ class SelfHostedApplicationDestinationAllPreviewWorkersDestination(TypedDict, to type: Required[Literal["all_preview_workers"]] - overrides: Iterable[SelfHostedApplicationDestinationAllPreviewWorkersDestinationOverride] + overrides: Iterable[DestinationOverrideParam] """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -1238,6 +1348,7 @@ class BrowserSSHApplication(TypedDict, total=False): type: Required[ Literal[ "self_hosted", + "end_user", "saas", "ssh", "vnc", @@ -1416,7 +1527,7 @@ class BrowserSSHApplication(TypedDict, total=False): """The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), - ms, s, m, h. Note: unsupported for infrastructure type applications. + ms, s, m, h. """ skip_interstitial: bool @@ -1437,26 +1548,13 @@ class BrowserSSHApplication(TypedDict, total=False): """ -class BrowserSSHApplicationDestinationPublicDestinationOverride(TypedDict, total=False): - behavior: Required[Literal["public"]] - """The behavior to apply to matching requests.""" - - path_pattern: Required[str] - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class BrowserSSHApplicationDestinationPublicDestination(TypedDict, total=False): """A public hostname that Access will secure. Public destinations support sub-domain and path. Wildcard '*' can be used in the definition. """ - overrides: Iterable[BrowserSSHApplicationDestinationPublicDestinationOverride] + overrides: Iterable[DestinationOverrideParam] """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -1510,19 +1608,6 @@ class BrowserSSHApplicationDestinationViaMcpServerPortalDestination(TypedDict, t type: Literal["via_mcp_server_portal"] -class BrowserSSHApplicationDestinationWorkerDestinationOverride(TypedDict, total=False): - behavior: Required[Literal["public"]] - """The behavior to apply to matching requests.""" - - path_pattern: Required[str] - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class BrowserSSHApplicationDestinationWorkerDestination(TypedDict, total=False): """A specific Cloudflare Worker that Access will secure. @@ -1534,7 +1619,7 @@ class BrowserSSHApplicationDestinationWorkerDestination(TypedDict, total=False): worker_id: Required[str] """The ID of the Cloudflare Worker to protect with Access.""" - overrides: Iterable[BrowserSSHApplicationDestinationWorkerDestinationOverride] + overrides: Iterable[DestinationOverrideParam] """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -1542,19 +1627,6 @@ class BrowserSSHApplicationDestinationWorkerDestination(TypedDict, total=False): """ -class BrowserSSHApplicationDestinationPreviewWorkerDestinationOverride(TypedDict, total=False): - behavior: Required[Literal["public"]] - """The behavior to apply to matching requests.""" - - path_pattern: Required[str] - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class BrowserSSHApplicationDestinationPreviewWorkerDestination(TypedDict, total=False): """A specific Cloudflare Worker whose preview deployments Access will secure. @@ -1569,7 +1641,7 @@ class BrowserSSHApplicationDestinationPreviewWorkerDestination(TypedDict, total= Access. """ - overrides: Iterable[BrowserSSHApplicationDestinationPreviewWorkerDestinationOverride] + overrides: Iterable[DestinationOverrideParam] """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -1577,19 +1649,6 @@ class BrowserSSHApplicationDestinationPreviewWorkerDestination(TypedDict, total= """ -class BrowserSSHApplicationDestinationAllWorkersDestinationOverride(TypedDict, total=False): - behavior: Required[Literal["public"]] - """The behavior to apply to matching requests.""" - - path_pattern: Required[str] - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class BrowserSSHApplicationDestinationAllWorkersDestination(TypedDict, total=False): """ Protects all Cloudflare Workers on the account with Access, including their preview deployments. At most one destination of this type can exist per account. The `worker`, `preview_worker`, `all_preview_workers`, and `public` destination types take precedence, so you can create separate applications to override the policies for specific Workers, their previews, or specific paths. @@ -1597,7 +1656,7 @@ class BrowserSSHApplicationDestinationAllWorkersDestination(TypedDict, total=Fal type: Required[Literal["all_workers"]] - overrides: Iterable[BrowserSSHApplicationDestinationAllWorkersDestinationOverride] + overrides: Iterable[DestinationOverrideParam] """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -1605,19 +1664,6 @@ class BrowserSSHApplicationDestinationAllWorkersDestination(TypedDict, total=Fal """ -class BrowserSSHApplicationDestinationAllPreviewWorkersDestinationOverride(TypedDict, total=False): - behavior: Required[Literal["public"]] - """The behavior to apply to matching requests.""" - - path_pattern: Required[str] - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class BrowserSSHApplicationDestinationAllPreviewWorkersDestination(TypedDict, total=False): """ Protects the preview deployments of all Cloudflare Workers on the account with Access. At most one destination of this type can exist per account. The `worker`, `preview_worker`, and `public` destination types take precedence, so you can create separate applications to override the policies for specific Workers, their previews, or specific paths. @@ -1625,7 +1671,7 @@ class BrowserSSHApplicationDestinationAllPreviewWorkersDestination(TypedDict, to type: Required[Literal["all_preview_workers"]] - overrides: Iterable[BrowserSSHApplicationDestinationAllPreviewWorkersDestinationOverride] + overrides: Iterable[DestinationOverrideParam] """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -1944,6 +1990,7 @@ class BrowserVNCApplication(TypedDict, total=False): type: Required[ Literal[ "self_hosted", + "end_user", "saas", "ssh", "vnc", @@ -2122,7 +2169,7 @@ class BrowserVNCApplication(TypedDict, total=False): """The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), - ms, s, m, h. Note: unsupported for infrastructure type applications. + ms, s, m, h. """ skip_interstitial: bool @@ -2143,26 +2190,13 @@ class BrowserVNCApplication(TypedDict, total=False): """ -class BrowserVNCApplicationDestinationPublicDestinationOverride(TypedDict, total=False): - behavior: Required[Literal["public"]] - """The behavior to apply to matching requests.""" - - path_pattern: Required[str] - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class BrowserVNCApplicationDestinationPublicDestination(TypedDict, total=False): """A public hostname that Access will secure. Public destinations support sub-domain and path. Wildcard '*' can be used in the definition. """ - overrides: Iterable[BrowserVNCApplicationDestinationPublicDestinationOverride] + overrides: Iterable[DestinationOverrideParam] """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -2216,19 +2250,6 @@ class BrowserVNCApplicationDestinationViaMcpServerPortalDestination(TypedDict, t type: Literal["via_mcp_server_portal"] -class BrowserVNCApplicationDestinationWorkerDestinationOverride(TypedDict, total=False): - behavior: Required[Literal["public"]] - """The behavior to apply to matching requests.""" - - path_pattern: Required[str] - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class BrowserVNCApplicationDestinationWorkerDestination(TypedDict, total=False): """A specific Cloudflare Worker that Access will secure. @@ -2240,7 +2261,7 @@ class BrowserVNCApplicationDestinationWorkerDestination(TypedDict, total=False): worker_id: Required[str] """The ID of the Cloudflare Worker to protect with Access.""" - overrides: Iterable[BrowserVNCApplicationDestinationWorkerDestinationOverride] + overrides: Iterable[DestinationOverrideParam] """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -2248,19 +2269,6 @@ class BrowserVNCApplicationDestinationWorkerDestination(TypedDict, total=False): """ -class BrowserVNCApplicationDestinationPreviewWorkerDestinationOverride(TypedDict, total=False): - behavior: Required[Literal["public"]] - """The behavior to apply to matching requests.""" - - path_pattern: Required[str] - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class BrowserVNCApplicationDestinationPreviewWorkerDestination(TypedDict, total=False): """A specific Cloudflare Worker whose preview deployments Access will secure. @@ -2275,7 +2283,7 @@ class BrowserVNCApplicationDestinationPreviewWorkerDestination(TypedDict, total= Access. """ - overrides: Iterable[BrowserVNCApplicationDestinationPreviewWorkerDestinationOverride] + overrides: Iterable[DestinationOverrideParam] """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -2283,19 +2291,6 @@ class BrowserVNCApplicationDestinationPreviewWorkerDestination(TypedDict, total= """ -class BrowserVNCApplicationDestinationAllWorkersDestinationOverride(TypedDict, total=False): - behavior: Required[Literal["public"]] - """The behavior to apply to matching requests.""" - - path_pattern: Required[str] - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class BrowserVNCApplicationDestinationAllWorkersDestination(TypedDict, total=False): """ Protects all Cloudflare Workers on the account with Access, including their preview deployments. At most one destination of this type can exist per account. The `worker`, `preview_worker`, `all_preview_workers`, and `public` destination types take precedence, so you can create separate applications to override the policies for specific Workers, their previews, or specific paths. @@ -2303,7 +2298,7 @@ class BrowserVNCApplicationDestinationAllWorkersDestination(TypedDict, total=Fal type: Required[Literal["all_workers"]] - overrides: Iterable[BrowserVNCApplicationDestinationAllWorkersDestinationOverride] + overrides: Iterable[DestinationOverrideParam] """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -2311,19 +2306,6 @@ class BrowserVNCApplicationDestinationAllWorkersDestination(TypedDict, total=Fal """ -class BrowserVNCApplicationDestinationAllPreviewWorkersDestinationOverride(TypedDict, total=False): - behavior: Required[Literal["public"]] - """The behavior to apply to matching requests.""" - - path_pattern: Required[str] - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class BrowserVNCApplicationDestinationAllPreviewWorkersDestination(TypedDict, total=False): """ Protects the preview deployments of all Cloudflare Workers on the account with Access. At most one destination of this type can exist per account. The `worker`, `preview_worker`, and `public` destination types take precedence, so you can create separate applications to override the policies for specific Workers, their previews, or specific paths. @@ -2331,7 +2313,7 @@ class BrowserVNCApplicationDestinationAllPreviewWorkersDestination(TypedDict, to type: Required[Literal["all_preview_workers"]] - overrides: Iterable[BrowserVNCApplicationDestinationAllPreviewWorkersDestinationOverride] + overrides: Iterable[DestinationOverrideParam] """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -2644,6 +2626,7 @@ class AppLauncherApplication(TypedDict, total=False): type: Required[ Literal[ "self_hosted", + "end_user", "saas", "ssh", "vnc", @@ -2723,7 +2706,7 @@ class AppLauncherApplication(TypedDict, total=False): """The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), - ms, s, m, h. Note: unsupported for infrastructure type applications. + ms, s, m, h. """ skip_app_launcher_login_page: bool @@ -2921,7 +2904,7 @@ class DeviceEnrollmentPermissionsApplication(TypedDict, total=False): """The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), - ms, s, m, h. Note: unsupported for infrastructure type applications. + ms, s, m, h. """ @@ -3091,7 +3074,7 @@ class BrowserIsolationPermissionsApplication(TypedDict, total=False): """The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), - ms, s, m, h. Note: unsupported for infrastructure type applications. + ms, s, m, h. """ @@ -3270,7 +3253,7 @@ class GatewayIdentityProxyEndpointApplication(TypedDict, total=False): """The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), - ms, s, m, h. Note: unsupported for infrastructure type applications. + ms, s, m, h. """ @@ -3563,6 +3546,13 @@ class InfrastructureApplication(TypedDict, total=False): policies: Iterable[InfrastructureApplicationPolicy] """The policies that Access applies to the application.""" + session_duration: str + """The maximum duration of a connection to this application's targets. + + Connections are terminated once it elapses. Must be in the format `30m` or + `2h45m`, in whole seconds. Valid time units are: s, m, h. + """ + class InfrastructureApplicationTargetCriterionExcludeTargetAttributes(TypedDict, total=False): """Hostname selector map for include, require, or exclude rules. @@ -3771,6 +3761,13 @@ class InfrastructureApplicationPolicy(TypedDict, total=False): applications. """ + policy_resolution_account_id: str + """ + The account ID used to resolve policy resources and identity for cross-account + WARP authentication. The account must be trusted by the account that owns this + policy. + """ + require: Iterable[AccessRuleParam] """Rules evaluated with an AND logical operator. @@ -3951,7 +3948,7 @@ class BrowserRDPApplication(TypedDict, total=False): """The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), - ms, s, m, h. Note: unsupported for infrastructure type applications. + ms, s, m, h. """ skip_interstitial: bool @@ -4069,26 +4066,13 @@ class BrowserRDPApplicationTargetCriterion(TypedDict, total=False): """Contains a map of target attribute keys to target attribute values.""" -class BrowserRDPApplicationDestinationPublicDestinationOverride(TypedDict, total=False): - behavior: Required[Literal["public"]] - """The behavior to apply to matching requests.""" - - path_pattern: Required[str] - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class BrowserRDPApplicationDestinationPublicDestination(TypedDict, total=False): """A public hostname that Access will secure. Public destinations support sub-domain and path. Wildcard '*' can be used in the definition. """ - overrides: Iterable[BrowserRDPApplicationDestinationPublicDestinationOverride] + overrides: Iterable[DestinationOverrideParam] """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -4142,19 +4126,6 @@ class BrowserRDPApplicationDestinationViaMcpServerPortalDestination(TypedDict, t type: Literal["via_mcp_server_portal"] -class BrowserRDPApplicationDestinationWorkerDestinationOverride(TypedDict, total=False): - behavior: Required[Literal["public"]] - """The behavior to apply to matching requests.""" - - path_pattern: Required[str] - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class BrowserRDPApplicationDestinationWorkerDestination(TypedDict, total=False): """A specific Cloudflare Worker that Access will secure. @@ -4166,7 +4137,7 @@ class BrowserRDPApplicationDestinationWorkerDestination(TypedDict, total=False): worker_id: Required[str] """The ID of the Cloudflare Worker to protect with Access.""" - overrides: Iterable[BrowserRDPApplicationDestinationWorkerDestinationOverride] + overrides: Iterable[DestinationOverrideParam] """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -4174,19 +4145,6 @@ class BrowserRDPApplicationDestinationWorkerDestination(TypedDict, total=False): """ -class BrowserRDPApplicationDestinationPreviewWorkerDestinationOverride(TypedDict, total=False): - behavior: Required[Literal["public"]] - """The behavior to apply to matching requests.""" - - path_pattern: Required[str] - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class BrowserRDPApplicationDestinationPreviewWorkerDestination(TypedDict, total=False): """A specific Cloudflare Worker whose preview deployments Access will secure. @@ -4201,7 +4159,7 @@ class BrowserRDPApplicationDestinationPreviewWorkerDestination(TypedDict, total= Access. """ - overrides: Iterable[BrowserRDPApplicationDestinationPreviewWorkerDestinationOverride] + overrides: Iterable[DestinationOverrideParam] """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -4209,19 +4167,6 @@ class BrowserRDPApplicationDestinationPreviewWorkerDestination(TypedDict, total= """ -class BrowserRDPApplicationDestinationAllWorkersDestinationOverride(TypedDict, total=False): - behavior: Required[Literal["public"]] - """The behavior to apply to matching requests.""" - - path_pattern: Required[str] - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class BrowserRDPApplicationDestinationAllWorkersDestination(TypedDict, total=False): """ Protects all Cloudflare Workers on the account with Access, including their preview deployments. At most one destination of this type can exist per account. The `worker`, `preview_worker`, `all_preview_workers`, and `public` destination types take precedence, so you can create separate applications to override the policies for specific Workers, their previews, or specific paths. @@ -4229,7 +4174,7 @@ class BrowserRDPApplicationDestinationAllWorkersDestination(TypedDict, total=Fal type: Required[Literal["all_workers"]] - overrides: Iterable[BrowserRDPApplicationDestinationAllWorkersDestinationOverride] + overrides: Iterable[DestinationOverrideParam] """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -4237,19 +4182,6 @@ class BrowserRDPApplicationDestinationAllWorkersDestination(TypedDict, total=Fal """ -class BrowserRDPApplicationDestinationAllPreviewWorkersDestinationOverride(TypedDict, total=False): - behavior: Required[Literal["public"]] - """The behavior to apply to matching requests.""" - - path_pattern: Required[str] - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class BrowserRDPApplicationDestinationAllPreviewWorkersDestination(TypedDict, total=False): """ Protects the preview deployments of all Cloudflare Workers on the account with Access. At most one destination of this type can exist per account. The `worker`, `preview_worker`, and `public` destination types take precedence, so you can create separate applications to override the policies for specific Workers, their previews, or specific paths. @@ -4257,7 +4189,7 @@ class BrowserRDPApplicationDestinationAllPreviewWorkersDestination(TypedDict, to type: Required[Literal["all_preview_workers"]] - overrides: Iterable[BrowserRDPApplicationDestinationAllPreviewWorkersDestinationOverride] + overrides: Iterable[DestinationOverrideParam] """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -4678,7 +4610,7 @@ class McpServerApplication(TypedDict, total=False): """The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), - ms, s, m, h. Note: unsupported for infrastructure type applications. + ms, s, m, h. """ tags: SequenceNotStr[str] @@ -4688,26 +4620,13 @@ class McpServerApplication(TypedDict, total=False): """ -class McpServerApplicationDestinationPublicDestinationOverride(TypedDict, total=False): - behavior: Required[Literal["public"]] - """The behavior to apply to matching requests.""" - - path_pattern: Required[str] - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class McpServerApplicationDestinationPublicDestination(TypedDict, total=False): """A public hostname that Access will secure. Public destinations support sub-domain and path. Wildcard '*' can be used in the definition. """ - overrides: Iterable[McpServerApplicationDestinationPublicDestinationOverride] + overrides: Iterable[DestinationOverrideParam] """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -4761,19 +4680,6 @@ class McpServerApplicationDestinationViaMcpServerPortalDestination(TypedDict, to type: Literal["via_mcp_server_portal"] -class McpServerApplicationDestinationWorkerDestinationOverride(TypedDict, total=False): - behavior: Required[Literal["public"]] - """The behavior to apply to matching requests.""" - - path_pattern: Required[str] - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class McpServerApplicationDestinationWorkerDestination(TypedDict, total=False): """A specific Cloudflare Worker that Access will secure. @@ -4785,7 +4691,7 @@ class McpServerApplicationDestinationWorkerDestination(TypedDict, total=False): worker_id: Required[str] """The ID of the Cloudflare Worker to protect with Access.""" - overrides: Iterable[McpServerApplicationDestinationWorkerDestinationOverride] + overrides: Iterable[DestinationOverrideParam] """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -4793,19 +4699,6 @@ class McpServerApplicationDestinationWorkerDestination(TypedDict, total=False): """ -class McpServerApplicationDestinationPreviewWorkerDestinationOverride(TypedDict, total=False): - behavior: Required[Literal["public"]] - """The behavior to apply to matching requests.""" - - path_pattern: Required[str] - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class McpServerApplicationDestinationPreviewWorkerDestination(TypedDict, total=False): """A specific Cloudflare Worker whose preview deployments Access will secure. @@ -4820,7 +4713,7 @@ class McpServerApplicationDestinationPreviewWorkerDestination(TypedDict, total=F Access. """ - overrides: Iterable[McpServerApplicationDestinationPreviewWorkerDestinationOverride] + overrides: Iterable[DestinationOverrideParam] """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -4828,19 +4721,6 @@ class McpServerApplicationDestinationPreviewWorkerDestination(TypedDict, total=F """ -class McpServerApplicationDestinationAllWorkersDestinationOverride(TypedDict, total=False): - behavior: Required[Literal["public"]] - """The behavior to apply to matching requests.""" - - path_pattern: Required[str] - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class McpServerApplicationDestinationAllWorkersDestination(TypedDict, total=False): """ Protects all Cloudflare Workers on the account with Access, including their preview deployments. At most one destination of this type can exist per account. The `worker`, `preview_worker`, `all_preview_workers`, and `public` destination types take precedence, so you can create separate applications to override the policies for specific Workers, their previews, or specific paths. @@ -4848,7 +4728,7 @@ class McpServerApplicationDestinationAllWorkersDestination(TypedDict, total=Fals type: Required[Literal["all_workers"]] - overrides: Iterable[McpServerApplicationDestinationAllWorkersDestinationOverride] + overrides: Iterable[DestinationOverrideParam] """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -4856,19 +4736,6 @@ class McpServerApplicationDestinationAllWorkersDestination(TypedDict, total=Fals """ -class McpServerApplicationDestinationAllPreviewWorkersDestinationOverride(TypedDict, total=False): - behavior: Required[Literal["public"]] - """The behavior to apply to matching requests.""" - - path_pattern: Required[str] - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class McpServerApplicationDestinationAllPreviewWorkersDestination(TypedDict, total=False): """ Protects the preview deployments of all Cloudflare Workers on the account with Access. At most one destination of this type can exist per account. The `worker`, `preview_worker`, and `public` destination types take precedence, so you can create separate applications to override the policies for specific Workers, their previews, or specific paths. @@ -4876,7 +4743,7 @@ class McpServerApplicationDestinationAllPreviewWorkersDestination(TypedDict, tot type: Required[Literal["all_preview_workers"]] - overrides: Iterable[McpServerApplicationDestinationAllPreviewWorkersDestinationOverride] + overrides: Iterable[DestinationOverrideParam] """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -5283,7 +5150,7 @@ class McpServerPortalApplication(TypedDict, total=False): """The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), - ms, s, m, h. Note: unsupported for infrastructure type applications. + ms, s, m, h. """ tags: SequenceNotStr[str] @@ -5293,26 +5160,13 @@ class McpServerPortalApplication(TypedDict, total=False): """ -class McpServerPortalApplicationDestinationPublicDestinationOverride(TypedDict, total=False): - behavior: Required[Literal["public"]] - """The behavior to apply to matching requests.""" - - path_pattern: Required[str] - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class McpServerPortalApplicationDestinationPublicDestination(TypedDict, total=False): """A public hostname that Access will secure. Public destinations support sub-domain and path. Wildcard '*' can be used in the definition. """ - overrides: Iterable[McpServerPortalApplicationDestinationPublicDestinationOverride] + overrides: Iterable[DestinationOverrideParam] """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -5366,19 +5220,6 @@ class McpServerPortalApplicationDestinationViaMcpServerPortalDestination(TypedDi type: Literal["via_mcp_server_portal"] -class McpServerPortalApplicationDestinationWorkerDestinationOverride(TypedDict, total=False): - behavior: Required[Literal["public"]] - """The behavior to apply to matching requests.""" - - path_pattern: Required[str] - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class McpServerPortalApplicationDestinationWorkerDestination(TypedDict, total=False): """A specific Cloudflare Worker that Access will secure. @@ -5390,7 +5231,7 @@ class McpServerPortalApplicationDestinationWorkerDestination(TypedDict, total=Fa worker_id: Required[str] """The ID of the Cloudflare Worker to protect with Access.""" - overrides: Iterable[McpServerPortalApplicationDestinationWorkerDestinationOverride] + overrides: Iterable[DestinationOverrideParam] """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -5398,19 +5239,6 @@ class McpServerPortalApplicationDestinationWorkerDestination(TypedDict, total=Fa """ -class McpServerPortalApplicationDestinationPreviewWorkerDestinationOverride(TypedDict, total=False): - behavior: Required[Literal["public"]] - """The behavior to apply to matching requests.""" - - path_pattern: Required[str] - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class McpServerPortalApplicationDestinationPreviewWorkerDestination(TypedDict, total=False): """A specific Cloudflare Worker whose preview deployments Access will secure. @@ -5425,7 +5253,7 @@ class McpServerPortalApplicationDestinationPreviewWorkerDestination(TypedDict, t Access. """ - overrides: Iterable[McpServerPortalApplicationDestinationPreviewWorkerDestinationOverride] + overrides: Iterable[DestinationOverrideParam] """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -5433,19 +5261,6 @@ class McpServerPortalApplicationDestinationPreviewWorkerDestination(TypedDict, t """ -class McpServerPortalApplicationDestinationAllWorkersDestinationOverride(TypedDict, total=False): - behavior: Required[Literal["public"]] - """The behavior to apply to matching requests.""" - - path_pattern: Required[str] - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class McpServerPortalApplicationDestinationAllWorkersDestination(TypedDict, total=False): """ Protects all Cloudflare Workers on the account with Access, including their preview deployments. At most one destination of this type can exist per account. The `worker`, `preview_worker`, `all_preview_workers`, and `public` destination types take precedence, so you can create separate applications to override the policies for specific Workers, their previews, or specific paths. @@ -5453,7 +5268,7 @@ class McpServerPortalApplicationDestinationAllWorkersDestination(TypedDict, tota type: Required[Literal["all_workers"]] - overrides: Iterable[McpServerPortalApplicationDestinationAllWorkersDestinationOverride] + overrides: Iterable[DestinationOverrideParam] """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -5461,19 +5276,6 @@ class McpServerPortalApplicationDestinationAllWorkersDestination(TypedDict, tota """ -class McpServerPortalApplicationDestinationAllPreviewWorkersDestinationOverride(TypedDict, total=False): - behavior: Required[Literal["public"]] - """The behavior to apply to matching requests.""" - - path_pattern: Required[str] - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class McpServerPortalApplicationDestinationAllPreviewWorkersDestination(TypedDict, total=False): """ Protects the preview deployments of all Cloudflare Workers on the account with Access. At most one destination of this type can exist per account. The `worker`, `preview_worker`, and `public` destination types take precedence, so you can create separate applications to override the policies for specific Workers, their previews, or specific paths. @@ -5481,7 +5283,7 @@ class McpServerPortalApplicationDestinationAllPreviewWorkersDestination(TypedDic type: Required[Literal["all_preview_workers"]] - overrides: Iterable[McpServerPortalApplicationDestinationAllPreviewWorkersDestinationOverride] + overrides: Iterable[DestinationOverrideParam] """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -5771,6 +5573,7 @@ class McpServerPortalApplicationSCIMConfig(TypedDict, total=False): ApplicationUpdateParams: TypeAlias = Union[ + AccessEndUserProps, SelfHostedApplication, SaaSApplication, BrowserSSHApplication, diff --git a/src/cloudflare/types/zero_trust/access/application_update_response.py b/src/cloudflare/types/zero_trust/access/application_update_response.py index f02fa43d9b0..7fd9d6cfb9d 100644 --- a/src/cloudflare/types/zero_trust/access/application_update_response.py +++ b/src/cloudflare/types/zero_trust/access/application_update_response.py @@ -14,6 +14,7 @@ from .application_type import ApplicationType from .scim_config_mapping import SCIMConfigMapping from .self_hosted_domains import SelfHostedDomains +from .destination_override import DestinationOverride from .applications.access_rule import AccessRule from .scim_config_authentication_oauth2 import SCIMConfigAuthenticationOauth2 from .scim_config_authentication_http_basic import SCIMConfigAuthenticationHTTPBasic @@ -21,20 +22,25 @@ __all__ = [ "ApplicationUpdateResponse", + "EndUserApplication", + "EndUserApplicationOAuthConfiguration", + "EndUserApplicationOAuthConfigurationDynamicClientRegistration", + "EndUserApplicationOAuthConfigurationGrant", + "EndUserApplicationDestination", + "EndUserApplicationDestinationAccessEndUserPublicDestination", + "EndUserApplicationDestinationAccessEndUserWorkerDestination", + "EndUserApplicationDestinationAccessEndUserPreviewWorkerDestination", + "EndUserApplicationDestinationAccessEndUserAllWorkersDestination", + "EndUserApplicationDestinationAccessEndUserAllPreviewWorkersDestination", "SelfHostedApplication", "SelfHostedApplicationDestination", "SelfHostedApplicationDestinationPublicDestination", - "SelfHostedApplicationDestinationPublicDestinationOverride", "SelfHostedApplicationDestinationPrivateDestination", "SelfHostedApplicationDestinationViaMcpServerPortalDestination", "SelfHostedApplicationDestinationWorkerDestination", - "SelfHostedApplicationDestinationWorkerDestinationOverride", "SelfHostedApplicationDestinationPreviewWorkerDestination", - "SelfHostedApplicationDestinationPreviewWorkerDestinationOverride", "SelfHostedApplicationDestinationAllWorkersDestination", - "SelfHostedApplicationDestinationAllWorkersDestinationOverride", "SelfHostedApplicationDestinationAllPreviewWorkersDestination", - "SelfHostedApplicationDestinationAllPreviewWorkersDestinationOverride", "SelfHostedApplicationMfaConfig", "SelfHostedApplicationOAuthConfiguration", "SelfHostedApplicationOAuthConfigurationDynamicClientRegistration", @@ -62,17 +68,12 @@ "BrowserSSHApplication", "BrowserSSHApplicationDestination", "BrowserSSHApplicationDestinationPublicDestination", - "BrowserSSHApplicationDestinationPublicDestinationOverride", "BrowserSSHApplicationDestinationPrivateDestination", "BrowserSSHApplicationDestinationViaMcpServerPortalDestination", "BrowserSSHApplicationDestinationWorkerDestination", - "BrowserSSHApplicationDestinationWorkerDestinationOverride", "BrowserSSHApplicationDestinationPreviewWorkerDestination", - "BrowserSSHApplicationDestinationPreviewWorkerDestinationOverride", "BrowserSSHApplicationDestinationAllWorkersDestination", - "BrowserSSHApplicationDestinationAllWorkersDestinationOverride", "BrowserSSHApplicationDestinationAllPreviewWorkersDestination", - "BrowserSSHApplicationDestinationAllPreviewWorkersDestinationOverride", "BrowserSSHApplicationMfaConfig", "BrowserSSHApplicationOAuthConfiguration", "BrowserSSHApplicationOAuthConfigurationDynamicClientRegistration", @@ -89,17 +90,12 @@ "BrowserVNCApplication", "BrowserVNCApplicationDestination", "BrowserVNCApplicationDestinationPublicDestination", - "BrowserVNCApplicationDestinationPublicDestinationOverride", "BrowserVNCApplicationDestinationPrivateDestination", "BrowserVNCApplicationDestinationViaMcpServerPortalDestination", "BrowserVNCApplicationDestinationWorkerDestination", - "BrowserVNCApplicationDestinationWorkerDestinationOverride", "BrowserVNCApplicationDestinationPreviewWorkerDestination", - "BrowserVNCApplicationDestinationPreviewWorkerDestinationOverride", "BrowserVNCApplicationDestinationAllWorkersDestination", - "BrowserVNCApplicationDestinationAllWorkersDestinationOverride", "BrowserVNCApplicationDestinationAllPreviewWorkersDestination", - "BrowserVNCApplicationDestinationAllPreviewWorkersDestinationOverride", "BrowserVNCApplicationMfaConfig", "BrowserVNCApplicationOAuthConfiguration", "BrowserVNCApplicationOAuthConfigurationDynamicClientRegistration", @@ -163,17 +159,12 @@ "BrowserRDPApplicationTargetCriterionRequireTargetAttributes", "BrowserRDPApplicationDestination", "BrowserRDPApplicationDestinationPublicDestination", - "BrowserRDPApplicationDestinationPublicDestinationOverride", "BrowserRDPApplicationDestinationPrivateDestination", "BrowserRDPApplicationDestinationViaMcpServerPortalDestination", "BrowserRDPApplicationDestinationWorkerDestination", - "BrowserRDPApplicationDestinationWorkerDestinationOverride", "BrowserRDPApplicationDestinationPreviewWorkerDestination", - "BrowserRDPApplicationDestinationPreviewWorkerDestinationOverride", "BrowserRDPApplicationDestinationAllWorkersDestination", - "BrowserRDPApplicationDestinationAllWorkersDestinationOverride", "BrowserRDPApplicationDestinationAllPreviewWorkersDestination", - "BrowserRDPApplicationDestinationAllPreviewWorkersDestinationOverride", "BrowserRDPApplicationMfaConfig", "BrowserRDPApplicationOAuthConfiguration", "BrowserRDPApplicationOAuthConfigurationDynamicClientRegistration", @@ -190,17 +181,12 @@ "McpServerApplication", "McpServerApplicationDestination", "McpServerApplicationDestinationPublicDestination", - "McpServerApplicationDestinationPublicDestinationOverride", "McpServerApplicationDestinationPrivateDestination", "McpServerApplicationDestinationViaMcpServerPortalDestination", "McpServerApplicationDestinationWorkerDestination", - "McpServerApplicationDestinationWorkerDestinationOverride", "McpServerApplicationDestinationPreviewWorkerDestination", - "McpServerApplicationDestinationPreviewWorkerDestinationOverride", "McpServerApplicationDestinationAllWorkersDestination", - "McpServerApplicationDestinationAllWorkersDestinationOverride", "McpServerApplicationDestinationAllPreviewWorkersDestination", - "McpServerApplicationDestinationAllPreviewWorkersDestinationOverride", "McpServerApplicationOAuthConfiguration", "McpServerApplicationOAuthConfigurationDynamicClientRegistration", "McpServerApplicationOAuthConfigurationGrant", @@ -216,17 +202,12 @@ "McpServerPortalApplication", "McpServerPortalApplicationDestination", "McpServerPortalApplicationDestinationPublicDestination", - "McpServerPortalApplicationDestinationPublicDestinationOverride", "McpServerPortalApplicationDestinationPrivateDestination", "McpServerPortalApplicationDestinationViaMcpServerPortalDestination", "McpServerPortalApplicationDestinationWorkerDestination", - "McpServerPortalApplicationDestinationWorkerDestinationOverride", "McpServerPortalApplicationDestinationPreviewWorkerDestination", - "McpServerPortalApplicationDestinationPreviewWorkerDestinationOverride", "McpServerPortalApplicationDestinationAllWorkersDestination", - "McpServerPortalApplicationDestinationAllWorkersDestinationOverride", "McpServerPortalApplicationDestinationAllPreviewWorkersDestination", - "McpServerPortalApplicationDestinationAllPreviewWorkersDestinationOverride", "McpServerPortalApplicationOAuthConfiguration", "McpServerPortalApplicationOAuthConfigurationDynamicClientRegistration", "McpServerPortalApplicationOAuthConfigurationGrant", @@ -242,16 +223,195 @@ ] -class SelfHostedApplicationDestinationPublicDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" +class EndUserApplicationOAuthConfigurationDynamicClientRegistration(BaseModel): + """Settings for OAuth dynamic client registration.""" + + allow_any_on_localhost: Optional[bool] = None + """Allows any client with redirect URIs on localhost.""" + + allow_any_on_loopback: Optional[bool] = None + """Allows any client with redirect URIs on 127.0.0.1.""" + + allowed_uris: Optional[List[str]] = None + """The URIs that are allowed as redirect URIs for dynamically registered clients. + + HTTP and HTTPS paths may end in `/*` to match all sub-paths. Custom-scheme URIs + must be explicitly configured and match exactly. + """ + + enabled: Optional[bool] = None + """Whether dynamic client registration is enabled.""" + + +class EndUserApplicationOAuthConfigurationGrant(BaseModel): + """Settings for OAuth grant behavior.""" + + access_token_lifetime: Optional[str] = None + """The lifetime of the access token. + + Must be in the format `300ms` or `2h45m`. Valid time units are ns, us (or µs), + ms, s, m, h. + """ + + session_duration: Optional[str] = None + """The duration of the OAuth session. + + Must be in the format `300ms` or `2h45m`. Valid time units are ns, us (or µs), + ms, s, m, h. + """ + + +class EndUserApplicationOAuthConfiguration(BaseModel): + """ + **Beta:** Optional configuration for managing an OAuth authorization flow controlled by Access. When set, Access will act as the OAuth authorization server for this application. Only compatible with OAuth clients that support [RFC 8707](https://datatracker.ietf.org/doc/html/rfc8707) (Resource Indicators for OAuth 2.0). This feature is currently in beta. + """ + + dynamic_client_registration: Optional[EndUserApplicationOAuthConfigurationDynamicClientRegistration] = None + """Settings for OAuth dynamic client registration.""" + + enabled: Optional[Literal[True]] = None + """Managed OAuth is required for end user applications and cannot be disabled.""" + + grant: Optional[EndUserApplicationOAuthConfigurationGrant] = None + """Settings for OAuth grant behavior.""" + + +class EndUserApplicationDestinationAccessEndUserPublicDestination(BaseModel): + uri: str + """The public hostname and optional path to secure.""" + + overrides: Optional[List[DestinationOverride]] = None + """Rules that override how Access handles requests to this destination. + + Each rule can make a matching path public, bypassing Access authentication. + Overrides are supported for public destinations and Worker destinations. + """ + + type: Optional[Literal["public"]] = None + + +class EndUserApplicationDestinationAccessEndUserWorkerDestination(BaseModel): + type: Literal["worker"] + + worker_id: str + """The ID of the Cloudflare Worker to secure.""" + + overrides: Optional[List[DestinationOverride]] = None + """Rules that override how Access handles requests to this destination. + + Each rule can make a matching path public, bypassing Access authentication. + Overrides are supported for public destinations and Worker destinations. + """ + + +class EndUserApplicationDestinationAccessEndUserPreviewWorkerDestination(BaseModel): + type: Literal["preview_worker"] + + worker_id: str + """The ID of the Cloudflare Worker whose previews to secure.""" + + overrides: Optional[List[DestinationOverride]] = None + """Rules that override how Access handles requests to this destination. + + Each rule can make a matching path public, bypassing Access authentication. + Overrides are supported for public destinations and Worker destinations. + """ + + +class EndUserApplicationDestinationAccessEndUserAllWorkersDestination(BaseModel): + type: Literal["all_workers"] + + overrides: Optional[List[DestinationOverride]] = None + """Rules that override how Access handles requests to this destination. + + Each rule can make a matching path public, bypassing Access authentication. + Overrides are supported for public destinations and Worker destinations. + """ + + +class EndUserApplicationDestinationAccessEndUserAllPreviewWorkersDestination(BaseModel): + type: Literal["all_preview_workers"] - path_pattern: str - """The request path pattern to match. + overrides: Optional[List[DestinationOverride]] = None + """Rules that override how Access handles requests to this destination. + + Each rule can make a matching path public, bypassing Access authentication. + Overrides are supported for public destinations and Worker destinations. + """ + + +EndUserApplicationDestination: TypeAlias = Union[ + EndUserApplicationDestinationAccessEndUserPublicDestination, + EndUserApplicationDestinationAccessEndUserWorkerDestination, + EndUserApplicationDestinationAccessEndUserPreviewWorkerDestination, + EndUserApplicationDestinationAccessEndUserAllWorkersDestination, + EndUserApplicationDestinationAccessEndUserAllPreviewWorkersDestination, +] + + +class EndUserApplication(BaseModel): + oauth_configuration: EndUserApplicationOAuthConfiguration + """ + **Beta:** Optional configuration for managing an OAuth authorization flow + controlled by Access. When set, Access will act as the OAuth authorization + server for this application. Only compatible with OAuth clients that support + [RFC 8707](https://datatracker.ietf.org/doc/html/rfc8707) (Resource Indicators + for OAuth 2.0). This feature is currently in beta. + """ + + type: Literal[ + "self_hosted", + "end_user", + "saas", + "ssh", + "vnc", + "app_launcher", + "warp", + "biso", + "bookmark", + "dash_sso", + "infrastructure", + "rdp", + "mcp", + "mcp_portal", + "proxy_endpoint", + ] + """The application type.""" + + user_populations: List[str] + """The single user population associated with this application.""" + + id: Optional[str] = None + """UUID.""" + + allowed_idps: Optional[List[AllowedIdPs]] = None + """The identity providers your users can select when connecting to this + application. + + Defaults to all IdPs configured in your account. + """ + + aud: Optional[str] = None + """Audience tag.""" + + destinations: Optional[List[EndUserApplicationDestination]] = None + """Public hostname and Workers destinations secured by Access.""" + + domain: Optional[str] = None + """The primary hostname and path secured by Access. + + This domain will be displayed if the app is visible in the App Launcher. + """ + + name: Optional[str] = None + """The name of the application.""" - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. + self_hosted_domains: Optional[List[SelfHostedDomains]] = None + """List of public domains that Access will secure. + + This field is deprecated in favor of `destinations` and will be supported until + **November 21, 2025.** If `destinations` are provided, then + `self_hosted_domains` will be ignored. """ @@ -261,7 +421,7 @@ class SelfHostedApplicationDestinationPublicDestination(BaseModel): Public destinations support sub-domain and path. Wildcard '*' can be used in the definition. """ - overrides: Optional[List[SelfHostedApplicationDestinationPublicDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -315,19 +475,6 @@ class SelfHostedApplicationDestinationViaMcpServerPortalDestination(BaseModel): type: Optional[Literal["via_mcp_server_portal"]] = None -class SelfHostedApplicationDestinationWorkerDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class SelfHostedApplicationDestinationWorkerDestination(BaseModel): """A specific Cloudflare Worker that Access will secure. @@ -339,7 +486,7 @@ class SelfHostedApplicationDestinationWorkerDestination(BaseModel): worker_id: str """The ID of the Cloudflare Worker to protect with Access.""" - overrides: Optional[List[SelfHostedApplicationDestinationWorkerDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -347,19 +494,6 @@ class SelfHostedApplicationDestinationWorkerDestination(BaseModel): """ -class SelfHostedApplicationDestinationPreviewWorkerDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class SelfHostedApplicationDestinationPreviewWorkerDestination(BaseModel): """A specific Cloudflare Worker whose preview deployments Access will secure. @@ -374,7 +508,7 @@ class SelfHostedApplicationDestinationPreviewWorkerDestination(BaseModel): Access. """ - overrides: Optional[List[SelfHostedApplicationDestinationPreviewWorkerDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -382,19 +516,6 @@ class SelfHostedApplicationDestinationPreviewWorkerDestination(BaseModel): """ -class SelfHostedApplicationDestinationAllWorkersDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class SelfHostedApplicationDestinationAllWorkersDestination(BaseModel): """ Protects all Cloudflare Workers on the account with Access, including their preview deployments. At most one destination of this type can exist per account. The `worker`, `preview_worker`, `all_preview_workers`, and `public` destination types take precedence, so you can create separate applications to override the policies for specific Workers, their previews, or specific paths. @@ -402,7 +523,7 @@ class SelfHostedApplicationDestinationAllWorkersDestination(BaseModel): type: Literal["all_workers"] - overrides: Optional[List[SelfHostedApplicationDestinationAllWorkersDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -410,19 +531,6 @@ class SelfHostedApplicationDestinationAllWorkersDestination(BaseModel): """ -class SelfHostedApplicationDestinationAllPreviewWorkersDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class SelfHostedApplicationDestinationAllPreviewWorkersDestination(BaseModel): """ Protects the preview deployments of all Cloudflare Workers on the account with Access. At most one destination of this type can exist per account. The `worker`, `preview_worker`, and `public` destination types take precedence, so you can create separate applications to override the policies for specific Workers, their previews, or specific paths. @@ -430,7 +538,7 @@ class SelfHostedApplicationDestinationAllPreviewWorkersDestination(BaseModel): type: Literal["all_preview_workers"] - overrides: Optional[List[SelfHostedApplicationDestinationAllPreviewWorkersDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -624,6 +732,13 @@ class SelfHostedApplicationPolicy(BaseModel): name: Optional[str] = None """The name of the Access policy.""" + policy_resolution_account_id: Optional[str] = None + """ + The account ID used to resolve policy resources and identity for cross-account + WARP authentication. The account must be trusted by the account that owns this + policy. + """ + precedence: Optional[int] = None """The order of execution for this policy. @@ -915,7 +1030,7 @@ class SelfHostedApplication(BaseModel): """The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), - ms, s, m, h. Note: unsupported for infrastructure type applications. + ms, s, m, h. """ skip_interstitial: Optional[bool] = None @@ -1034,6 +1149,13 @@ class SaaSApplicationPolicy(BaseModel): name: Optional[str] = None """The name of the Access policy.""" + policy_resolution_account_id: Optional[str] = None + """ + The account ID used to resolve policy resources and identity for cross-account + WARP authentication. The account must be trusted by the account that owns this + policy. + """ + precedence: Optional[int] = None """The order of execution for this policy. @@ -1216,26 +1338,13 @@ class SaaSApplication(BaseModel): """The application type.""" -class BrowserSSHApplicationDestinationPublicDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class BrowserSSHApplicationDestinationPublicDestination(BaseModel): """A public hostname that Access will secure. Public destinations support sub-domain and path. Wildcard '*' can be used in the definition. """ - overrides: Optional[List[BrowserSSHApplicationDestinationPublicDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -1289,19 +1398,6 @@ class BrowserSSHApplicationDestinationViaMcpServerPortalDestination(BaseModel): type: Optional[Literal["via_mcp_server_portal"]] = None -class BrowserSSHApplicationDestinationWorkerDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class BrowserSSHApplicationDestinationWorkerDestination(BaseModel): """A specific Cloudflare Worker that Access will secure. @@ -1313,7 +1409,7 @@ class BrowserSSHApplicationDestinationWorkerDestination(BaseModel): worker_id: str """The ID of the Cloudflare Worker to protect with Access.""" - overrides: Optional[List[BrowserSSHApplicationDestinationWorkerDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -1321,19 +1417,6 @@ class BrowserSSHApplicationDestinationWorkerDestination(BaseModel): """ -class BrowserSSHApplicationDestinationPreviewWorkerDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class BrowserSSHApplicationDestinationPreviewWorkerDestination(BaseModel): """A specific Cloudflare Worker whose preview deployments Access will secure. @@ -1348,7 +1431,7 @@ class BrowserSSHApplicationDestinationPreviewWorkerDestination(BaseModel): Access. """ - overrides: Optional[List[BrowserSSHApplicationDestinationPreviewWorkerDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -1356,19 +1439,6 @@ class BrowserSSHApplicationDestinationPreviewWorkerDestination(BaseModel): """ -class BrowserSSHApplicationDestinationAllWorkersDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class BrowserSSHApplicationDestinationAllWorkersDestination(BaseModel): """ Protects all Cloudflare Workers on the account with Access, including their preview deployments. At most one destination of this type can exist per account. The `worker`, `preview_worker`, `all_preview_workers`, and `public` destination types take precedence, so you can create separate applications to override the policies for specific Workers, their previews, or specific paths. @@ -1376,7 +1446,7 @@ class BrowserSSHApplicationDestinationAllWorkersDestination(BaseModel): type: Literal["all_workers"] - overrides: Optional[List[BrowserSSHApplicationDestinationAllWorkersDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -1384,19 +1454,6 @@ class BrowserSSHApplicationDestinationAllWorkersDestination(BaseModel): """ -class BrowserSSHApplicationDestinationAllPreviewWorkersDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class BrowserSSHApplicationDestinationAllPreviewWorkersDestination(BaseModel): """ Protects the preview deployments of all Cloudflare Workers on the account with Access. At most one destination of this type can exist per account. The `worker`, `preview_worker`, and `public` destination types take precedence, so you can create separate applications to override the policies for specific Workers, their previews, or specific paths. @@ -1404,7 +1461,7 @@ class BrowserSSHApplicationDestinationAllPreviewWorkersDestination(BaseModel): type: Literal["all_preview_workers"] - overrides: Optional[List[BrowserSSHApplicationDestinationAllPreviewWorkersDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -1598,6 +1655,13 @@ class BrowserSSHApplicationPolicy(BaseModel): name: Optional[str] = None """The name of the Access policy.""" + policy_resolution_account_id: Optional[str] = None + """ + The account ID used to resolve policy resources and identity for cross-account + WARP authentication. The account must be trusted by the account that owns this + policy. + """ + precedence: Optional[int] = None """The order of execution for this policy. @@ -1733,6 +1797,7 @@ class BrowserSSHApplication(BaseModel): type: Literal[ "self_hosted", + "end_user", "saas", "ssh", "vnc", @@ -1904,7 +1969,7 @@ class BrowserSSHApplication(BaseModel): """The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), - ms, s, m, h. Note: unsupported for infrastructure type applications. + ms, s, m, h. """ skip_interstitial: Optional[bool] = None @@ -1925,26 +1990,13 @@ class BrowserSSHApplication(BaseModel): """ -class BrowserVNCApplicationDestinationPublicDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class BrowserVNCApplicationDestinationPublicDestination(BaseModel): """A public hostname that Access will secure. Public destinations support sub-domain and path. Wildcard '*' can be used in the definition. """ - overrides: Optional[List[BrowserVNCApplicationDestinationPublicDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -1998,19 +2050,6 @@ class BrowserVNCApplicationDestinationViaMcpServerPortalDestination(BaseModel): type: Optional[Literal["via_mcp_server_portal"]] = None -class BrowserVNCApplicationDestinationWorkerDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class BrowserVNCApplicationDestinationWorkerDestination(BaseModel): """A specific Cloudflare Worker that Access will secure. @@ -2022,7 +2061,7 @@ class BrowserVNCApplicationDestinationWorkerDestination(BaseModel): worker_id: str """The ID of the Cloudflare Worker to protect with Access.""" - overrides: Optional[List[BrowserVNCApplicationDestinationWorkerDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -2030,19 +2069,6 @@ class BrowserVNCApplicationDestinationWorkerDestination(BaseModel): """ -class BrowserVNCApplicationDestinationPreviewWorkerDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class BrowserVNCApplicationDestinationPreviewWorkerDestination(BaseModel): """A specific Cloudflare Worker whose preview deployments Access will secure. @@ -2057,7 +2083,7 @@ class BrowserVNCApplicationDestinationPreviewWorkerDestination(BaseModel): Access. """ - overrides: Optional[List[BrowserVNCApplicationDestinationPreviewWorkerDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -2065,19 +2091,6 @@ class BrowserVNCApplicationDestinationPreviewWorkerDestination(BaseModel): """ -class BrowserVNCApplicationDestinationAllWorkersDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class BrowserVNCApplicationDestinationAllWorkersDestination(BaseModel): """ Protects all Cloudflare Workers on the account with Access, including their preview deployments. At most one destination of this type can exist per account. The `worker`, `preview_worker`, `all_preview_workers`, and `public` destination types take precedence, so you can create separate applications to override the policies for specific Workers, their previews, or specific paths. @@ -2085,7 +2098,7 @@ class BrowserVNCApplicationDestinationAllWorkersDestination(BaseModel): type: Literal["all_workers"] - overrides: Optional[List[BrowserVNCApplicationDestinationAllWorkersDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -2093,19 +2106,6 @@ class BrowserVNCApplicationDestinationAllWorkersDestination(BaseModel): """ -class BrowserVNCApplicationDestinationAllPreviewWorkersDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class BrowserVNCApplicationDestinationAllPreviewWorkersDestination(BaseModel): """ Protects the preview deployments of all Cloudflare Workers on the account with Access. At most one destination of this type can exist per account. The `worker`, `preview_worker`, and `public` destination types take precedence, so you can create separate applications to override the policies for specific Workers, their previews, or specific paths. @@ -2113,7 +2113,7 @@ class BrowserVNCApplicationDestinationAllPreviewWorkersDestination(BaseModel): type: Literal["all_preview_workers"] - overrides: Optional[List[BrowserVNCApplicationDestinationAllPreviewWorkersDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -2307,6 +2307,13 @@ class BrowserVNCApplicationPolicy(BaseModel): name: Optional[str] = None """The name of the Access policy.""" + policy_resolution_account_id: Optional[str] = None + """ + The account ID used to resolve policy resources and identity for cross-account + WARP authentication. The account must be trusted by the account that owns this + policy. + """ + precedence: Optional[int] = None """The order of execution for this policy. @@ -2442,6 +2449,7 @@ class BrowserVNCApplication(BaseModel): type: Literal[ "self_hosted", + "end_user", "saas", "ssh", "vnc", @@ -2613,7 +2621,7 @@ class BrowserVNCApplication(BaseModel): """The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), - ms, s, m, h. Note: unsupported for infrastructure type applications. + ms, s, m, h. """ skip_interstitial: Optional[bool] = None @@ -2759,6 +2767,13 @@ class AppLauncherApplicationPolicy(BaseModel): name: Optional[str] = None """The name of the Access policy.""" + policy_resolution_account_id: Optional[str] = None + """ + The account ID used to resolve policy resources and identity for cross-account + WARP authentication. The account must be trusted by the account that owns this + policy. + """ + precedence: Optional[int] = None """The order of execution for this policy. @@ -2790,6 +2805,7 @@ class AppLauncherApplicationPolicy(BaseModel): class AppLauncherApplication(BaseModel): type: Literal[ "self_hosted", + "end_user", "saas", "ssh", "vnc", @@ -2871,7 +2887,7 @@ class AppLauncherApplication(BaseModel): """The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), - ms, s, m, h. Note: unsupported for infrastructure type applications. + ms, s, m, h. """ skip_app_launcher_login_page: Optional[bool] = None @@ -2976,6 +2992,13 @@ class DeviceEnrollmentPermissionsApplicationPolicy(BaseModel): name: Optional[str] = None """The name of the Access policy.""" + policy_resolution_account_id: Optional[str] = None + """ + The account ID used to resolve policy resources and identity for cross-account + WARP authentication. The account must be trusted by the account that owns this + policy. + """ + precedence: Optional[int] = None """The order of execution for this policy. @@ -3058,7 +3081,7 @@ class DeviceEnrollmentPermissionsApplication(BaseModel): """The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), - ms, s, m, h. Note: unsupported for infrastructure type applications. + ms, s, m, h. """ @@ -3160,6 +3183,13 @@ class BrowserIsolationPermissionsApplicationPolicy(BaseModel): name: Optional[str] = None """The name of the Access policy.""" + policy_resolution_account_id: Optional[str] = None + """ + The account ID used to resolve policy resources and identity for cross-account + WARP authentication. The account must be trusted by the account that owns this + policy. + """ + precedence: Optional[int] = None """The order of execution for this policy. @@ -3242,7 +3272,7 @@ class BrowserIsolationPermissionsApplication(BaseModel): """The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), - ms, s, m, h. Note: unsupported for infrastructure type applications. + ms, s, m, h. """ @@ -3344,6 +3374,13 @@ class GatewayIdentityProxyEndpointApplicationPolicy(BaseModel): name: Optional[str] = None """The name of the Access policy.""" + policy_resolution_account_id: Optional[str] = None + """ + The account ID used to resolve policy resources and identity for cross-account + WARP authentication. The account must be trusted by the account that owns this + policy. + """ + precedence: Optional[int] = None """The order of execution for this policy. @@ -3426,7 +3463,7 @@ class GatewayIdentityProxyEndpointApplication(BaseModel): """The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), - ms, s, m, h. Note: unsupported for infrastructure type applications. + ms, s, m, h. """ @@ -3528,6 +3565,13 @@ class BookmarkApplicationPolicy(BaseModel): name: Optional[str] = None """The name of the Access policy.""" + policy_resolution_account_id: Optional[str] = None + """ + The account ID used to resolve policy resources and identity for cross-account + WARP authentication. The account must be trusted by the account that owns this + policy. + """ + precedence: Optional[int] = None """The order of execution for this policy. @@ -3799,6 +3843,13 @@ class InfrastructureApplicationPolicy(BaseModel): name: Optional[str] = None """The name of the Access policy.""" + policy_resolution_account_id: Optional[str] = None + """ + The account ID used to resolve policy resources and identity for cross-account + WARP authentication. The account must be trusted by the account that owns this + policy. + """ + require: Optional[List[AccessRule]] = None """Rules evaluated with an AND logical operator. @@ -3831,6 +3882,13 @@ class InfrastructureApplication(BaseModel): policies: Optional[List[InfrastructureApplicationPolicy]] = None + session_duration: Optional[str] = None + """The maximum duration of a connection to this application's targets. + + Connections are terminated once it elapses. Must be in the format `30m` or + `2h45m`, in whole seconds. Valid time units are: s, m, h. + """ + class BrowserRDPApplicationTargetCriterionExcludeTargetAttributes(BaseModel): """Hostname selector map for include, require, or exclude rules. @@ -3929,26 +3987,13 @@ class BrowserRDPApplicationTargetCriterion(BaseModel): """Contains a map of target attribute keys to target attribute values.""" -class BrowserRDPApplicationDestinationPublicDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class BrowserRDPApplicationDestinationPublicDestination(BaseModel): """A public hostname that Access will secure. Public destinations support sub-domain and path. Wildcard '*' can be used in the definition. """ - overrides: Optional[List[BrowserRDPApplicationDestinationPublicDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -4002,19 +4047,6 @@ class BrowserRDPApplicationDestinationViaMcpServerPortalDestination(BaseModel): type: Optional[Literal["via_mcp_server_portal"]] = None -class BrowserRDPApplicationDestinationWorkerDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class BrowserRDPApplicationDestinationWorkerDestination(BaseModel): """A specific Cloudflare Worker that Access will secure. @@ -4026,7 +4058,7 @@ class BrowserRDPApplicationDestinationWorkerDestination(BaseModel): worker_id: str """The ID of the Cloudflare Worker to protect with Access.""" - overrides: Optional[List[BrowserRDPApplicationDestinationWorkerDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -4034,19 +4066,6 @@ class BrowserRDPApplicationDestinationWorkerDestination(BaseModel): """ -class BrowserRDPApplicationDestinationPreviewWorkerDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class BrowserRDPApplicationDestinationPreviewWorkerDestination(BaseModel): """A specific Cloudflare Worker whose preview deployments Access will secure. @@ -4061,7 +4080,7 @@ class BrowserRDPApplicationDestinationPreviewWorkerDestination(BaseModel): Access. """ - overrides: Optional[List[BrowserRDPApplicationDestinationPreviewWorkerDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -4069,19 +4088,6 @@ class BrowserRDPApplicationDestinationPreviewWorkerDestination(BaseModel): """ -class BrowserRDPApplicationDestinationAllWorkersDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class BrowserRDPApplicationDestinationAllWorkersDestination(BaseModel): """ Protects all Cloudflare Workers on the account with Access, including their preview deployments. At most one destination of this type can exist per account. The `worker`, `preview_worker`, `all_preview_workers`, and `public` destination types take precedence, so you can create separate applications to override the policies for specific Workers, their previews, or specific paths. @@ -4089,7 +4095,7 @@ class BrowserRDPApplicationDestinationAllWorkersDestination(BaseModel): type: Literal["all_workers"] - overrides: Optional[List[BrowserRDPApplicationDestinationAllWorkersDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -4097,19 +4103,6 @@ class BrowserRDPApplicationDestinationAllWorkersDestination(BaseModel): """ -class BrowserRDPApplicationDestinationAllPreviewWorkersDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class BrowserRDPApplicationDestinationAllPreviewWorkersDestination(BaseModel): """ Protects the preview deployments of all Cloudflare Workers on the account with Access. At most one destination of this type can exist per account. The `worker`, `preview_worker`, and `public` destination types take precedence, so you can create separate applications to override the policies for specific Workers, their previews, or specific paths. @@ -4117,7 +4110,7 @@ class BrowserRDPApplicationDestinationAllPreviewWorkersDestination(BaseModel): type: Literal["all_preview_workers"] - overrides: Optional[List[BrowserRDPApplicationDestinationAllPreviewWorkersDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -4311,6 +4304,13 @@ class BrowserRDPApplicationPolicy(BaseModel): name: Optional[str] = None """The name of the Access policy.""" + policy_resolution_account_id: Optional[str] = None + """ + The account ID used to resolve policy resources and identity for cross-account + WARP authentication. The account must be trusted by the account that owns this + policy. + """ + precedence: Optional[int] = None """The order of execution for this policy. @@ -4604,7 +4604,7 @@ class BrowserRDPApplication(BaseModel): """The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), - ms, s, m, h. Note: unsupported for infrastructure type applications. + ms, s, m, h. """ skip_interstitial: Optional[bool] = None @@ -4625,26 +4625,13 @@ class BrowserRDPApplication(BaseModel): """ -class McpServerApplicationDestinationPublicDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class McpServerApplicationDestinationPublicDestination(BaseModel): """A public hostname that Access will secure. Public destinations support sub-domain and path. Wildcard '*' can be used in the definition. """ - overrides: Optional[List[McpServerApplicationDestinationPublicDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -4698,19 +4685,6 @@ class McpServerApplicationDestinationViaMcpServerPortalDestination(BaseModel): type: Optional[Literal["via_mcp_server_portal"]] = None -class McpServerApplicationDestinationWorkerDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class McpServerApplicationDestinationWorkerDestination(BaseModel): """A specific Cloudflare Worker that Access will secure. @@ -4722,7 +4696,7 @@ class McpServerApplicationDestinationWorkerDestination(BaseModel): worker_id: str """The ID of the Cloudflare Worker to protect with Access.""" - overrides: Optional[List[McpServerApplicationDestinationWorkerDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -4730,19 +4704,6 @@ class McpServerApplicationDestinationWorkerDestination(BaseModel): """ -class McpServerApplicationDestinationPreviewWorkerDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class McpServerApplicationDestinationPreviewWorkerDestination(BaseModel): """A specific Cloudflare Worker whose preview deployments Access will secure. @@ -4757,7 +4718,7 @@ class McpServerApplicationDestinationPreviewWorkerDestination(BaseModel): Access. """ - overrides: Optional[List[McpServerApplicationDestinationPreviewWorkerDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -4765,19 +4726,6 @@ class McpServerApplicationDestinationPreviewWorkerDestination(BaseModel): """ -class McpServerApplicationDestinationAllWorkersDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class McpServerApplicationDestinationAllWorkersDestination(BaseModel): """ Protects all Cloudflare Workers on the account with Access, including their preview deployments. At most one destination of this type can exist per account. The `worker`, `preview_worker`, `all_preview_workers`, and `public` destination types take precedence, so you can create separate applications to override the policies for specific Workers, their previews, or specific paths. @@ -4785,7 +4733,7 @@ class McpServerApplicationDestinationAllWorkersDestination(BaseModel): type: Literal["all_workers"] - overrides: Optional[List[McpServerApplicationDestinationAllWorkersDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -4793,19 +4741,6 @@ class McpServerApplicationDestinationAllWorkersDestination(BaseModel): """ -class McpServerApplicationDestinationAllPreviewWorkersDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class McpServerApplicationDestinationAllPreviewWorkersDestination(BaseModel): """ Protects the preview deployments of all Cloudflare Workers on the account with Access. At most one destination of this type can exist per account. The `worker`, `preview_worker`, and `public` destination types take precedence, so you can create separate applications to override the policies for specific Workers, their previews, or specific paths. @@ -4813,7 +4748,7 @@ class McpServerApplicationDestinationAllPreviewWorkersDestination(BaseModel): type: Literal["all_preview_workers"] - overrides: Optional[List[McpServerApplicationDestinationAllPreviewWorkersDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -4987,6 +4922,13 @@ class McpServerApplicationPolicy(BaseModel): name: Optional[str] = None """The name of the Access policy.""" + policy_resolution_account_id: Optional[str] = None + """ + The account ID used to resolve policy resources and identity for cross-account + WARP authentication. The account must be trusted by the account that owns this + policy. + """ + precedence: Optional[int] = None """The order of execution for this policy. @@ -5219,7 +5161,7 @@ class McpServerApplication(BaseModel): """The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), - ms, s, m, h. Note: unsupported for infrastructure type applications. + ms, s, m, h. """ tags: Optional[List[str]] = None @@ -5229,26 +5171,13 @@ class McpServerApplication(BaseModel): """ -class McpServerPortalApplicationDestinationPublicDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class McpServerPortalApplicationDestinationPublicDestination(BaseModel): """A public hostname that Access will secure. Public destinations support sub-domain and path. Wildcard '*' can be used in the definition. """ - overrides: Optional[List[McpServerPortalApplicationDestinationPublicDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -5302,19 +5231,6 @@ class McpServerPortalApplicationDestinationViaMcpServerPortalDestination(BaseMod type: Optional[Literal["via_mcp_server_portal"]] = None -class McpServerPortalApplicationDestinationWorkerDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class McpServerPortalApplicationDestinationWorkerDestination(BaseModel): """A specific Cloudflare Worker that Access will secure. @@ -5326,7 +5242,7 @@ class McpServerPortalApplicationDestinationWorkerDestination(BaseModel): worker_id: str """The ID of the Cloudflare Worker to protect with Access.""" - overrides: Optional[List[McpServerPortalApplicationDestinationWorkerDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -5334,19 +5250,6 @@ class McpServerPortalApplicationDestinationWorkerDestination(BaseModel): """ -class McpServerPortalApplicationDestinationPreviewWorkerDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class McpServerPortalApplicationDestinationPreviewWorkerDestination(BaseModel): """A specific Cloudflare Worker whose preview deployments Access will secure. @@ -5361,7 +5264,7 @@ class McpServerPortalApplicationDestinationPreviewWorkerDestination(BaseModel): Access. """ - overrides: Optional[List[McpServerPortalApplicationDestinationPreviewWorkerDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -5369,19 +5272,6 @@ class McpServerPortalApplicationDestinationPreviewWorkerDestination(BaseModel): """ -class McpServerPortalApplicationDestinationAllWorkersDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class McpServerPortalApplicationDestinationAllWorkersDestination(BaseModel): """ Protects all Cloudflare Workers on the account with Access, including their preview deployments. At most one destination of this type can exist per account. The `worker`, `preview_worker`, `all_preview_workers`, and `public` destination types take precedence, so you can create separate applications to override the policies for specific Workers, their previews, or specific paths. @@ -5389,7 +5279,7 @@ class McpServerPortalApplicationDestinationAllWorkersDestination(BaseModel): type: Literal["all_workers"] - overrides: Optional[List[McpServerPortalApplicationDestinationAllWorkersDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -5397,19 +5287,6 @@ class McpServerPortalApplicationDestinationAllWorkersDestination(BaseModel): """ -class McpServerPortalApplicationDestinationAllPreviewWorkersDestinationOverride(BaseModel): - behavior: Literal["public"] - """The behavior to apply to matching requests.""" - - path_pattern: str - """The request path pattern to match. - - Wildcards (`*`) are supported, but each path segment may have at most one - wildcard. Unlike the `uri` in public destinations, override path patterns do not - implicitly cover subpaths; to do that, use a wildcard. - """ - - class McpServerPortalApplicationDestinationAllPreviewWorkersDestination(BaseModel): """ Protects the preview deployments of all Cloudflare Workers on the account with Access. At most one destination of this type can exist per account. The `worker`, `preview_worker`, and `public` destination types take precedence, so you can create separate applications to override the policies for specific Workers, their previews, or specific paths. @@ -5417,7 +5294,7 @@ class McpServerPortalApplicationDestinationAllPreviewWorkersDestination(BaseMode type: Literal["all_preview_workers"] - overrides: Optional[List[McpServerPortalApplicationDestinationAllPreviewWorkersDestinationOverride]] = None + overrides: Optional[List[DestinationOverride]] = None """Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. @@ -5591,6 +5468,13 @@ class McpServerPortalApplicationPolicy(BaseModel): name: Optional[str] = None """The name of the Access policy.""" + policy_resolution_account_id: Optional[str] = None + """ + The account ID used to resolve policy resources and identity for cross-account + WARP authentication. The account must be trusted by the account that owns this + policy. + """ + precedence: Optional[int] = None """The order of execution for this policy. @@ -5829,7 +5713,7 @@ class McpServerPortalApplication(BaseModel): """The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), - ms, s, m, h. Note: unsupported for infrastructure type applications. + ms, s, m, h. """ tags: Optional[List[str]] = None @@ -5840,6 +5724,7 @@ class McpServerPortalApplication(BaseModel): ApplicationUpdateResponse: TypeAlias = Union[ + EndUserApplication, SelfHostedApplication, SaaSApplication, BrowserSSHApplication, diff --git a/src/cloudflare/types/zero_trust/access/applications/access_rule.py b/src/cloudflare/types/zero_trust/access/applications/access_rule.py index 8b3777d0507..f41488d8690 100644 --- a/src/cloudflare/types/zero_trust/access/applications/access_rule.py +++ b/src/cloudflare/types/zero_trust/access/applications/access_rule.py @@ -34,6 +34,8 @@ "AccessLoginMethodRuleLoginMethod", "AccessOIDCClaimRule", "AccessOIDCClaimRuleOIDC", + "AccessServiceTokenTagRule", + "AccessServiceTokenTagRuleServiceTokenTag", "AccessLinkedAppTokenRule", "AccessLinkedAppTokenRuleLinkedAppToken", "AccessUserRiskScoreRule", @@ -105,6 +107,31 @@ class AccessOIDCClaimRule(BaseModel): oidc: AccessOIDCClaimRuleOIDC +class AccessServiceTokenTagRuleServiceTokenTag(BaseModel): + key: str + """The tag key to match. + + Keys are case-sensitive and may contain Unicode letters and digits, underscores, + periods, and hyphens. + """ + + value: str + """The tag value to match. + + Values are case-sensitive, preserve whitespace, and must not contain NUL + characters. + """ + + +class AccessServiceTokenTagRule(BaseModel): + """Matches an Access service token with the specified tag key and value. + + Only compatible with non_identity decisions. + """ + + service_token_tag: AccessServiceTokenTagRuleServiceTokenTag + + class AccessLinkedAppTokenRuleLinkedAppToken(BaseModel): app_uid: str """The ID of an Access OIDC SaaS application""" @@ -170,6 +197,7 @@ class AccessCloudflareAccountMemberRule(BaseModel): SAMLGroupRule, AccessOIDCClaimRule, ServiceTokenRule, + AccessServiceTokenTagRule, AccessLinkedAppTokenRule, AccessUserRiskScoreRule, AccessCloudflareAccountMemberRule, diff --git a/src/cloudflare/types/zero_trust/access/applications/access_rule_param.py b/src/cloudflare/types/zero_trust/access/applications/access_rule_param.py index dc92fec6309..285458bfb09 100644 --- a/src/cloudflare/types/zero_trust/access/applications/access_rule_param.py +++ b/src/cloudflare/types/zero_trust/access/applications/access_rule_param.py @@ -35,6 +35,8 @@ "AccessLoginMethodRuleLoginMethod", "AccessOIDCClaimRule", "AccessOIDCClaimRuleOIDC", + "AccessServiceTokenTagRule", + "AccessServiceTokenTagRuleServiceTokenTag", "AccessLinkedAppTokenRule", "AccessLinkedAppTokenRuleLinkedAppToken", "AccessUserRiskScoreRule", @@ -106,6 +108,31 @@ class AccessOIDCClaimRule(TypedDict, total=False): oidc: Required[AccessOIDCClaimRuleOIDC] +class AccessServiceTokenTagRuleServiceTokenTag(TypedDict, total=False): + key: Required[str] + """The tag key to match. + + Keys are case-sensitive and may contain Unicode letters and digits, underscores, + periods, and hyphens. + """ + + value: Required[str] + """The tag value to match. + + Values are case-sensitive, preserve whitespace, and must not contain NUL + characters. + """ + + +class AccessServiceTokenTagRule(TypedDict, total=False): + """Matches an Access service token with the specified tag key and value. + + Only compatible with non_identity decisions. + """ + + service_token_tag: Required[AccessServiceTokenTagRuleServiceTokenTag] + + class AccessLinkedAppTokenRuleLinkedAppToken(TypedDict, total=False): app_uid: Required[str] """The ID of an Access OIDC SaaS application""" @@ -171,6 +198,7 @@ class AccessCloudflareAccountMemberRule(TypedDict, total=False): SAMLGroupRuleParam, AccessOIDCClaimRule, ServiceTokenRuleParam, + AccessServiceTokenTagRule, AccessLinkedAppTokenRule, AccessUserRiskScoreRule, AccessCloudflareAccountMemberRule, diff --git a/src/cloudflare/types/zero_trust/access/applications/policy_create_params.py b/src/cloudflare/types/zero_trust/access/applications/policy_create_params.py index 94f2bf548da..af9e2b78b30 100644 --- a/src/cloudflare/types/zero_trust/access/applications/policy_create_params.py +++ b/src/cloudflare/types/zero_trust/access/applications/policy_create_params.py @@ -158,6 +158,13 @@ class AccessInfraPolicyReq(TypedDict, total=False): applications. """ + policy_resolution_account_id: str + """ + The account ID used to resolve policy resources and identity for cross-account + WARP authentication. The account must be trusted by the account that owns this + policy. + """ + require: Iterable[AccessRuleParam] """Rules evaluated with an AND logical operator. diff --git a/src/cloudflare/types/zero_trust/access/applications/policy_create_response.py b/src/cloudflare/types/zero_trust/access/applications/policy_create_response.py index eafc52b7a24..ab4813db331 100644 --- a/src/cloudflare/types/zero_trust/access/applications/policy_create_response.py +++ b/src/cloudflare/types/zero_trust/access/applications/policy_create_response.py @@ -120,6 +120,13 @@ class UnionMember0(BaseModel): name: Optional[str] = None """The name of the Access policy.""" + policy_resolution_account_id: Optional[str] = None + """ + The account ID used to resolve policy resources and identity for cross-account + WARP authentication. The account must be trusted by the account that owns this + policy. + """ + precedence: Optional[int] = None """The order of execution for this policy. @@ -237,6 +244,13 @@ class UnionMember1(BaseModel): name: Optional[str] = None """The name of the Access policy.""" + policy_resolution_account_id: Optional[str] = None + """ + The account ID used to resolve policy resources and identity for cross-account + WARP authentication. The account must be trusted by the account that owns this + policy. + """ + require: Optional[List[AccessRule]] = None """Rules evaluated with an AND logical operator. diff --git a/src/cloudflare/types/zero_trust/access/applications/policy_get_response.py b/src/cloudflare/types/zero_trust/access/applications/policy_get_response.py index d8a1a3df929..640eee5403c 100644 --- a/src/cloudflare/types/zero_trust/access/applications/policy_get_response.py +++ b/src/cloudflare/types/zero_trust/access/applications/policy_get_response.py @@ -120,6 +120,13 @@ class UnionMember0(BaseModel): name: Optional[str] = None """The name of the Access policy.""" + policy_resolution_account_id: Optional[str] = None + """ + The account ID used to resolve policy resources and identity for cross-account + WARP authentication. The account must be trusted by the account that owns this + policy. + """ + precedence: Optional[int] = None """The order of execution for this policy. @@ -237,6 +244,13 @@ class UnionMember1(BaseModel): name: Optional[str] = None """The name of the Access policy.""" + policy_resolution_account_id: Optional[str] = None + """ + The account ID used to resolve policy resources and identity for cross-account + WARP authentication. The account must be trusted by the account that owns this + policy. + """ + require: Optional[List[AccessRule]] = None """Rules evaluated with an AND logical operator. diff --git a/src/cloudflare/types/zero_trust/access/applications/policy_list_response.py b/src/cloudflare/types/zero_trust/access/applications/policy_list_response.py index 9bfecea2ea3..b3dc3892770 100644 --- a/src/cloudflare/types/zero_trust/access/applications/policy_list_response.py +++ b/src/cloudflare/types/zero_trust/access/applications/policy_list_response.py @@ -120,6 +120,13 @@ class UnionMember0(BaseModel): name: Optional[str] = None """The name of the Access policy.""" + policy_resolution_account_id: Optional[str] = None + """ + The account ID used to resolve policy resources and identity for cross-account + WARP authentication. The account must be trusted by the account that owns this + policy. + """ + precedence: Optional[int] = None """The order of execution for this policy. @@ -237,6 +244,13 @@ class UnionMember1(BaseModel): name: Optional[str] = None """The name of the Access policy.""" + policy_resolution_account_id: Optional[str] = None + """ + The account ID used to resolve policy resources and identity for cross-account + WARP authentication. The account must be trusted by the account that owns this + policy. + """ + require: Optional[List[AccessRule]] = None """Rules evaluated with an AND logical operator. diff --git a/src/cloudflare/types/zero_trust/access/applications/policy_test_create_params.py b/src/cloudflare/types/zero_trust/access/applications/policy_test_create_params.py index 2a51da86148..07ee5f19645 100644 --- a/src/cloudflare/types/zero_trust/access/applications/policy_test_create_params.py +++ b/src/cloudflare/types/zero_trust/access/applications/policy_test_create_params.py @@ -117,6 +117,13 @@ class PolicyUnionMember0(TypedDict, total=False): mfa_config: PolicyUnionMember0MfaConfig """Configures multi-factor authentication (MFA) settings.""" + policy_resolution_account_id: str + """ + The account ID used to resolve policy resources and identity for cross-account + WARP authentication. The account must be trusted by the account that owns this + policy. + """ + purpose_justification_prompt: str """A custom message that will appear on the purpose justification screen.""" diff --git a/src/cloudflare/types/zero_trust/access/applications/policy_update_params.py b/src/cloudflare/types/zero_trust/access/applications/policy_update_params.py index 1eb5a8f1f75..08fb7d53f8e 100644 --- a/src/cloudflare/types/zero_trust/access/applications/policy_update_params.py +++ b/src/cloudflare/types/zero_trust/access/applications/policy_update_params.py @@ -164,6 +164,13 @@ class AccessInfraPolicyReq(TypedDict, total=False): applications. """ + policy_resolution_account_id: str + """ + The account ID used to resolve policy resources and identity for cross-account + WARP authentication. The account must be trusted by the account that owns this + policy. + """ + require: Iterable[AccessRuleParam] """Rules evaluated with an AND logical operator. diff --git a/src/cloudflare/types/zero_trust/access/applications/policy_update_response.py b/src/cloudflare/types/zero_trust/access/applications/policy_update_response.py index cebf83df622..6d1c4a257c7 100644 --- a/src/cloudflare/types/zero_trust/access/applications/policy_update_response.py +++ b/src/cloudflare/types/zero_trust/access/applications/policy_update_response.py @@ -120,6 +120,13 @@ class UnionMember0(BaseModel): name: Optional[str] = None """The name of the Access policy.""" + policy_resolution_account_id: Optional[str] = None + """ + The account ID used to resolve policy resources and identity for cross-account + WARP authentication. The account must be trusted by the account that owns this + policy. + """ + precedence: Optional[int] = None """The order of execution for this policy. @@ -237,6 +244,13 @@ class UnionMember1(BaseModel): name: Optional[str] = None """The name of the Access policy.""" + policy_resolution_account_id: Optional[str] = None + """ + The account ID used to resolve policy resources and identity for cross-account + WARP authentication. The account must be trusted by the account that owns this + policy. + """ + require: Optional[List[AccessRule]] = None """Rules evaluated with an AND logical operator. diff --git a/src/cloudflare/types/zero_trust/access/custom_page_validate_params.py b/src/cloudflare/types/zero_trust/access/custom_page_validate_params.py new file mode 100644 index 00000000000..a485027357d --- /dev/null +++ b/src/cloudflare/types/zero_trust/access/custom_page_validate_params.py @@ -0,0 +1,21 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal, Required, TypedDict + +__all__ = ["CustomPageValidateParams"] + + +class CustomPageValidateParams(TypedDict, total=False): + account_id: Required[str] + """Identifier.""" + + template: Required[str] + """The Liquid template to validate.""" + + type: Required[Literal["identity_denied", "forbidden", "login", "interstitial"]] + """Custom page type.""" + + version: int + """Contract version to validate against; omit for the latest.""" diff --git a/src/cloudflare/types/zero_trust/access/custom_page_validate_response.py b/src/cloudflare/types/zero_trust/access/custom_page_validate_response.py new file mode 100644 index 00000000000..8a2452c09c6 --- /dev/null +++ b/src/cloudflare/types/zero_trust/access/custom_page_validate_response.py @@ -0,0 +1,50 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional +from typing_extensions import Literal + +from ...._models import BaseModel + +__all__ = ["CustomPageValidateResponse", "Error", "Warning"] + + +class Error(BaseModel): + """A single validation finding for a template.""" + + message: str + """Human-readable description of the finding.""" + + tier: str + """The validation tier that produced the finding (e.g. html, liquid).""" + + ref: Optional[str] = None + """Optional pointer to the part of the template the finding refers to.""" + + +class Warning(BaseModel): + """A single validation finding for a template.""" + + message: str + """Human-readable description of the finding.""" + + tier: str + """The validation tier that produced the finding (e.g. html, liquid).""" + + ref: Optional[str] = None + """Optional pointer to the part of the template the finding refers to.""" + + +class CustomPageValidateResponse(BaseModel): + """The result of validating a template's content.""" + + errors: List[Error] + """Blocking findings; a non-empty list means the template cannot be published.""" + + page_type: Literal["identity_denied", "forbidden", "login", "interstitial"] + """Custom page type.""" + + version: int + """The contract version the template was validated against.""" + + warnings: List[Warning] + """Advisory findings that do not block publishing.""" diff --git a/src/cloudflare/types/zero_trust/access/destination_override.py b/src/cloudflare/types/zero_trust/access/destination_override.py new file mode 100644 index 00000000000..f4f1b61a1aa --- /dev/null +++ b/src/cloudflare/types/zero_trust/access/destination_override.py @@ -0,0 +1,20 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing_extensions import Literal + +from ...._models import BaseModel + +__all__ = ["DestinationOverride"] + + +class DestinationOverride(BaseModel): + behavior: Literal["public"] + """The behavior to apply to matching requests.""" + + path_pattern: str + """The request path pattern to match. + + Wildcards (`*`) are supported, but each path segment may have at most one + wildcard. Unlike the `uri` in public destinations, override path patterns do not + implicitly cover subpaths; to do that, use a wildcard. + """ diff --git a/src/cloudflare/types/zero_trust/access/destination_override_param.py b/src/cloudflare/types/zero_trust/access/destination_override_param.py new file mode 100644 index 00000000000..d36c31950a0 --- /dev/null +++ b/src/cloudflare/types/zero_trust/access/destination_override_param.py @@ -0,0 +1,20 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal, Required, TypedDict + +__all__ = ["DestinationOverrideParam"] + + +class DestinationOverrideParam(TypedDict, total=False): + behavior: Required[Literal["public"]] + """The behavior to apply to matching requests.""" + + path_pattern: Required[str] + """The request path pattern to match. + + Wildcards (`*`) are supported, but each path segment may have at most one + wildcard. Unlike the `uri` in public destinations, override path patterns do not + implicitly cover subpaths; to do that, use a wildcard. + """ diff --git a/src/cloudflare/types/zero_trust/access/logs/__init__.py b/src/cloudflare/types/zero_trust/access/logs/__init__.py index a6057a5095f..b6fd2f75460 100644 --- a/src/cloudflare/types/zero_trust/access/logs/__init__.py +++ b/src/cloudflare/types/zero_trust/access/logs/__init__.py @@ -3,5 +3,8 @@ from __future__ import annotations from .access_request import AccessRequest as AccessRequest +from .jit_request_list_params import JitRequestListParams as JitRequestListParams +from .jit_request_get_response import JitRequestGetResponse as JitRequestGetResponse +from .jit_request_list_response import JitRequestListResponse as JitRequestListResponse from .access_request_list_params import AccessRequestListParams as AccessRequestListParams from .access_request_list_response import AccessRequestListResponse as AccessRequestListResponse diff --git a/src/cloudflare/types/zero_trust/access/logs/jit_request_get_response.py b/src/cloudflare/types/zero_trust/access/logs/jit_request_get_response.py new file mode 100644 index 00000000000..72970ee3747 --- /dev/null +++ b/src/cloudflare/types/zero_trust/access/logs/jit_request_get_response.py @@ -0,0 +1,62 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional +from datetime import datetime +from typing_extensions import Literal + +from pydantic import Field as FieldInfo + +from ....._models import BaseModel + +__all__ = ["JitRequestGetResponse", "Event"] + + +class Event(BaseModel): + actor_email: Optional[str] = None + + actor_idp: Optional[str] = None + + actor_uuid: Optional[str] = None + + decision_outcome: Optional[str] = None + + rayid: Optional[str] = FieldInfo(alias="ray_id", default=None) + + session_duration_seconds: Optional[int] = None + + success: Optional[bool] = None + + timestamp: Optional[datetime] = None + + type: Optional[ + Literal["CREATED", "APPROVER_DECISION", "COMMITTED", "CANCELED", "LOGIN_SUCCESS", "REDIRECT_TO_ACTIVE"] + ] = None + + +class JitRequestGetResponse(BaseModel): + app_aud: Optional[str] = None + """Audience of the Access application.""" + + app_hostname: Optional[str] = None + + approvals_received: Optional[int] = None + """Number of unique actors who approved the request.""" + + approver_emails: Optional[List[str]] = None + """Unique actors who approved the request.""" + + created_at: Optional[datetime] = None + + events: Optional[List[Event]] = None + + expires_at: Optional[datetime] = None + + knock_request_id: Optional[str] = None + """Unique identifier for the JIT request.""" + + purpose_justification: Optional[str] = None + + requester_email: Optional[str] = None + + status: Optional[Literal["PENDING", "APPROVED", "DENIED", "CANCELED", "SPENT"]] = None + """JIT request status. `SPENT` is deprecated and interpreted as `APPROVED`.""" diff --git a/src/cloudflare/types/zero_trust/access/logs/jit_request_list_params.py b/src/cloudflare/types/zero_trust/access/logs/jit_request_list_params.py new file mode 100644 index 00000000000..6abbcf01dc9 --- /dev/null +++ b/src/cloudflare/types/zero_trust/access/logs/jit_request_list_params.py @@ -0,0 +1,40 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Union +from datetime import datetime +from typing_extensions import Literal, Required, Annotated, TypedDict + +from ....._utils import PropertyInfo + +__all__ = ["JitRequestListParams"] + + +class JitRequestListParams(TypedDict, total=False): + account_id: Required[str] + """Identifier.""" + + page: int + """Page number of results.""" + + per_page: int + """Number of results per page.""" + + search: str + """ + Case-insensitive search over request ID, requester email, application audience, + and application hostname. + """ + + since: Annotated[Union[str, datetime], PropertyInfo(format="iso8601")] + """The earliest request timestamp to query. + + Defaults to 366 days before the current time. + """ + + status: Literal["PENDING", "APPROVED", "DENIED", "CANCELED", "SPENT"] + """JIT request status. `SPENT` is deprecated and interpreted as `APPROVED`.""" + + until: Annotated[Union[str, datetime], PropertyInfo(format="iso8601")] + """The latest request timestamp to query. Defaults to the current time.""" diff --git a/src/cloudflare/types/zero_trust/access/logs/jit_request_list_response.py b/src/cloudflare/types/zero_trust/access/logs/jit_request_list_response.py new file mode 100644 index 00000000000..e0a221a778b --- /dev/null +++ b/src/cloudflare/types/zero_trust/access/logs/jit_request_list_response.py @@ -0,0 +1,36 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional +from datetime import datetime +from typing_extensions import Literal + +from ....._models import BaseModel + +__all__ = ["JitRequestListResponse"] + + +class JitRequestListResponse(BaseModel): + app_aud: Optional[str] = None + """Audience of the Access application.""" + + app_hostname: Optional[str] = None + + approvals_received: Optional[int] = None + """Number of unique actors who approved the request.""" + + approver_emails: Optional[List[str]] = None + """Unique actors who approved the request.""" + + created_at: Optional[datetime] = None + + expires_at: Optional[datetime] = None + + knock_request_id: Optional[str] = None + """Unique identifier for the JIT request.""" + + purpose_justification: Optional[str] = None + + requester_email: Optional[str] = None + + status: Optional[Literal["PENDING", "APPROVED", "DENIED", "CANCELED", "SPENT"]] = None + """JIT request status. `SPENT` is deprecated and interpreted as `APPROVED`.""" diff --git a/src/cloudflare/types/zero_trust/access/mfa/__init__.py b/src/cloudflare/types/zero_trust/access/mfa/__init__.py new file mode 100644 index 00000000000..e62c5232f1b --- /dev/null +++ b/src/cloudflare/types/zero_trust/access/mfa/__init__.py @@ -0,0 +1,5 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from .authenticator_catalog_list_response import AuthenticatorCatalogListResponse as AuthenticatorCatalogListResponse diff --git a/src/cloudflare/types/zero_trust/access/mfa/authenticator_catalog_list_response.py b/src/cloudflare/types/zero_trust/access/mfa/authenticator_catalog_list_response.py new file mode 100644 index 00000000000..95abf03899b --- /dev/null +++ b/src/cloudflare/types/zero_trust/access/mfa/authenticator_catalog_list_response.py @@ -0,0 +1,18 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from ....._models import BaseModel + +__all__ = ["AuthenticatorCatalogListResponse"] + + +class AuthenticatorCatalogListResponse(BaseModel): + """A FIDO2 authenticator device AAGUID entry""" + + aaguid: str + """ + The Authenticator Attestation GUID (AAGUID) uniquely identifying a FIDO2 + authenticator model + """ + + name: str + """The human-readable name of the FIDO2 authenticator""" diff --git a/src/cloudflare/types/zero_trust/access/policy_create_params.py b/src/cloudflare/types/zero_trust/access/policy_create_params.py index 9bde14a455a..c4ec30b8c2b 100644 --- a/src/cloudflare/types/zero_trust/access/policy_create_params.py +++ b/src/cloudflare/types/zero_trust/access/policy_create_params.py @@ -62,6 +62,13 @@ class PolicyCreateParams(TypedDict, total=False): mfa_config: MfaConfig """Configures multi-factor authentication (MFA) settings.""" + policy_resolution_account_id: str + """ + The account ID used to resolve policy resources and identity for cross-account + WARP authentication. The account must be trusted by the account that owns this + policy. + """ + purpose_justification_prompt: str """A custom message that will appear on the purpose justification screen.""" diff --git a/src/cloudflare/types/zero_trust/access/policy_create_response.py b/src/cloudflare/types/zero_trust/access/policy_create_response.py index d283e56622c..cc984435ba8 100644 --- a/src/cloudflare/types/zero_trust/access/policy_create_response.py +++ b/src/cloudflare/types/zero_trust/access/policy_create_response.py @@ -113,6 +113,13 @@ class PolicyCreateResponse(BaseModel): name: Optional[str] = None """The name of the Access policy.""" + policy_resolution_account_id: Optional[str] = None + """ + The account ID used to resolve policy resources and identity for cross-account + WARP authentication. The account must be trusted by the account that owns this + policy. + """ + purpose_justification_prompt: Optional[str] = None """A custom message that will appear on the purpose justification screen.""" diff --git a/src/cloudflare/types/zero_trust/access/policy_get_response.py b/src/cloudflare/types/zero_trust/access/policy_get_response.py index 515e0abf759..9bc61b63348 100644 --- a/src/cloudflare/types/zero_trust/access/policy_get_response.py +++ b/src/cloudflare/types/zero_trust/access/policy_get_response.py @@ -113,6 +113,13 @@ class PolicyGetResponse(BaseModel): name: Optional[str] = None """The name of the Access policy.""" + policy_resolution_account_id: Optional[str] = None + """ + The account ID used to resolve policy resources and identity for cross-account + WARP authentication. The account must be trusted by the account that owns this + policy. + """ + purpose_justification_prompt: Optional[str] = None """A custom message that will appear on the purpose justification screen.""" diff --git a/src/cloudflare/types/zero_trust/access/policy_list_response.py b/src/cloudflare/types/zero_trust/access/policy_list_response.py index 4b79075ecad..38f137efb5a 100644 --- a/src/cloudflare/types/zero_trust/access/policy_list_response.py +++ b/src/cloudflare/types/zero_trust/access/policy_list_response.py @@ -113,6 +113,13 @@ class PolicyListResponse(BaseModel): name: Optional[str] = None """The name of the Access policy.""" + policy_resolution_account_id: Optional[str] = None + """ + The account ID used to resolve policy resources and identity for cross-account + WARP authentication. The account must be trusted by the account that owns this + policy. + """ + purpose_justification_prompt: Optional[str] = None """A custom message that will appear on the purpose justification screen.""" diff --git a/src/cloudflare/types/zero_trust/access/policy_update_params.py b/src/cloudflare/types/zero_trust/access/policy_update_params.py index 5e0c9e6eb40..d5d0c0516ef 100644 --- a/src/cloudflare/types/zero_trust/access/policy_update_params.py +++ b/src/cloudflare/types/zero_trust/access/policy_update_params.py @@ -62,6 +62,13 @@ class PolicyUpdateParams(TypedDict, total=False): mfa_config: MfaConfig """Configures multi-factor authentication (MFA) settings.""" + policy_resolution_account_id: str + """ + The account ID used to resolve policy resources and identity for cross-account + WARP authentication. The account must be trusted by the account that owns this + policy. + """ + purpose_justification_prompt: str """A custom message that will appear on the purpose justification screen.""" diff --git a/src/cloudflare/types/zero_trust/access/policy_update_response.py b/src/cloudflare/types/zero_trust/access/policy_update_response.py index 1be42c9ad16..5538e4c7eca 100644 --- a/src/cloudflare/types/zero_trust/access/policy_update_response.py +++ b/src/cloudflare/types/zero_trust/access/policy_update_response.py @@ -113,6 +113,13 @@ class PolicyUpdateResponse(BaseModel): name: Optional[str] = None """The name of the Access policy.""" + policy_resolution_account_id: Optional[str] = None + """ + The account ID used to resolve policy resources and identity for cross-account + WARP authentication. The account must be trusted by the account that owns this + policy. + """ + purpose_justification_prompt: Optional[str] = None """A custom message that will appear on the purpose justification screen.""" diff --git a/src/cloudflare/types/zero_trust/access/service_token.py b/src/cloudflare/types/zero_trust/access/service_token.py index 082c660d620..07e9eaffd6c 100644 --- a/src/cloudflare/types/zero_trust/access/service_token.py +++ b/src/cloudflare/types/zero_trust/access/service_token.py @@ -1,6 +1,6 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import Optional +from typing import Dict, Optional from datetime import datetime from ...._models import BaseModel @@ -31,10 +31,38 @@ class ServiceToken(BaseModel): A disabled service token cannot be used to authenticate; both its current and previous `client_secret` stop being accepted, but the token itself is preserved - and can be re-enabled at any time. Defaults to enabled when omitted on create. + and can be re-enabled. A service token reported as leaked is disabled + automatically and cannot be re-enabled until its secret is rotated; attempting + to do so returns a 409. Defaults to enabled when omitted on create. """ expires_at: Optional[datetime] = None + leak_report_url: Optional[str] = None + """Where the leaked `client_secret` was found, if provided by the reporter. + + Omitted if the token has not been reported as leaked. + """ + + leak_reported_at: Optional[datetime] = None + """ + When a secret scanning partner reported this service token's `client_secret` as + leaked. A leaked service token is disabled and must be rotated before it can be + re-enabled. Cleared once the secret is rotated. Omitted if the token has not + been reported as leaked. + """ + + leak_reporter: Optional[str] = None + """The secret scanning partner that reported the leak. + + Omitted if the token has not been reported as leaked. + """ + name: Optional[str] = None """The name of the service token.""" + + tags: Optional[Dict[str, str]] = None + """Tags associated with the service token, as key-value pairs. + + On update, replaces all existing tags. + """ diff --git a/src/cloudflare/types/zero_trust/access/service_token_create_params.py b/src/cloudflare/types/zero_trust/access/service_token_create_params.py index dce7270a988..1beb3b273a9 100644 --- a/src/cloudflare/types/zero_trust/access/service_token_create_params.py +++ b/src/cloudflare/types/zero_trust/access/service_token_create_params.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing import Union +from typing import Dict, Union, Optional from datetime import datetime from typing_extensions import Required, Annotated, TypedDict @@ -26,7 +26,9 @@ class ServiceTokenCreateParams(TypedDict, total=False): A version number identifying the current `client_secret` associated with the service token. Incrementing it triggers a rotation; the previous secret will still be accepted until the time indicated by - `previous_client_secret_expires_at`. + `previous_client_secret_expires_at`. If the service token was reported as + leaked, `previous_client_secret_expires_at` is not required, may not be in the + future, and the previous secret is discarded immediately. """ duration: str @@ -42,7 +44,9 @@ class ServiceTokenCreateParams(TypedDict, total=False): A disabled service token cannot be used to authenticate; both its current and previous `client_secret` stop being accepted, but the token itself is preserved - and can be re-enabled at any time. Defaults to enabled when omitted on create. + and can be re-enabled. A service token reported as leaked is disabled + automatically and cannot be re-enabled until its secret is rotated; attempting + to do so returns a 409. Defaults to enabled when omitted on create. """ previous_client_secret_expires_at: Annotated[Union[str, datetime], PropertyInfo(format="iso8601")] @@ -51,5 +55,12 @@ class ServiceTokenCreateParams(TypedDict, total=False): This can be modified at any point after a rotation. For example, you may extend it further into the future if you need more time to update services with the new secret; or move it into the past to immediately invalidate the previous token in - case of compromise. + case of compromise. Rotating a service token that was reported as leaked + discards the previous secret entirely, so no grace period can be set. + """ + + tags: Optional[Dict[str, str]] + """Tags associated with the service token, as key-value pairs. + + On update, replaces all existing tags. """ diff --git a/src/cloudflare/types/zero_trust/access/service_token_create_response.py b/src/cloudflare/types/zero_trust/access/service_token_create_response.py index ef22a9eadc1..0c0bba7f8e8 100644 --- a/src/cloudflare/types/zero_trust/access/service_token_create_response.py +++ b/src/cloudflare/types/zero_trust/access/service_token_create_response.py @@ -1,6 +1,6 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import Optional +from typing import Dict, Optional from ...._models import BaseModel @@ -37,8 +37,16 @@ class ServiceTokenCreateResponse(BaseModel): A disabled service token cannot be used to authenticate; both its current and previous `client_secret` stop being accepted, but the token itself is preserved - and can be re-enabled at any time. Defaults to enabled when omitted on create. + and can be re-enabled. A service token reported as leaked is disabled + automatically and cannot be re-enabled until its secret is rotated; attempting + to do so returns a 409. Defaults to enabled when omitted on create. """ name: Optional[str] = None """The name of the service token.""" + + tags: Optional[Dict[str, str]] = None + """Tags associated with the service token, as key-value pairs. + + On update, replaces all existing tags. + """ diff --git a/src/cloudflare/types/zero_trust/access/service_token_rotate_params.py b/src/cloudflare/types/zero_trust/access/service_token_rotate_params.py index 2fb1017ea1a..9380d8c400d 100644 --- a/src/cloudflare/types/zero_trust/access/service_token_rotate_params.py +++ b/src/cloudflare/types/zero_trust/access/service_token_rotate_params.py @@ -19,5 +19,6 @@ class ServiceTokenRotateParams(TypedDict, total=False): """The expiration of the previous `client_secret`. If not provided, it defaults to the current timestamp in order to immediately - expire the previous secret. + expire the previous secret. If the service token was reported as leaked, this + must not be in the future; the leaked secret is discarded immediately. """ diff --git a/src/cloudflare/types/zero_trust/access/service_token_rotate_response.py b/src/cloudflare/types/zero_trust/access/service_token_rotate_response.py index f6763c177b4..0344a6d7d1e 100644 --- a/src/cloudflare/types/zero_trust/access/service_token_rotate_response.py +++ b/src/cloudflare/types/zero_trust/access/service_token_rotate_response.py @@ -1,6 +1,6 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import Optional +from typing import Dict, Optional from ...._models import BaseModel @@ -37,8 +37,16 @@ class ServiceTokenRotateResponse(BaseModel): A disabled service token cannot be used to authenticate; both its current and previous `client_secret` stop being accepted, but the token itself is preserved - and can be re-enabled at any time. Defaults to enabled when omitted on create. + and can be re-enabled. A service token reported as leaked is disabled + automatically and cannot be re-enabled until its secret is rotated; attempting + to do so returns a 409. Defaults to enabled when omitted on create. """ name: Optional[str] = None """The name of the service token.""" + + tags: Optional[Dict[str, str]] = None + """Tags associated with the service token, as key-value pairs. + + On update, replaces all existing tags. + """ diff --git a/src/cloudflare/types/zero_trust/access/service_token_update_params.py b/src/cloudflare/types/zero_trust/access/service_token_update_params.py index bce789b14ae..71773feac9e 100644 --- a/src/cloudflare/types/zero_trust/access/service_token_update_params.py +++ b/src/cloudflare/types/zero_trust/access/service_token_update_params.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing import Union +from typing import Dict, Union, Optional from datetime import datetime from typing_extensions import Annotated, TypedDict @@ -23,7 +23,9 @@ class ServiceTokenUpdateParams(TypedDict, total=False): A version number identifying the current `client_secret` associated with the service token. Incrementing it triggers a rotation; the previous secret will still be accepted until the time indicated by - `previous_client_secret_expires_at`. + `previous_client_secret_expires_at`. If the service token was reported as + leaked, `previous_client_secret_expires_at` is not required, may not be in the + future, and the previous secret is discarded immediately. """ duration: str @@ -39,7 +41,9 @@ class ServiceTokenUpdateParams(TypedDict, total=False): A disabled service token cannot be used to authenticate; both its current and previous `client_secret` stop being accepted, but the token itself is preserved - and can be re-enabled at any time. Defaults to enabled when omitted on create. + and can be re-enabled. A service token reported as leaked is disabled + automatically and cannot be re-enabled until its secret is rotated; attempting + to do so returns a 409. Defaults to enabled when omitted on create. """ name: str @@ -51,5 +55,12 @@ class ServiceTokenUpdateParams(TypedDict, total=False): This can be modified at any point after a rotation. For example, you may extend it further into the future if you need more time to update services with the new secret; or move it into the past to immediately invalidate the previous token in - case of compromise. + case of compromise. Rotating a service token that was reported as leaked + discards the previous secret entirely, so no grace period can be set. + """ + + tags: Optional[Dict[str, str]] + """Tags associated with the service token, as key-value pairs. + + On update, replaces all existing tags. """ diff --git a/src/cloudflare/types/zero_trust/access/user_population_create_params.py b/src/cloudflare/types/zero_trust/access/user_population_create_params.py new file mode 100644 index 00000000000..d793735627c --- /dev/null +++ b/src/cloudflare/types/zero_trust/access/user_population_create_params.py @@ -0,0 +1,20 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Required, TypedDict + +__all__ = ["UserPopulationCreateParams"] + + +class UserPopulationCreateParams(TypedDict, total=False): + account_id: Required[str] + """Identifier.""" + + name: Required[str] + """The name of the user population. + + Leading and trailing whitespace is trimmed before validation. After trimming, + the name must contain at least one non-whitespace character and must not exceed + 128 UTF-8 bytes. + """ diff --git a/src/cloudflare/types/zero_trust/access/user_population_create_response.py b/src/cloudflare/types/zero_trust/access/user_population_create_response.py new file mode 100644 index 00000000000..5cda11483ee --- /dev/null +++ b/src/cloudflare/types/zero_trust/access/user_population_create_response.py @@ -0,0 +1,18 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from ...._models import BaseModel + +__all__ = ["UserPopulationCreateResponse"] + + +class UserPopulationCreateResponse(BaseModel): + id: str + """UUID.""" + + name: str + """The name of the user population. + + Leading and trailing whitespace is trimmed before validation. After trimming, + the name must contain at least one non-whitespace character and must not exceed + 128 UTF-8 bytes. + """ diff --git a/src/cloudflare/types/zero_trust/access/user_population_delete_response.py b/src/cloudflare/types/zero_trust/access/user_population_delete_response.py new file mode 100644 index 00000000000..f8d4ae06a64 --- /dev/null +++ b/src/cloudflare/types/zero_trust/access/user_population_delete_response.py @@ -0,0 +1,12 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional + +from ...._models import BaseModel + +__all__ = ["UserPopulationDeleteResponse"] + + +class UserPopulationDeleteResponse(BaseModel): + id: Optional[str] = None + """UUID.""" diff --git a/src/cloudflare/types/zero_trust/access/user_population_get_response.py b/src/cloudflare/types/zero_trust/access/user_population_get_response.py new file mode 100644 index 00000000000..e2f2c18fef0 --- /dev/null +++ b/src/cloudflare/types/zero_trust/access/user_population_get_response.py @@ -0,0 +1,18 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from ...._models import BaseModel + +__all__ = ["UserPopulationGetResponse"] + + +class UserPopulationGetResponse(BaseModel): + id: str + """UUID.""" + + name: str + """The name of the user population. + + Leading and trailing whitespace is trimmed before validation. After trimming, + the name must contain at least one non-whitespace character and must not exceed + 128 UTF-8 bytes. + """ diff --git a/src/cloudflare/types/zero_trust/access/user_population_list_params.py b/src/cloudflare/types/zero_trust/access/user_population_list_params.py new file mode 100644 index 00000000000..44ef65ee5d8 --- /dev/null +++ b/src/cloudflare/types/zero_trust/access/user_population_list_params.py @@ -0,0 +1,18 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Required, TypedDict + +__all__ = ["UserPopulationListParams"] + + +class UserPopulationListParams(TypedDict, total=False): + account_id: Required[str] + """Identifier.""" + + page: int + """Page number of results.""" + + per_page: int + """Number of results per page.""" diff --git a/src/cloudflare/types/zero_trust/access/user_population_list_response.py b/src/cloudflare/types/zero_trust/access/user_population_list_response.py new file mode 100644 index 00000000000..949d3223013 --- /dev/null +++ b/src/cloudflare/types/zero_trust/access/user_population_list_response.py @@ -0,0 +1,18 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from ...._models import BaseModel + +__all__ = ["UserPopulationListResponse"] + + +class UserPopulationListResponse(BaseModel): + id: str + """UUID.""" + + name: str + """The name of the user population. + + Leading and trailing whitespace is trimmed before validation. After trimming, + the name must contain at least one non-whitespace character and must not exceed + 128 UTF-8 bytes. + """ diff --git a/src/cloudflare/types/zero_trust/access/user_population_update_params.py b/src/cloudflare/types/zero_trust/access/user_population_update_params.py new file mode 100644 index 00000000000..d5d129d561a --- /dev/null +++ b/src/cloudflare/types/zero_trust/access/user_population_update_params.py @@ -0,0 +1,20 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Required, TypedDict + +__all__ = ["UserPopulationUpdateParams"] + + +class UserPopulationUpdateParams(TypedDict, total=False): + account_id: Required[str] + """Identifier.""" + + name: Required[str] + """The name of the user population. + + Leading and trailing whitespace is trimmed before validation. After trimming, + the name must contain at least one non-whitespace character and must not exceed + 128 UTF-8 bytes. + """ diff --git a/src/cloudflare/types/zero_trust/access/user_population_update_response.py b/src/cloudflare/types/zero_trust/access/user_population_update_response.py new file mode 100644 index 00000000000..e8ed248b74c --- /dev/null +++ b/src/cloudflare/types/zero_trust/access/user_population_update_response.py @@ -0,0 +1,18 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from ...._models import BaseModel + +__all__ = ["UserPopulationUpdateResponse"] + + +class UserPopulationUpdateResponse(BaseModel): + id: str + """UUID.""" + + name: str + """The name of the user population. + + Leading and trailing whitespace is trimmed before validation. After trimming, + the name must contain at least one non-whitespace character and must not exceed + 128 UTF-8 bytes. + """ diff --git a/src/cloudflare/types/zero_trust/access/user_populations/__init__.py b/src/cloudflare/types/zero_trust/access/user_populations/__init__.py new file mode 100644 index 00000000000..01049c03bfb --- /dev/null +++ b/src/cloudflare/types/zero_trust/access/user_populations/__init__.py @@ -0,0 +1,14 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from .user_get_params import UserGetParams as UserGetParams +from .user_list_params import UserListParams as UserListParams +from .user_get_response import UserGetResponse as UserGetResponse +from .user_create_params import UserCreateParams as UserCreateParams +from .user_list_response import UserListResponse as UserListResponse +from .user_update_params import UserUpdateParams as UserUpdateParams +from .user_replace_params import UserReplaceParams as UserReplaceParams +from .user_create_response import UserCreateResponse as UserCreateResponse +from .user_update_response import UserUpdateResponse as UserUpdateResponse +from .user_replace_response import UserReplaceResponse as UserReplaceResponse diff --git a/src/cloudflare/types/zero_trust/access/user_populations/user_create_params.py b/src/cloudflare/types/zero_trust/access/user_populations/user_create_params.py new file mode 100644 index 00000000000..30f8834c07e --- /dev/null +++ b/src/cloudflare/types/zero_trust/access/user_populations/user_create_params.py @@ -0,0 +1,68 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Union, Iterable +from datetime import datetime +from typing_extensions import Required, Annotated, TypedDict + +from ....._types import SequenceNotStr +from ....._utils import PropertyInfo + +__all__ = ["UserCreateParams", "Email", "Meta", "Name"] + + +class UserCreateParams(TypedDict, total=False): + account_id: Required[str] + """Identifier.""" + + active: bool + + display_name: Annotated[str, PropertyInfo(alias="displayName")] + + emails: Iterable[Email] + + external_id: Annotated[str, PropertyInfo(alias="externalId")] + + meta: Meta + + name: Name + + schemas: SequenceNotStr[str] + """The SCIM schemas that apply to this resource.""" + + user_name: Annotated[str, PropertyInfo(alias="userName")] + + +class Email(TypedDict, total=False): + primary: bool + + type: str + + value: str + + +class Meta(TypedDict, total=False): + created: Annotated[Union[str, datetime], PropertyInfo(format="iso8601")] + + last_modified: Annotated[Union[str, datetime], PropertyInfo(alias="lastModified", format="iso8601")] + + location: str + + resource_type: Annotated[str, PropertyInfo(alias="resourceType")] + + version: str + + +class Name(TypedDict, total=False): + family_name: Annotated[str, PropertyInfo(alias="familyName")] + + formatted: str + + given_name: Annotated[str, PropertyInfo(alias="givenName")] + + honorific_prefix: Annotated[str, PropertyInfo(alias="honorificPrefix")] + + honorific_suffix: Annotated[str, PropertyInfo(alias="honorificSuffix")] + + middle_name: Annotated[str, PropertyInfo(alias="middleName")] diff --git a/src/cloudflare/types/zero_trust/access/user_populations/user_create_response.py b/src/cloudflare/types/zero_trust/access/user_populations/user_create_response.py new file mode 100644 index 00000000000..6dc37817442 --- /dev/null +++ b/src/cloudflare/types/zero_trust/access/user_populations/user_create_response.py @@ -0,0 +1,79 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import TYPE_CHECKING, Dict, List, Optional +from datetime import datetime + +from pydantic import Field as FieldInfo + +from ....._models import BaseModel + +__all__ = ["UserCreateResponse", "Email", "Meta", "Name"] + + +class Email(BaseModel): + primary: Optional[bool] = None + + type: Optional[str] = None + + value: Optional[str] = None + + +class Meta(BaseModel): + created: Optional[datetime] = None + + last_modified: Optional[datetime] = FieldInfo(alias="lastModified", default=None) + + location: Optional[str] = None + + resource_type: Optional[str] = FieldInfo(alias="resourceType", default=None) + + version: Optional[str] = None + + +class Name(BaseModel): + family_name: Optional[str] = FieldInfo(alias="familyName", default=None) + + formatted: Optional[str] = None + + given_name: Optional[str] = FieldInfo(alias="givenName", default=None) + + honorific_prefix: Optional[str] = FieldInfo(alias="honorificPrefix", default=None) + + honorific_suffix: Optional[str] = FieldInfo(alias="honorificSuffix", default=None) + + middle_name: Optional[str] = FieldInfo(alias="middleName", default=None) + + +class UserCreateResponse(BaseModel): + """A SCIM User resource. Additional SCIM extension attributes are supported.""" + + id: Optional[str] = None + + active: Optional[bool] = None + + display_name: Optional[str] = FieldInfo(alias="displayName", default=None) + + emails: Optional[List[Email]] = None + + external_id: Optional[str] = FieldInfo(alias="externalId", default=None) + + meta: Optional[Meta] = None + + name: Optional[Name] = None + + schemas: Optional[List[str]] = None + """The SCIM schemas that apply to this resource.""" + + user_name: Optional[str] = FieldInfo(alias="userName", default=None) + + if TYPE_CHECKING: + # Some versions of Pydantic <2.8.0 have a bug and don’t allow assigning a + # value to this field, so for compatibility we avoid doing it at runtime. + __pydantic_extra__: Dict[str, object] = FieldInfo(init=False) # pyright: ignore[reportIncompatibleVariableOverride] + + # Stub to indicate that arbitrary properties are accepted. + # To access properties that are not valid identifiers you can use `getattr`, e.g. + # `getattr(obj, '$type')` + def __getattr__(self, attr: str) -> object: ... + else: + __pydantic_extra__: Dict[str, object] diff --git a/src/cloudflare/types/zero_trust/access/user_populations/user_get_params.py b/src/cloudflare/types/zero_trust/access/user_populations/user_get_params.py new file mode 100644 index 00000000000..9721683a60b --- /dev/null +++ b/src/cloudflare/types/zero_trust/access/user_populations/user_get_params.py @@ -0,0 +1,23 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Required, Annotated, TypedDict + +from ....._utils import PropertyInfo + +__all__ = ["UserGetParams"] + + +class UserGetParams(TypedDict, total=False): + account_id: Required[str] + """Identifier.""" + + user_population_id: Required[str] + """UUID.""" + + attributes: str + """Comma-separated SCIM attributes to return.""" + + excluded_attributes: Annotated[str, PropertyInfo(alias="excludedAttributes")] + """Comma-separated SCIM attributes to exclude from the response.""" diff --git a/src/cloudflare/types/zero_trust/access/user_populations/user_get_response.py b/src/cloudflare/types/zero_trust/access/user_populations/user_get_response.py new file mode 100644 index 00000000000..c1d333a0920 --- /dev/null +++ b/src/cloudflare/types/zero_trust/access/user_populations/user_get_response.py @@ -0,0 +1,79 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import TYPE_CHECKING, Dict, List, Optional +from datetime import datetime + +from pydantic import Field as FieldInfo + +from ....._models import BaseModel + +__all__ = ["UserGetResponse", "Email", "Meta", "Name"] + + +class Email(BaseModel): + primary: Optional[bool] = None + + type: Optional[str] = None + + value: Optional[str] = None + + +class Meta(BaseModel): + created: Optional[datetime] = None + + last_modified: Optional[datetime] = FieldInfo(alias="lastModified", default=None) + + location: Optional[str] = None + + resource_type: Optional[str] = FieldInfo(alias="resourceType", default=None) + + version: Optional[str] = None + + +class Name(BaseModel): + family_name: Optional[str] = FieldInfo(alias="familyName", default=None) + + formatted: Optional[str] = None + + given_name: Optional[str] = FieldInfo(alias="givenName", default=None) + + honorific_prefix: Optional[str] = FieldInfo(alias="honorificPrefix", default=None) + + honorific_suffix: Optional[str] = FieldInfo(alias="honorificSuffix", default=None) + + middle_name: Optional[str] = FieldInfo(alias="middleName", default=None) + + +class UserGetResponse(BaseModel): + """A SCIM User resource. Additional SCIM extension attributes are supported.""" + + id: Optional[str] = None + + active: Optional[bool] = None + + display_name: Optional[str] = FieldInfo(alias="displayName", default=None) + + emails: Optional[List[Email]] = None + + external_id: Optional[str] = FieldInfo(alias="externalId", default=None) + + meta: Optional[Meta] = None + + name: Optional[Name] = None + + schemas: Optional[List[str]] = None + """The SCIM schemas that apply to this resource.""" + + user_name: Optional[str] = FieldInfo(alias="userName", default=None) + + if TYPE_CHECKING: + # Some versions of Pydantic <2.8.0 have a bug and don’t allow assigning a + # value to this field, so for compatibility we avoid doing it at runtime. + __pydantic_extra__: Dict[str, object] = FieldInfo(init=False) # pyright: ignore[reportIncompatibleVariableOverride] + + # Stub to indicate that arbitrary properties are accepted. + # To access properties that are not valid identifiers you can use `getattr`, e.g. + # `getattr(obj, '$type')` + def __getattr__(self, attr: str) -> object: ... + else: + __pydantic_extra__: Dict[str, object] diff --git a/src/cloudflare/types/zero_trust/access/user_populations/user_list_params.py b/src/cloudflare/types/zero_trust/access/user_populations/user_list_params.py new file mode 100644 index 00000000000..3457b72a2da --- /dev/null +++ b/src/cloudflare/types/zero_trust/access/user_populations/user_list_params.py @@ -0,0 +1,29 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Required, Annotated, TypedDict + +from ....._utils import PropertyInfo + +__all__ = ["UserListParams"] + + +class UserListParams(TypedDict, total=False): + account_id: Required[str] + """Identifier.""" + + attributes: str + """Comma-separated SCIM attributes to return.""" + + count: int + """The maximum number of results to return.""" + + excluded_attributes: Annotated[str, PropertyInfo(alias="excludedAttributes")] + """Comma-separated SCIM attributes to exclude from the response.""" + + filter: str + """A SCIM filter expression.""" + + start_index: Annotated[int, PropertyInfo(alias="startIndex")] + """The 1-based index of the first result to return.""" diff --git a/src/cloudflare/types/zero_trust/access/user_populations/user_list_response.py b/src/cloudflare/types/zero_trust/access/user_populations/user_list_response.py new file mode 100644 index 00000000000..ad002eadbdd --- /dev/null +++ b/src/cloudflare/types/zero_trust/access/user_populations/user_list_response.py @@ -0,0 +1,91 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import TYPE_CHECKING, Dict, List, Optional +from datetime import datetime + +from pydantic import Field as FieldInfo + +from ....._models import BaseModel + +__all__ = ["UserListResponse", "Resource", "ResourceEmail", "ResourceMeta", "ResourceName"] + + +class ResourceEmail(BaseModel): + primary: Optional[bool] = None + + type: Optional[str] = None + + value: Optional[str] = None + + +class ResourceMeta(BaseModel): + created: Optional[datetime] = None + + last_modified: Optional[datetime] = FieldInfo(alias="lastModified", default=None) + + location: Optional[str] = None + + resource_type: Optional[str] = FieldInfo(alias="resourceType", default=None) + + version: Optional[str] = None + + +class ResourceName(BaseModel): + family_name: Optional[str] = FieldInfo(alias="familyName", default=None) + + formatted: Optional[str] = None + + given_name: Optional[str] = FieldInfo(alias="givenName", default=None) + + honorific_prefix: Optional[str] = FieldInfo(alias="honorificPrefix", default=None) + + honorific_suffix: Optional[str] = FieldInfo(alias="honorificSuffix", default=None) + + middle_name: Optional[str] = FieldInfo(alias="middleName", default=None) + + +class Resource(BaseModel): + """A SCIM User resource. Additional SCIM extension attributes are supported.""" + + id: Optional[str] = None + + active: Optional[bool] = None + + display_name: Optional[str] = FieldInfo(alias="displayName", default=None) + + emails: Optional[List[ResourceEmail]] = None + + external_id: Optional[str] = FieldInfo(alias="externalId", default=None) + + meta: Optional[ResourceMeta] = None + + name: Optional[ResourceName] = None + + schemas: Optional[List[str]] = None + """The SCIM schemas that apply to this resource.""" + + user_name: Optional[str] = FieldInfo(alias="userName", default=None) + + if TYPE_CHECKING: + # Some versions of Pydantic <2.8.0 have a bug and don’t allow assigning a + # value to this field, so for compatibility we avoid doing it at runtime. + __pydantic_extra__: Dict[str, object] = FieldInfo(init=False) # pyright: ignore[reportIncompatibleVariableOverride] + + # Stub to indicate that arbitrary properties are accepted. + # To access properties that are not valid identifiers you can use `getattr`, e.g. + # `getattr(obj, '$type')` + def __getattr__(self, attr: str) -> object: ... + else: + __pydantic_extra__: Dict[str, object] + + +class UserListResponse(BaseModel): + items_per_page: int = FieldInfo(alias="itemsPerPage") + + resources: List[Resource] = FieldInfo(alias="Resources") + + schemas: List[str] + + start_index: int = FieldInfo(alias="startIndex") + + total_results: int = FieldInfo(alias="totalResults") diff --git a/src/cloudflare/types/zero_trust/access/user_populations/user_replace_params.py b/src/cloudflare/types/zero_trust/access/user_populations/user_replace_params.py new file mode 100644 index 00000000000..4e195b3f1a1 --- /dev/null +++ b/src/cloudflare/types/zero_trust/access/user_populations/user_replace_params.py @@ -0,0 +1,71 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Union, Iterable +from datetime import datetime +from typing_extensions import Required, Annotated, TypedDict + +from ....._types import SequenceNotStr +from ....._utils import PropertyInfo + +__all__ = ["UserReplaceParams", "Email", "Meta", "Name"] + + +class UserReplaceParams(TypedDict, total=False): + account_id: Required[str] + """Identifier.""" + + user_population_id: Required[str] + """UUID.""" + + active: bool + + display_name: Annotated[str, PropertyInfo(alias="displayName")] + + emails: Iterable[Email] + + external_id: Annotated[str, PropertyInfo(alias="externalId")] + + meta: Meta + + name: Name + + schemas: SequenceNotStr[str] + """The SCIM schemas that apply to this resource.""" + + user_name: Annotated[str, PropertyInfo(alias="userName")] + + +class Email(TypedDict, total=False): + primary: bool + + type: str + + value: str + + +class Meta(TypedDict, total=False): + created: Annotated[Union[str, datetime], PropertyInfo(format="iso8601")] + + last_modified: Annotated[Union[str, datetime], PropertyInfo(alias="lastModified", format="iso8601")] + + location: str + + resource_type: Annotated[str, PropertyInfo(alias="resourceType")] + + version: str + + +class Name(TypedDict, total=False): + family_name: Annotated[str, PropertyInfo(alias="familyName")] + + formatted: str + + given_name: Annotated[str, PropertyInfo(alias="givenName")] + + honorific_prefix: Annotated[str, PropertyInfo(alias="honorificPrefix")] + + honorific_suffix: Annotated[str, PropertyInfo(alias="honorificSuffix")] + + middle_name: Annotated[str, PropertyInfo(alias="middleName")] diff --git a/src/cloudflare/types/zero_trust/access/user_populations/user_replace_response.py b/src/cloudflare/types/zero_trust/access/user_populations/user_replace_response.py new file mode 100644 index 00000000000..c1033219911 --- /dev/null +++ b/src/cloudflare/types/zero_trust/access/user_populations/user_replace_response.py @@ -0,0 +1,79 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import TYPE_CHECKING, Dict, List, Optional +from datetime import datetime + +from pydantic import Field as FieldInfo + +from ....._models import BaseModel + +__all__ = ["UserReplaceResponse", "Email", "Meta", "Name"] + + +class Email(BaseModel): + primary: Optional[bool] = None + + type: Optional[str] = None + + value: Optional[str] = None + + +class Meta(BaseModel): + created: Optional[datetime] = None + + last_modified: Optional[datetime] = FieldInfo(alias="lastModified", default=None) + + location: Optional[str] = None + + resource_type: Optional[str] = FieldInfo(alias="resourceType", default=None) + + version: Optional[str] = None + + +class Name(BaseModel): + family_name: Optional[str] = FieldInfo(alias="familyName", default=None) + + formatted: Optional[str] = None + + given_name: Optional[str] = FieldInfo(alias="givenName", default=None) + + honorific_prefix: Optional[str] = FieldInfo(alias="honorificPrefix", default=None) + + honorific_suffix: Optional[str] = FieldInfo(alias="honorificSuffix", default=None) + + middle_name: Optional[str] = FieldInfo(alias="middleName", default=None) + + +class UserReplaceResponse(BaseModel): + """A SCIM User resource. Additional SCIM extension attributes are supported.""" + + id: Optional[str] = None + + active: Optional[bool] = None + + display_name: Optional[str] = FieldInfo(alias="displayName", default=None) + + emails: Optional[List[Email]] = None + + external_id: Optional[str] = FieldInfo(alias="externalId", default=None) + + meta: Optional[Meta] = None + + name: Optional[Name] = None + + schemas: Optional[List[str]] = None + """The SCIM schemas that apply to this resource.""" + + user_name: Optional[str] = FieldInfo(alias="userName", default=None) + + if TYPE_CHECKING: + # Some versions of Pydantic <2.8.0 have a bug and don’t allow assigning a + # value to this field, so for compatibility we avoid doing it at runtime. + __pydantic_extra__: Dict[str, object] = FieldInfo(init=False) # pyright: ignore[reportIncompatibleVariableOverride] + + # Stub to indicate that arbitrary properties are accepted. + # To access properties that are not valid identifiers you can use `getattr`, e.g. + # `getattr(obj, '$type')` + def __getattr__(self, attr: str) -> object: ... + else: + __pydantic_extra__: Dict[str, object] diff --git a/src/cloudflare/types/zero_trust/access/user_populations/user_update_params.py b/src/cloudflare/types/zero_trust/access/user_populations/user_update_params.py new file mode 100644 index 00000000000..57411a9a350 --- /dev/null +++ b/src/cloudflare/types/zero_trust/access/user_populations/user_update_params.py @@ -0,0 +1,31 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Dict, Union, Iterable, Optional +from typing_extensions import Literal, Required, Annotated, TypedDict + +from ....._types import SequenceNotStr +from ....._utils import PropertyInfo + +__all__ = ["UserUpdateParams", "Operation"] + + +class UserUpdateParams(TypedDict, total=False): + account_id: Required[str] + """Identifier.""" + + user_population_id: Required[str] + """UUID.""" + + operations: Required[Annotated[Iterable[Operation], PropertyInfo(alias="Operations")]] + + schemas: SequenceNotStr[str] + + +class Operation(TypedDict, total=False): + op: Required[Literal["add", "remove", "replace"]] + + path: str + + value: Union[Optional[str], float, bool, Iterable[object], Dict[str, object]] diff --git a/src/cloudflare/types/zero_trust/access/user_populations/user_update_response.py b/src/cloudflare/types/zero_trust/access/user_populations/user_update_response.py new file mode 100644 index 00000000000..0ae4167663a --- /dev/null +++ b/src/cloudflare/types/zero_trust/access/user_populations/user_update_response.py @@ -0,0 +1,79 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import TYPE_CHECKING, Dict, List, Optional +from datetime import datetime + +from pydantic import Field as FieldInfo + +from ....._models import BaseModel + +__all__ = ["UserUpdateResponse", "Email", "Meta", "Name"] + + +class Email(BaseModel): + primary: Optional[bool] = None + + type: Optional[str] = None + + value: Optional[str] = None + + +class Meta(BaseModel): + created: Optional[datetime] = None + + last_modified: Optional[datetime] = FieldInfo(alias="lastModified", default=None) + + location: Optional[str] = None + + resource_type: Optional[str] = FieldInfo(alias="resourceType", default=None) + + version: Optional[str] = None + + +class Name(BaseModel): + family_name: Optional[str] = FieldInfo(alias="familyName", default=None) + + formatted: Optional[str] = None + + given_name: Optional[str] = FieldInfo(alias="givenName", default=None) + + honorific_prefix: Optional[str] = FieldInfo(alias="honorificPrefix", default=None) + + honorific_suffix: Optional[str] = FieldInfo(alias="honorificSuffix", default=None) + + middle_name: Optional[str] = FieldInfo(alias="middleName", default=None) + + +class UserUpdateResponse(BaseModel): + """A SCIM User resource. Additional SCIM extension attributes are supported.""" + + id: Optional[str] = None + + active: Optional[bool] = None + + display_name: Optional[str] = FieldInfo(alias="displayName", default=None) + + emails: Optional[List[Email]] = None + + external_id: Optional[str] = FieldInfo(alias="externalId", default=None) + + meta: Optional[Meta] = None + + name: Optional[Name] = None + + schemas: Optional[List[str]] = None + """The SCIM schemas that apply to this resource.""" + + user_name: Optional[str] = FieldInfo(alias="userName", default=None) + + if TYPE_CHECKING: + # Some versions of Pydantic <2.8.0 have a bug and don’t allow assigning a + # value to this field, so for compatibility we avoid doing it at runtime. + __pydantic_extra__: Dict[str, object] = FieldInfo(init=False) # pyright: ignore[reportIncompatibleVariableOverride] + + # Stub to indicate that arbitrary properties are accepted. + # To access properties that are not valid identifiers you can use `getattr`, e.g. + # `getattr(obj, '$type')` + def __getattr__(self, attr: str) -> object: ... + else: + __pydantic_extra__: Dict[str, object] diff --git a/src/cloudflare/types/zero_trust/access/users/__init__.py b/src/cloudflare/types/zero_trust/access/users/__init__.py index 5f23decf1fe..6107e729a63 100644 --- a/src/cloudflare/types/zero_trust/access/users/__init__.py +++ b/src/cloudflare/types/zero_trust/access/users/__init__.py @@ -2,7 +2,7 @@ from __future__ import annotations -from .identity import Identity as Identity from .failed_login_list_response import FailedLoginListResponse as FailedLoginListResponse from .active_session_get_response import ActiveSessionGetResponse as ActiveSessionGetResponse from .active_session_list_response import ActiveSessionListResponse as ActiveSessionListResponse +from .last_seen_identity_get_response import LastSeenIdentityGetResponse as LastSeenIdentityGetResponse diff --git a/src/cloudflare/types/zero_trust/access/users/identity.py b/src/cloudflare/types/zero_trust/access/users/last_seen_identity_get_response.py similarity index 75% rename from src/cloudflare/types/zero_trust/access/users/identity.py rename to src/cloudflare/types/zero_trust/access/users/last_seen_identity_get_response.py index 37153c6f6eb..bb137508d99 100644 --- a/src/cloudflare/types/zero_trust/access/users/identity.py +++ b/src/cloudflare/types/zero_trust/access/users/last_seen_identity_get_response.py @@ -1,12 +1,22 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import Dict, Optional +from typing import Dict, List, Optional +from datetime import datetime from pydantic import Field as FieldInfo from ....._models import BaseModel -__all__ = ["Identity", "DeviceSessions", "DevicePosture", "DevicePostureCheck", "Geo", "IdP", "MTLSAuth"] +__all__ = [ + "LastSeenIdentityGetResponse", + "DeviceSessions", + "DevicePosture", + "DevicePostureCheck", + "Geo", + "IdP", + "MTLSAuth", + "Passkey", +] class DeviceSessions(BaseModel): @@ -61,7 +71,18 @@ class MTLSAuth(BaseModel): cert_serial: Optional[str] = None -class Identity(BaseModel): +class Passkey(BaseModel): + id: Optional[str] = None + """Authenticator ID used to delete the passkey.""" + + created_at: Optional[datetime] = None + + last_used_at: Optional[datetime] = None + + name: Optional[str] = None + + +class LastSeenIdentityGetResponse(BaseModel): account_id: Optional[str] = None auth_status: Optional[str] = None @@ -90,6 +111,9 @@ class Identity(BaseModel): mtls_auth: Optional[MTLSAuth] = None + passkeys: Optional[List[Passkey]] = None + """Active passkey enrollments for the user.""" + service_token_id: Optional[str] = None service_token_status: Optional[bool] = None diff --git a/src/cloudflare/types/zero_trust/casb/application_get_response.py b/src/cloudflare/types/zero_trust/casb/application_get_response.py index ff15d8ba852..5d960102b06 100644 --- a/src/cloudflare/types/zero_trust/casb/application_get_response.py +++ b/src/cloudflare/types/zero_trust/casb/application_get_response.py @@ -123,6 +123,7 @@ class ApplicationGetResponse(BaseModel): "SALESFORCE", "SERVICENOW", "SLACK", + "ZOOM", ] """Vendor identifier. @@ -141,6 +142,7 @@ class ApplicationGetResponse(BaseModel): - `SALESFORCE` - SALESFORCE - `SERVICENOW` - SERVICENOW - `SLACK` - SLACK + - `ZOOM` - ZOOM """ auth_methods: List[AuthMethod] diff --git a/src/cloudflare/types/zero_trust/casb/application_list_response.py b/src/cloudflare/types/zero_trust/casb/application_list_response.py index 714a6633024..888ec273350 100644 --- a/src/cloudflare/types/zero_trust/casb/application_list_response.py +++ b/src/cloudflare/types/zero_trust/casb/application_list_response.py @@ -66,6 +66,7 @@ class ApplicationListResponse(BaseModel): "SALESFORCE", "SERVICENOW", "SLACK", + "ZOOM", ] """Vendor identifier (e.g. microsoft_internal, google_workspace). @@ -84,6 +85,7 @@ class ApplicationListResponse(BaseModel): - `SALESFORCE` - SALESFORCE - `SERVICENOW` - SERVICENOW - `SLACK` - SLACK + - `ZOOM` - ZOOM """ auth_methods: List[AuthMethod] diff --git a/src/cloudflare/types/zero_trust/casb/integration_create_params.py b/src/cloudflare/types/zero_trust/casb/integration_create_params.py index 976a5ceee6e..b26b153d3da 100644 --- a/src/cloudflare/types/zero_trust/casb/integration_create_params.py +++ b/src/cloudflare/types/zero_trust/casb/integration_create_params.py @@ -30,6 +30,7 @@ class IntegrationCreateParams(TypedDict, total=False): "SALESFORCE", "SERVICENOW", "SLACK", + "ZOOM", ] ] """Vendor/application slug (e.g., GOOGLE_WORKSPACE). @@ -49,6 +50,7 @@ class IntegrationCreateParams(TypedDict, total=False): - `SALESFORCE` - SALESFORCE - `SERVICENOW` - SERVICENOW - `SLACK` - SLACK + - `ZOOM` - ZOOM """ credentials: Required[Dict[str, object]] @@ -57,6 +59,13 @@ class IntegrationCreateParams(TypedDict, total=False): name: Required[str] """Name of the integration.""" + use_cases: Required[List[Literal["casb", "ces", "auto_remediation"]]] + """List of use case or feature slugs to enroll. + + At least one use case (casb, ces) is required; auto_remediation may be added + alongside casb (e.g., ['casb', 'ces', 'auto_remediation']). + """ + auth_method: Optional[str] """Authentication method slug (uses default if omitted).""" @@ -65,9 +74,3 @@ class IntegrationCreateParams(TypedDict, total=False): permissions: SequenceNotStr[str] """List of permission scopes (uses policy defaults if empty).""" - - use_cases: List[Literal["casb", "ces", "auto_remediation"]] - """ - List of use case or feature slugs to enroll (e.g., ['casb', 'ces', - 'auto_remediation']). - """ diff --git a/src/cloudflare/types/zero_trust/casb/integration_list_response.py b/src/cloudflare/types/zero_trust/casb/integration_list_response.py index 5b34dda6902..333ab81b952 100644 --- a/src/cloudflare/types/zero_trust/casb/integration_list_response.py +++ b/src/cloudflare/types/zero_trust/casb/integration_list_response.py @@ -1,11 +1,19 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import Dict, Optional +from typing import Dict, List, Optional from datetime import datetime from ...._models import BaseModel -__all__ = ["IntegrationListResponse"] +__all__ = ["IntegrationListResponse", "AuthMethod"] + + +class AuthMethod(BaseModel): + """The integration's authentication method.""" + + id: str + + display_name: str class IntegrationListResponse(BaseModel): @@ -16,6 +24,9 @@ class IntegrationListResponse(BaseModel): application: Dict[str, Optional[str]] + auth_method: Optional[AuthMethod] = None + """The integration's authentication method.""" + created: datetime """When the integration was created.""" @@ -30,3 +41,6 @@ class IntegrationListResponse(BaseModel): updated: datetime """When the integration was last updated.""" + + use_cases: List[str] + """Use cases enabled for the integration.""" diff --git a/src/cloudflare/types/zero_trust/casb/posture/__init__.py b/src/cloudflare/types/zero_trust/casb/posture/__init__.py index ff70c1181c3..64125e78900 100644 --- a/src/cloudflare/types/zero_trust/casb/posture/__init__.py +++ b/src/cloudflare/types/zero_trust/casb/posture/__init__.py @@ -33,12 +33,21 @@ from .webhook_delete_response import WebhookDeleteResponse as WebhookDeleteResponse from .webhook_evaluate_params import WebhookEvaluateParams as WebhookEvaluateParams from .webhook_update_response import WebhookUpdateResponse as WebhookUpdateResponse +from .asset_schema_list_params import AssetSchemaListParams as AssetSchemaListParams from .finding_type_list_params import FindingTypeListParams as FindingTypeListParams +from .asset_schema_get_response import AssetSchemaGetResponse as AssetSchemaGetResponse from .finding_type_get_response import FindingTypeGetResponse as FindingTypeGetResponse from .finding_unignore_response import FindingUnignoreResponse as FindingUnignoreResponse from .webhook_evaluate_response import WebhookEvaluateResponse as WebhookEvaluateResponse +from .asset_schema_list_response import AssetSchemaListResponse as AssetSchemaListResponse +from .finding_type_create_params import FindingTypeCreateParams as FindingTypeCreateParams from .finding_type_list_response import FindingTypeListResponse as FindingTypeListResponse +from .finding_type_update_params import FindingTypeUpdateParams as FindingTypeUpdateParams from .finding_tune_severity_params import FindingTuneSeverityParams as FindingTuneSeverityParams +from .finding_type_create_response import FindingTypeCreateResponse as FindingTypeCreateResponse +from .finding_type_update_response import FindingTypeUpdateResponse as FindingTypeUpdateResponse +from .finding_type_validate_params import FindingTypeValidateParams as FindingTypeValidateParams from .finding_tune_severity_response import FindingTuneSeverityResponse as FindingTuneSeverityResponse +from .finding_type_validate_response import FindingTypeValidateResponse as FindingTypeValidateResponse from .finding_reset_severity_response import FindingResetSeverityResponse as FindingResetSeverityResponse from .webhook_evaluate_existing_response import WebhookEvaluateExistingResponse as WebhookEvaluateExistingResponse diff --git a/src/cloudflare/types/zero_trust/casb/posture/asset_schema_get_response.py b/src/cloudflare/types/zero_trust/casb/posture/asset_schema_get_response.py new file mode 100644 index 00000000000..3ca19fcbb15 --- /dev/null +++ b/src/cloudflare/types/zero_trust/casb/posture/asset_schema_get_response.py @@ -0,0 +1,21 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Dict + +from pydantic import Field as FieldInfo + +from ....._models import BaseModel + +__all__ = ["AssetSchemaGetResponse"] + + +class AssetSchemaGetResponse(BaseModel): + asset_class: str + """Asset class identifier (PascalCase), e.g. AnthropicApiKey.""" + + schema_: Dict[str, object] = FieldInfo(alias="schema") + """ + Fields and related attributes a custom finding type may reference for this asset + class, as a JSON Schema. Top-level properties are `asset` and, when related + resources exist, `associated`. + """ diff --git a/src/cloudflare/types/zero_trust/casb/posture/asset_schema_list_params.py b/src/cloudflare/types/zero_trust/casb/posture/asset_schema_list_params.py new file mode 100644 index 00000000000..9f0588ee061 --- /dev/null +++ b/src/cloudflare/types/zero_trust/casb/posture/asset_schema_list_params.py @@ -0,0 +1,32 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal, Required, TypedDict + +__all__ = ["AssetSchemaListParams"] + + +class AssetSchemaListParams(TypedDict, total=False): + account_id: Required[str] + + vendor: Literal[ + "ANTHROPIC", + "AWS", + "BITBUCKET", + "BOX", + "CONFLUENCE", + "DROPBOX", + "GITHUB", + "GOOGLE_CLOUD_PLATFORM", + "GOOGLE_WORKSPACE", + "JIRA", + "MICROSOFT", + "OPENAI", + "SALESFORCE", + "SERVICENOW", + "SLACK", + "WORKDAY", + "ZOOM", + ] + """Restrict the result to a single vendor. Unknown values return 400.""" diff --git a/src/cloudflare/types/zero_trust/casb/posture/asset_schema_list_response.py b/src/cloudflare/types/zero_trust/casb/posture/asset_schema_list_response.py new file mode 100644 index 00000000000..483cd73d577 --- /dev/null +++ b/src/cloudflare/types/zero_trust/casb/posture/asset_schema_list_response.py @@ -0,0 +1,20 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List + +from ....._models import BaseModel + +__all__ = ["AssetSchemaListResponse", "AssetClass"] + + +class AssetClass(BaseModel): + asset_class: str + """Asset class identifier (PascalCase), e.g. AnthropicUser.""" + + +class AssetSchemaListResponse(BaseModel): + asset_classes: List[AssetClass] + """Asset classes belonging to this vendor, sorted by asset_class.""" + + vendor: str + """Canonical vendor enum value, e.g. GOOGLE_WORKSPACE.""" diff --git a/src/cloudflare/types/zero_trust/casb/posture/finding_export_params.py b/src/cloudflare/types/zero_trust/casb/posture/finding_export_params.py index 209fbf3174a..34fcc09d625 100644 --- a/src/cloudflare/types/zero_trust/casb/posture/finding_export_params.py +++ b/src/cloudflare/types/zero_trust/casb/posture/finding_export_params.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing import List, Union, Iterable, Optional +from typing import List, Union, Iterable from datetime import datetime from typing_extensions import Literal, Required, Annotated, TypedDict @@ -36,7 +36,7 @@ class FindingExportParams(TypedDict, total=False): orders: Iterable[Order] """Which fields to use when ordering the findings.""" - product: Optional[Literal["SaaS", "Cloud"]] + product: Literal["SaaS", "Cloud"] """Filter by finding's category product.""" search: str diff --git a/src/cloudflare/types/zero_trust/casb/posture/finding_get_response.py b/src/cloudflare/types/zero_trust/casb/posture/finding_get_response.py index b51f8f68878..389eb33d1b6 100644 --- a/src/cloudflare/types/zero_trust/casb/posture/finding_get_response.py +++ b/src/cloudflare/types/zero_trust/casb/posture/finding_get_response.py @@ -69,12 +69,80 @@ class Finding(BaseModel): vendor: str """The SaaS/Cloud vendor of the platform with which the finding is associated.""" + applies_to_all_integrations: Optional[bool] = None + """ + Whether this finding type applies to every current and future integration of the + vendor. + """ + + asset_class: Optional[str] = None + """Asset class the finding type's policy evaluates.""" + + asset_vendor: Optional[ + Literal[ + "ANTHROPIC", + "AWS", + "BITBUCKET", + "BOX", + "CONFLUENCE", + "DROPBOX", + "GITHUB", + "GOOGLE_CLOUD_PLATFORM", + "GOOGLE_WORKSPACE", + "JIRA", + "MICROSOFT", + "OPENAI", + "SALESFORCE", + "SERVICENOW", + "SLACK", + "ZOOM", + ] + ] = None + """Canonical vendor enum value.""" + + created_at: Optional[datetime] = None + """Timestamp when the finding type was created.""" + description: Optional[str] = None """Detailed description of the finding.""" + expression: Optional[str] = None + """Rego expression backing this finding type. + + For custom finding types, generated package and import declarations are omitted. + System expressions are returned unchanged. + """ + + integration_ids: Optional[List[str]] = None + """ + Integrations this finding type applies to when applies_to_all_integrations is + false. + """ + + match_count: Optional[int] = None + """Number of currently active finding instances across the account's integrations. + + Zero when none have been detected. + """ + + origin: Optional[Literal["system", "custom"]] = None + """Whether the finding type is system-managed or customer-created.""" + + quarantined: Optional[bool] = None + """Whether evaluation of this finding type is suspended by an operator. + + Present only when true. + """ + remediation: Optional[FindingRemediation] = None """Remediation guide information for a finding.""" + updated_at: Optional[datetime] = None + """Timestamp when the finding type was last updated.""" + + version: Optional[int] = None + """Current version of the finding type. Incremented on each update.""" + class IntegrationPolicy(BaseModel): """Policy configuration for an integration.""" diff --git a/src/cloudflare/types/zero_trust/casb/posture/finding_ignore_response.py b/src/cloudflare/types/zero_trust/casb/posture/finding_ignore_response.py index d5f65cb5a01..2e0dd45d295 100644 --- a/src/cloudflare/types/zero_trust/casb/posture/finding_ignore_response.py +++ b/src/cloudflare/types/zero_trust/casb/posture/finding_ignore_response.py @@ -69,12 +69,80 @@ class Finding(BaseModel): vendor: str """The SaaS/Cloud vendor of the platform with which the finding is associated.""" + applies_to_all_integrations: Optional[bool] = None + """ + Whether this finding type applies to every current and future integration of the + vendor. + """ + + asset_class: Optional[str] = None + """Asset class the finding type's policy evaluates.""" + + asset_vendor: Optional[ + Literal[ + "ANTHROPIC", + "AWS", + "BITBUCKET", + "BOX", + "CONFLUENCE", + "DROPBOX", + "GITHUB", + "GOOGLE_CLOUD_PLATFORM", + "GOOGLE_WORKSPACE", + "JIRA", + "MICROSOFT", + "OPENAI", + "SALESFORCE", + "SERVICENOW", + "SLACK", + "ZOOM", + ] + ] = None + """Canonical vendor enum value.""" + + created_at: Optional[datetime] = None + """Timestamp when the finding type was created.""" + description: Optional[str] = None """Detailed description of the finding.""" + expression: Optional[str] = None + """Rego expression backing this finding type. + + For custom finding types, generated package and import declarations are omitted. + System expressions are returned unchanged. + """ + + integration_ids: Optional[List[str]] = None + """ + Integrations this finding type applies to when applies_to_all_integrations is + false. + """ + + match_count: Optional[int] = None + """Number of currently active finding instances across the account's integrations. + + Zero when none have been detected. + """ + + origin: Optional[Literal["system", "custom"]] = None + """Whether the finding type is system-managed or customer-created.""" + + quarantined: Optional[bool] = None + """Whether evaluation of this finding type is suspended by an operator. + + Present only when true. + """ + remediation: Optional[FindingRemediation] = None """Remediation guide information for a finding.""" + updated_at: Optional[datetime] = None + """Timestamp when the finding type was last updated.""" + + version: Optional[int] = None + """Current version of the finding type. Incremented on each update.""" + class IntegrationPolicy(BaseModel): """Policy configuration for an integration.""" diff --git a/src/cloudflare/types/zero_trust/casb/posture/finding_list_response.py b/src/cloudflare/types/zero_trust/casb/posture/finding_list_response.py index 2cbc3dbb217..f885e2b3dd5 100644 --- a/src/cloudflare/types/zero_trust/casb/posture/finding_list_response.py +++ b/src/cloudflare/types/zero_trust/casb/posture/finding_list_response.py @@ -69,12 +69,80 @@ class Finding(BaseModel): vendor: str """The SaaS/Cloud vendor of the platform with which the finding is associated.""" + applies_to_all_integrations: Optional[bool] = None + """ + Whether this finding type applies to every current and future integration of the + vendor. + """ + + asset_class: Optional[str] = None + """Asset class the finding type's policy evaluates.""" + + asset_vendor: Optional[ + Literal[ + "ANTHROPIC", + "AWS", + "BITBUCKET", + "BOX", + "CONFLUENCE", + "DROPBOX", + "GITHUB", + "GOOGLE_CLOUD_PLATFORM", + "GOOGLE_WORKSPACE", + "JIRA", + "MICROSOFT", + "OPENAI", + "SALESFORCE", + "SERVICENOW", + "SLACK", + "ZOOM", + ] + ] = None + """Canonical vendor enum value.""" + + created_at: Optional[datetime] = None + """Timestamp when the finding type was created.""" + description: Optional[str] = None """Detailed description of the finding.""" + expression: Optional[str] = None + """Rego expression backing this finding type. + + For custom finding types, generated package and import declarations are omitted. + System expressions are returned unchanged. + """ + + integration_ids: Optional[List[str]] = None + """ + Integrations this finding type applies to when applies_to_all_integrations is + false. + """ + + match_count: Optional[int] = None + """Number of currently active finding instances across the account's integrations. + + Zero when none have been detected. + """ + + origin: Optional[Literal["system", "custom"]] = None + """Whether the finding type is system-managed or customer-created.""" + + quarantined: Optional[bool] = None + """Whether evaluation of this finding type is suspended by an operator. + + Present only when true. + """ + remediation: Optional[FindingRemediation] = None """Remediation guide information for a finding.""" + updated_at: Optional[datetime] = None + """Timestamp when the finding type was last updated.""" + + version: Optional[int] = None + """Current version of the finding type. Incremented on each update.""" + class IntegrationPolicy(BaseModel): """Policy configuration for an integration.""" diff --git a/src/cloudflare/types/zero_trust/casb/posture/finding_reset_severity_response.py b/src/cloudflare/types/zero_trust/casb/posture/finding_reset_severity_response.py index 80750f09a19..a91434d6a4a 100644 --- a/src/cloudflare/types/zero_trust/casb/posture/finding_reset_severity_response.py +++ b/src/cloudflare/types/zero_trust/casb/posture/finding_reset_severity_response.py @@ -69,12 +69,80 @@ class Finding(BaseModel): vendor: str """The SaaS/Cloud vendor of the platform with which the finding is associated.""" + applies_to_all_integrations: Optional[bool] = None + """ + Whether this finding type applies to every current and future integration of the + vendor. + """ + + asset_class: Optional[str] = None + """Asset class the finding type's policy evaluates.""" + + asset_vendor: Optional[ + Literal[ + "ANTHROPIC", + "AWS", + "BITBUCKET", + "BOX", + "CONFLUENCE", + "DROPBOX", + "GITHUB", + "GOOGLE_CLOUD_PLATFORM", + "GOOGLE_WORKSPACE", + "JIRA", + "MICROSOFT", + "OPENAI", + "SALESFORCE", + "SERVICENOW", + "SLACK", + "ZOOM", + ] + ] = None + """Canonical vendor enum value.""" + + created_at: Optional[datetime] = None + """Timestamp when the finding type was created.""" + description: Optional[str] = None """Detailed description of the finding.""" + expression: Optional[str] = None + """Rego expression backing this finding type. + + For custom finding types, generated package and import declarations are omitted. + System expressions are returned unchanged. + """ + + integration_ids: Optional[List[str]] = None + """ + Integrations this finding type applies to when applies_to_all_integrations is + false. + """ + + match_count: Optional[int] = None + """Number of currently active finding instances across the account's integrations. + + Zero when none have been detected. + """ + + origin: Optional[Literal["system", "custom"]] = None + """Whether the finding type is system-managed or customer-created.""" + + quarantined: Optional[bool] = None + """Whether evaluation of this finding type is suspended by an operator. + + Present only when true. + """ + remediation: Optional[FindingRemediation] = None """Remediation guide information for a finding.""" + updated_at: Optional[datetime] = None + """Timestamp when the finding type was last updated.""" + + version: Optional[int] = None + """Current version of the finding type. Incremented on each update.""" + class IntegrationPolicy(BaseModel): """Policy configuration for an integration.""" diff --git a/src/cloudflare/types/zero_trust/casb/posture/finding_tune_severity_response.py b/src/cloudflare/types/zero_trust/casb/posture/finding_tune_severity_response.py index ceff30a1156..913e65b93b4 100644 --- a/src/cloudflare/types/zero_trust/casb/posture/finding_tune_severity_response.py +++ b/src/cloudflare/types/zero_trust/casb/posture/finding_tune_severity_response.py @@ -69,12 +69,80 @@ class Finding(BaseModel): vendor: str """The SaaS/Cloud vendor of the platform with which the finding is associated.""" + applies_to_all_integrations: Optional[bool] = None + """ + Whether this finding type applies to every current and future integration of the + vendor. + """ + + asset_class: Optional[str] = None + """Asset class the finding type's policy evaluates.""" + + asset_vendor: Optional[ + Literal[ + "ANTHROPIC", + "AWS", + "BITBUCKET", + "BOX", + "CONFLUENCE", + "DROPBOX", + "GITHUB", + "GOOGLE_CLOUD_PLATFORM", + "GOOGLE_WORKSPACE", + "JIRA", + "MICROSOFT", + "OPENAI", + "SALESFORCE", + "SERVICENOW", + "SLACK", + "ZOOM", + ] + ] = None + """Canonical vendor enum value.""" + + created_at: Optional[datetime] = None + """Timestamp when the finding type was created.""" + description: Optional[str] = None """Detailed description of the finding.""" + expression: Optional[str] = None + """Rego expression backing this finding type. + + For custom finding types, generated package and import declarations are omitted. + System expressions are returned unchanged. + """ + + integration_ids: Optional[List[str]] = None + """ + Integrations this finding type applies to when applies_to_all_integrations is + false. + """ + + match_count: Optional[int] = None + """Number of currently active finding instances across the account's integrations. + + Zero when none have been detected. + """ + + origin: Optional[Literal["system", "custom"]] = None + """Whether the finding type is system-managed or customer-created.""" + + quarantined: Optional[bool] = None + """Whether evaluation of this finding type is suspended by an operator. + + Present only when true. + """ + remediation: Optional[FindingRemediation] = None """Remediation guide information for a finding.""" + updated_at: Optional[datetime] = None + """Timestamp when the finding type was last updated.""" + + version: Optional[int] = None + """Current version of the finding type. Incremented on each update.""" + class IntegrationPolicy(BaseModel): """Policy configuration for an integration.""" diff --git a/src/cloudflare/types/zero_trust/casb/posture/finding_type_create_params.py b/src/cloudflare/types/zero_trust/casb/posture/finding_type_create_params.py new file mode 100644 index 00000000000..60ef0ad4e22 --- /dev/null +++ b/src/cloudflare/types/zero_trust/casb/posture/finding_type_create_params.py @@ -0,0 +1,72 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal, Required, TypedDict + +from ....._types import SequenceNotStr + +__all__ = ["FindingTypeCreateParams"] + + +class FindingTypeCreateParams(TypedDict, total=False): + account_id: Required[str] + + applies_to_all_integrations: Required[bool] + """ + When true, this finding type applies to every current and future integration of + the vendor. + """ + + asset_class: Required[str] + """Asset class this finding type applies to (PascalCase, e.g. GoogleWorkspaceFile)""" + + asset_vendor: Required[ + Literal[ + "ANTHROPIC", + "AWS", + "BITBUCKET", + "BOX", + "CONFLUENCE", + "DROPBOX", + "GITHUB", + "GOOGLE_CLOUD_PLATFORM", + "GOOGLE_WORKSPACE", + "JIRA", + "MICROSOFT", + "OPENAI", + "SALESFORCE", + "SERVICENOW", + "SLACK", + "ZOOM", + ] + ] + """ + Canonical vendor enum for the platform whose assets this finding type evaluates. + """ + + description: Required[str] + """Human-readable description of the finding type. + + Cannot be empty. Maximum 4096 characters. + """ + + expression: Required[str] + """Rego expression body for the policy. + + `package cloudflare.casb.custom` and `import rego.v1` are added automatically. + Do not include package or import declarations. This field cannot be changed + after creation. Maximum 4096 characters. + """ + + name: Required[str] + """Human-readable name for the finding type. Maximum 256 characters.""" + + severity: Required[Literal["Critical", "High", "Medium", "Low"]] + """Default severity used when no integration-specific severity override exists.""" + + integration_ids: SequenceNotStr[str] + """ + Required and non-empty when applies_to_all_integrations is false; omit when it + is true. + """ diff --git a/src/cloudflare/types/zero_trust/casb/posture/finding_type_create_response.py b/src/cloudflare/types/zero_trust/casb/posture/finding_type_create_response.py new file mode 100644 index 00000000000..5554bf7d89e --- /dev/null +++ b/src/cloudflare/types/zero_trust/casb/posture/finding_type_create_response.py @@ -0,0 +1,110 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional +from datetime import datetime +from typing_extensions import Literal + +from ....._models import BaseModel + +__all__ = ["FindingTypeCreateResponse", "Category"] + + +class Category(BaseModel): + """Category information for a finding.""" + + observation: Literal["Issue", "Insight", "Activity"] + """The type of the observation.""" + + product: Literal["SaaS", "Cloud"] + """The product category.""" + + type: Literal["Content", "Posture"] + """The type of the finding category.""" + + +class FindingTypeCreateResponse(BaseModel): + """Basic finding type information.""" + + id: str + """The unique identifier of the finding.""" + + applies_to_all_integrations: bool + """ + Whether this finding type applies to every current and future integration of the + vendor. + """ + + asset_class: str + """Asset class the finding type's policy evaluates.""" + + asset_vendor: Literal[ + "ANTHROPIC", + "AWS", + "BITBUCKET", + "BOX", + "CONFLUENCE", + "DROPBOX", + "GITHUB", + "GOOGLE_CLOUD_PLATFORM", + "GOOGLE_WORKSPACE", + "JIRA", + "MICROSOFT", + "OPENAI", + "SALESFORCE", + "SERVICENOW", + "SLACK", + "ZOOM", + ] + """Canonical vendor enum value.""" + + category: Category + """Category information for a finding.""" + + created_at: datetime + """Timestamp when the finding type was created.""" + + description: Optional[str] = None + """Detailed description of the finding.""" + + expression: str + """Rego expression backing this finding type. + + For custom finding types, generated package and import declarations are omitted. + System expressions are returned unchanged. + """ + + name: str + """The name of the finding.""" + + origin: Literal["system", "custom"] + """Whether the finding type is system-managed or customer-created.""" + + severity: Literal["Critical", "High", "Medium", "Low"] + """Default severity used when no integration-specific severity override exists.""" + + updated_at: datetime + """Timestamp when the finding type was last updated.""" + + vendor: str + """The SaaS/Cloud vendor of the platform with which the finding is associated.""" + + version: int + """Current version of the finding type. Incremented on each update.""" + + integration_ids: Optional[List[str]] = None + """ + Integrations this finding type applies to when applies_to_all_integrations is + false. + """ + + match_count: Optional[int] = None + """Number of currently active finding instances across the account's integrations. + + Zero when none have been detected. + """ + + quarantined: Optional[bool] = None + """Whether evaluation of this finding type is suspended by an operator. + + Present only when true. + """ diff --git a/src/cloudflare/types/zero_trust/casb/posture/finding_type_get_response.py b/src/cloudflare/types/zero_trust/casb/posture/finding_type_get_response.py index 16daafc8709..b22b999bbd2 100644 --- a/src/cloudflare/types/zero_trust/casb/posture/finding_type_get_response.py +++ b/src/cloudflare/types/zero_trust/casb/posture/finding_type_get_response.py @@ -1,6 +1,7 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import Optional +from typing import List, Optional +from datetime import datetime from typing_extensions import Literal from ....._models import BaseModel @@ -39,5 +40,73 @@ class FindingTypeGetResponse(BaseModel): vendor: str """The SaaS/Cloud vendor of the platform with which the finding is associated.""" + applies_to_all_integrations: Optional[bool] = None + """ + Whether this finding type applies to every current and future integration of the + vendor. + """ + + asset_class: Optional[str] = None + """Asset class the finding type's policy evaluates.""" + + asset_vendor: Optional[ + Literal[ + "ANTHROPIC", + "AWS", + "BITBUCKET", + "BOX", + "CONFLUENCE", + "DROPBOX", + "GITHUB", + "GOOGLE_CLOUD_PLATFORM", + "GOOGLE_WORKSPACE", + "JIRA", + "MICROSOFT", + "OPENAI", + "SALESFORCE", + "SERVICENOW", + "SLACK", + "ZOOM", + ] + ] = None + """Canonical vendor enum value.""" + + created_at: Optional[datetime] = None + """Timestamp when the finding type was created.""" + description: Optional[str] = None """Detailed description of the finding.""" + + expression: Optional[str] = None + """Rego expression backing this finding type. + + For custom finding types, generated package and import declarations are omitted. + System expressions are returned unchanged. + """ + + integration_ids: Optional[List[str]] = None + """ + Integrations this finding type applies to when applies_to_all_integrations is + false. + """ + + match_count: Optional[int] = None + """Number of currently active finding instances across the account's integrations. + + Zero when none have been detected. + """ + + origin: Optional[Literal["system", "custom"]] = None + """Whether the finding type is system-managed or customer-created.""" + + quarantined: Optional[bool] = None + """Whether evaluation of this finding type is suspended by an operator. + + Present only when true. + """ + + updated_at: Optional[datetime] = None + """Timestamp when the finding type was last updated.""" + + version: Optional[int] = None + """Current version of the finding type. Incremented on each update.""" diff --git a/src/cloudflare/types/zero_trust/casb/posture/finding_type_list_params.py b/src/cloudflare/types/zero_trust/casb/posture/finding_type_list_params.py index d2196ab7dd0..182862aaeff 100644 --- a/src/cloudflare/types/zero_trust/casb/posture/finding_type_list_params.py +++ b/src/cloudflare/types/zero_trust/casb/posture/finding_type_list_params.py @@ -2,8 +2,11 @@ from __future__ import annotations -from typing import List -from typing_extensions import Literal, Required, TypedDict +from typing import List, Union +from datetime import datetime +from typing_extensions import Literal, Required, Annotated, TypedDict + +from ....._utils import PropertyInfo __all__ = ["FindingTypeListParams"] @@ -11,15 +14,66 @@ class FindingTypeListParams(TypedDict, total=False): account_id: Required[str] + direction: Literal["asc", "desc"] + """Sort direction for the primary field. + + Defaults to 'desc'. Ties are resolved by case-insensitive name, then ID, both + ascending regardless of direction. + """ + + max_updated_at: Annotated[Union[str, datetime], PropertyInfo(format="iso8601")] + """ + Return only finding types updated at or before this RFC 3339 timestamp + (inclusive). + """ + + min_updated_at: Annotated[Union[str, datetime], PropertyInfo(format="iso8601")] + """ + Return only finding types updated at or after this RFC 3339 timestamp + (inclusive). + """ + + order: Literal["created", "updated", "match_count", "name", "vendor", "type", "origin", "severity"] + """Field to sort by (case-insensitive). + + Defaults to 'created'. Name and vendor sorting is case-insensitive; vendor uses + friendly provider names. Ascending order: type Content then Posture; origin + custom then system; severity Low, Medium, High, Critical. + """ + + origins: List[Literal["custom", "system"]] + """Filter finding types by origin. + + Supports multiple comma-separated, case-insensitive values. + """ + page: int """A page number within the paginated result set.""" per_page: int """Number of results to return per page.""" + quarantined: bool + """ + When true, return only quarantined finding types; when false, return only + non-quarantined finding types. Omit to return both. + """ + search: str """Filter finding types by name or ID (case-insensitive substring match).""" + severities: List[Literal["critical", "high", "medium", "low"]] + """Filter finding types by severity. + + Supports multiple comma-separated, case-insensitive values. + """ + + types: List[Literal["Content", "Posture"]] + """Filter finding types by category type. + + Supports multiple comma-separated, case-insensitive values. + """ + vendors: List[ Literal[ "ANTHROPIC", @@ -33,7 +87,6 @@ class FindingTypeListParams(TypedDict, total=False): "GOOGLE_WORKSPACE", "JIRA", "MICROSOFT", - "MICROSOFT_INTERNAL", "OPENAI", "SALESFORCE", "SERVICENOW", diff --git a/src/cloudflare/types/zero_trust/casb/posture/finding_type_list_response.py b/src/cloudflare/types/zero_trust/casb/posture/finding_type_list_response.py index 2664e053aea..853fa47d1d8 100644 --- a/src/cloudflare/types/zero_trust/casb/posture/finding_type_list_response.py +++ b/src/cloudflare/types/zero_trust/casb/posture/finding_type_list_response.py @@ -1,6 +1,7 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import Optional +from typing import List, Optional +from datetime import datetime from typing_extensions import Literal from ....._models import BaseModel @@ -39,5 +40,73 @@ class FindingTypeListResponse(BaseModel): vendor: str """The SaaS/Cloud vendor of the platform with which the finding is associated.""" + applies_to_all_integrations: Optional[bool] = None + """ + Whether this finding type applies to every current and future integration of the + vendor. + """ + + asset_class: Optional[str] = None + """Asset class the finding type's policy evaluates.""" + + asset_vendor: Optional[ + Literal[ + "ANTHROPIC", + "AWS", + "BITBUCKET", + "BOX", + "CONFLUENCE", + "DROPBOX", + "GITHUB", + "GOOGLE_CLOUD_PLATFORM", + "GOOGLE_WORKSPACE", + "JIRA", + "MICROSOFT", + "OPENAI", + "SALESFORCE", + "SERVICENOW", + "SLACK", + "ZOOM", + ] + ] = None + """Canonical vendor enum value.""" + + created_at: Optional[datetime] = None + """Timestamp when the finding type was created.""" + description: Optional[str] = None """Detailed description of the finding.""" + + expression: Optional[str] = None + """Rego expression backing this finding type. + + For custom finding types, generated package and import declarations are omitted. + System expressions are returned unchanged. + """ + + integration_ids: Optional[List[str]] = None + """ + Integrations this finding type applies to when applies_to_all_integrations is + false. + """ + + match_count: Optional[int] = None + """Number of currently active finding instances across the account's integrations. + + Zero when none have been detected. + """ + + origin: Optional[Literal["system", "custom"]] = None + """Whether the finding type is system-managed or customer-created.""" + + quarantined: Optional[bool] = None + """Whether evaluation of this finding type is suspended by an operator. + + Present only when true. + """ + + updated_at: Optional[datetime] = None + """Timestamp when the finding type was last updated.""" + + version: Optional[int] = None + """Current version of the finding type. Incremented on each update.""" diff --git a/src/cloudflare/types/zero_trust/casb/posture/finding_type_update_params.py b/src/cloudflare/types/zero_trust/casb/posture/finding_type_update_params.py new file mode 100644 index 00000000000..95536674ff6 --- /dev/null +++ b/src/cloudflare/types/zero_trust/casb/posture/finding_type_update_params.py @@ -0,0 +1,44 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal, Required, TypedDict + +from ....._types import SequenceNotStr + +__all__ = ["FindingTypeUpdateParams"] + + +class FindingTypeUpdateParams(TypedDict, total=False): + account_id: Required[str] + + applies_to_all_integrations: Required[bool] + """ + When true, this finding type applies to every current and future integration of + the vendor. + """ + + description: str + """Optional description of the finding type. + + Cannot be empty if provided. Maximum 4096 characters. + """ + + integration_ids: SequenceNotStr[str] + """ + Required and non-empty when applies_to_all_integrations is false; omit when it + is true. + """ + + name: str + """Human-readable name for the finding type. + + Cannot be empty if provided. Maximum 256 characters. + """ + + severity: Literal["Critical", "High", "Medium", "Low"] + """Default severity used when no integration-specific severity override exists. + + Changing it reclassifies existing and future findings that do not have an + override. + """ diff --git a/src/cloudflare/types/zero_trust/casb/posture/finding_type_update_response.py b/src/cloudflare/types/zero_trust/casb/posture/finding_type_update_response.py new file mode 100644 index 00000000000..2fea42c3ebe --- /dev/null +++ b/src/cloudflare/types/zero_trust/casb/posture/finding_type_update_response.py @@ -0,0 +1,110 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional +from datetime import datetime +from typing_extensions import Literal + +from ....._models import BaseModel + +__all__ = ["FindingTypeUpdateResponse", "Category"] + + +class Category(BaseModel): + """Category information for a finding.""" + + observation: Literal["Issue", "Insight", "Activity"] + """The type of the observation.""" + + product: Literal["SaaS", "Cloud"] + """The product category.""" + + type: Literal["Content", "Posture"] + """The type of the finding category.""" + + +class FindingTypeUpdateResponse(BaseModel): + """Basic finding type information.""" + + id: str + """The unique identifier of the finding.""" + + applies_to_all_integrations: bool + """ + Whether this finding type applies to every current and future integration of the + vendor. + """ + + asset_class: str + """Asset class the finding type's policy evaluates.""" + + asset_vendor: Literal[ + "ANTHROPIC", + "AWS", + "BITBUCKET", + "BOX", + "CONFLUENCE", + "DROPBOX", + "GITHUB", + "GOOGLE_CLOUD_PLATFORM", + "GOOGLE_WORKSPACE", + "JIRA", + "MICROSOFT", + "OPENAI", + "SALESFORCE", + "SERVICENOW", + "SLACK", + "ZOOM", + ] + """Canonical vendor enum value.""" + + category: Category + """Category information for a finding.""" + + created_at: datetime + """Timestamp when the finding type was created.""" + + description: Optional[str] = None + """Detailed description of the finding.""" + + expression: str + """Rego expression backing this finding type. + + For custom finding types, generated package and import declarations are omitted. + System expressions are returned unchanged. + """ + + name: str + """The name of the finding.""" + + origin: Literal["system", "custom"] + """Whether the finding type is system-managed or customer-created.""" + + severity: Literal["Critical", "High", "Medium", "Low"] + """Default severity used when no integration-specific severity override exists.""" + + updated_at: datetime + """Timestamp when the finding type was last updated.""" + + vendor: str + """The SaaS/Cloud vendor of the platform with which the finding is associated.""" + + version: int + """Current version of the finding type. Incremented on each update.""" + + integration_ids: Optional[List[str]] = None + """ + Integrations this finding type applies to when applies_to_all_integrations is + false. + """ + + match_count: Optional[int] = None + """Number of currently active finding instances across the account's integrations. + + Zero when none have been detected. + """ + + quarantined: Optional[bool] = None + """Whether evaluation of this finding type is suspended by an operator. + + Present only when true. + """ diff --git a/src/cloudflare/types/zero_trust/casb/posture/finding_type_validate_params.py b/src/cloudflare/types/zero_trust/casb/posture/finding_type_validate_params.py new file mode 100644 index 00000000000..6804addf6a6 --- /dev/null +++ b/src/cloudflare/types/zero_trust/casb/posture/finding_type_validate_params.py @@ -0,0 +1,72 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal, Required, TypedDict + +from ....._types import SequenceNotStr + +__all__ = ["FindingTypeValidateParams"] + + +class FindingTypeValidateParams(TypedDict, total=False): + account_id: Required[str] + + applies_to_all_integrations: Required[bool] + """ + When true, this finding type applies to every current and future integration of + the vendor. + """ + + asset_class: Required[str] + """Asset class this finding type applies to (PascalCase, e.g. GoogleWorkspaceFile)""" + + asset_vendor: Required[ + Literal[ + "ANTHROPIC", + "AWS", + "BITBUCKET", + "BOX", + "CONFLUENCE", + "DROPBOX", + "GITHUB", + "GOOGLE_CLOUD_PLATFORM", + "GOOGLE_WORKSPACE", + "JIRA", + "MICROSOFT", + "OPENAI", + "SALESFORCE", + "SERVICENOW", + "SLACK", + "ZOOM", + ] + ] + """ + Canonical vendor enum for the platform whose assets this finding type evaluates. + """ + + description: Required[str] + """Human-readable description of the finding type. + + Cannot be empty. Maximum 4096 characters. + """ + + expression: Required[str] + """Rego expression body for the policy. + + `package cloudflare.casb.custom` and `import rego.v1` are added automatically. + Do not include package or import declarations. This field cannot be changed + after creation. Maximum 4096 characters. + """ + + name: Required[str] + """Human-readable name for the finding type. Maximum 256 characters.""" + + severity: Required[Literal["Critical", "High", "Medium", "Low"]] + """Default severity used when no integration-specific severity override exists.""" + + integration_ids: SequenceNotStr[str] + """ + Required and non-empty when applies_to_all_integrations is false; omit when it + is true. + """ diff --git a/src/cloudflare/types/zero_trust/casb/posture/finding_type_validate_response.py b/src/cloudflare/types/zero_trust/casb/posture/finding_type_validate_response.py new file mode 100644 index 00000000000..4d81d092653 --- /dev/null +++ b/src/cloudflare/types/zero_trust/casb/posture/finding_type_validate_response.py @@ -0,0 +1,53 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional + +from ....._models import BaseModel + +__all__ = ["FindingTypeValidateResponse", "Error"] + + +class Error(BaseModel): + detail: str + """Description of the problem.""" + + message: str + """Deprecated: use `detail`.""" + + code: Optional[str] = None + """Machine-readable identifier for the class of problem, when one is available. + + Omitted otherwise. + """ + + column: Optional[int] = None + """1-based column on `line`. + + Omitted when the problem could not be located in the submitted source. + """ + + field: Optional[str] = None + """ + Request field the problem belongs to, matching the property names of + `ValidateFindingTypeRequest`. Array properties are reported per entry with a + zero-based index, for example `integration_ids[0]`. Empty when the problem + cannot be attributed to a single submitted field. + """ + + line: Optional[int] = None + """1-based line in `expression` where the problem was found. + + Omitted when the problem could not be located in the submitted source. + """ + + +class FindingTypeValidateResponse(BaseModel): + errors: List[Error] + """Every problem found with the candidate, so all of them can be surfaced at once. + + Empty when `valid` is true. Problems without a location come first, followed by + located problems ordered by `line`, then `column`. + """ + + valid: bool + """Whether the candidate finding type would be accepted as-is.""" diff --git a/src/cloudflare/types/zero_trust/casb/posture/finding_unignore_response.py b/src/cloudflare/types/zero_trust/casb/posture/finding_unignore_response.py index 68d08f212bc..e8a1a965c86 100644 --- a/src/cloudflare/types/zero_trust/casb/posture/finding_unignore_response.py +++ b/src/cloudflare/types/zero_trust/casb/posture/finding_unignore_response.py @@ -69,12 +69,80 @@ class Finding(BaseModel): vendor: str """The SaaS/Cloud vendor of the platform with which the finding is associated.""" + applies_to_all_integrations: Optional[bool] = None + """ + Whether this finding type applies to every current and future integration of the + vendor. + """ + + asset_class: Optional[str] = None + """Asset class the finding type's policy evaluates.""" + + asset_vendor: Optional[ + Literal[ + "ANTHROPIC", + "AWS", + "BITBUCKET", + "BOX", + "CONFLUENCE", + "DROPBOX", + "GITHUB", + "GOOGLE_CLOUD_PLATFORM", + "GOOGLE_WORKSPACE", + "JIRA", + "MICROSOFT", + "OPENAI", + "SALESFORCE", + "SERVICENOW", + "SLACK", + "ZOOM", + ] + ] = None + """Canonical vendor enum value.""" + + created_at: Optional[datetime] = None + """Timestamp when the finding type was created.""" + description: Optional[str] = None """Detailed description of the finding.""" + expression: Optional[str] = None + """Rego expression backing this finding type. + + For custom finding types, generated package and import declarations are omitted. + System expressions are returned unchanged. + """ + + integration_ids: Optional[List[str]] = None + """ + Integrations this finding type applies to when applies_to_all_integrations is + false. + """ + + match_count: Optional[int] = None + """Number of currently active finding instances across the account's integrations. + + Zero when none have been detected. + """ + + origin: Optional[Literal["system", "custom"]] = None + """Whether the finding type is system-managed or customer-created.""" + + quarantined: Optional[bool] = None + """Whether evaluation of this finding type is suspended by an operator. + + Present only when true. + """ + remediation: Optional[FindingRemediation] = None """Remediation guide information for a finding.""" + updated_at: Optional[datetime] = None + """Timestamp when the finding type was last updated.""" + + version: Optional[int] = None + """Current version of the finding type. Incremented on each update.""" + class IntegrationPolicy(BaseModel): """Policy configuration for an integration.""" diff --git a/src/cloudflare/types/zero_trust/casb/posture/policy_create_response.py b/src/cloudflare/types/zero_trust/casb/posture/policy_create_response.py index 42645e6f2b7..ab46819433c 100644 --- a/src/cloudflare/types/zero_trust/casb/posture/policy_create_response.py +++ b/src/cloudflare/types/zero_trust/casb/posture/policy_create_response.py @@ -74,7 +74,7 @@ class PolicyCreateResponse(BaseModel): finding_type_id: str """The finding type this policy is associated with. - Immutable after creation; changing it replaces the policy. + Immutable after creation; attempts to change it via update are rejected. """ integration_ids: List[str] diff --git a/src/cloudflare/types/zero_trust/casb/posture/policy_get_response.py b/src/cloudflare/types/zero_trust/casb/posture/policy_get_response.py index 402710d7627..45ab4c3b613 100644 --- a/src/cloudflare/types/zero_trust/casb/posture/policy_get_response.py +++ b/src/cloudflare/types/zero_trust/casb/posture/policy_get_response.py @@ -74,7 +74,7 @@ class PolicyGetResponse(BaseModel): finding_type_id: str """The finding type this policy is associated with. - Immutable after creation; changing it replaces the policy. + Immutable after creation; attempts to change it via update are rejected. """ integration_ids: List[str] diff --git a/src/cloudflare/types/zero_trust/casb/posture/policy_list_response.py b/src/cloudflare/types/zero_trust/casb/posture/policy_list_response.py index ed8946eff14..0d8a0300366 100644 --- a/src/cloudflare/types/zero_trust/casb/posture/policy_list_response.py +++ b/src/cloudflare/types/zero_trust/casb/posture/policy_list_response.py @@ -74,7 +74,7 @@ class PolicyListResponse(BaseModel): finding_type_id: str """The finding type this policy is associated with. - Immutable after creation; changing it replaces the policy. + Immutable after creation; attempts to change it via update are rejected. """ integration_ids: List[str] diff --git a/src/cloudflare/types/zero_trust/casb/posture/policy_update_response.py b/src/cloudflare/types/zero_trust/casb/posture/policy_update_response.py index 4999d840386..d90b816ce88 100644 --- a/src/cloudflare/types/zero_trust/casb/posture/policy_update_response.py +++ b/src/cloudflare/types/zero_trust/casb/posture/policy_update_response.py @@ -74,7 +74,7 @@ class PolicyUpdateResponse(BaseModel): finding_type_id: str """The finding type this policy is associated with. - Immutable after creation; changing it replaces the policy. + Immutable after creation; attempts to change it via update are rejected. """ integration_ids: List[str] diff --git a/src/cloudflare/types/zero_trust/cws/__init__.py b/src/cloudflare/types/zero_trust/cws/__init__.py new file mode 100644 index 00000000000..e023b53eb53 --- /dev/null +++ b/src/cloudflare/types/zero_trust/cws/__init__.py @@ -0,0 +1,50 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from .policy import Policy as Policy +from .workload import Workload as Workload +from .deployment import Deployment as Deployment +from .domain_acl import DomainACL as DomainACL +from .policy_set import PolicySet as PolicySet +from .rego_module import RegoModule as RegoModule +from .rego_metadata import RegoMetadata as RegoMetadata +from .tenant_structure import TenantStructure as TenantStructure +from .policy_list_params import PolicyListParams as PolicyListParams +from .policy_create_params import PolicyCreateParams as PolicyCreateParams +from .policy_update_params import PolicyUpdateParams as PolicyUpdateParams +from .workload_list_params import WorkloadListParams as WorkloadListParams +from .basic_auth_credential import BasicAuthCredential as BasicAuthCredential +from .deployment_list_params import DeploymentListParams as DeploymentListParams +from .domain_acl_list_params import DomainACLListParams as DomainACLListParams +from .policy_delete_response import PolicyDeleteResponse as PolicyDeleteResponse +from .policy_set_list_params import PolicySetListParams as PolicySetListParams +from .workload_create_params import WorkloadCreateParams as WorkloadCreateParams +from .workload_update_params import WorkloadUpdateParams as WorkloadUpdateParams +from .rego_module_list_params import RegoModuleListParams as RegoModuleListParams +from .deployment_create_params import DeploymentCreateParams as DeploymentCreateParams +from .deployment_update_params import DeploymentUpdateParams as DeploymentUpdateParams +from .domain_acl_create_params import DomainACLCreateParams as DomainACLCreateParams +from .domain_acl_update_params import DomainACLUpdateParams as DomainACLUpdateParams +from .policy_set_create_params import PolicySetCreateParams as PolicySetCreateParams +from .policy_set_update_params import PolicySetUpdateParams as PolicySetUpdateParams +from .workload_delete_response import WorkloadDeleteResponse as WorkloadDeleteResponse +from .rego_metadata_list_params import RegoMetadataListParams as RegoMetadataListParams +from .rego_module_create_params import RegoModuleCreateParams as RegoModuleCreateParams +from .rego_module_update_params import RegoModuleUpdateParams as RegoModuleUpdateParams +from .deployment_delete_response import DeploymentDeleteResponse as DeploymentDeleteResponse +from .domain_acl_delete_response import DomainACLDeleteResponse as DomainACLDeleteResponse +from .policy_set_delete_response import PolicySetDeleteResponse as PolicySetDeleteResponse +from .rego_metadata_create_params import RegoMetadataCreateParams as RegoMetadataCreateParams +from .rego_metadata_update_params import RegoMetadataUpdateParams as RegoMetadataUpdateParams +from .rego_module_delete_response import RegoModuleDeleteResponse as RegoModuleDeleteResponse +from .tenant_structure_list_params import TenantStructureListParams as TenantStructureListParams +from .rego_metadata_delete_response import RegoMetadataDeleteResponse as RegoMetadataDeleteResponse +from .tenant_structure_create_params import TenantStructureCreateParams as TenantStructureCreateParams +from .tenant_structure_update_params import TenantStructureUpdateParams as TenantStructureUpdateParams +from .tenant_structure_delete_response import TenantStructureDeleteResponse as TenantStructureDeleteResponse +from .basic_auth_credential_list_params import BasicAuthCredentialListParams as BasicAuthCredentialListParams +from .basic_auth_credential_create_params import BasicAuthCredentialCreateParams as BasicAuthCredentialCreateParams +from .basic_auth_credential_delete_response import ( + BasicAuthCredentialDeleteResponse as BasicAuthCredentialDeleteResponse, +) diff --git a/src/cloudflare/types/zero_trust/cws/basic_auth_credential.py b/src/cloudflare/types/zero_trust/cws/basic_auth_credential.py new file mode 100644 index 00000000000..ed3291aecb6 --- /dev/null +++ b/src/cloudflare/types/zero_trust/cws/basic_auth_credential.py @@ -0,0 +1,23 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from datetime import datetime + +from ...._models import BaseModel + +__all__ = ["BasicAuthCredential"] + + +class BasicAuthCredential(BaseModel): + id: str + """Server-assigned UUID""" + + created_at: datetime + + updated_at: datetime + + username: str + """Login presented by the client. + + Printable ASCII only, excluding space and colon (RFC 7617 forbids a colon in the + user-id). + """ diff --git a/src/cloudflare/types/zero_trust/cws/basic_auth_credential_create_params.py b/src/cloudflare/types/zero_trust/cws/basic_auth_credential_create_params.py new file mode 100644 index 00000000000..97f288f401c --- /dev/null +++ b/src/cloudflare/types/zero_trust/cws/basic_auth_credential_create_params.py @@ -0,0 +1,15 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Required, TypedDict + +__all__ = ["BasicAuthCredentialCreateParams"] + + +class BasicAuthCredentialCreateParams(TypedDict, total=False): + account_id: Required[str] + """Cloudflare account ID (32-character hexadecimal string)""" + + username: Required[str] + """Login presented by the client. Printable ASCII only, excluding space and colon.""" diff --git a/src/cloudflare/types/zero_trust/cws/basic_auth_credential_delete_response.py b/src/cloudflare/types/zero_trust/cws/basic_auth_credential_delete_response.py new file mode 100644 index 00000000000..92b1b026c69 --- /dev/null +++ b/src/cloudflare/types/zero_trust/cws/basic_auth_credential_delete_response.py @@ -0,0 +1,9 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from ...._models import BaseModel + +__all__ = ["BasicAuthCredentialDeleteResponse"] + + +class BasicAuthCredentialDeleteResponse(BaseModel): + id: str diff --git a/src/cloudflare/types/zero_trust/cws/basic_auth_credential_list_params.py b/src/cloudflare/types/zero_trust/cws/basic_auth_credential_list_params.py new file mode 100644 index 00000000000..842b8ad18d2 --- /dev/null +++ b/src/cloudflare/types/zero_trust/cws/basic_auth_credential_list_params.py @@ -0,0 +1,30 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal, Required, TypedDict + +__all__ = ["BasicAuthCredentialListParams"] + + +class BasicAuthCredentialListParams(TypedDict, total=False): + account_id: Required[str] + """Cloudflare account ID (32-character hexadecimal string)""" + + cursor: str + """Pagination cursor from previous response""" + + deployment_id: str + """Filter to credentials attached to this deployment""" + + direction: Literal["asc", "desc"] + """Sort direction (default: asc)""" + + order: Literal["username", "created_at", "updated_at"] + """Field to order results by (default: created_at)""" + + per_page: int + """Number of items per page (1-100, default 20)""" + + username: str + """Filter by username (case-insensitive substring match)""" diff --git a/src/cloudflare/types/zero_trust/cws/basic_auth_credentials/__init__.py b/src/cloudflare/types/zero_trust/cws/basic_auth_credentials/__init__.py new file mode 100644 index 00000000000..44ca133a7e6 --- /dev/null +++ b/src/cloudflare/types/zero_trust/cws/basic_auth_credentials/__init__.py @@ -0,0 +1,8 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from .basic_auth_secret import BasicAuthSecret as BasicAuthSecret +from .secret_list_params import SecretListParams as SecretListParams +from .secret_create_params import SecretCreateParams as SecretCreateParams +from .secret_delete_response import SecretDeleteResponse as SecretDeleteResponse diff --git a/src/cloudflare/types/zero_trust/cws/basic_auth_credentials/basic_auth_secret.py b/src/cloudflare/types/zero_trust/cws/basic_auth_credentials/basic_auth_secret.py new file mode 100644 index 00000000000..264d1896914 --- /dev/null +++ b/src/cloudflare/types/zero_trust/cws/basic_auth_credentials/basic_auth_secret.py @@ -0,0 +1,18 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional +from datetime import datetime + +from ....._models import BaseModel + +__all__ = ["BasicAuthSecret"] + + +class BasicAuthSecret(BaseModel): + id: str + """Server-assigned UUID""" + + created_at: datetime + + expires_at: Optional[datetime] = None + """Optional RFC 3339 expiration time. Omit for no expiration.""" diff --git a/src/cloudflare/types/zero_trust/cws/basic_auth_credentials/secret_create_params.py b/src/cloudflare/types/zero_trust/cws/basic_auth_credentials/secret_create_params.py new file mode 100644 index 00000000000..cdc8e52f450 --- /dev/null +++ b/src/cloudflare/types/zero_trust/cws/basic_auth_credentials/secret_create_params.py @@ -0,0 +1,25 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Union +from datetime import datetime +from typing_extensions import Required, Annotated, TypedDict + +from ....._utils import PropertyInfo + +__all__ = ["SecretCreateParams"] + + +class SecretCreateParams(TypedDict, total=False): + account_id: Required[str] + """Cloudflare account ID (32-character hexadecimal string)""" + + password: Required[str] + """Password stored only as a one-way hash and never returned. + + Maximum 72 UTF-8 bytes. + """ + + expires_at: Annotated[Union[str, datetime, None], PropertyInfo(format="iso8601")] + """Optional deactivation deadline (RFC 3339). Omit or null for no expiry.""" diff --git a/src/cloudflare/types/zero_trust/cws/basic_auth_credentials/secret_delete_response.py b/src/cloudflare/types/zero_trust/cws/basic_auth_credentials/secret_delete_response.py new file mode 100644 index 00000000000..d850aacf08e --- /dev/null +++ b/src/cloudflare/types/zero_trust/cws/basic_auth_credentials/secret_delete_response.py @@ -0,0 +1,9 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from ....._models import BaseModel + +__all__ = ["SecretDeleteResponse"] + + +class SecretDeleteResponse(BaseModel): + id: str diff --git a/src/cloudflare/types/zero_trust/cws/basic_auth_credentials/secret_list_params.py b/src/cloudflare/types/zero_trust/cws/basic_auth_credentials/secret_list_params.py new file mode 100644 index 00000000000..e95ab9418ca --- /dev/null +++ b/src/cloudflare/types/zero_trust/cws/basic_auth_credentials/secret_list_params.py @@ -0,0 +1,24 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal, Required, TypedDict + +__all__ = ["SecretListParams"] + + +class SecretListParams(TypedDict, total=False): + account_id: Required[str] + """Cloudflare account ID (32-character hexadecimal string)""" + + cursor: str + """Pagination cursor from previous response""" + + direction: Literal["asc", "desc"] + """Sort direction (default: asc)""" + + order: Literal["created_at"] + """Field to order results by (default: created_at)""" + + per_page: int + """Number of items per page (1-100, default 20)""" diff --git a/src/cloudflare/types/zero_trust/cws/deployment.py b/src/cloudflare/types/zero_trust/cws/deployment.py new file mode 100644 index 00000000000..f9f4ea74c49 --- /dev/null +++ b/src/cloudflare/types/zero_trust/cws/deployment.py @@ -0,0 +1,45 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Dict, List, Optional +from datetime import datetime +from typing_extensions import Literal + +from ...._models import BaseModel + +__all__ = ["Deployment"] + + +class Deployment(BaseModel): + id: str + """Server-assigned UUID""" + + basic_auth_credential_ids: Optional[List[str]] = None + """IDs of basic-auth credentials attached to this deployment""" + + created_at: datetime + + default_mode: Literal["ALLOW", "BLOCK"] + """Default traffic decision when no policy set matches""" + + name: str + """Human-readable name; unique per account""" + + on_error_action: Literal["BLOCK", "SKIP"] + """Action applied when an enforcing policy has a runtime Rego error""" + + policy_set_ids: Optional[List[str]] = None + """IDs of policy sets attached to this deployment""" + + rego_raise_error: bool + """Whether OPA builtin failures are raised as runtime evaluation errors""" + + tags: Dict[str, str] + """Tags attached to this deployment""" + + updated_at: datetime + + description: Optional[str] = None + """Optional free-form description.""" + + domain_acl_id: Optional[str] = None + """ID of the attached domain ACL. Omitted when none.""" diff --git a/src/cloudflare/types/zero_trust/cws/deployment_create_params.py b/src/cloudflare/types/zero_trust/cws/deployment_create_params.py new file mode 100644 index 00000000000..c71e58cd03c --- /dev/null +++ b/src/cloudflare/types/zero_trust/cws/deployment_create_params.py @@ -0,0 +1,48 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Dict, Optional +from typing_extensions import Literal, Required, TypedDict + +from ...._types import SequenceNotStr + +__all__ = ["DeploymentCreateParams"] + + +class DeploymentCreateParams(TypedDict, total=False): + account_id: Required[str] + """Cloudflare account ID (32-character hexadecimal string)""" + + basic_auth_credential_ids: Required[Optional[SequenceNotStr[str]]] + """IDs of basic-auth credentials to attach""" + + default_mode: Required[Literal["ALLOW", "BLOCK"]] + """Default traffic mode: ALLOW or BLOCK""" + + name: Required[str] + """Name of the deployment""" + + policy_set_ids: Required[Optional[SequenceNotStr[str]]] + """IDs of policy sets to attach""" + + description: str + """Optional free-form description.""" + + domain_acl_id: Optional[str] + """ID of the domain ACL to attach (omit or null for none)""" + + on_error_action: Literal["BLOCK", "SKIP"] + """Action for runtime Rego errors. Omit to use BLOCK.""" + + rego_raise_error: bool + """Whether OPA builtin failures are raised as runtime evaluation errors. + + Omit to use the default true value. + """ + + tags: Dict[str, str] + """Tags to attach. + + Keys are limited to 256 UTF-8 bytes and values to 1024 UTF-8 bytes. + """ diff --git a/src/cloudflare/types/zero_trust/cws/deployment_delete_response.py b/src/cloudflare/types/zero_trust/cws/deployment_delete_response.py new file mode 100644 index 00000000000..a5ca997f80f --- /dev/null +++ b/src/cloudflare/types/zero_trust/cws/deployment_delete_response.py @@ -0,0 +1,9 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from ...._models import BaseModel + +__all__ = ["DeploymentDeleteResponse"] + + +class DeploymentDeleteResponse(BaseModel): + id: str diff --git a/src/cloudflare/types/zero_trust/cws/deployment_list_params.py b/src/cloudflare/types/zero_trust/cws/deployment_list_params.py new file mode 100644 index 00000000000..5470d1412ea --- /dev/null +++ b/src/cloudflare/types/zero_trust/cws/deployment_list_params.py @@ -0,0 +1,27 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal, Required, TypedDict + +__all__ = ["DeploymentListParams"] + + +class DeploymentListParams(TypedDict, total=False): + account_id: Required[str] + """Cloudflare account ID (32-character hexadecimal string)""" + + cursor: str + """Pagination cursor from previous response""" + + direction: Literal["asc", "desc"] + """Sort direction (default: asc)""" + + name: str + """Filter by deployment name (case-insensitive substring match)""" + + order: Literal["name", "created_at", "updated_at"] + """Field to order results by (default: created_at)""" + + per_page: int + """Number of items per page (1-100, default 20)""" diff --git a/src/cloudflare/types/zero_trust/cws/deployment_update_params.py b/src/cloudflare/types/zero_trust/cws/deployment_update_params.py new file mode 100644 index 00000000000..55f86965777 --- /dev/null +++ b/src/cloudflare/types/zero_trust/cws/deployment_update_params.py @@ -0,0 +1,49 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Dict, Optional +from typing_extensions import Literal, Required, TypedDict + +from ...._types import SequenceNotStr + +__all__ = ["DeploymentUpdateParams"] + + +class DeploymentUpdateParams(TypedDict, total=False): + account_id: Required[str] + """Cloudflare account ID (32-character hexadecimal string)""" + + basic_auth_credential_ids: Required[Optional[SequenceNotStr[str]]] + """Replacement set of basic-auth credential IDs""" + + default_mode: Required[Literal["ALLOW", "BLOCK"]] + """Default traffic mode: ALLOW or BLOCK""" + + name: Required[str] + """Name of the deployment""" + + policy_set_ids: Required[Optional[SequenceNotStr[str]]] + """Replacement set of policy set IDs""" + + description: str + """Optional free-form description.""" + + domain_acl_id: Optional[str] + """ID of the domain ACL to attach (omit or null to clear)""" + + on_error_action: Literal["BLOCK", "SKIP"] + """Action for runtime Rego errors. Omit to reset to BLOCK.""" + + rego_raise_error: bool + """Whether OPA builtin failures are raised as runtime evaluation errors. + + Omit to reset to true. + """ + + tags: Dict[str, str] + """Replacement tag set. + + Omit or use {} to clear. Keys are limited to 256 UTF-8 bytes and values to 1024 + UTF-8 bytes. + """ diff --git a/src/cloudflare/types/zero_trust/cws/domain_acl.py b/src/cloudflare/types/zero_trust/cws/domain_acl.py new file mode 100644 index 00000000000..b32b45f9253 --- /dev/null +++ b/src/cloudflare/types/zero_trust/cws/domain_acl.py @@ -0,0 +1,35 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional +from datetime import datetime +from typing_extensions import Literal + +from ...._models import BaseModel + +__all__ = ["DomainACL", "Entry"] + + +class Entry(BaseModel): + action: Literal["ALLOW", "BLOCK"] + """Per-domain decision overriding the parent ACL's default_action""" + + domain: str + """Hostname or domain pattern, capped at 255 UTF-8 bytes""" + + +class DomainACL(BaseModel): + id: str + """Server-assigned UUID""" + + created_at: datetime + + default_action: Literal["ALLOW", "BLOCK"] + """Action applied when no entry matches the request domain""" + + entries: Optional[List[Entry]] = None + """Per-domain action overrides. Each domain appears at most once.""" + + name: str + """Human-readable name; unique per account""" + + updated_at: datetime diff --git a/src/cloudflare/types/zero_trust/cws/domain_acl_create_params.py b/src/cloudflare/types/zero_trust/cws/domain_acl_create_params.py new file mode 100644 index 00000000000..e71c96f1aec --- /dev/null +++ b/src/cloudflare/types/zero_trust/cws/domain_acl_create_params.py @@ -0,0 +1,30 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Iterable, Optional +from typing_extensions import Literal, Required, TypedDict + +__all__ = ["DomainACLCreateParams", "Entry"] + + +class DomainACLCreateParams(TypedDict, total=False): + account_id: Required[str] + """Cloudflare account ID (32-character hexadecimal string)""" + + default_action: Required[Literal["ALLOW", "BLOCK"]] + """Default action when no entry matches""" + + entries: Required[Optional[Iterable[Entry]]] + """Domain entries for this ACL. Each domain must appear at most once.""" + + name: Required[str] + """Name of the domain ACL""" + + +class Entry(TypedDict, total=False): + action: Required[Literal["ALLOW", "BLOCK"]] + """Per-domain decision overriding the parent ACL's default_action""" + + domain: Required[str] + """Hostname or domain pattern, capped at 255 UTF-8 bytes""" diff --git a/src/cloudflare/types/zero_trust/cws/domain_acl_delete_response.py b/src/cloudflare/types/zero_trust/cws/domain_acl_delete_response.py new file mode 100644 index 00000000000..871fd68a247 --- /dev/null +++ b/src/cloudflare/types/zero_trust/cws/domain_acl_delete_response.py @@ -0,0 +1,9 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from ...._models import BaseModel + +__all__ = ["DomainACLDeleteResponse"] + + +class DomainACLDeleteResponse(BaseModel): + id: str diff --git a/src/cloudflare/types/zero_trust/cws/domain_acl_list_params.py b/src/cloudflare/types/zero_trust/cws/domain_acl_list_params.py new file mode 100644 index 00000000000..68ebcbb3f4b --- /dev/null +++ b/src/cloudflare/types/zero_trust/cws/domain_acl_list_params.py @@ -0,0 +1,30 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal, Required, TypedDict + +__all__ = ["DomainACLListParams"] + + +class DomainACLListParams(TypedDict, total=False): + account_id: Required[str] + """Cloudflare account ID (32-character hexadecimal string)""" + + cursor: str + """Pagination cursor from previous response""" + + deployment_id: str + """Filter to domain ACLs attached to this deployment""" + + direction: Literal["asc", "desc"] + """Sort direction (default: asc)""" + + name: str + """Filter by domain ACL name (case-insensitive substring match)""" + + order: Literal["name", "created_at", "updated_at"] + """Field to order results by (default: created_at)""" + + per_page: int + """Number of items per page (1-100, default 20)""" diff --git a/src/cloudflare/types/zero_trust/cws/domain_acl_update_params.py b/src/cloudflare/types/zero_trust/cws/domain_acl_update_params.py new file mode 100644 index 00000000000..fb827fac422 --- /dev/null +++ b/src/cloudflare/types/zero_trust/cws/domain_acl_update_params.py @@ -0,0 +1,30 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Iterable, Optional +from typing_extensions import Literal, Required, TypedDict + +__all__ = ["DomainACLUpdateParams", "Entry"] + + +class DomainACLUpdateParams(TypedDict, total=False): + account_id: Required[str] + """Cloudflare account ID (32-character hexadecimal string)""" + + default_action: Required[Literal["ALLOW", "BLOCK"]] + """Default action when no entry matches""" + + entries: Required[Optional[Iterable[Entry]]] + """Replacement set of domain entries. Each domain must appear at most once.""" + + name: Required[str] + """Name of the domain ACL""" + + +class Entry(TypedDict, total=False): + action: Required[Literal["ALLOW", "BLOCK"]] + """Per-domain decision overriding the parent ACL's default_action""" + + domain: Required[str] + """Hostname or domain pattern, capped at 255 UTF-8 bytes""" diff --git a/src/cloudflare/types/zero_trust/cws/policy.py b/src/cloudflare/types/zero_trust/cws/policy.py new file mode 100644 index 00000000000..953a0027cb0 --- /dev/null +++ b/src/cloudflare/types/zero_trust/cws/policy.py @@ -0,0 +1,50 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Dict, Optional +from datetime import datetime + +from ...._models import BaseModel + +__all__ = ["Policy"] + + +class Policy(BaseModel): + id: str + """Server-assigned UUID""" + + created_at: datetime + + entrypoint: str + """Non-function rule declared in rego_source. + + Evaluation uses data... + """ + + filter: str + """Filter expression that determines whether this policy applies. + + Maximum 4096 UTF-8 bytes. + """ + + name: str + """Human-readable name; unique per account""" + + package_path: str + """Dotted path derived from rego_source. + + Begins with policy. and is unique per account. + """ + + rego_source: str + """ + Inline Rego source with a package beginning with "policy." Maximum 16384 UTF-8 + bytes. + """ + + tags: Dict[str, str] + """Tags attached to this policy""" + + updated_at: datetime + + description: Optional[str] = None + """Optional free-form description.""" diff --git a/src/cloudflare/types/zero_trust/cws/policy_create_params.py b/src/cloudflare/types/zero_trust/cws/policy_create_params.py new file mode 100644 index 00000000000..13121de63a1 --- /dev/null +++ b/src/cloudflare/types/zero_trust/cws/policy_create_params.py @@ -0,0 +1,43 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Dict +from typing_extensions import Required, TypedDict + +__all__ = ["PolicyCreateParams"] + + +class PolicyCreateParams(TypedDict, total=False): + account_id: Required[str] + """Cloudflare account ID (32-character hexadecimal string)""" + + entrypoint: Required[str] + """Non-function rule declared in rego_source. + + Evaluation uses data... + """ + + filter: Required[str] + """Filter expression that determines whether this policy applies. + + Maximum 4096 UTF-8 bytes. + """ + + name: Required[str] + """Name of the policy""" + + rego_source: Required[str] + """ + Inline Rego source with a package beginning with "policy." Maximum 16384 UTF-8 + bytes. + """ + + description: str + """Optional free-form description.""" + + tags: Dict[str, str] + """Tags to attach. + + Keys are limited to 256 UTF-8 bytes and values to 1024 UTF-8 bytes. + """ diff --git a/src/cloudflare/types/zero_trust/cws/policy_delete_response.py b/src/cloudflare/types/zero_trust/cws/policy_delete_response.py new file mode 100644 index 00000000000..4b75e1a8d70 --- /dev/null +++ b/src/cloudflare/types/zero_trust/cws/policy_delete_response.py @@ -0,0 +1,9 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from ...._models import BaseModel + +__all__ = ["PolicyDeleteResponse"] + + +class PolicyDeleteResponse(BaseModel): + id: str diff --git a/src/cloudflare/types/zero_trust/cws/policy_list_params.py b/src/cloudflare/types/zero_trust/cws/policy_list_params.py new file mode 100644 index 00000000000..8b609402dd2 --- /dev/null +++ b/src/cloudflare/types/zero_trust/cws/policy_list_params.py @@ -0,0 +1,33 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal, Required, TypedDict + +__all__ = ["PolicyListParams"] + + +class PolicyListParams(TypedDict, total=False): + account_id: Required[str] + """Cloudflare account ID (32-character hexadecimal string)""" + + cursor: str + """Pagination cursor from previous response""" + + direction: Literal["asc", "desc"] + """Sort direction (default: asc)""" + + name: str + """Filter by policy name (case-insensitive substring match)""" + + order: Literal["name", "created_at", "updated_at"] + """Field to order results by (default: created_at)""" + + package_path: str + """Filter by package path (case-sensitive literal substring match)""" + + per_page: int + """Number of items per page (1-100, default 20)""" + + policy_set_id: str + """Filter to policies attached to (members of) this policy set""" diff --git a/src/cloudflare/types/zero_trust/cws/policy_set.py b/src/cloudflare/types/zero_trust/cws/policy_set.py new file mode 100644 index 00000000000..7a3e10a081e --- /dev/null +++ b/src/cloudflare/types/zero_trust/cws/policy_set.py @@ -0,0 +1,49 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Dict, List, Optional +from datetime import datetime + +from ...._models import BaseModel + +__all__ = ["PolicySet", "Policy"] + + +class Policy(BaseModel): + enforce: bool + """Whether this policy should enforce when it matches. + + False keeps the policy attached for non-enforcing evaluation. + """ + + policy_id: str + """ID of the member policy""" + + +class PolicySet(BaseModel): + id: str + """Server-assigned UUID""" + + created_at: datetime + + exclude_workload_ids: Optional[List[str]] = None + """IDs of workloads that exclude matching requests. Exclusions take precedence.""" + + include_workload_ids: Optional[List[str]] = None + """IDs of workloads that include matching requests. + + Empty includes all requests before exclusions. + """ + + name: str + """Human-readable name; unique per account""" + + policies: Optional[List[Policy]] = None + """Member policies and their per-membership enforcement mode""" + + tags: Dict[str, str] + """Tags attached to this policy set""" + + updated_at: datetime + + description: Optional[str] = None + """Optional free-form description.""" diff --git a/src/cloudflare/types/zero_trust/cws/policy_set_create_params.py b/src/cloudflare/types/zero_trust/cws/policy_set_create_params.py new file mode 100644 index 00000000000..43fa412c169 --- /dev/null +++ b/src/cloudflare/types/zero_trust/cws/policy_set_create_params.py @@ -0,0 +1,50 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Dict, Iterable, Optional +from typing_extensions import Required, TypedDict + +from ...._types import SequenceNotStr + +__all__ = ["PolicySetCreateParams", "Policy"] + + +class PolicySetCreateParams(TypedDict, total=False): + account_id: Required[str] + """Cloudflare account ID (32-character hexadecimal string)""" + + name: Required[str] + """Name of the policy set""" + + policies: Required[Optional[Iterable[Policy]]] + """Policies to include with per-membership enforcement mode""" + + description: str + """Optional free-form description.""" + + exclude_workload_ids: Optional[SequenceNotStr[str]] + """Workload IDs that exclude matching requests. Exclusions take precedence.""" + + include_workload_ids: Optional[SequenceNotStr[str]] + """Workload IDs that include matching requests. + + Empty or omitted includes all requests before exclusions. + """ + + tags: Dict[str, str] + """Tags to attach. + + Keys are limited to 256 UTF-8 bytes and values to 1024 UTF-8 bytes. + """ + + +class Policy(TypedDict, total=False): + policy_id: Required[str] + """ID of the member policy""" + + enforce: bool + """Whether this policy should enforce when it matches. + + Defaults to true; false keeps the policy attached for non-enforcing evaluation. + """ diff --git a/src/cloudflare/types/zero_trust/cws/policy_set_delete_response.py b/src/cloudflare/types/zero_trust/cws/policy_set_delete_response.py new file mode 100644 index 00000000000..cec63f19150 --- /dev/null +++ b/src/cloudflare/types/zero_trust/cws/policy_set_delete_response.py @@ -0,0 +1,9 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from ...._models import BaseModel + +__all__ = ["PolicySetDeleteResponse"] + + +class PolicySetDeleteResponse(BaseModel): + id: str diff --git a/src/cloudflare/types/zero_trust/cws/policy_set_list_params.py b/src/cloudflare/types/zero_trust/cws/policy_set_list_params.py new file mode 100644 index 00000000000..1273d1fe6bc --- /dev/null +++ b/src/cloudflare/types/zero_trust/cws/policy_set_list_params.py @@ -0,0 +1,30 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal, Required, TypedDict + +__all__ = ["PolicySetListParams"] + + +class PolicySetListParams(TypedDict, total=False): + account_id: Required[str] + """Cloudflare account ID (32-character hexadecimal string)""" + + cursor: str + """Pagination cursor from previous response""" + + deployment_id: str + """Filter to policy sets attached to this deployment""" + + direction: Literal["asc", "desc"] + """Sort direction (default: asc)""" + + name: str + """Filter by policy set name (case-insensitive substring match)""" + + order: Literal["name", "created_at", "updated_at"] + """Field to order results by (default: created_at)""" + + per_page: int + """Number of items per page (1-100, default 20)""" diff --git a/src/cloudflare/types/zero_trust/cws/policy_set_update_params.py b/src/cloudflare/types/zero_trust/cws/policy_set_update_params.py new file mode 100644 index 00000000000..86f59b4d6fb --- /dev/null +++ b/src/cloudflare/types/zero_trust/cws/policy_set_update_params.py @@ -0,0 +1,51 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Dict, Iterable, Optional +from typing_extensions import Required, TypedDict + +from ...._types import SequenceNotStr + +__all__ = ["PolicySetUpdateParams", "Policy"] + + +class PolicySetUpdateParams(TypedDict, total=False): + account_id: Required[str] + """Cloudflare account ID (32-character hexadecimal string)""" + + name: Required[str] + """Name of the policy set""" + + policies: Required[Optional[Iterable[Policy]]] + """Replacement set of policies with per-membership enforcement mode""" + + description: str + """Optional free-form description.""" + + exclude_workload_ids: Optional[SequenceNotStr[str]] + """Replacement set of excluded workload IDs. Exclusions take precedence.""" + + include_workload_ids: Optional[SequenceNotStr[str]] + """Replacement set of included workload IDs. + + Empty or omitted includes all requests before exclusions. + """ + + tags: Dict[str, str] + """Replacement tag set. + + Omit or use {} to clear. Keys are limited to 256 UTF-8 bytes and values to 1024 + UTF-8 bytes. + """ + + +class Policy(TypedDict, total=False): + policy_id: Required[str] + """ID of the member policy""" + + enforce: bool + """Whether this policy should enforce when it matches. + + Defaults to true; false keeps the policy attached for non-enforcing evaluation. + """ diff --git a/src/cloudflare/types/zero_trust/cws/policy_update_params.py b/src/cloudflare/types/zero_trust/cws/policy_update_params.py new file mode 100644 index 00000000000..f791f70e458 --- /dev/null +++ b/src/cloudflare/types/zero_trust/cws/policy_update_params.py @@ -0,0 +1,44 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Dict +from typing_extensions import Required, TypedDict + +__all__ = ["PolicyUpdateParams"] + + +class PolicyUpdateParams(TypedDict, total=False): + account_id: Required[str] + """Cloudflare account ID (32-character hexadecimal string)""" + + entrypoint: Required[str] + """Non-function rule declared in rego_source. + + Evaluation uses data... + """ + + filter: Required[str] + """Filter expression that determines whether this policy applies. + + Maximum 4096 UTF-8 bytes. + """ + + name: Required[str] + """Name of the policy""" + + rego_source: Required[str] + """ + Inline Rego source with a package beginning with "policy." Maximum 16384 UTF-8 + bytes. + """ + + description: str + """Optional free-form description.""" + + tags: Dict[str, str] + """Replacement tag set. + + Omit or use {} to clear. Keys are limited to 256 UTF-8 bytes and values to 1024 + UTF-8 bytes. + """ diff --git a/src/cloudflare/types/zero_trust/cws/rego_metadata.py b/src/cloudflare/types/zero_trust/cws/rego_metadata.py new file mode 100644 index 00000000000..b3d923140e2 --- /dev/null +++ b/src/cloudflare/types/zero_trust/cws/rego_metadata.py @@ -0,0 +1,27 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from datetime import datetime + +from ...._models import BaseModel + +__all__ = ["RegoMetadata"] + + +class RegoMetadata(BaseModel): + id: str + """Server-assigned UUID""" + + created_at: datetime + + data: object + + import_path: str + """ + Unique Rego import path in the form metadata., with one alphanumeric or + underscore segment. Reference it as data.. + """ + + name: str + """Human-readable name; unique per account""" + + updated_at: datetime diff --git a/src/cloudflare/types/zero_trust/cws/rego_metadata_create_params.py b/src/cloudflare/types/zero_trust/cws/rego_metadata_create_params.py new file mode 100644 index 00000000000..4b1eca289d7 --- /dev/null +++ b/src/cloudflare/types/zero_trust/cws/rego_metadata_create_params.py @@ -0,0 +1,23 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Required, TypedDict + +__all__ = ["RegoMetadataCreateParams"] + + +class RegoMetadataCreateParams(TypedDict, total=False): + account_id: Required[str] + """Cloudflare account ID (32-character hexadecimal string)""" + + data: Required[object] + + import_path: Required[str] + """ + Unique Rego import path in the form metadata., with one alphanumeric or + underscore segment. Reference it as data.. + """ + + name: Required[str] + """Name of the rego metadata document (unique per account)""" diff --git a/src/cloudflare/types/zero_trust/cws/rego_metadata_delete_response.py b/src/cloudflare/types/zero_trust/cws/rego_metadata_delete_response.py new file mode 100644 index 00000000000..b33c7718a7d --- /dev/null +++ b/src/cloudflare/types/zero_trust/cws/rego_metadata_delete_response.py @@ -0,0 +1,9 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from ...._models import BaseModel + +__all__ = ["RegoMetadataDeleteResponse"] + + +class RegoMetadataDeleteResponse(BaseModel): + id: str diff --git a/src/cloudflare/types/zero_trust/cws/rego_metadata_list_params.py b/src/cloudflare/types/zero_trust/cws/rego_metadata_list_params.py new file mode 100644 index 00000000000..9ab29627bca --- /dev/null +++ b/src/cloudflare/types/zero_trust/cws/rego_metadata_list_params.py @@ -0,0 +1,30 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal, Required, TypedDict + +__all__ = ["RegoMetadataListParams"] + + +class RegoMetadataListParams(TypedDict, total=False): + account_id: Required[str] + """Cloudflare account ID (32-character hexadecimal string)""" + + cursor: str + """Pagination cursor from previous response""" + + direction: Literal["asc", "desc"] + """Sort direction (default: asc)""" + + import_path: str + """Filter by import path (case-sensitive literal substring match)""" + + name: str + """Filter by rego metadata name (case-insensitive substring match)""" + + order: Literal["name", "created_at", "updated_at"] + """Field to order results by (default: created_at)""" + + per_page: int + """Number of items per page (1-100, default 20)""" diff --git a/src/cloudflare/types/zero_trust/cws/rego_metadata_update_params.py b/src/cloudflare/types/zero_trust/cws/rego_metadata_update_params.py new file mode 100644 index 00000000000..5726e9e0ae4 --- /dev/null +++ b/src/cloudflare/types/zero_trust/cws/rego_metadata_update_params.py @@ -0,0 +1,23 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Required, TypedDict + +__all__ = ["RegoMetadataUpdateParams"] + + +class RegoMetadataUpdateParams(TypedDict, total=False): + account_id: Required[str] + """Cloudflare account ID (32-character hexadecimal string)""" + + data: Required[object] + + import_path: Required[str] + """ + Unique Rego import path in the form metadata., with one alphanumeric or + underscore segment. Reference it as data.. + """ + + name: Required[str] + """Name of the rego metadata document (unique per account)""" diff --git a/src/cloudflare/types/zero_trust/cws/rego_module.py b/src/cloudflare/types/zero_trust/cws/rego_module.py new file mode 100644 index 00000000000..edeed406eea --- /dev/null +++ b/src/cloudflare/types/zero_trust/cws/rego_module.py @@ -0,0 +1,31 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from datetime import datetime + +from ...._models import BaseModel + +__all__ = ["RegoModule"] + + +class RegoModule(BaseModel): + id: str + """Server-assigned UUID""" + + created_at: datetime + + name: str + """Human-readable name; unique per account""" + + package_path: str + """Dotted path derived from rego_source. + + Begins with lib. and is unique per account. + """ + + rego_source: str + """ + Library Rego source with a package beginning with "lib." Maximum 16384 UTF-8 + bytes. + """ + + updated_at: datetime diff --git a/src/cloudflare/types/zero_trust/cws/rego_module_create_params.py b/src/cloudflare/types/zero_trust/cws/rego_module_create_params.py new file mode 100644 index 00000000000..13e732e0c92 --- /dev/null +++ b/src/cloudflare/types/zero_trust/cws/rego_module_create_params.py @@ -0,0 +1,21 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Required, TypedDict + +__all__ = ["RegoModuleCreateParams"] + + +class RegoModuleCreateParams(TypedDict, total=False): + account_id: Required[str] + """Cloudflare account ID (32-character hexadecimal string)""" + + name: Required[str] + """Name of the Rego module (unique per account)""" + + rego_source: Required[str] + """ + Library Rego source with a package beginning with "lib." Maximum 16384 UTF-8 + bytes. + """ diff --git a/src/cloudflare/types/zero_trust/cws/rego_module_delete_response.py b/src/cloudflare/types/zero_trust/cws/rego_module_delete_response.py new file mode 100644 index 00000000000..04a395832b1 --- /dev/null +++ b/src/cloudflare/types/zero_trust/cws/rego_module_delete_response.py @@ -0,0 +1,9 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from ...._models import BaseModel + +__all__ = ["RegoModuleDeleteResponse"] + + +class RegoModuleDeleteResponse(BaseModel): + id: str diff --git a/src/cloudflare/types/zero_trust/cws/rego_module_list_params.py b/src/cloudflare/types/zero_trust/cws/rego_module_list_params.py new file mode 100644 index 00000000000..88b08b76435 --- /dev/null +++ b/src/cloudflare/types/zero_trust/cws/rego_module_list_params.py @@ -0,0 +1,30 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal, Required, TypedDict + +__all__ = ["RegoModuleListParams"] + + +class RegoModuleListParams(TypedDict, total=False): + account_id: Required[str] + """Cloudflare account ID (32-character hexadecimal string)""" + + cursor: str + """Pagination cursor from previous response""" + + direction: Literal["asc", "desc"] + """Sort direction (default: asc)""" + + name: str + """Filter by Rego module name (case-insensitive substring match)""" + + order: Literal["name", "created_at", "updated_at"] + """Field to order results by (default: created_at)""" + + package_path: str + """Filter by package path (case-sensitive literal substring match)""" + + per_page: int + """Number of items per page (1-100, default 20)""" diff --git a/src/cloudflare/types/zero_trust/cws/rego_module_update_params.py b/src/cloudflare/types/zero_trust/cws/rego_module_update_params.py new file mode 100644 index 00000000000..4b1c4ed4efa --- /dev/null +++ b/src/cloudflare/types/zero_trust/cws/rego_module_update_params.py @@ -0,0 +1,21 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Required, TypedDict + +__all__ = ["RegoModuleUpdateParams"] + + +class RegoModuleUpdateParams(TypedDict, total=False): + account_id: Required[str] + """Cloudflare account ID (32-character hexadecimal string)""" + + name: Required[str] + """Name of the Rego module (unique per account)""" + + rego_source: Required[str] + """ + Library Rego source with a package beginning with "lib." Maximum 16384 UTF-8 + bytes. + """ diff --git a/src/cloudflare/types/zero_trust/cws/tenant_structure.py b/src/cloudflare/types/zero_trust/cws/tenant_structure.py new file mode 100644 index 00000000000..7699f4ab7fb --- /dev/null +++ b/src/cloudflare/types/zero_trust/cws/tenant_structure.py @@ -0,0 +1,33 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional +from datetime import datetime +from typing_extensions import Literal + +from ...._models import BaseModel + +__all__ = ["TenantStructure"] + + +class TenantStructure(BaseModel): + id: str + """Server-assigned UUID""" + + application: Literal["aws", "cloudflare"] + """Platform this structure models. + + Immutable after creation; determines valid node kinds and identifier formats. + """ + + created_at: datetime + + name: str + """Human-readable name; unique per account""" + + updated_at: datetime + + import_path: Optional[str] = None + """Optional unique Rego mount path in the form tenant... + + The application segment must match application; omitted when unmounted. + """ diff --git a/src/cloudflare/types/zero_trust/cws/tenant_structure_create_params.py b/src/cloudflare/types/zero_trust/cws/tenant_structure_create_params.py new file mode 100644 index 00000000000..7cca925e5d4 --- /dev/null +++ b/src/cloudflare/types/zero_trust/cws/tenant_structure_create_params.py @@ -0,0 +1,24 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal, Required, TypedDict + +__all__ = ["TenantStructureCreateParams"] + + +class TenantStructureCreateParams(TypedDict, total=False): + account_id: Required[str] + """Cloudflare account ID (32-character hexadecimal string)""" + + application: Required[Literal["aws", "cloudflare"]] + """Platform this structure models. Immutable after creation.""" + + name: Required[str] + """Human-readable name; unique per account""" + + import_path: str + """ + Optional unique Rego mount path in the form tenant..; + application must match. Omit to leave unmounted. + """ diff --git a/src/cloudflare/types/zero_trust/cws/tenant_structure_delete_response.py b/src/cloudflare/types/zero_trust/cws/tenant_structure_delete_response.py new file mode 100644 index 00000000000..53dc0e4a17f --- /dev/null +++ b/src/cloudflare/types/zero_trust/cws/tenant_structure_delete_response.py @@ -0,0 +1,9 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from ...._models import BaseModel + +__all__ = ["TenantStructureDeleteResponse"] + + +class TenantStructureDeleteResponse(BaseModel): + id: str diff --git a/src/cloudflare/types/zero_trust/cws/tenant_structure_list_params.py b/src/cloudflare/types/zero_trust/cws/tenant_structure_list_params.py new file mode 100644 index 00000000000..dc2a3b263fd --- /dev/null +++ b/src/cloudflare/types/zero_trust/cws/tenant_structure_list_params.py @@ -0,0 +1,30 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal, Required, TypedDict + +__all__ = ["TenantStructureListParams"] + + +class TenantStructureListParams(TypedDict, total=False): + account_id: Required[str] + """Cloudflare account ID (32-character hexadecimal string)""" + + cursor: str + """Pagination cursor from previous response""" + + direction: Literal["asc", "desc"] + """Sort direction (default: asc)""" + + import_path: str + """Filter by import path (case-sensitive literal substring match)""" + + name: str + """Filter by tenant structure name (case-insensitive substring match)""" + + order: Literal["name", "created_at", "updated_at"] + """Field to order results by (default: created_at)""" + + per_page: int + """Number of items per page (1-100, default 20)""" diff --git a/src/cloudflare/types/zero_trust/cws/tenant_structure_update_params.py b/src/cloudflare/types/zero_trust/cws/tenant_structure_update_params.py new file mode 100644 index 00000000000..3488f86a9f5 --- /dev/null +++ b/src/cloudflare/types/zero_trust/cws/tenant_structure_update_params.py @@ -0,0 +1,24 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal, Required, TypedDict + +__all__ = ["TenantStructureUpdateParams"] + + +class TenantStructureUpdateParams(TypedDict, total=False): + account_id: Required[str] + """Cloudflare account ID (32-character hexadecimal string)""" + + application: Required[Literal["aws", "cloudflare"]] + """Platform this structure models. Must match the existing value.""" + + name: Required[str] + """Human-readable name; unique per account""" + + import_path: str + """ + Optional unique Rego mount path in the form tenant..; + application must match. Omit to clear. + """ diff --git a/src/cloudflare/types/zero_trust/cws/tenant_structures/__init__.py b/src/cloudflare/types/zero_trust/cws/tenant_structures/__init__.py new file mode 100644 index 00000000000..4dbf149d431 --- /dev/null +++ b/src/cloudflare/types/zero_trust/cws/tenant_structures/__init__.py @@ -0,0 +1,11 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from .node_list_params import NodeListParams as NodeListParams +from .node_batch_params import NodeBatchParams as NodeBatchParams +from .node_create_params import NodeCreateParams as NodeCreateParams +from .node_update_params import NodeUpdateParams as NodeUpdateParams +from .node_batch_response import NodeBatchResponse as NodeBatchResponse +from .node_delete_response import NodeDeleteResponse as NodeDeleteResponse +from .tenant_structure_node import TenantStructureNode as TenantStructureNode diff --git a/src/cloudflare/types/zero_trust/cws/tenant_structures/node_batch_params.py b/src/cloudflare/types/zero_trust/cws/tenant_structures/node_batch_params.py new file mode 100644 index 00000000000..15232c67ef9 --- /dev/null +++ b/src/cloudflare/types/zero_trust/cws/tenant_structures/node_batch_params.py @@ -0,0 +1,68 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Iterable +from typing_extensions import Required, TypedDict + +__all__ = ["NodeBatchParams", "Create", "Delete", "Update"] + + +class NodeBatchParams(TypedDict, total=False): + account_id: Required[str] + """Cloudflare account ID (32-character hexadecimal string)""" + + creates: Required[Iterable[Create]] + """Nodes to create; parents may be created elsewhere in this request""" + + deletes: Required[Iterable[Delete]] + """ + Nodes to delete; every descendant that will not be reparented must also be + deleted + """ + + updates: Required[Iterable[Update]] + """Nodes whose mutable fields should be fully replaced""" + + +class Create(TypedDict, total=False): + native_id: Required[str] + """ + Cloud-native identifier of this node, unique within the structure; the + parent-reference target. Shape depends on the structure's application. Immutable + after create. + """ + + node_kind: Required[str] + """Position in the tree. + + Legal values depend on the structure's application (aws: root/ou/account; + cloudflare: org/account/zone). At most one root per structure. Immutable after + create. + """ + + name: str + """Display name (e.g. an OU or account name), mutable. Optional; empty by default.""" + + parent: str + """Native ID of this node's parent. + + Required for non-root nodes and omitted for the root. The parent must be in the + same structure and able to contain this node kind. + """ + + +class Delete(TypedDict, total=False): + id: Required[str] + """ID of the node to delete""" + + +class Update(TypedDict, total=False): + id: Required[str] + """ID of the node to update""" + + name: str + """Full replacement display name""" + + parent: str + """Full replacement parent native ID; omit for the root""" diff --git a/src/cloudflare/types/zero_trust/cws/tenant_structures/node_batch_response.py b/src/cloudflare/types/zero_trust/cws/tenant_structures/node_batch_response.py new file mode 100644 index 00000000000..60d6cac646e --- /dev/null +++ b/src/cloudflare/types/zero_trust/cws/tenant_structures/node_batch_response.py @@ -0,0 +1,20 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List + +from ....._models import BaseModel +from .tenant_structure_node import TenantStructureNode + +__all__ = ["NodeBatchResponse", "Deleted"] + + +class Deleted(BaseModel): + id: str + + +class NodeBatchResponse(BaseModel): + created: List[TenantStructureNode] + + deleted: List[Deleted] + + updated: List[TenantStructureNode] diff --git a/src/cloudflare/types/zero_trust/cws/tenant_structures/node_create_params.py b/src/cloudflare/types/zero_trust/cws/tenant_structures/node_create_params.py new file mode 100644 index 00000000000..2932a72b01a --- /dev/null +++ b/src/cloudflare/types/zero_trust/cws/tenant_structures/node_create_params.py @@ -0,0 +1,37 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Required, TypedDict + +__all__ = ["NodeCreateParams"] + + +class NodeCreateParams(TypedDict, total=False): + account_id: Required[str] + """Cloudflare account ID (32-character hexadecimal string)""" + + native_id: Required[str] + """ + Cloud-native identifier of this node, unique within the structure; the + parent-reference target. Shape depends on the structure's application. Immutable + after create. + """ + + node_kind: Required[str] + """Position in the tree. + + Legal values depend on the structure's application (aws: root/ou/account; + cloudflare: org/account/zone). At most one root per structure. Immutable after + create. + """ + + name: str + """Display name (e.g. an OU or account name), mutable. Optional; empty by default.""" + + parent: str + """Native ID of this node's parent. + + Required for non-root nodes and omitted for the root. The parent must be in the + same structure and able to contain this node kind. + """ diff --git a/src/cloudflare/types/zero_trust/cws/tenant_structures/node_delete_response.py b/src/cloudflare/types/zero_trust/cws/tenant_structures/node_delete_response.py new file mode 100644 index 00000000000..8e4a7901b15 --- /dev/null +++ b/src/cloudflare/types/zero_trust/cws/tenant_structures/node_delete_response.py @@ -0,0 +1,9 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from ....._models import BaseModel + +__all__ = ["NodeDeleteResponse"] + + +class NodeDeleteResponse(BaseModel): + id: str diff --git a/src/cloudflare/types/zero_trust/cws/tenant_structures/node_list_params.py b/src/cloudflare/types/zero_trust/cws/tenant_structures/node_list_params.py new file mode 100644 index 00000000000..b66749a4a5f --- /dev/null +++ b/src/cloudflare/types/zero_trust/cws/tenant_structures/node_list_params.py @@ -0,0 +1,36 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal, Required, TypedDict + +__all__ = ["NodeListParams"] + + +class NodeListParams(TypedDict, total=False): + account_id: Required[str] + """Cloudflare account ID (32-character hexadecimal string)""" + + cursor: str + """Pagination cursor from previous response""" + + direction: Literal["asc", "desc"] + """Sort direction (default: asc)""" + + name: str + """Filter by node name (case-insensitive substring match)""" + + native_id: str + """Filter by exact cloud-native identifier""" + + node_kind: str + """Filter by exact node kind""" + + order: Literal["name", "created_at", "updated_at"] + """Field to order results by (default: created_at)""" + + parent: str + """Filter by exact parent native ID""" + + per_page: int + """Number of items per page (1-100, default 20)""" diff --git a/src/cloudflare/types/zero_trust/cws/tenant_structures/node_update_params.py b/src/cloudflare/types/zero_trust/cws/tenant_structures/node_update_params.py new file mode 100644 index 00000000000..04cac57aa20 --- /dev/null +++ b/src/cloudflare/types/zero_trust/cws/tenant_structures/node_update_params.py @@ -0,0 +1,40 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Required, TypedDict + +__all__ = ["NodeUpdateParams"] + + +class NodeUpdateParams(TypedDict, total=False): + account_id: Required[str] + """Cloudflare account ID (32-character hexadecimal string)""" + + structure_id: Required[str] + """ID of the parent tenant structure""" + + native_id: Required[str] + """ + Cloud-native identifier of this node, unique within the structure; the + parent-reference target. Shape depends on the structure's application. Immutable + after create. + """ + + node_kind: Required[str] + """Position in the tree. + + Legal values depend on the structure's application (aws: root/ou/account; + cloudflare: org/account/zone). At most one root per structure. Immutable after + create. + """ + + name: str + """Display name (e.g. an OU or account name), mutable. Optional; empty by default.""" + + parent: str + """Native ID of this node's parent. + + Required for non-root nodes and omitted for the root. The parent must be in the + same structure and able to contain this node kind. + """ diff --git a/src/cloudflare/types/zero_trust/cws/tenant_structures/tenant_structure_node.py b/src/cloudflare/types/zero_trust/cws/tenant_structures/tenant_structure_node.py new file mode 100644 index 00000000000..323f1001c1d --- /dev/null +++ b/src/cloudflare/types/zero_trust/cws/tenant_structures/tenant_structure_node.py @@ -0,0 +1,42 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional +from datetime import datetime + +from ....._models import BaseModel + +__all__ = ["TenantStructureNode"] + + +class TenantStructureNode(BaseModel): + id: str + """Server-assigned UUID""" + + created_at: datetime + + native_id: str + """ + Cloud-native identifier of this node, unique within the structure; the + parent-reference target. Shape depends on the structure's application. Immutable + after create. + """ + + node_kind: str + """Position in the tree. + + Legal values depend on the structure's application (aws: root/ou/account; + cloudflare: org/account/zone). At most one root per structure. Immutable after + create. + """ + + updated_at: datetime + + name: Optional[str] = None + """Display name (e.g. an OU or account name), mutable. Optional; empty by default.""" + + parent: Optional[str] = None + """Native ID of this node's parent. + + Required for non-root nodes and omitted for the root. The parent must be in the + same structure and able to contain this node kind. + """ diff --git a/src/cloudflare/types/zero_trust/cws/workload.py b/src/cloudflare/types/zero_trust/cws/workload.py new file mode 100644 index 00000000000..13557cd2cf3 --- /dev/null +++ b/src/cloudflare/types/zero_trust/cws/workload.py @@ -0,0 +1,32 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Dict, Optional +from datetime import datetime + +from ...._models import BaseModel + +__all__ = ["Workload"] + + +class Workload(BaseModel): + id: str + """Server-assigned UUID""" + + created_at: datetime + + filter: str + """Filter expression selecting the requests this workload matches. + + Maximum 4096 UTF-8 bytes. + """ + + name: str + """Human-readable handle; unique per account.""" + + tags: Dict[str, str] + """Tags attached to this workload""" + + updated_at: datetime + + description: Optional[str] = None + """Optional free-form description.""" diff --git a/src/cloudflare/types/zero_trust/cws/workload_create_params.py b/src/cloudflare/types/zero_trust/cws/workload_create_params.py new file mode 100644 index 00000000000..e65f6158ad1 --- /dev/null +++ b/src/cloudflare/types/zero_trust/cws/workload_create_params.py @@ -0,0 +1,31 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Dict +from typing_extensions import Required, TypedDict + +__all__ = ["WorkloadCreateParams"] + + +class WorkloadCreateParams(TypedDict, total=False): + account_id: Required[str] + """Cloudflare account ID (32-character hexadecimal string)""" + + filter: Required[str] + """Filter expression selecting the requests this workload matches. + + Maximum 4096 UTF-8 bytes. + """ + + name: Required[str] + """Human-readable handle; unique per account.""" + + description: str + """Optional free-form description.""" + + tags: Dict[str, str] + """Tags to attach. + + Keys are limited to 256 UTF-8 bytes and values to 1024 UTF-8 bytes. + """ diff --git a/src/cloudflare/types/zero_trust/cws/workload_delete_response.py b/src/cloudflare/types/zero_trust/cws/workload_delete_response.py new file mode 100644 index 00000000000..a5af4c3ff2a --- /dev/null +++ b/src/cloudflare/types/zero_trust/cws/workload_delete_response.py @@ -0,0 +1,9 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from ...._models import BaseModel + +__all__ = ["WorkloadDeleteResponse"] + + +class WorkloadDeleteResponse(BaseModel): + id: str diff --git a/src/cloudflare/types/zero_trust/cws/workload_list_params.py b/src/cloudflare/types/zero_trust/cws/workload_list_params.py new file mode 100644 index 00000000000..9e13eb7a049 --- /dev/null +++ b/src/cloudflare/types/zero_trust/cws/workload_list_params.py @@ -0,0 +1,30 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal, Required, TypedDict + +__all__ = ["WorkloadListParams"] + + +class WorkloadListParams(TypedDict, total=False): + account_id: Required[str] + """Cloudflare account ID (32-character hexadecimal string)""" + + cursor: str + """Pagination cursor from previous response""" + + direction: Literal["asc", "desc"] + """Sort direction (default: asc)""" + + name: str + """Filter by workload name (case-insensitive substring match)""" + + order: Literal["name", "created_at", "updated_at"] + """Field to order results by (default: created_at)""" + + per_page: int + """Number of items per page (1-100, default 20)""" + + policy_set_id: str + """Filter to workloads attached to this policy set""" diff --git a/src/cloudflare/types/zero_trust/cws/workload_update_params.py b/src/cloudflare/types/zero_trust/cws/workload_update_params.py new file mode 100644 index 00000000000..10991455db5 --- /dev/null +++ b/src/cloudflare/types/zero_trust/cws/workload_update_params.py @@ -0,0 +1,32 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Dict +from typing_extensions import Required, TypedDict + +__all__ = ["WorkloadUpdateParams"] + + +class WorkloadUpdateParams(TypedDict, total=False): + account_id: Required[str] + """Cloudflare account ID (32-character hexadecimal string)""" + + filter: Required[str] + """Filter expression selecting the requests this workload matches. + + Maximum 4096 UTF-8 bytes. + """ + + name: Required[str] + """Human-readable handle; unique per account.""" + + description: str + """Optional free-form description.""" + + tags: Dict[str, str] + """Replacement tag set. + + Omit or use {} to clear. Keys are limited to 256 UTF-8 bytes and values to 1024 + UTF-8 bytes. + """ diff --git a/src/cloudflare/types/zero_trust/devices/device_get_response.py b/src/cloudflare/types/zero_trust/devices/device_get_response.py index 4d1482fb4b1..14a200b9459 100644 --- a/src/cloudflare/types/zero_trust/devices/device_get_response.py +++ b/src/cloudflare/types/zero_trust/devices/device_get_response.py @@ -103,6 +103,12 @@ class DeviceGetResponse(BaseModel): model: Optional[str] = None """The model name of the device.""" + multiuser: Optional[bool] = None + """ + True if this device is in + [multi-user mode](https://developers.cloudflare.com/cloudflare-one/connections/connect-devices/warp/deployment/mdm-deployment/windows-multiuser/). + """ + os_version: Optional[str] = None """The device operating system version number.""" diff --git a/src/cloudflare/types/zero_trust/devices/device_list_response.py b/src/cloudflare/types/zero_trust/devices/device_list_response.py index e22f8f7d830..8d6b2981d8a 100644 --- a/src/cloudflare/types/zero_trust/devices/device_list_response.py +++ b/src/cloudflare/types/zero_trust/devices/device_list_response.py @@ -103,6 +103,12 @@ class DeviceListResponse(BaseModel): model: Optional[str] = None """The model name of the device.""" + multiuser: Optional[bool] = None + """ + True if this device is in + [multi-user mode](https://developers.cloudflare.com/cloudflare-one/connections/connect-devices/warp/deployment/mdm-deployment/windows-multiuser/). + """ + os_version: Optional[str] = None """The device operating system version number.""" diff --git a/src/cloudflare/types/zero_trust/devices/policies/custom_create_params.py b/src/cloudflare/types/zero_trust/devices/policies/custom_create_params.py index e2d27fd594c..8a2f9671438 100644 --- a/src/cloudflare/types/zero_trust/devices/policies/custom_create_params.py +++ b/src/cloudflare/types/zero_trust/devices/policies/custom_create_params.py @@ -71,6 +71,13 @@ class CustomCreateParams(TypedDict, total=False): Suffixes are evaluated in order. Use an empty array to clear. """ + enable_device_credential_authentication: bool + """ + Determines whether the WARP client can silently reauthenticate the user with + device credentials (Microsoft Entra) instead of prompting for browser-based + reauthentication. + """ + enabled: bool """Whether the policy will be applied to matching devices.""" @@ -117,7 +124,7 @@ class CustomCreateParams(TypedDict, total=False): Available values: "identity.email", "identity.groups.id", "identity.groups.name", "identity.groups.email", "identity.service_token_uuid", - "identity.saml_attributes", "network", "os.name", "os.version". + "identity.saml_attributes", "network", "os.name", "os.version", "device.tags". """ precedence: float @@ -213,6 +220,12 @@ class GlobalAcceleration(TypedDict, total=False): Either wireguard_endpoints or masque_endpoints must be provided. """ + allow_manual_override: bool + """ + Whether WARP users may manually override the automatic Global Acceleration + decision. Defaults to true when not provided. + """ + autoswitch: bool """Automatically switch Global Acceleration regions based on device location. diff --git a/src/cloudflare/types/zero_trust/devices/policies/custom_edit_params.py b/src/cloudflare/types/zero_trust/devices/policies/custom_edit_params.py index bf3d7365eee..dec0a13e3c0 100644 --- a/src/cloudflare/types/zero_trust/devices/policies/custom_edit_params.py +++ b/src/cloudflare/types/zero_trust/devices/policies/custom_edit_params.py @@ -68,6 +68,13 @@ class CustomEditParams(TypedDict, total=False): Suffixes are evaluated in order. Use an empty array to clear. """ + enable_device_credential_authentication: bool + """ + Determines whether the WARP client can silently reauthenticate the user with + device credentials (Microsoft Entra) instead of prompting for browser-based + reauthentication. + """ + enabled: bool """Whether the policy will be applied to matching devices.""" @@ -114,7 +121,7 @@ class CustomEditParams(TypedDict, total=False): Available values: "identity.email", "identity.groups.id", "identity.groups.name", "identity.groups.email", "identity.service_token_uuid", - "identity.saml_attributes", "network", "os.name", "os.version". + "identity.saml_attributes", "network", "os.name", "os.version", "device.tags". """ name: str @@ -207,6 +214,12 @@ class GlobalAcceleration(TypedDict, total=False): Either wireguard_endpoints or masque_endpoints must be provided. """ + allow_manual_override: bool + """ + Whether WARP users may manually override the automatic Global Acceleration + decision. Defaults to true when not provided. + """ + autoswitch: bool """Automatically switch Global Acceleration regions based on device location. diff --git a/src/cloudflare/types/zero_trust/devices/policies/default_edit_params.py b/src/cloudflare/types/zero_trust/devices/policies/default_edit_params.py index 9c80d3c09b6..221801b2396 100644 --- a/src/cloudflare/types/zero_trust/devices/policies/default_edit_params.py +++ b/src/cloudflare/types/zero_trust/devices/policies/default_edit_params.py @@ -46,6 +46,13 @@ class DefaultEditParams(TypedDict, total=False): Suffixes are evaluated in order. Use an empty array to clear. """ + enable_device_credential_authentication: bool + """ + Determines whether the WARP client can silently reauthenticate the user with + device credentials (Microsoft Entra) instead of prompting for browser-based + reauthentication. + """ + exclude: Iterable[SplitTunnelExcludeParam] """List of routes excluded in the WARP client's tunnel. @@ -151,6 +158,12 @@ class GlobalAcceleration(TypedDict, total=False): Either wireguard_endpoints or masque_endpoints must be provided. """ + allow_manual_override: bool + """ + Whether WARP users may manually override the automatic Global Acceleration + decision. Defaults to true when not provided. + """ + autoswitch: bool """Automatically switch Global Acceleration regions based on device location. diff --git a/src/cloudflare/types/zero_trust/devices/policies/default_edit_response.py b/src/cloudflare/types/zero_trust/devices/policies/default_edit_response.py index ee7f41f01a1..ecafd94a689 100644 --- a/src/cloudflare/types/zero_trust/devices/policies/default_edit_response.py +++ b/src/cloudflare/types/zero_trust/devices/policies/default_edit_response.py @@ -43,6 +43,12 @@ class GlobalAcceleration(BaseModel): Either wireguard_endpoints or masque_endpoints must be provided. """ + allow_manual_override: Optional[bool] = None + """ + Whether WARP users may manually override the automatic Global Acceleration + decision. Defaults to true when not provided. + """ + autoswitch: Optional[bool] = None """Automatically switch Global Acceleration regions based on device location. @@ -106,6 +112,13 @@ class DefaultEditResponse(BaseModel): Suffixes are evaluated in order. Use an empty array to clear. """ + enable_device_credential_authentication: Optional[bool] = None + """ + Determines whether the WARP client can silently reauthenticate the user with + device credentials (Microsoft Entra) instead of prompting for browser-based + reauthentication. + """ + enabled: Optional[bool] = None """Whether the policy will be applied to matching devices.""" diff --git a/src/cloudflare/types/zero_trust/devices/policies/default_get_response.py b/src/cloudflare/types/zero_trust/devices/policies/default_get_response.py index 8b080e2dff1..6c7517a8cee 100644 --- a/src/cloudflare/types/zero_trust/devices/policies/default_get_response.py +++ b/src/cloudflare/types/zero_trust/devices/policies/default_get_response.py @@ -43,6 +43,12 @@ class GlobalAcceleration(BaseModel): Either wireguard_endpoints or masque_endpoints must be provided. """ + allow_manual_override: Optional[bool] = None + """ + Whether WARP users may manually override the automatic Global Acceleration + decision. Defaults to true when not provided. + """ + autoswitch: Optional[bool] = None """Automatically switch Global Acceleration regions based on device location. @@ -106,6 +112,13 @@ class DefaultGetResponse(BaseModel): Suffixes are evaluated in order. Use an empty array to clear. """ + enable_device_credential_authentication: Optional[bool] = None + """ + Determines whether the WARP client can silently reauthenticate the user with + device credentials (Microsoft Entra) instead of prompting for browser-based + reauthentication. + """ + enabled: Optional[bool] = None """Whether the policy will be applied to matching devices.""" diff --git a/src/cloudflare/types/zero_trust/devices/settings_policy.py b/src/cloudflare/types/zero_trust/devices/settings_policy.py index 53f64e549ff..8bde10075b8 100644 --- a/src/cloudflare/types/zero_trust/devices/settings_policy.py +++ b/src/cloudflare/types/zero_trust/devices/settings_policy.py @@ -64,6 +64,12 @@ class GlobalAcceleration(BaseModel): Either wireguard_endpoints or masque_endpoints must be provided. """ + allow_manual_override: Optional[bool] = None + """ + Whether WARP users may manually override the automatic Global Acceleration + decision. Defaults to true when not provided. + """ + autoswitch: Optional[bool] = None """Automatically switch Global Acceleration regions based on device location. @@ -147,6 +153,13 @@ class SettingsPolicy(BaseModel): Suffixes are evaluated in order. Use an empty array to clear. """ + enable_device_credential_authentication: Optional[bool] = None + """ + Determines whether the WARP client can silently reauthenticate the user with + device credentials (Microsoft Entra) instead of prompting for browser-based + reauthentication. + """ + enabled: Optional[bool] = None """Whether the policy will be applied to matching devices.""" @@ -191,7 +204,7 @@ class SettingsPolicy(BaseModel): Available values: "identity.email", "identity.groups.id", "identity.groups.name", "identity.groups.email", "identity.service_token_uuid", - "identity.saml_attributes", "network", "os.name", "os.version". + "identity.saml_attributes", "network", "os.name", "os.version", "device.tags". """ name: Optional[str] = None diff --git a/src/cloudflare/types/zero_trust/dlp/__init__.py b/src/cloudflare/types/zero_trust/dlp/__init__.py index 928fddeeca4..289f00b1ddf 100644 --- a/src/cloudflare/types/zero_trust/dlp/__init__.py +++ b/src/cloudflare/types/zero_trust/dlp/__init__.py @@ -4,8 +4,11 @@ from .dataset import Dataset as Dataset from .profile import Profile as Profile +from .validator import Validator as Validator +from .references import References as References from .dlp_settings import DLPSettings as DLPSettings from .dataset_array import DatasetArray as DatasetArray +from .validator_array import ValidatorArray as ValidatorArray from .dataset_creation import DatasetCreation as DatasetCreation from .context_awareness import ContextAwareness as ContextAwareness from .entry_get_response import EntryGetResponse as EntryGetResponse @@ -22,6 +25,7 @@ from .entry_create_response import EntryCreateResponse as EntryCreateResponse from .entry_update_response import EntryUpdateResponse as EntryUpdateResponse from .setting_update_params import SettingUpdateParams as SettingUpdateParams +from .validator_list_params import ValidatorListParams as ValidatorListParams from .context_awareness_param import ContextAwarenessParam as ContextAwarenessParam from .data_class_get_response import DataClassGetResponse as DataClassGetResponse from .pattern_validate_params import PatternValidateParams as PatternValidateParams diff --git a/src/cloudflare/types/zero_trust/dlp/entries/custom_create_params.py b/src/cloudflare/types/zero_trust/dlp/entries/custom_create_params.py index 8700d3d8469..59f8f353ae7 100644 --- a/src/cloudflare/types/zero_trust/dlp/entries/custom_create_params.py +++ b/src/cloudflare/types/zero_trust/dlp/entries/custom_create_params.py @@ -5,6 +5,7 @@ from typing import Optional from typing_extensions import Required, TypedDict +from ....._types import SequenceNotStr from ..profiles.pattern_param import PatternParam __all__ = ["CustomCreateParams"] @@ -22,3 +23,6 @@ class CustomCreateParams(TypedDict, total=False): description: Optional[str] profile_id: str + + validator_ids: SequenceNotStr[str] + """Validators the new entry should reference, by id, at most 10.""" diff --git a/src/cloudflare/types/zero_trust/dlp/entries/custom_create_response.py b/src/cloudflare/types/zero_trust/dlp/entries/custom_create_response.py index 8b6cbc94fbf..dc9b1ab3d81 100644 --- a/src/cloudflare/types/zero_trust/dlp/entries/custom_create_response.py +++ b/src/cloudflare/types/zero_trust/dlp/entries/custom_create_response.py @@ -1,6 +1,6 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import Optional +from typing import List, Optional from datetime import datetime from ....._models import BaseModel @@ -25,3 +25,12 @@ class CustomCreateResponse(BaseModel): description: Optional[str] = None profile_id: Optional[str] = None + + validator_ids: Optional[List[str]] = None + """Validators this entry references, by id, at most 10. + + An empty list means the entry references none. + + Returned by the entry endpoints. Not returned on entries embedded in other + responses, such as profiles. + """ diff --git a/src/cloudflare/types/zero_trust/dlp/entries/custom_get_response.py b/src/cloudflare/types/zero_trust/dlp/entries/custom_get_response.py index a745edc59c1..489fbde8ba9 100644 --- a/src/cloudflare/types/zero_trust/dlp/entries/custom_get_response.py +++ b/src/cloudflare/types/zero_trust/dlp/entries/custom_get_response.py @@ -61,6 +61,15 @@ class UnionMember0(BaseModel): upload_status: Optional[Literal["empty", "uploading", "pending", "processing", "failed", "complete"]] = None + validator_ids: Optional[List[str]] = None + """Validators this entry references, by id, at most 10. + + An empty list means the entry references none. + + Returned by the entry endpoints. Not returned on entries embedded in other + responses, such as profiles. + """ + class UnionMember1Profile(BaseModel): """Computed entry field for a profile that an entry is shared into.""" @@ -278,7 +287,7 @@ class UnionMember6(BaseModel): updated_at: datetime - word_list: object + word_list: List[str] profile_id: Optional[str] = None diff --git a/src/cloudflare/types/zero_trust/dlp/entries/custom_list_response.py b/src/cloudflare/types/zero_trust/dlp/entries/custom_list_response.py index cf653c6f0a1..dd78a279526 100644 --- a/src/cloudflare/types/zero_trust/dlp/entries/custom_list_response.py +++ b/src/cloudflare/types/zero_trust/dlp/entries/custom_list_response.py @@ -1,6 +1,6 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import Union, Optional +from typing import List, Union, Optional from datetime import datetime from typing_extensions import Literal, TypeAlias @@ -44,6 +44,15 @@ class UnionMember0(BaseModel): upload_status: Optional[Literal["empty", "uploading", "pending", "processing", "failed", "complete"]] = None + validator_ids: Optional[List[str]] = None + """Validators this entry references, by id, at most 10. + + An empty list means the entry references none. + + Returned by the entry endpoints. Not returned on entries embedded in other + responses, such as profiles. + """ + class UnionMember1(BaseModel): id: str @@ -203,7 +212,7 @@ class UnionMember6(BaseModel): updated_at: datetime - word_list: object + word_list: List[str] profile_id: Optional[str] = None diff --git a/src/cloudflare/types/zero_trust/dlp/entries/custom_update_params.py b/src/cloudflare/types/zero_trust/dlp/entries/custom_update_params.py index c6e957d80d3..c8c90aefcdb 100644 --- a/src/cloudflare/types/zero_trust/dlp/entries/custom_update_params.py +++ b/src/cloudflare/types/zero_trust/dlp/entries/custom_update_params.py @@ -5,6 +5,7 @@ from typing import Optional from typing_extensions import Required, TypedDict +from ....._types import SequenceNotStr from ..profiles.pattern_param import PatternParam __all__ = ["CustomUpdateParams"] @@ -20,3 +21,13 @@ class CustomUpdateParams(TypedDict, total=False): pattern: Required[PatternParam] description: Optional[str] + + validator_ids: SequenceNotStr[str] + """Validators this entry should reference, by id, at most 10. + + Replaces the current set. + + Optional, unlike the rest of this body: omitting it leaves the current + attachments alone, so a client that predates validators cannot detach them by + accident. Send `[]` to detach. + """ diff --git a/src/cloudflare/types/zero_trust/dlp/entries/custom_update_response.py b/src/cloudflare/types/zero_trust/dlp/entries/custom_update_response.py index 1f77d4b9b31..b5a5e34d76c 100644 --- a/src/cloudflare/types/zero_trust/dlp/entries/custom_update_response.py +++ b/src/cloudflare/types/zero_trust/dlp/entries/custom_update_response.py @@ -1,6 +1,6 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import Optional +from typing import List, Optional from datetime import datetime from ....._models import BaseModel @@ -25,3 +25,12 @@ class CustomUpdateResponse(BaseModel): description: Optional[str] = None profile_id: Optional[str] = None + + validator_ids: Optional[List[str]] = None + """Validators this entry references, by id, at most 10. + + An empty list means the entry references none. + + Returned by the entry endpoints. Not returned on entries embedded in other + responses, such as profiles. + """ diff --git a/src/cloudflare/types/zero_trust/dlp/entries/integration_get_response.py b/src/cloudflare/types/zero_trust/dlp/entries/integration_get_response.py index 7311eeb67aa..25a5a15baa5 100644 --- a/src/cloudflare/types/zero_trust/dlp/entries/integration_get_response.py +++ b/src/cloudflare/types/zero_trust/dlp/entries/integration_get_response.py @@ -61,6 +61,15 @@ class UnionMember0(BaseModel): upload_status: Optional[Literal["empty", "uploading", "pending", "processing", "failed", "complete"]] = None + validator_ids: Optional[List[str]] = None + """Validators this entry references, by id, at most 10. + + An empty list means the entry references none. + + Returned by the entry endpoints. Not returned on entries embedded in other + responses, such as profiles. + """ + class UnionMember1Profile(BaseModel): """Computed entry field for a profile that an entry is shared into.""" @@ -278,7 +287,7 @@ class UnionMember6(BaseModel): updated_at: datetime - word_list: object + word_list: List[str] profile_id: Optional[str] = None diff --git a/src/cloudflare/types/zero_trust/dlp/entries/integration_list_response.py b/src/cloudflare/types/zero_trust/dlp/entries/integration_list_response.py index 250f1d06b4f..d21faf3f955 100644 --- a/src/cloudflare/types/zero_trust/dlp/entries/integration_list_response.py +++ b/src/cloudflare/types/zero_trust/dlp/entries/integration_list_response.py @@ -1,6 +1,6 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import Union, Optional +from typing import List, Union, Optional from datetime import datetime from typing_extensions import Literal, TypeAlias @@ -44,6 +44,15 @@ class UnionMember0(BaseModel): upload_status: Optional[Literal["empty", "uploading", "pending", "processing", "failed", "complete"]] = None + validator_ids: Optional[List[str]] = None + """Validators this entry references, by id, at most 10. + + An empty list means the entry references none. + + Returned by the entry endpoints. Not returned on entries embedded in other + responses, such as profiles. + """ + class UnionMember1(BaseModel): id: str @@ -203,7 +212,7 @@ class UnionMember6(BaseModel): updated_at: datetime - word_list: object + word_list: List[str] profile_id: Optional[str] = None diff --git a/src/cloudflare/types/zero_trust/dlp/entries/predefined_get_response.py b/src/cloudflare/types/zero_trust/dlp/entries/predefined_get_response.py index b43b2e59b4a..4677ea541ac 100644 --- a/src/cloudflare/types/zero_trust/dlp/entries/predefined_get_response.py +++ b/src/cloudflare/types/zero_trust/dlp/entries/predefined_get_response.py @@ -61,6 +61,15 @@ class UnionMember0(BaseModel): upload_status: Optional[Literal["empty", "uploading", "pending", "processing", "failed", "complete"]] = None + validator_ids: Optional[List[str]] = None + """Validators this entry references, by id, at most 10. + + An empty list means the entry references none. + + Returned by the entry endpoints. Not returned on entries embedded in other + responses, such as profiles. + """ + class UnionMember1Profile(BaseModel): """Computed entry field for a profile that an entry is shared into.""" @@ -278,7 +287,7 @@ class UnionMember6(BaseModel): updated_at: datetime - word_list: object + word_list: List[str] profile_id: Optional[str] = None diff --git a/src/cloudflare/types/zero_trust/dlp/entries/predefined_list_response.py b/src/cloudflare/types/zero_trust/dlp/entries/predefined_list_response.py index e9f1f57a601..b25ba999d86 100644 --- a/src/cloudflare/types/zero_trust/dlp/entries/predefined_list_response.py +++ b/src/cloudflare/types/zero_trust/dlp/entries/predefined_list_response.py @@ -1,6 +1,6 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import Union, Optional +from typing import List, Union, Optional from datetime import datetime from typing_extensions import Literal, TypeAlias @@ -44,6 +44,15 @@ class UnionMember0(BaseModel): upload_status: Optional[Literal["empty", "uploading", "pending", "processing", "failed", "complete"]] = None + validator_ids: Optional[List[str]] = None + """Validators this entry references, by id, at most 10. + + An empty list means the entry references none. + + Returned by the entry endpoints. Not returned on entries embedded in other + responses, such as profiles. + """ + class UnionMember1(BaseModel): id: str @@ -203,7 +212,7 @@ class UnionMember6(BaseModel): updated_at: datetime - word_list: object + word_list: List[str] profile_id: Optional[str] = None diff --git a/src/cloudflare/types/zero_trust/dlp/entry_create_params.py b/src/cloudflare/types/zero_trust/dlp/entry_create_params.py index 6b6c3364021..9626eee7136 100644 --- a/src/cloudflare/types/zero_trust/dlp/entry_create_params.py +++ b/src/cloudflare/types/zero_trust/dlp/entry_create_params.py @@ -5,6 +5,7 @@ from typing import Optional from typing_extensions import Required, TypedDict +from ...._types import SequenceNotStr from .profiles.pattern_param import PatternParam __all__ = ["EntryCreateParams"] @@ -22,3 +23,6 @@ class EntryCreateParams(TypedDict, total=False): description: Optional[str] profile_id: str + + validator_ids: SequenceNotStr[str] + """Validators the new entry should reference, by id, at most 10.""" diff --git a/src/cloudflare/types/zero_trust/dlp/entry_create_response.py b/src/cloudflare/types/zero_trust/dlp/entry_create_response.py index cd3cd80dea5..1ea0bc8bc63 100644 --- a/src/cloudflare/types/zero_trust/dlp/entry_create_response.py +++ b/src/cloudflare/types/zero_trust/dlp/entry_create_response.py @@ -1,6 +1,6 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import Optional +from typing import List, Optional from datetime import datetime from ...._models import BaseModel @@ -25,3 +25,12 @@ class EntryCreateResponse(BaseModel): description: Optional[str] = None profile_id: Optional[str] = None + + validator_ids: Optional[List[str]] = None + """Validators this entry references, by id, at most 10. + + An empty list means the entry references none. + + Returned by the entry endpoints. Not returned on entries embedded in other + responses, such as profiles. + """ diff --git a/src/cloudflare/types/zero_trust/dlp/entry_get_response.py b/src/cloudflare/types/zero_trust/dlp/entry_get_response.py index 8f8633beaa9..d4831bdf5f8 100644 --- a/src/cloudflare/types/zero_trust/dlp/entry_get_response.py +++ b/src/cloudflare/types/zero_trust/dlp/entry_get_response.py @@ -61,6 +61,15 @@ class UnionMember0(BaseModel): upload_status: Optional[Literal["empty", "uploading", "pending", "processing", "failed", "complete"]] = None + validator_ids: Optional[List[str]] = None + """Validators this entry references, by id, at most 10. + + An empty list means the entry references none. + + Returned by the entry endpoints. Not returned on entries embedded in other + responses, such as profiles. + """ + class UnionMember1Profile(BaseModel): """Computed entry field for a profile that an entry is shared into.""" @@ -278,7 +287,7 @@ class UnionMember6(BaseModel): updated_at: datetime - word_list: object + word_list: List[str] profile_id: Optional[str] = None diff --git a/src/cloudflare/types/zero_trust/dlp/entry_list_response.py b/src/cloudflare/types/zero_trust/dlp/entry_list_response.py index 88963de58c0..86e20b2a43b 100644 --- a/src/cloudflare/types/zero_trust/dlp/entry_list_response.py +++ b/src/cloudflare/types/zero_trust/dlp/entry_list_response.py @@ -1,6 +1,6 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import Union, Optional +from typing import List, Union, Optional from datetime import datetime from typing_extensions import Literal, TypeAlias @@ -44,6 +44,15 @@ class UnionMember0(BaseModel): upload_status: Optional[Literal["empty", "uploading", "pending", "processing", "failed", "complete"]] = None + validator_ids: Optional[List[str]] = None + """Validators this entry references, by id, at most 10. + + An empty list means the entry references none. + + Returned by the entry endpoints. Not returned on entries embedded in other + responses, such as profiles. + """ + class UnionMember1(BaseModel): id: str @@ -203,7 +212,7 @@ class UnionMember6(BaseModel): updated_at: datetime - word_list: object + word_list: List[str] profile_id: Optional[str] = None diff --git a/src/cloudflare/types/zero_trust/dlp/entry_update_params.py b/src/cloudflare/types/zero_trust/dlp/entry_update_params.py index 04a45767afe..51701815e18 100644 --- a/src/cloudflare/types/zero_trust/dlp/entry_update_params.py +++ b/src/cloudflare/types/zero_trust/dlp/entry_update_params.py @@ -5,6 +5,7 @@ from typing import Union, Optional from typing_extensions import Literal, Required, TypeAlias, TypedDict +from ...._types import SequenceNotStr from .profiles.pattern_param import PatternParam __all__ = ["EntryUpdateParams", "Variant0", "Variant1", "Variant2"] @@ -23,6 +24,16 @@ class Variant0(TypedDict, total=False): enabled: bool + validator_ids: SequenceNotStr[str] + """Validators this entry should reference, by id, at most 10. + + Replaces the current set. + + Optional, unlike the rest of this body: omitting it leaves the current + attachments alone, so a client that predates validators cannot detach them by + accident. Send `[]` to detach. + """ + class Variant1(TypedDict, total=False): account_id: Required[str] diff --git a/src/cloudflare/types/zero_trust/dlp/entry_update_response.py b/src/cloudflare/types/zero_trust/dlp/entry_update_response.py index d03bcc95f80..d6a94fe9bb1 100644 --- a/src/cloudflare/types/zero_trust/dlp/entry_update_response.py +++ b/src/cloudflare/types/zero_trust/dlp/entry_update_response.py @@ -1,6 +1,6 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import Union, Optional +from typing import List, Union, Optional from datetime import datetime from typing_extensions import Literal, TypeAlias @@ -42,6 +42,15 @@ class CustomEntry(BaseModel): profile_id: Optional[str] = None + validator_ids: Optional[List[str]] = None + """Validators this entry references, by id, at most 10. + + An empty list means the entry references none. + + Returned by the entry endpoints. Not returned on entries embedded in other + responses, such as profiles. + """ + class CustomPromptTopicEntry(BaseModel): id: str @@ -191,7 +200,7 @@ class WordListEntry(BaseModel): updated_at: datetime - word_list: object + word_list: List[str] profile_id: Optional[str] = None diff --git a/src/cloudflare/types/zero_trust/dlp/profile.py b/src/cloudflare/types/zero_trust/dlp/profile.py index c43680f975a..02484e4c171 100644 --- a/src/cloudflare/types/zero_trust/dlp/profile.py +++ b/src/cloudflare/types/zero_trust/dlp/profile.py @@ -99,6 +99,15 @@ class CustomProfileEntryCustomEntry(BaseModel): profile_id: Optional[str] = None + validator_ids: Optional[List[str]] = None + """Validators this entry references, by id, at most 10. + + An empty list means the entry references none. + + Returned by the entry endpoints. Not returned on entries embedded in other + responses, such as profiles. + """ + class CustomProfileEntryCustomPromptTopicEntry(BaseModel): id: str @@ -250,7 +259,7 @@ class CustomProfileEntryWordListEntry(BaseModel): updated_at: datetime - word_list: object + word_list: List[str] profile_id: Optional[str] = None @@ -295,6 +304,15 @@ class CustomProfileSharedEntryCustomEntry(BaseModel): profile_id: Optional[str] = None + validator_ids: Optional[List[str]] = None + """Validators this entry references, by id, at most 10. + + An empty list means the entry references none. + + Returned by the entry endpoints. Not returned on entries embedded in other + responses, such as profiles. + """ + class CustomProfileSharedEntryCustomPromptTopicEntry(BaseModel): id: str @@ -447,7 +465,7 @@ class CustomProfileSharedEntryWordListEntry(BaseModel): updated_at: datetime - word_list: object + word_list: List[str] profile_id: Optional[str] = None @@ -529,6 +547,15 @@ class PredefinedProfileEntryCustomEntry(BaseModel): profile_id: Optional[str] = None + validator_ids: Optional[List[str]] = None + """Validators this entry references, by id, at most 10. + + An empty list means the entry references none. + + Returned by the entry endpoints. Not returned on entries embedded in other + responses, such as profiles. + """ + class PredefinedProfileEntryCustomPromptTopicEntry(BaseModel): id: str @@ -680,7 +707,7 @@ class PredefinedProfileEntryWordListEntry(BaseModel): updated_at: datetime - word_list: object + word_list: List[str] profile_id: Optional[str] = None @@ -744,6 +771,15 @@ class IntegrationProfileEntryCustomEntry(BaseModel): profile_id: Optional[str] = None + validator_ids: Optional[List[str]] = None + """Validators this entry references, by id, at most 10. + + An empty list means the entry references none. + + Returned by the entry endpoints. Not returned on entries embedded in other + responses, such as profiles. + """ + class IntegrationProfileEntryCustomPromptTopicEntry(BaseModel): id: str @@ -895,7 +931,7 @@ class IntegrationProfileEntryWordListEntry(BaseModel): updated_at: datetime - word_list: object + word_list: List[str] profile_id: Optional[str] = None @@ -930,6 +966,15 @@ class IntegrationProfileSharedEntryCustomEntry(BaseModel): profile_id: Optional[str] = None + validator_ids: Optional[List[str]] = None + """Validators this entry references, by id, at most 10. + + An empty list means the entry references none. + + Returned by the entry endpoints. Not returned on entries embedded in other + responses, such as profiles. + """ + class IntegrationProfileSharedEntryCustomPromptTopicEntry(BaseModel): id: str @@ -1082,7 +1127,7 @@ class IntegrationProfileSharedEntryWordListEntry(BaseModel): updated_at: datetime - word_list: object + word_list: List[str] profile_id: Optional[str] = None diff --git a/src/cloudflare/types/zero_trust/dlp/profiles/predefined_profile.py b/src/cloudflare/types/zero_trust/dlp/profiles/predefined_profile.py index 791a5ece0f2..a9840efb2ce 100644 --- a/src/cloudflare/types/zero_trust/dlp/profiles/predefined_profile.py +++ b/src/cloudflare/types/zero_trust/dlp/profiles/predefined_profile.py @@ -43,6 +43,15 @@ class EntryCustomEntry(BaseModel): profile_id: Optional[str] = None + validator_ids: Optional[List[str]] = None + """Validators this entry references, by id, at most 10. + + An empty list means the entry references none. + + Returned by the entry endpoints. Not returned on entries embedded in other + responses, such as profiles. + """ + class EntryCustomPromptTopicEntry(BaseModel): id: str @@ -194,7 +203,7 @@ class EntryWordListEntry(BaseModel): updated_at: datetime - word_list: object + word_list: List[str] profile_id: Optional[str] = None diff --git a/src/cloudflare/types/zero_trust/dlp/references.py b/src/cloudflare/types/zero_trust/dlp/references.py new file mode 100644 index 00000000000..b287a5011c4 --- /dev/null +++ b/src/cloudflare/types/zero_trust/dlp/references.py @@ -0,0 +1,38 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List +from typing_extensions import Literal + +from ...._models import BaseModel + +__all__ = ["References", "Entry"] + + +class Entry(BaseModel): + """A detection entry that uses a validator.""" + + id: str + + name: str + + type: Literal[ + "custom", "custom_prompt_topic", "predefined", "integration", "exact_data", "document_fingerprint", "word_list" + ] + """The type of a detection entry.""" + + +class References(BaseModel): + """What currently uses a validator. + + Deleting a validator that is still in use returns `409`, so + check this first. + + Read-only. A validator is attached or detached by updating the detection entry that uses it, not + by writing this back. + """ + + entries: List[Entry] + """The detection entries using this validator, ordered by name.""" + + entry_count: int + """Number of detection entries this validator is attached to.""" diff --git a/src/cloudflare/types/zero_trust/dlp/validator.py b/src/cloudflare/types/zero_trust/dlp/validator.py new file mode 100644 index 00000000000..d2ad7396163 --- /dev/null +++ b/src/cloudflare/types/zero_trust/dlp/validator.py @@ -0,0 +1,74 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Union +from datetime import datetime +from typing_extensions import Literal, TypeAlias + +from ...._models import BaseModel +from .references import References +from .validators.word import Word + +__all__ = ["Validator", "ProximityWordValidator", "WorkerValidator"] + + +class ProximityWordValidator(BaseModel): + """A reusable list of weighted words. + + Attaching it to a detection entry raises the confidence of + that entry's matches when one of the words appears nearby, and lowers it when none do. + """ + + id: str + + created_at: datetime + + kind: Literal["proximity_words"] + + name: str + """A name for this validator, at most 50 characters.""" + + referenced_by: References + """What currently uses a validator. + + Deleting a validator that is still in use returns `409`, so check this first. + + Read-only. A validator is attached or detached by updating the detection entry + that uses it, not by writing this back. + """ + + updated_at: datetime + + words: List[Word] + """The words that raise confidence when found near a match.""" + + +class WorkerValidator(BaseModel): + """A customer Worker registered as a validator.""" + + id: str + + created_at: datetime + + kind: Literal["worker"] + + name: str + """A name for this validator, at most 50 characters.""" + + referenced_by: References + """What currently uses a validator. + + Deleting a validator that is still in use returns `409`, so check this first. + + Read-only. A validator is attached or detached by updating the detection entry + that uses it, not by writing this back. + """ + + script_tag: str + """The public script tag of the customer's Worker that scores matches.""" + + updated_at: datetime + + default: Union[float, Literal["veto"], None] = None + + +Validator: TypeAlias = Union[ProximityWordValidator, WorkerValidator] diff --git a/src/cloudflare/types/zero_trust/dlp/validator_array.py b/src/cloudflare/types/zero_trust/dlp/validator_array.py new file mode 100644 index 00000000000..14176b14c54 --- /dev/null +++ b/src/cloudflare/types/zero_trust/dlp/validator_array.py @@ -0,0 +1,10 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List +from typing_extensions import TypeAlias + +from .validator import Validator + +__all__ = ["ValidatorArray"] + +ValidatorArray: TypeAlias = List[Validator] diff --git a/src/cloudflare/types/zero_trust/dlp/validator_list_params.py b/src/cloudflare/types/zero_trust/dlp/validator_list_params.py new file mode 100644 index 00000000000..df1d1d414a6 --- /dev/null +++ b/src/cloudflare/types/zero_trust/dlp/validator_list_params.py @@ -0,0 +1,15 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Optional +from typing_extensions import Literal, Required, TypedDict + +__all__ = ["ValidatorListParams"] + + +class ValidatorListParams(TypedDict, total=False): + account_id: Required[str] + + kind: Optional[Literal["proximity_words", "worker"]] + """Only return validators of this kind. Omit to return every kind.""" diff --git a/src/cloudflare/types/zero_trust/dlp/validators/__init__.py b/src/cloudflare/types/zero_trust/dlp/validators/__init__.py new file mode 100644 index 00000000000..9a586570b3d --- /dev/null +++ b/src/cloudflare/types/zero_trust/dlp/validators/__init__.py @@ -0,0 +1,11 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from .word import Word as Word +from .weight import Weight as Weight +from .word_param import WordParam as WordParam +from .proximity_word_validator import ProximityWordValidator as ProximityWordValidator +from .proximity_word_create_params import ProximityWordCreateParams as ProximityWordCreateParams +from .proximity_word_update_params import ProximityWordUpdateParams as ProximityWordUpdateParams +from .proximity_word_validator_array import ProximityWordValidatorArray as ProximityWordValidatorArray diff --git a/src/cloudflare/types/zero_trust/dlp/validators/proximity_word_create_params.py b/src/cloudflare/types/zero_trust/dlp/validators/proximity_word_create_params.py new file mode 100644 index 00000000000..476e67667fc --- /dev/null +++ b/src/cloudflare/types/zero_trust/dlp/validators/proximity_word_create_params.py @@ -0,0 +1,27 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Iterable +from typing_extensions import Required, TypedDict + +from .word_param import WordParam + +__all__ = ["ProximityWordCreateParams"] + + +class ProximityWordCreateParams(TypedDict, total=False): + account_id: Required[str] + + name: Required[str] + """A name for this validator, at most 50 characters.""" + + words: Required[Iterable[WordParam]] + """ + The words that raise confidence when found near a match, at most 100 per + validator. Matching ignores case, so the list may not contain the same word + twice with different capitalisation. Words are stored as sent. + + For example, a validator for medical record numbers might use + `[{"word": "patient", "weight": "strong"}, {"word": "diagnosis", "weight": "moderate"}, {"word": "mrn", "weight": "weak"}]`. + """ diff --git a/src/cloudflare/types/zero_trust/dlp/validators/proximity_word_update_params.py b/src/cloudflare/types/zero_trust/dlp/validators/proximity_word_update_params.py new file mode 100644 index 00000000000..f9cecffc747 --- /dev/null +++ b/src/cloudflare/types/zero_trust/dlp/validators/proximity_word_update_params.py @@ -0,0 +1,27 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Iterable +from typing_extensions import Required, TypedDict + +from .word_param import WordParam + +__all__ = ["ProximityWordUpdateParams"] + + +class ProximityWordUpdateParams(TypedDict, total=False): + account_id: Required[str] + + name: Required[str] + """A name for this validator, at most 50 characters.""" + + words: Required[Iterable[WordParam]] + """ + The words that raise confidence when found near a match, at most 100 per + validator. Matching ignores case, so the list may not contain the same word + twice with different capitalisation. Words are stored as sent. + + For example, a validator for medical record numbers might use + `[{"word": "patient", "weight": "strong"}, {"word": "diagnosis", "weight": "moderate"}, {"word": "mrn", "weight": "weak"}]`. + """ diff --git a/src/cloudflare/types/zero_trust/dlp/validators/proximity_word_validator.py b/src/cloudflare/types/zero_trust/dlp/validators/proximity_word_validator.py new file mode 100644 index 00000000000..6a78eb614aa --- /dev/null +++ b/src/cloudflare/types/zero_trust/dlp/validators/proximity_word_validator.py @@ -0,0 +1,39 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List +from datetime import datetime + +from .word import Word +from ....._models import BaseModel +from ..references import References + +__all__ = ["ProximityWordValidator"] + + +class ProximityWordValidator(BaseModel): + """A reusable list of weighted words. + + Attaching it to a detection entry raises the confidence of + that entry's matches when one of the words appears nearby, and lowers it when none do. + """ + + id: str + + created_at: datetime + + name: str + """A name for this validator, at most 50 characters.""" + + referenced_by: References + """What currently uses a validator. + + Deleting a validator that is still in use returns `409`, so check this first. + + Read-only. A validator is attached or detached by updating the detection entry + that uses it, not by writing this back. + """ + + updated_at: datetime + + words: List[Word] + """The words that raise confidence when found near a match.""" diff --git a/src/cloudflare/types/zero_trust/dlp/validators/proximity_word_validator_array.py b/src/cloudflare/types/zero_trust/dlp/validators/proximity_word_validator_array.py new file mode 100644 index 00000000000..0019221c416 --- /dev/null +++ b/src/cloudflare/types/zero_trust/dlp/validators/proximity_word_validator_array.py @@ -0,0 +1,10 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List +from typing_extensions import TypeAlias + +from .proximity_word_validator import ProximityWordValidator + +__all__ = ["ProximityWordValidatorArray"] + +ProximityWordValidatorArray: TypeAlias = List[ProximityWordValidator] diff --git a/src/cloudflare/types/zero_trust/dlp/validators/weight.py b/src/cloudflare/types/zero_trust/dlp/validators/weight.py new file mode 100644 index 00000000000..5b44e54c287 --- /dev/null +++ b/src/cloudflare/types/zero_trust/dlp/validators/weight.py @@ -0,0 +1,7 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing_extensions import Literal, TypeAlias + +__all__ = ["Weight"] + +Weight: TypeAlias = Literal["strong", "moderate", "weak"] diff --git a/src/cloudflare/types/zero_trust/dlp/validators/word.py b/src/cloudflare/types/zero_trust/dlp/validators/word.py new file mode 100644 index 00000000000..19361c26c60 --- /dev/null +++ b/src/cloudflare/types/zero_trust/dlp/validators/word.py @@ -0,0 +1,23 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from .weight import Weight +from ....._models import BaseModel + +__all__ = ["Word"] + + +class Word(BaseModel): + """A word that raises a match's confidence when it appears near the match.""" + + weight: Weight + """How much a word contributes to a match's confidence when it is found nearby. + + Separate from a profile's high/medium/low confidence threshold: this describes + how telling the word is, not how confident the resulting match is. + """ + + word: str + """The word or phrase to look for. + + Must contain 1–128 characters and is matched case-insensitively. + """ diff --git a/src/cloudflare/types/zero_trust/dlp/validators/word_param.py b/src/cloudflare/types/zero_trust/dlp/validators/word_param.py new file mode 100644 index 00000000000..df8ec41b282 --- /dev/null +++ b/src/cloudflare/types/zero_trust/dlp/validators/word_param.py @@ -0,0 +1,26 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Required, TypedDict + +from .weight import Weight + +__all__ = ["WordParam"] + + +class WordParam(TypedDict, total=False): + """A word that raises a match's confidence when it appears near the match.""" + + weight: Required[Weight] + """How much a word contributes to a match's confidence when it is found nearby. + + Separate from a profile's high/medium/low confidence threshold: this describes + how telling the word is, not how confident the resulting match is. + """ + + word: Required[str] + """The word or phrase to look for. + + Must contain 1–128 characters and is matched case-insensitively. + """ diff --git a/src/cloudflare/types/zero_trust/gateway/__init__.py b/src/cloudflare/types/zero_trust/gateway/__init__.py index 0e920c31c0c..d2fa3500a78 100644 --- a/src/cloudflare/types/zero_trust/gateway/__init__.py +++ b/src/cloudflare/types/zero_trust/gateway/__init__.py @@ -56,6 +56,7 @@ from .pacfile_list_response import PacfileListResponse as PacfileListResponse from .pacfile_update_params import PacfileUpdateParams as PacfileUpdateParams from .body_scanning_settings import BodyScanningSettings as BodyScanningSettings +from .dns_destination_ips_id import DNSDestinationIPsID as DNSDestinationIPsID from .location_create_params import LocationCreateParams as LocationCreateParams from .location_update_params import LocationUpdateParams as LocationUpdateParams from .extended_email_matching import ExtendedEmailMatching as ExtendedEmailMatching @@ -92,5 +93,6 @@ from .audit_ssh_setting_update_params import AuditSSHSettingUpdateParams as AuditSSHSettingUpdateParams from .certificate_deactivate_response import CertificateDeactivateResponse as CertificateDeactivateResponse from .browser_isolation_settings_param import BrowserIsolationSettingsParam as BrowserIsolationSettingsParam +from .dns_destination_ip_list_response import DNSDestinationIPListResponse as DNSDestinationIPListResponse from .custom_certificate_settings_param import CustomCertificateSettingsParam as CustomCertificateSettingsParam from .gateway_configuration_settings_param import GatewayConfigurationSettingsParam as GatewayConfigurationSettingsParam diff --git a/src/cloudflare/types/zero_trust/gateway/certificate_activate_response.py b/src/cloudflare/types/zero_trust/gateway/certificate_activate_response.py index 6d37a9f8492..9ab91f23470 100644 --- a/src/cloudflare/types/zero_trust/gateway/certificate_activate_response.py +++ b/src/cloudflare/types/zero_trust/gateway/certificate_activate_response.py @@ -44,6 +44,12 @@ class CertificateActivateResponse(BaseModel): issuer_raw: Optional[str] = None """Provide the entire issuer field of the certificate (read-only).""" + region: Optional[str] = None + """ + Indicate the read-only region the certificate authority's key material is pinned + to. Omitted for certificates that were created without a region. + """ + type: Optional[Literal["custom", "gateway_managed"]] = None """Indicate the read-only certificate type, BYO-PKI (custom) or Gateway-managed.""" diff --git a/src/cloudflare/types/zero_trust/gateway/certificate_create_response.py b/src/cloudflare/types/zero_trust/gateway/certificate_create_response.py index 0f02d529315..b438a59f35b 100644 --- a/src/cloudflare/types/zero_trust/gateway/certificate_create_response.py +++ b/src/cloudflare/types/zero_trust/gateway/certificate_create_response.py @@ -44,6 +44,12 @@ class CertificateCreateResponse(BaseModel): issuer_raw: Optional[str] = None """Provide the entire issuer field of the certificate (read-only).""" + region: Optional[str] = None + """ + Indicate the read-only region the certificate authority's key material is pinned + to. Omitted for certificates that were created without a region. + """ + type: Optional[Literal["custom", "gateway_managed"]] = None """Indicate the read-only certificate type, BYO-PKI (custom) or Gateway-managed.""" diff --git a/src/cloudflare/types/zero_trust/gateway/certificate_deactivate_response.py b/src/cloudflare/types/zero_trust/gateway/certificate_deactivate_response.py index 6393425aedc..a11a0d28a4f 100644 --- a/src/cloudflare/types/zero_trust/gateway/certificate_deactivate_response.py +++ b/src/cloudflare/types/zero_trust/gateway/certificate_deactivate_response.py @@ -44,6 +44,12 @@ class CertificateDeactivateResponse(BaseModel): issuer_raw: Optional[str] = None """Provide the entire issuer field of the certificate (read-only).""" + region: Optional[str] = None + """ + Indicate the read-only region the certificate authority's key material is pinned + to. Omitted for certificates that were created without a region. + """ + type: Optional[Literal["custom", "gateway_managed"]] = None """Indicate the read-only certificate type, BYO-PKI (custom) or Gateway-managed.""" diff --git a/src/cloudflare/types/zero_trust/gateway/certificate_delete_response.py b/src/cloudflare/types/zero_trust/gateway/certificate_delete_response.py index 15674c552bd..54c9ec50570 100644 --- a/src/cloudflare/types/zero_trust/gateway/certificate_delete_response.py +++ b/src/cloudflare/types/zero_trust/gateway/certificate_delete_response.py @@ -44,6 +44,12 @@ class CertificateDeleteResponse(BaseModel): issuer_raw: Optional[str] = None """Provide the entire issuer field of the certificate (read-only).""" + region: Optional[str] = None + """ + Indicate the read-only region the certificate authority's key material is pinned + to. Omitted for certificates that were created without a region. + """ + type: Optional[Literal["custom", "gateway_managed"]] = None """Indicate the read-only certificate type, BYO-PKI (custom) or Gateway-managed.""" diff --git a/src/cloudflare/types/zero_trust/gateway/certificate_get_response.py b/src/cloudflare/types/zero_trust/gateway/certificate_get_response.py index 506298f781a..928dcb0f7ca 100644 --- a/src/cloudflare/types/zero_trust/gateway/certificate_get_response.py +++ b/src/cloudflare/types/zero_trust/gateway/certificate_get_response.py @@ -44,6 +44,12 @@ class CertificateGetResponse(BaseModel): issuer_raw: Optional[str] = None """Provide the entire issuer field of the certificate (read-only).""" + region: Optional[str] = None + """ + Indicate the read-only region the certificate authority's key material is pinned + to. Omitted for certificates that were created without a region. + """ + type: Optional[Literal["custom", "gateway_managed"]] = None """Indicate the read-only certificate type, BYO-PKI (custom) or Gateway-managed.""" diff --git a/src/cloudflare/types/zero_trust/gateway/certificate_list_response.py b/src/cloudflare/types/zero_trust/gateway/certificate_list_response.py index a82d657d019..b186483a44a 100644 --- a/src/cloudflare/types/zero_trust/gateway/certificate_list_response.py +++ b/src/cloudflare/types/zero_trust/gateway/certificate_list_response.py @@ -44,6 +44,12 @@ class CertificateListResponse(BaseModel): issuer_raw: Optional[str] = None """Provide the entire issuer field of the certificate (read-only).""" + region: Optional[str] = None + """ + Indicate the read-only region the certificate authority's key material is pinned + to. Omitted for certificates that were created without a region. + """ + type: Optional[Literal["custom", "gateway_managed"]] = None """Indicate the read-only certificate type, BYO-PKI (custom) or Gateway-managed.""" diff --git a/src/cloudflare/types/zero_trust/gateway/dns_destination_ip_list_response.py b/src/cloudflare/types/zero_trust/gateway/dns_destination_ip_list_response.py new file mode 100644 index 00000000000..32e6e235660 --- /dev/null +++ b/src/cloudflare/types/zero_trust/gateway/dns_destination_ip_list_response.py @@ -0,0 +1,22 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing_extensions import Literal + +from ...._models import BaseModel + +__all__ = ["DNSDestinationIPListResponse"] + + +class DNSDestinationIPListResponse(BaseModel): + id: str + + backup_ip: str + + pair_type: Literal["shared", "dedicated", "byoip"] + """ + Specify whether the pair shared across multiple accounts (shared) or available + exclusively to this account. Non-shared pairs can contain Cloudflare-owned IPs + (dedicated) or customer-provided IPs (byoip). + """ + + primary_ip: str diff --git a/src/cloudflare/types/tenants/account_type_list_response.py b/src/cloudflare/types/zero_trust/gateway/dns_destination_ips_id.py similarity index 62% rename from src/cloudflare/types/tenants/account_type_list_response.py rename to src/cloudflare/types/zero_trust/gateway/dns_destination_ips_id.py index 9583cbe105d..ee978d74323 100644 --- a/src/cloudflare/types/tenants/account_type_list_response.py +++ b/src/cloudflare/types/zero_trust/gateway/dns_destination_ips_id.py @@ -2,6 +2,6 @@ from typing_extensions import TypeAlias -__all__ = ["AccountTypeListResponse"] +__all__ = ["DNSDestinationIPsID"] -AccountTypeListResponse: TypeAlias = str +DNSDestinationIPsID: TypeAlias = str diff --git a/src/cloudflare/types/zero_trust/gateway/gateway_rule.py b/src/cloudflare/types/zero_trust/gateway/gateway_rule.py index 4b4cec82e05..3698e385c12 100644 --- a/src/cloudflare/types/zero_trust/gateway/gateway_rule.py +++ b/src/cloudflare/types/zero_trust/gateway/gateway_rule.py @@ -55,6 +55,7 @@ class GatewayRule(BaseModel): "resolve", "quarantine", "redirect", + "forward", ] """ Specify the action to perform when the associated traffic, identity, and device diff --git a/src/cloudflare/types/zero_trust/gateway/location.py b/src/cloudflare/types/zero_trust/gateway/location.py index 800127101af..1d5306143cd 100644 --- a/src/cloudflare/types/zero_trust/gateway/location.py +++ b/src/cloudflare/types/zero_trust/gateway/location.py @@ -6,6 +6,7 @@ from .endpoint import Endpoint from ...._models import BaseModel +from .dns_destination_ips_id import DNSDestinationIPsID __all__ = ["Location", "MaxTTL", "Network"] @@ -43,7 +44,7 @@ class Location(BaseModel): created_at: Optional[datetime] = None - dns_destination_ips_id: Optional[str] = None + dns_destination_ips_id: Optional[DNSDestinationIPsID] = None """ Indicate the identifier of the pair of IPv4 addresses assigned to this location. """ @@ -55,6 +56,12 @@ class Location(BaseModel): block rather than the standard Cloudflare IPv6 block. """ + dns64_enabled: Optional[bool] = None + """Enable DNS64 synthesis for DNS queries matched to this location. + + When updating a location, omitting this field resets it to false. + """ + doh_subdomain: Optional[str] = None """Specify the DNS over HTTPS domain that receives DNS requests. diff --git a/src/cloudflare/types/zero_trust/gateway/location_create_params.py b/src/cloudflare/types/zero_trust/gateway/location_create_params.py index b3d4a317864..8e77b4cdb15 100644 --- a/src/cloudflare/types/zero_trust/gateway/location_create_params.py +++ b/src/cloudflare/types/zero_trust/gateway/location_create_params.py @@ -29,6 +29,12 @@ class LocationCreateParams(TypedDict, total=False): pre-assigned pair remains unchanged. """ + dns64_enabled: bool + """Enable DNS64 synthesis for DNS queries matched to this location. + + When updating a location, omitting this field resets it to false. + """ + ecs_support: bool """Indicate whether the location must resolve EDNS queries.""" diff --git a/src/cloudflare/types/zero_trust/gateway/location_update_params.py b/src/cloudflare/types/zero_trust/gateway/location_update_params.py index ffc7630b9f4..716377eab06 100644 --- a/src/cloudflare/types/zero_trust/gateway/location_update_params.py +++ b/src/cloudflare/types/zero_trust/gateway/location_update_params.py @@ -29,6 +29,12 @@ class LocationUpdateParams(TypedDict, total=False): pre-assigned pair remains unchanged. """ + dns64_enabled: bool + """Enable DNS64 synthesis for DNS queries matched to this location. + + When updating a location, omitting this field resets it to false. + """ + ecs_support: bool """Indicate whether the location must resolve EDNS queries.""" diff --git a/src/cloudflare/types/zero_trust/gateway/rule_create_params.py b/src/cloudflare/types/zero_trust/gateway/rule_create_params.py index 5f68c7a53c0..34185786f93 100644 --- a/src/cloudflare/types/zero_trust/gateway/rule_create_params.py +++ b/src/cloudflare/types/zero_trust/gateway/rule_create_params.py @@ -36,6 +36,7 @@ class RuleCreateParams(TypedDict, total=False): "resolve", "quarantine", "redirect", + "forward", ] ] """ diff --git a/src/cloudflare/types/zero_trust/gateway/rule_setting.py b/src/cloudflare/types/zero_trust/gateway/rule_setting.py index b770c906c51..b792fa9c083 100644 --- a/src/cloudflare/types/zero_trust/gateway/rule_setting.py +++ b/src/cloudflare/types/zero_trust/gateway/rule_setting.py @@ -11,13 +11,13 @@ __all__ = [ "RuleSetting", - "AuditSSH", "BISOAdminControls", "BlockPage", "CheckSession", "DNSResolvers", "Egress", "ForensicCopy", + "Forward", "L4override", "NotificationSettings", "PayloadLog", @@ -28,16 +28,6 @@ ] -class AuditSSH(BaseModel): - """Define the settings for the Audit SSH action. - - Settable only for `l4` rules with `audit_ssh` action. - """ - - command_logging: Optional[bool] = None - """Enable SSH command logging.""" - - class BISOAdminControls(BaseModel): """Configure browser isolation behavior. @@ -74,11 +64,15 @@ class BISOAdminControls(BaseModel): du: Optional[bool] = None """Set to false to enable uploading. Only applies when `version == "v1"`.""" - keyboard: Optional[Literal["enabled", "disabled"]] = None + keyboard: Optional[Literal["enabled", "disabled", "enable_read_only_actions"]] = None """Configure keyboard usage behavior. - If this field is absent, keyboard usage remains enabled. Applies only when - version == "v2". + When set to enable_read_only_actions, only approved browser commands (find, + copy, print, zoom, and select-all) may execute; other keyboard input is blocked + from reaching the page. Copy and print remain subject to their independent + controls. If this field is absent, keyboard usage remains enabled. Applies only + when version == "v2". The enable_read_only_actions value requires an explicit + version of "v2". """ paste: Optional[Literal["enabled", "disabled", "remote_only"]] = None @@ -180,6 +174,16 @@ class ForensicCopy(BaseModel): """Enable sending the copy to storage.""" +class Forward(BaseModel): + """Forward matching HTTP requests to a Worker. + + Required for `http` rules with the action set to `forward`. + """ + + worker_id: str + """Specify the public Worker ID of the target Worker.""" + + class L4override(BaseModel): """Send matching traffic to the supplied destination IP address and port. @@ -305,12 +309,6 @@ class RuleSetting(BaseModel): rules. """ - audit_ssh: Optional[AuditSSH] = None - """Define the settings for the Audit SSH action. - - Settable only for `l4` rules with `audit_ssh` action. - """ - biso_admin_controls: Optional[BISOAdminControls] = None """Configure browser isolation behavior. @@ -379,6 +377,12 @@ class RuleSetting(BaseModel): rule matches. """ + forward: Optional[Forward] = None + """Forward matching HTTP requests to a Worker. + + Required for `http` rules with the action set to `forward`. + """ + ignore_cname_category_matches: Optional[bool] = None """Ignore category matches at CNAME domains in a response. diff --git a/src/cloudflare/types/zero_trust/gateway/rule_setting_param.py b/src/cloudflare/types/zero_trust/gateway/rule_setting_param.py index 99d7b26f8d8..e66001ee3a3 100644 --- a/src/cloudflare/types/zero_trust/gateway/rule_setting_param.py +++ b/src/cloudflare/types/zero_trust/gateway/rule_setting_param.py @@ -11,13 +11,13 @@ __all__ = [ "RuleSettingParam", - "AuditSSH", "BISOAdminControls", "BlockPage", "CheckSession", "DNSResolvers", "Egress", "ForensicCopy", + "Forward", "L4override", "NotificationSettings", "PayloadLog", @@ -28,16 +28,6 @@ ] -class AuditSSH(TypedDict, total=False): - """Define the settings for the Audit SSH action. - - Settable only for `l4` rules with `audit_ssh` action. - """ - - command_logging: bool - """Enable SSH command logging.""" - - class BISOAdminControls(TypedDict, total=False): """Configure browser isolation behavior. @@ -74,11 +64,15 @@ class BISOAdminControls(TypedDict, total=False): du: bool """Set to false to enable uploading. Only applies when `version == "v1"`.""" - keyboard: Literal["enabled", "disabled"] + keyboard: Literal["enabled", "disabled", "enable_read_only_actions"] """Configure keyboard usage behavior. - If this field is absent, keyboard usage remains enabled. Applies only when - version == "v2". + When set to enable_read_only_actions, only approved browser commands (find, + copy, print, zoom, and select-all) may execute; other keyboard input is blocked + from reaching the page. Copy and print remain subject to their independent + controls. If this field is absent, keyboard usage remains enabled. Applies only + when version == "v2". The enable_read_only_actions value requires an explicit + version of "v2". """ paste: Literal["enabled", "disabled", "remote_only"] @@ -180,6 +174,16 @@ class ForensicCopy(TypedDict, total=False): """Enable sending the copy to storage.""" +class Forward(TypedDict, total=False): + """Forward matching HTTP requests to a Worker. + + Required for `http` rules with the action set to `forward`. + """ + + worker_id: Required[str] + """Specify the public Worker ID of the target Worker.""" + + class L4override(TypedDict, total=False): """Send matching traffic to the supplied destination IP address and port. @@ -305,12 +309,6 @@ class RuleSettingParam(TypedDict, total=False): rules. """ - audit_ssh: Optional[AuditSSH] - """Define the settings for the Audit SSH action. - - Settable only for `l4` rules with `audit_ssh` action. - """ - biso_admin_controls: BISOAdminControls """Configure browser isolation behavior. @@ -379,6 +377,12 @@ class RuleSettingParam(TypedDict, total=False): rule matches. """ + forward: Optional[Forward] + """Forward matching HTTP requests to a Worker. + + Required for `http` rules with the action set to `forward`. + """ + ignore_cname_category_matches: bool """Ignore category matches at CNAME domains in a response. diff --git a/src/cloudflare/types/zero_trust/gateway/rule_update_params.py b/src/cloudflare/types/zero_trust/gateway/rule_update_params.py index 9e5e9ff4a6f..c620ee95c79 100644 --- a/src/cloudflare/types/zero_trust/gateway/rule_update_params.py +++ b/src/cloudflare/types/zero_trust/gateway/rule_update_params.py @@ -36,6 +36,7 @@ class RuleUpdateParams(TypedDict, total=False): "resolve", "quarantine", "redirect", + "forward", ] ] """ diff --git a/src/cloudflare/types/zero_trust/identity_provider.py b/src/cloudflare/types/zero_trust/identity_provider.py index 9483d894530..9bb800e777a 100644 --- a/src/cloudflare/types/zero_trust/identity_provider.py +++ b/src/cloudflare/types/zero_trust/identity_provider.py @@ -37,6 +37,10 @@ "AccessOIDCConfig", "AccessOIDCSAMLCertificateSet", "AccessOIDCSAMLCertificateSetCurrentCertificate", + "AccessDuo", + "AccessDuoConfig", + "AccessDuoSAMLCertificateSet", + "AccessDuoSAMLCertificateSetCurrentCertificate", "AccessOkta", "AccessOktaConfig", "AccessOktaSAMLCertificateSet", @@ -65,6 +69,10 @@ "AccessCloudflareConfig", "AccessCloudflareSAMLCertificateSet", "AccessCloudflareSAMLCertificateSetCurrentCertificate", + "AccessPasskeys", + "AccessPasskeysConfig", + "AccessPasskeysSAMLCertificateSet", + "AccessPasskeysSAMLCertificateSetCurrentCertificate", ] @@ -849,6 +857,118 @@ class AccessOIDC(BaseModel): """ +class AccessDuoConfig(BaseModel): + """The configuration parameters for the identity provider. + + To view the required parameters for a specific provider, refer to our [developer documentation](https://developers.cloudflare.com/cloudflare-one/identity/idp-integration/). + """ + + client_id: Optional[str] = None + """The client ID from the Duo Generic OIDC Relying Party metadata.""" + + client_secret: Optional[str] = None + """The client secret from the Duo Generic OIDC Relying Party metadata.""" + + issuer_url: Optional[str] = None + """The issuer URL from the Duo Generic OIDC Relying Party metadata.""" + + +class AccessDuoSAMLCertificateSetCurrentCertificate(BaseModel): + """The currently active certificate used for encrypting SAML assertions""" + + is_current: bool + """Indicates whether this is the currently active certificate""" + + not_after: datetime + """Certificate expiration date. + + Certificates are automatically rotated 30 days before expiration. + """ + + public_certificate: str + """ + PEM-encoded X.509 certificate containing the public key. Configure this + certificate in your external SAML Identity Provider to enable encryption. + """ + + uid: str + """Unique identifier for the certificate""" + + +class AccessDuoSAMLCertificateSet(BaseModel): + """ + The SAML encryption certificate set details, including current and previous certificates. + Only present for SAML identity providers with a certificate set assigned. + """ + + created_at: datetime + """Timestamp when the certificate set was created""" + + uid: str + """Unique identifier for the certificate set""" + + updated_at: datetime + """Timestamp when the certificate set was last updated (e.g., during rotation)""" + + current_certificate: Optional[AccessDuoSAMLCertificateSetCurrentCertificate] = None + """The currently active certificate used for encrypting SAML assertions""" + + previous_certificate: Optional[object] = None + """The previous certificate, maintained during rotation to ensure continuity. + + Null if no rotation has occurred. Mirrors the structure of `saml_certificate`. + """ + + +class AccessDuo(BaseModel): + config: AccessDuoConfig + """The configuration parameters for the identity provider. + + To view the required parameters for a specific provider, refer to our + [developer documentation](https://developers.cloudflare.com/cloudflare-one/identity/idp-integration/). + """ + + name: str + """The name of the identity provider, shown to users on the login page.""" + + type: IdentityProviderType + """The type of identity provider. + + To determine the value for a specific provider, refer to our + [developer documentation](https://developers.cloudflare.com/cloudflare-one/identity/idp-integration/). + """ + + id: Optional[str] = None + """UUID.""" + + read_only: Optional[bool] = None + """ + Indicates that the identity provider is immutable and cannot be updated or + deleted via the API. + """ + + saml_certificate_set: Optional[AccessDuoSAMLCertificateSet] = None + """ + The SAML encryption certificate set details, including current and previous + certificates. Only present for SAML identity providers with a certificate set + assigned. + """ + + saml_certificate_set_id: Optional[str] = None + """ + The UID of the SAML encryption certificate set assigned to this Identity + Provider. Only present for SAML identity providers with encryption configured. + Create a certificate set via POST to + `/identity_providers/{id}/saml_certificate`. + """ + + scim_config: Optional[IdentityProviderSCIMConfig] = None + """ + The configuration settings for enabling a System for Cross-Domain Identity + Management (SCIM) with the identity provider. + """ + + class AccessOktaConfig(BaseModel): """The configuration parameters for the identity provider. @@ -1688,6 +1808,117 @@ class AccessCloudflare(BaseModel): """ +class AccessPasskeysConfig(BaseModel): + """The configuration parameters for the identity provider. + + To view the required parameters for a specific provider, refer to our [developer documentation](https://developers.cloudflare.com/cloudflare-one/identity/idp-integration/). + """ + + login_page_auto_prompt: Optional[bool] = None + """ + When enabled, the Access login page automatically prompts the user to + authenticate with a passkey. + """ + + redirect_url: Optional[str] = None + + +class AccessPasskeysSAMLCertificateSetCurrentCertificate(BaseModel): + """The currently active certificate used for encrypting SAML assertions""" + + is_current: bool + """Indicates whether this is the currently active certificate""" + + not_after: datetime + """Certificate expiration date. + + Certificates are automatically rotated 30 days before expiration. + """ + + public_certificate: str + """ + PEM-encoded X.509 certificate containing the public key. Configure this + certificate in your external SAML Identity Provider to enable encryption. + """ + + uid: str + """Unique identifier for the certificate""" + + +class AccessPasskeysSAMLCertificateSet(BaseModel): + """ + The SAML encryption certificate set details, including current and previous certificates. + Only present for SAML identity providers with a certificate set assigned. + """ + + created_at: datetime + """Timestamp when the certificate set was created""" + + uid: str + """Unique identifier for the certificate set""" + + updated_at: datetime + """Timestamp when the certificate set was last updated (e.g., during rotation)""" + + current_certificate: Optional[AccessPasskeysSAMLCertificateSetCurrentCertificate] = None + """The currently active certificate used for encrypting SAML assertions""" + + previous_certificate: Optional[object] = None + """The previous certificate, maintained during rotation to ensure continuity. + + Null if no rotation has occurred. Mirrors the structure of `saml_certificate`. + """ + + +class AccessPasskeys(BaseModel): + config: AccessPasskeysConfig + """The configuration parameters for the identity provider. + + To view the required parameters for a specific provider, refer to our + [developer documentation](https://developers.cloudflare.com/cloudflare-one/identity/idp-integration/). + """ + + name: str + """The name of the identity provider, shown to users on the login page.""" + + type: IdentityProviderType + """The type of identity provider. + + To determine the value for a specific provider, refer to our + [developer documentation](https://developers.cloudflare.com/cloudflare-one/identity/idp-integration/). + """ + + id: Optional[str] = None + """UUID.""" + + read_only: Optional[bool] = None + """ + Indicates that the identity provider is immutable and cannot be updated or + deleted via the API. + """ + + saml_certificate_set: Optional[AccessPasskeysSAMLCertificateSet] = None + """ + The SAML encryption certificate set details, including current and previous + certificates. Only present for SAML identity providers with a certificate set + assigned. + """ + + saml_certificate_set_id: Optional[str] = None + """ + The UID of the SAML encryption certificate set assigned to this Identity + Provider. Only present for SAML identity providers with encryption configured. + Create a certificate set via POST to + `/identity_providers/{id}/saml_certificate`. + """ + + scim_config: Optional[IdentityProviderSCIMConfig] = None + """ + The configuration settings for enabling a System for Cross-Domain Identity + Management (SCIM) with the identity provider. + """ + + IdentityProvider: TypeAlias = Union[ AzureAD, AccessCentrify, @@ -1697,6 +1928,7 @@ class AccessCloudflare(BaseModel): AccessGoogleApps, AccessLinkedin, AccessOIDC, + AccessDuo, AccessOkta, AccessOnelogin, AccessPingone, @@ -1704,4 +1936,5 @@ class AccessCloudflare(BaseModel): AccessYandex, AccessOnetimepin, AccessCloudflare, + AccessPasskeys, ] diff --git a/src/cloudflare/types/zero_trust/identity_provider_create_params.py b/src/cloudflare/types/zero_trust/identity_provider_create_params.py index acf5312be52..23e51d5a48a 100644 --- a/src/cloudflare/types/zero_trust/identity_provider_create_params.py +++ b/src/cloudflare/types/zero_trust/identity_provider_create_params.py @@ -25,6 +25,8 @@ "AccessLinkedin", "AccessOIDC", "AccessOIDCConfig", + "AccessDuo", + "AccessDuoConfig", "AccessOkta", "AccessOktaConfig", "AccessOnelogin", @@ -39,6 +41,8 @@ "AccessOnetimepinConfig", "AccessCloudflare", "AccessCloudflareConfig", + "AccessPasskeys", + "AccessPasskeysConfig", ] @@ -504,6 +508,61 @@ class AccessOIDCConfig(TypedDict, total=False): """The token_endpoint URL of your IdP""" +class AccessDuo(TypedDict, total=False): + config: Required[AccessDuoConfig] + """The configuration parameters for the identity provider. + + To view the required parameters for a specific provider, refer to our + [developer documentation](https://developers.cloudflare.com/cloudflare-one/identity/idp-integration/). + """ + + name: Required[str] + """The name of the identity provider, shown to users on the login page.""" + + type: Required[IdentityProviderType] + """The type of identity provider. + + To determine the value for a specific provider, refer to our + [developer documentation](https://developers.cloudflare.com/cloudflare-one/identity/idp-integration/). + """ + + account_id: str + """The Account ID to use for this endpoint. Mutually exclusive with the Zone ID.""" + + zone_id: str + """The Zone ID to use for this endpoint. Mutually exclusive with the Account ID.""" + + saml_certificate_set_id: str + """ + The UID of the SAML encryption certificate set assigned to this Identity + Provider. Only present for SAML identity providers with encryption configured. + Create a certificate set via POST to + `/identity_providers/{id}/saml_certificate`. + """ + + scim_config: IdentityProviderSCIMConfigParam + """ + The configuration settings for enabling a System for Cross-Domain Identity + Management (SCIM) with the identity provider. + """ + + +class AccessDuoConfig(TypedDict, total=False): + """The configuration parameters for the identity provider. + + To view the required parameters for a specific provider, refer to our [developer documentation](https://developers.cloudflare.com/cloudflare-one/identity/idp-integration/). + """ + + client_id: str + """The client ID from the Duo Generic OIDC Relying Party metadata.""" + + client_secret: str + """The client secret from the Duo Generic OIDC Relying Party metadata.""" + + issuer_url: str + """The issuer URL from the Duo Generic OIDC Relying Party metadata.""" + + class AccessOkta(TypedDict, total=False): config: Required[AccessOktaConfig] """The configuration parameters for the identity provider. @@ -942,6 +1001,58 @@ class AccessCloudflareConfig(TypedDict, total=False): """ +class AccessPasskeys(TypedDict, total=False): + config: Required[AccessPasskeysConfig] + """The configuration parameters for the identity provider. + + To view the required parameters for a specific provider, refer to our + [developer documentation](https://developers.cloudflare.com/cloudflare-one/identity/idp-integration/). + """ + + name: Required[str] + """The name of the identity provider, shown to users on the login page.""" + + type: Required[IdentityProviderType] + """The type of identity provider. + + To determine the value for a specific provider, refer to our + [developer documentation](https://developers.cloudflare.com/cloudflare-one/identity/idp-integration/). + """ + + account_id: str + """The Account ID to use for this endpoint. Mutually exclusive with the Zone ID.""" + + zone_id: str + """The Zone ID to use for this endpoint. Mutually exclusive with the Account ID.""" + + saml_certificate_set_id: str + """ + The UID of the SAML encryption certificate set assigned to this Identity + Provider. Only present for SAML identity providers with encryption configured. + Create a certificate set via POST to + `/identity_providers/{id}/saml_certificate`. + """ + + scim_config: IdentityProviderSCIMConfigParam + """ + The configuration settings for enabling a System for Cross-Domain Identity + Management (SCIM) with the identity provider. + """ + + +class AccessPasskeysConfig(TypedDict, total=False): + """The configuration parameters for the identity provider. + + To view the required parameters for a specific provider, refer to our [developer documentation](https://developers.cloudflare.com/cloudflare-one/identity/idp-integration/). + """ + + login_page_auto_prompt: bool + """ + When enabled, the Access login page automatically prompts the user to + authenticate with a passkey. + """ + + IdentityProviderCreateParams: TypeAlias = Union[ AzureAD, AccessCentrify, @@ -951,6 +1062,7 @@ class AccessCloudflareConfig(TypedDict, total=False): AccessGoogleApps, AccessLinkedin, AccessOIDC, + AccessDuo, AccessOkta, AccessOnelogin, AccessPingone, @@ -958,4 +1070,5 @@ class AccessCloudflareConfig(TypedDict, total=False): AccessYandex, AccessOnetimepin, AccessCloudflare, + AccessPasskeys, ] diff --git a/src/cloudflare/types/zero_trust/identity_provider_list_response.py b/src/cloudflare/types/zero_trust/identity_provider_list_response.py index d661b30897d..3c0798878cc 100644 --- a/src/cloudflare/types/zero_trust/identity_provider_list_response.py +++ b/src/cloudflare/types/zero_trust/identity_provider_list_response.py @@ -37,6 +37,10 @@ "AccessOIDCConfig", "AccessOIDCSAMLCertificateSet", "AccessOIDCSAMLCertificateSetCurrentCertificate", + "AccessDuo", + "AccessDuoConfig", + "AccessDuoSAMLCertificateSet", + "AccessDuoSAMLCertificateSetCurrentCertificate", "AccessOkta", "AccessOktaConfig", "AccessOktaSAMLCertificateSet", @@ -65,6 +69,10 @@ "AccessCloudflareConfig", "AccessCloudflareSAMLCertificateSet", "AccessCloudflareSAMLCertificateSetCurrentCertificate", + "AccessPasskeys", + "AccessPasskeysConfig", + "AccessPasskeysSAMLCertificateSet", + "AccessPasskeysSAMLCertificateSetCurrentCertificate", ] @@ -849,6 +857,118 @@ class AccessOIDC(BaseModel): """ +class AccessDuoConfig(BaseModel): + """The configuration parameters for the identity provider. + + To view the required parameters for a specific provider, refer to our [developer documentation](https://developers.cloudflare.com/cloudflare-one/identity/idp-integration/). + """ + + client_id: Optional[str] = None + """The client ID from the Duo Generic OIDC Relying Party metadata.""" + + client_secret: Optional[str] = None + """The client secret from the Duo Generic OIDC Relying Party metadata.""" + + issuer_url: Optional[str] = None + """The issuer URL from the Duo Generic OIDC Relying Party metadata.""" + + +class AccessDuoSAMLCertificateSetCurrentCertificate(BaseModel): + """The currently active certificate used for encrypting SAML assertions""" + + is_current: bool + """Indicates whether this is the currently active certificate""" + + not_after: datetime + """Certificate expiration date. + + Certificates are automatically rotated 30 days before expiration. + """ + + public_certificate: str + """ + PEM-encoded X.509 certificate containing the public key. Configure this + certificate in your external SAML Identity Provider to enable encryption. + """ + + uid: str + """Unique identifier for the certificate""" + + +class AccessDuoSAMLCertificateSet(BaseModel): + """ + The SAML encryption certificate set details, including current and previous certificates. + Only present for SAML identity providers with a certificate set assigned. + """ + + created_at: datetime + """Timestamp when the certificate set was created""" + + uid: str + """Unique identifier for the certificate set""" + + updated_at: datetime + """Timestamp when the certificate set was last updated (e.g., during rotation)""" + + current_certificate: Optional[AccessDuoSAMLCertificateSetCurrentCertificate] = None + """The currently active certificate used for encrypting SAML assertions""" + + previous_certificate: Optional[object] = None + """The previous certificate, maintained during rotation to ensure continuity. + + Null if no rotation has occurred. Mirrors the structure of `saml_certificate`. + """ + + +class AccessDuo(BaseModel): + config: AccessDuoConfig + """The configuration parameters for the identity provider. + + To view the required parameters for a specific provider, refer to our + [developer documentation](https://developers.cloudflare.com/cloudflare-one/identity/idp-integration/). + """ + + name: str + """The name of the identity provider, shown to users on the login page.""" + + type: IdentityProviderType + """The type of identity provider. + + To determine the value for a specific provider, refer to our + [developer documentation](https://developers.cloudflare.com/cloudflare-one/identity/idp-integration/). + """ + + id: Optional[str] = None + """UUID.""" + + read_only: Optional[bool] = None + """ + Indicates that the identity provider is immutable and cannot be updated or + deleted via the API. + """ + + saml_certificate_set: Optional[AccessDuoSAMLCertificateSet] = None + """ + The SAML encryption certificate set details, including current and previous + certificates. Only present for SAML identity providers with a certificate set + assigned. + """ + + saml_certificate_set_id: Optional[str] = None + """ + The UID of the SAML encryption certificate set assigned to this Identity + Provider. Only present for SAML identity providers with encryption configured. + Create a certificate set via POST to + `/identity_providers/{id}/saml_certificate`. + """ + + scim_config: Optional[IdentityProviderSCIMConfig] = None + """ + The configuration settings for enabling a System for Cross-Domain Identity + Management (SCIM) with the identity provider. + """ + + class AccessOktaConfig(BaseModel): """The configuration parameters for the identity provider. @@ -1688,6 +1808,117 @@ class AccessCloudflare(BaseModel): """ +class AccessPasskeysConfig(BaseModel): + """The configuration parameters for the identity provider. + + To view the required parameters for a specific provider, refer to our [developer documentation](https://developers.cloudflare.com/cloudflare-one/identity/idp-integration/). + """ + + login_page_auto_prompt: Optional[bool] = None + """ + When enabled, the Access login page automatically prompts the user to + authenticate with a passkey. + """ + + redirect_url: Optional[str] = None + + +class AccessPasskeysSAMLCertificateSetCurrentCertificate(BaseModel): + """The currently active certificate used for encrypting SAML assertions""" + + is_current: bool + """Indicates whether this is the currently active certificate""" + + not_after: datetime + """Certificate expiration date. + + Certificates are automatically rotated 30 days before expiration. + """ + + public_certificate: str + """ + PEM-encoded X.509 certificate containing the public key. Configure this + certificate in your external SAML Identity Provider to enable encryption. + """ + + uid: str + """Unique identifier for the certificate""" + + +class AccessPasskeysSAMLCertificateSet(BaseModel): + """ + The SAML encryption certificate set details, including current and previous certificates. + Only present for SAML identity providers with a certificate set assigned. + """ + + created_at: datetime + """Timestamp when the certificate set was created""" + + uid: str + """Unique identifier for the certificate set""" + + updated_at: datetime + """Timestamp when the certificate set was last updated (e.g., during rotation)""" + + current_certificate: Optional[AccessPasskeysSAMLCertificateSetCurrentCertificate] = None + """The currently active certificate used for encrypting SAML assertions""" + + previous_certificate: Optional[object] = None + """The previous certificate, maintained during rotation to ensure continuity. + + Null if no rotation has occurred. Mirrors the structure of `saml_certificate`. + """ + + +class AccessPasskeys(BaseModel): + config: AccessPasskeysConfig + """The configuration parameters for the identity provider. + + To view the required parameters for a specific provider, refer to our + [developer documentation](https://developers.cloudflare.com/cloudflare-one/identity/idp-integration/). + """ + + name: str + """The name of the identity provider, shown to users on the login page.""" + + type: IdentityProviderType + """The type of identity provider. + + To determine the value for a specific provider, refer to our + [developer documentation](https://developers.cloudflare.com/cloudflare-one/identity/idp-integration/). + """ + + id: Optional[str] = None + """UUID.""" + + read_only: Optional[bool] = None + """ + Indicates that the identity provider is immutable and cannot be updated or + deleted via the API. + """ + + saml_certificate_set: Optional[AccessPasskeysSAMLCertificateSet] = None + """ + The SAML encryption certificate set details, including current and previous + certificates. Only present for SAML identity providers with a certificate set + assigned. + """ + + saml_certificate_set_id: Optional[str] = None + """ + The UID of the SAML encryption certificate set assigned to this Identity + Provider. Only present for SAML identity providers with encryption configured. + Create a certificate set via POST to + `/identity_providers/{id}/saml_certificate`. + """ + + scim_config: Optional[IdentityProviderSCIMConfig] = None + """ + The configuration settings for enabling a System for Cross-Domain Identity + Management (SCIM) with the identity provider. + """ + + IdentityProviderListResponse: TypeAlias = Union[ AzureAD, AccessCentrify, @@ -1697,6 +1928,7 @@ class AccessCloudflare(BaseModel): AccessGoogleApps, AccessLinkedin, AccessOIDC, + AccessDuo, AccessOkta, AccessOnelogin, AccessPingone, @@ -1704,4 +1936,5 @@ class AccessCloudflare(BaseModel): AccessYandex, AccessOnetimepin, AccessCloudflare, + AccessPasskeys, ] diff --git a/src/cloudflare/types/zero_trust/identity_provider_param.py b/src/cloudflare/types/zero_trust/identity_provider_param.py index 9a71f0612f8..f9d0bb0c3df 100644 --- a/src/cloudflare/types/zero_trust/identity_provider_param.py +++ b/src/cloudflare/types/zero_trust/identity_provider_param.py @@ -24,6 +24,8 @@ "AccessLinkedin", "AccessOIDC", "AccessOIDCConfig", + "AccessDuo", + "AccessDuoConfig", "AccessOkta", "AccessOktaConfig", "AccessOnelogin", @@ -38,6 +40,8 @@ "AccessOnetimepinConfig", "AccessCloudflare", "AccessCloudflareConfig", + "AccessPasskeys", + "AccessPasskeysConfig", ] @@ -381,6 +385,55 @@ class AccessOIDC(TypedDict, total=False): """ +class AccessDuoConfig(TypedDict, total=False): + """The configuration parameters for the identity provider. + + To view the required parameters for a specific provider, refer to our [developer documentation](https://developers.cloudflare.com/cloudflare-one/identity/idp-integration/). + """ + + client_id: str + """The client ID from the Duo Generic OIDC Relying Party metadata.""" + + client_secret: str + """The client secret from the Duo Generic OIDC Relying Party metadata.""" + + issuer_url: str + """The issuer URL from the Duo Generic OIDC Relying Party metadata.""" + + +class AccessDuo(TypedDict, total=False): + config: Required[AccessDuoConfig] + """The configuration parameters for the identity provider. + + To view the required parameters for a specific provider, refer to our + [developer documentation](https://developers.cloudflare.com/cloudflare-one/identity/idp-integration/). + """ + + name: Required[str] + """The name of the identity provider, shown to users on the login page.""" + + type: Required[IdentityProviderType] + """The type of identity provider. + + To determine the value for a specific provider, refer to our + [developer documentation](https://developers.cloudflare.com/cloudflare-one/identity/idp-integration/). + """ + + saml_certificate_set_id: str + """ + The UID of the SAML encryption certificate set assigned to this Identity + Provider. Only present for SAML identity providers with encryption configured. + Create a certificate set via POST to + `/identity_providers/{id}/saml_certificate`. + """ + + scim_config: IdentityProviderSCIMConfigParam + """ + The configuration settings for enabling a System for Cross-Domain Identity + Management (SCIM) with the identity provider. + """ + + class AccessOktaConfig(TypedDict, total=False): """The configuration parameters for the identity provider. @@ -777,6 +830,52 @@ class AccessCloudflare(TypedDict, total=False): """ +class AccessPasskeysConfig(TypedDict, total=False): + """The configuration parameters for the identity provider. + + To view the required parameters for a specific provider, refer to our [developer documentation](https://developers.cloudflare.com/cloudflare-one/identity/idp-integration/). + """ + + login_page_auto_prompt: bool + """ + When enabled, the Access login page automatically prompts the user to + authenticate with a passkey. + """ + + +class AccessPasskeys(TypedDict, total=False): + config: Required[AccessPasskeysConfig] + """The configuration parameters for the identity provider. + + To view the required parameters for a specific provider, refer to our + [developer documentation](https://developers.cloudflare.com/cloudflare-one/identity/idp-integration/). + """ + + name: Required[str] + """The name of the identity provider, shown to users on the login page.""" + + type: Required[IdentityProviderType] + """The type of identity provider. + + To determine the value for a specific provider, refer to our + [developer documentation](https://developers.cloudflare.com/cloudflare-one/identity/idp-integration/). + """ + + saml_certificate_set_id: str + """ + The UID of the SAML encryption certificate set assigned to this Identity + Provider. Only present for SAML identity providers with encryption configured. + Create a certificate set via POST to + `/identity_providers/{id}/saml_certificate`. + """ + + scim_config: IdentityProviderSCIMConfigParam + """ + The configuration settings for enabling a System for Cross-Domain Identity + Management (SCIM) with the identity provider. + """ + + IdentityProviderParam: TypeAlias = Union[ AzureADParam, AccessCentrify, @@ -786,6 +885,7 @@ class AccessCloudflare(TypedDict, total=False): AccessGoogleApps, AccessLinkedin, AccessOIDC, + AccessDuo, AccessOkta, AccessOnelogin, AccessPingone, @@ -793,4 +893,5 @@ class AccessCloudflare(TypedDict, total=False): AccessYandex, AccessOnetimepin, AccessCloudflare, + AccessPasskeys, ] diff --git a/src/cloudflare/types/zero_trust/identity_provider_type.py b/src/cloudflare/types/zero_trust/identity_provider_type.py index 7dca466f5cb..b52530ecbb7 100644 --- a/src/cloudflare/types/zero_trust/identity_provider_type.py +++ b/src/cloudflare/types/zero_trust/identity_provider_type.py @@ -15,9 +15,11 @@ "google", "linkedin", "oidc", + "duo", "okta", "onelogin", "pingone", "yandex", "cloudflare", + "passkeys", ] diff --git a/src/cloudflare/types/zero_trust/identity_provider_update_params.py b/src/cloudflare/types/zero_trust/identity_provider_update_params.py index ec79694f10f..dddb5dd579f 100644 --- a/src/cloudflare/types/zero_trust/identity_provider_update_params.py +++ b/src/cloudflare/types/zero_trust/identity_provider_update_params.py @@ -25,6 +25,8 @@ "AccessLinkedin", "AccessOIDC", "AccessOIDCConfig", + "AccessDuo", + "AccessDuoConfig", "AccessOkta", "AccessOktaConfig", "AccessOnelogin", @@ -39,6 +41,8 @@ "AccessOnetimepinConfig", "AccessCloudflare", "AccessCloudflareConfig", + "AccessPasskeys", + "AccessPasskeysConfig", ] @@ -504,6 +508,61 @@ class AccessOIDCConfig(TypedDict, total=False): """The token_endpoint URL of your IdP""" +class AccessDuo(TypedDict, total=False): + config: Required[AccessDuoConfig] + """The configuration parameters for the identity provider. + + To view the required parameters for a specific provider, refer to our + [developer documentation](https://developers.cloudflare.com/cloudflare-one/identity/idp-integration/). + """ + + name: Required[str] + """The name of the identity provider, shown to users on the login page.""" + + type: Required[IdentityProviderType] + """The type of identity provider. + + To determine the value for a specific provider, refer to our + [developer documentation](https://developers.cloudflare.com/cloudflare-one/identity/idp-integration/). + """ + + account_id: str + """The Account ID to use for this endpoint. Mutually exclusive with the Zone ID.""" + + zone_id: str + """The Zone ID to use for this endpoint. Mutually exclusive with the Account ID.""" + + saml_certificate_set_id: str + """ + The UID of the SAML encryption certificate set assigned to this Identity + Provider. Only present for SAML identity providers with encryption configured. + Create a certificate set via POST to + `/identity_providers/{id}/saml_certificate`. + """ + + scim_config: IdentityProviderSCIMConfigParam + """ + The configuration settings for enabling a System for Cross-Domain Identity + Management (SCIM) with the identity provider. + """ + + +class AccessDuoConfig(TypedDict, total=False): + """The configuration parameters for the identity provider. + + To view the required parameters for a specific provider, refer to our [developer documentation](https://developers.cloudflare.com/cloudflare-one/identity/idp-integration/). + """ + + client_id: str + """The client ID from the Duo Generic OIDC Relying Party metadata.""" + + client_secret: str + """The client secret from the Duo Generic OIDC Relying Party metadata.""" + + issuer_url: str + """The issuer URL from the Duo Generic OIDC Relying Party metadata.""" + + class AccessOkta(TypedDict, total=False): config: Required[AccessOktaConfig] """The configuration parameters for the identity provider. @@ -942,6 +1001,58 @@ class AccessCloudflareConfig(TypedDict, total=False): """ +class AccessPasskeys(TypedDict, total=False): + config: Required[AccessPasskeysConfig] + """The configuration parameters for the identity provider. + + To view the required parameters for a specific provider, refer to our + [developer documentation](https://developers.cloudflare.com/cloudflare-one/identity/idp-integration/). + """ + + name: Required[str] + """The name of the identity provider, shown to users on the login page.""" + + type: Required[IdentityProviderType] + """The type of identity provider. + + To determine the value for a specific provider, refer to our + [developer documentation](https://developers.cloudflare.com/cloudflare-one/identity/idp-integration/). + """ + + account_id: str + """The Account ID to use for this endpoint. Mutually exclusive with the Zone ID.""" + + zone_id: str + """The Zone ID to use for this endpoint. Mutually exclusive with the Account ID.""" + + saml_certificate_set_id: str + """ + The UID of the SAML encryption certificate set assigned to this Identity + Provider. Only present for SAML identity providers with encryption configured. + Create a certificate set via POST to + `/identity_providers/{id}/saml_certificate`. + """ + + scim_config: IdentityProviderSCIMConfigParam + """ + The configuration settings for enabling a System for Cross-Domain Identity + Management (SCIM) with the identity provider. + """ + + +class AccessPasskeysConfig(TypedDict, total=False): + """The configuration parameters for the identity provider. + + To view the required parameters for a specific provider, refer to our [developer documentation](https://developers.cloudflare.com/cloudflare-one/identity/idp-integration/). + """ + + login_page_auto_prompt: bool + """ + When enabled, the Access login page automatically prompts the user to + authenticate with a passkey. + """ + + IdentityProviderUpdateParams: TypeAlias = Union[ AzureAD, AccessCentrify, @@ -951,6 +1062,7 @@ class AccessCloudflareConfig(TypedDict, total=False): AccessGoogleApps, AccessLinkedin, AccessOIDC, + AccessDuo, AccessOkta, AccessOnelogin, AccessPingone, @@ -958,4 +1070,5 @@ class AccessCloudflareConfig(TypedDict, total=False): AccessYandex, AccessOnetimepin, AccessCloudflare, + AccessPasskeys, ] diff --git a/src/cloudflare/types/zero_trust/identity_providers/scim/__init__.py b/src/cloudflare/types/zero_trust/identity_providers/scim/__init__.py index f050b879af4..d588d8b9087 100644 --- a/src/cloudflare/types/zero_trust/identity_providers/scim/__init__.py +++ b/src/cloudflare/types/zero_trust/identity_providers/scim/__init__.py @@ -4,3 +4,4 @@ from .user_list_params import UserListParams as UserListParams from .group_list_params import GroupListParams as GroupListParams +from .group_get_response import GroupGetResponse as GroupGetResponse diff --git a/src/cloudflare/types/zero_trust/identity_providers/scim/group_get_response.py b/src/cloudflare/types/zero_trust/identity_providers/scim/group_get_response.py new file mode 100644 index 00000000000..aee1752ba62 --- /dev/null +++ b/src/cloudflare/types/zero_trust/identity_providers/scim/group_get_response.py @@ -0,0 +1,57 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional +from datetime import datetime +from typing_extensions import Literal + +from pydantic import Field as FieldInfo + +from ....._models import BaseModel + +__all__ = ["GroupGetResponse", "Member", "Meta"] + + +class Member(BaseModel): + value: str + """The unique Cloudflare-generated Id of the member resource.""" + + ref: Optional[str] = FieldInfo(alias="$ref", default=None) + """The URI of the member resource.""" + + display: Optional[str] = None + """The display name of the member resource.""" + + type: Optional[Literal["User", "Group"]] = None + """The SCIM resource type of the member.""" + + +class Meta(BaseModel): + """The metadata of the SCIM resource.""" + + created: Optional[datetime] = None + """The timestamp of when the SCIM resource was created.""" + + last_modified: Optional[datetime] = FieldInfo(alias="lastModified", default=None) + """The timestamp of when the SCIM resource was last modified.""" + + +class GroupGetResponse(BaseModel): + id: Optional[str] = None + """The unique Cloudflare-generated Id of the SCIM resource.""" + + display_name: Optional[str] = FieldInfo(alias="displayName", default=None) + """The display name of the SCIM Group resource.""" + + external_id: Optional[str] = FieldInfo(alias="externalId", default=None) + """The IdP-generated Id of the SCIM resource.""" + + members: Optional[List[Member]] = None + """The direct members of the SCIM Group resource.""" + + meta: Optional[Meta] = None + """The metadata of the SCIM resource.""" + + schemas: Optional[List[str]] = None + """ + The list of URIs which indicate the attributes contained within a SCIM resource. + """ diff --git a/src/cloudflare/types/zero_trust/organization.py b/src/cloudflare/types/zero_trust/organization.py index 49da381d460..c040a5169ff 100644 --- a/src/cloudflare/types/zero_trust/organization.py +++ b/src/cloudflare/types/zero_trust/organization.py @@ -115,7 +115,11 @@ class Organization(BaseModel): """ auth_domain: Optional[str] = None - """The unique subdomain assigned to your Zero Trust organization.""" + """The unique subdomain assigned to your Zero Trust organization. + + If omitted on creation, a unique subdomain is auto-generated in the format + `adjective-noun-hex4` (e.g. `frosty-moon-7a3b.cloudflareaccess.com`). + """ auto_redirect_to_identity: Optional[bool] = None """ @@ -142,6 +146,9 @@ class Organization(BaseModel): the request. """ + disable_end_user_app_creation: Optional[bool] = None + """Whether creation of end user applications is disabled for this organization.""" + is_ui_read_only: Optional[bool] = None """Lock all settings as Read-Only in the Dashboard, regardless of user permission. @@ -166,7 +173,11 @@ class Organization(BaseModel): """ name: Optional[str] = None - """The name of your Zero Trust organization.""" + """The name of your Zero Trust organization. + + When omitted on creation, defaults to the provided auth_domain; when both are + omitted, defaults to the auto-generated subdomain slug (e.g. frosty-moon-7a3b). + """ service_token_inactivity: Optional[ServiceTokenInactivity] = None """Configures automatic enforcement for inactive service tokens. diff --git a/src/cloudflare/types/zero_trust/organization_create_params.py b/src/cloudflare/types/zero_trust/organization_create_params.py index 7fac410a07d..fe2fc1fa8e3 100644 --- a/src/cloudflare/types/zero_trust/organization_create_params.py +++ b/src/cloudflare/types/zero_trust/organization_create_params.py @@ -12,12 +12,6 @@ class OrganizationCreateParams(TypedDict, total=False): - auth_domain: Required[str] - """The unique subdomain assigned to your Zero Trust organization.""" - - name: Required[str] - """The name of your Zero Trust organization.""" - account_id: str """The Account ID to use for this endpoint. Mutually exclusive with the Zone ID.""" @@ -30,6 +24,13 @@ class OrganizationCreateParams(TypedDict, total=False): organization. Application settings will take precedence over this value. """ + auth_domain: str + """The unique subdomain assigned to your Zero Trust organization. + + If omitted on creation, a unique subdomain is auto-generated in the format + `adjective-noun-hex4` (e.g. `frosty-moon-7a3b.cloudflareaccess.com`). + """ + auto_redirect_to_identity: bool """ When set to `true`, users skip the identity provider selection step during @@ -53,6 +54,9 @@ class OrganizationCreateParams(TypedDict, total=False): the request. """ + disable_end_user_app_creation: bool + """Whether creation of end user applications is disabled for this organization.""" + is_ui_read_only: bool """Lock all settings as Read-Only in the Dashboard, regardless of user permission. @@ -76,6 +80,13 @@ class OrganizationCreateParams(TypedDict, total=False): the organization has any non-infrastructure applications. """ + name: str + """The name of your Zero Trust organization. + + When omitted on creation, defaults to the provided auth_domain; when both are + omitted, defaults to the auto-generated subdomain slug (e.g. frosty-moon-7a3b). + """ + service_token_inactivity: ServiceTokenInactivity """Configures automatic enforcement for inactive service tokens. diff --git a/src/cloudflare/types/zero_trust/organization_list_response.py b/src/cloudflare/types/zero_trust/organization_list_response.py index 48358350ca3..6610773eeb6 100644 --- a/src/cloudflare/types/zero_trust/organization_list_response.py +++ b/src/cloudflare/types/zero_trust/organization_list_response.py @@ -115,7 +115,11 @@ class OrganizationListResponse(BaseModel): """ auth_domain: Optional[str] = None - """The unique subdomain assigned to your Zero Trust organization.""" + """The unique subdomain assigned to your Zero Trust organization. + + If omitted on creation, a unique subdomain is auto-generated in the format + `adjective-noun-hex4` (e.g. `frosty-moon-7a3b.cloudflareaccess.com`). + """ auto_redirect_to_identity: Optional[bool] = None """ @@ -142,6 +146,9 @@ class OrganizationListResponse(BaseModel): the request. """ + disable_end_user_app_creation: Optional[bool] = None + """Whether creation of end user applications is disabled for this organization.""" + is_ui_read_only: Optional[bool] = None """Lock all settings as Read-Only in the Dashboard, regardless of user permission. @@ -166,7 +173,11 @@ class OrganizationListResponse(BaseModel): """ name: Optional[str] = None - """The name of your Zero Trust organization.""" + """The name of your Zero Trust organization. + + When omitted on creation, defaults to the provided auth_domain; when both are + omitted, defaults to the auto-generated subdomain slug (e.g. frosty-moon-7a3b). + """ service_token_inactivity: Optional[ServiceTokenInactivity] = None """Configures automatic enforcement for inactive service tokens. diff --git a/src/cloudflare/types/zero_trust/organization_update_params.py b/src/cloudflare/types/zero_trust/organization_update_params.py index 6367e48e4cd..1093618cf73 100644 --- a/src/cloudflare/types/zero_trust/organization_update_params.py +++ b/src/cloudflare/types/zero_trust/organization_update_params.py @@ -25,7 +25,11 @@ class OrganizationUpdateParams(TypedDict, total=False): """ auth_domain: str - """The unique subdomain assigned to your Zero Trust organization.""" + """The unique subdomain assigned to your Zero Trust organization. + + If omitted on creation, a unique subdomain is auto-generated in the format + `adjective-noun-hex4` (e.g. `frosty-moon-7a3b.cloudflareaccess.com`). + """ auto_redirect_to_identity: bool """ @@ -52,6 +56,9 @@ class OrganizationUpdateParams(TypedDict, total=False): the request. """ + disable_end_user_app_creation: bool + """Whether creation of end user applications is disabled for this organization.""" + is_ui_read_only: bool """Lock all settings as Read-Only in the Dashboard, regardless of user permission. @@ -76,7 +83,11 @@ class OrganizationUpdateParams(TypedDict, total=False): """ name: str - """The name of your Zero Trust organization.""" + """The name of your Zero Trust organization. + + When omitted on creation, defaults to the provided auth_domain; when both are + omitted, defaults to the auto-generated subdomain slug (e.g. frosty-moon-7a3b). + """ service_token_inactivity: ServiceTokenInactivity """Configures automatic enforcement for inactive service tokens. diff --git a/src/cloudflare/types/zero_trust/organizations/doh_get_response.py b/src/cloudflare/types/zero_trust/organizations/doh_get_response.py index 6c1ccb40a7c..ac2b17d68b4 100644 --- a/src/cloudflare/types/zero_trust/organizations/doh_get_response.py +++ b/src/cloudflare/types/zero_trust/organizations/doh_get_response.py @@ -1,6 +1,6 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import Optional +from typing import Dict, Optional from datetime import datetime from ...._models import BaseModel @@ -39,10 +39,38 @@ class DOHGetResponse(BaseModel): A disabled service token cannot be used to authenticate; both its current and previous `client_secret` stop being accepted, but the token itself is preserved - and can be re-enabled at any time. Defaults to enabled when omitted on create. + and can be re-enabled. A service token reported as leaked is disabled + automatically and cannot be re-enabled until its secret is rotated; attempting + to do so returns a 409. Defaults to enabled when omitted on create. """ expires_at: Optional[datetime] = None + leak_report_url: Optional[str] = None + """Where the leaked `client_secret` was found, if provided by the reporter. + + Omitted if the token has not been reported as leaked. + """ + + leak_reported_at: Optional[datetime] = None + """ + When a secret scanning partner reported this service token's `client_secret` as + leaked. A leaked service token is disabled and must be rotated before it can be + re-enabled. Cleared once the secret is rotated. Omitted if the token has not + been reported as leaked. + """ + + leak_reporter: Optional[str] = None + """The secret scanning partner that reported the leak. + + Omitted if the token has not been reported as leaked. + """ + name: Optional[str] = None """The name of the service token.""" + + tags: Optional[Dict[str, str]] = None + """Tags associated with the service token, as key-value pairs. + + On update, replaces all existing tags. + """ diff --git a/src/cloudflare/types/zero_trust/organizations/doh_update_response.py b/src/cloudflare/types/zero_trust/organizations/doh_update_response.py index 3817116e567..f11da386b7c 100644 --- a/src/cloudflare/types/zero_trust/organizations/doh_update_response.py +++ b/src/cloudflare/types/zero_trust/organizations/doh_update_response.py @@ -1,6 +1,6 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import Optional +from typing import Dict, Optional from datetime import datetime from ...._models import BaseModel @@ -39,10 +39,38 @@ class DOHUpdateResponse(BaseModel): A disabled service token cannot be used to authenticate; both its current and previous `client_secret` stop being accepted, but the token itself is preserved - and can be re-enabled at any time. Defaults to enabled when omitted on create. + and can be re-enabled. A service token reported as leaked is disabled + automatically and cannot be re-enabled until its secret is rotated; attempting + to do so returns a 409. Defaults to enabled when omitted on create. """ expires_at: Optional[datetime] = None + leak_report_url: Optional[str] = None + """Where the leaked `client_secret` was found, if provided by the reporter. + + Omitted if the token has not been reported as leaked. + """ + + leak_reported_at: Optional[datetime] = None + """ + When a secret scanning partner reported this service token's `client_secret` as + leaked. A leaked service token is disabled and must be rotated before it can be + re-enabled. Cleared once the secret is rotated. Omitted if the token has not + been reported as leaked. + """ + + leak_reporter: Optional[str] = None + """The secret scanning partner that reported the leak. + + Omitted if the token has not been reported as leaked. + """ + name: Optional[str] = None """The name of the service token.""" + + tags: Optional[Dict[str, str]] = None + """Tags associated with the service token, as key-value pairs. + + On update, replaces all existing tags. + """ diff --git a/src/cloudflare/types/zero_trust/resource_library/application_create_params.py b/src/cloudflare/types/zero_trust/resource_library/application_create_params.py index 6cb8ae95bde..84fa11dbe9c 100644 --- a/src/cloudflare/types/zero_trust/resource_library/application_create_params.py +++ b/src/cloudflare/types/zero_trust/resource_library/application_create_params.py @@ -17,10 +17,10 @@ class Variant0(TypedDict, total=False): """Hostnames matched by the application.""" category_id: int - """Returns the category ID.""" + """Numeric identifier for an application category.""" human_id: str - """Returns the human readable ID.""" + """Human-readable identifier for the application.""" ip_subnets: SequenceNotStr[str] """IP subnets for this application. @@ -30,10 +30,14 @@ class Variant0(TypedDict, total=False): """ name: str - """Returns the application name.""" + """Application name.""" port_protocols: SequenceNotStr[str] - """Port and protocol pairs matched by the application.""" + """ + Ports matched by the application, in `protocol/port` or inclusive + `protocol/start-end` format (for example, `tcp/443` or `udp/10000-20000`). TCP + and UDP ports must be between 0 and 65535. + """ support_domains: SequenceNotStr[str] """Support domains matched by the application.""" @@ -50,19 +54,23 @@ class Variant1(TypedDict, total=False): """ category_id: int - """Returns the category ID.""" + """Numeric identifier for an application category.""" hostnames: SequenceNotStr[str] """Hostnames matched by the application.""" human_id: str - """Returns the human readable ID.""" + """Human-readable identifier for the application.""" name: str - """Returns the application name.""" + """Application name.""" port_protocols: SequenceNotStr[str] - """Port and protocol pairs matched by the application.""" + """ + Ports matched by the application, in `protocol/port` or inclusive + `protocol/start-end` format (for example, `tcp/443` or `udp/10000-20000`). TCP + and UDP ports must be between 0 and 65535. + """ support_domains: SequenceNotStr[str] """Support domains matched by the application.""" diff --git a/src/cloudflare/types/zero_trust/resource_library/application_create_response.py b/src/cloudflare/types/zero_trust/resource_library/application_create_response.py index 9b2e71589a2..46b5a73d750 100644 --- a/src/cloudflare/types/zero_trust/resource_library/application_create_response.py +++ b/src/cloudflare/types/zero_trust/resource_library/application_create_response.py @@ -10,7 +10,7 @@ class ApplicationCreateResponse(BaseModel): id: int - """Returns the application ID.""" + """Numeric identifier for the application.""" application_confidence_score: float """Confidence score for the application. Returns -1 when no score is available.""" @@ -25,7 +25,7 @@ class ApplicationCreateResponse(BaseModel): """Returns the application type description.""" category_id: int - """Returns the category ID.""" + """Numeric identifier for an application category.""" created_at: str """Returns the application creation time.""" @@ -37,7 +37,7 @@ class ApplicationCreateResponse(BaseModel): """Hostnames matched by the application.""" human_id: str - """Returns the human readable ID.""" + """Human-readable identifier for the application.""" ip_subnets: List[str] """IP subnets for this application. @@ -47,10 +47,14 @@ class ApplicationCreateResponse(BaseModel): """ name: str - """Returns the application name.""" + """Application name.""" port_protocols: List[str] - """Port and protocol pairs matched by the application.""" + """ + Ports matched by the application, in `protocol/port` or inclusive + `protocol/start-end` format (for example, `tcp/443` or `udp/10000-20000`). TCP + and UDP ports must be between 0 and 65535. + """ support_domains: List[str] """Support domains matched by the application.""" diff --git a/src/cloudflare/types/zero_trust/resource_library/application_get_response.py b/src/cloudflare/types/zero_trust/resource_library/application_get_response.py index 2d3d3cac442..24349ed58e4 100644 --- a/src/cloudflare/types/zero_trust/resource_library/application_get_response.py +++ b/src/cloudflare/types/zero_trust/resource_library/application_get_response.py @@ -10,7 +10,7 @@ class ApplicationGetResponse(BaseModel): id: int - """Returns the application ID.""" + """Numeric identifier for the application.""" application_confidence_score: float """Confidence score for the application. Returns -1 when no score is available.""" @@ -25,7 +25,7 @@ class ApplicationGetResponse(BaseModel): """Returns the application type description.""" category_id: int - """Returns the category ID.""" + """Numeric identifier for an application category.""" created_at: str """Returns the application creation time.""" @@ -37,7 +37,7 @@ class ApplicationGetResponse(BaseModel): """Hostnames matched by the application.""" human_id: str - """Returns the human readable ID.""" + """Human-readable identifier for the application.""" ip_subnets: List[str] """IP subnets for this application. @@ -47,10 +47,14 @@ class ApplicationGetResponse(BaseModel): """ name: str - """Returns the application name.""" + """Application name.""" port_protocols: List[str] - """Port and protocol pairs matched by the application.""" + """ + Ports matched by the application, in `protocol/port` or inclusive + `protocol/start-end` format (for example, `tcp/443` or `udp/10000-20000`). TCP + and UDP ports must be between 0 and 65535. + """ support_domains: List[str] """Support domains matched by the application.""" diff --git a/src/cloudflare/types/zero_trust/resource_library/application_list_params.py b/src/cloudflare/types/zero_trust/resource_library/application_list_params.py index b5223e67401..6846b92d4bd 100644 --- a/src/cloudflare/types/zero_trust/resource_library/application_list_params.py +++ b/src/cloudflare/types/zero_trust/resource_library/application_list_params.py @@ -10,14 +10,24 @@ class ApplicationListParams(TypedDict, total=False): account_id: Required[str] + cursor: str + """Opaque value from `result_info.cursor` of the previous response. + + Returns the results that follow it. Send the same `filter`, `search`, `lookup`, + and `order_by` values as the request that returned it; `limit` and `fields` may + change. An empty value is the same as no cursor. A modified cursor, or one used + with different values, returns `400`. + """ + fields: str """ Return only the listed properties on each application, as a comma-separated list. Use this to keep responses small when you only need part of each - application — for example populating a picker with `fields=id,name` instead of + application, for example populating a picker with `fields=id,name` instead of downloading every hostname and IP subnet. - Omit this parameter to receive the full application object. + Omit this parameter to receive the full application object, including when + lookup is used. `id` is always returned. @@ -29,30 +39,45 @@ class ApplicationListParams(TypedDict, total=False): """ filter: str - """Filter applications using key:value format. Supported filter keys: - - - name: Filter by application name (e.g., name:HR) - - id: Filter by application ID (e.g., id:498) - - human_id: Filter by human-readable ID (e.g., human_id:HR) - - hostname: Filter by hostname or support domain (e.g., - hostname:portal.example.com) - - source: Filter by application source name (e.g., source:cloudflare) - - ip_subnet: Filter by IP subnet using CIDR containment — returns applications - where any stored subnet contains the search value (e.g., ip_subnet:10.0.1.5/32 - matches apps with 10.0.0.0/16) - - category_id: Filter by category ID (e.g., category_id:12). - - category_name: Filter by category name (e.g., category_name:HR). - - supported: Filter by supported Cloudflare product (e.g., supported:ACCESS). - Values: GATEWAY, ACCESS, CASB. - - review_status: Filter by the account's Gateway review status. Values: - approved, unapproved, in_review, unreviewed. . + """Filter applications using `key:value` format. Supported filter keys: + + - `name`: application name (for example, `name:HR`). + - `id`: application ID (for example, `id:498`). + - `human_id`: human-readable ID (for example, `human_id:HR`). + - `hostname`: hostname or support domain (for example, + `hostname:portal.example.com`). + - `source`: application source name (for example, `source:cloudflare`). + - `ip_subnet`: CIDR containment; returns applications where a stored subnet + contains the search value (for example, `ip_subnet:10.0.1.5/32` matches + `10.0.0.0/16`). + - `category_id`: category ID (for example, `category_id:12`). + - `category_name`: category name (for example, `category_name:HR`). + - `supported`: supported Cloudflare product. Values: `GATEWAY`, `ACCESS`, + `CASB`. + - `review_status`: account-specific Gateway review status. Values: `approved`, + `unapproved`, `in_review`, `unreviewed`. """ limit: int - """Limit of number of results to return (max 250).""" + """Number of results to return. Defaults to 25; values are clamped to 1–250.""" + + lookup: str + """ + Find complete, case-insensitive application name mentions in a phrase or rule + sentence. Misspelled names do not match. Returns matching applications ranked by + relevance. Must be between 2 and 1000 characters, with no control characters + other than tab and line breaks. Uses the same filters, fields, and pagination as + listing. `search` cannot be combined with lookup. Results are ranked by + relevance, so `order_by` is ignored. To keep the text out of URLs, send it to + `POST .../applications/lookup` instead. + """ offset: int - """Offset of results to return.""" + """Number of results to skip. + + Defaults to 0; negative values are clamped to 0. Ignored when `cursor` is + provided. + """ order_by: str """Order results using field:direction format. @@ -60,6 +85,7 @@ class ApplicationListParams(TypedDict, total=False): Supported fields are name, id, human_id, category_id, application_type, application_confidence_score, and gen_ai_score. Supported directions are asc and desc. Ignored when search is provided; results are ranked by relevance instead. + Also ignored when lookup is provided. """ search: str diff --git a/src/cloudflare/types/zero_trust/resource_library/application_list_response.py b/src/cloudflare/types/zero_trust/resource_library/application_list_response.py index f1412d10ab0..dea61d47355 100644 --- a/src/cloudflare/types/zero_trust/resource_library/application_list_response.py +++ b/src/cloudflare/types/zero_trust/resource_library/application_list_response.py @@ -11,11 +11,11 @@ class ApplicationListResponse(BaseModel): """Describes one application in a list response. - This endpoint returns every property below unless the `fields` query parameter narrows the response, so treat all of them except `id` as optional. + The response returns every property below unless `fields` narrows it. Treat all properties except `id` as optional. """ id: int - """Returns the application ID.""" + """Numeric identifier for the application.""" application_confidence_score: Optional[float] = None """Confidence score for the application. Returns -1 when no score is available.""" @@ -33,7 +33,7 @@ class ApplicationListResponse(BaseModel): """Returns the application type description.""" category_id: Optional[int] = None - """Returns the category ID.""" + """Numeric identifier for an application category.""" created_at: Optional[str] = None """Returns the application creation time.""" @@ -45,7 +45,7 @@ class ApplicationListResponse(BaseModel): """Hostnames matched by the application.""" human_id: Optional[str] = None - """Returns the human readable ID.""" + """Human-readable identifier for the application.""" ip_subnets: Optional[List[str]] = None """IP subnets for this application. @@ -55,10 +55,14 @@ class ApplicationListResponse(BaseModel): """ name: Optional[str] = None - """Returns the application name.""" + """Application name.""" port_protocols: Optional[List[str]] = None - """Port and protocol pairs matched by the application.""" + """ + Ports matched by the application, in `protocol/port` or inclusive + `protocol/start-end` format (for example, `tcp/443` or `udp/10000-20000`). TCP + and UDP ports must be between 0 and 65535. + """ review_status: Optional[Literal["approved", "unapproved", "in_review", "unreviewed"]] = None """The account-specific Gateway review status. diff --git a/src/cloudflare/types/zero_trust/resource_library/application_update_params.py b/src/cloudflare/types/zero_trust/resource_library/application_update_params.py index 82b1ed2dc19..762ed245986 100644 --- a/src/cloudflare/types/zero_trust/resource_library/application_update_params.py +++ b/src/cloudflare/types/zero_trust/resource_library/application_update_params.py @@ -23,7 +23,11 @@ class ApplicationUpdateParams(TypedDict, total=False): """ port_protocols: SequenceNotStr[str] - """Port and protocol pairs matched by the application.""" + """ + Ports matched by the application, in `protocol/port` or inclusive + `protocol/start-end` format (for example, `tcp/443` or `udp/10000-20000`). TCP + and UDP ports must be between 0 and 65535. + """ support_domains: SequenceNotStr[str] """Support domains matched by the application.""" diff --git a/src/cloudflare/types/zero_trust/resource_library/application_update_response.py b/src/cloudflare/types/zero_trust/resource_library/application_update_response.py index 730d3053383..c2cc5a488f6 100644 --- a/src/cloudflare/types/zero_trust/resource_library/application_update_response.py +++ b/src/cloudflare/types/zero_trust/resource_library/application_update_response.py @@ -10,7 +10,7 @@ class ApplicationUpdateResponse(BaseModel): id: int - """Returns the application ID.""" + """Numeric identifier for the application.""" application_confidence_score: float """Confidence score for the application. Returns -1 when no score is available.""" @@ -25,7 +25,7 @@ class ApplicationUpdateResponse(BaseModel): """Returns the application type description.""" category_id: int - """Returns the category ID.""" + """Numeric identifier for an application category.""" created_at: str """Returns the application creation time.""" @@ -37,7 +37,7 @@ class ApplicationUpdateResponse(BaseModel): """Hostnames matched by the application.""" human_id: str - """Returns the human readable ID.""" + """Human-readable identifier for the application.""" ip_subnets: List[str] """IP subnets for this application. @@ -47,10 +47,14 @@ class ApplicationUpdateResponse(BaseModel): """ name: str - """Returns the application name.""" + """Application name.""" port_protocols: List[str] - """Port and protocol pairs matched by the application.""" + """ + Ports matched by the application, in `protocol/port` or inclusive + `protocol/start-end` format (for example, `tcp/443` or `udp/10000-20000`). TCP + and UDP ports must be between 0 and 65535. + """ support_domains: List[str] """Support domains matched by the application.""" diff --git a/src/cloudflare/types/zero_trust/resource_library/category_get_response.py b/src/cloudflare/types/zero_trust/resource_library/category_get_response.py index 2b9d4a0090b..075a3240965 100644 --- a/src/cloudflare/types/zero_trust/resource_library/category_get_response.py +++ b/src/cloudflare/types/zero_trust/resource_library/category_get_response.py @@ -7,7 +7,7 @@ class CategoryGetResponse(BaseModel): id: int - """Returns the category ID.""" + """Numeric identifier for an application category.""" created_at: str """Returns the category creation time.""" diff --git a/src/cloudflare/types/zero_trust/resource_library/category_list_params.py b/src/cloudflare/types/zero_trust/resource_library/category_list_params.py index 5d80d7606f3..fd64bcbe9cb 100644 --- a/src/cloudflare/types/zero_trust/resource_library/category_list_params.py +++ b/src/cloudflare/types/zero_trust/resource_library/category_list_params.py @@ -10,8 +10,20 @@ class CategoryListParams(TypedDict, total=False): account_id: Required[str] + cursor: str + """Opaque value from `result_info.cursor` of the previous response. + + Returns the categories that follow it. `limit` may change between requests. An + empty value is the same as no cursor. A modified cursor, or one returned by a + different list, returns `400`. + """ + limit: int - """Limit of number of results to return.""" + """Number of results to return. Defaults to 25; values are clamped to 1–250.""" offset: int - """Offset of results to return.""" + """Number of results to skip. + + Defaults to 0; negative values are clamped to 0. Ignored when `cursor` is + provided. + """ diff --git a/src/cloudflare/types/zero_trust/resource_library/category_list_response.py b/src/cloudflare/types/zero_trust/resource_library/category_list_response.py index 99ec4a8344e..6cf6dc2598b 100644 --- a/src/cloudflare/types/zero_trust/resource_library/category_list_response.py +++ b/src/cloudflare/types/zero_trust/resource_library/category_list_response.py @@ -7,7 +7,7 @@ class CategoryListResponse(BaseModel): id: int - """Returns the category ID.""" + """Numeric identifier for an application category.""" created_at: str """Returns the category creation time.""" diff --git a/src/cloudflare/types/zero_trust/risk_scoring/behaviour_get_response.py b/src/cloudflare/types/zero_trust/risk_scoring/behaviour_get_response.py index b5689e1087b..9752c39f4b0 100644 --- a/src/cloudflare/types/zero_trust/risk_scoring/behaviour_get_response.py +++ b/src/cloudflare/types/zero_trust/risk_scoring/behaviour_get_response.py @@ -15,7 +15,7 @@ class Behaviors(BaseModel): name: str - risk_level: Literal["low", "medium", "high"] + risk_level: Literal["info", "low", "medium", "high"] class BehaviourGetResponse(BaseModel): diff --git a/src/cloudflare/types/zero_trust/risk_scoring/behaviour_update_params.py b/src/cloudflare/types/zero_trust/risk_scoring/behaviour_update_params.py index 6caa1e31244..70fe988c22b 100644 --- a/src/cloudflare/types/zero_trust/risk_scoring/behaviour_update_params.py +++ b/src/cloudflare/types/zero_trust/risk_scoring/behaviour_update_params.py @@ -17,4 +17,4 @@ class BehaviourUpdateParams(TypedDict, total=False): class Behaviors(TypedDict, total=False): enabled: Required[bool] - risk_level: Required[Literal["low", "medium", "high"]] + risk_level: Required[Literal["info", "low", "medium", "high"]] diff --git a/src/cloudflare/types/zero_trust/risk_scoring/behaviour_update_response.py b/src/cloudflare/types/zero_trust/risk_scoring/behaviour_update_response.py index bf4b13b3235..b60c334d962 100644 --- a/src/cloudflare/types/zero_trust/risk_scoring/behaviour_update_response.py +++ b/src/cloudflare/types/zero_trust/risk_scoring/behaviour_update_response.py @@ -11,7 +11,7 @@ class Behaviors(BaseModel): enabled: bool - risk_level: Literal["low", "medium", "high"] + risk_level: Literal["info", "low", "medium", "high"] class BehaviourUpdateResponse(BaseModel): diff --git a/src/cloudflare/types/zero_trust/risk_scoring/summary_get_response.py b/src/cloudflare/types/zero_trust/risk_scoring/summary_get_response.py index d8140100e25..0afd2e8a500 100644 --- a/src/cloudflare/types/zero_trust/risk_scoring/summary_get_response.py +++ b/src/cloudflare/types/zero_trust/risk_scoring/summary_get_response.py @@ -16,7 +16,7 @@ class User(BaseModel): last_event: datetime - max_risk_level: Literal["low", "medium", "high"] + max_risk_level: Literal["info", "low", "medium", "high"] name: str diff --git a/src/cloudflare/types/zero_trust/risk_scoring_get_response.py b/src/cloudflare/types/zero_trust/risk_scoring_get_response.py index 5fd47373074..3e782133c56 100644 --- a/src/cloudflare/types/zero_trust/risk_scoring_get_response.py +++ b/src/cloudflare/types/zero_trust/risk_scoring_get_response.py @@ -14,7 +14,7 @@ class Event(BaseModel): name: str - risk_level: Literal["low", "medium", "high"] + risk_level: Literal["info", "low", "medium", "high"] timestamp: datetime @@ -30,4 +30,4 @@ class RiskScoringGetResponse(BaseModel): last_reset_time: Optional[datetime] = None - risk_level: Optional[Literal["low", "medium", "high"]] = None + risk_level: Optional[Literal["info", "low", "medium", "high"]] = None diff --git a/src/cloudflare/types/zero_trust/tunnel_list_response.py b/src/cloudflare/types/zero_trust/tunnel_list_response.py index 691e2bc77d7..9e76574d8e0 100644 --- a/src/cloudflare/types/zero_trust/tunnel_list_response.py +++ b/src/cloudflare/types/zero_trust/tunnel_list_response.py @@ -42,7 +42,7 @@ class TunnelWARPConnectorTunnelConnection(BaseModel): class TunnelWARPConnectorTunnel(BaseModel): - """A Warp Connector Tunnel that connects your origin to Cloudflare's edge.""" + """A Mesh node that connects your origin to Cloudflare's edge.""" id: Optional[str] = None """UUID of the tunnel.""" diff --git a/src/cloudflare/types/zero_trust/tunnels/warp_connector/configuration_get_response.py b/src/cloudflare/types/zero_trust/tunnels/warp_connector/configuration_get_response.py index ec7a21f96fc..24024fc9199 100644 --- a/src/cloudflare/types/zero_trust/tunnels/warp_connector/configuration_get_response.py +++ b/src/cloudflare/types/zero_trust/tunnels/warp_connector/configuration_get_response.py @@ -53,11 +53,11 @@ class ConfigurationGetResponse(BaseModel): """Timestamp of when the resource was created.""" ha_mode: Literal["none", "disabled", "aws", "local"] - """High-availability mode for the WARP Connector tunnel. + """High-availability mode for the Mesh node. `none` means HA is enabled but no provider is configured yet (newly created - tunnels default to this). `disabled` means HA is explicitly turned off. `aws` - uses AWS ENI move for failover. `local` uses virtual IPs (VIPs) on the local + nodes default to this). `disabled` means HA is explicitly turned off. `aws` uses + AWS ENI move for failover. `local` uses virtual IPs (VIPs) on the local interface. """ diff --git a/src/cloudflare/types/zero_trust/tunnels/warp_connector/configuration_update_params.py b/src/cloudflare/types/zero_trust/tunnels/warp_connector/configuration_update_params.py index ae57389e24a..a2d29e14022 100644 --- a/src/cloudflare/types/zero_trust/tunnels/warp_connector/configuration_update_params.py +++ b/src/cloudflare/types/zero_trust/tunnels/warp_connector/configuration_update_params.py @@ -20,11 +20,11 @@ class ConfigurationUpdateParams(TypedDict, total=False): """Identifier.""" ha_mode: Required[Literal["none", "disabled", "aws", "local"]] - """High-availability mode for the WARP Connector tunnel. + """High-availability mode for the Mesh node. `none` means HA is enabled but no provider is configured yet (newly created - tunnels default to this). `disabled` means HA is explicitly turned off. `aws` - uses AWS ENI move for failover. `local` uses virtual IPs (VIPs) on the local + nodes default to this). `disabled` means HA is explicitly turned off. `aws` uses + AWS ENI move for failover. `local` uses virtual IPs (VIPs) on the local interface. """ diff --git a/src/cloudflare/types/zero_trust/tunnels/warp_connector/configuration_update_response.py b/src/cloudflare/types/zero_trust/tunnels/warp_connector/configuration_update_response.py index 899c188b845..90f871bbd68 100644 --- a/src/cloudflare/types/zero_trust/tunnels/warp_connector/configuration_update_response.py +++ b/src/cloudflare/types/zero_trust/tunnels/warp_connector/configuration_update_response.py @@ -53,11 +53,11 @@ class ConfigurationUpdateResponse(BaseModel): """Timestamp of when the resource was created.""" ha_mode: Literal["none", "disabled", "aws", "local"] - """High-availability mode for the WARP Connector tunnel. + """High-availability mode for the Mesh node. `none` means HA is enabled but no provider is configured yet (newly created - tunnels default to this). `disabled` means HA is explicitly turned off. `aws` - uses AWS ENI move for failover. `local` uses virtual IPs (VIPs) on the local + nodes default to this). `disabled` means HA is explicitly turned off. `aws` uses + AWS ENI move for failover. `local` uses virtual IPs (VIPs) on the local interface. """ diff --git a/src/cloudflare/types/zero_trust/tunnels/warp_connector/connection_get_response.py b/src/cloudflare/types/zero_trust/tunnels/warp_connector/connection_get_response.py index f8597ba0133..3b48d737037 100644 --- a/src/cloudflare/types/zero_trust/tunnels/warp_connector/connection_get_response.py +++ b/src/cloudflare/types/zero_trust/tunnels/warp_connector/connection_get_response.py @@ -26,13 +26,11 @@ class Conn(BaseModel): """Timestamp of when the connection was established.""" origin_ip: Optional[str] = None - """The public IP address of the host running WARP Connector.""" + """The public IP address of the host running the Mesh node connector.""" class ConnectionGetResponse(BaseModel): - """ - A WARP Connector client that maintains a connection to a Cloudflare data center. - """ + """A Mesh node connector that maintains a connection to a Cloudflare data center.""" id: Optional[str] = None """UUID of the Cloudflare Tunnel connector.""" @@ -41,15 +39,13 @@ class ConnectionGetResponse(BaseModel): """The cloudflared OS architecture used to establish this connection.""" conns: Optional[List[Conn]] = None - """ - The WARP Connector Tunnel connections between your origin and Cloudflare's edge. - """ + """The Mesh node connections between your origin and Cloudflare's edge.""" features: Optional[List[str]] = None """Features enabled for the Cloudflare Tunnel.""" ha_status: Optional[Literal["offline", "passive", "active"]] = None - """The HA status of a WARP Connector client.""" + """The HA status of a Mesh node connector.""" run_at: Optional[datetime] = None """Timestamp of when the tunnel connection was started.""" diff --git a/src/cloudflare/types/zero_trust/tunnels/warp_connector/connector_get_response.py b/src/cloudflare/types/zero_trust/tunnels/warp_connector/connector_get_response.py index 6d566662c43..79c3a4e5f77 100644 --- a/src/cloudflare/types/zero_trust/tunnels/warp_connector/connector_get_response.py +++ b/src/cloudflare/types/zero_trust/tunnels/warp_connector/connector_get_response.py @@ -26,13 +26,11 @@ class Conn(BaseModel): """Timestamp of when the connection was established.""" origin_ip: Optional[str] = None - """The public IP address of the host running WARP Connector.""" + """The public IP address of the host running the Mesh node connector.""" class ConnectorGetResponse(BaseModel): - """ - A WARP Connector client that maintains a connection to a Cloudflare data center. - """ + """A Mesh node connector that maintains a connection to a Cloudflare data center.""" id: Optional[str] = None """UUID of the Cloudflare Tunnel connector.""" @@ -41,15 +39,13 @@ class ConnectorGetResponse(BaseModel): """The cloudflared OS architecture used to establish this connection.""" conns: Optional[List[Conn]] = None - """ - The WARP Connector Tunnel connections between your origin and Cloudflare's edge. - """ + """The Mesh node connections between your origin and Cloudflare's edge.""" features: Optional[List[str]] = None """Features enabled for the Cloudflare Tunnel.""" ha_status: Optional[Literal["offline", "passive", "active"]] = None - """The HA status of a WARP Connector client.""" + """The HA status of a Mesh node connector.""" run_at: Optional[datetime] = None """Timestamp of when the tunnel connection was started.""" diff --git a/src/cloudflare/types/zero_trust/tunnels/warp_connector_create_response.py b/src/cloudflare/types/zero_trust/tunnels/warp_connector_create_response.py index 23e7fea1232..be66b3effd6 100644 --- a/src/cloudflare/types/zero_trust/tunnels/warp_connector_create_response.py +++ b/src/cloudflare/types/zero_trust/tunnels/warp_connector_create_response.py @@ -41,7 +41,7 @@ class Connection(BaseModel): class WARPConnectorCreateResponse(BaseModel): - """A Warp Connector Tunnel that connects your origin to Cloudflare's edge.""" + """A Mesh node that connects your origin to Cloudflare's edge.""" id: Optional[str] = None """UUID of the tunnel.""" diff --git a/src/cloudflare/types/zero_trust/tunnels/warp_connector_delete_response.py b/src/cloudflare/types/zero_trust/tunnels/warp_connector_delete_response.py index 7e9cb7745ed..3335b6252cd 100644 --- a/src/cloudflare/types/zero_trust/tunnels/warp_connector_delete_response.py +++ b/src/cloudflare/types/zero_trust/tunnels/warp_connector_delete_response.py @@ -41,7 +41,7 @@ class Connection(BaseModel): class WARPConnectorDeleteResponse(BaseModel): - """A Warp Connector Tunnel that connects your origin to Cloudflare's edge.""" + """A Mesh node that connects your origin to Cloudflare's edge.""" id: Optional[str] = None """UUID of the tunnel.""" diff --git a/src/cloudflare/types/zero_trust/tunnels/warp_connector_edit_response.py b/src/cloudflare/types/zero_trust/tunnels/warp_connector_edit_response.py index 6f063366634..42a75b011c5 100644 --- a/src/cloudflare/types/zero_trust/tunnels/warp_connector_edit_response.py +++ b/src/cloudflare/types/zero_trust/tunnels/warp_connector_edit_response.py @@ -41,7 +41,7 @@ class Connection(BaseModel): class WARPConnectorEditResponse(BaseModel): - """A Warp Connector Tunnel that connects your origin to Cloudflare's edge.""" + """A Mesh node that connects your origin to Cloudflare's edge.""" id: Optional[str] = None """UUID of the tunnel.""" diff --git a/src/cloudflare/types/zero_trust/tunnels/warp_connector_get_response.py b/src/cloudflare/types/zero_trust/tunnels/warp_connector_get_response.py index fa1075bddc8..e629bf495dd 100644 --- a/src/cloudflare/types/zero_trust/tunnels/warp_connector_get_response.py +++ b/src/cloudflare/types/zero_trust/tunnels/warp_connector_get_response.py @@ -41,7 +41,7 @@ class Connection(BaseModel): class WARPConnectorGetResponse(BaseModel): - """A Warp Connector Tunnel that connects your origin to Cloudflare's edge.""" + """A Mesh node that connects your origin to Cloudflare's edge.""" id: Optional[str] = None """UUID of the tunnel.""" diff --git a/src/cloudflare/types/zero_trust/tunnels/warp_connector_list_response.py b/src/cloudflare/types/zero_trust/tunnels/warp_connector_list_response.py index 3859674646e..d4c593bf89f 100644 --- a/src/cloudflare/types/zero_trust/tunnels/warp_connector_list_response.py +++ b/src/cloudflare/types/zero_trust/tunnels/warp_connector_list_response.py @@ -41,7 +41,7 @@ class Connection(BaseModel): class WARPConnectorListResponse(BaseModel): - """A Warp Connector Tunnel that connects your origin to Cloudflare's edge.""" + """A Mesh node that connects your origin to Cloudflare's edge.""" id: Optional[str] = None """UUID of the tunnel.""" diff --git a/src/cloudflare/types/zones/__init__.py b/src/cloudflare/types/zones/__init__.py index f5515ef7dff..76e2d574c98 100644 --- a/src/cloudflare/types/zones/__init__.py +++ b/src/cloudflare/types/zones/__init__.py @@ -98,7 +98,6 @@ from .automatic_https_rewrites_param import AutomaticHTTPSRewritesParam as AutomaticHTTPSRewritesParam from .custom_nameserver_get_response import CustomNameserverGetResponse as CustomNameserverGetResponse from .opportunistic_encryption_param import OpportunisticEncryptionParam as OpportunisticEncryptionParam -from .automatic_platform_optimization import AutomaticPlatformOptimization as AutomaticPlatformOptimization from .custom_nameserver_update_params import CustomNameserverUpdateParams as CustomNameserverUpdateParams from .transformations_allowed_origins import TransformationsAllowedOrigins as TransformationsAllowedOrigins from .transformations_c2pa_edit_params import TransformationsC2paEditParams as TransformationsC2paEditParams diff --git a/src/cloudflare/types/zones/advanced_ddos.py b/src/cloudflare/types/zones/advanced_ddos.py index d000cb19bc7..9c02fb1c512 100644 --- a/src/cloudflare/types/zones/advanced_ddos.py +++ b/src/cloudflare/types/zones/advanced_ddos.py @@ -1,6 +1,6 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import Optional +from typing import List, Union, Optional from datetime import datetime from typing_extensions import Literal @@ -17,7 +17,7 @@ class AdvancedDDoS(BaseModel): id: Literal["advanced_ddos"] """ID of the zone setting.""" - value: Literal["on", "off"] + value: Union[str, float, bool, List[str], object] """Current value of the zone setting.""" editable: Optional[Literal[True, False]] = None diff --git a/src/cloudflare/types/zones/always_online.py b/src/cloudflare/types/zones/always_online.py index eefa275ffda..072afe952eb 100644 --- a/src/cloudflare/types/zones/always_online.py +++ b/src/cloudflare/types/zones/always_online.py @@ -1,6 +1,6 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import Optional +from typing import List, Union, Optional from datetime import datetime from typing_extensions import Literal @@ -17,7 +17,7 @@ class AlwaysOnline(BaseModel): id: Literal["always_online"] """ID of the zone setting.""" - value: Literal["on", "off"] + value: Union[str, float, bool, List[str], object] """Current value of the zone setting.""" editable: Optional[Literal[True, False]] = None diff --git a/src/cloudflare/types/zones/automatic_platform_optimization.py b/src/cloudflare/types/zones/automatic_platform_optimization.py deleted file mode 100644 index dbf8d141501..00000000000 --- a/src/cloudflare/types/zones/automatic_platform_optimization.py +++ /dev/null @@ -1,38 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from typing import List - -from ..._models import BaseModel - -__all__ = ["AutomaticPlatformOptimization"] - - -class AutomaticPlatformOptimization(BaseModel): - cache_by_device_type: bool - """ - Indicates whether or not - [cache by device type](https://developers.cloudflare.com/automatic-platform-optimization/reference/cache-device-type/) - is enabled. - """ - - cf: bool - """Indicates whether or not Cloudflare proxy is enabled.""" - - enabled: bool - """Indicates whether or not Automatic Platform Optimization is enabled.""" - - hostnames: List[str] - """ - An array of hostnames where Automatic Platform Optimization for WordPress is - activated. - """ - - wordpress: bool - """Indicates whether or not site is powered by WordPress.""" - - wp_plugin: bool - """ - Indicates whether or not - [Cloudflare for WordPress plugin](https://wordpress.org/plugins/cloudflare/) is - installed. - """ diff --git a/src/cloudflare/types/zones/brotli.py b/src/cloudflare/types/zones/brotli.py index 25d2f10d56a..0e1b8308129 100644 --- a/src/cloudflare/types/zones/brotli.py +++ b/src/cloudflare/types/zones/brotli.py @@ -1,6 +1,6 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import Optional +from typing import List, Union, Optional from datetime import datetime from typing_extensions import Literal @@ -17,7 +17,7 @@ class Brotli(BaseModel): id: Literal["brotli"] """ID of the zone setting.""" - value: Literal["off", "on"] + value: Union[str, float, bool, List[str], object] """Current value of the zone setting.""" editable: Optional[Literal[True, False]] = None diff --git a/src/cloudflare/types/zones/challenge_ttl.py b/src/cloudflare/types/zones/challenge_ttl.py index 4621ef14546..0dd0bc20ac1 100644 --- a/src/cloudflare/types/zones/challenge_ttl.py +++ b/src/cloudflare/types/zones/challenge_ttl.py @@ -1,6 +1,6 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import Optional +from typing import List, Union, Optional from datetime import datetime from typing_extensions import Literal @@ -17,7 +17,7 @@ class ChallengeTTL(BaseModel): id: Literal["challenge_ttl"] """ID of the zone setting.""" - value: Literal[300, 900, 1800, 2700, 3600, 7200, 10800, 14400, 28800, 57600, 86400, 604800, 2592000, 31536000] + value: Union[str, float, bool, List[str], object] """Current value of the zone setting.""" editable: Optional[Literal[True, False]] = None diff --git a/src/cloudflare/types/zones/ciphers.py b/src/cloudflare/types/zones/ciphers.py index 40050e055d5..d32194cac54 100644 --- a/src/cloudflare/types/zones/ciphers.py +++ b/src/cloudflare/types/zones/ciphers.py @@ -1,6 +1,6 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import List, Optional +from typing import List, Union, Optional from datetime import datetime from typing_extensions import Literal @@ -18,7 +18,7 @@ class Ciphers(BaseModel): id: Literal["ciphers"] """ID of the zone setting.""" - value: List[str] + value: Union[str, float, bool, List[str], object] """Current value of the zone setting.""" editable: Optional[Literal[True, False]] = None diff --git a/src/cloudflare/types/zones/development_mode.py b/src/cloudflare/types/zones/development_mode.py index 87b21a0fdd7..9c21d640f43 100644 --- a/src/cloudflare/types/zones/development_mode.py +++ b/src/cloudflare/types/zones/development_mode.py @@ -1,6 +1,6 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import Optional +from typing import List, Union, Optional from datetime import datetime from typing_extensions import Literal @@ -17,7 +17,7 @@ class DevelopmentMode(BaseModel): id: Literal["development_mode"] """ID of the zone setting.""" - value: Literal["on", "off"] + value: Union[str, float, bool, List[str], object] """Current value of the zone setting.""" editable: Optional[Literal[True, False]] = None diff --git a/src/cloudflare/types/zones/early_hints.py b/src/cloudflare/types/zones/early_hints.py index e1a8247dc66..95cceac8258 100644 --- a/src/cloudflare/types/zones/early_hints.py +++ b/src/cloudflare/types/zones/early_hints.py @@ -1,6 +1,6 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import Optional +from typing import List, Union, Optional from datetime import datetime from typing_extensions import Literal @@ -17,7 +17,7 @@ class EarlyHints(BaseModel): id: Literal["early_hints"] """ID of the zone setting.""" - value: Literal["on", "off"] + value: Union[str, float, bool, List[str], object] """Current value of the zone setting.""" editable: Optional[Literal[True, False]] = None diff --git a/src/cloudflare/types/zones/h2_prioritization.py b/src/cloudflare/types/zones/h2_prioritization.py index 0e91e0becf0..e397eb0664a 100644 --- a/src/cloudflare/types/zones/h2_prioritization.py +++ b/src/cloudflare/types/zones/h2_prioritization.py @@ -1,6 +1,6 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import Optional +from typing import List, Union, Optional from datetime import datetime from typing_extensions import Literal @@ -17,7 +17,7 @@ class H2Prioritization(BaseModel): id: Literal["h2_prioritization"] """ID of the zone setting.""" - value: Literal["on", "off", "custom"] + value: Union[str, float, bool, List[str], object] """Current value of the zone setting.""" editable: Optional[Literal[True, False]] = None diff --git a/src/cloudflare/types/zones/hotlink_protection.py b/src/cloudflare/types/zones/hotlink_protection.py index 9d659066b33..aec7526a66f 100644 --- a/src/cloudflare/types/zones/hotlink_protection.py +++ b/src/cloudflare/types/zones/hotlink_protection.py @@ -1,6 +1,6 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import Optional +from typing import List, Union, Optional from datetime import datetime from typing_extensions import Literal @@ -17,7 +17,7 @@ class HotlinkProtection(BaseModel): id: Literal["hotlink_protection"] """ID of the zone setting.""" - value: Literal["on", "off"] + value: Union[str, float, bool, List[str], object] """Current value of the zone setting.""" editable: Optional[Literal[True, False]] = None diff --git a/src/cloudflare/types/zones/http2.py b/src/cloudflare/types/zones/http2.py index 417b4808ce2..6d05234e6d8 100644 --- a/src/cloudflare/types/zones/http2.py +++ b/src/cloudflare/types/zones/http2.py @@ -1,6 +1,6 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import Optional +from typing import List, Union, Optional from datetime import datetime from typing_extensions import Literal @@ -15,7 +15,7 @@ class HTTP2(BaseModel): id: Literal["http2"] """ID of the zone setting.""" - value: Literal["on", "off"] + value: Union[str, float, bool, List[str], object] """Current value of the zone setting.""" editable: Optional[Literal[True, False]] = None diff --git a/src/cloudflare/types/zones/http3.py b/src/cloudflare/types/zones/http3.py index b48a595a0ea..4836e241f53 100644 --- a/src/cloudflare/types/zones/http3.py +++ b/src/cloudflare/types/zones/http3.py @@ -1,6 +1,6 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import Optional +from typing import List, Union, Optional from datetime import datetime from typing_extensions import Literal @@ -15,7 +15,7 @@ class HTTP3(BaseModel): id: Literal["http3"] """ID of the zone setting.""" - value: Literal["on", "off"] + value: Union[str, float, bool, List[str], object] """Current value of the zone setting.""" editable: Optional[Literal[True, False]] = None diff --git a/src/cloudflare/types/zones/image_resizing.py b/src/cloudflare/types/zones/image_resizing.py index 06931d4bc9e..7634e17c858 100644 --- a/src/cloudflare/types/zones/image_resizing.py +++ b/src/cloudflare/types/zones/image_resizing.py @@ -1,6 +1,6 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import Optional +from typing import List, Union, Optional from datetime import datetime from typing_extensions import Literal @@ -17,7 +17,7 @@ class ImageResizing(BaseModel): id: Literal["image_resizing"] """ID of the zone setting.""" - value: Literal["on", "off", "open"] + value: Union[str, float, bool, List[str], object] """Current value of the zone setting.""" editable: Optional[Literal[True, False]] = None diff --git a/src/cloudflare/types/zones/ipv6.py b/src/cloudflare/types/zones/ipv6.py index 539201755df..a6da2fc2e55 100644 --- a/src/cloudflare/types/zones/ipv6.py +++ b/src/cloudflare/types/zones/ipv6.py @@ -1,6 +1,6 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import Optional +from typing import List, Union, Optional from datetime import datetime from typing_extensions import Literal @@ -18,7 +18,7 @@ class IPV6(BaseModel): id: Literal["ipv6"] """ID of the zone setting.""" - value: Literal["off", "on"] + value: Union[str, float, bool, List[str], object] """Current value of the zone setting.""" editable: Optional[Literal[True, False]] = None diff --git a/src/cloudflare/types/zones/min_tls_version.py b/src/cloudflare/types/zones/min_tls_version.py index 9c6c1776093..799a9e0aefb 100644 --- a/src/cloudflare/types/zones/min_tls_version.py +++ b/src/cloudflare/types/zones/min_tls_version.py @@ -1,6 +1,6 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import Optional +from typing import List, Union, Optional from datetime import datetime from typing_extensions import Literal @@ -18,7 +18,7 @@ class MinTLSVersion(BaseModel): id: Literal["min_tls_version"] """ID of the zone setting.""" - value: Literal["1.0", "1.1", "1.2", "1.3"] + value: Union[str, float, bool, List[str], object] """Current value of the zone setting.""" editable: Optional[Literal[True, False]] = None diff --git a/src/cloudflare/types/zones/nel.py b/src/cloudflare/types/zones/nel.py index 1861deb8c2d..7d5aceb0388 100644 --- a/src/cloudflare/types/zones/nel.py +++ b/src/cloudflare/types/zones/nel.py @@ -1,20 +1,21 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import Optional +from typing import Union, Optional from datetime import datetime -from typing_extensions import Literal +from typing_extensions import Literal, TypeAlias from ..._models import BaseModel -__all__ = ["NEL", "Value"] +__all__ = ["NEL", "Value", "ValueEnabled"] -class Value(BaseModel): - """Current value of the zone setting.""" - +class ValueEnabled(BaseModel): enabled: Optional[bool] = None +Value: TypeAlias = Union[ValueEnabled, ValueEnabled, ValueEnabled, ValueEnabled, ValueEnabled] + + class NEL(BaseModel): """Enable Network Error Logging reporting on your zone. (Beta)""" diff --git a/src/cloudflare/types/zones/opportunistic_onion.py b/src/cloudflare/types/zones/opportunistic_onion.py index 8fb40ebaf10..b2bc65d94ef 100644 --- a/src/cloudflare/types/zones/opportunistic_onion.py +++ b/src/cloudflare/types/zones/opportunistic_onion.py @@ -1,6 +1,6 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import Optional +from typing import List, Union, Optional from datetime import datetime from typing_extensions import Literal @@ -17,7 +17,7 @@ class OpportunisticOnion(BaseModel): id: Literal["opportunistic_onion"] """ID of the zone setting.""" - value: Literal["on", "off"] + value: Union[str, float, bool, List[str], object] """Current value of the zone setting.""" editable: Optional[Literal[True, False]] = None diff --git a/src/cloudflare/types/zones/orange_to_orange.py b/src/cloudflare/types/zones/orange_to_orange.py index 41aa95bce0f..0d75569d4fd 100644 --- a/src/cloudflare/types/zones/orange_to_orange.py +++ b/src/cloudflare/types/zones/orange_to_orange.py @@ -1,6 +1,6 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import Optional +from typing import List, Union, Optional from datetime import datetime from typing_extensions import Literal @@ -17,7 +17,7 @@ class OrangeToOrange(BaseModel): id: Literal["orange_to_orange"] """ID of the zone setting.""" - value: Literal["on", "off"] + value: Union[str, float, bool, List[str], object] """Current value of the zone setting.""" editable: Optional[Literal[True, False]] = None diff --git a/src/cloudflare/types/zones/prefetch_preload.py b/src/cloudflare/types/zones/prefetch_preload.py index 0f71a36d466..464e2c1db6a 100644 --- a/src/cloudflare/types/zones/prefetch_preload.py +++ b/src/cloudflare/types/zones/prefetch_preload.py @@ -1,6 +1,6 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import Optional +from typing import List, Union, Optional from datetime import datetime from typing_extensions import Literal @@ -18,7 +18,7 @@ class PrefetchPreload(BaseModel): id: Literal["prefetch_preload"] """ID of the zone setting.""" - value: Literal["on", "off"] + value: Union[str, float, bool, List[str], object] """Current value of the zone setting.""" editable: Optional[Literal[True, False]] = None diff --git a/src/cloudflare/types/zones/proxy_read_timeout.py b/src/cloudflare/types/zones/proxy_read_timeout.py index 9bd7119e735..9cbc4c6024d 100644 --- a/src/cloudflare/types/zones/proxy_read_timeout.py +++ b/src/cloudflare/types/zones/proxy_read_timeout.py @@ -1,6 +1,6 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import Optional +from typing import List, Union, Optional from datetime import datetime from typing_extensions import Literal @@ -15,8 +15,8 @@ class ProxyReadTimeout(BaseModel): id: Literal["proxy_read_timeout"] """ID of the zone setting.""" - value: float - """Current value of the zone setting.""" + value: Union[str, float, bool, List[str], object] + """Value of the zone setting. Notes: Value must be between 1 and 6000""" editable: Optional[Literal[True, False]] = None """ diff --git a/src/cloudflare/types/zones/pseudo_ipv4.py b/src/cloudflare/types/zones/pseudo_ipv4.py index 0f9e01622db..e3ea8232381 100644 --- a/src/cloudflare/types/zones/pseudo_ipv4.py +++ b/src/cloudflare/types/zones/pseudo_ipv4.py @@ -1,6 +1,6 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import Optional +from typing import List, Union, Optional from datetime import datetime from typing_extensions import Literal @@ -15,7 +15,7 @@ class PseudoIPV4(BaseModel): id: Literal["pseudo_ipv4"] """Value of the Pseudo IPv4 setting.""" - value: Literal["off", "add_header", "overwrite_header"] + value: Union[str, float, bool, List[str], object] """Current value of the zone setting.""" editable: Optional[Literal[True, False]] = None diff --git a/src/cloudflare/types/zones/security_headers.py b/src/cloudflare/types/zones/security_headers.py index 365fe97e9cf..4ee0cd5e6f2 100644 --- a/src/cloudflare/types/zones/security_headers.py +++ b/src/cloudflare/types/zones/security_headers.py @@ -1,15 +1,20 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import Optional +from typing import Union, Optional from datetime import datetime -from typing_extensions import Literal +from typing_extensions import Literal, TypeAlias from ..._models import BaseModel -__all__ = ["SecurityHeaders", "Value", "ValueStrictTransportSecurity"] +__all__ = [ + "SecurityHeaders", + "Value", + "ValueStrictTransportSecurity", + "ValueStrictTransportSecurityStrictTransportSecurity", +] -class ValueStrictTransportSecurity(BaseModel): +class ValueStrictTransportSecurityStrictTransportSecurity(BaseModel): """Strict Transport Security.""" enabled: Optional[bool] = None @@ -28,13 +33,20 @@ class ValueStrictTransportSecurity(BaseModel): """Enable automatic preload of the HSTS configuration.""" -class Value(BaseModel): - """Current value of the zone setting.""" - - strict_transport_security: Optional[ValueStrictTransportSecurity] = None +class ValueStrictTransportSecurity(BaseModel): + strict_transport_security: Optional[ValueStrictTransportSecurityStrictTransportSecurity] = None """Strict Transport Security.""" +Value: TypeAlias = Union[ + ValueStrictTransportSecurity, + ValueStrictTransportSecurity, + ValueStrictTransportSecurity, + ValueStrictTransportSecurity, + ValueStrictTransportSecurity, +] + + class SecurityHeaders(BaseModel): """Cloudflare security header for a zone.""" diff --git a/src/cloudflare/types/zones/server_side_excludes.py b/src/cloudflare/types/zones/server_side_excludes.py index eeeb026e60a..d2996e1d732 100644 --- a/src/cloudflare/types/zones/server_side_excludes.py +++ b/src/cloudflare/types/zones/server_side_excludes.py @@ -1,6 +1,6 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import Optional +from typing import List, Union, Optional from datetime import datetime from typing_extensions import Literal @@ -17,7 +17,7 @@ class ServerSideExcludes(BaseModel): id: Literal["server_side_exclude"] """ID of the zone setting.""" - value: Literal["on", "off"] + value: Union[str, float, bool, List[str], object] """Current value of the zone setting.""" editable: Optional[Literal[True, False]] = None diff --git a/src/cloudflare/types/zones/setting_edit_response.py b/src/cloudflare/types/zones/setting_edit_response.py index 1f4f791a7fa..18f92468715 100644 --- a/src/cloudflare/types/zones/setting_edit_response.py +++ b/src/cloudflare/types/zones/setting_edit_response.py @@ -1,6 +1,6 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import Union, Optional +from typing import List, Union, Optional from datetime import datetime from typing_extensions import Literal, TypeAlias @@ -33,7 +33,6 @@ from .proxy_read_timeout import ProxyReadTimeout from .opportunistic_onion import OpportunisticOnion from .server_side_excludes import ServerSideExcludes -from .automatic_platform_optimization import AutomaticPlatformOptimization __all__ = [ "SettingEditResponse", @@ -64,6 +63,12 @@ "ZonesResponseBuffering2", "ZonesRocketLoader2", "ZonesSchemasAutomaticPlatformOptimization", + "ZonesSchemasAutomaticPlatformOptimizationValue", + "ZonesSchemasAutomaticPlatformOptimizationValueUnionMember0", + "ZonesSchemasAutomaticPlatformOptimizationValueUnionMember1", + "ZonesSchemasAutomaticPlatformOptimizationValueUnionMember2", + "ZonesSchemasAutomaticPlatformOptimizationValueUnionMember3", + "ZonesSchemasAutomaticPlatformOptimizationValueUnionMember4", "ZonesSearchForAgents", "ZonesSecurityLevel2", "ZonesSha1Support", @@ -75,6 +80,7 @@ "ZonesTrueClientIPHeader2", "ZonesWAF2", "ZonesWebmcpEnabled", + "ZonesWebmcpMcpURL", "ZonesWebmcpPacks", ] @@ -115,7 +121,7 @@ class ZonesAlwaysUseHTTPS2(BaseModel): id: Literal["always_use_https"] """ID of the zone setting.""" - value: Literal["on", "off"] + value: Union[str, float, bool, List[str], object] """Current value of the zone setting.""" editable: Optional[Literal[True, False]] = None @@ -134,7 +140,7 @@ class ZonesAutomaticHTTPSRewrites2(BaseModel): id: Literal["automatic_https_rewrites"] """ID of the zone setting.""" - value: Literal["on", "off"] + value: Union[str, float, bool, List[str], object] """Current value of the zone setting.""" editable: Optional[Literal[True, False]] = None @@ -155,8 +161,15 @@ class ZonesBrowserCacheTTL2(BaseModel): id: Literal["browser_cache_ttl"] """ID of the zone setting.""" - value: int - """Current value of the zone setting.""" + value: Union[str, float, bool, List[str], object] + """Value of the zone setting in seconds. Minimum values by plan: + + - Free: 1 second + - Pro: 1 second + - Business: 1 second + - Enterprise: 1 second Setting a TTL of 0 is equivalent to selecting + `Respect Existing Headers` and is allowed for all plans. + """ editable: Optional[Literal[True, False]] = None """ @@ -176,7 +189,7 @@ class ZonesBrowserCheck2(BaseModel): id: Literal["browser_check"] """ID of the zone setting.""" - value: Literal["on", "off"] + value: Union[str, float, bool, List[str], object] """Current value of the zone setting.""" editable: Optional[Literal[True, False]] = None @@ -198,7 +211,7 @@ class ZonesCacheLevel2(BaseModel): id: Literal["cache_level"] """ID of the zone setting.""" - value: Literal["aggressive", "basic", "simplified"] + value: Union[str, float, bool, List[str], object] """Current value of the zone setting.""" editable: Optional[Literal[True, False]] = None @@ -217,7 +230,7 @@ class ZonesChinaNetworkEnabled(BaseModel): id: Literal["china_network_enabled"] """ID of the zone setting.""" - value: Literal["on", "off"] + value: Union[str, float, bool, List[str], object] """Current value of the zone setting.""" editable: Optional[Literal[True, False]] = None @@ -240,7 +253,7 @@ class ZonesContentConverter(BaseModel): id: Literal["content_converter"] """ID of the zone setting.""" - value: Literal["off", "on"] + value: Union[str, float, bool, List[str], object] """Current value of the zone setting.""" editable: Optional[Literal[True, False]] = None @@ -259,7 +272,7 @@ class ZonesCNAMEFlattening(BaseModel): id: Literal["cname_flattening"] """How to flatten the cname destination.""" - value: Literal["flatten_at_root", "flatten_all"] + value: Union[str, float, bool, List[str], object] """Current value of the zone setting.""" editable: Optional[Literal[True, False]] = None @@ -280,29 +293,7 @@ class ZonesEdgeCacheTTL2(BaseModel): id: Literal["edge_cache_ttl"] """ID of the zone setting.""" - value: Literal[ - 30, - 60, - 300, - 1200, - 1800, - 3600, - 7200, - 10800, - 14400, - 18000, - 28800, - 43200, - 57600, - 72000, - 86400, - 172800, - 259200, - 345600, - 432000, - 518400, - 604800, - ] + value: Union[str, float, bool, List[str], object] """Current value of the zone setting.""" editable: Optional[Literal[True, False]] = None @@ -323,7 +314,7 @@ class ZonesEmailObfuscation2(BaseModel): id: Literal["email_obfuscation"] """ID of the zone setting.""" - value: Literal["on", "off"] + value: Union[str, float, bool, List[str], object] """Current value of the zone setting.""" editable: Optional[Literal[True, False]] = None @@ -344,7 +335,7 @@ class ZonesIPGeolocation2(BaseModel): id: Literal["ip_geolocation"] """ID of the zone setting.""" - value: Literal["on", "off"] + value: Union[str, float, bool, List[str], object] """Current value of the zone setting.""" editable: Optional[Literal[True, False]] = None @@ -363,34 +354,7 @@ class ZonesMaxUpload(BaseModel): id: Literal["max_upload"] """identifier of the zone setting.""" - value: Literal[ - 100, - 125, - 150, - 175, - 200, - 225, - 250, - 275, - 300, - 325, - 350, - 375, - 400, - 425, - 450, - 475, - 500, - 1000, - 1500, - 2000, - 2500, - 3000, - 3500, - 4000, - 4500, - 5000, - ] + value: Union[str, float, bool, List[str], object] """Current value of the zone setting.""" editable: Optional[Literal[True, False]] = None @@ -414,7 +378,7 @@ class ZonesMirage2(BaseModel): id: Literal["mirage"] """ID of the zone setting.""" - value: Literal["on", "off"] + value: Union[str, float, bool, List[str], object] """Current value of the zone setting.""" editable: Optional[Literal[True, False]] = None @@ -433,7 +397,7 @@ class ZonesOpportunisticEncryption2(BaseModel): id: Literal["opportunistic_encryption"] """ID of the zone setting.""" - value: Literal["on", "off"] + value: Union[str, float, bool, List[str], object] """Current value of the zone setting.""" editable: Optional[Literal[True, False]] = None @@ -454,7 +418,7 @@ class ZonesOriginErrorPagePassThru2(BaseModel): id: Literal["origin_error_page_pass_thru"] """ID of the zone setting.""" - value: Literal["on", "off"] + value: Union[str, float, bool, List[str], object] """Current value of the zone setting.""" editable: Optional[Literal[True, False]] = None @@ -506,7 +470,7 @@ class ZonesPolish2(BaseModel): id: Literal["polish"] """ID of the zone setting.""" - value: Literal["off", "lossless", "lossy"] + value: Union[str, float, bool, List[str], object] """Current value of the zone setting.""" editable: Optional[Literal[True, False]] = None @@ -528,7 +492,7 @@ class ZonesPreRender(BaseModel): id: Literal["pre_render"] """ID of the zone setting.""" - value: Literal["off", "on"] + value: Union[str, float, bool, List[str], object] """Current value of the zone setting.""" editable: Optional[Literal[True, False]] = None @@ -549,7 +513,7 @@ class ZonesPrivacyPass(BaseModel): id: Literal["privacy_pass"] """ID of the zone setting.""" - value: Literal["on", "off"] + value: Union[str, float, bool, List[str], object] """Current value of the zone setting.""" editable: Optional[Literal[True, False]] = None @@ -571,7 +535,7 @@ class ZonesRedirectsForAITraining(BaseModel): id: Literal["redirects_for_ai_training"] """ID of the zone setting.""" - value: Literal["off", "on"] + value: Union[str, float, bool, List[str], object] """Current value of the zone setting.""" editable: Optional[Literal[True, False]] = None @@ -592,7 +556,7 @@ class ZonesReplaceInsecureJS(BaseModel): id: Literal["replace_insecure_js"] """ID of the zone setting.""" - value: Literal["on", "off"] + value: Union[str, float, bool, List[str], object] """Current value of the zone setting.""" editable: Optional[Literal[True, False]] = None @@ -614,7 +578,7 @@ class ZonesResponseBuffering2(BaseModel): id: Literal["response_buffering"] """ID of the zone setting.""" - value: Literal["on", "off"] + value: Union[str, float, bool, List[str], object] """Current value of the zone setting.""" editable: Optional[Literal[True, False]] = None @@ -635,7 +599,7 @@ class ZonesRocketLoader2(BaseModel): id: Literal["rocket_loader"] """ID of the zone setting.""" - value: Literal["on", "off"] + value: Union[str, float, bool, List[str], object] """Current value of the zone setting.""" editable: Optional[Literal[True, False]] = None @@ -648,6 +612,170 @@ class ZonesRocketLoader2(BaseModel): """last time this setting was modified.""" +class ZonesSchemasAutomaticPlatformOptimizationValueUnionMember0(BaseModel): + cache_by_device_type: Optional[bool] = None + """ + Indicates whether or not + [cache by device type](https://developers.cloudflare.com/automatic-platform-optimization/reference/cache-device-type/) + is enabled. + """ + + cf: Optional[bool] = None + """Indicates whether or not Cloudflare proxy is enabled.""" + + enabled: Optional[bool] = None + """Indicates whether or not Automatic Platform Optimization is enabled.""" + + hostnames: Optional[List[str]] = None + """ + An array of hostnames where Automatic Platform Optimization for WordPress is + activated. + """ + + wordpress: Optional[bool] = None + """Indicates whether or not site is powered by WordPress.""" + + wp_plugin: Optional[bool] = None + """ + Indicates whether or not + [Cloudflare for WordPress plugin](https://wordpress.org/plugins/cloudflare/) is + installed. + """ + + +class ZonesSchemasAutomaticPlatformOptimizationValueUnionMember1(BaseModel): + cache_by_device_type: Optional[bool] = None + """ + Indicates whether or not + [cache by device type](https://developers.cloudflare.com/automatic-platform-optimization/reference/cache-device-type/) + is enabled. + """ + + cf: Optional[bool] = None + """Indicates whether or not Cloudflare proxy is enabled.""" + + enabled: Optional[bool] = None + """Indicates whether or not Automatic Platform Optimization is enabled.""" + + hostnames: Optional[List[str]] = None + """ + An array of hostnames where Automatic Platform Optimization for WordPress is + activated. + """ + + wordpress: Optional[bool] = None + """Indicates whether or not site is powered by WordPress.""" + + wp_plugin: Optional[bool] = None + """ + Indicates whether or not + [Cloudflare for WordPress plugin](https://wordpress.org/plugins/cloudflare/) is + installed. + """ + + +class ZonesSchemasAutomaticPlatformOptimizationValueUnionMember2(BaseModel): + cache_by_device_type: Optional[bool] = None + """ + Indicates whether or not + [cache by device type](https://developers.cloudflare.com/automatic-platform-optimization/reference/cache-device-type/) + is enabled. + """ + + cf: Optional[bool] = None + """Indicates whether or not Cloudflare proxy is enabled.""" + + enabled: Optional[bool] = None + """Indicates whether or not Automatic Platform Optimization is enabled.""" + + hostnames: Optional[List[str]] = None + """ + An array of hostnames where Automatic Platform Optimization for WordPress is + activated. + """ + + wordpress: Optional[bool] = None + """Indicates whether or not site is powered by WordPress.""" + + wp_plugin: Optional[bool] = None + """ + Indicates whether or not + [Cloudflare for WordPress plugin](https://wordpress.org/plugins/cloudflare/) is + installed. + """ + + +class ZonesSchemasAutomaticPlatformOptimizationValueUnionMember3(BaseModel): + cache_by_device_type: Optional[bool] = None + """ + Indicates whether or not + [cache by device type](https://developers.cloudflare.com/automatic-platform-optimization/reference/cache-device-type/) + is enabled. + """ + + cf: Optional[bool] = None + """Indicates whether or not Cloudflare proxy is enabled.""" + + enabled: Optional[bool] = None + """Indicates whether or not Automatic Platform Optimization is enabled.""" + + hostnames: Optional[List[str]] = None + """ + An array of hostnames where Automatic Platform Optimization for WordPress is + activated. + """ + + wordpress: Optional[bool] = None + """Indicates whether or not site is powered by WordPress.""" + + wp_plugin: Optional[bool] = None + """ + Indicates whether or not + [Cloudflare for WordPress plugin](https://wordpress.org/plugins/cloudflare/) is + installed. + """ + + +class ZonesSchemasAutomaticPlatformOptimizationValueUnionMember4(BaseModel): + cache_by_device_type: Optional[bool] = None + """ + Indicates whether or not + [cache by device type](https://developers.cloudflare.com/automatic-platform-optimization/reference/cache-device-type/) + is enabled. + """ + + cf: Optional[bool] = None + """Indicates whether or not Cloudflare proxy is enabled.""" + + enabled: Optional[bool] = None + """Indicates whether or not Automatic Platform Optimization is enabled.""" + + hostnames: Optional[List[str]] = None + """ + An array of hostnames where Automatic Platform Optimization for WordPress is + activated. + """ + + wordpress: Optional[bool] = None + """Indicates whether or not site is powered by WordPress.""" + + wp_plugin: Optional[bool] = None + """ + Indicates whether or not + [Cloudflare for WordPress plugin](https://wordpress.org/plugins/cloudflare/) is + installed. + """ + + +ZonesSchemasAutomaticPlatformOptimizationValue: TypeAlias = Union[ + ZonesSchemasAutomaticPlatformOptimizationValueUnionMember0, + ZonesSchemasAutomaticPlatformOptimizationValueUnionMember1, + ZonesSchemasAutomaticPlatformOptimizationValueUnionMember2, + ZonesSchemasAutomaticPlatformOptimizationValueUnionMember3, + ZonesSchemasAutomaticPlatformOptimizationValueUnionMember4, +] + + class ZonesSchemasAutomaticPlatformOptimization(BaseModel): """ [Automatic Platform Optimization for WordPress](https://developers.cloudflare.com/automatic-platform-optimization/) serves your WordPress site from Cloudflare's edge network and caches third-party fonts. @@ -656,7 +784,7 @@ class ZonesSchemasAutomaticPlatformOptimization(BaseModel): id: Literal["automatic_platform_optimization"] """ID of the zone setting.""" - value: AutomaticPlatformOptimization + value: ZonesSchemasAutomaticPlatformOptimizationValue """Current value of the zone setting.""" editable: Optional[Literal[True, False]] = None @@ -680,7 +808,7 @@ class ZonesSearchForAgents(BaseModel): id: Literal["search_for_agents"] """ID of the zone setting.""" - value: Literal["off", "on"] + value: Union[str, float, bool, List[str], object] """Current value of the zone setting.""" editable: Optional[Literal[True, False]] = None @@ -701,7 +829,7 @@ class ZonesSecurityLevel2(BaseModel): id: Literal["security_level"] """ID of the zone setting.""" - value: Literal["off", "essentially_off", "low", "medium", "high", "under_attack"] + value: Union[str, float, bool, List[str], object] """Current value of the zone setting.""" editable: Optional[Literal[True, False]] = None @@ -720,7 +848,7 @@ class ZonesSha1Support(BaseModel): id: Literal["sha1_support"] """Zone setting identifier.""" - value: Literal["off", "on"] + value: Union[str, float, bool, List[str], object] """Current value of the zone setting.""" editable: Optional[Literal[True, False]] = None @@ -741,7 +869,7 @@ class ZonesSortQueryStringForCache2(BaseModel): id: Literal["sort_query_string_for_cache"] """ID of the zone setting.""" - value: Literal["on", "off"] + value: Union[str, float, bool, List[str], object] """Current value of the zone setting.""" editable: Optional[Literal[True, False]] = None @@ -762,7 +890,7 @@ class ZonesSSL2(BaseModel): id: Literal["ssl"] """ID of the zone setting.""" - value: Literal["off", "flexible", "full", "strict"] + value: Union[str, float, bool, List[str], object] """Current value of the zone setting.""" editable: Optional[Literal[True, False]] = None @@ -781,7 +909,7 @@ class ZonesTLS1_2Only(BaseModel): id: Literal["tls_1_2_only"] """Zone setting identifier.""" - value: Literal["off", "on"] + value: Union[str, float, bool, List[str], object] """Current value of the zone setting.""" editable: Optional[Literal[True, False]] = None @@ -805,7 +933,7 @@ class ZonesTransformations(BaseModel): Shared between Image Transformations and Video Transformations. """ - value: Literal["on", "off", "open"] + value: Union[str, float, bool, List[str], object] """Current value of the zone setting.""" editable: Optional[Literal[True, False]] = None @@ -829,8 +957,14 @@ class ZonesTransformationsAllowedOrigins(BaseModel): Shared between Image Transformations and Video Transformations. """ - value: str - """Current value of the zone setting.""" + value: Union[str, float, bool, List[str], object] + """ + Comma-separated list of allowed origins. Refer to the + [Image Transformations](https://developers.cloudflare.com/images/transform-images/sources/) + and + [Video Transformations](https://developers.cloudflare.com/stream/transform-videos/#getting-started) + documentation for more information. + """ editable: Optional[Literal[True, False]] = None """ @@ -850,7 +984,7 @@ class ZonesTrueClientIPHeader2(BaseModel): id: Literal["true_client_ip_header"] """ID of the zone setting.""" - value: Literal["on", "off"] + value: Union[str, float, bool, List[str], object] """Current value of the zone setting.""" editable: Optional[Literal[True, False]] = None @@ -872,7 +1006,7 @@ class ZonesWAF2(BaseModel): id: Literal["waf"] """ID of the zone setting.""" - value: Literal["on", "off"] + value: Union[str, float, bool, List[str], object] """Current value of the zone setting.""" editable: Optional[Literal[True, False]] = None @@ -897,7 +1031,7 @@ class ZonesWebmcpEnabled(BaseModel): id: Literal["webmcp_enabled"] """ID of the zone setting.""" - value: Literal["off", "on"] + value: Union[str, float, bool, List[str], object] """Current value of the zone setting.""" editable: Optional[Literal[True, False]] = None @@ -910,6 +1044,39 @@ class ZonesWebmcpEnabled(BaseModel): """last time this setting was modified.""" +class ZonesWebmcpMcpURL(BaseModel): + """ + Optional per-zone path of the site's own MCP server, used by the WebMCP + mcp-server-client tool pack to list and call the site's MCP tools from + the browser. The path is resolved against the page's origin, so it + applies to every hostname in the zone. Only takes effect when + webmcp_enabled is on and the mcp-server-client pack is active. Leave + empty to use /mcp. This setting is currently in beta and its behavior + may change. + """ + + id: Literal["webmcp_mcp_url"] + """ID of the zone setting.""" + + value: Union[str, float, bool, List[str], object] + """ + Root-relative path (with optional query string) of this zone's MCP endpoint, for + example "/api/mcp". Surfaced to the injected bridge as the data-mcp-url + attribute. Absolute and protocol-relative URLs, fragments, and characters + outside RFC 3986 paths and queries are rejected. An empty value clears the + override so the bridge uses /mcp. + """ + + editable: Optional[Literal[True, False]] = None + """ + Whether or not this setting can be modified for this zone (based on your + Cloudflare plan level). + """ + + modified_on: Optional[datetime] = None + """last time this setting was modified.""" + + class ZonesWebmcpPacks(BaseModel): """ Optional per-zone override of which bundled WebMCP tool packs the @@ -922,8 +1089,13 @@ class ZonesWebmcpPacks(BaseModel): id: Literal["webmcp_packs"] """ID of the zone setting.""" - value: str - """Current value of the zone setting.""" + value: Union[str, float, bool, List[str], object] + """ + Comma-separated list of WebMCP tool-pack names to activate for this zone (for + example, "c2pa,mcp-server-client"), surfaced to the injected bridge as the + data-packs attribute. An empty value clears the override so the bridge uses its + built-in default pack set. + """ editable: Optional[Literal[True, False]] = None """ @@ -999,6 +1171,7 @@ class ZonesWebmcpPacks(BaseModel): ZonesTrueClientIPHeader2, ZonesWAF2, ZonesWebmcpEnabled, + ZonesWebmcpMcpURL, ZonesWebmcpPacks, WebP, Websocket, diff --git a/src/cloudflare/types/zones/setting_get_response.py b/src/cloudflare/types/zones/setting_get_response.py index 9c3cbb32661..5a003ba1d47 100644 --- a/src/cloudflare/types/zones/setting_get_response.py +++ b/src/cloudflare/types/zones/setting_get_response.py @@ -1,6 +1,6 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import Union, Optional +from typing import List, Union, Optional from datetime import datetime from typing_extensions import Literal, TypeAlias @@ -33,7 +33,6 @@ from .proxy_read_timeout import ProxyReadTimeout from .opportunistic_onion import OpportunisticOnion from .server_side_excludes import ServerSideExcludes -from .automatic_platform_optimization import AutomaticPlatformOptimization __all__ = [ "SettingGetResponse", @@ -64,6 +63,12 @@ "ZonesResponseBuffering2", "ZonesRocketLoader2", "ZonesSchemasAutomaticPlatformOptimization", + "ZonesSchemasAutomaticPlatformOptimizationValue", + "ZonesSchemasAutomaticPlatformOptimizationValueUnionMember0", + "ZonesSchemasAutomaticPlatformOptimizationValueUnionMember1", + "ZonesSchemasAutomaticPlatformOptimizationValueUnionMember2", + "ZonesSchemasAutomaticPlatformOptimizationValueUnionMember3", + "ZonesSchemasAutomaticPlatformOptimizationValueUnionMember4", "ZonesSearchForAgents", "ZonesSecurityLevel2", "ZonesSha1Support", @@ -75,6 +80,7 @@ "ZonesTrueClientIPHeader2", "ZonesWAF2", "ZonesWebmcpEnabled", + "ZonesWebmcpMcpURL", "ZonesWebmcpPacks", ] @@ -115,7 +121,7 @@ class ZonesAlwaysUseHTTPS2(BaseModel): id: Literal["always_use_https"] """ID of the zone setting.""" - value: Literal["on", "off"] + value: Union[str, float, bool, List[str], object] """Current value of the zone setting.""" editable: Optional[Literal[True, False]] = None @@ -134,7 +140,7 @@ class ZonesAutomaticHTTPSRewrites2(BaseModel): id: Literal["automatic_https_rewrites"] """ID of the zone setting.""" - value: Literal["on", "off"] + value: Union[str, float, bool, List[str], object] """Current value of the zone setting.""" editable: Optional[Literal[True, False]] = None @@ -155,8 +161,15 @@ class ZonesBrowserCacheTTL2(BaseModel): id: Literal["browser_cache_ttl"] """ID of the zone setting.""" - value: int - """Current value of the zone setting.""" + value: Union[str, float, bool, List[str], object] + """Value of the zone setting in seconds. Minimum values by plan: + + - Free: 1 second + - Pro: 1 second + - Business: 1 second + - Enterprise: 1 second Setting a TTL of 0 is equivalent to selecting + `Respect Existing Headers` and is allowed for all plans. + """ editable: Optional[Literal[True, False]] = None """ @@ -176,7 +189,7 @@ class ZonesBrowserCheck2(BaseModel): id: Literal["browser_check"] """ID of the zone setting.""" - value: Literal["on", "off"] + value: Union[str, float, bool, List[str], object] """Current value of the zone setting.""" editable: Optional[Literal[True, False]] = None @@ -198,7 +211,7 @@ class ZonesCacheLevel2(BaseModel): id: Literal["cache_level"] """ID of the zone setting.""" - value: Literal["aggressive", "basic", "simplified"] + value: Union[str, float, bool, List[str], object] """Current value of the zone setting.""" editable: Optional[Literal[True, False]] = None @@ -217,7 +230,7 @@ class ZonesChinaNetworkEnabled(BaseModel): id: Literal["china_network_enabled"] """ID of the zone setting.""" - value: Literal["on", "off"] + value: Union[str, float, bool, List[str], object] """Current value of the zone setting.""" editable: Optional[Literal[True, False]] = None @@ -240,7 +253,7 @@ class ZonesContentConverter(BaseModel): id: Literal["content_converter"] """ID of the zone setting.""" - value: Literal["off", "on"] + value: Union[str, float, bool, List[str], object] """Current value of the zone setting.""" editable: Optional[Literal[True, False]] = None @@ -259,7 +272,7 @@ class ZonesCNAMEFlattening(BaseModel): id: Literal["cname_flattening"] """How to flatten the cname destination.""" - value: Literal["flatten_at_root", "flatten_all"] + value: Union[str, float, bool, List[str], object] """Current value of the zone setting.""" editable: Optional[Literal[True, False]] = None @@ -280,29 +293,7 @@ class ZonesEdgeCacheTTL2(BaseModel): id: Literal["edge_cache_ttl"] """ID of the zone setting.""" - value: Literal[ - 30, - 60, - 300, - 1200, - 1800, - 3600, - 7200, - 10800, - 14400, - 18000, - 28800, - 43200, - 57600, - 72000, - 86400, - 172800, - 259200, - 345600, - 432000, - 518400, - 604800, - ] + value: Union[str, float, bool, List[str], object] """Current value of the zone setting.""" editable: Optional[Literal[True, False]] = None @@ -323,7 +314,7 @@ class ZonesEmailObfuscation2(BaseModel): id: Literal["email_obfuscation"] """ID of the zone setting.""" - value: Literal["on", "off"] + value: Union[str, float, bool, List[str], object] """Current value of the zone setting.""" editable: Optional[Literal[True, False]] = None @@ -344,7 +335,7 @@ class ZonesIPGeolocation2(BaseModel): id: Literal["ip_geolocation"] """ID of the zone setting.""" - value: Literal["on", "off"] + value: Union[str, float, bool, List[str], object] """Current value of the zone setting.""" editable: Optional[Literal[True, False]] = None @@ -363,34 +354,7 @@ class ZonesMaxUpload(BaseModel): id: Literal["max_upload"] """identifier of the zone setting.""" - value: Literal[ - 100, - 125, - 150, - 175, - 200, - 225, - 250, - 275, - 300, - 325, - 350, - 375, - 400, - 425, - 450, - 475, - 500, - 1000, - 1500, - 2000, - 2500, - 3000, - 3500, - 4000, - 4500, - 5000, - ] + value: Union[str, float, bool, List[str], object] """Current value of the zone setting.""" editable: Optional[Literal[True, False]] = None @@ -414,7 +378,7 @@ class ZonesMirage2(BaseModel): id: Literal["mirage"] """ID of the zone setting.""" - value: Literal["on", "off"] + value: Union[str, float, bool, List[str], object] """Current value of the zone setting.""" editable: Optional[Literal[True, False]] = None @@ -433,7 +397,7 @@ class ZonesOpportunisticEncryption2(BaseModel): id: Literal["opportunistic_encryption"] """ID of the zone setting.""" - value: Literal["on", "off"] + value: Union[str, float, bool, List[str], object] """Current value of the zone setting.""" editable: Optional[Literal[True, False]] = None @@ -454,7 +418,7 @@ class ZonesOriginErrorPagePassThru2(BaseModel): id: Literal["origin_error_page_pass_thru"] """ID of the zone setting.""" - value: Literal["on", "off"] + value: Union[str, float, bool, List[str], object] """Current value of the zone setting.""" editable: Optional[Literal[True, False]] = None @@ -506,7 +470,7 @@ class ZonesPolish2(BaseModel): id: Literal["polish"] """ID of the zone setting.""" - value: Literal["off", "lossless", "lossy"] + value: Union[str, float, bool, List[str], object] """Current value of the zone setting.""" editable: Optional[Literal[True, False]] = None @@ -528,7 +492,7 @@ class ZonesPreRender(BaseModel): id: Literal["pre_render"] """ID of the zone setting.""" - value: Literal["off", "on"] + value: Union[str, float, bool, List[str], object] """Current value of the zone setting.""" editable: Optional[Literal[True, False]] = None @@ -549,7 +513,7 @@ class ZonesPrivacyPass(BaseModel): id: Literal["privacy_pass"] """ID of the zone setting.""" - value: Literal["on", "off"] + value: Union[str, float, bool, List[str], object] """Current value of the zone setting.""" editable: Optional[Literal[True, False]] = None @@ -571,7 +535,7 @@ class ZonesRedirectsForAITraining(BaseModel): id: Literal["redirects_for_ai_training"] """ID of the zone setting.""" - value: Literal["off", "on"] + value: Union[str, float, bool, List[str], object] """Current value of the zone setting.""" editable: Optional[Literal[True, False]] = None @@ -592,7 +556,7 @@ class ZonesReplaceInsecureJS(BaseModel): id: Literal["replace_insecure_js"] """ID of the zone setting.""" - value: Literal["on", "off"] + value: Union[str, float, bool, List[str], object] """Current value of the zone setting.""" editable: Optional[Literal[True, False]] = None @@ -614,7 +578,7 @@ class ZonesResponseBuffering2(BaseModel): id: Literal["response_buffering"] """ID of the zone setting.""" - value: Literal["on", "off"] + value: Union[str, float, bool, List[str], object] """Current value of the zone setting.""" editable: Optional[Literal[True, False]] = None @@ -635,7 +599,7 @@ class ZonesRocketLoader2(BaseModel): id: Literal["rocket_loader"] """ID of the zone setting.""" - value: Literal["on", "off"] + value: Union[str, float, bool, List[str], object] """Current value of the zone setting.""" editable: Optional[Literal[True, False]] = None @@ -648,6 +612,170 @@ class ZonesRocketLoader2(BaseModel): """last time this setting was modified.""" +class ZonesSchemasAutomaticPlatformOptimizationValueUnionMember0(BaseModel): + cache_by_device_type: Optional[bool] = None + """ + Indicates whether or not + [cache by device type](https://developers.cloudflare.com/automatic-platform-optimization/reference/cache-device-type/) + is enabled. + """ + + cf: Optional[bool] = None + """Indicates whether or not Cloudflare proxy is enabled.""" + + enabled: Optional[bool] = None + """Indicates whether or not Automatic Platform Optimization is enabled.""" + + hostnames: Optional[List[str]] = None + """ + An array of hostnames where Automatic Platform Optimization for WordPress is + activated. + """ + + wordpress: Optional[bool] = None + """Indicates whether or not site is powered by WordPress.""" + + wp_plugin: Optional[bool] = None + """ + Indicates whether or not + [Cloudflare for WordPress plugin](https://wordpress.org/plugins/cloudflare/) is + installed. + """ + + +class ZonesSchemasAutomaticPlatformOptimizationValueUnionMember1(BaseModel): + cache_by_device_type: Optional[bool] = None + """ + Indicates whether or not + [cache by device type](https://developers.cloudflare.com/automatic-platform-optimization/reference/cache-device-type/) + is enabled. + """ + + cf: Optional[bool] = None + """Indicates whether or not Cloudflare proxy is enabled.""" + + enabled: Optional[bool] = None + """Indicates whether or not Automatic Platform Optimization is enabled.""" + + hostnames: Optional[List[str]] = None + """ + An array of hostnames where Automatic Platform Optimization for WordPress is + activated. + """ + + wordpress: Optional[bool] = None + """Indicates whether or not site is powered by WordPress.""" + + wp_plugin: Optional[bool] = None + """ + Indicates whether or not + [Cloudflare for WordPress plugin](https://wordpress.org/plugins/cloudflare/) is + installed. + """ + + +class ZonesSchemasAutomaticPlatformOptimizationValueUnionMember2(BaseModel): + cache_by_device_type: Optional[bool] = None + """ + Indicates whether or not + [cache by device type](https://developers.cloudflare.com/automatic-platform-optimization/reference/cache-device-type/) + is enabled. + """ + + cf: Optional[bool] = None + """Indicates whether or not Cloudflare proxy is enabled.""" + + enabled: Optional[bool] = None + """Indicates whether or not Automatic Platform Optimization is enabled.""" + + hostnames: Optional[List[str]] = None + """ + An array of hostnames where Automatic Platform Optimization for WordPress is + activated. + """ + + wordpress: Optional[bool] = None + """Indicates whether or not site is powered by WordPress.""" + + wp_plugin: Optional[bool] = None + """ + Indicates whether or not + [Cloudflare for WordPress plugin](https://wordpress.org/plugins/cloudflare/) is + installed. + """ + + +class ZonesSchemasAutomaticPlatformOptimizationValueUnionMember3(BaseModel): + cache_by_device_type: Optional[bool] = None + """ + Indicates whether or not + [cache by device type](https://developers.cloudflare.com/automatic-platform-optimization/reference/cache-device-type/) + is enabled. + """ + + cf: Optional[bool] = None + """Indicates whether or not Cloudflare proxy is enabled.""" + + enabled: Optional[bool] = None + """Indicates whether or not Automatic Platform Optimization is enabled.""" + + hostnames: Optional[List[str]] = None + """ + An array of hostnames where Automatic Platform Optimization for WordPress is + activated. + """ + + wordpress: Optional[bool] = None + """Indicates whether or not site is powered by WordPress.""" + + wp_plugin: Optional[bool] = None + """ + Indicates whether or not + [Cloudflare for WordPress plugin](https://wordpress.org/plugins/cloudflare/) is + installed. + """ + + +class ZonesSchemasAutomaticPlatformOptimizationValueUnionMember4(BaseModel): + cache_by_device_type: Optional[bool] = None + """ + Indicates whether or not + [cache by device type](https://developers.cloudflare.com/automatic-platform-optimization/reference/cache-device-type/) + is enabled. + """ + + cf: Optional[bool] = None + """Indicates whether or not Cloudflare proxy is enabled.""" + + enabled: Optional[bool] = None + """Indicates whether or not Automatic Platform Optimization is enabled.""" + + hostnames: Optional[List[str]] = None + """ + An array of hostnames where Automatic Platform Optimization for WordPress is + activated. + """ + + wordpress: Optional[bool] = None + """Indicates whether or not site is powered by WordPress.""" + + wp_plugin: Optional[bool] = None + """ + Indicates whether or not + [Cloudflare for WordPress plugin](https://wordpress.org/plugins/cloudflare/) is + installed. + """ + + +ZonesSchemasAutomaticPlatformOptimizationValue: TypeAlias = Union[ + ZonesSchemasAutomaticPlatformOptimizationValueUnionMember0, + ZonesSchemasAutomaticPlatformOptimizationValueUnionMember1, + ZonesSchemasAutomaticPlatformOptimizationValueUnionMember2, + ZonesSchemasAutomaticPlatformOptimizationValueUnionMember3, + ZonesSchemasAutomaticPlatformOptimizationValueUnionMember4, +] + + class ZonesSchemasAutomaticPlatformOptimization(BaseModel): """ [Automatic Platform Optimization for WordPress](https://developers.cloudflare.com/automatic-platform-optimization/) serves your WordPress site from Cloudflare's edge network and caches third-party fonts. @@ -656,7 +784,7 @@ class ZonesSchemasAutomaticPlatformOptimization(BaseModel): id: Literal["automatic_platform_optimization"] """ID of the zone setting.""" - value: AutomaticPlatformOptimization + value: ZonesSchemasAutomaticPlatformOptimizationValue """Current value of the zone setting.""" editable: Optional[Literal[True, False]] = None @@ -680,7 +808,7 @@ class ZonesSearchForAgents(BaseModel): id: Literal["search_for_agents"] """ID of the zone setting.""" - value: Literal["off", "on"] + value: Union[str, float, bool, List[str], object] """Current value of the zone setting.""" editable: Optional[Literal[True, False]] = None @@ -701,7 +829,7 @@ class ZonesSecurityLevel2(BaseModel): id: Literal["security_level"] """ID of the zone setting.""" - value: Literal["off", "essentially_off", "low", "medium", "high", "under_attack"] + value: Union[str, float, bool, List[str], object] """Current value of the zone setting.""" editable: Optional[Literal[True, False]] = None @@ -720,7 +848,7 @@ class ZonesSha1Support(BaseModel): id: Literal["sha1_support"] """Zone setting identifier.""" - value: Literal["off", "on"] + value: Union[str, float, bool, List[str], object] """Current value of the zone setting.""" editable: Optional[Literal[True, False]] = None @@ -741,7 +869,7 @@ class ZonesSortQueryStringForCache2(BaseModel): id: Literal["sort_query_string_for_cache"] """ID of the zone setting.""" - value: Literal["on", "off"] + value: Union[str, float, bool, List[str], object] """Current value of the zone setting.""" editable: Optional[Literal[True, False]] = None @@ -762,7 +890,7 @@ class ZonesSSL2(BaseModel): id: Literal["ssl"] """ID of the zone setting.""" - value: Literal["off", "flexible", "full", "strict"] + value: Union[str, float, bool, List[str], object] """Current value of the zone setting.""" editable: Optional[Literal[True, False]] = None @@ -781,7 +909,7 @@ class ZonesTLS1_2Only(BaseModel): id: Literal["tls_1_2_only"] """Zone setting identifier.""" - value: Literal["off", "on"] + value: Union[str, float, bool, List[str], object] """Current value of the zone setting.""" editable: Optional[Literal[True, False]] = None @@ -805,7 +933,7 @@ class ZonesTransformations(BaseModel): Shared between Image Transformations and Video Transformations. """ - value: Literal["on", "off", "open"] + value: Union[str, float, bool, List[str], object] """Current value of the zone setting.""" editable: Optional[Literal[True, False]] = None @@ -829,8 +957,14 @@ class ZonesTransformationsAllowedOrigins(BaseModel): Shared between Image Transformations and Video Transformations. """ - value: str - """Current value of the zone setting.""" + value: Union[str, float, bool, List[str], object] + """ + Comma-separated list of allowed origins. Refer to the + [Image Transformations](https://developers.cloudflare.com/images/transform-images/sources/) + and + [Video Transformations](https://developers.cloudflare.com/stream/transform-videos/#getting-started) + documentation for more information. + """ editable: Optional[Literal[True, False]] = None """ @@ -850,7 +984,7 @@ class ZonesTrueClientIPHeader2(BaseModel): id: Literal["true_client_ip_header"] """ID of the zone setting.""" - value: Literal["on", "off"] + value: Union[str, float, bool, List[str], object] """Current value of the zone setting.""" editable: Optional[Literal[True, False]] = None @@ -872,7 +1006,7 @@ class ZonesWAF2(BaseModel): id: Literal["waf"] """ID of the zone setting.""" - value: Literal["on", "off"] + value: Union[str, float, bool, List[str], object] """Current value of the zone setting.""" editable: Optional[Literal[True, False]] = None @@ -897,7 +1031,7 @@ class ZonesWebmcpEnabled(BaseModel): id: Literal["webmcp_enabled"] """ID of the zone setting.""" - value: Literal["off", "on"] + value: Union[str, float, bool, List[str], object] """Current value of the zone setting.""" editable: Optional[Literal[True, False]] = None @@ -910,6 +1044,39 @@ class ZonesWebmcpEnabled(BaseModel): """last time this setting was modified.""" +class ZonesWebmcpMcpURL(BaseModel): + """ + Optional per-zone path of the site's own MCP server, used by the WebMCP + mcp-server-client tool pack to list and call the site's MCP tools from + the browser. The path is resolved against the page's origin, so it + applies to every hostname in the zone. Only takes effect when + webmcp_enabled is on and the mcp-server-client pack is active. Leave + empty to use /mcp. This setting is currently in beta and its behavior + may change. + """ + + id: Literal["webmcp_mcp_url"] + """ID of the zone setting.""" + + value: Union[str, float, bool, List[str], object] + """ + Root-relative path (with optional query string) of this zone's MCP endpoint, for + example "/api/mcp". Surfaced to the injected bridge as the data-mcp-url + attribute. Absolute and protocol-relative URLs, fragments, and characters + outside RFC 3986 paths and queries are rejected. An empty value clears the + override so the bridge uses /mcp. + """ + + editable: Optional[Literal[True, False]] = None + """ + Whether or not this setting can be modified for this zone (based on your + Cloudflare plan level). + """ + + modified_on: Optional[datetime] = None + """last time this setting was modified.""" + + class ZonesWebmcpPacks(BaseModel): """ Optional per-zone override of which bundled WebMCP tool packs the @@ -922,8 +1089,13 @@ class ZonesWebmcpPacks(BaseModel): id: Literal["webmcp_packs"] """ID of the zone setting.""" - value: str - """Current value of the zone setting.""" + value: Union[str, float, bool, List[str], object] + """ + Comma-separated list of WebMCP tool-pack names to activate for this zone (for + example, "c2pa,mcp-server-client"), surfaced to the injected bridge as the + data-packs attribute. An empty value clears the override so the bridge uses its + built-in default pack set. + """ editable: Optional[Literal[True, False]] = None """ @@ -999,6 +1171,7 @@ class ZonesWebmcpPacks(BaseModel): ZonesTrueClientIPHeader2, ZonesWAF2, ZonesWebmcpEnabled, + ZonesWebmcpMcpURL, ZonesWebmcpPacks, WebP, Websocket, diff --git a/src/cloudflare/types/zones/tls_1_3.py b/src/cloudflare/types/zones/tls_1_3.py index 40f93e7dea0..e5faf56bff8 100644 --- a/src/cloudflare/types/zones/tls_1_3.py +++ b/src/cloudflare/types/zones/tls_1_3.py @@ -1,6 +1,6 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import Optional +from typing import List, Union, Optional from datetime import datetime from typing_extensions import Literal @@ -15,7 +15,7 @@ class TLS1_3(BaseModel): id: Literal["tls_1_3"] """ID of the zone setting.""" - value: Literal["on", "off", "zrt"] + value: Union[str, float, bool, List[str], object] """Current value of the zone setting.""" editable: Optional[Literal[True, False]] = None diff --git a/src/cloudflare/types/zones/tls_client_auth.py b/src/cloudflare/types/zones/tls_client_auth.py index 851154373b2..41620a9b2a1 100644 --- a/src/cloudflare/types/zones/tls_client_auth.py +++ b/src/cloudflare/types/zones/tls_client_auth.py @@ -1,6 +1,6 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import Optional +from typing import List, Union, Optional from datetime import datetime from typing_extensions import Literal @@ -17,7 +17,7 @@ class TLSClientAuth(BaseModel): id: Literal["tls_client_auth"] """ID of the zone setting.""" - value: Literal["on", "off"] + value: Union[str, float, bool, List[str], object] """Current value of the zone setting.""" editable: Optional[Literal[True, False]] = None diff --git a/src/cloudflare/types/zones/webp.py b/src/cloudflare/types/zones/webp.py index e9a13b2621c..ce3027f59ed 100644 --- a/src/cloudflare/types/zones/webp.py +++ b/src/cloudflare/types/zones/webp.py @@ -1,6 +1,6 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import Optional +from typing import List, Union, Optional from datetime import datetime from typing_extensions import Literal @@ -17,7 +17,7 @@ class WebP(BaseModel): id: Literal["webp"] """ID of the zone setting.""" - value: Literal["off", "on"] + value: Union[str, float, bool, List[str], object] """Current value of the zone setting.""" editable: Optional[Literal[True, False]] = None diff --git a/src/cloudflare/types/zones/websocket.py b/src/cloudflare/types/zones/websocket.py index 4a87e2140a4..a520733f9bd 100644 --- a/src/cloudflare/types/zones/websocket.py +++ b/src/cloudflare/types/zones/websocket.py @@ -1,6 +1,6 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import Optional +from typing import List, Union, Optional from datetime import datetime from typing_extensions import Literal @@ -17,7 +17,7 @@ class Websocket(BaseModel): id: Literal["websockets"] """ID of the zone setting.""" - value: Literal["off", "on"] + value: Union[str, float, bool, List[str], object] """Current value of the zone setting.""" editable: Optional[Literal[True, False]] = None diff --git a/src/cloudflare/types/zones/zero_rtt.py b/src/cloudflare/types/zones/zero_rtt.py index 004b2c5a3d4..dbe7bc41b74 100644 --- a/src/cloudflare/types/zones/zero_rtt.py +++ b/src/cloudflare/types/zones/zero_rtt.py @@ -1,6 +1,6 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import Optional +from typing import List, Union, Optional from datetime import datetime from typing_extensions import Literal @@ -15,7 +15,7 @@ class ZeroRTT(BaseModel): id: Literal["0rtt"] """ID of the zone setting.""" - value: Literal["on", "off"] + value: Union[str, float, bool, List[str], object] """Current value of the zone setting.""" editable: Optional[Literal[True, False]] = None diff --git a/tests/api_resources/abuse_reports/test_mitigations.py b/tests/api_resources/abuse_reports/test_mitigations.py index cf5e6b6280b..277957853a3 100644 --- a/tests/api_resources/abuse_reports/test_mitigations.py +++ b/tests/api_resources/abuse_reports/test_mitigations.py @@ -127,6 +127,7 @@ def test_method_review_with_all_params(self, client: Cloudflare) -> None: "company": "company", "counter_notice_response": "counter_notice_response", }, + explanation="explanation", type="counter_notice", ) assert_matches_type(SyncSinglePage[MitigationReviewResponse], mitigation, path=["response"]) @@ -286,6 +287,7 @@ async def test_method_review_with_all_params(self, async_client: AsyncCloudflare "company": "company", "counter_notice_response": "counter_notice_response", }, + explanation="explanation", type="counter_notice", ) assert_matches_type(AsyncSinglePage[MitigationReviewResponse], mitigation, path=["response"]) diff --git a/tests/api_resources/accounts/subscriptions/test_bulk.py b/tests/api_resources/accounts/subscriptions/test_bulk.py index 60947174c64..48df3266f2f 100644 --- a/tests/api_resources/accounts/subscriptions/test_bulk.py +++ b/tests/api_resources/accounts/subscriptions/test_bulk.py @@ -3,7 +3,7 @@ from __future__ import annotations import os -from typing import Any, Optional, cast +from typing import Any, cast import pytest @@ -22,7 +22,7 @@ def test_method_create(self, client: Cloudflare) -> None: bulk = client.accounts.subscriptions.bulk.create( account_id="023e105f4ecef8ad9ca31a8372d0c353", ) - assert_matches_type(Optional[BulkCreateResponse], bulk, path=["response"]) + assert_matches_type(BulkCreateResponse, bulk, path=["response"]) @parametrize def test_method_create_with_all_params(self, client: Cloudflare) -> None: @@ -47,7 +47,7 @@ def test_method_create_with_all_params(self, client: Cloudflare) -> None: ], user_is_on_session=True, ) - assert_matches_type(Optional[BulkCreateResponse], bulk, path=["response"]) + assert_matches_type(BulkCreateResponse, bulk, path=["response"]) @parametrize def test_raw_response_create(self, client: Cloudflare) -> None: @@ -58,7 +58,7 @@ def test_raw_response_create(self, client: Cloudflare) -> None: assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" bulk = response.parse() - assert_matches_type(Optional[BulkCreateResponse], bulk, path=["response"]) + assert_matches_type(BulkCreateResponse, bulk, path=["response"]) @parametrize def test_streaming_response_create(self, client: Cloudflare) -> None: @@ -69,7 +69,7 @@ def test_streaming_response_create(self, client: Cloudflare) -> None: assert response.http_request.headers.get("X-Stainless-Lang") == "python" bulk = response.parse() - assert_matches_type(Optional[BulkCreateResponse], bulk, path=["response"]) + assert_matches_type(BulkCreateResponse, bulk, path=["response"]) assert cast(Any, response.is_closed) is True @@ -91,7 +91,7 @@ async def test_method_create(self, async_client: AsyncCloudflare) -> None: bulk = await async_client.accounts.subscriptions.bulk.create( account_id="023e105f4ecef8ad9ca31a8372d0c353", ) - assert_matches_type(Optional[BulkCreateResponse], bulk, path=["response"]) + assert_matches_type(BulkCreateResponse, bulk, path=["response"]) @parametrize async def test_method_create_with_all_params(self, async_client: AsyncCloudflare) -> None: @@ -116,7 +116,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncCloudflare ], user_is_on_session=True, ) - assert_matches_type(Optional[BulkCreateResponse], bulk, path=["response"]) + assert_matches_type(BulkCreateResponse, bulk, path=["response"]) @parametrize async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None: @@ -127,7 +127,7 @@ async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None: assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" bulk = await response.parse() - assert_matches_type(Optional[BulkCreateResponse], bulk, path=["response"]) + assert_matches_type(BulkCreateResponse, bulk, path=["response"]) @parametrize async def test_streaming_response_create(self, async_client: AsyncCloudflare) -> None: @@ -138,7 +138,7 @@ async def test_streaming_response_create(self, async_client: AsyncCloudflare) -> assert response.http_request.headers.get("X-Stainless-Lang") == "python" bulk = await response.parse() - assert_matches_type(Optional[BulkCreateResponse], bulk, path=["response"]) + assert_matches_type(BulkCreateResponse, bulk, path=["response"]) assert cast(Any, response.is_closed) is True diff --git a/tests/api_resources/accounts/test_pay_bad_debt.py b/tests/api_resources/accounts/test_pay_bad_debt.py deleted file mode 100644 index 83b4c52cc07..00000000000 --- a/tests/api_resources/accounts/test_pay_bad_debt.py +++ /dev/null @@ -1,116 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -import os -from typing import Any, cast - -import pytest - -from cloudflare import Cloudflare, AsyncCloudflare -from tests.utils import assert_matches_type -from cloudflare.types.accounts import PayBadDebtCreateResponse - -base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") - - -class TestPayBadDebt: - parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) - - @parametrize - def test_method_create(self, client: Cloudflare) -> None: - pay_bad_debt = client.accounts.pay_bad_debt.create( - account_id="023e105f4ecef8ad9ca31a8372d0c353", - ) - assert_matches_type(PayBadDebtCreateResponse, pay_bad_debt, path=["response"]) - - @parametrize - def test_method_create_with_all_params(self, client: Cloudflare) -> None: - pay_bad_debt = client.accounts.pay_bad_debt.create( - account_id="023e105f4ecef8ad9ca31a8372d0c353", - payment_method_id="payment_method_id", - ) - assert_matches_type(PayBadDebtCreateResponse, pay_bad_debt, path=["response"]) - - @parametrize - def test_raw_response_create(self, client: Cloudflare) -> None: - response = client.accounts.pay_bad_debt.with_raw_response.create( - account_id="023e105f4ecef8ad9ca31a8372d0c353", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - pay_bad_debt = response.parse() - assert_matches_type(PayBadDebtCreateResponse, pay_bad_debt, path=["response"]) - - @parametrize - def test_streaming_response_create(self, client: Cloudflare) -> None: - with client.accounts.pay_bad_debt.with_streaming_response.create( - account_id="023e105f4ecef8ad9ca31a8372d0c353", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - pay_bad_debt = response.parse() - assert_matches_type(PayBadDebtCreateResponse, pay_bad_debt, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @parametrize - def test_path_params_create(self, client: Cloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): - client.accounts.pay_bad_debt.with_raw_response.create( - account_id="", - ) - - -class TestAsyncPayBadDebt: - parametrize = pytest.mark.parametrize( - "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] - ) - - @parametrize - async def test_method_create(self, async_client: AsyncCloudflare) -> None: - pay_bad_debt = await async_client.accounts.pay_bad_debt.create( - account_id="023e105f4ecef8ad9ca31a8372d0c353", - ) - assert_matches_type(PayBadDebtCreateResponse, pay_bad_debt, path=["response"]) - - @parametrize - async def test_method_create_with_all_params(self, async_client: AsyncCloudflare) -> None: - pay_bad_debt = await async_client.accounts.pay_bad_debt.create( - account_id="023e105f4ecef8ad9ca31a8372d0c353", - payment_method_id="payment_method_id", - ) - assert_matches_type(PayBadDebtCreateResponse, pay_bad_debt, path=["response"]) - - @parametrize - async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None: - response = await async_client.accounts.pay_bad_debt.with_raw_response.create( - account_id="023e105f4ecef8ad9ca31a8372d0c353", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - pay_bad_debt = await response.parse() - assert_matches_type(PayBadDebtCreateResponse, pay_bad_debt, path=["response"]) - - @parametrize - async def test_streaming_response_create(self, async_client: AsyncCloudflare) -> None: - async with async_client.accounts.pay_bad_debt.with_streaming_response.create( - account_id="023e105f4ecef8ad9ca31a8372d0c353", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - pay_bad_debt = await response.parse() - assert_matches_type(PayBadDebtCreateResponse, pay_bad_debt, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @parametrize - async def test_path_params_create(self, async_client: AsyncCloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): - await async_client.accounts.pay_bad_debt.with_raw_response.create( - account_id="", - ) diff --git a/tests/api_resources/ai_gateway/billing/topup/test_config.py b/tests/api_resources/ai_gateway/billing/topup/test_config.py index 1890e4b80b2..33a39b6d1d8 100644 --- a/tests/api_resources/ai_gateway/billing/topup/test_config.py +++ b/tests/api_resources/ai_gateway/billing/topup/test_config.py @@ -19,7 +19,7 @@ class TestConfig: @pytest.mark.skip(reason="HTTP 404 error from prism") @parametrize - def test_method_create(self, client: Cloudflare) -> None: + def test_method_create_overload_1(self, client: Cloudflare) -> None: config = client.ai_gateway.billing.topup.config.create( account_id="account_id", amount=5000, @@ -29,7 +29,7 @@ def test_method_create(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="HTTP 404 error from prism") @parametrize - def test_raw_response_create(self, client: Cloudflare) -> None: + def test_raw_response_create_overload_1(self, client: Cloudflare) -> None: response = client.ai_gateway.billing.topup.config.with_raw_response.create( account_id="account_id", amount=5000, @@ -43,7 +43,7 @@ def test_raw_response_create(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="HTTP 404 error from prism") @parametrize - def test_streaming_response_create(self, client: Cloudflare) -> None: + def test_streaming_response_create_overload_1(self, client: Cloudflare) -> None: with client.ai_gateway.billing.topup.config.with_streaming_response.create( account_id="account_id", amount=5000, @@ -59,7 +59,7 @@ def test_streaming_response_create(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="HTTP 404 error from prism") @parametrize - def test_path_params_create(self, client: Cloudflare) -> None: + def test_path_params_create_overload_1(self, client: Cloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): client.ai_gateway.billing.topup.config.with_raw_response.create( account_id="", @@ -67,6 +67,82 @@ def test_path_params_create(self, client: Cloudflare) -> None: threshold=500, ) + @pytest.mark.skip(reason="HTTP 404 error from prism") + @parametrize + def test_method_create_overload_2(self, client: Cloudflare) -> None: + config = client.ai_gateway.billing.topup.config.create( + account_id="account_id", + amount=5000, + consent_version="auto-topup-v1", + payment_method_id="pm_123", + setup_idempotency_key="f6af84c0-12d6-4c46-840d-2e4934df85e1", + threshold=500, + ) + assert_matches_type(ConfigCreateResponse, config, path=["response"]) + + @pytest.mark.skip(reason="HTTP 404 error from prism") + @parametrize + def test_method_create_with_all_params_overload_2(self, client: Cloudflare) -> None: + config = client.ai_gateway.billing.topup.config.create( + account_id="account_id", + amount=5000, + consent_version="auto-topup-v1", + payment_method_id="pm_123", + setup_idempotency_key="f6af84c0-12d6-4c46-840d-2e4934df85e1", + threshold=500, + setup_intent_id="seti_123", + ) + assert_matches_type(ConfigCreateResponse, config, path=["response"]) + + @pytest.mark.skip(reason="HTTP 404 error from prism") + @parametrize + def test_raw_response_create_overload_2(self, client: Cloudflare) -> None: + response = client.ai_gateway.billing.topup.config.with_raw_response.create( + account_id="account_id", + amount=5000, + consent_version="auto-topup-v1", + payment_method_id="pm_123", + setup_idempotency_key="f6af84c0-12d6-4c46-840d-2e4934df85e1", + threshold=500, + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + config = response.parse() + assert_matches_type(ConfigCreateResponse, config, path=["response"]) + + @pytest.mark.skip(reason="HTTP 404 error from prism") + @parametrize + def test_streaming_response_create_overload_2(self, client: Cloudflare) -> None: + with client.ai_gateway.billing.topup.config.with_streaming_response.create( + account_id="account_id", + amount=5000, + consent_version="auto-topup-v1", + payment_method_id="pm_123", + setup_idempotency_key="f6af84c0-12d6-4c46-840d-2e4934df85e1", + threshold=500, + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + config = response.parse() + assert_matches_type(ConfigCreateResponse, config, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="HTTP 404 error from prism") + @parametrize + def test_path_params_create_overload_2(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.ai_gateway.billing.topup.config.with_raw_response.create( + account_id="", + amount=5000, + consent_version="auto-topup-v1", + payment_method_id="pm_123", + setup_idempotency_key="f6af84c0-12d6-4c46-840d-2e4934df85e1", + threshold=500, + ) + @pytest.mark.skip(reason="HTTP 404 error from prism") @parametrize def test_method_delete(self, client: Cloudflare) -> None: @@ -159,20 +235,90 @@ class TestAsyncConfig: @pytest.mark.skip(reason="HTTP 404 error from prism") @parametrize - async def test_method_create(self, async_client: AsyncCloudflare) -> None: + async def test_method_create_overload_1(self, async_client: AsyncCloudflare) -> None: + config = await async_client.ai_gateway.billing.topup.config.create( + account_id="account_id", + amount=5000, + threshold=500, + ) + assert_matches_type(ConfigCreateResponse, config, path=["response"]) + + @pytest.mark.skip(reason="HTTP 404 error from prism") + @parametrize + async def test_raw_response_create_overload_1(self, async_client: AsyncCloudflare) -> None: + response = await async_client.ai_gateway.billing.topup.config.with_raw_response.create( + account_id="account_id", + amount=5000, + threshold=500, + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + config = await response.parse() + assert_matches_type(ConfigCreateResponse, config, path=["response"]) + + @pytest.mark.skip(reason="HTTP 404 error from prism") + @parametrize + async def test_streaming_response_create_overload_1(self, async_client: AsyncCloudflare) -> None: + async with async_client.ai_gateway.billing.topup.config.with_streaming_response.create( + account_id="account_id", + amount=5000, + threshold=500, + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + config = await response.parse() + assert_matches_type(ConfigCreateResponse, config, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="HTTP 404 error from prism") + @parametrize + async def test_path_params_create_overload_1(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.ai_gateway.billing.topup.config.with_raw_response.create( + account_id="", + amount=5000, + threshold=500, + ) + + @pytest.mark.skip(reason="HTTP 404 error from prism") + @parametrize + async def test_method_create_overload_2(self, async_client: AsyncCloudflare) -> None: + config = await async_client.ai_gateway.billing.topup.config.create( + account_id="account_id", + amount=5000, + consent_version="auto-topup-v1", + payment_method_id="pm_123", + setup_idempotency_key="f6af84c0-12d6-4c46-840d-2e4934df85e1", + threshold=500, + ) + assert_matches_type(ConfigCreateResponse, config, path=["response"]) + + @pytest.mark.skip(reason="HTTP 404 error from prism") + @parametrize + async def test_method_create_with_all_params_overload_2(self, async_client: AsyncCloudflare) -> None: config = await async_client.ai_gateway.billing.topup.config.create( account_id="account_id", amount=5000, + consent_version="auto-topup-v1", + payment_method_id="pm_123", + setup_idempotency_key="f6af84c0-12d6-4c46-840d-2e4934df85e1", threshold=500, + setup_intent_id="seti_123", ) assert_matches_type(ConfigCreateResponse, config, path=["response"]) @pytest.mark.skip(reason="HTTP 404 error from prism") @parametrize - async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None: + async def test_raw_response_create_overload_2(self, async_client: AsyncCloudflare) -> None: response = await async_client.ai_gateway.billing.topup.config.with_raw_response.create( account_id="account_id", amount=5000, + consent_version="auto-topup-v1", + payment_method_id="pm_123", + setup_idempotency_key="f6af84c0-12d6-4c46-840d-2e4934df85e1", threshold=500, ) @@ -183,10 +329,13 @@ async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None: @pytest.mark.skip(reason="HTTP 404 error from prism") @parametrize - async def test_streaming_response_create(self, async_client: AsyncCloudflare) -> None: + async def test_streaming_response_create_overload_2(self, async_client: AsyncCloudflare) -> None: async with async_client.ai_gateway.billing.topup.config.with_streaming_response.create( account_id="account_id", amount=5000, + consent_version="auto-topup-v1", + payment_method_id="pm_123", + setup_idempotency_key="f6af84c0-12d6-4c46-840d-2e4934df85e1", threshold=500, ) as response: assert not response.is_closed @@ -199,11 +348,14 @@ async def test_streaming_response_create(self, async_client: AsyncCloudflare) -> @pytest.mark.skip(reason="HTTP 404 error from prism") @parametrize - async def test_path_params_create(self, async_client: AsyncCloudflare) -> None: + async def test_path_params_create_overload_2(self, async_client: AsyncCloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): await async_client.ai_gateway.billing.topup.config.with_raw_response.create( account_id="", amount=5000, + consent_version="auto-topup-v1", + payment_method_id="pm_123", + setup_idempotency_key="f6af84c0-12d6-4c46-840d-2e4934df85e1", threshold=500, ) diff --git a/tests/api_resources/aisearch/namespaces/instances/test_items.py b/tests/api_resources/aisearch/namespaces/instances/test_items.py index 839f66c136f..5dd626a0cc6 100644 --- a/tests/api_resources/aisearch/namespaces/instances/test_items.py +++ b/tests/api_resources/aisearch/namespaces/instances/test_items.py @@ -40,7 +40,7 @@ def test_method_list(self, client: Cloudflare) -> None: item = client.aisearch.namespaces.instances.items.list( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", ) assert_matches_type(SyncV4PagePaginationArray[ItemListResponse], item, path=["response"]) @@ -49,7 +49,7 @@ def test_method_list_with_all_params(self, client: Cloudflare) -> None: item = client.aisearch.namespaces.instances.items.list( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", item_id="item_id", key="key", metadata_filter="metadata_filter", @@ -67,7 +67,7 @@ def test_raw_response_list(self, client: Cloudflare) -> None: response = client.aisearch.namespaces.instances.items.with_raw_response.list( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", ) assert response.is_closed is True @@ -80,7 +80,7 @@ def test_streaming_response_list(self, client: Cloudflare) -> None: with client.aisearch.namespaces.instances.items.with_streaming_response.list( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -96,21 +96,21 @@ def test_path_params_list(self, client: Cloudflare) -> None: client.aisearch.namespaces.instances.items.with_raw_response.list( id="my-ai-search", account_id="", - name="my-namespace", + namespace="my-namespace", ) - with pytest.raises(ValueError, match=r"Expected a non-empty value for `name` but received ''"): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `namespace` but received ''"): client.aisearch.namespaces.instances.items.with_raw_response.list( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="", + namespace="", ) with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): client.aisearch.namespaces.instances.items.with_raw_response.list( id="", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", ) @parametrize @@ -118,7 +118,7 @@ def test_method_delete(self, client: Cloudflare) -> None: item = client.aisearch.namespaces.instances.items.delete( item_id="item_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", ) assert_matches_type(ItemDeleteResponse, item, path=["response"]) @@ -128,7 +128,7 @@ def test_raw_response_delete(self, client: Cloudflare) -> None: response = client.aisearch.namespaces.instances.items.with_raw_response.delete( item_id="item_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", ) @@ -142,7 +142,7 @@ def test_streaming_response_delete(self, client: Cloudflare) -> None: with client.aisearch.namespaces.instances.items.with_streaming_response.delete( item_id="item_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", ) as response: assert not response.is_closed @@ -159,15 +159,15 @@ def test_path_params_delete(self, client: Cloudflare) -> None: client.aisearch.namespaces.instances.items.with_raw_response.delete( item_id="item_id", account_id="", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", ) - with pytest.raises(ValueError, match=r"Expected a non-empty value for `name` but received ''"): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `namespace` but received ''"): client.aisearch.namespaces.instances.items.with_raw_response.delete( item_id="item_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="", + namespace="", id="my-ai-search", ) @@ -175,7 +175,7 @@ def test_path_params_delete(self, client: Cloudflare) -> None: client.aisearch.namespaces.instances.items.with_raw_response.delete( item_id="item_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="", ) @@ -183,7 +183,7 @@ def test_path_params_delete(self, client: Cloudflare) -> None: client.aisearch.namespaces.instances.items.with_raw_response.delete( item_id="", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", ) @@ -192,7 +192,7 @@ def test_method_chunks(self, client: Cloudflare) -> None: item = client.aisearch.namespaces.instances.items.chunks( item_id="item_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", ) assert_matches_type(ItemChunksResponse, item, path=["response"]) @@ -202,7 +202,7 @@ def test_method_chunks_with_all_params(self, client: Cloudflare) -> None: item = client.aisearch.namespaces.instances.items.chunks( item_id="item_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", limit=1, offset=0, @@ -214,7 +214,7 @@ def test_raw_response_chunks(self, client: Cloudflare) -> None: response = client.aisearch.namespaces.instances.items.with_raw_response.chunks( item_id="item_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", ) @@ -228,7 +228,7 @@ def test_streaming_response_chunks(self, client: Cloudflare) -> None: with client.aisearch.namespaces.instances.items.with_streaming_response.chunks( item_id="item_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", ) as response: assert not response.is_closed @@ -245,15 +245,15 @@ def test_path_params_chunks(self, client: Cloudflare) -> None: client.aisearch.namespaces.instances.items.with_raw_response.chunks( item_id="item_id", account_id="", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", ) - with pytest.raises(ValueError, match=r"Expected a non-empty value for `name` but received ''"): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `namespace` but received ''"): client.aisearch.namespaces.instances.items.with_raw_response.chunks( item_id="item_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="", + namespace="", id="my-ai-search", ) @@ -261,7 +261,7 @@ def test_path_params_chunks(self, client: Cloudflare) -> None: client.aisearch.namespaces.instances.items.with_raw_response.chunks( item_id="item_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="", ) @@ -269,7 +269,7 @@ def test_path_params_chunks(self, client: Cloudflare) -> None: client.aisearch.namespaces.instances.items.with_raw_response.chunks( item_id="", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", ) @@ -278,7 +278,7 @@ def test_method_create_or_update(self, client: Cloudflare) -> None: item = client.aisearch.namespaces.instances.items.create_or_update( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", key="key", next_action="INDEX", ) @@ -289,7 +289,7 @@ def test_method_create_or_update_with_all_params(self, client: Cloudflare) -> No item = client.aisearch.namespaces.instances.items.create_or_update( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", key="key", next_action="INDEX", wait_for_completion=True, @@ -301,7 +301,7 @@ def test_raw_response_create_or_update(self, client: Cloudflare) -> None: response = client.aisearch.namespaces.instances.items.with_raw_response.create_or_update( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", key="key", next_action="INDEX", ) @@ -316,7 +316,7 @@ def test_streaming_response_create_or_update(self, client: Cloudflare) -> None: with client.aisearch.namespaces.instances.items.with_streaming_response.create_or_update( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", key="key", next_action="INDEX", ) as response: @@ -334,16 +334,16 @@ def test_path_params_create_or_update(self, client: Cloudflare) -> None: client.aisearch.namespaces.instances.items.with_raw_response.create_or_update( id="my-ai-search", account_id="", - name="my-namespace", + namespace="my-namespace", key="key", next_action="INDEX", ) - with pytest.raises(ValueError, match=r"Expected a non-empty value for `name` but received ''"): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `namespace` but received ''"): client.aisearch.namespaces.instances.items.with_raw_response.create_or_update( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="", + namespace="", key="key", next_action="INDEX", ) @@ -352,7 +352,7 @@ def test_path_params_create_or_update(self, client: Cloudflare) -> None: client.aisearch.namespaces.instances.items.with_raw_response.create_or_update( id="", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", key="key", next_action="INDEX", ) @@ -366,7 +366,7 @@ def test_method_download(self, client: Cloudflare, respx_mock: MockRouter) -> No item = client.aisearch.namespaces.instances.items.download( item_id="item_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", ) assert item.is_closed @@ -384,7 +384,7 @@ def test_raw_response_download(self, client: Cloudflare, respx_mock: MockRouter) item = client.aisearch.namespaces.instances.items.with_raw_response.download( item_id="item_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", ) @@ -402,7 +402,7 @@ def test_streaming_response_download(self, client: Cloudflare, respx_mock: MockR with client.aisearch.namespaces.instances.items.with_streaming_response.download( item_id="item_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", ) as item: assert not item.is_closed @@ -421,15 +421,15 @@ def test_path_params_download(self, client: Cloudflare) -> None: client.aisearch.namespaces.instances.items.with_raw_response.download( item_id="item_id", account_id="", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", ) - with pytest.raises(ValueError, match=r"Expected a non-empty value for `name` but received ''"): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `namespace` but received ''"): client.aisearch.namespaces.instances.items.with_raw_response.download( item_id="item_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="", + namespace="", id="my-ai-search", ) @@ -437,7 +437,7 @@ def test_path_params_download(self, client: Cloudflare) -> None: client.aisearch.namespaces.instances.items.with_raw_response.download( item_id="item_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="", ) @@ -445,7 +445,7 @@ def test_path_params_download(self, client: Cloudflare) -> None: client.aisearch.namespaces.instances.items.with_raw_response.download( item_id="", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", ) @@ -454,7 +454,7 @@ def test_method_get(self, client: Cloudflare) -> None: item = client.aisearch.namespaces.instances.items.get( item_id="item_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", ) assert_matches_type(ItemGetResponse, item, path=["response"]) @@ -464,7 +464,7 @@ def test_raw_response_get(self, client: Cloudflare) -> None: response = client.aisearch.namespaces.instances.items.with_raw_response.get( item_id="item_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", ) @@ -478,7 +478,7 @@ def test_streaming_response_get(self, client: Cloudflare) -> None: with client.aisearch.namespaces.instances.items.with_streaming_response.get( item_id="item_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", ) as response: assert not response.is_closed @@ -495,15 +495,15 @@ def test_path_params_get(self, client: Cloudflare) -> None: client.aisearch.namespaces.instances.items.with_raw_response.get( item_id="item_id", account_id="", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", ) - with pytest.raises(ValueError, match=r"Expected a non-empty value for `name` but received ''"): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `namespace` but received ''"): client.aisearch.namespaces.instances.items.with_raw_response.get( item_id="item_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="", + namespace="", id="my-ai-search", ) @@ -511,7 +511,7 @@ def test_path_params_get(self, client: Cloudflare) -> None: client.aisearch.namespaces.instances.items.with_raw_response.get( item_id="item_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="", ) @@ -519,7 +519,7 @@ def test_path_params_get(self, client: Cloudflare) -> None: client.aisearch.namespaces.instances.items.with_raw_response.get( item_id="", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", ) @@ -528,7 +528,7 @@ def test_method_logs(self, client: Cloudflare) -> None: item = client.aisearch.namespaces.instances.items.logs( item_id="item_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", ) assert_matches_type(ItemLogsResponse, item, path=["response"]) @@ -538,7 +538,7 @@ def test_method_logs_with_all_params(self, client: Cloudflare) -> None: item = client.aisearch.namespaces.instances.items.logs( item_id="item_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", cursor="cursor", limit=1, @@ -550,7 +550,7 @@ def test_raw_response_logs(self, client: Cloudflare) -> None: response = client.aisearch.namespaces.instances.items.with_raw_response.logs( item_id="item_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", ) @@ -564,7 +564,7 @@ def test_streaming_response_logs(self, client: Cloudflare) -> None: with client.aisearch.namespaces.instances.items.with_streaming_response.logs( item_id="item_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", ) as response: assert not response.is_closed @@ -581,15 +581,15 @@ def test_path_params_logs(self, client: Cloudflare) -> None: client.aisearch.namespaces.instances.items.with_raw_response.logs( item_id="item_id", account_id="", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", ) - with pytest.raises(ValueError, match=r"Expected a non-empty value for `name` but received ''"): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `namespace` but received ''"): client.aisearch.namespaces.instances.items.with_raw_response.logs( item_id="item_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="", + namespace="", id="my-ai-search", ) @@ -597,7 +597,7 @@ def test_path_params_logs(self, client: Cloudflare) -> None: client.aisearch.namespaces.instances.items.with_raw_response.logs( item_id="item_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="", ) @@ -605,7 +605,7 @@ def test_path_params_logs(self, client: Cloudflare) -> None: client.aisearch.namespaces.instances.items.with_raw_response.logs( item_id="", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", ) @@ -614,7 +614,7 @@ def test_method_sync(self, client: Cloudflare) -> None: item = client.aisearch.namespaces.instances.items.sync( item_id="item_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", next_action="INDEX", ) @@ -625,7 +625,7 @@ def test_method_sync_with_all_params(self, client: Cloudflare) -> None: item = client.aisearch.namespaces.instances.items.sync( item_id="item_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", next_action="INDEX", wait_for_completion=True, @@ -637,7 +637,7 @@ def test_raw_response_sync(self, client: Cloudflare) -> None: response = client.aisearch.namespaces.instances.items.with_raw_response.sync( item_id="item_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", next_action="INDEX", ) @@ -652,7 +652,7 @@ def test_streaming_response_sync(self, client: Cloudflare) -> None: with client.aisearch.namespaces.instances.items.with_streaming_response.sync( item_id="item_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", next_action="INDEX", ) as response: @@ -670,16 +670,16 @@ def test_path_params_sync(self, client: Cloudflare) -> None: client.aisearch.namespaces.instances.items.with_raw_response.sync( item_id="item_id", account_id="", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", next_action="INDEX", ) - with pytest.raises(ValueError, match=r"Expected a non-empty value for `name` but received ''"): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `namespace` but received ''"): client.aisearch.namespaces.instances.items.with_raw_response.sync( item_id="item_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="", + namespace="", id="my-ai-search", next_action="INDEX", ) @@ -688,7 +688,7 @@ def test_path_params_sync(self, client: Cloudflare) -> None: client.aisearch.namespaces.instances.items.with_raw_response.sync( item_id="item_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="", next_action="INDEX", ) @@ -697,7 +697,7 @@ def test_path_params_sync(self, client: Cloudflare) -> None: client.aisearch.namespaces.instances.items.with_raw_response.sync( item_id="", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", next_action="INDEX", ) @@ -707,7 +707,7 @@ def test_method_upload(self, client: Cloudflare) -> None: item = client.aisearch.namespaces.instances.items.upload( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", file={"file": b"Example data"}, ) assert_matches_type(ItemUploadResponse, item, path=["response"]) @@ -717,7 +717,7 @@ def test_method_upload_with_all_params(self, client: Cloudflare) -> None: item = client.aisearch.namespaces.instances.items.upload( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", file={ "file": b"Example data", "metadata": "metadata", @@ -731,7 +731,7 @@ def test_raw_response_upload(self, client: Cloudflare) -> None: response = client.aisearch.namespaces.instances.items.with_raw_response.upload( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", file={"file": b"Example data"}, ) @@ -745,7 +745,7 @@ def test_streaming_response_upload(self, client: Cloudflare) -> None: with client.aisearch.namespaces.instances.items.with_streaming_response.upload( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", file={"file": b"Example data"}, ) as response: assert not response.is_closed @@ -762,15 +762,15 @@ def test_path_params_upload(self, client: Cloudflare) -> None: client.aisearch.namespaces.instances.items.with_raw_response.upload( id="my-ai-search", account_id="", - name="my-namespace", + namespace="my-namespace", file={"file": b"Example data"}, ) - with pytest.raises(ValueError, match=r"Expected a non-empty value for `name` but received ''"): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `namespace` but received ''"): client.aisearch.namespaces.instances.items.with_raw_response.upload( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="", + namespace="", file={"file": b"Example data"}, ) @@ -778,7 +778,7 @@ def test_path_params_upload(self, client: Cloudflare) -> None: client.aisearch.namespaces.instances.items.with_raw_response.upload( id="", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", file={"file": b"Example data"}, ) @@ -793,7 +793,7 @@ async def test_method_list(self, async_client: AsyncCloudflare) -> None: item = await async_client.aisearch.namespaces.instances.items.list( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", ) assert_matches_type(AsyncV4PagePaginationArray[ItemListResponse], item, path=["response"]) @@ -802,7 +802,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncCloudflare) item = await async_client.aisearch.namespaces.instances.items.list( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", item_id="item_id", key="key", metadata_filter="metadata_filter", @@ -820,7 +820,7 @@ async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None: response = await async_client.aisearch.namespaces.instances.items.with_raw_response.list( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", ) assert response.is_closed is True @@ -833,7 +833,7 @@ async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> N async with async_client.aisearch.namespaces.instances.items.with_streaming_response.list( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -849,21 +849,21 @@ async def test_path_params_list(self, async_client: AsyncCloudflare) -> None: await async_client.aisearch.namespaces.instances.items.with_raw_response.list( id="my-ai-search", account_id="", - name="my-namespace", + namespace="my-namespace", ) - with pytest.raises(ValueError, match=r"Expected a non-empty value for `name` but received ''"): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `namespace` but received ''"): await async_client.aisearch.namespaces.instances.items.with_raw_response.list( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="", + namespace="", ) with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): await async_client.aisearch.namespaces.instances.items.with_raw_response.list( id="", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", ) @parametrize @@ -871,7 +871,7 @@ async def test_method_delete(self, async_client: AsyncCloudflare) -> None: item = await async_client.aisearch.namespaces.instances.items.delete( item_id="item_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", ) assert_matches_type(ItemDeleteResponse, item, path=["response"]) @@ -881,7 +881,7 @@ async def test_raw_response_delete(self, async_client: AsyncCloudflare) -> None: response = await async_client.aisearch.namespaces.instances.items.with_raw_response.delete( item_id="item_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", ) @@ -895,7 +895,7 @@ async def test_streaming_response_delete(self, async_client: AsyncCloudflare) -> async with async_client.aisearch.namespaces.instances.items.with_streaming_response.delete( item_id="item_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", ) as response: assert not response.is_closed @@ -912,15 +912,15 @@ async def test_path_params_delete(self, async_client: AsyncCloudflare) -> None: await async_client.aisearch.namespaces.instances.items.with_raw_response.delete( item_id="item_id", account_id="", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", ) - with pytest.raises(ValueError, match=r"Expected a non-empty value for `name` but received ''"): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `namespace` but received ''"): await async_client.aisearch.namespaces.instances.items.with_raw_response.delete( item_id="item_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="", + namespace="", id="my-ai-search", ) @@ -928,7 +928,7 @@ async def test_path_params_delete(self, async_client: AsyncCloudflare) -> None: await async_client.aisearch.namespaces.instances.items.with_raw_response.delete( item_id="item_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="", ) @@ -936,7 +936,7 @@ async def test_path_params_delete(self, async_client: AsyncCloudflare) -> None: await async_client.aisearch.namespaces.instances.items.with_raw_response.delete( item_id="", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", ) @@ -945,7 +945,7 @@ async def test_method_chunks(self, async_client: AsyncCloudflare) -> None: item = await async_client.aisearch.namespaces.instances.items.chunks( item_id="item_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", ) assert_matches_type(ItemChunksResponse, item, path=["response"]) @@ -955,7 +955,7 @@ async def test_method_chunks_with_all_params(self, async_client: AsyncCloudflare item = await async_client.aisearch.namespaces.instances.items.chunks( item_id="item_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", limit=1, offset=0, @@ -967,7 +967,7 @@ async def test_raw_response_chunks(self, async_client: AsyncCloudflare) -> None: response = await async_client.aisearch.namespaces.instances.items.with_raw_response.chunks( item_id="item_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", ) @@ -981,7 +981,7 @@ async def test_streaming_response_chunks(self, async_client: AsyncCloudflare) -> async with async_client.aisearch.namespaces.instances.items.with_streaming_response.chunks( item_id="item_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", ) as response: assert not response.is_closed @@ -998,15 +998,15 @@ async def test_path_params_chunks(self, async_client: AsyncCloudflare) -> None: await async_client.aisearch.namespaces.instances.items.with_raw_response.chunks( item_id="item_id", account_id="", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", ) - with pytest.raises(ValueError, match=r"Expected a non-empty value for `name` but received ''"): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `namespace` but received ''"): await async_client.aisearch.namespaces.instances.items.with_raw_response.chunks( item_id="item_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="", + namespace="", id="my-ai-search", ) @@ -1014,7 +1014,7 @@ async def test_path_params_chunks(self, async_client: AsyncCloudflare) -> None: await async_client.aisearch.namespaces.instances.items.with_raw_response.chunks( item_id="item_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="", ) @@ -1022,7 +1022,7 @@ async def test_path_params_chunks(self, async_client: AsyncCloudflare) -> None: await async_client.aisearch.namespaces.instances.items.with_raw_response.chunks( item_id="", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", ) @@ -1031,7 +1031,7 @@ async def test_method_create_or_update(self, async_client: AsyncCloudflare) -> N item = await async_client.aisearch.namespaces.instances.items.create_or_update( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", key="key", next_action="INDEX", ) @@ -1042,7 +1042,7 @@ async def test_method_create_or_update_with_all_params(self, async_client: Async item = await async_client.aisearch.namespaces.instances.items.create_or_update( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", key="key", next_action="INDEX", wait_for_completion=True, @@ -1054,7 +1054,7 @@ async def test_raw_response_create_or_update(self, async_client: AsyncCloudflare response = await async_client.aisearch.namespaces.instances.items.with_raw_response.create_or_update( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", key="key", next_action="INDEX", ) @@ -1069,7 +1069,7 @@ async def test_streaming_response_create_or_update(self, async_client: AsyncClou async with async_client.aisearch.namespaces.instances.items.with_streaming_response.create_or_update( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", key="key", next_action="INDEX", ) as response: @@ -1087,16 +1087,16 @@ async def test_path_params_create_or_update(self, async_client: AsyncCloudflare) await async_client.aisearch.namespaces.instances.items.with_raw_response.create_or_update( id="my-ai-search", account_id="", - name="my-namespace", + namespace="my-namespace", key="key", next_action="INDEX", ) - with pytest.raises(ValueError, match=r"Expected a non-empty value for `name` but received ''"): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `namespace` but received ''"): await async_client.aisearch.namespaces.instances.items.with_raw_response.create_or_update( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="", + namespace="", key="key", next_action="INDEX", ) @@ -1105,7 +1105,7 @@ async def test_path_params_create_or_update(self, async_client: AsyncCloudflare) await async_client.aisearch.namespaces.instances.items.with_raw_response.create_or_update( id="", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", key="key", next_action="INDEX", ) @@ -1119,7 +1119,7 @@ async def test_method_download(self, async_client: AsyncCloudflare, respx_mock: item = await async_client.aisearch.namespaces.instances.items.download( item_id="item_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", ) assert item.is_closed @@ -1137,7 +1137,7 @@ async def test_raw_response_download(self, async_client: AsyncCloudflare, respx_ item = await async_client.aisearch.namespaces.instances.items.with_raw_response.download( item_id="item_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", ) @@ -1155,7 +1155,7 @@ async def test_streaming_response_download(self, async_client: AsyncCloudflare, async with async_client.aisearch.namespaces.instances.items.with_streaming_response.download( item_id="item_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", ) as item: assert not item.is_closed @@ -1174,15 +1174,15 @@ async def test_path_params_download(self, async_client: AsyncCloudflare) -> None await async_client.aisearch.namespaces.instances.items.with_raw_response.download( item_id="item_id", account_id="", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", ) - with pytest.raises(ValueError, match=r"Expected a non-empty value for `name` but received ''"): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `namespace` but received ''"): await async_client.aisearch.namespaces.instances.items.with_raw_response.download( item_id="item_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="", + namespace="", id="my-ai-search", ) @@ -1190,7 +1190,7 @@ async def test_path_params_download(self, async_client: AsyncCloudflare) -> None await async_client.aisearch.namespaces.instances.items.with_raw_response.download( item_id="item_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="", ) @@ -1198,7 +1198,7 @@ async def test_path_params_download(self, async_client: AsyncCloudflare) -> None await async_client.aisearch.namespaces.instances.items.with_raw_response.download( item_id="", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", ) @@ -1207,7 +1207,7 @@ async def test_method_get(self, async_client: AsyncCloudflare) -> None: item = await async_client.aisearch.namespaces.instances.items.get( item_id="item_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", ) assert_matches_type(ItemGetResponse, item, path=["response"]) @@ -1217,7 +1217,7 @@ async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None: response = await async_client.aisearch.namespaces.instances.items.with_raw_response.get( item_id="item_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", ) @@ -1231,7 +1231,7 @@ async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> No async with async_client.aisearch.namespaces.instances.items.with_streaming_response.get( item_id="item_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", ) as response: assert not response.is_closed @@ -1248,15 +1248,15 @@ async def test_path_params_get(self, async_client: AsyncCloudflare) -> None: await async_client.aisearch.namespaces.instances.items.with_raw_response.get( item_id="item_id", account_id="", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", ) - with pytest.raises(ValueError, match=r"Expected a non-empty value for `name` but received ''"): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `namespace` but received ''"): await async_client.aisearch.namespaces.instances.items.with_raw_response.get( item_id="item_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="", + namespace="", id="my-ai-search", ) @@ -1264,7 +1264,7 @@ async def test_path_params_get(self, async_client: AsyncCloudflare) -> None: await async_client.aisearch.namespaces.instances.items.with_raw_response.get( item_id="item_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="", ) @@ -1272,7 +1272,7 @@ async def test_path_params_get(self, async_client: AsyncCloudflare) -> None: await async_client.aisearch.namespaces.instances.items.with_raw_response.get( item_id="", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", ) @@ -1281,7 +1281,7 @@ async def test_method_logs(self, async_client: AsyncCloudflare) -> None: item = await async_client.aisearch.namespaces.instances.items.logs( item_id="item_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", ) assert_matches_type(ItemLogsResponse, item, path=["response"]) @@ -1291,7 +1291,7 @@ async def test_method_logs_with_all_params(self, async_client: AsyncCloudflare) item = await async_client.aisearch.namespaces.instances.items.logs( item_id="item_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", cursor="cursor", limit=1, @@ -1303,7 +1303,7 @@ async def test_raw_response_logs(self, async_client: AsyncCloudflare) -> None: response = await async_client.aisearch.namespaces.instances.items.with_raw_response.logs( item_id="item_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", ) @@ -1317,7 +1317,7 @@ async def test_streaming_response_logs(self, async_client: AsyncCloudflare) -> N async with async_client.aisearch.namespaces.instances.items.with_streaming_response.logs( item_id="item_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", ) as response: assert not response.is_closed @@ -1334,15 +1334,15 @@ async def test_path_params_logs(self, async_client: AsyncCloudflare) -> None: await async_client.aisearch.namespaces.instances.items.with_raw_response.logs( item_id="item_id", account_id="", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", ) - with pytest.raises(ValueError, match=r"Expected a non-empty value for `name` but received ''"): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `namespace` but received ''"): await async_client.aisearch.namespaces.instances.items.with_raw_response.logs( item_id="item_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="", + namespace="", id="my-ai-search", ) @@ -1350,7 +1350,7 @@ async def test_path_params_logs(self, async_client: AsyncCloudflare) -> None: await async_client.aisearch.namespaces.instances.items.with_raw_response.logs( item_id="item_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="", ) @@ -1358,7 +1358,7 @@ async def test_path_params_logs(self, async_client: AsyncCloudflare) -> None: await async_client.aisearch.namespaces.instances.items.with_raw_response.logs( item_id="", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", ) @@ -1367,7 +1367,7 @@ async def test_method_sync(self, async_client: AsyncCloudflare) -> None: item = await async_client.aisearch.namespaces.instances.items.sync( item_id="item_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", next_action="INDEX", ) @@ -1378,7 +1378,7 @@ async def test_method_sync_with_all_params(self, async_client: AsyncCloudflare) item = await async_client.aisearch.namespaces.instances.items.sync( item_id="item_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", next_action="INDEX", wait_for_completion=True, @@ -1390,7 +1390,7 @@ async def test_raw_response_sync(self, async_client: AsyncCloudflare) -> None: response = await async_client.aisearch.namespaces.instances.items.with_raw_response.sync( item_id="item_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", next_action="INDEX", ) @@ -1405,7 +1405,7 @@ async def test_streaming_response_sync(self, async_client: AsyncCloudflare) -> N async with async_client.aisearch.namespaces.instances.items.with_streaming_response.sync( item_id="item_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", next_action="INDEX", ) as response: @@ -1423,16 +1423,16 @@ async def test_path_params_sync(self, async_client: AsyncCloudflare) -> None: await async_client.aisearch.namespaces.instances.items.with_raw_response.sync( item_id="item_id", account_id="", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", next_action="INDEX", ) - with pytest.raises(ValueError, match=r"Expected a non-empty value for `name` but received ''"): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `namespace` but received ''"): await async_client.aisearch.namespaces.instances.items.with_raw_response.sync( item_id="item_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="", + namespace="", id="my-ai-search", next_action="INDEX", ) @@ -1441,7 +1441,7 @@ async def test_path_params_sync(self, async_client: AsyncCloudflare) -> None: await async_client.aisearch.namespaces.instances.items.with_raw_response.sync( item_id="item_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="", next_action="INDEX", ) @@ -1450,7 +1450,7 @@ async def test_path_params_sync(self, async_client: AsyncCloudflare) -> None: await async_client.aisearch.namespaces.instances.items.with_raw_response.sync( item_id="", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", next_action="INDEX", ) @@ -1460,7 +1460,7 @@ async def test_method_upload(self, async_client: AsyncCloudflare) -> None: item = await async_client.aisearch.namespaces.instances.items.upload( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", file={"file": b"Example data"}, ) assert_matches_type(ItemUploadResponse, item, path=["response"]) @@ -1470,7 +1470,7 @@ async def test_method_upload_with_all_params(self, async_client: AsyncCloudflare item = await async_client.aisearch.namespaces.instances.items.upload( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", file={ "file": b"Example data", "metadata": "metadata", @@ -1484,7 +1484,7 @@ async def test_raw_response_upload(self, async_client: AsyncCloudflare) -> None: response = await async_client.aisearch.namespaces.instances.items.with_raw_response.upload( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", file={"file": b"Example data"}, ) @@ -1498,7 +1498,7 @@ async def test_streaming_response_upload(self, async_client: AsyncCloudflare) -> async with async_client.aisearch.namespaces.instances.items.with_streaming_response.upload( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", file={"file": b"Example data"}, ) as response: assert not response.is_closed @@ -1515,15 +1515,15 @@ async def test_path_params_upload(self, async_client: AsyncCloudflare) -> None: await async_client.aisearch.namespaces.instances.items.with_raw_response.upload( id="my-ai-search", account_id="", - name="my-namespace", + namespace="my-namespace", file={"file": b"Example data"}, ) - with pytest.raises(ValueError, match=r"Expected a non-empty value for `name` but received ''"): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `namespace` but received ''"): await async_client.aisearch.namespaces.instances.items.with_raw_response.upload( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="", + namespace="", file={"file": b"Example data"}, ) @@ -1531,6 +1531,6 @@ async def test_path_params_upload(self, async_client: AsyncCloudflare) -> None: await async_client.aisearch.namespaces.instances.items.with_raw_response.upload( id="", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", file={"file": b"Example data"}, ) diff --git a/tests/api_resources/aisearch/namespaces/instances/test_jobs.py b/tests/api_resources/aisearch/namespaces/instances/test_jobs.py index 83dc130dee3..4dbcd556285 100644 --- a/tests/api_resources/aisearch/namespaces/instances/test_jobs.py +++ b/tests/api_resources/aisearch/namespaces/instances/test_jobs.py @@ -29,7 +29,7 @@ def test_method_create(self, client: Cloudflare) -> None: job = client.aisearch.namespaces.instances.jobs.create( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", ) assert_matches_type(JobCreateResponse, job, path=["response"]) @@ -38,7 +38,7 @@ def test_method_create_with_all_params(self, client: Cloudflare) -> None: job = client.aisearch.namespaces.instances.jobs.create( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", description="description", ) assert_matches_type(JobCreateResponse, job, path=["response"]) @@ -48,7 +48,7 @@ def test_raw_response_create(self, client: Cloudflare) -> None: response = client.aisearch.namespaces.instances.jobs.with_raw_response.create( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", ) assert response.is_closed is True @@ -61,7 +61,7 @@ def test_streaming_response_create(self, client: Cloudflare) -> None: with client.aisearch.namespaces.instances.jobs.with_streaming_response.create( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -77,21 +77,21 @@ def test_path_params_create(self, client: Cloudflare) -> None: client.aisearch.namespaces.instances.jobs.with_raw_response.create( id="my-ai-search", account_id="", - name="my-namespace", + namespace="my-namespace", ) - with pytest.raises(ValueError, match=r"Expected a non-empty value for `name` but received ''"): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `namespace` but received ''"): client.aisearch.namespaces.instances.jobs.with_raw_response.create( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="", + namespace="", ) with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): client.aisearch.namespaces.instances.jobs.with_raw_response.create( id="", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", ) @parametrize @@ -99,7 +99,7 @@ def test_method_update(self, client: Cloudflare) -> None: job = client.aisearch.namespaces.instances.jobs.update( job_id="job_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", action="cancel", ) @@ -110,7 +110,7 @@ def test_raw_response_update(self, client: Cloudflare) -> None: response = client.aisearch.namespaces.instances.jobs.with_raw_response.update( job_id="job_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", action="cancel", ) @@ -125,7 +125,7 @@ def test_streaming_response_update(self, client: Cloudflare) -> None: with client.aisearch.namespaces.instances.jobs.with_streaming_response.update( job_id="job_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", action="cancel", ) as response: @@ -143,16 +143,16 @@ def test_path_params_update(self, client: Cloudflare) -> None: client.aisearch.namespaces.instances.jobs.with_raw_response.update( job_id="job_id", account_id="", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", action="cancel", ) - with pytest.raises(ValueError, match=r"Expected a non-empty value for `name` but received ''"): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `namespace` but received ''"): client.aisearch.namespaces.instances.jobs.with_raw_response.update( job_id="job_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="", + namespace="", id="my-ai-search", action="cancel", ) @@ -161,7 +161,7 @@ def test_path_params_update(self, client: Cloudflare) -> None: client.aisearch.namespaces.instances.jobs.with_raw_response.update( job_id="job_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="", action="cancel", ) @@ -170,7 +170,7 @@ def test_path_params_update(self, client: Cloudflare) -> None: client.aisearch.namespaces.instances.jobs.with_raw_response.update( job_id="", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", action="cancel", ) @@ -180,7 +180,7 @@ def test_method_list(self, client: Cloudflare) -> None: job = client.aisearch.namespaces.instances.jobs.list( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", ) assert_matches_type(SyncV4PagePaginationArray[JobListResponse], job, path=["response"]) @@ -189,7 +189,7 @@ def test_method_list_with_all_params(self, client: Cloudflare) -> None: job = client.aisearch.namespaces.instances.jobs.list( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", page=1, per_page=0, ) @@ -200,7 +200,7 @@ def test_raw_response_list(self, client: Cloudflare) -> None: response = client.aisearch.namespaces.instances.jobs.with_raw_response.list( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", ) assert response.is_closed is True @@ -213,7 +213,7 @@ def test_streaming_response_list(self, client: Cloudflare) -> None: with client.aisearch.namespaces.instances.jobs.with_streaming_response.list( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -229,21 +229,21 @@ def test_path_params_list(self, client: Cloudflare) -> None: client.aisearch.namespaces.instances.jobs.with_raw_response.list( id="my-ai-search", account_id="", - name="my-namespace", + namespace="my-namespace", ) - with pytest.raises(ValueError, match=r"Expected a non-empty value for `name` but received ''"): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `namespace` but received ''"): client.aisearch.namespaces.instances.jobs.with_raw_response.list( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="", + namespace="", ) with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): client.aisearch.namespaces.instances.jobs.with_raw_response.list( id="", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", ) @parametrize @@ -251,7 +251,7 @@ def test_method_get(self, client: Cloudflare) -> None: job = client.aisearch.namespaces.instances.jobs.get( job_id="job_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", ) assert_matches_type(JobGetResponse, job, path=["response"]) @@ -261,7 +261,7 @@ def test_raw_response_get(self, client: Cloudflare) -> None: response = client.aisearch.namespaces.instances.jobs.with_raw_response.get( job_id="job_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", ) @@ -275,7 +275,7 @@ def test_streaming_response_get(self, client: Cloudflare) -> None: with client.aisearch.namespaces.instances.jobs.with_streaming_response.get( job_id="job_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", ) as response: assert not response.is_closed @@ -292,15 +292,15 @@ def test_path_params_get(self, client: Cloudflare) -> None: client.aisearch.namespaces.instances.jobs.with_raw_response.get( job_id="job_id", account_id="", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", ) - with pytest.raises(ValueError, match=r"Expected a non-empty value for `name` but received ''"): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `namespace` but received ''"): client.aisearch.namespaces.instances.jobs.with_raw_response.get( job_id="job_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="", + namespace="", id="my-ai-search", ) @@ -308,7 +308,7 @@ def test_path_params_get(self, client: Cloudflare) -> None: client.aisearch.namespaces.instances.jobs.with_raw_response.get( job_id="job_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="", ) @@ -316,7 +316,7 @@ def test_path_params_get(self, client: Cloudflare) -> None: client.aisearch.namespaces.instances.jobs.with_raw_response.get( job_id="", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", ) @@ -325,7 +325,7 @@ def test_method_logs(self, client: Cloudflare) -> None: job = client.aisearch.namespaces.instances.jobs.logs( job_id="job_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", ) assert_matches_type(JobLogsResponse, job, path=["response"]) @@ -335,7 +335,7 @@ def test_method_logs_with_all_params(self, client: Cloudflare) -> None: job = client.aisearch.namespaces.instances.jobs.logs( job_id="job_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", page=1, per_page=0, @@ -347,7 +347,7 @@ def test_raw_response_logs(self, client: Cloudflare) -> None: response = client.aisearch.namespaces.instances.jobs.with_raw_response.logs( job_id="job_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", ) @@ -361,7 +361,7 @@ def test_streaming_response_logs(self, client: Cloudflare) -> None: with client.aisearch.namespaces.instances.jobs.with_streaming_response.logs( job_id="job_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", ) as response: assert not response.is_closed @@ -378,15 +378,15 @@ def test_path_params_logs(self, client: Cloudflare) -> None: client.aisearch.namespaces.instances.jobs.with_raw_response.logs( job_id="job_id", account_id="", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", ) - with pytest.raises(ValueError, match=r"Expected a non-empty value for `name` but received ''"): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `namespace` but received ''"): client.aisearch.namespaces.instances.jobs.with_raw_response.logs( job_id="job_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="", + namespace="", id="my-ai-search", ) @@ -394,7 +394,7 @@ def test_path_params_logs(self, client: Cloudflare) -> None: client.aisearch.namespaces.instances.jobs.with_raw_response.logs( job_id="job_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="", ) @@ -402,7 +402,7 @@ def test_path_params_logs(self, client: Cloudflare) -> None: client.aisearch.namespaces.instances.jobs.with_raw_response.logs( job_id="", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", ) @@ -417,7 +417,7 @@ async def test_method_create(self, async_client: AsyncCloudflare) -> None: job = await async_client.aisearch.namespaces.instances.jobs.create( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", ) assert_matches_type(JobCreateResponse, job, path=["response"]) @@ -426,7 +426,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncCloudflare job = await async_client.aisearch.namespaces.instances.jobs.create( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", description="description", ) assert_matches_type(JobCreateResponse, job, path=["response"]) @@ -436,7 +436,7 @@ async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None: response = await async_client.aisearch.namespaces.instances.jobs.with_raw_response.create( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", ) assert response.is_closed is True @@ -449,7 +449,7 @@ async def test_streaming_response_create(self, async_client: AsyncCloudflare) -> async with async_client.aisearch.namespaces.instances.jobs.with_streaming_response.create( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -465,21 +465,21 @@ async def test_path_params_create(self, async_client: AsyncCloudflare) -> None: await async_client.aisearch.namespaces.instances.jobs.with_raw_response.create( id="my-ai-search", account_id="", - name="my-namespace", + namespace="my-namespace", ) - with pytest.raises(ValueError, match=r"Expected a non-empty value for `name` but received ''"): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `namespace` but received ''"): await async_client.aisearch.namespaces.instances.jobs.with_raw_response.create( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="", + namespace="", ) with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): await async_client.aisearch.namespaces.instances.jobs.with_raw_response.create( id="", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", ) @parametrize @@ -487,7 +487,7 @@ async def test_method_update(self, async_client: AsyncCloudflare) -> None: job = await async_client.aisearch.namespaces.instances.jobs.update( job_id="job_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", action="cancel", ) @@ -498,7 +498,7 @@ async def test_raw_response_update(self, async_client: AsyncCloudflare) -> None: response = await async_client.aisearch.namespaces.instances.jobs.with_raw_response.update( job_id="job_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", action="cancel", ) @@ -513,7 +513,7 @@ async def test_streaming_response_update(self, async_client: AsyncCloudflare) -> async with async_client.aisearch.namespaces.instances.jobs.with_streaming_response.update( job_id="job_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", action="cancel", ) as response: @@ -531,16 +531,16 @@ async def test_path_params_update(self, async_client: AsyncCloudflare) -> None: await async_client.aisearch.namespaces.instances.jobs.with_raw_response.update( job_id="job_id", account_id="", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", action="cancel", ) - with pytest.raises(ValueError, match=r"Expected a non-empty value for `name` but received ''"): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `namespace` but received ''"): await async_client.aisearch.namespaces.instances.jobs.with_raw_response.update( job_id="job_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="", + namespace="", id="my-ai-search", action="cancel", ) @@ -549,7 +549,7 @@ async def test_path_params_update(self, async_client: AsyncCloudflare) -> None: await async_client.aisearch.namespaces.instances.jobs.with_raw_response.update( job_id="job_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="", action="cancel", ) @@ -558,7 +558,7 @@ async def test_path_params_update(self, async_client: AsyncCloudflare) -> None: await async_client.aisearch.namespaces.instances.jobs.with_raw_response.update( job_id="", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", action="cancel", ) @@ -568,7 +568,7 @@ async def test_method_list(self, async_client: AsyncCloudflare) -> None: job = await async_client.aisearch.namespaces.instances.jobs.list( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", ) assert_matches_type(AsyncV4PagePaginationArray[JobListResponse], job, path=["response"]) @@ -577,7 +577,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncCloudflare) job = await async_client.aisearch.namespaces.instances.jobs.list( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", page=1, per_page=0, ) @@ -588,7 +588,7 @@ async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None: response = await async_client.aisearch.namespaces.instances.jobs.with_raw_response.list( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", ) assert response.is_closed is True @@ -601,7 +601,7 @@ async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> N async with async_client.aisearch.namespaces.instances.jobs.with_streaming_response.list( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -617,21 +617,21 @@ async def test_path_params_list(self, async_client: AsyncCloudflare) -> None: await async_client.aisearch.namespaces.instances.jobs.with_raw_response.list( id="my-ai-search", account_id="", - name="my-namespace", + namespace="my-namespace", ) - with pytest.raises(ValueError, match=r"Expected a non-empty value for `name` but received ''"): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `namespace` but received ''"): await async_client.aisearch.namespaces.instances.jobs.with_raw_response.list( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="", + namespace="", ) with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): await async_client.aisearch.namespaces.instances.jobs.with_raw_response.list( id="", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", ) @parametrize @@ -639,7 +639,7 @@ async def test_method_get(self, async_client: AsyncCloudflare) -> None: job = await async_client.aisearch.namespaces.instances.jobs.get( job_id="job_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", ) assert_matches_type(JobGetResponse, job, path=["response"]) @@ -649,7 +649,7 @@ async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None: response = await async_client.aisearch.namespaces.instances.jobs.with_raw_response.get( job_id="job_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", ) @@ -663,7 +663,7 @@ async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> No async with async_client.aisearch.namespaces.instances.jobs.with_streaming_response.get( job_id="job_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", ) as response: assert not response.is_closed @@ -680,15 +680,15 @@ async def test_path_params_get(self, async_client: AsyncCloudflare) -> None: await async_client.aisearch.namespaces.instances.jobs.with_raw_response.get( job_id="job_id", account_id="", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", ) - with pytest.raises(ValueError, match=r"Expected a non-empty value for `name` but received ''"): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `namespace` but received ''"): await async_client.aisearch.namespaces.instances.jobs.with_raw_response.get( job_id="job_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="", + namespace="", id="my-ai-search", ) @@ -696,7 +696,7 @@ async def test_path_params_get(self, async_client: AsyncCloudflare) -> None: await async_client.aisearch.namespaces.instances.jobs.with_raw_response.get( job_id="job_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="", ) @@ -704,7 +704,7 @@ async def test_path_params_get(self, async_client: AsyncCloudflare) -> None: await async_client.aisearch.namespaces.instances.jobs.with_raw_response.get( job_id="", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", ) @@ -713,7 +713,7 @@ async def test_method_logs(self, async_client: AsyncCloudflare) -> None: job = await async_client.aisearch.namespaces.instances.jobs.logs( job_id="job_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", ) assert_matches_type(JobLogsResponse, job, path=["response"]) @@ -723,7 +723,7 @@ async def test_method_logs_with_all_params(self, async_client: AsyncCloudflare) job = await async_client.aisearch.namespaces.instances.jobs.logs( job_id="job_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", page=1, per_page=0, @@ -735,7 +735,7 @@ async def test_raw_response_logs(self, async_client: AsyncCloudflare) -> None: response = await async_client.aisearch.namespaces.instances.jobs.with_raw_response.logs( job_id="job_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", ) @@ -749,7 +749,7 @@ async def test_streaming_response_logs(self, async_client: AsyncCloudflare) -> N async with async_client.aisearch.namespaces.instances.jobs.with_streaming_response.logs( job_id="job_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", ) as response: assert not response.is_closed @@ -766,15 +766,15 @@ async def test_path_params_logs(self, async_client: AsyncCloudflare) -> None: await async_client.aisearch.namespaces.instances.jobs.with_raw_response.logs( job_id="job_id", account_id="", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", ) - with pytest.raises(ValueError, match=r"Expected a non-empty value for `name` but received ''"): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `namespace` but received ''"): await async_client.aisearch.namespaces.instances.jobs.with_raw_response.logs( job_id="job_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="", + namespace="", id="my-ai-search", ) @@ -782,7 +782,7 @@ async def test_path_params_logs(self, async_client: AsyncCloudflare) -> None: await async_client.aisearch.namespaces.instances.jobs.with_raw_response.logs( job_id="job_id", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="", ) @@ -790,6 +790,6 @@ async def test_path_params_logs(self, async_client: AsyncCloudflare) -> None: await async_client.aisearch.namespaces.instances.jobs.with_raw_response.logs( job_id="", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", id="my-ai-search", ) diff --git a/tests/api_resources/aisearch/namespaces/test_instances.py b/tests/api_resources/aisearch/namespaces/test_instances.py index e9860808da2..0e8abd55d82 100644 --- a/tests/api_resources/aisearch/namespaces/test_instances.py +++ b/tests/api_resources/aisearch/namespaces/test_instances.py @@ -30,7 +30,7 @@ class TestInstances: @parametrize def test_method_create(self, client: Cloudflare) -> None: instance = client.aisearch.namespaces.instances.create( - name="my-namespace", + namespace="my-namespace", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", id="my-ai-search", ) @@ -39,7 +39,7 @@ def test_method_create(self, client: Cloudflare) -> None: @parametrize def test_method_create_with_all_params(self, client: Cloudflare) -> None: instance = client.aisearch.namespaces.instances.create( - name="my-namespace", + namespace="my-namespace", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", id="my-ai-search", ai_gateway_id="ai_gateway_id", @@ -70,6 +70,10 @@ def test_method_create_with_all_params(self, client: Cloudflare) -> None: max_num_results=1, metadata={ "created_from_aisearch_wizard": True, + "created_from_emdash_plugin": { + "type": "native", + "version": "version", + }, "worker_domain": "worker_domain", }, public_endpoint_params={ @@ -149,7 +153,7 @@ def test_method_create_with_all_params(self, client: Cloudflare) -> None: @parametrize def test_raw_response_create(self, client: Cloudflare) -> None: response = client.aisearch.namespaces.instances.with_raw_response.create( - name="my-namespace", + namespace="my-namespace", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", id="my-ai-search", ) @@ -162,7 +166,7 @@ def test_raw_response_create(self, client: Cloudflare) -> None: @parametrize def test_streaming_response_create(self, client: Cloudflare) -> None: with client.aisearch.namespaces.instances.with_streaming_response.create( - name="my-namespace", + namespace="my-namespace", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", id="my-ai-search", ) as response: @@ -178,14 +182,14 @@ def test_streaming_response_create(self, client: Cloudflare) -> None: def test_path_params_create(self, client: Cloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): client.aisearch.namespaces.instances.with_raw_response.create( - name="my-namespace", + namespace="my-namespace", account_id="", id="my-ai-search", ) - with pytest.raises(ValueError, match=r"Expected a non-empty value for `name` but received ''"): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `namespace` but received ''"): client.aisearch.namespaces.instances.with_raw_response.create( - name="", + namespace="", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", id="my-ai-search", ) @@ -195,7 +199,7 @@ def test_method_update(self, client: Cloudflare) -> None: instance = client.aisearch.namespaces.instances.update( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", ) assert_matches_type(InstanceUpdateResponse, instance, path=["response"]) @@ -204,7 +208,7 @@ def test_method_update_with_all_params(self, client: Cloudflare) -> None: instance = client.aisearch.namespaces.instances.update( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", ai_gateway_id="ai_gateway_id", aisearch_model="ai_search_model", cache=True, @@ -232,6 +236,10 @@ def test_method_update_with_all_params(self, client: Cloudflare) -> None: max_num_results=1, metadata={ "created_from_aisearch_wizard": True, + "created_from_emdash_plugin": { + "type": "native", + "version": "version", + }, "worker_domain": "worker_domain", }, paused=True, @@ -318,7 +326,7 @@ def test_raw_response_update(self, client: Cloudflare) -> None: response = client.aisearch.namespaces.instances.with_raw_response.update( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", ) assert response.is_closed is True @@ -331,7 +339,7 @@ def test_streaming_response_update(self, client: Cloudflare) -> None: with client.aisearch.namespaces.instances.with_streaming_response.update( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -347,27 +355,27 @@ def test_path_params_update(self, client: Cloudflare) -> None: client.aisearch.namespaces.instances.with_raw_response.update( id="my-ai-search", account_id="", - name="my-namespace", + namespace="my-namespace", ) - with pytest.raises(ValueError, match=r"Expected a non-empty value for `name` but received ''"): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `namespace` but received ''"): client.aisearch.namespaces.instances.with_raw_response.update( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="", + namespace="", ) with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): client.aisearch.namespaces.instances.with_raw_response.update( id="", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", ) @parametrize def test_method_list(self, client: Cloudflare) -> None: instance = client.aisearch.namespaces.instances.list( - name="my-namespace", + namespace="my-namespace", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", ) assert_matches_type(SyncV4PagePaginationArray[InstanceListResponse], instance, path=["response"]) @@ -375,10 +383,9 @@ def test_method_list(self, client: Cloudflare) -> None: @parametrize def test_method_list_with_all_params(self, client: Cloudflare) -> None: instance = client.aisearch.namespaces.instances.list( - name="my-namespace", + namespace="my-namespace", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", hostname="x", - namespace="namespace", order_by="created_at", order_by_direction="asc", page=1, @@ -390,7 +397,7 @@ def test_method_list_with_all_params(self, client: Cloudflare) -> None: @parametrize def test_raw_response_list(self, client: Cloudflare) -> None: response = client.aisearch.namespaces.instances.with_raw_response.list( - name="my-namespace", + namespace="my-namespace", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", ) @@ -402,7 +409,7 @@ def test_raw_response_list(self, client: Cloudflare) -> None: @parametrize def test_streaming_response_list(self, client: Cloudflare) -> None: with client.aisearch.namespaces.instances.with_streaming_response.list( - name="my-namespace", + namespace="my-namespace", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", ) as response: assert not response.is_closed @@ -417,13 +424,13 @@ def test_streaming_response_list(self, client: Cloudflare) -> None: def test_path_params_list(self, client: Cloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): client.aisearch.namespaces.instances.with_raw_response.list( - name="my-namespace", + namespace="my-namespace", account_id="", ) - with pytest.raises(ValueError, match=r"Expected a non-empty value for `name` but received ''"): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `namespace` but received ''"): client.aisearch.namespaces.instances.with_raw_response.list( - name="", + namespace="", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", ) @@ -432,7 +439,7 @@ def test_method_delete(self, client: Cloudflare) -> None: instance = client.aisearch.namespaces.instances.delete( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", ) assert_matches_type(InstanceDeleteResponse, instance, path=["response"]) @@ -441,7 +448,7 @@ def test_raw_response_delete(self, client: Cloudflare) -> None: response = client.aisearch.namespaces.instances.with_raw_response.delete( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", ) assert response.is_closed is True @@ -454,7 +461,7 @@ def test_streaming_response_delete(self, client: Cloudflare) -> None: with client.aisearch.namespaces.instances.with_streaming_response.delete( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -470,21 +477,21 @@ def test_path_params_delete(self, client: Cloudflare) -> None: client.aisearch.namespaces.instances.with_raw_response.delete( id="my-ai-search", account_id="", - name="my-namespace", + namespace="my-namespace", ) - with pytest.raises(ValueError, match=r"Expected a non-empty value for `name` but received ''"): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `namespace` but received ''"): client.aisearch.namespaces.instances.with_raw_response.delete( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="", + namespace="", ) with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): client.aisearch.namespaces.instances.with_raw_response.delete( id="", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", ) @parametrize @@ -492,7 +499,7 @@ def test_method_chat_completions(self, client: Cloudflare) -> None: instance = client.aisearch.namespaces.instances.chat_completions( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", messages=[ { "content": "string", @@ -507,7 +514,7 @@ def test_method_chat_completions_with_all_params(self, client: Cloudflare) -> No instance = client.aisearch.namespaces.instances.chat_completions( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", messages=[ { "content": "string", @@ -560,7 +567,7 @@ def test_raw_response_chat_completions(self, client: Cloudflare) -> None: response = client.aisearch.namespaces.instances.with_raw_response.chat_completions( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", messages=[ { "content": "string", @@ -579,7 +586,7 @@ def test_streaming_response_chat_completions(self, client: Cloudflare) -> None: with client.aisearch.namespaces.instances.with_streaming_response.chat_completions( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", messages=[ { "content": "string", @@ -601,7 +608,7 @@ def test_path_params_chat_completions(self, client: Cloudflare) -> None: client.aisearch.namespaces.instances.with_raw_response.chat_completions( id="my-ai-search", account_id="", - name="my-namespace", + namespace="my-namespace", messages=[ { "content": "string", @@ -610,11 +617,11 @@ def test_path_params_chat_completions(self, client: Cloudflare) -> None: ], ) - with pytest.raises(ValueError, match=r"Expected a non-empty value for `name` but received ''"): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `namespace` but received ''"): client.aisearch.namespaces.instances.with_raw_response.chat_completions( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="", + namespace="", messages=[ { "content": "string", @@ -627,7 +634,7 @@ def test_path_params_chat_completions(self, client: Cloudflare) -> None: client.aisearch.namespaces.instances.with_raw_response.chat_completions( id="", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", messages=[ { "content": "string", @@ -636,12 +643,78 @@ def test_path_params_chat_completions(self, client: Cloudflare) -> None: ], ) + @parametrize + def test_method_move(self, client: Cloudflare) -> None: + instance = client.aisearch.namespaces.instances.move( + id="my-blog", + account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", + namespace="production", + new_namespace="staging", + ) + assert_matches_type(object, instance, path=["response"]) + + @parametrize + def test_raw_response_move(self, client: Cloudflare) -> None: + response = client.aisearch.namespaces.instances.with_raw_response.move( + id="my-blog", + account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", + namespace="production", + new_namespace="staging", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + instance = response.parse() + assert_matches_type(object, instance, path=["response"]) + + @parametrize + def test_streaming_response_move(self, client: Cloudflare) -> None: + with client.aisearch.namespaces.instances.with_streaming_response.move( + id="my-blog", + account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", + namespace="production", + new_namespace="staging", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + instance = response.parse() + assert_matches_type(object, instance, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_move(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.aisearch.namespaces.instances.with_raw_response.move( + id="my-blog", + account_id="", + namespace="production", + new_namespace="staging", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `namespace` but received ''"): + client.aisearch.namespaces.instances.with_raw_response.move( + id="my-blog", + account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", + namespace="", + new_namespace="staging", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): + client.aisearch.namespaces.instances.with_raw_response.move( + id="", + account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", + namespace="production", + new_namespace="staging", + ) + @parametrize def test_method_read(self, client: Cloudflare) -> None: instance = client.aisearch.namespaces.instances.read( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", ) assert_matches_type(InstanceReadResponse, instance, path=["response"]) @@ -650,7 +723,7 @@ def test_raw_response_read(self, client: Cloudflare) -> None: response = client.aisearch.namespaces.instances.with_raw_response.read( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", ) assert response.is_closed is True @@ -663,7 +736,7 @@ def test_streaming_response_read(self, client: Cloudflare) -> None: with client.aisearch.namespaces.instances.with_streaming_response.read( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -679,21 +752,21 @@ def test_path_params_read(self, client: Cloudflare) -> None: client.aisearch.namespaces.instances.with_raw_response.read( id="my-ai-search", account_id="", - name="my-namespace", + namespace="my-namespace", ) - with pytest.raises(ValueError, match=r"Expected a non-empty value for `name` but received ''"): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `namespace` but received ''"): client.aisearch.namespaces.instances.with_raw_response.read( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="", + namespace="", ) with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): client.aisearch.namespaces.instances.with_raw_response.read( id="", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", ) @parametrize @@ -701,7 +774,7 @@ def test_method_search(self, client: Cloudflare) -> None: instance = client.aisearch.namespaces.instances.search( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", ) assert_matches_type(InstanceSearchResponse, instance, path=["response"]) @@ -710,7 +783,7 @@ def test_method_search_with_all_params(self, client: Cloudflare) -> None: instance = client.aisearch.namespaces.instances.search( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", aisearch_options={ "cache": { "cache_threshold": "super_strict_match", @@ -762,7 +835,7 @@ def test_raw_response_search(self, client: Cloudflare) -> None: response = client.aisearch.namespaces.instances.with_raw_response.search( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", ) assert response.is_closed is True @@ -775,7 +848,7 @@ def test_streaming_response_search(self, client: Cloudflare) -> None: with client.aisearch.namespaces.instances.with_streaming_response.search( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -791,21 +864,21 @@ def test_path_params_search(self, client: Cloudflare) -> None: client.aisearch.namespaces.instances.with_raw_response.search( id="my-ai-search", account_id="", - name="my-namespace", + namespace="my-namespace", ) - with pytest.raises(ValueError, match=r"Expected a non-empty value for `name` but received ''"): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `namespace` but received ''"): client.aisearch.namespaces.instances.with_raw_response.search( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="", + namespace="", ) with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): client.aisearch.namespaces.instances.with_raw_response.search( id="", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", ) @parametrize @@ -813,7 +886,7 @@ def test_method_stats(self, client: Cloudflare) -> None: instance = client.aisearch.namespaces.instances.stats( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", ) assert_matches_type(InstanceStatsResponse, instance, path=["response"]) @@ -822,7 +895,7 @@ def test_raw_response_stats(self, client: Cloudflare) -> None: response = client.aisearch.namespaces.instances.with_raw_response.stats( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", ) assert response.is_closed is True @@ -835,7 +908,7 @@ def test_streaming_response_stats(self, client: Cloudflare) -> None: with client.aisearch.namespaces.instances.with_streaming_response.stats( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -851,21 +924,21 @@ def test_path_params_stats(self, client: Cloudflare) -> None: client.aisearch.namespaces.instances.with_raw_response.stats( id="my-ai-search", account_id="", - name="my-namespace", + namespace="my-namespace", ) - with pytest.raises(ValueError, match=r"Expected a non-empty value for `name` but received ''"): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `namespace` but received ''"): client.aisearch.namespaces.instances.with_raw_response.stats( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="", + namespace="", ) with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): client.aisearch.namespaces.instances.with_raw_response.stats( id="", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", ) @@ -877,7 +950,7 @@ class TestAsyncInstances: @parametrize async def test_method_create(self, async_client: AsyncCloudflare) -> None: instance = await async_client.aisearch.namespaces.instances.create( - name="my-namespace", + namespace="my-namespace", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", id="my-ai-search", ) @@ -886,7 +959,7 @@ async def test_method_create(self, async_client: AsyncCloudflare) -> None: @parametrize async def test_method_create_with_all_params(self, async_client: AsyncCloudflare) -> None: instance = await async_client.aisearch.namespaces.instances.create( - name="my-namespace", + namespace="my-namespace", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", id="my-ai-search", ai_gateway_id="ai_gateway_id", @@ -917,6 +990,10 @@ async def test_method_create_with_all_params(self, async_client: AsyncCloudflare max_num_results=1, metadata={ "created_from_aisearch_wizard": True, + "created_from_emdash_plugin": { + "type": "native", + "version": "version", + }, "worker_domain": "worker_domain", }, public_endpoint_params={ @@ -996,7 +1073,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncCloudflare @parametrize async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None: response = await async_client.aisearch.namespaces.instances.with_raw_response.create( - name="my-namespace", + namespace="my-namespace", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", id="my-ai-search", ) @@ -1009,7 +1086,7 @@ async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None: @parametrize async def test_streaming_response_create(self, async_client: AsyncCloudflare) -> None: async with async_client.aisearch.namespaces.instances.with_streaming_response.create( - name="my-namespace", + namespace="my-namespace", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", id="my-ai-search", ) as response: @@ -1025,14 +1102,14 @@ async def test_streaming_response_create(self, async_client: AsyncCloudflare) -> async def test_path_params_create(self, async_client: AsyncCloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): await async_client.aisearch.namespaces.instances.with_raw_response.create( - name="my-namespace", + namespace="my-namespace", account_id="", id="my-ai-search", ) - with pytest.raises(ValueError, match=r"Expected a non-empty value for `name` but received ''"): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `namespace` but received ''"): await async_client.aisearch.namespaces.instances.with_raw_response.create( - name="", + namespace="", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", id="my-ai-search", ) @@ -1042,7 +1119,7 @@ async def test_method_update(self, async_client: AsyncCloudflare) -> None: instance = await async_client.aisearch.namespaces.instances.update( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", ) assert_matches_type(InstanceUpdateResponse, instance, path=["response"]) @@ -1051,7 +1128,7 @@ async def test_method_update_with_all_params(self, async_client: AsyncCloudflare instance = await async_client.aisearch.namespaces.instances.update( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", ai_gateway_id="ai_gateway_id", aisearch_model="ai_search_model", cache=True, @@ -1079,6 +1156,10 @@ async def test_method_update_with_all_params(self, async_client: AsyncCloudflare max_num_results=1, metadata={ "created_from_aisearch_wizard": True, + "created_from_emdash_plugin": { + "type": "native", + "version": "version", + }, "worker_domain": "worker_domain", }, paused=True, @@ -1165,7 +1246,7 @@ async def test_raw_response_update(self, async_client: AsyncCloudflare) -> None: response = await async_client.aisearch.namespaces.instances.with_raw_response.update( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", ) assert response.is_closed is True @@ -1178,7 +1259,7 @@ async def test_streaming_response_update(self, async_client: AsyncCloudflare) -> async with async_client.aisearch.namespaces.instances.with_streaming_response.update( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -1194,27 +1275,27 @@ async def test_path_params_update(self, async_client: AsyncCloudflare) -> None: await async_client.aisearch.namespaces.instances.with_raw_response.update( id="my-ai-search", account_id="", - name="my-namespace", + namespace="my-namespace", ) - with pytest.raises(ValueError, match=r"Expected a non-empty value for `name` but received ''"): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `namespace` but received ''"): await async_client.aisearch.namespaces.instances.with_raw_response.update( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="", + namespace="", ) with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): await async_client.aisearch.namespaces.instances.with_raw_response.update( id="", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", ) @parametrize async def test_method_list(self, async_client: AsyncCloudflare) -> None: instance = await async_client.aisearch.namespaces.instances.list( - name="my-namespace", + namespace="my-namespace", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", ) assert_matches_type(AsyncV4PagePaginationArray[InstanceListResponse], instance, path=["response"]) @@ -1222,10 +1303,9 @@ async def test_method_list(self, async_client: AsyncCloudflare) -> None: @parametrize async def test_method_list_with_all_params(self, async_client: AsyncCloudflare) -> None: instance = await async_client.aisearch.namespaces.instances.list( - name="my-namespace", + namespace="my-namespace", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", hostname="x", - namespace="namespace", order_by="created_at", order_by_direction="asc", page=1, @@ -1237,7 +1317,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncCloudflare) @parametrize async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None: response = await async_client.aisearch.namespaces.instances.with_raw_response.list( - name="my-namespace", + namespace="my-namespace", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", ) @@ -1249,7 +1329,7 @@ async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None: @parametrize async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> None: async with async_client.aisearch.namespaces.instances.with_streaming_response.list( - name="my-namespace", + namespace="my-namespace", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", ) as response: assert not response.is_closed @@ -1264,13 +1344,13 @@ async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> N async def test_path_params_list(self, async_client: AsyncCloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): await async_client.aisearch.namespaces.instances.with_raw_response.list( - name="my-namespace", + namespace="my-namespace", account_id="", ) - with pytest.raises(ValueError, match=r"Expected a non-empty value for `name` but received ''"): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `namespace` but received ''"): await async_client.aisearch.namespaces.instances.with_raw_response.list( - name="", + namespace="", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", ) @@ -1279,7 +1359,7 @@ async def test_method_delete(self, async_client: AsyncCloudflare) -> None: instance = await async_client.aisearch.namespaces.instances.delete( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", ) assert_matches_type(InstanceDeleteResponse, instance, path=["response"]) @@ -1288,7 +1368,7 @@ async def test_raw_response_delete(self, async_client: AsyncCloudflare) -> None: response = await async_client.aisearch.namespaces.instances.with_raw_response.delete( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", ) assert response.is_closed is True @@ -1301,7 +1381,7 @@ async def test_streaming_response_delete(self, async_client: AsyncCloudflare) -> async with async_client.aisearch.namespaces.instances.with_streaming_response.delete( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -1317,21 +1397,21 @@ async def test_path_params_delete(self, async_client: AsyncCloudflare) -> None: await async_client.aisearch.namespaces.instances.with_raw_response.delete( id="my-ai-search", account_id="", - name="my-namespace", + namespace="my-namespace", ) - with pytest.raises(ValueError, match=r"Expected a non-empty value for `name` but received ''"): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `namespace` but received ''"): await async_client.aisearch.namespaces.instances.with_raw_response.delete( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="", + namespace="", ) with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): await async_client.aisearch.namespaces.instances.with_raw_response.delete( id="", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", ) @parametrize @@ -1339,7 +1419,7 @@ async def test_method_chat_completions(self, async_client: AsyncCloudflare) -> N instance = await async_client.aisearch.namespaces.instances.chat_completions( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", messages=[ { "content": "string", @@ -1354,7 +1434,7 @@ async def test_method_chat_completions_with_all_params(self, async_client: Async instance = await async_client.aisearch.namespaces.instances.chat_completions( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", messages=[ { "content": "string", @@ -1407,7 +1487,7 @@ async def test_raw_response_chat_completions(self, async_client: AsyncCloudflare response = await async_client.aisearch.namespaces.instances.with_raw_response.chat_completions( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", messages=[ { "content": "string", @@ -1426,7 +1506,7 @@ async def test_streaming_response_chat_completions(self, async_client: AsyncClou async with async_client.aisearch.namespaces.instances.with_streaming_response.chat_completions( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", messages=[ { "content": "string", @@ -1448,7 +1528,7 @@ async def test_path_params_chat_completions(self, async_client: AsyncCloudflare) await async_client.aisearch.namespaces.instances.with_raw_response.chat_completions( id="my-ai-search", account_id="", - name="my-namespace", + namespace="my-namespace", messages=[ { "content": "string", @@ -1457,11 +1537,11 @@ async def test_path_params_chat_completions(self, async_client: AsyncCloudflare) ], ) - with pytest.raises(ValueError, match=r"Expected a non-empty value for `name` but received ''"): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `namespace` but received ''"): await async_client.aisearch.namespaces.instances.with_raw_response.chat_completions( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="", + namespace="", messages=[ { "content": "string", @@ -1474,7 +1554,7 @@ async def test_path_params_chat_completions(self, async_client: AsyncCloudflare) await async_client.aisearch.namespaces.instances.with_raw_response.chat_completions( id="", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", messages=[ { "content": "string", @@ -1483,12 +1563,78 @@ async def test_path_params_chat_completions(self, async_client: AsyncCloudflare) ], ) + @parametrize + async def test_method_move(self, async_client: AsyncCloudflare) -> None: + instance = await async_client.aisearch.namespaces.instances.move( + id="my-blog", + account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", + namespace="production", + new_namespace="staging", + ) + assert_matches_type(object, instance, path=["response"]) + + @parametrize + async def test_raw_response_move(self, async_client: AsyncCloudflare) -> None: + response = await async_client.aisearch.namespaces.instances.with_raw_response.move( + id="my-blog", + account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", + namespace="production", + new_namespace="staging", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + instance = await response.parse() + assert_matches_type(object, instance, path=["response"]) + + @parametrize + async def test_streaming_response_move(self, async_client: AsyncCloudflare) -> None: + async with async_client.aisearch.namespaces.instances.with_streaming_response.move( + id="my-blog", + account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", + namespace="production", + new_namespace="staging", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + instance = await response.parse() + assert_matches_type(object, instance, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_move(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.aisearch.namespaces.instances.with_raw_response.move( + id="my-blog", + account_id="", + namespace="production", + new_namespace="staging", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `namespace` but received ''"): + await async_client.aisearch.namespaces.instances.with_raw_response.move( + id="my-blog", + account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", + namespace="", + new_namespace="staging", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): + await async_client.aisearch.namespaces.instances.with_raw_response.move( + id="", + account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", + namespace="production", + new_namespace="staging", + ) + @parametrize async def test_method_read(self, async_client: AsyncCloudflare) -> None: instance = await async_client.aisearch.namespaces.instances.read( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", ) assert_matches_type(InstanceReadResponse, instance, path=["response"]) @@ -1497,7 +1643,7 @@ async def test_raw_response_read(self, async_client: AsyncCloudflare) -> None: response = await async_client.aisearch.namespaces.instances.with_raw_response.read( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", ) assert response.is_closed is True @@ -1510,7 +1656,7 @@ async def test_streaming_response_read(self, async_client: AsyncCloudflare) -> N async with async_client.aisearch.namespaces.instances.with_streaming_response.read( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -1526,21 +1672,21 @@ async def test_path_params_read(self, async_client: AsyncCloudflare) -> None: await async_client.aisearch.namespaces.instances.with_raw_response.read( id="my-ai-search", account_id="", - name="my-namespace", + namespace="my-namespace", ) - with pytest.raises(ValueError, match=r"Expected a non-empty value for `name` but received ''"): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `namespace` but received ''"): await async_client.aisearch.namespaces.instances.with_raw_response.read( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="", + namespace="", ) with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): await async_client.aisearch.namespaces.instances.with_raw_response.read( id="", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", ) @parametrize @@ -1548,7 +1694,7 @@ async def test_method_search(self, async_client: AsyncCloudflare) -> None: instance = await async_client.aisearch.namespaces.instances.search( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", ) assert_matches_type(InstanceSearchResponse, instance, path=["response"]) @@ -1557,7 +1703,7 @@ async def test_method_search_with_all_params(self, async_client: AsyncCloudflare instance = await async_client.aisearch.namespaces.instances.search( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", aisearch_options={ "cache": { "cache_threshold": "super_strict_match", @@ -1609,7 +1755,7 @@ async def test_raw_response_search(self, async_client: AsyncCloudflare) -> None: response = await async_client.aisearch.namespaces.instances.with_raw_response.search( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", ) assert response.is_closed is True @@ -1622,7 +1768,7 @@ async def test_streaming_response_search(self, async_client: AsyncCloudflare) -> async with async_client.aisearch.namespaces.instances.with_streaming_response.search( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -1638,21 +1784,21 @@ async def test_path_params_search(self, async_client: AsyncCloudflare) -> None: await async_client.aisearch.namespaces.instances.with_raw_response.search( id="my-ai-search", account_id="", - name="my-namespace", + namespace="my-namespace", ) - with pytest.raises(ValueError, match=r"Expected a non-empty value for `name` but received ''"): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `namespace` but received ''"): await async_client.aisearch.namespaces.instances.with_raw_response.search( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="", + namespace="", ) with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): await async_client.aisearch.namespaces.instances.with_raw_response.search( id="", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", ) @parametrize @@ -1660,7 +1806,7 @@ async def test_method_stats(self, async_client: AsyncCloudflare) -> None: instance = await async_client.aisearch.namespaces.instances.stats( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", ) assert_matches_type(InstanceStatsResponse, instance, path=["response"]) @@ -1669,7 +1815,7 @@ async def test_raw_response_stats(self, async_client: AsyncCloudflare) -> None: response = await async_client.aisearch.namespaces.instances.with_raw_response.stats( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", ) assert response.is_closed is True @@ -1682,7 +1828,7 @@ async def test_streaming_response_stats(self, async_client: AsyncCloudflare) -> async with async_client.aisearch.namespaces.instances.with_streaming_response.stats( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -1698,19 +1844,19 @@ async def test_path_params_stats(self, async_client: AsyncCloudflare) -> None: await async_client.aisearch.namespaces.instances.with_raw_response.stats( id="my-ai-search", account_id="", - name="my-namespace", + namespace="my-namespace", ) - with pytest.raises(ValueError, match=r"Expected a non-empty value for `name` but received ''"): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `namespace` but received ''"): await async_client.aisearch.namespaces.instances.with_raw_response.stats( id="my-ai-search", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="", + namespace="", ) with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): await async_client.aisearch.namespaces.instances.with_raw_response.stats( id="", account_id="c3dc5f0b34a14ff8e1b3ec04895e1b22", - name="my-namespace", + namespace="my-namespace", ) diff --git a/tests/api_resources/aisearch/test_instances.py b/tests/api_resources/aisearch/test_instances.py index a582133697c..556a74a1836 100644 --- a/tests/api_resources/aisearch/test_instances.py +++ b/tests/api_resources/aisearch/test_instances.py @@ -73,6 +73,10 @@ def test_method_create_with_all_params(self, client: Cloudflare) -> None: max_num_results=1, metadata={ "created_from_aisearch_wizard": True, + "created_from_emdash_plugin": { + "type": "native", + "version": "version", + }, "worker_domain": "worker_domain", }, public_endpoint_params={ @@ -230,6 +234,10 @@ def test_method_update_with_all_params(self, client: Cloudflare) -> None: max_num_results=1, metadata={ "created_from_aisearch_wizard": True, + "created_from_emdash_plugin": { + "type": "native", + "version": "version", + }, "worker_domain": "worker_domain", }, paused=True, @@ -866,6 +874,10 @@ async def test_method_create_with_all_params(self, async_client: AsyncCloudflare max_num_results=1, metadata={ "created_from_aisearch_wizard": True, + "created_from_emdash_plugin": { + "type": "native", + "version": "version", + }, "worker_domain": "worker_domain", }, public_endpoint_params={ @@ -1023,6 +1035,10 @@ async def test_method_update_with_all_params(self, async_client: AsyncCloudflare max_num_results=1, metadata={ "created_from_aisearch_wizard": True, + "created_from_emdash_plugin": { + "type": "native", + "version": "version", + }, "worker_domain": "worker_domain", }, paused=True, diff --git a/tests/api_resources/api_gateway/discovery/test_operations.py b/tests/api_resources/api_gateway/discovery/test_operations.py index 44eb1a89572..ecf7bf7c9a5 100644 --- a/tests/api_resources/api_gateway/discovery/test_operations.py +++ b/tests/api_resources/api_gateway/discovery/test_operations.py @@ -12,6 +12,7 @@ from cloudflare.pagination import SyncV4PagePaginationArray, AsyncV4PagePaginationArray from cloudflare.types.api_gateway import DiscoveryOperation from cloudflare.types.api_gateway.discovery import ( + OperationEditResponse, OperationBulkEditResponse, ) @@ -130,6 +131,63 @@ def test_path_params_bulk_edit(self, client: Cloudflare) -> None: }, ) + @parametrize + def test_method_edit(self, client: Cloudflare) -> None: + operation = client.api_gateway.discovery.operations.edit( + discovery_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + assert_matches_type(OperationEditResponse, operation, path=["response"]) + + @parametrize + def test_method_edit_with_all_params(self, client: Cloudflare) -> None: + operation = client.api_gateway.discovery.operations.edit( + discovery_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + state="review", + ) + assert_matches_type(OperationEditResponse, operation, path=["response"]) + + @parametrize + def test_raw_response_edit(self, client: Cloudflare) -> None: + response = client.api_gateway.discovery.operations.with_raw_response.edit( + discovery_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + operation = response.parse() + assert_matches_type(OperationEditResponse, operation, path=["response"]) + + @parametrize + def test_streaming_response_edit(self, client: Cloudflare) -> None: + with client.api_gateway.discovery.operations.with_streaming_response.edit( + discovery_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + operation = response.parse() + assert_matches_type(OperationEditResponse, operation, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_edit(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + client.api_gateway.discovery.operations.with_raw_response.edit( + discovery_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + zone_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `discovery_id` but received ''"): + client.api_gateway.discovery.operations.with_raw_response.edit( + discovery_id="", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + class TestAsyncOperations: parametrize = pytest.mark.parametrize( @@ -244,3 +302,60 @@ async def test_path_params_bulk_edit(self, async_client: AsyncCloudflare) -> Non "b17c8043-99a0-4202-b7d9-8f7cdbee02cd": {}, }, ) + + @parametrize + async def test_method_edit(self, async_client: AsyncCloudflare) -> None: + operation = await async_client.api_gateway.discovery.operations.edit( + discovery_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + assert_matches_type(OperationEditResponse, operation, path=["response"]) + + @parametrize + async def test_method_edit_with_all_params(self, async_client: AsyncCloudflare) -> None: + operation = await async_client.api_gateway.discovery.operations.edit( + discovery_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + state="review", + ) + assert_matches_type(OperationEditResponse, operation, path=["response"]) + + @parametrize + async def test_raw_response_edit(self, async_client: AsyncCloudflare) -> None: + response = await async_client.api_gateway.discovery.operations.with_raw_response.edit( + discovery_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + operation = await response.parse() + assert_matches_type(OperationEditResponse, operation, path=["response"]) + + @parametrize + async def test_streaming_response_edit(self, async_client: AsyncCloudflare) -> None: + async with async_client.api_gateway.discovery.operations.with_streaming_response.edit( + discovery_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + operation = await response.parse() + assert_matches_type(OperationEditResponse, operation, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_edit(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + await async_client.api_gateway.discovery.operations.with_raw_response.edit( + discovery_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + zone_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `discovery_id` but received ''"): + await async_client.api_gateway.discovery.operations.with_raw_response.edit( + discovery_id="", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) diff --git a/tests/api_resources/magic_cloud_networking/__init__.py b/tests/api_resources/billing/spend_policies/__init__.py similarity index 100% rename from tests/api_resources/magic_cloud_networking/__init__.py rename to tests/api_resources/billing/spend_policies/__init__.py diff --git a/tests/api_resources/billing/spend_policies/test_activity.py b/tests/api_resources/billing/spend_policies/test_activity.py new file mode 100644 index 00000000000..032864290e8 --- /dev/null +++ b/tests/api_resources/billing/spend_policies/test_activity.py @@ -0,0 +1,121 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import os +from typing import Any, cast + +import pytest + +from cloudflare import Cloudflare, AsyncCloudflare +from tests.utils import assert_matches_type +from cloudflare.pagination import SyncCursorPaginationAfter, AsyncCursorPaginationAfter +from cloudflare.types.billing.spend_policies import ActivityListResponse + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestActivity: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @parametrize + def test_method_list(self, client: Cloudflare) -> None: + activity = client.billing.spend_policies.activity.list( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + assert_matches_type(SyncCursorPaginationAfter[ActivityListResponse], activity, path=["response"]) + + @parametrize + def test_method_list_with_all_params(self, client: Cloudflare) -> None: + activity = client.billing.spend_policies.activity.list( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + cursor="cursor", + limit=50, + period="current_billing_cycle", + ) + assert_matches_type(SyncCursorPaginationAfter[ActivityListResponse], activity, path=["response"]) + + @parametrize + def test_raw_response_list(self, client: Cloudflare) -> None: + response = client.billing.spend_policies.activity.with_raw_response.list( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + activity = response.parse() + assert_matches_type(SyncCursorPaginationAfter[ActivityListResponse], activity, path=["response"]) + + @parametrize + def test_streaming_response_list(self, client: Cloudflare) -> None: + with client.billing.spend_policies.activity.with_streaming_response.list( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + activity = response.parse() + assert_matches_type(SyncCursorPaginationAfter[ActivityListResponse], activity, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_list(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.billing.spend_policies.activity.with_raw_response.list( + account_id="", + ) + + +class TestAsyncActivity: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @parametrize + async def test_method_list(self, async_client: AsyncCloudflare) -> None: + activity = await async_client.billing.spend_policies.activity.list( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + assert_matches_type(AsyncCursorPaginationAfter[ActivityListResponse], activity, path=["response"]) + + @parametrize + async def test_method_list_with_all_params(self, async_client: AsyncCloudflare) -> None: + activity = await async_client.billing.spend_policies.activity.list( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + cursor="cursor", + limit=50, + period="current_billing_cycle", + ) + assert_matches_type(AsyncCursorPaginationAfter[ActivityListResponse], activity, path=["response"]) + + @parametrize + async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None: + response = await async_client.billing.spend_policies.activity.with_raw_response.list( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + activity = await response.parse() + assert_matches_type(AsyncCursorPaginationAfter[ActivityListResponse], activity, path=["response"]) + + @parametrize + async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> None: + async with async_client.billing.spend_policies.activity.with_streaming_response.list( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + activity = await response.parse() + assert_matches_type(AsyncCursorPaginationAfter[ActivityListResponse], activity, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_list(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.billing.spend_policies.activity.with_raw_response.list( + account_id="", + ) diff --git a/tests/api_resources/billing/spend_policies/test_audit.py b/tests/api_resources/billing/spend_policies/test_audit.py new file mode 100644 index 00000000000..d9248edf57c --- /dev/null +++ b/tests/api_resources/billing/spend_policies/test_audit.py @@ -0,0 +1,141 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import os +from typing import Any, cast + +import pytest + +from cloudflare import Cloudflare, AsyncCloudflare +from tests.utils import assert_matches_type +from cloudflare.pagination import SyncSinglePage, AsyncSinglePage +from cloudflare.types.billing.spend_policies import AuditListResponse + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestAudit: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @parametrize + def test_method_list(self, client: Cloudflare) -> None: + audit = client.billing.spend_policies.audit.list( + policy_id="6f1c2b8e-3d4a-4f5b-9c6d-7e8f9a0b1c2d", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + assert_matches_type(SyncSinglePage[AuditListResponse], audit, path=["response"]) + + @parametrize + def test_method_list_with_all_params(self, client: Cloudflare) -> None: + audit = client.billing.spend_policies.audit.list( + policy_id="6f1c2b8e-3d4a-4f5b-9c6d-7e8f9a0b1c2d", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + limit=50, + period="current_billing_cycle", + ) + assert_matches_type(SyncSinglePage[AuditListResponse], audit, path=["response"]) + + @parametrize + def test_raw_response_list(self, client: Cloudflare) -> None: + response = client.billing.spend_policies.audit.with_raw_response.list( + policy_id="6f1c2b8e-3d4a-4f5b-9c6d-7e8f9a0b1c2d", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + audit = response.parse() + assert_matches_type(SyncSinglePage[AuditListResponse], audit, path=["response"]) + + @parametrize + def test_streaming_response_list(self, client: Cloudflare) -> None: + with client.billing.spend_policies.audit.with_streaming_response.list( + policy_id="6f1c2b8e-3d4a-4f5b-9c6d-7e8f9a0b1c2d", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + audit = response.parse() + assert_matches_type(SyncSinglePage[AuditListResponse], audit, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_list(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.billing.spend_policies.audit.with_raw_response.list( + policy_id="6f1c2b8e-3d4a-4f5b-9c6d-7e8f9a0b1c2d", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `policy_id` but received ''"): + client.billing.spend_policies.audit.with_raw_response.list( + policy_id="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + +class TestAsyncAudit: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @parametrize + async def test_method_list(self, async_client: AsyncCloudflare) -> None: + audit = await async_client.billing.spend_policies.audit.list( + policy_id="6f1c2b8e-3d4a-4f5b-9c6d-7e8f9a0b1c2d", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + assert_matches_type(AsyncSinglePage[AuditListResponse], audit, path=["response"]) + + @parametrize + async def test_method_list_with_all_params(self, async_client: AsyncCloudflare) -> None: + audit = await async_client.billing.spend_policies.audit.list( + policy_id="6f1c2b8e-3d4a-4f5b-9c6d-7e8f9a0b1c2d", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + limit=50, + period="current_billing_cycle", + ) + assert_matches_type(AsyncSinglePage[AuditListResponse], audit, path=["response"]) + + @parametrize + async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None: + response = await async_client.billing.spend_policies.audit.with_raw_response.list( + policy_id="6f1c2b8e-3d4a-4f5b-9c6d-7e8f9a0b1c2d", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + audit = await response.parse() + assert_matches_type(AsyncSinglePage[AuditListResponse], audit, path=["response"]) + + @parametrize + async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> None: + async with async_client.billing.spend_policies.audit.with_streaming_response.list( + policy_id="6f1c2b8e-3d4a-4f5b-9c6d-7e8f9a0b1c2d", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + audit = await response.parse() + assert_matches_type(AsyncSinglePage[AuditListResponse], audit, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_list(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.billing.spend_policies.audit.with_raw_response.list( + policy_id="6f1c2b8e-3d4a-4f5b-9c6d-7e8f9a0b1c2d", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `policy_id` but received ''"): + await async_client.billing.spend_policies.audit.with_raw_response.list( + policy_id="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) diff --git a/tests/api_resources/billing/test_spend_policies.py b/tests/api_resources/billing/test_spend_policies.py new file mode 100644 index 00000000000..3f5f59e1222 --- /dev/null +++ b/tests/api_resources/billing/test_spend_policies.py @@ -0,0 +1,637 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import os +from typing import Any, cast + +import pytest + +from cloudflare import Cloudflare, AsyncCloudflare +from tests.utils import assert_matches_type +from cloudflare.pagination import SyncSinglePage, AsyncSinglePage +from cloudflare.types.billing import ( + SpendPolicyGetResponse, + SpendPolicyListResponse, + SpendPolicyCreateResponse, + SpendPolicyDeleteResponse, + SpendPolicyUpdateResponse, +) + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestSpendPolicies: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @parametrize + def test_method_create(self, client: Cloudflare) -> None: + spend_policy = client.billing.spend_policies.create( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + action="notification", + enabled=True, + name="Durable Objects alert", + product_id="durable_objects", + threshold_cents=100, + ) + assert_matches_type(SpendPolicyCreateResponse, spend_policy, path=["response"]) + + @parametrize + def test_method_create_with_all_params(self, client: Cloudflare) -> None: + spend_policy = client.billing.spend_policies.create( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + action="notification", + enabled=True, + name="Durable Objects alert", + product_id="durable_objects", + threshold_cents=100, + notification_email="billing@example.com", + ) + assert_matches_type(SpendPolicyCreateResponse, spend_policy, path=["response"]) + + @parametrize + def test_raw_response_create(self, client: Cloudflare) -> None: + response = client.billing.spend_policies.with_raw_response.create( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + action="notification", + enabled=True, + name="Durable Objects alert", + product_id="durable_objects", + threshold_cents=100, + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + spend_policy = response.parse() + assert_matches_type(SpendPolicyCreateResponse, spend_policy, path=["response"]) + + @parametrize + def test_streaming_response_create(self, client: Cloudflare) -> None: + with client.billing.spend_policies.with_streaming_response.create( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + action="notification", + enabled=True, + name="Durable Objects alert", + product_id="durable_objects", + threshold_cents=100, + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + spend_policy = response.parse() + assert_matches_type(SpendPolicyCreateResponse, spend_policy, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_create(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.billing.spend_policies.with_raw_response.create( + account_id="", + action="notification", + enabled=True, + name="Durable Objects alert", + product_id="durable_objects", + threshold_cents=100, + ) + + @parametrize + def test_method_update(self, client: Cloudflare) -> None: + spend_policy = client.billing.spend_policies.update( + policy_id="6f1c2b8e-3d4a-4f5b-9c6d-7e8f9a0b1c2d", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + action="notification", + enabled=True, + name="Workers cap", + product_id="workers", + threshold_cents=100, + if_match='"3"', + ) + assert_matches_type(SpendPolicyUpdateResponse, spend_policy, path=["response"]) + + @parametrize + def test_method_update_with_all_params(self, client: Cloudflare) -> None: + spend_policy = client.billing.spend_policies.update( + policy_id="6f1c2b8e-3d4a-4f5b-9c6d-7e8f9a0b1c2d", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + action="notification", + enabled=True, + name="Workers cap", + product_id="workers", + threshold_cents=100, + if_match='"3"', + notification_email="billing@example.com", + ) + assert_matches_type(SpendPolicyUpdateResponse, spend_policy, path=["response"]) + + @parametrize + def test_raw_response_update(self, client: Cloudflare) -> None: + response = client.billing.spend_policies.with_raw_response.update( + policy_id="6f1c2b8e-3d4a-4f5b-9c6d-7e8f9a0b1c2d", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + action="notification", + enabled=True, + name="Workers cap", + product_id="workers", + threshold_cents=100, + if_match='"3"', + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + spend_policy = response.parse() + assert_matches_type(SpendPolicyUpdateResponse, spend_policy, path=["response"]) + + @parametrize + def test_streaming_response_update(self, client: Cloudflare) -> None: + with client.billing.spend_policies.with_streaming_response.update( + policy_id="6f1c2b8e-3d4a-4f5b-9c6d-7e8f9a0b1c2d", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + action="notification", + enabled=True, + name="Workers cap", + product_id="workers", + threshold_cents=100, + if_match='"3"', + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + spend_policy = response.parse() + assert_matches_type(SpendPolicyUpdateResponse, spend_policy, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_update(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.billing.spend_policies.with_raw_response.update( + policy_id="6f1c2b8e-3d4a-4f5b-9c6d-7e8f9a0b1c2d", + account_id="", + action="notification", + enabled=True, + name="Workers cap", + product_id="workers", + threshold_cents=100, + if_match='"3"', + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `policy_id` but received ''"): + client.billing.spend_policies.with_raw_response.update( + policy_id="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + action="notification", + enabled=True, + name="Workers cap", + product_id="workers", + threshold_cents=100, + if_match='"3"', + ) + + @parametrize + def test_method_list(self, client: Cloudflare) -> None: + spend_policy = client.billing.spend_policies.list( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + assert_matches_type(SyncSinglePage[SpendPolicyListResponse], spend_policy, path=["response"]) + + @parametrize + def test_raw_response_list(self, client: Cloudflare) -> None: + response = client.billing.spend_policies.with_raw_response.list( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + spend_policy = response.parse() + assert_matches_type(SyncSinglePage[SpendPolicyListResponse], spend_policy, path=["response"]) + + @parametrize + def test_streaming_response_list(self, client: Cloudflare) -> None: + with client.billing.spend_policies.with_streaming_response.list( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + spend_policy = response.parse() + assert_matches_type(SyncSinglePage[SpendPolicyListResponse], spend_policy, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_list(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.billing.spend_policies.with_raw_response.list( + account_id="", + ) + + @parametrize + def test_method_delete(self, client: Cloudflare) -> None: + spend_policy = client.billing.spend_policies.delete( + policy_id="6f1c2b8e-3d4a-4f5b-9c6d-7e8f9a0b1c2d", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + if_match='"3"', + ) + assert_matches_type(SpendPolicyDeleteResponse, spend_policy, path=["response"]) + + @parametrize + def test_raw_response_delete(self, client: Cloudflare) -> None: + response = client.billing.spend_policies.with_raw_response.delete( + policy_id="6f1c2b8e-3d4a-4f5b-9c6d-7e8f9a0b1c2d", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + if_match='"3"', + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + spend_policy = response.parse() + assert_matches_type(SpendPolicyDeleteResponse, spend_policy, path=["response"]) + + @parametrize + def test_streaming_response_delete(self, client: Cloudflare) -> None: + with client.billing.spend_policies.with_streaming_response.delete( + policy_id="6f1c2b8e-3d4a-4f5b-9c6d-7e8f9a0b1c2d", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + if_match='"3"', + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + spend_policy = response.parse() + assert_matches_type(SpendPolicyDeleteResponse, spend_policy, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_delete(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.billing.spend_policies.with_raw_response.delete( + policy_id="6f1c2b8e-3d4a-4f5b-9c6d-7e8f9a0b1c2d", + account_id="", + if_match='"3"', + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `policy_id` but received ''"): + client.billing.spend_policies.with_raw_response.delete( + policy_id="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + if_match='"3"', + ) + + @parametrize + def test_method_get(self, client: Cloudflare) -> None: + spend_policy = client.billing.spend_policies.get( + policy_id="6f1c2b8e-3d4a-4f5b-9c6d-7e8f9a0b1c2d", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + assert_matches_type(SpendPolicyGetResponse, spend_policy, path=["response"]) + + @parametrize + def test_raw_response_get(self, client: Cloudflare) -> None: + response = client.billing.spend_policies.with_raw_response.get( + policy_id="6f1c2b8e-3d4a-4f5b-9c6d-7e8f9a0b1c2d", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + spend_policy = response.parse() + assert_matches_type(SpendPolicyGetResponse, spend_policy, path=["response"]) + + @parametrize + def test_streaming_response_get(self, client: Cloudflare) -> None: + with client.billing.spend_policies.with_streaming_response.get( + policy_id="6f1c2b8e-3d4a-4f5b-9c6d-7e8f9a0b1c2d", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + spend_policy = response.parse() + assert_matches_type(SpendPolicyGetResponse, spend_policy, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_get(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.billing.spend_policies.with_raw_response.get( + policy_id="6f1c2b8e-3d4a-4f5b-9c6d-7e8f9a0b1c2d", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `policy_id` but received ''"): + client.billing.spend_policies.with_raw_response.get( + policy_id="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + +class TestAsyncSpendPolicies: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @parametrize + async def test_method_create(self, async_client: AsyncCloudflare) -> None: + spend_policy = await async_client.billing.spend_policies.create( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + action="notification", + enabled=True, + name="Durable Objects alert", + product_id="durable_objects", + threshold_cents=100, + ) + assert_matches_type(SpendPolicyCreateResponse, spend_policy, path=["response"]) + + @parametrize + async def test_method_create_with_all_params(self, async_client: AsyncCloudflare) -> None: + spend_policy = await async_client.billing.spend_policies.create( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + action="notification", + enabled=True, + name="Durable Objects alert", + product_id="durable_objects", + threshold_cents=100, + notification_email="billing@example.com", + ) + assert_matches_type(SpendPolicyCreateResponse, spend_policy, path=["response"]) + + @parametrize + async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None: + response = await async_client.billing.spend_policies.with_raw_response.create( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + action="notification", + enabled=True, + name="Durable Objects alert", + product_id="durable_objects", + threshold_cents=100, + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + spend_policy = await response.parse() + assert_matches_type(SpendPolicyCreateResponse, spend_policy, path=["response"]) + + @parametrize + async def test_streaming_response_create(self, async_client: AsyncCloudflare) -> None: + async with async_client.billing.spend_policies.with_streaming_response.create( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + action="notification", + enabled=True, + name="Durable Objects alert", + product_id="durable_objects", + threshold_cents=100, + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + spend_policy = await response.parse() + assert_matches_type(SpendPolicyCreateResponse, spend_policy, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_create(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.billing.spend_policies.with_raw_response.create( + account_id="", + action="notification", + enabled=True, + name="Durable Objects alert", + product_id="durable_objects", + threshold_cents=100, + ) + + @parametrize + async def test_method_update(self, async_client: AsyncCloudflare) -> None: + spend_policy = await async_client.billing.spend_policies.update( + policy_id="6f1c2b8e-3d4a-4f5b-9c6d-7e8f9a0b1c2d", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + action="notification", + enabled=True, + name="Workers cap", + product_id="workers", + threshold_cents=100, + if_match='"3"', + ) + assert_matches_type(SpendPolicyUpdateResponse, spend_policy, path=["response"]) + + @parametrize + async def test_method_update_with_all_params(self, async_client: AsyncCloudflare) -> None: + spend_policy = await async_client.billing.spend_policies.update( + policy_id="6f1c2b8e-3d4a-4f5b-9c6d-7e8f9a0b1c2d", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + action="notification", + enabled=True, + name="Workers cap", + product_id="workers", + threshold_cents=100, + if_match='"3"', + notification_email="billing@example.com", + ) + assert_matches_type(SpendPolicyUpdateResponse, spend_policy, path=["response"]) + + @parametrize + async def test_raw_response_update(self, async_client: AsyncCloudflare) -> None: + response = await async_client.billing.spend_policies.with_raw_response.update( + policy_id="6f1c2b8e-3d4a-4f5b-9c6d-7e8f9a0b1c2d", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + action="notification", + enabled=True, + name="Workers cap", + product_id="workers", + threshold_cents=100, + if_match='"3"', + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + spend_policy = await response.parse() + assert_matches_type(SpendPolicyUpdateResponse, spend_policy, path=["response"]) + + @parametrize + async def test_streaming_response_update(self, async_client: AsyncCloudflare) -> None: + async with async_client.billing.spend_policies.with_streaming_response.update( + policy_id="6f1c2b8e-3d4a-4f5b-9c6d-7e8f9a0b1c2d", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + action="notification", + enabled=True, + name="Workers cap", + product_id="workers", + threshold_cents=100, + if_match='"3"', + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + spend_policy = await response.parse() + assert_matches_type(SpendPolicyUpdateResponse, spend_policy, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_update(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.billing.spend_policies.with_raw_response.update( + policy_id="6f1c2b8e-3d4a-4f5b-9c6d-7e8f9a0b1c2d", + account_id="", + action="notification", + enabled=True, + name="Workers cap", + product_id="workers", + threshold_cents=100, + if_match='"3"', + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `policy_id` but received ''"): + await async_client.billing.spend_policies.with_raw_response.update( + policy_id="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + action="notification", + enabled=True, + name="Workers cap", + product_id="workers", + threshold_cents=100, + if_match='"3"', + ) + + @parametrize + async def test_method_list(self, async_client: AsyncCloudflare) -> None: + spend_policy = await async_client.billing.spend_policies.list( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + assert_matches_type(AsyncSinglePage[SpendPolicyListResponse], spend_policy, path=["response"]) + + @parametrize + async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None: + response = await async_client.billing.spend_policies.with_raw_response.list( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + spend_policy = await response.parse() + assert_matches_type(AsyncSinglePage[SpendPolicyListResponse], spend_policy, path=["response"]) + + @parametrize + async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> None: + async with async_client.billing.spend_policies.with_streaming_response.list( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + spend_policy = await response.parse() + assert_matches_type(AsyncSinglePage[SpendPolicyListResponse], spend_policy, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_list(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.billing.spend_policies.with_raw_response.list( + account_id="", + ) + + @parametrize + async def test_method_delete(self, async_client: AsyncCloudflare) -> None: + spend_policy = await async_client.billing.spend_policies.delete( + policy_id="6f1c2b8e-3d4a-4f5b-9c6d-7e8f9a0b1c2d", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + if_match='"3"', + ) + assert_matches_type(SpendPolicyDeleteResponse, spend_policy, path=["response"]) + + @parametrize + async def test_raw_response_delete(self, async_client: AsyncCloudflare) -> None: + response = await async_client.billing.spend_policies.with_raw_response.delete( + policy_id="6f1c2b8e-3d4a-4f5b-9c6d-7e8f9a0b1c2d", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + if_match='"3"', + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + spend_policy = await response.parse() + assert_matches_type(SpendPolicyDeleteResponse, spend_policy, path=["response"]) + + @parametrize + async def test_streaming_response_delete(self, async_client: AsyncCloudflare) -> None: + async with async_client.billing.spend_policies.with_streaming_response.delete( + policy_id="6f1c2b8e-3d4a-4f5b-9c6d-7e8f9a0b1c2d", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + if_match='"3"', + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + spend_policy = await response.parse() + assert_matches_type(SpendPolicyDeleteResponse, spend_policy, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_delete(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.billing.spend_policies.with_raw_response.delete( + policy_id="6f1c2b8e-3d4a-4f5b-9c6d-7e8f9a0b1c2d", + account_id="", + if_match='"3"', + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `policy_id` but received ''"): + await async_client.billing.spend_policies.with_raw_response.delete( + policy_id="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + if_match='"3"', + ) + + @parametrize + async def test_method_get(self, async_client: AsyncCloudflare) -> None: + spend_policy = await async_client.billing.spend_policies.get( + policy_id="6f1c2b8e-3d4a-4f5b-9c6d-7e8f9a0b1c2d", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + assert_matches_type(SpendPolicyGetResponse, spend_policy, path=["response"]) + + @parametrize + async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None: + response = await async_client.billing.spend_policies.with_raw_response.get( + policy_id="6f1c2b8e-3d4a-4f5b-9c6d-7e8f9a0b1c2d", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + spend_policy = await response.parse() + assert_matches_type(SpendPolicyGetResponse, spend_policy, path=["response"]) + + @parametrize + async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> None: + async with async_client.billing.spend_policies.with_streaming_response.get( + policy_id="6f1c2b8e-3d4a-4f5b-9c6d-7e8f9a0b1c2d", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + spend_policy = await response.parse() + assert_matches_type(SpendPolicyGetResponse, spend_policy, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_get(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.billing.spend_policies.with_raw_response.get( + policy_id="6f1c2b8e-3d4a-4f5b-9c6d-7e8f9a0b1c2d", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `policy_id` but received ''"): + await async_client.billing.spend_policies.with_raw_response.get( + policy_id="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) diff --git a/tests/api_resources/brand_protection/test_queries.py b/tests/api_resources/brand_protection/test_queries.py index 94135ab542e..dd79d58088f 100644 --- a/tests/api_resources/brand_protection/test_queries.py +++ b/tests/api_resources/brand_protection/test_queries.py @@ -35,7 +35,12 @@ def test_method_create_with_all_params(self, client: Cloudflare) -> None: max_time=parse_datetime("2019-12-27T18:11:19.117Z"), min_time=parse_datetime("2019-12-27T18:11:19.117Z"), body_scan=True, - string_matches={}, + string_matches=[ + { + "pattern": "pattern", + "max_edit_distance": 0, + } + ], body_tag="tag", ) assert query is None @@ -140,7 +145,7 @@ def test_method_bulk(self, client: Cloudflare) -> None: def test_method_bulk_with_all_params(self, client: Cloudflare) -> None: query = client.brand_protection.queries.bulk( account_id="x", - queries=[{"foo": "bar"}], + queries=[{"foo": {}}], ) assert query is None @@ -203,7 +208,12 @@ async def test_method_create_with_all_params(self, async_client: AsyncCloudflare max_time=parse_datetime("2019-12-27T18:11:19.117Z"), min_time=parse_datetime("2019-12-27T18:11:19.117Z"), body_scan=True, - string_matches={}, + string_matches=[ + { + "pattern": "pattern", + "max_edit_distance": 0, + } + ], body_tag="tag", ) assert query is None @@ -308,7 +318,7 @@ async def test_method_bulk(self, async_client: AsyncCloudflare) -> None: async def test_method_bulk_with_all_params(self, async_client: AsyncCloudflare) -> None: query = await async_client.brand_protection.queries.bulk( account_id="x", - queries=[{"foo": "bar"}], + queries=[{"foo": {}}], ) assert query is None diff --git a/tests/api_resources/browser_rendering/devtools/browser/test_page.py b/tests/api_resources/browser_rendering/devtools/browser/test_page.py deleted file mode 100644 index fd0c53f0ddb..00000000000 --- a/tests/api_resources/browser_rendering/devtools/browser/test_page.py +++ /dev/null @@ -1,172 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -import os -from typing import Any, cast - -import pytest - -from cloudflare import Cloudflare, AsyncCloudflare - -base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") - - -class TestPage: - parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) - - @pytest.mark.skip(reason="HTTP 101 error from prism") - @parametrize - def test_method_get(self, client: Cloudflare) -> None: - page = client.browser_rendering.devtools.browser.page.get( - target_id="target_id", - account_id="account_id", - session_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ) - assert page is None - - @pytest.mark.skip(reason="HTTP 101 error from prism") - @parametrize - def test_method_get_with_all_params(self, client: Cloudflare) -> None: - page = client.browser_rendering.devtools.browser.page.get( - target_id="target_id", - account_id="account_id", - session_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - cf_brapi_guardrails="eyJtb2RlIjoicmVhZG9ubHkifQ", - ) - assert page is None - - @pytest.mark.skip(reason="HTTP 101 error from prism") - @parametrize - def test_raw_response_get(self, client: Cloudflare) -> None: - response = client.browser_rendering.devtools.browser.page.with_raw_response.get( - target_id="target_id", - account_id="account_id", - session_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - page = response.parse() - assert page is None - - @pytest.mark.skip(reason="HTTP 101 error from prism") - @parametrize - def test_streaming_response_get(self, client: Cloudflare) -> None: - with client.browser_rendering.devtools.browser.page.with_streaming_response.get( - target_id="target_id", - account_id="account_id", - session_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - page = response.parse() - assert page is None - - assert cast(Any, response.is_closed) is True - - @pytest.mark.skip(reason="HTTP 101 error from prism") - @parametrize - def test_path_params_get(self, client: Cloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): - client.browser_rendering.devtools.browser.page.with_raw_response.get( - target_id="target_id", - account_id="", - session_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ) - - with pytest.raises(ValueError, match=r"Expected a non-empty value for `session_id` but received ''"): - client.browser_rendering.devtools.browser.page.with_raw_response.get( - target_id="target_id", - account_id="account_id", - session_id="", - ) - - with pytest.raises(ValueError, match=r"Expected a non-empty value for `target_id` but received ''"): - client.browser_rendering.devtools.browser.page.with_raw_response.get( - target_id="", - account_id="account_id", - session_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ) - - -class TestAsyncPage: - parametrize = pytest.mark.parametrize( - "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] - ) - - @pytest.mark.skip(reason="HTTP 101 error from prism") - @parametrize - async def test_method_get(self, async_client: AsyncCloudflare) -> None: - page = await async_client.browser_rendering.devtools.browser.page.get( - target_id="target_id", - account_id="account_id", - session_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ) - assert page is None - - @pytest.mark.skip(reason="HTTP 101 error from prism") - @parametrize - async def test_method_get_with_all_params(self, async_client: AsyncCloudflare) -> None: - page = await async_client.browser_rendering.devtools.browser.page.get( - target_id="target_id", - account_id="account_id", - session_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - cf_brapi_guardrails="eyJtb2RlIjoicmVhZG9ubHkifQ", - ) - assert page is None - - @pytest.mark.skip(reason="HTTP 101 error from prism") - @parametrize - async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None: - response = await async_client.browser_rendering.devtools.browser.page.with_raw_response.get( - target_id="target_id", - account_id="account_id", - session_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - page = await response.parse() - assert page is None - - @pytest.mark.skip(reason="HTTP 101 error from prism") - @parametrize - async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> None: - async with async_client.browser_rendering.devtools.browser.page.with_streaming_response.get( - target_id="target_id", - account_id="account_id", - session_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - page = await response.parse() - assert page is None - - assert cast(Any, response.is_closed) is True - - @pytest.mark.skip(reason="HTTP 101 error from prism") - @parametrize - async def test_path_params_get(self, async_client: AsyncCloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): - await async_client.browser_rendering.devtools.browser.page.with_raw_response.get( - target_id="target_id", - account_id="", - session_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ) - - with pytest.raises(ValueError, match=r"Expected a non-empty value for `session_id` but received ''"): - await async_client.browser_rendering.devtools.browser.page.with_raw_response.get( - target_id="target_id", - account_id="account_id", - session_id="", - ) - - with pytest.raises(ValueError, match=r"Expected a non-empty value for `target_id` but received ''"): - await async_client.browser_rendering.devtools.browser.page.with_raw_response.get( - target_id="", - account_id="account_id", - session_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ) diff --git a/tests/api_resources/browser_rendering/devtools/test_browser.py b/tests/api_resources/browser_rendering/devtools/test_browser.py index 31ed151ca6a..4a066f789ae 100644 --- a/tests/api_resources/browser_rendering/devtools/test_browser.py +++ b/tests/api_resources/browser_rendering/devtools/test_browser.py @@ -124,125 +124,6 @@ def test_path_params_delete(self, client: Cloudflare) -> None: account_id="account_id", ) - @pytest.mark.skip(reason="HTTP 101 error from prism") - @parametrize - def test_method_connect(self, client: Cloudflare) -> None: - browser = client.browser_rendering.devtools.browser.connect( - session_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) - assert browser is None - - @pytest.mark.skip(reason="HTTP 101 error from prism") - @parametrize - def test_method_connect_with_all_params(self, client: Cloudflare) -> None: - browser = client.browser_rendering.devtools.browser.connect( - session_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - keep_alive=10000, - lab=True, - recording=True, - cf_brapi_guardrails="eyJtb2RlIjoicmVhZG9ubHkifQ", - ) - assert browser is None - - @pytest.mark.skip(reason="HTTP 101 error from prism") - @parametrize - def test_raw_response_connect(self, client: Cloudflare) -> None: - response = client.browser_rendering.devtools.browser.with_raw_response.connect( - session_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - browser = response.parse() - assert browser is None - - @pytest.mark.skip(reason="HTTP 101 error from prism") - @parametrize - def test_streaming_response_connect(self, client: Cloudflare) -> None: - with client.browser_rendering.devtools.browser.with_streaming_response.connect( - session_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - browser = response.parse() - assert browser is None - - assert cast(Any, response.is_closed) is True - - @pytest.mark.skip(reason="HTTP 101 error from prism") - @parametrize - def test_path_params_connect(self, client: Cloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): - client.browser_rendering.devtools.browser.with_raw_response.connect( - session_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="", - ) - - with pytest.raises(ValueError, match=r"Expected a non-empty value for `session_id` but received ''"): - client.browser_rendering.devtools.browser.with_raw_response.connect( - session_id="", - account_id="account_id", - ) - - @pytest.mark.skip(reason="HTTP 101 error from prism") - @parametrize - def test_method_launch(self, client: Cloudflare) -> None: - browser = client.browser_rendering.devtools.browser.launch( - account_id="account_id", - ) - assert browser is None - - @pytest.mark.skip(reason="HTTP 101 error from prism") - @parametrize - def test_method_launch_with_all_params(self, client: Cloudflare) -> None: - browser = client.browser_rendering.devtools.browser.launch( - account_id="account_id", - keep_alive=10000, - lab=True, - recording=True, - cf_brapi_guardrails="eyJhbGxvd2VkRG9tYWlucyI6WyIqLmV4YW1wbGUuY29tIl19", - ) - assert browser is None - - @pytest.mark.skip(reason="HTTP 101 error from prism") - @parametrize - def test_raw_response_launch(self, client: Cloudflare) -> None: - response = client.browser_rendering.devtools.browser.with_raw_response.launch( - account_id="account_id", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - browser = response.parse() - assert browser is None - - @pytest.mark.skip(reason="HTTP 101 error from prism") - @parametrize - def test_streaming_response_launch(self, client: Cloudflare) -> None: - with client.browser_rendering.devtools.browser.with_streaming_response.launch( - account_id="account_id", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - browser = response.parse() - assert browser is None - - assert cast(Any, response.is_closed) is True - - @pytest.mark.skip(reason="HTTP 101 error from prism") - @parametrize - def test_path_params_launch(self, client: Cloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): - client.browser_rendering.devtools.browser.with_raw_response.launch( - account_id="", - ) - @parametrize def test_method_protocol(self, client: Cloudflare) -> None: browser = client.browser_rendering.devtools.browser.protocol( @@ -447,125 +328,6 @@ async def test_path_params_delete(self, async_client: AsyncCloudflare) -> None: account_id="account_id", ) - @pytest.mark.skip(reason="HTTP 101 error from prism") - @parametrize - async def test_method_connect(self, async_client: AsyncCloudflare) -> None: - browser = await async_client.browser_rendering.devtools.browser.connect( - session_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) - assert browser is None - - @pytest.mark.skip(reason="HTTP 101 error from prism") - @parametrize - async def test_method_connect_with_all_params(self, async_client: AsyncCloudflare) -> None: - browser = await async_client.browser_rendering.devtools.browser.connect( - session_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - keep_alive=10000, - lab=True, - recording=True, - cf_brapi_guardrails="eyJtb2RlIjoicmVhZG9ubHkifQ", - ) - assert browser is None - - @pytest.mark.skip(reason="HTTP 101 error from prism") - @parametrize - async def test_raw_response_connect(self, async_client: AsyncCloudflare) -> None: - response = await async_client.browser_rendering.devtools.browser.with_raw_response.connect( - session_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - browser = await response.parse() - assert browser is None - - @pytest.mark.skip(reason="HTTP 101 error from prism") - @parametrize - async def test_streaming_response_connect(self, async_client: AsyncCloudflare) -> None: - async with async_client.browser_rendering.devtools.browser.with_streaming_response.connect( - session_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - browser = await response.parse() - assert browser is None - - assert cast(Any, response.is_closed) is True - - @pytest.mark.skip(reason="HTTP 101 error from prism") - @parametrize - async def test_path_params_connect(self, async_client: AsyncCloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): - await async_client.browser_rendering.devtools.browser.with_raw_response.connect( - session_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="", - ) - - with pytest.raises(ValueError, match=r"Expected a non-empty value for `session_id` but received ''"): - await async_client.browser_rendering.devtools.browser.with_raw_response.connect( - session_id="", - account_id="account_id", - ) - - @pytest.mark.skip(reason="HTTP 101 error from prism") - @parametrize - async def test_method_launch(self, async_client: AsyncCloudflare) -> None: - browser = await async_client.browser_rendering.devtools.browser.launch( - account_id="account_id", - ) - assert browser is None - - @pytest.mark.skip(reason="HTTP 101 error from prism") - @parametrize - async def test_method_launch_with_all_params(self, async_client: AsyncCloudflare) -> None: - browser = await async_client.browser_rendering.devtools.browser.launch( - account_id="account_id", - keep_alive=10000, - lab=True, - recording=True, - cf_brapi_guardrails="eyJhbGxvd2VkRG9tYWlucyI6WyIqLmV4YW1wbGUuY29tIl19", - ) - assert browser is None - - @pytest.mark.skip(reason="HTTP 101 error from prism") - @parametrize - async def test_raw_response_launch(self, async_client: AsyncCloudflare) -> None: - response = await async_client.browser_rendering.devtools.browser.with_raw_response.launch( - account_id="account_id", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - browser = await response.parse() - assert browser is None - - @pytest.mark.skip(reason="HTTP 101 error from prism") - @parametrize - async def test_streaming_response_launch(self, async_client: AsyncCloudflare) -> None: - async with async_client.browser_rendering.devtools.browser.with_streaming_response.launch( - account_id="account_id", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - browser = await response.parse() - assert browser is None - - assert cast(Any, response.is_closed) is True - - @pytest.mark.skip(reason="HTTP 101 error from prism") - @parametrize - async def test_path_params_launch(self, async_client: AsyncCloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): - await async_client.browser_rendering.devtools.browser.with_raw_response.launch( - account_id="", - ) - @parametrize async def test_method_protocol(self, async_client: AsyncCloudflare) -> None: browser = await async_client.browser_rendering.devtools.browser.protocol( diff --git a/tests/api_resources/browser_rendering/test_accessibility_tree.py b/tests/api_resources/browser_rendering/test_accessibility_tree.py index 6bd7967e063..282f6907ebf 100644 --- a/tests/api_resources/browser_rendering/test_accessibility_tree.py +++ b/tests/api_resources/browser_rendering/test_accessibility_tree.py @@ -30,6 +30,7 @@ def test_method_create_with_all_params_overload_1(self, client: Cloudflare) -> N accessibility_tree = client.browser_rendering.accessibility_tree.create( account_id="account_id", url="url", + browser="kitesurf", cache_ttl=0, action_timeout=120000, add_script_tag=[ @@ -151,6 +152,7 @@ def test_method_create_with_all_params_overload_2(self, client: Cloudflare) -> N accessibility_tree = client.browser_rendering.accessibility_tree.create( account_id="account_id", html="html", + browser="kitesurf", cache_ttl=0, action_timeout=120000, add_script_tag=[ @@ -278,6 +280,7 @@ async def test_method_create_with_all_params_overload_1(self, async_client: Asyn accessibility_tree = await async_client.browser_rendering.accessibility_tree.create( account_id="account_id", url="url", + browser="kitesurf", cache_ttl=0, action_timeout=120000, add_script_tag=[ @@ -399,6 +402,7 @@ async def test_method_create_with_all_params_overload_2(self, async_client: Asyn accessibility_tree = await async_client.browser_rendering.accessibility_tree.create( account_id="account_id", html="html", + browser="kitesurf", cache_ttl=0, action_timeout=120000, add_script_tag=[ diff --git a/tests/api_resources/browser_rendering/test_content.py b/tests/api_resources/browser_rendering/test_content.py index ec27c5cee32..ea5bfceb7ff 100644 --- a/tests/api_resources/browser_rendering/test_content.py +++ b/tests/api_resources/browser_rendering/test_content.py @@ -29,6 +29,7 @@ def test_method_create_with_all_params_overload_1(self, client: Cloudflare) -> N content = client.browser_rendering.content.create( account_id="account_id", url="url", + browser="kitesurf", cache_ttl=0, action_timeout=120000, add_script_tag=[ @@ -148,6 +149,7 @@ def test_method_create_with_all_params_overload_2(self, client: Cloudflare) -> N content = client.browser_rendering.content.create( account_id="account_id", html="html", + browser="kitesurf", cache_ttl=0, action_timeout=120000, add_script_tag=[ @@ -273,6 +275,7 @@ async def test_method_create_with_all_params_overload_1(self, async_client: Asyn content = await async_client.browser_rendering.content.create( account_id="account_id", url="url", + browser="kitesurf", cache_ttl=0, action_timeout=120000, add_script_tag=[ @@ -392,6 +395,7 @@ async def test_method_create_with_all_params_overload_2(self, async_client: Asyn content = await async_client.browser_rendering.content.create( account_id="account_id", html="html", + browser="kitesurf", cache_ttl=0, action_timeout=120000, add_script_tag=[ diff --git a/tests/api_resources/browser_rendering/test_json.py b/tests/api_resources/browser_rendering/test_json.py index c82db3b2aaf..97bd51b996c 100644 --- a/tests/api_resources/browser_rendering/test_json.py +++ b/tests/api_resources/browser_rendering/test_json.py @@ -30,6 +30,7 @@ def test_method_create_with_all_params_overload_1(self, client: Cloudflare) -> N json = client.browser_rendering.json.create( account_id="account_id", url="url", + browser="kitesurf", cache_ttl=0, action_timeout=120000, add_script_tag=[ @@ -160,6 +161,7 @@ def test_method_create_with_all_params_overload_2(self, client: Cloudflare) -> N json = client.browser_rendering.json.create( account_id="account_id", html="html", + browser="kitesurf", cache_ttl=0, action_timeout=120000, add_script_tag=[ @@ -296,6 +298,7 @@ async def test_method_create_with_all_params_overload_1(self, async_client: Asyn json = await async_client.browser_rendering.json.create( account_id="account_id", url="url", + browser="kitesurf", cache_ttl=0, action_timeout=120000, add_script_tag=[ @@ -426,6 +429,7 @@ async def test_method_create_with_all_params_overload_2(self, async_client: Asyn json = await async_client.browser_rendering.json.create( account_id="account_id", html="html", + browser="kitesurf", cache_ttl=0, action_timeout=120000, add_script_tag=[ diff --git a/tests/api_resources/browser_rendering/test_links.py b/tests/api_resources/browser_rendering/test_links.py index 0a18c4b028d..363facc8373 100644 --- a/tests/api_resources/browser_rendering/test_links.py +++ b/tests/api_resources/browser_rendering/test_links.py @@ -30,6 +30,7 @@ def test_method_create_with_all_params_overload_1(self, client: Cloudflare) -> N link = client.browser_rendering.links.create( account_id="account_id", url="url", + browser="kitesurf", cache_ttl=0, action_timeout=120000, add_script_tag=[ @@ -151,6 +152,7 @@ def test_method_create_with_all_params_overload_2(self, client: Cloudflare) -> N link = client.browser_rendering.links.create( account_id="account_id", html="html", + browser="kitesurf", cache_ttl=0, action_timeout=120000, add_script_tag=[ @@ -278,6 +280,7 @@ async def test_method_create_with_all_params_overload_1(self, async_client: Asyn link = await async_client.browser_rendering.links.create( account_id="account_id", url="url", + browser="kitesurf", cache_ttl=0, action_timeout=120000, add_script_tag=[ @@ -399,6 +402,7 @@ async def test_method_create_with_all_params_overload_2(self, async_client: Asyn link = await async_client.browser_rendering.links.create( account_id="account_id", html="html", + browser="kitesurf", cache_ttl=0, action_timeout=120000, add_script_tag=[ diff --git a/tests/api_resources/browser_rendering/test_markdown.py b/tests/api_resources/browser_rendering/test_markdown.py index 1bec1bb05bb..74256d23781 100644 --- a/tests/api_resources/browser_rendering/test_markdown.py +++ b/tests/api_resources/browser_rendering/test_markdown.py @@ -29,6 +29,7 @@ def test_method_create_with_all_params_overload_1(self, client: Cloudflare) -> N markdown = client.browser_rendering.markdown.create( account_id="account_id", url="url", + browser="kitesurf", cache_ttl=0, action_timeout=120000, add_script_tag=[ @@ -148,6 +149,7 @@ def test_method_create_with_all_params_overload_2(self, client: Cloudflare) -> N markdown = client.browser_rendering.markdown.create( account_id="account_id", html="html", + browser="kitesurf", cache_ttl=0, action_timeout=120000, add_script_tag=[ @@ -273,6 +275,7 @@ async def test_method_create_with_all_params_overload_1(self, async_client: Asyn markdown = await async_client.browser_rendering.markdown.create( account_id="account_id", url="url", + browser="kitesurf", cache_ttl=0, action_timeout=120000, add_script_tag=[ @@ -392,6 +395,7 @@ async def test_method_create_with_all_params_overload_2(self, async_client: Asyn markdown = await async_client.browser_rendering.markdown.create( account_id="account_id", html="html", + browser="kitesurf", cache_ttl=0, action_timeout=120000, add_script_tag=[ diff --git a/tests/api_resources/browser_rendering/test_pdf.py b/tests/api_resources/browser_rendering/test_pdf.py index 02877acae4d..beae699c157 100644 --- a/tests/api_resources/browser_rendering/test_pdf.py +++ b/tests/api_resources/browser_rendering/test_pdf.py @@ -47,6 +47,7 @@ def test_method_create_with_all_params_overload_1(self, client: Cloudflare, resp pdf = client.browser_rendering.pdf.create( account_id="account_id", url="url", + browser="kitesurf", cache_ttl=0, action_timeout=120000, add_script_tag=[ @@ -214,6 +215,7 @@ def test_method_create_with_all_params_overload_2(self, client: Cloudflare, resp pdf = client.browser_rendering.pdf.create( account_id="account_id", html="html", + browser="kitesurf", cache_ttl=0, action_timeout=120000, add_script_tag=[ @@ -389,6 +391,7 @@ async def test_method_create_with_all_params_overload_1( pdf = await async_client.browser_rendering.pdf.create( account_id="account_id", url="url", + browser="kitesurf", cache_ttl=0, action_timeout=120000, add_script_tag=[ @@ -560,6 +563,7 @@ async def test_method_create_with_all_params_overload_2( pdf = await async_client.browser_rendering.pdf.create( account_id="account_id", html="html", + browser="kitesurf", cache_ttl=0, action_timeout=120000, add_script_tag=[ diff --git a/tests/api_resources/browser_rendering/test_scrape.py b/tests/api_resources/browser_rendering/test_scrape.py index 01abd6c73db..1355207abe1 100644 --- a/tests/api_resources/browser_rendering/test_scrape.py +++ b/tests/api_resources/browser_rendering/test_scrape.py @@ -30,6 +30,7 @@ def test_method_create_with_all_params_overload_1(self, client: Cloudflare) -> N scrape = client.browser_rendering.scrape.create( account_id="account_id", url="url", + browser="kitesurf", cache_ttl=0, action_timeout=120000, add_script_tag=[ @@ -150,6 +151,7 @@ def test_method_create_with_all_params_overload_2(self, client: Cloudflare) -> N scrape = client.browser_rendering.scrape.create( account_id="account_id", html="html", + browser="kitesurf", cache_ttl=0, action_timeout=120000, add_script_tag=[ @@ -276,6 +278,7 @@ async def test_method_create_with_all_params_overload_1(self, async_client: Asyn scrape = await async_client.browser_rendering.scrape.create( account_id="account_id", url="url", + browser="kitesurf", cache_ttl=0, action_timeout=120000, add_script_tag=[ @@ -396,6 +399,7 @@ async def test_method_create_with_all_params_overload_2(self, async_client: Asyn scrape = await async_client.browser_rendering.scrape.create( account_id="account_id", html="html", + browser="kitesurf", cache_ttl=0, action_timeout=120000, add_script_tag=[ diff --git a/tests/api_resources/browser_rendering/test_screenshot.py b/tests/api_resources/browser_rendering/test_screenshot.py index 4bc566b737a..d814269ce42 100644 --- a/tests/api_resources/browser_rendering/test_screenshot.py +++ b/tests/api_resources/browser_rendering/test_screenshot.py @@ -30,6 +30,7 @@ def test_method_create_with_all_params_overload_1(self, client: Cloudflare) -> N screenshot = client.browser_rendering.screenshot.create( account_id="account_id", url="url", + browser="kitesurf", cache_ttl=0, action_timeout=120000, add_script_tag=[ @@ -168,6 +169,7 @@ def test_method_create_with_all_params_overload_2(self, client: Cloudflare) -> N screenshot = client.browser_rendering.screenshot.create( account_id="account_id", html="html", + browser="kitesurf", cache_ttl=0, action_timeout=120000, add_script_tag=[ @@ -312,6 +314,7 @@ async def test_method_create_with_all_params_overload_1(self, async_client: Asyn screenshot = await async_client.browser_rendering.screenshot.create( account_id="account_id", url="url", + browser="kitesurf", cache_ttl=0, action_timeout=120000, add_script_tag=[ @@ -450,6 +453,7 @@ async def test_method_create_with_all_params_overload_2(self, async_client: Asyn screenshot = await async_client.browser_rendering.screenshot.create( account_id="account_id", html="html", + browser="kitesurf", cache_ttl=0, action_timeout=120000, add_script_tag=[ diff --git a/tests/api_resources/browser_rendering/test_snapshot.py b/tests/api_resources/browser_rendering/test_snapshot.py index d98b5e1fbb9..782d1c7dd01 100644 --- a/tests/api_resources/browser_rendering/test_snapshot.py +++ b/tests/api_resources/browser_rendering/test_snapshot.py @@ -30,6 +30,7 @@ def test_method_create_with_all_params_overload_1(self, client: Cloudflare) -> N snapshot = client.browser_rendering.snapshot.create( account_id="account_id", url="url", + browser="kitesurf", cache_ttl=0, action_timeout=120000, add_script_tag=[ @@ -166,6 +167,7 @@ def test_method_create_with_all_params_overload_2(self, client: Cloudflare) -> N snapshot = client.browser_rendering.snapshot.create( account_id="account_id", html="html", + browser="kitesurf", cache_ttl=0, action_timeout=120000, add_script_tag=[ @@ -308,6 +310,7 @@ async def test_method_create_with_all_params_overload_1(self, async_client: Asyn snapshot = await async_client.browser_rendering.snapshot.create( account_id="account_id", url="url", + browser="kitesurf", cache_ttl=0, action_timeout=120000, add_script_tag=[ @@ -444,6 +447,7 @@ async def test_method_create_with_all_params_overload_2(self, async_client: Asyn snapshot = await async_client.browser_rendering.snapshot.create( account_id="account_id", html="html", + browser="kitesurf", cache_ttl=0, action_timeout=120000, add_script_tag=[ diff --git a/tests/api_resources/cloudforce_one/test_threat_events.py b/tests/api_resources/cloudforce_one/test_threat_events.py index 738e28ede8b..91fe9c634ce 100644 --- a/tests/api_resources/cloudforce_one/test_threat_events.py +++ b/tests/api_resources/cloudforce_one/test_threat_events.py @@ -157,6 +157,15 @@ def test_method_list_with_all_params(self, client: Cloudflare) -> None: "value": "x", } ], + search_branches=[ + [ + { + "field": "attacker", + "op": "equals", + "value": "x", + } + ] + ], ) assert_matches_type(ThreatEventListResponse, threat_event, path=["response"]) @@ -675,6 +684,15 @@ async def test_method_list_with_all_params(self, async_client: AsyncCloudflare) "value": "x", } ], + search_branches=[ + [ + { + "field": "attacker", + "op": "equals", + "value": "x", + } + ] + ], ) assert_matches_type(ThreatEventListResponse, threat_event, path=["response"]) diff --git a/tests/api_resources/cloudforce_one/threat_events/test_queries.py b/tests/api_resources/cloudforce_one/threat_events/test_queries.py index 2cd20625c59..402d8e47945 100644 --- a/tests/api_resources/cloudforce_one/threat_events/test_queries.py +++ b/tests/api_resources/cloudforce_one/threat_events/test_queries.py @@ -26,11 +26,8 @@ class TestQueries: def test_method_create(self, client: Cloudflare) -> None: query = client.cloudforce_one.threat_events.queries.create( account_id="account_id", - alert_enabled=True, - alert_rollup_enabled=True, name="name", query_json="query_json", - rule_enabled=True, ) assert_matches_type(QueryCreateResponse, query, path=["response"]) @@ -38,10 +35,10 @@ def test_method_create(self, client: Cloudflare) -> None: def test_method_create_with_all_params(self, client: Cloudflare) -> None: query = client.cloudforce_one.threat_events.queries.create( account_id="account_id", - alert_enabled=True, - alert_rollup_enabled=True, name="name", query_json="query_json", + alert_enabled=True, + alert_rollup_enabled=True, rule_enabled=True, rule_scope="rule_scope", ) @@ -51,11 +48,8 @@ def test_method_create_with_all_params(self, client: Cloudflare) -> None: def test_raw_response_create(self, client: Cloudflare) -> None: response = client.cloudforce_one.threat_events.queries.with_raw_response.create( account_id="account_id", - alert_enabled=True, - alert_rollup_enabled=True, name="name", query_json="query_json", - rule_enabled=True, ) assert response.is_closed is True @@ -67,11 +61,8 @@ def test_raw_response_create(self, client: Cloudflare) -> None: def test_streaming_response_create(self, client: Cloudflare) -> None: with client.cloudforce_one.threat_events.queries.with_streaming_response.create( account_id="account_id", - alert_enabled=True, - alert_rollup_enabled=True, name="name", query_json="query_json", - rule_enabled=True, ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -86,11 +77,8 @@ def test_path_params_create(self, client: Cloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): client.cloudforce_one.threat_events.queries.with_raw_response.create( account_id="", - alert_enabled=True, - alert_rollup_enabled=True, name="name", query_json="query_json", - rule_enabled=True, ) @parametrize @@ -281,11 +269,8 @@ class TestAsyncQueries: async def test_method_create(self, async_client: AsyncCloudflare) -> None: query = await async_client.cloudforce_one.threat_events.queries.create( account_id="account_id", - alert_enabled=True, - alert_rollup_enabled=True, name="name", query_json="query_json", - rule_enabled=True, ) assert_matches_type(QueryCreateResponse, query, path=["response"]) @@ -293,10 +278,10 @@ async def test_method_create(self, async_client: AsyncCloudflare) -> None: async def test_method_create_with_all_params(self, async_client: AsyncCloudflare) -> None: query = await async_client.cloudforce_one.threat_events.queries.create( account_id="account_id", - alert_enabled=True, - alert_rollup_enabled=True, name="name", query_json="query_json", + alert_enabled=True, + alert_rollup_enabled=True, rule_enabled=True, rule_scope="rule_scope", ) @@ -306,11 +291,8 @@ async def test_method_create_with_all_params(self, async_client: AsyncCloudflare async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None: response = await async_client.cloudforce_one.threat_events.queries.with_raw_response.create( account_id="account_id", - alert_enabled=True, - alert_rollup_enabled=True, name="name", query_json="query_json", - rule_enabled=True, ) assert response.is_closed is True @@ -322,11 +304,8 @@ async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None: async def test_streaming_response_create(self, async_client: AsyncCloudflare) -> None: async with async_client.cloudforce_one.threat_events.queries.with_streaming_response.create( account_id="account_id", - alert_enabled=True, - alert_rollup_enabled=True, name="name", query_json="query_json", - rule_enabled=True, ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -341,11 +320,8 @@ async def test_path_params_create(self, async_client: AsyncCloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): await async_client.cloudforce_one.threat_events.queries.with_raw_response.create( account_id="", - alert_enabled=True, - alert_rollup_enabled=True, name="name", query_json="query_json", - rule_enabled=True, ) @parametrize diff --git a/tests/api_resources/cloudforce_one/threat_signals/test_articles.py b/tests/api_resources/cloudforce_one/threat_signals/test_articles.py index 5037b331165..5f6db68daaa 100644 --- a/tests/api_resources/cloudforce_one/threat_signals/test_articles.py +++ b/tests/api_resources/cloudforce_one/threat_signals/test_articles.py @@ -41,11 +41,14 @@ def test_method_list_with_all_params(self, client: Cloudflare) -> None: fetched_after=parse_datetime("2019-12-27T18:11:19.117Z"), fetched_before=parse_datetime("2019-12-27T18:11:19.117Z"), include_total=True, + min_relevance="low", per_page=1, + pir_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", published_after=parse_datetime("2019-12-27T18:11:19.117Z"), published_before=parse_datetime("2019-12-27T18:11:19.117Z"), read=True, search="x", + severity=["high", "critical"], sort="sort", source_type="curated", tag="tag", @@ -258,11 +261,14 @@ async def test_method_list_with_all_params(self, async_client: AsyncCloudflare) fetched_after=parse_datetime("2019-12-27T18:11:19.117Z"), fetched_before=parse_datetime("2019-12-27T18:11:19.117Z"), include_total=True, + min_relevance="low", per_page=1, + pir_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", published_after=parse_datetime("2019-12-27T18:11:19.117Z"), published_before=parse_datetime("2019-12-27T18:11:19.117Z"), read=True, search="x", + severity=["high", "critical"], sort="sort", source_type="curated", tag="tag", diff --git a/tests/api_resources/cloudforce_one/threat_signals/test_skills.py b/tests/api_resources/cloudforce_one/threat_signals/test_skills.py index 8cabfca3af1..9bf39e6c8f2 100644 --- a/tests/api_resources/cloudforce_one/threat_signals/test_skills.py +++ b/tests/api_resources/cloudforce_one/threat_signals/test_skills.py @@ -26,6 +26,16 @@ class TestSkills: @parametrize def test_method_create(self, client: Cloudflare) -> None: + skill = client.cloudforce_one.threat_signals.skills.create( + account_id="account_id", + name="x", + output_schema="x", + prompt="x", + ) + assert_matches_type(SkillCreateResponse, skill, path=["response"]) + + @parametrize + def test_method_create_with_all_params(self, client: Cloudflare) -> None: skill = client.cloudforce_one.threat_signals.skills.create( account_id="account_id", name="x", @@ -42,7 +52,6 @@ def test_raw_response_create(self, client: Cloudflare) -> None: name="x", output_schema="x", prompt="x", - type="summary", ) assert response.is_closed is True @@ -57,7 +66,6 @@ def test_streaming_response_create(self, client: Cloudflare) -> None: name="x", output_schema="x", prompt="x", - type="summary", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -75,7 +83,6 @@ def test_path_params_create(self, client: Cloudflare) -> None: name="x", output_schema="x", prompt="x", - type="summary", ) @parametrize @@ -290,6 +297,16 @@ class TestAsyncSkills: @parametrize async def test_method_create(self, async_client: AsyncCloudflare) -> None: + skill = await async_client.cloudforce_one.threat_signals.skills.create( + account_id="account_id", + name="x", + output_schema="x", + prompt="x", + ) + assert_matches_type(SkillCreateResponse, skill, path=["response"]) + + @parametrize + async def test_method_create_with_all_params(self, async_client: AsyncCloudflare) -> None: skill = await async_client.cloudforce_one.threat_signals.skills.create( account_id="account_id", name="x", @@ -306,7 +323,6 @@ async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None: name="x", output_schema="x", prompt="x", - type="summary", ) assert response.is_closed is True @@ -321,7 +337,6 @@ async def test_streaming_response_create(self, async_client: AsyncCloudflare) -> name="x", output_schema="x", prompt="x", - type="summary", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -339,7 +354,6 @@ async def test_path_params_create(self, async_client: AsyncCloudflare) -> None: name="x", output_schema="x", prompt="x", - type="summary", ) @parametrize diff --git a/tests/api_resources/connectivity/directory/test_services.py b/tests/api_resources/connectivity/directory/test_services.py index 9bc05cd322a..fe203be7d83 100644 --- a/tests/api_resources/connectivity/directory/test_services.py +++ b/tests/api_resources/connectivity/directory/test_services.py @@ -48,7 +48,11 @@ def test_method_create_with_all_params_overload_1(self, client: Cloudflare) -> N type="http", http_port=8080, https_port=8443, - tls_settings={"cert_verification_mode": "verify_full"}, + tls_settings={ + "cert_verification_mode": "verify_full", + "certificate_authority": "705db030-8247-489b-80dd-0d6256e5950d", + "client_certificate": "a493fbb4-34bc-4218-a63c-61a9323ac725", + }, ) assert_matches_type(Optional[ServiceCreateResponse], service, path=["response"]) @@ -126,7 +130,11 @@ def test_method_create_with_all_params_overload_2(self, client: Cloudflare) -> N type="tcp", app_protocol="postgresql", tcp_port=5432, - tls_settings={"cert_verification_mode": "verify_full"}, + tls_settings={ + "cert_verification_mode": "verify_full", + "certificate_authority": "705db030-8247-489b-80dd-0d6256e5950d", + "client_certificate": "a493fbb4-34bc-4218-a63c-61a9323ac725", + }, ) assert_matches_type(Optional[ServiceCreateResponse], service, path=["response"]) @@ -206,7 +214,11 @@ def test_method_update_with_all_params_overload_1(self, client: Cloudflare) -> N type="http", http_port=8080, https_port=8443, - tls_settings={"cert_verification_mode": "verify_full"}, + tls_settings={ + "cert_verification_mode": "verify_full", + "certificate_authority": "705db030-8247-489b-80dd-0d6256e5950d", + "client_certificate": "a493fbb4-34bc-4218-a63c-61a9323ac725", + }, ) assert_matches_type(Optional[ServiceUpdateResponse], service, path=["response"]) @@ -301,7 +313,11 @@ def test_method_update_with_all_params_overload_2(self, client: Cloudflare) -> N type="tcp", app_protocol="postgresql", tcp_port=5432, - tls_settings={"cert_verification_mode": "verify_full"}, + tls_settings={ + "cert_verification_mode": "verify_full", + "certificate_authority": "705db030-8247-489b-80dd-0d6256e5950d", + "client_certificate": "a493fbb4-34bc-4218-a63c-61a9323ac725", + }, ) assert_matches_type(Optional[ServiceUpdateResponse], service, path=["response"]) @@ -544,7 +560,11 @@ async def test_method_create_with_all_params_overload_1(self, async_client: Asyn type="http", http_port=8080, https_port=8443, - tls_settings={"cert_verification_mode": "verify_full"}, + tls_settings={ + "cert_verification_mode": "verify_full", + "certificate_authority": "705db030-8247-489b-80dd-0d6256e5950d", + "client_certificate": "a493fbb4-34bc-4218-a63c-61a9323ac725", + }, ) assert_matches_type(Optional[ServiceCreateResponse], service, path=["response"]) @@ -622,7 +642,11 @@ async def test_method_create_with_all_params_overload_2(self, async_client: Asyn type="tcp", app_protocol="postgresql", tcp_port=5432, - tls_settings={"cert_verification_mode": "verify_full"}, + tls_settings={ + "cert_verification_mode": "verify_full", + "certificate_authority": "705db030-8247-489b-80dd-0d6256e5950d", + "client_certificate": "a493fbb4-34bc-4218-a63c-61a9323ac725", + }, ) assert_matches_type(Optional[ServiceCreateResponse], service, path=["response"]) @@ -702,7 +726,11 @@ async def test_method_update_with_all_params_overload_1(self, async_client: Asyn type="http", http_port=8080, https_port=8443, - tls_settings={"cert_verification_mode": "verify_full"}, + tls_settings={ + "cert_verification_mode": "verify_full", + "certificate_authority": "705db030-8247-489b-80dd-0d6256e5950d", + "client_certificate": "a493fbb4-34bc-4218-a63c-61a9323ac725", + }, ) assert_matches_type(Optional[ServiceUpdateResponse], service, path=["response"]) @@ -797,7 +825,11 @@ async def test_method_update_with_all_params_overload_2(self, async_client: Asyn type="tcp", app_protocol="postgresql", tcp_port=5432, - tls_settings={"cert_verification_mode": "verify_full"}, + tls_settings={ + "cert_verification_mode": "verify_full", + "certificate_authority": "705db030-8247-489b-80dd-0d6256e5950d", + "client_certificate": "a493fbb4-34bc-4218-a63c-61a9323ac725", + }, ) assert_matches_type(Optional[ServiceUpdateResponse], service, path=["response"]) diff --git a/tests/api_resources/containers/test_applications.py b/tests/api_resources/containers/test_applications.py index 879a1ad78d0..845acec7037 100644 --- a/tests/api_resources/containers/test_applications.py +++ b/tests/api_resources/containers/test_applications.py @@ -148,6 +148,7 @@ def test_method_create_with_all_params_overload_2(self, client: Cloudflare) -> N "port": 1, }, }, + constraints={"jurisdiction": "eu"}, observability={"logs": {"enabled": True}}, ) assert_matches_type(ApplicationCreateResponse, application, path=["response"]) @@ -542,6 +543,7 @@ async def test_method_create_with_all_params_overload_2(self, async_client: Asyn "port": 1, }, }, + constraints={"jurisdiction": "eu"}, observability={"logs": {"enabled": True}}, ) assert_matches_type(ApplicationCreateResponse, application, path=["response"]) diff --git a/tests/api_resources/d1/test_database.py b/tests/api_resources/d1/test_database.py index 352eeb0ee0d..eb39ed63535 100644 --- a/tests/api_resources/d1/test_database.py +++ b/tests/api_resources/d1/test_database.py @@ -301,6 +301,7 @@ def test_method_export_with_all_params(self, client: Cloudflare) -> None: output_format="polling", current_bookmark="current_bookmark", dump_options={ + "compatibility": "d1", "no_data": True, "no_schema": True, "tables": ["string"], @@ -820,6 +821,63 @@ def test_path_params_raw_overload_2(self, client: Cloudflare) -> None: batch=[{"sql": "SELECT * FROM myTable WHERE field = ? OR field = ?;"}], ) + @parametrize + def test_method_undelete(self, client: Cloudflare) -> None: + database = client.d1.database.undelete( + database_id="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + assert_matches_type(D1, database, path=["response"]) + + @parametrize + def test_method_undelete_with_all_params(self, client: Cloudflare) -> None: + database = client.d1.database.undelete( + database_id="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + new_name="my-database", + ) + assert_matches_type(D1, database, path=["response"]) + + @parametrize + def test_raw_response_undelete(self, client: Cloudflare) -> None: + response = client.d1.database.with_raw_response.undelete( + database_id="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + database = response.parse() + assert_matches_type(D1, database, path=["response"]) + + @parametrize + def test_streaming_response_undelete(self, client: Cloudflare) -> None: + with client.d1.database.with_streaming_response.undelete( + database_id="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + database = response.parse() + assert_matches_type(D1, database, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_undelete(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.d1.database.with_raw_response.undelete( + database_id="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `database_id` but received ''"): + client.d1.database.with_raw_response.undelete( + database_id="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + class TestAsyncDatabase: parametrize = pytest.mark.parametrize( @@ -1102,6 +1160,7 @@ async def test_method_export_with_all_params(self, async_client: AsyncCloudflare output_format="polling", current_bookmark="current_bookmark", dump_options={ + "compatibility": "d1", "no_data": True, "no_schema": True, "tables": ["string"], @@ -1620,3 +1679,60 @@ async def test_path_params_raw_overload_2(self, async_client: AsyncCloudflare) - account_id="023e105f4ecef8ad9ca31a8372d0c353", batch=[{"sql": "SELECT * FROM myTable WHERE field = ? OR field = ?;"}], ) + + @parametrize + async def test_method_undelete(self, async_client: AsyncCloudflare) -> None: + database = await async_client.d1.database.undelete( + database_id="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + assert_matches_type(D1, database, path=["response"]) + + @parametrize + async def test_method_undelete_with_all_params(self, async_client: AsyncCloudflare) -> None: + database = await async_client.d1.database.undelete( + database_id="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + new_name="my-database", + ) + assert_matches_type(D1, database, path=["response"]) + + @parametrize + async def test_raw_response_undelete(self, async_client: AsyncCloudflare) -> None: + response = await async_client.d1.database.with_raw_response.undelete( + database_id="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + database = await response.parse() + assert_matches_type(D1, database, path=["response"]) + + @parametrize + async def test_streaming_response_undelete(self, async_client: AsyncCloudflare) -> None: + async with async_client.d1.database.with_streaming_response.undelete( + database_id="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + database = await response.parse() + assert_matches_type(D1, database, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_undelete(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.d1.database.with_raw_response.undelete( + database_id="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `database_id` but received ''"): + await async_client.d1.database.with_raw_response.undelete( + database_id="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) diff --git a/tests/api_resources/diagnostics/test_endpoint_healthchecks.py b/tests/api_resources/diagnostics/test_endpoint_healthchecks.py index 406240e1223..64d168df43f 100644 --- a/tests/api_resources/diagnostics/test_endpoint_healthchecks.py +++ b/tests/api_resources/diagnostics/test_endpoint_healthchecks.py @@ -9,6 +9,7 @@ from cloudflare import Cloudflare, AsyncCloudflare from tests.utils import assert_matches_type +from cloudflare.pagination import SyncSinglePage, AsyncSinglePage from cloudflare.types.diagnostics import ( EndpointHealthcheckGetResponse, EndpointHealthcheckListResponse, @@ -153,7 +154,7 @@ def test_method_list(self, client: Cloudflare) -> None: endpoint_healthcheck = client.diagnostics.endpoint_healthchecks.list( account_id="023e105f4ecef8ad9ca31a8372d0c353", ) - assert_matches_type(Optional[EndpointHealthcheckListResponse], endpoint_healthcheck, path=["response"]) + assert_matches_type(SyncSinglePage[EndpointHealthcheckListResponse], endpoint_healthcheck, path=["response"]) @parametrize def test_raw_response_list(self, client: Cloudflare) -> None: @@ -164,7 +165,7 @@ def test_raw_response_list(self, client: Cloudflare) -> None: assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" endpoint_healthcheck = response.parse() - assert_matches_type(Optional[EndpointHealthcheckListResponse], endpoint_healthcheck, path=["response"]) + assert_matches_type(SyncSinglePage[EndpointHealthcheckListResponse], endpoint_healthcheck, path=["response"]) @parametrize def test_streaming_response_list(self, client: Cloudflare) -> None: @@ -175,7 +176,9 @@ def test_streaming_response_list(self, client: Cloudflare) -> None: assert response.http_request.headers.get("X-Stainless-Lang") == "python" endpoint_healthcheck = response.parse() - assert_matches_type(Optional[EndpointHealthcheckListResponse], endpoint_healthcheck, path=["response"]) + assert_matches_type( + SyncSinglePage[EndpointHealthcheckListResponse], endpoint_healthcheck, path=["response"] + ) assert cast(Any, response.is_closed) is True @@ -418,7 +421,7 @@ async def test_method_list(self, async_client: AsyncCloudflare) -> None: endpoint_healthcheck = await async_client.diagnostics.endpoint_healthchecks.list( account_id="023e105f4ecef8ad9ca31a8372d0c353", ) - assert_matches_type(Optional[EndpointHealthcheckListResponse], endpoint_healthcheck, path=["response"]) + assert_matches_type(AsyncSinglePage[EndpointHealthcheckListResponse], endpoint_healthcheck, path=["response"]) @parametrize async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None: @@ -429,7 +432,7 @@ async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None: assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" endpoint_healthcheck = await response.parse() - assert_matches_type(Optional[EndpointHealthcheckListResponse], endpoint_healthcheck, path=["response"]) + assert_matches_type(AsyncSinglePage[EndpointHealthcheckListResponse], endpoint_healthcheck, path=["response"]) @parametrize async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> None: @@ -440,7 +443,9 @@ async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> N assert response.http_request.headers.get("X-Stainless-Lang") == "python" endpoint_healthcheck = await response.parse() - assert_matches_type(Optional[EndpointHealthcheckListResponse], endpoint_healthcheck, path=["response"]) + assert_matches_type( + AsyncSinglePage[EndpointHealthcheckListResponse], endpoint_healthcheck, path=["response"] + ) assert cast(Any, response.is_closed) is True diff --git a/tests/api_resources/dns/settings/account/test_nameserver_sets.py b/tests/api_resources/dns/settings/account/test_nameserver_sets.py new file mode 100644 index 00000000000..66618515848 --- /dev/null +++ b/tests/api_resources/dns/settings/account/test_nameserver_sets.py @@ -0,0 +1,442 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import os +from typing import Any, cast + +import pytest + +from cloudflare import Cloudflare, AsyncCloudflare +from tests.utils import assert_matches_type +from cloudflare.pagination import SyncV4PagePaginationArray, AsyncV4PagePaginationArray +from cloudflare.types.dns.settings.account import ( + NameserverSetGetResponse, + NameserverSetListResponse, + NameserverSetCreateResponse, + NameserverSetDeleteResponse, +) + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestNameserverSets: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @parametrize + def test_method_create(self, client: Cloudflare) -> None: + nameserver_set = client.dns.settings.account.nameserver_sets.create( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + name="Production nameservers", + nameservers=[{"name": "ns1.example.com"}], + ) + assert_matches_type(NameserverSetCreateResponse, nameserver_set, path=["response"]) + + @parametrize + def test_method_create_with_all_params(self, client: Cloudflare) -> None: + nameserver_set = client.dns.settings.account.nameserver_sets.create( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + name="Production nameservers", + nameservers=[ + { + "name": "ns1.example.com", + "ip_count": 1, + } + ], + advanced=False, + ip_set=1, + ) + assert_matches_type(NameserverSetCreateResponse, nameserver_set, path=["response"]) + + @parametrize + def test_raw_response_create(self, client: Cloudflare) -> None: + response = client.dns.settings.account.nameserver_sets.with_raw_response.create( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + name="Production nameservers", + nameservers=[{"name": "ns1.example.com"}], + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + nameserver_set = response.parse() + assert_matches_type(NameserverSetCreateResponse, nameserver_set, path=["response"]) + + @parametrize + def test_streaming_response_create(self, client: Cloudflare) -> None: + with client.dns.settings.account.nameserver_sets.with_streaming_response.create( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + name="Production nameservers", + nameservers=[{"name": "ns1.example.com"}], + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + nameserver_set = response.parse() + assert_matches_type(NameserverSetCreateResponse, nameserver_set, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_create(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.dns.settings.account.nameserver_sets.with_raw_response.create( + account_id="", + name="Production nameservers", + nameservers=[{"name": "ns1.example.com"}], + ) + + @parametrize + def test_method_list(self, client: Cloudflare) -> None: + nameserver_set = client.dns.settings.account.nameserver_sets.list( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + assert_matches_type(SyncV4PagePaginationArray[NameserverSetListResponse], nameserver_set, path=["response"]) + + @parametrize + def test_method_list_with_all_params(self, client: Cloudflare) -> None: + nameserver_set = client.dns.settings.account.nameserver_sets.list( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + page=1, + per_page=5, + ) + assert_matches_type(SyncV4PagePaginationArray[NameserverSetListResponse], nameserver_set, path=["response"]) + + @parametrize + def test_raw_response_list(self, client: Cloudflare) -> None: + response = client.dns.settings.account.nameserver_sets.with_raw_response.list( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + nameserver_set = response.parse() + assert_matches_type(SyncV4PagePaginationArray[NameserverSetListResponse], nameserver_set, path=["response"]) + + @parametrize + def test_streaming_response_list(self, client: Cloudflare) -> None: + with client.dns.settings.account.nameserver_sets.with_streaming_response.list( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + nameserver_set = response.parse() + assert_matches_type(SyncV4PagePaginationArray[NameserverSetListResponse], nameserver_set, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_list(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.dns.settings.account.nameserver_sets.with_raw_response.list( + account_id="", + ) + + @parametrize + def test_method_delete(self, client: Cloudflare) -> None: + nameserver_set = client.dns.settings.account.nameserver_sets.delete( + nameserver_set_id="0123456789abcdef0123456789abcdef", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + assert_matches_type(NameserverSetDeleteResponse, nameserver_set, path=["response"]) + + @parametrize + def test_raw_response_delete(self, client: Cloudflare) -> None: + response = client.dns.settings.account.nameserver_sets.with_raw_response.delete( + nameserver_set_id="0123456789abcdef0123456789abcdef", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + nameserver_set = response.parse() + assert_matches_type(NameserverSetDeleteResponse, nameserver_set, path=["response"]) + + @parametrize + def test_streaming_response_delete(self, client: Cloudflare) -> None: + with client.dns.settings.account.nameserver_sets.with_streaming_response.delete( + nameserver_set_id="0123456789abcdef0123456789abcdef", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + nameserver_set = response.parse() + assert_matches_type(NameserverSetDeleteResponse, nameserver_set, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_delete(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.dns.settings.account.nameserver_sets.with_raw_response.delete( + nameserver_set_id="0123456789abcdef0123456789abcdef", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `nameserver_set_id` but received ''"): + client.dns.settings.account.nameserver_sets.with_raw_response.delete( + nameserver_set_id="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + @parametrize + def test_method_get(self, client: Cloudflare) -> None: + nameserver_set = client.dns.settings.account.nameserver_sets.get( + nameserver_set_id="0123456789abcdef0123456789abcdef", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + assert_matches_type(NameserverSetGetResponse, nameserver_set, path=["response"]) + + @parametrize + def test_raw_response_get(self, client: Cloudflare) -> None: + response = client.dns.settings.account.nameserver_sets.with_raw_response.get( + nameserver_set_id="0123456789abcdef0123456789abcdef", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + nameserver_set = response.parse() + assert_matches_type(NameserverSetGetResponse, nameserver_set, path=["response"]) + + @parametrize + def test_streaming_response_get(self, client: Cloudflare) -> None: + with client.dns.settings.account.nameserver_sets.with_streaming_response.get( + nameserver_set_id="0123456789abcdef0123456789abcdef", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + nameserver_set = response.parse() + assert_matches_type(NameserverSetGetResponse, nameserver_set, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_get(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.dns.settings.account.nameserver_sets.with_raw_response.get( + nameserver_set_id="0123456789abcdef0123456789abcdef", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `nameserver_set_id` but received ''"): + client.dns.settings.account.nameserver_sets.with_raw_response.get( + nameserver_set_id="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + +class TestAsyncNameserverSets: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @parametrize + async def test_method_create(self, async_client: AsyncCloudflare) -> None: + nameserver_set = await async_client.dns.settings.account.nameserver_sets.create( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + name="Production nameservers", + nameservers=[{"name": "ns1.example.com"}], + ) + assert_matches_type(NameserverSetCreateResponse, nameserver_set, path=["response"]) + + @parametrize + async def test_method_create_with_all_params(self, async_client: AsyncCloudflare) -> None: + nameserver_set = await async_client.dns.settings.account.nameserver_sets.create( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + name="Production nameservers", + nameservers=[ + { + "name": "ns1.example.com", + "ip_count": 1, + } + ], + advanced=False, + ip_set=1, + ) + assert_matches_type(NameserverSetCreateResponse, nameserver_set, path=["response"]) + + @parametrize + async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None: + response = await async_client.dns.settings.account.nameserver_sets.with_raw_response.create( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + name="Production nameservers", + nameservers=[{"name": "ns1.example.com"}], + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + nameserver_set = await response.parse() + assert_matches_type(NameserverSetCreateResponse, nameserver_set, path=["response"]) + + @parametrize + async def test_streaming_response_create(self, async_client: AsyncCloudflare) -> None: + async with async_client.dns.settings.account.nameserver_sets.with_streaming_response.create( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + name="Production nameservers", + nameservers=[{"name": "ns1.example.com"}], + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + nameserver_set = await response.parse() + assert_matches_type(NameserverSetCreateResponse, nameserver_set, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_create(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.dns.settings.account.nameserver_sets.with_raw_response.create( + account_id="", + name="Production nameservers", + nameservers=[{"name": "ns1.example.com"}], + ) + + @parametrize + async def test_method_list(self, async_client: AsyncCloudflare) -> None: + nameserver_set = await async_client.dns.settings.account.nameserver_sets.list( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + assert_matches_type(AsyncV4PagePaginationArray[NameserverSetListResponse], nameserver_set, path=["response"]) + + @parametrize + async def test_method_list_with_all_params(self, async_client: AsyncCloudflare) -> None: + nameserver_set = await async_client.dns.settings.account.nameserver_sets.list( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + page=1, + per_page=5, + ) + assert_matches_type(AsyncV4PagePaginationArray[NameserverSetListResponse], nameserver_set, path=["response"]) + + @parametrize + async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None: + response = await async_client.dns.settings.account.nameserver_sets.with_raw_response.list( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + nameserver_set = await response.parse() + assert_matches_type(AsyncV4PagePaginationArray[NameserverSetListResponse], nameserver_set, path=["response"]) + + @parametrize + async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> None: + async with async_client.dns.settings.account.nameserver_sets.with_streaming_response.list( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + nameserver_set = await response.parse() + assert_matches_type( + AsyncV4PagePaginationArray[NameserverSetListResponse], nameserver_set, path=["response"] + ) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_list(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.dns.settings.account.nameserver_sets.with_raw_response.list( + account_id="", + ) + + @parametrize + async def test_method_delete(self, async_client: AsyncCloudflare) -> None: + nameserver_set = await async_client.dns.settings.account.nameserver_sets.delete( + nameserver_set_id="0123456789abcdef0123456789abcdef", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + assert_matches_type(NameserverSetDeleteResponse, nameserver_set, path=["response"]) + + @parametrize + async def test_raw_response_delete(self, async_client: AsyncCloudflare) -> None: + response = await async_client.dns.settings.account.nameserver_sets.with_raw_response.delete( + nameserver_set_id="0123456789abcdef0123456789abcdef", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + nameserver_set = await response.parse() + assert_matches_type(NameserverSetDeleteResponse, nameserver_set, path=["response"]) + + @parametrize + async def test_streaming_response_delete(self, async_client: AsyncCloudflare) -> None: + async with async_client.dns.settings.account.nameserver_sets.with_streaming_response.delete( + nameserver_set_id="0123456789abcdef0123456789abcdef", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + nameserver_set = await response.parse() + assert_matches_type(NameserverSetDeleteResponse, nameserver_set, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_delete(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.dns.settings.account.nameserver_sets.with_raw_response.delete( + nameserver_set_id="0123456789abcdef0123456789abcdef", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `nameserver_set_id` but received ''"): + await async_client.dns.settings.account.nameserver_sets.with_raw_response.delete( + nameserver_set_id="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + @parametrize + async def test_method_get(self, async_client: AsyncCloudflare) -> None: + nameserver_set = await async_client.dns.settings.account.nameserver_sets.get( + nameserver_set_id="0123456789abcdef0123456789abcdef", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + assert_matches_type(NameserverSetGetResponse, nameserver_set, path=["response"]) + + @parametrize + async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None: + response = await async_client.dns.settings.account.nameserver_sets.with_raw_response.get( + nameserver_set_id="0123456789abcdef0123456789abcdef", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + nameserver_set = await response.parse() + assert_matches_type(NameserverSetGetResponse, nameserver_set, path=["response"]) + + @parametrize + async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> None: + async with async_client.dns.settings.account.nameserver_sets.with_streaming_response.get( + nameserver_set_id="0123456789abcdef0123456789abcdef", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + nameserver_set = await response.parse() + assert_matches_type(NameserverSetGetResponse, nameserver_set, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_get(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.dns.settings.account.nameserver_sets.with_raw_response.get( + nameserver_set_id="0123456789abcdef0123456789abcdef", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `nameserver_set_id` but received ''"): + await async_client.dns.settings.account.nameserver_sets.with_raw_response.get( + nameserver_set_id="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) diff --git a/tests/api_resources/email_security/settings/test_allow_policies.py b/tests/api_resources/email_security/settings/test_allow_policies.py index 60c94b19241..f0261fd7516 100644 --- a/tests/api_resources/email_security/settings/test_allow_policies.py +++ b/tests/api_resources/email_security/settings/test_allow_policies.py @@ -9,6 +9,7 @@ from cloudflare import Cloudflare, AsyncCloudflare from tests.utils import assert_matches_type +from cloudflare._utils import parse_datetime from cloudflare.pagination import SyncV4PagePaginationArray, AsyncV4PagePaginationArray from cloudflare.types.email_security.settings import ( AllowPolicyGetResponse, @@ -51,6 +52,7 @@ def test_method_create_with_all_params(self, client: Cloudflare) -> None: pattern_type="EMAIL", verify_sender=True, comments="Trust all messages send from test@example.com", + expires_at=parse_datetime("2027-01-01T00:00:00Z"), is_recipient=False, is_sender=True, is_spoof=False, @@ -121,6 +123,7 @@ def test_method_list_with_all_params(self, client: Cloudflare) -> None: allow_policy = client.email_security.settings.allow_policies.list( account_id="023e105f4ecef8ad9ca31a8372d0c353", direction="asc", + expired=True, is_acceptable_sender=True, is_exempt_recipient=True, is_trusted_sender=True, @@ -323,6 +326,7 @@ def test_method_edit_with_all_params(self, client: Cloudflare) -> None: policy_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", comments="Trust all messages send from test@example.com", + expires_at=parse_datetime("2027-01-01T00:00:00Z"), is_acceptable_sender=False, is_exempt_recipient=False, is_recipient=False, @@ -459,6 +463,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncCloudflare pattern_type="EMAIL", verify_sender=True, comments="Trust all messages send from test@example.com", + expires_at=parse_datetime("2027-01-01T00:00:00Z"), is_recipient=False, is_sender=True, is_spoof=False, @@ -529,6 +534,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncCloudflare) allow_policy = await async_client.email_security.settings.allow_policies.list( account_id="023e105f4ecef8ad9ca31a8372d0c353", direction="asc", + expired=True, is_acceptable_sender=True, is_exempt_recipient=True, is_trusted_sender=True, @@ -731,6 +737,7 @@ async def test_method_edit_with_all_params(self, async_client: AsyncCloudflare) policy_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", comments="Trust all messages send from test@example.com", + expires_at=parse_datetime("2027-01-01T00:00:00Z"), is_acceptable_sender=False, is_exempt_recipient=False, is_recipient=False, diff --git a/tests/api_resources/email_security/settings/test_block_senders.py b/tests/api_resources/email_security/settings/test_block_senders.py index 43efaa89fef..09731dbde19 100644 --- a/tests/api_resources/email_security/settings/test_block_senders.py +++ b/tests/api_resources/email_security/settings/test_block_senders.py @@ -9,6 +9,7 @@ from cloudflare import Cloudflare, AsyncCloudflare from tests.utils import assert_matches_type +from cloudflare._utils import parse_datetime from cloudflare.pagination import SyncV4PagePaginationArray, AsyncV4PagePaginationArray from cloudflare.types.email_security.settings import ( BlockSenderGetResponse, @@ -43,6 +44,7 @@ def test_method_create_with_all_params(self, client: Cloudflare) -> None: pattern="test@example.com", pattern_type="EMAIL", comments="Block sender with email test@example.com", + expires_at=parse_datetime("2027-01-01T00:00:00Z"), ) assert_matches_type(Optional[BlockSenderCreateResponse], block_sender, path=["response"]) @@ -98,6 +100,7 @@ def test_method_list_with_all_params(self, client: Cloudflare) -> None: block_sender = client.email_security.settings.block_senders.list( account_id="023e105f4ecef8ad9ca31a8372d0c353", direction="asc", + expired=True, order="pattern", page=1, pattern="pattern", @@ -304,6 +307,7 @@ def test_method_edit_with_all_params(self, client: Cloudflare) -> None: pattern_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", comments="Block sender with email test@example.com", + expires_at=parse_datetime("2027-01-01T00:00:00Z"), is_regex=False, pattern="test@example.com", pattern_type="EMAIL", @@ -425,6 +429,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncCloudflare pattern="test@example.com", pattern_type="EMAIL", comments="Block sender with email test@example.com", + expires_at=parse_datetime("2027-01-01T00:00:00Z"), ) assert_matches_type(Optional[BlockSenderCreateResponse], block_sender, path=["response"]) @@ -480,6 +485,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncCloudflare) block_sender = await async_client.email_security.settings.block_senders.list( account_id="023e105f4ecef8ad9ca31a8372d0c353", direction="asc", + expired=True, order="pattern", page=1, pattern="pattern", @@ -686,6 +692,7 @@ async def test_method_edit_with_all_params(self, async_client: AsyncCloudflare) pattern_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", comments="Block sender with email test@example.com", + expires_at=parse_datetime("2027-01-01T00:00:00Z"), is_regex=False, pattern="test@example.com", pattern_type="EMAIL", diff --git a/tests/api_resources/email_security/settings/test_content_policies.py b/tests/api_resources/email_security/settings/test_content_policies.py index 9945be791a2..95a314aa48b 100644 --- a/tests/api_resources/email_security/settings/test_content_policies.py +++ b/tests/api_resources/email_security/settings/test_content_policies.py @@ -9,6 +9,7 @@ from cloudflare import Cloudflare, AsyncCloudflare from tests.utils import assert_matches_type +from cloudflare._utils import parse_datetime from cloudflare.pagination import SyncV4PagePaginationArray, AsyncV4PagePaginationArray from cloudflare.types.email_security.settings import ( ContentPolicyGetResponse, @@ -44,6 +45,7 @@ def test_method_create_with_all_params(self, client: Cloudflare) -> None: name="Block phishing keywords", pattern="urgent.*verify.*account", targets=["SUBJECT"], + expires_at=parse_datetime("2027-01-01T00:00:00Z"), notes="Blocks common phishing subject lines", ) assert_matches_type(Optional[ContentPolicyCreateResponse], content_policy, path=["response"]) @@ -104,6 +106,7 @@ def test_method_list_with_all_params(self, client: Cloudflare) -> None: account_id="023e105f4ecef8ad9ca31a8372d0c353", direction="asc", enabled=True, + expired=True, name="name", order="name", page=1, @@ -315,6 +318,7 @@ def test_method_edit_with_all_params(self, client: Cloudflare) -> None: policy_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", enabled=True, + expires_at=parse_datetime("2027-01-01T00:00:00Z"), name="Block phishing keywords", notes="Blocks common phishing subject lines", pattern="urgent.*verify.*account", @@ -435,6 +439,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncCloudflare name="Block phishing keywords", pattern="urgent.*verify.*account", targets=["SUBJECT"], + expires_at=parse_datetime("2027-01-01T00:00:00Z"), notes="Blocks common phishing subject lines", ) assert_matches_type(Optional[ContentPolicyCreateResponse], content_policy, path=["response"]) @@ -495,6 +500,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncCloudflare) account_id="023e105f4ecef8ad9ca31a8372d0c353", direction="asc", enabled=True, + expired=True, name="name", order="name", page=1, @@ -708,6 +714,7 @@ async def test_method_edit_with_all_params(self, async_client: AsyncCloudflare) policy_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", enabled=True, + expires_at=parse_datetime("2027-01-01T00:00:00Z"), name="Block phishing keywords", notes="Blocks common phishing subject lines", pattern="urgent.*verify.*account", diff --git a/tests/api_resources/email_sending/test_suppressions.py b/tests/api_resources/email_sending/test_suppressions.py index 50ad74f5cd7..c9942a03a58 100644 --- a/tests/api_resources/email_sending/test_suppressions.py +++ b/tests/api_resources/email_sending/test_suppressions.py @@ -197,7 +197,7 @@ def test_method_edit_with_all_params(self, client: Cloudflare) -> None: account_id="12345678", expires_at=parse_datetime("2027-01-01T00:00:00Z"), note="Customer re-confirmed opt-in", - scope={}, + scope={"type": "account"}, ) assert_matches_type(SuppressionEditResponse, suppression, path=["response"]) @@ -508,7 +508,7 @@ async def test_method_edit_with_all_params(self, async_client: AsyncCloudflare) account_id="12345678", expires_at=parse_datetime("2027-01-01T00:00:00Z"), note="Customer re-confirmed opt-in", - scope={}, + scope={"type": "account"}, ) assert_matches_type(SuppressionEditResponse, suppression, path=["response"]) diff --git a/tests/api_resources/flagship/apps/test_flags.py b/tests/api_resources/flagship/apps/test_flags.py index afa90c4c156..19fa9b3c062 100644 --- a/tests/api_resources/flagship/apps/test_flags.py +++ b/tests/api_resources/flagship/apps/test_flags.py @@ -76,6 +76,7 @@ def test_method_create_with_all_params(self, client: Cloudflare) -> None: ], variations={"foo": "string"}, description="description", + metadata={"foo": True}, type="boolean", ) assert_matches_type(FlagCreateResponse, flag, path=["response"]) @@ -242,6 +243,7 @@ def test_method_update_with_all_params(self, client: Cloudflare) -> None: ], variations={"foo": "string"}, description="description", + metadata={"foo": True}, type="boolean", ) assert_matches_type(FlagUpdateResponse, flag, path=["response"]) @@ -618,6 +620,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncCloudflare ], variations={"foo": "string"}, description="description", + metadata={"foo": True}, type="boolean", ) assert_matches_type(FlagCreateResponse, flag, path=["response"]) @@ -784,6 +787,7 @@ async def test_method_update_with_all_params(self, async_client: AsyncCloudflare ], variations={"foo": "string"}, description="description", + metadata={"foo": True}, type="boolean", ) assert_matches_type(FlagUpdateResponse, flag, path=["response"]) diff --git a/tests/api_resources/magic_cloud_networking/catalog_syncs/__init__.py b/tests/api_resources/k2/__init__.py similarity index 100% rename from tests/api_resources/magic_cloud_networking/catalog_syncs/__init__.py rename to tests/api_resources/k2/__init__.py diff --git a/tests/api_resources/magic_cloud_networking/on_ramps/__init__.py b/tests/api_resources/k2/streams/__init__.py similarity index 100% rename from tests/api_resources/magic_cloud_networking/on_ramps/__init__.py rename to tests/api_resources/k2/streams/__init__.py diff --git a/tests/api_resources/k2/streams/test_subscriptions.py b/tests/api_resources/k2/streams/test_subscriptions.py new file mode 100644 index 00000000000..9b43b5b28d9 --- /dev/null +++ b/tests/api_resources/k2/streams/test_subscriptions.py @@ -0,0 +1,121 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import os +from typing import Any, cast + +import pytest + +from cloudflare import Cloudflare, AsyncCloudflare +from tests.utils import assert_matches_type +from cloudflare.pagination import SyncSinglePage, AsyncSinglePage +from cloudflare.types.k2.streams import SubscriptionListResponse + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestSubscriptions: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @parametrize + def test_method_list(self, client: Cloudflare) -> None: + subscription = client.k2.streams.subscriptions.list( + stream_id="053e105f4ecef8ad9ca31a8372d0c353", + account_id="0123105f4ecef8ad9ca31a8372d0c353", + ) + assert_matches_type(SyncSinglePage[SubscriptionListResponse], subscription, path=["response"]) + + @parametrize + def test_raw_response_list(self, client: Cloudflare) -> None: + response = client.k2.streams.subscriptions.with_raw_response.list( + stream_id="053e105f4ecef8ad9ca31a8372d0c353", + account_id="0123105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + subscription = response.parse() + assert_matches_type(SyncSinglePage[SubscriptionListResponse], subscription, path=["response"]) + + @parametrize + def test_streaming_response_list(self, client: Cloudflare) -> None: + with client.k2.streams.subscriptions.with_streaming_response.list( + stream_id="053e105f4ecef8ad9ca31a8372d0c353", + account_id="0123105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + subscription = response.parse() + assert_matches_type(SyncSinglePage[SubscriptionListResponse], subscription, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_list(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.k2.streams.subscriptions.with_raw_response.list( + stream_id="053e105f4ecef8ad9ca31a8372d0c353", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `stream_id` but received ''"): + client.k2.streams.subscriptions.with_raw_response.list( + stream_id="", + account_id="0123105f4ecef8ad9ca31a8372d0c353", + ) + + +class TestAsyncSubscriptions: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @parametrize + async def test_method_list(self, async_client: AsyncCloudflare) -> None: + subscription = await async_client.k2.streams.subscriptions.list( + stream_id="053e105f4ecef8ad9ca31a8372d0c353", + account_id="0123105f4ecef8ad9ca31a8372d0c353", + ) + assert_matches_type(AsyncSinglePage[SubscriptionListResponse], subscription, path=["response"]) + + @parametrize + async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None: + response = await async_client.k2.streams.subscriptions.with_raw_response.list( + stream_id="053e105f4ecef8ad9ca31a8372d0c353", + account_id="0123105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + subscription = await response.parse() + assert_matches_type(AsyncSinglePage[SubscriptionListResponse], subscription, path=["response"]) + + @parametrize + async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> None: + async with async_client.k2.streams.subscriptions.with_streaming_response.list( + stream_id="053e105f4ecef8ad9ca31a8372d0c353", + account_id="0123105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + subscription = await response.parse() + assert_matches_type(AsyncSinglePage[SubscriptionListResponse], subscription, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_list(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.k2.streams.subscriptions.with_raw_response.list( + stream_id="053e105f4ecef8ad9ca31a8372d0c353", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `stream_id` but received ''"): + await async_client.k2.streams.subscriptions.with_raw_response.list( + stream_id="", + account_id="0123105f4ecef8ad9ca31a8372d0c353", + ) diff --git a/tests/api_resources/k2/test_streams.py b/tests/api_resources/k2/test_streams.py new file mode 100644 index 00000000000..b600a320cc8 --- /dev/null +++ b/tests/api_resources/k2/test_streams.py @@ -0,0 +1,558 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import os +from typing import Any, cast + +import pytest + +from cloudflare import Cloudflare, AsyncCloudflare +from tests.utils import assert_matches_type +from cloudflare.types.k2 import ( + StreamGetResponse, + StreamListResponse, + StreamCreateResponse, + StreamUpdateResponse, +) +from cloudflare.pagination import SyncV4PagePaginationArray, AsyncV4PagePaginationArray + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestStreams: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @parametrize + def test_method_create(self, client: Cloudflare) -> None: + stream = client.k2.streams.create( + account_id="0123105f4ecef8ad9ca31a8372d0c353", + name="my_k2_stream", + ) + assert_matches_type(StreamCreateResponse, stream, path=["response"]) + + @parametrize + def test_method_create_with_all_params(self, client: Cloudflare) -> None: + stream = client.k2.streams.create( + account_id="0123105f4ecef8ad9ca31a8372d0c353", + name="my_k2_stream", + http={ + "enabled": True, + "authentication": True, + "cors": {"origins": ["string"]}, + }, + retention_seconds=3600, + worker_binding={"enabled": True}, + ) + assert_matches_type(StreamCreateResponse, stream, path=["response"]) + + @parametrize + def test_raw_response_create(self, client: Cloudflare) -> None: + response = client.k2.streams.with_raw_response.create( + account_id="0123105f4ecef8ad9ca31a8372d0c353", + name="my_k2_stream", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + stream = response.parse() + assert_matches_type(StreamCreateResponse, stream, path=["response"]) + + @parametrize + def test_streaming_response_create(self, client: Cloudflare) -> None: + with client.k2.streams.with_streaming_response.create( + account_id="0123105f4ecef8ad9ca31a8372d0c353", + name="my_k2_stream", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + stream = response.parse() + assert_matches_type(StreamCreateResponse, stream, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_create(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.k2.streams.with_raw_response.create( + account_id="", + name="my_k2_stream", + ) + + @parametrize + def test_method_update(self, client: Cloudflare) -> None: + stream = client.k2.streams.update( + stream_id="053e105f4ecef8ad9ca31a8372d0c353", + account_id="0123105f4ecef8ad9ca31a8372d0c353", + ) + assert_matches_type(StreamUpdateResponse, stream, path=["response"]) + + @parametrize + def test_method_update_with_all_params(self, client: Cloudflare) -> None: + stream = client.k2.streams.update( + stream_id="053e105f4ecef8ad9ca31a8372d0c353", + account_id="0123105f4ecef8ad9ca31a8372d0c353", + http={ + "enabled": True, + "authentication": True, + "cors": {"origins": ["string"]}, + }, + retention_seconds=3600, + worker_binding={"enabled": True}, + ) + assert_matches_type(StreamUpdateResponse, stream, path=["response"]) + + @parametrize + def test_raw_response_update(self, client: Cloudflare) -> None: + response = client.k2.streams.with_raw_response.update( + stream_id="053e105f4ecef8ad9ca31a8372d0c353", + account_id="0123105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + stream = response.parse() + assert_matches_type(StreamUpdateResponse, stream, path=["response"]) + + @parametrize + def test_streaming_response_update(self, client: Cloudflare) -> None: + with client.k2.streams.with_streaming_response.update( + stream_id="053e105f4ecef8ad9ca31a8372d0c353", + account_id="0123105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + stream = response.parse() + assert_matches_type(StreamUpdateResponse, stream, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_update(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.k2.streams.with_raw_response.update( + stream_id="053e105f4ecef8ad9ca31a8372d0c353", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `stream_id` but received ''"): + client.k2.streams.with_raw_response.update( + stream_id="", + account_id="0123105f4ecef8ad9ca31a8372d0c353", + ) + + @parametrize + def test_method_list(self, client: Cloudflare) -> None: + stream = client.k2.streams.list( + account_id="0123105f4ecef8ad9ca31a8372d0c353", + ) + assert_matches_type(SyncV4PagePaginationArray[StreamListResponse], stream, path=["response"]) + + @parametrize + def test_method_list_with_all_params(self, client: Cloudflare) -> None: + stream = client.k2.streams.list( + account_id="0123105f4ecef8ad9ca31a8372d0c353", + name="x", + page=1, + per_page=1, + ) + assert_matches_type(SyncV4PagePaginationArray[StreamListResponse], stream, path=["response"]) + + @parametrize + def test_raw_response_list(self, client: Cloudflare) -> None: + response = client.k2.streams.with_raw_response.list( + account_id="0123105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + stream = response.parse() + assert_matches_type(SyncV4PagePaginationArray[StreamListResponse], stream, path=["response"]) + + @parametrize + def test_streaming_response_list(self, client: Cloudflare) -> None: + with client.k2.streams.with_streaming_response.list( + account_id="0123105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + stream = response.parse() + assert_matches_type(SyncV4PagePaginationArray[StreamListResponse], stream, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_list(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.k2.streams.with_raw_response.list( + account_id="", + ) + + @parametrize + def test_method_delete(self, client: Cloudflare) -> None: + stream = client.k2.streams.delete( + stream_id="053e105f4ecef8ad9ca31a8372d0c353", + account_id="0123105f4ecef8ad9ca31a8372d0c353", + ) + assert_matches_type(object, stream, path=["response"]) + + @parametrize + def test_raw_response_delete(self, client: Cloudflare) -> None: + response = client.k2.streams.with_raw_response.delete( + stream_id="053e105f4ecef8ad9ca31a8372d0c353", + account_id="0123105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + stream = response.parse() + assert_matches_type(object, stream, path=["response"]) + + @parametrize + def test_streaming_response_delete(self, client: Cloudflare) -> None: + with client.k2.streams.with_streaming_response.delete( + stream_id="053e105f4ecef8ad9ca31a8372d0c353", + account_id="0123105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + stream = response.parse() + assert_matches_type(object, stream, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_delete(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.k2.streams.with_raw_response.delete( + stream_id="053e105f4ecef8ad9ca31a8372d0c353", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `stream_id` but received ''"): + client.k2.streams.with_raw_response.delete( + stream_id="", + account_id="0123105f4ecef8ad9ca31a8372d0c353", + ) + + @parametrize + def test_method_get(self, client: Cloudflare) -> None: + stream = client.k2.streams.get( + stream_id="053e105f4ecef8ad9ca31a8372d0c353", + account_id="0123105f4ecef8ad9ca31a8372d0c353", + ) + assert_matches_type(StreamGetResponse, stream, path=["response"]) + + @parametrize + def test_raw_response_get(self, client: Cloudflare) -> None: + response = client.k2.streams.with_raw_response.get( + stream_id="053e105f4ecef8ad9ca31a8372d0c353", + account_id="0123105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + stream = response.parse() + assert_matches_type(StreamGetResponse, stream, path=["response"]) + + @parametrize + def test_streaming_response_get(self, client: Cloudflare) -> None: + with client.k2.streams.with_streaming_response.get( + stream_id="053e105f4ecef8ad9ca31a8372d0c353", + account_id="0123105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + stream = response.parse() + assert_matches_type(StreamGetResponse, stream, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_get(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.k2.streams.with_raw_response.get( + stream_id="053e105f4ecef8ad9ca31a8372d0c353", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `stream_id` but received ''"): + client.k2.streams.with_raw_response.get( + stream_id="", + account_id="0123105f4ecef8ad9ca31a8372d0c353", + ) + + +class TestAsyncStreams: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @parametrize + async def test_method_create(self, async_client: AsyncCloudflare) -> None: + stream = await async_client.k2.streams.create( + account_id="0123105f4ecef8ad9ca31a8372d0c353", + name="my_k2_stream", + ) + assert_matches_type(StreamCreateResponse, stream, path=["response"]) + + @parametrize + async def test_method_create_with_all_params(self, async_client: AsyncCloudflare) -> None: + stream = await async_client.k2.streams.create( + account_id="0123105f4ecef8ad9ca31a8372d0c353", + name="my_k2_stream", + http={ + "enabled": True, + "authentication": True, + "cors": {"origins": ["string"]}, + }, + retention_seconds=3600, + worker_binding={"enabled": True}, + ) + assert_matches_type(StreamCreateResponse, stream, path=["response"]) + + @parametrize + async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None: + response = await async_client.k2.streams.with_raw_response.create( + account_id="0123105f4ecef8ad9ca31a8372d0c353", + name="my_k2_stream", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + stream = await response.parse() + assert_matches_type(StreamCreateResponse, stream, path=["response"]) + + @parametrize + async def test_streaming_response_create(self, async_client: AsyncCloudflare) -> None: + async with async_client.k2.streams.with_streaming_response.create( + account_id="0123105f4ecef8ad9ca31a8372d0c353", + name="my_k2_stream", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + stream = await response.parse() + assert_matches_type(StreamCreateResponse, stream, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_create(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.k2.streams.with_raw_response.create( + account_id="", + name="my_k2_stream", + ) + + @parametrize + async def test_method_update(self, async_client: AsyncCloudflare) -> None: + stream = await async_client.k2.streams.update( + stream_id="053e105f4ecef8ad9ca31a8372d0c353", + account_id="0123105f4ecef8ad9ca31a8372d0c353", + ) + assert_matches_type(StreamUpdateResponse, stream, path=["response"]) + + @parametrize + async def test_method_update_with_all_params(self, async_client: AsyncCloudflare) -> None: + stream = await async_client.k2.streams.update( + stream_id="053e105f4ecef8ad9ca31a8372d0c353", + account_id="0123105f4ecef8ad9ca31a8372d0c353", + http={ + "enabled": True, + "authentication": True, + "cors": {"origins": ["string"]}, + }, + retention_seconds=3600, + worker_binding={"enabled": True}, + ) + assert_matches_type(StreamUpdateResponse, stream, path=["response"]) + + @parametrize + async def test_raw_response_update(self, async_client: AsyncCloudflare) -> None: + response = await async_client.k2.streams.with_raw_response.update( + stream_id="053e105f4ecef8ad9ca31a8372d0c353", + account_id="0123105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + stream = await response.parse() + assert_matches_type(StreamUpdateResponse, stream, path=["response"]) + + @parametrize + async def test_streaming_response_update(self, async_client: AsyncCloudflare) -> None: + async with async_client.k2.streams.with_streaming_response.update( + stream_id="053e105f4ecef8ad9ca31a8372d0c353", + account_id="0123105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + stream = await response.parse() + assert_matches_type(StreamUpdateResponse, stream, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_update(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.k2.streams.with_raw_response.update( + stream_id="053e105f4ecef8ad9ca31a8372d0c353", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `stream_id` but received ''"): + await async_client.k2.streams.with_raw_response.update( + stream_id="", + account_id="0123105f4ecef8ad9ca31a8372d0c353", + ) + + @parametrize + async def test_method_list(self, async_client: AsyncCloudflare) -> None: + stream = await async_client.k2.streams.list( + account_id="0123105f4ecef8ad9ca31a8372d0c353", + ) + assert_matches_type(AsyncV4PagePaginationArray[StreamListResponse], stream, path=["response"]) + + @parametrize + async def test_method_list_with_all_params(self, async_client: AsyncCloudflare) -> None: + stream = await async_client.k2.streams.list( + account_id="0123105f4ecef8ad9ca31a8372d0c353", + name="x", + page=1, + per_page=1, + ) + assert_matches_type(AsyncV4PagePaginationArray[StreamListResponse], stream, path=["response"]) + + @parametrize + async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None: + response = await async_client.k2.streams.with_raw_response.list( + account_id="0123105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + stream = await response.parse() + assert_matches_type(AsyncV4PagePaginationArray[StreamListResponse], stream, path=["response"]) + + @parametrize + async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> None: + async with async_client.k2.streams.with_streaming_response.list( + account_id="0123105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + stream = await response.parse() + assert_matches_type(AsyncV4PagePaginationArray[StreamListResponse], stream, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_list(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.k2.streams.with_raw_response.list( + account_id="", + ) + + @parametrize + async def test_method_delete(self, async_client: AsyncCloudflare) -> None: + stream = await async_client.k2.streams.delete( + stream_id="053e105f4ecef8ad9ca31a8372d0c353", + account_id="0123105f4ecef8ad9ca31a8372d0c353", + ) + assert_matches_type(object, stream, path=["response"]) + + @parametrize + async def test_raw_response_delete(self, async_client: AsyncCloudflare) -> None: + response = await async_client.k2.streams.with_raw_response.delete( + stream_id="053e105f4ecef8ad9ca31a8372d0c353", + account_id="0123105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + stream = await response.parse() + assert_matches_type(object, stream, path=["response"]) + + @parametrize + async def test_streaming_response_delete(self, async_client: AsyncCloudflare) -> None: + async with async_client.k2.streams.with_streaming_response.delete( + stream_id="053e105f4ecef8ad9ca31a8372d0c353", + account_id="0123105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + stream = await response.parse() + assert_matches_type(object, stream, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_delete(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.k2.streams.with_raw_response.delete( + stream_id="053e105f4ecef8ad9ca31a8372d0c353", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `stream_id` but received ''"): + await async_client.k2.streams.with_raw_response.delete( + stream_id="", + account_id="0123105f4ecef8ad9ca31a8372d0c353", + ) + + @parametrize + async def test_method_get(self, async_client: AsyncCloudflare) -> None: + stream = await async_client.k2.streams.get( + stream_id="053e105f4ecef8ad9ca31a8372d0c353", + account_id="0123105f4ecef8ad9ca31a8372d0c353", + ) + assert_matches_type(StreamGetResponse, stream, path=["response"]) + + @parametrize + async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None: + response = await async_client.k2.streams.with_raw_response.get( + stream_id="053e105f4ecef8ad9ca31a8372d0c353", + account_id="0123105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + stream = await response.parse() + assert_matches_type(StreamGetResponse, stream, path=["response"]) + + @parametrize + async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> None: + async with async_client.k2.streams.with_streaming_response.get( + stream_id="053e105f4ecef8ad9ca31a8372d0c353", + account_id="0123105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + stream = await response.parse() + assert_matches_type(StreamGetResponse, stream, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_get(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.k2.streams.with_raw_response.get( + stream_id="053e105f4ecef8ad9ca31a8372d0c353", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `stream_id` but received ''"): + await async_client.k2.streams.with_raw_response.get( + stream_id="", + account_id="0123105f4ecef8ad9ca31a8372d0c353", + ) diff --git a/tests/api_resources/kv/test_namespaces.py b/tests/api_resources/kv/test_namespaces.py index 13ee36393b2..a4305be0012 100644 --- a/tests/api_resources/kv/test_namespaces.py +++ b/tests/api_resources/kv/test_namespaces.py @@ -38,6 +38,7 @@ def test_method_create_with_all_params(self, client: Cloudflare) -> None: account_id="023e105f4ecef8ad9ca31a8372d0c353", title="My Own Namespace", jurisdiction="eu", + mode="instant", ) assert_matches_type(Optional[Namespace], namespace, path=["response"]) @@ -488,6 +489,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncCloudflare account_id="023e105f4ecef8ad9ca31a8372d0c353", title="My Own Namespace", jurisdiction="eu", + mode="instant", ) assert_matches_type(Optional[Namespace], namespace, path=["response"]) diff --git a/tests/api_resources/load_balancers/test_pools.py b/tests/api_resources/load_balancers/test_pools.py index 2f251e7e181..0555472835e 100644 --- a/tests/api_resources/load_balancers/test_pools.py +++ b/tests/api_resources/load_balancers/test_pools.py @@ -47,8 +47,10 @@ def test_method_create_with_all_params(self, client: Cloudflare) -> None: "weight": 0.6, } ], + check_regions=["WEU", "ENAM"], description="Primary data center - Provider XYZ", enabled=False, + health_sources=["regional", "global"], latitude=0, load_shedding={ "default_percent": 0, @@ -60,6 +62,7 @@ def test_method_create_with_all_params(self, client: Cloudflare) -> None: minimum_origins=0, monitor="monitor", monitor_group="monitor_group", + networks=["cloudflare", "jdcloud"], notification_email="someone@example.com,sometwo@example.com", notification_filter={ "origin": { @@ -155,6 +158,7 @@ def test_method_update_with_all_params(self, client: Cloudflare) -> None: minimum_origins=0, monitor="monitor", monitor_group="monitor_group", + networks=["cloudflare", "jdcloud"], notification_email="someone@example.com,sometwo@example.com", notification_filter={ "origin": { @@ -392,6 +396,7 @@ def test_method_edit_with_all_params(self, client: Cloudflare) -> None: monitor="monitor", monitor_group="monitor_group", name="primary-dc-1", + networks=["cloudflare", "jdcloud"], notification_email="someone@example.com,sometwo@example.com", notification_filter={ "origin": { @@ -539,8 +544,10 @@ async def test_method_create_with_all_params(self, async_client: AsyncCloudflare "weight": 0.6, } ], + check_regions=["WEU", "ENAM"], description="Primary data center - Provider XYZ", enabled=False, + health_sources=["regional", "global"], latitude=0, load_shedding={ "default_percent": 0, @@ -552,6 +559,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncCloudflare minimum_origins=0, monitor="monitor", monitor_group="monitor_group", + networks=["cloudflare", "jdcloud"], notification_email="someone@example.com,sometwo@example.com", notification_filter={ "origin": { @@ -647,6 +655,7 @@ async def test_method_update_with_all_params(self, async_client: AsyncCloudflare minimum_origins=0, monitor="monitor", monitor_group="monitor_group", + networks=["cloudflare", "jdcloud"], notification_email="someone@example.com,sometwo@example.com", notification_filter={ "origin": { @@ -884,6 +893,7 @@ async def test_method_edit_with_all_params(self, async_client: AsyncCloudflare) monitor="monitor", monitor_group="monitor_group", name="primary-dc-1", + networks=["cloudflare", "jdcloud"], notification_email="someone@example.com,sometwo@example.com", notification_filter={ "origin": { diff --git a/tests/api_resources/magic_cloud_networking/catalog_syncs/test_prebuilt_policies.py b/tests/api_resources/magic_cloud_networking/catalog_syncs/test_prebuilt_policies.py deleted file mode 100644 index 9159a726003..00000000000 --- a/tests/api_resources/magic_cloud_networking/catalog_syncs/test_prebuilt_policies.py +++ /dev/null @@ -1,119 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -import os -from typing import Any, cast - -import pytest - -from cloudflare import Cloudflare, AsyncCloudflare -from tests.utils import assert_matches_type -from cloudflare.pagination import SyncSinglePage, AsyncSinglePage -from cloudflare.types.magic_cloud_networking.catalog_syncs import ( - PrebuiltPolicyListResponse, -) - -base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") - - -class TestPrebuiltPolicies: - parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) - - @parametrize - def test_method_list(self, client: Cloudflare) -> None: - prebuilt_policy = client.magic_cloud_networking.catalog_syncs.prebuilt_policies.list( - account_id="account_id", - ) - assert_matches_type(SyncSinglePage[PrebuiltPolicyListResponse], prebuilt_policy, path=["response"]) - - @parametrize - def test_method_list_with_all_params(self, client: Cloudflare) -> None: - prebuilt_policy = client.magic_cloud_networking.catalog_syncs.prebuilt_policies.list( - account_id="account_id", - destination_type="NONE", - ) - assert_matches_type(SyncSinglePage[PrebuiltPolicyListResponse], prebuilt_policy, path=["response"]) - - @parametrize - def test_raw_response_list(self, client: Cloudflare) -> None: - response = client.magic_cloud_networking.catalog_syncs.prebuilt_policies.with_raw_response.list( - account_id="account_id", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - prebuilt_policy = response.parse() - assert_matches_type(SyncSinglePage[PrebuiltPolicyListResponse], prebuilt_policy, path=["response"]) - - @parametrize - def test_streaming_response_list(self, client: Cloudflare) -> None: - with client.magic_cloud_networking.catalog_syncs.prebuilt_policies.with_streaming_response.list( - account_id="account_id", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - prebuilt_policy = response.parse() - assert_matches_type(SyncSinglePage[PrebuiltPolicyListResponse], prebuilt_policy, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @parametrize - def test_path_params_list(self, client: Cloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): - client.magic_cloud_networking.catalog_syncs.prebuilt_policies.with_raw_response.list( - account_id="", - ) - - -class TestAsyncPrebuiltPolicies: - parametrize = pytest.mark.parametrize( - "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] - ) - - @parametrize - async def test_method_list(self, async_client: AsyncCloudflare) -> None: - prebuilt_policy = await async_client.magic_cloud_networking.catalog_syncs.prebuilt_policies.list( - account_id="account_id", - ) - assert_matches_type(AsyncSinglePage[PrebuiltPolicyListResponse], prebuilt_policy, path=["response"]) - - @parametrize - async def test_method_list_with_all_params(self, async_client: AsyncCloudflare) -> None: - prebuilt_policy = await async_client.magic_cloud_networking.catalog_syncs.prebuilt_policies.list( - account_id="account_id", - destination_type="NONE", - ) - assert_matches_type(AsyncSinglePage[PrebuiltPolicyListResponse], prebuilt_policy, path=["response"]) - - @parametrize - async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None: - response = await async_client.magic_cloud_networking.catalog_syncs.prebuilt_policies.with_raw_response.list( - account_id="account_id", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - prebuilt_policy = await response.parse() - assert_matches_type(AsyncSinglePage[PrebuiltPolicyListResponse], prebuilt_policy, path=["response"]) - - @parametrize - async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> None: - async with async_client.magic_cloud_networking.catalog_syncs.prebuilt_policies.with_streaming_response.list( - account_id="account_id", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - prebuilt_policy = await response.parse() - assert_matches_type(AsyncSinglePage[PrebuiltPolicyListResponse], prebuilt_policy, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @parametrize - async def test_path_params_list(self, async_client: AsyncCloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): - await async_client.magic_cloud_networking.catalog_syncs.prebuilt_policies.with_raw_response.list( - account_id="", - ) diff --git a/tests/api_resources/magic_cloud_networking/on_ramps/test_address_spaces.py b/tests/api_resources/magic_cloud_networking/on_ramps/test_address_spaces.py deleted file mode 100644 index 4813fc1dc17..00000000000 --- a/tests/api_resources/magic_cloud_networking/on_ramps/test_address_spaces.py +++ /dev/null @@ -1,272 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -import os -from typing import Any, cast - -import pytest - -from cloudflare import Cloudflare, AsyncCloudflare -from tests.utils import assert_matches_type -from cloudflare.types.magic_cloud_networking.on_ramps import ( - AddressSpaceEditResponse, - AddressSpaceListResponse, - AddressSpaceUpdateResponse, -) - -base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") - - -class TestAddressSpaces: - parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) - - @parametrize - def test_method_update(self, client: Cloudflare) -> None: - address_space = client.magic_cloud_networking.on_ramps.address_spaces.update( - account_id="account_id", - prefixes=["192.168.0.0/16"], - ) - assert_matches_type(AddressSpaceUpdateResponse, address_space, path=["response"]) - - @parametrize - def test_raw_response_update(self, client: Cloudflare) -> None: - response = client.magic_cloud_networking.on_ramps.address_spaces.with_raw_response.update( - account_id="account_id", - prefixes=["192.168.0.0/16"], - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - address_space = response.parse() - assert_matches_type(AddressSpaceUpdateResponse, address_space, path=["response"]) - - @parametrize - def test_streaming_response_update(self, client: Cloudflare) -> None: - with client.magic_cloud_networking.on_ramps.address_spaces.with_streaming_response.update( - account_id="account_id", - prefixes=["192.168.0.0/16"], - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - address_space = response.parse() - assert_matches_type(AddressSpaceUpdateResponse, address_space, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @parametrize - def test_path_params_update(self, client: Cloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): - client.magic_cloud_networking.on_ramps.address_spaces.with_raw_response.update( - account_id="", - prefixes=["192.168.0.0/16"], - ) - - @parametrize - def test_method_list(self, client: Cloudflare) -> None: - address_space = client.magic_cloud_networking.on_ramps.address_spaces.list( - account_id="account_id", - ) - assert_matches_type(AddressSpaceListResponse, address_space, path=["response"]) - - @parametrize - def test_raw_response_list(self, client: Cloudflare) -> None: - response = client.magic_cloud_networking.on_ramps.address_spaces.with_raw_response.list( - account_id="account_id", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - address_space = response.parse() - assert_matches_type(AddressSpaceListResponse, address_space, path=["response"]) - - @parametrize - def test_streaming_response_list(self, client: Cloudflare) -> None: - with client.magic_cloud_networking.on_ramps.address_spaces.with_streaming_response.list( - account_id="account_id", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - address_space = response.parse() - assert_matches_type(AddressSpaceListResponse, address_space, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @parametrize - def test_path_params_list(self, client: Cloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): - client.magic_cloud_networking.on_ramps.address_spaces.with_raw_response.list( - account_id="", - ) - - @parametrize - def test_method_edit(self, client: Cloudflare) -> None: - address_space = client.magic_cloud_networking.on_ramps.address_spaces.edit( - account_id="account_id", - prefixes=["192.168.0.0/16"], - ) - assert_matches_type(AddressSpaceEditResponse, address_space, path=["response"]) - - @parametrize - def test_raw_response_edit(self, client: Cloudflare) -> None: - response = client.magic_cloud_networking.on_ramps.address_spaces.with_raw_response.edit( - account_id="account_id", - prefixes=["192.168.0.0/16"], - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - address_space = response.parse() - assert_matches_type(AddressSpaceEditResponse, address_space, path=["response"]) - - @parametrize - def test_streaming_response_edit(self, client: Cloudflare) -> None: - with client.magic_cloud_networking.on_ramps.address_spaces.with_streaming_response.edit( - account_id="account_id", - prefixes=["192.168.0.0/16"], - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - address_space = response.parse() - assert_matches_type(AddressSpaceEditResponse, address_space, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @parametrize - def test_path_params_edit(self, client: Cloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): - client.magic_cloud_networking.on_ramps.address_spaces.with_raw_response.edit( - account_id="", - prefixes=["192.168.0.0/16"], - ) - - -class TestAsyncAddressSpaces: - parametrize = pytest.mark.parametrize( - "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] - ) - - @parametrize - async def test_method_update(self, async_client: AsyncCloudflare) -> None: - address_space = await async_client.magic_cloud_networking.on_ramps.address_spaces.update( - account_id="account_id", - prefixes=["192.168.0.0/16"], - ) - assert_matches_type(AddressSpaceUpdateResponse, address_space, path=["response"]) - - @parametrize - async def test_raw_response_update(self, async_client: AsyncCloudflare) -> None: - response = await async_client.magic_cloud_networking.on_ramps.address_spaces.with_raw_response.update( - account_id="account_id", - prefixes=["192.168.0.0/16"], - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - address_space = await response.parse() - assert_matches_type(AddressSpaceUpdateResponse, address_space, path=["response"]) - - @parametrize - async def test_streaming_response_update(self, async_client: AsyncCloudflare) -> None: - async with async_client.magic_cloud_networking.on_ramps.address_spaces.with_streaming_response.update( - account_id="account_id", - prefixes=["192.168.0.0/16"], - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - address_space = await response.parse() - assert_matches_type(AddressSpaceUpdateResponse, address_space, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @parametrize - async def test_path_params_update(self, async_client: AsyncCloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): - await async_client.magic_cloud_networking.on_ramps.address_spaces.with_raw_response.update( - account_id="", - prefixes=["192.168.0.0/16"], - ) - - @parametrize - async def test_method_list(self, async_client: AsyncCloudflare) -> None: - address_space = await async_client.magic_cloud_networking.on_ramps.address_spaces.list( - account_id="account_id", - ) - assert_matches_type(AddressSpaceListResponse, address_space, path=["response"]) - - @parametrize - async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None: - response = await async_client.magic_cloud_networking.on_ramps.address_spaces.with_raw_response.list( - account_id="account_id", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - address_space = await response.parse() - assert_matches_type(AddressSpaceListResponse, address_space, path=["response"]) - - @parametrize - async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> None: - async with async_client.magic_cloud_networking.on_ramps.address_spaces.with_streaming_response.list( - account_id="account_id", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - address_space = await response.parse() - assert_matches_type(AddressSpaceListResponse, address_space, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @parametrize - async def test_path_params_list(self, async_client: AsyncCloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): - await async_client.magic_cloud_networking.on_ramps.address_spaces.with_raw_response.list( - account_id="", - ) - - @parametrize - async def test_method_edit(self, async_client: AsyncCloudflare) -> None: - address_space = await async_client.magic_cloud_networking.on_ramps.address_spaces.edit( - account_id="account_id", - prefixes=["192.168.0.0/16"], - ) - assert_matches_type(AddressSpaceEditResponse, address_space, path=["response"]) - - @parametrize - async def test_raw_response_edit(self, async_client: AsyncCloudflare) -> None: - response = await async_client.magic_cloud_networking.on_ramps.address_spaces.with_raw_response.edit( - account_id="account_id", - prefixes=["192.168.0.0/16"], - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - address_space = await response.parse() - assert_matches_type(AddressSpaceEditResponse, address_space, path=["response"]) - - @parametrize - async def test_streaming_response_edit(self, async_client: AsyncCloudflare) -> None: - async with async_client.magic_cloud_networking.on_ramps.address_spaces.with_streaming_response.edit( - account_id="account_id", - prefixes=["192.168.0.0/16"], - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - address_space = await response.parse() - assert_matches_type(AddressSpaceEditResponse, address_space, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @parametrize - async def test_path_params_edit(self, async_client: AsyncCloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): - await async_client.magic_cloud_networking.on_ramps.address_spaces.with_raw_response.edit( - account_id="", - prefixes=["192.168.0.0/16"], - ) diff --git a/tests/api_resources/magic_cloud_networking/test_catalog_syncs.py b/tests/api_resources/magic_cloud_networking/test_catalog_syncs.py deleted file mode 100644 index 71e9deec8ed..00000000000 --- a/tests/api_resources/magic_cloud_networking/test_catalog_syncs.py +++ /dev/null @@ -1,780 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -import os -from typing import Any, cast - -import pytest - -from cloudflare import Cloudflare, AsyncCloudflare -from tests.utils import assert_matches_type -from cloudflare.pagination import SyncSinglePage, AsyncSinglePage -from cloudflare.types.magic_cloud_networking import ( - CatalogSyncGetResponse, - CatalogSyncEditResponse, - CatalogSyncListResponse, - CatalogSyncCreateResponse, - CatalogSyncDeleteResponse, - CatalogSyncUpdateResponse, -) - -base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") - - -class TestCatalogSyncs: - parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) - - @parametrize - def test_method_create(self, client: Cloudflare) -> None: - catalog_sync = client.magic_cloud_networking.catalog_syncs.create( - account_id="account_id", - destination_type="NONE", - name="name", - update_mode="AUTO", - ) - assert_matches_type(CatalogSyncCreateResponse, catalog_sync, path=["response"]) - - @parametrize - def test_method_create_with_all_params(self, client: Cloudflare) -> None: - catalog_sync = client.magic_cloud_networking.catalog_syncs.create( - account_id="account_id", - destination_type="NONE", - name="name", - update_mode="AUTO", - description="description", - policy="policy", - forwarded="forwarded", - ) - assert_matches_type(CatalogSyncCreateResponse, catalog_sync, path=["response"]) - - @parametrize - def test_raw_response_create(self, client: Cloudflare) -> None: - response = client.magic_cloud_networking.catalog_syncs.with_raw_response.create( - account_id="account_id", - destination_type="NONE", - name="name", - update_mode="AUTO", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - catalog_sync = response.parse() - assert_matches_type(CatalogSyncCreateResponse, catalog_sync, path=["response"]) - - @parametrize - def test_streaming_response_create(self, client: Cloudflare) -> None: - with client.magic_cloud_networking.catalog_syncs.with_streaming_response.create( - account_id="account_id", - destination_type="NONE", - name="name", - update_mode="AUTO", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - catalog_sync = response.parse() - assert_matches_type(CatalogSyncCreateResponse, catalog_sync, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @parametrize - def test_path_params_create(self, client: Cloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): - client.magic_cloud_networking.catalog_syncs.with_raw_response.create( - account_id="", - destination_type="NONE", - name="name", - update_mode="AUTO", - ) - - @parametrize - def test_method_update(self, client: Cloudflare) -> None: - catalog_sync = client.magic_cloud_networking.catalog_syncs.update( - sync_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) - assert_matches_type(CatalogSyncUpdateResponse, catalog_sync, path=["response"]) - - @parametrize - def test_method_update_with_all_params(self, client: Cloudflare) -> None: - catalog_sync = client.magic_cloud_networking.catalog_syncs.update( - sync_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - description="description", - name="name", - policy="policy", - update_mode="AUTO", - ) - assert_matches_type(CatalogSyncUpdateResponse, catalog_sync, path=["response"]) - - @parametrize - def test_raw_response_update(self, client: Cloudflare) -> None: - response = client.magic_cloud_networking.catalog_syncs.with_raw_response.update( - sync_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - catalog_sync = response.parse() - assert_matches_type(CatalogSyncUpdateResponse, catalog_sync, path=["response"]) - - @parametrize - def test_streaming_response_update(self, client: Cloudflare) -> None: - with client.magic_cloud_networking.catalog_syncs.with_streaming_response.update( - sync_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - catalog_sync = response.parse() - assert_matches_type(CatalogSyncUpdateResponse, catalog_sync, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @parametrize - def test_path_params_update(self, client: Cloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): - client.magic_cloud_networking.catalog_syncs.with_raw_response.update( - sync_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="", - ) - - with pytest.raises(ValueError, match=r"Expected a non-empty value for `sync_id` but received ''"): - client.magic_cloud_networking.catalog_syncs.with_raw_response.update( - sync_id="", - account_id="account_id", - ) - - @parametrize - def test_method_list(self, client: Cloudflare) -> None: - catalog_sync = client.magic_cloud_networking.catalog_syncs.list( - account_id="account_id", - ) - assert_matches_type(SyncSinglePage[CatalogSyncListResponse], catalog_sync, path=["response"]) - - @parametrize - def test_raw_response_list(self, client: Cloudflare) -> None: - response = client.magic_cloud_networking.catalog_syncs.with_raw_response.list( - account_id="account_id", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - catalog_sync = response.parse() - assert_matches_type(SyncSinglePage[CatalogSyncListResponse], catalog_sync, path=["response"]) - - @parametrize - def test_streaming_response_list(self, client: Cloudflare) -> None: - with client.magic_cloud_networking.catalog_syncs.with_streaming_response.list( - account_id="account_id", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - catalog_sync = response.parse() - assert_matches_type(SyncSinglePage[CatalogSyncListResponse], catalog_sync, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @parametrize - def test_path_params_list(self, client: Cloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): - client.magic_cloud_networking.catalog_syncs.with_raw_response.list( - account_id="", - ) - - @parametrize - def test_method_delete(self, client: Cloudflare) -> None: - catalog_sync = client.magic_cloud_networking.catalog_syncs.delete( - sync_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) - assert_matches_type(CatalogSyncDeleteResponse, catalog_sync, path=["response"]) - - @parametrize - def test_method_delete_with_all_params(self, client: Cloudflare) -> None: - catalog_sync = client.magic_cloud_networking.catalog_syncs.delete( - sync_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - delete_destination=True, - ) - assert_matches_type(CatalogSyncDeleteResponse, catalog_sync, path=["response"]) - - @parametrize - def test_raw_response_delete(self, client: Cloudflare) -> None: - response = client.magic_cloud_networking.catalog_syncs.with_raw_response.delete( - sync_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - catalog_sync = response.parse() - assert_matches_type(CatalogSyncDeleteResponse, catalog_sync, path=["response"]) - - @parametrize - def test_streaming_response_delete(self, client: Cloudflare) -> None: - with client.magic_cloud_networking.catalog_syncs.with_streaming_response.delete( - sync_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - catalog_sync = response.parse() - assert_matches_type(CatalogSyncDeleteResponse, catalog_sync, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @parametrize - def test_path_params_delete(self, client: Cloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): - client.magic_cloud_networking.catalog_syncs.with_raw_response.delete( - sync_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="", - ) - - with pytest.raises(ValueError, match=r"Expected a non-empty value for `sync_id` but received ''"): - client.magic_cloud_networking.catalog_syncs.with_raw_response.delete( - sync_id="", - account_id="account_id", - ) - - @parametrize - def test_method_edit(self, client: Cloudflare) -> None: - catalog_sync = client.magic_cloud_networking.catalog_syncs.edit( - sync_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) - assert_matches_type(CatalogSyncEditResponse, catalog_sync, path=["response"]) - - @parametrize - def test_method_edit_with_all_params(self, client: Cloudflare) -> None: - catalog_sync = client.magic_cloud_networking.catalog_syncs.edit( - sync_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - description="description", - name="name", - policy="policy", - update_mode="AUTO", - ) - assert_matches_type(CatalogSyncEditResponse, catalog_sync, path=["response"]) - - @parametrize - def test_raw_response_edit(self, client: Cloudflare) -> None: - response = client.magic_cloud_networking.catalog_syncs.with_raw_response.edit( - sync_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - catalog_sync = response.parse() - assert_matches_type(CatalogSyncEditResponse, catalog_sync, path=["response"]) - - @parametrize - def test_streaming_response_edit(self, client: Cloudflare) -> None: - with client.magic_cloud_networking.catalog_syncs.with_streaming_response.edit( - sync_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - catalog_sync = response.parse() - assert_matches_type(CatalogSyncEditResponse, catalog_sync, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @parametrize - def test_path_params_edit(self, client: Cloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): - client.magic_cloud_networking.catalog_syncs.with_raw_response.edit( - sync_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="", - ) - - with pytest.raises(ValueError, match=r"Expected a non-empty value for `sync_id` but received ''"): - client.magic_cloud_networking.catalog_syncs.with_raw_response.edit( - sync_id="", - account_id="account_id", - ) - - @parametrize - def test_method_get(self, client: Cloudflare) -> None: - catalog_sync = client.magic_cloud_networking.catalog_syncs.get( - sync_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) - assert_matches_type(CatalogSyncGetResponse, catalog_sync, path=["response"]) - - @parametrize - def test_raw_response_get(self, client: Cloudflare) -> None: - response = client.magic_cloud_networking.catalog_syncs.with_raw_response.get( - sync_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - catalog_sync = response.parse() - assert_matches_type(CatalogSyncGetResponse, catalog_sync, path=["response"]) - - @parametrize - def test_streaming_response_get(self, client: Cloudflare) -> None: - with client.magic_cloud_networking.catalog_syncs.with_streaming_response.get( - sync_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - catalog_sync = response.parse() - assert_matches_type(CatalogSyncGetResponse, catalog_sync, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @parametrize - def test_path_params_get(self, client: Cloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): - client.magic_cloud_networking.catalog_syncs.with_raw_response.get( - sync_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="", - ) - - with pytest.raises(ValueError, match=r"Expected a non-empty value for `sync_id` but received ''"): - client.magic_cloud_networking.catalog_syncs.with_raw_response.get( - sync_id="", - account_id="account_id", - ) - - @parametrize - def test_method_refresh(self, client: Cloudflare) -> None: - catalog_sync = client.magic_cloud_networking.catalog_syncs.refresh( - sync_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) - assert_matches_type(str, catalog_sync, path=["response"]) - - @parametrize - def test_raw_response_refresh(self, client: Cloudflare) -> None: - response = client.magic_cloud_networking.catalog_syncs.with_raw_response.refresh( - sync_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - catalog_sync = response.parse() - assert_matches_type(str, catalog_sync, path=["response"]) - - @parametrize - def test_streaming_response_refresh(self, client: Cloudflare) -> None: - with client.magic_cloud_networking.catalog_syncs.with_streaming_response.refresh( - sync_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - catalog_sync = response.parse() - assert_matches_type(str, catalog_sync, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @parametrize - def test_path_params_refresh(self, client: Cloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): - client.magic_cloud_networking.catalog_syncs.with_raw_response.refresh( - sync_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="", - ) - - with pytest.raises(ValueError, match=r"Expected a non-empty value for `sync_id` but received ''"): - client.magic_cloud_networking.catalog_syncs.with_raw_response.refresh( - sync_id="", - account_id="account_id", - ) - - -class TestAsyncCatalogSyncs: - parametrize = pytest.mark.parametrize( - "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] - ) - - @parametrize - async def test_method_create(self, async_client: AsyncCloudflare) -> None: - catalog_sync = await async_client.magic_cloud_networking.catalog_syncs.create( - account_id="account_id", - destination_type="NONE", - name="name", - update_mode="AUTO", - ) - assert_matches_type(CatalogSyncCreateResponse, catalog_sync, path=["response"]) - - @parametrize - async def test_method_create_with_all_params(self, async_client: AsyncCloudflare) -> None: - catalog_sync = await async_client.magic_cloud_networking.catalog_syncs.create( - account_id="account_id", - destination_type="NONE", - name="name", - update_mode="AUTO", - description="description", - policy="policy", - forwarded="forwarded", - ) - assert_matches_type(CatalogSyncCreateResponse, catalog_sync, path=["response"]) - - @parametrize - async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None: - response = await async_client.magic_cloud_networking.catalog_syncs.with_raw_response.create( - account_id="account_id", - destination_type="NONE", - name="name", - update_mode="AUTO", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - catalog_sync = await response.parse() - assert_matches_type(CatalogSyncCreateResponse, catalog_sync, path=["response"]) - - @parametrize - async def test_streaming_response_create(self, async_client: AsyncCloudflare) -> None: - async with async_client.magic_cloud_networking.catalog_syncs.with_streaming_response.create( - account_id="account_id", - destination_type="NONE", - name="name", - update_mode="AUTO", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - catalog_sync = await response.parse() - assert_matches_type(CatalogSyncCreateResponse, catalog_sync, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @parametrize - async def test_path_params_create(self, async_client: AsyncCloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): - await async_client.magic_cloud_networking.catalog_syncs.with_raw_response.create( - account_id="", - destination_type="NONE", - name="name", - update_mode="AUTO", - ) - - @parametrize - async def test_method_update(self, async_client: AsyncCloudflare) -> None: - catalog_sync = await async_client.magic_cloud_networking.catalog_syncs.update( - sync_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) - assert_matches_type(CatalogSyncUpdateResponse, catalog_sync, path=["response"]) - - @parametrize - async def test_method_update_with_all_params(self, async_client: AsyncCloudflare) -> None: - catalog_sync = await async_client.magic_cloud_networking.catalog_syncs.update( - sync_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - description="description", - name="name", - policy="policy", - update_mode="AUTO", - ) - assert_matches_type(CatalogSyncUpdateResponse, catalog_sync, path=["response"]) - - @parametrize - async def test_raw_response_update(self, async_client: AsyncCloudflare) -> None: - response = await async_client.magic_cloud_networking.catalog_syncs.with_raw_response.update( - sync_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - catalog_sync = await response.parse() - assert_matches_type(CatalogSyncUpdateResponse, catalog_sync, path=["response"]) - - @parametrize - async def test_streaming_response_update(self, async_client: AsyncCloudflare) -> None: - async with async_client.magic_cloud_networking.catalog_syncs.with_streaming_response.update( - sync_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - catalog_sync = await response.parse() - assert_matches_type(CatalogSyncUpdateResponse, catalog_sync, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @parametrize - async def test_path_params_update(self, async_client: AsyncCloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): - await async_client.magic_cloud_networking.catalog_syncs.with_raw_response.update( - sync_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="", - ) - - with pytest.raises(ValueError, match=r"Expected a non-empty value for `sync_id` but received ''"): - await async_client.magic_cloud_networking.catalog_syncs.with_raw_response.update( - sync_id="", - account_id="account_id", - ) - - @parametrize - async def test_method_list(self, async_client: AsyncCloudflare) -> None: - catalog_sync = await async_client.magic_cloud_networking.catalog_syncs.list( - account_id="account_id", - ) - assert_matches_type(AsyncSinglePage[CatalogSyncListResponse], catalog_sync, path=["response"]) - - @parametrize - async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None: - response = await async_client.magic_cloud_networking.catalog_syncs.with_raw_response.list( - account_id="account_id", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - catalog_sync = await response.parse() - assert_matches_type(AsyncSinglePage[CatalogSyncListResponse], catalog_sync, path=["response"]) - - @parametrize - async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> None: - async with async_client.magic_cloud_networking.catalog_syncs.with_streaming_response.list( - account_id="account_id", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - catalog_sync = await response.parse() - assert_matches_type(AsyncSinglePage[CatalogSyncListResponse], catalog_sync, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @parametrize - async def test_path_params_list(self, async_client: AsyncCloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): - await async_client.magic_cloud_networking.catalog_syncs.with_raw_response.list( - account_id="", - ) - - @parametrize - async def test_method_delete(self, async_client: AsyncCloudflare) -> None: - catalog_sync = await async_client.magic_cloud_networking.catalog_syncs.delete( - sync_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) - assert_matches_type(CatalogSyncDeleteResponse, catalog_sync, path=["response"]) - - @parametrize - async def test_method_delete_with_all_params(self, async_client: AsyncCloudflare) -> None: - catalog_sync = await async_client.magic_cloud_networking.catalog_syncs.delete( - sync_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - delete_destination=True, - ) - assert_matches_type(CatalogSyncDeleteResponse, catalog_sync, path=["response"]) - - @parametrize - async def test_raw_response_delete(self, async_client: AsyncCloudflare) -> None: - response = await async_client.magic_cloud_networking.catalog_syncs.with_raw_response.delete( - sync_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - catalog_sync = await response.parse() - assert_matches_type(CatalogSyncDeleteResponse, catalog_sync, path=["response"]) - - @parametrize - async def test_streaming_response_delete(self, async_client: AsyncCloudflare) -> None: - async with async_client.magic_cloud_networking.catalog_syncs.with_streaming_response.delete( - sync_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - catalog_sync = await response.parse() - assert_matches_type(CatalogSyncDeleteResponse, catalog_sync, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @parametrize - async def test_path_params_delete(self, async_client: AsyncCloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): - await async_client.magic_cloud_networking.catalog_syncs.with_raw_response.delete( - sync_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="", - ) - - with pytest.raises(ValueError, match=r"Expected a non-empty value for `sync_id` but received ''"): - await async_client.magic_cloud_networking.catalog_syncs.with_raw_response.delete( - sync_id="", - account_id="account_id", - ) - - @parametrize - async def test_method_edit(self, async_client: AsyncCloudflare) -> None: - catalog_sync = await async_client.magic_cloud_networking.catalog_syncs.edit( - sync_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) - assert_matches_type(CatalogSyncEditResponse, catalog_sync, path=["response"]) - - @parametrize - async def test_method_edit_with_all_params(self, async_client: AsyncCloudflare) -> None: - catalog_sync = await async_client.magic_cloud_networking.catalog_syncs.edit( - sync_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - description="description", - name="name", - policy="policy", - update_mode="AUTO", - ) - assert_matches_type(CatalogSyncEditResponse, catalog_sync, path=["response"]) - - @parametrize - async def test_raw_response_edit(self, async_client: AsyncCloudflare) -> None: - response = await async_client.magic_cloud_networking.catalog_syncs.with_raw_response.edit( - sync_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - catalog_sync = await response.parse() - assert_matches_type(CatalogSyncEditResponse, catalog_sync, path=["response"]) - - @parametrize - async def test_streaming_response_edit(self, async_client: AsyncCloudflare) -> None: - async with async_client.magic_cloud_networking.catalog_syncs.with_streaming_response.edit( - sync_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - catalog_sync = await response.parse() - assert_matches_type(CatalogSyncEditResponse, catalog_sync, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @parametrize - async def test_path_params_edit(self, async_client: AsyncCloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): - await async_client.magic_cloud_networking.catalog_syncs.with_raw_response.edit( - sync_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="", - ) - - with pytest.raises(ValueError, match=r"Expected a non-empty value for `sync_id` but received ''"): - await async_client.magic_cloud_networking.catalog_syncs.with_raw_response.edit( - sync_id="", - account_id="account_id", - ) - - @parametrize - async def test_method_get(self, async_client: AsyncCloudflare) -> None: - catalog_sync = await async_client.magic_cloud_networking.catalog_syncs.get( - sync_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) - assert_matches_type(CatalogSyncGetResponse, catalog_sync, path=["response"]) - - @parametrize - async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None: - response = await async_client.magic_cloud_networking.catalog_syncs.with_raw_response.get( - sync_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - catalog_sync = await response.parse() - assert_matches_type(CatalogSyncGetResponse, catalog_sync, path=["response"]) - - @parametrize - async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> None: - async with async_client.magic_cloud_networking.catalog_syncs.with_streaming_response.get( - sync_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - catalog_sync = await response.parse() - assert_matches_type(CatalogSyncGetResponse, catalog_sync, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @parametrize - async def test_path_params_get(self, async_client: AsyncCloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): - await async_client.magic_cloud_networking.catalog_syncs.with_raw_response.get( - sync_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="", - ) - - with pytest.raises(ValueError, match=r"Expected a non-empty value for `sync_id` but received ''"): - await async_client.magic_cloud_networking.catalog_syncs.with_raw_response.get( - sync_id="", - account_id="account_id", - ) - - @parametrize - async def test_method_refresh(self, async_client: AsyncCloudflare) -> None: - catalog_sync = await async_client.magic_cloud_networking.catalog_syncs.refresh( - sync_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) - assert_matches_type(str, catalog_sync, path=["response"]) - - @parametrize - async def test_raw_response_refresh(self, async_client: AsyncCloudflare) -> None: - response = await async_client.magic_cloud_networking.catalog_syncs.with_raw_response.refresh( - sync_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - catalog_sync = await response.parse() - assert_matches_type(str, catalog_sync, path=["response"]) - - @parametrize - async def test_streaming_response_refresh(self, async_client: AsyncCloudflare) -> None: - async with async_client.magic_cloud_networking.catalog_syncs.with_streaming_response.refresh( - sync_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - catalog_sync = await response.parse() - assert_matches_type(str, catalog_sync, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @parametrize - async def test_path_params_refresh(self, async_client: AsyncCloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): - await async_client.magic_cloud_networking.catalog_syncs.with_raw_response.refresh( - sync_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="", - ) - - with pytest.raises(ValueError, match=r"Expected a non-empty value for `sync_id` but received ''"): - await async_client.magic_cloud_networking.catalog_syncs.with_raw_response.refresh( - sync_id="", - account_id="account_id", - ) diff --git a/tests/api_resources/magic_cloud_networking/test_cloud_integrations.py b/tests/api_resources/magic_cloud_networking/test_cloud_integrations.py deleted file mode 100644 index d03faca3b56..00000000000 --- a/tests/api_resources/magic_cloud_networking/test_cloud_integrations.py +++ /dev/null @@ -1,995 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -import os -from typing import Any, cast - -import pytest - -from cloudflare import Cloudflare, AsyncCloudflare -from tests.utils import assert_matches_type -from cloudflare.pagination import SyncSinglePage, AsyncSinglePage -from cloudflare.types.magic_cloud_networking import ( - CloudIntegrationGetResponse, - CloudIntegrationEditResponse, - CloudIntegrationListResponse, - CloudIntegrationCreateResponse, - CloudIntegrationDeleteResponse, - CloudIntegrationUpdateResponse, - CloudIntegrationDiscoverResponse, - CloudIntegrationDiscoverAllResponse, - CloudIntegrationInitialSetupResponse, -) - -base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") - - -class TestCloudIntegrations: - parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) - - @parametrize - def test_method_create(self, client: Cloudflare) -> None: - cloud_integration = client.magic_cloud_networking.cloud_integrations.create( - account_id="account_id", - cloud_type="AWS", - friendly_name="friendly_name", - ) - assert_matches_type(CloudIntegrationCreateResponse, cloud_integration, path=["response"]) - - @parametrize - def test_method_create_with_all_params(self, client: Cloudflare) -> None: - cloud_integration = client.magic_cloud_networking.cloud_integrations.create( - account_id="account_id", - cloud_type="AWS", - friendly_name="friendly_name", - description="description", - forwarded="forwarded", - ) - assert_matches_type(CloudIntegrationCreateResponse, cloud_integration, path=["response"]) - - @parametrize - def test_raw_response_create(self, client: Cloudflare) -> None: - response = client.magic_cloud_networking.cloud_integrations.with_raw_response.create( - account_id="account_id", - cloud_type="AWS", - friendly_name="friendly_name", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - cloud_integration = response.parse() - assert_matches_type(CloudIntegrationCreateResponse, cloud_integration, path=["response"]) - - @parametrize - def test_streaming_response_create(self, client: Cloudflare) -> None: - with client.magic_cloud_networking.cloud_integrations.with_streaming_response.create( - account_id="account_id", - cloud_type="AWS", - friendly_name="friendly_name", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - cloud_integration = response.parse() - assert_matches_type(CloudIntegrationCreateResponse, cloud_integration, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @parametrize - def test_path_params_create(self, client: Cloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): - client.magic_cloud_networking.cloud_integrations.with_raw_response.create( - account_id="", - cloud_type="AWS", - friendly_name="friendly_name", - ) - - @parametrize - def test_method_update(self, client: Cloudflare) -> None: - cloud_integration = client.magic_cloud_networking.cloud_integrations.update( - provider_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) - assert_matches_type(CloudIntegrationUpdateResponse, cloud_integration, path=["response"]) - - @parametrize - def test_method_update_with_all_params(self, client: Cloudflare) -> None: - cloud_integration = client.magic_cloud_networking.cloud_integrations.update( - provider_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - aws_arn="aws_arn", - azure_subscription_id="azure_subscription_id", - azure_tenant_id="azure_tenant_id", - description="description", - friendly_name="friendly_name", - gcp_project_id="gcp_project_id", - gcp_service_account_email="gcp_service_account_email", - ) - assert_matches_type(CloudIntegrationUpdateResponse, cloud_integration, path=["response"]) - - @parametrize - def test_raw_response_update(self, client: Cloudflare) -> None: - response = client.magic_cloud_networking.cloud_integrations.with_raw_response.update( - provider_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - cloud_integration = response.parse() - assert_matches_type(CloudIntegrationUpdateResponse, cloud_integration, path=["response"]) - - @parametrize - def test_streaming_response_update(self, client: Cloudflare) -> None: - with client.magic_cloud_networking.cloud_integrations.with_streaming_response.update( - provider_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - cloud_integration = response.parse() - assert_matches_type(CloudIntegrationUpdateResponse, cloud_integration, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @parametrize - def test_path_params_update(self, client: Cloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): - client.magic_cloud_networking.cloud_integrations.with_raw_response.update( - provider_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="", - ) - - with pytest.raises(ValueError, match=r"Expected a non-empty value for `provider_id` but received ''"): - client.magic_cloud_networking.cloud_integrations.with_raw_response.update( - provider_id="", - account_id="account_id", - ) - - @parametrize - def test_method_list(self, client: Cloudflare) -> None: - cloud_integration = client.magic_cloud_networking.cloud_integrations.list( - account_id="account_id", - ) - assert_matches_type(SyncSinglePage[CloudIntegrationListResponse], cloud_integration, path=["response"]) - - @parametrize - def test_method_list_with_all_params(self, client: Cloudflare) -> None: - cloud_integration = client.magic_cloud_networking.cloud_integrations.list( - account_id="account_id", - cloudflare=True, - desc=True, - order_by="order_by", - status=True, - ) - assert_matches_type(SyncSinglePage[CloudIntegrationListResponse], cloud_integration, path=["response"]) - - @parametrize - def test_raw_response_list(self, client: Cloudflare) -> None: - response = client.magic_cloud_networking.cloud_integrations.with_raw_response.list( - account_id="account_id", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - cloud_integration = response.parse() - assert_matches_type(SyncSinglePage[CloudIntegrationListResponse], cloud_integration, path=["response"]) - - @parametrize - def test_streaming_response_list(self, client: Cloudflare) -> None: - with client.magic_cloud_networking.cloud_integrations.with_streaming_response.list( - account_id="account_id", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - cloud_integration = response.parse() - assert_matches_type(SyncSinglePage[CloudIntegrationListResponse], cloud_integration, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @parametrize - def test_path_params_list(self, client: Cloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): - client.magic_cloud_networking.cloud_integrations.with_raw_response.list( - account_id="", - ) - - @parametrize - def test_method_delete(self, client: Cloudflare) -> None: - cloud_integration = client.magic_cloud_networking.cloud_integrations.delete( - provider_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) - assert_matches_type(CloudIntegrationDeleteResponse, cloud_integration, path=["response"]) - - @parametrize - def test_raw_response_delete(self, client: Cloudflare) -> None: - response = client.magic_cloud_networking.cloud_integrations.with_raw_response.delete( - provider_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - cloud_integration = response.parse() - assert_matches_type(CloudIntegrationDeleteResponse, cloud_integration, path=["response"]) - - @parametrize - def test_streaming_response_delete(self, client: Cloudflare) -> None: - with client.magic_cloud_networking.cloud_integrations.with_streaming_response.delete( - provider_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - cloud_integration = response.parse() - assert_matches_type(CloudIntegrationDeleteResponse, cloud_integration, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @parametrize - def test_path_params_delete(self, client: Cloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): - client.magic_cloud_networking.cloud_integrations.with_raw_response.delete( - provider_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="", - ) - - with pytest.raises(ValueError, match=r"Expected a non-empty value for `provider_id` but received ''"): - client.magic_cloud_networking.cloud_integrations.with_raw_response.delete( - provider_id="", - account_id="account_id", - ) - - @parametrize - def test_method_discover(self, client: Cloudflare) -> None: - cloud_integration = client.magic_cloud_networking.cloud_integrations.discover( - provider_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) - assert_matches_type(CloudIntegrationDiscoverResponse, cloud_integration, path=["response"]) - - @parametrize - def test_method_discover_with_all_params(self, client: Cloudflare) -> None: - cloud_integration = client.magic_cloud_networking.cloud_integrations.discover( - provider_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - v2=True, - ) - assert_matches_type(CloudIntegrationDiscoverResponse, cloud_integration, path=["response"]) - - @parametrize - def test_raw_response_discover(self, client: Cloudflare) -> None: - response = client.magic_cloud_networking.cloud_integrations.with_raw_response.discover( - provider_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - cloud_integration = response.parse() - assert_matches_type(CloudIntegrationDiscoverResponse, cloud_integration, path=["response"]) - - @parametrize - def test_streaming_response_discover(self, client: Cloudflare) -> None: - with client.magic_cloud_networking.cloud_integrations.with_streaming_response.discover( - provider_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - cloud_integration = response.parse() - assert_matches_type(CloudIntegrationDiscoverResponse, cloud_integration, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @parametrize - def test_path_params_discover(self, client: Cloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): - client.magic_cloud_networking.cloud_integrations.with_raw_response.discover( - provider_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="", - ) - - with pytest.raises(ValueError, match=r"Expected a non-empty value for `provider_id` but received ''"): - client.magic_cloud_networking.cloud_integrations.with_raw_response.discover( - provider_id="", - account_id="account_id", - ) - - @parametrize - def test_method_discover_all(self, client: Cloudflare) -> None: - cloud_integration = client.magic_cloud_networking.cloud_integrations.discover_all( - account_id="account_id", - ) - assert_matches_type(CloudIntegrationDiscoverAllResponse, cloud_integration, path=["response"]) - - @parametrize - def test_raw_response_discover_all(self, client: Cloudflare) -> None: - response = client.magic_cloud_networking.cloud_integrations.with_raw_response.discover_all( - account_id="account_id", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - cloud_integration = response.parse() - assert_matches_type(CloudIntegrationDiscoverAllResponse, cloud_integration, path=["response"]) - - @parametrize - def test_streaming_response_discover_all(self, client: Cloudflare) -> None: - with client.magic_cloud_networking.cloud_integrations.with_streaming_response.discover_all( - account_id="account_id", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - cloud_integration = response.parse() - assert_matches_type(CloudIntegrationDiscoverAllResponse, cloud_integration, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @parametrize - def test_path_params_discover_all(self, client: Cloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): - client.magic_cloud_networking.cloud_integrations.with_raw_response.discover_all( - account_id="", - ) - - @parametrize - def test_method_edit(self, client: Cloudflare) -> None: - cloud_integration = client.magic_cloud_networking.cloud_integrations.edit( - provider_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) - assert_matches_type(CloudIntegrationEditResponse, cloud_integration, path=["response"]) - - @parametrize - def test_method_edit_with_all_params(self, client: Cloudflare) -> None: - cloud_integration = client.magic_cloud_networking.cloud_integrations.edit( - provider_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - aws_arn="aws_arn", - azure_subscription_id="azure_subscription_id", - azure_tenant_id="azure_tenant_id", - description="description", - friendly_name="friendly_name", - gcp_project_id="gcp_project_id", - gcp_service_account_email="gcp_service_account_email", - ) - assert_matches_type(CloudIntegrationEditResponse, cloud_integration, path=["response"]) - - @parametrize - def test_raw_response_edit(self, client: Cloudflare) -> None: - response = client.magic_cloud_networking.cloud_integrations.with_raw_response.edit( - provider_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - cloud_integration = response.parse() - assert_matches_type(CloudIntegrationEditResponse, cloud_integration, path=["response"]) - - @parametrize - def test_streaming_response_edit(self, client: Cloudflare) -> None: - with client.magic_cloud_networking.cloud_integrations.with_streaming_response.edit( - provider_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - cloud_integration = response.parse() - assert_matches_type(CloudIntegrationEditResponse, cloud_integration, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @parametrize - def test_path_params_edit(self, client: Cloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): - client.magic_cloud_networking.cloud_integrations.with_raw_response.edit( - provider_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="", - ) - - with pytest.raises(ValueError, match=r"Expected a non-empty value for `provider_id` but received ''"): - client.magic_cloud_networking.cloud_integrations.with_raw_response.edit( - provider_id="", - account_id="account_id", - ) - - @parametrize - def test_method_get(self, client: Cloudflare) -> None: - cloud_integration = client.magic_cloud_networking.cloud_integrations.get( - provider_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) - assert_matches_type(CloudIntegrationGetResponse, cloud_integration, path=["response"]) - - @parametrize - def test_method_get_with_all_params(self, client: Cloudflare) -> None: - cloud_integration = client.magic_cloud_networking.cloud_integrations.get( - provider_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - status=True, - ) - assert_matches_type(CloudIntegrationGetResponse, cloud_integration, path=["response"]) - - @parametrize - def test_raw_response_get(self, client: Cloudflare) -> None: - response = client.magic_cloud_networking.cloud_integrations.with_raw_response.get( - provider_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - cloud_integration = response.parse() - assert_matches_type(CloudIntegrationGetResponse, cloud_integration, path=["response"]) - - @parametrize - def test_streaming_response_get(self, client: Cloudflare) -> None: - with client.magic_cloud_networking.cloud_integrations.with_streaming_response.get( - provider_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - cloud_integration = response.parse() - assert_matches_type(CloudIntegrationGetResponse, cloud_integration, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @parametrize - def test_path_params_get(self, client: Cloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): - client.magic_cloud_networking.cloud_integrations.with_raw_response.get( - provider_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="", - ) - - with pytest.raises(ValueError, match=r"Expected a non-empty value for `provider_id` but received ''"): - client.magic_cloud_networking.cloud_integrations.with_raw_response.get( - provider_id="", - account_id="account_id", - ) - - @parametrize - def test_method_initial_setup(self, client: Cloudflare) -> None: - cloud_integration = client.magic_cloud_networking.cloud_integrations.initial_setup( - provider_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) - assert_matches_type(CloudIntegrationInitialSetupResponse, cloud_integration, path=["response"]) - - @parametrize - def test_raw_response_initial_setup(self, client: Cloudflare) -> None: - response = client.magic_cloud_networking.cloud_integrations.with_raw_response.initial_setup( - provider_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - cloud_integration = response.parse() - assert_matches_type(CloudIntegrationInitialSetupResponse, cloud_integration, path=["response"]) - - @parametrize - def test_streaming_response_initial_setup(self, client: Cloudflare) -> None: - with client.magic_cloud_networking.cloud_integrations.with_streaming_response.initial_setup( - provider_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - cloud_integration = response.parse() - assert_matches_type(CloudIntegrationInitialSetupResponse, cloud_integration, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @parametrize - def test_path_params_initial_setup(self, client: Cloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): - client.magic_cloud_networking.cloud_integrations.with_raw_response.initial_setup( - provider_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="", - ) - - with pytest.raises(ValueError, match=r"Expected a non-empty value for `provider_id` but received ''"): - client.magic_cloud_networking.cloud_integrations.with_raw_response.initial_setup( - provider_id="", - account_id="account_id", - ) - - -class TestAsyncCloudIntegrations: - parametrize = pytest.mark.parametrize( - "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] - ) - - @parametrize - async def test_method_create(self, async_client: AsyncCloudflare) -> None: - cloud_integration = await async_client.magic_cloud_networking.cloud_integrations.create( - account_id="account_id", - cloud_type="AWS", - friendly_name="friendly_name", - ) - assert_matches_type(CloudIntegrationCreateResponse, cloud_integration, path=["response"]) - - @parametrize - async def test_method_create_with_all_params(self, async_client: AsyncCloudflare) -> None: - cloud_integration = await async_client.magic_cloud_networking.cloud_integrations.create( - account_id="account_id", - cloud_type="AWS", - friendly_name="friendly_name", - description="description", - forwarded="forwarded", - ) - assert_matches_type(CloudIntegrationCreateResponse, cloud_integration, path=["response"]) - - @parametrize - async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None: - response = await async_client.magic_cloud_networking.cloud_integrations.with_raw_response.create( - account_id="account_id", - cloud_type="AWS", - friendly_name="friendly_name", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - cloud_integration = await response.parse() - assert_matches_type(CloudIntegrationCreateResponse, cloud_integration, path=["response"]) - - @parametrize - async def test_streaming_response_create(self, async_client: AsyncCloudflare) -> None: - async with async_client.magic_cloud_networking.cloud_integrations.with_streaming_response.create( - account_id="account_id", - cloud_type="AWS", - friendly_name="friendly_name", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - cloud_integration = await response.parse() - assert_matches_type(CloudIntegrationCreateResponse, cloud_integration, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @parametrize - async def test_path_params_create(self, async_client: AsyncCloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): - await async_client.magic_cloud_networking.cloud_integrations.with_raw_response.create( - account_id="", - cloud_type="AWS", - friendly_name="friendly_name", - ) - - @parametrize - async def test_method_update(self, async_client: AsyncCloudflare) -> None: - cloud_integration = await async_client.magic_cloud_networking.cloud_integrations.update( - provider_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) - assert_matches_type(CloudIntegrationUpdateResponse, cloud_integration, path=["response"]) - - @parametrize - async def test_method_update_with_all_params(self, async_client: AsyncCloudflare) -> None: - cloud_integration = await async_client.magic_cloud_networking.cloud_integrations.update( - provider_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - aws_arn="aws_arn", - azure_subscription_id="azure_subscription_id", - azure_tenant_id="azure_tenant_id", - description="description", - friendly_name="friendly_name", - gcp_project_id="gcp_project_id", - gcp_service_account_email="gcp_service_account_email", - ) - assert_matches_type(CloudIntegrationUpdateResponse, cloud_integration, path=["response"]) - - @parametrize - async def test_raw_response_update(self, async_client: AsyncCloudflare) -> None: - response = await async_client.magic_cloud_networking.cloud_integrations.with_raw_response.update( - provider_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - cloud_integration = await response.parse() - assert_matches_type(CloudIntegrationUpdateResponse, cloud_integration, path=["response"]) - - @parametrize - async def test_streaming_response_update(self, async_client: AsyncCloudflare) -> None: - async with async_client.magic_cloud_networking.cloud_integrations.with_streaming_response.update( - provider_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - cloud_integration = await response.parse() - assert_matches_type(CloudIntegrationUpdateResponse, cloud_integration, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @parametrize - async def test_path_params_update(self, async_client: AsyncCloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): - await async_client.magic_cloud_networking.cloud_integrations.with_raw_response.update( - provider_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="", - ) - - with pytest.raises(ValueError, match=r"Expected a non-empty value for `provider_id` but received ''"): - await async_client.magic_cloud_networking.cloud_integrations.with_raw_response.update( - provider_id="", - account_id="account_id", - ) - - @parametrize - async def test_method_list(self, async_client: AsyncCloudflare) -> None: - cloud_integration = await async_client.magic_cloud_networking.cloud_integrations.list( - account_id="account_id", - ) - assert_matches_type(AsyncSinglePage[CloudIntegrationListResponse], cloud_integration, path=["response"]) - - @parametrize - async def test_method_list_with_all_params(self, async_client: AsyncCloudflare) -> None: - cloud_integration = await async_client.magic_cloud_networking.cloud_integrations.list( - account_id="account_id", - cloudflare=True, - desc=True, - order_by="order_by", - status=True, - ) - assert_matches_type(AsyncSinglePage[CloudIntegrationListResponse], cloud_integration, path=["response"]) - - @parametrize - async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None: - response = await async_client.magic_cloud_networking.cloud_integrations.with_raw_response.list( - account_id="account_id", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - cloud_integration = await response.parse() - assert_matches_type(AsyncSinglePage[CloudIntegrationListResponse], cloud_integration, path=["response"]) - - @parametrize - async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> None: - async with async_client.magic_cloud_networking.cloud_integrations.with_streaming_response.list( - account_id="account_id", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - cloud_integration = await response.parse() - assert_matches_type(AsyncSinglePage[CloudIntegrationListResponse], cloud_integration, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @parametrize - async def test_path_params_list(self, async_client: AsyncCloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): - await async_client.magic_cloud_networking.cloud_integrations.with_raw_response.list( - account_id="", - ) - - @parametrize - async def test_method_delete(self, async_client: AsyncCloudflare) -> None: - cloud_integration = await async_client.magic_cloud_networking.cloud_integrations.delete( - provider_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) - assert_matches_type(CloudIntegrationDeleteResponse, cloud_integration, path=["response"]) - - @parametrize - async def test_raw_response_delete(self, async_client: AsyncCloudflare) -> None: - response = await async_client.magic_cloud_networking.cloud_integrations.with_raw_response.delete( - provider_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - cloud_integration = await response.parse() - assert_matches_type(CloudIntegrationDeleteResponse, cloud_integration, path=["response"]) - - @parametrize - async def test_streaming_response_delete(self, async_client: AsyncCloudflare) -> None: - async with async_client.magic_cloud_networking.cloud_integrations.with_streaming_response.delete( - provider_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - cloud_integration = await response.parse() - assert_matches_type(CloudIntegrationDeleteResponse, cloud_integration, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @parametrize - async def test_path_params_delete(self, async_client: AsyncCloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): - await async_client.magic_cloud_networking.cloud_integrations.with_raw_response.delete( - provider_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="", - ) - - with pytest.raises(ValueError, match=r"Expected a non-empty value for `provider_id` but received ''"): - await async_client.magic_cloud_networking.cloud_integrations.with_raw_response.delete( - provider_id="", - account_id="account_id", - ) - - @parametrize - async def test_method_discover(self, async_client: AsyncCloudflare) -> None: - cloud_integration = await async_client.magic_cloud_networking.cloud_integrations.discover( - provider_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) - assert_matches_type(CloudIntegrationDiscoverResponse, cloud_integration, path=["response"]) - - @parametrize - async def test_method_discover_with_all_params(self, async_client: AsyncCloudflare) -> None: - cloud_integration = await async_client.magic_cloud_networking.cloud_integrations.discover( - provider_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - v2=True, - ) - assert_matches_type(CloudIntegrationDiscoverResponse, cloud_integration, path=["response"]) - - @parametrize - async def test_raw_response_discover(self, async_client: AsyncCloudflare) -> None: - response = await async_client.magic_cloud_networking.cloud_integrations.with_raw_response.discover( - provider_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - cloud_integration = await response.parse() - assert_matches_type(CloudIntegrationDiscoverResponse, cloud_integration, path=["response"]) - - @parametrize - async def test_streaming_response_discover(self, async_client: AsyncCloudflare) -> None: - async with async_client.magic_cloud_networking.cloud_integrations.with_streaming_response.discover( - provider_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - cloud_integration = await response.parse() - assert_matches_type(CloudIntegrationDiscoverResponse, cloud_integration, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @parametrize - async def test_path_params_discover(self, async_client: AsyncCloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): - await async_client.magic_cloud_networking.cloud_integrations.with_raw_response.discover( - provider_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="", - ) - - with pytest.raises(ValueError, match=r"Expected a non-empty value for `provider_id` but received ''"): - await async_client.magic_cloud_networking.cloud_integrations.with_raw_response.discover( - provider_id="", - account_id="account_id", - ) - - @parametrize - async def test_method_discover_all(self, async_client: AsyncCloudflare) -> None: - cloud_integration = await async_client.magic_cloud_networking.cloud_integrations.discover_all( - account_id="account_id", - ) - assert_matches_type(CloudIntegrationDiscoverAllResponse, cloud_integration, path=["response"]) - - @parametrize - async def test_raw_response_discover_all(self, async_client: AsyncCloudflare) -> None: - response = await async_client.magic_cloud_networking.cloud_integrations.with_raw_response.discover_all( - account_id="account_id", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - cloud_integration = await response.parse() - assert_matches_type(CloudIntegrationDiscoverAllResponse, cloud_integration, path=["response"]) - - @parametrize - async def test_streaming_response_discover_all(self, async_client: AsyncCloudflare) -> None: - async with async_client.magic_cloud_networking.cloud_integrations.with_streaming_response.discover_all( - account_id="account_id", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - cloud_integration = await response.parse() - assert_matches_type(CloudIntegrationDiscoverAllResponse, cloud_integration, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @parametrize - async def test_path_params_discover_all(self, async_client: AsyncCloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): - await async_client.magic_cloud_networking.cloud_integrations.with_raw_response.discover_all( - account_id="", - ) - - @parametrize - async def test_method_edit(self, async_client: AsyncCloudflare) -> None: - cloud_integration = await async_client.magic_cloud_networking.cloud_integrations.edit( - provider_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) - assert_matches_type(CloudIntegrationEditResponse, cloud_integration, path=["response"]) - - @parametrize - async def test_method_edit_with_all_params(self, async_client: AsyncCloudflare) -> None: - cloud_integration = await async_client.magic_cloud_networking.cloud_integrations.edit( - provider_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - aws_arn="aws_arn", - azure_subscription_id="azure_subscription_id", - azure_tenant_id="azure_tenant_id", - description="description", - friendly_name="friendly_name", - gcp_project_id="gcp_project_id", - gcp_service_account_email="gcp_service_account_email", - ) - assert_matches_type(CloudIntegrationEditResponse, cloud_integration, path=["response"]) - - @parametrize - async def test_raw_response_edit(self, async_client: AsyncCloudflare) -> None: - response = await async_client.magic_cloud_networking.cloud_integrations.with_raw_response.edit( - provider_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - cloud_integration = await response.parse() - assert_matches_type(CloudIntegrationEditResponse, cloud_integration, path=["response"]) - - @parametrize - async def test_streaming_response_edit(self, async_client: AsyncCloudflare) -> None: - async with async_client.magic_cloud_networking.cloud_integrations.with_streaming_response.edit( - provider_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - cloud_integration = await response.parse() - assert_matches_type(CloudIntegrationEditResponse, cloud_integration, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @parametrize - async def test_path_params_edit(self, async_client: AsyncCloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): - await async_client.magic_cloud_networking.cloud_integrations.with_raw_response.edit( - provider_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="", - ) - - with pytest.raises(ValueError, match=r"Expected a non-empty value for `provider_id` but received ''"): - await async_client.magic_cloud_networking.cloud_integrations.with_raw_response.edit( - provider_id="", - account_id="account_id", - ) - - @parametrize - async def test_method_get(self, async_client: AsyncCloudflare) -> None: - cloud_integration = await async_client.magic_cloud_networking.cloud_integrations.get( - provider_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) - assert_matches_type(CloudIntegrationGetResponse, cloud_integration, path=["response"]) - - @parametrize - async def test_method_get_with_all_params(self, async_client: AsyncCloudflare) -> None: - cloud_integration = await async_client.magic_cloud_networking.cloud_integrations.get( - provider_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - status=True, - ) - assert_matches_type(CloudIntegrationGetResponse, cloud_integration, path=["response"]) - - @parametrize - async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None: - response = await async_client.magic_cloud_networking.cloud_integrations.with_raw_response.get( - provider_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - cloud_integration = await response.parse() - assert_matches_type(CloudIntegrationGetResponse, cloud_integration, path=["response"]) - - @parametrize - async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> None: - async with async_client.magic_cloud_networking.cloud_integrations.with_streaming_response.get( - provider_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - cloud_integration = await response.parse() - assert_matches_type(CloudIntegrationGetResponse, cloud_integration, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @parametrize - async def test_path_params_get(self, async_client: AsyncCloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): - await async_client.magic_cloud_networking.cloud_integrations.with_raw_response.get( - provider_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="", - ) - - with pytest.raises(ValueError, match=r"Expected a non-empty value for `provider_id` but received ''"): - await async_client.magic_cloud_networking.cloud_integrations.with_raw_response.get( - provider_id="", - account_id="account_id", - ) - - @parametrize - async def test_method_initial_setup(self, async_client: AsyncCloudflare) -> None: - cloud_integration = await async_client.magic_cloud_networking.cloud_integrations.initial_setup( - provider_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) - assert_matches_type(CloudIntegrationInitialSetupResponse, cloud_integration, path=["response"]) - - @parametrize - async def test_raw_response_initial_setup(self, async_client: AsyncCloudflare) -> None: - response = await async_client.magic_cloud_networking.cloud_integrations.with_raw_response.initial_setup( - provider_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - cloud_integration = await response.parse() - assert_matches_type(CloudIntegrationInitialSetupResponse, cloud_integration, path=["response"]) - - @parametrize - async def test_streaming_response_initial_setup(self, async_client: AsyncCloudflare) -> None: - async with async_client.magic_cloud_networking.cloud_integrations.with_streaming_response.initial_setup( - provider_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - cloud_integration = await response.parse() - assert_matches_type(CloudIntegrationInitialSetupResponse, cloud_integration, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @parametrize - async def test_path_params_initial_setup(self, async_client: AsyncCloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): - await async_client.magic_cloud_networking.cloud_integrations.with_raw_response.initial_setup( - provider_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="", - ) - - with pytest.raises(ValueError, match=r"Expected a non-empty value for `provider_id` but received ''"): - await async_client.magic_cloud_networking.cloud_integrations.with_raw_response.initial_setup( - provider_id="", - account_id="account_id", - ) diff --git a/tests/api_resources/magic_cloud_networking/test_on_ramps.py b/tests/api_resources/magic_cloud_networking/test_on_ramps.py deleted file mode 100644 index 50fbd41a8c1..00000000000 --- a/tests/api_resources/magic_cloud_networking/test_on_ramps.py +++ /dev/null @@ -1,1132 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -import os -from typing import Any, cast - -import httpx -import pytest -from respx import MockRouter - -from cloudflare import Cloudflare, AsyncCloudflare -from tests.utils import assert_matches_type -from cloudflare._response import ( - BinaryAPIResponse, - AsyncBinaryAPIResponse, - StreamedBinaryAPIResponse, - AsyncStreamedBinaryAPIResponse, -) -from cloudflare.pagination import SyncSinglePage, AsyncSinglePage -from cloudflare.types.magic_cloud_networking import ( - OnRampGetResponse, - OnRampEditResponse, - OnRampListResponse, - OnRampPlanResponse, - OnRampApplyResponse, - OnRampCreateResponse, - OnRampDeleteResponse, - OnRampUpdateResponse, -) - -base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") - - -class TestOnRamps: - parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) - - @parametrize - def test_method_create(self, client: Cloudflare) -> None: - on_ramp = client.magic_cloud_networking.on_ramps.create( - account_id="account_id", - cloud_type="AWS", - dynamic_routing=True, - install_routes_in_cloud=True, - install_routes_in_magic_wan=True, - name="name", - type="OnrampTypeSingle", - ) - assert_matches_type(OnRampCreateResponse, on_ramp, path=["response"]) - - @parametrize - def test_method_create_with_all_params(self, client: Cloudflare) -> None: - on_ramp = client.magic_cloud_networking.on_ramps.create( - account_id="account_id", - cloud_type="AWS", - dynamic_routing=True, - install_routes_in_cloud=True, - install_routes_in_magic_wan=True, - name="name", - type="OnrampTypeSingle", - adopted_hub_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - attached_hubs=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], - attached_vpcs=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], - cloud_asn=0, - description="description", - hub_provider_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - manage_hub_to_hub_attachments=True, - manage_vpc_to_hub_attachments=True, - region="region", - vpc="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - forwarded="forwarded", - ) - assert_matches_type(OnRampCreateResponse, on_ramp, path=["response"]) - - @parametrize - def test_raw_response_create(self, client: Cloudflare) -> None: - response = client.magic_cloud_networking.on_ramps.with_raw_response.create( - account_id="account_id", - cloud_type="AWS", - dynamic_routing=True, - install_routes_in_cloud=True, - install_routes_in_magic_wan=True, - name="name", - type="OnrampTypeSingle", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - on_ramp = response.parse() - assert_matches_type(OnRampCreateResponse, on_ramp, path=["response"]) - - @parametrize - def test_streaming_response_create(self, client: Cloudflare) -> None: - with client.magic_cloud_networking.on_ramps.with_streaming_response.create( - account_id="account_id", - cloud_type="AWS", - dynamic_routing=True, - install_routes_in_cloud=True, - install_routes_in_magic_wan=True, - name="name", - type="OnrampTypeSingle", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - on_ramp = response.parse() - assert_matches_type(OnRampCreateResponse, on_ramp, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @parametrize - def test_path_params_create(self, client: Cloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): - client.magic_cloud_networking.on_ramps.with_raw_response.create( - account_id="", - cloud_type="AWS", - dynamic_routing=True, - install_routes_in_cloud=True, - install_routes_in_magic_wan=True, - name="name", - type="OnrampTypeSingle", - ) - - @parametrize - def test_method_update(self, client: Cloudflare) -> None: - on_ramp = client.magic_cloud_networking.on_ramps.update( - onramp_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) - assert_matches_type(OnRampUpdateResponse, on_ramp, path=["response"]) - - @parametrize - def test_method_update_with_all_params(self, client: Cloudflare) -> None: - on_ramp = client.magic_cloud_networking.on_ramps.update( - onramp_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - attached_hubs=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], - attached_vpcs=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], - description="description", - install_routes_in_cloud=True, - install_routes_in_magic_wan=True, - manage_hub_to_hub_attachments=True, - manage_vpc_to_hub_attachments=True, - name="name", - vpc="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ) - assert_matches_type(OnRampUpdateResponse, on_ramp, path=["response"]) - - @parametrize - def test_raw_response_update(self, client: Cloudflare) -> None: - response = client.magic_cloud_networking.on_ramps.with_raw_response.update( - onramp_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - on_ramp = response.parse() - assert_matches_type(OnRampUpdateResponse, on_ramp, path=["response"]) - - @parametrize - def test_streaming_response_update(self, client: Cloudflare) -> None: - with client.magic_cloud_networking.on_ramps.with_streaming_response.update( - onramp_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - on_ramp = response.parse() - assert_matches_type(OnRampUpdateResponse, on_ramp, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @parametrize - def test_path_params_update(self, client: Cloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): - client.magic_cloud_networking.on_ramps.with_raw_response.update( - onramp_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="", - ) - - with pytest.raises(ValueError, match=r"Expected a non-empty value for `onramp_id` but received ''"): - client.magic_cloud_networking.on_ramps.with_raw_response.update( - onramp_id="", - account_id="account_id", - ) - - @parametrize - def test_method_list(self, client: Cloudflare) -> None: - on_ramp = client.magic_cloud_networking.on_ramps.list( - account_id="account_id", - ) - assert_matches_type(SyncSinglePage[OnRampListResponse], on_ramp, path=["response"]) - - @parametrize - def test_method_list_with_all_params(self, client: Cloudflare) -> None: - on_ramp = client.magic_cloud_networking.on_ramps.list( - account_id="account_id", - desc=True, - order_by="order_by", - status=True, - vpcs=True, - ) - assert_matches_type(SyncSinglePage[OnRampListResponse], on_ramp, path=["response"]) - - @parametrize - def test_raw_response_list(self, client: Cloudflare) -> None: - response = client.magic_cloud_networking.on_ramps.with_raw_response.list( - account_id="account_id", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - on_ramp = response.parse() - assert_matches_type(SyncSinglePage[OnRampListResponse], on_ramp, path=["response"]) - - @parametrize - def test_streaming_response_list(self, client: Cloudflare) -> None: - with client.magic_cloud_networking.on_ramps.with_streaming_response.list( - account_id="account_id", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - on_ramp = response.parse() - assert_matches_type(SyncSinglePage[OnRampListResponse], on_ramp, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @parametrize - def test_path_params_list(self, client: Cloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): - client.magic_cloud_networking.on_ramps.with_raw_response.list( - account_id="", - ) - - @parametrize - def test_method_delete(self, client: Cloudflare) -> None: - on_ramp = client.magic_cloud_networking.on_ramps.delete( - onramp_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) - assert_matches_type(OnRampDeleteResponse, on_ramp, path=["response"]) - - @parametrize - def test_method_delete_with_all_params(self, client: Cloudflare) -> None: - on_ramp = client.magic_cloud_networking.on_ramps.delete( - onramp_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - destroy=True, - force=True, - ) - assert_matches_type(OnRampDeleteResponse, on_ramp, path=["response"]) - - @parametrize - def test_raw_response_delete(self, client: Cloudflare) -> None: - response = client.magic_cloud_networking.on_ramps.with_raw_response.delete( - onramp_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - on_ramp = response.parse() - assert_matches_type(OnRampDeleteResponse, on_ramp, path=["response"]) - - @parametrize - def test_streaming_response_delete(self, client: Cloudflare) -> None: - with client.magic_cloud_networking.on_ramps.with_streaming_response.delete( - onramp_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - on_ramp = response.parse() - assert_matches_type(OnRampDeleteResponse, on_ramp, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @parametrize - def test_path_params_delete(self, client: Cloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): - client.magic_cloud_networking.on_ramps.with_raw_response.delete( - onramp_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="", - ) - - with pytest.raises(ValueError, match=r"Expected a non-empty value for `onramp_id` but received ''"): - client.magic_cloud_networking.on_ramps.with_raw_response.delete( - onramp_id="", - account_id="account_id", - ) - - @parametrize - def test_method_apply(self, client: Cloudflare) -> None: - on_ramp = client.magic_cloud_networking.on_ramps.apply( - onramp_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) - assert_matches_type(OnRampApplyResponse, on_ramp, path=["response"]) - - @parametrize - def test_raw_response_apply(self, client: Cloudflare) -> None: - response = client.magic_cloud_networking.on_ramps.with_raw_response.apply( - onramp_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - on_ramp = response.parse() - assert_matches_type(OnRampApplyResponse, on_ramp, path=["response"]) - - @parametrize - def test_streaming_response_apply(self, client: Cloudflare) -> None: - with client.magic_cloud_networking.on_ramps.with_streaming_response.apply( - onramp_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - on_ramp = response.parse() - assert_matches_type(OnRampApplyResponse, on_ramp, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @parametrize - def test_path_params_apply(self, client: Cloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): - client.magic_cloud_networking.on_ramps.with_raw_response.apply( - onramp_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="", - ) - - with pytest.raises(ValueError, match=r"Expected a non-empty value for `onramp_id` but received ''"): - client.magic_cloud_networking.on_ramps.with_raw_response.apply( - onramp_id="", - account_id="account_id", - ) - - @parametrize - def test_method_edit(self, client: Cloudflare) -> None: - on_ramp = client.magic_cloud_networking.on_ramps.edit( - onramp_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) - assert_matches_type(OnRampEditResponse, on_ramp, path=["response"]) - - @parametrize - def test_method_edit_with_all_params(self, client: Cloudflare) -> None: - on_ramp = client.magic_cloud_networking.on_ramps.edit( - onramp_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - attached_hubs=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], - attached_vpcs=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], - description="description", - install_routes_in_cloud=True, - install_routes_in_magic_wan=True, - manage_hub_to_hub_attachments=True, - manage_vpc_to_hub_attachments=True, - name="name", - vpc="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ) - assert_matches_type(OnRampEditResponse, on_ramp, path=["response"]) - - @parametrize - def test_raw_response_edit(self, client: Cloudflare) -> None: - response = client.magic_cloud_networking.on_ramps.with_raw_response.edit( - onramp_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - on_ramp = response.parse() - assert_matches_type(OnRampEditResponse, on_ramp, path=["response"]) - - @parametrize - def test_streaming_response_edit(self, client: Cloudflare) -> None: - with client.magic_cloud_networking.on_ramps.with_streaming_response.edit( - onramp_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - on_ramp = response.parse() - assert_matches_type(OnRampEditResponse, on_ramp, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @parametrize - def test_path_params_edit(self, client: Cloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): - client.magic_cloud_networking.on_ramps.with_raw_response.edit( - onramp_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="", - ) - - with pytest.raises(ValueError, match=r"Expected a non-empty value for `onramp_id` but received ''"): - client.magic_cloud_networking.on_ramps.with_raw_response.edit( - onramp_id="", - account_id="account_id", - ) - - @parametrize - @pytest.mark.respx(base_url=base_url) - def test_method_export(self, client: Cloudflare, respx_mock: MockRouter) -> None: - respx_mock.post("/accounts/account_id/magic/cloud/onramps/182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e/export").mock( - return_value=httpx.Response(200, json={"foo": "bar"}) - ) - on_ramp = client.magic_cloud_networking.on_ramps.export( - onramp_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) - assert on_ramp.is_closed - assert on_ramp.json() == {"foo": "bar"} - assert cast(Any, on_ramp.is_closed) is True - assert isinstance(on_ramp, BinaryAPIResponse) - - @parametrize - @pytest.mark.respx(base_url=base_url) - def test_raw_response_export(self, client: Cloudflare, respx_mock: MockRouter) -> None: - respx_mock.post("/accounts/account_id/magic/cloud/onramps/182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e/export").mock( - return_value=httpx.Response(200, json={"foo": "bar"}) - ) - - on_ramp = client.magic_cloud_networking.on_ramps.with_raw_response.export( - onramp_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) - - assert on_ramp.is_closed is True - assert on_ramp.http_request.headers.get("X-Stainless-Lang") == "python" - assert on_ramp.json() == {"foo": "bar"} - assert isinstance(on_ramp, BinaryAPIResponse) - - @parametrize - @pytest.mark.respx(base_url=base_url) - def test_streaming_response_export(self, client: Cloudflare, respx_mock: MockRouter) -> None: - respx_mock.post("/accounts/account_id/magic/cloud/onramps/182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e/export").mock( - return_value=httpx.Response(200, json={"foo": "bar"}) - ) - with client.magic_cloud_networking.on_ramps.with_streaming_response.export( - onramp_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) as on_ramp: - assert not on_ramp.is_closed - assert on_ramp.http_request.headers.get("X-Stainless-Lang") == "python" - - assert on_ramp.json() == {"foo": "bar"} - assert cast(Any, on_ramp.is_closed) is True - assert isinstance(on_ramp, StreamedBinaryAPIResponse) - - assert cast(Any, on_ramp.is_closed) is True - - @parametrize - @pytest.mark.respx(base_url=base_url) - def test_path_params_export(self, client: Cloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): - client.magic_cloud_networking.on_ramps.with_raw_response.export( - onramp_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="", - ) - - with pytest.raises(ValueError, match=r"Expected a non-empty value for `onramp_id` but received ''"): - client.magic_cloud_networking.on_ramps.with_raw_response.export( - onramp_id="", - account_id="account_id", - ) - - @parametrize - def test_method_get(self, client: Cloudflare) -> None: - on_ramp = client.magic_cloud_networking.on_ramps.get( - onramp_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) - assert_matches_type(OnRampGetResponse, on_ramp, path=["response"]) - - @parametrize - def test_method_get_with_all_params(self, client: Cloudflare) -> None: - on_ramp = client.magic_cloud_networking.on_ramps.get( - onramp_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - planned_resources=True, - post_apply_resources=True, - status=True, - vpcs=True, - ) - assert_matches_type(OnRampGetResponse, on_ramp, path=["response"]) - - @parametrize - def test_raw_response_get(self, client: Cloudflare) -> None: - response = client.magic_cloud_networking.on_ramps.with_raw_response.get( - onramp_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - on_ramp = response.parse() - assert_matches_type(OnRampGetResponse, on_ramp, path=["response"]) - - @parametrize - def test_streaming_response_get(self, client: Cloudflare) -> None: - with client.magic_cloud_networking.on_ramps.with_streaming_response.get( - onramp_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - on_ramp = response.parse() - assert_matches_type(OnRampGetResponse, on_ramp, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @parametrize - def test_path_params_get(self, client: Cloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): - client.magic_cloud_networking.on_ramps.with_raw_response.get( - onramp_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="", - ) - - with pytest.raises(ValueError, match=r"Expected a non-empty value for `onramp_id` but received ''"): - client.magic_cloud_networking.on_ramps.with_raw_response.get( - onramp_id="", - account_id="account_id", - ) - - @parametrize - def test_method_plan(self, client: Cloudflare) -> None: - on_ramp = client.magic_cloud_networking.on_ramps.plan( - onramp_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) - assert_matches_type(OnRampPlanResponse, on_ramp, path=["response"]) - - @parametrize - def test_raw_response_plan(self, client: Cloudflare) -> None: - response = client.magic_cloud_networking.on_ramps.with_raw_response.plan( - onramp_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - on_ramp = response.parse() - assert_matches_type(OnRampPlanResponse, on_ramp, path=["response"]) - - @parametrize - def test_streaming_response_plan(self, client: Cloudflare) -> None: - with client.magic_cloud_networking.on_ramps.with_streaming_response.plan( - onramp_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - on_ramp = response.parse() - assert_matches_type(OnRampPlanResponse, on_ramp, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @parametrize - def test_path_params_plan(self, client: Cloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): - client.magic_cloud_networking.on_ramps.with_raw_response.plan( - onramp_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="", - ) - - with pytest.raises(ValueError, match=r"Expected a non-empty value for `onramp_id` but received ''"): - client.magic_cloud_networking.on_ramps.with_raw_response.plan( - onramp_id="", - account_id="account_id", - ) - - -class TestAsyncOnRamps: - parametrize = pytest.mark.parametrize( - "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] - ) - - @parametrize - async def test_method_create(self, async_client: AsyncCloudflare) -> None: - on_ramp = await async_client.magic_cloud_networking.on_ramps.create( - account_id="account_id", - cloud_type="AWS", - dynamic_routing=True, - install_routes_in_cloud=True, - install_routes_in_magic_wan=True, - name="name", - type="OnrampTypeSingle", - ) - assert_matches_type(OnRampCreateResponse, on_ramp, path=["response"]) - - @parametrize - async def test_method_create_with_all_params(self, async_client: AsyncCloudflare) -> None: - on_ramp = await async_client.magic_cloud_networking.on_ramps.create( - account_id="account_id", - cloud_type="AWS", - dynamic_routing=True, - install_routes_in_cloud=True, - install_routes_in_magic_wan=True, - name="name", - type="OnrampTypeSingle", - adopted_hub_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - attached_hubs=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], - attached_vpcs=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], - cloud_asn=0, - description="description", - hub_provider_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - manage_hub_to_hub_attachments=True, - manage_vpc_to_hub_attachments=True, - region="region", - vpc="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - forwarded="forwarded", - ) - assert_matches_type(OnRampCreateResponse, on_ramp, path=["response"]) - - @parametrize - async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None: - response = await async_client.magic_cloud_networking.on_ramps.with_raw_response.create( - account_id="account_id", - cloud_type="AWS", - dynamic_routing=True, - install_routes_in_cloud=True, - install_routes_in_magic_wan=True, - name="name", - type="OnrampTypeSingle", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - on_ramp = await response.parse() - assert_matches_type(OnRampCreateResponse, on_ramp, path=["response"]) - - @parametrize - async def test_streaming_response_create(self, async_client: AsyncCloudflare) -> None: - async with async_client.magic_cloud_networking.on_ramps.with_streaming_response.create( - account_id="account_id", - cloud_type="AWS", - dynamic_routing=True, - install_routes_in_cloud=True, - install_routes_in_magic_wan=True, - name="name", - type="OnrampTypeSingle", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - on_ramp = await response.parse() - assert_matches_type(OnRampCreateResponse, on_ramp, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @parametrize - async def test_path_params_create(self, async_client: AsyncCloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): - await async_client.magic_cloud_networking.on_ramps.with_raw_response.create( - account_id="", - cloud_type="AWS", - dynamic_routing=True, - install_routes_in_cloud=True, - install_routes_in_magic_wan=True, - name="name", - type="OnrampTypeSingle", - ) - - @parametrize - async def test_method_update(self, async_client: AsyncCloudflare) -> None: - on_ramp = await async_client.magic_cloud_networking.on_ramps.update( - onramp_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) - assert_matches_type(OnRampUpdateResponse, on_ramp, path=["response"]) - - @parametrize - async def test_method_update_with_all_params(self, async_client: AsyncCloudflare) -> None: - on_ramp = await async_client.magic_cloud_networking.on_ramps.update( - onramp_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - attached_hubs=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], - attached_vpcs=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], - description="description", - install_routes_in_cloud=True, - install_routes_in_magic_wan=True, - manage_hub_to_hub_attachments=True, - manage_vpc_to_hub_attachments=True, - name="name", - vpc="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ) - assert_matches_type(OnRampUpdateResponse, on_ramp, path=["response"]) - - @parametrize - async def test_raw_response_update(self, async_client: AsyncCloudflare) -> None: - response = await async_client.magic_cloud_networking.on_ramps.with_raw_response.update( - onramp_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - on_ramp = await response.parse() - assert_matches_type(OnRampUpdateResponse, on_ramp, path=["response"]) - - @parametrize - async def test_streaming_response_update(self, async_client: AsyncCloudflare) -> None: - async with async_client.magic_cloud_networking.on_ramps.with_streaming_response.update( - onramp_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - on_ramp = await response.parse() - assert_matches_type(OnRampUpdateResponse, on_ramp, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @parametrize - async def test_path_params_update(self, async_client: AsyncCloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): - await async_client.magic_cloud_networking.on_ramps.with_raw_response.update( - onramp_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="", - ) - - with pytest.raises(ValueError, match=r"Expected a non-empty value for `onramp_id` but received ''"): - await async_client.magic_cloud_networking.on_ramps.with_raw_response.update( - onramp_id="", - account_id="account_id", - ) - - @parametrize - async def test_method_list(self, async_client: AsyncCloudflare) -> None: - on_ramp = await async_client.magic_cloud_networking.on_ramps.list( - account_id="account_id", - ) - assert_matches_type(AsyncSinglePage[OnRampListResponse], on_ramp, path=["response"]) - - @parametrize - async def test_method_list_with_all_params(self, async_client: AsyncCloudflare) -> None: - on_ramp = await async_client.magic_cloud_networking.on_ramps.list( - account_id="account_id", - desc=True, - order_by="order_by", - status=True, - vpcs=True, - ) - assert_matches_type(AsyncSinglePage[OnRampListResponse], on_ramp, path=["response"]) - - @parametrize - async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None: - response = await async_client.magic_cloud_networking.on_ramps.with_raw_response.list( - account_id="account_id", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - on_ramp = await response.parse() - assert_matches_type(AsyncSinglePage[OnRampListResponse], on_ramp, path=["response"]) - - @parametrize - async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> None: - async with async_client.magic_cloud_networking.on_ramps.with_streaming_response.list( - account_id="account_id", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - on_ramp = await response.parse() - assert_matches_type(AsyncSinglePage[OnRampListResponse], on_ramp, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @parametrize - async def test_path_params_list(self, async_client: AsyncCloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): - await async_client.magic_cloud_networking.on_ramps.with_raw_response.list( - account_id="", - ) - - @parametrize - async def test_method_delete(self, async_client: AsyncCloudflare) -> None: - on_ramp = await async_client.magic_cloud_networking.on_ramps.delete( - onramp_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) - assert_matches_type(OnRampDeleteResponse, on_ramp, path=["response"]) - - @parametrize - async def test_method_delete_with_all_params(self, async_client: AsyncCloudflare) -> None: - on_ramp = await async_client.magic_cloud_networking.on_ramps.delete( - onramp_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - destroy=True, - force=True, - ) - assert_matches_type(OnRampDeleteResponse, on_ramp, path=["response"]) - - @parametrize - async def test_raw_response_delete(self, async_client: AsyncCloudflare) -> None: - response = await async_client.magic_cloud_networking.on_ramps.with_raw_response.delete( - onramp_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - on_ramp = await response.parse() - assert_matches_type(OnRampDeleteResponse, on_ramp, path=["response"]) - - @parametrize - async def test_streaming_response_delete(self, async_client: AsyncCloudflare) -> None: - async with async_client.magic_cloud_networking.on_ramps.with_streaming_response.delete( - onramp_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - on_ramp = await response.parse() - assert_matches_type(OnRampDeleteResponse, on_ramp, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @parametrize - async def test_path_params_delete(self, async_client: AsyncCloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): - await async_client.magic_cloud_networking.on_ramps.with_raw_response.delete( - onramp_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="", - ) - - with pytest.raises(ValueError, match=r"Expected a non-empty value for `onramp_id` but received ''"): - await async_client.magic_cloud_networking.on_ramps.with_raw_response.delete( - onramp_id="", - account_id="account_id", - ) - - @parametrize - async def test_method_apply(self, async_client: AsyncCloudflare) -> None: - on_ramp = await async_client.magic_cloud_networking.on_ramps.apply( - onramp_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) - assert_matches_type(OnRampApplyResponse, on_ramp, path=["response"]) - - @parametrize - async def test_raw_response_apply(self, async_client: AsyncCloudflare) -> None: - response = await async_client.magic_cloud_networking.on_ramps.with_raw_response.apply( - onramp_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - on_ramp = await response.parse() - assert_matches_type(OnRampApplyResponse, on_ramp, path=["response"]) - - @parametrize - async def test_streaming_response_apply(self, async_client: AsyncCloudflare) -> None: - async with async_client.magic_cloud_networking.on_ramps.with_streaming_response.apply( - onramp_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - on_ramp = await response.parse() - assert_matches_type(OnRampApplyResponse, on_ramp, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @parametrize - async def test_path_params_apply(self, async_client: AsyncCloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): - await async_client.magic_cloud_networking.on_ramps.with_raw_response.apply( - onramp_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="", - ) - - with pytest.raises(ValueError, match=r"Expected a non-empty value for `onramp_id` but received ''"): - await async_client.magic_cloud_networking.on_ramps.with_raw_response.apply( - onramp_id="", - account_id="account_id", - ) - - @parametrize - async def test_method_edit(self, async_client: AsyncCloudflare) -> None: - on_ramp = await async_client.magic_cloud_networking.on_ramps.edit( - onramp_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) - assert_matches_type(OnRampEditResponse, on_ramp, path=["response"]) - - @parametrize - async def test_method_edit_with_all_params(self, async_client: AsyncCloudflare) -> None: - on_ramp = await async_client.magic_cloud_networking.on_ramps.edit( - onramp_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - attached_hubs=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], - attached_vpcs=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], - description="description", - install_routes_in_cloud=True, - install_routes_in_magic_wan=True, - manage_hub_to_hub_attachments=True, - manage_vpc_to_hub_attachments=True, - name="name", - vpc="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ) - assert_matches_type(OnRampEditResponse, on_ramp, path=["response"]) - - @parametrize - async def test_raw_response_edit(self, async_client: AsyncCloudflare) -> None: - response = await async_client.magic_cloud_networking.on_ramps.with_raw_response.edit( - onramp_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - on_ramp = await response.parse() - assert_matches_type(OnRampEditResponse, on_ramp, path=["response"]) - - @parametrize - async def test_streaming_response_edit(self, async_client: AsyncCloudflare) -> None: - async with async_client.magic_cloud_networking.on_ramps.with_streaming_response.edit( - onramp_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - on_ramp = await response.parse() - assert_matches_type(OnRampEditResponse, on_ramp, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @parametrize - async def test_path_params_edit(self, async_client: AsyncCloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): - await async_client.magic_cloud_networking.on_ramps.with_raw_response.edit( - onramp_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="", - ) - - with pytest.raises(ValueError, match=r"Expected a non-empty value for `onramp_id` but received ''"): - await async_client.magic_cloud_networking.on_ramps.with_raw_response.edit( - onramp_id="", - account_id="account_id", - ) - - @parametrize - @pytest.mark.respx(base_url=base_url) - async def test_method_export(self, async_client: AsyncCloudflare, respx_mock: MockRouter) -> None: - respx_mock.post("/accounts/account_id/magic/cloud/onramps/182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e/export").mock( - return_value=httpx.Response(200, json={"foo": "bar"}) - ) - on_ramp = await async_client.magic_cloud_networking.on_ramps.export( - onramp_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) - assert on_ramp.is_closed - assert await on_ramp.json() == {"foo": "bar"} - assert cast(Any, on_ramp.is_closed) is True - assert isinstance(on_ramp, AsyncBinaryAPIResponse) - - @parametrize - @pytest.mark.respx(base_url=base_url) - async def test_raw_response_export(self, async_client: AsyncCloudflare, respx_mock: MockRouter) -> None: - respx_mock.post("/accounts/account_id/magic/cloud/onramps/182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e/export").mock( - return_value=httpx.Response(200, json={"foo": "bar"}) - ) - - on_ramp = await async_client.magic_cloud_networking.on_ramps.with_raw_response.export( - onramp_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) - - assert on_ramp.is_closed is True - assert on_ramp.http_request.headers.get("X-Stainless-Lang") == "python" - assert await on_ramp.json() == {"foo": "bar"} - assert isinstance(on_ramp, AsyncBinaryAPIResponse) - - @parametrize - @pytest.mark.respx(base_url=base_url) - async def test_streaming_response_export(self, async_client: AsyncCloudflare, respx_mock: MockRouter) -> None: - respx_mock.post("/accounts/account_id/magic/cloud/onramps/182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e/export").mock( - return_value=httpx.Response(200, json={"foo": "bar"}) - ) - async with async_client.magic_cloud_networking.on_ramps.with_streaming_response.export( - onramp_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) as on_ramp: - assert not on_ramp.is_closed - assert on_ramp.http_request.headers.get("X-Stainless-Lang") == "python" - - assert await on_ramp.json() == {"foo": "bar"} - assert cast(Any, on_ramp.is_closed) is True - assert isinstance(on_ramp, AsyncStreamedBinaryAPIResponse) - - assert cast(Any, on_ramp.is_closed) is True - - @parametrize - @pytest.mark.respx(base_url=base_url) - async def test_path_params_export(self, async_client: AsyncCloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): - await async_client.magic_cloud_networking.on_ramps.with_raw_response.export( - onramp_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="", - ) - - with pytest.raises(ValueError, match=r"Expected a non-empty value for `onramp_id` but received ''"): - await async_client.magic_cloud_networking.on_ramps.with_raw_response.export( - onramp_id="", - account_id="account_id", - ) - - @parametrize - async def test_method_get(self, async_client: AsyncCloudflare) -> None: - on_ramp = await async_client.magic_cloud_networking.on_ramps.get( - onramp_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) - assert_matches_type(OnRampGetResponse, on_ramp, path=["response"]) - - @parametrize - async def test_method_get_with_all_params(self, async_client: AsyncCloudflare) -> None: - on_ramp = await async_client.magic_cloud_networking.on_ramps.get( - onramp_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - planned_resources=True, - post_apply_resources=True, - status=True, - vpcs=True, - ) - assert_matches_type(OnRampGetResponse, on_ramp, path=["response"]) - - @parametrize - async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None: - response = await async_client.magic_cloud_networking.on_ramps.with_raw_response.get( - onramp_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - on_ramp = await response.parse() - assert_matches_type(OnRampGetResponse, on_ramp, path=["response"]) - - @parametrize - async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> None: - async with async_client.magic_cloud_networking.on_ramps.with_streaming_response.get( - onramp_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - on_ramp = await response.parse() - assert_matches_type(OnRampGetResponse, on_ramp, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @parametrize - async def test_path_params_get(self, async_client: AsyncCloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): - await async_client.magic_cloud_networking.on_ramps.with_raw_response.get( - onramp_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="", - ) - - with pytest.raises(ValueError, match=r"Expected a non-empty value for `onramp_id` but received ''"): - await async_client.magic_cloud_networking.on_ramps.with_raw_response.get( - onramp_id="", - account_id="account_id", - ) - - @parametrize - async def test_method_plan(self, async_client: AsyncCloudflare) -> None: - on_ramp = await async_client.magic_cloud_networking.on_ramps.plan( - onramp_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) - assert_matches_type(OnRampPlanResponse, on_ramp, path=["response"]) - - @parametrize - async def test_raw_response_plan(self, async_client: AsyncCloudflare) -> None: - response = await async_client.magic_cloud_networking.on_ramps.with_raw_response.plan( - onramp_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - on_ramp = await response.parse() - assert_matches_type(OnRampPlanResponse, on_ramp, path=["response"]) - - @parametrize - async def test_streaming_response_plan(self, async_client: AsyncCloudflare) -> None: - async with async_client.magic_cloud_networking.on_ramps.with_streaming_response.plan( - onramp_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - on_ramp = await response.parse() - assert_matches_type(OnRampPlanResponse, on_ramp, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @parametrize - async def test_path_params_plan(self, async_client: AsyncCloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): - await async_client.magic_cloud_networking.on_ramps.with_raw_response.plan( - onramp_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="", - ) - - with pytest.raises(ValueError, match=r"Expected a non-empty value for `onramp_id` but received ''"): - await async_client.magic_cloud_networking.on_ramps.with_raw_response.plan( - onramp_id="", - account_id="account_id", - ) diff --git a/tests/api_resources/magic_cloud_networking/test_resources.py b/tests/api_resources/magic_cloud_networking/test_resources.py deleted file mode 100644 index 8275125681e..00000000000 --- a/tests/api_resources/magic_cloud_networking/test_resources.py +++ /dev/null @@ -1,508 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -import os -from typing import Any, cast - -import httpx -import pytest -from respx import MockRouter - -from cloudflare import Cloudflare, AsyncCloudflare -from tests.utils import assert_matches_type -from cloudflare._response import ( - BinaryAPIResponse, - AsyncBinaryAPIResponse, - StreamedBinaryAPIResponse, - AsyncStreamedBinaryAPIResponse, -) -from cloudflare.pagination import SyncV4PagePaginationArray, AsyncV4PagePaginationArray -from cloudflare.types.magic_cloud_networking import ( - ResourceGetResponse, - ResourceListResponse, -) - -base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") - - -class TestResources: - parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) - - @parametrize - def test_method_list(self, client: Cloudflare) -> None: - resource = client.magic_cloud_networking.resources.list( - account_id="account_id", - ) - assert_matches_type(SyncV4PagePaginationArray[ResourceListResponse], resource, path=["response"]) - - @parametrize - def test_method_list_with_all_params(self, client: Cloudflare) -> None: - resource = client.magic_cloud_networking.resources.list( - account_id="account_id", - cloudflare=True, - desc=True, - managed=True, - order_by="order_by", - page=1, - per_page=1, - provider_id="provider_id", - region="region", - resource_group="resource_group", - resource_id=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], - resource_type=["aws_customer_gateway"], - search=["string"], - v2=True, - ) - assert_matches_type(SyncV4PagePaginationArray[ResourceListResponse], resource, path=["response"]) - - @parametrize - def test_raw_response_list(self, client: Cloudflare) -> None: - response = client.magic_cloud_networking.resources.with_raw_response.list( - account_id="account_id", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - resource = response.parse() - assert_matches_type(SyncV4PagePaginationArray[ResourceListResponse], resource, path=["response"]) - - @parametrize - def test_streaming_response_list(self, client: Cloudflare) -> None: - with client.magic_cloud_networking.resources.with_streaming_response.list( - account_id="account_id", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - resource = response.parse() - assert_matches_type(SyncV4PagePaginationArray[ResourceListResponse], resource, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @parametrize - def test_path_params_list(self, client: Cloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): - client.magic_cloud_networking.resources.with_raw_response.list( - account_id="", - ) - - @parametrize - @pytest.mark.respx(base_url=base_url) - def test_method_export(self, client: Cloudflare, respx_mock: MockRouter) -> None: - respx_mock.get("/accounts/account_id/magic/cloud/resources/export").mock( - return_value=httpx.Response(200, json={"foo": "bar"}) - ) - resource = client.magic_cloud_networking.resources.export( - account_id="account_id", - ) - assert resource.is_closed - assert resource.json() == {"foo": "bar"} - assert cast(Any, resource.is_closed) is True - assert isinstance(resource, BinaryAPIResponse) - - @parametrize - @pytest.mark.respx(base_url=base_url) - def test_method_export_with_all_params(self, client: Cloudflare, respx_mock: MockRouter) -> None: - respx_mock.get("/accounts/account_id/magic/cloud/resources/export").mock( - return_value=httpx.Response(200, json={"foo": "bar"}) - ) - resource = client.magic_cloud_networking.resources.export( - account_id="account_id", - desc=True, - order_by="order_by", - provider_id="provider_id", - region="region", - resource_group="resource_group", - resource_id=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], - resource_type=["aws_customer_gateway"], - search=["string"], - v2=True, - ) - assert resource.is_closed - assert resource.json() == {"foo": "bar"} - assert cast(Any, resource.is_closed) is True - assert isinstance(resource, BinaryAPIResponse) - - @parametrize - @pytest.mark.respx(base_url=base_url) - def test_raw_response_export(self, client: Cloudflare, respx_mock: MockRouter) -> None: - respx_mock.get("/accounts/account_id/magic/cloud/resources/export").mock( - return_value=httpx.Response(200, json={"foo": "bar"}) - ) - - resource = client.magic_cloud_networking.resources.with_raw_response.export( - account_id="account_id", - ) - - assert resource.is_closed is True - assert resource.http_request.headers.get("X-Stainless-Lang") == "python" - assert resource.json() == {"foo": "bar"} - assert isinstance(resource, BinaryAPIResponse) - - @parametrize - @pytest.mark.respx(base_url=base_url) - def test_streaming_response_export(self, client: Cloudflare, respx_mock: MockRouter) -> None: - respx_mock.get("/accounts/account_id/magic/cloud/resources/export").mock( - return_value=httpx.Response(200, json={"foo": "bar"}) - ) - with client.magic_cloud_networking.resources.with_streaming_response.export( - account_id="account_id", - ) as resource: - assert not resource.is_closed - assert resource.http_request.headers.get("X-Stainless-Lang") == "python" - - assert resource.json() == {"foo": "bar"} - assert cast(Any, resource.is_closed) is True - assert isinstance(resource, StreamedBinaryAPIResponse) - - assert cast(Any, resource.is_closed) is True - - @parametrize - @pytest.mark.respx(base_url=base_url) - def test_path_params_export(self, client: Cloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): - client.magic_cloud_networking.resources.with_raw_response.export( - account_id="", - ) - - @parametrize - def test_method_get(self, client: Cloudflare) -> None: - resource = client.magic_cloud_networking.resources.get( - resource_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) - assert_matches_type(ResourceGetResponse, resource, path=["response"]) - - @parametrize - def test_method_get_with_all_params(self, client: Cloudflare) -> None: - resource = client.magic_cloud_networking.resources.get( - resource_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - v2=True, - ) - assert_matches_type(ResourceGetResponse, resource, path=["response"]) - - @parametrize - def test_raw_response_get(self, client: Cloudflare) -> None: - response = client.magic_cloud_networking.resources.with_raw_response.get( - resource_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - resource = response.parse() - assert_matches_type(ResourceGetResponse, resource, path=["response"]) - - @parametrize - def test_streaming_response_get(self, client: Cloudflare) -> None: - with client.magic_cloud_networking.resources.with_streaming_response.get( - resource_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - resource = response.parse() - assert_matches_type(ResourceGetResponse, resource, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @parametrize - def test_path_params_get(self, client: Cloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): - client.magic_cloud_networking.resources.with_raw_response.get( - resource_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="", - ) - - with pytest.raises(ValueError, match=r"Expected a non-empty value for `resource_id` but received ''"): - client.magic_cloud_networking.resources.with_raw_response.get( - resource_id="", - account_id="account_id", - ) - - @parametrize - def test_method_policy_preview(self, client: Cloudflare) -> None: - resource = client.magic_cloud_networking.resources.policy_preview( - account_id="account_id", - policy="policy", - ) - assert_matches_type(str, resource, path=["response"]) - - @parametrize - def test_raw_response_policy_preview(self, client: Cloudflare) -> None: - response = client.magic_cloud_networking.resources.with_raw_response.policy_preview( - account_id="account_id", - policy="policy", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - resource = response.parse() - assert_matches_type(str, resource, path=["response"]) - - @parametrize - def test_streaming_response_policy_preview(self, client: Cloudflare) -> None: - with client.magic_cloud_networking.resources.with_streaming_response.policy_preview( - account_id="account_id", - policy="policy", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - resource = response.parse() - assert_matches_type(str, resource, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @parametrize - def test_path_params_policy_preview(self, client: Cloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): - client.magic_cloud_networking.resources.with_raw_response.policy_preview( - account_id="", - policy="policy", - ) - - -class TestAsyncResources: - parametrize = pytest.mark.parametrize( - "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] - ) - - @parametrize - async def test_method_list(self, async_client: AsyncCloudflare) -> None: - resource = await async_client.magic_cloud_networking.resources.list( - account_id="account_id", - ) - assert_matches_type(AsyncV4PagePaginationArray[ResourceListResponse], resource, path=["response"]) - - @parametrize - async def test_method_list_with_all_params(self, async_client: AsyncCloudflare) -> None: - resource = await async_client.magic_cloud_networking.resources.list( - account_id="account_id", - cloudflare=True, - desc=True, - managed=True, - order_by="order_by", - page=1, - per_page=1, - provider_id="provider_id", - region="region", - resource_group="resource_group", - resource_id=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], - resource_type=["aws_customer_gateway"], - search=["string"], - v2=True, - ) - assert_matches_type(AsyncV4PagePaginationArray[ResourceListResponse], resource, path=["response"]) - - @parametrize - async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None: - response = await async_client.magic_cloud_networking.resources.with_raw_response.list( - account_id="account_id", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - resource = await response.parse() - assert_matches_type(AsyncV4PagePaginationArray[ResourceListResponse], resource, path=["response"]) - - @parametrize - async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> None: - async with async_client.magic_cloud_networking.resources.with_streaming_response.list( - account_id="account_id", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - resource = await response.parse() - assert_matches_type(AsyncV4PagePaginationArray[ResourceListResponse], resource, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @parametrize - async def test_path_params_list(self, async_client: AsyncCloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): - await async_client.magic_cloud_networking.resources.with_raw_response.list( - account_id="", - ) - - @parametrize - @pytest.mark.respx(base_url=base_url) - async def test_method_export(self, async_client: AsyncCloudflare, respx_mock: MockRouter) -> None: - respx_mock.get("/accounts/account_id/magic/cloud/resources/export").mock( - return_value=httpx.Response(200, json={"foo": "bar"}) - ) - resource = await async_client.magic_cloud_networking.resources.export( - account_id="account_id", - ) - assert resource.is_closed - assert await resource.json() == {"foo": "bar"} - assert cast(Any, resource.is_closed) is True - assert isinstance(resource, AsyncBinaryAPIResponse) - - @parametrize - @pytest.mark.respx(base_url=base_url) - async def test_method_export_with_all_params(self, async_client: AsyncCloudflare, respx_mock: MockRouter) -> None: - respx_mock.get("/accounts/account_id/magic/cloud/resources/export").mock( - return_value=httpx.Response(200, json={"foo": "bar"}) - ) - resource = await async_client.magic_cloud_networking.resources.export( - account_id="account_id", - desc=True, - order_by="order_by", - provider_id="provider_id", - region="region", - resource_group="resource_group", - resource_id=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], - resource_type=["aws_customer_gateway"], - search=["string"], - v2=True, - ) - assert resource.is_closed - assert await resource.json() == {"foo": "bar"} - assert cast(Any, resource.is_closed) is True - assert isinstance(resource, AsyncBinaryAPIResponse) - - @parametrize - @pytest.mark.respx(base_url=base_url) - async def test_raw_response_export(self, async_client: AsyncCloudflare, respx_mock: MockRouter) -> None: - respx_mock.get("/accounts/account_id/magic/cloud/resources/export").mock( - return_value=httpx.Response(200, json={"foo": "bar"}) - ) - - resource = await async_client.magic_cloud_networking.resources.with_raw_response.export( - account_id="account_id", - ) - - assert resource.is_closed is True - assert resource.http_request.headers.get("X-Stainless-Lang") == "python" - assert await resource.json() == {"foo": "bar"} - assert isinstance(resource, AsyncBinaryAPIResponse) - - @parametrize - @pytest.mark.respx(base_url=base_url) - async def test_streaming_response_export(self, async_client: AsyncCloudflare, respx_mock: MockRouter) -> None: - respx_mock.get("/accounts/account_id/magic/cloud/resources/export").mock( - return_value=httpx.Response(200, json={"foo": "bar"}) - ) - async with async_client.magic_cloud_networking.resources.with_streaming_response.export( - account_id="account_id", - ) as resource: - assert not resource.is_closed - assert resource.http_request.headers.get("X-Stainless-Lang") == "python" - - assert await resource.json() == {"foo": "bar"} - assert cast(Any, resource.is_closed) is True - assert isinstance(resource, AsyncStreamedBinaryAPIResponse) - - assert cast(Any, resource.is_closed) is True - - @parametrize - @pytest.mark.respx(base_url=base_url) - async def test_path_params_export(self, async_client: AsyncCloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): - await async_client.magic_cloud_networking.resources.with_raw_response.export( - account_id="", - ) - - @parametrize - async def test_method_get(self, async_client: AsyncCloudflare) -> None: - resource = await async_client.magic_cloud_networking.resources.get( - resource_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) - assert_matches_type(ResourceGetResponse, resource, path=["response"]) - - @parametrize - async def test_method_get_with_all_params(self, async_client: AsyncCloudflare) -> None: - resource = await async_client.magic_cloud_networking.resources.get( - resource_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - v2=True, - ) - assert_matches_type(ResourceGetResponse, resource, path=["response"]) - - @parametrize - async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None: - response = await async_client.magic_cloud_networking.resources.with_raw_response.get( - resource_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - resource = await response.parse() - assert_matches_type(ResourceGetResponse, resource, path=["response"]) - - @parametrize - async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> None: - async with async_client.magic_cloud_networking.resources.with_streaming_response.get( - resource_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="account_id", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - resource = await response.parse() - assert_matches_type(ResourceGetResponse, resource, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @parametrize - async def test_path_params_get(self, async_client: AsyncCloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): - await async_client.magic_cloud_networking.resources.with_raw_response.get( - resource_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_id="", - ) - - with pytest.raises(ValueError, match=r"Expected a non-empty value for `resource_id` but received ''"): - await async_client.magic_cloud_networking.resources.with_raw_response.get( - resource_id="", - account_id="account_id", - ) - - @parametrize - async def test_method_policy_preview(self, async_client: AsyncCloudflare) -> None: - resource = await async_client.magic_cloud_networking.resources.policy_preview( - account_id="account_id", - policy="policy", - ) - assert_matches_type(str, resource, path=["response"]) - - @parametrize - async def test_raw_response_policy_preview(self, async_client: AsyncCloudflare) -> None: - response = await async_client.magic_cloud_networking.resources.with_raw_response.policy_preview( - account_id="account_id", - policy="policy", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - resource = await response.parse() - assert_matches_type(str, resource, path=["response"]) - - @parametrize - async def test_streaming_response_policy_preview(self, async_client: AsyncCloudflare) -> None: - async with async_client.magic_cloud_networking.resources.with_streaming_response.policy_preview( - account_id="account_id", - policy="policy", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - resource = await response.parse() - assert_matches_type(str, resource, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @parametrize - async def test_path_params_policy_preview(self, async_client: AsyncCloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): - await async_client.magic_cloud_networking.resources.with_raw_response.policy_preview( - account_id="", - policy="policy", - ) diff --git a/tests/api_resources/magic_network_monitoring/rules/test_advertisements.py b/tests/api_resources/magic_network_monitoring/rules/test_advertisements.py index c9415da5b36..31f3a7bfbae 100644 --- a/tests/api_resources/magic_network_monitoring/rules/test_advertisements.py +++ b/tests/api_resources/magic_network_monitoring/rules/test_advertisements.py @@ -22,7 +22,6 @@ def test_method_edit(self, client: Cloudflare) -> None: advertisement = client.magic_network_monitoring.rules.advertisements.edit( rule_id="2890e6fa406311ed9b5a23f70f6fb8cf", account_id="6f91088a406011ed95aed352566e8d4c", - body={}, ) assert_matches_type(Optional[Advertisement], advertisement, path=["response"]) @@ -31,7 +30,6 @@ def test_raw_response_edit(self, client: Cloudflare) -> None: response = client.magic_network_monitoring.rules.advertisements.with_raw_response.edit( rule_id="2890e6fa406311ed9b5a23f70f6fb8cf", account_id="6f91088a406011ed95aed352566e8d4c", - body={}, ) assert response.is_closed is True @@ -44,7 +42,6 @@ def test_streaming_response_edit(self, client: Cloudflare) -> None: with client.magic_network_monitoring.rules.advertisements.with_streaming_response.edit( rule_id="2890e6fa406311ed9b5a23f70f6fb8cf", account_id="6f91088a406011ed95aed352566e8d4c", - body={}, ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -60,14 +57,12 @@ def test_path_params_edit(self, client: Cloudflare) -> None: client.magic_network_monitoring.rules.advertisements.with_raw_response.edit( rule_id="2890e6fa406311ed9b5a23f70f6fb8cf", account_id="", - body={}, ) with pytest.raises(ValueError, match=r"Expected a non-empty value for `rule_id` but received ''"): client.magic_network_monitoring.rules.advertisements.with_raw_response.edit( rule_id="", account_id="6f91088a406011ed95aed352566e8d4c", - body={}, ) @@ -81,7 +76,6 @@ async def test_method_edit(self, async_client: AsyncCloudflare) -> None: advertisement = await async_client.magic_network_monitoring.rules.advertisements.edit( rule_id="2890e6fa406311ed9b5a23f70f6fb8cf", account_id="6f91088a406011ed95aed352566e8d4c", - body={}, ) assert_matches_type(Optional[Advertisement], advertisement, path=["response"]) @@ -90,7 +84,6 @@ async def test_raw_response_edit(self, async_client: AsyncCloudflare) -> None: response = await async_client.magic_network_monitoring.rules.advertisements.with_raw_response.edit( rule_id="2890e6fa406311ed9b5a23f70f6fb8cf", account_id="6f91088a406011ed95aed352566e8d4c", - body={}, ) assert response.is_closed is True @@ -103,7 +96,6 @@ async def test_streaming_response_edit(self, async_client: AsyncCloudflare) -> N async with async_client.magic_network_monitoring.rules.advertisements.with_streaming_response.edit( rule_id="2890e6fa406311ed9b5a23f70f6fb8cf", account_id="6f91088a406011ed95aed352566e8d4c", - body={}, ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -119,12 +111,10 @@ async def test_path_params_edit(self, async_client: AsyncCloudflare) -> None: await async_client.magic_network_monitoring.rules.advertisements.with_raw_response.edit( rule_id="2890e6fa406311ed9b5a23f70f6fb8cf", account_id="", - body={}, ) with pytest.raises(ValueError, match=r"Expected a non-empty value for `rule_id` but received ''"): await async_client.magic_network_monitoring.rules.advertisements.with_raw_response.edit( rule_id="", account_id="6f91088a406011ed95aed352566e8d4c", - body={}, ) diff --git a/tests/api_resources/magic_transit/sites/test_lans.py b/tests/api_resources/magic_transit/sites/test_lans.py index c76d6e34030..598b39502e3 100644 --- a/tests/api_resources/magic_transit/sites/test_lans.py +++ b/tests/api_resources/magic_transit/sites/test_lans.py @@ -40,6 +40,12 @@ def test_method_create_with_all_params(self, client: Cloudflare) -> None: name="name", nat={"static_prefix": "192.0.2.0/24"}, physport=1, + remote_subnets=[ + { + "local_alias_prefix": "192.0.2.0/24", + "remote_prefix": "192.0.2.0/24", + } + ], routed_subnets=[ { "next_hop": "192.0.2.1", @@ -136,6 +142,12 @@ def test_method_update_with_all_params(self, client: Cloudflare) -> None: name="name", nat={"static_prefix": "192.0.2.0/24"}, physport=1, + remote_subnets=[ + { + "local_alias_prefix": "192.0.2.0/24", + "remote_prefix": "192.0.2.0/24", + } + ], routed_subnets=[ { "next_hop": "192.0.2.1", @@ -351,6 +363,12 @@ def test_method_edit_with_all_params(self, client: Cloudflare) -> None: name="name", nat={"static_prefix": "192.0.2.0/24"}, physport=1, + remote_subnets=[ + { + "local_alias_prefix": "192.0.2.0/24", + "remote_prefix": "192.0.2.0/24", + } + ], routed_subnets=[ { "next_hop": "192.0.2.1", @@ -522,6 +540,12 @@ async def test_method_create_with_all_params(self, async_client: AsyncCloudflare name="name", nat={"static_prefix": "192.0.2.0/24"}, physport=1, + remote_subnets=[ + { + "local_alias_prefix": "192.0.2.0/24", + "remote_prefix": "192.0.2.0/24", + } + ], routed_subnets=[ { "next_hop": "192.0.2.1", @@ -618,6 +642,12 @@ async def test_method_update_with_all_params(self, async_client: AsyncCloudflare name="name", nat={"static_prefix": "192.0.2.0/24"}, physport=1, + remote_subnets=[ + { + "local_alias_prefix": "192.0.2.0/24", + "remote_prefix": "192.0.2.0/24", + } + ], routed_subnets=[ { "next_hop": "192.0.2.1", @@ -833,6 +863,12 @@ async def test_method_edit_with_all_params(self, async_client: AsyncCloudflare) name="name", nat={"static_prefix": "192.0.2.0/24"}, physport=1, + remote_subnets=[ + { + "local_alias_prefix": "192.0.2.0/24", + "remote_prefix": "192.0.2.0/24", + } + ], routed_subnets=[ { "next_hop": "192.0.2.1", diff --git a/tests/api_resources/magic_transit/sites/test_wans.py b/tests/api_resources/magic_transit/sites/test_wans.py index 894f95491bc..87b16d37479 100644 --- a/tests/api_resources/magic_transit/sites/test_wans.py +++ b/tests/api_resources/magic_transit/sites/test_wans.py @@ -10,9 +10,7 @@ from cloudflare import Cloudflare, AsyncCloudflare from tests.utils import assert_matches_type from cloudflare.pagination import SyncSinglePage, AsyncSinglePage -from cloudflare.types.magic_transit.sites import ( - WAN, -) +from cloudflare.types.magic_transit.sites import WAN base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") @@ -39,10 +37,13 @@ def test_method_create_with_all_params(self, client: Cloudflare) -> None: load_balance_inner_flows=True, name="name", priority=0, + provisioned_download_kbps=500, + provisioned_upload_kbps=100, static_addressing={ "address": "192.0.2.0/24", "gateway_address": "192.0.2.1", "secondary_address": "192.0.2.0/24", + "secondary_gateway_address": "192.0.2.1", }, vlan_tag=42, ) @@ -112,10 +113,13 @@ def test_method_update_with_all_params(self, client: Cloudflare) -> None: name="name", physport=1, priority=0, + provisioned_download_kbps=500, + provisioned_upload_kbps=100, static_addressing={ "address": "192.0.2.0/24", "gateway_address": "192.0.2.1", "secondary_address": "192.0.2.0/24", + "secondary_gateway_address": "192.0.2.1", }, vlan_tag=42, ) @@ -300,10 +304,13 @@ def test_method_edit_with_all_params(self, client: Cloudflare) -> None: name="name", physport=1, priority=0, + provisioned_download_kbps=500, + provisioned_upload_kbps=100, static_addressing={ "address": "192.0.2.0/24", "gateway_address": "192.0.2.1", "secondary_address": "192.0.2.0/24", + "secondary_gateway_address": "192.0.2.1", }, vlan_tag=42, ) @@ -445,10 +452,13 @@ async def test_method_create_with_all_params(self, async_client: AsyncCloudflare load_balance_inner_flows=True, name="name", priority=0, + provisioned_download_kbps=500, + provisioned_upload_kbps=100, static_addressing={ "address": "192.0.2.0/24", "gateway_address": "192.0.2.1", "secondary_address": "192.0.2.0/24", + "secondary_gateway_address": "192.0.2.1", }, vlan_tag=42, ) @@ -518,10 +528,13 @@ async def test_method_update_with_all_params(self, async_client: AsyncCloudflare name="name", physport=1, priority=0, + provisioned_download_kbps=500, + provisioned_upload_kbps=100, static_addressing={ "address": "192.0.2.0/24", "gateway_address": "192.0.2.1", "secondary_address": "192.0.2.0/24", + "secondary_gateway_address": "192.0.2.1", }, vlan_tag=42, ) @@ -706,10 +719,13 @@ async def test_method_edit_with_all_params(self, async_client: AsyncCloudflare) name="name", physport=1, priority=0, + provisioned_download_kbps=500, + provisioned_upload_kbps=100, static_addressing={ "address": "192.0.2.0/24", "gateway_address": "192.0.2.1", "secondary_address": "192.0.2.0/24", + "secondary_gateway_address": "192.0.2.1", }, vlan_tag=42, ) diff --git a/tests/api_resources/managed_defense/vulnerability_discovery/test_scans.py b/tests/api_resources/managed_defense/vulnerability_discovery/test_scans.py index d6b078d09f7..de6b81845a0 100644 --- a/tests/api_resources/managed_defense/vulnerability_discovery/test_scans.py +++ b/tests/api_resources/managed_defense/vulnerability_discovery/test_scans.py @@ -28,7 +28,7 @@ class TestScans: def test_method_create(self, client: Cloudflare) -> None: scan = client.managed_defense.vulnerability_discovery.scans.create( account_id="023e105f4ecef8ad9ca31a8372d0c353", - repos=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], + repos=[{"name": "x"}], ) assert_matches_type(ScanCreateResponse, scan, path=["response"]) @@ -36,8 +36,13 @@ def test_method_create(self, client: Cloudflare) -> None: def test_method_create_with_all_params(self, client: Cloudflare) -> None: scan = client.managed_defense.vulnerability_discovery.scans.create( account_id="023e105f4ecef8ad9ca31a8372d0c353", - repos=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], - repo_hosts={"foo": ["x"]}, + repos=[ + { + "name": "x", + "branch": "x", + "hosts": ["x"], + } + ], telemetry_window={ "end": parse_datetime("2019-12-27T18:11:19.117Z"), "start": parse_datetime("2019-12-27T18:11:19.117Z"), @@ -50,7 +55,7 @@ def test_method_create_with_all_params(self, client: Cloudflare) -> None: def test_raw_response_create(self, client: Cloudflare) -> None: response = client.managed_defense.vulnerability_discovery.scans.with_raw_response.create( account_id="023e105f4ecef8ad9ca31a8372d0c353", - repos=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], + repos=[{"name": "x"}], ) assert response.is_closed is True @@ -62,7 +67,7 @@ def test_raw_response_create(self, client: Cloudflare) -> None: def test_streaming_response_create(self, client: Cloudflare) -> None: with client.managed_defense.vulnerability_discovery.scans.with_streaming_response.create( account_id="023e105f4ecef8ad9ca31a8372d0c353", - repos=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], + repos=[{"name": "x"}], ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -77,7 +82,7 @@ def test_path_params_create(self, client: Cloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): client.managed_defense.vulnerability_discovery.scans.with_raw_response.create( account_id="", - repos=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], + repos=[{"name": "x"}], ) @parametrize @@ -235,7 +240,7 @@ class TestAsyncScans: async def test_method_create(self, async_client: AsyncCloudflare) -> None: scan = await async_client.managed_defense.vulnerability_discovery.scans.create( account_id="023e105f4ecef8ad9ca31a8372d0c353", - repos=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], + repos=[{"name": "x"}], ) assert_matches_type(ScanCreateResponse, scan, path=["response"]) @@ -243,8 +248,13 @@ async def test_method_create(self, async_client: AsyncCloudflare) -> None: async def test_method_create_with_all_params(self, async_client: AsyncCloudflare) -> None: scan = await async_client.managed_defense.vulnerability_discovery.scans.create( account_id="023e105f4ecef8ad9ca31a8372d0c353", - repos=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], - repo_hosts={"foo": ["x"]}, + repos=[ + { + "name": "x", + "branch": "x", + "hosts": ["x"], + } + ], telemetry_window={ "end": parse_datetime("2019-12-27T18:11:19.117Z"), "start": parse_datetime("2019-12-27T18:11:19.117Z"), @@ -257,7 +267,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncCloudflare async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None: response = await async_client.managed_defense.vulnerability_discovery.scans.with_raw_response.create( account_id="023e105f4ecef8ad9ca31a8372d0c353", - repos=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], + repos=[{"name": "x"}], ) assert response.is_closed is True @@ -269,7 +279,7 @@ async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None: async def test_streaming_response_create(self, async_client: AsyncCloudflare) -> None: async with async_client.managed_defense.vulnerability_discovery.scans.with_streaming_response.create( account_id="023e105f4ecef8ad9ca31a8372d0c353", - repos=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], + repos=[{"name": "x"}], ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -284,7 +294,7 @@ async def test_path_params_create(self, async_client: AsyncCloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): await async_client.managed_defense.vulnerability_discovery.scans.with_raw_response.create( account_id="", - repos=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], + repos=[{"name": "x"}], ) @parametrize diff --git a/tests/api_resources/monetization/__init__.py b/tests/api_resources/monetization/__init__.py new file mode 100644 index 00000000000..fd8019a9a1a --- /dev/null +++ b/tests/api_resources/monetization/__init__.py @@ -0,0 +1 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. diff --git a/tests/api_resources/monetization/test_rules.py b/tests/api_resources/monetization/test_rules.py new file mode 100644 index 00000000000..cc3607cf46c --- /dev/null +++ b/tests/api_resources/monetization/test_rules.py @@ -0,0 +1,635 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import os +from typing import Any, cast + +import pytest + +from cloudflare import Cloudflare, AsyncCloudflare +from tests.utils import assert_matches_type +from cloudflare.types.monetization import ( + MonetizationRule, + MonetizationRuleCollection, +) + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestRules: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @parametrize + def test_method_update(self, client: Cloudflare) -> None: + rule = client.monetization.rules.update( + zone_id="9f1839b6152d298aca64c4e906b6d074", + rules=[ + { + "address": "0x1234567890abcdef1234567890abcdef12345678===", + "expression": '(http.request.uri.path eq "/premium" and http.request.method in {"GET" "POST"})', + "price": "250000", + "scheme": "exact", + } + ], + ) + assert_matches_type(MonetizationRuleCollection, rule, path=["response"]) + + @parametrize + def test_raw_response_update(self, client: Cloudflare) -> None: + response = client.monetization.rules.with_raw_response.update( + zone_id="9f1839b6152d298aca64c4e906b6d074", + rules=[ + { + "address": "0x1234567890abcdef1234567890abcdef12345678===", + "expression": '(http.request.uri.path eq "/premium" and http.request.method in {"GET" "POST"})', + "price": "250000", + "scheme": "exact", + } + ], + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + rule = response.parse() + assert_matches_type(MonetizationRuleCollection, rule, path=["response"]) + + @parametrize + def test_streaming_response_update(self, client: Cloudflare) -> None: + with client.monetization.rules.with_streaming_response.update( + zone_id="9f1839b6152d298aca64c4e906b6d074", + rules=[ + { + "address": "0x1234567890abcdef1234567890abcdef12345678===", + "expression": '(http.request.uri.path eq "/premium" and http.request.method in {"GET" "POST"})', + "price": "250000", + "scheme": "exact", + } + ], + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + rule = response.parse() + assert_matches_type(MonetizationRuleCollection, rule, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_update(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + client.monetization.rules.with_raw_response.update( + zone_id="", + rules=[ + { + "address": "0x1234567890abcdef1234567890abcdef12345678===", + "expression": '(http.request.uri.path eq "/premium" and http.request.method in {"GET" "POST"})', + "price": "250000", + "scheme": "exact", + } + ], + ) + + @parametrize + def test_method_delete(self, client: Cloudflare) -> None: + rule = client.monetization.rules.delete( + zone_id="9f1839b6152d298aca64c4e906b6d074", + ) + assert_matches_type(MonetizationRuleCollection, rule, path=["response"]) + + @parametrize + def test_raw_response_delete(self, client: Cloudflare) -> None: + response = client.monetization.rules.with_raw_response.delete( + zone_id="9f1839b6152d298aca64c4e906b6d074", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + rule = response.parse() + assert_matches_type(MonetizationRuleCollection, rule, path=["response"]) + + @parametrize + def test_streaming_response_delete(self, client: Cloudflare) -> None: + with client.monetization.rules.with_streaming_response.delete( + zone_id="9f1839b6152d298aca64c4e906b6d074", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + rule = response.parse() + assert_matches_type(MonetizationRuleCollection, rule, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_delete(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + client.monetization.rules.with_raw_response.delete( + zone_id="", + ) + + @parametrize + def test_method_delete_rule(self, client: Cloudflare) -> None: + rule = client.monetization.rules.delete_rule( + rule_id="023e105f4ecef8ad9ca31a8372d0c353", + zone_id="9f1839b6152d298aca64c4e906b6d074", + ) + assert_matches_type(MonetizationRuleCollection, rule, path=["response"]) + + @parametrize + def test_raw_response_delete_rule(self, client: Cloudflare) -> None: + response = client.monetization.rules.with_raw_response.delete_rule( + rule_id="023e105f4ecef8ad9ca31a8372d0c353", + zone_id="9f1839b6152d298aca64c4e906b6d074", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + rule = response.parse() + assert_matches_type(MonetizationRuleCollection, rule, path=["response"]) + + @parametrize + def test_streaming_response_delete_rule(self, client: Cloudflare) -> None: + with client.monetization.rules.with_streaming_response.delete_rule( + rule_id="023e105f4ecef8ad9ca31a8372d0c353", + zone_id="9f1839b6152d298aca64c4e906b6d074", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + rule = response.parse() + assert_matches_type(MonetizationRuleCollection, rule, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_delete_rule(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + client.monetization.rules.with_raw_response.delete_rule( + rule_id="023e105f4ecef8ad9ca31a8372d0c353", + zone_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `rule_id` but received ''"): + client.monetization.rules.with_raw_response.delete_rule( + rule_id="", + zone_id="9f1839b6152d298aca64c4e906b6d074", + ) + + @parametrize + def test_method_edit_rule(self, client: Cloudflare) -> None: + rule = client.monetization.rules.edit_rule( + rule_id="023e105f4ecef8ad9ca31a8372d0c353", + zone_id="9f1839b6152d298aca64c4e906b6d074", + ) + assert_matches_type(MonetizationRuleCollection, rule, path=["response"]) + + @parametrize + def test_method_edit_rule_with_all_params(self, client: Cloudflare) -> None: + rule = client.monetization.rules.edit_rule( + rule_id="023e105f4ecef8ad9ca31a8372d0c353", + zone_id="9f1839b6152d298aca64c4e906b6d074", + address="0x1234567890abcdef1234567890abcdef12345678===", + description="Premium API endpoint", + enabled=True, + expression='(http.request.uri.path eq "/premium" and http.request.method in {"GET" "POST"})', + price="250000", + scheme="exact", + ) + assert_matches_type(MonetizationRuleCollection, rule, path=["response"]) + + @parametrize + def test_raw_response_edit_rule(self, client: Cloudflare) -> None: + response = client.monetization.rules.with_raw_response.edit_rule( + rule_id="023e105f4ecef8ad9ca31a8372d0c353", + zone_id="9f1839b6152d298aca64c4e906b6d074", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + rule = response.parse() + assert_matches_type(MonetizationRuleCollection, rule, path=["response"]) + + @parametrize + def test_streaming_response_edit_rule(self, client: Cloudflare) -> None: + with client.monetization.rules.with_streaming_response.edit_rule( + rule_id="023e105f4ecef8ad9ca31a8372d0c353", + zone_id="9f1839b6152d298aca64c4e906b6d074", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + rule = response.parse() + assert_matches_type(MonetizationRuleCollection, rule, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_edit_rule(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + client.monetization.rules.with_raw_response.edit_rule( + rule_id="023e105f4ecef8ad9ca31a8372d0c353", + zone_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `rule_id` but received ''"): + client.monetization.rules.with_raw_response.edit_rule( + rule_id="", + zone_id="9f1839b6152d298aca64c4e906b6d074", + ) + + @parametrize + def test_method_get(self, client: Cloudflare) -> None: + rule = client.monetization.rules.get( + zone_id="9f1839b6152d298aca64c4e906b6d074", + ) + assert_matches_type(MonetizationRuleCollection, rule, path=["response"]) + + @parametrize + def test_raw_response_get(self, client: Cloudflare) -> None: + response = client.monetization.rules.with_raw_response.get( + zone_id="9f1839b6152d298aca64c4e906b6d074", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + rule = response.parse() + assert_matches_type(MonetizationRuleCollection, rule, path=["response"]) + + @parametrize + def test_streaming_response_get(self, client: Cloudflare) -> None: + with client.monetization.rules.with_streaming_response.get( + zone_id="9f1839b6152d298aca64c4e906b6d074", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + rule = response.parse() + assert_matches_type(MonetizationRuleCollection, rule, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_get(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + client.monetization.rules.with_raw_response.get( + zone_id="", + ) + + @parametrize + def test_method_get_rule(self, client: Cloudflare) -> None: + rule = client.monetization.rules.get_rule( + rule_id="023e105f4ecef8ad9ca31a8372d0c353", + zone_id="9f1839b6152d298aca64c4e906b6d074", + ) + assert_matches_type(MonetizationRule, rule, path=["response"]) + + @parametrize + def test_raw_response_get_rule(self, client: Cloudflare) -> None: + response = client.monetization.rules.with_raw_response.get_rule( + rule_id="023e105f4ecef8ad9ca31a8372d0c353", + zone_id="9f1839b6152d298aca64c4e906b6d074", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + rule = response.parse() + assert_matches_type(MonetizationRule, rule, path=["response"]) + + @parametrize + def test_streaming_response_get_rule(self, client: Cloudflare) -> None: + with client.monetization.rules.with_streaming_response.get_rule( + rule_id="023e105f4ecef8ad9ca31a8372d0c353", + zone_id="9f1839b6152d298aca64c4e906b6d074", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + rule = response.parse() + assert_matches_type(MonetizationRule, rule, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_get_rule(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + client.monetization.rules.with_raw_response.get_rule( + rule_id="023e105f4ecef8ad9ca31a8372d0c353", + zone_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `rule_id` but received ''"): + client.monetization.rules.with_raw_response.get_rule( + rule_id="", + zone_id="9f1839b6152d298aca64c4e906b6d074", + ) + + +class TestAsyncRules: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @parametrize + async def test_method_update(self, async_client: AsyncCloudflare) -> None: + rule = await async_client.monetization.rules.update( + zone_id="9f1839b6152d298aca64c4e906b6d074", + rules=[ + { + "address": "0x1234567890abcdef1234567890abcdef12345678===", + "expression": '(http.request.uri.path eq "/premium" and http.request.method in {"GET" "POST"})', + "price": "250000", + "scheme": "exact", + } + ], + ) + assert_matches_type(MonetizationRuleCollection, rule, path=["response"]) + + @parametrize + async def test_raw_response_update(self, async_client: AsyncCloudflare) -> None: + response = await async_client.monetization.rules.with_raw_response.update( + zone_id="9f1839b6152d298aca64c4e906b6d074", + rules=[ + { + "address": "0x1234567890abcdef1234567890abcdef12345678===", + "expression": '(http.request.uri.path eq "/premium" and http.request.method in {"GET" "POST"})', + "price": "250000", + "scheme": "exact", + } + ], + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + rule = await response.parse() + assert_matches_type(MonetizationRuleCollection, rule, path=["response"]) + + @parametrize + async def test_streaming_response_update(self, async_client: AsyncCloudflare) -> None: + async with async_client.monetization.rules.with_streaming_response.update( + zone_id="9f1839b6152d298aca64c4e906b6d074", + rules=[ + { + "address": "0x1234567890abcdef1234567890abcdef12345678===", + "expression": '(http.request.uri.path eq "/premium" and http.request.method in {"GET" "POST"})', + "price": "250000", + "scheme": "exact", + } + ], + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + rule = await response.parse() + assert_matches_type(MonetizationRuleCollection, rule, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_update(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + await async_client.monetization.rules.with_raw_response.update( + zone_id="", + rules=[ + { + "address": "0x1234567890abcdef1234567890abcdef12345678===", + "expression": '(http.request.uri.path eq "/premium" and http.request.method in {"GET" "POST"})', + "price": "250000", + "scheme": "exact", + } + ], + ) + + @parametrize + async def test_method_delete(self, async_client: AsyncCloudflare) -> None: + rule = await async_client.monetization.rules.delete( + zone_id="9f1839b6152d298aca64c4e906b6d074", + ) + assert_matches_type(MonetizationRuleCollection, rule, path=["response"]) + + @parametrize + async def test_raw_response_delete(self, async_client: AsyncCloudflare) -> None: + response = await async_client.monetization.rules.with_raw_response.delete( + zone_id="9f1839b6152d298aca64c4e906b6d074", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + rule = await response.parse() + assert_matches_type(MonetizationRuleCollection, rule, path=["response"]) + + @parametrize + async def test_streaming_response_delete(self, async_client: AsyncCloudflare) -> None: + async with async_client.monetization.rules.with_streaming_response.delete( + zone_id="9f1839b6152d298aca64c4e906b6d074", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + rule = await response.parse() + assert_matches_type(MonetizationRuleCollection, rule, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_delete(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + await async_client.monetization.rules.with_raw_response.delete( + zone_id="", + ) + + @parametrize + async def test_method_delete_rule(self, async_client: AsyncCloudflare) -> None: + rule = await async_client.monetization.rules.delete_rule( + rule_id="023e105f4ecef8ad9ca31a8372d0c353", + zone_id="9f1839b6152d298aca64c4e906b6d074", + ) + assert_matches_type(MonetizationRuleCollection, rule, path=["response"]) + + @parametrize + async def test_raw_response_delete_rule(self, async_client: AsyncCloudflare) -> None: + response = await async_client.monetization.rules.with_raw_response.delete_rule( + rule_id="023e105f4ecef8ad9ca31a8372d0c353", + zone_id="9f1839b6152d298aca64c4e906b6d074", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + rule = await response.parse() + assert_matches_type(MonetizationRuleCollection, rule, path=["response"]) + + @parametrize + async def test_streaming_response_delete_rule(self, async_client: AsyncCloudflare) -> None: + async with async_client.monetization.rules.with_streaming_response.delete_rule( + rule_id="023e105f4ecef8ad9ca31a8372d0c353", + zone_id="9f1839b6152d298aca64c4e906b6d074", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + rule = await response.parse() + assert_matches_type(MonetizationRuleCollection, rule, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_delete_rule(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + await async_client.monetization.rules.with_raw_response.delete_rule( + rule_id="023e105f4ecef8ad9ca31a8372d0c353", + zone_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `rule_id` but received ''"): + await async_client.monetization.rules.with_raw_response.delete_rule( + rule_id="", + zone_id="9f1839b6152d298aca64c4e906b6d074", + ) + + @parametrize + async def test_method_edit_rule(self, async_client: AsyncCloudflare) -> None: + rule = await async_client.monetization.rules.edit_rule( + rule_id="023e105f4ecef8ad9ca31a8372d0c353", + zone_id="9f1839b6152d298aca64c4e906b6d074", + ) + assert_matches_type(MonetizationRuleCollection, rule, path=["response"]) + + @parametrize + async def test_method_edit_rule_with_all_params(self, async_client: AsyncCloudflare) -> None: + rule = await async_client.monetization.rules.edit_rule( + rule_id="023e105f4ecef8ad9ca31a8372d0c353", + zone_id="9f1839b6152d298aca64c4e906b6d074", + address="0x1234567890abcdef1234567890abcdef12345678===", + description="Premium API endpoint", + enabled=True, + expression='(http.request.uri.path eq "/premium" and http.request.method in {"GET" "POST"})', + price="250000", + scheme="exact", + ) + assert_matches_type(MonetizationRuleCollection, rule, path=["response"]) + + @parametrize + async def test_raw_response_edit_rule(self, async_client: AsyncCloudflare) -> None: + response = await async_client.monetization.rules.with_raw_response.edit_rule( + rule_id="023e105f4ecef8ad9ca31a8372d0c353", + zone_id="9f1839b6152d298aca64c4e906b6d074", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + rule = await response.parse() + assert_matches_type(MonetizationRuleCollection, rule, path=["response"]) + + @parametrize + async def test_streaming_response_edit_rule(self, async_client: AsyncCloudflare) -> None: + async with async_client.monetization.rules.with_streaming_response.edit_rule( + rule_id="023e105f4ecef8ad9ca31a8372d0c353", + zone_id="9f1839b6152d298aca64c4e906b6d074", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + rule = await response.parse() + assert_matches_type(MonetizationRuleCollection, rule, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_edit_rule(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + await async_client.monetization.rules.with_raw_response.edit_rule( + rule_id="023e105f4ecef8ad9ca31a8372d0c353", + zone_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `rule_id` but received ''"): + await async_client.monetization.rules.with_raw_response.edit_rule( + rule_id="", + zone_id="9f1839b6152d298aca64c4e906b6d074", + ) + + @parametrize + async def test_method_get(self, async_client: AsyncCloudflare) -> None: + rule = await async_client.monetization.rules.get( + zone_id="9f1839b6152d298aca64c4e906b6d074", + ) + assert_matches_type(MonetizationRuleCollection, rule, path=["response"]) + + @parametrize + async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None: + response = await async_client.monetization.rules.with_raw_response.get( + zone_id="9f1839b6152d298aca64c4e906b6d074", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + rule = await response.parse() + assert_matches_type(MonetizationRuleCollection, rule, path=["response"]) + + @parametrize + async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> None: + async with async_client.monetization.rules.with_streaming_response.get( + zone_id="9f1839b6152d298aca64c4e906b6d074", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + rule = await response.parse() + assert_matches_type(MonetizationRuleCollection, rule, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_get(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + await async_client.monetization.rules.with_raw_response.get( + zone_id="", + ) + + @parametrize + async def test_method_get_rule(self, async_client: AsyncCloudflare) -> None: + rule = await async_client.monetization.rules.get_rule( + rule_id="023e105f4ecef8ad9ca31a8372d0c353", + zone_id="9f1839b6152d298aca64c4e906b6d074", + ) + assert_matches_type(MonetizationRule, rule, path=["response"]) + + @parametrize + async def test_raw_response_get_rule(self, async_client: AsyncCloudflare) -> None: + response = await async_client.monetization.rules.with_raw_response.get_rule( + rule_id="023e105f4ecef8ad9ca31a8372d0c353", + zone_id="9f1839b6152d298aca64c4e906b6d074", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + rule = await response.parse() + assert_matches_type(MonetizationRule, rule, path=["response"]) + + @parametrize + async def test_streaming_response_get_rule(self, async_client: AsyncCloudflare) -> None: + async with async_client.monetization.rules.with_streaming_response.get_rule( + rule_id="023e105f4ecef8ad9ca31a8372d0c353", + zone_id="9f1839b6152d298aca64c4e906b6d074", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + rule = await response.parse() + assert_matches_type(MonetizationRule, rule, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_get_rule(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + await async_client.monetization.rules.with_raw_response.get_rule( + rule_id="023e105f4ecef8ad9ca31a8372d0c353", + zone_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `rule_id` but received ''"): + await async_client.monetization.rules.with_raw_response.get_rule( + rule_id="", + zone_id="9f1839b6152d298aca64c4e906b6d074", + ) diff --git a/tests/api_resources/network_interconnects/test_cnis.py b/tests/api_resources/network_interconnects/test_cnis.py index d5e3853c2fc..2f18c74f95e 100644 --- a/tests/api_resources/network_interconnects/test_cnis.py +++ b/tests/api_resources/network_interconnects/test_cnis.py @@ -49,7 +49,7 @@ def test_method_create_with_all_params(self, client: Cloudflare) -> None: }, bgp={ "customer_asn": 0, - "extra_prefixes": ["string"], + "extra_prefixes": ["192.168.3.4/31"], "md5_key": "md5_key", }, ) @@ -142,7 +142,7 @@ def test_method_update_with_all_params(self, client: Cloudflare) -> None: p2p_ip="192.168.3.4/31", bgp={ "customer_asn": 0, - "extra_prefixes": ["string"], + "extra_prefixes": ["192.168.3.4/31"], "md5_key": "md5_key", }, bgp_mode="dynamic_route_exchange", @@ -407,7 +407,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncCloudflare }, bgp={ "customer_asn": 0, - "extra_prefixes": ["string"], + "extra_prefixes": ["192.168.3.4/31"], "md5_key": "md5_key", }, ) @@ -500,7 +500,7 @@ async def test_method_update_with_all_params(self, async_client: AsyncCloudflare p2p_ip="192.168.3.4/31", bgp={ "customer_asn": 0, - "extra_prefixes": ["string"], + "extra_prefixes": ["192.168.3.4/31"], "md5_key": "md5_key", }, bgp_mode="dynamic_route_exchange", diff --git a/tests/api_resources/organizations/test_organization_profile.py b/tests/api_resources/organizations/test_organization_profile.py index baec280f552..96ada822451 100644 --- a/tests/api_resources/organizations/test_organization_profile.py +++ b/tests/api_resources/organizations/test_organization_profile.py @@ -19,6 +19,13 @@ class TestOrganizationProfile: @parametrize def test_method_update(self, client: Cloudflare) -> None: + organization_profile = client.organizations.organization_profile.update( + organization_id="a7b9c3d2e8f4a1b5c6d0e9f2a3b7c4d8", + ) + assert organization_profile is None + + @parametrize + def test_method_update_with_all_params(self, client: Cloudflare) -> None: organization_profile = client.organizations.organization_profile.update( organization_id="a7b9c3d2e8f4a1b5c6d0e9f2a3b7c4d8", business_address="business_address", @@ -33,11 +40,6 @@ def test_method_update(self, client: Cloudflare) -> None: def test_raw_response_update(self, client: Cloudflare) -> None: response = client.organizations.organization_profile.with_raw_response.update( organization_id="a7b9c3d2e8f4a1b5c6d0e9f2a3b7c4d8", - business_address="business_address", - business_email="business_email", - business_name="business_name", - business_phone="business_phone", - external_metadata="external_metadata", ) assert response.is_closed is True @@ -49,11 +51,6 @@ def test_raw_response_update(self, client: Cloudflare) -> None: def test_streaming_response_update(self, client: Cloudflare) -> None: with client.organizations.organization_profile.with_streaming_response.update( organization_id="a7b9c3d2e8f4a1b5c6d0e9f2a3b7c4d8", - business_address="business_address", - business_email="business_email", - business_name="business_name", - business_phone="business_phone", - external_metadata="external_metadata", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -68,11 +65,6 @@ def test_path_params_update(self, client: Cloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `organization_id` but received ''"): client.organizations.organization_profile.with_raw_response.update( organization_id="", - business_address="business_address", - business_email="business_email", - business_name="business_name", - business_phone="business_phone", - external_metadata="external_metadata", ) @parametrize @@ -121,6 +113,13 @@ class TestAsyncOrganizationProfile: @parametrize async def test_method_update(self, async_client: AsyncCloudflare) -> None: + organization_profile = await async_client.organizations.organization_profile.update( + organization_id="a7b9c3d2e8f4a1b5c6d0e9f2a3b7c4d8", + ) + assert organization_profile is None + + @parametrize + async def test_method_update_with_all_params(self, async_client: AsyncCloudflare) -> None: organization_profile = await async_client.organizations.organization_profile.update( organization_id="a7b9c3d2e8f4a1b5c6d0e9f2a3b7c4d8", business_address="business_address", @@ -135,11 +134,6 @@ async def test_method_update(self, async_client: AsyncCloudflare) -> None: async def test_raw_response_update(self, async_client: AsyncCloudflare) -> None: response = await async_client.organizations.organization_profile.with_raw_response.update( organization_id="a7b9c3d2e8f4a1b5c6d0e9f2a3b7c4d8", - business_address="business_address", - business_email="business_email", - business_name="business_name", - business_phone="business_phone", - external_metadata="external_metadata", ) assert response.is_closed is True @@ -151,11 +145,6 @@ async def test_raw_response_update(self, async_client: AsyncCloudflare) -> None: async def test_streaming_response_update(self, async_client: AsyncCloudflare) -> None: async with async_client.organizations.organization_profile.with_streaming_response.update( organization_id="a7b9c3d2e8f4a1b5c6d0e9f2a3b7c4d8", - business_address="business_address", - business_email="business_email", - business_name="business_name", - business_phone="business_phone", - external_metadata="external_metadata", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -170,11 +159,6 @@ async def test_path_params_update(self, async_client: AsyncCloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `organization_id` but received ''"): await async_client.organizations.organization_profile.with_raw_response.update( organization_id="", - business_address="business_address", - business_email="business_email", - business_name="business_name", - business_phone="business_phone", - external_metadata="external_metadata", ) @parametrize diff --git a/tests/api_resources/pipelines/test_sinks.py b/tests/api_resources/pipelines/test_sinks.py index 9192f8ff605..03604f2d9bd 100644 --- a/tests/api_resources/pipelines/test_sinks.py +++ b/tests/api_resources/pipelines/test_sinks.py @@ -128,7 +128,9 @@ def test_method_list(self, client: Cloudflare) -> None: def test_method_list_with_all_params(self, client: Cloudflare) -> None: sink = client.pipelines.sinks.list( account_id="0123105f4ecef8ad9ca31a8372d0c353", + direction="asc", name="x", + order_by="name", page=0, per_page=0, pipeline_id="pipeline_id", @@ -374,7 +376,9 @@ async def test_method_list(self, async_client: AsyncCloudflare) -> None: async def test_method_list_with_all_params(self, async_client: AsyncCloudflare) -> None: sink = await async_client.pipelines.sinks.list( account_id="0123105f4ecef8ad9ca31a8372d0c353", + direction="asc", name="x", + order_by="name", page=0, per_page=0, pipeline_id="pipeline_id", diff --git a/tests/api_resources/pipelines/test_streams.py b/tests/api_resources/pipelines/test_streams.py index cc566782877..26c49635ef3 100644 --- a/tests/api_resources/pipelines/test_streams.py +++ b/tests/api_resources/pipelines/test_streams.py @@ -170,7 +170,9 @@ def test_method_list(self, client: Cloudflare) -> None: def test_method_list_with_all_params(self, client: Cloudflare) -> None: stream = client.pipelines.streams.list( account_id="0123105f4ecef8ad9ca31a8372d0c353", + direction="asc", name="x", + order_by="name", page=0, per_page=0, pipeline_id="043e105f4ecef8ad9ca31a8372d0c353", @@ -457,7 +459,9 @@ async def test_method_list(self, async_client: AsyncCloudflare) -> None: async def test_method_list_with_all_params(self, async_client: AsyncCloudflare) -> None: stream = await async_client.pipelines.streams.list( account_id="0123105f4ecef8ad9ca31a8372d0c353", + direction="asc", name="x", + order_by="name", page=0, per_page=0, pipeline_id="043e105f4ecef8ad9ca31a8372d0c353", diff --git a/tests/api_resources/r2/buckets/test_jobs.py b/tests/api_resources/r2/buckets/test_jobs.py new file mode 100644 index 00000000000..36cf5f7ba80 --- /dev/null +++ b/tests/api_resources/r2/buckets/test_jobs.py @@ -0,0 +1,562 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import os +from typing import Any, cast + +import pytest + +from cloudflare import Cloudflare, AsyncCloudflare +from tests.utils import assert_matches_type +from cloudflare.types.r2.buckets import ( + JobGetResponse, + JobListResponse, + JobCreateResponse, +) + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestJobs: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @parametrize + def test_method_create_overload_1(self, client: Cloudflare) -> None: + job = client.r2.buckets.jobs.create( + bucket_name="example-bucket", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + job_type="prefixDelete", + prefix="path/to/", + ) + assert_matches_type(JobCreateResponse, job, path=["response"]) + + @parametrize + def test_method_create_with_all_params_overload_1(self, client: Cloudflare) -> None: + job = client.r2.buckets.jobs.create( + bucket_name="example-bucket", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + job_type="prefixDelete", + prefix="path/to/", + cf_r2_data_catalog_check="cf-r2-data-catalog-check", + cf_r2_jurisdiction="default", + ) + assert_matches_type(JobCreateResponse, job, path=["response"]) + + @parametrize + def test_raw_response_create_overload_1(self, client: Cloudflare) -> None: + response = client.r2.buckets.jobs.with_raw_response.create( + bucket_name="example-bucket", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + job_type="prefixDelete", + prefix="path/to/", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + job = response.parse() + assert_matches_type(JobCreateResponse, job, path=["response"]) + + @parametrize + def test_streaming_response_create_overload_1(self, client: Cloudflare) -> None: + with client.r2.buckets.jobs.with_streaming_response.create( + bucket_name="example-bucket", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + job_type="prefixDelete", + prefix="path/to/", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + job = response.parse() + assert_matches_type(JobCreateResponse, job, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_create_overload_1(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.r2.buckets.jobs.with_raw_response.create( + bucket_name="example-bucket", + account_id="", + job_type="prefixDelete", + prefix="path/to/", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `bucket_name` but received ''"): + client.r2.buckets.jobs.with_raw_response.create( + bucket_name="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + job_type="prefixDelete", + prefix="path/to/", + ) + + @parametrize + def test_method_create_overload_2(self, client: Cloudflare) -> None: + job = client.r2.buckets.jobs.create( + bucket_name="example-bucket", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + job_type="storageClassMigration", + ) + assert_matches_type(JobCreateResponse, job, path=["response"]) + + @parametrize + def test_method_create_with_all_params_overload_2(self, client: Cloudflare) -> None: + job = client.r2.buckets.jobs.create( + bucket_name="example-bucket", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + job_type="storageClassMigration", + destination_storage_class="Standard", + source_storage_class="Standard", + cf_r2_data_catalog_check="cf-r2-data-catalog-check", + cf_r2_jurisdiction="default", + ) + assert_matches_type(JobCreateResponse, job, path=["response"]) + + @parametrize + def test_raw_response_create_overload_2(self, client: Cloudflare) -> None: + response = client.r2.buckets.jobs.with_raw_response.create( + bucket_name="example-bucket", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + job_type="storageClassMigration", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + job = response.parse() + assert_matches_type(JobCreateResponse, job, path=["response"]) + + @parametrize + def test_streaming_response_create_overload_2(self, client: Cloudflare) -> None: + with client.r2.buckets.jobs.with_streaming_response.create( + bucket_name="example-bucket", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + job_type="storageClassMigration", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + job = response.parse() + assert_matches_type(JobCreateResponse, job, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_create_overload_2(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.r2.buckets.jobs.with_raw_response.create( + bucket_name="example-bucket", + account_id="", + job_type="storageClassMigration", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `bucket_name` but received ''"): + client.r2.buckets.jobs.with_raw_response.create( + bucket_name="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + job_type="storageClassMigration", + ) + + @parametrize + def test_method_list(self, client: Cloudflare) -> None: + job = client.r2.buckets.jobs.list( + bucket_name="example-bucket", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + assert_matches_type(JobListResponse, job, path=["response"]) + + @parametrize + def test_method_list_with_all_params(self, client: Cloudflare) -> None: + job = client.r2.buckets.jobs.list( + bucket_name="example-bucket", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + continuation_token="continuationToken", + job_type="prefixDelete", + max_keys=0, + status="ENQUEUED", + cf_r2_jurisdiction="default", + ) + assert_matches_type(JobListResponse, job, path=["response"]) + + @parametrize + def test_raw_response_list(self, client: Cloudflare) -> None: + response = client.r2.buckets.jobs.with_raw_response.list( + bucket_name="example-bucket", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + job = response.parse() + assert_matches_type(JobListResponse, job, path=["response"]) + + @parametrize + def test_streaming_response_list(self, client: Cloudflare) -> None: + with client.r2.buckets.jobs.with_streaming_response.list( + bucket_name="example-bucket", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + job = response.parse() + assert_matches_type(JobListResponse, job, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_list(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.r2.buckets.jobs.with_raw_response.list( + bucket_name="example-bucket", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `bucket_name` but received ''"): + client.r2.buckets.jobs.with_raw_response.list( + bucket_name="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + @parametrize + def test_method_get(self, client: Cloudflare) -> None: + job = client.r2.buckets.jobs.get( + job_id="job_id", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + bucket_name="example-bucket", + ) + assert_matches_type(JobGetResponse, job, path=["response"]) + + @parametrize + def test_method_get_with_all_params(self, client: Cloudflare) -> None: + job = client.r2.buckets.jobs.get( + job_id="job_id", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + bucket_name="example-bucket", + cf_r2_jurisdiction="default", + ) + assert_matches_type(JobGetResponse, job, path=["response"]) + + @parametrize + def test_raw_response_get(self, client: Cloudflare) -> None: + response = client.r2.buckets.jobs.with_raw_response.get( + job_id="job_id", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + bucket_name="example-bucket", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + job = response.parse() + assert_matches_type(JobGetResponse, job, path=["response"]) + + @parametrize + def test_streaming_response_get(self, client: Cloudflare) -> None: + with client.r2.buckets.jobs.with_streaming_response.get( + job_id="job_id", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + bucket_name="example-bucket", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + job = response.parse() + assert_matches_type(JobGetResponse, job, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_get(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.r2.buckets.jobs.with_raw_response.get( + job_id="job_id", + account_id="", + bucket_name="example-bucket", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `bucket_name` but received ''"): + client.r2.buckets.jobs.with_raw_response.get( + job_id="job_id", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + bucket_name="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `job_id` but received ''"): + client.r2.buckets.jobs.with_raw_response.get( + job_id="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + bucket_name="example-bucket", + ) + + +class TestAsyncJobs: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @parametrize + async def test_method_create_overload_1(self, async_client: AsyncCloudflare) -> None: + job = await async_client.r2.buckets.jobs.create( + bucket_name="example-bucket", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + job_type="prefixDelete", + prefix="path/to/", + ) + assert_matches_type(JobCreateResponse, job, path=["response"]) + + @parametrize + async def test_method_create_with_all_params_overload_1(self, async_client: AsyncCloudflare) -> None: + job = await async_client.r2.buckets.jobs.create( + bucket_name="example-bucket", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + job_type="prefixDelete", + prefix="path/to/", + cf_r2_data_catalog_check="cf-r2-data-catalog-check", + cf_r2_jurisdiction="default", + ) + assert_matches_type(JobCreateResponse, job, path=["response"]) + + @parametrize + async def test_raw_response_create_overload_1(self, async_client: AsyncCloudflare) -> None: + response = await async_client.r2.buckets.jobs.with_raw_response.create( + bucket_name="example-bucket", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + job_type="prefixDelete", + prefix="path/to/", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + job = await response.parse() + assert_matches_type(JobCreateResponse, job, path=["response"]) + + @parametrize + async def test_streaming_response_create_overload_1(self, async_client: AsyncCloudflare) -> None: + async with async_client.r2.buckets.jobs.with_streaming_response.create( + bucket_name="example-bucket", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + job_type="prefixDelete", + prefix="path/to/", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + job = await response.parse() + assert_matches_type(JobCreateResponse, job, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_create_overload_1(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.r2.buckets.jobs.with_raw_response.create( + bucket_name="example-bucket", + account_id="", + job_type="prefixDelete", + prefix="path/to/", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `bucket_name` but received ''"): + await async_client.r2.buckets.jobs.with_raw_response.create( + bucket_name="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + job_type="prefixDelete", + prefix="path/to/", + ) + + @parametrize + async def test_method_create_overload_2(self, async_client: AsyncCloudflare) -> None: + job = await async_client.r2.buckets.jobs.create( + bucket_name="example-bucket", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + job_type="storageClassMigration", + ) + assert_matches_type(JobCreateResponse, job, path=["response"]) + + @parametrize + async def test_method_create_with_all_params_overload_2(self, async_client: AsyncCloudflare) -> None: + job = await async_client.r2.buckets.jobs.create( + bucket_name="example-bucket", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + job_type="storageClassMigration", + destination_storage_class="Standard", + source_storage_class="Standard", + cf_r2_data_catalog_check="cf-r2-data-catalog-check", + cf_r2_jurisdiction="default", + ) + assert_matches_type(JobCreateResponse, job, path=["response"]) + + @parametrize + async def test_raw_response_create_overload_2(self, async_client: AsyncCloudflare) -> None: + response = await async_client.r2.buckets.jobs.with_raw_response.create( + bucket_name="example-bucket", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + job_type="storageClassMigration", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + job = await response.parse() + assert_matches_type(JobCreateResponse, job, path=["response"]) + + @parametrize + async def test_streaming_response_create_overload_2(self, async_client: AsyncCloudflare) -> None: + async with async_client.r2.buckets.jobs.with_streaming_response.create( + bucket_name="example-bucket", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + job_type="storageClassMigration", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + job = await response.parse() + assert_matches_type(JobCreateResponse, job, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_create_overload_2(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.r2.buckets.jobs.with_raw_response.create( + bucket_name="example-bucket", + account_id="", + job_type="storageClassMigration", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `bucket_name` but received ''"): + await async_client.r2.buckets.jobs.with_raw_response.create( + bucket_name="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + job_type="storageClassMigration", + ) + + @parametrize + async def test_method_list(self, async_client: AsyncCloudflare) -> None: + job = await async_client.r2.buckets.jobs.list( + bucket_name="example-bucket", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + assert_matches_type(JobListResponse, job, path=["response"]) + + @parametrize + async def test_method_list_with_all_params(self, async_client: AsyncCloudflare) -> None: + job = await async_client.r2.buckets.jobs.list( + bucket_name="example-bucket", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + continuation_token="continuationToken", + job_type="prefixDelete", + max_keys=0, + status="ENQUEUED", + cf_r2_jurisdiction="default", + ) + assert_matches_type(JobListResponse, job, path=["response"]) + + @parametrize + async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None: + response = await async_client.r2.buckets.jobs.with_raw_response.list( + bucket_name="example-bucket", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + job = await response.parse() + assert_matches_type(JobListResponse, job, path=["response"]) + + @parametrize + async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> None: + async with async_client.r2.buckets.jobs.with_streaming_response.list( + bucket_name="example-bucket", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + job = await response.parse() + assert_matches_type(JobListResponse, job, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_list(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.r2.buckets.jobs.with_raw_response.list( + bucket_name="example-bucket", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `bucket_name` but received ''"): + await async_client.r2.buckets.jobs.with_raw_response.list( + bucket_name="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + @parametrize + async def test_method_get(self, async_client: AsyncCloudflare) -> None: + job = await async_client.r2.buckets.jobs.get( + job_id="job_id", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + bucket_name="example-bucket", + ) + assert_matches_type(JobGetResponse, job, path=["response"]) + + @parametrize + async def test_method_get_with_all_params(self, async_client: AsyncCloudflare) -> None: + job = await async_client.r2.buckets.jobs.get( + job_id="job_id", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + bucket_name="example-bucket", + cf_r2_jurisdiction="default", + ) + assert_matches_type(JobGetResponse, job, path=["response"]) + + @parametrize + async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None: + response = await async_client.r2.buckets.jobs.with_raw_response.get( + job_id="job_id", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + bucket_name="example-bucket", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + job = await response.parse() + assert_matches_type(JobGetResponse, job, path=["response"]) + + @parametrize + async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> None: + async with async_client.r2.buckets.jobs.with_streaming_response.get( + job_id="job_id", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + bucket_name="example-bucket", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + job = await response.parse() + assert_matches_type(JobGetResponse, job, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_get(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.r2.buckets.jobs.with_raw_response.get( + job_id="job_id", + account_id="", + bucket_name="example-bucket", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `bucket_name` but received ''"): + await async_client.r2.buckets.jobs.with_raw_response.get( + job_id="job_id", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + bucket_name="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `job_id` but received ''"): + await async_client.r2.buckets.jobs.with_raw_response.get( + job_id="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + bucket_name="example-bucket", + ) diff --git a/tests/api_resources/radar/robots_txt/top/test_user_agents.py b/tests/api_resources/radar/robots_txt/top/test_user_agents.py index 9d9eea9a1e6..a7724af1bda 100644 --- a/tests/api_resources/radar/robots_txt/top/test_user_agents.py +++ b/tests/api_resources/radar/robots_txt/top/test_user_agents.py @@ -28,7 +28,7 @@ def test_method_directive_with_all_params(self, client: Cloudflare) -> None: user_agent = client.radar.robots_txt.top.user_agents.directive( date=[parse_date("2019-12-27")], directive="ALLOW", - domain_category=["string"], + domain_category=["News & Media"], format="JSON", limit=1, name=["main_series"], @@ -72,7 +72,7 @@ async def test_method_directive_with_all_params(self, async_client: AsyncCloudfl user_agent = await async_client.radar.robots_txt.top.user_agents.directive( date=[parse_date("2019-12-27")], directive="ALLOW", - domain_category=["string"], + domain_category=["News & Media"], format="JSON", limit=1, name=["main_series"], diff --git a/tests/api_resources/radar/test_agent_readiness.py b/tests/api_resources/radar/test_agent_readiness.py index d8ebdee6540..7aede73c968 100644 --- a/tests/api_resources/radar/test_agent_readiness.py +++ b/tests/api_resources/radar/test_agent_readiness.py @@ -30,7 +30,7 @@ def test_method_summary_with_all_params(self, client: Cloudflare) -> None: agent_readiness = client.radar.agent_readiness.summary( dimension="CHECK", date=parse_date("2024-09-19"), - domain_category=["string"], + domain_category=["News & Media"], format="JSON", name=["main_series"], ) @@ -78,7 +78,7 @@ async def test_method_summary_with_all_params(self, async_client: AsyncCloudflar agent_readiness = await async_client.radar.agent_readiness.summary( dimension="CHECK", date=parse_date("2024-09-19"), - domain_category=["string"], + domain_category=["News & Media"], format="JSON", name=["main_series"], ) diff --git a/tests/api_resources/radar/test_ranking.py b/tests/api_resources/radar/test_ranking.py index a0db34fccf4..d16eb1250cd 100644 --- a/tests/api_resources/radar/test_ranking.py +++ b/tests/api_resources/radar/test_ranking.py @@ -32,7 +32,7 @@ def test_method_timeseries_groups_with_all_params(self, client: Cloudflare) -> N date_end=[parse_datetime("2019-12-27T18:11:19.117Z")], date_range=["7d"], date_start=[parse_datetime("2019-12-27T18:11:19.117Z")], - domain_category=["string"], + domain_category=["News & Media"], domains=["google.com"], format="JSON", limit=1, @@ -71,7 +71,7 @@ def test_method_top(self, client: Cloudflare) -> None: def test_method_top_with_all_params(self, client: Cloudflare) -> None: ranking = client.radar.ranking.top( date=[parse_date("2019-12-27")], - domain_category=["string"], + domain_category=["News & Media"], format="JSON", limit=5, location=["string"], @@ -117,7 +117,7 @@ async def test_method_timeseries_groups_with_all_params(self, async_client: Asyn date_end=[parse_datetime("2019-12-27T18:11:19.117Z")], date_range=["7d"], date_start=[parse_datetime("2019-12-27T18:11:19.117Z")], - domain_category=["string"], + domain_category=["News & Media"], domains=["google.com"], format="JSON", limit=1, @@ -156,7 +156,7 @@ async def test_method_top(self, async_client: AsyncCloudflare) -> None: async def test_method_top_with_all_params(self, async_client: AsyncCloudflare) -> None: ranking = await async_client.radar.ranking.top( date=[parse_date("2019-12-27")], - domain_category=["string"], + domain_category=["News & Media"], format="JSON", limit=5, location=["string"], diff --git a/tests/api_resources/realtime_kit/test_meetings.py b/tests/api_resources/realtime_kit/test_meetings.py index ae2c6ce71e1..9d3ccd6b2c1 100644 --- a/tests/api_resources/realtime_kit/test_meetings.py +++ b/tests/api_resources/realtime_kit/test_meetings.py @@ -170,6 +170,10 @@ def test_method_add_participant_with_all_params(self, client: Cloudflare) -> Non app_id="14a396e7-ca44-4937-bf1f-050a69118543", custom_participant_id="custom_participant_id", preset_name="preset_name", + token={ + "expires_on": parse_datetime("2026-10-01T11:00:00Z"), + "not_before": parse_datetime("2026-10-01T09:00:00Z"), + }, name="Mary Sue", picture="https://i.imgur.com/test.jpg", ) @@ -716,6 +720,19 @@ def test_method_refresh_participant_token(self, client: Cloudflare) -> None: ) assert_matches_type(MeetingRefreshParticipantTokenResponse, meeting, path=["response"]) + @pytest.mark.skip(reason="TODO: auth not handled well") + @parametrize + def test_method_refresh_participant_token_with_all_params(self, client: Cloudflare) -> None: + meeting = client.realtime_kit.meetings.refresh_participant_token( + participant_id="participant_id", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + app_id="14a396e7-ca44-4937-bf1f-050a69118543", + meeting_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + expires_on=parse_datetime("2026-10-01T11:00:00Z"), + not_before=parse_datetime("2026-10-01T09:00:00Z"), + ) + assert_matches_type(MeetingRefreshParticipantTokenResponse, meeting, path=["response"]) + @pytest.mark.skip(reason="TODO: auth not handled well") @parametrize def test_raw_response_refresh_participant_token(self, client: Cloudflare) -> None: @@ -1194,6 +1211,10 @@ async def test_method_add_participant_with_all_params(self, async_client: AsyncC app_id="14a396e7-ca44-4937-bf1f-050a69118543", custom_participant_id="custom_participant_id", preset_name="preset_name", + token={ + "expires_on": parse_datetime("2026-10-01T11:00:00Z"), + "not_before": parse_datetime("2026-10-01T09:00:00Z"), + }, name="Mary Sue", picture="https://i.imgur.com/test.jpg", ) @@ -1740,6 +1761,19 @@ async def test_method_refresh_participant_token(self, async_client: AsyncCloudfl ) assert_matches_type(MeetingRefreshParticipantTokenResponse, meeting, path=["response"]) + @pytest.mark.skip(reason="TODO: auth not handled well") + @parametrize + async def test_method_refresh_participant_token_with_all_params(self, async_client: AsyncCloudflare) -> None: + meeting = await async_client.realtime_kit.meetings.refresh_participant_token( + participant_id="participant_id", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + app_id="14a396e7-ca44-4937-bf1f-050a69118543", + meeting_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + expires_on=parse_datetime("2026-10-01T11:00:00Z"), + not_before=parse_datetime("2026-10-01T09:00:00Z"), + ) + assert_matches_type(MeetingRefreshParticipantTokenResponse, meeting, path=["response"]) + @pytest.mark.skip(reason="TODO: auth not handled well") @parametrize async def test_raw_response_refresh_participant_token(self, async_client: AsyncCloudflare) -> None: diff --git a/tests/api_resources/realtime_kit/test_webhooks.py b/tests/api_resources/realtime_kit/test_webhooks.py index 6ee003e2550..773ce059f9f 100644 --- a/tests/api_resources/realtime_kit/test_webhooks.py +++ b/tests/api_resources/realtime_kit/test_webhooks.py @@ -429,19 +429,9 @@ def test_method_replace_webhook(self, client: Cloudflare) -> None: webhook_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", account_id="023e105f4ecef8ad9ca31a8372d0c353", app_id="14a396e7-ca44-4937-bf1f-050a69118543", - events=[ - "meeting.started", - "meeting.ended", - "meeting.participantJoined", - "meeting.participantLeft", - "meeting.chatSynced", - "recording.statusUpdate", - "livestreaming.statusUpdate", - "meeting.transcript", - "meeting.summary", - ], - name="All events webhook", - url="https://webhook.site/b23a5bbd-c7b0-4ced-a9e2-78ae7889897e", + events=["meeting.started"], + name="My Webhook", + url="https://example.com/webhook", ) assert_matches_type(WebhookReplaceWebhookResponse, webhook, path=["response"]) @@ -452,19 +442,9 @@ def test_method_replace_webhook_with_all_params(self, client: Cloudflare) -> Non webhook_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", account_id="023e105f4ecef8ad9ca31a8372d0c353", app_id="14a396e7-ca44-4937-bf1f-050a69118543", - events=[ - "meeting.started", - "meeting.ended", - "meeting.participantJoined", - "meeting.participantLeft", - "meeting.chatSynced", - "recording.statusUpdate", - "livestreaming.statusUpdate", - "meeting.transcript", - "meeting.summary", - ], - name="All events webhook", - url="https://webhook.site/b23a5bbd-c7b0-4ced-a9e2-78ae7889897e", + events=["meeting.started"], + name="My Webhook", + url="https://example.com/webhook", enabled=True, ) assert_matches_type(WebhookReplaceWebhookResponse, webhook, path=["response"]) @@ -476,19 +456,9 @@ def test_raw_response_replace_webhook(self, client: Cloudflare) -> None: webhook_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", account_id="023e105f4ecef8ad9ca31a8372d0c353", app_id="14a396e7-ca44-4937-bf1f-050a69118543", - events=[ - "meeting.started", - "meeting.ended", - "meeting.participantJoined", - "meeting.participantLeft", - "meeting.chatSynced", - "recording.statusUpdate", - "livestreaming.statusUpdate", - "meeting.transcript", - "meeting.summary", - ], - name="All events webhook", - url="https://webhook.site/b23a5bbd-c7b0-4ced-a9e2-78ae7889897e", + events=["meeting.started"], + name="My Webhook", + url="https://example.com/webhook", ) assert response.is_closed is True @@ -503,19 +473,9 @@ def test_streaming_response_replace_webhook(self, client: Cloudflare) -> None: webhook_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", account_id="023e105f4ecef8ad9ca31a8372d0c353", app_id="14a396e7-ca44-4937-bf1f-050a69118543", - events=[ - "meeting.started", - "meeting.ended", - "meeting.participantJoined", - "meeting.participantLeft", - "meeting.chatSynced", - "recording.statusUpdate", - "livestreaming.statusUpdate", - "meeting.transcript", - "meeting.summary", - ], - name="All events webhook", - url="https://webhook.site/b23a5bbd-c7b0-4ced-a9e2-78ae7889897e", + events=["meeting.started"], + name="My Webhook", + url="https://example.com/webhook", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -533,19 +493,9 @@ def test_path_params_replace_webhook(self, client: Cloudflare) -> None: webhook_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", account_id="", app_id="14a396e7-ca44-4937-bf1f-050a69118543", - events=[ - "meeting.started", - "meeting.ended", - "meeting.participantJoined", - "meeting.participantLeft", - "meeting.chatSynced", - "recording.statusUpdate", - "livestreaming.statusUpdate", - "meeting.transcript", - "meeting.summary", - ], - name="All events webhook", - url="https://webhook.site/b23a5bbd-c7b0-4ced-a9e2-78ae7889897e", + events=["meeting.started"], + name="My Webhook", + url="https://example.com/webhook", ) with pytest.raises(ValueError, match=r"Expected a non-empty value for `app_id` but received ''"): @@ -553,19 +503,9 @@ def test_path_params_replace_webhook(self, client: Cloudflare) -> None: webhook_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", account_id="023e105f4ecef8ad9ca31a8372d0c353", app_id="", - events=[ - "meeting.started", - "meeting.ended", - "meeting.participantJoined", - "meeting.participantLeft", - "meeting.chatSynced", - "recording.statusUpdate", - "livestreaming.statusUpdate", - "meeting.transcript", - "meeting.summary", - ], - name="All events webhook", - url="https://webhook.site/b23a5bbd-c7b0-4ced-a9e2-78ae7889897e", + events=["meeting.started"], + name="My Webhook", + url="https://example.com/webhook", ) with pytest.raises(ValueError, match=r"Expected a non-empty value for `webhook_id` but received ''"): @@ -573,19 +513,9 @@ def test_path_params_replace_webhook(self, client: Cloudflare) -> None: webhook_id="", account_id="023e105f4ecef8ad9ca31a8372d0c353", app_id="14a396e7-ca44-4937-bf1f-050a69118543", - events=[ - "meeting.started", - "meeting.ended", - "meeting.participantJoined", - "meeting.participantLeft", - "meeting.chatSynced", - "recording.statusUpdate", - "livestreaming.statusUpdate", - "meeting.transcript", - "meeting.summary", - ], - name="All events webhook", - url="https://webhook.site/b23a5bbd-c7b0-4ced-a9e2-78ae7889897e", + events=["meeting.started"], + name="My Webhook", + url="https://example.com/webhook", ) @@ -999,19 +929,9 @@ async def test_method_replace_webhook(self, async_client: AsyncCloudflare) -> No webhook_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", account_id="023e105f4ecef8ad9ca31a8372d0c353", app_id="14a396e7-ca44-4937-bf1f-050a69118543", - events=[ - "meeting.started", - "meeting.ended", - "meeting.participantJoined", - "meeting.participantLeft", - "meeting.chatSynced", - "recording.statusUpdate", - "livestreaming.statusUpdate", - "meeting.transcript", - "meeting.summary", - ], - name="All events webhook", - url="https://webhook.site/b23a5bbd-c7b0-4ced-a9e2-78ae7889897e", + events=["meeting.started"], + name="My Webhook", + url="https://example.com/webhook", ) assert_matches_type(WebhookReplaceWebhookResponse, webhook, path=["response"]) @@ -1022,19 +942,9 @@ async def test_method_replace_webhook_with_all_params(self, async_client: AsyncC webhook_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", account_id="023e105f4ecef8ad9ca31a8372d0c353", app_id="14a396e7-ca44-4937-bf1f-050a69118543", - events=[ - "meeting.started", - "meeting.ended", - "meeting.participantJoined", - "meeting.participantLeft", - "meeting.chatSynced", - "recording.statusUpdate", - "livestreaming.statusUpdate", - "meeting.transcript", - "meeting.summary", - ], - name="All events webhook", - url="https://webhook.site/b23a5bbd-c7b0-4ced-a9e2-78ae7889897e", + events=["meeting.started"], + name="My Webhook", + url="https://example.com/webhook", enabled=True, ) assert_matches_type(WebhookReplaceWebhookResponse, webhook, path=["response"]) @@ -1046,19 +956,9 @@ async def test_raw_response_replace_webhook(self, async_client: AsyncCloudflare) webhook_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", account_id="023e105f4ecef8ad9ca31a8372d0c353", app_id="14a396e7-ca44-4937-bf1f-050a69118543", - events=[ - "meeting.started", - "meeting.ended", - "meeting.participantJoined", - "meeting.participantLeft", - "meeting.chatSynced", - "recording.statusUpdate", - "livestreaming.statusUpdate", - "meeting.transcript", - "meeting.summary", - ], - name="All events webhook", - url="https://webhook.site/b23a5bbd-c7b0-4ced-a9e2-78ae7889897e", + events=["meeting.started"], + name="My Webhook", + url="https://example.com/webhook", ) assert response.is_closed is True @@ -1073,19 +973,9 @@ async def test_streaming_response_replace_webhook(self, async_client: AsyncCloud webhook_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", account_id="023e105f4ecef8ad9ca31a8372d0c353", app_id="14a396e7-ca44-4937-bf1f-050a69118543", - events=[ - "meeting.started", - "meeting.ended", - "meeting.participantJoined", - "meeting.participantLeft", - "meeting.chatSynced", - "recording.statusUpdate", - "livestreaming.statusUpdate", - "meeting.transcript", - "meeting.summary", - ], - name="All events webhook", - url="https://webhook.site/b23a5bbd-c7b0-4ced-a9e2-78ae7889897e", + events=["meeting.started"], + name="My Webhook", + url="https://example.com/webhook", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -1103,19 +993,9 @@ async def test_path_params_replace_webhook(self, async_client: AsyncCloudflare) webhook_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", account_id="", app_id="14a396e7-ca44-4937-bf1f-050a69118543", - events=[ - "meeting.started", - "meeting.ended", - "meeting.participantJoined", - "meeting.participantLeft", - "meeting.chatSynced", - "recording.statusUpdate", - "livestreaming.statusUpdate", - "meeting.transcript", - "meeting.summary", - ], - name="All events webhook", - url="https://webhook.site/b23a5bbd-c7b0-4ced-a9e2-78ae7889897e", + events=["meeting.started"], + name="My Webhook", + url="https://example.com/webhook", ) with pytest.raises(ValueError, match=r"Expected a non-empty value for `app_id` but received ''"): @@ -1123,19 +1003,9 @@ async def test_path_params_replace_webhook(self, async_client: AsyncCloudflare) webhook_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", account_id="023e105f4ecef8ad9ca31a8372d0c353", app_id="", - events=[ - "meeting.started", - "meeting.ended", - "meeting.participantJoined", - "meeting.participantLeft", - "meeting.chatSynced", - "recording.statusUpdate", - "livestreaming.statusUpdate", - "meeting.transcript", - "meeting.summary", - ], - name="All events webhook", - url="https://webhook.site/b23a5bbd-c7b0-4ced-a9e2-78ae7889897e", + events=["meeting.started"], + name="My Webhook", + url="https://example.com/webhook", ) with pytest.raises(ValueError, match=r"Expected a non-empty value for `webhook_id` but received ''"): @@ -1143,17 +1013,7 @@ async def test_path_params_replace_webhook(self, async_client: AsyncCloudflare) webhook_id="", account_id="023e105f4ecef8ad9ca31a8372d0c353", app_id="14a396e7-ca44-4937-bf1f-050a69118543", - events=[ - "meeting.started", - "meeting.ended", - "meeting.participantJoined", - "meeting.participantLeft", - "meeting.chatSynced", - "recording.statusUpdate", - "livestreaming.statusUpdate", - "meeting.transcript", - "meeting.summary", - ], - name="All events webhook", - url="https://webhook.site/b23a5bbd-c7b0-4ced-a9e2-78ae7889897e", + events=["meeting.started"], + name="My Webhook", + url="https://example.com/webhook", ) diff --git a/tests/api_resources/registrar/test_domains.py b/tests/api_resources/registrar/test_domains.py deleted file mode 100644 index 3b39d042c4f..00000000000 --- a/tests/api_resources/registrar/test_domains.py +++ /dev/null @@ -1,351 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -import os -from typing import Any, cast - -import pytest - -from cloudflare import Cloudflare, AsyncCloudflare -from tests.utils import assert_matches_type -from cloudflare.pagination import SyncSinglePage, AsyncSinglePage -from cloudflare.types.registrar import Domain - -# pyright: reportDeprecated=false - -base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") - - -class TestDomains: - parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) - - @parametrize - def test_method_update(self, client: Cloudflare) -> None: - with pytest.warns(DeprecationWarning): - domain = client.registrar.domains.update( - domain_name="example.com", - account_id="023e105f4ecef8ad9ca31a8372d0c353", - ) - - assert_matches_type(object, domain, path=["response"]) - - @parametrize - def test_method_update_with_all_params(self, client: Cloudflare) -> None: - with pytest.warns(DeprecationWarning): - domain = client.registrar.domains.update( - domain_name="example.com", - account_id="023e105f4ecef8ad9ca31a8372d0c353", - auto_renew=True, - locked=False, - privacy=True, - ) - - assert_matches_type(object, domain, path=["response"]) - - @parametrize - def test_raw_response_update(self, client: Cloudflare) -> None: - with pytest.warns(DeprecationWarning): - response = client.registrar.domains.with_raw_response.update( - domain_name="example.com", - account_id="023e105f4ecef8ad9ca31a8372d0c353", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - domain = response.parse() - assert_matches_type(object, domain, path=["response"]) - - @parametrize - def test_streaming_response_update(self, client: Cloudflare) -> None: - with pytest.warns(DeprecationWarning): - with client.registrar.domains.with_streaming_response.update( - domain_name="example.com", - account_id="023e105f4ecef8ad9ca31a8372d0c353", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - domain = response.parse() - assert_matches_type(object, domain, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @parametrize - def test_path_params_update(self, client: Cloudflare) -> None: - with pytest.warns(DeprecationWarning): - with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): - client.registrar.domains.with_raw_response.update( - domain_name="example.com", - account_id="", - ) - - with pytest.raises(ValueError, match=r"Expected a non-empty value for `domain_name` but received ''"): - client.registrar.domains.with_raw_response.update( - domain_name="", - account_id="023e105f4ecef8ad9ca31a8372d0c353", - ) - - @parametrize - def test_method_list(self, client: Cloudflare) -> None: - with pytest.warns(DeprecationWarning): - domain = client.registrar.domains.list( - account_id="023e105f4ecef8ad9ca31a8372d0c353", - ) - - assert_matches_type(SyncSinglePage[Domain], domain, path=["response"]) - - @parametrize - def test_raw_response_list(self, client: Cloudflare) -> None: - with pytest.warns(DeprecationWarning): - response = client.registrar.domains.with_raw_response.list( - account_id="023e105f4ecef8ad9ca31a8372d0c353", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - domain = response.parse() - assert_matches_type(SyncSinglePage[Domain], domain, path=["response"]) - - @parametrize - def test_streaming_response_list(self, client: Cloudflare) -> None: - with pytest.warns(DeprecationWarning): - with client.registrar.domains.with_streaming_response.list( - account_id="023e105f4ecef8ad9ca31a8372d0c353", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - domain = response.parse() - assert_matches_type(SyncSinglePage[Domain], domain, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @parametrize - def test_path_params_list(self, client: Cloudflare) -> None: - with pytest.warns(DeprecationWarning): - with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): - client.registrar.domains.with_raw_response.list( - account_id="", - ) - - @parametrize - def test_method_get(self, client: Cloudflare) -> None: - with pytest.warns(DeprecationWarning): - domain = client.registrar.domains.get( - domain_name="example.com", - account_id="023e105f4ecef8ad9ca31a8372d0c353", - ) - - assert_matches_type(object, domain, path=["response"]) - - @parametrize - def test_raw_response_get(self, client: Cloudflare) -> None: - with pytest.warns(DeprecationWarning): - response = client.registrar.domains.with_raw_response.get( - domain_name="example.com", - account_id="023e105f4ecef8ad9ca31a8372d0c353", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - domain = response.parse() - assert_matches_type(object, domain, path=["response"]) - - @parametrize - def test_streaming_response_get(self, client: Cloudflare) -> None: - with pytest.warns(DeprecationWarning): - with client.registrar.domains.with_streaming_response.get( - domain_name="example.com", - account_id="023e105f4ecef8ad9ca31a8372d0c353", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - domain = response.parse() - assert_matches_type(object, domain, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @parametrize - def test_path_params_get(self, client: Cloudflare) -> None: - with pytest.warns(DeprecationWarning): - with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): - client.registrar.domains.with_raw_response.get( - domain_name="example.com", - account_id="", - ) - - with pytest.raises(ValueError, match=r"Expected a non-empty value for `domain_name` but received ''"): - client.registrar.domains.with_raw_response.get( - domain_name="", - account_id="023e105f4ecef8ad9ca31a8372d0c353", - ) - - -class TestAsyncDomains: - parametrize = pytest.mark.parametrize( - "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] - ) - - @parametrize - async def test_method_update(self, async_client: AsyncCloudflare) -> None: - with pytest.warns(DeprecationWarning): - domain = await async_client.registrar.domains.update( - domain_name="example.com", - account_id="023e105f4ecef8ad9ca31a8372d0c353", - ) - - assert_matches_type(object, domain, path=["response"]) - - @parametrize - async def test_method_update_with_all_params(self, async_client: AsyncCloudflare) -> None: - with pytest.warns(DeprecationWarning): - domain = await async_client.registrar.domains.update( - domain_name="example.com", - account_id="023e105f4ecef8ad9ca31a8372d0c353", - auto_renew=True, - locked=False, - privacy=True, - ) - - assert_matches_type(object, domain, path=["response"]) - - @parametrize - async def test_raw_response_update(self, async_client: AsyncCloudflare) -> None: - with pytest.warns(DeprecationWarning): - response = await async_client.registrar.domains.with_raw_response.update( - domain_name="example.com", - account_id="023e105f4ecef8ad9ca31a8372d0c353", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - domain = await response.parse() - assert_matches_type(object, domain, path=["response"]) - - @parametrize - async def test_streaming_response_update(self, async_client: AsyncCloudflare) -> None: - with pytest.warns(DeprecationWarning): - async with async_client.registrar.domains.with_streaming_response.update( - domain_name="example.com", - account_id="023e105f4ecef8ad9ca31a8372d0c353", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - domain = await response.parse() - assert_matches_type(object, domain, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @parametrize - async def test_path_params_update(self, async_client: AsyncCloudflare) -> None: - with pytest.warns(DeprecationWarning): - with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): - await async_client.registrar.domains.with_raw_response.update( - domain_name="example.com", - account_id="", - ) - - with pytest.raises(ValueError, match=r"Expected a non-empty value for `domain_name` but received ''"): - await async_client.registrar.domains.with_raw_response.update( - domain_name="", - account_id="023e105f4ecef8ad9ca31a8372d0c353", - ) - - @parametrize - async def test_method_list(self, async_client: AsyncCloudflare) -> None: - with pytest.warns(DeprecationWarning): - domain = await async_client.registrar.domains.list( - account_id="023e105f4ecef8ad9ca31a8372d0c353", - ) - - assert_matches_type(AsyncSinglePage[Domain], domain, path=["response"]) - - @parametrize - async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None: - with pytest.warns(DeprecationWarning): - response = await async_client.registrar.domains.with_raw_response.list( - account_id="023e105f4ecef8ad9ca31a8372d0c353", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - domain = await response.parse() - assert_matches_type(AsyncSinglePage[Domain], domain, path=["response"]) - - @parametrize - async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> None: - with pytest.warns(DeprecationWarning): - async with async_client.registrar.domains.with_streaming_response.list( - account_id="023e105f4ecef8ad9ca31a8372d0c353", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - domain = await response.parse() - assert_matches_type(AsyncSinglePage[Domain], domain, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @parametrize - async def test_path_params_list(self, async_client: AsyncCloudflare) -> None: - with pytest.warns(DeprecationWarning): - with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): - await async_client.registrar.domains.with_raw_response.list( - account_id="", - ) - - @parametrize - async def test_method_get(self, async_client: AsyncCloudflare) -> None: - with pytest.warns(DeprecationWarning): - domain = await async_client.registrar.domains.get( - domain_name="example.com", - account_id="023e105f4ecef8ad9ca31a8372d0c353", - ) - - assert_matches_type(object, domain, path=["response"]) - - @parametrize - async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None: - with pytest.warns(DeprecationWarning): - response = await async_client.registrar.domains.with_raw_response.get( - domain_name="example.com", - account_id="023e105f4ecef8ad9ca31a8372d0c353", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - domain = await response.parse() - assert_matches_type(object, domain, path=["response"]) - - @parametrize - async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> None: - with pytest.warns(DeprecationWarning): - async with async_client.registrar.domains.with_streaming_response.get( - domain_name="example.com", - account_id="023e105f4ecef8ad9ca31a8372d0c353", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - domain = await response.parse() - assert_matches_type(object, domain, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @parametrize - async def test_path_params_get(self, async_client: AsyncCloudflare) -> None: - with pytest.warns(DeprecationWarning): - with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): - await async_client.registrar.domains.with_raw_response.get( - domain_name="example.com", - account_id="", - ) - - with pytest.raises(ValueError, match=r"Expected a non-empty value for `domain_name` but received ''"): - await async_client.registrar.domains.with_raw_response.get( - domain_name="", - account_id="023e105f4ecef8ad9ca31a8372d0c353", - ) diff --git a/tests/api_resources/resource_sharing/test_recipients.py b/tests/api_resources/resource_sharing/test_recipients.py index a9ca17ea87e..4be15df1f4c 100644 --- a/tests/api_resources/resource_sharing/test_recipients.py +++ b/tests/api_resources/resource_sharing/test_recipients.py @@ -37,7 +37,6 @@ def test_method_create_with_all_params(self, client: Cloudflare) -> None: share_id="3fd85f74b32742f1bff64a85009dda07", path_account_id="023e105f4ecef8ad9ca31a8372d0c353", body_account_id="023e105f4ecef8ad9ca31a8372d0c353", - organization_id="023e105f4ecef8ad9ca31a8372d0c353", recipient_account_id="023e105f4ecef8ad9ca31a8372d0c353", ) assert_matches_type(Optional[RecipientCreateResponse], recipient, path=["response"]) @@ -291,7 +290,6 @@ async def test_method_create_with_all_params(self, async_client: AsyncCloudflare share_id="3fd85f74b32742f1bff64a85009dda07", path_account_id="023e105f4ecef8ad9ca31a8372d0c353", body_account_id="023e105f4ecef8ad9ca31a8372d0c353", - organization_id="023e105f4ecef8ad9ca31a8372d0c353", recipient_account_id="023e105f4ecef8ad9ca31a8372d0c353", ) assert_matches_type(Optional[RecipientCreateResponse], recipient, path=["response"]) diff --git a/tests/api_resources/resource_sharing/test_resources.py b/tests/api_resources/resource_sharing/test_resources.py index a07aeebdca1..687692215a0 100644 --- a/tests/api_resources/resource_sharing/test_resources.py +++ b/tests/api_resources/resource_sharing/test_resources.py @@ -31,7 +31,7 @@ def test_method_create(self, client: Cloudflare) -> None: account_id="023e105f4ecef8ad9ca31a8372d0c353", meta={}, resource_account_id="023e105f4ecef8ad9ca31a8372d0c353", - resource_id="023e105f4ecef8ad9ca31a8372d0c353", + resource_id="0a679032-bbb2-4b7e-9acc-dd5c5cb27a17", resource_type="custom-ruleset", ) assert_matches_type(Optional[ResourceCreateResponse], resource, path=["response"]) @@ -43,7 +43,7 @@ def test_raw_response_create(self, client: Cloudflare) -> None: account_id="023e105f4ecef8ad9ca31a8372d0c353", meta={}, resource_account_id="023e105f4ecef8ad9ca31a8372d0c353", - resource_id="023e105f4ecef8ad9ca31a8372d0c353", + resource_id="0a679032-bbb2-4b7e-9acc-dd5c5cb27a17", resource_type="custom-ruleset", ) @@ -59,7 +59,7 @@ def test_streaming_response_create(self, client: Cloudflare) -> None: account_id="023e105f4ecef8ad9ca31a8372d0c353", meta={}, resource_account_id="023e105f4ecef8ad9ca31a8372d0c353", - resource_id="023e105f4ecef8ad9ca31a8372d0c353", + resource_id="0a679032-bbb2-4b7e-9acc-dd5c5cb27a17", resource_type="custom-ruleset", ) as response: assert not response.is_closed @@ -78,7 +78,7 @@ def test_path_params_create(self, client: Cloudflare) -> None: account_id="", meta={}, resource_account_id="023e105f4ecef8ad9ca31a8372d0c353", - resource_id="023e105f4ecef8ad9ca31a8372d0c353", + resource_id="0a679032-bbb2-4b7e-9acc-dd5c5cb27a17", resource_type="custom-ruleset", ) @@ -88,7 +88,7 @@ def test_path_params_create(self, client: Cloudflare) -> None: account_id="023e105f4ecef8ad9ca31a8372d0c353", meta={}, resource_account_id="023e105f4ecef8ad9ca31a8372d0c353", - resource_id="023e105f4ecef8ad9ca31a8372d0c353", + resource_id="0a679032-bbb2-4b7e-9acc-dd5c5cb27a17", resource_type="custom-ruleset", ) @@ -351,7 +351,7 @@ async def test_method_create(self, async_client: AsyncCloudflare) -> None: account_id="023e105f4ecef8ad9ca31a8372d0c353", meta={}, resource_account_id="023e105f4ecef8ad9ca31a8372d0c353", - resource_id="023e105f4ecef8ad9ca31a8372d0c353", + resource_id="0a679032-bbb2-4b7e-9acc-dd5c5cb27a17", resource_type="custom-ruleset", ) assert_matches_type(Optional[ResourceCreateResponse], resource, path=["response"]) @@ -363,7 +363,7 @@ async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None: account_id="023e105f4ecef8ad9ca31a8372d0c353", meta={}, resource_account_id="023e105f4ecef8ad9ca31a8372d0c353", - resource_id="023e105f4ecef8ad9ca31a8372d0c353", + resource_id="0a679032-bbb2-4b7e-9acc-dd5c5cb27a17", resource_type="custom-ruleset", ) @@ -379,7 +379,7 @@ async def test_streaming_response_create(self, async_client: AsyncCloudflare) -> account_id="023e105f4ecef8ad9ca31a8372d0c353", meta={}, resource_account_id="023e105f4ecef8ad9ca31a8372d0c353", - resource_id="023e105f4ecef8ad9ca31a8372d0c353", + resource_id="0a679032-bbb2-4b7e-9acc-dd5c5cb27a17", resource_type="custom-ruleset", ) as response: assert not response.is_closed @@ -398,7 +398,7 @@ async def test_path_params_create(self, async_client: AsyncCloudflare) -> None: account_id="", meta={}, resource_account_id="023e105f4ecef8ad9ca31a8372d0c353", - resource_id="023e105f4ecef8ad9ca31a8372d0c353", + resource_id="0a679032-bbb2-4b7e-9acc-dd5c5cb27a17", resource_type="custom-ruleset", ) @@ -408,7 +408,7 @@ async def test_path_params_create(self, async_client: AsyncCloudflare) -> None: account_id="023e105f4ecef8ad9ca31a8372d0c353", meta={}, resource_account_id="023e105f4ecef8ad9ca31a8372d0c353", - resource_id="023e105f4ecef8ad9ca31a8372d0c353", + resource_id="0a679032-bbb2-4b7e-9acc-dd5c5cb27a17", resource_type="custom-ruleset", ) diff --git a/tests/api_resources/rulesets/phases/test_versions.py b/tests/api_resources/rulesets/phases/test_versions.py index 002f11ccc12..482d11e2d64 100644 --- a/tests/api_resources/rulesets/phases/test_versions.py +++ b/tests/api_resources/rulesets/phases/test_versions.py @@ -9,7 +9,6 @@ from cloudflare import Cloudflare, AsyncCloudflare from tests.utils import assert_matches_type -from cloudflare.pagination import SyncSinglePage, AsyncSinglePage from cloudflare.types.rulesets.phases import VersionGetResponse, VersionListResponse base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") @@ -25,7 +24,7 @@ def test_method_list(self, client: Cloudflare) -> None: ruleset_phase="http_request_firewall_custom", account_id="account_id", ) - assert_matches_type(SyncSinglePage[VersionListResponse], version, path=["response"]) + assert_matches_type(VersionListResponse, version, path=["response"]) @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize @@ -34,7 +33,7 @@ def test_method_list_with_all_params(self, client: Cloudflare) -> None: ruleset_phase="http_request_firewall_custom", account_id="account_id", ) - assert_matches_type(SyncSinglePage[VersionListResponse], version, path=["response"]) + assert_matches_type(VersionListResponse, version, path=["response"]) @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize @@ -47,7 +46,7 @@ def test_raw_response_list(self, client: Cloudflare) -> None: assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" version = response.parse() - assert_matches_type(SyncSinglePage[VersionListResponse], version, path=["response"]) + assert_matches_type(VersionListResponse, version, path=["response"]) @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize @@ -60,7 +59,7 @@ def test_streaming_response_list(self, client: Cloudflare) -> None: assert response.http_request.headers.get("X-Stainless-Lang") == "python" version = response.parse() - assert_matches_type(SyncSinglePage[VersionListResponse], version, path=["response"]) + assert_matches_type(VersionListResponse, version, path=["response"]) assert cast(Any, response.is_closed) is True @@ -166,7 +165,7 @@ async def test_method_list(self, async_client: AsyncCloudflare) -> None: ruleset_phase="http_request_firewall_custom", account_id="account_id", ) - assert_matches_type(AsyncSinglePage[VersionListResponse], version, path=["response"]) + assert_matches_type(VersionListResponse, version, path=["response"]) @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize @@ -175,7 +174,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncCloudflare) ruleset_phase="http_request_firewall_custom", account_id="account_id", ) - assert_matches_type(AsyncSinglePage[VersionListResponse], version, path=["response"]) + assert_matches_type(VersionListResponse, version, path=["response"]) @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize @@ -188,7 +187,7 @@ async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None: assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" version = await response.parse() - assert_matches_type(AsyncSinglePage[VersionListResponse], version, path=["response"]) + assert_matches_type(VersionListResponse, version, path=["response"]) @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize @@ -201,7 +200,7 @@ async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> N assert response.http_request.headers.get("X-Stainless-Lang") == "python" version = await response.parse() - assert_matches_type(AsyncSinglePage[VersionListResponse], version, path=["response"]) + assert_matches_type(VersionListResponse, version, path=["response"]) assert cast(Any, response.is_closed) is True diff --git a/tests/api_resources/rulesets/test_versions.py b/tests/api_resources/rulesets/test_versions.py index 8d121b42a55..d3730fe0f03 100644 --- a/tests/api_resources/rulesets/test_versions.py +++ b/tests/api_resources/rulesets/test_versions.py @@ -9,7 +9,6 @@ from cloudflare import Cloudflare, AsyncCloudflare from tests.utils import assert_matches_type -from cloudflare.pagination import SyncSinglePage, AsyncSinglePage from cloudflare.types.rulesets import VersionGetResponse, VersionListResponse base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") @@ -25,7 +24,7 @@ def test_method_list(self, client: Cloudflare) -> None: ruleset_id="2f2feab2026849078ba485f918791bdc", account_id="account_id", ) - assert_matches_type(SyncSinglePage[VersionListResponse], version, path=["response"]) + assert_matches_type(VersionListResponse, version, path=["response"]) @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize @@ -34,7 +33,7 @@ def test_method_list_with_all_params(self, client: Cloudflare) -> None: ruleset_id="2f2feab2026849078ba485f918791bdc", account_id="account_id", ) - assert_matches_type(SyncSinglePage[VersionListResponse], version, path=["response"]) + assert_matches_type(VersionListResponse, version, path=["response"]) @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize @@ -47,7 +46,7 @@ def test_raw_response_list(self, client: Cloudflare) -> None: assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" version = response.parse() - assert_matches_type(SyncSinglePage[VersionListResponse], version, path=["response"]) + assert_matches_type(VersionListResponse, version, path=["response"]) @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize @@ -60,7 +59,7 @@ def test_streaming_response_list(self, client: Cloudflare) -> None: assert response.http_request.headers.get("X-Stainless-Lang") == "python" version = response.parse() - assert_matches_type(SyncSinglePage[VersionListResponse], version, path=["response"]) + assert_matches_type(VersionListResponse, version, path=["response"]) assert cast(Any, response.is_closed) is True @@ -261,7 +260,7 @@ async def test_method_list(self, async_client: AsyncCloudflare) -> None: ruleset_id="2f2feab2026849078ba485f918791bdc", account_id="account_id", ) - assert_matches_type(AsyncSinglePage[VersionListResponse], version, path=["response"]) + assert_matches_type(VersionListResponse, version, path=["response"]) @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize @@ -270,7 +269,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncCloudflare) ruleset_id="2f2feab2026849078ba485f918791bdc", account_id="account_id", ) - assert_matches_type(AsyncSinglePage[VersionListResponse], version, path=["response"]) + assert_matches_type(VersionListResponse, version, path=["response"]) @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize @@ -283,7 +282,7 @@ async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None: assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" version = await response.parse() - assert_matches_type(AsyncSinglePage[VersionListResponse], version, path=["response"]) + assert_matches_type(VersionListResponse, version, path=["response"]) @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize @@ -296,7 +295,7 @@ async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> N assert response.http_request.headers.get("X-Stainless-Lang") == "python" version = await response.parse() - assert_matches_type(AsyncSinglePage[VersionListResponse], version, path=["response"]) + assert_matches_type(VersionListResponse, version, path=["response"]) assert cast(Any, response.is_closed) is True diff --git a/tests/api_resources/secrets_store/stores/test_secrets.py b/tests/api_resources/secrets_store/stores/test_secrets.py index c9b96739383..8a4cec0f193 100644 --- a/tests/api_resources/secrets_store/stores/test_secrets.py +++ b/tests/api_resources/secrets_store/stores/test_secrets.py @@ -32,7 +32,6 @@ def test_method_create(self, client: Cloudflare) -> None: body=[ { "name": "MY_API_KEY", - "scopes": ["workers", "ai_gateway", "dex", "access", "websearch"], "value": "api-token-secret-123", } ], @@ -47,7 +46,6 @@ def test_raw_response_create(self, client: Cloudflare) -> None: body=[ { "name": "MY_API_KEY", - "scopes": ["workers", "ai_gateway", "dex", "access", "websearch"], "value": "api-token-secret-123", } ], @@ -66,7 +64,6 @@ def test_streaming_response_create(self, client: Cloudflare) -> None: body=[ { "name": "MY_API_KEY", - "scopes": ["workers", "ai_gateway", "dex", "access", "websearch"], "value": "api-token-secret-123", } ], @@ -88,7 +85,6 @@ def test_path_params_create(self, client: Cloudflare) -> None: body=[ { "name": "MY_API_KEY", - "scopes": ["workers", "ai_gateway", "dex", "access", "websearch"], "value": "api-token-secret-123", } ], @@ -101,7 +97,6 @@ def test_path_params_create(self, client: Cloudflare) -> None: body=[ { "name": "MY_API_KEY", - "scopes": ["workers", "ai_gateway", "dex", "access", "websearch"], "value": "api-token-secret-123", } ], @@ -290,7 +285,6 @@ def test_method_duplicate(self, client: Cloudflare) -> None: account_id="985e105f4ecef8ad9ca31a8372d0c353", store_id="023e105f4ecef8ad9ca31a8372d0c353", name="MY_API_KEY", - scopes=["workers", "ai_gateway", "dex", "access", "websearch"], ) assert_matches_type(Optional[SecretDuplicateResponse], secret, path=["response"]) @@ -302,8 +296,8 @@ def test_method_duplicate_with_all_params(self, client: Cloudflare) -> None: account_id="985e105f4ecef8ad9ca31a8372d0c353", store_id="023e105f4ecef8ad9ca31a8372d0c353", name="MY_API_KEY", - scopes=["workers", "ai_gateway", "dex", "access", "websearch"], comment="info about my secret", + scopes=["workers", "ai_gateway", "dex", "access", "websearch"], ) assert_matches_type(Optional[SecretDuplicateResponse], secret, path=["response"]) @@ -315,7 +309,6 @@ def test_raw_response_duplicate(self, client: Cloudflare) -> None: account_id="985e105f4ecef8ad9ca31a8372d0c353", store_id="023e105f4ecef8ad9ca31a8372d0c353", name="MY_API_KEY", - scopes=["workers", "ai_gateway", "dex", "access", "websearch"], ) assert response.is_closed is True @@ -331,7 +324,6 @@ def test_streaming_response_duplicate(self, client: Cloudflare) -> None: account_id="985e105f4ecef8ad9ca31a8372d0c353", store_id="023e105f4ecef8ad9ca31a8372d0c353", name="MY_API_KEY", - scopes=["workers", "ai_gateway", "dex", "access", "websearch"], ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -350,7 +342,6 @@ def test_path_params_duplicate(self, client: Cloudflare) -> None: account_id="", store_id="023e105f4ecef8ad9ca31a8372d0c353", name="MY_API_KEY", - scopes=["workers", "ai_gateway", "dex", "access", "websearch"], ) with pytest.raises(ValueError, match=r"Expected a non-empty value for `store_id` but received ''"): @@ -359,7 +350,6 @@ def test_path_params_duplicate(self, client: Cloudflare) -> None: account_id="985e105f4ecef8ad9ca31a8372d0c353", store_id="", name="MY_API_KEY", - scopes=["workers", "ai_gateway", "dex", "access", "websearch"], ) with pytest.raises(ValueError, match=r"Expected a non-empty value for `secret_id` but received ''"): @@ -368,7 +358,6 @@ def test_path_params_duplicate(self, client: Cloudflare) -> None: account_id="985e105f4ecef8ad9ca31a8372d0c353", store_id="023e105f4ecef8ad9ca31a8372d0c353", name="MY_API_KEY", - scopes=["workers", "ai_gateway", "dex", "access", "websearch"], ) @pytest.mark.skip(reason="TODO: investigate prism error for 422 Unprocessable Entity") @@ -522,7 +511,6 @@ async def test_method_create(self, async_client: AsyncCloudflare) -> None: body=[ { "name": "MY_API_KEY", - "scopes": ["workers", "ai_gateway", "dex", "access", "websearch"], "value": "api-token-secret-123", } ], @@ -537,7 +525,6 @@ async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None: body=[ { "name": "MY_API_KEY", - "scopes": ["workers", "ai_gateway", "dex", "access", "websearch"], "value": "api-token-secret-123", } ], @@ -556,7 +543,6 @@ async def test_streaming_response_create(self, async_client: AsyncCloudflare) -> body=[ { "name": "MY_API_KEY", - "scopes": ["workers", "ai_gateway", "dex", "access", "websearch"], "value": "api-token-secret-123", } ], @@ -578,7 +564,6 @@ async def test_path_params_create(self, async_client: AsyncCloudflare) -> None: body=[ { "name": "MY_API_KEY", - "scopes": ["workers", "ai_gateway", "dex", "access", "websearch"], "value": "api-token-secret-123", } ], @@ -591,7 +576,6 @@ async def test_path_params_create(self, async_client: AsyncCloudflare) -> None: body=[ { "name": "MY_API_KEY", - "scopes": ["workers", "ai_gateway", "dex", "access", "websearch"], "value": "api-token-secret-123", } ], @@ -780,7 +764,6 @@ async def test_method_duplicate(self, async_client: AsyncCloudflare) -> None: account_id="985e105f4ecef8ad9ca31a8372d0c353", store_id="023e105f4ecef8ad9ca31a8372d0c353", name="MY_API_KEY", - scopes=["workers", "ai_gateway", "dex", "access", "websearch"], ) assert_matches_type(Optional[SecretDuplicateResponse], secret, path=["response"]) @@ -792,8 +775,8 @@ async def test_method_duplicate_with_all_params(self, async_client: AsyncCloudfl account_id="985e105f4ecef8ad9ca31a8372d0c353", store_id="023e105f4ecef8ad9ca31a8372d0c353", name="MY_API_KEY", - scopes=["workers", "ai_gateway", "dex", "access", "websearch"], comment="info about my secret", + scopes=["workers", "ai_gateway", "dex", "access", "websearch"], ) assert_matches_type(Optional[SecretDuplicateResponse], secret, path=["response"]) @@ -805,7 +788,6 @@ async def test_raw_response_duplicate(self, async_client: AsyncCloudflare) -> No account_id="985e105f4ecef8ad9ca31a8372d0c353", store_id="023e105f4ecef8ad9ca31a8372d0c353", name="MY_API_KEY", - scopes=["workers", "ai_gateway", "dex", "access", "websearch"], ) assert response.is_closed is True @@ -821,7 +803,6 @@ async def test_streaming_response_duplicate(self, async_client: AsyncCloudflare) account_id="985e105f4ecef8ad9ca31a8372d0c353", store_id="023e105f4ecef8ad9ca31a8372d0c353", name="MY_API_KEY", - scopes=["workers", "ai_gateway", "dex", "access", "websearch"], ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -840,7 +821,6 @@ async def test_path_params_duplicate(self, async_client: AsyncCloudflare) -> Non account_id="", store_id="023e105f4ecef8ad9ca31a8372d0c353", name="MY_API_KEY", - scopes=["workers", "ai_gateway", "dex", "access", "websearch"], ) with pytest.raises(ValueError, match=r"Expected a non-empty value for `store_id` but received ''"): @@ -849,7 +829,6 @@ async def test_path_params_duplicate(self, async_client: AsyncCloudflare) -> Non account_id="985e105f4ecef8ad9ca31a8372d0c353", store_id="", name="MY_API_KEY", - scopes=["workers", "ai_gateway", "dex", "access", "websearch"], ) with pytest.raises(ValueError, match=r"Expected a non-empty value for `secret_id` but received ''"): @@ -858,7 +837,6 @@ async def test_path_params_duplicate(self, async_client: AsyncCloudflare) -> Non account_id="985e105f4ecef8ad9ca31a8372d0c353", store_id="023e105f4ecef8ad9ca31a8372d0c353", name="MY_API_KEY", - scopes=["workers", "ai_gateway", "dex", "access", "websearch"], ) @pytest.mark.skip(reason="TODO: investigate prism error for 422 Unprocessable Entity") diff --git a/tests/api_resources/tenants/test_account_types.py b/tests/api_resources/tenants/test_account_types.py deleted file mode 100644 index 27a9312c379..00000000000 --- a/tests/api_resources/tenants/test_account_types.py +++ /dev/null @@ -1,101 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -import os -from typing import Any, cast - -import pytest - -from cloudflare import Cloudflare, AsyncCloudflare -from tests.utils import assert_matches_type -from cloudflare.pagination import SyncSinglePage, AsyncSinglePage -from cloudflare.types.tenants import AccountTypeListResponse - -base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") - - -class TestAccountTypes: - parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) - - @parametrize - def test_method_list(self, client: Cloudflare) -> None: - account_type = client.tenants.account_types.list( - "tenant_id", - ) - assert_matches_type(SyncSinglePage[AccountTypeListResponse], account_type, path=["response"]) - - @parametrize - def test_raw_response_list(self, client: Cloudflare) -> None: - response = client.tenants.account_types.with_raw_response.list( - "tenant_id", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - account_type = response.parse() - assert_matches_type(SyncSinglePage[AccountTypeListResponse], account_type, path=["response"]) - - @parametrize - def test_streaming_response_list(self, client: Cloudflare) -> None: - with client.tenants.account_types.with_streaming_response.list( - "tenant_id", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - account_type = response.parse() - assert_matches_type(SyncSinglePage[AccountTypeListResponse], account_type, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @parametrize - def test_path_params_list(self, client: Cloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `tenant_id` but received ''"): - client.tenants.account_types.with_raw_response.list( - "", - ) - - -class TestAsyncAccountTypes: - parametrize = pytest.mark.parametrize( - "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] - ) - - @parametrize - async def test_method_list(self, async_client: AsyncCloudflare) -> None: - account_type = await async_client.tenants.account_types.list( - "tenant_id", - ) - assert_matches_type(AsyncSinglePage[AccountTypeListResponse], account_type, path=["response"]) - - @parametrize - async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None: - response = await async_client.tenants.account_types.with_raw_response.list( - "tenant_id", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - account_type = await response.parse() - assert_matches_type(AsyncSinglePage[AccountTypeListResponse], account_type, path=["response"]) - - @parametrize - async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> None: - async with async_client.tenants.account_types.with_streaming_response.list( - "tenant_id", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - account_type = await response.parse() - assert_matches_type(AsyncSinglePage[AccountTypeListResponse], account_type, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @parametrize - async def test_path_params_list(self, async_client: AsyncCloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `tenant_id` but received ''"): - await async_client.tenants.account_types.with_raw_response.list( - "", - ) diff --git a/tests/api_resources/tenants/test_accounts.py b/tests/api_resources/tenants/test_accounts.py index d953e879695..c825f3cf709 100644 --- a/tests/api_resources/tenants/test_accounts.py +++ b/tests/api_resources/tenants/test_accounts.py @@ -9,8 +9,8 @@ from cloudflare import Cloudflare, AsyncCloudflare from tests.utils import assert_matches_type -from cloudflare.pagination import SyncSinglePage, AsyncSinglePage -from cloudflare.types.tenants import TenantAccount +from cloudflare.pagination import SyncV4PagePaginationArray, AsyncV4PagePaginationArray +from cloudflare.types.tenants import AccountListResponse base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") @@ -21,31 +21,56 @@ class TestAccounts: @parametrize def test_method_list(self, client: Cloudflare) -> None: account = client.tenants.accounts.list( - "tenant_id", + tenant_id="tenant_id", ) - assert_matches_type(SyncSinglePage[TenantAccount], account, path=["response"]) + assert_matches_type(SyncV4PagePaginationArray[AccountListResponse], account, path=["response"]) + + @parametrize + def test_method_list_with_all_params(self, client: Cloudflare) -> None: + account = client.tenants.accounts.list( + tenant_id="tenant_id", + account_pubname={ + "contains": "contains", + "ends_with": "endsWith", + "starts_with": "startsWith", + }, + direction="asc", + include_total=True, + name={ + "contains": "contains", + "ends_with": "endsWith", + "starts_with": "startsWith", + }, + order_by="account_name", + page=0, + page_size=0, + page_token="page_token", + per_page=0, + status="active", + ) + assert_matches_type(SyncV4PagePaginationArray[AccountListResponse], account, path=["response"]) @parametrize def test_raw_response_list(self, client: Cloudflare) -> None: response = client.tenants.accounts.with_raw_response.list( - "tenant_id", + tenant_id="tenant_id", ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" account = response.parse() - assert_matches_type(SyncSinglePage[TenantAccount], account, path=["response"]) + assert_matches_type(SyncV4PagePaginationArray[AccountListResponse], account, path=["response"]) @parametrize def test_streaming_response_list(self, client: Cloudflare) -> None: with client.tenants.accounts.with_streaming_response.list( - "tenant_id", + tenant_id="tenant_id", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" account = response.parse() - assert_matches_type(SyncSinglePage[TenantAccount], account, path=["response"]) + assert_matches_type(SyncV4PagePaginationArray[AccountListResponse], account, path=["response"]) assert cast(Any, response.is_closed) is True @@ -53,7 +78,7 @@ def test_streaming_response_list(self, client: Cloudflare) -> None: def test_path_params_list(self, client: Cloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `tenant_id` but received ''"): client.tenants.accounts.with_raw_response.list( - "", + tenant_id="", ) @@ -65,31 +90,56 @@ class TestAsyncAccounts: @parametrize async def test_method_list(self, async_client: AsyncCloudflare) -> None: account = await async_client.tenants.accounts.list( - "tenant_id", + tenant_id="tenant_id", + ) + assert_matches_type(AsyncV4PagePaginationArray[AccountListResponse], account, path=["response"]) + + @parametrize + async def test_method_list_with_all_params(self, async_client: AsyncCloudflare) -> None: + account = await async_client.tenants.accounts.list( + tenant_id="tenant_id", + account_pubname={ + "contains": "contains", + "ends_with": "endsWith", + "starts_with": "startsWith", + }, + direction="asc", + include_total=True, + name={ + "contains": "contains", + "ends_with": "endsWith", + "starts_with": "startsWith", + }, + order_by="account_name", + page=0, + page_size=0, + page_token="page_token", + per_page=0, + status="active", ) - assert_matches_type(AsyncSinglePage[TenantAccount], account, path=["response"]) + assert_matches_type(AsyncV4PagePaginationArray[AccountListResponse], account, path=["response"]) @parametrize async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None: response = await async_client.tenants.accounts.with_raw_response.list( - "tenant_id", + tenant_id="tenant_id", ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" account = await response.parse() - assert_matches_type(AsyncSinglePage[TenantAccount], account, path=["response"]) + assert_matches_type(AsyncV4PagePaginationArray[AccountListResponse], account, path=["response"]) @parametrize async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> None: async with async_client.tenants.accounts.with_streaming_response.list( - "tenant_id", + tenant_id="tenant_id", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" account = await response.parse() - assert_matches_type(AsyncSinglePage[TenantAccount], account, path=["response"]) + assert_matches_type(AsyncV4PagePaginationArray[AccountListResponse], account, path=["response"]) assert cast(Any, response.is_closed) is True @@ -97,5 +147,5 @@ async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> N async def test_path_params_list(self, async_client: AsyncCloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `tenant_id` but received ''"): await async_client.tenants.accounts.with_raw_response.list( - "", + tenant_id="", ) diff --git a/tests/api_resources/tenants/test_entitlements.py b/tests/api_resources/tenants/test_entitlements.py deleted file mode 100644 index fce9a351a94..00000000000 --- a/tests/api_resources/tenants/test_entitlements.py +++ /dev/null @@ -1,100 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -import os -from typing import Any, cast - -import pytest - -from cloudflare import Cloudflare, AsyncCloudflare -from tests.utils import assert_matches_type -from cloudflare.types.tenants import TenantEntitlements - -base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") - - -class TestEntitlements: - parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) - - @parametrize - def test_method_get(self, client: Cloudflare) -> None: - entitlement = client.tenants.entitlements.get( - "tenant_id", - ) - assert_matches_type(TenantEntitlements, entitlement, path=["response"]) - - @parametrize - def test_raw_response_get(self, client: Cloudflare) -> None: - response = client.tenants.entitlements.with_raw_response.get( - "tenant_id", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - entitlement = response.parse() - assert_matches_type(TenantEntitlements, entitlement, path=["response"]) - - @parametrize - def test_streaming_response_get(self, client: Cloudflare) -> None: - with client.tenants.entitlements.with_streaming_response.get( - "tenant_id", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - entitlement = response.parse() - assert_matches_type(TenantEntitlements, entitlement, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @parametrize - def test_path_params_get(self, client: Cloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `tenant_id` but received ''"): - client.tenants.entitlements.with_raw_response.get( - "", - ) - - -class TestAsyncEntitlements: - parametrize = pytest.mark.parametrize( - "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] - ) - - @parametrize - async def test_method_get(self, async_client: AsyncCloudflare) -> None: - entitlement = await async_client.tenants.entitlements.get( - "tenant_id", - ) - assert_matches_type(TenantEntitlements, entitlement, path=["response"]) - - @parametrize - async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None: - response = await async_client.tenants.entitlements.with_raw_response.get( - "tenant_id", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - entitlement = await response.parse() - assert_matches_type(TenantEntitlements, entitlement, path=["response"]) - - @parametrize - async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> None: - async with async_client.tenants.entitlements.with_streaming_response.get( - "tenant_id", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - entitlement = await response.parse() - assert_matches_type(TenantEntitlements, entitlement, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @parametrize - async def test_path_params_get(self, async_client: AsyncCloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `tenant_id` but received ''"): - await async_client.tenants.entitlements.with_raw_response.get( - "", - ) diff --git a/tests/api_resources/test_abuse_reports.py b/tests/api_resources/test_abuse_reports.py index 16aaf345712..dc2fe9de8ef 100644 --- a/tests/api_resources/test_abuse_reports.py +++ b/tests/api_resources/test_abuse_reports.py @@ -1028,7 +1028,9 @@ def test_method_list_with_all_params(self, client: Cloudflare) -> None: domain="domain", mitigation_status="pending", page=0, + pending_notice=True, per_page=0, + search="search", sort="sort", status="accepted", type="PHISH", @@ -2136,7 +2138,9 @@ async def test_method_list_with_all_params(self, async_client: AsyncCloudflare) domain="domain", mitigation_status="pending", page=0, + pending_notice=True, per_page=0, + search="search", sort="sort", status="accepted", type="PHISH", diff --git a/tests/api_resources/test_ai_gateway.py b/tests/api_resources/test_ai_gateway.py index 33046e02ea1..b5cebb7241a 100644 --- a/tests/api_resources/test_ai_gateway.py +++ b/tests/api_resources/test_ai_gateway.py @@ -62,6 +62,7 @@ def test_method_create_with_all_params(self, client: Cloudflare) -> None: "s11": "FLAG", "s12": "FLAG", "s13": "FLAG", + "s14": "FLAG", "s2": "FLAG", "s3": "FLAG", "s4": "FLAG", @@ -78,6 +79,7 @@ def test_method_create_with_all_params(self, client: Cloudflare) -> None: "s11": "FLAG", "s12": "FLAG", "s13": "FLAG", + "s14": "FLAG", "s2": "FLAG", "s3": "FLAG", "s4": "FLAG", @@ -224,6 +226,7 @@ def test_method_update_with_all_params(self, client: Cloudflare) -> None: "s11": "FLAG", "s12": "FLAG", "s13": "FLAG", + "s14": "FLAG", "s2": "FLAG", "s3": "FLAG", "s4": "FLAG", @@ -240,6 +243,7 @@ def test_method_update_with_all_params(self, client: Cloudflare) -> None: "s11": "FLAG", "s12": "FLAG", "s13": "FLAG", + "s14": "FLAG", "s2": "FLAG", "s3": "FLAG", "s4": "FLAG", @@ -547,6 +551,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncCloudflare "s11": "FLAG", "s12": "FLAG", "s13": "FLAG", + "s14": "FLAG", "s2": "FLAG", "s3": "FLAG", "s4": "FLAG", @@ -563,6 +568,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncCloudflare "s11": "FLAG", "s12": "FLAG", "s13": "FLAG", + "s14": "FLAG", "s2": "FLAG", "s3": "FLAG", "s4": "FLAG", @@ -709,6 +715,7 @@ async def test_method_update_with_all_params(self, async_client: AsyncCloudflare "s11": "FLAG", "s12": "FLAG", "s13": "FLAG", + "s14": "FLAG", "s2": "FLAG", "s3": "FLAG", "s4": "FLAG", @@ -725,6 +732,7 @@ async def test_method_update_with_all_params(self, async_client: AsyncCloudflare "s11": "FLAG", "s12": "FLAG", "s13": "FLAG", + "s14": "FLAG", "s2": "FLAG", "s3": "FLAG", "s4": "FLAG", diff --git a/tests/api_resources/test_basin_catalog.py b/tests/api_resources/test_basin_catalog.py index 4edbe0eca39..91d3247b8aa 100644 --- a/tests/api_resources/test_basin_catalog.py +++ b/tests/api_resources/test_basin_catalog.py @@ -172,6 +172,15 @@ def test_method_enable(self, client: Cloudflare) -> None: ) assert_matches_type(Optional[BasinCatalogEnableResponse], basin_catalog, path=["response"]) + @parametrize + def test_method_enable_with_all_params(self, client: Cloudflare) -> None: + basin_catalog = client.basin_catalog.enable( + bucket_name="my-data-bucket", + account_id="0123456789abcdef0123456789abcdef", + credential={"token": "your-cloudflare-api-token-here"}, + ) + assert_matches_type(Optional[BasinCatalogEnableResponse], basin_catalog, path=["response"]) + @parametrize def test_raw_response_enable(self, client: Cloudflare) -> None: response = client.basin_catalog.with_raw_response.enable( @@ -417,6 +426,15 @@ async def test_method_enable(self, async_client: AsyncCloudflare) -> None: ) assert_matches_type(Optional[BasinCatalogEnableResponse], basin_catalog, path=["response"]) + @parametrize + async def test_method_enable_with_all_params(self, async_client: AsyncCloudflare) -> None: + basin_catalog = await async_client.basin_catalog.enable( + bucket_name="my-data-bucket", + account_id="0123456789abcdef0123456789abcdef", + credential={"token": "your-cloudflare-api-token-here"}, + ) + assert_matches_type(Optional[BasinCatalogEnableResponse], basin_catalog, path=["response"]) + @parametrize async def test_raw_response_enable(self, async_client: AsyncCloudflare) -> None: response = await async_client.basin_catalog.with_raw_response.enable( diff --git a/tests/api_resources/test_bot_management.py b/tests/api_resources/test_bot_management.py index 826b1294c5a..b1db6023c5f 100644 --- a/tests/api_resources/test_bot_management.py +++ b/tests/api_resources/test_bot_management.py @@ -31,6 +31,13 @@ def test_method_update_overload_1(self, client: Cloudflare) -> None: def test_method_update_with_all_params_overload_1(self, client: Cloudflare) -> None: bot_management = client.bot_management.update( zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ai_agents={ + "anthropic_agent": "block", + "google_agent": "block", + "instinct": "block", + "muse": "block", + "openai_agent": "block", + }, ai_bots_migration_opt_out=False, ai_bots_protection="block", aisearch="block", @@ -89,6 +96,13 @@ def test_method_update_overload_2(self, client: Cloudflare) -> None: def test_method_update_with_all_params_overload_2(self, client: Cloudflare) -> None: bot_management = client.bot_management.update( zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ai_agents={ + "anthropic_agent": "block", + "google_agent": "block", + "instinct": "block", + "muse": "block", + "openai_agent": "block", + }, ai_bots_migration_opt_out=False, ai_bots_protection="block", aisearch="block", @@ -150,6 +164,13 @@ def test_method_update_overload_3(self, client: Cloudflare) -> None: def test_method_update_with_all_params_overload_3(self, client: Cloudflare) -> None: bot_management = client.bot_management.update( zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ai_agents={ + "anthropic_agent": "block", + "google_agent": "block", + "instinct": "block", + "muse": "block", + "openai_agent": "block", + }, ai_bots_migration_opt_out=False, ai_bots_protection="block", aisearch="block", @@ -212,6 +233,13 @@ def test_method_update_overload_4(self, client: Cloudflare) -> None: def test_method_update_with_all_params_overload_4(self, client: Cloudflare) -> None: bot_management = client.bot_management.update( zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ai_agents={ + "anthropic_agent": "block", + "google_agent": "block", + "instinct": "block", + "muse": "block", + "openai_agent": "block", + }, ai_bots_migration_opt_out=False, ai_bots_protection="block", aisearch="block", @@ -316,6 +344,13 @@ async def test_method_update_overload_1(self, async_client: AsyncCloudflare) -> async def test_method_update_with_all_params_overload_1(self, async_client: AsyncCloudflare) -> None: bot_management = await async_client.bot_management.update( zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ai_agents={ + "anthropic_agent": "block", + "google_agent": "block", + "instinct": "block", + "muse": "block", + "openai_agent": "block", + }, ai_bots_migration_opt_out=False, ai_bots_protection="block", aisearch="block", @@ -374,6 +409,13 @@ async def test_method_update_overload_2(self, async_client: AsyncCloudflare) -> async def test_method_update_with_all_params_overload_2(self, async_client: AsyncCloudflare) -> None: bot_management = await async_client.bot_management.update( zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ai_agents={ + "anthropic_agent": "block", + "google_agent": "block", + "instinct": "block", + "muse": "block", + "openai_agent": "block", + }, ai_bots_migration_opt_out=False, ai_bots_protection="block", aisearch="block", @@ -435,6 +477,13 @@ async def test_method_update_overload_3(self, async_client: AsyncCloudflare) -> async def test_method_update_with_all_params_overload_3(self, async_client: AsyncCloudflare) -> None: bot_management = await async_client.bot_management.update( zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ai_agents={ + "anthropic_agent": "block", + "google_agent": "block", + "instinct": "block", + "muse": "block", + "openai_agent": "block", + }, ai_bots_migration_opt_out=False, ai_bots_protection="block", aisearch="block", @@ -497,6 +546,13 @@ async def test_method_update_overload_4(self, async_client: AsyncCloudflare) -> async def test_method_update_with_all_params_overload_4(self, async_client: AsyncCloudflare) -> None: bot_management = await async_client.bot_management.update( zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ai_agents={ + "anthropic_agent": "block", + "google_agent": "block", + "instinct": "block", + "muse": "block", + "openai_agent": "block", + }, ai_bots_migration_opt_out=False, ai_bots_protection="block", aisearch="block", diff --git a/tests/api_resources/test_load_balancers.py b/tests/api_resources/test_load_balancers.py index cb1ad0ba577..6133e6beac3 100644 --- a/tests/api_resources/test_load_balancers.py +++ b/tests/api_resources/test_load_balancers.py @@ -57,7 +57,37 @@ def test_method_create_with_all_params(self, client: Cloudflare) -> None: "mode": "resolver_ip", "prefer_ecs": "always", }, - networks=["string"], + networks=["cloudflare", "jdcloud"], + pool_sets=[ + { + "disabled": True, + "fixed_response": { + "content_type": "application/json", + "location": "www.example.com", + "message_body": "Testing Hello", + "status_code": 0, + }, + "match": { + "default": True, + "topology": { + "countries": ["string"], + "pops": ["string"], + "regions": ["WNAM"], + }, + }, + "name": "wnam-primary", + "overrides": { + "fallback_pool": "9290f38c5d07c2e2f4df57b1f61d4196", + "pool_default_weight": 0.2, + "pool_weights": { + "9290f38c5d07c2e2f4df57b1f61d4196": 0.5, + "de90f38ced07c2e2f4df50b1f61d4194": 0.3, + }, + "pools": ["17b5962d775c646f3f9725cbc7a53df4"], + "steering_policy": "random", + }, + } + ], pop_pools={ "LAX": ["de90f38ced07c2e2f4df50b1f61d4194", "9290f38c5d07c2e2f4df57b1f61d4196"], "LHR": ["abd90f38ced07c2e2f4df50b1f61d4194", "f9138c5d07c2e2f4df57b1f61d4196"], @@ -258,7 +288,37 @@ def test_method_update_with_all_params(self, client: Cloudflare) -> None: "mode": "resolver_ip", "prefer_ecs": "always", }, - networks=["string"], + networks=["cloudflare", "jdcloud"], + pool_sets=[ + { + "disabled": True, + "fixed_response": { + "content_type": "application/json", + "location": "www.example.com", + "message_body": "Testing Hello", + "status_code": 0, + }, + "match": { + "default": True, + "topology": { + "countries": ["string"], + "pops": ["string"], + "regions": ["WNAM"], + }, + }, + "name": "wnam-primary", + "overrides": { + "fallback_pool": "9290f38c5d07c2e2f4df57b1f61d4196", + "pool_default_weight": 0.2, + "pool_weights": { + "9290f38c5d07c2e2f4df57b1f61d4196": 0.5, + "de90f38ced07c2e2f4df50b1f61d4194": 0.3, + }, + "pools": ["17b5962d775c646f3f9725cbc7a53df4"], + "steering_policy": "random", + }, + } + ], pop_pools={ "LAX": ["de90f38ced07c2e2f4df50b1f61d4194", "9290f38c5d07c2e2f4df57b1f61d4196"], "LHR": ["abd90f38ced07c2e2f4df50b1f61d4194", "f9138c5d07c2e2f4df57b1f61d4196"], @@ -581,7 +641,37 @@ def test_method_edit_with_all_params(self, client: Cloudflare) -> None: "prefer_ecs": "always", }, name="www.example.com", - networks=["string"], + networks=["cloudflare", "jdcloud"], + pool_sets=[ + { + "disabled": True, + "fixed_response": { + "content_type": "application/json", + "location": "www.example.com", + "message_body": "Testing Hello", + "status_code": 0, + }, + "match": { + "default": True, + "topology": { + "countries": ["string"], + "pops": ["string"], + "regions": ["WNAM"], + }, + }, + "name": "wnam-primary", + "overrides": { + "fallback_pool": "9290f38c5d07c2e2f4df57b1f61d4196", + "pool_default_weight": 0.2, + "pool_weights": { + "9290f38c5d07c2e2f4df57b1f61d4196": 0.5, + "de90f38ced07c2e2f4df50b1f61d4194": 0.3, + }, + "pools": ["17b5962d775c646f3f9725cbc7a53df4"], + "steering_policy": "random", + }, + } + ], pop_pools={ "LAX": ["de90f38ced07c2e2f4df50b1f61d4194", "9290f38c5d07c2e2f4df57b1f61d4196"], "LHR": ["abd90f38ced07c2e2f4df50b1f61d4194", "f9138c5d07c2e2f4df57b1f61d4196"], @@ -830,7 +920,37 @@ async def test_method_create_with_all_params(self, async_client: AsyncCloudflare "mode": "resolver_ip", "prefer_ecs": "always", }, - networks=["string"], + networks=["cloudflare", "jdcloud"], + pool_sets=[ + { + "disabled": True, + "fixed_response": { + "content_type": "application/json", + "location": "www.example.com", + "message_body": "Testing Hello", + "status_code": 0, + }, + "match": { + "default": True, + "topology": { + "countries": ["string"], + "pops": ["string"], + "regions": ["WNAM"], + }, + }, + "name": "wnam-primary", + "overrides": { + "fallback_pool": "9290f38c5d07c2e2f4df57b1f61d4196", + "pool_default_weight": 0.2, + "pool_weights": { + "9290f38c5d07c2e2f4df57b1f61d4196": 0.5, + "de90f38ced07c2e2f4df50b1f61d4194": 0.3, + }, + "pools": ["17b5962d775c646f3f9725cbc7a53df4"], + "steering_policy": "random", + }, + } + ], pop_pools={ "LAX": ["de90f38ced07c2e2f4df50b1f61d4194", "9290f38c5d07c2e2f4df57b1f61d4196"], "LHR": ["abd90f38ced07c2e2f4df50b1f61d4194", "f9138c5d07c2e2f4df57b1f61d4196"], @@ -1031,7 +1151,37 @@ async def test_method_update_with_all_params(self, async_client: AsyncCloudflare "mode": "resolver_ip", "prefer_ecs": "always", }, - networks=["string"], + networks=["cloudflare", "jdcloud"], + pool_sets=[ + { + "disabled": True, + "fixed_response": { + "content_type": "application/json", + "location": "www.example.com", + "message_body": "Testing Hello", + "status_code": 0, + }, + "match": { + "default": True, + "topology": { + "countries": ["string"], + "pops": ["string"], + "regions": ["WNAM"], + }, + }, + "name": "wnam-primary", + "overrides": { + "fallback_pool": "9290f38c5d07c2e2f4df57b1f61d4196", + "pool_default_weight": 0.2, + "pool_weights": { + "9290f38c5d07c2e2f4df57b1f61d4196": 0.5, + "de90f38ced07c2e2f4df50b1f61d4194": 0.3, + }, + "pools": ["17b5962d775c646f3f9725cbc7a53df4"], + "steering_policy": "random", + }, + } + ], pop_pools={ "LAX": ["de90f38ced07c2e2f4df50b1f61d4194", "9290f38c5d07c2e2f4df57b1f61d4196"], "LHR": ["abd90f38ced07c2e2f4df50b1f61d4194", "f9138c5d07c2e2f4df57b1f61d4196"], @@ -1354,7 +1504,37 @@ async def test_method_edit_with_all_params(self, async_client: AsyncCloudflare) "prefer_ecs": "always", }, name="www.example.com", - networks=["string"], + networks=["cloudflare", "jdcloud"], + pool_sets=[ + { + "disabled": True, + "fixed_response": { + "content_type": "application/json", + "location": "www.example.com", + "message_body": "Testing Hello", + "status_code": 0, + }, + "match": { + "default": True, + "topology": { + "countries": ["string"], + "pops": ["string"], + "regions": ["WNAM"], + }, + }, + "name": "wnam-primary", + "overrides": { + "fallback_pool": "9290f38c5d07c2e2f4df57b1f61d4196", + "pool_default_weight": 0.2, + "pool_weights": { + "9290f38c5d07c2e2f4df57b1f61d4196": 0.5, + "de90f38ced07c2e2f4df50b1f61d4194": 0.3, + }, + "pools": ["17b5962d775c646f3f9725cbc7a53df4"], + "steering_policy": "random", + }, + } + ], pop_pools={ "LAX": ["de90f38ced07c2e2f4df50b1f61d4194", "9290f38c5d07c2e2f4df57b1f61d4196"], "LHR": ["abd90f38ced07c2e2f4df50b1f61d4194", "f9138c5d07c2e2f4df57b1f61d4196"], diff --git a/tests/api_resources/test_organizations.py b/tests/api_resources/test_organizations.py index 1eff0bf1acf..340711c5a16 100644 --- a/tests/api_resources/test_organizations.py +++ b/tests/api_resources/test_organizations.py @@ -24,14 +24,14 @@ class TestOrganizations: @parametrize def test_method_create(self, client: Cloudflare) -> None: organization = client.organizations.create( - name="name", + name="x", ) assert_matches_type(Organization, organization, path=["response"]) @parametrize def test_method_create_with_all_params(self, client: Cloudflare) -> None: organization = client.organizations.create( - name="name", + name="x", parent={"id": "a7b9c3d2e8f4a1b5c6d0e9f2a3b7c4d8"}, profile={ "business_address": "business_address", @@ -46,7 +46,7 @@ def test_method_create_with_all_params(self, client: Cloudflare) -> None: @parametrize def test_raw_response_create(self, client: Cloudflare) -> None: response = client.organizations.with_raw_response.create( - name="name", + name="x", ) assert response.is_closed is True @@ -57,7 +57,7 @@ def test_raw_response_create(self, client: Cloudflare) -> None: @parametrize def test_streaming_response_create(self, client: Cloudflare) -> None: with client.organizations.with_streaming_response.create( - name="name", + name="x", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -71,7 +71,6 @@ def test_streaming_response_create(self, client: Cloudflare) -> None: def test_method_update(self, client: Cloudflare) -> None: organization = client.organizations.update( organization_id="a7b9c3d2e8f4a1b5c6d0e9f2a3b7c4d8", - name="name", ) assert_matches_type(Organization, organization, path=["response"]) @@ -80,14 +79,7 @@ def test_method_update_with_all_params(self, client: Cloudflare) -> None: organization = client.organizations.update( organization_id="a7b9c3d2e8f4a1b5c6d0e9f2a3b7c4d8", name="name", - parent={"id": "a7b9c3d2e8f4a1b5c6d0e9f2a3b7c4d8"}, - profile={ - "business_address": "business_address", - "business_email": "business_email", - "business_name": "business_name", - "business_phone": "business_phone", - "external_metadata": "external_metadata", - }, + parent_id="a7b9c3d2e8f4a1b5c6d0e9f2a3b7c4d8", ) assert_matches_type(Organization, organization, path=["response"]) @@ -95,7 +87,6 @@ def test_method_update_with_all_params(self, client: Cloudflare) -> None: def test_raw_response_update(self, client: Cloudflare) -> None: response = client.organizations.with_raw_response.update( organization_id="a7b9c3d2e8f4a1b5c6d0e9f2a3b7c4d8", - name="name", ) assert response.is_closed is True @@ -107,7 +98,6 @@ def test_raw_response_update(self, client: Cloudflare) -> None: def test_streaming_response_update(self, client: Cloudflare) -> None: with client.organizations.with_streaming_response.update( organization_id="a7b9c3d2e8f4a1b5c6d0e9f2a3b7c4d8", - name="name", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -122,7 +112,6 @@ def test_path_params_update(self, client: Cloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `organization_id` but received ''"): client.organizations.with_raw_response.update( organization_id="", - name="name", ) @parametrize @@ -139,11 +128,14 @@ def test_method_list_with_all_params(self, client: Cloudflare) -> None: "organization": "organization", "user": "user", }, + direction="asc", + member={"email": "email"}, name={ "contains": "contains", "ends_with": "endsWith", "starts_with": "startsWith", }, + order_by="name", page_size=0, page_token="page_token", parent={"id": "a7b9c3d2e8f4a1b5c6d0e9f2a3b7c4d8"}, @@ -255,14 +247,14 @@ class TestAsyncOrganizations: @parametrize async def test_method_create(self, async_client: AsyncCloudflare) -> None: organization = await async_client.organizations.create( - name="name", + name="x", ) assert_matches_type(Organization, organization, path=["response"]) @parametrize async def test_method_create_with_all_params(self, async_client: AsyncCloudflare) -> None: organization = await async_client.organizations.create( - name="name", + name="x", parent={"id": "a7b9c3d2e8f4a1b5c6d0e9f2a3b7c4d8"}, profile={ "business_address": "business_address", @@ -277,7 +269,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncCloudflare @parametrize async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None: response = await async_client.organizations.with_raw_response.create( - name="name", + name="x", ) assert response.is_closed is True @@ -288,7 +280,7 @@ async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None: @parametrize async def test_streaming_response_create(self, async_client: AsyncCloudflare) -> None: async with async_client.organizations.with_streaming_response.create( - name="name", + name="x", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -302,7 +294,6 @@ async def test_streaming_response_create(self, async_client: AsyncCloudflare) -> async def test_method_update(self, async_client: AsyncCloudflare) -> None: organization = await async_client.organizations.update( organization_id="a7b9c3d2e8f4a1b5c6d0e9f2a3b7c4d8", - name="name", ) assert_matches_type(Organization, organization, path=["response"]) @@ -311,14 +302,7 @@ async def test_method_update_with_all_params(self, async_client: AsyncCloudflare organization = await async_client.organizations.update( organization_id="a7b9c3d2e8f4a1b5c6d0e9f2a3b7c4d8", name="name", - parent={"id": "a7b9c3d2e8f4a1b5c6d0e9f2a3b7c4d8"}, - profile={ - "business_address": "business_address", - "business_email": "business_email", - "business_name": "business_name", - "business_phone": "business_phone", - "external_metadata": "external_metadata", - }, + parent_id="a7b9c3d2e8f4a1b5c6d0e9f2a3b7c4d8", ) assert_matches_type(Organization, organization, path=["response"]) @@ -326,7 +310,6 @@ async def test_method_update_with_all_params(self, async_client: AsyncCloudflare async def test_raw_response_update(self, async_client: AsyncCloudflare) -> None: response = await async_client.organizations.with_raw_response.update( organization_id="a7b9c3d2e8f4a1b5c6d0e9f2a3b7c4d8", - name="name", ) assert response.is_closed is True @@ -338,7 +321,6 @@ async def test_raw_response_update(self, async_client: AsyncCloudflare) -> None: async def test_streaming_response_update(self, async_client: AsyncCloudflare) -> None: async with async_client.organizations.with_streaming_response.update( organization_id="a7b9c3d2e8f4a1b5c6d0e9f2a3b7c4d8", - name="name", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -353,7 +335,6 @@ async def test_path_params_update(self, async_client: AsyncCloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `organization_id` but received ''"): await async_client.organizations.with_raw_response.update( organization_id="", - name="name", ) @parametrize @@ -370,11 +351,14 @@ async def test_method_list_with_all_params(self, async_client: AsyncCloudflare) "organization": "organization", "user": "user", }, + direction="asc", + member={"email": "email"}, name={ "contains": "contains", "ends_with": "endsWith", "starts_with": "startsWith", }, + order_by="name", page_size=0, page_token="page_token", parent={"id": "a7b9c3d2e8f4a1b5c6d0e9f2a3b7c4d8"}, diff --git a/tests/api_resources/test_precursor.py b/tests/api_resources/test_precursor.py index e5cb0f3fe51..2cdda133da5 100644 --- a/tests/api_resources/test_precursor.py +++ b/tests/api_resources/test_precursor.py @@ -28,15 +28,17 @@ def test_method_update(self, client: Cloudflare) -> None: def test_method_update_with_all_params(self, client: Cloudflare) -> None: precursor = client.precursor.update( zone_id="023e105f4ecef8ad9ca31a8372d0c353", - default_mode="min-friction", - enforcement_rules=[ + cloudflare_version="1.0", + mode="monitor", + rules=[ { "expression": 'http.request.uri.path eq "/login"', - "mode": "max-security", - "description": "Ease friction on the login path", + "show_interstitial": True, + "description": "Show an interstitial on the login path", "enabled": True, } ], + show_interstitial=True, ) assert_matches_type(Optional[PrecursorConfig], precursor, path=["response"]) @@ -126,15 +128,17 @@ async def test_method_update(self, async_client: AsyncCloudflare) -> None: async def test_method_update_with_all_params(self, async_client: AsyncCloudflare) -> None: precursor = await async_client.precursor.update( zone_id="023e105f4ecef8ad9ca31a8372d0c353", - default_mode="min-friction", - enforcement_rules=[ + cloudflare_version="1.0", + mode="monitor", + rules=[ { "expression": 'http.request.uri.path eq "/login"', - "mode": "max-security", - "description": "Ease friction on the login path", + "show_interstitial": True, + "description": "Show an interstitial on the login path", "enabled": True, } ], + show_interstitial=True, ) assert_matches_type(Optional[PrecursorConfig], precursor, path=["response"]) diff --git a/tests/api_resources/test_r2_data_catalog.py b/tests/api_resources/test_r2_data_catalog.py index d85d83ebd21..b3da1f6d576 100644 --- a/tests/api_resources/test_r2_data_catalog.py +++ b/tests/api_resources/test_r2_data_catalog.py @@ -193,6 +193,17 @@ def test_method_enable(self, client: Cloudflare) -> None: assert_matches_type(Optional[R2DataCatalogEnableResponse], r2_data_catalog, path=["response"]) + @parametrize + def test_method_enable_with_all_params(self, client: Cloudflare) -> None: + with pytest.warns(DeprecationWarning): + r2_data_catalog = client.r2_data_catalog.enable( + bucket_name="my-data-bucket", + account_id="0123456789abcdef0123456789abcdef", + credential={"token": "your-cloudflare-api-token-here"}, + ) + + assert_matches_type(Optional[R2DataCatalogEnableResponse], r2_data_catalog, path=["response"]) + @parametrize def test_raw_response_enable(self, client: Cloudflare) -> None: with pytest.warns(DeprecationWarning): @@ -465,6 +476,17 @@ async def test_method_enable(self, async_client: AsyncCloudflare) -> None: assert_matches_type(Optional[R2DataCatalogEnableResponse], r2_data_catalog, path=["response"]) + @parametrize + async def test_method_enable_with_all_params(self, async_client: AsyncCloudflare) -> None: + with pytest.warns(DeprecationWarning): + r2_data_catalog = await async_client.r2_data_catalog.enable( + bucket_name="my-data-bucket", + account_id="0123456789abcdef0123456789abcdef", + credential={"token": "your-cloudflare-api-token-here"}, + ) + + assert_matches_type(Optional[R2DataCatalogEnableResponse], r2_data_catalog, path=["response"]) + @parametrize async def test_raw_response_enable(self, async_client: AsyncCloudflare) -> None: with pytest.warns(DeprecationWarning): diff --git a/tests/api_resources/test_resource_sharing.py b/tests/api_resources/test_resource_sharing.py index c6f74647ef4..fbe17ee5b23 100644 --- a/tests/api_resources/test_resource_sharing.py +++ b/tests/api_resources/test_resource_sharing.py @@ -29,15 +29,31 @@ def test_method_create(self, client: Cloudflare) -> None: resource_sharing = client.resource_sharing.create( account_id="023e105f4ecef8ad9ca31a8372d0c353", name="My Shared WAF Managed Rule", - recipients=[{}], + ) + assert_matches_type(Optional[ResourceSharingCreateResponse], resource_sharing, path=["response"]) + + @parametrize + def test_method_create_with_all_params(self, client: Cloudflare) -> None: + resource_sharing = client.resource_sharing.create( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + name="My Shared WAF Managed Rule", + excluded_recipients=[{"account_id": "023e105f4ecef8ad9ca31a8372d0c353"}], + recipients=[ + { + "account_id": "023e105f4ecef8ad9ca31a8372d0c353", + "organization_id": "023e105f4ecef8ad9ca31a8372d0c353", + "recipient_account_id": "023e105f4ecef8ad9ca31a8372d0c353", + } + ], resources=[ { "meta": {}, "resource_account_id": "023e105f4ecef8ad9ca31a8372d0c353", - "resource_id": "023e105f4ecef8ad9ca31a8372d0c353", + "resource_id": "0a679032-bbb2-4b7e-9acc-dd5c5cb27a17", "resource_type": "custom-ruleset", } ], + tags={"foo": "string"}, ) assert_matches_type(Optional[ResourceSharingCreateResponse], resource_sharing, path=["response"]) @@ -46,15 +62,6 @@ def test_raw_response_create(self, client: Cloudflare) -> None: response = client.resource_sharing.with_raw_response.create( account_id="023e105f4ecef8ad9ca31a8372d0c353", name="My Shared WAF Managed Rule", - recipients=[{}], - resources=[ - { - "meta": {}, - "resource_account_id": "023e105f4ecef8ad9ca31a8372d0c353", - "resource_id": "023e105f4ecef8ad9ca31a8372d0c353", - "resource_type": "custom-ruleset", - } - ], ) assert response.is_closed is True @@ -67,15 +74,6 @@ def test_streaming_response_create(self, client: Cloudflare) -> None: with client.resource_sharing.with_streaming_response.create( account_id="023e105f4ecef8ad9ca31a8372d0c353", name="My Shared WAF Managed Rule", - recipients=[{}], - resources=[ - { - "meta": {}, - "resource_account_id": "023e105f4ecef8ad9ca31a8372d0c353", - "resource_id": "023e105f4ecef8ad9ca31a8372d0c353", - "resource_type": "custom-ruleset", - } - ], ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -91,15 +89,6 @@ def test_path_params_create(self, client: Cloudflare) -> None: client.resource_sharing.with_raw_response.create( account_id="", name="My Shared WAF Managed Rule", - recipients=[{}], - resources=[ - { - "meta": {}, - "resource_account_id": "023e105f4ecef8ad9ca31a8372d0c353", - "resource_id": "023e105f4ecef8ad9ca31a8372d0c353", - "resource_type": "custom-ruleset", - } - ], ) @parametrize @@ -111,6 +100,16 @@ def test_method_update(self, client: Cloudflare) -> None: ) assert_matches_type(Optional[ResourceSharingUpdateResponse], resource_sharing, path=["response"]) + @parametrize + def test_method_update_with_all_params(self, client: Cloudflare) -> None: + resource_sharing = client.resource_sharing.update( + share_id="3fd85f74b32742f1bff64a85009dda07", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + name="My Shared WAF Managed Rule", + tags={"foo": "string"}, + ) + assert_matches_type(Optional[ResourceSharingUpdateResponse], resource_sharing, path=["response"]) + @parametrize def test_raw_response_update(self, client: Cloudflare) -> None: response = client.resource_sharing.with_raw_response.update( @@ -169,6 +168,7 @@ def test_method_list_with_all_params(self, client: Cloudflare) -> None: direction="asc", include_recipient_counts=True, include_resources=True, + include_tags_from="api", kind="sent", order="name", page=2, @@ -276,6 +276,7 @@ def test_method_get_with_all_params(self, client: Cloudflare) -> None: account_id="023e105f4ecef8ad9ca31a8372d0c353", include_recipient_counts=True, include_resources=True, + include_tags_from="api", ) assert_matches_type(Optional[ResourceSharingGetResponse], resource_sharing, path=["response"]) @@ -330,15 +331,31 @@ async def test_method_create(self, async_client: AsyncCloudflare) -> None: resource_sharing = await async_client.resource_sharing.create( account_id="023e105f4ecef8ad9ca31a8372d0c353", name="My Shared WAF Managed Rule", - recipients=[{}], + ) + assert_matches_type(Optional[ResourceSharingCreateResponse], resource_sharing, path=["response"]) + + @parametrize + async def test_method_create_with_all_params(self, async_client: AsyncCloudflare) -> None: + resource_sharing = await async_client.resource_sharing.create( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + name="My Shared WAF Managed Rule", + excluded_recipients=[{"account_id": "023e105f4ecef8ad9ca31a8372d0c353"}], + recipients=[ + { + "account_id": "023e105f4ecef8ad9ca31a8372d0c353", + "organization_id": "023e105f4ecef8ad9ca31a8372d0c353", + "recipient_account_id": "023e105f4ecef8ad9ca31a8372d0c353", + } + ], resources=[ { "meta": {}, "resource_account_id": "023e105f4ecef8ad9ca31a8372d0c353", - "resource_id": "023e105f4ecef8ad9ca31a8372d0c353", + "resource_id": "0a679032-bbb2-4b7e-9acc-dd5c5cb27a17", "resource_type": "custom-ruleset", } ], + tags={"foo": "string"}, ) assert_matches_type(Optional[ResourceSharingCreateResponse], resource_sharing, path=["response"]) @@ -347,15 +364,6 @@ async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None: response = await async_client.resource_sharing.with_raw_response.create( account_id="023e105f4ecef8ad9ca31a8372d0c353", name="My Shared WAF Managed Rule", - recipients=[{}], - resources=[ - { - "meta": {}, - "resource_account_id": "023e105f4ecef8ad9ca31a8372d0c353", - "resource_id": "023e105f4ecef8ad9ca31a8372d0c353", - "resource_type": "custom-ruleset", - } - ], ) assert response.is_closed is True @@ -368,15 +376,6 @@ async def test_streaming_response_create(self, async_client: AsyncCloudflare) -> async with async_client.resource_sharing.with_streaming_response.create( account_id="023e105f4ecef8ad9ca31a8372d0c353", name="My Shared WAF Managed Rule", - recipients=[{}], - resources=[ - { - "meta": {}, - "resource_account_id": "023e105f4ecef8ad9ca31a8372d0c353", - "resource_id": "023e105f4ecef8ad9ca31a8372d0c353", - "resource_type": "custom-ruleset", - } - ], ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -392,15 +391,6 @@ async def test_path_params_create(self, async_client: AsyncCloudflare) -> None: await async_client.resource_sharing.with_raw_response.create( account_id="", name="My Shared WAF Managed Rule", - recipients=[{}], - resources=[ - { - "meta": {}, - "resource_account_id": "023e105f4ecef8ad9ca31a8372d0c353", - "resource_id": "023e105f4ecef8ad9ca31a8372d0c353", - "resource_type": "custom-ruleset", - } - ], ) @parametrize @@ -412,6 +402,16 @@ async def test_method_update(self, async_client: AsyncCloudflare) -> None: ) assert_matches_type(Optional[ResourceSharingUpdateResponse], resource_sharing, path=["response"]) + @parametrize + async def test_method_update_with_all_params(self, async_client: AsyncCloudflare) -> None: + resource_sharing = await async_client.resource_sharing.update( + share_id="3fd85f74b32742f1bff64a85009dda07", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + name="My Shared WAF Managed Rule", + tags={"foo": "string"}, + ) + assert_matches_type(Optional[ResourceSharingUpdateResponse], resource_sharing, path=["response"]) + @parametrize async def test_raw_response_update(self, async_client: AsyncCloudflare) -> None: response = await async_client.resource_sharing.with_raw_response.update( @@ -472,6 +472,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncCloudflare) direction="asc", include_recipient_counts=True, include_resources=True, + include_tags_from="api", kind="sent", order="name", page=2, @@ -583,6 +584,7 @@ async def test_method_get_with_all_params(self, async_client: AsyncCloudflare) - account_id="023e105f4ecef8ad9ca31a8372d0c353", include_recipient_counts=True, include_resources=True, + include_tags_from="api", ) assert_matches_type(Optional[ResourceSharingGetResponse], resource_sharing, path=["response"]) diff --git a/tests/api_resources/test_resource_tagging.py b/tests/api_resources/test_resource_tagging.py index 9593dacdeb3..574ad58e398 100644 --- a/tests/api_resources/test_resource_tagging.py +++ b/tests/api_resources/test_resource_tagging.py @@ -32,6 +32,7 @@ def test_method_list_with_all_params(self, client: Cloudflare) -> None: id=["023e105f4ecef8ad9ca31a8372d0c353"], case_insensitive=True, cursor="eyJhY2NvdW50X2lkIjoxMjM0NTY3ODkwfQ", + include_navigation=True, name="name", tag=["production", "env=prod", "env=prod,staging", "!archived", "region!=us-west-1"], type=["zone"], @@ -93,6 +94,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncCloudflare) id=["023e105f4ecef8ad9ca31a8372d0c353"], case_insensitive=True, cursor="eyJhY2NvdW50X2lkIjoxMjM0NTY3ODkwfQ", + include_navigation=True, name="name", tag=["production", "env=prod", "env=prod,staging", "!archived", "region!=us-west-1"], type=["zone"], diff --git a/tests/api_resources/test_rulesets.py b/tests/api_resources/test_rulesets.py index 5e9a7c2dfc7..3d05fdad7ee 100644 --- a/tests/api_resources/test_rulesets.py +++ b/tests/api_resources/test_rulesets.py @@ -9,7 +9,6 @@ from cloudflare import Cloudflare, AsyncCloudflare from tests.utils import assert_matches_type -from cloudflare.pagination import SyncCursorPagination, AsyncCursorPagination from cloudflare.types.rulesets import ( RulesetGetResponse, RulesetListResponse, @@ -225,7 +224,7 @@ def test_method_list(self, client: Cloudflare) -> None: ruleset = client.rulesets.list( account_id="account_id", ) - assert_matches_type(SyncCursorPagination[RulesetListResponse], ruleset, path=["response"]) + assert_matches_type(RulesetListResponse, ruleset, path=["response"]) @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize @@ -235,7 +234,7 @@ def test_method_list_with_all_params(self, client: Cloudflare) -> None: cursor="dGhpc2lzYW5leGFtcGxlCg", per_page=3, ) - assert_matches_type(SyncCursorPagination[RulesetListResponse], ruleset, path=["response"]) + assert_matches_type(RulesetListResponse, ruleset, path=["response"]) @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize @@ -247,7 +246,7 @@ def test_raw_response_list(self, client: Cloudflare) -> None: assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" ruleset = response.parse() - assert_matches_type(SyncCursorPagination[RulesetListResponse], ruleset, path=["response"]) + assert_matches_type(RulesetListResponse, ruleset, path=["response"]) @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize @@ -259,7 +258,7 @@ def test_streaming_response_list(self, client: Cloudflare) -> None: assert response.http_request.headers.get("X-Stainless-Lang") == "python" ruleset = response.parse() - assert_matches_type(SyncCursorPagination[RulesetListResponse], ruleset, path=["response"]) + assert_matches_type(RulesetListResponse, ruleset, path=["response"]) assert cast(Any, response.is_closed) is True @@ -619,7 +618,7 @@ async def test_method_list(self, async_client: AsyncCloudflare) -> None: ruleset = await async_client.rulesets.list( account_id="account_id", ) - assert_matches_type(AsyncCursorPagination[RulesetListResponse], ruleset, path=["response"]) + assert_matches_type(RulesetListResponse, ruleset, path=["response"]) @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize @@ -629,7 +628,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncCloudflare) cursor="dGhpc2lzYW5leGFtcGxlCg", per_page=3, ) - assert_matches_type(AsyncCursorPagination[RulesetListResponse], ruleset, path=["response"]) + assert_matches_type(RulesetListResponse, ruleset, path=["response"]) @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize @@ -641,7 +640,7 @@ async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None: assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" ruleset = await response.parse() - assert_matches_type(AsyncCursorPagination[RulesetListResponse], ruleset, path=["response"]) + assert_matches_type(RulesetListResponse, ruleset, path=["response"]) @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize @@ -653,7 +652,7 @@ async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> N assert response.http_request.headers.get("X-Stainless-Lang") == "python" ruleset = await response.parse() - assert_matches_type(AsyncCursorPagination[RulesetListResponse], ruleset, path=["response"]) + assert_matches_type(RulesetListResponse, ruleset, path=["response"]) assert cast(Any, response.is_closed) is True diff --git a/tests/api_resources/test_tenant_custom_nameservers.py b/tests/api_resources/test_tenant_custom_nameservers.py deleted file mode 100644 index 83dd4f7fdd1..00000000000 --- a/tests/api_resources/test_tenant_custom_nameservers.py +++ /dev/null @@ -1,331 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -import os -from typing import Any, Optional, cast - -import pytest - -from cloudflare import Cloudflare, AsyncCloudflare -from tests.utils import assert_matches_type -from cloudflare.pagination import SyncSinglePage, AsyncSinglePage -from cloudflare.types.tenant_custom_nameservers import ( - TenantCustomNameserverGetResponse, - TenantCustomNameserverCreateResponse, - TenantCustomNameserverDeleteResponse, -) - -base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") - - -class TestTenantCustomNameservers: - parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) - - @parametrize - def test_method_create(self, client: Cloudflare) -> None: - tenant_custom_nameserver = client.tenant_custom_nameservers.create( - tenant_tag="699d98642c564d2e855e9661899b7252", - ns_name="ns1.example.com", - ) - assert_matches_type(Optional[TenantCustomNameserverCreateResponse], tenant_custom_nameserver, path=["response"]) - - @parametrize - def test_method_create_with_all_params(self, client: Cloudflare) -> None: - tenant_custom_nameserver = client.tenant_custom_nameservers.create( - tenant_tag="699d98642c564d2e855e9661899b7252", - ns_name="ns1.example.com", - ns_set=1, - ) - assert_matches_type(Optional[TenantCustomNameserverCreateResponse], tenant_custom_nameserver, path=["response"]) - - @parametrize - def test_raw_response_create(self, client: Cloudflare) -> None: - response = client.tenant_custom_nameservers.with_raw_response.create( - tenant_tag="699d98642c564d2e855e9661899b7252", - ns_name="ns1.example.com", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - tenant_custom_nameserver = response.parse() - assert_matches_type(Optional[TenantCustomNameserverCreateResponse], tenant_custom_nameserver, path=["response"]) - - @parametrize - def test_streaming_response_create(self, client: Cloudflare) -> None: - with client.tenant_custom_nameservers.with_streaming_response.create( - tenant_tag="699d98642c564d2e855e9661899b7252", - ns_name="ns1.example.com", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - tenant_custom_nameserver = response.parse() - assert_matches_type( - Optional[TenantCustomNameserverCreateResponse], tenant_custom_nameserver, path=["response"] - ) - - assert cast(Any, response.is_closed) is True - - @parametrize - def test_path_params_create(self, client: Cloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `tenant_tag` but received ''"): - client.tenant_custom_nameservers.with_raw_response.create( - tenant_tag="", - ns_name="ns1.example.com", - ) - - @parametrize - def test_method_delete(self, client: Cloudflare) -> None: - tenant_custom_nameserver = client.tenant_custom_nameservers.delete( - custom_ns_id="ns1.example.com", - tenant_tag="699d98642c564d2e855e9661899b7252", - ) - assert_matches_type( - SyncSinglePage[TenantCustomNameserverDeleteResponse], tenant_custom_nameserver, path=["response"] - ) - - @parametrize - def test_raw_response_delete(self, client: Cloudflare) -> None: - response = client.tenant_custom_nameservers.with_raw_response.delete( - custom_ns_id="ns1.example.com", - tenant_tag="699d98642c564d2e855e9661899b7252", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - tenant_custom_nameserver = response.parse() - assert_matches_type( - SyncSinglePage[TenantCustomNameserverDeleteResponse], tenant_custom_nameserver, path=["response"] - ) - - @parametrize - def test_streaming_response_delete(self, client: Cloudflare) -> None: - with client.tenant_custom_nameservers.with_streaming_response.delete( - custom_ns_id="ns1.example.com", - tenant_tag="699d98642c564d2e855e9661899b7252", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - tenant_custom_nameserver = response.parse() - assert_matches_type( - SyncSinglePage[TenantCustomNameserverDeleteResponse], tenant_custom_nameserver, path=["response"] - ) - - assert cast(Any, response.is_closed) is True - - @parametrize - def test_path_params_delete(self, client: Cloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `tenant_tag` but received ''"): - client.tenant_custom_nameservers.with_raw_response.delete( - custom_ns_id="ns1.example.com", - tenant_tag="", - ) - - with pytest.raises(ValueError, match=r"Expected a non-empty value for `custom_ns_id` but received ''"): - client.tenant_custom_nameservers.with_raw_response.delete( - custom_ns_id="", - tenant_tag="699d98642c564d2e855e9661899b7252", - ) - - @parametrize - def test_method_get(self, client: Cloudflare) -> None: - tenant_custom_nameserver = client.tenant_custom_nameservers.get( - "699d98642c564d2e855e9661899b7252", - ) - assert_matches_type( - SyncSinglePage[TenantCustomNameserverGetResponse], tenant_custom_nameserver, path=["response"] - ) - - @parametrize - def test_raw_response_get(self, client: Cloudflare) -> None: - response = client.tenant_custom_nameservers.with_raw_response.get( - "699d98642c564d2e855e9661899b7252", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - tenant_custom_nameserver = response.parse() - assert_matches_type( - SyncSinglePage[TenantCustomNameserverGetResponse], tenant_custom_nameserver, path=["response"] - ) - - @parametrize - def test_streaming_response_get(self, client: Cloudflare) -> None: - with client.tenant_custom_nameservers.with_streaming_response.get( - "699d98642c564d2e855e9661899b7252", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - tenant_custom_nameserver = response.parse() - assert_matches_type( - SyncSinglePage[TenantCustomNameserverGetResponse], tenant_custom_nameserver, path=["response"] - ) - - assert cast(Any, response.is_closed) is True - - @parametrize - def test_path_params_get(self, client: Cloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `tenant_tag` but received ''"): - client.tenant_custom_nameservers.with_raw_response.get( - "", - ) - - -class TestAsyncTenantCustomNameservers: - parametrize = pytest.mark.parametrize( - "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] - ) - - @parametrize - async def test_method_create(self, async_client: AsyncCloudflare) -> None: - tenant_custom_nameserver = await async_client.tenant_custom_nameservers.create( - tenant_tag="699d98642c564d2e855e9661899b7252", - ns_name="ns1.example.com", - ) - assert_matches_type(Optional[TenantCustomNameserverCreateResponse], tenant_custom_nameserver, path=["response"]) - - @parametrize - async def test_method_create_with_all_params(self, async_client: AsyncCloudflare) -> None: - tenant_custom_nameserver = await async_client.tenant_custom_nameservers.create( - tenant_tag="699d98642c564d2e855e9661899b7252", - ns_name="ns1.example.com", - ns_set=1, - ) - assert_matches_type(Optional[TenantCustomNameserverCreateResponse], tenant_custom_nameserver, path=["response"]) - - @parametrize - async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None: - response = await async_client.tenant_custom_nameservers.with_raw_response.create( - tenant_tag="699d98642c564d2e855e9661899b7252", - ns_name="ns1.example.com", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - tenant_custom_nameserver = await response.parse() - assert_matches_type(Optional[TenantCustomNameserverCreateResponse], tenant_custom_nameserver, path=["response"]) - - @parametrize - async def test_streaming_response_create(self, async_client: AsyncCloudflare) -> None: - async with async_client.tenant_custom_nameservers.with_streaming_response.create( - tenant_tag="699d98642c564d2e855e9661899b7252", - ns_name="ns1.example.com", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - tenant_custom_nameserver = await response.parse() - assert_matches_type( - Optional[TenantCustomNameserverCreateResponse], tenant_custom_nameserver, path=["response"] - ) - - assert cast(Any, response.is_closed) is True - - @parametrize - async def test_path_params_create(self, async_client: AsyncCloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `tenant_tag` but received ''"): - await async_client.tenant_custom_nameservers.with_raw_response.create( - tenant_tag="", - ns_name="ns1.example.com", - ) - - @parametrize - async def test_method_delete(self, async_client: AsyncCloudflare) -> None: - tenant_custom_nameserver = await async_client.tenant_custom_nameservers.delete( - custom_ns_id="ns1.example.com", - tenant_tag="699d98642c564d2e855e9661899b7252", - ) - assert_matches_type( - AsyncSinglePage[TenantCustomNameserverDeleteResponse], tenant_custom_nameserver, path=["response"] - ) - - @parametrize - async def test_raw_response_delete(self, async_client: AsyncCloudflare) -> None: - response = await async_client.tenant_custom_nameservers.with_raw_response.delete( - custom_ns_id="ns1.example.com", - tenant_tag="699d98642c564d2e855e9661899b7252", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - tenant_custom_nameserver = await response.parse() - assert_matches_type( - AsyncSinglePage[TenantCustomNameserverDeleteResponse], tenant_custom_nameserver, path=["response"] - ) - - @parametrize - async def test_streaming_response_delete(self, async_client: AsyncCloudflare) -> None: - async with async_client.tenant_custom_nameservers.with_streaming_response.delete( - custom_ns_id="ns1.example.com", - tenant_tag="699d98642c564d2e855e9661899b7252", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - tenant_custom_nameserver = await response.parse() - assert_matches_type( - AsyncSinglePage[TenantCustomNameserverDeleteResponse], tenant_custom_nameserver, path=["response"] - ) - - assert cast(Any, response.is_closed) is True - - @parametrize - async def test_path_params_delete(self, async_client: AsyncCloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `tenant_tag` but received ''"): - await async_client.tenant_custom_nameservers.with_raw_response.delete( - custom_ns_id="ns1.example.com", - tenant_tag="", - ) - - with pytest.raises(ValueError, match=r"Expected a non-empty value for `custom_ns_id` but received ''"): - await async_client.tenant_custom_nameservers.with_raw_response.delete( - custom_ns_id="", - tenant_tag="699d98642c564d2e855e9661899b7252", - ) - - @parametrize - async def test_method_get(self, async_client: AsyncCloudflare) -> None: - tenant_custom_nameserver = await async_client.tenant_custom_nameservers.get( - "699d98642c564d2e855e9661899b7252", - ) - assert_matches_type( - AsyncSinglePage[TenantCustomNameserverGetResponse], tenant_custom_nameserver, path=["response"] - ) - - @parametrize - async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None: - response = await async_client.tenant_custom_nameservers.with_raw_response.get( - "699d98642c564d2e855e9661899b7252", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - tenant_custom_nameserver = await response.parse() - assert_matches_type( - AsyncSinglePage[TenantCustomNameserverGetResponse], tenant_custom_nameserver, path=["response"] - ) - - @parametrize - async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> None: - async with async_client.tenant_custom_nameservers.with_streaming_response.get( - "699d98642c564d2e855e9661899b7252", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - tenant_custom_nameserver = await response.parse() - assert_matches_type( - AsyncSinglePage[TenantCustomNameserverGetResponse], tenant_custom_nameserver, path=["response"] - ) - - assert cast(Any, response.is_closed) is True - - @parametrize - async def test_path_params_get(self, async_client: AsyncCloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `tenant_tag` but received ''"): - await async_client.tenant_custom_nameservers.with_raw_response.get( - "", - ) diff --git a/tests/api_resources/test_tenants.py b/tests/api_resources/test_tenants.py deleted file mode 100644 index 5b9b1ffb98a..00000000000 --- a/tests/api_resources/test_tenants.py +++ /dev/null @@ -1,100 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -import os -from typing import Any, cast - -import pytest - -from cloudflare import Cloudflare, AsyncCloudflare -from tests.utils import assert_matches_type -from cloudflare.types.tenants import Tenant - -base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") - - -class TestTenants: - parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) - - @parametrize - def test_method_get(self, client: Cloudflare) -> None: - tenant = client.tenants.get( - "tenant_id", - ) - assert_matches_type(Tenant, tenant, path=["response"]) - - @parametrize - def test_raw_response_get(self, client: Cloudflare) -> None: - response = client.tenants.with_raw_response.get( - "tenant_id", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - tenant = response.parse() - assert_matches_type(Tenant, tenant, path=["response"]) - - @parametrize - def test_streaming_response_get(self, client: Cloudflare) -> None: - with client.tenants.with_streaming_response.get( - "tenant_id", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - tenant = response.parse() - assert_matches_type(Tenant, tenant, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @parametrize - def test_path_params_get(self, client: Cloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `tenant_id` but received ''"): - client.tenants.with_raw_response.get( - "", - ) - - -class TestAsyncTenants: - parametrize = pytest.mark.parametrize( - "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] - ) - - @parametrize - async def test_method_get(self, async_client: AsyncCloudflare) -> None: - tenant = await async_client.tenants.get( - "tenant_id", - ) - assert_matches_type(Tenant, tenant, path=["response"]) - - @parametrize - async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None: - response = await async_client.tenants.with_raw_response.get( - "tenant_id", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - tenant = await response.parse() - assert_matches_type(Tenant, tenant, path=["response"]) - - @parametrize - async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> None: - async with async_client.tenants.with_streaming_response.get( - "tenant_id", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - tenant = await response.parse() - assert_matches_type(Tenant, tenant, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @parametrize - async def test_path_params_get(self, async_client: AsyncCloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `tenant_id` but received ''"): - await async_client.tenants.with_raw_response.get( - "", - ) diff --git a/tests/api_resources/test_workflows.py b/tests/api_resources/test_workflows.py index aa7c8102e82..f7203ed0790 100644 --- a/tests/api_resources/test_workflows.py +++ b/tests/api_resources/test_workflows.py @@ -45,6 +45,7 @@ def test_method_update_with_all_params(self, client: Cloudflare) -> None: "error_retention": "5 minutes", "success_retention": "5 minutes", }, + jurisdiction="eu", limits={"steps": 1}, schedules=[{"cron": "x"}], ) @@ -270,6 +271,7 @@ async def test_method_update_with_all_params(self, async_client: AsyncCloudflare "error_retention": "5 minutes", "success_retention": "5 minutes", }, + jurisdiction="eu", limits={"steps": 1}, schedules=[{"cron": "x"}], ) diff --git a/tests/api_resources/url_scanner/test_scans.py b/tests/api_resources/url_scanner/test_scans.py index 0bf41c85a78..b9f396c42a2 100644 --- a/tests/api_resources/url_scanner/test_scans.py +++ b/tests/api_resources/url_scanner/test_scans.py @@ -45,7 +45,7 @@ def test_method_create_with_all_params(self, client: Cloudflare) -> None: account_id="account_id", url="https://www.example.com", agent_readiness=True, - country="AF", + country="AE", customagent="customagent", custom_headers={"foo": "string"}, referer="referer", @@ -441,7 +441,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncCloudflare account_id="account_id", url="https://www.example.com", agent_readiness=True, - country="AF", + country="AE", customagent="customagent", custom_headers={"foo": "string"}, referer="referer", diff --git a/tests/api_resources/user/test_tenants.py b/tests/api_resources/user/test_tenants.py index 17e7b732394..e6e17cc491a 100644 --- a/tests/api_resources/user/test_tenants.py +++ b/tests/api_resources/user/test_tenants.py @@ -10,7 +10,7 @@ from cloudflare import Cloudflare, AsyncCloudflare from tests.utils import assert_matches_type from cloudflare.pagination import SyncSinglePage, AsyncSinglePage -from cloudflare.types.organizations import Organization +from cloudflare.types.user import TenantListResponse base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") @@ -21,7 +21,7 @@ class TestTenants: @parametrize def test_method_list(self, client: Cloudflare) -> None: tenant = client.user.tenants.list() - assert_matches_type(SyncSinglePage[Organization], tenant, path=["response"]) + assert_matches_type(SyncSinglePage[TenantListResponse], tenant, path=["response"]) @parametrize def test_raw_response_list(self, client: Cloudflare) -> None: @@ -30,7 +30,7 @@ def test_raw_response_list(self, client: Cloudflare) -> None: assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" tenant = response.parse() - assert_matches_type(SyncSinglePage[Organization], tenant, path=["response"]) + assert_matches_type(SyncSinglePage[TenantListResponse], tenant, path=["response"]) @parametrize def test_streaming_response_list(self, client: Cloudflare) -> None: @@ -39,7 +39,7 @@ def test_streaming_response_list(self, client: Cloudflare) -> None: assert response.http_request.headers.get("X-Stainless-Lang") == "python" tenant = response.parse() - assert_matches_type(SyncSinglePage[Organization], tenant, path=["response"]) + assert_matches_type(SyncSinglePage[TenantListResponse], tenant, path=["response"]) assert cast(Any, response.is_closed) is True @@ -52,7 +52,7 @@ class TestAsyncTenants: @parametrize async def test_method_list(self, async_client: AsyncCloudflare) -> None: tenant = await async_client.user.tenants.list() - assert_matches_type(AsyncSinglePage[Organization], tenant, path=["response"]) + assert_matches_type(AsyncSinglePage[TenantListResponse], tenant, path=["response"]) @parametrize async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None: @@ -61,7 +61,7 @@ async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None: assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" tenant = await response.parse() - assert_matches_type(AsyncSinglePage[Organization], tenant, path=["response"]) + assert_matches_type(AsyncSinglePage[TenantListResponse], tenant, path=["response"]) @parametrize async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> None: @@ -70,6 +70,6 @@ async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> N assert response.http_request.headers.get("X-Stainless-Lang") == "python" tenant = await response.parse() - assert_matches_type(AsyncSinglePage[Organization], tenant, path=["response"]) + assert_matches_type(AsyncSinglePage[TenantListResponse], tenant, path=["response"]) assert cast(Any, response.is_closed) is True diff --git a/tests/api_resources/vectorize/test_indexes.py b/tests/api_resources/vectorize/test_indexes.py index 58f6825765c..f57f2bc9a86 100644 --- a/tests/api_resources/vectorize/test_indexes.py +++ b/tests/api_resources/vectorize/test_indexes.py @@ -17,6 +17,7 @@ IndexDeleteResponse, IndexInsertResponse, IndexUpsertResponse, + IndexGetByIDsResponse, IndexDeleteByIDsResponse, IndexListVectorsResponse, ) @@ -295,7 +296,7 @@ def test_method_get_by_ids(self, client: Cloudflare) -> None: index_name="example-index", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) - assert_matches_type(object, index, path=["response"]) + assert_matches_type(SyncSinglePage[IndexGetByIDsResponse], index, path=["response"]) @parametrize def test_method_get_by_ids_with_all_params(self, client: Cloudflare) -> None: @@ -304,7 +305,7 @@ def test_method_get_by_ids_with_all_params(self, client: Cloudflare) -> None: account_id="023e105f4ecef8ad9ca31a8372d0c353", ids=["5121db81354a40c6aedc3fe1ace51c59", "f90eb49c2107486abdfd78c67e853430"], ) - assert_matches_type(object, index, path=["response"]) + assert_matches_type(SyncSinglePage[IndexGetByIDsResponse], index, path=["response"]) @parametrize def test_raw_response_get_by_ids(self, client: Cloudflare) -> None: @@ -316,7 +317,7 @@ def test_raw_response_get_by_ids(self, client: Cloudflare) -> None: assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" index = response.parse() - assert_matches_type(object, index, path=["response"]) + assert_matches_type(SyncSinglePage[IndexGetByIDsResponse], index, path=["response"]) @parametrize def test_streaming_response_get_by_ids(self, client: Cloudflare) -> None: @@ -328,7 +329,7 @@ def test_streaming_response_get_by_ids(self, client: Cloudflare) -> None: assert response.http_request.headers.get("X-Stainless-Lang") == "python" index = response.parse() - assert_matches_type(object, index, path=["response"]) + assert_matches_type(SyncSinglePage[IndexGetByIDsResponse], index, path=["response"]) assert cast(Any, response.is_closed) is True @@ -931,7 +932,7 @@ async def test_method_get_by_ids(self, async_client: AsyncCloudflare) -> None: index_name="example-index", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) - assert_matches_type(object, index, path=["response"]) + assert_matches_type(AsyncSinglePage[IndexGetByIDsResponse], index, path=["response"]) @parametrize async def test_method_get_by_ids_with_all_params(self, async_client: AsyncCloudflare) -> None: @@ -940,7 +941,7 @@ async def test_method_get_by_ids_with_all_params(self, async_client: AsyncCloudf account_id="023e105f4ecef8ad9ca31a8372d0c353", ids=["5121db81354a40c6aedc3fe1ace51c59", "f90eb49c2107486abdfd78c67e853430"], ) - assert_matches_type(object, index, path=["response"]) + assert_matches_type(AsyncSinglePage[IndexGetByIDsResponse], index, path=["response"]) @parametrize async def test_raw_response_get_by_ids(self, async_client: AsyncCloudflare) -> None: @@ -952,7 +953,7 @@ async def test_raw_response_get_by_ids(self, async_client: AsyncCloudflare) -> N assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" index = await response.parse() - assert_matches_type(object, index, path=["response"]) + assert_matches_type(AsyncSinglePage[IndexGetByIDsResponse], index, path=["response"]) @parametrize async def test_streaming_response_get_by_ids(self, async_client: AsyncCloudflare) -> None: @@ -964,7 +965,7 @@ async def test_streaming_response_get_by_ids(self, async_client: AsyncCloudflare assert response.http_request.headers.get("X-Stainless-Lang") == "python" index = await response.parse() - assert_matches_type(object, index, path=["response"]) + assert_matches_type(AsyncSinglePage[IndexGetByIDsResponse], index, path=["response"]) assert cast(Any, response.is_closed) is True diff --git a/tests/api_resources/workers/beta/workers/test_versions.py b/tests/api_resources/workers/beta/workers/test_versions.py index d7a47f9960c..a7a7bc76297 100644 --- a/tests/api_resources/workers/beta/workers/test_versions.py +++ b/tests/api_resources/workers/beta/workers/test_versions.py @@ -5,10 +5,18 @@ import os from typing import Any, cast +import httpx import pytest +from respx import MockRouter from cloudflare import Cloudflare, AsyncCloudflare from tests.utils import assert_matches_type +from cloudflare._response import ( + BinaryAPIResponse, + AsyncBinaryAPIResponse, + StreamedBinaryAPIResponse, + AsyncStreamedBinaryAPIResponse, +) from cloudflare.pagination import SyncV4PagePaginationArray, AsyncV4PagePaginationArray from cloudflare.types.workers.beta.workers import ( Version, @@ -357,6 +365,110 @@ def test_path_params_get(self, client: Cloudflare) -> None: worker_id="worker_id", ) + @parametrize + @pytest.mark.respx(base_url=base_url) + def test_method_profile(self, client: Cloudflare, respx_mock: MockRouter) -> None: + respx_mock.post( + "/accounts/023e105f4ecef8ad9ca31a8372d0c353/workers/workers/worker_id/versions/version_id/profile" + ).mock(return_value=httpx.Response(200, json={"foo": "bar"})) + version = client.workers.beta.workers.versions.profile( + version_id="version_id", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + worker_id="worker_id", + duration_ms=1000, + ) + assert version.is_closed + assert version.json() == {"foo": "bar"} + assert cast(Any, version.is_closed) is True + assert isinstance(version, BinaryAPIResponse) + + @parametrize + @pytest.mark.respx(base_url=base_url) + def test_method_profile_with_all_params(self, client: Cloudflare, respx_mock: MockRouter) -> None: + respx_mock.post( + "/accounts/023e105f4ecef8ad9ca31a8372d0c353/workers/workers/worker_id/versions/version_id/profile" + ).mock(return_value=httpx.Response(200, json={"foo": "bar"})) + version = client.workers.beta.workers.versions.profile( + version_id="version_id", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + worker_id="worker_id", + duration_ms=1000, + actor_id="actor_id", + namespace_id="namespace_id", + profile_type="cpu", + ) + assert version.is_closed + assert version.json() == {"foo": "bar"} + assert cast(Any, version.is_closed) is True + assert isinstance(version, BinaryAPIResponse) + + @parametrize + @pytest.mark.respx(base_url=base_url) + def test_raw_response_profile(self, client: Cloudflare, respx_mock: MockRouter) -> None: + respx_mock.post( + "/accounts/023e105f4ecef8ad9ca31a8372d0c353/workers/workers/worker_id/versions/version_id/profile" + ).mock(return_value=httpx.Response(200, json={"foo": "bar"})) + + version = client.workers.beta.workers.versions.with_raw_response.profile( + version_id="version_id", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + worker_id="worker_id", + duration_ms=1000, + ) + + assert version.is_closed is True + assert version.http_request.headers.get("X-Stainless-Lang") == "python" + assert version.json() == {"foo": "bar"} + assert isinstance(version, BinaryAPIResponse) + + @parametrize + @pytest.mark.respx(base_url=base_url) + def test_streaming_response_profile(self, client: Cloudflare, respx_mock: MockRouter) -> None: + respx_mock.post( + "/accounts/023e105f4ecef8ad9ca31a8372d0c353/workers/workers/worker_id/versions/version_id/profile" + ).mock(return_value=httpx.Response(200, json={"foo": "bar"})) + with client.workers.beta.workers.versions.with_streaming_response.profile( + version_id="version_id", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + worker_id="worker_id", + duration_ms=1000, + ) as version: + assert not version.is_closed + assert version.http_request.headers.get("X-Stainless-Lang") == "python" + + assert version.json() == {"foo": "bar"} + assert cast(Any, version.is_closed) is True + assert isinstance(version, StreamedBinaryAPIResponse) + + assert cast(Any, version.is_closed) is True + + @parametrize + @pytest.mark.respx(base_url=base_url) + def test_path_params_profile(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.workers.beta.workers.versions.with_raw_response.profile( + version_id="version_id", + account_id="", + worker_id="worker_id", + duration_ms=1000, + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `worker_id` but received ''"): + client.workers.beta.workers.versions.with_raw_response.profile( + version_id="version_id", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + worker_id="", + duration_ms=1000, + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `version_id` but received ''"): + client.workers.beta.workers.versions.with_raw_response.profile( + version_id="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + worker_id="worker_id", + duration_ms=1000, + ) + class TestAsyncVersions: parametrize = pytest.mark.parametrize( @@ -698,3 +810,107 @@ async def test_path_params_get(self, async_client: AsyncCloudflare) -> None: account_id="023e105f4ecef8ad9ca31a8372d0c353", worker_id="worker_id", ) + + @parametrize + @pytest.mark.respx(base_url=base_url) + async def test_method_profile(self, async_client: AsyncCloudflare, respx_mock: MockRouter) -> None: + respx_mock.post( + "/accounts/023e105f4ecef8ad9ca31a8372d0c353/workers/workers/worker_id/versions/version_id/profile" + ).mock(return_value=httpx.Response(200, json={"foo": "bar"})) + version = await async_client.workers.beta.workers.versions.profile( + version_id="version_id", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + worker_id="worker_id", + duration_ms=1000, + ) + assert version.is_closed + assert await version.json() == {"foo": "bar"} + assert cast(Any, version.is_closed) is True + assert isinstance(version, AsyncBinaryAPIResponse) + + @parametrize + @pytest.mark.respx(base_url=base_url) + async def test_method_profile_with_all_params(self, async_client: AsyncCloudflare, respx_mock: MockRouter) -> None: + respx_mock.post( + "/accounts/023e105f4ecef8ad9ca31a8372d0c353/workers/workers/worker_id/versions/version_id/profile" + ).mock(return_value=httpx.Response(200, json={"foo": "bar"})) + version = await async_client.workers.beta.workers.versions.profile( + version_id="version_id", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + worker_id="worker_id", + duration_ms=1000, + actor_id="actor_id", + namespace_id="namespace_id", + profile_type="cpu", + ) + assert version.is_closed + assert await version.json() == {"foo": "bar"} + assert cast(Any, version.is_closed) is True + assert isinstance(version, AsyncBinaryAPIResponse) + + @parametrize + @pytest.mark.respx(base_url=base_url) + async def test_raw_response_profile(self, async_client: AsyncCloudflare, respx_mock: MockRouter) -> None: + respx_mock.post( + "/accounts/023e105f4ecef8ad9ca31a8372d0c353/workers/workers/worker_id/versions/version_id/profile" + ).mock(return_value=httpx.Response(200, json={"foo": "bar"})) + + version = await async_client.workers.beta.workers.versions.with_raw_response.profile( + version_id="version_id", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + worker_id="worker_id", + duration_ms=1000, + ) + + assert version.is_closed is True + assert version.http_request.headers.get("X-Stainless-Lang") == "python" + assert await version.json() == {"foo": "bar"} + assert isinstance(version, AsyncBinaryAPIResponse) + + @parametrize + @pytest.mark.respx(base_url=base_url) + async def test_streaming_response_profile(self, async_client: AsyncCloudflare, respx_mock: MockRouter) -> None: + respx_mock.post( + "/accounts/023e105f4ecef8ad9ca31a8372d0c353/workers/workers/worker_id/versions/version_id/profile" + ).mock(return_value=httpx.Response(200, json={"foo": "bar"})) + async with async_client.workers.beta.workers.versions.with_streaming_response.profile( + version_id="version_id", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + worker_id="worker_id", + duration_ms=1000, + ) as version: + assert not version.is_closed + assert version.http_request.headers.get("X-Stainless-Lang") == "python" + + assert await version.json() == {"foo": "bar"} + assert cast(Any, version.is_closed) is True + assert isinstance(version, AsyncStreamedBinaryAPIResponse) + + assert cast(Any, version.is_closed) is True + + @parametrize + @pytest.mark.respx(base_url=base_url) + async def test_path_params_profile(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.workers.beta.workers.versions.with_raw_response.profile( + version_id="version_id", + account_id="", + worker_id="worker_id", + duration_ms=1000, + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `worker_id` but received ''"): + await async_client.workers.beta.workers.versions.with_raw_response.profile( + version_id="version_id", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + worker_id="", + duration_ms=1000, + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `version_id` but received ''"): + await async_client.workers.beta.workers.versions.with_raw_response.profile( + version_id="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + worker_id="worker_id", + duration_ms=1000, + ) diff --git a/tests/api_resources/workers/observability/test_destinations.py b/tests/api_resources/workers/observability/test_destinations.py index 82f2c056fef..2e11a7d96d6 100644 --- a/tests/api_resources/workers/observability/test_destinations.py +++ b/tests/api_resources/workers/observability/test_destinations.py @@ -114,12 +114,22 @@ def test_method_update(self, client: Cloudflare) -> None: destination = client.workers.observability.destinations.update( slug="slug", account_id="account_id", + enabled=True, + ) + assert_matches_type(DestinationUpdateResponse, destination, path=["response"]) + + @parametrize + def test_method_update_with_all_params(self, client: Cloudflare) -> None: + destination = client.workers.observability.destinations.update( + slug="slug", + account_id="account_id", + enabled=True, configuration={ "headers": {"foo": "string"}, "type": "logpush", "url": "url", + "replace_headers": True, }, - enabled=True, ) assert_matches_type(DestinationUpdateResponse, destination, path=["response"]) @@ -128,11 +138,6 @@ def test_raw_response_update(self, client: Cloudflare) -> None: response = client.workers.observability.destinations.with_raw_response.update( slug="slug", account_id="account_id", - configuration={ - "headers": {"foo": "string"}, - "type": "logpush", - "url": "url", - }, enabled=True, ) @@ -146,11 +151,6 @@ def test_streaming_response_update(self, client: Cloudflare) -> None: with client.workers.observability.destinations.with_streaming_response.update( slug="slug", account_id="account_id", - configuration={ - "headers": {"foo": "string"}, - "type": "logpush", - "url": "url", - }, enabled=True, ) as response: assert not response.is_closed @@ -167,11 +167,6 @@ def test_path_params_update(self, client: Cloudflare) -> None: client.workers.observability.destinations.with_raw_response.update( slug="slug", account_id="", - configuration={ - "headers": {"foo": "string"}, - "type": "logpush", - "url": "url", - }, enabled=True, ) @@ -179,11 +174,6 @@ def test_path_params_update(self, client: Cloudflare) -> None: client.workers.observability.destinations.with_raw_response.update( slug="", account_id="account_id", - configuration={ - "headers": {"foo": "string"}, - "type": "logpush", - "url": "url", - }, enabled=True, ) @@ -381,12 +371,22 @@ async def test_method_update(self, async_client: AsyncCloudflare) -> None: destination = await async_client.workers.observability.destinations.update( slug="slug", account_id="account_id", + enabled=True, + ) + assert_matches_type(DestinationUpdateResponse, destination, path=["response"]) + + @parametrize + async def test_method_update_with_all_params(self, async_client: AsyncCloudflare) -> None: + destination = await async_client.workers.observability.destinations.update( + slug="slug", + account_id="account_id", + enabled=True, configuration={ "headers": {"foo": "string"}, "type": "logpush", "url": "url", + "replace_headers": True, }, - enabled=True, ) assert_matches_type(DestinationUpdateResponse, destination, path=["response"]) @@ -395,11 +395,6 @@ async def test_raw_response_update(self, async_client: AsyncCloudflare) -> None: response = await async_client.workers.observability.destinations.with_raw_response.update( slug="slug", account_id="account_id", - configuration={ - "headers": {"foo": "string"}, - "type": "logpush", - "url": "url", - }, enabled=True, ) @@ -413,11 +408,6 @@ async def test_streaming_response_update(self, async_client: AsyncCloudflare) -> async with async_client.workers.observability.destinations.with_streaming_response.update( slug="slug", account_id="account_id", - configuration={ - "headers": {"foo": "string"}, - "type": "logpush", - "url": "url", - }, enabled=True, ) as response: assert not response.is_closed @@ -434,11 +424,6 @@ async def test_path_params_update(self, async_client: AsyncCloudflare) -> None: await async_client.workers.observability.destinations.with_raw_response.update( slug="slug", account_id="", - configuration={ - "headers": {"foo": "string"}, - "type": "logpush", - "url": "url", - }, enabled=True, ) @@ -446,11 +431,6 @@ async def test_path_params_update(self, async_client: AsyncCloudflare) -> None: await async_client.workers.observability.destinations.with_raw_response.update( slug="", account_id="account_id", - configuration={ - "headers": {"foo": "string"}, - "type": "logpush", - "url": "url", - }, enabled=True, ) diff --git a/tests/api_resources/workers/scripts/test_deployments.py b/tests/api_resources/workers/scripts/test_deployments.py index 87039826bdb..a707b33d4c3 100644 --- a/tests/api_resources/workers/scripts/test_deployments.py +++ b/tests/api_resources/workers/scripts/test_deployments.py @@ -52,6 +52,7 @@ def test_method_create_with_all_params(self, client: Cloudflare) -> None: ], force=True, annotations={"workers_message": "Deploy bug fix."}, + code_update_strategy={"mode": "immediate"}, ) assert_matches_type(Deployment, deployment, path=["response"]) @@ -338,6 +339,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncCloudflare ], force=True, annotations={"workers_message": "Deploy bug fix."}, + code_update_strategy={"mode": "immediate"}, ) assert_matches_type(Deployment, deployment, path=["response"]) diff --git a/tests/api_resources/workers/test_domains.py b/tests/api_resources/workers/test_domains.py index 26cf1ec1f53..26bb5bf6a14 100644 --- a/tests/api_resources/workers/test_domains.py +++ b/tests/api_resources/workers/test_domains.py @@ -40,6 +40,8 @@ def test_method_update_with_all_params(self, client: Cloudflare) -> None: account_id="023e105f4ecef8ad9ca31a8372d0c353", hostname="app.example.com", service="my-worker", + enabled=True, + previews_enabled=False, zone_id="593c9c94de529bbbfaac7c53ced0447d", zone_name="example.com", ) @@ -96,8 +98,10 @@ def test_method_list(self, client: Cloudflare) -> None: def test_method_list_with_all_params(self, client: Cloudflare) -> None: domain = client.workers.domains.list( account_id="023e105f4ecef8ad9ca31a8372d0c353", + enabled=True, environment="production", hostname="app.example.com", + previews_enabled=False, service="my-worker", zone_id="593c9c94de529bbbfaac7c53ced0447d", zone_name="example.com", @@ -254,6 +258,8 @@ async def test_method_update_with_all_params(self, async_client: AsyncCloudflare account_id="023e105f4ecef8ad9ca31a8372d0c353", hostname="app.example.com", service="my-worker", + enabled=True, + previews_enabled=False, zone_id="593c9c94de529bbbfaac7c53ced0447d", zone_name="example.com", ) @@ -310,8 +316,10 @@ async def test_method_list(self, async_client: AsyncCloudflare) -> None: async def test_method_list_with_all_params(self, async_client: AsyncCloudflare) -> None: domain = await async_client.workers.domains.list( account_id="023e105f4ecef8ad9ca31a8372d0c353", + enabled=True, environment="production", hostname="app.example.com", + previews_enabled=False, service="my-worker", zone_id="593c9c94de529bbbfaac7c53ced0447d", zone_name="example.com", diff --git a/tests/api_resources/workers/test_scripts.py b/tests/api_resources/workers/test_scripts.py index 5a0b163abd2..0b217aa9f82 100644 --- a/tests/api_resources/workers/test_scripts.py +++ b/tests/api_resources/workers/test_scripts.py @@ -67,6 +67,7 @@ def test_method_update_with_all_params(self, client: Cloudflare) -> None: "enabled": True, "cross_version_cache": True, }, + "code_update_strategy": {"mode": "immediate"}, "compatibility_date": "2021-01-01T00:00:00Z", "compatibility_flags": ["nodejs_compat"], "exports": { @@ -462,6 +463,7 @@ async def test_method_update_with_all_params(self, async_client: AsyncCloudflare "enabled": True, "cross_version_cache": True, }, + "code_update_strategy": {"mode": "immediate"}, "compatibility_date": "2021-01-01T00:00:00Z", "compatibility_flags": ["nodejs_compat"], "exports": { diff --git a/tests/api_resources/workers_for_platforms/dispatch/namespaces/scripts/test_tags.py b/tests/api_resources/workers_for_platforms/dispatch/namespaces/scripts/test_tags.py index c5832ab128f..db3679e898f 100644 --- a/tests/api_resources/workers_for_platforms/dispatch/namespaces/scripts/test_tags.py +++ b/tests/api_resources/workers_for_platforms/dispatch/namespaces/scripts/test_tags.py @@ -12,6 +12,7 @@ from cloudflare.pagination import SyncSinglePage, AsyncSinglePage from cloudflare.types.workers_for_platforms.dispatch.namespaces.scripts import ( TagListResponse, + TagDeleteResponse, TagUpdateResponse, ) @@ -150,17 +151,28 @@ def test_path_params_list(self, client: Cloudflare) -> None: @parametrize def test_method_delete(self, client: Cloudflare) -> None: tag = client.workers_for_platforms.dispatch.namespaces.scripts.tags.delete( - tag="my-tag", + tag="environment", account_id="023e105f4ecef8ad9ca31a8372d0c353", dispatch_namespace="my-dispatch-namespace", script_name="this-is_my_script-01", ) - assert_matches_type(object, tag, path=["response"]) + assert_matches_type(TagDeleteResponse, tag, path=["response"]) + + @parametrize + def test_method_delete_with_all_params(self, client: Cloudflare) -> None: + tag = client.workers_for_platforms.dispatch.namespaces.scripts.tags.delete( + tag="environment", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + dispatch_namespace="my-dispatch-namespace", + script_name="this-is_my_script-01", + api_version="2026-10-01.epoch", + ) + assert_matches_type(TagDeleteResponse, tag, path=["response"]) @parametrize def test_raw_response_delete(self, client: Cloudflare) -> None: response = client.workers_for_platforms.dispatch.namespaces.scripts.tags.with_raw_response.delete( - tag="my-tag", + tag="environment", account_id="023e105f4ecef8ad9ca31a8372d0c353", dispatch_namespace="my-dispatch-namespace", script_name="this-is_my_script-01", @@ -169,12 +181,12 @@ def test_raw_response_delete(self, client: Cloudflare) -> None: assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" tag = response.parse() - assert_matches_type(object, tag, path=["response"]) + assert_matches_type(TagDeleteResponse, tag, path=["response"]) @parametrize def test_streaming_response_delete(self, client: Cloudflare) -> None: with client.workers_for_platforms.dispatch.namespaces.scripts.tags.with_streaming_response.delete( - tag="my-tag", + tag="environment", account_id="023e105f4ecef8ad9ca31a8372d0c353", dispatch_namespace="my-dispatch-namespace", script_name="this-is_my_script-01", @@ -183,7 +195,7 @@ def test_streaming_response_delete(self, client: Cloudflare) -> None: assert response.http_request.headers.get("X-Stainless-Lang") == "python" tag = response.parse() - assert_matches_type(object, tag, path=["response"]) + assert_matches_type(TagDeleteResponse, tag, path=["response"]) assert cast(Any, response.is_closed) is True @@ -191,7 +203,7 @@ def test_streaming_response_delete(self, client: Cloudflare) -> None: def test_path_params_delete(self, client: Cloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): client.workers_for_platforms.dispatch.namespaces.scripts.tags.with_raw_response.delete( - tag="my-tag", + tag="environment", account_id="", dispatch_namespace="my-dispatch-namespace", script_name="this-is_my_script-01", @@ -199,7 +211,7 @@ def test_path_params_delete(self, client: Cloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `dispatch_namespace` but received ''"): client.workers_for_platforms.dispatch.namespaces.scripts.tags.with_raw_response.delete( - tag="my-tag", + tag="environment", account_id="023e105f4ecef8ad9ca31a8372d0c353", dispatch_namespace="", script_name="this-is_my_script-01", @@ -207,7 +219,7 @@ def test_path_params_delete(self, client: Cloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `script_name` but received ''"): client.workers_for_platforms.dispatch.namespaces.scripts.tags.with_raw_response.delete( - tag="my-tag", + tag="environment", account_id="023e105f4ecef8ad9ca31a8372d0c353", dispatch_namespace="my-dispatch-namespace", script_name="", @@ -356,17 +368,28 @@ async def test_path_params_list(self, async_client: AsyncCloudflare) -> None: @parametrize async def test_method_delete(self, async_client: AsyncCloudflare) -> None: tag = await async_client.workers_for_platforms.dispatch.namespaces.scripts.tags.delete( - tag="my-tag", + tag="environment", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + dispatch_namespace="my-dispatch-namespace", + script_name="this-is_my_script-01", + ) + assert_matches_type(TagDeleteResponse, tag, path=["response"]) + + @parametrize + async def test_method_delete_with_all_params(self, async_client: AsyncCloudflare) -> None: + tag = await async_client.workers_for_platforms.dispatch.namespaces.scripts.tags.delete( + tag="environment", account_id="023e105f4ecef8ad9ca31a8372d0c353", dispatch_namespace="my-dispatch-namespace", script_name="this-is_my_script-01", + api_version="2026-10-01.epoch", ) - assert_matches_type(object, tag, path=["response"]) + assert_matches_type(TagDeleteResponse, tag, path=["response"]) @parametrize async def test_raw_response_delete(self, async_client: AsyncCloudflare) -> None: response = await async_client.workers_for_platforms.dispatch.namespaces.scripts.tags.with_raw_response.delete( - tag="my-tag", + tag="environment", account_id="023e105f4ecef8ad9ca31a8372d0c353", dispatch_namespace="my-dispatch-namespace", script_name="this-is_my_script-01", @@ -375,12 +398,12 @@ async def test_raw_response_delete(self, async_client: AsyncCloudflare) -> None: assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" tag = await response.parse() - assert_matches_type(object, tag, path=["response"]) + assert_matches_type(TagDeleteResponse, tag, path=["response"]) @parametrize async def test_streaming_response_delete(self, async_client: AsyncCloudflare) -> None: async with async_client.workers_for_platforms.dispatch.namespaces.scripts.tags.with_streaming_response.delete( - tag="my-tag", + tag="environment", account_id="023e105f4ecef8ad9ca31a8372d0c353", dispatch_namespace="my-dispatch-namespace", script_name="this-is_my_script-01", @@ -389,7 +412,7 @@ async def test_streaming_response_delete(self, async_client: AsyncCloudflare) -> assert response.http_request.headers.get("X-Stainless-Lang") == "python" tag = await response.parse() - assert_matches_type(object, tag, path=["response"]) + assert_matches_type(TagDeleteResponse, tag, path=["response"]) assert cast(Any, response.is_closed) is True @@ -397,7 +420,7 @@ async def test_streaming_response_delete(self, async_client: AsyncCloudflare) -> async def test_path_params_delete(self, async_client: AsyncCloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): await async_client.workers_for_platforms.dispatch.namespaces.scripts.tags.with_raw_response.delete( - tag="my-tag", + tag="environment", account_id="", dispatch_namespace="my-dispatch-namespace", script_name="this-is_my_script-01", @@ -405,7 +428,7 @@ async def test_path_params_delete(self, async_client: AsyncCloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `dispatch_namespace` but received ''"): await async_client.workers_for_platforms.dispatch.namespaces.scripts.tags.with_raw_response.delete( - tag="my-tag", + tag="environment", account_id="023e105f4ecef8ad9ca31a8372d0c353", dispatch_namespace="", script_name="this-is_my_script-01", @@ -413,7 +436,7 @@ async def test_path_params_delete(self, async_client: AsyncCloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `script_name` but received ''"): await async_client.workers_for_platforms.dispatch.namespaces.scripts.tags.with_raw_response.delete( - tag="my-tag", + tag="environment", account_id="023e105f4ecef8ad9ca31a8372d0c353", dispatch_namespace="my-dispatch-namespace", script_name="", diff --git a/tests/api_resources/workers_for_platforms/dispatch/namespaces/test_scripts.py b/tests/api_resources/workers_for_platforms/dispatch/namespaces/test_scripts.py index 7288091cc0d..55a5e933bcf 100644 --- a/tests/api_resources/workers_for_platforms/dispatch/namespaces/test_scripts.py +++ b/tests/api_resources/workers_for_platforms/dispatch/namespaces/test_scripts.py @@ -63,6 +63,7 @@ def test_method_update_with_all_params(self, client: Cloudflare) -> None: "enabled": True, "cross_version_cache": True, }, + "code_update_strategy": {"mode": "immediate"}, "compatibility_date": "2021-01-01T00:00:00Z", "compatibility_flags": ["nodejs_compat"], "exports": { @@ -397,6 +398,7 @@ async def test_method_update_with_all_params(self, async_client: AsyncCloudflare "enabled": True, "cross_version_cache": True, }, + "code_update_strategy": {"mode": "immediate"}, "compatibility_date": "2021-01-01T00:00:00Z", "compatibility_flags": ["nodejs_compat"], "exports": { diff --git a/tests/api_resources/zero_trust/access/applications/test_policies.py b/tests/api_resources/zero_trust/access/applications/test_policies.py index f6a24c86363..9efd6a668f3 100644 --- a/tests/api_resources/zero_trust/access/applications/test_policies.py +++ b/tests/api_resources/zero_trust/access/applications/test_policies.py @@ -153,6 +153,7 @@ def test_method_create_with_all_params_overload_2(self, client: Cloudflare) -> N "mfa_disabled": False, "session_duration": "24h", }, + policy_resolution_account_id="policy_resolution_account_id", require=[{"certificate": {}}], ) assert_matches_type(Optional[PolicyCreateResponse], policy, path=["response"]) @@ -366,6 +367,7 @@ def test_method_update_with_all_params_overload_2(self, client: Cloudflare) -> N "mfa_disabled": False, "session_duration": "24h", }, + policy_resolution_account_id="policy_resolution_account_id", require=[{"certificate": {}}], ) assert_matches_type(Optional[PolicyUpdateResponse], policy, path=["response"]) @@ -815,6 +817,7 @@ async def test_method_create_with_all_params_overload_2(self, async_client: Asyn "mfa_disabled": False, "session_duration": "24h", }, + policy_resolution_account_id="policy_resolution_account_id", require=[{"certificate": {}}], ) assert_matches_type(Optional[PolicyCreateResponse], policy, path=["response"]) @@ -1028,6 +1031,7 @@ async def test_method_update_with_all_params_overload_2(self, async_client: Asyn "mfa_disabled": False, "session_duration": "24h", }, + policy_resolution_account_id="policy_resolution_account_id", require=[{"certificate": {}}], ) assert_matches_type(Optional[PolicyUpdateResponse], policy, path=["response"]) diff --git a/tests/api_resources/zero_trust/access/logs/test_jit_requests.py b/tests/api_resources/zero_trust/access/logs/test_jit_requests.py new file mode 100644 index 00000000000..7126d85e055 --- /dev/null +++ b/tests/api_resources/zero_trust/access/logs/test_jit_requests.py @@ -0,0 +1,227 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import os +from typing import Any, Optional, cast + +import pytest + +from cloudflare import Cloudflare, AsyncCloudflare +from tests.utils import assert_matches_type +from cloudflare._utils import parse_datetime +from cloudflare.pagination import SyncV4PagePaginationArray, AsyncV4PagePaginationArray +from cloudflare.types.zero_trust.access.logs import ( + JitRequestGetResponse, + JitRequestListResponse, +) + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestJitRequests: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @parametrize + def test_method_list(self, client: Cloudflare) -> None: + jit_request = client.zero_trust.access.logs.jit_requests.list( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + assert_matches_type(SyncV4PagePaginationArray[JitRequestListResponse], jit_request, path=["response"]) + + @parametrize + def test_method_list_with_all_params(self, client: Cloudflare) -> None: + jit_request = client.zero_trust.access.logs.jit_requests.list( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + page=0, + per_page=1000, + search="search", + since=parse_datetime("2019-12-27T18:11:19.117Z"), + status="PENDING", + until=parse_datetime("2019-12-27T18:11:19.117Z"), + ) + assert_matches_type(SyncV4PagePaginationArray[JitRequestListResponse], jit_request, path=["response"]) + + @parametrize + def test_raw_response_list(self, client: Cloudflare) -> None: + response = client.zero_trust.access.logs.jit_requests.with_raw_response.list( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + jit_request = response.parse() + assert_matches_type(SyncV4PagePaginationArray[JitRequestListResponse], jit_request, path=["response"]) + + @parametrize + def test_streaming_response_list(self, client: Cloudflare) -> None: + with client.zero_trust.access.logs.jit_requests.with_streaming_response.list( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + jit_request = response.parse() + assert_matches_type(SyncV4PagePaginationArray[JitRequestListResponse], jit_request, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_list(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.access.logs.jit_requests.with_raw_response.list( + account_id="", + ) + + @parametrize + def test_method_get(self, client: Cloudflare) -> None: + jit_request = client.zero_trust.access.logs.jit_requests.get( + knock_request_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + assert_matches_type(Optional[JitRequestGetResponse], jit_request, path=["response"]) + + @parametrize + def test_raw_response_get(self, client: Cloudflare) -> None: + response = client.zero_trust.access.logs.jit_requests.with_raw_response.get( + knock_request_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + jit_request = response.parse() + assert_matches_type(Optional[JitRequestGetResponse], jit_request, path=["response"]) + + @parametrize + def test_streaming_response_get(self, client: Cloudflare) -> None: + with client.zero_trust.access.logs.jit_requests.with_streaming_response.get( + knock_request_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + jit_request = response.parse() + assert_matches_type(Optional[JitRequestGetResponse], jit_request, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_get(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.access.logs.jit_requests.with_raw_response.get( + knock_request_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `knock_request_id` but received ''"): + client.zero_trust.access.logs.jit_requests.with_raw_response.get( + knock_request_id="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + +class TestAsyncJitRequests: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @parametrize + async def test_method_list(self, async_client: AsyncCloudflare) -> None: + jit_request = await async_client.zero_trust.access.logs.jit_requests.list( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + assert_matches_type(AsyncV4PagePaginationArray[JitRequestListResponse], jit_request, path=["response"]) + + @parametrize + async def test_method_list_with_all_params(self, async_client: AsyncCloudflare) -> None: + jit_request = await async_client.zero_trust.access.logs.jit_requests.list( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + page=0, + per_page=1000, + search="search", + since=parse_datetime("2019-12-27T18:11:19.117Z"), + status="PENDING", + until=parse_datetime("2019-12-27T18:11:19.117Z"), + ) + assert_matches_type(AsyncV4PagePaginationArray[JitRequestListResponse], jit_request, path=["response"]) + + @parametrize + async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.access.logs.jit_requests.with_raw_response.list( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + jit_request = await response.parse() + assert_matches_type(AsyncV4PagePaginationArray[JitRequestListResponse], jit_request, path=["response"]) + + @parametrize + async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.access.logs.jit_requests.with_streaming_response.list( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + jit_request = await response.parse() + assert_matches_type(AsyncV4PagePaginationArray[JitRequestListResponse], jit_request, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_list(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.access.logs.jit_requests.with_raw_response.list( + account_id="", + ) + + @parametrize + async def test_method_get(self, async_client: AsyncCloudflare) -> None: + jit_request = await async_client.zero_trust.access.logs.jit_requests.get( + knock_request_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + assert_matches_type(Optional[JitRequestGetResponse], jit_request, path=["response"]) + + @parametrize + async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.access.logs.jit_requests.with_raw_response.get( + knock_request_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + jit_request = await response.parse() + assert_matches_type(Optional[JitRequestGetResponse], jit_request, path=["response"]) + + @parametrize + async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.access.logs.jit_requests.with_streaming_response.get( + knock_request_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + jit_request = await response.parse() + assert_matches_type(Optional[JitRequestGetResponse], jit_request, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_get(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.access.logs.jit_requests.with_raw_response.get( + knock_request_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `knock_request_id` but received ''"): + await async_client.zero_trust.access.logs.jit_requests.with_raw_response.get( + knock_request_id="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) diff --git a/tests/api_resources/zero_trust/access/mfa/__init__.py b/tests/api_resources/zero_trust/access/mfa/__init__.py new file mode 100644 index 00000000000..fd8019a9a1a --- /dev/null +++ b/tests/api_resources/zero_trust/access/mfa/__init__.py @@ -0,0 +1 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. diff --git a/tests/api_resources/zero_trust/access/mfa/test_authenticator_catalog.py b/tests/api_resources/zero_trust/access/mfa/test_authenticator_catalog.py new file mode 100644 index 00000000000..35a60ecf177 --- /dev/null +++ b/tests/api_resources/zero_trust/access/mfa/test_authenticator_catalog.py @@ -0,0 +1,105 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import os +from typing import Any, cast + +import pytest + +from cloudflare import Cloudflare, AsyncCloudflare +from tests.utils import assert_matches_type +from cloudflare.pagination import SyncSinglePage, AsyncSinglePage +from cloudflare.types.zero_trust.access.mfa import AuthenticatorCatalogListResponse + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestAuthenticatorCatalog: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @parametrize + def test_method_list(self, client: Cloudflare) -> None: + authenticator_catalog = client.zero_trust.access.mfa.authenticator_catalog.list( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + assert_matches_type(SyncSinglePage[AuthenticatorCatalogListResponse], authenticator_catalog, path=["response"]) + + @parametrize + def test_raw_response_list(self, client: Cloudflare) -> None: + response = client.zero_trust.access.mfa.authenticator_catalog.with_raw_response.list( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + authenticator_catalog = response.parse() + assert_matches_type(SyncSinglePage[AuthenticatorCatalogListResponse], authenticator_catalog, path=["response"]) + + @parametrize + def test_streaming_response_list(self, client: Cloudflare) -> None: + with client.zero_trust.access.mfa.authenticator_catalog.with_streaming_response.list( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + authenticator_catalog = response.parse() + assert_matches_type( + SyncSinglePage[AuthenticatorCatalogListResponse], authenticator_catalog, path=["response"] + ) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_list(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.access.mfa.authenticator_catalog.with_raw_response.list( + account_id="", + ) + + +class TestAsyncAuthenticatorCatalog: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @parametrize + async def test_method_list(self, async_client: AsyncCloudflare) -> None: + authenticator_catalog = await async_client.zero_trust.access.mfa.authenticator_catalog.list( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + assert_matches_type(AsyncSinglePage[AuthenticatorCatalogListResponse], authenticator_catalog, path=["response"]) + + @parametrize + async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.access.mfa.authenticator_catalog.with_raw_response.list( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + authenticator_catalog = await response.parse() + assert_matches_type(AsyncSinglePage[AuthenticatorCatalogListResponse], authenticator_catalog, path=["response"]) + + @parametrize + async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.access.mfa.authenticator_catalog.with_streaming_response.list( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + authenticator_catalog = await response.parse() + assert_matches_type( + AsyncSinglePage[AuthenticatorCatalogListResponse], authenticator_catalog, path=["response"] + ) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_list(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.access.mfa.authenticator_catalog.with_raw_response.list( + account_id="", + ) diff --git a/tests/api_resources/zero_trust/access/test_applications.py b/tests/api_resources/zero_trust/access/test_applications.py index cb9250e4383..ed9ba899447 100644 --- a/tests/api_resources/zero_trust/access/test_applications.py +++ b/tests/api_resources/zero_trust/access/test_applications.py @@ -28,8 +28,9 @@ class TestApplications: @parametrize def test_method_create_overload_1(self, client: Cloudflare) -> None: application = client.zero_trust.access.applications.create( - domain="test.example.com/admin", + oauth_configuration={}, type="self_hosted", + user_populations=["f174e90a-fafe-4643-bbbc-4a0ed4fc8415"], account_id="account_id", ) assert_matches_type(Optional[ApplicationCreateResponse], application, path=["response"]) @@ -37,6 +38,106 @@ def test_method_create_overload_1(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize def test_method_create_with_all_params_overload_1(self, client: Cloudflare) -> None: + application = client.zero_trust.access.applications.create( + oauth_configuration={ + "dynamic_client_registration": { + "allow_any_on_localhost": True, + "allow_any_on_loopback": True, + "allowed_uris": ["https://example.com/callback", "com.example.app:/oauth/callback"], + "enabled": True, + }, + "enabled": True, + "grant": { + "access_token_lifetime": "5m", + "session_duration": "24h", + }, + }, + type="self_hosted", + user_populations=["f174e90a-fafe-4643-bbbc-4a0ed4fc8415"], + account_id="account_id", + allowed_idps=["699d98642c564d2e855e9661899b7252"], + destinations=[ + { + "uri": "uri", + "overrides": [ + { + "behavior": "public", + "path_pattern": "/health/*", + } + ], + "type": "public", + } + ], + domain="test.example.com/admin", + name="Admin Site", + self_hosted_domains=["test.example.com/admin", "test.anotherexample.com/staff"], + ) + assert_matches_type(Optional[ApplicationCreateResponse], application, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_raw_response_create_overload_1(self, client: Cloudflare) -> None: + response = client.zero_trust.access.applications.with_raw_response.create( + oauth_configuration={}, + type="self_hosted", + user_populations=["f174e90a-fafe-4643-bbbc-4a0ed4fc8415"], + account_id="account_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + application = response.parse() + assert_matches_type(Optional[ApplicationCreateResponse], application, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_streaming_response_create_overload_1(self, client: Cloudflare) -> None: + with client.zero_trust.access.applications.with_streaming_response.create( + oauth_configuration={}, + type="self_hosted", + user_populations=["f174e90a-fafe-4643-bbbc-4a0ed4fc8415"], + account_id="account_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + application = response.parse() + assert_matches_type(Optional[ApplicationCreateResponse], application, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_path_params_create_overload_1(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"You must provide either account_id or zone_id"): + client.zero_trust.access.applications.with_raw_response.create( + oauth_configuration={}, + type="self_hosted", + user_populations=["f174e90a-fafe-4643-bbbc-4a0ed4fc8415"], + account_id="", + ) + + with pytest.raises(ValueError, match=r"You must provide either account_id or zone_id"): + client.zero_trust.access.applications.with_raw_response.create( + oauth_configuration={}, + type="self_hosted", + user_populations=["f174e90a-fafe-4643-bbbc-4a0ed4fc8415"], + account_id="account_id", + ) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_method_create_overload_2(self, client: Cloudflare) -> None: + application = client.zero_trust.access.applications.create( + domain="test.example.com/admin", + type="self_hosted", + account_id="account_id", + ) + assert_matches_type(Optional[ApplicationCreateResponse], application, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_method_create_with_all_params_overload_2(self, client: Cloudflare) -> None: application = client.zero_trust.access.applications.create( domain="test.example.com/admin", type="self_hosted", @@ -212,7 +313,7 @@ def test_method_create_with_all_params_overload_1(self, client: Cloudflare) -> N @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_raw_response_create_overload_1(self, client: Cloudflare) -> None: + def test_raw_response_create_overload_2(self, client: Cloudflare) -> None: response = client.zero_trust.access.applications.with_raw_response.create( domain="test.example.com/admin", type="self_hosted", @@ -226,7 +327,7 @@ def test_raw_response_create_overload_1(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_streaming_response_create_overload_1(self, client: Cloudflare) -> None: + def test_streaming_response_create_overload_2(self, client: Cloudflare) -> None: with client.zero_trust.access.applications.with_streaming_response.create( domain="test.example.com/admin", type="self_hosted", @@ -242,7 +343,7 @@ def test_streaming_response_create_overload_1(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_path_params_create_overload_1(self, client: Cloudflare) -> None: + def test_path_params_create_overload_2(self, client: Cloudflare) -> None: with pytest.raises(ValueError, match=r"You must provide either account_id or zone_id"): client.zero_trust.access.applications.with_raw_response.create( domain="test.example.com/admin", @@ -259,7 +360,7 @@ def test_path_params_create_overload_1(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_method_create_overload_2(self, client: Cloudflare) -> None: + def test_method_create_overload_3(self, client: Cloudflare) -> None: application = client.zero_trust.access.applications.create( account_id="account_id", ) @@ -267,7 +368,7 @@ def test_method_create_overload_2(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_method_create_with_all_params_overload_2(self, client: Cloudflare) -> None: + def test_method_create_with_all_params_overload_3(self, client: Cloudflare) -> None: application = client.zero_trust.access.applications.create( account_id="account_id", allowed_idps=["699d98642c564d2e855e9661899b7252"], @@ -338,7 +439,7 @@ def test_method_create_with_all_params_overload_2(self, client: Cloudflare) -> N @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_raw_response_create_overload_2(self, client: Cloudflare) -> None: + def test_raw_response_create_overload_3(self, client: Cloudflare) -> None: response = client.zero_trust.access.applications.with_raw_response.create( account_id="account_id", ) @@ -350,7 +451,7 @@ def test_raw_response_create_overload_2(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_streaming_response_create_overload_2(self, client: Cloudflare) -> None: + def test_streaming_response_create_overload_3(self, client: Cloudflare) -> None: with client.zero_trust.access.applications.with_streaming_response.create( account_id="account_id", ) as response: @@ -364,7 +465,7 @@ def test_streaming_response_create_overload_2(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_path_params_create_overload_2(self, client: Cloudflare) -> None: + def test_path_params_create_overload_3(self, client: Cloudflare) -> None: with pytest.raises(ValueError, match=r"You must provide either account_id or zone_id"): client.zero_trust.access.applications.with_raw_response.create( account_id="", @@ -377,7 +478,7 @@ def test_path_params_create_overload_2(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_method_create_overload_3(self, client: Cloudflare) -> None: + def test_method_create_overload_4(self, client: Cloudflare) -> None: application = client.zero_trust.access.applications.create( domain="test.example.com/admin", type="self_hosted", @@ -387,7 +488,7 @@ def test_method_create_overload_3(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_method_create_with_all_params_overload_3(self, client: Cloudflare) -> None: + def test_method_create_with_all_params_overload_4(self, client: Cloudflare) -> None: application = client.zero_trust.access.applications.create( domain="test.example.com/admin", type="self_hosted", @@ -563,7 +664,7 @@ def test_method_create_with_all_params_overload_3(self, client: Cloudflare) -> N @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_raw_response_create_overload_3(self, client: Cloudflare) -> None: + def test_raw_response_create_overload_4(self, client: Cloudflare) -> None: response = client.zero_trust.access.applications.with_raw_response.create( domain="test.example.com/admin", type="self_hosted", @@ -577,7 +678,7 @@ def test_raw_response_create_overload_3(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_streaming_response_create_overload_3(self, client: Cloudflare) -> None: + def test_streaming_response_create_overload_4(self, client: Cloudflare) -> None: with client.zero_trust.access.applications.with_streaming_response.create( domain="test.example.com/admin", type="self_hosted", @@ -593,7 +694,7 @@ def test_streaming_response_create_overload_3(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_path_params_create_overload_3(self, client: Cloudflare) -> None: + def test_path_params_create_overload_4(self, client: Cloudflare) -> None: with pytest.raises(ValueError, match=r"You must provide either account_id or zone_id"): client.zero_trust.access.applications.with_raw_response.create( domain="test.example.com/admin", @@ -610,7 +711,7 @@ def test_path_params_create_overload_3(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_method_create_overload_4(self, client: Cloudflare) -> None: + def test_method_create_overload_5(self, client: Cloudflare) -> None: application = client.zero_trust.access.applications.create( domain="test.example.com/admin", type="self_hosted", @@ -620,7 +721,7 @@ def test_method_create_overload_4(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_method_create_with_all_params_overload_4(self, client: Cloudflare) -> None: + def test_method_create_with_all_params_overload_5(self, client: Cloudflare) -> None: application = client.zero_trust.access.applications.create( domain="test.example.com/admin", type="self_hosted", @@ -796,7 +897,7 @@ def test_method_create_with_all_params_overload_4(self, client: Cloudflare) -> N @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_raw_response_create_overload_4(self, client: Cloudflare) -> None: + def test_raw_response_create_overload_5(self, client: Cloudflare) -> None: response = client.zero_trust.access.applications.with_raw_response.create( domain="test.example.com/admin", type="self_hosted", @@ -810,7 +911,7 @@ def test_raw_response_create_overload_4(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_streaming_response_create_overload_4(self, client: Cloudflare) -> None: + def test_streaming_response_create_overload_5(self, client: Cloudflare) -> None: with client.zero_trust.access.applications.with_streaming_response.create( domain="test.example.com/admin", type="self_hosted", @@ -826,7 +927,7 @@ def test_streaming_response_create_overload_4(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_path_params_create_overload_4(self, client: Cloudflare) -> None: + def test_path_params_create_overload_5(self, client: Cloudflare) -> None: with pytest.raises(ValueError, match=r"You must provide either account_id or zone_id"): client.zero_trust.access.applications.with_raw_response.create( domain="test.example.com/admin", @@ -843,7 +944,7 @@ def test_path_params_create_overload_4(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_method_create_overload_5(self, client: Cloudflare) -> None: + def test_method_create_overload_6(self, client: Cloudflare) -> None: application = client.zero_trust.access.applications.create( type="self_hosted", account_id="account_id", @@ -852,7 +953,7 @@ def test_method_create_overload_5(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_method_create_with_all_params_overload_5(self, client: Cloudflare) -> None: + def test_method_create_with_all_params_overload_6(self, client: Cloudflare) -> None: application = client.zero_trust.access.applications.create( type="self_hosted", account_id="account_id", @@ -885,7 +986,7 @@ def test_method_create_with_all_params_overload_5(self, client: Cloudflare) -> N @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_raw_response_create_overload_5(self, client: Cloudflare) -> None: + def test_raw_response_create_overload_6(self, client: Cloudflare) -> None: response = client.zero_trust.access.applications.with_raw_response.create( type="self_hosted", account_id="account_id", @@ -898,7 +999,7 @@ def test_raw_response_create_overload_5(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_streaming_response_create_overload_5(self, client: Cloudflare) -> None: + def test_streaming_response_create_overload_6(self, client: Cloudflare) -> None: with client.zero_trust.access.applications.with_streaming_response.create( type="self_hosted", account_id="account_id", @@ -913,7 +1014,7 @@ def test_streaming_response_create_overload_5(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_path_params_create_overload_5(self, client: Cloudflare) -> None: + def test_path_params_create_overload_6(self, client: Cloudflare) -> None: with pytest.raises(ValueError, match=r"You must provide either account_id or zone_id"): client.zero_trust.access.applications.with_raw_response.create( type="self_hosted", @@ -928,7 +1029,7 @@ def test_path_params_create_overload_5(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_method_create_overload_6(self, client: Cloudflare) -> None: + def test_method_create_overload_7(self, client: Cloudflare) -> None: application = client.zero_trust.access.applications.create( type="self_hosted", account_id="account_id", @@ -937,7 +1038,7 @@ def test_method_create_overload_6(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_method_create_with_all_params_overload_6(self, client: Cloudflare) -> None: + def test_method_create_with_all_params_overload_7(self, client: Cloudflare) -> None: application = client.zero_trust.access.applications.create( type="self_hosted", account_id="account_id", @@ -953,7 +1054,7 @@ def test_method_create_with_all_params_overload_6(self, client: Cloudflare) -> N @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_raw_response_create_overload_6(self, client: Cloudflare) -> None: + def test_raw_response_create_overload_7(self, client: Cloudflare) -> None: response = client.zero_trust.access.applications.with_raw_response.create( type="self_hosted", account_id="account_id", @@ -966,7 +1067,7 @@ def test_raw_response_create_overload_6(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_streaming_response_create_overload_6(self, client: Cloudflare) -> None: + def test_streaming_response_create_overload_7(self, client: Cloudflare) -> None: with client.zero_trust.access.applications.with_streaming_response.create( type="self_hosted", account_id="account_id", @@ -981,7 +1082,7 @@ def test_streaming_response_create_overload_6(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_path_params_create_overload_6(self, client: Cloudflare) -> None: + def test_path_params_create_overload_7(self, client: Cloudflare) -> None: with pytest.raises(ValueError, match=r"You must provide either account_id or zone_id"): client.zero_trust.access.applications.with_raw_response.create( type="self_hosted", @@ -996,7 +1097,7 @@ def test_path_params_create_overload_6(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_method_create_overload_7(self, client: Cloudflare) -> None: + def test_method_create_overload_8(self, client: Cloudflare) -> None: application = client.zero_trust.access.applications.create( type="self_hosted", account_id="account_id", @@ -1005,7 +1106,7 @@ def test_method_create_overload_7(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_method_create_with_all_params_overload_7(self, client: Cloudflare) -> None: + def test_method_create_with_all_params_overload_8(self, client: Cloudflare) -> None: application = client.zero_trust.access.applications.create( type="self_hosted", account_id="account_id", @@ -1021,7 +1122,7 @@ def test_method_create_with_all_params_overload_7(self, client: Cloudflare) -> N @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_raw_response_create_overload_7(self, client: Cloudflare) -> None: + def test_raw_response_create_overload_8(self, client: Cloudflare) -> None: response = client.zero_trust.access.applications.with_raw_response.create( type="self_hosted", account_id="account_id", @@ -1034,7 +1135,7 @@ def test_raw_response_create_overload_7(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_streaming_response_create_overload_7(self, client: Cloudflare) -> None: + def test_streaming_response_create_overload_8(self, client: Cloudflare) -> None: with client.zero_trust.access.applications.with_streaming_response.create( type="self_hosted", account_id="account_id", @@ -1049,7 +1150,7 @@ def test_streaming_response_create_overload_7(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_path_params_create_overload_7(self, client: Cloudflare) -> None: + def test_path_params_create_overload_8(self, client: Cloudflare) -> None: with pytest.raises(ValueError, match=r"You must provide either account_id or zone_id"): client.zero_trust.access.applications.with_raw_response.create( type="self_hosted", @@ -1064,7 +1165,7 @@ def test_path_params_create_overload_7(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_method_create_overload_8(self, client: Cloudflare) -> None: + def test_method_create_overload_9(self, client: Cloudflare) -> None: application = client.zero_trust.access.applications.create( type="self_hosted", account_id="account_id", @@ -1073,7 +1174,7 @@ def test_method_create_overload_8(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_method_create_with_all_params_overload_8(self, client: Cloudflare) -> None: + def test_method_create_with_all_params_overload_9(self, client: Cloudflare) -> None: application = client.zero_trust.access.applications.create( type="self_hosted", account_id="account_id", @@ -1091,7 +1192,7 @@ def test_method_create_with_all_params_overload_8(self, client: Cloudflare) -> N @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_raw_response_create_overload_8(self, client: Cloudflare) -> None: + def test_raw_response_create_overload_9(self, client: Cloudflare) -> None: response = client.zero_trust.access.applications.with_raw_response.create( type="self_hosted", account_id="account_id", @@ -1104,7 +1205,7 @@ def test_raw_response_create_overload_8(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_streaming_response_create_overload_8(self, client: Cloudflare) -> None: + def test_streaming_response_create_overload_9(self, client: Cloudflare) -> None: with client.zero_trust.access.applications.with_streaming_response.create( type="self_hosted", account_id="account_id", @@ -1119,7 +1220,7 @@ def test_streaming_response_create_overload_8(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_path_params_create_overload_8(self, client: Cloudflare) -> None: + def test_path_params_create_overload_9(self, client: Cloudflare) -> None: with pytest.raises(ValueError, match=r"You must provide either account_id or zone_id"): client.zero_trust.access.applications.with_raw_response.create( type="self_hosted", @@ -1134,7 +1235,7 @@ def test_path_params_create_overload_8(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_method_create_overload_9(self, client: Cloudflare) -> None: + def test_method_create_overload_10(self, client: Cloudflare) -> None: application = client.zero_trust.access.applications.create( account_id="account_id", ) @@ -1142,7 +1243,7 @@ def test_method_create_overload_9(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_method_create_with_all_params_overload_9(self, client: Cloudflare) -> None: + def test_method_create_with_all_params_overload_10(self, client: Cloudflare) -> None: application = client.zero_trust.access.applications.create( account_id="account_id", app_launcher_visible=True, @@ -1157,7 +1258,7 @@ def test_method_create_with_all_params_overload_9(self, client: Cloudflare) -> N @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_raw_response_create_overload_9(self, client: Cloudflare) -> None: + def test_raw_response_create_overload_10(self, client: Cloudflare) -> None: response = client.zero_trust.access.applications.with_raw_response.create( account_id="account_id", ) @@ -1169,7 +1270,7 @@ def test_raw_response_create_overload_9(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_streaming_response_create_overload_9(self, client: Cloudflare) -> None: + def test_streaming_response_create_overload_10(self, client: Cloudflare) -> None: with client.zero_trust.access.applications.with_streaming_response.create( account_id="account_id", ) as response: @@ -1183,7 +1284,7 @@ def test_streaming_response_create_overload_9(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_path_params_create_overload_9(self, client: Cloudflare) -> None: + def test_path_params_create_overload_10(self, client: Cloudflare) -> None: with pytest.raises(ValueError, match=r"You must provide either account_id or zone_id"): client.zero_trust.access.applications.with_raw_response.create( account_id="", @@ -1196,7 +1297,7 @@ def test_path_params_create_overload_9(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_method_create_overload_10(self, client: Cloudflare) -> None: + def test_method_create_overload_11(self, client: Cloudflare) -> None: application = client.zero_trust.access.applications.create( target_criteria=[ { @@ -1211,7 +1312,7 @@ def test_method_create_overload_10(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_method_create_with_all_params_overload_10(self, client: Cloudflare) -> None: + def test_method_create_with_all_params_overload_11(self, client: Cloudflare) -> None: application = client.zero_trust.access.applications.create( target_criteria=[ { @@ -1257,15 +1358,17 @@ def test_method_create_with_all_params_overload_10(self, client: Cloudflare) -> "mfa_disabled": False, "session_duration": "24h", }, + "policy_resolution_account_id": "policy_resolution_account_id", "require": [{"certificate": {}}], } ], + session_duration="8h", ) assert_matches_type(Optional[ApplicationCreateResponse], application, path=["response"]) @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_raw_response_create_overload_10(self, client: Cloudflare) -> None: + def test_raw_response_create_overload_11(self, client: Cloudflare) -> None: response = client.zero_trust.access.applications.with_raw_response.create( target_criteria=[ { @@ -1284,7 +1387,7 @@ def test_raw_response_create_overload_10(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_streaming_response_create_overload_10(self, client: Cloudflare) -> None: + def test_streaming_response_create_overload_11(self, client: Cloudflare) -> None: with client.zero_trust.access.applications.with_streaming_response.create( target_criteria=[ { @@ -1305,7 +1408,7 @@ def test_streaming_response_create_overload_10(self, client: Cloudflare) -> None @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_path_params_create_overload_10(self, client: Cloudflare) -> None: + def test_path_params_create_overload_11(self, client: Cloudflare) -> None: with pytest.raises(ValueError, match=r"You must provide either account_id or zone_id"): client.zero_trust.access.applications.with_raw_response.create( target_criteria=[ @@ -1332,7 +1435,7 @@ def test_path_params_create_overload_10(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_method_create_overload_11(self, client: Cloudflare) -> None: + def test_method_create_overload_12(self, client: Cloudflare) -> None: application = client.zero_trust.access.applications.create( domain="test.example.com/admin", target_criteria=[ @@ -1348,7 +1451,7 @@ def test_method_create_overload_11(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_method_create_with_all_params_overload_11(self, client: Cloudflare) -> None: + def test_method_create_with_all_params_overload_12(self, client: Cloudflare) -> None: application = client.zero_trust.access.applications.create( domain="test.example.com/admin", target_criteria=[ @@ -1543,7 +1646,7 @@ def test_method_create_with_all_params_overload_11(self, client: Cloudflare) -> @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_raw_response_create_overload_11(self, client: Cloudflare) -> None: + def test_raw_response_create_overload_12(self, client: Cloudflare) -> None: response = client.zero_trust.access.applications.with_raw_response.create( domain="test.example.com/admin", target_criteria=[ @@ -1563,7 +1666,7 @@ def test_raw_response_create_overload_11(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_streaming_response_create_overload_11(self, client: Cloudflare) -> None: + def test_streaming_response_create_overload_12(self, client: Cloudflare) -> None: with client.zero_trust.access.applications.with_streaming_response.create( domain="test.example.com/admin", target_criteria=[ @@ -1585,7 +1688,7 @@ def test_streaming_response_create_overload_11(self, client: Cloudflare) -> None @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_path_params_create_overload_11(self, client: Cloudflare) -> None: + def test_path_params_create_overload_12(self, client: Cloudflare) -> None: with pytest.raises(ValueError, match=r"You must provide either account_id or zone_id"): client.zero_trust.access.applications.with_raw_response.create( domain="test.example.com/admin", @@ -1614,7 +1717,7 @@ def test_path_params_create_overload_11(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_method_create_overload_12(self, client: Cloudflare) -> None: + def test_method_create_overload_13(self, client: Cloudflare) -> None: application = client.zero_trust.access.applications.create( type="mcp", account_id="account_id", @@ -1623,7 +1726,7 @@ def test_method_create_overload_12(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_method_create_with_all_params_overload_12(self, client: Cloudflare) -> None: + def test_method_create_with_all_params_overload_13(self, client: Cloudflare) -> None: application = client.zero_trust.access.applications.create( type="mcp", account_id="account_id", @@ -1773,7 +1876,7 @@ def test_method_create_with_all_params_overload_12(self, client: Cloudflare) -> @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_raw_response_create_overload_12(self, client: Cloudflare) -> None: + def test_raw_response_create_overload_13(self, client: Cloudflare) -> None: response = client.zero_trust.access.applications.with_raw_response.create( type="mcp", account_id="account_id", @@ -1786,7 +1889,7 @@ def test_raw_response_create_overload_12(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_streaming_response_create_overload_12(self, client: Cloudflare) -> None: + def test_streaming_response_create_overload_13(self, client: Cloudflare) -> None: with client.zero_trust.access.applications.with_streaming_response.create( type="mcp", account_id="account_id", @@ -1801,7 +1904,7 @@ def test_streaming_response_create_overload_12(self, client: Cloudflare) -> None @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_path_params_create_overload_12(self, client: Cloudflare) -> None: + def test_path_params_create_overload_13(self, client: Cloudflare) -> None: with pytest.raises(ValueError, match=r"You must provide either account_id or zone_id"): client.zero_trust.access.applications.with_raw_response.create( type="mcp", @@ -1816,7 +1919,7 @@ def test_path_params_create_overload_12(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_method_create_overload_13(self, client: Cloudflare) -> None: + def test_method_create_overload_14(self, client: Cloudflare) -> None: application = client.zero_trust.access.applications.create( type="mcp_portal", account_id="account_id", @@ -1825,7 +1928,7 @@ def test_method_create_overload_13(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_method_create_with_all_params_overload_13(self, client: Cloudflare) -> None: + def test_method_create_with_all_params_overload_14(self, client: Cloudflare) -> None: application = client.zero_trust.access.applications.create( type="mcp_portal", account_id="account_id", @@ -1976,7 +2079,7 @@ def test_method_create_with_all_params_overload_13(self, client: Cloudflare) -> @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_raw_response_create_overload_13(self, client: Cloudflare) -> None: + def test_raw_response_create_overload_14(self, client: Cloudflare) -> None: response = client.zero_trust.access.applications.with_raw_response.create( type="mcp_portal", account_id="account_id", @@ -1989,7 +2092,7 @@ def test_raw_response_create_overload_13(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_streaming_response_create_overload_13(self, client: Cloudflare) -> None: + def test_streaming_response_create_overload_14(self, client: Cloudflare) -> None: with client.zero_trust.access.applications.with_streaming_response.create( type="mcp_portal", account_id="account_id", @@ -2004,7 +2107,7 @@ def test_streaming_response_create_overload_13(self, client: Cloudflare) -> None @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_path_params_create_overload_13(self, client: Cloudflare) -> None: + def test_path_params_create_overload_14(self, client: Cloudflare) -> None: with pytest.raises(ValueError, match=r"You must provide either account_id or zone_id"): client.zero_trust.access.applications.with_raw_response.create( type="mcp_portal", @@ -2022,8 +2125,9 @@ def test_path_params_create_overload_13(self, client: Cloudflare) -> None: def test_method_update_overload_1(self, client: Cloudflare) -> None: application = client.zero_trust.access.applications.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", - domain="test.example.com/admin", + oauth_configuration={}, type="self_hosted", + user_populations=["f174e90a-fafe-4643-bbbc-4a0ed4fc8415"], account_id="account_id", ) assert_matches_type(Optional[ApplicationUpdateResponse], application, path=["response"]) @@ -2031,6 +2135,121 @@ def test_method_update_overload_1(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize def test_method_update_with_all_params_overload_1(self, client: Cloudflare) -> None: + application = client.zero_trust.access.applications.update( + app_id="023e105f4ecef8ad9ca31a8372d0c353", + oauth_configuration={ + "dynamic_client_registration": { + "allow_any_on_localhost": True, + "allow_any_on_loopback": True, + "allowed_uris": ["https://example.com/callback", "com.example.app:/oauth/callback"], + "enabled": True, + }, + "enabled": True, + "grant": { + "access_token_lifetime": "5m", + "session_duration": "24h", + }, + }, + type="self_hosted", + user_populations=["f174e90a-fafe-4643-bbbc-4a0ed4fc8415"], + account_id="account_id", + allowed_idps=["699d98642c564d2e855e9661899b7252"], + destinations=[ + { + "uri": "uri", + "overrides": [ + { + "behavior": "public", + "path_pattern": "/health/*", + } + ], + "type": "public", + } + ], + domain="test.example.com/admin", + name="Admin Site", + self_hosted_domains=["test.example.com/admin", "test.anotherexample.com/staff"], + ) + assert_matches_type(Optional[ApplicationUpdateResponse], application, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_raw_response_update_overload_1(self, client: Cloudflare) -> None: + response = client.zero_trust.access.applications.with_raw_response.update( + app_id="023e105f4ecef8ad9ca31a8372d0c353", + oauth_configuration={}, + type="self_hosted", + user_populations=["f174e90a-fafe-4643-bbbc-4a0ed4fc8415"], + account_id="account_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + application = response.parse() + assert_matches_type(Optional[ApplicationUpdateResponse], application, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_streaming_response_update_overload_1(self, client: Cloudflare) -> None: + with client.zero_trust.access.applications.with_streaming_response.update( + app_id="023e105f4ecef8ad9ca31a8372d0c353", + oauth_configuration={}, + type="self_hosted", + user_populations=["f174e90a-fafe-4643-bbbc-4a0ed4fc8415"], + account_id="account_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + application = response.parse() + assert_matches_type(Optional[ApplicationUpdateResponse], application, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_path_params_update_overload_1(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `app_id` but received ''"): + client.zero_trust.access.applications.with_raw_response.update( + app_id="", + oauth_configuration={}, + type="self_hosted", + user_populations=["f174e90a-fafe-4643-bbbc-4a0ed4fc8415"], + account_id="account_id", + ) + + with pytest.raises(ValueError, match=r"You must provide either account_id or zone_id"): + client.zero_trust.access.applications.with_raw_response.update( + app_id="023e105f4ecef8ad9ca31a8372d0c353", + oauth_configuration={}, + type="self_hosted", + user_populations=["f174e90a-fafe-4643-bbbc-4a0ed4fc8415"], + account_id="", + ) + + with pytest.raises(ValueError, match=r"You must provide either account_id or zone_id"): + client.zero_trust.access.applications.with_raw_response.update( + app_id="023e105f4ecef8ad9ca31a8372d0c353", + oauth_configuration={}, + type="self_hosted", + user_populations=["f174e90a-fafe-4643-bbbc-4a0ed4fc8415"], + account_id="account_id", + ) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_method_update_overload_2(self, client: Cloudflare) -> None: + application = client.zero_trust.access.applications.update( + app_id="023e105f4ecef8ad9ca31a8372d0c353", + domain="test.example.com/admin", + type="self_hosted", + account_id="account_id", + ) + assert_matches_type(Optional[ApplicationUpdateResponse], application, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_method_update_with_all_params_overload_2(self, client: Cloudflare) -> None: application = client.zero_trust.access.applications.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", domain="test.example.com/admin", @@ -2207,7 +2426,7 @@ def test_method_update_with_all_params_overload_1(self, client: Cloudflare) -> N @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_raw_response_update_overload_1(self, client: Cloudflare) -> None: + def test_raw_response_update_overload_2(self, client: Cloudflare) -> None: response = client.zero_trust.access.applications.with_raw_response.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", domain="test.example.com/admin", @@ -2222,7 +2441,7 @@ def test_raw_response_update_overload_1(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_streaming_response_update_overload_1(self, client: Cloudflare) -> None: + def test_streaming_response_update_overload_2(self, client: Cloudflare) -> None: with client.zero_trust.access.applications.with_streaming_response.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", domain="test.example.com/admin", @@ -2239,7 +2458,7 @@ def test_streaming_response_update_overload_1(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_path_params_update_overload_1(self, client: Cloudflare) -> None: + def test_path_params_update_overload_2(self, client: Cloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `app_id` but received ''"): client.zero_trust.access.applications.with_raw_response.update( app_id="", @@ -2266,7 +2485,7 @@ def test_path_params_update_overload_1(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_method_update_overload_2(self, client: Cloudflare) -> None: + def test_method_update_overload_3(self, client: Cloudflare) -> None: application = client.zero_trust.access.applications.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", account_id="account_id", @@ -2275,7 +2494,7 @@ def test_method_update_overload_2(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_method_update_with_all_params_overload_2(self, client: Cloudflare) -> None: + def test_method_update_with_all_params_overload_3(self, client: Cloudflare) -> None: application = client.zero_trust.access.applications.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", account_id="account_id", @@ -2347,7 +2566,7 @@ def test_method_update_with_all_params_overload_2(self, client: Cloudflare) -> N @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_raw_response_update_overload_2(self, client: Cloudflare) -> None: + def test_raw_response_update_overload_3(self, client: Cloudflare) -> None: response = client.zero_trust.access.applications.with_raw_response.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", account_id="account_id", @@ -2360,7 +2579,7 @@ def test_raw_response_update_overload_2(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_streaming_response_update_overload_2(self, client: Cloudflare) -> None: + def test_streaming_response_update_overload_3(self, client: Cloudflare) -> None: with client.zero_trust.access.applications.with_streaming_response.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", account_id="account_id", @@ -2375,7 +2594,7 @@ def test_streaming_response_update_overload_2(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_path_params_update_overload_2(self, client: Cloudflare) -> None: + def test_path_params_update_overload_3(self, client: Cloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `app_id` but received ''"): client.zero_trust.access.applications.with_raw_response.update( app_id="", @@ -2396,7 +2615,7 @@ def test_path_params_update_overload_2(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_method_update_overload_3(self, client: Cloudflare) -> None: + def test_method_update_overload_4(self, client: Cloudflare) -> None: application = client.zero_trust.access.applications.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", domain="test.example.com/admin", @@ -2407,7 +2626,7 @@ def test_method_update_overload_3(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_method_update_with_all_params_overload_3(self, client: Cloudflare) -> None: + def test_method_update_with_all_params_overload_4(self, client: Cloudflare) -> None: application = client.zero_trust.access.applications.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", domain="test.example.com/admin", @@ -2584,7 +2803,7 @@ def test_method_update_with_all_params_overload_3(self, client: Cloudflare) -> N @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_raw_response_update_overload_3(self, client: Cloudflare) -> None: + def test_raw_response_update_overload_4(self, client: Cloudflare) -> None: response = client.zero_trust.access.applications.with_raw_response.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", domain="test.example.com/admin", @@ -2599,7 +2818,7 @@ def test_raw_response_update_overload_3(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_streaming_response_update_overload_3(self, client: Cloudflare) -> None: + def test_streaming_response_update_overload_4(self, client: Cloudflare) -> None: with client.zero_trust.access.applications.with_streaming_response.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", domain="test.example.com/admin", @@ -2616,7 +2835,7 @@ def test_streaming_response_update_overload_3(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_path_params_update_overload_3(self, client: Cloudflare) -> None: + def test_path_params_update_overload_4(self, client: Cloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `app_id` but received ''"): client.zero_trust.access.applications.with_raw_response.update( app_id="", @@ -2643,7 +2862,7 @@ def test_path_params_update_overload_3(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_method_update_overload_4(self, client: Cloudflare) -> None: + def test_method_update_overload_5(self, client: Cloudflare) -> None: application = client.zero_trust.access.applications.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", domain="test.example.com/admin", @@ -2654,7 +2873,7 @@ def test_method_update_overload_4(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_method_update_with_all_params_overload_4(self, client: Cloudflare) -> None: + def test_method_update_with_all_params_overload_5(self, client: Cloudflare) -> None: application = client.zero_trust.access.applications.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", domain="test.example.com/admin", @@ -2831,7 +3050,7 @@ def test_method_update_with_all_params_overload_4(self, client: Cloudflare) -> N @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_raw_response_update_overload_4(self, client: Cloudflare) -> None: + def test_raw_response_update_overload_5(self, client: Cloudflare) -> None: response = client.zero_trust.access.applications.with_raw_response.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", domain="test.example.com/admin", @@ -2846,7 +3065,7 @@ def test_raw_response_update_overload_4(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_streaming_response_update_overload_4(self, client: Cloudflare) -> None: + def test_streaming_response_update_overload_5(self, client: Cloudflare) -> None: with client.zero_trust.access.applications.with_streaming_response.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", domain="test.example.com/admin", @@ -2863,7 +3082,7 @@ def test_streaming_response_update_overload_4(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_path_params_update_overload_4(self, client: Cloudflare) -> None: + def test_path_params_update_overload_5(self, client: Cloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `app_id` but received ''"): client.zero_trust.access.applications.with_raw_response.update( app_id="", @@ -2890,7 +3109,7 @@ def test_path_params_update_overload_4(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_method_update_overload_5(self, client: Cloudflare) -> None: + def test_method_update_overload_6(self, client: Cloudflare) -> None: application = client.zero_trust.access.applications.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", type="self_hosted", @@ -2900,7 +3119,7 @@ def test_method_update_overload_5(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_method_update_with_all_params_overload_5(self, client: Cloudflare) -> None: + def test_method_update_with_all_params_overload_6(self, client: Cloudflare) -> None: application = client.zero_trust.access.applications.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", type="self_hosted", @@ -2934,7 +3153,7 @@ def test_method_update_with_all_params_overload_5(self, client: Cloudflare) -> N @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_raw_response_update_overload_5(self, client: Cloudflare) -> None: + def test_raw_response_update_overload_6(self, client: Cloudflare) -> None: response = client.zero_trust.access.applications.with_raw_response.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", type="self_hosted", @@ -2948,7 +3167,7 @@ def test_raw_response_update_overload_5(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_streaming_response_update_overload_5(self, client: Cloudflare) -> None: + def test_streaming_response_update_overload_6(self, client: Cloudflare) -> None: with client.zero_trust.access.applications.with_streaming_response.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", type="self_hosted", @@ -2964,7 +3183,7 @@ def test_streaming_response_update_overload_5(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_path_params_update_overload_5(self, client: Cloudflare) -> None: + def test_path_params_update_overload_6(self, client: Cloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `app_id` but received ''"): client.zero_trust.access.applications.with_raw_response.update( app_id="", @@ -2988,7 +3207,7 @@ def test_path_params_update_overload_5(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_method_update_overload_6(self, client: Cloudflare) -> None: + def test_method_update_overload_7(self, client: Cloudflare) -> None: application = client.zero_trust.access.applications.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", type="self_hosted", @@ -2998,7 +3217,7 @@ def test_method_update_overload_6(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_method_update_with_all_params_overload_6(self, client: Cloudflare) -> None: + def test_method_update_with_all_params_overload_7(self, client: Cloudflare) -> None: application = client.zero_trust.access.applications.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", type="self_hosted", @@ -3015,7 +3234,7 @@ def test_method_update_with_all_params_overload_6(self, client: Cloudflare) -> N @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_raw_response_update_overload_6(self, client: Cloudflare) -> None: + def test_raw_response_update_overload_7(self, client: Cloudflare) -> None: response = client.zero_trust.access.applications.with_raw_response.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", type="self_hosted", @@ -3029,7 +3248,7 @@ def test_raw_response_update_overload_6(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_streaming_response_update_overload_6(self, client: Cloudflare) -> None: + def test_streaming_response_update_overload_7(self, client: Cloudflare) -> None: with client.zero_trust.access.applications.with_streaming_response.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", type="self_hosted", @@ -3045,7 +3264,7 @@ def test_streaming_response_update_overload_6(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_path_params_update_overload_6(self, client: Cloudflare) -> None: + def test_path_params_update_overload_7(self, client: Cloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `app_id` but received ''"): client.zero_trust.access.applications.with_raw_response.update( app_id="", @@ -3069,7 +3288,7 @@ def test_path_params_update_overload_6(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_method_update_overload_7(self, client: Cloudflare) -> None: + def test_method_update_overload_8(self, client: Cloudflare) -> None: application = client.zero_trust.access.applications.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", type="self_hosted", @@ -3079,7 +3298,7 @@ def test_method_update_overload_7(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_method_update_with_all_params_overload_7(self, client: Cloudflare) -> None: + def test_method_update_with_all_params_overload_8(self, client: Cloudflare) -> None: application = client.zero_trust.access.applications.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", type="self_hosted", @@ -3096,7 +3315,7 @@ def test_method_update_with_all_params_overload_7(self, client: Cloudflare) -> N @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_raw_response_update_overload_7(self, client: Cloudflare) -> None: + def test_raw_response_update_overload_8(self, client: Cloudflare) -> None: response = client.zero_trust.access.applications.with_raw_response.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", type="self_hosted", @@ -3110,7 +3329,7 @@ def test_raw_response_update_overload_7(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_streaming_response_update_overload_7(self, client: Cloudflare) -> None: + def test_streaming_response_update_overload_8(self, client: Cloudflare) -> None: with client.zero_trust.access.applications.with_streaming_response.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", type="self_hosted", @@ -3126,7 +3345,7 @@ def test_streaming_response_update_overload_7(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_path_params_update_overload_7(self, client: Cloudflare) -> None: + def test_path_params_update_overload_8(self, client: Cloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `app_id` but received ''"): client.zero_trust.access.applications.with_raw_response.update( app_id="", @@ -3150,7 +3369,7 @@ def test_path_params_update_overload_7(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_method_update_overload_8(self, client: Cloudflare) -> None: + def test_method_update_overload_9(self, client: Cloudflare) -> None: application = client.zero_trust.access.applications.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", type="self_hosted", @@ -3160,7 +3379,7 @@ def test_method_update_overload_8(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_method_update_with_all_params_overload_8(self, client: Cloudflare) -> None: + def test_method_update_with_all_params_overload_9(self, client: Cloudflare) -> None: application = client.zero_trust.access.applications.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", type="self_hosted", @@ -3179,7 +3398,7 @@ def test_method_update_with_all_params_overload_8(self, client: Cloudflare) -> N @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_raw_response_update_overload_8(self, client: Cloudflare) -> None: + def test_raw_response_update_overload_9(self, client: Cloudflare) -> None: response = client.zero_trust.access.applications.with_raw_response.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", type="self_hosted", @@ -3193,7 +3412,7 @@ def test_raw_response_update_overload_8(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_streaming_response_update_overload_8(self, client: Cloudflare) -> None: + def test_streaming_response_update_overload_9(self, client: Cloudflare) -> None: with client.zero_trust.access.applications.with_streaming_response.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", type="self_hosted", @@ -3209,7 +3428,7 @@ def test_streaming_response_update_overload_8(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_path_params_update_overload_8(self, client: Cloudflare) -> None: + def test_path_params_update_overload_9(self, client: Cloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `app_id` but received ''"): client.zero_trust.access.applications.with_raw_response.update( app_id="", @@ -3233,7 +3452,7 @@ def test_path_params_update_overload_8(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_method_update_overload_9(self, client: Cloudflare) -> None: + def test_method_update_overload_10(self, client: Cloudflare) -> None: application = client.zero_trust.access.applications.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", account_id="account_id", @@ -3242,7 +3461,7 @@ def test_method_update_overload_9(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_method_update_with_all_params_overload_9(self, client: Cloudflare) -> None: + def test_method_update_with_all_params_overload_10(self, client: Cloudflare) -> None: application = client.zero_trust.access.applications.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", account_id="account_id", @@ -3258,7 +3477,7 @@ def test_method_update_with_all_params_overload_9(self, client: Cloudflare) -> N @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_raw_response_update_overload_9(self, client: Cloudflare) -> None: + def test_raw_response_update_overload_10(self, client: Cloudflare) -> None: response = client.zero_trust.access.applications.with_raw_response.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", account_id="account_id", @@ -3271,7 +3490,7 @@ def test_raw_response_update_overload_9(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_streaming_response_update_overload_9(self, client: Cloudflare) -> None: + def test_streaming_response_update_overload_10(self, client: Cloudflare) -> None: with client.zero_trust.access.applications.with_streaming_response.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", account_id="account_id", @@ -3286,7 +3505,7 @@ def test_streaming_response_update_overload_9(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_path_params_update_overload_9(self, client: Cloudflare) -> None: + def test_path_params_update_overload_10(self, client: Cloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `app_id` but received ''"): client.zero_trust.access.applications.with_raw_response.update( app_id="", @@ -3307,7 +3526,7 @@ def test_path_params_update_overload_9(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_method_update_overload_10(self, client: Cloudflare) -> None: + def test_method_update_overload_11(self, client: Cloudflare) -> None: application = client.zero_trust.access.applications.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", target_criteria=[ @@ -3323,7 +3542,7 @@ def test_method_update_overload_10(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_method_update_with_all_params_overload_10(self, client: Cloudflare) -> None: + def test_method_update_with_all_params_overload_11(self, client: Cloudflare) -> None: application = client.zero_trust.access.applications.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", target_criteria=[ @@ -3370,15 +3589,17 @@ def test_method_update_with_all_params_overload_10(self, client: Cloudflare) -> "mfa_disabled": False, "session_duration": "24h", }, + "policy_resolution_account_id": "policy_resolution_account_id", "require": [{"certificate": {}}], } ], + session_duration="8h", ) assert_matches_type(Optional[ApplicationUpdateResponse], application, path=["response"]) @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_raw_response_update_overload_10(self, client: Cloudflare) -> None: + def test_raw_response_update_overload_11(self, client: Cloudflare) -> None: response = client.zero_trust.access.applications.with_raw_response.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", target_criteria=[ @@ -3398,7 +3619,7 @@ def test_raw_response_update_overload_10(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_streaming_response_update_overload_10(self, client: Cloudflare) -> None: + def test_streaming_response_update_overload_11(self, client: Cloudflare) -> None: with client.zero_trust.access.applications.with_streaming_response.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", target_criteria=[ @@ -3420,7 +3641,7 @@ def test_streaming_response_update_overload_10(self, client: Cloudflare) -> None @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_path_params_update_overload_10(self, client: Cloudflare) -> None: + def test_path_params_update_overload_11(self, client: Cloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `app_id` but received ''"): client.zero_trust.access.applications.with_raw_response.update( app_id="", @@ -3462,7 +3683,7 @@ def test_path_params_update_overload_10(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_method_update_overload_11(self, client: Cloudflare) -> None: + def test_method_update_overload_12(self, client: Cloudflare) -> None: application = client.zero_trust.access.applications.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", domain="test.example.com/admin", @@ -3479,7 +3700,7 @@ def test_method_update_overload_11(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_method_update_with_all_params_overload_11(self, client: Cloudflare) -> None: + def test_method_update_with_all_params_overload_12(self, client: Cloudflare) -> None: application = client.zero_trust.access.applications.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", domain="test.example.com/admin", @@ -3675,7 +3896,7 @@ def test_method_update_with_all_params_overload_11(self, client: Cloudflare) -> @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_raw_response_update_overload_11(self, client: Cloudflare) -> None: + def test_raw_response_update_overload_12(self, client: Cloudflare) -> None: response = client.zero_trust.access.applications.with_raw_response.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", domain="test.example.com/admin", @@ -3696,7 +3917,7 @@ def test_raw_response_update_overload_11(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_streaming_response_update_overload_11(self, client: Cloudflare) -> None: + def test_streaming_response_update_overload_12(self, client: Cloudflare) -> None: with client.zero_trust.access.applications.with_streaming_response.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", domain="test.example.com/admin", @@ -3719,7 +3940,7 @@ def test_streaming_response_update_overload_11(self, client: Cloudflare) -> None @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_path_params_update_overload_11(self, client: Cloudflare) -> None: + def test_path_params_update_overload_12(self, client: Cloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `app_id` but received ''"): client.zero_trust.access.applications.with_raw_response.update( app_id="", @@ -3764,7 +3985,7 @@ def test_path_params_update_overload_11(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_method_update_overload_12(self, client: Cloudflare) -> None: + def test_method_update_overload_13(self, client: Cloudflare) -> None: application = client.zero_trust.access.applications.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", type="mcp", @@ -3774,7 +3995,7 @@ def test_method_update_overload_12(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_method_update_with_all_params_overload_12(self, client: Cloudflare) -> None: + def test_method_update_with_all_params_overload_13(self, client: Cloudflare) -> None: application = client.zero_trust.access.applications.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", type="mcp", @@ -3925,7 +4146,7 @@ def test_method_update_with_all_params_overload_12(self, client: Cloudflare) -> @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_raw_response_update_overload_12(self, client: Cloudflare) -> None: + def test_raw_response_update_overload_13(self, client: Cloudflare) -> None: response = client.zero_trust.access.applications.with_raw_response.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", type="mcp", @@ -3939,7 +4160,7 @@ def test_raw_response_update_overload_12(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_streaming_response_update_overload_12(self, client: Cloudflare) -> None: + def test_streaming_response_update_overload_13(self, client: Cloudflare) -> None: with client.zero_trust.access.applications.with_streaming_response.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", type="mcp", @@ -3955,7 +4176,7 @@ def test_streaming_response_update_overload_12(self, client: Cloudflare) -> None @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_path_params_update_overload_12(self, client: Cloudflare) -> None: + def test_path_params_update_overload_13(self, client: Cloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `app_id` but received ''"): client.zero_trust.access.applications.with_raw_response.update( app_id="", @@ -3979,7 +4200,7 @@ def test_path_params_update_overload_12(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_method_update_overload_13(self, client: Cloudflare) -> None: + def test_method_update_overload_14(self, client: Cloudflare) -> None: application = client.zero_trust.access.applications.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", type="mcp_portal", @@ -3989,7 +4210,7 @@ def test_method_update_overload_13(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_method_update_with_all_params_overload_13(self, client: Cloudflare) -> None: + def test_method_update_with_all_params_overload_14(self, client: Cloudflare) -> None: application = client.zero_trust.access.applications.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", type="mcp_portal", @@ -4141,7 +4362,7 @@ def test_method_update_with_all_params_overload_13(self, client: Cloudflare) -> @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_raw_response_update_overload_13(self, client: Cloudflare) -> None: + def test_raw_response_update_overload_14(self, client: Cloudflare) -> None: response = client.zero_trust.access.applications.with_raw_response.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", type="mcp_portal", @@ -4155,7 +4376,7 @@ def test_raw_response_update_overload_13(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_streaming_response_update_overload_13(self, client: Cloudflare) -> None: + def test_streaming_response_update_overload_14(self, client: Cloudflare) -> None: with client.zero_trust.access.applications.with_streaming_response.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", type="mcp_portal", @@ -4171,7 +4392,7 @@ def test_streaming_response_update_overload_13(self, client: Cloudflare) -> None @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_path_params_update_overload_13(self, client: Cloudflare) -> None: + def test_path_params_update_overload_14(self, client: Cloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `app_id` but received ''"): client.zero_trust.access.applications.with_raw_response.update( app_id="", @@ -4467,8 +4688,9 @@ class TestAsyncApplications: @parametrize async def test_method_create_overload_1(self, async_client: AsyncCloudflare) -> None: application = await async_client.zero_trust.access.applications.create( - domain="test.example.com/admin", + oauth_configuration={}, type="self_hosted", + user_populations=["f174e90a-fafe-4643-bbbc-4a0ed4fc8415"], account_id="account_id", ) assert_matches_type(Optional[ApplicationCreateResponse], application, path=["response"]) @@ -4476,6 +4698,106 @@ async def test_method_create_overload_1(self, async_client: AsyncCloudflare) -> @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize async def test_method_create_with_all_params_overload_1(self, async_client: AsyncCloudflare) -> None: + application = await async_client.zero_trust.access.applications.create( + oauth_configuration={ + "dynamic_client_registration": { + "allow_any_on_localhost": True, + "allow_any_on_loopback": True, + "allowed_uris": ["https://example.com/callback", "com.example.app:/oauth/callback"], + "enabled": True, + }, + "enabled": True, + "grant": { + "access_token_lifetime": "5m", + "session_duration": "24h", + }, + }, + type="self_hosted", + user_populations=["f174e90a-fafe-4643-bbbc-4a0ed4fc8415"], + account_id="account_id", + allowed_idps=["699d98642c564d2e855e9661899b7252"], + destinations=[ + { + "uri": "uri", + "overrides": [ + { + "behavior": "public", + "path_pattern": "/health/*", + } + ], + "type": "public", + } + ], + domain="test.example.com/admin", + name="Admin Site", + self_hosted_domains=["test.example.com/admin", "test.anotherexample.com/staff"], + ) + assert_matches_type(Optional[ApplicationCreateResponse], application, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_raw_response_create_overload_1(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.access.applications.with_raw_response.create( + oauth_configuration={}, + type="self_hosted", + user_populations=["f174e90a-fafe-4643-bbbc-4a0ed4fc8415"], + account_id="account_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + application = await response.parse() + assert_matches_type(Optional[ApplicationCreateResponse], application, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_streaming_response_create_overload_1(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.access.applications.with_streaming_response.create( + oauth_configuration={}, + type="self_hosted", + user_populations=["f174e90a-fafe-4643-bbbc-4a0ed4fc8415"], + account_id="account_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + application = await response.parse() + assert_matches_type(Optional[ApplicationCreateResponse], application, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_path_params_create_overload_1(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"You must provide either account_id or zone_id"): + await async_client.zero_trust.access.applications.with_raw_response.create( + oauth_configuration={}, + type="self_hosted", + user_populations=["f174e90a-fafe-4643-bbbc-4a0ed4fc8415"], + account_id="", + ) + + with pytest.raises(ValueError, match=r"You must provide either account_id or zone_id"): + await async_client.zero_trust.access.applications.with_raw_response.create( + oauth_configuration={}, + type="self_hosted", + user_populations=["f174e90a-fafe-4643-bbbc-4a0ed4fc8415"], + account_id="account_id", + ) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_method_create_overload_2(self, async_client: AsyncCloudflare) -> None: + application = await async_client.zero_trust.access.applications.create( + domain="test.example.com/admin", + type="self_hosted", + account_id="account_id", + ) + assert_matches_type(Optional[ApplicationCreateResponse], application, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_method_create_with_all_params_overload_2(self, async_client: AsyncCloudflare) -> None: application = await async_client.zero_trust.access.applications.create( domain="test.example.com/admin", type="self_hosted", @@ -4651,7 +4973,7 @@ async def test_method_create_with_all_params_overload_1(self, async_client: Asyn @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_raw_response_create_overload_1(self, async_client: AsyncCloudflare) -> None: + async def test_raw_response_create_overload_2(self, async_client: AsyncCloudflare) -> None: response = await async_client.zero_trust.access.applications.with_raw_response.create( domain="test.example.com/admin", type="self_hosted", @@ -4665,7 +4987,7 @@ async def test_raw_response_create_overload_1(self, async_client: AsyncCloudflar @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_streaming_response_create_overload_1(self, async_client: AsyncCloudflare) -> None: + async def test_streaming_response_create_overload_2(self, async_client: AsyncCloudflare) -> None: async with async_client.zero_trust.access.applications.with_streaming_response.create( domain="test.example.com/admin", type="self_hosted", @@ -4681,7 +5003,7 @@ async def test_streaming_response_create_overload_1(self, async_client: AsyncClo @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_path_params_create_overload_1(self, async_client: AsyncCloudflare) -> None: + async def test_path_params_create_overload_2(self, async_client: AsyncCloudflare) -> None: with pytest.raises(ValueError, match=r"You must provide either account_id or zone_id"): await async_client.zero_trust.access.applications.with_raw_response.create( domain="test.example.com/admin", @@ -4698,7 +5020,7 @@ async def test_path_params_create_overload_1(self, async_client: AsyncCloudflare @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_method_create_overload_2(self, async_client: AsyncCloudflare) -> None: + async def test_method_create_overload_3(self, async_client: AsyncCloudflare) -> None: application = await async_client.zero_trust.access.applications.create( account_id="account_id", ) @@ -4706,7 +5028,7 @@ async def test_method_create_overload_2(self, async_client: AsyncCloudflare) -> @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_method_create_with_all_params_overload_2(self, async_client: AsyncCloudflare) -> None: + async def test_method_create_with_all_params_overload_3(self, async_client: AsyncCloudflare) -> None: application = await async_client.zero_trust.access.applications.create( account_id="account_id", allowed_idps=["699d98642c564d2e855e9661899b7252"], @@ -4777,7 +5099,7 @@ async def test_method_create_with_all_params_overload_2(self, async_client: Asyn @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_raw_response_create_overload_2(self, async_client: AsyncCloudflare) -> None: + async def test_raw_response_create_overload_3(self, async_client: AsyncCloudflare) -> None: response = await async_client.zero_trust.access.applications.with_raw_response.create( account_id="account_id", ) @@ -4789,7 +5111,7 @@ async def test_raw_response_create_overload_2(self, async_client: AsyncCloudflar @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_streaming_response_create_overload_2(self, async_client: AsyncCloudflare) -> None: + async def test_streaming_response_create_overload_3(self, async_client: AsyncCloudflare) -> None: async with async_client.zero_trust.access.applications.with_streaming_response.create( account_id="account_id", ) as response: @@ -4803,7 +5125,7 @@ async def test_streaming_response_create_overload_2(self, async_client: AsyncClo @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_path_params_create_overload_2(self, async_client: AsyncCloudflare) -> None: + async def test_path_params_create_overload_3(self, async_client: AsyncCloudflare) -> None: with pytest.raises(ValueError, match=r"You must provide either account_id or zone_id"): await async_client.zero_trust.access.applications.with_raw_response.create( account_id="", @@ -4816,7 +5138,7 @@ async def test_path_params_create_overload_2(self, async_client: AsyncCloudflare @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_method_create_overload_3(self, async_client: AsyncCloudflare) -> None: + async def test_method_create_overload_4(self, async_client: AsyncCloudflare) -> None: application = await async_client.zero_trust.access.applications.create( domain="test.example.com/admin", type="self_hosted", @@ -4826,7 +5148,7 @@ async def test_method_create_overload_3(self, async_client: AsyncCloudflare) -> @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_method_create_with_all_params_overload_3(self, async_client: AsyncCloudflare) -> None: + async def test_method_create_with_all_params_overload_4(self, async_client: AsyncCloudflare) -> None: application = await async_client.zero_trust.access.applications.create( domain="test.example.com/admin", type="self_hosted", @@ -5002,7 +5324,7 @@ async def test_method_create_with_all_params_overload_3(self, async_client: Asyn @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_raw_response_create_overload_3(self, async_client: AsyncCloudflare) -> None: + async def test_raw_response_create_overload_4(self, async_client: AsyncCloudflare) -> None: response = await async_client.zero_trust.access.applications.with_raw_response.create( domain="test.example.com/admin", type="self_hosted", @@ -5016,7 +5338,7 @@ async def test_raw_response_create_overload_3(self, async_client: AsyncCloudflar @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_streaming_response_create_overload_3(self, async_client: AsyncCloudflare) -> None: + async def test_streaming_response_create_overload_4(self, async_client: AsyncCloudflare) -> None: async with async_client.zero_trust.access.applications.with_streaming_response.create( domain="test.example.com/admin", type="self_hosted", @@ -5032,7 +5354,7 @@ async def test_streaming_response_create_overload_3(self, async_client: AsyncClo @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_path_params_create_overload_3(self, async_client: AsyncCloudflare) -> None: + async def test_path_params_create_overload_4(self, async_client: AsyncCloudflare) -> None: with pytest.raises(ValueError, match=r"You must provide either account_id or zone_id"): await async_client.zero_trust.access.applications.with_raw_response.create( domain="test.example.com/admin", @@ -5049,7 +5371,7 @@ async def test_path_params_create_overload_3(self, async_client: AsyncCloudflare @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_method_create_overload_4(self, async_client: AsyncCloudflare) -> None: + async def test_method_create_overload_5(self, async_client: AsyncCloudflare) -> None: application = await async_client.zero_trust.access.applications.create( domain="test.example.com/admin", type="self_hosted", @@ -5059,7 +5381,7 @@ async def test_method_create_overload_4(self, async_client: AsyncCloudflare) -> @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_method_create_with_all_params_overload_4(self, async_client: AsyncCloudflare) -> None: + async def test_method_create_with_all_params_overload_5(self, async_client: AsyncCloudflare) -> None: application = await async_client.zero_trust.access.applications.create( domain="test.example.com/admin", type="self_hosted", @@ -5235,7 +5557,7 @@ async def test_method_create_with_all_params_overload_4(self, async_client: Asyn @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_raw_response_create_overload_4(self, async_client: AsyncCloudflare) -> None: + async def test_raw_response_create_overload_5(self, async_client: AsyncCloudflare) -> None: response = await async_client.zero_trust.access.applications.with_raw_response.create( domain="test.example.com/admin", type="self_hosted", @@ -5249,7 +5571,7 @@ async def test_raw_response_create_overload_4(self, async_client: AsyncCloudflar @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_streaming_response_create_overload_4(self, async_client: AsyncCloudflare) -> None: + async def test_streaming_response_create_overload_5(self, async_client: AsyncCloudflare) -> None: async with async_client.zero_trust.access.applications.with_streaming_response.create( domain="test.example.com/admin", type="self_hosted", @@ -5265,7 +5587,7 @@ async def test_streaming_response_create_overload_4(self, async_client: AsyncClo @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_path_params_create_overload_4(self, async_client: AsyncCloudflare) -> None: + async def test_path_params_create_overload_5(self, async_client: AsyncCloudflare) -> None: with pytest.raises(ValueError, match=r"You must provide either account_id or zone_id"): await async_client.zero_trust.access.applications.with_raw_response.create( domain="test.example.com/admin", @@ -5282,7 +5604,7 @@ async def test_path_params_create_overload_4(self, async_client: AsyncCloudflare @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_method_create_overload_5(self, async_client: AsyncCloudflare) -> None: + async def test_method_create_overload_6(self, async_client: AsyncCloudflare) -> None: application = await async_client.zero_trust.access.applications.create( type="self_hosted", account_id="account_id", @@ -5291,7 +5613,7 @@ async def test_method_create_overload_5(self, async_client: AsyncCloudflare) -> @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_method_create_with_all_params_overload_5(self, async_client: AsyncCloudflare) -> None: + async def test_method_create_with_all_params_overload_6(self, async_client: AsyncCloudflare) -> None: application = await async_client.zero_trust.access.applications.create( type="self_hosted", account_id="account_id", @@ -5324,7 +5646,7 @@ async def test_method_create_with_all_params_overload_5(self, async_client: Asyn @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_raw_response_create_overload_5(self, async_client: AsyncCloudflare) -> None: + async def test_raw_response_create_overload_6(self, async_client: AsyncCloudflare) -> None: response = await async_client.zero_trust.access.applications.with_raw_response.create( type="self_hosted", account_id="account_id", @@ -5337,7 +5659,7 @@ async def test_raw_response_create_overload_5(self, async_client: AsyncCloudflar @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_streaming_response_create_overload_5(self, async_client: AsyncCloudflare) -> None: + async def test_streaming_response_create_overload_6(self, async_client: AsyncCloudflare) -> None: async with async_client.zero_trust.access.applications.with_streaming_response.create( type="self_hosted", account_id="account_id", @@ -5352,7 +5674,7 @@ async def test_streaming_response_create_overload_5(self, async_client: AsyncClo @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_path_params_create_overload_5(self, async_client: AsyncCloudflare) -> None: + async def test_path_params_create_overload_6(self, async_client: AsyncCloudflare) -> None: with pytest.raises(ValueError, match=r"You must provide either account_id or zone_id"): await async_client.zero_trust.access.applications.with_raw_response.create( type="self_hosted", @@ -5367,7 +5689,7 @@ async def test_path_params_create_overload_5(self, async_client: AsyncCloudflare @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_method_create_overload_6(self, async_client: AsyncCloudflare) -> None: + async def test_method_create_overload_7(self, async_client: AsyncCloudflare) -> None: application = await async_client.zero_trust.access.applications.create( type="self_hosted", account_id="account_id", @@ -5376,7 +5698,7 @@ async def test_method_create_overload_6(self, async_client: AsyncCloudflare) -> @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_method_create_with_all_params_overload_6(self, async_client: AsyncCloudflare) -> None: + async def test_method_create_with_all_params_overload_7(self, async_client: AsyncCloudflare) -> None: application = await async_client.zero_trust.access.applications.create( type="self_hosted", account_id="account_id", @@ -5392,7 +5714,7 @@ async def test_method_create_with_all_params_overload_6(self, async_client: Asyn @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_raw_response_create_overload_6(self, async_client: AsyncCloudflare) -> None: + async def test_raw_response_create_overload_7(self, async_client: AsyncCloudflare) -> None: response = await async_client.zero_trust.access.applications.with_raw_response.create( type="self_hosted", account_id="account_id", @@ -5405,7 +5727,7 @@ async def test_raw_response_create_overload_6(self, async_client: AsyncCloudflar @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_streaming_response_create_overload_6(self, async_client: AsyncCloudflare) -> None: + async def test_streaming_response_create_overload_7(self, async_client: AsyncCloudflare) -> None: async with async_client.zero_trust.access.applications.with_streaming_response.create( type="self_hosted", account_id="account_id", @@ -5420,7 +5742,7 @@ async def test_streaming_response_create_overload_6(self, async_client: AsyncClo @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_path_params_create_overload_6(self, async_client: AsyncCloudflare) -> None: + async def test_path_params_create_overload_7(self, async_client: AsyncCloudflare) -> None: with pytest.raises(ValueError, match=r"You must provide either account_id or zone_id"): await async_client.zero_trust.access.applications.with_raw_response.create( type="self_hosted", @@ -5435,7 +5757,7 @@ async def test_path_params_create_overload_6(self, async_client: AsyncCloudflare @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_method_create_overload_7(self, async_client: AsyncCloudflare) -> None: + async def test_method_create_overload_8(self, async_client: AsyncCloudflare) -> None: application = await async_client.zero_trust.access.applications.create( type="self_hosted", account_id="account_id", @@ -5444,7 +5766,7 @@ async def test_method_create_overload_7(self, async_client: AsyncCloudflare) -> @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_method_create_with_all_params_overload_7(self, async_client: AsyncCloudflare) -> None: + async def test_method_create_with_all_params_overload_8(self, async_client: AsyncCloudflare) -> None: application = await async_client.zero_trust.access.applications.create( type="self_hosted", account_id="account_id", @@ -5460,7 +5782,7 @@ async def test_method_create_with_all_params_overload_7(self, async_client: Asyn @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_raw_response_create_overload_7(self, async_client: AsyncCloudflare) -> None: + async def test_raw_response_create_overload_8(self, async_client: AsyncCloudflare) -> None: response = await async_client.zero_trust.access.applications.with_raw_response.create( type="self_hosted", account_id="account_id", @@ -5473,7 +5795,7 @@ async def test_raw_response_create_overload_7(self, async_client: AsyncCloudflar @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_streaming_response_create_overload_7(self, async_client: AsyncCloudflare) -> None: + async def test_streaming_response_create_overload_8(self, async_client: AsyncCloudflare) -> None: async with async_client.zero_trust.access.applications.with_streaming_response.create( type="self_hosted", account_id="account_id", @@ -5488,7 +5810,7 @@ async def test_streaming_response_create_overload_7(self, async_client: AsyncClo @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_path_params_create_overload_7(self, async_client: AsyncCloudflare) -> None: + async def test_path_params_create_overload_8(self, async_client: AsyncCloudflare) -> None: with pytest.raises(ValueError, match=r"You must provide either account_id or zone_id"): await async_client.zero_trust.access.applications.with_raw_response.create( type="self_hosted", @@ -5503,7 +5825,7 @@ async def test_path_params_create_overload_7(self, async_client: AsyncCloudflare @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_method_create_overload_8(self, async_client: AsyncCloudflare) -> None: + async def test_method_create_overload_9(self, async_client: AsyncCloudflare) -> None: application = await async_client.zero_trust.access.applications.create( type="self_hosted", account_id="account_id", @@ -5512,7 +5834,7 @@ async def test_method_create_overload_8(self, async_client: AsyncCloudflare) -> @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_method_create_with_all_params_overload_8(self, async_client: AsyncCloudflare) -> None: + async def test_method_create_with_all_params_overload_9(self, async_client: AsyncCloudflare) -> None: application = await async_client.zero_trust.access.applications.create( type="self_hosted", account_id="account_id", @@ -5530,7 +5852,7 @@ async def test_method_create_with_all_params_overload_8(self, async_client: Asyn @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_raw_response_create_overload_8(self, async_client: AsyncCloudflare) -> None: + async def test_raw_response_create_overload_9(self, async_client: AsyncCloudflare) -> None: response = await async_client.zero_trust.access.applications.with_raw_response.create( type="self_hosted", account_id="account_id", @@ -5543,7 +5865,7 @@ async def test_raw_response_create_overload_8(self, async_client: AsyncCloudflar @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_streaming_response_create_overload_8(self, async_client: AsyncCloudflare) -> None: + async def test_streaming_response_create_overload_9(self, async_client: AsyncCloudflare) -> None: async with async_client.zero_trust.access.applications.with_streaming_response.create( type="self_hosted", account_id="account_id", @@ -5558,7 +5880,7 @@ async def test_streaming_response_create_overload_8(self, async_client: AsyncClo @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_path_params_create_overload_8(self, async_client: AsyncCloudflare) -> None: + async def test_path_params_create_overload_9(self, async_client: AsyncCloudflare) -> None: with pytest.raises(ValueError, match=r"You must provide either account_id or zone_id"): await async_client.zero_trust.access.applications.with_raw_response.create( type="self_hosted", @@ -5573,7 +5895,7 @@ async def test_path_params_create_overload_8(self, async_client: AsyncCloudflare @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_method_create_overload_9(self, async_client: AsyncCloudflare) -> None: + async def test_method_create_overload_10(self, async_client: AsyncCloudflare) -> None: application = await async_client.zero_trust.access.applications.create( account_id="account_id", ) @@ -5581,7 +5903,7 @@ async def test_method_create_overload_9(self, async_client: AsyncCloudflare) -> @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_method_create_with_all_params_overload_9(self, async_client: AsyncCloudflare) -> None: + async def test_method_create_with_all_params_overload_10(self, async_client: AsyncCloudflare) -> None: application = await async_client.zero_trust.access.applications.create( account_id="account_id", app_launcher_visible=True, @@ -5596,7 +5918,7 @@ async def test_method_create_with_all_params_overload_9(self, async_client: Asyn @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_raw_response_create_overload_9(self, async_client: AsyncCloudflare) -> None: + async def test_raw_response_create_overload_10(self, async_client: AsyncCloudflare) -> None: response = await async_client.zero_trust.access.applications.with_raw_response.create( account_id="account_id", ) @@ -5608,7 +5930,7 @@ async def test_raw_response_create_overload_9(self, async_client: AsyncCloudflar @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_streaming_response_create_overload_9(self, async_client: AsyncCloudflare) -> None: + async def test_streaming_response_create_overload_10(self, async_client: AsyncCloudflare) -> None: async with async_client.zero_trust.access.applications.with_streaming_response.create( account_id="account_id", ) as response: @@ -5622,7 +5944,7 @@ async def test_streaming_response_create_overload_9(self, async_client: AsyncClo @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_path_params_create_overload_9(self, async_client: AsyncCloudflare) -> None: + async def test_path_params_create_overload_10(self, async_client: AsyncCloudflare) -> None: with pytest.raises(ValueError, match=r"You must provide either account_id or zone_id"): await async_client.zero_trust.access.applications.with_raw_response.create( account_id="", @@ -5635,7 +5957,7 @@ async def test_path_params_create_overload_9(self, async_client: AsyncCloudflare @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_method_create_overload_10(self, async_client: AsyncCloudflare) -> None: + async def test_method_create_overload_11(self, async_client: AsyncCloudflare) -> None: application = await async_client.zero_trust.access.applications.create( target_criteria=[ { @@ -5650,7 +5972,7 @@ async def test_method_create_overload_10(self, async_client: AsyncCloudflare) -> @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_method_create_with_all_params_overload_10(self, async_client: AsyncCloudflare) -> None: + async def test_method_create_with_all_params_overload_11(self, async_client: AsyncCloudflare) -> None: application = await async_client.zero_trust.access.applications.create( target_criteria=[ { @@ -5696,15 +6018,17 @@ async def test_method_create_with_all_params_overload_10(self, async_client: Asy "mfa_disabled": False, "session_duration": "24h", }, + "policy_resolution_account_id": "policy_resolution_account_id", "require": [{"certificate": {}}], } ], + session_duration="8h", ) assert_matches_type(Optional[ApplicationCreateResponse], application, path=["response"]) @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_raw_response_create_overload_10(self, async_client: AsyncCloudflare) -> None: + async def test_raw_response_create_overload_11(self, async_client: AsyncCloudflare) -> None: response = await async_client.zero_trust.access.applications.with_raw_response.create( target_criteria=[ { @@ -5723,7 +6047,7 @@ async def test_raw_response_create_overload_10(self, async_client: AsyncCloudfla @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_streaming_response_create_overload_10(self, async_client: AsyncCloudflare) -> None: + async def test_streaming_response_create_overload_11(self, async_client: AsyncCloudflare) -> None: async with async_client.zero_trust.access.applications.with_streaming_response.create( target_criteria=[ { @@ -5744,7 +6068,7 @@ async def test_streaming_response_create_overload_10(self, async_client: AsyncCl @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_path_params_create_overload_10(self, async_client: AsyncCloudflare) -> None: + async def test_path_params_create_overload_11(self, async_client: AsyncCloudflare) -> None: with pytest.raises(ValueError, match=r"You must provide either account_id or zone_id"): await async_client.zero_trust.access.applications.with_raw_response.create( target_criteria=[ @@ -5771,7 +6095,7 @@ async def test_path_params_create_overload_10(self, async_client: AsyncCloudflar @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_method_create_overload_11(self, async_client: AsyncCloudflare) -> None: + async def test_method_create_overload_12(self, async_client: AsyncCloudflare) -> None: application = await async_client.zero_trust.access.applications.create( domain="test.example.com/admin", target_criteria=[ @@ -5787,7 +6111,7 @@ async def test_method_create_overload_11(self, async_client: AsyncCloudflare) -> @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_method_create_with_all_params_overload_11(self, async_client: AsyncCloudflare) -> None: + async def test_method_create_with_all_params_overload_12(self, async_client: AsyncCloudflare) -> None: application = await async_client.zero_trust.access.applications.create( domain="test.example.com/admin", target_criteria=[ @@ -5982,7 +6306,7 @@ async def test_method_create_with_all_params_overload_11(self, async_client: Asy @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_raw_response_create_overload_11(self, async_client: AsyncCloudflare) -> None: + async def test_raw_response_create_overload_12(self, async_client: AsyncCloudflare) -> None: response = await async_client.zero_trust.access.applications.with_raw_response.create( domain="test.example.com/admin", target_criteria=[ @@ -6002,7 +6326,7 @@ async def test_raw_response_create_overload_11(self, async_client: AsyncCloudfla @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_streaming_response_create_overload_11(self, async_client: AsyncCloudflare) -> None: + async def test_streaming_response_create_overload_12(self, async_client: AsyncCloudflare) -> None: async with async_client.zero_trust.access.applications.with_streaming_response.create( domain="test.example.com/admin", target_criteria=[ @@ -6024,7 +6348,7 @@ async def test_streaming_response_create_overload_11(self, async_client: AsyncCl @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_path_params_create_overload_11(self, async_client: AsyncCloudflare) -> None: + async def test_path_params_create_overload_12(self, async_client: AsyncCloudflare) -> None: with pytest.raises(ValueError, match=r"You must provide either account_id or zone_id"): await async_client.zero_trust.access.applications.with_raw_response.create( domain="test.example.com/admin", @@ -6053,7 +6377,7 @@ async def test_path_params_create_overload_11(self, async_client: AsyncCloudflar @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_method_create_overload_12(self, async_client: AsyncCloudflare) -> None: + async def test_method_create_overload_13(self, async_client: AsyncCloudflare) -> None: application = await async_client.zero_trust.access.applications.create( type="mcp", account_id="account_id", @@ -6062,7 +6386,7 @@ async def test_method_create_overload_12(self, async_client: AsyncCloudflare) -> @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_method_create_with_all_params_overload_12(self, async_client: AsyncCloudflare) -> None: + async def test_method_create_with_all_params_overload_13(self, async_client: AsyncCloudflare) -> None: application = await async_client.zero_trust.access.applications.create( type="mcp", account_id="account_id", @@ -6212,7 +6536,7 @@ async def test_method_create_with_all_params_overload_12(self, async_client: Asy @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_raw_response_create_overload_12(self, async_client: AsyncCloudflare) -> None: + async def test_raw_response_create_overload_13(self, async_client: AsyncCloudflare) -> None: response = await async_client.zero_trust.access.applications.with_raw_response.create( type="mcp", account_id="account_id", @@ -6225,7 +6549,7 @@ async def test_raw_response_create_overload_12(self, async_client: AsyncCloudfla @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_streaming_response_create_overload_12(self, async_client: AsyncCloudflare) -> None: + async def test_streaming_response_create_overload_13(self, async_client: AsyncCloudflare) -> None: async with async_client.zero_trust.access.applications.with_streaming_response.create( type="mcp", account_id="account_id", @@ -6240,7 +6564,7 @@ async def test_streaming_response_create_overload_12(self, async_client: AsyncCl @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_path_params_create_overload_12(self, async_client: AsyncCloudflare) -> None: + async def test_path_params_create_overload_13(self, async_client: AsyncCloudflare) -> None: with pytest.raises(ValueError, match=r"You must provide either account_id or zone_id"): await async_client.zero_trust.access.applications.with_raw_response.create( type="mcp", @@ -6255,7 +6579,7 @@ async def test_path_params_create_overload_12(self, async_client: AsyncCloudflar @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_method_create_overload_13(self, async_client: AsyncCloudflare) -> None: + async def test_method_create_overload_14(self, async_client: AsyncCloudflare) -> None: application = await async_client.zero_trust.access.applications.create( type="mcp_portal", account_id="account_id", @@ -6264,7 +6588,7 @@ async def test_method_create_overload_13(self, async_client: AsyncCloudflare) -> @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_method_create_with_all_params_overload_13(self, async_client: AsyncCloudflare) -> None: + async def test_method_create_with_all_params_overload_14(self, async_client: AsyncCloudflare) -> None: application = await async_client.zero_trust.access.applications.create( type="mcp_portal", account_id="account_id", @@ -6415,7 +6739,7 @@ async def test_method_create_with_all_params_overload_13(self, async_client: Asy @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_raw_response_create_overload_13(self, async_client: AsyncCloudflare) -> None: + async def test_raw_response_create_overload_14(self, async_client: AsyncCloudflare) -> None: response = await async_client.zero_trust.access.applications.with_raw_response.create( type="mcp_portal", account_id="account_id", @@ -6428,7 +6752,7 @@ async def test_raw_response_create_overload_13(self, async_client: AsyncCloudfla @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_streaming_response_create_overload_13(self, async_client: AsyncCloudflare) -> None: + async def test_streaming_response_create_overload_14(self, async_client: AsyncCloudflare) -> None: async with async_client.zero_trust.access.applications.with_streaming_response.create( type="mcp_portal", account_id="account_id", @@ -6443,7 +6767,7 @@ async def test_streaming_response_create_overload_13(self, async_client: AsyncCl @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_path_params_create_overload_13(self, async_client: AsyncCloudflare) -> None: + async def test_path_params_create_overload_14(self, async_client: AsyncCloudflare) -> None: with pytest.raises(ValueError, match=r"You must provide either account_id or zone_id"): await async_client.zero_trust.access.applications.with_raw_response.create( type="mcp_portal", @@ -6461,8 +6785,9 @@ async def test_path_params_create_overload_13(self, async_client: AsyncCloudflar async def test_method_update_overload_1(self, async_client: AsyncCloudflare) -> None: application = await async_client.zero_trust.access.applications.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", - domain="test.example.com/admin", + oauth_configuration={}, type="self_hosted", + user_populations=["f174e90a-fafe-4643-bbbc-4a0ed4fc8415"], account_id="account_id", ) assert_matches_type(Optional[ApplicationUpdateResponse], application, path=["response"]) @@ -6470,6 +6795,121 @@ async def test_method_update_overload_1(self, async_client: AsyncCloudflare) -> @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize async def test_method_update_with_all_params_overload_1(self, async_client: AsyncCloudflare) -> None: + application = await async_client.zero_trust.access.applications.update( + app_id="023e105f4ecef8ad9ca31a8372d0c353", + oauth_configuration={ + "dynamic_client_registration": { + "allow_any_on_localhost": True, + "allow_any_on_loopback": True, + "allowed_uris": ["https://example.com/callback", "com.example.app:/oauth/callback"], + "enabled": True, + }, + "enabled": True, + "grant": { + "access_token_lifetime": "5m", + "session_duration": "24h", + }, + }, + type="self_hosted", + user_populations=["f174e90a-fafe-4643-bbbc-4a0ed4fc8415"], + account_id="account_id", + allowed_idps=["699d98642c564d2e855e9661899b7252"], + destinations=[ + { + "uri": "uri", + "overrides": [ + { + "behavior": "public", + "path_pattern": "/health/*", + } + ], + "type": "public", + } + ], + domain="test.example.com/admin", + name="Admin Site", + self_hosted_domains=["test.example.com/admin", "test.anotherexample.com/staff"], + ) + assert_matches_type(Optional[ApplicationUpdateResponse], application, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_raw_response_update_overload_1(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.access.applications.with_raw_response.update( + app_id="023e105f4ecef8ad9ca31a8372d0c353", + oauth_configuration={}, + type="self_hosted", + user_populations=["f174e90a-fafe-4643-bbbc-4a0ed4fc8415"], + account_id="account_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + application = await response.parse() + assert_matches_type(Optional[ApplicationUpdateResponse], application, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_streaming_response_update_overload_1(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.access.applications.with_streaming_response.update( + app_id="023e105f4ecef8ad9ca31a8372d0c353", + oauth_configuration={}, + type="self_hosted", + user_populations=["f174e90a-fafe-4643-bbbc-4a0ed4fc8415"], + account_id="account_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + application = await response.parse() + assert_matches_type(Optional[ApplicationUpdateResponse], application, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_path_params_update_overload_1(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `app_id` but received ''"): + await async_client.zero_trust.access.applications.with_raw_response.update( + app_id="", + oauth_configuration={}, + type="self_hosted", + user_populations=["f174e90a-fafe-4643-bbbc-4a0ed4fc8415"], + account_id="account_id", + ) + + with pytest.raises(ValueError, match=r"You must provide either account_id or zone_id"): + await async_client.zero_trust.access.applications.with_raw_response.update( + app_id="023e105f4ecef8ad9ca31a8372d0c353", + oauth_configuration={}, + type="self_hosted", + user_populations=["f174e90a-fafe-4643-bbbc-4a0ed4fc8415"], + account_id="", + ) + + with pytest.raises(ValueError, match=r"You must provide either account_id or zone_id"): + await async_client.zero_trust.access.applications.with_raw_response.update( + app_id="023e105f4ecef8ad9ca31a8372d0c353", + oauth_configuration={}, + type="self_hosted", + user_populations=["f174e90a-fafe-4643-bbbc-4a0ed4fc8415"], + account_id="account_id", + ) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_method_update_overload_2(self, async_client: AsyncCloudflare) -> None: + application = await async_client.zero_trust.access.applications.update( + app_id="023e105f4ecef8ad9ca31a8372d0c353", + domain="test.example.com/admin", + type="self_hosted", + account_id="account_id", + ) + assert_matches_type(Optional[ApplicationUpdateResponse], application, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_method_update_with_all_params_overload_2(self, async_client: AsyncCloudflare) -> None: application = await async_client.zero_trust.access.applications.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", domain="test.example.com/admin", @@ -6646,7 +7086,7 @@ async def test_method_update_with_all_params_overload_1(self, async_client: Asyn @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_raw_response_update_overload_1(self, async_client: AsyncCloudflare) -> None: + async def test_raw_response_update_overload_2(self, async_client: AsyncCloudflare) -> None: response = await async_client.zero_trust.access.applications.with_raw_response.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", domain="test.example.com/admin", @@ -6661,7 +7101,7 @@ async def test_raw_response_update_overload_1(self, async_client: AsyncCloudflar @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_streaming_response_update_overload_1(self, async_client: AsyncCloudflare) -> None: + async def test_streaming_response_update_overload_2(self, async_client: AsyncCloudflare) -> None: async with async_client.zero_trust.access.applications.with_streaming_response.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", domain="test.example.com/admin", @@ -6678,7 +7118,7 @@ async def test_streaming_response_update_overload_1(self, async_client: AsyncClo @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_path_params_update_overload_1(self, async_client: AsyncCloudflare) -> None: + async def test_path_params_update_overload_2(self, async_client: AsyncCloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `app_id` but received ''"): await async_client.zero_trust.access.applications.with_raw_response.update( app_id="", @@ -6705,7 +7145,7 @@ async def test_path_params_update_overload_1(self, async_client: AsyncCloudflare @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_method_update_overload_2(self, async_client: AsyncCloudflare) -> None: + async def test_method_update_overload_3(self, async_client: AsyncCloudflare) -> None: application = await async_client.zero_trust.access.applications.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", account_id="account_id", @@ -6714,7 +7154,7 @@ async def test_method_update_overload_2(self, async_client: AsyncCloudflare) -> @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_method_update_with_all_params_overload_2(self, async_client: AsyncCloudflare) -> None: + async def test_method_update_with_all_params_overload_3(self, async_client: AsyncCloudflare) -> None: application = await async_client.zero_trust.access.applications.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", account_id="account_id", @@ -6786,7 +7226,7 @@ async def test_method_update_with_all_params_overload_2(self, async_client: Asyn @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_raw_response_update_overload_2(self, async_client: AsyncCloudflare) -> None: + async def test_raw_response_update_overload_3(self, async_client: AsyncCloudflare) -> None: response = await async_client.zero_trust.access.applications.with_raw_response.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", account_id="account_id", @@ -6799,7 +7239,7 @@ async def test_raw_response_update_overload_2(self, async_client: AsyncCloudflar @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_streaming_response_update_overload_2(self, async_client: AsyncCloudflare) -> None: + async def test_streaming_response_update_overload_3(self, async_client: AsyncCloudflare) -> None: async with async_client.zero_trust.access.applications.with_streaming_response.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", account_id="account_id", @@ -6814,7 +7254,7 @@ async def test_streaming_response_update_overload_2(self, async_client: AsyncClo @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_path_params_update_overload_2(self, async_client: AsyncCloudflare) -> None: + async def test_path_params_update_overload_3(self, async_client: AsyncCloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `app_id` but received ''"): await async_client.zero_trust.access.applications.with_raw_response.update( app_id="", @@ -6835,7 +7275,7 @@ async def test_path_params_update_overload_2(self, async_client: AsyncCloudflare @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_method_update_overload_3(self, async_client: AsyncCloudflare) -> None: + async def test_method_update_overload_4(self, async_client: AsyncCloudflare) -> None: application = await async_client.zero_trust.access.applications.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", domain="test.example.com/admin", @@ -6846,7 +7286,7 @@ async def test_method_update_overload_3(self, async_client: AsyncCloudflare) -> @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_method_update_with_all_params_overload_3(self, async_client: AsyncCloudflare) -> None: + async def test_method_update_with_all_params_overload_4(self, async_client: AsyncCloudflare) -> None: application = await async_client.zero_trust.access.applications.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", domain="test.example.com/admin", @@ -7023,7 +7463,7 @@ async def test_method_update_with_all_params_overload_3(self, async_client: Asyn @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_raw_response_update_overload_3(self, async_client: AsyncCloudflare) -> None: + async def test_raw_response_update_overload_4(self, async_client: AsyncCloudflare) -> None: response = await async_client.zero_trust.access.applications.with_raw_response.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", domain="test.example.com/admin", @@ -7038,7 +7478,7 @@ async def test_raw_response_update_overload_3(self, async_client: AsyncCloudflar @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_streaming_response_update_overload_3(self, async_client: AsyncCloudflare) -> None: + async def test_streaming_response_update_overload_4(self, async_client: AsyncCloudflare) -> None: async with async_client.zero_trust.access.applications.with_streaming_response.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", domain="test.example.com/admin", @@ -7055,7 +7495,7 @@ async def test_streaming_response_update_overload_3(self, async_client: AsyncClo @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_path_params_update_overload_3(self, async_client: AsyncCloudflare) -> None: + async def test_path_params_update_overload_4(self, async_client: AsyncCloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `app_id` but received ''"): await async_client.zero_trust.access.applications.with_raw_response.update( app_id="", @@ -7082,7 +7522,7 @@ async def test_path_params_update_overload_3(self, async_client: AsyncCloudflare @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_method_update_overload_4(self, async_client: AsyncCloudflare) -> None: + async def test_method_update_overload_5(self, async_client: AsyncCloudflare) -> None: application = await async_client.zero_trust.access.applications.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", domain="test.example.com/admin", @@ -7093,7 +7533,7 @@ async def test_method_update_overload_4(self, async_client: AsyncCloudflare) -> @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_method_update_with_all_params_overload_4(self, async_client: AsyncCloudflare) -> None: + async def test_method_update_with_all_params_overload_5(self, async_client: AsyncCloudflare) -> None: application = await async_client.zero_trust.access.applications.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", domain="test.example.com/admin", @@ -7270,7 +7710,7 @@ async def test_method_update_with_all_params_overload_4(self, async_client: Asyn @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_raw_response_update_overload_4(self, async_client: AsyncCloudflare) -> None: + async def test_raw_response_update_overload_5(self, async_client: AsyncCloudflare) -> None: response = await async_client.zero_trust.access.applications.with_raw_response.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", domain="test.example.com/admin", @@ -7285,7 +7725,7 @@ async def test_raw_response_update_overload_4(self, async_client: AsyncCloudflar @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_streaming_response_update_overload_4(self, async_client: AsyncCloudflare) -> None: + async def test_streaming_response_update_overload_5(self, async_client: AsyncCloudflare) -> None: async with async_client.zero_trust.access.applications.with_streaming_response.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", domain="test.example.com/admin", @@ -7302,7 +7742,7 @@ async def test_streaming_response_update_overload_4(self, async_client: AsyncClo @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_path_params_update_overload_4(self, async_client: AsyncCloudflare) -> None: + async def test_path_params_update_overload_5(self, async_client: AsyncCloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `app_id` but received ''"): await async_client.zero_trust.access.applications.with_raw_response.update( app_id="", @@ -7329,7 +7769,7 @@ async def test_path_params_update_overload_4(self, async_client: AsyncCloudflare @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_method_update_overload_5(self, async_client: AsyncCloudflare) -> None: + async def test_method_update_overload_6(self, async_client: AsyncCloudflare) -> None: application = await async_client.zero_trust.access.applications.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", type="self_hosted", @@ -7339,7 +7779,7 @@ async def test_method_update_overload_5(self, async_client: AsyncCloudflare) -> @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_method_update_with_all_params_overload_5(self, async_client: AsyncCloudflare) -> None: + async def test_method_update_with_all_params_overload_6(self, async_client: AsyncCloudflare) -> None: application = await async_client.zero_trust.access.applications.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", type="self_hosted", @@ -7373,7 +7813,7 @@ async def test_method_update_with_all_params_overload_5(self, async_client: Asyn @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_raw_response_update_overload_5(self, async_client: AsyncCloudflare) -> None: + async def test_raw_response_update_overload_6(self, async_client: AsyncCloudflare) -> None: response = await async_client.zero_trust.access.applications.with_raw_response.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", type="self_hosted", @@ -7387,7 +7827,7 @@ async def test_raw_response_update_overload_5(self, async_client: AsyncCloudflar @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_streaming_response_update_overload_5(self, async_client: AsyncCloudflare) -> None: + async def test_streaming_response_update_overload_6(self, async_client: AsyncCloudflare) -> None: async with async_client.zero_trust.access.applications.with_streaming_response.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", type="self_hosted", @@ -7403,7 +7843,7 @@ async def test_streaming_response_update_overload_5(self, async_client: AsyncClo @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_path_params_update_overload_5(self, async_client: AsyncCloudflare) -> None: + async def test_path_params_update_overload_6(self, async_client: AsyncCloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `app_id` but received ''"): await async_client.zero_trust.access.applications.with_raw_response.update( app_id="", @@ -7427,7 +7867,7 @@ async def test_path_params_update_overload_5(self, async_client: AsyncCloudflare @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_method_update_overload_6(self, async_client: AsyncCloudflare) -> None: + async def test_method_update_overload_7(self, async_client: AsyncCloudflare) -> None: application = await async_client.zero_trust.access.applications.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", type="self_hosted", @@ -7437,7 +7877,7 @@ async def test_method_update_overload_6(self, async_client: AsyncCloudflare) -> @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_method_update_with_all_params_overload_6(self, async_client: AsyncCloudflare) -> None: + async def test_method_update_with_all_params_overload_7(self, async_client: AsyncCloudflare) -> None: application = await async_client.zero_trust.access.applications.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", type="self_hosted", @@ -7454,7 +7894,7 @@ async def test_method_update_with_all_params_overload_6(self, async_client: Asyn @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_raw_response_update_overload_6(self, async_client: AsyncCloudflare) -> None: + async def test_raw_response_update_overload_7(self, async_client: AsyncCloudflare) -> None: response = await async_client.zero_trust.access.applications.with_raw_response.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", type="self_hosted", @@ -7468,7 +7908,7 @@ async def test_raw_response_update_overload_6(self, async_client: AsyncCloudflar @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_streaming_response_update_overload_6(self, async_client: AsyncCloudflare) -> None: + async def test_streaming_response_update_overload_7(self, async_client: AsyncCloudflare) -> None: async with async_client.zero_trust.access.applications.with_streaming_response.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", type="self_hosted", @@ -7484,7 +7924,7 @@ async def test_streaming_response_update_overload_6(self, async_client: AsyncClo @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_path_params_update_overload_6(self, async_client: AsyncCloudflare) -> None: + async def test_path_params_update_overload_7(self, async_client: AsyncCloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `app_id` but received ''"): await async_client.zero_trust.access.applications.with_raw_response.update( app_id="", @@ -7508,7 +7948,7 @@ async def test_path_params_update_overload_6(self, async_client: AsyncCloudflare @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_method_update_overload_7(self, async_client: AsyncCloudflare) -> None: + async def test_method_update_overload_8(self, async_client: AsyncCloudflare) -> None: application = await async_client.zero_trust.access.applications.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", type="self_hosted", @@ -7518,7 +7958,7 @@ async def test_method_update_overload_7(self, async_client: AsyncCloudflare) -> @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_method_update_with_all_params_overload_7(self, async_client: AsyncCloudflare) -> None: + async def test_method_update_with_all_params_overload_8(self, async_client: AsyncCloudflare) -> None: application = await async_client.zero_trust.access.applications.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", type="self_hosted", @@ -7535,7 +7975,7 @@ async def test_method_update_with_all_params_overload_7(self, async_client: Asyn @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_raw_response_update_overload_7(self, async_client: AsyncCloudflare) -> None: + async def test_raw_response_update_overload_8(self, async_client: AsyncCloudflare) -> None: response = await async_client.zero_trust.access.applications.with_raw_response.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", type="self_hosted", @@ -7549,7 +7989,7 @@ async def test_raw_response_update_overload_7(self, async_client: AsyncCloudflar @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_streaming_response_update_overload_7(self, async_client: AsyncCloudflare) -> None: + async def test_streaming_response_update_overload_8(self, async_client: AsyncCloudflare) -> None: async with async_client.zero_trust.access.applications.with_streaming_response.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", type="self_hosted", @@ -7565,7 +8005,7 @@ async def test_streaming_response_update_overload_7(self, async_client: AsyncClo @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_path_params_update_overload_7(self, async_client: AsyncCloudflare) -> None: + async def test_path_params_update_overload_8(self, async_client: AsyncCloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `app_id` but received ''"): await async_client.zero_trust.access.applications.with_raw_response.update( app_id="", @@ -7589,7 +8029,7 @@ async def test_path_params_update_overload_7(self, async_client: AsyncCloudflare @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_method_update_overload_8(self, async_client: AsyncCloudflare) -> None: + async def test_method_update_overload_9(self, async_client: AsyncCloudflare) -> None: application = await async_client.zero_trust.access.applications.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", type="self_hosted", @@ -7599,7 +8039,7 @@ async def test_method_update_overload_8(self, async_client: AsyncCloudflare) -> @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_method_update_with_all_params_overload_8(self, async_client: AsyncCloudflare) -> None: + async def test_method_update_with_all_params_overload_9(self, async_client: AsyncCloudflare) -> None: application = await async_client.zero_trust.access.applications.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", type="self_hosted", @@ -7618,7 +8058,7 @@ async def test_method_update_with_all_params_overload_8(self, async_client: Asyn @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_raw_response_update_overload_8(self, async_client: AsyncCloudflare) -> None: + async def test_raw_response_update_overload_9(self, async_client: AsyncCloudflare) -> None: response = await async_client.zero_trust.access.applications.with_raw_response.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", type="self_hosted", @@ -7632,7 +8072,7 @@ async def test_raw_response_update_overload_8(self, async_client: AsyncCloudflar @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_streaming_response_update_overload_8(self, async_client: AsyncCloudflare) -> None: + async def test_streaming_response_update_overload_9(self, async_client: AsyncCloudflare) -> None: async with async_client.zero_trust.access.applications.with_streaming_response.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", type="self_hosted", @@ -7648,7 +8088,7 @@ async def test_streaming_response_update_overload_8(self, async_client: AsyncClo @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_path_params_update_overload_8(self, async_client: AsyncCloudflare) -> None: + async def test_path_params_update_overload_9(self, async_client: AsyncCloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `app_id` but received ''"): await async_client.zero_trust.access.applications.with_raw_response.update( app_id="", @@ -7672,7 +8112,7 @@ async def test_path_params_update_overload_8(self, async_client: AsyncCloudflare @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_method_update_overload_9(self, async_client: AsyncCloudflare) -> None: + async def test_method_update_overload_10(self, async_client: AsyncCloudflare) -> None: application = await async_client.zero_trust.access.applications.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", account_id="account_id", @@ -7681,7 +8121,7 @@ async def test_method_update_overload_9(self, async_client: AsyncCloudflare) -> @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_method_update_with_all_params_overload_9(self, async_client: AsyncCloudflare) -> None: + async def test_method_update_with_all_params_overload_10(self, async_client: AsyncCloudflare) -> None: application = await async_client.zero_trust.access.applications.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", account_id="account_id", @@ -7697,7 +8137,7 @@ async def test_method_update_with_all_params_overload_9(self, async_client: Asyn @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_raw_response_update_overload_9(self, async_client: AsyncCloudflare) -> None: + async def test_raw_response_update_overload_10(self, async_client: AsyncCloudflare) -> None: response = await async_client.zero_trust.access.applications.with_raw_response.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", account_id="account_id", @@ -7710,7 +8150,7 @@ async def test_raw_response_update_overload_9(self, async_client: AsyncCloudflar @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_streaming_response_update_overload_9(self, async_client: AsyncCloudflare) -> None: + async def test_streaming_response_update_overload_10(self, async_client: AsyncCloudflare) -> None: async with async_client.zero_trust.access.applications.with_streaming_response.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", account_id="account_id", @@ -7725,7 +8165,7 @@ async def test_streaming_response_update_overload_9(self, async_client: AsyncClo @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_path_params_update_overload_9(self, async_client: AsyncCloudflare) -> None: + async def test_path_params_update_overload_10(self, async_client: AsyncCloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `app_id` but received ''"): await async_client.zero_trust.access.applications.with_raw_response.update( app_id="", @@ -7746,7 +8186,7 @@ async def test_path_params_update_overload_9(self, async_client: AsyncCloudflare @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_method_update_overload_10(self, async_client: AsyncCloudflare) -> None: + async def test_method_update_overload_11(self, async_client: AsyncCloudflare) -> None: application = await async_client.zero_trust.access.applications.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", target_criteria=[ @@ -7762,7 +8202,7 @@ async def test_method_update_overload_10(self, async_client: AsyncCloudflare) -> @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_method_update_with_all_params_overload_10(self, async_client: AsyncCloudflare) -> None: + async def test_method_update_with_all_params_overload_11(self, async_client: AsyncCloudflare) -> None: application = await async_client.zero_trust.access.applications.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", target_criteria=[ @@ -7809,15 +8249,17 @@ async def test_method_update_with_all_params_overload_10(self, async_client: Asy "mfa_disabled": False, "session_duration": "24h", }, + "policy_resolution_account_id": "policy_resolution_account_id", "require": [{"certificate": {}}], } ], + session_duration="8h", ) assert_matches_type(Optional[ApplicationUpdateResponse], application, path=["response"]) @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_raw_response_update_overload_10(self, async_client: AsyncCloudflare) -> None: + async def test_raw_response_update_overload_11(self, async_client: AsyncCloudflare) -> None: response = await async_client.zero_trust.access.applications.with_raw_response.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", target_criteria=[ @@ -7837,7 +8279,7 @@ async def test_raw_response_update_overload_10(self, async_client: AsyncCloudfla @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_streaming_response_update_overload_10(self, async_client: AsyncCloudflare) -> None: + async def test_streaming_response_update_overload_11(self, async_client: AsyncCloudflare) -> None: async with async_client.zero_trust.access.applications.with_streaming_response.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", target_criteria=[ @@ -7859,7 +8301,7 @@ async def test_streaming_response_update_overload_10(self, async_client: AsyncCl @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_path_params_update_overload_10(self, async_client: AsyncCloudflare) -> None: + async def test_path_params_update_overload_11(self, async_client: AsyncCloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `app_id` but received ''"): await async_client.zero_trust.access.applications.with_raw_response.update( app_id="", @@ -7901,7 +8343,7 @@ async def test_path_params_update_overload_10(self, async_client: AsyncCloudflar @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_method_update_overload_11(self, async_client: AsyncCloudflare) -> None: + async def test_method_update_overload_12(self, async_client: AsyncCloudflare) -> None: application = await async_client.zero_trust.access.applications.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", domain="test.example.com/admin", @@ -7918,7 +8360,7 @@ async def test_method_update_overload_11(self, async_client: AsyncCloudflare) -> @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_method_update_with_all_params_overload_11(self, async_client: AsyncCloudflare) -> None: + async def test_method_update_with_all_params_overload_12(self, async_client: AsyncCloudflare) -> None: application = await async_client.zero_trust.access.applications.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", domain="test.example.com/admin", @@ -8114,7 +8556,7 @@ async def test_method_update_with_all_params_overload_11(self, async_client: Asy @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_raw_response_update_overload_11(self, async_client: AsyncCloudflare) -> None: + async def test_raw_response_update_overload_12(self, async_client: AsyncCloudflare) -> None: response = await async_client.zero_trust.access.applications.with_raw_response.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", domain="test.example.com/admin", @@ -8135,7 +8577,7 @@ async def test_raw_response_update_overload_11(self, async_client: AsyncCloudfla @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_streaming_response_update_overload_11(self, async_client: AsyncCloudflare) -> None: + async def test_streaming_response_update_overload_12(self, async_client: AsyncCloudflare) -> None: async with async_client.zero_trust.access.applications.with_streaming_response.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", domain="test.example.com/admin", @@ -8158,7 +8600,7 @@ async def test_streaming_response_update_overload_11(self, async_client: AsyncCl @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_path_params_update_overload_11(self, async_client: AsyncCloudflare) -> None: + async def test_path_params_update_overload_12(self, async_client: AsyncCloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `app_id` but received ''"): await async_client.zero_trust.access.applications.with_raw_response.update( app_id="", @@ -8203,7 +8645,7 @@ async def test_path_params_update_overload_11(self, async_client: AsyncCloudflar @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_method_update_overload_12(self, async_client: AsyncCloudflare) -> None: + async def test_method_update_overload_13(self, async_client: AsyncCloudflare) -> None: application = await async_client.zero_trust.access.applications.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", type="mcp", @@ -8213,7 +8655,7 @@ async def test_method_update_overload_12(self, async_client: AsyncCloudflare) -> @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_method_update_with_all_params_overload_12(self, async_client: AsyncCloudflare) -> None: + async def test_method_update_with_all_params_overload_13(self, async_client: AsyncCloudflare) -> None: application = await async_client.zero_trust.access.applications.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", type="mcp", @@ -8364,7 +8806,7 @@ async def test_method_update_with_all_params_overload_12(self, async_client: Asy @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_raw_response_update_overload_12(self, async_client: AsyncCloudflare) -> None: + async def test_raw_response_update_overload_13(self, async_client: AsyncCloudflare) -> None: response = await async_client.zero_trust.access.applications.with_raw_response.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", type="mcp", @@ -8378,7 +8820,7 @@ async def test_raw_response_update_overload_12(self, async_client: AsyncCloudfla @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_streaming_response_update_overload_12(self, async_client: AsyncCloudflare) -> None: + async def test_streaming_response_update_overload_13(self, async_client: AsyncCloudflare) -> None: async with async_client.zero_trust.access.applications.with_streaming_response.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", type="mcp", @@ -8394,7 +8836,7 @@ async def test_streaming_response_update_overload_12(self, async_client: AsyncCl @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_path_params_update_overload_12(self, async_client: AsyncCloudflare) -> None: + async def test_path_params_update_overload_13(self, async_client: AsyncCloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `app_id` but received ''"): await async_client.zero_trust.access.applications.with_raw_response.update( app_id="", @@ -8418,7 +8860,7 @@ async def test_path_params_update_overload_12(self, async_client: AsyncCloudflar @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_method_update_overload_13(self, async_client: AsyncCloudflare) -> None: + async def test_method_update_overload_14(self, async_client: AsyncCloudflare) -> None: application = await async_client.zero_trust.access.applications.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", type="mcp_portal", @@ -8428,7 +8870,7 @@ async def test_method_update_overload_13(self, async_client: AsyncCloudflare) -> @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_method_update_with_all_params_overload_13(self, async_client: AsyncCloudflare) -> None: + async def test_method_update_with_all_params_overload_14(self, async_client: AsyncCloudflare) -> None: application = await async_client.zero_trust.access.applications.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", type="mcp_portal", @@ -8580,7 +9022,7 @@ async def test_method_update_with_all_params_overload_13(self, async_client: Asy @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_raw_response_update_overload_13(self, async_client: AsyncCloudflare) -> None: + async def test_raw_response_update_overload_14(self, async_client: AsyncCloudflare) -> None: response = await async_client.zero_trust.access.applications.with_raw_response.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", type="mcp_portal", @@ -8594,7 +9036,7 @@ async def test_raw_response_update_overload_13(self, async_client: AsyncCloudfla @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_streaming_response_update_overload_13(self, async_client: AsyncCloudflare) -> None: + async def test_streaming_response_update_overload_14(self, async_client: AsyncCloudflare) -> None: async with async_client.zero_trust.access.applications.with_streaming_response.update( app_id="023e105f4ecef8ad9ca31a8372d0c353", type="mcp_portal", @@ -8610,7 +9052,7 @@ async def test_streaming_response_update_overload_13(self, async_client: AsyncCl @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_path_params_update_overload_13(self, async_client: AsyncCloudflare) -> None: + async def test_path_params_update_overload_14(self, async_client: AsyncCloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `app_id` but received ''"): await async_client.zero_trust.access.applications.with_raw_response.update( app_id="", diff --git a/tests/api_resources/zero_trust/access/test_custom_pages.py b/tests/api_resources/zero_trust/access/test_custom_pages.py index 9e2d31952ca..9352f043fce 100644 --- a/tests/api_resources/zero_trust/access/test_custom_pages.py +++ b/tests/api_resources/zero_trust/access/test_custom_pages.py @@ -14,6 +14,7 @@ CustomPage, CustomPageWithoutHTML, CustomPageDeleteResponse, + CustomPageValidateResponse, ) base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") @@ -301,6 +302,62 @@ def test_path_params_get(self, client: Cloudflare) -> None: account_id="023e105f4ecef8ad9ca31a8372d0c353", ) + @parametrize + def test_method_validate(self, client: Cloudflare) -> None: + custom_page = client.zero_trust.access.custom_pages.validate( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + template="template", + type="identity_denied", + ) + assert_matches_type(Optional[CustomPageValidateResponse], custom_page, path=["response"]) + + @parametrize + def test_method_validate_with_all_params(self, client: Cloudflare) -> None: + custom_page = client.zero_trust.access.custom_pages.validate( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + template="template", + type="identity_denied", + version=0, + ) + assert_matches_type(Optional[CustomPageValidateResponse], custom_page, path=["response"]) + + @parametrize + def test_raw_response_validate(self, client: Cloudflare) -> None: + response = client.zero_trust.access.custom_pages.with_raw_response.validate( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + template="template", + type="identity_denied", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + custom_page = response.parse() + assert_matches_type(Optional[CustomPageValidateResponse], custom_page, path=["response"]) + + @parametrize + def test_streaming_response_validate(self, client: Cloudflare) -> None: + with client.zero_trust.access.custom_pages.with_streaming_response.validate( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + template="template", + type="identity_denied", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + custom_page = response.parse() + assert_matches_type(Optional[CustomPageValidateResponse], custom_page, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_validate(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.access.custom_pages.with_raw_response.validate( + account_id="", + template="template", + type="identity_denied", + ) + class TestAsyncCustomPages: parametrize = pytest.mark.parametrize( @@ -585,3 +642,59 @@ async def test_path_params_get(self, async_client: AsyncCloudflare) -> None: custom_page_id="", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) + + @parametrize + async def test_method_validate(self, async_client: AsyncCloudflare) -> None: + custom_page = await async_client.zero_trust.access.custom_pages.validate( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + template="template", + type="identity_denied", + ) + assert_matches_type(Optional[CustomPageValidateResponse], custom_page, path=["response"]) + + @parametrize + async def test_method_validate_with_all_params(self, async_client: AsyncCloudflare) -> None: + custom_page = await async_client.zero_trust.access.custom_pages.validate( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + template="template", + type="identity_denied", + version=0, + ) + assert_matches_type(Optional[CustomPageValidateResponse], custom_page, path=["response"]) + + @parametrize + async def test_raw_response_validate(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.access.custom_pages.with_raw_response.validate( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + template="template", + type="identity_denied", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + custom_page = await response.parse() + assert_matches_type(Optional[CustomPageValidateResponse], custom_page, path=["response"]) + + @parametrize + async def test_streaming_response_validate(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.access.custom_pages.with_streaming_response.validate( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + template="template", + type="identity_denied", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + custom_page = await response.parse() + assert_matches_type(Optional[CustomPageValidateResponse], custom_page, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_validate(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.access.custom_pages.with_raw_response.validate( + account_id="", + template="template", + type="identity_denied", + ) diff --git a/tests/api_resources/zero_trust/access/test_policies.py b/tests/api_resources/zero_trust/access/test_policies.py index d699482a599..78126a870d8 100644 --- a/tests/api_resources/zero_trust/access/test_policies.py +++ b/tests/api_resources/zero_trust/access/test_policies.py @@ -67,6 +67,7 @@ def test_method_create_with_all_params(self, client: Cloudflare) -> None: "mfa_disabled": False, "session_duration": "24h", }, + policy_resolution_account_id="policy_resolution_account_id", purpose_justification_prompt="Please enter a justification for entering this protected domain.", purpose_justification_required=True, require=[{"certificate": {}}], @@ -159,6 +160,7 @@ def test_method_update_with_all_params(self, client: Cloudflare) -> None: "mfa_disabled": False, "session_duration": "24h", }, + policy_resolution_account_id="policy_resolution_account_id", purpose_justification_prompt="Please enter a justification for entering this protected domain.", purpose_justification_required=True, require=[{"certificate": {}}], @@ -410,6 +412,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncCloudflare "mfa_disabled": False, "session_duration": "24h", }, + policy_resolution_account_id="policy_resolution_account_id", purpose_justification_prompt="Please enter a justification for entering this protected domain.", purpose_justification_required=True, require=[{"certificate": {}}], @@ -502,6 +505,7 @@ async def test_method_update_with_all_params(self, async_client: AsyncCloudflare "mfa_disabled": False, "session_duration": "24h", }, + policy_resolution_account_id="policy_resolution_account_id", purpose_justification_prompt="Please enter a justification for entering this protected domain.", purpose_justification_required=True, require=[{"certificate": {}}], diff --git a/tests/api_resources/zero_trust/access/test_service_tokens.py b/tests/api_resources/zero_trust/access/test_service_tokens.py index 82ff920f195..5ae80049f09 100644 --- a/tests/api_resources/zero_trust/access/test_service_tokens.py +++ b/tests/api_resources/zero_trust/access/test_service_tokens.py @@ -42,6 +42,7 @@ def test_method_create_with_all_params(self, client: Cloudflare) -> None: duration="60m", enabled=True, previous_client_secret_expires_at=parse_datetime("2014-01-01T05:20:00.12345Z"), + tags={"environment": "production"}, ) assert_matches_type(Optional[ServiceTokenCreateResponse], service_token, path=["response"]) @@ -108,6 +109,7 @@ def test_method_update_with_all_params(self, client: Cloudflare) -> None: enabled=True, name="CI/CD token", previous_client_secret_expires_at=parse_datetime("2014-01-01T05:20:00.12345Z"), + tags={"environment": "production"}, ) assert_matches_type(Optional[ServiceToken], service_token, path=["response"]) @@ -483,6 +485,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncCloudflare duration="60m", enabled=True, previous_client_secret_expires_at=parse_datetime("2014-01-01T05:20:00.12345Z"), + tags={"environment": "production"}, ) assert_matches_type(Optional[ServiceTokenCreateResponse], service_token, path=["response"]) @@ -549,6 +552,7 @@ async def test_method_update_with_all_params(self, async_client: AsyncCloudflare enabled=True, name="CI/CD token", previous_client_secret_expires_at=parse_datetime("2014-01-01T05:20:00.12345Z"), + tags={"environment": "production"}, ) assert_matches_type(Optional[ServiceToken], service_token, path=["response"]) diff --git a/tests/api_resources/zero_trust/access/test_user_populations.py b/tests/api_resources/zero_trust/access/test_user_populations.py new file mode 100644 index 00000000000..4d168022837 --- /dev/null +++ b/tests/api_resources/zero_trust/access/test_user_populations.py @@ -0,0 +1,511 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import os +from typing import Any, Optional, cast + +import pytest + +from cloudflare import Cloudflare, AsyncCloudflare +from tests.utils import assert_matches_type +from cloudflare.pagination import SyncV4PagePaginationArray, AsyncV4PagePaginationArray +from cloudflare.types.zero_trust.access import ( + UserPopulationGetResponse, + UserPopulationListResponse, + UserPopulationCreateResponse, + UserPopulationDeleteResponse, + UserPopulationUpdateResponse, +) + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestUserPopulations: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @parametrize + def test_method_create(self, client: Cloudflare) -> None: + user_population = client.zero_trust.access.user_populations.create( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + name="Employees", + ) + assert_matches_type(Optional[UserPopulationCreateResponse], user_population, path=["response"]) + + @parametrize + def test_raw_response_create(self, client: Cloudflare) -> None: + response = client.zero_trust.access.user_populations.with_raw_response.create( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + name="Employees", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + user_population = response.parse() + assert_matches_type(Optional[UserPopulationCreateResponse], user_population, path=["response"]) + + @parametrize + def test_streaming_response_create(self, client: Cloudflare) -> None: + with client.zero_trust.access.user_populations.with_streaming_response.create( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + name="Employees", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + user_population = response.parse() + assert_matches_type(Optional[UserPopulationCreateResponse], user_population, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_create(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.access.user_populations.with_raw_response.create( + account_id="", + name="Employees", + ) + + @parametrize + def test_method_update(self, client: Cloudflare) -> None: + user_population = client.zero_trust.access.user_populations.update( + user_population_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + name="Employees", + ) + assert_matches_type(Optional[UserPopulationUpdateResponse], user_population, path=["response"]) + + @parametrize + def test_raw_response_update(self, client: Cloudflare) -> None: + response = client.zero_trust.access.user_populations.with_raw_response.update( + user_population_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + name="Employees", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + user_population = response.parse() + assert_matches_type(Optional[UserPopulationUpdateResponse], user_population, path=["response"]) + + @parametrize + def test_streaming_response_update(self, client: Cloudflare) -> None: + with client.zero_trust.access.user_populations.with_streaming_response.update( + user_population_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + name="Employees", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + user_population = response.parse() + assert_matches_type(Optional[UserPopulationUpdateResponse], user_population, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_update(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.access.user_populations.with_raw_response.update( + user_population_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + account_id="", + name="Employees", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `user_population_id` but received ''"): + client.zero_trust.access.user_populations.with_raw_response.update( + user_population_id="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + name="Employees", + ) + + @parametrize + def test_method_list(self, client: Cloudflare) -> None: + user_population = client.zero_trust.access.user_populations.list( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + assert_matches_type(SyncV4PagePaginationArray[UserPopulationListResponse], user_population, path=["response"]) + + @parametrize + def test_method_list_with_all_params(self, client: Cloudflare) -> None: + user_population = client.zero_trust.access.user_populations.list( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + page=0, + per_page=1000, + ) + assert_matches_type(SyncV4PagePaginationArray[UserPopulationListResponse], user_population, path=["response"]) + + @parametrize + def test_raw_response_list(self, client: Cloudflare) -> None: + response = client.zero_trust.access.user_populations.with_raw_response.list( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + user_population = response.parse() + assert_matches_type(SyncV4PagePaginationArray[UserPopulationListResponse], user_population, path=["response"]) + + @parametrize + def test_streaming_response_list(self, client: Cloudflare) -> None: + with client.zero_trust.access.user_populations.with_streaming_response.list( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + user_population = response.parse() + assert_matches_type( + SyncV4PagePaginationArray[UserPopulationListResponse], user_population, path=["response"] + ) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_list(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.access.user_populations.with_raw_response.list( + account_id="", + ) + + @parametrize + def test_method_delete(self, client: Cloudflare) -> None: + user_population = client.zero_trust.access.user_populations.delete( + user_population_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + assert_matches_type(Optional[UserPopulationDeleteResponse], user_population, path=["response"]) + + @parametrize + def test_raw_response_delete(self, client: Cloudflare) -> None: + response = client.zero_trust.access.user_populations.with_raw_response.delete( + user_population_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + user_population = response.parse() + assert_matches_type(Optional[UserPopulationDeleteResponse], user_population, path=["response"]) + + @parametrize + def test_streaming_response_delete(self, client: Cloudflare) -> None: + with client.zero_trust.access.user_populations.with_streaming_response.delete( + user_population_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + user_population = response.parse() + assert_matches_type(Optional[UserPopulationDeleteResponse], user_population, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_delete(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.access.user_populations.with_raw_response.delete( + user_population_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `user_population_id` but received ''"): + client.zero_trust.access.user_populations.with_raw_response.delete( + user_population_id="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + @parametrize + def test_method_get(self, client: Cloudflare) -> None: + user_population = client.zero_trust.access.user_populations.get( + user_population_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + assert_matches_type(Optional[UserPopulationGetResponse], user_population, path=["response"]) + + @parametrize + def test_raw_response_get(self, client: Cloudflare) -> None: + response = client.zero_trust.access.user_populations.with_raw_response.get( + user_population_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + user_population = response.parse() + assert_matches_type(Optional[UserPopulationGetResponse], user_population, path=["response"]) + + @parametrize + def test_streaming_response_get(self, client: Cloudflare) -> None: + with client.zero_trust.access.user_populations.with_streaming_response.get( + user_population_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + user_population = response.parse() + assert_matches_type(Optional[UserPopulationGetResponse], user_population, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_get(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.access.user_populations.with_raw_response.get( + user_population_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `user_population_id` but received ''"): + client.zero_trust.access.user_populations.with_raw_response.get( + user_population_id="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + +class TestAsyncUserPopulations: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @parametrize + async def test_method_create(self, async_client: AsyncCloudflare) -> None: + user_population = await async_client.zero_trust.access.user_populations.create( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + name="Employees", + ) + assert_matches_type(Optional[UserPopulationCreateResponse], user_population, path=["response"]) + + @parametrize + async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.access.user_populations.with_raw_response.create( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + name="Employees", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + user_population = await response.parse() + assert_matches_type(Optional[UserPopulationCreateResponse], user_population, path=["response"]) + + @parametrize + async def test_streaming_response_create(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.access.user_populations.with_streaming_response.create( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + name="Employees", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + user_population = await response.parse() + assert_matches_type(Optional[UserPopulationCreateResponse], user_population, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_create(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.access.user_populations.with_raw_response.create( + account_id="", + name="Employees", + ) + + @parametrize + async def test_method_update(self, async_client: AsyncCloudflare) -> None: + user_population = await async_client.zero_trust.access.user_populations.update( + user_population_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + name="Employees", + ) + assert_matches_type(Optional[UserPopulationUpdateResponse], user_population, path=["response"]) + + @parametrize + async def test_raw_response_update(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.access.user_populations.with_raw_response.update( + user_population_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + name="Employees", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + user_population = await response.parse() + assert_matches_type(Optional[UserPopulationUpdateResponse], user_population, path=["response"]) + + @parametrize + async def test_streaming_response_update(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.access.user_populations.with_streaming_response.update( + user_population_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + name="Employees", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + user_population = await response.parse() + assert_matches_type(Optional[UserPopulationUpdateResponse], user_population, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_update(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.access.user_populations.with_raw_response.update( + user_population_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + account_id="", + name="Employees", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `user_population_id` but received ''"): + await async_client.zero_trust.access.user_populations.with_raw_response.update( + user_population_id="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + name="Employees", + ) + + @parametrize + async def test_method_list(self, async_client: AsyncCloudflare) -> None: + user_population = await async_client.zero_trust.access.user_populations.list( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + assert_matches_type(AsyncV4PagePaginationArray[UserPopulationListResponse], user_population, path=["response"]) + + @parametrize + async def test_method_list_with_all_params(self, async_client: AsyncCloudflare) -> None: + user_population = await async_client.zero_trust.access.user_populations.list( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + page=0, + per_page=1000, + ) + assert_matches_type(AsyncV4PagePaginationArray[UserPopulationListResponse], user_population, path=["response"]) + + @parametrize + async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.access.user_populations.with_raw_response.list( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + user_population = await response.parse() + assert_matches_type(AsyncV4PagePaginationArray[UserPopulationListResponse], user_population, path=["response"]) + + @parametrize + async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.access.user_populations.with_streaming_response.list( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + user_population = await response.parse() + assert_matches_type( + AsyncV4PagePaginationArray[UserPopulationListResponse], user_population, path=["response"] + ) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_list(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.access.user_populations.with_raw_response.list( + account_id="", + ) + + @parametrize + async def test_method_delete(self, async_client: AsyncCloudflare) -> None: + user_population = await async_client.zero_trust.access.user_populations.delete( + user_population_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + assert_matches_type(Optional[UserPopulationDeleteResponse], user_population, path=["response"]) + + @parametrize + async def test_raw_response_delete(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.access.user_populations.with_raw_response.delete( + user_population_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + user_population = await response.parse() + assert_matches_type(Optional[UserPopulationDeleteResponse], user_population, path=["response"]) + + @parametrize + async def test_streaming_response_delete(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.access.user_populations.with_streaming_response.delete( + user_population_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + user_population = await response.parse() + assert_matches_type(Optional[UserPopulationDeleteResponse], user_population, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_delete(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.access.user_populations.with_raw_response.delete( + user_population_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `user_population_id` but received ''"): + await async_client.zero_trust.access.user_populations.with_raw_response.delete( + user_population_id="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + @parametrize + async def test_method_get(self, async_client: AsyncCloudflare) -> None: + user_population = await async_client.zero_trust.access.user_populations.get( + user_population_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + assert_matches_type(Optional[UserPopulationGetResponse], user_population, path=["response"]) + + @parametrize + async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.access.user_populations.with_raw_response.get( + user_population_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + user_population = await response.parse() + assert_matches_type(Optional[UserPopulationGetResponse], user_population, path=["response"]) + + @parametrize + async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.access.user_populations.with_streaming_response.get( + user_population_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + user_population = await response.parse() + assert_matches_type(Optional[UserPopulationGetResponse], user_population, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_get(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.access.user_populations.with_raw_response.get( + user_population_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `user_population_id` but received ''"): + await async_client.zero_trust.access.user_populations.with_raw_response.get( + user_population_id="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) diff --git a/tests/api_resources/zero_trust/access/user_populations/__init__.py b/tests/api_resources/zero_trust/access/user_populations/__init__.py new file mode 100644 index 00000000000..fd8019a9a1a --- /dev/null +++ b/tests/api_resources/zero_trust/access/user_populations/__init__.py @@ -0,0 +1 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. diff --git a/tests/api_resources/zero_trust/access/user_populations/test_users.py b/tests/api_resources/zero_trust/access/user_populations/test_users.py new file mode 100644 index 00000000000..eb2751f88da --- /dev/null +++ b/tests/api_resources/zero_trust/access/user_populations/test_users.py @@ -0,0 +1,939 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import os +from typing import Any, Optional, cast + +import pytest + +from cloudflare import Cloudflare, AsyncCloudflare +from tests.utils import assert_matches_type +from cloudflare._utils import parse_datetime +from cloudflare.types.zero_trust.access.user_populations import ( + UserGetResponse, + UserListResponse, + UserCreateResponse, + UserUpdateResponse, + UserReplaceResponse, +) + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestUsers: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @parametrize + def test_method_create(self, client: Cloudflare) -> None: + user = client.zero_trust.access.user_populations.users.create( + user_population_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + assert_matches_type(Optional[UserCreateResponse], user, path=["response"]) + + @parametrize + def test_method_create_with_all_params(self, client: Cloudflare) -> None: + user = client.zero_trust.access.user_populations.users.create( + user_population_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + active=True, + display_name="displayName", + emails=[ + { + "primary": True, + "type": "type", + "value": "value", + } + ], + external_id="externalId", + meta={ + "created": parse_datetime("2019-12-27T18:11:19.117Z"), + "last_modified": parse_datetime("2019-12-27T18:11:19.117Z"), + "location": "https://example.com", + "resource_type": "resourceType", + "version": "version", + }, + name={ + "family_name": "familyName", + "formatted": "formatted", + "given_name": "givenName", + "honorific_prefix": "honorificPrefix", + "honorific_suffix": "honorificSuffix", + "middle_name": "middleName", + }, + schemas=["string"], + user_name="userName", + ) + assert_matches_type(Optional[UserCreateResponse], user, path=["response"]) + + @parametrize + def test_raw_response_create(self, client: Cloudflare) -> None: + response = client.zero_trust.access.user_populations.users.with_raw_response.create( + user_population_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + user = response.parse() + assert_matches_type(Optional[UserCreateResponse], user, path=["response"]) + + @parametrize + def test_streaming_response_create(self, client: Cloudflare) -> None: + with client.zero_trust.access.user_populations.users.with_streaming_response.create( + user_population_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + user = response.parse() + assert_matches_type(Optional[UserCreateResponse], user, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_create(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.access.user_populations.users.with_raw_response.create( + user_population_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `user_population_id` but received ''"): + client.zero_trust.access.user_populations.users.with_raw_response.create( + user_population_id="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + @parametrize + def test_method_update(self, client: Cloudflare) -> None: + user = client.zero_trust.access.user_populations.users.update( + user_id="user_id", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + user_population_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + operations=[{"op": "add"}], + ) + assert_matches_type(Optional[UserUpdateResponse], user, path=["response"]) + + @parametrize + def test_method_update_with_all_params(self, client: Cloudflare) -> None: + user = client.zero_trust.access.user_populations.users.update( + user_id="user_id", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + user_population_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + operations=[ + { + "op": "add", + "path": "path", + "value": "string", + } + ], + schemas=["string"], + ) + assert_matches_type(Optional[UserUpdateResponse], user, path=["response"]) + + @parametrize + def test_raw_response_update(self, client: Cloudflare) -> None: + response = client.zero_trust.access.user_populations.users.with_raw_response.update( + user_id="user_id", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + user_population_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + operations=[{"op": "add"}], + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + user = response.parse() + assert_matches_type(Optional[UserUpdateResponse], user, path=["response"]) + + @parametrize + def test_streaming_response_update(self, client: Cloudflare) -> None: + with client.zero_trust.access.user_populations.users.with_streaming_response.update( + user_id="user_id", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + user_population_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + operations=[{"op": "add"}], + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + user = response.parse() + assert_matches_type(Optional[UserUpdateResponse], user, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_update(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.access.user_populations.users.with_raw_response.update( + user_id="user_id", + account_id="", + user_population_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + operations=[{"op": "add"}], + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `user_population_id` but received ''"): + client.zero_trust.access.user_populations.users.with_raw_response.update( + user_id="user_id", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + user_population_id="", + operations=[{"op": "add"}], + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `user_id` but received ''"): + client.zero_trust.access.user_populations.users.with_raw_response.update( + user_id="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + user_population_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + operations=[{"op": "add"}], + ) + + @parametrize + def test_method_list(self, client: Cloudflare) -> None: + user = client.zero_trust.access.user_populations.users.list( + user_population_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + assert_matches_type(Optional[UserListResponse], user, path=["response"]) + + @parametrize + def test_method_list_with_all_params(self, client: Cloudflare) -> None: + user = client.zero_trust.access.user_populations.users.list( + user_population_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + attributes="attributes", + count=0, + excluded_attributes="excludedAttributes", + filter="filter", + start_index=1, + ) + assert_matches_type(Optional[UserListResponse], user, path=["response"]) + + @parametrize + def test_raw_response_list(self, client: Cloudflare) -> None: + response = client.zero_trust.access.user_populations.users.with_raw_response.list( + user_population_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + user = response.parse() + assert_matches_type(Optional[UserListResponse], user, path=["response"]) + + @parametrize + def test_streaming_response_list(self, client: Cloudflare) -> None: + with client.zero_trust.access.user_populations.users.with_streaming_response.list( + user_population_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + user = response.parse() + assert_matches_type(Optional[UserListResponse], user, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_list(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.access.user_populations.users.with_raw_response.list( + user_population_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `user_population_id` but received ''"): + client.zero_trust.access.user_populations.users.with_raw_response.list( + user_population_id="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + @parametrize + def test_method_delete(self, client: Cloudflare) -> None: + user = client.zero_trust.access.user_populations.users.delete( + user_id="user_id", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + user_population_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + ) + assert user is None + + @parametrize + def test_raw_response_delete(self, client: Cloudflare) -> None: + response = client.zero_trust.access.user_populations.users.with_raw_response.delete( + user_id="user_id", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + user_population_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + user = response.parse() + assert user is None + + @parametrize + def test_streaming_response_delete(self, client: Cloudflare) -> None: + with client.zero_trust.access.user_populations.users.with_streaming_response.delete( + user_id="user_id", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + user_population_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + user = response.parse() + assert user is None + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_delete(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.access.user_populations.users.with_raw_response.delete( + user_id="user_id", + account_id="", + user_population_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `user_population_id` but received ''"): + client.zero_trust.access.user_populations.users.with_raw_response.delete( + user_id="user_id", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + user_population_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `user_id` but received ''"): + client.zero_trust.access.user_populations.users.with_raw_response.delete( + user_id="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + user_population_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + ) + + @parametrize + def test_method_get(self, client: Cloudflare) -> None: + user = client.zero_trust.access.user_populations.users.get( + user_id="user_id", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + user_population_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + ) + assert_matches_type(Optional[UserGetResponse], user, path=["response"]) + + @parametrize + def test_method_get_with_all_params(self, client: Cloudflare) -> None: + user = client.zero_trust.access.user_populations.users.get( + user_id="user_id", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + user_population_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + attributes="attributes", + excluded_attributes="excludedAttributes", + ) + assert_matches_type(Optional[UserGetResponse], user, path=["response"]) + + @parametrize + def test_raw_response_get(self, client: Cloudflare) -> None: + response = client.zero_trust.access.user_populations.users.with_raw_response.get( + user_id="user_id", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + user_population_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + user = response.parse() + assert_matches_type(Optional[UserGetResponse], user, path=["response"]) + + @parametrize + def test_streaming_response_get(self, client: Cloudflare) -> None: + with client.zero_trust.access.user_populations.users.with_streaming_response.get( + user_id="user_id", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + user_population_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + user = response.parse() + assert_matches_type(Optional[UserGetResponse], user, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_get(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.access.user_populations.users.with_raw_response.get( + user_id="user_id", + account_id="", + user_population_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `user_population_id` but received ''"): + client.zero_trust.access.user_populations.users.with_raw_response.get( + user_id="user_id", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + user_population_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `user_id` but received ''"): + client.zero_trust.access.user_populations.users.with_raw_response.get( + user_id="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + user_population_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + ) + + @parametrize + def test_method_replace(self, client: Cloudflare) -> None: + user = client.zero_trust.access.user_populations.users.replace( + user_id="user_id", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + user_population_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + ) + assert_matches_type(Optional[UserReplaceResponse], user, path=["response"]) + + @parametrize + def test_method_replace_with_all_params(self, client: Cloudflare) -> None: + user = client.zero_trust.access.user_populations.users.replace( + user_id="user_id", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + user_population_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + active=True, + display_name="displayName", + emails=[ + { + "primary": True, + "type": "type", + "value": "value", + } + ], + external_id="externalId", + meta={ + "created": parse_datetime("2019-12-27T18:11:19.117Z"), + "last_modified": parse_datetime("2019-12-27T18:11:19.117Z"), + "location": "https://example.com", + "resource_type": "resourceType", + "version": "version", + }, + name={ + "family_name": "familyName", + "formatted": "formatted", + "given_name": "givenName", + "honorific_prefix": "honorificPrefix", + "honorific_suffix": "honorificSuffix", + "middle_name": "middleName", + }, + schemas=["string"], + user_name="userName", + ) + assert_matches_type(Optional[UserReplaceResponse], user, path=["response"]) + + @parametrize + def test_raw_response_replace(self, client: Cloudflare) -> None: + response = client.zero_trust.access.user_populations.users.with_raw_response.replace( + user_id="user_id", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + user_population_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + user = response.parse() + assert_matches_type(Optional[UserReplaceResponse], user, path=["response"]) + + @parametrize + def test_streaming_response_replace(self, client: Cloudflare) -> None: + with client.zero_trust.access.user_populations.users.with_streaming_response.replace( + user_id="user_id", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + user_population_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + user = response.parse() + assert_matches_type(Optional[UserReplaceResponse], user, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_replace(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.access.user_populations.users.with_raw_response.replace( + user_id="user_id", + account_id="", + user_population_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `user_population_id` but received ''"): + client.zero_trust.access.user_populations.users.with_raw_response.replace( + user_id="user_id", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + user_population_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `user_id` but received ''"): + client.zero_trust.access.user_populations.users.with_raw_response.replace( + user_id="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + user_population_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + ) + + +class TestAsyncUsers: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @parametrize + async def test_method_create(self, async_client: AsyncCloudflare) -> None: + user = await async_client.zero_trust.access.user_populations.users.create( + user_population_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + assert_matches_type(Optional[UserCreateResponse], user, path=["response"]) + + @parametrize + async def test_method_create_with_all_params(self, async_client: AsyncCloudflare) -> None: + user = await async_client.zero_trust.access.user_populations.users.create( + user_population_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + active=True, + display_name="displayName", + emails=[ + { + "primary": True, + "type": "type", + "value": "value", + } + ], + external_id="externalId", + meta={ + "created": parse_datetime("2019-12-27T18:11:19.117Z"), + "last_modified": parse_datetime("2019-12-27T18:11:19.117Z"), + "location": "https://example.com", + "resource_type": "resourceType", + "version": "version", + }, + name={ + "family_name": "familyName", + "formatted": "formatted", + "given_name": "givenName", + "honorific_prefix": "honorificPrefix", + "honorific_suffix": "honorificSuffix", + "middle_name": "middleName", + }, + schemas=["string"], + user_name="userName", + ) + assert_matches_type(Optional[UserCreateResponse], user, path=["response"]) + + @parametrize + async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.access.user_populations.users.with_raw_response.create( + user_population_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + user = await response.parse() + assert_matches_type(Optional[UserCreateResponse], user, path=["response"]) + + @parametrize + async def test_streaming_response_create(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.access.user_populations.users.with_streaming_response.create( + user_population_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + user = await response.parse() + assert_matches_type(Optional[UserCreateResponse], user, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_create(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.access.user_populations.users.with_raw_response.create( + user_population_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `user_population_id` but received ''"): + await async_client.zero_trust.access.user_populations.users.with_raw_response.create( + user_population_id="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + @parametrize + async def test_method_update(self, async_client: AsyncCloudflare) -> None: + user = await async_client.zero_trust.access.user_populations.users.update( + user_id="user_id", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + user_population_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + operations=[{"op": "add"}], + ) + assert_matches_type(Optional[UserUpdateResponse], user, path=["response"]) + + @parametrize + async def test_method_update_with_all_params(self, async_client: AsyncCloudflare) -> None: + user = await async_client.zero_trust.access.user_populations.users.update( + user_id="user_id", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + user_population_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + operations=[ + { + "op": "add", + "path": "path", + "value": "string", + } + ], + schemas=["string"], + ) + assert_matches_type(Optional[UserUpdateResponse], user, path=["response"]) + + @parametrize + async def test_raw_response_update(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.access.user_populations.users.with_raw_response.update( + user_id="user_id", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + user_population_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + operations=[{"op": "add"}], + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + user = await response.parse() + assert_matches_type(Optional[UserUpdateResponse], user, path=["response"]) + + @parametrize + async def test_streaming_response_update(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.access.user_populations.users.with_streaming_response.update( + user_id="user_id", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + user_population_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + operations=[{"op": "add"}], + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + user = await response.parse() + assert_matches_type(Optional[UserUpdateResponse], user, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_update(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.access.user_populations.users.with_raw_response.update( + user_id="user_id", + account_id="", + user_population_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + operations=[{"op": "add"}], + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `user_population_id` but received ''"): + await async_client.zero_trust.access.user_populations.users.with_raw_response.update( + user_id="user_id", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + user_population_id="", + operations=[{"op": "add"}], + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `user_id` but received ''"): + await async_client.zero_trust.access.user_populations.users.with_raw_response.update( + user_id="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + user_population_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + operations=[{"op": "add"}], + ) + + @parametrize + async def test_method_list(self, async_client: AsyncCloudflare) -> None: + user = await async_client.zero_trust.access.user_populations.users.list( + user_population_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + assert_matches_type(Optional[UserListResponse], user, path=["response"]) + + @parametrize + async def test_method_list_with_all_params(self, async_client: AsyncCloudflare) -> None: + user = await async_client.zero_trust.access.user_populations.users.list( + user_population_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + attributes="attributes", + count=0, + excluded_attributes="excludedAttributes", + filter="filter", + start_index=1, + ) + assert_matches_type(Optional[UserListResponse], user, path=["response"]) + + @parametrize + async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.access.user_populations.users.with_raw_response.list( + user_population_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + user = await response.parse() + assert_matches_type(Optional[UserListResponse], user, path=["response"]) + + @parametrize + async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.access.user_populations.users.with_streaming_response.list( + user_population_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + user = await response.parse() + assert_matches_type(Optional[UserListResponse], user, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_list(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.access.user_populations.users.with_raw_response.list( + user_population_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `user_population_id` but received ''"): + await async_client.zero_trust.access.user_populations.users.with_raw_response.list( + user_population_id="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + @parametrize + async def test_method_delete(self, async_client: AsyncCloudflare) -> None: + user = await async_client.zero_trust.access.user_populations.users.delete( + user_id="user_id", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + user_population_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + ) + assert user is None + + @parametrize + async def test_raw_response_delete(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.access.user_populations.users.with_raw_response.delete( + user_id="user_id", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + user_population_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + user = await response.parse() + assert user is None + + @parametrize + async def test_streaming_response_delete(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.access.user_populations.users.with_streaming_response.delete( + user_id="user_id", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + user_population_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + user = await response.parse() + assert user is None + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_delete(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.access.user_populations.users.with_raw_response.delete( + user_id="user_id", + account_id="", + user_population_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `user_population_id` but received ''"): + await async_client.zero_trust.access.user_populations.users.with_raw_response.delete( + user_id="user_id", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + user_population_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `user_id` but received ''"): + await async_client.zero_trust.access.user_populations.users.with_raw_response.delete( + user_id="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + user_population_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + ) + + @parametrize + async def test_method_get(self, async_client: AsyncCloudflare) -> None: + user = await async_client.zero_trust.access.user_populations.users.get( + user_id="user_id", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + user_population_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + ) + assert_matches_type(Optional[UserGetResponse], user, path=["response"]) + + @parametrize + async def test_method_get_with_all_params(self, async_client: AsyncCloudflare) -> None: + user = await async_client.zero_trust.access.user_populations.users.get( + user_id="user_id", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + user_population_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + attributes="attributes", + excluded_attributes="excludedAttributes", + ) + assert_matches_type(Optional[UserGetResponse], user, path=["response"]) + + @parametrize + async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.access.user_populations.users.with_raw_response.get( + user_id="user_id", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + user_population_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + user = await response.parse() + assert_matches_type(Optional[UserGetResponse], user, path=["response"]) + + @parametrize + async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.access.user_populations.users.with_streaming_response.get( + user_id="user_id", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + user_population_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + user = await response.parse() + assert_matches_type(Optional[UserGetResponse], user, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_get(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.access.user_populations.users.with_raw_response.get( + user_id="user_id", + account_id="", + user_population_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `user_population_id` but received ''"): + await async_client.zero_trust.access.user_populations.users.with_raw_response.get( + user_id="user_id", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + user_population_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `user_id` but received ''"): + await async_client.zero_trust.access.user_populations.users.with_raw_response.get( + user_id="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + user_population_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + ) + + @parametrize + async def test_method_replace(self, async_client: AsyncCloudflare) -> None: + user = await async_client.zero_trust.access.user_populations.users.replace( + user_id="user_id", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + user_population_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + ) + assert_matches_type(Optional[UserReplaceResponse], user, path=["response"]) + + @parametrize + async def test_method_replace_with_all_params(self, async_client: AsyncCloudflare) -> None: + user = await async_client.zero_trust.access.user_populations.users.replace( + user_id="user_id", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + user_population_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + active=True, + display_name="displayName", + emails=[ + { + "primary": True, + "type": "type", + "value": "value", + } + ], + external_id="externalId", + meta={ + "created": parse_datetime("2019-12-27T18:11:19.117Z"), + "last_modified": parse_datetime("2019-12-27T18:11:19.117Z"), + "location": "https://example.com", + "resource_type": "resourceType", + "version": "version", + }, + name={ + "family_name": "familyName", + "formatted": "formatted", + "given_name": "givenName", + "honorific_prefix": "honorificPrefix", + "honorific_suffix": "honorificSuffix", + "middle_name": "middleName", + }, + schemas=["string"], + user_name="userName", + ) + assert_matches_type(Optional[UserReplaceResponse], user, path=["response"]) + + @parametrize + async def test_raw_response_replace(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.access.user_populations.users.with_raw_response.replace( + user_id="user_id", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + user_population_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + user = await response.parse() + assert_matches_type(Optional[UserReplaceResponse], user, path=["response"]) + + @parametrize + async def test_streaming_response_replace(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.access.user_populations.users.with_streaming_response.replace( + user_id="user_id", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + user_population_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + user = await response.parse() + assert_matches_type(Optional[UserReplaceResponse], user, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_replace(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.access.user_populations.users.with_raw_response.replace( + user_id="user_id", + account_id="", + user_population_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `user_population_id` but received ''"): + await async_client.zero_trust.access.user_populations.users.with_raw_response.replace( + user_id="user_id", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + user_population_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `user_id` but received ''"): + await async_client.zero_trust.access.user_populations.users.with_raw_response.replace( + user_id="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + user_population_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + ) diff --git a/tests/api_resources/zero_trust/access/users/test_last_seen_identity.py b/tests/api_resources/zero_trust/access/users/test_last_seen_identity.py index 5505fe5588a..eaba134a2f4 100644 --- a/tests/api_resources/zero_trust/access/users/test_last_seen_identity.py +++ b/tests/api_resources/zero_trust/access/users/test_last_seen_identity.py @@ -9,7 +9,7 @@ from cloudflare import Cloudflare, AsyncCloudflare from tests.utils import assert_matches_type -from cloudflare.types.zero_trust.access.users import Identity +from cloudflare.types.zero_trust.access.users import LastSeenIdentityGetResponse base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") @@ -23,7 +23,7 @@ def test_method_get(self, client: Cloudflare) -> None: user_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) - assert_matches_type(Optional[Identity], last_seen_identity, path=["response"]) + assert_matches_type(Optional[LastSeenIdentityGetResponse], last_seen_identity, path=["response"]) @parametrize def test_raw_response_get(self, client: Cloudflare) -> None: @@ -35,7 +35,7 @@ def test_raw_response_get(self, client: Cloudflare) -> None: assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" last_seen_identity = response.parse() - assert_matches_type(Optional[Identity], last_seen_identity, path=["response"]) + assert_matches_type(Optional[LastSeenIdentityGetResponse], last_seen_identity, path=["response"]) @parametrize def test_streaming_response_get(self, client: Cloudflare) -> None: @@ -47,7 +47,7 @@ def test_streaming_response_get(self, client: Cloudflare) -> None: assert response.http_request.headers.get("X-Stainless-Lang") == "python" last_seen_identity = response.parse() - assert_matches_type(Optional[Identity], last_seen_identity, path=["response"]) + assert_matches_type(Optional[LastSeenIdentityGetResponse], last_seen_identity, path=["response"]) assert cast(Any, response.is_closed) is True @@ -77,7 +77,7 @@ async def test_method_get(self, async_client: AsyncCloudflare) -> None: user_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) - assert_matches_type(Optional[Identity], last_seen_identity, path=["response"]) + assert_matches_type(Optional[LastSeenIdentityGetResponse], last_seen_identity, path=["response"]) @parametrize async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None: @@ -89,7 +89,7 @@ async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None: assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" last_seen_identity = await response.parse() - assert_matches_type(Optional[Identity], last_seen_identity, path=["response"]) + assert_matches_type(Optional[LastSeenIdentityGetResponse], last_seen_identity, path=["response"]) @parametrize async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> None: @@ -101,7 +101,7 @@ async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> No assert response.http_request.headers.get("X-Stainless-Lang") == "python" last_seen_identity = await response.parse() - assert_matches_type(Optional[Identity], last_seen_identity, path=["response"]) + assert_matches_type(Optional[LastSeenIdentityGetResponse], last_seen_identity, path=["response"]) assert cast(Any, response.is_closed) is True diff --git a/tests/api_resources/zero_trust/access/users/test_mfa_authenticators.py b/tests/api_resources/zero_trust/access/users/test_mfa_authenticators.py new file mode 100644 index 00000000000..d3cfbba9938 --- /dev/null +++ b/tests/api_resources/zero_trust/access/users/test_mfa_authenticators.py @@ -0,0 +1,143 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import os +from typing import Any, cast + +import pytest + +from cloudflare import Cloudflare, AsyncCloudflare +from tests.utils import assert_matches_type + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestMfaAuthenticators: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @parametrize + def test_method_delete(self, client: Cloudflare) -> None: + mfa_authenticator = client.zero_trust.access.users.mfa_authenticators.delete( + authenticator_id="test-authenticator-id-123", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + user_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + ) + assert_matches_type(object, mfa_authenticator, path=["response"]) + + @parametrize + def test_raw_response_delete(self, client: Cloudflare) -> None: + response = client.zero_trust.access.users.mfa_authenticators.with_raw_response.delete( + authenticator_id="test-authenticator-id-123", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + user_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + mfa_authenticator = response.parse() + assert_matches_type(object, mfa_authenticator, path=["response"]) + + @parametrize + def test_streaming_response_delete(self, client: Cloudflare) -> None: + with client.zero_trust.access.users.mfa_authenticators.with_streaming_response.delete( + authenticator_id="test-authenticator-id-123", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + user_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + mfa_authenticator = response.parse() + assert_matches_type(object, mfa_authenticator, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_delete(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.access.users.mfa_authenticators.with_raw_response.delete( + authenticator_id="test-authenticator-id-123", + account_id="", + user_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `user_id` but received ''"): + client.zero_trust.access.users.mfa_authenticators.with_raw_response.delete( + authenticator_id="test-authenticator-id-123", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + user_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `authenticator_id` but received ''"): + client.zero_trust.access.users.mfa_authenticators.with_raw_response.delete( + authenticator_id="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + user_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + ) + + +class TestAsyncMfaAuthenticators: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @parametrize + async def test_method_delete(self, async_client: AsyncCloudflare) -> None: + mfa_authenticator = await async_client.zero_trust.access.users.mfa_authenticators.delete( + authenticator_id="test-authenticator-id-123", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + user_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + ) + assert_matches_type(object, mfa_authenticator, path=["response"]) + + @parametrize + async def test_raw_response_delete(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.access.users.mfa_authenticators.with_raw_response.delete( + authenticator_id="test-authenticator-id-123", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + user_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + mfa_authenticator = await response.parse() + assert_matches_type(object, mfa_authenticator, path=["response"]) + + @parametrize + async def test_streaming_response_delete(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.access.users.mfa_authenticators.with_streaming_response.delete( + authenticator_id="test-authenticator-id-123", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + user_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + mfa_authenticator = await response.parse() + assert_matches_type(object, mfa_authenticator, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_delete(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.access.users.mfa_authenticators.with_raw_response.delete( + authenticator_id="test-authenticator-id-123", + account_id="", + user_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `user_id` but received ''"): + await async_client.zero_trust.access.users.mfa_authenticators.with_raw_response.delete( + authenticator_id="test-authenticator-id-123", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + user_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `authenticator_id` but received ''"): + await async_client.zero_trust.access.users.mfa_authenticators.with_raw_response.delete( + authenticator_id="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + user_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + ) diff --git a/tests/api_resources/zero_trust/access/users/test_passkeys.py b/tests/api_resources/zero_trust/access/users/test_passkeys.py new file mode 100644 index 00000000000..9e698f951e1 --- /dev/null +++ b/tests/api_resources/zero_trust/access/users/test_passkeys.py @@ -0,0 +1,143 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import os +from typing import Any, cast + +import pytest + +from cloudflare import Cloudflare, AsyncCloudflare +from tests.utils import assert_matches_type + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestPasskeys: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @parametrize + def test_method_delete(self, client: Cloudflare) -> None: + passkey = client.zero_trust.access.users.passkeys.delete( + authenticator_id="test-authenticator-id-123", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + user_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + ) + assert_matches_type(object, passkey, path=["response"]) + + @parametrize + def test_raw_response_delete(self, client: Cloudflare) -> None: + response = client.zero_trust.access.users.passkeys.with_raw_response.delete( + authenticator_id="test-authenticator-id-123", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + user_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + passkey = response.parse() + assert_matches_type(object, passkey, path=["response"]) + + @parametrize + def test_streaming_response_delete(self, client: Cloudflare) -> None: + with client.zero_trust.access.users.passkeys.with_streaming_response.delete( + authenticator_id="test-authenticator-id-123", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + user_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + passkey = response.parse() + assert_matches_type(object, passkey, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_delete(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.access.users.passkeys.with_raw_response.delete( + authenticator_id="test-authenticator-id-123", + account_id="", + user_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `user_id` but received ''"): + client.zero_trust.access.users.passkeys.with_raw_response.delete( + authenticator_id="test-authenticator-id-123", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + user_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `authenticator_id` but received ''"): + client.zero_trust.access.users.passkeys.with_raw_response.delete( + authenticator_id="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + user_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + ) + + +class TestAsyncPasskeys: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @parametrize + async def test_method_delete(self, async_client: AsyncCloudflare) -> None: + passkey = await async_client.zero_trust.access.users.passkeys.delete( + authenticator_id="test-authenticator-id-123", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + user_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + ) + assert_matches_type(object, passkey, path=["response"]) + + @parametrize + async def test_raw_response_delete(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.access.users.passkeys.with_raw_response.delete( + authenticator_id="test-authenticator-id-123", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + user_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + passkey = await response.parse() + assert_matches_type(object, passkey, path=["response"]) + + @parametrize + async def test_streaming_response_delete(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.access.users.passkeys.with_streaming_response.delete( + authenticator_id="test-authenticator-id-123", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + user_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + passkey = await response.parse() + assert_matches_type(object, passkey, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_delete(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.access.users.passkeys.with_raw_response.delete( + authenticator_id="test-authenticator-id-123", + account_id="", + user_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `user_id` but received ''"): + await async_client.zero_trust.access.users.passkeys.with_raw_response.delete( + authenticator_id="test-authenticator-id-123", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + user_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `authenticator_id` but received ''"): + await async_client.zero_trust.access.users.passkeys.with_raw_response.delete( + authenticator_id="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + user_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + ) diff --git a/tests/api_resources/zero_trust/casb/posture/test_asset_schemas.py b/tests/api_resources/zero_trust/casb/posture/test_asset_schemas.py new file mode 100644 index 00000000000..6d805d3219a --- /dev/null +++ b/tests/api_resources/zero_trust/casb/posture/test_asset_schemas.py @@ -0,0 +1,216 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import os +from typing import Any, Optional, cast + +import pytest + +from cloudflare import Cloudflare, AsyncCloudflare +from tests.utils import assert_matches_type +from cloudflare.pagination import SyncSinglePage, AsyncSinglePage +from cloudflare.types.zero_trust.casb.posture import ( + AssetSchemaGetResponse, + AssetSchemaListResponse, +) + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestAssetSchemas: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @parametrize + def test_method_list(self, client: Cloudflare) -> None: + asset_schema = client.zero_trust.casb.posture.asset_schemas.list( + account_id="46148281d8a93d002ef242d8b0d5f9f6", + ) + assert_matches_type(SyncSinglePage[AssetSchemaListResponse], asset_schema, path=["response"]) + + @parametrize + def test_method_list_with_all_params(self, client: Cloudflare) -> None: + asset_schema = client.zero_trust.casb.posture.asset_schemas.list( + account_id="46148281d8a93d002ef242d8b0d5f9f6", + vendor="ANTHROPIC", + ) + assert_matches_type(SyncSinglePage[AssetSchemaListResponse], asset_schema, path=["response"]) + + @parametrize + def test_raw_response_list(self, client: Cloudflare) -> None: + response = client.zero_trust.casb.posture.asset_schemas.with_raw_response.list( + account_id="46148281d8a93d002ef242d8b0d5f9f6", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + asset_schema = response.parse() + assert_matches_type(SyncSinglePage[AssetSchemaListResponse], asset_schema, path=["response"]) + + @parametrize + def test_streaming_response_list(self, client: Cloudflare) -> None: + with client.zero_trust.casb.posture.asset_schemas.with_streaming_response.list( + account_id="46148281d8a93d002ef242d8b0d5f9f6", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + asset_schema = response.parse() + assert_matches_type(SyncSinglePage[AssetSchemaListResponse], asset_schema, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_list(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.casb.posture.asset_schemas.with_raw_response.list( + account_id="", + ) + + @parametrize + def test_method_get(self, client: Cloudflare) -> None: + asset_schema = client.zero_trust.casb.posture.asset_schemas.get( + asset_class="AnthropicApiKey", + account_id="46148281d8a93d002ef242d8b0d5f9f6", + ) + assert_matches_type(Optional[AssetSchemaGetResponse], asset_schema, path=["response"]) + + @parametrize + def test_raw_response_get(self, client: Cloudflare) -> None: + response = client.zero_trust.casb.posture.asset_schemas.with_raw_response.get( + asset_class="AnthropicApiKey", + account_id="46148281d8a93d002ef242d8b0d5f9f6", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + asset_schema = response.parse() + assert_matches_type(Optional[AssetSchemaGetResponse], asset_schema, path=["response"]) + + @parametrize + def test_streaming_response_get(self, client: Cloudflare) -> None: + with client.zero_trust.casb.posture.asset_schemas.with_streaming_response.get( + asset_class="AnthropicApiKey", + account_id="46148281d8a93d002ef242d8b0d5f9f6", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + asset_schema = response.parse() + assert_matches_type(Optional[AssetSchemaGetResponse], asset_schema, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_get(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.casb.posture.asset_schemas.with_raw_response.get( + asset_class="AnthropicApiKey", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `asset_class` but received ''"): + client.zero_trust.casb.posture.asset_schemas.with_raw_response.get( + asset_class="", + account_id="46148281d8a93d002ef242d8b0d5f9f6", + ) + + +class TestAsyncAssetSchemas: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @parametrize + async def test_method_list(self, async_client: AsyncCloudflare) -> None: + asset_schema = await async_client.zero_trust.casb.posture.asset_schemas.list( + account_id="46148281d8a93d002ef242d8b0d5f9f6", + ) + assert_matches_type(AsyncSinglePage[AssetSchemaListResponse], asset_schema, path=["response"]) + + @parametrize + async def test_method_list_with_all_params(self, async_client: AsyncCloudflare) -> None: + asset_schema = await async_client.zero_trust.casb.posture.asset_schemas.list( + account_id="46148281d8a93d002ef242d8b0d5f9f6", + vendor="ANTHROPIC", + ) + assert_matches_type(AsyncSinglePage[AssetSchemaListResponse], asset_schema, path=["response"]) + + @parametrize + async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.casb.posture.asset_schemas.with_raw_response.list( + account_id="46148281d8a93d002ef242d8b0d5f9f6", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + asset_schema = await response.parse() + assert_matches_type(AsyncSinglePage[AssetSchemaListResponse], asset_schema, path=["response"]) + + @parametrize + async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.casb.posture.asset_schemas.with_streaming_response.list( + account_id="46148281d8a93d002ef242d8b0d5f9f6", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + asset_schema = await response.parse() + assert_matches_type(AsyncSinglePage[AssetSchemaListResponse], asset_schema, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_list(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.casb.posture.asset_schemas.with_raw_response.list( + account_id="", + ) + + @parametrize + async def test_method_get(self, async_client: AsyncCloudflare) -> None: + asset_schema = await async_client.zero_trust.casb.posture.asset_schemas.get( + asset_class="AnthropicApiKey", + account_id="46148281d8a93d002ef242d8b0d5f9f6", + ) + assert_matches_type(Optional[AssetSchemaGetResponse], asset_schema, path=["response"]) + + @parametrize + async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.casb.posture.asset_schemas.with_raw_response.get( + asset_class="AnthropicApiKey", + account_id="46148281d8a93d002ef242d8b0d5f9f6", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + asset_schema = await response.parse() + assert_matches_type(Optional[AssetSchemaGetResponse], asset_schema, path=["response"]) + + @parametrize + async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.casb.posture.asset_schemas.with_streaming_response.get( + asset_class="AnthropicApiKey", + account_id="46148281d8a93d002ef242d8b0d5f9f6", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + asset_schema = await response.parse() + assert_matches_type(Optional[AssetSchemaGetResponse], asset_schema, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_get(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.casb.posture.asset_schemas.with_raw_response.get( + asset_class="AnthropicApiKey", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `asset_class` but received ''"): + await async_client.zero_trust.casb.posture.asset_schemas.with_raw_response.get( + asset_class="", + account_id="46148281d8a93d002ef242d8b0d5f9f6", + ) diff --git a/tests/api_resources/zero_trust/casb/posture/test_finding_types.py b/tests/api_resources/zero_trust/casb/posture/test_finding_types.py index 16b50ec4144..b9fd4c638fa 100644 --- a/tests/api_resources/zero_trust/casb/posture/test_finding_types.py +++ b/tests/api_resources/zero_trust/casb/posture/test_finding_types.py @@ -9,10 +9,14 @@ from cloudflare import Cloudflare, AsyncCloudflare from tests.utils import assert_matches_type +from cloudflare._utils import parse_datetime from cloudflare.pagination import SyncV4PagePaginationArray, AsyncV4PagePaginationArray from cloudflare.types.zero_trust.casb.posture import ( FindingTypeGetResponse, FindingTypeListResponse, + FindingTypeCreateResponse, + FindingTypeUpdateResponse, + FindingTypeValidateResponse, ) base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") @@ -21,6 +25,153 @@ class TestFindingTypes: parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + @parametrize + def test_method_create(self, client: Cloudflare) -> None: + finding_type = client.zero_trust.casb.posture.finding_types.create( + account_id="46148281d8a93d002ef242d8b0d5f9f6", + applies_to_all_integrations=True, + asset_class="GoogleWorkspaceFile", + asset_vendor="GOOGLE_WORKSPACE", + description="Detects files shared with too many users", + expression='default result := "pass"\n\nresult := "fail" if input.asset.publicLinkDisabled == false\n', + name="Excessive File Sharing", + severity="High", + ) + assert_matches_type(Optional[FindingTypeCreateResponse], finding_type, path=["response"]) + + @parametrize + def test_method_create_with_all_params(self, client: Cloudflare) -> None: + finding_type = client.zero_trust.casb.posture.finding_types.create( + account_id="46148281d8a93d002ef242d8b0d5f9f6", + applies_to_all_integrations=True, + asset_class="GoogleWorkspaceFile", + asset_vendor="GOOGLE_WORKSPACE", + description="Detects files shared with too many users", + expression='default result := "pass"\n\nresult := "fail" if input.asset.publicLinkDisabled == false\n', + name="Excessive File Sharing", + severity="High", + integration_ids=["550e8400-e29b-41d4-a716-446655440000"], + ) + assert_matches_type(Optional[FindingTypeCreateResponse], finding_type, path=["response"]) + + @parametrize + def test_raw_response_create(self, client: Cloudflare) -> None: + response = client.zero_trust.casb.posture.finding_types.with_raw_response.create( + account_id="46148281d8a93d002ef242d8b0d5f9f6", + applies_to_all_integrations=True, + asset_class="GoogleWorkspaceFile", + asset_vendor="GOOGLE_WORKSPACE", + description="Detects files shared with too many users", + expression='default result := "pass"\n\nresult := "fail" if input.asset.publicLinkDisabled == false\n', + name="Excessive File Sharing", + severity="High", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + finding_type = response.parse() + assert_matches_type(Optional[FindingTypeCreateResponse], finding_type, path=["response"]) + + @parametrize + def test_streaming_response_create(self, client: Cloudflare) -> None: + with client.zero_trust.casb.posture.finding_types.with_streaming_response.create( + account_id="46148281d8a93d002ef242d8b0d5f9f6", + applies_to_all_integrations=True, + asset_class="GoogleWorkspaceFile", + asset_vendor="GOOGLE_WORKSPACE", + description="Detects files shared with too many users", + expression='default result := "pass"\n\nresult := "fail" if input.asset.publicLinkDisabled == false\n', + name="Excessive File Sharing", + severity="High", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + finding_type = response.parse() + assert_matches_type(Optional[FindingTypeCreateResponse], finding_type, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_create(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.casb.posture.finding_types.with_raw_response.create( + account_id="", + applies_to_all_integrations=True, + asset_class="GoogleWorkspaceFile", + asset_vendor="GOOGLE_WORKSPACE", + description="Detects files shared with too many users", + expression='default result := "pass"\n\nresult := "fail" if input.asset.publicLinkDisabled == false\n', + name="Excessive File Sharing", + severity="High", + ) + + @parametrize + def test_method_update(self, client: Cloudflare) -> None: + finding_type = client.zero_trust.casb.posture.finding_types.update( + finding_type_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="46148281d8a93d002ef242d8b0d5f9f6", + applies_to_all_integrations=True, + ) + assert_matches_type(Optional[FindingTypeUpdateResponse], finding_type, path=["response"]) + + @parametrize + def test_method_update_with_all_params(self, client: Cloudflare) -> None: + finding_type = client.zero_trust.casb.posture.finding_types.update( + finding_type_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="46148281d8a93d002ef242d8b0d5f9f6", + applies_to_all_integrations=True, + description="Detects files shared with too many users", + integration_ids=["550e8400-e29b-41d4-a716-446655440000"], + name="Excessive File Sharing", + severity="High", + ) + assert_matches_type(Optional[FindingTypeUpdateResponse], finding_type, path=["response"]) + + @parametrize + def test_raw_response_update(self, client: Cloudflare) -> None: + response = client.zero_trust.casb.posture.finding_types.with_raw_response.update( + finding_type_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="46148281d8a93d002ef242d8b0d5f9f6", + applies_to_all_integrations=True, + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + finding_type = response.parse() + assert_matches_type(Optional[FindingTypeUpdateResponse], finding_type, path=["response"]) + + @parametrize + def test_streaming_response_update(self, client: Cloudflare) -> None: + with client.zero_trust.casb.posture.finding_types.with_streaming_response.update( + finding_type_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="46148281d8a93d002ef242d8b0d5f9f6", + applies_to_all_integrations=True, + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + finding_type = response.parse() + assert_matches_type(Optional[FindingTypeUpdateResponse], finding_type, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_update(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.casb.posture.finding_types.with_raw_response.update( + finding_type_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + applies_to_all_integrations=True, + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `finding_type_id` but received ''"): + client.zero_trust.casb.posture.finding_types.with_raw_response.update( + finding_type_id="", + account_id="46148281d8a93d002ef242d8b0d5f9f6", + applies_to_all_integrations=True, + ) + @parametrize def test_method_list(self, client: Cloudflare) -> None: finding_type = client.zero_trust.casb.posture.finding_types.list( @@ -32,9 +183,17 @@ def test_method_list(self, client: Cloudflare) -> None: def test_method_list_with_all_params(self, client: Cloudflare) -> None: finding_type = client.zero_trust.casb.posture.finding_types.list( account_id="46148281d8a93d002ef242d8b0d5f9f6", + direction="asc", + max_updated_at=parse_datetime("2019-12-27T18:11:19.117Z"), + min_updated_at=parse_datetime("2019-12-27T18:11:19.117Z"), + order="created", + origins=["system"], page=0, per_page=0, + quarantined=True, search="search", + severities=["high"], + types=["Content"], vendors=["GOOGLE_WORKSPACE"], ) assert_matches_type(SyncV4PagePaginationArray[FindingTypeListResponse], finding_type, path=["response"]) @@ -70,6 +229,54 @@ def test_path_params_list(self, client: Cloudflare) -> None: account_id="", ) + @parametrize + def test_method_delete(self, client: Cloudflare) -> None: + finding_type = client.zero_trust.casb.posture.finding_types.delete( + finding_type_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="46148281d8a93d002ef242d8b0d5f9f6", + ) + assert finding_type is None + + @parametrize + def test_raw_response_delete(self, client: Cloudflare) -> None: + response = client.zero_trust.casb.posture.finding_types.with_raw_response.delete( + finding_type_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="46148281d8a93d002ef242d8b0d5f9f6", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + finding_type = response.parse() + assert finding_type is None + + @parametrize + def test_streaming_response_delete(self, client: Cloudflare) -> None: + with client.zero_trust.casb.posture.finding_types.with_streaming_response.delete( + finding_type_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="46148281d8a93d002ef242d8b0d5f9f6", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + finding_type = response.parse() + assert finding_type is None + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_delete(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.casb.posture.finding_types.with_raw_response.delete( + finding_type_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `finding_type_id` but received ''"): + client.zero_trust.casb.posture.finding_types.with_raw_response.delete( + finding_type_id="", + account_id="46148281d8a93d002ef242d8b0d5f9f6", + ) + @parametrize def test_method_get(self, client: Cloudflare) -> None: finding_type = client.zero_trust.casb.posture.finding_types.get( @@ -118,12 +325,240 @@ def test_path_params_get(self, client: Cloudflare) -> None: account_id="46148281d8a93d002ef242d8b0d5f9f6", ) + @parametrize + def test_method_validate(self, client: Cloudflare) -> None: + finding_type = client.zero_trust.casb.posture.finding_types.validate( + account_id="46148281d8a93d002ef242d8b0d5f9f6", + applies_to_all_integrations=True, + asset_class="GoogleWorkspaceFile", + asset_vendor="GOOGLE_WORKSPACE", + description="Detects files shared with too many users", + expression='default result := "pass"\n\nresult := "fail" if input.asset.publicLinkDisabled == false\n', + name="Excessive File Sharing", + severity="High", + ) + assert_matches_type(Optional[FindingTypeValidateResponse], finding_type, path=["response"]) + + @parametrize + def test_method_validate_with_all_params(self, client: Cloudflare) -> None: + finding_type = client.zero_trust.casb.posture.finding_types.validate( + account_id="46148281d8a93d002ef242d8b0d5f9f6", + applies_to_all_integrations=True, + asset_class="GoogleWorkspaceFile", + asset_vendor="GOOGLE_WORKSPACE", + description="Detects files shared with too many users", + expression='default result := "pass"\n\nresult := "fail" if input.asset.publicLinkDisabled == false\n', + name="Excessive File Sharing", + severity="High", + integration_ids=["550e8400-e29b-41d4-a716-446655440000"], + ) + assert_matches_type(Optional[FindingTypeValidateResponse], finding_type, path=["response"]) + + @parametrize + def test_raw_response_validate(self, client: Cloudflare) -> None: + response = client.zero_trust.casb.posture.finding_types.with_raw_response.validate( + account_id="46148281d8a93d002ef242d8b0d5f9f6", + applies_to_all_integrations=True, + asset_class="GoogleWorkspaceFile", + asset_vendor="GOOGLE_WORKSPACE", + description="Detects files shared with too many users", + expression='default result := "pass"\n\nresult := "fail" if input.asset.publicLinkDisabled == false\n', + name="Excessive File Sharing", + severity="High", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + finding_type = response.parse() + assert_matches_type(Optional[FindingTypeValidateResponse], finding_type, path=["response"]) + + @parametrize + def test_streaming_response_validate(self, client: Cloudflare) -> None: + with client.zero_trust.casb.posture.finding_types.with_streaming_response.validate( + account_id="46148281d8a93d002ef242d8b0d5f9f6", + applies_to_all_integrations=True, + asset_class="GoogleWorkspaceFile", + asset_vendor="GOOGLE_WORKSPACE", + description="Detects files shared with too many users", + expression='default result := "pass"\n\nresult := "fail" if input.asset.publicLinkDisabled == false\n', + name="Excessive File Sharing", + severity="High", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + finding_type = response.parse() + assert_matches_type(Optional[FindingTypeValidateResponse], finding_type, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_validate(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.casb.posture.finding_types.with_raw_response.validate( + account_id="", + applies_to_all_integrations=True, + asset_class="GoogleWorkspaceFile", + asset_vendor="GOOGLE_WORKSPACE", + description="Detects files shared with too many users", + expression='default result := "pass"\n\nresult := "fail" if input.asset.publicLinkDisabled == false\n', + name="Excessive File Sharing", + severity="High", + ) + class TestAsyncFindingTypes: parametrize = pytest.mark.parametrize( "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] ) + @parametrize + async def test_method_create(self, async_client: AsyncCloudflare) -> None: + finding_type = await async_client.zero_trust.casb.posture.finding_types.create( + account_id="46148281d8a93d002ef242d8b0d5f9f6", + applies_to_all_integrations=True, + asset_class="GoogleWorkspaceFile", + asset_vendor="GOOGLE_WORKSPACE", + description="Detects files shared with too many users", + expression='default result := "pass"\n\nresult := "fail" if input.asset.publicLinkDisabled == false\n', + name="Excessive File Sharing", + severity="High", + ) + assert_matches_type(Optional[FindingTypeCreateResponse], finding_type, path=["response"]) + + @parametrize + async def test_method_create_with_all_params(self, async_client: AsyncCloudflare) -> None: + finding_type = await async_client.zero_trust.casb.posture.finding_types.create( + account_id="46148281d8a93d002ef242d8b0d5f9f6", + applies_to_all_integrations=True, + asset_class="GoogleWorkspaceFile", + asset_vendor="GOOGLE_WORKSPACE", + description="Detects files shared with too many users", + expression='default result := "pass"\n\nresult := "fail" if input.asset.publicLinkDisabled == false\n', + name="Excessive File Sharing", + severity="High", + integration_ids=["550e8400-e29b-41d4-a716-446655440000"], + ) + assert_matches_type(Optional[FindingTypeCreateResponse], finding_type, path=["response"]) + + @parametrize + async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.casb.posture.finding_types.with_raw_response.create( + account_id="46148281d8a93d002ef242d8b0d5f9f6", + applies_to_all_integrations=True, + asset_class="GoogleWorkspaceFile", + asset_vendor="GOOGLE_WORKSPACE", + description="Detects files shared with too many users", + expression='default result := "pass"\n\nresult := "fail" if input.asset.publicLinkDisabled == false\n', + name="Excessive File Sharing", + severity="High", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + finding_type = await response.parse() + assert_matches_type(Optional[FindingTypeCreateResponse], finding_type, path=["response"]) + + @parametrize + async def test_streaming_response_create(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.casb.posture.finding_types.with_streaming_response.create( + account_id="46148281d8a93d002ef242d8b0d5f9f6", + applies_to_all_integrations=True, + asset_class="GoogleWorkspaceFile", + asset_vendor="GOOGLE_WORKSPACE", + description="Detects files shared with too many users", + expression='default result := "pass"\n\nresult := "fail" if input.asset.publicLinkDisabled == false\n', + name="Excessive File Sharing", + severity="High", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + finding_type = await response.parse() + assert_matches_type(Optional[FindingTypeCreateResponse], finding_type, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_create(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.casb.posture.finding_types.with_raw_response.create( + account_id="", + applies_to_all_integrations=True, + asset_class="GoogleWorkspaceFile", + asset_vendor="GOOGLE_WORKSPACE", + description="Detects files shared with too many users", + expression='default result := "pass"\n\nresult := "fail" if input.asset.publicLinkDisabled == false\n', + name="Excessive File Sharing", + severity="High", + ) + + @parametrize + async def test_method_update(self, async_client: AsyncCloudflare) -> None: + finding_type = await async_client.zero_trust.casb.posture.finding_types.update( + finding_type_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="46148281d8a93d002ef242d8b0d5f9f6", + applies_to_all_integrations=True, + ) + assert_matches_type(Optional[FindingTypeUpdateResponse], finding_type, path=["response"]) + + @parametrize + async def test_method_update_with_all_params(self, async_client: AsyncCloudflare) -> None: + finding_type = await async_client.zero_trust.casb.posture.finding_types.update( + finding_type_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="46148281d8a93d002ef242d8b0d5f9f6", + applies_to_all_integrations=True, + description="Detects files shared with too many users", + integration_ids=["550e8400-e29b-41d4-a716-446655440000"], + name="Excessive File Sharing", + severity="High", + ) + assert_matches_type(Optional[FindingTypeUpdateResponse], finding_type, path=["response"]) + + @parametrize + async def test_raw_response_update(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.casb.posture.finding_types.with_raw_response.update( + finding_type_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="46148281d8a93d002ef242d8b0d5f9f6", + applies_to_all_integrations=True, + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + finding_type = await response.parse() + assert_matches_type(Optional[FindingTypeUpdateResponse], finding_type, path=["response"]) + + @parametrize + async def test_streaming_response_update(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.casb.posture.finding_types.with_streaming_response.update( + finding_type_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="46148281d8a93d002ef242d8b0d5f9f6", + applies_to_all_integrations=True, + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + finding_type = await response.parse() + assert_matches_type(Optional[FindingTypeUpdateResponse], finding_type, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_update(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.casb.posture.finding_types.with_raw_response.update( + finding_type_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + applies_to_all_integrations=True, + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `finding_type_id` but received ''"): + await async_client.zero_trust.casb.posture.finding_types.with_raw_response.update( + finding_type_id="", + account_id="46148281d8a93d002ef242d8b0d5f9f6", + applies_to_all_integrations=True, + ) + @parametrize async def test_method_list(self, async_client: AsyncCloudflare) -> None: finding_type = await async_client.zero_trust.casb.posture.finding_types.list( @@ -135,9 +570,17 @@ async def test_method_list(self, async_client: AsyncCloudflare) -> None: async def test_method_list_with_all_params(self, async_client: AsyncCloudflare) -> None: finding_type = await async_client.zero_trust.casb.posture.finding_types.list( account_id="46148281d8a93d002ef242d8b0d5f9f6", + direction="asc", + max_updated_at=parse_datetime("2019-12-27T18:11:19.117Z"), + min_updated_at=parse_datetime("2019-12-27T18:11:19.117Z"), + order="created", + origins=["system"], page=0, per_page=0, + quarantined=True, search="search", + severities=["high"], + types=["Content"], vendors=["GOOGLE_WORKSPACE"], ) assert_matches_type(AsyncV4PagePaginationArray[FindingTypeListResponse], finding_type, path=["response"]) @@ -173,6 +616,54 @@ async def test_path_params_list(self, async_client: AsyncCloudflare) -> None: account_id="", ) + @parametrize + async def test_method_delete(self, async_client: AsyncCloudflare) -> None: + finding_type = await async_client.zero_trust.casb.posture.finding_types.delete( + finding_type_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="46148281d8a93d002ef242d8b0d5f9f6", + ) + assert finding_type is None + + @parametrize + async def test_raw_response_delete(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.casb.posture.finding_types.with_raw_response.delete( + finding_type_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="46148281d8a93d002ef242d8b0d5f9f6", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + finding_type = await response.parse() + assert finding_type is None + + @parametrize + async def test_streaming_response_delete(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.casb.posture.finding_types.with_streaming_response.delete( + finding_type_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="46148281d8a93d002ef242d8b0d5f9f6", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + finding_type = await response.parse() + assert finding_type is None + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_delete(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.casb.posture.finding_types.with_raw_response.delete( + finding_type_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `finding_type_id` but received ''"): + await async_client.zero_trust.casb.posture.finding_types.with_raw_response.delete( + finding_type_id="", + account_id="46148281d8a93d002ef242d8b0d5f9f6", + ) + @parametrize async def test_method_get(self, async_client: AsyncCloudflare) -> None: finding_type = await async_client.zero_trust.casb.posture.finding_types.get( @@ -220,3 +711,84 @@ async def test_path_params_get(self, async_client: AsyncCloudflare) -> None: finding_type_id="", account_id="46148281d8a93d002ef242d8b0d5f9f6", ) + + @parametrize + async def test_method_validate(self, async_client: AsyncCloudflare) -> None: + finding_type = await async_client.zero_trust.casb.posture.finding_types.validate( + account_id="46148281d8a93d002ef242d8b0d5f9f6", + applies_to_all_integrations=True, + asset_class="GoogleWorkspaceFile", + asset_vendor="GOOGLE_WORKSPACE", + description="Detects files shared with too many users", + expression='default result := "pass"\n\nresult := "fail" if input.asset.publicLinkDisabled == false\n', + name="Excessive File Sharing", + severity="High", + ) + assert_matches_type(Optional[FindingTypeValidateResponse], finding_type, path=["response"]) + + @parametrize + async def test_method_validate_with_all_params(self, async_client: AsyncCloudflare) -> None: + finding_type = await async_client.zero_trust.casb.posture.finding_types.validate( + account_id="46148281d8a93d002ef242d8b0d5f9f6", + applies_to_all_integrations=True, + asset_class="GoogleWorkspaceFile", + asset_vendor="GOOGLE_WORKSPACE", + description="Detects files shared with too many users", + expression='default result := "pass"\n\nresult := "fail" if input.asset.publicLinkDisabled == false\n', + name="Excessive File Sharing", + severity="High", + integration_ids=["550e8400-e29b-41d4-a716-446655440000"], + ) + assert_matches_type(Optional[FindingTypeValidateResponse], finding_type, path=["response"]) + + @parametrize + async def test_raw_response_validate(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.casb.posture.finding_types.with_raw_response.validate( + account_id="46148281d8a93d002ef242d8b0d5f9f6", + applies_to_all_integrations=True, + asset_class="GoogleWorkspaceFile", + asset_vendor="GOOGLE_WORKSPACE", + description="Detects files shared with too many users", + expression='default result := "pass"\n\nresult := "fail" if input.asset.publicLinkDisabled == false\n', + name="Excessive File Sharing", + severity="High", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + finding_type = await response.parse() + assert_matches_type(Optional[FindingTypeValidateResponse], finding_type, path=["response"]) + + @parametrize + async def test_streaming_response_validate(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.casb.posture.finding_types.with_streaming_response.validate( + account_id="46148281d8a93d002ef242d8b0d5f9f6", + applies_to_all_integrations=True, + asset_class="GoogleWorkspaceFile", + asset_vendor="GOOGLE_WORKSPACE", + description="Detects files shared with too many users", + expression='default result := "pass"\n\nresult := "fail" if input.asset.publicLinkDisabled == false\n', + name="Excessive File Sharing", + severity="High", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + finding_type = await response.parse() + assert_matches_type(Optional[FindingTypeValidateResponse], finding_type, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_validate(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.casb.posture.finding_types.with_raw_response.validate( + account_id="", + applies_to_all_integrations=True, + asset_class="GoogleWorkspaceFile", + asset_vendor="GOOGLE_WORKSPACE", + description="Detects files shared with too many users", + expression='default result := "pass"\n\nresult := "fail" if input.asset.publicLinkDisabled == false\n', + name="Excessive File Sharing", + severity="High", + ) diff --git a/tests/api_resources/zero_trust/casb/posture/test_webhooks.py b/tests/api_resources/zero_trust/casb/posture/test_webhooks.py index 1166ff2bc76..f102aeaad2a 100644 --- a/tests/api_resources/zero_trust/casb/posture/test_webhooks.py +++ b/tests/api_resources/zero_trust/casb/posture/test_webhooks.py @@ -30,7 +30,7 @@ class TestWebhooks: def test_method_create(self, client: Cloudflare) -> None: webhook = client.zero_trust.casb.posture.webhooks.create( account_id="46148281d8a93d002ef242d8b0d5f9f6", - authentication_type="Bearer Auth", + authentication_type="HMAC-Signing", destination_url="https://example.com/webhook", label="Send to Slack", ) @@ -40,18 +40,14 @@ def test_method_create(self, client: Cloudflare) -> None: def test_method_create_with_all_params(self, client: Cloudflare) -> None: webhook = client.zero_trust.casb.posture.webhooks.create( account_id="46148281d8a93d002ef242d8b0d5f9f6", - authentication_type="Bearer Auth", + authentication_type="HMAC-Signing", destination_url="https://example.com/webhook", label="Send to Slack", headers=[ - { - "key": "Authorization", - "value": "Bearer token123", - }, { "key": "X-Custom-Header", "value": "value", - }, + } ], signing_secret="my-secret-key", status="enabled", @@ -62,7 +58,7 @@ def test_method_create_with_all_params(self, client: Cloudflare) -> None: def test_raw_response_create(self, client: Cloudflare) -> None: response = client.zero_trust.casb.posture.webhooks.with_raw_response.create( account_id="46148281d8a93d002ef242d8b0d5f9f6", - authentication_type="Bearer Auth", + authentication_type="HMAC-Signing", destination_url="https://example.com/webhook", label="Send to Slack", ) @@ -76,7 +72,7 @@ def test_raw_response_create(self, client: Cloudflare) -> None: def test_streaming_response_create(self, client: Cloudflare) -> None: with client.zero_trust.casb.posture.webhooks.with_streaming_response.create( account_id="46148281d8a93d002ef242d8b0d5f9f6", - authentication_type="Bearer Auth", + authentication_type="HMAC-Signing", destination_url="https://example.com/webhook", label="Send to Slack", ) as response: @@ -93,7 +89,7 @@ def test_path_params_create(self, client: Cloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): client.zero_trust.casb.posture.webhooks.with_raw_response.create( account_id="", - authentication_type="Bearer Auth", + authentication_type="HMAC-Signing", destination_url="https://example.com/webhook", label="Send to Slack", ) @@ -103,7 +99,7 @@ def test_method_update(self, client: Cloudflare) -> None: webhook = client.zero_trust.casb.posture.webhooks.update( webhook_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", account_id="46148281d8a93d002ef242d8b0d5f9f6", - authentication_type="Bearer Auth", + authentication_type="HMAC-Signing", destination_url="https://example.com/webhook", label="Send to Slack", status="enabled", @@ -115,19 +111,15 @@ def test_method_update_with_all_params(self, client: Cloudflare) -> None: webhook = client.zero_trust.casb.posture.webhooks.update( webhook_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", account_id="46148281d8a93d002ef242d8b0d5f9f6", - authentication_type="Bearer Auth", + authentication_type="HMAC-Signing", destination_url="https://example.com/webhook", label="Send to Slack", status="enabled", headers=[ - { - "key": "Authorization", - "value": "Bearer token123", - }, { "key": "X-Custom-Header", "value": "value", - }, + } ], signing_secret="my-secret-key", ) @@ -138,7 +130,7 @@ def test_raw_response_update(self, client: Cloudflare) -> None: response = client.zero_trust.casb.posture.webhooks.with_raw_response.update( webhook_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", account_id="46148281d8a93d002ef242d8b0d5f9f6", - authentication_type="Bearer Auth", + authentication_type="HMAC-Signing", destination_url="https://example.com/webhook", label="Send to Slack", status="enabled", @@ -154,7 +146,7 @@ def test_streaming_response_update(self, client: Cloudflare) -> None: with client.zero_trust.casb.posture.webhooks.with_streaming_response.update( webhook_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", account_id="46148281d8a93d002ef242d8b0d5f9f6", - authentication_type="Bearer Auth", + authentication_type="HMAC-Signing", destination_url="https://example.com/webhook", label="Send to Slack", status="enabled", @@ -173,7 +165,7 @@ def test_path_params_update(self, client: Cloudflare) -> None: client.zero_trust.casb.posture.webhooks.with_raw_response.update( webhook_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", account_id="", - authentication_type="Bearer Auth", + authentication_type="HMAC-Signing", destination_url="https://example.com/webhook", label="Send to Slack", status="enabled", @@ -183,7 +175,7 @@ def test_path_params_update(self, client: Cloudflare) -> None: client.zero_trust.casb.posture.webhooks.with_raw_response.update( webhook_id="", account_id="46148281d8a93d002ef242d8b0d5f9f6", - authentication_type="Bearer Auth", + authentication_type="HMAC-Signing", destination_url="https://example.com/webhook", label="Send to Slack", status="enabled", @@ -279,7 +271,7 @@ def test_path_params_delete(self, client: Cloudflare) -> None: def test_method_evaluate(self, client: Cloudflare) -> None: webhook = client.zero_trust.casb.posture.webhooks.evaluate( account_id="46148281d8a93d002ef242d8b0d5f9f6", - authentication_type="Bearer Auth", + authentication_type="HMAC-Signing", destination_url="https://example.com/webhook", ) assert_matches_type(Optional[WebhookEvaluateResponse], webhook, path=["response"]) @@ -288,17 +280,13 @@ def test_method_evaluate(self, client: Cloudflare) -> None: def test_method_evaluate_with_all_params(self, client: Cloudflare) -> None: webhook = client.zero_trust.casb.posture.webhooks.evaluate( account_id="46148281d8a93d002ef242d8b0d5f9f6", - authentication_type="Bearer Auth", + authentication_type="HMAC-Signing", destination_url="https://example.com/webhook", headers=[ - { - "key": "Authorization", - "value": "Bearer token123", - }, { "key": "X-Custom-Header", "value": "value", - }, + } ], signing_secret="my-secret-key", ) @@ -308,7 +296,7 @@ def test_method_evaluate_with_all_params(self, client: Cloudflare) -> None: def test_raw_response_evaluate(self, client: Cloudflare) -> None: response = client.zero_trust.casb.posture.webhooks.with_raw_response.evaluate( account_id="46148281d8a93d002ef242d8b0d5f9f6", - authentication_type="Bearer Auth", + authentication_type="HMAC-Signing", destination_url="https://example.com/webhook", ) @@ -321,7 +309,7 @@ def test_raw_response_evaluate(self, client: Cloudflare) -> None: def test_streaming_response_evaluate(self, client: Cloudflare) -> None: with client.zero_trust.casb.posture.webhooks.with_streaming_response.evaluate( account_id="46148281d8a93d002ef242d8b0d5f9f6", - authentication_type="Bearer Auth", + authentication_type="HMAC-Signing", destination_url="https://example.com/webhook", ) as response: assert not response.is_closed @@ -337,7 +325,7 @@ def test_path_params_evaluate(self, client: Cloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): client.zero_trust.casb.posture.webhooks.with_raw_response.evaluate( account_id="", - authentication_type="Bearer Auth", + authentication_type="HMAC-Signing", destination_url="https://example.com/webhook", ) @@ -447,7 +435,7 @@ class TestAsyncWebhooks: async def test_method_create(self, async_client: AsyncCloudflare) -> None: webhook = await async_client.zero_trust.casb.posture.webhooks.create( account_id="46148281d8a93d002ef242d8b0d5f9f6", - authentication_type="Bearer Auth", + authentication_type="HMAC-Signing", destination_url="https://example.com/webhook", label="Send to Slack", ) @@ -457,18 +445,14 @@ async def test_method_create(self, async_client: AsyncCloudflare) -> None: async def test_method_create_with_all_params(self, async_client: AsyncCloudflare) -> None: webhook = await async_client.zero_trust.casb.posture.webhooks.create( account_id="46148281d8a93d002ef242d8b0d5f9f6", - authentication_type="Bearer Auth", + authentication_type="HMAC-Signing", destination_url="https://example.com/webhook", label="Send to Slack", headers=[ - { - "key": "Authorization", - "value": "Bearer token123", - }, { "key": "X-Custom-Header", "value": "value", - }, + } ], signing_secret="my-secret-key", status="enabled", @@ -479,7 +463,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncCloudflare async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None: response = await async_client.zero_trust.casb.posture.webhooks.with_raw_response.create( account_id="46148281d8a93d002ef242d8b0d5f9f6", - authentication_type="Bearer Auth", + authentication_type="HMAC-Signing", destination_url="https://example.com/webhook", label="Send to Slack", ) @@ -493,7 +477,7 @@ async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None: async def test_streaming_response_create(self, async_client: AsyncCloudflare) -> None: async with async_client.zero_trust.casb.posture.webhooks.with_streaming_response.create( account_id="46148281d8a93d002ef242d8b0d5f9f6", - authentication_type="Bearer Auth", + authentication_type="HMAC-Signing", destination_url="https://example.com/webhook", label="Send to Slack", ) as response: @@ -510,7 +494,7 @@ async def test_path_params_create(self, async_client: AsyncCloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): await async_client.zero_trust.casb.posture.webhooks.with_raw_response.create( account_id="", - authentication_type="Bearer Auth", + authentication_type="HMAC-Signing", destination_url="https://example.com/webhook", label="Send to Slack", ) @@ -520,7 +504,7 @@ async def test_method_update(self, async_client: AsyncCloudflare) -> None: webhook = await async_client.zero_trust.casb.posture.webhooks.update( webhook_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", account_id="46148281d8a93d002ef242d8b0d5f9f6", - authentication_type="Bearer Auth", + authentication_type="HMAC-Signing", destination_url="https://example.com/webhook", label="Send to Slack", status="enabled", @@ -532,19 +516,15 @@ async def test_method_update_with_all_params(self, async_client: AsyncCloudflare webhook = await async_client.zero_trust.casb.posture.webhooks.update( webhook_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", account_id="46148281d8a93d002ef242d8b0d5f9f6", - authentication_type="Bearer Auth", + authentication_type="HMAC-Signing", destination_url="https://example.com/webhook", label="Send to Slack", status="enabled", headers=[ - { - "key": "Authorization", - "value": "Bearer token123", - }, { "key": "X-Custom-Header", "value": "value", - }, + } ], signing_secret="my-secret-key", ) @@ -555,7 +535,7 @@ async def test_raw_response_update(self, async_client: AsyncCloudflare) -> None: response = await async_client.zero_trust.casb.posture.webhooks.with_raw_response.update( webhook_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", account_id="46148281d8a93d002ef242d8b0d5f9f6", - authentication_type="Bearer Auth", + authentication_type="HMAC-Signing", destination_url="https://example.com/webhook", label="Send to Slack", status="enabled", @@ -571,7 +551,7 @@ async def test_streaming_response_update(self, async_client: AsyncCloudflare) -> async with async_client.zero_trust.casb.posture.webhooks.with_streaming_response.update( webhook_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", account_id="46148281d8a93d002ef242d8b0d5f9f6", - authentication_type="Bearer Auth", + authentication_type="HMAC-Signing", destination_url="https://example.com/webhook", label="Send to Slack", status="enabled", @@ -590,7 +570,7 @@ async def test_path_params_update(self, async_client: AsyncCloudflare) -> None: await async_client.zero_trust.casb.posture.webhooks.with_raw_response.update( webhook_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", account_id="", - authentication_type="Bearer Auth", + authentication_type="HMAC-Signing", destination_url="https://example.com/webhook", label="Send to Slack", status="enabled", @@ -600,7 +580,7 @@ async def test_path_params_update(self, async_client: AsyncCloudflare) -> None: await async_client.zero_trust.casb.posture.webhooks.with_raw_response.update( webhook_id="", account_id="46148281d8a93d002ef242d8b0d5f9f6", - authentication_type="Bearer Auth", + authentication_type="HMAC-Signing", destination_url="https://example.com/webhook", label="Send to Slack", status="enabled", @@ -696,7 +676,7 @@ async def test_path_params_delete(self, async_client: AsyncCloudflare) -> None: async def test_method_evaluate(self, async_client: AsyncCloudflare) -> None: webhook = await async_client.zero_trust.casb.posture.webhooks.evaluate( account_id="46148281d8a93d002ef242d8b0d5f9f6", - authentication_type="Bearer Auth", + authentication_type="HMAC-Signing", destination_url="https://example.com/webhook", ) assert_matches_type(Optional[WebhookEvaluateResponse], webhook, path=["response"]) @@ -705,17 +685,13 @@ async def test_method_evaluate(self, async_client: AsyncCloudflare) -> None: async def test_method_evaluate_with_all_params(self, async_client: AsyncCloudflare) -> None: webhook = await async_client.zero_trust.casb.posture.webhooks.evaluate( account_id="46148281d8a93d002ef242d8b0d5f9f6", - authentication_type="Bearer Auth", + authentication_type="HMAC-Signing", destination_url="https://example.com/webhook", headers=[ - { - "key": "Authorization", - "value": "Bearer token123", - }, { "key": "X-Custom-Header", "value": "value", - }, + } ], signing_secret="my-secret-key", ) @@ -725,7 +701,7 @@ async def test_method_evaluate_with_all_params(self, async_client: AsyncCloudfla async def test_raw_response_evaluate(self, async_client: AsyncCloudflare) -> None: response = await async_client.zero_trust.casb.posture.webhooks.with_raw_response.evaluate( account_id="46148281d8a93d002ef242d8b0d5f9f6", - authentication_type="Bearer Auth", + authentication_type="HMAC-Signing", destination_url="https://example.com/webhook", ) @@ -738,7 +714,7 @@ async def test_raw_response_evaluate(self, async_client: AsyncCloudflare) -> Non async def test_streaming_response_evaluate(self, async_client: AsyncCloudflare) -> None: async with async_client.zero_trust.casb.posture.webhooks.with_streaming_response.evaluate( account_id="46148281d8a93d002ef242d8b0d5f9f6", - authentication_type="Bearer Auth", + authentication_type="HMAC-Signing", destination_url="https://example.com/webhook", ) as response: assert not response.is_closed @@ -754,7 +730,7 @@ async def test_path_params_evaluate(self, async_client: AsyncCloudflare) -> None with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): await async_client.zero_trust.casb.posture.webhooks.with_raw_response.evaluate( account_id="", - authentication_type="Bearer Auth", + authentication_type="HMAC-Signing", destination_url="https://example.com/webhook", ) diff --git a/tests/api_resources/zero_trust/casb/test_integrations.py b/tests/api_resources/zero_trust/casb/test_integrations.py index a2791ddc02d..493c62270ad 100644 --- a/tests/api_resources/zero_trust/casb/test_integrations.py +++ b/tests/api_resources/zero_trust/casb/test_integrations.py @@ -32,6 +32,7 @@ def test_method_create(self, client: Cloudflare) -> None: application="GOOGLE_WORKSPACE", credentials={"admin_email": "bar"}, name="My Google Workspace", + use_cases=["casb", "ces"], ) assert_matches_type(IntegrationCreateResponse, integration, path=["response"]) @@ -42,10 +43,10 @@ def test_method_create_with_all_params(self, client: Cloudflare) -> None: application="GOOGLE_WORKSPACE", credentials={"admin_email": "bar"}, name="My Google Workspace", + use_cases=["casb", "ces"], auth_method="service_account", dlp_profiles=["e91a2360-da51-4fdf-9711-bcdecd462614"], permissions=["https://www.googleapis.com/auth/drive.readonly"], - use_cases=["casb", "ces"], ) assert_matches_type(IntegrationCreateResponse, integration, path=["response"]) @@ -56,6 +57,7 @@ def test_raw_response_create(self, client: Cloudflare) -> None: application="GOOGLE_WORKSPACE", credentials={"admin_email": "bar"}, name="My Google Workspace", + use_cases=["casb", "ces"], ) assert response.is_closed is True @@ -70,6 +72,7 @@ def test_streaming_response_create(self, client: Cloudflare) -> None: application="GOOGLE_WORKSPACE", credentials={"admin_email": "bar"}, name="My Google Workspace", + use_cases=["casb", "ces"], ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -87,6 +90,7 @@ def test_path_params_create(self, client: Cloudflare) -> None: application="GOOGLE_WORKSPACE", credentials={"admin_email": "bar"}, name="My Google Workspace", + use_cases=["casb", "ces"], ) @parametrize @@ -412,6 +416,7 @@ async def test_method_create(self, async_client: AsyncCloudflare) -> None: application="GOOGLE_WORKSPACE", credentials={"admin_email": "bar"}, name="My Google Workspace", + use_cases=["casb", "ces"], ) assert_matches_type(IntegrationCreateResponse, integration, path=["response"]) @@ -422,10 +427,10 @@ async def test_method_create_with_all_params(self, async_client: AsyncCloudflare application="GOOGLE_WORKSPACE", credentials={"admin_email": "bar"}, name="My Google Workspace", + use_cases=["casb", "ces"], auth_method="service_account", dlp_profiles=["e91a2360-da51-4fdf-9711-bcdecd462614"], permissions=["https://www.googleapis.com/auth/drive.readonly"], - use_cases=["casb", "ces"], ) assert_matches_type(IntegrationCreateResponse, integration, path=["response"]) @@ -436,6 +441,7 @@ async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None: application="GOOGLE_WORKSPACE", credentials={"admin_email": "bar"}, name="My Google Workspace", + use_cases=["casb", "ces"], ) assert response.is_closed is True @@ -450,6 +456,7 @@ async def test_streaming_response_create(self, async_client: AsyncCloudflare) -> application="GOOGLE_WORKSPACE", credentials={"admin_email": "bar"}, name="My Google Workspace", + use_cases=["casb", "ces"], ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -467,6 +474,7 @@ async def test_path_params_create(self, async_client: AsyncCloudflare) -> None: application="GOOGLE_WORKSPACE", credentials={"admin_email": "bar"}, name="My Google Workspace", + use_cases=["casb", "ces"], ) @parametrize diff --git a/tests/api_resources/zero_trust/cws/__init__.py b/tests/api_resources/zero_trust/cws/__init__.py new file mode 100644 index 00000000000..fd8019a9a1a --- /dev/null +++ b/tests/api_resources/zero_trust/cws/__init__.py @@ -0,0 +1 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. diff --git a/tests/api_resources/zero_trust/cws/basic_auth_credentials/__init__.py b/tests/api_resources/zero_trust/cws/basic_auth_credentials/__init__.py new file mode 100644 index 00000000000..fd8019a9a1a --- /dev/null +++ b/tests/api_resources/zero_trust/cws/basic_auth_credentials/__init__.py @@ -0,0 +1 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. diff --git a/tests/api_resources/zero_trust/cws/basic_auth_credentials/test_secrets.py b/tests/api_resources/zero_trust/cws/basic_auth_credentials/test_secrets.py new file mode 100644 index 00000000000..fe6c851629d --- /dev/null +++ b/tests/api_resources/zero_trust/cws/basic_auth_credentials/test_secrets.py @@ -0,0 +1,515 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import os +from typing import Any, cast + +import pytest + +from cloudflare import Cloudflare, AsyncCloudflare +from tests.utils import assert_matches_type +from cloudflare._utils import parse_datetime +from cloudflare.pagination import SyncCursorPagination, AsyncCursorPagination +from cloudflare.types.zero_trust.cws.basic_auth_credentials import ( + BasicAuthSecret, + SecretDeleteResponse, +) + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestSecrets: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @parametrize + def test_method_create(self, client: Cloudflare) -> None: + secret = client.zero_trust.cws.basic_auth_credentials.secrets.create( + credential_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + password="x", + ) + assert_matches_type(BasicAuthSecret, secret, path=["response"]) + + @parametrize + def test_method_create_with_all_params(self, client: Cloudflare) -> None: + secret = client.zero_trust.cws.basic_auth_credentials.secrets.create( + credential_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + password="x", + expires_at=parse_datetime("2019-12-27T18:11:19.117Z"), + ) + assert_matches_type(BasicAuthSecret, secret, path=["response"]) + + @parametrize + def test_raw_response_create(self, client: Cloudflare) -> None: + response = client.zero_trust.cws.basic_auth_credentials.secrets.with_raw_response.create( + credential_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + password="x", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + secret = response.parse() + assert_matches_type(BasicAuthSecret, secret, path=["response"]) + + @parametrize + def test_streaming_response_create(self, client: Cloudflare) -> None: + with client.zero_trust.cws.basic_auth_credentials.secrets.with_streaming_response.create( + credential_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + password="x", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + secret = response.parse() + assert_matches_type(BasicAuthSecret, secret, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_create(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.cws.basic_auth_credentials.secrets.with_raw_response.create( + credential_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + password="x", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `credential_id` but received ''"): + client.zero_trust.cws.basic_auth_credentials.secrets.with_raw_response.create( + credential_id="", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + password="x", + ) + + @parametrize + def test_method_list(self, client: Cloudflare) -> None: + secret = client.zero_trust.cws.basic_auth_credentials.secrets.list( + credential_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + assert_matches_type(SyncCursorPagination[BasicAuthSecret], secret, path=["response"]) + + @parametrize + def test_method_list_with_all_params(self, client: Cloudflare) -> None: + secret = client.zero_trust.cws.basic_auth_credentials.secrets.list( + credential_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + cursor="cursor", + direction="asc", + order="created_at", + per_page=1, + ) + assert_matches_type(SyncCursorPagination[BasicAuthSecret], secret, path=["response"]) + + @parametrize + def test_raw_response_list(self, client: Cloudflare) -> None: + response = client.zero_trust.cws.basic_auth_credentials.secrets.with_raw_response.list( + credential_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + secret = response.parse() + assert_matches_type(SyncCursorPagination[BasicAuthSecret], secret, path=["response"]) + + @parametrize + def test_streaming_response_list(self, client: Cloudflare) -> None: + with client.zero_trust.cws.basic_auth_credentials.secrets.with_streaming_response.list( + credential_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + secret = response.parse() + assert_matches_type(SyncCursorPagination[BasicAuthSecret], secret, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_list(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.cws.basic_auth_credentials.secrets.with_raw_response.list( + credential_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `credential_id` but received ''"): + client.zero_trust.cws.basic_auth_credentials.secrets.with_raw_response.list( + credential_id="", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + + @parametrize + def test_method_delete(self, client: Cloudflare) -> None: + secret = client.zero_trust.cws.basic_auth_credentials.secrets.delete( + secret_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + credential_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(SecretDeleteResponse, secret, path=["response"]) + + @parametrize + def test_raw_response_delete(self, client: Cloudflare) -> None: + response = client.zero_trust.cws.basic_auth_credentials.secrets.with_raw_response.delete( + secret_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + credential_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + secret = response.parse() + assert_matches_type(SecretDeleteResponse, secret, path=["response"]) + + @parametrize + def test_streaming_response_delete(self, client: Cloudflare) -> None: + with client.zero_trust.cws.basic_auth_credentials.secrets.with_streaming_response.delete( + secret_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + credential_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + secret = response.parse() + assert_matches_type(SecretDeleteResponse, secret, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_delete(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.cws.basic_auth_credentials.secrets.with_raw_response.delete( + secret_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + credential_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `credential_id` but received ''"): + client.zero_trust.cws.basic_auth_credentials.secrets.with_raw_response.delete( + secret_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + credential_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `secret_id` but received ''"): + client.zero_trust.cws.basic_auth_credentials.secrets.with_raw_response.delete( + secret_id="", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + credential_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + @parametrize + def test_method_get(self, client: Cloudflare) -> None: + secret = client.zero_trust.cws.basic_auth_credentials.secrets.get( + secret_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + credential_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(BasicAuthSecret, secret, path=["response"]) + + @parametrize + def test_raw_response_get(self, client: Cloudflare) -> None: + response = client.zero_trust.cws.basic_auth_credentials.secrets.with_raw_response.get( + secret_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + credential_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + secret = response.parse() + assert_matches_type(BasicAuthSecret, secret, path=["response"]) + + @parametrize + def test_streaming_response_get(self, client: Cloudflare) -> None: + with client.zero_trust.cws.basic_auth_credentials.secrets.with_streaming_response.get( + secret_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + credential_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + secret = response.parse() + assert_matches_type(BasicAuthSecret, secret, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_get(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.cws.basic_auth_credentials.secrets.with_raw_response.get( + secret_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + credential_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `credential_id` but received ''"): + client.zero_trust.cws.basic_auth_credentials.secrets.with_raw_response.get( + secret_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + credential_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `secret_id` but received ''"): + client.zero_trust.cws.basic_auth_credentials.secrets.with_raw_response.get( + secret_id="", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + credential_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + +class TestAsyncSecrets: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @parametrize + async def test_method_create(self, async_client: AsyncCloudflare) -> None: + secret = await async_client.zero_trust.cws.basic_auth_credentials.secrets.create( + credential_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + password="x", + ) + assert_matches_type(BasicAuthSecret, secret, path=["response"]) + + @parametrize + async def test_method_create_with_all_params(self, async_client: AsyncCloudflare) -> None: + secret = await async_client.zero_trust.cws.basic_auth_credentials.secrets.create( + credential_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + password="x", + expires_at=parse_datetime("2019-12-27T18:11:19.117Z"), + ) + assert_matches_type(BasicAuthSecret, secret, path=["response"]) + + @parametrize + async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.cws.basic_auth_credentials.secrets.with_raw_response.create( + credential_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + password="x", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + secret = await response.parse() + assert_matches_type(BasicAuthSecret, secret, path=["response"]) + + @parametrize + async def test_streaming_response_create(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.cws.basic_auth_credentials.secrets.with_streaming_response.create( + credential_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + password="x", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + secret = await response.parse() + assert_matches_type(BasicAuthSecret, secret, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_create(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.cws.basic_auth_credentials.secrets.with_raw_response.create( + credential_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + password="x", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `credential_id` but received ''"): + await async_client.zero_trust.cws.basic_auth_credentials.secrets.with_raw_response.create( + credential_id="", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + password="x", + ) + + @parametrize + async def test_method_list(self, async_client: AsyncCloudflare) -> None: + secret = await async_client.zero_trust.cws.basic_auth_credentials.secrets.list( + credential_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + assert_matches_type(AsyncCursorPagination[BasicAuthSecret], secret, path=["response"]) + + @parametrize + async def test_method_list_with_all_params(self, async_client: AsyncCloudflare) -> None: + secret = await async_client.zero_trust.cws.basic_auth_credentials.secrets.list( + credential_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + cursor="cursor", + direction="asc", + order="created_at", + per_page=1, + ) + assert_matches_type(AsyncCursorPagination[BasicAuthSecret], secret, path=["response"]) + + @parametrize + async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.cws.basic_auth_credentials.secrets.with_raw_response.list( + credential_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + secret = await response.parse() + assert_matches_type(AsyncCursorPagination[BasicAuthSecret], secret, path=["response"]) + + @parametrize + async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.cws.basic_auth_credentials.secrets.with_streaming_response.list( + credential_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + secret = await response.parse() + assert_matches_type(AsyncCursorPagination[BasicAuthSecret], secret, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_list(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.cws.basic_auth_credentials.secrets.with_raw_response.list( + credential_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `credential_id` but received ''"): + await async_client.zero_trust.cws.basic_auth_credentials.secrets.with_raw_response.list( + credential_id="", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + + @parametrize + async def test_method_delete(self, async_client: AsyncCloudflare) -> None: + secret = await async_client.zero_trust.cws.basic_auth_credentials.secrets.delete( + secret_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + credential_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(SecretDeleteResponse, secret, path=["response"]) + + @parametrize + async def test_raw_response_delete(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.cws.basic_auth_credentials.secrets.with_raw_response.delete( + secret_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + credential_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + secret = await response.parse() + assert_matches_type(SecretDeleteResponse, secret, path=["response"]) + + @parametrize + async def test_streaming_response_delete(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.cws.basic_auth_credentials.secrets.with_streaming_response.delete( + secret_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + credential_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + secret = await response.parse() + assert_matches_type(SecretDeleteResponse, secret, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_delete(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.cws.basic_auth_credentials.secrets.with_raw_response.delete( + secret_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + credential_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `credential_id` but received ''"): + await async_client.zero_trust.cws.basic_auth_credentials.secrets.with_raw_response.delete( + secret_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + credential_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `secret_id` but received ''"): + await async_client.zero_trust.cws.basic_auth_credentials.secrets.with_raw_response.delete( + secret_id="", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + credential_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + @parametrize + async def test_method_get(self, async_client: AsyncCloudflare) -> None: + secret = await async_client.zero_trust.cws.basic_auth_credentials.secrets.get( + secret_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + credential_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(BasicAuthSecret, secret, path=["response"]) + + @parametrize + async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.cws.basic_auth_credentials.secrets.with_raw_response.get( + secret_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + credential_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + secret = await response.parse() + assert_matches_type(BasicAuthSecret, secret, path=["response"]) + + @parametrize + async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.cws.basic_auth_credentials.secrets.with_streaming_response.get( + secret_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + credential_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + secret = await response.parse() + assert_matches_type(BasicAuthSecret, secret, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_get(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.cws.basic_auth_credentials.secrets.with_raw_response.get( + secret_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + credential_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `credential_id` but received ''"): + await async_client.zero_trust.cws.basic_auth_credentials.secrets.with_raw_response.get( + secret_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + credential_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `secret_id` but received ''"): + await async_client.zero_trust.cws.basic_auth_credentials.secrets.with_raw_response.get( + secret_id="", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + credential_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) diff --git a/tests/api_resources/zero_trust/cws/tenant_structures/__init__.py b/tests/api_resources/zero_trust/cws/tenant_structures/__init__.py new file mode 100644 index 00000000000..fd8019a9a1a --- /dev/null +++ b/tests/api_resources/zero_trust/cws/tenant_structures/__init__.py @@ -0,0 +1 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. diff --git a/tests/api_resources/zero_trust/cws/tenant_structures/test_nodes.py b/tests/api_resources/zero_trust/cws/tenant_structures/test_nodes.py new file mode 100644 index 00000000000..7e11478df4e --- /dev/null +++ b/tests/api_resources/zero_trust/cws/tenant_structures/test_nodes.py @@ -0,0 +1,883 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import os +from typing import Any, cast + +import pytest + +from cloudflare import Cloudflare, AsyncCloudflare +from tests.utils import assert_matches_type +from cloudflare.pagination import SyncCursorPagination, AsyncCursorPagination +from cloudflare.types.zero_trust.cws.tenant_structures import ( + NodeBatchResponse, + NodeDeleteResponse, + TenantStructureNode, +) + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestNodes: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @parametrize + def test_method_create(self, client: Cloudflare) -> None: + node = client.zero_trust.cws.tenant_structures.nodes.create( + structure_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + native_id="x", + node_kind="x", + ) + assert_matches_type(TenantStructureNode, node, path=["response"]) + + @parametrize + def test_method_create_with_all_params(self, client: Cloudflare) -> None: + node = client.zero_trust.cws.tenant_structures.nodes.create( + structure_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + native_id="x", + node_kind="x", + name="name", + parent="parent", + ) + assert_matches_type(TenantStructureNode, node, path=["response"]) + + @parametrize + def test_raw_response_create(self, client: Cloudflare) -> None: + response = client.zero_trust.cws.tenant_structures.nodes.with_raw_response.create( + structure_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + native_id="x", + node_kind="x", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + node = response.parse() + assert_matches_type(TenantStructureNode, node, path=["response"]) + + @parametrize + def test_streaming_response_create(self, client: Cloudflare) -> None: + with client.zero_trust.cws.tenant_structures.nodes.with_streaming_response.create( + structure_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + native_id="x", + node_kind="x", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + node = response.parse() + assert_matches_type(TenantStructureNode, node, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_create(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.cws.tenant_structures.nodes.with_raw_response.create( + structure_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + native_id="x", + node_kind="x", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `structure_id` but received ''"): + client.zero_trust.cws.tenant_structures.nodes.with_raw_response.create( + structure_id="", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + native_id="x", + node_kind="x", + ) + + @parametrize + def test_method_update(self, client: Cloudflare) -> None: + node = client.zero_trust.cws.tenant_structures.nodes.update( + node_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + structure_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + native_id="x", + node_kind="x", + ) + assert_matches_type(TenantStructureNode, node, path=["response"]) + + @parametrize + def test_method_update_with_all_params(self, client: Cloudflare) -> None: + node = client.zero_trust.cws.tenant_structures.nodes.update( + node_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + structure_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + native_id="x", + node_kind="x", + name="name", + parent="parent", + ) + assert_matches_type(TenantStructureNode, node, path=["response"]) + + @parametrize + def test_raw_response_update(self, client: Cloudflare) -> None: + response = client.zero_trust.cws.tenant_structures.nodes.with_raw_response.update( + node_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + structure_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + native_id="x", + node_kind="x", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + node = response.parse() + assert_matches_type(TenantStructureNode, node, path=["response"]) + + @parametrize + def test_streaming_response_update(self, client: Cloudflare) -> None: + with client.zero_trust.cws.tenant_structures.nodes.with_streaming_response.update( + node_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + structure_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + native_id="x", + node_kind="x", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + node = response.parse() + assert_matches_type(TenantStructureNode, node, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_update(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.cws.tenant_structures.nodes.with_raw_response.update( + node_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + structure_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + native_id="x", + node_kind="x", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `structure_id` but received ''"): + client.zero_trust.cws.tenant_structures.nodes.with_raw_response.update( + node_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + structure_id="", + native_id="x", + node_kind="x", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `node_id` but received ''"): + client.zero_trust.cws.tenant_structures.nodes.with_raw_response.update( + node_id="", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + structure_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + native_id="x", + node_kind="x", + ) + + @parametrize + def test_method_list(self, client: Cloudflare) -> None: + node = client.zero_trust.cws.tenant_structures.nodes.list( + structure_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + assert_matches_type(SyncCursorPagination[TenantStructureNode], node, path=["response"]) + + @parametrize + def test_method_list_with_all_params(self, client: Cloudflare) -> None: + node = client.zero_trust.cws.tenant_structures.nodes.list( + structure_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + cursor="cursor", + direction="asc", + name="name", + native_id="native_id", + node_kind="node_kind", + order="name", + parent="parent", + per_page=1, + ) + assert_matches_type(SyncCursorPagination[TenantStructureNode], node, path=["response"]) + + @parametrize + def test_raw_response_list(self, client: Cloudflare) -> None: + response = client.zero_trust.cws.tenant_structures.nodes.with_raw_response.list( + structure_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + node = response.parse() + assert_matches_type(SyncCursorPagination[TenantStructureNode], node, path=["response"]) + + @parametrize + def test_streaming_response_list(self, client: Cloudflare) -> None: + with client.zero_trust.cws.tenant_structures.nodes.with_streaming_response.list( + structure_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + node = response.parse() + assert_matches_type(SyncCursorPagination[TenantStructureNode], node, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_list(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.cws.tenant_structures.nodes.with_raw_response.list( + structure_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `structure_id` but received ''"): + client.zero_trust.cws.tenant_structures.nodes.with_raw_response.list( + structure_id="", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + + @parametrize + def test_method_delete(self, client: Cloudflare) -> None: + node = client.zero_trust.cws.tenant_structures.nodes.delete( + node_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + structure_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(NodeDeleteResponse, node, path=["response"]) + + @parametrize + def test_raw_response_delete(self, client: Cloudflare) -> None: + response = client.zero_trust.cws.tenant_structures.nodes.with_raw_response.delete( + node_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + structure_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + node = response.parse() + assert_matches_type(NodeDeleteResponse, node, path=["response"]) + + @parametrize + def test_streaming_response_delete(self, client: Cloudflare) -> None: + with client.zero_trust.cws.tenant_structures.nodes.with_streaming_response.delete( + node_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + structure_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + node = response.parse() + assert_matches_type(NodeDeleteResponse, node, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_delete(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.cws.tenant_structures.nodes.with_raw_response.delete( + node_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + structure_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `structure_id` but received ''"): + client.zero_trust.cws.tenant_structures.nodes.with_raw_response.delete( + node_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + structure_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `node_id` but received ''"): + client.zero_trust.cws.tenant_structures.nodes.with_raw_response.delete( + node_id="", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + structure_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + @parametrize + def test_method_batch(self, client: Cloudflare) -> None: + node = client.zero_trust.cws.tenant_structures.nodes.batch( + structure_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + creates=[ + { + "native_id": "x", + "node_kind": "x", + } + ], + deletes=[{"id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"}], + updates=[{"id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"}], + ) + assert_matches_type(NodeBatchResponse, node, path=["response"]) + + @parametrize + def test_raw_response_batch(self, client: Cloudflare) -> None: + response = client.zero_trust.cws.tenant_structures.nodes.with_raw_response.batch( + structure_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + creates=[ + { + "native_id": "x", + "node_kind": "x", + } + ], + deletes=[{"id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"}], + updates=[{"id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"}], + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + node = response.parse() + assert_matches_type(NodeBatchResponse, node, path=["response"]) + + @parametrize + def test_streaming_response_batch(self, client: Cloudflare) -> None: + with client.zero_trust.cws.tenant_structures.nodes.with_streaming_response.batch( + structure_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + creates=[ + { + "native_id": "x", + "node_kind": "x", + } + ], + deletes=[{"id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"}], + updates=[{"id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"}], + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + node = response.parse() + assert_matches_type(NodeBatchResponse, node, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_batch(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.cws.tenant_structures.nodes.with_raw_response.batch( + structure_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + creates=[ + { + "native_id": "x", + "node_kind": "x", + } + ], + deletes=[{"id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"}], + updates=[{"id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"}], + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `structure_id` but received ''"): + client.zero_trust.cws.tenant_structures.nodes.with_raw_response.batch( + structure_id="", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + creates=[ + { + "native_id": "x", + "node_kind": "x", + } + ], + deletes=[{"id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"}], + updates=[{"id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"}], + ) + + @parametrize + def test_method_get(self, client: Cloudflare) -> None: + node = client.zero_trust.cws.tenant_structures.nodes.get( + node_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + structure_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(TenantStructureNode, node, path=["response"]) + + @parametrize + def test_raw_response_get(self, client: Cloudflare) -> None: + response = client.zero_trust.cws.tenant_structures.nodes.with_raw_response.get( + node_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + structure_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + node = response.parse() + assert_matches_type(TenantStructureNode, node, path=["response"]) + + @parametrize + def test_streaming_response_get(self, client: Cloudflare) -> None: + with client.zero_trust.cws.tenant_structures.nodes.with_streaming_response.get( + node_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + structure_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + node = response.parse() + assert_matches_type(TenantStructureNode, node, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_get(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.cws.tenant_structures.nodes.with_raw_response.get( + node_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + structure_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `structure_id` but received ''"): + client.zero_trust.cws.tenant_structures.nodes.with_raw_response.get( + node_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + structure_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `node_id` but received ''"): + client.zero_trust.cws.tenant_structures.nodes.with_raw_response.get( + node_id="", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + structure_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + +class TestAsyncNodes: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @parametrize + async def test_method_create(self, async_client: AsyncCloudflare) -> None: + node = await async_client.zero_trust.cws.tenant_structures.nodes.create( + structure_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + native_id="x", + node_kind="x", + ) + assert_matches_type(TenantStructureNode, node, path=["response"]) + + @parametrize + async def test_method_create_with_all_params(self, async_client: AsyncCloudflare) -> None: + node = await async_client.zero_trust.cws.tenant_structures.nodes.create( + structure_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + native_id="x", + node_kind="x", + name="name", + parent="parent", + ) + assert_matches_type(TenantStructureNode, node, path=["response"]) + + @parametrize + async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.cws.tenant_structures.nodes.with_raw_response.create( + structure_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + native_id="x", + node_kind="x", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + node = await response.parse() + assert_matches_type(TenantStructureNode, node, path=["response"]) + + @parametrize + async def test_streaming_response_create(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.cws.tenant_structures.nodes.with_streaming_response.create( + structure_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + native_id="x", + node_kind="x", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + node = await response.parse() + assert_matches_type(TenantStructureNode, node, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_create(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.cws.tenant_structures.nodes.with_raw_response.create( + structure_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + native_id="x", + node_kind="x", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `structure_id` but received ''"): + await async_client.zero_trust.cws.tenant_structures.nodes.with_raw_response.create( + structure_id="", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + native_id="x", + node_kind="x", + ) + + @parametrize + async def test_method_update(self, async_client: AsyncCloudflare) -> None: + node = await async_client.zero_trust.cws.tenant_structures.nodes.update( + node_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + structure_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + native_id="x", + node_kind="x", + ) + assert_matches_type(TenantStructureNode, node, path=["response"]) + + @parametrize + async def test_method_update_with_all_params(self, async_client: AsyncCloudflare) -> None: + node = await async_client.zero_trust.cws.tenant_structures.nodes.update( + node_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + structure_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + native_id="x", + node_kind="x", + name="name", + parent="parent", + ) + assert_matches_type(TenantStructureNode, node, path=["response"]) + + @parametrize + async def test_raw_response_update(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.cws.tenant_structures.nodes.with_raw_response.update( + node_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + structure_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + native_id="x", + node_kind="x", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + node = await response.parse() + assert_matches_type(TenantStructureNode, node, path=["response"]) + + @parametrize + async def test_streaming_response_update(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.cws.tenant_structures.nodes.with_streaming_response.update( + node_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + structure_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + native_id="x", + node_kind="x", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + node = await response.parse() + assert_matches_type(TenantStructureNode, node, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_update(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.cws.tenant_structures.nodes.with_raw_response.update( + node_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + structure_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + native_id="x", + node_kind="x", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `structure_id` but received ''"): + await async_client.zero_trust.cws.tenant_structures.nodes.with_raw_response.update( + node_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + structure_id="", + native_id="x", + node_kind="x", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `node_id` but received ''"): + await async_client.zero_trust.cws.tenant_structures.nodes.with_raw_response.update( + node_id="", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + structure_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + native_id="x", + node_kind="x", + ) + + @parametrize + async def test_method_list(self, async_client: AsyncCloudflare) -> None: + node = await async_client.zero_trust.cws.tenant_structures.nodes.list( + structure_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + assert_matches_type(AsyncCursorPagination[TenantStructureNode], node, path=["response"]) + + @parametrize + async def test_method_list_with_all_params(self, async_client: AsyncCloudflare) -> None: + node = await async_client.zero_trust.cws.tenant_structures.nodes.list( + structure_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + cursor="cursor", + direction="asc", + name="name", + native_id="native_id", + node_kind="node_kind", + order="name", + parent="parent", + per_page=1, + ) + assert_matches_type(AsyncCursorPagination[TenantStructureNode], node, path=["response"]) + + @parametrize + async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.cws.tenant_structures.nodes.with_raw_response.list( + structure_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + node = await response.parse() + assert_matches_type(AsyncCursorPagination[TenantStructureNode], node, path=["response"]) + + @parametrize + async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.cws.tenant_structures.nodes.with_streaming_response.list( + structure_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + node = await response.parse() + assert_matches_type(AsyncCursorPagination[TenantStructureNode], node, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_list(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.cws.tenant_structures.nodes.with_raw_response.list( + structure_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `structure_id` but received ''"): + await async_client.zero_trust.cws.tenant_structures.nodes.with_raw_response.list( + structure_id="", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + + @parametrize + async def test_method_delete(self, async_client: AsyncCloudflare) -> None: + node = await async_client.zero_trust.cws.tenant_structures.nodes.delete( + node_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + structure_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(NodeDeleteResponse, node, path=["response"]) + + @parametrize + async def test_raw_response_delete(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.cws.tenant_structures.nodes.with_raw_response.delete( + node_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + structure_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + node = await response.parse() + assert_matches_type(NodeDeleteResponse, node, path=["response"]) + + @parametrize + async def test_streaming_response_delete(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.cws.tenant_structures.nodes.with_streaming_response.delete( + node_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + structure_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + node = await response.parse() + assert_matches_type(NodeDeleteResponse, node, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_delete(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.cws.tenant_structures.nodes.with_raw_response.delete( + node_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + structure_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `structure_id` but received ''"): + await async_client.zero_trust.cws.tenant_structures.nodes.with_raw_response.delete( + node_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + structure_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `node_id` but received ''"): + await async_client.zero_trust.cws.tenant_structures.nodes.with_raw_response.delete( + node_id="", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + structure_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + @parametrize + async def test_method_batch(self, async_client: AsyncCloudflare) -> None: + node = await async_client.zero_trust.cws.tenant_structures.nodes.batch( + structure_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + creates=[ + { + "native_id": "x", + "node_kind": "x", + } + ], + deletes=[{"id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"}], + updates=[{"id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"}], + ) + assert_matches_type(NodeBatchResponse, node, path=["response"]) + + @parametrize + async def test_raw_response_batch(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.cws.tenant_structures.nodes.with_raw_response.batch( + structure_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + creates=[ + { + "native_id": "x", + "node_kind": "x", + } + ], + deletes=[{"id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"}], + updates=[{"id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"}], + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + node = await response.parse() + assert_matches_type(NodeBatchResponse, node, path=["response"]) + + @parametrize + async def test_streaming_response_batch(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.cws.tenant_structures.nodes.with_streaming_response.batch( + structure_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + creates=[ + { + "native_id": "x", + "node_kind": "x", + } + ], + deletes=[{"id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"}], + updates=[{"id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"}], + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + node = await response.parse() + assert_matches_type(NodeBatchResponse, node, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_batch(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.cws.tenant_structures.nodes.with_raw_response.batch( + structure_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + creates=[ + { + "native_id": "x", + "node_kind": "x", + } + ], + deletes=[{"id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"}], + updates=[{"id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"}], + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `structure_id` but received ''"): + await async_client.zero_trust.cws.tenant_structures.nodes.with_raw_response.batch( + structure_id="", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + creates=[ + { + "native_id": "x", + "node_kind": "x", + } + ], + deletes=[{"id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"}], + updates=[{"id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"}], + ) + + @parametrize + async def test_method_get(self, async_client: AsyncCloudflare) -> None: + node = await async_client.zero_trust.cws.tenant_structures.nodes.get( + node_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + structure_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(TenantStructureNode, node, path=["response"]) + + @parametrize + async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.cws.tenant_structures.nodes.with_raw_response.get( + node_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + structure_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + node = await response.parse() + assert_matches_type(TenantStructureNode, node, path=["response"]) + + @parametrize + async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.cws.tenant_structures.nodes.with_streaming_response.get( + node_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + structure_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + node = await response.parse() + assert_matches_type(TenantStructureNode, node, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_get(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.cws.tenant_structures.nodes.with_raw_response.get( + node_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + structure_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `structure_id` but received ''"): + await async_client.zero_trust.cws.tenant_structures.nodes.with_raw_response.get( + node_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + structure_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `node_id` but received ''"): + await async_client.zero_trust.cws.tenant_structures.nodes.with_raw_response.get( + node_id="", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + structure_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) diff --git a/tests/api_resources/zero_trust/cws/test_basic_auth_credentials.py b/tests/api_resources/zero_trust/cws/test_basic_auth_credentials.py new file mode 100644 index 00000000000..43483d4b58d --- /dev/null +++ b/tests/api_resources/zero_trust/cws/test_basic_auth_credentials.py @@ -0,0 +1,406 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import os +from typing import Any, cast + +import pytest + +from cloudflare import Cloudflare, AsyncCloudflare +from tests.utils import assert_matches_type +from cloudflare.pagination import SyncCursorPagination, AsyncCursorPagination +from cloudflare.types.zero_trust.cws import ( + BasicAuthCredential, + BasicAuthCredentialDeleteResponse, +) + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestBasicAuthCredentials: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @parametrize + def test_method_create(self, client: Cloudflare) -> None: + basic_auth_credential = client.zero_trust.cws.basic_auth_credentials.create( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + username="x", + ) + assert_matches_type(BasicAuthCredential, basic_auth_credential, path=["response"]) + + @parametrize + def test_raw_response_create(self, client: Cloudflare) -> None: + response = client.zero_trust.cws.basic_auth_credentials.with_raw_response.create( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + username="x", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + basic_auth_credential = response.parse() + assert_matches_type(BasicAuthCredential, basic_auth_credential, path=["response"]) + + @parametrize + def test_streaming_response_create(self, client: Cloudflare) -> None: + with client.zero_trust.cws.basic_auth_credentials.with_streaming_response.create( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + username="x", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + basic_auth_credential = response.parse() + assert_matches_type(BasicAuthCredential, basic_auth_credential, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_create(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.cws.basic_auth_credentials.with_raw_response.create( + account_id="", + username="x", + ) + + @parametrize + def test_method_list(self, client: Cloudflare) -> None: + basic_auth_credential = client.zero_trust.cws.basic_auth_credentials.list( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + assert_matches_type(SyncCursorPagination[BasicAuthCredential], basic_auth_credential, path=["response"]) + + @parametrize + def test_method_list_with_all_params(self, client: Cloudflare) -> None: + basic_auth_credential = client.zero_trust.cws.basic_auth_credentials.list( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + cursor="cursor", + deployment_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + direction="asc", + order="username", + per_page=1, + username="username", + ) + assert_matches_type(SyncCursorPagination[BasicAuthCredential], basic_auth_credential, path=["response"]) + + @parametrize + def test_raw_response_list(self, client: Cloudflare) -> None: + response = client.zero_trust.cws.basic_auth_credentials.with_raw_response.list( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + basic_auth_credential = response.parse() + assert_matches_type(SyncCursorPagination[BasicAuthCredential], basic_auth_credential, path=["response"]) + + @parametrize + def test_streaming_response_list(self, client: Cloudflare) -> None: + with client.zero_trust.cws.basic_auth_credentials.with_streaming_response.list( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + basic_auth_credential = response.parse() + assert_matches_type(SyncCursorPagination[BasicAuthCredential], basic_auth_credential, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_list(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.cws.basic_auth_credentials.with_raw_response.list( + account_id="", + ) + + @parametrize + def test_method_delete(self, client: Cloudflare) -> None: + basic_auth_credential = client.zero_trust.cws.basic_auth_credentials.delete( + credential_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + assert_matches_type(BasicAuthCredentialDeleteResponse, basic_auth_credential, path=["response"]) + + @parametrize + def test_raw_response_delete(self, client: Cloudflare) -> None: + response = client.zero_trust.cws.basic_auth_credentials.with_raw_response.delete( + credential_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + basic_auth_credential = response.parse() + assert_matches_type(BasicAuthCredentialDeleteResponse, basic_auth_credential, path=["response"]) + + @parametrize + def test_streaming_response_delete(self, client: Cloudflare) -> None: + with client.zero_trust.cws.basic_auth_credentials.with_streaming_response.delete( + credential_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + basic_auth_credential = response.parse() + assert_matches_type(BasicAuthCredentialDeleteResponse, basic_auth_credential, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_delete(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.cws.basic_auth_credentials.with_raw_response.delete( + credential_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `credential_id` but received ''"): + client.zero_trust.cws.basic_auth_credentials.with_raw_response.delete( + credential_id="", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + + @parametrize + def test_method_get(self, client: Cloudflare) -> None: + basic_auth_credential = client.zero_trust.cws.basic_auth_credentials.get( + credential_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + assert_matches_type(BasicAuthCredential, basic_auth_credential, path=["response"]) + + @parametrize + def test_raw_response_get(self, client: Cloudflare) -> None: + response = client.zero_trust.cws.basic_auth_credentials.with_raw_response.get( + credential_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + basic_auth_credential = response.parse() + assert_matches_type(BasicAuthCredential, basic_auth_credential, path=["response"]) + + @parametrize + def test_streaming_response_get(self, client: Cloudflare) -> None: + with client.zero_trust.cws.basic_auth_credentials.with_streaming_response.get( + credential_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + basic_auth_credential = response.parse() + assert_matches_type(BasicAuthCredential, basic_auth_credential, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_get(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.cws.basic_auth_credentials.with_raw_response.get( + credential_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `credential_id` but received ''"): + client.zero_trust.cws.basic_auth_credentials.with_raw_response.get( + credential_id="", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + + +class TestAsyncBasicAuthCredentials: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @parametrize + async def test_method_create(self, async_client: AsyncCloudflare) -> None: + basic_auth_credential = await async_client.zero_trust.cws.basic_auth_credentials.create( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + username="x", + ) + assert_matches_type(BasicAuthCredential, basic_auth_credential, path=["response"]) + + @parametrize + async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.cws.basic_auth_credentials.with_raw_response.create( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + username="x", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + basic_auth_credential = await response.parse() + assert_matches_type(BasicAuthCredential, basic_auth_credential, path=["response"]) + + @parametrize + async def test_streaming_response_create(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.cws.basic_auth_credentials.with_streaming_response.create( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + username="x", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + basic_auth_credential = await response.parse() + assert_matches_type(BasicAuthCredential, basic_auth_credential, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_create(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.cws.basic_auth_credentials.with_raw_response.create( + account_id="", + username="x", + ) + + @parametrize + async def test_method_list(self, async_client: AsyncCloudflare) -> None: + basic_auth_credential = await async_client.zero_trust.cws.basic_auth_credentials.list( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + assert_matches_type(AsyncCursorPagination[BasicAuthCredential], basic_auth_credential, path=["response"]) + + @parametrize + async def test_method_list_with_all_params(self, async_client: AsyncCloudflare) -> None: + basic_auth_credential = await async_client.zero_trust.cws.basic_auth_credentials.list( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + cursor="cursor", + deployment_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + direction="asc", + order="username", + per_page=1, + username="username", + ) + assert_matches_type(AsyncCursorPagination[BasicAuthCredential], basic_auth_credential, path=["response"]) + + @parametrize + async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.cws.basic_auth_credentials.with_raw_response.list( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + basic_auth_credential = await response.parse() + assert_matches_type(AsyncCursorPagination[BasicAuthCredential], basic_auth_credential, path=["response"]) + + @parametrize + async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.cws.basic_auth_credentials.with_streaming_response.list( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + basic_auth_credential = await response.parse() + assert_matches_type(AsyncCursorPagination[BasicAuthCredential], basic_auth_credential, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_list(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.cws.basic_auth_credentials.with_raw_response.list( + account_id="", + ) + + @parametrize + async def test_method_delete(self, async_client: AsyncCloudflare) -> None: + basic_auth_credential = await async_client.zero_trust.cws.basic_auth_credentials.delete( + credential_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + assert_matches_type(BasicAuthCredentialDeleteResponse, basic_auth_credential, path=["response"]) + + @parametrize + async def test_raw_response_delete(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.cws.basic_auth_credentials.with_raw_response.delete( + credential_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + basic_auth_credential = await response.parse() + assert_matches_type(BasicAuthCredentialDeleteResponse, basic_auth_credential, path=["response"]) + + @parametrize + async def test_streaming_response_delete(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.cws.basic_auth_credentials.with_streaming_response.delete( + credential_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + basic_auth_credential = await response.parse() + assert_matches_type(BasicAuthCredentialDeleteResponse, basic_auth_credential, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_delete(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.cws.basic_auth_credentials.with_raw_response.delete( + credential_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `credential_id` but received ''"): + await async_client.zero_trust.cws.basic_auth_credentials.with_raw_response.delete( + credential_id="", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + + @parametrize + async def test_method_get(self, async_client: AsyncCloudflare) -> None: + basic_auth_credential = await async_client.zero_trust.cws.basic_auth_credentials.get( + credential_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + assert_matches_type(BasicAuthCredential, basic_auth_credential, path=["response"]) + + @parametrize + async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.cws.basic_auth_credentials.with_raw_response.get( + credential_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + basic_auth_credential = await response.parse() + assert_matches_type(BasicAuthCredential, basic_auth_credential, path=["response"]) + + @parametrize + async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.cws.basic_auth_credentials.with_streaming_response.get( + credential_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + basic_auth_credential = await response.parse() + assert_matches_type(BasicAuthCredential, basic_auth_credential, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_get(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.cws.basic_auth_credentials.with_raw_response.get( + credential_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `credential_id` but received ''"): + await async_client.zero_trust.cws.basic_auth_credentials.with_raw_response.get( + credential_id="", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) diff --git a/tests/api_resources/zero_trust/cws/test_deployments.py b/tests/api_resources/zero_trust/cws/test_deployments.py new file mode 100644 index 00000000000..2ab6440605a --- /dev/null +++ b/tests/api_resources/zero_trust/cws/test_deployments.py @@ -0,0 +1,630 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import os +from typing import Any, cast + +import pytest + +from cloudflare import Cloudflare, AsyncCloudflare +from tests.utils import assert_matches_type +from cloudflare.pagination import SyncCursorPagination, AsyncCursorPagination +from cloudflare.types.zero_trust.cws import ( + Deployment, + DeploymentDeleteResponse, +) + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestDeployments: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @parametrize + def test_method_create(self, client: Cloudflare) -> None: + deployment = client.zero_trust.cws.deployments.create( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + basic_auth_credential_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], + default_mode="ALLOW", + name="x", + policy_set_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], + ) + assert_matches_type(Deployment, deployment, path=["response"]) + + @parametrize + def test_method_create_with_all_params(self, client: Cloudflare) -> None: + deployment = client.zero_trust.cws.deployments.create( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + basic_auth_credential_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], + default_mode="ALLOW", + name="x", + policy_set_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], + description="description", + domain_acl_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + on_error_action="BLOCK", + rego_raise_error=True, + tags={"foo": "string"}, + ) + assert_matches_type(Deployment, deployment, path=["response"]) + + @parametrize + def test_raw_response_create(self, client: Cloudflare) -> None: + response = client.zero_trust.cws.deployments.with_raw_response.create( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + basic_auth_credential_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], + default_mode="ALLOW", + name="x", + policy_set_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + deployment = response.parse() + assert_matches_type(Deployment, deployment, path=["response"]) + + @parametrize + def test_streaming_response_create(self, client: Cloudflare) -> None: + with client.zero_trust.cws.deployments.with_streaming_response.create( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + basic_auth_credential_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], + default_mode="ALLOW", + name="x", + policy_set_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + deployment = response.parse() + assert_matches_type(Deployment, deployment, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_create(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.cws.deployments.with_raw_response.create( + account_id="", + basic_auth_credential_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], + default_mode="ALLOW", + name="x", + policy_set_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], + ) + + @parametrize + def test_method_update(self, client: Cloudflare) -> None: + deployment = client.zero_trust.cws.deployments.update( + deployment_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + basic_auth_credential_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], + default_mode="ALLOW", + name="x", + policy_set_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], + ) + assert_matches_type(Deployment, deployment, path=["response"]) + + @parametrize + def test_method_update_with_all_params(self, client: Cloudflare) -> None: + deployment = client.zero_trust.cws.deployments.update( + deployment_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + basic_auth_credential_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], + default_mode="ALLOW", + name="x", + policy_set_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], + description="description", + domain_acl_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + on_error_action="BLOCK", + rego_raise_error=True, + tags={"foo": "string"}, + ) + assert_matches_type(Deployment, deployment, path=["response"]) + + @parametrize + def test_raw_response_update(self, client: Cloudflare) -> None: + response = client.zero_trust.cws.deployments.with_raw_response.update( + deployment_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + basic_auth_credential_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], + default_mode="ALLOW", + name="x", + policy_set_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + deployment = response.parse() + assert_matches_type(Deployment, deployment, path=["response"]) + + @parametrize + def test_streaming_response_update(self, client: Cloudflare) -> None: + with client.zero_trust.cws.deployments.with_streaming_response.update( + deployment_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + basic_auth_credential_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], + default_mode="ALLOW", + name="x", + policy_set_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + deployment = response.parse() + assert_matches_type(Deployment, deployment, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_update(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.cws.deployments.with_raw_response.update( + deployment_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + basic_auth_credential_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], + default_mode="ALLOW", + name="x", + policy_set_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `deployment_id` but received ''"): + client.zero_trust.cws.deployments.with_raw_response.update( + deployment_id="", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + basic_auth_credential_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], + default_mode="ALLOW", + name="x", + policy_set_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], + ) + + @parametrize + def test_method_list(self, client: Cloudflare) -> None: + deployment = client.zero_trust.cws.deployments.list( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + assert_matches_type(SyncCursorPagination[Deployment], deployment, path=["response"]) + + @parametrize + def test_method_list_with_all_params(self, client: Cloudflare) -> None: + deployment = client.zero_trust.cws.deployments.list( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + cursor="cursor", + direction="asc", + name="name", + order="name", + per_page=1, + ) + assert_matches_type(SyncCursorPagination[Deployment], deployment, path=["response"]) + + @parametrize + def test_raw_response_list(self, client: Cloudflare) -> None: + response = client.zero_trust.cws.deployments.with_raw_response.list( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + deployment = response.parse() + assert_matches_type(SyncCursorPagination[Deployment], deployment, path=["response"]) + + @parametrize + def test_streaming_response_list(self, client: Cloudflare) -> None: + with client.zero_trust.cws.deployments.with_streaming_response.list( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + deployment = response.parse() + assert_matches_type(SyncCursorPagination[Deployment], deployment, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_list(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.cws.deployments.with_raw_response.list( + account_id="", + ) + + @parametrize + def test_method_delete(self, client: Cloudflare) -> None: + deployment = client.zero_trust.cws.deployments.delete( + deployment_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + assert_matches_type(DeploymentDeleteResponse, deployment, path=["response"]) + + @parametrize + def test_raw_response_delete(self, client: Cloudflare) -> None: + response = client.zero_trust.cws.deployments.with_raw_response.delete( + deployment_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + deployment = response.parse() + assert_matches_type(DeploymentDeleteResponse, deployment, path=["response"]) + + @parametrize + def test_streaming_response_delete(self, client: Cloudflare) -> None: + with client.zero_trust.cws.deployments.with_streaming_response.delete( + deployment_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + deployment = response.parse() + assert_matches_type(DeploymentDeleteResponse, deployment, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_delete(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.cws.deployments.with_raw_response.delete( + deployment_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `deployment_id` but received ''"): + client.zero_trust.cws.deployments.with_raw_response.delete( + deployment_id="", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + + @parametrize + def test_method_get(self, client: Cloudflare) -> None: + deployment = client.zero_trust.cws.deployments.get( + deployment_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + assert_matches_type(Deployment, deployment, path=["response"]) + + @parametrize + def test_raw_response_get(self, client: Cloudflare) -> None: + response = client.zero_trust.cws.deployments.with_raw_response.get( + deployment_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + deployment = response.parse() + assert_matches_type(Deployment, deployment, path=["response"]) + + @parametrize + def test_streaming_response_get(self, client: Cloudflare) -> None: + with client.zero_trust.cws.deployments.with_streaming_response.get( + deployment_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + deployment = response.parse() + assert_matches_type(Deployment, deployment, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_get(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.cws.deployments.with_raw_response.get( + deployment_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `deployment_id` but received ''"): + client.zero_trust.cws.deployments.with_raw_response.get( + deployment_id="", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + + +class TestAsyncDeployments: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @parametrize + async def test_method_create(self, async_client: AsyncCloudflare) -> None: + deployment = await async_client.zero_trust.cws.deployments.create( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + basic_auth_credential_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], + default_mode="ALLOW", + name="x", + policy_set_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], + ) + assert_matches_type(Deployment, deployment, path=["response"]) + + @parametrize + async def test_method_create_with_all_params(self, async_client: AsyncCloudflare) -> None: + deployment = await async_client.zero_trust.cws.deployments.create( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + basic_auth_credential_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], + default_mode="ALLOW", + name="x", + policy_set_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], + description="description", + domain_acl_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + on_error_action="BLOCK", + rego_raise_error=True, + tags={"foo": "string"}, + ) + assert_matches_type(Deployment, deployment, path=["response"]) + + @parametrize + async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.cws.deployments.with_raw_response.create( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + basic_auth_credential_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], + default_mode="ALLOW", + name="x", + policy_set_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + deployment = await response.parse() + assert_matches_type(Deployment, deployment, path=["response"]) + + @parametrize + async def test_streaming_response_create(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.cws.deployments.with_streaming_response.create( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + basic_auth_credential_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], + default_mode="ALLOW", + name="x", + policy_set_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + deployment = await response.parse() + assert_matches_type(Deployment, deployment, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_create(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.cws.deployments.with_raw_response.create( + account_id="", + basic_auth_credential_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], + default_mode="ALLOW", + name="x", + policy_set_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], + ) + + @parametrize + async def test_method_update(self, async_client: AsyncCloudflare) -> None: + deployment = await async_client.zero_trust.cws.deployments.update( + deployment_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + basic_auth_credential_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], + default_mode="ALLOW", + name="x", + policy_set_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], + ) + assert_matches_type(Deployment, deployment, path=["response"]) + + @parametrize + async def test_method_update_with_all_params(self, async_client: AsyncCloudflare) -> None: + deployment = await async_client.zero_trust.cws.deployments.update( + deployment_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + basic_auth_credential_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], + default_mode="ALLOW", + name="x", + policy_set_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], + description="description", + domain_acl_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + on_error_action="BLOCK", + rego_raise_error=True, + tags={"foo": "string"}, + ) + assert_matches_type(Deployment, deployment, path=["response"]) + + @parametrize + async def test_raw_response_update(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.cws.deployments.with_raw_response.update( + deployment_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + basic_auth_credential_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], + default_mode="ALLOW", + name="x", + policy_set_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + deployment = await response.parse() + assert_matches_type(Deployment, deployment, path=["response"]) + + @parametrize + async def test_streaming_response_update(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.cws.deployments.with_streaming_response.update( + deployment_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + basic_auth_credential_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], + default_mode="ALLOW", + name="x", + policy_set_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + deployment = await response.parse() + assert_matches_type(Deployment, deployment, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_update(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.cws.deployments.with_raw_response.update( + deployment_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + basic_auth_credential_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], + default_mode="ALLOW", + name="x", + policy_set_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `deployment_id` but received ''"): + await async_client.zero_trust.cws.deployments.with_raw_response.update( + deployment_id="", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + basic_auth_credential_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], + default_mode="ALLOW", + name="x", + policy_set_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], + ) + + @parametrize + async def test_method_list(self, async_client: AsyncCloudflare) -> None: + deployment = await async_client.zero_trust.cws.deployments.list( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + assert_matches_type(AsyncCursorPagination[Deployment], deployment, path=["response"]) + + @parametrize + async def test_method_list_with_all_params(self, async_client: AsyncCloudflare) -> None: + deployment = await async_client.zero_trust.cws.deployments.list( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + cursor="cursor", + direction="asc", + name="name", + order="name", + per_page=1, + ) + assert_matches_type(AsyncCursorPagination[Deployment], deployment, path=["response"]) + + @parametrize + async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.cws.deployments.with_raw_response.list( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + deployment = await response.parse() + assert_matches_type(AsyncCursorPagination[Deployment], deployment, path=["response"]) + + @parametrize + async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.cws.deployments.with_streaming_response.list( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + deployment = await response.parse() + assert_matches_type(AsyncCursorPagination[Deployment], deployment, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_list(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.cws.deployments.with_raw_response.list( + account_id="", + ) + + @parametrize + async def test_method_delete(self, async_client: AsyncCloudflare) -> None: + deployment = await async_client.zero_trust.cws.deployments.delete( + deployment_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + assert_matches_type(DeploymentDeleteResponse, deployment, path=["response"]) + + @parametrize + async def test_raw_response_delete(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.cws.deployments.with_raw_response.delete( + deployment_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + deployment = await response.parse() + assert_matches_type(DeploymentDeleteResponse, deployment, path=["response"]) + + @parametrize + async def test_streaming_response_delete(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.cws.deployments.with_streaming_response.delete( + deployment_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + deployment = await response.parse() + assert_matches_type(DeploymentDeleteResponse, deployment, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_delete(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.cws.deployments.with_raw_response.delete( + deployment_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `deployment_id` but received ''"): + await async_client.zero_trust.cws.deployments.with_raw_response.delete( + deployment_id="", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + + @parametrize + async def test_method_get(self, async_client: AsyncCloudflare) -> None: + deployment = await async_client.zero_trust.cws.deployments.get( + deployment_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + assert_matches_type(Deployment, deployment, path=["response"]) + + @parametrize + async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.cws.deployments.with_raw_response.get( + deployment_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + deployment = await response.parse() + assert_matches_type(Deployment, deployment, path=["response"]) + + @parametrize + async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.cws.deployments.with_streaming_response.get( + deployment_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + deployment = await response.parse() + assert_matches_type(Deployment, deployment, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_get(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.cws.deployments.with_raw_response.get( + deployment_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `deployment_id` but received ''"): + await async_client.zero_trust.cws.deployments.with_raw_response.get( + deployment_id="", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) diff --git a/tests/api_resources/zero_trust/cws/test_domain_acls.py b/tests/api_resources/zero_trust/cws/test_domain_acls.py new file mode 100644 index 00000000000..04681076d0f --- /dev/null +++ b/tests/api_resources/zero_trust/cws/test_domain_acls.py @@ -0,0 +1,638 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import os +from typing import Any, cast + +import pytest + +from cloudflare import Cloudflare, AsyncCloudflare +from tests.utils import assert_matches_type +from cloudflare.pagination import SyncCursorPagination, AsyncCursorPagination +from cloudflare.types.zero_trust.cws import ( + DomainACL, + DomainACLDeleteResponse, +) + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestDomainACLs: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @parametrize + def test_method_create(self, client: Cloudflare) -> None: + domain_acl = client.zero_trust.cws.domain_acls.create( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + default_action="ALLOW", + entries=[ + { + "action": "ALLOW", + "domain": "x", + } + ], + name="x", + ) + assert_matches_type(DomainACL, domain_acl, path=["response"]) + + @parametrize + def test_raw_response_create(self, client: Cloudflare) -> None: + response = client.zero_trust.cws.domain_acls.with_raw_response.create( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + default_action="ALLOW", + entries=[ + { + "action": "ALLOW", + "domain": "x", + } + ], + name="x", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + domain_acl = response.parse() + assert_matches_type(DomainACL, domain_acl, path=["response"]) + + @parametrize + def test_streaming_response_create(self, client: Cloudflare) -> None: + with client.zero_trust.cws.domain_acls.with_streaming_response.create( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + default_action="ALLOW", + entries=[ + { + "action": "ALLOW", + "domain": "x", + } + ], + name="x", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + domain_acl = response.parse() + assert_matches_type(DomainACL, domain_acl, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_create(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.cws.domain_acls.with_raw_response.create( + account_id="", + default_action="ALLOW", + entries=[ + { + "action": "ALLOW", + "domain": "x", + } + ], + name="x", + ) + + @parametrize + def test_method_update(self, client: Cloudflare) -> None: + domain_acl = client.zero_trust.cws.domain_acls.update( + domain_acl_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + default_action="ALLOW", + entries=[ + { + "action": "ALLOW", + "domain": "x", + } + ], + name="x", + ) + assert_matches_type(DomainACL, domain_acl, path=["response"]) + + @parametrize + def test_raw_response_update(self, client: Cloudflare) -> None: + response = client.zero_trust.cws.domain_acls.with_raw_response.update( + domain_acl_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + default_action="ALLOW", + entries=[ + { + "action": "ALLOW", + "domain": "x", + } + ], + name="x", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + domain_acl = response.parse() + assert_matches_type(DomainACL, domain_acl, path=["response"]) + + @parametrize + def test_streaming_response_update(self, client: Cloudflare) -> None: + with client.zero_trust.cws.domain_acls.with_streaming_response.update( + domain_acl_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + default_action="ALLOW", + entries=[ + { + "action": "ALLOW", + "domain": "x", + } + ], + name="x", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + domain_acl = response.parse() + assert_matches_type(DomainACL, domain_acl, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_update(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.cws.domain_acls.with_raw_response.update( + domain_acl_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + default_action="ALLOW", + entries=[ + { + "action": "ALLOW", + "domain": "x", + } + ], + name="x", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `domain_acl_id` but received ''"): + client.zero_trust.cws.domain_acls.with_raw_response.update( + domain_acl_id="", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + default_action="ALLOW", + entries=[ + { + "action": "ALLOW", + "domain": "x", + } + ], + name="x", + ) + + @parametrize + def test_method_list(self, client: Cloudflare) -> None: + domain_acl = client.zero_trust.cws.domain_acls.list( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + assert_matches_type(SyncCursorPagination[DomainACL], domain_acl, path=["response"]) + + @parametrize + def test_method_list_with_all_params(self, client: Cloudflare) -> None: + domain_acl = client.zero_trust.cws.domain_acls.list( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + cursor="cursor", + deployment_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + direction="asc", + name="name", + order="name", + per_page=1, + ) + assert_matches_type(SyncCursorPagination[DomainACL], domain_acl, path=["response"]) + + @parametrize + def test_raw_response_list(self, client: Cloudflare) -> None: + response = client.zero_trust.cws.domain_acls.with_raw_response.list( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + domain_acl = response.parse() + assert_matches_type(SyncCursorPagination[DomainACL], domain_acl, path=["response"]) + + @parametrize + def test_streaming_response_list(self, client: Cloudflare) -> None: + with client.zero_trust.cws.domain_acls.with_streaming_response.list( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + domain_acl = response.parse() + assert_matches_type(SyncCursorPagination[DomainACL], domain_acl, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_list(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.cws.domain_acls.with_raw_response.list( + account_id="", + ) + + @parametrize + def test_method_delete(self, client: Cloudflare) -> None: + domain_acl = client.zero_trust.cws.domain_acls.delete( + domain_acl_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + assert_matches_type(DomainACLDeleteResponse, domain_acl, path=["response"]) + + @parametrize + def test_raw_response_delete(self, client: Cloudflare) -> None: + response = client.zero_trust.cws.domain_acls.with_raw_response.delete( + domain_acl_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + domain_acl = response.parse() + assert_matches_type(DomainACLDeleteResponse, domain_acl, path=["response"]) + + @parametrize + def test_streaming_response_delete(self, client: Cloudflare) -> None: + with client.zero_trust.cws.domain_acls.with_streaming_response.delete( + domain_acl_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + domain_acl = response.parse() + assert_matches_type(DomainACLDeleteResponse, domain_acl, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_delete(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.cws.domain_acls.with_raw_response.delete( + domain_acl_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `domain_acl_id` but received ''"): + client.zero_trust.cws.domain_acls.with_raw_response.delete( + domain_acl_id="", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + + @parametrize + def test_method_get(self, client: Cloudflare) -> None: + domain_acl = client.zero_trust.cws.domain_acls.get( + domain_acl_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + assert_matches_type(DomainACL, domain_acl, path=["response"]) + + @parametrize + def test_raw_response_get(self, client: Cloudflare) -> None: + response = client.zero_trust.cws.domain_acls.with_raw_response.get( + domain_acl_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + domain_acl = response.parse() + assert_matches_type(DomainACL, domain_acl, path=["response"]) + + @parametrize + def test_streaming_response_get(self, client: Cloudflare) -> None: + with client.zero_trust.cws.domain_acls.with_streaming_response.get( + domain_acl_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + domain_acl = response.parse() + assert_matches_type(DomainACL, domain_acl, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_get(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.cws.domain_acls.with_raw_response.get( + domain_acl_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `domain_acl_id` but received ''"): + client.zero_trust.cws.domain_acls.with_raw_response.get( + domain_acl_id="", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + + +class TestAsyncDomainACLs: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @parametrize + async def test_method_create(self, async_client: AsyncCloudflare) -> None: + domain_acl = await async_client.zero_trust.cws.domain_acls.create( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + default_action="ALLOW", + entries=[ + { + "action": "ALLOW", + "domain": "x", + } + ], + name="x", + ) + assert_matches_type(DomainACL, domain_acl, path=["response"]) + + @parametrize + async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.cws.domain_acls.with_raw_response.create( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + default_action="ALLOW", + entries=[ + { + "action": "ALLOW", + "domain": "x", + } + ], + name="x", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + domain_acl = await response.parse() + assert_matches_type(DomainACL, domain_acl, path=["response"]) + + @parametrize + async def test_streaming_response_create(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.cws.domain_acls.with_streaming_response.create( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + default_action="ALLOW", + entries=[ + { + "action": "ALLOW", + "domain": "x", + } + ], + name="x", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + domain_acl = await response.parse() + assert_matches_type(DomainACL, domain_acl, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_create(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.cws.domain_acls.with_raw_response.create( + account_id="", + default_action="ALLOW", + entries=[ + { + "action": "ALLOW", + "domain": "x", + } + ], + name="x", + ) + + @parametrize + async def test_method_update(self, async_client: AsyncCloudflare) -> None: + domain_acl = await async_client.zero_trust.cws.domain_acls.update( + domain_acl_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + default_action="ALLOW", + entries=[ + { + "action": "ALLOW", + "domain": "x", + } + ], + name="x", + ) + assert_matches_type(DomainACL, domain_acl, path=["response"]) + + @parametrize + async def test_raw_response_update(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.cws.domain_acls.with_raw_response.update( + domain_acl_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + default_action="ALLOW", + entries=[ + { + "action": "ALLOW", + "domain": "x", + } + ], + name="x", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + domain_acl = await response.parse() + assert_matches_type(DomainACL, domain_acl, path=["response"]) + + @parametrize + async def test_streaming_response_update(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.cws.domain_acls.with_streaming_response.update( + domain_acl_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + default_action="ALLOW", + entries=[ + { + "action": "ALLOW", + "domain": "x", + } + ], + name="x", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + domain_acl = await response.parse() + assert_matches_type(DomainACL, domain_acl, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_update(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.cws.domain_acls.with_raw_response.update( + domain_acl_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + default_action="ALLOW", + entries=[ + { + "action": "ALLOW", + "domain": "x", + } + ], + name="x", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `domain_acl_id` but received ''"): + await async_client.zero_trust.cws.domain_acls.with_raw_response.update( + domain_acl_id="", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + default_action="ALLOW", + entries=[ + { + "action": "ALLOW", + "domain": "x", + } + ], + name="x", + ) + + @parametrize + async def test_method_list(self, async_client: AsyncCloudflare) -> None: + domain_acl = await async_client.zero_trust.cws.domain_acls.list( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + assert_matches_type(AsyncCursorPagination[DomainACL], domain_acl, path=["response"]) + + @parametrize + async def test_method_list_with_all_params(self, async_client: AsyncCloudflare) -> None: + domain_acl = await async_client.zero_trust.cws.domain_acls.list( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + cursor="cursor", + deployment_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + direction="asc", + name="name", + order="name", + per_page=1, + ) + assert_matches_type(AsyncCursorPagination[DomainACL], domain_acl, path=["response"]) + + @parametrize + async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.cws.domain_acls.with_raw_response.list( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + domain_acl = await response.parse() + assert_matches_type(AsyncCursorPagination[DomainACL], domain_acl, path=["response"]) + + @parametrize + async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.cws.domain_acls.with_streaming_response.list( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + domain_acl = await response.parse() + assert_matches_type(AsyncCursorPagination[DomainACL], domain_acl, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_list(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.cws.domain_acls.with_raw_response.list( + account_id="", + ) + + @parametrize + async def test_method_delete(self, async_client: AsyncCloudflare) -> None: + domain_acl = await async_client.zero_trust.cws.domain_acls.delete( + domain_acl_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + assert_matches_type(DomainACLDeleteResponse, domain_acl, path=["response"]) + + @parametrize + async def test_raw_response_delete(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.cws.domain_acls.with_raw_response.delete( + domain_acl_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + domain_acl = await response.parse() + assert_matches_type(DomainACLDeleteResponse, domain_acl, path=["response"]) + + @parametrize + async def test_streaming_response_delete(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.cws.domain_acls.with_streaming_response.delete( + domain_acl_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + domain_acl = await response.parse() + assert_matches_type(DomainACLDeleteResponse, domain_acl, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_delete(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.cws.domain_acls.with_raw_response.delete( + domain_acl_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `domain_acl_id` but received ''"): + await async_client.zero_trust.cws.domain_acls.with_raw_response.delete( + domain_acl_id="", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + + @parametrize + async def test_method_get(self, async_client: AsyncCloudflare) -> None: + domain_acl = await async_client.zero_trust.cws.domain_acls.get( + domain_acl_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + assert_matches_type(DomainACL, domain_acl, path=["response"]) + + @parametrize + async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.cws.domain_acls.with_raw_response.get( + domain_acl_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + domain_acl = await response.parse() + assert_matches_type(DomainACL, domain_acl, path=["response"]) + + @parametrize + async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.cws.domain_acls.with_streaming_response.get( + domain_acl_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + domain_acl = await response.parse() + assert_matches_type(DomainACL, domain_acl, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_get(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.cws.domain_acls.with_raw_response.get( + domain_acl_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `domain_acl_id` but received ''"): + await async_client.zero_trust.cws.domain_acls.with_raw_response.get( + domain_acl_id="", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) diff --git a/tests/api_resources/zero_trust/cws/test_policies.py b/tests/api_resources/zero_trust/cws/test_policies.py new file mode 100644 index 00000000000..49f9a2aa7d0 --- /dev/null +++ b/tests/api_resources/zero_trust/cws/test_policies.py @@ -0,0 +1,622 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import os +from typing import Any, cast + +import pytest + +from cloudflare import Cloudflare, AsyncCloudflare +from tests.utils import assert_matches_type +from cloudflare.pagination import SyncCursorPagination, AsyncCursorPagination +from cloudflare.types.zero_trust.cws import ( + Policy, + PolicyDeleteResponse, +) + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestPolicies: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @parametrize + def test_method_create(self, client: Cloudflare) -> None: + policy = client.zero_trust.cws.policies.create( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + entrypoint="entrypoint", + filter="x", + name="x", + rego_source="x", + ) + assert_matches_type(Policy, policy, path=["response"]) + + @parametrize + def test_method_create_with_all_params(self, client: Cloudflare) -> None: + policy = client.zero_trust.cws.policies.create( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + entrypoint="entrypoint", + filter="x", + name="x", + rego_source="x", + description="description", + tags={"foo": "string"}, + ) + assert_matches_type(Policy, policy, path=["response"]) + + @parametrize + def test_raw_response_create(self, client: Cloudflare) -> None: + response = client.zero_trust.cws.policies.with_raw_response.create( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + entrypoint="entrypoint", + filter="x", + name="x", + rego_source="x", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + policy = response.parse() + assert_matches_type(Policy, policy, path=["response"]) + + @parametrize + def test_streaming_response_create(self, client: Cloudflare) -> None: + with client.zero_trust.cws.policies.with_streaming_response.create( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + entrypoint="entrypoint", + filter="x", + name="x", + rego_source="x", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + policy = response.parse() + assert_matches_type(Policy, policy, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_create(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.cws.policies.with_raw_response.create( + account_id="", + entrypoint="entrypoint", + filter="x", + name="x", + rego_source="x", + ) + + @parametrize + def test_method_update(self, client: Cloudflare) -> None: + policy = client.zero_trust.cws.policies.update( + policy_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + entrypoint="entrypoint", + filter="x", + name="x", + rego_source="x", + ) + assert_matches_type(Policy, policy, path=["response"]) + + @parametrize + def test_method_update_with_all_params(self, client: Cloudflare) -> None: + policy = client.zero_trust.cws.policies.update( + policy_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + entrypoint="entrypoint", + filter="x", + name="x", + rego_source="x", + description="description", + tags={"foo": "string"}, + ) + assert_matches_type(Policy, policy, path=["response"]) + + @parametrize + def test_raw_response_update(self, client: Cloudflare) -> None: + response = client.zero_trust.cws.policies.with_raw_response.update( + policy_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + entrypoint="entrypoint", + filter="x", + name="x", + rego_source="x", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + policy = response.parse() + assert_matches_type(Policy, policy, path=["response"]) + + @parametrize + def test_streaming_response_update(self, client: Cloudflare) -> None: + with client.zero_trust.cws.policies.with_streaming_response.update( + policy_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + entrypoint="entrypoint", + filter="x", + name="x", + rego_source="x", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + policy = response.parse() + assert_matches_type(Policy, policy, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_update(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.cws.policies.with_raw_response.update( + policy_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + entrypoint="entrypoint", + filter="x", + name="x", + rego_source="x", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `policy_id` but received ''"): + client.zero_trust.cws.policies.with_raw_response.update( + policy_id="", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + entrypoint="entrypoint", + filter="x", + name="x", + rego_source="x", + ) + + @parametrize + def test_method_list(self, client: Cloudflare) -> None: + policy = client.zero_trust.cws.policies.list( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + assert_matches_type(SyncCursorPagination[Policy], policy, path=["response"]) + + @parametrize + def test_method_list_with_all_params(self, client: Cloudflare) -> None: + policy = client.zero_trust.cws.policies.list( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + cursor="cursor", + direction="asc", + name="name", + order="name", + package_path="package_path", + per_page=1, + policy_set_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(SyncCursorPagination[Policy], policy, path=["response"]) + + @parametrize + def test_raw_response_list(self, client: Cloudflare) -> None: + response = client.zero_trust.cws.policies.with_raw_response.list( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + policy = response.parse() + assert_matches_type(SyncCursorPagination[Policy], policy, path=["response"]) + + @parametrize + def test_streaming_response_list(self, client: Cloudflare) -> None: + with client.zero_trust.cws.policies.with_streaming_response.list( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + policy = response.parse() + assert_matches_type(SyncCursorPagination[Policy], policy, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_list(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.cws.policies.with_raw_response.list( + account_id="", + ) + + @parametrize + def test_method_delete(self, client: Cloudflare) -> None: + policy = client.zero_trust.cws.policies.delete( + policy_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + assert_matches_type(PolicyDeleteResponse, policy, path=["response"]) + + @parametrize + def test_raw_response_delete(self, client: Cloudflare) -> None: + response = client.zero_trust.cws.policies.with_raw_response.delete( + policy_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + policy = response.parse() + assert_matches_type(PolicyDeleteResponse, policy, path=["response"]) + + @parametrize + def test_streaming_response_delete(self, client: Cloudflare) -> None: + with client.zero_trust.cws.policies.with_streaming_response.delete( + policy_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + policy = response.parse() + assert_matches_type(PolicyDeleteResponse, policy, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_delete(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.cws.policies.with_raw_response.delete( + policy_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `policy_id` but received ''"): + client.zero_trust.cws.policies.with_raw_response.delete( + policy_id="", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + + @parametrize + def test_method_get(self, client: Cloudflare) -> None: + policy = client.zero_trust.cws.policies.get( + policy_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + assert_matches_type(Policy, policy, path=["response"]) + + @parametrize + def test_raw_response_get(self, client: Cloudflare) -> None: + response = client.zero_trust.cws.policies.with_raw_response.get( + policy_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + policy = response.parse() + assert_matches_type(Policy, policy, path=["response"]) + + @parametrize + def test_streaming_response_get(self, client: Cloudflare) -> None: + with client.zero_trust.cws.policies.with_streaming_response.get( + policy_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + policy = response.parse() + assert_matches_type(Policy, policy, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_get(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.cws.policies.with_raw_response.get( + policy_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `policy_id` but received ''"): + client.zero_trust.cws.policies.with_raw_response.get( + policy_id="", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + + +class TestAsyncPolicies: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @parametrize + async def test_method_create(self, async_client: AsyncCloudflare) -> None: + policy = await async_client.zero_trust.cws.policies.create( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + entrypoint="entrypoint", + filter="x", + name="x", + rego_source="x", + ) + assert_matches_type(Policy, policy, path=["response"]) + + @parametrize + async def test_method_create_with_all_params(self, async_client: AsyncCloudflare) -> None: + policy = await async_client.zero_trust.cws.policies.create( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + entrypoint="entrypoint", + filter="x", + name="x", + rego_source="x", + description="description", + tags={"foo": "string"}, + ) + assert_matches_type(Policy, policy, path=["response"]) + + @parametrize + async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.cws.policies.with_raw_response.create( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + entrypoint="entrypoint", + filter="x", + name="x", + rego_source="x", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + policy = await response.parse() + assert_matches_type(Policy, policy, path=["response"]) + + @parametrize + async def test_streaming_response_create(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.cws.policies.with_streaming_response.create( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + entrypoint="entrypoint", + filter="x", + name="x", + rego_source="x", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + policy = await response.parse() + assert_matches_type(Policy, policy, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_create(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.cws.policies.with_raw_response.create( + account_id="", + entrypoint="entrypoint", + filter="x", + name="x", + rego_source="x", + ) + + @parametrize + async def test_method_update(self, async_client: AsyncCloudflare) -> None: + policy = await async_client.zero_trust.cws.policies.update( + policy_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + entrypoint="entrypoint", + filter="x", + name="x", + rego_source="x", + ) + assert_matches_type(Policy, policy, path=["response"]) + + @parametrize + async def test_method_update_with_all_params(self, async_client: AsyncCloudflare) -> None: + policy = await async_client.zero_trust.cws.policies.update( + policy_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + entrypoint="entrypoint", + filter="x", + name="x", + rego_source="x", + description="description", + tags={"foo": "string"}, + ) + assert_matches_type(Policy, policy, path=["response"]) + + @parametrize + async def test_raw_response_update(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.cws.policies.with_raw_response.update( + policy_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + entrypoint="entrypoint", + filter="x", + name="x", + rego_source="x", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + policy = await response.parse() + assert_matches_type(Policy, policy, path=["response"]) + + @parametrize + async def test_streaming_response_update(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.cws.policies.with_streaming_response.update( + policy_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + entrypoint="entrypoint", + filter="x", + name="x", + rego_source="x", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + policy = await response.parse() + assert_matches_type(Policy, policy, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_update(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.cws.policies.with_raw_response.update( + policy_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + entrypoint="entrypoint", + filter="x", + name="x", + rego_source="x", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `policy_id` but received ''"): + await async_client.zero_trust.cws.policies.with_raw_response.update( + policy_id="", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + entrypoint="entrypoint", + filter="x", + name="x", + rego_source="x", + ) + + @parametrize + async def test_method_list(self, async_client: AsyncCloudflare) -> None: + policy = await async_client.zero_trust.cws.policies.list( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + assert_matches_type(AsyncCursorPagination[Policy], policy, path=["response"]) + + @parametrize + async def test_method_list_with_all_params(self, async_client: AsyncCloudflare) -> None: + policy = await async_client.zero_trust.cws.policies.list( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + cursor="cursor", + direction="asc", + name="name", + order="name", + package_path="package_path", + per_page=1, + policy_set_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(AsyncCursorPagination[Policy], policy, path=["response"]) + + @parametrize + async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.cws.policies.with_raw_response.list( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + policy = await response.parse() + assert_matches_type(AsyncCursorPagination[Policy], policy, path=["response"]) + + @parametrize + async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.cws.policies.with_streaming_response.list( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + policy = await response.parse() + assert_matches_type(AsyncCursorPagination[Policy], policy, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_list(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.cws.policies.with_raw_response.list( + account_id="", + ) + + @parametrize + async def test_method_delete(self, async_client: AsyncCloudflare) -> None: + policy = await async_client.zero_trust.cws.policies.delete( + policy_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + assert_matches_type(PolicyDeleteResponse, policy, path=["response"]) + + @parametrize + async def test_raw_response_delete(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.cws.policies.with_raw_response.delete( + policy_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + policy = await response.parse() + assert_matches_type(PolicyDeleteResponse, policy, path=["response"]) + + @parametrize + async def test_streaming_response_delete(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.cws.policies.with_streaming_response.delete( + policy_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + policy = await response.parse() + assert_matches_type(PolicyDeleteResponse, policy, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_delete(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.cws.policies.with_raw_response.delete( + policy_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `policy_id` but received ''"): + await async_client.zero_trust.cws.policies.with_raw_response.delete( + policy_id="", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + + @parametrize + async def test_method_get(self, async_client: AsyncCloudflare) -> None: + policy = await async_client.zero_trust.cws.policies.get( + policy_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + assert_matches_type(Policy, policy, path=["response"]) + + @parametrize + async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.cws.policies.with_raw_response.get( + policy_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + policy = await response.parse() + assert_matches_type(Policy, policy, path=["response"]) + + @parametrize + async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.cws.policies.with_streaming_response.get( + policy_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + policy = await response.parse() + assert_matches_type(Policy, policy, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_get(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.cws.policies.with_raw_response.get( + policy_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `policy_id` but received ''"): + await async_client.zero_trust.cws.policies.with_raw_response.get( + policy_id="", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) diff --git a/tests/api_resources/zero_trust/cws/test_policy_sets.py b/tests/api_resources/zero_trust/cws/test_policy_sets.py new file mode 100644 index 00000000000..d11bad8629e --- /dev/null +++ b/tests/api_resources/zero_trust/cws/test_policy_sets.py @@ -0,0 +1,604 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import os +from typing import Any, cast + +import pytest + +from cloudflare import Cloudflare, AsyncCloudflare +from tests.utils import assert_matches_type +from cloudflare.pagination import SyncCursorPagination, AsyncCursorPagination +from cloudflare.types.zero_trust.cws import ( + PolicySet, + PolicySetDeleteResponse, +) + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestPolicySets: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @parametrize + def test_method_create(self, client: Cloudflare) -> None: + policy_set = client.zero_trust.cws.policy_sets.create( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + name="x", + policies=[{"policy_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"}], + ) + assert_matches_type(PolicySet, policy_set, path=["response"]) + + @parametrize + def test_method_create_with_all_params(self, client: Cloudflare) -> None: + policy_set = client.zero_trust.cws.policy_sets.create( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + name="x", + policies=[ + { + "policy_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + "enforce": True, + } + ], + description="description", + exclude_workload_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], + include_workload_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], + tags={"foo": "string"}, + ) + assert_matches_type(PolicySet, policy_set, path=["response"]) + + @parametrize + def test_raw_response_create(self, client: Cloudflare) -> None: + response = client.zero_trust.cws.policy_sets.with_raw_response.create( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + name="x", + policies=[{"policy_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"}], + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + policy_set = response.parse() + assert_matches_type(PolicySet, policy_set, path=["response"]) + + @parametrize + def test_streaming_response_create(self, client: Cloudflare) -> None: + with client.zero_trust.cws.policy_sets.with_streaming_response.create( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + name="x", + policies=[{"policy_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"}], + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + policy_set = response.parse() + assert_matches_type(PolicySet, policy_set, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_create(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.cws.policy_sets.with_raw_response.create( + account_id="", + name="x", + policies=[{"policy_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"}], + ) + + @parametrize + def test_method_update(self, client: Cloudflare) -> None: + policy_set = client.zero_trust.cws.policy_sets.update( + policy_set_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + name="x", + policies=[{"policy_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"}], + ) + assert_matches_type(PolicySet, policy_set, path=["response"]) + + @parametrize + def test_method_update_with_all_params(self, client: Cloudflare) -> None: + policy_set = client.zero_trust.cws.policy_sets.update( + policy_set_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + name="x", + policies=[ + { + "policy_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + "enforce": True, + } + ], + description="description", + exclude_workload_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], + include_workload_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], + tags={"foo": "string"}, + ) + assert_matches_type(PolicySet, policy_set, path=["response"]) + + @parametrize + def test_raw_response_update(self, client: Cloudflare) -> None: + response = client.zero_trust.cws.policy_sets.with_raw_response.update( + policy_set_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + name="x", + policies=[{"policy_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"}], + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + policy_set = response.parse() + assert_matches_type(PolicySet, policy_set, path=["response"]) + + @parametrize + def test_streaming_response_update(self, client: Cloudflare) -> None: + with client.zero_trust.cws.policy_sets.with_streaming_response.update( + policy_set_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + name="x", + policies=[{"policy_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"}], + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + policy_set = response.parse() + assert_matches_type(PolicySet, policy_set, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_update(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.cws.policy_sets.with_raw_response.update( + policy_set_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + name="x", + policies=[{"policy_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"}], + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `policy_set_id` but received ''"): + client.zero_trust.cws.policy_sets.with_raw_response.update( + policy_set_id="", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + name="x", + policies=[{"policy_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"}], + ) + + @parametrize + def test_method_list(self, client: Cloudflare) -> None: + policy_set = client.zero_trust.cws.policy_sets.list( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + assert_matches_type(SyncCursorPagination[PolicySet], policy_set, path=["response"]) + + @parametrize + def test_method_list_with_all_params(self, client: Cloudflare) -> None: + policy_set = client.zero_trust.cws.policy_sets.list( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + cursor="cursor", + deployment_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + direction="asc", + name="name", + order="name", + per_page=1, + ) + assert_matches_type(SyncCursorPagination[PolicySet], policy_set, path=["response"]) + + @parametrize + def test_raw_response_list(self, client: Cloudflare) -> None: + response = client.zero_trust.cws.policy_sets.with_raw_response.list( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + policy_set = response.parse() + assert_matches_type(SyncCursorPagination[PolicySet], policy_set, path=["response"]) + + @parametrize + def test_streaming_response_list(self, client: Cloudflare) -> None: + with client.zero_trust.cws.policy_sets.with_streaming_response.list( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + policy_set = response.parse() + assert_matches_type(SyncCursorPagination[PolicySet], policy_set, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_list(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.cws.policy_sets.with_raw_response.list( + account_id="", + ) + + @parametrize + def test_method_delete(self, client: Cloudflare) -> None: + policy_set = client.zero_trust.cws.policy_sets.delete( + policy_set_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + assert_matches_type(PolicySetDeleteResponse, policy_set, path=["response"]) + + @parametrize + def test_raw_response_delete(self, client: Cloudflare) -> None: + response = client.zero_trust.cws.policy_sets.with_raw_response.delete( + policy_set_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + policy_set = response.parse() + assert_matches_type(PolicySetDeleteResponse, policy_set, path=["response"]) + + @parametrize + def test_streaming_response_delete(self, client: Cloudflare) -> None: + with client.zero_trust.cws.policy_sets.with_streaming_response.delete( + policy_set_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + policy_set = response.parse() + assert_matches_type(PolicySetDeleteResponse, policy_set, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_delete(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.cws.policy_sets.with_raw_response.delete( + policy_set_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `policy_set_id` but received ''"): + client.zero_trust.cws.policy_sets.with_raw_response.delete( + policy_set_id="", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + + @parametrize + def test_method_get(self, client: Cloudflare) -> None: + policy_set = client.zero_trust.cws.policy_sets.get( + policy_set_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + assert_matches_type(PolicySet, policy_set, path=["response"]) + + @parametrize + def test_raw_response_get(self, client: Cloudflare) -> None: + response = client.zero_trust.cws.policy_sets.with_raw_response.get( + policy_set_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + policy_set = response.parse() + assert_matches_type(PolicySet, policy_set, path=["response"]) + + @parametrize + def test_streaming_response_get(self, client: Cloudflare) -> None: + with client.zero_trust.cws.policy_sets.with_streaming_response.get( + policy_set_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + policy_set = response.parse() + assert_matches_type(PolicySet, policy_set, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_get(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.cws.policy_sets.with_raw_response.get( + policy_set_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `policy_set_id` but received ''"): + client.zero_trust.cws.policy_sets.with_raw_response.get( + policy_set_id="", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + + +class TestAsyncPolicySets: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @parametrize + async def test_method_create(self, async_client: AsyncCloudflare) -> None: + policy_set = await async_client.zero_trust.cws.policy_sets.create( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + name="x", + policies=[{"policy_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"}], + ) + assert_matches_type(PolicySet, policy_set, path=["response"]) + + @parametrize + async def test_method_create_with_all_params(self, async_client: AsyncCloudflare) -> None: + policy_set = await async_client.zero_trust.cws.policy_sets.create( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + name="x", + policies=[ + { + "policy_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + "enforce": True, + } + ], + description="description", + exclude_workload_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], + include_workload_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], + tags={"foo": "string"}, + ) + assert_matches_type(PolicySet, policy_set, path=["response"]) + + @parametrize + async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.cws.policy_sets.with_raw_response.create( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + name="x", + policies=[{"policy_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"}], + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + policy_set = await response.parse() + assert_matches_type(PolicySet, policy_set, path=["response"]) + + @parametrize + async def test_streaming_response_create(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.cws.policy_sets.with_streaming_response.create( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + name="x", + policies=[{"policy_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"}], + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + policy_set = await response.parse() + assert_matches_type(PolicySet, policy_set, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_create(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.cws.policy_sets.with_raw_response.create( + account_id="", + name="x", + policies=[{"policy_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"}], + ) + + @parametrize + async def test_method_update(self, async_client: AsyncCloudflare) -> None: + policy_set = await async_client.zero_trust.cws.policy_sets.update( + policy_set_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + name="x", + policies=[{"policy_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"}], + ) + assert_matches_type(PolicySet, policy_set, path=["response"]) + + @parametrize + async def test_method_update_with_all_params(self, async_client: AsyncCloudflare) -> None: + policy_set = await async_client.zero_trust.cws.policy_sets.update( + policy_set_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + name="x", + policies=[ + { + "policy_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + "enforce": True, + } + ], + description="description", + exclude_workload_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], + include_workload_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], + tags={"foo": "string"}, + ) + assert_matches_type(PolicySet, policy_set, path=["response"]) + + @parametrize + async def test_raw_response_update(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.cws.policy_sets.with_raw_response.update( + policy_set_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + name="x", + policies=[{"policy_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"}], + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + policy_set = await response.parse() + assert_matches_type(PolicySet, policy_set, path=["response"]) + + @parametrize + async def test_streaming_response_update(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.cws.policy_sets.with_streaming_response.update( + policy_set_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + name="x", + policies=[{"policy_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"}], + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + policy_set = await response.parse() + assert_matches_type(PolicySet, policy_set, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_update(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.cws.policy_sets.with_raw_response.update( + policy_set_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + name="x", + policies=[{"policy_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"}], + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `policy_set_id` but received ''"): + await async_client.zero_trust.cws.policy_sets.with_raw_response.update( + policy_set_id="", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + name="x", + policies=[{"policy_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"}], + ) + + @parametrize + async def test_method_list(self, async_client: AsyncCloudflare) -> None: + policy_set = await async_client.zero_trust.cws.policy_sets.list( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + assert_matches_type(AsyncCursorPagination[PolicySet], policy_set, path=["response"]) + + @parametrize + async def test_method_list_with_all_params(self, async_client: AsyncCloudflare) -> None: + policy_set = await async_client.zero_trust.cws.policy_sets.list( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + cursor="cursor", + deployment_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + direction="asc", + name="name", + order="name", + per_page=1, + ) + assert_matches_type(AsyncCursorPagination[PolicySet], policy_set, path=["response"]) + + @parametrize + async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.cws.policy_sets.with_raw_response.list( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + policy_set = await response.parse() + assert_matches_type(AsyncCursorPagination[PolicySet], policy_set, path=["response"]) + + @parametrize + async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.cws.policy_sets.with_streaming_response.list( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + policy_set = await response.parse() + assert_matches_type(AsyncCursorPagination[PolicySet], policy_set, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_list(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.cws.policy_sets.with_raw_response.list( + account_id="", + ) + + @parametrize + async def test_method_delete(self, async_client: AsyncCloudflare) -> None: + policy_set = await async_client.zero_trust.cws.policy_sets.delete( + policy_set_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + assert_matches_type(PolicySetDeleteResponse, policy_set, path=["response"]) + + @parametrize + async def test_raw_response_delete(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.cws.policy_sets.with_raw_response.delete( + policy_set_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + policy_set = await response.parse() + assert_matches_type(PolicySetDeleteResponse, policy_set, path=["response"]) + + @parametrize + async def test_streaming_response_delete(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.cws.policy_sets.with_streaming_response.delete( + policy_set_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + policy_set = await response.parse() + assert_matches_type(PolicySetDeleteResponse, policy_set, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_delete(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.cws.policy_sets.with_raw_response.delete( + policy_set_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `policy_set_id` but received ''"): + await async_client.zero_trust.cws.policy_sets.with_raw_response.delete( + policy_set_id="", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + + @parametrize + async def test_method_get(self, async_client: AsyncCloudflare) -> None: + policy_set = await async_client.zero_trust.cws.policy_sets.get( + policy_set_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + assert_matches_type(PolicySet, policy_set, path=["response"]) + + @parametrize + async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.cws.policy_sets.with_raw_response.get( + policy_set_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + policy_set = await response.parse() + assert_matches_type(PolicySet, policy_set, path=["response"]) + + @parametrize + async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.cws.policy_sets.with_streaming_response.get( + policy_set_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + policy_set = await response.parse() + assert_matches_type(PolicySet, policy_set, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_get(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.cws.policy_sets.with_raw_response.get( + policy_set_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `policy_set_id` but received ''"): + await async_client.zero_trust.cws.policy_sets.with_raw_response.get( + policy_set_id="", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) diff --git a/tests/api_resources/zero_trust/cws/test_rego_metadata.py b/tests/api_resources/zero_trust/cws/test_rego_metadata.py new file mode 100644 index 00000000000..ce2601fbe76 --- /dev/null +++ b/tests/api_resources/zero_trust/cws/test_rego_metadata.py @@ -0,0 +1,548 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import os +from typing import Any, cast + +import pytest + +from cloudflare import Cloudflare, AsyncCloudflare +from tests.utils import assert_matches_type +from cloudflare.pagination import SyncCursorPagination, AsyncCursorPagination +from cloudflare.types.zero_trust.cws import ( + RegoMetadata, + RegoMetadataDeleteResponse, +) + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestRegoMetadata: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @parametrize + def test_method_create(self, client: Cloudflare) -> None: + rego_metadata = client.zero_trust.cws.rego_metadata.create( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + data={}, + import_path="x", + name="x", + ) + assert_matches_type(RegoMetadata, rego_metadata, path=["response"]) + + @parametrize + def test_raw_response_create(self, client: Cloudflare) -> None: + response = client.zero_trust.cws.rego_metadata.with_raw_response.create( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + data={}, + import_path="x", + name="x", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + rego_metadata = response.parse() + assert_matches_type(RegoMetadata, rego_metadata, path=["response"]) + + @parametrize + def test_streaming_response_create(self, client: Cloudflare) -> None: + with client.zero_trust.cws.rego_metadata.with_streaming_response.create( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + data={}, + import_path="x", + name="x", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + rego_metadata = response.parse() + assert_matches_type(RegoMetadata, rego_metadata, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_create(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.cws.rego_metadata.with_raw_response.create( + account_id="", + data={}, + import_path="x", + name="x", + ) + + @parametrize + def test_method_update(self, client: Cloudflare) -> None: + rego_metadata = client.zero_trust.cws.rego_metadata.update( + rego_metadata_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + data={}, + import_path="x", + name="x", + ) + assert_matches_type(RegoMetadata, rego_metadata, path=["response"]) + + @parametrize + def test_raw_response_update(self, client: Cloudflare) -> None: + response = client.zero_trust.cws.rego_metadata.with_raw_response.update( + rego_metadata_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + data={}, + import_path="x", + name="x", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + rego_metadata = response.parse() + assert_matches_type(RegoMetadata, rego_metadata, path=["response"]) + + @parametrize + def test_streaming_response_update(self, client: Cloudflare) -> None: + with client.zero_trust.cws.rego_metadata.with_streaming_response.update( + rego_metadata_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + data={}, + import_path="x", + name="x", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + rego_metadata = response.parse() + assert_matches_type(RegoMetadata, rego_metadata, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_update(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.cws.rego_metadata.with_raw_response.update( + rego_metadata_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + data={}, + import_path="x", + name="x", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `rego_metadata_id` but received ''"): + client.zero_trust.cws.rego_metadata.with_raw_response.update( + rego_metadata_id="", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + data={}, + import_path="x", + name="x", + ) + + @parametrize + def test_method_list(self, client: Cloudflare) -> None: + rego_metadata = client.zero_trust.cws.rego_metadata.list( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + assert_matches_type(SyncCursorPagination[RegoMetadata], rego_metadata, path=["response"]) + + @parametrize + def test_method_list_with_all_params(self, client: Cloudflare) -> None: + rego_metadata = client.zero_trust.cws.rego_metadata.list( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + cursor="cursor", + direction="asc", + import_path="import_path", + name="name", + order="name", + per_page=1, + ) + assert_matches_type(SyncCursorPagination[RegoMetadata], rego_metadata, path=["response"]) + + @parametrize + def test_raw_response_list(self, client: Cloudflare) -> None: + response = client.zero_trust.cws.rego_metadata.with_raw_response.list( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + rego_metadata = response.parse() + assert_matches_type(SyncCursorPagination[RegoMetadata], rego_metadata, path=["response"]) + + @parametrize + def test_streaming_response_list(self, client: Cloudflare) -> None: + with client.zero_trust.cws.rego_metadata.with_streaming_response.list( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + rego_metadata = response.parse() + assert_matches_type(SyncCursorPagination[RegoMetadata], rego_metadata, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_list(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.cws.rego_metadata.with_raw_response.list( + account_id="", + ) + + @parametrize + def test_method_delete(self, client: Cloudflare) -> None: + rego_metadata = client.zero_trust.cws.rego_metadata.delete( + rego_metadata_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + assert_matches_type(RegoMetadataDeleteResponse, rego_metadata, path=["response"]) + + @parametrize + def test_raw_response_delete(self, client: Cloudflare) -> None: + response = client.zero_trust.cws.rego_metadata.with_raw_response.delete( + rego_metadata_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + rego_metadata = response.parse() + assert_matches_type(RegoMetadataDeleteResponse, rego_metadata, path=["response"]) + + @parametrize + def test_streaming_response_delete(self, client: Cloudflare) -> None: + with client.zero_trust.cws.rego_metadata.with_streaming_response.delete( + rego_metadata_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + rego_metadata = response.parse() + assert_matches_type(RegoMetadataDeleteResponse, rego_metadata, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_delete(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.cws.rego_metadata.with_raw_response.delete( + rego_metadata_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `rego_metadata_id` but received ''"): + client.zero_trust.cws.rego_metadata.with_raw_response.delete( + rego_metadata_id="", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + + @parametrize + def test_method_get(self, client: Cloudflare) -> None: + rego_metadata = client.zero_trust.cws.rego_metadata.get( + rego_metadata_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + assert_matches_type(RegoMetadata, rego_metadata, path=["response"]) + + @parametrize + def test_raw_response_get(self, client: Cloudflare) -> None: + response = client.zero_trust.cws.rego_metadata.with_raw_response.get( + rego_metadata_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + rego_metadata = response.parse() + assert_matches_type(RegoMetadata, rego_metadata, path=["response"]) + + @parametrize + def test_streaming_response_get(self, client: Cloudflare) -> None: + with client.zero_trust.cws.rego_metadata.with_streaming_response.get( + rego_metadata_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + rego_metadata = response.parse() + assert_matches_type(RegoMetadata, rego_metadata, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_get(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.cws.rego_metadata.with_raw_response.get( + rego_metadata_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `rego_metadata_id` but received ''"): + client.zero_trust.cws.rego_metadata.with_raw_response.get( + rego_metadata_id="", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + + +class TestAsyncRegoMetadata: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @parametrize + async def test_method_create(self, async_client: AsyncCloudflare) -> None: + rego_metadata = await async_client.zero_trust.cws.rego_metadata.create( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + data={}, + import_path="x", + name="x", + ) + assert_matches_type(RegoMetadata, rego_metadata, path=["response"]) + + @parametrize + async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.cws.rego_metadata.with_raw_response.create( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + data={}, + import_path="x", + name="x", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + rego_metadata = await response.parse() + assert_matches_type(RegoMetadata, rego_metadata, path=["response"]) + + @parametrize + async def test_streaming_response_create(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.cws.rego_metadata.with_streaming_response.create( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + data={}, + import_path="x", + name="x", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + rego_metadata = await response.parse() + assert_matches_type(RegoMetadata, rego_metadata, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_create(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.cws.rego_metadata.with_raw_response.create( + account_id="", + data={}, + import_path="x", + name="x", + ) + + @parametrize + async def test_method_update(self, async_client: AsyncCloudflare) -> None: + rego_metadata = await async_client.zero_trust.cws.rego_metadata.update( + rego_metadata_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + data={}, + import_path="x", + name="x", + ) + assert_matches_type(RegoMetadata, rego_metadata, path=["response"]) + + @parametrize + async def test_raw_response_update(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.cws.rego_metadata.with_raw_response.update( + rego_metadata_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + data={}, + import_path="x", + name="x", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + rego_metadata = await response.parse() + assert_matches_type(RegoMetadata, rego_metadata, path=["response"]) + + @parametrize + async def test_streaming_response_update(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.cws.rego_metadata.with_streaming_response.update( + rego_metadata_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + data={}, + import_path="x", + name="x", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + rego_metadata = await response.parse() + assert_matches_type(RegoMetadata, rego_metadata, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_update(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.cws.rego_metadata.with_raw_response.update( + rego_metadata_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + data={}, + import_path="x", + name="x", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `rego_metadata_id` but received ''"): + await async_client.zero_trust.cws.rego_metadata.with_raw_response.update( + rego_metadata_id="", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + data={}, + import_path="x", + name="x", + ) + + @parametrize + async def test_method_list(self, async_client: AsyncCloudflare) -> None: + rego_metadata = await async_client.zero_trust.cws.rego_metadata.list( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + assert_matches_type(AsyncCursorPagination[RegoMetadata], rego_metadata, path=["response"]) + + @parametrize + async def test_method_list_with_all_params(self, async_client: AsyncCloudflare) -> None: + rego_metadata = await async_client.zero_trust.cws.rego_metadata.list( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + cursor="cursor", + direction="asc", + import_path="import_path", + name="name", + order="name", + per_page=1, + ) + assert_matches_type(AsyncCursorPagination[RegoMetadata], rego_metadata, path=["response"]) + + @parametrize + async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.cws.rego_metadata.with_raw_response.list( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + rego_metadata = await response.parse() + assert_matches_type(AsyncCursorPagination[RegoMetadata], rego_metadata, path=["response"]) + + @parametrize + async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.cws.rego_metadata.with_streaming_response.list( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + rego_metadata = await response.parse() + assert_matches_type(AsyncCursorPagination[RegoMetadata], rego_metadata, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_list(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.cws.rego_metadata.with_raw_response.list( + account_id="", + ) + + @parametrize + async def test_method_delete(self, async_client: AsyncCloudflare) -> None: + rego_metadata = await async_client.zero_trust.cws.rego_metadata.delete( + rego_metadata_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + assert_matches_type(RegoMetadataDeleteResponse, rego_metadata, path=["response"]) + + @parametrize + async def test_raw_response_delete(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.cws.rego_metadata.with_raw_response.delete( + rego_metadata_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + rego_metadata = await response.parse() + assert_matches_type(RegoMetadataDeleteResponse, rego_metadata, path=["response"]) + + @parametrize + async def test_streaming_response_delete(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.cws.rego_metadata.with_streaming_response.delete( + rego_metadata_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + rego_metadata = await response.parse() + assert_matches_type(RegoMetadataDeleteResponse, rego_metadata, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_delete(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.cws.rego_metadata.with_raw_response.delete( + rego_metadata_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `rego_metadata_id` but received ''"): + await async_client.zero_trust.cws.rego_metadata.with_raw_response.delete( + rego_metadata_id="", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + + @parametrize + async def test_method_get(self, async_client: AsyncCloudflare) -> None: + rego_metadata = await async_client.zero_trust.cws.rego_metadata.get( + rego_metadata_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + assert_matches_type(RegoMetadata, rego_metadata, path=["response"]) + + @parametrize + async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.cws.rego_metadata.with_raw_response.get( + rego_metadata_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + rego_metadata = await response.parse() + assert_matches_type(RegoMetadata, rego_metadata, path=["response"]) + + @parametrize + async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.cws.rego_metadata.with_streaming_response.get( + rego_metadata_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + rego_metadata = await response.parse() + assert_matches_type(RegoMetadata, rego_metadata, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_get(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.cws.rego_metadata.with_raw_response.get( + rego_metadata_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `rego_metadata_id` but received ''"): + await async_client.zero_trust.cws.rego_metadata.with_raw_response.get( + rego_metadata_id="", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) diff --git a/tests/api_resources/zero_trust/cws/test_rego_modules.py b/tests/api_resources/zero_trust/cws/test_rego_modules.py new file mode 100644 index 00000000000..39ddfeca516 --- /dev/null +++ b/tests/api_resources/zero_trust/cws/test_rego_modules.py @@ -0,0 +1,530 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import os +from typing import Any, cast + +import pytest + +from cloudflare import Cloudflare, AsyncCloudflare +from tests.utils import assert_matches_type +from cloudflare.pagination import SyncCursorPagination, AsyncCursorPagination +from cloudflare.types.zero_trust.cws import ( + RegoModule, + RegoModuleDeleteResponse, +) + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestRegoModules: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @parametrize + def test_method_create(self, client: Cloudflare) -> None: + rego_module = client.zero_trust.cws.rego_modules.create( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + name="x", + rego_source="x", + ) + assert_matches_type(RegoModule, rego_module, path=["response"]) + + @parametrize + def test_raw_response_create(self, client: Cloudflare) -> None: + response = client.zero_trust.cws.rego_modules.with_raw_response.create( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + name="x", + rego_source="x", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + rego_module = response.parse() + assert_matches_type(RegoModule, rego_module, path=["response"]) + + @parametrize + def test_streaming_response_create(self, client: Cloudflare) -> None: + with client.zero_trust.cws.rego_modules.with_streaming_response.create( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + name="x", + rego_source="x", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + rego_module = response.parse() + assert_matches_type(RegoModule, rego_module, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_create(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.cws.rego_modules.with_raw_response.create( + account_id="", + name="x", + rego_source="x", + ) + + @parametrize + def test_method_update(self, client: Cloudflare) -> None: + rego_module = client.zero_trust.cws.rego_modules.update( + rego_module_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + name="x", + rego_source="x", + ) + assert_matches_type(RegoModule, rego_module, path=["response"]) + + @parametrize + def test_raw_response_update(self, client: Cloudflare) -> None: + response = client.zero_trust.cws.rego_modules.with_raw_response.update( + rego_module_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + name="x", + rego_source="x", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + rego_module = response.parse() + assert_matches_type(RegoModule, rego_module, path=["response"]) + + @parametrize + def test_streaming_response_update(self, client: Cloudflare) -> None: + with client.zero_trust.cws.rego_modules.with_streaming_response.update( + rego_module_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + name="x", + rego_source="x", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + rego_module = response.parse() + assert_matches_type(RegoModule, rego_module, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_update(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.cws.rego_modules.with_raw_response.update( + rego_module_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + name="x", + rego_source="x", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `rego_module_id` but received ''"): + client.zero_trust.cws.rego_modules.with_raw_response.update( + rego_module_id="", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + name="x", + rego_source="x", + ) + + @parametrize + def test_method_list(self, client: Cloudflare) -> None: + rego_module = client.zero_trust.cws.rego_modules.list( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + assert_matches_type(SyncCursorPagination[RegoModule], rego_module, path=["response"]) + + @parametrize + def test_method_list_with_all_params(self, client: Cloudflare) -> None: + rego_module = client.zero_trust.cws.rego_modules.list( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + cursor="cursor", + direction="asc", + name="name", + order="name", + package_path="package_path", + per_page=1, + ) + assert_matches_type(SyncCursorPagination[RegoModule], rego_module, path=["response"]) + + @parametrize + def test_raw_response_list(self, client: Cloudflare) -> None: + response = client.zero_trust.cws.rego_modules.with_raw_response.list( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + rego_module = response.parse() + assert_matches_type(SyncCursorPagination[RegoModule], rego_module, path=["response"]) + + @parametrize + def test_streaming_response_list(self, client: Cloudflare) -> None: + with client.zero_trust.cws.rego_modules.with_streaming_response.list( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + rego_module = response.parse() + assert_matches_type(SyncCursorPagination[RegoModule], rego_module, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_list(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.cws.rego_modules.with_raw_response.list( + account_id="", + ) + + @parametrize + def test_method_delete(self, client: Cloudflare) -> None: + rego_module = client.zero_trust.cws.rego_modules.delete( + rego_module_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + assert_matches_type(RegoModuleDeleteResponse, rego_module, path=["response"]) + + @parametrize + def test_raw_response_delete(self, client: Cloudflare) -> None: + response = client.zero_trust.cws.rego_modules.with_raw_response.delete( + rego_module_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + rego_module = response.parse() + assert_matches_type(RegoModuleDeleteResponse, rego_module, path=["response"]) + + @parametrize + def test_streaming_response_delete(self, client: Cloudflare) -> None: + with client.zero_trust.cws.rego_modules.with_streaming_response.delete( + rego_module_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + rego_module = response.parse() + assert_matches_type(RegoModuleDeleteResponse, rego_module, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_delete(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.cws.rego_modules.with_raw_response.delete( + rego_module_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `rego_module_id` but received ''"): + client.zero_trust.cws.rego_modules.with_raw_response.delete( + rego_module_id="", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + + @parametrize + def test_method_get(self, client: Cloudflare) -> None: + rego_module = client.zero_trust.cws.rego_modules.get( + rego_module_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + assert_matches_type(RegoModule, rego_module, path=["response"]) + + @parametrize + def test_raw_response_get(self, client: Cloudflare) -> None: + response = client.zero_trust.cws.rego_modules.with_raw_response.get( + rego_module_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + rego_module = response.parse() + assert_matches_type(RegoModule, rego_module, path=["response"]) + + @parametrize + def test_streaming_response_get(self, client: Cloudflare) -> None: + with client.zero_trust.cws.rego_modules.with_streaming_response.get( + rego_module_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + rego_module = response.parse() + assert_matches_type(RegoModule, rego_module, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_get(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.cws.rego_modules.with_raw_response.get( + rego_module_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `rego_module_id` but received ''"): + client.zero_trust.cws.rego_modules.with_raw_response.get( + rego_module_id="", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + + +class TestAsyncRegoModules: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @parametrize + async def test_method_create(self, async_client: AsyncCloudflare) -> None: + rego_module = await async_client.zero_trust.cws.rego_modules.create( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + name="x", + rego_source="x", + ) + assert_matches_type(RegoModule, rego_module, path=["response"]) + + @parametrize + async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.cws.rego_modules.with_raw_response.create( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + name="x", + rego_source="x", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + rego_module = await response.parse() + assert_matches_type(RegoModule, rego_module, path=["response"]) + + @parametrize + async def test_streaming_response_create(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.cws.rego_modules.with_streaming_response.create( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + name="x", + rego_source="x", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + rego_module = await response.parse() + assert_matches_type(RegoModule, rego_module, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_create(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.cws.rego_modules.with_raw_response.create( + account_id="", + name="x", + rego_source="x", + ) + + @parametrize + async def test_method_update(self, async_client: AsyncCloudflare) -> None: + rego_module = await async_client.zero_trust.cws.rego_modules.update( + rego_module_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + name="x", + rego_source="x", + ) + assert_matches_type(RegoModule, rego_module, path=["response"]) + + @parametrize + async def test_raw_response_update(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.cws.rego_modules.with_raw_response.update( + rego_module_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + name="x", + rego_source="x", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + rego_module = await response.parse() + assert_matches_type(RegoModule, rego_module, path=["response"]) + + @parametrize + async def test_streaming_response_update(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.cws.rego_modules.with_streaming_response.update( + rego_module_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + name="x", + rego_source="x", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + rego_module = await response.parse() + assert_matches_type(RegoModule, rego_module, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_update(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.cws.rego_modules.with_raw_response.update( + rego_module_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + name="x", + rego_source="x", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `rego_module_id` but received ''"): + await async_client.zero_trust.cws.rego_modules.with_raw_response.update( + rego_module_id="", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + name="x", + rego_source="x", + ) + + @parametrize + async def test_method_list(self, async_client: AsyncCloudflare) -> None: + rego_module = await async_client.zero_trust.cws.rego_modules.list( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + assert_matches_type(AsyncCursorPagination[RegoModule], rego_module, path=["response"]) + + @parametrize + async def test_method_list_with_all_params(self, async_client: AsyncCloudflare) -> None: + rego_module = await async_client.zero_trust.cws.rego_modules.list( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + cursor="cursor", + direction="asc", + name="name", + order="name", + package_path="package_path", + per_page=1, + ) + assert_matches_type(AsyncCursorPagination[RegoModule], rego_module, path=["response"]) + + @parametrize + async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.cws.rego_modules.with_raw_response.list( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + rego_module = await response.parse() + assert_matches_type(AsyncCursorPagination[RegoModule], rego_module, path=["response"]) + + @parametrize + async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.cws.rego_modules.with_streaming_response.list( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + rego_module = await response.parse() + assert_matches_type(AsyncCursorPagination[RegoModule], rego_module, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_list(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.cws.rego_modules.with_raw_response.list( + account_id="", + ) + + @parametrize + async def test_method_delete(self, async_client: AsyncCloudflare) -> None: + rego_module = await async_client.zero_trust.cws.rego_modules.delete( + rego_module_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + assert_matches_type(RegoModuleDeleteResponse, rego_module, path=["response"]) + + @parametrize + async def test_raw_response_delete(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.cws.rego_modules.with_raw_response.delete( + rego_module_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + rego_module = await response.parse() + assert_matches_type(RegoModuleDeleteResponse, rego_module, path=["response"]) + + @parametrize + async def test_streaming_response_delete(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.cws.rego_modules.with_streaming_response.delete( + rego_module_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + rego_module = await response.parse() + assert_matches_type(RegoModuleDeleteResponse, rego_module, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_delete(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.cws.rego_modules.with_raw_response.delete( + rego_module_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `rego_module_id` but received ''"): + await async_client.zero_trust.cws.rego_modules.with_raw_response.delete( + rego_module_id="", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + + @parametrize + async def test_method_get(self, async_client: AsyncCloudflare) -> None: + rego_module = await async_client.zero_trust.cws.rego_modules.get( + rego_module_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + assert_matches_type(RegoModule, rego_module, path=["response"]) + + @parametrize + async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.cws.rego_modules.with_raw_response.get( + rego_module_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + rego_module = await response.parse() + assert_matches_type(RegoModule, rego_module, path=["response"]) + + @parametrize + async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.cws.rego_modules.with_streaming_response.get( + rego_module_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + rego_module = await response.parse() + assert_matches_type(RegoModule, rego_module, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_get(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.cws.rego_modules.with_raw_response.get( + rego_module_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `rego_module_id` but received ''"): + await async_client.zero_trust.cws.rego_modules.with_raw_response.get( + rego_module_id="", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) diff --git a/tests/api_resources/zero_trust/cws/test_tenant_structures.py b/tests/api_resources/zero_trust/cws/test_tenant_structures.py new file mode 100644 index 00000000000..1224ee960ec --- /dev/null +++ b/tests/api_resources/zero_trust/cws/test_tenant_structures.py @@ -0,0 +1,572 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import os +from typing import Any, cast + +import pytest + +from cloudflare import Cloudflare, AsyncCloudflare +from tests.utils import assert_matches_type +from cloudflare.pagination import SyncCursorPagination, AsyncCursorPagination +from cloudflare.types.zero_trust.cws import ( + TenantStructure, + TenantStructureDeleteResponse, +) + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestTenantStructures: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @parametrize + def test_method_create(self, client: Cloudflare) -> None: + tenant_structure = client.zero_trust.cws.tenant_structures.create( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + application="aws", + name="x", + ) + assert_matches_type(TenantStructure, tenant_structure, path=["response"]) + + @parametrize + def test_method_create_with_all_params(self, client: Cloudflare) -> None: + tenant_structure = client.zero_trust.cws.tenant_structures.create( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + application="aws", + name="x", + import_path="x", + ) + assert_matches_type(TenantStructure, tenant_structure, path=["response"]) + + @parametrize + def test_raw_response_create(self, client: Cloudflare) -> None: + response = client.zero_trust.cws.tenant_structures.with_raw_response.create( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + application="aws", + name="x", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + tenant_structure = response.parse() + assert_matches_type(TenantStructure, tenant_structure, path=["response"]) + + @parametrize + def test_streaming_response_create(self, client: Cloudflare) -> None: + with client.zero_trust.cws.tenant_structures.with_streaming_response.create( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + application="aws", + name="x", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + tenant_structure = response.parse() + assert_matches_type(TenantStructure, tenant_structure, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_create(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.cws.tenant_structures.with_raw_response.create( + account_id="", + application="aws", + name="x", + ) + + @parametrize + def test_method_update(self, client: Cloudflare) -> None: + tenant_structure = client.zero_trust.cws.tenant_structures.update( + structure_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + application="aws", + name="x", + ) + assert_matches_type(TenantStructure, tenant_structure, path=["response"]) + + @parametrize + def test_method_update_with_all_params(self, client: Cloudflare) -> None: + tenant_structure = client.zero_trust.cws.tenant_structures.update( + structure_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + application="aws", + name="x", + import_path="x", + ) + assert_matches_type(TenantStructure, tenant_structure, path=["response"]) + + @parametrize + def test_raw_response_update(self, client: Cloudflare) -> None: + response = client.zero_trust.cws.tenant_structures.with_raw_response.update( + structure_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + application="aws", + name="x", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + tenant_structure = response.parse() + assert_matches_type(TenantStructure, tenant_structure, path=["response"]) + + @parametrize + def test_streaming_response_update(self, client: Cloudflare) -> None: + with client.zero_trust.cws.tenant_structures.with_streaming_response.update( + structure_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + application="aws", + name="x", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + tenant_structure = response.parse() + assert_matches_type(TenantStructure, tenant_structure, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_update(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.cws.tenant_structures.with_raw_response.update( + structure_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + application="aws", + name="x", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `structure_id` but received ''"): + client.zero_trust.cws.tenant_structures.with_raw_response.update( + structure_id="", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + application="aws", + name="x", + ) + + @parametrize + def test_method_list(self, client: Cloudflare) -> None: + tenant_structure = client.zero_trust.cws.tenant_structures.list( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + assert_matches_type(SyncCursorPagination[TenantStructure], tenant_structure, path=["response"]) + + @parametrize + def test_method_list_with_all_params(self, client: Cloudflare) -> None: + tenant_structure = client.zero_trust.cws.tenant_structures.list( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + cursor="cursor", + direction="asc", + import_path="import_path", + name="name", + order="name", + per_page=1, + ) + assert_matches_type(SyncCursorPagination[TenantStructure], tenant_structure, path=["response"]) + + @parametrize + def test_raw_response_list(self, client: Cloudflare) -> None: + response = client.zero_trust.cws.tenant_structures.with_raw_response.list( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + tenant_structure = response.parse() + assert_matches_type(SyncCursorPagination[TenantStructure], tenant_structure, path=["response"]) + + @parametrize + def test_streaming_response_list(self, client: Cloudflare) -> None: + with client.zero_trust.cws.tenant_structures.with_streaming_response.list( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + tenant_structure = response.parse() + assert_matches_type(SyncCursorPagination[TenantStructure], tenant_structure, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_list(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.cws.tenant_structures.with_raw_response.list( + account_id="", + ) + + @parametrize + def test_method_delete(self, client: Cloudflare) -> None: + tenant_structure = client.zero_trust.cws.tenant_structures.delete( + structure_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + assert_matches_type(TenantStructureDeleteResponse, tenant_structure, path=["response"]) + + @parametrize + def test_raw_response_delete(self, client: Cloudflare) -> None: + response = client.zero_trust.cws.tenant_structures.with_raw_response.delete( + structure_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + tenant_structure = response.parse() + assert_matches_type(TenantStructureDeleteResponse, tenant_structure, path=["response"]) + + @parametrize + def test_streaming_response_delete(self, client: Cloudflare) -> None: + with client.zero_trust.cws.tenant_structures.with_streaming_response.delete( + structure_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + tenant_structure = response.parse() + assert_matches_type(TenantStructureDeleteResponse, tenant_structure, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_delete(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.cws.tenant_structures.with_raw_response.delete( + structure_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `structure_id` but received ''"): + client.zero_trust.cws.tenant_structures.with_raw_response.delete( + structure_id="", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + + @parametrize + def test_method_get(self, client: Cloudflare) -> None: + tenant_structure = client.zero_trust.cws.tenant_structures.get( + structure_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + assert_matches_type(TenantStructure, tenant_structure, path=["response"]) + + @parametrize + def test_raw_response_get(self, client: Cloudflare) -> None: + response = client.zero_trust.cws.tenant_structures.with_raw_response.get( + structure_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + tenant_structure = response.parse() + assert_matches_type(TenantStructure, tenant_structure, path=["response"]) + + @parametrize + def test_streaming_response_get(self, client: Cloudflare) -> None: + with client.zero_trust.cws.tenant_structures.with_streaming_response.get( + structure_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + tenant_structure = response.parse() + assert_matches_type(TenantStructure, tenant_structure, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_get(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.cws.tenant_structures.with_raw_response.get( + structure_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `structure_id` but received ''"): + client.zero_trust.cws.tenant_structures.with_raw_response.get( + structure_id="", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + + +class TestAsyncTenantStructures: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @parametrize + async def test_method_create(self, async_client: AsyncCloudflare) -> None: + tenant_structure = await async_client.zero_trust.cws.tenant_structures.create( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + application="aws", + name="x", + ) + assert_matches_type(TenantStructure, tenant_structure, path=["response"]) + + @parametrize + async def test_method_create_with_all_params(self, async_client: AsyncCloudflare) -> None: + tenant_structure = await async_client.zero_trust.cws.tenant_structures.create( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + application="aws", + name="x", + import_path="x", + ) + assert_matches_type(TenantStructure, tenant_structure, path=["response"]) + + @parametrize + async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.cws.tenant_structures.with_raw_response.create( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + application="aws", + name="x", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + tenant_structure = await response.parse() + assert_matches_type(TenantStructure, tenant_structure, path=["response"]) + + @parametrize + async def test_streaming_response_create(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.cws.tenant_structures.with_streaming_response.create( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + application="aws", + name="x", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + tenant_structure = await response.parse() + assert_matches_type(TenantStructure, tenant_structure, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_create(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.cws.tenant_structures.with_raw_response.create( + account_id="", + application="aws", + name="x", + ) + + @parametrize + async def test_method_update(self, async_client: AsyncCloudflare) -> None: + tenant_structure = await async_client.zero_trust.cws.tenant_structures.update( + structure_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + application="aws", + name="x", + ) + assert_matches_type(TenantStructure, tenant_structure, path=["response"]) + + @parametrize + async def test_method_update_with_all_params(self, async_client: AsyncCloudflare) -> None: + tenant_structure = await async_client.zero_trust.cws.tenant_structures.update( + structure_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + application="aws", + name="x", + import_path="x", + ) + assert_matches_type(TenantStructure, tenant_structure, path=["response"]) + + @parametrize + async def test_raw_response_update(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.cws.tenant_structures.with_raw_response.update( + structure_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + application="aws", + name="x", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + tenant_structure = await response.parse() + assert_matches_type(TenantStructure, tenant_structure, path=["response"]) + + @parametrize + async def test_streaming_response_update(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.cws.tenant_structures.with_streaming_response.update( + structure_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + application="aws", + name="x", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + tenant_structure = await response.parse() + assert_matches_type(TenantStructure, tenant_structure, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_update(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.cws.tenant_structures.with_raw_response.update( + structure_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + application="aws", + name="x", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `structure_id` but received ''"): + await async_client.zero_trust.cws.tenant_structures.with_raw_response.update( + structure_id="", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + application="aws", + name="x", + ) + + @parametrize + async def test_method_list(self, async_client: AsyncCloudflare) -> None: + tenant_structure = await async_client.zero_trust.cws.tenant_structures.list( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + assert_matches_type(AsyncCursorPagination[TenantStructure], tenant_structure, path=["response"]) + + @parametrize + async def test_method_list_with_all_params(self, async_client: AsyncCloudflare) -> None: + tenant_structure = await async_client.zero_trust.cws.tenant_structures.list( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + cursor="cursor", + direction="asc", + import_path="import_path", + name="name", + order="name", + per_page=1, + ) + assert_matches_type(AsyncCursorPagination[TenantStructure], tenant_structure, path=["response"]) + + @parametrize + async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.cws.tenant_structures.with_raw_response.list( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + tenant_structure = await response.parse() + assert_matches_type(AsyncCursorPagination[TenantStructure], tenant_structure, path=["response"]) + + @parametrize + async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.cws.tenant_structures.with_streaming_response.list( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + tenant_structure = await response.parse() + assert_matches_type(AsyncCursorPagination[TenantStructure], tenant_structure, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_list(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.cws.tenant_structures.with_raw_response.list( + account_id="", + ) + + @parametrize + async def test_method_delete(self, async_client: AsyncCloudflare) -> None: + tenant_structure = await async_client.zero_trust.cws.tenant_structures.delete( + structure_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + assert_matches_type(TenantStructureDeleteResponse, tenant_structure, path=["response"]) + + @parametrize + async def test_raw_response_delete(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.cws.tenant_structures.with_raw_response.delete( + structure_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + tenant_structure = await response.parse() + assert_matches_type(TenantStructureDeleteResponse, tenant_structure, path=["response"]) + + @parametrize + async def test_streaming_response_delete(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.cws.tenant_structures.with_streaming_response.delete( + structure_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + tenant_structure = await response.parse() + assert_matches_type(TenantStructureDeleteResponse, tenant_structure, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_delete(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.cws.tenant_structures.with_raw_response.delete( + structure_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `structure_id` but received ''"): + await async_client.zero_trust.cws.tenant_structures.with_raw_response.delete( + structure_id="", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + + @parametrize + async def test_method_get(self, async_client: AsyncCloudflare) -> None: + tenant_structure = await async_client.zero_trust.cws.tenant_structures.get( + structure_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + assert_matches_type(TenantStructure, tenant_structure, path=["response"]) + + @parametrize + async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.cws.tenant_structures.with_raw_response.get( + structure_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + tenant_structure = await response.parse() + assert_matches_type(TenantStructure, tenant_structure, path=["response"]) + + @parametrize + async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.cws.tenant_structures.with_streaming_response.get( + structure_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + tenant_structure = await response.parse() + assert_matches_type(TenantStructure, tenant_structure, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_get(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.cws.tenant_structures.with_raw_response.get( + structure_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `structure_id` but received ''"): + await async_client.zero_trust.cws.tenant_structures.with_raw_response.get( + structure_id="", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) diff --git a/tests/api_resources/zero_trust/cws/test_workloads.py b/tests/api_resources/zero_trust/cws/test_workloads.py new file mode 100644 index 00000000000..29bbfd3e66d --- /dev/null +++ b/tests/api_resources/zero_trust/cws/test_workloads.py @@ -0,0 +1,576 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import os +from typing import Any, cast + +import pytest + +from cloudflare import Cloudflare, AsyncCloudflare +from tests.utils import assert_matches_type +from cloudflare.pagination import SyncCursorPagination, AsyncCursorPagination +from cloudflare.types.zero_trust.cws import ( + Workload, + WorkloadDeleteResponse, +) + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestWorkloads: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @parametrize + def test_method_create(self, client: Cloudflare) -> None: + workload = client.zero_trust.cws.workloads.create( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + filter="x", + name="x", + ) + assert_matches_type(Workload, workload, path=["response"]) + + @parametrize + def test_method_create_with_all_params(self, client: Cloudflare) -> None: + workload = client.zero_trust.cws.workloads.create( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + filter="x", + name="x", + description="description", + tags={"foo": "string"}, + ) + assert_matches_type(Workload, workload, path=["response"]) + + @parametrize + def test_raw_response_create(self, client: Cloudflare) -> None: + response = client.zero_trust.cws.workloads.with_raw_response.create( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + filter="x", + name="x", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + workload = response.parse() + assert_matches_type(Workload, workload, path=["response"]) + + @parametrize + def test_streaming_response_create(self, client: Cloudflare) -> None: + with client.zero_trust.cws.workloads.with_streaming_response.create( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + filter="x", + name="x", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + workload = response.parse() + assert_matches_type(Workload, workload, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_create(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.cws.workloads.with_raw_response.create( + account_id="", + filter="x", + name="x", + ) + + @parametrize + def test_method_update(self, client: Cloudflare) -> None: + workload = client.zero_trust.cws.workloads.update( + workload_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + filter="x", + name="x", + ) + assert_matches_type(Workload, workload, path=["response"]) + + @parametrize + def test_method_update_with_all_params(self, client: Cloudflare) -> None: + workload = client.zero_trust.cws.workloads.update( + workload_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + filter="x", + name="x", + description="description", + tags={"foo": "string"}, + ) + assert_matches_type(Workload, workload, path=["response"]) + + @parametrize + def test_raw_response_update(self, client: Cloudflare) -> None: + response = client.zero_trust.cws.workloads.with_raw_response.update( + workload_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + filter="x", + name="x", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + workload = response.parse() + assert_matches_type(Workload, workload, path=["response"]) + + @parametrize + def test_streaming_response_update(self, client: Cloudflare) -> None: + with client.zero_trust.cws.workloads.with_streaming_response.update( + workload_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + filter="x", + name="x", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + workload = response.parse() + assert_matches_type(Workload, workload, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_update(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.cws.workloads.with_raw_response.update( + workload_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + filter="x", + name="x", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `workload_id` but received ''"): + client.zero_trust.cws.workloads.with_raw_response.update( + workload_id="", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + filter="x", + name="x", + ) + + @parametrize + def test_method_list(self, client: Cloudflare) -> None: + workload = client.zero_trust.cws.workloads.list( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + assert_matches_type(SyncCursorPagination[Workload], workload, path=["response"]) + + @parametrize + def test_method_list_with_all_params(self, client: Cloudflare) -> None: + workload = client.zero_trust.cws.workloads.list( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + cursor="cursor", + direction="asc", + name="name", + order="name", + per_page=1, + policy_set_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(SyncCursorPagination[Workload], workload, path=["response"]) + + @parametrize + def test_raw_response_list(self, client: Cloudflare) -> None: + response = client.zero_trust.cws.workloads.with_raw_response.list( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + workload = response.parse() + assert_matches_type(SyncCursorPagination[Workload], workload, path=["response"]) + + @parametrize + def test_streaming_response_list(self, client: Cloudflare) -> None: + with client.zero_trust.cws.workloads.with_streaming_response.list( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + workload = response.parse() + assert_matches_type(SyncCursorPagination[Workload], workload, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_list(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.cws.workloads.with_raw_response.list( + account_id="", + ) + + @parametrize + def test_method_delete(self, client: Cloudflare) -> None: + workload = client.zero_trust.cws.workloads.delete( + workload_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + assert_matches_type(WorkloadDeleteResponse, workload, path=["response"]) + + @parametrize + def test_raw_response_delete(self, client: Cloudflare) -> None: + response = client.zero_trust.cws.workloads.with_raw_response.delete( + workload_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + workload = response.parse() + assert_matches_type(WorkloadDeleteResponse, workload, path=["response"]) + + @parametrize + def test_streaming_response_delete(self, client: Cloudflare) -> None: + with client.zero_trust.cws.workloads.with_streaming_response.delete( + workload_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + workload = response.parse() + assert_matches_type(WorkloadDeleteResponse, workload, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_delete(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.cws.workloads.with_raw_response.delete( + workload_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `workload_id` but received ''"): + client.zero_trust.cws.workloads.with_raw_response.delete( + workload_id="", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + + @parametrize + def test_method_get(self, client: Cloudflare) -> None: + workload = client.zero_trust.cws.workloads.get( + workload_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + assert_matches_type(Workload, workload, path=["response"]) + + @parametrize + def test_raw_response_get(self, client: Cloudflare) -> None: + response = client.zero_trust.cws.workloads.with_raw_response.get( + workload_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + workload = response.parse() + assert_matches_type(Workload, workload, path=["response"]) + + @parametrize + def test_streaming_response_get(self, client: Cloudflare) -> None: + with client.zero_trust.cws.workloads.with_streaming_response.get( + workload_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + workload = response.parse() + assert_matches_type(Workload, workload, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_get(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.cws.workloads.with_raw_response.get( + workload_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `workload_id` but received ''"): + client.zero_trust.cws.workloads.with_raw_response.get( + workload_id="", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + + +class TestAsyncWorkloads: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @parametrize + async def test_method_create(self, async_client: AsyncCloudflare) -> None: + workload = await async_client.zero_trust.cws.workloads.create( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + filter="x", + name="x", + ) + assert_matches_type(Workload, workload, path=["response"]) + + @parametrize + async def test_method_create_with_all_params(self, async_client: AsyncCloudflare) -> None: + workload = await async_client.zero_trust.cws.workloads.create( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + filter="x", + name="x", + description="description", + tags={"foo": "string"}, + ) + assert_matches_type(Workload, workload, path=["response"]) + + @parametrize + async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.cws.workloads.with_raw_response.create( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + filter="x", + name="x", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + workload = await response.parse() + assert_matches_type(Workload, workload, path=["response"]) + + @parametrize + async def test_streaming_response_create(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.cws.workloads.with_streaming_response.create( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + filter="x", + name="x", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + workload = await response.parse() + assert_matches_type(Workload, workload, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_create(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.cws.workloads.with_raw_response.create( + account_id="", + filter="x", + name="x", + ) + + @parametrize + async def test_method_update(self, async_client: AsyncCloudflare) -> None: + workload = await async_client.zero_trust.cws.workloads.update( + workload_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + filter="x", + name="x", + ) + assert_matches_type(Workload, workload, path=["response"]) + + @parametrize + async def test_method_update_with_all_params(self, async_client: AsyncCloudflare) -> None: + workload = await async_client.zero_trust.cws.workloads.update( + workload_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + filter="x", + name="x", + description="description", + tags={"foo": "string"}, + ) + assert_matches_type(Workload, workload, path=["response"]) + + @parametrize + async def test_raw_response_update(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.cws.workloads.with_raw_response.update( + workload_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + filter="x", + name="x", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + workload = await response.parse() + assert_matches_type(Workload, workload, path=["response"]) + + @parametrize + async def test_streaming_response_update(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.cws.workloads.with_streaming_response.update( + workload_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + filter="x", + name="x", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + workload = await response.parse() + assert_matches_type(Workload, workload, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_update(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.cws.workloads.with_raw_response.update( + workload_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + filter="x", + name="x", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `workload_id` but received ''"): + await async_client.zero_trust.cws.workloads.with_raw_response.update( + workload_id="", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + filter="x", + name="x", + ) + + @parametrize + async def test_method_list(self, async_client: AsyncCloudflare) -> None: + workload = await async_client.zero_trust.cws.workloads.list( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + assert_matches_type(AsyncCursorPagination[Workload], workload, path=["response"]) + + @parametrize + async def test_method_list_with_all_params(self, async_client: AsyncCloudflare) -> None: + workload = await async_client.zero_trust.cws.workloads.list( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + cursor="cursor", + direction="asc", + name="name", + order="name", + per_page=1, + policy_set_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(AsyncCursorPagination[Workload], workload, path=["response"]) + + @parametrize + async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.cws.workloads.with_raw_response.list( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + workload = await response.parse() + assert_matches_type(AsyncCursorPagination[Workload], workload, path=["response"]) + + @parametrize + async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.cws.workloads.with_streaming_response.list( + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + workload = await response.parse() + assert_matches_type(AsyncCursorPagination[Workload], workload, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_list(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.cws.workloads.with_raw_response.list( + account_id="", + ) + + @parametrize + async def test_method_delete(self, async_client: AsyncCloudflare) -> None: + workload = await async_client.zero_trust.cws.workloads.delete( + workload_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + assert_matches_type(WorkloadDeleteResponse, workload, path=["response"]) + + @parametrize + async def test_raw_response_delete(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.cws.workloads.with_raw_response.delete( + workload_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + workload = await response.parse() + assert_matches_type(WorkloadDeleteResponse, workload, path=["response"]) + + @parametrize + async def test_streaming_response_delete(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.cws.workloads.with_streaming_response.delete( + workload_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + workload = await response.parse() + assert_matches_type(WorkloadDeleteResponse, workload, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_delete(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.cws.workloads.with_raw_response.delete( + workload_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `workload_id` but received ''"): + await async_client.zero_trust.cws.workloads.with_raw_response.delete( + workload_id="", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + + @parametrize + async def test_method_get(self, async_client: AsyncCloudflare) -> None: + workload = await async_client.zero_trust.cws.workloads.get( + workload_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + assert_matches_type(Workload, workload, path=["response"]) + + @parametrize + async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.cws.workloads.with_raw_response.get( + workload_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + workload = await response.parse() + assert_matches_type(Workload, workload, path=["response"]) + + @parametrize + async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.cws.workloads.with_streaming_response.get( + workload_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + workload = await response.parse() + assert_matches_type(Workload, workload, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_get(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.cws.workloads.with_raw_response.get( + workload_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `workload_id` but received ''"): + await async_client.zero_trust.cws.workloads.with_raw_response.get( + workload_id="", + account_id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + ) diff --git a/tests/api_resources/zero_trust/devices/policies/test_custom.py b/tests/api_resources/zero_trust/devices/policies/test_custom.py index 0e56c102caf..d8c56f41a49 100644 --- a/tests/api_resources/zero_trust/devices/policies/test_custom.py +++ b/tests/api_resources/zero_trust/devices/policies/test_custom.py @@ -51,6 +51,7 @@ def test_method_create_with_all_params(self, client: Cloudflare) -> None: "description": "Example internal domains", } ], + enable_device_credential_authentication=False, enabled=True, exclude=[ { @@ -64,6 +65,7 @@ def test_method_create_with_all_params(self, client: Cloudflare) -> None: "enabled": True, "masque_endpoints": ["198.51.100.1:443"], "wireguard_endpoints": ["198.51.100.1:2408"], + "allow_manual_override": True, "autoswitch": True, }, include=[ @@ -258,6 +260,7 @@ def test_method_edit_with_all_params(self, client: Cloudflare) -> None: "description": "Example internal domains", } ], + enable_device_credential_authentication=False, enabled=True, exclude=[ { @@ -271,6 +274,7 @@ def test_method_edit_with_all_params(self, client: Cloudflare) -> None: "enabled": True, "masque_endpoints": ["198.51.100.1:443"], "wireguard_endpoints": ["198.51.100.1:2408"], + "allow_manual_override": True, "autoswitch": True, }, include=[ @@ -435,6 +439,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncCloudflare "description": "Example internal domains", } ], + enable_device_credential_authentication=False, enabled=True, exclude=[ { @@ -448,6 +453,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncCloudflare "enabled": True, "masque_endpoints": ["198.51.100.1:443"], "wireguard_endpoints": ["198.51.100.1:2408"], + "allow_manual_override": True, "autoswitch": True, }, include=[ @@ -642,6 +648,7 @@ async def test_method_edit_with_all_params(self, async_client: AsyncCloudflare) "description": "Example internal domains", } ], + enable_device_credential_authentication=False, enabled=True, exclude=[ { @@ -655,6 +662,7 @@ async def test_method_edit_with_all_params(self, async_client: AsyncCloudflare) "enabled": True, "masque_endpoints": ["198.51.100.1:443"], "wireguard_endpoints": ["198.51.100.1:2408"], + "allow_manual_override": True, "autoswitch": True, }, include=[ diff --git a/tests/api_resources/zero_trust/devices/policies/test_default.py b/tests/api_resources/zero_trust/devices/policies/test_default.py index dcf15290312..78f55bba13a 100644 --- a/tests/api_resources/zero_trust/devices/policies/test_default.py +++ b/tests/api_resources/zero_trust/devices/policies/test_default.py @@ -40,6 +40,7 @@ def test_method_edit_with_all_params(self, client: Cloudflare) -> None: "description": "Example internal domains", } ], + enable_device_credential_authentication=False, exclude=[ { "address": "192.0.2.0/24", @@ -52,6 +53,7 @@ def test_method_edit_with_all_params(self, client: Cloudflare) -> None: "enabled": True, "masque_endpoints": ["198.51.100.1:443"], "wireguard_endpoints": ["198.51.100.1:2408"], + "allow_manual_override": True, "autoswitch": True, }, include=[ @@ -177,6 +179,7 @@ async def test_method_edit_with_all_params(self, async_client: AsyncCloudflare) "description": "Example internal domains", } ], + enable_device_credential_authentication=False, exclude=[ { "address": "192.0.2.0/24", @@ -189,6 +192,7 @@ async def test_method_edit_with_all_params(self, async_client: AsyncCloudflare) "enabled": True, "masque_endpoints": ["198.51.100.1:443"], "wireguard_endpoints": ["198.51.100.1:2408"], + "allow_manual_override": True, "autoswitch": True, }, include=[ diff --git a/tests/api_resources/zero_trust/dlp/entries/test_custom.py b/tests/api_resources/zero_trust/dlp/entries/test_custom.py index 203e9acb871..b19456b408a 100644 --- a/tests/api_resources/zero_trust/dlp/entries/test_custom.py +++ b/tests/api_resources/zero_trust/dlp/entries/test_custom.py @@ -45,6 +45,7 @@ def test_method_create_with_all_params(self, client: Cloudflare) -> None: }, description="description", profile_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + validator_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], ) assert_matches_type(Optional[CustomCreateResponse], custom, path=["response"]) @@ -113,6 +114,7 @@ def test_method_update_with_all_params(self, client: Cloudflare) -> None: "validation": "luhn", }, description="description", + validator_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], ) assert_matches_type(Optional[CustomUpdateResponse], custom, path=["response"]) @@ -333,6 +335,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncCloudflare }, description="description", profile_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + validator_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], ) assert_matches_type(Optional[CustomCreateResponse], custom, path=["response"]) @@ -401,6 +404,7 @@ async def test_method_update_with_all_params(self, async_client: AsyncCloudflare "validation": "luhn", }, description="description", + validator_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], ) assert_matches_type(Optional[CustomUpdateResponse], custom, path=["response"]) diff --git a/tests/api_resources/zero_trust/dlp/test_entries.py b/tests/api_resources/zero_trust/dlp/test_entries.py index 55ef6364827..17a39406e79 100644 --- a/tests/api_resources/zero_trust/dlp/test_entries.py +++ b/tests/api_resources/zero_trust/dlp/test_entries.py @@ -45,6 +45,7 @@ def test_method_create_with_all_params(self, client: Cloudflare) -> None: }, description="description", profile_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + validator_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], ) assert_matches_type(Optional[EntryCreateResponse], entry, path=["response"]) @@ -114,6 +115,7 @@ def test_method_update_with_all_params_overload_1(self, client: Cloudflare) -> N type="custom", description="description", enabled=True, + validator_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], ) assert_matches_type(Optional[EntryUpdateResponse], entry, path=["response"]) @@ -470,6 +472,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncCloudflare }, description="description", profile_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + validator_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], ) assert_matches_type(Optional[EntryCreateResponse], entry, path=["response"]) @@ -539,6 +542,7 @@ async def test_method_update_with_all_params_overload_1(self, async_client: Asyn type="custom", description="description", enabled=True, + validator_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], ) assert_matches_type(Optional[EntryUpdateResponse], entry, path=["response"]) diff --git a/tests/api_resources/zero_trust/dlp/test_validators.py b/tests/api_resources/zero_trust/dlp/test_validators.py new file mode 100644 index 00000000000..b1f641adcf2 --- /dev/null +++ b/tests/api_resources/zero_trust/dlp/test_validators.py @@ -0,0 +1,213 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import os +from typing import Any, Optional, cast + +import pytest + +from cloudflare import Cloudflare, AsyncCloudflare +from tests.utils import assert_matches_type +from cloudflare.pagination import SyncSinglePage, AsyncSinglePage +from cloudflare.types.zero_trust.dlp import Validator + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestValidators: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @parametrize + def test_method_list(self, client: Cloudflare) -> None: + validator = client.zero_trust.dlp.validators.list( + account_id="account_id", + ) + assert_matches_type(SyncSinglePage[Validator], validator, path=["response"]) + + @parametrize + def test_method_list_with_all_params(self, client: Cloudflare) -> None: + validator = client.zero_trust.dlp.validators.list( + account_id="account_id", + kind="proximity_words", + ) + assert_matches_type(SyncSinglePage[Validator], validator, path=["response"]) + + @parametrize + def test_raw_response_list(self, client: Cloudflare) -> None: + response = client.zero_trust.dlp.validators.with_raw_response.list( + account_id="account_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + validator = response.parse() + assert_matches_type(SyncSinglePage[Validator], validator, path=["response"]) + + @parametrize + def test_streaming_response_list(self, client: Cloudflare) -> None: + with client.zero_trust.dlp.validators.with_streaming_response.list( + account_id="account_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + validator = response.parse() + assert_matches_type(SyncSinglePage[Validator], validator, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_list(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.dlp.validators.with_raw_response.list( + account_id="", + ) + + @parametrize + def test_method_get(self, client: Cloudflare) -> None: + validator = client.zero_trust.dlp.validators.get( + validator_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + ) + assert_matches_type(Optional[Validator], validator, path=["response"]) + + @parametrize + def test_raw_response_get(self, client: Cloudflare) -> None: + response = client.zero_trust.dlp.validators.with_raw_response.get( + validator_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + validator = response.parse() + assert_matches_type(Optional[Validator], validator, path=["response"]) + + @parametrize + def test_streaming_response_get(self, client: Cloudflare) -> None: + with client.zero_trust.dlp.validators.with_streaming_response.get( + validator_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + validator = response.parse() + assert_matches_type(Optional[Validator], validator, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_get(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.dlp.validators.with_raw_response.get( + validator_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `validator_id` but received ''"): + client.zero_trust.dlp.validators.with_raw_response.get( + validator_id="", + account_id="account_id", + ) + + +class TestAsyncValidators: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @parametrize + async def test_method_list(self, async_client: AsyncCloudflare) -> None: + validator = await async_client.zero_trust.dlp.validators.list( + account_id="account_id", + ) + assert_matches_type(AsyncSinglePage[Validator], validator, path=["response"]) + + @parametrize + async def test_method_list_with_all_params(self, async_client: AsyncCloudflare) -> None: + validator = await async_client.zero_trust.dlp.validators.list( + account_id="account_id", + kind="proximity_words", + ) + assert_matches_type(AsyncSinglePage[Validator], validator, path=["response"]) + + @parametrize + async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.dlp.validators.with_raw_response.list( + account_id="account_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + validator = await response.parse() + assert_matches_type(AsyncSinglePage[Validator], validator, path=["response"]) + + @parametrize + async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.dlp.validators.with_streaming_response.list( + account_id="account_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + validator = await response.parse() + assert_matches_type(AsyncSinglePage[Validator], validator, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_list(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.dlp.validators.with_raw_response.list( + account_id="", + ) + + @parametrize + async def test_method_get(self, async_client: AsyncCloudflare) -> None: + validator = await async_client.zero_trust.dlp.validators.get( + validator_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + ) + assert_matches_type(Optional[Validator], validator, path=["response"]) + + @parametrize + async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.dlp.validators.with_raw_response.get( + validator_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + validator = await response.parse() + assert_matches_type(Optional[Validator], validator, path=["response"]) + + @parametrize + async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.dlp.validators.with_streaming_response.get( + validator_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + validator = await response.parse() + assert_matches_type(Optional[Validator], validator, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_get(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.dlp.validators.with_raw_response.get( + validator_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `validator_id` but received ''"): + await async_client.zero_trust.dlp.validators.with_raw_response.get( + validator_id="", + account_id="account_id", + ) diff --git a/tests/api_resources/zero_trust/dlp/validators/__init__.py b/tests/api_resources/zero_trust/dlp/validators/__init__.py new file mode 100644 index 00000000000..fd8019a9a1a --- /dev/null +++ b/tests/api_resources/zero_trust/dlp/validators/__init__.py @@ -0,0 +1 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. diff --git a/tests/api_resources/zero_trust/dlp/validators/test_proximity_words.py b/tests/api_resources/zero_trust/dlp/validators/test_proximity_words.py new file mode 100644 index 00000000000..26b342c8a63 --- /dev/null +++ b/tests/api_resources/zero_trust/dlp/validators/test_proximity_words.py @@ -0,0 +1,593 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import os +from typing import Any, Optional, cast + +import pytest + +from cloudflare import Cloudflare, AsyncCloudflare +from tests.utils import assert_matches_type +from cloudflare.pagination import SyncSinglePage, AsyncSinglePage +from cloudflare.types.zero_trust.dlp.validators import ( + ProximityWordValidator, +) + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestProximityWords: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @parametrize + def test_method_create(self, client: Cloudflare) -> None: + proximity_word = client.zero_trust.dlp.validators.proximity_words.create( + account_id="account_id", + name="HIPAA context words", + words=[ + { + "weight": "strong", + "word": "social security number", + } + ], + ) + assert_matches_type(Optional[ProximityWordValidator], proximity_word, path=["response"]) + + @parametrize + def test_raw_response_create(self, client: Cloudflare) -> None: + response = client.zero_trust.dlp.validators.proximity_words.with_raw_response.create( + account_id="account_id", + name="HIPAA context words", + words=[ + { + "weight": "strong", + "word": "social security number", + } + ], + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + proximity_word = response.parse() + assert_matches_type(Optional[ProximityWordValidator], proximity_word, path=["response"]) + + @parametrize + def test_streaming_response_create(self, client: Cloudflare) -> None: + with client.zero_trust.dlp.validators.proximity_words.with_streaming_response.create( + account_id="account_id", + name="HIPAA context words", + words=[ + { + "weight": "strong", + "word": "social security number", + } + ], + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + proximity_word = response.parse() + assert_matches_type(Optional[ProximityWordValidator], proximity_word, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_create(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.dlp.validators.proximity_words.with_raw_response.create( + account_id="", + name="HIPAA context words", + words=[ + { + "weight": "strong", + "word": "social security number", + } + ], + ) + + @parametrize + def test_method_update(self, client: Cloudflare) -> None: + proximity_word = client.zero_trust.dlp.validators.proximity_words.update( + validator_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + name="HIPAA context words", + words=[ + { + "weight": "strong", + "word": "social security number", + } + ], + ) + assert_matches_type(Optional[ProximityWordValidator], proximity_word, path=["response"]) + + @parametrize + def test_raw_response_update(self, client: Cloudflare) -> None: + response = client.zero_trust.dlp.validators.proximity_words.with_raw_response.update( + validator_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + name="HIPAA context words", + words=[ + { + "weight": "strong", + "word": "social security number", + } + ], + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + proximity_word = response.parse() + assert_matches_type(Optional[ProximityWordValidator], proximity_word, path=["response"]) + + @parametrize + def test_streaming_response_update(self, client: Cloudflare) -> None: + with client.zero_trust.dlp.validators.proximity_words.with_streaming_response.update( + validator_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + name="HIPAA context words", + words=[ + { + "weight": "strong", + "word": "social security number", + } + ], + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + proximity_word = response.parse() + assert_matches_type(Optional[ProximityWordValidator], proximity_word, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_update(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.dlp.validators.proximity_words.with_raw_response.update( + validator_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + name="HIPAA context words", + words=[ + { + "weight": "strong", + "word": "social security number", + } + ], + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `validator_id` but received ''"): + client.zero_trust.dlp.validators.proximity_words.with_raw_response.update( + validator_id="", + account_id="account_id", + name="HIPAA context words", + words=[ + { + "weight": "strong", + "word": "social security number", + } + ], + ) + + @parametrize + def test_method_list(self, client: Cloudflare) -> None: + proximity_word = client.zero_trust.dlp.validators.proximity_words.list( + account_id="account_id", + ) + assert_matches_type(SyncSinglePage[ProximityWordValidator], proximity_word, path=["response"]) + + @parametrize + def test_raw_response_list(self, client: Cloudflare) -> None: + response = client.zero_trust.dlp.validators.proximity_words.with_raw_response.list( + account_id="account_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + proximity_word = response.parse() + assert_matches_type(SyncSinglePage[ProximityWordValidator], proximity_word, path=["response"]) + + @parametrize + def test_streaming_response_list(self, client: Cloudflare) -> None: + with client.zero_trust.dlp.validators.proximity_words.with_streaming_response.list( + account_id="account_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + proximity_word = response.parse() + assert_matches_type(SyncSinglePage[ProximityWordValidator], proximity_word, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_list(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.dlp.validators.proximity_words.with_raw_response.list( + account_id="", + ) + + @parametrize + def test_method_delete(self, client: Cloudflare) -> None: + proximity_word = client.zero_trust.dlp.validators.proximity_words.delete( + validator_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + ) + assert_matches_type(object, proximity_word, path=["response"]) + + @parametrize + def test_raw_response_delete(self, client: Cloudflare) -> None: + response = client.zero_trust.dlp.validators.proximity_words.with_raw_response.delete( + validator_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + proximity_word = response.parse() + assert_matches_type(object, proximity_word, path=["response"]) + + @parametrize + def test_streaming_response_delete(self, client: Cloudflare) -> None: + with client.zero_trust.dlp.validators.proximity_words.with_streaming_response.delete( + validator_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + proximity_word = response.parse() + assert_matches_type(object, proximity_word, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_delete(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.dlp.validators.proximity_words.with_raw_response.delete( + validator_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `validator_id` but received ''"): + client.zero_trust.dlp.validators.proximity_words.with_raw_response.delete( + validator_id="", + account_id="account_id", + ) + + @parametrize + def test_method_get(self, client: Cloudflare) -> None: + proximity_word = client.zero_trust.dlp.validators.proximity_words.get( + validator_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + ) + assert_matches_type(Optional[ProximityWordValidator], proximity_word, path=["response"]) + + @parametrize + def test_raw_response_get(self, client: Cloudflare) -> None: + response = client.zero_trust.dlp.validators.proximity_words.with_raw_response.get( + validator_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + proximity_word = response.parse() + assert_matches_type(Optional[ProximityWordValidator], proximity_word, path=["response"]) + + @parametrize + def test_streaming_response_get(self, client: Cloudflare) -> None: + with client.zero_trust.dlp.validators.proximity_words.with_streaming_response.get( + validator_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + proximity_word = response.parse() + assert_matches_type(Optional[ProximityWordValidator], proximity_word, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_get(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.dlp.validators.proximity_words.with_raw_response.get( + validator_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `validator_id` but received ''"): + client.zero_trust.dlp.validators.proximity_words.with_raw_response.get( + validator_id="", + account_id="account_id", + ) + + +class TestAsyncProximityWords: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @parametrize + async def test_method_create(self, async_client: AsyncCloudflare) -> None: + proximity_word = await async_client.zero_trust.dlp.validators.proximity_words.create( + account_id="account_id", + name="HIPAA context words", + words=[ + { + "weight": "strong", + "word": "social security number", + } + ], + ) + assert_matches_type(Optional[ProximityWordValidator], proximity_word, path=["response"]) + + @parametrize + async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.dlp.validators.proximity_words.with_raw_response.create( + account_id="account_id", + name="HIPAA context words", + words=[ + { + "weight": "strong", + "word": "social security number", + } + ], + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + proximity_word = await response.parse() + assert_matches_type(Optional[ProximityWordValidator], proximity_word, path=["response"]) + + @parametrize + async def test_streaming_response_create(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.dlp.validators.proximity_words.with_streaming_response.create( + account_id="account_id", + name="HIPAA context words", + words=[ + { + "weight": "strong", + "word": "social security number", + } + ], + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + proximity_word = await response.parse() + assert_matches_type(Optional[ProximityWordValidator], proximity_word, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_create(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.dlp.validators.proximity_words.with_raw_response.create( + account_id="", + name="HIPAA context words", + words=[ + { + "weight": "strong", + "word": "social security number", + } + ], + ) + + @parametrize + async def test_method_update(self, async_client: AsyncCloudflare) -> None: + proximity_word = await async_client.zero_trust.dlp.validators.proximity_words.update( + validator_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + name="HIPAA context words", + words=[ + { + "weight": "strong", + "word": "social security number", + } + ], + ) + assert_matches_type(Optional[ProximityWordValidator], proximity_word, path=["response"]) + + @parametrize + async def test_raw_response_update(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.dlp.validators.proximity_words.with_raw_response.update( + validator_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + name="HIPAA context words", + words=[ + { + "weight": "strong", + "word": "social security number", + } + ], + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + proximity_word = await response.parse() + assert_matches_type(Optional[ProximityWordValidator], proximity_word, path=["response"]) + + @parametrize + async def test_streaming_response_update(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.dlp.validators.proximity_words.with_streaming_response.update( + validator_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + name="HIPAA context words", + words=[ + { + "weight": "strong", + "word": "social security number", + } + ], + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + proximity_word = await response.parse() + assert_matches_type(Optional[ProximityWordValidator], proximity_word, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_update(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.dlp.validators.proximity_words.with_raw_response.update( + validator_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + name="HIPAA context words", + words=[ + { + "weight": "strong", + "word": "social security number", + } + ], + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `validator_id` but received ''"): + await async_client.zero_trust.dlp.validators.proximity_words.with_raw_response.update( + validator_id="", + account_id="account_id", + name="HIPAA context words", + words=[ + { + "weight": "strong", + "word": "social security number", + } + ], + ) + + @parametrize + async def test_method_list(self, async_client: AsyncCloudflare) -> None: + proximity_word = await async_client.zero_trust.dlp.validators.proximity_words.list( + account_id="account_id", + ) + assert_matches_type(AsyncSinglePage[ProximityWordValidator], proximity_word, path=["response"]) + + @parametrize + async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.dlp.validators.proximity_words.with_raw_response.list( + account_id="account_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + proximity_word = await response.parse() + assert_matches_type(AsyncSinglePage[ProximityWordValidator], proximity_word, path=["response"]) + + @parametrize + async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.dlp.validators.proximity_words.with_streaming_response.list( + account_id="account_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + proximity_word = await response.parse() + assert_matches_type(AsyncSinglePage[ProximityWordValidator], proximity_word, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_list(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.dlp.validators.proximity_words.with_raw_response.list( + account_id="", + ) + + @parametrize + async def test_method_delete(self, async_client: AsyncCloudflare) -> None: + proximity_word = await async_client.zero_trust.dlp.validators.proximity_words.delete( + validator_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + ) + assert_matches_type(object, proximity_word, path=["response"]) + + @parametrize + async def test_raw_response_delete(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.dlp.validators.proximity_words.with_raw_response.delete( + validator_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + proximity_word = await response.parse() + assert_matches_type(object, proximity_word, path=["response"]) + + @parametrize + async def test_streaming_response_delete(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.dlp.validators.proximity_words.with_streaming_response.delete( + validator_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + proximity_word = await response.parse() + assert_matches_type(object, proximity_word, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_delete(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.dlp.validators.proximity_words.with_raw_response.delete( + validator_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `validator_id` but received ''"): + await async_client.zero_trust.dlp.validators.proximity_words.with_raw_response.delete( + validator_id="", + account_id="account_id", + ) + + @parametrize + async def test_method_get(self, async_client: AsyncCloudflare) -> None: + proximity_word = await async_client.zero_trust.dlp.validators.proximity_words.get( + validator_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + ) + assert_matches_type(Optional[ProximityWordValidator], proximity_word, path=["response"]) + + @parametrize + async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.dlp.validators.proximity_words.with_raw_response.get( + validator_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + proximity_word = await response.parse() + assert_matches_type(Optional[ProximityWordValidator], proximity_word, path=["response"]) + + @parametrize + async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.dlp.validators.proximity_words.with_streaming_response.get( + validator_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + proximity_word = await response.parse() + assert_matches_type(Optional[ProximityWordValidator], proximity_word, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_get(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.dlp.validators.proximity_words.with_raw_response.get( + validator_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `validator_id` but received ''"): + await async_client.zero_trust.dlp.validators.proximity_words.with_raw_response.get( + validator_id="", + account_id="account_id", + ) diff --git a/tests/api_resources/tenants/test_memberships.py b/tests/api_resources/zero_trust/gateway/test_dns_destination_ips.py similarity index 50% rename from tests/api_resources/tenants/test_memberships.py rename to tests/api_resources/zero_trust/gateway/test_dns_destination_ips.py index fd70477e87f..e8596a27d62 100644 --- a/tests/api_resources/tenants/test_memberships.py +++ b/tests/api_resources/zero_trust/gateway/test_dns_destination_ips.py @@ -10,92 +10,92 @@ from cloudflare import Cloudflare, AsyncCloudflare from tests.utils import assert_matches_type from cloudflare.pagination import SyncSinglePage, AsyncSinglePage -from cloudflare.types.tenants import TenantMembership +from cloudflare.types.zero_trust.gateway import DNSDestinationIPListResponse base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") -class TestMemberships: +class TestDNSDestinationIPs: parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) @parametrize def test_method_list(self, client: Cloudflare) -> None: - membership = client.tenants.memberships.list( - "tenant_id", + dns_destination_ip = client.zero_trust.gateway.dns_destination_ips.list( + account_id="699d98642c564d2e855e9661899b7252", ) - assert_matches_type(SyncSinglePage[TenantMembership], membership, path=["response"]) + assert_matches_type(SyncSinglePage[DNSDestinationIPListResponse], dns_destination_ip, path=["response"]) @parametrize def test_raw_response_list(self, client: Cloudflare) -> None: - response = client.tenants.memberships.with_raw_response.list( - "tenant_id", + response = client.zero_trust.gateway.dns_destination_ips.with_raw_response.list( + account_id="699d98642c564d2e855e9661899b7252", ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" - membership = response.parse() - assert_matches_type(SyncSinglePage[TenantMembership], membership, path=["response"]) + dns_destination_ip = response.parse() + assert_matches_type(SyncSinglePage[DNSDestinationIPListResponse], dns_destination_ip, path=["response"]) @parametrize def test_streaming_response_list(self, client: Cloudflare) -> None: - with client.tenants.memberships.with_streaming_response.list( - "tenant_id", + with client.zero_trust.gateway.dns_destination_ips.with_streaming_response.list( + account_id="699d98642c564d2e855e9661899b7252", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" - membership = response.parse() - assert_matches_type(SyncSinglePage[TenantMembership], membership, path=["response"]) + dns_destination_ip = response.parse() + assert_matches_type(SyncSinglePage[DNSDestinationIPListResponse], dns_destination_ip, path=["response"]) assert cast(Any, response.is_closed) is True @parametrize def test_path_params_list(self, client: Cloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `tenant_id` but received ''"): - client.tenants.memberships.with_raw_response.list( - "", + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.gateway.dns_destination_ips.with_raw_response.list( + account_id="", ) -class TestAsyncMemberships: +class TestAsyncDNSDestinationIPs: parametrize = pytest.mark.parametrize( "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] ) @parametrize async def test_method_list(self, async_client: AsyncCloudflare) -> None: - membership = await async_client.tenants.memberships.list( - "tenant_id", + dns_destination_ip = await async_client.zero_trust.gateway.dns_destination_ips.list( + account_id="699d98642c564d2e855e9661899b7252", ) - assert_matches_type(AsyncSinglePage[TenantMembership], membership, path=["response"]) + assert_matches_type(AsyncSinglePage[DNSDestinationIPListResponse], dns_destination_ip, path=["response"]) @parametrize async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None: - response = await async_client.tenants.memberships.with_raw_response.list( - "tenant_id", + response = await async_client.zero_trust.gateway.dns_destination_ips.with_raw_response.list( + account_id="699d98642c564d2e855e9661899b7252", ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" - membership = await response.parse() - assert_matches_type(AsyncSinglePage[TenantMembership], membership, path=["response"]) + dns_destination_ip = await response.parse() + assert_matches_type(AsyncSinglePage[DNSDestinationIPListResponse], dns_destination_ip, path=["response"]) @parametrize async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> None: - async with async_client.tenants.memberships.with_streaming_response.list( - "tenant_id", + async with async_client.zero_trust.gateway.dns_destination_ips.with_streaming_response.list( + account_id="699d98642c564d2e855e9661899b7252", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" - membership = await response.parse() - assert_matches_type(AsyncSinglePage[TenantMembership], membership, path=["response"]) + dns_destination_ip = await response.parse() + assert_matches_type(AsyncSinglePage[DNSDestinationIPListResponse], dns_destination_ip, path=["response"]) assert cast(Any, response.is_closed) is True @parametrize async def test_path_params_list(self, async_client: AsyncCloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `tenant_id` but received ''"): - await async_client.tenants.memberships.with_raw_response.list( - "", + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.gateway.dns_destination_ips.with_raw_response.list( + account_id="", ) diff --git a/tests/api_resources/zero_trust/gateway/test_locations.py b/tests/api_resources/zero_trust/gateway/test_locations.py index a7bf9242abe..cedd02677fc 100644 --- a/tests/api_resources/zero_trust/gateway/test_locations.py +++ b/tests/api_resources/zero_trust/gateway/test_locations.py @@ -35,6 +35,7 @@ def test_method_create_with_all_params(self, client: Cloudflare) -> None: name="Austin Office Location", client_default=False, dns_destination_ips_id="0e4a32c6-6fb8-4858-9296-98f51631e8e6", + dns64_enabled=False, ecs_support=False, endpoints={ "doh": { @@ -111,6 +112,7 @@ def test_method_update_with_all_params(self, client: Cloudflare) -> None: name="Austin Office Location", client_default=False, dns_destination_ips_id="0e4a32c6-6fb8-4858-9296-98f51631e8e6", + dns64_enabled=False, ecs_support=False, endpoints={ "doh": { @@ -346,6 +348,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncCloudflare name="Austin Office Location", client_default=False, dns_destination_ips_id="0e4a32c6-6fb8-4858-9296-98f51631e8e6", + dns64_enabled=False, ecs_support=False, endpoints={ "doh": { @@ -422,6 +425,7 @@ async def test_method_update_with_all_params(self, async_client: AsyncCloudflare name="Austin Office Location", client_default=False, dns_destination_ips_id="0e4a32c6-6fb8-4858-9296-98f51631e8e6", + dns64_enabled=False, ecs_support=False, endpoints={ "doh": { diff --git a/tests/api_resources/zero_trust/gateway/test_rules.py b/tests/api_resources/zero_trust/gateway/test_rules.py index 7a6a36a9535..ab01faf28c8 100644 --- a/tests/api_resources/zero_trust/gateway/test_rules.py +++ b/tests/api_resources/zero_trust/gateway/test_rules.py @@ -52,7 +52,6 @@ def test_method_create_with_all_params(self, client: Cloudflare) -> None: "X-Custom-Header-Name": ["somecustomvalue"], }, "allow_child_bypass": False, - "audit_ssh": {"command_logging": False}, "biso_admin_controls": { "copy": "remote_only", "dcp": True, @@ -104,6 +103,7 @@ def test_method_create_with_all_params(self, client: Cloudflare) -> None: "ipv6": "2001:DB8::/64", }, "forensic_copy": {"enabled": True}, + "forward": {"worker_id": "0123456789abcdef0123456789abcdef"}, "ignore_cname_category_matches": True, "insecure_disable_dnssec_validation": False, "ip_categories": True, @@ -219,7 +219,6 @@ def test_method_update_with_all_params(self, client: Cloudflare) -> None: "X-Custom-Header-Name": ["somecustomvalue"], }, "allow_child_bypass": False, - "audit_ssh": {"command_logging": False}, "biso_admin_controls": { "copy": "remote_only", "dcp": True, @@ -271,6 +270,7 @@ def test_method_update_with_all_params(self, client: Cloudflare) -> None: "ipv6": "2001:DB8::/64", }, "forensic_copy": {"enabled": True}, + "forward": {"worker_id": "0123456789abcdef0123456789abcdef"}, "ignore_cname_category_matches": True, "insecure_disable_dnssec_validation": False, "ip_categories": True, @@ -632,7 +632,6 @@ async def test_method_create_with_all_params(self, async_client: AsyncCloudflare "X-Custom-Header-Name": ["somecustomvalue"], }, "allow_child_bypass": False, - "audit_ssh": {"command_logging": False}, "biso_admin_controls": { "copy": "remote_only", "dcp": True, @@ -684,6 +683,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncCloudflare "ipv6": "2001:DB8::/64", }, "forensic_copy": {"enabled": True}, + "forward": {"worker_id": "0123456789abcdef0123456789abcdef"}, "ignore_cname_category_matches": True, "insecure_disable_dnssec_validation": False, "ip_categories": True, @@ -799,7 +799,6 @@ async def test_method_update_with_all_params(self, async_client: AsyncCloudflare "X-Custom-Header-Name": ["somecustomvalue"], }, "allow_child_bypass": False, - "audit_ssh": {"command_logging": False}, "biso_admin_controls": { "copy": "remote_only", "dcp": True, @@ -851,6 +850,7 @@ async def test_method_update_with_all_params(self, async_client: AsyncCloudflare "ipv6": "2001:DB8::/64", }, "forensic_copy": {"enabled": True}, + "forward": {"worker_id": "0123456789abcdef0123456789abcdef"}, "ignore_cname_category_matches": True, "insecure_disable_dnssec_validation": False, "ip_categories": True, diff --git a/tests/api_resources/zero_trust/identity_providers/scim/test_groups.py b/tests/api_resources/zero_trust/identity_providers/scim/test_groups.py index ec0416409d6..b3cdb4af41e 100644 --- a/tests/api_resources/zero_trust/identity_providers/scim/test_groups.py +++ b/tests/api_resources/zero_trust/identity_providers/scim/test_groups.py @@ -3,7 +3,7 @@ from __future__ import annotations import os -from typing import Any, cast +from typing import Any, Optional, cast import pytest @@ -11,6 +11,7 @@ from tests.utils import assert_matches_type from cloudflare.pagination import SyncV4PagePaginationArray, AsyncV4PagePaginationArray from cloudflare.types.zero_trust.access import ZeroTrustGroup +from cloudflare.types.zero_trust.identity_providers.scim import GroupGetResponse base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") @@ -79,6 +80,126 @@ def test_path_params_list(self, client: Cloudflare) -> None: account_id="023e105f4ecef8ad9ca31a8372d0c353", ) + @parametrize + def test_method_delete(self, client: Cloudflare) -> None: + group = client.zero_trust.identity_providers.scim.groups.delete( + group_id="023e105f4ecef8ad9ca31a8372d0c353", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + identity_provider_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + ) + assert group is None + + @parametrize + def test_raw_response_delete(self, client: Cloudflare) -> None: + response = client.zero_trust.identity_providers.scim.groups.with_raw_response.delete( + group_id="023e105f4ecef8ad9ca31a8372d0c353", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + identity_provider_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + group = response.parse() + assert group is None + + @parametrize + def test_streaming_response_delete(self, client: Cloudflare) -> None: + with client.zero_trust.identity_providers.scim.groups.with_streaming_response.delete( + group_id="023e105f4ecef8ad9ca31a8372d0c353", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + identity_provider_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + group = response.parse() + assert group is None + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_delete(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.identity_providers.scim.groups.with_raw_response.delete( + group_id="023e105f4ecef8ad9ca31a8372d0c353", + account_id="", + identity_provider_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `identity_provider_id` but received ''"): + client.zero_trust.identity_providers.scim.groups.with_raw_response.delete( + group_id="023e105f4ecef8ad9ca31a8372d0c353", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + identity_provider_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `group_id` but received ''"): + client.zero_trust.identity_providers.scim.groups.with_raw_response.delete( + group_id="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + identity_provider_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + ) + + @parametrize + def test_method_get(self, client: Cloudflare) -> None: + group = client.zero_trust.identity_providers.scim.groups.get( + group_id="023e105f4ecef8ad9ca31a8372d0c353", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + identity_provider_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + ) + assert_matches_type(Optional[GroupGetResponse], group, path=["response"]) + + @parametrize + def test_raw_response_get(self, client: Cloudflare) -> None: + response = client.zero_trust.identity_providers.scim.groups.with_raw_response.get( + group_id="023e105f4ecef8ad9ca31a8372d0c353", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + identity_provider_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + group = response.parse() + assert_matches_type(Optional[GroupGetResponse], group, path=["response"]) + + @parametrize + def test_streaming_response_get(self, client: Cloudflare) -> None: + with client.zero_trust.identity_providers.scim.groups.with_streaming_response.get( + group_id="023e105f4ecef8ad9ca31a8372d0c353", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + identity_provider_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + group = response.parse() + assert_matches_type(Optional[GroupGetResponse], group, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_get(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.identity_providers.scim.groups.with_raw_response.get( + group_id="023e105f4ecef8ad9ca31a8372d0c353", + account_id="", + identity_provider_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `identity_provider_id` but received ''"): + client.zero_trust.identity_providers.scim.groups.with_raw_response.get( + group_id="023e105f4ecef8ad9ca31a8372d0c353", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + identity_provider_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `group_id` but received ''"): + client.zero_trust.identity_providers.scim.groups.with_raw_response.get( + group_id="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + identity_provider_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + ) + class TestAsyncGroups: parametrize = pytest.mark.parametrize( @@ -145,3 +266,123 @@ async def test_path_params_list(self, async_client: AsyncCloudflare) -> None: identity_provider_id="", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) + + @parametrize + async def test_method_delete(self, async_client: AsyncCloudflare) -> None: + group = await async_client.zero_trust.identity_providers.scim.groups.delete( + group_id="023e105f4ecef8ad9ca31a8372d0c353", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + identity_provider_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + ) + assert group is None + + @parametrize + async def test_raw_response_delete(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.identity_providers.scim.groups.with_raw_response.delete( + group_id="023e105f4ecef8ad9ca31a8372d0c353", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + identity_provider_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + group = await response.parse() + assert group is None + + @parametrize + async def test_streaming_response_delete(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.identity_providers.scim.groups.with_streaming_response.delete( + group_id="023e105f4ecef8ad9ca31a8372d0c353", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + identity_provider_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + group = await response.parse() + assert group is None + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_delete(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.identity_providers.scim.groups.with_raw_response.delete( + group_id="023e105f4ecef8ad9ca31a8372d0c353", + account_id="", + identity_provider_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `identity_provider_id` but received ''"): + await async_client.zero_trust.identity_providers.scim.groups.with_raw_response.delete( + group_id="023e105f4ecef8ad9ca31a8372d0c353", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + identity_provider_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `group_id` but received ''"): + await async_client.zero_trust.identity_providers.scim.groups.with_raw_response.delete( + group_id="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + identity_provider_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + ) + + @parametrize + async def test_method_get(self, async_client: AsyncCloudflare) -> None: + group = await async_client.zero_trust.identity_providers.scim.groups.get( + group_id="023e105f4ecef8ad9ca31a8372d0c353", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + identity_provider_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + ) + assert_matches_type(Optional[GroupGetResponse], group, path=["response"]) + + @parametrize + async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.identity_providers.scim.groups.with_raw_response.get( + group_id="023e105f4ecef8ad9ca31a8372d0c353", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + identity_provider_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + group = await response.parse() + assert_matches_type(Optional[GroupGetResponse], group, path=["response"]) + + @parametrize + async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.identity_providers.scim.groups.with_streaming_response.get( + group_id="023e105f4ecef8ad9ca31a8372d0c353", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + identity_provider_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + group = await response.parse() + assert_matches_type(Optional[GroupGetResponse], group, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_get(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.identity_providers.scim.groups.with_raw_response.get( + group_id="023e105f4ecef8ad9ca31a8372d0c353", + account_id="", + identity_provider_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `identity_provider_id` but received ''"): + await async_client.zero_trust.identity_providers.scim.groups.with_raw_response.get( + group_id="023e105f4ecef8ad9ca31a8372d0c353", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + identity_provider_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `group_id` but received ''"): + await async_client.zero_trust.identity_providers.scim.groups.with_raw_response.get( + group_id="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + identity_provider_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + ) diff --git a/tests/api_resources/zero_trust/identity_providers/scim/test_users.py b/tests/api_resources/zero_trust/identity_providers/scim/test_users.py index 6750d8d9774..033109f302b 100644 --- a/tests/api_resources/zero_trust/identity_providers/scim/test_users.py +++ b/tests/api_resources/zero_trust/identity_providers/scim/test_users.py @@ -3,7 +3,7 @@ from __future__ import annotations import os -from typing import Any, cast +from typing import Any, Optional, cast import pytest @@ -81,6 +81,126 @@ def test_path_params_list(self, client: Cloudflare) -> None: account_id="023e105f4ecef8ad9ca31a8372d0c353", ) + @parametrize + def test_method_delete(self, client: Cloudflare) -> None: + user = client.zero_trust.identity_providers.scim.users.delete( + user_id="023e105f4ecef8ad9ca31a8372d0c353", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + identity_provider_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + ) + assert user is None + + @parametrize + def test_raw_response_delete(self, client: Cloudflare) -> None: + response = client.zero_trust.identity_providers.scim.users.with_raw_response.delete( + user_id="023e105f4ecef8ad9ca31a8372d0c353", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + identity_provider_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + user = response.parse() + assert user is None + + @parametrize + def test_streaming_response_delete(self, client: Cloudflare) -> None: + with client.zero_trust.identity_providers.scim.users.with_streaming_response.delete( + user_id="023e105f4ecef8ad9ca31a8372d0c353", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + identity_provider_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + user = response.parse() + assert user is None + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_delete(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.identity_providers.scim.users.with_raw_response.delete( + user_id="023e105f4ecef8ad9ca31a8372d0c353", + account_id="", + identity_provider_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `identity_provider_id` but received ''"): + client.zero_trust.identity_providers.scim.users.with_raw_response.delete( + user_id="023e105f4ecef8ad9ca31a8372d0c353", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + identity_provider_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `user_id` but received ''"): + client.zero_trust.identity_providers.scim.users.with_raw_response.delete( + user_id="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + identity_provider_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + ) + + @parametrize + def test_method_get(self, client: Cloudflare) -> None: + user = client.zero_trust.identity_providers.scim.users.get( + user_id="023e105f4ecef8ad9ca31a8372d0c353", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + identity_provider_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + ) + assert_matches_type(Optional[AccessUser], user, path=["response"]) + + @parametrize + def test_raw_response_get(self, client: Cloudflare) -> None: + response = client.zero_trust.identity_providers.scim.users.with_raw_response.get( + user_id="023e105f4ecef8ad9ca31a8372d0c353", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + identity_provider_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + user = response.parse() + assert_matches_type(Optional[AccessUser], user, path=["response"]) + + @parametrize + def test_streaming_response_get(self, client: Cloudflare) -> None: + with client.zero_trust.identity_providers.scim.users.with_streaming_response.get( + user_id="023e105f4ecef8ad9ca31a8372d0c353", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + identity_provider_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + user = response.parse() + assert_matches_type(Optional[AccessUser], user, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_get(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.identity_providers.scim.users.with_raw_response.get( + user_id="023e105f4ecef8ad9ca31a8372d0c353", + account_id="", + identity_provider_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `identity_provider_id` but received ''"): + client.zero_trust.identity_providers.scim.users.with_raw_response.get( + user_id="023e105f4ecef8ad9ca31a8372d0c353", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + identity_provider_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `user_id` but received ''"): + client.zero_trust.identity_providers.scim.users.with_raw_response.get( + user_id="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + identity_provider_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + ) + class TestAsyncUsers: parametrize = pytest.mark.parametrize( @@ -149,3 +269,123 @@ async def test_path_params_list(self, async_client: AsyncCloudflare) -> None: identity_provider_id="", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) + + @parametrize + async def test_method_delete(self, async_client: AsyncCloudflare) -> None: + user = await async_client.zero_trust.identity_providers.scim.users.delete( + user_id="023e105f4ecef8ad9ca31a8372d0c353", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + identity_provider_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + ) + assert user is None + + @parametrize + async def test_raw_response_delete(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.identity_providers.scim.users.with_raw_response.delete( + user_id="023e105f4ecef8ad9ca31a8372d0c353", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + identity_provider_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + user = await response.parse() + assert user is None + + @parametrize + async def test_streaming_response_delete(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.identity_providers.scim.users.with_streaming_response.delete( + user_id="023e105f4ecef8ad9ca31a8372d0c353", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + identity_provider_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + user = await response.parse() + assert user is None + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_delete(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.identity_providers.scim.users.with_raw_response.delete( + user_id="023e105f4ecef8ad9ca31a8372d0c353", + account_id="", + identity_provider_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `identity_provider_id` but received ''"): + await async_client.zero_trust.identity_providers.scim.users.with_raw_response.delete( + user_id="023e105f4ecef8ad9ca31a8372d0c353", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + identity_provider_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `user_id` but received ''"): + await async_client.zero_trust.identity_providers.scim.users.with_raw_response.delete( + user_id="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + identity_provider_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + ) + + @parametrize + async def test_method_get(self, async_client: AsyncCloudflare) -> None: + user = await async_client.zero_trust.identity_providers.scim.users.get( + user_id="023e105f4ecef8ad9ca31a8372d0c353", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + identity_provider_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + ) + assert_matches_type(Optional[AccessUser], user, path=["response"]) + + @parametrize + async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.identity_providers.scim.users.with_raw_response.get( + user_id="023e105f4ecef8ad9ca31a8372d0c353", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + identity_provider_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + user = await response.parse() + assert_matches_type(Optional[AccessUser], user, path=["response"]) + + @parametrize + async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.identity_providers.scim.users.with_streaming_response.get( + user_id="023e105f4ecef8ad9ca31a8372d0c353", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + identity_provider_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + user = await response.parse() + assert_matches_type(Optional[AccessUser], user, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_get(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.identity_providers.scim.users.with_raw_response.get( + user_id="023e105f4ecef8ad9ca31a8372d0c353", + account_id="", + identity_provider_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `identity_provider_id` but received ''"): + await async_client.zero_trust.identity_providers.scim.users.with_raw_response.get( + user_id="023e105f4ecef8ad9ca31a8372d0c353", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + identity_provider_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `user_id` but received ''"): + await async_client.zero_trust.identity_providers.scim.users.with_raw_response.get( + user_id="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + identity_provider_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + ) diff --git a/tests/api_resources/zero_trust/resource_library/test_applications.py b/tests/api_resources/zero_trust/resource_library/test_applications.py index dcef062e71f..5900e598996 100644 --- a/tests/api_resources/zero_trust/resource_library/test_applications.py +++ b/tests/api_resources/zero_trust/resource_library/test_applications.py @@ -9,7 +9,7 @@ from cloudflare import Cloudflare, AsyncCloudflare from tests.utils import assert_matches_type -from cloudflare.pagination import SyncSinglePage, AsyncSinglePage +from cloudflare.pagination import SyncCursorPaginationAfter, AsyncCursorPaginationAfter from cloudflare.types.zero_trust.resource_library import ( ApplicationGetResponse, ApplicationListResponse, @@ -40,7 +40,7 @@ def test_method_create_with_all_params_overload_1(self, client: Cloudflare) -> N human_id="HR", ip_subnets=["192.168.1.0/24", "2001:db8::/48"], name="HR", - port_protocols=["tcp/80", "tcp/443"], + port_protocols=["tcp/443", "udp/10000-20000"], support_domains=["example.com", "foo.com"], ) assert_matches_type(Optional[ApplicationCreateResponse], application, path=["response"]) @@ -96,7 +96,7 @@ def test_method_create_with_all_params_overload_2(self, client: Cloudflare) -> N hostnames=["example.com", "foo.com"], human_id="HR", name="HR", - port_protocols=["tcp/80", "tcp/443"], + port_protocols=["tcp/443", "udp/10000-20000"], support_domains=["example.com", "foo.com"], ) assert_matches_type(Optional[ApplicationCreateResponse], application, path=["response"]) @@ -150,7 +150,7 @@ def test_method_update_with_all_params(self, client: Cloudflare) -> None: account_id="023e105f4ecef8ad9ca31a8372d0c353", hostnames=["example.com", "foo.com"], ip_subnets=["192.168.1.0/24", "2001:db8::/48"], - port_protocols=["tcp/80", "tcp/443"], + port_protocols=["tcp/443", "udp/10000-20000"], support_domains=["example.com", "foo.com"], ) assert_matches_type(Optional[ApplicationUpdateResponse], application, path=["response"]) @@ -194,20 +194,22 @@ def test_method_list(self, client: Cloudflare) -> None: application = client.zero_trust.resource_library.applications.list( account_id="023e105f4ecef8ad9ca31a8372d0c353", ) - assert_matches_type(SyncSinglePage[ApplicationListResponse], application, path=["response"]) + assert_matches_type(SyncCursorPaginationAfter[ApplicationListResponse], application, path=["response"]) @parametrize def test_method_list_with_all_params(self, client: Cloudflare) -> None: application = client.zero_trust.resource_library.applications.list( account_id="023e105f4ecef8ad9ca31a8372d0c353", + cursor="cursor", fields="fields", filter="filter", limit=0, + lookup="xx", offset=0, order_by="order_by", search="xx", ) - assert_matches_type(SyncSinglePage[ApplicationListResponse], application, path=["response"]) + assert_matches_type(SyncCursorPaginationAfter[ApplicationListResponse], application, path=["response"]) @parametrize def test_raw_response_list(self, client: Cloudflare) -> None: @@ -218,7 +220,7 @@ def test_raw_response_list(self, client: Cloudflare) -> None: assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" application = response.parse() - assert_matches_type(SyncSinglePage[ApplicationListResponse], application, path=["response"]) + assert_matches_type(SyncCursorPaginationAfter[ApplicationListResponse], application, path=["response"]) @parametrize def test_streaming_response_list(self, client: Cloudflare) -> None: @@ -229,7 +231,7 @@ def test_streaming_response_list(self, client: Cloudflare) -> None: assert response.http_request.headers.get("X-Stainless-Lang") == "python" application = response.parse() - assert_matches_type(SyncSinglePage[ApplicationListResponse], application, path=["response"]) + assert_matches_type(SyncCursorPaginationAfter[ApplicationListResponse], application, path=["response"]) assert cast(Any, response.is_closed) is True @@ -347,7 +349,7 @@ async def test_method_create_with_all_params_overload_1(self, async_client: Asyn human_id="HR", ip_subnets=["192.168.1.0/24", "2001:db8::/48"], name="HR", - port_protocols=["tcp/80", "tcp/443"], + port_protocols=["tcp/443", "udp/10000-20000"], support_domains=["example.com", "foo.com"], ) assert_matches_type(Optional[ApplicationCreateResponse], application, path=["response"]) @@ -403,7 +405,7 @@ async def test_method_create_with_all_params_overload_2(self, async_client: Asyn hostnames=["example.com", "foo.com"], human_id="HR", name="HR", - port_protocols=["tcp/80", "tcp/443"], + port_protocols=["tcp/443", "udp/10000-20000"], support_domains=["example.com", "foo.com"], ) assert_matches_type(Optional[ApplicationCreateResponse], application, path=["response"]) @@ -457,7 +459,7 @@ async def test_method_update_with_all_params(self, async_client: AsyncCloudflare account_id="023e105f4ecef8ad9ca31a8372d0c353", hostnames=["example.com", "foo.com"], ip_subnets=["192.168.1.0/24", "2001:db8::/48"], - port_protocols=["tcp/80", "tcp/443"], + port_protocols=["tcp/443", "udp/10000-20000"], support_domains=["example.com", "foo.com"], ) assert_matches_type(Optional[ApplicationUpdateResponse], application, path=["response"]) @@ -501,20 +503,22 @@ async def test_method_list(self, async_client: AsyncCloudflare) -> None: application = await async_client.zero_trust.resource_library.applications.list( account_id="023e105f4ecef8ad9ca31a8372d0c353", ) - assert_matches_type(AsyncSinglePage[ApplicationListResponse], application, path=["response"]) + assert_matches_type(AsyncCursorPaginationAfter[ApplicationListResponse], application, path=["response"]) @parametrize async def test_method_list_with_all_params(self, async_client: AsyncCloudflare) -> None: application = await async_client.zero_trust.resource_library.applications.list( account_id="023e105f4ecef8ad9ca31a8372d0c353", + cursor="cursor", fields="fields", filter="filter", limit=0, + lookup="xx", offset=0, order_by="order_by", search="xx", ) - assert_matches_type(AsyncSinglePage[ApplicationListResponse], application, path=["response"]) + assert_matches_type(AsyncCursorPaginationAfter[ApplicationListResponse], application, path=["response"]) @parametrize async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None: @@ -525,7 +529,7 @@ async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None: assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" application = await response.parse() - assert_matches_type(AsyncSinglePage[ApplicationListResponse], application, path=["response"]) + assert_matches_type(AsyncCursorPaginationAfter[ApplicationListResponse], application, path=["response"]) @parametrize async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> None: @@ -536,7 +540,7 @@ async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> N assert response.http_request.headers.get("X-Stainless-Lang") == "python" application = await response.parse() - assert_matches_type(AsyncSinglePage[ApplicationListResponse], application, path=["response"]) + assert_matches_type(AsyncCursorPaginationAfter[ApplicationListResponse], application, path=["response"]) assert cast(Any, response.is_closed) is True diff --git a/tests/api_resources/zero_trust/resource_library/test_categories.py b/tests/api_resources/zero_trust/resource_library/test_categories.py index cac61082a1f..9124d9e1b71 100644 --- a/tests/api_resources/zero_trust/resource_library/test_categories.py +++ b/tests/api_resources/zero_trust/resource_library/test_categories.py @@ -9,7 +9,7 @@ from cloudflare import Cloudflare, AsyncCloudflare from tests.utils import assert_matches_type -from cloudflare.pagination import SyncSinglePage, AsyncSinglePage +from cloudflare.pagination import SyncCursorPaginationAfter, AsyncCursorPaginationAfter from cloudflare.types.zero_trust.resource_library import CategoryGetResponse, CategoryListResponse base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") @@ -23,16 +23,17 @@ def test_method_list(self, client: Cloudflare) -> None: category = client.zero_trust.resource_library.categories.list( account_id="023e105f4ecef8ad9ca31a8372d0c353", ) - assert_matches_type(SyncSinglePage[CategoryListResponse], category, path=["response"]) + assert_matches_type(SyncCursorPaginationAfter[CategoryListResponse], category, path=["response"]) @parametrize def test_method_list_with_all_params(self, client: Cloudflare) -> None: category = client.zero_trust.resource_library.categories.list( account_id="023e105f4ecef8ad9ca31a8372d0c353", + cursor="cursor", limit=0, offset=0, ) - assert_matches_type(SyncSinglePage[CategoryListResponse], category, path=["response"]) + assert_matches_type(SyncCursorPaginationAfter[CategoryListResponse], category, path=["response"]) @parametrize def test_raw_response_list(self, client: Cloudflare) -> None: @@ -43,7 +44,7 @@ def test_raw_response_list(self, client: Cloudflare) -> None: assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" category = response.parse() - assert_matches_type(SyncSinglePage[CategoryListResponse], category, path=["response"]) + assert_matches_type(SyncCursorPaginationAfter[CategoryListResponse], category, path=["response"]) @parametrize def test_streaming_response_list(self, client: Cloudflare) -> None: @@ -54,7 +55,7 @@ def test_streaming_response_list(self, client: Cloudflare) -> None: assert response.http_request.headers.get("X-Stainless-Lang") == "python" category = response.parse() - assert_matches_type(SyncSinglePage[CategoryListResponse], category, path=["response"]) + assert_matches_type(SyncCursorPaginationAfter[CategoryListResponse], category, path=["response"]) assert cast(Any, response.is_closed) is True @@ -118,16 +119,17 @@ async def test_method_list(self, async_client: AsyncCloudflare) -> None: category = await async_client.zero_trust.resource_library.categories.list( account_id="023e105f4ecef8ad9ca31a8372d0c353", ) - assert_matches_type(AsyncSinglePage[CategoryListResponse], category, path=["response"]) + assert_matches_type(AsyncCursorPaginationAfter[CategoryListResponse], category, path=["response"]) @parametrize async def test_method_list_with_all_params(self, async_client: AsyncCloudflare) -> None: category = await async_client.zero_trust.resource_library.categories.list( account_id="023e105f4ecef8ad9ca31a8372d0c353", + cursor="cursor", limit=0, offset=0, ) - assert_matches_type(AsyncSinglePage[CategoryListResponse], category, path=["response"]) + assert_matches_type(AsyncCursorPaginationAfter[CategoryListResponse], category, path=["response"]) @parametrize async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None: @@ -138,7 +140,7 @@ async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None: assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" category = await response.parse() - assert_matches_type(AsyncSinglePage[CategoryListResponse], category, path=["response"]) + assert_matches_type(AsyncCursorPaginationAfter[CategoryListResponse], category, path=["response"]) @parametrize async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> None: @@ -149,7 +151,7 @@ async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> N assert response.http_request.headers.get("X-Stainless-Lang") == "python" category = await response.parse() - assert_matches_type(AsyncSinglePage[CategoryListResponse], category, path=["response"]) + assert_matches_type(AsyncCursorPaginationAfter[CategoryListResponse], category, path=["response"]) assert cast(Any, response.is_closed) is True diff --git a/tests/api_resources/zero_trust/risk_scoring/test_behaviours.py b/tests/api_resources/zero_trust/risk_scoring/test_behaviours.py index 3c6ca23a906..9281b8e5e40 100644 --- a/tests/api_resources/zero_trust/risk_scoring/test_behaviours.py +++ b/tests/api_resources/zero_trust/risk_scoring/test_behaviours.py @@ -27,7 +27,7 @@ def test_method_update(self, client: Cloudflare) -> None: behaviors={ "foo": { "enabled": True, - "risk_level": "low", + "risk_level": "info", } }, ) @@ -40,7 +40,7 @@ def test_raw_response_update(self, client: Cloudflare) -> None: behaviors={ "foo": { "enabled": True, - "risk_level": "low", + "risk_level": "info", } }, ) @@ -57,7 +57,7 @@ def test_streaming_response_update(self, client: Cloudflare) -> None: behaviors={ "foo": { "enabled": True, - "risk_level": "low", + "risk_level": "info", } }, ) as response: @@ -77,7 +77,7 @@ def test_path_params_update(self, client: Cloudflare) -> None: behaviors={ "foo": { "enabled": True, - "risk_level": "low", + "risk_level": "info", } }, ) @@ -133,7 +133,7 @@ async def test_method_update(self, async_client: AsyncCloudflare) -> None: behaviors={ "foo": { "enabled": True, - "risk_level": "low", + "risk_level": "info", } }, ) @@ -146,7 +146,7 @@ async def test_raw_response_update(self, async_client: AsyncCloudflare) -> None: behaviors={ "foo": { "enabled": True, - "risk_level": "low", + "risk_level": "info", } }, ) @@ -163,7 +163,7 @@ async def test_streaming_response_update(self, async_client: AsyncCloudflare) -> behaviors={ "foo": { "enabled": True, - "risk_level": "low", + "risk_level": "info", } }, ) as response: @@ -183,7 +183,7 @@ async def test_path_params_update(self, async_client: AsyncCloudflare) -> None: behaviors={ "foo": { "enabled": True, - "risk_level": "low", + "risk_level": "info", } }, ) diff --git a/tests/api_resources/zero_trust/test_identity_providers.py b/tests/api_resources/zero_trust/test_identity_providers.py index 225644bb8eb..5731f226f5c 100644 --- a/tests/api_resources/zero_trust/test_identity_providers.py +++ b/tests/api_resources/zero_trust/test_identity_providers.py @@ -726,12 +726,9 @@ def test_method_create_overload_9(self, client: Cloudflare) -> None: def test_method_create_with_all_params_overload_9(self, client: Cloudflare) -> None: identity_provider = client.zero_trust.identity_providers.create( config={ - "authorization_server_id": "aus9o8wzkhckw9TLa0h7z", - "claims": ["email_verified", "preferred_username", "custom_claim_name"], - "client_id": "", + "client_id": "DIABC123678901234567", "client_secret": "", - "email_claim_name": "custom_claim_name", - "okta_account": "https://dev-abc123.oktapreview.com", + "issuer_url": "https://sso-abc1def2.sso.duosecurity.com/oidc/DIABC123678901234567", }, name="Widget Corps IDP", type="onetimepin", @@ -813,11 +810,12 @@ def test_method_create_overload_10(self, client: Cloudflare) -> None: def test_method_create_with_all_params_overload_10(self, client: Cloudflare) -> None: identity_provider = client.zero_trust.identity_providers.create( config={ + "authorization_server_id": "aus9o8wzkhckw9TLa0h7z", "claims": ["email_verified", "preferred_username", "custom_claim_name"], "client_id": "", "client_secret": "", "email_claim_name": "custom_claim_name", - "onelogin_account": "https://mycompany.onelogin.com", + "okta_account": "https://dev-abc123.oktapreview.com", }, name="Widget Corps IDP", type="onetimepin", @@ -903,7 +901,7 @@ def test_method_create_with_all_params_overload_11(self, client: Cloudflare) -> "client_id": "", "client_secret": "", "email_claim_name": "custom_claim_name", - "ping_env_id": "342b5660-0c32-4936-a5a4-ce21fae57b0a", + "onelogin_account": "https://mycompany.onelogin.com", }, name="Widget Corps IDP", type="onetimepin", @@ -983,6 +981,92 @@ def test_method_create_overload_12(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize def test_method_create_with_all_params_overload_12(self, client: Cloudflare) -> None: + identity_provider = client.zero_trust.identity_providers.create( + config={ + "claims": ["email_verified", "preferred_username", "custom_claim_name"], + "client_id": "", + "client_secret": "", + "email_claim_name": "custom_claim_name", + "ping_env_id": "342b5660-0c32-4936-a5a4-ce21fae57b0a", + }, + name="Widget Corps IDP", + type="onetimepin", + account_id="account_id", + saml_certificate_set_id="c409ef44-e72c-41c8-8c0b-278c8a6f4fd8", + scim_config={ + "enabled": True, + "identity_update_behavior": "automatic", + "seat_deprovision": True, + "user_deprovision": True, + }, + ) + assert_matches_type(Optional[IdentityProvider], identity_provider, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_raw_response_create_overload_12(self, client: Cloudflare) -> None: + response = client.zero_trust.identity_providers.with_raw_response.create( + config={}, + name="Widget Corps IDP", + type="onetimepin", + account_id="account_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + identity_provider = response.parse() + assert_matches_type(Optional[IdentityProvider], identity_provider, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_streaming_response_create_overload_12(self, client: Cloudflare) -> None: + with client.zero_trust.identity_providers.with_streaming_response.create( + config={}, + name="Widget Corps IDP", + type="onetimepin", + account_id="account_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + identity_provider = response.parse() + assert_matches_type(Optional[IdentityProvider], identity_provider, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_path_params_create_overload_12(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"You must provide either account_id or zone_id"): + client.zero_trust.identity_providers.with_raw_response.create( + config={}, + name="Widget Corps IDP", + type="onetimepin", + account_id="", + ) + + with pytest.raises(ValueError, match=r"You must provide either account_id or zone_id"): + client.zero_trust.identity_providers.with_raw_response.create( + config={}, + name="Widget Corps IDP", + type="onetimepin", + account_id="account_id", + ) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_method_create_overload_13(self, client: Cloudflare) -> None: + identity_provider = client.zero_trust.identity_providers.create( + config={}, + name="Widget Corps IDP", + type="onetimepin", + account_id="account_id", + ) + assert_matches_type(Optional[IdentityProvider], identity_provider, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_method_create_with_all_params_overload_13(self, client: Cloudflare) -> None: identity_provider = client.zero_trust.identity_providers.create( config={ "attributes": ["group", "department_code", "divison"], @@ -1016,7 +1100,7 @@ def test_method_create_with_all_params_overload_12(self, client: Cloudflare) -> @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_raw_response_create_overload_12(self, client: Cloudflare) -> None: + def test_raw_response_create_overload_13(self, client: Cloudflare) -> None: response = client.zero_trust.identity_providers.with_raw_response.create( config={}, name="Widget Corps IDP", @@ -1031,7 +1115,7 @@ def test_raw_response_create_overload_12(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_streaming_response_create_overload_12(self, client: Cloudflare) -> None: + def test_streaming_response_create_overload_13(self, client: Cloudflare) -> None: with client.zero_trust.identity_providers.with_streaming_response.create( config={}, name="Widget Corps IDP", @@ -1048,7 +1132,7 @@ def test_streaming_response_create_overload_12(self, client: Cloudflare) -> None @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_path_params_create_overload_12(self, client: Cloudflare) -> None: + def test_path_params_create_overload_13(self, client: Cloudflare) -> None: with pytest.raises(ValueError, match=r"You must provide either account_id or zone_id"): client.zero_trust.identity_providers.with_raw_response.create( config={}, @@ -1067,7 +1151,7 @@ def test_path_params_create_overload_12(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_method_create_overload_13(self, client: Cloudflare) -> None: + def test_method_create_overload_14(self, client: Cloudflare) -> None: identity_provider = client.zero_trust.identity_providers.create( config={}, name="Widget Corps IDP", @@ -1078,7 +1162,7 @@ def test_method_create_overload_13(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_method_create_with_all_params_overload_13(self, client: Cloudflare) -> None: + def test_method_create_with_all_params_overload_14(self, client: Cloudflare) -> None: identity_provider = client.zero_trust.identity_providers.create( config={ "client_id": "", @@ -1099,7 +1183,7 @@ def test_method_create_with_all_params_overload_13(self, client: Cloudflare) -> @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_raw_response_create_overload_13(self, client: Cloudflare) -> None: + def test_raw_response_create_overload_14(self, client: Cloudflare) -> None: response = client.zero_trust.identity_providers.with_raw_response.create( config={}, name="Widget Corps IDP", @@ -1114,7 +1198,7 @@ def test_raw_response_create_overload_13(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_streaming_response_create_overload_13(self, client: Cloudflare) -> None: + def test_streaming_response_create_overload_14(self, client: Cloudflare) -> None: with client.zero_trust.identity_providers.with_streaming_response.create( config={}, name="Widget Corps IDP", @@ -1131,7 +1215,7 @@ def test_streaming_response_create_overload_13(self, client: Cloudflare) -> None @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_path_params_create_overload_13(self, client: Cloudflare) -> None: + def test_path_params_create_overload_14(self, client: Cloudflare) -> None: with pytest.raises(ValueError, match=r"You must provide either account_id or zone_id"): client.zero_trust.identity_providers.with_raw_response.create( config={}, @@ -1150,7 +1234,7 @@ def test_path_params_create_overload_13(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_method_create_overload_14(self, client: Cloudflare) -> None: + def test_method_create_overload_15(self, client: Cloudflare) -> None: identity_provider = client.zero_trust.identity_providers.create( config={}, name="Widget Corps IDP", @@ -1161,7 +1245,7 @@ def test_method_create_overload_14(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_method_create_with_all_params_overload_14(self, client: Cloudflare) -> None: + def test_method_create_with_all_params_overload_15(self, client: Cloudflare) -> None: identity_provider = client.zero_trust.identity_providers.create( config={}, name="Widget Corps IDP", @@ -1179,7 +1263,7 @@ def test_method_create_with_all_params_overload_14(self, client: Cloudflare) -> @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_raw_response_create_overload_14(self, client: Cloudflare) -> None: + def test_raw_response_create_overload_15(self, client: Cloudflare) -> None: response = client.zero_trust.identity_providers.with_raw_response.create( config={}, name="Widget Corps IDP", @@ -1194,7 +1278,7 @@ def test_raw_response_create_overload_14(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_streaming_response_create_overload_14(self, client: Cloudflare) -> None: + def test_streaming_response_create_overload_15(self, client: Cloudflare) -> None: with client.zero_trust.identity_providers.with_streaming_response.create( config={}, name="Widget Corps IDP", @@ -1211,7 +1295,7 @@ def test_streaming_response_create_overload_14(self, client: Cloudflare) -> None @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_path_params_create_overload_14(self, client: Cloudflare) -> None: + def test_path_params_create_overload_15(self, client: Cloudflare) -> None: with pytest.raises(ValueError, match=r"You must provide either account_id or zone_id"): client.zero_trust.identity_providers.with_raw_response.create( config={}, @@ -1230,7 +1314,7 @@ def test_path_params_create_overload_14(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_method_create_overload_15(self, client: Cloudflare) -> None: + def test_method_create_overload_16(self, client: Cloudflare) -> None: identity_provider = client.zero_trust.identity_providers.create( config={}, name="Widget Corps IDP", @@ -1241,7 +1325,7 @@ def test_method_create_overload_15(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_method_create_with_all_params_overload_15(self, client: Cloudflare) -> None: + def test_method_create_with_all_params_overload_16(self, client: Cloudflare) -> None: identity_provider = client.zero_trust.identity_providers.create( config={"restrict_to_account_members": True}, name="Widget Corps IDP", @@ -1259,7 +1343,7 @@ def test_method_create_with_all_params_overload_15(self, client: Cloudflare) -> @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_raw_response_create_overload_15(self, client: Cloudflare) -> None: + def test_raw_response_create_overload_16(self, client: Cloudflare) -> None: response = client.zero_trust.identity_providers.with_raw_response.create( config={}, name="Widget Corps IDP", @@ -1274,7 +1358,7 @@ def test_raw_response_create_overload_15(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_streaming_response_create_overload_15(self, client: Cloudflare) -> None: + def test_streaming_response_create_overload_16(self, client: Cloudflare) -> None: with client.zero_trust.identity_providers.with_streaming_response.create( config={}, name="Widget Corps IDP", @@ -1291,7 +1375,87 @@ def test_streaming_response_create_overload_15(self, client: Cloudflare) -> None @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_path_params_create_overload_15(self, client: Cloudflare) -> None: + def test_path_params_create_overload_16(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"You must provide either account_id or zone_id"): + client.zero_trust.identity_providers.with_raw_response.create( + config={}, + name="Widget Corps IDP", + type="onetimepin", + account_id="", + ) + + with pytest.raises(ValueError, match=r"You must provide either account_id or zone_id"): + client.zero_trust.identity_providers.with_raw_response.create( + config={}, + name="Widget Corps IDP", + type="onetimepin", + account_id="account_id", + ) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_method_create_overload_17(self, client: Cloudflare) -> None: + identity_provider = client.zero_trust.identity_providers.create( + config={}, + name="Widget Corps IDP", + type="onetimepin", + account_id="account_id", + ) + assert_matches_type(Optional[IdentityProvider], identity_provider, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_method_create_with_all_params_overload_17(self, client: Cloudflare) -> None: + identity_provider = client.zero_trust.identity_providers.create( + config={"login_page_auto_prompt": True}, + name="Widget Corps IDP", + type="onetimepin", + account_id="account_id", + saml_certificate_set_id="c409ef44-e72c-41c8-8c0b-278c8a6f4fd8", + scim_config={ + "enabled": True, + "identity_update_behavior": "automatic", + "seat_deprovision": True, + "user_deprovision": True, + }, + ) + assert_matches_type(Optional[IdentityProvider], identity_provider, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_raw_response_create_overload_17(self, client: Cloudflare) -> None: + response = client.zero_trust.identity_providers.with_raw_response.create( + config={}, + name="Widget Corps IDP", + type="onetimepin", + account_id="account_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + identity_provider = response.parse() + assert_matches_type(Optional[IdentityProvider], identity_provider, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_streaming_response_create_overload_17(self, client: Cloudflare) -> None: + with client.zero_trust.identity_providers.with_streaming_response.create( + config={}, + name="Widget Corps IDP", + type="onetimepin", + account_id="account_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + identity_provider = response.parse() + assert_matches_type(Optional[IdentityProvider], identity_provider, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_path_params_create_overload_17(self, client: Cloudflare) -> None: with pytest.raises(ValueError, match=r"You must provide either account_id or zone_id"): client.zero_trust.identity_providers.with_raw_response.create( config={}, @@ -2134,12 +2298,9 @@ def test_method_update_with_all_params_overload_9(self, client: Cloudflare) -> N identity_provider = client.zero_trust.identity_providers.update( identity_provider_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", config={ - "authorization_server_id": "aus9o8wzkhckw9TLa0h7z", - "claims": ["email_verified", "preferred_username", "custom_claim_name"], - "client_id": "", + "client_id": "DIABC123678901234567", "client_secret": "", - "email_claim_name": "custom_claim_name", - "okta_account": "https://dev-abc123.oktapreview.com", + "issuer_url": "https://sso-abc1def2.sso.duosecurity.com/oidc/DIABC123678901234567", }, name="Widget Corps IDP", type="onetimepin", @@ -2236,11 +2397,12 @@ def test_method_update_with_all_params_overload_10(self, client: Cloudflare) -> identity_provider = client.zero_trust.identity_providers.update( identity_provider_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", config={ + "authorization_server_id": "aus9o8wzkhckw9TLa0h7z", "claims": ["email_verified", "preferred_username", "custom_claim_name"], "client_id": "", "client_secret": "", "email_claim_name": "custom_claim_name", - "onelogin_account": "https://mycompany.onelogin.com", + "okta_account": "https://dev-abc123.oktapreview.com", }, name="Widget Corps IDP", type="onetimepin", @@ -2341,7 +2503,7 @@ def test_method_update_with_all_params_overload_11(self, client: Cloudflare) -> "client_id": "", "client_secret": "", "email_claim_name": "custom_claim_name", - "ping_env_id": "342b5660-0c32-4936-a5a4-ce21fae57b0a", + "onelogin_account": "https://mycompany.onelogin.com", }, name="Widget Corps IDP", type="onetimepin", @@ -2438,21 +2600,11 @@ def test_method_update_with_all_params_overload_12(self, client: Cloudflare) -> identity_provider = client.zero_trust.identity_providers.update( identity_provider_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", config={ - "attributes": ["group", "department_code", "divison"], - "email_attribute_name": "Email", - "enable_encryption": True, - "force_authn": True, - "header_attributes": [ - { - "attribute_name": "attribute_name", - "header_name": "header_name", - } - ], - "idp_public_certs": ["string"], - "issuer_url": "https://whoami.com", - "max_sso_url_length": 8192, - "sign_request": True, - "sso_target_url": "https://edgeaccess.org/idp/saml/login", + "claims": ["email_verified", "preferred_username", "custom_claim_name"], + "client_id": "", + "client_secret": "", + "email_claim_name": "custom_claim_name", + "ping_env_id": "342b5660-0c32-4936-a5a4-ce21fae57b0a", }, name="Widget Corps IDP", type="onetimepin", @@ -2549,8 +2701,21 @@ def test_method_update_with_all_params_overload_13(self, client: Cloudflare) -> identity_provider = client.zero_trust.identity_providers.update( identity_provider_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", config={ - "client_id": "", - "client_secret": "", + "attributes": ["group", "department_code", "divison"], + "email_attribute_name": "Email", + "enable_encryption": True, + "force_authn": True, + "header_attributes": [ + { + "attribute_name": "attribute_name", + "header_name": "header_name", + } + ], + "idp_public_certs": ["string"], + "issuer_url": "https://whoami.com", + "max_sso_url_length": 8192, + "sign_request": True, + "sso_target_url": "https://edgeaccess.org/idp/saml/login", }, name="Widget Corps IDP", type="onetimepin", @@ -2646,7 +2811,10 @@ def test_method_update_overload_14(self, client: Cloudflare) -> None: def test_method_update_with_all_params_overload_14(self, client: Cloudflare) -> None: identity_provider = client.zero_trust.identity_providers.update( identity_provider_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", - config={}, + config={ + "client_id": "", + "client_secret": "", + }, name="Widget Corps IDP", type="onetimepin", account_id="account_id", @@ -2741,7 +2909,7 @@ def test_method_update_overload_15(self, client: Cloudflare) -> None: def test_method_update_with_all_params_overload_15(self, client: Cloudflare) -> None: identity_provider = client.zero_trust.identity_providers.update( identity_provider_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", - config={"restrict_to_account_members": True}, + config={}, name="Widget Corps IDP", type="onetimepin", account_id="account_id", @@ -2821,7 +2989,197 @@ def test_path_params_update_overload_15(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - def test_method_list(self, client: Cloudflare) -> None: + def test_method_update_overload_16(self, client: Cloudflare) -> None: + identity_provider = client.zero_trust.identity_providers.update( + identity_provider_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + config={}, + name="Widget Corps IDP", + type="onetimepin", + account_id="account_id", + ) + assert_matches_type(Optional[IdentityProvider], identity_provider, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_method_update_with_all_params_overload_16(self, client: Cloudflare) -> None: + identity_provider = client.zero_trust.identity_providers.update( + identity_provider_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + config={"restrict_to_account_members": True}, + name="Widget Corps IDP", + type="onetimepin", + account_id="account_id", + saml_certificate_set_id="c409ef44-e72c-41c8-8c0b-278c8a6f4fd8", + scim_config={ + "enabled": True, + "identity_update_behavior": "automatic", + "seat_deprovision": True, + "user_deprovision": True, + }, + ) + assert_matches_type(Optional[IdentityProvider], identity_provider, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_raw_response_update_overload_16(self, client: Cloudflare) -> None: + response = client.zero_trust.identity_providers.with_raw_response.update( + identity_provider_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + config={}, + name="Widget Corps IDP", + type="onetimepin", + account_id="account_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + identity_provider = response.parse() + assert_matches_type(Optional[IdentityProvider], identity_provider, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_streaming_response_update_overload_16(self, client: Cloudflare) -> None: + with client.zero_trust.identity_providers.with_streaming_response.update( + identity_provider_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + config={}, + name="Widget Corps IDP", + type="onetimepin", + account_id="account_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + identity_provider = response.parse() + assert_matches_type(Optional[IdentityProvider], identity_provider, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_path_params_update_overload_16(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `identity_provider_id` but received ''"): + client.zero_trust.identity_providers.with_raw_response.update( + identity_provider_id="", + config={}, + name="Widget Corps IDP", + type="onetimepin", + account_id="account_id", + ) + + with pytest.raises(ValueError, match=r"You must provide either account_id or zone_id"): + client.zero_trust.identity_providers.with_raw_response.update( + identity_provider_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + config={}, + name="Widget Corps IDP", + type="onetimepin", + account_id="", + ) + + with pytest.raises(ValueError, match=r"You must provide either account_id or zone_id"): + client.zero_trust.identity_providers.with_raw_response.update( + identity_provider_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + config={}, + name="Widget Corps IDP", + type="onetimepin", + account_id="account_id", + ) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_method_update_overload_17(self, client: Cloudflare) -> None: + identity_provider = client.zero_trust.identity_providers.update( + identity_provider_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + config={}, + name="Widget Corps IDP", + type="onetimepin", + account_id="account_id", + ) + assert_matches_type(Optional[IdentityProvider], identity_provider, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_method_update_with_all_params_overload_17(self, client: Cloudflare) -> None: + identity_provider = client.zero_trust.identity_providers.update( + identity_provider_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + config={"login_page_auto_prompt": True}, + name="Widget Corps IDP", + type="onetimepin", + account_id="account_id", + saml_certificate_set_id="c409ef44-e72c-41c8-8c0b-278c8a6f4fd8", + scim_config={ + "enabled": True, + "identity_update_behavior": "automatic", + "seat_deprovision": True, + "user_deprovision": True, + }, + ) + assert_matches_type(Optional[IdentityProvider], identity_provider, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_raw_response_update_overload_17(self, client: Cloudflare) -> None: + response = client.zero_trust.identity_providers.with_raw_response.update( + identity_provider_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + config={}, + name="Widget Corps IDP", + type="onetimepin", + account_id="account_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + identity_provider = response.parse() + assert_matches_type(Optional[IdentityProvider], identity_provider, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_streaming_response_update_overload_17(self, client: Cloudflare) -> None: + with client.zero_trust.identity_providers.with_streaming_response.update( + identity_provider_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + config={}, + name="Widget Corps IDP", + type="onetimepin", + account_id="account_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + identity_provider = response.parse() + assert_matches_type(Optional[IdentityProvider], identity_provider, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_path_params_update_overload_17(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `identity_provider_id` but received ''"): + client.zero_trust.identity_providers.with_raw_response.update( + identity_provider_id="", + config={}, + name="Widget Corps IDP", + type="onetimepin", + account_id="account_id", + ) + + with pytest.raises(ValueError, match=r"You must provide either account_id or zone_id"): + client.zero_trust.identity_providers.with_raw_response.update( + identity_provider_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + config={}, + name="Widget Corps IDP", + type="onetimepin", + account_id="", + ) + + with pytest.raises(ValueError, match=r"You must provide either account_id or zone_id"): + client.zero_trust.identity_providers.with_raw_response.update( + identity_provider_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + config={}, + name="Widget Corps IDP", + type="onetimepin", + account_id="account_id", + ) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + def test_method_list(self, client: Cloudflare) -> None: identity_provider = client.zero_trust.identity_providers.list( account_id="account_id", ) @@ -3729,12 +4087,9 @@ async def test_method_create_overload_9(self, async_client: AsyncCloudflare) -> async def test_method_create_with_all_params_overload_9(self, async_client: AsyncCloudflare) -> None: identity_provider = await async_client.zero_trust.identity_providers.create( config={ - "authorization_server_id": "aus9o8wzkhckw9TLa0h7z", - "claims": ["email_verified", "preferred_username", "custom_claim_name"], - "client_id": "", + "client_id": "DIABC123678901234567", "client_secret": "", - "email_claim_name": "custom_claim_name", - "okta_account": "https://dev-abc123.oktapreview.com", + "issuer_url": "https://sso-abc1def2.sso.duosecurity.com/oidc/DIABC123678901234567", }, name="Widget Corps IDP", type="onetimepin", @@ -3816,11 +4171,12 @@ async def test_method_create_overload_10(self, async_client: AsyncCloudflare) -> async def test_method_create_with_all_params_overload_10(self, async_client: AsyncCloudflare) -> None: identity_provider = await async_client.zero_trust.identity_providers.create( config={ + "authorization_server_id": "aus9o8wzkhckw9TLa0h7z", "claims": ["email_verified", "preferred_username", "custom_claim_name"], "client_id": "", "client_secret": "", "email_claim_name": "custom_claim_name", - "onelogin_account": "https://mycompany.onelogin.com", + "okta_account": "https://dev-abc123.oktapreview.com", }, name="Widget Corps IDP", type="onetimepin", @@ -3906,7 +4262,7 @@ async def test_method_create_with_all_params_overload_11(self, async_client: Asy "client_id": "", "client_secret": "", "email_claim_name": "custom_claim_name", - "ping_env_id": "342b5660-0c32-4936-a5a4-ce21fae57b0a", + "onelogin_account": "https://mycompany.onelogin.com", }, name="Widget Corps IDP", type="onetimepin", @@ -3986,6 +4342,92 @@ async def test_method_create_overload_12(self, async_client: AsyncCloudflare) -> @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize async def test_method_create_with_all_params_overload_12(self, async_client: AsyncCloudflare) -> None: + identity_provider = await async_client.zero_trust.identity_providers.create( + config={ + "claims": ["email_verified", "preferred_username", "custom_claim_name"], + "client_id": "", + "client_secret": "", + "email_claim_name": "custom_claim_name", + "ping_env_id": "342b5660-0c32-4936-a5a4-ce21fae57b0a", + }, + name="Widget Corps IDP", + type="onetimepin", + account_id="account_id", + saml_certificate_set_id="c409ef44-e72c-41c8-8c0b-278c8a6f4fd8", + scim_config={ + "enabled": True, + "identity_update_behavior": "automatic", + "seat_deprovision": True, + "user_deprovision": True, + }, + ) + assert_matches_type(Optional[IdentityProvider], identity_provider, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_raw_response_create_overload_12(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.identity_providers.with_raw_response.create( + config={}, + name="Widget Corps IDP", + type="onetimepin", + account_id="account_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + identity_provider = await response.parse() + assert_matches_type(Optional[IdentityProvider], identity_provider, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_streaming_response_create_overload_12(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.identity_providers.with_streaming_response.create( + config={}, + name="Widget Corps IDP", + type="onetimepin", + account_id="account_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + identity_provider = await response.parse() + assert_matches_type(Optional[IdentityProvider], identity_provider, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_path_params_create_overload_12(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"You must provide either account_id or zone_id"): + await async_client.zero_trust.identity_providers.with_raw_response.create( + config={}, + name="Widget Corps IDP", + type="onetimepin", + account_id="", + ) + + with pytest.raises(ValueError, match=r"You must provide either account_id or zone_id"): + await async_client.zero_trust.identity_providers.with_raw_response.create( + config={}, + name="Widget Corps IDP", + type="onetimepin", + account_id="account_id", + ) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_method_create_overload_13(self, async_client: AsyncCloudflare) -> None: + identity_provider = await async_client.zero_trust.identity_providers.create( + config={}, + name="Widget Corps IDP", + type="onetimepin", + account_id="account_id", + ) + assert_matches_type(Optional[IdentityProvider], identity_provider, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_method_create_with_all_params_overload_13(self, async_client: AsyncCloudflare) -> None: identity_provider = await async_client.zero_trust.identity_providers.create( config={ "attributes": ["group", "department_code", "divison"], @@ -4019,7 +4461,7 @@ async def test_method_create_with_all_params_overload_12(self, async_client: Asy @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_raw_response_create_overload_12(self, async_client: AsyncCloudflare) -> None: + async def test_raw_response_create_overload_13(self, async_client: AsyncCloudflare) -> None: response = await async_client.zero_trust.identity_providers.with_raw_response.create( config={}, name="Widget Corps IDP", @@ -4034,7 +4476,7 @@ async def test_raw_response_create_overload_12(self, async_client: AsyncCloudfla @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_streaming_response_create_overload_12(self, async_client: AsyncCloudflare) -> None: + async def test_streaming_response_create_overload_13(self, async_client: AsyncCloudflare) -> None: async with async_client.zero_trust.identity_providers.with_streaming_response.create( config={}, name="Widget Corps IDP", @@ -4051,7 +4493,7 @@ async def test_streaming_response_create_overload_12(self, async_client: AsyncCl @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_path_params_create_overload_12(self, async_client: AsyncCloudflare) -> None: + async def test_path_params_create_overload_13(self, async_client: AsyncCloudflare) -> None: with pytest.raises(ValueError, match=r"You must provide either account_id or zone_id"): await async_client.zero_trust.identity_providers.with_raw_response.create( config={}, @@ -4070,7 +4512,7 @@ async def test_path_params_create_overload_12(self, async_client: AsyncCloudflar @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_method_create_overload_13(self, async_client: AsyncCloudflare) -> None: + async def test_method_create_overload_14(self, async_client: AsyncCloudflare) -> None: identity_provider = await async_client.zero_trust.identity_providers.create( config={}, name="Widget Corps IDP", @@ -4081,12 +4523,92 @@ async def test_method_create_overload_13(self, async_client: AsyncCloudflare) -> @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_method_create_with_all_params_overload_13(self, async_client: AsyncCloudflare) -> None: + async def test_method_create_with_all_params_overload_14(self, async_client: AsyncCloudflare) -> None: + identity_provider = await async_client.zero_trust.identity_providers.create( + config={ + "client_id": "", + "client_secret": "", + }, + name="Widget Corps IDP", + type="onetimepin", + account_id="account_id", + saml_certificate_set_id="c409ef44-e72c-41c8-8c0b-278c8a6f4fd8", + scim_config={ + "enabled": True, + "identity_update_behavior": "automatic", + "seat_deprovision": True, + "user_deprovision": True, + }, + ) + assert_matches_type(Optional[IdentityProvider], identity_provider, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_raw_response_create_overload_14(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.identity_providers.with_raw_response.create( + config={}, + name="Widget Corps IDP", + type="onetimepin", + account_id="account_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + identity_provider = await response.parse() + assert_matches_type(Optional[IdentityProvider], identity_provider, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_streaming_response_create_overload_14(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.identity_providers.with_streaming_response.create( + config={}, + name="Widget Corps IDP", + type="onetimepin", + account_id="account_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + identity_provider = await response.parse() + assert_matches_type(Optional[IdentityProvider], identity_provider, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_path_params_create_overload_14(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"You must provide either account_id or zone_id"): + await async_client.zero_trust.identity_providers.with_raw_response.create( + config={}, + name="Widget Corps IDP", + type="onetimepin", + account_id="", + ) + + with pytest.raises(ValueError, match=r"You must provide either account_id or zone_id"): + await async_client.zero_trust.identity_providers.with_raw_response.create( + config={}, + name="Widget Corps IDP", + type="onetimepin", + account_id="account_id", + ) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_method_create_overload_15(self, async_client: AsyncCloudflare) -> None: + identity_provider = await async_client.zero_trust.identity_providers.create( + config={}, + name="Widget Corps IDP", + type="onetimepin", + account_id="account_id", + ) + assert_matches_type(Optional[IdentityProvider], identity_provider, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_method_create_with_all_params_overload_15(self, async_client: AsyncCloudflare) -> None: identity_provider = await async_client.zero_trust.identity_providers.create( - config={ - "client_id": "", - "client_secret": "", - }, + config={}, name="Widget Corps IDP", type="onetimepin", account_id="account_id", @@ -4102,7 +4624,7 @@ async def test_method_create_with_all_params_overload_13(self, async_client: Asy @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_raw_response_create_overload_13(self, async_client: AsyncCloudflare) -> None: + async def test_raw_response_create_overload_15(self, async_client: AsyncCloudflare) -> None: response = await async_client.zero_trust.identity_providers.with_raw_response.create( config={}, name="Widget Corps IDP", @@ -4117,7 +4639,7 @@ async def test_raw_response_create_overload_13(self, async_client: AsyncCloudfla @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_streaming_response_create_overload_13(self, async_client: AsyncCloudflare) -> None: + async def test_streaming_response_create_overload_15(self, async_client: AsyncCloudflare) -> None: async with async_client.zero_trust.identity_providers.with_streaming_response.create( config={}, name="Widget Corps IDP", @@ -4134,7 +4656,7 @@ async def test_streaming_response_create_overload_13(self, async_client: AsyncCl @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_path_params_create_overload_13(self, async_client: AsyncCloudflare) -> None: + async def test_path_params_create_overload_15(self, async_client: AsyncCloudflare) -> None: with pytest.raises(ValueError, match=r"You must provide either account_id or zone_id"): await async_client.zero_trust.identity_providers.with_raw_response.create( config={}, @@ -4153,7 +4675,7 @@ async def test_path_params_create_overload_13(self, async_client: AsyncCloudflar @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_method_create_overload_14(self, async_client: AsyncCloudflare) -> None: + async def test_method_create_overload_16(self, async_client: AsyncCloudflare) -> None: identity_provider = await async_client.zero_trust.identity_providers.create( config={}, name="Widget Corps IDP", @@ -4164,9 +4686,9 @@ async def test_method_create_overload_14(self, async_client: AsyncCloudflare) -> @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_method_create_with_all_params_overload_14(self, async_client: AsyncCloudflare) -> None: + async def test_method_create_with_all_params_overload_16(self, async_client: AsyncCloudflare) -> None: identity_provider = await async_client.zero_trust.identity_providers.create( - config={}, + config={"restrict_to_account_members": True}, name="Widget Corps IDP", type="onetimepin", account_id="account_id", @@ -4182,7 +4704,7 @@ async def test_method_create_with_all_params_overload_14(self, async_client: Asy @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_raw_response_create_overload_14(self, async_client: AsyncCloudflare) -> None: + async def test_raw_response_create_overload_16(self, async_client: AsyncCloudflare) -> None: response = await async_client.zero_trust.identity_providers.with_raw_response.create( config={}, name="Widget Corps IDP", @@ -4197,7 +4719,7 @@ async def test_raw_response_create_overload_14(self, async_client: AsyncCloudfla @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_streaming_response_create_overload_14(self, async_client: AsyncCloudflare) -> None: + async def test_streaming_response_create_overload_16(self, async_client: AsyncCloudflare) -> None: async with async_client.zero_trust.identity_providers.with_streaming_response.create( config={}, name="Widget Corps IDP", @@ -4214,7 +4736,7 @@ async def test_streaming_response_create_overload_14(self, async_client: AsyncCl @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_path_params_create_overload_14(self, async_client: AsyncCloudflare) -> None: + async def test_path_params_create_overload_16(self, async_client: AsyncCloudflare) -> None: with pytest.raises(ValueError, match=r"You must provide either account_id or zone_id"): await async_client.zero_trust.identity_providers.with_raw_response.create( config={}, @@ -4233,7 +4755,7 @@ async def test_path_params_create_overload_14(self, async_client: AsyncCloudflar @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_method_create_overload_15(self, async_client: AsyncCloudflare) -> None: + async def test_method_create_overload_17(self, async_client: AsyncCloudflare) -> None: identity_provider = await async_client.zero_trust.identity_providers.create( config={}, name="Widget Corps IDP", @@ -4244,9 +4766,9 @@ async def test_method_create_overload_15(self, async_client: AsyncCloudflare) -> @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_method_create_with_all_params_overload_15(self, async_client: AsyncCloudflare) -> None: + async def test_method_create_with_all_params_overload_17(self, async_client: AsyncCloudflare) -> None: identity_provider = await async_client.zero_trust.identity_providers.create( - config={"restrict_to_account_members": True}, + config={"login_page_auto_prompt": True}, name="Widget Corps IDP", type="onetimepin", account_id="account_id", @@ -4262,7 +4784,7 @@ async def test_method_create_with_all_params_overload_15(self, async_client: Asy @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_raw_response_create_overload_15(self, async_client: AsyncCloudflare) -> None: + async def test_raw_response_create_overload_17(self, async_client: AsyncCloudflare) -> None: response = await async_client.zero_trust.identity_providers.with_raw_response.create( config={}, name="Widget Corps IDP", @@ -4277,7 +4799,7 @@ async def test_raw_response_create_overload_15(self, async_client: AsyncCloudfla @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_streaming_response_create_overload_15(self, async_client: AsyncCloudflare) -> None: + async def test_streaming_response_create_overload_17(self, async_client: AsyncCloudflare) -> None: async with async_client.zero_trust.identity_providers.with_streaming_response.create( config={}, name="Widget Corps IDP", @@ -4294,7 +4816,7 @@ async def test_streaming_response_create_overload_15(self, async_client: AsyncCl @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_path_params_create_overload_15(self, async_client: AsyncCloudflare) -> None: + async def test_path_params_create_overload_17(self, async_client: AsyncCloudflare) -> None: with pytest.raises(ValueError, match=r"You must provide either account_id or zone_id"): await async_client.zero_trust.identity_providers.with_raw_response.create( config={}, @@ -5137,12 +5659,9 @@ async def test_method_update_with_all_params_overload_9(self, async_client: Asyn identity_provider = await async_client.zero_trust.identity_providers.update( identity_provider_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", config={ - "authorization_server_id": "aus9o8wzkhckw9TLa0h7z", - "claims": ["email_verified", "preferred_username", "custom_claim_name"], - "client_id": "", + "client_id": "DIABC123678901234567", "client_secret": "", - "email_claim_name": "custom_claim_name", - "okta_account": "https://dev-abc123.oktapreview.com", + "issuer_url": "https://sso-abc1def2.sso.duosecurity.com/oidc/DIABC123678901234567", }, name="Widget Corps IDP", type="onetimepin", @@ -5239,11 +5758,12 @@ async def test_method_update_with_all_params_overload_10(self, async_client: Asy identity_provider = await async_client.zero_trust.identity_providers.update( identity_provider_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", config={ + "authorization_server_id": "aus9o8wzkhckw9TLa0h7z", "claims": ["email_verified", "preferred_username", "custom_claim_name"], "client_id": "", "client_secret": "", "email_claim_name": "custom_claim_name", - "onelogin_account": "https://mycompany.onelogin.com", + "okta_account": "https://dev-abc123.oktapreview.com", }, name="Widget Corps IDP", type="onetimepin", @@ -5344,7 +5864,7 @@ async def test_method_update_with_all_params_overload_11(self, async_client: Asy "client_id": "", "client_secret": "", "email_claim_name": "custom_claim_name", - "ping_env_id": "342b5660-0c32-4936-a5a4-ce21fae57b0a", + "onelogin_account": "https://mycompany.onelogin.com", }, name="Widget Corps IDP", type="onetimepin", @@ -5438,6 +5958,107 @@ async def test_method_update_overload_12(self, async_client: AsyncCloudflare) -> @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize async def test_method_update_with_all_params_overload_12(self, async_client: AsyncCloudflare) -> None: + identity_provider = await async_client.zero_trust.identity_providers.update( + identity_provider_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + config={ + "claims": ["email_verified", "preferred_username", "custom_claim_name"], + "client_id": "", + "client_secret": "", + "email_claim_name": "custom_claim_name", + "ping_env_id": "342b5660-0c32-4936-a5a4-ce21fae57b0a", + }, + name="Widget Corps IDP", + type="onetimepin", + account_id="account_id", + saml_certificate_set_id="c409ef44-e72c-41c8-8c0b-278c8a6f4fd8", + scim_config={ + "enabled": True, + "identity_update_behavior": "automatic", + "seat_deprovision": True, + "user_deprovision": True, + }, + ) + assert_matches_type(Optional[IdentityProvider], identity_provider, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_raw_response_update_overload_12(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.identity_providers.with_raw_response.update( + identity_provider_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + config={}, + name="Widget Corps IDP", + type="onetimepin", + account_id="account_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + identity_provider = await response.parse() + assert_matches_type(Optional[IdentityProvider], identity_provider, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_streaming_response_update_overload_12(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.identity_providers.with_streaming_response.update( + identity_provider_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + config={}, + name="Widget Corps IDP", + type="onetimepin", + account_id="account_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + identity_provider = await response.parse() + assert_matches_type(Optional[IdentityProvider], identity_provider, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_path_params_update_overload_12(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `identity_provider_id` but received ''"): + await async_client.zero_trust.identity_providers.with_raw_response.update( + identity_provider_id="", + config={}, + name="Widget Corps IDP", + type="onetimepin", + account_id="account_id", + ) + + with pytest.raises(ValueError, match=r"You must provide either account_id or zone_id"): + await async_client.zero_trust.identity_providers.with_raw_response.update( + identity_provider_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + config={}, + name="Widget Corps IDP", + type="onetimepin", + account_id="", + ) + + with pytest.raises(ValueError, match=r"You must provide either account_id or zone_id"): + await async_client.zero_trust.identity_providers.with_raw_response.update( + identity_provider_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + config={}, + name="Widget Corps IDP", + type="onetimepin", + account_id="account_id", + ) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_method_update_overload_13(self, async_client: AsyncCloudflare) -> None: + identity_provider = await async_client.zero_trust.identity_providers.update( + identity_provider_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + config={}, + name="Widget Corps IDP", + type="onetimepin", + account_id="account_id", + ) + assert_matches_type(Optional[IdentityProvider], identity_provider, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_method_update_with_all_params_overload_13(self, async_client: AsyncCloudflare) -> None: identity_provider = await async_client.zero_trust.identity_providers.update( identity_provider_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", config={ @@ -5472,7 +6093,7 @@ async def test_method_update_with_all_params_overload_12(self, async_client: Asy @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_raw_response_update_overload_12(self, async_client: AsyncCloudflare) -> None: + async def test_raw_response_update_overload_13(self, async_client: AsyncCloudflare) -> None: response = await async_client.zero_trust.identity_providers.with_raw_response.update( identity_provider_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", config={}, @@ -5488,7 +6109,7 @@ async def test_raw_response_update_overload_12(self, async_client: AsyncCloudfla @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_streaming_response_update_overload_12(self, async_client: AsyncCloudflare) -> None: + async def test_streaming_response_update_overload_13(self, async_client: AsyncCloudflare) -> None: async with async_client.zero_trust.identity_providers.with_streaming_response.update( identity_provider_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", config={}, @@ -5506,7 +6127,7 @@ async def test_streaming_response_update_overload_12(self, async_client: AsyncCl @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_path_params_update_overload_12(self, async_client: AsyncCloudflare) -> None: + async def test_path_params_update_overload_13(self, async_client: AsyncCloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `identity_provider_id` but received ''"): await async_client.zero_trust.identity_providers.with_raw_response.update( identity_provider_id="", @@ -5536,7 +6157,7 @@ async def test_path_params_update_overload_12(self, async_client: AsyncCloudflar @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_method_update_overload_13(self, async_client: AsyncCloudflare) -> None: + async def test_method_update_overload_14(self, async_client: AsyncCloudflare) -> None: identity_provider = await async_client.zero_trust.identity_providers.update( identity_provider_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", config={}, @@ -5548,7 +6169,7 @@ async def test_method_update_overload_13(self, async_client: AsyncCloudflare) -> @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_method_update_with_all_params_overload_13(self, async_client: AsyncCloudflare) -> None: + async def test_method_update_with_all_params_overload_14(self, async_client: AsyncCloudflare) -> None: identity_provider = await async_client.zero_trust.identity_providers.update( identity_provider_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", config={ @@ -5570,7 +6191,7 @@ async def test_method_update_with_all_params_overload_13(self, async_client: Asy @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_raw_response_update_overload_13(self, async_client: AsyncCloudflare) -> None: + async def test_raw_response_update_overload_14(self, async_client: AsyncCloudflare) -> None: response = await async_client.zero_trust.identity_providers.with_raw_response.update( identity_provider_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", config={}, @@ -5586,7 +6207,7 @@ async def test_raw_response_update_overload_13(self, async_client: AsyncCloudfla @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_streaming_response_update_overload_13(self, async_client: AsyncCloudflare) -> None: + async def test_streaming_response_update_overload_14(self, async_client: AsyncCloudflare) -> None: async with async_client.zero_trust.identity_providers.with_streaming_response.update( identity_provider_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", config={}, @@ -5604,7 +6225,7 @@ async def test_streaming_response_update_overload_13(self, async_client: AsyncCl @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_path_params_update_overload_13(self, async_client: AsyncCloudflare) -> None: + async def test_path_params_update_overload_14(self, async_client: AsyncCloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `identity_provider_id` but received ''"): await async_client.zero_trust.identity_providers.with_raw_response.update( identity_provider_id="", @@ -5634,7 +6255,7 @@ async def test_path_params_update_overload_13(self, async_client: AsyncCloudflar @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_method_update_overload_14(self, async_client: AsyncCloudflare) -> None: + async def test_method_update_overload_15(self, async_client: AsyncCloudflare) -> None: identity_provider = await async_client.zero_trust.identity_providers.update( identity_provider_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", config={}, @@ -5646,7 +6267,7 @@ async def test_method_update_overload_14(self, async_client: AsyncCloudflare) -> @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_method_update_with_all_params_overload_14(self, async_client: AsyncCloudflare) -> None: + async def test_method_update_with_all_params_overload_15(self, async_client: AsyncCloudflare) -> None: identity_provider = await async_client.zero_trust.identity_providers.update( identity_provider_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", config={}, @@ -5665,7 +6286,7 @@ async def test_method_update_with_all_params_overload_14(self, async_client: Asy @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_raw_response_update_overload_14(self, async_client: AsyncCloudflare) -> None: + async def test_raw_response_update_overload_15(self, async_client: AsyncCloudflare) -> None: response = await async_client.zero_trust.identity_providers.with_raw_response.update( identity_provider_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", config={}, @@ -5681,7 +6302,7 @@ async def test_raw_response_update_overload_14(self, async_client: AsyncCloudfla @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_streaming_response_update_overload_14(self, async_client: AsyncCloudflare) -> None: + async def test_streaming_response_update_overload_15(self, async_client: AsyncCloudflare) -> None: async with async_client.zero_trust.identity_providers.with_streaming_response.update( identity_provider_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", config={}, @@ -5699,7 +6320,7 @@ async def test_streaming_response_update_overload_14(self, async_client: AsyncCl @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_path_params_update_overload_14(self, async_client: AsyncCloudflare) -> None: + async def test_path_params_update_overload_15(self, async_client: AsyncCloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `identity_provider_id` but received ''"): await async_client.zero_trust.identity_providers.with_raw_response.update( identity_provider_id="", @@ -5729,7 +6350,7 @@ async def test_path_params_update_overload_14(self, async_client: AsyncCloudflar @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_method_update_overload_15(self, async_client: AsyncCloudflare) -> None: + async def test_method_update_overload_16(self, async_client: AsyncCloudflare) -> None: identity_provider = await async_client.zero_trust.identity_providers.update( identity_provider_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", config={}, @@ -5741,7 +6362,7 @@ async def test_method_update_overload_15(self, async_client: AsyncCloudflare) -> @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_method_update_with_all_params_overload_15(self, async_client: AsyncCloudflare) -> None: + async def test_method_update_with_all_params_overload_16(self, async_client: AsyncCloudflare) -> None: identity_provider = await async_client.zero_trust.identity_providers.update( identity_provider_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", config={"restrict_to_account_members": True}, @@ -5760,7 +6381,7 @@ async def test_method_update_with_all_params_overload_15(self, async_client: Asy @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_raw_response_update_overload_15(self, async_client: AsyncCloudflare) -> None: + async def test_raw_response_update_overload_16(self, async_client: AsyncCloudflare) -> None: response = await async_client.zero_trust.identity_providers.with_raw_response.update( identity_provider_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", config={}, @@ -5776,7 +6397,7 @@ async def test_raw_response_update_overload_15(self, async_client: AsyncCloudfla @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_streaming_response_update_overload_15(self, async_client: AsyncCloudflare) -> None: + async def test_streaming_response_update_overload_16(self, async_client: AsyncCloudflare) -> None: async with async_client.zero_trust.identity_providers.with_streaming_response.update( identity_provider_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", config={}, @@ -5794,7 +6415,102 @@ async def test_streaming_response_update_overload_15(self, async_client: AsyncCl @pytest.mark.skip(reason="TODO: investigate broken test") @parametrize - async def test_path_params_update_overload_15(self, async_client: AsyncCloudflare) -> None: + async def test_path_params_update_overload_16(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `identity_provider_id` but received ''"): + await async_client.zero_trust.identity_providers.with_raw_response.update( + identity_provider_id="", + config={}, + name="Widget Corps IDP", + type="onetimepin", + account_id="account_id", + ) + + with pytest.raises(ValueError, match=r"You must provide either account_id or zone_id"): + await async_client.zero_trust.identity_providers.with_raw_response.update( + identity_provider_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + config={}, + name="Widget Corps IDP", + type="onetimepin", + account_id="", + ) + + with pytest.raises(ValueError, match=r"You must provide either account_id or zone_id"): + await async_client.zero_trust.identity_providers.with_raw_response.update( + identity_provider_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + config={}, + name="Widget Corps IDP", + type="onetimepin", + account_id="account_id", + ) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_method_update_overload_17(self, async_client: AsyncCloudflare) -> None: + identity_provider = await async_client.zero_trust.identity_providers.update( + identity_provider_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + config={}, + name="Widget Corps IDP", + type="onetimepin", + account_id="account_id", + ) + assert_matches_type(Optional[IdentityProvider], identity_provider, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_method_update_with_all_params_overload_17(self, async_client: AsyncCloudflare) -> None: + identity_provider = await async_client.zero_trust.identity_providers.update( + identity_provider_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + config={"login_page_auto_prompt": True}, + name="Widget Corps IDP", + type="onetimepin", + account_id="account_id", + saml_certificate_set_id="c409ef44-e72c-41c8-8c0b-278c8a6f4fd8", + scim_config={ + "enabled": True, + "identity_update_behavior": "automatic", + "seat_deprovision": True, + "user_deprovision": True, + }, + ) + assert_matches_type(Optional[IdentityProvider], identity_provider, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_raw_response_update_overload_17(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.identity_providers.with_raw_response.update( + identity_provider_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + config={}, + name="Widget Corps IDP", + type="onetimepin", + account_id="account_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + identity_provider = await response.parse() + assert_matches_type(Optional[IdentityProvider], identity_provider, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_streaming_response_update_overload_17(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.identity_providers.with_streaming_response.update( + identity_provider_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + config={}, + name="Widget Corps IDP", + type="onetimepin", + account_id="account_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + identity_provider = await response.parse() + assert_matches_type(Optional[IdentityProvider], identity_provider, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="TODO: investigate broken test") + @parametrize + async def test_path_params_update_overload_17(self, async_client: AsyncCloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `identity_provider_id` but received ''"): await async_client.zero_trust.identity_providers.with_raw_response.update( identity_provider_id="", diff --git a/tests/api_resources/zero_trust/test_organizations.py b/tests/api_resources/zero_trust/test_organizations.py index 3b00d23e9fe..dbe5607330d 100644 --- a/tests/api_resources/zero_trust/test_organizations.py +++ b/tests/api_resources/zero_trust/test_organizations.py @@ -25,8 +25,6 @@ class TestOrganizations: @parametrize def test_method_create(self, client: Cloudflare) -> None: organization = client.zero_trust.organizations.create( - auth_domain="test.cloudflareaccess.com", - name="Widget Corps Internal Applications", account_id="account_id", ) assert_matches_type(Optional[Organization], organization, path=["response"]) @@ -35,13 +33,13 @@ def test_method_create(self, client: Cloudflare) -> None: @parametrize def test_method_create_with_all_params(self, client: Cloudflare) -> None: organization = client.zero_trust.organizations.create( - auth_domain="test.cloudflareaccess.com", - name="Widget Corps Internal Applications", account_id="account_id", allow_authenticate_via_warp=True, + auth_domain="test.cloudflareaccess.com", auto_redirect_to_identity=True, deny_unmatched_requests=True, deny_unmatched_requests_exempted_zone_names=["example.com"], + disable_end_user_app_creation=False, is_ui_read_only=True, login_design={ "background_color": "#c5ed1b", @@ -64,6 +62,7 @@ def test_method_create_with_all_params(self, client: Cloudflare) -> None: "touch_policy": "always", }, mfa_required_for_all_apps=False, + name="Widget Corps Internal Applications", service_token_inactivity={ "action": "disable", "enabled": True, @@ -82,8 +81,6 @@ def test_method_create_with_all_params(self, client: Cloudflare) -> None: @parametrize def test_raw_response_create(self, client: Cloudflare) -> None: response = client.zero_trust.organizations.with_raw_response.create( - auth_domain="test.cloudflareaccess.com", - name="Widget Corps Internal Applications", account_id="account_id", ) @@ -96,8 +93,6 @@ def test_raw_response_create(self, client: Cloudflare) -> None: @parametrize def test_streaming_response_create(self, client: Cloudflare) -> None: with client.zero_trust.organizations.with_streaming_response.create( - auth_domain="test.cloudflareaccess.com", - name="Widget Corps Internal Applications", account_id="account_id", ) as response: assert not response.is_closed @@ -113,15 +108,11 @@ def test_streaming_response_create(self, client: Cloudflare) -> None: def test_path_params_create(self, client: Cloudflare) -> None: with pytest.raises(ValueError, match=r"You must provide either account_id or zone_id"): client.zero_trust.organizations.with_raw_response.create( - auth_domain="test.cloudflareaccess.com", - name="Widget Corps Internal Applications", account_id="", ) with pytest.raises(ValueError, match=r"You must provide either account_id or zone_id"): client.zero_trust.organizations.with_raw_response.create( - auth_domain="test.cloudflareaccess.com", - name="Widget Corps Internal Applications", account_id="account_id", ) @@ -147,6 +138,7 @@ def test_method_update_with_all_params(self, client: Cloudflare) -> None: }, deny_unmatched_requests=True, deny_unmatched_requests_exempted_zone_names=["example.com"], + disable_end_user_app_creation=False, is_ui_read_only=True, login_design={ "background_color": "#c5ed1b", @@ -353,8 +345,6 @@ class TestAsyncOrganizations: @parametrize async def test_method_create(self, async_client: AsyncCloudflare) -> None: organization = await async_client.zero_trust.organizations.create( - auth_domain="test.cloudflareaccess.com", - name="Widget Corps Internal Applications", account_id="account_id", ) assert_matches_type(Optional[Organization], organization, path=["response"]) @@ -363,13 +353,13 @@ async def test_method_create(self, async_client: AsyncCloudflare) -> None: @parametrize async def test_method_create_with_all_params(self, async_client: AsyncCloudflare) -> None: organization = await async_client.zero_trust.organizations.create( - auth_domain="test.cloudflareaccess.com", - name="Widget Corps Internal Applications", account_id="account_id", allow_authenticate_via_warp=True, + auth_domain="test.cloudflareaccess.com", auto_redirect_to_identity=True, deny_unmatched_requests=True, deny_unmatched_requests_exempted_zone_names=["example.com"], + disable_end_user_app_creation=False, is_ui_read_only=True, login_design={ "background_color": "#c5ed1b", @@ -392,6 +382,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncCloudflare "touch_policy": "always", }, mfa_required_for_all_apps=False, + name="Widget Corps Internal Applications", service_token_inactivity={ "action": "disable", "enabled": True, @@ -410,8 +401,6 @@ async def test_method_create_with_all_params(self, async_client: AsyncCloudflare @parametrize async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None: response = await async_client.zero_trust.organizations.with_raw_response.create( - auth_domain="test.cloudflareaccess.com", - name="Widget Corps Internal Applications", account_id="account_id", ) @@ -424,8 +413,6 @@ async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None: @parametrize async def test_streaming_response_create(self, async_client: AsyncCloudflare) -> None: async with async_client.zero_trust.organizations.with_streaming_response.create( - auth_domain="test.cloudflareaccess.com", - name="Widget Corps Internal Applications", account_id="account_id", ) as response: assert not response.is_closed @@ -441,15 +428,11 @@ async def test_streaming_response_create(self, async_client: AsyncCloudflare) -> async def test_path_params_create(self, async_client: AsyncCloudflare) -> None: with pytest.raises(ValueError, match=r"You must provide either account_id or zone_id"): await async_client.zero_trust.organizations.with_raw_response.create( - auth_domain="test.cloudflareaccess.com", - name="Widget Corps Internal Applications", account_id="", ) with pytest.raises(ValueError, match=r"You must provide either account_id or zone_id"): await async_client.zero_trust.organizations.with_raw_response.create( - auth_domain="test.cloudflareaccess.com", - name="Widget Corps Internal Applications", account_id="account_id", ) @@ -475,6 +458,7 @@ async def test_method_update_with_all_params(self, async_client: AsyncCloudflare }, deny_unmatched_requests=True, deny_unmatched_requests_exempted_zone_names=["example.com"], + disable_end_user_app_creation=False, is_ui_read_only=True, login_design={ "background_color": "#c5ed1b", diff --git a/uv.lock b/uv.lock index d94a4a8f031..e0a25657f17 100644 --- a/uv.lock +++ b/uv.lock @@ -259,7 +259,7 @@ wheels = [ [[package]] name = "cloudflare" -version = "5.9.0" +version = "5.10.0" source = { editable = "." } dependencies = [ { name = "anyio", version = "4.12.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10' or (extra == 'group-10-cloudflare-pydantic-v1' and extra == 'group-10-cloudflare-pydantic-v2')" },